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:
+26
-20
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: specify
|
||||
description: Use when the design is already settled — a long in-context design discussion, an exhaustive tracker issue, or a ratified design handed over by brainstorm — and a spec must be produced from those sources with review but without an interview. The spec-production core: applies the feature-acceptance criterion, writes the spec under paths.spec_dir, runs the parse and grounding-check gates, takes user sign-off, hands off to planner. Bounces to brainstorm the moment the sources do not resolve a load-bearing design decision. Co-equal third entry path alongside brainstorm and tdd.
|
||||
description: Use when the design is already settled — a long in-context design discussion, an exhaustive tracker issue, or a ratified design handed over by brainstorm — and a spec must be produced from those sources with review but without an interview. The spec-production core: applies the feature-acceptance criterion, writes the spec under docs/specs, runs the parse and grounding-check gates, takes user sign-off, hands off to planner. Bounces to brainstorm the moment the sources do not resolve a load-bearing design decision. Co-equal third entry path alongside brainstorm and tdd.
|
||||
---
|
||||
|
||||
# specify — spec-production entry path
|
||||
@@ -33,9 +33,11 @@ RED from GREEN across two dispatches so the spec stays honest;
|
||||
`specify` splits deciding from producing so the producing phase reads
|
||||
the decision as a *source* rather than making it inline.
|
||||
|
||||
This skill is **not** opt-in. Unlike `tdd` (a profile-gated bypass),
|
||||
`specify` is a core pipeline node: it is the gate before `planner` on
|
||||
every design path that is not a bug fix or a test-specifiable feature.
|
||||
Where `tdd` is one entry path among three (chosen when behaviour is
|
||||
test-specifiable), `specify` sits on every prose-design path — it is
|
||||
not bypassed for those.
|
||||
|
||||
## When to Use / Skipping
|
||||
|
||||
@@ -52,8 +54,8 @@ Triggers:
|
||||
load-bearing decision. Use `brainstorm` (its discovery is what
|
||||
resolves the fork). `specify` itself bounces here the moment it
|
||||
detects this (see The Iron Law and Step 1.5).
|
||||
- A test-specifiable feature, on a profile that enables `tdd` — the
|
||||
RED executable-spec is the spec. Use `tdd` directly.
|
||||
- A test-specifiable feature — the RED executable-spec is the spec.
|
||||
Use `tdd` directly.
|
||||
- An observed bug — use `debug` directly (RED-first).
|
||||
- A tidy iteration — use `audit` directly.
|
||||
- A trivial mechanical edit — per the project's CLAUDE.md carve-out.
|
||||
@@ -96,7 +98,7 @@ Before producing anything, establish what the sources actually say:
|
||||
- **Chain entry** (from `brainstorm`): the ratified design narrative
|
||||
is already in-context. Re-ground lightly — fresh `git log`, the
|
||||
files the design touches — rather than re-deriving it.
|
||||
- If the project has a design ledger under `paths.design_ledger`,
|
||||
- If the project has a design ledger (its CLAUDE.md project facts),
|
||||
walk to the contracts the work touches. Note any `status:
|
||||
aspirational` source: its code is a target, not verified fact —
|
||||
track it for the Step-4 parse gate.
|
||||
@@ -199,16 +201,17 @@ honest* slice of the north-star program the infrastructure serves. "No
|
||||
surface so no code to show" is the rationalisation to refuse.
|
||||
|
||||
**Code lifted from an aspirational source is a hypothesis, not
|
||||
evidence.** If the concrete code here is lifted from a `design_models`
|
||||
evidence.** If the concrete code here is lifted from a design-models
|
||||
file (or any `status: aspirational` source, per Step 1), it carries no
|
||||
validation by default. Treat it as the spec's most suspect bytes: it
|
||||
must clear the Step-4 parse-every-block gate before PASS.
|
||||
|
||||
### Step 3 — Write the spec
|
||||
|
||||
Path: under `paths.spec_dir`, with a name per the project's
|
||||
`naming.policy` (see profile schema). Determine the next slot per the
|
||||
policy.
|
||||
Path: under `docs/specs`, named per the fixed naming convention —
|
||||
`NNNN-slug.md`, 4-digit per-directory counter (see
|
||||
`docs/conventions.md`). Determine the next free number by scanning the
|
||||
directory.
|
||||
|
||||
Structure:
|
||||
|
||||
@@ -256,10 +259,10 @@ Inline checklist (not a subagent dispatch):
|
||||
worked user-facing example for a surface cycle)? A load-bearing
|
||||
change described only in prose is a self-review failure to fix.
|
||||
6. **Parse-every-block gate.** Extract every fenced code block and run
|
||||
it through the `spec_validation` gate defined in
|
||||
`docs/profile-schema.md` (which owns the parser-invocation
|
||||
protocol, the no-parser skip, the malformed-entry failure, and the
|
||||
no-op when the profile declares no `spec_validation`). A parse
|
||||
it through the spec-validation parsers the project declares in its
|
||||
CLAUDE.md project facts (a fence label with no parser is a documented
|
||||
skip, never a silent pass; a malformed entry fails closed; the whole
|
||||
gate is a no-op when the project declares no parsers). A parse
|
||||
failure is a self-review failure — fix the spec; do not pass
|
||||
unparsed bytes downstream. Paste the parse-trace into the chat: a
|
||||
visible trace attests the gate fired; its absence means it was
|
||||
@@ -338,7 +341,8 @@ the commit itself.
|
||||
**In `/boss` (autonomous):** `specify` is dispatched autonomously —
|
||||
it is bounded (no interview). It runs the criterion, parse, and
|
||||
grounding-check gates without a checkpoint. What happens at *this*
|
||||
gate then depends on the profile slot `pipeline.boss.spec_auto_sign`:
|
||||
gate then depends on whether the project enables spec auto-sign (its
|
||||
CLAUDE.md project facts):
|
||||
|
||||
- **Slot absent or `false` (default):** `specify` **pauses here** as a
|
||||
problem-state notify ("spec X ready, please sign off") and waits for
|
||||
@@ -434,7 +438,7 @@ is invoked from `specify`. NO direct jump to `implement`.
|
||||
|
||||
Hand off carries:
|
||||
|
||||
- path to the spec under `paths.spec_dir`
|
||||
- path to the spec under `docs/specs`
|
||||
- iteration scope ("the first iteration covers section X+Y of the
|
||||
spec")
|
||||
|
||||
@@ -488,8 +492,9 @@ discipline `tdd` applies when behaviour is not test-specifiable.
|
||||
- "The sources are thorough, skip a gate" thoughts (any flavour)
|
||||
- A load-bearing change described in prose with no before → after code
|
||||
block; a surface cycle with no worked user-facing example
|
||||
- A spec carrying a code block whose fence label has a configured
|
||||
`spec_validation` parser, committed without a parse-trace in the chat
|
||||
- A spec carrying a code block whose fence label has a spec-validation
|
||||
parser (the project's CLAUDE.md project facts), committed without a
|
||||
parse-trace in the chat
|
||||
- Lifting code verbatim from a `status: aspirational` source without
|
||||
flagging it for the Step-4 parse gate
|
||||
- Editing the spec file after a Step 5 PASS without re-dispatching
|
||||
@@ -520,7 +525,8 @@ discipline `tdd` applies when behaviour is not test-specifiable.
|
||||
PASS / BLOCK / INFRA_ERROR.
|
||||
- **Agent dispatched (auto-sign only):** `agents/spec-skeptic.md` —
|
||||
dispatched in Step 6 five times in parallel (one per lens) ONLY under
|
||||
a `/boss` session with `pipeline.boss.spec_auto_sign` enabled. Each
|
||||
a `/boss` session with spec auto-sign enabled (the project's CLAUDE.md
|
||||
project facts). Each
|
||||
juror tries to refute the spec along its lens; a unanimous `SOUND` is
|
||||
what lets the orchestrator sign in the user's place. An editorial-lens
|
||||
`BLOCK` (`criterion` / `ambiguity` / `plan-readiness`) is self-
|
||||
@@ -529,7 +535,7 @@ discipline `tdd` applies when behaviour is not test-specifiable.
|
||||
an exhausted budget falls back to the human sign-off pause.
|
||||
- **Ad-hoc dispatch.** The orchestrator MAY also ad-hoc dispatch
|
||||
`../planner/agents/plan-recon.md` during Step 1 when the work enters
|
||||
code territory not recently read; opt-in, not part of the standard
|
||||
process.
|
||||
code territory not recently read; discretionary, not part of the
|
||||
standard process.
|
||||
- **Project feature-acceptance criterion:** declared in the project's
|
||||
`CLAUDE.md`. Applied prospectively in Step 2.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: grounding-check
|
||||
description: Read-only grounding-check reviewer for spec drafts. Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it; also validates the spec's own fenced code blocks against the project's configured parsers. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files.
|
||||
description: Read-only grounding-check reviewer for spec drafts. Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it; also validates the spec's own fenced code blocks against the spec-validation parsers the project declares in its CLAUDE.md project facts. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
@@ -28,16 +28,16 @@ right now, justify the assertions this spec rests on?"
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always`
|
||||
plus `standing_reading.by_role.grounding-check` in the
|
||||
project profile. The defaults include `CLAUDE.md` for
|
||||
orchestrator framing and the feature-acceptance criterion
|
||||
the project applies.
|
||||
The standing reading is `CLAUDE.md` plus
|
||||
`git log -10 --format=full`, then the per-role standing
|
||||
reading the project lists in its CLAUDE.md project facts.
|
||||
`CLAUDE.md` carries the orchestrator framing and the
|
||||
feature-acceptance criterion the project applies.
|
||||
|
||||
In addition, every dispatch:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if
|
||||
configured) plus the contracts its index links — the
|
||||
- The project's design ledger, if it has one (its CLAUDE.md
|
||||
project facts), plus the contracts its index links — the
|
||||
canonical contract ledger the new spec must compose with.
|
||||
- `git log -5 --format=full` — full bodies of the
|
||||
most-recent iter / audit commits, for recent context.
|
||||
@@ -46,9 +46,9 @@ In addition, every dispatch:
|
||||
- The spec file at the path the controller hands you (the
|
||||
spec under review).
|
||||
|
||||
You do NOT read files under `paths.plan_dir` (the plan does
|
||||
You do NOT read files under `docs/plans` (the plan does
|
||||
not yet exist). You do NOT read other specs from
|
||||
`paths.spec_dir` unless the spec under review explicitly
|
||||
`docs/specs` unless the spec under review explicitly
|
||||
references one — and if it does, you read the referenced
|
||||
section, not the whole spec.
|
||||
|
||||
@@ -109,8 +109,8 @@ decreasing order of strength:
|
||||
|
||||
1. A direct unit / integration test that exercises the
|
||||
mechanism by name.
|
||||
2. An end-to-end fixture (under the examples / fixtures
|
||||
directory configured in the project) that exercises the
|
||||
2. An end-to-end fixture (under the project's examples /
|
||||
fixtures directory) that exercises the
|
||||
mechanism indirectly but whose build / run output
|
||||
depends on it.
|
||||
3. A property-test or roundtrip test that pins the mechanism
|
||||
@@ -138,7 +138,7 @@ mechanism strongly.
|
||||
EXTRACT ASSUMPTIONS FROM THE SPEC, NOT FROM YOUR MEMORY.
|
||||
RATIFICATION REQUIRES A NAMED, CURRENTLY-GREEN TEST. NOT CODE PRESENCE. NOT RECALL.
|
||||
ONE UNRATIFIED LOAD-BEARING ASSUMPTION = BLOCK. NO PARTIAL CREDIT.
|
||||
ONE SPEC CODE BLOCK THAT FAILS ITS CONFIGURED PARSER = BLOCK.
|
||||
ONE SPEC CODE BLOCK THAT FAILS ITS PROJECT-DECLARED PARSER = BLOCK.
|
||||
YOU DO NOT EDIT FILES. YOU DO NOT PROPOSE FIXES.
|
||||
YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER RUNS ARE OK.)
|
||||
```
|
||||
@@ -156,9 +156,9 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER
|
||||
3. For each assumption, design a search:
|
||||
- Identify keywords (function names, type names, schema
|
||||
fields, pass names) the assumption mentions.
|
||||
- `grep` the test directories under `paths.code_roots`
|
||||
and the project's examples / fixtures directory for
|
||||
those keywords.
|
||||
- `grep` the test directories under the project's code
|
||||
roots (its CLAUDE.md project facts) and the project's
|
||||
examples / fixtures directory for those keywords.
|
||||
- Enumerate tests by name using the project's test-list
|
||||
command (e.g. `cargo test --list -p <crate>` for Rust;
|
||||
analogous for the project's test framework).
|
||||
@@ -167,27 +167,28 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, AND PER-BLOCK PARSER
|
||||
4. Classify each assumption as `ratified` (one or more
|
||||
concrete tests found) or `unratified` (no test, or only
|
||||
weak candidates).
|
||||
5. **Code-block parse pass.** If the project profile declares
|
||||
`spec_validation.parsers`, extract every fenced code block
|
||||
5. **Code-block parse pass.** If the project declares
|
||||
spec-validation parsers (its CLAUDE.md project facts),
|
||||
extract every fenced code block
|
||||
from the spec. For each block whose fence label has a
|
||||
`parsers` entry: write it to a temp file with the entry's
|
||||
`ext`, run the entry's `cmd` with `{file}` substituted, and
|
||||
declared parser: write it to a temp file with the parser's
|
||||
`ext`, run the parser's `cmd` with `{file}` substituted, and
|
||||
require exit 0. A non-zero exit marks the block unparseable.
|
||||
A block whose fence label has no entry is skipped and noted
|
||||
A block whose fence label has no parser is skipped and noted
|
||||
("no parser for fence label X"); never a silent pass. If the
|
||||
profile declares no `spec_validation`, this pass is a
|
||||
project declares no spec-validation parsers, this pass is a
|
||||
documented no-op. This pass is complementary to the
|
||||
assumption search: it checks the spec's own bytes against the
|
||||
live tool, not the codebase's behaviour — and it is
|
||||
independent of the orchestrator's own Step-7 parse gate, the
|
||||
fresh-context second line of the same defense.
|
||||
6. Compute aggregate status:
|
||||
- All assumptions ratified AND every configured-label block
|
||||
parsed clean → `PASS`.
|
||||
- All assumptions ratified AND every block whose fence label
|
||||
has a declared parser parsed clean → `PASS`.
|
||||
- One or more unratified assumptions, OR one or more
|
||||
unparseable code blocks → `BLOCK`.
|
||||
- Any infra error (cannot read spec, type-check fails,
|
||||
workspace does not build, a configured parser command is
|
||||
workspace does not build, a declared parser command is
|
||||
missing from PATH) → `INFRA_ERROR`.
|
||||
7. Emit the report in the format below.
|
||||
|
||||
@@ -265,7 +266,7 @@ the assumption-extraction step yields an empty list, emit
|
||||
| "I extracted too many assumptions, let me trim the report" | Don't trim. If a spec has too many assumptions to check, that is the finding — report it as BLOCK with reason "spec too broad". |
|
||||
| "The orchestrator will override if I block, so I'll lean toward PASS" | The override is the orchestrator's job, not yours. Your job is to be the fresh-context check. Skewing toward PASS defeats the whole role. |
|
||||
| "I'll run the full test suite to see which tests are actually green" | You may NOT run the full test suite. Use the project's test-list command to enumerate, then read test bodies. Running tests would mutate workspace state and is out of scope for a read-only review. |
|
||||
| "The code block is just illustrative, not a claim about behaviour" | A spec code block whose fence label has a configured parser is a hypothesis the downstream plan will lift verbatim. Illustrative or not, if it does not parse it is a defect. Run the parser and report the failure. |
|
||||
| "The code block is just illustrative, not a claim about behaviour" | A spec code block whose fence label has a project-declared parser is a hypothesis the downstream plan will lift verbatim. Illustrative or not, if it does not parse it is a defect. Run the parser and report the failure. |
|
||||
|
||||
## Red Flags — STOP
|
||||
|
||||
@@ -278,7 +279,7 @@ the assumption-extraction step yields an empty list, emit
|
||||
- About to mark an assumption ratified based on code
|
||||
presence rather than test presence
|
||||
- About to PASS a spec carrying a code block whose fence label
|
||||
has a configured parser without having run that parser
|
||||
has a project-declared parser without having run that parser
|
||||
- About to skip an assumption because "it would always be
|
||||
true"
|
||||
- Report exceeding ~500 tokens
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: spec-skeptic
|
||||
description: Read-only adversarial spec reviewer for the boss auto-sign panel. Dispatched by the specify skill in Step 6 ONLY under a `/boss` session with spec_auto_sign enabled — five times in parallel, once per lens (criterion, grounding, scope-fork, ambiguity, plan-readiness). Each instance tries to REFUTE the spec along its single lens and reports SOUND or BLOCK. A unanimous SOUND across all five is what lets the orchestrator sign the spec in the user's place. Does NOT propose fixes, does NOT edit files.
|
||||
description: Read-only adversarial spec reviewer for the boss auto-sign panel. Dispatched by the specify skill in Step 6 ONLY under a `/boss` session with spec auto-sign enabled (the project's CLAUDE.md project facts) — five times in parallel, once per lens (criterion, grounding, scope-fork, ambiguity, plan-readiness). Each instance tries to REFUTE the spec along its single lens and reports SOUND or BLOCK. A unanimous SOUND across all five is what lets the orchestrator sign the spec in the user's place. Does NOT propose fixes, does NOT edit files.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
@@ -12,7 +12,8 @@ tools: Read, Glob, Grep, Bash
|
||||
|
||||
A spec normally carries the user's signature: the human reads it
|
||||
and approves before any plan is built. Under a `/boss` session with
|
||||
`spec_auto_sign` enabled, the orchestrator may sign in the user's
|
||||
spec auto-sign enabled (the project's CLAUDE.md project facts), the
|
||||
orchestrator may sign in the user's
|
||||
place — but only if it is genuinely safe, and **model
|
||||
self-confidence is not a safety signal**. The orchestrator that
|
||||
wrote the spec is the worst-placed party to judge whether it is good;
|
||||
@@ -52,28 +53,31 @@ question — your task is to answer "yes, I can refute" (`BLOCK`) or
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.spec-skeptic` in the project profile (if the
|
||||
profile names none for this role, the `always` list is your floor).
|
||||
The defaults include `CLAUDE.md` for orchestrator framing and the
|
||||
The standing reading is `CLAUDE.md` plus
|
||||
`git log -10 --format=full`, then the per-role standing reading the
|
||||
project lists in its CLAUDE.md project facts (if the project names none
|
||||
for this role, the standing `CLAUDE.md` + git-log floor is yours).
|
||||
`CLAUDE.md` carries the orchestrator framing and the
|
||||
feature-acceptance criterion the project applies — the `criterion`
|
||||
lens leans on it directly.
|
||||
|
||||
In addition, every dispatch:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if configured)
|
||||
plus the contracts its index links — the canonical ledger the spec
|
||||
must compose with.
|
||||
- The project's design ledger, if it has one (its CLAUDE.md project
|
||||
facts), plus the contracts its index links — the canonical ledger
|
||||
the spec must compose with.
|
||||
- `git log -5 --format=full` — recent context.
|
||||
- The plugin's `../../README.md` — skill-system architecture and the
|
||||
standard agent structure.
|
||||
- The spec file at `spec_path` (the spec under review).
|
||||
- For the `grounding` lens additionally: the test directories under
|
||||
`paths.code_roots` and the project's examples / fixtures directory —
|
||||
the project's code roots (its CLAUDE.md project facts) and the
|
||||
project's examples / fixtures directory —
|
||||
you grep these to confirm or refute ratification.
|
||||
- For the `scope-fork` lens additionally: the sources the spec was
|
||||
built from. The seeding issue is reachable via the profile's
|
||||
`issue_tracker.show_cmd` (issue index appended last) — invoke it so
|
||||
built from. The seeding issue is reachable via the project's issue
|
||||
show command (its CLAUDE.md project facts) — it MUST render the issue
|
||||
WITH its comment thread (issue index appended last) — invoke it so
|
||||
you read the issue **with its comment thread**, not the body alone.
|
||||
You judge "resolved vs picked" against what the sources actually say,
|
||||
not against what reads plausibly. A fork the issue *body* still lists
|
||||
@@ -86,10 +90,10 @@ In addition, every dispatch:
|
||||
`decision: X` with no provenance is an orchestrator self-assertion
|
||||
dressed as settled, not a source: it does **not** resolve the fork, and
|
||||
a load-bearing decision whose only support is such a comment is a
|
||||
refutation. If `show_cmd` is unset, you have only the body — a fork the
|
||||
body lists open is unresolved to you.
|
||||
refutation. If the project declares no issue show command, you have
|
||||
only the body — a fork the body lists open is unresolved to you.
|
||||
|
||||
You do NOT read files under `paths.plan_dir` (the plan does not yet
|
||||
You do NOT read files under `docs/plans` (the plan does not yet
|
||||
exist). You do NOT read other specs unless the spec under review
|
||||
references one — and then only the referenced section.
|
||||
|
||||
@@ -129,7 +133,8 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, PER-BLOCK PARSER RUN
|
||||
`#[ignore]`/`xfail`/disabled does not pin; code presence does not
|
||||
pin; your own recall does not pin). For `scope-fork`, this means
|
||||
listing the load-bearing decisions and checking each against the
|
||||
sources read via `show_cmd` (issue **with comments**); a fork the
|
||||
sources read via the project's issue show command (issue **with
|
||||
comments**); a fork the
|
||||
issue body lists open is resolved only by a reconciliation comment
|
||||
that carries provenance (see the standing reading list) — a
|
||||
provenance-less one does not count. For the others, read for the
|
||||
|
||||
Reference in New Issue
Block a user