Spec: how the variant gets built, not just where it lives
The axis is not the repo. A repo is cheap and reversible; an interface two apps depend on is neither. Two specs are guesses, two implementations are facts -- so one app builds the primitive in the shared place and the other adopts it, and the second use corrects the shape. Until then the shared place is a home, not an agreed interface. Prices both options rather than assuming one. A separate repo buys CI, a release process, a version, and a second pin to keep in step -- the frozen-tokens.css trap one layer down. Starting as a directory inside an app avoids that and hits Go's module boundary instead: importing oficina/docs/... would drag the whole Docs application into Sheets, and avoiding that means a nested module.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011F5CivVm4CmL9ByfSSAaXA
1 file changed,
+33
−0
docs/superpowers/specs/2026-08-30-docs-design.md+33 −0
No CI script — run details
Intent
diff --git a/docs/superpowers/specs/2026-08-30-docs-design.md b/docs/superpowers/specs/2026-08-30-docs-design.md| index 80c99ff..35ae1e5 100644 |
| --- a/docs/superpowers/specs/2026-08-30-docs-design.md |
| +++ b/docs/superpowers/specs/2026-08-30-docs-design.md |
| @@ -637,6 +637,39 @@ colour, type and shape, where a variant can add a component a theme cannot. |
| module's own vocabulary. It is what a variant's gallery needs, so neither |
| suite app should design a documentation tool before looking at it. |
| +**How the variant gets built — the axis that matters is not the repo.** A |
| +repo is cheap and reversible; an interface two apps depend on is neither. |
| +Creating a repo commits nobody to a shape, and agreeing an inspector's props |
| +commits everybody. |
| + |
| +Two specs are guesses; two implementations are facts. A document editor's |
| +inspector holds text and style properties, a spreadsheet's holds cell format |
| +and data validation, and an abstraction designed from both specs at once |
| +risks a shape fitting neither — discovered only after both are built. |
| + |
| +**So: one app builds it, in the shared place, and the other adopts it.** Not |
| +two implementations merged, and not an interface designed from two specs. The |
| +second *use* corrects the shape, which is what working code tells you and a |
| +spec cannot. Until that second adoption the shared place is a **home, not an |
| +agreed interface** — treating it as an interface earlier produces exactly the |
| +ill-fitting abstraction the sequencing exists to avoid. |
| + |
| +**What a separate repo costs, priced rather than assumed:** CI, a release |
| +process, a version, and a dependency edge into two apps. It also reproduces |
| +the frozen-`tokens.css` trap one layer down — the variant pins a rastrillo |
| +version, the apps pin a variant version, and there are two pins to keep in |
| +step instead of one. That is the trap that already cost this project a manual |
| +runbook step and a `rastrillo doctor` to mechanise. |
| + |
| +**Against the alternative of starting it as a directory inside whichever app |
| +builds first:** Go's module boundaries make the second consumer's import |
| +awkward — importing `oficina/docs/...` would drag the entire Docs application |
| +in as a dependency of Sheets, and avoiding that means a nested module, which |
| +is fiddly in a different way. Recorded because the directory-first option is |
| +otherwise the cheaper-looking one. |
| + |
| +Paul's call; unresolved here (§15). |
| + |
| **Unchanged: the colour engine stays a `ui` dependency** (§10.2). It is a |
| function rather than a component, and Docs remains a declared consumer of it |
| upstream. |