@thebassclef/lite 0.1.3 → 1.0.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 +431 -135
- package/dist/cli.js +433 -137
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.bassclef-source.json +10 -0
- package/{substrate → dist/lite}/.claude/hooks/artifact-ingestion-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/assert-verify-steering.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/bassclef-source-config-validate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/bassclef-sync.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/compound-noun-scrub.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/kiss-expansion-inject.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/longrun-prep-compounding-sequence-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/plain-english-steering.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/post-skill-friction-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/post-skill-telemetry.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/pre-build-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/pre-commit-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/session-end.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/session-reflection.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/skill-body-grade-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/skill-body-intent-drift.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/state-validate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/substrate-clarity-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/temperance-gate.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/testing-tier-enforce.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/turn-prose-grade-measure.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/turn-prose-kiss-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/vocabulary-migration-check.sh +0 -0
- package/{substrate → dist/lite}/.claude/hooks/whereami-utc-gate.sh +0 -0
- package/dist/lite/.claude/settings.json +212 -0
- package/dist/lite/CLAUDE.md +41 -0
- package/dist/lite/gitignore +58 -0
- package/dist/lite/standards/bassclef-wiring-manifest.json +497 -0
- package/dist/lite/whereami.md +24 -0
- package/package.json +8 -2
- package/substrate/.bassclef/lite-manifest.json +0 -2701
- package/substrate/.claude/agents/architect.md +0 -70
- package/substrate/.claude/agents/builder.md +0 -114
- package/substrate/.claude/agents/designer.md +0 -156
- package/substrate/.claude/agents/reviewer.md +0 -88
- package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +0 -492
- package/substrate/.claude/hooks/skill-step-list-check.sh +0 -171
- package/substrate/.claude/luminaries/alan-cooper.md +0 -170
- package/substrate/.claude/luminaries/alistair-cockburn.md +0 -140
- package/substrate/.claude/luminaries/amazon-pr-faq.md +0 -34
- package/substrate/.claude/luminaries/ash-maurya.md +0 -121
- package/substrate/.claude/luminaries/bill-buxton.md +0 -210
- package/substrate/.claude/luminaries/charles-sanders-peirce.md +0 -150
- package/substrate/.claude/luminaries/david-ogilvy.md +0 -192
- package/substrate/.claude/luminaries/don-norman.md +0 -173
- package/substrate/.claude/luminaries/edward-tufte.md +0 -179
- package/substrate/.claude/luminaries/eric-evans.md +0 -160
- package/substrate/.claude/luminaries/frederick-brooks.md +0 -50
- package/substrate/.claude/luminaries/gang-of-four.md +0 -157
- package/substrate/.claude/luminaries/glenford-myers.md +0 -230
- package/substrate/.claude/luminaries/hunt-thomas.md +0 -115
- package/substrate/.claude/luminaries/hyrum-wright.md +0 -94
- package/substrate/.claude/luminaries/jason-fried-dhh.md +0 -46
- package/substrate/.claude/luminaries/jesse-james-garrett.md +0 -154
- package/substrate/.claude/luminaries/john-ousterhout.md +0 -94
- package/substrate/.claude/luminaries/karl-popper.md +0 -132
- package/substrate/.claude/luminaries/kent-beck.md +0 -168
- package/substrate/.claude/luminaries/linus-torvalds.md +0 -218
- package/substrate/.claude/luminaries/martin-fowler.md +0 -164
- package/substrate/.claude/luminaries/michael-feathers.md +0 -125
- package/substrate/.claude/luminaries/michael-nygard.md +0 -118
- package/substrate/.claude/luminaries/robert-c-martin.md +0 -164
- package/substrate/.claude/luminaries/saltzer-schroeder.md +0 -194
- package/substrate/.claude/luminaries/sophia-prater.md +0 -193
- package/substrate/.claude/luminaries/stephen-toulmin.md +0 -131
- package/substrate/.claude/luminaries/tony-hoare.md +0 -170
- package/substrate/.claude/luminaries/vaughn-vernon.md +0 -50
- package/substrate/.claude/luminaries/w-edwards-deming.md +0 -158
- package/substrate/.claude/rules/accessor-library-discipline.md +0 -138
- package/substrate/.claude/rules/adr-discipline.md +0 -120
- package/substrate/.claude/rules/api-conventions.md +0 -125
- package/substrate/.claude/rules/artifact-ingestion.md +0 -179
- package/substrate/.claude/rules/assert-only-after-verify.md +0 -137
- package/substrate/.claude/rules/blocked-items.md +0 -146
- package/substrate/.claude/rules/bootstrap-pair-discipline.md +0 -141
- package/substrate/.claude/rules/branching.md +0 -28
- package/substrate/.claude/rules/cold-adopter-harness-discipline.md +0 -129
- package/substrate/.claude/rules/commit-conventions.md +0 -22
- package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +0 -188
- package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +0 -188
- package/substrate/.claude/rules/context-engineering.md +0 -202
- package/substrate/.claude/rules/context-management.md +0 -85
- package/substrate/.claude/rules/defensive-bash.md +0 -68
- package/substrate/.claude/rules/deferred-actions.md +0 -233
- package/substrate/.claude/rules/destructive-operations.md +0 -69
- package/substrate/.claude/rules/diagnosis.md +0 -38
- package/substrate/.claude/rules/github-issue-flash-tweet.md +0 -156
- package/substrate/.claude/rules/guardrails.md +0 -73
- package/substrate/.claude/rules/hook-wire-on-author.md +0 -103
- package/substrate/.claude/rules/identifier-leak-prevention.md +0 -104
- package/substrate/.claude/rules/iteration-bet-brief-completeness.md +0 -54
- package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +0 -98
- package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +0 -89
- package/substrate/.claude/rules/loop-discipline.md +0 -81
- package/substrate/.claude/rules/manual-prod-approval.md +0 -100
- package/substrate/.claude/rules/marker-enrichment-discipline.md +0 -99
- package/substrate/.claude/rules/mobile-ephemeral-session.md +0 -109
- package/substrate/.claude/rules/new-dependency-check.md +0 -51
- package/substrate/.claude/rules/oo-ad-entry-point.md +0 -117
- package/substrate/.claude/rules/operator-facing-prose.md +0 -196
- package/substrate/.claude/rules/option-label-discipline.md +0 -108
- package/substrate/.claude/rules/pattern-annotation.md +0 -100
- package/substrate/.claude/rules/plain-english-discipline.md +0 -156
- package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +0 -211
- package/substrate/.claude/rules/pr-body-shape.md +0 -317
- package/substrate/.claude/rules/pr-strategy.md +0 -167
- package/substrate/.claude/rules/pr-title-shape.md +0 -161
- package/substrate/.claude/rules/prototype-workflow.md +0 -65
- package/substrate/.claude/rules/reserved-skill-names.md +0 -123
- package/substrate/.claude/rules/schema-management.md +0 -49
- package/substrate/.claude/rules/sdlc-gates.md +0 -149
- package/substrate/.claude/rules/security.md +0 -37
- package/substrate/.claude/rules/session-artifacts.md +0 -236
- package/substrate/.claude/rules/skill-composition-declarations.md +0 -124
- package/substrate/.claude/rules/skill-description-clarity.md +0 -247
- package/substrate/.claude/rules/skill-procedure-step-list.md +0 -137
- package/substrate/.claude/rules/state-schema-validation.md +0 -162
- package/substrate/.claude/rules/stuck-signal-diagnostic.md +0 -140
- package/substrate/.claude/rules/substrate-config-schema.md +0 -98
- package/substrate/.claude/rules/test-list-discipline.md +0 -175
- package/substrate/.claude/rules/test-sufficiency.md +0 -210
- package/substrate/.claude/rules/testing-tier-config.md +0 -145
- package/substrate/.claude/rules/testing.md +0 -38
- package/substrate/.claude/rules/turn-estimate-grounding.md +0 -134
- package/substrate/.claude/rules/visual-hierarchy.md +0 -437
- package/substrate/.claude/rules/we-dont-break-adopters.md +0 -126
- package/substrate/.claude/rules/whereami-load-bearing.md +0 -202
- package/substrate/.claude/rules/writing-craft-discipline.md +0 -92
- package/substrate/.claude/rules/wu-sequencing-compounds.md +0 -145
- package/substrate/.claude/skills/build/SKILL.md +0 -640
- package/substrate/.claude/skills/chronicle/SKILL.md +0 -55
- package/substrate/.claude/skills/clean-artifacts/SKILL.md +0 -249
- package/substrate/.claude/skills/decompose/SKILL.md +0 -280
- package/substrate/.claude/skills/diagnose/SKILL.md +0 -297
- package/substrate/.claude/skills/feynman/SKILL.md +0 -90
- package/substrate/.claude/skills/howdoi/SKILL.md +0 -105
- package/substrate/.claude/skills/ia-model/SKILL.md +0 -108
- package/substrate/.claude/skills/interaction-design/SKILL.md +0 -112
- package/substrate/.claude/skills/interpret-input/SKILL.md +0 -180
- package/substrate/.claude/skills/journal/SKILL.md +0 -209
- package/substrate/.claude/skills/kiss/SKILL.md +0 -449
- package/substrate/.claude/skills/launch/SKILL.md +0 -915
- package/substrate/.claude/skills/lean-canvas/SKILL.md +0 -332
- package/substrate/.claude/skills/longrun/SKILL.md +0 -463
- package/substrate/.claude/skills/luminary/SKILL.md +0 -481
- package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +0 -177
- package/substrate/.claude/skills/onboard-repo/SKILL.md +0 -1624
- package/substrate/.claude/skills/pattern-review/SKILL.md +0 -99
- package/substrate/.claude/skills/personas/SKILL.md +0 -207
- package/substrate/.claude/skills/promote/SKILL.md +0 -283
- package/substrate/.claude/skills/requirement/SKILL.md +0 -98
- package/substrate/.claude/skills/retro/SKILL.md +0 -117
- package/substrate/.claude/skills/riff/SKILL.md +0 -114
- package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +0 -163
- package/substrate/.claude/skills/session-end/SKILL.md +0 -309
- package/substrate/.claude/skills/session-log/SKILL.md +0 -299
- package/substrate/.claude/skills/skills/SKILL.md +0 -228
- package/substrate/.claude/skills/spec/SKILL.md +0 -105
- package/substrate/.claude/skills/sprint/SKILL.md +0 -392
- package/substrate/.claude/skills/stage/SKILL.md +0 -384
- package/substrate/.claude/skills/state-a-problem/SKILL.md +0 -185
- package/substrate/.claude/skills/temperance/SKILL.md +0 -108
- package/substrate/.claude/skills/use-case/SKILL.md +0 -417
- package/substrate/.claude/skills/user-stories/SKILL.md +0 -268
- package/substrate/.claude/skills/value-prop/SKILL.md +0 -251
- package/substrate/.claude/skills/verify/SKILL.md +0 -160
- package/substrate/.claude/skills/visual-review/SKILL.md +0 -503
- package/substrate/.claude/skills/whats-the-plan/SKILL.md +0 -202
- package/substrate/.claude/skills/whereami/SKILL.md +0 -307
- package/substrate/AGENTS.md +0 -79
- package/substrate/CLAUDE-lite.md +0 -85
- package/substrate/CODE_OF_CONDUCT.md +0 -28
- package/substrate/CONTRIBUTING.md +0 -177
- package/substrate/README.md +0 -173
- package/substrate/SECURITY.md +0 -19
- package/substrate/architecture/decisions/ADR-029-release-pipeline.md +0 -79
- package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +0 -139
- package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +0 -192
- package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +0 -145
- package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +0 -155
- package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +0 -162
- package/substrate/lib/clean-artifacts-sweep.sh +0 -112
- package/substrate/lib/code-comment-discipline.sh +0 -144
- package/substrate/lib/composer-preflight.sh +0 -459
- package/substrate/lib/hook-inject.sh +0 -255
- package/substrate/lib/luminary-pick.sh +0 -96
- package/substrate/lib/output-discipline.sh +0 -143
- package/substrate/lib/prose-scan-boundary.sh +0 -171
- package/substrate/lib/rewrite-check.sh +0 -214
- package/substrate/lib/state.sh +0 -1372
- package/substrate/lib/telemetry.sh +0 -205
- package/substrate/lib/tier-check.sh +0 -187
- package/substrate/lib/tier-dependency-audit.sh +0 -1088
- package/substrate/presence/install/bassclef-hook-connect.sh +0 -178
- package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +0 -841
- package/substrate/presence/install/bassclef-sync.template.sh +0 -2076
- package/substrate/presence/install/schedule-auto-save.cron.sh +0 -88
- package/substrate/presence/install/schedule-auto-save.taskscheduler.md +0 -122
- package/substrate/scripts/aggregate-telemetry.sh +0 -217
- package/substrate/scripts/analyze-tier-dependencies.sh +0 -239
- package/substrate/scripts/generate-lite-manifest.sh +0 -505
- package/substrate/scripts/generate-tier-manifest.sh +0 -28
- package/substrate/scripts/intent-drift-check.sh +0 -456
- package/substrate/scripts/lite-manifest-drift-check.sh +0 -146
- package/substrate/scripts/render-lite-manifest-doc.sh +0 -150
- package/substrate/standards/adr-template.md +0 -86
- package/substrate/standards/api-conventions/nextjs.md +0 -84
- package/substrate/standards/artifact-composition.md +0 -209
- package/substrate/standards/bash-hook-safety.md +0 -246
- package/substrate/standards/bassclef-configs-schema.md +0 -232
- package/substrate/standards/bassclef-evolution.md +0 -143
- package/substrate/standards/bassclef-internal-jargon.md +0 -244
- package/substrate/standards/bassclef-managed-sentinel.md +0 -96
- package/substrate/standards/bassclef-source-config.md +0 -228
- package/substrate/standards/branch-stacking.md +0 -408
- package/substrate/standards/code-safety-principles.md +0 -176
- package/substrate/standards/composer-prerequisites.md +0 -155
- package/substrate/standards/deferred-actions-schema.md +0 -204
- package/substrate/standards/dependency-discipline/cargo.md +0 -39
- package/substrate/standards/dependency-discipline/gem.md +0 -43
- package/substrate/standards/dependency-discipline/go-mod.md +0 -41
- package/substrate/standards/dependency-discipline/npm.md +0 -42
- package/substrate/standards/dependency-discipline/pip.md +0 -42
- package/substrate/standards/deployment-topology/ec2-tailscale.md +0 -225
- package/substrate/standards/deployment-topology.md +0 -69
- package/substrate/standards/docs-sync-allowlist.md +0 -76
- package/substrate/standards/domain-and-dns.md +0 -145
- package/substrate/standards/frontend-stack.md +0 -67
- package/substrate/standards/frontmatter-schema.md +0 -154
- package/substrate/standards/graceful-exit.md +0 -227
- package/substrate/standards/hook-idempotency.md +0 -102
- package/substrate/standards/hook-injection-discipline.md +0 -202
- package/substrate/standards/hook-install-class.md +0 -215
- package/substrate/standards/input-handler-interface.md +0 -152
- package/substrate/standards/lite-manifest-schema-changes.md +0 -135
- package/substrate/standards/luminary-matching.md +0 -105
- package/substrate/standards/luminary-problem-patterns.md +0 -481
- package/substrate/standards/migration-discipline/active-record.md +0 -50
- package/substrate/standards/migration-discipline/alembic.md +0 -43
- package/substrate/standards/migration-discipline/gorm.md +0 -50
- package/substrate/standards/migration-discipline/prisma.md +0 -53
- package/substrate/standards/migration-discipline/sqlalchemy.md +0 -51
- package/substrate/standards/mobile-ephemeral-session.md +0 -167
- package/substrate/standards/model-routing-discipline.md +0 -160
- package/substrate/standards/ogilvy-writing-rules.md +0 -225
- package/substrate/standards/opener-discipline.md +0 -96
- package/substrate/standards/operator-facing-prose-discipline.md +0 -201
- package/substrate/standards/persona-schema.md +0 -229
- package/substrate/standards/pluggable-luminaries.md +0 -323
- package/substrate/standards/pr-body-discipline.md +0 -115
- package/substrate/standards/preview-state-schema.md +0 -189
- package/substrate/standards/project-directory-layout.md +0 -276
- package/substrate/standards/release-tagging.md +0 -137
- package/substrate/standards/reserved-skill-names.md +0 -120
- package/substrate/standards/scannable-multi-option-output.md +0 -261
- package/substrate/standards/sdlc-compliance.md +0 -286
- package/substrate/standards/sdlc-gates/typescript.md +0 -57
- package/substrate/standards/secrets-lifecycle.md +0 -210
- package/substrate/standards/security-scanner-adapter.md +0 -145
- package/substrate/standards/session-board.md +0 -256
- package/substrate/standards/skill-output-discipline.md +0 -90
- package/substrate/standards/state-spine-contract.md +0 -255
- package/substrate/standards/state-spine.md +0 -511
- package/substrate/standards/steering-hints/kiss-words.md +0 -11
- package/substrate/standards/substrate-config-schema.md +0 -267
- package/substrate/standards/tech-stack-config.md +0 -109
- package/substrate/standards/tier-dependency-analysis.md +0 -167
- package/substrate/standards/tier-runtime-deps/lite.md +0 -57
- package/substrate/standards/tier-tag-schema.md +0 -155
- package/substrate/standards/two-layer-config.md +0 -99
- package/substrate/standards/use-case-format.md +0 -292
- package/substrate/standards/user-story-invest.md +0 -268
- package/substrate/standards/velocity-and-appetite.md +0 -229
- package/substrate/standards/voice-input-pattern.md +0 -119
- package/substrate/standards/whereami-schema.md +0 -301
- package/substrate/standards/worktree-management.md +0 -211
- package/substrate/standards/writing-guide.md +0 -213
- package/substrate/templates/chronicle-template.md +0 -75
- package/substrate/templates/deferred-action-template.md +0 -45
- package/substrate/templates/memory-proposal-template.md +0 -77
- package/substrate/templates/persona-template.md +0 -200
- package/substrate/templates/pr-faq.md +0 -45
- package/substrate/templates/secret-rotation-template.md +0 -162
- package/substrate/templates/spec-template.md +0 -131
- package/substrate/templates/use-case-template.md +0 -194
- package/substrate/templates/user-story-template.md +0 -107
- package/substrate/templates/whereami-template.md +0 -101
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
tier: lite
|
|
3
|
-
description: "When a hook emits the same BLOCKED signal across ≥3 consecutive sessions and the underlying state counter hasn't moved, the signal is stuck."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Stuck-Signal Diagnostic
|
|
7
|
-
|
|
8
|
-
When a hook emits the same BLOCKED signal across ≥3 consecutive sessions
|
|
9
|
-
and the underlying state counter hasn't moved, the signal is stuck.
|
|
10
|
-
A stuck signal is evidence of a **substrate defect**, not operator
|
|
11
|
-
error — the hook is correctly detecting a condition the fix path
|
|
12
|
-
cannot clear. Continuing to fire the same banner without reading the
|
|
13
|
-
mechanism that produces it reproduces the acknowledge-and-skip loop
|
|
14
|
-
`blocked-items.md` was built to close.
|
|
15
|
-
|
|
16
|
-
## When this rule fires
|
|
17
|
-
|
|
18
|
-
Any BLOCKED banner whose underlying counter / state has not advanced
|
|
19
|
-
across ≥3 sessions. Observable shapes:
|
|
20
|
-
|
|
21
|
-
- `BLOCKED: verify-compliance — X%` where X is identical 3 sessions running
|
|
22
|
-
- `BLOCKED: temperance-compliance — X%` where X is identical 3 sessions running
|
|
23
|
-
- `BLOCKED: metrics — DORA stale` with identical staleness counts
|
|
24
|
-
- `BLOCKED: release-notes — last entry N days ago` where N grows but no
|
|
25
|
-
release is written
|
|
26
|
-
- Any hook-surfaced BLOCKED whose associated counter/timestamp/state
|
|
27
|
-
is numerically or categorically unchanged across the last 3 chronicles
|
|
28
|
-
|
|
29
|
-
The operator does not need to flag the staleness. The agent must
|
|
30
|
-
self-detect by comparing current banner text against the prior
|
|
31
|
-
session's banner text (visible in chronicles or `/sprint` output).
|
|
32
|
-
|
|
33
|
-
## Mandatory mechanism-read
|
|
34
|
-
|
|
35
|
-
When stuck-signal is detected, the agent MUST:
|
|
36
|
-
|
|
37
|
-
1. **Stop addressing the symptom.** Do not propose running the usual
|
|
38
|
-
fix (e.g., "let me run /verify more diligently this session"). The
|
|
39
|
-
fix has been tried and the counter hasn't moved. That's the signal.
|
|
40
|
-
|
|
41
|
-
2. **Read the mechanism files named in the banner.** The hook banner
|
|
42
|
-
names the exact paths. Follow the paths. Read every one.
|
|
43
|
-
|
|
44
|
-
3. **Trace the counter's update path.** From mechanism-file read,
|
|
45
|
-
answer:
|
|
46
|
-
- Where is the counter computed?
|
|
47
|
-
- What state does the counter consume?
|
|
48
|
-
- What action updates that state?
|
|
49
|
-
- Is the update actually landing, or landing to a surface the
|
|
50
|
-
counter doesn't read?
|
|
51
|
-
|
|
52
|
-
4. **Fire /diagnose on the mechanism.** Treat the stuck signal as a
|
|
53
|
-
substrate failure per `diagnosis.md`. Is/Is-Not + Five Whys +
|
|
54
|
-
Hypothesis applied to the hook + state-file + update path — not to
|
|
55
|
-
the surface behavior.
|
|
56
|
-
|
|
57
|
-
5. **Resolve via substrate edit or escalate.** The fix is almost
|
|
58
|
-
always in the mechanism: wrong path, stale regex, counter reading
|
|
59
|
-
a location the writer stopped using, `/tmp` marker lost across
|
|
60
|
-
sandbox teardown. Edit the substrate, commit, verify the counter
|
|
61
|
-
advances. If substrate-read reveals no defect, escalate — the
|
|
62
|
-
counter is correct and the work is genuinely undone; `blocked-items.md`
|
|
63
|
-
default (resolve) applies.
|
|
64
|
-
|
|
65
|
-
## Post-resolution obligation: mandatory /promote
|
|
66
|
-
|
|
67
|
-
When mechanism-read reveals a substrate defect (hook path wrong,
|
|
68
|
-
state file rotted, marker format changed, compliance calc broken),
|
|
69
|
-
resolution MUST include firing `/promote` with the `substrate-defect`
|
|
70
|
-
classifier. See `blocked-items.md` §"When resolution reveals a
|
|
71
|
-
substrate defect" for the full protocol and `promote/SKILL.md` for
|
|
72
|
-
the template.
|
|
73
|
-
|
|
74
|
-
Fixing the local instance without promoting means the same defect
|
|
75
|
-
keeps firing in consumer repos — which is exactly the
|
|
76
|
-
acknowledge-and-skip loop at a different layer.
|
|
77
|
-
|
|
78
|
-
## Why this rule exists
|
|
79
|
-
|
|
80
|
-
2026-04-20 session end + 2026-04-21 session start (the loop that
|
|
81
|
-
motivated bet `2026-04-21a-blocked-signal-integrity`): session-rescue
|
|
82
|
-
hook fired 15 times in ≤4 hours, each session acknowledging the
|
|
83
|
-
deferred-actions BLOCKED block, resolving the nominal entry, and
|
|
84
|
-
shipping — only for the next stop to write a fresh rescue entry.
|
|
85
|
-
|
|
86
|
-
The counter ("15 deferred-action entries resolvable") stayed stuck
|
|
87
|
-
because resolution lived in the local session but the hook's
|
|
88
|
-
detection path rotted during `/tmp` sandbox teardown. The mechanism
|
|
89
|
-
file (`session-end.sh`) had a calendar-date chronicle check that fired
|
|
90
|
-
even when a fresh chronicle existed with a different date pattern —
|
|
91
|
-
a substrate defect that `/verify`-more-carefully could not clear.
|
|
92
|
-
|
|
93
|
-
Root cause: the agent kept "resolving" the surface while the
|
|
94
|
-
mechanism produced fresh false-positives. Three sessions of identical
|
|
95
|
-
banner text. The signal was stuck. Nobody read `session-end.sh`.
|
|
96
|
-
|
|
97
|
-
This rule removes the option to "try harder" when the counter hasn't
|
|
98
|
-
moved. If the counter is stuck, the fix is in the mechanism, not in
|
|
99
|
-
the work.
|
|
100
|
-
|
|
101
|
-
## Relationship to other rules
|
|
102
|
-
|
|
103
|
-
- `blocked-items.md` — the base BLOCKED-resolve-or-explicit-defer
|
|
104
|
-
protocol; stuck-signal is a specific escalation branch
|
|
105
|
-
- `diagnosis.md` — Is/Is-Not + Five Whys applies to the mechanism
|
|
106
|
-
when the signal is stuck
|
|
107
|
-
- `sdlc-gates.md` — observed failure → temperance → diagnose chain;
|
|
108
|
-
stuck-signal is an observed failure in the meta-signal layer
|
|
109
|
-
- `artifact-ingestion.md` — "read the file before producing" extends
|
|
110
|
-
to "read the mechanism before resolving"
|
|
111
|
-
- Post-resolution `/promote` obligation: `blocked-items.md` §"When
|
|
112
|
-
resolution reveals a substrate defect"
|
|
113
|
-
|
|
114
|
-
## Enforcement
|
|
115
|
-
|
|
116
|
-
Methodology-level. The compliance-counter hooks
|
|
117
|
-
(`session-reflection.d/40-gate-compliance.sh` and siblings) name
|
|
118
|
-
mechanism paths in their BLOCKED banners so the agent has the
|
|
119
|
-
literal file paths to read — no guessing about what "mechanism"
|
|
120
|
-
means. If stuck-signal recurs without mechanism-read in the next 6
|
|
121
|
-
months, upgrade to hook-enforced: refuse session advance until an
|
|
122
|
-
Edit tool call lands on the named mechanism path.
|
|
123
|
-
|
|
124
|
-
## Override
|
|
125
|
-
|
|
126
|
-
There is no override. Stuck-signal is the condition under which
|
|
127
|
-
"proceed and try again" is the failure mode. If the counter is
|
|
128
|
-
stuck, the agent reads the mechanism. Full stop.
|
|
129
|
-
|
|
130
|
-
Operator may still explicitly defer the underlying BLOCKED item per
|
|
131
|
-
`blocked-items.md` deferral syntax ("skip metrics this session") —
|
|
132
|
-
but the mechanism-read obligation still fires the next session unless
|
|
133
|
-
the operator also defers that (rare, e.g., "mechanism-read next
|
|
134
|
-
week, I'm unblocking you manually this time").
|
|
135
|
-
|
|
136
|
-
## Retirement condition
|
|
137
|
-
|
|
138
|
-
If counter-stuck incidents fall to zero for 12 months with no
|
|
139
|
-
operator-flagged false-negatives, this rule has done its job.
|
|
140
|
-
Retirement candidate — the methodology-layer habit is durable.
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
tier: lite
|
|
3
|
-
globs: ["substrate.config.md", "substrate.secrets.md", ".claude/skills/**/*.md", ".claude/hooks/**/*", "standards/**/*.md"]
|
|
4
|
-
description: Substrate config + secrets schemas — single source of truth for external resource references and secret lifecycle
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Substrate Config + Secrets Schema (rule)
|
|
8
|
-
|
|
9
|
-
Two paired files; each owns one concern:
|
|
10
|
-
|
|
11
|
-
| File | Owns | Standard |
|
|
12
|
-
|------|------|----------|
|
|
13
|
-
| `substrate.config.md` | External resource *references* (Google Doc IDs, URLs, repo refs, env-var names) | `standards/substrate-config-schema.md` |
|
|
14
|
-
| `substrate.secrets.md` | Secret *lifecycle* (rotation cadence, expiry, runbooks, health checks) | `standards/secrets-lifecycle.md` |
|
|
15
|
-
|
|
16
|
-
Both are read at session-start; agents always source from these files.
|
|
17
|
-
|
|
18
|
-
INSTEAD of memory or hardcoded values: read at session-start from
|
|
19
|
-
`substrate.config.md` (resources) and `substrate.secrets.md` (lifecycle).
|
|
20
|
-
|
|
21
|
-
## Agent behavior rules
|
|
22
|
-
|
|
23
|
-
1. **Read resources only from `substrate.config.md`.** When a skill
|
|
24
|
-
or hook needs a doc ID, URL, or similar reference, the agent
|
|
25
|
-
reads it from this file at runtime. Don't hardcode. Don't cache.
|
|
26
|
-
|
|
27
|
-
INSTEAD: read at runtime from `substrate.config.md`. Field name is
|
|
28
|
-
the interface; raw value is implementation detail that can change.
|
|
29
|
-
|
|
30
|
-
2. **Reference by field name, not by raw value.** In project memory,
|
|
31
|
-
in chronicles, in commit messages: say `brand_corpus_doc_id`, not
|
|
32
|
-
`1gps7mmEYBCud...`. The raw value is an implementation detail;
|
|
33
|
-
the field name is the interface.
|
|
34
|
-
|
|
35
|
-
3. **When a resource is missing**, prompt the operator to add it to
|
|
36
|
-
`substrate.config.md` with a typed field name. Use the suffix
|
|
37
|
-
convention: `*_doc_id`, `*_url`, `*_repo`, `*_path`, `*_token_name`,
|
|
38
|
-
etc. (full list in the standard).
|
|
39
|
-
|
|
40
|
-
4. **No raw secrets in `substrate.config.md`.** That file is
|
|
41
|
-
committed to git. Store the *name* of the env var holding the
|
|
42
|
-
secret (`anthropic_key_name: ANTHROPIC_API_KEY`).
|
|
43
|
-
|
|
44
|
-
INSTEAD of inlining the secret value: keep values in their
|
|
45
|
-
authoritative storage (1Password / GitHub Actions Secrets /
|
|
46
|
-
AWS Secrets Manager / `.env`); the config file points by name.
|
|
47
|
-
|
|
48
|
-
5. **Secret *lifecycle* belongs in `substrate.secrets.md`**, not
|
|
49
|
-
`substrate.config.md`. References go in config; rotation cadence,
|
|
50
|
-
expiry dates, runbook paths, and health-check commands go in
|
|
51
|
-
secrets. Each file owns its concern.
|
|
52
|
-
|
|
53
|
-
INSTEAD of mixing concerns: lifecycle metadata (last_rotated,
|
|
54
|
-
expiry_at, rotation_procedure) lives in `substrate.secrets.md`;
|
|
55
|
-
resource references (doc IDs, URLs, env-var names) live in
|
|
56
|
-
`substrate.config.md`. Cross-reference between the two files.
|
|
57
|
-
|
|
58
|
-
6. **No secret VALUES anywhere in the repo.** `substrate.secrets.md`
|
|
59
|
-
tracks references and metadata only — values stay in their
|
|
60
|
-
authoritative storage (1Password / GitHub Actions Secrets / `.env`
|
|
61
|
-
/ AWS Secrets Manager). The session-start hook
|
|
62
|
-
(`.claude/hooks/session-reflection.d/90-secrets-expiry.sh`) surfaces
|
|
63
|
-
BLOCKED when any secret is within `alert_threshold_days`; resolve
|
|
64
|
-
per the entry's `rotation_procedure` runbook.
|
|
65
|
-
|
|
66
|
-
7. **When migrating old code**, replace hardcoded IDs with
|
|
67
|
-
`substrate.config.md` lookups. Grep for the raw ID value across
|
|
68
|
-
`.claude/`, `standards/`, `strategy/`, and the raw content of
|
|
69
|
-
project memory. Replace with field-name reference.
|
|
70
|
-
|
|
71
|
-
## Why this rule exists
|
|
72
|
-
|
|
73
|
-
Before this rule (learned 2026-04-12):
|
|
74
|
-
- Brand corpus doc ID lived in project memory
|
|
75
|
-
- Hardcoded in `/journal-export` skill
|
|
76
|
-
- Also referenced indirectly in other places
|
|
77
|
-
- Agent pushed to wrong doc, operator caught the mismatch, hours of
|
|
78
|
-
confusion and re-pushing followed
|
|
79
|
-
|
|
80
|
-
After: one place. Typed. Skills read at runtime. Memory points by
|
|
81
|
-
name. Agents can't confuse which doc is which because there's only
|
|
82
|
-
one source.
|
|
83
|
-
|
|
84
|
-
## Bootstrap path for new repos
|
|
85
|
-
|
|
86
|
-
When `/autonomous start` scaffolds a new repo's `substrate.config.md`,
|
|
87
|
-
it prompts for every known resource field (per the standard's "Known
|
|
88
|
-
fields" section). Operators can skip (defaults apply), but each known
|
|
89
|
-
field is surfaced once so nothing gets stored in memory or hardcoded
|
|
90
|
-
by accident.
|
|
91
|
-
|
|
92
|
-
## Related
|
|
93
|
-
|
|
94
|
-
- `standards/substrate-config-schema.md` — full standard
|
|
95
|
-
- `.claude/skills/autonomous/SKILL.md` — scaffold prompts for
|
|
96
|
-
each known field
|
|
97
|
-
- `.claude/skills/substrate-check/SKILL.md` — can validate config schema
|
|
98
|
-
compliance in a repo
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
tier: lite
|
|
3
|
-
description: "Every test file opens with a # test-list: commented block enumerating the assertions the step owes."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Test-List Discipline
|
|
7
|
-
|
|
8
|
-
Every test file opens with a `# test-list:` commented block enumerating
|
|
9
|
-
the assertions the step owes. Each line is one intended assertion,
|
|
10
|
-
written before any source is edited. Implemented assertions get `[x]`;
|
|
11
|
-
pending stay `[ ]`. Remaining `[ ]` lines visible at commit time are
|
|
12
|
-
honest in-flight signal — truth about what is still owed.
|
|
13
|
-
|
|
14
|
-
This rule is the **planning layer** of TDD discipline. The Tier 0 hook
|
|
15
|
-
(bassclef#1037) enforces test presence + recency: test file exists, test
|
|
16
|
-
mtime ≤ source mtime. That catches tests written after source. It does
|
|
17
|
-
not catch tests written before source that miss intended assertions.
|
|
18
|
-
|
|
19
|
-
INSTEAD: Beck's test list surfaces intent as a tangible artifact at the
|
|
20
|
-
top of the test file, where reviewer and future-reader can see what was
|
|
21
|
-
considered AND deferred vs what was missed entirely.
|
|
22
|
-
|
|
23
|
-
## Why this rule exists
|
|
24
|
-
|
|
25
|
-
Bassclef adopts Kent Beck as the TDD anchor — Tier 0 enforces his
|
|
26
|
-
red-green-refactor cycle mechanically. The Tier 0 framing came from
|
|
27
|
-
*Test-Driven Development By Example* chapter on cycle discipline.
|
|
28
|
-
Beck's same book opens (chapters 1-3) with the test list as a separate
|
|
29
|
-
discipline: write the list of tests you intend to write BEFORE you
|
|
30
|
-
start; cross off as you go; add new tests to the list as they surface.
|
|
31
|
-
|
|
32
|
-
Bassclef imported the cycle without importing the planning artifact.
|
|
33
|
-
Result: agents (and operators) write a test, see it pass, ship — and
|
|
34
|
-
the next reader has no record of which assertions were considered AND
|
|
35
|
-
deferred vs which were missed entirely. The two collapse into silence.
|
|
36
|
-
|
|
37
|
-
INSTEAD: the test-list block at the top of every test file makes the
|
|
38
|
-
record visible. Considered-and-deferred assertions live as `[~]` lines
|
|
39
|
-
with one-line reasons; missed assertions get added as `[ ]` lines as
|
|
40
|
-
soon as a reviewer or later reader notices them.
|
|
41
|
-
|
|
42
|
-
Surfaced 2026-06-17 during /longrun prep when operator pushed twice on
|
|
43
|
-
"feels incomplete" sufficiency framing. The mechanical sufficiency
|
|
44
|
-
criteria (sister test-sufficiency rule) IS the answer to what to assert;
|
|
45
|
-
the test list IS the answer to whether you covered the intent. Both are
|
|
46
|
-
required.
|
|
47
|
-
|
|
48
|
-
## Format contract
|
|
49
|
-
|
|
50
|
-
Every test file (any file matching `*test*.sh`, `*.test.*`, `test_*.py`,
|
|
51
|
-
`*_test.go`, etc. depending on stack) opens with this block before any
|
|
52
|
-
test code:
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
# test-list:
|
|
56
|
-
# [x] Skip case: empty stdin returns exit 0
|
|
57
|
-
# [x] Skip case: non-matching tool_name returns exit 0
|
|
58
|
-
# [ ] Behavior: matched tool with valid input writes marker
|
|
59
|
-
# [ ] Behavior: matched tool with invalid input returns exit 3 with stderr
|
|
60
|
-
# [ ] Override: SKIP_FOO=1 bypasses and logs to trace
|
|
61
|
-
# [ ] Edge: missing external binary (jq) returns exit 0 with warning
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Rules:
|
|
65
|
-
|
|
66
|
-
- `# test-list:` is the literal marker (greppable; future hook reads it)
|
|
67
|
-
- One assertion per line; `[ ]` pending, `[x]` implemented
|
|
68
|
-
- Each line is one sentence in plain English describing the assertion
|
|
69
|
-
- Lines added as new assertions surface during implementation (the list grows)
|
|
70
|
-
- Lines stay in place when an assertion turns out not to apply — mark `[~]` with one-line reason inline.
|
|
71
|
-
|
|
72
|
-
INSTEAD of removing the line: keep the `[~]` record so future-reader sees the assertion was considered and judged not-applicable, with the reason. Removal loses the consideration history.
|
|
73
|
-
|
|
74
|
-
- The block lives at the top of the test file, before any source code
|
|
75
|
-
|
|
76
|
-
## What this rule requires
|
|
77
|
-
|
|
78
|
-
When authoring or extending a test file:
|
|
79
|
-
|
|
80
|
-
1. **Before writing any test code**, write the `# test-list:` block enumerating intended assertions. Use the test-sufficiency rubric (sister rule) as the source for what categories of assertion a hook test needs.
|
|
81
|
-
2. **As each assertion is implemented**, change its `[ ]` to `[x]` in the same commit that ships the test.
|
|
82
|
-
3. **If new assertions surface during implementation**, add them to the list as `[ ]` lines. The list grows; that is honest signal.
|
|
83
|
-
4. **Before commit**, scan remaining `[ ]` lines. Each is either:
|
|
84
|
-
- Implemented in this commit (mark `[x]`)
|
|
85
|
-
- Genuinely deferred (mark `[~]` with one-line reason; commit that reason as the file's record)
|
|
86
|
-
- Required but missed — write the assertion now and mark `[x]`.
|
|
87
|
-
|
|
88
|
-
INSTEAD of committing with the line as `[ ]` when the assertion is owed by THIS commit: write the assertion, mark `[x]`, then commit. Pending lines are for genuinely-next-commit work.
|
|
89
|
-
|
|
90
|
-
## What satisfies the rule
|
|
91
|
-
|
|
92
|
-
A test file is conformant when:
|
|
93
|
-
|
|
94
|
-
- Top of file has `# test-list:` block
|
|
95
|
-
- Every line in the block has `[x]`, `[ ]`, or `[~]` prefix
|
|
96
|
-
- Every `[x]` line maps to at least one test function in the file
|
|
97
|
-
- Every `[~]` line has a one-line reason inline
|
|
98
|
-
- Pending `[ ]` lines at commit time are intentional (operator-visible signal that work continues)
|
|
99
|
-
|
|
100
|
-
## Anti-shapes (what fails the rule)
|
|
101
|
-
|
|
102
|
-
The hook-future-extension will BLOCK at these shapes. For now, reviewer + agent self-check.
|
|
103
|
-
|
|
104
|
-
- A test file with no `# test-list:` block at all.
|
|
105
|
-
|
|
106
|
-
INSTEAD: add the block before committing; even retrofitting a list from an existing test file's contents is better than missing one, because the act of writing the list surfaces assertions the existing tests missed.
|
|
107
|
-
|
|
108
|
-
- A test file with a block that contains only `[x]` lines while obvious assertions are missing.
|
|
109
|
-
|
|
110
|
-
INSTEAD: surface the gap by adding `[ ]` lines for the missing assertions; the visible gap is the call-to-action for the next commit.
|
|
111
|
-
|
|
112
|
-
- A `[~]` line without inline reason.
|
|
113
|
-
|
|
114
|
-
INSTEAD: add the one-line reason in the same commit that marks the line `[~]`; the reason IS the audit trail.
|
|
115
|
-
|
|
116
|
-
- A `[x]` line with no matching test function.
|
|
117
|
-
|
|
118
|
-
INSTEAD: either implement the test function (if the assertion was meant to ship) OR change `[x]` to `[~]` with reason (if the assertion turned out not to apply).
|
|
119
|
-
|
|
120
|
-
## When this rule fires
|
|
121
|
-
|
|
122
|
-
Auto-loaded into every session via `additionalDirectories`. Agents
|
|
123
|
-
self-check before committing any test file. The Tier 0 hook
|
|
124
|
-
(`testing-tier-enforce.sh`) does not currently enforce this block.
|
|
125
|
-
|
|
126
|
-
INSTEAD: methodology-level enforcement via agent + reviewer attention.
|
|
127
|
-
Mechanical extension deferred to follow-on ticket; see V2 section below.
|
|
128
|
-
|
|
129
|
-
## V2 — mechanical extension (deferred)
|
|
130
|
-
|
|
131
|
-
When operator observes recurring drift from manual self-check, file a
|
|
132
|
-
follow-on ticket extending Tier 0 hook with a grep for `# test-list:`
|
|
133
|
-
block in any test file being committed. BLOCK when missing. Allowlist
|
|
134
|
-
existing test files in a sister `.claude/hooks/test-list-allowlist.txt`
|
|
135
|
-
with grace window (same pattern as Phase A shellcheck-allowlist).
|
|
136
|
-
|
|
137
|
-
For now: methodology layer. Reviewer + agent self-check.
|
|
138
|
-
|
|
139
|
-
## Override
|
|
140
|
-
|
|
141
|
-
`SKIP_TEST_LIST=1` — logged via trace-helper per bassclef hook
|
|
142
|
-
override idiom. Use only for migration commits backfilling old test
|
|
143
|
-
files OR for emergency rescue when the rule itself appears wrong.
|
|
144
|
-
|
|
145
|
-
INSTEAD of overriding for routine work: write the test-list block. The
|
|
146
|
-
block costs ~30 seconds of typing; the override cost compounds across
|
|
147
|
-
every consumer repo's reviewer attention.
|
|
148
|
-
|
|
149
|
-
## Composes with
|
|
150
|
-
|
|
151
|
-
- `.claude/rules/testing-tier-config.md` — Tier 0 enforces presence + recency; this adds intent transparency
|
|
152
|
-
- `.claude/rules/test-sufficiency.md` — 10-criterion mechanical sufficiency rubric; supplies WHAT to assert; this supplies HOW to track
|
|
153
|
-
- `.claude/rules/testing.md` — what makes a good test (test-content guidance); this adds the planning artifact
|
|
154
|
-
- `@luminary kent-beck` — TDD anchor; chapters 1-3 of TDD By Example are the bassclef source
|
|
155
|
-
|
|
156
|
-
## Distinct from
|
|
157
|
-
|
|
158
|
-
- `testing-tier-config.md` — about WHICH paths require which tier of enforcement
|
|
159
|
-
- `testing.md` — about what makes a test good once you write it
|
|
160
|
-
- `test-sufficiency.md` — about what categories of assertion to consider
|
|
161
|
-
- `iteration-bet-brief-completeness.md` — about handoff brief completeness; different scope
|
|
162
|
-
|
|
163
|
-
## Refs
|
|
164
|
-
|
|
165
|
-
- bassclef#1090 — this rule's filing ticket
|
|
166
|
-
- bassclef#1037 — Tier 0 strict-TDD discipline (Phase A); this extends with intent transparency
|
|
167
|
-
- bassclef#867 — anchor-luminary verification pattern (Beck as TDD anchor)
|
|
168
|
-
- Beck — Test-Driven Development By Example (Addison-Wesley, 2002), chapters 1-3
|
|
169
|
-
- `docs/iteration-bets/2026-06-17b-sufficiency-rubric-plus-hardening-longrun.md` — goal authoring this rule
|
|
170
|
-
|
|
171
|
-
## Retirement condition
|
|
172
|
-
|
|
173
|
-
This rule retires only if bassclef migrates off TDD as a primary
|
|
174
|
-
discipline. The test list as a planning artifact survives any specific
|
|
175
|
-
test-framework or tier-config evolution.
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
tier: lite
|
|
3
|
-
description: The Tier 0 hook (bassclef#1037) enforces test PRESENCE + RECENCY.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Test Sufficiency Rubric
|
|
7
|
-
|
|
8
|
-
The Tier 0 hook (bassclef#1037) enforces test PRESENCE + RECENCY. The test file exists. Its mtime is at least as new as the source file's. That catches tests written after source. It catches zero things about whether the test ASSERTS ENOUGH.
|
|
9
|
-
|
|
10
|
-
This rule codifies the 12 mechanical criteria the agent applies before committing any test file. Each criterion is greppable, countable, and verifiable against the source it tests. Together they form the sufficiency contract for bassclef's Tier 0 hooks, state-spine accessors, and adopter-stack code where systematic discipline earns its keep.
|
|
11
|
-
|
|
12
|
-
INSTEAD of relying on "feels complete" — the squishy framing that surfaced this gap during /longrun prep 2026-06-17 — the agent applies the 12 criteria mechanically. The agent marks each as covered or deferred with reason in the test-list block (bassclef#1090) and ships the result.
|
|
13
|
-
|
|
14
|
-
## Anchor luminaries
|
|
15
|
-
|
|
16
|
-
- `@luminary kent-beck` — TDD rhythm anchor; test list is the planning artifact this rubric assumes
|
|
17
|
-
- `@luminary glenford-myers` — Coverage taxonomy anchor; criteria 1-4 are direct applications of Myers's 1979 categories
|
|
18
|
-
- `@luminary tony-hoare` — Contract testing anchor; criteria 5-10 are precondition / postcondition / invariant assertions in disguise
|
|
19
|
-
|
|
20
|
-
The rubric is what each luminary's lens produces when applied to a bassclef bash hook or state-spine accessor. The substrate operationalizes the discipline; the luminaries supply the why.
|
|
21
|
-
|
|
22
|
-
## The 12 criteria
|
|
23
|
-
|
|
24
|
-
### 1. Branch coverage (Myers — decision coverage)
|
|
25
|
-
|
|
26
|
-
Every branch in the source has at least one test that exercises it. Mechanically: `grep -cE '^\s*(if|elif|else|case|\|\|)' <source>` counts decision points; the test file owes that many `[x]` lines minimum.
|
|
27
|
-
|
|
28
|
-
Example for `auto-save-idle.sh` with 4 branches (no-changes / lock-present / defer-present / proceed): the test file owes 4 tests minimum to satisfy decision coverage alone.
|
|
29
|
-
|
|
30
|
-
INSTEAD of one test that covers the happy path: one test per branch. The marginal cost per test is small at write-time and compounds across every consumer adopting the hook.
|
|
31
|
-
|
|
32
|
-
### 2. Exit code matrix (Hoare — postcondition)
|
|
33
|
-
|
|
34
|
-
Every distinct `exit N` in the source has at least one test that triggers that exit and asserts the code matches. Mechanically: `grep -oE 'exit [0-9]+' <source> | sort -u` enumerates the codes; the test file owes one assertion per code.
|
|
35
|
-
|
|
36
|
-
Example: `pre-commit-gate.sh` has `exit 0` (pass), `exit 2` (BLOCK), `exit 3` (validation fail). Test file asserts each appears under the input that triggers it.
|
|
37
|
-
|
|
38
|
-
INSTEAD of asserting only success exit: one assertion per distinct exit code. Exit codes ARE the hook's postcondition contract with the harness; the test list owes one Hoare-style `{P} S {Q-exit-N}` triple per code.
|
|
39
|
-
|
|
40
|
-
### 3. Tool-name matcher (Myers — equivalence partitioning)
|
|
41
|
-
|
|
42
|
-
For hooks matching on `tool_name`, the test file has one test per matched tool AND at least one non-matched tool asserting pass-through. Each matched tool is one equivalence class; the non-matched set is another class with one representative.
|
|
43
|
-
|
|
44
|
-
Example: `pre-commit-gate.sh` matches `Edit|Write|MultiEdit`. Test file owes: Edit-fires test, Write-fires test, MultiEdit-fires test, Bash-pass-through test, NotebookEdit-pass-through test.
|
|
45
|
-
|
|
46
|
-
INSTEAD of asserting only the matched class: cover both halves of the discriminator. Pass-through tests catch matcher regressions that would silently expand the hook's surface.
|
|
47
|
-
|
|
48
|
-
### 4. Path-matcher coverage (Myers — boundary value)
|
|
49
|
-
|
|
50
|
-
For hooks matching on file paths or globs, the test file has a positive test (path matches) AND a near-miss negative test (similar path doesn't match) per glob. Boundary value applied to string-shape inputs.
|
|
51
|
-
|
|
52
|
-
Example: hook matches `state/markers/temperance/*.marker`. Positive test: `state/markers/temperance/foo.marker`. Near-miss tests: `state/markers/temperance/foo` (no extension), `state/markers/temperance-x/foo.marker` (similar dir name), `state/temperance/foo.marker` (missing markers segment).
|
|
53
|
-
|
|
54
|
-
INSTEAD of asserting only the matched path: near-miss tests catch glob bugs that would either widen or narrow the matcher unexpectedly.
|
|
55
|
-
|
|
56
|
-
### 5. Override path (Hoare — alternative precondition)
|
|
57
|
-
|
|
58
|
-
Every `SKIP_*` env var bypass in the source has one test that exercises the override AND asserts the override path fires (logged via trace-helper, hook exits with pass code, side effects suppressed).
|
|
59
|
-
|
|
60
|
-
Example: `auto-save-idle.sh` honors `SKIP_AUTO_SAVE=1`. Test file owes: with-flag-set test (asserts no-commit + trace log emission), without-flag test (asserts normal path).
|
|
61
|
-
|
|
62
|
-
INSTEAD of treating override paths as unused: they are alternative preconditions in Hoare's framing. Each override is a `{P-skip-set} S {Q-bypass}` triple the test list owes one entry for.
|
|
63
|
-
|
|
64
|
-
### 6. stdin contract (Hoare — precondition discipline)
|
|
65
|
-
|
|
66
|
-
The hook reads JSON from the harness via stdin. Each discriminated input shape (different `tool_input` fields, different content shapes) has one test that exercises it.
|
|
67
|
-
|
|
68
|
-
Example: `pre-commit-gate.sh` discriminates on `tool_input.file_path` (string) and absent (some Edit calls omit it). Test file owes: file_path-present test, file_path-absent test, malformed-JSON test (graceful error path).
|
|
69
|
-
|
|
70
|
-
INSTEAD of asserting only the well-formed input: malformed JSON is a precondition violation the hook must handle without crashing. Tests assert the hook reports the violation rather than crashing the harness.
|
|
71
|
-
|
|
72
|
-
### 7. External-binary handling (Hoare — invariant under environment variation)
|
|
73
|
-
|
|
74
|
-
For every external call (`jq`, `gh`, `git`, `flock`, `python3`, etc.), tests either mock the binary OR exercise a graceful-missing test asserting the hook handles binary-absent without crashing.
|
|
75
|
-
|
|
76
|
-
Example: hook calls `jq` to parse JSON. Test file owes: jq-present happy-path test, jq-missing test (asserts hook detects and exits with informative stderr OR falls back to bash-native parsing).
|
|
77
|
-
|
|
78
|
-
INSTEAD of assuming every adopter environment has every binary: external binaries are an environmental precondition the hook should fail soft against. Bassclef-internal hooks may assume `jq` (Tier 0). Adopter-distributed hooks should not.
|
|
79
|
-
|
|
80
|
-
### 8. Trap / cleanup (Hoare — class invariant via `trap EXIT`)
|
|
81
|
-
|
|
82
|
-
Sources that use `trap '...' EXIT` (per defensive-bash.md) need two tests: one exercises the success path (verify cleanup ran) AND one exercises a failure path (verify cleanup still ran).
|
|
83
|
-
|
|
84
|
-
Example: hook acquires `flock` and uses `trap "flock -u" EXIT`. Test file owes: success-path test (verify lock released on normal exit), failure-path test (verify lock released when hook fails mid-execution).
|
|
85
|
-
|
|
86
|
-
INSTEAD of trusting `trap` works by inspection: the trap IS the class invariant; the test verifies the invariant holds across both observable paths. Trap regressions silently leak resources.
|
|
87
|
-
|
|
88
|
-
### 9. stderr format (Hoare — postcondition contract for BLOCK exits)
|
|
89
|
-
|
|
90
|
-
For BLOCK exits (code 2 or 3), the test asserts the stderr message contains the required structured fields per `.claude/rules/blocked-items.md`: entity type, path being acted on, ajv error details (when applicable), three resolution paths.
|
|
91
|
-
|
|
92
|
-
Example: `state-validate.sh` BLOCKs on schema failure. Test file owes: BLOCK-exit test asserts stderr contains "Entity type:", "Path:", "ajv:", and the three resolution-path lines.
|
|
93
|
-
|
|
94
|
-
INSTEAD of asserting only exit code on BLOCK: the stderr message IS the contract with the agent. A BLOCK with empty stderr is a worse failure than no BLOCK at all — the agent loses the remediation path.
|
|
95
|
-
|
|
96
|
-
### 10. State-file interactions (Hoare — postcondition on side effects)
|
|
97
|
-
|
|
98
|
-
For hooks that read or write markers in `state/markers/` (or any state file), tests cover both read paths and write paths. Read-path test: state file present in expected shape → hook reads correctly. Write-path test: hook write completes → file content matches the expected shape.
|
|
99
|
-
|
|
100
|
-
Example: `pre-commit-gate.sh` reads `state/markers/temperance/<branch-slug>.marker`. Test file owes: marker-present test (verify hook reads + passes), marker-absent test (verify hook BLOCKs + writes BLOCKED stderr), marker-malformed test (verify hook fails-soft with informative error).
|
|
101
|
-
|
|
102
|
-
INSTEAD of testing only the read OR only the write: state-file interactions are bidirectional contracts. Skipping the write-path test means schema drift between writer and reader goes unnoticed until production.
|
|
103
|
-
|
|
104
|
-
### 11. Path resolution under both install classes (Hoare — invariant under install layout; added bet 27c WU-9)
|
|
105
|
-
|
|
106
|
-
For hooks that read project resources (standards files, configs, libs) AND declare `# install-class: dual` per `standards/hook-install-class.md`, tests pin behavior under both install layouts. Project class (CLAUDE_PROJECT_DIR set). Operator class (HOME_OVERRIDE pointing at fixture user-install layout). Mechanically: at least one test per resource read that fires under each layout.
|
|
107
|
-
|
|
108
|
-
Example: `turn-prose-kiss-check.sh` reads `standards/bassclef-internal-jargon.md` via `resolve_standards_path` from `lib/hook-inject.sh`. The test file owes four tests — Test 54 (CLAUDE_PROJECT_DIR layer 1), Test 55 (KISS_STANDARDS_FILE env layer 2), Test 56 (HOME_OVERRIDE layer 3), Test 57 (all layers fail; defensive fallback). PR #427 ships exactly those four tests.
|
|
109
|
-
|
|
110
|
-
INSTEAD of testing only project install: install class is an environmental precondition the hook MUST honor under both layouts. Skipping the operator install test produces the silent fail pattern that surfaced 2026-06-27 (kiss path resolution defect; chronicle Gate Evidence row 1). The cure pattern (HOME_OVERRIDE fixture + Tests 54-57 shape) is reusable across every dual-class hook.
|
|
111
|
-
|
|
112
|
-
This criterion fires when the source under test declares `install-class: dual` (most steering hooks; some adopter-distributed project hooks). Source declares `install-class: project` only → criterion does not fire. Project resources always resolve cleanly under project install.
|
|
113
|
-
|
|
114
|
-
### 12. Invocation-mode variation for coordinated fragments (Feathers + Hoare — invariant under invocation mode; added bet 2026-07-30c WU-3)
|
|
115
|
-
|
|
116
|
-
For modules invoked by a coordinator (fragments under `session-reflection.d/`, `pre-commit-hooks.d/`, or any `*.d/` directory that a parent hook sources), tests pin behavior under BOTH invocation modes:
|
|
117
|
-
|
|
118
|
-
- **Standalone**: `bash "$module"` — exit codes propagate normally; the module runs as its own process
|
|
119
|
-
- **Sourced**: coordinator sources the module under `set -e`; the module MUST use `return` (or safe dual form) not `exit`, else the coordinator dies with the module's exit code
|
|
120
|
-
|
|
121
|
-
Mechanically: at least one test per fragment that (a) sources it under a set -e wrapper and asserts a canary after the source fires, and (b) invokes it standalone via bash and asserts no "return: can only" error appears in stderr.
|
|
122
|
-
|
|
123
|
-
Example: `.claude/hooks/session-reflection.d/*.sh` fragments. Test file `.claude/hooks/tests/session-reflection-coordinator-full.test.sh` (bet 2026-07-30c WU-1) runs Class A (sourced-parent-survives) plus Class B (standalone-no-return-error) for every fragment. The wrapper injects the coordinator-side helpers (`blocked_banner`, `trace_log`, `BASSCLEF_DIR`) as stubs so the fragment's contract with the parent scope is honored during the test.
|
|
124
|
-
|
|
125
|
-
INSTEAD of trusting that `exit` in a sourced file is fine: sourced `exit` kills the parent process silently. The class shipped in PR #542 (2026-06-30 — `05-active-bet.sh`) and cost 36 days of silent session-start check skips in every adopter session until PR #992 cured 2026-07-30. Criterion 12 exists so the class cannot recur — every new fragment PR ships with sourced-parent-survives AND standalone-no-return-error assertions.
|
|
126
|
-
|
|
127
|
-
This criterion fires when the source lives under a `*.d/` directory whose parent hook sources fragments in a loop. Detection: the source directory name ends in `.d/` AND at least one sibling `.sh` file in the parent directory sources files from that directory. Adopter-authored fragments that plug into bassclef coordinators inherit this criterion at PR time.
|
|
128
|
-
|
|
129
|
-
Coordinator-side coupling note: fragments frequently call helper functions the coordinator defines (e.g., `blocked_banner`, `trace_log`) and read environment variables the coordinator exports (e.g., `BASSCLEF_DIR`). The invocation-mode test wrapper MUST inject these helpers as stubs so the test characterizes the fragment under conditions matching real coordinator invocation. Skipping the stubs produces false-red on any fragment that calls a coordinator helper.
|
|
130
|
-
|
|
131
|
-
## How to apply the rubric
|
|
132
|
-
|
|
133
|
-
1. **Before writing any test**, list applicable criteria for the source under test. Some hooks have all 10; some (pure-function libraries) have fewer (no stdin contract, no override path).
|
|
134
|
-
2. **Open the test file with the test-list block** (bassclef#1090). Use one `[ ]` line per criterion-derived assertion.
|
|
135
|
-
3. **Implement each assertion**, marking `[x]` as each ships. Add new `[ ]` lines as additional cases surface during implementation.
|
|
136
|
-
4. **Before commit**, scan the test-list for `[ ]` lines. Each is either:
|
|
137
|
-
- Implemented in this commit (mark `[x]`)
|
|
138
|
-
- Genuinely deferred (mark `[~]` with one-line reason per test-list-discipline.md)
|
|
139
|
-
- Required but missed (write the assertion now; do not commit with the line as `[ ]` when it should be `[x]`)
|
|
140
|
-
5. **Verify mechanical counts** for criteria 1, 2, 7: branch count, exit count, external-binary count. The test count must equal or exceed each source count.
|
|
141
|
-
|
|
142
|
-
INSTEAD of relying on "feels complete": each criterion has a greppable verification. If the test file has fewer `[x]` lines than the source has branches, the rubric is not satisfied. Concrete, mechanical, auditable.
|
|
143
|
-
|
|
144
|
-
## What the rubric does NOT cover
|
|
145
|
-
|
|
146
|
-
- **Test rhythm** — when to write tests (route to Beck via `testing-tier-config.md` Tier 0)
|
|
147
|
-
- **Test quality** — what makes a test well-written (route to `.claude/rules/testing.md`)
|
|
148
|
-
- **Test design** — whether the source's shape makes testing easy or hard (route to Ousterhout via `john-ousterhout.md`)
|
|
149
|
-
- **Property-based testing** — coverage of input space via QuickCheck-style generators (future addition if a stack adopts it; not in bassclef's bash substrate today)
|
|
150
|
-
- **Multi-fragment coordinator interactions** — how fragment N's side effects change fragment N+1's behavior (route to integration tests at the coordinator level, e.g., `session-reflection-coordinator.test.sh` per PR #992; criterion 12 covers per-fragment invocation-mode contract only)
|
|
151
|
-
|
|
152
|
-
INSTEAD of folding these into the rubric: each routes to a sister discipline. The rubric is sufficiency at the assertion-category layer; quality and rhythm and design are different surfaces.
|
|
153
|
-
|
|
154
|
-
## Override
|
|
155
|
-
|
|
156
|
-
`SKIP_TEST_SUFFICIENCY=1 <command>` — logged via trace-helper. Use only for one-shot migration scripts, emergency rescue, or when adding the assertion would require infrastructure not yet in place (file follow-on ticket).
|
|
157
|
-
|
|
158
|
-
INSTEAD of overriding for routine work: write the assertion. Each criterion costs minutes at write-time; each missed assertion costs hours of debugging when it ships.
|
|
159
|
-
|
|
160
|
-
## When this rule fires
|
|
161
|
-
|
|
162
|
-
Auto-loaded into every session via `additionalDirectories`. Agents self-check before committing any test file. The Tier 0 hook (`testing-tier-enforce.sh`) does not currently enforce the rubric mechanically.
|
|
163
|
-
|
|
164
|
-
INSTEAD: methodology layer with reviewer + agent self-check. V2 mechanical extension deferred to follow-on ticket. Count-based criteria (1, 2, 7) are auto-verifiable via the existing Tier 0 hook with a grep extension.
|
|
165
|
-
|
|
166
|
-
## V2 — mechanical extension (deferred)
|
|
167
|
-
|
|
168
|
-
The operator files a follow-on ticket to extend the Tier 0 hook when recurring drift shows up in manual self-check. The follow-on covers:
|
|
169
|
-
|
|
170
|
-
- Branch count: grep source for decision points; count test `[x]` lines; BLOCK when test count < branch count
|
|
171
|
-
- Exit code matrix: grep source for `exit N`; verify test asserts each
|
|
172
|
-
- External binary handling: grep source for external calls; verify test mocks or graceful-missing path exists per call
|
|
173
|
-
|
|
174
|
-
Subjective criteria (3-6, 8-10) stay methodology-only. Beck + Myers + Hoare's disciplines pair best with reviewer judgment for those; mechanical enforcement at the subjective layer produces gaming, not quality.
|
|
175
|
-
|
|
176
|
-
## Composes with
|
|
177
|
-
|
|
178
|
-
- `.claude/rules/test-list-discipline.md` (bassclef#1090) — Beck's planning artifact; the test-list IS the rubric tracking surface
|
|
179
|
-
- `.claude/rules/testing-tier-config.md` (bassclef#1037) — Tier 0 presence + recency; this rule layers sufficiency on top
|
|
180
|
-
- `.claude/rules/testing.md` — what makes a good test once you write it
|
|
181
|
-
- `.claude/rules/defensive-bash.md` — 7 bash disciplines; criteria 7-8 verify defensive-bash compliance in tests
|
|
182
|
-
- `.claude/rules/state-schema-validation.md` — state-spine accessor tests use criterion 10 (state-file interactions)
|
|
183
|
-
- `.claude/rules/blocked-items.md` — criterion 9 (stderr format) cites this rule's structured-field requirements
|
|
184
|
-
- `@luminary kent-beck` — TDD rhythm + test-list anchor
|
|
185
|
-
- `@luminary glenford-myers` — coverage taxonomy anchor (criteria 1-4)
|
|
186
|
-
- `@luminary tony-hoare` — contract testing anchor (criteria 5-10)
|
|
187
|
-
|
|
188
|
-
## Distinct from
|
|
189
|
-
|
|
190
|
-
- `testing-tier-config.md` — WHICH paths require WHICH tier of enforcement; this is WHAT assertions a tier 0/1 test owes
|
|
191
|
-
- `testing.md` — WHAT makes a test well-written once you write it
|
|
192
|
-
- `test-list-discipline.md` — HOW to track which assertions are owed/done/deferred
|
|
193
|
-
- `iteration-bet-brief-completeness.md` — separate scope (delegation briefs, not test code)
|
|
194
|
-
|
|
195
|
-
## Refs
|
|
196
|
-
|
|
197
|
-
- bassclef#1098 — this rule's filing ticket
|
|
198
|
-
- bassclef#1037 — Tier 0 strict-TDD discipline (Phase A); this extends with sufficiency layer
|
|
199
|
-
- bassclef#1090 — Beck test-list discipline (sister rule; planning artifact for this rubric)
|
|
200
|
-
- bassclef#1092 — Glenford Myers full luminary (anchor for criteria 1-4)
|
|
201
|
-
- bassclef#1094 — Tony Hoare full luminary (anchor for criteria 5-10)
|
|
202
|
-
- bassclef#1095 — full-from-filing policy (the luminaries cited here ship full)
|
|
203
|
-
- `docs/iteration-bets/2026-06-17b-sufficiency-rubric-plus-hardening-longrun.md` — goal authoring this rule (eat-own-dogfood: WU-2a/b/c hardening uses this rubric)
|
|
204
|
-
- Beck — *Test-Driven Development By Example* (Addison-Wesley, 2002)
|
|
205
|
-
- Myers — *The Art of Software Testing* (Wiley, 1979)
|
|
206
|
-
- Hoare — *Communications of the ACM* 12(10), 1969
|
|
207
|
-
|
|
208
|
-
## Retirement condition
|
|
209
|
-
|
|
210
|
-
This rule retires only if bassclef migrates off systematic testing as a primary discipline. Specific criteria may evolve (V2 mechanical extension may absorb criteria 1, 2, 7; property-based testing may add criterion 11 if a stack adopts it) but the discipline of mechanical sufficiency-at-write-time survives.
|