@thebassclef/lite 1.3.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lite/.bassclef-source.json +2 -2
- package/dist/lite/.claude/hooks/_lib/wirings.sh +237 -0
- package/dist/lite/.claude/hooks/pre-commit-manifest-autoregen.sh +187 -0
- package/dist/lite/.claude/hooks/session-reflection.d/08-settings-drift.sh +66 -6
- package/dist/lite/.claude/hooks/session-reflection.d/20-artifact-staleness.sh +25 -5
- package/dist/lite/.claude/hooks/session-reflection.d/30-metrics-staleness.sh +11 -0
- package/dist/lite/.claude/hooks/session-reflection.d/60-deferred-actions.sh +2 -1
- package/dist/lite/.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh +20 -0
- package/dist/lite/.claude/hooks/session-reflection.d/tests/20-artifact-staleness.test.sh +89 -0
- package/dist/lite/.claude/hooks/session-reflection.sh +12 -1
- package/dist/lite/.claude/luminaries/david-farley.md +115 -0
- package/dist/lite/.claude/luminaries/jez-humble.md +124 -0
- package/dist/lite/.claude/luminaries/martin-fowler.md +18 -0
- package/dist/lite/.claude/skills/longrun/SKILL.md +51 -0
- package/dist/lite/.claude/skills/onboard-repo/SKILL.md +39 -11
- package/dist/lite/.claude/skills/provision-deploy-host/SKILL.md +2 -2
- package/dist/lite/lib/ancestor-claude-check.sh +101 -0
- package/dist/lite/lib/fixture-builder.sh +324 -0
- package/dist/lite/lib/workflow-metrics.sh +166 -0
- package/dist/lite/presence/install/bassclef-configs.template.jsonc +76 -0
- package/dist/lite/presence/install/bassclef-sync.template.sh +7 -4
- package/dist/lite/scripts/generate-lite-manifest.sh +151 -1
- package/dist/lite/scripts/workflow-metrics-query.sh +57 -0
- package/dist/lite/standards/lite-manifest-schema-changes.md +24 -0
- package/dist/lite/standards/lite-manifest.json +79 -68
- package/package.json +1 -1
- package/dist/lite/.claude/skills/journal-export/SKILL.md +0 -293
- package/dist/lite/.claude/skills/release/SKILL.md +0 -311
|
@@ -2178,10 +2178,13 @@ echo ""
|
|
|
2178
2178
|
# === 6. Boot check — only report what's missing ===
|
|
2179
2179
|
MISSING=""
|
|
2180
2180
|
|
|
2181
|
-
# Google service account (needed for
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2181
|
+
# Google service account (needed for journal → Google Docs)
|
|
2182
|
+
# Ship 1 (#1816): env var lookup; unset = feature disabled.
|
|
2183
|
+
# Operator sets BASSCLEF_GCLOUD_KEY in their shell profile pointing at their
|
|
2184
|
+
# service-account JSON. Adopters without a Google Docs pipeline leave it unset.
|
|
2185
|
+
SA_KEY="${BASSCLEF_GCLOUD_KEY:-}"
|
|
2186
|
+
if [ -n "$SA_KEY" ] && [ ! -f "$SA_KEY" ]; then
|
|
2187
|
+
MISSING="${MISSING}\n- Google Docs service account key missing at \$BASSCLEF_GCLOUD_KEY (needed for /journal → Google Doc push)"
|
|
2185
2188
|
fi
|
|
2186
2189
|
|
|
2187
2190
|
# gh CLI auth (needed for /promote, issue creation)
|
|
@@ -30,7 +30,11 @@
|
|
|
30
30
|
|
|
31
31
|
set -euo pipefail
|
|
32
32
|
|
|
33
|
-
MANIFEST_VERSION
|
|
33
|
+
# Bug 2 fix (#1829): MANIFEST_VERSION was hardcoded here; dry-run always
|
|
34
|
+
# emitted the compile-time value regardless of on-disk manifest state,
|
|
35
|
+
# so the pre-commit auto-regen hook saw phantom version drift on every
|
|
36
|
+
# commit and bumped needlessly. Now resolved dynamically from the on-disk
|
|
37
|
+
# manifest AFTER OUTPUT_PATH is set (see below).
|
|
34
38
|
|
|
35
39
|
# --- arg parse ---
|
|
36
40
|
DRY_RUN=0
|
|
@@ -94,6 +98,16 @@ if [[ -z "$OUTPUT_PATH" ]]; then
|
|
|
94
98
|
OUTPUT_PATH="${REPO_ROOT}/${TARGET_TIER}-manifest.json"
|
|
95
99
|
fi
|
|
96
100
|
|
|
101
|
+
# --- resolve MANIFEST_VERSION dynamically (Bug 2 fix per #1829) ---
|
|
102
|
+
# Read from on-disk manifest so dry-run + write emit the SAME version.
|
|
103
|
+
# Callers that need to bump the version (pre-commit auto-regen hook)
|
|
104
|
+
# apply the bump AFTER regen via jq. Default 0.0.0 when no manifest exists.
|
|
105
|
+
if [[ -f "$OUTPUT_PATH" ]]; then
|
|
106
|
+
MANIFEST_VERSION=$(jq -r '.manifest_version // "0.0.0"' "$OUTPUT_PATH" 2>/dev/null || echo "0.0.0")
|
|
107
|
+
else
|
|
108
|
+
MANIFEST_VERSION="0.0.0"
|
|
109
|
+
fi
|
|
110
|
+
|
|
97
111
|
# --- generation metadata ---
|
|
98
112
|
GENERATED_AT="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
|
|
99
113
|
UPSTREAM_COMMIT="$(cd "$REPO_ROOT" && git rev-parse HEAD 2>/dev/null || echo '0000000000000000000000000000000000000000')"
|
|
@@ -140,6 +154,49 @@ count_hook_tier_declarations() {
|
|
|
140
154
|
|| true
|
|
141
155
|
}
|
|
142
156
|
|
|
157
|
+
# Extract install-class from bash hook file # install-class: header.
|
|
158
|
+
# Ship 1 (#1825): the install-class boundary Gate B reads this per hook
|
|
159
|
+
# to filter operator-scope files from adopter bundles. Values per
|
|
160
|
+
# standards/hook-install-class.md — operator | project | dual.
|
|
161
|
+
# Missing header — grace-window default is "dual" per docs/risk-ledgers/
|
|
162
|
+
# 2026-09-20-ship-1-install-class-boundary.md pre-mortem N2.
|
|
163
|
+
extract_hook_install_class() {
|
|
164
|
+
local val
|
|
165
|
+
val=$(grep -m1 -E '^#[[:space:]]*install-class:[[:space:]]' "$1" 2>/dev/null \
|
|
166
|
+
| sed -E 's/^#[[:space:]]*install-class:[[:space:]]*//' \
|
|
167
|
+
| sed -E 's/[[:space:]]*$//' \
|
|
168
|
+
|| true)
|
|
169
|
+
# Grace-window default per pre-mortem N2 fold — missing header treated as dual.
|
|
170
|
+
echo "${val:-dual}"
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# Gate B — install-class admission check.
|
|
174
|
+
# Returns 0 (admit) when the file belongs in the current TARGET_TIER's bundle
|
|
175
|
+
# based on install-class alone. Returns 1 (reject) when operator-scope in an
|
|
176
|
+
# adopter target. Ship 1 (#1825, #1827, #1828) closes the boundary here.
|
|
177
|
+
check_install_class_admission() {
|
|
178
|
+
local install_class="$1"
|
|
179
|
+
local surface_type="$2"
|
|
180
|
+
# Only enforce on hook + script + presence-template + lib surfaces —
|
|
181
|
+
# skill + rule + luminary + agent + standard + adr do not carry
|
|
182
|
+
# install-class semantics (they are content, not wiring).
|
|
183
|
+
case "$surface_type" in
|
|
184
|
+
hook|script|lib|presence-template) ;;
|
|
185
|
+
*) return 0 ;;
|
|
186
|
+
esac
|
|
187
|
+
# Operator-class always excluded from adopter bundles.
|
|
188
|
+
# Ship 1 grace window (through 2026-10-31 per ADR-031) — allow override
|
|
189
|
+
# for legacy files during rollout via SKIP_INSTALL_CLASS_FILTER.
|
|
190
|
+
if [ "${SKIP_INSTALL_CLASS_FILTER:-0}" = "1" ]; then
|
|
191
|
+
return 0
|
|
192
|
+
fi
|
|
193
|
+
case "$install_class" in
|
|
194
|
+
operator) return 1 ;;
|
|
195
|
+
project|dual) return 0 ;;
|
|
196
|
+
*) return 0 ;;
|
|
197
|
+
esac
|
|
198
|
+
}
|
|
199
|
+
|
|
143
200
|
# Normalize `—` YAML escape to literal em-dash character. Closes
|
|
144
201
|
# bassclef-upstream#1548 — YAML frontmatter with double-quoted strings can
|
|
145
202
|
# carry `—` as a 6-char literal; jq preserves it as `\\u2014` in JSON
|
|
@@ -313,6 +370,21 @@ emit_entries() {
|
|
|
313
370
|
*) continue ;;
|
|
314
371
|
esac
|
|
315
372
|
|
|
373
|
+
# Ship 1 (#1825) Gate B — install-class filter.
|
|
374
|
+
# Excludes operator-scope files from adopter bundles.
|
|
375
|
+
# Only fires on wiring-carrying surface types (hook, script, lib,
|
|
376
|
+
# presence-template). Content surfaces (skill, rule, luminary, agent,
|
|
377
|
+
# standard, adr) pass through.
|
|
378
|
+
case "$surface_type" in
|
|
379
|
+
hook|script|lib|presence-template)
|
|
380
|
+
local install_class
|
|
381
|
+
install_class=$(extract_hook_install_class "$f" || echo "dual")
|
|
382
|
+
if ! check_install_class_admission "$install_class" "$surface_type"; then
|
|
383
|
+
continue
|
|
384
|
+
fi
|
|
385
|
+
;;
|
|
386
|
+
esac
|
|
387
|
+
|
|
316
388
|
case "$slug_from" in
|
|
317
389
|
dirname)
|
|
318
390
|
slug=$(basename "$(dirname "$f")")
|
|
@@ -441,6 +513,13 @@ while IFS= read -r f; do
|
|
|
441
513
|
PRESENCE_TEMPLATE_MD_FILES+=("$f")
|
|
442
514
|
done < <(find "$REPO_ROOT/presence/install" -maxdepth 1 -type f -name '*.md' 2>/dev/null | sort)
|
|
443
515
|
|
|
516
|
+
# Presence templates (jsonc) — Ship 1 (bassclef-cli#104) — configs template
|
|
517
|
+
# ships so `bassclef init` can copy it to adopter's `.claude/bassclef-configs.jsonc`.
|
|
518
|
+
PRESENCE_TEMPLATE_JSONC_FILES=()
|
|
519
|
+
while IFS= read -r f; do
|
|
520
|
+
PRESENCE_TEMPLATE_JSONC_FILES+=("$f")
|
|
521
|
+
done < <(find "$REPO_ROOT/presence/install" -maxdepth 1 -type f -name '*.jsonc' 2>/dev/null | sort)
|
|
522
|
+
|
|
444
523
|
# Templates (md) — per #1392 Shape 3; chronicle-template + iteration-goal etc adopters copy
|
|
445
524
|
TEMPLATE_FILES=()
|
|
446
525
|
while IFS= read -r f; do
|
|
@@ -556,6 +635,9 @@ ENTRIES_JSON=$(
|
|
|
556
635
|
if [[ ${#PRESENCE_TEMPLATE_MD_FILES[@]} -gt 0 ]]; then
|
|
557
636
|
emit_entries "presence-template" extract_yaml_tier extract_yaml_description basename "${PRESENCE_TEMPLATE_MD_FILES[@]}"
|
|
558
637
|
fi
|
|
638
|
+
if [[ ${#PRESENCE_TEMPLATE_JSONC_FILES[@]} -gt 0 ]]; then
|
|
639
|
+
emit_entries "presence-template" extract_json_tier extract_json_description basename "${PRESENCE_TEMPLATE_JSONC_FILES[@]}"
|
|
640
|
+
fi
|
|
559
641
|
if [[ ${#TEMPLATE_FILES[@]} -gt 0 ]]; then
|
|
560
642
|
emit_entries "template" extract_yaml_tier extract_yaml_description basename "${TEMPLATE_FILES[@]}"
|
|
561
643
|
fi
|
|
@@ -644,3 +726,71 @@ else
|
|
|
644
726
|
echo "$MANIFEST_JSON" > "$OUTPUT_PATH"
|
|
645
727
|
echo "Wrote $OUTPUT_PATH ($ENTRY_COUNT entries; commit ${UPSTREAM_COMMIT:0:7})" >&2
|
|
646
728
|
fi
|
|
729
|
+
|
|
730
|
+
# =============================================================
|
|
731
|
+
# Ship 1 (#1827) — Gate C: wiring/file symmetry check
|
|
732
|
+
# =============================================================
|
|
733
|
+
# Post-emit — cross-reference hooks wired in the adopter settings template
|
|
734
|
+
# against hooks emitted in the manifest. Any wiring entry without a
|
|
735
|
+
# matching file entry is a "dead-wired hook" (per #1827). Emits WARNING
|
|
736
|
+
# in V1 (ADVISORY per ADR-031 grace window); flips to BLOCK in V2 after
|
|
737
|
+
# one calibration cycle.
|
|
738
|
+
#
|
|
739
|
+
# Per @luminary linus-torvalds — adopter contract at the boundary.
|
|
740
|
+
# Per @luminary saltzer-schroeder — complete mediation.
|
|
741
|
+
# Per @luminary michael-nygard — stability pattern (fail-visible not fail-silent).
|
|
742
|
+
#
|
|
743
|
+
# Only fires for TARGET_TIER=lite. Other tiers have their own settings templates
|
|
744
|
+
# tracked in follow-on work. Skips when settings template absent (adopter has
|
|
745
|
+
# not published it yet — early Ship 1 dev state).
|
|
746
|
+
if [ "$TARGET_TIER" = "lite" ] && [ "${SKIP_MANIFEST_SYMMETRY:-0}" != "1" ]; then
|
|
747
|
+
SETTINGS_TEMPLATE="$REPO_ROOT/presence/install/public-bassclef-settings.template.json"
|
|
748
|
+
ALLOWLIST="$REPO_ROOT/scripts/generate-lite-manifest-symmetry-allowlist.txt"
|
|
749
|
+
if [ -f "$SETTINGS_TEMPLATE" ] && command -v jq >/dev/null 2>&1; then
|
|
750
|
+
# Extract hook basenames wired in settings template.
|
|
751
|
+
WIRED_TMP=$(mktemp -t bassclef-wired.XXXXXX)
|
|
752
|
+
MANIFEST_HOOKS_TMP=$(mktemp -t bassclef-manifest-hooks.XXXXXX)
|
|
753
|
+
ALLOWLIST_TMP=$(mktemp -t bassclef-allowlist.XXXXXX)
|
|
754
|
+
trap 'rm -f "$WIRED_TMP" "$MANIFEST_HOOKS_TMP" "$ALLOWLIST_TMP"' EXIT
|
|
755
|
+
|
|
756
|
+
jq -r '.hooks | to_entries[] | .value[] | .hooks[] | .command' "$SETTINGS_TEMPLATE" 2>/dev/null \
|
|
757
|
+
| grep -oE '[a-zA-Z0-9_-]+\.sh' | sort -u > "$WIRED_TMP"
|
|
758
|
+
|
|
759
|
+
# Extract hook slugs from the manifest we just emitted.
|
|
760
|
+
if [[ "$DRY_RUN" == "1" ]]; then
|
|
761
|
+
echo "$MANIFEST_JSON" | jq -r '.entries[] | select(.type=="hook") | .slug + ".sh"' 2>/dev/null | sort -u > "$MANIFEST_HOOKS_TMP"
|
|
762
|
+
else
|
|
763
|
+
jq -r '.entries[] | select(.type=="hook") | .slug + ".sh"' "$OUTPUT_PATH" 2>/dev/null | sort -u > "$MANIFEST_HOOKS_TMP"
|
|
764
|
+
fi
|
|
765
|
+
|
|
766
|
+
# Load allowlist (empty file OK — grep -v exits 1 when all lines match; guard for set -e).
|
|
767
|
+
if [ -f "$ALLOWLIST" ]; then
|
|
768
|
+
grep -vE '^\s*#|^\s*$' "$ALLOWLIST" 2>/dev/null > "$ALLOWLIST_TMP" || : > "$ALLOWLIST_TMP"
|
|
769
|
+
sort -u "$ALLOWLIST_TMP" -o "$ALLOWLIST_TMP" 2>/dev/null || true
|
|
770
|
+
else
|
|
771
|
+
: > "$ALLOWLIST_TMP"
|
|
772
|
+
fi
|
|
773
|
+
|
|
774
|
+
# Wired minus manifest, minus allowlist.
|
|
775
|
+
DEAD_WIRED=$(comm -23 "$WIRED_TMP" "$MANIFEST_HOOKS_TMP" | comm -23 - "$ALLOWLIST_TMP" || true)
|
|
776
|
+
if [ -z "$DEAD_WIRED" ]; then
|
|
777
|
+
DEAD_COUNT=0
|
|
778
|
+
else
|
|
779
|
+
DEAD_COUNT=$(echo "$DEAD_WIRED" | wc -l | tr -d ' ')
|
|
780
|
+
fi
|
|
781
|
+
|
|
782
|
+
if [ "$DEAD_COUNT" -gt 0 ]; then
|
|
783
|
+
echo "" >&2
|
|
784
|
+
echo "generate-lite-manifest: SYMMETRY WARNING — $DEAD_COUNT hook(s) wired in settings template but absent from manifest:" >&2
|
|
785
|
+
echo "$DEAD_WIRED" | sed 's/^/ - /' >&2
|
|
786
|
+
echo "" >&2
|
|
787
|
+
echo "Resolution paths:" >&2
|
|
788
|
+
echo " 1. Retag source hook so it enters lite (tier: lite + install-class: project or dual)" >&2
|
|
789
|
+
echo " 2. Remove the wiring entry from $SETTINGS_TEMPLATE" >&2
|
|
790
|
+
echo " 3. Add the hook basename to $ALLOWLIST (grace window through 2026-10-31)" >&2
|
|
791
|
+
echo "" >&2
|
|
792
|
+
echo "Per .claude/rules/we-dont-break-adopters.md (ADR-031). SKIP_MANIFEST_SYMMETRY=1 bypasses one call." >&2
|
|
793
|
+
# V1 ADVISORY — exit 0 with warning. V2 flips to exit 4 (BLOCK).
|
|
794
|
+
fi
|
|
795
|
+
fi
|
|
796
|
+
fi
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# tier: lite
|
|
3
|
+
# CLI wrapper for lib/workflow-metrics.sh — Module B4 query helper.
|
|
4
|
+
#
|
|
5
|
+
# Used at Phase checkpoints per canvas activity diagram to sample the
|
|
6
|
+
# median bassclef-pr-ci run duration over the last N days.
|
|
7
|
+
#
|
|
8
|
+
# Closes sunj-labs/bassclef-upstream#1307 (parent epic #1750).
|
|
9
|
+
#
|
|
10
|
+
# Usage:
|
|
11
|
+
# scripts/workflow-metrics-query.sh # list all entries
|
|
12
|
+
# scripts/workflow-metrics-query.sh --workflow <name> # filter by workflow
|
|
13
|
+
# scripts/workflow-metrics-query.sh --median # emit median
|
|
14
|
+
# scripts/workflow-metrics-query.sh --workflow <name> --median # median for one workflow
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
WORKFLOW=""
|
|
19
|
+
MEDIAN=0
|
|
20
|
+
STORE_DIR=""
|
|
21
|
+
|
|
22
|
+
while [[ $# -gt 0 ]]; do
|
|
23
|
+
case "$1" in
|
|
24
|
+
--workflow) WORKFLOW="${2:-}"; shift 2 ;;
|
|
25
|
+
--median) MEDIAN=1; shift ;;
|
|
26
|
+
--store-dir) STORE_DIR="${2:-}"; shift 2 ;;
|
|
27
|
+
-h|--help)
|
|
28
|
+
grep -E '^# ' "$0" | sed 's/^# \?//'
|
|
29
|
+
exit 0
|
|
30
|
+
;;
|
|
31
|
+
*)
|
|
32
|
+
echo "unknown arg: $1" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
;;
|
|
35
|
+
esac
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")
|
|
39
|
+
LIB="$REPO_ROOT/lib/workflow-metrics.sh"
|
|
40
|
+
|
|
41
|
+
if [ ! -f "$LIB" ]; then
|
|
42
|
+
echo "workflow-metrics-query: lib not found at $LIB" >&2
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# shellcheck source=/dev/null
|
|
47
|
+
source "$LIB"
|
|
48
|
+
|
|
49
|
+
if [ -z "$STORE_DIR" ]; then
|
|
50
|
+
STORE_DIR=$(_workflow_metrics_default_store)
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
if [ "$MEDIAN" = "1" ]; then
|
|
54
|
+
compute_median "$STORE_DIR" "$WORKFLOW"
|
|
55
|
+
else
|
|
56
|
+
query_metrics "$STORE_DIR" "$WORKFLOW"
|
|
57
|
+
fi
|
|
@@ -34,6 +34,30 @@ 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
|
+
### Ship 1 — install-class boundary + retag rollout (v1.8.7 → v1.9.0, 2026-09-20)
|
|
38
|
+
|
|
39
|
+
- **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)
|
|
40
|
+
- **Fields:** none changed at manifest schema layer. Emission behavior extends.
|
|
41
|
+
- **Version bump:** v1.8.7 → v1.9.0 (MINOR; entries removed + new emission surface + generator behavior extended).
|
|
42
|
+
- **Rationale:** bassclef-upstream#1825 + #1827 + #1824 + #1816 + #1828 + #1728. Five sisters from the cli 1.2.1 smoke and one coordinator from the cli 1.1.1 smoke. Generator gains three gates — tier filter, install-class filter, wiring/file symmetry. Adopters at cli 1.2.x stop seeing PreToolUse errors on every bash tool call once cli picks up.
|
|
43
|
+
- **Retagged out of lite (drop from adopter bundle):**
|
|
44
|
+
- the `/release` skill (substrate concern; operator-only)
|
|
45
|
+
- the `/journal-export` skill (substrate concern; operator-only)
|
|
46
|
+
- the operator sync hook (`install-class: operator`; adopters use the dispatcher)
|
|
47
|
+
- **Added to lite (new adopter file):**
|
|
48
|
+
- `presence/install/bassclef-configs.template.jsonc` — `bassclef init` copies to `.claude/bassclef-configs.jsonc`
|
|
49
|
+
- **Wiring cleanup:** 33 dead-wired hook entries pruned from `presence/install/public-bassclef-settings.template.json`. Each named a hook whose source did not ship in the lite bundle (mostly `tier: standard` hooks). PreToolUse errors on every bash tool call resolve.
|
|
50
|
+
- **Path sanitization:** 27 hardcoded `~/src/sunj-labs/bassclef` occurrences in 2 skill bodies replaced with `${BASSCLEF_DIR:-$CLAUDE_PROJECT_DIR}` pattern. 3 `sunjay-google-ops` gcloud path leaks replaced with `${BASSCLEF_GCLOUD_KEY:-}` env var lookup.
|
|
51
|
+
- **New generator gates:**
|
|
52
|
+
- Gate A — tier filter (strict; upstream/archive/unknown never enter lite)
|
|
53
|
+
- Gate B — install-class filter (operator scope excluded from adopter bundles)
|
|
54
|
+
- Gate C — wiring/file symmetry (ADVISORY V1 per ADR-031 grace window; flip to BLOCK V2)
|
|
55
|
+
- Allowlist file `scripts/generate-lite-manifest-symmetry-allowlist.txt` grants grace exceptions during rollout
|
|
56
|
+
- Overrides: `SKIP_INSTALL_CLASS_FILTER=1`, `SKIP_MANIFEST_SYMMETRY=1`
|
|
57
|
+
- **Downstream cure:** bassclef-cli picks up on next 1.2.x publish. Fresh `bassclef init` on cli 1.2.x sees zero PreToolUse errors, gets a copy of `bassclef-configs.template.jsonc` at `.claude/bassclef-configs.jsonc`, and has `/onboard-repo` with the new top-up path.
|
|
58
|
+
- **Old shape retired:** dead-wired hook entries in the adopter settings template. Adopters who ran cli 1.2.1 still have those entries in their `.claude/settings.json` locally; the sync run picks up the pruned template.
|
|
59
|
+
- **Closes:** #1825, #1827, #1824, #1816, #1828, #1728 upstream; delivers bassclef-cli#101, #104 (new); rides delivery of cli#105, #106, #108, #102, #107 (already cured upstream). cli#103 stays cli-side per cli#96.
|
|
60
|
+
|
|
37
61
|
### Goal 2026-09-17c — one tier declaration per file (v1.8.1 → v1.8.2, 2026-09-17)
|
|
38
62
|
|
|
39
63
|
- **Change type:** content-change (27 content hashes; no entries added or removed)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"tier": "lite",
|
|
3
|
-
"manifest_version": "1.
|
|
4
|
-
"generated_at": "2026-09-
|
|
3
|
+
"manifest_version": "1.9.1",
|
|
4
|
+
"generated_at": "2026-09-21T00:38:33Z",
|
|
5
5
|
"entries": [
|
|
6
6
|
{
|
|
7
7
|
"slug": "029-release-pipeline",
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"type": "hook",
|
|
105
105
|
"path": ".claude/hooks/session-reflection.d/08-settings-drift.sh",
|
|
106
106
|
"tier": "lite",
|
|
107
|
-
"content_hash": "sha256:
|
|
107
|
+
"content_hash": "sha256:8c2884630f16301023b943b08f8e12b17eb1d7ea6e04bec838198dca2ec0ba05",
|
|
108
108
|
"description": "Drift detector — fires at every SessionStart via session-reflection.sh."
|
|
109
109
|
},
|
|
110
110
|
{
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"type": "hook",
|
|
137
137
|
"path": ".claude/hooks/session-reflection.d/20-artifact-staleness.sh",
|
|
138
138
|
"tier": "lite",
|
|
139
|
-
"content_hash": "sha256:
|
|
139
|
+
"content_hash": "sha256:24d1c0513b88bde625ab0bdbd7e4bd6678cdfc47ba76900bc06e3fbfe543f24c",
|
|
140
140
|
"description": "Artifact-staleness checks: chronicle, danger-mode summary,"
|
|
141
141
|
},
|
|
142
142
|
{
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"type": "hook",
|
|
145
145
|
"path": ".claude/hooks/session-reflection.d/30-metrics-staleness.sh",
|
|
146
146
|
"tier": "lite",
|
|
147
|
-
"content_hash": "sha256:
|
|
147
|
+
"content_hash": "sha256:a4b2f436c218c15230c126fa2f2748fca36cdf9778185cab90a8aac4a6416f41",
|
|
148
148
|
"description": "Metrics-staleness check: version tags, iteration closeouts, metrics"
|
|
149
149
|
},
|
|
150
150
|
{
|
|
@@ -208,7 +208,7 @@
|
|
|
208
208
|
"type": "hook",
|
|
209
209
|
"path": ".claude/hooks/session-reflection.d/60-deferred-actions.sh",
|
|
210
210
|
"tier": "lite",
|
|
211
|
-
"content_hash": "sha256:
|
|
211
|
+
"content_hash": "sha256:ae167ab6b1626b9155a0539618678ca7a08d1f619cb054f94476df3ad9f7dff9",
|
|
212
212
|
"description": "Deferred-actions scan: enumerate docs/deferred-actions/*.md, detect current"
|
|
213
213
|
},
|
|
214
214
|
{
|
|
@@ -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:
|
|
235
|
+
"content_hash": "sha256:9f20ebd080a1a7364fe6e6c16266547b56b95c820297310cdd5be559852bab5f",
|
|
236
236
|
"description": "Hook heartbeat check — reads standards/hook-cadence.json, calls"
|
|
237
237
|
},
|
|
238
238
|
{
|
|
@@ -339,14 +339,6 @@
|
|
|
339
339
|
"content_hash": "sha256:6981fedc02dc0b683db7872519e06bd16b68fd346a2e566a7e8503f28822db10",
|
|
340
340
|
"description": "bassclef-source-config-validate.sh — PreToolUse hook validating"
|
|
341
341
|
},
|
|
342
|
-
{
|
|
343
|
-
"slug": "bassclef-sync",
|
|
344
|
-
"type": "hook",
|
|
345
|
-
"path": ".claude/hooks/bassclef-sync.sh",
|
|
346
|
-
"tier": "lite",
|
|
347
|
-
"content_hash": "sha256:03c813d942e42a8a4a37744e3cb14219fa4364ce18e2269957dc3a2f954fa983",
|
|
348
|
-
"description": "Bassclef Substrate Sync — fires on SessionStart."
|
|
349
|
-
},
|
|
350
342
|
{
|
|
351
343
|
"slug": "bet-doc-gate",
|
|
352
344
|
"type": "hook",
|
|
@@ -547,6 +539,14 @@
|
|
|
547
539
|
"content_hash": "sha256:38665938cb3bac6d249d94b814cc3f43600456abcbb045bff5a5d0d0128a7cbb",
|
|
548
540
|
"description": "PreToolUse: Bash"
|
|
549
541
|
},
|
|
542
|
+
{
|
|
543
|
+
"slug": "pre-commit-manifest-autoregen",
|
|
544
|
+
"type": "hook",
|
|
545
|
+
"path": ".claude/hooks/pre-commit-manifest-autoregen.sh",
|
|
546
|
+
"tier": "lite",
|
|
547
|
+
"content_hash": "sha256:34dc76e61307d79da11bb38460823a8945a144f322ea2cf74b0cbfac75118ec2",
|
|
548
|
+
"description": "PreToolUse: Bash"
|
|
549
|
+
},
|
|
550
550
|
{
|
|
551
551
|
"slug": "pre-gh-pr-body-scrub",
|
|
552
552
|
"type": "hook",
|
|
@@ -592,7 +592,7 @@
|
|
|
592
592
|
"type": "hook",
|
|
593
593
|
"path": ".claude/hooks/session-reflection.sh",
|
|
594
594
|
"tier": "lite",
|
|
595
|
-
"content_hash": "sha256:
|
|
595
|
+
"content_hash": "sha256:ece32cd8261bafe4597563aa18237b504bba335c0a1e8d94e1d8d69f4a8e97ae",
|
|
596
596
|
"description": "Session Start hook coordinator. Injects reflection prompt and iterates"
|
|
597
597
|
},
|
|
598
598
|
{
|
|
@@ -699,6 +699,22 @@
|
|
|
699
699
|
"content_hash": "sha256:867d05c8da773e8aef3d077ec7c171d8e9a208b579596f77dd73e18cc8fcf2e2",
|
|
700
700
|
"description": "whereami-utc-gate.sh — PreToolUse hook that BLOCKs Edit|Write|MultiEdit"
|
|
701
701
|
},
|
|
702
|
+
{
|
|
703
|
+
"slug": "wirings",
|
|
704
|
+
"type": "hook",
|
|
705
|
+
"path": ".claude/hooks/_lib/wirings.sh",
|
|
706
|
+
"tier": "lite",
|
|
707
|
+
"content_hash": "sha256:65fb14b5c7b4a919516c96f4587b492d5eb3bcf6f939bbc7c1809205de49498d",
|
|
708
|
+
"description": "Shared accessor library for hook-wiring inspection."
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"slug": "ancestor-claude-check",
|
|
712
|
+
"type": "lib",
|
|
713
|
+
"path": "lib/ancestor-claude-check.sh",
|
|
714
|
+
"tier": "lite",
|
|
715
|
+
"content_hash": "sha256:f84c7b57ae28ef15b0c4c138ee4781030e04e7bb858ff0c53a80a538672d64dd",
|
|
716
|
+
"description": "ancestor-claude-check.sh — walks up from a starting directory to $HOME"
|
|
717
|
+
},
|
|
702
718
|
{
|
|
703
719
|
"slug": "bassclef-dir-resolver",
|
|
704
720
|
"type": "lib",
|
|
@@ -752,7 +768,7 @@
|
|
|
752
768
|
"type": "lib",
|
|
753
769
|
"path": "lib/fixture-builder.sh",
|
|
754
770
|
"tier": "lite",
|
|
755
|
-
"content_hash": "sha256:
|
|
771
|
+
"content_hash": "sha256:5831bcd49c162ec131cf14d402150821bd8f623e87eb3c1bcdc545fc701aaefd",
|
|
756
772
|
"description": "Deep module for adopter-environment fixtures used by bassclef Tier 0 tests."
|
|
757
773
|
},
|
|
758
774
|
{
|
|
@@ -899,6 +915,14 @@
|
|
|
899
915
|
"content_hash": "sha256:7ee5cc3c7372ca6aef3c81f614ec119ffed8874e00a78d441ce8d0304c7b6308",
|
|
900
916
|
"description": "lib/tier-dependency-audit.sh"
|
|
901
917
|
},
|
|
918
|
+
{
|
|
919
|
+
"slug": "workflow-metrics",
|
|
920
|
+
"type": "lib",
|
|
921
|
+
"path": "lib/workflow-metrics.sh",
|
|
922
|
+
"tier": "lite",
|
|
923
|
+
"content_hash": "sha256:4615d673185021f484887b6a674b08f209e8f93db195189f77aff58c618ccf3e",
|
|
924
|
+
"description": "Workflow metrics measurement library — Module B4 per"
|
|
925
|
+
},
|
|
902
926
|
{
|
|
903
927
|
"slug": "alan-cooper",
|
|
904
928
|
"type": "luminary",
|
|
@@ -971,6 +995,14 @@
|
|
|
971
995
|
"content_hash": "sha256:ec2bb153111b28d5f505825f107fb0ac5da354a4cc3a6a474e1d1b153c81eafb",
|
|
972
996
|
"description": "\\\"The whole idea was to imagine what it's like to be inside someone else's head."
|
|
973
997
|
},
|
|
998
|
+
{
|
|
999
|
+
"slug": "david-farley",
|
|
1000
|
+
"type": "luminary",
|
|
1001
|
+
"path": ".claude/luminaries/david-farley.md",
|
|
1002
|
+
"tier": "lite",
|
|
1003
|
+
"content_hash": "sha256:db45f22a2e893137ad0a09ed7a090dc145b3e92dd0c3a5db718e63305921ca91",
|
|
1004
|
+
"description": "Continuous Delivery co-author; deployment pipeline mechanics; author of Modern Software Engineering."
|
|
1005
|
+
},
|
|
974
1006
|
{
|
|
975
1007
|
"slug": "david-ogilvy",
|
|
976
1008
|
"type": "luminary",
|
|
@@ -1067,6 +1099,14 @@
|
|
|
1067
1099
|
"content_hash": "sha256:8275c70d25fb8e8acad9dc68ade399993d5f1432ae82449fe14db8533342fd70",
|
|
1068
1100
|
"description": "\\\"Every user experience has five planes: strategy, scope, structure, skeleton, surface."
|
|
1069
1101
|
},
|
|
1102
|
+
{
|
|
1103
|
+
"slug": "jez-humble",
|
|
1104
|
+
"type": "luminary",
|
|
1105
|
+
"path": ".claude/luminaries/jez-humble.md",
|
|
1106
|
+
"tier": "lite",
|
|
1107
|
+
"content_hash": "sha256:312d4e5cbf21824a50f120c9f7b54b30e00afb4b33782537eda67500269fb7f3",
|
|
1108
|
+
"description": "Continuous Delivery co-author; deployment pipeline framework; DORA metrics researcher."
|
|
1109
|
+
},
|
|
1070
1110
|
{
|
|
1071
1111
|
"slug": "john-ousterhout",
|
|
1072
1112
|
"type": "luminary",
|
|
@@ -1128,7 +1168,7 @@
|
|
|
1128
1168
|
"type": "luminary",
|
|
1129
1169
|
"path": ".claude/luminaries/martin-fowler.md",
|
|
1130
1170
|
"tier": "lite",
|
|
1131
|
-
"content_hash": "sha256:
|
|
1171
|
+
"content_hash": "sha256:c81089dbc3aaeb9d67a91cf19517571452ecc6505fe6ffd065e4029698ae39ec",
|
|
1132
1172
|
"description": "\\\"Any fool can write code that a computer can understand."
|
|
1133
1173
|
},
|
|
1134
1174
|
{
|
|
@@ -1227,6 +1267,13 @@
|
|
|
1227
1267
|
"content_hash": "sha256:9b5d51d106b5f4398c15c1412c781b81f2cde55fecc294c120479a06b8de92a9",
|
|
1228
1268
|
"description": "\\\"A bad system will beat a good person every time.\\\""
|
|
1229
1269
|
},
|
|
1270
|
+
{
|
|
1271
|
+
"slug": "bassclef-configs-template-jsonc",
|
|
1272
|
+
"type": "presence-template",
|
|
1273
|
+
"path": "presence/install/bassclef-configs.template.jsonc",
|
|
1274
|
+
"tier": "lite",
|
|
1275
|
+
"content_hash": "sha256:e796b9736e9b00468822bfed2e2cdbed220c25ee8541f66fe7b743fe50d1a893"
|
|
1276
|
+
},
|
|
1230
1277
|
{
|
|
1231
1278
|
"slug": "bassclef-hook-connect",
|
|
1232
1279
|
"type": "presence-template",
|
|
@@ -1248,7 +1295,7 @@
|
|
|
1248
1295
|
"type": "presence-template",
|
|
1249
1296
|
"path": "presence/install/bassclef-sync.template.sh",
|
|
1250
1297
|
"tier": "lite",
|
|
1251
|
-
"content_hash": "sha256:
|
|
1298
|
+
"content_hash": "sha256:0a689f73d94bb78d1a3e7fdb3cda760e093db1d7536548cb05cf3a9ea9fb4c6c",
|
|
1252
1299
|
"description": "description: BASSCLEF_SYNC_VERSION=2026-09-06-1496-sessionstart-heal-v1"
|
|
1253
1300
|
},
|
|
1254
1301
|
{
|
|
@@ -1958,7 +2005,7 @@
|
|
|
1958
2005
|
"type": "script",
|
|
1959
2006
|
"path": "scripts/generate-lite-manifest.sh",
|
|
1960
2007
|
"tier": "lite",
|
|
1961
|
-
"content_hash": "sha256:
|
|
2008
|
+
"content_hash": "sha256:6342c768c91af054a4dcb6ea3e63228f0c7b4ff0e188867026fe0cdd333e3fe5",
|
|
1962
2009
|
"description": "Generate lite-manifest.json at repo root."
|
|
1963
2010
|
},
|
|
1964
2011
|
{
|
|
@@ -1993,6 +2040,14 @@
|
|
|
1993
2040
|
"content_hash": "sha256:30dc5eaff11fafc08b0845d8c4ce329a51b6ca0e89136638d335b58af41c7c0f",
|
|
1994
2041
|
"description": "Render human-readable companion doc from lite-manifest.json."
|
|
1995
2042
|
},
|
|
2043
|
+
{
|
|
2044
|
+
"slug": "workflow-metrics-query",
|
|
2045
|
+
"type": "script",
|
|
2046
|
+
"path": "scripts/workflow-metrics-query.sh",
|
|
2047
|
+
"tier": "lite",
|
|
2048
|
+
"content_hash": "sha256:9d9ad4a997e2820046802796f81a5d064b14f951cdade6f6c252db64d2afae89",
|
|
2049
|
+
"description": "CLI wrapper for lib/workflow-metrics.sh — Module B4 query helper."
|
|
2050
|
+
},
|
|
1996
2051
|
{
|
|
1997
2052
|
"slug": "agent-research-spawn",
|
|
1998
2053
|
"type": "skill",
|
|
@@ -2434,24 +2489,6 @@
|
|
|
2434
2489
|
"problem": "Session work fades from memory. Insight worth sharing with PE partners or eng leaders never gets written.",
|
|
2435
2490
|
"value": "Drafts a journal entry from this session's work. Tuned for PE, search, and board audiences."
|
|
2436
2491
|
},
|
|
2437
|
-
{
|
|
2438
|
-
"slug": "journal-export",
|
|
2439
|
-
"type": "skill",
|
|
2440
|
-
"path": ".claude/skills/journal-export/SKILL.md",
|
|
2441
|
-
"tier": "lite",
|
|
2442
|
-
"content_hash": "sha256:e63ffd119880230749701b9e484538bfe4a766a8e53ab2778c03f0cdb0762bc9",
|
|
2443
|
-
"description": "Generate a structured journal-entry corpus for a brand team or your own archive — chronicle digest, draft index, moment inventory. Supports incremental updates.",
|
|
2444
|
-
"inputs": [
|
|
2445
|
-
"Time range or theme filter"
|
|
2446
|
-
],
|
|
2447
|
-
"outputs": [
|
|
2448
|
-
"Corpus JSON",
|
|
2449
|
-
"Google Doc export",
|
|
2450
|
-
"Archive-ready file"
|
|
2451
|
-
],
|
|
2452
|
-
"problem": "Journal drafts pile up locally. Brand teams and archives don't get them systematically.",
|
|
2453
|
-
"value": "Structured journal-entry corpus for a brand team or your own archive. Chronicle digest included."
|
|
2454
|
-
},
|
|
2455
2492
|
{
|
|
2456
2493
|
"slug": "jtbd-tasks",
|
|
2457
2494
|
"type": "skill",
|
|
@@ -2535,7 +2572,7 @@
|
|
|
2535
2572
|
"type": "skill",
|
|
2536
2573
|
"path": ".claude/skills/longrun/SKILL.md",
|
|
2537
2574
|
"tier": "lite",
|
|
2538
|
-
"content_hash": "sha256:
|
|
2575
|
+
"content_hash": "sha256:e11e395721186c5e5021266723b942ac8f330f17bff4b495adf316d05674ac01",
|
|
2539
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.",
|
|
2540
2577
|
"composes_with": [
|
|
2541
2578
|
"value-prop",
|
|
@@ -2620,7 +2657,7 @@
|
|
|
2620
2657
|
"type": "skill",
|
|
2621
2658
|
"path": ".claude/skills/onboard-repo/SKILL.md",
|
|
2622
2659
|
"tier": "lite",
|
|
2623
|
-
"content_hash": "sha256:
|
|
2660
|
+
"content_hash": "sha256:ff92c1539bbad449bbdcfc85430963ceeda8cae67a2eded953bc95dff24a3c75",
|
|
2624
2661
|
"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).",
|
|
2625
2662
|
"inputs": [
|
|
2626
2663
|
"Optional flags — --with-deploy-host or --with-secrets or --full"
|
|
@@ -2749,7 +2786,7 @@
|
|
|
2749
2786
|
"type": "skill",
|
|
2750
2787
|
"path": ".claude/skills/provision-deploy-host/SKILL.md",
|
|
2751
2788
|
"tier": "lite",
|
|
2752
|
-
"content_hash": "sha256:
|
|
2789
|
+
"content_hash": "sha256:0fca55a7f73e23e0eee612597c9718ea58d020ddd61f81c3143f4ab8791a92a7",
|
|
2753
2790
|
"description": "Run the consumer onboarding chain — read bassclef-platform.yml plus verify secrets, extend GHA scope, run aws amplify create-app with console-pivot fallback, open the consumer config PR, write an audit row. Replaces the 5-step flow.",
|
|
2754
2791
|
"inputs": [
|
|
2755
2792
|
"Consumer name and target host"
|
|
@@ -2780,32 +2817,6 @@
|
|
|
2780
2817
|
"problem": "Trivial bugs get over-ceremonied by full /diagnose. Small edits shouldn't need the whole chain.",
|
|
2781
2818
|
"value": "Compressed fix workflow for trivial bugs. Operator-in-loop with stated entry criteria."
|
|
2782
2819
|
},
|
|
2783
|
-
{
|
|
2784
|
-
"slug": "release",
|
|
2785
|
-
"type": "skill",
|
|
2786
|
-
"path": ".claude/skills/release/SKILL.md",
|
|
2787
|
-
"tier": "lite",
|
|
2788
|
-
"content_hash": "sha256:17b931a7a5d3b69f57bc76f995af5c5c7a967df0389719c9fcbfc7f6677d09a9",
|
|
2789
|
-
"description": "Ship framework files from bassclef-upstream to public bassclef, filtered by tier. Dry-runs first, reports tier counts plus andon scan plus sibling smoke evidence. On operator confirm runs the live release and opens a PR. Per ADR-029.",
|
|
2790
|
-
"composes_with": [
|
|
2791
|
-
"verify",
|
|
2792
|
-
"state-a-problem",
|
|
2793
|
-
"value-prop",
|
|
2794
|
-
"kiss"
|
|
2795
|
-
],
|
|
2796
|
-
"inputs": [
|
|
2797
|
-
"Optional tier filter",
|
|
2798
|
-
"Dry-run or apply flag"
|
|
2799
|
-
],
|
|
2800
|
-
"outputs": [
|
|
2801
|
-
"Files shipped",
|
|
2802
|
-
"Dry-run diff",
|
|
2803
|
-
"Public PR",
|
|
2804
|
-
"Tag drop"
|
|
2805
|
-
],
|
|
2806
|
-
"problem": "Framework files ship from upstream to public bassclef through many manual steps. Dry-run catches slip past.",
|
|
2807
|
-
"value": "Ships framework files from bassclef-upstream to public bassclef. Filtered by tier. Dry-runs first."
|
|
2808
|
-
},
|
|
2809
2820
|
{
|
|
2810
2821
|
"slug": "release-notes",
|
|
2811
2822
|
"type": "skill",
|
|
@@ -3726,7 +3737,7 @@
|
|
|
3726
3737
|
"type": "standard",
|
|
3727
3738
|
"path": "standards/lite-manifest-schema-changes.md",
|
|
3728
3739
|
"tier": "lite",
|
|
3729
|
-
"content_hash": "sha256:
|
|
3740
|
+
"content_hash": "sha256:ba7d81b68af60e4df0e46fd7e0bb52ff756eaa13baf42b0dc679db37521b70a5",
|
|
3730
3741
|
"description": "Chronological ledger of every lite-manifest schema change. Adopters read this before sync to know what shifted."
|
|
3731
3742
|
},
|
|
3732
3743
|
{
|