◉ANTIGRAVITY LABJP
Articles/Integrations
⬡ Integrations/2026-07-11Advanced

Nobody Is There to Say Yes: Writing Unified Permissions as an Unattended Contract

The v2.2.1 unified permission system assumes a person is watching. On a 3 a.m. scheduled run, that assumption quietly breaks. Here is how I declared the policy up front as an allow / deny / queue contract so an unattended agent never stalls on a prompt no one can answer.

Antigravity377unified permissionsscheduled runs5unattended operationpermission design4

✦ Premium Article

A scheduled run I had kicked off at 3 a.m. was still not finished by morning. I opened the log and it stopped on a single line: "Allow writing to this file?" There was no one there to answer.

The unified permission system that landed in v2.2.1 is a refreshingly plain mechanism for controlling what an agent is allowed to do. But that plainness rests on an assumption: that someone is sitting in front of the screen, ready to press allow or deny. The more you run agents overnight or before dawn as a solo developer, the more quietly that assumption slips away. Today I want to walk through the design I actually built to close that gap.

What happens when you carry an interactive mechanism into unattended hours

The default behavior of unified permissions is to ask when it meets an operation it has not seen before. In an interactive session that is correct. Returning judgment to a human is the foundation of safe design.

The trouble is that this same behavior runs unchanged during hours when there is no human to ask. When an agent running headless or on a schedule raises a prompt, no response comes back. It times out, or worse, it sits there holding the run open. In my case, a stalled process kept a lock and dragged the next scheduled start into the jam, chaining two nights of jobs together. The failure was in one place; the damage spread sideways.

Flipping everything to "allow" is the easy escape, but that throws away the reason you enabled unified permissions in the first place. Precisely because it is unattended, I want the permitted surface to stay narrow — and yet not stall. The only way to have both is to decide the answers before execution instead of asking during it.

The unattended contract: an allow / deny / queue trichotomy

The key was to stop treating the decision as a binary. Interactively, allow-or-deny is enough, because a person can think on the spot. Unattended, both ends hurt. Lean toward allow and dangerous operations slip through; lean toward deny and legitimate work is dropped.

So I added a third exit: queue.

DecisionRuntime behaviorMeaning
allowExecute as-isReversible, contained operations you can call safe in advance
denyRefuse, stop, and recordThings you never want touched unattended: destructive production changes, secret reads
queueHold execution for a morning decisionNeither clearly safe nor clearly dangerous — worth one human glance

An unattended contract is the promise that every operation that could arise is mapped, ahead of time, to one of these three. At runtime the agent consults the contract instead of asking. No prompt appears. So nothing stalls.

I set the axis of judgment on reversibility and blast radius, not on the name of a permission. Reads and changes inside the worktree are allow; side effects over the network or writes to shared resources are queue; destructive operations and secrets are deny. That line maps cleanly onto the operation categories unified permissions already enumerates.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦A manifest that maps unified permissions to allow / deny / queue before the agent runs
✦An audit log of the prompts that would have appeared, plus a morning re-entry digest
✦Measured numbers from 30 nights of scheduled runs: deadlocks, queue volume, and what deny actually stopped
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

⬡ Integrations2026-09-20
antigravity-preview-05-2026 shuts down October 5: which setups need more than a string swap
The shutdown date for antigravity-preview-05-2026 is set for October 5, and the official page gives you the date and the successor name, nothing more. If you only read output_text, swapping the string is the whole migration. If you read steps, it is not.
⬡ Integrations2026-09-18
When a session starts with MCP tools missing, where do you stop?
When MCP initialization fails at startup, the agent quietly falls back to other means and keeps going. Here is a small script that asks your servers directly which tools they expose, plus the three branches I decided on in advance for when something is missing.
⬡ Integrations2026-08-03
I Measured Before Writing a Number: MCP Connect and Tool Calls Differed by 486x
Antigravity 2.4.3 lets you set a timeout per MCP server. To find a defensible number I built a stdio server, measured each boundary separately, and found why a single value cannot cover both.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links