fix(boss): done-state is queue-empty-of-autonomously-doable, not primary-task-complete

A /boss run whose closing gate (audit / milestone fieldtest) surfaces new
follow-up work no longer stops at a manufactured done-state: the
follow-ups — routed inline or filed onto the tracker — re-enter the queue
and take the direction-freedom test, and the loop continues onto the
autonomously-doable subset. Being discovered after the primary task, or
falling outside the originally discussed scope, is not a stopping reason.

The done-state check gains its two edges everywhere it is stated
(Overview, exit list, Iron Law, Step 1, Step 4, notify state 1):

- closing-gate follow-ups re-enter the queue; primary-task-complete is a
  sub-goal, never a done-state;
- a queue of only user-reserved leftovers (idea items, user-reserved
  acts) IS a legitimate done-state, named in the notify — while a
  remaining design fork stays a bounce-back (triggers 1/4, problem-state
  notify), never a done-state wrap-up; when both remain, the bounce
  governs.

Plus a rationalisation-table row and a red flag pinning the observed
failure shape (file the fieldtest findings, then declare done).

closes #21
This commit is contained in:
2026-07-02 12:34:04 +02:00
parent 6bfec9655c
commit 52c87d19ce
+71 -21
View File
@@ -13,8 +13,9 @@ 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 is empty (done-state) or a
real design fork forces a bounce-back to the user.
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;
@@ -44,8 +45,8 @@ 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 is empty and the done-state procedure has
fired).
- 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.
@@ -54,7 +55,7 @@ re-enters by typing `/boss` again.
```
NO AUTONOMOUS DISPATCH OUTSIDE A `/boss` SESSION.
DONE-STATE = QUEUE EMPTY, NOT SUB-GOAL COMPLETE.
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
@@ -83,8 +84,10 @@ 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: skip to Step 5
(done-state). Do not invent work; an empty queue is a real
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
@@ -245,9 +248,35 @@ For each dispatched skill's result, decide:
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** — queue is empty AND the cycle is fully
ratified (audit drift-clean, fieldtest clean if applicable).
Go to Step 5. A `/boss` done-state means this run has nothing
- **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, 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
@@ -284,6 +313,19 @@ 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
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
@@ -416,16 +458,22 @@ question.
Two states call for a notify; nothing else does — plus a third,
narrow one for spec auto-sign:
1. **Done-state.** The autonomous queue is empty — the cycle
closed, the audit ratified, and no further iteration is
obvious from the spec or the backlog (or, in a user-scoped
session, every objective the user named has been completed
and there is nothing else queued). 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.
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
@@ -685,7 +733,8 @@ the user wants it — there is no autonomous filing to govern.
| 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, not sub-goal-complete. If the next iteration is obvious and substantive, keep dispatching. |
| "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. |
| "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. |
@@ -710,6 +759,7 @@ the user wants it — there is no autonomous filing to govern.
## 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 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.