diff --git a/.claude/skills/boss b/.claude/skills/boss new file mode 120000 index 0000000..7bc6e12 --- /dev/null +++ b/.claude/skills/boss @@ -0,0 +1 @@ +../../skills/boss \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md index ccf1f9b..8e42608 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,6 +48,12 @@ are sharper tools, not a replacement for orchestrator judgement. Specs go to `docs/specs/.md`, plans to `docs/plans/.md`. +Autonomous orchestrator mode — picking the next iter from +`docs/roadmap.md` and looping until done-state — is gated to the +user-invoked `/boss` skill (`skills/boss/SKILL.md`). Outside +`/boss`, the default is interactive collaboration: the user asks, +Claude responds, Claude stops. + ## My role: orchestrator I am the **orchestrator** of this project, not the implementer. The @@ -167,112 +173,6 @@ appeal does not count; neither does human ergonomics. Full criterion lives in `docs/DESIGN.md` ("Feature-acceptance criterion") and is applied as a gate by `skills/brainstorm/SKILL.md` during spec writing. -### Direction freedom - -I have authority to choose the next iteration, refactor, or feature -without asking. Wrong calls are contained, not recovered: only the -Boss 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 -- ` on -the working tree (Boss-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. - -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 milestone - closed, the audit ratified, and no further iteration is obvious - from the spec or the roadmap (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 - milestone 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 I cannot resolve, an unexpected - invariant violation, an external dependency failure, or the - user has explicitly asked for a checkpoint. - -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 milestone with obvious follow-up iters, 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 him a decision to make. When in doubt, continue. - -~/.claude/notify.sh "Text" - -When notifying, the message body should be the actionable -summary: what I need from them, in one short line. Skip the -"hi, I" framing — just the gist. The user will see it on phone -and likely respond by returning to the session. - -By default, I act autonomous. The notification is the -exception, not the rule. - -### Done-state notifications: WhatsNew.md - -When the trigger is **done-state** (autonomous work has wrapped -up, nothing left to do for the user to react to), the procedure -is two-step and the two outputs share one text: - -1. Append a new entry to `docs/WhatsNew.md` (newest at the bottom, - append-only — same chronological convention as the per-iter journals). -2. Send the same text via `~/.claude/notify.sh`. - -The text must be written for the **user-as-reader who did not -watch me work**: - -- **Language: English.** Same as the rest of the repo; both - WhatsNew.md and the Notify push are permanent enough to be - treated as project content. -- **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 his 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) are *not* done-state and do **not** produce a -WhatsNew entry — they stay as Notify-only. - -Format of a WhatsNew entry: a `## YYYY-MM-DD — ` -heading followed by the message body. The body must match the -Notify text verbatim. - ## Bug fixes — TDD, always Bug fixes are RED-first, autonomous, no orchestrator gate. See diff --git a/bench/orchestrator-stats/2026-05-12-iter-boss.json b/bench/orchestrator-stats/2026-05-12-iter-boss.json new file mode 100644 index 0000000..636fcbc --- /dev/null +++ b/bench/orchestrator-stats/2026-05-12-iter-boss.json @@ -0,0 +1,12 @@ +{ + "iter_id": "boss", + "date": "2026-05-12", + "mode": "standard", + "outcome": "DONE", + "tasks_total": 6, + "tasks_completed": 6, + "reloops_per_task": { "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0 }, + "review_loops_spec": 0, + "review_loops_quality": 0, + "blocked_reason": null +} diff --git a/docs/journals/2026-05-12-iter-boss.md b/docs/journals/2026-05-12-iter-boss.md new file mode 100644 index 0000000..b221b39 --- /dev/null +++ b/docs/journals/2026-05-12-iter-boss.md @@ -0,0 +1,69 @@ +# 2026-05-12 — iter boss: `/boss` skill — autonomous-mode discipline gated to user invocation + +## What shipped + +- New skill at `skills/boss/SKILL.md`. Consolidates the three + mode-specific subsections that previously lived in `CLAUDE.md`: + Direction freedom, Notifications, Done-state notifications: + WhatsNew.md. +- `CLAUDE.md` refactored. Three subsections removed (~95 lines). + Skill-system pointer paragraph extended with one sentence + naming `/boss` as the autonomous-mode gate. +- `.claude/skills/boss` symlink created (`../../skills/boss`), + matching the discoverability convention codified in + `skills/README.md`. +- `skills/README.md` updated: skill table extended with a `boss` + row, heading shifted from "seven skills" to "eight skills", + pipeline diagram captioned with a `/boss`-wraps note. +- Two cross-references repointed: `skills/implement/SKILL.md` + and `skills/implement/agents/ailang-implement-orchestrator.md` + both named the "Done-state notifications" subsection of + CLAUDE.md by sub-heading; both now point at `skills/boss/SKILL.md`. + +## Why + +CLAUDE.md is always loaded into context. Mixing universal facts +(agent role boundaries, commit discipline, design rationale, file +roles, TDD-for-bugs) with mode-specific autonomy rules (direction +freedom, notifications, WhatsNew procedure) was OK while +autonomous-by-default was the operating assumption — but it +conflicted with the user's intent that a fresh session should be +collaborative-interactive unless explicitly elevated. + +The mode-switch needs to be explicit. `/boss` is the explicit +elevation, and only the three genuinely mode-specific subsections +move with it. Universal orchestrator discipline stays in CLAUDE.md +because it applies whether `/boss` is active or not: agents need +to know role boundaries when dispatched in any session, design +discipline applies whenever a design choice is made (including a +`brainstorm` invoked outside `/boss`), and the orchestrator can +edit skills at any time. + +## Decisions + +- **Tightened the move-list from seven items to three.** The + initial spec proposed moving "My role: orchestrator", "Authority + over skills/", "Design rationale ≠ effort", "Feature acceptance", + "When NOT to delegate", plus the three mode-specific subsections. + Planner recon surfaced that the first five are universal, not + mode-specific — they apply in any session. The move-list was + narrowed to the three genuinely mode-specific items. The + brainstorm Step 7.5 grounding-check was re-dispatched on the + edited spec and returned PASS. +- **No private agents under `skills/boss/agents/`.** `/boss` is an + orchestration layer, not a worker. It dispatches the existing + skills (and their agents). The skill table reflects this by + listing `boss` as a meta-skill without an agent-roster row. +- **Cross-reference repoints kept tight.** Recon found 11+ + agent/skill files that reference "CLAUDE.md — orchestrator + framing". Most of those resolve correctly to the universal + content that stays in CLAUDE.md. Only two files name the moved + subsections by sub-heading (`implement/SKILL.md` and the + orchestrator-agent's standing reading list); only those two + were repointed. + +## Status + +Iter closed. No bench regressions to check (markdown-only change, +no compiler touch). No audit needed (single-iter milestone, no +DESIGN.md change). Acceptance criteria from the spec all met. diff --git a/docs/journals/INDEX.md b/docs/journals/INDEX.md index a5dca1d..5608bd6 100644 --- a/docs/journals/INDEX.md +++ b/docs/journals/INDEX.md @@ -19,3 +19,4 @@ - 2026-05-12 — iter rt.1: roundtrip invariant audit tests (3 new tests + ailx-pair dynamic); all PASS first-shot, no gaps surfaced → 2026-05-12-iter-rt.1.md - 2026-05-12 — iter rt.2: DESIGN.md anchor for Roundtrip Invariant (top-level section + Decision 6 Constraint 2 upward cross-reference) → 2026-05-12-iter-rt.2.md - 2026-05-12 — audit-rt: milestone close (Roundtrip Invariant) — architect drift fixed in rt.tidy (3 items: Direction-2 5th test, roadmap P1 removed, wording sync); bench all-green → 2026-05-12-audit-rt.md +- 2026-05-12 — iter boss: `/boss` skill — autonomous-mode discipline (Direction freedom, Notifications, WhatsNew procedure) extracted from CLAUDE.md into a user-invoked skill → 2026-05-12-iter-boss.md diff --git a/skills/README.md b/skills/README.md index fbb9651..d1d841a 100644 --- a/skills/README.md +++ b/skills/README.md @@ -10,7 +10,7 @@ The system was bootstrapped on 2026-05-09. See `docs/specs/2026-05-09-skill-system.md` for the design and `docs/journal-archive.md` ("Skill system live") for the rationale. -## The seven skills +## The eight skills | Skill | Trigger | Output | Mandatory? | |-------|---------|--------|------------| @@ -21,9 +21,14 @@ The system was bootstrapped on 2026-05-09. See | [`docwriter`](docwriter/SKILL.md) | API surface stabilized; rustdoc lag suspected | rustdoc updates in `///` and `//!`, uncommitted in the working tree | No — Boss-dispatched only | | [`fieldtest`](fieldtest/SKILL.md) | Boss-dispatched post-audit field test on a milestone that touched user-visible surface | 2-4 `.ailx` example fixtures + `docs/specs/-fieldtest-.md`, all uncommitted in the working tree | No — Boss-dispatched only | | [`debug`](debug/SKILL.md) | Bug encountered (failing test, segfault, wrong stdout) | RED-test in the working tree (uncommitted) + cause analysis | **Mandatory RED-first** for any bug | +| [`boss`](boss/SKILL.md) | User-invoked only (`/boss`) | Autonomous orchestration session — dispatches existing skills until done-state or bounce-back | No — user-gated | ## Pipeline +> Inside a `/boss` session the orchestrator walks this pipeline +> autonomously. Outside `/boss`, the pipeline runs only when the +> user explicitly invokes a skill. + ``` [new milestone] [bug observed] | | diff --git a/skills/boss/SKILL.md b/skills/boss/SKILL.md new file mode 100644 index 0000000..19fa336 --- /dev/null +++ b/skills/boss/SKILL.md @@ -0,0 +1,263 @@ +--- +name: boss +description: User-invoked only (typed as `/boss`). Activates autonomous orchestrator mode — Claude picks the next iteration from `docs/roadmap.md`, 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 the way Brummel-as-LLM moves the +AILang project forward when the user is away. Inside this mode, +Claude reads `docs/roadmap.md`, 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 roadmap, no +multi-iter 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 + +Triggers: + +- The user explicitly types `/boss` in chat. + +Never auto-invoked. The using-superpowers rule that the harness +applies — "if a skill might apply, invoke it" — does NOT apply to +this skill. `/boss` is a deliberate mode switch performed by the +user, not a heuristic that Claude resolves on its own. A session +that wanders into autonomous behaviour without `/boss` is a +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 THREE NAMED TRIGGERS. +WHATSNEW.MD + NOTIFY ARE ONE TEXT, NOT TWO. +``` + +Universal rules (only-Boss-commits, main-is-sacrosanct, language, +TDD-for-bugs) come from `CLAUDE.md` and apply regardless of +mode. This skill does not restate them. + +## The Process + +### Step 1 — Read the queue + +`docs/roadmap.md` is the priority-ordered forward queue. Read it +first. The top item is the candidate for the next dispatch. + +If the queue is empty: skip to Step 5 (done-state). Do not invent +work; an empty queue is a real signal that the milestone 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 (from `skills/README.md`): + +``` +brainstorm → planner → implement → audit → fieldtest + + + debug (bug-triggered) + + + docwriter (post-stability) +``` + +Match the chosen item to the right entry skill. If a milestone is +new and no spec exists: `brainstorm`. If a spec exists but no plan: +`planner`. If a plan exists: `implement`. If a milestone is closing: +`audit`. If the iter is a bugfix: `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 three named triggers fired (see + "Notifications" below). Send a notify, stop the loop. +- **Done-state** — queue is empty AND the milestone is fully + ratified (audit clean, fieldtest clean if applicable). Go to + Step 5. + +### Step 5 — On done-state: WhatsNew.md + Notify + +Run the procedure named in "Done-state notifications: WhatsNew.md" +below. The two outputs share one verbatim text. + +## Direction freedom + +I have authority to choose the next iteration, refactor, or feature +without asking. Wrong calls are contained, not recovered: only the +Boss 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 -- ` on +the working tree (Boss-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. + +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 milestone + closed, the audit ratified, and no further iteration is obvious + from the spec or the roadmap (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 + milestone 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 I cannot resolve, an unexpected + invariant violation, an external dependency failure, or the + user has explicitly asked for a checkpoint. + +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 milestone with obvious follow-up iters, 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 him a decision to make. When in doubt, continue. + +~/.claude/notify.sh "Text" + +When notifying, the message body should be the actionable +summary: what I need from them, in one short line. Skip the +"hi, I" framing — just the gist. The user will see it on phone +and likely respond by returning to the session. + +By default, I act autonomous. The notification is the +exception, not the rule. + +## Done-state notifications: WhatsNew.md + +When the trigger is **done-state** (autonomous work has wrapped +up, nothing left to do for the user to react to), the procedure +is two-step and the two outputs share one text: + +1. Append a new entry to `docs/WhatsNew.md` (newest at the bottom, + append-only — same chronological convention as the per-iter journals). +2. Send the same text via `~/.claude/notify.sh`. + +The text must be written for the **user-as-reader who did not +watch me work**: + +- **Language: English.** Same as the rest of the repo; both + WhatsNew.md and the Notify push are permanent enough to be + treated as project content. +- **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 his 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) are *not* done-state and do **not** produce a +WhatsNew entry — they stay as Notify-only. + +Format of a WhatsNew entry: a `## YYYY-MM-DD — ` +heading followed by the message body. The body must match the +Notify text verbatim. + +## Common Rationalisations + +| Excuse | Reality | +|--------|---------| +| "Iter just landed cleanly, let me notify so user can see" | Mid-flow notifications burn user attention without giving them a decision to make. Iter-clean is internal progress, not a notify event. | +| "Sub-goal of the milestone is done, that counts as done-state" | Done-state is queue-empty, not sub-goal-complete. If the next iter is obvious and substantive, keep dispatching. | +| "Top of roadmap 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 milestone with obvious follow-up, the user's intent was "wake me when there's nothing else to do" — continue. | +| "Done-state hit, send notify, append WhatsNew later" | WhatsNew + notify are one text. Append first (atomic), send second. Splitting them is how the WhatsNew gets forgotten. | +| "WhatsNew can name the iter code — user will figure out what it means" | No. WhatsNew is for the user-as-reader who did not watch me work. Iter codes, crate names, function identifiers, type names — all internal, all banned. | + +## 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 write a WhatsNew entry that names a crate, an iter code, or an agent. +- About to bounce back at every iter boundary "just to be safe" — that's reactive deference, not direction freedom. +- About to send the WhatsNew text and the Notify text with different wording — they must be one verbatim text. + +## Cross-references + +- **Skill system index:** `skills/README.md` — skill table, agent + roster, pipeline diagram. +- **Universal rules:** `CLAUDE.md` — agent role boundaries, commit + discipline, design rationale, authority over skills, feature + acceptance, TDD-for-bugs, file-role roster. +- **Queue:** `docs/roadmap.md` — priority-ordered forward queue + consumed by Step 1. +- **Canonical feature-acceptance criterion:** `docs/DESIGN.md` + §"Feature-acceptance criterion" — the criterion that gates new + features; applied at spec time by `skills/brainstorm`. +- **Downstream skills dispatched:** `skills/brainstorm`, + `skills/planner`, `skills/implement`, `skills/audit`, + `skills/fieldtest`, `skills/debug`, `skills/docwriter`. diff --git a/skills/implement/SKILL.md b/skills/implement/SKILL.md index e861ecb..36434fe 100644 --- a/skills/implement/SKILL.md +++ b/skills/implement/SKILL.md @@ -141,8 +141,9 @@ unstaged changes. Nothing is committed yet. the same commit (or a follow-up commit): `- YYYY-MM-DD — iter : -iter-.md` 6. If trigger is done-state and the user is away, write a - `docs/WhatsNew.md` entry + run `notify.sh` per CLAUDE.md's - "Done-state notifications" subsection. + `docs/WhatsNew.md` entry + run `notify.sh` per + `skills/boss/SKILL.md` "Done-state notifications: WhatsNew.md" + subsection. ### Step 4 — Boss handling (on BLOCKED) diff --git a/skills/implement/agents/ailang-implement-orchestrator.md b/skills/implement/agents/ailang-implement-orchestrator.md index d4c89e0..10c4f75 100644 --- a/skills/implement/agents/ailang-implement-orchestrator.md +++ b/skills/implement/agents/ailang-implement-orchestrator.md @@ -28,9 +28,10 @@ context and dies with it. Read these before doing anything else, in this order: -1. `CLAUDE.md` — orchestrator framing, in particular the - "Done-state notifications: WhatsNew.md" subsection (WhatsNew is - Boss-side, NOT this agent's job). +1. `CLAUDE.md` — orchestrator framing (agent role boundaries, + commit discipline). Note: the "Done-state notifications: + WhatsNew.md" procedure has moved to `skills/boss/SKILL.md`; + WhatsNew is Boss-side regardless of mode, NOT this agent's job. 2. `docs/DESIGN.md` — invariants any iter must respect. 3. `docs/journals/INDEX.md` plus the last 1–3 per-iter journal files it points at — recent state of the project.