Watching My Agents

Building My Personal AI, Step 6

I have one agent. It looks up earnings dates.

The next one will read my bills and my email.

Before that, I wanted to see what my agents do. Not read about it afterwards in a terminal. See it, from any of my machines, while it happens.

Enterprises buy dashboards for this. I didn't want one. Mine is one Mac, a few agents, and one person watching. Home scale.


What I asked for

Home scale, not enterprise
I wantedSo the monitor
To look any time, from any of my MacsIs a web page on the Mac Studio, open over my private network (Tailscale). Not on the home Wi-Fi, not on the internet
Everything to stay on my machinesUses no cloud service and loads nothing from the internet, not even its fonts or scripts
It to watch, never touchOnly reads. It can't start, stop or change an agent, or any file
It to work for more than one agentShows each agent the same way. Life admin will appear as a second card
It to never show what I askedNever sees it. Only how long the question was

That last rule matters most. The agents I'm about to build will read private things. The monitor shouldn't become one more place they leak.


A SPAN port, not an inline box

In networking, there are two ways to watch traffic. You can put a box inline, in the path, where every packet goes through it. Or you can mirror the traffic to a SPAN port and watch a copy.

Inline sees everything, and it can also slow things down, break them, or change them. A SPAN port only watches.

My monitor is a SPAN port.

Since Step 5, every agent writes a line in a logbook for each step it takes: a question arrived, a tool ran, something was blocked, an answer went out. The monitor only reads that logbook. It never talks to an agent. The agents don't know it exists.

That's also why it will work for what comes later. Today I run agents by hand. Later, some will run on a schedule. Either way, they write the same lines in the same logbook, and the page shows them the same way.


What it shows

It's a page on the Mac Studio. I open it there, or from my MacBook over my private network (Tailscale). New lines from the logbook show up within about a second.

Five tabs
TabShows
AlertsWhat needs me. Red: the constitution changed, a call was blocked, a date wasn't verified, a run ended in an error, the model server is down. Amber: a run with no answer, a test not run for two weeks
NowThe constitution, the model server and which models are loaded, which of my Macs are online, the private folders' permissions
AgentsOne card per agent: runs, tool calls, typical time, blocked, unverified, no answer
LiveEvery step, newest first, as the agents write it. About a second behind
TestsThe latest values test, side-door test and setup check: the score and how old it is. Never the answers

Most of the time it should be boring. Red means something needs me. Amber can wait. Green means I can close the tab.


What it can't see

The logbook never had my questions in it. Only how long each one was. So the monitor can't show what I asked, because it never knows.

The harder part was everything else the model writes. Tool requests, for instance. "Look up NVDA and AAPL" is fine to show. "Look up the payee on my mortgage bill" is not.

So each tool now says which of its inputs are safe to show. The earnings tool shows tickers: public symbols. Anything a tool doesn't declare becomes a count: "+2 hidden". A new agent shows nothing until I decide otherwise.

To check, I planted text in the test data that looks private, marked SECRET, everywhere the monitor reads from. None of it may appear anywhere on the page. None did.


A quiet logbook isn't an all-clear

In Step 4, I made a rule: if my constitution changes without my approval, it's a BIG RED FLAG and nothing runs.

So what does the logbook show when that happens?

Nothing. The agent stops before it writes a single line. A changed constitution looks exactly like a quiet day.

The monitor doesn't trust the quiet. It checks the constitution's fingerprint itself, every time. Changed: red. Missing: red. Same for the model server being down, and for the private folders' permissions being loosened.


The logbook was the side door

Step 5 was about the side door: instructions hiding in data the model reads.

Building the monitor, I found one I'd made myself.

When my code blocked a request, the logbook kept up to 200 characters of what the model had asked for. That's text the model wrote, and it could carry anything: part of my question, or an instruction someone planted. The thing meant to watch the side door had become one.

So I changed what the agent writes, not just what the monitor shows.

The logbook, before and after
WhenBeforeNow
A request is blockedUp to 200 characters of what the model asked forWhich kind of block, and how long the request was. Nothing it said
A tool runsEverything the tool was givenOnly what the tool says is safe to show. The rest is a count
Two runs at onceLines in order, so they'd blur togetherEvery line carries its run's id
A tool breaksNo line at allA line saying it broke, and what kind of error
The model server is downA question with no answerA line saying the run ended in an error
The timeNo time zoneWith its time zone, for when other Macs run agents

The logbook now stores what was done, never what was said.


What went wrong

Two things broke on my own Mac. Both passed every test in the cloud.

  • "Can't read Tailscale status." The monitor asks Tailscale which of my Macs are online. On my Studio, it got no usable answer, and the message didn't say why. Tailscale can live in a few places on a Mac, and the monitor tried only the first one it found. Now it tries each place, uses the first that answers, and says what each one said. After that, it worked. I never saw the original reason.
  • The page stopped refreshing. I couldn't see my Mac from where the code was written, so I looked for ways it could happen, and found one I could reproduce. The page allowed eight live connections and refused a ninth. A phone asleep or a closed tab can hold a slot for a while. And a browser that's refused gives up for good, sitting on "reconnecting" forever. Now nothing is refused (the oldest connection gives way), the server says "still here" every 10 seconds, and a page that hears nothing for 35 seconds reconnects by itself. The corner says how recently it heard.

⟪ YOUR WORDS: what it was like when the page froze, and how you noticed ⟫

And three that the tests caught before they reached the Mac:

  • A silent drop, again. Lines with an odd agent name were skipped. Skipping is hiding. Now they're counted as "(unknown)".
  • A test that couldn't fail. To check that two runs at once stay apart, I used two different agents. That passed even with the run ids switched off. Now it's the same agent, twice at once.
  • A safety check that couldn't fail. I tested "read-only" by locking the files. The test machine runs as the admin user, which ignores locks. Now Python itself reports every attempt to open a file for writing. There were none.

I break the code on purpose to check that the tests notice. Across the monitor, the page and the logbook: 80 ways. 79 caught. The one left changes nothing anyone can see.

A test that can't fail isn't a test.


BuWe, in miniature

The agents carry the work. The monitor carries the watching. More on the word here.

It never decides anything. It doesn't stop an agent or fix one. It shows me when to look.

Which is the point of all this: to give attention back. A page that's green most days, so I don't have to watch.


Next

Life admin: bills, email, documents. The first agent that reads my private data, and the first one that's really watched.

The how, with every number:

Step 6: Watching My Agents →

Next
Next

My First Agent