Files
solution-erp/.claude/workflows/runs/2026-07-12-h22-wal-adopt/spec-h22-wal-adopt-12-07-2026.md

49 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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, VERDICT `READY_WITH_NUANCES` 14 nuance N1-N14) → **lead verified + CHỈNH 3 điểm**: (1) **D2 hook = PowerShell `.ps1` variant** thay bash-nguồn — evidence xung-đột 2-context: lead đo PS-context `Get-Command bash` → `C:\WINDOWS\system32\bash.exe` WSL-HỎNG (execvpe fail) vs invest đo cmd-context `where bash` → Git-Bash đứng trước; exec-env hook thật KHÔNG xác định được trong phiên → chọn path-independent `powershell.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 --check` PASS (precedent S110 X7, bỏ wording mơ hồ) · (3) `.gitattributes` `*.sh text eol=lf` VẪ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-ignore` exit-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.ps1` port 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.json` tracked đổi-hiếm-owner-directed; hook chỉ commit LOCAL, CI trigger lúc PUSH, squash → push-set ≡ hôm nay); **per-path `git add` từ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.json` CREATE 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 commit `wal:` do HOOK sinh trong `git log` phiê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-DANH `wal: pause` KHÔNG `git 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ánh `wf:` §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ục `wf:` → 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ũ; field `session:` khác phiên = BÌNH-THƯỜNG, chỉ cảnh-báo nếu `updated` mớ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 trong `git log --format=%s origin/main..HEAD` (span CHƯA-push — không bao giờ rewrite đã-push X4) → K>0 → `git reset --soft HEAD~K` gộ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òng `wf:<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.md` **PHẦ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-commit `wal:`} / 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: commit `wal:` (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)"; root `CLAUDE.md` 2 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.