[CLAUDE] Docs: S63 session-end closeout — STATUS/HANDOFF S63 + ef-core count-residual fix + H1/H2 spawn-records (gate PASS 5/5)

- STATUS Recently Done + HANDOFF S63 section (closeout S60-62 + Harness 5/6 + gitattributes)

- ef-core SKILL.md :282/:291 residual 93/49->88/50 (H1 caught 2 missed count-flush lines)

- agent-memory spawn-record S63 x2 monitor (tooling-auditor + harvest-curator, B3 verify->append)

- H2 harvest-gate PASS 5/5 (0 MISS/orphan, 0-byte=0 x8 files, pointer no-overwrite) · H1 tooling canonical-fresh + 2 deep-doc defer-monthly · both self-report claude-opus-4-8[1m] (H5 fallback confirm)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-06-15 21:35:00 +07:00
parent 08c7036302
commit 8e3c360411
5 changed files with 29 additions and 2 deletions

View File

@ -35,3 +35,4 @@ H2 harvest-MD-integrity auditor **SOLUTION_ERP-self**. Read-only + **propose-onl
- **2026-06-11 (S59 `/session-end` 5-trục GATE — tối, 9 body-spawn + closeout-floor):** **GATE PASS 5/5, 0 MISS** (lần đầu 0 on-behalf cần đề xuất kể từ chuỗi 4-MISS post-S57bis). Coverage: tooling ×2 (`:35` start + `:36` end-run mtime 18:15 NGOÀI brief 9-spawn = closeout-floor H1 → reconcile tổng 11) · harvest `:34` · inv recon `:73` · **cicd 6/6 entry RIÊNG #273-278 `:71-76`, sha-chain khớp git log 1:1** (56882ac→9c330d2, topic khớp commit-msg từng run) · 7 role không-spawn 0 phantom. Completeness 4-field 10/10 (#275 honest PASS-PARTIAL PE=1 UAT-leftover). Placement: đúng nhà, stray=0, inv S51→archive VERBATIM moved-not-cut + pointer "curated S59"; nit FIFO swap #273(`:75`)↔#274(`:76`) + archive double-blank. Corruption: 0-byte=0 ×2 nơi · mojibake 3 hit ĐỀU quoted-cũ (cicd:85 = #377 shift ĐÚNG +6 từ :79 — arithmetic shift = số dòng insert, method nhanh phân biệt cũ/mới) · **cicd 54KB/102-dòng (brief nói ~46) + inv 32.9KB over-cap → curate-L2 P1**. Fidelity: bundle BSh2fG2X/D22KfpPc triangulated 5 nguồn (cicd:71 + STATUS:6/:27 + HANDOFF:5 + log:4/:43) · WI=71 ×3 entry · gotcha #61/#62 disk `:1099/:1111` · tooling end-entry tree-state khớp git status độc lập — no-escalate. **2 flag content:** cicd `:53` "Bundle live S59" STALE 1 run (ghi #277 ex7Tc92G/DzUeSk96, live thật = #278 — entry :71 đúng, chỉ status-line lệch) → propose 1-line fix; #275 "09:46:42 sáng" nghi UTC-mislabel = 16:46 chiều local (STATUS:6 nói "chiều nay"; kết luận not-resurrect GIỮ). Tag [s59-end, gate-pass-5/5, 0-miss, cicd-54kb, line53-stale].
- **2026-06-12 (S60 @start RE-REPORT — post-S59 đóng-TRỌN):** Verdict 🟢 CLEAN cả 5 mục — tree clean HEAD `6bf28bf` (18:49:21), 11/11 agent-memory mtime ≤18:42:45 đều TRONG closeout → 0 mồ-côi. Coverage S59 14-spawn ĐỦ: H1 tooling `:35/:36` + H2 ×2 + recon inv `:73` + cicd run-coverage 10/10 #273#282 (6 entry `:72-77` + `:71` #279/280 + extension FINAL-v2 #281/282 — 9 spawn→8 record-unit do supersede-fold, 0 run thiếu). Wave=0 · stray=0 · 0-byte=0 ×2 nơi · user-memory 23 file = index 22 + MEMORY.md 5.6KB khớp · cicd tail `0a` sạch. **2 flag GATE S59-end RESOLVED bởi em main:** `:53` bundle-live → FINAL-v2 `B1DtNT9C`/`D6uF3Mln` #282 ✓ + #275 UTC annotate `:75` ✓. #383 vẫn lạc (`:89``:96` shift +7 đúng arithmetic, annotation guard intact). Chore P1 carry: **cicd 56,480B/103L over-cap 3rd-session + phình 54→56.5KB/buổi** + inv 32,931B → curate-L2 (kèm relocate #383 + FIFO swap #273#274); watch reviewer 30,354B + impl-be 28,585B. Tag [s60-start, clean, flags-resolved, cicd-56kb]. *(em main APPEND B3 — H2-proposed, verify: 0-byte/tree-clean/size đối chiếu độc lập ✓)*
- **2026-06-12 (S61 @start RE-REPORT — S60 đóng KHÔNG trọn):** Verdict 🟡 — S60 2 commit (37122f0 11:53 + 6db195d 14:30) KHÔNG docs-closeout (STATUS/HANDOFF/session-log đều dừng S59). Harvest-MD: 3 delta ĐÃ COMMIT bundle 37122f0 (harvest `:34` + inv ×2 `:73-75` tag s60 đúng-hết-drift + test-spec `:56` +14→254) + 1 mồ-côi cicd dirty `:71` mtime 14:37 entry-kép #283/#284 SANE (bundle-chain B1DtNT9C→akytoBnc→DSvM8h3A + user-chain khớp #282, sha khớp git, 2 test file disk-verified mtime trước commit). Coverage 5/6: **MISS reviewer die-mid-run** (commit body 37122f0 tự khai, file intact KHÔNG 0-byte) → on-behalf APPENDED S61-start (die lần 3: S57bis ×2 + S60). Đợt2 6db195d 0 sub-delta = em-main-direct evidence (16-min turnaround, test mtime 14:27) — flag không phán. Wave=0 · stray=0 · 0-byte=0 ×2 nơi · mojibake 2 hit quoted-cũ. Flags: test-spec baseline 254 stale vs **256 thật (59 Dom+197 Infra — em main dotnet test S61-start)** · CLAUDE.md "240 test" stale · inv `:51` pointer archive nhưng S52 entry chỉ ở git (cut-honest-labeled, nit) · **cicd 61KB/104L over-cap 4th session +4.5KB/buổi → curate-L2 P1 GẤP** + inv 32.7KB. Method ⭐: commit-body = nguồn spawn-evidence khi sub die không để delta (reviewer "die mid-run" tự khai trong msg 37122f0). Tag [s61-start, s60-incomplete-close, reviewer-die-3rd, cicd-61kb]. *(em main APPEND B3 — H2-proposed, verify: commit-body 37122f0 reviewer-die ✓ + test 256 tự chạy ✓ + cicd-dirty diff đối chiếu độc lập ✓)*
- **2026-06-15 (S63 `/session-end` 5-trục GATE — em-main-solo, 0 product-sub):** **GATE PASS 5/5, 0 MISS, 0 orphan.** Session = bootstrap + S63 closeout(S60-62) + check-email + Harness 5/6 adopt + gitattributes; sub DUY NHẤT = 2 monitor (H1+H2 start+end). Coverage: 2 monitor record-proposed (không product-sub miss). Completeness 4-field. **0-byte=0** ×8 file S63-written (session-log 10264B · adap-report H5 4930B/H6 5562B · adap-request 2779B · email 3853B · .gitattributes 348B · 2 reviewer child 1838/1701B). Placement: **fe-admin/.claude GONE** + 2 child đúng `agent-memory/reviewer/` + **pointer no-overwrite (31959B preserved)** + moved-not-cut (git log → S63 `5e6dcc1`). Corruption: U+FFFD=0 ×8. Fidelity: em-main-solo honest self-gate (đúng H6.1 governance→solo + precedent S56) → no-escalate. Wave=0 (S63 no-workflow). **3 flag non-block:** (1) email body-hash `8a247984` H2 không verify scope (3 candidate Python sai formula) — **em main ĐÃ self-verify spec-canonical recompute==stored** (PowerShell), non-issue · (2) **cicd 62KB over-cap 5th-session +2.3KB/S61 → curate-L2 P1 GẤP** (carry 41→54→56→61→62KB) · (3) "CLAUDE.md count stale" = docs/CLAUDE.md FULL (root ĐÃ fresh). Tag [s63-end, gate-pass-5/5, 0-miss, em-main-solo, cicd-62kb]. *(em main APPEND B3 — H2-proposed, verify: 0-byte ×8 + pointer-31959B + tree-clean đối chiếu độc lập ✓)*

View File

@ -34,3 +34,4 @@ H1 tooling-freshness auditor **SOLUTION_ERP-self**. Read-only + **propose-only**
- **2026-06-11 (S58 `/session-end` CHỐT 4-mặt — PARTIAL, return-cut giữa chừng, on-behalf em main ghi hộ):** Return bị cut sau finding chính (verdict 4-mặt đầy đủ KHÔNG kịp emit). FINDING ĐÃ GIAO: docs **KHÔNG stale như brief giả định** — STATUS lines 27/52/53 ĐÃ flush tới `ea793a4`+`3ebaf84`/Run #386 + bundle `DMm9rtNA`/`BUkOMn_Y` (em main flush song song lúc H1 chạy) → bài học brief: "chưa flush" là snapshot lúc spawn, auditor phải re-ground từ disk hiện tại (đã làm đúng). Em main tự chốt phần còn lại từ data sáng: ①SKILL — sáng patched đủ (ef-core ×5 + README + dep-audit), chiều không thêm skill; ②ROSTER 11 + two-tier frontmatter không đổi; ③PLUGIN 18/15/3 không đổi, 0 new-alloc (UI/UX guide AI_INFRA = reference doc, KHÔNG phải plugin/skill — đã cite trong frontend-designer MEMORY S58 entry); ④DOCS — session-end flush hoàn tất (STATUS/HANDOFF/session-log/error-ledger E-008+AS-12). SURPRISE: return-cut class này (chết giữa emit sau khi finding chính đã ra) = nhẹ hơn die-0-byte, finding salvageable từ partial return. Tag `[s58, session-end-chot, return-cut-partial, on-behalf]`.
- **2026-06-11 (S59 @start RE-REPORT — ALL-4-FRESH, 0 drift, tree clean):** Bootstrap sau S58 đóng-sạch (HEAD `1577927`, tree clean). 4-mặt **TẤT CẢ FRESH, 0 drift mới** — session đầu tiên 0-patch kể từ S57bis. ①SKILL 6 project + 23 standalone **unchanged** (list standalone identical S58); 0 skill mới/đổi/mất. ②ROSTER **CLEAN 11=11=11** — disk 11 .md (README.md=doc KHÔNG đếm) = README:3/:13 "11 sub" = STATUS:24 "11"; frontmatter grep = **4 inherit (database-agent·harvest-curator·investigator-codebase·reviewer) + 7 pin claude-opus-4-8** ✅ khớp two-tier H4 (README:3 list khớp chính xác). ③PLUGIN **CLEAN 18/15/3 identical** S58 (settings.json:17-35 verbatim; 3 OFF: pr-review-toolkit:20·code-modernization:22·hookify:27), README:166 "18(15/3)" khớp, 0 new-alloc. ④DOCS **ALL-COUNT-FRESH ground-truthed từ disk:** Mig **49**=49 (disk `Persistence/Migrations/*.cs` đếm 49, cao nhất `20260611044424_AddWorkItemToPurchaseEvaluation`) · menu keys **57**=57 (`MenuKeys.cs` const đếm 57) · gotcha **60**=60 (max `### 60.`) · test 240 (S57bis+S58 log authoritative, KHÔNG attr-count) · tables 93 (cicd Run #379). CLAUDE.md root :53/:66/:133 + STATUS :14/:15/:20/:21 + README roster ALL khớp disk. **Minor narrative-lag (KHÔNG phải drift, KHÔNG patch):** STATUS:6 header "Run #382/#383/#384" thiếu #386 NHƯNG body+bundle:27 đã đúng #386 → cosmetic, defer. Carry-flag bất biến: docs/CLAUDE.md gotcha "(55)" (monthly 07-01) · schema-diagram §16+ Mig 32-49 ERD debt (~17 mig). **Method:** Bash-tool nuốt `$`-var của inline PS → phải `powershell -NoProfile -Command "& {...}"` với escape `\$`; Migrations KHÔNG ở `Infrastructure/Migrations``Infrastructure/Persistence/Migrations` — verify path trước khi đếm. 0 delta đề xuất (clean baseline). Tag `[s59-start, 4-mat-all-fresh, 0-drift, clean-tree]`.
- **2026-06-11 (S59 `/session-end` CHỐT 4-mặt — ALL-FRESH, 0 drift, em main docs-flush verified):** 6 commit code S59 (`56882ac``9c330d2`, Gitea Run #273#278 — KHÁC đếm Run#38x S58, run_number reset) đã COMMIT+prod-verify; em main vừa flush docs (CHƯA commit, tree 5 MEMORY.md M + 4 docs M + 1 untracked session-log). 4-mặt **ALL-FRESH, 0 drift**: ①SKILL 6 project + 23 standalone **unchanged** (0 mới/đổi/mất); `SearchableSelect.tsx` ×2 app = code FE (UI primitive `components/ui/`), **KHÔNG phải skill/plugin** → confirm 0 new-alloc. ②ROSTER **CLEAN 11=11=11** (disk/README:3/STATUS:24); two-tier frontmatter UNCHANGED (4 inherit+7 pin). ③PLUGIN **CLEAN 18/15/3 identical** (3 OFF pr-review-toolkit·code-modernization·hookify), 0 new-alloc. ④DOCS **cross-count CONSISTENT, em main flush ĐÚNG**: gotcha **62**=62 (max `### 62.` = count 62 contiguous, #61/#62=S59 verified `gotchas.md:1099/:1111`) = STATUS:21 "62" = CLAUDE.md root:133 "62 bẫy"; bundle **`BSh2fG2X`/`D22KfpPc`** TRIANGULATED 4-source (STATUS:27 + HANDOFF:5 + session-log:4 + cicd-MEMORY:71 full Run#278 provenance — anti-pattern#3 stable-after-success verified) ✅; session-log `2026-06-11-S59-wipe-tree-pmh-uat-batch.md` EXISTS; HANDOFF:9 S59 section + HANDOFF:5 header 06-11 present; STATUS:16 master-row 71 WorkItems + STATUS:34/:48 In-Progress(none)/Recently-Done S59 present; spec `master-import-data.generated.md` 74 W-rows. **Cross-doc 0 LỆCH/SÓT.** Carry-flag bất biến: docs/CLAUDE.md gotcha "(55)" (monthly 07-01) · schema-diagram §16+ Mig 32-49 ERD debt. **Method-learning:** (a) bundle-hash KHÔNG tin 1-source — S59 triangulate 4 nguồn (đối lại S57bis bài học "session-log không ghi → unverified"); cicd-MEMORY:71 là nguồn provenance giàu nhất (Run#+sha+rotate-from+health). (b) Tool-gotcha PS: `Get-Content -Raw` + `-TotalCount` MUTUALLY EXCLUSIVE → frontmatter-read fail; dùng Grep tool `^model:` thay loop. (c) Run-number S59 reset #273-278 ≠ S58 #38x (run_number API đổi đếm cùng pipeline — KHÔNG nhầm regression). 0 delta đề xuất. Tag `[s59-end, 4-mat-all-fresh, 0-drift, bundle-triangulated-4src, searchableselect-not-skill]`.
- **2026-06-15 (S63 start+end CHỐT 4-mặt — em-main-solo session):** @start audit + @end chốt sau S63 closeout(S60-62) + Harness 5/6 adopt + .gitattributes. **Self-report `claude-opus-4-8[1m]`** ("Opus 4.8, 1M context") = demote-pin ĂN runtime post-restart — **data-point H5:** lead + demote-sub ĐỀU Opus 4.8 lúc Fable-down (two-tier collapse single-tier như H5 mô tả). Verdict: ①SKILL 🟡 count-flush ĐÚNG (Mig 50/88/gotcha 64 ở ef-core desc:3/hist:19/total:74 + README:20/:90 + dep-audit:153) NHƯNG 2 residual ef-core `:282`+`:291` kẹt 93/49 → **em main FIXED in-session**. ②ROSTER 🟢 11=11=11, two-tier frontmatter (4 inherit+7 pin) đúng, agents/README:10 caveat H5 consistent runtime. ③PLUGIN 🟢 18/15/3 identical, **0 new-alloc** (H5/H6=governance · .gitattributes=hygiene — KHÔNG skill/plugin mới). ④DOCS 🟡 canonical FRESH (root CLAUDE.md:53/:66/:133 + STATUS + HANDOFF + agents/README khớp state THẬT) · 2 stale deep-doc defer-monthly (docs/CLAUDE.md full 58→64/93→88 + schema-diagram §16+ Mig 32-50). Method ⭐: system-reminder claudeMd header = pre-session snapshot (hiện "49 mig→93" cũ) → re-Read line thật (root=50→88 fresh), KHÔNG tin context-injection. Tag [s63, 4-mat, model-opus-confirm-h5, ef-residual-fixed, canonical-fresh]. *(em main APPEND B3 — H1-proposed, verify: self-report model + ef-core :282/:291 fix + canonical grep độc lập ✓)*

View File

@ -279,7 +279,7 @@ sqlcmd -S .\SQLEXPRESS -d SolutionErp -U vrapp -P <pw> -i migrate.sql
## Code pointers
- `src/Backend/SolutionErp.Infrastructure/Persistence/ApplicationDbContext.cs` — DbSet cho 93 bảng (49 migration)
- `src/Backend/SolutionErp.Infrastructure/Persistence/ApplicationDbContext.cs` — DbSet cho 88 bảng (50 migration)
- `src/Backend/SolutionErp.Infrastructure/Persistence/DesignTimeDbContextFactory.cs` — EF tooling factory
- `src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs` — seed + warn + migrate runtime + backfill (idempotent reconcile pattern)
- `src/Backend/SolutionErp.Infrastructure/Persistence/Configurations/` — IEntityTypeConfiguration<T> per entity
@ -288,5 +288,5 @@ sqlcmd -S .\SQLEXPRESS -d SolutionErp -U vrapp -P <pw> -i migrate.sql
## Related
- `docs/database/database-guide.md` — conventions + migration workflow chi tiết
- `docs/database/schema-diagram.md`**ERD 93 bảng** + §11 PE + §12 Budget + §13 PEDeptOpinions (Mig 15) + §14 ApprovalWorkflow V2 (Mig 22-25) + §15 PE Level Opinions V2 (Mig 26); §16+ Mig 27-49 detail pending (xem migration table)
- `docs/database/schema-diagram.md`**ERD 88 bảng** + §11 PE + §12 ~~Budget~~ (REMOVED Mig 50) + §13 PEDeptOpinions (Mig 15) + §14 ApprovalWorkflow V2 (Mig 22-25) + §15 PE Level Opinions V2 (Mig 26); §16+ Mig 27-50 detail pending (xem migration table)
- `docs/gotchas.md` #7, #17, #38 — migration pitfalls + Identity 4-field rename

View File

@ -6,6 +6,25 @@
---
## S63 (2026-06-15) — Docs-closeout S60-62 + adopt Harness 5+6 + .gitattributes eol=lf (3 commit, em-main solo)
**Anh: `/session-start` → bootstrap bắt drift (docs S59 vs git S62 + stray reviewer) → chốt "đóng trọn closeout (A)" → `/check-email ai_infra` (mailbox trống, guide cũ intact) → "check kỹ harness 5/6" → `/adap-apply` cả 2 + `/send-email` ai_infra → "làm hết + session-end".**
**Done (3 commit `5e6dcc1`→`dbbf89a`→`08c7036`, đều push):**
- **Closeout S60-62:** reconcile stray reviewer cwd-misland (move+pointer, no-overwrite) + count-flush 4 file (Mig 50·88 bảng·263 test·64 gotcha·53 menu·Budget REMOVED) + session-log .
- **Harness 5** (model-fallback): SE đã de-facto fallback FableOpus 4.8 1M (Fable/Mythos down 06-12 no-ETA) book caveat + session-start BƯỚC 0.6 H5.1 check; KHÔNG RCA/memory-permanent (external outage blameless). adap-report 06-13.
- **Harness 6** (governed-ultracode): H6.1 auto-HMW mode-ON (ultra-on+T4) + H6.2 hmw.js role-lessinherit lead; H6.7 đã sẵn S49. adap-report 06-15. Email ai_infra (`8a247984` spec-canonical, sửa mis-stamp S58).
- **`.gitattributes`** broadcasts eol=lf + adap-request federated.
**🔴 NEXT SESSION (anh):**
- **⚠ RESTART CLI (đầu việc):** activate `session-start` BƯỚC 0.6 (H5.1 model-check) + `ultra-on`/T4 H6.1 (auto-HMW) command no hot-reload. hmw.js H6.2 đã live (no-restart).
- **H5.6 restore** khi Fable 5 về (no-ETA): đổi lead lại Fable + spawn-test confirm `claude-fable-5[1m]` + gỡ caveat `agents/README` + báo update AI_INFRA.
- **Ops của anh (giữ S58/S59):** tzutil VPS · anh Chương email dọn typo · báo 5 real staff password `User@1234567` · gán CNTT lock nv.cao/nv.truong.
- **Backlog:** test-after guard suppliers authz + LockDemoSampleUsers · F4 approver-edit-budget UI (BE scope sẵn, chờ anh Kiệt UAT) · **monthly audit 2026-07-01** (curate cicd-monitor L1 **63.6KB** over-cap lần 5 + schema-diagram §16+ Mig 32-50 ERD + docs/CLAUDE.md full count-flush).
- **Cert** `api.solutions.com.vn` ~2026-07-23 (auto-renew ~06-23).
---
## S60S62 (2026-06-12→06-13) — PE ngân sách per-gói-thầu (Mig 50, XÓA Budget) + workflow polish + soft-warning [4 commit prod-verified · docs bù S63]
**Anh Kiệt (FDC) UAT realtime eoffice → chuỗi chỉnh PE: ràng buộc gửi-duyệt + gỡ "Từ chối" (S60) → ngân sách gói thầu theo Excel + XÓA module Budget cũ (S61 Mig 50) → vượt ngân sách cho lưu, cảnh báo mềm (S62). 3 session ship code KHÔNG closeout docs → S63 `/session-start` bù (git log phát hiện drift S59→S62).**

View File

@ -45,6 +45,12 @@
## ✅ Recently Done (newest on top — 3 session; cũ hơn → session logs)
### S63 (2026-06-15) — ✅ Docs-closeout S60-62 (bù 3 session) + adopt Harness 5+6 + .gitattributes eol=lf — 3 commit em-main solo
- **Closeout S60-62** (`5e6dcc1`): drift bắt `/session-start` (git log: docs dừng S59 vs HEAD S62 + Mig 50). Reconcile **stray reviewer cwd-misland** (2 file concanonical + pointer no-overwrite, xóa `fe-admin/.claude`) · commit harvest (cicd MEMORY Run #286 + gotcha #63/#64) · **count-flush 4 file** (Mig 4950 · tables 9388 · test 240263 · gotcha 6264 · menu 5753 · Budget module REMOVEDPeWorkItemBudgets) · session-log `2026-06-12-S60-S62-*`.
- **Adopt Harness 5+6** (`dbbf89a`): **H5 model-fallback** (SE đã de-facto Opus 4.8 1M do Fable down 06-12 book caveat agents/README + session-start BƯỚC 0.6; KHÔNG RCA/memory-permanent) · **H6 governed-ultracode** (H6.1 auto-HMW mode-ON + hmw.js role-lessinherit; H6.7 role/memory-fidelity đã sẵn S49) · 2 adap-report + email ai_infra (`8a247984` spec-canonical self-verified, sửa mis-stamp S58).
- **`.gitattributes`** (`08c7036`): `broadcasts/** eol=lf` (ổn định email body-hash cross-checkout) + adap-request federated (mis-stamp CLASS propose floor eol=lf lên AI_INFRA).
- **State:** test 263 (N/A re-run 0 code change) · RAG 2423 · lead **Opus 4.8 1M** (H5 fallback, Fable down). **Anh RESTART CLI** activate session-start BƯỚC 0.6 + ultra-on H6.1 (command no hot-reload; hmw.js H6.2 đã live). session log S60-62 + 2 adap-report + 1 adap-request.
### S60S62 (2026-06-12→06-13) — ✅ PE workflow polish + ngân sách per-gói-thầu (Mig 50, XÓA module Budget) + soft-warning vượt NS — 4 commit prod-verified Run ~#283→#286 [docs viết bù S63]
- **S60 `37122f0`+`6db195d`:** ràng buộc gửi duyệt đủ 4 thông tin mục 3 (đơn vị được chọn + giá chào>0 + ngân sách + bảng so sánh đính kèm, áp cả Admin) + rename mục 3 "Đơn vị NCC/TP được chọn" + bypass drafter-in-chain V2 bước-đầu (audit 3 tầng) · gỡ hành động "Từ chối" khỏi cả 4 policy (chỉ còn Duyệt/Trả lại, guard chặn TuChoi mọi caller). Test 240→256.
- **S61 `79ef8da` Mig 50 `ReplaceBudgetModuleWithPeWorkItemBudgets`:** bảng `PeWorkItemBudgets` per-gói-thầu (Dự án×Hạng mục, UNIQUE filtered) + **XÓA module Budget cũ** + drop PE/Contracts.BudgetId + backfill BudgetManual→BudgetPeriod TRƯỚC DropColumn (phiếu UAT giữ số) + bảng "Tổng hợp ngân sách trình ký" 2-block 9-dòng Excel anh Kiệt + nhập role PRO/CCM (Forbidden fail-closed) + XÓA FE budgets pages/types/menu `Bg_*`. Test → **263** (45D+218I). database-agent advise (no FK vật lý · DropIndex trước DropColumn SQL 5074 · IN-list). **gotcha #63** (EF RenameColumn sai-semantics) + **#64** (Design-DB 0-rows ≠ Dev-DB data-migrate).