Blog

Approve Every Agent Action From Your Phone (Haptic Approvals)

Akshay Sarode
Direct answer

The mobile app gets an FCM push when an agent requests a permission. Long-press the notification to approve. The agent gets the answer 200–800ms later and continues. The phone is not a viewer — it's the approval surface for the whole fleet.

The annoying thing about agent permission prompts is that they happen at 11:47am while you're in a meeting, and the agent waits patiently for you to come back to your desk. Twenty minutes later you sit down, see the prompt, click yes, watch the agent finish in three seconds. The 20 minutes were 100% slack.

The fix is to put the approval surface in your pocket. Not the whole dashboard — just the approval. The phone is the right device for it: always with you, has haptics, has biometric auth.

The flow

  1. Agent asks: can I run git push origin task-3?
  2. Daemon writes to approvals/{id} with TTL 300s.
  3. Cloud Function fires FCM push to every registered approval channel for the owner.
  4. Phone buzzes. Notification: "task-3 wants to git push origin task-3".
  5. Long-press notification → quick-action sheet with Approve / Deny.
  6. You tap Approve. Face ID confirms. App writes status: approved.
  7. Daemon's snapshot listener fires; agent's permission resolves; agent continues.

From buzz to back-running: 5 seconds end-to-end if you're holding the phone, 30 seconds if you have to dig it out of your pocket. Either way, miles better than 20 minutes.

Why long-press, not tap-the-button?

iOS's notification long-press exposes a quick-action sheet without opening the app. That's what you want — you don't want to launch a full app to grant a 0.5-second permission. Tap-to-open works for "show me what's going on"; long-press-to-act works for "I trust this, just do it."

Same on Android via notification actions.

Why haptic at all?

A silent push is just another notification you ignore. A short pattern haptic ("approval-required") is recognizable and unique. After a week your hand pattern-matches and you don't even need to look at the screen first.

iOS HIG: use UINotificationFeedbackGenerator with warning for "needs attention" — short two-pulse buzz. Android: a 100ms vibration with the notification.

Auth on the phone

Approval is a privileged action. The phone app uses Face ID / Touch ID / device passcode for the actual approve gesture. The push can be tapped without auth (just shows you the prompt); the approve action requires the biometric.

Edge case: phone is on the dresser, charging. You're not there. The approval times out at 300s and the agent gets a denial. This is a feature — agents shouldn't wait forever on a human who isn't around.

What "approve" actually means

Two flavors:

One-shot is the default and the right policy for most cases. Sticky is for "I trust this agent on this kind of action and don't want a buzz every time" — sandbox capabilities are usually a better answer than sticky approvals, but the option exists.

What can be approved

Anything the agent expresses as a permission request. Common ones:

Why not just SMS?

SMS is slower (5–60s instead of 0.5s), has no haptic differentiation from spam, and can't easily express a structured action. FCM push handles iOS + Android natively, supports actions, and has typical 200–800ms delivery.

For users who specifically want SMS (no smartphone or just don't want the app), the same approval can be sent as a Twilio SMS with a one-time approval URL. The URL is single-use and TTL'd — same security properties as the in-app approve.

What we ship

Celistra's mobile app does this for every agent's permission request. The Ujex Mobile subsystem (the engine underneath) provides the same primitive — mobile.ask(prompt, detail, ttlSec) — to anyone building agents on Ujex SDK.

FAQ

What if I miss the push?

The approval times out at the TTL set by the agent (default 300s). The agent receives a denial and chooses how to handle it — often by retrying later or escalating to a different action.

Can multiple humans approve?

Yes. The FCM push fans out to every approval channel registered to the agent's owner. First-responder wins; once approved or denied, subsequent taps see 'already decided.'

Is the permission request encrypted?

Yes. FCM payload contains only the approval ID and an opaque hint; the full prompt is fetched from Firestore by the app over a TLS-authenticated connection.

What about Apple Watch?

The notification mirrors to watchOS for free; the long-press / quick-action approval works on the watch. We don't ship a separate watch app.