@thebassclef/lite 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,7 +35,7 @@ See [`standards/os-support.md`](standards/os-support.md) for the full policy.
35
35
 
36
36
  ## Current release
37
37
 
38
- <!-- version-start -->1.6.0<!-- version-end -->
38
+ <!-- version-start -->1.7.0<!-- version-end -->
39
39
 
40
40
  See [CHANGELOG.md](CHANGELOG.md) for release notes.
41
41
 
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const version = "1.6.0";
3
+ const version = "1.7.0";
4
4
  exports.version = version;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version: "1.6.0";
1
+ export declare const version: "1.7.0";
2
2
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "1.6.0";
1
+ const version = "1.7.0";
2
2
  export {
3
3
  version
4
4
  };
@@ -66,6 +66,33 @@ JTBD → HTA → Entity Model → State Diagrams → Sequence Diagrams → /deco
66
66
  - **Don't conflate "propose" with "execute".** When operator says "propose," "options," "path forward" — wait for explicit go signal.
67
67
  - **Don't use bassclef-internal jargon** in operator-facing prose. Plain English at grade-10 reading level.
68
68
  - **Don't push to main without PR review** even on solo workflows.
69
+ - **Don't run `git stash -u` on repos with gitignored substrate.** The `-u` flag moves untracked files to the stash. When your adopter repo gitignores `.claude/hooks/`, `.claude/skills/`, `.claude/rules/`, `.claude/agents/`, or `.claude/luminaries/`, `git stash -u` grabs the substrate files and Stop hooks fail with "No such file or directory" on every tool call. INSTEAD: use plain `git stash` unless you have vetted every untracked file first.
70
+
71
+ ## Substrate git posture
72
+
73
+ Bassclef ships adopter `.gitignore` (per `presence/dist-templates/.gitignore`) with substrate tracked-by-default. Substrate paths under `.claude/hooks/`, `.claude/skills/`, `.claude/rules/`, `.claude/agents/`, `.claude/luminaries/` are NOT gitignored. Adopters commit substrate so `git stash -u` and similar verbs cannot grab it.
74
+
75
+ **Opt-out recipe** — if you prefer substrate gitignored in your adopter repo:
76
+
77
+ 1. Add these lines to your `.gitignore`:
78
+
79
+ ```
80
+ .claude/hooks/
81
+ .claude/skills/
82
+ .claude/rules/
83
+ .claude/agents/
84
+ .claude/luminaries/
85
+ ```
86
+
87
+ 2. Untrack the files git already indexed:
88
+
89
+ ```
90
+ git rm --cached -r .claude/hooks .claude/skills .claude/rules .claude/agents .claude/luminaries
91
+ ```
92
+
93
+ 3. Commit the change.
94
+
95
+ **Caveat.** `bassclef-sync` may re-add substrate files on the next session-start. If that happens, re-run the untrack step. Long-term cure lives with the sync script.
69
96
 
70
97
  ## Luminaries at design boundaries
71
98
 
@@ -86,12 +86,14 @@ MSG="${MSG} explicit operator statement (\"skip recent-artifacts this session\"
86
86
  MSG="${MSG} Override: SKIP_RECENT_ARTIFACTS=1 <command> (logged)."
87
87
 
88
88
  # Emit via inherited blocked_banner (defined in session-reflection.sh)
89
+ # Per standards/session-start-banner-discipline.md — this check is ADVISORY:
90
+ # recent strategic artifacts are context worth reading; session may proceed.
89
91
  if type blocked_banner >/dev/null 2>&1; then
90
- blocked_banner "$MSG"
92
+ blocked_banner "$MSG" advisory
91
93
  else
92
94
  # Defensive fallback if module is invoked outside the coordinator
93
95
  echo ""
94
- echo "🛑🛑🛑 BLOCKED 🛑🛑🛑"
96
+ echo "⚠ ADVISORY"
95
97
  echo "$MSG"
96
98
  echo ""
97
99
  fi
@@ -104,10 +104,12 @@ done < <(jq -r '.critical_hooks[] | [.name, .max_age_seconds, .rationale] | @tsv
104
104
  if [ -n "$STALE_ENTRIES" ]; then
105
105
  NL=$'\n'
106
106
  MSG="hook liveness — stale hook(s) detected:$(echo -e "$STALE_ENTRIES")${NL}${NL}Cadence per standards/hook-cadence.json. Discipline per ADR-048 + .claude/rules/substrate-as-system.md.${NL}${NL}Resolve — run each named hook manually (check .claude/settings.json for its trigger event) OR file a substrate-defect ticket if the hook cannot be fired."
107
+ # Per standards/session-start-banner-discipline.md — stale hook is ADVISORY:
108
+ # session may proceed; operator informed to check hook trigger.
107
109
  if declare -f blocked_banner >/dev/null 2>&1; then
108
- blocked_banner "$MSG"
110
+ blocked_banner "$MSG" advisory
109
111
  else
110
- printf "BLOCKED: %b\n" "$MSG" >&2
112
+ printf "ADVISORY: %b\n" "$MSG" >&2
111
113
  fi
112
114
  fi
113
115
 
@@ -131,7 +131,9 @@ done
131
131
  # Surface findings
132
132
  if [ "$ANY_BLOCKED" = "1" ]; then
133
133
  MSG="workflow-staleness — bassclef workflow(s) failed >${THRESHOLD_HOURS}h ago without recovery:\n$(echo -e "$DETAILS")\nThis is the silent-failure class WU-9d retires. Read the failed run logs (gh run view <id>); root-cause + fix or operator-confirm deferral. Do not silently ignore."
134
- blocked_banner "$MSG"
134
+ # Per standards/session-start-banner-discipline.md — ADVISORY: workflow is
135
+ # failing but the current session can proceed; operator should investigate.
136
+ blocked_banner "$MSG" advisory
135
137
  elif [ "$ANY_WARN" = "1" ]; then
136
138
  echo "### WORKFLOW-STALENESS — WARN (within ${THRESHOLD_HOURS}h grace)"
137
139
  echo ""
@@ -11,6 +11,27 @@
11
11
  # works cleanly both sourced AND standalone. Silent-fail on missing
12
12
  # manifest or missing jq.
13
13
 
14
+ # SELF_MODE guard per bassclef-upstream#1804 — hook manifest staleness only
15
+ # meaningful for adopters watching for hook churn; bassclef-upstream IS
16
+ # the source where new hooks land daily.
17
+ if [ "${SELF_MODE:-0}" = "1" ]; then
18
+ return 0 2>/dev/null || exit 0
19
+ fi
20
+
21
+ # Fresh-install gate (bassclef-upstream#1896): on cold adopter install,
22
+ # every hook file's mtime equals install time (recent). The last_manifest_update
23
+ # field is older by design (records when maintainer bumped it upstream). Result:
24
+ # every hook flags as "new not in manifest" — spurious BLOCKED banner on every
25
+ # lite adopter's first session. Cure: skip when no heartbeat markers exist
26
+ # (mirrors 80-hook-heartbeat-check.sh cold-install gate #1818 Ship 3). The gate
27
+ # activates the moment a producer hook fires and writes its first marker.
28
+ # Anchor: @luminary donald-norman — banner fires only when a real problem
29
+ # exists. @luminary michael-feathers — cold-install mtime is characterization
30
+ # baseline; comparing against it produces false positives.
31
+ if [ ! -d "state/markers/hook-heartbeat" ]; then
32
+ return 0 2>/dev/null || exit 0
33
+ fi
34
+
14
35
  # Probe bundled path first (dist/lite/ ship path per ADR-056 D3), then
15
36
  # $BASSCLEF_DIR fallback for synced adopters. Pattern matches
16
37
  # session-reflection.sh:11-17. Cures #1732 Phase A silent-fail at operator
@@ -111,21 +111,24 @@ while IFS= read -r __shv_file; do
111
111
  done <<< "$__shv_settings_files"
112
112
 
113
113
  if [ -n "$__shv_missing" ]; then
114
- blocked_banner "settings-hook-verify" \
115
- "Hooks wired in settings.json but missing on disk:" \
116
- "$__shv_missing" \
117
- "" \
118
- "Cure paths:" \
119
- " 1. Re-run bassclef-sync.sh to restore vendored/symlinked hooks" \
120
- " 2. Edit the settings file and remove the stale entry" \
121
- " 3. Override this session: SKIP_SETTINGS_HOOK_VERIFY=1" \
122
- "" \
123
- "Per bassclef-upstream#888."
114
+ # Compose one $msg per blocked_banner (msg, severity?) signature.
115
+ # Prior code passed 10 args; args 3-9 silently dropped because banner
116
+ # takes only msg + optional severity. Per bassclef-upstream#1897.
117
+ __shv_msg="Hooks wired in settings.json but missing on disk:
118
+ $__shv_missing
119
+
120
+ Cure paths:
121
+ 1. Re-run bassclef-sync.sh to restore vendored/symlinked hooks
122
+ 2. Edit the settings file and remove the stale entry
123
+ 3. Override this session: SKIP_SETTINGS_HOOK_VERIFY=1
124
+
125
+ Per bassclef-upstream#888."
126
+ blocked_banner "$__shv_msg"
124
127
  trace_log "fired" "settings-hook-verify" "missing hooks detected" 2>/dev/null || true
125
128
  else
126
129
  trace_log "pass" "settings-hook-verify" "all wired hooks resolve" 2>/dev/null || true
127
130
  fi
128
131
 
129
132
  unset __shv_settings_files __shv_project_settings __shv_user_settings \
130
- __shv_missing __shv_file
133
+ __shv_missing __shv_file __shv_msg
131
134
  unset -f __shv_check_file __shv_scan_settings
@@ -85,20 +85,29 @@ blocked_banner() {
85
85
  local msg="$1"
86
86
  local severity="${2:-blocking}"
87
87
  echo ""
88
- if [ "$severity" = "advisory" ]; then
89
- echo "NOTE"
90
- echo "────────────────────────────────────────────"
91
- echo "$msg"
92
- echo "────────────────────────────────────────────"
93
- echo "Worth doing. Not blocking this session."
94
- else
95
- echo "🛑🛑🛑 BLOCKED 🛑🛑🛑"
96
- echo "────────────────────────────────────────────"
97
- echo "$msg"
98
- echo "────────────────────────────────────────────"
99
- echo "ACTION: resolve OR explicitly defer (per .claude/rules/blocked-items.md)."
100
- echo "Silence is not deferral. Propose this as item #1 in your session plan."
101
- fi
88
+ case "$severity" in
89
+ info)
90
+ echo "ℹ INFO"
91
+ echo "────────────────────────────────────────────"
92
+ echo "$msg"
93
+ echo "────────────────────────────────────────────"
94
+ ;;
95
+ advisory)
96
+ echo "⚠ ADVISORY"
97
+ echo "────────────────────────────────────────────"
98
+ echo "$msg"
99
+ echo "────────────────────────────────────────────"
100
+ echo "Worth reading. Not blocking this session."
101
+ ;;
102
+ blocking|*)
103
+ echo "🛑🛑🛑 BLOCKED 🛑🛑🛑"
104
+ echo "────────────────────────────────────────────"
105
+ echo "$msg"
106
+ echo "────────────────────────────────────────────"
107
+ echo "ACTION: resolve OR explicitly defer (per .claude/rules/blocked-items.md)."
108
+ echo "Silence is not deferral. Propose this as item #1 in your session plan."
109
+ ;;
110
+ esac
102
111
  echo ""
103
112
  }
104
113
 
@@ -13,21 +13,33 @@ This rule is the methodology layer. The mechanism is the /longrun SKILL body Ste
13
13
 
14
14
  Every `/longrun prep` dispatch. The SKILL body Step 0.85 checks for a plan doc first. When one is found, the compressed prep path fires (converged preset). When none matches, prep falls to exploratory or reversible-small per the picker.
15
15
 
16
- Detection criteria for the converged preset (all three must match):
16
+ Detection fires from three signal sources. The picker checks in precedence order:
17
+
18
+ **Signal 1 — plan doc present + fresh** (all three must match):
17
19
 
18
20
  1. File matching `docs/next-session-plan-*.md` exists at repo root
19
21
  2. File was modified within the last 48 hours (`find -mtime -2`)
20
22
  3. File body contains one of: `## Recommended session sequence`, `## Recommended sequence`, `## Next-session pickup`
21
23
 
24
+ **Signal 2 — fresh /state-a-problem marker** (`state/markers/state-a-problem/` `-mtime -2`).
25
+
26
+ **Signal 3 — whereami PRIMARY queue** (per Q1 /longrun 2026-09-22 Step 1):
27
+
28
+ 1. `docs/whereami.md` carries a `next_in_flight_goal:` line
29
+ 2. That line (or its continuation within 10 lines) names PRIMARY candidates in priority order (numbered `(1)`, `(2)` OR the phrase `priority order`)
30
+ 3. No unresolved `GATE` line sits above the PRIMARY list (a `GATE — wait for X` inside the same block blocks converged)
31
+
32
+ Precedence — plan doc wins over problem marker; problem marker wins over whereami PRIMARY. The mechanical helper at `scripts/longrun-preset-detect.sh` encodes this precedence. Test coverage at `scripts/tests/longrun-preset-detect.test.sh` (15 Tier 0 tests).
33
+
22
34
  ## The three presets (per bassclef-upstream#1598)
23
35
 
24
36
  Per `.claude/skills/longrun/SKILL.md` Step 0.85 picker. Prep renders in the shape that fits the mode:
25
37
 
26
38
  | Preset | Fires when | Shape |
27
39
  |---|---|---|
28
- | **converged** | Plan doc matches criteria above OR fresh `/state-a-problem` marker present | Lean canvas — Problem + Value + Solution + options table |
29
- | **exploratory** | No plan doc + operator typed `/longrun` alone + no fresh problem marker | Scan-table dominant — options table + one line per row + recommend row marker |
30
- | **reversible-small** | Small scope stated in the invocation + won't break other work | Three-chunk compact — one line per option, one recommend line, one action line |
40
+ | **converged** | Any of the three signals above fires (plan doc OR problem marker OR whereami PRIMARY) | Lean canvas — Problem + Value + Solution + options table |
41
+ | **exploratory** | No signal fires; operator typed `/longrun` alone | Scan-table dominant — options table + one line per row + recommend row marker |
42
+ | **reversible-small** | Small scope stated in the invocation + will not break other work | Three-chunk compact — one line per option, one recommend line, one action line |
31
43
 
32
44
  Ambiguous cases: picker asks `Converged / Exploratory / Small? (c/e/s/skip)`.
33
45
 
@@ -72,6 +84,13 @@ INSTEAD of overriding routinely: update the plan doc. A stale plan doc is a bad
72
84
  - `.claude/rules/plan-enumeration-needs-value-props.md` — every option in the compressed scan-table still carries a value-prop cell
73
85
  - `.claude/rules/blocked-items.md` — silence is not deferral (plan doc detection reports fire vs skip explicitly)
74
86
  - `.claude/rules/bootstrap-pair-discipline.md` — this rule + SKILL amendment ship as paired bootstrap
75
- - @luminary john-ousterhoutdeep module (compression path hides plan-doc detection behind narrow interface)
76
- - @luminary donald-normansignifier + feedback (plan doc presence is a signifier; compressed vs full ceremony is user feedback)
87
+ - `scripts/longrun-preset-detect.sh`mechanical detection helper (added Q1 /longrun 2026-09-22 Step 1)
88
+ - `scripts/tests/longrun-preset-detect.test.sh`Tier 0 test coverage (15 tests) pinning helper behavior
89
+ - `docs/use-cases/UC-rule-longrun-prep-whereami-signal.md` — brief use case for whereami PRIMARY signal
90
+ - @luminary john-ousterhout — deep module (compression path hides detection behind narrow helper interface)
91
+ - @luminary david-parnas — information hiding (rule cites helper; SKILL sources helper; logic in one place)
92
+ - @luminary tony-hoare — pre/postcondition contract (helper input: 3 optional dirs; output: exactly one preset + trigger source)
93
+ - @luminary donald-norman — signifier + feedback (helper prints trigger source to stderr so operator sees which signal fired)
94
+ - @luminary michael-nygard — stability (explicit precedence: plan doc > problem marker > whereami PRIMARY)
95
+ - @luminary michael-feathers — characterization test (fixtures pin REAL whereami shape variants)
77
96
  - @luminary frederick-brooks — conceptual integrity (compression preserves the option-table + card + step-card shape; only volume shrinks)
@@ -207,22 +207,39 @@ The helper stays advisory through 2026-10-31 per ADR-031. Old hooks and libs lan
207
207
 
208
208
  | Preset | Fires when | Rendered shape |
209
209
  |---|---|---|
210
- | **converged** | Plan doc newer than 48h + carries `## Recommended` section, OR fresh `/state-a-problem` marker present | Lean canvas — Problem + Value + Solution + options table + card on ask |
211
- | **exploratory** | No plan doc + operator typed `/longrun` alone + no fresh problem marker | Scan-table dominant — options table + one line per row + recommend row marker |
212
- | **reversible-small** | Small scope stated in the invocation + won't break other work | Three-chunk compact — one line per option, one recommend line, one action line |
210
+ | **converged** | Any of: plan doc newer than 48h + carries `## Recommended`; OR fresh `/state-a-problem` marker; OR whereami `next_in_flight_goal:` carries PRIMARY queue with no unresolved GATE above | Lean canvas — Problem + Value + Solution + options table + card on ask |
211
+ | **exploratory** | No plan doc + operator typed `/longrun` alone + no fresh problem marker + no whereami PRIMARY | Scan-table dominant — options table + one line per row + recommend row marker |
212
+ | **reversible-small** | Small scope stated in the invocation + will not break other work | Three-chunk compact — one line per option, one recommend line, one action line |
213
213
 
214
214
  Ambiguous cases: picker asks the operator directly — `Converged / Exploratory / Small? (c/e/s/skip)`.
215
215
 
216
- Detection commands:
216
+ Detection helper (per bassclef-upstream#1598 + Q1 /longrun 2026-09-22 Step 1). One call returns one preset. Trigger source goes to stderr.
217
217
 
218
218
  ```bash
219
- # Converged signal — plan doc present + fresh
219
+ bash scripts/longrun-preset-detect.sh \
220
+ --whereami docs/whereami.md \
221
+ --plan-doc-dir docs \
222
+ --problem-marker-dir state/markers/state-a-problem
223
+ ```
224
+
225
+ Helper stdout is one of: `converged`, `exploratory`, `reversible-small`, `ambiguous`. Helper stderr names the trigger: `trigger=plan-doc`, `trigger=problem-marker`, `trigger=whereami-PRIMARY`, or `trigger=none`.
226
+
227
+ Raw detection commands (still valid; the helper wraps these):
228
+
229
+ ```bash
230
+ # Signal 1 — plan doc present + fresh
220
231
  find docs -maxdepth 1 -name 'next-session-plan-*.md' -mtime -2 -type f 2>/dev/null | head -1
221
232
 
222
- # Fresh problem statement
233
+ # Signal 2 — fresh problem statement
223
234
  find state/markers/state-a-problem -type f -mtime -2 2>/dev/null | head -1
235
+
236
+ # Signal 3 — whereami PRIMARY queue (added 2026-09-22)
237
+ awk '/^next_in_flight_goal:/{flag=1; n=0} flag {print; n++; if (n>=10) flag=0}' docs/whereami.md \
238
+ | grep -iE 'primary' | grep -iE '\(1\)|priority order'
224
239
  ```
225
240
 
241
+ Precedence rule: plan doc wins over problem marker. Problem marker wins over whereami PRIMARY. The helper enforces this order.
242
+
226
243
  The picker writes the preset marker at `state/markers/longrun-preset/<branch>.marker`. Downstream Stop hook reads the marker + applies the per-preset axis set from `.claude/rules/compounding-sequence-fresh-analysis.md` § Per-preset axis sets.
227
244
 
228
245
  Converged preset triggers Step 0.75 shipped-state check first. When any recommended path lands SHIPPED, prep reshapes to exploratory automatically.
@@ -1,7 +1,7 @@
1
1
  {
2
- "version": "v1.1.0",
3
- "marker_tag": "release-2026-09-21-0e54fa7c",
4
- "release_date": "2026-09-21T22:20:31Z",
5
- "release_sha": "0e54fa7c",
6
- "release_tag": "release-2026-09-21-0e54fa7c"
2
+ "version": "v1.2.0",
3
+ "marker_tag": "release-2026-09-22-a26d8936",
4
+ "release_date": "2026-09-22T11:04:29Z",
5
+ "release_sha": "a26d8936",
6
+ "release_tag": "release-2026-09-22-a26d8936"
7
7
  }
@@ -1,12 +1,20 @@
1
1
  # Bassclef adopter .gitignore template
2
2
  # Ships via bassclef init from presence/dist-templates/.gitignore per goal 12e Step 3.
3
3
  #
4
+ # Substrate tracked-by-default policy (per bassclef-upstream#1691 Cure 3 Path A):
5
+ # Substrate files under .claude/hooks/, .claude/skills/, .claude/rules/,
6
+ # .claude/agents/, .claude/luminaries/ are NOT ignored here. Adopters
7
+ # commit them so `git stash -u` does not grab them and Stop hooks do
8
+ # not fail. See .claude/bassclef-orientation.md for the opt-out recipe
9
+ # if you prefer substrate gitignored.
10
+ #
4
11
  # Reasoning:
5
12
  # - state/markers/* — session-local telemetry (per feedback-marker-paths-real-files-not-symlinks memory)
6
13
  # - state/session-locks/ + state/session-timing/ — session-scoped ephemeral state
7
14
  # - state/tier-accounting/ + state/luminary-implementations/ — walker output; regenerated on demand
8
15
  # - dist/ — build output (per goal 12e Step 2 build-adopter-tree.sh)
9
16
  # - .claude/hooks/logs/ — hook trace logs (operator-only)
17
+ # - .claude/hooks/*.trace — hook trace output (operator-only)
10
18
  # - node_modules/ — universal
11
19
  # - .DS_Store — macOS metadata
12
20
  #
@@ -34,6 +34,47 @@ Every entry stays in this file for the life of the manifest. Never pruned. When
34
34
 
35
35
  ## Entries (newest first)
36
36
 
37
+ ### Q1 /longrun Slice D — session-start banner-tone discipline (v1.9.10 → v1.9.11, 2026-09-22)
38
+
39
+ - **Change type:** content-add (1 new standard) + content-change (session-reflection.sh + 3 fragments)
40
+ - **Fields:** 431 entries (up from 430). New standard `session-start-banner-discipline`. Content hashes shift on `session-reflection.sh` + 3 exemplar fragments.
41
+ - **Version bump:** v1.9.10 → v1.9.11 (patch; entry added + content-hash changes; no schema shape shift).
42
+ - **Rationale:** bassclef-upstream#1704 Norman + Cooper consult. `blocked_banner` extended to 3-severity palette (info / advisory / blocking). 3 exemplar fragments migrated to advisory tone so Sam's first-run reads context not "broken install."
43
+ - **Downstream cure:** none owed. Existing 27 `blocked_banner` callers keep default `blocking` behavior; adopters see no change unless they update fragments.
44
+
45
+ ### Q1 /longrun Slice C — adopter git safety docs + tracked-by-default policy (v1.9.9 → v1.9.10, 2026-09-22)
46
+
47
+ - **Change type:** content-change (1 content hash; no entries added or removed)
48
+ - **Fields:** none changed. 430 entries before and after. One `content_hash` value moves — `.claude/bassclef-orientation.md`.
49
+ - **Version bump:** v1.9.9 → v1.9.10 (patch; content-hash change only; no schema shape shift).
50
+ - **Rationale:** bassclef-upstream#1691 Cure 2 + Cure 3 Path A. Orientation.md gains a "Substrate git posture" section explaining tracked-by-default plus a `git stash -u` footgun bullet and adopter opt-out recipe. The `presence/dist-templates/.gitignore` already permits substrate tracking; Slice C confirms with an inline comment naming the policy. No file removal or rewrite. Adopters see zero behavior change unless they read the new section.
51
+ - **Downstream cure:** none owed for adopters. Content-only change; adopters get the docs update via next `bassclef-sync`. Adopter opt-out recipe is documented for the small subset who prefer substrate gitignored.
52
+
53
+ ### Q1 /longrun Slice A — 81-hook-manifest-staleness fresh-install gate (v1.9.8 → v1.9.9, 2026-09-22)
54
+
55
+ - **Change type:** content-change (1 content hash; no entries added or removed)
56
+ - **Fields:** none changed. 430 entries before and after. One `content_hash` value moves — `hook/81-hook-manifest-staleness`.
57
+ - **Version bump:** v1.9.8 → v1.9.9 (patch; content-hash change only; no schema shape shift).
58
+ - **Rationale:** bassclef-upstream#1896 cure. Cold adopter install produces mtime = install time on every hook. `81-hook-manifest-staleness.sh` compared each hook's mtime to `last_manifest_update` field, flagging every hook as "new not in manifest" on cold install. Added fresh-install gate mirroring `80-hook-heartbeat-check.sh` L39-41 pattern per #1818 Ship 3. Sister SELF_MODE guard also added per #1804 pattern.
59
+ - **Downstream cure:** none owed for adopters. Content-only change; adopters get the fixed hook via next `bassclef-sync`.
60
+
61
+ ### Q1 /longrun Slice B — settings-hook-verify blocked_banner caller cure (v1.9.7 → v1.9.8, 2026-09-22)
62
+
63
+ - **Change type:** content-change (1 content hash; no entries added or removed)
64
+ - **Fields:** none changed. 430 entries before and after. One `content_hash` value moves — `hook/95-settings-hook-verify`.
65
+ - **Version bump:** v1.9.7 → v1.9.8 (patch; content-hash change only; no schema shape shift).
66
+ - **Rationale:** bassclef-upstream#1897 caller-side cure. `.claude/hooks/session-reflection.d/95-settings-hook-verify.sh` L114-125 rewritten so the 10-arg blocked_banner call serializes into one `$msg` body per the (msg, severity?) signature at `.claude/hooks/session-reflection.sh` L84. Missing-hooks list now surfaces at session-start banner instead of dropping silently. Deep tier-template cure defers to #1901 follow-on.
67
+ - **Downstream cure:** none owed for adopters. Content-only change; adopters get the fixed hook via next `bassclef-sync`.
68
+
69
+ ### Q1 /longrun Step 1 — /longrun Step 0.85 whereami PRIMARY signal (v1.9.6 → v1.9.7, 2026-09-22)
70
+
71
+ - **Change type:** content-change (2 content hashes; no entries added or removed)
72
+ - **Fields:** none changed. 430 entries before and after. Two `content_hash` values move — `rule/longrun-prep-plan-doc-compression` and `skill/longrun`.
73
+ - **Version bump:** v1.9.6 → v1.9.7 (patch; content-hash change only; no schema shape shift, no entry count change).
74
+ - **Rationale:** bassclef-upstream#1598 extension. `/longrun` Step 0.85 preset picker gains a third converged signal — whereami `next_in_flight_goal:` PRIMARY queue with no unresolved GATE. Rule and SKILL body now cite the new mechanical helper at `scripts/longrun-preset-detect.sh`. Rule adds 4 anchor luminaries. SKILL Step 0.85 detection block adds helper invocation + raw command for signal 3 + precedence note.
75
+ - **Downstream cure:** none. Patch bump; adopters on sync pick it up at the next `bassclef-sync`. The new helper lives at `scripts/longrun-preset-detect.sh` (tier upstream) — adopters do not receive it, only the rule + SKILL prose that cites it.
76
+ - **Old shape retired:** none.
77
+
37
78
  ### Ship 1 — install-class boundary + retag rollout (v1.8.7 → v1.9.0, 2026-09-20)
38
79
 
39
80
  - **Change type:** entry-removal (3 entries drop) + entry-add (1 template ships) + policy-change (Gate B install-class filter + Gate C wiring/file symmetry check added to generator)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tier": "lite",
3
- "manifest_version": "1.9.6",
4
- "generated_at": "2026-09-21T21:28:13Z",
3
+ "manifest_version": "1.9.11",
4
+ "generated_at": "2026-09-22T06:14:43Z",
5
5
  "entries": [
6
6
  {
7
7
  "slug": "029-release-pipeline",
@@ -216,7 +216,7 @@
216
216
  "type": "hook",
217
217
  "path": ".claude/hooks/session-reflection.d/70-recent-strategic-artifacts.sh",
218
218
  "tier": "lite",
219
- "content_hash": "sha256:c3d8febfd3e9363df6da880a91493879893d0d3eeeabdba9a07d8fcfb7745645",
219
+ "content_hash": "sha256:3b5d8edc239d19f3b8d42dde3302a7bbd122d8ddfd5378643bec6414e4a8a3c2",
220
220
  "description": "Recent Strategic Artifacts — session-start branch of artifact-ingestion gate."
221
221
  },
222
222
  {
@@ -232,7 +232,7 @@
232
232
  "type": "hook",
233
233
  "path": ".claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh",
234
234
  "tier": "lite",
235
- "content_hash": "sha256:9f20ebd080a1a7364fe6e6c16266547b56b95c820297310cdd5be559852bab5f",
235
+ "content_hash": "sha256:fa72927b90d4f6f57733249f41f2353f930b84c18003c53f7a15c98eb8045e45",
236
236
  "description": "Hook heartbeat check — reads standards/hook-cadence.json, calls"
237
237
  },
238
238
  {
@@ -240,7 +240,7 @@
240
240
  "type": "hook",
241
241
  "path": ".claude/hooks/session-reflection.d/80-workflow-staleness.sh",
242
242
  "tier": "lite",
243
- "content_hash": "sha256:5bb185044991df0d2e658cb12f10f3306add8682a270f0005b73f30617d3cb6c",
243
+ "content_hash": "sha256:c8eb12402268851aa7a6fee69ac3a2e370c64ea67dcf78795067fb321cacc2a3",
244
244
  "description": "Workflow-staleness — surfaces silent bassclef workflow failures at"
245
245
  },
246
246
  {
@@ -248,7 +248,7 @@
248
248
  "type": "hook",
249
249
  "path": ".claude/hooks/session-reflection.d/81-hook-manifest-staleness.sh",
250
250
  "tier": "lite",
251
- "content_hash": "sha256:e3baa84fdb41585c51779773a2f63837eaab9f7896f9f5492a2db54d7269b75d",
251
+ "content_hash": "sha256:f4db0541d27a06e3f94ba557e7c8a39e747601b8ca9fd7af7313891b69548afd",
252
252
  "description": "Hook manifest staleness — flags standards/hook-cadence.json when it"
253
253
  },
254
254
  {
@@ -280,7 +280,7 @@
280
280
  "type": "hook",
281
281
  "path": ".claude/hooks/session-reflection.d/95-settings-hook-verify.sh",
282
282
  "tier": "lite",
283
- "content_hash": "sha256:b3cccaf7acf82d2832b60d214e08b22384b4f4dbd9cd9f4e68b07ca85706eb6a",
283
+ "content_hash": "sha256:5f2a66f82c947105029074da84428fa7c6d591c88200fd9b7e957f37138d09a6",
284
284
  "description": "Settings hook path verifier — fires at every SessionStart via"
285
285
  },
286
286
  {
@@ -592,7 +592,7 @@
592
592
  "type": "hook",
593
593
  "path": ".claude/hooks/session-reflection.sh",
594
594
  "tier": "lite",
595
- "content_hash": "sha256:ece32cd8261bafe4597563aa18237b504bba335c0a1e8d94e1d8d69f4a8e97ae",
595
+ "content_hash": "sha256:5d06b68d7503922cd3f5143ed2d83ec4e12c5d8e6f16822efcf2c702f49ed5b9",
596
596
  "description": "Session Start hook coordinator. Injects reflection prompt and iterates"
597
597
  },
598
598
  {
@@ -1326,7 +1326,7 @@
1326
1326
  "type": "root-doc",
1327
1327
  "path": ".claude/bassclef-orientation.md",
1328
1328
  "tier": "lite",
1329
- "content_hash": "sha256:7bc4b60259676a5f8f2a8f3f18734607c47ce5c0fb18bdb4c3b6b354904a3836"
1329
+ "content_hash": "sha256:657e68fe29c52aaf9dd54ff752cf6f69498543484e4a764db89ba9837c0d9436"
1330
1330
  },
1331
1331
  {
1332
1332
  "slug": "claude-lite",
@@ -1629,7 +1629,7 @@
1629
1629
  "type": "rule",
1630
1630
  "path": ".claude/rules/longrun-prep-plan-doc-compression.md",
1631
1631
  "tier": "lite",
1632
- "content_hash": "sha256:35c8b9b14383864291f03dc78414d85162814ad2d43daa1fabfb268ecca197a0",
1632
+ "content_hash": "sha256:c2c661c14988b3b0469c357fdda5600d9a4e9f237087c5b348c263d9a0e6c862",
1633
1633
  "description": "When a plan doc at docs/next-session-plan-*.md (modified within 48 hours) carries a ## Recommended session sequence (or equivalent) section, /longrun prep MUST skip the full Steps…"
1634
1634
  },
1635
1635
  {
@@ -2572,7 +2572,7 @@
2572
2572
  "type": "skill",
2573
2573
  "path": ".claude/skills/longrun/SKILL.md",
2574
2574
  "tier": "lite",
2575
- "content_hash": "sha256:e11e395721186c5e5021266723b942ac8f330f17bff4b495adf316d05674ac01",
2575
+ "content_hash": "sha256:1ab5a98d5ea805249761e092c7c8c8523eb3cd7ce53e6d89790d01e767a3df4b",
2576
2576
  "description": "Run a long autonomous session that paces itself. Prepares scope. Checkpoints at phase boundaries. Closes with session log and retrospective. Three modes: prep, checkpoint, closeout.",
2577
2577
  "composes_with": [
2578
2578
  "value-prop",
@@ -3737,7 +3737,7 @@
3737
3737
  "type": "standard",
3738
3738
  "path": "standards/lite-manifest-schema-changes.md",
3739
3739
  "tier": "lite",
3740
- "content_hash": "sha256:ba7d81b68af60e4df0e46fd7e0bb52ff756eaa13baf42b0dc679db37521b70a5",
3740
+ "content_hash": "sha256:17f5c69efd97240348b6f74d35b200400c2817f7e303eb288b027fbb2bb38991",
3741
3741
  "description": "Chronological ledger of every lite-manifest schema change. Adopters read this before sync to know what shifted."
3742
3742
  },
3743
3743
  {
@@ -3972,6 +3972,14 @@
3972
3972
  "content_hash": "sha256:eb3ef832175ed745c412ca42f9ad854d0a298b828e647706547dcded15e2e32a",
3973
3973
  "description": "The session-board is a session-level coordinator artifact for multi-bet longrun sessions."
3974
3974
  },
3975
+ {
3976
+ "slug": "session-start-banner-discipline",
3977
+ "type": "standard",
3978
+ "path": "standards/session-start-banner-discipline.md",
3979
+ "tier": "lite",
3980
+ "content_hash": "sha256:444a6f20be6bd175dabb06b8aedb527b9c93525786df0386fd785d1821451a4e",
3981
+ "description": "Four-level banner palette for session-start checks. Per Norman signifier + Cooper Sam persona consult. Match glyph to state."
3982
+ },
3975
3983
  {
3976
3984
  "slug": "sibling-validation-checklist",
3977
3985
  "type": "standard",
@@ -0,0 +1,99 @@
1
+ ---
2
+ tier: lite
3
+ description: Four-level banner palette for session-start checks. Per Norman signifier + Cooper Sam persona consult. Match glyph to state.
4
+ ---
5
+
6
+ # Session-start banner discipline
7
+
8
+ Session-start checks in `.claude/hooks/session-reflection.d/` emit banners that adopters read before any tool call runs. The banner shape trains the reader's expectation. A 🛑 emoji for an advisory check reads to a first-run adopter as "you broke something." That is a signifier mismatch (Norman) and a Cooper Sam-persona failure at the magic-demo boundary.
9
+
10
+ This standard names a four-level palette. Each check picks the level that matches its own state.
11
+
12
+ ## The four levels
13
+
14
+ | Level | Glyph | Text label | When to use |
15
+ |---|---|---|---|
16
+ | BLOCK | 🛑 | BLOCKED | The session cannot safely proceed with substantive work. Real defect. Missing prerequisite. Active drift that will corrupt state. |
17
+ | ADVISORY | ⚠ | ADVISORY | Context worth reading. Session may proceed. The operator is informed; they choose whether to act now or later. |
18
+ | INFO | ℹ | INFO | State report. No action needed. Fires only when the reader benefits from knowing the state. |
19
+ | silent-on-clean | — | — | Check runs but reports nothing when state is nominal. Fires only on non-nominal state (which routes to one of the three above). |
20
+
21
+ Every check picks exactly one level. Ambiguous cases default to silent-on-clean.
22
+
23
+ ## How to pick
24
+
25
+ Ask two questions in order.
26
+
27
+ 1. **Does this check indicate the session cannot safely proceed?** If yes, BLOCK. Cannot-proceed means: writing code now will corrupt state, or will ship a broken change, or will silently defeat a safety mechanism. Missing bassclef-sync template drift. Failing pre-commit gate. Schema validation error. These block.
28
+ 2. **Does the reader gain value from knowing about this now?** If yes, ADVISORY or INFO. ADVISORY when the reader may want to act (read the artifact, address the drift). INFO when it is pure state (last save time, current branch). If no, silent-on-clean.
29
+
30
+ Default to silent-on-clean when in doubt. Every advisory or info banner spends the reader's attention. Spend it on things they benefit from.
31
+
32
+ ## Signifier discipline (Norman)
33
+
34
+ The glyph is a signifier — a perceivable cue that suggests state. The signifier fit is:
35
+
36
+ - 🛑 signals "stop; something is wrong." Use only when something is wrong.
37
+ - ⚠ signals "look here; think." Use for context worth reading that does not block.
38
+ - ℹ signals "state report." Use when the state itself is the payload.
39
+
40
+ Pairing glyph with text label (BLOCKED / ADVISORY / INFO) protects screen readers, CI log parsers, and readers who read faster than they see. The text is the primary signifier; the glyph is data-ink that reinforces the level.
41
+
42
+ ## Sam persona discipline (Cooper)
43
+
44
+ Sam is a cold-adopter running bassclef for the first time. Sam's mental model: nothing about bassclef yet. Sam sees 🛑 and thinks "I broke the install." That is a persona failure.
45
+
46
+ Slice D applies the four-level palette so Sam's first-run reads context, not brokenness. Cure applies at every session-reflection.d fragment where the check is advisory. Fragments that indicate a real block keep 🛑.
47
+
48
+ **First-run adopter special case.** On the very first session (no prior state on disk), even advisory checks should default to silent-on-clean. A first-run adopter has no context to act on. Fire an ADVISORY only when the state is genuinely worth surfacing. The mechanism: check `LAST_SAVE_FILE` existence or session-timing marker count; skip advisory output on first-run unless the check is critical.
49
+
50
+ ## Data-ink ratio (Tufte)
51
+
52
+ Each glyph maps 1:1 to a severity level. The glyph carries information the reader uses to prioritize. That is data-ink, not decoration. Emoji as decoration (a 🎉 at the head of a section) is chartjunk. Emoji as severity mark (🛑 for BLOCK, ⚠ for ADVISORY) is data-ink.
53
+
54
+ ## Aggregate roll-up (session-end)
55
+
56
+ When session-start emits multiple banners, the reader benefits from a one-line summary at the end.
57
+
58
+ Format: `Session-start: N advisory, M info, K blocked.`
59
+
60
+ The roll-up prints only when count > 0 on any level. Fires from the last session-reflection.d fragment (name-sorted last). This slice ships the standard; the roll-up mechanism ships as follow-on.
61
+
62
+ ## API — blocked_banner (session-reflection.sh)
63
+
64
+ The existing `blocked_banner` function in `.claude/hooks/session-reflection.sh` accepts a second argument for severity:
65
+
66
+ ```
67
+ blocked_banner "message body" blocking # 🛑 BLOCKED (default)
68
+ blocked_banner "message body" advisory # ⚠ ADVISORY
69
+ blocked_banner "message body" info # ℹ INFO
70
+ ```
71
+
72
+ Callers that pass one argument keep the historical shape (blocking). The 27 pre-existing sites are untouched.
73
+
74
+ Silent-on-clean checks skip the `blocked_banner` call entirely on nominal state.
75
+
76
+ ## Migration path
77
+
78
+ This slice migrates three advisory-class fragments as exemplars:
79
+
80
+ - `.claude/hooks/session-reflection.d/70-recent-strategic-artifacts.sh`
81
+ - `.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh`
82
+ - `.claude/hooks/session-reflection.d/80-workflow-staleness.sh`
83
+
84
+ Remaining fragments migrate under a follow-on ticket. Each PR migrates one or a small set. The pattern is: pick the level per the two questions above, change the `blocked_banner "$MSG"` to `blocked_banner "$MSG" advisory` (or `info`), update the fragment's docstring to name the level.
85
+
86
+ ## Composes with
87
+
88
+ - `.claude/rules/blocked-items.md` — BLOCK protocol; still fires at the blocking level
89
+ - `.claude/rules/artifact-ingestion.md` §"Session-start branch" — the 70-recent-strategic-artifacts fragment is advisory per this standard
90
+ - `.claude/rules/bassclef-hook-drift-blocker.md` — a real drift is BLOCK; a stale check is ADVISORY
91
+ - `@luminary donald-norman` — signifier fit
92
+ - `@luminary alan-cooper` — Sam persona at first-run
93
+ - `@luminary edward-tufte` — data-ink ratio for glyph-as-data
94
+
95
+ ## Refs
96
+
97
+ - #1704 — the original consult ask (banner tone reads as broken to Sam)
98
+ - `.claude/hooks/session-reflection.sh` L84 — `blocked_banner` function
99
+ - `docs/canvases/2026-07-19-bassclef-lite.md` — Sam persona anchor for lite tier
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thebassclef/lite",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Bassclef CLI — install and upgrade bassclef in your project with two commands.",
5
5
  "keywords": [
6
6
  "bassclef",