@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.
- package/LICENSE +202 -0
- package/README.md +85 -4
- package/dist/cli.cjs +1610 -0
- package/dist/cli.js +1587 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/package.json +51 -3
- package/substrate/.bassclef/lite-manifest.json +1794 -0
- package/substrate/.claude/agents/architect.md +70 -0
- package/substrate/.claude/agents/builder.md +114 -0
- package/substrate/.claude/agents/designer.md +156 -0
- package/substrate/.claude/agents/reviewer.md +88 -0
- package/substrate/.claude/hooks/artifact-ingestion-gate.sh +357 -0
- package/substrate/.claude/hooks/assert-verify-steering.sh +77 -0
- package/substrate/.claude/hooks/bassclef-source-config-validate.sh +215 -0
- package/substrate/.claude/hooks/bassclef-sync.sh +634 -0
- package/substrate/.claude/hooks/compound-noun-scrub.sh +292 -0
- package/substrate/.claude/hooks/kiss-expansion-inject.sh +69 -0
- package/substrate/.claude/hooks/plain-english-steering.sh +156 -0
- package/substrate/.claude/hooks/post-skill-friction-check.sh +177 -0
- package/substrate/.claude/hooks/post-skill-telemetry.sh +62 -0
- package/substrate/.claude/hooks/pre-build-gate.sh +511 -0
- package/substrate/.claude/hooks/pre-commit-gate.sh +452 -0
- package/substrate/.claude/hooks/session-end.sh +433 -0
- package/substrate/.claude/hooks/session-reflection.sh +303 -0
- package/substrate/.claude/hooks/skill-body-grade-gate.sh +219 -0
- package/substrate/.claude/hooks/skill-body-intent-drift.sh +107 -0
- package/substrate/.claude/hooks/skill-step-list-check.sh +171 -0
- package/substrate/.claude/hooks/state-validate.sh +271 -0
- package/substrate/.claude/hooks/substrate-clarity-gate.sh +1110 -0
- package/substrate/.claude/hooks/temperance-gate.sh +147 -0
- package/substrate/.claude/hooks/testing-tier-enforce.sh +233 -0
- package/substrate/.claude/hooks/turn-prose-grade-measure.sh +219 -0
- package/substrate/.claude/hooks/turn-prose-kiss-check.sh +434 -0
- package/substrate/.claude/hooks/vocabulary-migration-check.sh +171 -0
- package/substrate/.claude/hooks/whereami-utc-gate.sh +142 -0
- package/substrate/.claude/luminaries/alan-cooper.md +170 -0
- package/substrate/.claude/luminaries/alistair-cockburn.md +140 -0
- package/substrate/.claude/luminaries/amazon-pr-faq.md +34 -0
- package/substrate/.claude/luminaries/ash-maurya.md +121 -0
- package/substrate/.claude/luminaries/bill-buxton.md +210 -0
- package/substrate/.claude/luminaries/charles-sanders-peirce.md +150 -0
- package/substrate/.claude/luminaries/david-ogilvy.md +192 -0
- package/substrate/.claude/luminaries/don-norman.md +173 -0
- package/substrate/.claude/luminaries/edward-tufte.md +179 -0
- package/substrate/.claude/luminaries/eric-evans.md +160 -0
- package/substrate/.claude/luminaries/frederick-brooks.md +50 -0
- package/substrate/.claude/luminaries/gang-of-four.md +157 -0
- package/substrate/.claude/luminaries/jason-fried-dhh.md +46 -0
- package/substrate/.claude/luminaries/jesse-james-garrett.md +154 -0
- package/substrate/.claude/luminaries/john-ousterhout.md +94 -0
- package/substrate/.claude/luminaries/karl-popper.md +132 -0
- package/substrate/.claude/luminaries/kent-beck.md +168 -0
- package/substrate/.claude/luminaries/linus-torvalds.md +218 -0
- package/substrate/.claude/luminaries/martin-fowler.md +164 -0
- package/substrate/.claude/luminaries/michael-feathers.md +125 -0
- package/substrate/.claude/luminaries/michael-nygard.md +118 -0
- package/substrate/.claude/luminaries/robert-c-martin.md +164 -0
- package/substrate/.claude/luminaries/saltzer-schroeder.md +194 -0
- package/substrate/.claude/luminaries/sophia-prater.md +193 -0
- package/substrate/.claude/luminaries/stephen-toulmin.md +131 -0
- package/substrate/.claude/rules/artifact-ingestion.md +179 -0
- package/substrate/.claude/rules/assert-only-after-verify.md +137 -0
- package/substrate/.claude/rules/blocked-items.md +146 -0
- package/substrate/.claude/rules/branching.md +28 -0
- package/substrate/.claude/rules/commit-conventions.md +22 -0
- package/substrate/.claude/rules/context-engineering.md +202 -0
- package/substrate/.claude/rules/context-management.md +85 -0
- package/substrate/.claude/rules/destructive-operations.md +69 -0
- package/substrate/.claude/rules/diagnosis.md +38 -0
- package/substrate/.claude/rules/guardrails.md +73 -0
- package/substrate/.claude/rules/identifier-leak-prevention.md +104 -0
- package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +98 -0
- package/substrate/.claude/rules/oo-ad-entry-point.md +117 -0
- package/substrate/.claude/rules/operator-facing-prose.md +196 -0
- package/substrate/.claude/rules/plain-english-discipline.md +154 -0
- package/substrate/.claude/rules/pr-body-shape.md +317 -0
- package/substrate/.claude/rules/pr-strategy.md +167 -0
- package/substrate/.claude/rules/sdlc-gates.md +149 -0
- package/substrate/.claude/rules/session-artifacts.md +236 -0
- package/substrate/.claude/rules/state-schema-validation.md +162 -0
- package/substrate/.claude/rules/whereami-load-bearing.md +202 -0
- package/substrate/.claude/rules/writing-craft-discipline.md +92 -0
- package/substrate/.claude/skills/build/SKILL.md +640 -0
- package/substrate/.claude/skills/decompose/SKILL.md +280 -0
- package/substrate/.claude/skills/diagnose/SKILL.md +297 -0
- package/substrate/.claude/skills/howdoi/SKILL.md +105 -0
- package/substrate/.claude/skills/ia-model/SKILL.md +108 -0
- package/substrate/.claude/skills/interaction-design/SKILL.md +112 -0
- package/substrate/.claude/skills/interpret-input/SKILL.md +180 -0
- package/substrate/.claude/skills/kiss/SKILL.md +449 -0
- package/substrate/.claude/skills/launch/SKILL.md +924 -0
- package/substrate/.claude/skills/lean-canvas/SKILL.md +332 -0
- package/substrate/.claude/skills/longrun/SKILL.md +426 -0
- package/substrate/.claude/skills/luminary/SKILL.md +481 -0
- package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +177 -0
- package/substrate/.claude/skills/onboard-repo/SKILL.md +2190 -0
- package/substrate/.claude/skills/pattern-review/SKILL.md +99 -0
- package/substrate/.claude/skills/personas/SKILL.md +207 -0
- package/substrate/.claude/skills/promote/SKILL.md +283 -0
- package/substrate/.claude/skills/requirement/SKILL.md +98 -0
- package/substrate/.claude/skills/retro/SKILL.md +117 -0
- package/substrate/.claude/skills/riff/SKILL.md +114 -0
- package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +163 -0
- package/substrate/.claude/skills/session-end/SKILL.md +309 -0
- package/substrate/.claude/skills/session-log/SKILL.md +299 -0
- package/substrate/.claude/skills/skills/SKILL.md +228 -0
- package/substrate/.claude/skills/spec/SKILL.md +105 -0
- package/substrate/.claude/skills/sprint/SKILL.md +392 -0
- package/substrate/.claude/skills/stage/SKILL.md +384 -0
- package/substrate/.claude/skills/state-a-problem/SKILL.md +185 -0
- package/substrate/.claude/skills/temperance/SKILL.md +108 -0
- package/substrate/.claude/skills/use-case/SKILL.md +417 -0
- package/substrate/.claude/skills/user-stories/SKILL.md +268 -0
- package/substrate/.claude/skills/value-prop/SKILL.md +251 -0
- package/substrate/.claude/skills/verify/SKILL.md +160 -0
- package/substrate/.claude/skills/whereami/SKILL.md +307 -0
- package/substrate/AGENTS.md +79 -0
- package/substrate/CLAUDE-lite.md +85 -0
- package/substrate/CODE_OF_CONDUCT.md +28 -0
- package/substrate/CONTRIBUTING.md +177 -0
- package/substrate/README.md +173 -0
- package/substrate/SECURITY.md +19 -0
- package/substrate/architecture/decisions/ADR-029-release-pipeline.md +79 -0
- package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +139 -0
- package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +192 -0
- package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +145 -0
- package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +155 -0
- package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +162 -0
- package/substrate/lib/clean-artifacts-sweep.sh +112 -0
- package/substrate/lib/code-comment-discipline.sh +144 -0
- package/substrate/lib/composer-preflight.sh +459 -0
- package/substrate/lib/hook-inject.sh +255 -0
- package/substrate/lib/luminary-pick.sh +96 -0
- package/substrate/lib/output-discipline.sh +143 -0
- package/substrate/lib/rewrite-check.sh +214 -0
- package/substrate/lib/state.sh +1372 -0
- package/substrate/lib/telemetry.sh +205 -0
- package/substrate/lib/tier-check.sh +138 -0
- package/substrate/lib/tier-dependency-audit.sh +933 -0
- package/substrate/presence/install/bassclef-hook-connect.sh +178 -0
- package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +841 -0
- package/substrate/presence/install/bassclef-sync.template.sh +2076 -0
- package/substrate/presence/install/schedule-auto-save.cron.sh +88 -0
- package/substrate/presence/install/schedule-auto-save.taskscheduler.md +122 -0
- package/substrate/scripts/aggregate-telemetry.sh +217 -0
- package/substrate/scripts/analyze-tier-dependencies.sh +239 -0
- package/substrate/scripts/generate-lite-manifest.sh +489 -0
- package/substrate/scripts/generate-tier-manifest.sh +28 -0
- package/substrate/scripts/intent-drift-check.sh +456 -0
- package/substrate/scripts/lite-manifest-drift-check.sh +146 -0
- package/substrate/scripts/render-lite-manifest-doc.sh +150 -0
- package/substrate/standards/bassclef-configs-schema.md +232 -0
- package/substrate/standards/bassclef-evolution.md +143 -0
- package/substrate/standards/bassclef-internal-jargon.md +244 -0
- package/substrate/standards/bassclef-managed-sentinel.md +96 -0
- package/substrate/standards/bassclef-source-config.md +228 -0
- package/substrate/standards/deferred-actions-schema.md +204 -0
- package/substrate/standards/docs-sync-allowlist.md +76 -0
- package/substrate/standards/graceful-exit.md +227 -0
- package/substrate/standards/hook-idempotency.md +102 -0
- package/substrate/standards/lite-manifest-schema-changes.md +75 -0
- package/substrate/standards/luminary-problem-patterns.md +481 -0
- package/substrate/standards/ogilvy-writing-rules.md +225 -0
- package/substrate/standards/opener-discipline.md +96 -0
- package/substrate/standards/operator-facing-prose-discipline.md +201 -0
- package/substrate/standards/project-directory-layout.md +276 -0
- package/substrate/standards/release-tagging.md +137 -0
- package/substrate/standards/sdlc-compliance.md +286 -0
- package/substrate/standards/secrets-lifecycle.md +210 -0
- package/substrate/standards/security-scanner-adapter.md +145 -0
- package/substrate/standards/skill-output-discipline.md +90 -0
- package/substrate/standards/state-spine.md +511 -0
- package/substrate/standards/tech-stack-config.md +109 -0
- package/substrate/standards/tier-dependency-analysis.md +167 -0
- package/substrate/standards/tier-runtime-deps/lite.md +57 -0
- package/substrate/standards/tier-tag-schema.md +155 -0
- package/substrate/standards/whereami-schema.md +301 -0
- package/substrate/standards/writing-guide.md +213 -0
- package/substrate/templates/deferred-action-template.md +45 -0
- 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.
|