The 'note vs check' framing maps onto a much older security idea: the confused deputy. Anything the model can influence is output, not policy - so the boundary has to live where the model has no write access. In practice that means the harness: an egress proxy with an allowlist, headers constructed by fixed code outside the model's reach, tool schemas that don't accept free-text header fields at all. There's also an asymmetry worth stating plainly: a program check has to work every time, a sentence only has to be outweighed once. And the check is testable - you can write a regression test that fails if the User-Agent ever contains the user's email. You cannot unit-test a paragraph in AGENTS.md. Keep the notes for taste and conventions; keep secrets and PII behind code.
DB
Damiano Bianda
Full-stack developer: Nuxt, Vue, TypeScript, Python. Based in Ticino.
The confused deputy is a better name for this than anything I came up with. The model holds authority it didn't earn (your email, your network access) and takes instructions from whoever wrote the last page it read.
Your ordering also matches what our test showed. A pattern check on the way out caught the plain email but missed the same address in base64. Building the User-Agent in fixed code removes that channel entirely, which is stronger than filtering it. An allowlist of destinations is stronger than a denylist of shapes for the same reason: it doesn't care how the data is encoded.
The regression test is a good point, and an easy one to make concrete: start a local server, have the agent fetch from it, and fail the build if any captured header contains the configured account email. I'd like to add exactly that to the small guard repo.
One place I'd extend the "keep it behind code" rule is commits. Git identity comes from config the agent can often read and sometimes write, so the harness should set user.email itself rather than leave it to the session.
Have you found a clean way to handle tools that legitimately need free text, like a search query, where you can't drop the field?
The 'note vs check' framing maps onto a much older security idea: the confused deputy. Anything the model can influence is output, not policy - so the boundary has to live where the model has no write access. In practice that means the harness: an egress proxy with an allowlist, headers constructed by fixed code outside the model's reach, tool schemas that don't accept free-text header fields at all. There's also an asymmetry worth stating plainly: a program check has to work every time, a sentence only has to be outweighed once. And the check is testable - you can write a regression test that fails if the User-Agent ever contains the user's email. You cannot unit-test a paragraph in AGENTS.md. Keep the notes for taste and conventions; keep secrets and PII behind code.