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:
+20
-22
@@ -26,32 +26,30 @@ To uninstall:
|
||||
|
||||
## 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
|
||||
cp ~/dev/skills/templates/project-profile.yml \
|
||||
<project-root>/.claude/dev-cycle-profile.yml
|
||||
$EDITOR <project-root>/.claude/dev-cycle-profile.yml
|
||||
$EDITOR <project-root>/CLAUDE.md # paste from templates/CLAUDE.md.fragment
|
||||
```
|
||||
|
||||
Edit the profile to match the project's paths, commands, and
|
||||
vocabulary. The skill bodies read the profile at the start of
|
||||
each invocation; there is no template-render step.
|
||||
|
||||
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.
|
||||
Everything the plugin does *not* read from project facts is a fixed
|
||||
convention (spec dir `docs/specs`, 4-digit naming, the pipeline graph,
|
||||
…) documented once in `docs/conventions.md` and `docs/pipeline.md` —
|
||||
not configurable per project.
|
||||
|
||||
## Update
|
||||
|
||||
|
||||
@@ -8,9 +8,10 @@ same discipline across any project.
|
||||
The plugin is **mechanics**: pipeline shape, hard-gates, TDD,
|
||||
RED-first bug fixing, agent-template, working-tree-as-quarantine,
|
||||
status protocol. It does **not** know your project's paths,
|
||||
build commands, vocabulary, or domain-specific contracts. Those
|
||||
live in a small per-project profile file
|
||||
(`.claude/dev-cycle-profile.yml`) plus the project's `CLAUDE.md`.
|
||||
build commands, or domain-specific contracts. Those few facts live
|
||||
in the project's own `CLAUDE.md` under a `## Skills plugin: project
|
||||
facts` heading; everything else is a fixed convention (see
|
||||
`docs/conventions.md`). There is no separate profile file.
|
||||
|
||||
## What's in the box
|
||||
|
||||
@@ -19,12 +20,12 @@ The pipeline skills, each with the agents it primarily dispatches:
|
||||
| Skill | Trigger | Output | Mandatory? |
|
||||
|-------|---------|--------|------------|
|
||||
| `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 |
|
||||
| `planner` | New iteration within an open cycle | plan under the configured plan dir | Hard-gate before implement |
|
||||
| `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 `docs/plans` | Hard-gate before implement |
|
||||
| `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 |
|
||||
| `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 |
|
||||
| `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 |
|
||||
@@ -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
|
||||
centre of every answer. It dispatches no agents.
|
||||
|
||||
Vocabulary is configurable. A **cycle** is one round in the
|
||||
pipeline graph; your project may call it a *release*, an *epic*,
|
||||
or whatever fits, and its sub-unit (the default *iteration*) a
|
||||
*sprint* or a *story*. A **milestone** is a distinct, higher
|
||||
axis — a tracker container (Gitea/GitHub milestone, Linear
|
||||
project) that spans potentially many cycles and closes only when
|
||||
The vocabulary is fixed. A **cycle** is one round in the
|
||||
pipeline graph, and its sub-unit is an **iteration**. A
|
||||
**milestone** is a distinct, higher axis — a Gitea milestone
|
||||
that spans potentially many cycles and closes only when
|
||||
the work it promised is complete *and* functional (see
|
||||
`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
|
||||
|
||||
@@ -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)
|
||||
- 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
|
||||
- Commands: build, test, lint, regression scripts
|
||||
- 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
|
||||
The handful of facts that genuinely vary per project live in the
|
||||
project's own `CLAUDE.md` under `## Skills plugin: project facts`:
|
||||
|
||||
See `docs/profile-schema.md` for the full schema and
|
||||
`templates/project-profile.yml` for a copy-and-fill starting point.
|
||||
- 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 (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
|
||||
|
||||
Profile slots are versioned with the plugin, not with your project.
|
||||
A new optional slot lands in `docs/profile-schema.md` and as a
|
||||
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.
|
||||
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 file and no parser — the skills read these facts from the
|
||||
project's `CLAUDE.md`, which is standing reading on every dispatch.
|
||||
|
||||
### Spec auto-sign (opt-in)
|
||||
|
||||
By default a `specify` dispatch in a `/boss` session pauses at its
|
||||
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
|
||||
unattended across spec boundaries can opt in with
|
||||
`pipeline.boss.spec_auto_sign: true`.
|
||||
unattended across spec boundaries can opt in by enabling spec
|
||||
auto-sign in its CLAUDE.md project facts.
|
||||
|
||||
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:
|
||||
@@ -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
|
||||
lists it open, `specify` records the resolution as a provenance-bearing
|
||||
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
|
||||
clean sign the orchestrator commits the spec
|
||||
(`(boss-signed)` in the subject), sends a mandatory informational notify
|
||||
@@ -172,9 +145,9 @@ a history rewind. See `specify/SKILL.md` Step 6,
|
||||
|
||||
## Install
|
||||
|
||||
See `INSTALL.md`. In short: clone, run `install.sh`, then drop
|
||||
a `dev-cycle-profile.yml` into each project that should use the
|
||||
plugin.
|
||||
See `INSTALL.md`. In short: clone, run `install.sh`, then add a
|
||||
`## Skills plugin: project facts` section to each project's
|
||||
`CLAUDE.md` (template in `templates/CLAUDE.md.fragment`).
|
||||
|
||||
## Status
|
||||
|
||||
|
||||
+8
-8
@@ -18,8 +18,8 @@ next cycle starts.
|
||||
## When to Use / Skipping
|
||||
|
||||
**Mandatory** at every cycle close. Skipping requires an
|
||||
explicit backlog issue (issue tracker configured under
|
||||
`git.issue_tracker`) naming:
|
||||
explicit backlog issue (the project's issue tracker — its
|
||||
CLAUDE.md project facts) naming:
|
||||
|
||||
- the blocking sibling cycle (if any),
|
||||
- the reason for deferral,
|
||||
@@ -47,8 +47,8 @@ Dispatch `architect` with the cycle scope (commit range from
|
||||
the previous cycle-close to `HEAD`):
|
||||
|
||||
```
|
||||
For cycle <X>: read the project's design ledger (configured
|
||||
under paths.design_ledger), walk its contracts;
|
||||
For cycle <X>: read the project's design ledger, if it has one
|
||||
(its CLAUDE.md project facts), walk its contracts;
|
||||
`git log <prev-close>..HEAD --format=full` for the cycle's
|
||||
iter and audit commit bodies; `git diff <prev-close>..HEAD`
|
||||
for the diff; report drift.
|
||||
@@ -59,10 +59,10 @@ Architect produces a prioritised drift list (see
|
||||
|
||||
### Step 2 — Regression check
|
||||
|
||||
Run the scripts configured under `commands.regression` in the
|
||||
project profile, in order. If the list is empty, the project
|
||||
has no regression gate and this step is a no-op (architect
|
||||
remains the gate).
|
||||
Run the project's regression command(s) (its CLAUDE.md project
|
||||
facts), in order. If there are none, the project has no
|
||||
regression gate and this step is a no-op (architect remains the
|
||||
gate).
|
||||
|
||||
The exit code of each script is the gate:
|
||||
|
||||
|
||||
+17
-16
@@ -28,13 +28,13 @@ the problem*.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.architect` in the project
|
||||
profile. The defaults include `CLAUDE.md` for the orchestrator
|
||||
framing.
|
||||
Always read `CLAUDE.md` (for the orchestrator framing) and
|
||||
`git log -10 --format=full`, plus the per-role standing reading
|
||||
the project lists in its CLAUDE.md project facts for the
|
||||
architect role.
|
||||
|
||||
Additionally, if the project has a design ledger configured
|
||||
under `paths.design_ledger`:
|
||||
Additionally, if the project has a design ledger (its CLAUDE.md
|
||||
project facts):
|
||||
|
||||
1. Walk the ledger end-to-end. Drift is measured against each
|
||||
contract it points to.
|
||||
@@ -42,7 +42,7 @@ under `paths.design_ledger`:
|
||||
commit bodies for the cycle you're reviewing. The most
|
||||
recent iter / audit commit bodies are the current claimed
|
||||
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
|
||||
signed up for. Drift is also measured against the spec.
|
||||
|
||||
@@ -51,7 +51,7 @@ under `paths.design_ledger`:
|
||||
| Field | Content |
|
||||
|-------|---------|
|
||||
| `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 |
|
||||
|
||||
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
|
||||
known pairings; walk each one against the cycle diff and
|
||||
flag any unpaired arm as drift.
|
||||
- **Project-specific architect sweeps.** If `commands.architect_sweeps`
|
||||
is configured in the project profile, run each script in
|
||||
the list. Exit 0 = clean for that sweep. Non-zero = at
|
||||
- **Project-specific architect sweeps.** If the project
|
||||
declares an architect-sweep command (its CLAUDE.md project
|
||||
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
|
||||
verify. The sweeps are the project's calibrated drift
|
||||
detectors; their semantics are defined in the project's
|
||||
@@ -107,16 +108,16 @@ command to confirm a claim, never to fix one).
|
||||
|
||||
## The Process
|
||||
|
||||
1. Read the standing list, in order: profile-configured
|
||||
standing reading → design ledger contracts →
|
||||
1. Read the standing list, in order: the standing reading
|
||||
above → design ledger contracts →
|
||||
`git log <prev-cycle-close>..HEAD --format=full` for the
|
||||
iter / audit commit bodies in scope → spec (if any) →
|
||||
recent diff.
|
||||
2. `git log --oneline -30` and
|
||||
`git diff <prev-cycle-close>..HEAD` for the factual diff.
|
||||
3. Run each script in `commands.architect_sweeps` (if
|
||||
configured). Treat each non-zero exit as a drift-suspicion
|
||||
to verify.
|
||||
3. Run each script in the project's architect-sweep command
|
||||
(its CLAUDE.md project facts), if it has one. Treat each
|
||||
non-zero exit as a drift-suspicion to verify.
|
||||
4. Read every changed file. Read the unchanged-but-load-
|
||||
bearing neighbours.
|
||||
5. Walk the project's lockstep-invariant pairings (from
|
||||
|
||||
@@ -34,8 +34,9 @@ over it with a chart.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.bencher` in the project profile.
|
||||
Always read `CLAUDE.md` and `git log -10 --format=full`, plus
|
||||
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
|
||||
script itself and any prior result baselines it references
|
||||
|
||||
+32
-35
@@ -72,10 +72,10 @@ skill does not restate them.
|
||||
### Step 1 — Read the queue
|
||||
|
||||
The project's issue tracker is the forward queue. Read open
|
||||
issues via the command configured under
|
||||
`git.issue_tracker.list_cmd` in the project profile. If that
|
||||
slot is empty, the project does not have an autonomously
|
||||
addressable queue — bounce back to the user with that diagnosis.
|
||||
issues via the list command in the project's CLAUDE.md project
|
||||
facts. If the project names no issue tracker there, it does not
|
||||
have an autonomously addressable queue — bounce back to the user
|
||||
with that diagnosis.
|
||||
|
||||
If the entire open backlog is empty: skip to Step 5
|
||||
(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)
|
||||
+
|
||||
tdd → implement (mini) (test-specifiable feature, if profile enables it)
|
||||
tdd → implement (mini) (test-specifiable feature)
|
||||
+
|
||||
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
|
||||
`SKILL.md` trigger section if unsure.
|
||||
|
||||
**Entry-path reflection (feature work).** When the profile enables the
|
||||
`tdd` phase, there are **three** entry paths for new feature work, and
|
||||
the choice is made by reflection every time, not by habit. Before
|
||||
**Entry-path reflection (feature work).** There are **three** entry
|
||||
paths for new feature work, and the choice is made by reflection every
|
||||
time, not by habit. Before
|
||||
dispatching, decide which fits the item in hand and record the one-line
|
||||
verdict ("test-specifiable → `tdd`" / "design settled → `specify`" /
|
||||
"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
|
||||
is **settled** and `specify` owns it. Dispatch `specify`
|
||||
autonomously: it is bounded (no interview), produces the spec through
|
||||
all the gates, and — unless the profile enables auto-sign (see below)
|
||||
— pauses at its own user-review gate (a problem-state notify, not a
|
||||
pre-dispatch checkpoint).
|
||||
all the gates, and — unless the project enables spec auto-sign (see
|
||||
below) — pauses at its own user-review gate (a problem-state notify,
|
||||
not a pre-dispatch checkpoint).
|
||||
- Writing the spec would force a choice between two or three plausible
|
||||
designs with real trade-offs — a genuine design fork — then discovery
|
||||
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).
|
||||
`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
|
||||
pre-dispatch checkpoint. The one exception is the opt-in auto-sign
|
||||
slot (`pipeline.boss.spec_auto_sign`): when a project enables it, a
|
||||
pre-dispatch checkpoint. The one exception is spec auto-sign: when a
|
||||
project enables it in its CLAUDE.md project facts, a
|
||||
spec that clears all objective gates AND a unanimous adversarial
|
||||
`spec-skeptic` panel is signed by the orchestrator without pausing,
|
||||
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
|
||||
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
|
||||
of routing borderline items to `brainstorm` "to be safe" — that is the
|
||||
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
|
||||
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
|
||||
two-way — `specify` for a settled design, `brainstorm` for an open one.
|
||||
`specify` is a core node (never profile-gated), so the settled-design
|
||||
path is always available; only the `tdd` test-specifiable branch is
|
||||
opt-in.
|
||||
All three entry paths are always available — none is profile-gated.
|
||||
The reflection is therefore always three-way: `tdd` for
|
||||
test-specifiable behaviour, `specify` for a settled design,
|
||||
`brainstorm` for an open one.
|
||||
|
||||
If the working tree is mid-flight (uncommitted changes left over
|
||||
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).
|
||||
- The user has explicitly asked for a checkpoint.
|
||||
- **The next item on the queue is a new cycle** — i.e. a top-
|
||||
level work container (in the project's vocabulary: milestone,
|
||||
epic, release, sprint root) that has no spec file yet and
|
||||
level work container (a milestone) that has no spec file yet and
|
||||
would require dispatching `brainstorm` to even begin.
|
||||
Continuing an open cycle (next iteration, audit, fieldtest,
|
||||
post-audit tidy) is autonomous; *starting* a new cycle is a
|
||||
@@ -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
|
||||
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
|
||||
continuing the run — see §"Spec auto-sign". This is the one
|
||||
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,
|
||||
continue.
|
||||
|
||||
The notification command is configured under
|
||||
`notifications.command` in the project profile and receives the
|
||||
message text as a single argument. If the profile does not
|
||||
configure one, fall back to printing the notification in chat.
|
||||
The notification command is `~/.claude/notify.sh` (the user-level
|
||||
convention); it receives the message text as a single argument. If it
|
||||
is unavailable, fall back to printing the notification in chat.
|
||||
|
||||
When notifying, the message body should be the actionable
|
||||
summary: what the orchestrator needs from the user, in one
|
||||
@@ -342,8 +339,8 @@ actionable ask, not a wrap-up summary.
|
||||
|
||||
## Spec auto-sign
|
||||
|
||||
Off by default. A project turns it on with
|
||||
`pipeline.boss.spec_auto_sign: true`. With it off, a `specify`
|
||||
Off by default. A project turns it on in its CLAUDE.md project facts
|
||||
(spec auto-sign: enabled). With it off, a `specify`
|
||||
dispatch in `/boss` always pauses for the user's signature — the
|
||||
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. |
|
||||
| "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. |
|
||||
| "`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. |
|
||||
| "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. |
|
||||
@@ -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 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 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
|
||||
|
||||
@@ -437,17 +434,17 @@ and defined there. The boss-side contract is just this:
|
||||
layer, loaded in every session, above the project file) — it
|
||||
carries constraints that bind autonomous runs too, including
|
||||
external-service-consent rules that `/boss` does not lift.
|
||||
- **Queue:** the URL configured under `git.issue_tracker.url` in
|
||||
the profile; CLI command at `git.issue_tracker.list_cmd`.
|
||||
- **Queue:** the project's issue tracker — its CLAUDE.md project
|
||||
facts name the repo slug, the browsable URL, and the list command.
|
||||
- **Glossary write-rule:** `../docs/glossary-convention.md` —
|
||||
record-reality discipline for the only autonomous glossary writer.
|
||||
- **Spec auto-sign gate:** owned by `../specify` Step 6; the
|
||||
adversarial juror is `../specify/agents/spec-skeptic.md` (dispatched
|
||||
five times, one per lens). Enabled per project by
|
||||
`pipeline.boss.spec_auto_sign` — see `../docs/profile-schema.md`.
|
||||
five times, one per lens). Enabled per project in its CLAUDE.md
|
||||
project facts — see `../docs/conventions.md`.
|
||||
- **Downstream skills dispatched:** `../brainstorm`,
|
||||
`../specify` (spec-production core; autonomously dispatchable for a
|
||||
settled design), `../planner`, `../implement`, `../audit`,
|
||||
`../fieldtest`, `../debug`, `../tdd` (test-specifiable feature,
|
||||
profile-gated; autonomously dispatchable like `../debug`),
|
||||
always available; autonomously dispatchable like `../debug`),
|
||||
`../docwriter`.
|
||||
|
||||
+8
-9
@@ -19,7 +19,7 @@ to prevent.
|
||||
|
||||
`brainstorm` does not write the spec. Its terminal state is handing the
|
||||
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*
|
||||
settled in the sources, `brainstorm` is skipped entirely and the work
|
||||
enters through `specify` directly.
|
||||
@@ -40,8 +40,7 @@ Triggers:
|
||||
long in-context discussion, settled design docs. Use `specify`
|
||||
directly: discovery would only re-litigate decisions the sources
|
||||
already made.
|
||||
- A test-specifiable feature, on a profile that enables `tdd` — use
|
||||
`tdd` directly.
|
||||
- A test-specifiable feature — use `tdd` directly.
|
||||
- A bug-fix iteration — use `debug` directly.
|
||||
- A tidy iteration — use `audit` directly.
|
||||
- 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
|
||||
recent iter / audit commits — current state of the project.
|
||||
- If the project has a design ledger configured under
|
||||
`paths.design_ledger`, walk to the relevant contracts for
|
||||
the invariants the new cycle might touch.
|
||||
- When reading any file under `paths.design_models` (or the
|
||||
ledger's "model" rows), note its `status` /
|
||||
- If the project has a design ledger (its CLAUDE.md project facts name
|
||||
it), walk to the relevant contracts for the invariants the new cycle
|
||||
might touch.
|
||||
- When reading any file under the project's design models, if it has
|
||||
them, or the ledger's "model" rows, note its `status` /
|
||||
`validated-against` frontmatter if present: `status:
|
||||
aspirational` means its code is a target, not verified fact.
|
||||
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.
|
||||
- **Ad-hoc dispatch.** The orchestrator MAY ad-hoc dispatch
|
||||
`../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.
|
||||
- **Project feature-acceptance criterion:** declared in the project's
|
||||
`CLAUDE.md` — applied prospectively by `specify` (its Step 2), not
|
||||
|
||||
+3
-4
@@ -28,8 +28,8 @@ dispatch, and handoff.
|
||||
|
||||
Trigger this skill on:
|
||||
|
||||
- a failing run of the project's test command (configured under
|
||||
`commands.test` in the profile)
|
||||
- a failing run of the project's test command (its CLAUDE.md
|
||||
project facts)
|
||||
- wrong stdout from running a project artefact
|
||||
- a segfault from a built binary
|
||||
- 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
|
||||
test-specifiable behaviour is its sibling `tdd`'s job (same
|
||||
two-stage RED→GREEN shape, triggered by a feature description
|
||||
rather than an observed misbehaviour) — route there instead,
|
||||
on profiles that enable it.
|
||||
rather than an observed misbehaviour) — route there instead.
|
||||
|
||||
## The Iron Law
|
||||
|
||||
|
||||
+13
-15
@@ -26,15 +26,14 @@ genuinely captures the symptom, not the post-fix code path.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.debugger` in the project profile.
|
||||
The defaults include `CLAUDE.md` for role boundaries and the
|
||||
recent `git log` for the most recent iter commits — the last
|
||||
iteration may have introduced the bug.
|
||||
Always read `CLAUDE.md` (for role boundaries) and
|
||||
`git log -10 --format=full` — the most recent iter commits, as
|
||||
the last iteration may have introduced the bug — plus the
|
||||
per-role standing reading the project lists in its CLAUDE.md
|
||||
project facts for the debugger role.
|
||||
|
||||
If the project has a design-ledger configured under
|
||||
`paths.design_ledger`, walk it for invariants the bug may have
|
||||
crossed.
|
||||
If the project has a design ledger (its CLAUDE.md project
|
||||
facts), walk it for invariants the bug may have crossed.
|
||||
|
||||
The four-phase process below is the single source of truth —
|
||||
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
|
||||
provides one, verify it; otherwise build one.
|
||||
3. Diagnose by data flow, not by guess:
|
||||
- Build error → run the project's build command
|
||||
(`commands.build` from the profile) with output captured
|
||||
- Test red → run the configured test command
|
||||
(`commands.test`) with verbose output and the failing
|
||||
test name targeted
|
||||
- Build error → run the project's build command (its
|
||||
CLAUDE.md project facts) with output captured
|
||||
- Test red → run the project's test command with verbose
|
||||
output and the failing test name targeted
|
||||
- Wrong stdout → run the artefact that produced it, capture
|
||||
stdout verbatim, compare to expected
|
||||
- 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.
|
||||
- Sweeping refactors layered on top of a bug fix.
|
||||
- Changes to the test once it's RED — the test is the contract.
|
||||
- Design-ledger edits (the file at `paths.design_ledger` in
|
||||
the profile, if configured).
|
||||
- Design-ledger edits (the project's design ledger, if it has
|
||||
one — its CLAUDE.md project facts).
|
||||
- Verdicts like "this whole subsystem is broken". Phase 4.5
|
||||
surfaces the architecture question; the orchestrator decides
|
||||
the verdict.
|
||||
|
||||
+13
-10
@@ -23,8 +23,10 @@ to prevent>
|
||||
|
||||
## Standing reading list
|
||||
|
||||
<list of always-binding documents — derived from the project
|
||||
profile's `standing_reading.always` plus `standing_reading.by_role.<this-role>`>
|
||||
<list of always-binding documents — the fixed always list (`CLAUDE.md`
|
||||
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
|
||||
|
||||
@@ -119,15 +121,16 @@ forcefully than "this role helps with X".
|
||||
|
||||
### Standing reading list
|
||||
|
||||
The plugin's skill body computes this from the project profile
|
||||
(`standing_reading.always` + `standing_reading.by_role.<role>`)
|
||||
and passes the resolved list to the agent via the carrier. The
|
||||
agent's body says, prosaically: "Read everything in the standing
|
||||
reading list before doing anything else."
|
||||
The plugin's skill body composes this list and passes it to the agent
|
||||
via the carrier. It is built from a fixed always list — `CLAUDE.md`
|
||||
plus `git log -10 --format=full`, binding on every role — extended by
|
||||
the per-role standing reading the project lists in its CLAUDE.md project
|
||||
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
|
||||
reads the project glossary without a per-role entry (see
|
||||
`profile-schema.md` § `paths`).
|
||||
When the project's CLAUDE.md project facts name a glossary path, that
|
||||
glossary is implicitly part of the always list, so every role reads the
|
||||
project glossary without a per-role entry.
|
||||
|
||||
The agent file itself does not hardcode file paths.
|
||||
|
||||
|
||||
@@ -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
@@ -1,20 +1,28 @@
|
||||
# Design
|
||||
|
||||
## Why split plugin from profile
|
||||
## Why split plugin from project
|
||||
|
||||
The skills system originally evolved inside the AILang project,
|
||||
where it grew organically against AILang's specific paths,
|
||||
build commands, vocabulary, and contracts. Lifting it into a
|
||||
plugin requires a clean separation between what is universal
|
||||
(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
|
||||
still make sense in a Python web project, a Rust CLI, and a
|
||||
TypeScript library? If yes, plugin. If it mentions `cargo`,
|
||||
`crates/`, `docs/design/INDEX.md`, `Form A`, or any project-specific
|
||||
identifier, it goes to the profile (as a slot) or to the
|
||||
project's `CLAUDE.md` (as sittenkodex).
|
||||
identifier, it goes to the project's `CLAUDE.md` — either as a
|
||||
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)
|
||||
|
||||
@@ -54,44 +62,42 @@ The plugin owns:
|
||||
- **Output budget discipline** — agents have word budgets on
|
||||
their reports.
|
||||
|
||||
## Profile layer (project-specific)
|
||||
## Fixed conventions (universal)
|
||||
|
||||
The profile fills slots that the plugin's prose references
|
||||
generically. Concretely:
|
||||
The constants that used to be configurable but were the same in
|
||||
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`,
|
||||
`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).
|
||||
## Project facts (project-specific)
|
||||
|
||||
The full schema lives in `profile-schema.md`. The functional
|
||||
starting template is `../templates/project-profile.yml`.
|
||||
The handful of facts that genuinely vary per project live in the
|
||||
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
|
||||
|
||||
The plugin uses **profile-driven prompts**, not template
|
||||
rendering. Each SKILL.md and agent file is generic prose that
|
||||
references the profile prosaically:
|
||||
The plugin uses **convention-and-fact prompts**, not template
|
||||
rendering and not a config parser. Each SKILL.md and agent file is
|
||||
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`
|
||||
> in the project profile. Use the naming policy configured under
|
||||
> `naming.policy`.
|
||||
> Write the spec to `docs/specs`. Use the project's build command
|
||||
> (its CLAUDE.md project facts).
|
||||
|
||||
When Claude Code loads the skill, the project profile is in
|
||||
context (the skill body explicitly instructs the model to read
|
||||
it first). The model performs the substitution at read-time.
|
||||
This avoids a build step and keeps a single source of truth in
|
||||
the repo.
|
||||
The project's `CLAUDE.md` is always in context (it is standing
|
||||
reading #1), so the model resolves the facts at read-time. This
|
||||
avoids a build step and keeps a single source of truth in the repo.
|
||||
|
||||
## Sittenkodex split
|
||||
|
||||
@@ -104,18 +110,19 @@ which are conditions for the plugin's own correctness.
|
||||
|
||||
The relationship:
|
||||
|
||||
- **Plugin** (this repo): mechanics, universal discipline
|
||||
- **Profile** (per project): slots — paths, commands,
|
||||
vocabulary, naming, git conventions, pipeline customisations
|
||||
- **Project CLAUDE.md**: sittenkodex — domain-specific anti-
|
||||
patterns and acceptance criteria
|
||||
- **Plugin** (this repo): mechanics, universal discipline, fixed
|
||||
conventions
|
||||
- **Project CLAUDE.md**: project facts — the few mechanical facts
|
||||
the skills consume (code roots, build/test, tracker slug, …) —
|
||||
plus sittenkodex (domain-specific anti-patterns and acceptance
|
||||
criteria)
|
||||
|
||||
## What's out of scope for this plugin
|
||||
|
||||
- **Issue-tracker integration**: the plugin can read the
|
||||
profile's `issue_tracker.kind`, `issue_tracker.list_cmd`, and
|
||||
`issue_tracker.show_cmd` and invoke the configured listing /
|
||||
single-issue commands, and `specify` may post a reconciliation
|
||||
- **Issue-tracker integration**: the plugin reads the project's
|
||||
issue-tracker commands (the repo slug, list command, and
|
||||
single-issue-with-comments command, all in its CLAUDE.md project
|
||||
facts) and invokes them, and `specify` may post a reconciliation
|
||||
comment via the tracker's comment command — but the plugin does
|
||||
not directly call Gitea / GitHub / Linear APIs. Every read and
|
||||
write goes through the configured shell command, so the plugin
|
||||
|
||||
@@ -9,18 +9,17 @@ this convention.
|
||||
|
||||
## Where it lives
|
||||
|
||||
A project opts in by setting `paths.glossary` in its
|
||||
`.claude/dev-cycle-profile.yml` (see `profile-schema.md` § `paths`).
|
||||
When the slot is set, the file it names is standing reading for every
|
||||
role — no separate `standing_reading.always` entry is required. When
|
||||
the slot is unset, the whole feature is a documented no-op.
|
||||
A project opts in by naming a glossary path in its CLAUDE.md project
|
||||
facts (see `conventions.md`). When it is named, the file it points to
|
||||
is standing reading for every role — no separate standing-reading entry
|
||||
is required. When the project names none, the whole feature is a
|
||||
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
|
||||
example renamings in `profile-schema.md` § `vocabulary` — the
|
||||
glossary's canonical entry, and its **Avoid** list, win. A
|
||||
`vocabulary.*` slot only sets which term the glossary then pins as
|
||||
canonical; it does not override the glossary.
|
||||
fixed vocabulary in `conventions.md` (cycle / iteration / milestone /
|
||||
contract) — the glossary's canonical entry, and its **Avoid** list,
|
||||
win.
|
||||
|
||||
## Format
|
||||
|
||||
|
||||
+9
-4
@@ -36,9 +36,12 @@ the structural binding.
|
||||
`docs/design/INDEX.md`, `crates/`, `bench/`).
|
||||
2. Strip project-specific commands (`cargo build`,
|
||||
`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`,
|
||||
`Boss`); use the profile's vocabulary slots.
|
||||
`Boss`); use the fixed vocabulary (cycle / iteration / milestone /
|
||||
contract).
|
||||
5. Strip project-specific contracts (honesty-rule,
|
||||
feature-acceptance). These belong in the project's own
|
||||
`CLAUDE.md`, not the plugin.
|
||||
@@ -51,8 +54,10 @@ the structural binding.
|
||||
1. Drop the `ailang-` prefix from the `name:` frontmatter
|
||||
field. The skill path is the disambiguator.
|
||||
2. Replace hardcoded standing-reading paths
|
||||
(`docs/design/INDEX.md`, etc.) with a reference to the profile's
|
||||
`standing_reading` section.
|
||||
(`docs/design/INDEX.md`, etc.) with the fixed standing reading
|
||||
(`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
|
||||
discipline constants; project-specific clauses go to the
|
||||
project's own `CLAUDE.md`.
|
||||
|
||||
+21
-19
@@ -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
|
||||
(directly from sources, or a ratified design handed over by
|
||||
`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
|
||||
interview. Bounces to `brainstorm` the moment the sources do not
|
||||
resolve a load-bearing design decision. A core node, not opt-in
|
||||
(unlike `tdd`).
|
||||
resolve a load-bearing design decision. A core node — the
|
||||
spec-production gate before `planner` on every design path.
|
||||
|
||||
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
|
||||
it on, a `/boss` run may sign a spec in the user's place — but only
|
||||
one exception is spec auto-sign (a project that enables it in its
|
||||
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
|
||||
`spec-skeptic` panel passes; the orchestrator's own confidence never
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
as one failing test. RED-first: the `tdd-author` agent turns a
|
||||
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.
|
||||
- `audit` is mandatory at cycle close.
|
||||
- `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
|
||||
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-
|
||||
dispatched.
|
||||
|
||||
@@ -225,14 +226,15 @@ commit body — never as undocumented practice.
|
||||
|
||||
## Pipeline configuration
|
||||
|
||||
The phase set, gating, and conditional dispatch are configured
|
||||
in the project profile under `pipeline:`. A project that does
|
||||
not want `fieldtest` simply omits the key. A project that wants
|
||||
a different gate set (e.g. `planner` without a `brainstorm`
|
||||
gate, for trivial bug-fix iterations) configures it there.
|
||||
There is none. The phase set, the gates, and the conditional
|
||||
dispatch shown above are fixed — the same for every project. All
|
||||
phases (`brainstorm`, `specify`, `planner`, `implement`, `audit`,
|
||||
`debug`, `tdd`, `fieldtest`, `docwriter`) are always available; which
|
||||
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 the profile sets `paths.glossary`, that file is standing reading
|
||||
for every role — the canonical-nomenclature source every skill and
|
||||
agent consults (see `glossary-convention.md`). Unset, it is a no-op.
|
||||
If a project declares a glossary in its CLAUDE.md project facts, that
|
||||
file is standing reading for every role — the canonical-nomenclature
|
||||
source every skill and agent consults (see `glossary-convention.md`).
|
||||
|
||||
@@ -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
@@ -23,9 +23,9 @@ never on a cycle clock.
|
||||
Orchestrator-dispatched only. Audit closing **does not**
|
||||
trigger docwriter. Trigger conditions are any of:
|
||||
|
||||
- The command configured under `commands.doc_build` in the
|
||||
project profile shows accumulated warnings across multiple
|
||||
components after a stability window of several cycles.
|
||||
- The project's doc-build command (its CLAUDE.md project facts)
|
||||
shows accumulated warnings across multiple components after a
|
||||
stability window of several cycles.
|
||||
- A backlog issue like "doc warning sweep" has matured — the
|
||||
surface it targets has not moved for a while.
|
||||
- Onboarding-readability check: navigating the generated docs
|
||||
|
||||
@@ -36,24 +36,24 @@ rename you make on the way.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.docwriter` in the project profile.
|
||||
The defaults include `CLAUDE.md` for the orchestrator framing.
|
||||
If the project has a design ledger configured under
|
||||
`paths.design_ledger`, walk it for the invariants the doc
|
||||
Always read `CLAUDE.md` (for the orchestrator framing) and
|
||||
`git log -10 --format=full`, plus the per-role standing reading
|
||||
the project lists in its CLAUDE.md project facts for the
|
||||
docwriter role. If the project has a design ledger (its
|
||||
CLAUDE.md project facts), walk it for the invariants the doc
|
||||
strings must reflect.
|
||||
|
||||
Additionally:
|
||||
|
||||
- `git log -10 --oneline` scoped to the project's code roots
|
||||
(`paths.code_roots`) — to spot which components recently
|
||||
shifted (those are likeliest to have stale docs).
|
||||
(its CLAUDE.md project facts) — to spot which components
|
||||
recently shifted (those are likeliest to have stale docs).
|
||||
- The components named in the carrier — read every public item
|
||||
before writing a single doc line. You can't summarise an
|
||||
item you haven't read.
|
||||
- Run the command configured under `commands.doc_build` and
|
||||
read all warnings. Every warning the carrier names must be
|
||||
gone when you're done.
|
||||
- Run the project's doc-build command (its CLAUDE.md project
|
||||
facts) and read all warnings. Every warning the carrier names
|
||||
must be gone when you're done.
|
||||
|
||||
## Carrier contract — what the controller hands you
|
||||
|
||||
@@ -71,7 +71,7 @@ If `scope` is empty, return `NEEDS_CONTEXT`.
|
||||
## 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.
|
||||
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.
|
||||
@@ -118,10 +118,10 @@ Javadoc `/** */`, etc.) for other languages.
|
||||
is so confusing it needs renaming, raise it in your report
|
||||
instead of changing it.
|
||||
- No new public exports. Visibility stays as-is.
|
||||
- No edits under the project's design or specs directories
|
||||
(`paths.design_ledger`, `paths.design_contracts`,
|
||||
`paths.design_models`, `paths.spec_dir`). The orchestrator
|
||||
owns those and the issue backlog.
|
||||
- No edits under the project's design directories — its design
|
||||
ledger, design contracts, and design models (its CLAUDE.md
|
||||
project facts) — or `docs/specs`. The orchestrator owns those
|
||||
and the issue backlog.
|
||||
- Don't paper over broken behaviour with prose — if
|
||||
doc-writing surfaces a real bug (a function whose doc you
|
||||
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`)
|
||||
|
||||
- `commands.doc_build` from the profile — zero warnings on
|
||||
every line you touched.
|
||||
- `commands.build` from the profile — green.
|
||||
- `commands.test` from the profile — green (doctests count
|
||||
if the language has them).
|
||||
- The project's doc-build command (its CLAUDE.md project facts)
|
||||
— zero warnings on every line you touched.
|
||||
- The project's build command — green.
|
||||
- The project's test command — green (doctests count if the
|
||||
language has them).
|
||||
|
||||
## Status protocol
|
||||
|
||||
@@ -195,7 +195,7 @@ for the orchestrator handoff, the produced fields are:
|
||||
directories
|
||||
- About to write a doc comment that contradicts the function
|
||||
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
|
||||
commit)
|
||||
- About to report `DONE` while one of the three verification
|
||||
|
||||
+6
-4
@@ -20,7 +20,7 @@ debt — even when audit reports `clean`.
|
||||
|
||||
The skill produces a friction-and-bug spec that the next
|
||||
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.
|
||||
|
||||
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
|
||||
`agents/fieldtester.md`. That file also carries the spec
|
||||
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,
|
||||
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
|
||||
field test is to simulate a downstream consumer who has only
|
||||
the public interface. The agent file enforces this with a
|
||||
hard path allowlist (computed from `paths.public_interface`
|
||||
in the profile); the orchestrator must trust that contract
|
||||
hard path allowlist (computed from the project's public
|
||||
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
|
||||
carrier.
|
||||
|
||||
|
||||
@@ -34,20 +34,22 @@ is for. Diagnostic unclear is *the finding*. Spec silent is
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.fieldtester` in the project
|
||||
profile. The defaults include `CLAUDE.md` for role boundaries.
|
||||
Always read `CLAUDE.md` (for role boundaries) and
|
||||
`git log -10 --format=full`, plus the per-role standing reading
|
||||
the project lists in its CLAUDE.md project facts for the
|
||||
fieldtester role.
|
||||
|
||||
In addition, you may read **only** files under the paths
|
||||
configured in `paths.public_interface` in the project profile.
|
||||
In addition, you may read **only** files under the project's
|
||||
public interface, if it has one (its CLAUDE.md project facts).
|
||||
This is the project's outward-facing surface (typically:
|
||||
README, the design ledger at `paths.design_ledger` if any,
|
||||
the docs directory, the examples corpus). You may NOT use
|
||||
the examples as a hint about how the implementation handles
|
||||
edge cases; only as a hint about the shape of the surface.
|
||||
README, the design ledger if any, the docs directory, the
|
||||
examples corpus). You may NOT use the examples as a hint about
|
||||
how the implementation handles edge cases; only as a hint about
|
||||
the shape of the surface.
|
||||
|
||||
You may also read fixtures you yourself create under
|
||||
`paths.fieldtest_examples`, plus any artefacts you produce
|
||||
You may also read fixtures you yourself create under the
|
||||
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
|
||||
IR, etc.).
|
||||
|
||||
@@ -69,7 +71,7 @@ skill references it rather than restating it.
|
||||
| `commit_range` | `<prev-cycle-close>..HEAD` |
|
||||
|
||||
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`.
|
||||
|
||||
### 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
|
||||
rather than yet another internal review. If you are about to
|
||||
read anything under `paths.code_roots` or `paths.bench_dir`
|
||||
(from the project profile), **stop**.
|
||||
read anything under the project's code roots or its benchmark
|
||||
directory (its CLAUDE.md project facts), **stop**.
|
||||
|
||||
The paths you may open are exactly:
|
||||
|
||||
- Files under `paths.public_interface` (from the profile)
|
||||
- Files under `paths.fieldtest_examples` that **you** create
|
||||
- Files under the project's public interface (its CLAUDE.md project facts)
|
||||
- Files under the project's fieldtest examples directory that **you** create
|
||||
- Artefacts you produce by running the project (binaries,
|
||||
output files, generated IR if exposed as part of the public
|
||||
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
|
||||
silently inverts its own purpose: it reports the *previously shipped*
|
||||
state as current, producing false positives on already-fixed bugs and
|
||||
masking newly-introduced ones. Run the build command from
|
||||
`commands.build` (or build the specific consumer binary the examples
|
||||
invoke) and confirm it succeeds before Phase 2 step 1; if the examples
|
||||
masking newly-introduced ones. Run the project's build command (its
|
||||
CLAUDE.md project facts) — or build the specific consumer binary the
|
||||
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
|
||||
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
|
||||
@@ -164,8 +166,9 @@ For each example, in this order:
|
||||
tool, etc.). Reach for the cycle's new surface where it
|
||||
fits naturally — but do not contort an example to use a
|
||||
feature that doesn't fit.
|
||||
2. Save under `paths.fieldtest_examples` with a name
|
||||
like `<cycle-short>_<n>_<slug>.<ext>`.
|
||||
2. Save under the project's fieldtest examples directory (its
|
||||
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
|
||||
commands, the exact output, the exact errors.
|
||||
4. Record verbatim:
|
||||
@@ -208,8 +211,9 @@ not merged.
|
||||
|
||||
### Phase 5 — Write the spec, hand back
|
||||
|
||||
Write the fieldtest spec under `paths.spec_dir` with a name
|
||||
shape per the project's naming convention. Use the spec
|
||||
Write the fieldtest spec under `docs/specs` with a name
|
||||
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
|
||||
spec file) in the working tree as unstaged changes. You do
|
||||
NOT commit — the orchestrator commits after reading the
|
||||
@@ -280,7 +284,7 @@ At most 350 words, structured:
|
||||
+ outcome (built? ran? matched expected?).
|
||||
- **Findings count by class:** e.g.
|
||||
`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`,
|
||||
`friction → plan` (tidy iteration),
|
||||
`spec_gap → ratify` or `tighten the design ledger`,
|
||||
@@ -298,7 +302,7 @@ fields are:
|
||||
|
||||
| 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 |
|
||||
| `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.
|
||||
- Edits to any file under the design ledger or specs
|
||||
directory. Spec gaps are reported, not patched.
|
||||
- Edits to anything under `paths.code_roots` or
|
||||
`paths.bench_dir`.
|
||||
- Edits to anything under the project's code roots or its
|
||||
benchmark directory (its CLAUDE.md project facts).
|
||||
- A `friction` finding without a 1-line recommendation.
|
||||
Every finding is actionable or it isn't a finding.
|
||||
- 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
|
||||
|
||||
- About to open any path under `paths.code_roots` or
|
||||
`paths.bench_dir`
|
||||
- About to open any path under the project's code roots or its
|
||||
benchmark directory (its CLAUDE.md project facts)
|
||||
- About to open an implementation-source file at all
|
||||
- About to hand-author an intermediate representation,
|
||||
internal serialisation, or any non-canonical fixture form
|
||||
|
||||
+25
-22
@@ -30,15 +30,15 @@ Triggers:
|
||||
- **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
|
||||
(a term already in consistent use, or a drift boss just resolved).
|
||||
- **bootstrap** — a project has terminology to pin but no glossary
|
||||
(`paths.glossary` unset, or naming an empty file), and the user invokes
|
||||
the build.
|
||||
- **bootstrap** — a project has terminology to pin but no glossary (no
|
||||
glossary path in its CLAUDE.md project facts, or the named file is
|
||||
empty), and the user invokes the build.
|
||||
|
||||
Skip or refuse:
|
||||
|
||||
- maintain asked with no `paths.glossary` slot set: there is nowhere to
|
||||
write. Stop and instruct the user to set `paths.glossary` (see
|
||||
`../docs/profile-schema.md` § `paths`) first.
|
||||
- maintain asked when the project's CLAUDE.md project facts name no
|
||||
glossary path: there is nowhere to write. Stop and instruct the user to
|
||||
record the glossary path in the project's CLAUDE.md first.
|
||||
- bootstrap asked on a glossary that already has entries: do not clobber.
|
||||
Stop with the entry count and recommend maintain.
|
||||
- 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
|
||||
|
||||
1. **Read the glossary and the convention.** Read the file named by
|
||||
`paths.glossary` and `../docs/glossary-convention.md`. If
|
||||
`paths.glossary` is unset, stop (see When to Use / Skipping).
|
||||
1. **Read the glossary and the convention.** Read the glossary file the
|
||||
project's CLAUDE.md project facts name, plus
|
||||
`../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:**`
|
||||
line, and a definition — the user's, or (in a boss session bound by
|
||||
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)
|
||||
|
||||
1. **Guard.** Read `paths.glossary`. If it names a file that already has
|
||||
entries, stop with the count and recommend maintain. If the slot is
|
||||
unset, continue, and note the build will also propose setting the slot
|
||||
(see `../docs/profile-schema.md` § `paths`).
|
||||
1. **Guard.** Read the glossary path from the project's CLAUDE.md project
|
||||
facts. If it names a file that already has entries, stop with the count
|
||||
and recommend maintain. If the project facts name no glossary path,
|
||||
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
|
||||
the project: `docs/`, `README.md`, the design ledger (if
|
||||
`paths.design_ledger` is set), the spec directory. One slice per
|
||||
coherent group, sized so a single agent can sweep it.
|
||||
the project: `docs/`, `README.md`, the project's design ledger, if it
|
||||
has one (its CLAUDE.md project facts), the spec directory `docs/specs`.
|
||||
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
|
||||
agent (`agents/glossary-extractor.md`) with the carrier: the slice and
|
||||
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
|
||||
resolve is left OUT of the glossary and noted as deferred. Never coin a
|
||||
term to fill a gap.
|
||||
7. **Assemble UNSTAGED.** Write the conforming glossary to
|
||||
`paths.glossary` (proposing the slot value if it was unset), in the
|
||||
convention's flat per-term-block format. Leave it unstaged for review.
|
||||
7. **Assemble UNSTAGED.** Write the conforming glossary to the path the
|
||||
project's CLAUDE.md project facts name (proposing one if none is
|
||||
recorded yet), in the convention's flat per-term-block format. Leave it
|
||||
unstaged for review.
|
||||
|
||||
## Iron Law
|
||||
|
||||
@@ -167,9 +170,9 @@ BOOTSTRAP IS USER-ONLY. NEVER COIN A TERM — RECORD REALITY.
|
||||
- **Rules (the single source):** `../docs/glossary-convention.md` —
|
||||
format, reading obligation, write-rule, glossary-as-SoT. This skill
|
||||
applies these; it restates none.
|
||||
- **Slot semantics:** `../docs/profile-schema.md` § `paths` — the
|
||||
`paths.glossary` slot (set ⇒ standing reading for every role; unset ⇒
|
||||
no-op).
|
||||
- **Glossary path:** the project's CLAUDE.md project facts — when they
|
||||
name a glossary path it is standing reading for every role; when they
|
||||
name none, this skill has nowhere to write and bootstrap proposes one.
|
||||
- **Agent dispatched:** `agents/glossary-extractor.md` — read-only
|
||||
per-slice prose extraction, fanned out in bootstrap.
|
||||
- **Glossary instance (dogfood):** `../docs/glossary.md` — this plugin's
|
||||
|
||||
@@ -19,10 +19,11 @@ slice and merges their reports.
|
||||
## Standing reading list
|
||||
|
||||
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
|
||||
standing reading, and `docs/glossary-convention.md` defines what a
|
||||
glossary-worthy concept term is versus incidental vocabulary — consult it
|
||||
so you report concepts, not every capitalised word.
|
||||
doing anything else. When the project's CLAUDE.md project facts name a
|
||||
glossary path, that glossary is standing reading for every role, and
|
||||
`docs/glossary-convention.md` defines what a glossary-worthy concept term
|
||||
is versus incidental vocabulary — consult it so you report concepts, not
|
||||
every capitalised word.
|
||||
|
||||
## Carrier contract
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
@@ -34,7 +34,7 @@ orchestrator-agent every dispatch.
|
||||
|
||||
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
|
||||
executable-spec) has handed off for the GREEN side (mini mode).
|
||||
|
||||
@@ -86,7 +86,7 @@ For a standard iteration:
|
||||
Agent("implement-orchestrator", {
|
||||
mode: "standard",
|
||||
iter_id: "<iter_id>",
|
||||
plan_path: "<path under paths.plan_dir>",
|
||||
plan_path: "<path under docs/plans>",
|
||||
task_range: [3, 8]
|
||||
})
|
||||
```
|
||||
@@ -188,7 +188,7 @@ history rewinding on main even if there were.
|
||||
|
||||
| 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 |
|
||||
|
||||
`implement` produces: an unstaged working tree containing the
|
||||
|
||||
@@ -28,16 +28,16 @@ with it.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.implement-orchestrator` in the
|
||||
project profile. The defaults include `CLAUDE.md` for
|
||||
orchestrator framing.
|
||||
The standing reading is fixed: `CLAUDE.md` plus
|
||||
`git log -10 --format=full` (see docs/conventions.md). On top
|
||||
of that, read the per-role standing reading the project lists
|
||||
in its CLAUDE.md project facts for `implement-orchestrator`.
|
||||
`CLAUDE.md` gives the orchestrator framing.
|
||||
|
||||
Additionally, every dispatch:
|
||||
|
||||
- If the project has a design ledger configured under
|
||||
`paths.design_ledger`, walk it for the invariants any iter
|
||||
must respect.
|
||||
- If the project has a design ledger (its CLAUDE.md project
|
||||
facts), walk it for the invariants any iter must respect.
|
||||
- `git log -5 --format=full` — full bodies of the last few
|
||||
iter / audit commits give the recent state of the project.
|
||||
Augment with `git log -15 --oneline` for a chronological
|
||||
@@ -58,7 +58,7 @@ rather than restating the semantics.
|
||||
|-------|---------|
|
||||
| `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) |
|
||||
| `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 |
|
||||
| `red_test_path` | (mini only) absolute path to the RED test from `debug` |
|
||||
| `cause_summary` | (mini only) 1–2 sentences from the debugger agent |
|
||||
@@ -309,8 +309,9 @@ visibility in `git status` is the point.
|
||||
### Phase 5 — Write stats file
|
||||
|
||||
Write a stats file at `/tmp/iter-<iter_id>/stats.json`, or
|
||||
under a project-configured stats directory if the project
|
||||
declares one (typically a subdirectory of `paths.bench_dir`).
|
||||
under a project stats directory if the project declares one
|
||||
(typically a subdirectory of the project's bench dir, if it
|
||||
has one — its CLAUDE.md project facts).
|
||||
At minimum:
|
||||
|
||||
```json
|
||||
|
||||
@@ -30,14 +30,15 @@ disappears.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.implementer` in the project
|
||||
profile. The defaults include `CLAUDE.md` for orchestrator
|
||||
framing and the project's design ledger (if configured) for
|
||||
the binding architectural decisions.
|
||||
The standing reading is fixed: `CLAUDE.md` plus
|
||||
`git log -10 --format=full` (see docs/conventions.md). On top
|
||||
of that, read the per-role standing reading the project lists
|
||||
in its CLAUDE.md project facts for `implementer`. `CLAUDE.md`
|
||||
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
|
||||
`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
|
||||
to you via the carrier (see below). If something is missing
|
||||
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:
|
||||
|
||||
- Pure refactors with no behaviour change — existing tests
|
||||
are the verification; if the project's `commands.test`
|
||||
is green pre and post, you're fine.
|
||||
are the verification; if the project's test command (its
|
||||
CLAUDE.md project facts) is green pre and post, you're fine.
|
||||
- Test-only tasks — you ARE writing the test, so no
|
||||
separate RED step.
|
||||
- Doc / comment / formatting changes.
|
||||
@@ -94,8 +95,8 @@ is yes — write the test.
|
||||
## Architecture rules
|
||||
|
||||
The binding architectural rules of the project are declared
|
||||
in `CLAUDE.md` and (if the project has one) the design
|
||||
ledger at `paths.design_ledger`. The specific rules are
|
||||
in `CLAUDE.md` and (if the project has one) its design
|
||||
ledger. The specific rules are
|
||||
project-specific, but they typically cover:
|
||||
|
||||
- **Determinism contracts.** Canonical forms, sort orders,
|
||||
@@ -149,8 +150,8 @@ substitute.
|
||||
- **REFACTOR** (optional, only if the diff has
|
||||
duplication or unclear names): clean up while keeping
|
||||
the test green. Don't add behaviour.
|
||||
6. **Verify** with the project's `commands.build` and
|
||||
`commands.test`. Both MUST be green. The test you wrote
|
||||
6. **Verify** with the project's build and test commands
|
||||
(its CLAUDE.md project facts). Both MUST be green. The test you wrote
|
||||
in RED MUST pass; no other test may regress.
|
||||
7. **Property doc comment.** The new test's doc comment
|
||||
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. |
|
||||
| "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. |
|
||||
| "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
|
||||
|
||||
@@ -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 substitute a "better" approach for the one in
|
||||
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
|
||||
contain what you need
|
||||
- About to write production code while the corresponding
|
||||
RED test does not yet exist (or has not yet been run +
|
||||
observed to fail)
|
||||
- About to mark a refactor `DONE` without re-running the
|
||||
project's `commands.test`
|
||||
project's test command
|
||||
|
||||
@@ -36,17 +36,18 @@ solution rather than the right one.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.quality-reviewer` in the
|
||||
project profile. The defaults include `CLAUDE.md` for
|
||||
orchestrator framing and the project's stated quality bar
|
||||
(the "Doing tasks" / discipline sections at the project
|
||||
level).
|
||||
The standing reading is fixed: `CLAUDE.md` plus
|
||||
`git log -10 --format=full` (see docs/conventions.md). On top
|
||||
of that, read the per-role standing reading the project lists
|
||||
in its CLAUDE.md project facts for `quality-reviewer`.
|
||||
`CLAUDE.md` gives the orchestrator framing and the project's
|
||||
stated quality bar (the "Doing tasks" / discipline sections
|
||||
at the project level).
|
||||
|
||||
Additionally:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if
|
||||
configured) — invariants the diff must respect live in
|
||||
- The project's design ledger, if it has one (its CLAUDE.md
|
||||
project facts) — invariants the diff must respect live in
|
||||
the linked contracts.
|
||||
- `../SKILL.md` (the implement SKILL) — the two-stage
|
||||
review process you are the second half of.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
---
|
||||
|
||||
@@ -40,20 +40,21 @@ extras, and you stop.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.spec-reviewer` in the project
|
||||
profile. The defaults include `CLAUDE.md` for orchestrator
|
||||
framing.
|
||||
The standing reading is fixed: `CLAUDE.md` plus
|
||||
`git log -10 --format=full` (see docs/conventions.md). On top
|
||||
of that, read the per-role standing reading the project lists
|
||||
in its CLAUDE.md project facts for `spec-reviewer`. `CLAUDE.md`
|
||||
gives the orchestrator framing.
|
||||
|
||||
Additionally:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if
|
||||
configured) — cross-reference any architectural-feeling
|
||||
- The project's design ledger, if it has one (its CLAUDE.md
|
||||
project facts) — cross-reference any architectural-feeling
|
||||
claim in the task text against the contract it links.
|
||||
- `../SKILL.md` (the implement SKILL) — the two-stage
|
||||
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
|
||||
your spec for this review.
|
||||
|
||||
|
||||
@@ -30,15 +30,16 @@ state the invariant in the doc comment, and you stop.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.tester` in the project
|
||||
profile. The defaults include `CLAUDE.md` for the
|
||||
orchestrator framing.
|
||||
The standing reading is fixed: `CLAUDE.md` plus
|
||||
`git log -10 --format=full` (see docs/conventions.md). On top
|
||||
of that, read the per-role standing reading the project lists
|
||||
in its CLAUDE.md project facts for `tester`. `CLAUDE.md` gives
|
||||
the orchestrator framing.
|
||||
|
||||
Additionally:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if
|
||||
configured) — the invariants the tests must protect live
|
||||
- The project's design ledger, if it has one (its CLAUDE.md
|
||||
project facts) — the invariants the tests must protect live
|
||||
in the linked contracts.
|
||||
- `git log -3 --format=full` — full bodies of the most
|
||||
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
|
||||
location.
|
||||
- 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
|
||||
as unstaged edits; the orchestrator commits them at the
|
||||
end of the iter alongside the feature work they protect.
|
||||
@@ -153,4 +155,4 @@ At most 200 words:
|
||||
property
|
||||
- About to introduce a non-deterministic input (system
|
||||
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
@@ -52,5 +52,5 @@ done
|
||||
|
||||
echo
|
||||
echo "Install complete."
|
||||
echo "Next: drop a profile into each project that should use the plugin:"
|
||||
echo " cp $REPO_DIR/templates/project-profile.yml <project>/.claude/dev-cycle-profile.yml"
|
||||
echo "Next: add a '## Skills plugin: project facts' section to each"
|
||||
echo "project's CLAUDE.md (template: $REPO_DIR/templates/CLAUDE.md.fragment)."
|
||||
|
||||
+2
-2
@@ -88,8 +88,8 @@ artefact mirrored to Gitea ("would it be committed → English", per
|
||||
`tea` is pre-authenticated via its own config (`~/.config/tea/`).
|
||||
Never read or echo that file — it holds a token. `tea` auto-detects
|
||||
the repository from the git remote; override with `--repo owner/name`
|
||||
when running outside the repo (the slug lives in
|
||||
`issue_tracker.repo` if a project profile sets it).
|
||||
when running outside the repo (the project's issue tracker — its
|
||||
CLAUDE.md project facts name the repo slug and the list/show commands).
|
||||
|
||||
| Operation | Command |
|
||||
|---|---|
|
||||
|
||||
+20
-18
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
@@ -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
|
||||
2-5 minutes without making judgement calls outside its remit.
|
||||
|
||||
Plans live under the project's `paths.plan_dir` with a name
|
||||
shape governed by the project's `naming.policy` (see profile
|
||||
schema). The header references the parent spec. The plan
|
||||
Plans live under `docs/plans` with the fixed name shape
|
||||
`NNNN-slug.md` — a 4-digit counter per directory (see
|
||||
`docs/conventions.md`). The header references the parent spec. The plan
|
||||
decomposes work into tasks; each task is the unit of review
|
||||
(spec-compliance and quality gates inside `implement`), not
|
||||
the unit of commit. Commits are an orchestrator-only decision
|
||||
@@ -28,7 +28,7 @@ diff.
|
||||
|
||||
Triggers:
|
||||
|
||||
- A spec under `paths.spec_dir` for the active cycle is
|
||||
- A spec under `docs/specs` for the active cycle is
|
||||
approved.
|
||||
- A new iteration within an active cycle is starting.
|
||||
|
||||
@@ -62,7 +62,7 @@ Non-negotiable.
|
||||
|
||||
### 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
|
||||
it before planning.
|
||||
|
||||
@@ -120,7 +120,7 @@ action that takes 2-5 minutes:
|
||||
|
||||
- [ ] **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>"
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
@@ -144,7 +144,7 @@ Every plan starts with this header:
|
||||
```markdown
|
||||
# <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
|
||||
> `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.
|
||||
9. **Parse-the-bytes-you-inline gate.** Every verbatim code body
|
||||
the plan inlines into a task step must be run through the
|
||||
`spec_validation` gate defined in `docs/profile-schema.md`
|
||||
(which owns the parser-invocation protocol, the noted
|
||||
no-parser skip, the malformed-entry failure, and the no-op
|
||||
when the profile declares no `spec_validation`) before
|
||||
spec-validation parsers the project declares in its CLAUDE.md
|
||||
project facts, following the parser-invocation protocol in
|
||||
`docs/conventions.md` (which owns the no-parser skip, the
|
||||
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
|
||||
lifts verbatim (example programs, fixtures); the project's
|
||||
source-language test / implementation bodies are NOT the
|
||||
@@ -242,7 +243,7 @@ Fix issues inline.
|
||||
### Step 6 — Hand off
|
||||
|
||||
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").
|
||||
|
||||
The orchestrator commits the plan when handing it forward
|
||||
@@ -253,8 +254,8 @@ The planner skill does not perform the commit itself.
|
||||
|
||||
| Direction | Carrier |
|
||||
|-----------|---------|
|
||||
| `specify` → `planner` | path to the spec under `paths.spec_dir` + iteration scope ("this iteration covers spec section X+Y") |
|
||||
| `planner` → `implement` | path to the plan under `paths.plan_dir` + optional task-range focus |
|
||||
| `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 `docs/plans` + optional task-range focus |
|
||||
| `planner` → `specify` (bounce) | spec contains placeholders or contradictions: name the offending section, request revision |
|
||||
|
||||
## 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. |
|
||||
| "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 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
|
||||
|
||||
@@ -279,8 +280,9 @@ The planner skill does not perform the commit itself.
|
||||
- Header missing parent spec reference
|
||||
- Self-review skipped because "the plan looks fine"
|
||||
- A task step inlining a surface-language code body whose fence
|
||||
label has a configured `spec_validation` parser, handed off
|
||||
without a parse-trace in the planner session
|
||||
label has a project-declared spec-validation parser (its
|
||||
CLAUDE.md project facts), handed off without a parse-trace in
|
||||
the planner session
|
||||
|
||||
## Cross-references
|
||||
|
||||
|
||||
@@ -32,21 +32,21 @@ naming where work lands.
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.plan-recon` in the project
|
||||
profile.
|
||||
The standing reading is `CLAUDE.md` plus
|
||||
`git log -10 --format=full`, then the per-role standing
|
||||
reading the project lists in its CLAUDE.md project facts.
|
||||
|
||||
In addition:
|
||||
|
||||
- If the project has a design ledger configured under
|
||||
`paths.design_ledger`, walk it to the contracts the carrier
|
||||
- If the project has a design ledger (its CLAUDE.md project
|
||||
facts), walk it to the contracts the carrier
|
||||
flags or that the spec touches; do not skim sections the
|
||||
spec does not touch.
|
||||
- `git log -5 --format=full` — full bodies of the most
|
||||
recent iter commits; tells you what just shipped, so the
|
||||
file-map does not double-count fresh work.
|
||||
- `../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.
|
||||
|
||||
## Carrier contract — what the controller hands you
|
||||
@@ -58,7 +58,7 @@ it.
|
||||
|
||||
| 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) |
|
||||
| `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,
|
||||
type, function, or invariant.
|
||||
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
|
||||
`git grep` or `Glob`+`Read` to anchor it to exact line
|
||||
numbers in the current tree. Record:
|
||||
|
||||
+4
-4
@@ -126,8 +126,8 @@ report.
|
||||
Resolve in this order:
|
||||
|
||||
1. `--out <path>` if the invoker passed one.
|
||||
2. The project profile's `paths.postmortem_dir` (if a
|
||||
`.claude/dev-cycle-profile.yml` exists and defines it).
|
||||
2. The project's post-mortem directory, if it has one (its CLAUDE.md
|
||||
project facts).
|
||||
3. Default: `docs/postmortems/<session-id-short>-<yyyy-mm-dd>.md`
|
||||
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.
|
||||
- **Hand-off target:** the `issue` skill, when a finding is a
|
||||
trackable defect worth filing.
|
||||
- **Profile slot (optional):** `paths.postmortem_dir` for the
|
||||
report destination.
|
||||
- **Report destination (optional):** the project's post-mortem
|
||||
directory, if its CLAUDE.md project facts name one.
|
||||
- **Data-source note:** this skill reads only the current
|
||||
session's own transcript and subagent logs. It does not crawl
|
||||
other projects or other sessions (single-session by design).
|
||||
|
||||
+26
-20
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
@@ -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
|
||||
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
|
||||
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
|
||||
|
||||
@@ -52,8 +54,8 @@ Triggers:
|
||||
load-bearing decision. Use `brainstorm` (its discovery is what
|
||||
resolves the fork). `specify` itself bounces here the moment it
|
||||
detects this (see The Iron Law and Step 1.5).
|
||||
- A test-specifiable feature, on a profile that enables `tdd` — the
|
||||
RED executable-spec is the spec. Use `tdd` directly.
|
||||
- A test-specifiable feature — the RED executable-spec is the spec.
|
||||
Use `tdd` directly.
|
||||
- An observed bug — use `debug` directly (RED-first).
|
||||
- A tidy iteration — use `audit` directly.
|
||||
- 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
|
||||
is already in-context. Re-ground lightly — fresh `git log`, the
|
||||
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:
|
||||
aspirational` source: its code is a target, not verified fact —
|
||||
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.
|
||||
|
||||
**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
|
||||
validation by default. Treat it as the spec's most suspect bytes: it
|
||||
must clear the Step-4 parse-every-block gate before PASS.
|
||||
|
||||
### Step 3 — Write the spec
|
||||
|
||||
Path: under `paths.spec_dir`, with a name per the project's
|
||||
`naming.policy` (see profile schema). Determine the next slot per the
|
||||
policy.
|
||||
Path: under `docs/specs`, named per the fixed naming convention —
|
||||
`NNNN-slug.md`, 4-digit per-directory counter (see
|
||||
`docs/conventions.md`). Determine the next free number by scanning the
|
||||
directory.
|
||||
|
||||
Structure:
|
||||
|
||||
@@ -256,10 +259,10 @@ Inline checklist (not a subagent dispatch):
|
||||
worked user-facing example for a surface cycle)? A load-bearing
|
||||
change described only in prose is a self-review failure to fix.
|
||||
6. **Parse-every-block gate.** Extract every fenced code block and run
|
||||
it through the `spec_validation` gate defined in
|
||||
`docs/profile-schema.md` (which owns the parser-invocation
|
||||
protocol, the no-parser skip, the malformed-entry failure, and the
|
||||
no-op when the profile declares no `spec_validation`). A parse
|
||||
it through the spec-validation parsers the project declares in its
|
||||
CLAUDE.md project facts (a fence label with no parser is a documented
|
||||
skip, never a silent pass; a malformed entry fails closed; the whole
|
||||
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
|
||||
unparsed bytes downstream. Paste the parse-trace into the chat: a
|
||||
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 —
|
||||
it is bounded (no interview). It runs the criterion, parse, and
|
||||
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
|
||||
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:
|
||||
|
||||
- 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
|
||||
spec")
|
||||
|
||||
@@ -488,8 +492,9 @@ discipline `tdd` applies when behaviour is not test-specifiable.
|
||||
- "The sources are thorough, skip a gate" thoughts (any flavour)
|
||||
- A load-bearing change described in prose with no before → after code
|
||||
block; a surface cycle with no worked user-facing example
|
||||
- A spec carrying a code block whose fence label has a configured
|
||||
`spec_validation` parser, committed without a parse-trace in the chat
|
||||
- A spec carrying a code block whose fence label has a spec-validation
|
||||
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
|
||||
flagging it for the Step-4 parse gate
|
||||
- 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.
|
||||
- **Agent dispatched (auto-sign only):** `agents/spec-skeptic.md` —
|
||||
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
|
||||
what lets the orchestrator sign in the user's place. An editorial-lens
|
||||
`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.
|
||||
- **Ad-hoc dispatch.** The orchestrator MAY also ad-hoc dispatch
|
||||
`../planner/agents/plan-recon.md` during Step 1 when the work enters
|
||||
code territory not recently read; opt-in, not part of the standard
|
||||
process.
|
||||
code territory not recently read; discretionary, not part of the
|
||||
standard process.
|
||||
- **Project feature-acceptance criterion:** declared in the project's
|
||||
`CLAUDE.md`. Applied prospectively in Step 2.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
---
|
||||
|
||||
@@ -28,16 +28,16 @@ right now, justify the assertions this spec rests on?"
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.grounding-check` in the
|
||||
project profile. The defaults include `CLAUDE.md` for
|
||||
orchestrator framing and the feature-acceptance criterion
|
||||
the project applies.
|
||||
The standing reading is `CLAUDE.md` plus
|
||||
`git log -10 --format=full`, then the per-role standing
|
||||
reading the project lists in its CLAUDE.md project facts.
|
||||
`CLAUDE.md` carries the orchestrator framing and the
|
||||
feature-acceptance criterion the project applies.
|
||||
|
||||
In addition, every dispatch:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if
|
||||
configured) plus the contracts its index links — the
|
||||
- The project's design ledger, if it has one (its CLAUDE.md
|
||||
project facts), plus the contracts its index links — the
|
||||
canonical contract ledger the new spec must compose with.
|
||||
- `git log -5 --format=full` — full bodies of the
|
||||
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
|
||||
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
|
||||
`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
|
||||
section, not the whole spec.
|
||||
|
||||
@@ -109,8 +109,8 @@ decreasing order of strength:
|
||||
|
||||
1. A direct unit / integration test that exercises the
|
||||
mechanism by name.
|
||||
2. An end-to-end fixture (under the examples / fixtures
|
||||
directory configured in the project) that exercises the
|
||||
2. An end-to-end fixture (under the project's examples /
|
||||
fixtures directory) that exercises the
|
||||
mechanism indirectly but whose build / run output
|
||||
depends on it.
|
||||
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.
|
||||
RATIFICATION REQUIRES A NAMED, CURRENTLY-GREEN TEST. NOT CODE PRESENCE. NOT RECALL.
|
||||
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 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:
|
||||
- Identify keywords (function names, type names, schema
|
||||
fields, pass names) the assumption mentions.
|
||||
- `grep` the test directories under `paths.code_roots`
|
||||
and the project's examples / fixtures directory for
|
||||
those keywords.
|
||||
- `grep` the test directories under the project's code
|
||||
roots (its CLAUDE.md project facts) and the project's
|
||||
examples / fixtures directory for those keywords.
|
||||
- Enumerate tests by name using the project's test-list
|
||||
command (e.g. `cargo test --list -p <crate>` for Rust;
|
||||
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
|
||||
concrete tests found) or `unratified` (no test, or only
|
||||
weak candidates).
|
||||
5. **Code-block parse pass.** If the project profile declares
|
||||
`spec_validation.parsers`, extract every fenced code block
|
||||
5. **Code-block parse pass.** If the project declares
|
||||
spec-validation parsers (its CLAUDE.md project facts),
|
||||
extract every fenced code block
|
||||
from the spec. For each block whose fence label has a
|
||||
`parsers` entry: write it to a temp file with the entry's
|
||||
`ext`, run the entry's `cmd` with `{file}` substituted, and
|
||||
declared parser: write it to a temp file with the parser's
|
||||
`ext`, run the parser's `cmd` with `{file}` substituted, and
|
||||
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
|
||||
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
|
||||
assumption search: it checks the spec's own bytes against the
|
||||
live tool, not the codebase's behaviour — and it is
|
||||
independent of the orchestrator's own Step-7 parse gate, the
|
||||
fresh-context second line of the same defense.
|
||||
6. Compute aggregate status:
|
||||
- All assumptions ratified AND every configured-label block
|
||||
parsed clean → `PASS`.
|
||||
- All assumptions ratified AND every block whose fence label
|
||||
has a declared parser parsed clean → `PASS`.
|
||||
- One or more unratified assumptions, OR one or more
|
||||
unparseable code blocks → `BLOCK`.
|
||||
- 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`.
|
||||
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". |
|
||||
| "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. |
|
||||
| "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
|
||||
|
||||
@@ -278,7 +279,7 @@ the assumption-extraction step yields an empty list, emit
|
||||
- About to mark an assumption ratified based on code
|
||||
presence rather than test presence
|
||||
- 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
|
||||
true"
|
||||
- Report exceeding ~500 tokens
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
---
|
||||
|
||||
@@ -12,7 +12,8 @@ tools: Read, Glob, Grep, Bash
|
||||
|
||||
A spec normally carries the user's signature: the human reads it
|
||||
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
|
||||
self-confidence is not a safety signal**. The orchestrator that
|
||||
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
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.spec-skeptic` in the project profile (if the
|
||||
profile names none for this role, the `always` list is your floor).
|
||||
The defaults include `CLAUDE.md` for orchestrator framing and the
|
||||
The standing reading is `CLAUDE.md` plus
|
||||
`git log -10 --format=full`, then the per-role standing reading the
|
||||
project lists in its CLAUDE.md project facts (if the project names none
|
||||
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`
|
||||
lens leans on it directly.
|
||||
|
||||
In addition, every dispatch:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if configured)
|
||||
plus the contracts its index links — the canonical ledger the spec
|
||||
must compose with.
|
||||
- The project's design ledger, if it has one (its CLAUDE.md project
|
||||
facts), plus the contracts its index links — the canonical ledger
|
||||
the spec must compose with.
|
||||
- `git log -5 --format=full` — recent context.
|
||||
- The plugin's `../../README.md` — skill-system architecture and the
|
||||
standard agent structure.
|
||||
- The spec file at `spec_path` (the spec under review).
|
||||
- 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.
|
||||
- For the `scope-fork` lens additionally: the sources the spec was
|
||||
built from. The seeding issue is reachable via the profile's
|
||||
`issue_tracker.show_cmd` (issue index appended last) — invoke it so
|
||||
built from. The seeding issue is reachable via the project's issue
|
||||
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 judge "resolved vs picked" against what the sources actually say,
|
||||
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
|
||||
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
|
||||
refutation. If `show_cmd` is unset, you have only the body — a fork the
|
||||
body lists open is unresolved to you.
|
||||
refutation. If the project declares no issue show command, you have
|
||||
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
|
||||
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
|
||||
pin; your own recall does not pin). For `scope-fork`, this means
|
||||
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
|
||||
that carries provenance (see the standing reading list) — a
|
||||
provenance-less one does not count. For the others, read for the
|
||||
|
||||
+7
-6
@@ -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
|
||||
"trivial mechanical edits" carve-out.
|
||||
|
||||
This skill is an opt-in entry path. A project enables it by
|
||||
listing a `tdd` phase in its profile `pipeline:` block (see
|
||||
`docs/profile-schema.md`); a profile that omits it keeps
|
||||
`brainstorm → specify → planner` as the only design entry path.
|
||||
This skill is a standard entry path, always available — one of the
|
||||
three design entries alongside `brainstorm → specify → planner` and
|
||||
`specify → planner`. Which one a given iteration uses is a fit
|
||||
decision per item, not a project setting.
|
||||
|
||||
## 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
|
||||
RED→GREEN shape, but triggered by an observed bug rather than a
|
||||
new-behaviour description.
|
||||
- **Profile slot:** the opt-in `tdd` phase under `pipeline:` in
|
||||
`docs/profile-schema.md`.
|
||||
- **Pipeline:** `../docs/pipeline.md` — `tdd` is a standard,
|
||||
always-available entry path; the graph and skip rules are fixed
|
||||
(not per-project).
|
||||
|
||||
+16
-14
@@ -45,20 +45,21 @@ You exist to prevent two failure modes specifically:
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.tdd-author` in the project profile. The
|
||||
defaults include `CLAUDE.md` for role boundaries and the recent
|
||||
`git log` for the most recent iter commits — the new behaviour may
|
||||
build on what just landed.
|
||||
Always read `CLAUDE.md` (for role boundaries) and
|
||||
`git log -10 --format=full` — the most recent iter commits, as
|
||||
the new behaviour may build on what just landed — plus the
|
||||
per-role standing reading the project lists in its CLAUDE.md
|
||||
project facts for the tdd-author role.
|
||||
|
||||
If the project has a design ledger configured under
|
||||
`paths.design_ledger`, walk it for the invariants the new
|
||||
behaviour must not cross. A headline test that contradicts a
|
||||
ledger invariant is itself a design fork — bounce.
|
||||
If the project has a design ledger (its CLAUDE.md project
|
||||
facts), walk it for the invariants the new behaviour must not
|
||||
cross. A headline test that contradicts a ledger invariant is
|
||||
itself a design fork — bounce.
|
||||
|
||||
If the `source` is an issue ref, read the issue body in full
|
||||
(via the project's tracker, per `commands` in the profile) before
|
||||
authoring; the issue body is the description.
|
||||
(via the project's issue tracker — its CLAUDE.md project facts;
|
||||
always Gitea) before authoring; the issue body is the
|
||||
description.
|
||||
|
||||
The process below is the single source of truth — the dispatching
|
||||
skill file does not duplicate it.
|
||||
@@ -106,8 +107,8 @@ Each phase completes before the next starts.
|
||||
values, not "handles the case correctly".
|
||||
3. **Fork check.** Ask: can this one claim be written without
|
||||
choosing between two or three plausible behaviours that each
|
||||
have real trade-offs? Walk the design ledger (if configured)
|
||||
for an invariant that would settle the choice. If the choice
|
||||
have real trade-offs? Walk the design ledger (if the project
|
||||
has one) for an invariant that would settle the choice. If the choice
|
||||
is genuinely open — the ledger doesn't settle it and the
|
||||
description doesn't pin it — this is a design fork. Return
|
||||
`BLOCKED` with the fork stated as the design question. Do not
|
||||
@@ -240,7 +241,8 @@ At most 250 words, structured:
|
||||
`brainstorm`).
|
||||
- An edit to the headline test's assertion to make it pass — the
|
||||
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
|
||||
check and decompose mode's two-round limit surface the design
|
||||
question; the orchestrator decides the verdict.
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
# Copy these sections into your project's CLAUDE.md to import the
|
||||
# baseline rules the skills plugin assumes. Edit freely afterwards —
|
||||
# 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
|
||||
|
||||
@@ -86,3 +93,70 @@ Example shape:
|
||||
| Pair | Failure mode |
|
||||
|------|--------------|
|
||||
| `<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".
|
||||
|
||||
@@ -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 }
|
||||
Reference in New Issue
Block a user