Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
16 KiB
SPEC — h22-wal-adopt — 12-07-2026 (S111)
Provenance (H21 note-c): engine-propose = investigator-codebase Fable-real single-deep-pass (lệnh-A anh gõ
/fable-real invest và review — đề tài harness AI_INFRA apply xuống; return SẠCH 0-garble, VERDICTREADY_WITH_NUANCES14 nuance N1-N14) → lead verified + CHỈNH 3 điểm: (1) D2 hook = PowerShell.ps1variant thay bash-nguồn — evidence xung-đột 2-context: lead đo PS-contextGet-Command bash→C:\WINDOWS\system32\bash.exeWSL-HỎNG (execvpe fail) vs invest đo cmd-contextwhere bash→ Git-Bash đứng trước; exec-env hook thật KHÔNG xác định được trong phiên → chọn path-independentpowershell.exe(system32, tuyệt đối); port NGUYÊN semantics sàn (per-path add + CAND commit + exit-0 mọi nhánh + 0 content/push/block); script-RUN verify tay được ngay phiên này — hook-FIRE vẫn phiên mới (N1 STAGED giữ) · (2) row #9 acceptance =node --checkPASS (precedent S110 X7, bỏ wording mơ hồ) · (3).gitattributes*.sh text eol=lfVẪN append (phòng-hờ .sh tương lai + fleet-parity, vô hại — repo hiện 0 file .sh) → lead tự ghi file này (single-writer). Worker KHÔNG tự đọc file — lead bơm nguyên văn qua args (hmw.js pattern).
Mục 1 — Tính-năng / đề-bài
Adopt Harness-22 WAL session-continuity (broadcast 2026-07-11-Governance-harness-22-wal-session-continuity, body-sha 3de0758a6377 verified): sổ .claude/WAL.md ≤40 dòng ghi-đè-không-append (chain-bằng-chứng [x]/[!]/[ ] + next 1-mệnh-lệnh + verify-trước-next, ground-truth thắng, cấm secret) · Stop-hook .claude/hooks/wal-flush.ps1 persist-only per-path+CAND+exit-0 (STAGED-until-verified — hook nạp lúc khởi-động phiên, phiên này KHÔNG THỂ verify fire) + .gitattributes *.sh text eol=lf append · cặp /pause /tiep (MỘT đường recovery duy nhất) · delta session-start (BƯỚC 0.7 MỚI WAL-check — ngoại-lệ CHỜ duy nhất) + session-end (§5.0 squash wal: trailing chưa-push + §6.4 reset-WAL bước cuối) · WAL-cho-workflow (mandate run-trace ≥3-task/>5', taskList-snapshot vào run.md, dòng wf: 5-trường, harvest-liền C4 + per-agent-file + honest per-turn≠per-task N9, /tiep = relaunch-cắt-gọt + memory-pack re-derive tươi, resume-run-id = bonus SAME-SESSION-ONLY) · codify engine PHẦN N + CAVEAT:402 honest-update + rules §5.2 exception wal: + CLAUDE.md 2-dòng con-trỏ + honest (a)-(e) áp SE (e = Dropbox 2-chiều: risk index.lock + bonus .git-sync durability).
Xong nghĩa là (DoD grep-được): Test-Path .claude/WAL.md=True và ≤40 dòng · .claude/hooks/wal-flush.ps1 chạy tay exit-0 + tạo commit wal: thật (script-RUN verified; hook-FIRE = phiên mới) · grep "Stop" .claude/settings.json ≥1 · grep *.sh text eol=lf .gitattributes =1 · grep wal: docs/rules.md ≥1 · grep BƯỚC 0.7 session-start.md =1 · grep reset --soft session-end.md ≥1 · engine grep PHẦN N ≥1 + STAGED-until-verified ≥1 + honest (a)-(e) đủ 5 · CLAUDE.md grep /tiep ≥1 · workflows/README.md vùng :31 có BẮT BUỘC · adap-report + email AI_INFRA + mark-proposal trình anh (CHƯA stamp) · HANDOFF NEXT-anh có pilot-checklist + restart-CLI note.
Mục 2 — Cách implement
Quyết định thiết kế
- D1 — WAL.md: template rỗng nguồn §2 NGUYÊN VĂN; tracked (verify idiom N12:
git check-ignoreexit-1 = NOT-IGNORED cho re-included path!.claude/**.gitignore:82-83 — đừng đọc exit-code trần); ghi-đè toàn-file mỗi lần; lead single-writer nội-dung sau MỖI subtask đổi trạng-thái; dogfood ghi-chain ngay trong phiên S111 này. - D2 — Hook (LEAD-CHỈNH PS1):
.claude/hooks/wal-flush.ps1port NGUYÊN logic nguồn §3: 3 path cố định.claude/WAL.md+.claude/agent-memory/+.claude/workflows/runs/(N3 — GIỮ NGUYÊN, AS-6 không tăng: 2 json churn.mfe-state/.archive-strikesđã gitignored :124-125,memory-budget.jsontracked đổi-hiếm-owner-directed; hook chỉ commit LOCAL, CI trigger lúc PUSH, squash → push-set ≡ hôm nay); per-pathgit addtừng cái (X3 — add đa-pathspec = all-or-nothing khi 1 path vắng, bài học đắt nguồn) + CAND-list chỉ path thực-có-staged + commit-m "wal: flush <yyyyMMddTHHmm>"KHÔNG Co-Authored-By + exit 0 MỌI nhánh (try/catch bọc toàn thân; Stop-hook exit≠0 có hành vi riêng — CẤM); KHÔNG content-gen, KHÔNG push, KHÔNG block-stop, KHÔNG path ngoài list.settings.jsonCREATE MỚI (N1 — file chưa tồn tại, merge-concern moot) nested-schema:{"hooks":{"Stop":[{"hooks":[{"type":"command","command":"powershell.exe -ExecutionPolicy Bypass -File .claude/hooks/wal-flush.ps1"}]}]}}. Status = STAGED-until-verified (X5): codify + enable cùng commit nhưng CẤM claim "đang chạy" trước khi thấy commitwal:do HOOK sinh tronggit logphiên MỚI (script-RUN tay ≠ hook-FIRE); honest-note (c) nguồn: nếu phiên mới không fire → thử biến-thể phẳng rồi verify lại. - D3 — /pause /tiep: GIỮ tên nguồn (N11 — 16 command hiện có, 0 trùng);
.claude/commands/pause.md= logic nguồn §4 /pause 5-bước (ngừng-spawn → flush-dirty → WAL-đúng-schema → commit ĐÍCH-DANHwal: pauseKHÔNGgit add -A→ báo-cáo + DỪNG HẲN; bất-biến: commit TRƯỚC tuyên-bố an-toàn);.claude/commands/tiep.md= nguồn §4 /tiep 4-bước + nhánhwf:§6 (đọc WAL → không-tồn-tại/toàn-[x]= báo "không có mạch dở" DỪNG SẠCH → chạy TOÀN BỘ verify → lệch = TIN GROUND-TRUTH sửa WAL trước → thực-thi next; mụcwf:→ relaunch-CẮT-GỌT: đọc run-folder + taskList-snapshot, grep run-id trong log-phiên = bằng-chứng đích-danh task-đã-xong, harvest-hồi-tố partial-honest [lead verify rồi append], relaunch CHỈ task còn lại + memory-pack RE-DERIVE TƯƠI); /tiep verify đọc CẢgit status+ disk run-folder KHÔNG chỉ git-log (N9); CẤM nạp transcript cũ; fieldsession:khác phiên = BÌNH-THƯỜNG, chỉ cảnh-báo nếuupdatedmới hơn lúc phiên hiện-tại bắt đầu. - D4 — session-start: BƯỚC 0.7 MỚI chèn sau BƯỚC 0.6 (:37-45) TRƯỚC Phase 1 READ (:47) — chặn trước read-set ~368K = token-save lớn nhất (N6); nội dung: đọc
.claude/WAL.md→ có[!]hoặc[ ]→ báo "có mạch dở,/tiepđể nối" + CHỜ anh chọn (ngoại-lệ CHỜ DUY NHẤT của quy-trình no-wait; chỉ là CON-TRỎ — quy-trình recovery viết ở MỘT chỗ = tiep.md); chain rỗng/toàn-[x]→ tiếp bình-thường. GIỮ NGUYÊN số 0.5/0.5b/0.6 (X10, precedent D4 S110 chống renumber-churn). - D5 — session-end: §5.0 MỚI ngay trước §5.1 (:111): đếm K = subject liên-tục
^wal:từ HEAD xuống tronggit log --format=%s origin/main..HEAD(span CHƯA-push — không bao giờ rewrite đã-push X4) → K>0 →git reset --soft HEAD~Kgộp vào commit-chốt; K=0 → skip; biên N7: (i) push chết phiên trước → HEAD=chốt-cũ-chưa-push KHÔNG bị fold (đếm dừng ở subject ≠wal:), được push lần này; (ii) wal: sandwiched dưới chốt → GIỮ (noise chấp nhận, per nguồn §5); +1 dòng N14: "squash xong = điểm review-diff wal-paths (AS-10 backstop dời về đây, KHÔNG mất — push vẫn gated em-main)". §6.4 MỚI sau §6.3 (:129) TRƯỚC footer :139: reset WAL về template rỗng = bước CUỐI (hook sẽ commit lần reset thành wal-commit trailing sau turn cuối — vô-hại, phiên sau squash). - D6 — WAL-cho-workflow:
workflows/README.md:31+ bảng :24 FLIP policy: mode-A vẫn cho fan-out NHỎ, nhưng run ≥3 task HOẶC ước >5 phút = BẮT BUỘC RUN-TRACE mode (args.run — per-agent-file trong run-folder) (sàn H22 owner nguồn đã chốt); run.md template +section## taskList snapshot(role · label · prompt-gist) ghi TRƯỚC launch (N10); dòngwf:<mục-đích> run=<folder> runId=<id|pending> args=<snapshot-ref> done=<k>/<N> harvested=<yes|no|partial>vào WAL NGAY SAU launch, lead điền runId khi có; harvest-LIỀN mỗi task xong = C4 per-turn (ĐÃ CÓ — hmw.js:99 + session-end:51) + honest-note granularity N9 (per-TURN ≠ per-TASK:parallel()trả cả batch cuối turn, Stop-hook cũng fire ở turn-boundary → chết GIỮA turn = returns mất, per-agent-file trên DISK là lớp cứu → /tiep đọc cả disk); memory-pack KHÔNG snapshot (X6 — re-derive tươi lúc /tiep; hiện đã compliant: pack qua args hmw.js:15); resume-by-run-id = bonus SAME-SESSION-ONLY (engine Workflow docs "same-session only" — CẤM claim cross-session, honest-note (d)). - D7 — Codify: engine
docs/governance/harness-11-engine.mdPHẦN N MỚI (trước CAVEAT :401): schema WAL + 2 tầng ghi (lead nội-dung ⟂ hook persist) + hook ĐƯỢC làm {git add 3-path, CAND-commitwal:} / KHÔNG-ĐƯỢC {content-gen, push, block-stop, path-ngoài-list, exit≠0} + STAGED-until-verified + honest (a)-(e) áp SE [(a) pilot chưa chạy tại SE — kill-test/đổi-acc/hook-fire = phiên mới+anh; (b) SE 0-mark-cấm-hook, N2 mô-tả-vs-luật, thứ-tự codify-trước-enable ĐÃ tôn trọng cùng-commit; (c) nested-schema default, fallback flat nếu phiên mới không fire; (d) resume-run-id same-session-only; (e) Dropbox 2-chiều: risk index.lock thấp-nhưng-có fail-open tự-lành + bonus .git-sync = commit local chưa-push vẫn sống qua tắt-máy/đổi-máy → /pause không cần push vẫn durable]; CAVEAT :402 honest-update: thêm ngoại-lệ đích-danh "Stop-hook wal-flush persist-only (PHẦN N) — 0-content, fail-open, KHÔNG phải gate (E.3-compatible)";docs/rules.md§5.2 (:213-221) append exception: "ngoại-lệ DUY-NHẤT: commitwal:(Stop-hook persist + /pause + WAL-reset) — máy sinh, KHÔNG Co-Authored-By, bị squash vào commit-chốt trước push (session-end §5.0)"; rootCLAUDE.md2 dòng con-trỏ: "Mạch việc dở 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." - D8 — hmw.js :9/:19 comment-only (em-main, X7 KHÔNG đổi code): :9 meta note mode-A default → "+ mandate H22: ≥3-task/>5' PHẢI RUN-TRACE (em-main scaffold + set args.run — script no-fs không tự ép, enforcement = convention lead)"; :19
run: OPTIONAL→ wording mandate-ref. - D9 — Mark H22 MỚI trình anh cuối phiên (P4 report-before-stamp §L.b(h)) — KHÔNG tự stamp (X5-mark); đề xuất §-target:
engine PHẦN N+.claude/hooks/+session-start BƯỚC 0.7/session-end §5.0+§6.4(≙ AI_INFRA H-22 CANONICAL §I4 + §H1). - D10 — Optional KHÔNG-block (owner-OK sau): deploy.yml paths-ignore +
.claude/agent-memory/**+.claude/workflows/runs/**(precedent.claude/skills/**:23) — triệt noise CI khi budget.json đổi; ghi option vào adap-report + HANDOFF, KHÔNG làm trong run này.
Ràng buộc thật
Worker Opus edit-DIRECT trong PHẠM VI file được giao (3 lane disjoint; residual → em-main git-diff revert AS-10) · WAL.md + .gitattributes + settings.json + engine + rules + CLAUDE.md + hmw.js + adap-report + email + mark-proposal + HANDOFF = em-main · command .md + hook = restart-CLI/phiên-mới mới ăn (S27 + ENV-DEPENDENT S110) → pilot-checklist nằm HANDOFF NEXT-anh · HISTORY (session-log, archive verbatim, adap-report cũ, diary) GIỮ nguyên văn · script-RUN tay verify trong phiên ≠ hook-FIRE (phiên mới).
Đường chết cần né
(X1) đụng hmw-mode.on/BƯỚC 0.5/ultra-* — HỆ KHÁC (HMW consent) · (X2) hook thêm content-gen/push/block-stop · (X3) add/commit đa-pathspec all-or-nothing · (X4) rewrite commit đã-push khi squash · (X5) claim hook "đang chạy" trước verify phiên mới (ghost-wire S100) · (X6) snapshot memory-pack · (X7) đổi code hmw.js (chỉ comment) · (X8) WAL append thay ghi-đè / vượt 40 dòng / chứa secret · (X9) commit script .sh trước khi .gitattributes có *.sh (n/a với .ps1 nhưng giữ thứ-tự: gitattributes trước) · (X10) renumber BƯỚC/§ cũ · (X11) tự stamp mark.
Mục 3 — Checklist thực hiện
| # | Vai | Deliverable | Acceptance (đo được) |
|---|---|---|---|
| 1 | em-main | .gitattributes append *.sh text eol=lf (X9-first) + .claude/WAL.md template nguồn §2 |
grep *.sh text eol=lf =1; Test-Path .claude/WAL.md=True; (gc).Count ≤40; check-ignore idiom → NOT-IGNORED |
| 2 | em-main | .claude/settings.json CREATE hooks-entry PS1 + STAGED-note trong engine |
grep "Stop" =1; grep wal-flush.ps1 =1; engine grep STAGED-until-verified ≥1 |
| 3 | worker-opus-1 (edit-direct, file MỚI) | .claude/commands/pause.md + .claude/commands/tiep.md (D3) |
2 file frontmatter description:; tiep grep "transcript"≥1(CẤM) + "ground-truth"≥1 + "wf:"≥1 + nhánh WAL-rỗng-dừng-sạch + "git status"≥1; pause grep "wal: pause"≥1 + "git add -A"≥1(CẤM-context) + trỏ /tiep |
| 4 | worker-opus-2 (edit-direct) | session-start.md BƯỚC 0.7 (D4) | grep "BƯỚC 0.7"=1; "CHỜ"≥1 vùng 0.7; git-diff KHÔNG chạm 0.5/0.5b/0.6/Phase-1+ |
| 5 | worker-opus-2 (edit-direct) | session-end.md §5.0 + §6.4 (D5) | grep "origin/main..HEAD"=1; "reset --soft"=1; "KHÔNG rewrite"≥1; "review-diff wal-paths"≥1; §6.4 sau 6.3 trước footer |
| 6 | worker-opus-3 (edit-direct, file MỚI) | .claude/hooks/wal-flush.ps1 (D2 PS1-port) |
lead chạy tay powershell -ExecutionPolicy Bypass -File exit-0 ×2 ca (có-delta → commit wal: thật; 0-delta → exit-0 im lặng); grep "exit 0"≥2 + try/catch; per-path loop + CAND; 0 push/content/block |
| 7 | worker-opus-3 (edit-direct) | workflows/README.md policy-flip :31+bảng + run.md template +## taskList snapshot (D6) |
vùng :31 có "BẮT BUỘC" + "≥3"/"5 phút"; grep "taskList snapshot"≥1; mode-A vẫn hợp lệ cho fan-out nhỏ |
| 8 | em-main | engine PHẦN N + CAVEAT:402 + rules §5.2 + CLAUDE.md pointer (D7) | grep "PHẦN N"≥1; :402 có "ngoại-lệ"; rules grep "wal:"≥1; CLAUDE.md grep "/tiep"≥1; honest a-e đủ 5 trong PHẦN N |
| 9 | em-main | hmw.js :9/:19 comment-only (D8) | node --check .claude/workflows/hmw.js PASS; grep "OPTIONAL" :19 vùng = 0 (thay mandate-ref); git-diff hmw.js chỉ comment-line |
| 10 | em-main | WAL.md dogfood ghi-chain S111 + run.md update + adap-report + email AI_INFRA + mark-proposal (D9) | WAL chain ≥3 mục [x] bằng-chứng lệnh; report nêu ĐÚNG NẤC "khung dựng + STAGED + script-RUN-verified, hook-FIRE + pilot = phiên mới"; ACTIVE-MARKS CHƯA đổi; AskUserQuestion trình |
| 11 | reviewer-Fable (vai anh gán trong lệnh) | Cổng-cuối biên-test + sweep | fault-inject cây tạm: hook thiếu-1-path vẫn commit path-còn + exit-0; WAL >40-dòng bị bắt; /tiep WAL-rỗng dừng sạch; grep toàn-repo con-trỏ recovery = MỘT đường /tiep; honest a-e present; 0.5/hmw-mode/ultra-* untouched; spec-compliance từng row |
| 12 | em-main | HANDOFF pilot-checklist + restart-CLI note + STATUS blurb | NEXT-anh có: restart CLI · phiên mới verify hook-FIRE (git log wal:) · kill-giữa-chain → /tiep · đổi-acc · squash dry-run thật · pause-roundtrip 1 workflow THẬT |
Map sàn-H22 → row: ① sổ WAL ≤40/schema/ghi-đè → #1+#10 · ② hai tầng ghi (lead⟂hook persist-only 0-content fail-open per-path) → #2+#6+#8 · ③ /pause+/tiep 1-đường → #3+#11 · ④ delta mở/đóng (WAL-check · squash chưa-push · reset cuối) → #4+#5 · ⑤ WAL-workflow (snapshot args · wf: · harvest-liền · relaunch-cắt-gọt · mandate per-agent-file · trung-thực mất-mát) → #7+#8+#3(nhánh wf:) · honest (a)-(e) → #8+#10.