| name | file-cycle |
| description | Reference document shared by the find-and-file iteration skills (/kaizen, /bughunt, /kaikaku) for their common single-iteration machinery โ author groomed issue(s), label by validation, file autonomously (multi-output), and declare the loop outcome. NOT user-invokable, and NOT the loop. The loop lives in `/loop`; this is one iteration's file cycle. The file-type sibling of `build-cycle`. Only load when a find-and-file skill directs you here. |
file-cycle โ shared single-iteration find-and-file skeleton
Don't invoke this directly, and don't loop from here. This is loaded by /kaizen, /bughunt, and /kaikaku for the file steps they share within one iteration. Looping (cadence, idle escalation, re-arming) is owned by /loop โ see that skill. If a user types /file-cycle, redirect them to a specialization, or to /loop <specialization> to run it as a loop.
This document defines the common skeleton for one iteration of a find-and-file development skill: acquire targets, gate them, then author and file a groomed issue for every candidate that clears the gate โ autonomously, labeled by validation โ and declare the outcome that /loop reads to decide what happens next. Each specialization (/kaizen, /bughunt, /kaikaku) plugs in its own target acquisition (Phase 1), quality gate (Phase 1.5), and issue-body template (the specialization-specific part of Phase 4โฒ); everything else lives here.
This is the producer half of the dev loop: find-and-file skills surface groomed work; the consumer side (/shovel-ready, the autodev pipeline, a human) implements it. file-cycle never builds โ there is no branch, no /ship, no merge, no PR. Its deliverable is a filed issue, not a diff. (The build-type sibling โ /shovel-ready โ uses build-cycle instead.)
The outcome contract
An iteration's last act is to declare its result so /loop can pace the loop:
LOOP-OUTCOME: <status> โ <one-line detail>
Find-and-file iterations emit one of: filed (one or more issues filed), empty (target acquisition found nothing), gate_killed (candidates found, none cleared Phase 1.5), or blocked (a genuine inability to proceed โ e.g. the tracker is unreachable). They never emit shipped or rejected โ those are build-cycle's (there is no PR to merge or have closed). See dev-skills:loop for the full table and what /loop does with each. Always end with this line โ a missing outcome is a contract violation that strands the loop.
Phase model
| Phase | Owner | Description |
|---|
| 1 | Specialization | Target acquisition. How candidates are found (parallel-agent audit, whole-system recon, etc.), including any adversarial verification/steelman. Empty โ declare empty and stop the iteration. |
| 1.5 | Specialization | Quality gate. Each candidate must clear a specialization-defined bar; apply it per candidate. If none clears, declare gate_killed and stop the iteration (both are normal, non-productive outcomes). |
| 4โฒ | file-cycle | Author and file the issue(s). One issue per candidate that clears the gate โ the specialization supplies the body template; this cycle owns labeling, dup-check, and autonomous filing. |
| 7 | file-cycle | Declare LOOP-OUTCOME. |
There is no Phase 2/3/3.5/4/5/6 โ no branch, implement, sync, /ship, /retro, or merge. This cycle jumps from the gate straight to filing. (The phase is numbered 4โฒ to mark it as the file-equivalent of build-cycle's Phase 4 /ship hand-off โ its whole build-substitute.) There is no idle-counter, no re-arm, and no cadence logic here โ those live in /loop. One invocation of a specialization = one iteration that ends at Phase 7.
Flags this cycle interprets
(/loop owns the loop flags โ --once, --idle-count, --drain โ and passes these through to the specialization verbatim.)
--auto โ no-op. There is no merge to automate; filing is already autonomous (Phase 4โฒ). Accepted as a harmless passthrough for back-compat and /loop invocations; it never means "merge" โ there is no merge.
--model=<sonnet|opus|haiku> โ pin the specialization's Phase 1 acquisition agents (and any steelman/verification agents) to a specific Claude generation, forwarded verbatim to their Agent/Workflow calls. The main session keeps its own model. Default (omitted): agents inherit the session's model.
Shared invariants
- File every candidate that clears the gate (multi-output). Acquisition usually surfaces several real candidates; file all that clear Phase 1.5 โ don't throw away validated runners-up, don't ship one and discard the rest, and don't make the user approve them one at a time. Each gets its own issue, labeled by its own validation outcome. The per-candidate quality gate, not an artificial per-iteration cap, is the throttle. (One iteration can legitimately file zero, one, or several issues.)
- No scope expansion mid-iteration. Adjacent findings that surface while authoring an issue become next iteration's candidates. Trust the loop.
- Fail hard, no fallbacks. Per the project's stance (read
CLAUDE.md), don't paper over what you find. A finding you can't substantiate isn't filed โ it's dropped, silently.
- Quality gate beats throughput. Each specialization defines its own bar (Phase 1.5). "Found something but not worth filing" is a normal, healthy outcome โ declare
gate_killed and let /loop pace it. Filing a weak issue is worse than filing none โ it erodes trust in the queue the consumer drains. Don't file a borderline candidate because "we have to produce something."
- File autonomously โ no in-session approval gate. file-cycle must be able to run unattended under
/loop. The Phase 1.5 gate (applied per candidate) is what makes unattended filing safe; the human reviews the filed issues on the tracker, the way they'd review PRs. Don't present a draft for sign-off, don't ask which to file, don't pick one and discard the rest. Cases that genuinely need a human decision get labeled needs-design and filed anyway (see Escalation), not withheld.
Quality gate principle (Phase 1.5)
Every find-and-file skill has a temptation to file SOMETHING every iteration to justify the run. Resist it. If no candidate clears the specialization's bar, report what was found and why each was rejected, then declare gate_killed โ don't file a borderline issue.
What "clearing the bar" means is specialization-specific and defined in each skill:
/kaizen: the candidate is unambiguously accidental complexity, uncontroversial, bounded, with a net-deletion cleanup.
/bughunt: provability โฅ 0.6 (a concrete red test is sketchable) AND reachable AND material, surviving adversarial verification.
/kaikaku: survives the Chesterton's-Fence steelman + anti-guard test, at high architectural leverage.
Phase 4โฒ โ Author and file the issue(s)
This is the whole build-equivalent โ there is no branch/implement/ship/merge. For each candidate that clears Phase 1.5, author a groomed issue and file it. This cycle owns the machinery below; the issue body is the specialization's (each skill gives its own template โ a bug report, a cleanup proposal, an architectural RFC).
Write the body from the specialization's template
The specialization defines the body sections. Whatever the shape, a groomed issue is decision-ready and actionable: it states the finding concretely (with file:line loci), why it matters, the evidence that it's real, and a concrete proposed change โ enough that a consumer (human or autodev) can pick it up without re-deriving the analysis.
Label by validation, not by default
The label depends on how far the analysis converged, not a fixed default. Don't reflexively stamp everything needs-design:
- Converged โ the candidate landed on a concrete plan with no open design forks (a standard mechanism, a clear fix/cleanup, only empirical assumptions left to check). Verify the key empirical assumptions yourself first (e.g. "no other call site depends on this shape" โ go confirm it), then label it the repo's build-queue label (
shovel-ready, or the project's equivalent). It can enter the consumer queue; a human glance is welcome but not a gate.
- Open forks remain โ a real decision/trade-off is unresolved (competing approaches, a load-bearing concern you couldn't fully rule out, a public-API/wire-format/data-model change others depend on). Label it
needs-design and frame the open fork explicitly in the issue's Open-questions section. Gate on human direction โ but still file it; don't withhold it.
The failure mode to avoid: labeling a verified, converged, standard-pattern finding needs-design and parking it behind a review it doesn't need. (Add the specialization's type label too where the project uses one โ e.g. bug for /bughunt.)
File โ dup-check, record, report
For every candidate that clears the gate:
- Dup-check the tracker first (
gh issue list --search "<key symptom / locus>") โ don't re-file an open finding.
- File it (
gh issue create) with the body and the label from above.
- Record the filed target so the next iteration's acquisition excludes it (and never re-surface a pending or previously-rejected target).
- Report the filed issue URLs and the count.
Phase 7 โ Declare the outcome
End the iteration with the LOOP-OUTCOME line (see the contract above). /loop reads it and owns everything after.
filed โ one or more issues were filed (Phase 4โฒ; report the count and URLs). /loop treats it as productive and re-arms long (a filed issue awaits the consumer on the tracker; there's no fast-follow).
gate_killed โ candidates were found but none cleared Phase 1.5. Non-productive; /loop idles. Report what was rejected and why โ a gate-kill is often a valuable confirmation (earned complexity, an unreachable defect-class).
empty โ acquisition surfaced nothing at the depth applied. Non-productive.
blocked โ a genuine inability to act (tracker unreachable, auth failure). Should be rare: file-cycle does not block for approval or to choose among candidates โ it files autonomously and labels human-decision cases needs-design.
The per-candidate quality gate is the throttle โ not a per-iteration cap, not a human approval step. File everything that clears it; withholding a validated candidate to avoid "filing too much" is the throw-away-work failure mode. But the bar is real and stays high.
Shared boundaries
- Don't build. No branch, no implementation, no
/ship, no PR, no merge from this cycle. If a candidate is small and self-contained enough that you're tempted to just fix it โ file it anyway; the consumer implements. (The specializations already route by altitude: an instance-fix is /bughunt, a tidy is /kaizen, a structural change is /kaikaku โ all file.)
- Don't loop from here. No
ScheduleWakeup, no idle-counter, no re-arm. End at Phase 7; /loop decides the rest.
- Don't withhold for approval. File autonomously; label the human-decision cases
needs-design.
- Don't re-surface a pending or rejected target. Track filed/rejected targets so acquisition excludes them until resolved.
- Don't file speculation. Every filed issue is substantiated to its specialization's bar. An unsubstantiated candidate is dropped, not filed with a hedge.
Shared escalation โ label, don't block
Find-and-file skills run unattended, so they do not stop to ask the user mid-iteration. The cases that would otherwise be an in-session question become a label + explicit framing in the issue, for the human to resolve on the tracker:
- A candidate whose right answer needs a human/product decision, or that touches a public API / wire format / data model others depend on โ file it
needs-design, open fork stated plainly. Don't decide it, don't withhold it.
- Multiple candidates clear the gate โ file them all (the multi-output default); there is no "pick one" to escalate.
- Acquisition keeps surfacing the same already-rejected finding โ that's a confirmation; note it in the run log and move on.
The only genuine blocked is an inability to act at all (tracker unreachable, auth failure). When a candidate is uncertain, the move is file it needs-design โ not ask. A labeled issue the human triages costs less than a stalled loop, and never throws away the work.