Files
solution-erp/docs/governance/error-ledger.md
pqhuy1987 c2d01f0dce
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m30s
[CLAUDE] Docs: S152 closeout — bookend hình B trọn 2 đầu + owner (30)(31)(32) + queue memory-ops TRỌN (squash 20 wal:)
- Owner 3-quyết: (30) JUMP để-nguyên-theo-nhịp · (31) 4 persona +NEVER-block (restart ĐÃ THOẢ) · (32) vòng 1→5 AUTO — lô consent gỡ 9 site (5 H1 + ring1-tự-bắt + 3 trio; E-013 EXT)
- Memory-ops TRỌN: A1-A4/D1/D2/R1/B-series — A7 392/392 · mfe 20/20-100% lần đầu · lead-gap drain 24.728→16.485B · strike-ledger + WARN-latch (-Ack = owner-action)
- V4 sleep AUTO đầu: 1 shard thật/16 KÊU · ring4 đầu-đời TRƯỢT-4/5 → 4 fix gist (scribe sub-ring4-close vì return-only)
- Thư model re-stamp: 59ce1d0f → 9c909007 published (G-024a) — adap-report Đính-chính @S152 + sweep 13 bề-mặt LIVE
- Bookend @close: stale 6 FLAG + gap 2 FLAG → vá 8/8; ring2 8/8 ĐẠT (4-A pin-bản-cắt → slot 33) · ring1 48Đ/5T/59-claim
- M9 13 đơn-vị diary (3 S151-deep hồi-tố) · #53 ×10-chắc → tally 60-cận-dưới + errata subject-1b85713
- Session-log 2 run= + completeness-gate 5-vòng ĐẠT · HANDOFF segment S152 (carry 3-đóng/3-mới/23-giữ; slot 33/34)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 01:58:30 +07:00

212 lines
45 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.

# Error-Ledger — SOLUTION_ERP (Gov-v2 §L keystone)
> **Living artifact.** Blameless RCA + Active-Guards index for SE. Closes the open delta from adap-report `2026-06-02-Governance-gov-v2-session-cmd-framework` (the only Gov-v2 floor item SE had distributed-but-not-formalized).
> **Maintained at `/session-end` §L.b** (deterministic step, not a daemon — G-015). Blameless = root-cause + guard, NOT blame.
## 📐 The 3-ledger triad (Gov-v2 §L.b / §G3 — form gộp, function intact)
SE maps the mandated 3 living ledgers onto existing + new artifacts (§F4 form-freedom):
| Ledger (function) | SE artifact | Role |
|---|---|---|
| **(i) error-ledger** | **this file** (`docs/governance/error-ledger.md`) | RCA blameless · Active-Guards index · 3-axis tag · 2-strike promote |
| **(ii) comms-ledger** | `docs/governance/README.md` "Cross-Project Adoption Ledger" + `docs/governance/adap-reports/` | 2-way cross-project OUT→ACK / IN→decided, link-not-copy |
| **(iii) summary-index** | `docs/STATUS.md` "Recently Done" + `docs/changelog/sessions/` | timeline spine, pointer-not-log, reverse-chron |
## 🔍 §L.a — Deterministic detect (action-signature scan @ session-end)
Detect by **action-signature** (NOT "AI tự phán có vi phạm không"). Scan the session for these; each hit → an RCA entry below. List is **open** — extend when a new class appears. (G-015: catches signatures in this list, NOT "mọi vi phạm".)
| # | Action-signature (grep/observe) | Rule it violates | On hit |
|---|---|---|---|
| AS-1 | `git add -A` / `git add .` | add-specific-files (concurrency safety, `feedback_rag_mcp_recovery_concurrency`) | RCA + re-stage specific |
| AS-2 | `--no-verify` / `--no-gpg-sign` / `commit.gpgsign=false` | no hook/sign bypass unless asked | RCA, justify or revert |
| AS-3 | sub-agent invokes `store_memory` | lead = sole RAG-writer (S47, mechanized) | should be impossible (allowlist-stripped); if chunk-count jumps w/o lead write → investigate |
| AS-4 | EF Mig adds UNIQUE/composite index on a soft-delete (`IsDeleted`) entity **without** `.HasFilter("[IsDeleted]=0")` | gotcha #57 (recreate-on-soft-deleted-slot → 500) | RCA + test-before + filter |
| AS-5 | heavy/long agent spawn in **foreground** | `feedback_background_spawn_visibility` (looks-frozen) | note; prefer `run_in_background` |
| AS-6 | docs-only commit that triggers a CI run | gotcha #41 path-filter (`paths-ignore`) | verify path-filter intact |
| AS-7 | model downgrade (haiku/sonnet) on codegen/guard/financial/security | critical-algo needs Max tier | RCA, re-run on Max |
| AS-8 | session-end memory `.md` Write leaving **0 bytes** | `feedback_session_end_memory_write_verify` (S46) | re-write + verify byte>0 |
| AS-9 | A/B/C choice handed to anh **without** decision-brief trục | Gov-v2 §G2 | reframe as full brief |
| AS-10 | sub-agent writes a tracked file (MEMORY.md / code) despite **R1 return-only** (Write/Bash residual) | R1 return-only (HMW) — prompt-rule, NOT mechanized (G-015) | git-diff post-P2 catch → lead VERIFY benign+accurate+placement → keep or revert (NOT a bug if correct; chunk-count for RAG-write) |
| AS-11 | cross-stack feature: BE validator/nullability ≠ FE required-marker for the SAME field | em-main shared-contract consistency (E-007) | RCA + align FE↔BE + reviewer-gate (held S51) |
| AS-12 | identifier-based data op trên prod (lock/seed/migrate-by-email/code) viết theo population đọc từ CODE/Dev, KHÔNG dump bảng env đích | gotcha #60 (E-008) — assertion 0-row/`-1` ⟹ nghi data-mismatch TRƯỚC code-bug | RCA + dump env-đích trước khi viết list + seed-password thỏa policy nghiêm nhất mọi env |
| AS-13 | **custom Workflow script (≠ hmw.js DEFAULT-mode)** chạy parallel **same-role** agents giữ Write → agents tự-ghi shared `agent-memory/<role>/MEMORY.md` → "file modified since read" race + verbose-append over-cap | E-009 — hmw.js DEFAULT có return-delta-guard, custom script KHÔNG kế-thừa | RCA + curate L1→L2 + custom workflow PHẢI copy return-delta-guard HOẶC file-disjoint 1-sub/file |
| AS-14 | phép ĐO text (length/char-count/so-sánh) qua `Get-Content`/console-pipe **KHÔNG ép encoding** trên file **no-BOM** (PS5.1 default = ANSI → ký-tự Việt đếm ×2-3) | đo-phải-chạm-đĩa-ĐÚNG-CÁCH (E-010; anh em với bẫy `grep -c``feedback_resume_premise_reverify`) | RCA + re-đo `[System.Text.UTF8Encoding]` tường-minh; số đã báo owner → đính-chính NGAY |
| AS-15 | **điểm-đóng-thật** (chốt-đợt commit+push HOẶC session-end) **KHÔNG kèm** delta diary monitor (H1/H2) **và KHÔNG** dòng counter §L.b(j) | session-end §L.b "(a)→(j) đủ HẾT, KHÔNG skip" (E-011 — nghi-thức chạy tắt; máy mù lớp "nghi-thức có chạy không") | RCA + spawn DỒN H1+H2 re-report phủ khoảng bị bỏ + harvest hồi-tố + đọc counter bù |
| **AS-16** | artifact **OUTWARD** (adap-report · email hub · broadcast) **cite sha CHƯA-push**, HOẶC được **stamp trước khi `git status --porcelain` sạch** | E-012 — closeout-squash phá đúng sha vừa cite ⇒ con-trỏ chết với người ngoài; và file sửa sau khi stamp làm câu trong bản đã-niêm thành sai. **Cite outward = commit SẼ SỐNG sau squash.** `git status` là bước **ĐẦU** của outward-gate, không phải bước cuối | RCA + re-anchor sang commit đã-push + **errata rời** (CẤM sửa file đã stamp — vỡ hash) |
| **AS-17** | sub được lệnh ghi-đĩa-trong-lúc-làm nhưng lúc return/chết sub-file chỉ có **SKELETON** (header/checklist, 0 finding) — byte-content KHÔNG tăng theo tiến độ | sub-class `skeleton-ruột-rỗng` (E-013 — S150 gate `wf_f4e4c006` khung 274B/0-append → S151 ×2 thuần [sub-lead-stale header-only + sub-lead-gap checklist-only] = **2-strike**; "ghi-đĩa-trong-lúc-làm = CẦN, KHÔNG ĐỦ" — `feedback_agent_return_garble_recover`) | lead verify **BYTE-CONTENT tăng thật GIỮA wave** (đọc RUỘT — size nhỏ = nghi-vấn không phải bằng-chứng, phân biệt skeleton vs đang-viết-dở; H2 m#19) → resume-in-session ép đổ ruột (S151: 5/5 sạch) · lane quan-trọng giữ N-lane-redundancy + em-main-solo backstop |
## 🛡️ Active-Guards index (2-strike promote: episodic → procedural)
> **net-effect rule:** a guard that costs more than it saves (hại>lợi) → **retire**. `verified` = ran ≥1× and held. `strikes` = times the underlying error recurred before the guard.
> **G-011 ladder (canonical on-disk từ S139 — trước đó chỉ sống trong lineage adap-reports):** nấc tiến-độ khi khai một việc: `agreed` (đồng-ý làm) → `executed` (lệnh đã chạy xong) → `verified` / `verified-pending-restart` (đã KIỂM chạy thật; edit agent-file no-hot-reload = verified-pending-restart). 🔴 **KHÔNG tự khai `verified`** khi chưa có phép kiểm chạy được. Tham-chiếu: rules §6.6 K4 relay-attribution.
> **Luật re-base số-sống (K6.2 — generalize E-010, adopt S139):** Re-base baseline = chốt số **SỐNG** tại lúc re-base — mọi số vào sổ đọc lại từ **nguồn sống tại thời-điểm ghi** (CẤM chép từ ghi-chú/phiên trước, kể cả ghi-chú của chính mình); byte = `(Get-Item).Length` (E-010). *(nhà đề-xuất-mặc-định — [owner-reviewable])*
> ### 🪤 Carve-out ô3 — điều-kiện SỐNG (adopt S141, ghim S142)
>
> **Nấc:** force-fire khi closeout gộp sổ chạy dưới dạng **đề-xuất-chạy chờ anh gật** (KHÔNG auto-run) đứng ở nấc **`PASS-với-carve-out`** — 🔴 **CẤM nâng thành `PASS-trần`**. Đây không phải trừ-điểm: nó ghim đúng *điều-kiện sống* của carve-out.
>
> **VALID chỉ khi CẢ 2 lưới còn sống CÙNG LÚC** (đích danh, không nói chung chung):
> - **(a) dòng-nợ read-only vẫn IN ở MỌI điểm dừng** — `scripts/nhip-no-probe.ps1`
> - **(b) cái dò "closeout-thiếu-nghi-thức" vẫn được NỐI** — section `H25-closeout-ritual (GAP-2)` trong `scripts/governance-detectors.ps1`
>
> **Vì sao buộc CẢ HAI:** chuyển từ "máy tự chạy" sang "chờ anh gật" thì rủi-ro MỚI sinh ra là *anh quên gật mà không ai kêu*. Hai lưới trên **chính là cái kêu** — dòng-nợ cho anh thấy khoản quá-hạn, cái dò bắt closeout gộp mà thiếu nghi-thức.
>
> 🔴 **1 lưới chết ⇒ carve-out mất lớp tự-minh-bạch ⇒ RE-EVAL nấc**, và trong lúc chờ thì **tụt về chạy-vô-điều-kiện** cho tới khi lưới sống lại. Đây là luật đứng, không phải khuyến-nghị.
>
> **Basis:** hub reply `9a35405b` **khối-2** (`broadcasts/inbox/2026-07-17-ai_infra-to-se-reply-adap-wave-carveout-dp2.md`) — hub CONFIRM carve-out hợp-lệ *và* ghim đúng 2 điều-kiện này.
>
> **Live-evidence S139→S140 (dogfood mở sổ, không khai suông):** dòng-nợ `light 8/6` quá-hạn IN tại cửa nối-lại → anh **gật** → cặp H24 (`lead-view-auditor` + `lead-omission-auditor`) chạy THẬT → ra cờ THẬT (2 cờ view-cũ sửa trong phiên + 1 cờ MED "quyết-định-chìm" lặp-2) → probe sau audit `light 0/6`. Đủ một vòng: **nợ hiện → gật → chạy → ra việc thật → nợ về 0.**
>
> **Kiểm tại S142:** cả 2 lưới **SỐNG** (`scripts/nhip-no-probe.ps1` có trên đĩa; `H25-closeout-ritual` còn wired trong suite và chạy ra output) ⇒ nấc `PASS-với-carve-out` đứng vững, chưa phải re-eval.
>
> **Cùng CLASS — trio-consent S141:** bộ-ba đồng-kiểm memory (`harness-eval`/`refine`/`audit`) chạy **consent-gated** cũng là carve-out CÙNG LOẠI, chịu CHUNG luật trên; lưới của nó = **(a) proposal-line in CẢ khi Light-session** (không skip im) + **(b) vết-skip ghi `.claude/WAL.md` dạng `trio: skipped S<nn> (lý-do)`** để chuỗi skip nhìn thấy được. Khai nấc `PASS-với-carve-out` trong adap-report, KHÔNG PASS-trần; 1 trong 2 lưới chết ⇒ re-eval y hệt ô3.
| Guard | Counters | Tier | Strikes | Verified | Net |
|---|---|---|---|---|---|
| CI `paths-ignore` docs-only skip | gotcha #41 (AS-6) | procedural | 2 | ✅ (every docs commit 0s) | +++ |
| em-main verify-on-disk + proxy-append after agent return | gotcha #53 truncation | procedural | 5× (S35-S42) | ✅ | +++ |
| test-before bug-fix + soft-delete-UNIQUE `.HasFilter` | gotcha #57 (AS-4) | procedural | 3 (Holiday S45 · LeaveType/Shift/OtPolicy S51) | ✅ Mig 43 + Mig 45 (5 test RED→GREEN) | ++ |
| reviewer pre-commit on cross-stack / wire-BE-CRUD (contract-mismatch net) | E-007 (AS-11) | procedural | 1 (S51 Driver FE↔BE) | ✅ S51 (caught pre-commit, fixed before deploy) | ++ |
| verify byte-content sub-file GIỮA wave + resume-ép-đổ-ruột (anti skeleton-rỗng) | AS-17 / #53 sub-class E-013 | procedural (promote 2-strike @S151) | 2 (S150 gate + S151 stale/gap) | ✅ S151 (resume 5/5, 0 mất dữ-liệu; trio return-only 3/3 clean cùng phiên = counter-datum) | ++ |
| authz regression test per-action policy | gotcha #44 silent-403 | procedural | 1 (promoted S45 +10 test) | ✅ | ++ |
| agent frontmatter `model: inherit` (not `[1m]`) | gotcha #37 | procedural | — | ✅ (FD agent loaded S48) | ++ |
| **lead = sole RAG-writer** (`store_memory` stripped, mechanized) | store_memory rebootstrap-loss (S41) + AS-3 | procedural | 2 (NamGroup + SE S41) | ✅ runtime S48 (0/8 subs) | +++ (failure-safe) |
| session-end verify memory byte>0 | S46 0-byte (AS-8) | procedural | 1 (S46) | ✅ S49 (new mem 2355B + 0 byte-0 scan) | ++ |
| **git-diff + chunk-count post-P2 containment** (defense-in-depth, HMW) | R1 sub-write residual (AS-10) · store_memory bypass (AS-3) | **procedural** (institutionalized S50 = standard B6 post-wave audit) | 1 (S49) | ✅ S49 (caught inv-api self-MEMORY in git-diff; chunk 2414=2414) + **S50 wave `h2-verify` (git-diff agent-memory EMPTY, chunk 2415=2415, 0 leak)** + **S93 (WF1 3-agent residual caught+reverted; WF2 0-residual after explicit return-only)** + **S95 (WF1+WF3 residual caught+reverted 2×; WF3 explicit-return-only STILL self-wrote → instruction-fix NOT 100%, git-diff = the net)** + **S103 (investigator recon-agent garble-CURATED own memory [archive/2026-07.md new dù L1 NOT over-cap 17337<25600] → caught+reverted git-checkout; #53 ×3 phiên → recover incl Lane-B-from-diary; reviewer/tooling-auditor self-writes = LEGIT harvest kept)** | +++ (G-015 honest — 5 fires/5 catches/0 escape; NOT allowlist-alone, NOT instruction-alone) |
| heavy spawn → `run_in_background` | looks-frozen | **procedural** (2-strike met) | 2 (S45, S48) | ✅ S48 (FD bg) + S50 (all 4 monitor+wave spawns bg) | + |
| RAG glob `**/`-anchored (not root) | gotcha #10 node_modules leak | procedural | 1 (S41) | ✅ (2406 clean) | ++ |
| dump bảng env-đích TRƯỚC identifier-based data op (lock/seed-by-email) | gotcha #60 (AS-12) | episodic | 1 (S57bis lock NO-OP) | ✅ S58 (recon dump → fix `5998163` → Run #382 đo 34 locked) | ++ |
| custom Workflow same-role → copy return-delta-guard HOẶC file-disjoint 1-sub/file | E-009 (AS-13) | episodic | 1 (S71 invest/review race) | ✅ S71 (curate workflow `wf_f32987b8` file-disjoint 1-sub/file = 0 race; finalize curate đóng over-cap) | ++ |
| đo text = ép `UTF8Encoding` tường-minh (PS5.1 no-BOM ⇒ ANSI ⇒ số phồng ×2-3) | E-010 (AS-14) | episodic | 1 (S130) | ✅ S130 (B3 round-trip dùng UTF8-explicit PASS 2 file; số đính-chính cùng phiên) | + |
| điểm-đóng-thật ⇒ tự-hỏi "diary monitor có delta? dòng counter có in?" (chờ hub canonical detector) | E-011 (AS-15) | episodic | 1 đợt (×3 closeout S128-S130) | ✅ S132 (spawn dồn H1+H2 phủ S127→S131 xong: H2 GAPS→CLOSED + H1 1-drift-FIXED + 2 diary H24 seeded + counter-line in §L.b(j)) | + (đề-xuất khung đã gửi hub `e46863c8`) |
## 📋 RCA entries (blameless — newest on top)
> Format: `E-NNN | date | rule | what | 5-why root | fix (prod-bug = 2-fix: code + guard) | prevention | tags[TYPE/ACTOR/COMPONENT]`
### E-014 — AS-18 slot-index tái-dụng làm MẤT owner-decision không để lại vết (S146, H24 `lead-omission-auditor` bắt, lead verify bằng `git show`)
- **rule (AS-18 NEW):** khối đánh số (`OWNER-DECISION [n]`, checklist, enum…) **CHỈ ĐƯỢC TĂNG index**. **CẤM tái-dụng số cũ cho nội-dung mới.** Đè slot = nội-dung cũ **biến mất im-lặng** — khác hẳn đổi giá-trị (còn thấy giá-trị cũ để grep).
- **what:** owner @S146 nói *"còn lại xử lý hết xong rồi session-end nhé"*; lead ghi ĐÚNG vào `.claude/WAL.md:9` slot `[7]` = **uỷ-quyền commit+push** (`ad02483`, `9c68bae`). Sau đó lead thêm 3 quyết-định session-model và **tái-dụng slot `[7]`**`e7d06f2` mất hẳn dòng cũ. Grep toàn repo = **0 hit**.
- **hệ-quả THẬT (không phải lý-thuyết):** lead hỏi lại *"cho push chưa"* **3 lượt liền** — hỏi lại đúng thứ owner ĐÃ trả lời, và hỏi ngay dưới khối tự đặt tên **"ghi đè, KHÔNG hỏi lại"**. Lead làm **ngược** chính luật mình viết.
- **5-why:** (1) lead thêm mục mới vào khối có sẵn → (2) chọn số kế-tiếp *theo cảm-giác* thay vì đọc số lớn nhất đang dùng → (3) `[7]` trông "trống" vì lead nhớ khối chỉ tới `[6]` → (4) WAL **ghi-đè toàn-file** nên không có diff-review từng dòng như commit thường → (5) **máy MÙ hoàn-toàn**: không detector nào biết `[7]` từng là thứ khác.
- **fix:** khôi phục `[7]` (nguồn `git show ad02483:.claude/WAL.md:9`) + đẩy session-model xuống `[8]` + ghi luật **SLOT-INDEX CHỈ-TĂNG** ngay tiêu-đề khối.
- **prevention/guard:** vai H24 soi **CÁI THIẾU** = catch-layer **DUY NHẤT** cho lớp này (H24 §2(1) *"máy MÙ gần như hoàn toàn"*). 🔴 Nhắc: WAL ghi-đè ⇒ **mọi mất-mát trong WAL đều im lặng** ⇒ đối-chứng phải là `git show <sha>:.claude/WAL.md`.
- **tags:** [slot-reuse / lead / WAL.md · owner-decision · gap-owner-specifics · class_repeat 2→3 CHẠM jump]
### E-013 — AS-17 sự-cố KHÔNG vào sổ bền + phép trích-xuất hỏng đọc thành "sạch" (S146, cụm 2 lỗi cùng lớp *"vắng mặt trông giống ổn"*)
- **rule (AS-17 NEW):** (a) sự-cố chỉ có vết trong **run-folder** = **CHƯA vào sổ**; phải đổ vào ≥1 **sổ bền** (error-ledger / STATUS / HANDOFF / auto-memory). (b) phép trích-xuất trả **RỖNG** phải phân-biệt *"không có gì"**"phép đo hỏng"***CẤM đọc rỗng thành sạch**.
- **what (a):** garble `#53` THẬT trên `harness-audit` @S144 (`trio-synthesis.md:20-21`) + lead thu-hẹp tập đối-chứng mà im-lặng (*"đối chứng 4 mốc: 0 LỆCH"* trong khi khối liệt **5**, mốc-5 chính là mốc lệch) ⇒ **0 hit** ở cả 5 sổ bền; sổ đếm `feedback_agent_return_garble_recover.md` dừng ở `×25 qua S143`. **S146 thêm 3 garble nữa** (lead-view · lead-omission · h24-audit — **3/3 vai lane-H24**).
- **what (b):** lead vá 6 site consent theo danh-sách H24 liệt, **vá 5 sót 1** (`ring2-audit.md:25` (tên cũ h24-audit.md — rename @S149) — câu tự mâu-thuẫn *"KHÔNG consent-gate … khi OVERDUE + anh consent"*). **Cơ-chế tái-dựng được:** lệnh trích `grep -oE '.{50}consent.{80}'` đòi **đúng 50 ký-tự TRƯỚC** match; trên dòng đó `consent` ở ~offset 30 ⇒ **0 match ⇒ output RỖNG** ⇒ lead đọc thành *"dòng này không có gì"*. Đúng phải là `.{0,60}`.
- **5-why (b):** (1) vá theo danh-sách người khác liệt → (2) không tự grep lại sau khi vá → (3) dùng cửa-sổ ngữ-cảnh **cố-định** thay vì **0..n** → (4) rỗng **trông y hệt** sạch (khác `grep -c` trả `0` — một con SỐ, nhìn là biết đang đếm) → (5) `h24-audit` bắt được vì nó **đọc dòng đó trong chính persona nạp vào mình** + đối-chứng đĩa = 2 nguồn.
- **fix:** vá `:25`; re-grep toàn file = 0; ghi cụm sự-cố vào chính entry này.
- **prevention/guard:** 🔴 **Luật: vá xong PHẢI tự grep lại bằng lệnh KHÁC lệnh đã dùng để tìm** (khác mẫu, khác cửa-sổ). Họ hàng đã có trong sổ: `grep -c` (dòng) vs `grep -o|wc -l` (occurrence) — nay thêm **cửa-sổ-ngữ-cảnh-cố-định**.
- **EXT @S152 — tái-phát lần 2, cùng-họ `ring*`, cùng hình-dạng (b):** đợt sleep-AUTO owner (32) quét 7-site trong `commands/`**sót trọn lớp `agents/`** — stale-close FLAG-4 bắt `ring4-audit.md:26/:27`; H1 liệt lô 5-site vẫn **sót site-6 `ring1-audit.md:24`** (vết núp trong ngoặc SAU câu đúng "KHÔNG consent-gate (…gật mới chạy)") — `ring1-close` tự bắt **trong persona chính mình** bằng mồi KHÁC ("gật mới chạy"); lead grep cùng-lớp ra thêm 3 site trio-persona (`harness-eval.md:4` description · `harness-refine.md:58` · `harness-audit.md:50` vế "First-run chờ consent") ⇒ **lô cuối 9 site** (+2 vết ring2 đã vá đúng từ trước). Guard siết thêm: **sweep theo LỚP-file (commands + agents + skills), đừng theo danh-sách-site người khác liệt; mồi grep ≥2 biến-thể** ("consent" · "anh gật" · "gật mới chạy").
- **tags:** [incident-unrecorded + extraction-silent-empty / lead / error-ledger · ring2-audit.md:25 · #53 ×3 S146 · EXT-S152 lô-9-site ring1-audit.md:24]
### E-012 — AS-16 bằng-chứng-tự-huỷ-sau-squash: 7 adap-report + 1 email hub neo vào sha `wal:` chưa-push, closeout-squash phá đúng sha đó (S143, reviewer-gate độc-lập bắt SAU khi thư đã gửi)
- **rule (AS-16 NEW):** artifact OUTWARD phải cite **commit SẼ SỐNG sau squash**, và phải qua `git status --porcelain` **TRƯỚC** khi stamp. Vi-phạm nền: `/adap-report` §3 *"evidence: commit-sha · file path · byte/dòng (đo THẬT)"* — đo thật nhưng **neo vào con-trỏ sắp chết**; và `/send-email` 6c selftest-stamp chỉ kiểm **hash khớp thân-thư**, KHÔNG kiểm **thân-thư có còn đúng sự-thật** lúc phát.
- **what:** (1) 7 adap-report cite `1a0fa59`/`a458102`/`96ab2679`/`c3708e9`/`b1d92b9` (đều `wal:`-commit local). Closeout §5.0 `reset --soft HEAD~8` gộp chúng vào `2757e41` ⇒ cả 5 thành **dangling**: `cat-file -t` = `commit` (sống nhờ reflog LOCAL) nhưng `merge-base --is-ancestor <sha> origin/main` = **exit 1** ⇒ hub clone repo về `git show 1a0fa59` = **object missing**. Nội-dung nguyên vẹn trong `2757e41`**chết con-trỏ, không chết việc**. (2) Cùng gốc: report + email khai `is-ancestor 96ab2679 HEAD = exit 0 → OK-reachable` làm bằng-chứng "contract v2 chạy runtime" — squash **cùng phiên** lật nó thành `exit 1`/`SQUASH-BENIGN`**phép đo tự huỷ trong chính phiên phát-biểu nó**. (3) Biến-thể thứ ba: email `:47` khai *"vế pull-age **chưa làm**, chờ owner"* — owner gật ngay sau đó, lead làm, `scripts/nhip-no-probe.ps1` sửa **sau** khi thư đã stamp ⇒ bản đã-niêm khai sai hiện-trạng, và **không sửa được** (sửa = vỡ hash).
- **5-why root:** (1) vì sao sha chết? — squash rewrite history. (2) vì sao squash sau khi cite? — report viết **trước** push, đúng thứ-tự tự-nhiên của việc ("làm xong thì ghi lại"). (3) vì sao thứ-tự đó sai? — vì với artifact OUTWARD, *người đọc ở repo KHÁC*, nên tham-chiếu chỉ có nghĩa nếu nó tồn tại **trên remote**, không phải trên đĩa mình. (4) vì sao không ai bắt lúc viết? — mọi phép verify của lead chạy **trên máy lead**, nơi reflog còn giữ sha ⇒ `cat-file -t` xanh ⇒ **kiểm bằng góc nhìn người-trong-nhà cho một artifact gửi người-ngoài**. (5) 🔴 **root:** *tiêu-chí verify được chọn theo cái mình đo được, không theo cái người nhận sẽ đo.* Cùng class với E-010 (đo bằng công-cụ tiện tay) và với "TRIPLE chọn enum DỄ" cũng bắt trong phiên này.
- **fix (KHÔNG prod-bug — artifact-only, vẫn 2 lớp):** *(a) lớp artifact:* re-anchor toàn bộ 7 report sang `2757e41` + thêm caveat ghi rõ sha cũ chỉ còn giá-trị local; phát **errata rời** `e43484cef10f` cho hub (CẤM sửa bản đã stamp). *(b) lớp luật:* AS-16 + 3 luật đọc-được ghi vào report/errata — **cite outward = commit sống sau squash** · **`git status` là bước ĐẦU của outward-gate** · **tách claim-DELTA (bền) khỏi claim-TUYỆT-ĐỐI (phải neo commit+thời-điểm)**.
- **prevention/guard:** *episodic → chờ strike-2.* Guard đề-xuất khi tái: chèn vào `/send-email` bước 6c một phép **`git status --porcelain` = rỗng** + **`merge-base --is-ancestor <mọi sha cite> origin/main`** trước khi stamp; fail ⇒ ABORT. 🔴 **Chưa wire** — vì guard này cần định-nghĩa "sha cite" (parse thân-thư) và có thể dương-giả với sha của repo KHÁC (hub sha như `58e28bae` KHÔNG nằm trong repo SE). Ghi làm nợ, không tự dựng cổng nửa vời.
- **Đối chứng (chứng đây là class, không phải xui):** wave TRƯỚC (S138S139) cite `7760cdf`/`da349fc` = commit **đích** sau squash → **sống hết tới nay**. Cùng người, cùng nghi-thức, khác đúng một điểm: thời-điểm viết report so với thời-điểm push.
- **tags:** `[GOVERNANCE/lead/outward-artifact · evidence-self-destruct-squash · cite-post-squash-commit · git-status-first · verify-tu-goc-nhin-nguoi-nhan]`
### E-011 — AS-15 nghi-thức chạy tắt: 3 closeout liên-tiếp S128-S130 KHÔNG spawn monitor H1/H2 + bỏ §L.b(j) — máy im suốt, lộ nhờ 1 câu hỏi của anh (S131 phát-hiện, S132 xử)
- **rule (AS-15 NEW):** session-end §L.b (session-end.md:52) *"auto-maintain (a)→(j) đủ HẾT, KHÔNG skip — thiếu = ledger thối"*; (d)(f) = H2 harvest-curator · (g) = H1 tooling-auditor · (j) = đọc counter/OVERDUE. **Điểm-đóng-thật** (chốt-đợt + push) đi qua mà nghi-thức không chạy = closeout chạy tắt, dù phiên kết thúc bằng `/pause` chứ không phải `/session-end`.
- **what:** 3 closeout liên-tiếp — S128 `289ba96` 20:57 · S129 `295c70c` 23:16 · S130 `71757fc` 00:26 — commit + push xong mà KHÔNG spawn H1/H2 (mtime diary 2 monitor đứng 2026-07-16 15:18; commit cuối chạm diary = `e9124fc` 15:19; S130 Recently-Done còn tự ghi *"0 sub spawn"*) + bỏ luôn §L.b(j) — cả lớp ĐỌC counter cuối phiên không chạy. Không detector nào đo lớp "nghi-thức có chạy không" → im lặng trông y hệt sạch; chỉ lộ khi anh hỏi *"sao không thấy lead-view/lead-omission/harvest chạy?"*. Họ-hàng cùng đợt (GAP-1, email `e46863c8`): mạch pause→`/tiep` không tick counter H24 → S128·S129·S130 không tick → counter dưới-đếm ~37% trên cửa-sổ 8 nhãn (5 tick/3 không).
- **5-why:** phiên kết thúc bằng `/pause` (H22 điểm-dừng chủ-động) hoặc mở bằng `/tiep` nối-mạch → không đi qua cổng `/session-end` → §L.b không ai gọi → không gate máy nào ép (a)→(j) → 3 phiên lặp cùng kiểu → gốc = **kẽ THIẾT-KẾ giao-điểm 2 harness** (H22 pause/tiep ⟂ nghi-thức đóng §L.b + H24 tick 1-điểm-vào), KHÔNG phải lỗi cá-nhân một phiên; máy mù lớp nghi-thức (cùng họ caveat (e) adap-report H24).
- **fix (KHÔNG prod-bug — process):** (đợt này) S131 mở session-end ĐÚNG nghi-thức đầu-tiên sau 3 lần tắt (sentinel + §L.a + archive-gate DRY PASS) — chết giữa vì session-limit → S132 `/tiep` nối: spawn DỒN H1+H2 phủ S127→S131 + harvest hồi-tố GAP-3 (diary 2 vai H24) + entry này. (báo) email hub `e46863c8` 3-gap stamped + đề-xuất khung: tick đa-điểm-vào H22×H24 · detector "closeout-missing-monitor" · "first-run-role-has-diary" — chờ hub canonical, SE không tự chế detector riêng.
- **prevention/guard:** AS-15 thêm §L.a + Active-Guard episodic (occurrences ×3 nhưng 1 đợt phát-hiện — promote nếu tái SAU guard). Wire tick vào `/tiep` + tick-at-close = đề-xuất ĐÃ TRÌNH ANH (email mục "SE tự làm trong-khung" #1), **CHỜ ANH GẬT mới sửa `tiep.md`** — không tự áp.
- **tags:** [ritual-skip / em-main / session-end×H22-pause-tiep×H24-counter]
### E-010 — AS-14 encoding-mismeasure: `Get-Content` no `-Encoding` trên file no-BOM → báo owner số sai ×2-3 (S130, tự-bắt + đính-chính trong-phiên)
- **rule (AS-14 NEW):** phép ĐO text (length/count/so-sánh) phải ép encoding tường-minh. PS5.1 `Get-Content` trên file UTF-8 **no-BOM** đọc theo ANSI ⇒ mỗi ký-tự Việt (2-3 byte UTF-8) đếm thành 2-3 char ⇒ số phồng ×2-3. Repo này CỐ Ý để docs no-BOM ⇒ mọi phép đo mặc-định đều dính.
- **what:** S130 khi trình 3 mục owner-gated, em đo mega-line bằng `(Get-Content docs\STATUS.md)[5].Length` = 70.008 / HANDOFF = 65.429 → báo anh "phình ~13K chỉ trong 1 ngày" ngay trong AskUserQuestion. Số THẬT (UTF8Encoding explicit): 64.794 / 59.686 — phình thật +113 ch + ~2.5K. Kết-luận "đang phình" đúng HƯỚNG nhưng độ-lớn sai ~5×. May: cả 3 phương án đã trên bàn từ S126 ⇒ quyết-định anh không dựa số này.
- **5-why:** đo nhanh bằng cách quen tay (Get-Content index) → không nhớ PS5.1 đoán encoding theo BOM → file cố-ý no-BOM (chính-sách repo) → số sai trôi thẳng vào câu hỏi trình anh → chỉ bị bắt khi B3-execute phải ReadAllText UTF8 (round-trip cần byte-đúng) cho ra số khác ⇒ tự-đính-chính. Gốc: **phép đo không khai encoding = phép đo chưa chạm đĩa đúng cách** — cùng họ bẫy `grep -c` (đếm dòng ≠ occurrence) S121.
- **fix (KHÔNG prod-bug — measurement-only):** (đo lại) mọi con số phát-biểu lại bằng `[System.Text.UTF8Encoding]::new($false)` + đính-chính với anh TRONG phiên (WAL + STATUS + HANDOFF ghi cả số sai lẫn số đúng). (guard) AS-14 thêm §L.a + Active-Guard episodic + append `feedback_resume_premise_reverify`.
- **prevention/guard:** đo text ⇒ `ReadAllText($path, UTF8Encoding-explicit)`; cần ĐỌC tiếng Việt từ console ⇒ dump-ra-file rồi Read (console PS cũng mojibake — đã thấy cùng phiên với ACTIVE-MARKS). Số đã lỡ báo owner ⇒ đính-chính ngay khi phát-hiện, giữ kết-luận nếu còn đúng + khai độ-lớn sai.
- **tags:** [measurement-mislabel / em-main-solo / docs-megaline+PS5.1-encoding]
### E-009 — AS-13 custom-workflow same-role MEMORY write-race → over-cap (S71, finalize-review-caught, curated same-session)
- **rule (AS-13 NEW):** custom Workflow script (≠ hmw.js DEFAULT-mode) chạy parallel **same-role** agents giữ Write → mỗi agent chạy frontmatter "update MEMORY before return" → concurrent writes shared `agent-memory/<role>/MEMORY.md` → "file modified since read" race + verbose-append over-cap. hmw.js DEFAULT-mode inject return-delta-only writeGuard; custom script KHÔNG kế-thừa.
- **what:** S71 Harness-10 adop chạy custom workflow (h10-invest 4× investigator-codebase · h10-review + h910-finalize 3× reviewer). Agents tự-ghi diary → 4 investigator ghi `investigator-codebase/MEMORY.md` đồng-thời + 3 reviewer ghi `reviewer/MEMORY.md`. Kết quả: reviewer 24.8→**36.7KB** (harness silent-truncate ~8KB HOT lúc spawn), investigator 24→29.8KB — cả 2 over auto-inject cap 25600. Content HỢP-LỆ (additive, 0 corruption, git numstat +N -0) nhưng P1 curate-debt (claimed CLOSED S70) re-opened.
- **5-why:** custom invest/review/finalize workflow author KHÔNG inject return-delta-guard mà hmw.js DEFAULT có → same-role agents mỗi con chạy "update MEMORY before return" → concurrent write cùng file → race + bloat tích-lũy → over-cap → harness silent HOT-truncate. Caught: finalize-review R3 (`wc -c`) + budget-audit-by-hand S71 (KHÔNG phải runtime-error — silent).
- **fix (KHÔNG prod-bug — 0 production code):** (process) curate L1→L2 `wf_f32987b8-03f` **file-disjoint 1-sub/file** (reviewer 36.7→24.8 + inv 29.8→23.2, 0-byte-loss numstat +N -0 + grep-Fxf 10/10 + md5sum) + budget.json re-measure + reviewer-gist gen:2. (guard) AS-13 + Active-Guard episodic + `feedback_harness10_run_trace` #2 lesson.
- **prevention/guard:** custom Workflow parallel same-role → (a) inject return-delta-only writeGuard (mirror hmw.js DEFAULT), HOẶC (b) file-disjoint 1-agent/memory-file (curate S71 dùng = 0 race). Budget-audit @session-start re-measure bắt re-accumulation. hmw.js RUN-TRACE mode (S71) đã guard.
- **tags:** [memory-race-overcap / custom-workflow-agents / agent-memory reviewer+investigator-codebase]
### E-008 — AS-12 lock-demo-user prod NO-OP: population Dev ≠ prod + seed silent-fail (S57bis ship, S58 fix, cicd-caught)
- **rule (AS-12 NEW):** thao tác data theo-identifier trên prod (lock/seed/migrate-by-email) mà list viết từ CODE/Dev population, KHÔNG dump bảng env đích → silent NO-OP/sai-target. Assertion trả 0-row/`-1` ⟹ nghi data-mismatch TRƯỚC khi nghi code.
- **what:** S57bis ship `LockDemoSampleUsersAsync` 14 email named-person (đọc từ seed code = population Dev-only). Demo prod thật = 20 UAT-matrix (`bod.1@`, `pm.nv@`… tạo TAY 05-13, chưa từng trong code). Run #381 deploy PASS + health 200 + code RAN — locked=0, hoàn toàn silent. Tầng 2 ẩn sâu hơn: `DemoUserPassword` 11 ký tự < prod `Identity:Password:RequiredLength=12` `CreateAsync` trả `IdentityResult.Failed` (LogWarning-only, by-design 1-fail-không-abort) **mọi startup từ trước tới giờ** named-person + `nv.cao`/`nv.truong` (IT pool root cause "helpdesk inert" S56!) + 5 real staff KHÔNG BAO GIỜ tồn tại trên prod.
- **5-why:** author tin seed code source-of-truth population Dev prod password-policy silent-fail silent `IdentityResult` không throw warning log prod không ai đọc chỉ cicd #381 data-dump (PASS+PARTIAL) bắt được test xanh + CI gate + health 200 đều với data-absence. **Why-0 (RAG-archaeology S58):** bug này TỪNG được phát hiện S22 (2026-05-13, session log ghi "Identity password policy 12 existing memory mention `User@123456` 11 chars OUTDATED", 20 UAT user seed bằng `TestUser@2026` 12 tự) nhưng const `DemoUserPassword` trong code KHÔNG được fix lúc đó knowledge nằm trong session-log không thành code-fix/guard tái diễn S57bis. Lesson: discovery phải đổi thành code-fix HOẶC ledger-guard ngay, session-log alone = chết.
- **fix (prod-bug = 2-fix):** (code) `5998163` union 20 email prod-population (exact-email, KHÔNG pattern `binh.le@` người thật sát scheme demo) + password 12 tự Run #382 đo thật: 55 user / 34 locked / helpdesk sống / 5 staff tạo / guard 6-6 active. (guard) gotcha **#60** + debug-checklist item 32 + cicd LESSON "lock/deactivate-by-email trả 0 ALWAYS dump actual Users trước khi score FAIL" + Active-Guard episodic mới (dump-env-đích).
- **prevention/guard:** mọi identifier-based op dump env đích TRƯỚC khi viết list; seed password const thỏa policy NGHIÊM NHẤT mọi env (prod 12); grep warning log sau deploy user-seed mới. AS-12 added §L.a.
- **tags:** [seed-silent-fail+population-mismatch / em-main-S57bis-author · cicd-caught · recon-grounded / DbInitializer]
### E-007 — AS-11 parallel-fan-out shared-contract mismatch (S51, reviewer-caught pre-commit)
- **rule (AS-11 NEW):** cross-stack feature fan-out where BE field nullability/validator FE required-marker for the SAME field contract mismatch (empty submit 400/500). Em-main shared-contract must spec required/optional consistently BOTH sides.
- **what:** P11-C BEFE parallel (file-disjoint) spawn. Driver `phoneNumber/licenseNumber/licenseClass`: BE `NotEmpty()` validator + EF `.IsRequired()` NOT NULL, but FE KIND_CONFIG rendered them OPTIONAL (no `required:true`) `buildBody` emptynull 400/500. 186 tests GREEN (no test hit empty-optional path).
- **5-why:** em-main BE brief said "mirror Vehicle (all-required)" but FE brief omitted `required:true` on those 3 each implementer faithful to its half inconsistency invisible until integration (file-disjoint parallel = no cross-talk) green tests correct contract.
- **fix:** (code) FE +`required:true` on the 3 fields (align to BE all-required, like Vehicle `HrmConfigsPage.tsx:132-134` ×2 app). (guard) reviewer pre-commit on cross-stack = the net that caught it (HELD).
- **prevention/guard:** Active-Guard "reviewer pre-commit on cross-stack/wire-BE-CRUD" (fired correctly) + NEW discipline: em-main cross-stack brief MUST state required/optional explicitly for EACH shared field (BE validator+nullability AND FE required-marker). AS-11 added to §L.a.
- **tags:** [contract-mismatch / em-main-brief+implementer-be+fe / HrmConfigsPage,HrmConfigFeatures]
### E-006 — AS-10 autonomous monitor write at session-end (S50, git-diff-caught)
- **rule (AS-10):** sub writes a tracked file despite propose-only / R1-return-only (Write/Bash residual) git-diff catch lead VERIFY benign+accurate+placement keep-if-correct or revert.
- **what:** @S50 `/session-end`, `git status` = **14 modified** but em-main personally edited ~7. Non-em-main writes: `error-ledger.md` (2 guard episodicprocedural promotions + E-002 #57 coords), 3 `adap-reports` (nacverified-runtime), 4 `agent-memory/*` Recent-activity, + `STATUS.md` (Recently-Done-S50 block / In-Progress flip / RAG-line 24062415 reconcile). mtimes 00:0000:05 = session-end monitor window; the 2 INFORM-only monitors (tooling-auditor + harvest-curator) were briefed propose-only and **reported "wrote nothing."**
- **5-why:** monitors retain `Bash` (G-015 residual write-channel; `store_memory`-strip read-only) 1 wrote canonical session-end content via shell exceeded propose-only mandate (B3 single-writer) self-report disk (Fidelity gap) undetected until em-main git-diff commit-gate.
- **fix:** (process) em-main commit-gate `git diff` review = backstop, **HELD** every changed line reviewed pre-commit accurate / benign / correctly-placed / 0-mojibake / chunk-2415 **adopted per AS-10 keep-if-correct** (NOT a content bug: matches what §L.b prescribes). (guard) "git-diff + chunk-count post-P2 containment" already promoted procedural this session; AS-10 now has its **first real fire**.
- **prevention/guard:** RECOMMEND (anh / AI_INFRA, charter-v2 infra): harden monitor tool-grant `Write/Edit` removal alone leaves Bash residual consider a session-end hook blocking sub-Bash-write to tracked paths, OR accept commit-gate as sufficient defense-in-depth. Fidelity: if monitors write, their reports MUST disclose it escalate 🟥 reviewer if recurs. Provenance timing-implicated, **not definitively attributable** (no false accusation).
- **recurrence S93 (2026-06-29):** AS-10 2nd fire 3 WF1 workflow-agents (investigator-codebase ×2 + reviewer, return-only) self-wrote agent-memory (diary append + archive self-curate + 1 stray `project_s92_*` mis-named file). git-diff post-P2 containment caught ALL em-main reverted (kept cicd-monitor PE-deploy harvest hợp-lệ). Guard HELD again. **WF2 fix:** added explicit "RETURN-ONLY: do NOT write ANY file incl MEMORY.md" to every lane prompt **0 residual** (instruction-fix worked, git-diff confirmed). Lesson: workflow-agent frontmatter "update MEMORY before return" fights return-only mandate prompt MUST override + git-diff is the net (G-015, not mechanized).
- **recurrence S95 (2026-07-01, H17 adopt):** AS-10 **3rd + 4th fire** WF1 (investigator-codebase self-compacted its MEMORY.md 25.516.98KB, CLAIMED archive-move but `archive/2026-06.md` was NOT created keeping it would have LOST 8.5KB) + WF3-Lane-A (reviewer self-wrote diary + new `project_s95_harness17_faultinjection.md`). git-diff post-P2 caught BOTH em-main reverted; cicd-monitor diary KEPT (normal-monitor-spawn, NOT return-only = legit). Guard HELD 2×. **🔑 Instruction-fix NOT 100%:** WF2(H17) had explicit return-only 0 residual, but **WF3 ALSO had explicit "TUYỆT ĐỐI return-only" yet reviewer STILL self-wrote** persona-write is stochastic; explicit-prompt REDUCES but does NOT eliminate **git-diff-revert remains the mandatory net (G-015 reconfirmed, instruction-alone insufficient).** Distinction codified: workflow-return-only-agent = REVERT; normal-monitor-spawn (diary verdict) = KEEP. **Dogfood:** contained WHILE adopting H17 whose C3-floor = single-writer the very floor being adopted saved real data. Guard net-effect ++ (4 fires, 4 catches, 0 escape).
- **recurrence S101 (2026-07-03):** AS-10 **fire 5-6 từ WORKFLOW LANES** (không phải monitor) WF1-H19 `investigator-codebase` + WF2-H18/H19 `reviewer` auto-ghi agent-memory theo frontmatter "Update MEMORY before return", bypass HMW B3 single-writer. git-diff bắt (session-end change-set) **harvest-curator Fidelity-gate PASS** (verify ĐỘC-LẬP: reviewer README:51-fix claim landed-verbatim hunk `@@-48,5+48,5`, 0 fabrication; U+FFFD=0/11; containment intact committed `e350660`) **KEPT per AS-10 keep-if-correct.** 🔑 KHÁC S95 default "workflow-lane=REVERT": S95 writes vấn-đề (stray mis-named file · claimed-missing-archive) revert; S101 writes = CLEAN harvest khớp lane-verdict keep-if-correct thắng. **Quyết bằng Fidelity-gate (harvest-curator), KHÔNG tự-phán** (đúng §L.b(f) nghi-bịaescalate 🟥 reviewer; đây 0-flag). **Cross-link:** dogfood-validate H19 §K.C GAP-3 "N-lane RETURN-only = convention KHÔNG mechanism" chính phiên codify GAP-3 thấy fire. Guard git-diff + Fidelity-gate HELD (6 fire, 6 catch, 0 escape). Tension frontmatter "update-MEMORY-before-return" HMW "return-only" stays-on-watch (commit-gate đủ defense-in-depth, chưa cần hook-block).
- **tags:** [containment-residual-write / monitor-sub+workflow-agent / governance-docs+agent-memory]
### E-005 — AS-1 `git add -A` on S49 governance commit (self-caught @session-end §L.a)
- **rule (AS-1):** stage specific files, not `git add -A`/`.` (concurrency safety `feedback_rag_mcp_recovery_concurrency`).
- **what:** S49 Harness 1/2/3 adoption commit used `git add -A` ×2 (main `e27d877` + sha-fill `0647b4c`) instead of `git add <specific>`.
- **5-why:** 37-file batch `-A` convenient habit skipped specific-stage AS-1 signature fired.
- **fix:** (process) MITIGATED pre-commit `git add -A --dry-run` verified exact 37-file scope + wave-folder-leak=0 + 0 unintended files BEFORE commit; no concurrent SE session running. Scope was correct no retroactive re-stage needed. (guard) next multi-file commit `git add <list>` OR dry-run-verify-first (this session did dry-run = acceptable mitigation).
- **prevention/guard:** Active-Guard AS-1 "add-specific or dry-run-verify-first". Blameless: outcome clean, but signature logged for honesty L.a = catch signature, not excuse it).
- **recurrence S71:** 2× `git add -A` (commits `8c47bd0` + `7875b39`) mitigated y hệt: `git status --short` containment-audit review FULL scope TRƯỚC mỗi stage (verify-first = mitigation hợp-lệ per guard); 0 unintended file (run-trace tracked + agent-memory curate = đúng tập dự kiến). Pattern ổn định: `-A` + pre-stage-status-review acceptable khi scope đã audit.
- **tags:** [git-hygiene / em-main / commit]
### E-004 — gotcha #53 agent truncation mid-MEMORY (recurring S35-S42)
- **rule:** agent must flush MEMORY before return; em main must receive complete work.
- **what:** heavy WRITE-agent (implementer/test-specialist) output truncates mid-MEMORY-update; return looks complete but isn't.
- **5-why:** brief too heavy spawn output cap hit truncation at the tail MEMORY update is last step silent partial.
- **fix:** (code/process) em main grep-verify-on-disk after return + proxy-append the agent's MEMORY next session (Strategy B, `feedback_implementer_truncation_mitigation`). (guard) brief 8K + Tiered Memory L1 ~30KB cap.
- **prevention/guard:** Active-Guard "verify-on-disk + proxy-append" (promoted, 5 strikes). 529 em main solo fallback, no retry-loop.
- **tags:** [process-truncation / sub-agent / agent-memory]
### E-003 — gotcha #44 silent 403 (S18, regression-tested S45)
- **rule:** authorization must fail loud, not silently break UX.
- **what:** class-level `[Authorize(Policy="Workflows.Read")]` non-admin 403 TanStack Query catch silent Drafter saw empty Workspace dropdown, no error.
- **5-why:** broad class-level policy GET blocked for non-admin FE swallowed 403 no surfaced error looked like "no data".
- **fix:** (code) class-level `[Authorize]` only; GET for any-authenticated; POST/DELETE keep admin policy. (guard) test-specialist authz regression test +10 (S45) reflection-scan per-action policy.
- **prevention/guard:** Active-Guard "authz regression test per-action policy" (promoted S45).
- **tags:** [authz-regression / backend+frontend / ApprovalWorkflowsV2Controller]
### E-002 — gotcha #57 Holiday UNIQUE unfiltered → 500 (S45, fixed Mig 43)
- **rule (AS-4):** soft-delete entity + UNIQUE index MUST `.HasFilter("[IsDeleted]=0")`.
- **what:** `Holidays` DB UNIQUE (Year,Date) unfiltered vs handler `!IsDeleted` admin delete + re-add same-date holiday = reachable 500.
- **5-why:** UNIQUE created unfiltered soft-deleted row keeps the slot handler allows logical re-create INSERT hits dead UNIQUE 500.
- **fix:** (code) Mig 43 `.HasFilter("[IsDeleted]=0")` (matches 13× existing pattern). (guard) Gap1 test-before reproduced the 500 first.
- **prevention/guard:** Active-Guard AS-4 + test-before. **RESOLVED S51 (Mig 45 `FilterHrmCatalogUniqueIndexesByIsDeleted`):** LeaveType + ShiftPattern + **OtPolicy** (OtPolicy was MISSED in "2 catalog" backlog caught via grep-all-config) now `.HasFilter("[IsDeleted]=0")`; test-before +5 `HrmConfigFilteredUniqueTests` REDGREEN (guard 2nd strike now verified). **EXT OPEN (worktree session S51, Mig 46):** Department/Supplier/Project (Master GLOBAL query-filter quirk auto-hides soft-deleted recreate reachable); ContractClause/MeetingRoom/EmployeeProfile = audit-SKIP (not-reachable, investigator S51).
- **tags:** [soft-delete-invariant / em-main+test-specialist / Holidays,LeaveType,ShiftPattern,OtPolicy,(ext)Master]
### E-001 — S46 user-memory 0-byte (close-out truncation)
- **rule (AS-8):** memory `.md` writes must persist (byte>0); index must not be empty.
- **what:** S45 close-out left `MEMORY.md` index + 1 entry at 0 bytes → S46 bootstrap ran with NO memory auto-inject (silent degrade).
- **5-why:** session-end Write created stub → body Write truncated (gotcha #53) → 0-byte file → not git-tracked (outside repo) → undetected until next bootstrap audit.
- **fix:** (process) rebuilt index + repopulated entry (S46). (guard) `feedback_session_end_memory_write_verify` + now session-end §L.b step (e)/(c) byte-check.
- **prevention/guard:** Active-Guard "session-end verify byte>0" (episodic→promoted S48, wired §L.b). `/session-start` audit also re-checks 0-byte (caught it S46, re-ran clean S48).
- **tags:** [memory-integrity / em-main / user-memory]
---
> **Maintenance:** append RCA on each AS-hit; promote a guard to `procedural` on its 2nd strike; mark `verified` once it holds through a session; retire by net-effect. Pointer entries only — full narrative lives in session-logs (summary-index).