@thebassclef/lite 1.4.0 → 1.4.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.
Files changed (32) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/lite/.bassclef-source.json +2 -2
  6. package/dist/lite/.claude/hooks/_lib/wirings.sh +237 -0
  7. package/dist/lite/.claude/hooks/pre-commit-manifest-autoregen.sh +187 -0
  8. package/dist/lite/.claude/hooks/session-reflection.d/08-settings-drift.sh +66 -6
  9. package/dist/lite/.claude/hooks/session-reflection.d/20-artifact-staleness.sh +25 -5
  10. package/dist/lite/.claude/hooks/session-reflection.d/30-metrics-staleness.sh +11 -0
  11. package/dist/lite/.claude/hooks/session-reflection.d/60-deferred-actions.sh +2 -1
  12. package/dist/lite/.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh +20 -0
  13. package/dist/lite/.claude/hooks/session-reflection.d/tests/20-artifact-staleness.test.sh +89 -0
  14. package/dist/lite/.claude/hooks/session-reflection.sh +12 -1
  15. package/dist/lite/.claude/luminaries/david-farley.md +115 -0
  16. package/dist/lite/.claude/luminaries/jez-humble.md +124 -0
  17. package/dist/lite/.claude/luminaries/martin-fowler.md +18 -0
  18. package/dist/lite/.claude/skills/longrun/SKILL.md +51 -0
  19. package/dist/lite/.claude/skills/onboard-repo/SKILL.md +39 -11
  20. package/dist/lite/.claude/skills/provision-deploy-host/SKILL.md +2 -2
  21. package/dist/lite/lib/ancestor-claude-check.sh +101 -0
  22. package/dist/lite/lib/fixture-builder.sh +324 -0
  23. package/dist/lite/lib/workflow-metrics.sh +166 -0
  24. package/dist/lite/presence/install/bassclef-configs.template.jsonc +76 -0
  25. package/dist/lite/presence/install/bassclef-sync.template.sh +7 -4
  26. package/dist/lite/scripts/generate-lite-manifest.sh +151 -1
  27. package/dist/lite/scripts/workflow-metrics-query.sh +57 -0
  28. package/dist/lite/standards/lite-manifest-schema-changes.md +24 -0
  29. package/dist/lite/standards/lite-manifest.json +79 -68
  30. package/package.json +1 -1
  31. package/dist/lite/.claude/skills/journal-export/SKILL.md +0 -293
  32. package/dist/lite/.claude/skills/release/SKILL.md +0 -311
@@ -1,293 +0,0 @@
1
- ---
2
- tier: lite
3
- name: journal-export
4
- description: "Generate a structured journal-entry corpus for a brand team or your own archive \u2014 chronicle digest, draft index, moment inventory. Supports incremental updates."
5
- problem: "Journal drafts pile up locally. Brand teams and archives don't get them systematically."
6
- value: "Structured journal-entry corpus for a brand team or your own archive. Chronicle digest included."
7
- inputs: [Time range or theme filter]
8
- outputs: [Corpus JSON, Google Doc export, Archive-ready file]
9
- user_invocable: true
10
- disable_model_invocation: false
11
- requires:
12
- files: [standards/writing-guide.md]
13
- network: true
14
- ---
15
-
16
- # /journal export — Journal-Entry Corpus
17
-
18
- Generate a structured content corpus from session chronicles and existing
19
- drafts. The corpus gives the brand team everything they need to produce
20
- journal entries without understanding the codebase.
21
-
22
- ## Usage
23
-
24
- ```
25
- /journal export → full generation (first run or rebuild)
26
- /journal export incremental → update with new sessions since last export
27
- ```
28
-
29
- ## What the corpus contains
30
-
31
- ### 1. Chronicle digest
32
-
33
- Every session summarized in ~150 words:
34
- - Date and repo
35
- - Theme tags (governance, reliability, design, constraint, methodology, product)
36
- - Key moment (the single most compelling thing that happened)
37
- - Quotable decision or insight (one sentence a brand team member can latch onto)
38
- - Audience fit (Board/PE, Engineering, or both)
39
-
40
- ### 2. Draft index
41
-
42
- Every existing journal entry with:
43
- - Date and source repo
44
- - Topic/title
45
- - Variant (A: Board or B: Engineering)
46
- - Angle taken
47
- - Status (drafted / published / held)
48
- - Hook strength assessment
49
-
50
- ### 3. Moment inventory
51
-
52
- Pre-mined moments across major themes. Each moment has:
53
- - Date, repo, session title
54
- - What happened (2-3 sentences)
55
- - Why it matters as a journal entry (tension, stakes, surprise, result)
56
- - Audience fit and hook strength
57
- - Whether an existing draft already covers this angle
58
-
59
- ### 4. Writing guide bundle
60
-
61
- Packaged for external handoff:
62
- - `standards/writing-guide.md` content (journal-entry style guide)
63
- - Audience definitions (PE/board vs. engineering variants)
64
- - Vocabulary rules (concept names, not implementation details)
65
- - Post structure (Hook → Setup → Body → Takeaway)
66
-
67
- ## Procedure
68
-
69
- ### Step 1: Locate all sources
70
-
71
- ```
72
- Chronicles:
73
- ~/src/sunj-labs/bassclef/chronicle/
74
- ~/src/your-org/your-app/docs/chronicle/
75
- ~/src/your-org/your-second-app/docs/chronicle/
76
-
77
- Existing drafts:
78
- ~/src/sunj-labs/bassclef/docs/operator-private/journals/
79
- ~/src/your-org/your-app/docs/operator-private/journals/
80
- ~/src/your-org/your-app/docs/operator-private/journals/legacy/ (pre-substrate content)
81
-
82
- Writing guide:
83
- ~/src/sunj-labs/bassclef/standards/writing-guide.md
84
- ```
85
-
86
- ### Step 2: Check for previous export
87
-
88
- Look for `docs/journal-corpus/` in bassclef. If it exists and the
89
- mode is `incremental`:
90
- - Read `docs/journal-corpus/last-export.md` for the last export date
91
- - Only process chronicles and drafts newer than that date
92
- - Append to existing corpus sections
93
-
94
- If full mode or no previous export: generate everything from scratch.
95
-
96
- ### Step 3: Read all chronicles
97
-
98
- For each chronicle:
99
- 1. Read the full file
100
- 2. Extract: date, repo, title, tags, key decisions, notable moments
101
- 3. Assign theme tags from this list:
102
- - **governance**: rules, gates, guardrails, permissions, ADRs, hooks
103
- - **reliability**: failures, diagnosis, fixes, what broke, resilience
104
- - **design**: luminaries, prototypes, visual review, UX migration, taste
105
- - **constraint**: budget, time budget, scope kills, trade-offs, real stakes
106
- - **methodology**: SDLC, choreography, skills, agents, substrate, process
107
- - **product**: features built, user-facing outcomes, family use, deals
108
- - **infrastructure**: deployment, CI/CD, bassclef sync, tooling
109
- 4. Identify the key moment (strongest journal-worthy content)
110
- 5. Rate audience fit and hook strength
111
-
112
- ### Step 4: Read all existing drafts
113
-
114
- For each draft:
115
- 1. Read the file
116
- 2. Extract: date, topic/title, variant, audience, angle
117
- 3. Note status (drafts in legacy/ are "pre-substrate")
118
-
119
- ### Step 5: Pre-mine major themes
120
-
121
- Run theme matching (same logic as `/journal mine`) for these themes:
122
- - "The autonomous SDLC journey"
123
- - "Governance that scales"
124
- - "Building under constraint"
125
- - "Design taste in AI agents"
126
- - "What broke"
127
- - "From zero to production"
128
-
129
- Surface top 3-5 moments per theme.
130
-
131
- ### Step 6: Assemble the corpus
132
-
133
- Write to `docs/journal-corpus/`:
134
-
135
- ```
136
- docs/journal-corpus/
137
- corpus.md # main document — digest + index + inventory
138
- last-export.md # metadata for incremental updates
139
- writing-guide.md # copy of standards/writing-guide.md for handoff
140
- ```
141
-
142
- **corpus.md** structure:
143
-
144
- ```markdown
145
- # Content Corpus — <your-org>
146
-
147
- Generated: YYYY-MM-DD
148
- Sessions covered: N (Dec 2025 - [latest])
149
- Repos: <list-the-repos-you-mine-chronicles-from>
150
-
151
- ## How to use this document
152
-
153
- This corpus contains the raw material for journal-entry content. Each session
154
- is summarized with theme tags and a key moment. To write a post:
155
-
156
- 1. Pick a theme or topic you want to write about
157
- 2. Find moments that serve that theme (use the theme index below)
158
- 3. Pick the strongest moment
159
- 4. Draft a standalone post — every post must work on its own,
160
- even if it covers a theme you've posted about before
161
-
162
- ## Chronicle digest
163
-
164
- ### [Repo name]
165
-
166
- | Date | Title | Themes | Key moment | Audience | Hook |
167
- |------|-------|--------|-----------|----------|------|
168
- | ... | ... | ... | ... | ... | ... |
169
-
170
- [For each session, a ~150 word summary follows the table]
171
-
172
- ## Draft index
173
-
174
- | Date | Repo | Title | Variant | Audience | Angle | Status |
175
- |------|------|-------|---------|----------|-------|--------|
176
- | ... | ... | ... | ... | ... | ... | ... |
177
-
178
- ## Moment inventory by theme
179
-
180
- ### [Theme name]
181
-
182
- | # | Date | Repo | Moment | Why it's strong | Hook |
183
- |---|------|------|--------|-----------------|------|
184
- | ... | ... | ... | ... | ... | ... |
185
-
186
- [Repeated for each theme]
187
-
188
- ## Writing guide
189
-
190
- [Full writing guide content]
191
- ```
192
-
193
- ### Step 7: Push to Google Docs
194
-
195
- Push the corpus to the brand team corpus doc. Read the doc ID from
196
- bassclef's `substrate.config.md` field `brand_corpus_doc_id` — never
197
- hardcode (per `standards/substrate-config-schema.md`):
198
-
199
- ```bash
200
- DOC_ID=$(grep "^brand_corpus_doc_id:" substrate.config.md | awk '{print $2}')
201
- npx tsx ~/src/your-org/your-app/scripts/push-to-gdoc.ts \
202
- --file docs/journal-corpus/corpus.md --replace \
203
- --doc-id "$DOC_ID"
204
- ```
205
-
206
- Use `--replace` to clear the doc first and re-push the full corpus
207
- (appending accumulates duplicates over time).
208
-
209
- The brand team corpus doc is separate from per-repo draft docs. It
210
- contains session digests, moment inventory, and writing guide — not
211
- the full post drafts. The per-repo drafts push separately at session-
212
- end using each repo's `journal_doc_id`.
213
-
214
- All doc IDs live in `substrate.config.md` — never hardcoded here,
215
- never stored in memory. See `standards/substrate-config-schema.md`
216
- for the bassclef field convention.
217
-
218
- ### Step 7a: Defer push when capabilities missing
219
-
220
- If `brand_corpus_doc_id` is configured but this session cannot push
221
- (missing `gcloud-auth` / `google-docs-write` — ephemeral-mobile,
222
- cloud-web, or desktop without the SA key), DO NOT silently skip. Write
223
- a deferred-action entry:
224
-
225
- ```bash
226
- TS=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
227
- ID="${TS}-journal-export-corpus-push"
228
- cp templates/deferred-action-template.md \
229
- "docs/deferred-actions/${ID}.md"
230
- # Fill frontmatter:
231
- # pending_action: push-brand-corpus-to-gdoc
232
- # requires_capability: [gcloud-auth, google-docs-write]
233
- # priority: medium
234
- # origin_skill: /journal-export
235
- # resolves_when: |
236
- # Brand corpus doc <brand_corpus_doc_id> reflects docs/journal-corpus/corpus.md
237
- # Body should cross-ref the corpus file + last-export.md.
238
- git add "docs/deferred-actions/${ID}.md"
239
- git commit -m "chore: defer journal-export corpus-push"
240
- ```
241
-
242
- See `.claude/rules/deferred-actions.md` and
243
- `standards/deferred-actions-schema.md`.
244
-
245
- ### Step 8: Record metadata
246
-
247
- Write `docs/journal-corpus/last-export.md`:
248
-
249
- ```markdown
250
- ---
251
- last_export: YYYY-MM-DD
252
- sessions_covered: N
253
- repos: [<list of mined repos>]
254
- chronicles_processed: N
255
- drafts_indexed: N
256
- themes_mined: N
257
- ---
258
- ```
259
-
260
- ## Incremental mode
261
-
262
- When called with `incremental`:
263
- 1. Read `last-export.md` for the cutoff date
264
- 2. Only read chronicles newer than the cutoff
265
- 3. Only read drafts newer than the cutoff
266
- 4. Append new sessions to the chronicle digest
267
- 5. Append new drafts to the draft index
268
- 6. Re-run theme mining with new material included
269
- 7. Update `last-export.md` with new date and counts
270
-
271
- ## Rules
272
-
273
- - The corpus is for external consumption — no internal jargon, file paths,
274
- or skill names unless they're in the vocabulary guide
275
- - Every session gets a summary even if it's "low" hook strength —
276
- the brand team decides what's worth writing about
277
- - Theme tags are additive — a session can have multiple themes
278
- - The writing guide section uses the SENTINEL_bassclef_version verbatim
279
- - Incremental updates append, never overwrite existing entries
280
-
281
- ## Scheduled refresh (Level 1 automation)
282
-
283
- The brand team corpus can be kept fresh automatically via a scheduled agent.
284
- See `docs/journal-corpus/REFRESH.md` for:
285
-
286
- - Manual refresh procedure (step-by-step bash commands)
287
- - Automated refresh setup using the `/schedule` skill (weekly, Monday 9am)
288
- - A map of all three Google Docs and how each one stays current
289
- - Troubleshooting guide
290
-
291
- ## Output discipline
292
-
293
- Dispatch `/kiss words --rewrite` on your skill output before you return it. See `standards/skill-output-discipline.md` for the contract.
@@ -1,311 +0,0 @@
1
- ---
2
- name: release
3
- description: "Ship framework files from bassclef-upstream to public bassclef, filtered by tier. Dry-runs first, reports tier counts plus andon scan plus sibling smoke evidence. On operator confirm runs the live release and opens a PR. Per ADR-029."
4
- problem: "Framework files ship from upstream to public bassclef through many manual steps. Dry-run catches slip past."
5
- value: "Ships framework files from bassclef-upstream to public bassclef. Filtered by tier. Dry-runs first."
6
- inputs: [Optional tier filter, Dry-run or apply flag]
7
- outputs: [Files shipped, Dry-run diff, Public PR, Tag drop]
8
- tier: lite
9
- user_invocable: true
10
- disable_model_invocation: false
11
- modes: [default, --dry-run, --skip-dry-run]
12
- composes_with: [verify, state-a-problem, value-prop, kiss]
13
- ---
14
- <!-- andon-allow: operator-private -->
15
- <!-- andon-allow: bassclef-upstream -->
16
-
17
- # /release
18
-
19
- ## What you get
20
-
21
- A staged path to ship framework files from bassclef-upstream to public bassclef.
22
-
23
- `/release` runs a dry-run first. It reports the tier filter result. It reports the andon scan. It reports the sibling smoke evidence. It waits for your confirmation. Then it runs `/verify`. Then it executes the live release.
24
-
25
- The live step does five things. It tags the source SHA. It rsyncs the filtered set to the target. It commits on a release branch in public bassclef. It opens a PR. After you merge the PR, it cuts semver tags on both repos with matching names.
26
-
27
- Per ADR-040 Decision 5, a second target — `bassclef-lite` — ships alongside `bassclef` for solo adopters. Same pipeline. Different tier filter. Both targets share the andon scan and sibling smoke discipline.
28
-
29
- ## When to use it
30
-
31
- - You shipped one or more framework changes locally and want them in public bassclef.
32
- - A session closed a goal whose acceptance includes "shipped to public."
33
- - You are preparing Doors Open and need to prove the pipeline works.
34
-
35
- Adopter sessions do not run `/release`. Adopters read the public bassclef release page and pull via `bassclef-sync`. Only bassclef-upstream sessions ship releases.
36
-
37
- ## When NOT to use
38
-
39
- Do not use `/release` to file evolution tickets. That is `/promote`. Do not use it to sync docs. That is `/docs-sync`. Do not use it on a dirty source tree. Commit or stash first. Do not use it when a prior release PR is still open on public. The new one would stack cumulatively.
40
-
41
- ## FAQ
42
-
43
- ### What are the steps of a release?
44
-
45
- 1. Dry-run — reports tier counts, andon scan, target dir, sibling smoke prompt.
46
- 2. Sibling smoke evidence — you paste PASS / FAIL / DEFERRED per the sibling-smoke rule.
47
- 3. Operator confirmation — you approve or decline the ship.
48
- 4. `/verify` — post-build check against the changes.
49
- 5. Live release — tag source, rsync filtered set, commit + push release branch, open PR.
50
- 6. PR body amend — replace the template stub with the recap drafted before Step 1.
51
- 7. Report — surface the PR URL.
52
- 8. Semver tag on both repos after the PR merges.
53
-
54
- ### Why dry-run first?
55
-
56
- The dry-run reports what the live release will do. It does not touch public bassclef. You see tier counts. You see andon scan hits. You see the target directory. You see the sibling smoke evidence prompt.
57
-
58
- If andon trips, the dry-run stops. It asks you to fix the offending file. Retag `tier: private`. Or scrub the leak. Or add `# andon-allow: <term>` header. Then retry.
59
-
60
- ### What is the sibling smoke evidence step?
61
-
62
- Per the sibling-smoke rule, some releases need a real Claude Code session on a sibling repo before shipping. This applies to releases touching adopter-observable files — hooks, rules, skills, agents, lib, schemas, sync templates.
63
-
64
- You paste one of:
65
-
66
- ```
67
- PASS: Sibling smoke: ran <sibling-repo> SessionStart at <ISO>; clean — <observation>
68
- FAIL: Sibling smoke: ran <sibling-repo> SessionStart at <ISO>; FAIL — <observation>
69
- DEFERRED: <rationale>; follow-on tracked at #<NNN>
70
- ```
71
-
72
- Silence is not deferral. The default is "run the smoke before /release."
73
-
74
- - **PASS** — proceed to Step 3.
75
- - **FAIL** — STOP. The release holds until the fix ships and a follow-up smoke confirms PASS.
76
- - **DEFERRED** — proceed only when the rationale names a non-blocking case (pure no-behavior rename). Cite a follow-on ticket. Otherwise STOP.
77
-
78
- V1 is ADVISORY. Silence is logged as a discipline miss but does not block dispatch. V2 flips to BLOCK once one calibration cycle ships.
79
-
80
- ### What does the live release step actually do?
81
-
82
- The script `scripts/release-to-bassclef.sh` does six things:
83
-
84
- 1. Pre-flight — dirty-tree guard on source AND target.
85
- 2. Tags source — `release-YYYY-MM-DD-<sha>`.
86
- 3. Re-runs tier filter and andon scan. Defense in depth. Files may have changed since dry-run.
87
- 4. rsyncs the filtered set to the target with a constrained `--delete`.
88
- 5. Commits in the target on `release/YYYY-MM-DD-<sha>` branch.
89
- 6. Pushes the branch and opens a PR against public bassclef `main`.
90
-
91
- For the bassclef-lite target (per ADR-040 D5), a sibling branch opens with `tier: lite | standard` filter. It uses a distinct release tag suffix.
92
-
93
- ### What does the PR body amend step do?
94
-
95
- The script writes a template body with the stub "Operator amends with the substantive changes in this release window." Adopters reading the PR see this stub instead of the actual story.
96
-
97
- Step 4.5 replaces the stub with the recap drafted before Step 1. The recap carries Problem + Summary + Test plan sections. It composes `/state-a-problem brief` + `/value-prop tweet` + session log entries.
98
-
99
- The step reads the just-opened PR body. It scans for the stub. If the stub is present, it amends via `gh pr edit`. Step 5 does not fire until the amendment lands OR `SKIP_RELEASE_PR_AMEND=1` is set.
100
-
101
- ### How do the semver tags work after the PR merges?
102
-
103
- Per ADR-039 and the release-tagging standard, after you merge the release PR:
104
-
105
- 1. Draft the tag name. The skill reads the change set and proposes a bump per semver policy.
106
- - **Major** — adopter-visible breaking change (rename, tier vocab, ADR-031 level).
107
- - **Minor** — new substrate surface.
108
- - **Patch** — cure only.
109
- 2. Draft release notes. Group by rule / hook / skill / standard / luminary / agent / ADR / cure. One line per PR with links. Apply `/kiss --grade10` to the body BEFORE writing to file per bassclef-upstream#634. The `pre-gh-release-body-scrub.sh` hook fires on `gh release create`. Unscrubbed notes BLOCK the call.
110
- 3. Cut the tag on both repos with the same name. `bassclef-upstream` is the source of truth. The tag on public `bassclef` (and `bassclef-lite`) is what adopters see. The GitHub Release page publishes on public bassclef only.
111
-
112
- First tag ever cut is `v0.1.0`. Confirm the tag name at Step 2 before the pipeline runs.
113
-
114
- ### What does /release refuse to do?
115
-
116
- - Dirty source tree. Commit or stash first.
117
- - Dirty target tree. Commit or stash in `~/src/sunj-labs/bassclef/` first.
118
- - Andon scan hit per ADR-029. Andon is required, not advisory.
119
- - Invalid tier value on any file. Must be `private | basic | premium | public | lite | standard`.
120
- - Tag collision. A release tag already exists at this SHA. Release was already cut today.
121
-
122
- ## Details below the fold
123
-
124
- ### Procedure — full
125
-
126
- **Step 1 — Dry-run.**
127
-
128
- ```bash
129
- bash scripts/release-to-bassclef.sh --dry-run
130
- ```
131
-
132
- Output reports source SHA. Would-be release tag. Tier bucket counts. Andon result. Target dir. Sibling smoke evidence prompt.
133
-
134
- If andon trips, STOP. Cure per FAQ above.
135
-
136
- **Step 1.5 — Sibling smoke evidence.** Paste PASS / FAIL / DEFERRED per the FAQ.
137
-
138
- **Step 2 — Operator confirmation.** Surface the dry-run summary. Ask: "Ship $count_inc files (tier=basic|public) to public bassclef on branch release-YYYY-MM-DD-<sha>?" Decline stops. Approve proceeds.
139
-
140
- **Step 3 — /verify.** Run `/verify`. It runs the check against your changes (substrate-clarity-gate on edits, etc.). It catches anything the dry-run missed.
141
-
142
- **Step 4 — Live release.** `bash scripts/release-to-bassclef.sh`. See FAQ for what the script does.
143
-
144
- **Step 4.5 — Amend PR body.** Read the just-opened PR body. Scan for the template stub. If present, amend via `gh pr edit --body-file <recap-file>`. Re-read to confirm the stub is gone. Step 5 does not fire until this lands.
145
-
146
- **Step 5 — Report.** Surface the PR URL. You review and merge in public bassclef.
147
-
148
- **Step 6 — Cut semver tags.** After the PR merges, draft release notes. Run `/kiss` on the notes. Then run the automation script (per bassclef-upstream#1005).
149
-
150
- The script does the rest. It reads the notes. It infers the semver bump. It cuts tags on both repos. It creates the GitHub Release page.
151
-
152
- ```bash
153
- # Dry-run first — always
154
- RELEASE_STEP6_DRY_RUN=1 bash scripts/release-step6.sh release-notes-<version>.md
155
-
156
- # Confirm the proposed tag, then live
157
- bash scripts/release-step6.sh release-notes-<version>.md
158
- ```
159
-
160
- Override env vars:
161
-
162
- - `RELEASE_STEP6_OVERRIDE_VERSION=v0.23.0` — skip the auto-bump. Use for major bumps.
163
- - `RELEASE_STEP6_TITLE="Custom title"` — override the title.
164
- - `SOURCE_REPO=<path>` and `TARGET_REPO=<path>` — override repo paths.
165
-
166
- The script fails fast on three cases. Missing notes file. Empty delta since last tag. Tag collision on source. See `.claude/hooks/tests/release-step6.test.sh` for the 6 covered cases.
167
-
168
- **Manual fallback:** if the script is not available, run `git tag` on both repos and `gh release create --latest` manually. See `standards/release-tagging.md` for the exact commands.
169
-
170
- ### Self-check step — before drafting the recap
171
-
172
- Before drafting the recap that feeds Step 4.5:
173
-
174
- 1. Read your draft against `standards/bassclef-internal-jargon.md` BLOCK terms.
175
- 2. Rewrite any BLOCK matches in plain English.
176
- 3. Compose the Problem section via `/state-a-problem brief`. The draft carries `/kiss --grade10` inline by default.
177
- 4. Compose the flash claim via `/value-prop tweet`.
178
- 5. Write the recap file.
179
-
180
- The `pre-gh-release-body-scrub.sh` hook is the safety net at the GitHub Release page. This self-check catches misses at the PR body surface.
181
-
182
- ### Modes
183
-
184
- - Default — dry-run then confirm then ship. Best for adopters and first runs.
185
- - `/release --skip-dry-run` — jump straight to live. Use only when you just ran a dry-run and want to skip the duplicate.
186
- - `/release --dry-run` — dry-run only. The live release does not fire under this flag.
187
- INSTEAD of skipping the live step when you intend to ship: use the default mode.
188
-
189
- ### Override paths
190
-
191
- - `BASSCLEF_PUBLIC_DIR=<path>` — override target dir. Falls back to a default path.
192
- - `SKIP_ANDON=1` — bypass andon scan.
193
- INSTEAD of bypassing in production: cure the offending file. Re-run the dry-run.
194
- - `SKIP_SIBLING_SMOKE=1` — bypass Step 1.5 sibling-smoke prompt.
195
- INSTEAD of bypassing routinely: run the smoke. Or defer with a follow-on ticket.
196
- - `SKIP_RELEASE_PR_AMEND=1` — allow Step 5 to fire with the stub still present.
197
- INSTEAD of habitually skipping the amend: draft the recap before Step 1.
198
- - `SKIP_RELEASE_TAG=1` — skip Step 6 for infrastructure fixes that ship before the next planned release window.
199
-
200
- ### Reads
201
-
202
- - `.claude/skills/*/SKILL.md`, `.claude/luminaries/*.md`, `.claude/rules/*.md`, `.claude/hooks/*.sh`, `architecture/decisions/*.md`, `standards/*.md` — files carrying `tier:` field
203
- - `standards/bassclef-internal-jargon.md` — andon scan term source (BLOCK tier)
204
- - `CLAUDE.md`, `substrate.config.md` — top-level docs shipped as-is
205
-
206
- ### Writes
207
-
208
- - `~/src/sunj-labs/bassclef/` (or `BASSCLEF_PUBLIC_DIR`) — filtered framework via rsync
209
- - (Per ADR-040 D5) `~/src/sunj-labs/bassclef-lite/` — the lite tier subset, once the sibling repo ships
210
- - A new branch and PR in public bassclef (and in bassclef-lite, per D5)
211
- - A git tag `release-YYYY-MM-DD-<sha>` in bassclef-upstream
212
-
213
- ### Grace window on old vocabulary
214
-
215
- Old vocabulary still works through 2026-10-31 per ADR-031 and the we-dont-break-adopters rule. Old terms — `bet`, `appetite`, `step`, `chronicle`. The `/chronicle` skill name still resolves alongside `/session-log`.
216
-
217
- ## Examples
218
-
219
- <!-- FKGL-EXEMPT: sample dry-run output -->
220
-
221
- **Dry-run summary (clean):**
222
-
223
- ```
224
- === /release dry-run ===
225
- Source SHA: 2ceb53b7
226
- Would-be tag: release-2026-07-19-2ceb53b7
227
- Files by tier:
228
- include (basic + public + untagged): 47
229
- exclude (private + upstream): 23
230
- Andon scan: CLEAN
231
- Target dir: ~/src/sunj-labs/bassclef/
232
- ```
233
-
234
- **Andon trip (STOP):**
235
-
236
- ```
237
- === /release dry-run ===
238
- Andon scan: 2 HITS
239
- - standards/foo.md line 42: BLOCK term hit
240
- - .claude/rules/bar.md line 8: BLOCK term hit
241
- STOP.
242
- ```
243
-
244
- <!-- /FKGL-EXEMPT -->
245
-
246
- ## Anti-patterns and INSTEAD
247
-
248
- | Anti-pattern | INSTEAD |
249
- |---|---|
250
- | Skip dry-run and go straight to live | Run dry-run first. The andon scan and tier counts protect against leaks |
251
- | Merge past an andon hit by setting SKIP_ANDON | Fix the file (retag or scrub or allowlist) and run dry-run again |
252
- | Silence a FAIL sibling-smoke and dispatch anyway | Hold the release. Ship the cure first. Confirm smoke PASS on the next run |
253
- | Skip Step 4.5 and let the release PR ship with the template stub | Amend the PR body with the drafted recap so adopters read the real story |
254
- | Fire /release when a prior release PR is open on public | Wait for the prior PR to merge. Otherwise the new PR would stack cumulatively |
255
-
256
- ## Composes with
257
-
258
- - `/verify` — Step 3 runs verify against the changes before live release.
259
- - `/state-a-problem` — drafts the recap for Step 4.5 PR body amendment.
260
- - `/value-prop` — flash summary for the same recap.
261
- - `/kiss` — applied at Step 2b before release notes write.
262
-
263
- ## Distinct from
264
-
265
- - `/promote` — files a `bassclef-evolution` ticket for framework change proposals. `/release` ships changes already decided. `/promote` proposes them.
266
- - `/docs-sync` — syncs adopter docs to GitHub Wiki. Separate channel. Not the release pipeline.
267
-
268
- ## Rules
269
-
270
- - Do not write to public bassclef without a clean andon scan. INSTEAD, fix any hits before dispatch.
271
- - Do not dispatch live release with a dirty source or target tree. INSTEAD, commit or stash first.
272
- - Do not skip Step 1.5 without explicit operator deferral. INSTEAD, run the smoke or file a follow-on ticket.
273
- - Do not skip Step 4.5. Adopters read the PR body first. INSTEAD, amend the stub before Step 5.
274
- - Always cut semver tags on both repos with the same name at Step 6.
275
-
276
- ## Test cases
277
-
278
- <!-- FKGL-EXEMPT: structured test spec -->
279
- | ID | Prompt | Expected behavior |
280
- |---|---|---|
281
- | T1 | `/release` on a clean tree with no adopter-observable changes | Dry-run reports counts + CLEAN andon; sibling-smoke prompt fires; operator confirmation gates live |
282
- | T2 | `/release` when standards/foo.md contains a BLOCK term | Andon trips; STOP; message names line + term |
283
- | T3 | `/release --dry-run` | Dry-run only; live release does not fire |
284
- | T4 | `/release --skip-dry-run` when just ran dry-run | Live release fires without repeating dry-run |
285
- | T5 | `/release` when a prior release PR is open on public | STOP with a stack warning |
286
- | T6 | Sibling smoke returns FAIL | Release held; PR does not open until cure ships |
287
- <!-- /FKGL-EXEMPT -->
288
-
289
- ## Sources read
290
-
291
- - ADR-029 release pipeline
292
- - ADR-039 release tagging policy
293
- - ADR-040 planning-skill vocabulary and lite profile (Decision 5 — two-repo release)
294
- - `.claude/rules/sibling-smoke-after-substrate-change.md`
295
- - `.claude/rules/plain-english-discipline.md`
296
- - `.claude/rules/we-dont-break-adopters.md`
297
- - `standards/tier-tag-schema.md`
298
- - `standards/release-tagging.md`
299
- - `standards/bassclef-internal-jargon.md`
300
- - `scripts/release-to-bassclef.sh`
301
- - bassclef-upstream#634 — /kiss on release notes
302
- - bassclef-upstream#694 — PR body amend at Step 4.5
303
- - bassclef-upstream#545 V2 — sibling-smoke prompt at Step 1.5
304
-
305
- ## Why this skill exists
306
-
307
- Cross-repo releases without discipline leak private content into public. They mismatch tags across repos. They ship template stubs that adopters read as the release story. `/release` enforces the pipeline. Leaks get caught before writes. Tags match on both repos. Adopters read the real recap. Without `/release`, cross-repo shipping is manual clickops or bypasses the andon gate.
308
-
309
- ## Output discipline
310
-
311
- Dispatch `/kiss words --rewrite` on your skill output before you return it. See `standards/skill-output-discipline.md` for the contract.