clay-borg/workplans/CB-WP-0014-execute-the-javascript.md
tegwick 4c930fac32 Declare CB-WP-0014: execute the JavaScript, tier M
Declaration 9 of 12. Structural tier M (adds an external dependency to
the toolchain); d4 = 2, no override.

CB-EV-0010 §4 recorded that the emitted JavaScript has never run, and
that sentence is the only thing keeping INTENT stage 1 open. It was
carried for a pass on the assumption that executing it was not possible
here. node v24.11.1 is on this machine. The assumption was never
checked — the same shape as every other finding of the last three
passes: a claim carried because nobody ran the command that settles it.

Executing it does not prove the table looks right; that needs a
rendering engine and a human eye. It proves the contract ADR-0007
control 5 rests on — that the page reports raw pointer facts and
nothing else — which is currently asserted by grepping the script for
game vocabulary. Grepping for absent words is a weak proxy for "this
code cannot construct a command".

T01 is a real dependency decision, priced under ADR-0007 D3's
acquisition rule so that "it's only a dev tool" is not an automatic
pass. CI runs on rust:1.97, which has no node, so the test either
forces an install or skips — and a test that skips silently is the
harness-does-nothing class this project has found five times.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 07:43:24 +02:00

136 lines
5 KiB
Markdown

---
id: CB-WP-0014
kind: product
title: "Execute the JavaScript, and close or keep stage 1"
status: todo
---
# Purpose
```
structural tier M (adds an external dependency to the toolchain —
InnerLoop v1.6 tier table)
chaos d4 = 2 → no override
declared tier M
```
Declaration 9 of 12. Tier M merges the survey and the ADR into one
document; the adversarial review is optional.
## The one thing blocking stage 1
CB-EV-0010 §4, stated plainly at the time:
> **The emitted JavaScript has never run.** Every test is on the Rust
> side: the socket loop is driven by synthetic HTTP, and the page is
> asserted against as a parsed document. No browser engine has executed
> `SCRIPT`.
All four of INTENT stage 1's named deliverables now exist. That sentence
is the only reason the stage is still open, and it has been carried
unexamined for one pass on the assumption that executing it was not
possible here.
**It is possible.** `node` v24.11.1 is on this machine. The assumption was
never checked, which makes it the same shape as every other finding in the
last three passes: a claim carried because nobody ran the one command that
would settle it.
## What executing it actually proves
Not that the table *looks* right — that needs a rendering engine and a
human eye, and neither is available here. What it proves is the contract
ADR-0007 control 5 rests on:
> the page reports **raw pointer facts and nothing else**, and Rust
> decides what command they mean.
That contract is currently asserted by a test that greps the emitted
script for game vocabulary. Grepping for the absence of words is a weak
proxy for "this code cannot construct a command". Running it, feeding it
synthetic pointer events, and observing exactly what it puts on the wire
is the real check.
## Task: decide whether a JS engine joins the toolchain
```task
id: CB-WP-0014-T01
status: todo
priority: high
```
Write `decisions/ADR-0009-*.md` (tier M: survey and decision in one).
**This is a real dependency decision, not a formality.** CI runs on the
`rust:1.97` image, which has no `node`. Adding a test that needs one means
either installing it in CI or letting the test skip — and **a test that
skips silently is the harness-does-nothing class this project has found
five times.** If it can skip, it must fail loudly instead.
Decide, and price it under ADR-0007 Decision 3's acquisition rule — the
rule this project adopted precisely so that "it's only a dev tool" is not
an automatic pass:
- `python3` is already a toolchain dependency, so this is the second, not
the first. Say whether that makes it cheaper or is merely a precedent
being leaned on.
- What the alternatives cost: no execution at all (status quo, and the
reason stage 1 is open), or a JS interpreter as a Rust crate (measure it
— do not estimate, and note that AM-4b now has an unmeasured proc-macro
share of its own).
- Whether the engine is required by `make all` or by a separate target.
**AM-4b is the budget this lands in**, and it is the instrument
CB-WP-0013 explicitly declined to correct. Do not use its uncorrected
headroom as an argument.
## Task: run it, end to end, through a real socket
```task
id: CB-WP-0014-T02
status: todo
priority: high
```
Execute `cb_render_html::doc::SCRIPT` in a real JS engine against a
minimal DOM, synthesize a pointer-down and pointer-up on two real element
ids from a real emitted document, and let its `fetch` reach the **actual
`Server`** — the same `next_choice` loop `cb-play --serve` runs.
Acceptance: the seat's `Choice` comes back from a pointer gesture that
originated in JavaScript. That is the first time anything in this project
has closed that loop.
**Controls, and they are the point.** The test must go red when:
- the JS is mutated to POST a command name instead of element ids — this
is **control 5 asserted rather than grepped**, and if it does not fire,
the grep test was the only thing holding the contract up;
- the pointer events are not delivered at all — the EXPECT-VACUOUS case, a
harness that runs a script and asserts nothing about what it did;
- the token is stripped from the endpoint the page was given.
## Task: close stage 1, or say what still blocks it
```task
id: CB-WP-0014-T03
status: todo
priority: high
```
`evidence/CB-EV-0012-*.md`, and then a decision on INTENT.
**Be precise about what is and is not established.** A passing JS test
proves the input contract and the loop. It does **not** prove that an SVG
table renders legibly, that a drag feels like a drag, or that a human can
play a game — none of which any test here can reach.
State which of stage 1's four deliverables are evidenced and which rest on
inspection, then close the stage or name the remaining blocker. Carrying
it open by default is as unexamined as closing it by default was going to
be.
**Adopt or reject the self-quoting rule** proposed in CB-EV-0011 §4: an
evidence file quotes the previous pass's final cost and never its own.
This pass is the first that can apply it — CB-WP-0013's figure is now
final. Decide it rather than inheriting it.