Subchapter 15.3
references/pipeline.mdMarkdown5 KBView on GitHub
Per-stage detail for the fixed pipeline SELECT → CHECK YOURSELF → PILOT → FAN-OUT → REPORT → REMEDIATE. The reality-check stages (CHECK YOURSELF, the pilot gate, the report reconciliation) are covered in safety-and-self-checks.md; this file covers the mechanical stages.
Also bundled
EvalsEnumerate, then filter, using finding-targets.md. The output is an explicit, finite list of resolved targets — names for multi-repo, paths for monorepo — each annotated with the matched signal. Show the list to the user. A campaign that cannot name its targets is not ready to run.
Record the count. It anchors the reconciliation in REPORT: selected = applied + already-compliant + skipped-not-applicable + held-back + failed.
Pick one representative target — not the easiest one; one whose shape is typical of the fleet. Run the recipe on it, surface the full diff, validate it. The pilot is the contract: “this exact change, ×N.” Its mechanics are identical to one FAN-OUT iteration, except it stops for explicit confirmation and discards (or keeps, if the user approves) its branch. Lock the pr_spec here — title format, body template, labels — because FAN-OUT replicates it without re-prompting.
Process confirmed targets in chunks of at most max_targets_per_run — a per-chunk concurrency cap, not a campaign ceiling. The total fan-out (count + scope) must be confirmed with the user before the first chunk (see safety-and-self-checks.md); the cap then bounds each chunk. For agentic recipes, send one chunk’s Agent calls in a single message so they run concurrently. Each target is handled in isolation — its failure is recorded and the rest continue.
Per target, in order:
skipped-not-applicable, stop here.already-compliant, stop here (no branch, no commit, no PR).pr_spec template, cut from the target’s default branch — never work on the default branch itself. Same input → same name, so a re-run reuses it rather than creating a duplicate.already-compliant and discard the branch.safety-and-self-checks.md) — did the recipe do only what the intent describes?validation field + Skill(perform-preflight)). Fail → failed, no commit, no PR.failed, no commit.Skill(committing-changes), using the locked title/type.pr_spec — never to a default branch, never force-pushed. Capture the PR URL.If dry_run is set, perform steps 1–9 and stop before commit, push, and open-PR (steps 10–11); record what would have shipped. It mutates no git state, local or remote.
Aggregate one row per target:
| Target | Status | PR | Notes |
|---|---|---|---|
<name> | applied / already-compliant / skipped-not-applicable / held-back / failed | <url or —> | <divergence, failure reason, or —> |
Then state the reconciliation explicitly: selected = applied + already-compliant + skipped-not-applicable + held-back + failed. If the arithmetic does not close, a target was dropped silently — find it before declaring done. Surface divergence flags and failure reasons in full; do not bury them under a success headline. See the prove-don’t-declare discipline in safety-and-self-checks.md.
Re-run the campaign against only the failed and skipped-not-applicable subset. Because every recipe declares an idempotency condition, a target that already succeeded is a clean no-op if it sneaks back into the set. Fix the root cause first — a recipe that failed validation on five targets the same way needs a recipe fix, not five retries.
already-compliant: no branch, no commit, no PR.Bulk enumeration plus per-target API calls can exhaust the GitHub rate limit. On a 403 or 429, back off exponentially and retry; insert a small delay between per-target API calls in large runs. Prefer one enumeration pass reused across the campaign over re-querying per target. A rate-limit pause is not a campaign failure — wait and resume.