CHUOI BAT BUOC (v2 §3.3 + §2.4(4)): fire -> chung-kien -> ROI MOI va -> het fire.
CAM va permission-matrix TRUOC = mat chinh bang-chung detector co rang.
TRUOC (capture ra runs/<id>/W4-detector-fire-15-07-2026.md muc 1-5, fix#9c time-anchored):
MED :3 writes 60 menu but canonical=54
MED :3 writes 240 policy but canonical=216
MED :16 writes 60 menu but canonical=54
LOW :81 writes 48 policy but canonical=216
LOW :16 title-stale anchor 2026-04-30 vs 2026-07-15 (76d)
TOTAL FLAGS: 50 <- khop CHINH XAC du-bao W2 (WAL:17 "49->50, -1 cadence +2 policy")
SAU: permission-matrix 0 FLAG | TOTAL 45 | tut dung 5 | 0 flag moi (do bang `comm`, khong dem mat).
CACH VA = B1 bo so + tro canonical, KHONG doi so (doi so thi lan sau lai stale).
Dung dung loi khuyen detector tu in: "OR replace with pointer '-> docs/STATUS.md'".
CHUOI NHAN-QUA W1<->W2 chung duoc 3 detector doi trang-thai DUNG thiet-ke:
- h24_cadence: "missing => measuring NOTHING" -> "M = light_every = 6 (read from config)"
- spawn-model-audit: "expected constant missing" -> "[OK] claude-opus-4-8 = owner-ratified"
- GAP-3 policy: "policy=MISSING" -> "216" + BAT NGAY permission-matrix:3
=> truoc W2, nua policy KHONG THE fire vi STATUS khong co row Policies => detector IM,
va su im-lang do trong y HET nhu "sach". Detector khong co nguon chuan = do NOTHING.
STALE NANG HON CON-SO (tim duoc luc va, detector count-token KHONG bat duoc):
SKILL.md:20 liet "Budgets root + 3 Bg_*" nhu menu DANG SONG.
Do dia: module Budget XOA tu S61 (Mig 50); 2 hit Bg_ con lai = COMMENT BIA-MO
(MenuKeys.cs:70 + fe-{admin,user}/src/lib/menuKeys.ts:29). Code sach, chi skill con mo-ta.
=> gioi-han detector dem-so: thay "60 != 54" nhung khong thay "4 trong 60 do da bi xoa 60 phien truoc".
DUONG-GIA CAU-TRUC (khai, KHONG sua -- doi hanh-vi detector = quyen anh/W5):
lead-view-auditor.md:45 FIRE title-stale vi bang vi-du cua no chua "2026-04-30" lam MAU
minh-hoa cho class view-stale-header. Cung CO-CHE voi loi da lam acceptance FIX#6 bat-kha-thi
(:47 chua "12 sub ... roster = 14" lam vi-du). 2 detector DOC-LAP, cung 1 file, cung 1 ly-do:
VI-DU VE STALE TRONG Y HET STALE. File dinh-nghia anti-pattern tat-yeu chua mau anti-pattern.
De-xuat (khong tu lam): detector can co-che mien-tru tuong-minh cho khoi vi-du.
LEAD TU BAT 2 LOI @W4:
(a) WAL ghi "permission-matrix 6 dong" -- that la 5 (dong :70 = context, khong phai flag).
Loi dem lan thu 3 trong phien; lan nay bat TRUOC khi thanh claim gui hub.
(b) Suyt claim au canonical: grep tho MenuKeys.cs ra 64 chuoi -> SAI (dem MOI chuoi trong file,
khong phai phan-tu mang All). W2 ground dung: |MenuKeys.All|=54 (:147) x |Actions|=4 = 216.
Lead BO so cua minh, dung so W2. Bai hoc: do bang cong-cu sai con te hon khong do --
vi no ra mot con-so TRONG CO VE do duoc.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
runs/ — Run-trace convention (Harness-10 · cấu trúc PHẲNG)
Mục đích: mỗi workflow fan-out (RUN-TRACE mode) ghi lại 1 dấu-vết hoàn-chỉnh trong
runs/<run-id>/git TRACKED — plan + per-sub detail + bản-gom. (🧊 sổ_ledger.md2-nhịp RETIRED H18-B S100 — đo bắt-thật 0/15 lifetime + mode-A coverage 0/8; orphan-authority = folder-scan L1/L2 dưới.) TRACKED nghĩa là mọi write trong run-folder hiện tronggit diff→ audit trực-tiếp, không cần tin lời agent return. Adopt AI_INFRA Harness-10 (anh 06-18) + DELTAh10-flat-detector-refine(06-18). Convention cha:../README.md.🆕 REFINE 06-18 — cấu trúc PHẲNG. Trước đây mỗi run-folder có 2 thư mục con (
sub-md/+harvest/). NAY mọi vết tích nằm phẳng cùng MỘT cấp trongruns/<run-id>/; phân biệt bản-thô (raw, per-sub) vs bản-đã-soát (verified, gom) bằng TÊN file, KHÔNG bằng thư mục con. Lý do: engine (hmw.jsJS-sandbox no-fs) chỉ tạo artifact ở một cấp một cách tự nhiên — bỏ thư-mục-con sâu thì xoá luôn một điểm-hay-quên ngay tại gốc (không còn thư-mục-con-để-quên-dựng).
run-id = YYYY-MM-DD-h<NN>-<slug> (vd 2026-06-18-harness-audit-invest). Nhiều run cùng ngày → slug phân-biệt stage (-invest / -implement / -review).
C1 — Cấu trúc PHẲNG (mỗi runs/<run-id>/ — file cùng MỘT cấp)
runs/<run-id>/
├── run.md ← (1) PLAN — em main @P1: meta + mục-tiêu + agents-table + guards + status OPEN→CLOSE
├── sub-<role>-<i>.md ← (2) PER-SUB raw — 1 file/sub/turn, prefix `sub-` (vd sub-investigator-codebase-0.md)
├── sub-<role>-<i>.md (fan-out cùng-role → đánh số -0 / -1 …)
└── <stage>-synthesis.md ← (3) GOM verified — em main: bản-gom 1 turn, suffix `-synthesis.md` (vd invest-synthesis.md)
Phân-biệt raw vs verified bằng TÊN, KHÔNG bằng subfolder:
| Loại | Quy-ước TÊN | Ai ghi | Nội-dung |
|---|---|---|---|
| PLAN | run.md (cố định) |
em main @P1 | nguồn-sự-thật của run: workflow run-id (evidence B3 wf_…), adap/mandate, checkpoint, opened, input-spec (nếu nối stage trước), agents-table (# · role · task), guards áp cho sub, output-path, status OPEN→CLOSE. |
| PER-SUB (raw) | prefix sub- → sub-<role>-<i>.md |
write-sub tự ghi @P2 · read-only sub → em main scribe @P3 | full working detail 1 sub. 1 sub-MD / role / turn (cùng-role → -0/-1). Read-only sub (CHỈ Bash) KHÔNG Bash-write MD (mojibake) → trả findings+subMdPath, em main single-writer. |
| GOM (verified) | suffix -synthesis.md → <stage>-synthesis.md |
em main per-turn (C4) | gom sub-*+findings → 5-trục integrity → build-spec/synthesis. |
🟢 Quy-tắc nhận-diện: file bắt đầu bằng
sub-= bản-thô (per-sub); file kết bằng-synthesis.md= bản-đã-soát (gom).run.md= plan. Không cần mở file/không cần subfolder để biết loại — đọc TÊN là đủ. (Khớp../hmw.jsinject path: engine ghi-directruns/<run-id>/sub-<role>-<i>.md, KHÔNGsub-md/….)Live dogfood:
2026-06-18-harness-audit-invest/=run.md+audit-synthesis.mdCHỈ (KHÔNG subfolder, KHÔNG rawsub-audit-*.md) — vì 1 auditor fail-no-StructuredOutput + 2 truncated → em main self-gate ground-truth từ đĩa, không có raw-sub để scribe (xemaudit-synthesis.md:4). Ví-dụ tênsub-<role>-<i>.mdlà minh-hoạ QUY-TẮC-ĐẶT-TÊN, KHÔNG phải artifact bắt-buộc mỗi run. Run2026-06-18-harness-fix-implement/mới có đủ raw (sub-impl-sleepcmd.md+sub-impl-runsreadme.md+implement-synthesis.md) = full flat set điển-hình.
C2 — Scaffold run.md ở OPEN (em main @P1, TRƯỚC khi invoke Workflow)
hmw.js chạy JS-sandbox no-filesystem → KHÔNG tự tạo folder/file. Em main PHẢI Write @P1:
- Tạo run-folder + PLAN:
runs/<run-id>/run.md(điền plan đầy-đủ). 🆕 KHÔNG cầnmkdir sub-md//harvest//.gitkeep— filesub-*và*-synthesis.mdsẽ sinh ra phẳng cùng cấp trong cùng folder đó (engine + em main ghi 1 cấp). Ghi OPEN-beat vào— 🧊 retired H18-B S100 (KHÔNG ghi beat mới; ledger frozen giữ lịch-sử. Orphan-authority = folder-scan L1/L2).runs/_ledger.md- (nối stage) trỏ
input spec:trongrun.mdsang<stage>-synthesis.mdcủa run trước (vd implement đọcinvest-synthesis.md).
🔴 C2 là fragile-point. Quên scaffold = run chạy nhưng KHÔNG có dấu-vết = lỗ-hổng âm-thầm (không lỗi, không cảnh-báo — chỉ thiếu file). 3-layer (C5) là lưới giảm-thiểu, KHÔNG khoá-cứng. Xem C7. 🆕 Cấu trúc phẳng bỏ 1 trong 2 điểm-hay-quên (không còn subfolder-to-forget); dư-lượng còn lại = vẫn phải tự ghi
<stage>-synthesis.mdmỗi run (close-gate C5/L3 bắt nếu thiếu).
taskList snapshot (H22 — ghi TRƯỚC launch)
Sàn WAL-cho-workflow (Harness-22 S111) — chống đốt-lại-token + mất-memory khi chết GIỮA workflow. Điều-kiện áp: run WAL-hóa = ≥3 task HOẶC ước chạy >5 phút (khớp ../README.md FLIP-policy) → BẮT BUỘC RUN-TRACE + 2 vật-liệu dưới ghi xuống đĩa TRƯỚC/NGAY-SAU launch:
- Section
## taskList snapshottrongrun.md— ghi TRƯỚC khi phóng. Mỗirun.mdPHẢI có section này liệt-kê từng task sắp phóng: (role · label · prompt-gist 1-dòng) — đủ vật-liệu để/tieprelaunch-cắt-gọt các task CÒN LẠI mà KHÔNG cần transcript cũ. (= "snapshot tham-số" mục ⑤ broadcast H22: ghi {danh-sách-task · spec} xuống đĩa trước launch.) - Dòng WAL
wf:(5 trường) — ghi NGAY SAU launch vào.claude/WAL.md, lead điềnrunIdkhi engine trả về:wf:<mục-đích> run=<run-folder> runId=<id|pending> args=<snapshot-ref> done=<k>/<N> harvested=<yes|no|partial>—run=trỏruns/<run-id>/;args=trỏ section## taskList snapshottrongrun.md(KHÔNG nhét spec dài vào WAL);done=<k>/<N>+harvested=partialcập-nhật khi harvest-liền mỗi task xong. - 🔴 memory-pack KHÔNG snapshot (X6): re-derive TƯƠI lúc
/tiep— snapshot memory-pack cũ sẽ lỗi-thời sau khi đã harvest phần đã-xong.
C3 — Git-tracked: VERIFY 2 nấc tách-bạch (chỗ hay nhầm)
Run-folder PHẢI git TRACKED (re-include qua .gitignore:83 !.claude/**, last-match-wins). Verify ĐỦ 2 nấc — đừng dừng ở nấc 1:
# Nấc (i) — GỠ-KHỎI-IGNORE (tracked-eligible): exit != 0 = KHÔNG bị ignore
git check-ignore .claude/workflows/runs ; echo "exit=$?" # SE: exit=1 ✓ (không ignore)
# Nấc (ii) — THẬT-SỰ-COMMIT: liệt-kê ra file = đã `git add`/commit
git ls-files .claude/workflows/runs | wc -l # SE: 22 ✓ (non-empty = đã commit)
- Nấc (i)
check-ignoreexit != 0 = thư-mục KHÔNG nằm trong ignore (tracked-eligible). ⚠️ Mới là đủ-điều-kiện-track, CHƯA chắc đã commit. - Nấc (ii)
ls-filesnon-empty = thật-sự có file trong index (đãgit add/commit). 🔴 eligible ≠ committed: một foldercheck-ignoreexit!=0 NHƯNGls-filesrỗng = chưa hề commit (bằng-chứng sống tại AI_INFRA chính trường-hợp này). PHẢI chạy CẢ 2 lệnh. - 🔴 ĐÚNG PATH mới đáng tin. Path đúng =
.claude/workflows/runs(đầy-đủ từ repo-root). Bareruns/(tên trần) là path SAI — ở repo khác,git check-ignore runstừ repo-root có thể trả exit 0 (match nhầm rule khác / không match negation.claude/**) → đọc sai thành "bị ignore". (Quan-sát SE: cảrunslẫn.claude/workflows/runsđều trả exit=1 vì .gitignore SE không có rulerunstrần — nhưng ĐỪNG dựa may-rủi đó: luôn dùng path đầy-đủ.claude/workflows/runs.) - Bẫy exit-code khi dùng
-v:git check-ignore -v <path>trả exit 0 cho CẢ ignore lẫn negation (!.claude/**) → đừng đọc exit của-vđể kết-luận; dùng dạng không--vở trên (exit!=0 = không ignore) hoặc&& echo IGNORED || echo NOT.
C4 — Per-turn primary (gom NGAY, không đợi session-end)
Gom là việc của turn, không defer. Sau MỖI fan-out turn → em main đọc sub-*+findings → ghi <stage>-synthesis.md liền trong turn đó (chính file synthesis này là bằng-chứng). Lợi: detail tươi, không mất qua nén-context; session-end chỉ VERIFY (không tái-tạo). Đây là đường CHÍNH (primary); gom toàn-bộ @session-end (L3) chỉ là lưới an-toàn (safety-net), KHÔNG phải đường chính.
C5 — 3-layer anti-miss (lưới chống bỏ-sót — KHÔNG khoá-cứng-cùng-lúc-fire)
| Layer | Khi | Làm gì |
|---|---|---|
| L1 in-run folder-check (🧊 ledger-check retired H18-B S100) | em-main @P1, lúc mở run mới (TRƯỚC scaffold) | scan runs/*/: nếu run TRƯỚC còn folder có run.md mà thiếu <stage>-synthesis.md (hoặc synthesis 0-byte) → gom + đóng nó TRƯỚC khi mở run mới. (L1 là convention EM-MAIN, KHÔNG phải hmw.js prompt. hmw.js chỉ emit C4 per-turn return-instruction cho sub tại writeGuard.) |
| L2 session-start orphan-scan | đầu session (session-start.md §2.1.1 H2) |
scan runs/*/ tìm orphan = folder có run.md mà KHÔNG có <stage>-synthesis.md (hoặc synthesis 0-byte) → báo + giải-quyết. (🧊 tiêu-chí ledger-⏳ retired H18-B S100; run cũ S71 dual-accept harvest/<stage>-synthesis.md.) |
| L3 session-end close-gate | cuối session (session-end.md §L.b(f) H2) |
VERIFY per-turn gom đã xong cho mọi runs/<id>/ (idempotent — KHÔNG re-APPEND, chống DUPLICATE-HARVEST) + 5-trục GATE backstop trước khi commit. 🆕 close-gate chấp nhận CẢ 2 dạng (old-subfolder + new-flat) trong giai-đoạn chuyển — xem C8. |
3 layer độc-lập, fire ở 3 thời-điểm khác nhau (run-open @P1 / session-start / session-end) — KHÔNG layer nào do engine enforce (hmw.js no-fs), cả 3 là convention em-main/H2. → giảm xác-suất sót, KHÔNG triệt-tiêu. Sót ở P1 (C2) cùng blind-spot với L1 (đều @P1) → chỉ bắt MUỘN ở L2 (session sau) / L3 (close-gate).
C6 — Ledger 2-nhịp + orphan resolution (_ledger.md) — 🧊 RETIRED H18-B S100 (nguyên-văn dưới GIỮ làm lịch-sử — dời-đi không xoá; orphan-authority = folder-scan C5 L1/L2; đảo-ngược = gỡ marker này + marker _ledger.md header + restore mandate C2-step-2)
Sổ tất-cả run, 1 bảng. Mỗi run 2 lần ghi (2-nhịp):
- OPEN-beat (@P1, lúc scaffold): thêm dòng
| <run-id> | <workflow> | <opened> | ⏳ | <agents> | ⏳ | <stage>-synthesis.md |. - CLOSE-beat (lúc đóng run): điền
closedtimestamp +verdict(PASS/FAIL + 1 dòng +wf_…) +harvest(path file synthesis ✓).
closed=⏳ = đang chạy (OPEN chưa CLOSE).
Orphan = dòng ledger closed=⏳ nhưng run thực-tế đã xong/bỏ (session bị kill, agent die-0-byte, quên CLOSE-beat). Giải-quyết-CỨNG (không để treo):
- Điều-tra đĩa THẬT:
run.mdstatus + có filesub-*? + có<stage>-synthesis.md? + git-log workflowwf_…. - Đóng tay nếu run thật-sự xong: điền CLOSE-beat (timestamp + verdict + harvest path).
- Đánh-dấu aborted nếu run bỏ-dở: verdict =
⚠️ ABORTED — <lý-do>, ghi rõ phần nào hoàn-thành (recover qua git/disk/prod truth, KHÔNG tin agent return-message).
C7 — 🔴 CAVEAT trung-thực (no-overclaim)
- Engine no-fs → scaffold KHÔNG tự-động.
hmw.js(JS-sandbox no-filesystem) KHÔNG tạo được folder/file. Run-trace dựa 100% vào em-main: scaffoldrun.md@P1 (C2) + tự ghi<stage>-synthesis.mdmỗi run (C4). Không có cơ-chế nào ép tạo file. NOT fully-autonomous — đây là hard-gate-trên-INPUT (em main tự dựng khung + tự bơm tham-số đầu/cuối mỗi run), KHÔNG phải engine tự-động. - Cấu trúc phẳng giảm fragile từ 2 → 1, KHÔNG triệt-tiêu. Bỏ subfolder xoá được điểm-hay-quên "dựng sẵn
sub-md/+harvest/" (engine giờ ghi 1 cấp, no subfolder-to-forget). NHƯNG còn dư-lượng: em-main VẪN phải nhớ ghi<stage>-synthesis.mdmỗi run (close-gate L3 bắt nếu thiếu). Điểm-yếu giảm 1-trong-2, chứ không biến mất → C2 vẫn bắt-buộc. - 3-layer = LƯỚI, KHÔNG khoá-cứng-cùng-lúc-fire. L1/L2/L3 bắt lỗi sau khi việc đã xảy ra (post-hoc) hoặc nhắc dựa-trên-input em-main-bơm — giảm xác-suất sót, KHÔNG chặn tại-đúng-thời-điểm-fire. Phòng-thủ-nhiều-lớp, KHÔNG bảo-đảm tuyệt-đối.
- G-015 no-overclaim — TRACKED ≠ read-only-ENFORCED. Run-folder git-tracked KHÔNG biến sub thành read-only: sub vẫn giữ Bash (write-channel mở — ghi-ngoài-repo git-diff mù / curl Qdrant). Containment THẬT (model dưới) = em-main single-writer + git-diff(in-repo) + chunk-count(RAG), defense-in-depth — KHÔNG sandbox cứng, KHÔNG claim "ENFORCED".
C8 — MIGRATION (run cũ giữ subfolder · close-gate chấp-nhận CẢ 2 dạng)
🔴 KHÔNG viết lại lịch-sử. 5 run-folder S71 đã chốt giữ NGUYÊN cấu trúc cũ sub-md/ + harvest/ (đã commit, KHÔNG đụng):
2026-06-18-h10-invest/ (run.md + sub-md/ + harvest/invest-synthesis.md) ← cũ, GIỮ
2026-06-18-h10-implement/ (run.md + sub-md/ + harvest/implement-synthesis.md) ← cũ, GIỮ
2026-06-18-h10-review/ (run.md + sub-md/ + harvest/review-synthesis.md) ← cũ, GIỮ
2026-06-18-h910-finalize/ (run.md + sub-md/ + harvest/finalize-synthesis.md) ← cũ, GIỮ
2026-06-18-h910-curate/ (run.md + sub-md/ + harvest/curate-synthesis.md) ← cũ, GIỮ
2026-06-18-harness-audit-invest/ (run.md + audit-synthesis.md) ← 🆕 FLAT
- Run MỚI từ refine 06-18 → dùng FLAT (
sub-<role>-<i>.md+<stage>-synthesis.mdcùng cấp). Run CŨ → để yên (đừng gom-lên-cấp/đừng xoá subfolder — re-writing history vô-ích + làm bẩn git-log). - 🟢 Close-gate (L3) ACCEPT BOTH suốt giai-đoạn chuyển: verify gom ở
harvest/<stage>-synthesis.md(dạng cũ) HOẶC<stage>-synthesis.mdphẳng (dạng mới). Không fail run cũ chỉ vì thiếu file-phẳng. - 2 nấc track (C3) áp cho CẢ 2 dạng:
check-ignoreexit!=0 +ls-filesnon-empty.
Containment model (PHẢI khớp ../hmw.js — đồng-bộ 2 chỗ: đây · ../hmw.js; 🧊 chỗ thứ-3 _ledger.md retired H18-B S100, header nó giữ bản frozen)
Run-folder
runs/<run-id>/được git TRACKED → mọi write HIỆN trong git-diff = audit trực-tiếp. Containment: tracked-change NGOÀIruns/<run-id>/VÀ NGOÀI code-disjoint đã giao = vi-phạm (thay model Harness-2 B6 "mọi tracked-change = vi-phạm"). G-015 no-overclaim: TRACKED ≠ read-only-enforced — sub vẫn giữ Bash (write-channel mở), containment THẬT = em-main single-writer + git-diff(in-repo) + chunk-count(RAG).
Anti-bypass detector — SE TAILORED-OUT (quyết-định có chủ-đích, anh chốt)
Refine 06-18 (b) đề-xuất làm-chặt một bộ-dò chống-lách-engine (soi nhật-ký/mã xem có run nào né engine chuẩn không) theo 3 chức-năng. SE quyết-định KHÔNG hiện-thực bộ-dò này — đã CÂN-NHẮC và thấy N/A cho threat-model của SE. Giữ trung-thực, KHÔNG overclaim "đã có anti-bypass detector".
Lý-do tailored-out:
- SE chạy workflow qua Anthropic Workflow tool (
hmw.jsinvoke), KHÔNG có bề-mặt-lách kiểu CLI-launcher. AI_INFRA threat-model giả-định một node-CLI launcher (đường-vòng chạy lén engine) cần bộ-dò canh. SE không có launcher như vậy → không có "đường-vòng" để dò. - Containment SE đã đủ bằng cơ-chế khác (G-015 defense-in-depth):
git diffcommit-gate (mọi write tracked HIỆN trong diff) + run-folder git-tracked (audit trực-tiếp) + folder-scan orphan L1/L2 (🧊 ledger-scan retired H18-B S100) — backstop THẬT (không phải prompt). Bộ-dò pattern-match thêm = trùng-lặp, không bịt lỗ mới.
3 chức-năng refine — CÂN-NHẮC rồi N/A cho SE:
| Chức-năng refine (b) | Áp SE? | Vì sao |
|---|---|---|
| (1) Whitelist launcher hợp-lệ | N/A | SE không có launcher-wrapper quanh engine → không có gì để whitelist. |
| (2) Khớp đa-dạng biến-thể path tới engine | N/A | SE invoke engine qua Workflow tool (1 đường duy-nhất), không có path-variant để khớp. |
| (3) Neo KHOÁ-khởi-chạy-thật (đừng match tên-engine lẫn trong script) + acceptance theo QUAN-HỆ | N/A | Không có log-scan detector → không có chỗ neo launch-key. Acceptance-by-relation (hợp-lệ ≠ vi-phạm, hợp-lệ tăng dần OK) là nguyên-tắc tốt nhưng chỉ áp được khi CÓ detector. |
🔴 No-overclaim: SE KHÔNG claim đã adopt anti-bypass detector. SE claim: đã đọc + cân-nhắc 3 chức-năng, chọn tailored-out vì threat-model SE không có CLI-launcher-bypass-surface; containment dựa git-diff + run-folder-tracked + ledger-orphan-scan (G-015). Nếu sau này SE thêm launcher-wrapper → re-visit quyết-định này.