Skill: harness-tour
WHAT
Purpose và context
- Purpose: Cho user THẤY (không phải đọc) harness hoạt động: bạn — Claude — cố tình vi phạm rule trên project thật, bị hook chặn theo thời gian thực, và tường thuật lại. Kết thúc không để lại rác.
- Trigger (when to use): user gõ hoặc nói "harness tour", "xem harness làm gì", "test short", "test full" (
disable-model-invocation: true
— chỉ chạy khi user gọi). Hai độ dài: SHORT (mặc định, R1·R2·R3) và FULL (R1–R10).
- Non-goals: không cài/sửa harness (chỉ gợi ý lệnh cài khi MISSING), không diễn giả khi không có hook, không đụng file có sẵn của project, không thay / (bản máy-diễn không cần phiên).
Mental model
ARGUMENTS → độ dài (SHORT|FULL) → pre-check harness (POC|PROD|MISSING) → mỗi cảnh: tường thuật → vi phạm có chủ đích trên path map 1-rule → hook chặn live → trích nguyên văn → khắc phục → dọn dẹp tour-demo* + row index cùng lượt → kết màn trích audit.jsonl
. Rule chia 3 nhóm: chặn-live (R1,R2,R3,R5,R7,R9) · ghi/nhắc không chặn (R4,R8,R10) · tầng repo (R6).
Input và output contract
| Field | Required? | Ý nghĩa |
|---|
| In | ARGUMENTS | không | chứa //"đầy đủ" → FULL; còn lại → SHORT |
| In | session mở ở root project đã cài harness | có | phải được load, không thì MISSING |
| Out | tường thuật + stderr chặn trích nguyên văn mỗi cảnh | có | vd , |
| Out | project sạch | có | mọi đã PASS bị xoá + row index tương ứng; artifact harness giữ nguyên |
| Out | kết màn | có | tóm rule vừa chặn + vài dòng cuối ; FULL thêm bảng 10 rule |
Rules và capabilities
- RULE-01 (MUST): Mỗi cảnh: tường thuật → vi phạm → trích nguyên văn lý do chặn → khắc phục. Không diễn tắt.
- RULE-02 (MUST): Chỉ đụng file tên ; tuyệt đối không sửa/xóa file có sẵn của project.
- RULE-03 (MUST): Một cảnh đáng-lẽ-chặn mà KHÔNG bị chặn → dừng tour, báo "hàng rào hỏng ở rule X" — đó là bug thật cần xử lý
(KHÔNG áp dụng cho nhóm không-chặn R4/R6/R8/R10 — chúng vốn không block).
- Capabilities: ghi/xoá file demo trong + sửa (row demo); đọc artifact audit; chạy script harness cục bộ. Phụ thuộc hook của host (PreToolUse/Stop) — không có hook thì không diễn.
Failure boundaries
- Pre-check không in gì → blocked (MISSING): DỪNG, gợi ý lệnh cài PoC + mở session mới tại root, không diễn giả.
- Cảnh đáng-lẽ-chặn mà không bị chặn → failed: dừng tour, báo "hàng rào hỏng ở rule X" (trừ R4/R6/R8/R10).
- Dọn dẹp xoá file mà sót row index → Stop hook R3 chặn chính lượt dọn → xoá row trong cùng lượt rồi kết thúc.
HOW
Main workflow
| Step | Type | Inputs | Action | Outputs/exit | Failure/next |
|---|
| W01 | deterministic | ARGUMENTS | Chọn độ dài tour | SHORT hoặc FULL | — |
| W02 | deterministic | root session | Pre-check harness (lệnh / dưới) | POC / PROD | không in gì → MISSING, dừng |
| W03 | effect | map path → rule | Diễn kịch bản SHORT (3 cảnh) hoặc FULL (R1–R10) tuần tự, tường thuật TRƯỚC mỗi cảnh | stderr chặn trích nguyên văn + file PASS | không bị chặn → dừng, báo hàng rào hỏng |
| W04 | effect | file tour-demo* đã PASS | Dọn dẹp cùng một lượt: xoá file + row index | project sạch | Stop R3 chặn → xoá row còn sót |
| W05 | deterministic | audit | Kết màn: tóm rule + | báo cáo | — |
Chi tiết từng bước (nguồn chân lý cho W01–W05):
Chọn độ dài tour (đọc ARGUMENTS)
- Chứa / / "đầy đủ" → FULL (R1–R10).
- Còn lại (mặc định, hay /) → SHORT (3 cảnh: R1 · R2 · R3).
Pre-check — phát hiện harness nào đang sống trong session
Chạy ở ROOT của session:
bash
{ grep -q llmwiki-validate .claude/settings.json 2>/dev/null && test -f harness/poc-vendor-neutral/bin/llmwiki-validate.py && echo POC; }
test -f llmwiki/.claude/hooks/pre_tool_use.py && echo PROD
- In → cách CHÍNH. PoC nay đủ R1–R10 (5 rule chặn ở PreToolUse + R3/R4/R8/R10 qua hook sự kiện).
- In → harness production. Cùng R1–R10, cùng kịch bản short/full dưới đây; chỉ khác tên hook script
(//) và R1 có thể chặn qua . Diễn y hệt.
- KHÔNG in gì → MISSING. DỪNG (đừng diễn giả), gợi ý cài (PoC là cách chính):
bash
curl -fsSL https://raw.githubusercontent.com/Rheinmir/setup/orca/harness/poc-vendor-neutral/bootstrap.sh | bash
rồi mở session Claude MỚI tại root project đó (để được load) → gõ lại .
Hook chỉ chặn khi session
load ở đúng root project đã cài. Mở session ở repo nguồn /
root khác → không có hook → tour KHÔNG diễn (diễn mà không bị chặn = dàn dựng, cấm).
Harness là HOOK, KHÔNG phải MCP (giải thích nếu user hỏi "sao /mcp không thấy")
Lớp chặn là
PreToolUse hook → kiểm bằng
hoặc khối
trong
, KHÔNG ở
.
MCP là thứ khác (tool cho model gọi). PoC: hook gọi
llmwiki-validate claude-hook
. Production:
…
Bảng map path → rule (DÙNG ĐÚNG path để mỗi cảnh chỉ kích 1 rule)
Nhiều rule cùng soi
→ chọn sai path là 2 rule cùng chặn, rối. Map chuẩn (theo
):
| Rule | File để vi phạm | Vì sao CHỈ rule đó kích |
|---|
| R1 no-write-raw | | deny_write glob |
| R2 origin-required | llmwiki/wiki/sources/draft/tour-demo.md
= ---\ntype: draft\n---\n# Tour Demo
(CÓ frontmatter, KHÔNG , KHÔNG ) | frontmatter → R9 qua; thiếu Origin → R2 chặn |
| R3 index-sync | (Stop) chính file R2 vừa tạo, CHƯA có trong | quét concepts/entities/sources/draft
so với index |
| R5 folder-structure | llmwiki/wiki/tour-demo.md
(ngay dưới , basename lạ) | forbid_root: không thuộc allow-list |
| R7 proposal-complete | llmwiki/wiki/sources/draft/tour-demo-proposal.md
— CÓ frontmatter + + + , THIẾU & | frontmatter→R9 qua, Origin→R2 qua → R7 là cái chặn |
| R9 okf-frontmatter | llmwiki/wiki/concepts/tour-demo.md
— CÓ nhưng KHÔNG có YAML frontmatter | có Origin nên R2 qua; thiếu → R9 chặn |
⚠️ R9 nay phủ
CẢ + (khớp global production — nháp cũng cần frontmatter). Vì R2/R9 cùng soi mọi content dir →
cô lập bằng NỘI DUNG, không bằng path: file CÓ frontmatter mà THIẾU Origin → chỉ R2; file CÓ Origin mà THIẾU frontmatter → chỉ R9.
Không-chặn-live (chỉ cho XEM artifact, nói rõ "không chặn"):
R4 (
.claude/audit/audit.jsonl
+
),
R8 (dòng
lúc SessionStart),
R10 (
.claude/audit/.docs-gate.json
đếm prompt).
Tầng repo:
R6 (pre-commit + CI
.github/workflows/harness.yml
+ skill
).
KỊCH BẢN SHORT (mặc định) — 3 cảnh, diễn TUẦN TỰ, tường thuật TRƯỚC mỗi cảnh
Mở màn: "Tôi sẽ cố tình vi phạm 3 rule. Xem hook chặn tôi theo thời gian thực — không phải tôi tự nhường."
Cảnh 1 — R1 (PreToolUse · deny ghi raw/):
- Tường thuật: "raw/ là inbox của con người, agent không được ghi."
- Write → exit 2 → CHẶN. Trích nguyên văn stderr . KHÔNG retry. File không ra đời.
Cảnh 2 — R2 (PreToolUse · ép ):
- Tường thuật: "Tạo file nguồn mà 'quên' → không truy được gốc."
- Write
llmwiki/wiki/sources/draft/tour-demo.md
= ---\ntype: draft\n---\n# Tour Demo
(CÓ frontmatter để R9 qua, nhưng KHÔNG có ) → exit 2 → CHẶN. Trích .
- Sửa: Write lại đúng file đó, thêm
## Origin\n- harness-tour demo
(giữ nguyên frontmatter) → lần này PASS, file được ghi.
Cảnh 3 — R3 (Stop · index nói dối):
- Tường thuật: "File tour-demo vừa tạo nhưng tôi cố tình KHÔNG ghi nó vào . Giờ thử kết thúc lượt."
- Kết thúc response tại đây mà không cập nhật index → Stop hook () trả exit 2, đưa danh sách lệch về.
- Khi bị block: trích nguyên văn
[R3 index-sync] wiki/index.md chưa liệt kê: …
, rồi thêm đúng 1 row cho tour-demo vào , sang dọn dẹp.
→ tiếp Dọn dẹp (dưới).
KỊCH BẢN FULL (khi ARGUMENTS có ) — R1–R10 tuần tự
Diễn 6 cảnh chặn-live (R1,R2,R3,R5,R7,R9) + 3 cái không-chặn cho xem artifact (R4,R8,R10) + 1 cái repo (R6).
Nói rõ trước nhóm không-chặn: "3 rule sau KHÔNG chặn lúc gõ — chúng GHI/NHẮC; tôi sẽ chỉ artifact làm bằng."
R1 — Write → CHẶN (deny raw/). Trích, không retry.
R2 — Write llmwiki/wiki/sources/draft/tour-demo.md
(CÓ frontmatter
để R9 qua, nhưng thiếu
) → CHẶN → thêm
→ PASS.
R3 — (Stop) kết thúc lượt khi file R2 chưa vào
→ Stop block → thêm row index → tiếp.
(Trong FULL, để liền mạch có thể gộp R3 vào cuối: sau khi tạo các file PASS bên dưới, thử kết thúc 1 lượt còn lệch index → block → cập nhật index.)
R4 — log-append (KHÔNG chặn): sau một Write PASS, chỉ
.claude/audit/audit.jsonl
vừa có dòng mới (tool+path+timestamp) và
được sinh lại.
vài dòng cuối làm bằng — "máy ghi, tôi không xoá được."
R5 — Write llmwiki/wiki/tour-demo.md
(ngay dưới
) → CHẶN
(file wiki phải nằm trong concepts/entities/…). Không retry.
R6 — verify-before-commit (repo, KHÔNG chặn-live): chỉ ra cổng commit gồm pre-commit hook + CI
.github/workflows/harness.yml
(gọi lõi
mode trên .md đổi) + skill
(Claude tự soi code mới trước khi commit). Đây là tầng repo, không phải session — không demo block trực tiếp.
R7 — Write llmwiki/wiki/sources/draft/tour-demo-proposal.md
có frontmatter +
+
+
nhưng THIẾU
&
→ CHẶN
→ sửa thêm 2 mục đó → PASS.
R8 — pattern-health (KHÔNG chặn): chạy
python3 harness/poc-vendor-neutral/bin/harness-events.py session
để hiện dòng
[harness] N rule đang gác…
(+ cảnh báo drift nếu policy lệch remote). Đây là thứ in lúc SessionStart.
R9 — Write llmwiki/wiki/concepts/tour-demo.md
có
nhưng KHÔNG có YAML frontmatter → CHẶN
(thiếu
) → sửa thêm
lên đầu → PASS.
R10 — docs-gate (KHÔNG chặn): cat .claude/audit/.docs-gate.json
cho thấy bộ đếm prompt; giải thích mỗi
(mặc định 5) lượt, UserPromptSubmit chèn directive đề nghị gọi
.
Kết FULL: bảng 10 rule — cái nào chặn-live, cái nào ghi/nhắc, cái nào ở repo; trích
làm bằng.
Dọn dẹp (BẮT BUỘC — cùng một lượt, kẻo R3 chặn)
Xóa MỌI file
đã
PASS (được tạo)
và xóa row tương ứng trong
trong cùng lượt
(xóa file mà để row → index lệch → Stop hook chặn chính lượt dọn):
- SHORT:
wiki/sources/draft/tour-demo.md
+ row của nó.
- FULL: thêm
wiki/sources/draft/tour-demo-proposal.md
, wiki/concepts/tour-demo.md
+ các row.
- Các file bị CHẶN (raw/tour-demo, wiki/tour-demo R5) không tồn tại → khỏi xóa.
- Artifact harness (, , ) là bản ghi máy hợp lệ → giữ nguyên, không xóa.
- TUYỆT ĐỐI không đụng file có sẵn khác của project.
Kết màn: tóm 1 đoạn các rule vừa chặn + "mọi tool call vừa rồi nằm trong
— máy ghi, tôi không quên được" (cat vài dòng cuối). Bản máy-diễn không cần phiên:
bash harness/poc-vendor-neutral/demo.sh
(13 assertion) ·
(63).
Branches
| ID | Kind | Guard | Hành vi | Skip / failure | Rejoin |
|---|
| B01 | user_optional | ARGUMENTS có / / "đầy đủ" | KỊCH BẢN FULL R1–R10 thay SHORT | mặc định → SHORT | W04 |
| B02 | conditional_required | pre-check in | diễn y hệt, chỉ khác tên hook script (//), R1 có thể chặn qua | — | W03 |
| B03 | recovery | pre-check không in gì (MISSING) | DỪNG, gợi ý lệnh curl PoC (khối Pre-check) rồi mở session MỚI tại root project | không diễn | kết thúc |
| B04 | user_optional | user hỏi "sao /mcp không thấy" | giải thích harness là HOOK (kiểm ), không phải MCP | — | W03 |
Validation và stopping
Mỗi cảnh chặn-live chỉ tính khi hook thật trả exit 2 và stderr được trích nguyên văn; không retry sau chặn (trừ bước khắc phục đã định). Tour dừng ngay khi một rule chặn-live không chặn. Xong khi không còn
và
khớp.
Examples
- Positive: trên project đã cài PoC → pre-check in → Write bị chặn → R2 chặn rồi PASS sau khi thêm → kết lượt bị Stop → thêm row → dọn
wiki/sources/draft/tour-demo.md
+ row cùng lượt.
- Boundary/failure: mở ở repo nguồn (không load của project) → pre-check không in gì → MISSING, dừng, gợi ý lệnh curl bootstrap + mở session mới; không diễn cảnh nào.