§L.a RCA: - E-012 + AS-16 NEW "bằng-chứng-tự-huỷ-sau-squash": outward artifact cite sha chưa-push / stamp trước khi git status sạch. Root = tiêu-chí verify chọn theo cái MÌNH đo được, không theo cái NGƯỜI NHẬN sẽ đo (cùng lớp E-010). Đối chứng: wave trước cite commit đích -> sống hết. §L.b: - (c) memory-triple: do exit 0 · de-xuat A7 251/251 · kiem reviewer FAIL 1C/4M/4m/1nit · do-record TOTAL 47 + nhip-no 4-vế. sleep-check 4d < 7d -> không INFORM. - (d)(f) harvest-curator GATE-PASS-5, 5-trục PASS, Fidelity on-behalf PASS STRONG 0-fabrication, C5 dạng-1 đủ, orphan 0/40, Sàn-5 khớp. Spawn-record 5 sub. - (g) tooling-auditor DRIFT-FOUND(4) -> vá hết: F-A doc "3-vế" vs script 4-vế (7 site prescriptive; giữ 15 file frozen) · F-B ghost-enum HIGH (mở enum 10->11 mà quên chính vai dùng nó + 2 site số) · F-C lead-model pin chưa ghi sổ (thêm dòng Lead row S143; cell canonical để owner quyết) · F-D marketplace. - (j) H24: class_repeat cập theo 2 vai · last_audit light/deep = 17 · history +S143 (khai rõ force-fire SỚM 1 nhịp theo lệnh owner, KHÔNG tới-hạn tự-nhiên). - (k) trio SKIP có vết (cần restart CLI) -> ghi CẢ session-log vì §6.4 reset WAL. Sửa-một-phía bắt được 4 lần trong phiên (tool-grant · enum · sổ đếm garble · _note counter) -> bài: đổi một con số thì grep con số đó repo-wide trước khi đóng. #53: 5/5 sub garble, 0 mất dữ-liệu nhờ ghi-đĩa. Tally ×20 -> ×25, +path-4 lead-on-behalf khi resume không cứu được diary. Test 528 kế-thừa (0 file src/fe/tests bị đụng, verify bằng diff). Bundle FROZEN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
16 KiB
/tiep — recovery MỘT đường cho MỌI kiểu gián-đoạn (Harness-22 WAL session-continuity)
Đây là đường recovery DUY-NHẤT để nối lại mạch việc dở sau bất-kỳ kiểu gián-đoạn nào — hết giới-hạn, crash, tắt máy, đổi tài-khoản, hay chết giữa một workflow. Gõ
/tiep(kể cả khi user chỉ nói "làm tiếp" bằng text thường). Cặp với/pause. Đặt tên/tiepđể tránh đè lệnh dựng-sẵn (/resume,/continue).
Thực-hiện tuần-tự: §0 (sàn) → §1 → §2 → §3 → §4.
0. 🔴 Sàn-3 canonical — "sổ trống ≠ sạch" (ĐỊNH-NGHĨA MỘT CHỖ DUY-NHẤT)
🔴 Đây là định-nghĩa DUY-NHẤT của "còn việc dở không?".
/session-startBƯỚC 0.7 chỉ TRỎ vào đây, CẤM chép logic sang (B1 con-trỏ-canonical). Hai điểm-vào (/tiep+0.7) PHẢI gọi cùng một định-nghĩa — nếu không, hai đường sẽ trả lời khác nhau về cùng một sự thật.Vì sao sàn này tồn-tại: WAL trống KHÔNG hàm ý sạch. Suy thẳng "chain rỗng ⇒ không có mạch dở ⇒ dừng" là BUG, và nó đã từng sống ngay trong chính file này (
tiep.md:15cũ) +session-start.md:51— lead mắc thật, không phải giả-định.
Vì sao WAL trống không đủ: hook có 3 điểm mù
.claude/hooks/wal-flush.ps1:7 tự-commit 3 path ở turn-boundary: .claude/WAL.md · .claude/agent-memory/ · .claude/workflows/runs/.
⇒ Hai tín-hiệu trực-giác nhất — "cây bẩn" và "có commit chưa đẩy" — đều MÙ đúng 3 vùng đó: hook vừa dọn sạch cây, vừa biến việc-dở thành wal: commit trông như nhiễu.
⇒ Nên phải soi bằng tín-hiệu hook KHÔNG chạm tới được.
🔴 BẬC MẠNH — thấy 1 trong 4 ⇒ HỎI LẠI ANH, KHÔNG tự kết-luận sạch
| # | Tín-hiệu | Vì sao đáng tin | Lệnh |
|---|---|---|---|
| ① | Orphan run-folder: runs/<id>/ có run.md mà không có bản-ghi-kết-quả (xem DUAL-ACCEPT dưới) |
git-independent — miễn-nhiễm hook hoàn-toàn (đọc đĩa, không đọc git) | xem block dưới |
| ② | origin/main..HEAD có commit KHÔNG phải wal: |
hook không bao giờ sinh loại commit này ⇒ có = người làm thật ⇒ không mù | git log --format='%s' origin/main..HEAD | grep -qv '^wal:' |
| ③ | closing: treo trong WAL |
= Sàn-2 sentinel (xem §0.b) | grep -q '^closing:' .claude/WAL.md |
| ④ | wal:-commit chưa đẩy có đụng .claude/workflows/runs/ |
🔴 thu-hồi một phần điểm mù: dù WAL.md bị xoá trắng, commit của chính hook vẫn tố-giác rằng một run đã được dựng |
git log --name-only --format='%s' origin/main..HEAD | grep -q 'workflows/runs/' |
① DUAL-ACCEPT — 2 dạng bản-ghi-kết-quả TÍNH LÀ ĐÓNG (dạng-3 RETIRED @S123 — xem dưới)
🔴 Nấc chuẩn (S122): câu hỏi là "đã harvest chưa" — một câu hỏi về NỘI DUNG. Nếu chỉ đo TÊN FILE thì detector đo cái dễ đo, không phải cái cần đo. Đo thật @S122: 8 dương-giả / 25 run = 32%, trong đó folder ghi chép đầy-đủ nhất (
pe-negative-quote: có cicd PASS + bundle-hash + smoke 200 + 6 stage[x]) vẫn bị xếp orphan. ⇒ nhận dạng-2 là làm detector ĐÚNG, KHÔNG phải làm nó dễ dãi.
for d in .claude/workflows/runs/*/; do
[ -f "$d/run.md" ] || continue # không có run.md ⇒ không phải run ⇒ bỏ qua
found=0
# dạng-1 — file PHẲNG (hiện-hành, h10-refine). `-s` = tồn-tại VÀ khác 0-byte.
for f in "$d"/*-synthesis.md; do [ -s "$f" ] && found=1 && break; done
[ $found -eq 1 ] && continue
# dạng-2 — C8 legacy. VERBATIM `workflows/README.md:19`:
# "C8: 5 run cũ S71 (h10-invest…h910-curate) giữ sub-md/+harvest/ (đừng rewrite
# history); close-gate chấp nhận CẢ HAI dạng."
for f in "$d"/harvest/*-synthesis.md; do [ -s "$f" ] && found=1 && break; done
[ $found -eq 1 ] && continue
echo "ORPHAN: $d"
done
🧊 dạng-3 RETIRED @S123 (anh chốt) — nhánh
grep -qiE '^#+[[:space:]]*synthesis' "$d/run.md"đã GỠ. Đo trước khi gỡ, 2 phép độc-lập (harvest-curator + lead), khớp nhau: bỏ nhánh dạng-3 ⇒ 0 folder thành orphan. Lý do lộ ở đối-chứng: cả 6 folder từng dựa dạng-3 (S112×4 ·S113·S114) nay đều có flat*-synthesis.mdsau retro-harvest22ea8c5⇒ dạng-1 bắt hết, dạng-3 dư-thừa hoàn-toàn. 🔴 LUẬT retire (phát-biểu ĐÚNG — S123 review bắt bản đầu viết sai): gỡ một nhánh legacy khi tập di-sản của nó RỖNG; giữ khi CÒN người thụ-hưởng. dạng-3 → 0 folder ⇒ gỡ. dạng-2 → 5 folder ⇒ giữ. Miễn-trừ C8 (tha di-sản) hết hiệu-lực đúng lúc hết di-sản để tha, không sớm hơn. ⚠️ Bản đầu S123 viết lý-do là: "doc CẤM viết mới mà máy VẪN NHẬN ⇒ cấm-bằng-trí-nhớ ⇒ gỡ". Nghe xuôi nhưng SAI — reviewer áp thẳng nó cho dạng-2:workflows/README.mdcũng ghi dạng-2 = "legacy C8 — nhận, cấm viết mới" ⇒ cùng hình-dạng ⇒ theo lý-do đó thì phải gỡ luôn dạng-2 ⇒ 5 folder S71 thành orphan ⇒ ép rewrite history mà chính C8 cấm. ⇒ Lý-do viết ra ≠ lý-do thật đang vận-hành. Bài: áp luật vừa viết cho nhánh ANH EM — vỡ thì luật sai, không phải nhánh sai. 🔸 Hệ-quả phụ (thật, nhưng KHÔNG phải lý-do): sau khi gỡ, luật và máy nói cùng một câu về dạng-3 ⇒ hết cần trí-nhớ để NÊU. Đó là cái được, không phải cái biện-minh.
🧪 Block này ĐÃ fault-inject trên cây tạm — S122 9/9 PASS, RE-VERIFY @S123 sau khi gỡ dạng-3: 7/7 PASS, chứng có RĂNG cả 2 chiều: FLAG đúng → orphan-thật · flat 0-byte · C8 0-byte · 🔴 run.md có
## Synthesismà KHÔNG có flat (ca này S122 IM, S123 FLAG — chính là hiệu-lực của việc retire). IM đúng → dạng-1 · dạng-2 · folder không córun.md. 🔴 Ca "0-byte" là ca anti-Goodhart — thiếu nó thì happy-path vẫn xanh mà sàn đã thủng. 🧊 2 ca S122 nay hết nghĩa (dạng-3IM ·"synthesis" giữa câu vănFLAG) — cả hai đo nhánh đã gỡ. Giữ lại làm chứng lịch-sử, KHÔNG phải test đang chạy.
⚠️ KHAI THẲNG 2 giới-hạn (đừng đọc thành "đã kín"):
- Dạng-4 KHÔNG máy nào bắt được — lập-luận CÒN ĐÚNG, ví-dụ ĐÃ LỖI-THỜI. Nhận dạng-4 = phải chấp-nhận "bất-kỳ run.md nào có vẻ nói về kết-quả" ⇒ quá lỏng, thành vô-nghĩa ⇒ dạng-4 để nguyên cho người phán, KHÔNG cơ-khí-hoá. Đây vẫn là kẽ CÒN LẠI. 🧊 Nhưng ví-dụ minh-hoạ thì đã chết — đính-chính @S123: bản S122 viết "
pe-negative-quoteghi kết-quả rải trong## Stages+## wf run-id… không phải chuyện đã xử". Đo lại:22ea8c5@14:28 đã thêmimplement-synthesis.md8.249B cho đúng folder đó ⇒ nay nó là dạng-1, máy bắt được. Mà câu văn kia viết ởdfa3dae@14:48 — SAU 20 phút. ⇒ doc khai "chưa xử" cho đúng thứ chính tác-giả nó vừa xử xong (stale-at-birth). 🔴 Vì sao phải đính-chính chứ không xoá cả mục: người đọc greppe-negative-quote→ thấy flat-file → kết-luận "cảnh-báo này sai" → vứt luôn cái caveat còn đúng. Ví-dụ chết kéo theo lập-luận sống. Đây là classacceptance literal tự-lão-hoá(S121): neo lập-luận vào một literal cụ-thể thì literal đổi là lập-luận mất uy-tín oan. Bài rút ra: neo vào TÍNH-CHẤT ("run.md kể kết-quả mà không có headingsynthesisnào"), đừng neo vào TÊN FOLDER.- Dual-accept = lưới PHÁT-HIỆN cho bản CŨ, KHÔNG phải giấy phép VIẾT bản MỚI. Đúng khuôn C8 đã dùng sẵn (tha di-sản, cấm viết mới kiểu cũ). 🔴 Run MỚI BẮT BUỘC ghi dạng-1 (
<stage>-synthesis.mdphẳng) —workflows/README.md:17thiết-kế tên file mang nghĩa (RAWsub-⟂ VERIFIED-synthesis.md); dạng-3 phá đúng thiết-kế đó. Đo @S122: cùng ngày 07-12,h22-wal-adoptghi dạng-1 cònS112-*ghi dạng-3 ⇒ thói-quen không nhất-quán, KHÔNG phải migration. ✅ @S123 khoảng-cách doc-vs-máy này ĐÃ ĐÓNG: trước đây doc cấm dạng-3 mà detector nhận ⇒ cấm bằng trí-nhớ. Nay gỡ nhánh dạng-3 ⇒ luật và máy nói cùng một câu. Di-sản không kêu oan (6 folder cũ đều đã có flat), mà tái-sinh thì máy bắt được ngay.
🟡 BẬC TRUNG-BÌNH — nhiều file bẩn NGOÀI 3 path hook persist
🔴 PHẢI loại nhiễu EOL TRƯỚC khi đếm — repo có ~188 file dính EOL-only diff; không loại thì bậc này LUÔN KÊU ⇒ tự vô-hiệu-hoá. Bẩn ngoài 3 path + không phải EOL-only ⇒ NÊU, hỏi lại nếu nhiều.
⚪ BẬC YẾU — bẩn thô (git status --porcelain khác rỗng)
Tín-hiệu YẾU NHẤT, dùng cuối. 🔴 porcelain rỗng KHÔNG phải bằng-chứng sạch — đo thật @S122: git MÙ hoàn-toàn với thư-mục RỖNG, nên 2 probe-dir tồn-tại trên đĩa suốt mà porcelain vẫn rỗng ⇒ dương-giả. Công-cụ quét-đĩa thấy, git không thấy.
Kết-luận sàn
- Bậc MẠNH thấy ≥1 ⇒ HỎI LẠI ANH (nêu rõ tín-hiệu nào, đường-dẫn nào). CẤM tự kết-luận "sạch".
- Cả 4 tín-hiệu MẠNH đều im + WAL chain rỗng/toàn
[x]⇒ mới được báo "không có mạch dở" và DỪNG SẠCH.
0.b Sàn-2 — đọc sentinel closing: (self-heal)
session-endghiclosing: S<nn> @<ts>vào WAL ở BƯỚC 0 (trước mọi flush); xoá ở§6.4.- ⇒ Thấy
closing:treo = phiên trước bị cắt GIỮA lúc đóng sổ (không phải đóng xong). - Self-heal:
closing:treo NHƯNG cả 4 tín-hiệu MẠNH khác đều im + ground-truth sạch ⇒ dọn dấu 1 lần, đi tiếp (không bắt anh xử tay). closing:treo VÀ có tín-hiệu MẠNH khác ⇒ HỎI LẠI.
1. Đọc .claude/WAL.md
- Đọc file
.claude/WAL.md. - Chain rỗng / toàn
[x]/ file không tồn-tại ⇒ 🔴 CHƯA ĐƯỢC KẾT-LUẬN GÌ. Bắt buộc chạy §0 bậc MẠNH trước:- Có tín-hiệu MẠNH ⇒ HỎI LẠI ANH (sổ trống nhưng đĩa nói còn việc — đúng ca sàn này sinh ra để bắt).
- 4/4 tín-hiệu MẠNH im ⇒ báo "không có mạch dở" và DỪNG SẠCH. KHÔNG bịa việc.
- (🧊 Bản trước S122 suy thẳng "chain rỗng ⇒ dừng sạch" — đó là bug, chính là thứ Sàn-3 vá.)
2. Đối-chứng ground-truth
- Chạy TOÀN BỘ lệnh trong
verify:. - VÀ đọc thêm
git status+ disk run-folder liên-quan — per-turn ≠ per-task (N9): các return của agent có thể mất khi phiên chết, NHƯNG file per-agent trên đĩa vẫn còn; nên đọc đĩa, đừng chỉ tin returns. - So kết-quả thực-tế với
chain:.
2.5 TICK counter + dòng-nợ (H24 — TICK TRƯỚC, dòng-nợ SAU; Item 1(b)+2 S135)
- TICK
.claude/governance/.session-counter.jsontheo contract (idempotent — NO-OP nếu cùng nhãn-phiên/cùng HEAD) — 🔴 CON-TRỎsession-start.md §2.1.8, CẤM chép logic tick (B1 canonical). Nhãn/tiep= nhãn-phiên MỚI (label-convention §2.1.8) ⇒ tick fire NGAY cửa vào, OVERDUE @9 hiện tại đây thay vì đợi cuối phiên. - Dòng-nợ (SAU tick — n-3): gọi
powershell.exe -ExecutionPolicy Bypass -File scripts/nhip-no-probe.ps1in dòng-nợ 4-vế (vế-1 nhịp-kiểm đọc post-tick). 🔴 probe KHÔNG chặn điểm dừng: lỗi → inprobe-loi (khong chan)→ đi tiếp.
3. Ground-truth thắng WAL
- LỆCH (kết-quả
verify:/git statusmâu-thuẫnchain:) → TIN GROUND-TRUTH: sửa WAL cho khớp thực-tế, báo chỗ lệch cho user, RỒI MỚI chạy tiếp. KHÔNG mù-quáng chạy theo chain sai. - KHỚP → thực-thi từ
next:, nối chain theo thứ-tự các mục còn[!]/[ ].
§3-bis — 🧾 in MASTER-CHECKLIST (cập-nhật từ WAL đã reconcile ở §3; VIEW derive tươi, KHÔNG file nguồn): derive từ WAL (đã ground-truth-reconcile) + HANDOFF —
- vừa-xong (mục vừa chuyển
[!]→[x]khi reconcile) · vẫn-treo ([!]/[ ]còn lại) · chờ-anh — 🔢 BẮT BUỘC ĐÁNH SỐ (anh trả lời bằng số). 🔴 Checklist = VIEW derive tươi — CẤM tạo file checklist nguồn-đôi (sàn-3).
4. Mục [!] dạng wf: → nhánh recovery-workflow
Nếu mục dở là một dòng wf: (chết giữa workflow) → relaunch ĐÃ-CẮT-GỌT, KHÔNG chạy lại từ đầu:
- Đọc run-folder +
## taskList snapshottrongrun.md(danh-sách-task + nội-dung spec đã snapshot lúc phóng). - Lấy bằng-chứng task-nào-đã-xong bằng cách grep run-id trong log-phiên (glob đường-dẫn — đây là grep ĐÍCH-DANH một chuỗi, KHÔNG nạp lại toàn-bộ transcript).
- Harvest-hồi-tố phần đã xong: lead verify rồi append trí-nhớ, đánh-dấu harvest partial-honest.
- RELAUNCH workflow chỉ với các task CÒN LẠI + memory-pack DẪN-XUẤT-LẠI TƯƠI (🔴 CẤM dùng snapshot memory-pack cũ — nó lỗi-thời sau khi đã harvest phần xong).
- 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; mặc-định dùng relaunch-đã-cắt-gọt.
Xong nhánh workflow thì vận-hành bình-thường tiếp (lead cập-nhật WAL sau mỗi subtask đổi trạng-thái).
🔒 CẤM tuyệt-đối:
- CẤM giả-định một bước đã xong nếu
verify:KHÔNG chứng-minh. - CẤM nạp lại transcript cũ — WAL + ground-truth (
verify:+git status+ đĩa) là ĐỦ; nếu thiếu thông-tin thì HỎI anh, đừng đoán.
ℹ️ Field session:: khác phiên hiện-tại là BÌNH-THƯỜNG — đó chính là use-case của /tiep (nối qua phiên / đổi acc). CHỈ cảnh-báo khi updated: mới hơn cả lúc phiên hiện-tại bắt đầu (dấu-hiệu có một phiên khác đang chạy song-song trên cùng repo).