refactor: drop dev-cycle-profile.yml for conventions + CLAUDE.md facts

The profile was never parsed — it was prose the skill bodies told the model to read, so most slots were dead, constant across every project, or fiction (the whole pipeline block, including the "tdd is opt-in" claim, was enforced by nothing).

Split it in two: constants become fixed conventions named directly by the skills (new docs/conventions.md), and the few genuinely per-project facts move to each project's CLAUDE.md under '## Skills plugin: project facts'. tdd/fieldtest/docwriter are now always available; the only behavioural toggle left is spec auto-sign.

Delete docs/profile-schema.md and templates/project-profile.yml; add docs/conventions.md and a project-facts section to templates/CLAUDE.md.fragment; rewrite all SKILL/agent prose and the pipeline/design/migration/README/INSTALL docs accordingly.
This commit is contained in:
2026-06-13 16:30:02 +02:00
parent 268ee705f4
commit 26e9630496
40 changed files with 752 additions and 894 deletions
+20 -22
View File
@@ -26,32 +26,30 @@ To uninstall:
## Per-project activation ## Per-project activation
A project opts in by dropping a profile file: There is no profile file. A project activates the plugin through its
own `CLAUDE.md` — which the skills read as standing reading on every
dispatch. Two things go in it:
1. **Project facts** — the handful of mechanical facts the skills
consume (code roots, build/test command, issue-tracker slug, …),
under a `## Skills plugin: project facts` heading.
2. **Sittenkodex** — feature acceptance criteria, anti-patterns the
project has earned the hard way, domain-specific contracts.
A starter for both lives in `templates/CLAUDE.md.fragment`: the
universal discipline sentences (only-orchestrator-commits, main
sacrosanct, …) plus a commented `## Skills plugin: project facts`
template. Copy what you need into the project's `CLAUDE.md` and fill
it in:
```sh ```sh
cp ~/dev/skills/templates/project-profile.yml \ $EDITOR <project-root>/CLAUDE.md # paste from templates/CLAUDE.md.fragment
<project-root>/.claude/dev-cycle-profile.yml
$EDITOR <project-root>/.claude/dev-cycle-profile.yml
``` ```
Edit the profile to match the project's paths, commands, and Everything the plugin does *not* read from project facts is a fixed
vocabulary. The skill bodies read the profile at the start of convention (spec dir `docs/specs`, 4-digit naming, the pipeline graph,
each invocation; there is no template-render step. …) documented once in `docs/conventions.md` and `docs/pipeline.md`
not configurable per project.
A project that has not dropped a profile file gets sensible
fallbacks (see `docs/profile-schema.md` for the defaults), but
the discipline shines when the profile is explicit.
## Per-project CLAUDE.md fragment
The plugin handles mechanics. Project-specific *sittenkodex*
feature acceptance criteria, anti-patterns the project has
earned the hard way, domain-specific contracts — belongs in the
project's own `CLAUDE.md`. A starter fragment with the universal
discipline sentences (only-orchestrator-commits, main sacrosanct,
no nostalgia for removed features, etc.) lives in
`templates/CLAUDE.md.fragment` for projects that want to import
those baseline rules without rewriting them.
## Update ## Update
+42 -69
View File
@@ -8,9 +8,10 @@ same discipline across any project.
The plugin is **mechanics**: pipeline shape, hard-gates, TDD, The plugin is **mechanics**: pipeline shape, hard-gates, TDD,
RED-first bug fixing, agent-template, working-tree-as-quarantine, RED-first bug fixing, agent-template, working-tree-as-quarantine,
status protocol. It does **not** know your project's paths, status protocol. It does **not** know your project's paths,
build commands, vocabulary, or domain-specific contracts. Those build commands, or domain-specific contracts. Those few facts live
live in a small per-project profile file in the project's own `CLAUDE.md` under a `## Skills plugin: project
(`.claude/dev-cycle-profile.yml`) plus the project's `CLAUDE.md`. facts` heading; everything else is a fixed convention (see
`docs/conventions.md`). There is no separate profile file.
## What's in the box ## What's in the box
@@ -19,12 +20,12 @@ The pipeline skills, each with the agents it primarily dispatches:
| Skill | Trigger | Output | Mandatory? | | Skill | Trigger | Output | Mandatory? |
|-------|---------|--------|------------| |-------|---------|--------|------------|
| `brainstorm` | New cycle with an open design | ratified design handed to `specify` (writes no spec itself) | Optional discovery front-end | | `brainstorm` | New cycle with an open design | ratified design handed to `specify` (writes no spec itself) | Optional discovery front-end |
| `specify` | Design settled in sources, or handed over by `brainstorm` | spec under the configured spec dir | Hard-gate before plan | | `specify` | Design settled in sources, or handed over by `brainstorm` | spec under `docs/specs` | Hard-gate before plan |
| `planner` | New iteration within an open cycle | plan under the configured plan dir | Hard-gate before implement | | `planner` | New iteration within an open cycle | plan under `docs/plans` | Hard-gate before implement |
| `implement` | Plan exists | code + tests, uncommitted in working tree | Standard iteration path | | `implement` | Plan exists | code + tests, uncommitted in working tree | Standard iteration path |
| `audit` | Cycle closing OR baseline drift suspected | drift report + regression report | Mandatory at cycle close | | `audit` | Cycle closing OR baseline drift suspected | drift report + regression report | Mandatory at cycle close |
| `debug` | Bug observed | RED test in working tree + cause analysis | Mandatory RED-first for any bug | | `debug` | Bug observed | RED test in working tree + cause analysis | Mandatory RED-first for any bug |
| `tdd` | Test-specifiable feature / issue (third entry path, alongside `brainstorm` and `specify`) | RED executable-spec in working tree → `implement` mini-mode | Opt-in entry path; bounces to `brainstorm` on a design fork | | `tdd` | Test-specifiable feature / issue (third entry path, alongside `brainstorm` and `specify`) | RED executable-spec in working tree → `implement` mini-mode | Standard entry path; bounces to `brainstorm` on a design fork |
| `fieldtest` | Orchestrator-dispatched post-audit | example fixtures + friction spec | Per-cycle optional; milestone fieldtest is the closing gate for a surface-touching milestone | | `fieldtest` | Orchestrator-dispatched post-audit | example fixtures + friction spec | Per-cycle optional; milestone fieldtest is the closing gate for a surface-touching milestone |
| `docwriter` | API surface stable across N cycles | rustdoc / docstring sweep | 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; can optionally sign specs in the user's place (opt-in, see below) | User-invoked, never auto-dispatched | | `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back; can optionally sign specs in the user's place (opt-in, see below) | User-invoked, never auto-dispatched |
@@ -49,15 +50,15 @@ only where the code is not self-explanatory. Prose is allowed
only in a supporting role — the pseudocode block stays the only in a supporting role — the pseudocode block stays the
centre of every answer. It dispatches no agents. centre of every answer. It dispatches no agents.
Vocabulary is configurable. A **cycle** is one round in the The vocabulary is fixed. A **cycle** is one round in the
pipeline graph; your project may call it a *release*, an *epic*, pipeline graph, and its sub-unit is an **iteration**. A
or whatever fits, and its sub-unit (the default *iteration*) a **milestone** is a distinct, higher axis — a Gitea milestone
*sprint* or a *story*. A **milestone** is a distinct, higher that spans potentially many cycles and closes only when
axis — a tracker container (Gitea/GitHub milestone, Linear
project) that spans potentially many cycles and closes only when
the work it promised is complete *and* functional (see the work it promised is complete *and* functional (see
`docs/pipeline.md` § Milestone-close gate). A cycle close is a `docs/pipeline.md` § Milestone-close gate). A cycle close is a
loop step; it is never a milestone close. loop step; it is never a milestone close. A single design-ledger
entry is a **contract**. (A project with a glossary may pin
different domain nomenclature — see `docs/glossary-convention.md`.)
## The two-layer split ## The two-layer split
@@ -77,67 +78,39 @@ This repo (the **plugin**) carries everything that is universal:
Opus 4.8 Workflows fan out at the top level but do not lift it) Opus 4.8 Workflows fan out at the top level but do not lift it)
- No orphan agents - No orphan agents
Your project carries a small **profile** that fills the slots: The constants that used to be configurable but were the same in
every project are now **fixed conventions** — named directly in the
skills and documented once in `docs/conventions.md`: spec dir
`docs/specs`, plan dir `docs/plans`, 4-digit per-directory naming,
the vocabulary above, standing reading (`CLAUDE.md` + `git log -10`),
git discipline, Gitea + `closes #N`, and the whole pipeline graph.
- Paths: spec dir, plan dir, design ledger, code roots, bench dir The handful of facts that genuinely vary per project live in the
- Commands: build, test, lint, regression scripts project's own `CLAUDE.md` under `## Skills plugin: project facts`:
- Vocabulary: cycle name, sub-cycle name, ledger-entry name
- Naming: counter prefix vs date prefix vs flat, slug shape
- Standing reading list: concrete files, per role
- Git: issue tracker kind, close marker, main-protection policy
- Pipeline customisations: which phases are mandatory, when
optional ones fire
See `docs/profile-schema.md` for the full schema and - Code roots; build / test / lint / doc-build commands
`templates/project-profile.yml` for a copy-and-fill starting point. - Regression scripts; architect sweeps
- Design ledger / glossary / contracts / models / bench / public
interface / fieldtest-examples paths
- Spec-validation parsers (fence label → `{ext, cmd}`, `cmd` carrying
the `{file}` placeholder; a label with no entry is a documented
skip, never a silent pass)
- Per-role standing reading
- Issue-tracker repo slug + list / show commands
- Spec auto-sign (off by default)
## Keeping a profile current The per-fact reference is the table in `docs/conventions.md`; the
copy-and-fill template is `templates/CLAUDE.md.fragment`. There is no
Profile slots are versioned with the plugin, not with your project. profile file and no parser — the skills read these facts from the
A new optional slot lands in `docs/profile-schema.md` and as a project's `CLAUDE.md`, which is standing reading on every dispatch.
commented-out block in `templates/project-profile.yml` — but an
existing profile does **not** gain it automatically. Every
consuming skill treats a missing optional slot as a documented
no-op, so an out-of-date profile never breaks; it just silently
skips whatever the new slot would have enabled.
That silence cuts both ways: a profile written before a slot
existed will quietly not run the gate the slot powers, and nothing
flags it. So after pulling a plugin update, skim the commented
blocks in `templates/project-profile.yml` and the matching sections
in `docs/profile-schema.md`; any optional section your profile
lacks is a candidate to retrofit. The slot reference lives with the
plugin, never in the project — when in doubt, the schema is the
source of truth.
### Retrofitting `spec_validation`
The `spec_validation.parsers` slot maps a markdown fence label to
the tool that validates a spec code block of that kind. It powers
the parse gates that stop a spec from shipping code blocks that do
not parse against the live tool:
- `specify` Step 4 self-review — the parse-every-block gate
- `planner` Step 5 self-review — the parse-the-bytes-you-inline gate
- the `grounding-check` agent's code-block parse pass
A profile written before this slot existed has no `spec_validation`
section, so all three gates are silent no-ops there. To opt in, add
the section: map each fence label your specs use (a surface
language, a JSON-against-schema block, an IR block, …) to its
`ext` + `cmd`, where `cmd` carries the `{file}` placeholder and
exits non-zero on a parse failure. A fence label with no entry is
skipped and documented, never silently trusted. See
`docs/profile-schema.md` § `spec_validation` for the shape and
`templates/project-profile.yml` for a commented example.
### Spec auto-sign (opt-in) ### Spec auto-sign (opt-in)
By default a `specify` dispatch in a `/boss` session pauses at its By default a `specify` dispatch in a `/boss` session pauses at its
user-review gate for the user's signature — the human approves every user-review gate for the user's signature — the human approves every
spec before any plan is built. A project that wants `/boss` to run spec before any plan is built. A project that wants `/boss` to run
unattended across spec boundaries can opt in with unattended across spec boundaries can opt in by enabling spec
`pipeline.boss.spec_auto_sign: true`. auto-sign in its CLAUDE.md project facts.
With it on, the orchestrator may sign a spec in the user's place, but With it on, the orchestrator may sign a spec in the user's place, but
never on its own confidence. Signing requires two stages to clear: never on its own confidence. Signing requires two stages to clear:
@@ -161,7 +134,7 @@ backstop that stops an editorial repair from quietly settling a design
question. When a fork was settled in-context but the seeding issue still question. When a fork was settled in-context but the seeding issue still
lists it open, `specify` records the resolution as a provenance-bearing lists it open, `specify` records the resolution as a provenance-bearing
reconciliation comment on the issue (Step 1.5), which the `scope-fork` reconciliation comment on the issue (Step 1.5), which the `scope-fork`
juror reads via `issue_tracker.show_cmd` — closing the blind spot where juror reads via the project's issue show command — closing the blind spot where
the in-context entry path could otherwise never clear that lens. On a the in-context entry path could otherwise never clear that lens. On a
clean sign the orchestrator commits the spec clean sign the orchestrator commits the spec
(`(boss-signed)` in the subject), sends a mandatory informational notify (`(boss-signed)` in the subject), sends a mandatory informational notify
@@ -172,9 +145,9 @@ a history rewind. See `specify/SKILL.md` Step 6,
## Install ## Install
See `INSTALL.md`. In short: clone, run `install.sh`, then drop See `INSTALL.md`. In short: clone, run `install.sh`, then add a
a `dev-cycle-profile.yml` into each project that should use the `## Skills plugin: project facts` section to each project's
plugin. `CLAUDE.md` (template in `templates/CLAUDE.md.fragment`).
## Status ## Status
+8 -8
View File
@@ -18,8 +18,8 @@ next cycle starts.
## When to Use / Skipping ## When to Use / Skipping
**Mandatory** at every cycle close. Skipping requires an **Mandatory** at every cycle close. Skipping requires an
explicit backlog issue (issue tracker configured under explicit backlog issue (the project's issue tracker — its
`git.issue_tracker`) naming: CLAUDE.md project facts) naming:
- the blocking sibling cycle (if any), - the blocking sibling cycle (if any),
- the reason for deferral, - the reason for deferral,
@@ -47,8 +47,8 @@ Dispatch `architect` with the cycle scope (commit range from
the previous cycle-close to `HEAD`): the previous cycle-close to `HEAD`):
``` ```
For cycle <X>: read the project's design ledger (configured For cycle <X>: read the project's design ledger, if it has one
under paths.design_ledger), walk its contracts; (its CLAUDE.md project facts), walk its contracts;
`git log <prev-close>..HEAD --format=full` for the cycle's `git log <prev-close>..HEAD --format=full` for the cycle's
iter and audit commit bodies; `git diff <prev-close>..HEAD` iter and audit commit bodies; `git diff <prev-close>..HEAD`
for the diff; report drift. for the diff; report drift.
@@ -59,10 +59,10 @@ Architect produces a prioritised drift list (see
### Step 2 — Regression check ### Step 2 — Regression check
Run the scripts configured under `commands.regression` in the Run the project's regression command(s) (its CLAUDE.md project
project profile, in order. If the list is empty, the project facts), in order. If there are none, the project has no
has no regression gate and this step is a no-op (architect regression gate and this step is a no-op (architect remains the
remains the gate). gate).
The exit code of each script is the gate: The exit code of each script is the gate:
+17 -16
View File
@@ -28,13 +28,13 @@ the problem*.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` Always read `CLAUDE.md` (for the orchestrator framing) and
plus `standing_reading.by_role.architect` in the project `git log -10 --format=full`, plus the per-role standing reading
profile. The defaults include `CLAUDE.md` for the orchestrator the project lists in its CLAUDE.md project facts for the
framing. architect role.
Additionally, if the project has a design ledger configured Additionally, if the project has a design ledger (its CLAUDE.md
under `paths.design_ledger`: project facts):
1. Walk the ledger end-to-end. Drift is measured against each 1. Walk the ledger end-to-end. Drift is measured against each
contract it points to. contract it points to.
@@ -42,7 +42,7 @@ under `paths.design_ledger`:
commit bodies for the cycle you're reviewing. The most commit bodies for the cycle you're reviewing. The most
recent iter / audit commit bodies are the current claimed recent iter / audit commit bodies are the current claimed
state; your job includes asking whether the claim is true. state; your job includes asking whether the claim is true.
3. If a spec file exists under `paths.spec_dir` for this 3. If a spec file exists under `docs/specs` for this
cycle, read it — the spec is the contract this cycle cycle, read it — the spec is the contract this cycle
signed up for. Drift is also measured against the spec. signed up for. Drift is also measured against the spec.
@@ -51,7 +51,7 @@ under `paths.design_ledger`:
| Field | Content | | Field | Content |
|-------|---------| |-------|---------|
| `cycle_scope` | Cycle identifier and commit range from previous cycle-close to `HEAD` | | `cycle_scope` | Cycle identifier and commit range from previous cycle-close to `HEAD` |
| `spec_path` | Path to the cycle's spec under `paths.spec_dir` if one exists, or `none` | | `spec_path` | Path to the cycle's spec under `docs/specs` if one exists, or `none` |
| `focus_hint` | Optional: orchestrator may flag a specific concern to prioritise | | `focus_hint` | Optional: orchestrator may flag a specific concern to prioritise |
If `cycle_scope` is empty, return a structural error and stop. If `cycle_scope` is empty, return a structural error and stop.
@@ -85,9 +85,10 @@ If `cycle_scope` is empty, return a structural error and stop.
silently broken. The project's `CLAUDE.md` enumerates the silently broken. The project's `CLAUDE.md` enumerates the
known pairings; walk each one against the cycle diff and known pairings; walk each one against the cycle diff and
flag any unpaired arm as drift. flag any unpaired arm as drift.
- **Project-specific architect sweeps.** If `commands.architect_sweeps` - **Project-specific architect sweeps.** If the project
is configured in the project profile, run each script in declares an architect-sweep command (its CLAUDE.md project
the list. Exit 0 = clean for that sweep. Non-zero = at facts), run each script in it. Exit 0 = clean for that sweep.
Non-zero = at
least one match; treat each match as a drift-suspicion to least one match; treat each match as a drift-suspicion to
verify. The sweeps are the project's calibrated drift verify. The sweeps are the project's calibrated drift
detectors; their semantics are defined in the project's detectors; their semantics are defined in the project's
@@ -107,16 +108,16 @@ command to confirm a claim, never to fix one).
## The Process ## The Process
1. Read the standing list, in order: profile-configured 1. Read the standing list, in order: the standing reading
standing reading → design ledger contracts → above → design ledger contracts →
`git log <prev-cycle-close>..HEAD --format=full` for the `git log <prev-cycle-close>..HEAD --format=full` for the
iter / audit commit bodies in scope → spec (if any) → iter / audit commit bodies in scope → spec (if any) →
recent diff. recent diff.
2. `git log --oneline -30` and 2. `git log --oneline -30` and
`git diff <prev-cycle-close>..HEAD` for the factual diff. `git diff <prev-cycle-close>..HEAD` for the factual diff.
3. Run each script in `commands.architect_sweeps` (if 3. Run each script in the project's architect-sweep command
configured). Treat each non-zero exit as a drift-suspicion (its CLAUDE.md project facts), if it has one. Treat each
to verify. non-zero exit as a drift-suspicion to verify.
4. Read every changed file. Read the unchanged-but-load- 4. Read every changed file. Read the unchanged-but-load-
bearing neighbours. bearing neighbours.
5. Walk the project's lockstep-invariant pairings (from 5. Walk the project's lockstep-invariant pairings (from
+3 -2
View File
@@ -34,8 +34,9 @@ over it with a chart.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` plus Always read `CLAUDE.md` and `git log -10 --format=full`, plus
`standing_reading.by_role.bencher` in the project profile. the per-role standing reading the project lists in its
CLAUDE.md project facts for the bencher role.
For diagnostics on a specific regression script, read the For diagnostics on a specific regression script, read the
script itself and any prior result baselines it references script itself and any prior result baselines it references
+32 -35
View File
@@ -72,10 +72,10 @@ skill does not restate them.
### Step 1 — Read the queue ### Step 1 — Read the queue
The project's issue tracker is the forward queue. Read open The project's issue tracker is the forward queue. Read open
issues via the command configured under issues via the list command in the project's CLAUDE.md project
`git.issue_tracker.list_cmd` in the project profile. If that facts. If the project names no issue tracker there, it does not
slot is empty, the project does not have an autonomously have an autonomously addressable queue — bounce back to the user
addressable queue — bounce back to the user with that diagnosis. with that diagnosis.
If the entire open backlog is empty: skip to Step 5 If the entire open backlog is empty: skip to Step 5
(done-state). Do not invent work; an empty queue is a real (done-state). Do not invent work; an empty queue is a real
@@ -98,7 +98,7 @@ brainstorm → specify → planner → implement → audit → fieldtest
+ +
debug (bug-triggered) debug (bug-triggered)
+ +
tdd → implement (mini) (test-specifiable feature, if profile enables it) tdd → implement (mini) (test-specifiable feature)
+ +
docwriter (post-stability) docwriter (post-stability)
``` ```
@@ -110,9 +110,9 @@ new feature work with no spec or plan yet, run the **Entry-path
reflection** below before dispatching anything. Read each skill's reflection** below before dispatching anything. Read each skill's
`SKILL.md` trigger section if unsure. `SKILL.md` trigger section if unsure.
**Entry-path reflection (feature work).** When the profile enables the **Entry-path reflection (feature work).** There are **three** entry
`tdd` phase, there are **three** entry paths for new feature work, and paths for new feature work, and the choice is made by reflection every
the choice is made by reflection every time, not by habit. Before time, not by habit. Before
dispatching, decide which fits the item in hand and record the one-line dispatching, decide which fits the item in hand and record the one-line
verdict ("test-specifiable → `tdd`" / "design settled → `specify`" / verdict ("test-specifiable → `tdd`" / "design settled → `specify`" /
"design fork → `brainstorm`") in the loop. The discriminator is the "design fork → `brainstorm`") in the loop. The discriminator is the
@@ -126,9 +126,9 @@ verdict ("test-specifiable → `tdd`" / "design settled → `specify`" /
exhaustive issue body, a long in-context discussion — then the design exhaustive issue body, a long in-context discussion — then the design
is **settled** and `specify` owns it. Dispatch `specify` is **settled** and `specify` owns it. Dispatch `specify`
autonomously: it is bounded (no interview), produces the spec through autonomously: it is bounded (no interview), produces the spec through
all the gates, and — unless the profile enables auto-sign (see below) all the gates, and — unless the project enables spec auto-sign (see
— pauses at its own user-review gate (a problem-state notify, not a below) — pauses at its own user-review gate (a problem-state notify,
pre-dispatch checkpoint). not a pre-dispatch checkpoint).
- Writing the spec would force a choice between two or three plausible - Writing the spec would force a choice between two or three plausible
designs with real trade-offs — a genuine design fork — then discovery designs with real trade-offs — a genuine design fork — then discovery
must resolve it first, and `brainstorm` owns it. Starting a fresh must resolve it first, and `brainstorm` owns it. Starting a fresh
@@ -143,13 +143,13 @@ both bounded (no open Q&A), whereas a fresh `brainstorm` is high-context
discovery the orchestrator cannot compact on its own (see trigger 4). discovery the orchestrator cannot compact on its own (see trigger 4).
`specify` dispatched in `/boss` pauses at its own Step-6 user-review `specify` dispatched in `/boss` pauses at its own Step-6 user-review
gate to take sign-off — that is a final-sign-off notify, not a gate to take sign-off — that is a final-sign-off notify, not a
pre-dispatch checkpoint. The one exception is the opt-in auto-sign pre-dispatch checkpoint. The one exception is spec auto-sign: when a
slot (`pipeline.boss.spec_auto_sign`): when a project enables it, a project enables it in its CLAUDE.md project facts, a
spec that clears all objective gates AND a unanimous adversarial spec that clears all objective gates AND a unanimous adversarial
`spec-skeptic` panel is signed by the orchestrator without pausing, `spec-skeptic` panel is signed by the orchestrator without pausing,
and the run continues to `planner` — see §"Spec auto-sign" below. The and the run continues to `planner` — see §"Spec auto-sign" below. The
gate is built so that the orchestrator's own confidence is never what gate is built so that the orchestrator's own confidence is never what
signs; absent the slot, the human signature stays mandatory. Do not signs; absent that, the human signature stays mandatory. Do not
let the asymmetry harden into a reflex let the asymmetry harden into a reflex
of routing borderline items to `brainstorm` "to be safe" — that is the of routing borderline items to `brainstorm` "to be safe" — that is the
exact bias this reflection exists to break; apply the design-line test exact bias this reflection exists to break; apply the design-line test
@@ -163,11 +163,10 @@ design was not settled / not test-specifiable after all, that escalation
routes to `brainstorm` and — being a new cycle needing a fresh routes to `brainstorm` and — being a new cycle needing a fresh
discovery — is a bounce-back to the user per the same trigger 4. discovery — is a bounce-back to the user per the same trigger 4.
If the profile does **not** enable the `tdd` phase, the reflection is All three entry paths are always available — none is profile-gated.
two-way — `specify` for a settled design, `brainstorm` for an open one. The reflection is therefore always three-way: `tdd` for
`specify` is a core node (never profile-gated), so the settled-design test-specifiable behaviour, `specify` for a settled design,
path is always available; only the `tdd` test-specifiable branch is `brainstorm` for an open one.
opt-in.
If the working tree is mid-flight (uncommitted changes left over If the working tree is mid-flight (uncommitted changes left over
from a previous session): inspect first, then resume the right from a previous session): inspect first, then resume the right
@@ -228,8 +227,7 @@ Bounce back to the user only when:
dependency failure, a discovered invariant violation). dependency failure, a discovered invariant violation).
- The user has explicitly asked for a checkpoint. - The user has explicitly asked for a checkpoint.
- **The next item on the queue is a new cycle** — i.e. a top- - **The next item on the queue is a new cycle** — i.e. a top-
level work container (in the project's vocabulary: milestone, level work container (a milestone) that has no spec file yet and
epic, release, sprint root) that has no spec file yet and
would require dispatching `brainstorm` to even begin. would require dispatching `brainstorm` to even begin.
Continuing an open cycle (next iteration, audit, fieldtest, Continuing an open cycle (next iteration, audit, fieldtest,
post-audit tidy) is autonomous; *starting* a new cycle is a post-audit tidy) is autonomous; *starting* a new cycle is a
@@ -274,7 +272,7 @@ narrow one that exists only when spec auto-sign is enabled:
the next backlog item is a new cycle (no spec yet) and the next backlog item is a new cycle (no spec yet) and
starting it would force a fresh `brainstorm`. starting it would force a fresh `brainstorm`.
3. **Auto-sign (only with `pipeline.boss.spec_auto_sign`).** The 3. **Auto-sign (only when the project enables spec auto-sign).** The
orchestrator signed a spec in the user's place and is orchestrator signed a spec in the user's place and is
continuing the run — see §"Spec auto-sign". This is the one continuing the run — see §"Spec auto-sign". This is the one
sanctioned mid-flow notify, and it is sanctioned *because it sanctioned mid-flow notify, and it is sanctioned *because it
@@ -296,10 +294,9 @@ Mid-flow progress notifications burn the user's attention
without giving them a decision to make. When in doubt, without giving them a decision to make. When in doubt,
continue. continue.
The notification command is configured under The notification command is `~/.claude/notify.sh` (the user-level
`notifications.command` in the project profile and receives the convention); it receives the message text as a single argument. If it
message text as a single argument. If the profile does not is unavailable, fall back to printing the notification in chat.
configure one, fall back to printing the notification in chat.
When notifying, the message body should be the actionable When notifying, the message body should be the actionable
summary: what the orchestrator needs from the user, in one summary: what the orchestrator needs from the user, in one
@@ -342,8 +339,8 @@ actionable ask, not a wrap-up summary.
## Spec auto-sign ## Spec auto-sign
Off by default. A project turns it on with Off by default. A project turns it on in its CLAUDE.md project facts
`pipeline.boss.spec_auto_sign: true`. With it off, a `specify` (spec auto-sign: enabled). With it off, a `specify`
dispatch in `/boss` always pauses for the user's signature — the dispatch in `/boss` always pauses for the user's signature — the
conservative default, unchanged. conservative default, unchanged.
@@ -409,7 +406,7 @@ and defined there. The boss-side contract is just this:
| "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. | | "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. |
| "Feature work, so route it to `brainstorm` — that's the safe default" | `brainstorm`, `specify`, and `tdd` are co-equal entry paths; none is the default. Routing a settled design to `brainstorm` re-litigates decided choices; routing a test-specifiable item there wastes the test path. Run the Entry-path reflection and pick by the design line. The only tilt toward `brainstorm` is a genuinely unresolved fork — and that is a fork, not a default. | | "Feature work, so route it to `brainstorm` — that's the safe default" | `brainstorm`, `specify`, and `tdd` are co-equal entry paths; none is the default. Routing a settled design to `brainstorm` re-litigates decided choices; routing a test-specifiable item there wastes the test path. Run the Entry-path reflection and pick by the design line. The only tilt toward `brainstorm` is a genuinely unresolved fork — and that is a fork, not a default. |
| "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 — it is NOT the high-context `brainstorm` cycle that trigger 4 reserves for the user. Dispatch it; it will pause at its own user-review gate for sign-off. The pre-dispatch bounce is for an *open* design that needs discovery, not for a settled one that needs only production. | | "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 — it is NOT the high-context `brainstorm` cycle that trigger 4 reserves for the user. Dispatch it; it will pause at its own user-review gate for sign-off. The pre-dispatch bounce is for an *open* design that needs discovery, not for a settled one that needs only production. |
| "`tdd` is opt-in / profile-gated, so it's the secondary skill" | Profile-gating is about whether the path is *available*, not about rank. Once enabled, the choice between the two is decided by fit per item, reflected on each time — not by treating `brainstorm` as primary and `tdd` as the exception. | | "`tdd` is the secondary skill, `brainstorm` is the real entry" | All three entry paths are always available and co-equal. The choice among them is decided by fit per item, reflected on each time — not by treating `brainstorm` as primary and `tdd` as the exception. |
| "Auto-sign is on and this spec is clearly good — I'll sign it and skip the panel" | The panel IS how a spec gets signed under auto-sign; there is no signing on judgement. Your sense that it is clearly good is the precise signal the gate is built not to trust. Run the objective gates, dispatch the five jurors, require unanimity. | | "Auto-sign is on and this spec is clearly good — I'll sign it and skip the panel" | The panel IS how a spec gets signed under auto-sign; there is no signing on judgement. Your sense that it is clearly good is the precise signal the gate is built not to trust. Run the objective gates, dispatch the five jurors, require unanimity. |
| "Four jurors said SOUND, one blocked on something I think is wrong — I'll sign" | Unanimous-or-nothing. You never sign over a `BLOCK`. If it is an editorial lens, repair it and re-run the whole panel (≤ 2 rounds); if it is a design lens or the budget is spent, it routes to the human sign-off it would have had anyway. Signing because *you* think the juror is wrong is overruling the panel — confidence by the back door. | | "Four jurors said SOUND, one blocked on something I think is wrong — I'll sign" | Unanimous-or-nothing. You never sign over a `BLOCK`. If it is an editorial lens, repair it and re-run the whole panel (≤ 2 rounds); if it is a design lens or the budget is spent, it routes to the human sign-off it would have had anyway. Signing because *you* think the juror is wrong is overruling the panel — confidence by the back door. |
| "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. | | "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. |
@@ -424,7 +421,7 @@ and defined there. The boss-side contract is just this:
- 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. - 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.
- About to route feature work to `brainstorm` without running the Entry-path reflection — defaulting to it because it "feels safer" than `specify` or `tdd`, rather than applying the design-line test. The three are co-equal; the choice is reflected on each time. Routing a *settled* design to `brainstorm` (re-litigating decided choices) is as much a failure as skipping discovery on an open one. - About to route feature work to `brainstorm` without running the Entry-path reflection — defaulting to it because it "feels safer" than `specify` or `tdd`, rather than applying the design-line test. The three are co-equal; the choice is reflected on each time. Routing a *settled* design to `brainstorm` (re-litigating decided choices) is as much a failure as skipping discovery on an open one.
- About to sign a spec under auto-sign on confidence — without all objective gates green and a unanimous `spec-skeptic` panel; signing over any `BLOCK`; self-correcting a *design*-lens (`scope-fork` / `grounding`) `BLOCK` instead of escalating; or looping past the 2-round budget. The gate exists so the orchestrator's confidence never signs. - About to sign a spec under auto-sign on confidence — without all objective gates green and a unanimous `spec-skeptic` panel; signing over any `BLOCK`; self-correcting a *design*-lens (`scope-fork` / `grounding`) `BLOCK` instead of escalating; or looping past the 2-round budget. The gate exists so the orchestrator's confidence never signs.
- About to run the auto-sign path at all when `pipeline.boss.spec_auto_sign` is not enabled, or to skip the mandatory auto-sign notify after signing. - About to run the auto-sign path at all when the project has not enabled spec auto-sign, or to skip the mandatory auto-sign notify after signing.
## Cross-references ## Cross-references
@@ -437,17 +434,17 @@ and defined there. The boss-side contract is just this:
layer, loaded in every session, above the project file) — it layer, loaded in every session, above the project file) — it
carries constraints that bind autonomous runs too, including carries constraints that bind autonomous runs too, including
external-service-consent rules that `/boss` does not lift. external-service-consent rules that `/boss` does not lift.
- **Queue:** the URL configured under `git.issue_tracker.url` in - **Queue:** the project's issue tracker — its CLAUDE.md project
the profile; CLI command at `git.issue_tracker.list_cmd`. facts name the repo slug, the browsable URL, and the list command.
- **Glossary write-rule:** `../docs/glossary-convention.md` - **Glossary write-rule:** `../docs/glossary-convention.md`
record-reality discipline for the only autonomous glossary writer. record-reality discipline for the only autonomous glossary writer.
- **Spec auto-sign gate:** owned by `../specify` Step 6; the - **Spec auto-sign gate:** owned by `../specify` Step 6; the
adversarial juror is `../specify/agents/spec-skeptic.md` (dispatched adversarial juror is `../specify/agents/spec-skeptic.md` (dispatched
five times, one per lens). Enabled per project by five times, one per lens). Enabled per project in its CLAUDE.md
`pipeline.boss.spec_auto_sign` — see `../docs/profile-schema.md`. project facts — see `../docs/conventions.md`.
- **Downstream skills dispatched:** `../brainstorm`, - **Downstream skills dispatched:** `../brainstorm`,
`../specify` (spec-production core; autonomously dispatchable for a `../specify` (spec-production core; autonomously dispatchable for a
settled design), `../planner`, `../implement`, `../audit`, settled design), `../planner`, `../implement`, `../audit`,
`../fieldtest`, `../debug`, `../tdd` (test-specifiable feature, `../fieldtest`, `../debug`, `../tdd` (test-specifiable feature,
profile-gated; autonomously dispatchable like `../debug`), always available; autonomously dispatchable like `../debug`),
`../docwriter`. `../docwriter`.
+8 -9
View File
@@ -19,7 +19,7 @@ to prevent.
`brainstorm` does not write the spec. Its terminal state is handing the `brainstorm` does not write the spec. Its terminal state is handing the
ratified design to `specify` (the spec-production core), which applies ratified design to `specify` (the spec-production core), which applies
the acceptance criterion, writes the spec under `paths.spec_dir`, runs the acceptance criterion, writes the spec under `docs/specs`, runs
the gates, and takes user sign-off. When the design is *already* the gates, and takes user sign-off. When the design is *already*
settled in the sources, `brainstorm` is skipped entirely and the work settled in the sources, `brainstorm` is skipped entirely and the work
enters through `specify` directly. enters through `specify` directly.
@@ -40,8 +40,7 @@ Triggers:
long in-context discussion, settled design docs. Use `specify` long in-context discussion, settled design docs. Use `specify`
directly: discovery would only re-litigate decisions the sources directly: discovery would only re-litigate decisions the sources
already made. already made.
- A test-specifiable feature, on a profile that enables `tdd` — use - A test-specifiable feature — use `tdd` directly.
`tdd` directly.
- A bug-fix iteration — use `debug` directly. - A bug-fix iteration — use `debug` directly.
- A tidy iteration — use `audit` directly. - A tidy iteration — use `audit` directly.
- A trivial mechanical edit — per the project's CLAUDE.md carve-out. - A trivial mechanical edit — per the project's CLAUDE.md carve-out.
@@ -65,11 +64,11 @@ Before asking any clarifying questions:
- `git log -5 --format=full` for the full bodies of the most - `git log -5 --format=full` for the full bodies of the most
recent iter / audit commits — current state of the project. recent iter / audit commits — current state of the project.
- If the project has a design ledger configured under - If the project has a design ledger (its CLAUDE.md project facts name
`paths.design_ledger`, walk to the relevant contracts for it), walk to the relevant contracts for the invariants the new cycle
the invariants the new cycle might touch. might touch.
- When reading any file under `paths.design_models` (or the - When reading any file under the project's design models, if it has
ledger's "model" rows), note its `status` / them, or the ledger's "model" rows, note its `status` /
`validated-against` frontmatter if present: `status: `validated-against` frontmatter if present: `status:
aspirational` means its code is a target, not verified fact. aspirational` means its code is a target, not verified fact.
Track which content you may lift from such a source — it is Track which content you may lift from such a source — it is
@@ -196,7 +195,7 @@ The production gates live there, not here.
when the sources do not resolve a design fork. when the sources do not resolve a design fork.
- **Ad-hoc dispatch.** The orchestrator MAY ad-hoc dispatch - **Ad-hoc dispatch.** The orchestrator MAY ad-hoc dispatch
`../planner/agents/plan-recon.md` during Step 1 when the cycle `../planner/agents/plan-recon.md` during Step 1 when the cycle
enters code territory not recently read; opt-in, not part of the enters code territory not recently read; ad-hoc, not part of the
standard process. standard process.
- **Project feature-acceptance criterion:** declared in the project's - **Project feature-acceptance criterion:** declared in the project's
`CLAUDE.md` — applied prospectively by `specify` (its Step 2), not `CLAUDE.md` — applied prospectively by `specify` (its Step 2), not
+3 -4
View File
@@ -28,8 +28,8 @@ dispatch, and handoff.
Trigger this skill on: Trigger this skill on:
- a failing run of the project's test command (configured under - a failing run of the project's test command (its CLAUDE.md
`commands.test` in the profile) project facts)
- wrong stdout from running a project artefact - wrong stdout from running a project artefact
- a segfault from a built binary - a segfault from a built binary
- a panic / unhandled exception in the toolchain - a panic / unhandled exception in the toolchain
@@ -43,8 +43,7 @@ for TDD" is the exact failure mode this skill exists to prevent.
`debug` is for a regression of *existing* behaviour. New `debug` is for a regression of *existing* behaviour. New
test-specifiable behaviour is its sibling `tdd`'s job (same test-specifiable behaviour is its sibling `tdd`'s job (same
two-stage RED→GREEN shape, triggered by a feature description two-stage RED→GREEN shape, triggered by a feature description
rather than an observed misbehaviour) — route there instead, rather than an observed misbehaviour) — route there instead.
on profiles that enable it.
## The Iron Law ## The Iron Law
+13 -15
View File
@@ -26,15 +26,14 @@ genuinely captures the symptom, not the post-fix code path.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` plus Always read `CLAUDE.md` (for role boundaries) and
`standing_reading.by_role.debugger` in the project profile. `git log -10 --format=full` the most recent iter commits, as
The defaults include `CLAUDE.md` for role boundaries and the the last iteration may have introduced the bug — plus the
recent `git log` for the most recent iter commits — the last per-role standing reading the project lists in its CLAUDE.md
iteration may have introduced the bug. project facts for the debugger role.
If the project has a design-ledger configured under If the project has a design ledger (its CLAUDE.md project
`paths.design_ledger`, walk it for invariants the bug may have facts), walk it for invariants the bug may have crossed.
crossed.
The four-phase process below is the single source of truth — The four-phase process below is the single source of truth —
the dispatching skill file does not duplicate it. the dispatching skill file does not duplicate it.
@@ -77,11 +76,10 @@ Each phase completes before the next starts.
2. Reproduce with the shortest possible command. If the carrier 2. Reproduce with the shortest possible command. If the carrier
provides one, verify it; otherwise build one. provides one, verify it; otherwise build one.
3. Diagnose by data flow, not by guess: 3. Diagnose by data flow, not by guess:
- Build error → run the project's build command - Build error → run the project's build command (its
(`commands.build` from the profile) with output captured CLAUDE.md project facts) with output captured
- Test red → run the configured test command - Test red → run the project's test command with verbose
(`commands.test`) with verbose output and the failing output and the failing test name targeted
test name targeted
- Wrong stdout → run the artefact that produced it, capture - Wrong stdout → run the artefact that produced it, capture
stdout verbatim, compare to expected stdout verbatim, compare to expected
- Segfault → run the binary, capture exit code; if `valgrind` - Segfault → run the binary, capture exit code; if `valgrind`
@@ -220,8 +218,8 @@ At most 250 words, structured:
- The fix. That's `implement` mini-mode's job. - The fix. That's `implement` mini-mode's job.
- Sweeping refactors layered on top of a bug fix. - Sweeping refactors layered on top of a bug fix.
- Changes to the test once it's RED — the test is the contract. - Changes to the test once it's RED — the test is the contract.
- Design-ledger edits (the file at `paths.design_ledger` in - Design-ledger edits (the project's design ledger, if it has
the profile, if configured). one — its CLAUDE.md project facts).
- Verdicts like "this whole subsystem is broken". Phase 4.5 - Verdicts like "this whole subsystem is broken". Phase 4.5
surfaces the architecture question; the orchestrator decides surfaces the architecture question; the orchestrator decides
the verdict. the verdict.
+13 -10
View File
@@ -23,8 +23,10 @@ to prevent>
## Standing reading list ## Standing reading list
<list of always-binding documents — derived from the project <list of always-binding documents — the fixed always list (`CLAUDE.md`
profile's `standing_reading.always` plus `standing_reading.by_role.<this-role>`> plus `git log -10 --format=full`), the per-role standing reading the
project lists in its CLAUDE.md project facts, and the project's glossary
if it has one>
## Carrier contract ## Carrier contract
@@ -119,15 +121,16 @@ forcefully than "this role helps with X".
### Standing reading list ### Standing reading list
The plugin's skill body computes this from the project profile The plugin's skill body composes this list and passes it to the agent
(`standing_reading.always` + `standing_reading.by_role.<role>`) via the carrier. It is built from a fixed always list — `CLAUDE.md`
and passes the resolved list to the agent via the carrier. The plus `git log -10 --format=full`, binding on every role — extended by
agent's body says, prosaically: "Read everything in the standing the per-role standing reading the project lists in its CLAUDE.md project
reading list before doing anything else." facts. The agent's body says, prosaically: "Read everything in the
standing reading list before doing anything else."
A set `paths.glossary` is implicitly part of `always`, so every role When the project's CLAUDE.md project facts name a glossary path, that
reads the project glossary without a per-role entry (see glossary is implicitly part of the always list, so every role reads the
`profile-schema.md` § `paths`). project glossary without a per-role entry.
The agent file itself does not hardcode file paths. The agent file itself does not hardcode file paths.
+144
View File
@@ -0,0 +1,144 @@
# Conventions
The skills plugin used to read a per-project `dev-cycle-profile.yml`.
It no longer does. There was never a parser — the profile was prose
the skill bodies told the model to read, and almost every slot was
either dead, constant across all projects, or derivable. So the
plugin now splits cleanly in two:
- **Fixed conventions** (this file) — the things that were constant
across every project. They are not configurable; the skill and agent
bodies name them directly.
- **Per-project facts** — the handful of things that genuinely vary
per project (where the code lives, how to build and test it, the
tracker slug, …). These live as prose in each project's own
`CLAUDE.md` under a `## Skills plugin: project facts` heading. See
`../templates/CLAUDE.md.fragment` for the template, and the section
list at the bottom of this file.
## File layout
| Artefact | Location |
|----------|----------|
| Specs (from `specify`) | `docs/specs/` |
| Plans (from `planner`) | `docs/plans/` |
These directories are fixed. A project that keeps specs and plans
elsewhere is the rare exception and states the override in its
`CLAUDE.md` project facts.
## Naming
Counter-prefixed, per directory: `NNNN-slug.md`, 4-digit
zero-padded. The counter is per directory, assigned in creation
order, and stable for the life of the file. New files take the
next-higher number; deleted files retire their number (numbers are
not recycled). `brainstorm` / `specify` / `planner` scan the target
directory for the next free number before writing.
The slug separator is `-`.
## Vocabulary
The pipeline's nouns are fixed:
| Term | Meaning |
|------|---------|
| **cycle** | One round in the pipeline graph (`brainstorm → specify → planner → implement → audit → [fieldtest]`). NOT the top-level container. |
| **iteration** | A sub-unit of a cycle. |
| **milestone** | Tracker container spanning many cycles; closes only when complete AND functional (see `pipeline.md` § Milestone-close gate). |
| **contract** | A single design-ledger entry. |
When a project declares a glossary (in its CLAUDE.md project facts),
that glossary is the source of truth for domain nomenclature and
overrides these names where they collide (see `glossary-convention.md`).
## Standing reading
Every agent reads, at the start of every dispatch:
- the project's `CLAUDE.md`
- `git log -10 --format=full`
A project may add more — globally or per role — in its CLAUDE.md
project facts (`standing reading`). If the project declares a
glossary, that file is implicitly standing reading for every role
too.
## Git discipline
- **Only the orchestrator commits.** No skill agent runs `git commit`.
Agents write into the working tree as unstaged changes; the
orchestrator inspects, decides commit shape, and commits.
- **main HEAD is sacrosanct.** Nobody runs `git reset` / `git revert`
on main (or any other protected branch). main moves forward only via
orchestrator commits; a wrong agent diff is discarded with
`git checkout -- <paths>` / `git stash`, never by rewinding main.
These also appear in the universal-discipline fragment
(`../templates/CLAUDE.md.fragment`) that each project's CLAUDE.md
imports.
## Issue tracker
The tracker is **Gitea** and the commit close-marker is `closes #N`
(`refs #N` for non-closing work). The per-project repo slug and the
list/show commands live in the project's CLAUDE.md project facts
(see below) — the `boss` skill reads the forward queue from there,
and the `spec-skeptic` `scope-fork` juror reads single issues with
their comment threads from there.
## Pipeline
The phase set, the gates, and the conditional dispatch are **fixed**
and documented once in `pipeline.md`. There is no per-project pipeline
configuration. In particular: `brainstorm`, `specify`, `planner`,
`implement`, `audit`, `debug`, `tdd`, `fieldtest`, and `docwriter` are
always available. `tdd` is a standard entry path for test-specifiable
work — not an opt-in. `audit` is mandatory at cycle close.
`fieldtest` / `docwriter` are orchestrator-dispatched. The single
behavioural toggle is spec auto-sign under `/boss`, declared (when a
project wants it) in that project's CLAUDE.md project facts.
## Per-project facts (in each project's CLAUDE.md)
Under `## Skills plugin: project facts`, where applicable:
| Fact | Used by | Notes |
|------|---------|-------|
| **code roots** | architect, quality-reviewer, fieldtester | Directories reviewers walk. Required. |
| **build / test command** | implement, audit | Required. Exit 0 = success. |
| **lint command** | (quality) | Optional. |
| **doc-build command** | docwriter | Optional; prints warnings on stderr. |
| **regression scripts** | audit (bencher) | Optional list; non-zero exit = regress. |
| **architect sweeps** | audit (architect) | Optional list; non-zero exit = drift suspicion. |
| **spec-validation parsers** | specify, grounding-check | Optional; fence-label → `{ext, cmd}` table. `cmd` MUST contain `{file}`. Absent label → documented skip, never silent pass. |
| **design ledger** | architect, most agents | Optional path (e.g. `design/INDEX.md`). |
| **glossary** | every role | Optional path; implicitly standing reading. |
| **design contracts / models** | docwriter, specify | Optional dirs. Aspirational-source frontmatter marker recommended (see below). |
| **bench dir** | fieldtest, bencher | Optional path. |
| **public interface** | fieldtester | Optional list — the only surface the fieldtester may read; everything else (code roots, bench) is forbidden to it. |
| **fieldtest examples** | fieldtester | Optional path where fixtures are written. |
| **by-role standing reading** | named agent | Optional; extra files/commands a specific role reads. |
| **issue tracker** | boss, spec-skeptic | Repo slug + list command + show command (the latter MUST render an issue WITH its comments). |
| **spec auto-sign** | boss, specify | Optional; `enabled` lets `/boss` sign a spec in the user's place through the auto-sign gate (default: human signature). |
### Aspirational-source marker (recommendation)
Files under a project's design-models / RFCs / proposals directory
commonly carry aspirational code — constructs written before the
surface that parses them exists. To let a later `specify` tell
aspirational content from validated contract, give each such file a
frontmatter marker:
```yaml
---
status: aspirational
validated-against: <commit-sha | "no validation">
---
```
When the marker is absent the signal is simply absent — `specify`
degrades to treating the content as unmarked, never hard-failing.
Content lifted from an aspirational source is flagged and must clear
the parse-every-block gate before it ships in a spec.
+50 -43
View File
@@ -1,20 +1,28 @@
# Design # Design
## Why split plugin from profile ## Why split plugin from project
The skills system originally evolved inside the AILang project, The skills system originally evolved inside the AILang project,
where it grew organically against AILang's specific paths, where it grew organically against AILang's specific paths,
build commands, vocabulary, and contracts. Lifting it into a build commands, vocabulary, and contracts. Lifting it into a
plugin requires a clean separation between what is universal plugin requires a clean separation between what is universal
(belongs in the plugin) and what is project-specific (belongs (belongs in the plugin) and what is project-specific (belongs
in a per-project profile). in the project's `CLAUDE.md`).
The litmus test: would a sentence in a SKILL or agent body The litmus test: would a sentence in a SKILL or agent body
still make sense in a Python web project, a Rust CLI, and a still make sense in a Python web project, a Rust CLI, and a
TypeScript library? If yes, plugin. If it mentions `cargo`, TypeScript library? If yes, plugin. If it mentions `cargo`,
`crates/`, `docs/design/INDEX.md`, `Form A`, or any project-specific `crates/`, `docs/design/INDEX.md`, `Form A`, or any project-specific
identifier, it goes to the profile (as a slot) or to the identifier, it goes to the project's `CLAUDE.md` — either as a
project's `CLAUDE.md` (as sittenkodex). project fact (the few mechanical facts the skills consume) or as
sittenkodex (domain contracts, anti-patterns).
There is no separate profile file. An earlier design had a
per-project `dev-cycle-profile.yml`, but it was never parsed — it
was prose the skill bodies told the model to read, and almost every
slot was constant across projects, dead, or derivable. So the
constant parts became fixed conventions (`conventions.md`) and the
genuinely-varying parts moved into each project's `CLAUDE.md`.
## Plugin layer (universal) ## Plugin layer (universal)
@@ -54,44 +62,42 @@ The plugin owns:
- **Output budget discipline** — agents have word budgets on - **Output budget discipline** — agents have word budgets on
their reports. their reports.
## Profile layer (project-specific) ## Fixed conventions (universal)
The profile fills slots that the plugin's prose references The constants that used to be configurable but were the same in
generically. Concretely: every project are now plugin conventions, named directly in skill
and agent bodies and documented once in `conventions.md`:
spec dir `docs/specs`, plan dir `docs/plans`, 4-digit per-directory
naming, the vocabulary cycle / iteration / milestone / contract,
standing reading (`CLAUDE.md` + `git log -10`), git discipline
(only-orchestrator commits, main sacrosanct), Gitea + `closes #N`,
and the whole pipeline graph (see `pipeline.md`).
- **Paths**: `spec_dir`, `plan_dir`, `design_ledger`, ## Project facts (project-specific)
`design_contracts`, `design_models`, `code_roots`, `bench_dir`.
- **Commands**: `build`, `test`, `lint`, `regression` (list).
- **Vocabulary**: `cycle`, `subcycle`, `ledger_entry`.
- **Naming**: `counter_dirs`, `policy` (`stable_per_directory_4digit`
or `date_prefix` or `flat`).
- **Standing reading**: `always` (a list), `by_role` (a map
from role to list).
- **Git**: `main_sacrosanct` (bool, default true),
`only_orchestrator_commits` (bool, default true),
`issue_tracker.kind` (`gitea` / `github` / `linear` / `none`),
`issue_tracker.close_marker` (e.g. `"closes #N"`).
- **Pipeline customisations**: per-phase `mandatory_before`,
`mandatory_at`, `boss_only`, `when` (a condition tag).
The full schema lives in `profile-schema.md`. The functional The handful of facts that genuinely vary per project live in the
starting template is `../templates/project-profile.yml`. project's `CLAUDE.md` under `## Skills plugin: project facts`:
code roots, build / test / lint / doc-build commands, regression
scripts, architect sweeps, design-ledger / glossary / contracts /
models / bench / public-interface / fieldtest-examples paths,
spec-validation parsers, by-role standing reading, the issue-tracker
repo slug and commands, and spec auto-sign. The template is in
`../templates/CLAUDE.md.fragment`; the per-fact reference is the
table in `conventions.md`.
## Resolution model ## Resolution model
The plugin uses **profile-driven prompts**, not template The plugin uses **convention-and-fact prompts**, not template
rendering. Each SKILL.md and agent file is generic prose that rendering and not a config parser. Each SKILL.md and agent file is
references the profile prosaically: generic prose that either names a fixed convention directly or
points at a project fact:
> Write the spec to the directory configured under `paths.spec_dir` > Write the spec to `docs/specs`. Use the project's build command
> in the project profile. Use the naming policy configured under > (its CLAUDE.md project facts).
> `naming.policy`.
When Claude Code loads the skill, the project profile is in The project's `CLAUDE.md` is always in context (it is standing
context (the skill body explicitly instructs the model to read reading #1), so the model resolves the facts at read-time. This
it first). The model performs the substitution at read-time. avoids a build step and keeps a single source of truth in the repo.
This avoids a build step and keeps a single source of truth in
the repo.
## Sittenkodex split ## Sittenkodex split
@@ -104,18 +110,19 @@ which are conditions for the plugin's own correctness.
The relationship: The relationship:
- **Plugin** (this repo): mechanics, universal discipline - **Plugin** (this repo): mechanics, universal discipline, fixed
- **Profile** (per project): slots — paths, commands, conventions
vocabulary, naming, git conventions, pipeline customisations - **Project CLAUDE.md**: project facts — the few mechanical facts
- **Project CLAUDE.md**: sittenkodex — domain-specific anti- the skills consume (code roots, build/test, tracker slug, …) —
patterns and acceptance criteria plus sittenkodex (domain-specific anti-patterns and acceptance
criteria)
## What's out of scope for this plugin ## What's out of scope for this plugin
- **Issue-tracker integration**: the plugin can read the - **Issue-tracker integration**: the plugin reads the project's
profile's `issue_tracker.kind`, `issue_tracker.list_cmd`, and issue-tracker commands (the repo slug, list command, and
`issue_tracker.show_cmd` and invoke the configured listing / single-issue-with-comments command, all in its CLAUDE.md project
single-issue commands, and `specify` may post a reconciliation facts) and invokes them, and `specify` may post a reconciliation
comment via the tracker's comment command — but the plugin does comment via the tracker's comment command — but the plugin does
not directly call Gitea / GitHub / Linear APIs. Every read and not directly call Gitea / GitHub / Linear APIs. Every read and
write goes through the configured shell command, so the plugin write goes through the configured shell command, so the plugin
+9 -10
View File
@@ -9,18 +9,17 @@ this convention.
## Where it lives ## Where it lives
A project opts in by setting `paths.glossary` in its A project opts in by naming a glossary path in its CLAUDE.md project
`.claude/dev-cycle-profile.yml` (see `profile-schema.md` § `paths`). facts (see `conventions.md`). When it is named, the file it points to
When the slot is set, the file it names is standing reading for every is standing reading for every role — no separate standing-reading entry
role — no separate `standing_reading.always` entry is required. When is required. When the project names none, the whole feature is a
the slot is unset, the whole feature is a documented no-op. documented no-op.
A set glossary is the source of truth for the project's nomenclature. A glossary is the source of truth for the project's nomenclature.
Where any other document names a concept differently — including the Where any other document names a concept differently — including the
example renamings in `profile-schema.md` § `vocabulary` — the fixed vocabulary in `conventions.md` (cycle / iteration / milestone /
glossary's canonical entry, and its **Avoid** list, win. A contract) — the glossary's canonical entry, and its **Avoid** list,
`vocabulary.*` slot only sets which term the glossary then pins as win.
canonical; it does not override the glossary.
## Format ## Format
+9 -4
View File
@@ -36,9 +36,12 @@ the structural binding.
`docs/design/INDEX.md`, `crates/`, `bench/`). `docs/design/INDEX.md`, `crates/`, `bench/`).
2. Strip project-specific commands (`cargo build`, 2. Strip project-specific commands (`cargo build`,
`bench/check.py`). `bench/check.py`).
3. Replace literals with profile-slot references in prose. 3. Replace literals with fixed conventions named directly (see
`conventions.md`) or, where they vary per project, a reference to
the project's `CLAUDE.md` project facts.
4. Strip project vocabulary (`AILang`, `Form A`, `.ail.json`, 4. Strip project vocabulary (`AILang`, `Form A`, `.ail.json`,
`Boss`); use the profile's vocabulary slots. `Boss`); use the fixed vocabulary (cycle / iteration / milestone /
contract).
5. Strip project-specific contracts (honesty-rule, 5. Strip project-specific contracts (honesty-rule,
feature-acceptance). These belong in the project's own feature-acceptance). These belong in the project's own
`CLAUDE.md`, not the plugin. `CLAUDE.md`, not the plugin.
@@ -51,8 +54,10 @@ the structural binding.
1. Drop the `ailang-` prefix from the `name:` frontmatter 1. Drop the `ailang-` prefix from the `name:` frontmatter
field. The skill path is the disambiguator. field. The skill path is the disambiguator.
2. Replace hardcoded standing-reading paths 2. Replace hardcoded standing-reading paths
(`docs/design/INDEX.md`, etc.) with a reference to the profile's (`docs/design/INDEX.md`, etc.) with the fixed standing reading
`standing_reading` section. (`CLAUDE.md` + `git log -10`) plus, for role-specific files, a
reference to the per-role standing reading in the project's
`CLAUDE.md` project facts.
3. Replace project-specific Iron Law clauses with the universal 3. Replace project-specific Iron Law clauses with the universal
discipline constants; project-specific clauses go to the discipline constants; project-specific clauses go to the
project's own `CLAUDE.md`. project's own `CLAUDE.md`.
+21 -19
View File
@@ -98,15 +98,16 @@ Hard-gate before plan — the spec-production core and the carrier of the
"no plan without an approved spec" invariant. Takes a settled design "no plan without an approved spec" invariant. Takes a settled design
(directly from sources, or a ratified design handed over by (directly from sources, or a ratified design handed over by
`brainstorm`), applies the feature-acceptance criterion, writes the `brainstorm`), applies the feature-acceptance criterion, writes the
spec to the configured `spec_dir`, runs the parse-every-block and spec to `docs/specs`, runs the parse-every-block and
`grounding-check` gates, and takes user sign-off — with review but no `grounding-check` gates, and takes user sign-off — with review but no
interview. Bounces to `brainstorm` the moment the sources do not interview. Bounces to `brainstorm` the moment the sources do not
resolve a load-bearing design decision. A core node, not opt-in resolve a load-bearing design decision. A core node — the
(unlike `tdd`). spec-production gate before `planner` on every design path.
The sign-off is the user's by default, including under `/boss`. The The sign-off is the user's by default, including under `/boss`. The
one exception is the opt-in `pipeline.boss.spec_auto_sign` slot: with one exception is spec auto-sign (a project that enables it in its
it on, a `/boss` run may sign a spec in the user's place — but only CLAUDE.md project facts): with it on, a `/boss` run may sign a spec in
the user's place — but only
when every objective gate is green AND a unanimous five-lens when every objective gate is green AND a unanimous five-lens
`spec-skeptic` panel passes; the orchestrator's own confidence never `spec-skeptic` panel passes; the orchestrator's own confidence never
signs. A `BLOCK` is never signed over: an editorial one (`criterion` / signs. A `BLOCK` is never signed over: an editorial one (`criterion` /
@@ -123,7 +124,7 @@ resolution instead of blocking on the stale body. See
### planner ### planner
Hard-gate before implement. Produces a placeholder-free, Hard-gate before implement. Produces a placeholder-free,
bite-sized implementation plan in the configured `plan_dir` bite-sized implementation plan in `docs/plans`
that the implement skill can execute task-by-task. Dispatches that the implement skill can execute task-by-task. Dispatches
the plan-recon agent for read-only file-structure mapping. the plan-recon agent for read-only file-structure mapping.
@@ -150,7 +151,7 @@ the GREEN side to the implement skill in mini mode.
### tdd ### tdd
Opt-in alternative to the `brainstorm → specify → planner` design entry, A standard alternative entry, alongside `brainstorm → specify → planner`,
for work whose desired behaviour is test-specifiable — expressible for work whose desired behaviour is test-specifiable — expressible
as one failing test. RED-first: the `tdd-author` agent turns a as one failing test. RED-first: the `tdd-author` agent turns a
description or issue into a single minimal, autonomous RED description or issue into a single minimal, autonomous RED
@@ -213,9 +214,9 @@ documents what the skill skips and under what conditions:
- `implement` is the iteration body; not skippable. - `implement` is the iteration body; not skippable.
- `audit` is mandatory at cycle close. - `audit` is mandatory at cycle close.
- `debug` is mandatory RED-first for any observable bug. - `debug` is mandatory RED-first for any observable bug.
- `tdd` is an opt-in alternative entry to `brainstorm` for - `tdd` is a standard alternative entry to `brainstorm` for
test-specifiable work; it bounces back to `brainstorm` on a test-specifiable work; it bounces back to `brainstorm` on a
design fork. A profile that omits the `tdd` phase disables it. design fork. Always available — not opt-in.
- `fieldtest` and `docwriter` are optional and orchestrator- - `fieldtest` and `docwriter` are optional and orchestrator-
dispatched. dispatched.
@@ -225,14 +226,15 @@ commit body — never as undocumented practice.
## Pipeline configuration ## Pipeline configuration
The phase set, gating, and conditional dispatch are configured There is none. The phase set, the gates, and the conditional
in the project profile under `pipeline:`. A project that does dispatch shown above are fixed — the same for every project. All
not want `fieldtest` simply omits the key. A project that wants phases (`brainstorm`, `specify`, `planner`, `implement`, `audit`,
a different gate set (e.g. `planner` without a `brainstorm` `debug`, `tdd`, `fieldtest`, `docwriter`) are always available; which
gate, for trivial bug-fix iterations) configures it there. ones run on a given iteration is the orchestrator's judgement per the
skip rules above, not a per-project setting. The only behavioural
toggle is spec auto-sign under `/boss`, declared in a project's
CLAUDE.md project facts. See `conventions.md`.
See `profile-schema.md` for the syntax. If a project declares a glossary in its CLAUDE.md project facts, that
file is standing reading for every role — the canonical-nomenclature
If the profile sets `paths.glossary`, that file is standing reading source every skill and agent consults (see `glossary-convention.md`).
for every role — the canonical-nomenclature source every skill and
agent consults (see `glossary-convention.md`). Unset, it is a no-op.
-290
View File
@@ -1,290 +0,0 @@
# Profile schema
Location: `<project-root>/.claude/dev-cycle-profile.yml`
Encoding: YAML. Each top-level key is a section. Keys are
lowercase snake_case. Lists are YAML sequences.
## `paths`
| Key | Type | Default | Description |
|---------------------|--------|------------------------|-------------|
| `spec_dir` | string | `docs/specs` | Where the specify skill writes specs. |
| `plan_dir` | string | `docs/plans` | Where the planner skill writes plans. |
| `glossary` | string | (unset) | Canonical-nomenclature file (optional). If set, it is standing reading for every role — no separate `standing_reading.always` entry is needed; unset is a documented no-op. See `glossary-convention.md`. |
| `design_ledger` | string | `docs/design/INDEX.md` | Canonical specification index (optional — projects without a design ledger can omit). |
| `design_contracts` | string | `design/contracts` | Directory of prose-authoritative contracts (optional). |
| `design_models` | string | `design/models` | Directory of onboarding whitepapers (optional). |
| `code_roots` | list | `[src]` | Code directories the architect / quality reviewer walk. |
| `bench_dir` | string | `bench` | Where regression harnesses live (optional). |
| `public_interface` | list | `[README.md, docs]` | Directories and files the `fieldtester` may read — the project's outward-facing surface (READMEs, design ledger, examples, public API docs). Everything else (especially `code_roots` and `bench_dir`) is forbidden to the fieldtester. |
| `fieldtest_examples`| string | `examples/fieldtest` | Where the `fieldtester` agent writes its fixtures. |
Omitted optional keys signal that the feature is unused in this
project; skills that depend on them either short-circuit or
skip the corresponding step.
### Aspirational-source marker (recommendation)
Files under `design_models` (or an equivalent `RFCs` /
`proposals` directory) commonly carry aspirational code —
constructs written before the surface that would parse them
exists. To let a later specify tell aspirational content from
validated contract, projects are encouraged (not required) to
give each such file a frontmatter marker:
```yaml
---
status: aspirational
validated-against: <commit-sha | "no validation">
---
```
`status: aspirational` says "the code here is a target, not a
verified fact"; `validated-against` records the last commit at
which someone actually ran the code through the live tool (or
`"no validation"`). A design ledger (`design_ledger`) is likewise
encouraged to distinguish "model" rows from "contract" rows so a
reading agent can mechanically tell which carry verified
behaviour.
When a file lacks the marker the signal is simply absent — the
specify skill degrades to treating its content as unmarked, never
hard-failing. The marker is consumed by the specify skill (see
its Step 1 and Step 4): content lifted from an aspirational source
is flagged and must clear the Step-4 parse-every-block gate before
it ships in a spec.
## `naming`
| Key | Type | Default | Description |
|--------------------|--------|----------------------------------|-------------|
| `counter_dirs` | list | `[docs/specs, docs/plans, design/contracts, design/models]` | Directories that use the counter-prefix policy. |
| `policy` | enum | `stable_per_directory_4digit` | One of `stable_per_directory_4digit`, `date_prefix`, `flat`. |
| `slug_separator` | string | `-` | Separator inside the slug. |
`stable_per_directory_4digit` means each listed directory has a
per-directory counter, 4-digit zero-padded, assigned in
creation order, stable for the life of the file. New files
take the next-higher number; deleted files retire their number.
`date_prefix` uses `YYYY-MM-DD-slug.md`.
`flat` uses `slug.md`.
## `commands`
| Key | Type | Default | Description |
|----------------|--------|----------------|-------------|
| `build` | string | (required) | Build command — exit 0 means success. |
| `test` | string | (required) | Test command — exit 0 means success. |
| `lint` | string | (optional) | Lint command — exit 0 means success. |
| `doc_build` | string | (optional) | Documentation-build command used by the `docwriter` skill. Should print warnings on stderr so the agent can enumerate them (e.g. `cargo doc --no-deps 2>&1`). Omit if the project has no API docs. |
| `regression` | list | `[]` | Regression scripts run by the audit skill. Each entry is a shell command; non-zero exit is a regress. |
| `architect_sweeps` | list | `[]` | Project-specific architect sweep commands run by the `architect` agent in addition to its universal checks. Each entry is a shell command; non-zero exit means at least one sweep matched and the matches are drift-suspicions to verify. Optional. |
## `spec_validation`
Optional. A registry mapping each markdown fence label to the tool
that validates a spec code block of that kind. The specify
parse-gate and the grounding-check code-block pass run these
parsers so that spec code blocks are treated as hypotheses to
verify, not as authoritative truth.
```yaml
spec_validation:
parsers:
ail:
ext: ".ail"
cmd: "ail parse {file}"
ail-json:
ext: ".ail.json"
cmd: "ail check {file}"
ll:
ext: ".ll"
cmd: "llvm-as {file} -o /dev/null"
```
The key of each `parsers` entry is the fence info-string of a spec
code block (the token immediately after the opening ` ``` `). Only
blocks whose label has an entry are validated; a block whose label
is absent from the map is skipped and the skip is documented ("no
parser for fence label X") — never a silent pass.
| Key | Type | Description |
|-------|--------|-------------|
| `ext` | string | Extension (including the leading dot) the harness gives the temp file it writes the block into, so tools that key off extension — `.ail` vs `.ail.json` — see the right one. |
| `cmd` | string | Validation command. MUST contain the `{file}` placeholder, which is substituted with the temp file's path. Exit 0 means a clean parse; any non-zero exit is a parse failure the consuming skill turns into a BLOCK. |
A malformed entry — `cmd` missing the `{file}` placeholder, or
either `ext` or `cmd` absent — is a profile error the consuming
skill surfaces, not a silent skip; the gate fails closed.
Omitting the whole `spec_validation` section disables the
block-validation gates: the consuming skills short-circuit, exactly
as with other omitted optional features.
## `vocabulary`
| Key | Type | Default | Description |
|----------------|--------|----------------|-------------|
| `cycle` | string | `cycle` | One round in the pipeline graph (NOT the top-level container). Examples: `cycle`, `release`, `epic`. |
| `subcycle` | string | `iteration` | A sub-unit of a cycle. Examples: `iteration`, `sprint`, `story`. |
| `milestone` | string | `milestone` | Tracker container spanning many cycles; closes only when complete AND functional (see `pipeline.md` § Milestone-close gate). Examples: `milestone`, `epic`, `release`. |
| `ledger_entry` | string | `contract` | What a single design-ledger entry is called. Examples: `contract`, `RFC`, `ADR`. |
Skills use these names in their generated artefacts and prose.
Picking accurate vocabulary keeps prose readable; the underlying
mechanics are identical regardless of name.
The renamings shown as examples above illustrate the slot only; they
are not nomenclature for any particular project. When a project sets
`paths.glossary`, that glossary is the source of truth for its
nomenclature and overrides these examples where they collide — a word
offered here may sit under **Avoid** in a given project's glossary
(see `glossary-convention.md`).
## `standing_reading`
| Key | Type | Default | Description |
|----------------|--------|----------------|-------------|
| `always` | list | `[CLAUDE.md]` | Files every agent reads at start of every dispatch. |
| `by_role` | map | `{}` | Map from role name to list of additional files. |
Role names match agent slugs: `architect`, `bencher`, `debugger`,
`implementer`, `tester`, `fieldtester`, `docwriter`,
`grounding-check`, `plan-recon`, `spec-reviewer`, `quality-reviewer`.
Entries may be shell commands as well as file paths — they are
read as opaque strings the agent should fetch / execute, e.g.
`"git log -10 --format=full"`.
A set `paths.glossary` is implicitly appended to every role's
`always` list — it does not need its own entry here. The slot's
authoritative semantics live at the `paths` row above.
## `git`
| Key | Type | Default | Description |
|------------------------------|------|---------|-------------|
| `main_sacrosanct` | bool | `true` | If true, no actor may reset or revert main. |
| `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`. |
| `issue_tracker.show_cmd` | string | (empty) | Shell command that renders **one** issue **with its comment thread**; the orchestrator and the `spec-skeptic` `scope-fork` juror append the issue index as the final argument (e.g. `tea issues --comments``tea issues --comments 55`). MUST include comments — a `specify` reconciliation comment (see `specify/SKILL.md` Step 1.5) is invisible to the juror otherwise. Examples: `tea issues --comments`, `gh issue view --comments`. If empty, the juror reads only the issue body and a fork resolved in-context but not echoed into the body cannot be ratified — auto-sign falls back to the human sign-off. |
| `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.
```yaml
pipeline:
brainstorm: {} # optional discovery front-end; no hard gate of its own
specify:
gates: [planner] # core node — planner cannot start until the spec is approved
planner:
gates: [implement]
implement: {} # standard
audit:
mandatory_at: cycle_close # auto-fires at end of each cycle
fieldtest:
boss_only: true # only orchestrator dispatches
when: surface_touch # condition tag (orchestrator judgement)
milestone_fieldtest:
boss_only: true
when: surface_touch # end-to-end proof of the milestone's promise
gates_close: milestone # its green roll-up is the functional leg of the milestone-close gate
docwriter:
boss_only: true
when: api_stable_across_n_cycles
debug:
trigger: bug # observable misbehaviour
red_first: true # RED test before any fix
# specify above is a CORE node (always present); tdd below is opt-in.
tdd: # opt-in: omit the key to disable the entry path
trigger: test_specifiable_feature # behaviour expressible as one failing test
red_first: true # RED executable-spec before any implementation
alt_to: brainstorm # alternative design entry; bounces back on a design fork
boss:
user_invoked: true # autonomous-orchestrator mode, /boss
spec_auto_sign: false # opt-in: let /boss sign a spec in the user's place (default off)
```
Phases not listed are disabled for the project. A project that
does not want a `fieldtest` phase simply omits the key. `tdd` is
opt-in the same way.
`boss.spec_auto_sign` is an opt-in slot, default off (a missing key
reads as `false`). With it off — the conservative default — a
`specify` dispatch in a `/boss` session always pauses at its Step-6
user-review gate for the user's signature, exactly as before. With it
**on**, the orchestrator may sign a spec in the user's place, but only
through `specify`'s auto-sign gate: every objective gate green
(precondition, parse, a `grounding-check` `PASS` with no human
override) AND a unanimous five-lens `spec-skeptic` panel. A `BLOCK` is
never signed over: an *editorial* one (`criterion` / `ambiguity` /
`plan-readiness`) the orchestrator repairs in a bounded loop (≤ 2
rounds, re-running the objective gates and re-dispatching all five
lenses each round), while a *design* one (`scope-fork` / `grounding`),
an `INFRA_ERROR`, any objective gate not green, or an exhausted budget
falls back to the human sign-off pause. Model self-confidence alone
never signs — the gate is built specifically not to rely on it. On a
clean sign the
orchestrator commits the spec (subject carries `(boss-signed)`), sends
the mandatory informational-with-veto notify, and continues to
`planner` without stopping. See `../specify/SKILL.md` Step 6 (gate
owner), `../specify/agents/spec-skeptic.md` (the juror), and
`../boss/SKILL.md` §"Spec auto-sign" (notify + veto contract). `specify`, by contrast, is a **core** node — it
is the spec-production gate before `planner` on every design path,
reachable directly from settled sources or via the optional
`brainstorm` discovery stage. `tdd` opt-in only adds the
test-specifiable bypass; with `tdd` omitted, the design entry paths
are `brainstorm → specify → planner` and `specify → planner`.
## Example: minimal profile
```yaml
paths:
spec_dir: docs/specs
plan_dir: docs/plans
code_roots: [src]
commands:
build: cargo build
test: cargo test
vocabulary:
cycle: cycle
subcycle: iteration
standing_reading:
always:
- CLAUDE.md
- "git log -10 --format=full"
git:
issue_tracker:
kind: github
close_marker: "closes #N"
pipeline:
brainstorm: {} # optional discovery; no hard gate
specify: { gates: [planner] }
planner: { gates: [implement] }
implement: {}
audit: { mandatory_at: cycle_close }
debug: { trigger: bug, red_first: true }
```
This minimal profile enables five phases, no fieldtest, no
docwriter, no design-ledger. Good starting point for a small
project.
+3 -3
View File
@@ -23,9 +23,9 @@ never on a cycle clock.
Orchestrator-dispatched only. Audit closing **does not** Orchestrator-dispatched only. Audit closing **does not**
trigger docwriter. Trigger conditions are any of: trigger docwriter. Trigger conditions are any of:
- The command configured under `commands.doc_build` in the - The project's doc-build command (its CLAUDE.md project facts)
project profile shows accumulated warnings across multiple shows accumulated warnings across multiple components after a
components after a stability window of several cycles. stability window of several cycles.
- A backlog issue like "doc warning sweep" has matured — the - A backlog issue like "doc warning sweep" has matured — the
surface it targets has not moved for a while. surface it targets has not moved for a while.
- Onboarding-readability check: navigating the generated docs - Onboarding-readability check: navigating the generated docs
+21 -21
View File
@@ -36,24 +36,24 @@ rename you make on the way.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` plus Always read `CLAUDE.md` (for the orchestrator framing) and
`standing_reading.by_role.docwriter` in the project profile. `git log -10 --format=full`, plus the per-role standing reading
The defaults include `CLAUDE.md` for the orchestrator framing. the project lists in its CLAUDE.md project facts for the
If the project has a design ledger configured under docwriter role. If the project has a design ledger (its
`paths.design_ledger`, walk it for the invariants the doc CLAUDE.md project facts), walk it for the invariants the doc
strings must reflect. strings must reflect.
Additionally: Additionally:
- `git log -10 --oneline` scoped to the project's code roots - `git log -10 --oneline` scoped to the project's code roots
(`paths.code_roots`) — to spot which components recently (its CLAUDE.md project facts) — to spot which components
shifted (those are likeliest to have stale docs). recently shifted (those are likeliest to have stale docs).
- The components named in the carrier — read every public item - The components named in the carrier — read every public item
before writing a single doc line. You can't summarise an before writing a single doc line. You can't summarise an
item you haven't read. item you haven't read.
- Run the command configured under `commands.doc_build` and - Run the project's doc-build command (its CLAUDE.md project
read all warnings. Every warning the carrier names must be facts) and read all warnings. Every warning the carrier names
gone when you're done. must be gone when you're done.
## Carrier contract — what the controller hands you ## Carrier contract — what the controller hands you
@@ -71,7 +71,7 @@ If `scope` is empty, return `NEEDS_CONTEXT`.
## The Iron Law ## The Iron Law
``` ```
NO API CHANGES. NO RENAMES. NO NEW PUBLIC EXPORTS. NO EDITS UNDER paths.design_ledger / paths.design_contracts / paths.design_models / paths.spec_dir. NO API CHANGES. NO RENAMES. NO NEW PUBLIC EXPORTS. NO EDITS UNDER THE PROJECT'S DESIGN LEDGER / DESIGN CONTRACTS / DESIGN MODELS (ITS CLAUDE.md PROJECT FACTS) OR docs/specs.
DOC COMMENTS ONLY. FINDINGS GET REPORTED, NOT FIXED. DOC COMMENTS ONLY. FINDINGS GET REPORTED, NOT FIXED.
EVERY PUBLIC ITEM YOU TOUCH MUST EITHER BE DOCUMENTED OR THE WARNING CLEARED. EVERY PUBLIC ITEM YOU TOUCH MUST EITHER BE DOCUMENTED OR THE WARNING CLEARED.
YOU NEVER COMMIT. DOC EDITS LIVE IN THE WORKING TREE; THE ORCHESTRATOR COMMITS. YOU NEVER COMMIT. DOC EDITS LIVE IN THE WORKING TREE; THE ORCHESTRATOR COMMITS.
@@ -118,10 +118,10 @@ Javadoc `/** */`, etc.) for other languages.
is so confusing it needs renaming, raise it in your report is so confusing it needs renaming, raise it in your report
instead of changing it. instead of changing it.
- No new public exports. Visibility stays as-is. - No new public exports. Visibility stays as-is.
- No edits under the project's design or specs directories - No edits under the project's design directories — its design
(`paths.design_ledger`, `paths.design_contracts`, ledger, design contracts, and design models (its CLAUDE.md
`paths.design_models`, `paths.spec_dir`). The orchestrator project facts) — or `docs/specs`. The orchestrator owns those
owns those and the issue backlog. and the issue backlog.
- Don't paper over broken behaviour with prose — if - Don't paper over broken behaviour with prose — if
doc-writing surfaces a real bug (a function whose doc you doc-writing surfaces a real bug (a function whose doc you
cannot honestly write because it doesn't actually do what cannot honestly write because it doesn't actually do what
@@ -129,11 +129,11 @@ Javadoc `/** */`, etc.) for other languages.
## Verification (all must pass before reporting `DONE`) ## Verification (all must pass before reporting `DONE`)
- `commands.doc_build` from the profile — zero warnings on - The project's doc-build command (its CLAUDE.md project facts)
every line you touched. — zero warnings on every line you touched.
- `commands.build` from the profile — green. - The project's build command — green.
- `commands.test` from the profile — green (doctests count - The project's test command — green (doctests count if the
if the language has them). language has them).
## Status protocol ## Status protocol
@@ -195,7 +195,7 @@ for the orchestrator handoff, the produced fields are:
directories directories
- About to write a doc comment that contradicts the function - About to write a doc comment that contradicts the function
body body
- About to skip the `commands.doc_build` re-run after edits - About to skip the project's doc-build re-run after edits
- About to run `git commit` (anywhere, ever — you never - About to run `git commit` (anywhere, ever — you never
commit) commit)
- About to report `DONE` while one of the three verification - About to report `DONE` while one of the three verification
+6 -4
View File
@@ -20,7 +20,7 @@ debt — even when audit reports `clean`.
The skill produces a friction-and-bug spec that the next The skill produces a friction-and-bug spec that the next
iteration's `planner` consumes as a reference. The spec sits iteration's `planner` consumes as a reference. The spec sits
next to cycle-design specs under `paths.spec_dir`, with a next to cycle-design specs under `docs/specs`, with a
`fieldtest-` prefix in the slug. `fieldtest-` prefix in the slug.
The substantive process — read the design ledger + cycle spec The substantive process — read the design ledger + cycle spec
@@ -29,7 +29,8 @@ per cycle axis, implement each as a downstream consumer, run
the result, classify findings, write the spec — lives in the result, classify findings, write the spec — lives in
`agents/fieldtester.md`. That file also carries the spec `agents/fieldtester.md`. That file also carries the spec
template, the source-isolation discipline (no reading under template, the source-isolation discipline (no reading under
`paths.code_roots` or `paths.bench_dir`), and the per-finding the project's code roots or its benchmark directory, if it has
one — its CLAUDE.md project facts), and the per-finding
classification rules. This skill file only governs trigger, classification rules. This skill file only governs trigger,
dispatch, and handoff. dispatch, and handoff.
@@ -106,8 +107,9 @@ EVERY FRICTION POINT AND BUG IS RECORDED. NONE IS WORKED AROUND.
The first clause is load-bearing: the whole point of the The first clause is load-bearing: the whole point of the
field test is to simulate a downstream consumer who has only field test is to simulate a downstream consumer who has only
the public interface. The agent file enforces this with a the public interface. The agent file enforces this with a
hard path allowlist (computed from `paths.public_interface` hard path allowlist (computed from the project's public
in the profile); the orchestrator must trust that contract interface, if it has one — its CLAUDE.md project facts); the
orchestrator must trust that contract
and not feed the agent implementation-internal hints in the and not feed the agent implementation-internal hints in the
carrier. carrier.
+33 -29
View File
@@ -34,20 +34,22 @@ is for. Diagnostic unclear is *the finding*. Spec silent is
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` Always read `CLAUDE.md` (for role boundaries) and
plus `standing_reading.by_role.fieldtester` in the project `git log -10 --format=full`, plus the per-role standing reading
profile. The defaults include `CLAUDE.md` for role boundaries. the project lists in its CLAUDE.md project facts for the
fieldtester role.
In addition, you may read **only** files under the paths In addition, you may read **only** files under the project's
configured in `paths.public_interface` in the project profile. public interface, if it has one (its CLAUDE.md project facts).
This is the project's outward-facing surface (typically: This is the project's outward-facing surface (typically:
README, the design ledger at `paths.design_ledger` if any, README, the design ledger if any, the docs directory, the
the docs directory, the examples corpus). You may NOT use examples corpus). You may NOT use the examples as a hint about
the examples as a hint about how the implementation handles how the implementation handles edge cases; only as a hint about
edge cases; only as a hint about the shape of the surface. the shape of the surface.
You may also read fixtures you yourself create under You may also read fixtures you yourself create under the
`paths.fieldtest_examples`, plus any artefacts you produce project's fieldtest examples directory, if it has one (its
CLAUDE.md project facts), plus any artefacts you produce
by running the project (binaries, output files, generated by running the project (binaries, output files, generated
IR, etc.). IR, etc.).
@@ -69,7 +71,7 @@ skill references it rather than restating it.
| `commit_range` | `<prev-cycle-close>..HEAD` | | `commit_range` | `<prev-cycle-close>..HEAD` |
If `axis_hints` is empty, infer from the cycle's spec under If `axis_hints` is empty, infer from the cycle's spec under
`paths.spec_dir` and the most recent iter commit bodies; if `docs/specs` and the most recent iter commit bodies; if
both are also empty, return `NEEDS_CONTEXT`. both are also empty, return `NEEDS_CONTEXT`.
### Milestone-scope variant ### Milestone-scope variant
@@ -105,13 +107,13 @@ RECORD WHAT HAPPENS. DO NOT FIX. DO NOT WORK AROUND.
The first clause is what makes this dispatch a field test The first clause is what makes this dispatch a field test
rather than yet another internal review. If you are about to rather than yet another internal review. If you are about to
read anything under `paths.code_roots` or `paths.bench_dir` read anything under the project's code roots or its benchmark
(from the project profile), **stop**. directory (its CLAUDE.md project facts), **stop**.
The paths you may open are exactly: The paths you may open are exactly:
- Files under `paths.public_interface` (from the profile) - Files under the project's public interface (its CLAUDE.md project facts)
- Files under `paths.fieldtest_examples` that **you** create - Files under the project's fieldtest examples directory that **you** create
- Artefacts you produce by running the project (binaries, - Artefacts you produce by running the project (binaries,
output files, generated IR if exposed as part of the public output files, generated IR if exposed as part of the public
interface) interface)
@@ -147,9 +149,9 @@ Each phase completes before the next starts.
current working tree.** A field test that runs a stale pre-built binary current working tree.** A field test that runs a stale pre-built binary
silently inverts its own purpose: it reports the *previously shipped* silently inverts its own purpose: it reports the *previously shipped*
state as current, producing false positives on already-fixed bugs and state as current, producing false positives on already-fixed bugs and
masking newly-introduced ones. Run the build command from masking newly-introduced ones. Run the project's build command (its
`commands.build` (or build the specific consumer binary the examples CLAUDE.md project facts) — or build the specific consumer binary the
invoke) and confirm it succeeds before Phase 2 step 1; if the examples examples invoke and confirm it succeeds before Phase 2 step 1; if the examples
invoke a release binary, build the release profile, not just debug. When invoke a release binary, build the release profile, not just debug. When
in doubt, invoke the tool through the build system (e.g. `cargo run`) in doubt, invoke the tool through the build system (e.g. `cargo run`)
rather than a path to a pre-existing artefact, so HEAD is always what rather than a path to a pre-existing artefact, so HEAD is always what
@@ -164,8 +166,9 @@ For each example, in this order:
tool, etc.). Reach for the cycle's new surface where it tool, etc.). Reach for the cycle's new surface where it
fits naturally — but do not contort an example to use a fits naturally — but do not contort an example to use a
feature that doesn't fit. feature that doesn't fit.
2. Save under `paths.fieldtest_examples` with a name 2. Save under the project's fieldtest examples directory (its
like `<cycle-short>_<n>_<slug>.<ext>`. CLAUDE.md project facts) with a name like
`<cycle-short>_<n>_<slug>.<ext>`.
3. Run the project the way a user would. Record the exact 3. Run the project the way a user would. Record the exact
commands, the exact output, the exact errors. commands, the exact output, the exact errors.
4. Record verbatim: 4. Record verbatim:
@@ -208,8 +211,9 @@ not merged.
### Phase 5 — Write the spec, hand back ### Phase 5 — Write the spec, hand back
Write the fieldtest spec under `paths.spec_dir` with a name Write the fieldtest spec under `docs/specs` with a name
shape per the project's naming convention. Use the spec following the `NNNN-slug.md` convention (4-digit prefix,
per-directory; see `docs/conventions.md`). Use the spec
template below. Leave all artefacts (the fixtures and the template below. Leave all artefacts (the fixtures and the
spec file) in the working tree as unstaged changes. You do spec file) in the working tree as unstaged changes. You do
NOT commit — the orchestrator commits after reading the NOT commit — the orchestrator commits after reading the
@@ -280,7 +284,7 @@ At most 350 words, structured:
+ outcome (built? ran? matched expected?). + outcome (built? ran? matched expected?).
- **Findings count by class:** e.g. - **Findings count by class:** e.g.
`bugs: 1, friction: 2, spec_gap: 1, working: 3`. `bugs: 1, friction: 2, spec_gap: 1, working: 3`.
- **Spec path:** under `paths.spec_dir`. - **Spec path:** under `docs/specs`.
- **Per-finding recommendation:** `bug → debug`, - **Per-finding recommendation:** `bug → debug`,
`friction → plan` (tidy iteration), `friction → plan` (tidy iteration),
`spec_gap → ratify` or `tighten the design ledger`, `spec_gap → ratify` or `tighten the design ledger`,
@@ -298,7 +302,7 @@ fields are:
| Field | Content | | Field | Content |
|-------|---------| |-------|---------|
| `spec_path` | spec file under `paths.spec_dir` with a `fieldtest-` prefix | | `spec_path` | spec file under `docs/specs` with a `fieldtest-` prefix |
| `examples_added` | list of fixture paths committed | | `examples_added` | list of fixture paths committed |
| `findings` | list, each with class (`bug` / `friction` / `spec_gap` / `working`) + recommendation | | `findings` | list, each with class (`bug` / `friction` / `spec_gap` / `working`) + recommendation |
@@ -309,8 +313,8 @@ fields are:
- Refactors of existing fixtures in the examples corpus. - Refactors of existing fixtures in the examples corpus.
- Edits to any file under the design ledger or specs - Edits to any file under the design ledger or specs
directory. Spec gaps are reported, not patched. directory. Spec gaps are reported, not patched.
- Edits to anything under `paths.code_roots` or - Edits to anything under the project's code roots or its
`paths.bench_dir`. benchmark directory (its CLAUDE.md project facts).
- A `friction` finding without a 1-line recommendation. - A `friction` finding without a 1-line recommendation.
Every finding is actionable or it isn't a finding. Every finding is actionable or it isn't a finding.
- An "all-clean" report on a cycle that touched user-visible - An "all-clean" report on a cycle that touched user-visible
@@ -333,8 +337,8 @@ fields are:
## Red Flags — STOP and re-read the public interface ## Red Flags — STOP and re-read the public interface
- About to open any path under `paths.code_roots` or - About to open any path under the project's code roots or its
`paths.bench_dir` benchmark directory (its CLAUDE.md project facts)
- About to open an implementation-source file at all - About to open an implementation-source file at all
- About to hand-author an intermediate representation, - About to hand-author an intermediate representation,
internal serialisation, or any non-canonical fixture form internal serialisation, or any non-canonical fixture form
+25 -22
View File
@@ -30,15 +30,15 @@ Triggers:
- **maintain** — a term is to be added, changed, or removed in an - **maintain** — a term is to be added, changed, or removed in an
existing glossary, by the user any time, or by boss to record reality existing glossary, by the user any time, or by boss to record reality
(a term already in consistent use, or a drift boss just resolved). (a term already in consistent use, or a drift boss just resolved).
- **bootstrap** — a project has terminology to pin but no glossary - **bootstrap** — a project has terminology to pin but no glossary (no
(`paths.glossary` unset, or naming an empty file), and the user invokes glossary path in its CLAUDE.md project facts, or the named file is
the build. empty), and the user invokes the build.
Skip or refuse: Skip or refuse:
- maintain asked with no `paths.glossary` slot set: there is nowhere to - maintain asked when the project's CLAUDE.md project facts name no
write. Stop and instruct the user to set `paths.glossary` (see glossary path: there is nowhere to write. Stop and instruct the user to
`../docs/profile-schema.md` § `paths`) first. record the glossary path in the project's CLAUDE.md first.
- bootstrap asked on a glossary that already has entries: do not clobber. - bootstrap asked on a glossary that already has entries: do not clobber.
Stop with the entry count and recommend maintain. Stop with the entry count and recommend maintain.
- bootstrap asked in a boss (autonomous) session: refuse. bootstrap is - bootstrap asked in a boss (autonomous) session: refuse. bootstrap is
@@ -68,9 +68,10 @@ If the mode is ambiguous, ask once; do not guess.
## The maintain procedure ## The maintain procedure
1. **Read the glossary and the convention.** Read the file named by 1. **Read the glossary and the convention.** Read the glossary file the
`paths.glossary` and `../docs/glossary-convention.md`. If project's CLAUDE.md project facts name, plus
`paths.glossary` is unset, stop (see When to Use / Skipping). `../docs/glossary-convention.md`. If the project facts name no glossary
path, stop (see When to Use / Skipping).
2. **Take the proposed entry.** A canonical-term heading, an `**Avoid:**` 2. **Take the proposed entry.** A canonical-term heading, an `**Avoid:**`
line, and a definition — the user's, or (in a boss session bound by line, and a definition — the user's, or (in a boss session bound by
record-reality) the term already in consistent use. record-reality) the term already in consistent use.
@@ -96,14 +97,15 @@ If the mode is ambiguous, ask once; do not guess.
## The bootstrap procedure (user-only) ## The bootstrap procedure (user-only)
1. **Guard.** Read `paths.glossary`. If it names a file that already has 1. **Guard.** Read the glossary path from the project's CLAUDE.md project
entries, stop with the count and recommend maintain. If the slot is facts. If it names a file that already has entries, stop with the count
unset, continue, and note the build will also propose setting the slot and recommend maintain. If the project facts name no glossary path,
(see `../docs/profile-schema.md` § `paths`). continue, and note the build will also propose recording one in the
project's CLAUDE.md.
2. **Partition the prose surface into slices** — the readable prose of 2. **Partition the prose surface into slices** — the readable prose of
the project: `docs/`, `README.md`, the design ledger (if the project: `docs/`, `README.md`, the project's design ledger, if it
`paths.design_ledger` is set), the spec directory. One slice per has one (its CLAUDE.md project facts), the spec directory `docs/specs`.
coherent group, sized so a single agent can sweep it. One slice per coherent group, sized so a single agent can sweep it.
3. **Fan out one `glossary-extractor` per slice.** Dispatch the read-only 3. **Fan out one `glossary-extractor` per slice.** Dispatch the read-only
agent (`agents/glossary-extractor.md`) with the carrier: the slice and agent (`agents/glossary-extractor.md`) with the carrier: the slice and
the extraction task. Agents do not nest; the skill curates each the extraction task. Agents do not nest; the skill curates each
@@ -121,9 +123,10 @@ If the mode is ambiguous, ask once; do not guess.
6. **Handle the unresolved.** A contested cluster the user does not 6. **Handle the unresolved.** A contested cluster the user does not
resolve is left OUT of the glossary and noted as deferred. Never coin a resolve is left OUT of the glossary and noted as deferred. Never coin a
term to fill a gap. term to fill a gap.
7. **Assemble UNSTAGED.** Write the conforming glossary to 7. **Assemble UNSTAGED.** Write the conforming glossary to the path the
`paths.glossary` (proposing the slot value if it was unset), in the project's CLAUDE.md project facts name (proposing one if none is
convention's flat per-term-block format. Leave it unstaged for review. recorded yet), in the convention's flat per-term-block format. Leave it
unstaged for review.
## Iron Law ## Iron Law
@@ -167,9 +170,9 @@ BOOTSTRAP IS USER-ONLY. NEVER COIN A TERM — RECORD REALITY.
- **Rules (the single source):** `../docs/glossary-convention.md` - **Rules (the single source):** `../docs/glossary-convention.md`
format, reading obligation, write-rule, glossary-as-SoT. This skill format, reading obligation, write-rule, glossary-as-SoT. This skill
applies these; it restates none. applies these; it restates none.
- **Slot semantics:** `../docs/profile-schema.md` § `paths` the - **Glossary path:** the project's CLAUDE.md project facts — when they
`paths.glossary` slot (set ⇒ standing reading for every role; unset ⇒ name a glossary path it is standing reading for every role; when they
no-op). name none, this skill has nowhere to write and bootstrap proposes one.
- **Agent dispatched:** `agents/glossary-extractor.md` — read-only - **Agent dispatched:** `agents/glossary-extractor.md` — read-only
per-slice prose extraction, fanned out in bootstrap. per-slice prose extraction, fanned out in bootstrap.
- **Glossary instance (dogfood):** `../docs/glossary.md` — this plugin's - **Glossary instance (dogfood):** `../docs/glossary.md` — this plugin's
+5 -4
View File
@@ -19,10 +19,11 @@ slice and merges their reports.
## Standing reading list ## Standing reading list
Read everything in the standing reading list passed in the carrier before Read everything in the standing reading list passed in the carrier before
doing anything else. A set `paths.glossary` is part of every role's doing anything else. When the project's CLAUDE.md project facts name a
standing reading, and `docs/glossary-convention.md` defines what a glossary path, that glossary is standing reading for every role, and
glossary-worthy concept term is versus incidental vocabulary — consult it `docs/glossary-convention.md` defines what a glossary-worthy concept term
so you report concepts, not every capitalised word. is versus incidental vocabulary — consult it so you report concepts, not
every capitalised word.
## Carrier contract ## Carrier contract
+4 -4
View File
@@ -1,6 +1,6 @@
--- ---
name: implement name: implement
description: Use when an implementation plan exists under paths.plan_dir and is ready to execute, OR when a debug RED-test is handed off for a bugfix. Dispatches the implement-orchestrator agent, which runs the entire per-task loop (implementer phase → spec-compliance check → quality check, as sequential role-switches in its own context) directly in the working tree without creating commits, writes a stats file (and on BLOCKED/PARTIAL also `BLOCKED.md`), and returns a compressed end-report. The orchestrator reads the end-report, inspects the working tree, decides commit shape, and performs all commits. description: Use when an implementation plan exists under docs/plans and is ready to execute, OR when a debug RED-test is handed off for a bugfix. Dispatches the implement-orchestrator agent, which runs the entire per-task loop (implementer phase → spec-compliance check → quality check, as sequential role-switches in its own context) directly in the working tree without creating commits, writes a stats file (and on BLOCKED/PARTIAL also `BLOCKED.md`), and returns a compressed end-report. The orchestrator reads the end-report, inspects the working tree, decides commit shape, and performs all commits.
--- ---
# implement — plan execution via a dedicated orchestrator-agent # implement — plan execution via a dedicated orchestrator-agent
@@ -34,7 +34,7 @@ orchestrator-agent every dispatch.
Triggers: Triggers:
- A plan exists under `paths.plan_dir` (standard mode). - A plan exists under `docs/plans` (standard mode).
- A `debug` skill (RED test + cause) or a `tdd` skill (RED - A `debug` skill (RED test + cause) or a `tdd` skill (RED
executable-spec) has handed off for the GREEN side (mini mode). executable-spec) has handed off for the GREEN side (mini mode).
@@ -86,7 +86,7 @@ For a standard iteration:
Agent("implement-orchestrator", { Agent("implement-orchestrator", {
mode: "standard", mode: "standard",
iter_id: "<iter_id>", iter_id: "<iter_id>",
plan_path: "<path under paths.plan_dir>", plan_path: "<path under docs/plans>",
task_range: [3, 8] task_range: [3, 8]
}) })
``` ```
@@ -188,7 +188,7 @@ history rewinding on main even if there were.
| Source | Carrier | | Source | Carrier |
|--------|---------| |--------|---------|
| from `planner` | path to plan under `paths.plan_dir` (+ optional `task_range`) | | from `planner` | path to plan under `docs/plans` (+ optional `task_range`) |
| from `debug` | RED-test path + cause summary + minimal-fix constraint | | from `debug` | RED-test path + cause summary + minimal-fix constraint |
`implement` produces: an unstaged working tree containing the `implement` produces: an unstaged working tree containing the
+11 -10
View File
@@ -28,16 +28,16 @@ with it.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is fixed: `CLAUDE.md` plus
plus `standing_reading.by_role.implement-orchestrator` in the `git log -10 --format=full` (see docs/conventions.md). On top
project profile. The defaults include `CLAUDE.md` for of that, read the per-role standing reading the project lists
orchestrator framing. in its CLAUDE.md project facts for `implement-orchestrator`.
`CLAUDE.md` gives the orchestrator framing.
Additionally, every dispatch: Additionally, every dispatch:
- If the project has a design ledger configured under - If the project has a design ledger (its CLAUDE.md project
`paths.design_ledger`, walk it for the invariants any iter facts), walk it for the invariants any iter must respect.
must respect.
- `git log -5 --format=full` — full bodies of the last few - `git log -5 --format=full` — full bodies of the last few
iter / audit commits give the recent state of the project. iter / audit commits give the recent state of the project.
Augment with `git log -15 --oneline` for a chronological Augment with `git log -15 --oneline` for a chronological
@@ -58,7 +58,7 @@ rather than restating the semantics.
|-------|---------| |-------|---------|
| `mode` | `"standard"` or `"mini"` | | `mode` | `"standard"` or `"mini"` |
| `iter_id` | e.g. `"ct.2.3"` (standard) or `"bugfix-<short-symptom>"` (mini). Used for scratch dir, stats filename — NOT a branch name (there is no branch) | | `iter_id` | e.g. `"ct.2.3"` (standard) or `"bugfix-<short-symptom>"` (mini). Used for scratch dir, stats filename — NOT a branch name (there is no branch) |
| `plan_path` | (standard only) path under `paths.plan_dir` | | `plan_path` | (standard only) path under `docs/plans` |
| `task_range` | (standard, optional) e.g. `[3, 8]` — run only Tasks 3..8 inclusive | | `task_range` | (standard, optional) e.g. `[3, 8]` — run only Tasks 3..8 inclusive |
| `red_test_path` | (mini only) absolute path to the RED test from `debug` | | `red_test_path` | (mini only) absolute path to the RED test from `debug` |
| `cause_summary` | (mini only) 12 sentences from the debugger agent | | `cause_summary` | (mini only) 12 sentences from the debugger agent |
@@ -309,8 +309,9 @@ visibility in `git status` is the point.
### Phase 5 — Write stats file ### Phase 5 — Write stats file
Write a stats file at `/tmp/iter-<iter_id>/stats.json`, or Write a stats file at `/tmp/iter-<iter_id>/stats.json`, or
under a project-configured stats directory if the project under a project stats directory if the project declares one
declares one (typically a subdirectory of `paths.bench_dir`). (typically a subdirectory of the project's bench dir, if it
has one — its CLAUDE.md project facts).
At minimum: At minimum:
```json ```json
+16 -15
View File
@@ -30,14 +30,15 @@ disappears.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is fixed: `CLAUDE.md` plus
plus `standing_reading.by_role.implementer` in the project `git log -10 --format=full` (see docs/conventions.md). On top
profile. The defaults include `CLAUDE.md` for orchestrator of that, read the per-role standing reading the project lists
framing and the project's design ledger (if configured) for in its CLAUDE.md project facts for `implementer`. `CLAUDE.md`
the binding architectural decisions. gives the orchestrator framing, and the project's design
ledger (if it has one) the binding architectural decisions.
You do **not** open plan or spec files under You do **not** open plan or spec files under
`paths.plan_dir` / `paths.spec_dir` directly. The controller `docs/plans` / `docs/specs` directly. The controller
has already extracted what you need from them and hands it has already extracted what you need from them and hands it
to you via the carrier (see below). If something is missing to you via the carrier (see below). If something is missing
from the carrier, that is a `NEEDS_CONTEXT` situation — from the carrier, that is a `NEEDS_CONTEXT` situation —
@@ -82,8 +83,8 @@ to enforce the discipline anyway.
Exceptions where RED-first does not apply: Exceptions where RED-first does not apply:
- Pure refactors with no behaviour change — existing tests - Pure refactors with no behaviour change — existing tests
are the verification; if the project's `commands.test` are the verification; if the project's test command (its
is green pre and post, you're fine. CLAUDE.md project facts) is green pre and post, you're fine.
- Test-only tasks — you ARE writing the test, so no - Test-only tasks — you ARE writing the test, so no
separate RED step. separate RED step.
- Doc / comment / formatting changes. - Doc / comment / formatting changes.
@@ -94,8 +95,8 @@ is yes — write the test.
## Architecture rules ## Architecture rules
The binding architectural rules of the project are declared The binding architectural rules of the project are declared
in `CLAUDE.md` and (if the project has one) the design in `CLAUDE.md` and (if the project has one) its design
ledger at `paths.design_ledger`. The specific rules are ledger. The specific rules are
project-specific, but they typically cover: project-specific, but they typically cover:
- **Determinism contracts.** Canonical forms, sort orders, - **Determinism contracts.** Canonical forms, sort orders,
@@ -149,8 +150,8 @@ substitute.
- **REFACTOR** (optional, only if the diff has - **REFACTOR** (optional, only if the diff has
duplication or unclear names): clean up while keeping duplication or unclear names): clean up while keeping
the test green. Don't add behaviour. the test green. Don't add behaviour.
6. **Verify** with the project's `commands.build` and 6. **Verify** with the project's build and test commands
`commands.test`. Both MUST be green. The test you wrote (its CLAUDE.md project facts). Both MUST be green. The test you wrote
in RED MUST pass; no other test may regress. in RED MUST pass; no other test may regress.
7. **Property doc comment.** The new test's doc comment 7. **Property doc comment.** The new test's doc comment
names the property it protects, not just what it names the property it protects, not just what it
@@ -225,7 +226,7 @@ know to unblock you, and stop. Do not implement on a hunch.
| "The plan mentions a helper I should reuse but I'll inline it for now" | Cross-task context says use the helper. Use the helper. Inlining "for now" creates the duplication the plan tried to avoid. | | "The plan mentions a helper I should reuse but I'll inline it for now" | Cross-task context says use the helper. Use the helper. Inlining "for now" creates the duplication the plan tried to avoid. |
| "Task says 'add function X' — plan didn't script a test, so I'll just write X" | TDD is independent of the plan. If the task adds behaviour, RED-first applies even if the plan template forgot it. Add the test inline; report the plan gap. | | "Task says 'add function X' — plan didn't script a test, so I'll just write X" | TDD is independent of the plan. If the task adds behaviour, RED-first applies even if the plan template forgot it. Add the test inline; report the plan gap. |
| "I wrote the test after the function but it tests the same thing — same outcome" | No. Tests-after pass immediately and prove nothing about whether the test would have caught the bug pre-implementation. Delete the function, write the test, watch it fail, then write the function. Spirit-not-ritual is the exact rationalisation TDD is built to defeat. | | "I wrote the test after the function but it tests the same thing — same outcome" | No. Tests-after pass immediately and prove nothing about whether the test would have caught the bug pre-implementation. Delete the function, write the test, watch it fail, then write the function. Spirit-not-ritual is the exact rationalisation TDD is built to defeat. |
| "Refactor only — no test, no verification" | Wrong half. No new test, but `commands.test` MUST still pass. A "refactor" that breaks an existing test is a behaviour change you didn't notice. | | "Refactor only — no test, no verification" | Wrong half. No new test, but the project's test command MUST still pass. A "refactor" that breaks an existing test is a behaviour change you didn't notice. |
## Red Flags — STOP ## Red Flags — STOP
@@ -238,11 +239,11 @@ know to unblock you, and stop. Do not implement on a hunch.
- About to report `DONE` while a concern is unspoken - About to report `DONE` while a concern is unspoken
- About to substitute a "better" approach for the one in - About to substitute a "better" approach for the one in
the task block at `task_text_path` the task block at `task_text_path`
- About to open `paths.plan_dir` or `paths.spec_dir` files - About to open `docs/plans` or `docs/specs` files
directly when the file at `task_text_path` should already directly when the file at `task_text_path` should already
contain what you need contain what you need
- About to write production code while the corresponding - About to write production code while the corresponding
RED test does not yet exist (or has not yet been run + RED test does not yet exist (or has not yet been run +
observed to fail) observed to fail)
- About to mark a refactor `DONE` without re-running the - About to mark a refactor `DONE` without re-running the
project's `commands.test` project's test command
+9 -8
View File
@@ -36,17 +36,18 @@ solution rather than the right one.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is fixed: `CLAUDE.md` plus
plus `standing_reading.by_role.quality-reviewer` in the `git log -10 --format=full` (see docs/conventions.md). On top
project profile. The defaults include `CLAUDE.md` for of that, read the per-role standing reading the project lists
orchestrator framing and the project's stated quality bar in its CLAUDE.md project facts for `quality-reviewer`.
(the "Doing tasks" / discipline sections at the project `CLAUDE.md` gives the orchestrator framing and the project's
level). stated quality bar (the "Doing tasks" / discipline sections
at the project level).
Additionally: Additionally:
- The project's design ledger at `paths.design_ledger` (if - The project's design ledger, if it has one (its CLAUDE.md
configured) — invariants the diff must respect live in project facts) — invariants the diff must respect live in
the linked contracts. the linked contracts.
- `../SKILL.md` (the implement SKILL) — the two-stage - `../SKILL.md` (the implement SKILL) — the two-stage
review process you are the second half of. review process you are the second half of.
+9 -8
View File
@@ -1,6 +1,6 @@
--- ---
name: spec-reviewer name: spec-reviewer
description: Read-only spec-compliance reviewer. Compares a recent diff against the task text from a plan under paths.plan_dir handed by the controller. Reports missing requirements and unrequested extras. Does NOT review code quality (that is quality-reviewer's job) and does NOT propose fixes (the implementer fixes; the orchestrator coordinates). description: Read-only spec-compliance reviewer. Compares a recent diff against the task text from a plan under docs/plans handed by the controller. Reports missing requirements and unrequested extras. Does NOT review code quality (that is quality-reviewer's job) and does NOT propose fixes (the implementer fixes; the orchestrator coordinates).
tools: Read, Glob, Grep, Bash tools: Read, Glob, Grep, Bash
--- ---
@@ -40,20 +40,21 @@ extras, and you stop.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is fixed: `CLAUDE.md` plus
plus `standing_reading.by_role.spec-reviewer` in the project `git log -10 --format=full` (see docs/conventions.md). On top
profile. The defaults include `CLAUDE.md` for orchestrator of that, read the per-role standing reading the project lists
framing. in its CLAUDE.md project facts for `spec-reviewer`. `CLAUDE.md`
gives the orchestrator framing.
Additionally: Additionally:
- The project's design ledger at `paths.design_ledger` (if - The project's design ledger, if it has one (its CLAUDE.md
configured) — cross-reference any architectural-feeling project facts) — cross-reference any architectural-feeling
claim in the task text against the contract it links. claim in the task text against the contract it links.
- `../SKILL.md` (the implement SKILL) — the two-stage - `../SKILL.md` (the implement SKILL) — the two-stage
review process you are one half of. review process you are one half of.
You do **not** read plan files under `paths.plan_dir` You do **not** read plan files under `docs/plans`
directly. The controller hands you the task text — that's directly. The controller hands you the task text — that's
your spec for this review. your spec for this review.
+10 -8
View File
@@ -30,15 +30,16 @@ state the invariant in the doc comment, and you stop.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is fixed: `CLAUDE.md` plus
plus `standing_reading.by_role.tester` in the project `git log -10 --format=full` (see docs/conventions.md). On top
profile. The defaults include `CLAUDE.md` for the of that, read the per-role standing reading the project lists
orchestrator framing. in its CLAUDE.md project facts for `tester`. `CLAUDE.md` gives
the orchestrator framing.
Additionally: Additionally:
- The project's design ledger at `paths.design_ledger` (if - The project's design ledger, if it has one (its CLAUDE.md
configured) — the invariants the tests must protect live project facts) — the invariants the tests must protect live
in the linked contracts. in the linked contracts.
- `git log -3 --format=full` — full bodies of the most - `git log -3 --format=full` — full bodies of the most
recent iter commits; they tell you what shipped and is recent iter commits; they tell you what shipped and is
@@ -98,7 +99,8 @@ DETERMINISTIC: SAME INPUT, SAME OUTPUT, EVERY RUN.
- Add the corresponding test in the project's E2E test - Add the corresponding test in the project's E2E test
location. location.
- Doc comment names the property. - Doc comment names the property.
4. Run the project's `commands.test`. Must be green. 4. Run the project's test command (its CLAUDE.md project
facts). Must be green.
5. Report. Your fixtures and tests stay in the working tree 5. Report. Your fixtures and tests stay in the working tree
as unstaged edits; the orchestrator commits them at the as unstaged edits; the orchestrator commits them at the
end of the iter alongside the feature work they protect. end of the iter alongside the feature work they protect.
@@ -153,4 +155,4 @@ At most 200 words:
property property
- About to introduce a non-deterministic input (system - About to introduce a non-deterministic input (system
time, `rand`, filesystem listing order) time, `rand`, filesystem listing order)
- About to skip the project's `commands.test` run - About to skip the project's test command run
+2 -2
View File
@@ -52,5 +52,5 @@ done
echo echo
echo "Install complete." echo "Install complete."
echo "Next: drop a profile into each project that should use the plugin:" echo "Next: add a '## Skills plugin: project facts' section to each"
echo " cp $REPO_DIR/templates/project-profile.yml <project>/.claude/dev-cycle-profile.yml" echo "project's CLAUDE.md (template: $REPO_DIR/templates/CLAUDE.md.fragment)."
+2 -2
View File
@@ -88,8 +88,8 @@ artefact mirrored to Gitea ("would it be committed → English", per
`tea` is pre-authenticated via its own config (`~/.config/tea/`). `tea` is pre-authenticated via its own config (`~/.config/tea/`).
Never read or echo that file — it holds a token. `tea` auto-detects Never read or echo that file — it holds a token. `tea` auto-detects
the repository from the git remote; override with `--repo owner/name` the repository from the git remote; override with `--repo owner/name`
when running outside the repo (the slug lives in when running outside the repo (the project's issue tracker — its
`issue_tracker.repo` if a project profile sets it). CLAUDE.md project facts name the repo slug and the list/show commands).
| Operation | Command | | Operation | Command |
|---|---| |---|---|
+20 -18
View File
@@ -1,6 +1,6 @@
--- ---
name: planner name: planner
description: Use when a cycle spec exists under paths.spec_dir and a new iteration is starting. Produces a placeholder-free, bite-sized implementation plan under paths.plan_dir that the implement skill can execute task-by-task. Hard-gate before any implementation work. description: Use when a cycle spec exists under docs/specs and a new iteration is starting. Produces a placeholder-free, bite-sized implementation plan under docs/plans that the implement skill can execute task-by-task. Hard-gate before any implementation work.
--- ---
# planner — spec → executable plan # planner — spec → executable plan
@@ -15,9 +15,9 @@ file that will be created or modified, and decomposes work
into bites small enough that a subagent can execute one in into bites small enough that a subagent can execute one in
2-5 minutes without making judgement calls outside its remit. 2-5 minutes without making judgement calls outside its remit.
Plans live under the project's `paths.plan_dir` with a name Plans live under `docs/plans` with the fixed name shape
shape governed by the project's `naming.policy` (see profile `NNNN-slug.md` — a 4-digit counter per directory (see
schema). The header references the parent spec. The plan `docs/conventions.md`). The header references the parent spec. The plan
decomposes work into tasks; each task is the unit of review decomposes work into tasks; each task is the unit of review
(spec-compliance and quality gates inside `implement`), not (spec-compliance and quality gates inside `implement`), not
the unit of commit. Commits are an orchestrator-only decision the unit of commit. Commits are an orchestrator-only decision
@@ -28,7 +28,7 @@ diff.
Triggers: Triggers:
- A spec under `paths.spec_dir` for the active cycle is - A spec under `docs/specs` for the active cycle is
approved. approved.
- A new iteration within an active cycle is starting. - A new iteration within an active cycle is starting.
@@ -62,7 +62,7 @@ Non-negotiable.
### Step 1 — Read the parent spec ### Step 1 — Read the parent spec
Read the spec under `paths.spec_dir` in full. NOT from memory. Read the spec under `docs/specs` in full. NOT from memory.
Even if the spec is recent and you wrote it yourself, re-read Even if the spec is recent and you wrote it yourself, re-read
it before planning. it before planning.
@@ -120,7 +120,7 @@ action that takes 2-5 minutes:
- [ ] **Step 2: Run test to verify it fails** - [ ] **Step 2: Run test to verify it fails**
Run: `<the project's test command from commands.test, scoped to this test>` Run: `<the project's test command (its CLAUDE.md project facts), scoped to this test>`
Expected: FAIL with "<exact expected message>" Expected: FAIL with "<exact expected message>"
- [ ] **Step 3: Write minimal implementation** - [ ] **Step 3: Write minimal implementation**
@@ -144,7 +144,7 @@ Every plan starts with this header:
```markdown ```markdown
# <Iteration Title> — Implementation Plan # <Iteration Title> — Implementation Plan
> **Parent spec:** `<path under paths.spec_dir>` > **Parent spec:** `<path under docs/specs>`
> >
> **For agentic workers:** REQUIRED SUB-SKILL: use the > **For agentic workers:** REQUIRED SUB-SKILL: use the
> `implement` skill to run this plan. Steps use `- [ ]` > `implement` skill to run this plan. Steps use `- [ ]`
@@ -223,10 +223,11 @@ Before handing the plan off, run this checklist inline:
every Run step whose assertion lives in a filter string. every Run step whose assertion lives in a filter string.
9. **Parse-the-bytes-you-inline gate.** Every verbatim code body 9. **Parse-the-bytes-you-inline gate.** Every verbatim code body
the plan inlines into a task step must be run through the the plan inlines into a task step must be run through the
`spec_validation` gate defined in `docs/profile-schema.md` spec-validation parsers the project declares in its CLAUDE.md
(which owns the parser-invocation protocol, the noted project facts, following the parser-invocation protocol in
no-parser skip, the malformed-entry failure, and the no-op `docs/conventions.md` (which owns the no-parser skip, the
when the profile declares no `spec_validation`) before malformed-entry failure, and the no-op when the project
declares no spec-validation parsers) before
hand-off. The target is the surface-language snippets the plan hand-off. The target is the surface-language snippets the plan
lifts verbatim (example programs, fixtures); the project's lifts verbatim (example programs, fixtures); the project's
source-language test / implementation bodies are NOT the source-language test / implementation bodies are NOT the
@@ -242,7 +243,7 @@ Fix issues inline.
### Step 6 — Hand off ### Step 6 — Hand off
The plan sits in the working tree as an unstaged file under The plan sits in the working tree as an unstaged file under
`paths.plan_dir`. Hand off to `implement` with: path to the `docs/plans`. Hand off to `implement` with: path to the
plan file + optional task focus ("only Tasks 1-3 this run"). plan file + optional task focus ("only Tasks 1-3 this run").
The orchestrator commits the plan when handing it forward The orchestrator commits the plan when handing it forward
@@ -253,8 +254,8 @@ The planner skill does not perform the commit itself.
| Direction | Carrier | | Direction | Carrier |
|-----------|---------| |-----------|---------|
| `specify``planner` | path to the spec under `paths.spec_dir` + iteration scope ("this iteration covers spec section X+Y") | | `specify``planner` | path to the spec under `docs/specs` + iteration scope ("this iteration covers spec section X+Y") |
| `planner``implement` | path to the plan under `paths.plan_dir` + optional task-range focus | | `planner``implement` | path to the plan under `docs/plans` + optional task-range focus |
| `planner``specify` (bounce) | spec contains placeholders or contradictions: name the offending section, request revision | | `planner``specify` (bounce) | spec contains placeholders or contradictions: name the offending section, request revision |
## Common Rationalisations ## Common Rationalisations
@@ -267,7 +268,7 @@ The planner skill does not perform the commit itself.
| "Step 5 'implement the parser' is fine, I'll detail it at execution time" | Then it's not a step, it's a wish. Steps are bite-sized OR the plan isn't done. | | "Step 5 'implement the parser' is fine, I'll detail it at execution time" | Then it's not a step, it's a wish. Steps are bite-sized OR the plan isn't done. |
| "Task 7 is similar to Task 4, just say so" | The executor may read tasks out of order. Repeat the code. | | "Task 7 is similar to Task 4, just say so" | The executor may read tasks out of order. Repeat the code. |
| "The spec has a TBD too, I can pass it through" | Bounce back to `specify`. Plans inherit spec gaps; spec gaps are not plan placeholders. | | "The spec has a TBD too, I can pass it through" | Bounce back to `specify`. Plans inherit spec gaps; spec gaps are not plan placeholders. |
| "The example program came straight from the spec, it must be valid" | The spec's code blocks are hypotheses, not verified bytes — specify's parse gate can be skipped and a post-spec edit can break them. Re-parse every surface-language body you inline; this is the last line before the implementer hits it (issue #1 Fix 4). | | "The example program came straight from the spec, it must be valid" | The spec's code blocks are hypotheses, not verified bytes — specify's parse gate can be skipped and a post-spec edit can break them. Re-parse every surface-language body you inline against the spec-validation parsers the project declares in its CLAUDE.md project facts; this is the last line before the implementer hits it (issue #1 Fix 4). |
## Red Flags — STOP ## Red Flags — STOP
@@ -279,8 +280,9 @@ The planner skill does not perform the commit itself.
- Header missing parent spec reference - Header missing parent spec reference
- Self-review skipped because "the plan looks fine" - Self-review skipped because "the plan looks fine"
- A task step inlining a surface-language code body whose fence - A task step inlining a surface-language code body whose fence
label has a configured `spec_validation` parser, handed off label has a project-declared spec-validation parser (its
without a parse-trace in the planner session CLAUDE.md project facts), handed off without a parse-trace in
the planner session
## Cross-references ## Cross-references
+8 -8
View File
@@ -32,21 +32,21 @@ naming where work lands.
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is `CLAUDE.md` plus
plus `standing_reading.by_role.plan-recon` in the project `git log -10 --format=full`, then the per-role standing
profile. reading the project lists in its CLAUDE.md project facts.
In addition: In addition:
- If the project has a design ledger configured under - If the project has a design ledger (its CLAUDE.md project
`paths.design_ledger`, walk it to the contracts the carrier facts), walk it to the contracts the carrier
flags or that the spec touches; do not skim sections the flags or that the spec touches; do not skim sections the
spec does not touch. spec does not touch.
- `git log -5 --format=full` — full bodies of the most - `git log -5 --format=full` — full bodies of the most
recent iter commits; tells you what just shipped, so the recent iter commits; tells you what just shipped, so the
file-map does not double-count fresh work. file-map does not double-count fresh work.
- `../SKILL.md` (the planner SKILL) — the role the recon - `../SKILL.md` (the planner SKILL) — the role the recon
serves. Do NOT open files under `paths.plan_dir`; plan serves. Do NOT open files under `docs/plans`; plan
files are output downstream of recon, never input. files are output downstream of recon, never input.
## Carrier contract — what the controller hands you ## Carrier contract — what the controller hands you
@@ -58,7 +58,7 @@ it.
| Field | Content | | Field | Content |
|-------|---------| |-------|---------|
| `spec_path` | Path to the spec under `paths.spec_dir` (mandatory) | | `spec_path` | Path to the spec under `docs/specs` (mandatory) |
| `iteration_scope` | Which sections of the spec this dispatch covers (mandatory) | | `iteration_scope` | Which sections of the spec this dispatch covers (mandatory) |
| `focus_hint` | Optional: orchestrator may flag a specific subsystem or symbol to prioritise | | `focus_hint` | Optional: orchestrator may flag a specific subsystem or symbol to prioritise |
@@ -85,7 +85,7 @@ never to fix or write.
2. Read the spec in full. Note every reference to a path, 2. Read the spec in full. Note every reference to a path,
type, function, or invariant. type, function, or invariant.
3. Read the standing list in order, plus the design ledger's 3. Read the standing list in order, plus the design ledger's
relevant contracts (if configured). relevant contracts (if the project has one).
4. For each path or symbol the spec references, run 4. For each path or symbol the spec references, run
`git grep` or `Glob`+`Read` to anchor it to exact line `git grep` or `Glob`+`Read` to anchor it to exact line
numbers in the current tree. Record: numbers in the current tree. Record:
+4 -4
View File
@@ -126,8 +126,8 @@ report.
Resolve in this order: Resolve in this order:
1. `--out <path>` if the invoker passed one. 1. `--out <path>` if the invoker passed one.
2. The project profile's `paths.postmortem_dir` (if a 2. The project's post-mortem directory, if it has one (its CLAUDE.md
`.claude/dev-cycle-profile.yml` exists and defines it). project facts).
3. Default: `docs/postmortems/<session-id-short>-<yyyy-mm-dd>.md` 3. Default: `docs/postmortems/<session-id-short>-<yyyy-mm-dd>.md`
under the project root, creating the directory if needed. under the project root, creating the directory if needed.
@@ -199,8 +199,8 @@ If the session is flagged `active`, add one line at the top:
aggregator. All numbers originate here. aggregator. All numbers originate here.
- **Hand-off target:** the `issue` skill, when a finding is a - **Hand-off target:** the `issue` skill, when a finding is a
trackable defect worth filing. trackable defect worth filing.
- **Profile slot (optional):** `paths.postmortem_dir` for the - **Report destination (optional):** the project's post-mortem
report destination. directory, if its CLAUDE.md project facts name one.
- **Data-source note:** this skill reads only the current - **Data-source note:** this skill reads only the current
session's own transcript and subagent logs. It does not crawl session's own transcript and subagent logs. It does not crawl
other projects or other sessions (single-session by design). other projects or other sessions (single-session by design).
+26 -20
View File
@@ -1,6 +1,6 @@
--- ---
name: specify name: specify
description: Use when the design is already settled — a long in-context design discussion, an exhaustive tracker issue, or a ratified design handed over by brainstorm — and a spec must be produced from those sources with review but without an interview. The spec-production core: applies the feature-acceptance criterion, writes the spec under paths.spec_dir, runs the parse and grounding-check gates, takes user sign-off, hands off to planner. Bounces to brainstorm the moment the sources do not resolve a load-bearing design decision. Co-equal third entry path alongside brainstorm and tdd. description: Use when the design is already settled — a long in-context design discussion, an exhaustive tracker issue, or a ratified design handed over by brainstorm — and a spec must be produced from those sources with review but without an interview. The spec-production core: applies the feature-acceptance criterion, writes the spec under docs/specs, runs the parse and grounding-check gates, takes user sign-off, hands off to planner. Bounces to brainstorm the moment the sources do not resolve a load-bearing design decision. Co-equal third entry path alongside brainstorm and tdd.
--- ---
# specify — spec-production entry path # specify — spec-production entry path
@@ -33,9 +33,11 @@ RED from GREEN across two dispatches so the spec stays honest;
`specify` splits deciding from producing so the producing phase reads `specify` splits deciding from producing so the producing phase reads
the decision as a *source* rather than making it inline. the decision as a *source* rather than making it inline.
This skill is **not** opt-in. Unlike `tdd` (a profile-gated bypass),
`specify` is a core pipeline node: it is the gate before `planner` on `specify` is a core pipeline node: it is the gate before `planner` on
every design path that is not a bug fix or a test-specifiable feature. every design path that is not a bug fix or a test-specifiable feature.
Where `tdd` is one entry path among three (chosen when behaviour is
test-specifiable), `specify` sits on every prose-design path — it is
not bypassed for those.
## When to Use / Skipping ## When to Use / Skipping
@@ -52,8 +54,8 @@ Triggers:
load-bearing decision. Use `brainstorm` (its discovery is what load-bearing decision. Use `brainstorm` (its discovery is what
resolves the fork). `specify` itself bounces here the moment it resolves the fork). `specify` itself bounces here the moment it
detects this (see The Iron Law and Step 1.5). detects this (see The Iron Law and Step 1.5).
- A test-specifiable feature, on a profile that enables `tdd` — the - A test-specifiable feature — the RED executable-spec is the spec.
RED executable-spec is the spec. Use `tdd` directly. Use `tdd` directly.
- An observed bug — use `debug` directly (RED-first). - An observed bug — use `debug` directly (RED-first).
- A tidy iteration — use `audit` directly. - A tidy iteration — use `audit` directly.
- A trivial mechanical edit — per the project's CLAUDE.md carve-out. - A trivial mechanical edit — per the project's CLAUDE.md carve-out.
@@ -96,7 +98,7 @@ Before producing anything, establish what the sources actually say:
- **Chain entry** (from `brainstorm`): the ratified design narrative - **Chain entry** (from `brainstorm`): the ratified design narrative
is already in-context. Re-ground lightly — fresh `git log`, the is already in-context. Re-ground lightly — fresh `git log`, the
files the design touches — rather than re-deriving it. files the design touches — rather than re-deriving it.
- If the project has a design ledger under `paths.design_ledger`, - If the project has a design ledger (its CLAUDE.md project facts),
walk to the contracts the work touches. Note any `status: walk to the contracts the work touches. Note any `status:
aspirational` source: its code is a target, not verified fact — aspirational` source: its code is a target, not verified fact —
track it for the Step-4 parse gate. track it for the Step-4 parse gate.
@@ -199,16 +201,17 @@ honest* slice of the north-star program the infrastructure serves. "No
surface so no code to show" is the rationalisation to refuse. surface so no code to show" is the rationalisation to refuse.
**Code lifted from an aspirational source is a hypothesis, not **Code lifted from an aspirational source is a hypothesis, not
evidence.** If the concrete code here is lifted from a `design_models` evidence.** If the concrete code here is lifted from a design-models
file (or any `status: aspirational` source, per Step 1), it carries no file (or any `status: aspirational` source, per Step 1), it carries no
validation by default. Treat it as the spec's most suspect bytes: it validation by default. Treat it as the spec's most suspect bytes: it
must clear the Step-4 parse-every-block gate before PASS. must clear the Step-4 parse-every-block gate before PASS.
### Step 3 — Write the spec ### Step 3 — Write the spec
Path: under `paths.spec_dir`, with a name per the project's Path: under `docs/specs`, named per the fixed naming convention —
`naming.policy` (see profile schema). Determine the next slot per the `NNNN-slug.md`, 4-digit per-directory counter (see
policy. `docs/conventions.md`). Determine the next free number by scanning the
directory.
Structure: Structure:
@@ -256,10 +259,10 @@ Inline checklist (not a subagent dispatch):
worked user-facing example for a surface cycle)? A load-bearing worked user-facing example for a surface cycle)? A load-bearing
change described only in prose is a self-review failure to fix. change described only in prose is a self-review failure to fix.
6. **Parse-every-block gate.** Extract every fenced code block and run 6. **Parse-every-block gate.** Extract every fenced code block and run
it through the `spec_validation` gate defined in it through the spec-validation parsers the project declares in its
`docs/profile-schema.md` (which owns the parser-invocation CLAUDE.md project facts (a fence label with no parser is a documented
protocol, the no-parser skip, the malformed-entry failure, and the skip, never a silent pass; a malformed entry fails closed; the whole
no-op when the profile declares no `spec_validation`). A parse gate is a no-op when the project declares no parsers). A parse
failure is a self-review failure — fix the spec; do not pass failure is a self-review failure — fix the spec; do not pass
unparsed bytes downstream. Paste the parse-trace into the chat: a unparsed bytes downstream. Paste the parse-trace into the chat: a
visible trace attests the gate fired; its absence means it was visible trace attests the gate fired; its absence means it was
@@ -338,7 +341,8 @@ the commit itself.
**In `/boss` (autonomous):** `specify` is dispatched autonomously — **In `/boss` (autonomous):** `specify` is dispatched autonomously —
it is bounded (no interview). It runs the criterion, parse, and it is bounded (no interview). It runs the criterion, parse, and
grounding-check gates without a checkpoint. What happens at *this* grounding-check gates without a checkpoint. What happens at *this*
gate then depends on the profile slot `pipeline.boss.spec_auto_sign`: gate then depends on whether the project enables spec auto-sign (its
CLAUDE.md project facts):
- **Slot absent or `false` (default):** `specify` **pauses here** as a - **Slot absent or `false` (default):** `specify` **pauses here** as a
problem-state notify ("spec X ready, please sign off") and waits for problem-state notify ("spec X ready, please sign off") and waits for
@@ -434,7 +438,7 @@ is invoked from `specify`. NO direct jump to `implement`.
Hand off carries: Hand off carries:
- path to the spec under `paths.spec_dir` - path to the spec under `docs/specs`
- iteration scope ("the first iteration covers section X+Y of the - iteration scope ("the first iteration covers section X+Y of the
spec") spec")
@@ -488,8 +492,9 @@ discipline `tdd` applies when behaviour is not test-specifiable.
- "The sources are thorough, skip a gate" thoughts (any flavour) - "The sources are thorough, skip a gate" thoughts (any flavour)
- A load-bearing change described in prose with no before → after code - A load-bearing change described in prose with no before → after code
block; a surface cycle with no worked user-facing example block; a surface cycle with no worked user-facing example
- A spec carrying a code block whose fence label has a configured - A spec carrying a code block whose fence label has a spec-validation
`spec_validation` parser, committed without a parse-trace in the chat parser (the project's CLAUDE.md project facts), committed without a
parse-trace in the chat
- Lifting code verbatim from a `status: aspirational` source without - Lifting code verbatim from a `status: aspirational` source without
flagging it for the Step-4 parse gate flagging it for the Step-4 parse gate
- Editing the spec file after a Step 5 PASS without re-dispatching - Editing the spec file after a Step 5 PASS without re-dispatching
@@ -520,7 +525,8 @@ discipline `tdd` applies when behaviour is not test-specifiable.
PASS / BLOCK / INFRA_ERROR. PASS / BLOCK / INFRA_ERROR.
- **Agent dispatched (auto-sign only):** `agents/spec-skeptic.md` - **Agent dispatched (auto-sign only):** `agents/spec-skeptic.md`
dispatched in Step 6 five times in parallel (one per lens) ONLY under dispatched in Step 6 five times in parallel (one per lens) ONLY under
a `/boss` session with `pipeline.boss.spec_auto_sign` enabled. Each a `/boss` session with spec auto-sign enabled (the project's CLAUDE.md
project facts). Each
juror tries to refute the spec along its lens; a unanimous `SOUND` is juror tries to refute the spec along its lens; a unanimous `SOUND` is
what lets the orchestrator sign in the user's place. An editorial-lens what lets the orchestrator sign in the user's place. An editorial-lens
`BLOCK` (`criterion` / `ambiguity` / `plan-readiness`) is self- `BLOCK` (`criterion` / `ambiguity` / `plan-readiness`) is self-
@@ -529,7 +535,7 @@ discipline `tdd` applies when behaviour is not test-specifiable.
an exhausted budget falls back to the human sign-off pause. an exhausted budget falls back to the human sign-off pause.
- **Ad-hoc dispatch.** The orchestrator MAY also ad-hoc dispatch - **Ad-hoc dispatch.** The orchestrator MAY also ad-hoc dispatch
`../planner/agents/plan-recon.md` during Step 1 when the work enters `../planner/agents/plan-recon.md` during Step 1 when the work enters
code territory not recently read; opt-in, not part of the standard code territory not recently read; discretionary, not part of the
process. standard process.
- **Project feature-acceptance criterion:** declared in the project's - **Project feature-acceptance criterion:** declared in the project's
`CLAUDE.md`. Applied prospectively in Step 2. `CLAUDE.md`. Applied prospectively in Step 2.
+28 -27
View File
@@ -1,6 +1,6 @@
--- ---
name: grounding-check name: grounding-check
description: Read-only grounding-check reviewer for spec drafts. Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it; also validates the spec's own fenced code blocks against the project's configured parsers. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files. description: Read-only grounding-check reviewer for spec drafts. Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it; also validates the spec's own fenced code blocks against the spec-validation parsers the project declares in its CLAUDE.md project facts. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files.
tools: Read, Glob, Grep, Bash tools: Read, Glob, Grep, Bash
--- ---
@@ -28,16 +28,16 @@ right now, justify the assertions this spec rests on?"
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` The standing reading is `CLAUDE.md` plus
plus `standing_reading.by_role.grounding-check` in the `git log -10 --format=full`, then the per-role standing
project profile. The defaults include `CLAUDE.md` for reading the project lists in its CLAUDE.md project facts.
orchestrator framing and the feature-acceptance criterion `CLAUDE.md` carries the orchestrator framing and the
the project applies. feature-acceptance criterion the project applies.
In addition, every dispatch: In addition, every dispatch:
- The project's design ledger at `paths.design_ledger` (if - The project's design ledger, if it has one (its CLAUDE.md
configured) plus the contracts its index links — the project facts), plus the contracts its index links — the
canonical contract ledger the new spec must compose with. canonical contract ledger the new spec must compose with.
- `git log -5 --format=full` — full bodies of the - `git log -5 --format=full` — full bodies of the
most-recent iter / audit commits, for recent context. most-recent iter / audit commits, for recent context.
@@ -46,9 +46,9 @@ In addition, every dispatch:
- The spec file at the path the controller hands you (the - The spec file at the path the controller hands you (the
spec under review). spec under review).
You do NOT read files under `paths.plan_dir` (the plan does You do NOT read files under `docs/plans` (the plan does
not yet exist). You do NOT read other specs from not yet exist). You do NOT read other specs from
`paths.spec_dir` unless the spec under review explicitly `docs/specs` unless the spec under review explicitly
references one — and if it does, you read the referenced references one — and if it does, you read the referenced
section, not the whole spec. section, not the whole spec.
@@ -109,8 +109,8 @@ decreasing order of strength:
1. A direct unit / integration test that exercises the 1. A direct unit / integration test that exercises the
mechanism by name. mechanism by name.
2. An end-to-end fixture (under the examples / fixtures 2. An end-to-end fixture (under the project's examples /
directory configured in the project) that exercises the fixtures directory) that exercises the
mechanism indirectly but whose build / run output mechanism indirectly but whose build / run output
depends on it. depends on it.
3. A property-test or roundtrip test that pins the mechanism 3. A property-test or roundtrip test that pins the mechanism
@@ -138,7 +138,7 @@ mechanism strongly.
EXTRACT ASSUMPTIONS FROM THE SPEC, NOT FROM YOUR MEMORY. EXTRACT ASSUMPTIONS FROM THE SPEC, NOT FROM YOUR MEMORY.
RATIFICATION REQUIRES A NAMED, CURRENTLY-GREEN TEST. NOT CODE PRESENCE. NOT RECALL. RATIFICATION REQUIRES A NAMED, CURRENTLY-GREEN TEST. NOT CODE PRESENCE. NOT RECALL.
ONE UNRATIFIED LOAD-BEARING ASSUMPTION = BLOCK. NO PARTIAL CREDIT. ONE UNRATIFIED LOAD-BEARING ASSUMPTION = BLOCK. NO PARTIAL CREDIT.
ONE SPEC CODE BLOCK THAT FAILS ITS CONFIGURED PARSER = BLOCK. ONE SPEC CODE BLOCK THAT FAILS ITS PROJECT-DECLARED PARSER = BLOCK.
YOU DO NOT EDIT FILES. YOU DO NOT PROPOSE FIXES. YOU DO NOT EDIT FILES. YOU DO NOT PROPOSE FIXES.
YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER RUNS ARE OK.) YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER RUNS ARE OK.)
``` ```
@@ -156,9 +156,9 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER
3. For each assumption, design a search: 3. For each assumption, design a search:
- Identify keywords (function names, type names, schema - Identify keywords (function names, type names, schema
fields, pass names) the assumption mentions. fields, pass names) the assumption mentions.
- `grep` the test directories under `paths.code_roots` - `grep` the test directories under the project's code
and the project's examples / fixtures directory for roots (its CLAUDE.md project facts) and the project's
those keywords. examples / fixtures directory for those keywords.
- Enumerate tests by name using the project's test-list - Enumerate tests by name using the project's test-list
command (e.g. `cargo test --list -p <crate>` for Rust; command (e.g. `cargo test --list -p <crate>` for Rust;
analogous for the project's test framework). analogous for the project's test framework).
@@ -167,27 +167,28 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER
4. Classify each assumption as `ratified` (one or more 4. Classify each assumption as `ratified` (one or more
concrete tests found) or `unratified` (no test, or only concrete tests found) or `unratified` (no test, or only
weak candidates). weak candidates).
5. **Code-block parse pass.** If the project profile declares 5. **Code-block parse pass.** If the project declares
`spec_validation.parsers`, extract every fenced code block spec-validation parsers (its CLAUDE.md project facts),
extract every fenced code block
from the spec. For each block whose fence label has a from the spec. For each block whose fence label has a
`parsers` entry: write it to a temp file with the entry's declared parser: write it to a temp file with the parser's
`ext`, run the entry's `cmd` with `{file}` substituted, and `ext`, run the parser's `cmd` with `{file}` substituted, and
require exit 0. A non-zero exit marks the block unparseable. require exit 0. A non-zero exit marks the block unparseable.
A block whose fence label has no entry is skipped and noted A block whose fence label has no parser is skipped and noted
("no parser for fence label X"); never a silent pass. If the ("no parser for fence label X"); never a silent pass. If the
profile declares no `spec_validation`, this pass is a project declares no spec-validation parsers, this pass is a
documented no-op. This pass is complementary to the documented no-op. This pass is complementary to the
assumption search: it checks the spec's own bytes against the assumption search: it checks the spec's own bytes against the
live tool, not the codebase's behaviour — and it is live tool, not the codebase's behaviour — and it is
independent of the orchestrator's own Step-7 parse gate, the independent of the orchestrator's own Step-7 parse gate, the
fresh-context second line of the same defense. fresh-context second line of the same defense.
6. Compute aggregate status: 6. Compute aggregate status:
- All assumptions ratified AND every configured-label block - All assumptions ratified AND every block whose fence label
parsed clean → `PASS`. has a declared parser parsed clean → `PASS`.
- One or more unratified assumptions, OR one or more - One or more unratified assumptions, OR one or more
unparseable code blocks → `BLOCK`. unparseable code blocks → `BLOCK`.
- Any infra error (cannot read spec, type-check fails, - Any infra error (cannot read spec, type-check fails,
workspace does not build, a configured parser command is workspace does not build, a declared parser command is
missing from PATH) → `INFRA_ERROR`. missing from PATH) → `INFRA_ERROR`.
7. Emit the report in the format below. 7. Emit the report in the format below.
@@ -265,7 +266,7 @@ the assumption-extraction step yields an empty list, emit
| "I extracted too many assumptions, let me trim the report" | Don't trim. If a spec has too many assumptions to check, that is the finding — report it as BLOCK with reason "spec too broad". | | "I extracted too many assumptions, let me trim the report" | Don't trim. If a spec has too many assumptions to check, that is the finding — report it as BLOCK with reason "spec too broad". |
| "The orchestrator will override if I block, so I'll lean toward PASS" | The override is the orchestrator's job, not yours. Your job is to be the fresh-context check. Skewing toward PASS defeats the whole role. | | "The orchestrator will override if I block, so I'll lean toward PASS" | The override is the orchestrator's job, not yours. Your job is to be the fresh-context check. Skewing toward PASS defeats the whole role. |
| "I'll run the full test suite to see which tests are actually green" | You may NOT run the full test suite. Use the project's test-list command to enumerate, then read test bodies. Running tests would mutate workspace state and is out of scope for a read-only review. | | "I'll run the full test suite to see which tests are actually green" | You may NOT run the full test suite. Use the project's test-list command to enumerate, then read test bodies. Running tests would mutate workspace state and is out of scope for a read-only review. |
| "The code block is just illustrative, not a claim about behaviour" | A spec code block whose fence label has a configured parser is a hypothesis the downstream plan will lift verbatim. Illustrative or not, if it does not parse it is a defect. Run the parser and report the failure. | | "The code block is just illustrative, not a claim about behaviour" | A spec code block whose fence label has a project-declared parser is a hypothesis the downstream plan will lift verbatim. Illustrative or not, if it does not parse it is a defect. Run the parser and report the failure. |
## Red Flags — STOP ## Red Flags — STOP
@@ -278,7 +279,7 @@ the assumption-extraction step yields an empty list, emit
- About to mark an assumption ratified based on code - About to mark an assumption ratified based on code
presence rather than test presence presence rather than test presence
- About to PASS a spec carrying a code block whose fence label - About to PASS a spec carrying a code block whose fence label
has a configured parser without having run that parser has a project-declared parser without having run that parser
- About to skip an assumption because "it would always be - About to skip an assumption because "it would always be
true" true"
- Report exceeding ~500 tokens - Report exceeding ~500 tokens
+21 -16
View File
@@ -1,6 +1,6 @@
--- ---
name: spec-skeptic name: spec-skeptic
description: Read-only adversarial spec reviewer for the boss auto-sign panel. Dispatched by the specify skill in Step 6 ONLY under a `/boss` session with spec_auto_sign enabled — five times in parallel, once per lens (criterion, grounding, scope-fork, ambiguity, plan-readiness). Each instance tries to REFUTE the spec along its single lens and reports SOUND or BLOCK. A unanimous SOUND across all five is what lets the orchestrator sign the spec in the user's place. Does NOT propose fixes, does NOT edit files. description: Read-only adversarial spec reviewer for the boss auto-sign panel. Dispatched by the specify skill in Step 6 ONLY under a `/boss` session with spec auto-sign enabled (the project's CLAUDE.md project facts) — five times in parallel, once per lens (criterion, grounding, scope-fork, ambiguity, plan-readiness). Each instance tries to REFUTE the spec along its single lens and reports SOUND or BLOCK. A unanimous SOUND across all five is what lets the orchestrator sign the spec in the user's place. Does NOT propose fixes, does NOT edit files.
tools: Read, Glob, Grep, Bash tools: Read, Glob, Grep, Bash
--- ---
@@ -12,7 +12,8 @@ tools: Read, Glob, Grep, Bash
A spec normally carries the user's signature: the human reads it A spec normally carries the user's signature: the human reads it
and approves before any plan is built. Under a `/boss` session with and approves before any plan is built. Under a `/boss` session with
`spec_auto_sign` enabled, the orchestrator may sign in the user's spec auto-sign enabled (the project's CLAUDE.md project facts), the
orchestrator may sign in the user's
place — but only if it is genuinely safe, and **model place — but only if it is genuinely safe, and **model
self-confidence is not a safety signal**. The orchestrator that self-confidence is not a safety signal**. The orchestrator that
wrote the spec is the worst-placed party to judge whether it is good; wrote the spec is the worst-placed party to judge whether it is good;
@@ -52,28 +53,31 @@ question — your task is to answer "yes, I can refute" (`BLOCK`) or
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` plus The standing reading is `CLAUDE.md` plus
`standing_reading.by_role.spec-skeptic` in the project profile (if the `git log -10 --format=full`, then the per-role standing reading the
profile names none for this role, the `always` list is your floor). project lists in its CLAUDE.md project facts (if the project names none
The defaults include `CLAUDE.md` for orchestrator framing and the for this role, the standing `CLAUDE.md` + git-log floor is yours).
`CLAUDE.md` carries the orchestrator framing and the
feature-acceptance criterion the project applies — the `criterion` feature-acceptance criterion the project applies — the `criterion`
lens leans on it directly. lens leans on it directly.
In addition, every dispatch: In addition, every dispatch:
- The project's design ledger at `paths.design_ledger` (if configured) - The project's design ledger, if it has one (its CLAUDE.md project
plus the contracts its index links — the canonical ledger the spec facts), plus the contracts its index links — the canonical ledger
must compose with. the spec must compose with.
- `git log -5 --format=full` — recent context. - `git log -5 --format=full` — recent context.
- The plugin's `../../README.md` — skill-system architecture and the - The plugin's `../../README.md` — skill-system architecture and the
standard agent structure. standard agent structure.
- The spec file at `spec_path` (the spec under review). - The spec file at `spec_path` (the spec under review).
- For the `grounding` lens additionally: the test directories under - For the `grounding` lens additionally: the test directories under
`paths.code_roots` and the project's examples / fixtures directory — the project's code roots (its CLAUDE.md project facts) and the
project's examples / fixtures directory —
you grep these to confirm or refute ratification. you grep these to confirm or refute ratification.
- For the `scope-fork` lens additionally: the sources the spec was - For the `scope-fork` lens additionally: the sources the spec was
built from. The seeding issue is reachable via the profile's built from. The seeding issue is reachable via the project's issue
`issue_tracker.show_cmd` (issue index appended last) — invoke it so show command (its CLAUDE.md project facts) — it MUST render the issue
WITH its comment thread (issue index appended last) — invoke it so
you read the issue **with its comment thread**, not the body alone. you read the issue **with its comment thread**, not the body alone.
You judge "resolved vs picked" against what the sources actually say, You judge "resolved vs picked" against what the sources actually say,
not against what reads plausibly. A fork the issue *body* still lists not against what reads plausibly. A fork the issue *body* still lists
@@ -86,10 +90,10 @@ In addition, every dispatch:
`decision: X` with no provenance is an orchestrator self-assertion `decision: X` with no provenance is an orchestrator self-assertion
dressed as settled, not a source: it does **not** resolve the fork, and dressed as settled, not a source: it does **not** resolve the fork, and
a load-bearing decision whose only support is such a comment is a a load-bearing decision whose only support is such a comment is a
refutation. If `show_cmd` is unset, you have only the body — a fork the refutation. If the project declares no issue show command, you have
body lists open is unresolved to you. only the body — a fork the body lists open is unresolved to you.
You do NOT read files under `paths.plan_dir` (the plan does not yet You do NOT read files under `docs/plans` (the plan does not yet
exist). You do NOT read other specs unless the spec under review exist). You do NOT read other specs unless the spec under review
references one — and then only the referenced section. references one — and then only the referenced section.
@@ -129,7 +133,8 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, PER-BLOCK PARSER RUN
`#[ignore]`/`xfail`/disabled does not pin; code presence does not `#[ignore]`/`xfail`/disabled does not pin; code presence does not
pin; your own recall does not pin). For `scope-fork`, this means pin; your own recall does not pin). For `scope-fork`, this means
listing the load-bearing decisions and checking each against the listing the load-bearing decisions and checking each against the
sources read via `show_cmd` (issue **with comments**); a fork the sources read via the project's issue show command (issue **with
comments**); a fork the
issue body lists open is resolved only by a reconciliation comment issue body lists open is resolved only by a reconciliation comment
that carries provenance (see the standing reading list) — a that carries provenance (see the standing reading list) — a
provenance-less one does not count. For the others, read for the provenance-less one does not count. For the others, read for the
+7 -6
View File
@@ -71,10 +71,10 @@ prevent, and it is no less a failure for being dressed as a test.
- a trivial mechanical edit — per the project's CLAUDE.md - a trivial mechanical edit — per the project's CLAUDE.md
"trivial mechanical edits" carve-out. "trivial mechanical edits" carve-out.
This skill is an opt-in entry path. A project enables it by This skill is a standard entry path, always available — one of the
listing a `tdd` phase in its profile `pipeline:` block (see three design entries alongside `brainstorm → specify → planner` and
`docs/profile-schema.md`); a profile that omits it keeps `specify → planner`. Which one a given iteration uses is a fit
`brainstorm → specify → planner` as the only design entry path. decision per item, not a project setting.
## The Iron Law ## The Iron Law
@@ -219,5 +219,6 @@ iteration and gets queued for a separate one.
- **Sibling RED-first skill:** `../debug/SKILL.md` — same two-stage - **Sibling RED-first skill:** `../debug/SKILL.md` — same two-stage
RED→GREEN shape, but triggered by an observed bug rather than a RED→GREEN shape, but triggered by an observed bug rather than a
new-behaviour description. new-behaviour description.
- **Profile slot:** the opt-in `tdd` phase under `pipeline:` in - **Pipeline:** `../docs/pipeline.md``tdd` is a standard,
`docs/profile-schema.md`. always-available entry path; the graph and skip rules are fixed
(not per-project).
+16 -14
View File
@@ -45,20 +45,21 @@ You exist to prevent two failure modes specifically:
## Standing reading list ## Standing reading list
Read the files configured under `standing_reading.always` plus Always read `CLAUDE.md` (for role boundaries) and
`standing_reading.by_role.tdd-author` in the project profile. The `git log -10 --format=full` the most recent iter commits, as
defaults include `CLAUDE.md` for role boundaries and the recent the new behaviour may build on what just landed — plus the
`git log` for the most recent iter commits — the new behaviour may per-role standing reading the project lists in its CLAUDE.md
build on what just landed. project facts for the tdd-author role.
If the project has a design ledger configured under If the project has a design ledger (its CLAUDE.md project
`paths.design_ledger`, walk it for the invariants the new facts), walk it for the invariants the new behaviour must not
behaviour must not cross. A headline test that contradicts a cross. A headline test that contradicts a ledger invariant is
ledger invariant is itself a design fork — bounce. itself a design fork — bounce.
If the `source` is an issue ref, read the issue body in full If the `source` is an issue ref, read the issue body in full
(via the project's tracker, per `commands` in the profile) before (via the project's issue tracker — its CLAUDE.md project facts;
authoring; the issue body is the description. always Gitea) before authoring; the issue body is the
description.
The process below is the single source of truth — the dispatching The process below is the single source of truth — the dispatching
skill file does not duplicate it. skill file does not duplicate it.
@@ -106,8 +107,8 @@ Each phase completes before the next starts.
values, not "handles the case correctly". values, not "handles the case correctly".
3. **Fork check.** Ask: can this one claim be written without 3. **Fork check.** Ask: can this one claim be written without
choosing between two or three plausible behaviours that each choosing between two or three plausible behaviours that each
have real trade-offs? Walk the design ledger (if configured) have real trade-offs? Walk the design ledger (if the project
for an invariant that would settle the choice. If the choice has one) for an invariant that would settle the choice. If the choice
is genuinely open — the ledger doesn't settle it and the is genuinely open — the ledger doesn't settle it and the
description doesn't pin it — this is a design fork. Return description doesn't pin it — this is a design fork. Return
`BLOCKED` with the fork stated as the design question. Do not `BLOCKED` with the fork stated as the design question. Do not
@@ -240,7 +241,8 @@ At most 250 words, structured:
`brainstorm`). `brainstorm`).
- An edit to the headline test's assertion to make it pass — the - An edit to the headline test's assertion to make it pass — the
assertion is the contract. assertion is the contract.
- Design-ledger edits (the file at `paths.design_ledger`). - Design-ledger edits (the project's design ledger, if it has
one — its CLAUDE.md project facts).
- Verdicts like "this whole approach is wrong". Phase 1's fork - Verdicts like "this whole approach is wrong". Phase 1's fork
check and decompose mode's two-round limit surface the design check and decompose mode's two-round limit surface the design
question; the orchestrator decides the verdict. question; the orchestrator decides the verdict.
+74
View File
@@ -3,6 +3,13 @@
# Copy these sections into your project's CLAUDE.md to import the # Copy these sections into your project's CLAUDE.md to import the
# baseline rules the skills plugin assumes. Edit freely afterwards — # baseline rules the skills plugin assumes. Edit freely afterwards —
# this is a starting point, not a binding template. # this is a starting point, not a binding template.
#
# The plugin reads the project's CLAUDE.md as standing reading on every
# dispatch. There is no separate profile file: the `## Skills plugin:
# project facts` section at the bottom is where the few per-project facts
# the skills need (code roots, build/test command, tracker slug, …) live.
# Everything else is a fixed convention documented in
# ~/dev/skills/docs/conventions.md and docs/pipeline.md.
## Roles ## Roles
@@ -86,3 +93,70 @@ Example shape:
| Pair | Failure mode | | Pair | Failure mode |
|------|--------------| |------|--------------|
| `<file A>:<func A>` ↔ `<file B>:<func B>` | <what breaks when the pair is not updated together> | | `<file A>:<func A>` ↔ `<file B>:<func B>` | <what breaks when the pair is not updated together> |
## Skills plugin: project facts
The few facts the skills plugin needs that genuinely vary per project.
Everything else is a fixed convention (see
`~/dev/skills/docs/conventions.md`). Keep this concise; omit any row
that does not apply.
- **Code roots** — directories the architect / quality reviewer walk.
Example: `src` (or `crates, runtime`, or `server, common,
clients/desktop`). *Required.*
- **Build** — example: `cargo build` (or
`cargo build --manifest-path server/Cargo.toml`). *Required.*
- **Test** — example: `cargo test` (or `cargo test --workspace`).
*Required.*
- **Lint** — optional. Example: `cargo clippy`.
- **Doc build** — optional, used by `docwriter`; should print warnings
to stderr. Example: `cargo doc --no-deps 2>&1`.
- **Regression scripts** — optional list, run by `audit`; non-zero
exit = regress. Example: `scripts/check.sh`.
- **Architect sweeps** — optional list, run by the `architect` agent in
addition to its universal checks; non-zero exit = drift suspicion.
- **Design ledger** — optional path to the canonical spec index.
Example: `design/INDEX.md`.
- **Glossary** — optional path; if set, it is standing reading for every
role. Example: `docs/glossary.md`.
- **Design contracts / models** — optional directories of
prose-authoritative contracts / onboarding whitepapers. Example:
`design/contracts`, `design/models`. (Aspirational-source frontmatter
marker recommended — see `docs/conventions.md`.)
- **Bench dir** — optional path. Example: `bench`.
- **Public interface** — optional list: the *only* surface the
`fieldtester` may read (everything else, especially code roots and
bench, is forbidden to it). Example: `README.md, docs, examples`.
- **Fieldtest examples** — optional path where the `fieldtester` writes
fixtures. Example: `examples/fieldtest`.
- **Spec-validation parsers** — optional. A fence-label → parser table
the `specify` parse-gate and `grounding-check` use to validate spec
code blocks. A block whose label has no entry is a documented skip,
never a silent pass. `cmd` MUST contain the `{file}` placeholder.
Example:
| Fence label | Temp ext | Command |
|-------------|----------|---------|
| `ail` | `.ail` | `ail check {file}` |
| `ail-json` | `.ail.json`| `ail check {file}` |
- **By-role standing reading** — optional. Extra files/commands a
specific agent role reads on every dispatch, beyond the universal
`CLAUDE.md` + `git log -10`. Role names match agent slugs (`architect`,
`bencher`, `debugger`, `fieldtester`, `grounding-check`, …). Example:
architect also reads `design/contracts`; debugger also runs
`git log -5 --format=full`.
- **Issue tracker** — Gitea repo slug plus the commands to read it.
Example:
- repo: `Brummel/<project>`
- list open issues: `tea issues ls --repo Brummel/<project> --state open`
- show one issue with comments: `tea issues --comments` (the index is
appended last → `tea issues --comments 55`). The show command MUST
include comments — otherwise a `specify` reconciliation comment is
invisible to the `scope-fork` juror and auto-sign falls back to the
human sign-off.
- **Spec auto-sign** — optional; default off (human signature required).
Set to **enabled** to let a `/boss` run sign a spec in the user's place
through `specify`'s auto-sign gate (every objective gate green AND a
unanimous five-lens `spec-skeptic` panel; the orchestrator's own
confidence never signs). See `boss/SKILL.md` § "Spec auto-sign".
-85
View File
@@ -1,85 +0,0 @@
# Project profile for the skills plugin.
#
# Drop a copy of this file at <project-root>/.claude/dev-cycle-profile.yml
# and edit. See ~/dev/skills/docs/profile-schema.md for the full schema
# and per-key documentation.
paths:
spec_dir: docs/specs
plan_dir: docs/plans
# glossary: docs/glossary.md # optional — if set, read as
# standing reading by every role
# design_ledger: docs/design/INDEX.md # optional
# design_contracts: design/contracts # optional
# design_models: design/models # optional
code_roots: [src]
# bench_dir: bench # optional
# public_interface: [README.md, docs] # what fieldtester may read; everything else is forbidden
# fieldtest_examples: examples/fieldtest # where fieldtester writes fixtures
naming:
counter_dirs: [docs/specs, docs/plans, design/contracts, design/models]
policy: stable_per_directory_4digit # stable_per_directory_4digit | date_prefix | flat
slug_separator: "-"
commands:
build: "" # REQUIRED — e.g. "cargo build" or "npm run build"
test: "" # REQUIRED — e.g. "cargo test" or "npm test"
# lint: "" # optional
# doc_build: "" # e.g. "cargo doc --no-deps 2>&1" — used by docwriter
regression: [] # list of shell commands run by audit; non-zero exit = regress
architect_sweeps: [] # optional project-specific architect sweeps; non-zero exit = drift suspicion
# spec_validation: # optional — fence label -> validator for spec code blocks
# parsers: # key = fence info-string; labels with no entry are skipped + documented
# ail:
# ext: ".ail" # extension for the temp file the harness writes the block into
# cmd: "ail parse {file}" # {file} = temp-file path; exit 0 = clean parse, non-zero = BLOCK
# ail-json:
# ext: ".ail.json"
# cmd: "ail check {file}"
vocabulary:
cycle: cycle # one round in the pipeline graph (NOT the top-level container)
subcycle: iteration # a sub-unit of a cycle
milestone: milestone # tracker container spanning many cycles; closes only when complete AND functional
ledger_entry: contract # what one design-ledger entry is called
standing_reading:
always:
- CLAUDE.md
- "git log -10 --format=full"
by_role:
# architect: [design/contracts]
# debugger: ["git log -5 --format=full"]
git:
main_sacrosanct: true
only_orchestrator_commits: true
protected_branches: [main]
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"
# show_cmd: "" # renders one issue WITH comments; index appended last.
# e.g. "tea issues --comments" -> "tea issues --comments 55"
notifications:
# command: "" # e.g. "~/.claude/notify.sh"; boss falls back to chat if empty
pipeline:
brainstorm: {} # optional discovery front-end; no hard gate of its own
specify: { gates: [planner] } # core node: spec-production gate before planner
planner: { gates: [implement] }
implement: {}
audit: { mandatory_at: cycle_close }
debug: { trigger: bug, red_first: true }
# tdd: { trigger: test_specifiable_feature, red_first: true, alt_to: brainstorm } # opt-in: executable-spec-first entry, alternative to brainstorm
# boss: { user_invoked: true } # autonomous orchestrator mode, /boss
# spec_auto_sign: false # opt-in: let /boss sign a spec in the user's place when all
# # objective gates are green AND a unanimous spec-skeptic panel
# # passes; default off (human signature mandatory). See profile-schema.md.
# fieldtest: { boss_only: true, when: surface_touch } # per-cycle usability test
# milestone_fieldtest: { boss_only: true, when: surface_touch, gates_close: milestone } # closing gate: end-to-end proof of the milestone's promise
# docwriter: { boss_only: true, when: api_stable_across_n_cycles }