@thebassclef/lite 0.1.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/dist/cli.cjs +238 -127
  2. package/dist/cli.js +240 -129
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/lite/.bassclef-source.json +10 -0
  7. package/dist/lite/.claude/settings.json +212 -0
  8. package/dist/lite/CLAUDE.md +41 -0
  9. package/dist/lite/gitignore +58 -0
  10. package/dist/lite/standards/bassclef-wiring-manifest.json +497 -0
  11. package/dist/lite/whereami.md +24 -0
  12. package/package.json +8 -2
  13. package/substrate/.bassclef/lite-manifest.json +0 -2701
  14. package/substrate/.claude/agents/architect.md +0 -70
  15. package/substrate/.claude/agents/builder.md +0 -114
  16. package/substrate/.claude/agents/designer.md +0 -156
  17. package/substrate/.claude/agents/reviewer.md +0 -88
  18. package/substrate/.claude/hooks/artifact-ingestion-gate.sh +0 -357
  19. package/substrate/.claude/hooks/assert-verify-steering.sh +0 -77
  20. package/substrate/.claude/hooks/bassclef-source-config-validate.sh +0 -215
  21. package/substrate/.claude/hooks/bassclef-sync.sh +0 -634
  22. package/substrate/.claude/hooks/compound-noun-scrub.sh +0 -292
  23. package/substrate/.claude/hooks/kiss-expansion-inject.sh +0 -69
  24. package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +0 -492
  25. package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +0 -492
  26. package/substrate/.claude/hooks/plain-english-steering.sh +0 -156
  27. package/substrate/.claude/hooks/post-skill-friction-check.sh +0 -177
  28. package/substrate/.claude/hooks/post-skill-telemetry.sh +0 -62
  29. package/substrate/.claude/hooks/pre-build-gate.sh +0 -511
  30. package/substrate/.claude/hooks/pre-commit-gate.sh +0 -451
  31. package/substrate/.claude/hooks/session-end.sh +0 -433
  32. package/substrate/.claude/hooks/session-reflection.sh +0 -303
  33. package/substrate/.claude/hooks/skill-body-grade-gate.sh +0 -219
  34. package/substrate/.claude/hooks/skill-body-intent-drift.sh +0 -107
  35. package/substrate/.claude/hooks/skill-step-list-check.sh +0 -171
  36. package/substrate/.claude/hooks/state-validate.sh +0 -271
  37. package/substrate/.claude/hooks/substrate-clarity-gate.sh +0 -1110
  38. package/substrate/.claude/hooks/temperance-gate.sh +0 -147
  39. package/substrate/.claude/hooks/testing-tier-enforce.sh +0 -233
  40. package/substrate/.claude/hooks/turn-prose-grade-measure.sh +0 -219
  41. package/substrate/.claude/hooks/turn-prose-kiss-check.sh +0 -463
  42. package/substrate/.claude/hooks/vocabulary-migration-check.sh +0 -171
  43. package/substrate/.claude/hooks/whereami-utc-gate.sh +0 -142
  44. package/substrate/.claude/luminaries/alan-cooper.md +0 -170
  45. package/substrate/.claude/luminaries/alistair-cockburn.md +0 -140
  46. package/substrate/.claude/luminaries/amazon-pr-faq.md +0 -34
  47. package/substrate/.claude/luminaries/ash-maurya.md +0 -121
  48. package/substrate/.claude/luminaries/bill-buxton.md +0 -210
  49. package/substrate/.claude/luminaries/charles-sanders-peirce.md +0 -150
  50. package/substrate/.claude/luminaries/david-ogilvy.md +0 -192
  51. package/substrate/.claude/luminaries/don-norman.md +0 -173
  52. package/substrate/.claude/luminaries/edward-tufte.md +0 -179
  53. package/substrate/.claude/luminaries/eric-evans.md +0 -160
  54. package/substrate/.claude/luminaries/frederick-brooks.md +0 -50
  55. package/substrate/.claude/luminaries/gang-of-four.md +0 -157
  56. package/substrate/.claude/luminaries/glenford-myers.md +0 -230
  57. package/substrate/.claude/luminaries/hunt-thomas.md +0 -115
  58. package/substrate/.claude/luminaries/hyrum-wright.md +0 -94
  59. package/substrate/.claude/luminaries/jason-fried-dhh.md +0 -46
  60. package/substrate/.claude/luminaries/jesse-james-garrett.md +0 -154
  61. package/substrate/.claude/luminaries/john-ousterhout.md +0 -94
  62. package/substrate/.claude/luminaries/karl-popper.md +0 -132
  63. package/substrate/.claude/luminaries/kent-beck.md +0 -168
  64. package/substrate/.claude/luminaries/linus-torvalds.md +0 -218
  65. package/substrate/.claude/luminaries/martin-fowler.md +0 -164
  66. package/substrate/.claude/luminaries/michael-feathers.md +0 -125
  67. package/substrate/.claude/luminaries/michael-nygard.md +0 -118
  68. package/substrate/.claude/luminaries/robert-c-martin.md +0 -164
  69. package/substrate/.claude/luminaries/saltzer-schroeder.md +0 -194
  70. package/substrate/.claude/luminaries/sophia-prater.md +0 -193
  71. package/substrate/.claude/luminaries/stephen-toulmin.md +0 -131
  72. package/substrate/.claude/luminaries/tony-hoare.md +0 -170
  73. package/substrate/.claude/luminaries/vaughn-vernon.md +0 -50
  74. package/substrate/.claude/luminaries/w-edwards-deming.md +0 -158
  75. package/substrate/.claude/rules/accessor-library-discipline.md +0 -138
  76. package/substrate/.claude/rules/adr-discipline.md +0 -120
  77. package/substrate/.claude/rules/api-conventions.md +0 -125
  78. package/substrate/.claude/rules/artifact-ingestion.md +0 -179
  79. package/substrate/.claude/rules/assert-only-after-verify.md +0 -137
  80. package/substrate/.claude/rules/blocked-items.md +0 -146
  81. package/substrate/.claude/rules/bootstrap-pair-discipline.md +0 -141
  82. package/substrate/.claude/rules/branching.md +0 -28
  83. package/substrate/.claude/rules/cold-adopter-harness-discipline.md +0 -129
  84. package/substrate/.claude/rules/commit-conventions.md +0 -22
  85. package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +0 -188
  86. package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +0 -188
  87. package/substrate/.claude/rules/context-engineering.md +0 -202
  88. package/substrate/.claude/rules/context-management.md +0 -85
  89. package/substrate/.claude/rules/defensive-bash.md +0 -68
  90. package/substrate/.claude/rules/deferred-actions.md +0 -233
  91. package/substrate/.claude/rules/destructive-operations.md +0 -69
  92. package/substrate/.claude/rules/diagnosis.md +0 -38
  93. package/substrate/.claude/rules/github-issue-flash-tweet.md +0 -156
  94. package/substrate/.claude/rules/guardrails.md +0 -73
  95. package/substrate/.claude/rules/hook-wire-on-author.md +0 -103
  96. package/substrate/.claude/rules/identifier-leak-prevention.md +0 -104
  97. package/substrate/.claude/rules/iteration-bet-brief-completeness.md +0 -54
  98. package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +0 -98
  99. package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +0 -89
  100. package/substrate/.claude/rules/loop-discipline.md +0 -81
  101. package/substrate/.claude/rules/manual-prod-approval.md +0 -100
  102. package/substrate/.claude/rules/marker-enrichment-discipline.md +0 -99
  103. package/substrate/.claude/rules/mobile-ephemeral-session.md +0 -109
  104. package/substrate/.claude/rules/new-dependency-check.md +0 -51
  105. package/substrate/.claude/rules/oo-ad-entry-point.md +0 -117
  106. package/substrate/.claude/rules/operator-facing-prose.md +0 -196
  107. package/substrate/.claude/rules/option-label-discipline.md +0 -108
  108. package/substrate/.claude/rules/pattern-annotation.md +0 -100
  109. package/substrate/.claude/rules/plain-english-discipline.md +0 -156
  110. package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +0 -211
  111. package/substrate/.claude/rules/pr-body-shape.md +0 -317
  112. package/substrate/.claude/rules/pr-strategy.md +0 -167
  113. package/substrate/.claude/rules/pr-title-shape.md +0 -161
  114. package/substrate/.claude/rules/prototype-workflow.md +0 -65
  115. package/substrate/.claude/rules/reserved-skill-names.md +0 -123
  116. package/substrate/.claude/rules/schema-management.md +0 -49
  117. package/substrate/.claude/rules/sdlc-gates.md +0 -149
  118. package/substrate/.claude/rules/security.md +0 -37
  119. package/substrate/.claude/rules/session-artifacts.md +0 -236
  120. package/substrate/.claude/rules/skill-composition-declarations.md +0 -124
  121. package/substrate/.claude/rules/skill-description-clarity.md +0 -247
  122. package/substrate/.claude/rules/skill-procedure-step-list.md +0 -137
  123. package/substrate/.claude/rules/state-schema-validation.md +0 -162
  124. package/substrate/.claude/rules/stuck-signal-diagnostic.md +0 -140
  125. package/substrate/.claude/rules/substrate-config-schema.md +0 -98
  126. package/substrate/.claude/rules/test-list-discipline.md +0 -175
  127. package/substrate/.claude/rules/test-sufficiency.md +0 -210
  128. package/substrate/.claude/rules/testing-tier-config.md +0 -145
  129. package/substrate/.claude/rules/testing.md +0 -38
  130. package/substrate/.claude/rules/turn-estimate-grounding.md +0 -134
  131. package/substrate/.claude/rules/visual-hierarchy.md +0 -437
  132. package/substrate/.claude/rules/we-dont-break-adopters.md +0 -126
  133. package/substrate/.claude/rules/whereami-load-bearing.md +0 -202
  134. package/substrate/.claude/rules/writing-craft-discipline.md +0 -92
  135. package/substrate/.claude/rules/wu-sequencing-compounds.md +0 -145
  136. package/substrate/.claude/skills/build/SKILL.md +0 -640
  137. package/substrate/.claude/skills/chronicle/SKILL.md +0 -55
  138. package/substrate/.claude/skills/clean-artifacts/SKILL.md +0 -249
  139. package/substrate/.claude/skills/decompose/SKILL.md +0 -280
  140. package/substrate/.claude/skills/diagnose/SKILL.md +0 -297
  141. package/substrate/.claude/skills/feynman/SKILL.md +0 -90
  142. package/substrate/.claude/skills/howdoi/SKILL.md +0 -105
  143. package/substrate/.claude/skills/ia-model/SKILL.md +0 -108
  144. package/substrate/.claude/skills/interaction-design/SKILL.md +0 -112
  145. package/substrate/.claude/skills/interpret-input/SKILL.md +0 -180
  146. package/substrate/.claude/skills/journal/SKILL.md +0 -209
  147. package/substrate/.claude/skills/kiss/SKILL.md +0 -449
  148. package/substrate/.claude/skills/launch/SKILL.md +0 -915
  149. package/substrate/.claude/skills/lean-canvas/SKILL.md +0 -332
  150. package/substrate/.claude/skills/longrun/SKILL.md +0 -463
  151. package/substrate/.claude/skills/luminary/SKILL.md +0 -481
  152. package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +0 -177
  153. package/substrate/.claude/skills/onboard-repo/SKILL.md +0 -1624
  154. package/substrate/.claude/skills/pattern-review/SKILL.md +0 -99
  155. package/substrate/.claude/skills/personas/SKILL.md +0 -207
  156. package/substrate/.claude/skills/promote/SKILL.md +0 -283
  157. package/substrate/.claude/skills/requirement/SKILL.md +0 -98
  158. package/substrate/.claude/skills/retro/SKILL.md +0 -117
  159. package/substrate/.claude/skills/riff/SKILL.md +0 -114
  160. package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +0 -163
  161. package/substrate/.claude/skills/session-end/SKILL.md +0 -309
  162. package/substrate/.claude/skills/session-log/SKILL.md +0 -299
  163. package/substrate/.claude/skills/skills/SKILL.md +0 -228
  164. package/substrate/.claude/skills/spec/SKILL.md +0 -105
  165. package/substrate/.claude/skills/sprint/SKILL.md +0 -392
  166. package/substrate/.claude/skills/stage/SKILL.md +0 -384
  167. package/substrate/.claude/skills/state-a-problem/SKILL.md +0 -185
  168. package/substrate/.claude/skills/temperance/SKILL.md +0 -108
  169. package/substrate/.claude/skills/use-case/SKILL.md +0 -417
  170. package/substrate/.claude/skills/user-stories/SKILL.md +0 -268
  171. package/substrate/.claude/skills/value-prop/SKILL.md +0 -251
  172. package/substrate/.claude/skills/verify/SKILL.md +0 -160
  173. package/substrate/.claude/skills/visual-review/SKILL.md +0 -503
  174. package/substrate/.claude/skills/whats-the-plan/SKILL.md +0 -202
  175. package/substrate/.claude/skills/whereami/SKILL.md +0 -307
  176. package/substrate/AGENTS.md +0 -79
  177. package/substrate/CLAUDE-lite.md +0 -85
  178. package/substrate/CODE_OF_CONDUCT.md +0 -28
  179. package/substrate/CONTRIBUTING.md +0 -177
  180. package/substrate/README.md +0 -173
  181. package/substrate/SECURITY.md +0 -19
  182. package/substrate/architecture/decisions/ADR-029-release-pipeline.md +0 -79
  183. package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +0 -139
  184. package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +0 -192
  185. package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +0 -145
  186. package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +0 -155
  187. package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +0 -162
  188. package/substrate/lib/clean-artifacts-sweep.sh +0 -112
  189. package/substrate/lib/code-comment-discipline.sh +0 -144
  190. package/substrate/lib/composer-preflight.sh +0 -459
  191. package/substrate/lib/hook-inject.sh +0 -255
  192. package/substrate/lib/luminary-pick.sh +0 -96
  193. package/substrate/lib/output-discipline.sh +0 -143
  194. package/substrate/lib/prose-scan-boundary.sh +0 -171
  195. package/substrate/lib/rewrite-check.sh +0 -214
  196. package/substrate/lib/state.sh +0 -1372
  197. package/substrate/lib/telemetry.sh +0 -205
  198. package/substrate/lib/tier-check.sh +0 -187
  199. package/substrate/lib/tier-dependency-audit.sh +0 -1088
  200. package/substrate/presence/install/bassclef-hook-connect.sh +0 -178
  201. package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +0 -841
  202. package/substrate/presence/install/bassclef-sync.template.sh +0 -2076
  203. package/substrate/presence/install/schedule-auto-save.cron.sh +0 -88
  204. package/substrate/presence/install/schedule-auto-save.taskscheduler.md +0 -122
  205. package/substrate/scripts/aggregate-telemetry.sh +0 -217
  206. package/substrate/scripts/analyze-tier-dependencies.sh +0 -239
  207. package/substrate/scripts/generate-lite-manifest.sh +0 -505
  208. package/substrate/scripts/generate-tier-manifest.sh +0 -28
  209. package/substrate/scripts/intent-drift-check.sh +0 -456
  210. package/substrate/scripts/lite-manifest-drift-check.sh +0 -146
  211. package/substrate/scripts/render-lite-manifest-doc.sh +0 -150
  212. package/substrate/standards/adr-template.md +0 -86
  213. package/substrate/standards/api-conventions/nextjs.md +0 -84
  214. package/substrate/standards/artifact-composition.md +0 -209
  215. package/substrate/standards/bash-hook-safety.md +0 -246
  216. package/substrate/standards/bassclef-configs-schema.md +0 -232
  217. package/substrate/standards/bassclef-evolution.md +0 -143
  218. package/substrate/standards/bassclef-internal-jargon.md +0 -244
  219. package/substrate/standards/bassclef-managed-sentinel.md +0 -96
  220. package/substrate/standards/bassclef-source-config.md +0 -228
  221. package/substrate/standards/branch-stacking.md +0 -408
  222. package/substrate/standards/code-safety-principles.md +0 -176
  223. package/substrate/standards/composer-prerequisites.md +0 -155
  224. package/substrate/standards/deferred-actions-schema.md +0 -204
  225. package/substrate/standards/dependency-discipline/cargo.md +0 -39
  226. package/substrate/standards/dependency-discipline/gem.md +0 -43
  227. package/substrate/standards/dependency-discipline/go-mod.md +0 -41
  228. package/substrate/standards/dependency-discipline/npm.md +0 -42
  229. package/substrate/standards/dependency-discipline/pip.md +0 -42
  230. package/substrate/standards/deployment-topology/ec2-tailscale.md +0 -225
  231. package/substrate/standards/deployment-topology.md +0 -69
  232. package/substrate/standards/docs-sync-allowlist.md +0 -76
  233. package/substrate/standards/domain-and-dns.md +0 -145
  234. package/substrate/standards/frontend-stack.md +0 -67
  235. package/substrate/standards/frontmatter-schema.md +0 -154
  236. package/substrate/standards/graceful-exit.md +0 -227
  237. package/substrate/standards/hook-idempotency.md +0 -102
  238. package/substrate/standards/hook-injection-discipline.md +0 -202
  239. package/substrate/standards/hook-install-class.md +0 -215
  240. package/substrate/standards/input-handler-interface.md +0 -152
  241. package/substrate/standards/lite-manifest-schema-changes.md +0 -135
  242. package/substrate/standards/luminary-matching.md +0 -105
  243. package/substrate/standards/luminary-problem-patterns.md +0 -481
  244. package/substrate/standards/migration-discipline/active-record.md +0 -50
  245. package/substrate/standards/migration-discipline/alembic.md +0 -43
  246. package/substrate/standards/migration-discipline/gorm.md +0 -50
  247. package/substrate/standards/migration-discipline/prisma.md +0 -53
  248. package/substrate/standards/migration-discipline/sqlalchemy.md +0 -51
  249. package/substrate/standards/mobile-ephemeral-session.md +0 -167
  250. package/substrate/standards/model-routing-discipline.md +0 -160
  251. package/substrate/standards/ogilvy-writing-rules.md +0 -225
  252. package/substrate/standards/opener-discipline.md +0 -96
  253. package/substrate/standards/operator-facing-prose-discipline.md +0 -201
  254. package/substrate/standards/persona-schema.md +0 -229
  255. package/substrate/standards/pluggable-luminaries.md +0 -323
  256. package/substrate/standards/pr-body-discipline.md +0 -115
  257. package/substrate/standards/preview-state-schema.md +0 -189
  258. package/substrate/standards/project-directory-layout.md +0 -276
  259. package/substrate/standards/release-tagging.md +0 -137
  260. package/substrate/standards/reserved-skill-names.md +0 -120
  261. package/substrate/standards/scannable-multi-option-output.md +0 -261
  262. package/substrate/standards/sdlc-compliance.md +0 -286
  263. package/substrate/standards/sdlc-gates/typescript.md +0 -57
  264. package/substrate/standards/secrets-lifecycle.md +0 -210
  265. package/substrate/standards/security-scanner-adapter.md +0 -145
  266. package/substrate/standards/session-board.md +0 -256
  267. package/substrate/standards/skill-output-discipline.md +0 -90
  268. package/substrate/standards/state-spine-contract.md +0 -255
  269. package/substrate/standards/state-spine.md +0 -511
  270. package/substrate/standards/steering-hints/kiss-words.md +0 -11
  271. package/substrate/standards/substrate-config-schema.md +0 -267
  272. package/substrate/standards/tech-stack-config.md +0 -109
  273. package/substrate/standards/tier-dependency-analysis.md +0 -167
  274. package/substrate/standards/tier-runtime-deps/lite.md +0 -57
  275. package/substrate/standards/tier-tag-schema.md +0 -155
  276. package/substrate/standards/two-layer-config.md +0 -99
  277. package/substrate/standards/use-case-format.md +0 -292
  278. package/substrate/standards/user-story-invest.md +0 -268
  279. package/substrate/standards/velocity-and-appetite.md +0 -229
  280. package/substrate/standards/voice-input-pattern.md +0 -119
  281. package/substrate/standards/whereami-schema.md +0 -301
  282. package/substrate/standards/worktree-management.md +0 -211
  283. package/substrate/standards/writing-guide.md +0 -213
  284. package/substrate/templates/chronicle-template.md +0 -75
  285. package/substrate/templates/deferred-action-template.md +0 -45
  286. package/substrate/templates/memory-proposal-template.md +0 -77
  287. package/substrate/templates/persona-template.md +0 -200
  288. package/substrate/templates/pr-faq.md +0 -45
  289. package/substrate/templates/secret-rotation-template.md +0 -162
  290. package/substrate/templates/spec-template.md +0 -131
  291. package/substrate/templates/use-case-template.md +0 -194
  292. package/substrate/templates/user-story-template.md +0 -107
  293. package/substrate/templates/whereami-template.md +0 -101
@@ -1,171 +0,0 @@
1
- #!/bin/bash
2
- # tier: lite
3
- # install-class: dual
4
- # Skill-step-list check — Stop hook that scans the transcript for a Skill tool
5
- # dispatch followed by an assistant response without a step-list block.
6
- #
7
- # Per sunj-labs/bassclef-upstream#1119: closes the SKILL-step-skip class caught
8
- # in session 2026-08-05a. Rule at .claude/rules/skill-procedure-step-list.md.
9
- # Ships as pair per bootstrap-pair-discipline.md.
10
- #
11
- # Sibling pattern: .claude/hooks/turn-prose-kiss-check.sh (Stop hook + transcript scan).
12
- #
13
- # Input (stdin): JSON with transcript_path + session_id
14
- # {"transcript_path": "/path/to/transcript.jsonl", "session_id": "..."}
15
- #
16
- # Toggle (env or .claude/bassclef-configs.jsonc):
17
- # SKILL_STEP_LIST_TOGGLE=true — advisory (exit 0, findings to stderr) [DEFAULT]
18
- # SKILL_STEP_LIST_TOGGLE=strict — strict (exit 2, blocks stop, forces rewrite)
19
- # SKILL_STEP_LIST_TOGGLE=false — silent (exit 0, no scan)
20
- #
21
- # Override per-call:
22
- # SKIP_SKILL_STEP_LIST=1 — skip scan, exit 0
23
- #
24
- # Exit codes:
25
- # 0 — pass (no findings, advisory mode, toggle off, override set, or no Skill dispatched)
26
- # 2 — block stop (strict mode + Skill dispatched + no step-list in response)
27
- #
28
- # Reads:
29
- # - $TRANSCRIPT_PATH (JSONL, one event per line)
30
- # - .claude/bassclef-configs.jsonc (toggle when env not set)
31
-
32
- set +e
33
-
34
- # === Override path ===
35
- if [ "${SKIP_SKILL_STEP_LIST:-0}" = "1" ]; then
36
- exit 0
37
- fi
38
-
39
- # === Source install-class resolver ===
40
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
41
-
42
- # Hook liveness heartbeat (silent-fail)
43
- {
44
- for _hb_c in "${SCRIPT_DIR}/../../lib/hook-heartbeat.sh" "${HOME:-/}/lib/hook-heartbeat.sh"; do
45
- [ -f "$_hb_c" ] && source "$_hb_c" && heartbeat_mark "skill-step-list-check" && break
46
- done
47
- unset _hb_c
48
- } 2>/dev/null || true
49
-
50
- for _candidate in \
51
- "${SCRIPT_DIR}/../../lib/hook-inject.sh" \
52
- "${HOME_OVERRIDE:-${HOME:-/}}/lib/hook-inject.sh"; do
53
- if [ -f "$_candidate" ]; then
54
- # shellcheck disable=SC1090
55
- source "$_candidate"
56
- break
57
- fi
58
- done
59
- unset _candidate
60
-
61
- # === Parse stdin JSON ===
62
- STDIN_JSON=$(cat 2>/dev/null || echo '{}')
63
- TRANSCRIPT_PATH=$(echo "$STDIN_JSON" | jq -r '.transcript_path // ""' 2>/dev/null)
64
-
65
- # Graceful skip if no transcript path
66
- if [ -z "$TRANSCRIPT_PATH" ]; then
67
- exit 0
68
- fi
69
-
70
- # Graceful skip if transcript file missing
71
- if [ ! -f "$TRANSCRIPT_PATH" ]; then
72
- exit 0
73
- fi
74
-
75
- # === Resolve config file ===
76
- if declare -f resolve_config_path >/dev/null 2>&1; then
77
- CONFIG_FILE=$(resolve_config_path 2>/dev/null) || CONFIG_FILE=""
78
- else
79
- CONFIG_FILE="${SCRIPT_DIR}/../bassclef-configs.jsonc"
80
- fi
81
-
82
- # === Resolve toggle ===
83
- TOGGLE="${SKILL_STEP_LIST_TOGGLE:-}"
84
- if [ -z "$TOGGLE" ]; then
85
- if [ -n "$CONFIG_FILE" ] && [ -f "$CONFIG_FILE" ]; then
86
- TOGGLE=$(sed 's|//.*||g' "$CONFIG_FILE" 2>/dev/null \
87
- | jq -r '.skill_step_list.toggle // "true"' 2>/dev/null)
88
- fi
89
- TOGGLE="${TOGGLE:-true}"
90
- fi
91
-
92
- case "$TOGGLE" in
93
- true|"true") MODE="advisory" ;;
94
- strict|"strict") MODE="strict" ;;
95
- false|"false") exit 0 ;;
96
- *) MODE="advisory" ;;
97
- esac
98
-
99
- # === Scan transcript for a Skill tool_use ===
100
- # We scan the last 200 lines to keep the hook fast.
101
- LAST_LINES=$(tail -200 "$TRANSCRIPT_PATH" 2>/dev/null)
102
-
103
- # Find lines with Skill tool_use
104
- SKILL_LINE_NUM=$(echo "$LAST_LINES" | grep -n '"type":"tool_use"' 2>/dev/null | grep '"name":"Skill"' | tail -1 | cut -d: -f1)
105
-
106
- if [ -z "$SKILL_LINE_NUM" ]; then
107
- # No Skill dispatched in recent transcript — silent pass
108
- exit 0
109
- fi
110
-
111
- # === Find the assistant text_content event AFTER the Skill line ===
112
- # The response we care about is the one after the Skill tool_result comes back.
113
- AFTER_SKILL=$(echo "$LAST_LINES" | tail -n +"$((SKILL_LINE_NUM + 1))" 2>/dev/null)
114
-
115
- # Get the latest assistant text_content in that portion
116
- LAST_ASSISTANT_AFTER=$(echo "$AFTER_SKILL" | grep '"type":"assistant"' | tail -1)
117
-
118
- if [ -z "$LAST_ASSISTANT_AFTER" ]; then
119
- # Skill dispatched but no response yet — silent pass
120
- exit 0
121
- fi
122
-
123
- # Extract text content from the assistant message
124
- MESSAGE_TEXT=$(echo "$LAST_ASSISTANT_AFTER" \
125
- | jq -r '.message.content[]? |
126
- if .type == "text" then
127
- .text
128
- else
129
- empty
130
- end' 2>/dev/null)
131
-
132
- if [ -z "$MESSAGE_TEXT" ]; then
133
- # Assistant message had no text content (tool_use only) — silent pass
134
- exit 0
135
- fi
136
-
137
- # === Check for step-list pattern ===
138
- # Pattern: two markers must both appear:
139
- # 1. A "Step N" reference (Step + digit)
140
- # 2. At least one "[x]" or "[~]" bracket status marker
141
- HAS_STEP=$(echo "$MESSAGE_TEXT" | grep -cE 'Step[[:space:]]+[0-9]+' 2>/dev/null)
142
- HAS_MARKER=$(echo "$MESSAGE_TEXT" | grep -cE '\[[x~]\]' 2>/dev/null)
143
-
144
- if [ "$HAS_STEP" -gt 0 ] && [ "$HAS_MARKER" -gt 0 ]; then
145
- # Step-list present — silent pass
146
- exit 0
147
- fi
148
-
149
- # === Missing step-list — emit finding ===
150
- NOTICE="SKILL step-list check: recent Skill dispatch response lacks a step-list block."
151
- NOTICE="$NOTICE Per .claude/rules/skill-procedure-step-list.md,"
152
- NOTICE="$NOTICE write each SKILL procedure step with [x] done+source OR [~] deferred+reason."
153
-
154
- # Trace log if trace-helper available
155
- if [ -f "${SCRIPT_DIR}/../../lib/trace-helper.sh" ]; then
156
- source "${SCRIPT_DIR}/../../lib/trace-helper.sh" 2>/dev/null
157
- if declare -f trace_record >/dev/null 2>&1; then
158
- trace_record "skill-step-list-check" "advisory-fired" "$NOTICE" 2>/dev/null
159
- fi
160
- fi
161
-
162
- if [ "$MODE" = "strict" ]; then
163
- echo "🛑 BLOCKED: $NOTICE" >&2
164
- echo "" >&2
165
- echo "To resolve: rewrite the response with a step list at the top." >&2
166
- echo "Override: SKIP_SKILL_STEP_LIST=1 <command> (logged)" >&2
167
- exit 2
168
- else
169
- echo "⚠ ADVISORY: $NOTICE" >&2
170
- exit 0
171
- fi
@@ -1,271 +0,0 @@
1
- #!/usr/bin/env bash
2
- # tier: lite
3
- # state-validate.sh — PreToolUse hook that validates state-spine entity
4
- # writes against their JSON schemas.
5
- #
6
- # Wires per .claude/settings.json under hooks.PreToolUse with matcher
7
- # "Edit|Write". Reads the tool's event JSON from stdin, detects whether
8
- # the target file is a state-spine entity, extracts its data per the
9
- # entity's storage shape, validates against the schema, and BLOCKs
10
- # (exit non-zero) on failure.
11
- #
12
- # Per ADR-015: JSON Schema only for v0. Validator: ajv-cli draft-2020-12.
13
- # Per state-spine.md: three storage shapes (A/B/C) handled via path-based
14
- # entity-type detection.
15
- # Per accessor-library-discipline.md: this is the write-side gate.
16
- #
17
- # Override: SKIP_STATE_VALIDATE=1 (logged to stderr).
18
- #
19
- # Pairs with: .claude/rules/state-schema-validation.md
20
-
21
- set -u
22
-
23
- # === Hook liveness heartbeat (WU-3 of bet 2026-07-31d; closes #1002) ===
24
- # Silent-fail — a missing lib never crashes the hook.
25
- {
26
- _hb_sd="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
27
- for _hb_c in "${_hb_sd}/../../lib/hook-heartbeat.sh" "${HOME:-/}/lib/hook-heartbeat.sh"; do
28
- [ -f "$_hb_c" ] && source "$_hb_c" && heartbeat_mark "state-validate" && break
29
- done
30
- unset _hb_sd _hb_c
31
- } 2>/dev/null || true
32
-
33
- # === Override path ===
34
-
35
- if [ "${SKIP_STATE_VALIDATE:-}" = "1" ]; then
36
- echo "[state-validate.sh] SKIP_STATE_VALIDATE=1 — bypassing validation" >&2
37
- exit 0
38
- fi
39
-
40
- # === Read PreToolUse event ===
41
-
42
- EVENT_JSON="$(cat)"
43
- TOOL_NAME="$(echo "$EVENT_JSON" | jq -r '.tool_name // empty')"
44
- TARGET_PATH="$(echo "$EVENT_JSON" | jq -r '.tool_input.file_path // empty')"
45
-
46
- # Tool filter: only Edit and Write trigger validation
47
- case "$TOOL_NAME" in
48
- Edit|Write|MultiEdit) ;;
49
- *) exit 0 ;;
50
- esac
51
-
52
- # Empty path → pass-through
53
- if [ -z "$TARGET_PATH" ]; then
54
- exit 0
55
- fi
56
-
57
- # === Resolve project dir + schema dir ===
58
-
59
- PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
60
- SCHEMA_DIR="${PROJECT_DIR}/standards/state-spine/schemas"
61
-
62
- # If schema dir doesn't exist, this repo doesn't have spine v0 yet — pass through
63
- if [ ! -d "$SCHEMA_DIR" ]; then
64
- exit 0
65
- fi
66
-
67
- # === Path-based entity detection ===
68
- #
69
- # Returns the entity slug (matching <slug>.schema.json) if path is a
70
- # state-spine entity, empty otherwise.
71
- detect_entity_type() {
72
- local path="$1"
73
- # Strip project_dir prefix if present
74
- local rel="${path#${PROJECT_DIR}/}"
75
- rel="${rel#./}"
76
-
77
- local result=""
78
- case "$rel" in
79
- docs/whereami.json) result="whereami" ;;
80
- substrate.config.json) result="substrate-config" ;;
81
- docs/preview-state/*.json) result="preview-state" ;;
82
- docs/iteration-bets/*.md) result="iteration-bet" ;;
83
- docs/roadmaps/*.md) result="roadmap" ;;
84
- docs/stacks/*.md) result="stack" ;;
85
- docs/decompositions/*.md) result="decomposition" ;;
86
- docs/personas/*.md) result="persona" ;;
87
- docs/deferred-actions/*.md) result="deferred-action" ;;
88
- chronicle/*.md|docs/chronicle/*.md) result="chronicle" ;;
89
- state/markers/*/*.json) result="marker" ;;
90
- docs/sessions/*.json) result="session" ;;
91
- docs/sessions/*.md) result="session" ;;
92
- docs/input-artifacts/*.json) result="input-artifact" ;;
93
- state/template-instances/*.json) result="template-instance" ;;
94
- state/inbox/*.json) result="inbox-work-item" ;;
95
- state/stack-templates/*.json) result="stack-template" ;;
96
- bassclef-platform.yml|bassclef-platform.yaml) result="bassclef-platform" ;;
97
- esac
98
-
99
- # bassclef-platform.yml lives at the root of a SIBLING repo (e.g.,
100
- # sunj-labs/platform-config). When edited from outside PROJECT_DIR,
101
- # the absolute path doesn't strip cleanly — match by basename suffix
102
- # as a fallback. The file MUST be at a repo root (not nested).
103
- if [ -z "$result" ]; then
104
- case "$path" in
105
- */bassclef-platform.yml|*/bassclef-platform.yaml) result="bassclef-platform" ;;
106
- esac
107
- fi
108
-
109
- echo "$result"
110
- }
111
-
112
- ENTITY="$(detect_entity_type "$TARGET_PATH")"
113
-
114
- # Non-state file → pass-through
115
- if [ -z "$ENTITY" ]; then
116
- exit 0
117
- fi
118
-
119
- # === Resolve schema file ===
120
-
121
- SCHEMA_FILE="${SCHEMA_DIR}/${ENTITY}.schema.json"
122
- if [ ! -f "$SCHEMA_FILE" ]; then
123
- echo "[state-validate.sh] schema for entity '$ENTITY' not found at $SCHEMA_FILE — pass-through" >&2
124
- exit 0
125
- fi
126
-
127
- # === Storage shape detection ===
128
- #
129
- # A = pure JSON (whole file validates)
130
- # B = markdown + YAML frontmatter (extract frontmatter, validate)
131
- # C = pure JSON (whole file validates) — same as A but for collection entities
132
- #
133
- # In practice for the validator: anything ending in .json validates the
134
- # whole file; anything ending in .md extracts YAML frontmatter and
135
- # validates that.
136
-
137
- extract_data_for_validation() {
138
- local path="$1"
139
- if [ ! -f "$path" ]; then
140
- echo "[state-validate.sh] file does not exist at write time: $path" >&2
141
- return 4
142
- fi
143
- case "$path" in
144
- *.json)
145
- cat "$path"
146
- ;;
147
- *.md)
148
- # Extract YAML frontmatter, convert to JSON
149
- awk '/^---$/{c++; next} c==1' "$path" | python3 -c "
150
- import sys, yaml, json
151
- try:
152
- data = yaml.safe_load(sys.stdin) or {}
153
- print(json.dumps(data, default=str))
154
- except Exception as e:
155
- print(f'YAML parse failed: {e}', file=sys.stderr)
156
- sys.exit(3)
157
- "
158
- ;;
159
- *.yml|*.yaml)
160
- # Pure YAML file (Shape D — entity is the whole file). Convert
161
- # to JSON and validate. Used by bassclef-platform.yml.
162
- python3 -c "
163
- import sys, yaml, json
164
- try:
165
- with open('$path') as f:
166
- data = yaml.safe_load(f) or {}
167
- print(json.dumps(data, default=str))
168
- except Exception as e:
169
- print(f'YAML parse failed: {e}', file=sys.stderr)
170
- sys.exit(3)
171
- "
172
- ;;
173
- *)
174
- echo "[state-validate.sh] unsupported extension for path: $path" >&2
175
- return 5
176
- ;;
177
- esac
178
- }
179
-
180
- # Hoare precondition cure (#1001): on new-file Write the target does not
181
- # yet exist on disk. Read tool_input.content from the event JSON and
182
- # materialize a temp file so the extract function can read it. Preserves
183
- # the disk-read path for Edit and existing-file Write. Silent no-op when
184
- # content is absent (matches prior file-missing behavior).
185
- NEW_FILE_TMP=""
186
- if [ ! -f "$TARGET_PATH" ] && [ "$TOOL_NAME" = "Write" ]; then
187
- WRITE_CONTENT="$(echo "$EVENT_JSON" | jq -r '.tool_input.content // empty')"
188
- if [ -n "$WRITE_CONTENT" ]; then
189
- NEW_FILE_TMP="$(mktemp -t state-validate-newfile-XXXXXX)${TARGET_PATH##*.}"
190
- # Add trailing dot if the extension detection above collapsed
191
- case "$TARGET_PATH" in
192
- *.*) NEW_FILE_TMP="${NEW_FILE_TMP%.*}.${TARGET_PATH##*.}" ;;
193
- esac
194
- printf '%s' "$WRITE_CONTENT" > "$NEW_FILE_TMP"
195
- trap 'rm -f "$NEW_FILE_TMP"' EXIT
196
- DATA_JSON="$(extract_data_for_validation "$NEW_FILE_TMP")"
197
- EXTRACT_EXIT=$?
198
- else
199
- exit 0
200
- fi
201
- else
202
- DATA_JSON="$(extract_data_for_validation "$TARGET_PATH")"
203
- EXTRACT_EXIT=$?
204
- fi
205
-
206
- if [ "$EXTRACT_EXIT" -ne 0 ]; then
207
- exit "$EXTRACT_EXIT"
208
- fi
209
-
210
- # Legacy pass-through: pre-spine artifacts have no YAML frontmatter at
211
- # all (e.g., bets authored before schemas existed). Skip validation
212
- # with WARN to nudge migration without BLOCKing routine work. WU-4
213
- # migration brings these into conformance progressively.
214
- if [ -z "$DATA_JSON" ] || [ "$DATA_JSON" = "{}" ] || [ "$DATA_JSON" = "null" ]; then
215
- echo "[state-validate.sh] WARN: $TARGET_PATH ($ENTITY) has no YAML frontmatter — legacy pass-through. Migrate via WU-4 to add minimal metadata." >&2
216
- exit 0
217
- fi
218
-
219
- # === Validate via ajv-cli ===
220
-
221
- # Stage data as a temp JSON file for ajv -d.
222
- # Note: ajv-cli detects format by file extension, and macOS mktemp -t
223
- # appends random suffix AFTER the template, so .json must be explicitly
224
- # tacked on via mv to ensure it's the trailing extension.
225
- DATA_TMP_RAW="$(mktemp -t state-validate-XXXXXX)"
226
- DATA_TMP="${DATA_TMP_RAW}.json"
227
- mv "$DATA_TMP_RAW" "$DATA_TMP"
228
- trap 'rm -f "$DATA_TMP"' EXIT
229
- echo "$DATA_JSON" > "$DATA_TMP"
230
-
231
- # Stage all schemas as -r refs so $ref resolution works (e.g., _reference, _value_prop, _appetite_actuals, step)
232
- REF_ARGS=""
233
- for ref_schema in "$SCHEMA_DIR"/_*.schema.json "$SCHEMA_DIR"/step.schema.json; do
234
- if [ -f "$ref_schema" ] && [ "$ref_schema" != "$SCHEMA_FILE" ]; then
235
- REF_ARGS="$REF_ARGS -r $ref_schema"
236
- fi
237
- done
238
-
239
- # Run ajv-cli; silence its noisy npm warnings, capture only validation result
240
- VALIDATION_OUTPUT="$(npx -y -p ajv-cli@5 -p ajv-formats@2 ajv validate \
241
- --spec=draft2020 \
242
- -s "$SCHEMA_FILE" \
243
- $REF_ARGS \
244
- -d "$DATA_TMP" \
245
- -c ajv-formats 2>&1)"
246
- VALIDATION_EXIT=$?
247
-
248
- if [ "$VALIDATION_EXIT" -eq 0 ]; then
249
- exit 0
250
- fi
251
-
252
- # === BLOCK with structured error ===
253
-
254
- echo "" >&2
255
- echo "🛑 STATE-VALIDATE — BLOCKED 🛑" >&2
256
- echo "" >&2
257
- echo "Entity: $ENTITY" >&2
258
- echo "Schema: $SCHEMA_FILE" >&2
259
- echo "Path: $TARGET_PATH" >&2
260
- echo "" >&2
261
- echo "Validation error:" >&2
262
- # Strip noisy npm warnings; surface only ajv's actual error lines
263
- echo "$VALIDATION_OUTPUT" | grep -v "^npm warn" | grep -v "^$" >&2
264
- echo "" >&2
265
- echo "Per .claude/rules/state-schema-validation.md: state-spine entity" >&2
266
- echo "writes must conform to their schema. Either:" >&2
267
- echo " 1. Fix the data to match the schema (preferred)" >&2
268
- echo " 2. Update the schema if it's wrong (requires PR review)" >&2
269
- echo " 3. Override with SKIP_STATE_VALIDATE=1 (logged; rare; not for normal work)" >&2
270
- echo "" >&2
271
- exit 3