hs:plan
Turns a request into a plan under plans/<timestamp>-<slug>/ — researched, constraint-scanned, red-teamed and validated before a line of code. Standards are an input, never invented: it reads harness/standards/ first and stops if they're missing. The plan is a contract for hs:cook; it writes nothing outside plans/.Biến một yêu cầu thành plan dưới plans/<timestamp>-<slug>/ — đã research, đã constraint-scan, đã red-team và validate trước dòng code đầu tiên. Standards là input, không tự chế: đọc harness/standards/ trước, thiếu thì dừng. Plan là hợp đồng cho hs:cook; không ghi gì ngoài plans/.
When to useKhi nào dùng
✓ Reach for it when✓ Dùng khi
- a real feature/refactor needs phases a teammate can runfeature/refactor thật cần phase dev khác cầm chạy được
- an open decision must be pinned against existing config/standardsquyết-định-mở phải chốt theo config/standards đã có
- you want a red-team pass before spending build budgetbạn muốn một lượt red-team trước khi rót ngân sách build
✗ Not for✗ Không dùng để
- writing code — that's
hs:cook's jobviết code — đó là việc củahs:cook - approving the plan for you — sign-off is the human's calltự duyệt plan — duyệt là việc của người
- files outside
plans/file ngoàiplans/
How to run itCách chạy
Invoke it in Claude Code with your request — e.g. /hs:plan add rate-limiting to the upload endpoint. Hard mode (default) runs the full chain; add --fast for a 1–2 file, low-risk change. --tdd is orthogonal: it spells out test-first → implement-after in every phase.Gọi trong Claude Code kèm yêu cầu — ví dụ /hs:plan thêm rate-limit cho endpoint upload. Hard mode (mặc định) chạy đủ chuỗi; thêm --fast cho việc 1–2 file, rủi ro thấp. --tdd trực giao: ghi rõ test-trước → implement-sau ở mỗi phase.
Standards firstStandards trước
It reads harness/standards/ before anything. Missing → it STOPS and asks you to load them; it won't plan on an empty base.Đọc harness/standards/ trước tiên. Thiếu → DỪNG và yêu cầu bạn nạp; không plan trên nền rỗng.
Scope challengeThách thức phạm vi
Three questions — what to reuse, the minimal change set, is it >8 files / >2 new classes / >3 phases — to expand, hold, or cut before any research. Before it builds a seam it traces one credible next case that has evidence across the plan's boundaries and prices the abstraction against refactoring later: the trace yields a task or nothing, never a new mode or registry while only one real case exists.Ba câu hỏi — tái dùng gì, tập thay đổi tối thiểu, có >8 file / >2 class mới / >3 phase — để mở rộng, giữ, hoặc cắt trước khi research. Trước khi dựng một seam, nó lần theo MỘT ca tiếp theo có bằng chứng qua các ranh giới của plan và so giá abstraction với chi phí refactor về sau: kết quả là một task hoặc không gì cả, không bao giờ là mode hay registry mới khi mới có một ca thật.
Research → constraint-scanResearch → constraint-scan
Up to two researcher agents in parallel, then grep ownership.yaml, stage-policy.yaml, and schemas/ so decisions respect existing policy.Tối đa hai agent researcher song song, rồi grep ownership.yaml, stage-policy.yaml, schemas/ để quyết định tôn trọng policy đã có.
Write the planViết plan
plan.md + phase files good enough for another dev to run. Any claim without a file:line anchor gets an [ASSUMED]/[PRIOR] tag.plan.md + phase file đủ để dev khác chạy. Mọi khẳng định thiếu mỏ neo file:line bị gắn tag [ASSUMED]/[PRIOR].
Red-team → validate → sweepRed-team → validate → quét
A hostile reviewer hunts failure modes; validate resolves the [ASSUMED] tags; a consistency sweep requires 0 contradictions before it recommends cook.Reviewer thù địch săn lỗi; validate giải các tag [ASSUMED]; quét nhất quán yêu cầu 0 mâu thuẫn trước khi đề xuất cook.
You approve, then cookBạn duyệt, rồi cook
It returns the plan's absolute path and asks for your approval. Then /clear and /hs:cook <absolute-path>.Nó trả về đường dẫn tuyệt đối của plan và xin duyệt từ bạn. Rồi /clear và /hs:cook <đường-dẫn-tuyệt-đối>.
Worked example: the contract, and the gateVí dụ thật: hợp đồng, và gate
The contract chain: plan → approve → cook → test → shipChuỗi hợp đồng: plan → duyệt → cook → test → ship
One enforced path. Each step leaves an artifact the next step (or the gate) reads. Drop the plan and the chain can't reach ship. real pipeline Một đường được ép. Mỗi bước để lại artifact mà bước sau (hoặc gate) đọc. Bỏ plan là chuỗi không tới được ship. pipeline thật
A plan directory is the contract on disk — plan.md, phase files, an artifacts/ folder the gate reads, and review reports:Một thư mục plan là hợp đồng trên đĩa — plan.md, các phase file, thư mục artifacts/ mà gate đọc, và báo cáo review:
plans/260818-0400-rate-limit-middleware/ plan.md phases/phase-1-4.md artifacts/verification.json artifacts/verification-p1.json artifacts/phase-latest-P1.json artifacts/plan-approval.yaml reports/code-review-260818-p1.md
No plan, no ship — the gate, realKhông plan, không ship — gate, thật
Try to git push with no active plan. The local hook emits an advisory (exit 0) naming the gap + three exits — never a dead end; enforcement is the remote CI receipts-gate. real output
Thử git push khi không có plan active. Hook tại máy phát advisory (exit 0) nêu chỗ thiếu + ba lối ra — không bao giờ là ngõ cụt; enforcement là receipts-gate ở CI từ xa. đầu ra thật
[advisory] gate_stage: hard stage 'push' needs an active plan but none resolved. Three exits: (1) create a plan under plans/ with `status: in_progress` frontmatter; (2) set HARNESS_ACTIVE_PLAN to the plan dir; (3) set `require_plan: false` for this stage in harness/data/stage-policy.yaml (tracked in git) — presence enforcement lives in remote CI (receipts-gate) [exit 0 — local gate is advisory; the remote CI receipts-gate is the hard block]
Two modes, one orthogonal flagHai mode, một cờ trực giao
| ModeMode | WhenKhi nào | GatesGates |
|---|---|---|
| fast | small job, 1–2 files, low riskviệc nhỏ, 1–2 file, rủi ro thấp | skips research + red-teambỏ research + red-team |
| hard (default) | a real feature or refactorfeature/refactor thật | constraint-scan → red-team → validateconstraint-scan → red-team → validate |
| --tdd | orthogonal to modetrực giao với mode | each phase spells out test-first → implement-aftermỗi phase ghi rõ test-trước → implement-sau |
Under the hood — hs-run planBên trong — hs-run plan
The skill drives the plan domain of hs-run — the deterministic step-sequence engine — through 5 verbs: scaffold (create the plan dir), next (advance the chain), record (persist a step's result), prompt (return the text for the next model turn), and graph (answer plan-graph.yaml queries). Each returns a JSON envelope (state, next_action, artifacts, refs) on one of six exit codes: 0 done, 1 findings, 2 broken, 3 deliberate refusal, 10 needs a model turn, 11 one more deterministic step.Skill chạy domain plan của hs-run — engine bước chạy tất định — qua 5 verb: scaffold (tạo thư mục plan), next (tiến chuỗi), record (lưu kết quả một bước), prompt (trả text cho lượt model kế), và graph (trả lời truy vấn plan-graph.yaml). Mỗi verb trả envelope JSON (state, next_action, artifacts, refs) trên một trong sáu mã thoát: 0 xong, 1 phát hiện, 2 hỏng, 3 từ chối có chủ đích, 10 cần lượt model, 11 còn một bước tất định.
The hard-mode flowLuồng hard-mode
An Evidence Filter runs both ways: every open-decision spot must cite file:line or carry an explicit [ASSUMED] (or [PRIOR] if it rests on prior/training knowledge) tag. Validate resolves those — interactive asks via questions, headless emits a "question + suggested default" table instead of blocking.Evidence Filter hai chiều: mọi vị trí quyết-định-mở phải dẫn file:line hoặc gắn tag [ASSUMED] (hoặc [PRIOR] nếu dựa trên tri thức có sẵn). Validate giải chúng — interactive hỏi qua câu hỏi, headless phát bảng "câu hỏi + default đề xuất" thay vì chặn.
Coverage-grid mode — --gridChế độ coverage-grid — --grid
Since v5.4.0. On a higher-risk plan, add --grid. After phase decomposition (Step 6) the planner builds a coverage grid from the plan's own §features and §risks — axes are feature × layer × lifecycle × risk_class × stakeholder, and values are never hand-typed (empty features ⇒ the grid refuses to run rather than fabricate). The skeleton sits on a deterministic covering array, so every axis combination is represented without a model in the build loop.Từ v5.4.0. Với plan rủi ro cao, thêm --grid. Sau khi phân rã phase (Step 6), planner dựng một coverage grid từ chính §features và §risks của plan — trục là feature × layer × lifecycle × risk_class × stakeholder, và giá trị không bao giờ gõ tay (features rỗng ⇒ grid từ chối chạy thay vì bịa). Skeleton nằm trên một covering array tất định, nên mọi tổ hợp trục được đại diện mà không cần model trong vòng build.
Timeline is hard — build → freeze → fill: rules are pre-registered and stamped into a ## Grid constraint rules (frozen) section of plan.md before the first cell is filled, so you see them at Approve; minting a rule during fill is fraud. Coverage splits into breadth (combinations covered) and depth (cells grounded), and an N/A cell earns credit only against a frozen rule whose hash matches the approved plan — closing "mark everything N/A to inflate the score". The verdict (pass / needs-detail / reject) must be resolved before Red-team: add coverage, or attest a cell [JUSTIFIED-THIN]. Full mechanics on Methodology.Trình tự cứng — build → freeze → fill: rule được pre-register và đóng dấu vào mục ## Grid constraint rules (frozen) trong plan.md trước khi điền ô đầu tiên, nên bạn thấy chúng lúc Approve; đúc rule trong khi fill là gian lận. Coverage tách thành bề rộng (tổ hợp được phủ) và chiều sâu (ô có căn cứ), và một ô N/A chỉ được credit theo một rule đóng băng có hash khớp plan đã duyệt — chặn "đánh N/A hết để thổi điểm". Verdict (pass / needs-detail / reject) phải được giải trước Red-team: thêm coverage, hoặc attest ô [JUSTIFIED-THIN]. Cơ chế đầy đủ ở Phương pháp.
Convene a panel — --ultra / --debateTriệu tập panel — --ultra / --debate
Since v6.2.0. When several answers to the same question are genuinely defensible, add --ultra [N] or --debate. Both are shapes of ONE panel: N independent producers work the question without seeing each other, and a separate reader — hs:escalation-consultant — synthesizes their output. They are the same mechanism, differing in whether the producers argue against each other or answer in parallel. Mutually exclusive with --fast/--hard/--deep/--parallel: the combination is refused by name, not silently resolved.Từ v6.2.0. Khi cùng một câu hỏi có nhiều câu trả lời đều đứng vững được, hãy thêm --ultra [N] hoặc --debate. Cả hai là hai hình dạng của MỘT panel: N nhà sản xuất độc lập cùng làm câu hỏi đó mà không thấy nhau, và một người đọc riêng — hs:escalation-consultant — tổng hợp kết quả. Cùng một cơ chế, chỉ khác ở chỗ các nhà sản xuất tranh luận với nhau hay trả lời song song. Loại trừ lẫn nhau với --fast/--hard/--deep/--parallel: tổ hợp đó bị từ chối kèm tên, không âm thầm tự xử.
12 skills take these flags — plan among them, plus advise, code-review, brainstorm, debug, fix, research, scout, review-pr, test, problem-solving, bootstrap. hs:cook is deliberately excluded: it mutates code, and the panel is built for the read-only shape. The routing survives an edit, because it is wired twice and independently: each skill body carries the order, and a separate UserPromptSubmit hook reads the raw prompt for a panel skill plus the flag and injects the directive whether or not that paragraph is still there.12 skill nhận các cờ này — plan nằm trong đó, cùng advise, code-review, brainstorm, debug, fix, research, scout, review-pr, test, problem-solving, bootstrap. hs:cook cố ý bị loại: nó sửa code, còn panel được xây cho hình dạng chỉ-đọc. Việc định tuyến sống sót qua một lần sửa, vì nó được nối hai lần độc lập nhau: thân mỗi skill mang đoạn lệnh, và một hook UserPromptSubmit riêng đọc prompt thô tìm skill-panel cộng cờ rồi tiêm chỉ dẫn bất kể đoạn văn kia còn hay mất.
Deferred-suite mode — --defer-suiteChế độ hoãn suite — --defer-suite
Since v6.1.0. On a plan whose phases each touch a narrow, well-declared slice, add --defer-suite. It stamps defer_suite: true into the plan's frontmatter, and hs:cook reads it back with no retyping: each phase then runs only the test files that phase's plan-graph.yaml node declares, instead of the whole tree every time. The full suite is not skipped — it is deferred, and owed: the plan cannot close until one run is recorded and stamped as that run.Từ v6.1.0. Với plan mà mỗi phase chạm một lát cắt hẹp, khai rõ, hãy thêm --defer-suite. Nó đóng dấu defer_suite: true vào frontmatter, và hs:cook đọc lại mà không cần gõ lại: mỗi phase khi đó chỉ chạy đúng tập test mà node của nó khai trong plan-graph.yaml, thay vì cả cây mỗi lượt. Suite đầy đủ KHÔNG bị bỏ — nó được hoãn, và bị ghi nợ: plan không đóng được cho tới khi có một lượt chạy được ghi nhận và đóng dấu đúng là lượt đó.
The flag is a consent decision, and it is treated like one. Unlike --grid, this carry has deliberately no infer-from-disk door: no artifact on disk can imply that a person agreed to defer verification, so only the frontmatter speaks — and only a real YAML true counts. The declaration is sealed by the approval hash, which folds the parsed value and not merely the line it was written on, because every reader branches through a YAML parser and a value that reads differently than it hashes is a value editable after approval.Cờ này là một quyết định đồng ý, và nó được đối xử đúng như vậy. Khác --grid, lần mang cờ này cố ý không có cửa suy-từ-đĩa: không artifact nào trên đĩa ngụ ý được rằng một con người đã đồng ý hoãn việc kiểm chứng, nên chỉ frontmatter lên tiếng — và chỉ một true YAML thật mới tính. Khai báo đó được niêm bằng hash phê duyệt, thứ gộp cả giá trị đã parse chứ không chỉ dòng chữ viết ra nó, vì mọi bên đọc đều đi qua bộ phân tích YAML, và một giá trị đọc ra khác với lúc băm là một giá trị sửa được sau khi đã ký.
Decisions, and the gate behind themQuyết định, và gate phía sau
Decisions outlive the chatQuyết định sống lâu hơn cuộc chat
An architecture decision pinned in validate is written via decision_register.py — append-only, monotonic IDs, injection-escaped. The register kills re-litigation: meet an old tension, read the register first, don't re-argue.Một quyết định kiến trúc chốt ở validate được ghi qua decision_register.py — append-only, ID monotonic, escape injection. Register giết re-litigation: gặp lại tension cũ, đọc register trước, không cãi lại.
The enforcement gateGate cưỡng chế
plan-approval.yaml anchors a plan hash to the normalized plan directory to prevent drift. You approve locally (advisory) — and a claimed approval whose hash no longer matches the plan is rejected by the artifact-forgery block, so you can't quietly edit a plan after approval. Want a hard remote check too? Wire the optional receipts-gate CI workflow into your own repo.plan-approval.yaml neo một hash plan vào thư mục plan chuẩn-hóa để chặn lệch. Bạn duyệt local (advisory) — và một approval khai báo mà hash không còn khớp plan sẽ bị chặn giả-mạo-artifact từ chối, nên không thể lặng lẽ sửa plan sau khi duyệt. Muốn thêm kiểm cứng ở remote? Gắn workflow CI receipts-gate (tùy chọn) vào CI của repo bạn.
harness/hooks/gate_stage.py (PreToolUse·Bash, compliance) advises (exit 0, naming the gap) on push|pr|ship|deploy when the active plan is missing the required artifact; the remote CI receipts-gate is what blocks. No plan on disk → the advisory names it and CI won't accept the push. This is a presence gate (DEC-unknown-9): it catches forgotten steps, not a determined cheater.
harness/hooks/gate_stage.py (PreToolUse·Bash, compliance) advisory (exit 0, nêu chỗ thiếu) trên push|pr|ship|deploy khi plan active thiếu artifact bắt buộc; receipts-gate ở CI từ xa mới là cái chặn. Không plan trên đĩa → advisory nêu ra và CI sẽ không nhận push. Đây là presence gate (DEC-unknown-9): bắt bước bị quên, không bắt kẻ cố gian.
FAQHỏi đáp
Does hs:plan write code?hs:plan có viết code không?
plans/. Implementation is hs:cook's job — keeping planning and building separate is the point.Không. Nó chỉ ghi file dưới plans/. Việc implement là của hs:cook — tách planning và build chính là chủ đích.What happens if standards are missing?Thiếu standards thì sao?
harness/standards/ (system-architecture.md + code-standards.md) first. The plan references shared standards instead of inventing its own.Nó dừng và yêu cầu nạp harness/standards/ (system-architecture.md + code-standards.md) trước. Plan tham chiếu standards chung thay vì tự chế.When should I use --fast instead of hard mode?Khi nào dùng --fast thay vì hard mode?
Who can approve the plan?Ai được duyệt plan?
plan_hash (plus the mandatory plan-graph.yaml sidecar), so reformatting needs no re-approval but a content change does. It's recorded via plan_approval.py.Tác giả tự duyệt — personal-first, không có roster reviewer (role gate chẳng chứng minh được gì với actor giả-mạo-được qua env). Guard thật là plan_hash chuẩn hóa (kèm sidecar plan-graph.yaml bắt buộc), nên reformat không cần duyệt lại nhưng đổi nội dung thì cần. Ghi qua plan_approval.py.