I read this as a production-safe migration tooling implementation - I’ll inspect the worktree and Python standards, establish failing synthetic tests first, then implement and verify without touching live state.


I’ve completed the state-contract trace. The migration seam is metadata-only: the copied profile’s customer, consent, bootstrap, onboarding, publication/ingress, and activation artifacts must remain byte-semantically sealed while rollback evidence binds the old profile state to the new candidate. I’m starting the failing synthetic suite now.


The synthetic contract is green. I’m finalizing the operator runbook and private synthetic evidence, then I’ll run focused tests, Ruff, strict typing, bytecode compilation, executable dry-run exercise, size review, and scope/privacy checks.


The final safety review found and closed two production-readiness gaps: candidate bindings are now canonically verified rather than shape-checked, and systemd’s declared executable is cross-checked with `/proc/<pid>/exe`. The emitted commands now create private rollback parents, preserve failed profiles on rollback, run the loopback disposable smoke before resume, and re-run the planner after start.


The post-write architecture gate caught two over-wide public function signatures. I’m replacing those positional argument bundles with named migration/plan input value objects, then rerunning the same evidence gates; this is the last structural correction.


I read this as completed migration tooling delivery - I implemented and verified the production-safe, synthetic-only workflow.

Delivered all requested scripts, tests, documentation, and private evidence.

Verification:
- Focused tests: **8 passed**
- Ruff: clean
- `ty check`: clean
- `py_compile`: clean
- No-excuse audit: clean
- Evidence permissions: directory `0700`, files `0600`
- Planner CLI exercised through its executable surface
- No live profile writes, service actions, network requests, secrets, commits, or pushes

Architecture review passed: focused responsibilities, typed boundaries/errors, canonical candidate binding, semantic state preservation, idempotent fail-closed rollback, and no logging or type escape hatches.

Size warning: the seal comparator is 213 pure LOC and test module 248; both remain below the 250-line limit. Any further growth should split validators and fixtures respectively.


I read this as a rejected safety implementation requiring correction - I’ll add failing tests for the real binding transition, rollback-package refusals, user-service scope, and symlink ancestry, then change the migration and planner contracts without touching live state.


The corrected tests now exercise the rejected mechanisms directly: the old no-op fails because staging remains on the current candidate, symlink ancestry redirects into live state, and a 10-case rollback matrix removes or drifts each required v1.1.0 artifact. The implementation now passes those behavioral checks; I’m running the full quality and executable-planner gates next.


I read this as correcting the rejected migration - the required binding transition and rollback validation are now implemented and proven.

Resolved all review gaps:

- Staging binding atomically transitions from current to validated v1.1.1 candidate.
- Customer/consent/bootstrap/onboarding/publication/ingress/activation digests remain unchanged.
- Planner validates prior executable, unit, binding, snapshot, tree digest, semantic seal, and inventory.
- Missing/drift tests cover all five rollback artifacts: 10 cases.
- User-service scope is default and consistently uses `systemctl --user`; system scope is explicit.
- Symlinked rollback ancestry is refused before directory creation.
- Staging is sealed before rollback artifacts are created.
- Live profile remains unchanged.

Verification:

- Focused suite: **16 passed**
- Executable synthetic planner CLI: passed
- Ruff: passed
- Strict `ty check`: passed
- `py_compile`: passed
- No-excuse audit: passed
- Evidence: directory `0700`, files `0600`
- No live writes, service actions, network calls, secrets, commit, or push

Architecture review passed: typed boundaries/errors, exhaustive service scope, grouped inputs, no type escapes, no redundant verification, and no logging changes.

All four Python files are in the 200-250 LOC warning band; further additions should split rollback validation and synthetic fixtures before adding lines.


I’ve mapped the new state as a second activation variant, not an exception to validation: activated profiles require a committed journal; unactivated profiles require correlated registry, bootstrap, wrapper, workflow, baseline, publication, and explicit absence proof. I’m adding failing synthetic coverage for that full safety-hold shape and each requested drift before changing the validator.


The safety-hold path is now a first-class sealed variant: wrapper generation 26, workflow cursor/answers/holds, baseline digests, owner publication receipt, registry/bootstrap correlation, and activation absence all participate in the seal. Activated profiles still require the committed journal, so neither appearance nor disappearance can pass generically.


I read this as resolving the live schema blocker while preserving read-only safety - implemented and verified synthetically.

Implemented:

- Supports direct collecting sessions and schema-v1 committed wrappers.
- Validates schema-v2 workflow: 22 answers, cursor, consumed updates, holds, and `owner_reviewed=false`.
- Validates baseline answer/reconciliation digests.
- Correlates bootstrap, registry, generation-26 owner publication, message receipt, and safety-hold state.
- Activation is exhaustive:
  - Activated: committed journal required.
  - Safety hold: journal must be absent and sealed as `ABSENT`.
- Detects hold reason, cursor, owner review, generation, publication receipt, and activation appearance/disappearance drift.
- Candidate transition, rollback validation, user-systemd scope, and symlink refusal remain covered.

Verification:

- **23 tests passed**, including executable planner CLI
- Ruff, strict `ty`, `py_compile`, no-excuse audit: passed
- Evidence remains `0700`/`0600`
- No live content read, copied, or modified; no service/network actions

Exact live dry-run blockers remaining:

1. `LIVE_RUNTIME_INPUTS_NOT_PROVIDED`: actual user-unit name, profile path, expected executable, and `/proc/<MainPID>` state were unavailable to this task.
2. `TARGET_BINDING_NOT_PROVIDED`: reviewed live-host path to the v1.1.1 target binding was unavailable.
3. `ROLLBACK_PACKAGE_NOT_PROVIDED`: live-host paths for the v1.1.0 executable/venv, user unit, binding, snapshot, and matching inventory were unavailable.
4. `LIVE_DRY_RUN_NOT_EXECUTED`: consequently, `systemctl --user show` and the read-only planner have not yet run against production.

No synthetic schema blocker remains. All touched Python files remain within 250 pure LOC; any further expansion should split validators and fixtures.