attach: stop nudging a child that is already the right size; remove --no-resize - #109
Merged
Merged
Conversation
…ght size The attach-time nudge (resize to cols-1 and back) exists to paper over serialize-replay artifacts. It fired on every attach, so connecting a viewer delivered SIGWINCH to an otherwise idle child — including the common case where the client attaches at exactly the size the session already has, where the child is by definition already drawn correctly. Nudge only when the attaching client's geometry differs from the session's, read before negotiateSize() so a smaller client that shrinks the session doesn't then look like it matched. `--force-resize` opts back in for children whose replay needs the redraw regardless. encodeAttach() now takes a flags bitmask rather than a geometryNeutral boolean, and the attach CLI path passes an AttachModes object instead of a fourth positional boolean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lw7FSfYArhebq26GUb1kHi
`pty attach --no-resize` (PR #96) let an interactive client receive the live screen and send input while opting out of min-wins size negotiation and the attach-time redraw SIGWINCH nudge. Its only consumer, fractal, is switching off it. The real problem fractal hit was the unconditional nudge on attach: every connect woke an idle child and perturbed the shared session. The parent commit fixes that directly — the nudge is now skipped when the client attaches at the size the session already has, with `--force-resize` to opt back in for children whose serialize replay needs the redraw regardless. That covers fractal's case without a second attach mode, so fractal now attaches ordinarily at the session's own geometry. Removes the ATTACH_FLAG_GEOMETRY_NEUTRAL protocol flag, the per-client `geometryNeutral` state and its stats counter, the `capabilities.geometryNeutralAttach` advertisement and the CLI's capability probe, and the `--no-resize` flag with its help and completion entries. ATTACH_FLAG_FORCE_RESIZE keeps its released value of 0x02; 0x01 is retired rather than reused. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lw7FSfYArhebq26GUb1kHi
This was referenced Jul 20, 2026
…ove-geometry-neutral-attach refactor(attach): remove geometry-neutral attach (--no-resize)
`--force-resize` was added alongside the conditional attach-time redraw nudge as an escape hatch, but nothing ever asked for it: no caller, no consumer, no reported child whose serialize replay actually needed the unconditional nudge. It was speculative surface, and it dragged an entire protocol mechanism along with it. Removing it lets the ATTACH frame go back to a plain 4-byte payload -- no optional flag byte, no `decodeAttachFlags`, no flag constants, no `AttachModes` plumbing through `cmdAttach`/`handleDeadSession`/ `doAttach`. `encodeAttach(rows, cols)` is once again exactly what it looks like. What remains is the branch's whole net effect: one behaviour fix. The attach-time redraw nudge fires only when the attaching client's geometry differs from the session's, so connecting a viewer at the current size no longer delivers SIGWINCH to an idle child. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lw7FSfYArhebq26GUb1kHi
schickling
marked this pull request as ready for review
July 20, 2026 21:29
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.
Now carries #110 as well, so this is the whole thing against
main: remove geometry-neutral attach, and stop nudging a child that is already the right size.The nudge
nudgeRedraw()(resize tocols - 1and back) fired on every attach. Its purpose is to paper over serialize-replay artifacts, but when a client attaches at exactly the size the session already has, the child is by definition already drawn for that geometry — so the nudge buys nothing and just deliversSIGWINCHto an otherwise idle process every time someone connects.It now fires only when the attaching client's geometry differs from the session's. The comparison is read before
negotiateSize(): a smaller client shrinks the session to its own size, which would otherwise look like it had matched by the time the decision is made. That case still nudges, as it should.--no-resizegoes awayYou asked whether fractal's embedded pane was read-only-with-crop or typed-into-while-cropped, and noted that read-only is already geometry-neutral so the feature wouldn't be strictly needed in the first case. The honest answer turned out to be that it isn't needed in either.
Fractal reads the session's geometry from
pty statsand opens its attach client at that size, cropping into the pane — it never reports the pane's dimensions. A client whose geometry equals the session's is inert innegotiateSize()by construction. So the geometry half of the neutral role was already a no-op for its only consumer.The 80×24 justification in #95 was a fractal defect — it launched
pty attachover pipes — not a pty gap, and it has since been fixed on our side by giving the attach client a real PTY. What genuinely remained was the nudge, which is fixed above for every client rather than through an opt-in role.What that leaves
The ATTACH frame goes back to a plain 4-byte payload.
ATTACH_FLAG_GEOMETRY_NEUTRAL,decodeAttachFlags, thegeometryNeutralclient field,capabilities.geometryNeutralAttach,clients.geometryNeutral,requireGeometryNeutralAttach(), andtests/neutral-attach-cli.test.tsare all gone.cmdAttach/doAttachreturn to their pre-#96 signatures.Net against
main: about 230 lines removed, ~10 added.I did briefly add the
--force-resizeflag you offered — then took it out again. You said we can always add it, and nothing needs it today; shipping an unused opt-in flag into your protocol would have repeated exactly the mistake this PR is undoing. If skipping the nudge does regress a child's layout, it's a small change to add then, and I'd rather that be driven by a real case.Verification
npm run typecheckclean.protocol,integration,completionssuites pass. Integration coverage: an ordinary attach at the session's current size produces noSIGWINCHin a quiescent child, and a client attaching at a different size still nudges.Unrelated pre-existing failures in my environment (all also present on
main):shells.test.tsandscreenshot.test.tsneedzsh/vim, which aren't installed here, andhelp.test.tsreports thecompletionscommand from #106 as undocumented.