Skip to content

Add PQSession.opensHeader ownership probe - #160

Closed
germ-mark wants to merge 1 commit into
mainfrom
llm/anchor-opens-header-probe
Closed

germ-mark wants to merge 1 commit into
mainfrom
llm/anchor-opens-header-probe

Conversation

@germ-mark

Copy link
Copy Markdown
Contributor

Adds an additive, pure-read probe on PQSession:

public func opensHeader(_ blob: Data) -> Bool

Returns true when one of the session's header receive-window keys authenticates the blob (the frame was sealed by this session's peer), false for a foreign or out-of-window frame, and true on a post-auth throw. It wraps the existing openIncoming path — no state mutation, no persistence push.

Why: ownership is not derivable at the call site — the wire frame is header-encrypted, so a pooled session scanning an inbound frame cannot tell "mine" from "not mine" by inspection. Ownership equals header openability, which only the engine knows. This exposes that signal so a caller can filter a non-owner's retry/recovery answer instead of spooling a frame it does not own. Purely additive: no change to any error classification or custody decision.

Tests: Tests/TwoMLSPQTests/OpensHeaderProbeTests.swift — owner's peer frame probes true, an independently-established sibling's frame probes false, and probing does not consume the frame (a subsequent decrypt still succeeds). Full Swift suite green (22 tests, 6 suites); swift format lint --strict clean. Mutation-verified: unconditional false fails the owner test, unconditional true fails the sibling test, and routing through a consuming door fails the purity test.

Known gap: the catch { return true } branch (a key-authenticated blob with a bad inner tag) is unreachable from the public API with an honest peer, so it is not exercised by tests — the doc comment records the reasoning.

Minor changeset included.

🤖 Generated with Claude Code

A pure read over the existing openIncoming path: true when one of the
session's header receive-window keys authenticates the blob, false for a
foreign or out-of-window frame, true on a post-auth throw. Ownership equals
openability, so this is the engine's ownership signal for a pooled session.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Oct 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cde60ed

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@germ-network/two-mls-pq Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@germ-mark

Copy link
Copy Markdown
Contributor Author

Closing: the Rust half of this probe is not needed. The anchor adoption flips iOS to the value engine and the pool scan will only ever walk value sessions (PQ anchors/invitations are being migrated). The probe will land on the value adapter + the AbstractTwoMLS.Session surface instead, with PQSession inheriting the fail-open default. The method here is correct — it is simply for the retiring engine.

@germ-mark germ-mark closed this Oct 5, 2026
@germ-mark
germ-mark deleted the llm/anchor-opens-header-probe branch October 5, 2026 04:24
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.

1 participant