# Owner-v1 Frozen Session Migration Runbook (Historical)

## Scope and authorization

This capability is pinned in code to profile `dualcoachtest`, customer `task22_dm_rehearsal`, and session `rb_Ar-NuKG3LH8CqHPXUgc88g`. The CLI accepts no caller-supplied identity, source, candidate, package, or authority digest. The authorized migration and owner approval have completed; this runbook is retained as historical procedure and grants no further live authority.

## Historical evidence versus release evidence

Historical source evidence remains readable and byte-identical:

- Historical workflow SHA-256: `3ebc6c37a5a189c056348e8e40992231c6572cf8b4145a50d4d90606855855bc`.
- Historical Task-22 freeze receipt candidate label: `1db5f5e410416278186ae1ed24c750419df71ee1b7e31b0ba7a9fdacc1fdcbeb` (not a release pin).
- Superseded pre-fix release candidate: `bd86e752408d6ec34d86763b7cfc0b71577d944ff8339726fceccf1510b02317`.
- Superseded pre-batch release candidate: `737889550c272235d50d611920de15756a0a66e760b73260b2147c0b91df2e78`.
- Superseded pre-final-repair candidate: `dcf4fef0b85737ccd9d8a712c4c7bbd0c98f4a6a98b8275ae1e4bd0cbcd352cd`.
- Superseded pre-approval release candidate: `21935f74750524dbff8f0c7657490e26aeb0c3db2229a46242fc295b6bb69d5e`.
- Current post-approval release candidate: `f2783b65b9d19506140495364a715d73dba8e9902733f66e53b8dfc4cc9c4578`.
- Current canonical profile-package digest: `48b0c779538bed0543339cbf82bbd48382960b51a5776fde75e4960cc9d20ac6`.
- Pre-approval freeze receipt digest: `2d30898ffb4ee4c8ec3d9c156042d74be70864db376446cafdcd77c401ba2d54`.
- Current candidate-bound freeze receipt digest: `bc1b892a8c8025268a6d41261f27109bf4c1701ef16074fd213b91413c202305`.
- Internally derived owner authority digest for the frozen source: `8407377ef1b5c8abf016bb74d186431a8726293ee6d9753f9ac224af405d6790`.
- Historical source generation: `24`; only generation `25` can be the owner publication.

The package digest is reproducible from manifest-owned `profile_package` leaves using: `SHA-256 over every manifest-owned profile_package leaf ordered by UTF-8 path; relative-path NUL exact-bytes NUL`.

## Historical pre-execution blocker (resolved)

Before migration, the customer directory `/home/cube/.hermes/profiles/dualcoachtest/data/customers/task22_dm_rehearsal` was mode `0775`, and default preflight correctly failed closed. The separately authorized normalization changed that exact inode to `0700`; migration then committed and finalized publication.

A separate, still-unauthorized operation is pinned as `scripts/nutrition-onboarding-owner-v1-migrate --normalize-customer-mode`. It acquires all eleven fixed-order exclusive locks and permits `0775` only for the exact descriptor-retained pinned customer-root device/inode; every other traversed profile directory must be owner-controlled `0700`. It proves pre/post process, lock, tree-identity, release, freeze, and all seven byte authorities; rejects links, wrong owner/group, extended access/default ACLs, and modes outside `0700`/`0775`; and changes only that descriptor with `fchmod(0700)` plus fsync. Its v2 sealed receipt binds the derived transaction, all release pins, actual pre/post metadata, all seven pre/post lengths and hashes, pre/post tree/lock/process proofs, timestamp, and result. A `0700` replay truthfully reports `changed=false`, `0700` to `0700`, with its own deterministic seal; it never invents a `0775` predecessor. Faults before or after `fchmod` recover by rerunning only this action. It never starts or performs the migration. This action was run exactly once under separate authorization and must not be replayed as authority for another mutation.

The isolated `hermes-gateway-dualcoachtest` service is active after post-approval restart recovery. Its running state grants no migration, activation, delivery, or Telegram authority.

## Historical required preflight

Run `scripts/nutrition-onboarding-owner-v1-migrate` without an action flag. It must:

1. acquire all fixed-order shared profile authorities without contention;
2. prove no gateway/target process or live PID/start-time lock authority;
3. recompute every manifest leaf, the multi-root candidate digest, and the separately canonicalized package digest;
4. verify all seven exact frozen files against `dualcoach-owner-v1-freeze-receipt.json`;
5. derive owner authority from registry/bootstrap/config linkage;
6. authenticate customer attestation generation 23 and historical trainer generation 24 from the HMAC outbox and match the historical projection;
7. prove the customer remains disabled and no activation, generation, draft, delivery, owner publication, emergency, or unresolved downstream authority exists;
8. return ready without creating a journal or changing any frozen byte.

No action flag may be used until this preflight succeeds twice and fresh independent verification confirms the release.

## Authorized execution protocol (not currently authorized)

`--execute` acquires the same authorities exclusively, writes and fsyncs a sealed `PREPARED` journal retaining all seven source byte strings and all derived pins, atomically replaces only the workflow through retained no-follow descriptors, then writes and fsyncs `STATE_COMMITTED`.

`--recover` accepts only the sealed, candidate/session/source/target/authority-bound journal and exact source-or-target workflow. `--rollback` is allowed only while no generation-25 outbox or emergency authority exists. At or after reservation, dispatch, unknown provider outcome, receipt, or commit, rollback is forbidden and blind Telegram retry is forbidden.

After an independently controlled gateway run creates exactly one authenticated generation-25 owner card, stop the gateway and use `--finalize-publication`. Finalization requires the HMAC-authenticated owner outbox receipt and exact matching projection before sealing `PUBLICATION_COMMITTED`.

Reset/archive verification must prove the owner-v1 journal and historical generation 24 plus owner generation 25 are archived together before removing the temporary mutator.
