# Independent review — Remozio plan, revision 23

Scope: full plan, with attention to post-revision-5 additions (audit journal, expiry/age, routing, push, LAN/relay, identity/Sparkle, protocol evolution) and their interaction with earlier invariants. Plan-only review; no testing or source inspection performed or claimed.

## Findings

### 1. Journal head-mismatch response under-specifies the single-writer failure it detects — Section 12, "Atomic journal writes" (Low–Medium)

Revision 23 adds: "verify its expected head before each append. A head mismatch closes that epoch and starts a fresh one with a discontinuity marker."

Since a fresh random epoch is already generated at every service start, a mid-run head mismatch can only mean a *second live writer* (dual LaunchDaemon instance, restore onto a running system, or a recovery process writing concurrently). The prescribed response — close the epoch and keep writing — does not converge in that scenario: two live writers would repeatedly invalidate each other's heads, fragmenting the journal. Worse, the mismatch is evidence that the single-writer assumption protecting the **consumption ledger** is broken; section 12 commits consumption and the audit event in one transaction, so continuing to admit and consume requests after a detected writer-ownership violation risks duplicate dispatch, which the audit fix alone cannot prevent.

Minimal correction (no UX change in normal operation): on head mismatch, stop appending, close action admission (consistent with section 17's "keep action admission closed until recovery validates"), and require validated single-writer recovery before any new epoch or consumption. Specify the single-writer exclusion mechanism (e.g., exclusive journal lock held for the epoch's lifetime) so the mismatch path is only reachable on genuine rollback/corruption.

### 2. Batch verification rule across in-epoch trust-generation changes is undefined — Section 12, "Sync and offline cache" (Low)

"Signed batches bind the Mac, account, journal epoch, trust generation, sequence range..." and "A journal epoch is bound to the combined trust generation at its creation. Normal trust updates do not reset history."

A revocation or floor commit without a restart changes the combined trust generation mid-epoch (the section 16 witness covers enrollment tombstones and floors, and rev 23 explicitly makes epochs independent of trust-state recovery). Subsequent batches in the same epoch therefore carry a different trust generation than the epoch's creation-time binding. The plan never states what the phone must verify: equality with the epoch's creation generation (breaks legitimate sync after any mid-run revocation), acceptance of any generation (renders the binding meaningless as rollback evidence), or monotonic increase within an epoch under the same authority key. Independent Swift/Kotlin implementations can diverge here, producing either availability failures or weakened conflict detection.

Minimal correction (no UX change): define the rule explicitly — e.g., the epoch records its creation generation for cross-checking, batches carry the current generation, and verifiers require monotonic non-decrease within an epoch plus consistency with known trust state; any decrease or conflict triggers the existing read-only gap/rollback reconciliation.

## Items checked and found consistent

- Command binding (full argv/env/cwd/stdin classification, digest recomputation at both verifiers, caller-exit boundary outcomes) — no widening of the allow-once exception; scope classification enforced by both verifiers from retained semantics, with the Little Snitch "current request" definition and second-attempt validation intact.
- Key separation: biometric, decision, transport, gateway-control, routing, update-scheduling, and enrollment purposes are distinct; relay/push/gateway cannot mint decisions or mutate mappings; credential packages remain recipient-bound.
- Rev 23 epoch mechanism vs. section 16 trust witness: random epochs correctly avoid dependence on the witness for audit-only rollback; cursor-ahead, repeated-sequence, and old-epoch cache handling are specified.
- Updates vs. UX: quiescent activation, drain, bounded "Update installing" resubmission, and the restart matrix preserve approval lifetimes and add no confirmations; floor commitment and anti-rollback are externally enforced with a feasibility gate.
- Routing is delivery-only; manual overrides persist; degraded-detection fallback fails toward phone delivery without granting authority.
- 1Password/Little Snitch adapters remain fully in scope with their fixture/race gates; no biometric-free path was extended to commands or 1Password.

## Deferred product preferences (not defects)

Idle interval (30s draft), five-minute expiry, retention duration, and the migration ceremony are explicitly gated for user choice; no finding inferred.

## Conclusion

**SUBSTANTIVE FINDINGS REMAIN** — two findings, both in the revision-23 journal-epoch machinery, both correctable without any UX regression (no added confirmations, biometrics, or manual steps). Neither rises above Low–Medium; the rest of the plan, including all prior review dispositions I could challenge, showed no concrete unresolved failure scenario. Remaining verification limits: all platform guarantees (pre-login key custody, descriptor-based execution, AX targeting, background Access auth, rollback-resistant activation) remain feasibility-gate deliverables, as is appropriate for a draft plan; this review asserts nothing about their outcome.
