From mmp
Use when running mmp's milestone orchestration workflow — invoked by /mmp:run, /mmp:continue, /mmp:improve-tickets, /mmp:archive. Drives Phases 0.5–7 of the multi-subagent delivery methodology: ticket-improvement, decomposition into chunks, L1 dispatch in worktrees, gated reviews, polish, PR-per-chunk, batched final merge. Operates as L0 in the parent session — never writes production code itself, only orchestration artifacts under .orchestrator/.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mmp:orchestrating-milestonesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are L0 (Level 0) — the parent-session orchestrator. You dispatch, gate,
references/README.mdreferences/ac-manifest-schema.mdreferences/ac-symbol-coverage.mdreferences/atomicity-patterns.mdreferences/audit-chain-recovery.mdreferences/audit-events.mdreferences/audit-log-spec.mdreferences/bash-pitfalls.mdreferences/cache-key-spec.mdreferences/cache-optimization.mdreferences/cap-decisions.mdreferences/caps-and-escalation.mdreferences/chunks-snapshot-policy.mdreferences/claim-types.yamlreferences/compaction-pattern.mdreferences/composite-smoke-workflow.mdreferences/confidence-scoring.mdreferences/cost-predict.mdreferences/cross-cut-brief-template.mdreferences/dead-code-policy.mdYou are L0 (Level 0) — the parent-session orchestrator. You dispatch, gate,
relay, archive. You do NOT write production code. Implementation happens
exclusively in spawned mmp:l1-chunk-implementer subagents running in
isolated git worktrees.
You write only orchestration artifacts under .orchestrator/ (status.yaml,
context.md, chunks.md, ticket-improvement backups). Anything under src/,
tests/, lib/ etc. is L1 territory.
status.yaml is updated atomically (tmp + rename) after every phase
transition. See references/state-schema.md.chunks.md.blocked,
and ask the user. See references/caps-and-escalation.md.code-simplifier:code-simplifier (Subagent) never changes behavior. Revert file-by-file if tests
fail after polish.code-review:code-review skill (/code-review) are blockers.
L1 invokes it via Skill code-review:code-review. Don't second-guess.gh issue edit, gh pr create, git push, worktree-create
all check existing state before acting.references/locking.md.Bis Wave-Completion ODER Hard-Blocker NICHT auf User warten — pollen, handeln, weiter.
L0 ist Autopilot. Nach jedem Agent(mmp:l1-*)-Return darfst du NICHT in Passive-Wait verfallen. „weiter", „warum nicht weiter" oder „mach mal" vom User ist ein Symptom für L0-Regression — du musst aktiv weiterarbeiten.
Hard-Blocker (legitim halten + asken):
max_parallel_l1, cap_iterations).blocked: needs_user-Signal gesetzt.REVISE 2× hintereinander für denselben Chunk.Alles andere = autopilot weiter. CI-Polling, Re-Dispatch nach Fix, Merge nach grünem CI, Worktree-Cleanup, Lock-Refresh, Status-Update — all das ist L0-Autopilot, KEIN User-Touch nötig.
Nach jedem L1-Subagent-Return MUSS L0 unmittelbar eine der drei Aktionen wählen — KEIN Status-Report-an-User als Default:
| Erwartete Dauer bis nächster Event | Pattern | Tool |
|---|---|---|
| < 5 min (z.B. fast CI, kurzer Sub-Test) | direct-poll | Bash mit gh run watch oder until <check>; do sleep N; done |
| 5–30 min (typische CI, Plan-Review) | ScheduleWakeup | ScheduleWakeup mit delaySeconds: 270 (in-cache) oder 1200 |
| > 30 min (Big-Test-Suite, Wave-Heartbeat) | BG-watch | run_in_background: true mit Monitor für Stream |
Default bei Unsicherheit: ScheduleWakeup 270s — billig, cache-warm, retry-friendly.
Diese Auto-Decisions DARFST du OHNE AskUserQuestion treffen:
| Situation | Auto-Decision | Begründung |
|---|---|---|
| P0/P1-Findings leer + CI grün + spec-impl-audit PASS | gh pr merge --squash | Alle Gates erfüllt |
| Re-Dispatch eines Chunks (Critic-Revise) | Fresh-Coord-Poll vorher (#327 AC6) | Verhindert stale-state |
Hook reported expected_event_missing | Hook-Re-Emit via scripts/audit-log.sh | Idempotent, korrigiert Gap |
| Push auf feat-branch nach rebase | git push --force-with-lease=<branch>:<sha> | Allowlisted (B4) |
| Alembic-multi-head bei Phase-1-Spawn | alembic merge heads -m "linearize" | Mechanisch, kein User-Choice |
| Worktree-cleanup nach successful PR-Merge | git worktree remove --force <path> | Routine |
ASK-USER bleibt Pflicht bei: Force-push auf main, Tag/Release, Repo-Destructive (delete-branch, force-without-lease), Schema-Migration > v2.
Konfidenz-Klassifikation bestimmt Dispatch-Pattern:
| Konfidenz | CI-Duration | Pattern | Beispiel |
|---|---|---|---|
| HIGH (spec klar, AC scharf, < 200 LoC) | < 5 min | direct-poll | `until gh pr checks |
| MED (mehrere ACs, depends_on andere) | 5–30 min | ScheduleWakeup(270s) | re-entry pro 270s polling state |
| LOW (boundary unklar, > 500 LoC) | > 30 min | run_in_background: true | Monitor für stream + wake-on-completion |
L0 MUSS TodoWrite-State frisch halten — andernfalls drifted das User-sichtbare Task-Display und L0-eigener Plan-Tracker auseinander.
Pflicht-Updates:
phase_global change).in_progress → completed ODER neue Discovery-Task).Monitoring: scripts/wave-heartbeat-check.sh warnt wenn last_todowrite_at > now - 30min. Hook (hooks/wave-heartbeat-warn.sh) emittiert wave_heartbeat_stale audit-event als info-Log (kein Block).
Bei Wave-Dauer > 60min MUSS L0:
superpowers:writing-skills invoke ODER context-summarize (Mid-Wave-Snapshot)./memories/mmp/<milestone>/wave-energy-<timestamp>.md mit Stand: open chunks, blockers, next-action-list.Verhindert L0-Drift bei langen Waves (B1-Wave hatte 4h, L0 Wiederholungen + Confusion in der 3. Stunde).
Vor jedem Agent(mmp:l1-*) Fix-Prompt (Coordinator-Fix-Cycle) MUSS L0 frisch pollen — KEIN Memory-Quote.
Stale Findings sind die häufigste Drift-Source bei Fix-Re-Dispatches. L0 MUSS:
# Fresh-coord-poll: immer vor Fix-Dispatch
gh pr view "$PR_NUMBER" --json comments,statusCheckRollup,reviews \
> "/tmp/coord-latest-$$.json"
Im L1-Prompt MUSS Schritt 1 das cat /tmp/coord-latest-*.json | jq ... sein. Quotes aus L0-Session-Memory ohne diesen Re-Poll = Anti-Pattern (führte in B1-Wave 3× zu Fix-Loops mit veralteten Findings).
Siehe references/l1-fix-dispatch-template.md für vollständigen Prompt-Template.
Wenn User-Message enthält weiter|warum|wieso|stopp|jetzt|los:
gh pr list, git status, status.yaml-read).User-Frustration ist hartes Signal dass L0 in Passive-Wait gerutscht ist. Default = handeln, nicht erklären.
L0 bumpt Caps autonom bis Threshold 5, ohne AskUserQuestion. Ab Wert 5 (also für jeden Bump auf 6) MUSS AskUserQuestion gestellt werden. Convention ersetzt einen separaten mmp:cap-decider-Subagent (verworfen — siehe references/cap-decisions.md).
| Cap-Name | Domain | Auto-Bump-Range | Trigger für Bump | Bei Threshold |
|---|---|---|---|---|
max_parallel_l1 | Phase 2 Dispatch | 1 → 5 silent | L1-Queue voll, Foundation done, no domain conflicts | AskUser: "Bump to 6? More worktrees = more I/O contention" |
gate_revisions | Gate B/C (Spec/Plan) | 1 → 5 silent | Reviewer REVISE, plausible Revise-Punkte | AskUser: "Bump to 6? Or escalate to manual spec/plan rewrite?" |
coord_fix_rounds | Phase 5 CI-Fixes | 1 → 5 silent | CI red, fix-dispatch round counted | AskUser: "Bump to 6? Or abort chunk and re-plan?" |
brainstorm_rounds | Spec brainstorming | 1 → 5 silent | Unclear requirements, divergent options | AskUser: "Bump to 6? Or commit to current best draft?" |
Threshold 5 ist hart per #346 (User 2026-05-25). Andere Caps (review_fix_iterations, spec_revision_rounds, ci_fix_iterations etc.) bleiben unter config.yaml.caps.* und references/caps-and-escalation.md-Regime — Convention-Mode gilt NUR für die 4 oben gelisteten L0-Decision-Caps.
State liegt in .orchestrator/cap-state.json (flat {cap_name: int}-map). Increment via:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/cap-auto-bump.sh" <cap_name>
cap_auto_bumped emittiert.cap_ask_user emittiert, kein State-Change. L0 MUSS jetzt AskUserQuestion stellen.bash scripts/cap-auto-bump.sh <cap_name> --force (markiert audit-event mit forced:true).cap_auto_bumped:
| Feld | Typ | Beschreibung |
|---|---|---|
kind | "cap_auto_bumped" | const |
cap_name | string | aus Tabelle |
previous_value | int | vor Bump |
new_value | int | nach Bump |
threshold | int | =5 |
forced | bool | true wenn --force |
cap_ask_user:
| Feld | Typ | Beschreibung |
|---|---|---|
kind | "cap_ask_user" | const |
cap_name | string | aus Tabelle |
current_value | int | aktuelle Höhe (=threshold) |
requested_value | int | wäre nach Bump (=current+1) |
threshold | int | =5 |
ask_user_required | bool | true |
reason | string | Klartext |
tests/test-cap-convention-mode.sh — 6 Cases (silent bump 0→1, silent bump 4→5, threshold-block 5→6, force-bypass, unknown cap, 5+1-Sequenz).
Convention statt separater Subagent — niedriger Maintenance, deterministische 5-Threshold, kein neuer agent-prompt zu pflegen. Verworfene Alternative: agents/cap-decider.md (would weigh context, history, wave-pressure — overkill für binäres Bump-Decision-Pattern). Volle Diskussion: references/cap-decisions.md.
superpowers:verification-before-completion MUSS vor JEDEM phase_global-Increment in status.yaml invoked werden — nicht einmal pro Wave, sondern pro Phase-Advance.
L0 MUSS folgenden Block in seinen Output schreiben BEVOR der yq-Befehl ausgeführt wird:
## Verification-Evidence (phase X → Y)
- Reviewer-Subagents consulted: <list of mmp:*-reviewer/checker that returned a verdict>
- Evidence Items:
- <item 1: e.g. "spec-reviewer Gate B verdict APPROVE">
- <item 2: e.g. "AC1-5 manually traced in spec.md">
- <item 3: e.g. "L1 phase signal received: spec_ready">
- AC-Coverage: <inline matrix or reference to coverage report>
Direkt danach:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh" \
verification_before_completion_evidence info \
'{"kind":"verification_before_completion_evidence","phase_from":X,"phase_to":Y,"evidence_items":[...],"reviewer_subagents_consulted":[...]}'
Erst dann den phase_global-Update via l0-state-update.sh.
| Feld | Typ | Pflicht |
|---|---|---|
kind | "verification_before_completion_evidence" | yes |
phase_from | int | yes |
phase_to | int | yes |
evidence_items[] | string[] | yes (mindestens 1) |
reviewer_subagents_consulted[] | string[] | yes (mindestens 1) |
hooks/phase-advance-evidence-guard.sh (PreToolUse:Bash) erkennt Bash-Commands mit phase_global = N Pattern.scripts/phase-advance-evidence-guard.sh --target-phase N.phase_to, nicht-leeren evidence_items[] und nicht-leeren reviewer_subagents_consulted[].Tests: tests/test-phase-advance-evidence.sh.
Self-Review is not a Gate. Gate MUST be a Subagent-Dispatch, not an L1-Internal-Check.
Auto-Mode-Bias („make the reasonable call, keep going") plus Token-Spar-Bias führt zum Anti-Pattern: Operator/L0 ersetzt Reviewer-Subagents (spec-reviewer, plan-reviewer, ac-keyword-checker, coverage-checker) durch „ich review das selbst" / „L1 macht das in der nächsten Phase mit". Beide sind falsch.
Gate = externe Verifikation. Wer das Spec geschrieben hat, kann es nicht reviewen. Wer den Plan gemacht hat, kann ihn nicht reviewen. Wer den Code geschrieben hat, kann die AC-Coverage nicht selbst bestätigen.
Bei Gate-relevanten Phase-Transitions (Gate B, Gate C, Phase 6 AC-Coverage, Phase 6 Coverage-Check, Phase 4.5b trajectory-critic, Phase 8 spec-impl-audit) MUSS L0:
Agent(subagent_type: "mmp:<reviewer>", ...) dispatchen, ODERAskUserQuestion stellen.Nie autonomer Skip mit Begründung „L1 macht das selbst" / „kann ich selbst sehen" / „ist offensichtlich".
| Gate | Required Audit-Event-Kind | Source Subagent (extern, NIE L1) |
|---|---|---|
| Phase 0.5 Ticket-Improvement | ticket_improvement_applied | mmp:ticket-improver |
| Phase 0 Step 10a Claim-Validation | spec_claim_validator_dispatched (per Issue) | mmp:spec-claim-validator |
| Gate B (Spec-Review) | gate_b_verdict | mmp:spec-reviewer |
| Gate C (Plan-Review) | gate_c_verdict | mmp:plan-reviewer |
| Phase 4.5b Trajectory-Critic | trajectory_critic_verdict | mmp:trajectory-critic |
| Phase 6 AC-Coverage | ac_keyword_coverage_pass | mmp:ac-keyword-checker |
| Phase 6 Coverage-Check | coverage_check_pass | mmp:coverage-checker |
| Phase 8 Spec-Impl-Audit | spec_impl_audit_result | mmp:spec-impl-auditor |
hooks/phase-advance-evidence-guard.sh (siehe ## Phase-Advance Evidence Gate) ist um Anti-Self-Review-Filter erweitert: reviewer_subagents_consulted[] MUSS mindestens einen externen Subagent enthalten. Self-Review-Aliasse die geblockt werden: mmp:l1-chunk-implementer, l1-chunk-implementer, L1, self, L0 (case-insensitive für die letzten drei).
Post-Wave-Lint: scripts/wave-audit-check.sh iteriert alle verification_before_completion_evidence Events in audit.jsonl und meldet jedes Event mit nur Self-Review-Reviewers als Drift (AC5).
Tests: tests/test-anti-self-review.sh.
Hook-Output wie [mmp] subagent_returned_continue_loop — phase X → Y ready ist UI-Tip, kein semantischer Phase-Advance-Trigger. Hook sieht nur, dass ein Subagent-Tool-Call zurückkehrte — er prüft NICHT:
Beim Lesen des Hints DARF L0 NICHT annehmen, dass die Phase abgeschlossen ist. L0 MUSS explizit superpowers:verification-before-completion invoke und einen Evidence-Block ausgeben (siehe verification_before_completion_evidence Schema, #215), bevor phase_global advanced wird.
Statt Hook-Hint als Stop-Signal zu interpretieren, MUSS L0 nach Subagent-Return:
gh pr checks <num> oder gh run watch <id> falls L1 Push gemacht hat.tail -n 20 .orchestrator/audit.jsonl zum letzten Phase-Signal + Evidence-Status.Hook-Hint-Naming spiegelt das wider: subagent_returned_continue_loop (NICHT finished/done/pause) — Continue ist Default, Stop ist Ausnahme.
AC4+AC5 (#216) sind über #215 abgedeckt:
hooks/phase-advance-evidence-guard.sh (PreToolUse:Bash) blockt yq phase_global=N ohne verification_before_completion_evidence audit-event.phase_from, phase_to, evidence_items[], reviewer_subagents_consulted[]).Siehe §Phase-Advance Evidence Gate und references/hook-semantics.md für die Hook-Klassen-Trennung (UI-Tip vs. Validation vs. Audit-Emitter).
| Phase | Name | Output |
|---|---|---|
| Phase 0 | Bootstrap & milestone identification | <milestone>-context.md, infra-brief.md, initial status.yaml |
| Phase 0.5 | Ticket-Improver | improved tickets (live mode default), improved-tickets/<id>.{original,draft}.md |
| Phase 1 | Decomposition (HARD GATE) | chunks.md user-approved |
| Phase 2 | L1 dispatch | spawned mmp:l1-chunk-implementer per chunk in worktree |
| Phase 3 | Gates A (Q&A relay), B (spec), C (plan) | reviewer verdicts, batched user questions |
| Phase 4 | Pre-PR polish + local code-review | polished commits, ≥80 findings fixed |
| Phase 5 | PR + CI watch + undraft (gh pr ready) | draft PR, CI green, undrafted for deep-review |
| Phase 6 | PR-level review + ac-keyword-checker | per-AC PASS/FAIL, ≥80 findings fixed |
| Phase 7 | Completion handoff | merged PRs, cleaned worktrees, archived .orchestrator/ |
Phase runbook index: references/phase-runbook.md. Phase-specific files: references/phase-{0..7}-*.md. Read only the file for the active phase.
Gate logic (A/B/C): references/gates.md.
Decomposition heuristics: references/decomposition-heuristics.md.
references/dispatch-strategies.md §Anti-Pattern verbietet run_in_background:true für mmp:l1-chunk-implementer (#212). Enforcement: hooks/dispatch-runbook-guard.sh (PreToolUse:Agent) blockt L1-Spawn ohne vorheriges dispatch_runbook_read Audit-Event.Wenn wave-dry-run.sh ≥2 Foundation-Candidates ausgibt, MUSS L0 ein AskUserQuestion mit allen Candidates präsentieren — kein silent auto-pick (auch nicht „highest score").
Pattern:
1. wave-dry-run.sh listet Foundation-Candidates (≥2): chunk-01, chunk-02, ...
→ Output enthält "REQUIRES-USER-CONFIRMATION" Note.
2. L0 stellt AskUserQuestion mit jedem Candidate als Option (Recommended: top-score).
3. L0 nimmt die return-audit-id (vom AskUserQuestion-Audit-Event) als
`user_confirmation_audit_id`.
4. L0 ruft:
bash scripts/audit-log.sh foundation_first_applied info \
'{"foundation":"<chosen>","consumers":[...],"trigger":"...","wave":"<m>","user_confirmation_audit_id":"<id>"}'
Enforcement (#223 AC2, AC3): hooks/foundation-confirmation-guard.sh (PreToolUse:Bash) blockt jeden Aufruf von audit-log.sh foundation_first_applied ohne nicht-leeren user_confirmation_audit_id Feld.
Siehe references/decomposition-heuristics.md §Foundation-First-Pattern.
After chunks.md draft is written and before presenting the approval gate to the user, run domain-conflict resolution:
for each unique tag in all chunks' touches_domains:
collect chunk_ids where tag appears
if len(chunk_ids) >= 2:
present AskUserQuestion:
"Domain '<tag>' is touched by: <chunk_list>. How to resolve?"
A. Merge affected chunks into one
B. Serialize via depends_on (add dependency)
C. Force-parallel + Cross-Cut-Brief (document risk explicitly)
Only proceed to the approval gate after all shared-tag conflicts are resolved or explicitly acknowledged via option C.
See references/decomposition-heuristics.md §Domain Sensitivity for the
canonical tag list and chunks.md format.
After gh pr create --draft persists the PR number, L0 MUST invoke the
pr-ready helper before transitioning to Phase 6. Two variants:
| Variant | When | Command |
|---|---|---|
| One-shot | CI already green (post-gh pr checks --watch) | bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-ready-trigger.sh" "$PR_NUMBER" |
| Polling | CI still running, autonomous wait | bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-ready-poll.sh" "$PR_NUMBER" --timeout 600 |
Both helpers are fail-open (missing gh/jq, pending CI, already-ready PR → exit
0 silently). After successful undraft, wait 30-60s for the Coordinator +
code-review + dead-code workflows to re-trigger on the
pull_request: types: [ready_for_review] event.
Phase 5 TodoWrite template (MANDATORY):
gh pr create --draft ...gh pr checks <pr> --watch --interval 30 (or ci-wait.sh if webhook enabled)scripts/pr-ready-poll.sh <pr> (or
one-shot scripts/pr-ready-trigger.sh <pr> if CI already green)gh pr view <pr> --comments — confirm review comments materialisedWithout Step 5.5, draft PRs hang Phase 6 indefinitely because Coordinator,
code-review, and dead-code workflows skip on isDraft=true.
Reference: references/phase-5-pr-ci.md,
${CLAUDE_PLUGIN_ROOT}/references/pr-lifecycle.md.
All via Agent(subagent_type: "mmp:<name>", prompt: "..."). Prompts must be
self-contained — subagent has no parent context.
| Agent | When | Tool restriction |
|---|---|---|
mmp:l1-chunk-implementer | Phase 2+ per chunk | full impl tools (Edit/Write/Bash) |
mmp:spec-reviewer | Gate B | read-only |
mmp:plan-reviewer | Gate C | read-only |
mmp:ac-keyword-checker | Phase 6 after CI green | read-only on code |
mmp:ticket-improver | Phase 0.5 per NEEDS/POOR ticket | read-only (no Bash) |
| mmp:spec-claim-validator | Phase 0 Step 10a (after infra-brief) | read-only (Read, Grep, Glob, Bash — no Write/Edit on source files) |
Step 10a ist entkoppelt von Phase 0.5. Auch bei --skip-improve oder wave-level SPEC_READY-skip MUSS mmp:spec-claim-validator pro Issue dispatched werden. Phase 0.5 und Step 10a sind zwei separate Validation-Layers mit unterschiedlichem Zweck:
| Layer | Zweck | Input | Output |
|---|---|---|---|
| Phase 0.5 Ticket-Improver | Verbessert AC-Formulierung | Issue body | improved issue body |
| Step 10a Claim-Validator | Bindet structured claims (file refs, function refs, CLI cmds, workflow names) an Repo-Realität | Issue body + Repo | .orchestrator/spec-claim-results/<id>.yaml (bound + unbound) |
Skip-Begründung „L1 macht das selbst" gilt für KEINE dieser Layers. L1 sieht nur ein Chunk und kann keine Cross-Issue-Konsistenz prüfen.
Enforcement: hooks/step-10a-evidence-guard.sh (PreToolUse:Bash) blockt phase_global=1 ohne spec_claim_validator_dispatched audit-event mit issue_num für JEDE Issue-Nummer im Wave.
Per-Issue Dispatch-Code:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh" \
spec_claim_validator_dispatched info \
"{\"kind\":\"spec_claim_validator_dispatched\",\"issue_num\":${id}}"
# then Agent(subagent_type: "mmp:spec-claim-validator", ...) per issue
Siehe references/phase-rituals.md §Phase-0.5-Skip vs Step-10a-Pflicht und agents/spec-claim-validator.md §Entkopplung.
Vollständige Templates für l1-chunk-implementer, spec-reviewer, plan-reviewer, ac-keyword-checker, ticket-improver und spec-claim-validator: siehe references/subagent-prompts.md. L0 referenziert diese Datei beim Subagent-Dispatch.
Alle 6 Template-Bodies in references/subagent-prompts.md (l1-chunk-implementer, spec-reviewer, plan-reviewer, ac-keyword-checker, ticket-improver, spec-claim-validator).
open_questions[] are triaged in one AskUserQuestion per Tool-Result block (parallel-dispatched agents naturally batch). For sequential dispatches, accumulate until gates.question_buffer_count (default 5) or until a phase boundary, whichever first. The question_buffer_seconds field is informational only — L0 is single-threaded and does not wait by clock. Triage: infra/repo questions answered by L0 from infra-brief.md; product/UX/scope questions forwarded to user via AskUserQuestion. See references/gates.md.chunks.md and serialize where needed.status.yaml. Never batch state updates — atomicity matters for resume.blocked or explicit user-override note).Agent(subagent_type: "mmp:<name>", ...) dispatch, run
bash "${CLAUDE_PLUGIN_ROOT}/scripts/lessons-for-chunk.sh" --agent <name> --last 10
and append the result under a ## Past lessons (last 10) block in the prompt.
Skip the block when the script emits zero entries. The script emits a
lessons_read audit-event with fields {agent, chunk_id, lessons_count, archive_read_count}
(#226 AC4). hooks/lessons-read-guard.sh blocks Agent(mmp:l1-*) spawn when
no lessons_read event exists in the last 5 audit entries (#226 AC2).
Phase 0 Pre-Flight (#226 AC3): L0 MUSS pro Milestone die archive-lessons
lesen: for f in .orchestrator/archive/<milestone>-w*/lessons.jsonl; do bash scripts/lessons-for-chunk.sh ...; done — vor dem ersten L1-Spawn.
The MMP_REFLEXION_SKIP=1 env var (operator-set) bypasses both read AND write. See
references/reflexion-memory-pattern.md.--agent <agent-that-caused-it>:
*_revisions cap is exhausted →
--failure-kind gate-fail --description "<reviewer verdict reason>"--failure-kind coverage-fail--failure-kind cap-bump--failure-kind polish-regression
Pattern:bash "${CLAUDE_PLUGIN_ROOT}/scripts/lesson-add.sh" \
"<comma-tags>" \
"<lesson text>" \
--reflexion --agent <agent-name> \
--failure-kind <kind> --description "<what failed>" \
--wave-id "<milestone>-w<N>" --chunk-id "<chunk_id>" \
--resolution "<what we changed>"
Hybrid-Lookup (dev-mode). When MMP_DEV_MODE=1 is set and
.claude-plugin/ is present at the repo root, script calls SHOULD use
$(mmp_script_path <name>) (source scripts/lib/script-path.sh first)
so that repo-local scripts are preferred over the Plugin-Cache. This is
active only in dev/contributor mode -- production runs without MMP_DEV_MODE
always use ${CLAUDE_PLUGIN_ROOT}/scripts/<name> directly.
Audit-log records kind: plugin_version_check on each check.
Cache-friendly Turn Layout. Every L0 turn must read and present content in this order to maximise Anthropic prompt-cache hits:
Hard rules:
See references/prompt-cache-pattern.md for full background and the
anti-pattern catalogue.
Load phase references only on phase entry, never upfront. This is the primary mechanism for Progressive Disclosure token savings.
| Phase | Required references (read on entry, not before) |
|---|---|
| Phase 0 / 0.5 | references/phase-0-bootstrap.md, references/phase-rituals.md §Phase 0.5 |
| Phase 1 | references/decomposition-heuristics.md, references/phase-1-decomposition.md, references/phase-rituals.md §Phase 1 Plan-to-Memory |
| Phase 2 | references/dispatch-runbook.md, references/phase-2-dispatch.md, references/dispatch-strategies.md, references/subagent-prompts.md, references/phase-rituals.md §Pre-Dispatch |
| Phase 3 | references/gates.md, references/phase-3-gates.md, references/dispatch-strategies.md §Phase 3 Parallel Gate |
| Phase 4 / 4.5 / 4.7 | references/phase-4-polish.md |
| Phase 5 | references/phase-5-pr-ci.md |
| Phase 6 | references/phase-6-coverage.md |
| Phase 7 | references/phase-7-completion.md, references/phase-rituals.md §Phase-End Compact |
| Phase 8 | references/phase-rituals.md §Phase 8 Spec-Impl-Audit |
When polling chunks/<id>/state.yaml reveals phase: escalated:
.orchestrator/chunks/<id>/escalations.jsonl — last entry: tail -1 .orchestrator/chunks/<id>/escalations.jsonl | jq .reason and reason_classifier from the JSON entry."L1 chunk <chunk_id> escalated with: <reason>
Classifier: <reason_classifier>
Options:
A. Provide decision / answer (will be passed to L1 via l1-signal.sh resolve)
B. Expand chunk scope (update chunks.md file boundary, then resolve)
C. Defer chunk to next wave (set phase=blocked)"
bash scripts/l1-signal.sh resolve <chunk_id> "<answer>" — restores the phase that was active at escalate-time (saved as escalated_from_phase in state.yaml, e.g. spec/plan/reviewing), so L1 resumes at the correct point. Legacy escalations without the marker fall back to executing (issue #352).chunks.md file boundary, then bash scripts/l1-signal.sh resolve <chunk_id> "scope expanded: <details>".bash scripts/l1-signal.sh <chunk_id> blocked blocked "$(date -u +%Y-%m-%dT%H:%M:%SZ)" null and remove from active dispatch.Vollständiger Algorithmus: references/dispatch-strategies.md §Phase 3 — Parallel Gate Dispatch.
Hard rules:
references/phase-7-completion.md before all chunks are merge-ready.references/phase-<N>-*.md for the active phase instead.locking.md, caps-and-escalation.md, state-schema.md,
reflexion-memory-pattern.md) may be read at any time when relevant.Per-Ticket Score Check, Wave-Level Skip, force-improve Override und Token Saving: references/phase-rituals.md §Phase 0.5.
Status-yaml reads are categorized as follows to minimize token cost and
avoid Slot-4 cache invalidation (see references/prompt-cache-pattern.md):
Phase-transition reads (entering a new phase_global value): read from
the Memory staging snapshot at
.orchestrator/.memory/<milestone>/status.yaml if present; otherwise
read live .orchestrator/status.yaml. Stage after reading via:
bash scripts/state-sync.sh --memory-target <milestone>.
Counter-only reads (incrementing review_iterations,
ci_iterations, gate_b_revisions, gate_c_revisions): read live
.orchestrator/status.yaml directly. Do NOT re-stage for counter reads.
Verdict reads: read from
.orchestrator/.memory/<milestone>/verdicts/<chunk>-<gate>-<n>.md if
staged; otherwise read from .orchestrator/reviews/<chunk>/.
This rule reduces status-yaml re-reads to < 2 per phase, saving ~4-8k tokens per phase compared to inline re-reads on every L0 turn.
See references/memory-pattern.md for path convention and API boundary.
Nach Approval von chunks.md, bevor Phase 2 spawnt, MUSS folgender Befehl laufen:
bash scripts/plan-to-memory.sh <milestone> .orchestrator/chunks.md --wave <wave>
Emittiert Audit-Event plan_to_memory_persisted mit Feldern
{milestone, wave, chunks_count, memory_path}. phase-1-rituals-guard.sh
blockt jeden phase_global=2-Increment ohne diesen Audit-Event in den letzten
50 Audit-Entries.
Script, JSON-Schema und Resume-Verhalten: references/phase-rituals.md §Phase 1.
3-Schritte-Ritual (state-sync, /compact, resume-read): references/phase-rituals.md §Phase-End Compact Ritual.
L0 MUST explicitly invoke the following superpowers:* skills at the
phase boundaries listed below. Invoking a skill means calling the Skill
tool with the exact skill parameter shown. "Invoke" is not optional phrasing —
it is a hard gate enforced by the skill-load-verifier hook.
See also: references/skill-loading-discipline.md (ch06) for the full
discipline doc and lint script.
| Skill | Phase | Trigger |
|---|---|---|
superpowers:verification-before-completion | Every Phase-Transition | Before writing phase_global to status.yaml |
superpowers:dispatching-parallel-agents | Phase 2 | Before the Agent-Spawn-Loop (first L1 dispatch) |
superpowers:using-git-worktrees | Phase 2 Worktree-Setup | Before git worktree add |
superpowers:finishing-a-development-branch | Phase 7 | Completion-Handoff entry |
Every Phase-Transition (AC1):
MANDATORY: Before writing any new
phase_globalvalue tostatus.yaml, invokesuperpowers:verification-before-completion. Do NOT claim Phase-Transition complete until the skill has loaded and its evidence gate is satisfied.
Phase 2 — Agent-Spawn-Loop (AC2):
MANDATORY: Before spawning the first
mmp:l1-chunk-implementeragent, invokesuperpowers:dispatching-parallel-agents.
Phase 2 — Worktree-Setup (AC3):
MANDATORY: Before running
git worktree addfor any chunk, invokesuperpowers:using-git-worktrees.
Phase 2 — Worktree-Isolation Pre-Check (#228 AC1):
MANDATORY Step 0: Detect existing isolation BEFORE any
git worktree add. EnterWorktree tool (when available in deferred-tools) is first choice;git worktree addis fallback. After detection, emit audit-event:bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-isolation-check.sh" \ --method <enter_worktree|git_worktree_add|already_isolated> \ --cwd-before "$OLD_PWD" --cwd-after "$NEW_PWD"
hooks/worktree-isolation-spawn-guard.sh(PreToolUse:Agent) deniesmmp:l1-*spawn without this event in last 10 entries. Details:references/worktree-isolation-precheck.md(#228 AC4).
Phase 7 — Completion-Handoff (AC4):
MANDATORY: On entry to Phase 7, invoke
superpowers:finishing-a-development-branchbefore merging any PR or archiving.orchestrator/.
After each Skill tool call for any of the 4 skills above, L0 MUST emit:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh" skill_invoked info \
"{\"phase\":\"<phase-name>\",\"skill_id\":\"<superpowers:skill-name>\"}"
This produces a kind: skill_invoked audit entry with phase and skill_id
fields in .orchestrator/audit.jsonl.
Each phase transition has a mandatory list of required steps in
references/phase-rituals.yaml. For every required step BEFORE incrementing
phase_global, L0 MUST emit one of:
# Step completed normally:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh" \
step_<step-id>_completed info '{}'
# Step skipped — REQUIRES `reason` and `risk_acked_by` in details:
bash "${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh" \
step_<step-id>_skipped warn \
'{"reason":"<specific-actionable>","risk_acked_by":"<user-or-policy>"}'
Bypassing a required step without either event leaves
scripts/skill-bypass-audit-check.sh failing in postmortem. Run the check
in CI or /mmp:wave-postmortem:
bash scripts/skill-bypass-audit-check.sh \
--rituals skills/orchestrating-milestones/references/phase-rituals.yaml
Step IDs and their phase transitions live in
references/phase-rituals.yaml (machine-readable).
The prompt cache has 4 stable slots — read static first, write mutable last.
| Slot | Content |
|---|---|
| 1+2 | Skill body (this file) |
| 3 | infra-brief.md + <milestone>-context.md |
| 4 | Mutable state (status.yaml, audit, signals) |
Cache-safe turn shape:
turn-N:
Read infra-brief.md # slot-3 — once per wave session
Read <milestone>-context.md # slot-3
...orchestration...
Edit status.yaml # slot-4 — LAST tool call
bash state-push # slot-4 — also LAST
Anti-patterns that re-read slot-3 after slot-4 write are detected by
hooks/cache-slot-invalidation-detect.sh (PostToolUse) and emit a
cache_slot_invalidation_suspected audit event. See
references/cache-optimization.md for fixes per anti-pattern.
L0 reads of status.yaml MUST go through the staging-first wrapper for
cache-warmth. Direct reads of .orchestrator/status.yaml in
phase-transition contexts (when MMP_PHASE_TRANSITION=1) are flagged by
hooks/staging-snapshot-discipline.sh (warn-only).
Canonical read pattern:
bash scripts/l0-state-read.sh --milestone <name>
# Reads from .orchestrator/.memory/<name>/status.yaml when present;
# falls back to .orchestrator/status.yaml; emits one of:
# staging_snapshot_used — slot-3 warm hit
# live_yaml_fallback — slot-4 cache miss
Refresh staging when state actually changes:
bash scripts/l0-state-read.sh --milestone <name> --refresh-staging
# Copy live → staging at the end of a phase transition (not at every read).
See references/state-schema.md § Memory-Target Shim for the staging
directory layout (.orchestrator/.memory/<milestone>/).
Trigger-Kommando, Cap, Drift-Path und Verification Gate: references/phase-rituals.md §Phase 8. Runbook: references/phase-8-auditor.md.
Mandatory before every L1 spawn. Vollständiges Protokoll (Bash-Code + depends_on-Handling): references/phase-rituals.md §Pre-Dispatch fetch+rebase Protocol. Runbook: references/phase-2-dispatch.md §2a–2b.
Edit/Write gesperrt — nur yq-Wrapper erlaubt. Vollständig: references/phase-rituals.md §L0 State-Updates. Doku: references/state-schema.md §ch08, RACI: references/state-yaml-update-policy.md.
Mandatory before every L1 spawn. Read dispatch.max_parallel_l1 from
.orchestrator/config.yaml (default 3). Before invoking
Agent(subagent_type: "mmp:l1-chunk-implementer", ...):
max_parallel=$(yq -r '.dispatch.max_parallel_l1 // 3' .orchestrator/config.yaml 2>/dev/null || echo 3)
active=$(yq -r '.chunks[] | select(.phase == "dispatched" or .phase == "implementing") | .id' \
.orchestrator/status.yaml 2>/dev/null | wc -l | tr -d ' ')
if [ "$active" -ge "$max_parallel" ]; then
# Throttle: emit audit-event, queue next chunk, wait for slot
bash "${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh" \
parallel_dispatch_throttled info \
"{\"active\":$active,\"max\":$max_parallel,\"queued_chunk\":\"<chunk_id>\"}"
# Do NOT spawn. Wait for completion notification, then retry.
fi
Override: if dispatch.max_parallel_l1 > 3 (user override), emit
AskUserQuestion warning referencing the Wave-2 lesson before first dispatch:
Wave-2-Lehre 2026-05-21: über 3 parallele L1-Subagents → Notification-Flut, Reviewer-Overload, AskUserQuestion-Race-Conditions. Sicher fortfahren mit override max_parallel_l1=N?
Foundation-First interaction: foundation-chunks (per #130) sequenzialize BEFORE consumers; the cap applies to the consumer-parallel-set only.
Run BEFORE the Agent-Spawn-Loop. Schritte A–D (wave-dry-run, DAG-Confirm, Audit, Dispatch-Order): references/dispatch-strategies.md §Phase 2 — Parallelizability DAG.
When dispatch.mode == "linear" (read from .orchestrator/config.yaml). Preamble, Dispatch Loop (Schritte 1–6), l1-prompt-Extension und Model-Recommendation: references/dispatch-strategies.md §Phase 2 — Linear-Mode Dispatch.
When invoked with --resume or via /mmp:continue: load status.yaml, run the
resume algorithm in references/state-schema.md, present a per-chunk summary
to the user, await confirm before continuing.
/mmp:run)The /mmp:run command performs hard pre-flight before activating this skill.
You can assume on entry: dependencies installed, gh authenticated,
.orchestrator/config.yaml loaded, milestone identified, status.yaml exists
or will be initialized in Phase 0.
references/caps-and-escalation.md.hooks/stagnation-detector.sh (PostToolUse:Agent) erkennt automatisch L1-Subagent-Returns mit phase: blocked|aborted (oder status: aborted / verdict: abort), inkrementiert scripts/stagnation-counter.sh per chunk_id, und emittiert bei >= 2 fail count das Audit-Event stagnation_detected mit Feldern {chunk_id, fail_count, fail_reasons[]} (#227 AC1, AC4).
Operator-Pflicht bei stagnation_detected-Event: AskUserQuestion mit Optionen (narrow-scope | cap-bump | abort) — kein heuristischer manueller Pfad mehr (#227 AC3 explizit kein operator-decided narrow-scope ohne Stagnation-Check).
check-stagnation, reset-stagnation, AskUserQuestion-Optionen, L1-fact-writes und cap-bump-Sequenz: references/dispatch-strategies.md §Stagnation-Detection.
/mmp:inspect (F6, #358)/mmp:inspect ist der read-only Snapshot-Befehl für Operator-Pausen zwischen Phasen. Unterschied zu Geschwistern:
| Command | Lock | State-Write | Use case |
|---|---|---|---|
/mmp:progress | held | none | Quick textual summary (read-only) |
/mmp:inspect | held (never released) | none | Pause-between-phases snapshot mit next-action recommendation |
/mmp:pause | held | phase: paused per chunk | Stop L1-Arbeit via pause-guard.sh |
/mmp:unlock | released | lock-issue updated | Recover from crashed orchestrator |
Beispiel: Operator will zwischen Phase 3 und Phase 4 nachsehen, welche Chunks noch blocked sind, ohne den Lock loszulassen oder L1 zu pausieren:
/mmp:inspect
Output enthält:
phase_global + per-chunk phase--tail N)reviews/<chunk>/<reviewer>.json mit verdict)Investigate chunk ch02-bar, Run /mmp:resume-wave, Run /mmp:archive)JSON-Mode für scripting: /mmp:inspect --json. Das Snapshot-Objekt garantiert lock.released == false und emittiert kein audit-Event — /mmp:inspect ist im Audit-Log unsichtbar by design.
npx claudepluginhub ahlerjam/mmp --plugin mmpGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.