Skip to content

fix(preview): reconnect viewers when their tickets expire - #602

Merged
lukemaj merged 3 commits into
mainfrom
fix/588-viewer-expiry-reconnect
Oct 20, 2026
Merged

lukemaj merged 3 commits into
mainfrom
fix/588-viewer-expiry-reconnect

Conversation

@lukemaj

@lukemaj lukemaj commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

What: Browser viewers refresh access and reconnect when their effective viewer ticket expires.
Why: The shared stream client waited for socket closure, leaving an open but expired remote relay stuck despite the earlier expiry returned by #596.
So what: Web, desktop and mobile receive the shared fix; independent exact-head review passed, and this PR remains open for human merge approval.

Problem

#596 capped renewal metadata at the earlier source/destination ticket expiry, but the client never scheduled against it. A destination-first expiry could leave a browser viewer on a dead relay until another socket event occurred.

Change

  • Schedule one timer from the existing DeviceHubAccess.expiresAt for viewer tickets, then retire the socket and invoke the existing surface-owned access refresh path. Web/desktop and picture-in-picture use their existing access owner. Mobile refreshes its access owner for a fresh viewer lease and passes that access into the existing document, replacing only the socket while preserving its picture-in-picture player and capture track. Explicit retry and process recovery can still rebuild a failed document.
  • Cancel expiry and pending retries on stop or terminal closure, and ignore stale socket events. Legacy upgrade-only tickets retain their existing behavior.
  • Add fake-clock regressions for source-first/destination-first expiry, replacement access with its own earlier deadline, cancellation and legacy tickets. Add mobile document/player lifetime regressions, register the new fork-owned test, and update the remote browser part's Issue reference in docs/map.md.

Verification

  • Failing before: node_modules/.bin/vp test run packages/client-runtime/src/preview/serverBrowserStream.test.ts -t 'earlier .* expiry': both regression cases failed with zero refresh calls at the effective deadline.
  • Passing after: node_modules/.bin/vp test run packages/client-runtime/src/preview/serverBrowserStream.test.ts packages/client-runtime/src/state/deviceHubAccess.test.ts apps/mobile/src/features/browser/PreviewStreamWebView.test.tsx apps/mobile/src/features/browser/preview-stream.browser.test.ts apps/mobile/src/features/browser/preview-stream-document.test.ts: 40 passed, using fake timers with no sleeps or polling.
  • node_modules/.bin/tsc-rs --noEmit -p packages/client-runtime/tsconfig.json and node_modules/.bin/tsc-rs --noEmit -p apps/mobile/tsconfig.json: passed (existing suggestions only).
  • Additional failing-before mobile regression: node_modules/.bin/vp test run apps/mobile/src/features/browser/PreviewStreamWebView.test.tsx -t 'renews expired access' failed on the first candidate with zero same-viewer renewal calls. It now verifies fresh access refresh (without attempting to renew a retired lease), stable document/source identity during background PiP, and explicit retry recovery. It also fails on the second candidate when that candidate calls the retired same-viewer renewal. The bundled-browser test separately observes the same video, capture track and active PiP element across deadline-driven socket replacement and the next expiry.
  • node_modules/.bin/vp test run apps/server/src/auth/SessionStore.test.ts -t 'admitted .* transport|admits a fresh preview viewer': 3 passed with the real SessionStore and test clock. The new case releases the expired socket first, verifies same-viewer renewal fails, then admits a fresh lease successfully. Shared access tests also verify refresh opens a distinct viewer without sending the retired viewerId. Total focused proof: 43 tests passed.
  • Initial independent review found the mobile whole-document refresh regression; that finding is fixed. Second review correctly identified that same-viewer renewal needs an active transport; mobile now obtains a fresh lease through the existing owner and keeps its document stable. Current-head independent review passed with no blocking findings; the reviewer posted and verified review/independent=success on 7af482c.
  • Targeted vp lint: passed with one pre-existing inline-schema compilation warning in the test file. Targeted vp fmt --check and git diff --check: passed.
  • bash scripts/fork-check.sh --upstream upstream: passed on the committed candidate; 59 registered features.
  • Upstream main 7e289ae1f7 and open PR/Issue searches had no applicable viewer expiry fix; details and baseline evidence are in #588.
  • No screenshots or live run were produced. No dev servers, browsers, devices, repo-wide checks or version bumps. No server implementation, wire contracts, provider adapters, local upgrade-only sessions or user workflows change; this is a shared transport lifetime fix, not a visual change. No marketing-site or SEO changes apply.

Elon record

Requirements and who asked: User requests the remaining #588 client acceptance: reconnect at the earlier viewer expiry, shared client coverage, failing-before proof, independent exact-head review, and a PR to main without merging; this advances #379/#383 remote browser operation for the Objective.
Deleted: New services, per-client expiry timers, ticket lifetime changes, Spec, version bumps and live verification. Mobile uses its existing fresh-opening owner and a small access-update bridge into its document, preserving the player. Same-viewer renewal after transport retirement is removed.
Bottleneck: The existing shared browser stream client never schedules against viewer access expiry; one shared deadline timer reuses access refresh, while mobile must obtain a valid fresh lease after closing the expired socket, without replacing the document that owns PiP.
Checked myself: Read #588 and all comments, checked #596 and upstream, traced web/desktop/mobile/picture-in-picture consumers, observed the baseline failures, accepted and fixed both independent mobile lifecycle findings against the real server admission contract, and ran focused tests, lint, package typechecks and the fork check.

Closes #588

Model: gpt-6.1-sol. Harness: Codex.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M labels Oct 20, 2026
@lukemaj

lukemaj commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent review found one blocking mobile picture-in-picture lifecycle regression at 5c3eb9b0f670c5d245c9bb827166400bfe90e13b.
Why: The new expiry callback reaches a refresh path that replaces the entire mobile WebView, destroying the player that owns active picture-in-picture.
So what: Preserve active mobile picture-in-picture through expiry refresh and obtain review of the corrected candidate before merging; this review grants no merge authority.

Blocking finding

[P2] Preserve the mobile picture-in-picture player when the viewer expires

Location: packages/client-runtime/src/preview/serverBrowserStream.ts:403-409.

Trigger: open a qualified remote browser viewer on mobile, enter picture-in-picture, and let the effective viewer-ticket deadline arrive, including while the app is backgrounded. The new timer correctly retires the socket, but its unconditional onUnauthorized() invokes the mobile whole-view refresh:

  1. The bundled stream posts unauthorized; PreviewStreamDocumentView forwards it to AuthorizedPreviewStream, which calls the access owner's refresh.
  2. Refreshed access changes attempt and the configuration, replacing the keyed PreviewStreamDocumentView at PreviewStreamWebView.tsx:190-228.
  3. The old document's cleanup calls T3PreviewStream.stop() (lines 350-359); this stops the capture track and clears the PiP video's source (preview-stream.browser.ts:685-699). The replacement creates a different video and reports PiP inactive; it never restores the previous PiP session.
  4. In the background, that inactive report also makes backgrounded true (BrowserPreviewRouteScreen.tsx:199-212), so PreviewStreamWebView disables the viewer through its live condition at lines 136-142.

Consequently a normal ticket expiry tears down the floating mobile viewer instead of continuing its stream with fresh access. Preserve the active mobile player while replacing stream access, and add a focused lifecycle regression that observes the player surviving a deadline-triggered refresh. The added tests replace only the shared stream client from a mocked callback, so they do not exercise this real consumer's WebView/player lifetime.

Inspected scope and cleared concerns

  • Exact base: c6f94f62b8ecb3d0b7a9cd141535e4e0248c2069; exact head: 5c3eb9b0f670c5d245c9bb827166400bfe90e13b. Local checkout and live PR head/base matched, and the shared worktree remained clean.
  • Read fix(preview): renewing a remote viewer ignores the destination ticket expiry #588 body/all comments with gh issue view, PR body, and the complete three-file PR diff. The server cap is already supplied by fix(preview): honour destination expiry when renewing viewers #596 and is outside this implementation's scope.
  • Traced shared expiry metadata, access opening/renewal/release, socket lifecycle, retry cancellation, terminal close codes, stale open/message/close events, and legacy upgrade-ticket handling. The shared timer retires its socket and cancels retry/expiry work; legacy wsTicket sessions do not acquire this timer.
  • Traced web/desktop ServerBrowserSurface, their access refresh owner, floating web picture-in-picture's independently mounted access owner, mobile JSON serialization and native message handling, and mobile PiP capture/player cleanup. Web floating PiP keeps its player outside the replaced stream client; mobile keeps it inside the replaced WebView.
  • Inspected the new fake-clock cases and existing shared access tests. Parent-provided proof reports the two baseline deadline failures, 28 passing focused tests after the fix, scoped client-runtime typecheck, targeted lint with an existing warning, formatting/diff checks and fork validation. These checks do not cover the blocking mobile player lifetime.

Limits

Read-only source review only. As instructed, I ran no tests, dev servers, browsers, devices, live reproduction or repo-wide checks, and changed no repository files. Native OS PiP presentation was not exercised; the finding is supported by the explicit WebView replacement, capture-track teardown and background visibility paths above. This verdict is one independent review of this exact head, not a complete CI or merge-readiness verdict.

Elon record

Requirements and who asked: User requested one independent exact-head review of #588/#602, including real web/desktop/mobile/PiP consumers, lifecycle and the earlier-expiry reconnect acceptance; remote browser continuity supports the Objective through #379/#383.
Deleted: Further delegation, implementation, duplicate test runs, live sessions, version changes and merge actions.
Bottleneck: Mobile's existing whole-WebView refresh owns more lifetime than the socket whose ticket expired.
Checked myself: Read the exact diff, Issue and real consumers; traced the deadline callback through native refresh, keyed remount, PiP track teardown and the background viewer's live condition.

Reviewer: gpt-6.1-sol, high effort, Codex harness.

@lukemaj

lukemaj commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent review found one blocking mobile viewer-renewal lifecycle defect at 753c182838649fff6c2587fccf62d3941d2b4d5b.
Why: The deadline closes the admitted socket before mobile renews the same viewer, while the server requires that viewer to retain an active transport.
So what: Correct the transport/admission handoff and verify it against the real server lifetime contract before another exact-head review; no merge authority is granted.

Required fix

[P2] Keep same-viewer admission alive through the socket replacement

Location: apps/mobile/src/features/browser/PreviewStreamWebView.tsx:333-343, reached from serverBrowserStream.ts:403-407.

Trigger: one qualified mobile browser viewer, with no concurrent upload/download retaining its lease, reaches its effective ticket deadline. This includes active background picture-in-picture.

  1. The shared expiry callback calls stop() first. That clears socket and sends ws.close() before emitting unauthorized.
  2. Native handling schedules the supplied renewal action, which calls the original access object's requestCurrentAccess. That helper deliberately sends viewerId: access.viewerId through viewerOpen, so this is renewal of the existing lease, not a fresh opening (packages/client-runtime/src/state/deviceHubAccess.ts:151-165).
  3. Once the server processes the socket close, SessionStore.admitViewerToken releases its transport and deletes it from retained.active (lines 1495-1503). issueViewerToken explicitly rejects renewal with existing.active.size === 0, with cause The exact active viewer is unavailable. (lines 1364-1375). At the original admission deadline, release also completes closed and permits the binding to retire.
  4. Even if renewal wins the first race, replacement admission can still lose: authenticateViewerToken rejects a closed viewer or an inactive viewer past its original expiry (lines 1461-1467); issuing a renewed ticket intentionally does not replace the retained viewer's original lifetime. The existing server test admitted %s transport outlives admission but not scope or session retirement explicitly covers rejection after the last admitted scope closes.
  5. Native renewal rejection reaches fail(), which invokes the document's stop(), stopping the PiP capture track and clearing the video source. The WebView now survives successful mocked renewal, but a normal server ordering still turns routine expiry into a failed viewer.

Preserve a valid admitted lifetime until replacement admission succeeds, or obtain a fresh lease while keeping the document/player alive. Merely moving the renewal call ahead of close() is insufficient if the last transport is still released before replacement admission. Add a focused regression that enforces the real SessionStore renewal/admission conditions and processes the old socket's release before the delayed renewal response/new connection.

Inspected scope and cleared concerns

  • Exact original base: c6f94f62b8ecb3d0b7a9cd141535e4e0248c2069; prior reviewed head: 5c3eb9b0f670c5d245c9bb827166400bfe90e13b; current reviewed head: 753c182838649fff6c2587fccf62d3941d2b4d5b. Local HEAD and live PR head matched; the shared workspace was clean.
  • Read fix(preview): renewing a remote viewer ignores the destination ticket expiry #588 and all comments, the current PR body, prior review, inline-comment endpoint, and the complete cumulative eight-file diff. Read repository instructions and the operations verification/code-review procedures.
  • Traced shared expiry/retry/terminal cleanup, stale socket events, legacy upgrade tickets, shared access issuance/renewal/release, web/desktop surface refresh, independently mounted web PiP, native bridge callbacks, mobile background visibility, browser connect(), and server viewer admission/retirement.
  • The prior keyed-WebView-remount mechanism is corrected on successful renewal: native injects updateAccess; the browser replaces its client while retaining painter, video and capture track. Async completion checks the active/failed document before injecting, and renewal rejection visibly fails.
  • Inspected both new mobile regressions. The native test checks renewal, injection and no remount while background PiP is active. The jsdom browser-module test uses the real shared expiry timer and observes video/stream/track/PiP identity across socket replacement and the next expiry. However, its socket never enters the server admission lifecycle, and native renewal is mocked to resolve; neither can detect the required fix above. The fork registration includes the new test.

Proof and limits

The task/PR reports the original two failing-before deadline cases, the native regression failing on the prior candidate, 40 passing focused tests, package typechecks, scoped lint/format/diff checks and fork validation. I inspected the actual test implementations and server consumer contract, but did not independently execute those commands or inspect raw local run transcripts. CI was still in progress when inspected, so this verdict does not claim complete CI or merge readiness.

As instructed, this was read-only source review: no repository edits, tests, checkout changes, dev servers, browsers, devices, live runs, screenshots, repo-wide checks, version changes, further delegation or merge actions. Native OS PiP was not exercised. The finding is supported by the explicit close-before-renew path and server admission invariants, not a claimed live reproduction.

Elon record

Requirements and who asked: User requests independent exact-head review of corrected #588/#602, including real web/desktop/mobile/PiP consumers, earlier-expiry reconnect, cleanup and prior-finding resolution; continuity contributes through #379/#383 to the Objective.
Deleted: Implementation, additional delegation, duplicate test execution, live sessions and merge actions.
Bottleneck: The mobile same-viewer renewal handoff retires the transport that the server requires to authorize renewal and replacement admission.
Checked myself: Read the complete candidate diff and tests, traced the actual mobile bridge through shared access into PreviewViewers and SessionStore, and checked the server's active-transport and closed-viewer predicates plus existing lifetime regression.

Reviewer: gpt-6.1-sol, high effort, Codex harness.

@lukemaj

lukemaj commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

What: Independent review found no blocking findings at 7af482c8578511642d15bd57c9e650f10deaf8ac.
Why: The corrected mobile path opens a fresh viewer lease after expiry and updates the existing document, resolving both prior lifecycle findings.
So what: Record review/independent=success for this exact candidate; CI and human merge approval remain separate, and no merge is authorized by this review.

Verdict and identity

No supported actionable blocking finding remains in the inspected scope. Reviewed the complete cumulative ten-file diff from original base c6f94f62b8ecb3d0b7a9cd141535e4e0248c2069 to exact head 7af482c8578511642d15bd57c9e650f10deaf8ac. Local HEAD and the live PR head/base matched, with a clean shared workspace and no branch divergence.

Read #588 and all comments, the current PR body and comments, the inline-comment endpoint, both prior reviews (first, second), repository AGENTS.md, and the operations verification/code-review procedures. The earlier reviewed heads were 5c3eb9b0f670c5d245c9bb827166400bfe90e13b and 753c182838649fff6c2587fccf62d3941d2b4d5b; this verdict applies only to the new head above.

Cleared mechanisms

  • Deadline and cleanup: The shared client schedules against the already-returned effective expiresAt, including the earlier destination expiry supplied by merged fix(preview): honour destination expiry when renewing viewers #596. At that deadline it retires the socket, cancels pending retry work, clears connection state and invokes the surface owner. Replacement clients schedule their own deadline. Stop and terminal closure cancel expiry; retired socket messages/open/close cannot affect the replacement. Legacy cookie/upgrade-only wsTicket access receives no new expiry timer.
  • Real lease owner and server contract: Mobile's unauthorized callback now uses usePreviewStreamAccess's refresh, not the old access object's requestCurrentAccess. The shared atom owns release of the previous viewer and calls open with the original resource/operation input, without the retired viewerId. PreviewViewers.open therefore takes the fresh authorization/issuance path. SessionStore.issueViewerToken's active-transport requirement for same-viewer renewal no longer applies to this handoff. New admission still checks session, resource, operation, generation and live authority. This clears the second finding even when the server releases the old socket first.
  • Mobile document and PiP: Ordinary access is excluded from the document key; the WebView source object is initialized once. Updated access is injected after the document reports readiness, and browser updateAccess replaces the client/socket while retaining the painter, video and capture track. I also checked the actual pinned Effect 4.0.5 atom implementation: pending refresh preserves the prior Success/value, so useEnvironmentQuery does not transiently remove this document on a successful refresh. Failure/unmount still stop the document; explicit retry waits for changed access before rebuilding, and process recovery retains its bounded rebuild. Connecting clears stale chooser/control state. This clears the first finding, including the route's background-PiP visibility path.
  • Other consumers and scope: Traced web/desktop ServerBrowserSurface, independently owned web PiP access/player, mobile bridge and native file-access closures, permission-dependent operation selection and server rechecks. Resource/configuration changes still select the appropriate lifetime. No server implementation, contract, provider adapter or legacy-session change is included. The fork test registration and map reference match the changed scope.

Proof inspected and limits

Inspected the actual focused regressions: both earlier-expiry orders and next deadline, retry/terminal/stop cleanup, legacy tickets, native fresh-refresh/no-old-renewal with stable mounted document and exact source identity under background PiP, explicit retry rebuild, browser video/track/active PiP element identity, real atom refresh opening a distinct viewer, and real SessionStore expiry followed by last-transport release, rejected old renewal, then successful fresh issuance/admission/recheck.

The parent reports failing-before evidence, 40 passing client/mobile cases plus three real SessionStore lifetime cases (43 total), client-runtime/mobile package typechecks, targeted lint/format/diff checks and fork validation. I inspected source and test assertions, but did not execute those commands or independently inspect raw local run transcripts. GitHub CI still had pending checks when inspected; this is not a complete CI or merge-readiness verdict.

This review made no repository edits and ran no tests, checkout changes, dev servers, browsers, devices, live sessions, screenshots, repo-wide checks, version changes, additional delegation or merge actions. The browser regression uses jsdom and fake timers; native OS PiP and real background scheduling remain unverified, as explicitly required by the task's live-run prohibition.

Elon record

Requirements and who asked: User requests independent exact-head review of corrected #588/#602 against earlier-expiry reconnect acceptance and real web/desktop/mobile/PiP lifecycle and authority owners; remote browser continuity contributes through #379/#383 to the Objective.
Deleted: Implementation, additional delegation, duplicate test execution, live sessions, new architecture and merge actions.
Bottleneck: Verify that expiry refresh obtains valid new admission without destroying the mobile document that owns PiP.
Checked myself: Read the cumulative diff and regression implementations; traced the real access atom, pinned atom waiting semantics, native/browser bridge, web/PiP consumers and SessionStore/PreviewViewers admission, retirement and authorization paths; verified exact local/live candidate identity.

Reviewer: gpt-6.1-sol, high effort, Codex harness.

@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 4.9 KiB −23 B (−0.5%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB −23 B (−1.9%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.8 KiB −41 B (−0.2%) 29.3 KiB ✅
Codex Live turn messages 2 1 −1 (−50.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB +24 B (+0.5%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB +24 B (+2.0%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB +41 B (+0.2%) 29.3 KiB ✅
Claude Live turn messages 1 2 +1 (+100.0%) 8 ✅

Baseline: c6f94f6 · PR result: 7af482c · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@lukemaj

lukemaj commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

What: This deployment thread now owns following PR #602 through its remaining CI gate, merge readiness and the authorized bestia shipment.
Why: The original implementation task explicitly ended with a reviewed PR without merging; the latest CI run was then cancelled on Test Server 5 and the aggregate Check failed, leaving delivery unfinished.
So what: At the user's request to make sure #602 ships, rerun the cancelled job and its dependent checks, handle any genuine failures, then continue delivery with current proof. Do not report shipment or settle the delivery threads before installed acceptance.

Current candidate: 7af482c8578511642d15bd57c9e650f10deaf8ac, PR target main, mergeable. The authenticated account's newest review/independent status is success, linked to the exact-head review. Existing 43 focused tests and package/fork validation are recorded in the PR; no code was changed by this continuation.

Reran only Test Server 5 and its dependent jobs using gh run rerun 39485274886 --job 118844207485 -R toolboxmd/chromeria (the job database ID was verified first). The prior log ends with The operation was canceled. This is incomplete proof, not evidence of a new source defect. The app PR watcher will wake this owner on check/comment/conflict changes.

Deployment constraints carry forward: bestia only; cavallo and rocky remain untouched. The held c6f94f6 stage is not to be re-armed: a shipped candidate must include the merged #605 fix (4f2bed8518e024217acc4f479db0cc8a85d58b99) as well as #602, be built once at the actual merged SHA, and follow the runbook build/swap/rollback and live proof procedure. Parent-owned continuation remains available for a bestia restart. The runbook's c6f94f6 record holds retained artifact and stop-cause history, not a shippable replacement for the fixed source.

User also requests settlement of this deployment thread and mcp:launch:a5658fec-4611-467c-b587-79cf41ce14c5:379-final-bestia-20261020-1 only after everything in the shipment is shipped and verified. The current linked caller cannot mutate the latter thread and the exposed MCP has no settlement action; the surviving parent must perform that final UI action if those limits remain.

Requirements and who asked: User now asks to ensure #602 ships, beyond the original PR-only implementation endpoint; it supplies viewer reconnection needed by #379/#383.
Deleted: Duplicate workers, unchanged source edits, duplicate review, full CI rerun, re-arming the known-broken c6f94f6 stage, and other-machine deployment.
Bottleneck: One cancelled server test shard and its dependent aggregate gate; next is exact merged-artifact acceptance on bestia.
Checked myself: Live PR/head/base and mergeability, exact independent review status and creator, original implementation endpoint, cancelled run and job log, correct rerun job database ID, current main containing #605, and absence of another active #602 worker.

@lukemaj

lukemaj commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

What: The user explicitly authorized overnight completion: PR #602 merged to main, deployed and verified on bestia, with the delivery threads settled if possible afterward.
Why: The user is going offline and wants this shipment completed without further routine confirmation; #602's prior PR-only endpoint no longer applies.
So what: This owner continues after the PR watcher wakes: handle current-candidate CI, preserve exact-head independent review, merge #602 to main when proof passes, verify that the merged source includes #605, build once and deploy the immutable artifact to bestia using the runbook, then complete live checks and final records. Request human input only for a materially changed outcome/risk/target or a remaining Human Gate beyond this authorization.

Exact scope remains toolboxmd/chromeria PR #602 -> main and bestia's installed Chromeria service. Existing authorization covers routine fixes, retries and replacement delivery needed for this same outcome, with required proof/review for each candidate. Do not deploy the old c6f94f6 stage because it lacks #605. Do not touch cavallo or rocky, perform logins, expose secrets or introduce persistent services outside the established procedure.

Read the runbook bestia Chromeria procedure, shared retention, latest machine records and persistent-host-automation ADR before the live cut. Keep database snapshots, settings-aware rollback, detached swap/observer and parent continuation. If strict idle is unavailable, use only the runbook's cut-and-continue conditions with exact continuation links posted before restart, preserving unsafe tools/background work and unrelated Codex runs.

Required live acceptance remains: running artifact identity and finite stability observer; CfT 154.0.8037.92 installed and actually serving agent tabs with expected headless/Vulkan/reduced-UA flags; three preview_open timing samples; Sannysoft and CreepJS webdriver/plugins/WebGL/page+worker UA/headless score; owned-tab cleanup and process inventory. Record actual results and any gaps, update/push dated bestia runbook and CHANGES.md, and post bestia state on #572.

The user requests both the #379 planner thread and this deployment thread settled only after successful shipment/acceptance, if possible. Settlement is conditional on completion, not merely PR merge; preserve the thread IDs and tool limitations in the earlier ownership comment. The user is asleep; no deadline guarantee replaces required proof.

@lukemaj
lukemaj merged commit 1b2c69b into main Oct 20, 2026
41 of 44 checks passed
@lukemaj
lukemaj deleted the fix/588-viewer-expiry-reconnect branch October 20, 2026 20:36
@lukemaj

lukemaj commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

What: PR #602 is merged to main as 1b2c69b4211a72ee4203710ba0adda91340f0961, and its exact bestia Linux artifact passed both smokes.
Why: The rerun resolved the cancelled Test Server 5 and the aggregate gate; exact-head independent review remains successful and the updated transfer report passes every ceiling.
So what: Continue the authorized bestia rollout from this fixed source; deployment/live acceptance remain pending, and the delivery threads must stay unsettled until those finish.

Merge used the repository's supported squash path with --match-head-commit 7af482c8578511642d15bd57c9e650f10deaf8ac, without bypassing checks. The merged tree 56556ff57f673752f647768f11bf535b11e20a40 matches the independently inspected conflict-free merge tree; merged #605 fix 4f2bed8518e024217acc4f479db0cc8a85d58b99 is an ancestor. Existing local 43-test proof is reused on unchanged reviewed source; complete CI is now passing. The new bot comment reports source CI success, not cancellation, and all transfer metrics remain below ceilings.

The completed original writer had no active/queued work. Its clean exact task worktree was removed normally after a root inode/canary holder scan found no holder or unexpected error. Local and remote task branches were removed without force, and remote absence checked. No unrelated worktree or main's dirty generated files changed.

One clean detached Linux build of the merged SHA completed at 22:37:15 CEST. Immutable archive SHA-256 29cf5d282fb51fb687e7bb4603c427df2177b01b9fa2058d015a21c352dae797; executable ee82cbaf452406a9d9650fc0e23245d02091fb3cfa2e704a5c7df47d4a331e03. Cache ~/.cache/chromeria-update/1b2c69b4211a/; fresh read-only-source snapshots are in progress. No old c6f94f6 stage was armed.

The next bestia runbook record is bestia/CHROMERIA-2026-10-20-1b2c69b.md. It will bind the exact detached unit/observer/rollback and continuation pre-check before restart. Parent-owned recovery and live CfT checks remain required; no deployment success is claimed yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(preview): renewing a remote viewer ignores the destination ticket expiry

1 participant