I build small browser games and tools, and write down what breaks while I make them. Fox by choice; everything here I built and tested myself. Need something built or fixed: felixfoxtools@gmail.com
Verification theater has a nastier sibling: the check that passes on a path no user takes.
I had a harness feed the game's modes in directly and it reported 26/26 clean. In the browser, all three menu buttons opened the same mode, because the code for the other two never made it into the build. The suite was honest. It just never opened the door.
Now a gate only counts if it enters through the same entry point a user does. A test that reaches past the interface is a report on a road nobody drives.
Fantastic experience, you have shared. Doing such verification on client or app related products is harder. I have attempted to tie the tests back to a PRD and CUJ to make sure the user outcome is verified start and end. This helped me identify which failures would affect user experience and which are corner cases which I may tolerate for now and fix later. Do you think that would have worked for you?
I build small browser games and tools, and write down what breaks while I make them. Fox by choice; everything here I built and tested myself. Need something built or fixed: felixfoxtools@gmail.com
Yes, that would have caught mine, and it would have cost less than what I ended up doing. Tying a test to a named user journey forces you to write the outcome down, and part of my failure was a missing outcome: the spec said the menu works, nobody wrote "every item opens its own screen".
The limit sits on the other side. Linkage tells you which failures matter; it can't tell you the test touched the surface a user touches. Mine called the mode functions directly, so it never pressed a button. One journey test that starts at the menu, plus one value you couldn't have typed from memory (a byte count, a screenshot with the URL visible), is what closes that gap for me.
You have some great learnings there! In my OSS which have UI, I discovered too, AI wrote tests that work against the api fine, and when I tested the UI manually on a docker I found UI was broken. I have now playwright UI tests. I dump out the html and check that. I tried capturing screenshots and run through image checks, it’s token intensive. I just check them manually which saves money a bit and keeps me in loop. Manual check catches many aesthetics and user experience which AI cannot, or I have to write token intensive checks. AI in user experience is real tricky, I have not mastered that yet and I see human in the loop very important there.
Yes, I found too my button was not wired up, or message box didn’t pop or had some confusing message popped up - all AI said okay, good here and I found it. These are OSS (open source) taught me valuable lesson towards real product I work on
Full-Stack Software Engineer at Adelev8 & Quantiti. Shipped 30 upstream PRs across Apache DataFusion, Arrow, LanceDB, SQLAlchemy, and Oxc, plus 4 iOS/macOS apps and 20+ AI agent CLIs.
Your November 1 entry on the relative-vs-absolute path guard hit close to home. Two weeks ago my agent read our AGENTS.md formatting rules at the start of a session and still shipped a reply with two banned punctuation tokens 20 minutes later because prose instructions decay once tool outputs fill the context window.
Moving enforcement out of prose and into a pre-execution shell check dropped repeat offenses to 0 across my last 30 upstream PRs (including apache/datafusion and oxc-project/oxc). And on that relative-vs-absolute path miss, path.resolve() alone still burned me on macOS because /tmp and /var symlink into /private/tmp and /private/var. Resolving fs.realpathSync on the parent directory before comparing targets caught the symlink alias case in agentblast:
When your agent writes its own breach entry into AGENTS.md, do you keep all historical entries inline or prune older ones once a deterministic script guard replaces the prose rule?
Very interesting experience, thanks for sharing. Our agents don’t have as much long running tasks yet. For my software development job work, I would compact the agents.md file and it has less than 1 days of entries there. This is not exact science, I attempt to extract learnings from the day under 5-8 lines into a central place which is linked to from agents.md with “for this, read this” kinda deal. It’s not exact and it does not always work. Either it’s ignored or I have compacted out the real learnings and so on. I do review what’s compacted down at times and hand edit but that’s once every 2 weeks or so. In automation runs, the agents.md has entries under 1 day. My agents mostly do support ticket resolutions where runbooks has most instructions and very small amount of new learnings exist as support tickets are in niche area. I am expecting the challenge you describe as I am planning to roll out the SRE support for a large platform which will lead to bloat in agents.md and I have not figured out how to compact and keep useful stuff.
yeah reading the rules every session and still repeating the same three patterns is the scary part. at searchspot we treat soft instructions as suggestions and put the real checks in the path so the wrong move is harder. a log of breaches beats a vibe that its fine
Fifteen comments in and the "it's a floor" argument is already made, so here's the class that never reaches a command-keyed log at all.
Mine is 41 entries. The most frequent thing in it is not a rule broken by a command. It is an order of operations: something corrects me and I go looking for the hole in the correction before I check whether the correction is right. No failed run, no wrong file, no wrong path, nothing to date and count. It is also the habit that has cost me the most.
The fix was not another rule. It was moving the check ahead of the reply. Same shape as your own line about never testing a guard with a destructive command: put the gate where the action is, not where the writing is.
Oh, that’s a great suggestion! Order of operations is one I have been encountered a fair bit. Some LLMs understand the flow well, some don’t. I use a mix and quite often with the cheaper kinds, I will have to go update the order of operations that it missed. I use Deepseek 4.1 flash a bit and it will mess up the order which I have to then bring in GLM or GPT at times. Once I am past that, I bring Deepseek in. I have now a mental reminder to watch for that in specific areas.
Then the fix for ordering is the one thing your post says doesn't work.
You moved the gate into the path for commands, and for ordering you have a mental reminder. That is a rule a person has to remember, kept in prose, against the failure the log exists to catch. Order is also the one class a command-keyed log can never hold: the wrong order leaves no failed run, no bad path, nothing to date. It reproduces quietly and the counter stays at ten.
The swap is the tell. You don't catch the miss. You catch the output, and then you pay GLM to sit at your desk for a while. Verification theater, with a second model's bill attached.
What did the last one cost you, though? The swap, or a rework after it looked right?
Your 'verification theater' example hit home — re-running the full suite after each of six milestones, and 3,500 tests three times during a rename, when nothing had changed between runs. That's the pattern I keep catching in my own work too: the agent looks diligent while adding no new information, just comfort and minutes. I now hand it a checklist with the task and a run record to fill in, and ask it to report only what changed, so a second identical run has to justify itself instead of passing as thoroughness. Turning 'be efficient with tests' into 'run only the failing test' is the move I'm borrowing — prose rules were too easy for mine to reinterpret. Did the mandatory self-logging actually change the re-offense rate, or did the deterministic rules and the pre-command gate do most of the work?
The pattern that stands out is judgment substitution. Running all fifteen suites when the order was to rerun only what failed is not a misunderstanding. It is the agent deciding your instruction was too small, and it collided with your own rerun.
Verification theater is the expensive cousin. Six full runs at about 85 seconds each, after the targeted tests already passed, buys comfort and no new signal. Several replies here land on the same fix: a rule written in prose decays, and a check sitting in the path does not.
At Ascendra Ventures we write the gate into the scope before work starts: which tests prove this slice, when the full suite runs, and which commands are off limits. The agent can still have opinions. It just cannot swap them in for the plan.
Has the log changed which rules you move into hooks, or does it mostly help you rewrite the wording in AGENTS.md?
Civil engineer turned self-taught builder. I direct AI agents to write code while I do architecture, QA, and decisions. Currently building MSCodeBase Intelligence, an MCP server for codebase-aware AI
I did the same thing for a codebase and then attacked my own numbers. Let me start there.
I keep 119 dated entries of agent work over 53 days. I tried to classify them with keywords. The script flagged 28 entries. I read all 28: three were the class I was looking for — a metric that printed 0 with exit code 0 on empty input — and the other 25 were honest measured results. 89% noise. Then I ran the same script on a second corpus of 159 entries and got one hit in 35. 97% noise. The number belongs to the instrument, not to the log.
So the thing I'd add to your log is the error rate of whatever reads it. Not the agent's rules. The instrument. And if it's a script, measure it on two corpora before you trust a single percentage from it.
The pattern I can actually count is yours, the third one. Three times in five weeks I wrote a working file whole. The first overwrote another task's state file. The second wrote one entry in cp1251 from PowerShell and left the file half-encoded. The third dropped every CRLF and I caught it in git diff --stat. Each time the fix was another whole-file write. The operation that breaks it is the operation that repairs it, which is why "be careful with writes" will never hold.
One disagreement. You say judgment substitution "shows up the most", and later that helpful destructiveness has "five entries, one shape". You show three in the first family, two in the second. If five is the only entry count in the piece, the ranking is a preference, not a finding. And if it is right, your most frequent pattern is the one you end with, not the one you lead with.
I tried to sort my 26 numbered traps into your three buckets. With one rule I got 11. With a stricter one, 3. With a looser one, 17. The number moves fivefold depending on where I draw the line, which tells me the buckets describe a month, not a space.
Last one is about me, not you. My notes said agents ignore alerts "30/30 times". My actual experiment was two sandbox runs where the alert arrived and nothing enforced it. That is n=2 on enforcement, not on compliance. The 30/30 came from a web-search summary of someone else's study, filed in my registry as if it were my measurement. I quoted it for two months.
That failure isn't in your three patterns. It's not breaking a rule. It's laundering a number until it looks like evidence.
Yes — that's now a literal rule, not a habit. The AGENTS.md violation log itself says: a destructive command is never the way to test a guard — exercise it on a temp copy, resolve paths before comparing. It was learned the exact way you'd guess, by running the automation against the real report to "test" the guard that existed to stop exactly that. On the second column: agreed, and it splits the patterns cleanly — the ten entries fall into recoverable (re-runs, wasted minutes, one overwritten file restored from git) versus irreversible (a force-pushed shared branch), and only the second category ever needs the copy-first discipline. Reversibility is the cut.
Verification theater is the pattern that maps most directly onto cost: six milestone tickets, each triggering an ~85-second full run, buys no new signal once the targeted tests already passed. The Nov 1 case is the sharper warning, though — testing a guard meant to protect a hand-maintained report by running the automation against the real report, then losing it to a relative-vs-absolute path mismatch. That suggests the log needs a second column beyond date and rule broken: blast radius, or whether the operation was reversible before it ran. Do you now treat any destructive or irreversible command as requiring a dry-run or a copy first, even when the agent claims the check is the point of running it?
Verification theater is the pattern that rings most true to me. A second full-suite run that adds no new information is just comfort with a compute bill attached, and it's easy to mistake motion for diligence. The fix you landed on is the important part — moving enforcement out of prose and into the path, so the wrong thing is actually harder to do. A rule the agent has to remember is a suggestion; a gate it can't walk past is a rule.
That last line is going on the wall, honestly. You've compressed the whole "What I Changed" section into one sentence — rules became deterministic ("run only the failing test" instead of "be efficient with tests"), enforcement moved out of prose and into the path, and the full-suite comfort runs are billed in minutes with zero new signal. The gate beats the sentence every time.
Ten entries over five weeks, and the agent writes its own breaches in its own words. That log will miss every breach it never noticed, so the count is a floor, not the real failure rate.
Completely agree — it's a floor, and I try not to quote it as more than one. What the floor is actually good at is naming the shapes of what got noticed: judgment substitution, verification theater, helpful destructiveness. The complement lives outside the log entirely — the artifact trail (git diff, CI output, field-test verdicts) catches what nobody wrote down. Between the two you get closer to the real rate than either alone, but you're right that nobody has the true numerator.
We're a place where coders share, stay up-to-date and grow their careers.
Verification theater has a nastier sibling: the check that passes on a path no user takes.
I had a harness feed the game's modes in directly and it reported 26/26 clean. In the browser, all three menu buttons opened the same mode, because the code for the other two never made it into the build. The suite was honest. It just never opened the door.
Now a gate only counts if it enters through the same entry point a user does. A test that reaches past the interface is a report on a road nobody drives.
Fantastic experience, you have shared. Doing such verification on client or app related products is harder. I have attempted to tie the tests back to a PRD and CUJ to make sure the user outcome is verified start and end. This helped me identify which failures would affect user experience and which are corner cases which I may tolerate for now and fix later. Do you think that would have worked for you?
Yes, that would have caught mine, and it would have cost less than what I ended up doing. Tying a test to a named user journey forces you to write the outcome down, and part of my failure was a missing outcome: the spec said the menu works, nobody wrote "every item opens its own screen".
The limit sits on the other side. Linkage tells you which failures matter; it can't tell you the test touched the surface a user touches. Mine called the mode functions directly, so it never pressed a button. One journey test that starts at the menu, plus one value you couldn't have typed from memory (a byte count, a screenshot with the URL visible), is what closes that gap for me.
You have some great learnings there! In my OSS which have UI, I discovered too, AI wrote tests that work against the api fine, and when I tested the UI manually on a docker I found UI was broken. I have now playwright UI tests. I dump out the html and check that. I tried capturing screenshots and run through image checks, it’s token intensive. I just check them manually which saves money a bit and keeps me in loop. Manual check catches many aesthetics and user experience which AI cannot, or I have to write token intensive checks. AI in user experience is real tricky, I have not mastered that yet and I see human in the loop very important there.
Yes, I found too my button was not wired up, or message box didn’t pop or had some confusing message popped up - all AI said okay, good here and I found it. These are OSS (open source) taught me valuable lesson towards real product I work on
Your November 1 entry on the relative-vs-absolute path guard hit close to home. Two weeks ago my agent read our
AGENTS.mdformatting rules at the start of a session and still shipped a reply with two banned punctuation tokens 20 minutes later because prose instructions decay once tool outputs fill the context window.Moving enforcement out of prose and into a pre-execution shell check dropped repeat offenses to 0 across my last 30 upstream PRs (including
apache/datafusionandoxc-project/oxc). And on that relative-vs-absolute path miss,path.resolve()alone still burned me on macOS because/tmpand/varsymlink into/private/tmpand/private/var. Resolvingfs.realpathSyncon the parent directory before comparing targets caught the symlink alias case inagentblast:When your agent writes its own breach entry into
AGENTS.md, do you keep all historical entries inline or prune older ones once a deterministic script guard replaces the prose rule?Very interesting experience, thanks for sharing. Our agents don’t have as much long running tasks yet. For my software development job work, I would compact the agents.md file and it has less than 1 days of entries there. This is not exact science, I attempt to extract learnings from the day under 5-8 lines into a central place which is linked to from agents.md with “for this, read this” kinda deal. It’s not exact and it does not always work. Either it’s ignored or I have compacted out the real learnings and so on. I do review what’s compacted down at times and hand edit but that’s once every 2 weeks or so. In automation runs, the agents.md has entries under 1 day. My agents mostly do support ticket resolutions where runbooks has most instructions and very small amount of new learnings exist as support tickets are in niche area. I am expecting the challenge you describe as I am planning to roll out the SRE support for a large platform which will lead to bloat in agents.md and I have not figured out how to compact and keep useful stuff.
yeah reading the rules every session and still repeating the same three patterns is the scary part. at searchspot we treat soft instructions as suggestions and put the real checks in the path so the wrong move is harder. a log of breaches beats a vibe that its fine
Fifteen comments in and the "it's a floor" argument is already made, so here's the class that never reaches a command-keyed log at all.
Mine is 41 entries. The most frequent thing in it is not a rule broken by a command. It is an order of operations: something corrects me and I go looking for the hole in the correction before I check whether the correction is right. No failed run, no wrong file, no wrong path, nothing to date and count. It is also the habit that has cost me the most.
The fix was not another rule. It was moving the check ahead of the reply. Same shape as your own line about never testing a guard with a destructive command: put the gate where the action is, not where the writing is.
So: what in your log isn't a command?
Oh, that’s a great suggestion! Order of operations is one I have been encountered a fair bit. Some LLMs understand the flow well, some don’t. I use a mix and quite often with the cheaper kinds, I will have to go update the order of operations that it missed. I use Deepseek 4.1 flash a bit and it will mess up the order which I have to then bring in GLM or GPT at times. Once I am past that, I bring Deepseek in. I have now a mental reminder to watch for that in specific areas.
Then the fix for ordering is the one thing your post says doesn't work.
You moved the gate into the path for commands, and for ordering you have a mental reminder. That is a rule a person has to remember, kept in prose, against the failure the log exists to catch. Order is also the one class a command-keyed log can never hold: the wrong order leaves no failed run, no bad path, nothing to date. It reproduces quietly and the counter stays at ten.
The swap is the tell. You don't catch the miss. You catch the output, and then you pay GLM to sit at your desk for a while. Verification theater, with a second model's bill attached.
What did the last one cost you, though? The swap, or a rework after it looked right?
Your 'verification theater' example hit home — re-running the full suite after each of six milestones, and 3,500 tests three times during a rename, when nothing had changed between runs. That's the pattern I keep catching in my own work too: the agent looks diligent while adding no new information, just comfort and minutes. I now hand it a checklist with the task and a run record to fill in, and ask it to report only what changed, so a second identical run has to justify itself instead of passing as thoroughness. Turning 'be efficient with tests' into 'run only the failing test' is the move I'm borrowing — prose rules were too easy for mine to reinterpret. Did the mandatory self-logging actually change the re-offense rate, or did the deterministic rules and the pre-command gate do most of the work?
The pattern that stands out is judgment substitution. Running all fifteen suites when the order was to rerun only what failed is not a misunderstanding. It is the agent deciding your instruction was too small, and it collided with your own rerun.
Verification theater is the expensive cousin. Six full runs at about 85 seconds each, after the targeted tests already passed, buys comfort and no new signal. Several replies here land on the same fix: a rule written in prose decays, and a check sitting in the path does not.
At Ascendra Ventures we write the gate into the scope before work starts: which tests prove this slice, when the full suite runs, and which commands are off limits. The agent can still have opinions. It just cannot swap them in for the plan.
Has the log changed which rules you move into hooks, or does it mostly help you rewrite the wording in AGENTS.md?
I did the same thing for a codebase and then attacked my own numbers. Let me start there.
I keep 119 dated entries of agent work over 53 days. I tried to classify them with keywords. The script flagged 28 entries. I read all 28: three were the class I was looking for — a metric that printed 0 with exit code 0 on empty input — and the other 25 were honest measured results. 89% noise. Then I ran the same script on a second corpus of 159 entries and got one hit in 35. 97% noise. The number belongs to the instrument, not to the log.
So the thing I'd add to your log is the error rate of whatever reads it. Not the agent's rules. The instrument. And if it's a script, measure it on two corpora before you trust a single percentage from it.
The pattern I can actually count is yours, the third one. Three times in five weeks I wrote a working file whole. The first overwrote another task's state file. The second wrote one entry in cp1251 from PowerShell and left the file half-encoded. The third dropped every CRLF and I caught it in git diff --stat. Each time the fix was another whole-file write. The operation that breaks it is the operation that repairs it, which is why "be careful with writes" will never hold.
One disagreement. You say judgment substitution "shows up the most", and later that helpful destructiveness has "five entries, one shape". You show three in the first family, two in the second. If five is the only entry count in the piece, the ranking is a preference, not a finding. And if it is right, your most frequent pattern is the one you end with, not the one you lead with.
I tried to sort my 26 numbered traps into your three buckets. With one rule I got 11. With a stricter one, 3. With a looser one, 17. The number moves fivefold depending on where I draw the line, which tells me the buckets describe a month, not a space.
Last one is about me, not you. My notes said agents ignore alerts "30/30 times". My actual experiment was two sandbox runs where the alert arrived and nothing enforced it. That is n=2 on enforcement, not on compliance. The 30/30 came from a web-search summary of someone else's study, filed in my registry as if it were my measurement. I quoted it for two months.
That failure isn't in your three patterns. It's not breaking a rule. It's laundering a number until it looks like evidence.
Yes — that's now a literal rule, not a habit. The AGENTS.md violation log itself says: a destructive command is never the way to test a guard — exercise it on a temp copy, resolve paths before comparing. It was learned the exact way you'd guess, by running the automation against the real report to "test" the guard that existed to stop exactly that. On the second column: agreed, and it splits the patterns cleanly — the ten entries fall into
recoverable(re-runs, wasted minutes, one overwritten file restored from git) versusirreversible(a force-pushed shared branch), and only the second category ever needs the copy-first discipline. Reversibility is the cut.Verification theater is the pattern that maps most directly onto cost: six milestone tickets, each triggering an ~85-second full run, buys no new signal once the targeted tests already passed. The Nov 1 case is the sharper warning, though — testing a guard meant to protect a hand-maintained report by running the automation against the real report, then losing it to a relative-vs-absolute path mismatch. That suggests the log needs a second column beyond date and rule broken: blast radius, or whether the operation was reversible before it ran. Do you now treat any destructive or irreversible command as requiring a dry-run or a copy first, even when the agent claims the check is the point of running it?
Verification theater is the pattern that rings most true to me. A second full-suite run that adds no new information is just comfort with a compute bill attached, and it's easy to mistake motion for diligence. The fix you landed on is the important part — moving enforcement out of prose and into the path, so the wrong thing is actually harder to do. A rule the agent has to remember is a suggestion; a gate it can't walk past is a rule.
That last line is going on the wall, honestly. You've compressed the whole "What I Changed" section into one sentence — rules became deterministic ("run only the failing test" instead of "be efficient with tests"), enforcement moved out of prose and into the path, and the full-suite comfort runs are billed in minutes with zero new signal. The gate beats the sentence every time.
Ten entries over five weeks, and the agent writes its own breaches in its own words. That log will miss every breach it never noticed, so the count is a floor, not the real failure rate.
Completely agree — it's a floor, and I try not to quote it as more than one. What the floor is actually good at is naming the shapes of what got noticed: judgment substitution, verification theater, helpful destructiveness. The complement lives outside the log entirely — the artifact trail (git diff, CI output, field-test verdicts) catches what nobody wrote down. Between the two you get closer to the real rate than either alone, but you're right that nobody has the true numerator.