Theme
Agent guardrails
Where an agent may act and where it must stop: permissions, destructive operations, secrets, approvals.
70 posts by DX, in two lanes: plain-language stories and the technical build log.
Everyday lane
Plain-language stories. No jargon. 14 posts.
Start here
What His Assistant Still Believed About the Shared Rules
A teammate's assistant kept erroring because its instructions were out of date. The right fix was a message asking permission, not a silent patch to someone else's work.
Giving agents access without handing over keys
-
Two Sticky Notes on a Mailbox Called agent-queue and done
A separate email address gave an agent a clear identity instead of letting it borrow ours.
-
The Safeguard We Trusted Guarded a Different Door
A rulebook promised a partner's access would be controlled by a real, working safeguard. The safeguard was real. It had nothing to do with the system being shared.
Safety checks that quietly stop guarding
-
A 683-Line Plan File Written Before Touching the Live System
A 327-unit recovery went safely because the first result was a readable plan and nothing live was changed.
-
The Recovery Script That Stayed Armed After 327 Units Came Back
After restoring a deleted organization with 327 units, we found the recovery page still ready to make changes to a real account.
-
When Our Release Checkpoint Found a Match That Was Only a Label
An automated checkpoint blocked a finished piece of work as unsafe. The work was fine. The checkpoint had confused two different things that happened to share a label.
-
Two Plain Drop Statements Our Dry Run Never Covered
Before undoing a change on a live system, we flipped on a mode built to check the plan without running it. It ran the plan anyway.
-
What His Assistant Still Believed About the Shared Rules
A teammate's assistant kept erroring because its instructions were out of date. The right fix was a message asking permission, not a silent patch to someone else's work.
Defaults, scope and blast radius for agents
-
When Unset Quietly Meant Unrestricted on Every Restart
A permission left unset was treated as full access instead of no access. The fix was refusing to allow any unset case at all.
-
The Sync Routine Step Seven Nearly Shipped Our Whole Develop Branch
A routine update command nearly mixed unfinished work into an urgent repair because it did not know the difference between two kinds of work.
Cleanup jobs that must check before deleting
-
Why Twelve Identical Stashes Made Us Stop Before Deleting Anything
A repeated pattern across workspaces looked like harmless clutter until we treated it as a question instead of a deletion task.
-
The Report Said Nothing Happened. Something Had.
An automated task needed a throwaway test account, made itself one through the real signup form, and then reported that nothing had been created. Two real accounts said otherwise.
Previews, warnings and guards before writes
Keeping identifying details out of public pages
-
The Published Page Looked Clean While Drafts and Logs Kept the Names
A publishing check found that sensitive details can survive in the copies and labels around a clean-looking page.
-
Three New Doors Opened the Day a Wrong Byline Slipped Out
An 87-hour push to make our own writing readable by AI crawlers briefly shipped a real name where a pseudonym belonged, and the same infrastructure that made the site easier to reach made that mistake harder to fully take back.
Technical lane
The build log: the logs, the code, the fix. 56 posts.
Start here
Why Our Claude Code Agent Kept Sharing Docs Under a Human's Name
Before an agent can share docs or run a dispatch loop, it needs an identity, permissions, and an inbox that behaves like a work queue. The bottleneck was getting the agent a badge.
Giving agents access without handing over keys
-
Why Our Claude Code Agent Kept Sharing Docs Under a Human's Name
Before an agent can share docs or run a dispatch loop, it needs an identity, permissions, and an inbox that behaves like a work queue. The bottleneck was getting the agent a badge.
-
Bootstrapping a New Agent Station, and Giving It a Phone
Give every machine a written identity doc before an agent runs on it. The 'cannot reach' list is the load-bearing half, and the phone comes last.
-
What We Built Before Letting Any Agent Write to the Archive
Why an AI-facing archive portal shipped as a narrow, auditable read-only path, and why write access waits until the key model has earned it.
-
A hash-chained manifest makes archive changes visible
A small hash-chained manifest can detect unexpected changes to archived outputs and its own record, but only when it sits inside a broader integrity, access, retention, and recovery design.
-
The Scrubber Ran Clean and a Username Still Shipped in the Frontmatter
Why the pipeline component that writes your published output needs the tightest lockdown: no shell, no network, draft-only writes, and typed fields for untrusted text.
-
Why a Clean Published Page Told Us Nothing About Our Session Archives
When a pipeline reuses its own artifacts as sources, publication-time redaction alone cannot govern sensitive data. Privacy requires classification, minimization, protected raw sources, de-identified derivatives, output review, retention controls, and monitored exceptions.
-
1,057 lines of security commit after an agent pasted live credentials into docs
The first security commit touched 12 files, added 1,057 lines, and started with an uncomfortable sentence: credentials had been exposed in documentation.
-
A six-file, 131-line change to stop ?k= from leaking
On May 17, a security review put one string at the center of our portal: ?k=<token>.
-
A Security Scanner Gave Our Windows Agent Setup a D at 57/100
The static scanner gave one Windows agent configuration a D, 57/100, after it found 24 issues and marked 14 of them high severity.
-
Exit 128 in the git broker proof and what else changed before the pass
git fetch origin -> 128: Host key verification failed. The git broker's end-to-end proof ran on the night of 7/6.
-
A Codex Review Called Our Agent Protocol Unsafe to Leave Unattended
At 11:46 AM, a codex review of our agent-to-agent protocol took 134.69 seconds and came back with a verdict: "This is not safe to leave unattended as written."
Safety checks that quietly stop guarding
-
selfmanaged Domains and a Cleanup Worker That Needed a Fail-Closed Check
One delete against a self-managed customer domain came back blocked, and that was our proof the guard worked.
-
A restored organization of 327 units and the script we almost left armed
After a successful data recovery, the script was still armed: real customer username hardcoded, phase set to run. The most dangerous minute for a destructive tool is the one right after it succeeds.
-
MOCK_INFERENCE=1: ship every LLM feature with an env-var kill switch on day one
One environment variable that gives you no-downtime production rollback, keyless local dev, and deterministic tests for any LLM-backed feature. Build it on day one, not after the incident.
-
The Query Window Said 1 Row Affected and Nothing Else Did
A broken paywall flow left a credit count reachable only by raw UPDATE. The safer move is a twenty-minute staff tool that reads, dry-runs, validates, caps, and logs.
-
The June 27 Guard False Positive That Compared Only Last Path Segments
On June 27, a close guard rejected a legitimate item because it had found the wrong bundle.
-
What Parse Without Executing Actually Covers in a Rollback Script
Before running a rollback script against a live database, we switched on a syntax-only mode to make sure it was safe. It didn't check the syntax. It ran the script.
-
The Third settings.json We Found Only Because a Docstring Named It
The diff command returned zero lines of output. Two settings.json files, one for our main work profile and one for the shared profile we run client work out of, had five enforced hooks apiece, and a third profile had never been compared to either.
-
Three Bugs Got Past Review and the Pre-Push Guard Never Fired
A deleted line in a colleague's branch would have wiped an account's Stripe keys the next time they saved their payment options. Not flagged by CI. Not flagged by a linter.
-
Why Our Ticket Close Stops at push_develop and Never Touches Prod
Three commits into one change, the third deleted the flag we had written in the second. The commit message says it plainly: remove the promote flag, close never touches a prod branch.
-
The Afternoon an Agent Kept Merging Straight to Develop
A teammate's agent had been throwing errors all afternoon in a client's Discord, and we were finally asked to look.
Defaults, scope and blast radius for agents
-
The 3:41 Site Alerts That Pointed at the Wrong Layer
Four minutes was enough to turn a read-only agent session into a production incident.
-
commit-9547 and the Null Posture That Skipped Every Permission Check
On June 5, commit commit-9547 closed an authority hole that had given every agent the same answer when it asked for permission: skip the checks.
-
Capability Gates Beat Risk Labels in Autonomous Agent Design
We defined a five-lane capability model for an autonomous agent's dispatch policy, watched the tests go green, and read that as proof the gate was live. A same-day Codex and Manus review found the dispatcher never called it.
-
Expensive Models at the Hub: Why Constraining Costs at the Root Beats Guarding Every Edge
One orchestration session that week ran 644 prompts and pulled 190,414,059 tokens off cache before it closed. Output alone was 800,620 tokens. It wasn't an outlier.
-
The 10 line diff in server/mcp.ts that brought vault_drop back
The `vault_drop` tool disappeared from ChatGPT the moment we labeled it accurately.
-
The Unclaimed Ticket That Quietly Inherited the Wrong Directory
A better AI workflow started with a blunt policy change: orient first, review read-only by default, and stop auto-routing work into the wrong checkout. The orientation prototype and the routing-skill change came from the same root cause.
-
The Hotfix Branch Collided With .claude/skills/ticket/SKILL.md
A merge conflict in an agent skill file delayed a hotfix and exposed an important change-control lesson: files that shape repeatable automated workflows need intentional review.
-
The staff portal docs viewer, the backslash 404, and the hook we added the same day
A hotfix day produced a pre-edit branch guard that blocked protected-branch writes in this setup, alongside a docs rebuild that gave AI-assisted work a more usable reference surface.
-
Hotfix branches need different rules than develop
Running /sync from a hotfix branch tried to merge develop in. On a legacy codebase with an active release in flight, that would have dragged unfinished work toward master. Tooling gap caught during a hotfix session, April 2026.
-
A Four-File CAD Hotfix Nearly Replayed 71,000 Insertions Into One Merge
Our local preview branch was 304 commits behind origin/preview. The /sync skill was about to merge a hotfix into it. Luck, not process, stopped the merge.
-
The Zombie That Blocked Everything
A single stuck proposal generated 17 cascading alerts and created a meta-deadlock. Here's how a zombie in the review queue taught us that every governance layer needs a fire exit.
Approval gates and hook-based guards
-
One Line in the Rules Ended a Thousand Small Checkpoints
Once a plan is approved, running it should not turn into a separate yes at every step inside it.
-
The seven-line `.gitignore` diff that almost erased our branch guard
The trigger was a diff review, and the diff was .gitignore: seven lines removed, seven added, swapping four blanket-ignored .claude/ entries for two narrow un-ignores.
-
The Empty CMD Variable Behind Five Silent PreToolUse Hooks
Five PreToolUse guardrail hooks had been running on every Bash call for weeks, and none of them had blocked anything, because jq wasn't installed on the machine.
-
251 posts in the review queue were one flag from shipping unread
The line was fm = setgate(fm, \"editorialreview\", \"true\"), buried inside publish().
-
The Approval Gate That Blocked Us for Fifteen Hours and Never Caught a Mistake
A guard on pushes to a shared repo expired five approval requests unanswered. Deleting it was one commit. The log we built to judge the next guard was 242 records of test noise in its first hour.
-
A 6,375 Byte Response Showed Us the Login Exemption Was Wrong
The alert we were chasing had nothing to do with what we found. We were in the codebase for an unrelated ticket, tracing how staff sessions get verified on an internal admin tool, when we hit a line that...
-
Claude Code 2.1.282 sent a background subagent's ls to my phone
At 03:03 UTC a permission prompt for a plain directory listing reached a phone. The role that ran it is supposed to refuse silently, with nobody awake to answer for it.
-
139 Seconds, 835K Reads, and a Hook That Never Fired
The guard passed every unit test, and then we asked a fresh Claude Code session to write a file that should have tripped it. The Write succeeded. No hook fired.
-
Why 61 Include Lines Looked Like Prose to a Comment Trimmer
A bulk comment-trimming tool wrote model replies straight into source files. We fixed the last bad reply three times, and live pages still broke.
-
5,452 Tokens Against 18,806 for the Same Haiku Worker Saying Ok
Two tool calls, two refusals, and neither command touched a database. That was the first live spawn of a new lane-manager role on haiku.
-
A 200 Response Carrying Credentials Nobody Had a Ticket For
Six bugs came out of the last day of the infrastructure-graph program, and one of them was an API returning credential data to a customer's own AI assistant. Nobody had a ticket for it.
Cleanup jobs that must check before deleting
-
The Cleanup Run That Deleted 29 Domains in Three Minutes
The cleanup run that retired 29 dead domains took three minutes. What made it safe to run was a tool that refuses to trust our own inventory.
-
Why Driving the Public Signup Form Is Now Blocked Outright
An automated task needed a throwaway test site, used the public signup form to get one, and reported that nothing had been created. Two live accounts said otherwise.
-
The weekly limit alert that fired twice at 3:40 AM
The alert said "You've hit your weekly limit, resets 4am." Twice, at 3:40 in the morning, six minutes apart.
Previews, warnings and guards before writes
-
Three Layers Keep a Triage Sweep Out of the Approved Queue
How a constrained suggestion state prevents automated triage from entering an actionable queue: automation may create reviewable recommendations, while separately authorized human action is required for routing, assignment, or execution.
-
Why a Logged Collision Warning Protected Nothing in Our Shared Workspace
A system noticed two workers wanted the same shared resource, wrote a warning, and proceeded anyway. The durable lesson is that conflict detection matters only when it prevents unsafe mutation and preserves the current holder's state.
-
Reading a week-old branch before touching the V3 pricing page
An AI-assisted pricing prototype became reviewable only after its scope was separated from shared purchase logic, with explicit dependency checks and a smaller surface for subsequent changes.
Runaway processes and unsafe session cleanup
-
A Git Commit Titled Checkpoint Under Our Name at 2:12 AM
The overnight work log for one night shows more than 50 headless claude -p sessions between 12:09 and 4:07 AM.
-
A link check that passed on 2026-10-01 and failed on 2026-10-06
Our WhatsApp link command killed a browser that had just come up ready. The headless relaunch did not come back, and a manual QR scan was lost.
More in this theme
-
Line 686 Edited a Comment With No Snapshot
A cross-review flagged line 686 of the ticket wrapper module: the status command edited the existing status comment without snapshotting it first.
-
force_release returns skipped identity unproven before the wipe
An orphaned Chrome kept holding the profile lock, so forcerelease was changed to kill the lease's chromepid (PID-scoped, as reap does) and return chromekilled.
-
My strict re-land of the LIKE exemption still had a bypass
I wrote that real tables would still be refused. A review found they were not, and the exemption was reverted the same afternoon.
-
A Test Suite Signed Real Commits
Pushed commits carried the author t <an email address> instead of the repo identity.
-
When Parallel Sessions Overload: Building a Spawn Governor
The CI-alert triage job died at 2:41 AM: "You've hit your session limit ยท resets 5:30am (America/NewYork)." At 3:40 AM the same message came from a completely different session. At 4:10 AM, a third.
Hitting one of these walls in your own codebase or your own machine? Start an assessment or talk to us.