@thebassclef/lite 0.1.3 → 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 +216 -137
  2. package/dist/cli.js +218 -139
  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,492 +0,0 @@
1
- #!/bin/bash
2
- # tier: lite
3
- # install-class: dual
4
- # longrun-prep-compounding-sequence-check.sh — Stop hook that fires when
5
- # state/markers/turn-prose-surface/longrun_prep_proposal.marker is
6
- # present. Scans the latest assistant message for the 5 prescribed
7
- # column headers from /longrun SKILL Step 1.5 (compounding-sequence
8
- # analysis). Default V2 = strict (exit 2 on missing axes); explicit
9
- # advisory toggle preserved for backward compat.
10
- #
11
- # Per bassclef-upstream#426 V2 flip. Calibration cycle (one /longrun
12
- # prep after V1 ship) demonstrated the visibility gap: V1 advisory
13
- # emitted to stderr; agent could not see its own advisory, missed
14
- # 2-of-5 column at next prep. Flip closes the loop per ADR-035
15
- # substrate-as-system.
16
- #
17
- # Per bet 28a WU-5d (V1 ship) + bet 30b extension (V2 flip with
18
- # tonight's prep as eat-own-dogfood evidence).
19
- #
20
- # Sister hook pattern to turn-prose-kiss-check.sh (Stop hook scanning
21
- # marker-gated transcript).
22
- #
23
- # Override per-call: SKIP_COMPOUNDING_AXIS_CHECK=1
24
- # Backward compat: COMPOUNDING_AXIS_TOGGLE=advisory — exit 0 + finding
25
- # COMPOUNDING_AXIS_TOGGLE=strict — exit 2 (default; explicit opt-in)
26
- #
27
- # Frozen stderr contract (per bassclef-upstream#1536 Hyrum finding):
28
- # SECTION-EMPTY guard emits exactly:
29
- # "🛑 COMPOUNDING-AXIS — BLOCKED (SECTION-EMPTY per-shape parse boundary; V2 strict default)"
30
- # "🛑 COMPOUNDING-AXIS — ADVISORY (SECTION-EMPTY per-shape parse boundary; backward-compat opt-out)"
31
- # Per-shape line prefix: " 🔍 <shape>"
32
- # Any change to these strings updates this header comment as the observable contract.
33
- #
34
- # Tier 0 strict TDD: .claude/hooks/tests/longrun-prep-compounding-sequence-check.test.sh
35
-
36
- set +e
37
-
38
- INPUT=$(cat)
39
- TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // ""' 2>/dev/null || echo "")
40
- CWD=$(echo "$INPUT" | jq -r '.cwd // "."' 2>/dev/null || echo ".")
41
-
42
- # Override
43
- if [ "${SKIP_COMPOUNDING_AXIS_CHECK:-0}" = "1" ]; then
44
- exit 0
45
- fi
46
-
47
- # Marker gate — only fire when /longrun prep proposal is being authored
48
- MARKER_PATH="$CWD/state/markers/turn-prose-surface/longrun_prep_proposal.marker"
49
- if [ ! -f "$MARKER_PATH" ]; then
50
- exit 0
51
- fi
52
-
53
- # Auto-clean gate (Cure A per ticket #1555) — if a prior Stop event already
54
- # fired this hook cleanly (exit 0) during this prep session, skip subsequent
55
- # firings. The consumed sibling marker signals "primary marker's job is done".
56
- # Operator manually re-touches the primary marker for the next prep proposal.
57
- # Closes the doom loop where post-prep status turns kept tripping this hook.
58
- CONSUMED_MARKER="$CWD/state/markers/turn-prose-surface/longrun_prep_proposal.marker.consumed"
59
- if [ -f "$CONSUMED_MARKER" ]; then
60
- exit 0
61
- fi
62
-
63
- # Need transcript to scan
64
- if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
65
- exit 0
66
- fi
67
-
68
- # Extract last assistant message text (per turn-prose-kiss-check pattern)
69
- LAST_ASSISTANT_LINE=$(grep '"type":"assistant"' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)
70
- [ -z "$LAST_ASSISTANT_LINE" ] && exit 0
71
-
72
- MESSAGE_TEXT=$(echo "$LAST_ASSISTANT_LINE" | jq -r '.message.content[]? | select(.type == "text") | .text' 2>/dev/null)
73
- [ -z "$MESSAGE_TEXT" ] && exit 0
74
-
75
- # === Check compounding-sequence column headers ===
76
- # Per /longrun SKILL Step 1.5: option table must include columns for the
77
- # axis set. Hook accepts EITHER of two shapes during the ADR-031 grace
78
- # window through 2026-10-31 (bassclef#1555 PR-1):
79
- #
80
- # 5-axis LEGACY (original, per bet 28a WU-5d):
81
- # Compounding surface | Compounding rate | Foundation prereq |
82
- # Inverse-dependency | Risk class
83
- #
84
- # 6-axis NEW (per plan doc 2026-09-09-compounding-axis-refactor):
85
- # Deliverable | Problem | Value prop | Turns | Risk | Shipping priority
86
- #
87
- # Try each axis set. The hook passes if EITHER set matches. If neither
88
- # matches, BLOCK naming the axes missing from the closest shape (fewest
89
- # missing entries).
90
-
91
- check_axis_any() {
92
- # Returns 0 if any variant appears in MESSAGE_TEXT; else 1
93
- local variant
94
- for variant in "$@"; do
95
- if echo "$MESSAGE_TEXT" | grep -qi "$variant"; then
96
- return 0
97
- fi
98
- done
99
- return 1
100
- }
101
-
102
- # --- 5-axis LEGACY set ---
103
- FIVE_MISSING=()
104
- check_axis_any "Compounding surface" "Compounds at" "Where the payoff shows up" \
105
- || FIVE_MISSING+=("Compounding surface")
106
- check_axis_any "Compounding rate" "| *Rate" "How often it fires" \
107
- || FIVE_MISSING+=("Compounding rate")
108
- check_axis_any "Foundation prereq" "What must be true first" \
109
- || FIVE_MISSING+=("Foundation prereq")
110
- check_axis_any "Inverse-dependency" "Does this teach" \
111
- || FIVE_MISSING+=("Inverse-dependency")
112
- check_axis_any "Risk class" "| *Risk" "What breaks if" \
113
- || FIVE_MISSING+=("Risk class")
114
-
115
- # --- 6-axis NEW set (bassclef#1555 PR-1) ---
116
- SIX_MISSING=()
117
- check_axis_any "Deliverable" "Ships when" \
118
- || SIX_MISSING+=("Deliverable")
119
- check_axis_any "Problem" "Pain" \
120
- || SIX_MISSING+=("Problem")
121
- check_axis_any "Value prop" "value proposition" \
122
- || SIX_MISSING+=("Value prop")
123
- check_axis_any "Turns" "Turn count" "Turn range" "Turn estimate" \
124
- || SIX_MISSING+=("Turns")
125
- check_axis_any "Risk" "| *Risk" "🟢" "🟡" "🔴" \
126
- || SIX_MISSING+=("Risk")
127
- check_axis_any "Shipping priority" "Priority:" "\bQ1\b" "\bQ2\b" "\bQ3\b" "\bQ4\b" \
128
- || SIX_MISSING+=("Shipping priority")
129
-
130
- # Pick the shape with fewer missing axes; if neither set is complete, that
131
- # shape is what MISSING reports. If either set is complete (empty missing
132
- # array), the message passes the header check.
133
- if [ "${#FIVE_MISSING[@]}" -eq 0 ] || [ "${#SIX_MISSING[@]}" -eq 0 ]; then
134
- MISSING=()
135
- elif [ "${#FIVE_MISSING[@]}" -le "${#SIX_MISSING[@]}" ]; then
136
- MISSING=("${FIVE_MISSING[@]}")
137
- else
138
- MISSING=("${SIX_MISSING[@]}")
139
- fi
140
-
141
- # === Per-shape distinct-value check (bassclef-upstream#564) ===
142
- # When 2+ shape section headers appear (**Shape a**, ### Shape a, etc.),
143
- # the rule postcondition per Hoare requires each shape section to render
144
- # all 5 axes with distinct values. A single header row with axis names
145
- # but no per-shape values is R8 pattern — label without work.
146
- #
147
- # Per luminary consultation: Ousterhout (deep modules; SKILL + rule +
148
- # hook = one contract with matching depth), Hoare (strong postcondition),
149
- # Feathers (characterization tests use tonight's prep messages), Saltzer
150
- # & Schroeder (complete mediation; every axis cell mediates), Beck (TDD).
151
- #
152
- # Falsifies R8 flavor A (aggregate cells collapse axes into one).
153
- # This check only fires when message-level axis names ARE present
154
- # (avoids double-firing on pure message-level miss).
155
-
156
- # === Per-WU compounding-sequence check (bassclef-upstream#597) ===
157
- # When prep proposal contains a produces/consumes WU table with 2+ WU
158
- # rows (multi-step bet), the message must also render per-step compounding
159
- # axes — either via "Compounding value per step" heading OR per-step axis
160
- # rendering that names each step with its 5 axes.
161
- #
162
- # Convention worked for weeks (bet-doc convention). Tonight's PR #567
163
- # tightened Step 1.5 to require 5 distinct axes per shape and the
164
- # attention shift crowded the per-step habit out. Per ADR-035
165
- # substrate-as-system tenet, mechanize the convention so it survives
166
- # sibling-discipline tightening.
167
- #
168
- # Fires only when the message passes the shape-level checks first —
169
- # avoids double-firing when the message-level column check already
170
- # BLOCKED.
171
-
172
- if [ "${#MISSING[@]}" -eq 0 ]; then
173
- # Count WU rows in produces/consumes tables. WU row markers include:
174
- # | **1** | ... or | **WU-1** | ... or **WU-1** in bullets.
175
- # Use a permissive regex to catch canonical bet-doc formats.
176
- WU_ROW_COUNT=$(echo "$MESSAGE_TEXT" | grep -cE '^\|[[:space:]]*\*\*(WU-)?[0-9]+\*\*' 2>/dev/null || echo 0)
177
- # Sanitize (grep -c can print trailing content on some macOS bash)
178
- WU_ROW_COUNT=$(echo "$WU_ROW_COUNT" | tr -cd '0-9')
179
- [ -z "$WU_ROW_COUNT" ] && WU_ROW_COUNT=0
180
-
181
- if [ "$WU_ROW_COUNT" -ge 2 ]; then
182
- # Look for either the canonical section heading OR per-step axis rendering.
183
- HAS_PER_WU_HEADING=$(echo "$MESSAGE_TEXT" | grep -ciE '(compounding value per step|per-step compounding|compounding sequence per step|compounding.axis.*wu)' 2>/dev/null | tr -cd '0-9')
184
- [ -z "$HAS_PER_WU_HEADING" ] && HAS_PER_WU_HEADING=0
185
-
186
- if [ "$HAS_PER_WU_HEADING" -eq 0 ]; then
187
- TOGGLE="${COMPOUNDING_AXIS_TOGGLE:-strict}"
188
- if [ "$TOGGLE" = "advisory" ]; then
189
- LABEL="ADVISORY (per-step; backward-compat opt-out)"
190
- else
191
- LABEL="BLOCKED (per-step compounding columns missing; V1 strict default)"
192
- fi
193
-
194
- echo "" >&2
195
- echo "🛑 COMPOUNDING-AXIS — $LABEL" >&2
196
- echo "" >&2
197
- echo " /longrun prep proposal has $WU_ROW_COUNT WU rows in the" >&2
198
- echo " produces/consumes table but no per-step compounding-sequence" >&2
199
- echo " rendering (R8 pattern — convention displaced by sibling" >&2
200
- echo " tightening in PR #567)." >&2
201
- echo "" >&2
202
- echo " Per bassclef-upstream#597 + ADR-035 substrate-as-system:" >&2
203
- echo " each step section must carry the 5 axes (plain-English preferred):" >&2
204
- echo " - Where the payoff shows up (was: Compounding surface)" >&2
205
- echo " - How often it fires (was: Compounding rate)" >&2
206
- echo " - What must be true first (was: Foundation prereq)" >&2
207
- echo " - Does this teach a shape later work reuses (was: Inverse-dependency)" >&2
208
- echo " - What breaks if we ship this half-done (was: Risk class)" >&2
209
- echo " Both label forms accepted through 2026-10-31 per ADR-040 D4." >&2
210
- echo "" >&2
211
- echo " Cure: add a '## Compounding value per step' section OR render" >&2
212
- echo " each step with its 5 axes as bullets. See" >&2
213
- echo " .claude/rules/compounding-sequence-fresh-analysis.md for shape." >&2
214
- echo "" >&2
215
- echo " Override: SKIP_COMPOUNDING_AXIS_CHECK=1 (logged)" >&2
216
- echo " Backward compat: COMPOUNDING_AXIS_TOGGLE=advisory (exit 0)" >&2
217
- echo "" >&2
218
-
219
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
220
- if [ -f "$SCRIPT_DIR/trace-helper.sh" ]; then
221
- # shellcheck disable=SC1091
222
- source "$SCRIPT_DIR/trace-helper.sh"
223
- trace_log "compounding-sequence-check" "$LABEL per-step-missing count=$WU_ROW_COUNT"
224
- fi
225
-
226
- [ "$TOGGLE" = "advisory" ] && exit 0
227
- exit 2
228
- fi
229
- fi
230
-
231
- # Per bassclef-upstream#1193 — SKILL rename #830 replaced "Shape a-c"
232
- # with "Option a-e". Regex accepts both during the grace window
233
- # through 2026-10-31 per .claude/rules/we-dont-break-adopters.md.
234
- # After that date, only "Option [a-z]" matches.
235
- SHAPES=$(echo "$MESSAGE_TEXT" | grep -Eo '(Shape [a-c]|Option [a-z])\b' | sort -u)
236
-
237
- # Per bassclef-upstream#1376 — accept per-recommended-only shape.
238
- # When the message opens with `**Recommend:** Option X` (or Shape X),
239
- # the reader lands the pick in the first 15 lines. Non-recommended
240
- # options carry their axes as one-liner cells in the scan-table row,
241
- # not as full sections. The hook trusts the Recommend line: it treats
242
- # the labeled option as REQUIRED (section + 5 axes) and treats every
243
- # other option as OPTIONAL (a missing section stops SECTION-EMPTY from
244
- # firing on that option).
245
- #
246
- # Per Tufte data-ink (drop fields that do not change the pick) +
247
- # Prater progressive disclosure (default minimum; expand on ask).
248
- # Sister #959 lands the SKILL body trim; this hook amend unblocks it.
249
- RECOMMENDED_OPTION=$(echo "$MESSAGE_TEXT" | grep -Eo '\*\*Recommend[^*]*\*\*[[:space:]]*(Shape [a-c]|Option [a-z])' | head -1 | grep -Eo '(Shape [a-c]|Option [a-z])' | head -1)
250
- if [ -z "$SHAPES" ]; then
251
- SHAPE_COUNT=0
252
- else
253
- SHAPE_COUNT=$(echo "$SHAPES" | wc -l | tr -d ' ')
254
- fi
255
-
256
- # Per-shape check fires when 2+ options AND for recommended-only shape
257
- # even with 1 option (bassclef-upstream#1376) — the recommended option's
258
- # section must carry all 5 axes with distinct values.
259
- if [ "$SHAPE_COUNT" -ge 2 ] || [ -n "$RECOMMENDED_OPTION" ]; then
260
- PER_SHAPE_MISSING=""
261
- SECTION_EMPTY_SHAPES=""
262
- while IFS= read -r shape; do
263
- [ -z "$shape" ] && continue
264
- # Section boundaries require a heading anchor at line start
265
- # (H2+ heading like `## Option a`, `### Option a`, `#### Option a`,
266
- # or bold prefix `**Option a`) so mid-body cross-references like
267
- # "same end-state as Option b" do not trigger a false section
268
- # boundary. Cure per bassclef-upstream#1421 Option (a). H2+ range
269
- # per bassclef-upstream#1532 — options nested under a container H3
270
- # anchor (e.g., `### Compounding value per option`) resolve cleanly
271
- # regardless of nesting depth. H1 excluded by design.
272
- SECTION=$(echo "$MESSAGE_TEXT" | awk -v want="$shape" '
273
- BEGIN { in_section=0 }
274
- /^(##+ |\*\*)(Shape [a-c]|Option [a-z])/ {
275
- if ($0 ~ want) { in_section=1; print; next }
276
- else if (in_section) { in_section=0 }
277
- }
278
- in_section { print }
279
- ')
280
-
281
- # Hoare precondition guard (bassclef-upstream#1536) — when shape name
282
- # matches via grep-Eo but SECTION returns empty, the heading boundary
283
- # is missing. Fail-safe per Saltzer-Schroeder: capture + emit distinct
284
- # diagnostic under the existing banner + exit 2. Advisory toggle preserved.
285
- #
286
- # Recommended-only shape carve-out (bassclef-upstream#1376) — when the
287
- # message declares a recommended option via **Recommend:** ..., non-
288
- # recommended options may legitimately lack a section (they carry axes
289
- # as scan-table cells only). Skip SECTION-EMPTY for those; still fire
290
- # SECTION-EMPTY if the RECOMMENDED option has no section.
291
- if [ -z "$SECTION" ]; then
292
- if [ -n "$RECOMMENDED_OPTION" ] && [ "$shape" != "$RECOMMENDED_OPTION" ]; then
293
- continue
294
- fi
295
- SECTION_EMPTY_SHAPES="${SECTION_EMPTY_SHAPES} 🔍 ${shape}\n"
296
- continue
297
- fi
298
-
299
- # Recommended-only shape carve-out (bassclef-upstream#1376) —
300
- # only the recommended option must carry all 5 axes distinctly in
301
- # per-recommended-only mode. Non-recommended options with a partial
302
- # section skip the per-axis check.
303
- if [ -n "$RECOMMENDED_OPTION" ] && [ "$shape" != "$RECOMMENDED_OPTION" ]; then
304
- continue
305
- fi
306
-
307
- # Grace window per bet 2026-07-16b WU-2 (#734) + bassclef#1555 PR-1 —
308
- # per-shape check accepts EITHER 5-axis LEGACY or 6-axis NEW shape.
309
- # Determine which axis set the section uses, then verify all axes of
310
- # that set are present. If neither set is complete for this section,
311
- # report the set with fewer missing axes.
312
-
313
- # Try 5-axis set on this section
314
- FIVE_SECTION_MISSING=()
315
- echo "$SECTION" | grep -qiE "Compounding surface|Compounds at|Where the payoff shows up" \
316
- || FIVE_SECTION_MISSING+=("Compounding surface")
317
- echo "$SECTION" | grep -qiE "Compounding rate|\| *Rate|How often it fires" \
318
- || FIVE_SECTION_MISSING+=("Compounding rate")
319
- echo "$SECTION" | grep -qiE "Foundation prereq|What must be true first" \
320
- || FIVE_SECTION_MISSING+=("Foundation prereq")
321
- echo "$SECTION" | grep -qiE "Inverse-dependency|Does this teach" \
322
- || FIVE_SECTION_MISSING+=("Inverse-dependency")
323
- echo "$SECTION" | grep -qiE "Risk class|\| *Risk|What breaks if" \
324
- || FIVE_SECTION_MISSING+=("Risk class")
325
-
326
- # Try 6-axis set on this section
327
- SIX_SECTION_MISSING=()
328
- echo "$SECTION" | grep -qiE "Deliverable|Ships when" \
329
- || SIX_SECTION_MISSING+=("Deliverable")
330
- echo "$SECTION" | grep -qiE "Problem|Pain" \
331
- || SIX_SECTION_MISSING+=("Problem")
332
- echo "$SECTION" | grep -qiE "Value prop|value proposition" \
333
- || SIX_SECTION_MISSING+=("Value prop")
334
- echo "$SECTION" | grep -qiE "Turns|Turn count|Turn range|Turn estimate" \
335
- || SIX_SECTION_MISSING+=("Turns")
336
- echo "$SECTION" | grep -qiE "Risk|🟢|🟡|🔴" \
337
- || SIX_SECTION_MISSING+=("Risk")
338
- echo "$SECTION" | grep -qiE "Shipping priority|Priority:|\bQ1\b|\bQ2\b|\bQ3\b|\bQ4\b" \
339
- || SIX_SECTION_MISSING+=("Shipping priority")
340
-
341
- # Pick the shape with fewer missing per this section. If either set is
342
- # complete for this section, that section passes.
343
- if [ "${#FIVE_SECTION_MISSING[@]}" -eq 0 ] || [ "${#SIX_SECTION_MISSING[@]}" -eq 0 ]; then
344
- : # section passes — one of the two shapes is complete
345
- elif [ "${#FIVE_SECTION_MISSING[@]}" -le "${#SIX_SECTION_MISSING[@]}" ]; then
346
- for axis_name in "${FIVE_SECTION_MISSING[@]}"; do
347
- PER_SHAPE_MISSING="${PER_SHAPE_MISSING} - ${shape}: missing '${axis_name}'\n"
348
- done
349
- else
350
- for axis_name in "${SIX_SECTION_MISSING[@]}"; do
351
- PER_SHAPE_MISSING="${PER_SHAPE_MISSING} - ${shape}: missing '${axis_name}'\n"
352
- done
353
- fi
354
- done <<< "$SHAPES"
355
-
356
- # Hoare precondition guard emit — SECTION-EMPTY takes precedence over
357
- # "distinct values missing" because a failed parse is a different
358
- # failure class than missing content. Per bassclef-upstream#1536.
359
- if [ -n "$SECTION_EMPTY_SHAPES" ]; then
360
- TOGGLE="${COMPOUNDING_AXIS_TOGGLE:-strict}"
361
- if [ "$TOGGLE" = "advisory" ]; then
362
- LABEL="ADVISORY (SECTION-EMPTY per-shape parse boundary; backward-compat opt-out)"
363
- else
364
- LABEL="BLOCKED (SECTION-EMPTY per-shape parse boundary; V2 strict default)"
365
- fi
366
- echo "" >&2
367
- echo "🛑 COMPOUNDING-AXIS — $LABEL" >&2
368
- echo "" >&2
369
- echo " /longrun prep proposal references shapes but SECTION extraction" >&2
370
- echo " returned empty. Precondition failure — heading boundary not found." >&2
371
- echo " Per Hoare precondition contract (bassclef-upstream#1536)." >&2
372
- echo "" >&2
373
- echo " SECTION-EMPTY shapes:" >&2
374
- printf "$SECTION_EMPTY_SHAPES" >&2
375
- echo "" >&2
376
- echo " Cure: give each shape a heading anchor at H2 through H6" >&2
377
- echo " (e.g., '#### Option a') or bold prefix ('**Option a')." >&2
378
- echo " See fixture 2026-09-08-step-1-4c-worked-example/ for the shape." >&2
379
- echo "" >&2
380
- echo " Override: SKIP_COMPOUNDING_AXIS_CHECK=1 (logged)" >&2
381
- echo " Backward compat: COMPOUNDING_AXIS_TOGGLE=advisory (exit 0)" >&2
382
- echo "" >&2
383
-
384
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
385
- if [ -f "$SCRIPT_DIR/trace-helper.sh" ]; then
386
- # shellcheck disable=SC1091
387
- source "$SCRIPT_DIR/trace-helper.sh"
388
- trace_log "compounding-sequence-check" "$LABEL section-empty"
389
- fi
390
-
391
- [ "$TOGGLE" = "advisory" ] && exit 0
392
- exit 2
393
- fi
394
-
395
- if [ -n "$PER_SHAPE_MISSING" ]; then
396
- TOGGLE="${COMPOUNDING_AXIS_TOGGLE:-strict}"
397
- if [ "$TOGGLE" = "advisory" ]; then
398
- LABEL="ADVISORY (per-shape; backward-compat opt-out)"
399
- else
400
- LABEL="BLOCKED (per-shape distinct values missing; V2 strict default)"
401
- fi
402
-
403
- echo "" >&2
404
- echo "🛑 COMPOUNDING-AXIS — $LABEL" >&2
405
- echo "" >&2
406
- echo " /longrun prep proposal has $SHAPE_COUNT shape sections but" >&2
407
- echo " the axes do not render distinctly per shape (R8 pattern)." >&2
408
- echo "" >&2
409
- echo " Per bassclef-upstream#564 + luminary consultation" >&2
410
- echo " (Ousterhout/Hoare/Feathers/Saltzer-Schroeder/Beck):" >&2
411
- echo " each shape section must carry all 5 axes as distinct values." >&2
412
- echo "" >&2
413
- echo " Missing per-shape values:" >&2
414
- printf "$PER_SHAPE_MISSING" >&2
415
- echo "" >&2
416
- echo " Cure: for each shape (a, b, c...), render all 5 axes with" >&2
417
- echo " their distinct values under that shape's section." >&2
418
- echo "" >&2
419
- echo " Override: SKIP_COMPOUNDING_AXIS_CHECK=1 (logged)" >&2
420
- echo " Backward compat: COMPOUNDING_AXIS_TOGGLE=advisory (exit 0)" >&2
421
- echo "" >&2
422
-
423
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
424
- if [ -f "$SCRIPT_DIR/trace-helper.sh" ]; then
425
- # shellcheck disable=SC1091
426
- source "$SCRIPT_DIR/trace-helper.sh"
427
- trace_log "compounding-sequence-check" "$LABEL per-shape-missing"
428
- fi
429
-
430
- [ "$TOGGLE" = "advisory" ] && exit 0
431
- exit 2
432
- fi
433
- fi
434
- # True-clean pass — all message-level axes present, per-WU + per-shape
435
- # checks passed. Write consumed sibling marker per Cure A (ticket #1555)
436
- # so subsequent Stop events skip the scan for this prep session.
437
- touch "$CONSUMED_MARKER" 2>/dev/null || true
438
- exit 0
439
- fi
440
-
441
- # === Emit finding ===
442
- # Default V2 = strict. Explicit "advisory" toggle preserves backward compat.
443
- TOGGLE="${COMPOUNDING_AXIS_TOGGLE:-strict}"
444
-
445
- if [ "$TOGGLE" = "advisory" ]; then
446
- LABEL="ADVISORY (backward-compat opt-out)"
447
- else
448
- LABEL="BLOCKED (V2 strict default)"
449
- fi
450
-
451
- echo "" >&2
452
- echo "🛑 COMPOUNDING-AXIS — $LABEL" >&2
453
- echo "" >&2
454
- echo " /longrun prep proposal detected (marker present)." >&2
455
- echo " Per /longrun SKILL Step 1.5 + bet 28a WU-5d:" >&2
456
- echo " shape proposal table must include compounding-sequence columns." >&2
457
- echo "" >&2
458
- echo " Missing axes in latest assistant message (plain-English preferred):" >&2
459
- for col in "${MISSING[@]}"; do
460
- case "$col" in
461
- "Compounding surface") echo " - Where the payoff shows up (was: Compounding surface)" >&2 ;;
462
- "Compounding rate") echo " - How often it fires (was: Compounding rate)" >&2 ;;
463
- "Foundation prereq") echo " - What must be true first (was: Foundation prereq)" >&2 ;;
464
- "Inverse-dependency") echo " - Does this teach a shape later work reuses (was: Inverse-dependency)" >&2 ;;
465
- "Risk class") echo " - What breaks if we ship this half-done (was: Risk class)" >&2 ;;
466
- *) echo " - $col" >&2 ;;
467
- esac
468
- done
469
- echo "" >&2
470
- echo " Cure: add these axes to the option table before operator picks." >&2
471
- echo " Each option row carries a value per axis. Both label forms accepted" >&2
472
- echo " through 2026-10-31 per ADR-040 D4." >&2
473
- echo "" >&2
474
- echo " Override: SKIP_COMPOUNDING_AXIS_CHECK=1 (logged via trace)" >&2
475
- echo " Backward compat: COMPOUNDING_AXIS_TOGGLE=advisory (exit 0)" >&2
476
- echo "" >&2
477
-
478
- # Trace log
479
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
480
- if [ -f "$SCRIPT_DIR/trace-helper.sh" ]; then
481
- # shellcheck disable=SC1091
482
- source "$SCRIPT_DIR/trace-helper.sh"
483
- trace_log "compounding-sequence-check" "$LABEL missing=${MISSING[*]}"
484
- fi
485
-
486
- # Advisory mode (backward compat): exit 0
487
- if [ "$TOGGLE" = "advisory" ]; then
488
- exit 0
489
- fi
490
-
491
- # Strict mode (default V2): exit 2 to block the stop
492
- exit 2
@@ -1,156 +0,0 @@
1
- #!/bin/bash
2
- # tier: lite
3
- # install-class: dual
4
- # plain-english-steering.sh — UserPromptSubmit hook that injects
5
- # additionalContext steering the agent toward grade-10 plain English
6
- # at source. Per bassclef-upstream#443 + bet 28a WU-5c.
7
- #
8
- # Adds Layer 0 to the 5-layer prose-discipline defense
9
- # (per .claude/rules/operator-facing-prose.md):
10
- #
11
- # Layer 0 (this hook, UserPromptSubmit) — steer at source
12
- # Layer 1 (substrate-clarity-gate, PreToolUse Edit on substrate paths)
13
- # Layer 2 (pre-gh-pr-body-scrub, PreToolUse Bash for gh pr create/edit)
14
- # Layer 3 (pre-gh-issue-body-scrub + pre-git-commit-msg-scrub)
15
- # Layer 4 (turn-prose-kiss-check, Stop hook scanning assistant message)
16
- # Layer 5 (CI bassclef-pr-ci.yml jobs as backstop)
17
- #
18
- # Override per-call: SKIP_PLAIN_ENGLISH_STEERING=1
19
- #
20
- # Tier 0 strict TDD: .claude/hooks/tests/plain-english-steering.test.sh
21
-
22
- set +e
23
-
24
- # === Source install-class-aware lib (per kiss cure pattern) ===
25
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
26
- for _candidate in \
27
- "${SCRIPT_DIR}/../../lib/hook-inject.sh" \
28
- "${HOME_OVERRIDE:-${HOME:-/}}/lib/hook-inject.sh"; do
29
- if [ -f "$_candidate" ]; then
30
- # shellcheck disable=SC1090
31
- source "$_candidate"
32
- break
33
- fi
34
- done
35
-
36
- # Defensive: if lib not loaded, exit silent
37
- if ! declare -f emit_additional_context >/dev/null 2>&1; then
38
- exit 0
39
- fi
40
-
41
- # Override
42
- if [ "${SKIP_PLAIN_ENGLISH_STEERING:-0}" = "1" ]; then
43
- exit 0
44
- fi
45
-
46
- # === Read last-turn grade marker (if present) ===
47
- REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
48
- GRADE_MARKER="${REPO_ROOT}/state/markers/turn-grade/last-turn.json"
49
- FLAGS_MARKER="${REPO_ROOT}/state/markers/turn-prose-flags/last-turn.json"
50
- GRADE_LINE=""
51
- FALLBACK_WARNING=""
52
- FLAGS_LINE=""
53
-
54
- if [ -f "$GRADE_MARKER" ]; then
55
- LAST_GRADE=$(jq -r '.grade // ""' "$GRADE_MARKER" 2>/dev/null)
56
- LAST_WORDS=$(jq -r '.words // ""' "$GRADE_MARKER" 2>/dev/null)
57
- SOURCE=$(jq -r '.source // "UNKNOWN"' "$GRADE_MARKER" 2>/dev/null)
58
- if [ -n "$LAST_GRADE" ] && [ "$LAST_GRADE" != "null" ]; then
59
- # Classify per Norman + Ogilvy guidance (ticket #935 target shift):
60
- # - Aim grade 8 for 80%+ of prose (was grade 8-9 pre-#935)
61
- # - Grade 10 is the ceiling for simple technical sentences
62
- # - Sentences above 10 need EXPLICIT justification
63
- GRADE_STATUS=$(python3 -c "
64
- g = float('$LAST_GRADE')
65
- if g <= 8: print('ON TARGET (grade 8 or below)')
66
- elif g <= 9: print('SLIGHTLY ABOVE (target grade 8; ceiling 10) — trim one clause or drop a compound noun')
67
- elif g <= 10: print('AT THE GRADE-10 CEILING — tighten sentences and drop compound nouns to land at 8')
68
- else: print('ABOVE THE GRADE-10 CEILING — rewrite in short SVO. Any sentence above 10 needs a clear reason grades 8-10 could not say it')
69
- " 2>/dev/null)
70
-
71
- # Ship 1 #1312: extract top 3 offender sentences that broke grade 10.
72
- # Named offenders replace aggregate score as actionable signal.
73
- OFFENDERS_LINE=""
74
- OFFENDERS_COUNT=$(jq -r '.top_offenders | length' "$GRADE_MARKER" 2>/dev/null)
75
- if [ -n "$OFFENDERS_COUNT" ] && [ "$OFFENDERS_COUNT" != "null" ] && [ "$OFFENDERS_COUNT" -gt 0 ] 2>/dev/null; then
76
- OFFENDERS_BULLETS=$(jq -r '.top_offenders[] | "- Grade \(.grade), \(.words) words: \"\(.preview)\""' "$GRADE_MARKER" 2>/dev/null)
77
- OFFENDERS_LINE="
78
-
79
- **Top ${OFFENDERS_COUNT} sentence(s) from LAST turn above grade 10 — rewrite these first this turn:**
80
- ${OFFENDERS_BULLETS}"
81
- fi
82
-
83
- GRADE_LINE="
84
-
85
- **From your LAST turn (not this one): grade ${LAST_GRADE} (${LAST_WORDS} words). Target: grade 8 for 80%+ of prose. Ceiling: 10 for simple technical sentences. ${GRADE_STATUS}. THIS turn is not measured yet — self-check each sentence before I ship it.** (Per #1044 Option B: post-turn measurement + pre-turn injection means the number I see is one turn old by design.)${OFFENDERS_LINE}"
86
- if [ "$SOURCE" = "FALLBACK" ]; then
87
- FALLBACK_WARNING="
88
-
89
- **textstat not installed; grade uses the hand-rolled fallback. Numbers are approximate. Run \`pip install textstat\` for the sharper score.**"
90
- fi
91
- fi
92
- fi
93
-
94
- # === Read rewrite-check flags marker (ticket #935 extension) ===
95
- if [ -f "$FLAGS_MARKER" ]; then
96
- FL_WORDS=$(jq -r '.total_words // 0' "$FLAGS_MARKER" 2>/dev/null)
97
- FL_LONG=$(jq -r '.long_sentences // 0' "$FLAGS_MARKER" 2>/dev/null)
98
- FL_PASSIVE=$(jq -r '.passive_voice // 0' "$FLAGS_MARKER" 2>/dev/null)
99
- FL_HYPHEN=$(jq -r '.hyphen_words // 0' "$FLAGS_MARKER" 2>/dev/null)
100
- # Only inject the flags line when something caught the writer's attention
101
- if [ "$FL_LONG" != "0" ] || [ "$FL_PASSIVE" != "0" ] || [ "$FL_HYPHEN" != "0" ]; then
102
- FLAGS_LINE="
103
-
104
- **From your LAST turn (not this one) — hit counts.** Long sentences past 25 words: ${FL_LONG}. Passive voice: ${FL_PASSIVE}. Hyphen words: ${FL_HYPHEN}. THIS turn is not measured yet — I check each sentence before I ship it."
105
- fi
106
- fi
107
-
108
- # === Emit steering content ===
109
- # Extension per ticket #935 — first-person Ogilvy compose tests
110
- # grounded in standards/ogilvy-writing-rules.md (from #934 PR #938)
111
- STEERING_CONTENT="**Plain English for anything the operator or an adopter reads:**
112
-
113
- For turn output, PR body, issue body, session log, journal entry, and skill output:
114
-
115
- - Bassclef aims for grade 8 in most prose. Grade 10 is the top limit for simple technical sentences.
116
- - Above grade 10, give a clear reason grades 8-10 could not say it. A technical topic on its own is not a reason.
117
- - Short sentences. Subject-verb-object.
118
- - If I want to use a hyphen word (X-side, X-as-Y, N-layer X, X gate), I write what it does instead.
119
- - No more than two nouns in a row without a verb between them.
120
- - Drop words that only bassclef readers know — see standards/bassclef-internal-jargon.md.
121
- - Keep standard tech words: API, hook, PR, schema, ORM.
122
-
123
- **Vocabulary rename active (per ADR-040 D1; grace window through 2026-10-31):**
124
-
125
- When I author NEW prose for the operator or an adopter, I use the new terms:
126
-
127
- - Say **goal** not **bet**. (Historical goal IDs like \`bet 08-11a\` stay as-is.)
128
- - Say **step** not **WU** or **workunit**. (Historical \`WU-2\` refs stay.)
129
- - Say **in_flight_goal** not **in_flight_bet** for new whereami updates.
130
- - Say **time budget** not **appetite** for new prose.
131
- - Say **parent goal** and **thread** not **parent bet** and **arc** for new prose.
132
-
133
- **Discrimination cue.** Two situations, two different rules:
134
-
135
- 1. When I AUTHOR — writing my own sentence about work in flight or scope decisions — I use the new terms (Step-N, goal, time budget). Never introduce \`WU-N\` or \`bet\` or \`appetite\` in new prose.
136
- 2. When I QUOTE a past goal ID or reference (\`bet 27c WU-5\`, \`bet 2026-06-20a WU-1\`) — I preserve the exact historical string verbatim inside backticks. The backticks mark the historical boundary. The reader sees \"quote\" not \"active vocabulary.\"
137
-
138
- Rule of thumb: if I am about to type \`WU-\` in a sentence, ask — am I quoting a historical goal ID? If yes, wrap in backticks. If no, use Step-N instead.
139
-
140
- Historical mentions (past goal IDs, closed PR bodies, archived session logs) keep the old words — read-through via \`standards/vocabulary-migration.json\`.
141
-
142
- **Compose check this turn (per Ogilvy + Roman-Raphaelson via standards/ogilvy-writing-rules.md).**
143
- Before I write each sentence, I ask:
144
-
145
- - Natural voice — would a real person say this to a peer? If it sounds like corporate throat-clearing, rewrite.
146
- - Short units — is this sentence past 25 words? If yes, split.
147
- - Read-aloud — when I read this in my head, does it stumble? If yes, rewrite until it flows.
148
- - Completeness — is the ONE thing the reader needs to take from this actually written down in plain language?
149
- - Honesty — am I saying what I mean or hiding behind hedge words and euphemisms? Say it straight.
150
- - Facts with context — for each number or fact, did I say why it matters?
151
-
152
- Per bassclef#790 + .claude/rules/operator-facing-prose.md + .claude/rules/writing-craft-discipline.md.${GRADE_LINE}${FLAGS_LINE}${FALLBACK_WARNING}"
153
-
154
- # Use emit_additional_context to wrap as JSON envelope
155
- emit_additional_context "UserPromptSubmit" "$STEERING_CONTENT"
156
- exit 0