MOSHLINE
MOSHLINE / DOCSField manualOpen +
Docs/Agent control02

Approvals and “Confirm on Mac”

An approval card can describe an agent request without necessarily owning a channel that can answer it. Moshline shows remote actions only when the route is real and still valid.

Updated: 2026-07-23Applies to: Host Helper approval scopes bridge_relay and host_local

Outcome

You can tell whether a phone action will unblock the agent, why some requests remain host-local, and how timeout and risk policy change the available actions.

Visibility and control are different facts

Hooks can always report an observed permission request. Remote approval requires more: the provider hook must remain blocked, Moshline must retain the exact request identity, and the provider must define valid allow/deny output on hook stdout.

Moshline records that distinction in approval_scope. A bridge_relay request has a live synchronous path. A host_local request is useful context, but must be answered where the provider is running.

Current approval routes

PathPhone actionWhat reaches the agentFallback
Claude Code PermissionRequest + current HookApprove / Deny while relay is liveHook stdout returns Claude allow / deny protocol JSONClaude local permission UI
Claude event without a synchronous decision channelConfirm on Mac / Open TerminalNo remote decision is sentClaude local UI
Native Codex HookConfirm on Mac / Open TerminalObservational event onlyCodex local UI
Other observational provider HooksConfirm on Mac / Open TerminalObservational event onlyProvider local UI
Bridge-managed compatibility runnerApprove / Deny when its runner is activeRunner-specific protocol responseRunner or terminal prompt
Apple WatchLow-risk actions forwarded through iPhoneSame verified mobile routeOpen iPhone or terminal

How the Claude relay reaches the blocked hook

  1. 01Claude invokes the Moshline PermissionRequest hook and waits.
  2. 02The hook posts the request to the local Host daemon with awaiting_decision and a relay deadline.
  3. 03The daemon returns the stored request event ID; the hook long-polls the authenticated decision endpoint.
  4. 04iPhone or Watch sends a decision bound to that exact request and agent run.
  5. 05The daemon records permission.decided and wakes the matching hook waiter.
  6. 06The hook writes Claude's allow or deny JSON to stdout, which unblocks the provider.

What happens on timeout or network failure

  • The expired relay no longer accepts a late mobile decision.
  • Hook stdout stays empty when the Bridge is unreachable or no valid decision arrives.
  • Empty stdout deliberately returns control to the provider's normal local permission prompt.
  • The Inbox keeps the event as context but removes remote actions after the route expires.
  • Open Terminal remains available for full context and manual confirmation.

Risk policy still applies

A technically reachable route is not automatically safe for every surface. Apple Watch only exposes decisions that the iPhone classifies as safely actionable with limited context. Higher-risk or unknown requests should be reviewed in the App or terminal with command, cwd, risk, policy, and reason visible.

What “Confirm on Mac” means

It usually means Moshline received a real request but does not own a valid synchronous reply channel for that provider, or the previously valid relay has expired. It is not necessarily a pairing or notification failure.

  • Open the matching terminal session and answer the provider prompt.
  • For Claude Code, re-run Host Helper setup if the PermissionRequest hook is outdated.
  • For Codex, trust the current hook definition so events remain visible; native remote approval is still host-local.
  • Do not repeatedly tap an old notification after its relay deadline.

Related