@thebassclef/lite 1.3.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.
- package/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.bassclef-source.json +2 -2
- package/dist/lite/.claude/hooks/_lib/wirings.sh +237 -0
- package/dist/lite/.claude/hooks/pre-commit-manifest-autoregen.sh +187 -0
- package/dist/lite/.claude/hooks/session-reflection.d/08-settings-drift.sh +66 -6
- package/dist/lite/.claude/hooks/session-reflection.d/20-artifact-staleness.sh +25 -5
- package/dist/lite/.claude/hooks/session-reflection.d/30-metrics-staleness.sh +11 -0
- package/dist/lite/.claude/hooks/session-reflection.d/60-deferred-actions.sh +2 -1
- package/dist/lite/.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh +20 -0
- package/dist/lite/.claude/hooks/session-reflection.d/tests/20-artifact-staleness.test.sh +89 -0
- package/dist/lite/.claude/hooks/session-reflection.sh +12 -1
- package/dist/lite/.claude/luminaries/david-farley.md +115 -0
- package/dist/lite/.claude/luminaries/jez-humble.md +124 -0
- package/dist/lite/.claude/luminaries/martin-fowler.md +18 -0
- package/dist/lite/.claude/skills/longrun/SKILL.md +51 -0
- package/dist/lite/.claude/skills/onboard-repo/SKILL.md +39 -11
- package/dist/lite/.claude/skills/provision-deploy-host/SKILL.md +2 -2
- package/dist/lite/lib/ancestor-claude-check.sh +101 -0
- package/dist/lite/lib/fixture-builder.sh +324 -0
- package/dist/lite/lib/workflow-metrics.sh +166 -0
- package/dist/lite/presence/install/bassclef-configs.template.jsonc +76 -0
- package/dist/lite/presence/install/bassclef-sync.template.sh +7 -4
- package/dist/lite/scripts/generate-lite-manifest.sh +151 -1
- package/dist/lite/scripts/workflow-metrics-query.sh +57 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +24 -0
- package/dist/lite/standards/lite-manifest.json +79 -68
- package/package.json +1 -1
- package/dist/lite/.claude/skills/journal-export/SKILL.md +0 -293
- 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.
|