Files
solution-erp/.claude/agent-memory/investigator-codebase/MEMORY.md
2026-07-12 19:26:19 +07:00

116 lines
21 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Investigator-Codebase Agent — Persistent Memory
> **Persistent diary cross-session.** Auto-injected first ~200 lines at spawn (L1 HOT).
> Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · L2 `archive/` on-demand · L3 RAG `search_memory` just-in-time. Keep entry ≤ 1.5K chars (gotcha #53).
> Full verbatim history pre-S40 → git `d2f52ba` + `archive/2026-05-q1..q4.md` + `archive/2026-06.md`. 🗺️ **Lookup map: `archive/_INDEX.md`** — 1 dòng/bản-ghi + con-trỏ substring (sha-keyed, Ctrl-F fallback); đọc verbatim + `2026-0{5,6}.gist.md` theo nhu cầu. **S80 curate: moved 15 recon entries S65→S76 + 2× 06-20 → archive.**
> **Renamed S39:** investigator → investigator-codebase (internal half; external → investigator-api).
---
## 🎯 Role baseline
Read-only INTERNAL audit SOLUTION_ERP codebase. Tools: Read, Grep, Glob, Bash + 5 RAG MCP. Output: concise findings <500 words + file:line refs. Skills: `contract-workflow` + `permission-matrix` + `ef-core-migration`.
## 🚫 Split boundary (S39)
- MINE: internal SQL/EF/grep/reference mirror, sqlcmd schema scan, controller audit, migration diff, count grounding
- NOT: external docs/CVE/lib `investigator-api` · write implementer · test test-specialist · architecture decision em main
---
## 🆕 2026-07-12 (S113) — Supplier import v2 invest ensemble (5-lane, Opus MAX, RETURN-only) `[engine: fable-clone-ensemble · Opus-S113]`
Em-main harvest @closeout (H2 5 lane RETURN-only; content `runs/2026-07-12-S113-supplier-import-v2-invest/` journal.jsonl + spec).
- **task:** invest cách làm Supplier import v2 (R1-R7) 5 lăng-kính CÙNG vai investigator-codebase: schema-data-model · import-service · fe-ux · public-visibility-consumers · dedup-validation. `wf_e7896ca6-901`.
- **verdict:** 4/5 structured PASS + 1 lane `public-visibility-consumers` **#53-garble** em-main-solo grep recover (consumers = PE picker `PeDetailTabs:2222` + `ContractCreatePage:321` + dashboard, đều qua ListSuppliersQuery).
- **learned:** Conflation gốc `Supplier.Code` comment " NCC" nhưng S112 nhồi c4 viết-tắt vào R3 muốn tách. Ensemble hội tụ 6 điểm (IsPublic-bool · dedup-MST+Code-backstop · backfill · PublishCommand-riêng · BE-template · re-bake-token) + chẻ đôi D1 (schema-lens=A vs import-lens=B) anh chốt A.
- **surprise:** visibility-lane garble ĐÚNG lane quan-trọng nhất (R4/R6 ẩn draft); recover-lane spec-flag NHƯNG FE implement vẫn sót wiring 4-picker reviewer bắt draft-leak. Prod 37 NCC (không 22 ước). Tag `[s113, fable-clone-ensemble, supplier-import-v2, ma-ncc=code, visibility-garble-recover, dedup-mst]`.
## 🆕 2026-07-12 (S112) — 2 fable-clone invest ensemble (Opus MAX, RETURN-only) `[engine: fable-clone-ensemble · Opus-S112]`
Em-main harvest @closeout (H2 gate lanes RETURN-only, content verbatim `runs/2026-07-12-S112-{supplier-excel-import,pe-signoff-save-advance}/sub-invest-*.md`).
- **task:** (A) Supplier Excel-import mapping/approach/edge `wf_e2f23a84` · (B) PE sign-off save-advance current-flow/change-design/reject `wf_fd8f2bfe`; 3 lane/ensemble.
- **verdict:** cả 2 PASS_WITH_CONCERNS. Supplier 27/27 field bijective (30 cột27, 2 audit-col=owner-call). PE design = **sửa 1 CHỖ** gỡ/gate `ApplyDrafterBypassOnSubmitAsync`.
- **learned:** dedup Code `Ordinal` vs DB unique-index **CI-collation** normalize case TRƯỚC dedup+store (MAJOR, cả-3-lane-SÓT, reviewer bắt); PE "comment-own-boxsaveadvance" cơ-chế ĐÃ sẵn, chặn = bypass-feature S60 cần đảo.
- **surprise:** Supplier Approach-B (extend seed) ĐÃ SHIP prod (Mig 62, 4 NCC live invest bắt spec-"partial" SAI); PE EDGE-5 latent→**REACHABLE** (drafter forge Reject phiếu DaDuyet của mình). sub-file naming swapped (harvest reads content). Tag `[s112, fable-clone-ensemble, supplier-mapping, pe-bypass-a1, edge5-reachable]`.
## 📋 Patterns proven (apply confidently)
### Schema scan via sqlcmd
```bash
sqlcmd -S "(localdb)\MSSQLLocalDB" -d SolutionErp_Dev -Q "..." # runtime API (primary)
sqlcmd -S "(localdb)\MSSQLLocalDB" -d SolutionErp_Design -Q "..." # ef tooling
ssh vietreport-vps "sqlcmd -S .\SQLEXPRESS -d SolutionErp -U vrapp -P '...' -Q '...'" # prod
```
Queries: `sys.columns`, `sys.triggers`, `__EFMigrationsHistory`, `COUNT(*)`, `sys.indexes`.
**Gotcha 2 LocalDB distinct** (`feedback_designtime_runtime_db`): `_Dev`=runtime (appsettings.Development), `_Design`=`dotnet ef` default. Prod password fallback `C:\inetpub\solution-erp\api\appsettings.Production.json` khi `$env:PROD_DB_PASSWORD` empty.
### Controller / wire-claim audit
- Grep `\[Route\("api/[a-z]+"\)\]` enumerate controllers · `\[Authorize(Policy = "..."` per-action policy (gotcha #44 silent 403 class-level quá strict)
- Grep `// Mock` / `alert(` / `setEditing(null) // close UI` wire claim bugs · `IActionResult` vs `ActionResult<T>`
### Smoke verify catalog
Bearer từ `POST api.solutions.com.vn/api/auth/login` status matrix expected vs actual + file:line evidence.
### Memory cross-reference
30 user-memory tại `C:\Users\pqhuy\.claude\projects\D--...\memory\MEMORY.md` (index). Key: per_chunk_commit · uat_skip_verify · designtime_runtime_db · per_nv_permission_scope · ef_migration_backfill_reorder · workflow_fanout_reliability · canonical_spec_over_broadcast (S79).
### External research → DEFER `investigator-api` (split S39)
---
## ⚠️ Anti-patterns
Skip MEMORY update · Vague "seems like/probably" · Missing file:line · >500 words · ❌ Scope drift to architecture recommendation (em main decides)
---
## 🧠 SOLUTION_ERP context essentials (S80 verified — re-ground từ docs/STATUS.md canonical)
- **DB:** Dev `SolutionErp_Dev` · Design `SolutionErp_Design` (distinct) · Prod `.\SQLEXPRESS`/`SolutionErp`/`vrapp` via SSH `vietreport-vps`
- **Migration path:** `src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/*.cs` (⚠️ NOT root `/Migrations/`). **57 mig**, last `AddPeSuggestedPriceNotes`.
- **Counts S80 (canonical docs/STATUS.md):** 57 mig · **88 SQL tables** (count `.ToTable()` ModelSnapshot NOT DbSet) · ~253 endpoints · 68 FE pages · **54 menu keys** (BE `MenuKeys` const) · **354 test** (45 Domain + 309 Infra) · **71 gotchas** (format `### N.`) · 30 user-memory · 6 skills · **11 sub-agents** (all-inherit H8)
- **Tech:** .NET 10 Clean Arch (Api→Application←Domain + Infra) + CQRS MediatR + EF Core 10 + 2 React 19 Vite 8 TS 6 (fe-admin :8082 + fe-user :8080) + SQL Server + Gitea CI + IIS
- **Prod:** api/admin/eoffice.solutions.com.vn · Gitea `git.baocaogiaoduc.vn/vietreport-admin/solution-erp` (Actions API `/api/v1/repos/.../actions/tasks` NOT `/runs` 404, cache stale ~2min gotcha #46 — cross-check VPS mtime). Bundle live admin `CsJetgZH`/user `BVS0ApIm` (Run #330).
- **Auth:** `admin@solutions.com.vn/Admin@123456` (full) / `nv.test@solutions.com.vn/TestUser@123456` (Drafter). Response `accessToken`+`refreshToken`+`user`. Password ≥12 chars.
---
## 🔄 Active workflow schemas (V1 + V2 coexist post-S17)
- **V1 Mig 21 flat** — `WorkflowDefinition` pin PE/Contract cũ. Match Dept+PositionLevel.
- **V2 Mig 22-31** — `ApprovalWorkflow` pin PE/Contract mới, match `ApproverUserId` 1-1 OR-of-N cùng Cấp. Steps (Phòng) > Levels (Cấp). PE + Contract đã wire V2 (Mig 32+33 S29). Proposal V2 (Mig 38). WorkflowApps skeleton (Mig 39).
- Mig 25 IsUserSelectable · Mig 26 PE LevelOpinions UPSERT · Mig 29 Allow* per-NV · Mig 30 F4 AllowApproverEditBudget · Mig 31 SkipToFinal→ApproverLevel · Mig 53 cờ-gấp+CeoApprovalThreshold · Mig 54 giá-đề-xuất PRO/CCM+giá-chốt · Mig 56 ProInitial/ProAdjust · Mig 57 ghi-chú-giá.
- **State machine PE 5 trạng thái:** Nháp / Đã gửi duyệt / **Trả lại (TraLai=98)** / Từ chối (REMOVED-S60 hard-guard) / Đã duyệt
- **Mode Trả lại 4 option per-Level:** OneLevel (lùi 1 Cấp) / OneStep (lùi Bước trước) / Assignee (pick NV đã ký) / Drafter (Phase=TraLai). 3 mode đầu giữ ChoDuyet lùi pointer. Admin bypass `level.Allow*`.
---
## 📅 Recent activity (compressed — full verbatim → `archive/2026-06.md` via `archive/_INDEX.md`)
- **2026-07-12 (S112+ Supplier-import-v2 LENS-3 FE-dialog-UX invest `wf` fable-clone):** Task R2/R3/R7 FE. Ground-truth: SupplierImportDialog.tsx + SuppliersPage.tsx **SHA-identical 2-app** (`6313529c`/`e9143d93`) — but types/master.ts DRIFTS (fe-user thiếu `Department.parentId` Mig51, Supplier-portion vẫn mirror). Dialog = 2-step preview→confirm, table READ-ONLY (`:284-325`), **round-trips `preview.rows` verbatim** (`:190`+`:132-134`) → per-row edit ĐÃ khả-thi cho R3 (mutate `row.code`→confirm). Confirm gate `errorCount>0` disable (`:191`). **R2:** 0 template endpoint tồn tại; `ExpectedHeaderTokens` 30-token baked `SupplierExcelImportService.cs:35-68` = single-source cho BE-gen .xlsx row-4 (test Case6 chứng round-trip); blob-download precedent `PeDetailTabs.tsx:3273-79` (`api.get responseType:'blob'`+createObjectURL). **R7:** SuppliersPage cols code/name/type/taxCode/phone/actions (`:174-206`) — **KHÔNG có status/public col**; `Supplier` type có `status` (biz-status ≠ public) NHƯNG **0 field isPublic/visibility** (grep⌀) → R4/R7 cần field MỚI. **Mã NCC=Code** (Supplier.cs:7 comment + col4 TÊN-VIẾT-TẮT→Code). ⚠️**authz-mismatch:** import BE `[Roles=Admin,CatalogManager]` (`SuppliersController.cs:64,77`) vs FE btn gate `Suppliers/Create` (mở-all S59) → non-admin thấy nút→403; template sẽ kế-thừa. NO new menuKey/route. Tag `[s112, supplier-import-v2, fe-lens3, sha-mirror-drift-parentId, expectedheadertokens-template, no-ispublic-field, import-authz-mismatch]`.
- **[→ git+session-log 07-07] S105 BVAAU cross-repo auth RCA:** Q1 root-cause = FE Home MÙ session (bundle cũ relative `/api` trên site TĨNH `web.config` loại `^/api/``/api/auth/me` 404 → anonymous); fix API_BASE-absolute `51c69fb` LIVE. Q2 CRM1 hở 2 tầng (FE soft + API `enforceCrmGate:false`) → flip `AUTH_ENFORCE_CRM_GATE=true`. Q3 Zalo "User_ID" KHÔNG có UI. Class **"hub+site-tĩnh relative-`/api` chết im prod"**; #53-garble-7 → SendMessage-resume recover. *(verbatim → archive/2026-07.md)*
- **[→ 07-12 LENS-3 entry above + git 07-06] S104 Supplier 30-field 🅰️ schema-invest WF `wf_5ac2cdb0`:** SUPERSEDED anchors giữ: ClosedXML 0.105.0 = Excel-standard (KHÔNG OpenXml-raw, `csproj:8`); reuse-existing-cols>parallel; `UpdateSupplierCommand.cs:49-57` blind-set=latent#73; seed fill-nulls-if-exists (`DbInitializer.cs:2781`); `SupplierDto` hand-projected 2-site (`GetSupplierQuery.cs:21`+`ListSuppliersQuery.cs:48-50`); `Dialog.tsx:48` max-h-70vh; extract `ui/PathLink.tsx`. Chốt Mig 62 +18 nullable. *(verbatim → archive/2026-07.md)*
- **[→ git+session-log 07-03 + adap-reports] S101 H19-adopt Lane-2:** map reviewer=review-gate / investigator=ground-truth-lane; 12-pt tier-checklist ALL✅ (11/11 inherit, C3 no-`[1m]`-in-frontmatter); toggle-marker MUST copy `.gitignore:87` last-match placement; VACUOUS-MET all-inherit+Fable. *(verbatim → archive/2026-07.md)*
- **[→ git+session-log 07-02 + adap-reports] S100 H18-adopt WF1:** ⭐ ghost-wire-class **config-key-defined-but-unread** (`budget.json:54-55` script re-hardcode same-value→no-flag; catch=grep-key-across-scripts); cron=ghost-wire (CronList=0); `_ledger` orphan-catch 0/15-lifetime. *(verbatim → archive/2026-07.md)*
- **2026-07-12 (S112-b) Supplier import-v2 LENS-4 public/visibility recon (anh Kiệt FDC, RETURN-only):** ⭐ **3 SELECTION consumers ALL hit `GET /suppliers` (ListSuppliersQuery)** → (1) master `SuppliersPage.tsx:83` ×2-app (admin, MUST see draft opt-in) (2) PE add-supplier dropdown `PeDetailTabs.tsx:2222` pageSize=1000 (3) Contract create `ContractCreatePage.tsx:321` pageSize=200. **DISPLAY-of-existing (join by stored SupplierId → MUST NOT filter)**: ContractFeatures:293/392/434 · ContractWorkflowService:168/373 · ContractExcelExporter:44 · GetDashboardStats:42 (TopSuppliers group-over-contracts → draft never appears) · PeFeatures:560/728/874/952 · CreateContractFromEvaluation:63/168. **WRITE-GUARD backstops** (validate-supplier-exists on attach → add draft-reject): `ContractFeatures.cs:64` + `PurchaseEvaluationSupplierFeatures.cs:49`. **NO IsPublic field today**; `SupplierStatus` enum = business (DangHoatDong/Blacklist/NgungHopTac) NOT visibility. **SupplierConfiguration.cs:47/50** = Code unique-filtered `[IsDeleted]=0` + IsRequired + `HasQueryFilter(!IsDeleted)` only. c4 Tên-viết-tắt→Code (SupplierExcelImportService:249) + import HARD-requires Code (:103-108) → conflicts R3 "Mã NCC nhập sau, Excel không có cột". DTO hand-projected 2-site (List+Get). Rec: fail-closed default (GET public-only → dropdowns unchanged, S87/S88-safe) + stored `IsPublic bit`. Tag `[s112b, supplier-visibility, lens4, fail-closed-default, no-global-queryfilter]`.
- **[all verbatim → archive/2026-07.md] S98 verify-lane (detector 28→25, 8 derived-stale=FP vs canonical 61/89/440/79; grep exact misses README variant) · S97 feedback-audit (#77/#78/#79 `gotchas.md:1301/1317/1325`; #53-garble×6=cicd MEMORY-self-target ~17.5KB; Mig60 wrong-table Approvals→Mig61 Changelogs) · 07-01 Supplier-predecessor SUPERSEDED by 07-06 · S93 MFE denom=marks/AS/guards dedup-AS-xref=29, coverage exact-id OR ≥2-content-word.**
- **PE FROZEN-Mig59 patchwork + go-live recon cluster (S87→S89, 8 entries verbatim → `archive/2026-06.md`):** key catches — AREA-4 **LATENT #73-class BUG** HoSoLink absolute-set `PurchaseEvaluationFeatures.cs:280` but PeHeaderForm PUT OMITS→clears (2 PUT mutually destructive, no preserve-test) · AREA-3 AllowApproverFinalize AUTO(Mig58)+finalizeByCcmDelegation OPT-IN(Mig54) coexist AUTO-first, ApplyApprovedPrice allow-list {Ncc,ProMin,ProMax,Ccm} · AREA-2 budget-matrix band-aid `PeSuggestedPriceFeatures.cs:153-199` PRO=drafter vs CCM=role authz-asymm · AREA-6 FE all 6-comp+3-pages SHA-mirror 2-app, #70 stale-echo · S89 AllowApproverFinalize-NOTE **GAP BE-field-MỚI** (flag only `currentLevelOptions`, DTO no-carry→expose EndsBeforeCeo) · 06-24 winner=SINGLE `SelectedSupplierId` derived-3-site, terminal=per-Level bool · 06-23 urgent authz asymmetric, PE-create dropdown `PeWorkspaceCreateView.tsx:94`.
- **2026-06-20 governance recon (both → archive/_INDEX):** (a) landing-map — `harness-11-engine.md`=CANONICAL engine (D5/6/7 safety-tier+D8 one-dir-lock+D9 single-writer+D10 Bash-residual+CAVEAT no-OS-hook); `error-ledger.md`=§L.a AS-1..13+§L.b 7-step; rules.md §6.6=objective-criteria; report-before-stamp ⊂ D7 (extend not duplicate→C3 vocab-fork). (b) Harness-14 = age/recency-decay KHÔNG căn-cứ cắt feature; `memory-budget.json` 0 decay `keep_floor=5`=newest-protect drains-OLDEST; detectors canonical-anchor-vs-STATUS+disk 0 age-window; EVAL `golden-set-solution_erp.jsonl` 14q recall@5≥0.7 weekly-manual; anti-downgrade=H8 all-inherit PARTIAL (no generic rule grep 0).
- **PE recon cluster (S69→S76, verbatim → _INDEX):** "Giá chào thầu" mục-c=`WinnerQuoteTotal`=SUM(Quote.ThanhTien WHERE supplier==Selected) DERIVED 3-site; Budget gate=PURE ROLE no-phase (`canEditPro/Ccm` `PurchaseEvaluationFeatures.cs:800-801`); submission-count-lock NEXISTS (grep 0); Value-threshold HOOK B=`ApproveV2Async :816-845`; PRO/CCM/CEO=`Procurement/CostControl/Director` shorthand; V2 routing IGNORES roles (=ApproverUserId) 100% LINEAR.
- **Office/HRM recon cluster (S65→S69, verbatim → _INDEX):** 21 `Off_*` keys, 10 office pages `{fe-admin,fe-user}/src/pages/office/` SHA-mirror (exc MyAttendance+AttendanceReport admin-only); golive-flip=remove `RevokeTemporarilyHiddenModulesAsync` `DbInitializer.cs:2040`; Employee master-detail EXISTS, Dept FLAT pre-Mig51; NamGroup PURO=UI-skin hardcoded-navTree; **gotcha #66** `index.css h1-4{color}` OUTSIDE @layer→TW-v4 unlayered wins→heading MUST `text-white!`.
- **Governance/Harness recon cluster (S71, → _INDEX):** H8 all-inherit FULLY adopted both layers (12/12 frontmatter + hmw.js resolveModel); **run-trace "TRACKED" = 2-level** (`git check-ignore` eligible vs `git ls-files` committed — model works only post `git add`); G-015 containment shift (Harness-2 "mọi tracked=vi-phạm" → H10 "tracked NGOÀI run-folder+code-disjoint=vi-phạm"). **path-trap:** bare `runs/` from repo-root = 0 → actual `.claude/workflows/runs/` (22 tracked). detector refine(b) = `.claude/hooks`/`.claude/scripts` not-exist (now S75 has `scripts/governance-detectors.ps1`).
- **[→ git pre-S60]** S60 recon#2 V2-engine-map (ApproveV2Async:446-634 guard+UPSERT+advance; skipToFinal F2:561-602 precedent) · S60 PE Section-3 submit-guard ROLE-only. Full text git.
- **[→ archive/2026-06.md + git]** S52 P11-D/E/F 6-gap recon · S50 HrmConfigs add-kind 11-spot · S51 gotcha #57 EXT reachability (curated S59).
- **[→ archive/2026-05-q4.md + git d2f52ba]** S29-S37: clean-room > NamGroup-port verified 4× · Pattern 12-bis cross-module mirror · FK+freetext dual-write.
- **2026-07-10 (S108 first-real-run H19) `[engine: fable-real-single · Fable-S108]`** (em-main harvest B3, GAP-2/3): Task cite-audit 3 artifact S108 (fable-real-runbook 610-line + adap-request hot-reload + email-draft), ~111 anchor. Verdict **PARTIAL — 103/111 exact**: 7 off-by-1/2 (cụm reviewer:37-56 + investigator:46/:77 — systematic quanh code-fence) + 1 drift-note-stale (runbook:123 “9 vai” trong khi engine :328 đã 10) + email-fact FALSE **bắt trúng bẫy honesty** (hmw.js:31 chưa-sửa lúc audit → em-main vá thật sau verdict). Learned: worker-draft cite lệch ±1-2 quanh fence → audit MỞ ĐÚNG DÒNG đừng tin range · drift-note về file khác re-check ngay-trước-commit (canonical có thể được patch song song). Surprise: **meta-drift 2 tầng** — đoạn cảnh-báo-drift tự drift vì engine update TRƯỚC khi note viết xong. Return dòng-1 VERDICT-header chuẩn, 0 garble.
- **2026-07-12 (S111 H22 WAL deep-pass) `[engine: fable-real-single · Fable-S111]`:** H22 WAL adopt → READY_WITH_NUANCES + spec 3-mục (em-main gov/settings · w1 pause+tiep · w2 start/end delta · w3 hook+README). Chốt: (1) `.claude/settings*.json` KHÔNG tồn tại → hooks-entry CREATE mới; hook = STAGED-until-verified (S100 ghost-wire, chỉ claim khi thấy `wal:` commit phiên mới). (2) engine`:402` no-OS-hook = MÔ-TẢ (CAVEAT) không phải luật cấm; `:116` E.3 "hook fails-open ≠ gate" → persist-only TƯƠNG THÍCH, update :402; ACTIVE-MARKS 0 mark cấm-hook; H5 start`:41` chỉ cấm hook-switch MODEL. (3) AS-6 KHÔNG tăng: 2 runtime .json gitignored (`.gitignore:124-125`), hook commit LOCAL — push-set ≡ hôm nay. (4) cmd-PATH Git Bash trước WSL, bash 5.2.26 OK. (5) `.gitattributes` exists broadcasts-scoped → append `*.sh`; repo 0 .sh = zero churn. (6) 16 command 0 trùng pause/tiep. (7) Stop-hook fire chỉ TURN-boundary → chết giữa workflow-turn = vật-liệu DISK uncommitted, /tiep đọc cả git status/disk. (8) run.md thiếu taskList snapshot. Learned: "luật cấm hook" phải phân MÔ-TẢ vs LUẬT trước khi đòi carve-out. L1@19.8KB → suggest em-main curate.
- **2026-07-11 (S110 H21+MTv3 deep-pass) `[engine: fable-real-single · Fable-S110]`:** Task ground-truth 2 broadcast (H21 spec-file+per-invocation · MTv3 owner-choice) + inventory TOKEN toàn repo + SPEC 3-mục. Verdict **PASS**: (1) **12 persona file SẠCH 0-hit** fable/engine-token (grep 2 vòng cả `engine-đắt|top-model|ensemble`) — NGƯỢC hub vòng-1 bắt persona-phụ lỗi; (2) MTv3 self-check regex §5 chính-thức **0-hit** nhưng extended "lead LUÔN top-model" bắt 5 ACTIVE (engine:332 K.D · runbook:140/:455 · fable-real.md:17 · mark ACTIVE-MARKS:19) = **regex-heuristic-miss class** — sister diễn-đạt khác cụm regex; (3) **hmw.js:38 comment "tier:'fable' khi hệ-trọng" = xung-đột MTv3 §1.3/H21 §3** (đường nâng hạng-nhất DUY NHẤT = owner gõ; comment cho lead-discretion) — comment-only fix; (4) hmw-mode.on = HỆ KHÁC (consent fan-out T3 `ultracode-hmw-mem-governance`, content tự khai /ultra-on) — ngoài scope H21; (5) mega-line "VẪN ON" class = **standing-imperative-trong-history-blurb** (S109-header + HANDOFF NEXT-anh = ACTIVE cần sửa; blurb-body = snapshot giữ). Bẫy fidelity lớn nhất: MTv3 §1.2/1.3 "sub gán cứng hạng-hai" đọc như floor → tưởng phá H8 all-inherit; triage-reply S2 CÙNG NGÀY waive đích-danh ("không đổi gì với form all-inherit"). ⚠️ #53 garble lượt return đầu (trả status-line giữa-chừng thay verdict) → coordinator SendMessage re-emit trong-session = recover OK, diary ghi trước re-emit.
---
## 🔄 Curate trigger
- >~30KB → archive recent → L2 `archive/<period>.md` (byte-exact append) + `_INDEX.md` substring pointer. Stale >3mo → remove.
- **Last curate: 2026-07-06 (em-main single-writer, hook-triggered @21.4KB)** — 6 stale governance/superseded entries (S93/S97/S98/S100/S101 + 07-01 Supplier-predecessor) verbatim → `archive/2026-07.md`, replaced with pointer-stubs. L1 back under target.
- **Prev curate: 2026-06-18 S71** (29.8→23.2KB FIFO-trim 3 + gist gen:2). **Prev S70** (47.0→24.1KB dark-matter recovery + built _INDEX/gist). **Prev S40** (35.7→~20KB).