@thebassclef/lite 1.1.1 → 1.2.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +23 -6
- package/dist/cli.js +23 -6
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.claude/bassclef-configs.jsonc +56 -0
- package/dist/lite/.claude/bassclef-orientation.md +120 -0
- package/dist/lite/.claude/hooks/adr-discipline-check.sh +132 -0
- package/dist/lite/.claude/hooks/atomic-pr-check.sh +169 -0
- package/dist/lite/.claude/hooks/auto-save-idle.sh +51 -0
- package/dist/lite/.claude/hooks/bassclef-sync.sh +51 -13
- package/dist/lite/.claude/hooks/bet-doc-gate.sh +283 -0
- package/dist/lite/.claude/hooks/bug-diagnosis.sh +64 -0
- package/dist/lite/.claude/hooks/destructive-command-guard.sh +136 -0
- package/dist/lite/.claude/hooks/file-rename-discipline-check.sh +147 -0
- package/dist/lite/.claude/hooks/hook-classifier-canary.sh +158 -0
- package/dist/lite/.claude/hooks/kiss-default-check.sh +129 -0
- package/dist/lite/.claude/hooks/multi-tenancy-check.sh +83 -0
- package/dist/lite/.claude/hooks/oo-ad-entry-point-check.sh +216 -0
- package/dist/lite/.claude/hooks/operator-private-path-check.sh +203 -0
- package/dist/lite/.claude/hooks/pattern-annotation-validate.sh +142 -0
- package/dist/lite/.claude/hooks/plain-english-steering.sh +15 -1
- package/dist/lite/.claude/hooks/post-write-trace.sh +66 -0
- package/dist/lite/.claude/hooks/pr-body-scrub-check.sh +446 -0
- package/dist/lite/.claude/hooks/pre-commit-identifier-leak-scrub.sh +137 -0
- package/dist/lite/.claude/hooks/pre-gh-pr-body-scrub.sh +192 -0
- package/dist/lite/.claude/hooks/pre-gh-pr-title-scrub.sh +172 -0
- package/dist/lite/.claude/hooks/role-entry-gate.sh +115 -0
- package/dist/lite/.claude/hooks/save-state.sh +268 -0
- package/dist/lite/.claude/hooks/session-reflection.d/08-settings-drift.sh +8 -1
- package/dist/lite/.claude/hooks/session-reflection.d/10-abrupt-stop-recovery.sh +52 -0
- package/dist/lite/.claude/hooks/session-reflection.d/55-orientation-gate.sh +40 -4
- package/dist/lite/.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh +12 -5
- package/dist/lite/.claude/hooks/session-reflection.d/81-hook-manifest-staleness.sh +18 -2
- package/dist/lite/.claude/hooks/session-reflection.d/91-npm-version-drift.sh +54 -0
- package/dist/lite/.claude/hooks/session-reflection.d/tests/10-abrupt-stop-recovery.test.sh +95 -0
- package/dist/lite/.claude/hooks/session-reflection.sh +62 -15
- package/dist/lite/.claude/hooks/tool-failure-diagnosis.sh +50 -0
- package/dist/lite/.claude/luminaries/andrej-karpathy.md +165 -0
- package/dist/lite/.claude/luminaries/dave-gray.md +155 -0
- package/dist/lite/.claude/luminaries/gary-klein.md +166 -0
- package/dist/lite/.claude/luminaries/kaoru-ishikawa.md +162 -0
- package/dist/lite/.claude/luminaries/lean-product-canvas.md +33 -0
- package/dist/lite/.claude/luminaries/luke-wroblewski.md +224 -0
- package/dist/lite/.claude/luminaries/ryan-singer.md +113 -0
- package/dist/lite/.claude/luminaries/steve-krug.md +168 -0
- package/dist/lite/.claude/luminaries/tony-ulwick.md +134 -0
- package/dist/lite/.claude/rules/arc-level-orientation-before-leaf.md +60 -0
- package/dist/lite/.claude/rules/architect-review-discipline.md +71 -0
- package/dist/lite/.claude/rules/auto-fix-criteria.md +126 -0
- package/dist/lite/.claude/rules/bassclef-hook-drift-blocker.md +144 -0
- package/dist/lite/.claude/rules/bassclef-models-discovery.md +107 -0
- package/dist/lite/.claude/rules/bassclef-workflow-parity.md +104 -0
- package/dist/lite/.claude/rules/cost-governance.md +154 -0
- package/dist/lite/.claude/rules/file-rename-discipline.md +95 -0
- package/dist/lite/.claude/rules/mechanism-fidelity.md +88 -0
- package/dist/lite/.claude/rules/prototype-production-coupling.md +125 -0
- package/dist/lite/.claude/rules/quick-fix-criteria.md +90 -0
- package/dist/lite/.claude/rules/session-artifacts.md +30 -0
- package/dist/lite/.claude/rules/sibling-smoke-after-substrate-change.md +107 -0
- package/dist/lite/.claude/rules/substrate-as-system.md +67 -0
- package/dist/lite/.claude/rules/usability.md +22 -0
- package/dist/lite/.claude/settings.json +20 -0
- package/dist/lite/.claude/skills/agent-research-spawn/SKILL.md +100 -0
- package/dist/lite/.claude/skills/architect-review/SKILL.md +201 -0
- package/dist/lite/.claude/skills/auto-fix/SKILL.md +297 -0
- package/dist/lite/.claude/skills/autonomous/SKILL.md +300 -0
- package/dist/lite/.claude/skills/bind-subdomain/SKILL.md +232 -0
- package/dist/lite/.claude/skills/canvas/SKILL.md +41 -0
- package/dist/lite/.claude/skills/deploy-prod/SKILL.md +106 -0
- package/dist/lite/.claude/skills/docs-sync/SKILL.md +188 -0
- package/dist/lite/.claude/skills/eisenhower/SKILL.md +273 -0
- package/dist/lite/.claude/skills/empathy-map/SKILL.md +168 -0
- package/dist/lite/.claude/skills/frontend-design/SKILL.md +53 -0
- package/dist/lite/.claude/skills/interview-me/SKILL.md +171 -0
- package/dist/lite/.claude/skills/journal-export/SKILL.md +293 -0
- package/dist/lite/.claude/skills/jtbd-tasks/SKILL.md +203 -0
- package/dist/lite/.claude/skills/objectory-decompose/SKILL.md +256 -0
- package/dist/lite/.claude/skills/pick-luminaries/SKILL.md +100 -0
- package/dist/lite/.claude/skills/pre-mortem/SKILL.md +180 -0
- package/dist/lite/.claude/skills/prototype-gallery/SKILL.md +264 -0
- package/dist/lite/.claude/skills/provision-deploy-host/SKILL.md +257 -0
- package/dist/lite/.claude/skills/quick-fix/SKILL.md +273 -0
- package/dist/lite/.claude/skills/release/SKILL.md +311 -0
- package/dist/lite/.claude/skills/release-notes/SKILL.md +202 -0
- package/dist/lite/.claude/skills/rfc/SKILL.md +222 -0
- package/dist/lite/.claude/skills/riff-prototypes/SKILL.md +637 -0
- package/dist/lite/.claude/skills/secrets-bootstrap/SKILL.md +209 -0
- package/dist/lite/.claude/skills/skill/SKILL.md +304 -0
- package/dist/lite/.claude/skills/smoke-test/SKILL.md +100 -0
- package/dist/lite/.claude/skills/state/SKILL.md +204 -0
- package/dist/lite/.claude/skills/substrate-check/SKILL.md +218 -0
- package/dist/lite/.claude/skills/synthetic-user/SKILL.md +381 -0
- package/dist/lite/.claude/skills/task-scenarios/SKILL.md +105 -0
- package/dist/lite/.claude/skills/tier-dependency-audit/SKILL.md +139 -0
- package/dist/lite/.claude/skills/ux-migration/SKILL.md +424 -0
- package/dist/lite/.claude/skills/value-prop-canvas/SKILL.md +297 -0
- package/dist/lite/README.md +5 -1
- package/dist/lite/gitignore +6 -0
- package/dist/lite/lib/bassclef-dir-resolver.sh +85 -0
- package/dist/lite/lib/clone-failure-classifier.sh +59 -0
- package/dist/lite/lib/fixture-builder.sh +190 -0
- package/dist/lite/lib/fresh-install-check.sh +49 -0
- package/dist/lite/lib/hook-heartbeat.sh +0 -1
- package/dist/lite/lib/mechanism-fidelity.sh +569 -0
- package/dist/lite/lib/npm-version-check.sh +112 -0
- package/dist/lite/lib/preview-state.sh +229 -0
- package/dist/lite/lib/session-rescue.sh +0 -1
- package/dist/lite/scripts/generate-lite-manifest.sh +145 -4
- package/dist/lite/scripts/lite-manifest-drift-check.sh +5 -1
- package/dist/lite/standards/architect-review-discipline.md +222 -0
- package/dist/lite/standards/bassclef-platform.md +249 -0
- package/dist/lite/standards/bassclef-test-repos.md +97 -0
- package/dist/lite/standards/bassclef-wiring-manifest.json +25 -1
- package/dist/lite/standards/cold-adopter-harness.md +205 -0
- package/dist/lite/standards/data-management.md +135 -0
- package/dist/lite/standards/frontend-stack/nextjs-prisma.md +124 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +27 -0
- package/dist/lite/standards/lite-manifest.json +1456 -14
- package/dist/lite/standards/mechanism-fidelity.md +205 -0
- package/dist/lite/standards/operator-private-discipline.md +200 -0
- package/dist/lite/standards/operator-to-public-flow.md +195 -0
- package/dist/lite/standards/prototype-gallery.md +251 -0
- package/dist/lite/standards/pseudonym-key-schema.md +109 -0
- package/dist/lite/standards/sibling-validation-checklist.md +181 -0
- package/dist/lite/standards/slack-notifications.md +161 -0
- package/dist/lite/standards/synthetic-user-testing.md +173 -0
- package/dist/lite/standards/vendor-bindings.md +165 -0
- package/dist/lite/standards/vendor-plugins/frontend-design.md +66 -0
- package/dist/lite/standards/vpc-fit-validation.md +167 -0
- package/dist/lite/templates/gallery-yml.md +113 -0
- package/dist/lite/templates/product-canvas.md +169 -0
- package/dist/lite/templates/value-prop-canvas.md +180 -0
- package/package.json +3 -3
- /package/dist/lite/{whereami.md → docs/whereami.md} +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: Every file rename in bassclef registers an entry in standards/file-renames.json AND ships a fixture test that asserts the migrate script cures adopters carrying the old name.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# File-rename discipline
|
|
7
|
+
|
|
8
|
+
Every file rename in bassclef registers an entry in `standards/file-renames.json` AND ships a fixture test that asserts the migrate script cures adopters carrying the old name. No exception. The pre-commit hook at `.claude/hooks/file-rename-discipline-check.sh` blocks commits that delete a file under the discipline's scope unless the rename is registered.
|
|
9
|
+
|
|
10
|
+
This rule exists because a file rename shipped on 2026-06-21 without a migration path that reached every adopter. POA's session on 2026-06-29 surfaced the gap — broken symlinks at the old name, settings.json hooks pointing at files that no longer existed in bassclef. The first rename map entry (shipped in WU-9 of this goal) documents the case:
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
{
|
|
14
|
+
"old_name": "canonical-source-config-validate.sh",
|
|
15
|
+
"new_name": "bassclef-source-config-validate.sh",
|
|
16
|
+
"renamed_at": "2026-06-21"
|
|
17
|
+
}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The cure shipped in bet 29e WU-9; this rule prevents the next rename from repeating the failure.
|
|
21
|
+
|
|
22
|
+
## When this rule fires
|
|
23
|
+
|
|
24
|
+
Any commit that deletes a file under any of these paths:
|
|
25
|
+
|
|
26
|
+
- `.claude/hooks/`
|
|
27
|
+
- `.claude/skills/`
|
|
28
|
+
- `.claude/rules/`
|
|
29
|
+
- `.claude/luminaries/`
|
|
30
|
+
- `.claude/agents/`
|
|
31
|
+
- `scripts/`
|
|
32
|
+
- `lib/`
|
|
33
|
+
- `standards/`
|
|
34
|
+
- `presence/`
|
|
35
|
+
- `architecture/decisions/` (ADR renames need migration too)
|
|
36
|
+
|
|
37
|
+
The hook scans the commit's deletions against the rename map's `old_name` column. If a deletion is in the map, the commit proceeds. If a deletion is missing from the map, the hook BLOCKs with a structured remediation message naming the three required moves.
|
|
38
|
+
|
|
39
|
+
## What the rule requires
|
|
40
|
+
|
|
41
|
+
When a file in the scoped paths is renamed (deleted at the old path + created at the new path, OR moved via `git mv`), the same commit MUST include:
|
|
42
|
+
|
|
43
|
+
1. **A new entry in `standards/file-renames.json`** under the `renames` array — pairs the old filename with the new one, the date the rename ships, and a category tag.
|
|
44
|
+
|
|
45
|
+
2. **A fixture test under `.claude/hooks/tests/fixtures/adopter-<YYYY-MM-DD>-rename/`** (one fixture per rename event). The fixture mirrors the adopter state that will exist after the rename ships — broken symlinks at the old name, settings.json references that need rewriting, working symlinks at the new name. The migrate script's test suite runs against the fixture; assertions pin the cure.
|
|
46
|
+
|
|
47
|
+
3. **An entry in the goal doc or chronicle** that names the rename + the migration path. Renames are deliberate filings; passing renames have no place under this rule.
|
|
48
|
+
|
|
49
|
+
INSTEAD of treating a rename as a quick cleanup: file the entry, ship the fixture, name the event in a chronicle. The discipline takes minutes; the compound cost of skipping it shows up across every adopter.
|
|
50
|
+
|
|
51
|
+
When a file is being deleted without a successor (decommissioned, retired), the same commit MUST include:
|
|
52
|
+
|
|
53
|
+
- `# BREAKING: <reason>` comment in the deletion's PR body, OR
|
|
54
|
+
- An entry in a separate `compat_shims_preserved` section of `standards/file-renames.json` explaining why the old name continues to work via a different mechanism
|
|
55
|
+
|
|
56
|
+
INSTEAD of a bare deletion: pair the deletion with either the breaking-change declaration or the compat-shim entry. The adopter sees the change explicitly; the substrate carries the migration cost.
|
|
57
|
+
|
|
58
|
+
## Compat-shim case
|
|
59
|
+
|
|
60
|
+
Some renames preserve the old name as a compat shim per ADR-031. The dispatcher's legacy filename is the documented example — it works via the two-stage rocket per ADR-032, so adopters with the old name continue to load substrate cleanly without rewriting their settings.json. The rename map's `compat_shims_preserved` section records the case:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
{
|
|
64
|
+
"old_name": "canonical-sync.sh",
|
|
65
|
+
"reason": "ADR-031 compat-shim discipline kept alive",
|
|
66
|
+
"added": "2026-06-29"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
For compat-shim renames, the rename map's `compat_shims_preserved` list documents the case. The pre-commit hook treats the old name as still-living; the new name + old name coexist for the documented deprecation window.
|
|
71
|
+
|
|
72
|
+
INSTEAD of removing the old name silently when a compat shim is in place: keep the old name alive, document the shim, set a deprecation window. The adopter migrates on their own cadence; bassclef carries the cost in the meantime.
|
|
73
|
+
|
|
74
|
+
## Override path
|
|
75
|
+
|
|
76
|
+
`SKIP_FILE_RENAME_DISCIPLINE=1 <command>` — bypass logged via trace-helper. Two genuine cases:
|
|
77
|
+
|
|
78
|
+
- Migrating bulk content where the rename map cannot capture every entry within the commit window (operator-approved exception)
|
|
79
|
+
- Emergency rescue where the hook itself misbehaves and blocks legitimate work (file substrate-defect)
|
|
80
|
+
|
|
81
|
+
INSTEAD of using the override as a regular practice: register the rename. The map entry takes seconds; the override exists for genuine edge cases.
|
|
82
|
+
|
|
83
|
+
## Composes with
|
|
84
|
+
|
|
85
|
+
- `standards/file-renames.json` — the single source of truth for renames; this rule cites it as authoritative
|
|
86
|
+
- `scripts/migrate-adopter-references.sh` — Surface 5 + Surface 6 read the map
|
|
87
|
+
- `.claude/hooks/file-rename-discipline-check.sh` — the mechanical layer (added in this step)
|
|
88
|
+
- `.claude/rules/we-dont-break-adopters.md` — sister discipline (ADR-031); this rule operationalizes the "every rename ships with a migration path" requirement
|
|
89
|
+
- `.claude/rules/testing-tier-config.md` — Tier 0 strict-TDD on the hook + tests
|
|
90
|
+
- `.claude/rules/blocked-items.md` — BLOCK protocol the hook fires
|
|
91
|
+
- `.claude/rules/bootstrap-pair-discipline.md` — sister discipline at the "every primitive ships with its paired bootstrap" surface; this rule extends to rename events specifically
|
|
92
|
+
- @luminary linus-torvalds — adopter contract; the kernel preserves userspace through every rename; bassclef preserves adopter contracts the same way
|
|
93
|
+
- @luminary michael-feathers — characterization tests pin the actual adopter state before the cure ships
|
|
94
|
+
- @luminary kent-beck — mechanical enforcement at the commit boundary
|
|
95
|
+
- @luminary hyrum-wright — every observable filename becomes a contract with enough adopters
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: "Every rule that names a mechanical enforcement makes a contract: the mechanism exists, is wired, resolves paths under both install classes, has a Tier 0 test pinning behavior."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mechanism Fidelity
|
|
7
|
+
|
|
8
|
+
Every rule that names a mechanical enforcement makes a contract: the mechanism exists, is wired, resolves paths under both install classes, has a Tier 0 test pinning behavior. The mechanism-fidelity discipline verifies this contract end-to-end. Audit skill + harness check classes + (proposed) per-edit hook + this auto-loaded rule together form a 4-layer defense.
|
|
9
|
+
|
|
10
|
+
This rule is the methodology layer. The mechanical layers are `/audit-rule-mechanism-fidelity` skill (operator-invocable) + cold-adopter harness Shape d (per-PR) + bassclef-upstream#433 per-edit hook (proposed for cure bet). All 3 mechanical layers compose `lib/mechanism-fidelity.sh` — the shared deep module.
|
|
11
|
+
|
|
12
|
+
## When this rule fires
|
|
13
|
+
|
|
14
|
+
Every session. Auto-loaded via `additionalDirectories`. Cross-references the substrate-as-system tenet rule + cites the 4 verification layers.
|
|
15
|
+
|
|
16
|
+
The mechanical layers fire at:
|
|
17
|
+
- Per-edit: `bassclef-upstream#433` proposed hook (PreToolUse `Edit|Write` on `.claude/rules/*.md`) — V1 ADVISORY in cure bet
|
|
18
|
+
- Per-PR: cold-adopter harness Shape d 4 check classes (V1 ADVISORY in bet 27c WU-5)
|
|
19
|
+
- Per-architect-review: audit skill auto-fired (bet 27c WU-9.5 SKILL amendment)
|
|
20
|
+
- Per-operator-demand: audit skill operator-invocable (bet 27c WU-4)
|
|
21
|
+
|
|
22
|
+
## What this rule requires
|
|
23
|
+
|
|
24
|
+
For any rule body that names a mechanical enforcement:
|
|
25
|
+
|
|
26
|
+
1. **Cite the hook by filename** — `.claude/hooks/<name>.sh` reference in rule body
|
|
27
|
+
2. **Cite the wiring** — note that the hook is wired in `.claude/settings.json` (or operator settings under user install class)
|
|
28
|
+
3. **Cite the test** — note that Tier 0 test exists at `.claude/hooks/tests/<name>.test.sh` per `.claude/rules/testing-tier-config.md`
|
|
29
|
+
4. **Cite the install-class declaration** — note that the hook declares `# install-class: dual` (or operator/project as appropriate) per `standards/hook-install-class.md`
|
|
30
|
+
5. **Verify before commit** — at least one of the 4 mechanical layers MUST have run on the rule change (at minimum, `bash scripts/cold-adopter-harness-sync.sh --mode sync --target .` Shape d before push)
|
|
31
|
+
|
|
32
|
+
## Classification labels (per `standards/mechanism-fidelity.md`)
|
|
33
|
+
|
|
34
|
+
`lib/mechanism-fidelity.sh` `classify_finding` returns one of 10 labels for each rule claim:
|
|
35
|
+
|
|
36
|
+
| Label | Meaning | Cure |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `CLEAN` | exists + wired + path-ok + test present | no action |
|
|
39
|
+
| `DEAD-LETTER` | hook exists but not wired in settings.json | wire in settings.json (per `.claude/rules/hook-wire-on-author.md`) |
|
|
40
|
+
| `UNWIRED` | claimed hook does not exist anywhere | author the hook OR remove the rule's claim OR reword to methodology-only |
|
|
41
|
+
| `PATH-BROKEN` | hook uses SCRIPT_DIR/../../<project-resource> + declares install-class: operator | refactor to `install-class: dual` + source `lib/hook-inject.sh` (kiss cure PR #427 pattern) |
|
|
42
|
+
| `TEST-MISSING` | hook exists + wired + path-ok but no Tier 0 test | author Tier 0 test per `.claude/rules/test-sufficiency.md` |
|
|
43
|
+
| `METHODOLOGY-ONLY` | rule names no mechanism (intentional self-discipline) | no action; rule loads as steering only |
|
|
44
|
+
| `SILENT-PASS` | hook fires but exits 0 without enforcing (runtime-only finding) | surface via smoke step 5; cure per defect class |
|
|
45
|
+
| `NOT-WIRED-BY-DESIGN-CI` | hook lives on disk; referenced from `.github/workflows/*.yml`; settings.json is not the right home | no action — workflow IS the wiring (bet 29a WU-1) |
|
|
46
|
+
| `NOT-WIRED-BY-DESIGN-LAUNCHD` | hook is scheduled by macOS launchd or cron; header comment names the scheduler; settings.json is not the right home | no action — scheduler IS the wiring (bet 29a WU-1) |
|
|
47
|
+
| `NOT-WIRED-BY-DESIGN-LIB` | file is sourced by other hooks (library role); settings.json is not the right home | no action — sourcing IS the use pattern (bet 29a WU-1) |
|
|
48
|
+
|
|
49
|
+
## Anti-patterns
|
|
50
|
+
|
|
51
|
+
These shapes fail this rule.
|
|
52
|
+
|
|
53
|
+
**Rule cites a non-existent hook.** UNWIRED classification. Cure: author the hook OR remove the claim.
|
|
54
|
+
|
|
55
|
+
**Rule cites a hook that exists but is not in settings.json.** DEAD-LETTER classification. Cure: add the settings.json entry (per `.claude/rules/hook-wire-on-author.md`).
|
|
56
|
+
|
|
57
|
+
**Rule cites a hook that exists + is wired but uses SCRIPT_DIR/../../ pattern + declares install-class: operator.** PATH-BROKEN classification. Cure: refactor via `lib/hook-inject.sh` resolve_* helpers; declare `install-class: dual` (kiss cure PR #427 is the exemplar).
|
|
58
|
+
|
|
59
|
+
**Rule cites a hook that has no Tier 0 test.** TEST-MISSING classification. Cure: author the test per `.claude/rules/test-sufficiency.md` criterion 11 (path-resolution under both install classes).
|
|
60
|
+
|
|
61
|
+
**Rule body has no Sources read block citing the parent_goal path.** Different defect class (handled by `.claude/hooks/artifact-ingestion-gate.sh`); orthogonal but related.
|
|
62
|
+
|
|
63
|
+
## Composes with
|
|
64
|
+
|
|
65
|
+
- `.claude/rules/substrate-as-system.md` — sister tenet rule (per ADR-035 substrate-as-system tenet)
|
|
66
|
+
- `.claude/rules/bootstrap-pair-discipline.md` — instance 2 of the pair table covers rule + cited hook
|
|
67
|
+
- `.claude/rules/hook-wire-on-author.md` — settings.json wiring discipline (cure path for DEAD-LETTER findings)
|
|
68
|
+
- `.claude/rules/testing-tier-config.md` — Tier 0 strict-TDD on substrate paths (cure for TEST-MISSING)
|
|
69
|
+
- `.claude/rules/test-sufficiency.md` criterion 11 (added bet 27c WU-9) — path-resolution under both install classes
|
|
70
|
+
- `.claude/rules/cold-adopter-harness-discipline.md` — sister per-PR enforcement (lists Shape d check classes from WU-5)
|
|
71
|
+
- ADR-035 — substrate-as-system tenet + 9-surface hook taxonomy
|
|
72
|
+
- `standards/mechanism-fidelity.md` (bet 27c WU-2; extended bet 29a WU-1) — full reference; 10 classification labels; 5-step verification chain
|
|
73
|
+
- `standards/hook-install-class.md` (bet 27c WU-2) — install-class declarations
|
|
74
|
+
- `lib/mechanism-fidelity.sh` (bet 27c WU-3) — shared deep module for verification chain
|
|
75
|
+
- `lib/hook-inject.sh` (bet 27c WU-3) — path-resolution lib (cure for PATH-BROKEN)
|
|
76
|
+
- `.claude/skills/audit-rule-mechanism-fidelity/SKILL.md` (bet 27c WU-4) — operator-invocable audit
|
|
77
|
+
- `scripts/cold-adopter-harness-sync.sh` Shape d (bet 27c WU-5) — per-PR gate
|
|
78
|
+
- bassclef-upstream#433 — proposed per-edit enforcement hook (4th layer in defense stack)
|
|
79
|
+
- @luminary saltzer-schroeder — complete mediation (every previously-blind path closed)
|
|
80
|
+
- @luminary michael-feathers — characterization tests as cure (code without tests is legacy code by definition)
|
|
81
|
+
- @luminary tony-hoare — pre/postcondition contracts (rule body claims become observable contracts)
|
|
82
|
+
- @luminary john-ousterhout — deep modules (one impl, many consumers)
|
|
83
|
+
|
|
84
|
+
## Override
|
|
85
|
+
|
|
86
|
+
`SKIP_MECHANISM_FIDELITY=1 <command>` — for genuine one-shot scripts that intentionally skip verification. Logged via trace-helper.
|
|
87
|
+
|
|
88
|
+
INSTEAD of overriding for routine rule edits: run `bash scripts/cold-adopter-harness-sync.sh --mode sync --target .` Shape d before push. Catches V1 ADVISORY findings; cures defer to Bet C-pre-2.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: Design prototypes are load-bearing artifacts, not sketches.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Prototype–Production Coupling
|
|
7
|
+
|
|
8
|
+
Design prototypes are load-bearing artifacts, not sketches. Once a prototype
|
|
9
|
+
is approved and merged to `docs/prototypes/`, it becomes the reference the
|
|
10
|
+
production UI is measured against — and the gate that keeps backend
|
|
11
|
+
plumbing from outrunning its consuming surface.
|
|
12
|
+
|
|
13
|
+
Four obligations, all MUST:
|
|
14
|
+
|
|
15
|
+
## 1. Tokens extracted from prototype precede Construction
|
|
16
|
+
|
|
17
|
+
Design tokens (colors, spacing, typography, motion) extracted from the
|
|
18
|
+
approved prototype MUST land in `design/tokens/` (or equivalent
|
|
19
|
+
repo-level location) BEFORE any Construction branch builds the production
|
|
20
|
+
UI for that surface.
|
|
21
|
+
|
|
22
|
+
**Why**: building the production surface against ad-hoc values and then
|
|
23
|
+
"reconciling with tokens later" produces drift that visual review
|
|
24
|
+
catches after the fact, forcing rework. Tokens-first means production
|
|
25
|
+
inherits the prototype's visual contract from the first commit.
|
|
26
|
+
|
|
27
|
+
**How to apply**: when `/riff-prototypes` selects a direction and
|
|
28
|
+
the operator approves a variant, the next skill in the chain is token
|
|
29
|
+
extraction, not feature work. `/ux-migration` or `/frontend-design`
|
|
30
|
+
reads tokens from `design/tokens/`, not from the prototype HTML.
|
|
31
|
+
|
|
32
|
+
Closes #527 (POA).
|
|
33
|
+
|
|
34
|
+
## 2. Coupled-PR rule — backend doesn't ship without consuming surface
|
|
35
|
+
|
|
36
|
+
A backend PR that exposes or modifies a user-visible surface MUST NOT
|
|
37
|
+
merge to main until the consuming surface has **at least a merged
|
|
38
|
+
prototype** in `docs/prototypes/`. The prototype may be static, behind
|
|
39
|
+
a flag, or mock-data-driven — but it MUST be merged and discoverable.
|
|
40
|
+
|
|
41
|
+
**Why**: backend plumbing merged before the UX surface exists creates
|
|
42
|
+
orphaned work. Sequencing pressure moves to whatever's next, the
|
|
43
|
+
consuming UI ages, and the surface stays unchanged until someone
|
|
44
|
+
notices. Two POA sessions in April 2026 shipped this exact failure.
|
|
45
|
+
|
|
46
|
+
**How to apply**:
|
|
47
|
+
- "Consuming surface" = any API route, data model change, or schema
|
|
48
|
+
migration whose values land in a UI a user sees.
|
|
49
|
+
- Internal-only / operator-facing / tooling changes are exempt but
|
|
50
|
+
MUST be labeled as such in the PR description.
|
|
51
|
+
- Iteration proposals that sequence backend-before-UX MUST declare
|
|
52
|
+
the prototype commitment explicitly. A plumbing-first proposal
|
|
53
|
+
without a prototype-first predecessor is incomplete scope.
|
|
54
|
+
- Reviewer checklist item: "consuming UX has merged prototype" —
|
|
55
|
+
not self-reported, evidence required (link to prototype file).
|
|
56
|
+
|
|
57
|
+
Closes #114 (bassclef).
|
|
58
|
+
|
|
59
|
+
## 3. Visual-review-per-UI-PR is a MUST gate
|
|
60
|
+
|
|
61
|
+
Any PR that modifies production UI MUST run `/visual-review` before
|
|
62
|
+
merge. The review compares rendered output against design tokens,
|
|
63
|
+
usability standard, and luminary guidance.
|
|
64
|
+
|
|
65
|
+
**Why**: code review catches logic drift. Only visual review catches
|
|
66
|
+
visual drift. A UI PR that passes CI but hasn't been rendered and
|
|
67
|
+
inspected is unverified on the dimension that matters most for users.
|
|
68
|
+
|
|
69
|
+
**How to apply**:
|
|
70
|
+
- `/visual-review` output (screenshots + findings) attached to the PR
|
|
71
|
+
before merge approval
|
|
72
|
+
- Failure modes from visual review (token violations, usability gaps,
|
|
73
|
+
luminary mismatch) block merge the same way a failing test does
|
|
74
|
+
- Exempt: non-visual UI changes (data-only refactors, type changes,
|
|
75
|
+
pure accessibility labels). Must be declared in PR.
|
|
76
|
+
|
|
77
|
+
Closes #528 (POA).
|
|
78
|
+
|
|
79
|
+
## 4. Prototype-to-production drift test on each UI PR
|
|
80
|
+
|
|
81
|
+
`/visual-review` MUST include a step that diffs the rendered production
|
|
82
|
+
surface against the approved prototype for that surface. Structural
|
|
83
|
+
divergence (layout, hierarchy, affordances) from the prototype is a
|
|
84
|
+
finding, not an acceptable variance.
|
|
85
|
+
|
|
86
|
+
**Why**: prototypes encode design decisions that survive translation
|
|
87
|
+
into tokens + components. Production drift from prototype is either
|
|
88
|
+
(a) a bug in the build, or (b) an undocumented design change. Both
|
|
89
|
+
require surfacing, not silent acceptance.
|
|
90
|
+
|
|
91
|
+
**How to apply**:
|
|
92
|
+
- `/visual-review` procedure includes: "locate the approved prototype
|
|
93
|
+
referenced by the iteration goal or canvas; render both; diff
|
|
94
|
+
structurally"
|
|
95
|
+
- Acceptable variances: responsive adaptation, real-data density
|
|
96
|
+
shifts, performance-driven simplifications — all MUST be called out
|
|
97
|
+
in the review with rationale
|
|
98
|
+
- Unacceptable: layout restructure, affordance changes, hierarchy
|
|
99
|
+
inversions, token substitutions not documented in an ADR
|
|
100
|
+
|
|
101
|
+
Closes #575 (POA).
|
|
102
|
+
|
|
103
|
+
## Relationship to other rules
|
|
104
|
+
|
|
105
|
+
- `prototype-workflow.md` — protects operator approval of prototype
|
|
106
|
+
BEFORE commit; this rule enforces what happens AFTER approval
|
|
107
|
+
- `design-direction.md` — approvals are load-bearing; this rule
|
|
108
|
+
operationalizes "load-bearing" into four specific gates
|
|
109
|
+
- `usability.md` #7 — visual verification; #3 here is the stronger
|
|
110
|
+
MUST formulation
|
|
111
|
+
- `sdlc-gates.md` post-build — `/verify` on UI change runs
|
|
112
|
+
`/visual-review`; this rule defines what `/visual-review` must check
|
|
113
|
+
|
|
114
|
+
## Enforcement
|
|
115
|
+
|
|
116
|
+
- **#1 (tokens-first)**: methodology-level; `/ux-migration` and
|
|
117
|
+
`/frontend-design` SKILL.md reference `design/tokens/` as
|
|
118
|
+
prerequisite input
|
|
119
|
+
- **#2 (coupled-PR)**: reviewer checklist + pre-merge hook (future)
|
|
120
|
+
that checks whether PR touches user-surfacing paths and greps
|
|
121
|
+
`docs/prototypes/` for a matching merged prototype
|
|
122
|
+
- **#3 (visual-review MUST)**: `/verify` skill matches UI change type
|
|
123
|
+
to `/visual-review`; blocks commit without review artifact
|
|
124
|
+
- **#4 (drift test)**: `/visual-review` SKILL.md procedure includes
|
|
125
|
+
prototype-diff step
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: /quick-fix is the compressed fix workflow for trivial bugs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Quick-Fix Entry Criteria
|
|
7
|
+
|
|
8
|
+
`/quick-fix` is the compressed fix workflow for trivial bugs. Entry is
|
|
9
|
+
gated by STRICT criteria — all five must hold. This rule codifies them
|
|
10
|
+
so agents can't soften "mostly obvious" into "obvious."
|
|
11
|
+
|
|
12
|
+
## Criteria (ALL must hold)
|
|
13
|
+
|
|
14
|
+
1. **Localized** — defect lives in a single file (or two for rename /
|
|
15
|
+
type propagation). Cross-cutting concerns disqualify.
|
|
16
|
+
2. **Obvious cause** — root cause expressible in one sentence without
|
|
17
|
+
reading logs or drawing resolution chains.
|
|
18
|
+
3. **Obvious fix** — ≤10 lines of change, no new interfaces, no new
|
|
19
|
+
abstractions, no schema changes.
|
|
20
|
+
4. **Low blast radius** — NOT auth, NOT middleware, NOT schema, NOT
|
|
21
|
+
security, NOT tenant boundary. Any of those = full /diagnose.
|
|
22
|
+
5. **Reproducible OR trivially verifiable** — Step 0 repro is either
|
|
23
|
+
explicitly skippable (typo / env var / off-by-one) or one-line.
|
|
24
|
+
|
|
25
|
+
Any failure → escalate to /diagnose (full) or /auto-fix.
|
|
26
|
+
|
|
27
|
+
## Why strict
|
|
28
|
+
|
|
29
|
+
Observed across prior sessions: agents rationalize "mostly localized"
|
|
30
|
+
and "mostly obvious" into /quick-fix eligibility. Soft criteria collapse
|
|
31
|
+
into default. Hard five-out-of-five discipline is the only shape that
|
|
32
|
+
holds.
|
|
33
|
+
|
|
34
|
+
## Audit discipline
|
|
35
|
+
|
|
36
|
+
Every /quick-fix commit carries `[quick-fix]` footer. Monthly ratio:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
FIX_COUNT=$(git log --all --oneline --since='30 days ago' --grep='^fix:' | wc -l)
|
|
40
|
+
QF_COUNT=$(git log --all --oneline --since='30 days ago' --grep='\[quick-fix\]' | wc -l)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Target: ≤30% of fix branches use /quick-fix. Higher ratio = criteria
|
|
44
|
+
too loose OR defect mix over-represents trivial. Either shape is
|
|
45
|
+
actionable; silent drift is not.
|
|
46
|
+
|
|
47
|
+
## Blast-radius floor (hard)
|
|
48
|
+
|
|
49
|
+
These paths ALWAYS require full /diagnose regardless of other criteria:
|
|
50
|
+
|
|
51
|
+
- `src/middleware.ts` / `src/app/**/middleware.ts`
|
|
52
|
+
- `src/lib/auth/**` / `src/app/api/auth/**`
|
|
53
|
+
- `prisma/schema.prisma` / `prisma/migrations/**`
|
|
54
|
+
- `src/lib/security/**`
|
|
55
|
+
- Any tenant-scoped query or tenant-context resolution
|
|
56
|
+
- `.github/workflows/deploy*.yml`
|
|
57
|
+
- Production environment variables
|
|
58
|
+
- Database seed data
|
|
59
|
+
|
|
60
|
+
If the fix touches any of these → not eligible for /quick-fix,
|
|
61
|
+
regardless of size.
|
|
62
|
+
|
|
63
|
+
## Enforcement
|
|
64
|
+
|
|
65
|
+
- Skill: `.claude/skills/quick-fix/SKILL.md` requires explicit
|
|
66
|
+
criteria-check output before proceeding
|
|
67
|
+
- Methodology: agent self-checks every criterion; silence is not skip
|
|
68
|
+
- Future: pre-commit hook could check `[quick-fix]` footer presence on
|
|
69
|
+
any commit authored with /quick-fix; currently methodology-level
|
|
70
|
+
|
|
71
|
+
## Override
|
|
72
|
+
|
|
73
|
+
There is no override path for criteria. Either all five hold (quick-fix)
|
|
74
|
+
or they don't (full diagnose). Softening the criteria softens the rule.
|
|
75
|
+
|
|
76
|
+
## Relationship
|
|
77
|
+
|
|
78
|
+
- `.claude/skills/quick-fix/SKILL.md` — the skill that cites this rule
|
|
79
|
+
- `.claude/rules/diagnosis.md` — the full-ceremony rule
|
|
80
|
+
- `.claude/rules/auto-fix-criteria.md` — sibling for the autonomous lane
|
|
81
|
+
- `blocked-items.md` — if criteria fail, escalation is not optional
|
|
82
|
+
|
|
83
|
+
## When this rule retires
|
|
84
|
+
|
|
85
|
+
If observed over 6 months with audit ratio consistently ≤20% and zero
|
|
86
|
+
operator corrections, the criteria may be too strict. Loosen criterion
|
|
87
|
+
3 (lines) or criterion 1 (files) — not criterion 4 (blast radius).
|
|
88
|
+
Criterion 4 is load-bearing.
|
|
89
|
+
|
|
90
|
+
Closes bassclef #151 (paired with skill).
|
|
@@ -26,6 +26,36 @@ to specific adopter sessions.
|
|
|
26
26
|
This applies to bassclef's own repo only; adopter repos keep
|
|
27
27
|
chronicles + markers tracked per their own configuration.
|
|
28
28
|
|
|
29
|
+
### Known contradiction — this rule is authoritative, the shipped config is not yet
|
|
30
|
+
|
|
31
|
+
`presence/dist-templates/.gitignore` is the file adopters install. It
|
|
32
|
+
ignores `state/markers/`. That contradicts the sentence above, so an
|
|
33
|
+
adopter who runs `/temperance` watches the skill run `git add` and watches
|
|
34
|
+
git refuse it. Reported as bassclef-upstream#1694.
|
|
35
|
+
|
|
36
|
+
This rule wins. Adopters are meant to track their markers. The shipped
|
|
37
|
+
config has not caught up.
|
|
38
|
+
|
|
39
|
+
**Why it has not changed yet, and the order it must change in.** Per
|
|
40
|
+
RFC-0009: 31 of 899 markers measured 2026-09-17 carry an absolute path or
|
|
41
|
+
a machine name. Today the ignore fails safe — nothing leaks. Untracking
|
|
42
|
+
before those paths are scrubbed opens a window where 3.4% of markers can
|
|
43
|
+
be committed and pushed, and a path in git history is not removable
|
|
44
|
+
without rewriting someone else's repo.
|
|
45
|
+
|
|
46
|
+
So the order is: scrub the paths at write time, verify on a real install
|
|
47
|
+
per bassclef-upstream#1706, then stop ignoring. Not the other way round.
|
|
48
|
+
|
|
49
|
+
**Why adopters track them.** Not an audit trail — state transfer. A marker
|
|
50
|
+
that only exists on the machine that wrote it cannot reach a second machine
|
|
51
|
+
or a teammate. Every gate re-fires on the other side, and work does not pick
|
|
52
|
+
up where it left off. Tracking markers is what makes a session resumable by
|
|
53
|
+
someone else, or by the same person on different hardware.
|
|
54
|
+
|
|
55
|
+
Measured: 78 files reference `state/markers`, three read a marker's content,
|
|
56
|
+
and nothing reads marker history from git. That absence is a symptom of the
|
|
57
|
+
ignore, not an argument for it. Nothing reads what never survives.
|
|
58
|
+
|
|
29
59
|
## Backfill before current (MUST — applies to all artifacts below)
|
|
30
60
|
|
|
31
61
|
Before writing ANY session artifact (chronicle, journal entry, release notes):
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: When a PR touches an adopter-observable substrate path (.claude/hooks/.sh, .claude/rules/.md, .claude/skills//SKILL.md, .claude/agents/.md, lib/.sh, or…
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Sibling Smoke After Substrate Change
|
|
7
|
+
|
|
8
|
+
When a PR touches an adopter-observable substrate path (`.claude/hooks/*.sh`, `.claude/rules/*.md`, `.claude/skills/*/SKILL.md`, `.claude/agents/*.md`, `lib/*.sh`, or `standards/state-spine/schemas/*.json`), a sibling smoke obligation is owed before the next `/release` ships the change downstream. The harness verifies structure; the smoke test verifies behavior in a real adopter session.
|
|
9
|
+
|
|
10
|
+
This rule is the methodology layer. The mechanism (advisory prompt in `/release` dry-run output) ships under sunj-labs/bassclef-upstream#545 V2.
|
|
11
|
+
|
|
12
|
+
## When this rule fires
|
|
13
|
+
|
|
14
|
+
Any PR that touches adopter-observable substrate paths (matcher above). The cold-adopter harness rule at `.claude/rules/cold-adopter-harness-discipline.md` names the same matcher; this rule extends it with the sibling-smoke obligation.
|
|
15
|
+
|
|
16
|
+
The rule passes through on:
|
|
17
|
+
|
|
18
|
+
- PRs touching only operator content (chronicles, journals, deferred-actions)
|
|
19
|
+
- PRs touching only documentation that does not change adopter-observable behavior
|
|
20
|
+
- Bug fixes where the harness already covers the change class via fixture-driven tests
|
|
21
|
+
|
|
22
|
+
## What the rule requires
|
|
23
|
+
|
|
24
|
+
Between PR merge and the next `/release` dispatch, the operator runs a smoke test in a sibling adopter repo:
|
|
25
|
+
|
|
26
|
+
1. Pick a sibling — POA, twoDo, eugene-supplements, family-recipe-2, or quorum
|
|
27
|
+
2. Run `bash .claude/hooks/bassclef-sync.sh` in the sibling (pulls from current public bassclef OR from a temporary upstream pointer for pre-release verification)
|
|
28
|
+
3. Start a fresh Claude Code session in the sibling
|
|
29
|
+
4. Verify SessionStart output:
|
|
30
|
+
- No errors from new or modified hooks
|
|
31
|
+
- In-flight bet surfaces correctly (cure 1 from session-orientation audit)
|
|
32
|
+
- Orientation gate behaves correctly on main + feature branches (cure 2)
|
|
33
|
+
- No broken symlinks
|
|
34
|
+
- The cure's intended behavior visible (e.g., the new `### ACTIVE BET` block appears at SessionStart)
|
|
35
|
+
5. Record the smoke result with a one-line note in the next `/release` dry-run output:
|
|
36
|
+
- PASS: `Sibling smoke: ran <sibling-repo> SessionStart at <ISO timestamp>; clean — <one-line observation>`
|
|
37
|
+
- FAIL: `Sibling smoke: ran <sibling-repo> SessionStart at <ISO timestamp>; FAIL — <one-line observation>`. PR holds until cured.
|
|
38
|
+
|
|
39
|
+
The smoke is operator-driven. The mechanism extension under #545 V2 puts the prompt in `/release` dry-run output. Until V2 ships, the rule loads at session start and the operator runs the smoke before invoking `/release`.
|
|
40
|
+
|
|
41
|
+
## Sibling pick guidance
|
|
42
|
+
|
|
43
|
+
| Sibling | Best for | Why |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| POA | Highest-cure-impact changes | Largest adopter footprint; surfaced bet 30a's F7 cure validation |
|
|
46
|
+
| twoDo | UI-adjacent cures | Front-of-shop adopter; visible Stuff |
|
|
47
|
+
| eugene-supplements | apps/web Tier 1 / ORM-adjacent cures | Active development; runs frequent sessions |
|
|
48
|
+
| family-recipe-2 | Lower-traffic adopter | Catches edge cases the high-traffic siblings miss |
|
|
49
|
+
| quorum | Substrate-discipline cures | Heavy use of `/longrun`, `/temperance`, `/luminary`; surfaces SKILL.md drift |
|
|
50
|
+
|
|
51
|
+
Operator picks based on which sibling exercises the cure's surface most directly.
|
|
52
|
+
|
|
53
|
+
## Anti-patterns
|
|
54
|
+
|
|
55
|
+
These shapes fail the rule. Each pairs with the INSTEAD shape that satisfies it.
|
|
56
|
+
|
|
57
|
+
**Skipping the sibling smoke before `/release`** — cure rides to public bassclef; first adopter `bassclef-sync` pull verifies it in production. Cost compounds: if the cure is broken, every adopter pulls the broken version before the gap is noticed.
|
|
58
|
+
INSTEAD: smoke test BEFORE `/release` dry-run; surface the result in dry-run output.
|
|
59
|
+
|
|
60
|
+
**Running the smoke via temporary symlink swap (pointing the sibling at `bassclef-upstream` instead of `bassclef`)** — verifies the cure in a non-adopter shape. Adopters get the cure via `bassclef-sync` from public bassclef, not from `bassclef-upstream` directly. The symlink swap simulates an environment no real adopter runs in.
|
|
61
|
+
INSTEAD: ship the cure via `/release` to public bassclef first AND smoke against the public-pulled state, OR smoke against the fixture harness (`run-with-fixtures.sh`) which simulates adopter shape without the symlink swap.
|
|
62
|
+
|
|
63
|
+
**Treating CI "all green" as sufficient** — CI verifies structure + harness-level smoke. Real-session behavior in an adopter shape is unverified. Tonight's WU-B + WU-E shipped 9 GREEN CI checks and zero fixture-driven coverage.
|
|
64
|
+
INSTEAD: CI is necessary but not sufficient. Sibling smoke closes the behavior-verification gap.
|
|
65
|
+
|
|
66
|
+
**Shipping cure tests with no fixture header** — test rides CI's vanilla environment only. Cure's fixture coverage is zero. Per #545 fixture-header BLOCK (V2), this becomes a Tier 0 enforcement.
|
|
67
|
+
INSTEAD: every cure test on substrate-affecting paths declares `# fixtures: <name>` in its top-of-file header and uses `FIXTURE_DIR` in at least one assertion. The `run-with-fixtures.sh` wrapper runs the test per fixture; the cure rides every declared adopter shape.
|
|
68
|
+
|
|
69
|
+
## Override
|
|
70
|
+
|
|
71
|
+
`SKIP_SIBLING_SMOKE=1 <command>` — bypass for one `/release` call. Logged via trace-helper. Use only when:
|
|
72
|
+
|
|
73
|
+
- The cure is a pure no-behavior rename (no symlink target change, no hook semantics change)
|
|
74
|
+
- Emergency rescue where the smoke step itself is broken
|
|
75
|
+
- Operator-confirmed explicit defer naming a follow-on ticket that closes the smoke check
|
|
76
|
+
|
|
77
|
+
INSTEAD of overriding for routine `/release`: run the smoke. The cost is a few minutes; the discipline compounds across every adopter machine pulling the release.
|
|
78
|
+
|
|
79
|
+
## V2 mechanism (deferred to follow-on)
|
|
80
|
+
|
|
81
|
+
Extend `/release` skill dry-run output with a "Sibling smoke evidence" section:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
## Sibling smoke evidence
|
|
85
|
+
|
|
86
|
+
Required (paste one-line confirmation OR explicit defer):
|
|
87
|
+
> Sibling smoke: ran <sibling> SessionStart at <timestamp>; <PASS / FAIL or DEFERRED with reason>
|
|
88
|
+
|
|
89
|
+
Silence is not deferral. Default is run the smoke.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `/release` dispatch refuses to fire live until the operator pastes a confirmation OR sets `SKIP_SIBLING_SMOKE=1` with rationale.
|
|
93
|
+
|
|
94
|
+
V2 also extends `cold-adopter-harness-sync.sh` Shape d with Check 13 (fixture-header-presence): BLOCK on tests in `.claude/hooks/session-reflection.d/tests/` + `.claude/hooks/tests/` that exercise substrate-affecting paths AND lack a `# fixtures: <name>` header. Allowlist baseline for existing untagged tests at write time; grace window per `.claude/hooks/testing-tier-enforce-allowlist.txt` pattern.
|
|
95
|
+
|
|
96
|
+
## Composes with
|
|
97
|
+
|
|
98
|
+
- `.claude/rules/cold-adopter-harness-discipline.md` — sister rule; this rule extends with behavioral verification beyond the four Shape d structural checks
|
|
99
|
+
- `.claude/rules/we-dont-break-adopters.md` — sister ADR-031 discipline; sibling smoke is the operational form of "the cure works for adopters"
|
|
100
|
+
- `.claude/rules/testing-tier-config.md` — Tier 0 strict TDD on hooks; this rule extends to per-fixture coverage
|
|
101
|
+
- `.claude/rules/blocked-items.md` — BLOCKED protocol the V2 mechanism fires
|
|
102
|
+
- The fixture-tests wrapper (operator substrate) — runs each test per declared fixture
|
|
103
|
+
- `lib/fixture-builder.sh` — the deep module the fixtures use
|
|
104
|
+
- ADR-031 we-dont-break-adopters
|
|
105
|
+
- ADR-035 substrate-as-system (behavioral verification extends complete-mediation to the runtime layer)
|
|
106
|
+
- ADR-038 adopter testing harness redesign
|
|
107
|
+
- memory `feedback_smoke_test_after_cure_pattern` — the discipline this rule codifies
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: "Per ADR-035: bassclef's substrate is a system, not a bag of files."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Substrate as System
|
|
7
|
+
|
|
8
|
+
Per ADR-035: bassclef's substrate is a system, not a bag of files. Every rule that names a mechanical enforcement makes an end-to-end commitment — the mechanism exists, is wired, resolves paths under both install classes, and has a Tier 0 test that pins behavior. If any link in that chain fails, the rule's claim is unhonored and adopters inherit a contract the substrate cannot keep.
|
|
9
|
+
|
|
10
|
+
This rule is the auto-loaded reminder. The mechanical layer is `lib/mechanism-fidelity.sh` + `.claude/skills/audit-rule-mechanism-fidelity/SKILL.md` + cold-adopter harness Shape d (4 check classes). Both required.
|
|
11
|
+
|
|
12
|
+
## When this rule fires
|
|
13
|
+
|
|
14
|
+
Every session. Auto-loaded via `additionalDirectories`. The reminder steers authoring at every surface where a rule names a mechanism — goal docs, new rules, amended rules, new hooks, new skills.
|
|
15
|
+
|
|
16
|
+
## What this rule requires
|
|
17
|
+
|
|
18
|
+
When authoring or amending any rule that names a mechanical enforcement (a hook by filename, an event matcher, a settings.json entry, a Tier 0 test):
|
|
19
|
+
|
|
20
|
+
1. **End-to-end commitment** — the mechanism must exist on disk + be wired in settings.json + resolve paths under both install classes (project + operator) + have a Tier 0 test pinning behavior
|
|
21
|
+
2. **Path resolution under install class** — if the hook reads project resources, source `lib/hook-inject.sh` and use `resolve_standards_path` + `resolve_config_path` per `standards/hook-install-class.md`. Declare `# install-class: dual` in the hook header.
|
|
22
|
+
3. **Tier 0 test sufficient** — test pins behavior under both install classes via `HOME_OVERRIDE` fixture per `.claude/rules/test-sufficiency.md` (criterion 11 added in bet 27c WU-9). The kiss cure (PR #427) is the exemplar pattern.
|
|
23
|
+
4. **Per-PR verification** — cold-adopter harness Shape d (4 check classes) fires on every PR; ADVISORY V1 (lands in bet 27c WU-5), BLOCK V2 (lands in Bet C-pre-2 cure bet). Verification happens at adopter-PR time, not just at substrate-author time.
|
|
24
|
+
|
|
25
|
+
## Anti-patterns
|
|
26
|
+
|
|
27
|
+
These shapes fail this rule.
|
|
28
|
+
|
|
29
|
+
**Rule says X enforces but no hook exists at the named path.** Per ADR-035 substrate-as-system — claim without referent. Cure: author the hook OR remove the claim OR reword to methodology-only.
|
|
30
|
+
|
|
31
|
+
**Hook exists but settings.json doesn't wire it.** DEAD-LETTER per `lib/mechanism-fidelity.sh` classification. Cure: add settings.json entry.
|
|
32
|
+
|
|
33
|
+
**Hook is wired but reads project resources via SCRIPT_DIR/../../ and declares install-class: operator.** Class A failure. The kiss path-resolution defect (PR #427) was the live exemplar. Cure: declare `install-class: dual` + source `lib/hook-inject.sh` + use `resolve_standards_path` per the kiss cure pattern.
|
|
34
|
+
|
|
35
|
+
**Hook works under project install but Tier 0 test only verifies project-class behavior.** TEST-MISSING per `lib/mechanism-fidelity.sh` classification. Cure: add HOME_OVERRIDE fixture test per kiss cure Tests 54+56 pattern.
|
|
36
|
+
|
|
37
|
+
INSTEAD of any of these: check the claim before you author it, amend rule bodies to drop claims the substrate does not honor, and ship the fixes.
|
|
38
|
+
|
|
39
|
+
Operators on the standard or ultra tier can run `/audit-rule-mechanism-fidelity` to do the check in one pass. That skill ships at `tier: upstream`, so lite adopters do not have it. At lite, do the check by hand: open the hook the rule names, confirm it exists, confirm `.claude/settings.json` wires it, and confirm a test sits beside it.
|
|
40
|
+
|
|
41
|
+
## Composes with
|
|
42
|
+
|
|
43
|
+
- `.claude/rules/mechanism-fidelity.md` — sister rule that names the audit skill + harness check classes
|
|
44
|
+
- `.claude/rules/bootstrap-pair-discipline.md` — sister discipline (every primitive ships with its paired bootstrap; this rule extends to mechanism-fidelity verification)
|
|
45
|
+
- `.claude/rules/hook-wire-on-author.md` — sister discipline at the settings.json wiring surface
|
|
46
|
+
- `.claude/rules/testing-tier-config.md` — Tier 0 strict-TDD per substrate-internal path
|
|
47
|
+
- `.claude/rules/test-sufficiency.md` — criterion 11 (path-resolution under both install classes) added in bet 27c WU-9
|
|
48
|
+
- `.claude/rules/cold-adopter-harness-discipline.md` — per-PR gate this rule's verification rides
|
|
49
|
+
- ADR-035 — the authority this rule operationalizes at the methodology layer
|
|
50
|
+
- `standards/mechanism-fidelity.md` (WU-2 of bet 27c) — full reference for the verification chain
|
|
51
|
+
- `standards/hook-install-class.md` (WU-2) — `install-class: dual` declaration this rule cites
|
|
52
|
+
- `lib/hook-inject.sh` (WU-3) — path-resolution lib the cure pattern uses
|
|
53
|
+
- `lib/mechanism-fidelity.sh` (WU-3) — verification chain scanner
|
|
54
|
+
- `.claude/skills/audit-rule-mechanism-fidelity/SKILL.md` (WU-4) — operator-invocable audit
|
|
55
|
+
- `scripts/cold-adopter-harness-sync.sh` Shape d (WU-5) — per-PR gate
|
|
56
|
+
- `architecture/audits/2026-06-27-mechanism-fidelity.md` (WU-6) — first findings table
|
|
57
|
+
- `architecture/audits/2026-06-27-audit-method-blind-spot.md` (WU-7.5) — recursive Act phase
|
|
58
|
+
- bassclef-upstream#433 — proposed per-edit enforcement hook (PreToolUse Edit|Write on `.claude/rules/*.md` calls lib's verify chain at agent-author time); fourth layer in the defense stack alongside harness Shape d (per-PR) + audit skill (operator-invocable) + this rule (per-session steering)
|
|
59
|
+
- @luminary saltzer-schroeder — complete mediation
|
|
60
|
+
- @luminary michael-feathers — characterization tests as cure for legacy code
|
|
61
|
+
- @luminary john-ousterhout — deep modules (shared lib reuse across audit + harness)
|
|
62
|
+
|
|
63
|
+
## Override
|
|
64
|
+
|
|
65
|
+
`SKIP_SUBSTRATE_AS_SYSTEM=1 <command>` — for genuine one-shot scripts that intentionally skip the discipline (e.g., migration tooling). Logged via trace-helper.
|
|
66
|
+
|
|
67
|
+
INSTEAD of overriding for routine work: honor the end-to-end commitment. The cost is small (one settings.json line, one install-class declaration, one Tier 0 test); the discipline compounds across every adopter inheritance.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
globs: ["src/app/**/page.tsx", "src/components/**/*.tsx", "**/*.css"]
|
|
4
|
+
description: Usability check — loads only when touching UI files
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Post-build gate for UI changes. Run before merge.
|
|
8
|
+
|
|
9
|
+
1. Role check — sign in as least-privileged role (VIEWER/COLLABORATOR). No operator jargon visible.
|
|
10
|
+
2. Scanning distance — no label...value patterns wider than ~150px. Use labels-above-values for financial data.
|
|
11
|
+
3. Typography hierarchy — key numbers 14px+ bold, labels smaller + muted, no text <11px.
|
|
12
|
+
4. Jargon & copy — no database enums (BIZBUYSELL → BizBuySell), externalized labels, multi-tenant ready.
|
|
13
|
+
5. Attribution — show WHO performed actions, not just aggregate counts.
|
|
14
|
+
6. Accessibility — 44px tap targets, 4.5:1 contrast, no translucent text backgrounds.
|
|
15
|
+
7. Consistency — same badge treatment for same status everywhere.
|
|
16
|
+
|
|
17
|
+
For significant UI changes: screenshot each surface and attach to PR.
|
|
18
|
+
|
|
19
|
+
8. Visual verification — when Playwright MCP is available, screenshot the
|
|
20
|
+
page and verify programmatically: tap target sizes via DOM inspection,
|
|
21
|
+
contrast ratios, text sizes, badge consistency. Don't rely on code review
|
|
22
|
+
alone for visual correctness — see what the user sees.
|