# Migration conformance and recovery cases

This catalogue records the behavior implemented and tested by the experimental `0.1.0-dev.4` Host migration profile. It gives implementers concrete acceptance cases for the handoff and failure recovery. Passing these cases demonstrates this reference slice; it is not full OPRP conformance, a Host assessment, clinical validation or independent security certification.

The governing format and lifecycle are in [Host migration](host-migration.md). Tests use synthetic Patient/laboratory data, fixed private authority roots and temporary SQLite state. Real owner authentication, legal authority verification and administrative deployment interfaces remain unimplemented.

## Admission and authority

| Case | Required observed behavior | Evidence |
| --- | --- | --- |
| Export-only representative requests transfer | Reject; transfer-management permission is distinct. | Scoped representative management test. |
| Host sends archive without destination owner admission | `transfer_not_admitted`; no clinical materialization. | Missing-admission test. |
| Source/destination key or identity differs from plan | `wrong_transfer_host` or proof-signer failure. | Wrong-Host activation test. |
| Application attempts a Host migration operation | Reject; application credentials cannot access peer operations. | Application activation rejection test. |
| Destination record already exists | Reject admission; never silently merge or replace. | Shared empty-destination invariant and archive collision cases. |
| Representative loses current authority before release | Reject release; keep source frozen until authorized continuation/cancellation. | Source withdrawal test. |
| Representative loses destination authority after release | Reject activation; source remains moved; fresh owner continuation can proceed. | Destination withdrawal/reauthorization test. |
| Plan deadline expires before freeze/release | Reject; no implicit permission extension. | Expired-plan test. |

The source validates its current signed address binding; the destination admits precisely the source-signed plan. Trusted local owner assertions are simulation/integration inputs, not authentication protocols. Repeated token access does not require a repeated owner login: the already authorized workers drive the handoff, subject to current authority.

## Clinical integrity and custody

| Case | Required observed behavior | Evidence |
| --- | --- | --- |
| Source accepts writes while copying | Final archive includes current content and accepted operation receipts. | Live catch-up test and HTTPS demo. |
| Final package omits a baseline resource or receipt | `migration_catchup_incomplete`; no ready acceptance. | Missing-membership tests. |
| Source receives ready receipt for another valid archive | `migration_archive_mismatch`; no release. | Independently minted archive mismatch test. |
| Write acquires transaction lock after final fencing | `migration_fenced`, including an old receipt retry. | Shared-database second-process test. |
| Final snapshot exceeds supported size | Fail and roll back fence/snapshot together. | Failed-capture test. |
| Destination is staged/ready | Reject application record access and token requests; no writable Patient exists. | Staging test. |
| Source has signed release | Source reads/writes fail, grants are inactive and pending tasks close; abort cannot reopen it. | Irreversible-release test. |
| Activation collides with another stored resource | Roll back clinical rows, receipts, events and state; destination remains ready for explicit repair/retry. | Activation collision test. |
| Source retains an original copy | Keep it fenced; no automatic deletion. | Live test and demo. |
| Destination re-exports | Preserve final source archive and the signed handoff linking that exact archive. | Re-export evidence test. |

Source movement and destination activation are intentionally separate commits. Release creates a safe interval with no writer; activation removes that gap. The tests do not claim an atomic transaction spanning two Hosts or the address provider.

## Lost responses and normal restarts

| Lost or interrupted step | Recovery |
| --- | --- |
| Baseline submission | Send a fresh envelope with the same signed plan/archive; no application record is activated. |
| Final submission | Resend the exact final archive; recover the saved ready receipt. Never mint a replacement package after the source is fenced. |
| Source release result | Read/retry the same transfer and ready receipt; recover the saved release. Treat unknown release as potentially committed. |
| Destination activation result | Retry the exact signed release through the protected peer exchange; recover saved activation without duplicating resources/events. |
| Source completion acknowledgment | Resubmit the same activation proof; recover the same complete handoff. |
| Address publication result | Resubmit the complete handoff; compare-and-update is idempotent across address-provider restart. |
| Requester write response before move | After destination authorization, retry unchanged logical content and operation ID; preserved receipt returns original result. |
| Client route persistence | Do not change/send the queue route until SDK state saves; route mismatch blocks transmission. |

All wire retries use a fresh envelope/message ID, never replay an already accepted signed envelope. Persist the exact proof/archive objects because randomized signatures contribute to the digest bindings. Their saved content is patient-sensitive and needs operator-owned protection at rest.

The restart tests reopen normal current SQLite databases with the same Host identities. They do not restore stale copies or simulate disk loss, split storage clusters, malware or power failure at every instruction boundary. Crash fault injection, distributed fencing and anti-rollback recovery require additional acceptance evidence.

## Discovery and client behavior

Publication must verify source plan, destination ready, source release and destination activation before comparing the old source/generation. A missing activation, a mismatched archive/digest or stale prior generation cannot change the binding. After publication, clients remembering the new generation reject older otherwise-valid signed responses. A repeated publication can install a currently renewed destination credential with the same pinned keys without changing custody/generation.

The SDK switches only after signed discovery and patient binding checks. Source grants/refresh state are cleared rather than sent to the destination. Source credential expiry must not prevent following a valid new binding. Destination approval remains conditional on its policy. Old feed cursors fail; obtain a fresh snapshot before catch-up. These transitions are tested, including renewal after source credential expiry.

The queue binds each patient to a durable Host route. A move for one patient must not redirect another patient's queued PHI. Queue persistence failures, missing authorization and custody fences leave pending work unsent; conflicts or existing rejection require resolution. The single-worker reference adapter does not supply multi-process leases, arbitrary dependencies, automatic redirect handling or a background retry scheduler.

## Operator recovery decisions

Before a source release exists, an authenticated owner can authorize cancellation; the source resumes and signs the destination cleanup decision. After release, recover destination activation and publication. Do not clear a source fence because a destination or registry is temporarily unreachable. A renewed transport credential with the same keys can resume exchanges, but a Host key change, known revocation or missing final archive needs explicit recovery rather than a different unsigned URL.

If representative authority changed, use the Host's authenticated management process to approve continuation of the existing plan. Source continuation cannot extend its deadline. Destination continuation after a valid committed release changes only the local authorizing actor; it never changes the target/final archive or creates a second release. This is the same policy boundary used for ordinary conditional consent, not a prescribed portal flow.

A discovery compare-and-update conflict requires investigating the actual binding under the address owner's authority. The prototype leaves the destination active and source fenced; it does not overwrite a newer binding. Multiple address aliases and public update/enrollment APIs are not implemented. No automatic source deletion, cross-provider failback or restore over an occupied record is authorized by a handoff.

## Remaining release gates

The profile needs general FHIR/attachment/history coverage, incremental and resumable transfer, public management/admission APIs with verified owner authority, real status/renewal workers, capability negotiation, aliases/identifier recovery, sustained concurrent load and crash tests. Custody storage must resist rollback and distributed deployments must enforce fences across every writer. Forward secrecy, cryptographic composition, archival time/compromise evidence and recovery exceptions still require independent review.

The source and destination remain trusted operators. This code cannot prevent a dishonest Host from ignoring its state or signing false assertions. Restoring an old source database can discard a local fence; normal restart tests do not prove otherwise. Preserve and adjudicate signed release evidence before disaster-recovery activation. These limits remain part of the implementation status rather than being hidden behind the passing synthetic suite.
