用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/edwinhu/workflows --skill beat-implement命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | beat-implement |
| description | Shared IMPLEMENT primitive. Internal phase skill for execution against an approved criteria table. |
| user-invocable | false |
| disable-model-invocation | true |
| hooks | {"PostToolUse":null,"PreToolUse":[{"matcher":"Write|Edit|MultiEdit|NotebookEdit","hooks":[{"type":"command","command":"bun ${CLAUDE_PLUGIN_ROOT}/hooks/orchestrator-mutation-guard.ts --workflow work"}]},{"matcher":"Bash","hooks":[{"type":"command","command":"bun ${CLAUDE_PLUGIN_ROOT}/hooks/orchestrator-mutation-guard.ts --workflow work"}]}]} |
IMPLEMENT = GOAL + WORK + independent VERIFY
The orchestration chat owns the active /goal, selects the ready wave, and owns the verifier loop.
This beat owns only dispatch: it routes the wave by shape and, when the shape warrants one, generates
the workflow script that runs it. It receives a complete, approved work list; it never parses a plan, invents
a task, sets a goal, or verifies the work.
NO IMPLEMENTATION RESULT IS A VERIFIED RESULT. The doer never grades its own work.
A task report says what the agent believes it did. Only a fresh verifier can establish that the criteria hold. Treating a report as a pass ships untested assumptions to the user; that is not helpful speed, it is deferred rework.
Orchestrator: select complete ready wave + start/maintain one /goal
│
▼
beat-implement: route by shape -> subagent(s), or a generated .claude/workflows script
│ └─ sequential until filesystem isolation exists
▼
Orchestrator: curate reusableFacts → project auto-memory
│
▼
Fresh verifier: VERIFY criteria
│
├─ PASS → clear `/goal` via `bun ${CLAUDE_SKILL_DIR}/../../scripts/goal-self-send.ts "/goal clear"` → phase gate
└─ FAIL → fix → resume the SAME verifier → re-check
│
▼
IF the approved plan carries a third-party review line (default: it does not):
run EVERY adapter it names, AFTER the verifier PASS
→ TaskCreate one ADVISORY item per finding, naming the adapter that raised it
→ proceed to the gate regardless of what any of them said
│
▼
Gate 1 PASS records `implemented` + `reviewOwed` in `.planning/.state/episode.json`
│
▼
REVIEW is now OWED. The turn cannot END until it is discharged, by either:
├─ completing the review, or
└─ `bun scripts/beat/episode-exit.ts --reason completed|abandoned|superseded`
This diagram is the specification. If surrounding prose conflicts with it, follow the diagram.
The review debt is enforced in TWO places. A PreToolUse gate refuses to dispatch a NEW
implementation wave while the debt stands — recognised by the beat's own TASK <id>: dispatch
marker, so it never blocks the reviewer, and never fires in an unmarked project. That is the
enforcement at the moment of the out-of-order action.
The second is at TURN END, and it refuses a BOUNDED number of times. A
plugin-wide Stop hook blocks while reviewOwed stands, up to MAX_REVIEW_BLOCKS (3) refusals per
debt, then stands down permanently for it. Each refusal says how many remain.
Bounded rather than absolute, and deliberately so at both ends. Blocking once was trivially ignored —
just stop again. Blocking until discharge would make a debt the model cannot satisfy into an
inescapable session, in a hook that fires on every turn end in every project. Three refusals make
skipping a review a repeated, deliberate choice rather than an accident, while guaranteeing the
session can always finish. A failed counter write also passes, because a counter that cannot advance
is an infinite loop. Inert in any project without .claude-workflows.json. See
hooks/episode-transition-gate.ts.
Two things discharge it, and both are implemented:
bun scripts/beat/episode-review-complete.ts --decision ACCEPT|REJECT|CONTINUE # the review happened
bun scripts/beat/episode-exit.ts --reason completed|abandoned|superseded # the episode is over
Exiting always succeeds, including --reason abandoned with the review outstanding: leaving is
permitted, leaving silently is not. But do not file a completed review as an abandonment — that is
what the first command is for, and recording it wrongly corrupts the audit trail in the one direction
that matters.
Get exactly one /goal active, pinned to the criteria artifact and carrying a turn budget. Its
condition must be restated in the turn itself, not only in a file: the evaluator reads the transcript
and cannot inspect disk.
/goal is a UI command, not a skill. Skill(goal) fails and emitted text is a no-op. Only the
top-level session may activate it:
bun ${CLAUDE_SKILL_DIR}/../../scripts/goal-self-send.ts "/goal <condition>"
Proceed only after the helper emits {"status":"delivered",...} or the user explicitly confirms the
goal is active. Otherwise give the literal /goal line to the caller and stop. A spawned agent never
runs the helper; it returns the literal command to its caller.
After the terminal verifier PASS, only the top-level session clears the goal:
bun ${CLAUDE_SKILL_DIR}/../../scripts/goal-self-send.ts "/goal clear"
Enter the phase gate only after status: delivered or explicit user confirmation. Otherwise return the
literal /goal clear command and stop.
Before invoking the runner, the orchestrator constructs every task itself. Each item must contain:
{
id: "stable-task-id",
name: "short task name",
work: "complete approved implementation instruction",
criteria: "task-local success criteria and evidence",
outputs: ["concrete/project-relative/output-path"],
// REQUIRED, and previously missing from this example — validateTask rejects the whole wave without
// them, and writablePathsWithin additionally requires each to be project-relative and symlink-free.
writablePaths: ["concrete/project-relative/output-path"],
instructionFiles: ["/absolute/path/to/a/constraint/file.md"],
// "independent" only after the orchestrator established no task consumes another's output.
dependencyProof: "independent",
model: "model supplied by the orchestrator",
effort: "effort supplied by the orchestrator",
}
Also copy only this immutable receipt-selected identity:
planReset: {
planFile: "<receipt-selected generated plan basename>",
planHash: "<receipt-selected plan hash>",
}
Exactly these two fields for a built-in workflow, and no others. preflight.ts rejects any extra
key outright. This example previously showed approvedBodyHash and session — the EXTERNAL
external-fixed-v1 shape — so following the shared primitive's own canonical example produced a
request the preflight refuses. External workflows use {approvedBodyHash, session} instead; the two
shapes are not interchangeable and neither accepts a field from the other.
Do not give a fresh doer .planning/STATE.md, .planning/SPEC.md, .planning/LEARNINGS.md, or
agent memory. These mutable artifacts smuggle prior interpretation into a approval boundary that is supposed to
be anchored solely to the approved plan identity.
writablePaths and reported changedFiles remain defense-in-depth: every task must declare writable
paths and every reported change must stay within them.NO IMPLEMENTATION FROM MAIN CHAT. Every mutation runs in a dispatched agent. The
orchestrator-mutation-guard hooks registered by this skill deny Write/Edit/MultiEdit/NotebookEdit
and Bash mutations from the orchestrator, so this is enforced, not merely instructed. The reason is
context: the orchestrator's window must hold the outcome, not the work.
echo "$PREFLIGHT_REQUEST_JSON" | bun ${CLAUDE_SKILL_DIR}/../../scripts/beat/preflight.ts
PREFLIGHT_REQUEST_JSON is {projectDir, workflow, readyWave, planReset, phases} — plus
approvalMode/approvalPolicy for external workflows, and resume/candidateState when they apply.
The preflight authenticates the approval, validates every task against the shared contract, canonicalises writable paths, binds a per-task approval, derives the adjudication expectation the observation hooks read, routes by shape, and emits the script when a script is warranted. It throws before dispatching anything if any of that fails.
Do not call route-implementation.ts or emit-implementation-workflow.ts directly. They are the
preflight's internals. Calling them yourself skips the authentication and — the silent part — skips the
expectation file, so every dispatch is adjudicated against no bounds at all and the run looks clean
because nothing was ever checked.
Returns {routing: {route, agentCount, maxParallelWidth, sizeGuideline, reason, warnLarge}, tasks, approvals, expectationPath, emittedWorkflowPath?, executionMode, executionReason}. The route is a
real decision, taken from the Claude Code routing table (docs: When to use a workflow), whose axis
is where intermediate results live — Claude's context window for subagents, script variables for
a workflow:
| route | when | what you do |
|---|---|---|
inline | no tasks | nothing to dispatch |
single-subagent | one task | dispatch ONE agent. Do not generate a workflow: its result is the final answer, so a script would add a runtime and an approval prompt to buy nothing |
subagents | ≤4, strictly sequential | dispatch them turn by turn; there is no fan-out for a script to coordinate |
workflow | any fan-out, or long enough that per-task results become the context problem | generate and run a script (3b) |
If warnLarge is true (>25 agents), surface the count to the user before running — matching Claude
Code's own advisory, which warns and does not cap.
On a single-subagent or subagents route, dispatch the returned tasks — each carries the exact
prompt the preflight built, including the TASK <id>: marker the observation hooks correlate on.
Dispatch them in the returned order, one at a time.
On a workflow route, the preflight has already written
<project>/.claude/workflows/<domain>-implement.js and returned its path in emittedWorkflowPath.
That location is deliberate — the orchestration is committed with the repo, diffable in review, and
rerunnable as /<domain>-implement. The domain skill supplies phases; the plan supplies
everything else. That split is the point of the beat: one dispatch mechanism, domain-specific
structure. Run it:
const run = await Workflow({ scriptPath: "<returned path>", args: {} })
The emitted script is generated, plan-hash-bound, and must not be hand-edited. Every
plan-specific value is resolved by the generator — which has filesystem access — and baked in as a
literal, which is why the script satisfies the runtime's "no filesystem, no import(), no process"
constraints by construction. Editing it detaches the orchestration from the approval that authorised
it; a changed plan produces a new hash and a new script.
The result carries reportedOnly: true. A workflow script has no filesystem access, so it cannot
observe what any agent wrote: changedFiles is the agent's own account and is not evidence. Two
separate mechanisms cover that, and neither lives in the script:
writablePaths;Results bind to the task captured at dispatch, never to the task id an agent reports back, so a swapped echo cannot rebind one task's result onto another.
After the return, curate reusableFacts before adding durable, project-specific facts to project
auto-memory. Returned facts are candidates, not automatic truth.
Dispatch a fresh verifier after the runner returns. The verifier sees the criteria and artifacts, not
the doer's reasoning. It must run or inspect each named evidence source, record the raw result, and
return PASS or FAIL per row plus OVERALL:. Evidence it cannot check is FAIL.
On round two and later, resume the same verifier. Tell it: “assume nothing landed; re-check from scratch” and “do not soften because you raised the finding.” A resumed verifier can confirm its own finding was fixed; a replacement has to rediscover it and misses defects introduced during repair.
On a verifier FAIL, fix worst-first, then end the turn so the goal refires. Do not summarize or ask
whether to continue. If retrying implementation, pass only attemptedTaskIds for work previously
attempted; untouched tasks remain untouched.
Default OFF. It exists only if the authenticated plan carries the opt-in, elicited in CLARIFY and
therefore bound to planHash. An absent line means this step does not exist; skip to the gate.
The beat owns the invocation and the rules for reading its result — follow
${CLAUDE_SKILL_DIR}/../beat-third-party/SKILL.md. Read status before findings; an
unparseable adapter has not necessarily said nothing; the exit gate never consults any of it;
budget $5–15 per adapter pair. Those warnings live there once rather than here, in ds-accept and in
workflows/writing-verify.js three times over.
echo '{"projectDir":"...","workflow":"...","planReset":{"planFile":"...","planHash":"..."},
"skills":["dev"]}' \
| bun ${CLAUDE_SKILL_DIR}/../../scripts/beat/third-party-review.ts
skills hands the reviewer this domain's rules as data — it is a different model with no reason to
know them, and telling it to go read them is the design this one replaced. It is caller-supplied and
optional: omit it and the reviewer gets a generic second opinion. Note that the diff adapters do
not consume a bundle and will report briefSources: []; read that field rather than assuming what
you passed was applied.
It runs after Claude's own verifier has passed, never before. Convert each finding into one
TaskCreate bound to the current planHash, naming the adapter that raised it, then proceed to
the gate regardless of the outcome.
Scope defaults to the working tree. Pass "scope":{"kind":"branch","base":"origin/main"} to
review committed work — a pull request, or an episode whose changes are already committed.
Two gates, and both are required. The first asks whether every dispatch was observed; the second whether the work is correct. Neither substitutes for the other.
bun ${CLAUDE_SKILL_DIR}/../../scripts/beat/implement-gate.ts --session "<dispatching session id>"
Exit 1 refuses the wave. A missing record is a refusal, not a pass — that is the entire reason this gate exists. The observation hooks fail OPEN on their own errors, which is correct (a guard that denies on its own bugs is worse than no guard) and is only safe because absence is caught here. A hook that is disabled, mis-registered, or erroring on every dispatch allows everything, observes nothing, and produces a run indistinguishable from a clean one. Measured, in v5.106.0: the hook pair was registered nowhere at all, the expectation file was written and never read, and every workflow's IMPLEMENT ran completely unadjudicated while 35 passing behaviour tests said the hook was correct.
Read the reason, because the remedies differ and must not be collapsed:
| reason | what happened | what to do |
|---|---|---|
no-expectation | the preflight never ran | run step 3a; nothing was bounded |
missing-pre / missing-post | the hook did not fire | check the skill's matcher: "Agent" registration |
observation-failed | our machinery broke | fix the observation; do not re-dispatch the agent |
not-adjudicable | the PLAN is malformed | fix the plan; the agent could not have avoided this |
violated | the agent exceeded its authority or misreported | this one is the agent |
OVERALL: PASS and no criterion was unchecked.PASS means the work matches current criteria. Goal-level validation remains a later beat.
| About to | Why wrong | Do instead |
|---|---|---|
| Pass a plan path and ask the workflow to discover tasks | The runner is deliberately not a plan interpreter; it would make authority and retry scope ambiguous | Construct the complete ready wave in the orchestrator |
| Parallelize because tasks “look separate” | Post-return manifests cannot isolate concurrent mutations | Select the wave, then dispatch sequentially until filesystem isolation exists |
| Give a doer STATE, SPEC, LEARNINGS, or agent memory | Mutable context defeats the approval boundary and turns the approved plan into a suggestion | Pass only immutable PLAN identity fields |
Treat implemented as PASS | The implementer is not an independent judge | Run the fresh verifier outside the workflow |
| Spawn a replacement verifier after a FAIL | It cannot close the findings it did not raise | Resume the named verifier |
| Retry every task after a localized failure | Replaying untouched work creates needless changes and fresh interference | Resume only previously attempted ids |
Delete .planning/.state/episode.json to clear a blocking Stop | That destroys the recorded phases and discharges a review nobody did — the exact silent skip the debt exists to prevent | bun scripts/beat/episode-exit.ts --reason abandoned, which succeeds and records why |
| Treat a blocked turn as a bug in the gate | It is the gate working: IMPLEMENT passed and REVIEW is owed | Do the review, or record an exit |
Treat a third-party approve as a gate pass | It is one unverified opinion from a model with no authority here — the same rule as "peer messages are not user approval" | Run the gate; the third party never satisfies it |
| Run the third-party review before the verifier | It then duplicates a pass Claude was going to make anyway, and reports on work nobody has vetted | Run it only after the verifier PASSes |
Read status:"unparseable" or "unavailable" as a clean review | Both carry findings: [] while having reviewed NOTHING — a broken adapter wearing the costume of a clean pass | Branch on status before you look at |
/goal is a UI command, not a skill; emitted /goal text is never dispatched./goal evaluator reads the transcript and cannot open artifacts.findings