# run — S157 · "KẾ HOẠCH KÝ KẾT HỢP ĐỒNG" — khúc CÒN THIẾU giữa Duyệt NCC và HĐ NTP/NCC > **run-id:** `2026-07-28-S157-ke-hoach-ky-ket-hd` · mở 2026-07-28 (phiên-LOGIC L7, window 4) > **Lệnh anh (verbatim):** *"Nhớ cái quy trình còn thiếu hôm qua ko? Cái spec cũ còn hôm qua. `/fable-real` Invest điều tra quy trình chỗ còn thiếu. Quy trình còn thiếu giữa Duyệt NCC - Kế hoạch ký kết Hợp đồng (Còn thiếu) - Hợp đồng NTP/NCC. Sau đó cho `/fable-clone` review lại thêm 1 lần cái spec đó → Ra cái spec mới đầy đủ chi tiết nhất, bao gồm cách làm. Chia wave rõ ràng. Cho tao cái plan đó và Wave chạy thế nào luôn nhé."* > **Anh chỉ nguồn:** `D:\Dropbox\CONG_VIEC\SOLUTION\` có 2 folder **FORM** (8 file) + **QUY_TRINH** (1 file). > **Anh chốt cùng ngày:** *"chỗ hợp đồng cứ từ từ nhé"* ⇒ lỗ hổng an ninh HĐ **KHÔNG** nằm trong run này. --- ## 0. Nguồn — 2 tài liệu gốc, LẦN ĐẦU đưa vào vòng điều tra Wave S156 hôm qua **chỉ có PDF sơ đồ**. Run này bổ sung **2 tài liệu ISO gốc của công ty** — đây là delta nguồn quan trọng nhất so với hôm qua. | Nguồn | Trích ra | Vai trò | |---|---|---| | `QUY_TRINH\QT TRINH KY HOP DONG TP-NCC.docx` | `src-QT-TRINH-KY-HD.txt` (14.425 B · 38 para · 2 bảng) | **Quy trình ISO 9 bước** trình ký HĐ TP/NCC/Tổ đội — chuẩn đang áp dụng | | `FORM\SOL-CCM-FO-002.01.v01 Bang kiem tra hop dong.docx` | `src-FO-002.01-bang-kiem-tra-HD.txt` (21.287 B · bảng 40r×13c) | **Tờ "Chấp thuận Hợp đồng"** — vật mang chữ ký qua từng trạm (bản giấy của workflow) | | 7 form còn lại trong `FORM\` | *(chưa trích — 6 mẫu HĐ + RG-001 mã HĐ)* | Đã có bản parse ở `docs/forms-spec.md` (Phase 0) | | PDF sơ đồ 21 bước | `runs/2026-07-27-S156-bch-post-ceo-flow/run.md` | Nguồn hôm qua, GIỮ NGUYÊN | --- ## 1. 🔴 GROUNDING LEAD ĐO TRƯỚC KHI PHÓNG — phát hiện lật khung vấn đề ### 1.1 Quy trình ISO 9 bước (trích `src-QT-TRINH-KY-HD.txt` bảng 2) | # | Bước ISO | Trách nhiệm | SLA | |---|---|---|---| | 1 | Lựa chọn NTP/NCC | PB/BCH CT | — *(trỏ `SOL-PRO-SP-001` Quy trình Cung ứng)* | | 2 | Soạn thảo hợp đồng | QS/NV.PB · TBP/TPB | 07 ngày | | 3 | Góp ý nội dung | PD/PM/PRO/CCM/FIN/ACT | 07 ngày | | 4 | Đàm phán, thương thảo | QS/NV.PB · TBP/TPB · PD/PM | 07 ngày | | 5 | In hợp đồng *(NTP in 2 mặt, ký, đóng dấu → PD/PM/TPB ký nháy + ký cover FO-002.01)* | QS/NV.PB | 07 ngày | | 6 | Kiểm tra *(CCM ký nháy từng HĐ + ký cover)* | CCM | 03 ngày | | 7 | Duyệt *(xem xét + ký duyệt HĐ)* | BOD / NĐUQ | 01 ngày | | 8 | Đóng dấu hợp đồng | HRA / ISO | — | | 9 | Phát hành + Lưu trữ *(scan gửi CCM · gửi bản gốc NTP · lưu Server Filing System)* | PB/BCH CT · CCM | — | ### 1.2 🔴 PHÁT HIỆN A — 9 bước ISO ↔ 9 giá trị `ContractPhase` 1-9 KHỚP 1:1 ĐÚNG THỨ TỰ Lead tự đọc `src/Backend/SolutionErp.Domain/Contracts/ContractPhase.cs` (28 dòng, đọc TRỌN): | # ISO | Bước ISO | `ContractPhase` | Trạng thái enum | |---|---|---|---| | 1 | Lựa chọn NTP/NCC | `DangChon = 1` | `[LEGACY]` | | 2 | Soạn thảo HĐ | `DangSoanThao = 2` | 🟢 **SỐNG** (Nháp) | | 3 | Góp ý nội dung | `DangGopY = 3` | `[LEGACY]` | | 4 | Đàm phán | `DangDamPhan = 4` | `[LEGACY]` | | 5 | In hợp đồng / ký nháy | `DangInKy = 5` | `[LEGACY]` | | 6 | Kiểm tra CCM | `DangKiemTraCCM = 6` | `[LEGACY]` | | 7 | Duyệt BOD/NĐUQ | `DangTrinhKy = 7` | `[LEGACY]` | | 8 | Đóng dấu | `DangDongDau = 8` | `[LEGACY]` | | 9 | Phát hành + lưu trữ | `DaPhatHanh = 9` | 🟢 **SỐNG** (terminal) | ⇒ **7 phase `[LEGACY]` KHÔNG phải rác kiến trúc — chúng là quy trình ISO được mã-hoá CỨNG.** Post-Mig 21 / Session 17 thay bằng `ChoDuyet = 10` + con-trỏ `CurrentWorkflowStepIndex` chạy trên **workflow V2 admin-config** — tức chuyển từ *mã-hoá cứng 9 bước* sang *cấu-hình-được N bước*. 🔑 **Hệ quả lên verdict hôm qua:** verdict `LAI` (b.13→21 tái dùng V2) **KHÔNG đổi**, nhưng **lý do mạnh hơn hẳn**: V2 sinh ra CHÍNH ĐỂ biểu diễn quy trình ISO này dưới dạng cấu hình. Hôm qua invest chỉ lập luận được *"phase bị gỡ = trạm của b.13→21"*; nay có **tài liệu ISO gốc** chứng minh **vì sao** 9 trạm đó tồn tại. Đây là **chứng cứ mới**, không phải diễn giải lại. ### 1.3 🔴 PHÁT HIỆN B — khoảng trống nằm ĐÚNG giữa ISO-1 và ISO-2, và ISO doc KHÔNG có nó Quy trình ISO đi thẳng **bước 1 (Lựa chọn NTP/NCC) → bước 2 (Soạn thảo HĐ)**, KHÔNG có bước trung gian. Sơ đồ PDF (bản `14/2026`, mới hơn) chèn **b.7→12** đúng vào chỗ đó: ``` ISO-1 Lựa chọn NTP/NCC ≡ PE "Duyệt NCC" (PE.DaDuyet=7, PDF b.1→6) 🟢 ĐÃ CÓ └───────────── ⬛ KHOẢNG TRỐNG = "KẾ HOẠCH KÝ KẾT HỢP ĐỒNG" ⬛ ─────────────┐ PDF b.7→12: mail giao BCH · duyệt mẫu+shopdrawing với TVGS · │ 🔴 THIẾU tổng hợp hồ sơ + so sánh giá → đề xuất GIÁ TRỊ ký HĐ · │ CẢ Ở PMH kiểm tra → CCM kiểm tra → CEO ký / CCM đóng dấu approval │ DOC LẪN ┌─────────────────────────────────────────────────────────────────────────────┘ CODE ISO-2 Soạn thảo HĐ ≡ Contract `DangSoanThao=2` (PDF b.13) 🟢 ĐÃ CÓ ``` ⇒ **"Còn thiếu" theo nghĩa MẠNH: thiếu ở CẢ HAI tầng** — không có trong quy trình ISO đang ban hành, và không có trong code. Không phải "code chưa làm theo doc"; là **doc cũng chưa có**. 🔴 ⇒ spec ra từ run này **vừa là spec phần mềm, vừa là đề xuất bổ sung quy trình ISO** cho anh duyệt. ### 1.4 Đối chiếu SLA — 2 nguồn, 2 độ mịn (cần hoà giải, KHÔNG tự chọn) | Nguồn | SLA ghi | Ghi chú | |---|---|---| | ISO doc | 07 · 07 · 07 · 07 · 03 · 01 ngày (bước 2→7) | tổng ≈ **32 ngày** cho khúc soạn→duyệt | | PDF sơ đồ | `10-14 ngày` (b.1→4) · `3 ngày` (BCH gửi full info) · `7-10 ngày` (b.13→18) | mịn hơn ở khúc BCH | | Code hiện tại | `AddDays(7)` **hardcode** | lỗ L3 hôm qua — thụt lùi so V1, lỗ toàn-V2 (cả PE) | ### 1.5 Tờ `FO-002.01` = bản giấy của workflow duyệt Bảng 40r×13c, các khối ký theo phòng: **PHÒNG BAN/DỰ ÁN (ĐỀ XUẤT)** → **PHÒNG CUNG ỨNG** (điều khoản HĐ · điều khoản thanh toán · rủi ro pháp lý) → … mỗi khối có `Họ tên` + `Ngày` + cột `Ý KIẾN`. ⇒ Ánh xạ thẳng sang `ApprovalWorkflowStep` (Phòng) × `ApprovalWorkflowLevel` (Cấp) + `LevelOpinions` đã có sẵn ở V2 — **cần invest xác nhận độ khớp, đừng để lead tự kết luận.** ### 1.6 Nợ mang sang từ S156 — invest MỚI phải hấp thụ, không lặp lại 6 việc sửa bản invest cũ (`runs/2026-07-27-S156-bch-post-ceo-flow/review-synthesis.md` §G): 1. Claim SAI: *"hardcoded policy fallback"* → thật là **`ConflictException` `:115-116`** ⇒ HĐ sinh từ phiếu **KẸT CỨNG `ChoDuyet`**, hỏng CỨNG. **Gốc lỗi: invest tin skill-doc hơn ĐĨA.** 2. Siết biên: vùng phase-đã-gỡ là **b.14→19**, KHÔNG phải b.13→21. 3. Thiếu Q vai người TRÌNH — `ContractWorkflowService.cs:70-79` đòi `Drafter|DeptManager`, PMH mang `Procurement` ⇒ **403** ở b.13/b.17. 4. Cảnh báo lỗ hổng reject = **việc RIÊNG**, anh đã chốt *"cứ từ từ"* ⇒ **NGOÀI scope run này**. 5. Q5 thiếu phương án **(d) `skipToFinal` + `AllowApproverSkipToFinal :322`** — ĐÃ WIRE, 0 code BE. 6. **Q2 phải viết lại theo 2 TRỤC + 3 số đo cùng đơn vị** (số bảng mới · LOC BE · LOC FE) **lấy từ twin thật trong repo**, không ước cảm tính. --- ## 1.7 🔴 OWNER CHỐT TRONG CỬA (2026-07-28, anh trả lời trực tiếp báo-cáo grounding) Lead trình 2 điểm ở §1.5 và §1.4; anh chốt **cả hai**. Đây là **quyết định owner**, không phải suy luận lead. ### (O-1) Cấu trúc trình ký — **GIỐNG**, khác duy nhất ở NỘI DUNG > **anh (verbatim):** *"Đúng chính xác, cấu trúc trình ký giống, chỉ khác nội dụng thôi."* ⇒ Trả lời cho §1.5 (form `FO-002.01` ↔ `ApprovalWorkflowStep` × `Level` × `LevelOpinions`). 🔑 **Hệ quả kiến-trúc — MẠNH, chốt trước cả khi invest trả bài:** - Phiếu "Kế hoạch ký kết Hợp đồng" **TÁI DÙNG khung duyệt V2 đang chạy** (Quy trình > Bước=Phòng > Cấp=NV cụ thể, OR-of-N cùng cấp, `LevelOpinions` UPSERT khi duyệt) — **giống hệt PE và Contract V2 đang làm**. - Cái **DỰNG MỚI = NỘI DUNG phiếu** (các trường của "kế hoạch ký kết": căn cứ b.8-9 + so sánh giá + giá trị đề xuất), **KHÔNG phải cơ-chế duyệt**. - 🔻 **Q2 hôm qua (kiến trúc khúc 8-12, reviewer chấm `THIEU-PHUONG-AN` + thiên-vị) gần như TỰ ĐÓNG:** tranh luận 3 phương án hôm qua xoay quanh *"có dựng cơ-chế duyệt riêng không"*. Anh vừa trả lời: **không dựng cơ-chế mới, dùng lại khung**. ⇒ option-space thu về **chỉ còn trục NỘI DUNG** (phiếu riêng ⟂ mở rộng PE ⟂ entity con của Contract). **Invest vẫn phải trình 3 số đo cho trục còn lại**, nhưng KHÔNG cần bàn lại trục cơ-chế. - Đây cũng là **đối chứng ngoài-code cho verdict `LAI`**: khung V2 gánh được vì bản GIẤY vốn cùng hình dạng. ### (O-2) SLA — **THAM KHẢO thôi**, không phải ràng buộc > **anh (verbatim):** *"Cái này để tham khảo thôi, ko vấn đề j, đa số là trễ."* ⇒ Trả lời cho §1.4 (ISO 07/07/07/07/03/01 vs PDF 3 + 7-10 vs code hardcode `AddDays(7)`). 🔑 **Hệ quả:** - **KHÔNG dựng SLA-engine**, KHÔNG auto-approve-on-timeout, KHÔNG cảnh báo chặn. SLA = **hiển thị tham khảo**. - Không cần hoà giải 2 nguồn số ⇒ **gỡ một câu hỏi khỏi bộ câu hỏi trình anh**. - 🔸 Lỗ **L3** (`AddDays(7)` hardcode, hôm qua xếp "thụt lùi so V1, lỗ toàn-V2") **TỤT ƯU TIÊN** — vẫn là số hiển thị sai, nhưng **không gây hại vận-hành** vì không ai enforce theo nó. Ghi nhận, đừng nhét vào wave thi công của run này. - 🔴 **Đừng đọc quá lời anh:** anh nói SLA *không quan trọng*, KHÔNG nói *bỏ hiển thị deadline*. Giữ hiển thị. ## 2. taskList snapshot ### Wave 1 — `/fable-real invest` (SINGLE deep-pass, engine-đắt Fable, KHÔNG fan-out) ``` [1] investigator-codebase (Fable, effort max) → §A quy trình chi tiết khúc CÒN THIẾU (đối chiếu 3 nguồn: ISO doc · PDF · FO-002.01) → §B cách wire vào codebase (entity · migration · CQRS · controller · FE 2-app · menu/permission) → §C chia WAVE thi công + checklist ĐO ĐƯỢC từng wave → §D 6 việc sửa của review cũ đã hấp thụ thế nào (từng cái, đối chiếu ĐĨA không tin doc) propose-only; spec-file do LEAD ghi sau khi verify (H21 ① honest-note c) ``` ### Wave 2 — `/fable-clone reviewer` ensemble 4 lane (đóng gói C2: ≤3 file/lane · ép khung rỗng lượt 1-2 · trần 25) **Label C3 4-thành-phần — NEO TẠI ĐÂY** (panel ephemeral, không neo thì không tái lập/audit được): | Label (neo C3) | Lăng kính | File được đọc (≤3) | |---|---|---| | `Gate reviewer lens-wave s157` | Wave-plan có khả thi không · acceptance có **ĐO ĐƯỢC thật** không hay chỉ nghe như đo được · wave có deploy độc lập thật không | `spec-ke-hoach-ky-ket-hd-28-07-2026.md` · `runs/2026-07-27-S155-pe-delete-approver/run.md` | | `Gate reviewer lens-fidelity s157` | Spec có trung thực với **3 nguồn gốc** không — bịa bước / rơi bước / gán sai vai / nống biên | `spec-*.md` · `src-QT-TRINH-KY-HD.txt` · `src-FO-002.01-bang-kiem-tra-HD.txt` | | `Gate reviewer lens-schema s157` | **7 bảng** thừa/thiếu · loose-Guid vs FK · UNIQUE filtered · enum mới có đúng không · biến thể 5 bảng | `spec-*.md` · `ApprovalWorkflow.cs` · `PurchaseEvaluation.cs` | | `Gate reviewer lens-claims s157` | Verify ĐỘC LẬP mọi claim `file:line` trong §2 — có dương-giả không | `spec-*.md` · `ProposalFeatures.cs` · `MenuKeys.cs` | **taskList snapshot (wave 2):** 4 lane · `role: reviewer` ×4 · `tier: 'opus'` explicit từng lane (belt-and-suspenders theo GAP#6 — worker-tier-pin S124 đã che, nhưng lệnh này tự định nghĩa là "ensemble tier-2") · `maxTurns: 25` · lane RETURN-only, lead = single-writer refute+synthesize @P3/P4. ### Wave 3 — lead synthesize → `spec-ke-hoach-ky-ket-hd-28-07-2026.md` + **PLAN WAVE thi công trình anh** --- ## 3. Stages - [x] S0 — lead trích 2 tài liệu gốc (`src-QT-TRINH-KY-HD.txt` 14.425 B · `src-FO-002.01-*.txt` 21.287 B) - [x] S1 — lead grounding: đọc TRỌN `ContractPhase.cs` → **phát hiện A** (9 ISO ↔ 9 enum khớp 1:1) + **phát hiện B** (khoảng trống nằm giữa ISO-1 và ISO-2, thiếu ở CẢ doc lẫn code) - [x] S2 — scaffold run-folder + `run.md` (file này) - [x] S3 — `/fable-real investigator-codebase` deep-pass — **3 lượt, 2 sự-cố, PARTIAL-HONEST**: · lượt 1 **`skeleton-ruột-rỗng`**: 202K tok / 35 tool-use, đĩa chỉ **1.661 B khung rỗng 4 mục `[PENDING]`** (return garble `#53` = mẩu "Đọc tiếp 3 file S156"). **Ghi-đĩa-trong-lúc-làm = CẦN KHÔNG ĐỦ** — phải verify RUỘT có chữ. Header ĐÃ hấp thụ O-1/O-2 ⇒ SendMessage giữa chừng ăn. · lượt 2 (resume, **cắt còn 2 mục** theo khuôn cứu S156) → **§A + §B CLEAN**, đĩa 1.661→**23.085 B**, return khớp đĩa. · lượt 3 (resume §C/§D) — **tiến-trình CLI thoát giữa chừng**, agent stopped no-completion-record. Đĩa **KHÔNG đổi** (23.085 B, mtime 10:55) ⇒ §C/§D **chưa từng được ghi**. Mất = phần chưa làm, **0 mất dữ-liệu đã có**. **KHÔNG resume lần 3** (nguyên-nhân ngoại-cảnh, nhưng H21 ① đã cho phép: engine propose-only, **spec do LEAD ghi**; §A/§B CHÍNH LÀ phần propose). - [x] S4 — lead verify ĐỘC LẬP 4 claim load-bearing trên ĐĨA (không tin return): · **B.1 Proposal-lite phá OR-of-N** → ✅ THẬT: `ProposalFeatures.cs` `SelectMany` flatten `:427-429` + `ElementAtOrDefault` **1 row** `:433` + so đúng **1** `ApproverUserId` `:439`; comment code TỰ THÚ *"Lite version: assume 1 step per workflow"*. · **slot enum 10 trống** → ✅ THẬT: `ApprovalWorkflow.cs:53-67` dừng ở `TravelRequest = 9`. · **`Off_DeXuat` 4 key ĐỀU trong `All`** → ✅ THẬT `MenuKeys.cs:171`; **`Pe_*` sinh bằng factory `:150`/`:154` NẰM NGOÀI `All`** ⇒ policy per-action không tồn tại — bẫy claim đúng. · **Mig cuối = 68** → ✅ khớp `docs/STATUS.md` CURRENT STATE. - [x] S5 — lead ghi spec `spec-ke-hoach-ky-ket-hd-28-07-2026.md` (3 heading H21 ①) — §A/§B từ invest (đã verify) + **§C wave-plan + §D do LEAD viết** (đúng H21: propose ⟂ spec). - [ ] S6 — `/fable-clone reviewer` ensemble chấm spec - [ ] S7 — lead refute + synthesize → trình anh > 🔴 **Luật của run này (vết S156):** CẤM điền sẵn kết-quả cho stage chưa chạy. Byte-count · verdict · > TOTAL chỉ được ghi SAU khi đo thật. Mọi stage chưa chạy giữ `[ ]`.