Repository navigation
Description
Finding
A session with only join scope can send resize up to 500×200, but the screen DTO is capped at 120×50 and the guest layout(width, height) result must fit presentation_bytes (default 8192). A reflowing app that fills a 120×50 grid exceeds 8192 bytes, so one participant resizing their window makes the world's program unhealthy for everyone until an admin reinstalls. This is the same trap-poisoning class as #547, but the trigger is an unprivileged joiner's window resize, which is meant to be per-connection and unjournaled.
Evidence
pkgs/id/src/world_presentation.rs:15-17:MAX_SCREEN_WIDTH = 120,MAX_SCREEN_HEIGHT = 50.pkgs/id/src/world_session.rs:2309-2321:ClientFrame::Resizeacceptswidth 1..=500 and height 1..=200for any session holding join scope, and callssend_viewwith that viewport.pkgs/id/src/world.rs:78:presentation_bytes: 8192default.pkgs/id/src/world.rs:3109-3125:ViewAtsetsself.program_healthy = falsewhen thelayoutoutput exceedspresentation_bytes, and on anylayouterror — a world-wide state, not a per-session one.- A 120×50 grid is 6000 cells plus JSON framing, which easily exceeds 8192 bytes; resize is documented as session-local (
viewport_is_session_local_and_never_advances_the_world_sequence).
Why it matters
An unprivileged participant can take a shared world offline with a single resize, and it stays unhealthy for every participant until someone reinstalls the module. This is a denial-of-service the current bounds do not prevent.
Suggested fix (do not fix inline here — see note)
- Clamp
width/heighttoMAX_SCREEN_WIDTH/MAX_SCREEN_HEIGHTbefore callingview_at/send_view. - In
ViewAt, treat an oversizedlayoutresult as a per-session error (fall back toview()plus cropping) instead of settingprogram_healthy = false.
Proving test
A mock WorldProgram whose layout returns >8192 bytes when width > 100. Session A resizes to 500×200; assert session B still receives a view frame and that input is still accepted.
Not fixed inline
Left as an issue (not fixed in PR #804) because the fix lands in world.rs / world_session.rs, which Session B's in-flight module split (PR #808, F11.10) is moving; an inline edit here would collide with that work.
Related
#547 (F11.17: a trapping view must not poison the world) — this is a narrower, join-scope trigger.
Acceptance criteria
- A join-scoped session's
resizecan no longer make a world permanently unhealthy: an oversizedlayout()result for one connection's viewport degrades to a per-connection fallback (crop/clamp to that connection's presentation budget) instead of setting world-wideprogram_healthy = false. - Resize acceptance bounds and the screen DTO caps (120×50) /
presentation_bytesbudget are reconciled so the guest is never asked for a layout that cannot fit. - A regression test reproduces the poison path (joiner resize to a large viewport on a reflowing app) and shows the world stays healthy for other participants.
- Existing world/presentation tests stay green.
Activity
docs(id): Phase 14 plan — close-out: finish, measure, verify, open th…
fix(world): fallback to cropped view when guest layout() exceeds pres…
dezren39 commentedon Oct 26, 2026
Intake review
Related: Open PR #927 attempts the #811 fix and is still open; #942 tracks a distinct facet found in that PR (its oversized-layout fallback never re-checks
presentation_bytes). Same trap-poisoning class as #547. No merged PR resolves this (verified 2026-10-26).Notes: Priority high: an unprivileged joiner can permanently poison a shared world for everyone until an admin reinstalls — an availability bug with a trivial trigger (resizing a window). Acceptance criteria appended by this intake pass; original body preserved verbatim above them.
Risks: The fix interacts with PR #927's in-flight approach; whoever picks this up should coordinate with that PR rather than open a competing one.
Suggested approach: Clamp the effective layout viewport to the presentation budget per connection and treat an over-budget layout as a per-connection error, never a world-health transition; land alongside or inside PR #927.
fix(world): fallback to cropped view when guest layout() exceeds pres…
dezren39 commentedon Oct 27, 2026
🤖 Agent note · closeout — fixed on main, closing (queue task 1257, #1076 slice 5)
Re-checked against current main
f9c9ffdb(2026-10-27). The poison chain this issue filed — joiner resize → guestlayout()output exceedspresentation_bytes→program_healthy = falseworld-wide — no longer exists at either layer:pkgs/id/src/world/actor.rs,View~L1085 andViewAt~L1122): an over-limit presentation now incrementsview_failuresand returns an error for that view request only;program_healthyis not touched. A trapping view/layout likewise degrades to an error screen (in-code comment: 'does not poison the world').pkgs/id/src/sandbox.rsview()/layout_at()): a trapped view or layout does not poison the guest instance (F11.17) — commits9f4633a3('degrade a trapping view to an error screen') and07a906d0('do not poison the guest instance on a trapped view or layout'), both on main.a_trapping_view_degrades_to_an_error_and_recovers_on_the_next_event(pkgs/id/src/world/tests.rs:2416) asserts the trap is counted inview_failuresand the world recovers on the next event.The resize acceptance range itself is unchanged (
world_session/mod.rs: width 1..=500, height 1..=200 for join-scope sessions) andpresentation_bytesstill defaults to 8192 (world/mod.rs:91) — what changed is the consequence: per-viewer error instead of a world-wide outage.One residual gap, noted for #1076 slice 6: no dedicated test asserts the oversize (non-trapping) view/layout case leaves the world healthy — the existing test covers the trapping case and the oversize branch is structurally identical in the actor. Tracked as a slice-6 coverage item on #1076 rather than keeping this bug open.
Closing as fixed.
Merge pull request #927 from developing-today/fix-issue-811-425942400…