§L.a RCA: - E-012 + AS-16 NEW "bằng-chứng-tự-huỷ-sau-squash": outward artifact cite sha chưa-push / stamp trước khi git status sạch. Root = tiêu-chí verify chọn theo cái MÌNH đo được, không theo cái NGƯỜI NHẬN sẽ đo (cùng lớp E-010). Đối chứng: wave trước cite commit đích -> sống hết. §L.b: - (c) memory-triple: do exit 0 · de-xuat A7 251/251 · kiem reviewer FAIL 1C/4M/4m/1nit · do-record TOTAL 47 + nhip-no 4-vế. sleep-check 4d < 7d -> không INFORM. - (d)(f) harvest-curator GATE-PASS-5, 5-trục PASS, Fidelity on-behalf PASS STRONG 0-fabrication, C5 dạng-1 đủ, orphan 0/40, Sàn-5 khớp. Spawn-record 5 sub. - (g) tooling-auditor DRIFT-FOUND(4) -> vá hết: F-A doc "3-vế" vs script 4-vế (7 site prescriptive; giữ 15 file frozen) · F-B ghost-enum HIGH (mở enum 10->11 mà quên chính vai dùng nó + 2 site số) · F-C lead-model pin chưa ghi sổ (thêm dòng Lead row S143; cell canonical để owner quyết) · F-D marketplace. - (j) H24: class_repeat cập theo 2 vai · last_audit light/deep = 17 · history +S143 (khai rõ force-fire SỚM 1 nhịp theo lệnh owner, KHÔNG tới-hạn tự-nhiên). - (k) trio SKIP có vết (cần restart CLI) -> ghi CẢ session-log vì §6.4 reset WAL. Sửa-một-phía bắt được 4 lần trong phiên (tool-grant · enum · sổ đếm garble · _note counter) -> bài: đổi một con số thì grep con số đó repo-wide trước khi đóng. #53: 5/5 sub garble, 0 mất dữ-liệu nhờ ghi-đĩa. Tally ×20 -> ×25, +path-4 lead-on-behalf khi resume không cứu được diary. Test 528 kế-thừa (0 file src/fe/tests bị đụng, verify bằng diff). Bundle FROZEN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
39 KiB
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) |
🛡️ 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ự khaiverifiedkhi 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ànhPASS-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)trongscripts/governance-detectors.ps1Vì 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
9a35405bkhố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/6quá-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 auditlight 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.ps1có trên đĩa;H25-closeout-ritualcòn wired trong suite và chạy ra output) ⇒ nấcPASS-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.mddạngtrio: skipped S<nn> (lý-do)để chuỗi skip nhìn thấy được. Khai nấcPASS-với-carve-outtrong 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) | ++ |
| 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-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 --porcelainTRƯỚ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-email6c 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(đềuwal:-commit local). Closeout §5.0reset --soft HEAD~8gộp chúng vào2757e41⇒ cả 5 thành dangling:cat-file -t=commit(sống nhờ reflog LOCAL) nhưngmerge-base --is-ancestor <sha> origin/main= exit 1 ⇒ hub clone repo vềgit show 1a0fa59= object missing. Nội-dung nguyên vẹn trong2757e41⇒ chết con-trỏ, không chết việc. (2) Cùng gốc: report + email khaiis-ancestor 96ab2679 HEAD = exit 0 → OK-reachablelàm bằng-chứng "contract v2 chạy runtime" — squash cùng phiên lật nó thànhexit 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:47khai "vế pull-age chưa làm, chờ owner" — owner gật ngay sau đó, lead làm,scripts/nhip-no-probe.ps1sử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 -txanh ⇒ 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ờie43484cef10fcho 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 statuslà 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-emailbước 6c một phépgit status --porcelain= rỗng +merge-base --is-ancestor <mọi sha cite> origin/maintrướ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ư58e28baeKHÔ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 (S138–S139) 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
/pausechứ không phải/session-end. - what: 3 closeout liên-tiếp — S128
289ba9620:57 · S129295c70c23:16 · S13071757fc00: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 =e9124fc15: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, emaile46863c8): mạch pause→/tiepkhô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/tiepnố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
/tiepnố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 hube46863c83-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ửatiep.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-Contenttrê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 + appendfeedback_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 ghireviewer/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-03ffile-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
LockDemoSampleUsersAsync14 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:DemoUserPassword11 ký tự < prodIdentity:Password:RequiredLength=12→CreateAsynctrả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 là source-of-truth population → Dev ≠ prod vì password-policy silent-fail → silent vì
IdentityResultkhô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 mù 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 mentionUser@12345611 chars OUTDATED", 20 UAT user seed bằngTestUser@202612 ký tự) — nhưng constDemoUserPasswordtrong code KHÔNG được fix lúc đó → knowledge nằm trong session-log mà 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)
5998163union 20 email prod-population (exact-email, KHÔNG pattern —binh.le@người thật sát scheme demo) + password → 12 ký 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 có 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 BE∥FE parallel (file-disjoint) spawn. Driver
phoneNumber/licenseNumber/licenseClass: BENotEmpty()validator + EF.IsRequired()NOT NULL, but FE KIND_CONFIG rendered them OPTIONAL (norequired:true) →buildBodyempty→null → 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:trueon 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:trueon 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 episodic→procedural promotions + E-002 #57 coords), 3adap-reports(nac→verified-runtime), 4agent-memory/*Recent-activity, +STATUS.md(Recently-Done-S50 block / In-Progress flip / RAG-line 2406↔2415 reconcile). mtimes 00:00–00: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 diffreview = 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/Editremoval 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.5→16.98KB, CLAIMED archive-move but
archive/2026-06.mdwas NOT created → keeping it would have LOST 8.5KB) + WF3-Lane-A (reviewer self-wrote diary + newproject_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/H19reviewerauto-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 — committede350660) → KEPT per AS-10 keep-if-correct. 🔑 KHÁC S95 default "workflow-lane=REVERT": S95 writes CÓ 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ịa→escalate 🟥 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 nó 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 (maine27d877+ sha-fill0647b4c) instead ofgit add <specific>. - 5-why: 37-file batch →
-Aconvenient → habit → skipped specific-stage → AS-1 signature fired. - fix: (process) MITIGATED pre-commit —
git add -A --dry-runverified 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(commits8c47bd0+7875b39) — mitigated y hệt:git status --shortcontainment-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:
HolidaysDB 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 +5HrmConfigFilteredUniqueTestsRED→GREEN (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
.mdwrites must persist (byte>0); index must not be empty. - what: S45 close-out left
MEMORY.mdindex + 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-startaudit 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
proceduralon its 2nd strike; markverifiedonce it holds through a session; retire by net-effect. Pointer entries only — full narrative lives in session-logs (summary-index).