@thebassclef/lite 1.9.9 → 1.9.11
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/.claude/hooks/artifact-ingestion-gate.sh +9 -3
- package/dist/lite/.claude/hooks/pre-commit-gate.sh +31 -0
- package/dist/lite/.claude/hooks/pre-commit-identifier-leak-scrub.sh +58 -2
- package/dist/lite/.claude/hooks/save-state.sh +6 -1
- package/dist/lite/.claude/hooks/session-reflection.d/83-install-written-paths-rebuild.sh +111 -0
- package/dist/lite/.claude/hooks/session-reflection.d/97-last-block-count.sh +53 -0
- package/dist/lite/.claude/hooks/session-reflection.d/tests/97-last-block-count.test.sh +131 -0
- package/dist/lite/.claude/hooks/session-reflection.sh +22 -0
- package/dist/lite/.claude/hooks/state-validate.sh +8 -0
- package/dist/lite/.claude/rules/install-written-paths-mediation.md +74 -0
- package/dist/lite/.claude/rules/last-block-marker.md +79 -0
- package/dist/lite/.claude/skills/autonomous/SKILL.md +53 -7
- package/dist/lite/.claude/skills/build/SKILL.md +41 -5
- package/dist/lite/.claude/skills/deploy-prod/SKILL.md +10 -0
- package/dist/lite/.claude/skills/ia-model/SKILL.md +8 -0
- package/dist/lite/.claude/skills/interaction-design/SKILL.md +8 -0
- package/dist/lite/.claude/skills/jtbd-tasks/SKILL.md +9 -1
- package/dist/lite/.claude/skills/last-block/SKILL.md +99 -0
- package/dist/lite/.claude/skills/launch/SKILL.md +44 -12
- package/dist/lite/.claude/skills/objectory-decompose/SKILL.md +5 -17
- package/dist/lite/.claude/skills/onboard-repo/SKILL.md +18 -18
- package/dist/lite/.claude/skills/personas/SKILL.md +1 -1
- package/dist/lite/.claude/skills/use-case/SKILL.md +5 -4
- package/dist/lite/bassclef-version.json +5 -5
- package/dist/lite/lib/capability-probe.sh +39 -1
- package/dist/lite/lib/composer-preflight.sh +20 -4
- package/dist/lite/lib/install-written-paths.sh +369 -0
- package/dist/lite/lib/last-block.sh +153 -0
- package/dist/lite/lib/luminary-pick.sh +35 -13
- package/dist/lite/lib/state.sh +82 -11
- package/dist/lite/scripts/interpret-input.sh +19 -4
- package/dist/lite/standards/lite-manifest-schema-changes.md +115 -0
- package/dist/lite/standards/lite-manifest.json +80 -26
- package/dist/lite/standards/state-spine.md +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
title: Last-block marker
|
|
4
|
+
anchor_luminaries:
|
|
5
|
+
- john-ousterhout
|
|
6
|
+
- tony-hoare
|
|
7
|
+
- michael-feathers
|
|
8
|
+
- don-norman
|
|
9
|
+
- alan-cooper
|
|
10
|
+
- steve-krug
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Last-block marker
|
|
14
|
+
|
|
15
|
+
Every call to `blocked_banner()` or `guardrail_banner()` in `.claude/hooks/session-reflection.sh` persists a marker at `state/markers/last-block/<hook>.marker`. The marker carries the hook name, severity, timestamp, and verbatim banner text. The `/last-block` skill reads markers back.
|
|
16
|
+
|
|
17
|
+
This rule is the methodology layer. The mechanical layer is `lib/last-block.sh` sourced by `session-reflection.sh`. Both required together to close Kunal Finding #10.
|
|
18
|
+
|
|
19
|
+
## When this rule fires
|
|
20
|
+
|
|
21
|
+
Every call to `blocked_banner()` or `guardrail_banner()` in `.claude/hooks/session-reflection.sh`. The banner helpers already call `record_last_block` from the sourced lib. Hook authors who call these helpers get the marker for free.
|
|
22
|
+
|
|
23
|
+
## Marker format
|
|
24
|
+
|
|
25
|
+
Plaintext layout per `lib/last-block.sh`:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
hook: <hook-name>
|
|
29
|
+
severity: blocking|advisory|info|guardrail
|
|
30
|
+
fired_at: <ISO-8601 UTC>
|
|
31
|
+
session: <CLAUDE_SESSION_ID or "unknown">
|
|
32
|
+
---
|
|
33
|
+
<verbatim banner text, truncated at 8KB with a truncation marker>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Grep-friendly. One marker file per hook. Overwrites on each fire. No rotation in V1.
|
|
37
|
+
|
|
38
|
+
## What the rule requires
|
|
39
|
+
|
|
40
|
+
For hooks that fire BLOCK via `blocked_banner()` or `guardrail_banner()`:
|
|
41
|
+
|
|
42
|
+
- Pass the hook name via the `BASSCLEF_CALLING_HOOK` env var before the call. The default is `session-reflection` when unset.
|
|
43
|
+
- Pass a plain severity (`blocking` / `advisory` / `info`) to `blocked_banner()` as the second arg.
|
|
44
|
+
- The banner helper writes the marker on its own. No extra step.
|
|
45
|
+
|
|
46
|
+
For hooks that fire BLOCK via plain `echo` to stderr (not via the shared helpers):
|
|
47
|
+
|
|
48
|
+
- Follow-on retrofit per `.claude/rules/bootstrap-pair-discipline.md`. Adopt the shared helpers when the hook is next touched.
|
|
49
|
+
|
|
50
|
+
## Anti-patterns
|
|
51
|
+
|
|
52
|
+
**Hook writes a marker directly without using the lib.**
|
|
53
|
+
INSTEAD source `lib/last-block.sh` and call `record_last_block`. The lib owns the format.
|
|
54
|
+
|
|
55
|
+
**Marker format drift.**
|
|
56
|
+
INSTEAD the plaintext layout stays pinned in `lib/last-block.sh`. Change the lib + Tier 0 tests + this rule in one PR.
|
|
57
|
+
|
|
58
|
+
**BLOCK banner emitted directly to stderr without recording.**
|
|
59
|
+
INSTEAD route through `blocked_banner()` so the marker lands with the banner. If a hook has a reason to skip the shared helper, call `record_last_block` directly after the echo.
|
|
60
|
+
|
|
61
|
+
## Override
|
|
62
|
+
|
|
63
|
+
`SKIP_LAST_BLOCK_RECORD=1` bypasses marker recording for one call. Logged via trace-helper. Rare — mostly for test fixtures that need to control marker writing timing.
|
|
64
|
+
|
|
65
|
+
## Composes with
|
|
66
|
+
|
|
67
|
+
- `.claude/rules/blocked-items.md` — sister rule; the two banner shapes live there, and this rule adds the persistence requirement
|
|
68
|
+
- `.claude/rules/bootstrap-pair-discipline.md` — this rule + lib + skill + tests + settings wire ship together
|
|
69
|
+
- `.claude/rules/testing-tier-config.md` — Tier 0 strict TDD on `lib/last-block.sh`
|
|
70
|
+
- `.claude/rules/we-dont-break-adopters.md` — additive change; existing banner callers see no behavior change
|
|
71
|
+
- `.claude/hooks/session-reflection.sh` — the hook that sources the lib + calls record_last_block from both banner helpers
|
|
72
|
+
- `lib/last-block.sh` — the deep module
|
|
73
|
+
- `.claude/skills/last-block/SKILL.md` — the user-invocable surface
|
|
74
|
+
- @luminary john-ousterhout — deep module anchor
|
|
75
|
+
- @luminary tony-hoare — pre/postcondition anchor (write path fail-soft)
|
|
76
|
+
- @luminary michael-feathers — characterization anchor (Tier 0 tests pin every path)
|
|
77
|
+
- @luminary don-norman — signifier (banner footer teaches the recovery path)
|
|
78
|
+
- @luminary alan-cooper — goal-directed (one goal: get banner text back)
|
|
79
|
+
- @luminary steve-krug — discoverability (no-args default)
|
|
@@ -15,15 +15,19 @@ requires:
|
|
|
15
15
|
|
|
16
16
|
# Autonomous Development
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
<!-- FKGL-EXEMPT: cli#331 cure — orientation block names skill scope + tier split. Short SVO loses the tier contract. -->
|
|
19
|
+
Entry point for autonomous SDLC sessions. Use in any repo inheriting bassclef.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
**Lite adopters:** this file is self-contained. The `## Lite procedure` block below has the minimum steps to run `/autonomous start`. No `strategy/` file is needed at lite tier.
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
**Standard and ultra adopters:** deeper procedure lives in these standard-tier files:
|
|
24
|
+
|
|
25
|
+
- `strategy/autonomous-dry-run.md` — read-only boot preview
|
|
26
|
+
- `strategy/autonomous-boot-sequence.md` — full `/autonomous start` steps 0-9 + Construction automation A-E
|
|
27
|
+
- `strategy/agent-choreography.md` — multi-agent operational guide
|
|
28
|
+
|
|
29
|
+
Per cli#331 — closes the "lite skill points at files lite doesn't ship" gap.
|
|
30
|
+
<!-- /FKGL-EXEMPT -->
|
|
27
31
|
|
|
28
32
|
## Usage
|
|
29
33
|
|
|
@@ -263,6 +267,48 @@ silently proceed with defaults.
|
|
|
263
267
|
|
|
264
268
|
---
|
|
265
269
|
|
|
270
|
+
## Lite procedure — self-contained minimum (cli#331)
|
|
271
|
+
|
|
272
|
+
<!-- FKGL-EXEMPT: cli#331 cure — procedure block for lite adopters. Short SVO loses step contract. -->
|
|
273
|
+
Lite adopters run `/autonomous start` with this block only. No `strategy/` file needed.
|
|
274
|
+
|
|
275
|
+
**Step 0 — validate args.** Accept `operator-gated` or `orchestrator-gated` for gating. Accept `sequential` or `parallel` for mode. Reject anything else with a helpful error.
|
|
276
|
+
|
|
277
|
+
**Step 1 — ask the operator two choices.** Gating (default: operator-gated). Mode (default: sequential). Use AskUserQuestion.
|
|
278
|
+
|
|
279
|
+
**Step 2 — check readiness.** Run through this checklist. Scaffold missing items as you go:
|
|
280
|
+
- `substrate.config.md` present → if missing, dispatch `/onboard-repo` first
|
|
281
|
+
- `docs/whereami.md` present → if missing, dispatch `/onboard-repo` first
|
|
282
|
+
- Current iteration goal doc at `docs/iteration-bets/<slug>.md` → if missing, ask operator for the goal; create a minimal doc
|
|
283
|
+
- Session lock free → if active and >30 min old, clear with announcement
|
|
284
|
+
- Chronicle fresh (last 24h) → if stale, note "will write at session-end"
|
|
285
|
+
|
|
286
|
+
**Step 3 — risk register (optional on lite).** `docs/risk-register.md` is optional at lite tier. Create one only when operator asks or when mode is orchestrator-gated. Skip the check otherwise.
|
|
287
|
+
|
|
288
|
+
**Step 4 — budget ceiling (optional on lite).** Ask the operator "how many turns are you OK spending on this session?" Default to "proceed until operator says stop" when operator skips. Record whatever they say in session memory.
|
|
289
|
+
|
|
290
|
+
**Step 5 — confirm scope.** Echo the goal, the two choices, and the ceiling (or "no ceiling"). Ask: "Ready to start?" Wait for yes.
|
|
291
|
+
|
|
292
|
+
**Step 6 — execute the SDLC chain.** Fire the agents in order per gating choice:
|
|
293
|
+
- **operator-gated:** pause between each agent for operator approval. Agents: Shaper → PM → Architect → Designer → Builder → Reviewer → Deployer → Closer. Operator picks which fire.
|
|
294
|
+
- **orchestrator-gated:** chain the agents without pausing. Each writes a handoff doc. Builder commits code. Reviewer runs `/verify`. PRs open for operator merge (or admin-merge within scope).
|
|
295
|
+
|
|
296
|
+
**Step 7 — handle Construction.** For code work:
|
|
297
|
+
- Parse scope into GitHub issues (one issue per discrete change)
|
|
298
|
+
- Write stack manifest at `docs/stacks/<slug>.md` if more than one branch
|
|
299
|
+
- Create branches with issue numbers in name (not placeholder — per bassclef#295)
|
|
300
|
+
- Dispatch Builder per branch; fire `/temperance` + `/diagnose` + `/verify` per branch
|
|
301
|
+
- Open PR per branch; squash merge after Reviewer PASS
|
|
302
|
+
|
|
303
|
+
**Step 8 — close the session.** Dispatch `/session-end` which handles chronicle write, whereami bump, journal entry.
|
|
304
|
+
|
|
305
|
+
Lite adopters at any point can escalate to operator-gated mode mid-session. Say "pause for me to review" and the next agent handoff waits.
|
|
306
|
+
|
|
307
|
+
**Deep procedure for standard+ adopters.** Standard+ and ultra adopters have the strategy/ files above. Those cover Construction automation A-E, pre-build gates, branch stacking, context management, transition hierarchy, and the full choreography rules. Read them for the complete design.
|
|
308
|
+
<!-- /FKGL-EXEMPT -->
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
266
312
|
## Rules
|
|
267
313
|
|
|
268
314
|
- Never start work without operator confirmation
|
|
@@ -255,7 +255,7 @@ FLOOR_PATTERN='src/lib/auth/|src/middleware\.ts|prisma/schema\.prisma|prisma/mig
|
|
|
255
255
|
ACCEPTANCE_CONTENT=$(awk '
|
|
256
256
|
/^```/{in_code = !in_code; next}
|
|
257
257
|
in_code{next}
|
|
258
|
-
/^### WU-/{in_wu=1; next}
|
|
258
|
+
/^### (Step|WU)-/{in_wu=1; next}
|
|
259
259
|
/^## /{in_wu=0}
|
|
260
260
|
in_wu && /^- \[ \]/ {print}
|
|
261
261
|
' "docs/specs/${SPEC_PATH}.md" "docs/decompositions/${DECOMP_PATH}.md" 2>/dev/null)
|
|
@@ -273,8 +273,8 @@ fi
|
|
|
273
273
|
```
|
|
274
274
|
|
|
275
275
|
**Why this is precise (per bassclef#366):** the scan only looks at
|
|
276
|
-
step acceptance criteria (lines starting `- [ ]` under `###
|
|
277
|
-
headings, outside code blocks) plus file-path-shaped references in
|
|
276
|
+
step acceptance criteria (lines starting `- [ ]` under `### Step-N`
|
|
277
|
+
or `### WU-N` headings, outside code blocks) plus file-path-shaped references in
|
|
278
278
|
the goal's frontmatter. Prose paragraphs that DESCRIBE the floor (like
|
|
279
279
|
this section) don't trigger refusal. Code blocks that document the
|
|
280
280
|
floor don't trigger refusal. Only structured ACTIONS the agent would
|
|
@@ -371,7 +371,13 @@ fi
|
|
|
371
371
|
|
|
372
372
|
### Phase 2b — Adopter-mode framing (bassclef#943)
|
|
373
373
|
|
|
374
|
-
Two paths — adopter-mode and operator-mode. Default is adopter
|
|
374
|
+
Two paths — adopter-mode and operator-mode. Default is adopter after a `/launch --local` run. Operator-mode is the default otherwise.
|
|
375
|
+
|
|
376
|
+
Mode detection reads the goal doc's `preview_state:` frontmatter field. /launch writes that field. Open the file it names. When `local_url` is present, /build picks adopter-mode. Default to operator-mode when the field is absent.
|
|
377
|
+
|
|
378
|
+
<!-- FKGL-EXEMPT: ticket reference -->
|
|
379
|
+
Per sunj-labs/bassclef-cli#326.
|
|
380
|
+
<!-- /FKGL-EXEMPT -->
|
|
375
381
|
|
|
376
382
|
#### Adopter-mode pre-dispatch surface
|
|
377
383
|
|
|
@@ -590,7 +596,26 @@ already open. Operator merges inline.
|
|
|
590
596
|
|
|
591
597
|
### Phase 7 — ApprovalGateLink (LIVE — STUBBED)
|
|
592
598
|
|
|
593
|
-
|
|
599
|
+
<!-- FKGL-EXEMPT: cli#332 cure — Phase 7 branches on hosting_platform value. Three code-shape outputs. Technical stub-shape dispatch pattern. -->
|
|
600
|
+
|
|
601
|
+
Phase 7 branches on `hosting_platform` read from `substrate.config.md`:
|
|
602
|
+
|
|
603
|
+
**When `hosting_platform: none`** (lite adopters, operator-only tools, local-first apps) — emit:
|
|
604
|
+
|
|
605
|
+
```
|
|
606
|
+
TODO: live execution — built, not deployed. hosting_platform=none in
|
|
607
|
+
substrate.config.md. The code is reviewed and committed. Running it is
|
|
608
|
+
your choice.
|
|
609
|
+
|
|
610
|
+
To add hosting later:
|
|
611
|
+
- Edit substrate.config.md: set hosting_platform to one of
|
|
612
|
+
github-pages | netlify | cloudflare-pages | vercel | amplify
|
|
613
|
+
- Run /onboard-repo --with-deploy-host to wire the host
|
|
614
|
+
- Then /build Phase 7 will dispatch /deploy-prod via GitHub Environment
|
|
615
|
+
+ required-reviewer rail per manual-prod-approval.md.
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
**When `hosting_platform` is set to a known value** — emit:
|
|
594
619
|
|
|
595
620
|
```
|
|
596
621
|
TODO: live execution — when all steps merged + CI green, would dispatch
|
|
@@ -599,6 +624,17 @@ required-reviewer rail per manual-prod-approval.md. Operator approves
|
|
|
599
624
|
prod deploy via GitHub UI from phone. /build NEVER bypasses this rail.
|
|
600
625
|
```
|
|
601
626
|
|
|
627
|
+
**When `hosting_platform` is unset or unrecognized** — emit:
|
|
628
|
+
|
|
629
|
+
```
|
|
630
|
+
TODO: live execution — hosting_platform not set in substrate.config.md.
|
|
631
|
+
Can't deploy without a target. Set hosting_platform to one of none |
|
|
632
|
+
github-pages | netlify | cloudflare-pages | vercel | amplify, then re-run.
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
Per cli#332 — closes the "lite promises deployed app without a deploy path" honesty gap.
|
|
636
|
+
<!-- /FKGL-EXEMPT -->
|
|
637
|
+
|
|
602
638
|
<!-- FKGL-EXEMPT: Phase 7.5 references paths + skip criteria per architect-review SKILL; technical dispatch stub matches sibling STUB pattern -->
|
|
603
639
|
### Phase 7.5 — /architect-review auto-dispatch (LIVE — STUBBED, per #1437 Step 2 wiring)
|
|
604
640
|
|
|
@@ -17,8 +17,18 @@ requires:
|
|
|
17
17
|
|
|
18
18
|
# Deploy to Production
|
|
19
19
|
|
|
20
|
+
<!-- FKGL-EXEMPT: cli#332 cure — tier contract block names scope + override path. Short SVO loses host-override contract. -->
|
|
20
21
|
Standard deployment procedure. Run after code is reviewed and ready to ship.
|
|
21
22
|
|
|
23
|
+
**Tier contract (per cli#332):**
|
|
24
|
+
|
|
25
|
+
- This skill ships at `tier: lite` as a generic 5-step template: test → build → push → CI → verify.
|
|
26
|
+
- The template body is host-agnostic. Host-specific commands (AWS, Vercel, Netlify, Fly, Railway, GitHub Pages) are not shipped here.
|
|
27
|
+
- When `substrate.config.md` sets `hosting_platform` to a known value, standard-tier adopters add a host-specific wrapper that calls this skill AND runs the host commands. Lite adopters without `hosting_platform` run the template steps + stop.
|
|
28
|
+
- `/build` Phase 7 dispatches this skill only when `hosting_platform` is set to a known value — see /build Phase 7 branching logic per cli#332.
|
|
29
|
+
- `manual-prod-approval.md` applies in all tiers: GitHub Environment `prod` with required reviewer MUST be configured before any prod deploy fires.
|
|
30
|
+
<!-- /FKGL-EXEMPT -->
|
|
31
|
+
|
|
22
32
|
## Procedure
|
|
23
33
|
|
|
24
34
|
### Step 1: Pre-flight
|
|
@@ -62,6 +62,14 @@ Derive nav from the screen map. Apply Peter Morville's IA framework:
|
|
|
62
62
|
- **C**ategory: by type or classification
|
|
63
63
|
- **H**ierarchy: by importance or score
|
|
64
64
|
|
|
65
|
+
## Output file
|
|
66
|
+
|
|
67
|
+
Write to `docs/ia-models/<slug>.md`. Use the active goal or sprint slug. `/launch` Phase 6 reads from this path. `/build` Phase 0.5 reads from the same path.
|
|
68
|
+
|
|
69
|
+
<!-- FKGL-EXEMPT: ticket reference -->
|
|
70
|
+
Per sunj-labs/bassclef-cli#317.
|
|
71
|
+
<!-- /FKGL-EXEMPT -->
|
|
72
|
+
|
|
65
73
|
## Output Format
|
|
66
74
|
|
|
67
75
|
```markdown
|
|
@@ -68,6 +68,14 @@ BACKSTAGE (system does): Score → Index → Enrich → Notify
|
|
|
68
68
|
SUPPORT PROCESSES: Ingest → Classify → Deduplicate
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
## Output file
|
|
72
|
+
|
|
73
|
+
Write to `docs/interaction-designs/<slug>.md`. Use the active goal or sprint slug. `/build` Phase 0.5 reads from this path. `/launch` Phase 7 reads from the same path.
|
|
74
|
+
|
|
75
|
+
<!-- FKGL-EXEMPT: ticket reference -->
|
|
76
|
+
Per sunj-labs/bassclef-cli#317.
|
|
77
|
+
<!-- /FKGL-EXEMPT -->
|
|
78
|
+
|
|
71
79
|
## Output Format
|
|
72
80
|
|
|
73
81
|
For each interaction flow:
|
|
@@ -188,9 +188,17 @@ For each JTBD, produce:
|
|
|
188
188
|
| 1.1 ... | [job] | [screen or component implied] |
|
|
189
189
|
```
|
|
190
190
|
|
|
191
|
+
## Output file
|
|
192
|
+
|
|
193
|
+
Write to `docs/jtbd/<slug>.md`. Use the active goal or sprint slug. `/build` Phase 0.5 reads from this path. See the ticket noted at the end of this skill body.
|
|
194
|
+
|
|
195
|
+
<!-- FKGL-EXEMPT: ticket reference -->
|
|
196
|
+
Per sunj-labs/bassclef-cli#317.
|
|
197
|
+
<!-- /FKGL-EXEMPT -->
|
|
198
|
+
|
|
191
199
|
## Next Step
|
|
192
200
|
|
|
193
|
-
|
|
201
|
+
The output feeds `/task-scenarios` for user stories. Or it feeds `/ia-model` to drive IA.
|
|
194
202
|
|
|
195
203
|
## References
|
|
196
204
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: last-block
|
|
3
|
+
description: Print the exact text of a BLOCK or guardrail banner you saw this session or prior. No args shows the newest. One hook name shows that hook. --list enumerates every stored banner newest first.
|
|
4
|
+
tier: lite
|
|
5
|
+
user_invocable: true
|
|
6
|
+
disable_model_invocation: false
|
|
7
|
+
authoring_luminaries:
|
|
8
|
+
primary: john-ousterhout
|
|
9
|
+
supporting:
|
|
10
|
+
- tony-hoare
|
|
11
|
+
- michael-feathers
|
|
12
|
+
composes_with: []
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# /last-block
|
|
16
|
+
|
|
17
|
+
## What you get
|
|
18
|
+
|
|
19
|
+
An adopter who sees a BLOCK banner can retrieve the exact text later. No scrolling through the terminal. No grep over trace logs. Type `/last-block`. The banner prints.
|
|
20
|
+
|
|
21
|
+
## When to use it
|
|
22
|
+
|
|
23
|
+
Three cases.
|
|
24
|
+
|
|
25
|
+
- You saw a BLOCK banner, scrolled past it, and want to re-read the recipe or override instruction.
|
|
26
|
+
- You want to file a ticket and need the exact BLOCK text as evidence.
|
|
27
|
+
- You want to see which hooks fired BLOCK during the prior session.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
/last-block # print the newest stored banner
|
|
33
|
+
/last-block <hook-name> # print the banner stored under <hook-name>
|
|
34
|
+
/last-block --list # list every stored banner newest first
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## How it works
|
|
38
|
+
|
|
39
|
+
Every BLOCK banner printed by `blocked_banner()` or `guardrail_banner()` persists a marker at `state/markers/last-block/<hook>.marker`. Per-hook markers overwrite on each fire. The lib `lib/last-block.sh` reads them back.
|
|
40
|
+
|
|
41
|
+
Marker format is plaintext:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
hook: <hook-name>
|
|
45
|
+
severity: blocking|advisory|info|guardrail
|
|
46
|
+
fired_at: <ISO-8601 UTC>
|
|
47
|
+
session: <session-id or unknown>
|
|
48
|
+
---
|
|
49
|
+
<verbatim banner text, truncated at 8KB>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Procedure
|
|
53
|
+
|
|
54
|
+
1. Source `lib/last-block.sh`.
|
|
55
|
+
2. If `--list` arg, call `list_last_blocks` and print to stdout.
|
|
56
|
+
3. If a hook-name arg, call `read_last_block <hook>` and print.
|
|
57
|
+
4. Else call `read_last_block` and print the newest.
|
|
58
|
+
5. Exit 0 on hit, 1 on miss.
|
|
59
|
+
|
|
60
|
+
## Example
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
$ /last-block
|
|
64
|
+
hook: pre-commit-gate
|
|
65
|
+
severity: blocking
|
|
66
|
+
fired_at: 2026-10-04T15:21:08Z
|
|
67
|
+
session: 2026-10-04-slot-6
|
|
68
|
+
---
|
|
69
|
+
🛑 BLOCKED: path contains operator identifier /Users/<name>/...
|
|
70
|
+
Override: SKIP_OPERATOR_PATHS=1 git commit ...
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## FAQ
|
|
74
|
+
|
|
75
|
+
### What hooks persist markers?
|
|
76
|
+
|
|
77
|
+
Any hook that calls `blocked_banner()` or `guardrail_banner()` from `session-reflection.sh`. ~27 call sites today. Hooks that fire BLOCK via plain `echo` to stderr are a follow-on retrofit.
|
|
78
|
+
|
|
79
|
+
### Does the marker persist across machines?
|
|
80
|
+
|
|
81
|
+
No. Markers live in `state/markers/last-block/` which bassclef-upstream gitignores. The marker survives the session that wrote it; it does not sync to teammates.
|
|
82
|
+
|
|
83
|
+
### Can I clear markers?
|
|
84
|
+
|
|
85
|
+
Yes — delete `state/markers/last-block/<hook>.marker` or the whole directory. Next BLOCK fire re-populates.
|
|
86
|
+
|
|
87
|
+
### What if the lib is missing?
|
|
88
|
+
|
|
89
|
+
The banner helpers detect missing lib and skip the record call. Banners still print. The marker is just not written. `/last-block` reports "no block recorded".
|
|
90
|
+
|
|
91
|
+
## Refs
|
|
92
|
+
|
|
93
|
+
- Ticket: bassclef-upstream#2036 Finding #10
|
|
94
|
+
- UC: `docs/use-cases/UC-skill-last-block.md`
|
|
95
|
+
- Rule: `.claude/rules/last-block-marker.md`
|
|
96
|
+
- Lib: `lib/last-block.sh`
|
|
97
|
+
- Sister rule: `.claude/rules/blocked-items.md`
|
|
98
|
+
- Luminary: `.claude/luminaries/john-ousterhout.md` (deep module)
|
|
99
|
+
- /rfc outside lenses: `.claude/luminaries/don-norman.md` + `.claude/luminaries/steve-krug.md` + `.claude/luminaries/alan-cooper.md`
|
|
@@ -309,9 +309,35 @@ Per `standards/voice-input-pattern.md` + Phase V Hey-Alexa MVD goal (`docs/itera
|
|
|
309
309
|
- Existing text-mode + brownfield-mode behavior unchanged when flag absent
|
|
310
310
|
- Composes with `--brownfield` (rare; voice-driven brownfield refactor is plausible but not the MVD path)
|
|
311
311
|
|
|
312
|
+
### Phase 0b — hosting_platform ask (per cli#332)
|
|
313
|
+
|
|
314
|
+
<!-- FKGL-EXEMPT: cli#332 cure — hosting_platform ask step. Short SVO loses the config-key contract. -->
|
|
315
|
+
Read `substrate.config.md` for the `hosting_platform` key. If unset or missing, ask the operator once:
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
Where should this run?
|
|
319
|
+
a. local only (default — develop + preview on your machine)
|
|
320
|
+
b. a static host (GitHub Pages / Netlify / Cloudflare Pages / Vercel)
|
|
321
|
+
c. a server host (Amplify / Fly.io / Railway)
|
|
322
|
+
d. I'll deploy myself — just build the plan
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Write the answer to `substrate.config.md` `hosting_platform`:
|
|
326
|
+
- `a` → `hosting_platform: none`
|
|
327
|
+
- `b` → prompt for which static host; write that value (`github-pages` / `netlify` / `cloudflare-pages` / `vercel`)
|
|
328
|
+
- `c` → prompt for which server host; write that value (`amplify` / `fly` / `railway`)
|
|
329
|
+
- `d` → `hosting_platform: operator-managed`
|
|
330
|
+
|
|
331
|
+
If already set, skip the question. The answer flows to /build Phase 7 which branches on this value per cli#332.
|
|
332
|
+
|
|
333
|
+
Per cli#332 — closes "Nothing asks where the app will run" at the earliest surface in the chain.
|
|
334
|
+
<!-- /FKGL-EXEMPT -->
|
|
335
|
+
|
|
312
336
|
### Phase 1 — `/interpret-input`
|
|
313
337
|
|
|
338
|
+
<!-- FKGL-EXEMPT: pre-existing text-mode + brownfield-mode description — technical dispatch contract per bassclef#459 sub-goal 1. -->
|
|
314
339
|
Dispatches `/interpret-input` with the type detected by Phase 0. Text mode preserves the existing text-mode behavior; brownfield mode invokes the Phase C extractor (LR2 WU-1, bassclef#459 sub-goal 1) which walks the repo and populates structural hints (entities, actors, routes, README excerpt).
|
|
340
|
+
<!-- /FKGL-EXEMPT -->
|
|
315
341
|
|
|
316
342
|
```bash
|
|
317
343
|
# Generate sprint slug + InputArtifact path
|
|
@@ -353,7 +379,7 @@ Produces `InputArtifact` at `docs/input-artifacts/<sprint-slug>-input.json`. Dow
|
|
|
353
379
|
### Phase 2 — `/objectory-decompose` (full BCE matrix)
|
|
354
380
|
|
|
355
381
|
Same as `/stage` Phase 2 — Jacobson method via `/objectory-decompose`.
|
|
356
|
-
Output: `docs/decompositions/<slug>-domain.md` with entity inventory
|
|
382
|
+
Output: `docs/decompositions/<sprint-slug>-input-domain.md` with entity inventory
|
|
357
383
|
+ actor list + verb-goal pairs + BCE matrix.
|
|
358
384
|
|
|
359
385
|
**Distinction from `/stage`**: medium + full consume the FULL BCE
|
|
@@ -474,7 +500,7 @@ map derived from BCE entities.
|
|
|
474
500
|
/interaction-design # consumes /ia-model + /use-case
|
|
475
501
|
```
|
|
476
502
|
|
|
477
|
-
Output: state diagrams + sequence diagrams in `docs/interaction-
|
|
503
|
+
Output: state diagrams + sequence diagrams in `docs/interaction-designs/<slug>.md` (per sunj-labs/bassclef-cli#317).
|
|
478
504
|
|
|
479
505
|
### Phase 8 — `/decompose` (GRASP responsibility assignment)
|
|
480
506
|
|
|
@@ -526,12 +552,18 @@ to produce reviews per perspective. Reviews surface in PR body.
|
|
|
526
552
|
/ux-migration <chosen-variant-slug> # if base= provided, use that; else operator chooses post-gallery
|
|
527
553
|
```
|
|
528
554
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
555
|
+
<!-- FKGL-EXEMPT: cli#324 cure — technical precision required naming paired SKILL steps + file paths -->
|
|
556
|
+
|
|
557
|
+
Output: `docs/specs/ux-migration-<slug>.md` carries token extraction, prototype-to-React mapping, and work packages.
|
|
558
|
+
|
|
559
|
+
**When to run full `/ux-migration` vs partial (cli#324):**
|
|
560
|
+
|
|
561
|
+
- **Existing UI (redesign).** Run the full skill. The `/ux-migration` SKILL names this a MUST for redesigns.
|
|
562
|
+
- **Greenfield (no existing UI).** Run only Step 3b and Step 3c. Step 3b extracts design tokens. Step 3c maps prototype HTML to React components. The `/ux-migration` SKILL says skip the full migration for greenfield.
|
|
563
|
+
|
|
564
|
+
Pick by project state. Does `src/app/` carry a shipping UI? Yes means redesign. No means greenfield. When unsure, default to greenfield partial. The full gate's output is a component diff. A component diff has no value on an empty tree.
|
|
532
565
|
|
|
533
|
-
|
|
534
|
-
SKILL.md §"Step 7 — Selection → pipeline to Construction".
|
|
566
|
+
<!-- /FKGL-EXEMPT -->
|
|
535
567
|
|
|
536
568
|
### Phase 12 — Deploy or local-serve (mode-gated)
|
|
537
569
|
|
|
@@ -595,9 +627,9 @@ status != build-ready.
|
|
|
595
627
|
### Phase 14 — Scaffold Construction iteration-goal draft
|
|
596
628
|
|
|
597
629
|
```yaml
|
|
598
|
-
# docs/iteration-bets/<
|
|
630
|
+
# docs/iteration-bets/<sprint-slug>-construction.md (DRAFT) # cli#326
|
|
599
631
|
---
|
|
600
|
-
slug: <
|
|
632
|
+
slug: <sprint-slug>-construction
|
|
601
633
|
phase: Construction
|
|
602
634
|
status: draft # operator must change to "active" before /build-iteration runs
|
|
603
635
|
parent_roadmap: docs/roadmaps/<roadmap-slug>.md # if known
|
|
@@ -611,8 +643,8 @@ references:
|
|
|
611
643
|
- {type: spec, id: <sprint-slug>}
|
|
612
644
|
- {type: decomposition, id: <sprint-slug>-grasp}
|
|
613
645
|
- {type: input-artifact, id: <sprint-slug>-input}
|
|
614
|
-
|
|
615
|
-
mode: scope
|
|
646
|
+
time_budget:
|
|
647
|
+
mode: fixed-scope
|
|
616
648
|
estimated_turns: <derived from /spec step enumeration>
|
|
617
649
|
stopping_criteria:
|
|
618
650
|
- All step PRs filed (count from spec)
|
|
@@ -651,7 +683,7 @@ appetite:
|
|
|
651
683
|
**Viability signal**:
|
|
652
684
|
(derived from /spec acceptance criteria; operator confirms)
|
|
653
685
|
|
|
654
|
-
**
|
|
686
|
+
**Time budget**:
|
|
655
687
|
(derived from spec step enumeration; operator finalizes)
|
|
656
688
|
```
|
|
657
689
|
|
|
@@ -57,12 +57,6 @@ source lib/state.sh
|
|
|
57
57
|
INPUT=$(state_reference_get input-artifact "<slug>")
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
Or via wrapper:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
INPUT=$(bash scripts/state.sh get reference input-artifact "<slug>")
|
|
64
|
-
```
|
|
65
|
-
|
|
66
60
|
**Required fields** (extract via `jq`):
|
|
67
61
|
- `extracted_text` — the load-bearing input for analysis
|
|
68
62
|
- `type` — guides extraction (text vs. URL vs. image have different signals)
|
|
@@ -164,18 +158,12 @@ phase: jacobson # marks Phase B MVP scope; cockburn is follow-up
|
|
|
164
158
|
|
|
165
159
|
### 4. Validate output
|
|
166
160
|
|
|
167
|
-
|
|
168
|
-
against `decomposition.schema.json`.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
Or invoke explicitly:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
bash scripts/state.sh validate docs/decompositions/<slug>-domain.md
|
|
175
|
-
```
|
|
161
|
+
The state-validate.sh hook runs on write. It checks the frontmatter
|
|
162
|
+
against `decomposition.schema.json`. A failed check BLOCKs the write.
|
|
163
|
+
Fix the frontmatter and retry.
|
|
176
164
|
|
|
177
|
-
Exit 0 = clean
|
|
178
|
-
field
|
|
165
|
+
Exit 0 = clean. Exit 3 = schema violation. The BLOCK message names
|
|
166
|
+
the field.
|
|
179
167
|
|
|
180
168
|
### 5. Surface to next step
|
|
181
169
|
|
|
@@ -433,25 +433,25 @@ Idempotent API calls against the target repo via `gh`.
|
|
|
433
433
|
# Read from git remote — don't infer from cwd basename (cwd can be renamed)
|
|
434
434
|
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
|
|
435
435
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
[
|
|
441
|
-
[bug]="E4443A:Defect"
|
|
442
|
-
[enhancement]="A2EEEF:New or improved functionality"
|
|
443
|
-
[security]="FF0000:Security-relevant"
|
|
444
|
-
[infra]="C9D1D9:Infrastructure / workflows / tooling"
|
|
445
|
-
[priority-high]="E4443A:High priority"
|
|
446
|
-
[priority-medium]="F5B94A:Medium priority"
|
|
447
|
-
[question]="D876E3:Needs operator input or design discussion"
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
for NAME in "${!LABELS[@]}"; do
|
|
451
|
-
COLOR="${LABELS[$NAME]%%:*}"
|
|
452
|
-
DESC="${LABELS[$NAME]#*:}"
|
|
436
|
+
# Per cli#306 — use while-read loop over pipe-delimited heredoc instead
|
|
437
|
+
# of `declare -A`. macOS ships bash 3.2 which has no associative arrays.
|
|
438
|
+
# Format per line: NAME|COLOR|DESCRIPTION
|
|
439
|
+
while IFS='|' read -r NAME COLOR DESC; do
|
|
440
|
+
[ -z "$NAME" ] && continue
|
|
453
441
|
gh label create "$NAME" --repo "$REPO" --color "$COLOR" --description "$DESC" --force >/dev/null
|
|
454
|
-
done
|
|
442
|
+
done <<'EOF'
|
|
443
|
+
bassclef-evolution|A6E0F2|Candidate for promotion to bassclef
|
|
444
|
+
agent-user-proposed|D4A5F5|Proposed by agent in an app repo
|
|
445
|
+
bassclef-sync|8FD4A4|Related to bassclef substrate syncing
|
|
446
|
+
review-required|F5B94A|Blocks — human review required
|
|
447
|
+
bug|E4443A|Defect
|
|
448
|
+
enhancement|A2EEEF|New or improved functionality
|
|
449
|
+
security|FF0000|Security-relevant
|
|
450
|
+
infra|C9D1D9|Infrastructure / workflows / tooling
|
|
451
|
+
priority-high|E4443A|High priority
|
|
452
|
+
priority-medium|F5B94A|Medium priority
|
|
453
|
+
question|D876E3|Needs operator input or design discussion
|
|
454
|
+
EOF
|
|
455
455
|
```
|
|
456
456
|
|
|
457
457
|
Uses `--force` so the call is idempotent (updates existing label or
|
|
@@ -87,7 +87,7 @@ When no persona files exist in the repo, auto-populate a minimal persona file fo
|
|
|
87
87
|
|
|
88
88
|
- `CLAUDE.md` — read the "What this repo is" / "Active initiative" sections for goal context
|
|
89
89
|
- `substrate.config.md` — read `agents:` and `deploy_targets:` for role context
|
|
90
|
-
-
|
|
90
|
+
- Default slug: `operator`. Do not derive it from `user.email`. GitHub no-reply addresses carry the account ID and handle. The slug then leaks into committed docs (cli#320). Ask for a display name in-turn if the operator wants one.
|
|
91
91
|
|
|
92
92
|
Emit the operator default to the conversation (not to disk — operator decides whether to persist it):
|
|
93
93
|
|
|
@@ -101,10 +101,11 @@ if a required input is missing:
|
|
|
101
101
|
1. **Personas** — `docs/personas/*.md` (preferred) or
|
|
102
102
|
`docs/design/personas/*.md` (legacy). Use-case's **primary
|
|
103
103
|
actor** MUST be a persona slug, not "user."
|
|
104
|
-
2. **JTBDs** — `docs/
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
2. **JTBDs** — `docs/jtbd/*.md` (preferred, per cli#317) or
|
|
105
|
+
`docs/design/personas/[persona]/jtbds.md` (legacy fallback).
|
|
106
|
+
Each use case has a single **goal** that traces to a JTBD
|
|
107
|
+
outcome. Halt if no JTBDs for the scope in question (warn the
|
|
108
|
+
operator; offer to run `/jtbd-tasks` first).
|
|
108
109
|
3. **Value Prop Canvas** (optional) — `docs/value-prop-canvas/*.md`.
|
|
109
110
|
When present, Pain-Relievers + Gain-Creators ground the "why
|
|
110
111
|
this goal matters" framing in the stakeholders+interests block.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "v1.
|
|
3
|
-
"marker_tag": "release-2026-10-
|
|
4
|
-
"release_date": "2026-10-
|
|
5
|
-
"release_sha": "
|
|
6
|
-
"release_tag": "
|
|
2
|
+
"version": "v1.8.0",
|
|
3
|
+
"marker_tag": "release-2026-10-06-a874c748",
|
|
4
|
+
"release_date": "2026-10-06T20:56:57Z",
|
|
5
|
+
"release_sha": "a874c748",
|
|
6
|
+
"release_tag": "v1.8.0"
|
|
7
7
|
}
|