A gate that crosses from computed value to painted output
docs-e6 shipped a version of this bug and described the shape, which turned out to be sitting unnamed in this spec's formatting layer. Ruling 2 put one engine behind cell values. But a value is not what a cell shows: 123.456 under a currency format displays as a formatted string, and if the browser renders that from a raw number then number formatting is a second implementation of the same truth — the exact bug class ruling 2 exists to prevent, one layer down. So Go formats and the client paints strings it is handed. Formats are still edited as structured records; the client never sends a rendered string. The gate matters as much as the rule. Gate 4 proves the Go engine matches LibreOffice; gate 7 proves the client runs; neither proves that what a person sees is what the engine computed. Docs shipped precisely that: a conformance test comparing two runtimes of the same module, proving determinism, which WASM guarantees anyway, and never proving the thing its rule was about. Gate 11 reads the text actually painted in cells and compares it against the golden corpus. The rule to keep is that at least one gate must cross layers, because a suite of gates that all live inside one layer is a suite that agrees with itself. Also marks design system v2 as a dated dependency rather than an assumption, listing shipped versus staged explicitly. Pair, Allocate, rastrillo doctor and the bare-attribute grammar are ruled but not released, and neither consuming session could tell which was which by reading the upstream spec.
Reviewed-By: Fable (dispatched; see spec status line) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01APtNStXDZ5H2fAc1ZuGqtS
1 file changed,
+42
−1
docs/superpowers/specs/2026-08-30-sheets-design.md+42 −1
Intent
diff --git a/docs/superpowers/specs/2026-08-30-sheets-design.md b/docs/superpowers/specs/2026-08-30-sheets-design.md| index 7e1ab5b..cb89eef 100644 |
| --- a/docs/superpowers/specs/2026-08-30-sheets-design.md |
| +++ b/docs/superpowers/specs/2026-08-30-sheets-design.md |
| @@ -299,6 +299,21 @@ counts. The first draft applied it to cell storage, which was incoherent. |
| produced by a real spreadsheet, not by our reading of a spec. It is the only |
| honest way to claim 120 functions. |
| +**Go formats; the client paints strings it is given.** Ruling 2 put one |
| +engine behind cell *values* — but a value is not what a cell shows. `123.456` |
| +under a currency format displays `€123.46`, and if the browser renders that |
| +from a raw number, **number formatting is a second implementation of the |
| +same truth**, which is the exact bug class ruling 2 exists to prevent, one |
| +layer down. So the wire carries the display string alongside the raw value; |
| +Jspreadsheet paints what it is handed. Formats are still edited as |
| +structured records — the client sends "currency, 2dp", never a rendered |
| +string. |
| + |
| +*(Found by analogy: docs-e6's r1 declared "one engine, one truth" and then |
| +chose contentEditable, handing line-breaking to the browser — a second |
| +layout authority inside a spec whose founding rule forbade one. The same |
| +shape was sitting in this spec's formatting layer, unnamed. 2026-08-30.)* |
| + |
| **Recalc fan-out is priced, not assumed.** One edit to a cell feeding a |
| whole-column formula dirties thousands of dependents, each needing a seal, a |
| cell update and an SSE payload entry. The dirty set is capped per pass; past |
| @@ -689,13 +704,23 @@ upgrade with the module.** Re-copy deliberately on every rastrillo upgrade. |
| `rastrillo doctor` was proposed to make this mechanical, with this app as |
| its named consumer; adopt it the day it lands and delete the manual step. |
| +**Design system v2 is a dated dependency, not an assumption.** Everything |
| +this spec takes from it is either *shipped* (verified in `ui` at |
| +`origin/main`) or *staged* (ruled in rastrillo's spec, not in released |
| +code). Shipped: `ui.TokensCSS()`, the class vocabulary, the three themes. |
| +Staged, and therefore unavailable to us today: the bare-attribute grammar, |
| +`--rst-header-rule`, `Pair`, `Allocate`, `rastrillo doctor`. Neither of the |
| +two consuming sessions could tell a ruling from a released API by reading |
| +the design-system spec, which is why this paragraph exists rather than a |
| +reference to it. |
| + |
| **Upstream recording is a risk, not a fact.** `rastrillo doctor`, the |
| `(hue, chroma, background) → {fill, on-fill}` pair function and the |
| allocation entry point exist in this spec and in cross-session messages, and |
| in **zero files in the rastrillo repo**. Cross-session agreements that live |
| only downstream are agreements the upstream can silently never ship. **Task: |
| get each recorded upstream as an issue or spec section; until then treat all |
| -three as unavailable and keep the §10.2 shim.** |
| +three as unavailable and keep the §10.3 shim.** |
| ### 10.2 The four jank cuts, made concrete |
| @@ -801,6 +826,22 @@ From the first commit: |
| for cell content (§2.4). |
| 10. **Cache coherence** — assert no cell serves a cached value whose |
| `cache_version` predates its input's version (§4.4). |
| +11. **Computed value to painted output.** A browser drive reads the *text |
| + actually painted* in cells and compares it against the golden corpus's |
| + expected display strings — crossing from the engine to the screen. |
| + |
| +**Why gate 11 exists, and why gates 4 and 7 do not cover it** (docs-e6, |
| +2026-08-30). Gate 4 proves the Go engine matches LibreOffice. Gate 7 proves |
| +the client runs. Neither proves that what a person *sees* is what the engine |
| +computed — and a gate that compares two of our own layers against each other |
| +can stay green forever while the product is wrong. Docs shipped exactly that |
| +bug: a conformance test comparing two runtimes of the same module, proving |
| +determinism, which WASM guarantees anyway, and never proving the thing the |
| +rule was about. |
| + |
| +The rule to keep: **at least one gate must cross from computed value to |
| +painted output.** A suite of gates that all live inside one layer is a suite |
| +that agrees with itself. |
| Review on a deployed canary, never localhost. Verify a deploy with |
| `X-Carlos-Version` on the canonical host after the watch — never a 200. |