feat: add spec_validation profile slot (fence -> parser registry)

Defines an optional top-level `spec_validation` profile section: a
registry mapping each markdown fence label to the tool that validates
a spec code block of that kind (`ext` + `cmd`, with a `{file}`
placeholder; exit 0 = clean parse, non-zero = BLOCK). Labels without an
entry are skipped-and-documented; a malformed entry fails closed.

This is P0 of issue #1 — the shared prerequisite for the brainstorm
Step-4 parse gate (Fix 1) and the grounding-check code-block pass
(Fix 2). Contract only; no consumer reads the slot yet.

refs #1

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 14:21:43 +02:00
parent 540741e6e9
commit 4a2c70baed
2 changed files with 50 additions and 0 deletions
+41
View File
@@ -51,6 +51,47 @@ take the next-higher number; deleted files retire their number.
| `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 brainstorm
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 |
+9
View File
@@ -28,6 +28,15 @@ commands:
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 # what a top-level work unit is called
subcycle: iteration # what a sub-unit is called