Skip to content

spike: shim-in-pane substrate candidate - #75

Closed
arcaven wants to merge 2 commits into
mainfrom
spike/shim-in-pane
Closed

spike: shim-in-pane substrate candidate#75
arcaven wants to merge 2 commits into
mainfrom
spike/shim-in-pane

Conversation

@arcaven

@arcaven arcaven commented Jul 31, 2026

Copy link
Copy Markdown
Member

Marvel is choosing what owns the terminal, and the leading candidate has never been built, so its costs have been argued rather than measured. This branch builds it and measures it against the five signals pre-declared in aae-orc-e35c, so the substrate decision in aae-orc-kxce has numbers instead of preferences.

This is a spike. It feeds the kxce decision and is not for merge as-is. Prototype error handling, smallest protocol that answers the questions, one host, one OS.

What is here

cmd/marvel-shim runs inside a tmux pane as the OS parent of one harness: creack/pty allocates the child's PTY, the shim inherits its own stdio from the pane, tees child output to Unix-socket subscribers, and serves status/signal/stop/inject on a second socket. Launch shape is tmux new-window 'marvel-shim --control C --stream S -- claude'.

cmd/shimprobe carries the test children and clients; scripts/shim-spike.sh drives one subcommand per signal on a private tmux server socket (tmux -L shimspike), so it never touches an operator's sessions. Reproduce everything with scripts/shim-spike.sh all.

Results

All five signals pass. Two of them produced boundaries that matter more than the pass:

  • Run headless with no terminal above it, the shim gives the child a PTY and terminal capability queries still hang. The shim is not a terminal emulator; something above it has to answer. That is direct evidence against the candidates where marvel or the shim replaces tmux.
  • With --on-hup=detach the shim survives losing its pane, child alive and control socket serving. tmux is load-bearing for terminal emulation, not for supervision.

Claude Code 2.1.220 and codex-cli 0.146.0 produce byte-identical escape-sequence-inclusive pane captures plain and under the shim, and inject through the control socket drives both TUIs. The tee carried 300k lines with zero loss at about 25 MB/s, filling the shim-PTY-tee row that finding-005 left blank. Inject adds 25-40µs at p50 and showed no interleaving corruption from two concurrent supervisors at any payload width tested.

The signal-2 run found a real defect: child exit killed the subscriber pump goroutines mid-queue, so a lagging consumer lost 89% of the stream. Fixed, with a regression test in cmd/marvel-shim/stream_test.go.

Full method, per-signal evidence, measurements, macOS specifics, and a recommendation section addressed to aae-orc-kxce are in _kos/findings/finding-004-shim-in-pane-spike.md. Real Cursor CLI verification and a Linux run are named as future work; the decision stays with the operator per ADR-007.

Cost of merge

Additive only: two new binaries under cmd/, one script, one new dependency (github.com/creack/pty). No existing package is touched. go build, go vet, go test ./..., and golangci-lint are clean.

Refs: aae-orc-e35c, aae-orc-kxce

arcaven added 2 commits July 31, 2026 17:42
Spike for aae-orc-e35c, feeding the aae-orc-kxce substrate decision. Not
production code and not for merge as-is.

marvel-shim runs inside a tmux pane as the OS parent of one harness. It
allocates the child's PTY via creack/pty, inherits its own stdio from the
pane, tees child output to Unix-socket subscribers, and serves status,
signal, stop, and inject on a second Unix socket. Inject writes to the PTY
master, so the child cannot tell injected bytes from typed ones.

shimprobe carries the test children and clients: a size-aware child, a
numbered-ANSI producer, a terminal-capability prober for the falsification
case, a line-stamping echo child, a stream consumer, a control client, a
verbatim stream dump, and the round-trip timer. scripts/shim-spike.sh drives
one subcommand per pre-declared signal on a private tmux server socket.

The stream test guards a defect the signal-2 run found: child exit used to
kill the subscriber pump goroutines mid-queue, losing the tail for any
consumer that had not already drained.
…ed (finding-004)

All five pre-declared signals pass on macOS 26.5.2 with tmux 3.7b. The two
results that carry weight for the aae-orc-kxce decision are boundaries rather
than verdicts: run headless with no terminal above it, the shim gives the child
a PTY and terminal capability queries still hang, so the shim is not a terminal
emulator and something above it has to answer; and with --on-hup=detach the
shim survives losing its pane with the child alive and the control socket
serving, so tmux is load-bearing for terminal emulation but not for supervision.

Claude Code 2.1.220 and codex-cli 0.146.0 produce byte-identical
escape-sequence-inclusive pane captures plain and under the shim. Stream tee
carries 300k lines with zero loss at about 25 MB/s, which fills the
shim-PTY-tee row finding-005 left blank. Inject adds 25-40µs at p50 and showed
no interleaving corruption from two concurrent supervisors at any payload width
tested. Real Cursor CLI verification and a Linux run are named as future work.
@arcaven arcaven closed this Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant