Skip to content

Export every reachable session state for migration - #147

Draft
germ-mark wants to merge 8 commits into
mainfrom
llm/born-dedicated-migration-export
Draft

germ-mark wants to merge 8 commits into
mainfrom
llm/born-dedicated-migration-export

Conversation

@germ-mark

@germ-mark germ-mark commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

After the cutover nothing drives a Rust session, so a migration export that refuses a session loses it. This PR makes migration_export total. Every reachable deployed state exports, the native engine can mint it, and only corrupt data fails (ArchiveInvalid). BINDING_CONTRACT_VERSION bumps 35 → 36.

  • Keys: each group's signing keys are keyed by what its leaf presents, found by a derive-match. There are reservation keys for groups not yet created, catch-up entries for lagging leaves, and every rotation candidate in both classical sets. A pre-A.3 acceptor's send-PQ is empty, since A.3 founding mints its own key. A leaf whose key survives nowhere is exported as no-custody instead of refused.
  • Own offers: a peer can fold any outstanding own offer. So a window (capped at 102,400) carries them with their leaf secrets, minted as a separate on-demand blob. Offers the carried keys don't cover are omitted; a peer folding one wedges that session (accepted).
  • Deployed state: parked, wedged and mis-signed PQ rounds are carried as they are, for the native engine to heal.
  • Mapper: SessionMigrator.mint returns the archive plus the optional window. mintArchive is removed.
  • Also:
    • .misroutedFrame now has disposition .discardFrame, which shifts app handling and analytics;
    • every group's suite is checked before any crypto;
    • a correction to the 0.17.0 changelog.

Dependencies

Tests

  • Rust: cargo test -p two-mls-pq --features cryptokit passes 370, also with cryptokit,awslc. A seeded totality walk exports both sides at every step across the card, anchor, late-A.3 and born-dedicated modes, including mid-prepare.
  • Swift: 98 migrate and 19 other tests pass. They include cross-engine mint and restore for each carried state, a migrated pre-A.3 acceptor answering A.3 natively, the v0.15.0 and v0.16.0 row fixtures, and a heal proof for a stuck Rust A.5 rekey.
  • Clippy ×3, fmt, taplo and swift-format are clean.

Note, not introduced here: the "MSRV (1.85)" CI job builds with stable, because rust/rust-toolchain.toml overrides it. The real minimum is at least 1.88, since mls-rs-codec-derive needs darling 0.23.

🤖 Generated with Claude Code

@changeset-bot

changeset-bot Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4738fe3

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

Base automatically changed from llm/v016-session-fixtures to main September 23, 2026 08:02
germ-mark and others added 3 commits September 23, 2026 01:06
Born-dedicated acceptors (installed, classical-converged) and acceptors
still holding a parked return welcome were refused by migration_export,
which left most card sessions unmigratable. Admit them: the recv-PQ leaf
nothing in Rust catches up exports as pq_leaf_custody, stalled PQ rounds
carry across, and group suites are validated before any crypto.
Binding contract 36.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An ill-timed side-band re-send surfaces as misroutedFrame, and it is
normal traffic: the peer re-sends until answered, so dropping it is
lossless. This changes app-side handling and analytics buckets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@germ-mark
germ-mark force-pushed the llm/born-dedicated-migration-export branch from b0f9b0d to f02515b Compare September 23, 2026 08:06
germ-mark and others added 3 commits September 24, 2026 11:49
The migration export no longer refuses unsettled state. It carries
per-group signing keys (with reservations for groups not yet created),
rotation candidates, a bounded own-offer window with detached leaf
secrets, and deployed-engine flags, and errors only on corrupt data.
Pins mls-rs germ-integration for the pending-update exports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SessionMigrator.mint returns the session archive and, when present,
the minted own-offer window. Pins twomlspq-swift main until the
release that ships these inputs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@germ-mark germ-mark changed the title Export born-dedicated and undrained acceptors for migration (contract 36) Export every reachable session state for migration (contract 36) Sep 24, 2026
germ-mark and others added 2 commits September 24, 2026 12:12
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A.3 founding now mints its own fresh key, so native requires the unfounded
send-PQ to carry no reservation. Repins twomlspq-swift to 902fead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@germ-mark
germ-mark marked this pull request as draft September 24, 2026 20:48
@germ-mark germ-mark changed the title Export every reachable session state for migration (contract 36) Export every reachable session state for migration Sep 25, 2026

This branch has not been deployed

No deployments
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