boss: migration pilot — autonomous orchestrator mode generalised

First skill migrated from AILang's in-tree skills/. boss carries
the autonomous orchestrator authority (god-mode: dispatches every
other skill, decides done-state vs bounce-back), so it is the
load-bearing pilot for the migration pattern.

Profile schema gains three slots that boss needs:

- `git.issue_tracker.url`       — browsable issue list URL
- `git.issue_tracker.list_cmd`  — shell command listing open issues
- `notifications.command`       — script invoked on done-state /
  bounce-back; falls back to chat if empty

AILang-specific bits dropped from the prose:
- AILang/Gitea URL + tea CLI hardcoding → profile slots
- `design/contracts/0004-feature-acceptance.md` cross-reference
  → project CLAUDE.md (not the plugin's concern)
- "Boss" terminology → "orchestrator" (the plugin term; "Boss"
  was AILang vocabulary)
- "Brummel-as-LLM" → "the orchestrator"
- "milestone" → "cycle" (the profile's vocabulary slot)

Universal substance preserved verbatim: Iron Law, the five
process steps, the four bounce-back triggers + new-cycle
rationale, notification protocol, done-state editorial rules,
Common Rationalisations, Red Flags. No discipline-prose compression.

design/out-of-scope claim retracted: boss DOES generalise, and
its body now demonstrates how — the queue mechanic is a single
shell-command slot, not a transport-coupled contract.

skills/README.md flags boss as the landed pilot; the other seven
skills follow once the pattern is approved.
This commit is contained in:
2026-05-28 15:43:39 +02:00
parent de26df1727
commit 9e10e9dfee
6 changed files with 319 additions and 15 deletions
+2 -1
View File
@@ -14,7 +14,7 @@ live in a small per-project profile file
## What's in the box
Seven skills, each with the agents it primarily dispatches:
Eight skills, each with the agents it primarily dispatches:
| Skill | Trigger | Output | Mandatory? |
|-------|---------|--------|------------|
@@ -25,6 +25,7 @@ Seven skills, each with the agents it primarily dispatches:
| `debug` | Bug observed | RED test in working tree + cause analysis | Mandatory RED-first for any bug |
| `fieldtest` | Orchestrator-dispatched post-audit, surface-touching cycle | example fixtures + friction spec | Optional |
| `docwriter` | API surface stable across N cycles | rustdoc / docstring sweep | Optional |
| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back | User-invoked, never auto-dispatched |
Vocabulary is configurable. AILang calls a cycle a *milestone*
and a sub-cycle an *iteration*; your project may call them
+5 -9
View File
@@ -108,13 +108,9 @@ The relationship:
## What's out of scope for this plugin
- **Boss/autonomous-orchestrator mode**: AILang's `boss` skill
is gated to a user-invoked `/boss` for autonomous queue
execution. Whether that generalises across projects is
unclear (queue mechanics depend on issue-tracker semantics).
Not in the initial skeleton; possibly added later as
`skills/boss/` if a cross-project autonomous mode crystallises.
- **Issue-tracker integration**: the plugin can read the
profile's `issue_tracker.kind` and adjust commit-marker
suggestions, but does not directly call Gitea / GitHub /
Linear APIs.
profile's `issue_tracker.kind` and `issue_tracker.list_cmd`
and invoke the configured listing command, but does not
directly call Gitea / GitHub / Linear APIs. The `boss` skill
uses the configured shell command for queue reads, so the
plugin remains transport-agnostic.
+10
View File
@@ -82,8 +82,16 @@ read as opaque strings the agent should fetch / execute, e.g.
| `only_orchestrator_commits` | bool | `true` | If true, no agent commits; the orchestrator commits. |
| `issue_tracker.kind` | enum | `none` | One of `gitea`, `github`, `linear`, `none`. |
| `issue_tracker.close_marker` | string | `"closes #N"` | Marker the orchestrator includes in commit bodies to auto-close issues. |
| `issue_tracker.url` | string | (empty) | Human-browsable URL of the issue list — surfaced in notifications and cross-references. |
| `issue_tracker.list_cmd` | string | (empty) | Shell command that lists open issues. Used by the `boss` skill to read the forward queue. Examples: `tea issues ls --repo X/Y --state open`, `gh issue list --repo X/Y --state open`. |
| `protected_branches` | list | `[main]` | Branches that are sacrosanct in the same sense as main. |
## `notifications`
| Key | Type | Default | Description |
|-----------|--------|---------|-------------|
| `command` | string | (empty) | Shell command the `boss` skill invokes on done-state and bounce-back. Receives the message text as a single argument. Example: `"~/.claude/notify.sh"`. If empty, the orchestrator falls back to printing the notification in chat. |
## `pipeline`
Per-phase configuration. Each phase has its own sub-map.
@@ -106,6 +114,8 @@ pipeline:
debug:
trigger: bug # observable misbehaviour
red_first: true # RED test before any fix
boss:
user_invoked: true # autonomous-orchestrator mode, /boss
```
Phases not listed are disabled for the project. A project that
+9 -5
View File
@@ -6,16 +6,17 @@ live with their dispatching skill, not in a parallel top-level
directory — this is what makes the "no orphan agents" rule
structurally true rather than only documented.
The skeleton commit ships this directory empty. The actual
skill bodies and agents are migrated from AILang's in-tree
`~/dev/ailang/skills/` and generalised against the profile
schema (`../docs/profile-schema.md`) and the agent template
(`../docs/agent-template.md`) in **iteration 1**.
Migration from AILang's in-tree `~/dev/ailang/skills/` runs in
iteration 1. The `boss` skill is the migration pilot
(landed); the remaining seven skills follow once the pattern
is approved.
Expected layout after migration:
```
skills/
├── boss/ (pilot: landed)
│ └── SKILL.md
├── brainstorm/
│ ├── SKILL.md
│ └── agents/
@@ -51,6 +52,9 @@ skills/
└── docwriter.md
```
`boss` has no agents — it is itself the dispatcher of the
others, not a dispatcher-of-subagents.
`install.sh` symlinks each skill's directory into
`~/.claude/skills/<name>` and each skill's `agents/`
subdirectory into `~/.claude/agents/<name>`, so Claude Code's
+287
View File
@@ -0,0 +1,287 @@
---
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 is empty (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 is empty 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, NOT SUB-GOAL COMPLETE.
BOUNCE-BACK ONLY ON THE FOUR NAMED TRIGGERS.
A NEW CYCLE NEVER STARTS AUTONOMOUSLY — IT IS A BOUNCE-BACK.
```
Universal rules (only-orchestrator-commits, main-is-sacrosanct,
language, RED-first for bugs) come from the project's `CLAUDE.md`
and apply regardless of mode. This skill does not restate them.
## The Process
### Step 1 — Read the queue
The project's issue tracker is the forward queue. Read open
issues via the command configured under
`git.issue_tracker.list_cmd` in the project profile. If that
slot is empty, the project 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
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.
### Step 3 — Dispatch the appropriate downstream skill
Pipeline:
```
brainstorm → planner → implement → audit → fieldtest
+
debug (bug-triggered)
+
docwriter (post-stability)
```
Match the chosen item to the right entry skill. If a cycle is
new and no spec exists: **bounce back first** (per §"Direction
freedom" trigger 4 — new cycles never start autonomously); only
after the user green-lights the cycle (and the session shape)
does `brainstorm` get dispatched. 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`. Read each
skill's `SKILL.md` trigger section if unsure.
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.
### 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** — queue is empty AND the cycle is fully
ratified (audit clean, fieldtest clean if applicable). Go to
Step 5.
### 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. Wrong calls are contained,
not recovered: only the orchestrator commits, and only when the
working-tree state is consistent — so bad work doesn't reach
main in the first place. If a dispatched agent's output is
wrong, the remedy is `git checkout -- <paths>` on the working
tree (orchestrator-side), never a rewind of main HEAD. main is
forward-only.
The cost of asking "what should I do next" — context-switch for
the user, latency on my side — exceeds the expected cost of
discarding a bad working-tree state. So when the queue is
non-empty and the path is clear, just pick and proceed.
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 next item on the queue is a new cycle** — i.e. a top-
level work container (in the project's vocabulary: milestone,
epic, release, sprint root) that has no spec file yet and
would require dispatching `brainstorm` to even begin.
Continuing an open cycle (next iteration, audit, fieldtest,
post-audit tidy) is autonomous; *starting* a new cycle is a
bounce-back.
**Why this is different from the other three triggers.**
Cross-cycle work is high-context work. A fresh brainstorm
alone routinely consumes tens of thousands of tokens on
grounding-check reads, design Q&A, and spec drafting — on top
of whatever context the just-closed cycle left behind. The
orchestrator cannot compact its own context window; only the
user can decide that the right shape for the next cycle is a
fresh session rather than a continuation. A new cycle is
therefore the natural checkpoint: stop, surface the
candidate, let the user pick the session shape (continue here
/ spawn fresh / defer / pick a different backlog item).
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:
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.
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 next backlog item is a new cycle (no spec yet) and
starting it would force a fresh `brainstorm`.
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.
The notification command is configured under
`notifications.command` in the project profile and receives the
message text as a single argument. If the profile does not
configure one, 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.
- **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.
## 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, not sub-goal-complete. If the next iteration is obvious and substantive, keep dispatching. |
| "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" | No. Starting a new cycle is itself a bounce-back. A fresh `brainstorm` is high-context work, and the orchestrator cannot compact its own context — only the user can decide whether the next cycle wants a fresh session or a continuation of this one. The "obviousness" of the candidate is irrelevant; the *cross-cycle hop* is the checkpoint, not the topic choice. |
| "It's the same broad area as the cycle I just closed, that's not really a new cycle" | If there is no spec file for it yet and it would route through `brainstorm` to get one, it IS a new cycle for this rule's purposes. The rule keys on "needs a fresh spec", not on subjective continuity. |
## 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 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.
- About to bounce back at every iteration boundary "just to be safe" — that's reactive deference, not direction freedom.
- About to dispatch `brainstorm` on a backlog issue that does not yet have a spec file, without first bouncing back to the user. New cycles never start autonomously.
## 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.
- **Queue:** the URL configured under `git.issue_tracker.url` in
the profile; CLI command at `git.issue_tracker.list_cmd`.
- **Downstream skills dispatched:** `../brainstorm`,
`../planner`, `../implement`, `../audit`, `../fieldtest`,
`../debug`, `../docwriter`.
+6
View File
@@ -44,6 +44,11 @@ git:
issue_tracker:
kind: none # gitea | github | linear | none
close_marker: "closes #N"
# url: "" # human-browsable issue list URL
# list_cmd: "" # e.g. "tea issues ls --repo X/Y --state open"
notifications:
# command: "" # e.g. "~/.claude/notify.sh"; boss falls back to chat if empty
pipeline:
brainstorm: { gates: [planner] }
@@ -51,5 +56,6 @@ pipeline:
implement: {}
audit: { mandatory_at: cycle_close }
debug: { trigger: bug, red_first: true }
# boss: { user_invoked: true } # autonomous orchestrator mode, /boss
# fieldtest: { boss_only: true, when: surface_touch }
# docwriter: { boss_only: true, when: api_stable_across_n_cycles }