From d74b3f1e32f1b44e07044df6418ced920545df7c Mon Sep 17 00:00:00 2001 From: Paul Gebheim <86010+pgebheim@users.noreply.github.com> Date: Sun, 26 Jul 2026 06:09:16 +0000 Subject: [PATCH 1/2] feat(rig-epic,rig-task): front-loaded spec review + advisor gate (Smithers-loop learnings) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Port two learnings from the paired Smithers durable workflow back into the source-of-truth skills: - rig-epic `run`: **front-loaded spec review** — review ALL children's specs up front (architect+qa over every child vs the integration branch), resolve blockers once, then run children `--spec-cleared` so none re-pauses mid-run. A child that pauses on a spec question stalls the whole epic (fatal under parallel/durable execution); front-loading makes it the single spec decision. - rig-epic `run --advisor`: **unattended mode** — decide that front-loaded gate with a delegated architect advisor pass (proceed + synthesized per-child direction, or halt with a blocked report) instead of a human, so kicked-off epics run hands-off to child PRs. The Smithers workflow implements this with a cheap model (the "Fable advisor"). - rig-task `--spec-cleared`: skip Step 2's blocking pause (keep the notes, don't gate) when the caller already front-loaded the spec — the enabler for the above. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_015ENct54EpFjBkVMecSGh4z --- skills/rig-epic/SKILL.md | 42 ++++++++++++++++++++++++++++++++-------- skills/rig-task/SKILL.md | 11 ++++++++++- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/skills/rig-epic/SKILL.md b/skills/rig-epic/SKILL.md index 961eb68..f853d76 100644 --- a/skills/rig-epic/SKILL.md +++ b/skills/rig-epic/SKILL.md @@ -1,7 +1,7 @@ --- name: rig-epic description: "Plan and run a multi-ticket epic: decompose a feature into parent + child items and stack PRs on a shared integration branch instead of landing each on main. Use when children interleave (one item's runtime contract depends on another's incomplete state) — stacking keeps each child PR reviewable without temporarily breaking main, then squashes to main once. Triggers on: 'epic', 'plan epic', 'plan this as an epic', 'break this into an epic', 'start epic', 'integration branch', 'stack PRs', 'finish epic'." -argument-hint: "status | plan | start | next | run | review [] | finish [] [--merge] | prune" +argument-hint: "status | plan | start | next | run [--advisor] | review [] | finish [] [--merge] | prune" --- # rig-epic — integration-branch workflow @@ -145,9 +145,10 @@ Pre-flight: `git fetch origin`; confirm the parent and at least one child exist (Fallback for a child run *without* `--auto-merge`: fast-forward the branch over its tip — `git push origin origin/:refs/heads/`, which auto-closes that PR as MERGED. Safe to re-run.) -4. **Run `/rig-task --base --auto-merge`** — `--base` - makes the child's worktree branch from, and its PR target, the integration - branch; `--auto-merge` makes the child enable `gh pr merge --rebase --auto` on +4. **Run `/rig-task --base --auto-merge`** (add + `--spec-cleared` when `run`'s front-loaded spec review already cleared the + specs) — `--base` makes the child's worktree branch from, and its PR target, the + integration branch; `--auto-merge` makes the child enable `gh pr merge --rebase --auto` on its own PR once its review is clean, so **CI lands it into the integration branch** (the integration branch isn't the protected trunk, so a rebase auto-merge is fine here). Run one-shot (start→finish); it returns a single @@ -165,12 +166,37 @@ Pre-flight: `git fetch origin`; confirm the parent and at least one child exist `next` does exactly one child. Use `run` for the loop. -## `run` - -Loop `next` until no unblocked child remains: +## `run [--advisor]` + +**Front-loaded spec review — once, before the loop.** Review **all** children's +specs together, up front, instead of discovering blockers one child at a time +mid-run. A child that pauses on a spec question stalls the whole epic (and under +parallel or durable execution, a paused child can fail the batch outright), so +resolve the specs before any child starts coding: +1. Fan out `agents.architect` + `agents.qa` over **every** child's spec, read + against the integration branch; each returns its blockers. +2. Consolidate into one blocker list and resolve it **once** — clarify in the + tracker, or decide with the user. This is the epic's single spec decision point. +3. Then run each child with its own spec gate **pre-cleared**: + `/rig-task --base --auto-merge --spec-cleared`, so + no child re-pauses on a question already answered. + +This is the *pre-coding* spec pass; the combined-diff `review` (below) is the +*post-merge* code pass — different gates. + +**`--advisor` (unattended).** Decide that front-loaded gate with an **advisor +pass** instead of a human: a delegated `agents.architect` review reads the +architect + QA specs and either **proceeds** with synthesized per-child direction +(handed verbatim to each child's coder), or **halts** with a blocked report naming +what a human must decide. No human waits, so the epic runs hands-off to child PRs; +a genuine blocker still stops it rather than fanning out on a bad spec. (The paired +Smithers durable workflow implements this with a cheap model — the "Fable +advisor" — so kicked-off epics never park at the gate.) + +Then loop `next` until no unblocked child remains: ``` while an unblocked child exists: - run /rig-epic next + run /rig-epic next # children run --spec-cleared (spec was front-loaded) if it stopped without merging (outcome ≠ clean) → stop, hand back else → re-evaluate unblocked children ``` diff --git a/skills/rig-task/SKILL.md b/skills/rig-task/SKILL.md index c8b6239..23b4398 100644 --- a/skills/rig-task/SKILL.md +++ b/skills/rig-task/SKILL.md @@ -85,6 +85,12 @@ into a stacked integration branch, `--squash` into the trunk; if and hands back. `/rig-epic` passes `--auto-merge` per child so each lands on the integration branch on its own. +`--spec-cleared` — skip Step 2's blocking pause: run the spec review for its notes +but do **not** stop for a human to resolve blockers. Use when the caller already +front-loaded and cleared the spec (e.g. `/rig-epic run`'s front-loaded spec review +resolved every child's blockers up front), so this child doesn't re-pause on a +question already answered. Spec review still informs RED/GREEN; it just never gates. + Print the resolved unit + phase as the first output line, e.g. `rig-task start: ABC-369 (from branch alice/abc-369-...)` or `rig-task start: ad-hoc "add dark mode"`. @@ -149,7 +155,10 @@ Launch the **architect** and **qa** agents in parallel (names via `agents.*`): If either flags something that should be fixed before coding, clarify it — and, in tracker mode, update the item's description with the clarification and tell -the user what changed. +the user what changed. **With `--spec-cleared`** (a caller like `/rig-epic run` +already front-loaded and resolved the specs), skip this pause: keep the architect ++ qa notes to inform RED/GREEN, but do **not** stop for blockers — proceed +straight to Step 3. ## Step 3 — RED: tests first From a6829f0f2a05dc14d063687132d23dda9cc44b26 Mon Sep 17 00:00:00 2001 From: Paul Gebheim <86010+pgebheim@users.noreply.github.com> Date: Sun, 26 Jul 2026 06:13:26 +0000 Subject: [PATCH 2/2] fix(rig-epic,rig-task): child PRs squash-merge, not rebase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Child auto-merge said `gh pr merge --rebase --auto`, but many repos disallow rebase merges (and a repo with no required checks can't arm `--auto` at all). Switch to `--squash` for child PRs into the integration branch — into a stacked branch or the trunk — and merge directly when there are no checks for `--auto` to wait on. Matches the paired Smithers workflow. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_015ENct54EpFjBkVMecSGh4z --- skills/rig-epic/SKILL.md | 8 ++++---- skills/rig-task/SKILL.md | 23 ++++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/skills/rig-epic/SKILL.md b/skills/rig-epic/SKILL.md index f853d76..702bb03 100644 --- a/skills/rig-epic/SKILL.md +++ b/skills/rig-epic/SKILL.md @@ -148,11 +148,11 @@ Pre-flight: `git fetch origin`; confirm the parent and at least one child exist 4. **Run `/rig-task --base --auto-merge`** (add `--spec-cleared` when `run`'s front-loaded spec review already cleared the specs) — `--base` makes the child's worktree branch from, and its PR target, the - integration branch; `--auto-merge` makes the child enable `gh pr merge --rebase --auto` on + integration branch; `--auto-merge` makes the child enable `gh pr merge --squash --auto` on its own PR once its review is clean, so **CI lands it into the integration - branch** (the integration branch isn't the protected trunk, so a rebase - auto-merge is fine here). Run one-shot (start→finish); it returns a single - outcome string for the merge gate. + branch** (always **squash** — don't rebase-merge; many repos disallow it. If the + integration branch has no required checks, the child merges directly). Run + one-shot (start→finish); it returns a single outcome string for the merge gate. 5. **Merge gate — only `clean` is merge-green:** - `clean` → the child enabled auto-merge, so its PR lands when CI passes. **Wait** for it: poll `gh pr view --json state` (~60s, up to ~30min) diff --git a/skills/rig-task/SKILL.md b/skills/rig-task/SKILL.md index 23b4398..3e02d55 100644 --- a/skills/rig-task/SKILL.md +++ b/skills/rig-task/SKILL.md @@ -76,14 +76,15 @@ a cloud auto-fix workflow is enabled (see Step 6). of `vcs.baseRef`. A caller like `/rig-epic` passes the integration branch here so the child stacks on it rather than the trunk. -`--auto-merge` — once the pre-PR self-review (Step 4.5) is clean, enable -`gh pr merge --auto` so the PR lands **when CI / required checks pass — CI is -the merge gate, not a human**. Method follows the base: `--rebase --delete-branch` -into a stacked integration branch, `--squash` into the trunk; if -`vcs.protectedBranchMergeQueue` is true, pass `--auto` with **no** method flag -(the queue decides). Without this flag the skill never merges — it opens the PR -and hands back. `/rig-epic` passes `--auto-merge` per child so each lands on the -integration branch on its own. +`--auto-merge` — once the pre-PR self-review (Step 4.5) is clean, **squash-merge** +the PR: `gh pr merge --squash --delete-branch --auto` so it lands **when CI / +required checks pass — CI is the merge gate, not a human**. **Always squash** — +into a stacked integration branch *or* the trunk (don't rebase-merge; many repos +disallow it). If there are **no** required checks (`--auto` can't arm / the PR is +already mergeable), merge directly (drop `--auto`). If `vcs.protectedBranchMergeQueue` +is true, pass `--auto` with **no** method flag (the queue decides). Without this +flag the skill never merges — it opens the PR and hands back. `/rig-epic` passes +`--auto-merge` per child so each lands on the integration branch on its own. `--spec-cleared` — skip Step 2's blocking pause: run the spec review for its notes but do **not** stop for a human to resolve blockers. Use when the caller already @@ -244,9 +245,9 @@ don't pay a round-trip on. Delegate so the gate lives in one place: **Merge behavior.** Without `--auto-merge`, **do NOT `gh pr merge`** — open the PR and hand back (the human, `/rig-sprint`, or `/rig-epic` decides). **With -`--auto-merge`**, the self-review is clean, so enable `gh pr merge --auto` now -(method per the `--auto-merge` flag doc above); **CI/required checks are the merge -gate** — the PR lands on its own when they pass. Either way, don't hand-add PR +`--auto-merge`**, the self-review is clean, so enable `gh pr merge --squash --auto` +now (always squash — see the `--auto-merge` flag doc above); **CI/required checks are +the merge gate** — the PR lands on its own when they pass. Either way, don't hand-add PR labels if the project ships a PR-labeler workflow — it applies them. ---