@thebassclef/lite 1.9.15 → 1.9.18
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/agents/builder.md +7 -4
- package/dist/lite/.claude/bassclef-orientation.md +22 -0
- package/dist/lite/.claude/hooks/artifact-ingestion-gate.sh +11 -3
- package/dist/lite/.claude/hooks/assert-verify-steering.sh +1 -19
- package/dist/lite/.claude/hooks/plain-english-steering.sh +86 -41
- package/dist/lite/.claude/hooks/pre-commit-gate.sh +10 -2
- package/dist/lite/.claude/hooks/pre-push-shellcheck.sh +144 -0
- package/dist/lite/.claude/hooks/reviewer-dispatch-check.sh +153 -0
- package/dist/lite/.claude/hooks/session-reflection.d/83-install-written-paths-rebuild.sh +15 -32
- package/dist/lite/.claude/hooks/turn-prose-density-measure.sh +109 -0
- package/dist/lite/.claude/hooks/turn-prose-kiss-check.sh +28 -0
- package/dist/lite/.claude/rules/branching.md +2 -0
- package/dist/lite/.claude/rules/identifier-leak-prevention.md +2 -1
- package/dist/lite/.claude/rules/lite-manifest-schema-change-discipline.md +23 -0
- package/dist/lite/.claude/rules/reviewer-dispatch.md +95 -0
- package/dist/lite/.claude/settings.json +10 -0
- package/dist/lite/.claude/skills/build/SKILL.md +81 -6
- package/dist/lite/.claude/skills/eisenhower/SKILL.md +26 -0
- package/dist/lite/.claude/skills/launch/SKILL.md +45 -2
- package/dist/lite/.claude/skills/onboard-repo/SKILL.md +204 -40
- package/dist/lite/.claude/skills/onboard-repo/concise-prompt.sh +73 -0
- package/dist/lite/.claude/skills/onboard-repo/write-state-marker.sh +81 -0
- package/dist/lite/.claude/skills/pre-mortem/SKILL.md +56 -0
- package/dist/lite/.claude/skills/sprint/SKILL.md +24 -3
- package/dist/lite/.claude/skills/temperance/SKILL.md +15 -4
- package/dist/lite/README.md +2 -0
- package/dist/lite/bassclef-version.json +5 -5
- package/dist/lite/lib/install-written-paths.sh +250 -3
- package/dist/lite/lib/prose-marker.sh +203 -0
- package/dist/lite/lib/tier-dependency-audit.sh +52 -25
- package/dist/lite/presence/install/bassclef-sync.template.sh +86 -8
- package/dist/lite/scripts/generate-lite-manifest.sh +15 -0
- package/dist/lite/scripts/launch/local-serve.sh +149 -8
- package/dist/lite/standards/bassclef-wiring-manifest.json +12 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +49 -0
- package/dist/lite/standards/lite-manifest.json +90 -27
- package/dist/lite/standards/prose-marker-format.md +105 -0
- package/package.json +1 -1
|
@@ -256,6 +256,64 @@ bassclef_sync_parse_whereami_ts() {
|
|
|
256
256
|
return 0
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
+
# === #2130 — scope-aware install-class resolution + prior-sync check ===
|
|
260
|
+
# Reads a hook source file's `# install-class:` header. Returns one of:
|
|
261
|
+
# project | operator | dual | unknown
|
|
262
|
+
# Fails soft — missing file, missing header, or invalid value → "unknown".
|
|
263
|
+
#
|
|
264
|
+
# Anchor luminaries — @luminary linus-torvalds (adopter contract; project-class
|
|
265
|
+
# hooks must not report scope=operator), @luminary jerome-saltzer-and-michael-schroeder
|
|
266
|
+
# (every scope mediated per source declaration), @luminary michael-feathers
|
|
267
|
+
# (characterization anchor — pin the install-class header shape before cure).
|
|
268
|
+
_template_resolve_install_class() {
|
|
269
|
+
local hook_src="$1"
|
|
270
|
+
if [ ! -f "$hook_src" ]; then
|
|
271
|
+
echo "unknown"
|
|
272
|
+
return 0
|
|
273
|
+
fi
|
|
274
|
+
local header_val
|
|
275
|
+
header_val=$(head -10 "$hook_src" 2>/dev/null | grep -E \
|
|
276
|
+
'^# install-class:[[:space:]]*(operator|project|dual)[[:space:]]*$' \
|
|
277
|
+
| head -1 | sed -E 's/^# install-class:[[:space:]]*//;s/[[:space:]]*$//')
|
|
278
|
+
case "$header_val" in
|
|
279
|
+
project|operator|dual) echo "$header_val" ;;
|
|
280
|
+
*) echo "unknown" ;;
|
|
281
|
+
esac
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
# Returns 0 (true) if the hook is installed at the scope its install-class names.
|
|
285
|
+
# For `dual`, either project or operator location satisfies.
|
|
286
|
+
# For `unknown`, defaults to operator check per ADR-058 C2 grace window.
|
|
287
|
+
#
|
|
288
|
+
# $1 — hook basename (e.g., "pre-commit-gate.sh")
|
|
289
|
+
# $2 — scope value (project | operator | dual | unknown)
|
|
290
|
+
# Reads $CWD and $HOME. $CWD falls back to $(pwd) when unset.
|
|
291
|
+
_template_hook_present_at_scope() {
|
|
292
|
+
local hook_name="$1"
|
|
293
|
+
local scope="$2"
|
|
294
|
+
local cwd="${CWD:-$(pwd)}"
|
|
295
|
+
case "$scope" in
|
|
296
|
+
project)
|
|
297
|
+
[ -f "$cwd/.claude/hooks/$hook_name" ] && return 0
|
|
298
|
+
return 1
|
|
299
|
+
;;
|
|
300
|
+
operator)
|
|
301
|
+
[ -f "$HOME/.claude/hooks/$hook_name" ] && return 0
|
|
302
|
+
return 1
|
|
303
|
+
;;
|
|
304
|
+
dual)
|
|
305
|
+
[ -f "$cwd/.claude/hooks/$hook_name" ] && return 0
|
|
306
|
+
[ -f "$HOME/.claude/hooks/$hook_name" ] && return 0
|
|
307
|
+
return 1
|
|
308
|
+
;;
|
|
309
|
+
*)
|
|
310
|
+
# unknown — grace-window; check operator per legacy behavior
|
|
311
|
+
[ -f "$HOME/.claude/hooks/$hook_name" ] && return 0
|
|
312
|
+
return 1
|
|
313
|
+
;;
|
|
314
|
+
esac
|
|
315
|
+
}
|
|
316
|
+
|
|
259
317
|
# === #1929 — postcondition emitter (RESTORED/DEGRADED + JSON) ===
|
|
260
318
|
# Mirrors .claude/hooks/bassclef-sync.sh L215-243 (idempotent-complete-or-fail-loud
|
|
261
319
|
# pattern shipped under #1894 Cure 1 of #1691). Reads globals INSTALLED_COUNT,
|
|
@@ -1022,9 +1080,16 @@ if [ -d "$BASSCLEF_DIR/.claude/hooks" ]; then
|
|
|
1022
1080
|
fi
|
|
1023
1081
|
if [ -n "$_WALKER_MISS" ]; then
|
|
1024
1082
|
echo "$(date -u +%FT%TZ) install-fail-missing-dep $HOOK_NAME" >> "$BASSCLEF_TRACE_LOG"
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1083
|
+
# #2130 — resolve install-class scope + check if hook is already present
|
|
1084
|
+
# at scoped target from a prior sync. Prior-sync-present counts as installed.
|
|
1085
|
+
_HOOK_SCOPE=$(_template_resolve_install_class "$HOOK_SRC")
|
|
1086
|
+
if _template_hook_present_at_scope "$HOOK_NAME" "$_HOOK_SCOPE"; then
|
|
1087
|
+
INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
|
|
1088
|
+
else
|
|
1089
|
+
FAILED_COUNT=$((FAILED_COUNT + 1))
|
|
1090
|
+
missing_paths+=(".claude/hooks/$HOOK_NAME")
|
|
1091
|
+
missing_scopes+=("$_HOOK_SCOPE")
|
|
1092
|
+
fi
|
|
1028
1093
|
continue
|
|
1029
1094
|
fi
|
|
1030
1095
|
|
|
@@ -1038,9 +1103,15 @@ if [ -d "$BASSCLEF_DIR/.claude/hooks" ]; then
|
|
|
1038
1103
|
cp -p "$HOOK_SRC" "$TARGET_USER" 2>/dev/null || true
|
|
1039
1104
|
chmod +x "$TARGET_USER" 2>/dev/null || true
|
|
1040
1105
|
echo "$(date -u +%FT%TZ) dispatch-fail $HOOK_NAME" >> "$BASSCLEF_TRACE_LOG"
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1106
|
+
# #2130 — scope-aware missing[] + prior-sync pass-through
|
|
1107
|
+
_HOOK_SCOPE=$(_template_resolve_install_class "$HOOK_SRC")
|
|
1108
|
+
if _template_hook_present_at_scope "$HOOK_NAME" "$_HOOK_SCOPE"; then
|
|
1109
|
+
INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
|
|
1110
|
+
else
|
|
1111
|
+
FAILED_COUNT=$((FAILED_COUNT + 1))
|
|
1112
|
+
missing_paths+=(".claude/hooks/$HOOK_NAME")
|
|
1113
|
+
missing_scopes+=("$_HOOK_SCOPE")
|
|
1114
|
+
fi
|
|
1044
1115
|
fi
|
|
1045
1116
|
elif [ "$HAS_HEADER" = "1" ] && [ "$DISPATCH_AVAILABLE" = "0" ]; then
|
|
1046
1117
|
# S-F1 MED — dispatch lib missing; trace explicitly (not silent)
|
|
@@ -1059,8 +1130,15 @@ if [ -d "$BASSCLEF_DIR/.claude/hooks" ]; then
|
|
|
1059
1130
|
else
|
|
1060
1131
|
echo "$(date -u +%FT%TZ) skipped-invalid-header $HOOK_NAME" >> "$BASSCLEF_TRACE_LOG"
|
|
1061
1132
|
SKIPPED_INVALID=$((SKIPPED_INVALID + 1))
|
|
1062
|
-
|
|
1063
|
-
|
|
1133
|
+
# #2130 — invalid header → scope resolves to "unknown"; prior-sync still passes
|
|
1134
|
+
if _template_hook_present_at_scope "$HOOK_NAME" "unknown"; then
|
|
1135
|
+
# Operator-scope fallback cp above landed; treat as installed under grace
|
|
1136
|
+
INSTALLED_COUNT=$((INSTALLED_COUNT + 1))
|
|
1137
|
+
SKIPPED_INVALID=$((SKIPPED_INVALID - 1))
|
|
1138
|
+
else
|
|
1139
|
+
missing_paths+=(".claude/hooks/$HOOK_NAME")
|
|
1140
|
+
missing_scopes+=("unknown")
|
|
1141
|
+
fi
|
|
1064
1142
|
fi
|
|
1065
1143
|
fi
|
|
1066
1144
|
done
|
|
@@ -497,6 +497,18 @@ while IFS= read -r f; do
|
|
|
497
497
|
done < <(find "$REPO_ROOT/.claude/hooks" -mindepth 2 -type f -name '*.sh' \
|
|
498
498
|
-not -path '*/tests/*' -not -path '*/fixtures/*' 2>/dev/null | sort)
|
|
499
499
|
|
|
500
|
+
# Skill-helper scripts (bash) — per bassclef-upstream#2140. Skills (e.g.,
|
|
501
|
+
# onboard-repo) dispatch helper .sh files from their SKILL.md Procedure
|
|
502
|
+
# steps. Lite adopters that run those skills need the helpers to land
|
|
503
|
+
# in their bundle. Shipped as type=script (reuses existing enum; no
|
|
504
|
+
# schema shape change). Only lite-tagged helpers end up in lite-manifest;
|
|
505
|
+
# standard-tagged helpers inherit into standard-manifest + above.
|
|
506
|
+
SKILL_HELPER_FILES=()
|
|
507
|
+
while IFS= read -r f; do
|
|
508
|
+
SKILL_HELPER_FILES+=("$f")
|
|
509
|
+
done < <(find "$REPO_ROOT/.claude/skills" -mindepth 2 -type f -name '*.sh' \
|
|
510
|
+
-not -path '*/tests/*' -not -path '*/fixtures/*' 2>/dev/null | sort)
|
|
511
|
+
|
|
500
512
|
# Top-level .claude/*.md (bassclef-orientation.md) — vendored via @import from adopter
|
|
501
513
|
# CLAUDE.md; ships as root-doc. Per goal 2026-09-16a.
|
|
502
514
|
CLAUDE_DOC_FILES=()
|
|
@@ -635,6 +647,9 @@ ENTRIES_JSON=$(
|
|
|
635
647
|
if [[ ${#SCRIPT_FILES[@]} -gt 0 ]]; then
|
|
636
648
|
emit_entries "script" extract_hook_tier extract_hook_description basename "${SCRIPT_FILES[@]}"
|
|
637
649
|
fi
|
|
650
|
+
if [[ ${#SKILL_HELPER_FILES[@]} -gt 0 ]]; then
|
|
651
|
+
emit_entries "script" extract_hook_tier extract_hook_description basename "${SKILL_HELPER_FILES[@]}"
|
|
652
|
+
fi
|
|
638
653
|
if [[ ${#PRESENCE_TEMPLATE_SH_FILES[@]} -gt 0 ]]; then
|
|
639
654
|
emit_entries "presence-template" extract_hook_tier extract_hook_description basename "${PRESENCE_TEMPLATE_SH_FILES[@]}"
|
|
640
655
|
fi
|
|
@@ -30,16 +30,157 @@
|
|
|
30
30
|
# Cleanup: rely on the operator running scripts/launch/local-serve-stop.sh
|
|
31
31
|
# or just killing the PID. State file lists the PID for reference.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
# === #2131 — testable helpers for arg parsing + usage ===
|
|
34
|
+
# Anchor luminaries — @luminary linus-torvalds (default bind unchanged;
|
|
35
|
+
# --lan is opt-in; no silent regression), @luminary alan-cooper (honesty
|
|
36
|
+
# default — handoff text matches bind reality), @luminary michael-feathers
|
|
37
|
+
# (characterization anchor via LOCAL_SERVE_TEST_MODE guard).
|
|
38
|
+
|
|
39
|
+
_local_serve_print_usage() {
|
|
40
|
+
cat <<'USAGE'
|
|
41
|
+
usage: local-serve.sh [--lan] <gallery-dir> [port-hint]
|
|
42
|
+
|
|
43
|
+
Serves a /launch local-mode prototype gallery via python http.server.
|
|
44
|
+
|
|
45
|
+
Positional:
|
|
46
|
+
gallery-dir path to the gallery directory (must contain index.html)
|
|
47
|
+
port-hint optional starting port (default 8000)
|
|
48
|
+
|
|
49
|
+
Flags:
|
|
50
|
+
--lan bind to 0.0.0.0 (all interfaces) and PRINT the detected
|
|
51
|
+
LAN IP so phones/iPads on the same Wi-Fi can reach the
|
|
52
|
+
URL directly. Default is 127.0.0.1 (this computer only).
|
|
53
|
+
Prints a warning: any device on this Wi-Fi can open the URL.
|
|
54
|
+
Firewall note: macOS firewall may need to be off for the
|
|
55
|
+
port, or the OS will prompt on first bind.
|
|
56
|
+
--help print this usage
|
|
57
|
+
|
|
58
|
+
Exit codes:
|
|
59
|
+
0 — server started OR idempotent re-run returns existing URL
|
|
60
|
+
1 — python3 missing, gallery dir missing, port exhaustion, server crash
|
|
61
|
+
2 — bad args (missing gallery-dir, unknown flag)
|
|
62
|
+
USAGE
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Detects the machine's LAN IP so --lan mode can print a dialable URL
|
|
66
|
+
# instead of literal "0.0.0.0". Tries mac first (ipconfig getifaddr en0),
|
|
67
|
+
# then linux (hostname -I | awk '{print $1}'). Returns empty on both
|
|
68
|
+
# failures — the caller falls back to 127.0.0.1 so the --lan path
|
|
69
|
+
# degrades to "this computer only" rather than crashing.
|
|
70
|
+
# Per bassclef-upstream#2143 — the prior shape printed 0.0.0.0 which
|
|
71
|
+
# phones cannot dial.
|
|
72
|
+
_local_serve_detect_lan_ip() {
|
|
73
|
+
local ip
|
|
74
|
+
# macOS primary: en0 is the typical Wi-Fi interface
|
|
75
|
+
if command -v ipconfig >/dev/null 2>&1; then
|
|
76
|
+
ip=$(ipconfig getifaddr en0 2>/dev/null || true)
|
|
77
|
+
if [ -n "$ip" ]; then
|
|
78
|
+
echo "$ip"
|
|
79
|
+
return 0
|
|
80
|
+
fi
|
|
81
|
+
# macOS fallback: try en1 (secondary Wi-Fi on some models)
|
|
82
|
+
ip=$(ipconfig getifaddr en1 2>/dev/null || true)
|
|
83
|
+
if [ -n "$ip" ]; then
|
|
84
|
+
echo "$ip"
|
|
85
|
+
return 0
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
# Linux: hostname -I returns space-separated IPs; first is usually primary LAN
|
|
89
|
+
if command -v hostname >/dev/null 2>&1; then
|
|
90
|
+
ip=$(hostname -I 2>/dev/null | awk '{print $1}' || true)
|
|
91
|
+
if [ -n "$ip" ]; then
|
|
92
|
+
echo "$ip"
|
|
93
|
+
return 0
|
|
94
|
+
fi
|
|
95
|
+
fi
|
|
96
|
+
# Fallback: empty — caller uses 127.0.0.1
|
|
97
|
+
return 0
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Parses CLI args. Sets globals BIND_ADDR, DISPLAY_HOST, LAN_WARNING,
|
|
101
|
+
# GALLERY_DIR_PARSED, PORT_HINT_PARSED. Returns 0 on success. Returns
|
|
102
|
+
# non-zero on --help, unknown flag, or missing gallery-dir.
|
|
103
|
+
#
|
|
104
|
+
# BIND_ADDR is what python's http.server --bind sees (127.0.0.1 default,
|
|
105
|
+
# 0.0.0.0 under --lan so it listens on all interfaces).
|
|
106
|
+
# DISPLAY_HOST is what the printed URL + state file carries (127.0.0.1
|
|
107
|
+
# default, detected LAN IP under --lan). Separate so the printed URL is
|
|
108
|
+
# always dialable: 127.0.0.1 for the host, LAN IP for a phone on the
|
|
109
|
+
# same Wi-Fi. Per bassclef-upstream#2143.
|
|
110
|
+
_local_serve_parse_args() {
|
|
111
|
+
BIND_ADDR="127.0.0.1"
|
|
112
|
+
DISPLAY_HOST="127.0.0.1"
|
|
113
|
+
LAN_WARNING=""
|
|
114
|
+
GALLERY_DIR_PARSED=""
|
|
115
|
+
PORT_HINT_PARSED="8000"
|
|
116
|
+
local positional=()
|
|
117
|
+
local arg
|
|
118
|
+
local lan_mode=0
|
|
119
|
+
for arg in "$@"; do
|
|
120
|
+
case "$arg" in
|
|
121
|
+
--lan)
|
|
122
|
+
lan_mode=1
|
|
123
|
+
BIND_ADDR="0.0.0.0"
|
|
124
|
+
LAN_WARNING="WARN: --lan set; any device on this Wi-Fi can open this URL. Unset --lan to bind 127.0.0.1 only."
|
|
125
|
+
;;
|
|
126
|
+
--help|-h)
|
|
127
|
+
_local_serve_print_usage
|
|
128
|
+
return 1
|
|
129
|
+
;;
|
|
130
|
+
--*)
|
|
131
|
+
echo "ERROR: unknown flag: $arg" >&2
|
|
132
|
+
_local_serve_print_usage >&2
|
|
133
|
+
return 2
|
|
134
|
+
;;
|
|
135
|
+
*)
|
|
136
|
+
positional+=("$arg")
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
done
|
|
140
|
+
if [ "$lan_mode" -eq 1 ]; then
|
|
141
|
+
local detected
|
|
142
|
+
detected=$(_local_serve_detect_lan_ip)
|
|
143
|
+
if [ -n "$detected" ]; then
|
|
144
|
+
DISPLAY_HOST="$detected"
|
|
145
|
+
else
|
|
146
|
+
# Detection failed; fall back to 127.0.0.1 so the printed URL is still
|
|
147
|
+
# dialable from the host at least. Warn so the operator knows the
|
|
148
|
+
# phone-preview path won't work.
|
|
149
|
+
DISPLAY_HOST="127.0.0.1"
|
|
150
|
+
LAN_WARNING="${LAN_WARNING}
|
|
151
|
+
WARN: --lan set but LAN IP detection failed (ipconfig / hostname). Printed URL falls back to 127.0.0.1; phone preview will not work."
|
|
152
|
+
fi
|
|
153
|
+
fi
|
|
154
|
+
if [ "${#positional[@]}" -ge 1 ]; then
|
|
155
|
+
GALLERY_DIR_PARSED="${positional[0]}"
|
|
156
|
+
fi
|
|
157
|
+
if [ "${#positional[@]}" -ge 2 ]; then
|
|
158
|
+
PORT_HINT_PARSED="${positional[1]}"
|
|
159
|
+
fi
|
|
160
|
+
if [ -z "$GALLERY_DIR_PARSED" ]; then
|
|
161
|
+
echo "ERROR: gallery-dir required" >&2
|
|
162
|
+
_local_serve_print_usage >&2
|
|
163
|
+
return 2
|
|
164
|
+
fi
|
|
165
|
+
return 0
|
|
166
|
+
}
|
|
34
167
|
|
|
35
|
-
|
|
36
|
-
|
|
168
|
+
# === Test-mode guard — tests source + exercise helpers without running main ===
|
|
169
|
+
if [ "${LOCAL_SERVE_TEST_MODE:-}" = "1" ]; then
|
|
170
|
+
return 0 2>/dev/null || exit 0
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
set -e
|
|
37
174
|
|
|
38
|
-
if
|
|
39
|
-
echo "ERROR: gallery-dir required" >&2
|
|
40
|
-
echo "usage: $0 <gallery-dir> [port-hint]" >&2
|
|
175
|
+
if ! _local_serve_parse_args "$@"; then
|
|
41
176
|
exit 2
|
|
42
177
|
fi
|
|
178
|
+
GALLERY_DIR="$GALLERY_DIR_PARSED"
|
|
179
|
+
PORT_HINT="$PORT_HINT_PARSED"
|
|
180
|
+
|
|
181
|
+
if [ -n "$LAN_WARNING" ]; then
|
|
182
|
+
echo "$LAN_WARNING" >&2
|
|
183
|
+
fi
|
|
43
184
|
|
|
44
185
|
if ! command -v python3 >/dev/null 2>&1; then
|
|
45
186
|
echo "ERROR: python3 not on PATH. Install python3 first." >&2
|
|
@@ -92,7 +233,7 @@ fi
|
|
|
92
233
|
|
|
93
234
|
# Start http.server in background, bound to 127.0.0.1 only (no external exposure)
|
|
94
235
|
LOG_FILE="$STATE_DIR/${GALLERY_SLUG}.log"
|
|
95
|
-
nohup python3 -m http.server "$PORT" --bind
|
|
236
|
+
nohup python3 -m http.server "$PORT" --bind "$BIND_ADDR" --directory "$GALLERY_DIR" \
|
|
96
237
|
> "$LOG_FILE" 2>&1 &
|
|
97
238
|
SERVER_PID=$!
|
|
98
239
|
|
|
@@ -103,7 +244,7 @@ if ! kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
|
103
244
|
exit 1
|
|
104
245
|
fi
|
|
105
246
|
|
|
106
|
-
URL="http
|
|
247
|
+
URL="http://${DISPLAY_HOST}:${PORT}/"
|
|
107
248
|
|
|
108
249
|
# Write state file
|
|
109
250
|
cat > "$STATE_FILE" <<EOF
|
|
@@ -171,6 +171,12 @@
|
|
|
171
171
|
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/git-stash-u-guard.sh",
|
|
172
172
|
"timeout": 5,
|
|
173
173
|
"tier": "lite"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"type": "command",
|
|
177
|
+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/pre-push-shellcheck.sh",
|
|
178
|
+
"timeout": 60,
|
|
179
|
+
"tier": "lite"
|
|
174
180
|
}
|
|
175
181
|
]
|
|
176
182
|
},
|
|
@@ -392,6 +398,12 @@
|
|
|
392
398
|
"timeout": 10,
|
|
393
399
|
"tier": "lite"
|
|
394
400
|
},
|
|
401
|
+
{
|
|
402
|
+
"type": "command",
|
|
403
|
+
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/turn-prose-density-measure.sh",
|
|
404
|
+
"timeout": 10,
|
|
405
|
+
"tier": "lite"
|
|
406
|
+
},
|
|
395
407
|
{
|
|
396
408
|
"type": "command",
|
|
397
409
|
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/reviewer-dispatch-check.sh",
|
|
@@ -34,6 +34,55 @@ 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
|
+
### bassclef-upstream#2096 amendment 3 — pin hard stack rank in /eisenhower output (PATCH, 2026-10-13)
|
|
38
|
+
|
|
39
|
+
- **Change type:** content-change (`.claude/skills/eisenhower/SKILL.md` content_hash shift; new Step 4b section added)
|
|
40
|
+
- **Contracts affected:** `/eisenhower` SKILL body — adds Step 4b emitting cross-repo stack-rank table after per-quadrant tables
|
|
41
|
+
- **Version bump:** PATCH per content-only policy
|
|
42
|
+
- **Rationale:** bassclef-upstream#2096 amendment 3. The operator asked twice in-session for the hard stack rank with a repo column. The amendment pins the four-column shape (Rank · Ticket · Repo · Why this rank) and the Q1 → Q4 row order.
|
|
43
|
+
- **Downstream cure:** nothing required; adopters that invoke `/eisenhower` see the new table automatically next run.
|
|
44
|
+
- **Old shape retired:** nothing retired; this is a pure add.
|
|
45
|
+
|
|
46
|
+
### bassclef-upstream#2110 step 1 — add scripts/update-lite-manifest.sh wrapper + rule amendment (PATCH, 2026-10-13)
|
|
47
|
+
|
|
48
|
+
- **Change type:** content-change (two tier:lite files edited; one new tier:upstream script + test added)
|
|
49
|
+
- **Contracts affected:** `.claude/rules/lite-manifest-schema-change-discipline.md` entry — content_hash shift (added "Ledger-edit-then-regen order" section)
|
|
50
|
+
- **Version bump:** PATCH per content-only policy
|
|
51
|
+
- **Rationale:** bassclef-upstream#2110 — the natural authoring instinct is "regen first, then write ledger explaining the change." That order ships a stale ledger hash in the manifest because the ledger file is itself in the manifest. The wrapper `scripts/update-lite-manifest.sh` forces ledger-edit-then-regen order. Tier 0 tests at `scripts/tests/update-lite-manifest.test.sh` pin 10 cases.
|
|
52
|
+
- **Downstream cure:** nothing required; the wrapper is operator-side authoring convenience. Adopters do not run it. The rule amendment documents the preferred authoring path.
|
|
53
|
+
- **Old shape retired:** nothing retired; this is a pure add.
|
|
54
|
+
|
|
55
|
+
### bassclef-upstream#2157 step 6 — install-written-paths ajv-runtime content shift (v1.17.1 → v1.17.2, 2026-10-10)
|
|
56
|
+
|
|
57
|
+
- **Change type:** content-change (lib/install-written-paths.sh content_hash shift; no entry add/remove)
|
|
58
|
+
- **Contracts affected:** `lib/install-written-paths` entry — content_hash sha256 old `504f4f73...` → new `3c029eb9...`
|
|
59
|
+
- **Version bump:** v1.17.1 → v1.17.2 (PATCH per policy — content_hash change only)
|
|
60
|
+
- **Rationale:** bassclef-upstream#2157 step 6 adds `_iwp_ajv_validate` + `_iwp_schema_path` helpers (73 lines) in `lib/install-written-paths.sh` + extends `install_written_paths_verify` with strict ajv reject + `install_written_paths_register` with post-write advisory warning. All 5 public verbs retain signatures (Parnas information hiding). Reads via `is_install_written_path` stay cheap. Fail-soft when ajv missing.
|
|
61
|
+
- **Downstream cure:** no action for lite adopters. The lib stays backward-compatible — ajv-missing fail-soft keeps adopter machines working without ajv-cli. New verify-side strict reject only fires on explicit `install_written_paths_verify` calls, not on hot-path `is_install_written_path`.
|
|
62
|
+
- **Old shape retired:** nothing retired. PR #2149 CLI init.manifest.json fallback at L250-282 preserved per ADR-031 three-release-cycle rule — the cross-repo contracts registry ledger v1.0.1 entry names the retire schedule.
|
|
63
|
+
- **Refs:** `architecture/decisions/ADR-059-cross-repo-contract-drift-prevention.md`, bassclef-upstream#2157, bassclef-cli#415 (CLOSED via PR #416 SHA 9cf9014). See cross-repo contracts registry ledger v1.0.1 entry for the paired stage flip.
|
|
64
|
+
|
|
65
|
+
### bassclef-upstream v1.9.3 hotfix — manifest_version regression cure (v1.17.0 → v1.17.1, 2026-10-08)
|
|
66
|
+
|
|
67
|
+
- **Change type:** version-field-correction (0 content shift, 0 schema shape change). Prior v1.9.2 release shipped `manifest_version: "0.0.0"` due to a generator fallback bug — chained rebase regens compounded a null read into 0.0.0. cli bundler strict major=1 check rejected the shipped manifest.
|
|
68
|
+
- **Fields:** 449 entries (unchanged). manifest_version field only.
|
|
69
|
+
- **Version bump:** v1.17.0 → v1.17.1 (patch — version-field correction with no content shift; per policy f).
|
|
70
|
+
- **Rationale:** bassclef-cli-63 peer blocker report 2026-10-08 — v1.9.2 shipped `manifest_version: "0.0.0"`; `@thebassclef/lite@1.9.11` (2026-09-15) shipped `manifest_version: "1.6.1"`. Regression traced to commit `d59a3dfe` (PR #2135 prior session). cli bundler at `scripts/prepublish-bundle-substrate.mjs:69` enforces EXPECTED_LITE_MANIFEST_MAJOR=1; rejects v1.9.2.
|
|
71
|
+
- **Downstream cure:** no action for adopters at non-pin. cli bundler now reads a valid major digit; downstream readers that keyed on `manifest_version` get a non-zero value again.
|
|
72
|
+
- **Old shape retired:** nothing retired. v1.9.2's broken shape stays on tag v1.9.2; v1.9.3 supersedes.
|
|
73
|
+
- **Follow-on filed:** regression class caught by Tier 0 Test 50 in `.claude/hooks/tests/generate-lite-manifest.test.sh`. Generator fallback safety guard filed as sister ticket (prevents 0.0.0 from compounding across chained regens again).
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### bassclef-upstream#2140 — generator scans skill-helper subscripts (v1.16.10 → v1.17.0, 2026-10-08)
|
|
77
|
+
|
|
78
|
+
- **Change type:** content-add (1 new lite entry: `.claude/skills/onboard-repo/write-state-marker.sh` as type=script). Generator extended to scan `.claude/skills/*/*.sh` for skill-helper subscripts; emits them as existing type=script (no schema enum change).
|
|
79
|
+
- **Fields:** 448 → 449 entries (+1 at lite tier). Schema shape unchanged. The 2 sibling helpers at `.claude/skills/onboard-repo/` stay at `# tier: standard` so they don't ride into lite.
|
|
80
|
+
- **Version bump:** v1.16.10 → v1.17.0 (minor — adds an entry to entries[] per policy a).
|
|
81
|
+
- **Rationale:** bassclef-upstream#2140 — cold adopter 2026-10-07 ran /onboard-repo at lite tier; Phase 2.3.9 saw `cat: write-state-marker.sh: No such file` because the file was tagged standard and absent from lite manifest. Retag to lite + generator extension so lite adopters receive the helper.
|
|
82
|
+
- **Downstream cure:** no action for adopters at exact-pin. Downstream readers see one additional lite-tier entry under type=script. Adopters that iterate entries[] get the extra entry without any code change.
|
|
83
|
+
- **Old shape retired:** nothing retired. Content addition is additive.
|
|
84
|
+
|
|
85
|
+
|
|
37
86
|
### cli#319 — interpret-input writes intent field (v1.16.9 → v1.16.10, 2026-10-07)
|
|
38
87
|
|
|
39
88
|
- **Change type:** content-change (1 file: `scripts/interpret-input.sh`). Script now emits `intent` field in input-artifact JSON. Prior shape omitted it.
|