oficina / docs Public

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
Paul Campbell pushed by paul@keymail.dev 0edd9d5f9b425169e83d29700751cedb4e7df276 parent e199e2c
1 file changed, +33 −0
  • docs/superpowers/specs/2026-08-30-docs-design.md +33 −0

No CI script — run details

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.