plugins/coordinator/skills/dogfood/SKILL.md
Smoke-driven fix-through loop — invoke a newly-built thing (skill, script, pipeline, install process) and fix bugs until it works or gets replanned. Binary outcome only: converge or switch gears.
npx skillsauth add oduffy-delphi/coordinator-claude dogfoodInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Invoke a newly-built thing and exercise it until it works or gets replanned. Dogfooding is binary — either fix it through or switch gears. There is no third path: "log to backlog and keep going" is file-and-defer wearing a dogfood costume.
Distinct from siblings:
/bug-blitz works a known backlog./bug-sweep searches the repo for bugs./dogfood invokes a new thing and exercises it until it works or gets replanned.Announce at start: "Running /dogfood <target> — smoke-driven fix-through loop. Binary outcome: converge or switch gears."
Invoke /dogfood when:
Do NOT invoke /dogfood when:
/bug-blitz for known backlog items./bug-sweep.coordinator:validate.Self-dogfood-first default. When the target is a thing built in repo X, the canonical first invocation is /dogfood in repo X. Cross-repo dogfood is a deliberate follow-up after self-dogfood converges, not a substitute. When invoked with a target that lives in a different repo, the first action is to surface: "Self-dogfood-first default — confirm a self-dogfood pass was attempted in the producing repo before proceeding to cross-repo validation." Require PM acknowledgment to continue.
PM declares tier at invocation (/dogfood <target> [--narrow|--broad|--shakedown]). Default: --narrow.
| Tier | Scope | Budget | Mid-loop PM check |
|------|-------|--------|-------------------|
| --narrow | Single smoke surface — one install, one command, one happy-path sequence. "Does it work?" | Tight. | Only if surface explodes. |
| --broad | Multi-surface happy path. End-to-end flow across multiple commands/skills/agents. Auto-handoffs survive compaction. | Larger. | At budget halfway. |
| --shakedown | Comprehensive coverage matrix. Every tool/surface/path exercised once with realistic input. Requires declared matrix (see Pre-Flight Gate #4). | Largest. | At budget halfway and on PM check-in pause. |
Shakedown is a kind of dogfood, not a separate activity. It composes inward: a shakedown of a multi-tool surface is a broad dogfood across each tool's narrow surface with a coverage-matrix overlay.
Before entering the loop, four preconditions must hold (Gate 4 applies to --shakedown only). If any gate fails, the first deliverable of the dogfood session is to satisfy the precondition, then enter the loop.
The target must be safely re-invocable across iterations. If the target mutates state in a way that makes pass 2 differ from pass 1 for non-bug reasons, fix idempotency first. The fix is in-cone: idempotency is a property of the thing being dogfooded, not an external concern.
The target must emit tagged stdout, exit codes, or a status file that the EM can diff iteration-to-iteration. Naked-stdout streams are forbidden — write a capture-and-classify wrapper as the first deliverable if the target doesn't already produce machine-parseable output.
If the dogfood session is opened from a handoff or carries inherited scope language ("smoke verification only," "no scope expansion," "out of scope: refactor"), the EM surfaces the language to PM and forces disambiguation:
"This phrase invites file-and-defer when bugs surface. Confirm dogfood fix-through posture, not verification-only."
Hardcoded fix-through is the default. PM can override only with explicit reasoning. This gate runs as the first action of every /dogfood invocation, including autonomous runs. Skipping it is not permitted.
--shakedown only)PM declares the coverage matrix at invocation — every tool/surface/path to be exercised, with realistic input specified. Matrix is persisted to tasks/dogfood-<target>-<date>/coverage-matrix.md at session start and checked off iteration-to-iteration.
Without a declared matrix, --shakedown degrades to --broad and the EM surfaces the choice to PM before entering the loop. This gate exists because shakedown's value claim ("every surface exercised") is unfalsifiable without a prior declaration of what "every surface" means.
Out of scope for this run, no exceptions: gh pr merge, gh pr create against main, git push origin main, hibernate / shutdown / power-off, killing other processes, --no-verify / --no-gpg-sign. Do not propose; do not request authorization mid-run. Power-state cues ("late," "overnight," "tired") authorize urgency only — never hibernate or shutdown.
/dogfood is fail-closed-only — it does NOT set COORDINATOR_OVERRIDE_BRANCH=1 and does not run off the active workstream branch under any circumstance. No override mode. If the daily-branch hook blocks an operation, halt and surface to PM. Do not fight the hook.
[Gate 3 — Framing audit. Always first.]
invoke target
→ observe (capture stdout/stderr/exit, file diffs, hook fires, cross-channel consistency)
→ for each observation, classify explicitly into ONE of:
(a) in-cone, fix-now → fix it on this branch, this session
(b) out-of-cone, switch-gears → stop loop; surface to PM with replan ask
(c) surface-and-skip → genuinely out of scope (PM-product call,
externality, architectural rework). Surface
in flight-recorder; do NOT silently drop.
Defer is the rare exception, not the default.
Silent skips are forbidden. Logging to a generic backlog is forbidden.
→ write pass-<N>-modes.json (mandatory — see below)
→ re-invoke target
→ loop check (see Loop Exit)
The bug-revealing-bug cascade is the normal shape. Each fix uncovers the next layer; single-pass "find all bugs" mode is forbidden because the deepest bugs are invisible until shallower ones clear. Expect multiple passes; each pass narrows the remaining surface.
The observe step does not stop at exit code. Cross-channel observation is explicitly required:
When a contradiction surfaces across channels (success exit + warning stderr; status file says ready + no readiness probe firing), the fix is structural — capture in-process truth at decision time, emit one consistent signal — not patching the lying channel. This bug class is invisible to schema tests; only cross-channel reading catches it.
Every observation must be explicitly classified before acting. Log each classification in the flight-recorder.
In-cone — fix-now (default). Mechanical fixes (validator gaps, missing fallbacks, false-success exits, off-by-one, missing flag handling, idempotency gaps, the skill/script/pipeline body itself) are in-scope by definition because the dogfood IS the test. The default question is "is there a real reason this isn't fix-now?" not "do I have permission to fix this?"
In-cone fix surface includes:
bin/ helpersOut-of-cone — switch-gears. When the bug requires architectural rework that the plan author should re-do. A fix would require reversing a load-bearing structural choice in the thing being dogfooded. Loop ends on PM confirm.
Surface-and-skip. Reserved for: bugs requiring PM-level product decisions, externalities (PRs, signing, network), or genuinely-not-this-loop scope. Surface-and-skip is the rare exception, not the conservative move.
Required structured entry format per skip:
{ "category": "pm-product | externality | architectural-rework", "evidence": "<link-or-pointer-to-rationale>" }
Entries land in tasks/dogfood-<target>-<date>/surface-and-skip.md, NOT in tasks/bug-backlog.md. Routing surface-and-skip into the bug-backlog blurs the boundary with /bug-blitz (which works backlog) and undermines the "dogfood does not file remainder" rule.
Skip-ratio threshold: if skip-ratio exceeds 40% over the session, OR >2 consecutive skips occur without an interleaved fix-now, the EM surfaces "is this dogfood the wrong shape?" to PM. These thresholds signal the session has lost fix-through character and should be re-evaluated against switch-gears.
After each pass, the EM writes tasks/dogfood-<target>-<date>/pass-<N>-modes.json — a JSON list of {component, error-class} tuples, one per distinct failure mode observed. Example:
[
{ "component": "block-off-daily-branch.sh", "error-class": "exit-code-mismatch" },
{ "component": "coordinator-safe-commit", "error-class": "scope-overlap-false-positive" }
]
This file is the mechanical switch-gears signal:
{component, error-class} tuples in a single pass → switch-gears is warranted.EM no longer needs to judge subjectively — the JSON is the signal.
Each iteration also appends a tee'd log to tasks/dogfood-<target>-<date>/pass-<N>.log so iterations are diffable and compaction doesn't lose the trail. TaskList is the cross-iteration flight recorder.
Non-negotiable; learned from /bug-blitz Phase 3 remediation. Parallel executors that each call coordinator-safe-commit produce concurrent-commit absorption and scope sweep.
--narrow (no fanout, single-committer): EM commits each fix directly via plain git on the daily branch (SC-DR-008, lessons.md:207) — git add -- <explicit paths> && git commit -m "<subject>" -- <explicit paths>. Each commit carries empirical smoke evidence in the message body — the iteration's stdout/exit/probe transition that proves the fix landed. Smoke-evidence-in-commit is not optional.
--broad and --shakedown (fanout-capable, autonomous): Executors and fix agents are edit-and-report only — no commit, no coordinator-safe-commit invocation. The EM serializes commits at wave gates using a single fused Bash call:
git reset && git add -- <explicit paths from DONE> && git commit -m "<subject>"
Helper invocation is forbidden in executor scope under these tiers. Each commit carries smoke evidence in the body.
--expected-branch applies only on --narrow-mode executor dispatches that commit. Under --broad and --shakedown, executors never commit, so the flag is moot.
Fixes that span languages/files for one bug must ship as one unit; splitting parallelizes the executor at the cost of semantic guarantee.
Switch-gears is a judgment call informed by mechanical signals.
Well-grounded signals:
pass-<N>-modes.json contains ≥3–4 distinct {component, error-class} tuples. The loop has transitioned from "verify a fix" to "discover more bugs."EM proposes switch-gears with reasoning; PM confirms. On switch-gears the loop ends — the dogfood session output is the replan ask, not a converged thing.
Loop ends when ALL THREE of:
Alternative exits:
NOT an exit path:
PM is loop terminator, not loop driver. Once /dogfood is authorized, the EM hardcodes autonomous fix-through posture. Mid-loop "should I continue?" prompts are anti-signal — they burn PM context on operational decisions the EM is empowered to make. PM intervenes to stop or to confirm switch-gears, not to re-authorize each pass.
All per-session artifacts land in tasks/dogfood-<target>-<date>/:
| File | Contents |
|------|----------|
| pass-<N>.log | Tee'd output from each invocation |
| pass-<N>-modes.json | Distinct {component, error-class} tuples (mandatory) |
| surface-and-skip.md | Structured skip entries with category+evidence |
| coverage-matrix.md | (--shakedown only) Declared matrix + check-off state |
Do NOT route surface-and-skip findings to tasks/bug-backlog.md. If PM later decides any item belongs in the backlog, that is a deliberate hand-off, not automatic spillover.
/dogfood --broad and --shakedown are write-capable autonomous tiers. Under autonomous operation:
| Sibling | Boundary |
|---------|----------|
| /bug-blitz | Works tasks/bug-backlog.md. /dogfood does NOT file remainder there — if /dogfood exits via switch-gears, the output is a replan, not a backlog dump. |
| /bug-sweep | Searches the repo for latent bugs (repo-driven). /dogfood invokes a specific thing (invocation-driven). A sweep finds bugs that exist; a dogfood finds bugs that the new thing causes when used. |
| coordinator:validate | Static repo-state pre-flight. Appropriate before the first smoke pass and after the loop ends. Does not substitute for dynamic invocation. |
| /workstream-complete | /dogfood exit emits a workstream-complete-shaped summary (bugs surfaced + commits shipped + filed skips + verdict), but does not invoke /workstream-complete. PM may chain. |
| /learn-lessons | Surfaced doctrine drift is filed to tasks/lessons.md for /learn-lessons triage — out-of-loop, by design. |
## Dogfood Session Complete
**Target:** <target> | **Tier:** --narrow/--broad/--shakedown
**Outcome:** converged | switch-gears | pm-stopped
**Passes run:** N
**Bugs fixed this session:** F items
- [list with commit SHAs and one-line smoke evidence per fix]
**Surface-and-skip (in session flight-recorder):** S items
- [list with category + evidence pointer]
**Verdict:** <converged: thing works | switch-gears: replan ask | stopped: open observation was X>
tools
Orient session — preflight, load context, choose work
documentation
Wrap up finished work — capture lessons, update docs
development
Triangulate plan-claim / code-reality / review oracles to classify each plan into DELIVERED+REVIEWED / DELIVERED-UNREVIEWED / PARTIAL / IN-FLIGHT / ABANDONED. Run after any crash or 'did we actually finish what we think we finished?' moment.
testing
Check for a published coordinator update and advise a preserve-by-default migration path — never a blind overwrite.