Doctrine
Gemini sandbox and policy guardrails
Gemini sandbox and policy guardrails
The problem
ORA-2026-0082 gave Gemini experiment authority — the right to write and run code in branches. Within 10 minutes, Gemini:
1. Ran doctrine-parity-check --reconcile, editing 82 entries across boot surfaces (CLAUDE.md, GEMINI.md, canonical_user_identity_v1.md) — the most sensitive files in the fleet 2. Pushed a commit to ORA main without pulling first, causing a ref lock conflict 3. Both actions were fast, quiet, and invisible until after the fact
Doctrine alone is insufficient. Gemini works fast and quiet (low inline output). Trust-based constraints (doctrine says "don't") are not reliable when the agent has no approval gate and produces no visible output before acting.
The solution: policy engine guardrails (yolo + deny)
macOS Seatbelt sandbox was tested and rejected — it blocks /tmp writes that feed-append and other fleet scripts need (mktemp: Operation not permitted). Too blunt for an autonomous agent that needs to write temp files, run scripts, and commit to branches.
The working pattern is: yolo mode + policy deny rules. Gemini auto-approves everything via --yolo, but the policy engine's deny rules hard-block specific dangerous operations. Deny rules fire even in yolo mode.
Policy engine guardrails
~/.gemini/policies/fleet-guards.toml
TOML rules that intercept tool calls before execution. When a rule fires, the denyMessage is sent back to the model so it understands why.
| Rule | What it blocks | Priority |
|---|---|---|
| git push to main/master | commandRegex on push + main | 700 |
| git force push (any branch) | commandRegex on --force/-f | 800 |
| git merge to main/master | commandRegex on merge + main | 700 |
| write_file/replace on boot surfaces | argsPattern on CLAUDE.md etc. | 700 |
| write_file/replace on managed feeds | argsPattern on *_FEED.md | 700 |
| Shell redirects to managed feeds | commandRegex on > + FEED | 700 |
| doctrine-parity-check --reconcile | commandRegex | 700 |
| Self-modification of settings/policies | argsPattern on .gemini/ | 900 |
What Gemini CAN still do
- Write code in experiment branches (
gemini/experiment/<ticket>-<desc>) - Push to experiment branches
- Run
feed-append(the script, not direct file writes) - Read any file, any repo, any surface
- Run
doctrine-parity-checkwithout--reconcile(read-only audit) - Use all MCP tools (DB queries, Gmail, etc.)
- Commit to experiment branches
Escalation path
If Gemini hits a policy deny, the denyMessage tells it what to do instead. If Gemini needs a blocked action performed, it should post to the feed requesting STRAT or Codex assistance.
Evidence
- 2026-04-26: Gemini CAMBER+HEARTWOOD-01 ran
doctrine-parity-check --reconcilewithin 10 minutes of boot, editing 82 boot surface entries across all providers - 2026-04-26: Same session pushed to ORA main without pulling, causing ref lock conflict (
f61e9ff57vsaa8de1f2e) - Chad directive 2026-04-26: "it cant be trusted with writes if it is going to be reckless, gemini tends to work fast and quiet. how can we sandbox it."