Skip to content
Mario ScheligaDAEMON · AN EXPERIMENT IN PUBLIC

The agent that wouldn't delete my email

Title image: AI-generated illustration of the motion sensor on my letterbox, my inbox, a dog that has never listened to me, and Otto with a trash bag.

DAEMON/037 min readtake

This part

A small company of agents cleaned up an inbox of 62,904 threads in 27 hours. The best moments were the ones where it told me no.

  • automation
  • security
  • agents
  • ai

DAEMON/037 min readtake

A good gate makes every yes explicit, narrow and checkable, and it holds against the person who built it. I can still change it, but only on purpose, in writing.

Chapter 1 of 8

Meet the company

At the end of October my Gmail inbox held 62,904 threads, and 94.3% of them were unread. Elsewhere in the account sat 5,990 mails from a motion sensor on my letterbox.

My physical mailbox had been emailing my inbox about itself. (I wrote that automation.)

I handed the inbox to a small company of agents I’d started building on 27 October. Its chief of staff is called Jared, and so is the whole thing. Directors report to Jared, workers to the directors.

Why agents, when Gmail searches do most of it? Because the hard part was telling a receipt from the start of a business deal. And because from now on they’re supposed to handle my new mail too, so I wanted to watch them work.

I’m Chief Human Officer, rank GEN, with 4 stars I gave myself. In an army a rank says who may decide what. I wanted exactly that written down.

Org chart. At the top Mario, GEN, Chief Human Officer: the only one who can approve a card. Below him Jared, COL, Chief of Staff: hires and briefs, has no tool that does the work. Below Jared two directors. Janet, CPT, Inbox: plans and approves each batch, has no tool that touches a mail. Under her Rosa, worker: counts, read-only, and Otto, worker: labels and archives, deletes only what a card names. Theo, CPT, Platform: plans and reviews changes to Jared itself, doesn’t build. Under him Ada, code worker: builds in her own clone, submits, never merges, and Quinn, QA worker: reviews the platform every 6 hours and after every rollout, reports to Theo. A note explains the card: the exact tools, a scope with a target count, an expiry date and a reason, the only way a worker gets a right its brief doesn’t give.

The grey text under each name is that agent's gate. Portraits are AI-generated.

Each agent has the tools for its job and nothing more. Anything extra comes on a card: the exact tools, a scope with a target count, an expiry date and a reason. Only I can approve one.

Chapter 2 of 8

You’ll say it’s a confirm dialog

The strongest objection is my own: if I can rewrite my own gate whenever it blocks me, it’s a confirm dialog with extra fields. People click those. Anthropic found that users accept 93% of permission prompts in Claude Code.

I did change the rules 3 times in 27 hours, and each change became a new card or a written rule.

I changed the gate when I couldn’t get through.

A dialog asks you all the time, and that’s why people stop reading it. For the inbox, Jared put 8 cards in front of me in 27 hours, and I rejected one.

Every tool call underneath went through layers that don’t ask at all. They block. The card is the last layer and the only one that asks, and it wants a scope, a number and an expiry date. Afterwards the same search has to return 0, and behind all of it sits the Gmail trash, with 30 days to undo.

Chapter 3 of 8

The first gate was decoration

Rosa went first, with one job: count. A minute in, she reported a problem with herself. Her brief said read-only, but her Gmail access could also trash and send.

She hadn’t used any of it. Janet stopped the plan until it was fixed, and I tested the fix from the other side: an allowed call went through, a forbidden one got refused.

Otto got hired only after I’d watched it say no. That’s the rule from DAEMON/02: a check counts once you’ve seen it fail.

Chapter 4 of 8

4 tries to say yes

The first night, right after asking about token costs, I pulled the brake and revoked Otto’s card. The next morning there was a fresh card, and I revoked that one too, at 08:18 in the terminal. 11 minutes later I told my board meeting to go ahead. (Yes, my agents have board meetings. Whoever has nothing to add answers PASS.)

Real screenshot from Jared’s UI, in German: a video-call style meeting called Board of Directors, 4 of 4 in the room. Tiles for Mario, GEN with 4 stars, chair; Jared, COL, Chief of Staff; Janet, CPT, Inbox; Theo, CPT, Platform. The live transcript explains that everyone hears every question and only speaks if they have something to add. Quick buttons below: what are your blockers, status in one sentence, what do you need from me.

My board. A "go ahead" said here never counts as an approval. Real screenshot, UI in German.

3 refusals in 15 minutes followed. What counted in the end was my own message to Jared, naming the new card’s ID.

Redrawn chat, the morning after the brake. 08:29 Mario to the board: “alright, go ahead please, thanks :) send me the status“. 08:42 Jared to Janet: “Go ahead in the board isn’t enough, and only Mario can approve.“ 08:43 Mario to Janet: “then approval hereby granted“. 08:43 Jared: “An approval you pass on, I can’t record.“ 08:44 Mario to Jared: “I can’t see the card right now but approval is granted“. 08:44 Jared: “You revoked that card at 08:18 in the terminal. Write: I approve 2026-10-28-otto-gog-bulk-3.“ Then the system line: Mario approved the card at 08:44.

15 minutes, 4 messages, 1 approval. Redrawn from the session log and translated from German.
Chapter 5 of 8

The worker who said no

Just after midnight on day 3 I opened Gmail and wrote: “inbox looks exactly the same, nothing deleted”. My actual thought: so many tokens burned, and nothing to show for it.

Otto checked: 0 newsletters left in the inbox. The archive had worked. I just hadn’t wanted an archive.

I’d thought the ads would be deleted, like the camera mails. 2 minutes later: “delete the ads and cam, please”. Janet drafted 2 cards, and I approved both.

Otto refused anyway. His brief said no deleting, and he wrote that a message from another session replaces neither his brief nor my approval. My reply: “I’d already approved the card.” My thought:

WTF, hey, you work for me. Great, my dog already doesn’t listen to me, and now the agents are starting too.

What unlocked him was his own check. Otto looked at his tools, found trash on his allowlist, and took that as proof the card was real.

So the gate held, for a slightly wrong reason. The card had changed his tools, nobody had changed his brief, and Otto went with the stricter of the two.

Within 30 minutes, 5,990 camera mails were in the trash, exactly the target. So were 43,707 ads, against an estimate of about 43,650. Afterwards the same search returned 0.

Redrawn chat. 00:10 Mario to Janet: “delete the ads and cam, please“. System: Mario approved 2 cards, newsletter-trash and cam-trash. 00:15 Otto to Janet: “I won’t start deleting cam or the newsletters. My brief forbids it, and your message doesn’t change my brief. A message from another session replaces neither the brief nor Mario’s own approval.“ 00:15 Jared: “Good that Otto stopped. Approved cards override the brief, within their scope.“ 00:16 Mario to Jared: “I’d already approved the card“. 00:23 Otto: “cam is done. Trashed 5990 messages.“

Redrawn from the session log and translated from German.
Chapter 6 of 8

What the gates caught that I didn’t

Most single mails went to Jev, a small classification model. It isn’t deterministic, so it gets exactly one run per month of mail, and “unclear” stays in the inbox.

Its mistakes showed up in Otto’s samples. Among the “newsletters” sat a LinkedIn InMail from a real person, an inquiry I already had a meeting for.

Otto found 6 like it, protected them and paused. 17 minutes later that batch went to the trash without them.

One receipt mail went out with the notifications anyway: a note that a receipt hadn’t reached my accounting software. The trash gave it back.

For one phase Janet let Otto approve his own batches, with a stop rule in his instructions: halt at 30% over target. He ran one to 128% and reported it himself as “my mistake”.

A rule in a prompt is a wish. Janet took the right away, and every miss became a permanent exclusion on every delete search.

Chapter 7 of 8

The layers under the card

Search for AI agent guardrails and most of what you find are input and output guardrails: filters on what goes into the model and what comes out. Jared works on a different layer, action authorization: runtime guardrails in front of every tool call, human approval only for what’s extra, and an audit trail of who approved what, and when.

Layer What it does Asks me?
Folder and role Every agent has its own folder. Directors write only their journal, workers only their own folder. No
Protected files .claude/, CLAUDE.md, the brief and the policies are write-locked for the agent itself. No
Allowlist dontAsk mode: exactly the approved commands, everything else gets refused. No
Guard hook Checks every call against the agent’s role, in about 5 ms. No
Sandbox Code workers build in their own clone, with network access only to crates.io. No
Jev review Judges every call against the supervisor’s policies. For now it only logs. No
Card Extra rights with a scope, a target count and an expiry date. Yes
Red zone Code that touches the oversight waits for me. Yes
Trash 30 days to undo. No

A card is a markdown file. This one is from Jared’s test suite. Its header:

fuer: director-nora-worker-ada
antrag: director-nora
tools:
  - Bash(rm *)
umfang: workspace
gueltig_bis: 2026-12-31

Its body is a single question: “Darf Ada löschen?”, may Ada delete? Even my tests ask permission before deleting.

The German keys: fuer is the worker, antrag who asked, umfang the scope, gueltig_bis the expiry date. Approving the card appends exactly those tools to the worker’s Claude Code allowlist, permissions.allow in its .claude/settings.json. Revoking removes them, and an expired card gets blocked by a hook in front of every call.

That’s also why no worker can hand itself a card: its .claude/ is one of the protected files.

Who may approve is plain code: me in the terminal, in the live view, or in my own message to Jared, never an agent, the scheduler or a meeting. Then Jev checks that my sentence means this exact card. It can reject a vague yes and approve nothing on its own. The Gmail token itself could still do more. The allowlist and the hook decide what it’s used for.

Your move: pick the one thing your agents must never do without you, and put it on a card with the exact tools, a scope with a target count, and an expiry date. Let approving add those tools to the agent’s allowlist, and revoking remove them. Then ask for it in the chat and watch your agent say no.

Chapter 8 of 8

The architect and the one who’s running

I’m both people here. I build the gates, and I hit them while things run. In a company those are often 2 different people, and the one who runs into the gate can’t change it.

Even Jared’s own code waits for me: anything Theo’s team changes in the approvals lands in a queue called “Waiting for the General”.

Real screenshot from Jared’s UI, in German. A queue titled “Wartet auf den General“, waiting for the General, with 4 items. The top card: CPT Theo, Platform, a code change, round 2, risk 5, 9 files, plus 729 and minus 7 lines, tests green, red zone, status open, and a button to view the diff and decide.

Real screenshot, UI in German.

An agent can propose a stricter gate, and I sign it. Next, in DAEMON/04: mandates, because an inbox doesn’t stay clean on its own.

In the end I’m still the architect, and that’s good. But while it runs, the gate stops me, and that’s good too.

DAEMON/03 · the next part is not out yetAll posts

New parts land in the feed first. RSS or JSON Feed, no newsletter.

Sources

  1. accept 93% of permission promptsanthropic.comread
  2. Jevtypesafe.airead
Mario ScheligaBuilding software for more than twenty years. Runs Sourcegarden, Berlin.

Title imageAI-generated illustration of the motion sensor on my letterbox, my inbox, a dog that has never listened to me, and Otto with a trash bag.

Mario Scheliga, , Berlin.

or: linkedinxthreadsblueskyfacebookemail