@thebassclef/lite 0.0.1 → 0.1.2

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 (289) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +85 -4
  3. package/dist/cli.cjs +1612 -0
  4. package/dist/cli.js +1589 -0
  5. package/dist/index.cjs +4 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +4 -0
  8. package/package.json +51 -3
  9. package/substrate/.bassclef/lite-manifest.json +2701 -0
  10. package/substrate/.claude/agents/architect.md +70 -0
  11. package/substrate/.claude/agents/builder.md +114 -0
  12. package/substrate/.claude/agents/designer.md +156 -0
  13. package/substrate/.claude/agents/reviewer.md +88 -0
  14. package/substrate/.claude/hooks/artifact-ingestion-gate.sh +357 -0
  15. package/substrate/.claude/hooks/assert-verify-steering.sh +77 -0
  16. package/substrate/.claude/hooks/bassclef-source-config-validate.sh +215 -0
  17. package/substrate/.claude/hooks/bassclef-sync.sh +634 -0
  18. package/substrate/.claude/hooks/compound-noun-scrub.sh +292 -0
  19. package/substrate/.claude/hooks/kiss-expansion-inject.sh +69 -0
  20. package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +492 -0
  21. package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +492 -0
  22. package/substrate/.claude/hooks/plain-english-steering.sh +156 -0
  23. package/substrate/.claude/hooks/post-skill-friction-check.sh +177 -0
  24. package/substrate/.claude/hooks/post-skill-telemetry.sh +62 -0
  25. package/substrate/.claude/hooks/pre-build-gate.sh +511 -0
  26. package/substrate/.claude/hooks/pre-commit-gate.sh +451 -0
  27. package/substrate/.claude/hooks/session-end.sh +433 -0
  28. package/substrate/.claude/hooks/session-reflection.sh +303 -0
  29. package/substrate/.claude/hooks/skill-body-grade-gate.sh +219 -0
  30. package/substrate/.claude/hooks/skill-body-intent-drift.sh +107 -0
  31. package/substrate/.claude/hooks/skill-step-list-check.sh +171 -0
  32. package/substrate/.claude/hooks/state-validate.sh +271 -0
  33. package/substrate/.claude/hooks/substrate-clarity-gate.sh +1110 -0
  34. package/substrate/.claude/hooks/temperance-gate.sh +147 -0
  35. package/substrate/.claude/hooks/testing-tier-enforce.sh +233 -0
  36. package/substrate/.claude/hooks/turn-prose-grade-measure.sh +219 -0
  37. package/substrate/.claude/hooks/turn-prose-kiss-check.sh +463 -0
  38. package/substrate/.claude/hooks/vocabulary-migration-check.sh +171 -0
  39. package/substrate/.claude/hooks/whereami-utc-gate.sh +142 -0
  40. package/substrate/.claude/luminaries/alan-cooper.md +170 -0
  41. package/substrate/.claude/luminaries/alistair-cockburn.md +140 -0
  42. package/substrate/.claude/luminaries/amazon-pr-faq.md +34 -0
  43. package/substrate/.claude/luminaries/ash-maurya.md +121 -0
  44. package/substrate/.claude/luminaries/bill-buxton.md +210 -0
  45. package/substrate/.claude/luminaries/charles-sanders-peirce.md +150 -0
  46. package/substrate/.claude/luminaries/david-ogilvy.md +192 -0
  47. package/substrate/.claude/luminaries/don-norman.md +173 -0
  48. package/substrate/.claude/luminaries/edward-tufte.md +179 -0
  49. package/substrate/.claude/luminaries/eric-evans.md +160 -0
  50. package/substrate/.claude/luminaries/frederick-brooks.md +50 -0
  51. package/substrate/.claude/luminaries/gang-of-four.md +157 -0
  52. package/substrate/.claude/luminaries/glenford-myers.md +230 -0
  53. package/substrate/.claude/luminaries/hunt-thomas.md +115 -0
  54. package/substrate/.claude/luminaries/hyrum-wright.md +94 -0
  55. package/substrate/.claude/luminaries/jason-fried-dhh.md +46 -0
  56. package/substrate/.claude/luminaries/jesse-james-garrett.md +154 -0
  57. package/substrate/.claude/luminaries/john-ousterhout.md +94 -0
  58. package/substrate/.claude/luminaries/karl-popper.md +132 -0
  59. package/substrate/.claude/luminaries/kent-beck.md +168 -0
  60. package/substrate/.claude/luminaries/linus-torvalds.md +218 -0
  61. package/substrate/.claude/luminaries/martin-fowler.md +164 -0
  62. package/substrate/.claude/luminaries/michael-feathers.md +125 -0
  63. package/substrate/.claude/luminaries/michael-nygard.md +118 -0
  64. package/substrate/.claude/luminaries/robert-c-martin.md +164 -0
  65. package/substrate/.claude/luminaries/saltzer-schroeder.md +194 -0
  66. package/substrate/.claude/luminaries/sophia-prater.md +193 -0
  67. package/substrate/.claude/luminaries/stephen-toulmin.md +131 -0
  68. package/substrate/.claude/luminaries/tony-hoare.md +170 -0
  69. package/substrate/.claude/luminaries/vaughn-vernon.md +50 -0
  70. package/substrate/.claude/luminaries/w-edwards-deming.md +158 -0
  71. package/substrate/.claude/rules/accessor-library-discipline.md +138 -0
  72. package/substrate/.claude/rules/adr-discipline.md +120 -0
  73. package/substrate/.claude/rules/api-conventions.md +125 -0
  74. package/substrate/.claude/rules/artifact-ingestion.md +179 -0
  75. package/substrate/.claude/rules/assert-only-after-verify.md +137 -0
  76. package/substrate/.claude/rules/blocked-items.md +146 -0
  77. package/substrate/.claude/rules/bootstrap-pair-discipline.md +141 -0
  78. package/substrate/.claude/rules/branching.md +28 -0
  79. package/substrate/.claude/rules/cold-adopter-harness-discipline.md +129 -0
  80. package/substrate/.claude/rules/commit-conventions.md +22 -0
  81. package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +188 -0
  82. package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +188 -0
  83. package/substrate/.claude/rules/context-engineering.md +202 -0
  84. package/substrate/.claude/rules/context-management.md +85 -0
  85. package/substrate/.claude/rules/defensive-bash.md +68 -0
  86. package/substrate/.claude/rules/deferred-actions.md +233 -0
  87. package/substrate/.claude/rules/destructive-operations.md +69 -0
  88. package/substrate/.claude/rules/diagnosis.md +38 -0
  89. package/substrate/.claude/rules/github-issue-flash-tweet.md +156 -0
  90. package/substrate/.claude/rules/guardrails.md +73 -0
  91. package/substrate/.claude/rules/hook-wire-on-author.md +103 -0
  92. package/substrate/.claude/rules/identifier-leak-prevention.md +104 -0
  93. package/substrate/.claude/rules/iteration-bet-brief-completeness.md +54 -0
  94. package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +98 -0
  95. package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +89 -0
  96. package/substrate/.claude/rules/loop-discipline.md +81 -0
  97. package/substrate/.claude/rules/manual-prod-approval.md +100 -0
  98. package/substrate/.claude/rules/marker-enrichment-discipline.md +99 -0
  99. package/substrate/.claude/rules/mobile-ephemeral-session.md +109 -0
  100. package/substrate/.claude/rules/new-dependency-check.md +51 -0
  101. package/substrate/.claude/rules/oo-ad-entry-point.md +117 -0
  102. package/substrate/.claude/rules/operator-facing-prose.md +196 -0
  103. package/substrate/.claude/rules/option-label-discipline.md +108 -0
  104. package/substrate/.claude/rules/pattern-annotation.md +100 -0
  105. package/substrate/.claude/rules/plain-english-discipline.md +156 -0
  106. package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +211 -0
  107. package/substrate/.claude/rules/pr-body-shape.md +317 -0
  108. package/substrate/.claude/rules/pr-strategy.md +167 -0
  109. package/substrate/.claude/rules/pr-title-shape.md +161 -0
  110. package/substrate/.claude/rules/prototype-workflow.md +65 -0
  111. package/substrate/.claude/rules/reserved-skill-names.md +123 -0
  112. package/substrate/.claude/rules/schema-management.md +49 -0
  113. package/substrate/.claude/rules/sdlc-gates.md +149 -0
  114. package/substrate/.claude/rules/security.md +37 -0
  115. package/substrate/.claude/rules/session-artifacts.md +236 -0
  116. package/substrate/.claude/rules/skill-composition-declarations.md +124 -0
  117. package/substrate/.claude/rules/skill-description-clarity.md +247 -0
  118. package/substrate/.claude/rules/skill-procedure-step-list.md +137 -0
  119. package/substrate/.claude/rules/state-schema-validation.md +162 -0
  120. package/substrate/.claude/rules/stuck-signal-diagnostic.md +140 -0
  121. package/substrate/.claude/rules/substrate-config-schema.md +98 -0
  122. package/substrate/.claude/rules/test-list-discipline.md +175 -0
  123. package/substrate/.claude/rules/test-sufficiency.md +210 -0
  124. package/substrate/.claude/rules/testing-tier-config.md +145 -0
  125. package/substrate/.claude/rules/testing.md +38 -0
  126. package/substrate/.claude/rules/turn-estimate-grounding.md +134 -0
  127. package/substrate/.claude/rules/visual-hierarchy.md +437 -0
  128. package/substrate/.claude/rules/we-dont-break-adopters.md +126 -0
  129. package/substrate/.claude/rules/whereami-load-bearing.md +202 -0
  130. package/substrate/.claude/rules/writing-craft-discipline.md +92 -0
  131. package/substrate/.claude/rules/wu-sequencing-compounds.md +145 -0
  132. package/substrate/.claude/skills/build/SKILL.md +640 -0
  133. package/substrate/.claude/skills/chronicle/SKILL.md +55 -0
  134. package/substrate/.claude/skills/clean-artifacts/SKILL.md +249 -0
  135. package/substrate/.claude/skills/decompose/SKILL.md +280 -0
  136. package/substrate/.claude/skills/diagnose/SKILL.md +297 -0
  137. package/substrate/.claude/skills/feynman/SKILL.md +90 -0
  138. package/substrate/.claude/skills/howdoi/SKILL.md +105 -0
  139. package/substrate/.claude/skills/ia-model/SKILL.md +108 -0
  140. package/substrate/.claude/skills/interaction-design/SKILL.md +112 -0
  141. package/substrate/.claude/skills/interpret-input/SKILL.md +180 -0
  142. package/substrate/.claude/skills/journal/SKILL.md +209 -0
  143. package/substrate/.claude/skills/kiss/SKILL.md +449 -0
  144. package/substrate/.claude/skills/launch/SKILL.md +915 -0
  145. package/substrate/.claude/skills/lean-canvas/SKILL.md +332 -0
  146. package/substrate/.claude/skills/longrun/SKILL.md +463 -0
  147. package/substrate/.claude/skills/luminary/SKILL.md +481 -0
  148. package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +177 -0
  149. package/substrate/.claude/skills/onboard-repo/SKILL.md +1624 -0
  150. package/substrate/.claude/skills/pattern-review/SKILL.md +99 -0
  151. package/substrate/.claude/skills/personas/SKILL.md +207 -0
  152. package/substrate/.claude/skills/promote/SKILL.md +283 -0
  153. package/substrate/.claude/skills/requirement/SKILL.md +98 -0
  154. package/substrate/.claude/skills/retro/SKILL.md +117 -0
  155. package/substrate/.claude/skills/riff/SKILL.md +114 -0
  156. package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +163 -0
  157. package/substrate/.claude/skills/session-end/SKILL.md +309 -0
  158. package/substrate/.claude/skills/session-log/SKILL.md +299 -0
  159. package/substrate/.claude/skills/skills/SKILL.md +228 -0
  160. package/substrate/.claude/skills/spec/SKILL.md +105 -0
  161. package/substrate/.claude/skills/sprint/SKILL.md +392 -0
  162. package/substrate/.claude/skills/stage/SKILL.md +384 -0
  163. package/substrate/.claude/skills/state-a-problem/SKILL.md +185 -0
  164. package/substrate/.claude/skills/temperance/SKILL.md +108 -0
  165. package/substrate/.claude/skills/use-case/SKILL.md +417 -0
  166. package/substrate/.claude/skills/user-stories/SKILL.md +268 -0
  167. package/substrate/.claude/skills/value-prop/SKILL.md +251 -0
  168. package/substrate/.claude/skills/verify/SKILL.md +160 -0
  169. package/substrate/.claude/skills/visual-review/SKILL.md +503 -0
  170. package/substrate/.claude/skills/whats-the-plan/SKILL.md +202 -0
  171. package/substrate/.claude/skills/whereami/SKILL.md +307 -0
  172. package/substrate/AGENTS.md +79 -0
  173. package/substrate/CLAUDE-lite.md +85 -0
  174. package/substrate/CODE_OF_CONDUCT.md +28 -0
  175. package/substrate/CONTRIBUTING.md +177 -0
  176. package/substrate/README.md +173 -0
  177. package/substrate/SECURITY.md +19 -0
  178. package/substrate/architecture/decisions/ADR-029-release-pipeline.md +79 -0
  179. package/substrate/architecture/decisions/ADR-031-non-breaking-changes-adopter-discipline.md +139 -0
  180. package/substrate/architecture/decisions/ADR-032-adopter-sync-dispatcher-architecture.md +192 -0
  181. package/substrate/architecture/decisions/ADR-039-release-tagging-scheme.md +145 -0
  182. package/substrate/architecture/decisions/ADR-040-planning-skill-vocabulary-and-lite-profile.md +155 -0
  183. package/substrate/architecture/decisions/ADR-044-unified-skill-body-template.md +162 -0
  184. package/substrate/lib/clean-artifacts-sweep.sh +112 -0
  185. package/substrate/lib/code-comment-discipline.sh +144 -0
  186. package/substrate/lib/composer-preflight.sh +459 -0
  187. package/substrate/lib/hook-inject.sh +255 -0
  188. package/substrate/lib/luminary-pick.sh +96 -0
  189. package/substrate/lib/output-discipline.sh +143 -0
  190. package/substrate/lib/prose-scan-boundary.sh +171 -0
  191. package/substrate/lib/rewrite-check.sh +214 -0
  192. package/substrate/lib/state.sh +1372 -0
  193. package/substrate/lib/telemetry.sh +205 -0
  194. package/substrate/lib/tier-check.sh +187 -0
  195. package/substrate/lib/tier-dependency-audit.sh +1088 -0
  196. package/substrate/presence/install/bassclef-hook-connect.sh +178 -0
  197. package/substrate/presence/install/bassclef-sync.dispatcher.template.sh +841 -0
  198. package/substrate/presence/install/bassclef-sync.template.sh +2076 -0
  199. package/substrate/presence/install/schedule-auto-save.cron.sh +88 -0
  200. package/substrate/presence/install/schedule-auto-save.taskscheduler.md +122 -0
  201. package/substrate/scripts/aggregate-telemetry.sh +217 -0
  202. package/substrate/scripts/analyze-tier-dependencies.sh +239 -0
  203. package/substrate/scripts/generate-lite-manifest.sh +505 -0
  204. package/substrate/scripts/generate-tier-manifest.sh +28 -0
  205. package/substrate/scripts/intent-drift-check.sh +456 -0
  206. package/substrate/scripts/lite-manifest-drift-check.sh +146 -0
  207. package/substrate/scripts/render-lite-manifest-doc.sh +150 -0
  208. package/substrate/standards/adr-template.md +86 -0
  209. package/substrate/standards/api-conventions/nextjs.md +84 -0
  210. package/substrate/standards/artifact-composition.md +209 -0
  211. package/substrate/standards/bash-hook-safety.md +246 -0
  212. package/substrate/standards/bassclef-configs-schema.md +232 -0
  213. package/substrate/standards/bassclef-evolution.md +143 -0
  214. package/substrate/standards/bassclef-internal-jargon.md +244 -0
  215. package/substrate/standards/bassclef-managed-sentinel.md +96 -0
  216. package/substrate/standards/bassclef-source-config.md +228 -0
  217. package/substrate/standards/branch-stacking.md +408 -0
  218. package/substrate/standards/code-safety-principles.md +176 -0
  219. package/substrate/standards/composer-prerequisites.md +155 -0
  220. package/substrate/standards/deferred-actions-schema.md +204 -0
  221. package/substrate/standards/dependency-discipline/cargo.md +39 -0
  222. package/substrate/standards/dependency-discipline/gem.md +43 -0
  223. package/substrate/standards/dependency-discipline/go-mod.md +41 -0
  224. package/substrate/standards/dependency-discipline/npm.md +42 -0
  225. package/substrate/standards/dependency-discipline/pip.md +42 -0
  226. package/substrate/standards/deployment-topology/ec2-tailscale.md +225 -0
  227. package/substrate/standards/deployment-topology.md +69 -0
  228. package/substrate/standards/docs-sync-allowlist.md +76 -0
  229. package/substrate/standards/domain-and-dns.md +145 -0
  230. package/substrate/standards/frontend-stack.md +67 -0
  231. package/substrate/standards/frontmatter-schema.md +154 -0
  232. package/substrate/standards/graceful-exit.md +227 -0
  233. package/substrate/standards/hook-idempotency.md +102 -0
  234. package/substrate/standards/hook-injection-discipline.md +202 -0
  235. package/substrate/standards/hook-install-class.md +215 -0
  236. package/substrate/standards/input-handler-interface.md +152 -0
  237. package/substrate/standards/lite-manifest-schema-changes.md +135 -0
  238. package/substrate/standards/luminary-matching.md +105 -0
  239. package/substrate/standards/luminary-problem-patterns.md +481 -0
  240. package/substrate/standards/migration-discipline/active-record.md +50 -0
  241. package/substrate/standards/migration-discipline/alembic.md +43 -0
  242. package/substrate/standards/migration-discipline/gorm.md +50 -0
  243. package/substrate/standards/migration-discipline/prisma.md +53 -0
  244. package/substrate/standards/migration-discipline/sqlalchemy.md +51 -0
  245. package/substrate/standards/mobile-ephemeral-session.md +167 -0
  246. package/substrate/standards/model-routing-discipline.md +160 -0
  247. package/substrate/standards/ogilvy-writing-rules.md +225 -0
  248. package/substrate/standards/opener-discipline.md +96 -0
  249. package/substrate/standards/operator-facing-prose-discipline.md +201 -0
  250. package/substrate/standards/persona-schema.md +229 -0
  251. package/substrate/standards/pluggable-luminaries.md +323 -0
  252. package/substrate/standards/pr-body-discipline.md +115 -0
  253. package/substrate/standards/preview-state-schema.md +189 -0
  254. package/substrate/standards/project-directory-layout.md +276 -0
  255. package/substrate/standards/release-tagging.md +137 -0
  256. package/substrate/standards/reserved-skill-names.md +120 -0
  257. package/substrate/standards/scannable-multi-option-output.md +261 -0
  258. package/substrate/standards/sdlc-compliance.md +286 -0
  259. package/substrate/standards/sdlc-gates/typescript.md +57 -0
  260. package/substrate/standards/secrets-lifecycle.md +210 -0
  261. package/substrate/standards/security-scanner-adapter.md +145 -0
  262. package/substrate/standards/session-board.md +256 -0
  263. package/substrate/standards/skill-output-discipline.md +90 -0
  264. package/substrate/standards/state-spine-contract.md +255 -0
  265. package/substrate/standards/state-spine.md +511 -0
  266. package/substrate/standards/steering-hints/kiss-words.md +11 -0
  267. package/substrate/standards/substrate-config-schema.md +267 -0
  268. package/substrate/standards/tech-stack-config.md +109 -0
  269. package/substrate/standards/tier-dependency-analysis.md +167 -0
  270. package/substrate/standards/tier-runtime-deps/lite.md +57 -0
  271. package/substrate/standards/tier-tag-schema.md +155 -0
  272. package/substrate/standards/two-layer-config.md +99 -0
  273. package/substrate/standards/use-case-format.md +292 -0
  274. package/substrate/standards/user-story-invest.md +268 -0
  275. package/substrate/standards/velocity-and-appetite.md +229 -0
  276. package/substrate/standards/voice-input-pattern.md +119 -0
  277. package/substrate/standards/whereami-schema.md +301 -0
  278. package/substrate/standards/worktree-management.md +211 -0
  279. package/substrate/standards/writing-guide.md +213 -0
  280. package/substrate/templates/chronicle-template.md +75 -0
  281. package/substrate/templates/deferred-action-template.md +45 -0
  282. package/substrate/templates/memory-proposal-template.md +77 -0
  283. package/substrate/templates/persona-template.md +200 -0
  284. package/substrate/templates/pr-faq.md +45 -0
  285. package/substrate/templates/secret-rotation-template.md +162 -0
  286. package/substrate/templates/spec-template.md +131 -0
  287. package/substrate/templates/use-case-template.md +194 -0
  288. package/substrate/templates/user-story-template.md +107 -0
  289. package/substrate/templates/whereami-template.md +101 -0
@@ -0,0 +1,459 @@
1
+ #!/usr/bin/env bash
2
+ # tier: lite
3
+ # lib/composer-preflight.sh — shared pre-flight check for composer skills.
4
+ #
5
+ # Composer skills (/launch, /build, /shape full) source this helper
6
+ # in Phase -1 (before Phase 0). Surfaces 6 prerequisites at once:
7
+ # 1. feature-branch — repo on a feature branch (refuses on main)
8
+ # 2. state-spine — lib/state.sh present (AUTO-PREP from bassclef)
9
+ # 3. personas — at least 1 persona scaffolded (signal-and-offer)
10
+ # 4. budget — iteration_ceiling sufficient for estimate
11
+ # 5. skill-registry — dispatching skill resolves (covers bassclef#271)
12
+ # 6. deploy-host — hosting_platform set + adapter shipped (bassclef#449/#450)
13
+ #
14
+ # Usage (from a composer SKILL.md procedure):
15
+ # source $BASSCLEF_DIR/lib/composer-preflight.sh
16
+ # composer_preflight_check <skill_name> <estimated_turns> [--no-launch]
17
+ # case $? in
18
+ # 0) ;; # all pass — proceed to Phase 0
19
+ # 1) ;; # warnings — composer prompts operator proceed/abort
20
+ # 2) exit 1 ;; # failures — composer refuses dispatch
21
+ # esac
22
+ #
23
+ # --no-launch: variants-only run; Check 6 short-circuits to pass.
24
+ # Use when /launch is invoked for variant generation only,
25
+ # no deploy-host chain. /stage (light) is the typical caller.
26
+ #
27
+ # Override: SKIP_COMPOSER_PREFLIGHT=1 (logged via trace-helper).
28
+ #
29
+ # Standard: standards/composer-prerequisites.md
30
+ # Refs bassclef#408 (preflight scaffold) + bassclef#449/#450 (deploy-host check).
31
+
32
+ # Don't use `set -e` — preflight checks must complete even when one fails.
33
+
34
+ # Output format (key=value lines on stdout):
35
+ # check_<n>_name=<check name>
36
+ # check_<n>_status=<pass|warn|fail>
37
+ # check_<n>_message=<single-line message>
38
+ # check_<n>_recommendation=<single-line recommendation>
39
+ # summary_status=<pass|warn|fail>
40
+ # summary_count_pass=<n>
41
+ # summary_count_warn=<n>
42
+ # summary_count_fail=<n>
43
+
44
+ composer_preflight_check() {
45
+ local skill_name="${1:-}"
46
+ local estimated_turns="${2:-50}"
47
+ local mode_flag="${3:-}" # optional: --no-launch for variants-only runs
48
+
49
+ # Override hatch
50
+ if [ "${SKIP_COMPOSER_PREFLIGHT:-0}" = "1" ]; then
51
+ if command -v trace_log >/dev/null 2>&1; then
52
+ trace_log "composer-preflight" "OVERRIDE skill=$skill_name" 2>/dev/null || true
53
+ fi
54
+ echo "summary_status=skip"
55
+ return 0
56
+ fi
57
+
58
+ if [ -z "$skill_name" ]; then
59
+ echo "summary_status=fail" >&2
60
+ echo "ERROR: composer_preflight_check requires skill_name" >&2
61
+ return 2
62
+ fi
63
+
64
+ local pass=0 warn=0 fail=0
65
+
66
+ # === Check 1: feature-branch ===
67
+ local current_branch
68
+ current_branch=$(git branch --show-current 2>/dev/null || echo "")
69
+ echo "check_1_name=feature-branch"
70
+ if [ -z "$current_branch" ]; then
71
+ echo "check_1_status=fail"
72
+ echo "check_1_message=Not in a git repository OR branch detection failed"
73
+ echo "check_1_recommendation=Run from inside a git repository"
74
+ fail=$((fail + 1))
75
+ elif [ "$current_branch" = "main" ] || [ "$current_branch" = "master" ]; then
76
+ echo "check_1_status=fail"
77
+ echo "check_1_message=On $current_branch — composer skills refuse to run from default branch"
78
+ echo "check_1_recommendation=git checkout -b feature/<slug>"
79
+ fail=$((fail + 1))
80
+ else
81
+ echo "check_1_status=pass"
82
+ echo "check_1_message=On feature branch: $current_branch"
83
+ echo "check_1_recommendation="
84
+ pass=$((pass + 1))
85
+ fi
86
+
87
+ # === Check 2: state-spine ===
88
+ local repo_root
89
+ repo_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
90
+ echo "check_2_name=state-spine"
91
+ if [ -f "$repo_root/lib/state.sh" ]; then
92
+ echo "check_2_status=pass"
93
+ echo "check_2_message=lib/state.sh present"
94
+ echo "check_2_recommendation="
95
+ pass=$((pass + 1))
96
+ else
97
+ # Auto-prep available: bootstrap from BASSCLEF_DIR if reachable
98
+ local bassclef_state="${BASSCLEF_DIR:-}/lib/state.sh"
99
+ if [ -n "${BASSCLEF_DIR:-}" ] && [ -f "$bassclef_state" ]; then
100
+ echo "check_2_status=warn"
101
+ echo "check_2_message=lib/state.sh missing; AUTO-PREP available from $bassclef_state"
102
+ echo "check_2_recommendation=cp $bassclef_state $repo_root/lib/state.sh # safe to auto-execute"
103
+ warn=$((warn + 1))
104
+ else
105
+ echo "check_2_status=fail"
106
+ echo "check_2_message=lib/state.sh missing AND BASSCLEF_DIR not reachable"
107
+ echo "check_2_recommendation=Run /onboard-repo to bootstrap bassclef substrate"
108
+ fail=$((fail + 1))
109
+ fi
110
+ fi
111
+
112
+ # === Check 3: personas ===
113
+ echo "check_3_name=personas"
114
+ local persona_count=0
115
+ if [ -d "$repo_root/docs/personas" ]; then
116
+ persona_count=$(find "$repo_root/docs/personas" -maxdepth 1 -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ')
117
+ fi
118
+ if [ "$persona_count" -ge 1 ]; then
119
+ echo "check_3_status=pass"
120
+ echo "check_3_message=$persona_count persona(s) scaffolded"
121
+ echo "check_3_recommendation="
122
+ pass=$((pass + 1))
123
+ else
124
+ echo "check_3_status=warn"
125
+ echo "check_3_message=No personas scaffolded; composers default to operator-as-persona"
126
+ echo "check_3_recommendation=Run /personas to seed primary persona OR proceed with operator-only"
127
+ warn=$((warn + 1))
128
+ fi
129
+
130
+ # === Check 4: budget ===
131
+ echo "check_4_name=budget"
132
+ local budget_estimate=$(( estimated_turns * 10 / 100 )) # rough $0.10/turn proxy
133
+ local ceiling=""
134
+ if [ -f "$repo_root/substrate.config.md" ]; then
135
+ # Use [[:space:]] (POSIX) instead of \s (GNU extension) for BSD sed compat
136
+ ceiling=$(grep -E '^[[:space:]]*iteration_ceiling:' "$repo_root/substrate.config.md" 2>/dev/null \
137
+ | head -1 | sed 's/.*:[[:space:]]*//;s/[[:space:]].*//;s/^\$//' || echo "")
138
+ fi
139
+ if [ -z "$ceiling" ] || [ "$ceiling" = "0" ]; then
140
+ # Sequential mode (no burst cost) — pass
141
+ echo "check_4_status=pass"
142
+ echo "check_4_message=Sequential mode (\$0 burst); estimated $estimated_turns turns"
143
+ echo "check_4_recommendation="
144
+ pass=$((pass + 1))
145
+ elif ! [[ "$ceiling" =~ ^[0-9]+$ ]]; then
146
+ # Non-numeric ceiling (e.g., free-form description) — pass with note
147
+ echo "check_4_status=pass"
148
+ echo "check_4_message=iteration_ceiling: $ceiling (free-form); estimated $estimated_turns turns"
149
+ echo "check_4_recommendation="
150
+ pass=$((pass + 1))
151
+ elif [ "$ceiling" -lt "$budget_estimate" ]; then
152
+ echo "check_4_status=warn"
153
+ echo "check_4_message=iteration_ceiling \$$ceiling < estimated \$$budget_estimate ($estimated_turns turns)"
154
+ echo "check_4_recommendation=Bump iteration_ceiling in substrate.config.md OR reduce composer tier"
155
+ warn=$((warn + 1))
156
+ else
157
+ echo "check_4_status=pass"
158
+ echo "check_4_message=iteration_ceiling \$$ceiling >= estimated \$$budget_estimate"
159
+ echo "check_4_recommendation="
160
+ pass=$((pass + 1))
161
+ fi
162
+
163
+ # === Check 5: skill-registry ===
164
+ # Detects bassclef#271 race — skill not picked up by harness registry.
165
+ # Read-and-check approach: the skill MUST exist as SKILL.md at a discoverable
166
+ # path. Three discovery paths:
167
+ # a) ~/.claude/skills/<skill>/SKILL.md (user-level symlink — harness primary)
168
+ # b) <repo>/.claude/skills/<skill>/SKILL.md (repo-level — fallback)
169
+ # c) <BASSCLEF_DIR>/.claude/skills/<skill>/SKILL.md (bassclef authoritative)
170
+ echo "check_5_name=skill-registry"
171
+ local user_skill="$HOME/.claude/skills/$skill_name/SKILL.md"
172
+ local repo_skill="$repo_root/.claude/skills/$skill_name/SKILL.md"
173
+ local bassclef_skill="${BASSCLEF_DIR:-}/.claude/skills/$skill_name/SKILL.md"
174
+
175
+ if [ -f "$user_skill" ] || [ -L "$user_skill" ]; then
176
+ echo "check_5_status=pass"
177
+ echo "check_5_message=Skill resolves at user-level: $user_skill"
178
+ echo "check_5_recommendation="
179
+ pass=$((pass + 1))
180
+ elif [ -f "$repo_skill" ] || [ -L "$repo_skill" ]; then
181
+ echo "check_5_status=warn"
182
+ echo "check_5_message=Skill at repo-level only ($repo_skill); user-level symlink missing — harness may not pick up (bassclef#271)"
183
+ echo "check_5_recommendation=Run bassclef-sync.sh to create user-level symlink OR restart Claude session"
184
+ warn=$((warn + 1))
185
+ elif [ -n "${BASSCLEF_DIR:-}" ] && [ -f "$bassclef_skill" ]; then
186
+ echo "check_5_status=warn"
187
+ echo "check_5_message=Skill at bassclef only; consumer-side links missing — substrate sync incomplete"
188
+ echo "check_5_recommendation=Run bassclef-sync.sh in this repo OR /onboard-repo"
189
+ warn=$((warn + 1))
190
+ else
191
+ echo "check_5_status=fail"
192
+ echo "check_5_message=Skill /$skill_name not found at any discovery path"
193
+ echo "check_5_recommendation=Verify skill name OR check bassclef substrate sync"
194
+ fail=$((fail + 1))
195
+ fi
196
+
197
+ # === Check 6: deploy-host (bassclef#449/#450 + bassclef#523) ===
198
+ #
199
+ # Reads hosting_platform from substrate.config.md and verifies (a) a deploy
200
+ # adapter is shipped AND (b) provisioning has actually happened (the
201
+ # per-platform provisioning-indicator field is populated with a real value,
202
+ # not the schema's bracketed placeholder). Catches the preview→production
203
+ # gap before /launch burns 200t AND the silent-defer-bind class
204
+ # where Phase 12 silently no-ops because the consumer never ran
205
+ # /provision-deploy-host (bassclef#523 — today's POA mobile session).
206
+ #
207
+ # Logic:
208
+ # missing hosting_platform → fail (set hosting_platform: amplify)
209
+ # hosting_platform=none + --no-launch → pass (variants-only run)
210
+ # hosting_platform=none + no --no-launch → fail (refuse dispatch)
211
+ # adapter shipped + indicator populated → pass
212
+ # adapter shipped + indicator MISSING → fail with three-path remediation:
213
+ # run /provision-deploy-host inline / re-dispatch with --no-launch /
214
+ # explicit defer
215
+ # adapter not shipped (vercel | netlify | cf-pages) → warn
216
+ # any other value → fail (not in enum)
217
+ #
218
+ # Per-platform provisioning indicators (set by /provision-deploy-host on success):
219
+ # amplify → amplify_app_id (e.g., d154l5usyc80nk)
220
+ # ec2-tailscale → deploy_host (e.g., poa-prod.tailnet.ts.net)
221
+ # mock → no indicator required (test scaffold)
222
+ #
223
+ # The override --no-launch lets /launch run in variants-only mode
224
+ # (e.g., /stage light callers) without requiring deploy-host provisioning.
225
+ echo "check_6_name=deploy-host"
226
+ local hosting=""
227
+ if [ -f "$repo_root/substrate.config.md" ]; then
228
+ hosting=$(grep -E '^[[:space:]]*hosting_platform:' "$repo_root/substrate.config.md" 2>/dev/null \
229
+ | head -1 | sed 's/.*:[[:space:]]*//;s/[[:space:]].*//;s/^["'\'']//;s/["'\'']$//')
230
+ fi
231
+ local bassclef_adapter_dir="${BASSCLEF_DIR:-}/scripts/adapters/deploy"
232
+ local adapter_check=""
233
+ if [ -n "$hosting" ] && [ -n "${BASSCLEF_DIR:-}" ]; then
234
+ adapter_check="${bassclef_adapter_dir}/${hosting}.sh"
235
+ fi
236
+
237
+ # Helper: read the per-platform provisioning-indicator field from
238
+ # substrate.config.md. Returns the field value if populated and not the
239
+ # bracketed placeholder shape (e.g., `[e.g., d154l...]`); empty otherwise.
240
+ _check6_provisioning_indicator_value() {
241
+ local field="$1"
242
+ [ -f "$repo_root/substrate.config.md" ] || return 0
243
+ local val
244
+ val=$(grep -E "^[[:space:]]*${field}:" "$repo_root/substrate.config.md" 2>/dev/null \
245
+ | head -1 | sed 's/.*:[[:space:]]*//;s/[[:space:]]*#.*$//;s/^["'\'']//;s/["'\'']$//')
246
+ # Reject placeholders (bracketed values are schema templates, not real values)
247
+ case "$val" in
248
+ "" | \[*\] | "[]" )
249
+ echo ""
250
+ ;;
251
+ *)
252
+ echo "$val"
253
+ ;;
254
+ esac
255
+ }
256
+
257
+ if [ -z "$hosting" ]; then
258
+ echo "check_6_status=fail"
259
+ echo "check_6_message=hosting_platform missing from substrate.config.md"
260
+ echo "check_6_recommendation=Add 'hosting_platform: amplify' (bassclef default per ADR-008) OR 'hosting_platform: none' if no UI ships"
261
+ fail=$((fail + 1))
262
+ elif [ "$hosting" = "none" ]; then
263
+ if [ "$mode_flag" = "--no-launch" ]; then
264
+ echo "check_6_status=pass"
265
+ echo "check_6_message=hosting_platform=none + --no-launch (variants-only run)"
266
+ echo "check_6_recommendation="
267
+ pass=$((pass + 1))
268
+ else
269
+ echo "check_6_status=fail"
270
+ echo "check_6_message=hosting_platform=none — composer would generate variants that can't launch"
271
+ echo "check_6_recommendation=Set hosting_platform to a deploy provider (amplify) OR re-run with --no-launch for variants-only"
272
+ fail=$((fail + 1))
273
+ fi
274
+ elif [ -n "$adapter_check" ] && [ -f "$adapter_check" ]; then
275
+ # Adapter shipped — now verify provisioning indicator is populated.
276
+ # --no-launch override skips this gate (variants-only run).
277
+ if [ "$mode_flag" = "--no-launch" ]; then
278
+ echo "check_6_status=pass"
279
+ echo "check_6_message=hosting_platform=$hosting + --no-launch (variants-only; provisioning indicator gate bypassed)"
280
+ echo "check_6_recommendation="
281
+ pass=$((pass + 1))
282
+ else
283
+ local indicator_field=""
284
+ case "$hosting" in
285
+ amplify) indicator_field="amplify_app_id" ;;
286
+ ec2-tailscale) indicator_field="deploy_host" ;;
287
+ mock) indicator_field="" ;; # test scaffold, no indicator required
288
+ esac
289
+ local indicator_value=""
290
+ if [ -n "$indicator_field" ]; then
291
+ indicator_value=$(_check6_provisioning_indicator_value "$indicator_field")
292
+ fi
293
+ if [ -z "$indicator_field" ] || [ -n "$indicator_value" ]; then
294
+ echo "check_6_status=pass"
295
+ if [ -n "$indicator_field" ]; then
296
+ echo "check_6_message=hosting_platform=$hosting; adapter shipped; ${indicator_field}=${indicator_value}"
297
+ else
298
+ echo "check_6_message=hosting_platform=$hosting; adapter shipped (no indicator required for $hosting)"
299
+ fi
300
+ echo "check_6_recommendation="
301
+ pass=$((pass + 1))
302
+ else
303
+ echo "check_6_status=fail"
304
+ echo "check_6_message=hosting_platform=$hosting; adapter shipped but ${indicator_field} not populated in substrate.config.md — /provision-deploy-host has not run for this consumer"
305
+ echo "check_6_recommendation=Three paths: (a) run /provision-deploy-host (creates ${hosting} app + populates ${indicator_field}; ~1-2h, mostly waiting); (b) re-dispatch with --no-launch for variants-only (no deploy host needed); (c) explicit defer — tell the agent 'skip launch deploy-host check this session' (per blocked-items.md deferral syntax)"
306
+ fail=$((fail + 1))
307
+ fi
308
+ fi
309
+ elif [ "$hosting" = "vercel" ] || [ "$hosting" = "netlify" ] || [ "$hosting" = "cloudflare-pages" ]; then
310
+ echo "check_6_status=warn"
311
+ echo "check_6_message=hosting_platform=$hosting in schema enum but adapter not yet shipped"
312
+ echo "check_6_recommendation=Switch to amplify (bassclef default) OR contribute the adapter at scripts/adapters/deploy/${hosting}.sh"
313
+ warn=$((warn + 1))
314
+ elif [ "$hosting" = "amplify" ] || [ "$hosting" = "ec2-tailscale" ] || [ "$hosting" = "mock" ]; then
315
+ # Known-good enum value but adapter not found at expected path — could be
316
+ # BASSCLEF_DIR pointing at the wrong place, or substrate sync incomplete
317
+ if [ -z "${BASSCLEF_DIR:-}" ]; then
318
+ echo "check_6_status=warn"
319
+ echo "check_6_message=hosting_platform=$hosting (BASSCLEF_DIR not reachable; can't verify adapter)"
320
+ echo "check_6_recommendation=Set BASSCLEF_DIR OR run /onboard-repo to sync bassclef substrate"
321
+ warn=$((warn + 1))
322
+ else
323
+ echo "check_6_status=warn"
324
+ echo "check_6_message=hosting_platform=$hosting in enum but adapter missing at $adapter_check"
325
+ echo "check_6_recommendation=Run bassclef-sync.sh to refresh adapter symlinks OR check BASSCLEF_DIR points at bassclef repo root"
326
+ warn=$((warn + 1))
327
+ fi
328
+ else
329
+ echo "check_6_status=fail"
330
+ echo "check_6_message=hosting_platform=$hosting not in schema enum"
331
+ echo "check_6_recommendation=Use one of: amplify | ec2-tailscale | vercel | netlify | cloudflare-pages | none"
332
+ fail=$((fail + 1))
333
+ fi
334
+
335
+ # === Check 7: spec-and-use-case (bet 24a Step 2c per Cockburn ceremony matrix) ===
336
+ # Fires when staged diff includes code paths that merit spec + use-case coverage.
337
+ # Warns if no artifact at docs/use-cases/UC-*.md OR docs/specs/*.md OR
338
+ # docs/decompositions/*.md when substrate + adopter code staged.
339
+ # Per .claude/rules/oo-ad-entry-point.md (extended to include hook/lib/script paths).
340
+ # Cockburn tiering — new hook + lib merit brief use case; app code merits fully-dressed.
341
+ echo "check_7_name=spec-and-use-case"
342
+ local staged_code
343
+ staged_code=$(git diff --cached --name-only --diff-filter=AM 2>/dev/null | grep -E \
344
+ -e '^src/.*\.(ts|tsx|js|py)$' \
345
+ -e '^\.claude/hooks/[^/]+\.sh$' \
346
+ -e '^lib/[^/]+\.sh$' \
347
+ -e '^scripts/[^/]+\.sh$' \
348
+ || true)
349
+ if [ -z "$staged_code" ]; then
350
+ echo "check_7_status=pass"
351
+ echo "check_7_message=No code paths staged (docs-only or non-code commit)"
352
+ echo "check_7_recommendation="
353
+ pass=$((pass + 1))
354
+ else
355
+ local uc_count spec_count decomp_count total_artifacts
356
+ uc_count=$(ls "$repo_root/docs/use-cases/"UC-*.md 2>/dev/null | wc -l | tr -d ' ')
357
+ spec_count=$(ls "$repo_root/docs/specs/"*.md 2>/dev/null | wc -l | tr -d ' ')
358
+ decomp_count=$(ls "$repo_root/docs/decompositions/"*.md 2>/dev/null | wc -l | tr -d ' ')
359
+ total_artifacts=$((uc_count + spec_count + decomp_count))
360
+ if [ "$total_artifacts" -gt 0 ]; then
361
+ echo "check_7_status=pass"
362
+ echo "check_7_message=Code staged + $total_artifacts design artifact(s) present (uc=$uc_count spec=$spec_count decomp=$decomp_count)"
363
+ echo "check_7_recommendation="
364
+ pass=$((pass + 1))
365
+ else
366
+ echo "check_7_status=warn"
367
+ echo "check_7_message=Code paths staged but no use-case / spec / decomposition present"
368
+ echo "check_7_recommendation=Per Cockburn ceremony matrix — new hook + lib merit brief use case at docs/use-cases/UC-<slug>.md; app code merits fully-dressed. Skip only for typo/trivial extensions."
369
+ warn=$((warn + 1))
370
+ fi
371
+ fi
372
+
373
+ # === Summary ===
374
+ echo "summary_count_pass=$pass"
375
+ echo "summary_count_warn=$warn"
376
+ echo "summary_count_fail=$fail"
377
+ if [ "$fail" -gt 0 ]; then
378
+ echo "summary_status=fail"
379
+ return 2
380
+ elif [ "$warn" -gt 0 ]; then
381
+ echo "summary_status=warn"
382
+ return 1
383
+ else
384
+ echo "summary_status=pass"
385
+ return 0
386
+ fi
387
+ }
388
+
389
+ # Helper: render the structured output as a human-readable block.
390
+ # Composers can pipe `composer_preflight_check ... | composer_preflight_render`
391
+ # for a polished operator-facing surface.
392
+ composer_preflight_render() {
393
+ local skill_name="${1:-the skill}"
394
+ local input
395
+ input=$(cat)
396
+
397
+ echo ""
398
+ echo "============================================"
399
+ echo "PRE-FLIGHT CHECK — /$skill_name"
400
+ echo "============================================"
401
+
402
+ local i status name message rec
403
+ for i in 1 2 3 4 5 6 7; do
404
+ status=$(echo "$input" | grep -E "^check_${i}_status=" | head -1 | sed 's/^check_[0-9]_status=//')
405
+ name=$(echo "$input" | grep -E "^check_${i}_name=" | head -1 | sed 's/^check_[0-9]_name=//')
406
+ message=$(echo "$input" | grep -E "^check_${i}_message=" | head -1 | sed 's/^check_[0-9]_message=//')
407
+ rec=$(echo "$input" | grep -E "^check_${i}_recommendation=" | head -1 | sed 's/^check_[0-9]_recommendation=//')
408
+
409
+ # Skip render slot if check didn't fire (e.g., pre-Check-6 fixtures)
410
+ [ -z "$name" ] && continue
411
+
412
+ local glyph
413
+ case "$status" in
414
+ pass) glyph="✓" ;;
415
+ warn) glyph="⚠️ " ;;
416
+ fail) glyph="✗" ;;
417
+ *) glyph="?" ;;
418
+ esac
419
+
420
+ printf " %s %-15s %s\n" "$glyph" "$name" "$message"
421
+ if [ -n "$rec" ]; then
422
+ printf " └─ recommendation: %s\n" "$rec"
423
+ fi
424
+ done
425
+
426
+ local summary_status pass warn fail
427
+ summary_status=$(echo "$input" | grep "^summary_status=" | head -1 | sed 's/^summary_status=//')
428
+ pass=$(echo "$input" | grep "^summary_count_pass=" | head -1 | sed 's/^summary_count_pass=//')
429
+ warn=$(echo "$input" | grep "^summary_count_warn=" | head -1 | sed 's/^summary_count_warn=//')
430
+ fail=$(echo "$input" | grep "^summary_count_fail=" | head -1 | sed 's/^summary_count_fail=//')
431
+
432
+ echo ""
433
+ case "$summary_status" in
434
+ pass)
435
+ echo "DISPATCH READY: all $pass checks pass."
436
+ ;;
437
+ warn)
438
+ echo "DISPATCH WITH WARNINGS: $pass pass, $warn warn, $fail fail."
439
+ echo "Composer should ask operator to proceed/abort."
440
+ ;;
441
+ fail)
442
+ echo "DISPATCH REFUSED: $pass pass, $warn warn, $fail fail."
443
+ echo "Resolve fail-tier checks before proceeding."
444
+ ;;
445
+ skip)
446
+ echo "PRE-FLIGHT SKIPPED (SKIP_COMPOSER_PREFLIGHT=1)."
447
+ ;;
448
+ esac
449
+ echo "============================================"
450
+ echo ""
451
+ }
452
+
453
+ # If sourced, the functions are available. If executed directly, run a
454
+ # self-test against the current repo + report.
455
+ if [ "${BASH_SOURCE[0]:-$0}" = "${0}" ]; then
456
+ echo "Self-test mode: running composer_preflight_check for /launch with 60-turn estimate"
457
+ echo ""
458
+ composer_preflight_check "launch" 60 | composer_preflight_render "launch"
459
+ fi