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

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

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

Delete docs/profile-schema.md and templates/project-profile.yml; add docs/conventions.md and a project-facts section to templates/CLAUDE.md.fragment; rewrite all SKILL/agent prose and the pipeline/design/migration/README/INSTALL docs accordingly.
This commit is contained in:
2026-06-13 16:30:02 +02:00
parent 268ee705f4
commit 26e9630496
40 changed files with 752 additions and 894 deletions
+20 -22
View File
@@ -26,32 +26,30 @@ To uninstall:
## Per-project activation
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
+42 -69
View File
@@ -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
View File
@@ -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
View File
@@ -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
+3 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+144
View File
@@ -0,0 +1,144 @@
# Conventions
The skills plugin used to read a per-project `dev-cycle-profile.yml`.
It no longer does. There was never a parser — the profile was prose
the skill bodies told the model to read, and almost every slot was
either dead, constant across all projects, or derivable. So the
plugin now splits cleanly in two:
- **Fixed conventions** (this file) — the things that were constant
across every project. They are not configurable; the skill and agent
bodies name them directly.
- **Per-project facts** — the handful of things that genuinely vary
per project (where the code lives, how to build and test it, the
tracker slug, …). These live as prose in each project's own
`CLAUDE.md` under a `## Skills plugin: project facts` heading. See
`../templates/CLAUDE.md.fragment` for the template, and the section
list at the bottom of this file.
## File layout
| Artefact | Location |
|----------|----------|
| Specs (from `specify`) | `docs/specs/` |
| Plans (from `planner`) | `docs/plans/` |
These directories are fixed. A project that keeps specs and plans
elsewhere is the rare exception and states the override in its
`CLAUDE.md` project facts.
## Naming
Counter-prefixed, per directory: `NNNN-slug.md`, 4-digit
zero-padded. The counter is per directory, assigned in creation
order, and stable for the life of the file. New files take the
next-higher number; deleted files retire their number (numbers are
not recycled). `brainstorm` / `specify` / `planner` scan the target
directory for the next free number before writing.
The slug separator is `-`.
## Vocabulary
The pipeline's nouns are fixed:
| Term | Meaning |
|------|---------|
| **cycle** | One round in the pipeline graph (`brainstorm → specify → planner → implement → audit → [fieldtest]`). NOT the top-level container. |
| **iteration** | A sub-unit of a cycle. |
| **milestone** | Tracker container spanning many cycles; closes only when complete AND functional (see `pipeline.md` § Milestone-close gate). |
| **contract** | A single design-ledger entry. |
When a project declares a glossary (in its CLAUDE.md project facts),
that glossary is the source of truth for domain nomenclature and
overrides these names where they collide (see `glossary-convention.md`).
## Standing reading
Every agent reads, at the start of every dispatch:
- the project's `CLAUDE.md`
- `git log -10 --format=full`
A project may add more — globally or per role — in its CLAUDE.md
project facts (`standing reading`). If the project declares a
glossary, that file is implicitly standing reading for every role
too.
## Git discipline
- **Only the orchestrator commits.** No skill agent runs `git commit`.
Agents write into the working tree as unstaged changes; the
orchestrator inspects, decides commit shape, and commits.
- **main HEAD is sacrosanct.** Nobody runs `git reset` / `git revert`
on main (or any other protected branch). main moves forward only via
orchestrator commits; a wrong agent diff is discarded with
`git checkout -- <paths>` / `git stash`, never by rewinding main.
These also appear in the universal-discipline fragment
(`../templates/CLAUDE.md.fragment`) that each project's CLAUDE.md
imports.
## Issue tracker
The tracker is **Gitea** and the commit close-marker is `closes #N`
(`refs #N` for non-closing work). The per-project repo slug and the
list/show commands live in the project's CLAUDE.md project facts
(see below) — the `boss` skill reads the forward queue from there,
and the `spec-skeptic` `scope-fork` juror reads single issues with
their comment threads from there.
## Pipeline
The phase set, the gates, and the conditional dispatch are **fixed**
and documented once in `pipeline.md`. There is no per-project pipeline
configuration. In particular: `brainstorm`, `specify`, `planner`,
`implement`, `audit`, `debug`, `tdd`, `fieldtest`, and `docwriter` are
always available. `tdd` is a standard entry path for test-specifiable
work — not an opt-in. `audit` is mandatory at cycle close.
`fieldtest` / `docwriter` are orchestrator-dispatched. The single
behavioural toggle is spec auto-sign under `/boss`, declared (when a
project wants it) in that project's CLAUDE.md project facts.
## Per-project facts (in each project's CLAUDE.md)
Under `## Skills plugin: project facts`, where applicable:
| Fact | Used by | Notes |
|------|---------|-------|
| **code roots** | architect, quality-reviewer, fieldtester | Directories reviewers walk. Required. |
| **build / test command** | implement, audit | Required. Exit 0 = success. |
| **lint command** | (quality) | Optional. |
| **doc-build command** | docwriter | Optional; prints warnings on stderr. |
| **regression scripts** | audit (bencher) | Optional list; non-zero exit = regress. |
| **architect sweeps** | audit (architect) | Optional list; non-zero exit = drift suspicion. |
| **spec-validation parsers** | specify, grounding-check | Optional; fence-label → `{ext, cmd}` table. `cmd` MUST contain `{file}`. Absent label → documented skip, never silent pass. |
| **design ledger** | architect, most agents | Optional path (e.g. `design/INDEX.md`). |
| **glossary** | every role | Optional path; implicitly standing reading. |
| **design contracts / models** | docwriter, specify | Optional dirs. Aspirational-source frontmatter marker recommended (see below). |
| **bench dir** | fieldtest, bencher | Optional path. |
| **public interface** | fieldtester | Optional list — the only surface the fieldtester may read; everything else (code roots, bench) is forbidden to it. |
| **fieldtest examples** | fieldtester | Optional path where fixtures are written. |
| **by-role standing reading** | named agent | Optional; extra files/commands a specific role reads. |
| **issue tracker** | boss, spec-skeptic | Repo slug + list command + show command (the latter MUST render an issue WITH its comments). |
| **spec auto-sign** | boss, specify | Optional; `enabled` lets `/boss` sign a spec in the user's place through the auto-sign gate (default: human signature). |
### Aspirational-source marker (recommendation)
Files under a project's design-models / RFCs / proposals directory
commonly carry aspirational code — constructs written before the
surface that parses them exists. To let a later `specify` tell
aspirational content from validated contract, give each such file a
frontmatter marker:
```yaml
---
status: aspirational
validated-against: <commit-sha | "no validation">
---
```
When the marker is absent the signal is simply absent — `specify`
degrades to treating the content as unmarked, never hard-failing.
Content lifted from an aspirational source is flagged and must clear
the parse-every-block gate before it ships in a spec.
+50 -43
View File
@@ -1,20 +1,28 @@
# Design
## 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 -10
View File
@@ -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
View File
@@ -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
View File
@@ -98,15 +98,16 @@ Hard-gate before plan — the spec-production core and the carrier of the
"no plan without an approved spec" invariant. Takes a settled design
(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`).
-290
View File
@@ -1,290 +0,0 @@
# Profile schema
Location: `<project-root>/.claude/dev-cycle-profile.yml`
Encoding: YAML. Each top-level key is a section. Keys are
lowercase snake_case. Lists are YAML sequences.
## `paths`
| Key | Type | Default | Description |
|---------------------|--------|------------------------|-------------|
| `spec_dir` | string | `docs/specs` | Where the specify skill writes specs. |
| `plan_dir` | string | `docs/plans` | Where the planner skill writes plans. |
| `glossary` | string | (unset) | Canonical-nomenclature file (optional). If set, it is standing reading for every role — no separate `standing_reading.always` entry is needed; unset is a documented no-op. See `glossary-convention.md`. |
| `design_ledger` | string | `docs/design/INDEX.md` | Canonical specification index (optional — projects without a design ledger can omit). |
| `design_contracts` | string | `design/contracts` | Directory of prose-authoritative contracts (optional). |
| `design_models` | string | `design/models` | Directory of onboarding whitepapers (optional). |
| `code_roots` | list | `[src]` | Code directories the architect / quality reviewer walk. |
| `bench_dir` | string | `bench` | Where regression harnesses live (optional). |
| `public_interface` | list | `[README.md, docs]` | Directories and files the `fieldtester` may read — the project's outward-facing surface (READMEs, design ledger, examples, public API docs). Everything else (especially `code_roots` and `bench_dir`) is forbidden to the fieldtester. |
| `fieldtest_examples`| string | `examples/fieldtest` | Where the `fieldtester` agent writes its fixtures. |
Omitted optional keys signal that the feature is unused in this
project; skills that depend on them either short-circuit or
skip the corresponding step.
### Aspirational-source marker (recommendation)
Files under `design_models` (or an equivalent `RFCs` /
`proposals` directory) commonly carry aspirational code —
constructs written before the surface that would parse them
exists. To let a later specify tell aspirational content from
validated contract, projects are encouraged (not required) to
give each such file a frontmatter marker:
```yaml
---
status: aspirational
validated-against: <commit-sha | "no validation">
---
```
`status: aspirational` says "the code here is a target, not a
verified fact"; `validated-against` records the last commit at
which someone actually ran the code through the live tool (or
`"no validation"`). A design ledger (`design_ledger`) is likewise
encouraged to distinguish "model" rows from "contract" rows so a
reading agent can mechanically tell which carry verified
behaviour.
When a file lacks the marker the signal is simply absent — the
specify skill degrades to treating its content as unmarked, never
hard-failing. The marker is consumed by the specify skill (see
its Step 1 and Step 4): content lifted from an aspirational source
is flagged and must clear the Step-4 parse-every-block gate before
it ships in a spec.
## `naming`
| Key | Type | Default | Description |
|--------------------|--------|----------------------------------|-------------|
| `counter_dirs` | list | `[docs/specs, docs/plans, design/contracts, design/models]` | Directories that use the counter-prefix policy. |
| `policy` | enum | `stable_per_directory_4digit` | One of `stable_per_directory_4digit`, `date_prefix`, `flat`. |
| `slug_separator` | string | `-` | Separator inside the slug. |
`stable_per_directory_4digit` means each listed directory has a
per-directory counter, 4-digit zero-padded, assigned in
creation order, stable for the life of the file. New files
take the next-higher number; deleted files retire their number.
`date_prefix` uses `YYYY-MM-DD-slug.md`.
`flat` uses `slug.md`.
## `commands`
| Key | Type | Default | Description |
|----------------|--------|----------------|-------------|
| `build` | string | (required) | Build command — exit 0 means success. |
| `test` | string | (required) | Test command — exit 0 means success. |
| `lint` | string | (optional) | Lint command — exit 0 means success. |
| `doc_build` | string | (optional) | Documentation-build command used by the `docwriter` skill. Should print warnings on stderr so the agent can enumerate them (e.g. `cargo doc --no-deps 2>&1`). Omit if the project has no API docs. |
| `regression` | list | `[]` | Regression scripts run by the audit skill. Each entry is a shell command; non-zero exit is a regress. |
| `architect_sweeps` | list | `[]` | Project-specific architect sweep commands run by the `architect` agent in addition to its universal checks. Each entry is a shell command; non-zero exit means at least one sweep matched and the matches are drift-suspicions to verify. Optional. |
## `spec_validation`
Optional. A registry mapping each markdown fence label to the tool
that validates a spec code block of that kind. The specify
parse-gate and the grounding-check code-block pass run these
parsers so that spec code blocks are treated as hypotheses to
verify, not as authoritative truth.
```yaml
spec_validation:
parsers:
ail:
ext: ".ail"
cmd: "ail parse {file}"
ail-json:
ext: ".ail.json"
cmd: "ail check {file}"
ll:
ext: ".ll"
cmd: "llvm-as {file} -o /dev/null"
```
The key of each `parsers` entry is the fence info-string of a spec
code block (the token immediately after the opening ` ``` `). Only
blocks whose label has an entry are validated; a block whose label
is absent from the map is skipped and the skip is documented ("no
parser for fence label X") — never a silent pass.
| Key | Type | Description |
|-------|--------|-------------|
| `ext` | string | Extension (including the leading dot) the harness gives the temp file it writes the block into, so tools that key off extension — `.ail` vs `.ail.json` — see the right one. |
| `cmd` | string | Validation command. MUST contain the `{file}` placeholder, which is substituted with the temp file's path. Exit 0 means a clean parse; any non-zero exit is a parse failure the consuming skill turns into a BLOCK. |
A malformed entry — `cmd` missing the `{file}` placeholder, or
either `ext` or `cmd` absent — is a profile error the consuming
skill surfaces, not a silent skip; the gate fails closed.
Omitting the whole `spec_validation` section disables the
block-validation gates: the consuming skills short-circuit, exactly
as with other omitted optional features.
## `vocabulary`
| Key | Type | Default | Description |
|----------------|--------|----------------|-------------|
| `cycle` | string | `cycle` | One round in the pipeline graph (NOT the top-level container). Examples: `cycle`, `release`, `epic`. |
| `subcycle` | string | `iteration` | A sub-unit of a cycle. Examples: `iteration`, `sprint`, `story`. |
| `milestone` | string | `milestone` | Tracker container spanning many cycles; closes only when complete AND functional (see `pipeline.md` § Milestone-close gate). Examples: `milestone`, `epic`, `release`. |
| `ledger_entry` | string | `contract` | What a single design-ledger entry is called. Examples: `contract`, `RFC`, `ADR`. |
Skills use these names in their generated artefacts and prose.
Picking accurate vocabulary keeps prose readable; the underlying
mechanics are identical regardless of name.
The renamings shown as examples above illustrate the slot only; they
are not nomenclature for any particular project. When a project sets
`paths.glossary`, that glossary is the source of truth for its
nomenclature and overrides these examples where they collide — a word
offered here may sit under **Avoid** in a given project's glossary
(see `glossary-convention.md`).
## `standing_reading`
| Key | Type | Default | Description |
|----------------|--------|----------------|-------------|
| `always` | list | `[CLAUDE.md]` | Files every agent reads at start of every dispatch. |
| `by_role` | map | `{}` | Map from role name to list of additional files. |
Role names match agent slugs: `architect`, `bencher`, `debugger`,
`implementer`, `tester`, `fieldtester`, `docwriter`,
`grounding-check`, `plan-recon`, `spec-reviewer`, `quality-reviewer`.
Entries may be shell commands as well as file paths — they are
read as opaque strings the agent should fetch / execute, e.g.
`"git log -10 --format=full"`.
A set `paths.glossary` is implicitly appended to every role's
`always` list — it does not need its own entry here. The slot's
authoritative semantics live at the `paths` row above.
## `git`
| Key | Type | Default | Description |
|------------------------------|------|---------|-------------|
| `main_sacrosanct` | bool | `true` | If true, no actor may reset or revert main. |
| `only_orchestrator_commits` | bool | `true` | If true, no agent commits; the orchestrator commits. |
| `issue_tracker.kind` | enum | `none` | One of `gitea`, `github`, `linear`, `none`. |
| `issue_tracker.close_marker` | string | `"closes #N"` | Marker the orchestrator includes in commit bodies to auto-close issues. |
| `issue_tracker.url` | string | (empty) | Human-browsable URL of the issue list — surfaced in notifications and cross-references. |
| `issue_tracker.list_cmd` | string | (empty) | Shell command that lists open issues. Used by the `boss` skill to read the forward queue. Examples: `tea issues ls --repo X/Y --state open`, `gh issue list --repo X/Y --state open`. |
| `issue_tracker.show_cmd` | string | (empty) | Shell command that renders **one** issue **with its comment thread**; the orchestrator and the `spec-skeptic` `scope-fork` juror append the issue index as the final argument (e.g. `tea issues --comments``tea issues --comments 55`). MUST include comments — a `specify` reconciliation comment (see `specify/SKILL.md` Step 1.5) is invisible to the juror otherwise. Examples: `tea issues --comments`, `gh issue view --comments`. If empty, the juror reads only the issue body and a fork resolved in-context but not echoed into the body cannot be ratified — auto-sign falls back to the human sign-off. |
| `protected_branches` | list | `[main]` | Branches that are sacrosanct in the same sense as main. |
## `notifications`
| Key | Type | Default | Description |
|-----------|--------|---------|-------------|
| `command` | string | (empty) | Shell command the `boss` skill invokes on done-state and bounce-back. Receives the message text as a single argument. Example: `"~/.claude/notify.sh"`. If empty, the orchestrator falls back to printing the notification in chat. |
## `pipeline`
Per-phase configuration. Each phase has its own sub-map.
```yaml
pipeline:
brainstorm: {} # optional discovery front-end; no hard gate of its own
specify:
gates: [planner] # core node — planner cannot start until the spec is approved
planner:
gates: [implement]
implement: {} # standard
audit:
mandatory_at: cycle_close # auto-fires at end of each cycle
fieldtest:
boss_only: true # only orchestrator dispatches
when: surface_touch # condition tag (orchestrator judgement)
milestone_fieldtest:
boss_only: true
when: surface_touch # end-to-end proof of the milestone's promise
gates_close: milestone # its green roll-up is the functional leg of the milestone-close gate
docwriter:
boss_only: true
when: api_stable_across_n_cycles
debug:
trigger: bug # observable misbehaviour
red_first: true # RED test before any fix
# specify above is a CORE node (always present); tdd below is opt-in.
tdd: # opt-in: omit the key to disable the entry path
trigger: test_specifiable_feature # behaviour expressible as one failing test
red_first: true # RED executable-spec before any implementation
alt_to: brainstorm # alternative design entry; bounces back on a design fork
boss:
user_invoked: true # autonomous-orchestrator mode, /boss
spec_auto_sign: false # opt-in: let /boss sign a spec in the user's place (default off)
```
Phases not listed are disabled for the project. A project that
does not want a `fieldtest` phase simply omits the key. `tdd` is
opt-in the same way.
`boss.spec_auto_sign` is an opt-in slot, default off (a missing key
reads as `false`). With it off — the conservative default — a
`specify` dispatch in a `/boss` session always pauses at its Step-6
user-review gate for the user's signature, exactly as before. With it
**on**, the orchestrator may sign a spec in the user's place, but only
through `specify`'s auto-sign gate: every objective gate green
(precondition, parse, a `grounding-check` `PASS` with no human
override) AND a unanimous five-lens `spec-skeptic` panel. A `BLOCK` is
never signed over: an *editorial* one (`criterion` / `ambiguity` /
`plan-readiness`) the orchestrator repairs in a bounded loop (≤ 2
rounds, re-running the objective gates and re-dispatching all five
lenses each round), while a *design* one (`scope-fork` / `grounding`),
an `INFRA_ERROR`, any objective gate not green, or an exhausted budget
falls back to the human sign-off pause. Model self-confidence alone
never signs — the gate is built specifically not to rely on it. On a
clean sign the
orchestrator commits the spec (subject carries `(boss-signed)`), sends
the mandatory informational-with-veto notify, and continues to
`planner` without stopping. See `../specify/SKILL.md` Step 6 (gate
owner), `../specify/agents/spec-skeptic.md` (the juror), and
`../boss/SKILL.md` §"Spec auto-sign" (notify + veto contract). `specify`, by contrast, is a **core** node — it
is the spec-production gate before `planner` on every design path,
reachable directly from settled sources or via the optional
`brainstorm` discovery stage. `tdd` opt-in only adds the
test-specifiable bypass; with `tdd` omitted, the design entry paths
are `brainstorm → specify → planner` and `specify → planner`.
## Example: minimal profile
```yaml
paths:
spec_dir: docs/specs
plan_dir: docs/plans
code_roots: [src]
commands:
build: cargo build
test: cargo test
vocabulary:
cycle: cycle
subcycle: iteration
standing_reading:
always:
- CLAUDE.md
- "git log -10 --format=full"
git:
issue_tracker:
kind: github
close_marker: "closes #N"
pipeline:
brainstorm: {} # optional discovery; no hard gate
specify: { gates: [planner] }
planner: { gates: [implement] }
implement: {}
audit: { mandatory_at: cycle_close }
debug: { trigger: bug, red_first: true }
```
This minimal profile enables five phases, no fieldtest, no
docwriter, no design-ledger. Good starting point for a small
project.
+3 -3
View File
@@ -23,9 +23,9 @@ never on a cycle clock.
Orchestrator-dispatched only. Audit closing **does not**
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
+21 -21
View File
@@ -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
View File
@@ -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.
+33 -29
View File
@@ -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
View File
@@ -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
+5 -4
View File
@@ -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
View File
@@ -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
+11 -10
View File
@@ -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) 12 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
+16 -15
View File
@@ -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
+9 -8
View File
@@ -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.
+9 -8
View File
@@ -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.
+10 -8
View File
@@ -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
View File
@@ -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
View File
@@ -88,8 +88,8 @@ artefact mirrored to Gitea ("would it be committed → English", per
`tea` is pre-authenticated via its own config (`~/.config/tea/`).
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
View File
@@ -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
+8 -8
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+28 -27
View File
@@ -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
+21 -16
View File
@@ -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
View File
@@ -71,10 +71,10 @@ prevent, and it is no less a failure for being dressed as a test.
- a trivial mechanical edit — per the project's CLAUDE.md
"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
View File
@@ -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.
+74
View File
@@ -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".
-85
View File
@@ -1,85 +0,0 @@
# Project profile for the skills plugin.
#
# Drop a copy of this file at <project-root>/.claude/dev-cycle-profile.yml
# and edit. See ~/dev/skills/docs/profile-schema.md for the full schema
# and per-key documentation.
paths:
spec_dir: docs/specs
plan_dir: docs/plans
# glossary: docs/glossary.md # optional — if set, read as
# standing reading by every role
# design_ledger: docs/design/INDEX.md # optional
# design_contracts: design/contracts # optional
# design_models: design/models # optional
code_roots: [src]
# bench_dir: bench # optional
# public_interface: [README.md, docs] # what fieldtester may read; everything else is forbidden
# fieldtest_examples: examples/fieldtest # where fieldtester writes fixtures
naming:
counter_dirs: [docs/specs, docs/plans, design/contracts, design/models]
policy: stable_per_directory_4digit # stable_per_directory_4digit | date_prefix | flat
slug_separator: "-"
commands:
build: "" # REQUIRED — e.g. "cargo build" or "npm run build"
test: "" # REQUIRED — e.g. "cargo test" or "npm test"
# lint: "" # optional
# doc_build: "" # e.g. "cargo doc --no-deps 2>&1" — used by docwriter
regression: [] # list of shell commands run by audit; non-zero exit = regress
architect_sweeps: [] # optional project-specific architect sweeps; non-zero exit = drift suspicion
# spec_validation: # optional — fence label -> validator for spec code blocks
# parsers: # key = fence info-string; labels with no entry are skipped + documented
# ail:
# ext: ".ail" # extension for the temp file the harness writes the block into
# cmd: "ail parse {file}" # {file} = temp-file path; exit 0 = clean parse, non-zero = BLOCK
# ail-json:
# ext: ".ail.json"
# cmd: "ail check {file}"
vocabulary:
cycle: cycle # one round in the pipeline graph (NOT the top-level container)
subcycle: iteration # a sub-unit of a cycle
milestone: milestone # tracker container spanning many cycles; closes only when complete AND functional
ledger_entry: contract # what one design-ledger entry is called
standing_reading:
always:
- CLAUDE.md
- "git log -10 --format=full"
by_role:
# architect: [design/contracts]
# debugger: ["git log -5 --format=full"]
git:
main_sacrosanct: true
only_orchestrator_commits: true
protected_branches: [main]
issue_tracker:
kind: none # gitea | github | linear | none
close_marker: "closes #N"
# url: "" # human-browsable issue list URL
# list_cmd: "" # e.g. "tea issues ls --repo X/Y --state open"
# show_cmd: "" # renders one issue WITH comments; index appended last.
# e.g. "tea issues --comments" -> "tea issues --comments 55"
notifications:
# command: "" # e.g. "~/.claude/notify.sh"; boss falls back to chat if empty
pipeline:
brainstorm: {} # optional discovery front-end; no hard gate of its own
specify: { gates: [planner] } # core node: spec-production gate before planner
planner: { gates: [implement] }
implement: {}
audit: { mandatory_at: cycle_close }
debug: { trigger: bug, red_first: true }
# tdd: { trigger: test_specifiable_feature, red_first: true, alt_to: brainstorm } # opt-in: executable-spec-first entry, alternative to brainstorm
# boss: { user_invoked: true } # autonomous orchestrator mode, /boss
# spec_auto_sign: false # opt-in: let /boss sign a spec in the user's place when all
# # objective gates are green AND a unanimous spec-skeptic panel
# # passes; default off (human signature mandatory). See profile-schema.md.
# fieldtest: { boss_only: true, when: surface_touch } # per-cycle usability test
# milestone_fieldtest: { boss_only: true, when: surface_touch, gates_close: milestone } # closing gate: end-to-end proof of the milestone's promise
# docwriter: { boss_only: true, when: api_stable_across_n_cycles }