# Independent Plan Review — Remozio revision 3 (2026-09-29)

**Scope of review:** plan-only, no implementation audit. Assessed internal consistency, key/purpose separation, relay and same-user adversary resistance, command binding, biometric credential release, UI race handling, state-machine completeness, recovery paths, and acceptance coverage. Feasibility items explicitly scheduled as gates (AX capture, single-biometric credential release, descriptor-based execution, sudoers policy, true once-behavior validation) were treated as scheduled work, not defects.

## Findings

### Finding 1 (Medium) — Multi-phone enrollment cardinality and request routing are unspecified

**Sections:** 5 (Pairing, transport, and phone lifecycle), 6 (Signed request and state machine), 1 (inbox/per-Mac labels).

**Defect:** The plan consistently says "an enrolled authorized phone" (§6) and enrollment "binds the phone verification key to the Mac account" (§5), but never states whether one (Mac identity, account) tuple may have multiple simultaneously enrolled phones, or how requests are routed when it does. This is a reachable configuration, not a hypothetical: §5 explicitly permits an administrator to enroll a replacement phone without the existing phone's participation, and nothing requires revocation of the prior phone first (shared-machine or family use, or simple operator error during recovery).

**Concrete failure scenario:** An administrator enrolls phone B for an account while phone A remains enrolled. Either (a) requests fan out to both phones — the plan's stale-result machinery safely rejects the second approval, but nothing specifies that fan-out is the design, so an implementer could deliver to an arbitrary "most recently enrolled" phone, leaving the primary user with unexplained silent stalls (which §10 product acceptance explicitly forbids); or (b) delivery goes to one phone under an unspecified selection rule, and the lost/stale phone still holds valid signing authority the user believes is dormant. Approval authority over privileged execution then depends on an undocumented routing decision.

**Minimal correction:** Add one paragraph to §5/§6 declaring the v1 cardinality and semantics. The least-UX-impacting option: multiple phones per (Mac, account) are permitted, every enrolled phone receives each request, and the existing consumption ledger + explicit stale result (§6) handles double-approval — this requires no new machinery. **UX flag:** the alternative correction — restricting v1 to one active phone per tuple — reduces remote functionality and per the plan's own §1 rule requires user consultation; it must not be silently adopted as the "fix."

### Finding 2 (Low) — Over-limit request behavior is undefined, in tension with the no-truncation guarantee

**Sections:** 6 (explicit byte limits, strict parsing), 1 ("never silently truncated," "long commands remain fully accessible"), 8 (full argv display).

**Defect:** §6 mandates explicit byte limits and strict rejection of malformed envelopes; §1 mandates that long commands are never silently truncated. The plan never states what happens when a legitimate captured request (e.g., a compiler invocation with a large file list, or a large effective environment under §8's deterministic-environment capture) exceeds the wire limit. macOS argv can reach ~1 MB; any fixed limit is eventually hittable.

**Concrete failure scenario:** A coding tool submits a command whose canonical payload exceeds the byte limit. With no specified behavior, an implementer either truncates to fit (silently violating §1 and producing an approval bound to a falsified display) or rejects with a generic parse failure indistinguishable from tampering, leaving the caller with a hang or a misleading error. The user cannot tell the request was simply oversized.

**Minimal correction:** State in §6 that over-limit requests fail closed with a distinct, explicit caller status ("request too large," separate from denied/stale/unavailable per §8), that truncation is prohibited at every layer, and that limits are set and documented to bound realistic worst-case captures (argv + environment + requester row). No UX regression: this adds a clear error where the plan otherwise implies silent or confusing behavior; it adds no confirmations or manual steps.

### Finding 3 (Low) — Post-authorization caller death is unspecified

**Section:** 8 (Command execution adapter); partially mitigated by §8's stage-4 measurement work and "show requester-exited or tool-timeout explicitly."

**Defect:** §8 binds a request to caller/session lifetime and handles caller exit *while pending*, and defines disconnect behavior for a *started* command. The window between phone authorization and `exec` is unaddressed: if the caller (or its coding-tool harness) exits after the decision is consumed but before execution, the plan does not say whether the command runs with no output consumer or is cancelled post-consumption.

**Concrete failure scenario:** User approves; the harness hits its own timeout and exits in the approval-to-exec window. Either the approved privileged command executes with results lost and the caller seeing a plain timeout (the phone shows success — a confusing mismatch), or the service cancels after consumption, producing an "unknown" for an action that never had a side effect, muddying the carefully defined state semantics of §6.

**Minimal correction:** One sentence in §8: caller liveness is re-checked at the execution boundary via the same verified IPC identity; a dead caller at that point consumes the approval as a distinct "requester exited before execution" terminal state (no side effect, reported distinctly on the phone and to any reconnecting caller), never as "unknown" and never as silent execution. No UX change beyond a clearer result.

## Items verified as adequately planned (not findings)

- **Key separation and relay resistance (§3, §6):** authority/transport/adapter-receiving/biometric/decision/credential keys have distinct purposes and custody; decision key is purpose-narrowed, verified at both root and adapter, and cannot mint rule changes, command execution, credential release, or enrollment; acceptance tests cover recipient substitution, relay tampering, and impersonation.
- **Biometric policy consistency (§1, §6, §7, §9):** the user-confirmed Little Snitch once/cancel exception is correctly confined to the decision key and the captured request; session/timed rules correctly classified as reusable; both root and adapter re-enforce classification independent of button labels; no silent widening to command or 1Password paths.
- **UI race handling (§6, §9):** consumption-before-side-effect, bounded acknowledgment, permit invalidation on adapter death, no automatic retry, user-initiated Refresh with fresh challenge, and stale-permit acceptance tests form a closed design.
- **Recovery (§5):** independent admin authentication as the recovery path, no self-healing enrollment, revocation semantics for both phone keys and pending requests, credential invalidation handling.
- **Flux licensing (§4):** correctly treated as design-reference-only given the absent license; no copying planned.

## Tentative UX choices remaining open (explicitly gated in the plan — not defects)

These are scheduled feasibility/user decisions, listed per review instructions so they are not mistaken for convergence: five-minute expiry default (§5, to be validated against measured tool timeouts); encrypted relay/push wake (§5, pending user decision); StrongBox vs. TEE vs. software-key fallback (§4, user decision if fallback needed); single-BiometricPrompt CryptoObject credential release (§7 spike — failure forces a second biometric or weaker protection, both requiring user consultation); 1Password synthetic-typing fallback (§9, user decision); atomic execution vs. documented path-recheck race (§8 gate, user decision); sudoers policy integration choice (§8 gate); optional detached/resumable mode (§8, non-default, user decision); true one-time Little Snitch semantics per app/version (§9, user decision if unsupported). Review convergence under §11 must remain blocked while these are unresolved.

## Conclusion

**SUBSTANTIVE FINDINGS REMAIN** — one Medium (multi-phone enrollment/routing semantics) and two Low (over-limit request handling; post-authorization caller death). All corrections are specification additions; only the single-phone-restriction variant of Finding 1's correction would worsen UX and therefore requires user consultation. No findings demand completed implementation evidence; all flagged platform risks in the plan are already behind explicit feasibility gates.
