Das Problem & die IdeeThe problem & the idea
Unstrukturiertes Agent-Coding scheitert auf zwei bekannte Arten: Der frei laufende Agent verliert nach wenigen Iterationen die Richtung — er refactort funktionierenden Code, das Kontextfenster gerät in die „Dumb Zone", und die Entscheidungen von gestern sind weg. Das Wasserfall-Gegenteil überplant ein Feature, das noch niemand verstanden hat. CRAFT setzt dazwischen an: gleicher Workflow, gleiche Kontrolloberfläche — egal welcher Stack.
Das Kernprinzip: menschliche Kontrolle konzentriert an den harten Phasen (Planung, Recap, Review, eskalierte Bugs) — die Ausführung wird an sichere, parallele Agent-Arbeit delegiert, oder sie wird im optionalen Autopilot-Modus auf ein Plan-Gate und eine Freigabe am Ende des Epics verengt.
Neu in CRAFT 2.0: Die Zwischenreleases 1.6–1.8 haben Autopilot und Epic-Close Stück für Stück geliefert; 2.0 schließt sie ab und bringt den Rest.
- Der Autopilot ist vollständig —
/craft:execute <epic> --autopilotplant die offenen Einträge eines Epics, fragt dich einmal am Plan-Gate und baut, verifiziert per Befehl, reviewt und committet dann Slice für Slice auf einem Epic-Branch; er hält nur, wo ein Mensch gebraucht wird. Ohne--autopilotändert sich nichts (Ausführung). - Interaktive Slices laufen von selbst — mit
## Slice Flow→Mode: auto(dem Standard) startet jeder Phasen-Command den nächsten, bis einschließlich/craft:commit(Autonomie). - Jede Wahl ist ein Klick — Buchstaben-Menüs und Ja/Nein-Fragen kommen in einer interaktiven Session
als
AskUserQuestion. - Ein Pause-Wort — eine Nachricht, die nur
pause,pausierenoder/craft:pauselautet, pausiert den Slice am nächsten sicheren Punkt. - Fertige Epics schließen sich selbst —
/craft:commitschließt ein Epic nach dem Merge eines Autopilot-Laufs, nach einem sequenziellen Lauf oder nach Slice-für-Slice-Arbeit, auch über einen PR unter geschütztemmain(Abzweigungen). - Worktrees zählen nach ihrer Art — ein Worktree ohne
slice-<NNN>- /epic-<NNN>-Branch ändert nicht mehr, was/craft:committut, und ein In-place-Slice landet immer auf dem Trunk.
Unstructured agent coding fails in two familiar ways: the free-running agent loses direction after a few iterations — it refactors working code, the context window enters its "dumb zone", and yesterday's decisions are gone. The waterfall opposite over-plans a feature nobody understands yet. CRAFT sits in between: same workflow, same control surface — regardless of stack.
The core principle: human control concentrated at the hard phases (planning, recap, review, escalated bugs) — execution is delegated to safe, parallel agent work, or, in the opt-in autopilot mode, narrowed to one plan gate and an epic-end sign-off.
New in CRAFT 2.0: the interim releases 1.6–1.8 shipped the autopilot and the epic close piece by piece; 2.0 completes them and adds the rest.
- Autopilot mode is complete —
/craft:execute <epic> --autopilotplans an epic's open entries, asks you once at the plan gate, then builds, verifies by command, reviews and commits slice after slice on an epic branch, stopping only where a human is needed. Without--autopilot, nothing changes (execution). - Interactive slices flow by themselves — with
## Slice Flow→Mode: auto(the default), each phase command starts the next, up to and including/craft:commit(autonomy). - Every choice is a click — lettered menus and yes/no confirmations come as
AskUserQuestionclicks in an interactive session. - A pause word — a message that is only
pause,pausierenor/craft:pausepauses the slice at the next safe point. - Finished epics close themselves —
/craft:commitcloses an epic after an autopilot merge, a sequential run or slice-by-slice work, also through a PR under protectedmain(branch-offs). - Worktrees are judged by kind — a worktree on no
slice-<NNN>/epic-<NNN>branch no longer changes what/craft:commitdoes, and an in-place slice always lands on the trunk.
Vier DisziplinenFour disciplines
Kontext-ResetsContext resets
Jede Phase endet mit einem Markdown-Checkpoint. Chat ist kein Speicher — was zählt, wird noch im selben Zug in eine dauerhafte Datei geschrieben („Durable Capture"). Every phase ends with a Markdown checkpoint. Chat is not storage — anything that matters is written to a durable file in the same turn ("Durable Capture").
Vertical Slicing
Jeder Slice ist Ende-zu-Ende testbar und eigenständig erlebbar — kein „Frontend jetzt, Backend später". Slices sind feature-förmig, nicht komponenten-förmig. Every slice is end-to-end testable and standalone-experienceable — no "frontend now, backend later". Slices are feature-shaped, not component-shaped.
Wissens-SchichtenKnowledge layering
State (Code) ist abgeleitet; Intent (Warum) und Rules (Wie) sind explizit. Der Agent schlägt Änderungen an dauerhaftem Wissen vor — der Mensch bestätigt. State (code) is derived; Intent (why) and Rules (how) are explicit. The agent proposes changes to durable knowledge — the human confirms.
Explizite Autonomie-StufenExplicit autonomy levels
Lesen ist still, Edits im Plan-Scope laufen automatisch weiter, Regel-Änderungen brauchen Bestätigung, Push/Deploy fragt immer. Reads are silent, in-scope edits auto-continue, rule mutations need confirmation, pushes and deploys always ask.
Zwei-Ebenen-Architektur: Das Plugin liefert die universelle Hülle (Workflow +
Senior-Developer-Baseline, in jeder Session aktiv). Das Projekt behält seine Sprach-/Framework-Spezialisten
lokal (.claude/skills/ und .claude/agents/), lazy geladen — plus optionale Stack-Packs
(z. B. stack-php, stack-php-symfony, stack-php-api-platform, stack-php-shopware6, stack-php-shopware5, stack-php-laravel, stack-python, stack-ts, stack-bash), die in den code-nahen Phasen automatisch dazugeladen werden.
Two-tier architecture: the plugin ships the universal shell (workflow +
Senior-Developer baseline, active in every session). The project keeps its language/framework specialists
locally (.claude/skills/ and .claude/agents/), lazy-loaded — plus optional stack-packs
(e.g. stack-php, stack-php-symfony, stack-php-api-platform, stack-php-shopware6, stack-php-shopware5, stack-php-laravel, stack-python, stack-ts, stack-bash) autoloaded during the code-near phases.
Der 9-Phasen-LoopThe 9-phase loop
Das methodische Rückgrat. Phase 1–2 laufen nur beim Projektstart oder Betreten einer neuen Domäne; Routine-Slices starten in Phase 3. Nach Phase 9 kehrt der Loop zu Phase 3 zurück — der nächste Slice.
The methodological backbone. Phases 1–2 run only at project start or when entering a new domain; routine slices start at Phase 3. After Phase 9 the loop returns to Phase 3 — the next slice.
Die Phasen im DetailThe phases in detail
| # | Phase | Command | KontrolleControl | Was passiertWhat happens |
|---|---|---|---|---|
| 1 | Brainstorm | /craft:brainstorm | L0 | Problemraum erkunden, bevor Code existiert — divergente Ideation (Question Storming, SCAMPER, First Principles). Endet mit Markdown-Checkpoint + Kontext-Reset. Explore the problem space before code exists — divergent ideation (question storming, SCAMPER, first principles). Ends with a Markdown checkpoint + context reset. |
| 2 | Alignment | /craft:grill-me | L0 | Der Agent interviewt den Menschen und schließt die Lücke „alles Ungesagte wird erfunden". Richtung, Constraints, Akzeptanzkriterien als Checkpoint. The agent interviews the human, closing the "anything not said gets invented" gap. Direction, constraints, acceptance criteria as a checkpoint. |
| 3 | Planning | /craft:plan / /craft:epic | L1 | Kleinsten Ende-zu-Ende-Slice schneiden. Drei nicht überspringbare Fragen: Was ist der Trigger? Was ist der beobachtbare Effekt? Wie testen wir Ende-zu-Ende? Ohne Test-Strategie kein Plan. Cut the smallest end-to-end slice. Three non-skippable questions: what is the trigger? What is the observable effect? How do we test end-to-end? No plan without a test strategy. |
| 4 | Implementation | /craft:build | L2 | Plan in Code umsetzen, Sub-Tasks der Reihe nach, Tests laufen still (nur Rot wird gemeldet). Bündel-Meldung an jeder Sub-Task-Grenze; 30k-Token-Bremse gegen die „Dumb Zone". Edits außerhalb des Scopes fallen auf L1 zurück. Turn the plan into code, sub-tasks in order, tests run silently (only red surfaces). Bundle report at each sub-task boundary; 30k-token brake against the "dumb zone". Out-of-scope edits drop to L1. |
| 5 | Testing & UX | /craft:test | Human | Die einzige Phase, in der der Mensch das Artefakt selbst ausprobiert — konstitutiv, nie überspringbar, auch bei grünen Tests. 5a Demo-Setup → 5b Nutzer probiert → 5c Feedback: [W]orks / [B]ug / [U]X issue. Die eine, bewusst gewählte Ausnahme ist ein Autopilot-Lauf: Dort ersetzt ein Bestehen der committeten Checks des Slice (geprüft von scripts/verify-run.sh) den Halt, und die Prüfung des Produktgefühls wandert ans Epic-Ende (## UX Demo Script).
The only phase where the human exercises the artifact — constitutive, never skippable, even with green tests. 5a demo setup → 5b user exercises → 5c feedback: [W]orks / [B]ug / [U]X issue. The one opt-in exception is an autopilot run: there a pass of the slice's committed checks (judged by scripts/verify-run.sh) replaces the stop, and the product-feel check moves to the epic end (## UX Demo Script). |
| 6 | Recap | /craft:recap | L1 | Erzwingt mentale Ownership: „Wie funktioniert es? Führe mich von Trigger zu Effekt." Bei komplexen Slices wird ein Mermaid-Diagramm angeboten. Der Entwurf wird in Phase 9 zum Slice-Archiv. Forces mental ownership: "How does it work? Walk me trigger→effect." A Mermaid diagram is offered for complex slices. The draft becomes the slice archive in Phase 9. |
| 7 | Refactoring | /craft:refactor | L1 | Kleine strukturelle Verbesserungen, max. 2–3 Punkte pro Slice (mehr = eigener Slice). Drei dialogische Prompts. Pro Projekt abschaltbar — dann geht es von Phase 6 direkt zu Phase 8. Small structural improvements, max 2–3 items per slice (more = its own slice). Three dialogic prompts. Droppable per project — Phase 6 then hands straight to Phase 8. |
| 8 | Review | /craft:review | L2+L1 | Ein code-reviewer-Subagent mit frischem Kontextfenster klassifiziert Findings auf zwei Achsen: Schwere {Heavy, Light} × Fix-Natur {Local edit, Needs rethinking}. Lokale Edits werden in der Phase gefixt (Richtwert standardmäßig 5, kleine Fixes bis zum Doppelten; einstellbar über Review in-phase fix cap in rules.md → ## Self-Verification Settings); Heavy+Rethinking blockiert den Commit — bis der Mensch es routet: in einen neuen Slice (sobald er existiert) oder zurück in Phase 4. Findings werden pro Runde festgehalten; ein Re-Review prüft zuerst die früheren. Heavy nur mit realistischem Fehler (reproduziert oder im normalen Gebrauch erreichbar); höchstens 3 Runden — danach werden offene Light-Findings Follow-ups, ein offenes Heavy entscheidest du: accepted → known limit, eine gewährte Zusatzrunde oder ein neuer Slice.
Vor Phase 8 (Status planning, implementing, testing, review) ist /craft:review nur beratend: Findings, keine Fixes, keine Status-Änderung, nie ein Commit-Gate — und im Auto-Flow kettet es nichts an. Der volle Phase-8-Modus gilt ab refactoring, reviewing oder committing.
A code-reviewer subagent with a clean context window classifies findings on two axes: severity {Heavy, Light} × fix-nature {local edit, needs rethinking}. Local edits are fixed in-phase (guide value 5 by default, small fixes up to twice that; set by Review in-phase fix cap in rules.md → ## Self-Verification Settings); Heavy+rethinking blocks Commit — until the human routes it: to a new slice (once that slice exists) or back to Phase 4. Findings are recorded per round; a re-review verifies the earlier ones first. Heavy only with a realistic failure (reproduced, or reachable through normal use); at most 3 rounds — then open Light findings become follow-ups and you decide an open Heavy: accepted → known limit, a granted extra round, or a new slice.
Before Phase 8 (status planning, implementing, testing, review) /craft:review is only advisory: findings, no fixes, no status change, never a commit gate — and it never chains in auto flow. Full Phase-8 mode applies at refactoring, reviewing or committing. |
| 9 | Commit & Cleanup | /craft:commit | L1 | Atomare Commits (Conventional Commits + Slice:-Footer), Entscheidungs-Promotion ([K]eep/[I]ntent/[R]ules/[D]iscard), Slice-Archiv schreiben, Plan-Datei schließen (gelöscht oder nach .claude/plans/.closed/ verschoben). Der Slice schließt hier — und ebenso ein fertiges Epic (Epic-close: nach dem Merge oder PR aus a5 eines Autopilot-Laufs, nach einem sequenziellen Lauf oder nach Slice-für-Slice-Arbeit von Hand). Vier Modi: Standard, Slice-finalize, Epic-finalize, Epic-close. Im Autopilot-Lauf wird jede Entscheidung ohne Dialog als [K] festgehalten — eine Promotion in intent.md / rules.md bleibt Sache des Menschen.
Atomic commits (Conventional Commits + Slice: footer), decision promotion ([K]eep/[I]ntent/[R]ules/[D]iscard), slice archive written, plan file closed (deleted, or moved into .claude/plans/.closed/). The slice closes here — and so does a finished epic (Epic-close: after an autopilot run's a5 merge or PR, a sequential run, or slice-by-slice work by hand). Four modes: Standard, Slice-finalize, Epic-finalize, Epic-close. In an autopilot run every decision is recorded [K] without the dialog — a promotion into intent.md / rules.md stays a human's act. |
Quickstart
So fühlt sich ein Arbeitstag mit CRAFT an — vom Onboarding bis zum geschlossenen Slice:
What a working day with CRAFT feels like — from onboarding to a closed slice:
# einmalig pro Projekt: Projektwissen aufbauen (oder bestehendes .claude/ migrieren)once per project: bootstrap project knowledge (or migrate an existing .claude/)
❯ /craft:onboard
# jede Session: Kontext laden — läuft automatisch beim Session-Startevery session: load context — auto-runs at session start
❯ /craft:prime
✓ Project · ✓ CRAFT plugin v… · ✓ Rules↔State drift check · ✓ Tools (… bash, python3) · ✓ Senior-Developer baseline
✓ Agent models · ✓ Language · ✓ CRAFT profile · ✓ Autopilot budget · ✓ Local state gitignored · ✓ Statusline tap
Active slices · Recommended next
# neuer Slice: die drei Fragen (Trigger? Effekt? Test?) → Plan-Datei — mit Mode: auto endet er mit einem Klicknew slice: the three questions (trigger? effect? test?) → plan file — with Mode: auto it ends with one click
❯ /craft:plan user-login
→ .claude/plans/slice-001-user-login.md Status: planning
◆ Build now · Later # Build now — ab hier startet jede Phase die nächste selbstBuild now — from here each phase starts the next itself
Auto flow → /craft:build # Phase 4 — implementiert Sub-Tasks, Tests still im Hintergrundworks sub-tasks, tests silent
Auto flow → /craft:test # Phase 5 — DU probierst es aus, dein Klick:YOU exercise it, your click: [W]orks / [B]ug / [U]X
Auto flow → /craft:recap # Phase 6 — was & warum, du bestätigst jeden Absatzwhat & why, you confirm each paragraph
Auto flow → /craft:refactor # Phase 7 — optional, pro Projekt abschaltbaroptional, droppable per project
Auto flow → /craft:review # Phase 8 — Fresh-Context-Review; eine Eskalation routest du per Klickfresh-context review; you route an escalation by click
Auto flow → /craft:commit # Phase 9 — du bestätigst Split, Messages, Entscheidungen — Slice zu, der Flow endetyou confirm split, messages, decisions — slice closed, the flow ends
# anhalten: eine Nachricht, die nur aus pause, pausieren oder /craft:pause bestehtstop the flow: a message that is only pause, pausieren or /craft:pause
# Mode: manual (Preset careful): du tippst jedes Phasen-Kommando selbst, /craft:build … /craft:commitMode: manual (careful preset): you type each phase command yourself, /craft:build … /craft:commit
# wieder einsteigen, egal wo man stand:resume from wherever you left off:
❯ /craft:continue # liest den Status und empfiehlt das richtige Kommandoreads Status, recommends the right command
# groß denken: Epic planen und ohne Halt zwischen den Slices bauen lassen (CRAFT 2.0)think big: plan an epic and let it build with no halt between slices (CRAFT 2.0)
# Voraussetzung: eine Session, gestartet mitneeds a session started with CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 claude
❯ /craft:epic checkout-flow
❯ /craft:execute epic-001 --autopilot # plant ungeplante Einträge, ein Plan-Gate, dann jeder Slice ohne Halt auf dem Epic-Branchplans unplanned entries, one plan gate, then every slice with no halt, on the epic branch
❯ /craft:execute epic-001 # ohne --autopilot: parallele Worktrees — nicht freihändig, jeder Slice hält für dich an Phase 5 und 7without --autopilot: parallel worktrees — not hands-off, each slice halts for you at Phase 5 and 7
Kontext-Hygiene — der unterschätzte Effizienz-HebelContext hygiene — the underrated efficiency lever
Die Implementierungs-Session eines Slice sollte unter grob 150.000 Tokens bleiben (die
Leitlinie für Phase 4). Passt ein Slice nicht in eine Session, war er schon in Phase 3 zu groß — beim nächsten Mal
kleiner schneiden. Ist die Grenze erreicht, lohnt ein beherzter Schnitt:
/clear — und der SessionStart-Hook stößt /craft:prime automatisch wieder an.
Weil aller relevanter Zustand in Dateien lebt (Slice-Plan mit Status-Token, Intent, Rules, Profil), landet
die frische Session ohne Verlust exakt an der richtigen Stelle — genau dafür ist das Status-Token-Design
gebaut. Regelmäßiges Leeren statt endlosem Weiterschleppen hält das Modell aus seiner „Dumb Zone" und
bringt spürbar Effizienz.
Keep a slice's implementation session under roughly 150,000 tokens (the Phase 4
guideline). A slice that does not fit in one session was already too big in Phase 3 — slice smaller next time. Once
you reach that mark, a clean cut pays off:
/clear — and the SessionStart hook automatically re-triggers /craft:prime.
Because all relevant state lives in files (the slice plan with its status token, intent, rules, profile),
the fresh session lands exactly where you left off, losing nothing — that is precisely what the status-token
design is built for. Clearing regularly instead of dragging context along keeps the model out of its
"dumb zone" and is a real efficiency win.
❯ /clear # bei ~150k verbrauchten Tokens: Kontext leerenat ~150k tokens consumed: clear the context
❯ /craft:prime # läuft automatisch wieder an — lädt Status, empfiehlt den Wiedereinstiegauto-runs again — loads state, recommends where to resume
Der zweite Hebel ist die harte Abhängigkeit von context-mode — sie ist kein Zufall: context-mode führt große Ausgaben (Logs, Diffs, Suchläufe, Doku) in einer Sandbox aus und lässt nur die destillierte Antwort ins Kontextfenster. Das spart aktiv enorme Token-Mengen und erlaubt deutlich größere Sessions — erst dadurch läuft der 9-Phasen-Loop eines Slices in einem Rutsch.
The second lever is the hard dependency on context-mode — and it is no accident: context-mode runs large outputs (logs, diffs, searches, docs) in a sandbox and lets only the distilled answer into the context window. That actively saves enormous amounts of tokens and allows much larger sessions — it is what lets a slice's 9-phase loop run in one go.
Voraussetzungen (von /craft:prime hart geprüft): context-mode,
agent-browser, git, gh, bash ≥ 5.0 und python3
(für die Hilfsskripte). Prime sammelt alle fehlenden Werkzeuge und bricht dann einmal ab — mit dem
Installationsbefehl für das eigene Betriebssystem (brew, apt, dnf, …;
Windows über WSL 2). Ein unverändertes macOS bringt nur bash 3.2 mit: vorher brew install bash. Wird
Claude Code aus dem Dock oder einer IDE gestartet und sieht die neue bash nicht im PATH, nennt
Prime statt eines Installationsbefehls die PATH-Korrektur (aus dem Terminal starten oder
env.PATH in ~/.claude/settings.json setzen).
Prerequisites (strictly verified by /craft:prime): context-mode,
agent-browser, git, gh, bash ≥ 5.0 and python3
(for the helper scripts). Prime collects every missing tool, then aborts once — with the install command for
your OS (brew, apt, dnf, …; Windows via WSL 2). A stock macOS ships
bash 3.2: run brew install bash first. If Claude Code is launched from the Dock or an IDE and does
not see that bash on its PATH, prime names the PATH fix instead of an install command
(start from a terminal, or set env.PATH in ~/.claude/settings.json).
CRAFTs lokaler Zustand (.primed, .hook-env,
.execute.lock, .cache-guard, .pause-request, .closed/, settings.local.json, .craft/) gehört nicht ins Repo:
/craft:onboard trägt die nicht abgedeckten Pfade als # CRAFT local state-Block in die
.gitignore ein; in früher onboardeten Projekten bietet /craft:prime (Schritt 4f) das
an und schreibt erst nach deinem Ja (siehe Wissensmodell).
CRAFT's local state (.primed, .hook-env,
.execute.lock, .cache-guard, .pause-request, .closed/, settings.local.json, .craft/) does not belong in the repo:
/craft:onboard adds the uncovered paths to .gitignore as a
# CRAFT local state block; in projects onboarded earlier /craft:prime (step 4f) offers
it and writes only on your yes (see knowledge model).
Für Autopilot-Läufe liest CRAFT die Nutzungsfenster deines Plans aus der Statusline. Ein Plugin
kann den Tap dafür nicht selbst eintragen, deshalb bieten /craft:prime (Schritt 4h) und
/craft:onboard es an: Sie zeigen die Änderung an statusLine in deinen User-Settings, legen ein
Backup an und schreiben erst nach deinem Ja — dein eigener Statusline-Befehl läuft danach hinter dem Tap weiter.
ensure-statusline-tap.sh --remove nimmt ihn wieder heraus — führ das aus, bevor du CRAFT deinstallierst.
For autopilot runs CRAFT reads your plan's usage windows from the statusline. A plugin cannot
add the tap for that itself, so /craft:prime (step 4h) and /craft:onboard offer it: they show
the change to statusLine in your user settings, back the file up and write only on your yes — your own
statusline command keeps running behind the tap. ensure-statusline-tap.sh --remove takes it out again — run it before you uninstall CRAFT.
Der Status-Graph — und alle AbbiegemöglichkeitenThe status graph — and every branch-off
Jeder Slice-Plan trägt ein Status:-Feld — das Execution-Token des
Workflows: Ein Kommando schreibt es, das nächste konsumiert es. /craft:continue
liest den Status und routet zum richtigen Kommando; sein einziger Schreibzugriff ist das bestätigte Fortsetzen eines pausierten Slice
(Schritt 4a — das eine Resume: stellt den beim Pausieren gesicherten Paused-status wieder her). Der Graph ist maschinell geprüft
(scripts/test-workflow-status-graph.sh) — kein Status ohne Konsumenten.
Every slice plan carries a Status: field — the workflow's execution
token: one command writes it, the next consumes it. /craft:continue
reads the status and routes to the right command; its one write is the confirmed resume of a paused slice
(step 4a — the one resume: it restores the Paused-status recorded by the pause). The graph is machine-checked
(scripts/test-workflow-status-graph.sh) — no status without a consumer.
review = Phase 6 wartet, reviewing = Phase 8 läuft. Bis einschließlich review ist ein /craft:review nur beratend (Findings, keine Fixes, keine Status-Änderung).
„≤5“ ist der Standard für Max attempts (rules.md → ## Self-Verification Settings).
awaiting-approval trägt auch ein Epic-Plan, solange sein Close-PR offen ist (siehe /craft:commit ×2).review = phase 6 pending, reviewing = phase 8 running. Up to and including review, a /craft:review is only advisory (findings, no fixes, no status change).
"≤5" is the default Max attempts (rules.md → ## Self-Verification Settings).
An epic plan carries awaiting-approval too, while its close PR is open (see /craft:commit ×2).Die Abbiegungen im DetailThe branch-offs in detail
| Command | WannWhen | Was passiertWhat happens | RückwegWay back |
|---|---|---|---|
/craft:pause |
Kurz weg, Kontextwechsel — auch per Pause-Wort: eine Nachricht, die nur pause, pausieren oder /craft:pause lautet (siehe Autonomie) — oder ein unterbrochener /craft:execute-Lauf (pausiert jeden noch laufenden Slice)
Stepping away, context switch — also by the pause word: a message that is only pause, pausieren or /craft:pause (see autonomy) — or an interrupted /craft:execute run (pauses every slice still running) |
Pausen-Notiz plus Pause-Record (Paused-status = der ersetzte Status, Paused-since = Zeitstempel) in den Plan, paused; Code und Commits unangetastet. Bei einem interaktiven Slice in Arbeit (implementing, testing, review, refactoring, reviewing, committing) läuft — in beiden Flow-Modi — zuerst /craft:handoff (## Handoff, Handoff active: yes); die Notiz verfasst der Agent dann selbst und zeigt sie, statt zu fragen. Eine erneute Pause behält den Record. Ein blocked Slice wird abgelehnt — die Pause würde den Block verwerfen. Jeder Ausgang, auch einer ohne Pause, erledigt einen offenen Pause-Wunsch (pause-request.sh consume).
Pause note plus pause record (Paused-status = the status it replaces, Paused-since = timestamp) into the plan, paused; code and commits untouched. For an interactive slice in flight (implementing, testing, review, refactoring, reviewing, committing), in either flow mode, /craft:handoff runs first (## Handoff, Handoff active: yes); the agent then composes the note itself and shows it instead of asking. A repeated pause keeps the record. A blocked slice is refused — the pause would drop the block. Every exit, including one that pauses nothing, settles a pending pause request (pause-request.sh consume). |
/craft:continue — Schritt 4a stellt nach Bestätigung Paused-status wieder her (das eine Resume; /craft:build nutzt denselben Schritt)
/craft:continue — step 4a restores Paused-status on confirmation (the one resume; /craft:build runs the same step) |
/craft:handoff |
Kontext „vergiftet", Session festgefahrenContext poisoned, session stuck | Komprimierte Übergabe (## Handoff: Wo stehen wir / Versucht / Ausgeschlossen / Beste nächste Idee) in den Plan, Handoff active: yes. Der Status bleibt unverändert!
Condensed handoff (## Handoff: where we are / tried / ruled out / best next guess) into the plan, Handoff active: yes. Status stays unchanged! |
Neue Session — /craft:prime zeigt den Handoff prominentFresh session — /craft:prime surfaces the handoff prominently |
/craft:block |
Voraussetzung fehlt (Arbeit, Entscheidung, Zugang, Externes)A prerequisite is missing (work, decision, access, external) | Erstklassiger blocked-Zustand: Blocker-Typ klassifizieren (prerequisite-work | external | decision | access), Kontext festhalten, das aktuelle Execution-Token als Blocked-status sichern. Auch ein paused Slice lässt sich blockieren: Blocked-status kommt dann aus seinem Paused-status, der Pause-Record wird entfernt. Bei fehlender Arbeit: Fork Spawn / Park / Descope.
First-class blocked state: classify the blocker (prerequisite-work | external | decision | access), capture context, save the current execution token as Blocked-status. A paused slice can be blocked too: Blocked-status then comes from its Paused-status, and the pause record is removed. For missing work: the spawn / park / descope fork. |
/craft:unblock — [R] Resume / [P] Re-plan / [A] AbortSchließt der vorausgesetzte Slice via /craft:commit, wird der Blockierte automatisch wieder aufgetaucht.
When the prerequisite closes via /craft:commit, the blocked slice auto-resurfaces. |
/craft:abort |
Slice aufgebenAbandon a slice | Mehrfache Warnungen (frische Arbeit? Teil-Commits? Worktree? offener Handoff?), dann zwei Klicks als Bestätigung (der zweite nennt die Slice-ID und dass es nicht rückgängig zu machen ist); die Plan-Datei wird geschlossen: gelöscht, oder nach .claude/plans/.closed/ verschoben, wenn deine Settings das Löschen verbieten oder nachfragen (kein Archiv — abgebrochene Slices haben keinen Archivwert). Ein lebender Handoff-Marker im Worktree wird vor dem Entfernen angezeigt.
Multiple warnings (recent work? partial commits? worktree? open handoff?), then two clicks to confirm (the second names the slice ID and that it cannot be undone); the plan file is closed: deleted, or moved into .claude/plans/.closed/ when your settings deny or ask on removing it (no archive — aborted slices have no archive value). A live handoff marker in the worktree is shown before removal. |
keiner — bewusst endgültignone — deliberately final |
/craft:debug |
[B] in Phase 5, manuell, oder auto-angeboten nach 2 Fix-Versuchen am selben Symptom (Standard; Auto-trigger threshold, die 5 Versuche Max attempts — beide in rules.md → ## Self-Verification Settings)
[B] in phase 5, manual, or auto-offered after 2 fix attempts on the same symptom (default; Auto-trigger threshold, the 5 attempts Max attempts — both in rules.md → ## Self-Verification Settings) |
Vier Schritte: ALIGN (Bug gemeinsam präzisieren) → PROTOCOL (Verifikations-Kommando vor dem ersten Fix einfrieren) → AUTONOMOUS LOOP (bis 5 Versuche, jeder mit Verifikation + Negativ-Check, 15k-Token-Bremse) → ESCALATION (Handoff / Recap / Protokoll neu verhandeln / manuell). Im Autopilot: das Protokoll friert der Builder + code-reviewer ein (oder es ist der fehlgeschlagene committete Check), jeden Versuch beurteilt verify-run.sh, und nur der Endstopp erreicht dich.
Four steps: ALIGN (pin the bug down together) → PROTOCOL (freeze the verification command before any fix) → AUTONOMOUS LOOP (up to 5 attempts, each with verification + negative check, 15k token brake) → ESCALATION (handoff / recap / renegotiate protocol / take it manually). In an autopilot run: the protocol is frozen by the builder + code-reviewer (or is the failed committed check), every attempt is judged by verify-run.sh, and only the end stop reaches you. |
/craft:debug schreibt keinen Status. Erfolg aus Phase 5 → der Slice steht weiter auf testing, zurück zu /craft:test (erst [W] setzt review); aus Phase 4 → zurück zum laufenden Sub-Task. Der Verifikations-Befehl wird als Regressionstest angeboten.
/craft:debug writes no status. Success from phase 5 → the slice is still at testing, back to /craft:test (only [W] sets review); from phase 4 → back to the sub-task being built. The verification command is offered as a regression test. |
/craft:review → Phase 4 |
Heavy+Rethinking-Finding oder Fix-Ceiling (2 × Richtwert) erreicht bzw. nach dem Richtwert ein nicht kleiner Fix — der Mensch wählt den Rücksprung Heavy+rethinking finding, or the fix ceiling (2 × the guide value) reached, or, past the guide value, a finding that is not small — the human chooses the loop-back | Step 8 hängt je Finding einen Sub-Task Loop-back <ID> an, notiert die Entscheidung und setzt implementing. Findings stehen pro Runde mit IDs (R<round>-<n>) in ## Review Findings; ein Re-Review prüft zuerst jedes frühere Finding (holds / partial / broken) und meldet reopens <ID>, wenn ein Fix nicht hält. Welche Zeilen offen sind, liest ein Parser (scripts/review-findings-state.sh) — daran hängt das Commit-Gate. Im Autopilot entscheidet statt dir der Ping-Pong-Breaker (/craft:review Step 9): ein autonomer Rücksprung pro Finding; ein Reopen davon oder Runde 3 mit offenem Heavy (TRIP=, aus dem Record abgeleitet) setzt blocked mit einem Paket von höchstens 15 Zeilen.
Step 8 appends one Loop-back <ID> sub-task per finding, records the decision and sets implementing. Findings are recorded per round with IDs (R<round>-<n>) under ## Review Findings; a re-review first verifies every earlier finding (holds / partial / broken) and raises reopens <ID> when a fix did not hold. Which lines are open is read by one parser (scripts/review-findings-state.sh) — the commit gate depends on it. In an autopilot run the ping-pong breaker (/craft:review Step 9) decides instead of you: one autonomous loop-back per finding; a reopen of it, or round 3 ending with a Heavy open (TRIP=, derived from the record), sets blocked with a package of at most 15 lines. |
/craft:build → Phasen 5–7 → erneut /craft:review
/craft:build → phases 5–7 → /craft:review again |
/craft:release |
In-Place-Build wartet auf IDE-Review (awaiting-release) In-place build awaiting IDE review (awaiting-release) | Die explizite Geste „Ich habe den rohen Diff gesehen — weiter": zeigt git diff --stat, fragt [Y]/[N], setzt testing. Committet, merged und pusht nichts.
The explicit "I've seen the raw diff — proceed" gesture: shows git diff --stat, asks [Y]/[N], sets testing. Commits, merges, pushes nothing. |
weiter in Phase 5on into phase 5 |
/craft:commit ×2 |
Profil: pull-request + Protected-main: yes
Profile: pull-request + Protected-main: yes |
„Freigabe ≠ Merge": Erster Aufruf pusht + öffnet den PR (awaiting-approval), merged aber nicht. Der zweite Aufruf merged via gh pr merge — nur bei echtem GitHub-APPROVED, nie --admin. Der Mensch gibt frei, das System merged. Ein versionierter Plan verlässt den Trunk mit dem PR (scripts/plan-landing.sh).
Epic: Auch Epic-close läuft unter diesem Profil in zwei Durchgängen — dann steht der Epic-Plan auf awaiting-approval (STATE=closing). Der Abschluss fährt auf dem noch offenen PR des Epics mit (STATE=pr-path) oder auf einem eigenen Close-Branch epic-<NNN>-<slug>-close, vom Trunk abgezweigt.
Schutz: A6 stoppt einen Standard-Commit direkt auf dem Trunk — auch dann, wenn gerade der Worktree eines anderen Slice existiert. Ob ein In-place-Slice per Branch landet, entscheiden der erkannte Standard-Modus und der Start-Branch, den der Befehl vor Schritt 0 festhält. Worktrees auf keinem Slice- oder Epic-Branch zählen nicht; jeder wird in einer ·-Zeile genannt (scripts/worktree-kinds.sh).
Ein Slice eines sequenziellen Epics auf awaiting-approval wird mit einem erneuten /craft:execute <epic-NNN> fortgesetzt, nicht mit /craft:commit.
"Approval ≠ merge": the first invocation pushes + opens the PR (awaiting-approval) but does not merge. The second invocation merges via gh pr merge — only on a real GitHub APPROVED, never --admin. The human approves, the system merges. A tracked plan leaves the trunk with the PR (scripts/plan-landing.sh).
Epic: Epic-close also runs in two passes under this profile — the epic plan then reads awaiting-approval (STATE=closing). The close rides on the epic's own open PR (STATE=pr-path) or on a close branch epic-<NNN>-<slug>-close cut from the trunk.
Guards: A6 stops a Standard-mode commit on the trunk — also while another slice's worktree exists. Whether an in-place slice lands by its branch is decided by the detected Standard mode and the start branch the command holds before step 0. Worktrees on no slice or epic branch are ignored and each named in a · line (scripts/worktree-kinds.sh).
A sequential-epic slice at awaiting-approval is resumed by re-running /craft:execute <epic-NNN>, not /craft:commit. |
Slice bzw. Epic schließtslice or epic closes |
Dazu kommt ein zweiter Marker-Namensraum: In Worktrees schreibt der
slice-builder-Agent bei jeder menschenpflichtigen Pause eine .craft/handoff.md
(awaiting-test, awaiting-protocol, awaiting-scope-decision,
awaiting-refactor-decision, awaiting-rethink-decision, awaiting-block-decision,
failure) — das sind Worktree-Marker, keine Slice-Status. Gelöscht wird so ein Marker nie: Er gilt nur als
„Mensch gebraucht", solange der Slice-Plan im Worktree noch auf ihn wartet — also noch beim passenden Status
(paused; blocked für awaiting-block-decision, das /craft:unblock
auflöst; reviewing für awaiting-rethink-decision) und in derselben Episode
(Episode: = Paused-since, Blocked-since bzw. die Review-Runde). Ist die Frage
beantwortet, ist der Marker veraltet; eine spätere Pause belebt ihn nicht wieder. failure hat keinen
passenden Plan-Status: Er gilt bis zu einem neuen Versuch, dann benennt slice-builder ihn mit
--resolve --retry um. Das entscheidet ein Helfer, scripts/handoff-marker-state.sh, für den
SessionStart-Hook, /craft:worktree-status und /craft:execute — im Zweifel gilt der Marker.
slice-builder benennt veraltete Marker in handoff-resolved-<Written>.md um;
/craft:abort und /craft:worktree-clean zeigen einen lebenden Marker, bevor sie den
Worktree entfernen.
There is a second marker namespace: inside worktrees the slice-builder
agent writes a .craft/handoff.md on every human-required pause (awaiting-test,
awaiting-protocol, awaiting-scope-decision, awaiting-refactor-decision,
awaiting-rethink-decision, awaiting-block-decision, failure) — worktree markers,
not slice statuses. No command deletes such a marker: it means "human needed" only while the slice plan in the
worktree still waits for it — at the paired status (paused; blocked for
awaiting-block-decision, which /craft:unblock resolves; reviewing for
awaiting-rethink-decision) and in the same episode (Episode: =
Paused-since, Blocked-since or the review round). Once answered, the marker is stale; a later
pause never revives it. failure pairs with no plan status: it stays live until a retry, when
slice-builder renames it with --resolve --retry. One helper, scripts/handoff-marker-state.sh, decides this
for the SessionStart hook, /craft:worktree-status and /craft:execute — doubt means live.
slice-builder renames a stale marker to handoff-resolved-<Written>.md;
/craft:abort and /craft:worktree-clean show a live marker before they remove its worktree.
Wer entscheidet was — die Autonomie-TaxonomieWho decides what — the autonomy taxonomy
Vier Stufen regeln, wie selbstständig der Agent handelt. Jede Phase hat eine Default-Stufe (siehe Loop) — aber bestimmte Aktionstypen erzwingen ihre Stufe phasenübergreifend:
Four levels govern how independently the agent acts. Each phase has a default level (see the loop) — but certain action types force their level across all phases:
L0 Ask-Always
Explizit fragen, auf „Ja" warten.Ask explicitly, wait for a "yes".
L1 Propose-Confirm
Vorschlagen, Bestätigung abwarten.Propose, wait for confirmation.
L2 Auto-Notify
Handeln, dann kompakt an der Bündel-Grenze melden — Pause/Rollback möglich. Act, then report compactly at the bundle boundary — pause/rollback possible.
L3 Auto-Silent
Ohne Unterbrechung handeln (immer im nächsten Bündel zusammengefasst, nie unsichtbar). Act without interrupting (always summarized in the next bundle, never invisible).
| AktionAction | StufeLevel | BegründungRationale |
|---|---|---|
| Datei lesen, grep, Lint-Check, TestlaufFile read, grep, lint check, test run | L3 | reine Informationsbeschaffung, read-onlypure info gathering, read-only |
| Code-Edit im Plan-ScopeCode edit inside plan scope | L2 | der Plan ist der Vertragthe plan is the contract |
| Code-Edit außerhalb des Plan-ScopesCode edit outside plan scope | L1 | Scope-Grenzen bestätigt der Menschscope boundaries are the human's call |
| Git-Commit | L1 | nachvollziehbare Historieaccountable history |
| Lokale Branch-Operationen (nicht destruktiv)Local branch ops (non-destructive) | L2 | wiederherstellbarrecoverable |
rules.md / intent.md ändernmutation |
L0 | „heilig" — nie still mutiert"sacred" — never silently mutated |
| Git-Push, PR, Deploy | L0 | extern & irreversibelexternal & irreversible |
| Branch löschen, Force-PushBranch delete, force-push | L0 | destruktivdestructive |
Strukturell menschlich — vom Agenten nie fabriziert: UX-Feedback
([W]/[B]/[U]), Refactoring-Auswahl, Eskalations-Routing, Entscheidungs-Promotion
([K]/[I]/[R]/[D]), Scope-Änderungen, Merges. Im Autopilot-Lauf ersetzen feste Regeln einige dieser
Schritte, ohne ein Urteil zu erfinden: Der Ping-Pong-Breaker gibt einem Heavy + needs-rethinking-Finding genau einen
Rücksprung, verify-run.sh entscheidet Phase 5, Refactoring-Kandidaten werden festgehalten statt
angewendet, und jede Entscheidung wird als [K] notiert — der Mensch wählt und befördert am Epic-Ende.
Dazu die Bündel-Disziplin:
Meldung an jeder Sub-Task-Grenze, 30k-Token-Bremse (15k im Debug-Loop) gegen die „Dumb Zone", und
jede Auswahl — Buchstaben-Menüs, Ja/Nein, Fragen mit typischen Antworten — ist in einer interaktiven Session ein Klick
(AskUserQuestion). Eine Frage ohne sinnvolle Vorgaben (eine Vision, eine Fehlerbeschreibung) bleibt eine
Texteingabe. Hängt eine Frage von der vorigen Antwort ab, kommt sie in einem eigenen Aufruf; eine Bestätigungskette wie
die von /craft:abort endet beim ersten Nein. Wo niemand klicken kann (Subagent, claude -p),
zeigt das Menü immer die volle Legende — ebenso an den Autopilot-Stopps (Frage nach verwaisten Plänen, Plan-Gate, a5,
die ⛔-Stopps): Sie schalten den Cache-Guard scharf und werden getippt beantwortet, weil ein Klick an dessen Prompt-Hook vorbeiginge.
Structurally human — never fabricated by the agent: UX feedback
([W]/[B]/[U]), refactor selection, escalation routing, decision promotion
([K]/[I]/[R]/[D]), scope changes, merges. In an autopilot run deterministic rules replace some of these
steps without inventing a judgment: the ping-pong breaker gives a Heavy + needs-rethinking finding exactly one
loop-back, verify-run.sh decides Phase 5, refactor candidates are recorded rather than applied, and every
decision is recorded [K] — the human selects and promotes at the epic end.
Plus the bundling discipline:
a report at every sub-task boundary, a 30k token brake (15k inside the debug loop) against the
"dumb zone", and every choice — lettered menu, yes/no, question with typical answers — is a click
(AskUserQuestion) in an interactive session. A question with no meaningful presets (a Vision, a bug
description) stays typed. A question that depends on an earlier answer is asked in a call of its own; a confirmation
chain such as /craft:abort's ends at the first No. Where nobody can click (subagent, claude -p)
the menu always renders its full legend — as do the autopilot stops (the orphan question, the plan gate, a5, the ⛔
stops): they arm the cache guard and are answered by typing, because a click would get past its prompt hook.
Auto-Flow (Slice Flow → Mode: auto, der Standard): ein interaktiver Slice wandert von selbst von Phase zu Phase —
bis einschließlich des Commits. Am Ende jedes Phasen-Commands fragt der Agent scripts/flow-state.sh (Modus, Plan-Status) und
handelt nur nach NEXT= / STOP=; im Zweifel hält er an. Die menschlichen Entscheidungen bleiben menschlich — als Klicks —, und der Flow läuft
direkt nach der Antwort weiter. Wo er endet, nennt eine Zeile Auto flow stops: <reason>: committed; blocked, paused,
awaiting-release, awaiting-approval (ein Mensch hält den Slice); pause-requested; no-progress (die Phase endet im Status, in dem sie begann — sie wartet auf dich);
invalid-mode; no-plan, unknown-status. /craft:commit beendet den Flow und fragt den Helfer gar nicht mehr; ein beratendes /craft:review kettet nie an;
ein Command, der schon im Pre-flight ablehnt, macht keinen Flow-Schritt. Nie in einer Headless-Session (claude -p); /craft:execute und der Autopilot orchestrieren weiter selbst.
Mit Mode: auto fragt /craft:plan nach einem erfolgreich geschriebenen Plan mit einem Klick: Build now / Later.
manual (im Preset careful) ist das bisherige Verhalten: ein Command pro Phase, am Ende Recommended next:.
Das Pause-Wort (in beiden Flow-Modi): Schicke eine Nachricht, die nur pause, pausieren oder /craft:pause lautet
(stop und halt bewusst nicht). Es zählt nur für einen interaktiven Slice in Arbeit — nicht bei planning, nicht im Subagent Mode, nicht im Autopilot-Lauf.
Der Agent hält den Wunsch zuerst in .claude/plans/.pause-request fest
(scripts/pause-request.sh request); an der nächsten Sub-Task- oder Phasengrenze meldet flow-state.sh STOP=pause-requested.
Der Agent beendet den laufenden Schritt, schreibt die Übergabe (/craft:handoff) und pausiert den Slice (/craft:pause);
/craft:continue setzt fort. Läuft gerade kein Schritt, pausiert er sofort. Bei jedem Countdown — dem Sub-Task-Bündel von /craft:build, dem Punkte-Bündel von /craft:refactor, dem von /craft:debug — pausiert ein reines Pause-Wort den Slice; jede andere Eingabe hält nur den Countdown bzw. die Debug-Schleife an.
Erledigt wird ein Wunsch durch /craft:pause, /craft:handoff, /craft:commit, /craft:abort und jedes andere STOP=; ein Wunsch, der älter ist als das > Resumed: des Plans, gilt nicht.
Die Grenze des Hooks: UserPromptSubmit feuert nicht für eine Nachricht, die mitten im Zug zugestellt wird (Menschentest T3) — der Hook deckt nur ein Pause-Wort ab, das als eigener Prompt kommt.
/craft:pause bleibt ein Pause-Wort, ist aber ein Befehl: Claude Code hält ihn zurück, bis der Zug endet, er wirkt also erst dann und kann einen laufenden Flow nicht mitten im Zug anhalten wie pause / pausieren.
Auto flow (Slice Flow → Mode: auto, the default): an interactive slice moves from phase to phase by itself —
up to and including the commit. At the end of every phase command the agent asks scripts/flow-state.sh (mode, plan status) and
acts on NEXT= / STOP= only; in doubt it stops. The human decisions stay human — as clicks — and the flow goes on
right after the answer. Where it ends, one line says Auto flow stops: <reason>: committed; blocked, paused,
awaiting-release, awaiting-approval (a human holds the slice); pause-requested; no-progress (the phase ended in the status it began in — it waits for you);
invalid-mode; no-plan, unknown-status. /craft:commit ends the flow and never asks the helper; an advisory /craft:review never chains;
a command that refused in its Pre-flight runs no flow step. Never in a headless session (claude -p); /craft:execute and the autopilot keep orchestrating on their own.
With Mode: auto, /craft:plan asks one click after a successful plan write: Build now / Later.
manual (the careful preset) is the behavior as before: one command per phase, each ending with Recommended next:.
The pause word (in both flow modes): send a message that is only pause, pausieren or /craft:pause
(stop and halt are deliberately not pause words). It counts only for an interactive slice in flight — not at planning, not in Subagent Mode, not in an autopilot run.
The agent records the request first in .claude/plans/.pause-request
(scripts/pause-request.sh request); at the next sub-task or phase boundary flow-state.sh says STOP=pause-requested.
The agent finishes the running step, writes the handoff (/craft:handoff) and pauses the slice (/craft:pause);
/craft:continue resumes it. Sent while no step is running, it pauses at once. At every countdown — /craft:build's sub-task bundle, /craft:refactor's item bundle, /craft:debug's — a bare pause word pauses the slice; any other input halts only the countdown or the debug loop.
A request is settled by /craft:pause, /craft:handoff, /craft:commit, /craft:abort and any other STOP=; a request older than the plan's > Resumed: is no request.
The hook's limit: UserPromptSubmit does not fire for a message delivered mid-turn (human test T3), so the hook covers only a pause word sent as a prompt of its own.
/craft:pause stays a pause word but is a command: Claude Code holds it until the turn ends, so it takes effect only then and cannot stop a running flow mid-turn the way pause / pausieren can.
Regel-Konflikte: Bend / Override / RepealRule conflicts: bend / override / repeal
Will der Mensch eine Regel umgehen, biegt der Agent sie nie still — er bietet drei Stufen an:
Bend (nur dieser eine Austausch), Override (slice-weit, im Plan unter
Active Rule Overrides protokolliert, in Phase 9 gelöscht), Repeal (dauerhaft —
rules.md wird mit Bestätigung geändert). Drift zwischen Rules und State wird von
/craft:prime nur gemeldet, nie automatisch korrigiert.
When the human wants to bypass a rule, the agent never bends it silently — it offers three
stages: bend (this one exchange only), override (slice-scoped, recorded in
the plan under Active Rule Overrides, cleared in phase 9), repeal (permanent —
rules.md edited with confirmation). Rules↔State drift is only reported by
/craft:prime, never auto-corrected.
Autonome Ausführung — die vier WegeAutonomous execution — the four paths
/craft:execute <epic-NNN | slice-NNN> [--autopilot] ist der Orchestrator: Er
verwandelt einen geplanten Epic oder Slice in gebauten Code, ohne dass du jede Phase einzeln anstößt. Welcher der
ersten drei Wege läuft, entscheidet das CRAFT-Profil; der vierte, der Autopilot, ist ein
Schalter pro Lauf — egal, was Epic Mode sagt. Nur der Autopilot baut ein Epic freihändig bis zur
Abnahme. Im parallelen Modus hält jeder Slice für dich an: in Phase 5 (Handoff awaiting-test, Slice
pausiert) und in Phase 7 (die Refactoring-Auswahl, sofern Phase 7 nicht abgeschaltet ist). Du gehst mit
/craft:checkout hinein, setzt mit /craft:continue fort, beantwortest die Phase und rufst
danach /craft:execute erneut auf.
/craft:execute <epic-NNN | slice-NNN> [--autopilot] is the orchestrator: it turns
a planned epic or slice into built code without you starting every phase. Which of the first three paths runs is
decided by the CRAFT profile; the fourth, the autopilot, is a per-run switch, whatever
Epic Mode says. Only the autopilot builds an epic hands-off up to the sign-off. In parallel mode every
slice halts for you: at Phase 5 (an awaiting-test handoff, the slice paused) and at Phase 7 (the refactor
pick, unless Phase 7 is dropped). You go in with /craft:checkout, resume with
/craft:continue, answer the phase, then run /craft:execute again.
Epic Mode: parallel bzw. Execution → Mode: worktree;
Weg 2 Execution → Mode: in-place; Weg 3 Epic Mode: sequential; Weg 4, pro Lauf,
/craft:execute <epic> --autopilot — egal, was Epic Mode sagt: der sequenzielle Weg
auf einem Epic-Branch, ohne Halt zwischen den Slices.Epic Mode: parallel / Execution → Mode: worktree;
path 2 = Execution → Mode: in-place; path 3 = Epic Mode: sequential; path 4, per run,
/craft:execute <epic> --autopilot — whatever Epic Mode says: the sequential path on an
epic branch, with no halt between slices.Was der Orchestrator garantiert
- Worktree-Trust: Worktrees liegen außerhalb des Projektordners
(
../<repo>-worktrees/<slice-id>-<slug>/). Ihr Basisverzeichnis wird — einmalig, nach Bestätigung — inpermissions.additionalDirectoriesvon.claude/settings.local.jsoneingetragen, damit keine Permission-Prompts den Lauf stoppen. - Lock-Datei:
.claude/plans/.execute.lockverhindert parallele Läufe. Sie wird nie gelöscht, ihr Inhalt sagtheldoderreleased; ob ein neuer Lauf sie übernimmt, entscheidetexecute-lock.shnach fester Regel (Besitzer ist der Claude-Code-Prozess). Post-Assertions prüfen die Freigabe. - Abhängigkeiten: Slices mit
Depends-Onwerden als DAG aufgelöst; nur die freie „Frontier" läuft parallel. - Epic-Einträge ↔ Slice-IDs:
/craft:planverknüpft einen verfeinerten Zerlegungs-Eintrag mit seiner Slice-ID. A6 löst die Einträge nur überscripts/epic-entry-link.shauf (plan/landed/missing/ambiguous/unlinked) — so findet auch ein erneuter Lauf einen bereits gelandeten Slice. Ein Eintrag ohne Slice-ID wird abgelehnt, selbst wenn sein Plan existiert, mit dem Befehl, der ihn verknüpft. - Review-Checkpoints: Im Epic-Plan markierte Slices stoppen den Lauf vor dem Merge;
ein gezeigter Checkpoint wird mit dem Stand des Slice in
.craft/checkpoints.mddes Epic-Worktrees vermerkt — der nächste Lauf gilt als Freigabe und merged; hat sich der Slice seitdem geändert, hält er erneut. - Erneuter Lauf: Ein zweites
/craft:executebaut auf dem auf, was ein früherer Lauf hinterlassen hat. Schritt 1c (scripts/execute-resume-state.sh) liest das vor jedem Schreibzugriff: Worktrees werden wiederverwendet (reuse), gemergte Slices übersprungen (skip), der angehaltene Slice eines sequenziellen Epics fortgesetzt (resume), pausierte oder blockierte Slices bleiben stehen (held). Was nichts erklärt — ein übrig gebliebener Branch, ein schmutziger Baum, ein nicht committeter Epic-Plan (plan_not_committed) — bricht ab, bevor irgendetwas angelegt wird, und nennt die Korrektur. Der Plan eines Slices muss nicht committet sein: Schritt 5 kopiert ihn in den neuen Worktree (scripts/plan-roundtrip.shin). - Sauberer Baum: CRAFTs eigene Pläne, ID-Zähler und lokaler Zustand zählen nicht als
uncommittete Arbeit (
scripts/tree-dirt-state.sh). Ein Epic-Worktree entsteht nur aus einer Basis, die den Epic-Plan byte-gleich enthält; der Plan eines Slices wird stattdessen in seinen Worktree kopiert. Unter Protected-main reist das Entfernen eines versionierten Plans im freigegebenen PR mit; der zweite/craft:commit-Durchlauf entfernt die lokale Kopie, bevor er den Trunk synchronisiert (scripts/plan-landing.sh). - Autopilot (
--autopilot) — der freihändige Weg: baut ein Epic, egal wasEpic Modesagt, Slice für Slice in place aufepic-<NNN>-<slug>, ohne Halt zwischen den Slices;mainbewegt sich erst, wenn du am Ende Ja sagst. Voraussetzung: eine Session, gestartet mitCLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 claude(Builder im Vordergrund). Läuft die Session nicht auf Sonnet, nennt eine Zeile die Mehrkosten — das Modell wechselt der Lauf nie selbst (a0). - Autopilot — Planung und Plan-Gate (ap): Gibt es aktive Pläne, die kein Epic-Eintrag
verknüpft, während noch Einträge ungeplant sind, fragt der Lauf zuerst — einer davon könnte einen Eintrag schon
planen:
[P]trotzdem planen ·[N]stoppen (die Pläne erst verknüpfen oder mit/craft:abortverwerfen). Dann planenslice-planner-Agents jeden ungeplanten Eintrag (der Master vergibt die IDs und verknüpft die Einträge), einplan-architectprüft das Paket — seine Findings gehen bis zu zweimal automatisch an die Planner zurück —, und der Lauf hält einmal am Plan-Gate: das Paket samt Briefing,[Y]starten ·[R] <slice-id>[, …] — <note>überarbeiten ·[N]stoppen.[Y]fehlt, solange ein Plan eine Prüfung nicht bestanden hat, ein Eintrag gescheitert ist oder eineNEEDS-HUMAN:-Zeile offen ist; offene Findings desplan-architectsperren es nicht. Ob das Gate noch aussteht, leitetscripts/plan-gate-state.shab. - Autopilot — Briefing zum Start (a1): Jeder Aufruf, auch ein erneuter, gibt den Block von
scripts/autopilot-briefing.shunverändert weiter: Titel, Branch, dass der Checkout belegt ist, die Slice-Reihenfolge (topologisch nachDepends-On, bei Gleichstand in Zerlegungs-Reihenfolge), „Stops for you at", wie man anhält und wie man fortsetzt. Scheitert das Skript, endet der Lauf mit⛔ … briefing failed;scripts/autopilot-log.shverweigert jeden Slice-Schritt, bisrun startedfür diesen Aufruf im Log steht. - Autopilot — Bauen (a2/a3): je Slice ein
slice-builderim Vordergrund, dann/craft:commitauf Level 2 (Split ohne Rückfrage, Entscheidungen[K]) auf dem Epic-Branch. Phase 7 notiert bis zu zwei Refactoring-Kandidaten, wendet keinen an und listet sie im Epic-Digest; jedes Ereignis landet im## Autopilot Logdes Epic-Plans. Phase 5 prüftscripts/verify-run.shper Befehl aus dem<!-- craft:verify -->-Block der Test Strategy (jeder Befehl vorher gegen deine deny-/ask-Regeln geprüft); nur ein sauberer Pass ersetzt deine Prüfung, und die Landed-Zeile jedes Slice hält fest, ob Phase 5 per Befehl oder von dir bestanden wurde. Ein Bug (ein fehlgeschlagener Check, oder der 2. Fix am selben Symptom in Phase 4) bekommt zuerst einen autonomen/craft:debug-Loop, dessen Versucheverify-run.shbeurteilt. Im Review bekommt nur ein Heavy-Finding mit needs-rethinking einen autonomen Rücksprung nach Phase 4; taucht es wieder auf (TRIP=reopen:<ID>) oder ist die Rundengrenze erreicht (TRIP=round-cap), wird der Slice blockiert — mit einem Eskalationspaket von höchstens 15 Zeilen. - Autopilot — Halte: Ein erschöpfter Debug-Loop, ein abgelehnter oder fehlender Check, ein
ausgelöster Ping-Pong-Breaker, ein Blocker oder Fehler beenden den Lauf (
⛔ … stopped:), ebenso der Budget-Schutz (scripts/usage-state.shaus dem Statusline-Tap, Grenzen in## Autopilotdes Profils: kein Slice, den das 5-Stunden-Fenster samt Prognose nicht trägt, Halt an der nächsten Grenze im Builder — Sub-Task, Phase oder Debug-Versuch —, kein Slice über der Wochengrenze; ohne Messwert nach jedem Slice); ein erneuter Aufruf setzt fort. Die Orphan-Frage, das Plan-Gate, die Abnahme in a5 und jeder⛔-Halt werden getippt beantwortet, nicht geklickt — der Cache-Schutz sieht einen Prompt, keinen Klick. Jeder solche Halt nennt vorher, bis wann der Prompt-Cache warm ist; kommt deine Antwort später und ein Neuschreiben wäre teuer, blockierthooks/cache-guard.shsie und nennt den Neustart. - Autopilot — Abnahme (a5): Am Ende ein Digest, den
scripts/epic-digest.sherzeugt (nicht der Master aus dem Gedächtnis), mit dem UX-Demo-Skript aller Slices wörtlich, und die FrageMerge <epic-branch> into <trunk>?— bis zu deiner Antwort hält der Lauf seinen Lock.[Y]unterdirect:git merge --no-ff <epic-branch>in den Trunk.[Y]unterpull-request+Protected-main: yes: pusht den Epic-Branch und öffnet einen PR, dessen Text der Digest ist — ruf/craft:commitauf, bevor du ihn freigibst: es legt die Aufzeichnung des Epics in diesen PR.[N]: fertig, nicht gemergt, kein Abschluss. Endet die Session ohne Antwort, wird nichts geschrieben und der Lock bleibt gehalten; ein erneuter Aufruf fragt noch einmal. - Epic-close:
/craft:commitschließt ein fertiges Epic — Entscheidungen, Epic-Archiv, Epic-Plan, bei einem Autopilot-Epic auch den Epic-Branch: nach dem Merge oder PR eines Autopilot-Laufs (KIND=autopilot), nach s5 eines sequenziellen Epics und bei einem Epic, das Slice für Slice von Hand gebaut wurde (KIND=sequential). Ob es so weit ist, leitetscripts/epic-close-state.shab; zuerst fragt es[Y] close it / [N] leave it open. Bei geschütztem main läuft es in zwei Durchgängen — über den offenen Epic-PR oder, wenn keiner offen ist, über einen eigenen Close-Branchepic-<NNN>-<slug>-closemit Close-PR: Der erste Durchgang legt die Aufzeichnung in den PR, der zweite merged nach deiner Freigabe überghund synchronisiert den Trunk. - Harte Grenzen: merged nie selbst nach
main(das ist/craft:commit; einzige Ausnahme: dein[Y]am Ende eines Autopilot-Laufs) und löst Heavy+Rethinking-Findings nie selbst auf. Gepusht wird nur, wo ein PR entstehen muss — unter geschütztem main der Epic-Branch eines Autopilot-Laufs bei[Y]und der Slice-Branch eines sequenziellen Epics, dessen PR/craft:commitin s3 öffnet; nie der Trunk, nie mit Force. Was ein Halt bewirkt, hängt vom Weg ab: Im parallelen Modus bricht der Handoff eines Slice den Lauf nicht ab — unabhängige Slices laufen weiter —, und eine Unterbrechung pausiert jeden noch laufenden Slice mit Pause-Record. Im Autopilot beendet ein Handoff-, Fehler- oder Held-Halt den ganzen Lauf (⛔ … stopped:) und gibt den Lock frei; Esc beendet ihn, wo er gerade war, und pausiert nichts — der Lock bleibt gehalten, beim erneuten Aufruf fragt A4, ob der alte Lauf beendet ist ([N]), dann wird der Slice fortgesetzt. Im sequenziellen Epic gibt ein harter Halt mitten im Slice den Lock frei und stoppt; der erneute Aufruf setzt den Slice fort.
Rundherum: /craft:worktree-status (Übersicht aller Worktrees inkl. lebender Handoff-Marker),
/craft:checkout (in einen Worktree zum Inspizieren wechseln),
/craft:worktree-clean (verwaiste Worktrees nach Bestätigung entfernen, einen offenen Handoff vorher
anzeigen — nie mit --force).
What the orchestrator guarantees
- Worktree trust: worktrees live outside the project root
(
../<repo>-worktrees/<slice-id>-<slug>/). Their base directory is added — once, after confirmation — topermissions.additionalDirectoriesin.claude/settings.local.jsonso permission prompts can't stall the run. - Lock file:
.claude/plans/.execute.lockprevents concurrent runs. It is never removed; its content saysheldorreleased, and whether a new run takes it over isexecute-lock.sh's fixed rule (the owner is the Claude Code process). Post-assertions verify its release. - Dependencies: slices with
Depends-Onare resolved as a DAG; only the free "frontier" runs in parallel. - Epic entries ↔ slice IDs:
/craft:planlinks a refined decomposition entry to its slice ID. A6 resolves entries only throughscripts/epic-entry-link.sh(plan/landed/missing/ambiguous/unlinked) — so a re-run still finds a slice that has already landed. An entry without a slice ID is rejected, even while its plan exists, with the command that links it. - Review checkpoints: slices marked in the epic plan halt the run before merging;
a shown checkpoint is recorded with the slice's tip in the epic worktree's
.craft/checkpoints.md— the next run counts as the go-ahead and merges; a slice changed since it was shown halts again. - Re-runs: a second
/craft:executebuilds on what an earlier run left behind. Step 1c (scripts/execute-resume-state.sh) reads it before any write: worktrees are reused (reuse), merged slices skipped (skip), a sequential epic's stopped slice resumed (resume), paused or blocked slices left where they are (held). Anything nothing accounts for — a leftover branch, a dirty tree, an uncommitted epic plan (plan_not_committed) — aborts before anything is created and names the fix. A slice's plan needs no commit: step 5 copies it into the new worktree (scripts/plan-roundtrip.shin). - Clean tree: CRAFT's own plans, ID counters and local state do not count as uncommitted work
(
scripts/tree-dirt-state.sh). An epic worktree is created only from a base that holds the epic plan byte-identical; a slice's plan is copied into its worktree instead. Under protected main a tracked plan's removal rides in the approved PR; the second/craft:commitpass drops the local copy before it syncs the trunk (scripts/plan-landing.sh). - Autopilot (
--autopilot) — the hands-off path: builds an epic, whateverEpic Modesays, slice by slice in place onepic-<NNN>-<slug>, with no halt between slices;maindoes not move until you say yes at the end. Needs a session started withCLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 claude(foreground builders). A session not on Sonnet gets a one-line cost note — the run never switches the model itself (a0). - Autopilot — planning and the plan gate (ap): when active plans exist that no epic entry links
while entries are still unplanned, the run asks first — one of them may already plan an entry:
[P]plan anyway ·[N]stop (link them, or/craft:abortthem, first). Thenslice-planneragents plan every unplanned entry (the master allocates the IDs and links the entries), aplan-architectreviews the package — its findings go back to the planners up to twice — and the run stops once at the plan gate: the package plus the briefing,[Y]run ·[R] <slice-id>[, …] — <note>revise ·[N]stop.[Y]is withheld while a plan failed a check, an entry failed, or anyNEEDS-HUMAN:line is open; openplan-architectfindings do not withhold it. Whether the gate is still owed is derived byscripts/plan-gate-state.sh. - Autopilot — run-start briefing (a1): every invocation, re-runs included, relays the block of
scripts/autopilot-briefing.shunchanged: title, branch, that the checkout is occupied, the slice order (topological byDepends-On, ties in decomposition order), "Stops for you at", how to stop and how to resume. If the script fails, the run ends with⛔ … briefing failed;scripts/autopilot-log.shrefuses every slice step until this invocation'srun startedis logged. - Autopilot — building (a2/a3): a foreground
slice-builderper slice, then/craft:commitat Level 2 (split without questions, decisions[K]) on the epic branch. Phase 7 records up to two refactor candidates, applies none and lists them in the epic digest; every event goes to the epic plan's## Autopilot Log. Phase 5 is checked byscripts/verify-run.sh, by command, from the Test Strategy's<!-- craft:verify -->block (each command judged against your deny / ask rules first); only a clean pass replaces your check, and each slice's landed line records whether Phase 5 was verified by command or by you. A bug (a failed check, or a 2nd fix on the same symptom in Phase 4) first gets an autonomous/craft:debugloop whose attemptsverify-run.shjudges. In review, only a Heavy + needs-rethinking finding gets one autonomous loop-back to Phase 4; its reopen (TRIP=reopen:<ID>) or the round cap (TRIP=round-cap) blocks the slice, with an escalation package of at most 15 lines. - Autopilot — stops: an exhausted debug loop, a refused or missing check, a tripped ping-pong
breaker, a blocker or a failure ends the run (
⛔ … stopped:), and so does the budget guard (scripts/usage-state.shfrom the statusline tap, limits in the profile's## Autopilot: no slice the 5-hour window cannot carry with the forecast, a stop at the builder's next boundary — sub-task, phase or debug attempt —, no slice past the weekly limit; without a reading after every slice); a re-run resumes it. The orphan question, the plan gate, the a5 sign-off and every⛔stop are answered by typing, not by a click — the cache guard sees a prompt, not a click. Each such stop first says until when the prompt cache is warm; an answer that arrives later, when a re-write would be expensive, is blocked byhooks/cache-guard.shwith the restart. - Autopilot — sign-off (a5): at the end a digest generated by
scripts/epic-digest.sh(not written by the master from memory) with every slice's UX demo script as written, and the questionMerge <epic-branch> into <trunk>?— the run holds its lock until you answer.[Y]underdirect:git merge --no-ff <epic-branch>into the trunk.[Y]underpull-request+Protected-main: yes: pushes the epic branch and opens a PR whose body is the digest — run/craft:commitbefore you approve it: it adds the epic's record to that PR.[N]: complete, not merged, no close. A session that ends unanswered writes nothing and keeps the lock; a re-run asks again. - Epic-close:
/craft:commitcloses a finished epic — its decisions, epic archive, epic plan and, for an autopilot epic, its epic branch: after an autopilot run's merge or PR (KIND=autopilot), after a sequential epic's s5, and for an epic worked slice by slice by hand (KIND=sequential). Whether it is ready is derived byscripts/epic-close-state.sh; it asks[Y] close it / [N] leave it openfirst. Under protected main it runs in two passes — through the epic's open PR or, when none is open, through a close branch of its own,epic-<NNN>-<slug>-close, and a close PR: the first pass puts the record into the PR, the second merges viaghafter your approval and syncs the trunk. - Hard limits: never merges into
mainitself (that is/craft:commit; the one exception is your[Y]at the end of an autopilot run), never resolves Heavy+rethinking findings itself. It pushes only where a PR must be opened — under protected main, an autopilot run's epic branch on[Y], and a sequential epic's slice branch, whose PR/craft:commitopens in s3; never the trunk, never with force. What a stop does depends on the path: in parallel mode one slice's handoff doesn't abort the run — independent slices continue — and an interrupt pauses every slice still running, with its pause record. In an autopilot run a Handoff, Failure or Held stop ends the whole run (⛔ … stopped:) and releases the lock; Esc ends it where it was and pauses nothing — the lock stays held, the re-run's A4 asks whether the earlier run ended ([N]), then the slice resumes. In a sequential epic a mid-slice hard stop releases the lock and stops; the re-run resumes the slice.
Around it: /craft:worktree-status (overview of all worktrees incl. live handoff markers),
/craft:checkout (switch into a worktree for inspection),
/craft:worktree-clean (remove orphaned worktrees after confirmation, showing an open handoff first —
never with --force).
Alle Stellschrauben — die KonfigurationsreferenzEvery knob — the configuration reference
Das CRAFT-ProfilThe CRAFT profile — .claude/project/craft-profile.md
Das portable Betriebsprofil eines Projekts: Autonomie-, Commit-, Merge-, Sprach- und
Modell-Einstellungen an einem Ort. Fehlt die Datei, gilt implizit das Preset balanced.
Das Onboarding fragt [D] Defaults (immer das Preset balanced) oder [G] Guided:
eine Frage pro Stellschraube — Execution, Auto-commit (nur bei in-place), Co-Authored-By, Merge,
Epic Mode, Slice Flow, Permissions. Den Preset-Namen leitet es danach ab: careful / balanced /
autonomous nur bei exakter Übereinstimmung, sonst custom. Die Zeile > Preset:
ist nur ein Etikett, das /craft:prime meldet — es gelten immer die Werte in der Datei, ohne feldweises
Mischen mit einem Preset. /craft:prime validiert das Profil jede Session — Warnungen, nie Abbruch.
A project's portable operating profile: autonomy, commit, merge, language and model settings
in one place. If the file is absent, the balanced preset applies implicitly. Onboarding asks
[D] Defaults (always the balanced preset) or [G] Guided: one question per knob —
Execution, Auto-commit (only for in-place), Co-Authored-By, Merge, Epic Mode, Slice Flow, Permissions.
It derives the preset name afterwards: careful / balanced / autonomous only on an
exact match, otherwise custom. The > Preset: line is just a label that
/craft:prime reports — the values in the file always win, with no field-level merge with a preset.
/craft:prime validates the profile every session — warnings, never aborts.
| Preset | Execution Mode | Auto- commit | Merge | Epic Mode | Slice Flow | Permission Scope |
CharakterCharacter |
|---|---|---|---|---|---|---|---|
careful | in-place | off |
pull-request + protected-main + GitHub-Review |
sequential | manual | minimal |
/craft:execute <slice> hält vor Phase 5 für die Durchsicht in der IDE; Epics laufen sequenziell; alles landet per freigegebenem PR.
/craft:execute <slice> halts before phase 5 for the review in your IDE; epics run sequentially; everything lands via an approved PR. |
balanced ★ | worktree | on |
direct | parallel | auto | standard |
Der Default: parallele Worktrees, direkte Merges, Chat-Freigaben. The default: parallel worktrees, direct merges, chat approvals. |
autonomous | worktree | on |
direct | parallel | auto | broad |
Wie balanced, aber mit breiterer Read-only-Allowlist — weniger Prompts. Like balanced but with a broader read-only allowlist — fewer prompts. |
| Block → FeldBlock → field | Werte (Default fett)Values (default bold) | WirkungEffect |
|---|---|---|
Execution → Mode | worktree | in-place |
Worktree: Wegwerf-Worktree außerhalb des Repos, parallelsicher. In-place: Branch im Haupt-Checkout, Halt vor Phase 5 (/craft:release). Gilt nur für /craft:execute <slice>: ein Epic folgt Epic Mode, --autopilot seinem eigenen Weg.
Worktree: throwaway worktree outside the repo, parallel-safe. In-place: branch in the main checkout, halt before phase 5 (/craft:release). Governs /craft:execute <slice> only: an epic follows Epic Mode, --autopilot its own path. |
Commit Policy → Auto-commit | on | off |
Ändert derzeit kein Verhalten: Der Worktree-Weg committet die Arbeit eines Slices in /craft:execute Schritt 6, sobald er das Review bestanden hat (off wird dort ignoriert); der In-place-Weg hält alles bis /craft:release uncommitted, egal was hier steht. Einzige Wirkung: /craft:prime warnt bei off zusammen mit Mode: worktree.
Currently changes no behavior: the worktree path commits a slice's work at /craft:execute step 6, once it clears review (off is ignored there); the in-place path holds everything uncommitted until /craft:release, whatever this says. Its only effect: /craft:prime warns on off together with Mode: worktree. |
Commit Policy → Co-Authored-By | on | off |
on: /craft:commit hängt an jeden Commit des Laufs den wörtlichen Trailer Co-Authored-By: Claude <noreply@anthropic.com>. Das Feld ist die einzige Quelle einer Attribution: Zeilen, die die Claude-Code-Session selbst verlangt, kommen nicht dazu; eine nicht aktivierte Zeile entfällt kommentarlos. Alle drei Presets liefern off.
on: /craft:commit appends the literal trailer Co-Authored-By: Claude <noreply@anthropic.com> to every commit of the run. The field is the only source of attribution: lines the Claude Code session itself asks for are not added; a line the profile does not enable is omitted silently. All three presets ship off. |
Merge Workflow → Type | direct | pull-request |
direct: Merge direkt auf den Trunk. pull-request: öffnet nur zusammen mit Protected-main: yes einen PR (das [P] des Onboardings setzt beides) — mit Protected-main: no landet ein Slice wie bei direct.
direct: merge straight to trunk. pull-request: opens a PR only together with Protected-main: yes (onboarding's [P] sets both) — with Protected-main: no a slice lands as with direct. |
Merge Workflow → Protected-main | no | yes |
yes + pull-request = „Freigabe ≠ Merge": Merge nur nach echtem GitHub-Approval, nie --admin. yes zusammen mit direct ändert nichts.
yes + pull-request = "approval ≠ merge": merge only after a real GitHub approval, never --admin. yes together with direct changes nothing. |
Merge Workflow → Approval | chat | github-pr-review |
Wird derzeit von keinem Command gelesen, nur von /craft:prime validiert: Unter dem Protected-main-Gate ist ein GitHub-PR-Review ohnehin vorausgesetzt. Das Onboarding setzt github-pr-review mit [P], chat mit [D].
Currently read by no command, only validated by /craft:prime: under the protected-main gate a GitHub PR review is implied anyway. Onboarding sets github-pr-review with [P], chat with [D]. |
Merge Workflow → Approval-granularity | auto | per-slice | per-epic |
Implementiert ist nur auto: sequenzieller Epic → ein PR pro Slice; paralleler Epic/Einzel-Slice → ein PR am Ende. per-slice und per-epic validiert /craft:prime, umgesetzt sind sie derzeit nicht — gelandet wird wie bei auto.
Only auto is implemented: sequential epic → one PR per slice; parallel epic / lone slice → one PR at the end. per-slice and per-epic are validated by /craft:prime but currently not implemented — landing follows auto. |
Epic Mode → Default | parallel | sequential |
Siehe Ausführungsmodi. --autopilot geht seinen eigenen Weg, egal was hier steht.See execution modes. --autopilot runs its own path, whatever this says. |
Slice Flow → Mode | auto | manual |
auto: ein interaktiver Slice wandert von selbst von Phase zu Phase, bis einschließlich des Commits, und hält nur für menschliche Klicks an (flow-state.sh entscheidet; im Zweifel Stopp). manual: ein Command pro Phase, am Ende Recommended next: (Preset careful). Ein ungültiger Wert stoppt den Flow; /craft:prime warnt. Bei auto endet /craft:plan mit dem Klick Build now / Later. Außer für Klicks hält der Flow bei committed, blocked, paused, awaiting-release, awaiting-approval, bei no-progress (eine Phase endete, wo sie begann) und bei einem Pause-Wunsch — das Pause-Wort (pause, pausieren, /craft:pause) wirkt in beiden Modi. /craft:execute und der Autopilot bleiben unberührt.
auto: an interactive slice moves from phase to phase by itself, up to and including the commit, and stops only for human clicks (flow-state.sh decides; in doubt it stops). manual: one command per phase, each ending with Recommended next: (the careful preset). An invalid value stops the flow; /craft:prime warns. With auto, /craft:plan ends with a Build now / Later click. Besides clicks the flow stops at committed, blocked, paused, awaiting-release, awaiting-approval, on no-progress (a phase ended where it began) and on a pause request — the pause word (pause, pausieren, /craft:pause) works in both modes. /craft:execute and the autopilot are unaffected. |
Permissions → Scope | minimal | standard | broad |
Reine Dokumentation: hält fest, welche read-only-Allowlist das Onboarding einmal in .claude/settings.local.json geschrieben hat. Kein anderer Command gleicht sie ab — das Feld später zu ändern bewirkt nichts. minimal: git status/diff/log, ls · standard: + cat, grep, git show, gh pr view/list · broad: + wc, head, tail, git blame, gh issue view, gh run view. Nie ein mutierendes Kommando; find ist bewusst ausgeschlossen.
Documentation only: records which read-only allowlist onboarding wrote, once, to .claude/settings.local.json. No other command re-syncs it — changing the field later does nothing. minimal: git status/diff/log, ls · standard: + cat, grep, git show, gh pr view/list · broad: + wc, head, tail, git blame, gh issue view, gh run view. Never a mutating command; find is deliberately excluded. |
Autopilot → Budget-before-slice / Budget-in-slice / Budget-seven-day | 85 / 95 / 90 (1–100) |
Der Budget-Schutz eines Autopilot-Laufs, in Prozent der Nutzungsfenster deines Plans: kein neuer Slice, wenn 5-Stunden-Nutzung plus Prognose über der ersten Grenze liegt; der Builder hält ab der zweiten an der nächsten Grenze seines Laufs (Sub-Task, Phase, Debug-Versuch); kein weiterer Slice ab der Wochengrenze. Ein Fenster bei 99 % mit Cache-TTL 5m (Overage) stoppt immer. Die Prognose ist der aufgerundete Mittelwert der Δ five_hour der bisher gelandeten Slices, ohne Messwert 0. Ein ungültiger Wert fällt auf den Default zurück und wird von /craft:prime gemeldet; ein unbekannter Schlüssel ergibt nur eine Warnung. Ohne Messwert im Tap — kein Statusline-Tap, Tap unlesbar, älter als 300 s, ohne rate_limits oder von vor einem Fenster-Reset — zählt der letzte Messwert, den der Tap aufbewahrt hat, gegen Budget-estimated (nächste Zeile). Gibt es auch den nicht, gilt der konservative Modus: der Slice startet noch, danach stoppt der Lauf, also nach jedem Slice. /craft:prime (Schritt 4h) bietet an, den Tap nach deinem Ja einzutragen. Das Onboarding fragt diese Schlüssel nicht ab; das Profil-Template trägt die Defaults.
An autopilot run's budget guard, in percent of your plan's usage windows: no new slice while the 5-hour usage plus the forecast is above the first limit; from the second the builder stops at the next boundary of its spawn (sub-task, phase, debug attempt); no further slice from the weekly limit. A window at 99 % with cache TTL 5m (overage) always stops. The forecast is the rounded-up mean of the landed slices' Δ five_hour, 0 without a sample. An invalid value falls back to the default and is reported by /craft:prime; an unknown key only gives a warning. Without a reading in the tap — no statusline tap, or a tap that is unreadable, older than 300 s, lacks rate_limits or predates a window reset — the last reading the tap kept counts, against Budget-estimated (next row). Without that one too, conservative mode applies: the slice still starts, then the run stops, so it stops after every slice. /craft:prime (step 4h) offers to wire the tap on your yes. Onboarding never asks for these keys; the profile template carries the defaults. |
Autopilot → Budget-estimated | 80 (1–100) |
Die Grenze, wenn der Tap keinen Messwert hat: Alle Sessions schreiben denselben Tap, und eine Session ohne rate_limits (gerade gestartet oder kompaktiert) ersetzt den Messwert einer anderen. Der Tap bewahrt deshalb den letzten Messwert mit beiden Fenstern auf; ist er höchstens 30 Minuten alt und seitdem kein Fenster zurückgesetzt, urteilt der Budget-Schutz damit gegen diese niedrigere Grenze (geschätzter Modus): kein Slice startet, der Builder hält an und der Lauf stoppt nach dem Slice, sobald 5-Stunden-Nutzung (vor einem Slice plus Prognose) sie erreicht. Darunter läuft der Lauf weiter. Sie liegt nie über Budget-before-slice oder Budget-in-slice: eine niedrigere dieser beiden senkt sie mit. Mit einem exakten Messwert gelten die drei Grenzen oben unverändert.
The limit when the tap holds no reading: every session writes the same tap, and a session without rate_limits (just started or compacted) replaces another one's reading. So the tap keeps the last reading that carried both windows; when it is at most 30 minutes old and no window has reset since, the budget guard judges it against this lower limit (estimated mode): no slice starts, the builder stops and the run stops after the slice once the 5-hour usage (plus the forecast, before a slice) reaches it. Below it the run goes on. It is never above Budget-before-slice or Budget-in-slice: a lower one of those lowers it. With an exact reading the three limits above apply unchanged. |
Autopilot → Cache-guard-recache-tokens | 150000 (≥ 1) |
Kein Budget, sondern die Schwelle des Cache-Schutzes: Wartet eine Autopilot-Session auf dich und kommt deine Antwort erst nach Ablauf des Prompt-Caches, blockiert hooks/cache-guard.sh den Prompt mit dem Neustart (/clear, dann /craft:execute <epic> --autopilot), wenn das Neuschreiben mindestens so viele Tokens kostet — darunter ist es billiger als der Neustart. Jeder Halt nennt vorher, bis wann der Cache warm ist. Ein ungültiger Wert fällt auf den Default zurück und wird von /craft:prime gemeldet.
Not a budget but the cache guard's threshold: while an autopilot session waits on you and your answer arrives after the prompt cache expired, hooks/cache-guard.sh blocks the prompt with the restart (/clear, then /craft:execute <epic> --autopilot) when re-writing the cache would cost at least that many tokens — below it, a cold re-write is cheaper than the restart. Every stop first says until when the cache is warm. An invalid value falls back to the default and is reported by /craft:prime. |
Operational Language | Chat / Commits / Comments | Drei unabhängige Sprachen: Chat (Default: Systemsprache) für die Session, Commits (Default: Englisch) für /craft:commit, Comments (Default: Englisch) für /craft:build//craft:review.
Three independent languages: chat (default: system language) for the session, commits (default: English) for /craft:commit, comments (default: English) for /craft:build//craft:review. |
Agent Model Overrides | <agent>: opus | sonnet | haiku | inherit | fable | <model-id> |
Übersteuert das Frontmatter-Default eines Subagenten: slice-builder (Default sonnet, Tier execute, effort high, Cache-TTL 1h; Phasen 4–7 unter /craft:execute), code-reviewer (Default opus, Tier deep-reason; Phase 8, im Autopilot friert er außerdem das Debug-Protokoll ein), slice-planner (Default opus, Tier deep-reason; Phase 3 im Autopilot), plan-architect (Default opus, Tier deep-reason, effort high; Plan-Review im Autopilot). Die Tiers beschreibt model-defaults.md → Capability Tiers. Alle dialogischen Phasen laufen auf dem Session-Modell. fable ist gültig, aber nur vom Menschen wählbar — CRAFT selektiert es nie selbst, und /craft:prime warnt bei jedem Session-Start, weil es auf Usage-Credits abrechnen kann. Nicht jeder Wert erreicht den Agenten: der Spawn trägt nur eine engere Auswahl; alles andere meldet /craft:prime als wirkungslos und der Agent läuft auf seinem Frontmatter-Modell. Welche Werte ankommen, steht einmal in model-defaults.md → Spawn-Reachable Values.
Overrides a subagent's frontmatter default: slice-builder (default sonnet, tier execute, effort high, cache TTL 1h; phases 4–7 under /craft:execute), code-reviewer (default opus, tier deep-reason; phase 8, and in an autopilot run it also freezes the debug protocol), slice-planner (default opus, tier deep-reason; phase 3 in an autopilot run), plan-architect (default opus, tier deep-reason, effort high; plan review in an autopilot run). The tiers are described in model-defaults.md → Capability Tiers. All dialogic phases run on the session model. fable is valid but human-chosen only — CRAFT never selects it, and /craft:prime warns at every session start because it can bill to usage credits. Not every value reaches the agent: the spawn carries only a narrower set; anything else is reported inert by /craft:prime and the agent runs on its frontmatter model. Which values arrive is stated once, in model-defaults.md → Spawn-Reachable Values. |
Beim Upgrade auf CRAFT 2.0: Ein Profil ohne ## Slice Flow — jedes Projekt von vorher —
läuft als Mode: auto; wer einen Command pro Phase behalten will, ergänzt ## Slice Flow mit
- **Mode:** manual. Ein Profil aus dem bisherigen Template trägt ausdrücklich
Cache-guard-recache-tokens: 100000 und behält den Wert: auf 150000 anheben oder die Zeile
löschen (ein fehlender Schlüssel nimmt den neuen Default).
When upgrading to CRAFT 2.0: a profile without ## Slice Flow — every project from before —
runs as Mode: auto; to keep one command per phase, add ## Slice Flow with
- **Mode:** manual. A profile created from the previous template carries an explicit
Cache-guard-recache-tokens: 100000 and keeps it: raise it to 150000 or delete the line (an
absent key uses the new default).
Optionale Blöcke inOptional blocks in .claude/project/rules.md
| Block | Felder & DefaultsFields & defaults | WirkungEffect |
|---|---|---|
## Personality |
Stack-Pack: <name> | none |
Deklariert das Stack-Pack für die code-nahen Phasen. Auflösung: skills/<name>/ (im Plugin) → ~/.claude/craft-personalities/<name>/ (eigene Packs). Fehlt das Pack: Warnung, nie Abbruch. Das Onboarding erkennt einen Kandidaten an den Manifesten und fragt [C] Confirm / [O] Override / [N] None — nie ein stiller Eintrag.
Declares the stack-pack for the code-near phases. Resolution: skills/<name>/ (plugin-shipped) → ~/.claude/craft-personalities/<name>/ (your own packs). Missing pack: warning, never fatal. Onboarding detects a candidate from the manifests and asks [C] Confirm / [O] Override / [N] None — never written silently. |
## Worktree Settings |
Worktree path pattern: ../<repo>-worktrees/<slice-id>-<slug>/Branch name pattern: <slice-id>-<slug> |
Wo /craft:execute Worktrees anlegt und wie Branches heißen. Beim ersten Lauf trägt es die Worktree-Basis einmal, nach deiner Bestätigung, in permissions.additionalDirectories von .claude/settings.local.json ein.
Where /craft:execute creates worktrees and how branches are named. On its first run it adds the worktree base to permissions.additionalDirectories in .claude/settings.local.json — once, after you confirm. |
## Read-Only Context Sources |
- <absolute-path> pro Quelleper source |
„Connected projects": lesbar, aber schreibgeschützt — ein PreToolUse-Hook verweigert Write, Edit und NotebookEdit auf diese Pfade. Lesbar sind sie erst in permissions.additionalDirectories: das Onboarding fragt nach ihnen, /craft:prime (Schritt 4e) bietet ensure-readonly-context.sh --apply an. Der Ordner research/ im Repo ist immer geschützt.
"Connected projects": readable but write-blocked — a PreToolUse hook denies Write, Edit and NotebookEdit on these paths. They are readable only once in permissions.additionalDirectories: onboarding asks for them, /craft:prime (step 4e) offers ensure-readonly-context.sh --apply. The in-repo research/ folder is always protected. |
## Self-Verification Settings |
Max attempts: 5 · Auto-trigger threshold: 2 · Token brake during loop: 15000 · Stale slice threshold: 7 days · Review in-phase fix cap: 5 |
Stellschrauben für den Debug-Loop, das Auto-Angebot von /craft:debug, die Token-Bremse des Debug-Loops (die 30k-Bremse von Phase 4 ist fest), die Stale-Slice-Warnung von Prime und den Richtwert für In-Phase-Fixes des Reviews — pro Review-Runde, auch im Autopilot (kleine Fixes laufen bis zum Doppelten weiter und nennen, warum sie klein sind).
Knobs for the debug loop, the auto-offer of /craft:debug, the debug loop's token brake (phase 4's 30k brake is fixed), prime's stale-slice warning and review's in-phase fix guide value — per review round, in an autopilot run too (small fixes continue up to twice that and say why each is small). |
## Workflow Rules |
u. a. „Phase 7 entfällt"e.g. "phase 7 is dropped" | Ein Bullet, das Phase 7 als gestrichen erklärt, schaltet das Routing um: Recap übergibt direkt an Review. Der Status-Graph-Harness prüft beide Konfigurationen. A bullet declaring phase 7 dropped flips the routing: recap hands straight to review. The status-graph harness verifies both configurations. |
Die drei Persönlichkeits-EbenenThe three personality tiers
Tier 1 · Senior-Developer
Stack-agnostische Baseline, von /craft:prime einmal geladen, in jeder Phase aktiv:
Qualitäts-Hierarchie (Correctness > Tests > Architektur > Wartbarkeit > Performance > Konsistenz),
Workflow-Gates, Test-Disziplin-Matrix, Problem-Playbook.
Stack-agnostic baseline, loaded once by /craft:prime, active in every phase:
quality hierarchy (correctness > tests > architecture > maintainability > performance > consistency),
workflow gates, test-discipline matrix, problem playbook.
Tier 2 · Stack-Pack
Sprach- und Framework-Idiome. Mit dem Plugin kommen stack-php (PHP 8.4 / 8.5 ohne Framework + Composer + PHPUnit + PHPStan), stack-php-symfony (Symfony 8.1 mit 7.4 LTS + Doctrine + Messenger + Twig + PHPUnit), stack-php-api-platform (API Platform 5.0 auf Symfony + Provider/Processor + Filter + Hydra/OpenAPI + ApiTestCase), stack-php-shopware6 (Shopware 6.7 mit 6.6 + Plugins + DAL + Apps + Storefront/Admin + PHPUnit/Jest/Playwright), stack-php-shopware5 (Shopware 5.7, End-of-Life: Wartung ohne Upstream-Patches + Plugins 5.2+ und Legacy + Smarty + ExtJS/REST-API + PHPUnit 9.6), stack-php-laravel (PHP 8.4 / 8.5 + Laravel 12 + Filament + Pest), stack-python (Python 3.11 bis 3.15 ohne Web-Framework + uv + Ruff + mypy + pytest), stack-ts (TypeScript 7 auf Node ohne Frontend-Framework + ESM + npm + ESLint + Prettier + Vitest) und stack-bash (Bash 5 + set -euo pipefail mit Fallstricken + POSIX-sh- und macOS-3.2-Portabilität + ShellCheck + shfmt + bats-core).
Nur in den code-nahen Phasen geladen (Build, Test, Refactor, Review). Weitere Packs liegen als eigene unter
~/.claude/craft-personalities/ — die Vorlage templates/stack-pack/ im Plugin zeigt die Form, und jedes
Pack nennt in ## Sources, worauf es beruht und von wann es ist.
Language and framework idioms. The plugin ships stack-php (PHP 8.4 / 8.5 without a framework + Composer + PHPUnit + PHPStan), stack-php-symfony (Symfony 8.1 with the 7.4 LTS differences + Doctrine + Messenger + Twig + PHPUnit), stack-php-api-platform (API Platform 5.0 on Symfony + providers / processors + filters + Hydra / OpenAPI + ApiTestCase), stack-php-shopware6 (Shopware 6.7 with the 6.6 differences + plugins + DAL + apps + Storefront / Administration + PHPUnit / Jest / Playwright), stack-php-shopware5 (Shopware 5.7, end-of-life: maintenance without upstream patches + 5.2+ and legacy plugins + Smarty + ExtJS / REST API + PHPUnit 9.6), stack-php-laravel (PHP 8.4 / 8.5 + Laravel 12 + Filament + Pest), stack-python (Python 3.11 to 3.15 without a web framework + uv + Ruff + mypy + pytest), stack-ts (TypeScript 7 on Node without a frontend framework + ESM + npm + ESLint + Prettier + Vitest) and stack-bash (Bash 5 + set -euo pipefail and its pitfalls + POSIX sh and macOS 3.2 portability + ShellCheck + shfmt + bats-core).
Loaded only in the code-near phases (build, test, refactor, review). Further packs are your own, under
~/.claude/craft-personalities/ — the template templates/stack-pack/ in the plugin shows the shape, and every
pack states in ## Sources what it rests on and how old it is.
Tier 3 · Projekt-OverlayProject overlay
Die eigenen Konventionen des Projekts: rules.md (Code Conventions, Tabus,
exakte Tool-Kommandos) + intent.md. Stack-Packs verweisen bewusst hierher — immer wirksam.
The project's own conventions: rules.md (code conventions, taboos, exact tool
commands) + intent.md. Stack-packs explicitly defer here — always in effect.
Das Wissensmodell — „Chat ist kein Speicher"The knowledge model — "chat is not storage"
CRAFT trennt drei Wissensschichten mit unterschiedlicher Ground Truth. Alles Bleibende wird
im selben Zug, in dem es entsteht, in seine dauerhafte Heimat geschrieben — denn Kontext stirbt bei
/clear, Compaction und Session-Ende:
CRAFT separates three knowledge layers with distinct ground truth. Anything lasting is written
to its durable home in the same turn it is produced — because context dies on /clear,
compaction and session end:
| SchichtLayer | InhaltContent | Ground Truth | ZuhauseHome |
|---|---|---|---|
| State | Was heute existiertWhat exists today | Code, Git, ConfigsCode, git, configs | nicht dupliziert — bei Bedarf gelesennot duplicated — read on demand |
| Intent | Was wir wollen & warumWhat we want & why | vom Menschen verfassthuman-authored | intent.md |
| Rules | Wie wir bauen, immerHow we build, always | gegen State verifizierbarverifiable against State | rules.md |
Routing für bleibende Erkenntnisse: Warum → intent.md · Wie → rules.md ·
Langfrist-Phasen → roadmap.md · Slice-Entscheidungen → Slice-Archiv · Epic-Entscheidungen →
Epic-Plan · Querschnitts-Design (Domänenmodell, Szenario-Kataloge) → design/*.md.
Nach Phase 9 lebt das Gedächtnis in drei Orten: Code, Commits (mit Slice:-Footer) und dem
Slice-Archiv — dem Decision Log.
Routing for lasting insight: why → intent.md · how → rules.md ·
long-term phases → roadmap.md · slice decisions → slice archive · epic decisions → epic plan ·
cross-cutting design (domain model, scenario catalogs) → design/*.md.
After phase 9, memory lives in three places: code, commits (with Slice: footers) and the
slice archive — the decision log.
your-project/
├── CLAUDE.md # schlanker Index auf alles Untereslim index pointing at everything below
├── .gitignore # + Block „# CRAFT local state" (Onboard / Prime 4f)+ a "# CRAFT local state" block (onboard / prime 4f)
├── .claude/
│ ├── project/ # DAUERHAFT — versioniertDURABLE — version-controlled
│ │ ├── intent.md # Warum: Vision, Ziele, Entscheidungen (≤ ~80 Zeilen)why: vision, goals, decisions (≤ ~80 lines)
│ │ ├── rules.md # Wie: Stack, Konventionen, Tabus (≤ ~80 Zeilen)how: stack, conventions, taboos (≤ ~80 lines)
│ │ ├── craft-profile.md # Betriebsprofil (Presets & Stellschrauben)operating profile (presets & knobs)
│ │ ├── roadmap.md # optional: Backlog jenseits des Kernsoptional: backlog beyond the core
│ │ ├── design/ # Querschnitts-Designwissen, on demandcross-cutting design knowledge, on demand
│ │ └── slices/ # Archiv abgeschlossener Slices = Decision Logarchive of completed slices = decision log
│ ├── plans/ # EPHEMER — lebt nur solange ein Slice offen istEPHEMERAL — lives only while a slice is open
│ │ ├── slice-001-user-login.md # aktiver Plan — trägt das Status-Tokenactive plan — carries the status token
│ │ ├── epic-001-onboarding.md # Epic-Plan (epic-<NNN>-<slug>.md): Vision, Slice-Zerlegung, Autopilot-Logepic plan (epic-<NNN>-<slug>.md): vision, slice decomposition, autopilot log
│ │ ├── .next-id · .next-epic-id # ID-Zähler (getrennte Räume)ID counters (independent spaces)
│ │ ├── .primed # lokal: Session-Marker — Prime schreibt ihn, der SessionStart-Hook löscht ihnlocal: session marker — written by prime, cleared by the SessionStart hook
│ │ ├── .hook-env # lokal: die bash, mit der der Hook lief (Prime vergleicht)local: the bash the hook ran with (prime compares)
│ │ ├── .execute.lock # lokal: Run-Lock, nie gelöscht — held / releasedlocal: run lock, never removed — held / released
│ │ ├── .cache-guard # lokal: Marker des Cache-Schutzes — nie gelöscht, armed / disarmedlocal: the cache guard's marker — never removed, armed / disarmed
│ │ ├── .pause-request # lokal: Pause-Wunsch (beide Flow-Modi) — nie gelöscht, requested / consumedlocal: the pause request (both flow modes) — never removed, requested / consumed
│ │ └── .closed/ # lokal: geschlossene Pläne, wenn Löschen verboten ist oder nachfragt — nicht gelesenlocal: closed plans when removal is denied or asks — never read
│ ├── skills/ # projekt-lokale Spezialisten, lazy geladenproject-local specialists, lazy-loaded
│ └── settings.local.json # lokal: Allowlist + Worktree-Trustlocal: allowlist + worktree trust
├── .craft/tmp/ # lokal: die einzige Ablage des Autopilot-Masters für eigene Dateienlocal: the autopilot master's only place for its own files
└── research/ # immer schreibgeschützt (PreToolUse-Hook)always write-protected (PreToolUse hook)
../your-project-worktrees/ # Worktrees liegen außerhalb des Repos (/craft:execute)worktrees live outside the repo (/craft:execute)
├── slice-001-user-login/
│ └── .craft/ # lokallocal
│ ├── handoff.md # „Mensch gebraucht" — gilt nur, solange der Plan wartet"human needed" — counts only while the plan waits
│ ├── handoff-resolved-<Written>.md # beantwortet, von slice-builder umbenanntanswered, renamed by slice-builder
│ ├── plan-roundtrip # Record der Plan-Übergabe in den Worktree und zurückrecord of the plan's hand-in and read-back
│ └── .gitignore # versteckt den Record und sich selbst vor githides the record and itself from git
└── epic-001-onboarding/ # Epic-Worktree (epic-<NNN>-<slug>), sammelt die Slice-Mergesepic worktree (epic-<NNN>-<slug>), collects the slice merges
└── .craft/
├── checkpoints.md # Review-Checkpoints, die schon gezeigt wurdenreview checkpoints already shown
└── .gitignore # versteckt den Record und sich selbst vor githides the record and itself from git
Mit lokal markiert ist CRAFTs Zustand pro Klon — er gehört nie in einen Commit. Ob die
.gitignore des Projekts ihn abdeckt, entscheidet scripts/ensure-gitignore.sh per
git check-ignore; nur Regeln aus den eigenen .gitignore-Dateien zählen, eine persönliche
globale Excludes-Datei nicht (Team und CI haben sie nicht). Fehlende Pfade landen in einem
# CRAFT local state-Block — /craft:onboard schreibt ihn direkt, /craft:prime
(Schritt 4f) bietet ihn an. Ein bewusst wieder freigegebener Pfad (!-Regel) bleibt, wie er ist.
CRAFTs eigene Prüfungen auf einen sauberen Baum zählen diese Dateien ohnehin nicht mit.
Entries marked local are CRAFT's per-clone state — never committed. Whether the
project's .gitignore covers them is decided by scripts/ensure-gitignore.sh via
git check-ignore; only rules from the project's own .gitignore files count, a personal global
excludes file does not (teammates and CI don't have it). Missing paths go into one # CRAFT local state
block — /craft:onboard writes it directly, /craft:prime (step 4f) offers it. A path the
project un-ignores on purpose (! rule) is left as it is. CRAFT's own clean-tree checks do not count these
files either way.
Command-ReferenzCommand reference
24 Commands + 4 Skills für den direkten Aufruf, alle im /craft:-Namensraum
(bewusst — kollidiert nicht mit reservierten Namen wie /plan). Fast alle Commands beginnen mit
dem „Ensure-primed"-Gate: Ist die Session nicht geprimed, läuft /craft:prime automatisch vorweg.
24 commands + 4 user-facing skills, all in the /craft: namespace
(deliberate — no collision with reserved names like /plan). Nearly every command starts with
the "ensure-primed" gate: if the session isn't primed, /craft:prime runs first automatically.
Mit ## Slice Flow → Mode: auto (Default) startet jedes von
/craft:build, /craft:test, /craft:recap, /craft:refactor und
/craft:review am Ende die nächste Phase selbst (Auto flow → /craft:<phase>);
/craft:plan endet mit dem Klick Build now / Later, mit
/craft:commit endet der Flow. Ein beratendes (advisory) /craft:review verkettet nie,
/craft:release hat keinen Flow-Schritt. Mit Mode: manual endet jedes Kommando mit
Recommended next:.
With ## Slice Flow → Mode: auto (the default) each of
/craft:build, /craft:test, /craft:recap, /craft:refactor and
/craft:review starts the next phase itself (Auto flow → /craft:<phase>);
/craft:plan ends with the Build now / Later click, and
/craft:commit ends the flow. An advisory /craft:review never chains, and
/craft:release has no flow step. With Mode: manual each command ends with
Recommended next:.
| Session & NavigationSession & navigation | |
|---|---|
/craft:prime | Session-Start: Tool-Check (inkl. bash ≥ 5.0 und python3), Kontext laden, Drift-Check, Angebot für den Local-State-Block in der .gitignore und für den Statusline-Tap, aktive Slices, Empfehlung. Im CRAFT-Quell-Repo zusätzlich: läuft das Plugin aus dem Working Tree oder einer abweichenden installierten Kopie (per Inhalt verglichen)? Läuft automatisch (SessionStart-Hook).Session start: tool check (incl. bash ≥ 5.0 and python3), context load, drift check, local-state .gitignore and statusline-tap offers, active slices, recommendation. In CRAFT's own source repo also: does the plugin run from the working tree or a diverged installed copy (compared by content)? Auto-runs (SessionStart hook). |
/craft:continue | Liest den Status des aktiven Slice und empfiehlt das nächste Kommando — schreibt nur beim bestätigten Fortsetzen eines pausierten Slice (Schritt 4a stellt Paused-status wieder her); einen blockierten Slice verändert es nie.Reads the active slice's status, recommends the next command — writes only on the confirmed resume of a paused slice (step 4a restores Paused-status); never mutates a blocked slice. |
/craft:status | Leichte Übersicht: Slices, Phasen, Fortschrittsbalken, Blocker, Handoffs. Read-only.Lightweight overview: slices, phases, progress bars, blockers, handoffs. Read-only. |
/craft:checkout | In einen Worktree wechseln (Anleitung) zum Inspizieren während Recap/Review.Switch into a worktree (instructions) for inspection during recap/review. |
| Phasen-KommandosPhase commands | |
/craft:plan | Phase 3 — Slice planen: Trigger / Effekt / Test-Strategie, Sub-Tasks, Plan-Datei; verknüpft einen Epic-Eintrag mit der neuen Slice-ID.Phase 3 — plan a slice: trigger / effect / test strategy, sub-tasks, plan file; links an epic entry to the new slice ID. |
/craft:epic | Multi-Slice-Epic planen: Vision + Zerlegung (≥ 2 Slices), eigener ID-Raum.Plan a multi-slice epic: vision + decomposition (≥ 2 slices), own ID space. |
/craft:build | Phase 4 — implementieren, Sub-Tasks in Reihenfolge, Tests still, Bündel-Meldungen.Phase 4 — implement, sub-tasks in order, tests silent, bundle reports. |
/craft:test | Phase 5 — der Mensch testet: Demo-Setup → Ausprobieren → [W]/[B]/[U].Phase 5 — the human tests: demo setup → exercise → [W]/[B]/[U]. |
/craft:recap | Phase 6 — Was/Warum erklären, Entscheidungen sichern, ggf. Mermaid-Diagramm.Phase 6 — explain what/why, capture decisions, Mermaid diagram if complex. |
/craft:refactor | Phase 7 — max. 2–3 strukturelle Verbesserungen; pro Projekt abschaltbar.Phase 7 — max 2–3 structural improvements; droppable per project. |
/craft:review | Phase 8 — Fresh-Context-Review, Heavy/Light × Local/Rethink, Findings pro Runde, Rundengrenze 3 — je gewährter Extra-Runde (- note · extra round granted: <why>) eine mehr —, Rücksprung nach Phase 4, Commit-Gate; im Autopilot der Ping-Pong-Breaker (Step 9).Phase 8 — fresh-context review, heavy/light × local/rethink, findings per round, a round cap of 3, raised by one per granted extra round (- note · extra round granted: <why>), loop-back to phase 4, commit gate; in an autopilot run the ping-pong breaker (step 9). |
/craft:commit | Phase 9 — atomare Commits, Promotion-Dialog, Archiv (committet es selbst), Plan schließen, ggf. PR-Flow. Deine eigenen uncommitteten Änderungen bleiben unangetastet. Vier Modi: Standard; Slice-finalize merged einen Worktree-Slice, Epic-finalize den Epic-Branch eines parallelen Laufs; Epic-close schließt ein fertiges Epic — nach Merge oder PR eines Autopilot-Laufs, nach einem sequenziellen Lauf oder bei einem Epic, das Slice für Slice von Hand gebaut wurde —, das Epic-Archiv nach templates/epic-archive.md.template, bei geschütztem main in zwei Durchgängen über den offenen Epic-PR oder einen eigenen Close-PR. Auf einem Autopilot-Epic-Branch (Autopilot Mode) entfällt Step 6 und der Plan wird auf dem Epic-Branch geschlossen; ruft a3 es auf, fragt es nichts. Worktrees beurteilt es nur über scripts/worktree-kinds.sh: einer auf keinem Slice- oder Epic-Branch wird in einer ·-Zeile genannt und ignoriert, ebenso genannt wird ein CRAFT-Worktree, der kein Finalize-Ziel ist. A6 liest den erkannten Modus, In-place-finalize richtet sich nach Standard mode plus Start-Branch; scheitert dort der Merge, hält es an, bevor der Plan geschlossen wird.Phase 9 — atomic commits, promotion dialog, archive (committed by itself), plan closing, PR flow if configured. Your own uncommitted changes are left alone. Four modes: Standard; Slice-finalize merges a worktree slice, Epic-finalize a parallel run's epic branch; Epic-close closes a finished epic — after an autopilot run's merge or PR, a sequential run, or an epic worked slice by slice by hand — its epic archive from templates/epic-archive.md.template, under protected main in two passes, through the epic's open PR or a close PR of its own. On an autopilot epic branch (Autopilot Mode) Step 6 is skipped and the plan is closed on the epic branch; run by a3, it asks nothing. It judges worktrees only through scripts/worktree-kinds.sh: one on no slice or epic branch is named in a · line and ignored, and a CRAFT worktree that is no finalize target is named too. A6 reads the detected mode; In-place-finalize keys on Standard mode plus the start branch, and a failing merge there stops before the plan is closed. |
| OrchestrierungOrchestration | |
/craft:execute | Epic/Slice autonom bauen — parallel (Worktrees), in-place oder sequenziell; mit --autopilot ein Epic ohne Halt zwischen den Slices auf seinem Epic-Branch, ungeplante Einträge zuvor von Agents geplant und einmal von dir freigegeben. Ein erneuter Lauf baut auf dem vorherigen auf.Build an epic/slice autonomously — parallel (worktrees), in-place or sequential; with --autopilot an epic on its epic branch with no halt between slices, unplanned entries planned by agents first and approved by you once. A re-run builds on the earlier one. |
/craft:release | In-Place-Halt lösen: „Diff gesehen, weiter zu Phase 5".Lift the in-place halt: "diff reviewed, on to phase 5". |
| Unterbrechungen & ZustandInterrupts & state | |
/craft:pause | Slice pausieren: ein Slice in Arbeit bekommt zuerst die Übergabe (/craft:handoff), dann Notiz + Pause-Record (Paused-status / Paused-since) in den Plan; lehnt einen blockierten Slice ab. Für einen Slice in Arbeit formuliert es die Notiz selbst und zeigt sie. Es ist selbst ein Pause-Wort, aber als Command hält Claude Code es bis zum Ende des laufenden Turns zurück — einen laufenden Flow hält es nicht mitten im Turn an, wie es pause / pausieren tun. Jeder Ausgang räumt eine offene Pause-Anfrage in .claude/plans/.pause-request ab.Pause the slice: a slice in flight gets the handoff first (/craft:handoff), then note + pause record (Paused-status / Paused-since) into the plan; refuses a blocked slice. For a slice in flight it composes the note itself and shows it. It is a pause word itself, but as a command Claude Code holds it until the running turn ends — it cannot stop a running flow mid-turn the way pause / pausieren can. Every exit settles .claude/plans/.pause-request. |
/craft:handoff | Übergabe für frische Session schreiben (Status bleibt).Write a handoff for a fresh session (status unchanged). |
/craft:block / /craft:unblock | Blocker erstklassig erfassen / auflösen ([R]/[P]/[A]), Auto-Resurface via Commit.Record / clear a first-class blocker ([R]/[P]/[A]), auto-resurface via commit. |
/craft:abort | Slice endgültig verwerfen. Ohne Argument wählst du den Slice per Klick (mit Cancel). Jede Warnung ist ein eigener Klick, das Default-No zuerst — ein No beendet den Abbruch; am Ende zwei Klicks als Bestätigung. Zeigt vorher einen offenen Handoff im Worktree. Der Plan wird gelöscht oder, wenn deine Settings das Löschen verbieten oder nachfragen, nach .claude/plans/.closed/ verschoben.Discard a slice for good. With no argument you pick the slice by click (with Cancel). Every warning is a click of its own, the default No first — a No ends the abort; two clicks confirm at the end. Shows an open handoff in the worktree first. The plan is deleted, or moved into .claude/plans/.closed/ when your settings deny or ask on removing it. |
/craft:intent-update | Einziger Weg, intent.md außerhalb von Phase 9 zu ändern — Diff + Bestätigung.The only way to edit intent.md outside phase 9 — diff + confirmation. |
| Worktrees & WartungWorktrees & maintenance | |
/craft:worktree-status / -clean | Worktrees mit lebenden Handoff-Markern auflisten / verwaiste nach Bestätigung entfernen (offener Handoff wird vorher gezeigt).List worktrees with their live handoff markers / remove orphans after confirmation (an open handoff is shown first). |
/craft:onboard | Einmaliges Onboarding — Greenfield oder Migration eines bestehenden .claude/; trägt CRAFTs lokalen Zustand in die .gitignore ein und bietet den Statusline-Tap an.One-time onboarding — greenfield or migration of an existing .claude/; gitignores CRAFT's local state and offers the statusline tap. |
/craft:upgrade | Marketplace-Klon von GitHub synchronisieren; installiert wird per Auto-Update oder /plugin update craft@craft, geladen in einer neuen Session.Sync the marketplace clone from GitHub; installation happens by auto-update or /plugin update craft@craft, loaded in a new session. |
| Skills für den direkten AufrufUser-facing skills | |
/craft | Zustandsbewusster Einstieg: erkennt Onboarding-/Slice-Status, bietet gültige Aktionen an.State-aware entry point: detects onboarding/slice state, offers valid actions. |
/craft:brainstorm / /craft:grill-me | Phase 1 (Ideation) / Phase 2 (Alignment-Interview).Phase 1 (ideation) / phase 2 (alignment interview). |
/craft:debug | Bug-Verifikationsprotokoll ALIGN → PROTOCOL → LOOP → ESCALATION; im Autopilot autonom, beurteilt von verify-run.sh.Bug verification protocol ALIGN → PROTOCOL → LOOP → ESCALATION; autonomous in an autopilot run, judged by verify-run.sh. |
Unter der HaubeUnder the hood
Reines Markdown-PluginPure Markdown plugin
24 Commands, 15 Skills (6 universelle + 9 Stack-Packs), 4 Agents, 5 Hooks — Markdown, JSON und Bash. Kein Build,
kein MCP-Server. Das Repo ist sein eigener Marketplace (marketplace.json mit
source: "./").
24 commands, 15 skills (6 universal + 9 stack-packs), 4 agents, 5 hooks — Markdown, JSON and Bash. No build,
no MCP server. The repo is its own marketplace (marketplace.json with
source: "./").
Hooks
SessionStart: session-start.sh löscht .primed;
in onboardeten Projekten stößt er das Auto-Prime an und hält in .hook-env fest, mit welcher bash
er lief; worktree-handoff-notify.sh zeigt wartende Worktree-Handoffs — nur lebende,
per scripts/handoff-marker-state.sh.
PreToolUse: readonly-context-guard.sh verweigert Write/Edit/NotebookEdit auf
research/ und deklarierte Read-only-Quellen, dazu Read/Grep/Glob und Schreiben in
.claude/plans/.closed/ — mit pfad-normalisierender Traversal-Abwehr,
fail-open bei fehlendem jq.
UserPromptSubmit: cache-guard.sh, der Cache-Schutz des Autopiloten — wartet die Session
auf dich und kommt deine Antwort erst nach Ablauf des Prompt-Caches, blockiert er den Prompt (kein Request, kein
Neuschreiben des ganzen Kontexts) und nennt den Neustart — braucht der Stopp vorher einen Schritt von dir, nennt er
diesen zuerst. Er blockiert nur die Antwort auf seinen eigenen Stopp (eine Session, die danach weiterlief, nicht) und
erst ab Cache-guard-recache-tokens (Standard 150000); Builder-Hand-backs, Task-Notifications, Prompts einer
anderen Session und alles Unklare lässt er durch (fail-open); pause-watch.sh, der Pause-Wunsch des Slice-Flows —
eine Nachricht, die nur pause, pausieren oder /craft:pause lautet und als eigener Prompt kommt, wird bei einem laufenden Slice (in beiden Modi, auto und manual)
in .claude/plans/.pause-request vermerkt (für eine mitten im Zug zugestellte Nachricht feuert er nicht — dann vermerkt der Agent selbst); der Hook gibt nichts aus, blockiert nie und lässt alles Unklare durch.
Hooks bleiben kompatibel mit bash 3.2.
SessionStart: session-start.sh clears .primed;
in onboarded projects it triggers auto-prime and records in .hook-env which bash it ran with; worktree-handoff-notify.sh surfaces pending worktree handoffs — live ones only, via
scripts/handoff-marker-state.sh.
PreToolUse: readonly-context-guard.sh denies Write/Edit/NotebookEdit on
research/ and declared read-only sources, plus Read/Grep/Glob and writes into
.claude/plans/.closed/ — with path-normalizing traversal defense,
fail-open when jq is missing.
UserPromptSubmit: cache-guard.sh, the autopilot's cache guard — while the session waits
on you, a prompt that arrives after the prompt cache expired is blocked (no request, no re-write of the whole
context) and the restart is named — a stop that needs a step from you names that step first. It blocks only the
answer to its own stop (a session that went on after it is not blocked) and only from
Cache-guard-recache-tokens on (default 150000); a builder's hand-back, a task notification, a prompt of another session and
anything unclear pass (fail-open); pause-watch.sh, the slice flow's pause request —
a message that is only pause, pausieren or /craft:pause, sent as a prompt of its own while a slice is in flight (in both modes, auto and manual),
is recorded in .claude/plans/.pause-request (it does not fire for a message delivered mid-turn — then the agent records it itself); the hook prints nothing, never blocks and passes whatever it cannot classify.
Hooks stay bash-3.2-compatible.
Agents
code-reviewer (Opus): klassifiziert nur — hat keine
Write-/Edit-Tools; prüft bei einem Re-Review zuerst die früheren Findings. Seine zweite Rolle im Autopilot:
Protocol Freeze — er friert das Debug-Protokoll ein, das der slice-builder entworfen hat, oder weist es zurück,
an Stelle des Menschen. slice-builder (Sonnet, effort high, Cache-TTL 1h):
führt Phase 4–7 eines Slices im Worktree aus — im Autopilot-Lauf im Haupt-Checkout auf dem Epic-Branch, mit Phase 5
per verify-run.sh, dem autonomen Debug-Loop und dem Budget-Schutz (usage-state.sh --gate during)
an jeder Grenze seines Laufs —, schreibt bei jeder menschenpflichtigen Pause
.craft/handoff.md (mit Episode:), benennt beim Start einen veralteten Marker um,
committet/merged/pusht nie selbst und erfindet nie eine menschliche Antwort. slice-planner (Opus):
plant im Autopilot einen Epic-Eintrag über den Subagent Mode von /craft:plan — mit ID und Pfad, die der
Master vergeben hat; was nur du beantworten kannst, schreibt er als NEEDS-HUMAN: statt zu raten.
plan-architect (Opus, effort high): prüft vor dem Plan-Gate alle offenen Pläne eines Epics als Paket
— Überschneidungen, Verträge, Reihenfolge, Schnittgröße — und klassifiziert nur; die Planner überarbeiten.
code-reviewer (Opus): classifies only — has no Write/Edit tools; on a
re-review it verifies the earlier findings first. Its second role, in the autopilot: Protocol Freeze —
it freezes or rejects the debug protocol the slice-builder drafted, in place of the human.
slice-builder (Sonnet, effort high, cache TTL 1h): runs a slice's phases 4–7 in its worktree —
in an autopilot run in the main checkout on the epic branch, with Phase 5 by verify-run.sh, the
autonomous debug loop and the budget guard (usage-state.sh --gate during) at every boundary of its
spawn —, writes .craft/handoff.md (with its Episode:) on every
human-required pause, renames a stale marker at start, never commits/merges/pushes itself and never
fabricates a human answer. slice-planner (Opus): in an autopilot run, plans one epic entry
through /craft:plan's Subagent Mode — with the ID and path the master allocated; what only you can
answer it writes as NEEDS-HUMAN: instead of guessing. plan-architect (Opus, effort high):
before the plan gate, reviews an epic's open plans as a package — overlaps, contracts, order, sizing — and
classifies only; the planners revise.
Helfer & Selbst-TestsHelpers & self-tests
Entscheidungen, die mehrere Commands teilen, stehen genau einmal in einem Bash-Helfer unter
scripts/ — die Commands rufen ihn auf, statt die Regel nachzuerzählen. Die Harnesses (Tabelle unten)
treiben die Helfer gegen echte Fixtures und sichern Hooks und diese Seite ab; der Status-Graph wird über
maschinenlesbare Marker geprüft, denn Prosa ist nicht prüfbar (ein Grep unterscheidet Gebot nicht von Verbot).
Decisions several commands share live exactly once, in a Bash helper under
scripts/ — commands call it instead of restating the rule. The harnesses (table below) drive
the helpers against real fixtures and keep the hooks and this page honest; the status graph is checked through
machine-readable markers, because prose is not checkable (a grep can't tell prescription from prohibition).
Die Selbst-Test-HarnessesThe self-test harnesses
Harness (scripts/) | Was es absichertWhat it guards |
|---|---|
test-workflow-status-graph.sh | Status-Graph geschlossen unter beiden Phase-7-Konfigurationen; craft:writes/craft:reads-Marker und Tabelle stimmen in beide Richtungen überein; /craft:continue routet jeden Status zum richtigen Konsumenten. Dazu DELEGATION (ein Subagent-Mode-Abschnitt, der eine Regel an seinen interaktiven Zwilling übergibt, trägt das craft:delegates-Token und keinen eigenen Status-Write), DETECTION (die rules.md dieses Projekts erfüllt die kanonische Form der Phase-7-dropped-Regel), SECTIONS (P2 von /craft:plan leitet seine Pflichtabschnitte aus der Slice-Plan-Vorlage ab) und FLOW (die Status → Command-Karte von flow-state.sh --map ist in beide Richtungen an den Graphen gebunden).Status graph closed under both Phase-7 configurations; craft:writes/craft:reads markers and the table agree both ways; /craft:continue routes every status to its consumer. Plus DELEGATION (a Subagent-Mode section that hands a rule to its interactive twin carries the craft:delegates token and no status write of its own), DETECTION (this project's rules.md satisfies the canonical form of the Phase-7-dropped rule), SECTIONS (/craft:plan's P2 derives its required sections from the slice-plan template) and FLOW (the status → command map of flow-state.sh --map is bound to the graph in both directions). |
test-readonly-context.sh | Schreibschutz-Hook inkl. Traversal-Fällen und der Sync-Helfer ensure-readonly-context.sh; Hook und Helfer normalisieren Pfade gleich. Dieser Helfer und ensure-worktree-trust.sh übernehmen das GITIGNORED=-Urteil über die .claude/settings.local.json am Repository-Root aus ensure-gitignore.sh (auch bei einem Projekt im Unterverzeichnis) und schreiben .gitignore nie selbst; die GITIGNORED=no-Zeile in execute.md nennt diese Datei.Write-protection hook incl. traversal cases and the sync helper ensure-readonly-context.sh; hook and helper normalize paths alike. This helper and ensure-worktree-trust.sh take the GITIGNORED= verdict on the repository root's .claude/settings.local.json from ensure-gitignore.sh (also for a project in a subdirectory) and never write .gitignore themselves; execute.md's GITIGNORED=no line names that file. |
test-docs-site.sh | Diese Seite: Version und Zähler im Badge (ein Skill ist ein Verzeichnis mit SKILL.md), jedes vX.Y.Z gleich der Version in plugin.json, diese Harness-Tabelle in beide Richtungen an scripts/test-*.sh gebunden, EN/DE-Parität, Anker, Tag-Balance. Dazu die Release-Doku: CONTRIBUTING.md und CONTRIBUTING.de.md existieren und verlinken einander, README.md verlinkt CONTRIBUTING.md, jeder Listenpunkt unter [Unreleased] und im neuesten Release-Abschnitt des CHANGELOG.md ist eine Zeile — ein Selbsttest auf mutierten Kopien muss rot werden.This page: badge version and counts (a skill is a directory holding SKILL.md), every vX.Y.Z equal to the plugin.json version, this harness table bound to scripts/test-*.sh in both directions, EN/DE parity, anchors, tag balance. Plus the release docs: CONTRIBUTING.md and CONTRIBUTING.de.md exist and link each other, README.md links CONTRIBUTING.md, every list item under CHANGELOG.md's [Unreleased] and its newest release section is one line — a self-test on mutated copies must go red. |
test-plugin-cache-drift.sh | check-plugin-cache-drift.sh: läuft die installierte Kopie oder der Working Tree — per Inhalt, nicht per Version (Prime Schritt 5c).check-plugin-cache-drift.sh: installed copy vs. working tree — by content, not version (prime step 5c). |
test-toolchain-check.sh | check-toolchain.sh: bash ≥ 5.0 und python3, Installationsbefehl je Betriebssystem, die bash des Hooks; die Hooks laufen dabei unter /bin/bash 3.2. Gepinnt: Prime zeigt eine abweichende Hook-bash nur als informative ·-Zeile, nie als ⚠, und der Guard des Status-Graph-Harness stoppt nur für eine zu alte bash, nie für ein fehlendes python3. Dazu: Jeder Hook in hooks/hooks.json ist bash "${CLAUDE_PLUGIN_ROOT}/hooks/<name>.sh" — gequotet, damit ein Plugin-Pfad mit Leerzeichen ihn nicht zerlegt, ohne args (B38) —, und jedes Skript aus hooks/ ist genau einmal registriert; mutierte Kopien müssen rot werden.check-toolchain.sh: bash ≥ 5.0 and python3, per-OS install command, the hook's bash; hooks are run under /bin/bash 3.2. Pinned: prime shows a differing hook bash only as an informational · line, never ⚠, and the status-graph harness's guard stops only for a too-old bash, never for a missing python3. Plus: every hook in hooks/hooks.json is bash "${CLAUDE_PLUGIN_ROOT}/hooks/<name>.sh" — quoted, so a plugin path with a space cannot split it, and without args (B38) — and every script in hooks/ is registered exactly once; mutated copies must go red. |
test-gitignore-sync.sh | ensure-gitignore.sh: Abdeckung des lokalen Zustands, ein Block, Negationen respektiert, globale Excludes zählen nicht.ensure-gitignore.sh: local-state coverage, one block, negations respected, global excludes never count. |
test-handoff-marker-state.sh | handoff-marker-state.sh: lebend/veraltet je Plan-Status und Episode, „im Zweifel lebend", der fail-open-Pfad des Hooks.handoff-marker-state.sh: live/stale per plan status and episode, doubt-means-live, the hook's fail-open path. |
test-review-findings-state.sh | review-findings-state.sh: Runden, Finding-IDs, Auflösungen, offene Zeilen (Review Step 6/7, Commit Step 5), der Ping-Pong-Breaker (TRIP=, Reopens, Rundenlimit).review-findings-state.sh: rounds, finding IDs, resolutions, open lines (review steps 6/7, commit step 5), the ping-pong breaker (TRIP=, reopens, round cap). |
test-execute-resume-state.sh | execute-resume-state.sh (create / reuse / skip / resume / held / conflict) an echten git-Fixtures — der Plan-Guard plan_not_committed gilt nur noch für die Epic-Zeile —, dazu tree-dirt-state.sh samt --scope slice-worktree; --slices-from liest die Slices eines Autopilot-Laufs aus den Epic-Einträgen, statt sie vom Master zu nehmen.execute-resume-state.sh (create / reuse / skip / resume / held / conflict) on real git fixtures — the plan_not_committed guard is epic-line only now —, plus tree-dirt-state.sh incl. its --scope slice-worktree; --slices-from reads an autopilot run's slices off the epic's entries instead of taking them from the master. |
test-plan-roundtrip.sh | Der Plan-Rundweg des parallelen Worktree-Modus (Slice-067, B15): plan-roundtrip.sh kopiert den Plan eines Slices in den neuen Worktree (in), nach dem Commit der Slice-Arbeit zurück in den Haupt-Checkout (back, nur bei Status: committing) und macht die Kopie vor git worktree remove harmlos (release) — ein Protokoll in .craft/plan-roundtrip verhindert, dass etwas Ungelesenes überschrieben wird, und versteckt sich selbst vor git. Echte Worktree-Fixtures vom Hand-in bis zum gemergten Slice und entfernten Worktree, im Root-Projekt mit CRAFT-Block, ohne .craft/-Ignore, ganz ohne .gitignore und im Unterverzeichnis-Projekt mit und ohne Block — auch nach einem Phase-5-Handoff (aufgelöster Marker und .hook-env am Worktree-Root, die release vor git versteckt); dazu die Stellen in execute.md, commit.md und slice-builder.md.The plan round trip of parallel worktree mode (slice-067, B15): plan-roundtrip.sh copies a slice's plan into the new worktree (in), back into the main checkout once the slice work is committed (back, only at Status: committing) and makes the copy harmless before git worktree remove (release) — a record in .craft/plan-roundtrip keeps anything unread from being overwritten and hides itself from git. Real worktree fixtures from the hand-in to a merged slice and a removed worktree, in a root project with the CRAFT block, one without a .craft/ ignore, one without any .gitignore and a subdirectory project with and without the block — also after a Phase-5 handoff (a resolved marker and .hook-env at the worktree root, which release hides from git); plus the sites in execute.md, commit.md and slice-builder.md. |
test-plan-landing.sh | plan-landing.sh close / sync gegen ein Bare-Origin mit simuliertem Merge, inkl. Rollback.plan-landing.sh close / sync against a bare origin with a simulated merge, incl. rollback. |
test-delete-safe.sh | Löschsicheres Schließen (B19): delete-mode.sh erkennt eine deny- oder ask-Regel auf das Entfernen einer Datei (auf jeder Settings-Ebene, am konkreten Befehl), close-file.sh verschiebt dann nach .claude/plans/.closed/ und löscht nie selbst, execute-lock.sh führt den Lock als Zustand; dazu die Lesesperre des Guards (auch unter /bin/bash 3.2), Scanner, die .closed/ nicht sehen, die gebundenen Schließ-Stellen und der Aufräum-Hinweis.Delete-safe closing (B19): delete-mode.sh detects a deny or ask rule on removing a file (on every settings level, against the concrete command), close-file.sh then moves into .claude/plans/.closed/ and never removes anything itself, execute-lock.sh keeps the lock as state; plus the guard's read block (also under /bin/bash 3.2), scanners that do not see .closed/, the bound close sites and the cleanup hint. |
test-verify-run.sh | Autopilot-Verifikation (D35): verify-run.sh führt den <!-- craft:verify -->-Block der Test Strategy aus und schreibt die Evidenz selbst in den Plan; jeder Befehl wird vorher gegen deine deny-/ask-Regeln geprüft (permission-rule-match.sh, geteilt mit delete-mode.sh, erkennt Teilbefehle, Substitutionen und Wrapper) — ein Treffer oder Zweifel, und nichts läuft. Dazu Pass/Fail/kein Block/fehlerhaft, Timeouts, nur angehängte Runden und --only (eine benannte Teilmenge für den Debug-Loop).Autopilot verification (D35): verify-run.sh runs the Test Strategy's <!-- craft:verify --> block and writes the evidence into the plan itself; every command is first judged against your deny / ask rules (permission-rule-match.sh, shared with delete-mode.sh, aware of subcommands, substitutions and wrappers) — a match or doubt, and nothing runs. Plus pass / fail / no block / malformed, timeouts, append-only rounds and --only (a named subset for the debug loop). |
test-plan-gate-state.sh | plan-gate-state.sh: welche Pläne eines Epics noch auf das Plan-Gate des Autopilots warten — abgeleitet aus dem Planned-by:-Marker und der Freigabezeile im ## Autopilot Log, nie gespeichert; fehlerhafte Freigabezeilen geben nichts frei, NEEDS-HUMAN:-Fragen werden gezählt, und aktive Pläne, die kein Epic-Eintrag nennt, werden als ORPHAN gemeldet — der Autopilot fragt dann, bevor er plant. Dazu die Runden des Plan-Reviews (## Plan Review): offene Findings und wie viele automatische Revisionsrunden noch bleiben; eine unlesbare Zeile zählt offen und stoppt die Autonomie.plan-gate-state.sh: which of an epic's plans still await the autopilot's plan gate — derived from the Planned-by: marker and the approval line in the ## Autopilot Log, never stored; a malformed approval line approves nothing, NEEDS-HUMAN: questions are counted, and active plans no epic entry links are reported as ORPHAN — the autopilot then asks before it plans. Plus the plan review's rounds (## Plan Review): open findings and how many autonomous revision rounds are left; an unreadable line counts open and stops the autonomy. |
test-epic-digest.sh | epic-digest.sh: der Digest am Ende eines Autopilot-Laufs, den a5 unverändert weiterreicht — je Slice der erste Satz von ## What, Follow-ups und Phase-7-Kandidaten (nur am Zeilenanfang), dazu das ## UX Demo Script byte-gleich; Fehler sind benannt und geben nie einen halben Digest aus.epic-digest.sh: the autopilot's epic-end digest that a5 relays unchanged — per slice the first sentence of ## What, follow-ups and Phase-7 candidates (at the line start only), then the ## UX Demo Script byte-equal; errors are named and never print a partial digest. |
test-autopilot-log.sh | autopilot-log.sh (Slice-063, B23): jede Zeile im ## Autopilot Log schreibt der Helfer — er liest die Uhr selbst, setzt die Zeile als letzte der Sektion (fehlende Sektion über ## Recap Draft, CRLF, Fences sind keine Überschrift) und prüft, dass sie gelandet ist; der Master reicht nur die ausgegebene Zeile weiter. Dazu das Gate für a1: einen Slice-Schritt (▶/✓ mit Slice-ID) lehnt er ab, solange dieser Aufruf seit dem SINCE= des Locks kein run started geloggt hat. Gepinnt: execute.md schreibt keine Log-Zeile von Hand, nennt .craft/tmp/ als einzigen Ort für eigene Dateien und stoppt a4 bei einem Konflikt vor a5.autopilot-log.sh (slice-063, B23): every line of ## Autopilot Log is written by the helper — it reads the clock itself, places the line as the section's last (a missing section above ## Recap Draft, CRLF, fences are no heading) and checks it landed; the master only relays the printed line. Plus the gate for a1: a slice step (▶/✓ with a slice-ID) is refused until this invocation has logged run started since the lock's SINCE=. Pinned: execute.md writes no log line by hand, names .craft/tmp/ as the only place for its own files, and stops a4 on a conflict before a5. |
test-choice-prompts.sh | Die Klick-Stellen (Slice-076, D40 ergänzt): jede Stelle in commands/*.md und skills/debug/SKILL.md, an der der Mensch wählt, nennt AskUserQuestion selbst, auf einer Zeile mit <!-- craft:choice --> (Menschentest T2: ein Verweis auf die Regel wurde nie befolgt). Der Test prüft den Werkzeugnamen auf der Markerzeile, die Folgefragen-Stellen (Slice-077, D40 ergänzt: <!-- craft:choice sequence --> mit der festen Wendung „in an AskUserQuestion call of its own“ und einer deklarierten Zahl, derzeit /craft:abort), dass ein typed-Marker nur in execute.md im Block eines Cache-Guard-Arms steht (die Guard-Stopps bleiben Text), die je Datei deklarierte Stellenzahl in beide Richtungen und einen Legenden-Scan (zwei Klammer-Großbuchstaben, (Y / …) oder ein senkrechtes Menü mit einem Buchstaben je Zeile ohne Marker darüber schlagen an). Mutationstests auf Kopien (Name entfernt, Marker entfernt, unmarkierte Legende (inline und senkrecht), getippter Marker aus seinem Block, Name auf getippter Zeile, Zahl geändert) müssen rot werden. Bekannte Grenze: eine offene Frage ohne Legende und ohne Marker fängt nur die deklarierte Zahl.The click sites (slice-076, D40 amended): every site in commands/*.md and skills/debug/SKILL.md where the human chooses names AskUserQuestion itself, on a line marked <!-- craft:choice --> (human test T2: a pointer to the rule was never followed). The harness checks the tool name on the marker's line, the sequence sites (slice-077, D40 amended: <!-- craft:choice sequence --> with the fixed phrase “in an AskUserQuestion call of its own” and a declared count, today /craft:abort), that a typed marker sits only in execute.md in the block of a cache-guard arm (the guard's stops stay text), the per-file declared site count in both directions, and a legend scan (two bracketed capitals, (Y / …) or a vertical menu with one letter per line without a marker above them fail). Mutation self-tests on copies (name removed, marker removed, unmarked legend (inline and vertical), a typed marker moved out of its block, the name on a typed line, a count changed) must go red. Known limit: an open question with no legend and no marker is caught only by the declared count. |
test-worktree-kinds.sh | worktree-kinds.sh (Slice-078, B33): welche verknüpften Worktrees CRAFT gehören — ein Branch mit einem slice-<NNN>- oder epic-<NNN>-Token. Ein detached Worktree oder ein fremder Branch zählt nicht mehr: beim Abschluss von epic-005 hielt ein solcher Worktree ein abschließbares Epic aus dem Epic-close-Modus heraus, und unter Protected-main schaltete er A6 ab. Echte git-Fixtures (Slice, Epic, detached, fremder Branch, eigenes Branch-Muster, Token-Grenzen, ein Worktree ohne Verzeichnis, ein Pfad mit Leerzeichen, Aufruf aus einem verknüpften Worktree, Fehler) und Pins: /craft:commit Moduserkennung Schritt 0, 1 und 2 und die ·-Zeile für einen fremden Worktree, /craft:execute P5–P7; A6 (seit Slice-079) und In-place-finalize in Schritt 7 (seit Slice-080, dazu der Start-Branch) lesen den erkannten Modus statt einer Worktree-Zählung, und Schritt 2 nennt jeden CRAFT-Worktree, der kein Finalize-Ziel ist (ein noch laufender Slice ließ sonst einen Standard-Commit auf dem geschützten Trunk landen); das alte „only the main worktree“ steht in keiner der beiden Dateien mehr, auch nicht über einen Zeilenumbruch verteilt. Mutierte Kopien müssen rot werden. Bekannte Grenze: ein Branch-Muster ohne <slice-id> liest sich als fremd.worktree-kinds.sh (slice-078, B33): which linked worktrees are CRAFT's — a branch carrying a slice-<NNN> or epic-<NNN> token. A detached worktree or a foreign branch no longer counts: at the epic-005 close such a worktree kept a closable epic out of Epic-close mode, and under protected main it switched A6 off. Real git fixtures (slice, epic, detached, foreign branch, a custom branch pattern, token boundaries, a worktree without its directory, a path with a space, a run from a linked worktree, errors) and pins: /craft:commit Mode Detection steps 0, 1 and 2 and the · line for a foreign worktree, /craft:execute P5–P7; A6 (since slice-079) and Step 7's In-place-finalize (since slice-080, with the start branch) read the detected mode instead of a worktree count, and step 2 names each CRAFT worktree that is no finalize target (a slice still building let a Standard commit land on the protected trunk otherwise); the old "only the main worktree" is left in neither file, not even wrapped across lines. Mutated copies must go red. Known limit: a branch pattern without <slice-id> reads foreign. |
test-stack-packs.sh | Der Stack-Pack-Vertrag (Slice-083, D43), einmal im Kopf des Harness definiert: jedes skills/stack-*/ hat ein Frontmatter mit name = Verzeichnis, einer Beschreibung und disable-model-invocation: true, die Abschnitte Stack · Existing Projects · Reference Files · Build Order · Anti-Patterns · Sources in dieser Reihenfolge — ## Existing Projects direkt nach ## Stack und mit mindestens einem Eintrag (Slice-092: wie das Pack ältere oder alternative Werkzeuge eines bestehenden Projekts erkennt), die genannten references/-Dateien in beide Richtungen, ein Größenbudget, keine stehengebliebenen {{…}}-Platzhalter und ## Sources mit As of-Datum und Basis (research: jede Quelle mit https-URL). Die Vorlage templates/stack-pack/ wird gegen denselben Vertrag geprüft, und die Senior-Developer-Baseline trägt genau eine mit craft:existing-toolchain markierte Regel: die vorhandene Toolchain eines Projekts geht vor dem Default eines Packs. Dazu die Erkennungstabelle von /craft:onboard: jedes ausgelieferte Pack hat eine Zeile, die spezifischere Signatur kommt vor dem Framework, auf dem sie aufbaut, stack-bash direkt vor none, none zuletzt. Mutierte Kopien müssen rot werden, legitime Änderungen grün bleiben.The stack-pack contract (slice-083, D43), defined once in the harness header: every skills/stack-*/ has frontmatter with name = directory, a description and disable-model-invocation: true, the sections Stack · Existing Projects · Reference Files · Build Order · Anti-Patterns · Sources in this order — ## Existing Projects directly after ## Stack and with at least one entry (slice-092: how the pack recognises an existing project's older or alternative tools), the named references/ files in both directions, a size budget, no leftover {{…}} placeholder and ## Sources with an As of date and a basis (research: every source with an https URL). The template templates/stack-pack/ is checked against the same contract, and the Senior-Developer baseline carries exactly one rule marked craft:existing-toolchain: a project's existing toolchain wins over a pack's default. Plus /craft:onboard's detection table: every shipped pack has a row, the more specific signal precedes the framework it builds on, stack-bash sits directly above none, none comes last. Mutated copies must go red, legitimate edits stay green. |
test-autopilot-briefing.sh | autopilot-briefing.sh (Slice-069, B27): den Briefing-Block zum Start eines Autopilot-Laufs — Titel, Branch, belegter Checkout, die Slice-Reihenfolge, die „Stops for you at“-Zeilen und die Esc-/Resume-Zeile — druckt der Helfer; a1 und das Plan-Gate reichen ihn nur unverändert weiter. Den Zustand eines Slice entscheidet execute-resume-state.sh, nicht der Helfer; die Reihenfolge setzt einen Resume-Slice zuerst, dann die offenen Slices topologisch nach Depends-On, Gleichstand in Zerlegungsreihenfolge. Gepinnt: execute.md a1 ruft den Helfer auf und stoppt bei einem Fehler, das Plan-Gate zeigt eine ⚠-Zeile, s1 nennt den Gleichstand, und keine „Stops for you at“-Zeile steht mehr in execute.md.autopilot-briefing.sh (slice-069, B27): the briefing block at the start of an autopilot run — title, branch, occupied checkout, the slice order, the “Stops for you at” lines and the Esc / resume line — is printed by the helper; a1 and the plan gate only relay it unchanged. A slice’s state is decided by execute-resume-state.sh, not by the helper; the order puts a resume slice first, then the open slices topologically by Depends-On, ties in decomposition order. Pinned: execute.md a1 runs the helper and stops on an error, the plan gate shows a ⚠ line, s1 names the tie-break, and no “Stops for you at” line is left in execute.md. |
test-epic-close-state.sh | epic-close-state.sh (Slice-061/062/068, D37/D38/D39): ob /craft:commit ein Epic jetzt schließen kann — KIND=autopilot: a5 hat mit [Y] in den Trunk gemergt; KIND=sequential (kein Autopilot-Log): kein a5 nötig; beide: jeder Eintrag gelandet, ein Epic-Branch gemergt; echte Git-Fixtures für [N], Stopp vor a5, den PR-Pfad (offener PR, gemergter PR, Branch gelöscht) und closing (der Close-PR ist offen), anderen Trunk, offene Einträge, die Vorfahren-Falle (ein Branch ohne eigene Commits ist kein Merge), Commits nach dem Merge, Zeilen im Fence oder außerhalb des Logs, CRLF und Scan-Modus; dazu die Vorlage templates/epic-archive.md.template (Abschnitte, Frontmatter, kein ## Commits) und die Stellen in commit.md und execute.md (a5 und s5).epic-close-state.sh (slice-061/062/068, D37/D38/D39): whether /craft:commit can close an epic now — KIND=autopilot: a5 merged it into the trunk on [Y]; KIND=sequential (no autopilot log): no a5 needed; both: every entry landed, an epic branch merged; real git fixtures for [N], a stop before a5, the PR path (open PR, merged PR, branch gone) and closing (the close PR is open), another trunk, open entries, the ancestor trap (a branch without own commits is no merge), commits after the merge, lines in a fence or outside the log, CRLF and scan mode; plus the template templates/epic-archive.md.template (sections, frontmatter, no ## Commits) and the sites in commit.md and execute.md (a5 and s5). |
test-flow-state.sh | flow-state.sh (Slice-074, D42): das Urteil des Auto-Flows — jeder Plan-Status × beide Modi (NEXT= / STOP=), Standard auto ohne Profil, Block oder Schlüssel, ungültige Werte (im Zweifel Stopp), die Block-Grenze (Execution → Mode wird nicht gelesen), CRLF, fehlender oder fehlerhafter Plan, --from (eine Phase, die dort endet, wo sie begann, setzt nichts fort), --mode und --map; gepinnt: die Regel einmal in skills/workflow/SKILL.md, der craft:flow-Marker in den Phasen-Commands, „Build now“ in plan.md, Prime, Onboard, Vorlage, Presets und Defaults. Die Status → Command-Karte des Helfers bindet test-workflow-status-graph.sh in beide Richtungen an den Phasen-Graphen.flow-state.sh (slice-074, D42): the auto flow's verdict — every plan status × both modes (NEXT= / STOP=), the default auto without a profile, block or key, invalid values (doubt means stop), the block boundary (Execution → Mode is not read), CRLF, a missing or malformed plan, --from (a phase that ends where it began chains nothing), --mode and --map; pinned: the rule once in skills/workflow/SKILL.md, the craft:flow marker in the phase commands, “Build now” in plan.md, prime, onboard, the template, the presets and the defaults. The helper's status → command map is bound to the phase graph in both directions by test-workflow-status-graph.sh. |
test-pause-watch.sh | Der Pause-Wunsch des Slice-Flows (Slice-075, D42; beide Modi seit Slice-077): der UserPromptSubmit-Hook pause-watch.sh vermerkt eine Nachricht, die genau pause, pausieren oder /craft:pause lautet (getrimmt, Groß-/Kleinschreibung egal; stop, halt, ein Satz mit dem Wort, leer: nichts), in beiden Modi bei einem laufenden Slice; kaputte oder fehlende Payload, nicht schreibbarer Marker: der Prompt läuft durch, ohne Ausgabe und ohne stderr. Dazu pause-request.sh (request / state / consume, der Marker wird nie gelöscht, ein Wunsch vor dem Resume zählt nicht), STOP=pause-requested in flow-state.sh (nur diese Session, lebend, nicht verbraucht), die Registrierung in hooks.json und die Stellen der Regel. Jeder Hook-Fall läuft unter dem aktuellen bash und unter /bin/bash 3.2. Dazu der markierte Pause-Wort-Satz (<!-- craft:pause-word -->: erst request, laufenden Schritt beenden, /craft:handoff, /craft:pause) an sechs deklarierten Stellen und commands/pause.md (Ausstiege, Übergabe-Punkt, Verweis der Regel), zwölf Mutationsfälle. Der Befund (Menschentest T3): der Hook feuerte nicht für eine mitten im Zug zugestellte Nachricht — er deckt nur ein Pause-Wort als eigenen Prompt ab; was der Agent beim Sehen eines Worts tut, zeigt nur der interaktive Test.The slice flow's pause request (slice-075, D42; both modes since slice-077): the UserPromptSubmit hook pause-watch.sh records a message that is exactly pause, pausieren or /craft:pause (trimmed, case-folded; stop, halt, a sentence containing the word, empty: nothing), in both modes with a slice in flight; a malformed or missing payload, an unwritable marker: the prompt passes, silent on stdout and stderr. Plus pause-request.sh (request / state / consume, the marker is never removed, a request from before the resume does not count), STOP=pause-requested in flow-state.sh (this session only, live, not consumed), the registration in hooks.json and the sites of the rule. Every hook case runs under the current bash and under /bin/bash 3.2. Plus the marked pause-word sentence (<!-- craft:pause-word -->: request first, finish the running step, /craft:handoff, /craft:pause) at six declared sites and commands/pause.md (its exits, the handoff bullet, the rule's pointer), twelve mutation fixtures. The finding (human test T3): the hook did not fire for a message delivered mid-turn — it covers only a pause word sent as a prompt of its own; what the agent does on seeing a word only the interactive test shows. |
test-usage-state.sh | Der Budget-Schutz des Autopilots: usage-state.sh entscheidet aus dem Statusline-Tap (statusline-tap.sh, POSIX-sh), ob ein Slice starten (before), innerhalb weiterlaufen (during, der Builder an jeder Grenze seines Laufs: Sub-Task, Phase, Debug-Versuch) oder der Lauf nach einem Slice weitergehen darf (after) — Master und Builder handeln nur auf VERDICT=. Fehlender, veralteter oder kaputter Tap (konservativer Modus), der letzte Messwert, den der Tap aufbewahrt, und der geschätzte Modus gegen Budget-estimated (Slice-093: Alter, Fenster-Reset, 79/80 % in jedem Gate), jede Grenze an ihrer Kante, die feste Overage-Heuristik, Profil-Werte und ungültige Werte, die aus dem Log abgeleitete Prognose, das Δ je Slice, der byte-gleiche Durchreicher und sein Fail-open-Pfad, die Aufrufstellen und die an den Helfer gebundenen Profil-Kopien.The autopilot's budget guard: usage-state.sh decides from the statusline tap (statusline-tap.sh, POSIX sh) whether a slice may start (before), go on within (during, the builder at every boundary of its spawn: sub-task, phase, debug attempt) or the run may go on after one (after) — the master and the builder act on VERDICT= only. Missing, stale or broken taps (conservative mode), the last reading the tap keeps and the estimated mode against Budget-estimated (slice-093: age, window reset, 79/80 % in every gate), every limit at its edge, the fixed overage heuristic, profile values and invalid ones, the forecast derived from the log, the per-slice Δ, the byte-equal pass-through and its fail-open path, the call sites and the profile copies bound to the helper. |
test-statusline-wiring.sh | Die Verdrahtung des Statusline-Taps: ensure-statusline-tap.sh trägt den Tap nur nach einem Ja in die statusLine der User-Settings ein (--apply) und nimmt ihn wieder heraus (--remove). Jeder --check-Zustand (fehlt, auf Working Tree oder Cache verdrahtet, ohne refreshInterval, von einer höheren Ebene überschrieben, Tap im Marketplace-Klon noch nicht vorhanden, unlesbar) und dass --check nie schreibt; einfache und zusammengesetzte Befehle (sh -c), erhaltene Schlüssel, Einrückung, Symlink und Dateirechte, das byte-gleiche Backup, Ablehnungen ohne Schreibzugriff, der Hin- und Rückweg, die Wahl des Klons unter mehreren Marketplaces, versteckte und doppelte Taps, ein fehlgeschlagener Schreibvorgang und dass der eingetragene Befehl wirklich wie der ursprüngliche läuft.The statusline tap's wiring: ensure-statusline-tap.sh puts the tap into the user settings' statusLine only on a yes (--apply) and takes it out again (--remove). Every --check state (absent, wired to a working tree or the cache, no refreshInterval, overridden by a higher level, tap not yet in the marketplace clone, unreadable) and that --check never writes; plain and compound commands (sh -c), kept keys, indentation, symlink and file mode, the byte-equal backup, refusals that write nothing, the round trip, the clone chosen among several marketplaces, hidden and double taps, a failed write, and that the wired command really runs like the original. |
test-cache-guard.sh | Der Cache-Schutz des Autopiloten (Slice-060): der UserPromptSubmit-Hook cache-guard.sh blockiert einen Prompt, der nach Ablauf des Prompt-Caches kommt (kein Request), und lässt alles andere durch — scharf nur für die Session, die der Marker nennt; Cache warm, Tap einer anderen Session, fehlend, veraltet oder kaputt, Marker kaputt, kaputte Payload, kein python3, Builder-Hand-back (<agent-message from=), <task-notification>, /clear, Tokens unter der Schwelle; seit Slice-070 eine Session, die nach dem Stopp weiterlief (requests= im Marker, Toleranz 1), und ein action=, das der Neustart als Erstes nennt. Jeder Fall läuft unter dem aktuellen bash und unter /bin/bash 3.2 (Fehlertext auf stderr = rot), dazu der Scharf-/Entschärf-Helfer cache-guard-marker.sh mit der Ablaufzeile, der Profil-Schlüssel samt Warnung, die gebundenen Kopien (Tap-Pfad, Default, Stale-Alter), die Registrierung in hooks.json und die Stellen in execute.md, die scharf bzw. unscharf schalten.The autopilot's cache guard (slice-060): the UserPromptSubmit hook cache-guard.sh blocks a prompt that arrives after the prompt cache expired (no request) and passes everything else — armed only for the session the marker names; cache warm, a tap of another session, missing, stale or broken, a broken marker, a broken payload, no python3, a builder's hand-back (<agent-message from=), <task-notification>, /clear, tokens below the threshold; since slice-070 a session that went on after the stop (requests= in the marker, tolerance 1) and an action= the restart names first. Every case runs under the current bash and under /bin/bash 3.2 (error text on stderr = red), plus the arm / disarm helper cache-guard-marker.sh with the expiry line, the profile key and its warning, the bound copies (tap path, default, stale age), the registration in hooks.json and the sites in execute.md that arm and disarm it. |
test-epic-entry-link.sh | epic-entry-link.sh candidates / link / resolve: idempotente Links, tote IDs neu verknüpft, byte-genaue Schreibvorgänge.epic-entry-link.sh candidates / link / resolve: idempotent links, dead IDs relinked, byte-exact writes. |
test-example-regions.sh | Die Case-Table für example-regions.sh — die eine Antwort auf „ist diese Zeile ein Beispiel statt Inhalt?", die sich jeder Parser der Plan-Dateien teilt (epic-entry-link.sh, review-findings-state.sh, verify-run.sh, usage-state.sh, plan-gate-state.sh, epic-digest.sh, autopilot-log.sh, autopilot-briefing.sh, epic-close-state.sh, flow-state.sh, dazu test-workflow-status-graph.sh, test-model-enum.sh, test-choice-prompts.sh), statt sie je einzeln zu entscheiden. Der Helfer parst die Konstrukte statt sie zu zählen: Fences (verschachtelt, eingerückt, im Blockquote, offen geblieben), mehrzeilige HTML-Kommentarblöcke und <pre> in der einen Bindungsstelle, die kein Markdown ist. Ein einzeiliger HTML-Kommentar ist nie ein Beispiel — CRAFTs Marker sind HTML-Kommentare. Die Tabelle entstand vor dem Helfer und ist sein Vertrag.The case table for example-regions.sh — the one answer to "is this line an example rather than content?", shared by every parser of the plan files (epic-entry-link.sh, review-findings-state.sh, verify-run.sh, usage-state.sh, plan-gate-state.sh, epic-digest.sh, autopilot-log.sh, autopilot-briefing.sh, epic-close-state.sh, flow-state.sh, plus test-workflow-status-graph.sh, test-model-enum.sh, test-choice-prompts.sh) instead of each deciding it alone. The helper parses the constructs rather than counting them: fenced blocks (nested, indented, blockquoted, left unclosed), multi-line HTML comment blocks, and <pre> in the one binding site that is not Markdown. A single-line HTML comment is never an example, because CRAFT's markers are HTML comments. The table predates the helper and is its contract. |
test-model-enum.sh | Die erlaubten Modellwerte sind genau einmal deklariert (model-defaults.md); jede markierte Kopie in den Templates und auf dieser Seite wird in beide Richtungen dagegen geprüft, mit einer erwarteten Anzahl Bindungsstellen pro Datei, damit ein entfernter Marker laut wird statt still. Dazu: kein ausgelieferter Agent wählt fable, und die Agent-Frontmatter folgt der Cache-TTL-Regel; jeder Agent in agents/ wird gegen beide Tabellen geprüft, die sein Modell beschreiben (die Schleife läuft über das Verzeichnis, ein neuer Agent ohne Tier-Zeile wird rot). Eine zweite Deklaration ist ebenfalls gebunden: ## Spawn-Reachable Values, die Werte, die ein Spawn-Parameter tragen kann und die drei Commands zur Laufzeit lesen — über eine deklarierte Anzahl, die Teilmenge der erlaubten Werte und die Präsenz von Regel und Überschrift. Die Liste der gebundenen Dateien ist selbst gebunden: ein Baum-Scan lässt jede markierte, aber nicht gelistete Datei rot werden. 57 Mutationsfälle müssen rot werden, 3 legitime Änderungen grün bleiben. Der Grund steht im Namen des Falls, nicht im Prüfergebnis: der Lauf vergleicht den Exit-Status, nicht die Meldung.The allowed model values are declared exactly once (model-defaults.md); every marked copy in the templates and on this page is checked against it in both directions, with an expected binding-site count per file so a removed marker becomes loud rather than silent. Plus: no shipped agent selects fable, and the agent frontmatter follows the cache-TTL rule; every agent in agents/ is checked against both tables that describe its model (the loop runs over the directory, so a new agent without a tier row goes red). A second declaration is bound too: ## Spawn-Reachable Values, the values a spawn parameter can carry, which three commands read at run time — by a declared value count, a subset relation to the enum and the presence of its rule and heading. The list of bound files is itself bound: a tree-wide scan fails any marked file the list does not name. 57 mutation cases must go red and 3 legitimate edits must stay green. The reason lives in each case's label, not in what the run checks: it compares exit status, not the message. |
Begleitwerkzeuge (Pflicht, eines empfohlen)Companion tools (required, one recommended)
| Tool | Wofür CRAFT es brauchtWhat CRAFT needs it for |
|---|---|
context-mode | Kontextfenster-Schutz: große Ausgaben laufen in einer Sandbox, nur Ergebnisse gelangen in die Konversation. Spart aktiv große Token-Mengen und macht deutlich längere Sessions möglich — der 9-Phasen-Loop in einem Rutsch lebt davon (siehe Kontext-Hygiene).Context-window protection: large outputs run in a sandbox, only derived answers enter the conversation. Actively saves large amounts of tokens and enables much longer sessions — running the 9-phase loop in one go depends on it (see context hygiene). |
agent-browser | Browser-Automatisierung für Hands-on-Verifikation (Phase 5) — ein externes CLI, kein ausgelieferter Skill; /craft:prime prüft es auf dem PATH (command -v).Browser automation for hands-on verification (phase 5) — an external CLI, not a shipped skill; /craft:prime checks it on PATH (command -v). |
git | Worktrees, Branches, das gesamte Ausführungs- und Commit-Modell.Worktrees, branches, the whole execution and commit model. |
gh | PR-Landing im Protected-main-Profil (öffnen + mergen nur nach Approval).PR landing under the protected-main profile (open + merge only after approval). |
bash ≥ 5.0 | Mindest-Laufzeit der Skripte unter scripts/, definiert in scripts/check-toolchain.sh. Die Hooks und die Helfer, die sie aufrufen, bleiben bash-3.2-kompatibel — nur so können sie eine zu alte bash überhaupt melden.Minimum runtime for the scripts under scripts/, defined once in scripts/check-toolchain.sh. The hooks and the helpers they call stay bash-3.2-compatible — only that way can they report an old bash at all. |
python3 | Von den Hilfsskripten genutzt (z. B. zum Lesen und Schreiben der Settings-JSON). Auch beide UserPromptSubmit-Hooks lesen ihre Payload damit und lassen ohne python3 alles durch: der Cache-Schutz blockiert dann nie, und der Hook vermerkt kein Pause-Wort.Used by the helper scripts (e.g. to read and write the settings JSON). Both UserPromptSubmit hooks read their payload with it too and fail open without it: the cache guard then never blocks, and the hook records no pause word. |
context7 | Empfohlen, nicht Pflicht — /craft:prime prüft es nicht. Liefert aktuelle Library-, Framework- und SDK-Doku per MCP und hilft in Phase 3 und 4 gegen erfundene API-Aufrufe.Recommended, not required — /craft:prime does not check it. Fetches current library, framework and SDK docs via MCP and helps against hallucinated API calls in phases 3 and 4. |
Upgrade-Modell: /craft:upgrade synct nur den Marketplace-Klon
(~/.claude/plugins/marketplaces/…) — die Installation in den Plugin-Cache (ein Verzeichnis pro Version)
übernimmt Claude Code. Der Schlüssel dafür ist die version in plugin.json: Ist sie schon
installiert, wird nichts aktualisiert — neue Plugin-Stände erreichen Nutzer nur über ein Release mit höherer Version.
Ist Auto-Update für den Marketplace aktiv, lädt Claude Code die neue Version nach dem Session-Start im Hintergrund;
ohne Auto-Update installiert /plugin update craft@craft (CLI: claude plugin update craft@craft) sie.
Die laufende Session behält die geladene — Commands und Agents der neuen Version gibt es erst in einer neuen Session.
Wichtig fürs Dogfooding: Die laufende Session führt immer die Cache-Version aus, nicht den Working Tree;
im CRAFT-Quell-Repo meldet /craft:prime (Schritt 5c) die abweichenden Dateien.
Beim Upgrade auf CRAFT 2.0: Ein Profil ohne ## Slice Flow läuft als Mode: auto (wer einen Command
pro Phase behalten will, setzt Mode: manual); ein explizites Cache-guard-recache-tokens: 100000 aus
der 1.8.0-Vorlage bleibt stehen — auf 150000 anheben oder die Zeile löschen; und unter pull-request
+ Protected-main: yes stoppt /craft:commit einen Standard-Commit direkt auf dem Trunk jetzt auch, solange
der Worktree eines anderen Slices existiert — dann über einen eigenen Branch landen.
Upgrade model: /craft:upgrade only syncs the marketplace clone
(~/.claude/plugins/marketplaces/…) — installation into the plugin cache (one directory per version) is
Claude Code's job. Its key is the version in plugin.json: if that version is already
installed, nothing is updated — new plugin content reaches users only through a release with a higher version. With
auto-update enabled for the marketplace, Claude Code fetches the new version in the background after session start;
without auto-update, /plugin update craft@craft (CLI: claude plugin update craft@craft) installs it.
The running session keeps the one it loaded — the new version's commands and agents arrive in a new session.
Dogfooding caveat: a running session always executes the cache version, not the working tree; in CRAFT's own
source repo /craft:prime (step 5c) reports the differing files.
When upgrading to CRAFT 2.0: a profile without ## Slice Flow runs as Mode: auto (set
Mode: manual to keep one command per phase); an explicit Cache-guard-recache-tokens: 100000 from the
1.8.0 template is kept — raise it to 150000 or delete the line; and under pull-request +
Protected-main: yes, /craft:commit now also stops a Standard commit directly on the trunk while another
slice's worktree exists — land it through a branch of its own.