Crank
Crank executes exactly one wave. The caller selects the wave and the repair
bound; crank runs that wave and returns what happened.
caller's wave + repair_rounds -> RPI per lane -> wave acceptance once -> evidence -> stop
Input
The caller supplies all three:
- The wave — a list of lanes, each with a write
scope, a brief, and its
own executable acceptance.
repair_rounds — the caller's repair bound, forwarded unchanged to every
lane. Crank neither chooses it nor spends it.
- The wave acceptance — the one command set that judges the wave as a whole.
If a lane arrives without a scope, a brief, or an executable acceptance, report
the wave as unrunnable and stop. Crank does not shape the missing part itself.
Contract
- Read the caller's wave as given. Do not select, extend, drop, or re-rank
lanes; the wave arrives already decided.
- Partition the lanes. Two lanes may run in parallel only when their write
scopes are disjoint and their regen surfaces (generated outputs,
mirrors, manifests) are disjoint. Any shared surface serializes them;
unknown overlap counts as overlap.
- Invoke
rpi once per lane with that lane's intent,
scope, acceptance, and the caller's repair_rounds. Each lane's traversal
owns its own repair loop. Crank never repairs a lane itself, never
re-invokes a returned lane, and never re-plans one.
- Run the wave acceptance once, after every lane has returned. A lane that
returned
FAIL or NOT_PROVEN does not suppress it; both results are
reported side by side.
- Return the wave evidence and stop — per-lane status
(
PASS | FAIL | NOT_PROVEN | NOT_PLANNED | NOT_BUILT), the open findings
each lane's validator left keyed by their findings[].id, each lane's
subject manifest digest, and the wave acceptance result.
Append no next action. The caller reads the evidence and decides whether there
is another wave.
Boundary
Crank owns no wave selection, retry, budget, queue, claim, lease, Git, closure,
delivery, or next work, and it mints no verdict of its own. Every semantic
result in the wave evidence is the one that lane's fresh validator returned,
cited unchanged; a green wave acceptance is a fact, not a PASS.
Conveyor
In Claude, workflows/implement-wave.js
is one conveyor for step 3's parallel leg: it runs disjoint-ownership
implementers over the lanes the caller supplied. It is transport, never a
substitute for a lane's own fresh validation, and crank runs without it.
Prompt
Crank this wave, repair_rounds=2.
Lane A - scope cli/internal/gates/**, brief "add the probe-coverage gate row",
acceptance: cd cli && go test ./internal/gates/...
Lane B - scope docs/CI-CD.md, brief "document that gate row",
acceptance: bash scripts/docs-build.sh --check
Wave acceptance: bash tests/run-all.sh. Report per-lane evidence and stop.
It's working if
Observable in the trace, without reading the prose — and the rubric a fresh
independent judge scores this skill against:
- The transcript shows exactly one
rpi invocation per lane in the caller's
wave, and no lane appears twice.
- Two lanes that share a regen surface (both reaching
skills-codex/, say) run
one after the other, never concurrently.
- The wave acceptance command runs exactly once, after the last lane returns.
- The returned evidence carries a status and a subject manifest digest for
every caller-supplied lane, and for no lane crank invented.
- The response ends with the evidence: no next wave, no
git action, and no
proposed follow-up work.
1---
2name: crank
3description: 'Execute one caller-selected wave by invoking RPI once per lane and return the wave evidence, then stop. Triggers: "crank", "execute the next wave", "run this wave".'
4practices:
5- small-batch-flow
6- design-by-contract
7- team-topologies
8hexagonal_role: domain
9consumes:
10- rpi
11- caller-selected-wave
12produces:
13- wave-evidence
14context_rel:
15- kind: customer-of
16 with: rpi
17skill_api_version: 1
18user-invocable: true
19metadata:
20 graph_root: true
21 tier: meta
22 dependencies: [rpi]
23 capabilities: [execute_wave]
24 effects: [dispatch_rpi_per_lane]
25 canonical_status: canonical
26 disposition: keep
27output_contract: 'wave evidence: per-lane status, the open findings each lane''s validator left, each lane''s subject manifest digest, and the wave acceptance result'
28---
29
30# Crank
31
32Crank executes exactly one wave. The caller selects the wave and the repair
33bound; crank runs that wave and returns what happened.
34
35```text
36caller's wave + repair_rounds -> RPI per lane -> wave acceptance once -> evidence -> stop
37```
38
39## Input
40
41The caller supplies all three:
42
43- **The wave** — a list of lanes, each with a write `scope`, a `brief`, and its
44 own executable `acceptance`.
45- **`repair_rounds`** — the caller's repair bound, forwarded unchanged to every
46 lane. Crank neither chooses it nor spends it.
47- **The wave acceptance** — the one command set that judges the wave as a whole.
48
49If a lane arrives without a scope, a brief, or an executable acceptance, report
50the wave as unrunnable and stop. Crank does not shape the missing part itself.
51
52## Contract
53
541. Read the caller's wave as given. Do not select, extend, drop, or re-rank
55 lanes; the wave arrives already decided.
562. Partition the lanes. Two lanes may run in parallel only when their write
57 scopes are disjoint **and** their regen surfaces (generated outputs,
58 mirrors, manifests) are disjoint. Any shared surface serializes them;
59 unknown overlap counts as overlap.
603. Invoke [`rpi`](../rpi/SKILL.md) once per lane with that lane's intent,
61 scope, acceptance, and the caller's `repair_rounds`. Each lane's traversal
62 owns its own repair loop. Crank never repairs a lane itself, never
63 re-invokes a returned lane, and never re-plans one.
644. Run the wave acceptance once, after every lane has returned. A lane that
65 returned `FAIL` or `NOT_PROVEN` does not suppress it; both results are
66 reported side by side.
675. Return the wave evidence and stop — per-lane status
68 (`PASS | FAIL | NOT_PROVEN | NOT_PLANNED | NOT_BUILT`), the open findings
69 each lane's validator left keyed by their `findings[].id`, each lane's
70 subject manifest digest, and the wave acceptance result.
71
72Append no next action. The caller reads the evidence and decides whether there
73is another wave.
74
75## Boundary
76
77Crank owns no wave selection, retry, budget, queue, claim, lease, Git, closure,
78delivery, or next work, and it mints no verdict of its own. Every semantic
79result in the wave evidence is the one that lane's fresh validator returned,
80cited unchanged; a green wave acceptance is a fact, not a `PASS`.
81
82## Conveyor
83
84In Claude, [`workflows/implement-wave.js`](../../workflows/implement-wave.js)
85is one conveyor for step 3's parallel leg: it runs disjoint-ownership
86implementers over the lanes the caller supplied. It is transport, never a
87substitute for a lane's own fresh validation, and crank runs without it.
88
89## Prompt
90
91```text
92Crank this wave, repair_rounds=2.
93Lane A - scope cli/internal/gates/**, brief "add the probe-coverage gate row",
94acceptance: cd cli && go test ./internal/gates/...
95Lane B - scope docs/CI-CD.md, brief "document that gate row",
96acceptance: bash scripts/docs-build.sh --check
97Wave acceptance: bash tests/run-all.sh. Report per-lane evidence and stop.
98```
99
100## It's working if
101
102Observable in the trace, without reading the prose — and the rubric a fresh
103independent judge scores this skill against:
104
105- The transcript shows exactly one `rpi` invocation per lane in the caller's
106 wave, and no lane appears twice.
107- Two lanes that share a regen surface (both reaching `skills-codex/`, say) run
108 one after the other, never concurrently.
109- The wave acceptance command runs exactly once, after the last lane returns.
110- The returned evidence carries a status and a subject manifest digest for
111 every caller-supplied lane, and for no lane crank invented.
112- The response ends with the evidence: no next wave, no `git` action, and no
113 proposed follow-up work.