From f69af273cf9b66288a61d3b6471185b45e504e2b Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Mon, 10 Aug 2026 02:35:20 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20Docs:=20bookend=20@close=20S185=20ON?= =?UTF-8?q?E-SHOT=20(YC-018)=20=E2=80=94=20trio+H24deep+ring1/2+ctx=209-va?= =?UTF-8?q?i=20mot-mach,=20harvest=20698KB->11=20so,=2016-FLAG=20patched,?= =?UTF-8?q?=20Tests=20canonical=20668?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .claude/WAL.md | 2 +- .claude/agent-memory/harness-refine/MEMORY.md | 2 + .../implementer-backend/MEMORY.md | 4 +- .../implementer-backend/archive/2026-07.md | 3 + .../agent-memory/lead-stale-auditor/MEMORY.md | 14 +- .../lead-stale-auditor/archive/2026-07.md | 16 + .claude/agents/README.md | 2 + .claude/agents/lead-stale-auditor.md | 4 +- .claude/commands/adap-apply.md | 3 +- .claude/commands/fable-clone.md | 1 + .claude/commands/session-end.md | 6 + .claude/commands/session-start.md | 4 + .claude/governance/.session-counter.json | 57 +- .claude/sessions/session-13/_mind-s-13.md | 40 ++ .../bookend-close-synthesis.md | 33 + .../runs/2026-08-09-S185-bookend-close/run.md | 2 +- .../sub-ctx-audit-close.md | 285 +++++++++ CLAUDE.md | 7 + docs/HANDOFF.md | 30 +- docs/STATUS.md | 4 +- ...master-checklist-hai-tang-moi-cua-phien.md | 69 ++ ...ance-session-model-phien-logic-manifest.md | 38 ++ ...-19-Governance-goi-chot-owner-nam-khoan.md | 58 ++ ...-05-Governance-loi-do-luong-phan-1-va-2.md | 69 ++ ...huc-hai-dau-nhip-thua-va-luu-nguyen-van.md | 21 + docs/governance/adap-upgrade-pack-tracking.md | 19 +- docs/governance/ctx-soft-memory-se-draft.md | 4 +- docs/governance/naming-standard.md | 24 + docs/governance/so-yeu-cau-chu-du-an.md | 9 +- scripts/governance-detectors.ps1 | 438 ++++++++++++- scripts/loi-hua-may-baseline.json | 190 ++++++ scripts/loi-hua-may-scan.ps1 | 591 ++++++++++++++++++ scripts/nhip-no-probe.ps1 | 5 +- scripts/tien-kiem-cua.ps1 | 22 +- 34 files changed, 2004 insertions(+), 72 deletions(-) create mode 100644 .claude/agent-memory/lead-stale-auditor/archive/2026-07.md create mode 100644 .claude/workflows/runs/2026-08-09-S185-bookend-close/bookend-close-synthesis.md create mode 100644 .claude/workflows/runs/2026-08-09-S185-bookend-close/sub-ctx-audit-close.md create mode 100644 scripts/loi-hua-may-baseline.json create mode 100644 scripts/loi-hua-may-scan.ps1 diff --git a/.claude/WAL.md b/.claude/WAL.md index 7e6d660..d1c68ee 100644 --- a/.claude/WAL.md +++ b/.claude/WAL.md @@ -10,7 +10,7 @@ chain: [x] pause-2 nghi thức: PAUSE-2 land trước chèn (curator #1) + MIND-2 (curator SUA-6 → sửa cả 6) + marker + snapshot [ ] acceptance MẮT-ANH prod đọc-only: 8 leaf "Duyệt KHKK — Nhóm n" ra panel khuôn DuyetNcc + dialog 9-ô theo D3=C — 🔴 KHÔNG bấm "Tạo phiên bản mới" trên prod (ratchet 1 chiều) [ ] acceptance ĐỘNG local: seed 1 level cờ=true (A2-răng) + 1 phiếu ChoDuyet (T8) rồi đo -[ ] bookend @close: trio vòng-auto + cặp H24 @close + ring2 + DEEP-SWEEP (18/15 OVERDUE @S184-tick counter 57→58 — NEXT-em, giữ phán quyết FLAG-4) + ctx-audit @close (mồi = ring1-persona "CẤM chạy @open") +[x] bookend @close ONE-SHOT @S185 (YC-018 lượt đầu): 9 vai + 5 máy MỘT MẠCH — harvest 698KB→17-khối/11-sổ+7-tệp+7-lane · trio 40Đ/4T-183-số · H24-deep 16-FLAG trả-nợ-19/15 (tally máy @59) · ring2 16Đ/0T · ring1 30Đ/3T · tooling PWF-6 · ctx-audit 8-FLAG + MIND-3 (mind-check 11/11) · vá-sau-verdict: STATUS-668 + HANDOFF-12-slug-khôi-phục + sổ-YC-lật + A1/A2/A3 + (k-ter)-máy-3 · probe-sau: deep 0/15 ok, over-cap 5→3 — verify: test -s .claude/workflows/runs/2026-08-09-S185-bookend-close/bookend-close-synthesis.md [ ] governance-vá + đóng sổ: CÒN gom nợ harvest 576.255B/18-lượt (uỷ-quyền slot 71) + STATUS/HANDOFF closeout + YC-013 lật đóng sau mắt-anh — ✅ @S185: orphan S182 ĐÓNG (`implement-synthesis.md` + 7/7 ô + 2-thước-im) · 3 site tự-quy-chiếu VÁ+verify (session-start:161-162 trỏ-enum thay chép-class · detectors.ps1 pre-marker-segment → 29 slug vào lưới EXIT=0 · HANDOFF:58 dòng-bổ-sung giữ ảnh-chụp) [x] YC-017 ĐÓNG @S185: P1-P4 trọn — wf_5d16a842-28e 7/7 lane (16D+3P-đúng-luật+1S-khai; +C-7 lead tự vá rơi ⇒ 21/21 disposition) + verify-lead 3/3 + synthesis land — verify: test -s .claude/workflows/runs/2026-08-09-S185-email-adap-pipeline/implement-synthesis.md · tồn: C-1-đợi-rider-jump(nợ-chưa-có-chủ F-L2-2) · C-6-quyết-nén-ring2 · 4W+5-SKIP-owner (trình anh cuối lượt) [x] adap thư 08-08 TRỌN @S185 (Harness-9 2-workflow): 3 phép-thử ĐO THẬT (sàn-vs-trần ring2 DƯƠNG 24.793=96,8%cap+A5 · công-cụ-nói-dối ÂM 3/3-khớp · đo-trước-gộp DƯƠNG→vá `(f-bis)` session-end) + REVIEW độc-lập `PASS_WITH_FIXES` (2 FIX áp: nhãn f-bis + "dưới ràng-buộc A5") + K5 "đèn KHÔNG đếm 11 lớp" ghi vào report — verify: test -s docs/governance/adap-reports/2026-08-08-Governance-quy-trinh-hai-dau-phien-may-diem-danh-va-6-bai-hoc.md diff --git a/.claude/agent-memory/harness-refine/MEMORY.md b/.claude/agent-memory/harness-refine/MEMORY.md index 34020bf..263ac50 100644 --- a/.claude/agent-memory/harness-refine/MEMORY.md +++ b/.claude/agent-memory/harness-refine/MEMORY.md @@ -43,3 +43,5 @@ Con ĐỀ-XUẤT của bộ-ba đồng-kiểm memory-system (adopt AI_INFRA 2026 - 🔴 **Đây là VÒNG PHẢN HỒI DƯƠNG, không phải nợ kỹ-thuật:** khâu APPEND hỏng ⇒ diary đóng băng ⇒ sổ chốt-dừng sai ⇒ **quyết-định đề-xuất hỏng theo**. Cái hỏng ở khâu GHI quay lại làm hỏng khâu QUYẾT ĐỊNH. - 🔴 **5 TRƯỢT (harness-audit) đều ở TIỀN-ĐỀ, không ở lõi:** A2 *"+2.639 B / **1 ngày**"* thật = **9h52** (+0 B kể từ đó) · *"**nhanh nhất đội hình**"* **không chứng được** (vai này tự khai chạy **0 instrument**, số nền là eval-return vốn không chứa per-role history). Nhưng **A2 vẫn đứng** vì neo vào **headroom 2.315 < tripwire 3.070**, không neo vào tốc-độ. - Bài: **tách "số-học ĐẠT" khỏi "tiền-đề TRƯỢT"** — đừng làm tròn thành ĐẠT hay TRƯỢT; và **claim so-sánh cần phép so**, không suy từ 2 điểm đo. + +- **S185 (08-10) LUẬT promote (A3, audit-verified) `[LEAD APPEND theo refine-return]`:** **span ≠ nhãn heading.** CẤM neo action vào tiêu-đề span hay vào PROPOSE của archive-gate mà chưa MỞ SPAN ĐỌC DÒNG MỚI NHẤT bên trong. Pool drain = span ngoài last-N theo VỊ TRÍ, mà corpus này đặt mục cấu-trúc (Role baseline/Runs) ở ĐẦU ⇒ máy chĩa đúng vào phần phải giữ. Ca thật: nháp A1 suýt archive span "S152" chứa entry S185 viết cùng tối. Lặp ≥2 (S173 mù-trên-heading-đầu → S185 4/4 file). Tag `[s185, span-khac-nhan, mo-span-doc-dong-moi-nhat, keep-floor-vi-tri]` diff --git a/.claude/agent-memory/implementer-backend/MEMORY.md b/.claude/agent-memory/implementer-backend/MEMORY.md index abc84a5..a316c97 100644 --- a/.claude/agent-memory/implementer-backend/MEMORY.md +++ b/.claude/agent-memory/implementer-backend/MEMORY.md @@ -100,8 +100,8 @@ UI `disabled={!canX}` + BE helper `EnsureCanXAsync(id, userId)` throw 403 (NOT i - >~30KB → archive recent → L2 `archive/.md`. Stale >3mo → remove. - **Last curate: 2026-08-01 S167 (self-FIFO, hook read-limit-guard bắn @22.4KB)** (22.4→15.4KB, dưới ngưỡng 17.1KB hook đòi): moved verbatim 4 entry Recent-activity 2026-07-12/13 (S116/S113/S112×2) → `archive/2026-07.md` (2.8→10.3KB). Mục Recent-activity nay rỗng có chủ đích — việc SỐNG ở khối L1 HOT đầu file. Prev **S116** (21.5→~15KB): moved 3 oldest Recent-activity (2026-06-19/24/25: PE chuông · PE Section-B Mig 59 · S88 frozen-relocation) verbatim → `archive/2026-06.md`, kept 4 newest (S116/S113/S112×2). Prev **S112** (25.6→~16KB): S77→S56 7-entry → 2026-06.md. Prev **S70 Harness-9** (33.2→17.4KB): L2 dark-matter recovery + `_INDEX` + gists. Prev: S40 dedup-split · S34 · S22. -## S152 (2026-07-25) — R1 retention-note ranh auto-refuse test [M9 on-behalf lead] -- **Integration testing multiple components = việc `test-specialist`, KHÔNG phải mình** — mình scaffold + compile-check; assertion/integration test cross-component (SQLite fixture, authz regression) do test-specialist own (tiền lệ S67 HRM test-after +23, S69 +20 đều test-specialist). Nhận viết integration test = double-touch tests/ sai split. Tag `[s152, r1-retention, refuse-integration-testing-components]` +## S182→S185 (08-08→08-09) — entries mới-nhất (heading cũ "S152" đổi @S185 refine-A1: span≠nhãn — ruột span này chứa S182+S185; bullet S152 verbatim → `archive/2026-07.md`) +- (S152 R1 retention-note → `archive/2026-07.md` @S185 — moved-not-cut, 430B) - **S182 YC-013 (lead-seed, C2 /pause — lane đứt limit giữa W1, lane 1bis nối TỪ ĐĨA):** W0 trọn — phát hiện local có BA DB (lượt đầu trỏ nhầm base, TỰ KHAI "nhìn lượt đầu mà tuyên xong = PASS giả" rồi chạy lại đúng _Dev+_Design lên Mig 72) + baseline 645 đo độc lập + seed 8 row local ĐỦ roster. W1 5-fix land: `ContractSigningPlanWorkflowGuards.cs` public-static (Submit ở Infrastructure không thấy internal — 3 lối đã cân nhắc ghi doc-comment) · per-Code deactivate + normalize Trim().ToUpperInvariant() @`:348` (MAJOR-2 collation SQLite khác SQL-Server) · pin-check D6 2 message tách · changelog type-10 · DELETE-guard 8-module + IgnoreQueryFilters + D5+ApplicableType. Suite 660/0. → `runs/2026-08-08-S182-khkk-awf-mirror-ncc/sub-implementer-backend-0.md` diff --git a/.claude/agent-memory/implementer-backend/archive/2026-07.md b/.claude/agent-memory/implementer-backend/archive/2026-07.md index e1f0b6e..c580076 100644 --- a/.claude/agent-memory/implementer-backend/archive/2026-07.md +++ b/.claude/agent-memory/implementer-backend/archive/2026-07.md @@ -14,3 +14,6 @@ - **2026-07-12 (S112 PE sign-off close-review implement — `wf_7df56b89-7bb` GO-WITH-ADJ, owner anh Kiệt PROD-UAT-live, 4-region/1 file `PurchaseEvaluationWorkflowService.cs`, NO mig/FE/test → ACCEPT Case 1):** **C1 A1 (`ApplyDrafterBypassOnSubmitAsync`):** người soạn KÝ TAY ô cấp mình — `k=Max`→`minOwn=Min(drafterSlots.Order)`, bypass `<=k`→`1){pointer=minOwn}` STOP tại minOwn (người soạn tự ApproveV2Async); minOwn=1→bypass rỗng pointer giữ (0,1); non-contiguous Cấp1+Cấp3 ký tay đúng thứ tự. **C2 EDGE-5 hard-lock:** top `TransitionAsync` sau isAdmin/isSystem TRƯỚC mọi branch → `if(fromPhase is DaDuyet or TuChoi && !isAdmin && !isSystem) throw Conflict` (chặn non-admin lật phiếu terminal; Admin+System MIỄN); KHÔNG đụng EnsureCanRejectV2Async. **C3** no self-finalize (owner oQ1 permission-driven). **C4 opinion-history (`ApproveV2Async` UPSERT else):** old.Comment→Changelog (Workflow/Update/EntityId=level.Id) TRƯỚC overwrite chỉ khi non-empty — NO mig/bảng/endpoint. Build slnx **0/0**. Infra **4 FAIL/401 pass**: fail=C1 (PeSubmitGuardAndBypassTests 9/10/12/14 assert OLD auto-sign/terminal-on-submit); C2/C4 break 0 test → test-specialist ADD. LESSON: behavior-change write-site → run consumer tests, hand VERIFIED fail-list (KHÔNG sửa test). Tag `[s112, pe-signoff, a1-sign-own-level, edge5-hardlock, opinion-history-changelog, consumer-test-verified-handoff]`. - **2026-07-12 (S112 Supplier Excel-import Phase B BE — `wf_e2f23a84` invest-ensemble → `wf_75d6149b` close-review GO-WITH-ADJ, owner anh Kiệt, commit `e100ef0`, Mig 63 → ACCEPT Case 1/2):** **Service** `SupplierExcelImportService` (preview + confirm 2-stage) + 2 endpoint (`/suppliers/import/preview` [415 non-xlsx] · `/suppliers/import/confirm` [401 auth]) + **Mig 63 `AddSupplierImportSourceFields`** (Supplier +`SourceUpdatedAt datetime2?`+`SourceUpdatedBy nvarchar(200)?` provenance cột 29/30; 2 AddColumn nullable no-new-table 89). FE 2-app byte-identical (`SupplierImportDialog`). **LESSONS:** (1) dedup Code = **OrdinalIgnoreCase ở SERVICE** — DB unique-index CI-collation lật (SQLite fixture BINARY KHÔNG bắt, prod SQL Server CI bắt) → dedup KHÔNG dựa DB; (2) parser **absolute cell-index** (row-4 header-fingerprint), KHÔNG `CellsUsed()` (column-drift); (3) **all-or-nothing** gate TRƯỚC mutate (1 hard-error→Committed=false DB unchanged); (4) fill-nulls **SKIP Code/Name/Type** (chỉ điền field trống); (5) `.Normalize(FormC)` cho real-file NFD (close-review adjust bake 30 `RealFileHeaderTokens` byte-verify). **SURPRISE:** Approach-B (extend seed) ĐÃ ship 4 NCC prod (Mig 62) → spec "partial" SAI; import ghi entity **TRỰC TIẾP** (fill-where-non-empty) KHÔNG qua `UpdateSupplierCommand` (tránh NULL-clobber #73). Shipped Run #496 PASS, reviewer GO-WITH-ADJ (BE 6/6 axes). Tag `[s112, supplier-excel-import, mig63, ordinalignorecase-dedup-at-service, abs-cell-index-parser, all-or-nothing, fill-nulls-safe, normalize-formc-nfd, direct-entity-write]`. + +## @S152 R1 retention-note [moved-not-cut @S185 refine-A1, verbatim] +- **Integration testing multiple components = việc `test-specialist`, KHÔNG phải mình** — mình scaffold + compile-check; assertion/integration test cross-component (SQLite fixture, authz regression) do test-specialist own (tiền lệ S67 HRM test-after +23, S69 +20 đều test-specialist). Nhận viết integration test = double-touch tests/ sai split. Tag `[s152, r1-retention, refuse-integration-testing-components]` diff --git a/.claude/agent-memory/lead-stale-auditor/MEMORY.md b/.claude/agent-memory/lead-stale-auditor/MEMORY.md index 3689321..44347ef 100644 --- a/.claude/agent-memory/lead-stale-auditor/MEMORY.md +++ b/.claude/agent-memory/lead-stale-auditor/MEMORY.md @@ -23,17 +23,11 @@ H24 §2(1) vai-STALE — soi VIEW LỆCH SOURCE của cái LEAD surface. Class ∈ enum ĐÓNG `lead_self_audit.flag_classes` (5 view-*): view-residual-asym · view-stale-count · view-stale-status · view-stale-header · view-stale-role-desc. KHÔNG tự chế class; không phân-loại được → verbatim + escalate anh. Chạy theo NHỊP `h24_cadence` (đọc config, CẤM hardcode). ĐỌC output máy (`governance-detectors.ps1`) làm nền — chỉ thêm lăng-kính NGỮ-NGHĨA máy không phán được. KHÔNG lấn: tooling-freshness (H1) · harvest (H2) · cái-THIẾU (lead-gap-auditor). -## 📅 Runs +## 📅 Runs — TÓM (@S185 refine-A2; verbatim 8462B → `archive/2026-07.md`, moved-not-cut) -- **S124 (2026-07-15) FIRST real run / dogfood [fable-clone wave · counter=3 · retro-harvest @S132]:** **9 FLAG** = view-residual-asym ×8 + view-stale-count ×1. Root = MỘT owner-flip (S124 model-tier: all-inherit → worker-tier-pin opus): hmw.js + 14/14 frontmatter = UPDATED (source) nhưng derived docs/memory KHÔNG — đúng chân-dung "sửa nguồn quên gương". Sites: agents/README:38 diagram · session-start:50/:43 (BƯỚC 0.6 chạy MỖI phiên — premise inverted) · fable-clone.md:63/:57/:43 (GAP#6 rationale INVERTED + line-drift :50→:53) · ultra-on:35 · auto-memory project_harness4 (DOUBLY-superseded mà inject mỗi phiên) · STATUS:6 + HANDOFF:5 mega-line (⚠️ caveat: TRỘN live-topology với frozen-narrative — PHẢI tách per-occurrence, frozen để yên). +1 count: README:222 "12 folder" vs đĩa 14. VERIFIED-CLEAN negative: budget/ACTIVE-MARKS bodies/roster-count-14 sạch — chống false-alarm. **Lesson:** (1) my-layer = semantic call máy mù ("2 variants coexist" → cái nào là LIVE-claim đã stale) + surfaces ngoài count-set máy; (2) mega-line = neo bằng TRÍCH không col; (3) jump_on_class_repeat đọc đúng: 8 hit cùng-class trong 1 audit = doc-sync debt của 1 flip, KHÔNG phải cross-audit recurrence (first audit = seeding tally). Tag `[s124, first-dogfood, view-residual-asym-8, one-flip-many-mirrors]` -- **[Post-S124 resolution @S132 retro-note]:** phần lớn 9 flag đã được vá S125-S126 (all-inherit sweep S126: 284 instance → 15 floor-sống/5 file vá + fault-inject 2-chiều — xem `feedback_harness4_two_tier_model` + commit lịch-sử); auto-memory project_harness4 đã relabel "Model-tier evolution → worker-tier-pin S124". Diary này seed muộn — lần chạy kế (~counter 9) ĐỌC baseline S124 ở đây thay vì mù. - -- **S140 (2026-07-18) light-audit #3 [counter 14 · force-fire-debt P=3 wal:pause S139 · owner-consent]:** Machine baseline TOTAL 45 (=S139, 0 flag mới) — chỉ soi ngữ-nghĩa. **1 FLAG (view-stale-status, LOW):** `HANDOFF.md:8` NEXT-em còn liệt "spawn-probe reviewer 5-nhãn … nâng `624c378d` verified-pending→executed-runtime" như việc PHẢI-LÀM, nhưng SOURCE = adap-report `624c378d`:9 ĐÃ nâng **executed-runtime @S140** (probe agentId a56dcf6da0425e86c, 17s, 0-garble). To-do xong mid-session, chờ closeout clear. class_repeat view-stale-status 1(S137)→2 (jump@3 chưa chạm). **VERIFIED-CLEAN (chống false-alarm):** (a) report `624c378d`:9 tự-thân=executed-runtime ĐÚNG = nguồn-chân-lý nấc; (b) `_index.md:48`="processed" = email-layer KHÔNG phải adap-nấc → 0 stale; (c) `HANDOFF:5`+`STATUS:462` "624c378d=verified-pending" = narrative-recap S138-S139 đóng-băng-đúng-thời-điểm → KHÔNG flag (trap#3 frozen); (d) **3b model-flip S140→Fable**: canonical `STATUS §Sub-agents:450` dừng enumerate ở flip-8/S107 CÓ CHỦ-ĐÍCH (S106 anti-churn) ⇒ 0 re-stamp; 3 derived (agents/README:5 · session-start:37/41 · session-end:113) point-not-enumerate, 0 stale-model literal → NO FLAG. **Lesson:** nấc-adap advance ở phiên KẾ (S140) trong khi narrative-recap kẹt ở phiên GHI (S139) = staleness sống ở forward-pointer (NEXT-em), KHÔNG ở recap; report tự-thân là nguồn-chân-lý nấc, đừng flag recap. Tag `[s140, light#3, view-stale-status-1, nac-advance-vs-recap, model-flip-no-restamp]` -- **S143 (2026-07-22) DEEP-audit [counter 17 · ngưỡng 18 ⇒ FORCE-FIRE SỚM 1 NHỊP theo direction owner, KHÔNG tới-hạn tự-nhiên]** `[#53 garble ×2 → APPEND on-behalf bởi em-main sau VERIFY, B3; vai chưa tự ghi được]` — nguồn verbatim `runs/2026-07-22-S143-closeout-audit/sub-lead-view-1.md`. Machine baseline TOTAL **47** (45→46→47; +1 sau closeout S143). **3 FLAG, cả 3 cùng class `view-residual-asym`** — đều là **dư-lượng sửa-một-phía của CHÍNH phiên đó**: (1) `STATUS.md:450` ô canonical còn *"NO Write/Edit (chặn-bằng-thiếu-tool)"* trong khi `:462` cùng file + memory `feedback_monitor_residual_write_containment` đã lật (commit `3f4310f` vá memory, quên ô canonical); (2) `agents/README.md:190` còn khai "NO Write/Edit" như sự-thật tool-grant; (3) `agents/README.md:27` dòng **tự xưng "Roster THẬT"** liệt 14 vai, thiếu đúng 3 trio — `git show 2757e41` = **0 hunk** chạm dòng này. 🔴 **Lesson lớn nhất (reviewer bắt thêm site thứ 4 `:225` cùng lớp):** sweep của wave đặt acceptance = grep theo **CON SỐ** (`roster 14|14/14|14 folder|14 vai`) → 0 hit → tuyên bố sạch; nhưng 2 site nặng nhất **liệt kê TÊN, không chứa số nào** ⇒ lọt lưới nguyên wave. **"0 hit" chỉ chứng minh pattern không khớp, KHÔNG chứng minh hết drift — acceptance phải ĐẾM PHẦN TỬ rồi so canonical.** Cả 4 site đã vá `36cefcc`. class_repeat view-residual-asym 0→1 (jump@3 chưa chạm); view-stale-status không tái-hiện → reset 0. Tag `[s143, deep-force-fire-som, view-residual-asym-3, enum-ten-lot-grep-so, sua-mot-phia]` - -- **S148 (2026-07-24) light-audit #4 [counter 22 · light 5/6 CHƯA tới hạn ⇒ FORCE-FIRE theo P=1 closeout-gộp, owner-direction — KHÔNG phải nhịp tự nhiên]** `[diary ghi TRONG lúc làm, anti-#53]` — Machine baseline TOTAL **46** (S143=47 → 46; canonical resolve mig=67 test=528 gotcha=83 table=89 menu=54 policy=216). **5 FLAG.** 🔴 **Ca nặng nhất = CANONICAL-POISON:** `STATUS.md:448` row `| Tests | **528 PASS** | 45 Domain + 483 Infra` NHƯNG `STATUS.md:6` cùng file + `changelog/sessions/2026-07-23-1730-S147…:38` đều ghi **532 (45D+487I, was 483I → +4)** ⇒ closeout S147 vá header quên ô canonical; hệ-quả: detector đọc canonical=528 nên **mọi flag C2/B3 test đo bằng thước sai**, `[OK] canonical matches disk` chỉ cross-check mig+gotcha, **KHÔNG** cross-check test ⇒ mù đúng chỗ. Cặp **BẤT-ĐỐI-XỨNG NGƯỢC CHIỀU** cùng 1 cặp file: `STATUS:6` ghi "gotcha 82" trong khi `STATUS:449`=83 VÀ `docs/gotchas.md` max anchor `### 83.`=83 ⇒ một file, hai row, mỗi row stale MỘT chiều khác nhau. **Lesson:** khi canonical-row và header-line cùng sống trong 1 file, closeout dễ vá 1-trong-2 → *đừng giả định canonical luôn đúng chỉ vì nó tên là canonical*; và **cross-check của máy phủ tới đâu thì mới tin tới đó** (mig+gotcha có, test/table/menu/policy KHÔNG). Tag `[s148, light#4, canonical-poison-test-count, header-vs-canonical-row, cross-check-coverage]` - -- **S150 (2026-07-25) BOOKEND @close lượt ĐẦU (hình B — vô-điều-kiện, KHÔNG theo counter) · phiên-logic 3 (S149+S150) · counter 24** `[🔸 SELF-WRITTEN trong lúc làm, anti-#53 — chờ em-main VERIFY per B3]` — Machine TOTAL **46**. **6 FLAG**, và 5/6 nằm trên **cùng 1 file** `docs/HANDOFF.md`. 🔴 **Gốc chung, không phải 5 lỗi rời:** cả phiên-logic chạm HANDOFF đúng **4 dòng-diff** (toàn sweep rename) — mọi quyết-định S149 (O-2 posture-A · O-3 tập-rỗng · O-7 cap 20 · thư model `59ce1d0f` [nay = pre-re-stamp; published `9c909007` @S152] · rename 5 vai) đổ vào `WAL`+`_context-s-3`+`budget.json`+`hmw.js` nhưng **KHÔNG đổ vào sổ owner-facing** ⇒ anh vẫn đang đọc 3 mục "chờ anh chốt" mà chính anh đã uỷ-quyền chốt hôm qua. **Lesson-1 (mới):** *khi quyết-định đi qua đường UỶ-QUYỀN (anh nói "Trả lời 4 câu") thay vì owner-gõ-từng-số, nó land ở nơi lead làm việc chứ không ở nơi owner đọc* — bookend phải soi đúng cái khe đó. **Lesson-2 (đo được, đắt):** trục H24-3 session-label **hiện 0 file có hiệu-lực** — `STATUS.md` có **0** chuỗi `Last updated` (anchor bị đổi hình thành `CURRENT`, đúng thứ comment `:592-595` của chính detector cấm) và `HANDOFF:5` viết `(**S147**` nên regex `\(S` trượt ⇒ nhãn S147 sống trên thân S148/S149 mà máy im. **Không sửa detector (khác turf), nhưng "0 flag" ở trục này KHÔNG đọc thành sạch.** Bẫy tránh được: `grep -c "public const string"` MenuKeys ra **51**, đếm PHẦN-TỬ `All` mới ra **54** = khớp canonical (bài S143 lặp lại nguyên si). Tag `[s150, bookend-close-lan-dau, uy-quyen-land-sai-so, h24-3-anchor-reshape-blind, handoff-1-goc-5-la]` +- **S150 @close bookend đầu (hình B):** 6 FLAG, 5/6 cùng `docs/HANDOFF.md` — gốc chung: quyết-định đi đường UỶ-QUYỀN land ở nơi lead làm việc, KHÔNG ở nơi owner đọc. H24-3 anchor bị reshape ⇒ "0 flag" trục đó KHÔNG đọc thành sạch. Đếm PHẦN-TỬ thay grep-const (51 vs 54, bài S143). +- **S151 @open + S151-deep:** 5 FLAG vá @batch; bài #53: append TỪNG finding ngay, VERIFIED-CLEAN phải KÈM LỆNH. +- Chi tiết + tag đầy đủ: archive trên. ## S151 (2026-07-25) — bookend @open hình B [M9 lead on-behalf, verify từ sub-file] - {task: soi view-lệch-source 5 surface · nấc: verified (ring2 8/8 ĐẠT) · evidence: runs/2026-07-25-S151-h24-open-bookend/sub-lead-stale-S151.md 14.636B} diff --git a/.claude/agent-memory/lead-stale-auditor/archive/2026-07.md b/.claude/agent-memory/lead-stale-auditor/archive/2026-07.md new file mode 100644 index 0000000..336e009 --- /dev/null +++ b/.claude/agent-memory/lead-stale-auditor/archive/2026-07.md @@ -0,0 +1,16 @@ +# lead-stale-auditor — archive 2026-07 (tạo @S185 refine-A2) + +## 📅 Runs [moved-not-cut @S185, verbatim 8462B] + +## 📅 Runs + +- **S124 (2026-07-15) FIRST real run / dogfood [fable-clone wave · counter=3 · retro-harvest @S132]:** **9 FLAG** = view-residual-asym ×8 + view-stale-count ×1. Root = MỘT owner-flip (S124 model-tier: all-inherit → worker-tier-pin opus): hmw.js + 14/14 frontmatter = UPDATED (source) nhưng derived docs/memory KHÔNG — đúng chân-dung "sửa nguồn quên gương". Sites: agents/README:38 diagram · session-start:50/:43 (BƯỚC 0.6 chạy MỖI phiên — premise inverted) · fable-clone.md:63/:57/:43 (GAP#6 rationale INVERTED + line-drift :50→:53) · ultra-on:35 · auto-memory project_harness4 (DOUBLY-superseded mà inject mỗi phiên) · STATUS:6 + HANDOFF:5 mega-line (⚠️ caveat: TRỘN live-topology với frozen-narrative — PHẢI tách per-occurrence, frozen để yên). +1 count: README:222 "12 folder" vs đĩa 14. VERIFIED-CLEAN negative: budget/ACTIVE-MARKS bodies/roster-count-14 sạch — chống false-alarm. **Lesson:** (1) my-layer = semantic call máy mù ("2 variants coexist" → cái nào là LIVE-claim đã stale) + surfaces ngoài count-set máy; (2) mega-line = neo bằng TRÍCH không col; (3) jump_on_class_repeat đọc đúng: 8 hit cùng-class trong 1 audit = doc-sync debt của 1 flip, KHÔNG phải cross-audit recurrence (first audit = seeding tally). Tag `[s124, first-dogfood, view-residual-asym-8, one-flip-many-mirrors]` +- **[Post-S124 resolution @S132 retro-note]:** phần lớn 9 flag đã được vá S125-S126 (all-inherit sweep S126: 284 instance → 15 floor-sống/5 file vá + fault-inject 2-chiều — xem `feedback_harness4_two_tier_model` + commit lịch-sử); auto-memory project_harness4 đã relabel "Model-tier evolution → worker-tier-pin S124". Diary này seed muộn — lần chạy kế (~counter 9) ĐỌC baseline S124 ở đây thay vì mù. + +- **S140 (2026-07-18) light-audit #3 [counter 14 · force-fire-debt P=3 wal:pause S139 · owner-consent]:** Machine baseline TOTAL 45 (=S139, 0 flag mới) — chỉ soi ngữ-nghĩa. **1 FLAG (view-stale-status, LOW):** `HANDOFF.md:8` NEXT-em còn liệt "spawn-probe reviewer 5-nhãn … nâng `624c378d` verified-pending→executed-runtime" như việc PHẢI-LÀM, nhưng SOURCE = adap-report `624c378d`:9 ĐÃ nâng **executed-runtime @S140** (probe agentId a56dcf6da0425e86c, 17s, 0-garble). To-do xong mid-session, chờ closeout clear. class_repeat view-stale-status 1(S137)→2 (jump@3 chưa chạm). **VERIFIED-CLEAN (chống false-alarm):** (a) report `624c378d`:9 tự-thân=executed-runtime ĐÚNG = nguồn-chân-lý nấc; (b) `_index.md:48`="processed" = email-layer KHÔNG phải adap-nấc → 0 stale; (c) `HANDOFF:5`+`STATUS:462` "624c378d=verified-pending" = narrative-recap S138-S139 đóng-băng-đúng-thời-điểm → KHÔNG flag (trap#3 frozen); (d) **3b model-flip S140→Fable**: canonical `STATUS §Sub-agents:450` dừng enumerate ở flip-8/S107 CÓ CHỦ-ĐÍCH (S106 anti-churn) ⇒ 0 re-stamp; 3 derived (agents/README:5 · session-start:37/41 · session-end:113) point-not-enumerate, 0 stale-model literal → NO FLAG. **Lesson:** nấc-adap advance ở phiên KẾ (S140) trong khi narrative-recap kẹt ở phiên GHI (S139) = staleness sống ở forward-pointer (NEXT-em), KHÔNG ở recap; report tự-thân là nguồn-chân-lý nấc, đừng flag recap. Tag `[s140, light#3, view-stale-status-1, nac-advance-vs-recap, model-flip-no-restamp]` +- **S143 (2026-07-22) DEEP-audit [counter 17 · ngưỡng 18 ⇒ FORCE-FIRE SỚM 1 NHỊP theo direction owner, KHÔNG tới-hạn tự-nhiên]** `[#53 garble ×2 → APPEND on-behalf bởi em-main sau VERIFY, B3; vai chưa tự ghi được]` — nguồn verbatim `runs/2026-07-22-S143-closeout-audit/sub-lead-view-1.md`. Machine baseline TOTAL **47** (45→46→47; +1 sau closeout S143). **3 FLAG, cả 3 cùng class `view-residual-asym`** — đều là **dư-lượng sửa-một-phía của CHÍNH phiên đó**: (1) `STATUS.md:450` ô canonical còn *"NO Write/Edit (chặn-bằng-thiếu-tool)"* trong khi `:462` cùng file + memory `feedback_monitor_residual_write_containment` đã lật (commit `3f4310f` vá memory, quên ô canonical); (2) `agents/README.md:190` còn khai "NO Write/Edit" như sự-thật tool-grant; (3) `agents/README.md:27` dòng **tự xưng "Roster THẬT"** liệt 14 vai, thiếu đúng 3 trio — `git show 2757e41` = **0 hunk** chạm dòng này. 🔴 **Lesson lớn nhất (reviewer bắt thêm site thứ 4 `:225` cùng lớp):** sweep của wave đặt acceptance = grep theo **CON SỐ** (`roster 14|14/14|14 folder|14 vai`) → 0 hit → tuyên bố sạch; nhưng 2 site nặng nhất **liệt kê TÊN, không chứa số nào** ⇒ lọt lưới nguyên wave. **"0 hit" chỉ chứng minh pattern không khớp, KHÔNG chứng minh hết drift — acceptance phải ĐẾM PHẦN TỬ rồi so canonical.** Cả 4 site đã vá `36cefcc`. class_repeat view-residual-asym 0→1 (jump@3 chưa chạm); view-stale-status không tái-hiện → reset 0. Tag `[s143, deep-force-fire-som, view-residual-asym-3, enum-ten-lot-grep-so, sua-mot-phia]` + +- **S148 (2026-07-24) light-audit #4 [counter 22 · light 5/6 CHƯA tới hạn ⇒ FORCE-FIRE theo P=1 closeout-gộp, owner-direction — KHÔNG phải nhịp tự nhiên]** `[diary ghi TRONG lúc làm, anti-#53]` — Machine baseline TOTAL **46** (S143=47 → 46; canonical resolve mig=67 test=528 gotcha=83 table=89 menu=54 policy=216). **5 FLAG.** 🔴 **Ca nặng nhất = CANONICAL-POISON:** `STATUS.md:448` row `| Tests | **528 PASS** | 45 Domain + 483 Infra` NHƯNG `STATUS.md:6` cùng file + `changelog/sessions/2026-07-23-1730-S147…:38` đều ghi **532 (45D+487I, was 483I → +4)** ⇒ closeout S147 vá header quên ô canonical; hệ-quả: detector đọc canonical=528 nên **mọi flag C2/B3 test đo bằng thước sai**, `[OK] canonical matches disk` chỉ cross-check mig+gotcha, **KHÔNG** cross-check test ⇒ mù đúng chỗ. Cặp **BẤT-ĐỐI-XỨNG NGƯỢC CHIỀU** cùng 1 cặp file: `STATUS:6` ghi "gotcha 82" trong khi `STATUS:449`=83 VÀ `docs/gotchas.md` max anchor `### 83.`=83 ⇒ một file, hai row, mỗi row stale MỘT chiều khác nhau. **Lesson:** khi canonical-row và header-line cùng sống trong 1 file, closeout dễ vá 1-trong-2 → *đừng giả định canonical luôn đúng chỉ vì nó tên là canonical*; và **cross-check của máy phủ tới đâu thì mới tin tới đó** (mig+gotcha có, test/table/menu/policy KHÔNG). Tag `[s148, light#4, canonical-poison-test-count, header-vs-canonical-row, cross-check-coverage]` + +- **S150 (2026-07-25) BOOKEND @close lượt ĐẦU (hình B — vô-điều-kiện, KHÔNG theo counter) · phiên-logic 3 (S149+S150) · counter 24** `[🔸 SELF-WRITTEN trong lúc làm, anti-#53 — chờ em-main VERIFY per B3]` — Machine TOTAL **46**. **6 FLAG**, và 5/6 nằm trên **cùng 1 file** `docs/HANDOFF.md`. 🔴 **Gốc chung, không phải 5 lỗi rời:** cả phiên-logic chạm HANDOFF đúng **4 dòng-diff** (toàn sweep rename) — mọi quyết-định S149 (O-2 posture-A · O-3 tập-rỗng · O-7 cap 20 · thư model `59ce1d0f` [nay = pre-re-stamp; published `9c909007` @S152] · rename 5 vai) đổ vào `WAL`+`_context-s-3`+`budget.json`+`hmw.js` nhưng **KHÔNG đổ vào sổ owner-facing** ⇒ anh vẫn đang đọc 3 mục "chờ anh chốt" mà chính anh đã uỷ-quyền chốt hôm qua. **Lesson-1 (mới):** *khi quyết-định đi qua đường UỶ-QUYỀN (anh nói "Trả lời 4 câu") thay vì owner-gõ-từng-số, nó land ở nơi lead làm việc chứ không ở nơi owner đọc* — bookend phải soi đúng cái khe đó. **Lesson-2 (đo được, đắt):** trục H24-3 session-label **hiện 0 file có hiệu-lực** — `STATUS.md` có **0** chuỗi `Last updated` (anchor bị đổi hình thành `CURRENT`, đúng thứ comment `:592-595` của chính detector cấm) và `HANDOFF:5` viết `(**S147**` nên regex `\(S` trượt ⇒ nhãn S147 sống trên thân S148/S149 mà máy im. **Không sửa detector (khác turf), nhưng "0 flag" ở trục này KHÔNG đọc thành sạch.** Bẫy tránh được: `grep -c "public const string"` MenuKeys ra **51**, đếm PHẦN-TỬ `All` mới ra **54** = khớp canonical (bài S143 lặp lại nguyên si). Tag `[s150, bookend-close-lan-dau, uy-quyen-land-sai-so, h24-3-anchor-reshape-blind, handoff-1-goc-5-la]` + diff --git a/.claude/agents/README.md b/.claude/agents/README.md index 52196a1..e77549d 100644 --- a/.claude/agents/README.md +++ b/.claude/agents/README.md @@ -216,6 +216,8 @@ | ring4-audit (monitor round-KIỂM, S145) | ref-only — ĐỌC output `/sleep-recovery-memory-l2` `.gist.md` + Fidelity verdict; tự đo byte gốc vs gist; no-self-exempt độc-lập lượt nén; KHÔNG dùng domain skill | | ctx-audit (vai-3 vòng Ctx, S153) | ref-only — SOI-CHUỖI `_mind` @2-bookend: bất-biến |block|∈{p,p+1} đếm-ĐĨA + mồi-ngầm + kiểm-vết vai-1/2 (hồi-tố = fallback); ĐỌC output `mind-check` KHÔNG re-implement; PIN fail-closed, `_mind` vắng ⇒ NO-OP-có-khai; KHÔNG soi lead-surface (turf H24), KHÔNG kiểm vòng-đo khác (turf ring); KHÔNG dùng domain skill | | ctx-curator (vai-1 vòng Ctx, S153 OWNER-VETO) | ref-only — KIỂM bản NHÁP block @mỗi-`/pause` (5 khoản ngữ-nghĩa, SAU `mind-check --draft`); trả CHỈ văn bản `DAT\|SUA\|SKIP-CO-KHAI` ≤12 dòng; carve-out duy nhất `pause.md §1`; KHÔNG lấn @tiep/2-đầu; KHÔNG dùng domain skill | +| score-counter (tầng-2 luật chấm điểm, W4b S181) | ref-only — đọc `docs/governance/so-yeu-cau-chu-du-an.md` TỰ ĐẾM mục nhắc ≥2 (đơn-vị MỤC không LẦN); CẤM xem điểm tầng-1 trước khi đếm xong; sổ thưa ⇒ `KHÔNG ĐO ĐƯỢC`; luật canonical `harness-11-engine PHẦN P` — trỏ; KHÔNG dùng domain skill *(+2 row @S185 — tooling F-1: matrix 26/28 hở từ S182)* | +| score-count-auditor (tầng-3 luật chấm điểm, W4b S181) | ref-only — kiểm PHÉP ĐẾM tầng-1+tầng-2 (4 lỗi điển hình); CẤM đề xuất điểm KHÁC; chấm-sai → `error-ledger.md` kèm tầng; enum `_sealed_P3B_S181` niêm phong — CẤM nhét nhãn mới; PIN fail-closed; KHÔNG dùng domain skill | | ctx-verifier (vai-2 vòng Ctx, S153 OWNER-VETO) | ref-only — ĐỐI-CHIẾU 4-khoản (B-vs-`next:` TIN-SỔ-MÁY) + BẢN NẠP-LẠI ≤15 dòng @mỗi-`/tiep`, kết `LEAD-PHAI-NHAC-LAI:`; KHÔNG nạp NỀN hộ lead (`tiep_reload` = việc lead); KHÔNG lấn @pause/2-đầu; KHÔNG dùng domain skill | ## 🔧 Tool grant (S39 — +3 RAG MCP per agent) diff --git a/.claude/agents/lead-stale-auditor.md b/.claude/agents/lead-stale-auditor.md index 13c7ca3..e62e693 100644 --- a/.claude/agents/lead-stale-auditor.md +++ b/.claude/agents/lead-stale-auditor.md @@ -30,7 +30,7 @@ Broadcast H24 §2(1) ra lệnh: *"KHÔNG gộp chúng vào một vai cũ — g | Máy làm được | Máy MÙ — việc của mày | |---|---| -| "doc ghi 60 menu nhưng canonical 54" | *"con số khớp nhưng CÂU nói sai nghĩa"* | +| "doc chép một số đã thối so canonical" | *"con số khớp nhưng CÂU nói sai nghĩa"* *(ví dụ neo-digit cũ gỡ @S185 — chính cặp số mẫu trong persona này từng thối 3 đời F-10; canonical menu-key đọc SỐNG ở `docs/STATUS.md` row Menu-keys, đừng chép)* | | "anchor 2026-04-30 < mốc 2026-07-15" | *"doc này ĐÓNG-BĂNG có chủ-đích hay thật sự stale?"* | | grep chuỗi | *"lead viết 'đã ký' mà owner-decisions ghi ⚪ CHỜ"* | @@ -44,7 +44,7 @@ Nếu mày chỉ lặp lại output detector = **mày vô dụng**. Giá-trị c | class | Dấu-hiệu gốc (broadcast §2(1)) | Ví-dụ SE | |---|---|---| -| `view-stale-count` | bản-tóm-tắt còn trỏ **số** cũ sau khi source đã đổi | `CLAUDE.md` ghi "~60 menu key" khi canonical `STATUS.md:19` = 54 | +| `view-stale-count` | bản-tóm-tắt còn trỏ **số** cũ sau khi source đã đổi | một doc chép số menu-key trong khi canonical là row Menu-keys của `docs/STATUS.md` — đọc SỐNG, **CẤM chép digit vào đây** *(dòng này từng tự phạm 3 đời: neo `:19`/giá-trị cũ, 0-hit từ S173 — stale-F10 @S185 vá cả 2 site theo ring2-①)* | | `view-stale-header` | **tiêu-đề / changelog** chưa bump sau dấu-mốc governance mới | `SKILL.md` anchor `**Status (post Session 6 — 2026-04-30):**` trong khi mốc = 2026-07-15 | | `view-stale-status` | **chú-thích-trạng-thái** ("đã ký"/"đang chờ") chưa lật sau khi quyết-định đã chốt | spec ghi `⚪ chờ` mà `owner-decisions §Q3` đã `✅ Đồng ý` | | `view-stale-role-desc` | **con-số trong mô-tả một VAI** lệch thực-tế | `agents/README` ghi 12 sub khi roster = 14 | diff --git a/.claude/commands/adap-apply.md b/.claude/commands/adap-apply.md index d6cfee1..e6e1e11 100644 --- a/.claude/commands/adap-apply.md +++ b/.claude/commands/adap-apply.md @@ -16,7 +16,8 @@ argument-hint: `powershell.exe -ExecutionPolicy Bypass -File scripts/tien-kiem-cua.ps1 -Cua adap-apply` → in **1 dòng** `TIEN-KIEM: cua=… cua-dong-gan-nhat=… moc-trong-tep=… phien=… | nguon n/2 | `. -- 🔴 **KHÔNG CHẶN.** Lỗi bất kỳ ⇒ in `tien-kiem loi (khong chan)` rồi **ĐI TIẾP**. Máy **luôn `exit 0`** — cổng chặn bằng mã lỗi là wave **W3b**, chưa chốt; ai sửa máy này trả mã ≠0 là đã đổi lớp. +- 🔴 **KHÔNG CHẶN.** Lỗi bất kỳ ⇒ in `tien-kiem loi (khong chan)` rồi **ĐI TIẾP**. Máy **luôn `exit 0`** — cổng chặn bằng mã lỗi là wave **W3b**; ai sửa máy này trả mã ≠0 là đã đổi lớp. + - 🔸 **Trạng thái W3b @S185 — ĐỪNG hỏi lại owner:** **P1 ĐÃ CHỐT = PA-2** (hai mã thoát trong MỘT máy; owner @S180, land @S181 — `.claude/sessions/session-12/_context-s-12.md:55` + phân-loại 64/64 tại `docs/governance/harness-11-engine.md` PHẦN Q). **Vẫn CHƯA cắm** vì điều-kiện-vào có **hai vế** và vế thứ hai chưa đạt (`harness-11-engine.md:587` — *"rider-jump W2 đã soak INFORM ≥1 phiên"*): đo @S185 rider-jump **chưa tồn tại trên đĩa** ⇒ soak thật = **0 phiên**. Tái-lập: `grep -c "OVERDUE:jump" scripts/nhip-no-probe.ps1` = **0** (control cùng tệp `grep -c "OVERDUE"` = **6**). - 🔸 Cửa đóng gần nhất chọn bằng **dấu thời gian ghi TRONG tệp**, **không** tin `mtime` của hệ điều hành (hook `wal:` chạm tệp mỗi lượt; `git checkout` viết lại `mtime` hàng loạt). - 🔸 Cờ `THIEU-TAP` nghĩa là **0/2 nguồn đọc được** ⇒ **KHÔNG được đọc thành "sạch"**. Cờ `NGUON-HONG` / `LECH-PHIEN` là **INFORM**, không phải lệnh dừng. - 🔸 Bước nào của cửa bị lệch thì gọi tên theo `docs/governance/ritual-labels.md` (4 nhãn + vòng hỏi ngược 5 cột), **đừng tự chế nhãn**. diff --git a/.claude/commands/fable-clone.md b/.claude/commands/fable-clone.md index f7954f1..3aef25c 100644 --- a/.claude/commands/fable-clone.md +++ b/.claude/commands/fable-clone.md @@ -72,6 +72,7 @@ Ví dụ đang chạy: `Gate reviewer anchor s144` (24 ký tự) · `Vòng-3 har - **Vừa panel** ~≤40 ký tự; xung đột thì **đủ-thành-phần thắng ngắn-gọn** (`:25`). - **Một khuôn duy nhất** toàn repo (`:26`). - **Áp từ phiên kế** (`:51`) — spawn trước đó **giữ nguyên làm vết, KHÔNG sửa lùi** (khuôn hub `:43`). +- 🔴 **Khoản-④ LABEL-VÀO-run.md (vá C-7 @S185 — đo 08-09: chỉ 3/14 run tháng-8 có):** run-folder scaffold **PHẢI** mang label từng spawn trên đĩa — hoặc cột `label` trong bảng pipeline của `run.md`, hoặc 1 dòng `label: ` cạnh mỗi `sub-*.md` được kê. Panel/audit đọc **run.md**, không đọc lời kể — label chỉ sống trong tham-số spawn = vô hình với hậu-kiểm (đúng lỗi acceptance khoản-④ TRƯỢT @07-25). Run cũ giữ nguyên làm vết, KHÔNG retro-fit. **Acceptance (siết theo R3 — thêm control + neo artifact):** - ✅ **Negative-control**: cắm 1 label thiếu {pha·phiên} → phép đọc-lại **PHẢI TRƯỢT**. Không trượt = thước mù. diff --git a/.claude/commands/session-end.md b/.claude/commands/session-end.md index 52864d4..a9e7e8c 100644 --- a/.claude/commands/session-end.md +++ b/.claude/commands/session-end.md @@ -7,6 +7,10 @@ description: Đóng session SOLUTION_ERP — flush memory TOÀN roster + H2 harv > Trigger cuối session. Em main chủ trì, gọi lại sub-agent đã spawn. > ⚠️ **Harness note (F2 re-verified S100):** SendMessage khả dụng lại, NHƯNG flush-flow GIỮ NGUYÊN — agent đã tự update MEMORY khi return (BẮT BUỘC trong agent frontmatter) → em main đọc MEMORY on-disk để synthesize, KHÔNG cần re-spawn/SendMessage chỉ để flush. +> 🔴 **ONE-SHOT BOOKEND (YC-018 anh chốt @S185 · nguồn thư hub — path tra được [gap-F5]: `D:\Dropbox\CONG_VIEC\AI_INFRA\broadcasts\outbox\all\2026-08-08-Governance-quy-trinh-hai-dau-phien-may-diem-danh-va-6-bai-hoc.md` Phần 1b — ca-âm hub nguyên văn: *"một lượt đóng phiên của hub từng chạy **thiếu gần nửa số vai**, với lý do 'cạn ngữ cảnh' — một nhãn không kiểm được. Chủ dự án ra lệnh: các vòng audit phải tự động"*):** +> **TOÀN BỘ nghi-thức đóng phiên — BƯỚC 0 sentinel → §L.b (a)→(l) đủ MỌI vòng @close → §6.4 xoá sentinel — chạy TRỌN TRONG MỘT LƯỢT.** 🔴 CẤM rải qua nhiều cửa · CẤM dùng `/pause`·`/tiep` làm nhịp chia-chặng bookend · CẤM hẹn-vòng-cửa-sau (ca-âm NHÀ MÌNH: bookend @close hẹn từ S182 trôi 4 cửa-sổ tới S185 — đúng bệnh luật này diệt) · CẤM dừng chờ consent (mọi vòng AUTO từ S152) · "cạn ngữ cảnh" KHÔNG phải lý-do bỏ vai — vai còn thiếu thì lượt-nối `/tiep` đầu tiên PHẢI chạy nốt, có `closing:` sentinel làm chứng. +> **Đứt BẤT-KHẢ-KHÁNG** (limit/crash) ⇒ `/tiep` thấy `closing:` treo (Sàn-2) ⇒ **CHẠY HẾT phần §L.b còn thiếu NGAY LƯỢT-NỐI ĐẦU TIÊN**, cấm rải tiếp. *(Đối-xứng: `session-start.md` khối ONE-SHOT BOOKSTART — 2 site sửa cùng lượt @S185.)* + ## 📋 BƯỚC 0 — Show command body (visibility, no wait) Em main PHẢI echo **TOÀN BỘ nội dung command body này** (đầy đủ Phase 1-6 + sub-section + guard rule) trong response đầu tiên ĐỂ ANH USER ĐỌC LẠI. @@ -160,7 +164,9 @@ Em main PHẢI echo **TOÀN BỘ nội dung command body này** (đầy đủ Ph ```bash powershell.exe -ExecutionPolicy Bypass -File scripts/naming-scan.ps1 powershell.exe -ExecutionPolicy Bypass -File scripts/artifact-integrity.ps1 + powershell.exe -ExecutionPolicy Bypass -File scripts/loi-hua-may-scan.ps1 ``` + *(máy thứ 3 cắm @S185 — tooling F-2: `loi-hua-may-scan.ps1` dựng @lane7 YC-017 [self-test 11/11, mẫu-số 30] mà 0 cửa gọi = tái phát ĐÚNG lớp mồ-côi mục này sinh ra để diệt, ngay phiên kế sau khi mục land)* - 🔴 **KHÔNG CHẶN** — cả 2 máy `exit 0` by-design (cổng chặn = W3b, chưa cắm). Lỗi bất kỳ ⇒ in `quet-chuan loi (khong chan)` → đi tiếp. - 🔴 **Vì sao bước này tồn tại:** đo @S181 khi dựng bảng A16 — cả 2 máy có **0 cửa nghi-thức gọi**. Chúng được dựng ở W1/W2, chạy tốt, nhưng **chỉ sống khi có người gõ tay** ⇒ hết phiên là hết chạy. Đó là lớp *guard không có đường ghi = chết câm*: máy đúng, mà không ai bấm nút. - 🔸 Đọc gì: `naming-scan` → 7 dòng `mau so` + có `lech ky vong` không · `artifact-integrity` → dòng `luot DAT` + đếm **`VANG-DAT`** (mức CAO NHẤT, ve-6 P7). diff --git a/.claude/commands/session-start.md b/.claude/commands/session-start.md index 8a10874..7962569 100644 --- a/.claude/commands/session-start.md +++ b/.claude/commands/session-start.md @@ -7,6 +7,10 @@ description: Bootstrap session SOLUTION_ERP — load context, audit state (roste > Trigger đầu session. Em main chủ trì, spawn sub-agent khi task match delegate criteria. > ⚠️ **Harness note (F2 re-verified S100):** SendMessage **KHẢ DỤNG lại** (deferred tool — load qua ToolSearch; resume agent đã spawn TRONG-session, context giữ). Cross-session vẫn = **fresh spawn** (MEMORY on-disk auto-inject giữ context). agentId chỉ valid trong-session. +> 🔴 **ONE-SHOT BOOKSTART (YC-018 anh chốt @S185 · nguồn thư hub — path tra được [gap-F5]: `D:\Dropbox\CONG_VIEC\AI_INFRA\broadcasts\outbox\all\2026-08-08-Governance-quy-trinh-hai-dau-phien-may-diem-danh-va-6-bai-hoc.md` Phần 1b: *"lượt mở phiên gần nhất của hub chạy **trọn trong một lượt duy nhất**, không cần cửa tạm dừng nào chen giữa. Cái đắt là kỷ luật, không phải thời gian"*):** +> **TOÀN BỘ nghi-thức mở phiên — BƯỚC 0 → Phase 3.5 + đủ MỌI vòng @open — chạy TRỌN TRONG MỘT LƯỢT.** 🔴 CẤM rải nghi-thức qua nhiều cửa · CẤM dùng `/pause`·`/tiep` làm nhịp chia-chặng bookstart · CẤM hẹn-vòng-nào-cửa-sau · CẤM dừng giữa chừng chờ consent (mọi vòng đã AUTO từ S152 — dừng để hỏi cái đã AUTO = tự chế cổng, đúng lớp nhãn `tự ý bỏ` của `ritual-labels.md`). +> **Đứt BẤT-KHẢ-KHÁNG** (session-limit/crash — thứ không cấm được) ⇒ `/tiep` nối và **CHẠY HẾT phần nghi-thức còn thiếu NGAY LƯỢT-NỐI ĐẦU TIÊN**, cấm rải tiếp. `/pause`·`/tiep` vẫn nguyên vai trò H22 (recovery + dừng-chủ-động GIỮA các khối VIỆC) — thứ bị cấm là lấy chúng làm nhịp chặng NGHI-THỨC. *(Đối-xứng: `session-end.md` khối ONE-SHOT BOOKEND — 2 site sửa cùng lượt @S185.)* + ## 📋 BƯỚC 0 — Show command body (visibility, no wait) Em main PHẢI echo **TOÀN BỘ nội dung command body này** (đầy đủ Phase 1-3 + sub-section + guard rule) trong response đầu tiên ĐỂ ANH USER ĐỌC LẠI. diff --git a/.claude/governance/.session-counter.json b/.claude/governance/.session-counter.json index 7342373..8a61a8a 100644 --- a/.claude/governance/.session-counter.json +++ b/.claude/governance/.session-counter.json @@ -1,4 +1,4 @@ -{ +{ "_note": "Harness-24 (S121, 2026-07-15, wave adap-6-broadcast W2) session counter for lead-self-audit cadence. THIS FILE HOLDS STATE ONLY - every cadence NUMBER lives in .claude/agent-memory/memory-budget.json -\u003e h24_cadence (single-source, H24 section 2(3)). Never copy the digits here.", "_why_content_based_not_blind_increment": "Owner-decisions-15-07-2026 Q2, trap found by lane E: the Stop-hook .claude/hooks/wal-flush.ps1 auto-commits on EVERY turn-boundary. A blind counter++ would therefore tick many times per real session and the cadence would be meaningless. So a tick is CONTENT-ADDRESSED: it is keyed on the repo HEAD sha at tick time. Ticking twice on the same HEAD is a NO-OP, which is what makes running /session-start twice in a row safe (acceptance: 2x /session-start on the same HEAD =\u003e +1, not +2).", "_why_this_path": "Deliberately .claude/governance/ and NOT .claude/agent-memory/. The hook covers exactly four paths (.claude/WAL.md, agent-memory/, workflows/runs/, sessions/ - the 4th added S146 together with the session-model logic-session folder); .claude/governance/ is OUTSIDE all four, so this file is never swept into a \u0027wal:\u0027 commit as a side effect. Compare .claude/agent-memory/.mfe-state.json, which IS inside the hook\u0027s reach - a counter must not live there. RE-VERIFIED at S146 when the 4th path landed: the claim is about the DIRECTORY, and .claude/sessions/ != .claude/governance/, so widening the hook did NOT invalidate it - only the count changed. Any future widening of wal-flush.ps1 MUST re-check this sentence, not just bump the number.", @@ -16,42 +16,41 @@ "last_ticked_head": "8491923eff64df8cbef569711ece1e88d6a77d25", "last_ticked_at": "2026-08-08", "last_audit": { - "light_at_counter": 56, - "deep_at_counter": 40, + "light_at_counter": 59, + "deep_at_counter": 59, "_note": "Counter value at which the last light/deep self-audit actually ran. S140 (2026-07-18): light-audit #3 at counter=14 = FORCE-FIRE DEBT PAID (closeout S139 gop P=3 pause =\u003e OVERDUE(light) INFORM; owner direction S140 \u0027dong du 5 vong\u0027 = consent DP-3 =\u003e lead spawn ca CAP H24 dau phien). 2-vai coverage 0-garble, diary ghi TRONG luc lam (anti-#53). lead-view: 1 FLAG LOW view-stale-status (HANDOFF:8 NEXT-em con treo \u0027624c378d verified-pending-\u003eexecuted\u0027 nhu to-do trong khi da executed-runtime @S140 sang) - xu @closeout re-stamp + 2 INFORM clean (model-flip S140 Fable = owner-choice KHONG can re-stamp canonical per anti-churn S106; 3 surface frozen dung). lead-omission: 1 FLAG MED gap-owner-specifics (direction session-model S140 VANG tracker - da xu TRONG PHIEN: draft session-model-se-draft.md + email hub + closeout them carry) + INFORM gap-carry-aged non-vacuous LAN DAU (hook-vs-budget-cap streak 9\u003e=M6, owner-held) + INFORM route-H1 (cum 7-carry S117/S118 VO HINH voi carry-age detector - chi age carry re-tag trong NEXT segment; aging-measurement bo sot) + META diary lead-omission thieu entry S137 (GAP-3 tai) -\u003e backfill @closeout. Prior: light #2 at counter=11 (S137, OVERDUE 8/6 paid). S143 (2026-07-22): DEEP-audit RAN at counter=17 - FORCE-FIRE SOM 1 NHIP theo direction owner (nguong tu-nhien la 18 = 3+15), KHONG phai toi-han tu-nhien. Deep bao ham light =\u003e set CA HAI light_at=deep_at=17 (tranh no ao phien sau). Chi tiet FLAG/class_repeat: xem history[] entry S143. Moc ke tiep tinh tu 17: light ~ counter 23; deep ~ counter 32.", - "signal_session": "S182", + "signal_session": "S185", "signal_decided": [ - "view-stale-count", "view-stale-status", - "view-residual-asym", "view-stale-header", - "view-stale-role-desc", + "view-stale-count", + "view-residual-asym", "gap-carry-dropped", - "gap-carry-aged", "gap-decision-sunk", - "gap-owner-specifics" + "gap-owner-specifics", + "gap-underfill" ], - "signal_reset_done": false, + "signal_reset_done": true, "signal_last_kind": "light", "signal_coca": [ - + "gap-carry-aged" ] }, "class_repeat": { "_note": "Rolling tally per flag class from lead_self_audit.flag_classes (memory-budget.json). Key = class name, value = consecutive-audit repeat count. S124 first audit = SEED (fired-once), not repeats yet (per lead-view-auditor honest-note). jump_on_class_repeat=3.", "counts": { "view-claim-broader-than-sample": 0, - "view-residual-asym": 11, - "view-stale-count": 11, - "gap-carry-dropped": 13, - "gap-decision-sunk": 7, - "view-stale-status": 8, - "gap-owner-specifics": 6, + "view-residual-asym": 12, + "view-stale-count": 12, + "gap-carry-dropped": 14, + "gap-decision-sunk": 8, + "view-stale-status": 9, + "gap-owner-specifics": 7, "gap-carry-aged": 1, "gap-incident-unrecorded": 0, - "view-stale-header": 6, - "view-stale-role-desc": 2, - "gap-underfill": 0 + "view-stale-header": 7, + "view-stale-role-desc": 0, + "gap-underfill": 1 }, "_view_star_repair_S149": "VA NUA view-* BI BO @S148 - phat hien boi h24-audit (vai KIEM) @S149, evidence runs/2026-07-24-S148-h24-force-fire/sub-h24-audit-S149.md muc 3 + 9c. GOC: lead-view-auditor KHONG GAN CLASS cho FLAG nao @S148 (no VAN gan @S140 va @S143, va @S146 dung header chuan \u0027## FLAG-N - `class` - SEV\u0027) =\u003e lead single-writer khong co so de chep =\u003e nua view-* dung yen trong khi nua gap-* duoc ghi du. Doi chung bat-doi-xung: cung closeout do, 3 dong gap-* ghi day du - khac biet DUY NHAT la lead-omission CO dua bang tally co nguon. SO DA VA (co nguon, chac chan): view-stale-count 0-\u003e1 (S148 fire V1 canonical-poison test-count; S146 khong fire) - view-stale-status 0-\u003e2 (S146 fire per sub-lead-view-S146.md:11, S148 fire V3 trio-first-run stale =\u003e 2 vong LIEN TIEP, vong sau fire nua la CHAM JUMP). 🔴 view-residual-asym GIU NGUYEN 1 - KHONG PHAI vi dung, ma vi KHONG XAC DINH DUOC: gia tri that thuoc {0, 3}. Ly do: S143=1 -\u003e S146 fire x2 (sub-lead-view-S146.md:27,:43) =\u003e =2 -\u003e S148 KHONG BIET vi FLAG-4/FLAG-5 cua lead-view @S148 KHONG TON TAI TREN DIA (run-folder chi co run.md, 0 file sub-*; doi chung S146 co 3 file). Neu 1 trong 2 FLAG mat tich la view-residual-asym thi =3 =\u003e CHAM JUMP =\u003e tong 4 class armed chu khong phai 3. CAM ghi 0 (= khang dinh \u0027S148 khong fire class nay\u0027 = DAT-ao, dung lop H24 sinh ra de chan) va CAM ghi 3 (= doan len).", "_jump_state_S149": "3 class CHAC CHAN cham/vuot jump_on_class_repeat=3: gap-owner-specifics 4 - gap-decision-sunk 3 - gap-carry-dropped 3. + view-stale-status 2 = armed 2/3 (vong sau fire nua la cham). + view-residual-asym KHONG XAC DINH {0,3}. =\u003e CAU TRA LOI DUNG CHO OWNER LA DAI 3-4, KHONG PHAI SO 3 TRAN. Lead da trinh so 3 tran @S149 truoc khi co ket qua vai KIEM - DA DINH CHINH trong cung phien.", @@ -289,19 +288,19 @@ "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 55-\u003e56, session S181-\u003eS182, head b8d2274-\u003e936d1ae. Classify-before-tick: no regression (n=182 \u003e= stored n=181); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." }, { - "at": "2026-08-08", - "session": "S183", - "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 56->57, session S182->S183, head 936d1ae->9e8d67d. Classify-before-tick: no regression (n=183 >= stored n=182); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." + "at": "2026-08-08", + "session": "S183", + "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 56-\u003e57, session S182-\u003eS183, head 936d1ae-\u003e9e8d67d. Classify-before-tick: no regression (n=183 \u003e= stored n=182); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." }, { - "at": "2026-08-08", - "session": "S184", - "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 57->58, session S183->S184, head 9e8d67d->5469ec8. Classify-before-tick: no regression (n=184 >= stored n=183); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." + "at": "2026-08-08", + "session": "S184", + "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 57-\u003e58, session S183-\u003eS184, head 9e8d67d-\u003e5469ec8. Classify-before-tick: no regression (n=184 \u003e= stored n=183); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." }, { - "at": "2026-08-08", - "session": "S185", - "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 58->59, session S184->S185, head 5469ec8->8491923. Classify-before-tick: no regression (n=185 >= stored n=184); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." + "at": "2026-08-08", + "session": "S185", + "event": "CLEAN tick (session-counter-tick.ps1 M2): counter 58-\u003e59, session S184-\u003eS185, head 5469ec8-\u003e8491923. Classify-before-tick: no regression (n=185 \u003e= stored n=184); last_ticked_head reachable (merge-base --is-ancestor exit 0). 4 fields updated, 1 history entry appended, written atomically (temp + Move-Item -Force)." } ] } diff --git a/.claude/sessions/session-13/_mind-s-13.md b/.claude/sessions/session-13/_mind-s-13.md index a6e933d..56ac839 100644 --- a/.claude/sessions/session-13/_mind-s-13.md +++ b/.claude/sessions/session-13/_mind-s-13.md @@ -66,6 +66,46 @@ Máy chỉ quét phần **DƯỚI** marker đóng khối luật (dòng comment c (`_MIND_TOP_MARKER` trong scripts/session_ctx.py) -- khac khuon `FLOW-START` cua _context (khong may nao doc). --> +## MIND-3 — 2026-08-10T02:45:00+07:00 @ 6282806c (window 3+4, refresh @bookend-close S185 — nhịp BỔ SUNG theo phán ctx-audit F-1/F-2: 2 window làm việc dày chưa từng có block; ghi TRƯỚC _end/commit) + +### A. Gói-turn + +- Window-3 (S184 /tiep): reconcile + sửa lệch `wf:` orphan S182 — chi tiết duy nhất trước đây chỉ ở WAL, nay chép nhà bền: (i) claim cũ "mọi run đã đóng" SAI, đĩa 10 sub/0 synthesis; (ii) 7 ô run.md là Ô BẢNG markdown — tick kiểu `- [ ]` sẽ TRƯỢT CÂM; (iii) V-5 DI-TRÚ vào WAL @S184. +- Window-4 (S185 /tiep + `--resume`): verify 3/3 y hệt → adap thư 08-08 TRỌN (3 phép thử đo thật + `(f-bis)` land + REVIEW PASS_WITH_FIXES) → orphan S182 ĐÓNG 2-thước → 3 site tự-quy-chiếu vá → YC-017 pipeline P1-P4 trọn (fable-invest 0/39-NỢ · fable-review 13-finding · checklist 22C+4W · wf 7-lane Opus MAX 21/21-disposition) → YC-018 ONE-SHOT cấu hình 4 site → bookend @close MỘT MẠCH 9 vai (kết quả §E). + +### B. Hướng-tiếp + nhánh-đã-loại + +**Hướng:** vá bề-mặt theo FLAG-tổng (STATUS 668 + CURRENT-advance · HANDOFF segment/deep/carry-12-khôi-phục · sổ YC-011/016/017 lật + con-trỏ-bền · persona lead-stale 2-site · A1/A2/A3 refine · tooling F-1..F-4 · probe-comment 5-vế) → commit gom → trình anh khối chờ-quyết (4W + 5 SKIP-owner + C-6-nén + JUMP-7-class + mắt-anh 8-panel) → acceptance-động-local → closeout khi anh gọi. +**Nhánh đã LOẠI:** (a) sửa `signal_last_kind` "light"→"deep" tay — LOẠI: state-file của máy, lỗi ở TRÌNH TỰ GỌI của lead (light-stamp SAU deep), lần sau gọi light TRƯỚC; (b) gỡ carry theo gap §7(1) — LOẠI: ring2 BROKE-2 chứng dương-giả, carry còn vế mở; (c) pull-copy thư 08-08 vào inbox — LOẠI: kênh `all` đọc-tại-chỗ by-design, giải bằng ghi path tuyệt-đối vào 2 site ONE-SHOT + sổ. + +### C. Kế-hoạch (delta suy-nghĩ) + +Delta lớn nhất: **ONE-SHOT bookend chạy được thật** — 9 vai + máy trong một mạch, KHÔNG cửa pause/tiep chen (limit-reset bất-khả-kháng được nối bằng resume, không tính là cửa). Giá phải trả lộ ra đúng như thư 08-08 nói: "cái đắt là kỷ luật" — cụ thể là kỷ luật RESUME (9/9 vai #53-garble ít nhất 1 lần, artifact-first + resume cứu 100%, 0 byte mất). Hệ quả thiết kế: #53 giờ là NHỊP VẬN HÀNH mặc định chứ không phải sự cố — mọi spawn dài PHẢI artifact-first từ tool-call #1. +Delta thứ hai: chuỗi kiểm 3 tầng (đo→đề-xuất→kiểm + ring) lần đầu BẺ ĐƯỢC CẢ 3 NẤC trong cùng một vòng (eval sót mốc S154 · refine số 8.679→8.638 · và audit/ring tự-BROKE vào thước mình 2 lần/con) mà KHÔNG kết luận nào lật — sai số nhỏ, cùng chiều an-toàn, truy được cơ chế. Đây là trạng thái lưới khoẻ: bắt lỗi thật, không bắt lỗi ma. + +### D. Đang-thảo-luận + +- `{đang-cãi}` VK-5 — GIỮ nhãn (ctx-audit BÁC áp-máy-móc "tin sổ máy": `{đang-cãi}` đúng hơn ngăn thô của WAL; 3 bề mặt còn lệch, fail-safe giữ nguyên). +- `{treo-chờ-anh}` (72) mfe-eval closeout thường trực — chưa phán; nay CỦNG CỐ bởi E1 (impl-fe đứng yên 12 phiên vì `-Detail` 0 call-site). +- `{treo-chờ-anh}` ring5-audit slot (41) — thư 08-08 vòng-6 nhắc lại, vẫn chờ anh. +- `{treo-chờ-anh}` W-1 day-wake 3-chạm · W-3 owner-SỐ 4.3 (vớt lại sau 15 ngày rơi) · W-4 bảng thẩm-quyền (nhà đã locate) · 5 SKIP-owner lane1 · C-6 quyết-nén ring2 (căn cứ mới: value_protect 0/10 phủ hợp-đồng-vai — luật máy MÙ, chỉ owner phán) · JUMP 7-class ≥3. +- `{gần-chốt}` deep-sweep — **ĐÃ TRẢ @S185** (19/15 → deep_at=59, tally ghi máy) — hết là món thảo-luận, dòng này lật để đóng vòng đời nhãn. +- `{gần-chốt}` D5/D6 — WAL đã định-đoạt "chỉ chờ veto, KHÔNG chặn"; giữ 1 dòng chờ veto anh. +- `{gần-chốt}` V-5 vị-từ mã-hoá — **nhà thật = WAL + lượt này ĐÃ CẮM MÁY** (detector C15 rank-1/rank-2 land @S185 lane1) ⇒ vế "chưa cắm" ĐÃ ĐÓNG bằng vật; còn vế đổ-về-HANDOFF làm carry bền (ctx-audit ràng buộc (c)) — xử ở lượt vá HANDOFF ngay sau block này. +- `{gần-chốt}` ring1-persona `:25` "CẤM tự chạy ở open" — ctx-audit F-3: mồi TRƯỢT, hệ hỏng 3 tầng, ca vi phạm ngay trong L13; việc-của-em = sửa persona cho khớp vận hành thật (chạy @close đúng chữ; @open theo lệnh lead = hợp lệ hoá bằng chữ) — vá ở lượt persona kế, có nhà durable tại dòng này. +- `{mới-nêu}` nhánh upload căn-cứ dossier 0-guard-phase — giữ từ MIND-2, cửa sau cân nhắc hỏi anh. +- `{mới-nêu}` F-8 ctx-audit: `_end` phải ghi SAU `_mind` (tiền lệ session-12 off-by-one 82 giây) — nghi-thức closeout cần 1 dòng thứ-tự. +- `{mới-nêu}` F-1/F-4/F-5 ctx-audit: bước ghi-block @bookend chưa có trong CHỮ session-end (`mind-refresh` fail-LOUD chưa land) · `LEAD-PHAI-NHAC-LAI` 0-hit toàn cây sessions (phép chống nạp-suông đang suông) · trần đối-chứng vai-1/2 36,7% — 3 món thiết-kế trình anh cùng đợt governance kế. + +*(Đính chính ghi nhận: `_mind:108` (MIND-2 §E) chở bằng-chứng `find -newermt` chạy trên path không tồn tại — thước hỏng, kết luận 0-fan-out window-2 vẫn đúng qua phép mtime khác; block cũ bất biến nên đính chính tại đây.)* + +### E. Dòng-sống spawn/engine-run + +- Run YC-017 tại `.claude/workflows/runs/2026-08-09-S185-email-adap-pipeline/`: 2× fable (invest #53-resume → 0/39-NỢ, `sub-invest-email-adap-fable.md` · review 13-finding, `sub-review-checklist-fable.md`) + wf `wf_5d16a842-28e` 7 lane Opus MAX (16D+3P+1S; lane2 DỪNG-đúng-lệnh soak-vế-2, `sub-opus-lane{1..7}*.md`) — `implement-synthesis.md` land, run đóng dạng-1. +- Run bookend tại `.claude/workflows/runs/2026-08-09-S185-bookend-close/`: harvest-curator (698.109B → lead APPEND 17 khối/11 sổ + 7 tệp + 7 lane-placed, `sub-harvest-curator.md`) · máy ×5 (`script-arm-output.md`, f-bis lần đầu) · trio eval-MIXED-36-trục → refine-3-action-15-BÁC → audit-40Đ/4T-183-số (`harness-{eval,refine,audit}-return.md` + `sub-harness-audit.md`) · cặp H24 deep (stale 10-FLAG-SÀN `sub-lead-stale-deep.md` · gap 6-FLAG `sub-lead-gap-deep.md`) + tally máy deep+light@59 · ring2 16Đ/0T (`sub-ring2-audit.md`, 2 BROKE đắt) · tooling PASS_WITH_FLAGS-6 (`sub-tooling-auditor.md`; +tự-compact diary 31.696→14.852, ring1 verify 0-mất-chữ) · ring1 30Đ/3T (`sub-ring1-audit.md`, 17/17-verbatim · 7-tệp-MD5) · ctx-audit TRUOT-8-FLAG (`sub-ctx-audit-close.md` — đang chạy lúc block này soạn; tiền-lệ vá-S173 "§E có dòng cho vai ĐANG chạy"). +- 🔴 Chuỗi #53: 9/9 vai bookend + 2/2 fable + 1 H2 đều garble/đứt ≥1 lần — recover 10/10 bằng {disk-truth → resume → scribe}, mất 0 byte. Limit-reset 12:50am cắt 3 vai giữa chừng — nối bằng `--resume` của anh, chuỗi không đứt. + + ## MIND-2 — 2026-08-08T13:18:00+07:00 @ 06d873cc (window 2, refresh @/pause-2; sha = HEAD wal-flush lúc ghi, ship = 72568f05) ### A. Gói-turn diff --git a/.claude/workflows/runs/2026-08-09-S185-bookend-close/bookend-close-synthesis.md b/.claude/workflows/runs/2026-08-09-S185-bookend-close/bookend-close-synthesis.md new file mode 100644 index 0000000..5a6648d --- /dev/null +++ b/.claude/workflows/runs/2026-08-09-S185-bookend-close/bookend-close-synthesis.md @@ -0,0 +1,33 @@ +# bookend-close-synthesis — S185/L13 (ONE-SHOT lượt đầu, YC-018) + +> **VERIFIED bởi lead** @2026-08-10 ~03:15. Chuỗi 9 vai + 5 máy chạy MỘT MẠCH (limit-reset cắt 3 vai giữa chừng — nối `--resume`, không tính cửa). Mọi vai ≥1 lần #53 — recover 10/10 {disk-truth→resume→scribe}, 0 byte mất. + +## Kết quả chuỗi (chi tiết từng vai = bảng run.md + sub-file cùng folder) + +| Vòng | Kết quả | +|---|---| +| Harvest (H2 + lead APPEND) | 698.109 B nguồn → **17 khối/11 sổ + 7 tệp MD5-trùng + 7 lane placed** (ring1 verify 17/17 verbatim) | +| Máy ×5 (f-bis LẦN ĐẦU) | số SAU-append: 5 vai over-cap (trước-append chỉ thấy 1) — (f-bis) chứng giá trị ngay lần đầu chạy | +| V3 trio | eval MIXED 36-trục/11-signal (provenance 4/4 byte-exact) → refine 3-action/15-BÁC/5-ESC (tự-bác A1-phá: **span≠nhãn**) → audit 40Đ/4T, 183-số/180-exact, bẻ cả eval (sót mốc S154) lẫn refine (8.679→8.638 cơ-chế CRLF-est) — không kết luận nào lật | +| V2 H24 DEEP (trả nợ 19/15) | stale 10-FLAG-SÀN (canonical-poison 645-vs-668 nặng nhất) + gap 6-FLAG (12/23 carry vắng) → tally máy deep+light @counter-59 → ring2 16Đ/0T (BROKE-tự-quật + BROKE-mớm; tự đo 668/0) | +| V1 H1+ring1 | tooling PASS_WITH_FLAGS-6 (máy-mồ-côi-thứ-3) → ring1 30Đ/3T (3 TRƯỢT cùng hình "bảng tổng đếm hụt liệt-kê của mình") | +| V4 | NO-OP đúng luật (sleep không chạy — pin missing) | +| Ctx vai-3 | TRUOT 8-FLAG (3H: nhịp-refresh-`_mind` thiết-kế-hỏng · §E-0/19 · mồi-ring1-persona-TRƯỢT-hệ-hỏng-3-tầng) + phán MIND-3-bắt-buộc + 2 BÁC-đề-bài có đo | + +## Thi hành SAU verdict (Mirror C1 mở khoá — tất cả trong cùng lượt) + +1. **MIND-3** ghi (draft→máy `--draft` 6Đ→sửa phép-4→chèn→full-check **11/11 ĐẠT**; trước `_end`, §E có ctx-audit, 3 datum S184 vào nhà bền, 4 nhãn §D lật). +2. **Vá bề-mặt:** STATUS (mốc-sống S185/L13 + Tests 645→**668** hết canonical-poison) · HANDOFF (segment S185 + NEXT-em cập-nhật + carry 20→25 + **12 slug khôi phục ADDITIVE** + V-5 ghi đóng + trỏ report 08-08) · sổ YC (YC-011/YC-017 đóng + YC-016 chú-thích đối-xứng + 2 con-trỏ chết đổi mốc bền) · persona lead-stale **cả 2 site** `:33`+`:47` (ring2-①). +3. **A1/A2/A3 refine thi hành:** A1 impl-be 25.515→25.280 (move 430B; caveat "chưa giải hết" giữ nguyên) · A2 lead-stale 30.852→**22.997 dưới cap** (distill Runs 8.462B→tóm 606B + verbatim archive mới) · A3 promote luật span≠nhãn. +4. **Vá nhỏ:** probe comment 4→5 vế (audit §8) · agents/README matrix +2 row (F-1) · **(k-ter) cắm `loi-hua-may-scan.ps1` làm máy thứ 3** (F-2 HIGH — chạy qua cửa lần đầu, tự khai "đo GATE không đo SWEEP") · addendum-2 goi-chot 4.4 (F-3) · ONE-SHOT 2 site + path nguồn tra được (gap-F5). +5. **Probe SAU-vá:** `light 0/6 deep 0/15 ok | over-cap 3 | so-yc treo 2` — nợ deep XOÁ, over-cap 5→3. + +## Tồn sau bookend (không cái nào máy-tự-quyết) + +- **3 over-cap còn:** ring2 31.781 (chờ quyết C-6 — căn cứ audit: `value_protect` 0/10 phủ hợp-đồng-vai = luật máy MÙ, **owner phán**) · reviewer 31.341 (vừa harvest, để lắng) · tooling ~30.981 (E4: bệnh TỐC-ĐỘ +11.926/23 phiên, archive-mù = chữa nhầm trục). +- **E1** `-Detail` mfe-eval 0 call-site (impl-fe kẹt 12/13 suốt 12 phiên — mục MISS vô danh) · **E2** baseline `measured` = phép CHÉP chưa ai chép (16/17 rữa) · **F-1/F-4/F-5 ctx** (nhịp-refresh-`_mind` vào CHỮ + `LEAD-PHAI-NHAC-LAI` 0-hit + trần đối-chứng 36,7%) — gói governance kế. +- **Khối CHỜ-ANH** → báo cáo lượt này. + +## Ghi chú vận hành ONE-SHOT (lần đầu áp YC-018) + +Đắt đúng như thư nói — "kỷ luật, không phải thời gian": 100% vai #53-garble ≥1 lần, giá của one-shot = kỷ-luật-RESUME (artifact-first từ tool-call #1 + resume theo khuôn + scribe ngay). `signal_last_kind` cuối = "light" (em gọi light-stamp SAU deep — lần sau gọi light TRƯỚC deep để field cuối phản ánh đúng kind chính). diff --git a/.claude/workflows/runs/2026-08-09-S185-bookend-close/run.md b/.claude/workflows/runs/2026-08-09-S185-bookend-close/run.md index 1307b82..ac21461 100644 --- a/.claude/workflows/runs/2026-08-09-S185-bookend-close/run.md +++ b/.claude/workflows/runs/2026-08-09-S185-bookend-close/run.md @@ -17,7 +17,7 @@ | V2 ring2 AUTO sau cặp | ring2-audit | `Vòng-2 ring2 close s185` | [x] 16Đ/0T · falsify 4H/2B (BROKE-tự-quật + BROKE-mớm) · tự-đo 668/0 · 3 chỉ-dẫn vá | | V1 H1 tooling-chốt @close | tooling-auditor | `Vòng-1 tooling-auditor close s185` | [x] PASS_WITH_FLAGS-6 (F-2 HIGH máy-mồ-côi-thứ-3) · diary tự-compact 31.696→14.852 | | V1 ring1 KIỂM (SAU H1+H2) | ring1-audit | `Vòng-1 ring1 close s185` | [x] 30Đ/3T · 17/17-hạ-cánh-verbatim · 7-tệp-MD5 · compact-0-mất-chữ · 2-BROKE-vào-thước-mình | -| Ctx vai-3 @close | ctx-audit | `Core ctx-audit close s185` | [ ] | +| Ctx vai-3 @close | ctx-audit | `Core ctx-audit close s185` | [x] TRUOT-8-FLAG (3H) · MIND-3-bắt-buộc→ĐÃ GHI (mind-check 11/11) · 2 BÁC-đề-bài | | V4 ring4 | — | — | NO-OP đúng luật (sleep không chạy phiên này — pin missing) | ## Artifact chờ diff --git a/.claude/workflows/runs/2026-08-09-S185-bookend-close/sub-ctx-audit-close.md b/.claude/workflows/runs/2026-08-09-S185-bookend-close/sub-ctx-audit-close.md new file mode 100644 index 0000000..cdc2108 --- /dev/null +++ b/.claude/workflows/runs/2026-08-09-S185-bookend-close/sub-ctx-audit-close.md @@ -0,0 +1,285 @@ +# sub-ctx-audit-close — S185/L13 · vai-3 vòng Ctx · bookend @close + +`CTX-AUDIT: TRUOT — 8 FLAG` (3 HIGH · 1 MED-HIGH · 4 MED) · 7 ĐẠT · 2 BÁC-đề-bài · 1 phán-quyết thiết-kế + +- ts vai chạy: 2026-08-10 (window-4, S185) · lượt: **@close** · mode máy: `open` (chưa có `_end`) +- PIN nhận đủ 3/3 → **KHÔNG** SKIP: `_mind-s-13.md` (25.619 B) · `_context-s-13.md` (8.767 B) · run-folder `2026-08-09-S185-bookend-close/` +- Ca chạy = **KIỂM-CỦA-KIỂM** (phiên CÓ pause ×2 + tiep ×3 ⇒ vai-1 và vai-2 ĐÃ chạy) — KHÔNG phải fallback hồi-tố như S173/S182. + +--- + +## (0) MÁY TRƯỚC VAI — đọc nguyên văn, KHÔNG re-implement + +`python scripts/session_ctx.py mind-check --session 13` → **`dat=10 TRUOT=0 co=1 bo-qua-co-khai=0 => exit 0`** + +Mức `co` DUY NHẤT = phép **(10) thứ-tự bookend vs `_mind`**: +- `_mind` mtime = `2026-08-08T13:30:24` +- artifact bookend mới nhất = `2026-08-10T02:11:27` +- **lệch 132.062 giây = 2.201 phút = 36,7 giờ** +- máy tự in câu vá: *"chèn 1 block refresh SAU khi vòng cuối báo xong (trần (6) đã nói chỗ cho ca này)"* + +🔴 **Máy KHÔNG hở lượt này** — 8 FLAG dưới đều **ngoài tầm máy** (ngữ-nghĩa · liên-phiên · liên-tệp-lệnh). Máy xanh 10/10 mà lớp mềm đứng im 36,7 giờ qua 2 cửa-sổ ⇒ đúng ca **CLEAN nguy nhất** persona bắt tao thách. + +--- + +## (1) BẤT-BIẾN CHUỖI — tự đếm ĐĨA (số duy nhất tao được phép tự tái-dựng) + +🔴 **Tự bắt bẫy thước của chính mình:** lệnh đầu tao gõ `grep -c "^## MIND-"` ra **4** (s13) và **3** (s12) — **SAI**, vì nó ăn cả dòng schema-placeholder `## MIND-` nằm trong khối comment hướng-dẫn. Parser thật (khai ở `_mind:40`) là `^## MIND-\d+`. Đo lại bằng `grep -cE "^## MIND-[0-9]"`: + +| đại-lượng | tao đếm ĐĨA | máy in | khớp | +|---|---|---|---| +| `\|block\|` | **3** (MIND-0/1/2) | 3 | ✅ | +| `p` (`_pause-*.md`=2 + `pause-*.md`=0 dual-accept) | **2** | 2 | ✅ | +| kỳ vọng `[p, p+3]` = `[2,5]` | 3 ∈ [2,5] | dat | ✅ | +| `_end` tồn tại | **KHÔNG** | mode=open | ✅ | + +**Đ-1 ĐẠT — bất-biến chuỗi khớp máy tuyệt đối, 0 lệch, không cần in-2-số.** + +**Cân sổ marker (đĩa):** `_pause`=2 · `_tiep`=3 · `_snapshot`=2 · `_end`=0. +- snapshot **2 ↔ 2** pause: cân đúng luật auto-snap@pause. ✅ +- 🔴 **tiep 3 > pause 2** — dựng lại chuỗi bằng trường `window-ordinal` trong từng marker: + `_pause-1`(w1) → `_tiep-1`(w2) → `_pause-2`(w2) → `_tiep-2`(w3) → `_tiep-3`(w4) + ⇒ **window-3 ĐÓNG mà KHÔNG qua `/pause`**, và **window-4 (đang chạy) cũng chưa qua `/pause`**. + ⇒ 2 cửa-sổ liên tiếp đi TRỌN đường hợp-lệ với **0 lần ghi lớp mềm**. Đây là chân đế của F-1/F-2 dưới. +- Chứng độc lập bằng git: sau `5469ec88 wal: pause` (08-08 13:30) chỉ còn `d3837c87` 13:43 + `8491923e` 13:49 rồi **đứt tới 08-09 20:06** ⇒ **window-3 (S184) sống ~10 phút, đẻ đúng 2 commit `wal: flush`**. + +--- + +## (2) KIỂM VẾT VAI-1 (`ctx-curator` ×2) — đối-chứng CHỌN MẪU, không lặp trọn + +Vết: `_context:69` (PAUSE-1 → `SUA — 9 điểm`) · `_context:94` (PAUSE-2 → `SUA — 6 điểm`). + +**Mẫu A — curator @pause-2 #1 "thứ-tự land-PAUSE-trước-chèn-MIND" + #3 "header HEAD thật":** +- `_context` PAUSE-2 heading ts = `2026-08-08T13:18:00` · MIND-2 heading ts = `2026-08-08T13:18:00` → **khớp từng giây**, PAUSE land trước. +- MIND-2 heading `@ 06d873cc` · `_pause-2.md:2 head-sha` = `06d873cc…` → **khớp**. +- ⇒ **2/2 điểm curator ĐÃ LAND THẬT trên đĩa**, không phải verdict trang trí. + +**Mẫu B — curator @pause-1 #3 "V-5 rơi lần 2":** MIND-1 §D `:139` có `{mới-nêu}` V-5 kèm khai "đây là lần rơi thứ 2 nếu không mang tiếp" ⇒ **đã vớt thật**. + +**Đ-6 ĐẠT — vai-1 CÓ RĂNG, 3/3 mẫu đối-chứng ăn.** + +🔴 **Nhưng trần đối-chứng bị luật khoá — xem F-5.** + +--- + +## (3) KIỂM VẾT VAI-2 (`ctx-verifier` @tiep-3) — và tao SIẾT LẠI cờ #4 của nó + +Vết = **đúng 1 dòng**: `_tiep-3.md:6` — `NAP-LAI-SAN-SANG — 15 cờ (nặng nhất: S184 chỉ sống ở WAL · V-5 nhà nay = WAL:24 DI-TRÚ @S184 · deep 19/15 theo counter 59-40 · tiep-3ter-seed-unwired đóng tại cửa này bằng chính dòng này)`. + +**Đối-chứng cờ #4 ("S184 = 0 hit ở cả `_mind` lẫn `_context`, 3 datum sẽ mất khi WAL tái sinh"):** + +| vế | tao đo | phán | +|---|---|---| +| "S184 0 hit ở `_mind`/`_context`" | `_mind` nhắc `@S183` (`:105`), **không** S184; `_context` FLOW dừng ở PAUSE-2 | ✅ **ĐÚNG** | +| "3 datum sẽ MẤT" | cả 3 ý **CÓ MẶT** ở MIND-2 §D: V-5 `:96` · đề-nghị-ring2 `:97` · ring1-persona `:98` | 🔴 **BÁC MỘT PHẦN** | + +🔴 **Siết lại cho đúng — và cái đúng thì NGUY HƠN cái vai-2 nói:** thứ mất khi WAL tái sinh **không phải 3 ý** (chúng nằm trong block BẤT BIẾN), mà là **sự-kiện DI-TRÚ + địa-chỉ nhà MỚI**. Đo thêm để định lượng: +- `grep -c "V-5" docs/HANDOFF.md` = **0** · đề-nghị-ring2 = **0** (control-dương: `carry` = **105** hit, file 196.350 B ⇒ grep sống) +- ⇒ Sau khi WAL:25 bị tái sinh, nhà còn lại của V-5 = `_mind:96`, mà `:96` ghi **"nhà duy nhất = `bao-cao-cuoi.md:79` artifact đóng"** — **địa chỉ ĐÃ SAI từ S184**. +- ⇒ Kết cục thật không phải *"mất ý"* mà **"giữ ý với địa chỉ sai"** — tệ hơn, vì cửa-sổ sau mở ra thấy ý CÓ NHÀ nên không đi tìm. Đúng class tao bắt @S158: **con-trỏ chỉ SAI CHIỀU tệ hơn im lặng**. + +**BÁC-2 (giữ bản ghi ĐÚNG, từ chối áp máy móc "tin sổ máy"):** WAL:24 xếp **VK-5** vào ngăn `treo-chờ-anh (3 — THẬT sự cần anh phán)`, còn `_mind:91` gắn `{đang-cãi}`. Luật (iii)-1 bảo TIN SỔ MÁY ⇒ máy móc thì phải lật `_mind` thành `treo-chờ-anh`. **Tao TỪ CHỐI.** Nội dung `:91` nói rõ tranh chấp là *"3 bề mặt còn lệch — có thể anh ĐÃ phán rồi mà ledger ngân quá tay"*; đó **đúng nghĩa `đang-cãi`**, còn `treo-chờ-anh` sẽ khoá món sau cánh cửa chỉ anh mở được **trong khi có thể anh đã mở rồi**. Ngăn WAL là rổ THÔ; nhãn `_mind` mịn hơn và **đúng hơn**. (Tiền lệ tao @S173 F-3: *áp máy móc "tin sổ máy" sẽ GIẾT bản ghi ĐÚNG*.) + +--- + +## (4) 🔴 MỒI ĐÃ GIEO — `ring1-persona "CẤM chạy @open"` · CHẤM: **VẪN TREO** + +**Mồi gieo từ:** `_mind:190` (MIND-0 §D, @S182 open) → `:142` (MIND-1) → `:98` (MIND-2, tự khai *"đồng thời là MỒI ctx-audit @close sẽ chấm"*) → WAL:25 → `run.md:27-29`. + +**Đo 4 điểm:** + +1. **Persona: 0 SỬA.** `.claude/agents/ring1-audit.md:25` giữ **nguyên văn**: *"…⇒ **CẤM tự chạy ở open** dù thấy H1/H2 có vết mở-phiên"*; `:26` giữ fail-safe *"pin input missing ⇒ **NO-OP im-lặng**. Auto ≠ chạy-mù."* +2. **Vận hành kỳ này: ĐÚNG.** `run.md:19` — ring1 chạy ở nhánh `V1 ring1 KIỂM (SAU H1+H2)`, verdict `30Đ/3T`. Đúng chữ persona. +3. 🔴 **Ca vi-phạm nằm TRONG CHÍNH phiên-logic này, không phải quá khứ xa.** `_mind:199` (MIND-0 §E) ghi: `ring1-audit → 41 ĐẠT / 7 TRƯỢT / 8 KC → 2026-08-07-S182-bookend-open/sub-ring1-audit.md`. ⇒ **@open của L13 ring1 đã chạy ĐẦY ĐỦ**, không NO-OP. Và H1/H2 CÓ chạy @open đó (`_mind:195-196`) ⇒ **pin không rỗng** ⇒ fail-safe `:26` không kích, còn lệnh cấm `:25` thì **không có ai thi hành**. +4. 🔴 **Vai không tự biết.** `grep -i "open" sub-ring1-audit.md` (bản @close kỳ này) = **0 hit** — control-dương: `ring1` = **5 hit** cùng file ⇒ grep sống. Vai vừa chạy đúng cửa mà **không hề nêu** rằng chính nó đã chạy sai cửa một lần trong cùng phiên-logic. + +**⇒ PHÁN MỒI: TRƯỢT — mồi KHÔNG được xử.** Vận hành 1 lượt đúng ≠ đóng món; persona nguyên si, ca vi-phạm chưa ai đối chiếu, item "sửa persona" vẫn nằm ngăn *việc-CỦA-EM* ở WAL:25. + +### 🔴 Cái gì của HỆ đang hỏng (câu lead hỏi) + +**Ba tầng, tầng sau nặng hơn tầng trước:** + +- **(a) Lệnh cấm KHÔNG CÓ RĂNG.** Persona `:25` viết `CẤM tự chạy ở open` nhưng điều-kiện fail-safe `:26` lại neo vào *"pin missing"*. @open thì **pin CÓ** (H1/H2 chạy thật) ⇒ cấm-thì-cấm, cửa vẫn mở. **Đây là 2 mệnh đề không nối nhau trong CÙNG một persona, cách nhau 1 dòng.** Đúng khuôn tao đã bắt 3 lần: *bài học nằm cạnh chỗ đau vẫn không tự bật*. +- **(b) Món tự-sửa-hệ KHÔNG CÓ SỔ.** Nó sống ở WAL:25 ngăn *việc-CỦA-EM* — mà WAL **bị tái sinh mỗi closeout**. 6 cửa qua nó tồn tại **chỉ nhờ lead nhớ chép tay**. `grep` HANDOFF ra 2 hit nhưng cả 2 là văn-bản **kỳ S152** (`:231` *"Last updated (kỳ S152)"*, `:239`), **không phải** món này ⇒ **món này 0 nhà durable**. +- **(c) MỒI của tao ĐÃ LÀM ĐÚNG VIỆC — và đó mới là tin xấu.** Cơ-chế mồi hoạt động hoàn hảo: gieo @S182, sống qua 3 block, được WAL + run.md chở tới đúng cửa chấm. **Vấn đề không phải trí nhớ, mà là KHÔNG CÓ AI CÓ NGHĨA VỤ SỬA.** Một món được nhớ kỹ suốt 6 cửa mà không nhúc nhích ⇒ hệ đang thiếu **đường thi-hành**, không thiếu đường ghi-nhớ. (Trùng khít bài @S173: *bài học đang câu-chữ trong context KHÔNG TỰ BẬT; chỉ vá CÓ ĐƯỜNG THI HÀNH mới bật.*) + +**Đề (propose-only, lead phán):** nối 2 mệnh đề trong persona ring1 bằng 1 câu ĐO ĐƯỢC — *"cửa = `@close`; spawn ở `@open` ⇒ NO-OP có khai **kể cả khi pin đủ**"* — rồi món này ĐÓNG được bằng vật, không cần chép tay cửa sau. + +--- + +## (5) CARRY + NHÃN §D — ý nào ĐỊNH-ĐOẠT mà chưa lật, ý nào RƠI + +**Ý RƠI: 0.** Đối chiếu MIND-1 §D (10 ý) → MIND-2 §D (8 ý + 1 ghi-chú ngoài-list): 2 ý rời đi đều có **disposition đúng** — slot (67) rời vì **ĐÃ CHỐT** (YC-016, MIND-2 §A + PAUSE-2), 3-site tự-quy-chiếu rời vì **thành VIỆC** (ghi chú `:101` khai thẳng *"nay là VIỆC ở WAL, không còn thảo-luận; curator #4"*). **Đ-7 ĐẠT — khác hẳn S158 (8 ý rơi im lặng).** + +**Nhãn lệch thực-trạng (F-6):** + +| ý §D | nhãn hiện | thực-trạng đo được | phán | +|---|---|---|---| +| deep-sweep H24 `:94` | `{gần-chốt}` **17/15** | **ĐÃ CHẠY XONG** kỳ này: `run.md:15-16` lead-stale 10 FLAG + lead-gap 6 FLAG; và số thật là **19/15** (WAL:13 ghi 18/15 @S184, `run.md:3` ghi 19/15) | 🔴 ĐỊNH-ĐOẠT + **số sai 2 nấc** | +| D5+D6 `:95` | `{gần-chốt}` | WAL:25 định-đoạt: *"ĐÃ SHIP — gỡ khỏi ngăn chờ-anh, chỉ chờ veto, KHÔNG chặn"* | ĐỊNH-ĐOẠT, chưa lật | +| V-5 `:96` | `{gần-chốt}` | ý còn sống, nhưng **con-trỏ nhà SAI** (ghi `bao-cao-cuoi.md:79`; nhà thật từ S184 = WAL:25) | con-trỏ sai chiều | +| VK-5 `:91` | `{đang-cãi}` | WAL:24 xếp `treo-chờ-anh` | **BÁC** — xem (3), `_mind` đúng hơn | +| (72) `:92` · ring5(41) `:93` | `{treo-chờ-anh}` | WAL:24 xác nhận còn treo thật | ✅ ĐÚNG | +| ring1-persona `:98` | `{gần-chốt}` | 6 cửa không nhúc nhích | nhãn **lạc-quan quá tay** | +| upload-căn-cứ `:99` | `{mới-nêu}` | PAUSE-2 (2) xác nhận còn để hỏi anh | ✅ ĐÚNG | + +⇒ **4 nhãn cần lật/sửa** (deep-sweep, D5/D6, V-5-con-trỏ, ring1-persona). **Cả 4 chỉ lật được bằng MIND-3** — block cũ BẤT BIẾN. + +--- + +## (6) MỤC B vs `WAL next:` — TIN SỔ MÁY + cờ (F-7) + +- `_mind:78` §B: *"cửa sau = bookend @close (trio + cặp H24 + ring2 + DEEP-SWEEP **17/15** + ctx-audit) → vá governance → đóng sổ YC-013"* +- `WAL:20 next:`: *"[**YC-018** CẤU HÌNH XONG] → verify P4 `wf_5d16a842-28e` → bookend @close **TRỌN MỘT LƯỢT theo luật ONE-SHOT mới** (deep-sweep **19/15** + … + gom nợ harvest 576KB + **MIND-3 đính-chính**) → acceptance-động-local"* + +**Lệch 4 chỗ, tất cả một chiều — `_mind` mù:** (a) số deep 17 vs 19 · (b) **YC-017** (email/adap pipeline, 9 spawn, đóng @S185) vắng · (c) **YC-018 luật ONE-SHOT** — chính cái luật đang chi phối cửa này — vắng · (d) gom nợ harvest + MIND-3 vắng. + +🔴 **Nhưng quy-kết cho đúng: đây KHÔNG phải lead viết sai §B.** §B được viết @pause-2 và **đúng tại thời điểm đó**; nó lệch vì **không có nhịp nào bắt viết lại** trong 2 cửa-sổ kế. ⇒ triệu-chứng của F-1, không phải lỗi độc lập. + +--- + +## (7) 🔴 F-1 (HIGH) — NHỊP REFRESH-BOOKEND: MÁY BIẾT BÀI, LỆNH KHÔNG CƯỠNG. Tái phát lần 3. + +**Đo trên tệp LỆNH:** +- `grep -ci "mind" .claude/commands/session-end.md` = **4** (control-dương: grep sống). Bốn hit đó là: `:188` spawn **tao** · `:407-408` trường `markers:`/`mind-blocks=` của `_end` · `:409` closed-check. **KHÔNG hit nào là bước GHI/REFRESH block.** +- `grep "mind-refresh"` = **0** ⇒ vế **fail-LOUD** tao đề @S162 (*"cửa-sổ đóng mà `|block|` không tăng thì `_end` BẮT BUỘC mang `mind-refresh: BỎ QUA — `"*) **chưa bao giờ land**. +- `grep -c "_context" .claude/commands/session-end.md` = **0** ⇒ `_context` cũng **0 cửa ghi @closeout** — đúng lỗ tao nêu @S169 (mồi @close §9), **chưa port**. + +**Đo trên MÁY (ngược chiều):** +- phép (6) **chừa sẵn ngân sách**: *"block-0 + p refresh/pause + **tối đa 2 refresh bookend**"* +- phép (10) **tự in câu vá**: *"chèn 1 block refresh SAU khi vòng cuối báo xong"* + +**Đo trên chính `_mind`:** khối luật `:10` vẫn ghi **"GHI = lead (single-writer) @4 nhịp"** và liệt refresh **CHỈ @`/pause`**. + +🔴 **Kết luận class:** ngân sách tồn tại · lời khuyên tồn tại · **bước gọi KHÔNG tồn tại**. Đây là **ghost-wire 2 chiều** — *guard dựng mà không ai gọi*. Và nó là **lần tái phát thứ 3** (tao nêu @S158 → nêu lại + đề luật @S162 → nay). @S162 lead thi hành **nửa đầu** (viết MIND-5 bằng tay 1 lần) mà **nửa sau — sửa CHỮ của luật — không land** ⇒ **hành-vi-một-lần không dính; chỉ LUẬT mới dính.** Bằng chứng là kỳ này: 2 cửa-sổ, 0 ghi. + +🔴 **Hệ quả công bằng cho lead:** **theo CHỮ hiện hành, lead KHÔNG vi phạm gì** — không có pause thì không có nhịp ghi. Trượt nằm ở **THIẾT KẾ**, không ở thi hành. Tao ghi rõ để lượt sau không quy tội nhầm người. + +--- + +## (8) F-2 (HIGH) — THIỆT HẠI ĐO ĐƯỢC: §E phủ **0/19 spawn** + +Đếm ĐĨA mọi lượt chạy sau mtime block-top (`find runs -newermt "2026-08-08 13:30:24"`): + +| nguồn | lượt | chi tiết | +|---|---|---| +| `2026-08-09-S185-email-adap-pipeline/` | **9 spawn** | 1 `invest-email-adap-fable` + 1 `review-checklist-fable` + **7 lane** `sub-opus-lane1-detector…lane7-machine` | +| `2026-08-09-S185-bookend-close/` | **10 spawn** | harvest-curator · harness-{eval,refine,audit} · lead-{stale,gap}-deep · ring2 · tooling-auditor · ring1 · **+ ctx-audit (tao)** | +| engine-run | **1** | workflow `wf_5d16a842-28e` (7 lane) | +| máy | **5** | `script-arm-output.md` (22.950 B) | + +**TỔNG = 19 spawn + 6 engine/máy-run. `_mind` §E phủ: 0.** +Block-top MIND-2 §E có 4 dòng, **trọn vẹn cho window-2** (và tự khai *"window-2 KHÔNG fan-out — 0 workflow"*) ⇒ §E **không sai**, nó chỉ **dừng ở window-2**. + +So lịch sử: S159 **0/9** · S162 **0/13** · nay **0/19** — **thủng rộng nhất từ lúc tao sinh ra**, và lần này lỗ đã có người chỉ mặt 2 lần trước. + +--- + +## (9) F-4 (MED-HIGH) — `LEAD-PHAI-NHAC-LAI:` = **0 hit TOÀN CÂY** ⇒ một khoản của chính hợp-đồng tao là BẤT-KHẢ-THI + +Luật `tiep.md:197` (§3-ter) đòi bản-nạp-lại vai-2 **kết bằng** dòng `LEAD-PHAI-NHAC-LAI: · `, và *"Lead **PHẢI NHẮC LẠI** đúng các chi tiết đó… 'đã nạp' suông KHÔNG tính, metadata ts/hash KHÔNG tính"*. + +**Đo:** +- `grep -rn "LEAD-PHAI-NHAC-LAI" .claude/sessions/ + run-folder` = **0** +- control-dương ①: `NAP-LAI` cùng cây = **12** hit ⇒ grep sống +- control-dương ②: chuỗi tồn tại trong `tiep.md` = **1** hit ⇒ chuỗi tao tìm đúng chính tả của luật + +⇒ Cái móc để kiểm **chưa bao giờ chạm đĩa** — không riêng kỳ này mà **toàn bộ `.claude/sessions/`**. Hợp-đồng tao khoản (iii): *"kiểm lead có NHẮC LẠI thật không — bằng-chứng nội-dung, sàn khoản 3"* ⇒ **tao KHÔNG chấm được**, và khai thẳng thay vì cho ĐẠT-ảo. + +🔴 **Trớ trêu đáng ghi:** đây là phép chống *"đã nạp suông"*, và chính nó đang ở trạng thái **suông**. + +--- + +## (10) F-5 (MED) — TRẦN ĐỐI-CHỨNG 11/30 = 36,7%: luật cố ý cho vai-1/vai-2 "không đẻ file", chỉ vai-3 có file + +| vai | luật scribe | vết thực tế | điểm sinh ra | điểm CÓ TÊN | +|---|---|---|---|---| +| vai-1 `ctx-curator` | `pause.md:63` — *"verdict 1-dòng ghi vào `PAUSE-` mục (3) (**vết, không đẻ file**)"* | `_context:69` + `:94` | 9 + 6 = **15** | 4 + 4 = **8** | +| vai-2 `ctx-verifier` | `tiep.md:197` — *"verdict 1-dòng ghi vào biên-nhận (vết)"* | `_tiep-3.md:6` | **15** | **3** | +| vai-3 (tao) | `session-end.md:188` — *"Lead scribe `sub-ctx-audit-close.md` NGAY khi trả"* | file này | — | — | + +**30 điểm sinh ra · 11 có tên · 19 vô danh.** Tao được giao *"đọc verdict vai-1/vai-2, chấm đủ/kín"* — trần vật-lý của việc đó là **36,7%**. Phần "kín" tao **không chấm được**, và **không phải vì lười**: luật quy định vết đúng 1 dòng. + +🔴 **Nhận xét cân bằng, không đòi phình:** "không đẻ file" là chọn lựa CÓ LÝ (chống phình, chống rác run-folder). Cái lệch là **bất đối xứng**: hai vai soi **hành-vi GHI** (nơi lỗi sinh ra) để lại 1 dòng; vai soi **chuỗi** để lại 20-40 KB. Đề rẻ nhất (propose-only): giữ 1 dòng, nhưng **bắt liệt ĐỦ mã điểm** (`#1…#9`) thay vì `nặng nhất: …` — 0 file mới, 0 KB đáng kể, mà trần đối-chứng lên 100%. + +--- + +## (11) 🔴 MỒI-NGẦM TAO TỰ TÌM (không ai giao) — `mind-blocks=` SẼ SAI TRONG CHÍNH LƯỢT NÀY + +**Tiền lệ tao đo lại được, không tin trí nhớ:** +- `.claude/sessions/session-12/_end:7` khai `markers: _pause=1 · _tiep=1 · _snapshot=0 · **mind-blocks=1**` +- đĩa thật: `grep -cE "^## MIND-[0-9]" _mind-s-12.md` = **2** +- mtime: `_end` = `23:28:49.203` · `_mind-s-12.md` = `23:30:11.509` ⇒ **`_end` ghi TRƯỚC `_mind` 82 giây** + +⇒ Không phải đếm sai — **lỗi THỨ-TỰ GHI**: sổ cân được ghi **trước** sự kiện cuối mà nó phải kể. + +**Dự báo cho lượt này (kiểm được ngay, đừng đợi phiên sau):** WAL:20 đã hứa **MIND-3**. Nếu `_end` được ghi trước khi MIND-3 land ⇒ `_end` sẽ khai `mind-blocks=3` trong khi đĩa = **4**. Máy `mind-check` **CÓ** bắt (cross-check tự-khai vs đĩa → cờ-INFO) **nhưng** cờ đó chỉ sống ở phiên **đã đóng** — tức là kêu khi không còn ai nghe. + +**Chặn 1 câu:** ghi MIND-3 **TRƯỚC** `_end`; nếu buộc phải ngược thì `_end` khai `mind-blocks=4` theo **dự-kiến-đã-land** và verify lại sau khi land. + +**Phụ chú cùng họ (tự tìm, giữ làm vết):** `_end` **không có đuôi `.md`** — mọi phép quét `*.md` đều mù nó. Tao đã nêu class này @S173 (mất `ROTATE mật-khẩu prod`); nay xác nhận lần 2 bằng chính `session-12/_end`. Sổ cân cuối cùng của một phiên đóng là **tệp tàng hình nhất trong repo**. + +--- + +## (12) 🔴 PHÁN QUYẾT THIẾT-KẾ — MIND-3 CÓ CẦN **NGAY** TẠI BOOKEND NÀY KHÔNG? + +### **CÓ — BẮT BUỘC, trước khi ghi `_end` và trước commit chốt.** + +**6 căn cứ, không căn cứ nào là cảm tính:** + +1. **Máy đã kêu và đã kê toa.** Phép (10) `co` + tự in *"chèn 1 block refresh SAU khi vòng cuối báo xong"*. Bỏ qua = bỏ qua khuyến nghị của chính lưới rẻ nhất. +2. **Ngân sách CHỪA SẴN, không phải xin thêm.** Phép (6) cho `[p, p+3]` = `[2,5]`; hiện 3 ⇒ MIND-3 = 4, **vẫn trong trần**, 0 rủi ro. +3. **Dung lượng thừa.** 25.619 B / 49.152 B = **52,1%** ⇒ còn **23.533 B**. Không có cớ "sắp vượt trần nên hoãn". +4. **Block BẤT BIẾN ⇒ cửa này là cơ hội DUY NHẤT.** 19 spawn của window-3/4 và 4 nhãn §D sai **không lượt nào sau sửa được** — chỉ block MỚI mới kể được. Không ghi = đóng băng vĩnh viễn một phiên-logic mù 2/4 cửa-sổ. +5. **WAL đang tự hứa.** `WAL:20 next:` đã liệt đích danh *"MIND-3 đính-chính [`_mind:108` thước-hỏng · V-5 nhà=WAL:24 · D5/D6 hạ nhãn]"*. Closeout reset WAL **trước khi** MIND-3 land ⇒ mất chính lời hứa. +6. 🔴 **Căn cứ quyết định — bất đối xứng về ĐỘ BỀN:** WAL là sổ **bị tái sinh mỗi closeout**; block `_mind` là **append-only bất biến**. Món nào chỉ sống ở WAL mà chưa có đích HANDOFF/STATUS thì **cửa này là lần cuối cùng nó còn đọc được**. Đo cụ thể: V-5 (HANDOFF **0** hit) · đề-nghị-ring2 (**0** hit) · ring1-persona (2 hit nhưng là văn-bản kỳ S152, **không phải món này**) ⇒ **3/3 món không có nhà durable ngoài WAL**. + +### Nhưng KÈM 3 ràng buộc thi-hành — thiếu thì MIND-3 đẻ lỗi mới + +- **(a) THỨ TỰ: MIND-3 land TRƯỚC `_end`** — xem §(11); nếu không, `mind-blocks` off-by-one **tái phát lần 2**. +- **(b) §E của MIND-3 PHẢI có dòng cho `ctx-audit` ĐANG chạy** (tiền lệ vá @S173, và @S182 FLAG-7 đã bắt đúng hình này) — nếu không §E lại thiếu đúng lượt cuối, lặp vô hạn. +- **(c) V-5 ghi nhà MỚI (WAL:25) VÀ phải có đích đổ HANDOFF** theo chính `session-end.md:253` + `:307` (*"MỌI mục chưa-đóng PHẢI chỉ đích nơi đổ: carry-slug HANDOFF / WAL-line / STATUS-row"*) — vì WAL:25 sắp bị tái sinh. 🔴 Lưu ý: `_mind` **KHÔNG** nằm trong danh sách đích hợp-lệ đó ⇒ ghi vào `_mind` là **giữ trí nhớ**, KHÔNG phải **giao việc**. Cần cả hai. + +### 🔴 Và câu trả lời cho vế "lỗ này thuộc nhịp-ghi hợp-lệ hay không" + +**Hợp-lệ theo CHỮ, hỏng theo THIẾT KẾ.** Chữ hiện hành (`_mind:10` + `pause.md` (C-bis)) chỉ neo refresh vào `/pause` ⇒ 2 cửa-sổ không pause thì **không ai sai**. Nhưng máy chừa chỗ cho refresh-bookend, máy khuyên làm refresh-bookend, và tiền lệ MIND-5@S162 đã làm refresh-bookend ⇒ **thiết kế KỲ VỌNG nhịp thứ 5 mà lệnh không viết ra**. ⇒ **Ghi MIND-3 kỳ này là cần, nhưng KHÔNG ĐỦ** — làm tay lần thứ 2 sẽ rot lần thứ 4. Vá phải nằm ở **CHỮ**: thêm bước refresh vào `session-end §L.b` + vế fail-LOUD `mind-refresh: BỎ QUA — ` trong `_end`, và sửa `_mind:10` từ **"@4 nhịp"** thành **"@5 nhịp"**. + +--- + +## (13) BẢNG ĐẠT (7) — có gì thật sự tốt, ghi để không thổi phồng phần xấu + +| # | khoản | bằng chứng | +|---|---|---| +| Đ-1 | bất-biến chuỗi | tao đếm đĩa `\|block\|=3 · p=2` **khớp máy tuyệt đối**; snapshot 2↔2 pause cân sổ | +| Đ-2 | **neo xuất-xứ 3/3** — class tao bắt @S169+@S172 **ĐÃ ĐÓNG** | MIND-0 `ts 23:37:36 @ 936d1aed` vs git `936d1aed = 2026-08-07T23:37:36` **khớp từng giây**; MIND-1 `@706134da` = `_pause-1` head-sha; MIND-2 `@06d873cc` = `_pause-2` head-sha **và** heading tự khai *"sha = HEAD wal-flush lúc ghi, ship = 72568f05"* ⇒ đúng cách chống hiểu nhầm tao đòi | +| Đ-3 | 5 mục A-E đủ + nhãn D đủ | máy phụ-9 `dat`; tao đọc mắt 3/3 block, 0 mục trống im lặng | +| Đ-4 | 3 rào sạch | máy (1)(2)(3) `dat`; tao soi mắt: 0 verbatim lời anh dưới RULES-END, `_mind` chỉ trỏ *"xem PAUSE-2"* — đúng thiết kế nguồn-duy-nhất | +| Đ-5 | đã-chốt = con-trỏ | YC-016/slot(67) chốt ⇒ MIND-2 §A **trỏ** PAUSE-2, không chép nội dung | +| Đ-6 | vai-1 CÓ RĂNG | 3/3 mẫu đối-chứng ăn (thứ-tự land · HEAD thật · V-5 vớt) | +| Đ-7 | **0 ý rơi im lặng** | 2 ý rời §D đều có disposition đúng (chốt / thành-việc + ghi chú khai `:101`) — trái hẳn S158 (8 ý rơi) | + +--- + +## (14) NGOÀI TRỤC — escalate, KHÔNG tự lấn + +- `docs/STATUS.md` §In Progress **tự khai** *"mốc gần nhất S162 — phiên-LOGIC L8 … Section này STALE-BY-DESIGN"* trong khi đang ở **L13**. Với khoản (iii)-2 của tao (kế-hoạch C vs bản-đồ việc) ⇒ **STATUS không dùng được làm bản-đồ sống**; tao đối chiếu bằng WAL chain + `run.md`. Nêu để lead biết, **không phải việc của tao**. + +--- + +## checklistEvidence + +- **Máy đã đọc (không re-implement):** `python scripts/session_ctx.py mind-check --session 13` → `dat=10 TRUOT=0 co=1 exit 0`; cờ (10) lệch **132.062 s**. +- **Số TAO tự tái-dựng từ ĐĨA:** `|block|=3` (`grep -cE "^## MIND-[0-9]"` — sau khi **tự bắt** bẫy placeholder của `^## MIND-`) · `p=2` · `_tiep=3` · `_snapshot=2` · `_end=0` · **19 spawn + 6 engine/máy** (`find runs -newermt`) · s12 đối-chứng `mind-blocks` khai **1** vs đĩa **2**, `_end` sớm **82 s**. +- **0-hit LUÔN kèm control-dương:** `LEAD-PHAI-NHAC-LAI`=0 (control `NAP-LAI`=12, luật `tiep.md`=1) · `V-5` trong HANDOFF=0 (control `carry`=105, file 196.350 B) · `open` trong `sub-ring1-audit.md`=0 (control `ring1`=5) · `mind-refresh` trong `session-end.md`=0 (control `mind`=4). +- **Git đối-chứng:** `git log --since="2026-08-08 13:30"` dựng lại window-3 = ~10 phút / 2 commit; 3 SHA heading verify bằng `git log -1 --format=%cI`. + +## memoryDelta (4-field, lead seed on-behalf — tao KHÔNG tự ghi) + +- **carry mới:** `mind-refresh-bookend-luat-chua-land` (tái phát lần 3, S158→S162→S185) · `ring1-cam-open-khong-rang` (2 mệnh đề rời nhau cách 1 dòng trong cùng persona) · `nhac-lai-hook-0-hit-toan-cay` +- **carry ĐÓNG:** `mind-neo-xuat-xu-sai-2-truong` (@S172) — **3/3 block khớp**, MIND-2 còn khai thẳng nguồn sha ⇒ đóng bằng vật +- **giữ nếp:** tự re-chạy máy thay vì tin số PIN (lần 5) · 0-hit kèm control-dương (4/4) · **tự bắt thước của chính mình trước khi phán** (bẫy `^## MIND-`) · BÁC đề-bài khi đo không ủng hộ (2 lần: "3 datum sẽ mất" · VK-5 tin-sổ-máy) +- **tag:** `[s185, truot-8-flag, kiem-cua-kiem, nhip-refresh-bookend-tai-phat-lan-3, E-0-tren-19-spawn, moi-ring1-treo-6-cua, nhac-lai-hook-vang-mat, mind-blocks-thu-tu-ghi, neo-xuat-xu-dong]` + +--- + +END diff --git a/CLAUDE.md b/CLAUDE.md index fbd6414..48624de 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -19,6 +19,7 @@ Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Ser ``` > ⛓️ **Mạch việc dở (H22):** nằm ở `.claude/WAL.md`; nối lại DUY-NHẤT bằng `/tiep` — kể cả khi anh gõ "làm tiếp" bằng text thường. Không tự recovery cách khác. (Chốt dừng chủ-động = `/pause`; cơ-chế → `docs/governance/harness-11-engine.md` PHẦN N.) +> 🔴 **Nghi-thức 2 đầu phiên = ONE-SHOT (YC-018 anh chốt @S185, nguồn thư hub 08-08 Phần 1b):** bookstart + bookend chạy **trọn MỘT LƯỢT**, CẤM lấy `/pause`·`/tiep` làm nhịp chia-chặng nghi-thức, CẤM hẹn-vòng-cửa-sau; đứt bất-khả-kháng ⇒ lượt-nối đầu tiên chạy HẾT phần thiếu. Luật sống ở đầu [`session-start.md`](.claude/commands/session-start.md) + [`session-end.md`](.claude/commands/session-end.md) — dòng này CHỈ TRỎ (B1). > 🎛️ **Chế-độ đang hiệu-lực (operating-posture) — TRA Ở ĐÂU** *(adap đợt-11, `3-khoan:31-41` discoverability-home ⟂ implement-home)*: > file này **CỐ Ý KHÔNG chép giá-trị** ON/OFF — chép là sai ngay lượt sau khi anh toggle. Chỉ trỏ **nơi tra**: @@ -27,6 +28,12 @@ Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Ser > - **Lead model** → `~/.claude/settings.json` (**global, NGOÀI git** — grep trong repo sẽ ra 0 hit); probe runtime mỗi phiên ở BƯỚC 0.6. > - **Nhịp H24 / ngân-sách memory** → `.claude/agent-memory/memory-budget.json` (single-source; doc **trỏ key, không chép số**). +> 🗣️ **Lead suggest 1 dòng — non-blocking, rồi chạy luôn** *(adap `cost-lens` khoản ③ 19-07 — owner-side, KHÔNG floor)*: +> - Anh **gõ lệnh đích-danh** (`/fable-real`, `/ultra-on`, chỉ định vai…) = **kênh CỨNG** — thực thi, không bàn, không suggest gì thêm. +> - Anh giao việc mà **KHÔNG chỉ-định** cách chạy (chế-độ engine · vai · solo hay fan-out · độ sâu) ⇒ lead tự đánh giá, **nói đúng 1 dòng** *("việc này em chạy X vì …")* **rồi chạy luôn** — **KHÔNG treo chờ anh trả lời**. Anh đọc thấy, muốn đổi thì 1 lệnh là xong. +> - 🔴 **CẤM nén thành rule máy auto-route.** Hub đã thử cực đó rồi **RÚT** (mất tự-chủ + đóng cửa việc lead bắt được ca heuristic sai); cực ngược lại — lead im, anh tự nhớ hết — cũng bị bỏ. Chốt là ở **giữa**: mọi lựa chọn hiện ra bằng chữ, override được, không ai chờ ai. +> - Áp cho **mọi** lựa-chọn vận-hành mà lead làm thay anh được nhưng anh muốn giữ mắt nhìn — không riêng chuyện chọn engine. + ## ⚡ Quick Rules ### Backend — `.NET 10` Clean Architecture diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 0af76c0..2198a22 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -2,13 +2,27 @@ > **Tiering rule (S40):** giữ **2-3 session gần nhất**. Cũ hơn → `docs/changelog/sessions/`. Full brief history pre-S40 → `docs/_archive/HANDOFF-preS40-fullhistory.md`. -**🆕 Last updated:** 2026-08-07 (**S180→S181** — phiên-LOGIC **L12** windows 1-2). **Gói adap 7 GĐ ĐÓNG 10/10 wave.** Anh chốt 8 câu P1-P8 + ký 2 RC-mark. Roster 26→28 vai, cap 20→30 (slot 75 đóng). 3 máy governance mới + 4 máy vá. Push `55894a04..5ae60e41`. -> 🔢 **CHỜ ANH (trả lời bằng SỐ):** **(1)** duyệt `adap-reports/upgrade-pack-phased-bao-cao-cuoi.md` → gửi hub? · **(2)** ghép điều-kiện-3 của thư hub 08-07 vào **bậc-2** luật tự-trị (`ACTIVE-MARKS §LT3`)? · **(3)** P3 = **forward-only** (lead đang đọc vậy) hay **hồi-tố** trục xuất class khỏi enum đã niêm phong? · **(4)** VK-5 — cho nhập bảng `HANDOFF:10-17` vào khối chính sổ yêu-cầu, hay giữ ở phụ lục *suy ra*? -> 🔴 **NEXT-em (tự chạy, không cần anh):** cắm mã thoát W3b khi soak đủ (đã phân loại 64/64 ở `harness-11-engine PHẦN Q`) · `OVERDUE:deep` 15/15 · 3 tệp over-cap. -> 🔁 **RE-STAMP CARRY @S181** — đóng dấu lại **20 carry còn mở** (`session-end §L.b(j)(iv)`). Bản trước rơi **4 kỳ liên tiếp**, `class_repeat.gap-carry-dropped` = **12** = 4× ngưỡng JUMP ⇒ nghi-thức này **không có răng**, không phải đãng trí: +**🆕 Last updated:** 2026-08-10 (**S182→S185** — phiên-LOGIC **L13** windows 1-4; nhãn cũ "S180→S181/L12" giữ ở segment dưới). **YC-013 KHKK 8-panel SHIP+verify · YC-016 guard tay-cầm-phiếu SHIP+verify · YC-017 pipeline email/adap TRỌN (0/39 nợ per-id) · YC-018 ONE-SHOT bookend land 4 site · bookend @close MỘT MẠCH 9 vai** (trio 40Đ/4T · H24 deep 16 FLAG · ring1 30Đ/3T · ring2 16Đ/0T · ctx-audit 8 FLAG · harvest 698KB→17 khối/11 sổ). Adap-report 08-08: `docs/governance/adap-reports/2026-08-08-Governance-quy-trinh-hai-dau-phien-may-diem-danh-va-6-bai-hoc.md` (F-4 vá: trỏ bền tại đây). +> ✅ **KHỐI "CHỜ ANH @S181" — ĐÓNG 4/4 @S185, LẬT TỪNG CÂU KÈM EVIDENCE** *(đo tươi 2026-08-09, lane-4 `runs/2026-08-09-S185-email-adap-pipeline/sub-opus-lane4-report-hygiene.md §1`; 🔴 **cố ý KHÔNG lật cả cụm một nước** — 4 câu **không đồng-hạng bằng-chứng**, xem 2 nhóm dưới)*: +> - 🟢 **Nền = chữ owner trực-tiếp + VẬT CHỨNG NGOÀI (chắc nhất):** **(1)** duyệt `bao-cao-cuoi.md` → gửi hub — **DUYỆT + ĐÃ GỬI @S181**: `adap-reports/upgrade-pack-phased-bao-cao-cuoi.md:3` nguyên văn ***"1,2,3,4 -> OK"*** · thư thật trên đĩa `broadcasts/outbox/ai_infra/2026-08-07-se-to-ai_infra-upgrade-pack-phased-bao-cao-cuoi.md` (**7.231 B**, mtime 08-07 23:36) · dấu `ACTIVE-MARKS.md:27` `RC-pqhuy1987-07-08-2026-21-42-10` Active-High anh-confirm S181 (PHẠM-VI-KÝ loại trừ W3b + W5b(ii) — **giữ nguyên**). · **(2)** ghép điều-kiện-3 vào **bậc-2** — **ĐÃ GHÉP @S181**: `ACTIVE-MARKS.md:65` mang nguyên khối *"+ Điều-kiện-3 (ghép @S181, anh gật)"* (`grep -n "Điều-kiện-3"` → 1 hit) + sổ `owner-decisions-07-08-2026-dot-2.md:47`. +> - 🟡 **Nền = "OK" trả cho câu do LEAD đóng khung (yếu hơn — đường đảo còn mở, ghi để không đọc quá):** **(3)** P3 — **CHỐT FORWARD-ONLY @S181** (`owner-decisions…dot-2.md:48`): **KHÔNG** trục xuất 12 class đang có; 🔴 sổ tự khai *"Muốn hồi-tố về sau thì cần một lệnh **tường minh**, không suy từ 'OK'"*. · **(4)** VK-5 — **CHỐT GIỮ PHỤ LỤC @S181** (`:49`): bảng `HANDOFF:10-17` **KHÔNG** nhập khối chính sổ yêu-cầu, ở phụ lục nhãn *"suy ra, không phải nguyên văn"* (giữ sạch cột lời-nguyên-văn, luật chống-bẫy-A1). +> 🧊 *Nguyên văn dòng cũ (giữ làm vết — bài-5):* **(1)** duyệt `bao-cao-cuoi.md` → gửi hub? · **(2)** ghép điều-kiện-3 thư hub 08-07 vào bậc-2 (`ACTIVE-MARKS §LT3`)? · **(3)** P3 = forward-only (lead đang đọc vậy) hay hồi-tố trục xuất class khỏi enum đã niêm phong? · **(4)** VK-5 — nhập bảng `HANDOFF:10-17` vào khối chính sổ yêu-cầu hay giữ phụ lục *suy ra*? +> 🔴 **Bài của lượt lật này:** giả-thiết lúc giao việc là *"(3) và (4) chắc chưa có phán quyết"* — đo đĩa thì **cả 4 đều đã có**, phán quyết nằm sẵn ở `owner-decisions-07-08-2026-dot-2.md` mục *"Còn treo sau đợt-2"* từ **08-07**, tức khối này **hỏi lại anh một việc đã xong suốt 2 ngày**. Đúng lớp *"sổ nói dối theo hướng BI QUAN"* (`:74`) — và lần này nó sống được vì **không máy nào đối chiếu `HANDOFF` ⟂ sổ quyết-định**. +> 🔴 **NEXT-em (tự chạy, không cần anh — cập nhật @S185):** W3b mã-thoát = **CHỜ rider-jump được DỰNG** (lane2 chứng soak-vế-2 chưa thoả — rider-jump 0-hit toàn scripts, "nợ-chưa-có-chủ" F-L2-2; header tien-kiem đã flip PA-2) · ~~`OVERDUE:deep`~~ ✅ **ĐÃ TRẢ @S185** (19/15 → deep_at=59, tally ghi máy) · over-cap nay = **5 vai >25.600** (4 vai >30.720; A1 impl-be + A2 lead-stale thi hành @S185, ring2 chờ quyết C-6) · vá persona ring1 `:25` "CẤM @open" (ctx-audit F-3 hệ-hỏng-3-tầng) · addendum-2 goi-chot vế 4.4. +> 🔁 **RE-STAMP CARRY @S181** — đóng dấu lại **25 slug** (đếm lại @S185 theo stale-F6: 23 dòng dưới + 2 dòng CARRY-LẠI; số "20" cũ là view-stale-count) (`session-end §L.b(j)(iv)`). Bản trước rơi **4 kỳ liên tiếp**, `class_repeat.gap-carry-dropped` = **12** = 4× ngưỡng JUMP ⇒ nghi-thức này **không có răng**, không phải đãng trí: > `[carry:acceptance-runtime-khkk]` `[carry:account-trung]` `[carry:binh-le-decision]` `[carry:bvaau]` `[carry:ctx-t9-dogfood]` `[carry:e7-cot-chet-khkk]` `[carry:endline-sub-md]` `[carry:harvest-no-s168-s171]` `[carry:harvest-orphan-s159-tongquan]` `[carry:hmw-subfile-index-collision]` `[carry:pe-phanquyen]` `[carry:ring5-audit-gap]` `[carry:synthesis-roll-s159-s160]` `[carry:tiep-3ter-seed-unwired]` `[carry:tiep-reload-underfill]` `[carry:tools-whitelist-no-teeth]` `[carry:tra-bui-relogin]` `[carry:uat-s117]` `[carry:uat-s133-budget-freeze]` `[carry:uat-s134-luyke]` `[carry:w3b-cam-ma-thoat]` `[carry:bao-cao-cuoi-cho-duyet]` `[carry:h24-deep-overdue]` +> 🔺 **CARRY LẠI @S185 — 2 slug BỊ RỚT, nay trả về danh sách trên (ADDITIVE, không sửa dòng cũ):** `[carry:eval-thamquyen]` *(2 cột thẩm-quyền eval — slot **(22)**, nhà thật `runs/2026-07-25-S149-adap-backlog/sub-apply-L5-evalcuaeval.md:37,41,59,115`; có ở carry S150-S152, **0 hit** ở khối này trước lượt vá)* · `[carry:session-model-adopt]` *(cổng (c) duyệt bảng VC-1/2/3 — có ở carry S140-S151, **0 hit** ở khối này; wire đã xảy ra de-facto, xem addendum `adap-reports/2026-07-17-…session-model-phien-logic-manifest.md §6`)*. Lệnh chứng: `grep -c "carry:eval-thamquyen" docs/HANDOFF.md` → **1** trước vá (chỉ segment cũ `:241`), control-dương `carry:ctx-t9-dogfood` = **6**. +> 🔴 **2 ca `gap-carry-dropped` này KHÔNG nằm trong tally 4-kỳ ở trên** — chúng rơi **im lặng** và chỉ lộ ra khi có người đi tìm *nhà* của một câu hỏi (C-16), không phải khi chạy nghi-thức re-stamp. ⇒ bằng-chứng thứ hai cho chính câu *"nghi-thức này không có răng"*: nó **không tự phát hiện được slug mình đánh rơi**, vì nó chép danh-sách kỳ trước chứ không dựng lại từ nguồn. +> 🔸 **2 việc trình lead, lane-4 CỐ Ý KHÔNG tự làm:** (i) **đếm lệch** — header trên ghi *"20 carry còn mở"* nhưng danh-sách đếm được **23** slug (chưa kể 2 slug vừa carry lại) ⇒ tally là số của lead, không tự sửa. (ii) **`[carry:bao-cao-cuoi-cho-duyet]` đủ điều-kiện ĐÓNG** (câu (1) khối trên: duyệt + đã gửi hub + có dấu RC) — nhưng đóng carry thuộc nghi-thức `session-end §L.b(j)(iv)`, lane-4 chỉ **nêu ứng-viên**, không tự đóng. > ✅ **ĐÓNG @S181:** `[carry:hmw-width-vs-roster]` — cap 20→30, roster 28 ≤ 30, slot (75) khép. -> 🔴 **`[carry:h24-deep-overdue]` MỚI** — `OVERDUE:deep` 15/15 bị lead hạ xuống hàng NEXT-em ngang việc vặt (FLAG-4 `gap-decision-sunk`). Cổng ĐÃ kêu, máy ĐÃ in, lead ĐÃ chép 2 sổ — rồi vẫn hoãn. **Cổng kêu mà không đổi hành-vi = cổng không có răng.** +> 🔻 **THU HẸP @S185 (KHÔNG gỡ trắng): `[carry:ctx-t9-dogfood]`** — carry này **ĐA VẾ** (định nghĩa gốc `:206`+`:210`, khớp PHẦN B `runs/2026-07-26-S153-ctx-adopt/sub-fable-invest-S153.md:129-134`). Đóng **TỪNG VẾ có bằng-chứng**, vế thiếu thì **giữ**, không đóng cả cụm: +> · **#18 dogfood 4-cửa THẬT — ĐÓNG:** `session-start` Phase 3.5 → 8 tệp `_mind-s-{6..13}.md` (12.482→43.663 B) · `/pause` C-bis → `_context-s-12.md:47` entry `PAUSE-1` · `/tiep` §3-ter → `owner-decisions-07-08-2026-dot-2.md:3` *"window-2 … **vào bằng `/tiep`**"* + `ctx-verifier` diary **19.205 B** · `session-end` (l) → **10** tệp `sub-ctx-audit-{open,close}-*.md` (S154→S182). Lệnh: `ls .claude/sessions/*/_mind*.md` · `ls .claude/workflows/runs/*/sub-ctx-*.md`. +> · **#20 spawn-probe CẢ 3 vai ctx — ĐÓNG:** `ctx-audit` 10 artifact đĩa · `ctx-curator` diary **12.465 B** mtime 08-08 (seed ~1,5 KB) + chính anh chốt *"Residual ctx-curator — giữ"* @S179 (`:20`) cho 2 tệp nó GHI THẬT · `ctx-verifier` diary **19.205 B** mtime 08-07 23:14 + 15 cờ @S185 (report 08-08). +> · **#22 lưới C11(b) fault-inject 2-CHIỀU — ĐÓNG:** `runs/2026-07-24-S149-hoi-tu-bookend/sub-impl-M4-c11.md:46` ca (c) — part(b) `diary-0-delta` **FLAG** ⟂ part(a) **IM** (anti-FP). +> · **wall-clock (#16) — ĐÓNG:** điều-kiện *"lệch >2× thì điền số THẬT"* đã kích hoạt và đã điền — `pause.md:66`: **+~0,12 s máy** (draft 61,3 ms + full 55,4 ms; tệp 34 KB vẫn 63,8 ms), thay ước 0,3-0,6 s (**lệch 2,2-5,4×**). +> · 🔴 **CÒN MỞ — carry thu về đúng 2 vế này:** **(i) #19 mồi-ngầm XUYÊN-CỬA-SỔ mới đóng NỬA** — vế *gieo* ĐẠT có vết (`runs/2026-08-05-S173-bookend-open/sub-ctx-audit-open-S173.md:377` *"(i)-4 gieo mồi-ngầm | **ĐẠT** — gieo tại §(v)"*), nhưng vế *"cửa-sổ SAU (/tiep) **nêu lại đúng ý**"* **chưa trưng được** trên đĩa ⇒ chưa có bằng-chứng fidelity-sau-nối-lại, đúng cái hub dặn *"đừng tin số của hub, tự đo"*. **(ii) #23 vế đối-chứng-dương TRƯỚC T5** (`role:'ctx-audit'` phải throw STOP-HARD) **n-a — không tái-lập được**, T5 đã land từ S153; vế owner-note của #23 thì đóng theo slot (75). 🔸 *Vế owner-note và #22 KHÔNG được đọc là đã phủ #19 — 3 diary `harness-{eval,audit,refine}` là **trio 07-21**, KHÁC trio ctx.* +> 🔴 **`[carry:h24-deep-overdue]`** — ✅ **ĐÓNG @S185**: deep-sweep ĐÃ CHẠY (19/15 trả, cặp H24 16 FLAG + ring2 16Đ/0T, tally máy `deep_at=59`). 🧊 lời cũ giữ làm vết: cổng kêu 4 kỳ mới có người trả — "cổng kêu mà không đổi hành-vi = cổng không có răng" vẫn là bài học đúng. +> 🔺 **KHÔI PHỤC @S185 — 12 slug VẮNG khỏi khối trên** (gap-deep F-1: khối `Carry @S152` `:232` tự khai "đủ MỌI slug" 23 cái, RE-STAMP chỉ giữ 11; ADDITIVE trả về, phân-định per-slug ở `runs/2026-08-09-S185-bookend-close/sub-lead-gap-deep.md` — 7 rớt-thật · 5 đủ-evidence-sẽ-đóng-có-verify): `[carry:bookend-5-5]` `[carry:carry-age-vacuous]` `[carry:context-stock]` `[carry:g011-token-fork]` `[carry:hook-vs-budget-cap]` *(điều-kiện CÒN SỐNG: 4 diary vượt soft-cap đo @S185)* `[carry:hub-review-wave-1807]` `[carry:meld-forward-unmeasured]` `[carry:pull-warn-threshold]` `[carry:tham-sau-6-ca]` `[carry:tiep-window-crash]` `[carry:underfill-mau-so]` *(điều-kiện CÒN SỐNG: target 210.000 > headroom 134.573 máy in @S185)* `[carry:veto-window-s149]`. ✚ ghi-nhận đóng: **V-5 vị-từ mã-hoá ĐÓNG @S185** (detector C15 rank-1/rank-2 land, `governance-detectors.ps1` — đo thật 12 file/25 hit rank-1). --- @@ -31,6 +45,12 @@ **(73) 🔴 RESTART CLI để spawn-probe 3 vai STYLE** — chốt-chặn DUY NHẤT còn lại của đội STYLE. Registry = ảnh-chụp lúc khởi phiên, **KHÔNG hot-reload**; `ls` + grep `VALID_ROLES` chỉ là điều-kiện **CẦN**. Anh đã "OK" @S179 nhưng **chưa restart** ⇒ 3 vai vẫn `file-land`, chưa chạy lần nào. Bằng-chứng còn nợ: cửa-sổ S179 có **8 file `fe-*/src/**`** đúng địa-phận FE-style mà **0 con được gọi** (đã ghi `SKIP-CO-KHAI`, không im lặng). **(74) `ROTATE` mật-khẩu prod `vrapp`** — việc anh, treo từ S153, chưa có mốc. + +**(22) 🔺 RE-SURFACE @S185 — 2 cột thẩm-quyền `{owner-SỐ · owner-LUẬT}` của bảng eval-của-eval.** 🔴 **GIỮ NGUYÊN SỐ (22), CẤM cấp số mới** — dãy slot là MỘT chuỗi liên tục (1)…(75); mint (76) cho **cùng một câu** = đẻ 2 số cho 1 việc, đúng lớp lỗi *slot-index tái-dụng*. Đây **không** phải câu mới, là câu **đã lên bề mặt @S150 rồi RƠI**. +> **Nhà THẬT (locate xong @S185 — invest báo "0 hit ở `error-ledger`" là đúng, nhà nằm chỗ khác):** [`runs/2026-07-25-S149-adap-backlog/sub-apply-L5-evalcuaeval.md`](../.claude/workflows/runs/2026-07-25-S149-adap-backlog/sub-apply-L5-evalcuaeval.md) — `:37` luật (*"🔒 2 cột thẩm-quyền ĐỂ TRỐNG — owner điền"*) · `:41` header bảng **A** (7 thước độc-lập A1-A7) · `:59` header bảng **B** (11 check trong `governance-detectors.ps1`, B1-B11) · `:115` ô owner-LUẬT cụ-thể của **B11**. Lệnh: `rg -n "owner-LUẬT" .claude/workflows/runs/2026-07-25-S149-adap-backlog/` → **3 hit**. Con-trỏ phụ: `adap-reports/2026-07-21-…eval-cua-eval.md:14` (*"verified-pending (owner) — ĐỂ TRỐNG có chủ-đích"*). +> **Vì sao AI không tự điền:** thư hub 07-21 `:24` **verbatim** — *"…phân loại thẩm quyền {AI-tự-sửa · chủ-dự-án-quyết-**SỐ** (ngưỡng, target) · chủ-dự-án-quyết-**LUẬT** (bỏ check, đổi cơ chế, thêm gate)} — **AI không tự quyết hai cột sau**."* +> **Ô cụ-thể đang chờ anh (mẫu, không phải toàn bộ 18 dòng):** 🔒 **owner-LUẬT @B11** — vá H24-2 (chuyển 3 cờ `gap-carry-aged` sang INFORM) sẽ hạ TOTAL **46 → 43**, mà đó là **RỜI TẬP-ĐO** *(trông y hệt tiến-bộ mà không sửa gì thật)* ⇒ anh chốt: **ratify baseline mới 43**, hay **giữ 46 và chỉ đổi nhãn**? · 🔒 **owner-SỐ** — các ngưỡng/target đi kèm 4 thước verdict **SỬA** (A1 · A5 · B2 · B11). +> 🔴 **Khai kèm — carry của chính slot này ĐÃ RƠI:** `[carry:eval-thamquyen]` có ở khối carry **S150-S152**, nhưng **0 hit** trong khối RE-STAMP @S181 (`:9`) lẫn `Carry @S179` (`:78`/`:80`). Lệnh: `grep -c "carry:eval-thamquyen" docs/HANDOFF.md` → **1** (chỉ segment cũ `:241`); control-dương `carry:ctx-t9-dogfood` = **6**. ⇒ thêm **1 ca `gap-carry-dropped` chưa được đếm** — đúng cái `:8` tự tuyên *"nghi-thức này không có răng"*. **Carry nay carry lại cùng lượt** (xem khối RE-STAMP). Ràng thứ-tự: slot này là **tiền-đề của W-4** (điền bảng + duyệt 2 đề-xuất ngược hub) — chưa locate thì anh không có chỗ mà điền. **~~(75) `hmw_width.cap`~~ ✅ ĐÓNG @S181** — anh nói dứt khoát *"nâng cap"* ở câu **P4** ⇒ lead thi hành THẬT: cap **20→30** đủ **2 mirror** (`memory-budget.json` + `hmw.js WIDTH_CAP`). Roster nay **28** ≤ 30 ⇒ **hết LOUD-skip**. 🧊 **Giữ vết vì đây là bài học:** @S179 anh trả *"OK"* và lead **tự thu-hẹp** thành *"ghi-nhận, CHƯA phải lệnh đổi số"* ⇒ giữ 20 — đó chính là ca `lead-gap-auditor` FLAG-4 bắt (*"Diễn-giải của lead, không phải chữ của anh"*). Lần này không tự thu-hẹp. ### 🔵 NEXT em @S179 (em tự làm, không cần anh gật) diff --git a/docs/STATUS.md b/docs/STATUS.md index bef080f..db17ca2 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -3,7 +3,7 @@ > **Update rule:** trước khi bắt đầu 1 task → ghi row `🔥 In Progress`. Xong → `✅ Recently Done`. > **Tiering rule (S40):** chỉ giữ **state hiện tại + 3 session gần nhất** ở file này. Session cũ hơn → `docs/changelog/sessions/`. Full history pre-S40 → `docs/_archive/STATUS-preS40-fullhistory.md`. (Tránh over-context — xóa double, không cắt nội dung.) -> 🔴 **@S179: mốc SỐNG hiện tại = S179, phiên-LOGIC L11, window 7** — chuỗi UAT màn KHKK 8 đợt ship (cửa-sổ 5: `530af22`→`ca9208f` 6 đợt + **Mig 72**; cửa-sổ 6: đợt-7 `99370de` + đợt-8 `65f73a9`, bundle prod `CuWgMI7J`·`32bJmjpM`), rồi S179 vá đội STYLE (SỬA-1→6b) + H24 light-audit. **Dòng CURRENT ngay dưới đây advance @closeout nên tụt sau — giữa phiên đọc `.claude/WAL.md`.** +> 🔴 **@S185: mốc SỐNG hiện tại = S185, phiên-LOGIC L13, window 4** (2026-08-10) — YC-013 KHKK 8-panel + YC-016 guard tay-cầm-phiếu SHIP+verify prod · YC-017 pipeline email/adap trọn · YC-018 ONE-SHOT bookend land · bookend @close MỘT MẠCH 9 vai (chi tiết `docs/HANDOFF.md` segment mới + `runs/2026-08-09-S185-bookend-close/`). 🧊 mốc cũ S179/L11/window-7 (chuỗi UAT KHKK 8 đợt + đội STYLE) → xem segment Recently-Done. **Dòng CURRENT ngay dưới đây advance @closeout nên tụt sau — giữa phiên đọc `.claude/WAL.md`.** **🔥 CURRENT (S161→S168, 2026-07-31→08-01 — phiên-LOGIC **L9**: chuỗi SP-002 B0→B4 **TRỌN 8/8 wave**: K1→K7 SHIP (cicd 6/6 · 5/6-khỏe · 6/6 · 7/7 · 5/5 · K6 #440 5/5 · K7 PARTIAL-live-sạch · F-1 `7a903cf` · K7 bridge `aaed699` PWF-10) + **@S168 owner chốt (63)(b)=D+"mở rộng": GĐ3-D SHIP `081557b` (3 trang Panel-3, gate PWF-10/0-blocker) + K8-BLOCKER Lines-editor phát-hiện-bởi-dry-run + vá + SHIP `0bfadc2` (gate PWF-8/0-blocker) — cicd #444 PASS 6/6 — rồi **K8 DRY-RUN PASS TOÀN TRÌNH 2 NHÁNH** (PE A/052 finalize-CCM + A/053 full-CEO → KHKK/2026/001+002 qua endpoint-line-MỚI → bridge-K7 → HĐ ĐẦU TIÊN prod `ZZTEST-K8/NCC/SOL&ZZTEST-NCC-K8/01` DaPhatHanh → bản-cứng hasSealedCopy=True → QĐ9 4/4 vế [nguồn-khoá-409 + catalog-rename-không-lan] — sổ ID + seq-cháy: `sub-k8-dryrun.md` B15, 🔴 KHKK/2026 seq **001-002-003 ĐỀU là phiếu test** [001-002 dry-run + **003 bộ fx3**] ⇒ **phiếu THẬT đầu tiên = 004** — số cũ "003" ở dòng này SAI, vá @close S168 sau khi `lead-gap-auditor` F-2 bắt + lead đo prod xác nhận `sqlcmd` 3 phiếu đều phase=3)**; closeout-nợ TRẢ @S168 — mạch sống ở `.claude/WAL.md`; lineage L8 giữ dưới):** Mig **71** (K1 Mig70 `AddContractCatalogEntries` danh mục 86 dòng + K2 Mig71 `AddKhkkApprovalGroupCatalogAndFinalizeRuntime` — phiếu KHKK +nhóm duyệt N1-N8 backfill=1 + Line +hạng-mục + unique 3-cột) · **97 bảng** · **644 test PASS** (45D+599I — CI #444 KHỚP local; +5 Fact Lines-editor @S168; lineage 639 sau-K7 → 622 @S167 KHỚP CI #439 tách-phần) · gotcha **87** · counter **46** (tick S172; H24 light **2/6** deep **6/15** ok — `light_at=44` · `deep_at=40`; ⚠️ *cặp `light 2/6` trùng số với đợt S168 do tình cờ 42−40 = 46−44, chỉ vế `deep` mới lộ 2/15→6/15 — đừng liếc vế light rồi tưởng ô còn tươi*) · roster 28 · **MenuItems prod 142 GIỮ** (key `KeHoachKyKet` sinh **policy** không sinh menu-row — H1 bác nghi-vấn stale) · Policies **452** · Menu keys **113** (@S166 K4a +49 `Khkk_G*` bộ-sinh — canonical bảng `:470-471`, test T2 khoá drift; lineage 64/256 @K3: +`ContractCatalog` K1 [4 policy chưa endpoint tiêu thụ — khai #82] · +8 `AwV2_KhkkN1..N8`) · bundle prod → **canonical ở `:479`, KHÔNG chép số ở đây** (B1). 🔴 *Cặp `DXoYDy7R`/`o8KDluD1` từng ghi ở dòng này **chưa bao giờ là trạng-thái cuối** — `e5123ff` ship thêm 6 file FE-src SAU snapshot; đo live @S164: admin `B43R6Y17` · user `NLI5umBg`.* Contracts prod **0**. ① **5 wave KHKK SHIP (window-3, S161):** W1 `a8027c0` (Mig 69, 7 bảng, 89→96) · W2 `6cbc6ad` (CRUD+Dossier 15 policy) · W3 `df52fa0` (duyệt V2 3-trạm, test-before RED→GREEN) · W6 `761d818` (đường-ống HĐ V2) · W7 `3119cb9` (bản-cứng **1-MỐC** theo owner: form điền đủ → duyệt nếu có → upload bản cứng = xong). Mỗi wave: gate 5-anchor → hmw → test → reviewer → F-0 → cicd 3-chân. 3 quyết owner: mã `KHKK/{YYYY}/{Seq:D3}` · **bỏ "MB"** · GĐ4 1-mốc. @@ -471,7 +471,7 @@ monthly re-tier mega-line + ef-core SKILL Mig→59 + 3 vocab-fork (2026-07-01 du | FE pages | **68** | unchanged S54 (ItTicketsPage reassign = in-place 2 app); +1 S52 AttendanceReportPage | | Policies | **452** | 🔄 **452 @S166 K4a** = All 113 × 4 (máy khoá: test T2 `KhkkGroupMenuSeedTests` đỏ nếu drift; DELTA vá-2: +4 ContractCatalog K1 · +32 AwV2_KhkkN* K3 · +196 Khkk_G* K4a). Cũ: **220 @S161** (W1 KHKK: `All` +`KeHoachKyKet` ⇒ 55 × 4 — reviewer F-2 bắt cặp-row-đôi đúng luật dòng dưới) · 🆕 **row MỚI S121** (wave adap-6-broadcast W2 — H24 GAP-3: `governance-detectors.ps1` `Get-StatusValue` resolve canonical TỪ bảng này; **KHÔNG có row ⇒ token `policy` UNRESOLVED ⇒ nửa `policy` của GAP-3 không thể fire** ⇒ detector khai FAIL-LOUD + SKIP, KHÔNG im-lặng-giả-vờ-xanh). 🔴 **DERIVED, KHÔNG độc-lập:** `Policies = |MenuKeys.All| × |MenuKeys.Actions| = 55 × 4 = 220 (@S161; trước W1 = 54 × 4 = 216)` — sinh runtime ở `src/Backend/SolutionErp.Api/Program.cs:82-89` (`foreach menu → foreach action → opts.AddPolicy($"{menu}.{action}")`), `Actions = ["Read","Create","Update","Delete"]` (`MenuKeys.cs:167`). ⇒ **row này BUỘC đổi CÙNG row `Menu keys`**: thêm 1 menu key ⇒ 55 × 4 = 220; sửa `Menu keys` mà quên `Policies` ⇒ detector flag derived-doc thay vì flag chính chỗ sai. Ground S121 bằng đếm mã-nguồn (`MenuKeys.All` = 54 entry, `public const string` = 54, khớp) — KHÔNG chép số từ spec. ⚠️ `.claude/skills/permission-matrix/SKILL.md` ghi **~240 = STALE** ⇒ W4 vá (🔴 chuỗi H24 §2(4) BẮT BUỘC: detector fire → cổng chứng-kiến → RỒI MỚI vá; vá trước = giết chứng-nhân sống) | | Menu keys | **113** | 🔄 **113 @S166 K4a** (đo RUNTIME `MenuKeys.All` — test T2; +49 `Khkk_G{2-8}`+42-leaf bộ-sinh by-construction K4a · +8 `AwV2_KhkkN1..N8` K3 · +1 `ContractCatalog` K1 trên nền 55). Cũ: **+1 S161 `KeHoachKyKet` vào `All` (W1 KHKK — policy `KeHoachKyKet.*` sinh runtime; menu-row prod KHÔNG đổi, 142 giữ)** · +1 S69 `Off_Dashboard` (landing Văn phòng số). Prev re-ground S61 (`MenuKeys.cs` const — Mig 50 gỡ 4 `Bg_*` Budget menu cũ). Prev 57 (S58) | -| Tests | **645 PASS** | **45 Domain + 600 Infra** · 🔄 **645 @S179 — ĐO BẰNG CÁCH CHẠY THẬT** `dotnet test SolutionErp.slnx`: Domain `Failed: 0, Passed: 45` · Infra `Failed: 0, Passed: 600` (0 skip). 🔴 Không lấy số từ doc: `lead-stale-auditor` FLAG-4 bắt ô này còn **644**, mà 644 đang là **THƯỚC** cho 6 flag derived-stale của detector ⇒ canonical sai thì máy khuyên vá về số sai (class canonical-poison S148/S166). 🔸 Breakdown cũ ghi "599 Infra" cũng lệch — **600**. 🧊 **644 @S168 #444** (+5 Fact Lines-editor) · 🧊 **639 @S168-sáng** (đo tươi local 45D+594I sau K7 Δ+17; chuỗi K lineage: 597 K1 → 614 K3 → 622 K4c @S167 KHỚP CI #439 tách-phần → **639** K7 — gate `639=45+594` KHỚP cicd-K7 dòng-1) · 🧊 **+28 @S161** (5 wave KHKK: W1 566 → W2 574 → W3 580 → W6 587 → W7 590; đo tươi @S162 `dotnet test` 45+545, gate CI Run #432 khớp). ~~45 Domain + 517 Infra~~ · 0 fail / 0 skip · **S155 +30** (PE xóa-by-approver: `PeDeleteByApproverTests.cs` + T26/T27 — 🔴 **T27 khoá CẢ LỚP lỗi** *entity-có-cờ-mà-DTO-không-có* bằng reflection [mọi cờ `Allow*` trên entity phải có mặt trên DTO], **fault-inject xác nhận có răng**: tiêm bug ⇒ ĐỎ, khôi phục ⇒ xanh — không phải guard tuyên-bố suông; T26 giữ ĐỎ có chủ ý vì bug production thật, lead vá bằng đảo thứ tự chứ KHÔNG nới assert. Số 562 cross-check 2 nguồn độc-lập: log CI run #417 + `dotnet test` local @S156) · **S147 +4** (`ProjectCodeNormalizationTests` — Trim khi lưu + kiểm-trùng bỏ-dấu-cách; 🔴 **ô canonical này STALE 528/483I suốt S147→S148**, header `:6` và session-log S147 đều ghi 532/487I từ đầu — closeout S147 vá header mà quên ô canonical; H24 `lead-view-auditor` bắt @S148, lead verify 3-nguồn rồi vá) · **S134 +8** (`PePendingAccumulationTests` C1-C8 lũy-kế-TẠM-TÍNH: C1 ChoDuyet+winner vào delta-selected + PriorPes · C2 TuChoi/DaDuyet loại sạch · C3 Nháp list-only KHÔNG cộng tiền [D1] + TraLai vào delta-submitted [D2] · C4 peer-window CreatedAt · C5 delta âm signed · **C6 complementary-no-double-count exact-numbers [ComputeAsync bất động khi thêm peer non-terminal]** · C7 frozen→pending 0/null · C8 D4 changelog `[S134 pending-prior]` positive+contrast) · **S133 +11** (`PeBudgetFreezeTests` freeze-NS-at-DaDuyet: **T0 repro test-before RED→GREEN** [phiếu DaDuyet phải giữ số cũ sau `UpdatePeBudgetPro` — RED bắt 999tr @:184 pre-fix, phiếu đưa tới DaDuyet QUA service finalize mirror `PeApproverFinalizeTests` KHÔNG seed thẳng Phase] + **T1-T9** spec-coverage [snapshot các nhánh finalize + display-gate + 2 terminal-guard chặn sửa NS phiếu đã kết thúc (cả Admin) + backfill] + **site-5 AdminOverride** [reviewer catch — override thẳng → DaDuyet cũng chốt snapshot]) · **S118 +8** (PRO-perm scope-isolation **+4** `ProcurementMasterAccessSeedTests` [reflection no-prod-touch: upgrade-path Suppliers R+C+U + Master-Read · **scope-isolation** DeptManager-riêng vẫn revoke=false · insert-path no-Delete · idempotent] · ReportsController authz **+4** `AuthorizePolicyRegressionTests` [dashboard/export require Reports.Read · my-dashboard KHÔNG action-policy · class-level [Authorize] intact]) · **S117 +6** (PE endsBeforeCeo pointer-aware **+1** `PeFinalizeProjectionTests.ListPe_EndsBeforeCeo_ChoDuyet_PointerAware_PastFinalizeIsFalse` [ChoDuyet con-trỏ QUA cấp finalize → endsBeforeCeo=false, test-before RED→GREEN + EF-subquery translate smoke] · duyệt-theo-khoảng ProMinMax **+5** `PeApprovedPriceFinalizeTests` [happy set Min+Max · min==max boundary lock strict-`>` · thiếu-Max→Conflict not-finalized · min>max→Conflict · single-source+Max→Conflict wire-bug + regression Max=null] · harness `InvokeApply` 4→5 args fix TargetParameterCountException) · **S116 +9** (PE nhập giá âm: T1 ngân-sách-bất-biến khi quote-âm · T2 winnerQuoteTotal signed-sum · T3 submit-guard all-zero-blocked/pure-neg+net-zero-submittable · T4 CCM-net-threshold) · **S114 +9** (PE multi-NCC per hạng mục: `PeSelectWinnerClearTests` delete-invariant +4 [DeleteQuote/DeleteDetail re-derive IsWinner **test-before RED→GREEN** + guard-no-over-clear + UpsertQuote-update-branch coverage] + impl-lane +5 [per-hạng-mục-total · giaTri-single-partial · threshold-crossing · derive-invariant]) · **S113 +19** (Supplier import v2: `SupplierImportV2DedupTests` 13 [dedup MST-primary+Code-backstop T1-T7 · draft-on-import IsPublic · all-or-nothing · LayoutValid re-bake real-token · **null-Code→nháp FIXED** flipped-from-characterization] + `SupplierPublishAndListTests` 6 [publish-guard Code-required→409 · unpublish · list-filter published · DTO IsPublic]) · **S112 +18** (Supplier `SupplierExcelImportServiceTests` +10 [case-collation dedup có-RĂNG SQLite-BINARY-collation-nên-chứng-dedup-ở-SERVICE · fill-nulls-safe · all-or-nothing-abort · parser abs-cell-index/#REF!-null/header-fingerprint · Type-lạ→NCC · Status-emoji-strip] · PE `PeSubmitGuardAndBypassTests` 4-update→A1 [minOwn subordinate-only, pointer-stop] + 8-new [A1-happy · non-contiguous · EDGE-5 non-admin-throw/admin-pass/system-pass · opinion-history log/none]) · Prev 440: **S96 +6** (PE `PeApproverFinalizeTests` +2 [#6 finalize-opt-out→advance-CEO · #7 stale-noti-clear ExecuteUpdate] · `PeSuggestedPriceSetterAuthzTests` +4 [price-lock phase-guard after-submit — PRO/CCM ChoDuyet/DaDuyet→Conflict, Admin-override; +sửa SeedPeAsync default ChoDuyet→DangSoanThao spec-change]) · **S92 +3** (`AdminOnlyModulesRevokeTests` ẩn 5 nhóm menu chỉ Admin — non-Admin revoked-4-cờ / Admin untouched / Pe_* preserved) · **S91 +9** (ChangePassword self-service BE+test) · **S89 +3** (`PeDraftVisibilityTests` IDOR nháp riêng-tư) · **S88 +17** (D1 financials/CEO-notify/HoSoLink null-safe +11 · D2 create-contract multi-winner +6) · **S87 +25** (Mig 58 net +18: `PeMultiWinnerTests` sum + `PeSelectWinnerClearTests` multi-update + `PeSubmitGuardAndBypass` budget=0 + `PeApproverFinalizeTests` 5 auto-finalize [từng 7, −2 khi opt-in→auto rework] + `PeCcmThresholdFinalize`/`PeWorkItemBudget` collateral; Mig 59 +7 `PeCcmBudgetPeriodSetterAuthzTests` role-gate Admin|CCM/budget=0/null-clear) · **S86 +3** (`PeApproverNotifyExcludesDrafterTests` — notify "cần duyệt" loại NGƯỜI TẠO phiếu: drafter-excluded · co-approver-vẫn-nhận · drafter-vẫn-nhận-chuông-kết-quả) · **S85 +18** (PE CV PRO C5 hủy/đổi NCC winner +10 · urgent drafter-self-unset +5 · workflow-preserve bug-class S42 +3 `PeUpdateDraftWorkflowPreserveTests`) · **S83 +2** (PE require-workflow: `PeWorkItemGuardTests` ApprovalWorkflowId `NotEmpty` ×2 validator + submit-guard rewrite test 7/13 `PeSubmitGuardAndBypass` V1-submit-deprecated, no-count-change) · **S77 +10** (+7 `PeSuggestedPriceSetterAuthzTests` ghi chú PRO/CCM Mig 57 absolute-set/role-gate/null-clear/max-1000 · +3 `PeUrgentToggleAuthzTests` rewrite cờ-gấp **BẤT ĐỐI XỨNG** SET=function role / UNSET=function+DeptManager, plain-PRO-unset Forbidden) · **S76 +5** (`PeWorkItemBudgetTests` PRO split: set ProInitial+ProAdjust gồm âm · validator ProInitial≥0/ProAdjust-cho-âm · full=proFull khi CCM empty · full=CCM khi CCM present) · **S74 +5** (`PeWorkItemBudgetTests` §4b CcmNote: set CCM/Admin · null-clear absolute-set · non-priv Forbidden+no-mutate · all-3-persist) · **S73 +28** (PE opt-in finalize spec 6→11 + 10 giá-chốt `PeApprovedPriceFinalizeTests` + 13 setter-authz `PeSuggestedPriceSetterAuthzTests`) · **S69 +20** (Office-golive OfficeModulePermissionSeed 6 + PE PeCcmThresholdFinalize 5 + PeUrgentToggleAuthz 9) · **S67 +23 HRM test-after** (DepartmentTreeTests 8 cycle-guard/rollup + PeHoSoLinkTests 9 absolute-set + HrmProfilePermissionSeedTests 6 reflection-seed) → 286 · S61 +22 `PeWorkItemBudgetTests` −14 `BudgetPolicyTests` −1 → 263 · S60 +14 `PeSubmitGuardAndBypassTests` +2 spec → 256 (Domain 58→45 do drop Budget module tests) | +| Tests | **668 PASS** | **45 Domain + 623 Infra** · 🔄 **668 @S185 — ĐO BẰNG CÁCH CHẠY THẬT ×2 nguồn độc-lập** (`dotnet test SolutionErp.slnx` @/tiep-verify + `ring2-audit` tự chạy đối-chứng cùng ngày): Domain 45 · Infra 623 · 0 fail 0 skip. Lineage: +15 KHKK-mirror @S182 (14 spec + T15) + +8 `UploadDuyet_*/UploadCanCu_*` YC-016 @S183. 🧊 **645 @S179** (45D+600I — ô này từng kẹt 645 tới S185 trong khi suite đã 668: stale-F3 canonical-poison, máy lấy ô này làm thước in 6 flag khuyên vá về số SAI — vá @S185). 🔴 Không lấy số từ doc: `lead-stale-auditor` FLAG-4 bắt ô này còn **644**, mà 644 đang là **THƯỚC** cho 6 flag derived-stale của detector ⇒ canonical sai thì máy khuyên vá về số sai (class canonical-poison S148/S166). 🔸 Breakdown cũ ghi "599 Infra" cũng lệch — **600**. 🧊 **644 @S168 #444** (+5 Fact Lines-editor) · 🧊 **639 @S168-sáng** (đo tươi local 45D+594I sau K7 Δ+17; chuỗi K lineage: 597 K1 → 614 K3 → 622 K4c @S167 KHỚP CI #439 tách-phần → **639** K7 — gate `639=45+594` KHỚP cicd-K7 dòng-1) · 🧊 **+28 @S161** (5 wave KHKK: W1 566 → W2 574 → W3 580 → W6 587 → W7 590; đo tươi @S162 `dotnet test` 45+545, gate CI Run #432 khớp). ~~45 Domain + 517 Infra~~ · 0 fail / 0 skip · **S155 +30** (PE xóa-by-approver: `PeDeleteByApproverTests.cs` + T26/T27 — 🔴 **T27 khoá CẢ LỚP lỗi** *entity-có-cờ-mà-DTO-không-có* bằng reflection [mọi cờ `Allow*` trên entity phải có mặt trên DTO], **fault-inject xác nhận có răng**: tiêm bug ⇒ ĐỎ, khôi phục ⇒ xanh — không phải guard tuyên-bố suông; T26 giữ ĐỎ có chủ ý vì bug production thật, lead vá bằng đảo thứ tự chứ KHÔNG nới assert. Số 562 cross-check 2 nguồn độc-lập: log CI run #417 + `dotnet test` local @S156) · **S147 +4** (`ProjectCodeNormalizationTests` — Trim khi lưu + kiểm-trùng bỏ-dấu-cách; 🔴 **ô canonical này STALE 528/483I suốt S147→S148**, header `:6` và session-log S147 đều ghi 532/487I từ đầu — closeout S147 vá header mà quên ô canonical; H24 `lead-view-auditor` bắt @S148, lead verify 3-nguồn rồi vá) · **S134 +8** (`PePendingAccumulationTests` C1-C8 lũy-kế-TẠM-TÍNH: C1 ChoDuyet+winner vào delta-selected + PriorPes · C2 TuChoi/DaDuyet loại sạch · C3 Nháp list-only KHÔNG cộng tiền [D1] + TraLai vào delta-submitted [D2] · C4 peer-window CreatedAt · C5 delta âm signed · **C6 complementary-no-double-count exact-numbers [ComputeAsync bất động khi thêm peer non-terminal]** · C7 frozen→pending 0/null · C8 D4 changelog `[S134 pending-prior]` positive+contrast) · **S133 +11** (`PeBudgetFreezeTests` freeze-NS-at-DaDuyet: **T0 repro test-before RED→GREEN** [phiếu DaDuyet phải giữ số cũ sau `UpdatePeBudgetPro` — RED bắt 999tr @:184 pre-fix, phiếu đưa tới DaDuyet QUA service finalize mirror `PeApproverFinalizeTests` KHÔNG seed thẳng Phase] + **T1-T9** spec-coverage [snapshot các nhánh finalize + display-gate + 2 terminal-guard chặn sửa NS phiếu đã kết thúc (cả Admin) + backfill] + **site-5 AdminOverride** [reviewer catch — override thẳng → DaDuyet cũng chốt snapshot]) · **S118 +8** (PRO-perm scope-isolation **+4** `ProcurementMasterAccessSeedTests` [reflection no-prod-touch: upgrade-path Suppliers R+C+U + Master-Read · **scope-isolation** DeptManager-riêng vẫn revoke=false · insert-path no-Delete · idempotent] · ReportsController authz **+4** `AuthorizePolicyRegressionTests` [dashboard/export require Reports.Read · my-dashboard KHÔNG action-policy · class-level [Authorize] intact]) · **S117 +6** (PE endsBeforeCeo pointer-aware **+1** `PeFinalizeProjectionTests.ListPe_EndsBeforeCeo_ChoDuyet_PointerAware_PastFinalizeIsFalse` [ChoDuyet con-trỏ QUA cấp finalize → endsBeforeCeo=false, test-before RED→GREEN + EF-subquery translate smoke] · duyệt-theo-khoảng ProMinMax **+5** `PeApprovedPriceFinalizeTests` [happy set Min+Max · min==max boundary lock strict-`>` · thiếu-Max→Conflict not-finalized · min>max→Conflict · single-source+Max→Conflict wire-bug + regression Max=null] · harness `InvokeApply` 4→5 args fix TargetParameterCountException) · **S116 +9** (PE nhập giá âm: T1 ngân-sách-bất-biến khi quote-âm · T2 winnerQuoteTotal signed-sum · T3 submit-guard all-zero-blocked/pure-neg+net-zero-submittable · T4 CCM-net-threshold) · **S114 +9** (PE multi-NCC per hạng mục: `PeSelectWinnerClearTests` delete-invariant +4 [DeleteQuote/DeleteDetail re-derive IsWinner **test-before RED→GREEN** + guard-no-over-clear + UpsertQuote-update-branch coverage] + impl-lane +5 [per-hạng-mục-total · giaTri-single-partial · threshold-crossing · derive-invariant]) · **S113 +19** (Supplier import v2: `SupplierImportV2DedupTests` 13 [dedup MST-primary+Code-backstop T1-T7 · draft-on-import IsPublic · all-or-nothing · LayoutValid re-bake real-token · **null-Code→nháp FIXED** flipped-from-characterization] + `SupplierPublishAndListTests` 6 [publish-guard Code-required→409 · unpublish · list-filter published · DTO IsPublic]) · **S112 +18** (Supplier `SupplierExcelImportServiceTests` +10 [case-collation dedup có-RĂNG SQLite-BINARY-collation-nên-chứng-dedup-ở-SERVICE · fill-nulls-safe · all-or-nothing-abort · parser abs-cell-index/#REF!-null/header-fingerprint · Type-lạ→NCC · Status-emoji-strip] · PE `PeSubmitGuardAndBypassTests` 4-update→A1 [minOwn subordinate-only, pointer-stop] + 8-new [A1-happy · non-contiguous · EDGE-5 non-admin-throw/admin-pass/system-pass · opinion-history log/none]) · Prev 440: **S96 +6** (PE `PeApproverFinalizeTests` +2 [#6 finalize-opt-out→advance-CEO · #7 stale-noti-clear ExecuteUpdate] · `PeSuggestedPriceSetterAuthzTests` +4 [price-lock phase-guard after-submit — PRO/CCM ChoDuyet/DaDuyet→Conflict, Admin-override; +sửa SeedPeAsync default ChoDuyet→DangSoanThao spec-change]) · **S92 +3** (`AdminOnlyModulesRevokeTests` ẩn 5 nhóm menu chỉ Admin — non-Admin revoked-4-cờ / Admin untouched / Pe_* preserved) · **S91 +9** (ChangePassword self-service BE+test) · **S89 +3** (`PeDraftVisibilityTests` IDOR nháp riêng-tư) · **S88 +17** (D1 financials/CEO-notify/HoSoLink null-safe +11 · D2 create-contract multi-winner +6) · **S87 +25** (Mig 58 net +18: `PeMultiWinnerTests` sum + `PeSelectWinnerClearTests` multi-update + `PeSubmitGuardAndBypass` budget=0 + `PeApproverFinalizeTests` 5 auto-finalize [từng 7, −2 khi opt-in→auto rework] + `PeCcmThresholdFinalize`/`PeWorkItemBudget` collateral; Mig 59 +7 `PeCcmBudgetPeriodSetterAuthzTests` role-gate Admin|CCM/budget=0/null-clear) · **S86 +3** (`PeApproverNotifyExcludesDrafterTests` — notify "cần duyệt" loại NGƯỜI TẠO phiếu: drafter-excluded · co-approver-vẫn-nhận · drafter-vẫn-nhận-chuông-kết-quả) · **S85 +18** (PE CV PRO C5 hủy/đổi NCC winner +10 · urgent drafter-self-unset +5 · workflow-preserve bug-class S42 +3 `PeUpdateDraftWorkflowPreserveTests`) · **S83 +2** (PE require-workflow: `PeWorkItemGuardTests` ApprovalWorkflowId `NotEmpty` ×2 validator + submit-guard rewrite test 7/13 `PeSubmitGuardAndBypass` V1-submit-deprecated, no-count-change) · **S77 +10** (+7 `PeSuggestedPriceSetterAuthzTests` ghi chú PRO/CCM Mig 57 absolute-set/role-gate/null-clear/max-1000 · +3 `PeUrgentToggleAuthzTests` rewrite cờ-gấp **BẤT ĐỐI XỨNG** SET=function role / UNSET=function+DeptManager, plain-PRO-unset Forbidden) · **S76 +5** (`PeWorkItemBudgetTests` PRO split: set ProInitial+ProAdjust gồm âm · validator ProInitial≥0/ProAdjust-cho-âm · full=proFull khi CCM empty · full=CCM khi CCM present) · **S74 +5** (`PeWorkItemBudgetTests` §4b CcmNote: set CCM/Admin · null-clear absolute-set · non-priv Forbidden+no-mutate · all-3-persist) · **S73 +28** (PE opt-in finalize spec 6→11 + 10 giá-chốt `PeApprovedPriceFinalizeTests` + 13 setter-authz `PeSuggestedPriceSetterAuthzTests`) · **S69 +20** (Office-golive OfficeModulePermissionSeed 6 + PE PeCcmThresholdFinalize 5 + PeUrgentToggleAuthz 9) · **S67 +23 HRM test-after** (DepartmentTreeTests 8 cycle-guard/rollup + PeHoSoLinkTests 9 absolute-set + HrmProfilePermissionSeedTests 6 reflection-seed) → 286 · S61 +22 `PeWorkItemBudgetTests` −14 `BudgetPolicyTests` −1 → 263 · S60 +14 `PeSubmitGuardAndBypassTests` +2 spec → 256 (Domain 58→45 do drop Budget module tests) | | Gotchas | **87** | 🔄 **87 @S179 flush** — đo đĩa `docs/gotchas.md` max anchor = **87** (`lead-stale-auditor` FLAG-5 + máy HIGH `canonical-itself-stale`; #87 sinh ở S177 vá lệch 2 tầng). 🧊 **+S168 #86** (2-push-sát → Gitea auto-CANCEL run đầu cùng-branch: CANCELLED ≠ fail — verifier đọc run CUỐI của range + bằng-chứng artifact-level; side-effect @startup chỉ 1-startup cho cả cụm push; ca thật `aaed699` ship qua #442) · **+S162 #85** (menu-key OR-gate FE ≠ policy per-action BE: cây 4-folder GĐ gate `['Khkk_List','Khkk_G1','KeHoachKyKet'].some(can)` NHƯNG endpoint gắn `[Authorize(Policy="KeHoachKyKet.Read")]` [`ContractSigningPlansController.cs:36`] + `MenuPermissionHandler.cs:40` so khớp **CHÍNH XÁC 1 key** — KHÔNG kế-thừa cha, KHÔNG OR key con ⇒ role `Khkk_List=1 ∧ KeHoachKyKet=0`: FE mở cổng → API **403** → folder GĐ2 hiện "—" dưới **MỌI** gói thầu, claim "gate trước fetch ⇒ 0 rác 403" **vỡ**. Bẫy: luật "OR nhiều key" **ĐÚNG ở tầng HIỂN-THỊ** [`GetMyMenuTreeQuery.cs:61-96` trả node khi con `CanRead`] nhưng **SAI ở tầng API-authz** — mặt thứ 2 của #82, lần này **menu-hiện RỘNG hơn API-cho** [#82 là chiều ngược]. Fix = gate đúng key policy CỦA endpoint; **mở controller đọc attribute TRƯỚC khi wire gate**, đừng suy từ cây menu. Reviewer bắt **trước ship**; Dev 13/13 role đều `Contracts=1 ∧ KeHoachKyKet=1` nên **chưa lộ** — lớp "chưa vỡ vì dữ-liệu hiện tại may mắn", vá ngay không đợi triệu chứng). **+S159 #84** (revoker-2-chiều: sửa data tay trên prod bị code-path ungated @restart ĐẢO NGƯỢC im lặng — grant menu SQL tay bị revoker [S92] lật 447/494 row; fix = code-first seeder + gỡ nhánh + guard 2-vế + khuôn 3-chân-kiềng; liên-quan #75/#76 chiều seeder). **+S133 #81-EXT** (instance 2 indirect-assignment, KHÔNG số mới: snapshot-NS-at-DaDuyet hook đặt ở finalize choke-point NHƯNG 2 site gán Phase TRỰC TIẾP bypass — admin-override `PurchaseEvaluationWorkflowService.cs:308` `= targetPhase` + seeder `DbInitializer:1323` `= current` → phiếu vào DaDuyet qua 2 đường này KHÔNG snapshot [frozen=0, display rơi về live = đúng bug đang vá]; reviewer adversarial bắt pre-commit, em-main + 3 invocation implement đều sót — cùng bài enumeration-writer #81; meta: field-đích có hook/derive/snapshot ⇒ grep MỌI assignment-site kể cả override/seeder). +1 S126 (**#83** số AGGREGATE session-cumulative tự-lão-hoá — audit COUNTS đổi bởi CHÍNH spawn review sau đó [2/2/0→4/4/0]; outward mời-reproduce = bảng per-lane theo run-id, KHÔNG số tổng; reviewer-gate bắt, em-main-solo sót). +1 S118 (**#82** menu-flag grant ≠ quyền API thật: display-layer [Permission `CanRead`→`GetMyMenuTree` FE-menu] ⟂ API-authz-layer [controller `[Authorize(Policy=)]`] = 2 tầng ĐỘC-LẬP; grant `Suppliers` R+C+U cho PRO nhưng `PUT/DELETE /suppliers` gate `[Authorize(Roles="Admin,CatalogManager")]` → PRO vẫn 403 sửa/xóa NCC [chỉ Publish/Import theo `Suppliers.Update` là ăn]; ngược lại `ReportsController` `[Authorize]` trần → mọi authed-user đọc `dashboard` tài-chính-HĐ ngược S92; fix gate `[Authorize(Policy="Reports.Read")]` per-method + grep controller authz TRƯỚC khi tin hiệu-lực grant; reviewer adversarial bắt, em-main-solo tin menu-flag=quyền thì sót; liên-quan #44). +1 S114 (**#81** derived-invariant re-derive ở write/select NHƯNG SÓT DELETE writer [DeleteQuote/DeleteDetail cascade] → xóa quote-selected cuối của NCC → `Supplier.IsWinner` kẹt stale [Any(IsSelected)=false] → `CreateContract Where(IsWinner)` gom NCC phantom → **HĐ giaTri=0**; fix helper `PeWinnerInvariant.ReSyncAfterQuoteRemovalAsync` gọi sau SaveChanges 2 handler; **enumeration-writer-trong-spec KHÔNG đáng tin** → grep MỌI `.Remove(`/`.Add(`/`=field` chạm entity chứa field-nguồn; chỉ **verify-adversarial-refute** bắt [invest/review/implement đều sót]; cardinality S87/S88 lên tầng mutation-path). +1 S113 (**#80** null-forgiving `!` che NRE trên external-parsed data: `SupplierExcelImportService.NewSupplier` gán `Code = r.Code!.Trim()` → NullReferenceException khi parser trả `null` cho ô cột-4 rỗng [ĐÚNG path R4 "thiếu Mã NCC → nháp"] → confirm nổ 500 CẢ batch dù preview classify New-draft KHÔNG lỗi; sibling `IsPublic=!IsNullOrWhiteSpace(row.Code)` null-safe nhưng NewSupplier thì KHÔNG; empty-string `""` chạy OK nhưng FE round-trip blank→JSON `null` → nổ. Fix `(r.Code ?? "").Trim()`. **Build 0/0 KHÔNG bắt** [`!` tắt nullable-warning]; chỉ test-before-critical bắt. Lesson: `!` null-forgiving trên dữ-liệu-parse-ngoài = mìn, dùng `?? default`). +1 S97 (**#79** backfill soi NHẦM bảng — transition-marker "[Duyệt KẾT THÚC]" nằm ở `PurchaseEvaluationChangelogs.ContextNote` KHÔNG phải `PurchaseEvaluationApprovals` → Mig 60 backfill match 0, phiếu finalize-CCM giữ flag=0 hiện sai "Đã được CEO duyệt"; fix Mig 61 query đúng bảng. PE 2 bảng lịch-sử tách vai [Approvals=ai-duyệt record :745 · Changelogs=chuyển-phase+marker LogTransition :1073]; verify marker-count prod trước khi tin backfill). +1 S97 (**#78** display-flag suy CONFIG thay RUNTIME → nói dối khi instance lệch config: `endsBeforeCeo` từ "workflow CÓ cấp finalize" thay "phiếu NÀY finalize" → phiếu lên CEO báo sai "không qua CEO"; nặng sau S97 default-flip opt-in; fix field runtime `EndedByLevelFinalize` Mig 60. Flag = "instance ĐÃ làm-gì" KHÔNG "config CÓ THỂ"). +1 S96 (**#77** SPA deploy bundle cache-lag: team thấy UI CŨ dù đã deploy + Ctrl+F5 — index.html no-cache ĐÚNG-chuẩn + JS hash-immutable nhưng browser giữ tab-SPA-mở/cache-local → verify bundle prod **BYTE-LEVEL** (curl + grep string-fix trong `/assets/index-.js`) phân-biệt cache-vs-deploy; **incognito = golden-test**; no-service-worker nên clear-site-data đủ). +2 S91 (**#76** deploy render config từ `.example` KHÔNG phải file-gitignored → prod thiếu setting tới khi điền tay · **#75** seed ungated per-code RESURRECT data đã-wipe mỗi restart → gate sau env-flag `DemoSeed:Disabled` + verify-by-restart-thật). +1 S90 (**#74** Chrome-MCP screenshot kẹt SPA-SignalR `document_idle` → PowerShell `CopyFromScreen` + Win32 lọc-process-`chrome.exe`). +2 S85 (**#72** lệch giờ +7h — DateTime lưu UTC nhưng serialize thiếu 'Z' → FE `new Date()`=local → `UtcDateTimeJsonConverter` global ép UTC-with-Z · **#73** UpdateDraft absolute-set CLEAR field SÓT khỏi pattern null-safe = bug-class S42 → guard `if (request.X is not null)`). +1 S78 **#71** (thêm enum value vào entity DÙNG-CHUNG → pollute UI/guard phân-loại theo PROXY-predicate `supplierId===null` thay vì enum tường minh; file-khi-duyệt purpose=5 lẫn "Bảng so sánh" + false-pass submit-guard → grep mọi field-proxy predicate loại value mới + build-verify TỪNG app; em-main grep no-leak bắt trước deploy). +1 S76 **#70** (FE absolute-set echo field anh-em từ server-snapshot + `invalidate()` fire-and-forget → cửa-sổ stale-echo mất-dữ-liệu khi lưu 2 ô liên-tiếp; guard `useIsFetching` gate nút Lưu tới khi refetch land; reviewer workflow bắt, impl self-review sót). +1 S72 **#69** FE bundle-hash non-deterministic + `deploy.yml` rebuild-FE-unconditional → bundle rotate kể cả commit governance (SPA-fallback-200 trap; cicd Run #312). +2 S69: **#67** Tailwind v4 accent palette thiếu stop (teal/violet/amberx/greenx chỉ 50/100/500/600/700; dùng -300 → teal/violet rơi DEFAULT Tailwind sai-hệ, amberx/greenx drop hẳn — build PASS, phải soi dist CSS) · **#68** IDE TS diagnostic giữa background-agent/workflow = snapshot dở-dang (TS server bắn mỗi save), chỉ tin build SẠCH sau-cùng (2× session này: re-skin + PE-FE đều false-alarm). Prev +1 S68 **#66** Tailwind v4 rule element thô `h1-h4{color:#0b1220}` viết NGOÀI `@layer` thắng utility `text-white` → heading render đen; fix ĐIỂM `text-white!` (important, grep dist confirm), KHÔNG move `@layer` (load-bearing ~30+ heading toàn app). Prev +1 S65 **#65** build csproj con (vd `SolutionErp.Api.csproj`) ≠ `dotnet build SolutionErp.slnx` (gồm tests) → miss test-compile khi đổi chữ ký record command (CreateDepartmentCommand +ParentId) → CI CS7036 FAIL-gated Run #291 (deploy chặn, prod nguyên — test-gate làm đúng việc). Fix: build full slnx trước push BE signature-change. Prev +2 S61: **#63** EF scaffold tự sinh `RenameColumn` SAI-semantics khi drop+add cùng type (test xanh không bắt — SQLite EnsureCreated không replay migration) · **#64** `dotnet ef database update` áp Design-DB 0-rows ≠ Dev-DB → data-migrate `Sql()` chạy thật lần đầu trên prod. Prev +2 S59 (#61 sqlcmd `-f 65001` · #62 rename natural-key UPDATE trước deploy) | | User memory | **60** | 🔄 **re-ground S179** — đo lại ĐÚNG phương-pháp dòng này tự khai: `ls .claude/auto-memory/*.md | wc -l` = **61**, trừ 1 index `MEMORY.md` = **60** (`lead-stale-auditor` FLAG-9; máy MÙ trục này — không có cross-check). 🔴 Ô này trôi lại chỉ sau **9 nhãn phiên** kể từ lần re-ground trước ⇒ đây là ô **rụng nhanh**, đừng tin số cũ. 🧊 re-ground S170 — đếm đĩa 60 file trừ 1 index = 59 (số "31" stale từ S84; lead-stale FLAG @S169, ring2 verify, vá @S170 SAU khi ring chấm — đúng thứ-tự H24 §2(4) fire→chứng-kiến→vá). +S84 `feedback_derived_flush_execution` (derived→canonical flush = em-main execution KHÔNG gate user-confirm; monitor INFORM-only ≠ cần-anh-duyệt; chỉ ĐỔI-con-số/policy = quyền anh). +S79 `feedback_canonical_spec_over_broadcast` (adap pull canonical-command/§P đừng phỏng-theo broadcast + report-before-stamp dogfood + residual own-diary OK). +S75 `feedback_harness11_engine` (engine governance tự-bảo-trì + gotcha #30-via-Edit + multi-workflow-verify + git-add-specific lesson). re-ground S71 (H1 disk-count: 25 `feedback_*` + 3 `project_*`; STATUS "21" stale từ S64). +S71 `feedback_harness10_run_trace` (run-trace + 3 lesson). Prev +1 S64 `feedback_harness7_outward_writing_quality`; re-grounded S54 base 19 | | Skills | 6 | 3 domain + 3 ops | diff --git a/docs/governance/adap-reports/2026-07-17-Governance-master-checklist-hai-tang-moi-cua-phien.md b/docs/governance/adap-reports/2026-07-17-Governance-master-checklist-hai-tang-moi-cua-phien.md index 75a542d..3e0690f 100644 --- a/docs/governance/adap-reports/2026-07-17-Governance-master-checklist-hai-tang-moi-cua-phien.md +++ b/docs/governance/adap-reports/2026-07-17-Governance-master-checklist-hai-tang-moi-cua-phien.md @@ -25,3 +25,72 @@ - SELF-CHECK broadcast 4 ô: ô3 (chờ-owner đánh số, trả-lời-bằng-số xử được) = **PASS đã dùng thật** · ô4 (grep nguồn-đôi = KHÔNG) = **PASS 8=8** · ô1 (mở-phiên in 2-tầng khớp carry) + ô2 (mục cố-tình chưa xong tự xuất-hiện lại) = **PENDING** — cần 1 chu-kỳ đóng→mở phiên thật để chấm, chưa có dữ-liệu. - Vocab-nit (L3, LOW, chờ owner): nhãn "Luật-số sàn-5 (S138)" trùng token "sàn-5" với "Sàn-5 H22 hậu-kiểm CỜ" có trước trong cùng `session-end.md` — 2 hệ-sàn khác nhau; phân-biệt được nhờ emoji/prefix/tag; đề-xuất rename bản mới hoặc đăng-ký `vocab-alias-map.md` (KHÔNG seed detector, per bài S93). - Unpushed lúc ghi (push gộp @closeout S139). + +--- + +# ✅ ADDENDUM @S185 (2026-08-09) — chấm SELF-CHECK ô1/ô2 + sàn-2, sau 23 ngày + +> **Block MỚI, không sửa dòng cũ** (§5 caveat giữ nguyên làm vết — nó đúng lúc viết 17-07). Checklist item **C-18** của run `2026-08-09-S185-email-adap-pipeline`; ruột + lệnh: `.claude/workflows/runs/2026-08-09-S185-email-adap-pipeline/sub-opus-lane5-measure.md`. +> Lý do chấm bây giờ: caveat tự hẹn *"cần 1 chu-kỳ đóng→mở phiên thật"* — từ 17-07 tới nay đã qua **≥5 chu-kỳ** (session-13 có `_pause-1/2` · `_tiep-1/2/3` · `_snapshot-1/2`) và **29 commit** dạng closeout. Dữ-liệu ĐÃ CÓ. + +## Bảng chấm 4 ô SELF-CHECK + +| Ô | Nội dung | Nấc @S139 | **Nấc @S185** | Bằng-chứng | +|---|---|---|---|---| +| ô1 | mở phiên có in plan 2 tầng, tầng-1 khớp carry phiên trước? | PENDING | 🔶 **KHÔNG CHẤM ĐƯỢC — phép thử sai thiết-kế** | xem dưới | +| ô2 | mục cố-tình chưa xong có tự xuất-hiện lại? | PENDING | 🔴 **TRƯỢT — có số** | `HANDOFF` khối RE-STAMP | +| ô3 | khối chờ-owner có số, trả lời bằng số xử được? | PASS | ✅ **PASS (giữ)** | `HANDOFF` khối "CHỜ ANH — ĐÁNH SỐ" (73)(74)(75) + 4 câu P-số @S181 + `checklist-final.md` W-1…W-4 | +| ô4 | có file checklist nguồn-đôi mới không? | PASS 8=8 | ✅ **PASS về THỰC CHẤT · 🔶 phép đo cũ HẾT HẠN** | xem dưới | + +### 🔴 ô2 = TRƯỢT, và trượt cả sàn-4 (vòng carry khép kín) + +Ba bằng-chứng độc-lập, đều nằm sẵn trong `docs/HANDOFF.md`: +1. Khối **RE-STAMP CARRY @S181**: *"Bản trước rơi **4 kỳ liên tiếp**, `class_repeat.gap-carry-dropped` = **12** = 4× ngưỡng JUMP ⇒ nghi-thức này **không có răng**, không phải đãng trí."* — chính sổ tự kết luận. +2. Ngay dưới đó: *"**2 ca `gap-carry-dropped` này KHÔNG nằm trong tally 4-kỳ ở trên** — chúng rơi **im lặng** và chỉ lộ ra khi có người đi tìm nhà của một câu hỏi"* ⇒ con số 12 là **cận DƯỚI**. +3. Ca đích danh: `[carry:eval-thamquyen]` có mặt ở khối carry **S150-S152** nhưng **0 hit** trong khối RE-STAMP @S181 ⇒ **đúng kịch bản ô2**: mục chưa xong, đóng phiên, mở phiên sau **không** tự xuất hiện lại. + +⇒ Đây là **ca-âm vàng** mà ô2 hỏi. Không cần dựng thí-nghiệm mới: kho đã tự chạy thí-nghiệm đó 4 lần và trượt 4 lần. +🔸 Hệ quả nấc: sàn-4 của broadcast (*"vòng carry KHÉP KÍN … task rớt giữa hai phiên bị bắt thay vì dựa trí nhớ"*) — SE đạt phần **"có máy"** (H24-2 carry-age detector đo streak) nhưng **không đạt** phần **"bị BẮT"**: máy đếm được 12 mà nghi-thức vẫn rơi thêm 4 kỳ. Đúng phân biệt của chính kho: *"cổng kêu mà không đổi hành-vi = cổng không có răng"*. + +### 🔶 ô1 = phép thử neo vào thứ KHÔNG lưu lại được + +Thứ ô1 đòi chấm là **hành-vi in ra màn hình** ở cửa mở phiên. Vật chứng duy nhất của hành-vi đó nằm trong **transcript**, không nằm trên **đĩa** ⇒ 23 ngày sau **không ai chấm được**, kể cả khi nghi-thức đã chạy đủ 5 chu-kỳ. Đây không phải "chưa có dữ-liệu" (lý do cũ) mà là **phép thử tự nó không đo được bằng chứng-cứ bền**. + +Cái CHẤM ĐƯỢC bằng dữ-liệu sẵn (đề nghị thay thế): **hệ-quả durable của tầng-1**, tức *"artifact cửa-mở có chở trạng-thái carry của cửa-đóng trước không"*. Đo thử 1 điểm: `.claude/sessions/session-13/_context-s-13.md` **CÓ** chở (`:21` trỏ `HANDOFF` = *"brief 5 phút + bảng số chờ-anh + carry"*; `:62` chở trạng-thái thật *"Bookend @close S182 CHƯA chạy … treo-chờ-anh 5 câu ở WAL"*). ⇒ theo phép thử **thay thế** thì **ĐẠT ở điểm đo này**; theo phép thử **nguyên bản** thì **vô hiệu**. +🔴 Bài rút ra, chuyển được cho hub: **SELF-CHECK đòi chứng-cứ ở dạng bản-in sẽ hết hạn ngay khi cửa sổ đóng.** Ô nào cũng nên hỏi *"cái gì còn lại trên đĩa"*. + +### 🔶 ô4 = PASS thực chất, nhưng phép đo `8 = 8` đã hết hạn + +`find .claude docs -iname '*checklist*.md'` hôm nay = **16** (S139 = 8). Phân loại 16: + +| Nhà | Số | Bản chất | +|---|---|---| +| `docs/governance/adap-reports/` | **12** | báo-cáo VỀ broadcast có chữ "checklist" trong tên — **không** phải nguồn work-state | +| `.claude/workflows/runs/` | **3** | vật-chứng run (`checklist-verify-synthesis` 06-18 + `checklist-final` & `sub-review-checklist` của run hôm nay) — run-scoped, ephemeral | +| `docs/guides/security-checklist.md` | **1** | checklist nghiệp-vụ bảo-mật, có từ trước | + +⇒ **0 file nguồn-đôi work-state** ⇒ sàn-3 **vẫn đạt**. Nhưng phép đo mà report S139 dùng (*"8 trước = 8 sau"*) là **đếm bằng-nhau trên một corpus đang lớn** — nay mẫu số gấp đôi mà kết luận vẫn PASS, tức **con số không còn phân-biệt được gì**. Phải thay bằng **vị-từ**: *"có file nào tự nhận là nguồn trạng-thái-việc, song song với WAL/HANDOFF/STATUS không?"* +🔸 Khai thẳng ca biên: `runs/2026-08-09-…/checklist-final.md` (sinh hôm nay) là **work-ORDER** (spec giao việc), state per-item nằm ở `sub-*.md` + WAL — nên **không** tính nguồn-đôi. Ghi ra để người sau tự phán, thay vì im lặng cho qua. + +## Sàn-2 "sống ở MỌI cửa" — cập nhật từ 2/4 + +| Cửa | Khối `MASTER-CHECKLIST` trong lệnh (grep) | Vật-chứng nghi-thức ĐÃ CHẠY | Vật-chứng BẢN IN đúng khuôn | +|---|---|---|---| +| mở (`session-start.md`) | **1** | `_context-s-13.md` | ❌ (bản in không lưu đĩa) | +| dừng (`pause.md`) | **1** | `_pause-1.md` · `_pause-2.md` | ✅ @S139 (×2 lượt) | +| nối (`tiep.md`) | **1** | `_tiep-1/2/3.md` | ✅ @S139 (×1 lượt) | +| đóng (`session-end.md`) | **2** | **29 commit** closeout kể từ 07-17 | ❌ (bản in không lưu đĩa) | + +- Grep ra đúng **1/2/1/1** — **khớp byte con số report ghi @S139** ⇒ **0 drift sau 23 ngày**, khối không bị ai gỡ. +- Điều-kiện tự đặt của report (*"nếu lần đó không in đúng khuôn, nấc phải hạ lại executed-partial"*) **KHÔNG kích hoạt** — không có bằng-chứng in sai. Nhưng cũng **không thoả được** — không có bằng-chứng in đúng, vì cùng lý do ô1. +- ⇒ **Giữ nấc `executed`**, đổi caveat: từ *"chờ 1 chu-kỳ nữa"* (đã qua 5 chu-kỳ, vô hạn định) sang ***"phép thử phải đổi sang chứng-cứ durable"***. + +## Nấc sau addendum + +**`executed` (giữ)** cho 5/5 điểm sàn về mặt CÓ MẶT + 3/4 cửa vận-hành thật, **cộng 1 TRƯỢT tường-minh ở sàn-4/ô2** (vòng carry không khép — 4 kỳ liên tiếp, ≥12 lượt rớt, 1 slug đích danh). Không nâng lên `verified`; không hạ toàn khối vì 1 sàn trượt — **ghi tách bạch từng sàn** thay vì gộp 1 nhãn. + +## Việc đề-xuất (KHÔNG tự làm ở lane này — khai để nhận sau) +1. **Sàn-4 có răng:** carry rớt phải **chặn** closeout hoặc ít nhất **in tên slug rớt** ở cửa đóng, thay vì chỉ đếm streak. Cùng họ với bài *"cổng kêu mà không đổi hành-vi"*. +2. **Viết lại ô1 + ô2 của SELF-CHECK** theo chứng-cứ durable (artifact cửa-mở chở carry cửa-đóng ⇒ so được 2 file), gửi ngược hub như đề-xuất cải-tiến khuôn SELF-CHECK. +3. **Đổi acceptance ô4** từ đếm-bằng-nhau sang vị-từ nguồn-đôi. +🔸 (1) và (2) chạm nghi-thức/nhịp ⇒ **vùng owner**, chỉ khai. (3) là sửa acceptance trong report này, rẻ. diff --git a/docs/governance/adap-reports/2026-07-17-Governance-session-model-phien-logic-manifest.md b/docs/governance/adap-reports/2026-07-17-Governance-session-model-phien-logic-manifest.md index 2943272..903374c 100644 --- a/docs/governance/adap-reports/2026-07-17-Governance-session-model-phien-logic-manifest.md +++ b/docs/governance/adap-reports/2026-07-17-Governance-session-model-phien-logic-manifest.md @@ -34,3 +34,41 @@ - **5 câu hỏi SE gửi hub vẫn treo** (`session_ctx_kb`=64? · map N↔L + folder-form · VC từng dòng · hook 4-path? · prereq unblock) — email `b9ef5ede` chưa có reply. - 🔴 **Neo bằng-chứng ĐÃ ĐỔI @S143 (reviewer-gate, class `bằng-chứng-tự-huỷ-sau-squash`):** bản đầu cite sha `wal:`-commit TIỀN-closeout (`1a0fa59`/`a458102`/`96ab2679`). Closeout-squash gộp chúng vào `2757e41` ⇒ các sha đó thành **dangling**: `cat-file -t` vẫn ra `commit` (sống nhờ reflog LOCAL) nhưng `merge-base --is-ancestor origin/main` = **exit 1** ⇒ **hub clone repo về sẽ KHÔNG resolve nổi**. Nội-dung thì nguyên vẹn trong `2757e41` ⇒ **chết con-trỏ, không chết việc**. Đã re-anchor toàn bộ sang `2757e41`. **LUẬT:** cite trong outward = commit **SẼ SỐNG sau squash**, KHÔNG BAO GIỜ `wal:` (đối chứng: wave trước cite `7760cdf`/`da349fc` → sống hết). - ✅ **Đã push** — `2757e41` + `3f4310f` trên `origin/main` (thay câu khai chưa-đẩy ở bản đầu). + +--- + +## 6. ADDENDUM @S185 (2026-08-09) — "0 wire" đã hết đúng; nấc GIỮ `agreed`, và đây là lý do + +> 🔴 **Block MỚI, KHÔNG sửa §2 §3 §4 bên trên.** Mục 2 (`agreed`) và mục 3 (*"0 wire — đo chứ không khai suông"*) là **ảnh chụp @S143** và giữ nguyên làm vết. Trạng-thái hôm nay đọc ở đây. + +### 6.1 Wire ĐÃ XẢY RA — đo tươi từng khoản máy-kiểm-được (2026-08-09) + +| # | Khoản manifest | Nấc @S143 (§3) | Đo tươi hôm nay | Lệnh tái-lập | +|---|---|---|---|---| +| 1 | thư-mục phiên không bị `.gitignore` nuốt | ✅ đạt sẵn | ✅ giữ | — | +| 2 | cặp tạm-dừng/nối-lại + WAL có TRƯỚC | ✅ đạt sẵn | ✅ giữ (`/pause`+`/tiep`+`.claude/WAL.md`) | — | +| 3 | trần `session_ctx_kb` | ❌ **treo** | 🔄 **ĐÃ CÓ = 64**, kèm khoá vết `_session_ctx_kb_owner_set` ghi *"OWNER-SET TUONG-MINH @S146 2026-07-22"* | `grep -o 'session_ctx_kb[^,]*' .claude/agent-memory/memory-budget.json` → `64` + khoá owner-set | +| 4 | format-pin tên thư-mục theo ID phiên-LOGIC | ⚠️ **K4 form-conflict** | 🔄 **CHỐT THEO HUB-FORM**, 13 thư-mục sống `session-1 … session-13` | `ls -d .claude/sessions/*/` → 13 dir khớp `^session-\d+$` | + +Bổ sung: nhãn phiên-LOGIC đang **chạy thật xuyên nhiều cửa-sổ** — `L9` (`HANDOFF:95`) → `L12` (`HANDOFF:5`) → `L13` (`runs/2026-08-09-S185-email-adap-pipeline/run.md:1`). Lệnh: `grep -c "phiên-LOGIC" docs/HANDOFF.md docs/STATUS.md` → **7 · 9**. + +Nguồn hợp-thức của hướng wire: hub reply **`2026-07-22-ai_infra-to-se-reply-session-model-dung-ban-da-duyet`** (`content_sha256 8378a68b…`) — *"câu trả lời **không phải một mẫu mới**, mà là bản hub **đã chốt + owner đã GO**: manifest `101e69d6`… Dựng session-model trên bản này"*, và nói rõ *"**Không phải chờ trọn**"* (chỉ NGƯỠNG van mid-phiên là delta sau). + +### 6.2 🔴 Nhưng nấc **GIỮ `agreed`** — và đây là chỗ phải đọc kỹ + +Điều-kiện gate của §4 là **3 vế**: (a) hub phát mẫu ✅ · (b) khuôn bộ-ba SUB ✅ · **(c) owner duyệt bảng VC-1/2/3**. + +Đo hôm nay: `docs/governance/session-model-se-draft.md:64` vẫn ghi nguyên văn *"**(c) anh duyệt bảng VC-1/2/3 — ⏳ CHỜ ANH.** Đây là **điều-kiện CUỐI**, và giờ là điều-kiện duy nhất còn đứng chắn."* ⇒ **bảng VC-1/2/3 chưa từng được duyệt như một KHỐI.** + +Cái đã có là **2 quyết-định owner TƯỜNG MINH per-khoản**, không phải một lượt duyệt bảng: +- **K4 form** — owner override @S144, chốt hub-form @S146 (`session-model-se-draft.md:66` mục 1); +- **`session_ctx_kb`=64** — *"OWNER CHỐT TƯỜNG-MINH @S146"* (`:69-70` mục 2 + khoá vết trong `memory-budget.json`). + +⇒ Trạng-thái đúng chữ: **wire-de-facto per-khoản (2 khoản có chữ owner đích danh) + bảng VC chưa duyệt HÌNH-THỨC.** Không nâng nấc, vì nâng lên `executed` sẽ là claim rằng cổng (c) đã mở — nó chưa. Đây là **nhánh an-toàn của bậc-2** (`ACTIVE-MARKS §LT3`): đọc được 2 nghĩa (*"wire rồi ⇒ executed"* ⟂ *"cổng (c) chưa mở ⇒ agreed"*), hành-động không phá huỷ, chọn nhánh không-tự-phong-nấc và khai rõ. + +### 6.3 → W-list (trình chủ dự án, lane này KHÔNG tự quyết) + +**Câu cho anh:** bảng **VC-1/2/3** trong `docs/governance/session-model-se-draft.md` — (i) **phê duyệt hồi-tố** cả bảng (thì report này lên `executed` và `session-model-se-draft.md:64` được lật), hay (ii) **giữ per-khoản** (mỗi khoản một quyết riêng, bỏ hẳn khái niệm "duyệt bảng" — thì phải sửa §4 của report + `:64` của draft để hết câu *"điều-kiện duy nhất còn đứng chắn"* nói sai)? +🔸 Ràng: đây là **owner-LUẬT** (đổi cơ-chế cổng-duyệt), không phải việc lead tự thu-hẹp — đúng bài `HANDOFF:34` *"Diễn-giải của lead, không phải chữ của anh"*. + +🔸 **Khai kèm — carry đã RƠI:** slug `[carry:session-model-adopt]` (giữ đúng cổng này) có mặt ở các khối carry S140→S151 nhưng **KHÔNG** có trong khối RE-STAMP @S181 (`HANDOFF:9`). Lệnh: `grep -n "carry:session-model-adopt" docs/HANDOFF.md` → 6 hit, hit mới nhất `:218` (segment S151), **0 hit** trong `:9`/`:78`. Đây là một ca `gap-carry-dropped` chưa được đếm. diff --git a/docs/governance/adap-reports/2026-07-19-Governance-goi-chot-owner-nam-khoan.md b/docs/governance/adap-reports/2026-07-19-Governance-goi-chot-owner-nam-khoan.md index 8ccd5a5..eaedef8 100644 --- a/docs/governance/adap-reports/2026-07-19-Governance-goi-chot-owner-nam-khoan.md +++ b/docs/governance/adap-reports/2026-07-19-Governance-goi-chot-owner-nam-khoan.md @@ -38,3 +38,61 @@ - 🔴 **4.2 — vế "lane workflow có `tier:` override sống qua resume" đến nay VẪN CHƯA ĐO.** C15 kết luận cho Agent-tool, không cho lane workflow. Trạng-thái sau S144 không rõ ⇒ giữ **DEFER-đo** trung thực thay vì suy từ ca đã đo (đúng bài *tested = env đã test, không auto-generalize*, `goi-chot:23`). - 🔸 **4.4 — mẫu-số 19 là mẫu-số của lượt đo S144**, không phải hằng số; số câu-hứa trong repo đổi theo mỗi lượt viết doc. Bất kỳ ai đọc "19" như một chỉ-tiêu cố định là đọc sai. - 🔸 **sha thư chưa tái-đo hôm nay** (kế thừa frontmatter inbox theo brief). **Nấc dừng ở `executed`, KHÔNG `verified`** (`adap-report.md:31`). + +--- + +# ✅ ADDENDUM @S185 (2026-08-09) — ĐÓNG vế treo 4.2 (`tier:` override qua resume) + +> **Block MỚI, không sửa dòng cũ.** Dòng caveat *"4.2 — vế lane workflow … VẪN CHƯA ĐO … giữ DEFER-đo"* giữ nguyên làm vết: nó đúng lúc viết (25-07). Đây là lượt đo, checklist item **C-9** của run `2026-08-09-S185-email-adap-pipeline`. Ruột + lệnh: `.claude/workflows/runs/2026-08-09-S185-email-adap-pipeline/sub-opus-lane5-measure.md`. + +## Kết: **vế cũ = VACUOUS (n-a CÓ SỐ)** — nhưng rủi ro **đã dời chỗ**, và chỗ mới đang HỞ + +### (1) SE không có đường RESUME cho lane workflow ⇒ không có gì để "sống qua resume" + +| Phép đo | Kết quả | +|---|---| +| `grep -cniE "resume\|continue\|reattach\|session_id\|sessionId" .claude/workflows/hmw.js` | **0** | +| **Control dương** — cùng regex, tệp có chữ resume: `.claude/commands/tiep.md` | **13** ⇒ thước sống, 0 là **vắng thật** | +| Model gắn ở đâu | **DUY NHẤT** tại call-site spawn: `hmw.js:284` `agent(prompt, {…})` + `:291` `model: resolveModel(role, raw, t && t.tier, i)` | + +⇒ Mỗi lane là **một lần `agent()` mới**, model resolve ngay tại đó. **Không có resume ⇒ override không thể rớt qua resume.** Câu hỏi 4.2 ở dạng nguyên thuỷ **không áp cho SE**. + +### (2) 🔴 Rủi ro thật nằm ở RELAUNCH, và ở đó `tier:` KHÔNG có ai canh + +Đường phục-hồi của SE là **relaunch-đã-cắt-gọt** (`tiep.md:199-205`), không phải resume. Chính `:205` tự khai: *"Resume-theo-run-id (nếu engine có) = bonus CHỈ trong cùng phiên (SAME-SESSION-ONLY) — 🔴 CẤM claim nó chạy cross-session."* + +| Phép đo | Kết quả | +|---|---| +| `grep -ci tier .claude/commands/tiep.md` | **0** (control: `grep -ci model` = **2** ⇒ grep sống) | +| Bước 4 của nhánh `wf:` | dặn re-derive memory-pack **TƯƠI**, 🔴 CẤM snapshot cũ — **không một chữ** về giữ per-task `tier:` | +| run.md **có** `## taskList snapshot` | **54 / 88** run-folder | +| run.md **có chuỗi** `tier:` | **15 / 88** | +| run.md của **chính run đang chạy** (S185) | **0 hit** `taskList` · **0 hit** `tier` | + +**Chuỗi hỏng đầy đủ:** workflow chết → `/tiep` bước 1 bảo *"đọc `## taskList snapshot` trong run.md"* → với **34/88** run-folder (39%) **snapshot không tồn tại**, và run đang chạy hôm nay **nằm trong nhóm đó** → lead gõ lại taskList từ trí nhớ → thiếu `tier:` → `hmw.js:103-110` `resolveModel` trả `MODEL_INHERIT` → `:291` truyền `model: undefined` → frontmatter worker-tier `opus` cầm lái. **Không lỗi, không cảnh báo.** + +🔴 **Bất đối xứng của cảnh báo (đây là chỗ đáng vá):** `hmw.js:105` CÓ nhánh `⚠️` khi `tier` mang **giá-trị lạ**, nhưng **không có** nhánh nào khi `tier` **VẮNG** ở task mà lượt trước có. Tức máy kêu khi bạn gõ SAI, im khi bạn gõ THIẾU — mà thiếu mới là chế-độ hỏng của relaunch. + +### (3) Lưới bắt hiện có: chỉ HỒI-TỐ + +`scripts/spawn-model-audit.ps1` (PA-2b) so resolved-vs-expected và **tự khai giới hạn** ở header `:30-32`: *"This audit is RETROSPECTIVE… does not promise the next spawn stays on the expected version."* ⇒ một lane bị tụt tier vì relaunch **sẽ bị bắt SAU KHI đã chạy xong bằng model rẻ hơn**, không bị chặn trước. + +## Nấc mới cho 4.2 + +**`executed (có phạm vi) + đo XONG vế treo`** — thay `DEFER-đo`. Cụ thể: vế *"sống qua resume"* = **n-a có số** (0 đường resume, control dương 13); vế thay thế *"sống qua relaunch"* = **HỞ, đã định lượng** (0 hit `tier` trong `tiep.md`; 15/88 run.md chở `tier:`; run hôm nay 0/2 điều kiện). + +## Việc đề-xuất (KHÔNG tự làm — ngoài phạm vi lane đo, khai để nhận sau) + +1. `tiep.md` nhánh `wf:` bước 4: thêm **1 dòng** — *"chép lại per-task `tier:` từ `## taskList snapshot`; snapshot không có ⇒ khai `tier` đã mất, KHÔNG im lặng dùng mặc-định."* — chạm **file lệnh** ⇒ **ăn từ phiên sau restart** (ENV-DEP, không hot-reload). +2. Khuôn `run.md`: ép `## taskList snapshot` chở nguyên `tier:` — hiện chỉ 54/88 có snapshot. Cùng họ **C-7** (spawn-label khoản-④, cũng là "khuôn run.md thiếu trường"), nên gộp 1 lượt thay vì vá 2 lần. +3. `hmw.js`: cân nhắc log **1 dòng INFORM** khi taskList relaunch có role từng chạy `tier` mà lượt này vắng — nhưng máy không biết "lượt trước", nên rẻ hơn là để ở lớp `tiep.md` (mục 1). Ghi để không ai tưởng đã có máy canh. + +🔸 **Caveat của chính phép đo này:** 15/88 đếm theo **chuỗi `tier:`** nên gồm cả nhắc-trong-văn-xuôi, tức **15 là cận TRÊN** của "run.md thật sự chở override". 54/88 và 0/0 của run hôm nay thì đếm trực tiếp, không có nhập nhằng. + +--- + +## ADDENDUM-2 @S185 (2026-08-10) — vế 4.4 "máy-quét = DỰ-ĐỊNH" hết hiệu lực (block mới, row cũ giữ nguyên — bài-5) + +- **4.4 máy-quét lời-hứa-máy ĐÃ DỰNG:** `scripts/loi-hua-may-scan.ps1` (30.223 B, lane7 run `2026-08-09-S185-email-adap-pipeline` — self-test 11/11 PASS, fault-inject 3 ca cây tạm + control dương, 759ms). Mẫu-số ĐO LẠI = **30 dòng** (không phải 19 của C6 @S144 — cùng regex chạy 08-09; đúng lời khoản "mẫu-số công bố" phải tươi), 0 dòng `violation-open`. Nợ còn: ~~cửa gọi~~ ✅ cắm @S185 vào `session-end §L.b(k-ter)` (máy thứ 3). +- **4.2 vế "tier-qua-resume CHƯA ĐO"** → ĐÃ ĐO @S185 (lane5 C-9, addendum riêng nếu có — xem `sub-opus-lane5-measure.md`). +- 4.3 vẫn chờ owner-SỐ (W-3 — đã re-surface vào khối chờ-anh @S185 sau 15 ngày rơi). diff --git a/docs/governance/adap-reports/2026-08-05-Governance-loi-do-luong-phan-1-va-2.md b/docs/governance/adap-reports/2026-08-05-Governance-loi-do-luong-phan-1-va-2.md index d09cddb..1762aa9 100644 --- a/docs/governance/adap-reports/2026-08-05-Governance-loi-do-luong-phan-1-va-2.md +++ b/docs/governance/adap-reports/2026-08-05-Governance-loi-do-luong-phan-1-va-2.md @@ -64,3 +64,72 @@ Nhờ đúng mục đó mà SE **bác được Lớp 8 bằng 1 lệnh** thay v - SE **chỉ chạy phép bác cho 3/9 lớp** (7 · 8 + xác-nhận 1/3/5/6 bằng ca có sẵn trong phiên). **Lớp 2 · 4 · 9 chưa đo** — không claim fit, không claim miễn. - Rổ A liệt ca SE **tự bắt trước khi đọc thư**; công của thư ở đây là **đặt tên và gom thành lớp**, không phải phát hiện. Ghi đúng như vậy, không thổi. - **Phần 2 (ca riêng hub) đọc rồi, KHÔNG nhận làm sàn** — đúng chỉ-dẫn của chính thư. 3 nguyên-tắc bóc ra ở cuối Phần 1 thì có ăn: đặc-biệt *"khai sau khi chạy, không khai trước"* và *"bị chặn bởi quy-ước ≠ bị chặn bởi máy"* — cái sau SE đã có tiền-lệ `tools-whitelist-no-teeth` (whitelist = tuyên-bố ý-định, containment thật = git-diff commit-gate). + +--- + +# ✅ BỔ SUNG @S185 (2026-08-09) — đóng nợ "Lớp 2 · 4 · 9 chưa đo" + +> **Block MỚI, KHÔNG sửa dòng cũ.** Dòng Rổ C phía trên (*"Lớp 2 · 4 · 9 — chưa chạy phép bác, khai thẳng là chưa đo"*) **giữ nguyên làm vết** — nó đúng tại thời điểm 08-07. Đây là lần chạy thật, 2 ngày sau. +> **Ai chạy:** lane-5 của workflow `2026-08-09-S185-email-adap-pipeline`, checklist item **C-5**. Ruột đầy đủ + mọi lệnh tái-lập: `.claude/workflows/runs/2026-08-09-S185-email-adap-pipeline/sub-opus-lane5-measure.md`. +> **Engine:** KHÔNG spawn thêm — đọc thư gốc rồi tự chạy phép bác, đúng cách đợt 08-07. + +## Nấc G-011 phần bổ sung: **executed — 3/3 lớp CONFIRMED, 0 lớp bác được** + +| Lớp | Phép bác của thư | Kết quả SE 2026-08-09 | Nấc | +|---|---|---|---| +| **2** — chốt kiểm-chứng bị tiêu thụ | *"tìm mọi câu 'nếu X không xảy ra thì máy đã hỏng', chạy lại phép đo đó hôm nay"* | soi **5 chốt sống**: **2 HẾT HẠN**, 3 lệch hiệu-chuẩn | 🔴 **CONFIRMED** | +| **4** — nhãn không kiểm chứng được, phía người | *"10 quyết định gần nhất có lý do định lượng — bao nhiêu cái đủ 3 thành phần?"* | **4/10** đủ 3 · 5/10 được 2/3 · 1/10 được 1/3 · **+1 nhãn 0/3 đang cắt việc** | 🔴 **CONFIRMED** | +| **9** — hai nơi gọi chung một bộ trích | *"tìm hàm trích ≥2 nơi gọi, so xem có lọc giống nhau không"* | **14/30** hàm ≥2 nơi gọi; bộ trích lõi **1/3** nơi gọi giữ tín-hiệu | 🔴 **CONFIRMED** | + +⇒ Gộp 2 đợt: **8/9 lớp ÁP cho SE · 1/9 (Lớp 8) BÁC ĐƯỢC có số.** Đợt này **không bác được lớp nào** — khác đợt trước, ghi đúng vậy. + +## Lớp 2 — 2 chốt đã hết hạn + +**(1) `scripts/naming-scan.ps1` — máy in một số rồi tự giải thích bằng số khác, trong CÙNG một màn hình.** +`:317` in `$script:Total` **sống** → hôm nay ra `mau so TONG : 256`. Nhưng `:318-321` (và `:196`) hard-code lời giải thích *"goc 231 … => 233 sau W1"*, viết 08-07 ⇒ **hở 23 tên không ai giải thích**. Chua ở chỗ khoản (3) trong chính hợp-đồng của máy đó là *"LUON IN MAU SO canh moi con so"*. +Tái lập: `powershell -NoProfile -File scripts/naming-scan.ps1 | grep -E "mau so TONG|goc 231"` + +**(2) Neo số-dòng liên-tệp — 4/4 SAI.** +`naming-standard.md:107` chỉ đường sửa regex 5-họ tới `governance-detectors.ps1:1102` + `:1771` + `memory-selfimprove-audit.ps1:298`. Đo 2026-08-09 21:24: regex thật ở **`:1213`**, **`:1882`**, **`:307`** (trôi +111/+111/+9). `naming-scan.ps1:24` neo `:1109` cũng sai. +🔴 **Phát hiện phụ đắt hơn phát hiện chính:** toạ-độ trôi **ngay trong cửa-sổ đo** (`:1109` lúc ~21:1x → `:1213` lúc 21:24) vì lane khác đang sửa cùng tệp (114.797 → 122.956 B). ⇒ **neo số-dòng vào tệp có người đang sửa thì hạn dùng tính bằng PHÚT, không phải bằng phiên.** Cùng thuốc với Lớp 7 (*neo cấu trúc, đừng neo hình dạng*) và bài nhà `HEAD~n ≠ commit-trước-của-mình` (S177). Neo bền thay thế: `grep -n -- "-return)" scripts/governance-detectors.ps1`. + +**3 chốt còn lại lệch hiệu-chuẩn nhưng chức năng còn sống** (control vẫn ≠ 0 ⇒ thước còn thấy được): `naming-scan.ps1:25-26` control-dương ghi **58** → đo lại **9.238 byte / 127 điểm-mã**, không tái lập ở cả 2 đơn-vị · `so-yeu-cau-chu-du-an.md:69` control ghi **5 tệp** → đo lại **70** · `naming-scan.ps1:8-11` ngưỡng *"8-12 lớp nợ"* → hôm nay `LECH 8/256` rải 4 nhóm, tức **đọc "lớp"=cờ thì 8 ∈ [8,12] ✅, đọc "lớp"=nhóm thì 4 ∉ [8,12] ❌**. Cái cuối chính là **Lớp 3 tái diễn bên trong phép bác Lớp 2**. + +## Lớp 4 — 4/10, và cấu-phần rụng là "lệnh tái lập" + +Mẫu: 10 quyết-định gần nhất có lý-do định-lượng, quét ngược `.claude/WAL.md` (S185) → `checklist-final.md` (lead, hôm nay) → `docs/HANDOFF.md` (S179-S181). +- **Đủ 3/3 = 4** — đều là quyết-định ship/gate: test `668/0` · DLL prod `=3` · ring2 `30.781 B` vs cap · archive-gate `strike 1/2`. +- **2/3 = 5** — có đại-lượng + có ngưỡng, **thiếu đúng cái lệnh viết cạnh số**. +- **1/3 = 1** — nợ harvest `576.255 B / 18 lượt-vai`: có số, **không ngưỡng**. + +🔴 **Ca-âm nặng nhất nằm NGOÀI mẫu và ở TRONG chính lượt adopt thư này:** `checklist-final.md:43` *"### LANE-7 (CUỐI, **nếu còn ngân sách**)"* + `:8` *"nếu ngân sách không đủ thì khai, không ép"*. Nhãn *"ngân sách"* = **0/3 thành phần** (không đại-lượng, không lệnh, không ngưỡng) và **được dùng để định-đoạt phạm-vi công việc**. Đúng câu thư: *"lý do bị bác đã được dùng để cắt phạm vi công việc trước khi ai kịp kiểm."* +Nghiêm hơn ca hub một điểm: SE **đã có sàn** cho đúng nhãn đó — `.claude/commands/session-start.md:193` đòi so byte thật vs cap **kèm lệnh** `scripts/measure-agent-memory`. Luật CÓ, nhưng luật chỉ soi **máy**; câu văn của **người** đi vòng qua. Đúng nguyên nhân thư chỉ ra: *"luật thường được viết để soi máy, và người viết luật mặc nhiên đứng ngoài phạm vi."* + +## Lớp 9 — bộ trích tự viết hợp đồng, 2/3 nơi gọi vứt hợp đồng đi + +`scripts/session_ctx.py:285` `_split_content_region` trả `(region, line_offset, rules_end_found)`. Docstring `:290-291` tự đặt luật: *"Marker absent => scan the WHOLE file **+ raise a flag** … the safe failure direction is **LOUD, not lenient**."* + +| Nơi gọi | Nhận `rules_end`? | Hệ quả | +|---|---|---| +| `:614` full-mode | ✅ `if not rules_end:` → cờ *"quet TRON tep (huong hong NGHIEM)"* | đúng hợp đồng | +| `:565` draft-mode | ❌ `region, line_offset, _ =` | **im lặng** | +| `:572` draft-mode (đọc bản canonical) | ❌ `creg, coff, _ =` | **im lặng** | + +Hai nơi vứt cờ **chính là đường draft** — đường mà `:590` tự khai mục đích *"kiem NHAP truoc khi chen — loi khong bao gio vao tep"*. Một `_mind` draft thiếu `` sẽ bị quét **trọn tệp** (gồm cả khối luật vốn cố ý chép nguyên các chuỗi bị cấm) mà **cổng duy nhất dựng để chặn trước khi ghi thì không kêu**. Full-mode sẽ kêu — nhưng lúc đó nội dung đã nằm trong tệp. Đúng vị chua ca hub: **lỗi nằm ngay trong đường ống của cơ chế dựng ra để chặn lỗi**; class của nó (**citation-trap / use⟂mention**) là class SE đã có bài học riêng. + +Cùng họ, nhẹ hơn: `_check_pointer` nhận `closed=False` **đóng cứng** ở draft (`:584`) nhưng nhận `closed` **sống** ở full (`:628`) · `_check_numbering` + `_check_bookend_order` **chỉ chạy full-mode** ⇒ draft "sạch" không đồng nghĩa file sẽ sạch · regex 5-họ có **3 bản sao độc lập**, 0 hằng-số dùng chung (`naming-standard.md:107` đã tự khai, chưa gộp). + +## 🔴 Phản-biện gửi ngược hub (bổ sung đợt này) + +**4. Đề nghị hub thêm vào Lớp 2 một biến thể mà phép bác hiện tại KHÔNG bắt: chốt neo TOẠ-ĐỘ, không neo GIÁ-TRỊ.** +Phép bác của thư hướng người đọc đi tìm câu *"nếu X không xảy ra thì máy đã hỏng"* — tức chốt neo **giá trị đo được**. Ca đắt nhất SE tìm ra hôm nay lại là loại khác: chốt neo **số dòng** (`file:1102`). Nó không mang hình dạng mệnh-đề-canh nên **lọt lưới phép bác**, mà hậu quả y hệt — người đọc làm theo chỉ dẫn và sửa nhầm chỗ. Đề nghị thêm 1 câu vào mục "bác chúng tôi bằng cách nào": *"và mọi con trỏ `file:line` trong tài liệu — mở đúng dòng đó hôm nay, có còn là thứ được mô tả không?"* Rẻ, máy làm được, ở kho SE ra **4/4 sai**. + +**5. Lớp 4 nên nói rõ nó áp cho cả câu văn của người PHÂN VIỆC, không chỉ của trợ lý.** +Ca hub là trợ lý viện *"gần hết bộ nhớ ngữ cảnh"*. Ca SE là **lead** viết *"nếu còn ngân sách"* ngay trong bản checklist giao việc — cùng cơ chế, khác cấp. Nếu thư nêu thẳng "kể cả người phân việc", sister sẽ soi đúng chỗ đau thay vì chỉ soi output của agent. + +## Honest-caveat (phần bổ sung) + +- **Mẫu Lớp 4 = 10, khung quét do lane-5 tự chọn** (3 bề mặt, ngược thời gian). Khung khác (thêm session-log 07/2026) có thể ra tỷ lệ khác. Khung được ghi **trước** khi đếm để ai muốn bác thì bác bằng khung của họ — đúng thuốc Lớp 3. +- **Lớp 9 mới quét 1 tệp** (`session_ctx.py`, 30 hàm). `governance-detectors.ps1` (122.956 B) **chưa quét hết** vì đang bị lane khác sửa trong lúc đo. Không claim đã phủ toàn kho. +- **3 việc sửa lane-5 KHÔNG tự làm, khai để lượt sau nhận:** (i) `naming-scan.ps1:196/318-321` cho lời giải thích bám số in — cùng họ máy governance, tránh đụng lane đang sửa; (ii) `session_ctx.py:565/572` nhận `rules_end` — chạm đường ống ctx, cần fault-inject riêng; (iii) nhãn *"nếu còn ngân sách"* `checklist-final.md:43` — **quyền lead**, chỉ khai không sửa. +- Phần bổ sung này **không** đụng Rổ A/B/C cũ, **không** đổi nấc của Lớp 1·3·5·6·7·8 đã chốt 08-07. diff --git a/docs/governance/adap-reports/2026-08-07-Governance-nghi-thuc-hai-dau-nhip-thua-va-luu-nguyen-van.md b/docs/governance/adap-reports/2026-08-07-Governance-nghi-thuc-hai-dau-nhip-thua-va-luu-nguyen-van.md index 6a5419c..c799f47 100644 --- a/docs/governance/adap-reports/2026-08-07-Governance-nghi-thuc-hai-dau-nhip-thua-va-luu-nguyen-van.md +++ b/docs/governance/adap-reports/2026-08-07-Governance-nghi-thuc-hai-dau-nhip-thua-va-luu-nguyen-van.md @@ -38,3 +38,24 @@ Lý do hub nêu: ở kho họ các con audit **đã chạy đủ, đã sinh đ Ở SE không phải *"audit chạy mà không ghi được gì"*, mà là **"máy dựng xong, chạy đúng, mà KHÔNG CỬA NÀO GỌI"** — `naming-scan.ps1` + `artifact-integrity.ps1` có **0 cửa nghi-thức gọi**, chỉ sống khi người gõ tay. Phát hiện được **chỉ vì** bảng máy⟂tay của khoản A16 bắt phải có **ba nấc**; thang hai nấc (*"có máy / không có máy"*) xếp cả hai vào **CÓ**. ⇒ **Đề xuất cho hub:** cạnh câu *"đã chạy nhưng không ghi lại được"*, thêm biến thể *"đã dựng nhưng không ai gọi"*. Cùng gốc — **cổng báo xanh trên một phạm vi mà không ai đo** — nhưng lộ ra ở chỗ khác và cần phép đo khác (đếm cửa gọi, không đếm sự tồn tại của máy). + +--- + +## 8. ADDENDUM @S185 (2026-08-09) — đính chính dòng "CHƯA GHÉP" của mục 4 + +> 🔴 **Block MỚI, KHÔNG sửa mục 4 và mục 5 bên trên** (bài-5 thư 08-08: giữ ảnh chụp trạng-thái lúc viết làm vết, đính chính bằng block mới). Ai đọc mục 4 phải đọc tiếp tới đây. + +**Dòng đã STALE:** mục 4 hàng 2 ghi *"🔴 **CHƯA GHÉP** — chủ dự án gật P5 là gật **3 bậc**, chưa gật phần ghép này. Để **con trỏ**, không tự adopt"*; mục 5 ghi *"**Skip:** điều kiện 3 ghép vào bậc-2 — chờ chủ dự án phán riêng"*. + +**Sự thật đo tươi 2026-08-09 — ĐÃ GHÉP @S181, cùng phiên báo cáo này được viết:** + +| # | Bằng-chứng | Lệnh tái-lập | Kết quả | +|---|---|---|---| +| 1 | `.claude/governance/ACTIVE-MARKS.md:65` — hàng **bậc-2** của §LT3 mang nguyên khối *"🔴 **+ Điều-kiện-3 (ghép @S181, anh gật):** khi **không phân biệt được** *dời-có-chủ-ý* với *rơi-im-lặng* ⇒ khai đúng chữ **"không đủ dữ liệu"**; **CẤM mặc định về nhãn miễn tội.**"* | `grep -n "Điều-kiện-3" .claude/governance/ACTIVE-MARKS.md` | **1 hit @:65** | +| 2 | Sổ quyết-định `.claude/workflows/runs/2026-08-07-S180-adap-upgrade-pack-phased/owner-decisions-07-08-2026-dot-2.md:47` — *"✅ **P5 (d) — ĐÃ GHÉP @S181** (anh gật câu 2). Điều-kiện-3 nay là một vế **trong bậc-2** của `ACTIVE-MARKS §LT3`."* | đọc mục *"Còn treo sau đợt-2"* dòng 2 | khớp | + +⇒ **Nấc của khoản này: `skip / chờ-owner` → `executed`.** Nấc TỔNG của báo cáo (mục 2) **GIỮ `executed`**, không đổi — khoản này vốn là khoản duy nhất còn hở, nay khép. + +**Vì sao dòng cũ tồn tại được 2 ngày:** report viết @S181 lúc lead trình thư cho anh, và anh gật câu-2 **sau** khi report đã ghi. Không ai quay lại lật. Đây đúng lớp *"sổ nói dối theo hướng BI QUAN"* (`HANDOFF:74`) — báo còn nợ khi nợ đã trả; và lần này nó sống được vì **cửa duy nhất đóng khoản này là trí nhớ của lead**, không có máy nào đối chiếu report ⟂ `ACTIVE-MARKS`. + +🔸 **Khai giới hạn:** addendum này chỉ đính chính **trạng-thái ghép**. Nó **không** phong nấc *đã được kiểm chứng* (chỉ hub cấp), và **không** đụng phần "Tailored/Skip nhãn thứ năm" ở mục 5 — quyết-định đó (P3 = B, tập tín-hiệu ĐÓNG) vẫn nguyên hiệu lực. diff --git a/docs/governance/adap-upgrade-pack-tracking.md b/docs/governance/adap-upgrade-pack-tracking.md index 1b81804..692bc46 100644 --- a/docs/governance/adap-upgrade-pack-tracking.md +++ b/docs/governance/adap-upgrade-pack-tracking.md @@ -136,16 +136,25 @@ grep -c 'đã được kiểm chứng *|' docs/governance/adap-upgrade-pack-trac ### M3 — MỒ CÔI: có máy, KHÔNG cửa nào gọi (3 — sau khi wire 2 máy) -| Máy | Trạng thái @S181 | -|---|---| -| `seed-test-users-prod.ps1` | 🔴 **MỒ CÔI, mới lộ @S181** — 0 cửa gọi, và **lọt bộ-lọc loại-trừ** ở đầu §7 (`seed-*` không có trong danh sách) ⇒ theo chính luật của tệp này nó **phải** có mặt. Bản đầu bảng M3 thiếu dòng này | -| `wal-recovery-test.ps1` | 🔴 **CÒN mồ côi** — máy kiểm thử phục hồi WAL, đúng bản chất là chạy tay khi nghi ngờ. Giữ mồ côi **CÓ KHAI** | -| `session_scaffold.py` | 🔴 **CÒN mồ côi** — nghi trùng với `session-scaffold.ps1` (đang được gọi). **Chưa xác minh**, không xoá theo phỏng đoán | +| Máy | Trạng thái @S181 | Xác minh @S185 (C-10) — `wire-or-khai` | +|---|---|---| +| `seed-test-users-prod.ps1` | 🔴 **MỒ CÔI, mới lộ @S181** — 0 cửa gọi, và **lọt bộ-lọc loại-trừ** ở đầu §7 (`seed-*` không có trong danh sách) ⇒ theo chính luật của tệp này nó **phải** có mặt. Bản đầu bảng M3 thiếu dòng này | **KHAI, không wire.** 0 cửa gọi (đo lại, lệnh ở cuối mục). Bản chất = script **vận-hành sản-phẩm** (seed user test vào DB prod, chạy tay lúc triển khai — `docs/changelog/sessions/2026-05-13-2200-s22-chot-cuoi.md:147,280`), không phải máy governance. 🔴 **KHÔNG nới bộ-lọc**: thêm `seed-*` sẽ kéo **mẫu số 24→23** = đổi số đã đo và đã gửi hub ⇒ quyền lead/chủ dự án | +| `wal-recovery-test.ps1` | 🔴 **CÒN mồ côi** — máy kiểm thử phục hồi WAL, đúng bản chất là chạy tay khi nghi ngờ. Giữ mồ côi **CÓ KHAI** | **KHAI, không wire — trạng thái @S181 ĐỨNG.** 0 cửa gọi (đo lại). Bộ 4-ca/30-assert dùng để *chứng* defect-fix (`adap-reports/2026-07-13-Governance-harness-22-wal-defect-fix.md:14`), không phải nghi-thức định kỳ ⇒ wire vào bookend = trả chi phí thường-trực cho máy chỉ hữu ích khi có nghi vấn | +| `session_scaffold.py` | 🔴 **CÒN mồ côi** — nghi trùng với `session-scaffold.ps1` (đang được gọi). **Chưa xác minh**, không xoá theo phỏng đoán | 🔴 **Ô bên trái nay STALE — nghi-trùng ĐÃ XÁC MINH, bằng vật của chính wave S181.** `naming-standard.md:161` (W1): *"Fork thật duy nhất … TRÙNG KHÁI NIỆM, hai bản sinh tên đầu ra giống hệt, cả hai hard-pin, 0 nguồn chung"*; đã có mã + disposition **M-10** (`:253`) / **N-6** (`:271` → *"hợp nhất là đổi mã, không phải đổi tên"*, xếp W2). Nó **không chết hẳn**: `:200` đếm `session_scaffold.py:105` là **1 trong 4 site hard-pin** hình dạng `session-`. Lai lịch = **port near-verbatim từ hub** (`session_scaffold.py:4`, adopt S148). ⇒ **Mồ côi CÓ CHỦ ĐÍCH** (giữ đối-chiếu hub) — **KHAI, không wire, không xoá** | 🔸 **`naming-scan.ps1` + `artifact-integrity.ps1` ĐÃ CHUYỂN SANG M2** (wire `session-end §L.b(k-ter)` cùng lượt) — giữ tên ở đây sẽ thành *"số máy TỪNG mồ côi"* ⟂ *"số máy ĐANG mồ côi"*, đúng lớp lỗi mà bảng ba nấc sinh ra để chặn. 🔴 **Đây là phát hiện đắt nhất của W6.** Hai máy W1/W2 vừa dựng xong, chạy đúng, fault-inject có răng — **mà không cửa nào gọi**. Chúng chỉ sống khi có người gõ tay, nên hết phiên là hết chạy. Thang 2 nấc (*"có máy / không có máy"*) sẽ xếp chúng vào **CÓ** và ta yên tâm nhầm; đúng thứ A16 dựng nấc thứ ba để bắt. +🔴 **Lệch số phải khai (phát hiện @S185, C-10):** báo cáo cuối đã gửi hub ghi *"**2 mồ côi còn lại**"* (`adap-reports/upgrade-pack-phased-bao-cao-cuoi.md:64`), bảng này ghi **3**. Bảng đúng — `seed-test-users-prod.ps1` lộ **sau** khi câu tổng-kết của báo cáo đã viết (chính dòng của nó tự khai *"Bản đầu bảng M3 thiếu dòng này"*). Câu trong **bản đã gửi** vì thế là vật STALE; erratum ra hub = quyết định của lead, **không sửa lén bản đã gửi**. + +🔸 **Thước "0 cửa gọi" có răng — positive-control @S185:** cùng một lệnh chạy trên 4 máy ĐANG được gọi ra `nhip-no-probe.ps1` **7** · `memory-archive-gate.ps1` **3** · `artifact-integrity.ps1` **2** · `naming-scan.ps1` **1**, trúng đúng cửa mà M2 khai ⇒ **0-hit của 3 máy M3 là vắng-mặt THẬT**, không phải thước hỏng. Lệnh: + +```bash +git grep -l -F "" -- '.claude/commands' '.claude/agents' '.claude/hooks' \ + '.claude/settings.json' '.github' 'hmw.js' | wc -l +``` + ### Lệnh đo lại (đừng tin bảng, chạy lại) ```bash diff --git a/docs/governance/ctx-soft-memory-se-draft.md b/docs/governance/ctx-soft-memory-se-draft.md index b3de7a0..a141cfb 100644 --- a/docs/governance/ctx-soft-memory-se-draft.md +++ b/docs/governance/ctx-soft-memory-se-draft.md @@ -1,6 +1,6 @@ -# Ctx soft-memory — SE-form DRAFT (adopt thư `0df10df4` pause-tiep-upgrade-vong-ctx) +# Ctx soft-memory — SE-form ✅ RATIFIED + ĐÃ WIRE @S153 (adopt thư `0df10df4` pause-tiep-upgrade-vong-ctx) -> **Trạng thái: ✅ RATIFIED + ĐÃ WIRE @S153 (OWNER-VETO).** Anh bác (38)(a)-1-vai-gộp, chốt trực tiếp **"Build đủ 3 vai như hub"** qua AskUser ⇒ 3 vai `ctx-curator`/`ctx-verifier`/`ctx-audit` SỐNG trong roster (23, canonical → STATUS §Sub-agents) + máy `session_ctx.py mind-check` chạy mỗi cửa + wire tại `/pause §2.6(C-bis)` · `/tiep §3-ter` · bookend 2 đầu. Các câu đã định-đoạt: **(36)** hub-form spawn mỗi cửa (vai-1 @mỗi-pause = carve-out duy nhất luật "NGỪNG spawn", mirror hub O-1(a)) · **(37)(b)** nạp NỀN RÚT-GỌN theo khoá `tiep_reload` (`tiep.md §3-ter` cite "quyết (37)(b)") · **(38)(b)** 3 vai tách — marker inline dưới. 🧊 *Header cũ "DRAFT chờ anh chốt — CẤM wire" đứng từ S153→S164 SAU khi đã wire = **wired-but-declared-unwired** (ghost-wire chiều ngược, cùng class `closed.md` S146; ring1+ring2 bắt @S163 "ô xanh thủng"). Thân doc dưới GIỮ NGUYÊN dạng draft làm lineage — đọc "đề xuất" là đề-xuất-lúc-viết, không phải trạng-thái.* +> **Trạng thái: ✅ RATIFIED + ĐÃ WIRE @S153 (OWNER-VETO).** Anh bác (38)(a)-1-vai-gộp, chốt trực tiếp **"Build đủ 3 vai như hub"** qua AskUser ⇒ 3 vai `ctx-curator`/`ctx-verifier`/`ctx-audit` SỐNG trong roster (23, canonical → STATUS §Sub-agents) + máy `session_ctx.py mind-check` chạy mỗi cửa + wire tại `/pause §2.6(C-bis)` · `/tiep §3-ter` · bookend 2 đầu. Các câu đã định-đoạt: **(36)** hub-form spawn mỗi cửa (vai-1 @mỗi-pause = carve-out duy nhất luật "NGỪNG spawn", mirror hub O-1(a)) · **(37)(b)** nạp NỀN RÚT-GỌN theo khoá `tiep_reload` (`tiep.md §3-ter` cite "quyết (37)(b)") · **(38)(b)** 3 vai tách — marker inline dưới. 🧊 *Header cũ "DRAFT chờ anh chốt — CẤM wire" đứng từ S153→S164 SAU khi đã wire = **wired-but-declared-unwired** (ghost-wire chiều ngược, cùng class `closed.md` S146; ring1+ring2 bắt @S163 "ô xanh thủng"). **Dòng `#` đầu của chính tệp này còn trễ thêm một tầng nữa: nó giữ chữ `DRAFT` tới tận S185**, SAU khi khối trạng-thái ngay dưới đây đã vá — đúng lớp *"thân đã sửa, masthead sống sót"*; đồng-bộ @S185 theo `naming-standard.md` **§12-bis** (masthead của CHÍNH tệp vừa sửa), nguồn sàn `3-khoan:19-27`. Thân doc dưới GIỮ NGUYÊN dạng draft làm lineage — đọc "đề xuất" là đề-xuất-lúc-viết, không phải trạng-thái.* > Nguồn: broadcast `2026-07-25-Governance-pause-tiep-upgrade-vong-ctx` (sha `0df10df4` — stamp-verify OK @S153, copy `broadcasts/inbox/` root=pending). Hub tự khai: **build xong + gate xanh, dogfood CHƯA có cửa nào chạy qua** — adopt là adopt KHUÔN chưa-kiểm-chứng, lỗi phát hiện thì gửi về hub (hub-owner Q-1: "có j debug sau cũng đc"). ## 1. Bài toán (đúng SE) diff --git a/docs/governance/naming-standard.md b/docs/governance/naming-standard.md index cc95764..2eb3ad5 100644 --- a/docs/governance/naming-standard.md +++ b/docs/governance/naming-standard.md @@ -8,6 +8,7 @@ - **Kiểm kê máy nền:** `.claude/workflows/runs/2026-08-07-S180-adap-upgrade-pack-phased/sub-w1a-mayd-octen.md` — **14 đoạn máy đọc tên, 11 vỡ-câm**. Phụ lục A dưới đây là bản rút gọn BẮT BUỘC tra trước mọi lần đổi tên. - **Máy soi:** `scripts/naming-scan.ps1` — INFORM-only, mã thoát 0, quét **231 tên vật-bộ-máy**. - **Sổ đổi tên:** `docs/governance/rename-ledger.md` — chỉ-thêm-không-xoá. +- **Bổ sung SAU ngày ký:** **§12-bis** (masthead của chính tệp vừa sửa) — thêm 2026-08-09 / phiên S185, nguồn sàn `3-khoan:19-27`. *(Dòng này chính là §12-bis tự áp lên tệp của nó: thân đổi thì masthead phải nói ra.)* --- @@ -204,6 +205,29 @@ Một chuẩn "mọi tên kebab" sẽ **cờ 5 tệp đang đúng** = dương-gi 🔸 Hai bảng sao **cùng một regex** ở `detectors:1102` và `:1771` là **nợ kỹ thuật: 1 luật / 2 bản sao**. S159 đã phải vá **cả hai**; chú thích `:1769-1770` tự khai *"mirror of the C11(b) filter fix above"*. Hợp nhất thành một hằng số là việc nên làm — **không làm trong W1** (đụng máy đang sống, thuộc W2 theo `Q5`). +## §12-bis — MASTHEAD của CHÍNH tệp vừa sửa 🔴 + +**Nguồn sàn:** `broadcasts/inbox/ai_infra/2026-07-20-Governance-3-khoan-title-tier-posture-home-distill-params.md` **Khoản 1** (`:19-27` — vùng đóng băng L1 nên neo số dòng ở đây hợp lệ). Hub đo: **ba ca cùng một hình trong ba phiên liền**; ca nặng nhất — một doc chính sách mang tiêu đề khai một tên model **đã bị thay hai đời trước** — **sống sót qua hai lượt quét**. + +**Vì sao luật này nằm ở tệp này, ngay sau §12:** §12 liệt "số chỗ phải sửa ĐỒNG THỜI" theo **danh mục nơi TRỎ TỚI** một cái tên. Nhưng cách một tệp **tự mô tả chính nó** — dòng `#` đầu, khối masthead, dòng trạng thái ngay dưới tiêu đề — **không nằm trong danh mục của ai cả**. Nó là chỗ duy nhất không ai trỏ tới, nên là tầng sống lâu nhất sau mỗi lượt quét. Đây là chỗ ghi nó. + +**Luật (một bước, vài giây):** sửa THÂN một tệp trong một lượt quét/vá ⇒ **đọc lại dòng `#` đầu + khối masthead của CHÍNH tệp đó** trước khi tuyên lượt quét xong. Tuyên "xong" mà chưa đọc lại = **chưa xong**. + +**Phạm vi:** mọi tệp có masthead **mang trạng thái** — nhãn DRAFT/RATIFIED, mã phiên, ngày, tên chế độ, con số, tên model. Masthead thuần mô tả (chỉ nói tệp này là cái gì) thì miễn; miễn thì **nói ra**, đừng im (L4). + +**Phép thử (tái lập được, không cần máy):** + +```bash +for f in docs/governance/*.md docs/rules.md docs/STATUS.md docs/HANDOFF.md CLAUDE.md; do + printf "%-52s | %s\n" "$f" "$(grep -m1 '^#' "$f")"; done +``` + +Đối chiếu từng dòng in ra với trạng thái hiện hành **trong thân chính tệp đó** — không đối chiếu với trí nhớ. + +**Lượt chạy đầu (2026-08-09, phiên S185 — 21 tệp): một ca dương THẬT.** `docs/governance/ctx-soft-memory-se-draft.md` còn chữ `DRAFT` ở dòng `#` đầu trong khi khối trạng thái của **chính nó** đã tuyên `✅ RATIFIED + ĐÃ WIRE @S153 (OWNER-VETO)` — thân đã vá, masthead sống sót. Đã đồng bộ ngay trong lượt đó, giữ vết 🧊. **KHÔNG tính là ca:** `session-model-se-draft.md` — masthead ở đó **khớp** thân (`0 nghi-thức chuyển per-L`); thân có cũ hay không là câu của khoản đối chiếu thư trả lời hub 07-22, **không phải** lỗi masthead. Phân biệt hai loại này quan trọng: gộp lại sẽ đẻ ra dương giả và làm phép thử mất uy. + +**CHƯA CÓ MÁY** — khai theo **L0**: luật này sống bằng kỷ luật một bước, chưa đoạn máy nào ép. Ai muốn cắm máy thì cắm ở **lớp INFORM** (`naming-scan.ps1`, họ tệp `.md` có masthead mang trạng thái) và ghi vào **Phụ lục B**; **cấm** ký hình dạng sâu hơn nấc máy ép. + ## §13 — Giao thức di trú sáu bước (cho ca BUỘC phải đổi tên đã có người trỏ) 1. **Ký chuẩn** (tệp này). diff --git a/docs/governance/so-yeu-cau-chu-du-an.md b/docs/governance/so-yeu-cau-chu-du-an.md index 2bf7542..8e87730 100644 --- a/docs/governance/so-yeu-cau-chu-du-an.md +++ b/docs/governance/so-yeu-cau-chu-du-an.md @@ -32,7 +32,7 @@ Dữ-liệu cũ (WAL · HANDOFF · auto-memory · migration-todos) **KHÔNG** đ | mã | lời nguyên văn | thời điểm · phiên | trạng thái | số lần đã nhắc | con trỏ | 🔴 đội hiểu thành gì | nhắc-lại-của | |---|---|---|---|---|---|---|---| | `YC-001` | "Nói rõ các vấn đề trên nhé" | 2026-08-07 · S181 | đóng | 1 | báo-cáo lượt S181 | Giải thích 6 câu chờ-anh bằng nguồn thật, không phỏng theo trí nhớ — kèm khuyến nghị từng câu | | -| `YC-002` | "OK cứ làm dry-run luôn" | 2026-08-07 · S181 | **mở** | **4** | `WAL` chain W5 + W4b | *(lead hiểu SAI lượt đầu: tưởng dry-run các ô acceptance W3 ⇒ anh phải đính chính **3 lần**, xem 3 dòng dưới.)* Ý thật: **thi hành trọn plan adapt** | | +| `YC-002` | "OK cứ làm dry-run luôn" | 2026-08-07 · S181 | **mở** | **4** | `docs/changelog/sessions/` log S181 + run `2026-08-07-S180-adap-upgrade-pack-phased/` *(con-trỏ cũ "WAL W5+W4b" chết theo reset — gap-F2)* | *(lead hiểu SAI lượt đầu: tưởng dry-run các ô acceptance W3 ⇒ anh phải đính chính **3 lần**, xem 3 dòng dưới.)* Ý thật: **thi hành trọn plan adapt** | | | `YC-003` | "gõ /adap-apply (dry) -> OK chốt cái này cho W3" | 2026-08-07 · S181 | đóng | 1 | `WAL` chain "W3 acceptance 6/6 ĐÓNG" | Gõ lệnh thật để xác nhận thân lệnh nạp có BƯỚC 0, **không** áp thư nào | | | `YC-004` | "làm tiếp đi nhé, nãy tao nói dry-run tức chạy hết cái plan adapt ở turn trước chứ ko phải dry-run cái này" | 2026-08-07 · S181 | đóng | — | `WAL` chain "THI HÀNH 5/6 khoản đợt-2" | Đính chính lần 1 | **`YC-002`** | | `YC-005` | "làm xong thì chậy hết cái plan adapt nhé" | 2026-08-07 · S181 | đóng | — | cùng trên | Đính chính lần 2 | **`YC-002`** | @@ -41,13 +41,14 @@ Dữ-liệu cũ (WAL · HANDOFF · auto-memory · migration-todos) **KHÔNG** đ | `YC-008` | "Làm xong hết đi nhé" *(dán kèm bảng 5 wave còn lại, trong đó 2 wave ghi rõ đang CHẶN)* | 2026-08-07 · S181 | đóng | 1 | `WAL` chain W5/W4b | Chạy hết wave chạy được; 2 wave chặn thì chuẩn bị trọn rồi để đúng phần của anh | | | `YC-009` | "đồng ý stamp - ký tên -> Làm đi nhé" | 2026-08-07 · S181 | đóng | 1 | `ACTIVE-MARKS` mark `RC-…-21-42-10` | Cấp chữ ký niêm phong W6 **và** phán nốt P7 vế (ii) | | | `YC-010` | "OK làm hết rồi khép trọn đi" | 2026-08-07 · S181 | đóng | **2** | `WAL` chain W5b/W3b/W6 | Khép trọn gói: W5b + W3b + phần còn lại W6 | `YC-008` | -| `YC-011` | "1,2 -> làm đi, OK sau đó /session-end" | 2026-08-07 · S181 | mở | 1 | `WAL` `next:` | (1) push 42 commit · (2) cổng đồng-bộ + báo cáo cuối · rồi đóng phiên | | +| `YC-011` | "1,2 -> làm đi, OK sau đó /session-end" | 2026-08-07 · S181 | **đóng** *(lật @S185 — stale-F8: 3/3 vế xong từ S181, treo oan 4 nhãn phiên)* | 1 | closeout S181 commit `d2918790` + `HANDOFF` segment L12 *(con-trỏ cũ "WAL next:" đã chết theo reset — gap-F2, đổi sang mốc bền)* | (1) push 42 commit · (2) cổng đồng-bộ + báo cáo cuối · rồi đóng phiên — cả 3 đã thi hành @S181 | | | `YC-012` | "nâng cap" *(🔸 trích từ `spec-…-07-08-2026.md:64`, cửa-sổ **S180**, KHÔNG bắt trực tiếp ở cửa-sổ này — khai đúng nấc)* | 2026-08-07 · S180 | đóng | 1 | `memory-budget.json` `_cap_raised_S181` | Lệnh dứt khoát nâng `hmw_width.cap` 20→30. 🔴 @S179 lead **tự thu-hẹp** chữ "OK" thành "chưa phải lệnh đổi số" — lần này không tự thu-hẹp | | | `YC-013` | "Hiện tạo muốn cac quy trình này giống như duyệt NCC. Có thể thêm sửa xóa edit stick tương tự như duyệt NCC. Cho 2 /fable-real invest cách làm BE và Database, 1 /fable-real invest cách cấu hình giao diện front-end đúng nhất về UI lẫn giao diện, ko lệch. -> Ra các wave xử lý chi tiết nhất. cho 2 /fable-real review và tổng hợp các wave xử lý chi tiết. Cuối cùng fan-out cho Opus 5 MAX xử lý nhé." *(kèm 4 ảnh trang `approval-workflows-v2/DuyetNcc` + dialog Sửa-tại-chỗ)* | 2026-08-08 · S182 | **mở** *(code+deploy XONG — còn acceptance-mắt-anh + bookend @close rồi lật đóng; TASK → WAL)* | **2** | `runs/2026-08-08-S182-khkk-awf-mirror-ncc/` | 8 workflow "Duyệt KHKK — Nhóm 1..8" phải có ĐỦ chức năng như trang "Duyệt NCC": xem steps/cấp/NV + per-NV quyền duyệt + Sửa-tại-chỗ + Tạo-phiên-bản-mới + Ghim/Bỏ-ghim + Xoá-version + lịch-sử-versions. UI **không lệch** khuôn DuyetNcc. Pipeline anh chỉ định: 3 `/fable-real investigator-codebase` (BE · DB · FE-UI) → wave-plan chi tiết → 2 `/fable-real reviewer` → hmw fan-out **Opus 5 MAX** execute | | | `YC-014` | "C — Mờ ô chưa nghe (Recommended)" *(AskUser D3 @S182 — sau khi invest phát hiện 6/9 checkbox KHKK-runtime bỏ qua)* | 2026-08-08 · S182 | đóng | 1 | `spec-khkk-awf-mirror-ncc-DRAFT.md` MỤC 3 D3 | Dialog KHKK giữ layout y khuôn; ô máy-chưa-nghe **mờ + tooltip "chưa áp dụng cho KHKK"** (tiền lệ ô Duyệt-thẳng-Cấp-cuối @K3). KHÔNG port semantics đợt này (W3 hủy); port sau thì gỡ mờ dần | | | `YC-015` | "làm nốt cho ra giao diện luôn nhé" *(qua `/tiep` @S183)* | 2026-08-08 · S183 | đóng | — | WAL chain `[x]` cicd-4-chân | Verify deploy `706134da` cho giao diện 8 panel SỐNG trên prod — 4/4 chân PASS (bundle ×2 rotate + marker + DLL 3-hit + 8-row IsActive=1 + pin-lệch 0) | **`YC-013`** | -| `YC-016` | "1 -> (c) THEO TAY CẦM PHIẾU -> OK nhé" | 2026-08-08 · S183 | **mở** | 1 | WAL chain (TASK → WAL) | **Phán quyết slot (67)** treo từ S172: upload file-khi-duyệt KHKK theo TAY CẦM PHIẾU — phiếu Nháp/Trả-lại (tay người soạn) ⇒ NGƯỜI SOẠN up được; phiếu Chờ-duyệt ⇒ CHỈ NGƯỜI DUYỆT (thuộc workflow phiếu); guard ở API-layer (#82 2-tầng), kèm test. Slot (67) ĐÓNG | | -| `YC-017` | "AI_INFRA và /adap-apply — Cho /fable-real invest và review checklist cẩn thận sau đó cho Opus 5 MAX xử lý" *(args lệnh `/check-email` @S185)* | 2026-08-09 · S185 | **mở** | 1 | WAL chain (TASK → WAL) | Kéo thư AI_INFRA CẢ 2 kênh (`outbox/se` qua check-email + `outbox/all` qua adap-apply), rồi pipeline khuôn YC-013: `/fable-real investigator-codebase` soi trạng-thái thư/adopt + dựng checklist → `/fable-real reviewer` review checklist cẩn thận → hmw fan-out **Opus 5 MAX** execute. *(Thư 08-08 đã áp trọn @S185 TRƯỚC lệnh này — pipeline chạy trên phần việc CÒN LẠI mà invest tìm ra.)* | | +| `YC-016` | "1 -> (c) THEO TAY CẦM PHIẾU -> OK nhé" | 2026-08-08 · S183 | **mở** *(code+deploy+verify-DLL XONG @S183, RE-verify @S185 — còn acceptance-mắt-anh, lật cùng đợt YC-013; chú-thích thêm @S185 cho đối-xứng — stale-F9)* | 1 | ship `72568f05` + WAL chain (TASK → WAL) | **Phán quyết slot (67)** treo từ S172: upload file-khi-duyệt KHKK theo TAY CẦM PHIẾU — phiếu Nháp/Trả-lại (tay người soạn) ⇒ NGƯỜI SOẠN up được; phiếu Chờ-duyệt ⇒ CHỈ NGƯỜI DUYỆT (thuộc workflow phiếu); guard ở API-layer (#82 2-tầng), kèm test. Slot (67) ĐÓNG | | +| `YC-017` | "AI_INFRA và /adap-apply — Cho /fable-real invest và review checklist cẩn thận sau đó cho Opus 5 MAX xử lý" *(args lệnh `/check-email` @S185)* | 2026-08-09 · S185 | **đóng** *(pipeline P1→P4 trọn @S185: 0/39 nợ per-id · 21/21 item disposition; 4 câu W phát sinh → khối CHỜ-ANH riêng, không giữ YC mở)* | 1 | `runs/2026-08-09-S185-email-adap-pipeline/implement-synthesis.md` | Kéo thư AI_INFRA CẢ 2 kênh (`outbox/se` qua check-email + `outbox/all` qua adap-apply), rồi pipeline khuôn YC-013: `/fable-real investigator-codebase` soi trạng-thái thư/adopt + dựng checklist → `/fable-real reviewer` review checklist cẩn thận → hmw fan-out **Opus 5 MAX** execute. *(Thư 08-08 đã áp trọn @S185 TRƯỚC lệnh này — pipeline chạy trên phần việc CÒN LẠI mà invest tìm ra.)* | | +| `YC-018` | "2 phần bookend và bookstart -> trong đợt adapt này AI_INFRA cũng có hướng dẫn bọn mày chạy 1 mạch hết toàn bộ ko còn pause/tiep nữa, chú ý cấu hình cái đó kỹ nhé" | 2026-08-09 · S185 | **mở** | 1 | WAL chain (TASK → WAL) | Nghi-thức 2 đầu phiên (`/session-start` bookstart + `/session-end` bookend) phải chạy **TRỌN TRONG MỘT LƯỢT** như hub kể ở thư 08-08 Phần 1b ("lượt mở phiên gần nhất chạy trọn trong một lượt duy nhất, không cần cửa tạm dừng nào chen giữa") — cấu hình luật ONE-SHOT vào 2 file lệnh, CẤM rải nghi-thức qua nhiều cửa pause/tiep, CẤM hẹn-cửa-sau. *(Đội hiểu: pause/tiep VẪN là recovery khi đứt bất-khả-kháng [limit/crash — H22 giữ nguyên]; thứ bị cấm là DÙNG chúng làm nhịp chia-chặng nghi-thức. Anh bác cách hiểu này thì em sửa.)* | | > 🔴 **MỘT yêu-cầu, nhắc 4 lần.** Đây là dữ-liệu **TC-01** sinh ra để bắt, và nó tố-giác chính lead: hiểu sai ở `YC-002` nên anh phải nói lại 3 lần. **Ghi lại chứ không làm đẹp.** > diff --git a/scripts/governance-detectors.ps1 b/scripts/governance-detectors.ps1 index a09168a..a790371 100644 --- a/scripts/governance-detectors.ps1 +++ b/scripts/governance-detectors.ps1 @@ -347,10 +347,55 @@ if (Test-Path $gotchasPath) { ForEach-Object { $gotchaAnchors[[int]$_.Matches[0].Groups[1].Value] = $true } } +# --- L7-BOLT (C-2 @S185, medicine of broadcast 2026-08-05 "Lop 7 - neo vao hinh dang +# chu do nguoi go", Ro C) --------------------------------------------------------- +# '### N.' is a HUMAN-TYPED heading glyph. Let the writer file the two newest gotchas as +# "### 87 -" or "#### 87." and they drop OUT of $gotchaAnchors in silence -- after which +# this detector keeps emitting CONFIDENT per-ref lines ("'gotcha #87' has no anchor") +# that are pure artefacts of a dead parse, not findings. That is the exact failure the +# broadcast reports: the machine slid past the newest lines, re-anchored on an older +# block and printed 13 overdue items to the session when the true number was 0. +# +# The medicine has TWO layers and layer 2 is the load-bearing one: +# (1) do not anchor on the glyph -> not fixable here without owning gotchas.md's +# heading convention (= owner ground), so it is NOT attempted; declared instead. +# (2) add a live/dead BOLT read from an INDEPENDENT source: the newest anchor parsed +# must not sit more than ONE step behind canonical. Canonical here is the +# docs/STATUS.md Gotchas row -- a different FILE reached by a different parse +# (Get-StatusValue table-row regex), so a heading-shape change cannot move both. +# Off by more than one step => print "chua do duoc" and emit NO anchor-derived +# number. Without the bolt a "0" and a "13" are equally meaningless. +# Tolerance is ONE step by construction (a gotcha counted in STATUS whose section is +# written a beat later is normal drift, not a dead parse) - that is the broadcast's own +# wording ("khong cu hon moc moi nhat qua mot bac"), not a threshold invented here. +# SCOPE of the suppression: only the ANCHOR-EXISTENCE verdict is withheld. The +# range check (cites #N > canonical max) does NOT read $gotchaAnchors at all, so it +# keeps firing -- withholding it would hide a real witness behind a parse problem. +$anchorMaxGotcha = 0 +foreach ($ak in $gotchaAnchors.Keys) { if ($ak -gt $anchorMaxGotcha) { $anchorMaxGotcha = $ak } } +$gotchaAnchorLive = $true +$gotchaAnchorGap = 0 +if ($null -ne $maxGotcha -and $gotchaAnchors.Count -gt 0) { + $gotchaAnchorGap = $maxGotcha - $anchorMaxGotcha + if ($gotchaAnchorGap -gt 1) { $gotchaAnchorLive = $false } +} +$gotchaAnchorSuppressed = 0 + if ($null -eq $maxGotcha -or $gotchaAnchors.Count -eq 0) { Write-Host ' [skip] no canonical max-gotcha or no anchors parsed - cannot validate gotcha refs' -ForegroundColor DarkGray } else { + if (-not $gotchaAnchorLive) { + Write-Host (" CHUA DO DUOC (L7-bolt): newest '### N.' anchor parsed = {0} but canonical (docs/STATUS.md Gotchas) = {1} -> the heading anchor is {2} steps behind, i.e. the parse is DEAD, not the docs. Anchor-existence verdict WITHHELD - no number is emitted from a dead anchor." -f ` + $anchorMaxGotcha, $maxGotcha, $gotchaAnchorGap) -ForegroundColor Yellow + Write-InformFlag ("docs/gotchas.md") ` + ("L7-bolt: gotcha anchor parse is DEAD (newest '### N.' anchor = {0}, canonical = {1}, gap {2} > 1) - anchor-existence checking measured NOTHING this run (chua do duoc, NOT clean)" -f $anchorMaxGotcha, $maxGotcha, $gotchaAnchorGap) ` + "re-file the newest gotcha section(s) as '### . ' so the anchor parse reaches canonical, OR re-ground the docs/STATUS.md Gotchas row if IT is the stale side" + } + else { + Write-Host (" [ok] L7-bolt: newest anchor {0} vs canonical {1} (gap {2} <= 1) - anchor parse is LIVE, numbers below are measured" -f ` + $anchorMaxGotcha, $maxGotcha, $gotchaAnchorGap) -ForegroundColor DarkGray + } # Match "gotcha #N", "gotcha N", and bare "#N" tokens. # S151 fix (FP #111, H1 F-6 + ring1 confirm): the word-branch used to swallow # "gotchas 111.616B" (a BYTE-SIZE, thousands-separator) and flag a phantom #111. @@ -382,6 +427,10 @@ else { 'fix the number or add the gotcha to docs/gotchas.md' } elseif ($isGotchaWord -and -not $gotchaAnchors.ContainsKey($num)) { + # L7-bolt (C-2): a dead anchor parse makes EVERY ref look anchorless. + # Count what is withheld and print the count, so the drop in emitted + # lines is told by its COMPONENTS and can never read as "got cleaner". + if (-not $gotchaAnchorLive) { $gotchaAnchorSuppressed++; continue } Write-Flag 'LOW' ("{0}:{1}" -f (Rel $f.FullName), ($i + 1)) ` ("broken-gotcha-ref: 'gotcha #{0}' has no '### {0}.' anchor in gotchas.md" -f $num) ` 'fix ref or create the missing gotcha anchor' @@ -389,6 +438,9 @@ else { } } } + if (-not $gotchaAnchorLive) { + Write-Host (" L7-bolt withheld {0} anchor-existence line(s) this run (they would all be artefacts of the dead parse, not findings)" -f $gotchaAnchorSuppressed) -ForegroundColor Yellow + } } # --------------------------------------------------------------------------- @@ -908,18 +960,70 @@ else { # that flags the sentence DEFINING its own pattern is the self-reference trap. $carryRx = '\[carry:([a-z0-9][a-z0-9._-]*)\]' $carryLines = @() - foreach ($s in $segs) { + $carrySegIdx = @() # L7-bolt: which segment each carry-line came from + for ($si = 0; $si -lt $segs.Count; $si++) { $ks = @() - foreach ($cm in [regex]::Matches($s, $carryRx)) { $ks += $cm.Groups[1].Value } - if ($ks.Count -gt 0) { $carryLines += , (@($ks | Select-Object -Unique)) } + foreach ($cm in [regex]::Matches($segs[$si], $carryRx)) { $ks += $cm.Groups[1].Value } + if ($ks.Count -gt 0) { $carryLines += , (@($ks | Select-Object -Unique)); $carrySegIdx += $si } } Write-Host (" HANDOFF logic-segments (pre-marker + NEXT anh/em) = {0} ; of those, carry-lines = {1}" -f ` $segs.Count, $carryLines.Count) + # --- L7-BOLT (C-2 @S185, medicine of broadcast 2026-08-05 "Lop 7", Ro C) --------- + # This net anchors on TWO human-typed shapes: the '**NEXT anh/em' segment header and + # the '[carry:slug]' stamp. Only the NEWEST carry-bearing segment can hold a live + # streak, so if the newest block is typed differently (bold dropped, stamp cased + # '[Carry:'), the anchor SLIDES DOWN to an older block and every streak is then + # measured against history the repo already replaced -- while the output keeps its + # confident per-key shape ("streak=3 < M=6"). That is the broadcast's ca verbatim: + # the machine slid past the newest lines and reported precise, wrong numbers. + # + # BOLT, read from an INDEPENDENT source: the session milestone of the anchored + # segment vs the newest milestone in the SAME document parsed WITHOUT any of the two + # glyphs (plain S<N> scan over the raw text). Both readings come off the same file + # but through disjoint parse paths, so no single glyph change can move both. Off by + # more than ONE step => print "chua do duoc" and emit NO streak number. + # WHY the doc's own newest S and not the session counter: the question this net asks + # is "is my anchor at the FRONT of this document", which is a property of the + # document. The counter would answer a different question (is the document current), + # and picking a tolerance for THAT is an owner number -- not invented here. + $SMilestoneRx = '(?<![A-Za-z0-9])S(\d+)(?![\d])' + $docMaxS = 0 + foreach ($sm in [regex]::Matches($raw, $SMilestoneRx)) { + $sn = [int]$sm.Groups[1].Value; if ($sn -gt $docMaxS) { $docMaxS = $sn } + } + $anchorMaxS = 0 + if ($carrySegIdx.Count -gt 0) { + foreach ($sm in [regex]::Matches($segs[$carrySegIdx[0]], $SMilestoneRx)) { + $sn = [int]$sm.Groups[1].Value; if ($sn -gt $anchorMaxS) { $anchorMaxS = $sn } + } + } + $carryAnchorLive = $true + $carryAnchorGap = 0 + if ($carryLines.Count -gt 0 -and $docMaxS -gt 0 -and $anchorMaxS -gt 0) { + $carryAnchorGap = $docMaxS - $anchorMaxS + if ($carryAnchorGap -gt 1) { $carryAnchorLive = $false } + } + if ($carryLines.Count -eq 0) { Write-Host ' (0 carry-line - no [carry:<slug>] stamped yet, nothing to age)' -ForegroundColor DarkGray } + elseif ($docMaxS -eq 0 -or $anchorMaxS -eq 0) { + Write-Host (" CHUA DO DUOC (L7-bolt): no S<N> milestone readable ({0} in doc / {1} in anchored segment) - cannot tell whether the anchor is at the front of the file, so NO streak number is emitted" -f $docMaxS, $anchorMaxS) -ForegroundColor Yellow + Write-InformFlag 'docs/HANDOFF.md' ` + 'L7-bolt: carry-age anchor liveness UNMEASURABLE (no S<N> milestone in the doc and/or in the anchored segment) - carry-age measured NOTHING this run (chua do duoc, NOT clean)' ` + 'keep an S<N> session milestone in the newest carry block so the anchor can be proven to sit at the front of the file' + } + elseif (-not $carryAnchorLive) { + Write-Host (" CHUA DO DUOC (L7-bolt): carry anchor sits at S{0} while the document's newest milestone is S{1} ({2} steps behind) -> the '**NEXT' / '[carry:' shape anchor has SLID off the newest block. Streak numbers WITHHELD ({3} key(s) would have been scored against replaced history)." -f ` + $anchorMaxS, $docMaxS, $carryAnchorGap, $carryLines[0].Count) -ForegroundColor Yellow + Write-InformFlag 'docs/HANDOFF.md' ` + ("L7-bolt: carry-age anchor DEAD - anchored segment is S{0}, doc newest is S{1} (gap {2} > 1); {3} key(s) NOT scored, carry-age measured NOTHING this run (chua do duoc, NOT clean)" -f $anchorMaxS, $docMaxS, $carryAnchorGap, $carryLines[0].Count) ` + "restore the newest block's '**NEXT anh/em' header and lower-case '[carry:<slug>]' stamps so the newest segment is the anchored one again" + } else { + Write-Host (" [ok] L7-bolt: carry anchor S{0} vs doc newest S{1} (gap {2} <= 1) - anchor is at the front of the file, streaks below are measured" -f ` + $anchorMaxS, $docMaxS, $carryAnchorGap) -ForegroundColor DarkGray foreach ($k in $carryLines[0]) { $n = 0 for ($i = 0; $i -lt $carryLines.Count; $i++) { @@ -971,6 +1075,12 @@ else { # --------------------------------------------------------------------------- Write-Section 'H25-closeout-ritual (GAP-2)' +# C13 hook (carve-out liveness, C-8 @S185): counts close-groups this section ACTUALLY +# scored. 0 = the grid ran but measured nothing (skip branch) = "chet lang". Read by +# the C13 section far below; kept here so the number is produced by the grid itself and +# not re-derived (a second derivation would be a second definition). +$script:H25Scored = 0 + # Subject shape of a session-close commit. Held in a variable (used by -match on git # SUBJECTS, never on any scanned file) so no prose copy exists to self-trip a matcher. $CloseoutSubjectRx = '^\[CLAUDE\] Docs: S\d+.*(?:closeout|session-end)' @@ -1041,6 +1151,7 @@ else { continue } $prev = $closeGroups[$i + 1].Tip + $script:H25Scored++ # C13 hook: this group IS scored (not skipped) $range = ("{0}..{1}" -f $prev.Hash, $cur.Hash) $union = @() @@ -1942,6 +2053,325 @@ else { $c12Note = if ($c12Measured) { '' } else { ' -- MEASURED NOTHING (no session log at/after the land date); a 0 outside the window is not a green' } Write-Host (" C12 raw-engine-bypass flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c12Flags, $c12Note) -ForegroundColor DarkGray +# --------------------------------------------------------------------------- +# C13 - carve-out liveness (INFORM-only, NEW @S185; count SEPARATE, NOT in TOTAL) +# --------------------------------------------------------------------------- +# NAMING: this is the script's OWN C-numbering (C1..C12 already exist above). It is a +# DIFFERENT namespace from the S185 run-checklist codes; this detector implements +# checklist item C-8. Do not read "C13" as "checklist C-13". +# +# WHY: docs/governance/error-ledger.md "Carve-out o3 - dieu-kien SONG" pins the +# force-fire carve-out at rank `PASS-voi-carve-out`, VALID **only while BOTH grids are +# alive at the same time** (error-ledger:52-54, verbatim targets): +# (a) the read-only debt line still PRINTS at every stop point - scripts/nhip-no-probe.ps1 +# (b) the "closeout-missing-ritual" probe is still WIRED - section H25-closeout-ritual +# (GAP-2) in THIS script +# One grid dead => the carve-out loses its self-transparency layer => RE-EVAL the rank, +# and fall back to unconditional running until the grid is alive again (error-ledger:58). +# +# THE GAP THIS CLOSES - self-declared, not hypothetical. The SE adap-report for the +# 2026-07-17 hub reply says, in its own honest-caveat (section 5): +# "Carve-out dang duoc canh bang NGUOI, khong bang MAY ... khong co detector nao canh +# chinh dieu-kien do. Neu mot luoi chet lang, nac PASS-voi-carve-out se TIEP TUC duoc +# khai ma khong ai biet" +# and section 4 files the liveness detector as "follow-up, chua build". This section is that +# follow-up. Until now the condition holds by DISCIPLINE, which is exactly the +# `cam-bang-tri-nho` class the ledger forbids. +# +# HOW EACH GRID IS MEASURED (existence is NOT liveness): +# (a) is measured in TWO parts, because a guard can fail in two independent ways: +# (a1) EMITS - the probe is RUN and must print a line starting `NHIP-NO:`. +# Existence alone proves nothing: nhip-no-probe.ps1 exits 0 ALWAYS and +# degrades to `probe-loi (khong chan)` on any exception, i.e. its failure +# mode is precisely "alive-looking and silent". Only running it separates +# the two. Cost measured before wiring: ~512 ms, and this script is an +# audit tool, not a stop point (the stop-point cheapness predicate C7 is +# about /pause and /tiep, not about the detector suite). +# (a2) IS CALLED - at least one stop-point command file must carry a real +# INVOCATION. use vs mention matters here as a measured fact, not a theory: +# a prior count of "6 call sites" included .claude/commands/check-email.md, +# where both hits are the script's NAME in prose and neither is a call; the +# true set is 5. The predicate therefore requires `-File <...>nhip-no-probe.ps1` +# on the line, which prose mentions do not carry. A machine that emits +# perfectly but that nothing calls is dead in the only sense that matters. +# (b) is measured by whether the H25 section SCORED anything this run +# ($script:H25Scored), not by whether its code is present. A section that runs and +# takes the [skip] branch prints reassuring output while measuring nothing. +# +# SEVERITY: INFORM. A dead grid is a governance fact of some weight, but folding a +# brand-new net into the audited TOTAL (and raising its severity) is a post-triage, +# owner-gated decision per the sink contract at the top of this file - never the net +# author's call. The line shape is identical to Write-Flag, so `comm before/after` +# isolates it and a fault-inject greps it exactly like any other flag. +Write-Section 'C13 - carve-out liveness (INFORM-only)' +$c13Flags = 0 +$c13Measured = $false +$c13LedgerPath = Join-Path $RepoRoot 'docs\governance\error-ledger.md' +$c13Resolve = 'restore the dead grid, OR re-eval the carve-out rank in docs/governance/error-ledger.md (Carve-out o3) and fall back to unconditional running until it is alive again' + +if (-not (Test-Path $c13LedgerPath)) { + Write-Host ' [skip] docs/governance/error-ledger.md not found - no carve-out rank is being claimed here, nothing to guard' -ForegroundColor DarkGray +} +else { + $c13Measured = $true + + # ---- grid (a1): the probe RUNS and EMITS ---- + $probePath = Join-Path $RepoRoot 'scripts\nhip-no-probe.ps1' + $aEmits = $false + $aWhy = '' + if (-not (Test-Path $probePath)) { + $aWhy = 'scripts/nhip-no-probe.ps1 is GONE from disk' + } + else { + $pOut = '' + try { $pOut = (& powershell.exe -ExecutionPolicy Bypass -File $probePath -RepoRoot $RepoRoot 2>&1 | Out-String) } + catch { $pOut = '' } + if ($pOut -match '(?m)^NHIP-NO:') { $aEmits = $true } + else { + $first = (($pOut -split "`r?`n") | Where-Object { $_.Trim().Length -gt 0 } | Select-Object -First 1) + if ($null -eq $first) { $first = '(no output at all)' } + $aWhy = ("the probe ran but printed no 'NHIP-NO:' line (first line: {0})" -f $first.Trim()) + } + } + + # ---- grid (a2): at least one stop point CALLS it ---- + $callRx = '-File\s+\S*nhip-no-probe\.ps1' + $callSites = @() + $cmdDir = Join-Path $RepoRoot '.claude\commands' + if (Test-Path $cmdDir) { + foreach ($cf in (Get-ChildItem -Path $cmdDir -Filter *.md -File -ErrorAction SilentlyContinue)) { + $cl = Get-Content -Path $cf.FullName -Encoding UTF8 -ErrorAction SilentlyContinue + for ($i = 0; $i -lt $cl.Count; $i++) { + if ($cl[$i] -match $callRx) { $callSites += ("{0}:{1}" -f $cf.Name, ($i + 1)) } + } + } + } + + # ---- verdicts ---- + if (-not $aEmits) { + Write-InformFlag 'scripts/nhip-no-probe.ps1' ` + ("carve-out grid (a) DEAD - the debt line no longer prints: {0}. error-ledger 'Carve-out o3' requires BOTH grids alive; rank PASS-voi-carve-out is NOT valid while this is dead" -f $aWhy) ` + $c13Resolve + $c13Flags++ + } + elseif ($callSites.Count -eq 0) { + Write-InformFlag 'scripts/nhip-no-probe.ps1' ` + ("carve-out grid (a) DEAD-BY-DISCONNECT - the probe emits, but NO stop-point command actually calls it (0 lines matching '-File ...nhip-no-probe.ps1' under .claude/commands). A debt line nobody triggers is not printed 'at every stop point'") ` + $c13Resolve + $c13Flags++ + } + else { + Write-Host (" [ok] grid (a) ALIVE: nhip-no-probe emits NHIP-NO: and is CALLED from {0} stop point(s) - {1}" -f ` + $callSites.Count, ($callSites -join ', ')) -ForegroundColor DarkGray + } + + if ($script:H25Scored -le 0) { + Write-InformFlag 'scripts/governance-detectors.ps1 (H25-closeout-ritual)' ` + 'carve-out grid (b) DEAD - the closeout-ritual probe took its [skip] branch and scored 0 close-group this run, i.e. it is wired but measuring NOTHING. error-ledger Carve-out o3 requires BOTH grids alive' ` + $c13Resolve + $c13Flags++ + } + else { + Write-Host (" [ok] grid (b) ALIVE: H25-closeout-ritual scored {0} close-group(s) this run" -f $script:H25Scored) -ForegroundColor DarkGray + } +} +$c13Note = if ($c13Measured) { '' } else { ' -- MEASURED NOTHING (skipped above); a 0 after a skip is not a green' } +Write-Host (" C13 carve-out-liveness flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c13Flags, $c13Note) -ForegroundColor DarkGray + +# --------------------------------------------------------------------------- +# C14 - stamp_verify mirror-drift (INFORM-only, NEW @S185; count SEPARATE, NOT in TOTAL) +# --------------------------------------------------------------------------- +# NAMING: script-local C-numbering (see C13 note). This implements S185 checklist C-19. +# +# WHY: scripts/stamp_verify.py is a MIRROR, not a source. Its own header says so: +# "mirror-of AI_INFRA/scripts/stamp_verify.py (ported S141 ...) - re-pull khi hub doi +# section-N canon. KHONG sua logic local." +# The SE adap-report for 2026-07-17-Governance-chuan-hoa-stamp-decode says it plainly +# (section 5 honest-caveat): "hub doi section-N canon ma SE quen re-pull thi 2 ben lech IM LANG - hien +# KHONG CO MAY NAO canh drift giua 2 ban, chi co header-note nhac NGUOI." Measured @S185: +# a note is the only guard, and a note guards nothing once nobody re-reads it. Two copies +# of one canon = the drift class B1 exists to prevent (same shape as C9 above). +# +# WHAT IS COMPARED - and why not the raw bytes. Measured today: the two files differ by +# exactly ONE line, the local mirror-of note itself (`diff` = 1 added line, 2378 B vs +# 2247 B). A raw-hash watcher would therefore INFORM on EVERY run forever - a permanently +# red lamp is read as noise within a week and is just a dead grid pointing the other way. +# So the drift verdict is taken on the LOGIC hash: the declared local-only note line is +# excluded (it is the file's own statement that only the note may differ), CRLF is +# normalized to LF (a checkout EOL setting is not a canon change), and the RAW hashes are +# printed alongside anyway so nothing is hidden by the normalization. +# +# HUB PATH IS DERIVED, NEVER HARDCODED: repo-root -> up 2 -> AI_INFRA. An absolute path +# with a machine-specific prefix silently degrades to the else-branch on any other +# machine, and a silent degrade reads exactly like "clean" - the S122 W5 lesson already +# paid for once in this file. Hub unreachable => "CHUA DO DUOC", never [ok], never silence. +Write-Section 'C14 - stamp_verify mirror-drift (INFORM-only)' +$c14Flags = 0 +$c14Measured = $false + +function Get-MirrorHashes { + param([string]$Path) + $txt = [System.IO.File]::ReadAllText($Path) + $raw = $txt -replace "`r`n", "`n" + $logic = (($raw -split "`n") | Where-Object { $_ -notmatch '^\s*#.*mirror-of' }) -join "`n" + $sha = [System.Security.Cryptography.SHA256]::Create() + $enc = New-Object System.Text.UTF8Encoding($false) + $h1 = ($sha.ComputeHash($enc.GetBytes($raw)) | ForEach-Object { $_.ToString('x2') }) -join '' + $h2 = ($sha.ComputeHash($enc.GetBytes($logic)) | ForEach-Object { $_.ToString('x2') }) -join '' + return [pscustomobject]@{ Raw = $h1; Logic = $h2; Lines = (($raw -split "`n").Count) } +} + +$mirLocal = Join-Path $RepoRoot 'scripts\stamp_verify.py' +$hubRoot = $null +$p1 = Split-Path $RepoRoot -Parent +if ($null -ne $p1) { $p2 = Split-Path $p1 -Parent; if ($null -ne $p2) { $hubRoot = Join-Path $p2 'AI_INFRA' } } +$mirHub = if ($null -eq $hubRoot) { $null } else { Join-Path $hubRoot 'scripts\stamp_verify.py' } + +if (-not (Test-Path $mirLocal)) { + Write-InformFlag 'scripts/stamp_verify.py' ` + 'stamp mirror MISSING locally - the ported verifier is gone, so /check-email and /send-email fall back to the regex-pin path with nothing checking the canon' ` + 're-pull scripts/stamp_verify.py from AI_INFRA, or declare the regex-pin path canonical and retire the mirror in the SAME change' + $c14Flags++; $c14Measured = $true +} +elseif ($null -eq $mirHub -or -not (Test-Path $mirHub)) { + $shown = if ($null -eq $mirHub) { '(hub root underivable)' } else { $mirHub } + Write-Host (" CHUA DO DUOC: hub copy not reachable at {0} - drift is UNMEASURED on this machine (this is NOT a green; the mirror may be stale and nothing here can tell)" -f $shown) -ForegroundColor Yellow +} +else { + $c14Measured = $true + $hl = Get-MirrorHashes $mirLocal + $hh = Get-MirrorHashes $mirHub + if ($hl.Logic -ne $hh.Logic) { + Write-InformFlag 'scripts/stamp_verify.py' ` + ("stamp mirror DRIFT: local logic-sha {0} != hub logic-sha {1} (local {2} lines / hub {3} lines; raw-sha local {4} hub {5}) - the mirror no longer carries the hub canon, so a stamp verified here can pass while the hub would fail it" -f ` + $hl.Logic.Substring(0, 12), $hh.Logic.Substring(0, 12), $hl.Lines, $hh.Lines, $hl.Raw.Substring(0, 8), $hh.Raw.Substring(0, 8)) ` + 'BLOCKING NOTHING (INFORM): re-pull the hub copy over scripts/stamp_verify.py keeping ONLY the mirror-of header note, then re-run this detector' + $c14Flags++ + } + else { + $rawNote = if ($hl.Raw -eq $hh.Raw) { 'raw identical too' } else { ('raw differs only by the declared mirror-of note: local {0} / hub {1}' -f $hl.Raw.Substring(0, 8), $hh.Raw.Substring(0, 8)) } + Write-Host (" [ok] stamp mirror in sync: logic-sha {0} on both sides ({1})" -f $hl.Logic.Substring(0, 12), $rawNote) -ForegroundColor DarkGray + } +} +$c14Note = if ($c14Measured) { '' } else { ' -- MEASURED NOTHING (hub unreachable); a 0 here is "chua do duoc", not a green' } +Write-Host (" C14 stamp-mirror-drift flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c14Flags, $c14Note) -ForegroundColor DarkGray + +# --------------------------------------------------------------------------- +# C15 - V-5 encoding predicate (INFORM-only, NEW @S185; count SEPARATE, NOT in TOTAL) +# --------------------------------------------------------------------------- +# NAMING: script-local C-numbering (see C13 note). This implements S185 checklist C-11. +# +# WHY: the artifact roll-call machine (scripts/artifact-integrity.ps1) carries FOUR +# predicates - absent / empty / truncated / over-compressed - and is BLIND at the +# encoding level; the sub-w3 case proved it. The debt is on the books as "V-5 vi-tu +# ma-hoa CHUA CAM" in docs/governance/adap-reports/upgrade-pack-phased-bao-cao-cuoi.md:79 +# (section 9, "No co moc"), where the V5 line is FILLED BY HAND with no machine behind +# it. The spec already existed - one grep line, TWO ranks - and was only waiting for a +# home. This section is that home, i.e. the hand-filled line becomes a measured count. +# +# TWO RANKS, kept apart on purpose (they need different actions): +# rank-1 DATA LOSS - raw U+FFFD present (UTF-8 bytes EF BF BD). The original bytes +# are GONE; re-decoding cannot bring them back, only the source +# artifact can. Detected on BYTES, so it is decode-independent. +# rank-2 MOJIBAKE-ONLY - no U+FFFD, but double-encoding signatures present. Nothing is +# lost; a correct re-decode repairs it. +# rank-1 dominates when a file shows both: "lost" is the actionable fact. +# +# USE vs MENTION is enforced at the BYTE level and that is not a detail: a previous +# baseline counted a file that writes the ASCII token "<FFFD>" seven times as if it held +# seven damaged characters, then a later reader saw the count "drop" and went hunting a +# phantom file. Matching raw EF BF BD only cannot make that mistake - a doc that TALKS +# about U+FFFD in ASCII is invisible to it (proved by the boundary case in the harness). +# +# CORPUS: $GovMd PLUS .claude/workflows/runs/**/*.md. The run folders are excluded from +# $GovMd by the C4 self-line rule (they describe patterns), but that rule is about +# CONTENT patterns and this predicate reads BYTES, so the exclusion buys nothing here and +# costs everything: measured @S185, 7 of the 12 damaged files live exactly there. An +# auditor that skipped runs/ has already reported a false 0-hit once. +# +# The mojibake markers are built from CODE POINTS (same U helper as the VN tokens) so this +# .ps1 stays pure-ASCII on disk (gotcha #30) and so the detector never carries a literal +# specimen of the thing it hunts. +Write-Section 'C15 - V-5 encoding predicate (INFORM-only)' +$c15Flags = 0 +$c15Measured = $false + +# Double-encoding signatures. Chosen for precision over recall: each is a Latin-1 lead +# byte followed by a continuation-range char, a pair that legitimate Vietnamese/English +# prose does not produce. Recall is deliberately partial - this is a lowering net. +# NOTE ON THE PARENTHESES, which are load-bearing: each element must be wrapped so the +# '+' concatenation cannot run ACROSS the commas. Written without them, PowerShell folds +# the three patterns into ONE string and the array silently becomes Count=1 - a net that +# then matches nothing and reports a confident 0. That is not hypothetical: the first +# measurement taken while building this section was exactly that shape and returned +# "mojibake: 0 files" on a corpus that really holds 13. Verified by printing +# ($MojiRx.Count = 3) and each element's code points before trusting any number. +$MojiRx = @( + ((U @(0x00C3)) + '[' + (U @(0x00A0)) + '-' + (U @(0x00BF)) + ']'), + ((U @(0x00E2, 0x20AC))), + ((U @(0x00C4, 0x0091))) +) +# U+FFFD as its three UTF-8 bytes, seen through the Latin-1 view (EF BF BD). +$FFFD_BYTES = U @(0x00EF, 0x00BF, 0x00BD) + +$v5Files = @($GovMd) +$runsDirV5 = Join-Path $RepoRoot '.claude\workflows\runs' +if (Test-Path $runsDirV5) { + $v5Files += @(Get-ChildItem -Path $runsDirV5 -Recurse -Filter *.md -File -ErrorAction SilentlyContinue) +} +$v5Files = $v5Files | Where-Object { $_.FullName -notmatch '[\\/](bin|obj|node_modules)[\\/]' } + +if ($v5Files.Count -eq 0) { + Write-Host ' [skip] no .md in scope - encoding predicate measured NOTHING (not a green)' -ForegroundColor DarkGray +} +else { + $c15Measured = $true + $lossFiles = @(); $lossHits = 0 + $mojiFiles = @(); $mojiHits = 0 + foreach ($vf in $v5Files) { + $bytes = $null + try { $bytes = [System.IO.File]::ReadAllBytes($vf.FullName) } catch { $bytes = $null } + if ($null -eq $bytes) { continue } + # rank-1 counted on RAW BYTES via a Latin-1 view (codepage 28591 maps byte n -> + # char U+00n, 1:1 and lossless), so the needle EF BF BD is matched exactly as + # bytes while still using the fast .NET regex engine. A per-byte PowerShell loop + # measured the same thing but took ~18 s longer over this corpus. + $lat = [System.Text.Encoding]::GetEncoding(28591).GetString($bytes) + $n = ([regex]::Matches($lat, $FFFD_BYTES)).Count + if ($n -gt 0) { + $lossFiles += ("{0} x{1}" -f (Rel $vf.FullName), $n); $lossHits += $n + continue # rank-1 dominates: a lost-byte file is not re-classified as merely mojibake + } + $txt = [System.Text.Encoding]::UTF8.GetString($bytes) + $mm = 0 + foreach ($rx in $MojiRx) { $mm += ([regex]::Matches($txt, $rx)).Count } + if ($mm -gt 0) { $mojiFiles += ("{0} x{1}" -f (Rel $vf.FullName), $mm); $mojiHits += $mm } + } + + Write-Host (" V-5 measured over {0} .md (docs + .claude + workflows/runs) ; rank-1 data-loss: {1} file(s) / {2} hit(s) ; rank-2 mojibake-only: {3} file(s) / {4} hit(s)" -f ` + $v5Files.Count, $lossFiles.Count, $lossHits, $mojiFiles.Count, $mojiHits) + + if ($lossFiles.Count -gt 0) { + Write-InformFlag 'V-5 rank-1' ` + ("encoding DATA LOSS: {0} file(s) / {1} raw U+FFFD - the original bytes are gone and no re-decode recovers them; only the source artifact can" -f $lossFiles.Count, $lossHits) ` + 're-fetch each file from its source artifact (a re-save will NOT restore the lost characters); if a file is a frozen record, note the loss in it explicitly so it is not read as content' + $c15Flags++ + foreach ($lf in $lossFiles) { Write-Host (" [rank-1] {0}" -f $lf) -ForegroundColor DarkGray } + } + if ($mojiFiles.Count -gt 0) { + Write-InformFlag 'V-5 rank-2' ` + ("encoding MOJIBAKE-ONLY: {0} file(s) / {1} double-encoding signature(s) - nothing is lost, a correct re-decode repairs it" -f $mojiFiles.Count, $mojiHits) ` + 're-decode the file as UTF-8 and re-save; verify by re-running this detector (rank-2 must go to 0 without rank-1 rising)' + $c15Flags++ + foreach ($mf in $mojiFiles) { Write-Host (" [rank-2] {0}" -f $mf) -ForegroundColor DarkGray } + } + if ($lossFiles.Count -eq 0 -and $mojiFiles.Count -eq 0) { + Write-Host ' [ok] no encoding damage found in scope' -ForegroundColor DarkGray + } +} +$c15Note = if ($c15Measured) { '' } else { ' -- MEASURED NOTHING (skipped above); a 0 after a skip is not a green' } +Write-Host (" C15 V-5 encoding flags = {0} [INFORM-only, LOW, NOT folded into TOTAL baseline]{1}" -f $c15Flags, $c15Note) -ForegroundColor DarkGray + # --------------------------------------------------------------------------- # Summary + C4 self-exclusion audit (RUNTIME proof) # --------------------------------------------------------------------------- @@ -1965,7 +2395,7 @@ if ($selfInScan -eq 0 -and $leaked -eq 0) { Write-Host '' Write-Host ("TOTAL FLAGS: {0}" -f $script:FlagCount) -ForegroundColor Cyan -Write-Host ("INFORM-ONLY (new nets C6 cite-2-tier + H24-4 pending-flip + H24-5 counter-ancestor-classify + C9 hmw-width-drift + C11 h24-flag-form + C12 raw-engine-bypass): {0} - counted SEPARATELY, NOT in TOTAL above (anti-Goodhart, owner-set; fold+sev-raise is post-triage)" -f $script:InformCount) -ForegroundColor DarkGray +Write-Host ("INFORM-ONLY (new nets C6 cite-2-tier + H24-4 pending-flip + H24-5 counter-ancestor-classify + C9 hmw-width-drift + C11 h24-flag-form + C12 raw-engine-bypass + C13 carve-out-liveness + C14 stamp-mirror-drift + C15 V-5-encoding + the L7-bolt 'chua do duoc' lines): {0} - counted SEPARATELY, NOT in TOTAL above (anti-Goodhart, owner-set; fold+sev-raise is post-triage)" -f $script:InformCount) -ForegroundColor DarkGray Write-Host 'NOTE: DETECT-only lowering net. Exit 0 always (never fails build). FLAGs are advisory.' -ForegroundColor DarkGray exit 0 diff --git a/scripts/loi-hua-may-baseline.json b/scripts/loi-hua-may-baseline.json new file mode 100644 index 0000000..cc5f0fe --- /dev/null +++ b/scripts/loi-hua-may-baseline.json @@ -0,0 +1,190 @@ +{ + "note": "DENOMINATOR (mau-so) - liet ke TUONG MINH tung dong, KHONG phai output regex. Xem scripts/loi-hua-may-scan.ps1 .DESCRIPTION rang buoc (b). Entry disposition=TODO-classify VAN BI FLAG.", + "law": "2026-07-19-Governance-goi-chot-owner-nam-khoan khoan 4 (goi-chot:52)", + "scopeNote": "C6 corpus = docs/governance/*.md. Cham tay @S185 2026-08-09 tren cay snapshot dong bang.", + "dispositions": "history | caveat-honest | debt-open | design-note | draft-proposal | proof-elsewhere | violation-open | TODO-classify", + "violationOpenCount": 0, + "generatedAt": "2026-08-09", + "entries": [ + { + "file": "docs/governance/adap-upgrade-pack-tracking.md", + "fragment": "🔸 \"được cửa gọi\" ≠ \"fire vô điều kiện\". nhiều máy nằm sau cổng nhịp hoặc cổng overdue. nấc này", + "disposition": "caveat-honest", + "note": "tu thu hep claim: chi khai co duong ghi tu dong, khong khai chay moi phien" + }, + { + "file": "docs/governance/ctx-soft-memory-se-draft.md", + "fragment": "- 3 rào đầu tệp: (i) không chép lời anh (chỉ trỏ pause-\u003ck của context ) · (ii) cấm mọi biến-thể", + "disposition": "draft-proposal", + "note": "tep DRAFT chua wire; claim \"may doc ts quet _*\" chua neu path may" + }, + { + "file": "docs/governance/ctx-soft-memory-se-draft.md", + "fragment": "- chỗ cắm: /session-start (ghi mind block-0 @cuối bootstrap) · /pause §2.6 (+refresh) · /tiep §", + "disposition": "draft-proposal", + "note": "tep DRAFT chua wire; mo ta cho cam tuong lai" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "điểm-đóng-thật ⇒ tự-hỏi \"diary monitor có delta? dòng counter có in?\" (chờ hub canonical detect", + "disposition": "history", + "note": "dong so loi (ledger) + tu khai cho hub canonical detector" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "- 5-why: (1) người viết sổ vừa làm xong việc nên \"biết\" nó đã xong → (2) viết câu tổng-kết theo", + "disposition": "history", + "note": "tuong thuat 5-why cua mot su co da xay ra" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "- guard hiện có đã giữ: h2 5-trục fidelity-flag bắt được cả 3 ca trong cùng phiên chúng sinh ra", + "disposition": "history", + "note": "ghi ca DA quan sat duoc (3 ca cung phien) - past-tense, co bang chung" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "- what: 3 closeout liên-tiếp — s128 289ba96 20:57 · s129 295c70c 23:16 · s130 71757fc 00:26 — c", + "disposition": "history", + "note": "bien ban su co closeout S128-S130" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "- fix (không prod-bug — process): (đợt này) s131 mở session-end đúng nghi-thức đầu-tiên sau 3 l", + "disposition": "history", + "note": "bien ban fix cua chinh su co do" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "5-why → gốc: luật c1 tồn tại từ s138, viết bởi người đã cân nhắc từng tệp (wal được nêu làm ngo", + "disposition": "caveat-honest", + "note": "tu khai KHONG co may: \"0 cong may nao chan ghi trong cua-so do\"" + }, + { + "file": "docs/governance/error-ledger.md", + "fragment": "fix (2 vế, lỗi kép): (a) vá hành-vi — closeout sau: mọi ghi vào bề-mặt-đo xếp hàng sau verdict ", + "disposition": "debt-open", + "note": "no duoc ghi ro dang du-dinh: \"CHUA LAM, ghi thanh no: can mot may chan/canh bao\"" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "- c5 resolve-condition 🔴 — mỗi flag kèm resolve: \u003cđiều-kiện-gỡ-cờ . 2-strike anti-repeat = con", + "disposition": "design-note", + "note": "spec detector C5 + cau chong over-claim mechanized-2-strike" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "d6 — dò + nêu-cờ mọi thứ chạm prose/luật/con-trỏ-mục/thẩm-quyền/copy-chéo (3 detector c + monit", + "disposition": "design-note", + "note": "bang D6 mo ta ranh DO-only cua detector" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "honest nấc: h1 deterministic = executed-file + runtime-smoke s93 (chạy thật, 3-tier ok). h2 jud", + "disposition": "caveat-honest", + "note": "Honest nac: H2 judge = SCAFFOLD-only, tu tu choi nhan \"da do do-nho\"" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "honest nấc tổng §j (checklist 12 sàn 🔴): a 3/3 đạt (mechanized + runtime fault-inject 4/4) · b", + "disposition": "caveat-honest", + "note": "Honest nac tong §J - liet tung san dat/khong dat" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "- (v) honest nấc k.e: codify s110 + dogfood run-1 = chính lượt adopt này (spec-file 2026-07-11-", + "disposition": "caveat-honest", + "note": "Honest nac K.E: mechanized = 0, convention" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "l.c — ánh-xạ se (🟡 form + honest): se = convention (grep + phân-loại = kỷ-luật người, không cơ", + "disposition": "caveat-honest", + "note": "L.C tu khai SE = convention, KHONG co-che-hoa auto-fix" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "honest nấc §l: convention (không mechanized auto-fix — nhánh chỉ-dò per caveat \"auto-write luật", + "disposition": "caveat-honest", + "note": "Honest nac §L: mechanized THAT = CHI grep; phan-loai + sua = nguoi" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "m.c — run-loop 2-tầng (🔴 4-upgrade2 — 🟡 largely already-met honest): tầng-1 đo mỗi session-en", + "disposition": "proof-elsewhere", + "note": "neu 5 may bang STEM khong duoi .ps1 (memory-selfimprove-audit, mfe-eval, ...) - deu ton tai" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "- detector = lưới giảm-sót, không khoá-cứng — bắt @đầu/đóng-phiên (theo nhịp); giữa 2 nhịp có k", + "disposition": "caveat-honest", + "note": "tu khai detector = luoi giam-sot, co khoang-mu giua 2 nhip" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "- nấc dogfood: a2/a3/d4/d9/d11 = se runtime-mechanized sẵn (h11 = chuẩn-hoá). c1-c3 + b3 + memo", + "disposition": "caveat-honest", + "note": "phan-dinh executed-file KHAC da-chay-quan-sat" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "vì sao ranh nằm ở đây chứ không ở mức nghiêm trọng: nghiêm trọng đo hậu quả , còn mã thoát quyế", + "disposition": "design-note", + "note": "van ly-le ve ranh ma thoat (chu de W3b), khong phai claim nang-luc" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "cám dỗ ở đây là \"chặn có 1 cái thì cổng gần như vô dụng\" rồi nới tiêu chí cho nhiều cờ chặn hơn", + "disposition": "design-note", + "note": "canh bao Goodhart ve viec noi tieu chi cho nhieu co chan hon" + }, + { + "file": "docs/governance/harness-11-engine.md", + "fragment": "⇒ phân loại ở trên đã xong và có thể cắm , nhưng mã thoát chưa được đổi ở bất kỳ máy nào . mọi ", + "disposition": "caveat-honest", + "note": "tu khai ma thoat CHUA doi o bat ky may nao - moi may van exit 0" + }, + { + "file": "docs/governance/naming-standard.md", + "fragment": "- 🔴 điểm mù có chủ đích, phải biết: 112/719 tệp (15,6%) không thuộc bất kỳ họ nào — ghi chú, b", + "disposition": "caveat-honest", + "note": "diem mu CO CHU DICH 112/719 tep - tu khai gioi han" + }, + { + "file": "docs/governance/naming-standard.md", + "fragment": "⇒ chưa cần chủ dự án phán. nếu về sau ai muốn cho detectors:1109 kêu thật, lúc đó mới là xung đ", + "disposition": "design-note", + "note": "dieu kien tuong lai: neu ai muon cho detectors:1109 keu that" + }, + { + "file": "docs/governance/ritual-labels.md", + "fragment": "🔸 khai thiếu, không giấu: vế \"đánh giá lại điều kiện trên đĩa\" của nhãn tự ý bỏ hiện chưa có m", + "disposition": "caveat-honest", + "note": "tu khai CHUA CO MAY cho ve danh-gia-lai-dieu-kien" + }, + { + "file": "docs/governance/session-model-se-draft.md", + "fragment": "governance-detectors + h17 + m.b mỗi /session-start (skip light) per-l mở (giữa phiên chỉ khi n", + "disposition": "draft-proposal", + "note": "tep DRAFT chua wire; bang nhip do" + }, + { + "file": "docs/governance/session-model-se-draft.md", + "fragment": "hub §2 mô tả điểm dừng ghi delta vào \"một tệp ngữ-cảnh cộng-dồn của phiên\" . wal se là sổ mạch-", + "disposition": "design-note", + "note": "mo ta detector C5 cap 40 dong (neu bang ID trong engine doc)" + }, + { + "file": "docs/governance/vocab-alias-map.md", + "fragment": "một session-log viết \"two-tier\" hồi s60 là đúng sự thật lịch sử — nó phản ánh mô hình còn hiệu ", + "disposition": "design-note", + "note": "mo ta hanh vi detector C3 voi file dong bang" + }, + { + "file": "docs/governance/vocab-alias-map.md", + "fragment": "về việc detector có \"im\" sau khi tạo file này không", + "disposition": "design-note", + "note": "tieu de muc ban ve viec detector co im khong" + } + ] +} diff --git a/scripts/loi-hua-may-scan.ps1 b/scripts/loi-hua-may-scan.ps1 new file mode 100644 index 0000000..31fbac3 --- /dev/null +++ b/scripts/loi-hua-may-scan.ps1 @@ -0,0 +1,591 @@ +<# +.SYNOPSIS + loi-hua-may-scan.ps1 - C-12 machine-promise scanner (khoan 4.4, broadcast + 2026-07-19-Governance-goi-chot-owner-nam-khoan). + +.DESCRIPTION + Class scanned: sentences that ASSERT a machine capability ("X chan/quet/bat/ + dam-nhiem Y") in governance docs. Law (goi-chot:52): such a sentence MUST carry + existence-proof AT THE POINT OF CLAIM = {machine path + runnable command + + test/positive-control}. Missing any piece => the sentence MUST be written in the + intent form ("se build - CHUA co may"). Writing it in the have-it form is banned. + + Until today this gate was HUMAN-ONLY: both hub (goi-chot:54) and SE + (adap-report 4.4 + runs/2026-07-22-S144-adap-dot-11/C6-cua-loi-hua-may.md:60) + declared the automatic scanner as INTENT, not existing. This script is that + scanner. It is DETECT-and-FLAG-only: it never edits a file, exit code is + always 0 in scan mode (teeth live in -SelfTest, which exits 1 on failure). + + FOUR design constraints inherited from C6 (violating any = the machine is worse + than nothing, because a green scan would then mean "not measured"): + + (b) REGEX IS NOT THE DENOMINATOR. C6 measured: literal "may se" -> 0 hits + (blind: a fault-injected fake promise stayed green), loose regex -> 19 hits + with 4/19 = 21% false positives. Regex here is a CANDIDATE SIEVE only; the + denominator is the ENUMERATED baseline file (loi-hua-may-baseline.json). + (c) use ORTHOGONAL-TO mention, split by ENCLOSURE (not by shape, not by + charset). A line that DEFINES the rule or QUOTES an anti-pattern is not a + violation. Enclosure = fenced code block, blockquote, or quote-pair + around the verb. Same class SE paid for 3 generations in one wave (S123 + citation-trap). + (d) MEASURE THE GATE, NOT THE SWEEP. goi-chot:53 - "chan tu luc VIET". + This script reports lines NOT in the baseline (i.e. written after the gate + went in). It NEVER claims the corpus is clean. + (e) BACKFILL IS TIME-BOXED. goi-chot:55 floor covers governance docs that are + NEW. Legacy lines live in the baseline with an explicit disposition. + + FP-guard, tested: Vietnamese "bat buoc" = MANDATORY, not CATCH. The catch verb + carries a negative lookahead so it can never swallow it. This exact substring + bug produced the 21% inflation in C6 and is control #2 of -SelfTest. + + ASCII-only script body (gotcha #30): PowerShell 5.1 decodes a BOM-less .ps1 with + the system ANSI codepage under -File, which mojibakes any inline Vietnamese + literal so it stops matching correctly-decoded UTF-8 content. Every Vietnamese + token is therefore built from Unicode code points at RUNTIME. + +.PARAMETER RepoRoot + Repo root. Default = one level up from scripts/. Point it at a COPY of the tree + to fault-inject without touching the real repo. + +.PARAMETER BaselinePath + Enumerated denominator. Default = scripts/loi-hua-may-baseline.json. + +.PARAMETER All + Widen scope from the C6 corpus (docs/governance/*.md) to the wider governance + surface (rules/CLAUDE/commands/skills/gotchas). + +.PARAMETER EmitBaseline + Print the current candidate set as baseline JSON with disposition + "TODO-classify". Entries left at TODO-classify are STILL FLAGGED (LOW) - so + emitting a baseline can never silence anything on its own. + +.PARAMETER SelfTest + Run the 7 controls on a throwaway tree under $env:TEMP. Exits 1 if any control + fails. Nothing is written inside the repo. + +.EXAMPLE + powershell.exe -ExecutionPolicy Bypass -File scripts/loi-hua-may-scan.ps1 +.EXAMPLE + powershell.exe -ExecutionPolicy Bypass -File scripts/loi-hua-may-scan.ps1 -SelfTest +#> +param( + [string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path, + [string]$BaselinePath, + [switch]$All, + [switch]$EmitBaseline, + [switch]$SelfTest, + [switch]$NoProximity # audit hatch: run the pre-proximity sieve so anyone can + # diff the two flag sets and check what the rule removed +) + +$ErrorActionPreference = 'Continue' + +# --------------------------------------------------------------------------- +# Unicode-token builder (gotcha #30 mojibake guard) - see .DESCRIPTION. +# --------------------------------------------------------------------------- +function U { param([int[]]$cp) -join ($cp | ForEach-Object { [char]$_ }) } + +$T_CHAN = U @(0x63, 0x68, 0x1EB7, 0x6E) # chan (block) +$T_QUET = U @(0x71, 0x75, 0xE9, 0x74) # quet (scan) +$T_BAT = U @(0x62, 0x1EAF, 0x74) # bat (catch) +$T_BUOC = U @(0x62, 0x75, 0x1ED9, 0x63) # buoc (in "bat buoc" = mandatory) +$T_DAM = U @(0x111, 0x1EA3, 0x6D) # dam (dam-nhiem / dam bao) +$T_CANH = U @(0x63, 0x61, 0x6E, 0x68) # canh (watch) +$T_TUDONG= U @(0x74, 0x1EF1, 0x20, 0x111, 0x1ED9, 0x6E, 0x67) # tu dong (automatic) +$T_MAY = U @(0x6D, 0xE1, 0x79) # may (machine) +$T_LUOI = U @(0x6C, 0x1B0, 0x1EDB, 0x69) # luoi (net) +$T_SE = U @(0x73, 0x1EBD) # se (will) - fixtures only + +# --------------------------------------------------------------------------- +# Stage 1 - CANDIDATE SIEVE (explicitly NOT the denominator; see constraint b) +# A candidate = line carrying a MACHINE NOUN and a CAPABILITY VERB. +# --------------------------------------------------------------------------- +$NounPattern = '(?i)(detector|guard|hook|script|checker|scanner|\.ps1|\.py\b|' + + [regex]::Escape($T_MAY) + '|' + [regex]::Escape($T_LUOI) + ')' + +# "bat" carries a negative lookahead so "bat buoc" (mandatory) can never be read +# as "bat" (catch). This is the exact 21% inflation bug from C6, control #2. +# The separator class is [\s-]* , NOT \s* : this repo writes the word BOTH ways +# ("bat buoc" and "bat-buoc"). A \s*-only guard leaks on every hyphenated +# occurrence - found live at fable-real-runbook.md:571, where only the proximity +# rule was accidentally masking it. Controls #2 and #9 pin both spellings. +$VerbPattern = '(?i)(' + + [regex]::Escape($T_CHAN) + '|' + + [regex]::Escape($T_QUET) + '|' + + [regex]::Escape($T_BAT) + '(?![\s-]*' + [regex]::Escape($T_BUOC) + ')|' + + [regex]::Escape($T_DAM) + '|' + + [regex]::Escape($T_CANH) + '|' + + [regex]::Escape($T_TUDONG) + '|enforce|detect)' + +# Stage 1b - PROXIMITY. A capability assertion keeps its subject next to its +# verb ("detector X chan Y"). Without this, any long table row or narrative +# paragraph that happens to contain a machine noun in one cell and a verb 300 +# chars later in another cell is swept in - which is how the C6 loose regex got +# to 21% false positives. The line is therefore split on the markdown cell +# separator and the pair must co-occur inside ONE chunk, within MaxGap chars. +# Verified against the real corpus by diffing the flag set before/after and +# reading every line that dropped out (see run artifact) - the rule removes +# unrelated co-occurrences, not witnesses. +$ProxMaxGap = 80 + +# --------------------------------------------------------------------------- +# Stage 3 - EXISTENCE-PROOF tokens ("ma nao lam viec do?" answered inline). +# --------------------------------------------------------------------------- +$PathPattern = '(?i)([\w./-]+\.(?:ps1|py|js|sh|yml|yaml))' +$CmdPattern = '(?i)(powershell\.exe|pwsh|dotnet\s|node\s|python\s|npm\s|git\s)' + +# --------------------------------------------------------------------------- +# C4-style self-line exclusion: files that DESCRIBE the pattern must never be +# scanned for it, or the detector flags itself (and, via quotation, its own +# children - the S123 citation-trap went 3 generations in one wave). +# --------------------------------------------------------------------------- +$SelfExclude = @( + 'scripts/loi-hua-may-scan.ps1', + 'scripts/loi-hua-may-baseline.json', + '.claude/workflows/runs/' +) + +function Rel($full) { + $r = $full + if ($full.StartsWith($RepoRoot, [StringComparison]::OrdinalIgnoreCase)) { + $r = $full.Substring($RepoRoot.Length).TrimStart('\', '/') + } + return ($r -replace '\\', '/') +} + +function Test-SelfExcluded($relPath) { + foreach ($x in $SelfExclude) { if ($relPath -like ('*' + $x + '*')) { return $true } } + return $false +} + +# --------------------------------------------------------------------------- +# Scope. Default = the C6 corpus (docs/governance top level) so the number this +# script prints is comparable with the C6 measurement. -All widens it. +# adap-reports/ and adap-requests/ stay out by default: they are reports ABOUT +# hub broadcasts and are quotation-heavy by construction (mention, not use). +# --------------------------------------------------------------------------- +function Get-ScopeFiles { + param([string]$Root, [switch]$Wide) + $files = @() + $gov = Join-Path $Root 'docs/governance' + if (Test-Path $gov) { + $files += Get-ChildItem -LiteralPath $gov -Filter '*.md' -File -ErrorAction SilentlyContinue + } + if ($Wide) { + foreach ($p in @('docs/rules.md', 'docs/gotchas.md', 'CLAUDE.md', 'docs/CLAUDE.md')) { + $f = Join-Path $Root $p + if (Test-Path $f) { $files += Get-Item -LiteralPath $f } + } + $cmd = Join-Path $Root '.claude/commands' + if (Test-Path $cmd) { + $files += Get-ChildItem -LiteralPath $cmd -Filter '*.md' -File -Recurse -ErrorAction SilentlyContinue + } + $sk = Join-Path $Root '.claude/skills' + if (Test-Path $sk) { + $files += Get-ChildItem -LiteralPath $sk -Filter 'SKILL.md' -File -Recurse -ErrorAction SilentlyContinue + } + } + return ($files | Where-Object { -not (Test-SelfExcluded (Rel $_.FullName)) }) +} + +# --------------------------------------------------------------------------- +# Stage 2 - use ORTHOGONAL-TO mention, by ENCLOSURE (constraint c). +# Returns the mention reason, or $null when the line is a genuine ASSERTION. +# m1 fenced code block m2 blockquote m3 verb sits inside a quote pair +# --------------------------------------------------------------------------- +function Get-EnclosureSpans { + param([string]$Line) + $spans = @() + # Straight double quote, curly quotes, guillemets, backtick code span. + $pairs = @( + @{ open = [char]0x0022; close = [char]0x0022 }, + @{ open = [char]0x201C; close = [char]0x201D }, + @{ open = [char]0x00AB; close = [char]0x00BB }, + @{ open = [char]0x2018; close = [char]0x2019 }, + @{ open = [char]0x0060; close = [char]0x0060 } + ) + foreach ($p in $pairs) { + $i = 0 + while ($true) { + $s = $Line.IndexOf([string]$p.open, $i) + if ($s -lt 0) { break } + $e = $Line.IndexOf([string]$p.close, $s + 1) + if ($e -lt 0) { break } + $spans += , @($s, $e) + $i = $e + 1 + } + } + return $spans +} + +function Get-MentionReason { + param([string]$Line, [bool]$InFence) + if ($InFence) { return 'm1-code-fence' } + if ($Line -match '^\s{0,3}>') { return 'm2-blockquote' } + $m = [regex]::Match($Line, $VerbPattern) + if ($m.Success) { + foreach ($sp in (Get-EnclosureSpans $Line)) { + if ($m.Index -gt $sp[0] -and $m.Index -lt $sp[1]) { return 'm3-quoted' } + } + } + return $null +} + +# --------------------------------------------------------------------------- +# Stage 3 - proof AT THE POINT OF CLAIM ("tai cho", goi-chot:52). +# Returns: 'proof-ok' | 'proof-dead:<path>' | $null (no proof at all). +# +# Window rule, and why it is this narrow: the first cut used +/-2 lines and +# -SelfTest failed 2/8 - adjacent claims stole each other's proof (a promise +# inherited the proof of the bullet above it, and a clean line inherited the +# DEAD path of the bullet above it, i.e. contamination in both directions). +# "Tai cho" therefore means: the claim's own line, the line directly under it +# (sub-bullet / wrapped continuation), and the line directly above ONLY when +# that line is not itself a claim - proof already spoken for by another +# assertion is not proof of this one. +# +# 'proof-dead' (HIGH) is raised ONLY from the claim's OWN line: citing a machine +# that does not exist on disk is the sharpest failure of this class, but a dead +# path on a NEIGHBOURING line belongs to the neighbour, not here. +# --------------------------------------------------------------------------- +function Test-IsCandidate { + param([string]$Line) + if ($Line -notmatch $NounPattern) { return $false } + if ($Line -notmatch $VerbPattern) { return $false } + if ($NoProximity) { return $true } + foreach ($chunk in ($Line -split '\|')) { + $n = [regex]::Match($chunk, $NounPattern) + if (-not $n.Success) { continue } + foreach ($v in [regex]::Matches($chunk, $VerbPattern)) { + foreach ($nn in [regex]::Matches($chunk, $NounPattern)) { + if ([Math]::Abs($v.Index - $nn.Index) -le $ProxMaxGap) { return $true } + } + } + } + return $false +} + +# Machine index: every runnable file under scripts/ and .claude/. This repo +# routinely names a machine WITHOUT its directory (`governance-detectors.ps1`, +# `hmw.js:171-186`), and such a citation does answer the reviewer's one question +# ("ma nao lam viec do?"). A bare name that RESOLVES therefore counts as proof; +# a bare name that resolves nowhere is NOT escalated to HIGH (it may be a generic +# word), it simply fails to prove anything. +function New-MachineIndex { + param([string]$Root) + $set = @{} + foreach ($d in @('scripts', '.claude')) { + $p = Join-Path $Root $d + if (-not (Test-Path $p)) { continue } + Get-ChildItem -Path $p -Recurse -File -ErrorAction SilentlyContinue | + Where-Object { $_.FullName -notmatch '[\\/]node_modules[\\/]' -and + @('.ps1', '.py', '.js', '.sh') -contains $_.Extension.ToLowerInvariant() } | + ForEach-Object { $set[$_.Name.ToLowerInvariant()] = $true } + } + return $set +} + +function Get-PathVerdict { + param([string]$Line, [string]$Root, $Index) + $dead = @() + foreach ($pm in [regex]::Matches($Line, $PathPattern)) { + # Trim wrappers only. NEVER TrimStart('.') - it eats the leading dot of + # ".claude/hooks/..." and turns a live path into a phantom dead one. + # That exact bug produced this scanner's first HIGH flag, on a path that + # exists (naming-standard.md:50 -> .claude/hooks/wal-flush.ps1). + $cand = $pm.Groups[1].Value.Trim('`', '(', ')').TrimEnd(',', '.', ';', ':') + if ($cand -notmatch '[\\/]') { + # bare filename: proof only if it resolves to a real machine + if ($Index -and $Index.ContainsKey($cand.ToLowerInvariant())) { return 'ok' } + continue + } + $full = Join-Path $Root ($cand -replace '/', '\') + if (Test-Path -LiteralPath $full) { return 'ok' } + if ($Index -and $Index.ContainsKey(([System.IO.Path]::GetFileName($cand)).ToLowerInvariant())) { + return 'ok' # path stale but the machine exists elsewhere -> not a phantom + } + $dead += $cand + } + if ($dead.Count -gt 0) { return ('dead:' + $dead[0]) } + return $null +} + +function Get-ProofState { + param([string[]]$Lines, [int]$Idx, [string]$Root, $Index) + # (1) own line + if ($Lines[$Idx] -match $CmdPattern) { return 'proof-ok' } + $own = Get-PathVerdict -Line $Lines[$Idx] -Root $Root -Index $Index + if ($own -eq 'ok') { return 'proof-ok' } + + # (2) neighbours - proof only, never dead-path escalation + $neighbours = @() + if ($Idx + 1 -le $Lines.Count - 1) { $neighbours += ($Idx + 1) } + if ($Idx - 1 -ge 0 -and -not (Test-IsCandidate $Lines[$Idx - 1])) { $neighbours += ($Idx - 1) } + foreach ($n in $neighbours) { + if ($Lines[$n] -match $CmdPattern) { return 'proof-ok' } + if ((Get-PathVerdict -Line $Lines[$n] -Root $Root -Index $Index) -eq 'ok') { return 'proof-ok' } + } + + if ($own) { return ('proof-' + $own) } # dead:<path> on the claim's own line + return $null +} + +# --------------------------------------------------------------------------- +# Baseline (THE DENOMINATOR - enumerated by hand, constraint b). +# Matching is by NORMALISED TEXT FRAGMENT, never by line number: line numbers +# drift on every edit above them, and a drifting anchor would silently re-flag +# (or silently silence) the wrong line. +# --------------------------------------------------------------------------- +function Get-NormText { + param([string]$s) + $t = $s -replace '[`*_>#|]', ' ' + $t = $t -replace '\s+', ' ' + return $t.Trim().ToLowerInvariant() +} + +function Load-Baseline { + param([string]$Path) + $result = @{ entries = @(); loaded = $false; rejected = @() } + if (-not $Path -or -not (Test-Path -LiteralPath $Path)) { return $result } + try { + $raw = Get-Content -LiteralPath $Path -Raw -Encoding UTF8 | ConvertFrom-Json + } catch { + Write-Host ("[LOI-HUA-MAY] WARN | baseline unreadable: " + $Path) -ForegroundColor Yellow + return $result + } + $result.loaded = $true + foreach ($e in $raw.entries) { + # Teeth: a too-short fragment would match half the corpus and silence it. + if (-not $e.fragment -or $e.fragment.Length -lt 25) { + $result.rejected += $e + continue + } + $result.entries += [pscustomobject]@{ + file = $e.file + fragment = (Get-NormText $e.fragment) + disposition = $e.disposition + note = $e.note + } + } + return $result +} + +function Find-BaselineEntry { + param($Baseline, [string]$RelFile, [string]$NormLine) + foreach ($e in $Baseline.entries) { + if ($e.file -ne $RelFile) { continue } + if ($NormLine.Contains($e.fragment)) { return $e } + } + return $null +} + +# --------------------------------------------------------------------------- +# Core scan. +# --------------------------------------------------------------------------- +function Invoke-Scan { + param([string]$Root, $Files, $Baseline) + $out = @() + $index = New-MachineIndex -Root $Root + foreach ($f in $Files) { + $rel = Rel $f.FullName + $lines = @(Get-Content -LiteralPath $f.FullName -Encoding UTF8 -ErrorAction SilentlyContinue) + $inFence = $false + for ($i = 0; $i -lt $lines.Count; $i++) { + $line = $lines[$i] + if ($line -match '^\s*```') { $inFence = -not $inFence; continue } + if (-not (Test-IsCandidate $line)) { continue } + + $mention = Get-MentionReason -Line $line -InFence $inFence + if ($mention) { + $out += [pscustomobject]@{ File = $rel; Line = ($i + 1); Text = $line + Verdict = 'mention'; Severity = 'INFO'; Reason = $mention } + continue + } + + $proof = Get-ProofState -Lines $lines -Idx $i -Root $Root -Index $index + if ($proof -eq 'proof-ok') { + $out += [pscustomobject]@{ File = $rel; Line = ($i + 1); Text = $line + Verdict = 'proved'; Severity = 'INFO'; Reason = 'proof-ok' } + continue + } + if ($proof -and $proof.StartsWith('proof-dead')) { + $out += [pscustomobject]@{ File = $rel; Line = ($i + 1); Text = $line + Verdict = 'flag'; Severity = 'HIGH'; Reason = $proof } + continue + } + + $known = Find-BaselineEntry -Baseline $Baseline -RelFile $rel -NormLine (Get-NormText $line) + if ($known -and $known.disposition -ne 'TODO-classify') { + $out += [pscustomobject]@{ File = $rel; Line = ($i + 1); Text = $line + Verdict = 'baseline'; Severity = 'INFO'; Reason = ('baseline:' + $known.disposition) } + continue + } + if ($known) { + $out += [pscustomobject]@{ File = $rel; Line = ($i + 1); Text = $line + Verdict = 'flag'; Severity = 'LOW'; Reason = 'baseline-TODO-classify' } + continue + } + $out += [pscustomobject]@{ File = $rel; Line = ($i + 1); Text = $line + Verdict = 'flag'; Severity = 'MED'; Reason = 'no-proof-not-in-baseline' } + } + } + return $out +} + +# --------------------------------------------------------------------------- +# -SelfTest : 7 controls on a throwaway tree. Positive controls prove the net +# catches; negative controls prove it does not catch what it must not. A net +# that only ever passes happy-path proves nothing (house rule: +# feedback_faultinjection_proves_teeth). +# --------------------------------------------------------------------------- +function Invoke-SelfTest { + $tmp = Join-Path $env:TEMP ('loi-hua-may-selftest-' + [guid]::NewGuid().ToString('N').Substring(0, 8)) + $gov = Join-Path $tmp 'docs\governance' + $scr = Join-Path $tmp 'scripts' + New-Item -ItemType Directory -Path $gov -Force | Out-Null + New-Item -ItemType Directory -Path $scr -Force | Out-Null + Set-Content -LiteralPath (Join-Path $scr 'real-machine.ps1') -Value '# fixture' -Encoding UTF8 + + $q = [char]0x0022 + $fx = @() + $fx += '# fixture' + $fx += ('C1 detector ' + $T_CHAN + ' moi cau hua sai trong doc governance.') # 1 must flag MED + $fx += ('C2 3 GAP-guard ' + $T_BAT + ' ' + $T_BUOC + ' CA 2 mode - pin de stamp co nghia.') # 2 must NOT flag + $fx += ('> C3 luat: cau dang ' + $q + $T_MAY + ' ' + $T_SE + ' ' + $T_CHAN + ' X' + $q + ' phai co existence-proof.') # 3 must NOT + $fx += ('C4 detector ' + $T_QUET + ' drift: `scripts/real-machine.ps1` chay duoc.') # 4 must NOT flag + $fx += ('C5 detector ' + $T_QUET + ' drift: `scripts/khong-ton-tai.ps1` chay duoc.') # 5 must flag HIGH + $fx += 'C6 doan van thuong khong nhac may moc gi ca, chi la mo ta quy trinh.' # 6 must NOT flag + $fx += ('C7 legacy detector ' + $T_CHAN + ' cau hua cu tu truoc khi cong nay duoc cai dat.') # 7 baseline-suppressed + $fx += ('C9 RETURN guard ' + $T_BAT + '-' + $T_BUOC + ' theo SCHEMA - dau noi la gach ngang.') # 9 must NOT flag + $fx += ('C10 detector ' + $T_QUET + ' drift: `real-machine.ps1` - ten tran khong kem thu muc.') # 10 must NOT flag + $fx += ('C11 detector ' + $T_QUET + ' drift: `khong-he-ton-tai.ps1` - ten tran khong resolve.') # 11 must flag MED + Set-Content -LiteralPath (Join-Path $gov 'selftest.md') -Value $fx -Encoding UTF8 + + $blPath = Join-Path $tmp 'baseline.json' + $frag = ('legacy detector ' + $T_CHAN + ' cau hua cu tu truoc khi cong nay') + $bl = [pscustomobject]@{ + note = 'selftest fixture baseline' + entries = @([pscustomobject]@{ file = 'docs/governance/selftest.md'; fragment = $frag + disposition = 'legacy-pre-gate'; note = 'fixture' }) + } + Set-Content -LiteralPath $blPath -Value ($bl | ConvertTo-Json -Depth 5) -Encoding UTF8 + + $script:RepoRoot = $tmp + $files = Get-ScopeFiles -Root $tmp + $res = Invoke-Scan -Root $tmp -Files $files -Baseline (Load-Baseline $blPath) + + function Get-Row($tag) { return ($res | Where-Object { $_.Text -match ('^' + $tag + '\b') } | Select-Object -First 1) } + function Get-QuotedRow($tag) { return ($res | Where-Object { $_.Text -match $tag } | Select-Object -First 1) } + + $checks = @() + $r1 = Get-Row 'C1'; $checks += @{ n = 'C1 positive-control: cau hua khong proof' + ok = ($r1 -and $r1.Verdict -eq 'flag' -and $r1.Severity -eq 'MED'); got = $r1 } + $r2 = Get-Row 'C2'; $checks += @{ n = 'C2 FP-guard: bat-buoc KHONG duoc doc thanh bat' + ok = (-not $r2); got = $r2 } + $r3 = Get-QuotedRow 'C3'; $checks += @{ n = 'C3 use/mention: dong dinh-nghia-luat trong blockquote' + ok = ($r3 -and $r3.Verdict -eq 'mention'); got = $r3 } + $r4 = Get-Row 'C4'; $checks += @{ n = 'C4 proof-ok: script duoc cite CO tren dia' + ok = ($r4 -and $r4.Verdict -eq 'proved'); got = $r4 } + $r5 = Get-Row 'C5'; $checks += @{ n = 'C5 positive-control: cite script KHONG ton tai' + ok = ($r5 -and $r5.Verdict -eq 'flag' -and $r5.Severity -eq 'HIGH'); got = $r5 } + $r6 = Get-Row 'C6'; $checks += @{ n = 'C6 negative-control: van thuong khong bi hut vao' + ok = (-not $r6); got = $r6 } + $r7 = Get-Row 'C7'; $checks += @{ n = 'C7 baseline: dong legacy da liet ke -> khong flag' + ok = ($r7 -and $r7.Verdict -eq 'baseline'); got = $r7 } + + # C8: anti-Goodhart - the same line with disposition TODO-classify must STILL flag. + $bl2 = [pscustomobject]@{ note = 'todo'; entries = @([pscustomobject]@{ + file = 'docs/governance/selftest.md'; fragment = $frag; disposition = 'TODO-classify'; note = 'x' }) } + $bl2Path = Join-Path $tmp 'baseline-todo.json' + Set-Content -LiteralPath $bl2Path -Value ($bl2 | ConvertTo-Json -Depth 5) -Encoding UTF8 + $res2 = Invoke-Scan -Root $tmp -Files $files -Baseline (Load-Baseline $bl2Path) + $r8 = $res2 | Where-Object { $_.Text -match '^C7\b' } | Select-Object -First 1 + $checks += @{ n = 'C8 anti-Goodhart: TODO-classify KHONG duoc lam tat den' + ok = ($r8 -and $r8.Verdict -eq 'flag'); got = $r8 } + $r9 = Get-Row 'C9'; $checks += @{ n = 'C9 FP-guard: bat-buoc CO GACH NGANG cung khong duoc doc thanh bat' + ok = (-not $r9); got = $r9 } + $r10 = Get-Row 'C10'; $checks += @{ n = 'C10 proof: ten may TRAN resolve duoc = da tra loi "ma nao lam viec do"' + ok = ($r10 -and $r10.Verdict -eq 'proved'); got = $r10 } + $r11 = Get-Row 'C11'; $checks += @{ n = 'C11 positive-control: ten may TRAN khong resolve -> van flag' + ok = ($r11 -and $r11.Verdict -eq 'flag'); got = $r11 } + + Write-Host '' + Write-Host '===== SELF-TEST (tree: ' -NoNewline -ForegroundColor Cyan + Write-Host $tmp -NoNewline; Write-Host ') =====' -ForegroundColor Cyan + $fail = 0 + foreach ($c in $checks) { + if ($c.ok) { + Write-Host (' PASS ' + $c.n) -ForegroundColor Green + } else { + $fail++ + $g = 'ABSENT' + if ($c.got) { $g = ($c.got.Verdict + '/' + $c.got.Severity + '/' + $c.got.Reason) } + Write-Host (' FAIL ' + $c.n + ' [got: ' + $g + ']') -ForegroundColor Red + } + } + Write-Host '' + Write-Host ('SELF-TEST: ' + ($checks.Count - $fail) + '/' + $checks.Count + ' PASS') -ForegroundColor (& { if ($fail) { 'Red' } else { 'Green' } }) + Remove-Item -LiteralPath $tmp -Recurse -Force -ErrorAction SilentlyContinue + if ($fail) { exit 1 } + exit 0 +} + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- +if ($SelfTest) { Invoke-SelfTest } + +if (-not $BaselinePath) { $BaselinePath = Join-Path $PSScriptRoot 'loi-hua-may-baseline.json' } +$baseline = Load-Baseline $BaselinePath +$files = Get-ScopeFiles -Root $RepoRoot -Wide:$All +$res = Invoke-Scan -Root $RepoRoot -Files $files -Baseline $baseline + +if ($EmitBaseline) { + $entries = @() + foreach ($r in ($res | Where-Object { $_.Verdict -eq 'flag' })) { + $norm = (Get-NormText $r.Text) + $len = [Math]::Min(90, $norm.Length) + $entries += [pscustomobject]@{ file = $r.File; fragment = $norm.Substring(0, $len) + disposition = 'TODO-classify'; note = ('auto-emitted line ' + $r.Line) } + } + ([pscustomobject]@{ + note = 'DENOMINATOR (enumerated by hand). TODO-classify still flags - emitting cannot silence.' + scope = ($files | ForEach-Object { Rel $_.FullName }) + generatedAt = (Get-Date -Format 'yyyy-MM-dd') + entries = $entries + } | ConvertTo-Json -Depth 6) + exit 0 +} + +$flags = @($res | Where-Object { $_.Verdict -eq 'flag' }) +$mention = @($res | Where-Object { $_.Verdict -eq 'mention' }) +$proved = @($res | Where-Object { $_.Verdict -eq 'proved' }) +$known = @($res | Where-Object { $_.Verdict -eq 'baseline' }) + +Write-Host '' +Write-Host '===== LOI-HUA-MAY (khoan 4.4) =====' -ForegroundColor Cyan +Write-Host ('scope : ' + $files.Count + ' file' + $(if ($All) { ' (-All wide)' } else { ' (C6 corpus: docs/governance/*.md)' })) +Write-Host ('baseline : ' + $(if ($baseline.loaded) { ($baseline.entries.Count.ToString() + ' entry - ' + (Rel $BaselinePath)) } else { 'KHONG LOAD DUOC - moi dong deu se bi flag' })) +if ($baseline.rejected.Count -gt 0) { + Write-Host (' WARN : ' + $baseline.rejected.Count + ' entry bi loai (fragment < 25 ky tu, qua ngan -> se lam tat den nham)') -ForegroundColor Yellow +} +Write-Host ('candidate : ' + $res.Count + ' -> mention ' + $mention.Count + ' | proved ' + $proved.Count + ' | baseline ' + $known.Count + ' | FLAG ' + $flags.Count) +# The baseline total is printed BROKEN DOWN, never as one number: "30 known" would +# read as 30 settled lines, while "debt-open 1 / draft-proposal 3" keeps the debt +# visible. Same reason the emitter cannot self-classify. +if ($known.Count -gt 0) { + $bd = $known | Group-Object Reason | Sort-Object Count -Descending | + ForEach-Object { ($_.Name -replace '^baseline:', '') + ' ' + $_.Count } + Write-Host (' breakdown: ' + ($bd -join ' | ')) +} +Write-Host '' +foreach ($r in ($flags | Sort-Object Severity, File, Line)) { + $color = 'Yellow'; if ($r.Severity -eq 'HIGH') { $color = 'Red' }; if ($r.Severity -eq 'LOW') { $color = 'Gray' } + $txt = $r.Text.Trim(); if ($txt.Length -gt 120) { $txt = $txt.Substring(0, 120) + '...' } + Write-Host ("[LOI-HUA-MAY] {0,-4} | {1}:{2} | {3} | {4}" -f $r.Severity, $r.File, $r.Line, $r.Reason, $txt) -ForegroundColor $color + Write-Host (" resolve: them existence-proof tai cho {path may + lenh + test}, HOAC viet lai dang du-dinh, HOAC ghi vao baseline kem disposition") -ForegroundColor DarkGray +} +Write-Host '' +Write-Host 'DOC DUNG CON SO NAY: day la so dong CHUA-CO-PROOF va CHUA-CO-TRONG-BASELINE.' -ForegroundColor DarkCyan +Write-Host 'FLAG 0 != corpus sach. Cua nay do GATE (dong viet moi), khong do SWEEP (goi-chot:53).' -ForegroundColor DarkCyan +exit 0 diff --git a/scripts/nhip-no-probe.ps1 b/scripts/nhip-no-probe.ps1 index 39ee1cb..2950489 100644 --- a/scripts/nhip-no-probe.ps1 +++ b/scripts/nhip-no-probe.ps1 @@ -18,8 +18,9 @@ IN-LINE (no assumed default, not swallowed into the generic probe-loi) - keeps the no-default signal H24-2 depends on. - Output contract - EXACTLY one line: - NHIP-NO: kiem light a/e deep b/f <ok|OVERDUE:light|deep> | tran-bo-nho x over-cap | run-chua-gom y | pull-cach N ngay + Output contract - EXACTLY one line (5 ve - ve-5 so-yc them @S181; doc-fix S185 theo harness-audit §8: + comment nay tung khai 4 ve trong khi code :264 in 5 - doc-stale lop "chuoi trang-thai noi sai su that"): + NHIP-NO: kiem light a/e deep b/f <ok|OVERDUE:light|deep> | tran-bo-nho x over-cap | run-chua-gom y | pull-cach N ngay | so-yc treo T / nhac2+ K * kiem = audit cadence: a = counter - last_audit.light_at_counter (light debt), e = h24_cadence.light_every ; b/f = deep pair. OVERDUE when a>=e or b>=f. * tran-bo-nho = x agent-memory/*/MEMORY.md files whose (Get-Item).Length exceeds diff --git a/scripts/tien-kiem-cua.ps1 b/scripts/tien-kiem-cua.ps1 index a2957c2..d31545d 100644 --- a/scripts/tien-kiem-cua.ps1 +++ b/scripts/tien-kiem-cua.ps1 @@ -1,8 +1,26 @@ # tien-kiem-cua.ps1 - GD-3 khoan (iv): tien kiem chi phi ~0 o DAU MOI CUA. # # Chi DOC. KHONG ghi. LUON exit 0 - day la lop INFORM, KHONG phai cong chan. -# Cong chan bang ma loi = W3b (khoan C3-04 + thang 4 trang thai), dang cho owner (P1). -# Ai sua file nay de tra ma != 0 la da doi lop, phai qua W3b truoc. +# Cong chan bang ma loi = W3b (khoan C3-04 + thang 4 trang thai). +# +# [1] P1 DA CHOT = PA-2 (hai ma thoat trong MOT may) - owner @S180, land @S181. +# Nguon: .claude/sessions/session-12/_context-s-12.md:55 +# docs/governance/harness-11-engine.md PHAN Q (phan loai 64/64) +# => DUNG hoi lai owner ve P1. Cau cu o dong nay noi P1 con treo - da GO @S185 vi STALE. +# (co y KHONG trich lai nguyen van cau cu: trich = de mot hit grep song mai trong tep, +# bay citation-trap use-vs-mention da xay ra that 3 doi/1 wave o repo nay) +# +# [2] VAN CHUA CAM. Dieu-kien-vao W3b co HAI ve; ve thu hai CHUA DAT +# (harness-11-engine.md:587): "rider-jump W2 da soak INFORM >=1 phien". +# Do @S185: rider-jump CHUA TON TAI tren dia => soak thuc te = 0 phien. +# Tai-lap: grep -c "OVERDUE:jump" scripts/nhip-no-probe.ps1 -> 0 +# Control: grep -c "OVERDUE" scripts/nhip-no-probe.ps1 -> 6 (thuoc con song) +# Truc lich da du (4 phien tu 2026-08-07) nhung chu-ngu cua phep soak chua duoc dung. +# +# Mo khoa khi: grep -c "OVERDUE:jump" scripts/nhip-no-probe.ps1 >= 1 VA no da chay +# INFORM >= 1 phien (>=1 tick moi trong .session-counter.json SAU commit land cua no). +# +# Ai sua file nay de tra ma != 0 la da doi lop, phai qua W3b truoc (DU CA HAI ve). # # Vi sao KHONG tin mtime cua he dieu hanh: # hook 'wal:' cham tep o bien moi luot, va 'git checkout' viet lai mtime hang loat.