fe5ca8f8c0
Implements the three efficiency findings from the #310 pipeline measurement (refs #35): ~691k subagent tokens / ~3.5 h for a deliberately small cycle, with recon duplication as the single biggest obligatory per-cycle cost. 1. Cycle recon (pipeline.md § Cycle recon; specify, planner, brainstorm, boss, plan-recon): recon fan-out is budgeted per cycle, not per phase. One full plan-recon dispatch — normally specify Step 1, in a new pre-spec sources/recon_scope carrier form — serves both the spec's concrete code shapes and the plan's file-map. planner Step 2 becomes reuse-first (freshness / quotability / coverage conditions) with narrowly-bounded delta dispatches (new Delta dispatch contract in plan-recon.md); broad Explore-type grounding sweeps are banned in every mode. Field evidence: 151k (Explore) + 99k (plan-recon) with ~40 % overlap in one bounded cycle. 2. Fieldtest probe tier (fieldtest, fieldtester, pipeline.md, agent-template.md § model rule 2): a cycle whose user-visible delta is a single narrow axis dispatches the per-cycle fieldtest at tier: probe — 1-2 examples on exactly that axis, ~200-word report, explicit model:sonnet dispatch override (no dispatch-level effort override exists; frontmatter effort applies). Probe is a tier, not a skip; the milestone fieldtest always runs full tier on the frontmatter model, keeping the milestone-close gate's >=2-example floor unconditional. 3. Assumption economy (specify Step 3 + self-review item 6): grounding-check cost scales with the spec's assumption count, so specs state current-behaviour claims only where the change relies on them (the gate's own falsity test), demote context-only mentions to ledger citations, and keep iteration scope tight — fewer restatements, never fewer reliances. The gate itself is unchanged. Design reviewed pre-implementation (opus plan review); diff adversarially verified by a 3-lens review workflow (consistency, operability, cross-reference), confirmed findings folded in. refs #35
906 lines
59 KiB
Markdown
906 lines
59 KiB
Markdown
---
|
|
name: boss
|
|
description: User-invoked only (typed as `/boss`). Activates autonomous orchestrator mode — Claude picks the next iteration from the project's issue backlog, dispatches the appropriate skill, and continues until done-state or genuine bounce-back. Outside `/boss`, the default is interactive collaboration with the user, not autonomous queue execution.
|
|
---
|
|
|
|
# boss — autonomous orchestrator mode
|
|
|
|
> **Violating the letter of these rules is violating the spirit.**
|
|
|
|
## Overview
|
|
|
|
Autonomous orchestrator mode is how the orchestrator moves a
|
|
project forward when the user is away. Inside this mode, Claude
|
|
reads the project's issue backlog, picks the top item,
|
|
dispatches the right skill, integrates the result, and continues
|
|
to the next item — until the queue holds nothing more it can do
|
|
autonomously (done-state) or a real design fork forces a
|
|
bounce-back to the user.
|
|
|
|
Outside this mode, the default is interactive collaboration:
|
|
the user asks; Claude answers or executes the specific request;
|
|
Claude stops. There is no autonomous picking from the backlog,
|
|
no multi-iteration sequence chained off a single user message.
|
|
|
|
This skill exists to make the mode-switch explicit. Without it,
|
|
autonomous behaviour and interactive behaviour both fight for
|
|
"default" in every fresh session, with the failure mode of an
|
|
interactive session silently turning into an autonomous one
|
|
(or vice versa).
|
|
|
|
## When to Use / Skipping
|
|
|
|
Trigger:
|
|
|
|
- The user explicitly types `/boss` in chat.
|
|
|
|
Never auto-invoked. Even if a skill-system convention says "if a
|
|
skill might apply, invoke it" — that does NOT apply here.
|
|
`/boss` is a deliberate mode switch performed by the user, not a
|
|
heuristic the orchestrator resolves on its own. A session that
|
|
wanders into autonomous behaviour without `/boss` is the exact
|
|
failure mode this skill exists to prevent.
|
|
|
|
May be exited mid-session by:
|
|
|
|
- The user signalling "stop", "pause", or "back to chat".
|
|
- A bounce-back trigger firing (see "Direction freedom" below).
|
|
- Done-state (the queue holds nothing autonomously-doable and the
|
|
done-state procedure has fired).
|
|
|
|
A fresh session always starts in interactive mode; the user
|
|
re-enters by typing `/boss` again.
|
|
|
|
## The Iron Law
|
|
|
|
```
|
|
NO AUTONOMOUS DISPATCH OUTSIDE A `/boss` SESSION.
|
|
DONE-STATE = QUEUE EMPTY OF AUTONOMOUSLY-DOABLE ITEMS, NOT SUB-GOAL COMPLETE.
|
|
BOUNCE-BACK ONLY ON THE FOUR NAMED TRIGGERS.
|
|
A NEW CYCLE'S DESIGN RUNS AUTONOMOUSLY VIA THE `brainstorm` SWARM — IT DECIDES
|
|
THE CONVERGENT (CITED-GROUND) FORKS AND BOUNCES ONLY A DIVERGENT DIRECTION
|
|
FORK OR A GREENFIELD DESIGN BELOW THE SWARM'S GROUNDING FLOOR.
|
|
AUTONOMOUS COMMITS LAND ON THE RUN'S WORKTREE BRANCH — `main` MOVES ONLY VIA
|
|
THE USER-RATIFIED MERGE (§ THE RUN WORKTREE).
|
|
```
|
|
|
|
Universal rules (only-orchestrator-commits, main-is-sacrosanct,
|
|
worktree isolation for substantive work, language, RED-first for
|
|
bugs) come from the project's `CLAUDE.md`
|
|
— and from the user-level `~/.claude/CLAUDE.md` identity/security
|
|
layer above it, loaded in every session. Both bind regardless of
|
|
mode; autonomy does not lift a user-level constraint (e.g. an
|
|
external-service-consent rule that names `/boss` explicitly). This
|
|
skill does not restate them — with two deliberate local refinements:
|
|
`main`-is-sacrosanct holds **below the session anchor**, with the
|
|
rollback sandbox (§ Direction freedom) as the one narrow `/boss`
|
|
exception, letting the orchestrator wind back its *own* unpushed
|
|
autonomous commits above that anchor; and the worktree convention is
|
|
fixed at run granularity by § The run worktree (one worktree per run,
|
|
user-ratified merge).
|
|
|
|
## The Process
|
|
|
|
### Step 1 — Read the queue
|
|
|
|
The project's issue tracker is the forward queue. Read open
|
|
issues via the list command in the project's CLAUDE.md project
|
|
facts. If the project names no issue tracker there, it does not
|
|
have an autonomously addressable queue — bounce back to the user
|
|
with that diagnosis.
|
|
|
|
If the entire open backlog is empty — or holds only user-reserved
|
|
leftovers (`idea`-labelled items, user-reserved acts; an open
|
|
design fork bounces via Step 2 instead) — skip to Step 5
|
|
(done-state). Do not invent work; an exhausted queue is a real
|
|
signal that the cycle closed and there is nothing left.
|
|
|
|
### Step 2 — Pick the top item per direction-freedom rules
|
|
|
|
See "Direction freedom" below. The rules permit picking
|
|
autonomously when the path is clear. If the top item is a real
|
|
fork (two substantive options with no clear default), bounce
|
|
back to the user.
|
|
|
|
On a clean pick, mark work-start on the tracker: assign the issue
|
|
to the `claude` user (`../issue/SKILL.md` § tea mechanics — one
|
|
write, no removal; there is no in-progress label). A chat-seeded
|
|
run with no issue yet assigns the moment the reference issue is
|
|
created (§ The reference issue). The live run-worktree branch
|
|
(§ The run worktree) is the matching git-side signal.
|
|
|
|
### The run worktree (mandatory)
|
|
|
|
Before the first dispatch, the orchestrator enters a git worktree
|
|
for the run (harness `EnterWorktree`; name it `issue-N-<slug>` after
|
|
the reference issue, or the run's topic slug while no issue exists
|
|
yet — keep the slug short, the harness caps names at 64 chars, and
|
|
the name keys the worktree and its branch). A branch opened on the
|
|
topic slug keeps its name when the reference issue is created later
|
|
in the run — the issue's decision log names the branch; no rename
|
|
churn. Every commit the run makes lands on that branch;
|
|
the primary clone's `main` checkout is never touched. This is the
|
|
project-universal worktree convention
|
|
(`../docs/conventions.md` § Git discipline — which also pins
|
|
`worktree.baseRef: "head"`, so the branch bases on the local,
|
|
possibly-unpushed `main`) applied at run
|
|
granularity — one worktree per run, spanning its iterations. A run
|
|
that bounces at Step 2, before any dispatch, never opened a worktree
|
|
— there is then no branch to report.
|
|
|
|
- **Already isolated → don't nest.** A background session the
|
|
harness has already placed in a worktree needs no second one; a
|
|
resumed run whose worktree still exists re-enters it
|
|
(`EnterWorktree` with `path`, per the mid-flight rule in Step 3)
|
|
instead of opening a parallel tree.
|
|
- **The merge is user-reserved — a run-close act, not a queue
|
|
item.** At done-state or bounce-back after work has begun, the
|
|
branch stays where it is, unmerged; the notify names it as
|
|
awaiting review (§ Done-state notifications). Only after the
|
|
user's feedback does the orchestrator integrate: merge into
|
|
`main` from the primary clone — fast-forward preferred (rebase
|
|
the branch onto `main` first if `main` has moved) — push (the
|
|
ratification covers the push), then remove the worktree and
|
|
delete the branch (`git worktree remove` from outside the tree;
|
|
`ExitWorktree` does not remove a re-entered worktree). No pull
|
|
request is opened; the review is the user reading the branch,
|
|
human-in-the-loop. The merge joins push, formal milestone close,
|
|
and external-service consent in the user-reserved set — and,
|
|
being run-close integration, it never makes a queue item
|
|
non-doable mid-run.
|
|
- **`closes #N` fires at merge-and-push time.** Close-markers in
|
|
the run's commits reach the default branch only with the ratified
|
|
merge and its push — the reference issue stays open, correctly,
|
|
while the work awaits review.
|
|
|
|
### Step 3 — Dispatch the appropriate downstream skill
|
|
|
|
Pipeline:
|
|
|
|
```
|
|
brainstorm → specify → planner → implement → audit → fieldtest
|
|
specify → planner (design settled in sources, no discovery)
|
|
+
|
|
debug (bug-triggered)
|
|
+
|
|
tdd → implement (mini) (test-specifiable feature)
|
|
+
|
|
compiler-driven (behaviour-preserving type/signature edit; observe-then-bounce)
|
|
+
|
|
docwriter (post-stability)
|
|
```
|
|
|
|
Match the chosen item to the right entry skill. If a spec exists
|
|
but no plan: `planner`. If a plan exists: `implement`. If a cycle
|
|
is closing: `audit`. If the iteration is a bug-fix: `debug`. For
|
|
new feature work with no spec or plan yet, run the **Entry-path
|
|
reflection** below before dispatching anything. Read each skill's
|
|
`SKILL.md` trigger section if unsure.
|
|
|
|
**Pre-dispatch grounding stays light.** Queue triage reads issue
|
|
bodies and `git log`; it does not fan out. A code-territory read an
|
|
item needs belongs to the dispatched phase skill's own recon step —
|
|
the cycle recon (`../docs/pipeline.md` § Cycle recon) — and is
|
|
never a broad Explore-type sweep fired before, or instead of, that
|
|
step.
|
|
|
|
**Entry-path reflection (feature work).** Entry paths form an **ordered
|
|
cascade**, and the choice is made by reflection every time, not by
|
|
habit. The discriminator is no longer a single "design line": it adds a
|
|
**verification / enumeration axis** *ahead of* the settled-vs-fork
|
|
question, so each lighter path carries a **positive** trigger matched by
|
|
signature rather than being reached by elimination. Walk the cascade top
|
|
to bottom and take the **first** arm that matches; record the one-line
|
|
verdict ("observed bug → `debug`" / "design fork → `brainstorm`" /
|
|
"mechanical type-edit → `compiler-driven`" / "test-specifiable →
|
|
`tdd`" / "settled prose design → `specify`") in the loop.
|
|
|
|
```
|
|
route(task):
|
|
observed bug -> debug # RED-first gate, FIRST — never bypassed, even for a one-line fix
|
|
forces a genuine design choice -> brainstorm # the only place doubt resolves "up"
|
|
a type/signature edit at a definition
|
|
site, propagating mechanically -> compiler-driven # observe-then-bounce; behaviour-preserving
|
|
new behaviour as one honest assertion -> tdd
|
|
else -> spec-driven # the deliberate heavy fallback (specify -> planner)
|
|
```
|
|
|
|
- **Observed bug → `debug`.** A regression of existing behaviour is
|
|
RED-first, always, and this check is **first in the cascade** so a bug
|
|
whose fix happens to be a one-line type edit cannot slip into the
|
|
compiler-driven arm and bypass the RED-first gate. Dispatch
|
|
autonomously, as a bug issue already is.
|
|
- **Forces a genuine design choice → `brainstorm`.** Writing the work
|
|
down would force a choice between two or three plausible designs with
|
|
real trade-offs. Discovery must resolve it first — and `brainstorm` now
|
|
**dispatches autonomously**: its synthetic-user swarm decides the forks it
|
|
can settle on a cited shared ground (recorded on the reference issue) and
|
|
bounces only a genuine divergent direction fork, or a greenfield design
|
|
below its grounding floor, per §"Direction freedom" trigger 4. A fresh
|
|
`brainstorm` is no longer a blanket pre-dispatch bounce.
|
|
- **A type/signature edit at a definition site, propagating mechanically
|
|
→ `compiler-driven`.** The positive trigger is *syntactic and
|
|
observable*: a carrier/newtype narrowing, a constructor or field
|
|
rename, a signature change at a definition that the type checker then
|
|
enumerates across N call sites — **behaviour preserved**. The arm is
|
|
**observe-then-bounce** (its executor is `../implement` "The
|
|
compiler-driven arm" + the `compiler-driven-edit` workflow): make the
|
|
edit, build, run the suite; **clean build AND suite green unchanged →
|
|
commit; a hole that forces a design decision → bounce to `specify` (or
|
|
`tdd` if the hole turns out to be test-specifiable new behaviour, per
|
|
the straddle rule); the suite not green-unchanged → bounce to `debug`,
|
|
RED-first.** Entering on
|
|
the observable trigger and letting a real run settle the verdict is
|
|
what makes this sound — a mis-routed behaviour change fails the
|
|
post-condition and bounces instead of shipping green-but-wrong.
|
|
Dispatch autonomously; its bounces are reactive, not a pre-dispatch
|
|
checkpoint.
|
|
- **New behaviour as one honest assertion → `tdd`.** The desired
|
|
behaviour can be pinned by one minimal falsifiable assertion — "calling
|
|
X with Y returns Z". Dispatch autonomously.
|
|
- **Else → spec-driven (`specify` → `planner`).** The deliberate heavy
|
|
fallback for prose-design work the sources already settle (an
|
|
exhaustive issue body, a long in-context discussion). `specify` is
|
|
bounded (no interview); dispatch it autonomously and it signs through
|
|
its own Step-6 gate — the Step-5 `grounding-check` `PASS` — escalating
|
|
to a user-review pause (a problem-state notify, not a pre-dispatch
|
|
checkpoint) only when grounding blocks with no human to override it.
|
|
|
|
**The straddle rule (a rule, not an example).** "Add an enum variant"
|
|
straddles the compiler-driven and the tdd/spec arms. Decide by what the
|
|
edit *encodes*, not by its surface shape: an arm that is **mechanical /
|
|
forwarding** — the type checker enumerates the sites and behaviour is
|
|
preserved (an exhaustiveness-only variant, a pass-through case) — is
|
|
**compiler-driven**; an arm that **encodes new behaviour** — a variant
|
|
whose handling is a new code path with new observable output — is
|
|
**tdd** (one assertion) or **spec-driven** (a real design). When unsure
|
|
which side a change falls on, that doubt is itself the signal it carries
|
|
behaviour: route up to tdd/spec, not down to compiler-driven.
|
|
|
|
Every entry path now dispatches autonomously — `debug`, `compiler-driven`,
|
|
`tdd`, `specify`, and `brainstorm` — and what differs is only *what each
|
|
bounces on*, not whether it runs. The old asymmetry (a fresh `brainstorm`
|
|
bouncing before it starts) rested on context budget: a serial-interview
|
|
`brainstorm` was high-context discovery the orchestrator could not compact on
|
|
its own. The swarm retires that rationale — it IS the compaction: the
|
|
orchestrator gets back a triaged populated space, not a 10-round interview
|
|
transcript, so `brainstorm` decides the forks the swarm settles on a cited
|
|
ground and bounces only a divergent direction fork (or a greenfield design
|
|
below its grounding floor — see trigger 4). `specify` dispatched in `/boss`
|
|
signs through its own Step-6
|
|
gate — the Step-5 `grounding-check` `PASS`, an independent agent's
|
|
verdict against currently-green tests, not the orchestrator's confidence;
|
|
the run then continues to `planner` without pausing. A no-override
|
|
grounding `BLOCK` escalates to the user-review pause (a final-sign-off
|
|
notify, not a pre-dispatch checkpoint). The judgement that used to gate
|
|
the sign now lives inside `specify` Step 1.5, which decides derivable
|
|
forks boldly — see §"Spec auto-sign" below. Do not let the asymmetry
|
|
harden into a reflex of routing borderline items to `brainstorm` "to be
|
|
safe" — that is the exact bias this reflection exists to break; walk the
|
|
cascade honestly each time. The one principled tilt is two-sided: a fork
|
|
`specify` can *derive* an answer for (from the sources, the code,
|
|
consistency, risk) is spec-driven work, decided inside `specify` (Step
|
|
1.5), **not** a `brainstorm` bounce; only a fork that needs genuine
|
|
discovery, or that hangs on a user preference no source settles,
|
|
resolves to `brainstorm`. The lighter arms
|
|
also bounce reactively: a `specify` or `tdd` that later reports the
|
|
design was not settled / not test-specifiable, or a `compiler-driven`
|
|
run that hits a hole, escalates — `specify` / `tdd` to `brainstorm` (a
|
|
fresh cycle, a trigger-4 bounce-back), `compiler-driven` to `specify` or
|
|
`tdd` (a hole — a design choice vs. test-specifiable new behaviour, per
|
|
the straddle rule) or `debug` (the regression).
|
|
|
|
All entry paths are always available — none is profile-gated. The
|
|
cascade is the order of decision: the lighter arms (`debug`,
|
|
`compiler-driven`, `tdd`) carry positive triggers and dispatch
|
|
autonomously, `specify` dispatches autonomously and pauses at its
|
|
sign-off gate, and `brainstorm` dispatches its swarm autonomously —
|
|
deciding the forks it can settle on a cited ground and bouncing only a
|
|
divergent direction fork (or a greenfield design below its grounding
|
|
floor).
|
|
|
|
If the working tree is mid-flight (uncommitted changes left over
|
|
from a previous session): inspect first, then resume the right
|
|
step. Do not restart from scratch. If a previous run's worktree
|
|
still exists, resume *inside it* (`EnterWorktree` with its path,
|
|
§ The run worktree) rather than starting a parallel tree.
|
|
|
|
### Step 4 — Loop, deciding on each agent output
|
|
|
|
For each dispatched skill's result, decide:
|
|
|
|
- **Continue** — agent output is good, next item is obvious,
|
|
the queue is non-empty. Most common case.
|
|
- **Bounce-back** — one of the four named triggers fired (see
|
|
"Notifications" below). Send a notify, stop the loop.
|
|
- **Done-state** — the queue is empty of **autonomously-doable**
|
|
items AND the cycle is fully ratified (audit drift-clean,
|
|
fieldtest clean if applicable). Go to Step 5. The check has two
|
|
edges:
|
|
- **Closing-gate follow-ups re-enter the queue.** Follow-up
|
|
work this run's own closing gate surfaced — an audit drift
|
|
item, a fieldtest `bug` or `friction` finding — is queue work
|
|
like any other, whether it was routed inline (the skills'
|
|
documented dispositions) or filed onto the tracker (the
|
|
milestone shape). Walk each through the direction-freedom
|
|
test (§ Direction freedom): a clear, fork-free follow-up — a
|
|
bug with an established fix pattern, a mechanical edit, a
|
|
test-specifiable feature — sends the loop back to Step 2, no
|
|
matter that it was discovered *after* the primary task rather
|
|
than before. Primary-task-complete is a sub-goal, never a
|
|
done-state.
|
|
- **A queue of only user-reserved leftovers IS done-state.**
|
|
When everything still open genuinely needs the user without
|
|
blocking on a decision — an `idea`-labelled item (droppable
|
|
by definition; its triage is the user's prioritisation call)
|
|
or a user-reserved act (push, the ratified merge of the run's
|
|
branch into `main`, formal milestone close, external-service
|
|
consent) — the run is done; name those
|
|
leftovers in the notify. A remaining **design fork** is the
|
|
one user-reserved residue that is *not* done-state: it
|
|
matches bounce-back triggers 1/4 and takes the problem-state
|
|
notify's actionable ask, not the done-state wrap-up. When
|
|
both kinds remain, the bounce governs.
|
|
|
|
A `/boss` done-state means this run has nothing
|
|
left to dispatch; it is **not** an automatic milestone close —
|
|
closing a tracker milestone needs its end-to-end milestone
|
|
fieldtest green and stays a deliberate manual act (see
|
|
`../docs/pipeline.md` § Milestone-close gate).
|
|
|
|
If a term-drift is resolved during the loop — two names collapsed to
|
|
one, or a settled term not yet listed — record it in the project
|
|
glossary per `../docs/glossary-convention.md`: record reality, never
|
|
invent. This is the only glossary write authority outside the user.
|
|
Building a glossary from scratch (the `glossary` skill's bootstrap) is
|
|
*not* this authority — it is high-context, user-only work; when a project
|
|
lacks a glossary and drift is visible, recommend a bootstrap via
|
|
bounce-back, never run one autonomously.
|
|
|
|
### Step 5 — On done-state: Notify
|
|
|
|
Run the procedure named in "Done-state notifications" below.
|
|
|
|
## Direction freedom
|
|
|
|
The orchestrator has authority to choose the next iteration,
|
|
refactor, or feature without asking — and, under the bold stance, to
|
|
*decide* a load-bearing design fork it can derive an answer for rather
|
|
than bounce it (see `../specify/SKILL.md` Step 1.5). Wrong calls are
|
|
**contained or recovered**, not avoided by timidity: bad work is either
|
|
discarded before it reaches `main` (`git checkout -- <paths>` on the
|
|
working tree), or — once it is autonomous, committed, unpushed work — wound
|
|
back inside the rollback sandbox below. Being wrong is allowed; the cost
|
|
of a wrong call is bounded, and a bounded cost is cheaper than the
|
|
context-switch of asking.
|
|
|
|
The cost of asking "what should I do next" — context-switch for
|
|
the user, latency on my side — exceeds the expected cost of
|
|
discarding or rolling back a bad state. So when the queue is
|
|
non-empty and the path is clear, just pick and proceed.
|
|
|
|
The same test is the **done-state discriminator**. An open item is
|
|
**autonomously-doable** when it has a clear path with no genuine design
|
|
fork (a bug with an established fix pattern, a mechanical/type edit, a
|
|
test-specifiable feature) and requires no user-reserved act (no push, no
|
|
ratified merge into `main`, no formal milestone close, no
|
|
external-service consent). Follow-ups the
|
|
run's own closing gate discovered — audit drift items, fieldtest
|
|
findings, routed inline or filed onto the tracker — re-enter the queue
|
|
and take the same test; being discovered *after* the primary task does
|
|
not make an item a stopping point, and a narrow reading of the original
|
|
task's scope does not either. The run stops only when what remains is
|
|
empty or entirely user-reserved — a done-state for `idea` items and
|
|
user-reserved acts, a bounce-back for a fork (Step 4).
|
|
|
|
### The reference issue (mandatory)
|
|
|
|
Every `/boss` run is anchored to a tracker issue — the one that seeded
|
|
the cycle, or one `specify` creates when the work was settled in pure
|
|
chat with no prior issue (`../specify/SKILL.md` Step 1.5). The run always
|
|
has exactly one such reference issue, and the orchestrator **comments its
|
|
fork decisions there as it goes**: each load-bearing fork it derives, the
|
|
chosen option, and the rationale (or, for a user decision minuted from
|
|
the discussion, the provenance). It is the run's decision log — three
|
|
things at once:
|
|
|
|
- the **user's after-the-fact audit**: how the orchestrator decided what
|
|
it decided without them, in one auditable thread they can veto from;
|
|
- the orchestrator's **cross-run "issue memory"**: a later run reads the
|
|
thread to see what was already tried and why;
|
|
- the **only surviving trace of an abandoned attempt** — because a
|
|
rollback hard-drops the commits (below), the issue thread is what
|
|
remains of the dead-ended line.
|
|
|
|
These decision-log comments are issue entries — they obey
|
|
`../issue/SKILL.md`: rule 1 (impersonal and tool-neutral) and rule 4
|
|
(reachable and comprehensible). A later run or user lands on the **comment**, not the
|
|
chat that produced it, so each must be self-contained, reachable from the
|
|
tracker, and free of this loop's own control-flow.
|
|
|
|
- **State a user decision's provenance inline in English** — the
|
|
decision's intent and the date ("chose the mechanism refinement over the
|
|
rewrite" — 2026-06-28) — never a pointer at the chat ("settled in the
|
|
discussion", "decided in-context"). The chat is unreachable from the
|
|
tracker, and typically not English while the issue is an English
|
|
artefact — so state the intent, don't paste the chat's words; quote
|
|
verbatim only where the exact wording is load-bearing, and then
|
|
translated (`../issue/SKILL.md` rule 4). A pointer to the chat strands
|
|
every later reader.
|
|
- **Reproduce each fork's options and chosen rationale inline.** A bare
|
|
label ("Approach B") indexes a set the reader cannot see — spell the
|
|
options out, or name the choice on its own terms.
|
|
- **Tie a later comment to an earlier one by a host-free relative link to
|
|
that comment (`issues/N#issuecomment-M`), or restate the point** —
|
|
never "above" / "logged above" / "the prior comment", which a reader on a
|
|
direct comment-anchor link cannot resolve.
|
|
- **Record the decision, not the dispatch.** The comment logs what was
|
|
decided and why, and may carry a durable, tool-neutral readiness status
|
|
("design settled — ready for spec production"). It never writes this
|
|
loop's own next move into the issue — neither a named skill ("enter
|
|
`specify` from here", "next: dispatch `implement`") nor a role-periphrasis
|
|
for the same hand-off ("hand it to the spec writer next"). The test is
|
|
dispatch vs. status: directing *who runs what next* is out even when it
|
|
names no skill; the work's *condition* (settled, ready, blocked-on) stays.
|
|
Which actor runs next is Step 3/4 of *this* loop, meaningless to a later
|
|
reader who is not the loop; the issue's open/labelled state carries
|
|
"what's next" (`../issue/SKILL.md` rule 1).
|
|
|
|
The provenance block in § Skill-system feedback shows the form:
|
|
provenance written into the issue body, never pointed at.
|
|
|
|
A run that reaches a fork decision without a reference issue to record it
|
|
on is a bug: create the seeding issue first (Step 1.5 mechanic), then
|
|
decide.
|
|
|
|
### The rollback sandbox
|
|
|
|
`main` stays sacrosanct **below the session anchor**. At the start of an
|
|
autonomous run the orchestrator captures the HEAD commit it starts from
|
|
— the last user-ratified state — as the **session anchor**. The anchor is
|
|
that captured revision (a fixed sha), not the live `main` ref: in a git
|
|
worktree — the normal seat of a `/boss` run (§ The run worktree) — the
|
|
run sits on its own branch and the anchor is that branch's base, so a
|
|
`reset` to the anchor only ever moves the session branch and cannot
|
|
reach `main` at all; in the primary clone on `main` (the exception —
|
|
e.g. a repo that forbids worktrees) the two coincide. Everything the
|
|
orchestrator then commits autonomously, this run, and has **not
|
|
pushed**, is its own sandbox above that anchor.
|
|
|
|
Inside the sandbox, and only there, the forward-only rule is relaxed:
|
|
when the orchestrator runs itself into a dead end — `implement` stays
|
|
`BLOCKED` after its re-loops, `audit` or `fieldtest` exposes that an
|
|
earlier derived fork was wrong, a line of work is not salvageable
|
|
forward — it MAY `git reset --hard` back toward the anchor, to the point
|
|
before the wrong turn, and try again differently. The boundaries are
|
|
hard:
|
|
|
|
- **Never below the anchor.** The anchor is the floor. User-ratified
|
|
history is never rewound; the sandbox is only the orchestrator's own
|
|
autonomous commits.
|
|
- **Never a pushed commit.** Pushing hands work to the outside; a pushed
|
|
commit leaves the sandbox and reverts to forward-only (`git revert`),
|
|
never `reset`. In practice the orchestrator neither pushes autonomously
|
|
nor merges the run's branch into `main` (§ The run worktree), so the
|
|
sandbox is local.
|
|
- **Hard-drop, no parking.** A discarded attempt is gone — no
|
|
`attempt-N` branch or tag is kept. The reference-issue thread is its
|
|
trace; the transcript holds the rest. (The user's standing preference:
|
|
what the orchestrator threw away, the user does not want to see.)
|
|
- **Rollback is an escalation response, not a reflex.** It is for a genuine
|
|
dead end, not for flinching at the first agent that returns
|
|
`DONE_WITH_CONCERNS`. Reach for it when forward correction is clearly
|
|
more expensive or less safe than winding back and re-deciding.
|
|
|
|
Bounce back to the user only when:
|
|
|
|
- A queued option requires a real design judgement I have not
|
|
made myself (genuine architectural fork, multiple substantive
|
|
options none of which is clearly default).
|
|
- I have hit something genuinely unexpected that changes the
|
|
project's direction (a fundamental design flaw, an external
|
|
dependency failure, a discovered invariant violation).
|
|
- The user has explicitly asked for a checkpoint.
|
|
- **The `brainstorm` swarm surfaces a divergent direction fork.** A new
|
|
cycle's design runs autonomously through the `brainstorm` swarm, which
|
|
decides the forks it can settle on a cited shared ground and records them on
|
|
the reference issue. What bounces is the residue: a fork the swarm splits on,
|
|
or agrees on with no citable ground (ungrounded-consensus), or one the
|
|
orchestrator's own Step-2 enumeration held open — a genuine **direction
|
|
fork** only the user's preference can settle. A greenfield design *below the
|
|
swarm's grounding floor* (no ledger to cite against) likewise bounces,
|
|
because the swarm cannot run honestly and the work needs a human interview.
|
|
Continuing an open cycle and *starting* a new one are now both autonomous up
|
|
to this residue.
|
|
|
|
**Why this is different from the other three triggers.**
|
|
This is the design-judgement checkpoint the swarm cannot discharge. The
|
|
swarm compacts the discovery — the orchestrator gets back a triaged
|
|
populated space, not a high-context interview transcript — so the old "a
|
|
fresh brainstorm is too high-context to run autonomously" rationale is
|
|
retired (the swarm IS the compaction). What stays genuinely the user's is
|
|
the direction fork itself: a choice no source settles, where a guessed
|
|
default is the reactive-overreach the discipline forbids. Surface it as a
|
|
vetoable problem-state notify naming, in the user's terms, the design choice
|
|
that needs them; the convergent decisions ride along on the reference issue.
|
|
|
|
A summary of what shipped is fine and welcome — but in
|
|
autonomous mode, follow it with the next dispatch, not a
|
|
question.
|
|
|
|
## Notifications
|
|
|
|
Two states call for a notify; nothing else does — plus a third,
|
|
narrow one for spec auto-sign:
|
|
|
|
1. **Done-state.** The queue is empty of autonomously-doable
|
|
items — the cycle closed, the audit ratified, and nothing
|
|
the direction-freedom test clears is left open (or, in a
|
|
user-scoped session, every objective the user named has been
|
|
completed and no autonomously-doable follow-up is queued —
|
|
including ones this run's own closing gate just surfaced; a
|
|
narrow scope reading does not halt the run on a clear,
|
|
fork-free follow-up). A queue holding only user-reserved
|
|
leftovers — `idea`-labelled entries, user-reserved acts — is
|
|
a legitimate done-state; name them in the notify. A remaining
|
|
design fork is not: it bounces as problem-state (state 2). A
|
|
finished sub-goal inside a still-open cycle is *not*
|
|
done-state. If the next iteration is obvious and
|
|
substantive, keep dispatching — "test suite landed",
|
|
"audit clean before close-fixes", "iter N done with N+1 in
|
|
scope" are internal progress, not notify events.
|
|
|
|
2. **Problem-state.** A bounce-back trigger per §"Direction
|
|
freedom" — design fork the orchestrator cannot resolve, an
|
|
unexpected invariant violation, an external dependency
|
|
failure, the user has explicitly asked for a checkpoint, or
|
|
the `brainstorm` swarm surfaced a divergent direction fork
|
|
(or a greenfield design below its grounding floor) that needs
|
|
the user's call.
|
|
|
|
3. **Auto-sign.** The
|
|
orchestrator signed a spec in the user's place and is
|
|
continuing the run — see §"Spec auto-sign". This is the one
|
|
sanctioned mid-flow notify, and it is sanctioned *because it
|
|
carries a decision*: the spec normally needs the user's
|
|
signature, so the user retains a veto over what was signed
|
|
without them. It is not a progress ping — it is the audit
|
|
trail for a gate the user delegated. It does not stop the
|
|
loop.
|
|
|
|
A user-specified stop trigger ("until X is done, then notify")
|
|
counts as done-state only if X is truly the last actionable
|
|
item in the autonomous queue at that moment. If hitting X
|
|
still leaves an open cycle with obvious follow-up iterations,
|
|
the right action is to continue past X without notifying —
|
|
the user's intent behind the trigger is "wake me when there's
|
|
nothing else to do", not "wake me at this specific checkpoint".
|
|
|
|
Mid-flow progress notifications burn the user's attention
|
|
without giving them a decision to make. When in doubt,
|
|
continue.
|
|
|
|
Filing skill-system feedback on the plugin's own tracker
|
|
(§ Skill-system feedback) is likewise not a notify event — it is
|
|
captured, not surfaced.
|
|
|
|
The notification command is `~/.claude/notify.sh` (the user-level
|
|
convention); it receives the message text as a single argument. If it
|
|
is unavailable, fall back to printing the notification in chat.
|
|
|
|
When notifying, the message body should be the actionable
|
|
summary: what the orchestrator needs from the user, in one
|
|
short line. Skip the "hi, I" framing — just the gist. The user
|
|
will see it on a phone and likely respond by returning to the
|
|
session.
|
|
|
|
By default, the orchestrator acts autonomous. The notification
|
|
is the exception, not the rule.
|
|
|
|
## Done-state notifications
|
|
|
|
When the trigger is **done-state** (autonomous work has wrapped
|
|
up, nothing left to do for the user to react to), send one
|
|
text via the configured notification command.
|
|
|
|
The text must be written for the **user-as-reader who did not
|
|
watch the orchestrator work**:
|
|
|
|
- **Language: same as the rest of the repo.** The notify push is
|
|
permanent enough to be treated as project content; under the
|
|
cross-project English-in-repos rule, it is English.
|
|
- **No technical internals.** Don't name crates, function
|
|
identifiers, type names, agent names, or iteration codes
|
|
(`ct.1.7`, `18a`, etc.). Describe the *change in the project*
|
|
— what is now possible, fixed, or visible — not the mechanics.
|
|
- **Name the review handle.** When the run worked in its worktree
|
|
(§ The run worktree), its work sits unmerged on the branch; the
|
|
notify says so and names the branch. The no-internals rule bans
|
|
identifiers the user cannot act on; the branch is the one
|
|
identifier that exists *for* the user's action (review, then the
|
|
ratified merge), so it is carried. A run that bounced before
|
|
entering a worktree has no branch and names none.
|
|
- **No assumption of context.** The user is on their phone and
|
|
has not seen this session. Lead with the result; the *why*
|
|
is fine if it fits in one short clause.
|
|
- **Length: Telegram-pragmatic.** No hard cap, but a few
|
|
sentences, not an essay. If the work covered multiple
|
|
unrelated things, bullet them.
|
|
- **Tone: factual, not performative.** No celebration, no
|
|
"I have successfully…". Just "X works now, Y is fixed, Z is
|
|
new".
|
|
|
|
**Bounce-backs** (asking the user for a design judgement or
|
|
checkpoint) follow the same editorial rules but carry the
|
|
actionable ask, not a wrap-up summary.
|
|
|
|
## Spec auto-sign
|
|
|
|
Under `/boss`, the orchestrator signs a spec in the user's place
|
|
through `specify`'s Step-6 gate, which is owned and defined there.
|
|
(Outside `/boss`, the user signs every spec directly; there is no gate
|
|
to run.) A spec the gate cannot clear escalates to the human sign-off
|
|
pause. The boss-side contract is just this:
|
|
|
|
- **The signature is the `grounding-check` `PASS`, not the
|
|
orchestrator's judgement.** Under `/boss` the autonomous signature is
|
|
the Step-5 `grounding-check` returning `PASS` — an independent
|
|
fresh-context agent's verdict against currently-green tests. "The spec
|
|
looks good to me" is never a signature; that confidence is the exact
|
|
signal the gate refuses to trust. The former obligatory five-lens
|
|
`spec-skeptic` panel is **retired** (baseline tag
|
|
`pre-autosign-rework`); the judgement it used to apply now lives
|
|
upstream, in `specify` Step 1.5's bold-decide stance.
|
|
- **A no-override grounding `BLOCK` is never signed over.** With no human
|
|
in the loop, a grounding `BLOCK` (or `INFRA_ERROR`) cannot be
|
|
overridden, so it routes the spec to the human sign-off pause it would
|
|
have hit anyway. That is the one objective denial of an autonomous
|
|
sign.
|
|
- **Forks are decided upstream, boldly, and recorded.** `specify` Step
|
|
1.5 decides every load-bearing fork it can *derive* an answer for
|
|
(sources, code, existing-design consistency, risk) — pulling an ad-hoc
|
|
`spec-skeptic` lens as a bias-breaker when it is unsure whether its
|
|
leaning is judgement or bias — and records each decision in the run's
|
|
**reference issue** (see § Direction freedom). Only a *pure-preference*
|
|
fork, one only the user's taste can settle, bounces to the human. So a
|
|
spec reaching the sign gate carries no unresolved judgement; the only
|
|
thing the sign verifies is the objective grounding the check already
|
|
verifies. Editorial roughness the old panel would have caught is let
|
|
through deliberately — cheap to patch inline downstream, never worth an
|
|
obligatory five-juror panel on every spec.
|
|
- **On a clean sign, do not stop.** The spec is never committed — it is
|
|
a git-ignored working file, signed by the `grounding-check` PASS.
|
|
Make the sign auditable on the run's **reference issue** (a
|
|
decision-log comment recording that the spec was auto-signed on a
|
|
PASS with no human), fire the auto-sign notify, and continue to
|
|
`planner` in the same run. The notify is informational-with-veto, not
|
|
a pause.
|
|
- **The notify must be vetoable.** It follows the same editorial rules
|
|
as a done-state notify (English, user-as-reader, no iteration codes
|
|
or crate names) with one addition forced by its purpose: it must
|
|
name, in the user's terms, *what capability the signed spec covers*,
|
|
so the user can decide whether to veto. State plainly that the spec
|
|
was signed without them, that the plan is proceeding, and that a
|
|
reply vetoes. One example shape: "Signed off the spec for <plain
|
|
capability> myself and started the implementation plan — reply to
|
|
veto." No internals, but enough identity to act on.
|
|
- **A veto is a forward correction — or, within the run, a rollback.**
|
|
The spec is never a commit (it is a git-ignored working file), so a
|
|
veto is undone forward by shell-`rm`ing (or editing) the spec and
|
|
reverting only the downstream **code** it produced: `git revert` the
|
|
code commits below the session anchor (ratified history), or
|
|
`git checkout` the unstaged work, and file the redirection. *Within*
|
|
the autonomous run, the rollback sandbox (§ Direction freedom) is the
|
|
additional remedy: the orchestrator may hard-reset its own unpushed
|
|
autonomous **code** commits and the work built on them back toward the
|
|
session anchor when it judges the fork was wrong — its own work only,
|
|
never below the anchor, never a pushed commit — and shell-`rm`s the
|
|
git-ignored spec/plan of the abandoned line. The reference-issue thread
|
|
is the only surviving trace of the abandoned attempt.
|
|
|
|
## Skill-system feedback
|
|
|
|
A `/boss` run executes *through* the skill system, so the orchestrator is
|
|
the one actor positioned to notice when the **plugin itself** is the thing
|
|
that is broken — not the project it is working on, but the toolchain doing
|
|
the work. When it hits such a deficiency mid-run, it files it as an issue
|
|
against the **plugin's own tracker** and continues. The forward-queue
|
|
discipline that governs a project governs the plugin too: a shortcoming
|
|
that is not written down is one that recurs on the next run.
|
|
|
|
**What qualifies — a *durable plugin* deficiency.** Two conditions, both
|
|
required: the fault is in the plugin (a SKILL body, an agent, a
|
|
convention, the pipeline/cascade), and it would **recur** rather than
|
|
being a one-off. Positive triggers:
|
|
|
|
- A skill or convention is self-contradictory, or ambiguous enough that
|
|
the orchestrator had to *guess* which reading was intended.
|
|
- A gate or agent returned a clearly wrong verdict traceable to a gap in
|
|
its own instructions — not to a project bug (that is `debug`, on the
|
|
project tracker).
|
|
- The entry cascade or pipeline had no path for a situation the
|
|
orchestrator legitimately reached, forcing it to improvise.
|
|
- An agent-template field, a status-protocol value, or a cross-reference
|
|
is missing, wrong, or dangling.
|
|
|
|
**What does NOT qualify.** One-off project-specific friction; a project's
|
|
own missing config or facts; anything honestly attributable to the
|
|
*project* rather than the *plugin*. When unsure whose fault it is, it is
|
|
the project's — do not file against the plugin on a hunch. The evidence
|
|
gate makes this objective: if you cannot point to the offending
|
|
`path:line` *inside the plugin* that produced the wrong reading, it is not
|
|
plugin feedback — route it as a project bug (`debug`) or let it go.
|
|
|
|
**Mechanics.**
|
|
|
|
- **Target the plugin's own tracker, not the project's.** The run's
|
|
reference issue lives on the *project* tracker (§ Direction freedom);
|
|
this is a *separate* artefact on the *plugin's* tracker. Append
|
|
`--repo <plugin-slug>` to each `tea issues` call (the override flag the
|
|
`issue` skill documents). The slug is this very plugin's repository —
|
|
derive it from the plugin checkout's git remote
|
|
(`git -C ~/dev/skills remote get-url origin`, the home the skills are
|
|
symlinked from), currently `Brummel/Skills`, so a fork or rename needs
|
|
no edit here.
|
|
- **When the project *is* the plugin, the two trackers still do not
|
|
coincide.** The skills meta-repo is not driven through `/boss` — it has
|
|
no project-facts queue (Step 1 finds no tracker) and is worked directly,
|
|
never through its own pipeline — so "the plugin's tracker" and "the
|
|
project's tracker" never resolve to the same place in a real run. (If a
|
|
run ever did execute with the plugin as its project, plugin feedback
|
|
would still take its *own* issue, distinct from the run's reference
|
|
issue, carrying the provenance block.)
|
|
- **Write it through `../issue/SKILL.md`.** Imperative title, declarative
|
|
voice, validated-or-flagged (cite the offending `path:line` inside the
|
|
plugin), self-contained. Work-type label from the normal vocabulary —
|
|
usually `idea`, `bug` if a gate misfired, `feature` if a path is
|
|
missing. No label is minted for provenance.
|
|
- **Mark the provenance in the body.** The body opens with a block stating
|
|
plainly that `/boss` filed it autonomously and which project the run was
|
|
on, so any later reader knows no human vetted it at filing time — then
|
|
the motivation and the problem description:
|
|
|
|
````
|
|
> Filed autonomously by the `/boss` orchestrator while running on
|
|
> project "<project>". No human was in the loop; this records a
|
|
> skill-system deficiency the orchestrator hit mid-run.
|
|
|
|
## Motivation
|
|
Why it matters — what the ambiguity or gap cost this run.
|
|
|
|
## Problem
|
|
The deficiency itself, with the offending `path:line` in the plugin.
|
|
````
|
|
|
|
- **Dedupe, then file immediately.** The dedupe check is a gate in front
|
|
of the create, not an optional sibling step. One-shot it first — list
|
|
the plugin tracker's issues (`tea issues ls --repo <plugin-slug>`, open
|
|
*and* recently-closed). On an open match, comment there instead of
|
|
opening a duplicate. On a *closed* match, re-open or comment only if the
|
|
deficiency has clearly regressed, and treat a `wontfix`/by-design close
|
|
as a signal **not** to re-file — recurrence is exactly what the trigger
|
|
selects for, so a re-hit is expected, and re-litigating a settled close
|
|
is not the job. Otherwise create, the moment the deficiency is observed
|
|
(the context is richest then), and resume. Filing is a side-effect; it
|
|
never stops the loop.
|
|
|
|
**Never a substitute for a bounce-back.** Filing plugin feedback
|
|
discharges no decision, so it can never stand in for one the user owns. A
|
|
situation can match *both* a plugin deficiency *and* a bounce-back trigger
|
|
(§ Direction freedom) — most sharply when a self-contradictory skill
|
|
leaves a *load-bearing* decision the orchestrator cannot derive past, or
|
|
when the missing pipeline path is really a new cycle. There the
|
|
orchestrator **bounces**, and may file the plugin issue *as well*: the
|
|
issue captures the plugin gap, the bounce captures the call the user still
|
|
owns. The capturable deficiency (a route-around-able wrong verdict, an
|
|
improvised-past missing path, a dangling cross-reference) is
|
|
file-and-continue; the blocking one is file-*and*-bounce. "The cascade had
|
|
no path, so I'll file a gap and keep going" is the exact dodge this
|
|
forbids.
|
|
|
|
**Not a notify event.** Filing skill-system feedback is neither a
|
|
bounce-back (it asks the user for no decision) nor done-state. The filed
|
|
issue *is* the durable record; the user reviews the plugin tracker at
|
|
leisure. Notifying about it mid-run would be exactly the attention-burning
|
|
progress ping § Notifications forbids. It is also not a new outward-facing
|
|
action needing consent: it is the same issue-tracker write authority the
|
|
run already uses for its reference issue, pointed at a different repo.
|
|
|
|
**`/boss`-only.** In interactive mode the user is present, so a noticed
|
|
shortcoming is simply surfaced in chat and filed via the `issue` skill if
|
|
the user wants it — there is no autonomous filing to govern.
|
|
|
|
## Common Rationalisations
|
|
|
|
| Excuse | Reality |
|
|
|--------|---------|
|
|
| "Iteration just landed cleanly, let me notify so user can see" | Mid-flow notifications burn user attention without giving them a decision to make. Iteration-clean is internal progress, not a notify event. |
|
|
| "Sub-goal of the cycle is done, that counts as done-state" | Done-state is queue-empty-of-autonomously-doable, not sub-goal-complete. If the next iteration is obvious and substantive, keep dispatching. |
|
|
| "Primary task done, the audit/fieldtest findings are filed as issues — that's a wrap, notify done-state" | Filing the findings *repopulated the queue* — and findings routed inline instead (a `bug` → `debug`, a drift item → tidy iteration) are queue work all the same. Each follow-up takes the direction-freedom test like any other item: a clear, fork-free bug or mechanical edit continues the loop — being discovered after the primary task is not a stopping reason. Only a residue of `idea` items and user-reserved acts is a legitimate done-state; a remaining fork bounces instead. |
|
|
| "The picked item is tiny — skip the worktree, work on `main` directly" | The worktree is per-run, not per-item, and it is entered before the first dispatch — its cost is one `EnterWorktree`, once. Item size never decides where autonomous commits land; `main` moves only via the user-ratified merge (§ The run worktree). |
|
|
| "Top of the backlog has two equally good options, I'll just pick one" | If both are substantive and the choice is non-obvious, that's a real fork — bounce back. The cost of a wrong pick (working-tree discard) is higher than the cost of one short ping to the user. |
|
|
| "User said 'until X then notify', X just completed, notify now" | Check whether X was actually the last actionable thing. If hitting X leaves an open cycle with obvious follow-up, the user's intent was "wake me when there's nothing else to do" — continue. |
|
|
| "Notify can name the iteration code — user will figure out what it means" | No. The notify text is for the user-as-reader who did not watch the orchestrator work. Iteration codes, crate names, function identifiers, type names — all internal, all banned. |
|
|
| "The previous cycle closed cleanly and the next backlog item is obvious — just dispatch `brainstorm` and keep going" | Dispatching `brainstorm` IS now the autonomous move — its swarm decides the forks it can settle on a cited ground and records them. What you may not do is auto-decide a *divergent direction fork* the swarm could not ground; that bounces. Dispatch the swarm, decide the convergent forks, bounce only the residue. |
|
|
| "The swarm all converged, so I can auto-decide the whole design and move on" | Only forks converged on a *cited shared ground* are decided. Same-model stances agreeing with no citable ground is ungrounded-consensus — a direction fork that bounces, not a decision. Auto-deciding bare agreement is the false-convergence trap that ships the user's once-per-project fork past them. |
|
|
| "Feature work, so route it to `brainstorm` — that's the safe default" | The entry paths are an ordered cascade, none the default. Routing a settled design to `brainstorm` re-litigates decided choices; routing a test-specifiable item there wastes the test path; routing a behaviour-preserving type-edit there is the heavy-path gravity well this whole reflection exists to break. Walk the cascade and take the first matching positive trigger. The only tilt toward `brainstorm` is a genuinely unresolved fork — and that is a fork, not a default. |
|
|
| "It's just a mechanical rename across N files — run the full implement loop on it" | That is the `compiler-driven` arm's job, not the heavy loop. Route it there; the type checker enumerates the sites, and the done-signal (clean build AND suite green unchanged) is the gate. Funnelling a behaviour-preserving edit through the full per-task loop is the disproportionality the cascade was added to fix. |
|
|
| "The compiler-driven edit built clean — that's the done-signal, commit" | Clean build is only half. The done-signal is clean build **AND suite green unchanged**. A behaviour change can build clean; the unchanged-green suite is what catches it. No suite run, no commit — and if the suite isn't green-unchanged, bounce to `debug`. |
|
|
| "It's a bug but the fix is a one-line type edit — route it `compiler-driven`" | No. An observed bug is first in the cascade → `debug`, RED-first, regardless of how mechanical the fix looks. The bug-gate sits before the type-edit arm precisely so a regression cannot launder itself around RED-first. |
|
|
| "The issue is exhaustive but it's a new cycle, so bounce to the user before `specify`" | `specify` direct-entry is bounded and autonomously dispatchable — a settled design needs production, not discovery; don't route it through `brainstorm` at all. And even an *open* design no longer blanket-bounces: its swarm runs autonomously and bounces only a divergent direction fork. The bounce is for an unresolved *direction*, never for "it's new". |
|
|
| "`tdd` is the secondary skill, `brainstorm` is the real entry" | All entry paths are always available. The choice among them is the cascade, walked per item — not a habit of treating `brainstorm` as primary and the lighter arms as exceptions. The lighter arms exist to be reached; reaching past them by elimination is the failure the verification axis was added to prevent. |
|
|
| "This spec is clearly good — I'll sign it on my judgement" | Your judgement is not the signature; the Step-5 `grounding-check` `PASS` is. Run grounding and sign on the PASS. A no-override grounding `BLOCK` routes to the human — never signed over on confidence. (The old unanimous `spec-skeptic` panel is retired; do not re-introduce it as a gate.) |
|
|
| "There's an open fork — I'll bounce to `brainstorm` to be safe" | If you can *derive* an answer (sources, code, consistency, risk), decide it boldly and record it in the reference issue. Only a *pure-preference* fork bounces. Bouncing a derivable fork is exactly the timidity the bold stance retired; unsure if your leaning is bias, pull one ad-hoc `spec-skeptic` lens, then decide. |
|
|
| "I derived a fork but didn't bother logging it on the issue" | The reference-issue comment is mandatory. It is the user's only window into a call made without them — and, because a rollback hard-drops the commits, the only surviving trace of the attempt. No reference issue, no fork decision: create the seeding issue first. |
|
|
| "The user was in the discussion, so 'as decided in-context / above' is enough on the issue" | The decision log is read later by a run or user who was NOT in that discussion and may land on the comment alone. State the user's decision intent in English + date inline, reproduce the fork's options and rationale, and link any sibling comment by a host-free relative link (`issues/N#issuecomment-M`) — never "above" / "in-context". The chat is not reachable from the tracker, and not English while the issue is (`../issue/SKILL.md` rule 4); quote the exact words only where the wording is load-bearing, and then translated. |
|
|
| "I resolved the fork — I'll note that `specify` runs next so the thread is actionable" | The decision log records the decision and a tool-neutral readiness status, never this loop's dispatch. Directing who runs what next is session control-flow whether the skill is named ("dispatch `implement` next") or periphrased ("hand it to the spec writer") — meaningless to a later reader who isn't the loop, and declarative phrasing doesn't save it; "what's next" lives in the issue's open/labelled state (`../issue/SKILL.md` rule 1). |
|
|
| "Auto-sign let me continue, so I don't need to notify — it's just progress" | The auto-sign notify is mandatory and carries a decision (the user's veto over a signature made without them). It is the one sanctioned mid-flow notify precisely because it is not progress — it is the audit trail for a delegated gate. |
|
|
| "I hit a gap in the skill system itself — I should notify the user about it" | No. File it on the plugin's own tracker with an autonomous-provenance body block and continue (§ Skill-system feedback). It needs no mid-run decision, so notifying would be the attention-burning progress ping the notify discipline forbids; the filed issue is the durable record. |
|
|
| "Something was awkward this run — file it against the plugin tracker" | Only a *durable plugin* deficiency qualifies: the fault is the plugin's (not the project's) and it would recur on the next run. One-off project friction is not plugin feedback; when unsure whose fault it is, it is the project's. File on the plugin tracker (never the project's), dedupe against its issues first, and mark provenance in the body — never with a new label. |
|
|
| "The cascade had no path here — file a plugin issue and keep going" | If that same situation needs a design call only the user can make (trigger 1) or is a new cycle (trigger 4), filing the plugin gap does NOT discharge the bounce-back. Bounce first; file the gap too (§ Skill-system feedback). Plugin feedback is captured-not-surfaced precisely because it carries no decision — so it can never stand in for one that does. |
|
|
|
|
## Red Flags — STOP
|
|
|
|
- About to send a notify on an internal-progress event (test suite landed, audit clean before close-fixes, iter N done with N+1 in scope).
|
|
- About to declare done-state while the queue holds a follow-up that passes the direction-freedom test — including one this run's own closing gate just surfaced. Primary-task-complete is a sub-goal; "discovered after the primary task" and "outside the originally discussed tickets" are not stopping reasons. (The inverse holds too: a queue of only `idea` items and user-reserved acts IS done-state — do not grind through user-reserved work to avoid the notify; a remaining design fork bounces as problem-state instead.)
|
|
- About to dispatch the next skill without checking that the previous output was actually good.
|
|
- About to dispatch substantive work while sitting on the primary clone's `main` checkout — the run's work belongs in its worktree (§ The run worktree); enter it before the first dispatch.
|
|
- About to merge the run's worktree branch into `main` — or push it — without the user's review; the merge is human-in-the-loop, never autonomous, and no pull request is opened.
|
|
- About to autonomously dispatch in a session where the user did NOT type `/boss`.
|
|
- About to send a notify that names a crate, an iteration code, or an agent.
|
|
- About to bounce back at every iteration boundary "just to be safe" — that's reactive deference, not direction freedom.
|
|
- About to *auto-decide* a divergent direction fork the `brainstorm` swarm could not ground (or could only agree on with no citable ground) instead of bouncing it — or, conversely, bouncing the whole fresh `brainstorm` "to be safe" instead of running its swarm autonomously and bouncing only the divergent residue.
|
|
- About to route feature work to `brainstorm` without walking the Entry-path cascade — defaulting to it because it "feels safer" than the lighter arms, rather than taking the first matching positive trigger. Routing a *settled* design, a *test-specifiable* item, or a *behaviour-preserving type-edit* to `brainstorm` is as much a failure as skipping discovery on an open one.
|
|
- About to route an observed bug to the `compiler-driven` arm because "the fix is mechanical" — a regression is `debug`, RED-first; the bug-gate is first in the cascade for exactly this reason.
|
|
- About to route a behaviour-encoding change to `compiler-driven` because it "looks mechanical" — apply the straddle rule: if the change encodes new behaviour it is `tdd` / `spec-driven`, and doubt means it carries behaviour.
|
|
- About to accept a `compiler-driven` edit on a clean build without confirming the suite is green *unchanged* — the conjunction is the done-signal; a green-but-wrong change builds clean.
|
|
- About to sign a spec under auto-sign on confidence rather than on the Step-5 `grounding-check` `PASS` that is the autonomous signature; or signing over a no-override grounding `BLOCK` / `INFRA_ERROR` instead of routing it to the human sign-off pause.
|
|
- About to re-introduce the retired `spec-skeptic` panel as a sign gate (a unanimous five-juror pass as a precondition) — it is now only the optional Step-1.5 bias-breaker; or to run any auto-sign path outside a `/boss` session, or to skip the mandatory auto-sign notify after signing.
|
|
- About to *decide* a fork that hangs on pure user preference (no derivable better) instead of bouncing it — or its inverse, bouncing a *derivable* fork to `brainstorm` out of timidity.
|
|
- About to make a fork decision without recording it on the run's reference issue, or to run autonomously with no reference issue at all.
|
|
- About to record a fork decision that points at the chat ("settled in the discussion", "decided in-context") or at an earlier comment by "above" / "logged above" — the decision log is tracker-reachable per `../issue/SKILL.md` rule 4: state the provenance intent in English and reproduce the options inline, and link a sibling comment by a host-free relative link (`issues/N#issuecomment-M`).
|
|
- About to write this loop's next dispatch into a decision-log comment — whether a skill is named ("enter `specify` from here", "next: dispatch `implement`") or periphrased ("hand it to the spec writer next") — instead of a tool-neutral readiness status; which actor runs next is this loop's Step 3/4, not an issue fact (`../issue/SKILL.md` rule 1).
|
|
- About to `git reset` below the session anchor, or to `reset` a commit that has been pushed — the rollback sandbox is the orchestrator's *own unpushed* commits above the anchor only; user-ratified and pushed history is forward-only (`git revert`).
|
|
- About to notify the user about a skill-system deficiency instead of filing it on the plugin's own tracker and continuing (§ Skill-system feedback) — it is captured, never a notify event.
|
|
- About to file plugin feedback for one-off project friction rather than a durable plugin deficiency, against the *project's* tracker instead of the plugin's, without deduping against the plugin's issues, or marked with a new provenance label instead of the body block.
|
|
- About to file a plugin-feedback issue *instead of* a due bounce-back — filing captures the gap but discharges no decision; if a bounce-back trigger also fires, bounce (and file the gap too).
|
|
|
|
## Cross-references
|
|
|
|
- **Skill system index:** `../README.md` — skill table, agent
|
|
roster, pipeline diagram.
|
|
- **Universal rules:** the project's `CLAUDE.md` — orchestrator
|
|
role boundaries, commit discipline, design rationale,
|
|
authority over skills, feature acceptance, RED-first for bugs.
|
|
Plus the user-level `~/.claude/CLAUDE.md` (identity/security
|
|
layer, loaded in every session, above the project file) — it
|
|
carries constraints that bind autonomous runs too, including
|
|
external-service-consent rules that `/boss` does not lift.
|
|
- **Queue:** the project's issue tracker — its CLAUDE.md project
|
|
facts name the repo slug, the browsable URL, and the list command.
|
|
- **Issue-writing conventions:** `../issue/SKILL.md` — used both for the
|
|
run's reference issue on the *project* tracker and for skill-system
|
|
feedback filed on the *plugin's own* tracker (§ Skill-system feedback).
|
|
- **Worktree convention:** `../docs/conventions.md` § Git discipline —
|
|
substantive work in a git worktree, user-ratified merge, no pull
|
|
request; § The run worktree fixes the run-level mechanics.
|
|
- **Glossary write-rule:** `../docs/glossary-convention.md` —
|
|
record-reality discipline for the only autonomous glossary writer.
|
|
- **Spec auto-sign gate:** owned by `../specify` Step 6 — under `/boss`
|
|
the autonomous signature is the Step-5 `grounding-check` `PASS`. The
|
|
former obligatory `spec-skeptic` panel is retired; that agent
|
|
(`../specify/agents/spec-skeptic.md`) survives as the optional
|
|
Step-1.5 bias-breaker. See `../docs/conventions.md`.
|
|
- **Downstream skills dispatched:** `../brainstorm`,
|
|
`../specify` (spec-production core; autonomously dispatchable for a
|
|
settled design), `../planner`, `../implement`, `../audit`,
|
|
`../fieldtest`, `../debug`, `../tdd` (test-specifiable feature,
|
|
always available; autonomously dispatchable like `../debug`),
|
|
`../docwriter`.
|
|
- **Compiler-driven arm:** the lighter `compiler-driven` cascade arm and
|
|
its observe-then-bounce executor are owned by `../implement` ("The
|
|
compiler-driven arm") and shipped as the `compiler-driven-edit`
|
|
workflow. The selector arm here and that executor are co-located on
|
|
purpose: a future edit re-routing the light path back through the full
|
|
loop changes both cross-references and is a visible regression.
|