@thebassclef/lite 1.4.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.
Files changed (32) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/lite/.bassclef-source.json +2 -2
  6. package/dist/lite/.claude/hooks/_lib/wirings.sh +237 -0
  7. package/dist/lite/.claude/hooks/pre-commit-manifest-autoregen.sh +187 -0
  8. package/dist/lite/.claude/hooks/session-reflection.d/08-settings-drift.sh +66 -6
  9. package/dist/lite/.claude/hooks/session-reflection.d/20-artifact-staleness.sh +25 -5
  10. package/dist/lite/.claude/hooks/session-reflection.d/30-metrics-staleness.sh +11 -0
  11. package/dist/lite/.claude/hooks/session-reflection.d/60-deferred-actions.sh +2 -1
  12. package/dist/lite/.claude/hooks/session-reflection.d/80-hook-heartbeat-check.sh +20 -0
  13. package/dist/lite/.claude/hooks/session-reflection.d/tests/20-artifact-staleness.test.sh +89 -0
  14. package/dist/lite/.claude/hooks/session-reflection.sh +12 -1
  15. package/dist/lite/.claude/luminaries/david-farley.md +115 -0
  16. package/dist/lite/.claude/luminaries/jez-humble.md +124 -0
  17. package/dist/lite/.claude/luminaries/martin-fowler.md +18 -0
  18. package/dist/lite/.claude/skills/longrun/SKILL.md +51 -0
  19. package/dist/lite/.claude/skills/onboard-repo/SKILL.md +39 -11
  20. package/dist/lite/.claude/skills/provision-deploy-host/SKILL.md +2 -2
  21. package/dist/lite/lib/ancestor-claude-check.sh +101 -0
  22. package/dist/lite/lib/fixture-builder.sh +324 -0
  23. package/dist/lite/lib/workflow-metrics.sh +166 -0
  24. package/dist/lite/presence/install/bassclef-configs.template.jsonc +76 -0
  25. package/dist/lite/presence/install/bassclef-sync.template.sh +7 -4
  26. package/dist/lite/scripts/generate-lite-manifest.sh +151 -1
  27. package/dist/lite/scripts/workflow-metrics-query.sh +57 -0
  28. package/dist/lite/standards/lite-manifest-schema-changes.md +24 -0
  29. package/dist/lite/standards/lite-manifest.json +79 -68
  30. package/package.json +1 -1
  31. package/dist/lite/.claude/skills/journal-export/SKILL.md +0 -293
  32. 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 LinkedIn → Google Docs)
2182
- SA_KEY="$HOME/.config/gcloud/sunjay-google-ops.json"
2183
- if [ ! -f "$SA_KEY" ]; then
2184
- MISSING="${MISSING}\n- Google Docs service account key missing at $SA_KEY (needed for /journal Google Doc push)"
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="1.8.2"
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.8.5",
4
- "generated_at": "2026-09-18T12:53:51Z",
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:610c46bab04ca47af207824cc5faa24c7754c00b976b71d9be77057e9ea87a63",
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:5a406be60669e106c99e98da00d7acb8e9ce834a84e1145d244f5121cfd0f9a9",
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:6a296054a37741db7a9161a11e8582ce31f489f8fb1683d3c2cf2daf981242a7",
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:b119d0700df5823afeed631a6f4ddfb9cb0f302577e3b3977a30c8ddb85acd60",
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:4467390bb6f7dfa418c799ce175a9febc395e3b883c720c562e2c42ffdb1ff81",
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:a9f2492fcf1ae86da3da2e0b6311d8e68a01472e9d68e9504fe6044a5f55d99d",
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:85a59597e8898ea38e7d7442423381f0c4caa5ecf6780bbd0a71d63b819d3b13",
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:7fbf6ec65206fcbb6dbf2df1d24fed37555d495c6597885ff1a7f201ce3c2544",
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:f202c2bb2d252e72e3c2f80a99fea4fece95b9db3744721ce4fea12e3a4b4eb1",
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:950c701995965d543a692cfba919593bb6ae36c2103b5b93a7217d41bb9f0009",
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:65c43c8b003cfe34787021a6c34c0b9686f4467269aed304cebba0b4cc1e5346",
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:daaa194480170f0b4745ee5c72d267413d8dc249e4ece2711672118553121667",
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:62000692c88b5ceb15d3a04ae3f8c45a97728061e1915368af11f67945643ee1",
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:1269fad0dfe006a4c52094d4efb441101d87cbd3a85b1a1de0e8ff724fa20e44",
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
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thebassclef/lite",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Bassclef CLI — install and upgrade bassclef in your project with two commands.",
5
5
  "keywords": [
6
6
  "bassclef",