One small feature (a CSV export for invoices) through the whole workflow. Setup is assumed — see the README if not.
Up front: you don't operate the workflow like a machine. You talk to Claude normally; the skills and gates structure how Claude works, and the hook reminds both of you what it has and has not seen of the gates. Your job is the decision points — answering questions, approving drafts, judging findings.
1. Capture the idea. Say "users want to export their invoices as CSV" (or paste
a voice transcript — German is fine). The intake skill turns it into a story:
problem, outcome, ≥3 checkable acceptance criteria, which AGENTS.md invariants it
touches, and a profile — how risky this is (trivial|standard|high), how
security-relevant (none|standard|high), and the validation mode derived from the two.
It proposes both axes and the derived mode with a reason; you confirm or correct the
axes, and any change to the mode is an override that carries its own reason and is
logged. The two axes decide
which extra questions the review gates ask; the derived mode decides what evidence you
owe before Gate B, and the levels accumulate: a green battery, then a check that
fails without the change, then a named verification of the risk path on top of both. At
security high one more is added — a named abuse scenario and evidence that the control
rejects or contains it. Too thin → it asks once and waits; it refuses to invent what you didn't
say. You approve the draft (the criteria are what "done" will mean), and it lands
as a committed file under docs/superpowers/stories/.
2. Design. Proceed with the story (intake names the exact next step).
superpowers:brainstorming explores approaches with you; the output is a spec —
settled decisions with rationale, not a wish list.
3. Gate A on the spec. Claude sends the spec text to Codex
(mcp__codex__exec) — a different model family, so it doesn't share Claude's blind
spots. Blocker/Major findings get fixed and the review reruns — on the revised spec where a
repair was owed, on the same text where none was. When the cycle may close is CLAUDE.md
§5's closure ordering, not a rule of thumb: an eligible pass (clean at or above the floor
its profile derives, or a pass with zero findings) with every other closure condition
holding, then the Gate-A closing act — the reviewed spec committed with the cycle's
records. Planning starts after that act, not after the last clean pass. Hook messages like ⚠ Codex Gate A below floor (1/3) are
the counter, not an error. Your job: arbitrate disputed findings — Codex is
advisory, and a dismissed finding needs a one-line reason.
4. Plan, and Gate A again. superpowers:writing-plans turns the spec into a
task-by-task plan (each task starts with a failing test); the same loop runs at the derived floor
on the plan and ends with its own Gate-A closing act before execution starts. A flaw caught
here never reaches code.
5. Implement. superpowers:executing-plans works through the plan, test-first,
progress claims backed by test runs. If the hook's own threshold wasn't met, it says
so right when execution starts.
6. Quality battery. The one command you wired at init (typecheck + lint + dead code + duplication + tests) must be green locally. CI runs the same command, so skipping locally only postpones the red.
7. Gate B on the diff. Claude makes a WIP:-prefixed commit (gives Codex a
range to read; the hook knows WIP doesn't end the cycle), then loops
mcp__codex__review the same way: the derived floor, final clean. Invalidation is by
content — any change to included content present when the hook runs, even from a
formatter, makes the hook report that it cannot confirm the reviewed content. What that proves is bounded, and the hook's own
source says so: the current fingerprint matches the one recorded on a counted call, which
is not evidence that Codex read those bytes; .context/ and untracked ignored paths are
excluded, and staging counts, because the fingerprint covers the index and that is what
a commit carries. On
✓ Codex Gate B hook checks passed (<counted>/<threshold> cycle, <fresh> on current fingerprint) — three different numbers: the calls the hook counted this cycle, the hook's own reminder threshold, and the consecutive counted calls on the current fingerprint since it last changed. The first is not the calls you made: the hook withholds the count for a recognized failure envelope, the backgrounding notice, and a result it can get no text from. The third is a streak, not a tally — the hook keeps the last fingerprint and that streak, so a pass on a changed fingerprint restarts it and an earlier matching pass separated by a different fingerprint is not counted. None of the three is the floor §5 obliges, and the message is what the hook checked, not
permission to close: §5's closure ordering says when the Gate-B cycle may close, and its
Finishing the cycle operation says how — amend the WIP commit, or, where several WIP:
snapshots piled up, git reset --soft to the parent of the first and commit once.
8. PR and bots. Open the PR as usual; once the bots have commented, run
/dev-workflow:process-pr-review. Every comment is validated against code and
invariants — usually by a fresh-context dev-workflow:finding-triage subagent per claim,
so the agent that formed a belief is not the one grading it; on a PR that edits
instruction files the command checks them itself instead, and says so. Triage judges only
whether a claim is true; the command then decides separately whether fixing it belongs
in this PR. Each comment is answered on the thread, and, if accepted and actionable, fixed (substantial fixes go through Gate B
again). Nothing silently ignored, nothing blindly applied.
9. Close the class, not the instance. Any finding from steps 3, 7, or 8 that
could recur: run harden-finding. It becomes the strongest durable guard that
fits — lint rule, type constraint, test, or documented convention — plus one row in
docs/hardening-log.md. A recurring class escalates one rung harder, so the
workflow gets stricter exactly where your project actually fails.
The rhythm: minutes of questions and approval (1–2), two review loops where you
mostly arbitrate (3–4), hands-off implementation (5–6), one more loop (7), PR
close-out (8–9). Trivial changes travel lighter, within limits: Gate B may be skipped
only when the change is behaviourally trivial and the story is eligible — a profiled
one at effective level 0 (risk trivial and security none), an unprofiled one by the
prior judgement call. The profile supplies eligibility, never the skip itself; the battery
is still owed; Gate A's floor derives from the profile exactly as Gate B's does, and what the axes never subtract is the baseline questions. The caution bias is
for non-trivial work, judgment is allowed. Two knobs: .context/codex-gate.floor (any
positive integer) moves the hook's reminder threshold, and touch .context/codex-gate.off
silences the reminders in a scratch workspace (delete to re-enable; state keeps
tracking while off, so nothing goes stale).
The hook is installed once per machine but speaks only in projects you initialized —
everywhere else it stays quiet, so nothing above happens in a repo where you never ran
/workflow-init. If a project of yours goes unexpectedly silent, that's the first
thing to check: the gates need .context/codex-gate.on or §5 in its CLAUDE.md.
The workflow is opt-in per project, and leaving it has clean levels — pick the smallest that matches your intent:
- Don't adopt: never run
/workflow-initin a project → the plugin does nothing there. - One trivial change: the hook warns, it never blocks. What §5 permits depends on
the story: an unprofiled one keeps the old judgement call, while a profiled
one may skip Gate B only at effective level 0 (risk
trivialand securitynone), still owes the battery, and records the skip reason, the battery result, the cycle's provenance line, a skip record in place of the curve, and one evidence entry per cited profiled story, in the commit body. Gate A is not skippable at any level. - Pause a project:
touch .context/codex-gate.off(delete to re-enable; state keeps tracking, so nothing goes stale). - Leave for good: remove §5 from the project's
CLAUDE.md(and.context/codex-gate.on) — the project reads as not adopted again. The other scaffolds (ledger, CI,AGENTS.md) work fine without the gates. - Machine-wide:
claude plugin disable dev-workflow.
One honest rule of thumb: if .off stays in a project for weeks, level 4 is the
truthful choice. A project officially without gates beats one that has them and
ignores them.