@thebassclef/lite 0.0.1 → 0.1.0

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.
Files changed (182) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +85 -4
  3. package/dist/cli.cjs +1610 -0
  4. package/dist/cli.js +1587 -0
  5. package/dist/index.cjs +4 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +4 -0
  8. package/package.json +51 -3
  9. package/substrate/.bassclef/lite-manifest.json +1794 -0
  10. package/substrate/.claude/agents/architect.md +70 -0
  11. package/substrate/.claude/agents/builder.md +114 -0
  12. package/substrate/.claude/agents/designer.md +156 -0
  13. package/substrate/.claude/agents/reviewer.md +88 -0
  14. package/substrate/.claude/hooks/artifact-ingestion-gate.sh +357 -0
  15. package/substrate/.claude/hooks/assert-verify-steering.sh +77 -0
  16. package/substrate/.claude/hooks/bassclef-source-config-validate.sh +215 -0
  17. package/substrate/.claude/hooks/bassclef-sync.sh +634 -0
  18. package/substrate/.claude/hooks/compound-noun-scrub.sh +292 -0
  19. package/substrate/.claude/hooks/kiss-expansion-inject.sh +69 -0
  20. package/substrate/.claude/hooks/plain-english-steering.sh +156 -0
  21. package/substrate/.claude/hooks/post-skill-friction-check.sh +177 -0
  22. package/substrate/.claude/hooks/post-skill-telemetry.sh +62 -0
  23. package/substrate/.claude/hooks/pre-build-gate.sh +511 -0
  24. package/substrate/.claude/hooks/pre-commit-gate.sh +452 -0
  25. package/substrate/.claude/hooks/session-end.sh +433 -0
  26. package/substrate/.claude/hooks/session-reflection.sh +303 -0
  27. package/substrate/.claude/hooks/skill-body-grade-gate.sh +219 -0
  28. package/substrate/.claude/hooks/skill-body-intent-drift.sh +107 -0
  29. package/substrate/.claude/hooks/skill-step-list-check.sh +171 -0
  30. package/substrate/.claude/hooks/state-validate.sh +271 -0
  31. package/substrate/.claude/hooks/substrate-clarity-gate.sh +1110 -0
  32. package/substrate/.claude/hooks/temperance-gate.sh +147 -0
  33. package/substrate/.claude/hooks/testing-tier-enforce.sh +233 -0
  34. package/substrate/.claude/hooks/turn-prose-grade-measure.sh +219 -0
  35. package/substrate/.claude/hooks/turn-prose-kiss-check.sh +434 -0
  36. package/substrate/.claude/hooks/vocabulary-migration-check.sh +171 -0
  37. package/substrate/.claude/hooks/whereami-utc-gate.sh +142 -0
  38. package/substrate/.claude/luminaries/alan-cooper.md +170 -0
  39. package/substrate/.claude/luminaries/alistair-cockburn.md +140 -0
  40. package/substrate/.claude/luminaries/amazon-pr-faq.md +34 -0
  41. package/substrate/.claude/luminaries/ash-maurya.md +121 -0
  42. package/substrate/.claude/luminaries/bill-buxton.md +210 -0
  43. package/substrate/.claude/luminaries/charles-sanders-peirce.md +150 -0
  44. package/substrate/.claude/luminaries/david-ogilvy.md +192 -0
  45. package/substrate/.claude/luminaries/don-norman.md +173 -0
  46. package/substrate/.claude/luminaries/edward-tufte.md +179 -0
  47. package/substrate/.claude/luminaries/eric-evans.md +160 -0
  48. package/substrate/.claude/luminaries/frederick-brooks.md +50 -0
  49. package/substrate/.claude/luminaries/gang-of-four.md +157 -0
  50. package/substrate/.claude/luminaries/jason-fried-dhh.md +46 -0
  51. package/substrate/.claude/luminaries/jesse-james-garrett.md +154 -0
  52. package/substrate/.claude/luminaries/john-ousterhout.md +94 -0
  53. package/substrate/.claude/luminaries/karl-popper.md +132 -0
  54. package/substrate/.claude/luminaries/kent-beck.md +168 -0
  55. package/substrate/.claude/luminaries/linus-torvalds.md +218 -0
  56. package/substrate/.claude/luminaries/martin-fowler.md +164 -0
  57. package/substrate/.claude/luminaries/michael-feathers.md +125 -0
  58. package/substrate/.claude/luminaries/michael-nygard.md +118 -0
  59. package/substrate/.claude/luminaries/robert-c-martin.md +164 -0
  60. package/substrate/.claude/luminaries/saltzer-schroeder.md +194 -0
  61. package/substrate/.claude/luminaries/sophia-prater.md +193 -0
  62. package/substrate/.claude/luminaries/stephen-toulmin.md +131 -0
  63. package/substrate/.claude/rules/artifact-ingestion.md +179 -0
  64. package/substrate/.claude/rules/assert-only-after-verify.md +137 -0
  65. package/substrate/.claude/rules/blocked-items.md +146 -0
  66. package/substrate/.claude/rules/branching.md +28 -0
  67. package/substrate/.claude/rules/commit-conventions.md +22 -0
  68. package/substrate/.claude/rules/context-engineering.md +202 -0
  69. package/substrate/.claude/rules/context-management.md +85 -0
  70. package/substrate/.claude/rules/destructive-operations.md +69 -0
  71. package/substrate/.claude/rules/diagnosis.md +38 -0
  72. package/substrate/.claude/rules/guardrails.md +73 -0
  73. package/substrate/.claude/rules/identifier-leak-prevention.md +104 -0
  74. package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +98 -0
  75. package/substrate/.claude/rules/oo-ad-entry-point.md +117 -0
  76. package/substrate/.claude/rules/operator-facing-prose.md +196 -0
  77. package/substrate/.claude/rules/plain-english-discipline.md +154 -0
  78. package/substrate/.claude/rules/pr-body-shape.md +317 -0
  79. package/substrate/.claude/rules/pr-strategy.md +167 -0
  80. package/substrate/.claude/rules/sdlc-gates.md +149 -0
  81. package/substrate/.claude/rules/session-artifacts.md +236 -0
  82. package/substrate/.claude/rules/state-schema-validation.md +162 -0
  83. package/substrate/.claude/rules/whereami-load-bearing.md +202 -0
  84. package/substrate/.claude/rules/writing-craft-discipline.md +92 -0
  85. package/substrate/.claude/skills/build/SKILL.md +640 -0
  86. package/substrate/.claude/skills/decompose/SKILL.md +280 -0
  87. package/substrate/.claude/skills/diagnose/SKILL.md +297 -0
  88. package/substrate/.claude/skills/howdoi/SKILL.md +105 -0
  89. package/substrate/.claude/skills/ia-model/SKILL.md +108 -0
  90. package/substrate/.claude/skills/interaction-design/SKILL.md +112 -0
  91. package/substrate/.claude/skills/interpret-input/SKILL.md +180 -0
  92. package/substrate/.claude/skills/kiss/SKILL.md +449 -0
  93. package/substrate/.claude/skills/launch/SKILL.md +924 -0
  94. package/substrate/.claude/skills/lean-canvas/SKILL.md +332 -0
  95. package/substrate/.claude/skills/longrun/SKILL.md +426 -0
  96. package/substrate/.claude/skills/luminary/SKILL.md +481 -0
  97. package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +177 -0
  98. package/substrate/.claude/skills/onboard-repo/SKILL.md +2190 -0
  99. package/substrate/.claude/skills/pattern-review/SKILL.md +99 -0
  100. package/substrate/.claude/skills/personas/SKILL.md +207 -0
  101. package/substrate/.claude/skills/promote/SKILL.md +283 -0
  102. package/substrate/.claude/skills/requirement/SKILL.md +98 -0
  103. package/substrate/.claude/skills/retro/SKILL.md +117 -0
  104. package/substrate/.claude/skills/riff/SKILL.md +114 -0
  105. package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +163 -0
  106. package/substrate/.claude/skills/session-end/SKILL.md +309 -0
  107. package/substrate/.claude/skills/session-log/SKILL.md +299 -0
  108. package/substrate/.claude/skills/skills/SKILL.md +228 -0
  109. package/substrate/.claude/skills/spec/SKILL.md +105 -0
  110. package/substrate/.claude/skills/sprint/SKILL.md +392 -0
  111. package/substrate/.claude/skills/stage/SKILL.md +384 -0
  112. package/substrate/.claude/skills/state-a-problem/SKILL.md +185 -0
  113. package/substrate/.claude/skills/temperance/SKILL.md +108 -0
  114. package/substrate/.claude/skills/use-case/SKILL.md +417 -0
  115. package/substrate/.claude/skills/user-stories/SKILL.md +268 -0
  116. package/substrate/.claude/skills/value-prop/SKILL.md +251 -0
  117. package/substrate/.claude/skills/verify/SKILL.md +160 -0
  118. package/substrate/.claude/skills/whereami/SKILL.md +307 -0
  119. package/substrate/AGENTS.md +79 -0
  120. package/substrate/CLAUDE-lite.md +85 -0
  121. package/substrate/CODE_OF_CONDUCT.md +28 -0
  122. package/substrate/CONTRIBUTING.md +177 -0
  123. package/substrate/README.md +173 -0
  124. package/substrate/SECURITY.md +19 -0
  125. package/substrate/architecture/decisions/ADR-029-release-pipeline.md +79 -0
  126. package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +139 -0
  127. package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +192 -0
  128. package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +145 -0
  129. package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +155 -0
  130. package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +162 -0
  131. package/substrate/lib/clean-artifacts-sweep.sh +112 -0
  132. package/substrate/lib/code-comment-discipline.sh +144 -0
  133. package/substrate/lib/composer-preflight.sh +459 -0
  134. package/substrate/lib/hook-inject.sh +255 -0
  135. package/substrate/lib/luminary-pick.sh +96 -0
  136. package/substrate/lib/output-discipline.sh +143 -0
  137. package/substrate/lib/rewrite-check.sh +214 -0
  138. package/substrate/lib/state.sh +1372 -0
  139. package/substrate/lib/telemetry.sh +205 -0
  140. package/substrate/lib/tier-check.sh +138 -0
  141. package/substrate/lib/tier-dependency-audit.sh +933 -0
  142. package/substrate/presence/install/bassclef-hook-connect.sh +178 -0
  143. package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +841 -0
  144. package/substrate/presence/install/bassclef-sync.template.sh +2076 -0
  145. package/substrate/presence/install/schedule-auto-save.cron.sh +88 -0
  146. package/substrate/presence/install/schedule-auto-save.taskscheduler.md +122 -0
  147. package/substrate/scripts/aggregate-telemetry.sh +217 -0
  148. package/substrate/scripts/analyze-tier-dependencies.sh +239 -0
  149. package/substrate/scripts/generate-lite-manifest.sh +489 -0
  150. package/substrate/scripts/generate-tier-manifest.sh +28 -0
  151. package/substrate/scripts/intent-drift-check.sh +456 -0
  152. package/substrate/scripts/lite-manifest-drift-check.sh +146 -0
  153. package/substrate/scripts/render-lite-manifest-doc.sh +150 -0
  154. package/substrate/standards/bassclef-configs-schema.md +232 -0
  155. package/substrate/standards/bassclef-evolution.md +143 -0
  156. package/substrate/standards/bassclef-internal-jargon.md +244 -0
  157. package/substrate/standards/bassclef-managed-sentinel.md +96 -0
  158. package/substrate/standards/bassclef-source-config.md +228 -0
  159. package/substrate/standards/deferred-actions-schema.md +204 -0
  160. package/substrate/standards/docs-sync-allowlist.md +76 -0
  161. package/substrate/standards/graceful-exit.md +227 -0
  162. package/substrate/standards/hook-idempotency.md +102 -0
  163. package/substrate/standards/lite-manifest-schema-changes.md +75 -0
  164. package/substrate/standards/luminary-problem-patterns.md +481 -0
  165. package/substrate/standards/ogilvy-writing-rules.md +225 -0
  166. package/substrate/standards/opener-discipline.md +96 -0
  167. package/substrate/standards/operator-facing-prose-discipline.md +201 -0
  168. package/substrate/standards/project-directory-layout.md +276 -0
  169. package/substrate/standards/release-tagging.md +137 -0
  170. package/substrate/standards/sdlc-compliance.md +286 -0
  171. package/substrate/standards/secrets-lifecycle.md +210 -0
  172. package/substrate/standards/security-scanner-adapter.md +145 -0
  173. package/substrate/standards/skill-output-discipline.md +90 -0
  174. package/substrate/standards/state-spine.md +511 -0
  175. package/substrate/standards/tech-stack-config.md +109 -0
  176. package/substrate/standards/tier-dependency-analysis.md +167 -0
  177. package/substrate/standards/tier-runtime-deps/lite.md +57 -0
  178. package/substrate/standards/tier-tag-schema.md +155 -0
  179. package/substrate/standards/whereami-schema.md +301 -0
  180. package/substrate/standards/writing-guide.md +213 -0
  181. package/substrate/templates/deferred-action-template.md +45 -0
  182. package/substrate/templates/whereami-template.md +101 -0
@@ -0,0 +1,286 @@
1
+ ---
2
+ tier: lite
3
+ description: "Defines how gate evidence is captured, where it lives, and how it's queried."
4
+ ---
5
+
6
+ # SDLC Compliance Tracking Standard
7
+
8
+ Defines how gate evidence is captured, where it lives, and how it's queried.
9
+ Replaces the previous trace-log approach (empty action/outcome columns,
10
+ operational problems, now gitignored) with structured compliance data
11
+ embedded in existing artifacts.
12
+
13
+ ---
14
+
15
+ ## Design Decision: Compliance in Chronicles, Not Separate Files
16
+
17
+ Gate evidence lives **in the chronicle entry**, not in a separate compliance
18
+ report. Rationale:
19
+
20
+ 1. Chronicles already capture what happened — compliance is "did the gates
21
+ fire during what happened?"
22
+ 2. A separate file creates drift — the chronicle says one thing, the
23
+ compliance report says another
24
+ 3. Chronicles are append-only and committed to git — they're auditable
25
+ 4. The previous trace-log approach failed because it was a parallel artifact
26
+ nobody maintained
27
+
28
+ The trade-off: compliance data is less machine-queryable embedded in
29
+ chronicles than in structured JSON. If machine querying becomes needed,
30
+ extract it from chronicles rather than maintaining a parallel source of truth.
31
+
32
+ ---
33
+
34
+ ## Session Timing Fields
35
+
36
+ Every chronicle entry includes timing metadata in the frontmatter.
37
+ These fields close the feedback loop between time budget estimates and
38
+ actual session duration, enabling calibration over time.
39
+
40
+ ### Frontmatter timing fields
41
+
42
+ | Field | Type | Required | Description |
43
+ |-------|------|----------|-------------|
44
+ | `started_at` | ISO 8601 datetime | SHOULD | Session start — derived from first commit timestamp or conversation start |
45
+ | `ended_at` | ISO 8601 datetime | SHOULD | Session end — current time at chronicle write |
46
+ | `duration_minutes` | integer | SHOULD | Approximate elapsed minutes (ended_at − started_at) |
47
+ | `turns` | integer or `~N` | SHOULD | Approximate conversation turns this session |
48
+ | `closes` | array of strings | MAY | Issues resolved this session, e.g., `["#37", "#42"]` |
49
+
50
+ All timing fields are optional for backward compatibility — chronicles
51
+ without them are valid historical records. Use `~` prefix for approximate
52
+ values (e.g., `turns: ~40`).
53
+
54
+ ### Deriving timing data
55
+
56
+ - `started_at`: First commit on the session's work, or conversation start
57
+ time if available. Approximate is fine — trend data, not billing.
58
+ - `ended_at`: Current timestamp when the chronicle is written.
59
+ - `duration_minutes`: Simple subtraction, rounded to nearest 5 minutes.
60
+ - `turns`: Estimate from conversation length. Exact counting is fragile
61
+ and not worth the precision.
62
+
63
+ ---
64
+
65
+ ## Gate Evidence Format
66
+
67
+ Every chronicle entry includes a **Gate Evidence** section after the
68
+ narrative. This section records what gates fired and their outcomes.
69
+
70
+ ```markdown
71
+ ## Gate evidence
72
+
73
+ | Gate | Fired | Evidence | Outcome |
74
+ |------|-------|----------|---------|
75
+ | Temperance | yes | Stated approach before first edit on feature/NNN | Proceeded — scope matched spec |
76
+ | Diagnosis | n/a | Not a fix branch | — |
77
+ | Pre-build spec check | yes | Spec at docs/specs/crm.md, referenced in iteration goal | Current |
78
+ | Tests | yes | 12 unit, 3 integration, all pass | `npm test` exit 0 |
79
+ | Visual review | yes | docs/visual-reviews/2026-04-07-deal-card.md | PASS WITH NOTES |
80
+ | Verify | yes | Ran /verify after each task (3 tasks) | All passed |
81
+ | Architect review | no — not due | Last review: 2026-04-05 (6 commits ago, threshold is 10) | — |
82
+
83
+ ### Gate skip justifications
84
+ - Diagnosis skipped: feature branch, not fix branch (per sdlc-gates rule)
85
+ ```
86
+
87
+ ### Required fields
88
+
89
+ | Field | Description |
90
+ |-------|-------------|
91
+ | Gate | Which gate (from `.claude/rules/sdlc-gates.md`) |
92
+ | Fired | yes / no / n/a (with reason if no or n/a) |
93
+ | Evidence | Where to find proof — file path, commit hash, or inline note |
94
+ | Outcome | Result of the gate check |
95
+
96
+ ### Gate skip justifications
97
+
98
+ If a gate was skipped, the reason must be stated. Valid reasons:
99
+
100
+ - **n/a**: Gate doesn't apply (e.g., diagnosis on a feature branch)
101
+ - **Degraded mode**: Infrastructure unavailable (e.g., Playwright MCP missing
102
+ for visual review) — must note what was done instead
103
+ - **Assessed as trivial**: For diagnosis only — cause was immediately obvious
104
+ and reproducible. State the cause.
105
+
106
+ Invalid reasons:
107
+ - "Ran out of time" — gates are non-negotiable
108
+ - "Will do later" — gates fire before commit, not after
109
+ - No reason given — a bare "no" in the Fired column is a compliance failure
110
+
111
+ ---
112
+
113
+ ## Gates to Track
114
+
115
+ These are the gates defined in `.claude/rules/sdlc-gates.md` and
116
+ `strategy/agent-choreography.md` Section 9:
117
+
118
+ ### Pre-build gates (before writing code)
119
+
120
+ | Gate | Trigger | Evidence format |
121
+ |------|---------|----------------|
122
+ | Temperance | First edit per branch | "Stated approach: [summary]" |
123
+ | Diagnosis | All fix/ branches | "Is/Is Not completed, root cause: [summary]" or "Assessed as trivial: [cause]" |
124
+ | Spec check | Before Construction | "Spec at [path], current as of [date]" |
125
+ | Issue exists | Before branch creation | "Issue #NNN created/exists" |
126
+
127
+ ### Post-build gates (before committing)
128
+
129
+ | Gate | Trigger | Evidence format |
130
+ |------|---------|----------------|
131
+ | Tests | Every commit with logic changes | "[N] unit, [M] integration, all pass" |
132
+ | Verify | Every task completion | "Ran /verify — [outcome]" |
133
+ | Visual review | Every UI change | "Report at [path] — [verdict]" |
134
+ | Architect review | Every 10 commits or before launch | "Last review: [date], [N] commits ago" |
135
+
136
+ ### Session gates (phase/session boundaries)
137
+
138
+ | Gate | Trigger | Evidence format |
139
+ |------|---------|----------------|
140
+ | Chronicle | Phase transition + session end | "Chronicle at [path]" |
141
+ | Checkpoint | Exit conditions per graceful-exit.md | "Checkpoint at .claude/CHECKPOINT.md" |
142
+ | LinkedIn draft | Notable decisions (SHOULD) | "Draft at [path]" or "No notable moments this session" |
143
+
144
+ ---
145
+
146
+ ## Iteration Goal Closeout
147
+
148
+ When an iteration completes, append a **Closeout** section to the
149
+ iteration goal file. This captures actuals vs time budget and gate compliance
150
+ across the iteration's sessions — the feedback loop that calibrates
151
+ future time budget estimates.
152
+
153
+ ### Closeout format
154
+
155
+ ```markdown
156
+ ## Closeout
157
+
158
+ ### Actuals vs appetite
159
+
160
+ | Metric | Time budget | Actual | Delta |
161
+ |--------|----------|--------|-------|
162
+ | Turns | 40 | 52 | +30% |
163
+ | Duration | ~1 session | 2 sessions (75m + 40m) | +1 session |
164
+ | Issues closed | 3 | 2 | -1 (deferred #NNN) |
165
+
166
+ ### Gate compliance
167
+
168
+ | Gate | Expected | Fired | Skipped | Notes |
169
+ |------|----------|-------|---------|-------|
170
+ | Temperance | 3 | 3 | 0 | — |
171
+ | Diagnosis | 1 | 1 | 0 | fix branch |
172
+ | Tests | 3 | 2 | 1 | 1 docs-only commit, n/a |
173
+ | Verify | 3 | 3 | 0 | — |
174
+ | Visual review | 0 | 0 | 0 | no UI changes |
175
+
176
+ ### Calibration notes
177
+
178
+ [What was over/underscoped. Guidance for next similar iteration.
179
+ Example: "Time budget was tight — the extraction script was underscoped.
180
+ Next similar iteration: budget 50 turns."]
181
+ ```
182
+
183
+ ### When to write the closeout
184
+
185
+ - When all acceptance criteria are met (or explicitly deferred)
186
+ - Before writing the final chronicle for the iteration
187
+ - The closeout data comes from the session chronicles' timing fields
188
+ and gate evidence tables — it's an aggregation, not a separate data source
189
+
190
+ ### Acceptance criteria for closeout
191
+
192
+ The iteration goal's acceptance criteria checkboxes should be updated
193
+ to reflect actual completion state. Deferred items get a note explaining
194
+ why and a reference to the follow-up issue.
195
+
196
+ ---
197
+
198
+ ## Querying Compliance
199
+
200
+ ### Manual query (current approach)
201
+
202
+ ```bash
203
+ # Find all chronicles with gate evidence
204
+ grep -l "Gate evidence" chronicle/*.md
205
+
206
+ # Find skipped gates
207
+ grep -A 1 "no —\|no $" chronicle/*.md
208
+
209
+ # Find visual review failures
210
+ grep "FAIL" chronicle/*.md
211
+ ```
212
+
213
+ ### Architect review query
214
+
215
+ During `/architect-review`, the Architect reads the last 5 chronicles
216
+ and checks:
217
+
218
+ 1. Are all required gates present in each entry?
219
+ 2. Are there unexplained skips?
220
+ 3. Is there a pattern of degraded mode (infrastructure not available)?
221
+ 4. Are gate skip justifications valid?
222
+
223
+ This is the primary compliance audit mechanism — it runs every 10 commits.
224
+
225
+ ### Future: structured extraction
226
+
227
+ If machine-queryable compliance becomes needed:
228
+
229
+ 1. Extract gate evidence sections from chronicles into JSON
230
+ 2. Script: `scripts/extract-compliance.sh` → `docs/compliance/latest.json`
231
+ 3. Run on demand or as part of architect review
232
+ 4. The chronicle remains the source of truth; JSON is a derived view
233
+
234
+ Do not build this until there's a real need. The architect review query
235
+ is sufficient for current scale.
236
+
237
+ ---
238
+
239
+ ## Hook Integration
240
+
241
+ ### Existing hooks that produce gate evidence
242
+
243
+ | Hook | What it captures | Where |
244
+ |------|-----------------|-------|
245
+ | `pre-build-gate.sh` | Temperance fired, diagnosis fired (fix branches) | Blocks the edit until gate clears |
246
+ | `pre-commit` (if configured) | Tests pass, lint pass | Blocks the commit |
247
+ | `session-end` / Stop hook | Chronicle written, checkpoint written | Fires at session end |
248
+
249
+ ### Agent responsibility
250
+
251
+ Hooks capture mechanical gates (did the tool run?). The agent captures
252
+ semantic gates (was the outcome meaningful?). Both are needed.
253
+
254
+ The agent writes the gate evidence table in the chronicle. Hooks provide
255
+ the enforcement that gates fire at all. Neither replaces the other.
256
+
257
+ ---
258
+
259
+ ## Compliance Failures
260
+
261
+ A compliance failure is a chronicle entry where:
262
+
263
+ 1. A required gate shows "no" without a valid justification
264
+ 2. The gate evidence section is missing entirely
265
+ 3. Evidence references a file that doesn't exist
266
+
267
+ ### Response to compliance failures
268
+
269
+ - **At architect review**: Flag the failure, check if it caused actual harm
270
+ (missed bug, broken deployment, etc.), recommend process fix
271
+ - **At session start**: If the previous chronicle has a compliance failure,
272
+ note it in the current session's chronicle under "Entry state"
273
+ - **Do NOT retroactively fix chronicles** — they're historical records.
274
+ Note the gap and prevent recurrence.
275
+
276
+ ---
277
+
278
+ ## Relationship to Other Standards
279
+
280
+ | Standard | Relationship |
281
+ |----------|-------------|
282
+ | `.claude/rules/sdlc-gates.md` | Defines which gates exist; this standard defines how to track them |
283
+ | `strategy/agent-choreography.md` | Section 9 defines MUST gates; this standard defines evidence format |
284
+ | `standards/graceful-exit.md` | Checkpoint is a tracked gate at session boundaries |
285
+ | `.claude/skills/chronicle/SKILL.md` | Chronicle skill should include gate evidence template |
286
+ | `.claude/skills/architect-review/SKILL.md` | Architect review queries compliance from chronicles |
@@ -0,0 +1,210 @@
1
+ ---
2
+ tier: lite
3
+ description: substrate.secrets.md is the single declarative source for secrets/token lifecycle in any bassclef-substrate repo.
4
+ ---
5
+
6
+ # Secrets Lifecycle
7
+
8
+ `substrate.secrets.md` is the single declarative source for secrets/token
9
+ lifecycle in any bassclef-substrate repo. Schema:
10
+ `standards/state-spine/schemas/substrate-secrets.schema.json`.
11
+
12
+ ## Why this exists
13
+
14
+ Before this standard: tokens silently expired mid-session. The operator
15
+ hit a 401, then grepped historical chronicles to remember which token,
16
+ where it lives, how to rotate it. Every consumer team reinvented the
17
+ tracking — file in 1Password, sticky note, calendar reminder, none of
18
+ the above.
19
+
20
+ After this standard: every secret has a tracked expiry, a documented
21
+ rotation procedure, and a session-start hook that surfaces the warning
22
+ weeks before expiry. Friction removed; operational story declarative.
23
+
24
+ ## Why a separate file from `substrate.config.md`
25
+
26
+ `substrate.config.md` holds external resource *references* (doc IDs,
27
+ URLs, repo refs). `substrate.secrets.md` holds secret *lifecycle*
28
+ (expiry, rotation, health checks). Two different concerns:
29
+
30
+ - **Privacy posture**: secrets references are sensitive metadata
31
+ (storage location, expiry windows leak operational structure);
32
+ config references are public.
33
+ - **Audit lifecycle**: `last_rotated` + `expires_at` need date discipline;
34
+ config rarely changes.
35
+ - **Read-time consumers**: `scripts/secrets-status.sh` parses secrets;
36
+ `substrate.config.md` is read by skills/hooks for resource lookup.
37
+
38
+ Cross-reference: `substrate.config.md` carries a one-line pointer
39
+ ("secrets tracked in `substrate.secrets.md`"); `substrate.secrets.md`
40
+ carries a one-line back-pointer.
41
+
42
+ ## File shape
43
+
44
+ `substrate.secrets.md` uses Shape B (YAML frontmatter + markdown body):
45
+
46
+ ```markdown
47
+ ---
48
+ schema_version: v0
49
+ secrets:
50
+ - name: SLACK_WEBHOOK
51
+ purpose: posting to bassclef-activity channel
52
+ storage:
53
+ type: github_actions_secret
54
+ reference: SLACK_WEBHOOK
55
+ rotation_cadence: 1y
56
+ expires_at: 2026-09-15
57
+ rotation_procedure: docs/runbooks/rotate-slack-webhook.md
58
+ alert_threshold_days: 30
59
+ owner: operator
60
+ last_rotated: 2025-09-15
61
+ health_check_command: ""
62
+ ---
63
+
64
+ # Secrets — <repo name>
65
+
66
+ Lifecycle tracking for external integration credentials.
67
+ See `standards/secrets-lifecycle.md`.
68
+
69
+ [Optional human-readable notes per secret in body sections.]
70
+ ```
71
+
72
+ ## Field reference
73
+
74
+ | Field | Required | Type | Notes |
75
+ |-------|----------|------|-------|
76
+ | `name` | yes | string | UPPER_SNAKE_CASE. Logical name (env-var convention). NEVER the value. |
77
+ | `purpose` | yes | string | One-line: what does this secret allow? |
78
+ | `storage.type` | yes | enum | `1password \| env \| file \| github_actions_secret \| aws_secrets_manager \| custom` |
79
+ | `storage.reference` | yes | string | How to fetch the value at runtime (shape per type — see below). |
80
+ | `rotation_cadence` | yes | duration \| enum | `1y`, `6mo`, `90d`, `30d` OR `manual` / `on-leak` / `never` |
81
+ | `expires_at` | yes | date \| `never` | ISO 8601 (YYYY-MM-DD) OR `never` (lifetime credential) |
82
+ | `rotation_procedure` | yes | path | Path to runbook (`docs/runbooks/rotate-<name>.md`). Empty string when cadence=`never`. |
83
+ | `alert_threshold_days` | yes | integer \| `n/a` | Days-before-expiry to start surfacing BLOCKED. Use `n/a` for `never`. |
84
+ | `owner` | yes | string | Who rotates. `operator` for solo; team/handle for multi-operator. |
85
+ | `last_rotated` | yes | date \| `unknown` | ISO 8601 OR `unknown` if pre-tracking. |
86
+ | `health_check_command` | no | string | Optional shell command verifying secret is live. Empty string skips. |
87
+
88
+ ## Storage type vocabulary (v0)
89
+
90
+ Closed enum in v0; extensible via `custom` per consumer.
91
+
92
+ | Type | Reference shape | Example |
93
+ |------|----------------|---------|
94
+ | `1password` | vault path | `vault://bassclef/anthropic-api-key` |
95
+ | `env` | env var name | `CLOUDFLARE_API_TOKEN` |
96
+ | `file` | absolute path | `~/.poa-gauth.json` |
97
+ | `github_actions_secret` | secret name | `SLACK_WEBHOOK` |
98
+ | `aws_secrets_manager` | ARN or secret id | `arn:aws:secretsmanager:us-east-1:...:secret:my-secret-AbCdEf` |
99
+ | `custom` | free-form (document inline in body) | per-consumer |
100
+
101
+ ## Rotation cadence
102
+
103
+ ISO 8601 duration OR controlled enum:
104
+
105
+ - **Duration shorthand**: `1y`, `6mo`, `90d`, `30d`, `1w` (bassclef's friendly form)
106
+ - **Full ISO 8601**: `P1Y`, `P6M`, `P90D` (also accepted)
107
+ - **`manual`**: rotate when notified (e.g., compromise, vendor migration)
108
+ - **`on-leak`**: rotate only on incident; otherwise lifetime
109
+ - **`never`**: lifetime credential (rare; flag for review)
110
+
111
+ ## Expiry tracking
112
+
113
+ `expires_at` is the hard date the credential becomes invalid. The
114
+ session-start hook (`90-secrets-expiry.sh`) compares `expires_at` to
115
+ today's date and surfaces BLOCKED when within `alert_threshold_days`.
116
+
117
+ When `expires_at: never` the entry is never alerted; `alert_threshold_days`
118
+ must be `n/a` and `rotation_procedure` may be empty.
119
+
120
+ After rotation: update both `last_rotated` (to today) AND `expires_at`
121
+ (to the new expiry). The runbook should remind the operator.
122
+
123
+ ## Health checks
124
+
125
+ `health_check_command` is optional. When set, it's a shell command that
126
+ returns exit code 0 when the secret is live. Used by `secrets-status.sh
127
+ --health-check`. Should reference the env var (not hardcoded value):
128
+
129
+ ```yaml
130
+ health_check_command: "curl -s -H 'x-api-key: $ANTHROPIC_API_KEY' https://api.anthropic.com/v1/models | jq -e '.data'"
131
+ ```
132
+
133
+ For `manual` / `on-leak` / `never` cadences, health checks are still
134
+ useful (verify the credential hasn't been revoked).
135
+
136
+ ## Hard rules
137
+
138
+ 1. **NO secret VALUES.** Only references, expiry dates, rotation procedures,
139
+ and health-check commands. Values stay in their authoritative storage
140
+ (1Password / GitHub Actions Secrets / .env / AWS Secrets Manager).
141
+ 2. **NO commits of `.env` files**. Use `storage.type=env` with the
142
+ reference being the env var name; the value lives in a gitignored
143
+ `.env` consumed at runtime.
144
+ 3. **`substrate.secrets.md` is git-tracked.** Its content is
145
+ non-sensitive metadata. If your storage references leak operational
146
+ structure (e.g., AWS account IDs you'd rather not publish), use
147
+ `custom` type with a private reference shape.
148
+ 4. **Rotation updates BOTH `last_rotated` AND `expires_at`.** The runbook
149
+ reminds the operator.
150
+ 5. **`alert_threshold_days` matches risk profile.** Webhooks: 30 days.
151
+ API keys with manual rotation: longer. OAuth refresh tokens: shorter
152
+ if vendor revokes proactively.
153
+ 6. **`~/.config/bassclef/secrets.env` lines MUST use `export VAR=value`
154
+ format.** When the env adapter writes to that file, plain `VAR=value`
155
+ sets a shell variable only — bash subprocesses (including every
156
+ bassclef hook + helper) don't inherit it. `export VAR=value` enters
157
+ the environment proper and is inherited by every subprocess the
158
+ shell launches. The env adapter (`scripts/adapters/secrets/env.sh`)
159
+ enforces this format on writes; `/secrets-bootstrap --repair`
160
+ retroactively fixes legacy files that lack the prefix
161
+ (bassclef#976).
162
+
163
+ ## Tooling
164
+
165
+ | Tool | Purpose |
166
+ |------|---------|
167
+ | `scripts/secrets-status.sh` | Parses `substrate.secrets.md`, prints traffic-light status table, optional `--health-check` flag |
168
+ | `scripts/secrets-bootstrap.sh --repair` | Adds missing `export ` prefix to assignment lines in `~/.config/bassclef/secrets.env`. Creates dated backup. Required when subprocess inheritance breaks (bassclef#976) |
169
+ | `.claude/hooks/session-reflection.d/90-secrets-expiry.sh` | Session-start BLOCKED surface for any secret within `alert_threshold_days` |
170
+ | `templates/secret-rotation-template.md` | Runbook template for new secret rotation procedures |
171
+
172
+ ## Override paths
173
+
174
+ - **`SKIP_SECRETS_EXPIRY_CHECK=1`**: bypass the session-start hook for
175
+ one command. Logged to stderr per bassclef idiom.
176
+ - **No `substrate.secrets.md`**: hook is silent (graceful in repos
177
+ without secrets).
178
+
179
+ ## Migration
180
+
181
+ For repos adopting this standard:
182
+
183
+ 1. Copy `presence/install/substrate-secrets-template.md` to repo root
184
+ as `substrate.secrets.md`
185
+ 2. Populate one entry per tracked secret (start with the most painful —
186
+ typically the one that last expired)
187
+ 3. Add cross-reference in `substrate.config.md`
188
+ 4. Run `bash scripts/secrets-status.sh` to verify schema parses
189
+ 5. Commit; the session-start hook activates immediately
190
+
191
+ ## Out of scope (v1+)
192
+
193
+ - Slack/email cron alerts (v0 surfaces at session start only)
194
+ - AWS Secrets Manager / 1Password programmatic retrieval (v0 uses
195
+ per-secret `health_check_command`)
196
+ - Storage-type validators (vs per-secret command) — would require
197
+ bassclef-side implementations per type
198
+ - SOC 2 / ISO 27001 audit-trail integration — rotation log feeding
199
+ external audit systems
200
+
201
+ ## Composes with
202
+
203
+ - `standards/substrate-config-schema.md` — sibling standard for
204
+ references (non-secret)
205
+ - `.claude/rules/substrate-config-schema.md` — agent behavior rule;
206
+ references-only-by-name discipline applies to secrets too
207
+ - `.claude/rules/manual-prod-approval.md` — sibling
208
+ infrastructure-rail pattern
209
+ - `.claude/rules/context-engineering.md` — same just-in-time
210
+ context-surface discipline applied to operator runbook
@@ -0,0 +1,145 @@
1
+ ---
2
+ tier: lite
3
+ description: "The adapter pattern that turns bassclef's per-language security defaults into adopter-runnable CI."
4
+ ---
5
+
6
+ # Security Scanner Adapter Standard
7
+
8
+ The adapter pattern that turns bassclef's per-language security defaults into adopter-runnable CI. This standard is the reference; per-stack reference workflows ship under `config/security-scanners/` (Phase Y-3); `/onboard-repo` writes the stack choice to `.claude/bassclef-configs.jsonc` (Phase Y-4).
9
+
10
+ ## Why this exists
11
+
12
+ Adopter repos run bassclef's substrate as their development methodology. The substrate has security disciplines (`standards/code-safety-principles.md`, `.claude/rules/security.md`, `standards/bash-hook-safety.md`) but the disciplines need *scanners* to enforce them in adopter CI.
13
+
14
+ Today's gap: every adopter chooses, installs, and configures their own security scanners. Bassclef has no opinion on which scanners fire for which language. New adopters who do not know the security tool landscape ship with no scanners; experienced adopters duplicate effort across repos.
15
+
16
+ INSTEAD of per-adopter scanner choice from scratch: bassclef ships per-stack defaults. Adopters declare their stack at onboard time; bassclef wires the default scanners + ships a reference workflow they copy + customize.
17
+
18
+ ## Anchor
19
+
20
+ `@luminary saltzer-schroeder` — the eight protection-mechanism principles. Scanners are the mechanical enforcement layer for the source-code disciplines.
21
+
22
+ This standard composes with:
23
+
24
+ - `standards/code-safety-principles.md` — language-agnostic principles the scanners check
25
+ - `standards/bash-hook-safety.md` — bash-specific discipline; shellcheck is the scanner
26
+ - `standards/bassclef-configs-schema.md` § Security scanning (Phase Y-2) — adopter config surface
27
+ - `standards/deployment-topology.md` — sibling adapter pattern; same shape
28
+
29
+ ## The adapter shape
30
+
31
+ ```
32
+ adopter declares stack → bassclef-configs reads stack → workflow template fires per-stack scanners → scanner output meets discipline gates
33
+ ```
34
+
35
+ Same shape as the deploy-host adapter. Adopter declares the runtime; bassclef ships defaults; adopter customizes per-need.
36
+
37
+ Three pieces:
38
+
39
+ 1. **Stack declaration** — `.claude/bassclef-configs.jsonc` `security_scanning.stack` field
40
+ 2. **Reference workflow** — `config/security-scanners/<stack>.yml` (template the adopter copies)
41
+ 3. **Per-stack defaults** — listed in this standard's matrix below
42
+
43
+ ## Stack reference matrix
44
+
45
+ Six stack values. Six default scanner sets. Adopter copies the reference workflow + adjusts.
46
+
47
+ | Stack | Default scanners | What they catch |
48
+ |---|---|---|
49
+ | `node-typescript` | eslint-plugin-security + audit-ci + gitleaks | Source: XSS / SQL injection / unsafe regex / weak crypto. Deps: known CVEs. Secrets: leaked tokens. |
50
+ | `python` | bandit + safety + gitleaks | Source: SQL injection / weak crypto / unsafe pickle / shell injection. Deps: known CVEs. Secrets: leaked tokens. |
51
+ | `ruby` | brakeman + bundler-audit + gitleaks | Source: Rails-specific findings (mass-assignment / unsafe redirects / SQL injection). Deps: known CVEs. Secrets: leaked tokens. |
52
+ | `java` | spotbugs-security + dependency-check + gitleaks | Source: deserialization / XXE / unsafe reflection. Deps: known CVEs (OWASP DC). Secrets: leaked tokens. |
53
+ | `go` | gosec + govulncheck + gitleaks | Source: weak crypto / unsafe error handling / SQL injection. Deps: known CVEs. Secrets: leaked tokens. |
54
+ | `custom` | adopter-supplied list | Adopter responsible for choice + coverage |
55
+
56
+ `gitleaks` appears in every default set because secret detection is stack-agnostic.
57
+
58
+ `custom` is for adopters with a stack not in the bassclef defaults OR with specific scanner requirements (e.g., commercial Snyk / Veracode / Checkmarx). The adapter pattern allows opt-out without losing the schema discipline.
59
+
60
+ ## Reference workflows
61
+
62
+ Phase Y-3 ships the first two reference workflows: `config/security-scanners/node-typescript.yml` + `config/security-scanners/python.yml`. Ruby + Java + Go follow per adopter demand.
63
+
64
+ Each reference workflow:
65
+
66
+ - Triggers on PR + push to main (matches bassclef-pr-ci.yml pattern)
67
+ - Installs scanners
68
+ - Runs each scanner
69
+ - Outputs findings as PR comments (advisory) AND as workflow status (potential BLOCK)
70
+ - Uses `block_on_high_severity` field from bassclef-configs to decide BLOCK vs advisory
71
+
72
+ Adopters copy the template to `.github/workflows/security-scan.yml` in their consumer repo + customize.
73
+
74
+ ## How the adopter configures
75
+
76
+ `.claude/bassclef-configs.jsonc` `security_scanning` block (Phase Y-2):
77
+
78
+ ```jsonc
79
+ {
80
+ "security_scanning": {
81
+ // Stack name from the matrix above OR "custom".
82
+ // null = OFF (no security scanning configured).
83
+ "stack": "node-typescript",
84
+
85
+ // Optional additional scanners (e.g., commercial tools).
86
+ // Names are advisory; adopter writes their own workflow steps.
87
+ "additional_scanners": [],
88
+
89
+ // Block CI on high-severity findings; advisory-only otherwise.
90
+ // Recommended: true for production-bound work; false for early
91
+ // exploratory adopters.
92
+ "block_on_high_severity": true
93
+ }
94
+ }
95
+ ```
96
+
97
+ `null` stack means the adopter has not yet configured scanners; `/onboard-repo` will prompt at the next session. After choice, the field stays static — adopter edits it manually OR re-runs `/onboard-repo --reconfigure-security`.
98
+
99
+ ## Stack auto-detection
100
+
101
+ Phase Y-4 extends `/onboard-repo` with stack auto-detection. Heuristics:
102
+
103
+ | Signal | Hint |
104
+ |---|---|
105
+ | `package.json` exists + `typescript` or `@types/*` in deps | node-typescript |
106
+ | `package.json` exists + JavaScript only | node-typescript (with TS opt-out) |
107
+ | `requirements.txt` OR `pyproject.toml` OR `setup.py` | python |
108
+ | `Gemfile` OR `*.gemspec` | ruby |
109
+ | `pom.xml` OR `build.gradle` OR `*.java` | java |
110
+ | `go.mod` OR `*.go` | go |
111
+ | Multiple signals OR none | prompt operator + offer `custom` |
112
+
113
+ INSTEAD of asking the operator to remember the stack name: auto-detect from build files + confirm. The operator overrides if the detection is wrong.
114
+
115
+ ## What this adapter does NOT do
116
+
117
+ - Does not install scanners on the adopter machine — only generates the CI workflow that installs them per-run
118
+ - Does not maintain the scanner lists (adopters update reference workflows when new tool versions ship)
119
+ - Does not unify scanner output formats — each scanner outputs its native format; the workflow presents per-scanner sections
120
+ - Does not configure scanner-specific rules — adopters edit the reference workflow for per-org tuning
121
+ - Does not replace SAST / DAST commercial tools — the defaults are open-source baselines; adopters add commercial tools via `additional_scanners`
122
+
123
+ ## When this adapter fires
124
+
125
+ | Surface | Action |
126
+ |---|---|
127
+ | New adopter onboarding | `/onboard-repo` auto-detects stack + asks for confirmation + writes config |
128
+ | Existing adopter without security_scanning block | `/onboard-repo --reconfigure-security` (Phase Y-4) |
129
+ | Per PR in adopter repo | Adopter's copy of reference workflow fires |
130
+ | Reference workflow update in bassclef | Adopter notices via bassclef-sync; opts in to refresh their workflow |
131
+
132
+ ## Refs
133
+
134
+ - `standards/code-safety-principles.md` — language-agnostic principles the scanners check
135
+ - `standards/bash-hook-safety.md` — bash-specific discipline (shellcheck is the bash scanner)
136
+ - `standards/bassclef-configs-schema.md` § Security scanning (Phase Y-2; this PR's sibling)
137
+ - `standards/deployment-topology.md` — sibling adapter pattern
138
+ - `.claude/skills/onboard-repo/SKILL.md` (Phase Y-4) — onboarding integration
139
+ - `@luminary saltzer-schroeder` — anchor; mechanical enforcement of protection principles
140
+ - bassclef#1058 — failure-as-evidence for why adopters need substrate-supplied defaults
141
+ - docs/iteration-bets/2026-06-17a-secure-coding-foundations-longrun.md — Phase Y-1
142
+
143
+ ## Retirement
144
+
145
+ This standard retires when scanner choice converges (one bassclef scanner per stack) OR when a different security-enforcement model replaces per-stack scanner-based CI (e.g., universal SAST API). The adapter shape persists; the matrix entries evolve.