Bridge — The Control Surface
L0 RUNTIME · BUILT · DAILY USE

The factory's first organ is a window.

Built · 40 tests · in daily use

The GUTS Bridge is a private, browser-based control surface for the tmux sessions on one always-on machine. A session opened on the phone is the same live session when it is reopened on the desktop, with the same scrollback and the same running process. It survives disconnects, network changes, and overnight runs, because tmux holds the state, not the browser.

Under the hood it is deliberately small: Node, xterm.js, and node-pty wrapping tmux, reached only through Tailscale's private tunnel, behind a lock screen. Forty tests pass, unit and real-tmux integration. It runs the factory's front door every day.

claude-1● WORKING
~/projects/guts-bridge
✻ Razzle-dazzling… (34s · esc to interrupt)
claude-2● READY
~/projects/gims
Done. 12 files changed. Waiting on you.
dev-serverSHELL
~/projects/site
GET /blueprint.html 200 · 4ms

THE DASHBOARD, AS BUILT — one card per session: name, working directory, last output line. A stopped agent gets the ready-green border.

The browser is not running the factory. The browser is a window into the machine running the factory. The Bridge manages tmux sessions, full stop: no ledger, no routing, no planning. That restraint is the point. The runtime layer had to exist, stay up, and be trustworthy before any organ could stand on it. Every layer above this one, GIMS events, GONS sessions, GEDS episodes, GOMS tasks, assumes a machine that is always on and a human who can always reach it. The Bridge is that assumption, made real and tested.

What it does

Two headline capabilities, browser-tab switching between tmux sessions and private multi-device access over Tailscale, plus the ergonomics that make a phone a real console.

claude-1 logs dev + $ tmux new -A -s claude-1 $ claude ▌ live pty over websocket same session on every device
01 · SESSIONS AS TABS
Named tmux sessions become browser tabs: create with a tap, open, switch, kill (behind a confirm gate). The terminal is a real one, xterm.js bound over a WebSocket to node-pty attaching tmux, not a screenshot or a log tail. tmux is the source of truth; the server stores no session state and re-queries tmux for everything.
claude-1 ~/bridge claude-2 ● ~/gims dev-server ~/site logs ~/var ▸ last output line… ▸ waiting on you ▸ 200 · 4ms ▸ tail -f app.log GET /api/dashboard
02 · THE DASHBOARD
One card per session: its working directory, the last line of output, and a status badge. Enough to answer what is the machine doing right now from a phone, without opening a single terminal. This is the factory's floor view in embryo, one glance over every worker body.
a4f2 c81d WORKING e703 = e703 READY hash(screen) at poll t vs t+1 changing = working · identical = waiting
03 · AGENT AWARENESS
The Bridge knows when an agent has stopped and is waiting on you. The mechanism: it hashes the captured screen and compares across polls. A working agent's screen keeps changing (the spinner, the elapsed timer); a stopped one is byte-identical, and its card flips to a ready-green border. This landed after two simpler approaches failed: footer text like "esc to interrupt" persisted as a frozen frame after generation ended, and tmux activity timestamps missed in-place TUI repaints. This detection is the embryo of GONS-Core's heartbeat.
$ claude ▌ working… ESC TAB CTL ↑↓ ^C ^B
04 · PHONE-FIRST ERGONOMICS
A key toolbar supplies what phone keyboards lack: Esc, Tab, a sticky Ctrl, arrows, Ctrl-C, and the tmux prefix. Page-up, page-down, and jump-to-bottom scroll buttons; autocorrect disabled; a layout that survives the soft keyboard. The phone is not a degraded client, it is the primary console in daily use.
defaults names·dirs·cmd claude-1 claude-2 dev-server one tap after a reboot
05 · FLEET RESTORE
Save the current sessions as defaults, their names, their folders, and the agent command each one runs, then recreate the whole set with one tap. A reboot stops being a reconstruction project: the shape of the fleet is a saved thing, and standing it back up is a single gesture.
cookie cleared · lock screen from any device
06 · LOCK ON DEMAND
A Lock button on the dashboard ends the session, clears the auth cookie, and drops back to the lock screen, from any device. The gate is not only at the entrance; the human can close it at will. This is Rule 4 of the constitution in its first built form.

The security posture

A browser terminal is a shell into the machine, so it gets a gate even inside a private network. The model in one line: Tailscale restricts who can reach it, and a lock screen restricts who can use it.

LOOPBACK ONLY
The server binds 127.0.0.1 and nothing else. Tailscale Serve over HTTPS is the sole ingress: tailnet only, never Funnel, no port forwarding, no public SSH. Off the tailnet, the Bridge does not exist.
FAIL-CLOSED
No passphrase, or a signing secret shorter than 32 characters, and the server refuses to boot. It cannot be run open by accident.
THE LOCK
A rate-limited, timing-safe passphrase check issues a signed HMAC cookie (HttpOnly, SameSite=Strict). The same cookie is re-verified at the WebSocket handshake, before any shell is spawned.
NO SHELL STRINGS
Session names are the only untrusted input that reaches a subprocess. They are validated against a strict allowlist (^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$), and every tmux, git, and pty call uses discrete arguments, never a shell.
SECRETS STRIPPED
BRIDGE_* variables are removed from every spawned shell's environment, so nothing running inside a session, including an agent, can read the cookie-signing secret.
ONE HUMAN, TRUSTED TAILNET
Single passphrase, single operator, by design. The per-tab read-only View toggle is fat-finger prevention on a phone, not an access tier. The View/Operator/Admin tiers belong to a later layer and are not claimed here.

What it is not

The Bridge is MVP 0–1 of the blueprint's ladder, deliberately. Everything below was excluded on purpose, so the first organ could be boring, finished, and trusted.

NO GIMS
No event ledger, no session ledger, no work claims. The Bridge stores nothing but the auth cookie; it shells out to tmux live and re-queries it for everything.
NO GONS
No router, no spawning sessions from structured tasks, no message routing between sessions, no briefing console. The ready-green border notices a stopped agent; it does not act on it.
NO GEDS · NO GOMS
No anomaly or tension engine, no handoff packets, no goal, sprint, or task planning. The Bridge does not know whether a session runs Claude Code, a dev server, or htop, and does not care.
NO TIERS
No multi-user permission levels. One passphrase, one trusted human.
NO PUBLIC EXPOSURE
No Funnel, no port forwarding, no hardening for the open internet. Tailnet only, by design and by check (tailscale serve status must show Serve, not Funnel).

From the project's own README: "it manages tmux sessions, full stop." A tool that claims less and delivers all of it is the right foundation for a system whose later layers will have to be trusted with much more.

How it grows

The Bridge does not get replaced as the factory grows. It gets fed. Each rung of the ladder gives the same window more to show.

NOW ✓

The window Built

Lock screen, session tabs, dashboard cards, agent-stopped detection, one-tap fleet restore. The human can reach, read, and steer every worker body on the machine from any trusted device.

First sentences Next

The Bridge emits its first ledger sentences: a session created, opened, or killed becomes an append-only GIMS event, subject · verb · object · at · by · under. The window stops being the only witness; the factory starts keeping its own record.

MVP 3–4

From session cards to agent cards Designed

The design: once GONS-Core spawns sessions from GOMS objectives, today's card (name, directory, last line) will grow into an agent card carrying the task, the branch and worktree, the GIMS work claims, a risk level, and actions. The dashboard will become the floor view of GONS-Console, and the ready-green border will mature into a real heartbeat.

Agent: GOMS-Auth-1 Task: Refactor auth middleware Branch: agent/auth-refactor Worktree: ~/worktrees/guts-agent-auth Claims: backend/auth/** · tests/auth/** (exclusive-write) Status: tests failed — repair attempt 2/3 Risk: medium Actions: [Terminal] [Diff] [Ask GEDS] [Pause] [Summarize] [Request Merge]

The full ladder, MVP 0 through 7, is laid out on the blueprint: event spine, foreman, command room, relevance engine, generalized intent. The Bridge is the rung everything else stands on, and the only one that had to come first.