plan: Phase 3 target is the CONSOLE — engine renders the same picker to a terminal
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 30s

The non-browser platform is a console/TUI renderer: the engine's platform ops map
to a text-node tree (harness-web's mock DOM is ~90% there), render-to-console
prints it, a raw-stdin input loop drives simulate-click/input. The same
~relate-picker runs unchanged in a terminal — browser is one platform binding,
console another, test harness a third.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 17:11:51 +00:00
parent 0b13701ea4
commit b0c0fdd4b1

View File

@@ -74,10 +74,40 @@ Keep ONLY what needs a real browser in `relate-picker.spec.js` / `spa-check.spec
Delete the per-behavior browser tests now covered by SX. Net: ~2 browser tests + an
SX suite.
### Phase 3 — Stretch: the engine drives a non-browser target ("something else")
The mock platform already *is* a non-browser target. This phase makes it a real
alternative renderer (e.g. server-side DOM string-builder, or a native UI shim) and runs
the same picker through it — concretely proving platform-independence. Optional / future.
### Phase 3 — The engine drives the CONSOLE (the non-browser target)
The concrete "something else" is a **terminal / console platform**. This is the natural
sibling of the test harness: a harness test *asserts* the engine's output tree; the
console platform *renders* that same tree to text. Same platform abstraction — one
observes it, one draws it.
What it means concretely:
- **Platform ops → a console-backed element tree.** The engine only ever calls platform
primitives: `dom-create-element`, `dom-append`, `dom-set-attr`, `dom-query` (by id, for
`sx-target`), `dom-remove-child`, `dom-parent`, `morph-children`, `dom-listen`, `fetch`,
`set-timeout`. Implement these against an in-memory tree of text nodes instead of the
browser DOM. The mock DOM in `web/harness-web.sx` is ~90% of this already.
- **Render = print the tree as text** (ANSI/box-drawing) — a `render-to-console` mode
alongside `render-to-html` / `render-to-dom` (see `spec/render.sx`'s mode table). The
results `<ul>` becomes a list; `.sx-error` becomes a red line; the filter input is a
text field.
- **Events = a TUI input loop.** Keypresses / selection map to `simulate-input` /
`simulate-click` on the focused node — exactly the harness's `simulate-*`, but driven by
a real keyboard instead of a test.
- **`fetch` stays HTTP** (the host already serves `text/sx` fragments + `relate-options`),
or talks to a local store.
Payoff: the **same** `~relate-picker``sx-get`, debounced filter, `revealed` paging,
`sx-swap=delete`, `sx-error` retry — runs unchanged in a terminal. That is the proof that
the SX hypermedia engine is a *general* runtime, not a browser library: the browser is
just one platform binding, the console is another, the test harness is a third. Ambitious,
buildable, and the most convincing demonstration of the whole architecture
(`[[feedback_runtime_control]]`, `[[project_zero_dependencies]]`).
Sketch of work: (1) a `console-platform.sx` implementing the platform ops over a text
tree (fork `harness-web.sx`'s mock element), (2) a `render-to-console` mode in render.sx,
(3) a tiny input loop (raw-mode stdin → focus model → `simulate-*`), (4) run the host's
picker against it. Phase 1's SX tests become the regression suite for the console renderer
for free (they already drive the tree, just don't print it).
## Gaps & risks to resolve during Phase 0