| name | change-browser-runtime |
| description | Add, modify, or review Synergy Browser ownership, persisted page state, BrowserControl commands, routes and events, navigation policy, Desktop WebContentsView presentation, remote Browser host/WebRTC signaling and input, downloads, or Browser workspace UI. Use across packages/synergy/src/browser, Browser server routes/tools, packages/desktop, and packages/app Browser surfaces. |
Change the Browser Runtime
Trace the Shared Contract
- Read Browser runtime,
packages/synergy/AGENTS.md, packages/app/AGENTS.md, and packages/desktop/AGENTS.md.
- Identify the owner key and whether the behavior is canonical runtime state, a
BrowserControl command/result, a read-only event, presentation selection, host signaling, or Web UI state.
- Trace the change across Browser schemas/runtime, control and route handlers, persistence and reaping, Browser tools, Desktop host/view handlers, remote host/WebRTC data channel, generated SDK where applicable, and the Web Browser store/surface.
- Load
change-server-api for route/schema changes, develop-frontend for product UI, change-persistence for saved Browser state, and change-execution-boundaries for navigation or evaluation policy.
Preserve Ownership and Presentation
- Keep one Browser session per owner and at most one canonical page per Browser session. Do not introduce a tab adapter or merge host-only pages into canonical state.
- Keep page creation lazy. State reads, event subscriptions, signaling, and host attachment may ensure the owner session exists but must not create a page; ordinary first navigation owns page creation.
- Keep
POST /browser/control command/response behavior separate from the read-only /browser/events stream. Return explicit page-missing, host-pending, retryable, and terminal errors.
- Preserve Desktop-native
WebContentsView and remote WebRTC/data-channel presentation as peer modes over the same owner/page/control contract. Do not add iframe, screenshot-stream, pseudo-tab, or hidden fallback pages.
- Treat managed-local Desktop native presentation as strict. Bootstrap may passively read the owner key without a ticket, but events and controls require fresh owner-bound tickets after
host.registered; ticket, attach, renderer, and navigation failures remain in native recovery and never fall back to WebRTC. Web and remote Desktop select WebRTC explicitly.
- Keep pointer, keyboard, text, IME/paste, and viewport coordinates normalized across native and remote presentation. Preserve CSS width/height semantics and coalesced pending viewport behavior.
- Keep Chromium responsible for webpage network security. The gateway owns loopback binding, owner authentication, connection limits, CONNECT-establishment timeout, forwarding, and revoke cleanup; do not add IP-range classification, Fake-IP exceptions, localhost port lists, or DNS policy. Preserve protocol checks, workspace file containment, hidden/project metadata exclusions, download filtering, and sensitive-header redaction.
- Treat the server-provided session-state
ownerKey as canonical. Route directories select a route; they never derive native tickets, profiles, broker pages, or view attachment identity.
- Keep a native owner/page handle stable while replacing its
WebContentsView, control, and diagnostics generation. Preserve page/profile/proxy/URL/bounds/visibility/focus identity, emit page-scoped recovery status, keep recovery single-flight and bounded, and never replay an action whose execution outcome is unknown.
- Dispose live Browser state on session archive/delete and global shutdown; preserve profile, storage-state, download, annotation, and restored page-ID ownership.
- Keep Browser implementations out of the Agent worker runner's static dependency graph. Only serializable Browser tool definitions cross into the worker; callbacks, canonical sessions, Playwright/Chromium state, host signaling, native views, and WebRTC state remain Control Plane/tool-runtime owned.
- Attribute resource state by owner and page backend without exposing owner IDs. Retire the remote Host only after the broker reports no active canonical page; Performance aggregation must never close a page or stop the Host.
- Keep Browser viewer Origin authorization on explicit server CORS origins. Do not promote auto-detected LAN CORS origins or reverse-proxy forwarding headers into the viewer trust boundary. Origin checks supplement one-shot owner/page/role-bound tickets and never replace them.
Verify
- Add a failing test for the public invariant before implementation. Cover page creation, owner isolation, control/event separation, host transitions, policy, persistence, or cleanup at the owning layer.
- Run the focused Browser route/runtime/tool tests, Desktop Browser/view tests, and Web store/component tests affected by the change.
- Typecheck
packages/synergy, packages/desktop, and packages/app; regenerate the SDK only for OpenAPI-visible changes.
- Exercise both relevant presentations in an isolated runtime. A native-only check does not prove WebRTC behavior, and a remote check does not prove Desktop bounds/lifecycle.
- Finish with
bun run quality:quick and update the architecture/product contract when ownership, lifecycle, policy, transport, or presentation changes.
- When screenshot delivery changes, verify all three delivery paths: image-capable models receive provider-file image context; text-only models with an image-capable
vision_model receive a real readable asset path and look_at guidance; text-only models without an image-capable vision_model receive only a local path with no tool guidance.
- For native lifecycle changes, test both page timing orders: open workspace → first navigation and active page → open workspace. Verify a non-zero initial checkpoint, live surface attachment, close, and same-owner recreation.
- For native recovery changes, force renderer exit, unexpected destruction, transient and sustained unresponsive states, CDP timeout, generation replacement while attached, recovery-budget exhaustion, explicit Retry, and a main-document timeout. Verify the healthy-path unresponsive reload is bounded by the shared recovery budget, and that mid-navigation loading events (redirects) never reset the navigation retry counter. Assert that managed-local Desktop never requests a viewer ticket or mounts WebRTC during any failure.
- For Browser action changes, verify failure atomicity and agent-facing guidance.
select must distinguish value from label, targeted scroll must finish on a real scroll container, and includeSnapshot must make the next DOM state available without a second tool call.
- Run
packages/synergy/test/session/agent-worker-runtime-boundary.test.ts when a shared Browser schema or utility can become reachable from Agent inference.
- For resource-lifecycle changes, prove that an active page cancels idle Host retirement and report headless process coverage as partial when the driver cannot expose RSS.
- When Playwright imports or standalone packaging change, build the compiled runtime, copy the whole packaged runtime to a different directory, and run the packaged Playwright loader check there. Verify release validation, the curl installer, and Desktop packaging all retain the filesystem-backed Playwright Core sidecar.
Handoff
Report owner/page effects, command and event changes, persistence and cleanup, navigation/enforcement behavior, native and remote presentation coverage, generated contracts, tests, and manual runtime evidence.