11<!--
2- generated by /v:onboard from cited evidence on 2026-06-30 ; refresh with /v:onboard --refresh
2+ generated by /v:onboard from cited evidence on 2026-09-04 ; refresh with /v:onboard --refresh
33provenance: docs/superpowers/architecture/.onboard-manifest.json
44NOTE: generated. These are the conventions that differ from competent-developer defaults; each is
55cited to the evidence (a config, CI gate, or lint rule) it was derived from — not the model's prior.
@@ -12,41 +12,110 @@ Deltas from default practice that this repo actually enforces.
1212## Python: stdlib only
1313
1414- Write helper scripts in ** pure Python standard library** — no third-party runtime deps. The scope
15- gate is "Python 3.9-safe, stdlib only. Targets stock-macOS python3 3.9.6." (` scripts/compound-v-scope-check.py:98 ` )
16- - Ship a built-in ** ` --selftest ` ** that runs offline (builds throwaway git repos in ` $TMPDIR ` ). (` scripts/compound-v-scope-check.py:514-516 ` , ` scripts/compound-v-onboard.py:1185-1186 ` ) CI runs the
17- epic-state / epic-arbiter self-tests under a ** Python 3.9 floor** , then every other script's
18- ` --selftest ` on the same interpreter. (` .github/workflows/validate.yml:269-282 ` )
15+ gate is "Python 3.9-safe, stdlib only. Targets stock-macOS python3 3.9.6." (` scripts/compound-v-scope-check.py:141 ` );
16+ the ` /v:onboard ` toolkit says the same in its docstring. (` scripts/compound-v-onboard.py:1-2 ` )
17+ - Ship a built-in ** ` --selftest ` ** that runs offline (builds throwaway git repos in ` $TMPDIR ` ).
18+ (` scripts/compound-v-scope-check.py:626-683 ` , ` scripts/compound-v-onboard.py:1184-1186 ` )
19+ CI runs the epic-state / epic-arbiter self-tests first under a clean ** Python 3.9** to prove they
20+ stay dependency-free (` .github/workflows/validate.yml:285-289 ` ), then sweeps ** every** ` scripts/*.py `
21+ that mentions ` --selftest ` — discovery is dynamic, so a new script is picked up automatically.
22+ (` .github/workflows/validate.yml:298-312 ` )
1923- Reuse canonical shared constants instead of forking a second copy (e.g. secret-pattern families are
2024 imported from ` compound-v-memory.py ` , not redefined). (` scripts/compound-v-onboard.py:5-9 ` )
2125
26+ ## Tests live under ` tests/ ` , and the sweep must never match zero
27+
28+ - The selftest sweep globs ` scripts/*.py ` ** only** ; everything under ` tests/ ` is executed by a
29+ separate job. A test script parked in ` scripts/ ` is therefore a test CI never runs.
30+ (` .github/workflows/validate.yml:314-315 ` )
31+ - That job ** always runs** — no ` paths: ` filter and no ` if: ` guard, because GitHub reports a
32+ conditionally-skipped required check as ` Success ` — discovers ` .sh ` and ` .py ` recursively, and
33+ ** fails when it discovers nothing** : a guard that silently matches zero files is a false green.
34+ (` .github/workflows/validate.yml:317-374 ` )
35+
2236## Markdown frontmatter
2337
24- - Every skill (` skills/*/SKILL.md ` ) and agent (` agents/*.md ` ) needs ` name ` and ` description `
25- frontmatter; commands are exempt (name = filename). (` scripts/lint-frontmatter.py:110-115 ` )
38+ - Frontmatter is a ** path-class presence gate** : ` agents/*.md ` , ` commands/*.md ` and
39+ ` skills/*/SKILL.md ` must carry a block; every other ` .md ` is exempt. Required ` name ` and
40+ ` description ` (commands exempt from ` name ` — it is the filename). (` scripts/lint-frontmatter.py:8-20 ` )
2641- Keep ` description ` ≤ 500 chars (soft) and total frontmatter ≤ 1024 chars (hard). (` scripts/lint-frontmatter.py:33-34 ` )
27- - Quote any ` paths ` value containing glob chars (` {}[] ` ) — unquoted globs break YAML. (` scripts/lint-frontmatter.py:137-142 ` )
42+ - ` maxTurns ` , when present, must be a ** positive integer** — a string, float or negative is ignored by
43+ the runtime, so the agent runs uncapped while its file claims a cap. (` scripts/lint-frontmatter.py:161-170 ` )
44+ - Quote any ` paths ` value containing glob chars (` {}[] ` ) — unquoted globs break YAML.
45+ (` scripts/lint-frontmatter.py:172-177 ` )
2846
2947## Model policy — NEVER Haiku
3048
31- - ** Opus by default** , Sonnet only for the narrow junior-task carve-out; ** Haiku is forbidden.** The
32- frontmatter linter rejects any ` model: ` containing ` haiku ` (` scripts/lint-frontmatter.py:124-126 ` )
33- and additionally requires ` model: opus ` on every ` agents/*.md ` . (` scripts/lint-frontmatter.py:128-134 ` )
34- CI enforces the no-Haiku rule on agent files too. (` .github/workflows/validate.yml:92-97 ` )
35- - Execution-layer model values (` gpt-5.5 ` , etc.) are NEVER placed in any frontmatter — they live only
36- in the manifest/job_spec. (` skills/backend-launcher/SKILL.md:37 ` )
49+ - ** Opus by default.** The frontmatter linter rejects any ` model: ` containing ` haiku `
50+ (` scripts/lint-frontmatter.py:133-136 ` )
51+ and requires ` model: opus ` on every ` agents/*.md ` . (` scripts/lint-frontmatter.py:151-159 ` ) CI enforces
52+ the no-Haiku rule on agent files independently of the linter. (` .github/workflows/validate.yml:83-97 ` )
53+ - ** The one carve-out is named, not open.** ` code-archaeologist ` and ` doc-validator ` may carry
54+ ` model: sonnet ` because their work is scanning — reading a repository, resolving a library — and
55+ scanning is execution, not judgment. The allow-list is explicit and short on purpose.
56+ (` scripts/lint-frontmatter.py:36-44 ` )
57+ - ** Fable is never frontmatter.** It belongs to a business-critical * invocation* , set by the caller's
58+ ` model ` override; a static ` model: fable ` would spend the top model on every routine pre-flight.
59+ (` scripts/lint-frontmatter.py:147-150 ` )
60+ - Execution-layer model values (` gpt-5.6-sol ` , etc.) are NEVER placed in any frontmatter — they live
61+ only in the manifest/job_spec. (` skills/backend-launcher/SKILL.md:46 ` )
3762
3863## No fabricated metrics (anti-ruflo)
3964
4065- Do not print token-cost / savings numbers you cannot measure. CI greps ` scripts/ ` and ` docs/ ` for
41- fabricated-metric phrasing (e.g. "tokens saved", "cost savings: N") and fails the build on a hit. (` .github/workflows/validate.yml:156-179 ` )
66+ fabricated-metric phrasing (e.g. "tokens saved", "cost savings: N") and fails the build on a hit.
67+ (` .github/workflows/validate.yml:185-214 ` )
4268- No daemon, no MCP server, no external vector-DB service, no fabricated cost metrics — the anti-ruflo
43- charter. (` skills/compound-v/SKILL.md:44 ` )
69+ charter. (` skills/compound-v/SKILL.md:46 ` )
70+ - Measurement that is absent stays absent: a missing or unparseable usage source yields
71+ ` measured:false ` with null counts, never a substituted zero. (` scripts/compound-v-usage-extract.py:17-27 ` )
72+
73+ ## The test contract: a scope may never resolve to nothing
74+
75+ - ` test_scope: floor_only ` requires a non-empty ` floor_command ` , and ` test_scope: impacted ` requires a
76+ non-empty ` full_command ` — so no scope can resolve to running nothing. Overlapping ` impacted_map `
77+ ` when ` globs ** union** ; first-match-wins would silently drop declared coverage.
78+ (` skills/compound-v/execution-manifest.md:581-591 ` )
79+ - A job's own run-dir bookkeeping is excluded before glob matching, so writing ` state.json ` can neither
80+ match a ` when ` glob nor promote the job to the full suite as an "unmapped path".
81+ (` skills/compound-v/execution-manifest.md:593-599 ` )
82+ - ** Never write, anywhere, that the floor preserves pre-merge safety.** The floor is early feedback;
83+ the merge-blocking CI run is what restores the full-suite guarantee.
84+ (` skills/compound-v/execution-manifest.md:601-605 ` )
85+
86+ ## Shell scripts and hooks
87+
88+ - Hooks under ` hooks/*.sh ` must be executable, and ` shellcheck ` runs over ` hooks/*.sh ` ** and**
89+ ` scripts/compound-v-*.sh ` . (` .github/workflows/validate.yml:216-230 ` )
90+ - Every hook registration carries ` "shell": "bash" ` — the documented optional field — so these bash
91+ scripts are not handed to PowerShell on a Windows box with no Git Bash. (` hooks/hooks.json:2 ` )
92+ - A hook that can block the turn carries a ` || true ` suffix in its registration, because a syntax
93+ error is fatal before any in-script trap can run: the registration itself must neutralize it. (` hooks/hooks.json:3 ` )
94+ The ` PreToolUse ` lane guard deliberately does ** not** , because a non-zero ` PreToolUse ` exit is not a
95+ deny; copying the idiom there would be cargo-culting. (` hooks/hooks.json:4 ` )
96+
97+ ## YAML in manifests
98+
99+ - Write a multi-line job ` body ` as a ** block scalar** (` body: | ` ) — the shape every job in the shipped
100+ example uses, and the only one that keeps a paragraph's line breaks; a quoted flow scalar folds them
101+ into one line. (` examples/manifest.example.yaml:64-68 ` )
102+ - The ` body ` (or one of its ` description ` / ` prompt ` / ` spec ` aliases) is ** required** : a job with none
103+ of them is refused at emit, because a prompt carrying lanes and no instructions asks the worker to
104+ invent the task — and an invented task that stays inside its lane passes every gate here.
105+ (` skills/compound-v/execution-manifest.md:58 ` )
44106
45107## Doc placement
46108
47109- Generated/working docs live under ` docs/superpowers/** ` in a flat, predictable layout
48- (` recon/ ` , ` archaeology/ ` , ` expert/ ` , ` library-audit/ ` , ` execution/<run-id>/ ` , ` memory/ ` , ` specs/ ` , ` plans/ ` ). (` skills/compound-v/SKILL.md:197-225 ` )
49- - Onboarding output goes to ` docs/superpowers/architecture/* ` + root ` CONVENTIONS.md ` /` AGENTS.md ` /` CLAUDE.md ` . (` skills/compound-v/onboarding.md:9-13 ` )
110+ (` recon/ ` , ` archaeology/ ` , ` expert/ ` , ` library-audit/ ` , ` execution/<run-id>/ ` , ` memory/ ` , ` specs/ ` , ` plans/ ` ).
111+ (` skills/compound-v/SKILL.md:199-227 ` )
112+ - Onboarding output goes to ` docs/superpowers/architecture/* ` + root ` CONVENTIONS.md ` /` AGENTS.md ` /` CLAUDE.md ` .
113+ (` skills/compound-v/onboarding.md:9-13 ` )
114+ - Every committed run directory must carry a ** committed ` state.json ` ** ; CI fails on a manifest with
115+ no state beside it, and the historical gaps are allowlisted by id rather than back-filled, because a
116+ reconstructed audit trail is fabricated evidence, not a repair. (` .github/workflows/validate.yml:136-159 ` )
117+ - Every intra-repo markdown link must resolve; the dead-link scan runs ** last** in the job so
118+ cross-refs to files authored by later batches resolve at integration time. (` .github/workflows/validate.yml:232-274 ` )
50119
51120## cclint scope
52121
@@ -56,4 +125,15 @@ Deltas from default practice that this repo actually enforces.
56125
57126## Versioning
58127
59- - ` plugin.json ` and ` marketplace.json ` versions must match exactly; CI fails on drift. (` .github/workflows/validate.yml:43-52 ` )
128+ - ` plugin.json ` and ` marketplace.json ` versions must match exactly; CI fails on drift.
129+ (` .github/workflows/validate.yml:43-52 ` )
130+ - The top release heading in ` CHANGELOG.md ` must match ` plugin.json ` 's version — the guard parses the
131+ first ` ## [x.y.z] ` heading outside fenced code blocks. (` .github/workflows/validate.yml:54-81 ` )
132+
133+ ## Writing in the shared checkout during a run (not machine-enforced)
134+
135+ - While a ` direct ` -mode job is registered in a run's ` lane-map.json ` , treat the shared checkout as
136+ that job's lane: an out-of-lane write there lands in the job's git-derived changed set and BLOCKS
137+ it. The ` PreToolUse ` guard is only a floor — it fails open on anything it cannot resolve, including
138+ a write made by an interpreter one-liner, so nothing mechanical catches this one.
139+ (` skills/compound-v/state-machine.md:166 ` , ` hooks/lane-guard.sh:17-23 ` , ` hooks/lane-guard.sh:32-58 ` )
0 commit comments