From hone
Execute one or more Plans unattended through the hone loop: worktree, build (test-first), verify, consolidate, /code-review, land. Confirms each step by its artifacts, never a subagent's report; proceeds without checking in and stops only when blocked-unresolvable, genuinely ambiguous, or done, leaving the worktree as evidence. Invoke with /hone:run [change | --all].
How this skill is triggered — by the user, by Claude, or both
Slash command
/hone:run [change-name | --all][change-name | --all]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Input: $ARGUMENTS
Input: $ARGUMENTS
run is the automatic half of hone. Given a Plan it drives the whole loop and
lands the change green, unattended. It reports each step's completion from that
step's artifacts (the diff, the gate output, the review verdict), never from
a subagent's claim that it finished.
Resolve $ARGUMENTS:
<change>: run the single Plan .plans/<change>.md.--all: run every ready Plan in .plans/, each in its own worktree, landing
them one at a time (below)..plans/; if exactly one, run it; else ask which.Setup check: if scripts/run-tests.sh is missing, stop and tell the user to run
bash "${CLAUDE_PLUGIN_ROOT}/scripts/setup.sh" first; without the adapter the
gate can't verify anything.
Three hooks enforce the laws as you work: the guard (PreToolUse: test-first,
and no durable edits in the primary tree), the gate (Stop: the suite,
type-check, and lint stay green), and the nag (Stop, advisory: Plan and Note
hygiene).
Run these steps in order. Do not skip a step, and do not proceed past a step whose artifact does not confirm it. Two points stop and escalate: verify can't go green (stop-point 1) and review finds the change ambiguous (stop-point 2). The third way to stop is simply done (see The three ways to stop). On an escalating stop, leave the worktree in place as evidence and report. Never disable a gate to get past it.
The Plan check already happened: the plan-critic approved the Plan at
/hone:plan, with the human present to revise a rejection. Do not re-run it
here; spawn the worktree and build.
Spawn an isolated worktree and work in it for every step below:
WT=$(bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree.sh" add <change>)
That creates .worktrees/<change> on branch hone/<change> and prints its path.
cd "$WT". All build/verify/consolidate work happens here; the primary tree is a
merge target and the guard will block durable edits made in it.
The worktree is the change's claim, and the add is atomic: if it exits 4,
this change is already claimed: another run (in another session) owns it, or a
crashed run left it behind. Do not adopt that worktree: a single named change
stops and reports it (the human resumes leftover work by hand); under --all
it is skipped (below). Only exit 0 means you own this change and may proceed.
Implement the Plan test-first, one behaviour at a time. The guard enforces the
order, so work with it:
scripts/run-tests.sh <file> and
watch it fail for the right reason. A test that passes on first run is
test-after: the code was written first or the test asserts nothing; discard
and rewrite it.scripts/run-tests.sh (unit
tier); all green.A bug fix is the same loop: the first red test reproduces the defect, then you fix the root cause. Never fix first and add a confirming test after.
An unrelated defect discovered en route (broken tooling, a latent bug the Plan never mentioned) does not ride inside the change's commit. Fix it with its own red-green cycle and its own commit on the branch, honestly typed; if it is substantial, stop and escalate for its own Plan. The landing commit's body still notes the discovery; the fix just doesn't hide in an unrelated diff.
Where the Plan names a critical path, prefer a property test for any
universal invariant (parse(serialize(x)) == x) alongside the example tests.
bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree.sh" verify. Never run the
adapter bare with --all: full-suite runs share one cross-session lock with
land, because e2e tiers are load-sensitive and a suite racing another
session's suite or land produces phantom flakes and spurious rollbacks. The
wrapper waits its turn. (Per-file and unit-tier runs during build need no
wrapper.)scripts/typecheck.sh and scripts/lint.sh if present. All must be
green.hone/<change> branch it escalates to --all under the same
lock (so an integration regression can't merge on a green unit tier alone);
while the tree is dirty it runs the fast unit tier.timeout. Run the gate (and any long build or verify
command) in your Bash tool's background mode and poll it to completion, never
in the foreground where a kill reads as a spurious failure.Close verify by stating each check's outcome (tests, type-check, lint, mutation), including any skip with its reason ("mutation: skipped — no critical path named in the Plan"). An unstated skip is indistinguishable from a forgotten check, and this receipt is what a later audit of the transcript reads.
If verify cannot go green and you have exhausted the fix, stop and escalate (stop-point 1), leaving the worktree as evidence.
This is the only step that writes docs/ and the only step that prunes tests.
Sort everything the change leaves behind that is worth keeping into the place
where it can't go stale, applying the cut test (never write a line an agent
could recover from the code; if it can be a type, it already became one at
build):
docs/notes/<area>.md,
a map + one invariant, size-capped, 1:1 with an area);docs/decisions/<topic>.md, present-tense, one per topic, edited in place);docs/open-questions.md entry;.plans/<change>.md with git rm, here in the worktree. The Plan
is tracked and committed on the trunk, so the worktree checked it out; remove
it as part of this change (git rm .plans/<change>.md from $WT), and the
landing merge carries the deletion back to the primary tree. git history keeps
the Plan; the working tree does not. The Plan has done its job. (Already gone,
because you git-rm'd it earlier? Fine, do not re-add it.)Then submit the change to the consolidate-critic agent (Task tool,
subagent_type: consolidate-critic) with a constructed brief: the diff, the
Plan (still in hand), and the Decisions/Notes touched. It is prompted to argue
for deletion: a Decision restating code, a Note drifting into a spec, a
redundant test, an abstraction not earning its keep. Apply its accepted findings
(more pruning), or record why not.
/code-reviewRun Claude Code's built-in /code-review on the finished change (the worktree
diff) once: it is multi-agent (parallel finders plus a verification pass) and
the loop's most expensive step, so it runs a single time and hone reuses it rather
than shipping a reviewer. Give it a constructed brief: pass the Plan text (still in
hand, the file is gone) along with the diff, so the reviewer can tell a violation
of the Plan's stated stance from the stance itself.
The command is user-invocation-only (disable-model-invocation): the Skill
tool, a SlashCommand tool, and subagents all refuse it. That refusal is
expected: do not hand-roll a substitute reviewer (no Workflow, no
fan-out of Agent/Task finders); each one silently abandons the native review
this step reuses and is a step failure even when it produces findings. A slash
command in a print-mode (-p) prompt is a user invocation, so run the genuine
reviewer by nesting a headless Claude Code. Write the brief to a file, then invoke
it with the worktree as the working directory so the command's own git diff sees
the local change. Run it in the background (your Bash tool's background mode, not a
shell &) and poll the output file, because the fan-out outlasts the ~2m
foreground timeout:
claude -p "/code-review $(cat <brief-file>)" \
--add-dir <worktree> \
--allowedTools "Task Agent Read Grep Glob Bash(git *)" \
--model opus --effort high \
--output-format json > <out-file> 2>&1
That JSON envelope is this step's artifact. Before you trust any finding,
confirm it is real: <out-file> parses as JSON with is_error: false,
subtype: success, and a session_id. If it is missing, truncated, an error
envelope, or absent because you produced findings some other way, the native
review did not happen: fix it by running the nested call, never review around
it. Only once the envelope confirms do you read the review from its .result and
feed it into the triage below.
The full rationale lives in references/code-review.md: why the refusal happens,
why a hand-rolled substitute fails the step, the envelope-validation details, and
the marketplace-plugin decoy to avoid. Read it if this step misbehaves.
Triage its findings against the Plan:
verify, not by a second review.docs/open-questions.md entry. A decline that lives only in
the conversation is lost to the next cycle.Triage is yours; never pause to ask how many findings to apply. run is
unattended and a scope question is not a genuine fork. The default: apply every
confirmed finding inside the Plan's scope, and record out-of-scope ones
durably as follow-up material (a docs/open-questions.md entry, or a note in
the landing commit body suggesting a future Plan) rather than expanding the
change or blocking on a human.
If the review surfaces something that makes the change genuinely ambiguous or wrong to land (not merely large or out of scope), stop and escalate (stop-point 2).
Commit in the worktree, then hand the merge to worktree.sh land:
In $WT: git add -A && git commit with a Conventional Commits message. The
Decision(s) this change governs land in this same commit as the code.
The type follows the dominant durable artifact: a change that alters the
behaviour of deploy/ or scripts/ is never docs:, whatever prose rode
along. The body carries a Cut: line naming what consolidate removed
(pruned tests, dead code, deleted doc lines), or Cut: nothing, with the
reason, when there genuinely was nothing; the nag flags a zero-deletion
change, and this line is its answer. If the Plan declared Proof: real-environment, carry that same Proof: real-environment line in the
body: it is how land's proof gate (on by default) knows an assertion-level
suite is not enough for this change.
From the primary tree, land the branch:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree.sh" land <change>
That takes the land lock, so it is safe even when another run is
landing into the same primary tree at the same time: it waits its turn
instead of interleaving. Under the lock it merges --no-ff, re-runs the
whole suite in the primary tree (green confirms the merge: the
confirmation is the suite, not the merge succeeding), and on green removes
the worktree and deletes the branch. Read its exit:
land rolled it back (the primary
tree is left green) and kept the worktree as evidence. Stop and
escalate (this is stop-point 1 surfacing at land).--all
independence check missed an overlap: fold this change in serially and
flag it for a Decision-level look. Do not force the merge..hone-proof-off disables it) found a
Proof: real-environment change whose proof is still missing (no green
scripts/proof.sh, no .hone-proof/<change> sign-off). The merge did not
happen; the worktree
is kept. Stop and escalate, because the real-environment check is out of
the loop's boundary; the human runs the journey/canary and signs it off.
Never sign it off yourself..hone-authority-off disables it)
classified this as an irreversible change (destructive SQL, a db/ deletion, a
.hone-consequential-paths match) and found no .hone-grant/<change>. The
merge did not happen; the worktree is kept. Stop and escalate: this
needs the human's scoped grant, not a workaround. Never create the grant
yourself: authority is theirs to give.Never merge by hand, and never move the primary tree's HEAD
(git checkout/switch/stash/reset) to investigate: that races every
other session sharing the tree, and the bash-guard will stop you. The
primary tree stays on the trunk as a merge target; do any investigation in a
throwaway git worktree add --detach scratch tree.
Confirm to the user: what landed, the Decisions/Notes written, what was deleted (the Plan, and any pruned tests; every cycle removes something).
--all — many changes at onceParallelism is run over several Plans, not a special mode, and it is never
assumed. Check independence first, before spawning any worktree. Each
plan-critic ran at plan time, before later Plans existed; this is the first
moment the whole set is visible, so the cross-check is yours.
Read every ready Plan and compare them pairwise: the files and areas each
expects to change (its Notes for the loop, its What, a quick look at
src/), any shared type or persistent contract (a DB schema, a public API, a
wire or file format), and any Decision or Note more than one would touch. Then
partition:
State the partition and its reason before starting ("a and b are disjoint:
parallel; c touches the same schema as a: after a lands").
A change whose add exits 4 is already claimed by another run sharing this
repo: skip it and note the skip in the partition report; never adopt its
worktree. This is what keeps two concurrent /hone:run invocations from both
building the same Plan: the worktree is a single atomic claim.
Then land them one at a time through step 6:
worktree.sh land never interleaves two merges; within this run, still drive them one at a
time so each builds on the last landed result.land exit 2) means the check missed an
overlap: fold it into one serial change and flag it for a Decision-level
look. Do not force the merge.consolidate-critic
over the combined result) to catch cross-change duplication no single worktree
could see.run proceeds without checking in. It stops only when:
On 1 or 2, leave the worktree in place as evidence and escalate with the specific blocker. Never disable, weaken, or route around a gate to proceed: an escalated stop is a correct outcome, a forced pass is not.
The land gates (on by default) add a stop that is neither a failure nor a fork:
the authority gate (exit 8) awaits your scoped grant for an irreversible change,
and the proof gate (exit 7) awaits real-environment proof the loop cannot give.
Both are stops reserved to you by design: escalate and wait; never write the
grant or the sign-off yourself. (A project can disable either with
.hone-authority-off / .hone-proof-off.)
npx claudepluginhub dominik-rehse/hone --plugin honeCreates, edits, and verifies skills using a test-driven development approach with pressure scenarios and subagents.