@thebassclef/lite 0.1.0 → 0.1.3

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 (163) hide show
  1. package/dist/cli.cjs +40 -6
  2. package/dist/cli.js +40 -6
  3. package/dist/index.cjs +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/package.json +1 -1
  7. package/substrate/.bassclef/lite-manifest.json +999 -92
  8. package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +492 -0
  9. package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +492 -0
  10. package/substrate/.claude/hooks/pre-commit-gate.sh +1 -2
  11. package/substrate/.claude/hooks/turn-prose-kiss-check.sh +30 -1
  12. package/substrate/.claude/luminaries/glenford-myers.md +230 -0
  13. package/substrate/.claude/luminaries/hunt-thomas.md +115 -0
  14. package/substrate/.claude/luminaries/hyrum-wright.md +94 -0
  15. package/substrate/.claude/luminaries/michael-feathers.md +2 -2
  16. package/substrate/.claude/luminaries/tony-hoare.md +170 -0
  17. package/substrate/.claude/luminaries/vaughn-vernon.md +50 -0
  18. package/substrate/.claude/luminaries/w-edwards-deming.md +158 -0
  19. package/substrate/.claude/rules/accessor-library-discipline.md +138 -0
  20. package/substrate/.claude/rules/adr-discipline.md +120 -0
  21. package/substrate/.claude/rules/api-conventions.md +125 -0
  22. package/substrate/.claude/rules/bootstrap-pair-discipline.md +141 -0
  23. package/substrate/.claude/rules/cold-adopter-harness-discipline.md +129 -0
  24. package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +188 -0
  25. package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +188 -0
  26. package/substrate/.claude/rules/defensive-bash.md +68 -0
  27. package/substrate/.claude/rules/deferred-actions.md +233 -0
  28. package/substrate/.claude/rules/github-issue-flash-tweet.md +156 -0
  29. package/substrate/.claude/rules/hook-wire-on-author.md +103 -0
  30. package/substrate/.claude/rules/iteration-bet-brief-completeness.md +54 -0
  31. package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +3 -3
  32. package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +89 -0
  33. package/substrate/.claude/rules/loop-discipline.md +81 -0
  34. package/substrate/.claude/rules/manual-prod-approval.md +100 -0
  35. package/substrate/.claude/rules/marker-enrichment-discipline.md +99 -0
  36. package/substrate/.claude/rules/mobile-ephemeral-session.md +109 -0
  37. package/substrate/.claude/rules/new-dependency-check.md +51 -0
  38. package/substrate/.claude/rules/option-label-discipline.md +108 -0
  39. package/substrate/.claude/rules/pattern-annotation.md +100 -0
  40. package/substrate/.claude/rules/plain-english-discipline.md +11 -9
  41. package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +211 -0
  42. package/substrate/.claude/rules/pr-title-shape.md +161 -0
  43. package/substrate/.claude/rules/prototype-workflow.md +65 -0
  44. package/substrate/.claude/rules/reserved-skill-names.md +123 -0
  45. package/substrate/.claude/rules/schema-management.md +49 -0
  46. package/substrate/.claude/rules/security.md +37 -0
  47. package/substrate/.claude/rules/skill-composition-declarations.md +124 -0
  48. package/substrate/.claude/rules/skill-description-clarity.md +247 -0
  49. package/substrate/.claude/rules/skill-procedure-step-list.md +137 -0
  50. package/substrate/.claude/rules/stuck-signal-diagnostic.md +140 -0
  51. package/substrate/.claude/rules/substrate-config-schema.md +98 -0
  52. package/substrate/.claude/rules/test-list-discipline.md +175 -0
  53. package/substrate/.claude/rules/test-sufficiency.md +210 -0
  54. package/substrate/.claude/rules/testing-tier-config.md +145 -0
  55. package/substrate/.claude/rules/testing.md +38 -0
  56. package/substrate/.claude/rules/turn-estimate-grounding.md +134 -0
  57. package/substrate/.claude/rules/visual-hierarchy.md +437 -0
  58. package/substrate/.claude/rules/we-dont-break-adopters.md +126 -0
  59. package/substrate/.claude/rules/wu-sequencing-compounds.md +145 -0
  60. package/substrate/.claude/skills/build/SKILL.md +1 -1
  61. package/substrate/.claude/skills/chronicle/SKILL.md +55 -0
  62. package/substrate/.claude/skills/clean-artifacts/SKILL.md +249 -0
  63. package/substrate/.claude/skills/decompose/SKILL.md +1 -1
  64. package/substrate/.claude/skills/diagnose/SKILL.md +1 -1
  65. package/substrate/.claude/skills/feynman/SKILL.md +90 -0
  66. package/substrate/.claude/skills/howdoi/SKILL.md +1 -1
  67. package/substrate/.claude/skills/ia-model/SKILL.md +1 -1
  68. package/substrate/.claude/skills/interaction-design/SKILL.md +1 -1
  69. package/substrate/.claude/skills/interpret-input/SKILL.md +8 -8
  70. package/substrate/.claude/skills/journal/SKILL.md +209 -0
  71. package/substrate/.claude/skills/kiss/SKILL.md +1 -1
  72. package/substrate/.claude/skills/launch/SKILL.md +14 -23
  73. package/substrate/.claude/skills/lean-canvas/SKILL.md +1 -1
  74. package/substrate/.claude/skills/longrun/SKILL.md +45 -8
  75. package/substrate/.claude/skills/luminary/SKILL.md +1 -1
  76. package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +1 -1
  77. package/substrate/.claude/skills/onboard-repo/SKILL.md +143 -709
  78. package/substrate/.claude/skills/pattern-review/SKILL.md +1 -1
  79. package/substrate/.claude/skills/personas/SKILL.md +5 -5
  80. package/substrate/.claude/skills/promote/SKILL.md +1 -1
  81. package/substrate/.claude/skills/requirement/SKILL.md +1 -1
  82. package/substrate/.claude/skills/retro/SKILL.md +1 -1
  83. package/substrate/.claude/skills/riff/SKILL.md +1 -1
  84. package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +1 -1
  85. package/substrate/.claude/skills/session-end/SKILL.md +1 -1
  86. package/substrate/.claude/skills/session-log/SKILL.md +3 -3
  87. package/substrate/.claude/skills/skills/SKILL.md +1 -1
  88. package/substrate/.claude/skills/spec/SKILL.md +1 -1
  89. package/substrate/.claude/skills/sprint/SKILL.md +1 -1
  90. package/substrate/.claude/skills/stage/SKILL.md +1 -1
  91. package/substrate/.claude/skills/state-a-problem/SKILL.md +1 -1
  92. package/substrate/.claude/skills/temperance/SKILL.md +1 -1
  93. package/substrate/.claude/skills/use-case/SKILL.md +1 -1
  94. package/substrate/.claude/skills/user-stories/SKILL.md +1 -1
  95. package/substrate/.claude/skills/value-prop/SKILL.md +1 -1
  96. package/substrate/.claude/skills/verify/SKILL.md +1 -1
  97. package/substrate/.claude/skills/visual-review/SKILL.md +503 -0
  98. package/substrate/.claude/skills/whats-the-plan/SKILL.md +202 -0
  99. package/substrate/.claude/skills/whereami/SKILL.md +2 -2
  100. package/substrate/CONTRIBUTING.md +1 -1
  101. package/substrate/README.md +5 -5
  102. package/substrate/lib/prose-scan-boundary.sh +171 -0
  103. package/substrate/lib/tier-check.sh +50 -1
  104. package/substrate/lib/tier-dependency-audit.sh +159 -4
  105. package/substrate/presence/install/bassclef-sync.template.sh +1 -1
  106. package/substrate/scripts/generate-lite-manifest.sh +21 -5
  107. package/substrate/standards/adr-template.md +86 -0
  108. package/substrate/standards/api-conventions/nextjs.md +84 -0
  109. package/substrate/standards/artifact-composition.md +209 -0
  110. package/substrate/standards/bash-hook-safety.md +246 -0
  111. package/substrate/standards/branch-stacking.md +408 -0
  112. package/substrate/standards/code-safety-principles.md +176 -0
  113. package/substrate/standards/composer-prerequisites.md +155 -0
  114. package/substrate/standards/dependency-discipline/cargo.md +39 -0
  115. package/substrate/standards/dependency-discipline/gem.md +43 -0
  116. package/substrate/standards/dependency-discipline/go-mod.md +41 -0
  117. package/substrate/standards/dependency-discipline/npm.md +42 -0
  118. package/substrate/standards/dependency-discipline/pip.md +42 -0
  119. package/substrate/standards/deployment-topology/ec2-tailscale.md +225 -0
  120. package/substrate/standards/deployment-topology.md +69 -0
  121. package/substrate/standards/docs-sync-allowlist.md +4 -4
  122. package/substrate/standards/domain-and-dns.md +145 -0
  123. package/substrate/standards/frontend-stack.md +67 -0
  124. package/substrate/standards/frontmatter-schema.md +154 -0
  125. package/substrate/standards/hook-injection-discipline.md +202 -0
  126. package/substrate/standards/hook-install-class.md +215 -0
  127. package/substrate/standards/input-handler-interface.md +152 -0
  128. package/substrate/standards/lite-manifest-schema-changes.md +60 -0
  129. package/substrate/standards/luminary-matching.md +105 -0
  130. package/substrate/standards/migration-discipline/active-record.md +50 -0
  131. package/substrate/standards/migration-discipline/alembic.md +43 -0
  132. package/substrate/standards/migration-discipline/gorm.md +50 -0
  133. package/substrate/standards/migration-discipline/prisma.md +53 -0
  134. package/substrate/standards/migration-discipline/sqlalchemy.md +51 -0
  135. package/substrate/standards/mobile-ephemeral-session.md +167 -0
  136. package/substrate/standards/model-routing-discipline.md +160 -0
  137. package/substrate/standards/persona-schema.md +229 -0
  138. package/substrate/standards/pluggable-luminaries.md +323 -0
  139. package/substrate/standards/pr-body-discipline.md +115 -0
  140. package/substrate/standards/preview-state-schema.md +189 -0
  141. package/substrate/standards/reserved-skill-names.md +120 -0
  142. package/substrate/standards/scannable-multi-option-output.md +261 -0
  143. package/substrate/standards/sdlc-gates/typescript.md +57 -0
  144. package/substrate/standards/session-board.md +256 -0
  145. package/substrate/standards/state-spine-contract.md +255 -0
  146. package/substrate/standards/steering-hints/kiss-words.md +11 -0
  147. package/substrate/standards/substrate-config-schema.md +267 -0
  148. package/substrate/standards/tier-dependency-analysis.md +1 -1
  149. package/substrate/standards/tier-tag-schema.md +1 -1
  150. package/substrate/standards/two-layer-config.md +99 -0
  151. package/substrate/standards/use-case-format.md +292 -0
  152. package/substrate/standards/user-story-invest.md +268 -0
  153. package/substrate/standards/velocity-and-appetite.md +229 -0
  154. package/substrate/standards/voice-input-pattern.md +119 -0
  155. package/substrate/standards/worktree-management.md +211 -0
  156. package/substrate/templates/chronicle-template.md +75 -0
  157. package/substrate/templates/memory-proposal-template.md +77 -0
  158. package/substrate/templates/persona-template.md +200 -0
  159. package/substrate/templates/pr-faq.md +45 -0
  160. package/substrate/templates/secret-rotation-template.md +162 -0
  161. package/substrate/templates/spec-template.md +131 -0
  162. package/substrate/templates/use-case-template.md +194 -0
  163. package/substrate/templates/user-story-template.md +107 -0
@@ -0,0 +1,152 @@
1
+ ---
2
+ tier: lite
3
+ description: "The interface contract between operator inputs (text / URL / image / repo / transcript / napkin / mixed) and the cameo pipeline's extraction layer."
4
+ ---
5
+
6
+ # Input Handler Interface
7
+
8
+ The interface contract between operator inputs (text / URL / image /
9
+ repo / transcript / napkin / mixed) and the cameo pipeline's
10
+ extraction layer. `/interpret-input` produces a normalized `InputArtifact`
11
+ from any input shape; downstream skills (`/objectory-decompose`,
12
+ `/value-prop`, `/personas`) consume the normalized artifact, never raw
13
+ operator input.
14
+
15
+ This standard is the contract. The implementation is
16
+ `.claude/skills/interpret-input/SKILL.md` + `scripts/interpret-input.sh`.
17
+ Schema lives at `standards/state-spine/schemas/input-artifact.schema.json`.
18
+
19
+ ## Why this exists
20
+
21
+ Without an input-handler interface, every input shape requires its own
22
+ extraction code path. Adding a new input mode (e.g., PowerPoint slides,
23
+ PRD documents) means re-shaping the entire chain. The interface lets us:
24
+
25
+ - Implement extractors as ADAPTERS to the same downstream contract
26
+ - Test each extractor independently against the same schema
27
+ - Add new extractors without changing core extraction semantics
28
+ - Validate inputs structurally at the boundary
29
+
30
+ Per parent bet's amendment 2026-04-26c: original Phase B baked text-only
31
+ into `/objectory-decompose --text`, deferring abstraction to Phase C.
32
+ This forced a Phase B → Phase C refactor. The current shape establishes
33
+ the interface from day one with text as the first extractor implementation.
34
+
35
+ ## Sources read
36
+
37
+ - `docs/iteration-bets/2026-04-25-example-pipeline.md` Phase B amendment 2026-04-26c — interface-establishing rationale
38
+ - `docs/iteration-bets/2026-04-27d-example-pipeline-phase-b-mvp.md` WU-A — implementation scope
39
+ - `standards/state-spine/schemas/input-artifact.schema.json` — schema this contract references
40
+ - `standards/state-spine.md` §"Storage format" — InputArtifact is Shape C (pure JSON at `docs/input-artifacts/<slug>.json`)
41
+ - `.claude/luminaries/martin-fowler.md` — Adapter pattern (each extractor adapts a source shape to the InputArtifact contract)
42
+
43
+ ## Auto-detection heuristic
44
+
45
+ When `--type` is `auto` (default), `/interpret-input` infers type from
46
+ the source string:
47
+
48
+ | Pattern | Detected type |
49
+ |---|---|
50
+ | `^https?://` (URL prefix) | `url` |
51
+ | `\.(png\|jpg\|jpeg\|gif\|webp\|svg)$` (image extension) | `image` |
52
+ | `\.git$` or `github\.com` (repo URL/path) | `repo` |
53
+ | (default) | `text` |
54
+
55
+ Operator overrides by passing `--type=transcript` / `--type=napkin` /
56
+ `--type=mixed` explicitly. Auto-detection cannot distinguish a typed
57
+ transcript from prose, nor a hand-drawn napkin from a regular image —
58
+ both default to `text` and `image` respectively without explicit override.
59
+
60
+ ## Extractor responsibilities
61
+
62
+ Each extractor implements one input type. Common responsibilities:
63
+
64
+ | Step | What | Required |
65
+ |---|---|---|
66
+ | 1. Receive raw input | Accept `source` argument verbatim | yes |
67
+ | 2. Validate / normalize | Trim, decode, check existence (for paths) | yes |
68
+ | 3. Populate `extracted_text` | Produce normalized prose for downstream | yes |
69
+ | 4. Populate `structural_hints` | Extract type-specific signals when available | optional |
70
+ | 5. Populate `external_urls` | URL regex matches in source / extracted text | optional |
71
+ | 6. Schema validate | Output must conform to InputArtifact schema | yes |
72
+
73
+ `extracted_text` is the load-bearing output — `/objectory-decompose`
74
+ operates on it. `structural_hints` are best-effort enrichment.
75
+
76
+ ## Phase B vs Phase C scope
77
+
78
+ **Phase B (this MVP, WU-A)**: text mode is fully implemented. Other
79
+ modes return stub `InputArtifact` with:
80
+
81
+ - `type: <name>` (correct)
82
+ - `source: <input>` (correct)
83
+ - `extracted_text: "deferred to Phase C"` (sentinel value)
84
+ - All structural_hints empty
85
+ - `external_urls: []`
86
+
87
+ This lets downstream skills (`/objectory-decompose`, `/preview`)
88
+ exercise the interface against any input type without breaking on
89
+ "extractor not implemented." Stub artifacts are still schema-valid.
90
+
91
+ **Phase C (follow-up goal)**: implements remaining extractors as ADAPTERS
92
+ against this contract. No core extraction changes; only new extractor
93
+ implementations.
94
+
95
+ | Type | Extractor approach | Phase |
96
+ |---|---|---|
97
+ | text | Identity (extracted_text = source); URL regex for external_urls | B (this MVP) |
98
+ | url | Fetch + readable-text scrape; cite references | C |
99
+ | image | Vision-based UI-element extraction → boundary_objects | C |
100
+ | repo | Read README + top-level structure + open issues | C |
101
+ | transcript | Speaker-tagged actor → verb mapping | C |
102
+ | napkin | Hand-drawn diagram → entities + boundary_objects | C |
103
+ | mixed | Compose multiple extractors over multi-source input | C |
104
+
105
+ ## Storage shape
106
+
107
+ InputArtifact is Shape C (pure JSON) per `standards/state-spine.md`
108
+ §"Storage format":
109
+
110
+ ```
111
+ docs/input-artifacts/<slug>.json
112
+ ```
113
+
114
+ Validated at write by `state-validate.sh` PreToolUse hook against
115
+ `input-artifact.schema.json`. Operator-readable narrative belongs in
116
+ chronicles + decompositions, not in InputArtifact bodies.
117
+
118
+ ## Slug convention
119
+
120
+ ```
121
+ <YYYY-MM-DD>-<type>-<6-char-hash-of-source>
122
+ ```
123
+
124
+ Examples:
125
+ - `2026-04-27-text-3a1b2c` (text input from operator paragraph)
126
+ - `2026-04-27-url-9f8e7d` (URL extraction)
127
+ - `2026-04-27-repo-1a2b3c` (repo extraction)
128
+
129
+ Operator may override via `--slug=<custom>` for memorable fixtures
130
+ (e.g., `2026-04-27-poa-five-pandas-rework`).
131
+
132
+ ## Naming convention
133
+
134
+ Skills using InputArtifacts read via `state_reference_get input-artifact <slug>`
135
+ per `standards/state-spine-contract.md`. Direct `cat docs/input-artifacts/<slug>.json`
136
+ is forbidden by `accessor-library-discipline.md`.
137
+
138
+ ## Relationship to other standards
139
+
140
+ - `standards/state-spine.md` §"Storage format" — InputArtifact is Shape C
141
+ - `standards/state-spine/schemas/input-artifact.schema.json` — formal schema
142
+ - `standards/state-spine-contract.md` — accessor surface for reading
143
+ - `.claude/rules/accessor-library-discipline.md` — read-discipline applies
144
+ - `.claude/skills/interpret-input/SKILL.md` — the skill that produces InputArtifacts
145
+ - `.claude/skills/objectory-decompose/SKILL.md` — primary downstream consumer
146
+ - `.claude/skills/preview/SKILL.md` — composer that orchestrates the chain
147
+
148
+ ## Versioning
149
+
150
+ This contract is v0. New extractor additions are non-breaking (additive).
151
+ Schema changes (new required fields, removed properties) are v1; ship as
152
+ parallel `input-artifact-v1.schema.json` per Fowler expand-and-contract.
@@ -34,6 +34,66 @@ Every entry stays in this file for the life of the manifest. Never pruned. When
34
34
 
35
35
  ## Entries (newest first)
36
36
 
37
+ ### Tier alignment cure batch 6 + arc (73 flips + 21 source scrubs + adopter-doc rewrite) (v1.5.6 → v1.5.7, 2026-09-11)
38
+
39
+ - **Change type:** content-add + content-normalization
40
+ - **Fields:** manifest entry list gains 79 files across two waves. Batch 6 (2026-09-10, PR #1596) added 6 adopter-facing files flipped standard → lite. The 3-PR tier walk cleanup arc (2026-09-10 through 2026-09-11) added 73 more flipped files (PR #1599) plus 1 promoted from upstream → standard (`.claude/rules/sibling-smoke-after-substrate-change.md`). The arc also shifted `content_hash` on ~15 already-present entries whose bodies were edited during PR #1600 source-body scrubs and PR #1601 README + CONTRIBUTING rewrites. Notable entries added at lite tier: `.claude/rules/we-dont-break-adopters.md`, `.claude/rules/api-conventions.md`, `.claude/rules/schema-management.md`, `.claude/rules/hook-wire-on-author.md`, `.claude/rules/defensive-bash.md`, `.claude/rules/deferred-actions.md`, `.claude/rules/turn-estimate-grounding.md`, `.claude/rules/visual-hierarchy.md`, `.claude/rules/option-label-discipline.md`, `.claude/rules/pr-title-shape.md`, `.claude/rules/reserved-skill-names.md`, `.claude/rules/marker-enrichment-discipline.md`, `.claude/rules/new-dependency-check.md`, `.claude/rules/prototype-workflow.md`, `.claude/rules/longrun-prep-plan-doc-compression.md`, `.claude/rules/skill-procedure-step-list.md`, `.claude/rules/substrate-config-schema.md`, `.claude/rules/test-sufficiency.md`, `.claude/rules/wu-sequencing-compounds.md`, `.claude/rules/compounding-sequence-fresh-analysis.md`, `.claude/rules/iteration-bet-brief-completeness.md`, plus 4 luminaries (glenford-myers, hunt-thomas, vaughn-vernon, w-edwards-deming), 6 skills (chronicle, clean-artifacts, feynman, journal, visual-review, whats-the-plan), and 22 standards.
41
+ - **Version bump:** v1.5.6 → v1.5.7 (patch; content-only add + content-normalization on ~15 pre-existing entries whose bodies were edited; no schema shape shift)
42
+ - **Rationale:** Tier walk cleanup arc (parent ticket bassclef-upstream#1595). The arc followed the persona-grounded cleanup grid classified via `/extract-intent` (0.92 confidence) + fork classifier during session 2026-09-10e. Grid split 185 walker edges into three cures: PR A `#1599` shipped 73 tier flips + 1 promotion; PR B `#1600` shipped 21 source-body scrubs across 15 files (5 DROP + 12 BACKTICK + 3 REWRITE + 1 auto); PR C `#1601` rewrote README + CONTRIBUTING for adopter audience without naming operator-only file paths. Batch 6 `#1596` shipped separately the day before under the same parent. Walker delta across the arc: 114 → 112 lite alignment violations (net; 109 explicit closures across the arc; residual 107 exposed by transitive walk during the flip stage; final 112 approaches the ~73-edge irreducible substrate machinery floor).
43
+ - **Downstream cure:** No adopter code change needed. Adopters that sync will receive 79 new files in their lite manifest bundle plus fresh `content_hash` on ~15 previously-present files. Consumers reading `.entries[].path` see a longer list. Consumers using `.entries[].content_hash` for change detection see hashes shift on modified files (expected behavior; that field records live file state). Consumers pinning `~1.5` stay green (patch-level compatible). `manifest_version` field type unchanged; no field added, removed, or renamed.
44
+ - **Old shape retired:** Never. Files existed before at higher tier; only tier tag changed for adds. For content-normalization on the ~15 modified entries, the field shape stayed the same; only the body content shifted (which is what `content_hash` is for).
45
+ - **Related tickets:** bassclef-upstream#1595 (parent tier walk arc). Merged PRs: #1596 (batch 6), #1599 (arc PR A), #1600 (arc PR B), #1601 (arc PR C admin-merged as e31d25bc).
46
+
47
+ ### Tier alignment cure batch 5 — 15 adopter-facing rules + standards flipped to lite (v1.5.5 → v1.5.6, 2026-09-09)
48
+
49
+ - **Change type:** content-add
50
+ - **Fields:** manifest entry list gains 15 files that flipped tier tags to lite. High-confidence flips (9): `.claude/rules/accessor-library-discipline.md` (state accessor rules), `standards/reserved-skill-names.md` (skill authoring gate), `standards/substrate-config-schema.md` (adopter config schema), `standards/hook-install-class.md` (hook install class declarations), `standards/bash-hook-safety.md` (bash hook safety rules), `.claude/rules/pattern-annotation.md` (`@pattern` annotation contract), `.claude/rules/mobile-ephemeral-session.md` (mobile session discipline), `.claude/rules/loop-discipline.md` (per-PR six-step cycle), `.claude/rules/cold-adopter-harness-discipline.md` (adopter harness discipline). Judgment-call flips (6): `.claude/rules/stuck-signal-diagnostic.md` (diagnostic pattern for repeated warnings), `.claude/rules/skill-composition-declarations.md` (`composes_with` + `depends_on` fields), `.claude/rules/plan-enumeration-needs-value-props.md` (plan doc format discipline), `standards/velocity-and-appetite.md` (planning discipline), `standards/composer-prerequisites.md` (chain composition rules), `standards/code-safety-principles.md` (universal code discipline).
51
+ - **Version bump:** v1.5.5 → v1.5.6 (patch; content-only add, no schema shape shift)
52
+ - **Rationale:** Batch 5 of the tier alignment cure sequence (parent ticket bassclef-upstream#1568). Every target is a rule or standard adopters need to make their lite skills, hooks, and state accessors work correctly. Loop-discipline was previously `tier: upstream`; flipped to lite alongside the standard-tier group per same rationale — adopters run PRs, so per-PR discipline is adopter-facing.
53
+ - **Downstream cure:** No adopter code change needed. Adopters that sync will now receive these 15 files in their lite manifest bundle. Consumers reading manifest entries see 15 new paths. No field shape change. No content change on unchanged entries.
54
+ - **Old shape retired:** Never. Files existed before at higher tier; only tier tag changed.
55
+ - **Related tickets:** bassclef-upstream#1568 (parent tier graph walk audit). Sister PRs same session: #1573 (batch 1) + #1576 (batch 1b) + #1577 (batch 2) + #1578 (batch 3) + #1579 (batch 4).
56
+
57
+ ### Tier alignment cure batch 4 — 7 adopter-facing rules + Hyrum luminary flipped to lite (v1.5.4 → v1.5.5, 2026-09-09)
58
+
59
+ - **Change type:** content-add
60
+ - **Fields:** manifest entry list gains 7 files that flipped tier tags from standard to lite. All 7 are files adopters need to make their lite skills work. Rules: `testing-tier-config.md` (which tier of test per path), `github-issue-flash-tweet.md` (issue body format for `gh issue create`), `test-list-discipline.md` (Beck test-list authoring), `skill-description-clarity.md` (authoring skill descriptions), `bootstrap-pair-discipline.md` (every substrate building block ships paired), `adr-discipline.md` (ADR authoring per Nygard lifecycle). Luminary: `hyrum-wright.md` (design lens for observable behavior — sister to Hoare from batch 3).
61
+ - **Version bump:** v1.5.4 → v1.5.5 (patch; content-only add, no schema shape shift)
62
+ - **Rationale:** Batch 4 of the tier alignment cure sequence (parent ticket bassclef-upstream#1568). Shape e ADVISORY reported 38 alignment warnings where lite skills cited these 7 targets. Every target is adopter-facing: adopters test their own code (testing-tier-config, test-list-discipline), file issues (github-issue-flash-tweet), author skills (skill-description-clarity, bootstrap-pair-discipline), and author ADRs (adr-discipline). Hyrum luminary is cited from lite skills as a design lens the same way Hoare was in batch 3.
63
+ - **Downstream cure:** No adopter code change needed. Adopters that sync will now receive these 7 files in their lite manifest bundle. Consumers reading manifest entries see 7 new paths. No field shape change. No content change on unchanged entries.
64
+ - **Old shape retired:** Never. Files existed before at higher tier; only tier tag changed.
65
+ - **Related tickets:** bassclef-upstream#1568 (parent tier graph walk audit). Sister PRs same session: #1573 (batch 1) + #1576 (batch 1b) + #1577 (batch 2) + #1578 (batch 3).
66
+
67
+ ### Tier alignment cure batch 3 — chronicle template + Hoare luminary flipped to lite (v1.5.3 → v1.5.4, 2026-09-09)
68
+
69
+ - **Change type:** content-add
70
+ - **Fields:** manifest entry list gains 2 files that flipped tier tags from higher to lite. `templates/chronicle-template.md` flipped from `tier: upstream` to `tier: lite`; adopters use it via session-end and session-log skills to write their own session logs. `.claude/luminaries/tony-hoare.md` flipped from `tier: standard` to `tier: lite`; cited by 16 lite-tier sources (skills + rules + hooks) as a design lens for pre/postcondition contracts.
71
+ - **Version bump:** v1.5.3 → v1.5.4 (patch; content-only add, no schema shape shift)
72
+ - **Rationale:** Batch 3 of the tier alignment cure sequence (parent ticket bassclef-upstream#1568; sister PRs #1573 + #1576 + #1577 in the same session). Shape e ADVISORY reported 21 alignment violations where lite skills cited these two standard-or-higher targets. Both targets are files adopters need — chronicle template ships as adopter session-artifact scaffolding; Hoare luminary ships as a design lens the lite skill catalog references. Flipping targets down cures the 21 violations without touching source semantics.
73
+ - **Downstream cure:** No adopter code change needed. Adopters that sync will now receive the chronicle template + Hoare luminary in their lite manifest bundle. Consumers reading manifest entries see 2 new paths (`templates/chronicle-template.md` + `.claude/luminaries/tony-hoare.md`). No field shape change. No content change on unchanged entries.
74
+ - **Old shape retired:** Never. Both files existed before; only tier tag changed.
75
+ - **Related tickets:** bassclef-upstream#1568 (parent tier graph walk audit). Sister PRs same session: #1573 (batch 1 — 74 files) + #1576 (batch 1b — 10 sister-path files) + #1577 (batch 2 — 2 straggler tests).
76
+
77
+ ### Em-dash encoding normalized + content jargon cleanup (v1.5.2 → v1.5.3, 2026-09-08)
78
+
79
+ - **Change type:** content-normalization + content-refresh
80
+ - **Fields:** every string field (`description` + `problem` + `value`) that carried a `—` YAML escape in SKILL.md source. 20 lines in v1.5.2 lite manifest carried the raw `—` shape; all 84 em-dashes now emit as literal `—` character in JSON. Content refresh: /personas + /interpret-input SKILL.md body prose drops internal ticket refs (`#200` + `#1427`); descriptions updated to plain English.
81
+ - **Version bump:** v1.5.2 → v1.5.3 (patch; content-only normalization and refresh, no schema shape shift)
82
+ - **Rationale:** Downstream bassclef-web renderer at PR #274 writes manifest strings verbatim into MDX pages. Fields with the `—` escape rendered as raw 6-character text on docs.bassclef.dev instead of the em-dash glyph. Extractor now calls `normalize_em_dash` on every extracted YAML string; jq encodes uniformly. Peirce option a from ticket body. Content refresh addresses jargon leakage in SKILL bodies — adopters reading docs see plain sentences instead of internal ticket numbers.
83
+ - **Downstream cure:** No adopter code change needed. Consumers reading strings via `JSON.parse` see em-dash character consistently. Adopters that pinned exact description strings (unlikely) get updated content. Intent-drift check: /personas cosine 0.9924, /interpret-input cosine 0.9823 — both above the 0.90 threshold, intent preserved.
84
+ - **Old shape retired:** Never. Content shape stable; only normalization + prose refresh applied.
85
+ - **Related tickets:** bassclef-upstream#1548 (em-dash bug — this bump). bassclef-web#264 fold (content jargon cleanup — this bump). Sister ticket bassclef-web#275 covers the downstream renderer for `composes_with` + `depends_on` (extractor already emits both; renderer catch-up is the actual gap).
86
+
87
+ ### Content backfill: 96 skills gain curated descriptions (v1.5.1 → v1.5.2, 2026-09-07)
88
+
89
+ - **Change type:** content-add
90
+ - **Fields:** `description` on 34 lite + 62 standard SKILL.md files (96 total; lite manifest ships 34 populated). No schema change; the `description` field has always existed.
91
+ - **Version bump:** v1.5.1 → v1.5.2 (patch; content-only change, no schema shape shift)
92
+ - **Rationale:** Extends v0.37.1 four-field backfill with the 5th field. bassclef-web launch on 2026-09-09 renders `description` alongside `problem` + `value` + `inputs` + `outputs`. Prior descriptions passed skill-description-clarity discipline but 5 exceeded the 280-char ceiling and others missed inline mode/size names. Ogilvy discipline applied — verb-first, ≤270 chars, name modes inline, grade 8-9.
93
+ - **Downstream cure:** No adopter code change needed. Renderers that already project the description field see updated content. Same pin-update guidance as v0.37.1 — loosen exact string pins to a semver range.
94
+ - **Old shape retired:** Never. Field shape stays. Content is fresher.
95
+ - **Related tickets:** bassclef-upstream#1533 (description class — this bump cures the skill surface; non-skill types still deferred until extractor extends).
96
+
37
97
  ### Content backfill: 96 skills gain problem + value + inputs + outputs (v1.5.0 → v1.5.1, 2026-09-07)
38
98
 
39
99
  - **Change type:** content-add
@@ -0,0 +1,105 @@
1
+ ---
2
+ tier: lite
3
+ description: Bassclef core picks luminaries for variant generation via a single LLM call to the configured model provider.
4
+ ---
5
+
6
+ # Luminary Matching — Bassclef Core LLM Pick
7
+
8
+ Bassclef core picks luminaries for variant generation via a **single LLM call** to the configured model provider. The model reads the operator's intent paragraph plus a compact catalog summary (slug + primary domain + name) and returns N slugs whose perspective fits the UX + interaction patterns the intent implies.
9
+
10
+ No separate embedding vendor. No second-stage judge. One call, one provider, one model key — the same key the consumer is already using for everything else.
11
+
12
+ Adopters running the optional two-repo pattern (per `standards/operator-private-discipline.md`) who want richer signal (embedding shortlist + LLM judge) layer their own `/extract-intent` skill in their operator-private sibling via `additionalDirectories`. When loaded, that skill takes precedence and bassclef core stays oblivious.
13
+
14
+ ## Rule
15
+
16
+ Bassclef core's luminary picker uses:
17
+
18
+ - The operator's intent text (from `InputArtifact.intent` or a paragraph supplied at dispatch)
19
+ - The catalog at `state/luminary-implementations/*.json` (slug + primary_domain + name only)
20
+ - The configured model provider (`config/model-routing.yaml`)
21
+
22
+ It does NOT use:
23
+
24
+ - Separate embedding APIs
25
+ - Keyword/regex/grep scoring as the primary path
26
+ - Pre-computed embeddings cache
27
+
28
+ ## When matching fires
29
+
30
+ Any composer or skill that needs to ground variant generation in named luminaries:
31
+
32
+ - `/launch` Phase 3.5 — variants pre-grounded
33
+ - `/stage` Phase 3.5 — same
34
+ - `/riff-prototypes` — when invoked standalone (no upstream grounding artifact)
35
+ - `/luminary recommend` — when LLM picker is available
36
+
37
+ The picker fires once per intent. Variant generation in Phase 4 reads its output and assigns luminaries to the N luminary-driven variants. The Anthropic baseline always lands regardless.
38
+
39
+ ## Adapter — `lib/luminary-pick.sh`
40
+
41
+ The adapter exposes:
42
+
43
+ ```bash
44
+ luminary_pick "<intent text>" <N> <output_json_path> # full pipeline
45
+ luminary_pick_status # report LIVE or OFFLINE
46
+ ```
47
+
48
+ Output JSON shape:
49
+
50
+ ```json
51
+ {
52
+ "matched_luminaries": ["alan-cooper", "edward-tufte", "jakob-nielsen"],
53
+ "rationale": "Cooper for goal-directed flows; Tufte for data density; Nielsen for findability.",
54
+ "picker_version": "bassclef-llm-pick-1.0"
55
+ }
56
+ ```
57
+
58
+ ## Modes
59
+
60
+ | Mode | Trigger | Behavior |
61
+ |---|---|---|
62
+ | **LIVE** | `ANTHROPIC_API_KEY` set | Single LLM call; returns matched slugs |
63
+ | **OFFLINE** | Key missing or LLM call fails | Picker refuses; downstream falls back to `/luminary recommend` signal scoring |
64
+
65
+ ## Fallback path
66
+
67
+ If the LLM picker refuses or errors:
68
+
69
+ 1. Composer logs the refusal
70
+ 2. Falls back to `/luminary recommend` signal scoring (keyword + Garrett-plane + primary-domain coverage)
71
+ 3. Continues with variant generation against the signal-scored picks
72
+
73
+ Operator can also opt into the signal-scoring path explicitly via `/riff-prototypes --use-signal-scoring` to skip the LLM call entirely.
74
+
75
+ ## Operator-private override (optional two-repo pattern)
76
+
77
+ Adopters running the optional two-repo pattern (per `standards/operator-private-discipline.md`) can layer their own `/extract-intent` skill — operator-private substrate that ships richer signal (embedding shortlist + LLM judge) — via `additionalDirectories` injection. When that skill is present:
78
+
79
+ - `/launch`, `/stage`, `/riff-prototypes` prefer the operator-private `extracted_intent_grounding.matched_luminaries`
80
+ - bassclef-core's `/pick-luminaries` becomes a fallback path
81
+ - bassclef core stays oblivious to whether the operator-private override is loaded
82
+
83
+ This is the SENTINEL_bassclef_pattern: the operator-private sibling is a superset of bassclef-core. Operators load both and get the upgraded experience; cold adopters load only bassclef and get the LLM-pick default.
84
+
85
+ ## Composes with
86
+
87
+ - `lib/luminary-pick.sh` — the adapter
88
+ - `.claude/skills/pick-luminaries/SKILL.md` — operator-callable wrapper
89
+ - `state/luminary-implementations/*.json` — catalog manifest
90
+ - `config/model-routing.yaml` — provider selection
91
+ - `/launch` Phase 3.5 + `/stage` Phase 3.5 + `/riff-prototypes` — consumers
92
+
93
+ ## Override + escape hatches
94
+
95
+ - `/riff-prototypes --luminaries=<slug1>,<slug2>,...` — operator pin (skips picker entirely)
96
+ - `/riff-prototypes --use-signal-scoring` — skip LLM pick; use `/luminary recommend` signal scoring
97
+ - `LUMINARY_PICK_MODEL=<id>` — override the default Haiku-4-5 model
98
+
99
+ ## Sources read
100
+
101
+ - bassclef#476 LR8.10/8.11 — luminary catalog + traceability
102
+ - bassclef#944 — Voyage matcher excision; replaces ADR-017's two-vendor pipeline with this LLM-pick approach
103
+ - docs/iteration-bets/2026-06-13a-cold-adopter-unboxing-arc.md — parent goal (WU-3)
104
+ - `standards/model-routing-discipline.md` — provider selection mechanism this adapter uses
105
+
@@ -0,0 +1,50 @@
1
+ ---
2
+ tier: lite
3
+ description: The ActiveRecord sibling of .claude/rules/schema-management.md.
4
+ ---
5
+
6
+ # ActiveRecord (Rails) — migration discipline
7
+
8
+ The ActiveRecord sibling of `.claude/rules/schema-management.md`. Loads when adopter's `tech_stack.orm` is `active-record`.
9
+
10
+ ## Non-negotiable rule
11
+
12
+ **NEVER edit `db/schema.rb` (or `db/structure.sql`) by hand.** Those files are derived artifacts — Rails regenerates them after every migration. Hand-editing them ships drift the moment another developer runs `rails db:migrate`.
13
+
14
+ ## Workflow
15
+
16
+ 1. Generate the migration: `rails generate migration DescriptiveName field:type field:type`
17
+ 2. Review the generated file in `db/migrate/` — Rails generators are good but not infallible; manual edits often required for:
18
+ - Foreign keys + cascading deletes
19
+ - Add-index on large tables (`algorithm: :concurrently` for Postgres)
20
+ - Compound conditions on `add_column` (`null: false, default: ...`)
21
+ 3. Apply locally: `rails db:migrate`
22
+ 4. Commit the migration file AND the regenerated `db/schema.rb` (or `db/structure.sql`)
23
+ 5. On deploy, CI runs `rails db:migrate`
24
+
25
+ ## After DB reset
26
+
27
+ 1. `rails db:setup` (runs migrations + seeds)
28
+ 2. Or `rails db:create db:migrate db:seed`
29
+
30
+ ## After merging a branch with schema changes
31
+
32
+ 1. `rails db:migrate` — apply pending migrations
33
+ 2. Restart the Rails server — ActiveRecord caches schema metadata at boot
34
+ 3. Run the test suite (`bundle exec rspec` or `rails test`) — schema-coupled tests catch missed migrations
35
+
36
+ ## Drift check
37
+
38
+ `rails db:migrate:status` lists every migration + its applied/pending state. Pending migrations = drift.
39
+
40
+ ## Common pitfalls
41
+
42
+ - **`change_column` is one-way unless you write a reversible block** — manual `up` + `down` methods needed for non-reversible changes
43
+ - **Large-table migrations block writes** — use `strong_migrations` gem to lint; index changes especially need `add_index :table, :col, algorithm: :concurrently` on Postgres
44
+ - **`rake db:reset` in dev hides production migrations** — only re-runs from schema.rb; doesn't re-test migration files end-to-end
45
+
46
+ ## Sources
47
+
48
+ - Rails Guides — Active Record Migrations (https://guides.rubyonrails.org/active_record_migrations.html)
49
+ - strong_migrations gem (https://github.com/ankane/strong_migrations)
50
+ - Rails discipline ported from Prisma shape; ActiveRecord's auto-regenerated schema.rb is the Ruby-ecosystem equivalent of Prisma client regeneration.
@@ -0,0 +1,43 @@
1
+ ---
2
+ tier: lite
3
+ description: The Alembic sibling of .claude/rules/schema-management.md for adopters using Alembic without SQLAlchemy ORM models (raw SQL migrations against a Python codebase).
4
+ ---
5
+
6
+ # Alembic (standalone) — migration discipline
7
+
8
+ The Alembic sibling of `.claude/rules/schema-management.md` for adopters using Alembic **without** SQLAlchemy ORM models (raw SQL migrations against a Python codebase). Loads when adopter's `tech_stack.orm` is `alembic`.
9
+
10
+ For Alembic + SQLAlchemy autogen, see `sqlalchemy.md`.
11
+
12
+ ## Non-negotiable rule
13
+
14
+ **NEVER apply DDL outside an Alembic revision.** Direct `psql` / `mysql` / `sqlite3` DDL in production bypasses the migration audit trail.
15
+
16
+ ## Workflow
17
+
18
+ 1. Author a migration: `alembic revision -m "descriptive_name"` (no `--autogenerate` — you write the SQL by hand)
19
+ 2. Edit the generated file in `versions/` — populate `upgrade()` + `downgrade()` with `op.execute(text("..."))` or `op.create_table(...)` calls
20
+ 3. Apply locally: `alembic upgrade head`
21
+ 4. Test the downgrade path: `alembic downgrade -1`, then `alembic upgrade head`
22
+ 5. Commit the migration file
23
+ 6. On deploy, CI runs `alembic upgrade head`
24
+
25
+ ## After merging a branch with schema changes
26
+
27
+ 1. `alembic upgrade head` — apply pending migrations locally
28
+ 2. Verify DB shape matches expectations (Alembic doesn't model anything; the schema lives in DDL)
29
+
30
+ ## Drift check
31
+
32
+ Alembic doesn't auto-detect drift in standalone mode. The session-start hook compares `alembic current` against the latest revision in `versions/`. If they diverge, prompt to upgrade.
33
+
34
+ ## Common pitfalls
35
+
36
+ - **Writing migrations that read application data** — migrations should be idempotent and avoid coupling to app-side queries; data backfills go in separate scripts
37
+ - **Skipping downgrade implementation** — rollback path is mandatory for prod-grade work
38
+ - **Out-of-order revisions** — when parallel branches both create revisions from the same parent, merge with `alembic merge`
39
+
40
+ ## Sources
41
+
42
+ - Alembic docs (https://alembic.sqlalchemy.org/en/latest/)
43
+ - Standalone-Alembic discipline adapted from Prisma migration shape; the universal commitments are the same.
@@ -0,0 +1,50 @@
1
+ ---
2
+ tier: lite
3
+ description: The GORM (Go ORM) sibling of .claude/rules/schema-management.md.
4
+ ---
5
+
6
+ # GORM — migration discipline
7
+
8
+ The GORM (Go ORM) sibling of `.claude/rules/schema-management.md`. Loads when adopter's `tech_stack.orm` is `gorm`.
9
+
10
+ ## Non-negotiable rule
11
+
12
+ **NEVER use `db.AutoMigrate()` in production.** AutoMigrate is a development convenience — in production, it silently makes additive schema changes without an audit trail and refuses to drop columns or constraints, leaving stale columns forever.
13
+
14
+ Use an explicit migration tool — `golang-migrate`, `goose`, `atlas`, or `bun`'s migration layer.
15
+
16
+ ## Workflow (with `golang-migrate`)
17
+
18
+ 1. Edit the GORM model in `models/` (struct tags carry the schema intent)
19
+ 2. Author the migration: `migrate create -ext sql -dir db/migrations -seq descriptive_name`
20
+ 3. Populate `up.sql` and `down.sql` by hand — GORM doesn't generate SQL for you
21
+ 4. Apply locally: `migrate -path db/migrations -database "$DB_URL" up`
22
+ 5. Commit both the model change AND the migration files
23
+ 6. On deploy, CI runs `migrate -path db/migrations -database "$PROD_DB_URL" up`
24
+
25
+ ## After DB reset
26
+
27
+ 1. Re-run all pending migrations: `migrate up`
28
+ 2. Run seed scripts if any
29
+
30
+ ## After merging a branch with schema changes
31
+
32
+ 1. `migrate up` — apply pending migrations
33
+ 2. Restart the Go binary — GORM model definitions are compiled in; rebuild + restart
34
+ 3. Run integration tests against the new schema
35
+
36
+ ## Drift check
37
+
38
+ `migrate version` reports the currently applied version. Compare against the highest numeric revision in `db/migrations/` directory. If they diverge, run `migrate up` before further work.
39
+
40
+ ## Common pitfalls
41
+
42
+ - **GORM struct tags drifting from migration SQL** — GORM does not enforce them; the migration SQL is source of truth for the DB shape
43
+ - **Postgres enum changes** — Postgres enums are quirky; `golang-migrate` requires custom SQL for ALTER TYPE ... ADD VALUE
44
+ - **Forgetting `down.sql`** — rollback path is mandatory; an empty down.sql is a footgun
45
+
46
+ ## Sources
47
+
48
+ - golang-migrate docs (https://github.com/golang-migrate/migrate)
49
+ - GORM docs (https://gorm.io)
50
+ - Go-ecosystem discipline ported from Prisma shape.
@@ -0,0 +1,53 @@
1
+ ---
2
+ tier: lite
3
+ description: The Prisma sibling of .claude/rules/schema-management.md.
4
+ ---
5
+
6
+ # Prisma — migration discipline
7
+
8
+ The Prisma sibling of `.claude/rules/schema-management.md`. Loads when adopter's `tech_stack.orm` is `prisma`. Preserves the operator's existing Prisma discipline verbatim.
9
+
10
+ ## Non-negotiable rule
11
+
12
+ **NEVER use `prisma db push`. Always use `prisma migrate dev`.**
13
+
14
+ `db push` applies changes without creating migration files — this causes schema drift where prod and local databases diverge silently. When the local DB is reset, unmigrated changes are lost, breaking functionality.
15
+
16
+ ## Workflow
17
+
18
+ 1. Edit `prisma/schema.prisma`
19
+ 2. Run `npx prisma migrate dev --name descriptive_name`
20
+ 3. This creates a migration file AND applies it locally
21
+ 4. Commit the migration file with the schema change
22
+ 5. On deploy, CI runs `npx prisma migrate deploy`
23
+
24
+ ## After DB reset
25
+
26
+ - `npx prisma generate` — regenerate client
27
+ - Run any seed scripts
28
+ - Test auth by signing in
29
+
30
+ ## After merging a branch with schema changes (MUST — not optional)
31
+
32
+ 1. `npx prisma generate` — regenerate client from new schema
33
+ 2. Restart dev server — cached Prisma client won't pick up new models
34
+ 3. If DB was reset: run seed scripts for new entities
35
+ 4. Verify: new model is accessible via `prisma.[model].findMany()`
36
+ 5. If the merge includes new entities: seed test data (factories, not hardcoded — see `standards/data-management.md`)
37
+
38
+ This is a **MUST gate**. Skipping `prisma generate` after a schema merge causes runtime crashes: `Cannot read properties of undefined (reading 'findMany')`. The Prisma client literally does not know the model exists.
39
+
40
+ ## Drift check
41
+
42
+ The session-start hook checks for schema drift. If detected, create the missing migration before writing code.
43
+
44
+ ```bash
45
+ npx prisma migrate status
46
+ ```
47
+
48
+ A non-zero exit indicates pending migrations that have not been applied locally — drift signal.
49
+
50
+ ## Sources
51
+
52
+ - This sibling is verbatim of the prior `.claude/rules/schema-management.md` content. Path A split (bassclef#1133 WU-5) preserves operator's discipline for the Prisma case.
53
+ - POA (sole Prisma consumer in the sunj-labs portfolio as of 2026-06-18) reads this sibling unchanged.
@@ -0,0 +1,51 @@
1
+ ---
2
+ tier: lite
3
+ description: The SQLAlchemy sibling of .claude/rules/schema-management.md.
4
+ ---
5
+
6
+ # SQLAlchemy + Alembic — migration discipline
7
+
8
+ The SQLAlchemy sibling of `.claude/rules/schema-management.md`. Loads when adopter's `tech_stack.orm` is `sqlalchemy`. For standalone Alembic (non-SQLAlchemy use), see `alembic.md`.
9
+
10
+ ## Non-negotiable rule
11
+
12
+ **NEVER edit production schema directly via `Base.metadata.create_all()` or DB-side DDL.** SQLAlchemy's autogenerate is the migration source; bypassing it ships drift.
13
+
14
+ ## Workflow (Alembic via SQLAlchemy autogen)
15
+
16
+ 1. Edit the SQLAlchemy model in `models.py` (or wherever the adopter keeps declarative bases)
17
+ 2. Generate the migration: `alembic revision --autogenerate -m "descriptive_name"`
18
+ 3. **Review the generated migration before committing** — autogen misses many cases:
19
+ - Server-side defaults (`server_default=`) are detected only with explicit `compare_server_default=True` in env.py
20
+ - Enum changes need manual handling on Postgres
21
+ - Index renames are usually drop+create (data loss risk)
22
+ - Custom types (JSONB, ARRAY) need explicit handling
23
+ 4. Apply locally: `alembic upgrade head`
24
+ 5. Commit the migration file with the model change
25
+ 6. On deploy, CI runs `alembic upgrade head` against prod
26
+
27
+ ## After merging a branch with schema changes (MUST — not optional)
28
+
29
+ 1. `alembic upgrade head` — apply pending migrations locally
30
+ 2. Restart dev server — SQLAlchemy ORM models reload from source, but DB session connections may cache stale schema metadata
31
+ 3. If DB was reset: re-run seed / fixture scripts
32
+
33
+ ## Drift check
34
+
35
+ ```bash
36
+ alembic current
37
+ alembic history --indicate-current
38
+ ```
39
+
40
+ If `alembic check` (Alembic 1.9+) reports model-vs-DB divergence, generate the missing migration.
41
+
42
+ ## Common pitfalls
43
+
44
+ - **Autogen comparing on outdated metadata** — make sure `target_metadata = Base.metadata` in `env.py` reflects the latest import path
45
+ - **Multiple heads** after parallel branches — resolve via `alembic merge` before further development
46
+ - **`alembic stamp head`** is a footgun — only use it when you know the DB is already at that state; otherwise you skip migrations silently
47
+
48
+ ## Sources
49
+
50
+ - Alembic docs (https://alembic.sqlalchemy.org/en/latest/)
51
+ - SQLAlchemy migration discipline ports the operator's Prisma rule shape to the Python ecosystem.