Skip to content

[Experiment 38] Multi-client terminal resize policy finding - #45

Merged
pseudoseed merged 9 commits into
mainfrom
builder/experiment-38
Aug 22, 2026
Merged

[Experiment 38] Multi-client terminal resize policy finding#45
pseudoseed merged 9 commits into
mainfrom
builder/experiment-38

Conversation

@pseudoseed

Copy link
Copy Markdown
Owner

Refs #38

Follow-the-focused-client meets FR-38 additively for v2-only attach.

Finding. Last-writer-wins is real on current PtySession.resize. Two attached clients, A at 80x24 then B at 40x12, left live bash at stty size 12 40. Ignore-hidden still fights when both clients are visible. Per-viewer reflow cannot be done with one resize() call.

Additive. The prototype is a v2-owned broker that calls the existing resize() once. pty-session.ts is untouched.

Not additive. Mixed v1+v2 attach to the same session. tower-websocket.ts:76-80 still forwards every resize frame. That is a scope call, not a reason to edit PtySession.

Notes, prototype, and captured output: codev/experiments/38-multi-client-resize/.

No production code. Issue stays open for the follow-up.

@pseudoseed

Copy link
Copy Markdown
Owner Author

Reviewed at low risk tier and read in full: 692 additions, zero production files, everything under codev/experiments/ plus porch state. Base is main and #40's commits are not in the diff, as claimed.

Approved. Merge with --merge, not squash.

What I verified independently, rather than taking the summary

  • git diff --stat -- packages/codev/src/terminal/pty-session.ts is empty. The hard constraint from Part 0 held.
  • The last-writer-wins reproduction is a real PTY, not a described one. The capture carries the macOS zsh banner and stty size printing 12 40 after client B resized to 40x12. That is the shell reporting its own dimensions, which is the only evidence that actually settles it.
  • tower-websocket.ts:80 does forward resize control frames straight into session.resize, as the notes say. Two further call sites exist at pty-manager.ts:239 and :369, which is the REST path the notes name as "the same hole."
  • v2-resize-broker.mjs imports nothing from the terminal layer and takes applySize by injection. It is promotable as written.
  • Hypotheses and success criteria were written before the prototype, not fitted to the result.

What makes this finding worth keeping

Rejecting the two losing policies on evidence rather than taste is the valuable part. Ignore-hidden looks reasonable until you notice it only helps tabbed-away panes and still fights when both devices are visible, which is the entire product case. Per-viewer reflow is the nicer UI and cannot be done additively, because one PTY has one size.

The refusal to fake per-viewer reflow with client-side xterm wrap was the right call, and the stated reason is the correct one: it would look right until an agent drew a full-screen TUI at the PTY's real width, and then the iPad would be wrong in a worse and more confusing way.

Carried into the spec, not blocking this merge

  1. FR-38 is additive only for v2-to-v2 attach. A v1 client on the same session still calls resize() through tower-websocket.ts and the REST endpoint, and no v2 wrapper can stop it. The spec decides: forbid mixed attach, or accept the gap while the old UI is still used on that session. Routing v1 through the broker means editing a hot upstream file, which is a fork-constraint decision and deliberately not this spike's call.
  2. Focus is itself last-writer-wins. Two viewers both sending an explicit focus frame land back in the same shape one layer up. The notes flag treating input as implicit focus as the cheap fix and are honest that it was not coded. Worth doing in the production module.
  3. Not tested, correctly disclosed: real iPad Safari, WebGL context loss, client-side wrap. Those need a device and belong with the [Spike] v2 UI: HTTPS on a phone via Tailscale, through to one delivered push #39 work.

Tracking the production follow-up under #37 rather than holding #38 open for it.

@pseudoseed
pseudoseed merged commit 58fd5f5 into main Aug 22, 2026
7 checks passed
pseudoseed added a commit that referenced this pull request Aug 22, 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