Skip to content

Log a one-time connection's end when it was replaced or disposed - #1483

Merged
nedtwigg merged 3 commits into
mainfrom
fix/one-time-access-log-ends
Nov 1, 2026
Merged

nedtwigg merged 3 commits into
mainfrom
fix/one-time-access-log-ends

Conversation

@dormouse-bot

@dormouse-bot dormouse-bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

The access log from #1459 missed the end of a one-time connection in two cases. BurrowService.#onOneTimeChanged returned early for any runtime that was no longer #oneTime, before calling #logOneTime, and both cases run through a runtime that has just stopped being current:

  • Replaced while a phone confirms. #openOneTime swaps the new runtime in, then ends the old one. The phone that was confirming gets no one-time-denied entry. docs/specs/remote-security-model.md → "Access log" lists a one-time connection's refusal as an entry.
  • Disposed while connected. dispose() clears #oneTime, then ends the runtime. This happens when a VS Code broker window closes or the app quits, and it leaves a one-time-connected entry with no one-time-ended.

The fix logs before the identity check. Only publishing state to the webviews stays limited to the current runtime. A runtime that is no longer current emits exactly one more state, ended, since end() is synchronous and nothing after it announces. #oneTimeSeen still holds that runtime's label at that point, because the replacement has not announced anything yet.

Four new service.test.ts cases cover the log: a connection and its end, the disposed connection, the replaced confirming phone, and a link no phone confirmed, which logs nothing. The disposed and replaced cases fail on main. All four pass here, as does the rest of lib/src/host/remote/ except native-direct-peer.test.ts. Its four WebRTC cases time out in this sandbox on main as well, because they need a real network path.

This branch also merges #1487's branch, which pins the access-log story's timestamps to the story clock. Without it the Argos check on this PR stays red on that story's wall-clock diff, which has nothing to do with this change. Whichever of the two lands first, the other's copy of that commit becomes a no-op.

#onOneTimeChanged dropped every move of a runtime that was no longer the
current one before it reached the access log. Opening a new link while a
phone was confirming the old one therefore left no one-time-denied entry,
and a connection the service ended as it was disposed (a VS Code window
closing, a quit) left a one-time-connected entry with no one-time-ended.
Log first; only publishing state stays limited to the current runtime.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: b11effe
Status: ✅  Deploy successful!
Preview URL: https://7852b825.mouseterm.pages.dev
Branch Preview URL: https://fix-one-time-access-log-ends.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is red only on Argos: argos/storybook-chromium and argos/storybook-webkit each report "1 changed — waiting for your decision". The diff doesn't touch anything Storybook renders. No story imports lib/src/host/remote/service.ts; the remote stories import only types from service-protocol. The same "1 changed" diff is pending on #1479, #1480, and #1482, so it looks like a shared baseline change rather than something this PR caused. It needs a maintainer's accept or reject in Argos (build 2039, build 2040). Every other check is green, apart from the Hosted PR preview deploy jobs, which wait for approval and were not polled.

`PairedPhonesAndAccessLog` built its log in a `parameters` literal, which runs at module load, before the meta's `beforeEach` pins `Date.now` to `STORY_NOW`. The log therefore carried the CI runner's wall-clock time, and every PR showed an Argos diff on `modals-remotecontrolsection--paired-phones-and-access-log`. `pairedDevices` and `accessLogEntries` now take an optional `now`, and the story passes `STORY_NOW`; `OneTimeEndedNetworkNotAllowed`'s refusal time gets the same treatment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only red checks are the Argos ones: argos/storybook-chromium (build 2048) and argos/storybook-webkit (build 2047), each "1 changed". Every other check passed. This branch now carries #1487, which moves the access-log story off the runner's wall clock. Its description expects exactly one more baseline change, and #1487's own Argos builds (2043, 2044) report the same "1 changed". Accepting that diff once in Argos should keep the story stable, and this PR's change doesn't touch anything Storybook renders.

@nedtwigg
nedtwigg merged commit 940f9d9 into main Nov 1, 2026
19 checks passed
@nedtwigg
nedtwigg deleted the fix/one-time-access-log-ends branch November 1, 2026 00:09
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.

2 participants