Skip to content

Read no pairing frame while a confirmed pairing's write is in flight - #1237

Merged
nedtwigg merged 3 commits into
mainfrom
pairing-commit-transport
Oct 20, 2026
Merged

nedtwigg merged 3 commits into
mainfrom
pairing-commit-transport

Conversation

@nedtwigg

Copy link
Copy Markdown
Member

Hardening for the end of a pairing ceremony.

Once the person at the Burrow types the matching digits and the ACL write starts, local consent is final: teardown may drop the pipe, but nothing may cancel the write or announce a denial. One path did not honor that. In #onPairingTransport (lib/src/remote/burrow/burrow-runtime.ts), a transport frame that failed to decrypt disposed the ceremony as burrow-error directly, skipping the committing guard every other ending goes through. The write still landed, so the laptop said the pairing failed while the record was saved, and the retired ceremony meant the phone never received its outcome.

  • While a pairing is committing, its transport frames are not read at all, so no frame, an undecryptable one included, can end it. The write's own result is the outcome both ends hear, as before.
  • Expiry, replacement, and socket loss during the write already went through the guard (they drop the pipe without announcing anything) and are unchanged.

Tests

lib/src/remote/burrow/burrow-runtime.test.ts → "lets no pairing frame end a ceremony whose write has started": an undecryptable frame arriving mid-write leaves the invitation reserved; when the write completes the record is live, the phone decrypts ok: true, and the invitation retires as paired. It goes red with the fix reverted.

Specs

docs/specs/remote-security-model.md → "Pairing": the consent-is-final rule now says pairing frames arriving during the write are not read.

🤖 Generated with Claude Code

Once the person at the Burrow confirms the digits and the ACL write starts,
local consent is final. A pairing transport frame that failed to decrypt
still disposed the ceremony as `burrow-error`, skipping the committing
guard: the laptop reported a failure while the write landed, and the phone
never heard the outcome. Pairing frames are now ignored while committing,
so the write's own result is what both ends hear.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

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

Copy link
Copy Markdown

Deploying mouseterm with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1eff055
Status: ✅  Deploy successful!
Preview URL: https://3c3822ca.mouseterm.pages.dev
Branch Preview URL: https://pairing-commit-transport.mouseterm.pages.dev

View logs

@dormouse-bot dormouse-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The fix looks correct and I have no findings. The committing guard closes the one ending that skipped #finishPairing. Withholding approval only because the Workflow Lint check is red: zizmor flags a hash pin in ci.yml (line 403) whose version comment doesn't match the tag. This PR doesn't touch .github/, and main's latest Workflow Lint run (at ed40d010) fails the same way, so the fix belongs on main.

@nedtwigg
nedtwigg merged commit 5a8f4c0 into main Oct 20, 2026
15 checks passed
@nedtwigg
nedtwigg deleted the pairing-commit-transport branch October 20, 2026 16:25
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