✅ Prove one session view renders from source and a binary (#799) - #805
Open
taras wants to merge 2 commits into
Open
✅ Prove one session view renders from source and a binary (#799)#805taras wants to merge 2 commits into
taras wants to merge 2 commits into
Conversation
A terminal session was the one part of this system nothing could test. The rendering path existed only inside a running agent UI, so a regression in how a message is selected, replaced, coalesced, scrolled or repainted reached a person rather than a suite. This drives the whole path headlessly. `@bomb.sh/tty` 0.9.0 does layout, input decoding and ANSI as pure computation with no terminal attached, so one deterministic journey can ask the questions a reader would notice: seven named Markdown presentations render, a repository-local `Tool.md` outranks the default beside it, a streaming replacement lands in the same place, a backlog collapses to its latest completed revision, the view stays where the reader put it across an append and a resize, and an update costs fewer bytes than a repaint. Every claim carries a control that breaks it. The nine controls are a closed enum, each run in a process of its own, and the same invariant checker that admits the positive journey has to reject each one by the category of the claim it broke — so a claim that quietly stopped being checked fails here instead of passing. The journey runs twice: from TypeScript under Deno, and from a `deno compile` executable started outside the checkout with the proof Markdown explicitly embedded. A binary that lost a component has nothing to fall back on, so the two records are required to be equal in whole. Neither run may reach the network, spawn a process, write, read the host beyond the proof's own component roots, or use system or FFI authority. Environment is the exception and cannot be otherwise: the module graph an execution loads probes `process.env` while it is still being imported, so a process that denied it could not reach this proof's own code. That authority is withheld where a document can see it instead, and the document filesystem ledger records every path either journey asked for. The proof is disposable test infrastructure. It adds no production type, no component props, and no export; the `@bomb.sh/tty` pin is an exact root devDependency, and the test asserts that no shipped package adopted either it or these modules.
PR #805: ✅ Prove one session view renders from source and a binary (#799)18 files, +3474 / -932 Scope🔴 PR has 4406 lines changed. Split into focused PRs. 🟡 4406 lines changed. PRs under 400 receive more thorough review. 🟡 PR mixes config and source changes. Structural🟡 1 console statements. Slop✅ Slop indicators look low. Static AnalysisOxlint: 6 diagnostics across 2 files (4 rules) no-floating-promises (3): scripts/tests/session-rendering/journey.ts CorrectnessNo extraneous code patterns detected. |
This was referenced Sep 11, 2026
Downloaded from the Measure test weights run for 9a3cf24, unedited. The proof measures 15.7s under Deno and is charged to no other runtime, which is what the exclusion manifest says it should be.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A terminal session is the one part of this system nothing could test. The
rendering path existed only inside a running agent UI, so a regression in how a
message is selected, replaced, coalesced, scrolled or repainted reached a person
rather than a suite. Closes the evidence gap #799 describes.
What changes
Before:
No test drove a session view at all. Component selection for a message
presentation, streaming replacement, backlog collapsing, scroll and follow
state, resize, and incremental repaint were only ever exercised by a human
watching a real terminal.
After:
One deterministic Deno test runs a finite session journey twice — from
TypeScript source and from a
deno compileexecutable started outside thecheckout — and requires the two evidence records to be equal in whole. Nine
rejecting controls, one per claim, each run in a process of its own.
How it works
@bomb.sh/tty0.9.0 is a terminal renderer and input parser with zero I/O:it takes an operation tree and returns ANSI bytes, and takes raw bytes and
returns decoded key events. Both are pure computation over bundled WebAssembly,
so a full session view can be driven with no terminal, no PTY and no emulator.
A source task publishes immutable snapshots of a conversation. An ingest task
reduces each one the moment it arrives — fresh structural state, dirty stable
ids, a monotonically increasing view version. A projector renders whatever the
newest state says: a projection that resumes against a stale version is
discarded and restarted, and a commit is keyed by the entry's own id, so a
replacement takes the same place rather than arriving beside what it replaces.
Each entry is projected by executing an ordinary Markdown component. The
DocumentOutputcapture takes the Markdown before any terminal formatting,and a narrow projector lexes the paragraph / emphasis / fenced-code subset with
the existing parser and fails closed on anything else.
marked-terminalis notinvolved: tty alone decides what a frame's bytes are.
Review guide
Start with:
scripts/tests/session-rendering.test.tsThen review:
scripts/tests/session-rendering/evidence.ts— the invariant checker and therecord parser. One checker admits the positive journey and rejects every
control, by category.
scripts/tests/session-rendering/journey.ts— the scope-owned session view:private entry shape, ingest/project split, barrier, viewport, tty.
scripts/tests/session-rendering/markdown-projection.ts— the lexer and theoperation tree.
defaults/Session/Message/*.mdand the singlerepository/components/Session/Message/Tool.mdoverride.Look carefully at:
journey.ts. The source publishes the blockingrevision, waits for the barrier to actually engage, then publishes two more
revisions and the completion. Without that wait the backlog could be ingested
before the projector reached the barrier, and the coalescing claim would be
about nothing.
ensure()is registered before anything is acquired orsubscribed. The tty objects hold no host resource and expose no close API, so
teardown is the scope dropping its references.
What must stay true
existing include mechanism, checked by
presentation-selectionand broken bythe
omit-componentcontrol.include ordering, checked by
override-precedenceand broken bydefault-before-repository.checked by
structured-markdownin both the raw captures and the operations,independently, and broken by
plain-markdown.entry id, checked by
stable-replacement, broken byunstable-regions.checked by
coalescing, broken byno-coalescing.resize-preservation, broken byrow-offset-viewport.bounded-diffagainst a freshly constructed term rendering the same visibleframe, broken by
whole-history-repaint. No ANSI sequence and no byte countis written down anywhere.
forbidden-integrationover denied process authorities and a documentfilesystem ledger, broken by
forbidden-read.checkProductionBoundaryover each workspace manifest and export map.How to verify it
deno task test scripts/tests/session-rendering.test.ts \ scripts/tests/runtime-exclusions.test.ts \ scripts/tests/test-file-discovery.test.tsand fails if a
--includeis dropped — the binary has no checkout to fallback on and is deliberately run from a private temporary directory.
process exits non-zero (an accident) or is admitted (a claim nobody enforces).
compareRecordsis shown to reject both a missing member and a mismatcheddependency version, and to report no difference for a record against itself,
so the equality assertion is not passing vacuously.
checkJourneyis not green for the wrong reason.Scope
Included
@bomb.sh/tty0.9.0 root devDependency and the generated lockupdates.
Intentionally unchanged
configuration, or component-resolution behavior.
connection, provider-file access, PTY, terminal emulator, Grid provider,
Workflow behavior, or durable UI state.
test-weights.json— measured on a runner after the corpus settles, never byhand.
New dependencies
@bomb.sh/tty0.9.0, exact, rootdevDependenciesonly.ANSI diffing, as pure computation with no terminal attached.
marked-terminalformats Markdownfor a terminal but neither lays out a viewport, nor decodes input, nor
produces a cell-level diff, so it cannot answer whether an update costs less
than a repaint.
Generated or mechanical changes
deno.lockandpnpm-lock.yamlcome fromdeno install --frozen=false --dev --save-exact --package-json @bomb.sh/tty@0.9.0followed by
deno task setup. Both deltas are the single new package.Risks and limitations
deny network, subprocess, write, system and FFI authority outright, and read
only the proof's component roots plus core's own catalog. Environment is the
exception, and not by choice: the module graph an execution loads probes
process.envwhile it is still being imported —whichreadsOSTYPE, anddebugenumerates the whole environment — so a process that denied it cannotreach this proof's own code at all. The authority is therefore withheld where
a document can see it instead: no host
Envprovider is installed, and thedocument filesystem ledger records every path either journey asked for. This
is a deviation from the frozen matrix's wording, reported rather than worked
around.
scripts/tests/; reverting the commit removes it and the dependency pin withno production consequence.
Scope confirmation