# archive/2026-08-curate-s180.md — verbatim khối bị nén khỏi MEMORY.md @S180 (hook hard-cap 24.9KB>24.4KB → rewrite <17.1KB)

> Chép NGUYÊN VĂN các entry/section bị gộp thành 1-liner trong index. Ctrl-F theo nhãn phiên. Nguồn: MEMORY.md trạng thái ngay trước curate S180 (2026-08-07).

---

## [S180 entry — bản dài vừa viết @S180 trước curate]

- **S180 (08-07) ×Fable fit-map 4-thư upgrade-pack 7GĐ [`runs/2026-08-07-S180-adap-upgrade-pack-phased/sub-invest-fitmap-S180.md` ~26KB]:** PHỦ-ĐỦ 7GĐ/12TC/9LỖI. 🔴 Nghề: (1) hash 4 thư chỉ khớp qua máy canonical `scripts/stamp_verify.py` (strip-\r → split 2nd `---` → strip-1-LF) — phép tự chế MISMATCH cả 4, suýt phán "tamper" sai ⇒ mesh-hash LUÔN dùng máy sẵn; (2) TÔI = vai **7/7 dính #53** phiên này VÀ bị coordinator bắt đúng **LỚP-7 tự giẫm** (202K token đọc / 7KB đĩa ~15%) → lệnh "đổ ruột TRƯỚC đo SAU" cứu trọn — bài: tỉ-lệ byte-đĩa/token-đọc = tín hiệu giám sát được, đề xuất nối vào AS-17; (3) xung đột lớn DUY NHẤT gói = SE exit-0-advisory (`governance-detectors.ps1:1963` "Exit 0 always") ⟂ hub cổng-chặn-mã-lỗi-4-trạng-thái → VƯỢT-KHUNG; (4) GĐ-5 gần xong nhất (H21 per-invocation + tier-pin + spawn-audit + runs/ chung-gốc), GĐ-4 hổng nhất (0 sổ-yêu-cầu-anh, 0 chấm-điểm — grep "chấm điểm" commands 0-hit, control "điểm dừng"=3); (5) bác-một-phần nền lead: `pull_warn_days` trống = **CỐ Ý owner @S148 có khai** (`check-email.md:48` 🔒) ≠ ghost-wire — lead mời bác, đo ra khác thì nói. Tag `[s180, fit-map-7gd, stamp-verify-canonical-only, lop7-tu-giam-do-ruot-truoc, exit0-vs-gate-vuot-khung, pull-warn-days-owner-gated]`

---

## [S171 header-entry]

- **S171 (2026-08-04) ×Fable-5 — `VERDICT = 27 giống-được / 6 buộc-khác / 8 data-gap`, return SẠCH `[LEAD HARVEST HOI-TO @S172 — no mo tu closeout truoc; owner slot (71) chot 'gom va sleep thi auto, tu quyet'. Nguon = artifact tren dia, KHONG suy dien]; nguồn `runs/2026-08-04-S171-khkk-ui-mirror-pe/sub-investigator-codebase-invest-s171.md` **44.830 B** (artifact lớn nhất phiên)`:** Cấu trúc 8 mục: **§0 hai đính-chính vào ground-truth của LEAD (đặt TRƯỚC §1 — nghề đúng: bác tiền-đề trước khi xây trên nó)** · §1 bản-đồ 3 panel PE mẫu · §2 bản-đồ KHKK hiện trạng · §3 bảng DELTA per-panel · §4 data-gap · §5 kiến-trúc đề-xuất · §6 rủi-ro/bẫy · §7 checklist ĐO ĐƯỢC · §8 ba câu muốn lead đọc kỹ nhất. 🔴 **Bị 3 lane `reviewer` soi ngay sau đó và KHÔNG đứng trọn:** miễn-trừ **6 → 3** (P1-4 + P2-7 lật thành giống-được; P3-12 hạ xuống hoãn vì tiền-đề *'KHKK 3 trạm ngắn'* đo lại là **SAI** — `DbInitializer.cs:554` = 3 Bước × ≤2 Cấp, seed tự ghi *'sao từ workflow Duyệt NCC prod'*), và **6 acceptance của nó bị bẻ gãy khi chạy thật**. ⇒ **Bài: bản invest 44 KB rất đầy đủ vẫn KHÔNG thay được lượt reviewer đối-kháng** — đầy-đủ ≠ đúng. Tag `[s171, fable-5, 27-6-8, dinh-chinh-ground-truth-truoc, mien-tru-6-xuong-3, day-du-khong-bang-dung]`

---

## [S160 entry]

- **S160 (07-29) DRY-RUN toàn-trình đến HĐ cứng — 2 lane `/fable-real` [engine-label real-fable-S160; lane-2 lượt-1 #53 garble → resume sạch, đĩa mất 0 B] [`runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-{1,2}.md` 24.2K+32.2K]:** Lane-1 nguồn: ranh GĐ3=b.13→18/GĐ4=b.19→21 ĐÃ ratify @S159 spec `:27` (đừng suy lại từ QT); RG-001 v02 CHỈ 4 viết tắt — **codegen tự chế "MB"** (`ContractCodeGenerator.cs:25`, không gốc quy định); bản cứng vật lý SINH ở b.17-18 ∈GĐ3 (GĐ4 hiển thị readonly phần nó không tạo); FO-002.01 tick-box 6 loại ≠ 7 ContractType; forms-spec = parse chính v02, 0 lệch format. Lane-2 code: `Hdc_*` = **7-leaf-per-ContractType** (loop `DbInitializer.cs:1862-1867`) KHÔNG phải 6-leaf — đề bài lead sai 2 grounding, lane tự bẻ; KHÔNG có phase KyCung (8=DangDongDau LEGACY, terminal=DaPhatHanh 9 → GĐ4 = DERIVE sau terminal, 0 mig); 🔴 `DeleteContract` guard `Phase >= DangInKy` so sánh SỐ ⇒ chặn xóa cả 9/10/98/99 (dry-run rác phải admin-override hoặc chấp nhận); mặt tấn công thật = nhánh Reject-trước-guard `ContractWorkflowService.cs:49-66` (Approve CÓ guard); "khuôn PE per-action" KHÔNG tồn tại tầng attribute (PE class-trần + handler-Forbidden) — tiền lệ per-action thật = `/deleted` `ContractsController.cs:28-29` + Suppliers; `Contracts` ∈ All ⇒ 4 policy sống sẵn 0-key-mới. Lead đo bổ sung: **prod Contracts = 0 active + 0 deleted** (admin bypass `:298/:440` — sổ "7 HĐ V1" S156 STALE); login prod parse field `accessToken` (không phải `token`). Đầu ra: plan-cha + 7 spec-wave (W1-W3,W5-W8; W4/W9 defer) cùng run-folder. Tag `[s160, dry-run-toan-trinh, hdc-7-leaf-per-type, delete-guard-numeric-compare, reject-truoc-guard, contracts-policy-co-san, mb-khong-goc, prod-contracts-0]`

---

## [S157 entry]

- **S157 (07-28) KH-ký-kết-HĐ b.7→12 [§A+§B đĩa, §C/§D PENDING lượt sau, `runs/2026-07-28-S157-ke-hoach-ky-ket-hd/sub-invest-kehoach-1.md`]:** Owner chốt O-1 *"cấu trúc trình ký GIỐNG, khác nội dung"* ⇒ tái dùng khung V2, dựng 7 bảng NỘI-DUNG `ContractSigningPlan*` (Mig 69 thuần CreateTable; mig cuối=68 verify ls) + `ApplicableType=10` (slot trống `ApprovalWorkflow.cs:53-67`). 🔴 Bẫy twin MỚI: **Proposal-lite ApproveV2 PHÁ OR-of-N** — `ProposalFeatures.cs:427-439` flatten global-level + `ElementAtOrDefault` match 1-user, entity không có StepIndex (`Proposal.cs:27`) ⇒ 2-row-cùng-Order thành AND tuần tự; KH service PHẢI copy `ContractWorkflowService.ApproveV2Async:217-394`, Proposal chỉ làm khuôn CRUD/menu/FE. Twin đo thật: Proposal BE 849 · FE 1.956 LOC · 4 bảng (Mig 38 grep CreateTable) · PE 6.5K/14.9K cận trên. `ConflictException :115-116` tự xác minh đĩa (skill contract-workflow stale — fallback V1 chỉ sống đường display). ISO doc 9 bước ↔ `ContractPhase` 1-9 khớp 1:1 (7 LEGACY = ISO mã-hoá cứng); khúc b.7-12 thiếu CẢ ISO-doc lẫn code; FO-002.01 có luật auto-pass-quá-01-ngày (mâu thuẫn V2 no-auto-approve; O-2 SLA=tham-khảo). #53: coordinator chặn skeleton-rỗng @202K-token → cắt còn §A+§B, Edit-liền-tay từng mục. Tag `[s157, ke-hoach-ky-ket, proposal-lite-breaks-or-of-n, iso-9-steps-eq-contractphase]`

---

## [S156 entry]

- **S156 (07-27) BCH post-CEO flow bước 7→21 [§0-§3+§6 đĩa, §4-§5 PENDING lượt sau, `runs/2026-07-27-S156-bch-post-ceo-flow/sub-invest-bch-1.md`]:** Verdict **LAI** — 13→21 TÁI DÙNG Contract (7 dòng `[LEGACY]` `ContractPhase.cs:11-13` chính LÀ trạm 13-21 đã gỡ CỐ Ý Mig21/S17; V2 `ContractWorkflowService.cs:217-394` cookie-cutter sẵn, terminal gen-mã+DaPhatHanh) · 7-12 DỰNG MỚI (0-hit shopdrawing/TVGS, khuôn 12-bis + `ApplicableType=10` append-only). 🔴 Chuỗi "cơ-chế đúng, thứ đi qua KHÔNG có" phía HĐ: cầu PE→HĐ pin V1 (`CreateContractFromEvaluationFeatures.cs:68-71,108`) không nhận V2 + UpdateDraft không re-pin · `GetEligiblePhases` (`ContractFeatures.cs:334-351`) + inbox `PhaseActorRoles` (`:363-372`) 100% LEGACY-phase ⇒ approver V2/BCH KHÔNG xem/inbox được HĐ ChoDuyet · `CeoApprovalThreshold` 0-consumer HĐ (bước-18 ">5 tỷ" chưa có máy) · SLA V2 hardcode `AddDays(7)` 3 site, Step không có SlaDays · notify chỉ Drafter (`:407`) · `AttachmentPurpose` thiếu ký-nháy (enum-extend 0-mig tiền lệ PE=4) · HĐ TraLai reset-toàn-phần không 4-mode. Mig 68 `AddPeAllowApproverDelete` ĐÃ land 07-27 ⇒ mig kế = 69. Bắt lead sai grounding: 12 enum/7 LEGACY (lead ghi 9/6) — lead nhận. #53 strike-1 (return bốc hơi, đĩa nguyên → lead đọc từ đĩa, không redo). Tag `[s156, bch-post-ceo, verdict-lai, eligible-phases-legacy-only, bridge-pins-v1]`

---

## [S155 menu/trash/dept-head entry]

- **S155 (07-27) PE menu/trash/dept-head [21 finding, `runs/2026-07-27-S155-pe-delete-approver/sub-invest-menu-3.md`]:** 🔴 Menu = **SEED DB** không hard-code FE — `Pe_<Code>` khai `DbInitializer.cs:1874-1877`; thêm mục = restart API, 0 migration (upsert `:1888-1914` chỉ sửa `Order`, **KHÔNG đụng Label** ⇒ rename qua `labelBackfill:1918-1924`; `DisplayLabel` **CHỈ ăn fe-user** `MenuDtos.cs:14`). 6-chỗ-mirror: +2 seed permission SONG SONG `:2092-2096`/`:2492-2496` + regex `Layout.tsx:120` (fe-admin `:107` thiếu `WfView`). Đổi KEY = mồ côi 13 row/key × 10 key ⇒ giữ key chỉ đổi label. **`Đã duyệt` chạy được HÔM NAY**: `phase=` đủ 3 tầng (`Controller:23`→`Features:565`→`:620`), DaDuyet=7 ⇒ `?type=1&phase=7`, 0 route mới. `pendingMe` KHÔNG phải param BE (FE rẽ `/inbox` `ListPage:61-68` + lọc client `:182`). `IgnoreQueryFilters` 0 src/Backend / 15 hit tests; `HasQueryFilter(`=12. An-toàn accumulator = **cấu trúc** (`PeBudgetAccumulator.cs:42`/`:100` dựng `peers` FRESH). 🎁 Changelog `: BaseEntity` + lọc CHỈ `PurchaseEvaluationId` (`:1424`) ⇒ lịch sử phiếu-xóa đọc MIỄN PHÍ; cái chôn = DETAIL bundle. 0 tiền lệ thùng-rác (hit "khôi phục" duy nhất = STRING `EmployeeFeatures.cs:162` ghost-wire). 🔴 **"Trưởng phòng" CÓ TÊN CHƯA CÓ ĐỜI**: `Department.ManagerUserId` **0/10 Dev** + 2 FE hardcode `managerUserId: null` payload SỬA (`DepartmentsPage.tsx:43`/`:57`) ⇒ tự-xoá mỗi lần sửa phòng. `PositionLevel.TruongPhong` 33/33 NULL (V1-legacy). Tag `[s155, menu-seed-db, phase-param-exists, changelog-survives-softdelete, dept-head-name-only]`

---

## [S155 WF-V2 sửa-tại-chỗ entry]

- **S155 (07-27) WF-V2 sửa-tại-chỗ vs version-mới [25 finding, `runs/2026-07-27-S155-pe-delete-approver/sub-invest-wfver-4.md`]:** 🔴 **0 lệnh Update** — `ApprovalWorkflowsV2Controller.cs` (54d TOÀN BỘ) chỉ GET/POST/PATCH-user-selectable/DELETE ⇒ sửa 1 cờ = buộc POST = `MAX(Version per Code)+1` (`ApprovalWorkflowV2AdminFeatures.cs:325-328`) + hạ MỌI active cùng type (`:330-334`). Chặn THẬT bằng mã. 🔴 **F17:** POST tạo entity mới ⇒ **Id mới** (`:336`+`BaseEntity.cs:5`) mà phiếu đọc workflow theo **Id đã pin** (`PurchaseEvaluationWorkflowService.cs:674`) ⇒ **cờ mới KHÔNG tới phiếu đang chạy**; re-pin chỉ `PurchaseEvaluationFeatures.cs:149`/`:291` mà `:249-251` chặn chỉ Nháp/TraLai ⇒ ChoDuyet kẹt bản cũ vĩnh viễn; 0 backfill re-pin. ⇒ cờ `AllowApproverDelete` **HỎNG nếu không có lệnh Update**. Pin = **tham chiếu SỐNG** (chỉ NS có snapshot Mig67). Con trỏ **LAI**: Bước=INDEX `steps[currentIdx]` (`:686` vỡ ÂM THẦM/`:683` kẹt) · Cấp=ORDER-VALUE (`:694`→`:695` kẹt) ⇒ ranh AN-TOÀN = **không đổi tập `{Step.Order}`∪`{Level.Order}`**. 13 thao tác: 3 an-toàn (thêm-người-cùng-Order · cờ `Allow*` · đổi tên) · 2 nửa (bớt/đổi `ApproverUserId` → 403 GUID-trần `:705`, FK Restrict `PeLevelOpinionConfiguration:25-28`) · 6 phá-vỡ · 2 hỏi-owner (`CeoApprovalThreshold`·`Step.DepartmentId`). OR-of-N XÁC NHẬN (`:689` GroupBy Order) ⇒ owner không tự mâu thuẫn; ⚠️ comment `ApprovalWorkflow.cs:81-82` SAI *"KHÔNG OR-of-many"*. Blast 6+ module (198 hit/23 file). Designer **fe-admin ONLY** (`ApprovalWorkflowsV2Page.tsx`), "Nhân bản"→*"Tạo quy trình mới"*; **0 cảnh báo đang-dùng/0 disable IsActive**. F6 tick `:999-1007` +dây `:54/:110/:159/:177/:605` + fe-user `WorkflowMatrixViewPage.tsx:282` + BE `:41/:230/:188/:368`. CẤM delete-then-insert Levels → diff theo `Level.Id`. Tag `[s155, wf-v2-no-update-cmd, new-version-new-id-unreachable, pointer-index-vs-order]`

---

## [S149 section]

## S149 (2026-07-24→25) — 10 invocation gộp 1 entry [LEAD GHI ON-BEHALF @S150 — M9/B3 theo H2-F3 Coverage-miss (10 lượt → 0 delta sổ, ngoài lưới C11(b) by-design); nguồn: sub-file trong `runs/2026-07-24-S149-{dong-du-5-vong,hoi-tu-bookend,owner-gated-3-khoan}/` + `runs/2026-07-25-S149-adap-backlog/sub-invest-backlog.md`]

- 10 lượt invest @S149: chẩn-đoán **"SE = rules-đủ, máy-thiếu"** (0 script GHI `.session-counter.json` → chuỗi "đo rồi như chưa đo": backfill S146 · tally-rơi S148 · ×27≠33) — ĐỨNG qua gate reviewer-Fable, thành spec hội-tụ-bookend M1-M9. Backlog adap phân-loại **A-12/B-6/C-1/D-3** ("nợ REPORT không phải nợ ADOPT") → wave 6-lane land 23/23. O-2 nguồn thật = depth-axis → **posture-A**.
- #53 trong 10 lượt (ghi sổ garble @S150): L1 **ngược-#53** (return OK, ĐĨA không — vớt journal) · L5 kinh-điển (đĩa cứu) · L7 mất-cả-hai (bù deep-pass). Sub-class mới: ghi-đĩa-trong-lúc-làm = CẦN, KHÔNG ĐỦ.

## [S152 section]

## S152 (2026-07-25) — R1 retention-note không-fabricate [M9 on-behalf lead]
- **KHÔNG fabricate — uncertain thì nói "uncertain" + reason:** finding không chứng được từ đĩa/DB phải khai uncertain kèm lý-do thiếu-chứng, KHÔNG lấp bằng suy-đoán (tiền lệ tốt: A/018 S117 — verify prod-DB `Phase=ChoDuyet` trước khi phán "lũy kế đúng", thay vì đoán theo lời UAT). Claim ≠ chứng: mọi số kèm lệnh. Tag `[s152, r1-retention, no-fabricate-uncertain-reason]`

---

## [S158 section]

## S158 (2026-07-28) — `/fable-real` adap `day-wake-probe-first` [LEAD SEED ON-BEHALF @closeout M9 — mày chạy THẬT (Fable, 222K tok, 20 tool-use) nhưng KHÔNG tự ghi; nguồn = `runs/2026-07-28-S158-day-wake-probe-first/sub-invest-day-1.md` 25.440 B + adap-synthesis]

- **Return CLEAN 0-garble** giữa một closeout mà **7/8 lane khác đều `#53`**. Khác biệt DUY NHẤT: prompt ép **ghi đĩa từng phần trong lúc làm** + **verify RUỘT có chữ trước khi return**. ⇒ datum củng cố: chống `#53` = **thiết-kế artifact**, không phải prompt.
- 🔴 **BÁC 2 tiền-đề của LEAD — đây là giá trị chính của lượt này, không phải bản đề-xuất:**
  (a) *"SE có squash ⇒ có sha mồ-côi"* → đo `cat-file -e` + `is-ancestor` trên 8 marker = **sống 8 / mồ-côi 0**; squash `session-end` chỉ gọt trailing-`wal:` **chưa push**, 6/8 sha đã push. **Vẫn giữ guard** vì tiền lệ S127 dangling có thật + chính feature `/day` tự đẻ điều kiện orphan.
  (b) *"probe nên tái dùng Sàn-3"* → **BÁC bằng bằng-chứng CÙNG CỬA**: Sàn-3 ② HIT ⟂ anchor-delta 0 CLEAN, verdict **NGƯỢC NHAU** vì hỏi **2 câu khác nhau** (*"tồn-tại việc dở"* neo `origin/main` ⟂ *"đổi so điểm dừng"* neo marker pause) ⇒ dựng phép-2 KHÔNG vi phạm B1.
  **Nghề rút ra:** khi lead nêu sẵn một hướng nghiêng, cách bác mạnh nhất là **tìm một cửa mà 2 phép cho verdict ngược nhau** — mạnh hơn mọi lập luận về nguyên tắc.
- **Nghề đo đáng giữ:** anchor = **carrier-commit** `git log --diff-filter=A -1 -- <marker>` (commit ĐẦU TIÊN thêm chính file đó) — 8/8 resolve, **sống-sau-squash by construction**, và **nuốt luôn bẫy-anchor-lệch-1-nhịp** mà hub phải xử bằng bước resolve riêng. Mạnh hơn form của hub.
- **Đo BYTE, CẤM quy token** (chính lỗi làm thư hub trượt vòng r1: dán nhãn "token tự đo" lên proxy ký-tự). `tiep_reload` SE = **122.115 B / 5 nguồn**; nền SE **nhẹ hơn hub 3,6×** ⇒ đừng mượn số hub bán lợi ích.
- **2 phát hiện ngoài đề-bài, cả 2 lead xác nhận:** `docs/HANDOFF.md` segment mới nhất còn **S153** ⇒ nguồn-2 của `tiep_reload` nạp brief cũ **3 nhãn phiên** (vá @S158) · `_tiep-1.md` ghi head-sha **7 ký tự** trong khi 7 marker kia ghi đủ 40 = form drift trong cùng một loại marker.
- Tag `[s158, fable-adap, ghi-dia-cuu-return, bac-tien-de-lead-bang-cua-verdict-nguoc, carrier-commit-anchor, byte-khong-token, seed-on-behalf]`

---

## [S175 section]

## S175 (2026-08-05) — `/fable-real` invest cột DỰ ÁN trong ma-trận ngân sách [LEAD SEED ON-BEHALF @pause cổng C2 — mày chạy THẬT (Fable, 169K tok, 38 tool-use, ~12′) nhưng KHÔNG tự ghi; nguồn = `runs/2026-08-05-S175-duan-budget-column/run.md` + `spec-hang-muc-nhieu-dong-va-cot-du-an-05-08-2026.md`]

- 🔴 **BÁC 2 tiền-đề của LEAD — đây mới là giá trị chính của lượt này, không phải bản đề-xuất:**
  (a) Lead đoán *"cột DỰ ÁN là DI-CHỨNG module Budget cũ bị Mig 50 rút ruột"* → **SAI**. Đo git: cột sinh ở `e33481e` **19-06** (Mig 56), tức **SAU** Mig 50 (13-06) **6 ngày**, và **CÙNG COMMIT** với comment ý-định `PeWorkItemBudget.cs:19` *"DỰ ÁN: hiển thị FE-only (chưa wire BE — sau mới có NGƯỜI DỰ ÁN NHẬP)"* ⇒ **CHỖ-CHỪA-SẴN có chủ đích**, không phải xác chết.
  (b) Lead đo *"hardcode `—` ở ≥3 chỗ"* → **THIẾU**. Thật = **11 ô/app** (Block A 3 + Block B 8), mirror 2 app.
  **Nghề:** tiền-đề đổ mà **kết-luận hệ-quả vẫn đứng** ("phải dựng một tầng, không phải vá 1 cột") — đừng vứt cả kết luận khi vứt tiền-đề.
- 🔑 **Phát hiện ngoài đề-bài, đắt nhất lượt này:** `Project.BudgetTotal` **ĐÃ TỒN TẠI từ Mig 2 — day-1**, wired TRỌN 2 đầu (BE CRUD `ProjectFeatures.cs` + FE cột "Ngân sách" `ProjectsPage.tsx:117` + form `:205`). Chỉ (i) chưa nối vào ma-trận PE, (ii) **DỮ-LIỆU RỖNG: Dev 61/69 dự án NULL** (8 cái có số đều là demo-seed gated-OFF-prod). ⇒ rất có thể CHÍNH LÀ thứ owner nói *"bên mục ngân sách có mục dự án chưa điền vào"* — lớp **"cơ-chế đúng, dữ-liệu không có"** lần thứ 7.
- **Nghề đo đáng giữ:** truy phả-hệ một dòng code bằng **commit sinh ra nó + comment cùng commit**, thay vì suy từ khoảng thời-gian gần nhau. Mig 50 và cột DỰ ÁN cách nhau 6 ngày — đủ gần để đoán bừa là "di-chứng", và đoán đó SAI.
- **Kết cục thực-tế:** owner sau đó chốt *"ko cần so sánh j với số duyệt PRO hay CCM j cả"* ⇒ phương-án live-derive engine đề-xuất **KHÔNG land**; nhưng 2 đính-chính (a)(b) + phát hiện `Project.BudgetTotal` **vẫn còn giá trị** cho lượt sau. Điều-tra không land ≠ điều-tra vô ích.
- 🔸 **META hạ-tầng:** spawn tới với **TASK RỖNG** ("thiếu prompt — lỗi taskList @P0"); mày khôi-phục trọn đề-bài từ `run.md` trên ĐĨA. ⇒ củng cố khuôn **artifact-trên-đĩa > return**: run-folder cứu được cả ca dây-spawn hỏng.
- Tag `[s175, fable-real, bac-tien-de-lead, pha-he-bang-commit-sinh-ra, co-che-dung-du-lieu-khong-co, artifact-dia-cuu-spawn-rong, seed-on-behalf]`

---

## [Context blocks bị rút khỏi index @S180 — verbatim]

### Active workflow schemas (V1 + V2 coexist post-S17)
- **V1 Mig 21 flat** — `WorkflowDefinition` pin cũ, match Dept+PositionLevel.
- **V2 Mig 22-31** — `ApprovalWorkflow` pin PE/Contract, match `ApproverUserId` 1-1 OR-of-N cùng Cấp. Steps(Phòng)>Levels(Cấp). Proposal V2 Mig38, WorkflowApps Mig39. (Mig25 IsUserSelectable · 26 LevelOpinions UPSERT · 30 AllowApproverEditBudget · 31 SkipToFinal→ApproverLevel · 53 cờ-gấp+CeoThreshold · 54 giá-đề-xuất · 58 IsWinner multi + AllowApproverFinalize · 65 Quote.IsSelected per-hạng-mục · 66 ApprovedPrice Min-Max · 67 budget-freeze snapshot).
- **State PE 5:** Nháp / Đã gửi duyệt / Trả lại (TraLai=98) / Từ chối (TuChoi, REMOVED-path S60) / Đã duyệt
- **Mode Trả lại 4:** OneLevel / OneStep / Assignee / Drafter (Phase=TraLai). 3 đầu giữ ChoDuyet lùi pointer. Admin bypass `level.Allow*`.
- **Seeds gating:** `SeedDemoMasterDataAsync` gated `DemoSeed:Disabled` (OFF prod) · `SeedRealMasterDataAsync` UNGATED (62 dự án + 71 hạng mục Excel, per-code idempotent, exact-Code key #75/#76 resurrect risk).

### Counts row (đã derive-được từ STATUS, rút khỏi index)
- ~88 SQL tables (count `.ToTable()` snapshot NOT DbSet) · ~253 endpoints · 68 FE pages · 54 menu keys (`MenuKeys.cs`) · ~354 test · ~71+ gotchas · 14 sub-agents (worker-tier-pin S124) — SỐ STALE THEO THỜI GIAN, canonical → docs/STATUS.md.
