@thebassclef/lite 1.9.4 → 1.9.5

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.
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env bash
2
+ # tier: lite
3
+ # scripts/launch/parse-input-args.sh — argument parser for /launch
4
+ # (bassclef#459 sub-bet 2 — LR3 WU-2; renamed under bassclef#967).
5
+ #
6
+ # Parses /launch args and emits structured output describing whether
7
+ # the dispatch is text-mode (legacy paragraph input) or brownfield-mode
8
+ # (repo URL or local path).
9
+ #
10
+ # Usage forms:
11
+ # bash parse-input-args.sh <tier> "<text-paragraph>"
12
+ # bash parse-input-args.sh <tier> --brownfield <repo-url-or-path>
13
+ #
14
+ # Output (JSON to stdout):
15
+ # {
16
+ # "tier": "medium" | "full",
17
+ # "input_type": "text" | "repo",
18
+ # "input_source": "<paragraph or URL or path>",
19
+ # "brownfield_flag": true | false
20
+ # }
21
+ #
22
+ # Exit codes:
23
+ # 0 = parse OK
24
+ # 2 = bad input (missing tier, missing source, unknown tier)
25
+ #
26
+ # Pairs with: .claude/skills/launch/SKILL.md Phase 0
27
+ # scripts/interpret-input.sh (downstream consumer when input_type=repo)
28
+
29
+ set -u
30
+
31
+ TIER="${1:-}"
32
+ shift 2>/dev/null || true
33
+
34
+ if [ -z "$TIER" ]; then
35
+ echo "parse-input-args: missing <tier> (medium|full)" >&2
36
+ exit 2
37
+ fi
38
+
39
+ # Validate tier
40
+ case "$TIER" in
41
+ medium|full) ;;
42
+ quick|light)
43
+ echo "parse-input-args: $TIER is a prototype tier — use /preview $TIER instead" >&2
44
+ exit 2
45
+ ;;
46
+ *)
47
+ echo "parse-input-args: unknown tier '$TIER' (must be: medium|full)" >&2
48
+ exit 2
49
+ ;;
50
+ esac
51
+
52
+ INPUT_TYPE="text"
53
+ INPUT_SOURCE=""
54
+ BROWNFIELD_FLAG="false"
55
+ VOICE_INPUT_FLAG="false"
56
+ LOCAL_MODE="false"
57
+ REUSE_ARTIFACT_PATH=""
58
+
59
+ # Parse remaining args. --brownfield takes the next arg as source.
60
+ # Otherwise the first non-flag positional arg is the text paragraph.
61
+ while [ $# -gt 0 ]; do
62
+ case "$1" in
63
+ --brownfield)
64
+ BROWNFIELD_FLAG="true"
65
+ INPUT_TYPE="repo"
66
+ shift
67
+ if [ $# -eq 0 ] || [ -z "${1:-}" ]; then
68
+ echo "parse-input-args: --brownfield requires a <repo-url-or-path> argument" >&2
69
+ exit 2
70
+ fi
71
+ INPUT_SOURCE="$1"
72
+ shift
73
+ ;;
74
+ --brownfield=*)
75
+ BROWNFIELD_FLAG="true"
76
+ INPUT_TYPE="repo"
77
+ INPUT_SOURCE="${1#--brownfield=}"
78
+ shift
79
+ if [ -z "$INPUT_SOURCE" ]; then
80
+ echo "parse-input-args: --brownfield= requires a value" >&2
81
+ exit 2
82
+ fi
83
+ ;;
84
+ --voice-input)
85
+ # Phase V Hey-Alexa MVD — input text originated from voice dictation.
86
+ # Phase 3.5 intent extraction applies tolerant settings per
87
+ # standards/voice-input-pattern.md.
88
+ VOICE_INPUT_FLAG="true"
89
+ shift
90
+ ;;
91
+ --local)
92
+ # bassclef#923 A2 — adopter without vendor accounts. Phase 12
93
+ # swaps bind-subdomain for scripts/launch/local-serve.sh; gallery
94
+ # served on localhost. Anthropic API key is the only credential
95
+ # needed.
96
+ LOCAL_MODE="true"
97
+ shift
98
+ ;;
99
+ --reuse-artifact)
100
+ # bassclef-upstream#716 — reuse a pre-shaped InputArtifact instead
101
+ # of minting a fresh one via interpret-input.sh. Phase 1 of the
102
+ # SKILL branches on REUSE_ARTIFACT_PATH being non-empty: validates
103
+ # the file against input-artifact.schema.json, copies to sprint
104
+ # slot, skips interpret-input dispatch. Default off preserves
105
+ # existing text / --brownfield / --voice-input behavior.
106
+ shift
107
+ if [ $# -eq 0 ] || [ -z "${1:-}" ]; then
108
+ echo "parse-input-args: --reuse-artifact requires a <path> argument" >&2
109
+ exit 2
110
+ fi
111
+ REUSE_ARTIFACT_PATH="$1"
112
+ if [ ! -f "$REUSE_ARTIFACT_PATH" ]; then
113
+ echo "parse-input-args: --reuse-artifact file not found: $REUSE_ARTIFACT_PATH" >&2
114
+ exit 2
115
+ fi
116
+ shift
117
+ ;;
118
+ --reuse-artifact=*)
119
+ REUSE_ARTIFACT_PATH="${1#--reuse-artifact=}"
120
+ shift
121
+ if [ -z "$REUSE_ARTIFACT_PATH" ]; then
122
+ echo "parse-input-args: --reuse-artifact= requires a value" >&2
123
+ exit 2
124
+ fi
125
+ if [ ! -f "$REUSE_ARTIFACT_PATH" ]; then
126
+ echo "parse-input-args: --reuse-artifact file not found: $REUSE_ARTIFACT_PATH" >&2
127
+ exit 2
128
+ fi
129
+ ;;
130
+ --no-launch|--persist|base=*|seed=*)
131
+ # Pass-through flags consumed by other phases; ignored here
132
+ shift
133
+ ;;
134
+ --*)
135
+ # Unknown flag — pass through (phase-specific parsing may handle it)
136
+ shift
137
+ ;;
138
+ *)
139
+ # Positional text input (legacy mode)
140
+ if [ -z "$INPUT_SOURCE" ]; then
141
+ INPUT_SOURCE="$1"
142
+ fi
143
+ shift
144
+ ;;
145
+ esac
146
+ done
147
+
148
+ # When --reuse-artifact is set without a paragraph, use the artifact
149
+ # path as the INPUT_SOURCE so downstream SPRINT_SLUG md5 computation
150
+ # stays deterministic.
151
+ if [ -z "$INPUT_SOURCE" ] && [ -n "$REUSE_ARTIFACT_PATH" ]; then
152
+ INPUT_SOURCE="$REUSE_ARTIFACT_PATH"
153
+ fi
154
+
155
+ if [ -z "$INPUT_SOURCE" ]; then
156
+ echo "parse-input-args: missing input — pass a text paragraph or --brownfield <source> or --reuse-artifact <path>" >&2
157
+ exit 2
158
+ fi
159
+
160
+ # Emit JSON
161
+ jq -n \
162
+ --arg tier "$TIER" \
163
+ --arg input_type "$INPUT_TYPE" \
164
+ --arg input_source "$INPUT_SOURCE" \
165
+ --arg reuse_artifact_path "$REUSE_ARTIFACT_PATH" \
166
+ --argjson brownfield_flag "$BROWNFIELD_FLAG" \
167
+ --argjson voice_input_flag "$VOICE_INPUT_FLAG" \
168
+ --argjson local_mode "$LOCAL_MODE" \
169
+ '{
170
+ tier: $tier,
171
+ input_type: $input_type,
172
+ input_source: $input_source,
173
+ reuse_artifact_path: $reuse_artifact_path,
174
+ brownfield_flag: $brownfield_flag,
175
+ voice_input_flag: $voice_input_flag,
176
+ local_mode: $local_mode
177
+ }'
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env bash
2
+ # tier: lite
3
+ # scripts/longrun-preset-detect.sh — /longrun Step 0.85 preset picker helper
4
+ #
5
+ # Reads three signal sources and returns exactly one preset:
6
+ # converged | exploratory | reversible-small | ambiguous
7
+ #
8
+ # Signals (precedence order):
9
+ # 1. plan doc — docs/next-session-plan-*.md modified within 48h → converged
10
+ # 2. problem marker — state/markers/state-a-problem/*.marker within 48h → converged
11
+ # 3. whereami PRIMARY — next_in_flight_goal line with PRIMARY + priority-list
12
+ # shape AND no unresolved GATE line above → converged
13
+ # (else) → exploratory
14
+ #
15
+ # Contract (Hoare):
16
+ # Precondition: whereami path OR plan-doc dir OR problem-marker dir given
17
+ # Postcondition: stdout contains exactly one preset string; stderr contains
18
+ # a "trigger=<source>" line naming which signal fired
19
+ # Exit: always 0 (advisory helper; picker uses stdout)
20
+ #
21
+ # Per bassclef-upstream#1598 preset picker + Q1 /longrun 2026-09-22 Step 1
22
+ # Per docs/use-cases/UC-rule-longrun-prep-whereami-signal.md
23
+ # Per .claude/rules/longrun-prep-plan-doc-compression.md
24
+ # Anchor luminaries: parnas (narrow interface) + hoare (contract) + nygard (precedence)
25
+
26
+ set -uo pipefail
27
+
28
+ WHEREAMI=""
29
+ PLAN_DOC_DIR=""
30
+ PROBLEM_MARKER_DIR=""
31
+
32
+ while [ $# -gt 0 ]; do
33
+ case "$1" in
34
+ --whereami) WHEREAMI="$2"; shift 2 ;;
35
+ --plan-doc-dir) PLAN_DOC_DIR="$2"; shift 2 ;;
36
+ --problem-marker-dir) PROBLEM_MARKER_DIR="$2"; shift 2 ;;
37
+ *) shift ;;
38
+ esac
39
+ done
40
+
41
+ # Signal 1 — plan doc within 48h
42
+ if [ -n "$PLAN_DOC_DIR" ] && [ -d "$PLAN_DOC_DIR" ]; then
43
+ plan_doc=$(find "$PLAN_DOC_DIR" -maxdepth 1 -name 'next-session-plan-*.md' -mtime -2 -type f 2>/dev/null | head -1)
44
+ if [ -n "$plan_doc" ]; then
45
+ echo "trigger=plan-doc" >&2
46
+ echo "converged"
47
+ exit 0
48
+ fi
49
+ fi
50
+
51
+ # Signal 2 — fresh problem marker within 48h
52
+ if [ -n "$PROBLEM_MARKER_DIR" ] && [ -d "$PROBLEM_MARKER_DIR" ]; then
53
+ fresh_marker=$(find "$PROBLEM_MARKER_DIR" -type f -mtime -2 2>/dev/null | head -1)
54
+ if [ -n "$fresh_marker" ]; then
55
+ echo "trigger=problem-marker" >&2
56
+ echo "converged"
57
+ exit 0
58
+ fi
59
+ fi
60
+
61
+ # Signal 3 — whereami PRIMARY queue with no unresolved GATE
62
+ if [ -n "$WHEREAMI" ] && [ -f "$WHEREAMI" ]; then
63
+ # Grab the next_in_flight_goal line plus continuation lines (support both
64
+ # inline whereami shape and multi-line bulleted shape).
65
+ # Read the line and the 10 lines following it — captures multi-line PRIMARY forms.
66
+ goal_block=$(awk '/^next_in_flight_goal:/{flag=1; n=0} flag {print; n++; if (n>=10) flag=0}' "$WHEREAMI" 2>/dev/null)
67
+ if [ -n "$goal_block" ]; then
68
+ # Check for PRIMARY (case-insensitive) anywhere in the block
69
+ has_primary=$(echo "$goal_block" | grep -iE 'primary' >/dev/null 2>&1 && echo "yes" || echo "no")
70
+ # Priority shape — numbered "(1)" OR "priority order" phrase
71
+ has_priority_shape=$(echo "$goal_block" | grep -iE '\(1\)|priority order' >/dev/null 2>&1 && echo "yes" || echo "no")
72
+
73
+ # GATE guard — check for unresolved GATE line preceding PRIMARY within the block
74
+ has_gate=$(echo "$goal_block" | grep -iE 'gate[[:space:]:—-].*primary|gate:.*wait|GATE[[:space:]]+—[[:space:]]*wait' >/dev/null 2>&1 && echo "yes" || echo "no")
75
+
76
+ if [ "$has_primary" = "yes" ] && [ "$has_priority_shape" = "yes" ] && [ "$has_gate" = "no" ]; then
77
+ echo "trigger=whereami-PRIMARY" >&2
78
+ echo "converged"
79
+ exit 0
80
+ fi
81
+ fi
82
+ fi
83
+
84
+ # No signal fired — default to exploratory
85
+ echo "trigger=none" >&2
86
+ echo "exploratory"
87
+ exit 0
@@ -34,6 +34,42 @@ 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
+ ### #1961 — persistent statusline for bassclef version + sync status (v1.12.2 → v1.13.0, 2026-09-27)
38
+
39
+ - **Change type:** content-add (1 new entry: `statusline-version` lib) + content-change (2 files: `bassclef-sync` hook + `bassclef-orientation`)
40
+ - **Fields:** 440 entries → 441 entries. New entry: `lib/statusline-version.sh` (type=lib, slug=`statusline-version`). Content hashes shift on `bassclef-sync` and `bassclef-orientation` slugs (state-file writer added; opt-in section documented).
41
+ - **Version bump:** v1.12.2 → v1.13.0 (MINOR — new entry added, no shape shift, nothing removed).
42
+ - **Rationale:** peer session `bassclef-cli-b2` cold-adopter smoke on cli v1.9.4 + bassclef v1.6.2 surfaced the visibility gap. Operators cannot see bassclef version + sync status on every prompt today; the SessionStart banner scrolls off. The new lib reads state written by `bassclef-sync.sh` at end-of-run and emits `bassclef v<X> · <sync_status>` for adopters who opt in at user-scope. See PR (this cure) + `docs/use-cases/UC-lib-statusline-version-drift.md` + `docs/decompositions/2026-09-27-statusline-version-drift.md`.
43
+ - **Downstream cure:** none required. Adopters opt in via user-scope `~/.claude/settings.json` `statusLine.command` per the section in `.claude/bassclef-orientation.md`. Adopters who do not opt in see zero change.
44
+ - **Old shape retired:** none — additive only.
45
+
46
+ ### #1959 — /onboard-repo friendlier first-run greeting (v1.12.1 → v1.12.2, 2026-09-27)
47
+
48
+ - **Change type:** content-change (1 file: `onboard-repo` skill body)
49
+ - **Fields:** 440 entries (unchanged). Content hash shifts on the `onboard-repo` slug — `.claude/skills/onboard-repo/SKILL.md` gains a new `## First-run greeting (state-detected)` section BEFORE the existing 4-option picker.
50
+ - **Version bump:** v1.12.1 → v1.12.2 (content_hash change only → patch bump per policy).
51
+ - **Rationale:** peer bassclef-cli-b2 cold-adopter smoke against cli v1.9.4 + bassclef v1.6.2 flagged the first-run picker as slower than needed. Fresh-init adopter with `.bassclef/init.manifest.json` under 24h + no remote + on main now reads a two-line question naming the two most common paths (share on GitHub / top up local) plus a `skip` line to the full picker. Adopters outside those state conditions see the current picker unchanged.
52
+ - **Downstream cure:** none required. Adopters see one additional greeting section only when state matches.
53
+ - **Old shape retired:** none — the existing picker is preserved verbatim as fallback.
54
+
55
+ ### #1962 — capability-probe self-check removed (v1.12.0 → v1.12.1, 2026-09-26)
56
+
57
+ - **Change type:** content-change (1 file: `capability-probe`)
58
+ - **Fields:** 440 entries (unchanged). Content hash shifts on the `capability-probe` slug — `lib/capability-probe.sh` loses the runtime self-check block at L124-140.
59
+ - **Version bump:** v1.12.0 → v1.12.1 (content_hash change only → patch bump per policy).
60
+ - **Rationale:** peer bassclef-cli-aa cold-adopter smoke against `@thebassclef/lite@1.6.2` surfaced false WARN emissions on stderr from a self-check that erroneously reported missing functions on healthy state. Root cause not reproduced in bassclef-upstream root. The Tier 0 test at `lib/tests/capability-probe.test.sh` T02 already asserts every function resolves after source; that signal is stricter and more precise. See PR (this cure).
61
+ - **Downstream cure:** none required. Adopters see one fewer noise line on stderr when a session sources the lib.
62
+ - **Old shape retired:** immediately. The runtime WARN was noise, not a promised feature.
63
+
64
+ ### #1960 — extractor recurses nested scripts + retags two scripts to lite (v1.11.3 → v1.12.0, 2026-09-26)
65
+
66
+ - **Change type:** content-add (6 new entries) + policy-change (extractor recursion on 6 collections)
67
+ - **Fields:** 434 entries → 440 entries. New entries: `scripts/launch/local-serve.sh`, `scripts/launch/local-serve-stop.sh`, `scripts/launch/parse-input-args.sh`, `scripts/interpret-input/extract-repo.sh`, `scripts/interpret-input.sh` (retag standard → lite), `scripts/longrun-preset-detect.sh` (retag upstream → lite).
68
+ - **Version bump:** v1.11.3 → v1.12.0 (MINOR — entries added, no shape shift, no entries removed).
69
+ - **Rationale:** `scripts/generate-lite-manifest.sh` used `find -maxdepth 1` on six collections (`lib/`, `scripts/`, `presence/install/` × 3 file extensions, `templates/`). Nested scripts under `scripts/launch/` and `scripts/interpret-input/` silently dropped. `/launch` and `/longrun` skills at `tier: lite` dispatched shell files public bassclef never shipped. Peer session `bassclef-cli-b2` surfaced the class during cold-adopter smoke on cli v1.9.4 + bassclef v1.6.2. See PR (this cure) + `docs/use-cases/UC-scripts-generate-lite-manifest-recurse.md`.
70
+ - **Downstream cure:** none required for adopters at MINOR bump. Adopters pinning exact `manifest_version` (bassclef-web#256 + bassclef-cli#51 are the known consumers) update their pin from v1.11.x to v1.12.0 on their normal cadence. Coord comments posted on both tickets before the release cascade fires.
71
+ - **Old shape retired:** immediately. The pre-v1.12.0 flat extraction had no adopter-observable contract worth preserving — the omitted scripts were bugs, not features.
72
+
37
73
  ### Track 1 v1.5.1 — bassclef-sync clone-fail postcondition emit + banner-to-stderr (v1.11.0 → v1.11.1, 2026-09-24)
38
74
 
39
75
  - **Change type:** content-change (1 file: `bassclef-sync-template`)
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "tier": "lite",
3
- "manifest_version": "1.11.2",
4
- "generated_at": "2026-09-26T11:18:11Z",
3
+ "manifest_version": "1.13.0",
4
+ "generated_at": "2026-09-27T22:46:25Z",
5
5
  "entries": [
6
6
  {
7
7
  "slug": "029-release-pipeline",
@@ -608,7 +608,7 @@
608
608
  "type": "hook",
609
609
  "path": ".claude/hooks/session-reflection.sh",
610
610
  "tier": "lite",
611
- "content_hash": "sha256:5d06b68d7503922cd3f5143ed2d83ec4e12c5d8e6f16822efcf2c702f49ed5b9",
611
+ "content_hash": "sha256:7350b6b8e0163eb79207e01c2ef70be741ff6bcb94f23ca92acb387618b642d3",
612
612
  "description": "Session Start hook coordinator. Injects reflection prompt and iterates"
613
613
  },
614
614
  {
@@ -728,7 +728,7 @@
728
728
  "type": "lib",
729
729
  "path": "lib/ancestor-claude-check.sh",
730
730
  "tier": "lite",
731
- "content_hash": "sha256:f84c7b57ae28ef15b0c4c138ee4781030e04e7bb858ff0c53a80a538672d64dd",
731
+ "content_hash": "sha256:ccfbdb9f9d10f16c530c29d126a7a67386d2d15631e014ef1b44033d77c9a402",
732
732
  "description": "ancestor-claude-check.sh — walks up from a starting directory to $HOME"
733
733
  },
734
734
  {
@@ -744,7 +744,7 @@
744
744
  "type": "lib",
745
745
  "path": "lib/capability-probe.sh",
746
746
  "tier": "lite",
747
- "content_hash": "sha256:12d4d7cfa78bd07e1f67a405a88b960ac62ac637297698d8ca43f217b74f4de0",
747
+ "content_hash": "sha256:2db9a81735980513eebc9712510cb3b615557a5ab1b48ace48840ed28bc1e4c1",
748
748
  "description": "lib/capability-probe.sh — capability probe deep module."
749
749
  },
750
750
  {
@@ -915,6 +915,14 @@
915
915
  "content_hash": "sha256:38b6cfa82123e75bb1046b97887060962a62d90ba9d089764529207ebf8c8194",
916
916
  "description": "lib/state.sh — typed accessor library over bassclef's state spine."
917
917
  },
918
+ {
919
+ "slug": "statusline-version",
920
+ "type": "lib",
921
+ "path": "lib/statusline-version.sh",
922
+ "tier": "lite",
923
+ "content_hash": "sha256:89785704ee8df0cccfd20b32bbcca537505872cda75ca49fa6ee2824b236b27f",
924
+ "description": "lib/statusline-version.sh — bassclef statusline reader."
925
+ },
918
926
  {
919
927
  "slug": "telemetry",
920
928
  "type": "lib",
@@ -1319,7 +1327,7 @@
1319
1327
  "type": "presence-template",
1320
1328
  "path": "presence/install/bassclef-sync.template.sh",
1321
1329
  "tier": "lite",
1322
- "content_hash": "sha256:d79a9a6499c1bcaa368e0472f7a9cd76611f2dbdb8ab2b42533c3f85de2323c4",
1330
+ "content_hash": "sha256:92fa84059bd69964a35887b9b77812bfb3acc58c9ca4c9618bacf11d56079c2a",
1323
1331
  "description": "description: BASSCLEF_SYNC_VERSION=2026-09-06-1496-sessionstart-heal-v1"
1324
1332
  },
1325
1333
  {
@@ -1350,7 +1358,7 @@
1350
1358
  "type": "root-doc",
1351
1359
  "path": ".claude/bassclef-orientation.md",
1352
1360
  "tier": "lite",
1353
- "content_hash": "sha256:657e68fe29c52aaf9dd54ff752cf6f69498543484e4a764db89ba9837c0d9436"
1361
+ "content_hash": "sha256:25270e2b752a37c485b824c09b72352d264d5f2febc77b85ba5f8087db1d63b2"
1354
1362
  },
1355
1363
  {
1356
1364
  "slug": "claude-lite",
@@ -1477,7 +1485,7 @@
1477
1485
  "type": "rule",
1478
1486
  "path": ".claude/rules/blocked-items.md",
1479
1487
  "tier": "lite",
1480
- "content_hash": "sha256:e81e1e48d86e38fff8ba109f356e769dab8bbf362160bd2febcd6ae8f13b2b9b",
1488
+ "content_hash": "sha256:def3b1305f7d08d4b68cd7261827e1209d5606a9c35728b13f5c3ac4d68c9f66",
1481
1489
  "description": "Session-start hook output may contain lines prefixed with BLOCKED:."
1482
1490
  },
1483
1491
  {
@@ -2024,12 +2032,20 @@
2024
2032
  "content_hash": "sha256:d7a13ca4fb37283e50fc165bb5ebd6a65539d7dade005dcd38098e1d878c52b3",
2025
2033
  "description": "analyze-tier-dependencies.sh — orchestrator for the tier-dependency-audit subsystem"
2026
2034
  },
2035
+ {
2036
+ "slug": "extract-repo",
2037
+ "type": "script",
2038
+ "path": "scripts/interpret-input/extract-repo.sh",
2039
+ "tier": "lite",
2040
+ "content_hash": "sha256:ba15cb33e4d13ef3936d5ad7400a4be1460fae386189aafc9f29c382e4c6a16f",
2041
+ "description": "scripts/interpret-input/extract-repo.sh — Phase C repo extractor."
2042
+ },
2027
2043
  {
2028
2044
  "slug": "generate-lite-manifest",
2029
2045
  "type": "script",
2030
2046
  "path": "scripts/generate-lite-manifest.sh",
2031
2047
  "tier": "lite",
2032
- "content_hash": "sha256:6342c768c91af054a4dcb6ea3e63228f0c7b4ff0e188867026fe0cdd333e3fe5",
2048
+ "content_hash": "sha256:8d2741d06181f41af3d30965cdfd655d20508807e3fc799877fa2564811e5608",
2033
2049
  "description": "Generate lite-manifest.json at repo root."
2034
2050
  },
2035
2051
  {
@@ -2048,6 +2064,14 @@
2048
2064
  "content_hash": "sha256:9921d0b4c0375b3099bc3dc8457800ad157837286244f0ede46f8146127d0b73",
2049
2065
  "description": "intent-drift-check.sh — measure intent drift after an artifact body rewrite."
2050
2066
  },
2067
+ {
2068
+ "slug": "interpret-input",
2069
+ "type": "script",
2070
+ "path": "scripts/interpret-input.sh",
2071
+ "tier": "lite",
2072
+ "content_hash": "sha256:882ac0c728bb903b59a3d92648e9db738d1cf503eebfe3bfdd28094b28e6167c",
2073
+ "description": "scripts/interpret-input.sh — input-handler CLI wrapper."
2074
+ },
2051
2075
  {
2052
2076
  "slug": "lite-manifest-drift-check",
2053
2077
  "type": "script",
@@ -2056,6 +2080,38 @@
2056
2080
  "content_hash": "sha256:0f14aa7aec1b52820c53f7f1fd5e58d8742fd426577a6a8682f8d5f0a5ceba5f",
2057
2081
  "description": "Detect drift between committed lite-manifest.json and current substrate state."
2058
2082
  },
2083
+ {
2084
+ "slug": "local-serve",
2085
+ "type": "script",
2086
+ "path": "scripts/launch/local-serve.sh",
2087
+ "tier": "lite",
2088
+ "content_hash": "sha256:5494f4b46308e4b799d4e3aa2accc1f0880c78280dc8e5f5bcb45537d40036ab",
2089
+ "description": "local-serve.sh — serve a /launch local-mode prototype gallery via python http.server"
2090
+ },
2091
+ {
2092
+ "slug": "local-serve-stop",
2093
+ "type": "script",
2094
+ "path": "scripts/launch/local-serve-stop.sh",
2095
+ "tier": "lite",
2096
+ "content_hash": "sha256:89a0ee5c195c806c08ffc7221525ff6f805bd904580f94e6e7ed34be236c067b",
2097
+ "description": "local-serve-stop.sh — stop a local-serve.sh server by slug"
2098
+ },
2099
+ {
2100
+ "slug": "longrun-preset-detect",
2101
+ "type": "script",
2102
+ "path": "scripts/longrun-preset-detect.sh",
2103
+ "tier": "lite",
2104
+ "content_hash": "sha256:b339d2213b68d7db6d4d26ffbef96071507e62368ac274423e8a7367cfdb951d",
2105
+ "description": "scripts/longrun-preset-detect.sh — /longrun Step 0.85 preset picker helper"
2106
+ },
2107
+ {
2108
+ "slug": "parse-input-args",
2109
+ "type": "script",
2110
+ "path": "scripts/launch/parse-input-args.sh",
2111
+ "tier": "lite",
2112
+ "content_hash": "sha256:b117181be876c6fb76a7e9d11cf1fcbc25bbf56a9b4877a35dbf96e9bad13906",
2113
+ "description": "scripts/launch/parse-input-args.sh — argument parser for /launch"
2114
+ },
2059
2115
  {
2060
2116
  "slug": "render-lite-manifest-doc",
2061
2117
  "type": "script",
@@ -2596,7 +2652,7 @@
2596
2652
  "type": "skill",
2597
2653
  "path": ".claude/skills/longrun/SKILL.md",
2598
2654
  "tier": "lite",
2599
- "content_hash": "sha256:1ab5a98d5ea805249761e092c7c8c8523eb3cd7ce53e6d89790d01e767a3df4b",
2655
+ "content_hash": "sha256:1a7dbaf2098525b68609e0eed0ad24c56d0fdf6e7905da6196c0c620b0de6976",
2600
2656
  "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.",
2601
2657
  "composes_with": [
2602
2658
  "value-prop",
@@ -2681,7 +2737,7 @@
2681
2737
  "type": "skill",
2682
2738
  "path": ".claude/skills/onboard-repo/SKILL.md",
2683
2739
  "tier": "lite",
2684
- "content_hash": "sha256:ff92c1539bbad449bbdcfc85430963ceeda8cae67a2eded953bc95dff24a3c75",
2740
+ "content_hash": "sha256:1903e5140a85c40034d8109f522ad973da26d7a12a71ec9ae795c66438e23286",
2685
2741
  "description": "Bootstrap the bassclef framework in a new repo. Installs the sync hook. Scaffolds config, whereami, and CLAUDE.md. Modes: default, --with-deploy-host, --with-secrets, --full, --greenfield-from-intent (cold-adopter magic demo).",
2686
2742
  "inputs": [
2687
2743
  "Optional flags — --with-deploy-host or --with-secrets or --full"
@@ -3761,7 +3817,7 @@
3761
3817
  "type": "standard",
3762
3818
  "path": "standards/lite-manifest-schema-changes.md",
3763
3819
  "tier": "lite",
3764
- "content_hash": "sha256:bccea2ce3acc450f35729690e7c24706391c87186ce99ece91e574a8f4686c58",
3820
+ "content_hash": "sha256:312775fd9c55feb4537a4346de309b73a37d8f3c44793aa62f43b14246f3a2cd",
3765
3821
  "description": "Chronological ledger of every lite-manifest schema change. Adopters read this before sync to know what shifted."
3766
3822
  },
3767
3823
  {
@@ -4001,7 +4057,7 @@
4001
4057
  "type": "standard",
4002
4058
  "path": "standards/session-start-banner-discipline.md",
4003
4059
  "tier": "lite",
4004
- "content_hash": "sha256:444a6f20be6bd175dabb06b8aedb527b9c93525786df0386fd785d1821451a4e",
4060
+ "content_hash": "sha256:b9d4506ec8239583d7e61797b03cd4307531c664de0c4d384bdf1157162371e2",
4005
4061
  "description": "Four-level banner palette for session-start checks. Per Norman signifier + Cooper Sam persona consult. Match glyph to state."
4006
4062
  },
4007
4063
  {
@@ -9,26 +9,39 @@ Session-start checks in `.claude/hooks/session-reflection.d/` emit banners that
9
9
 
10
10
  This standard names a four-level palette. Each check picks the level that matches its own state.
11
11
 
12
- ## The four levels
12
+ ## The five levels
13
13
 
14
14
  | Level | Glyph | Text label | When to use |
15
15
  |---|---|---|---|
16
16
  | BLOCK | 🛑 | BLOCKED | The session cannot safely proceed with substantive work. Real defect. Missing prerequisite. Active drift that will corrupt state. |
17
+ | GUARDRAIL | ⚙ | BASSCLEF DISCIPLINE GATE | The session must pause and apply discipline before proceeding. Not a defect. Chronicle stale, architect-review overdue, temperance marker missing, /decompose evidence owed. Per sunj-labs/bassclef-upstream#1930 Category A. |
17
18
  | ADVISORY | ⚠ | ADVISORY | Context worth reading. Session may proceed. The operator is informed; they choose whether to act now or later. |
18
19
  | 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
+ | silent-on-clean | — | — | Check runs but reports nothing when state is nominal. Fires only on non-nominal state (which routes to one of the four above). |
20
21
 
21
22
  Every check picks exactly one level. Ambiguous cases default to silent-on-clean.
22
23
 
24
+ BLOCK and GUARDRAIL both stop the session on substantive work. The difference is tone. BLOCK signals a defect. GUARDRAIL signals a discipline pause. Machine readers grep the `BLOCKED:` prefix on message body lines regardless of header shape.
25
+
23
26
  ## How to pick
24
27
 
25
- Ask two questions in order.
28
+ Ask three questions in order.
26
29
 
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.
30
+ 1. **Does this check indicate a real defect that will corrupt state?** If yes, BLOCK. Schema validation failure, dangling reference, corrupt state file, missing bassclef-sync template drift. These block.
31
+ 2. **Does this check ask the agent to pause and apply discipline?** If yes, GUARDRAIL. Chronicle stale, architect-review overdue, temperance missing, /decompose evidence owed, pre-mortem light not fired. These are steering, not defects.
32
+ 3. **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
33
 
30
34
  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
35
 
36
+ ## Helper functions
37
+
38
+ Two shell helpers in `.claude/hooks/session-reflection.sh` render the banners.
39
+
40
+ - `blocked_banner "$msg" [severity]` — renders BLOCK, ADVISORY, or INFO based on the second arg (default: blocking). Used by all four historical severities.
41
+ - `guardrail_banner "$hook_name" "$step" "$retry"` — renders GUARDRAIL. Takes three args: hook name (goes in header), specific step, retry action. Reads `AI_NAME` from `${BASSCLEF_AI_NAME:-Claude}`. Per #1930 Category A design lock.
42
+
43
+ Callers migrate from `blocked_banner` (blocking) to `guardrail_banner` one at a time when the check fits the discipline-gate shape (question 2 above). The additive-only path preserves the machine-reader contract.
44
+
32
45
  ## Signifier discipline (Norman)
33
46
 
34
47
  The glyph is a signifier — a perceivable cue that suggests state. The signifier fit is:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thebassclef/lite",
3
- "version": "1.9.4",
3
+ "version": "1.9.5",
4
4
  "description": "Bassclef CLI — install and upgrade bassclef in your project with two commands.",
5
5
  "keywords": [
6
6
  "bassclef",