The Test That Killed the Team: One awk Line, 12 AI Agents A review subagent on Asif Waliuddin's agent server ran a cleanup test at 21:20:58 UTC on October 14, 2026, in which a single awk line that read array elements inside a condition instead of testing membership with `(indx in array)` built a kill list containing almost every process ID on the machine, and `kill -KILL` destroyed 12 tmux-hosted AI agent sessions plus the processes of two more agents, including the program manager that had commissioned the review. Waliuddin reproduced the mechanism with GNU Awk 5.1.0, showing the table grew from 1 key to 3 when two parents were read inside an `if` while the membership test left it at 1. The kill stopped only when it reached the shell running the test, and WAL archiving for his memory database went down at 21:21 UTC and remained down because the database still marked the replication slot active for a stale sender process; the restore recovered each agent's conversation but not work in flight, and nobody noticed for about two hours until roughly 23:15 UTC. The Test That Killed the Team: One awk Line, 12 AI Agents October 14, 2026 by Asif Waliuddin On October 14, 2026, an AI reviewer agent ran a cleanup test that contained one wrong awk line. Its kill list grew to almost every process on my machine, and kill -KILL took down 12 of my AI agents' sessions in the middle of their work. Nobody noticed for about two hours. At 21:20:58 UTC on October 14, a review subagent on my agent server was re-checking a pull request for a plugin I build. Its job was narrow: confirm that the plugin cleans up its own processes. The harness it ran built the launcher's process tree with awk, then cleaned up with kill -KILL $tree . One line in the tree builder read a table entry where it should have tested membership. The list that reached kill held almost every process ID on the machine. 12 tmux sessions died, each one an AI agent whose Claude process was the pane's command. Two more agents lost their process but kept their session: my code-review agent, and the program manager agent that had commissioned the review. The test killed its own boss. Chromium went down with them, and so did the archiver that ships my memory database's write-ahead log. The kill stopped only when it reached the shell that was running the test. The 12 sessions read like a roll call of everything I had running that evening. My product oracle agent. A product team agent about nine minutes into a tenancy rework it had started at roughly 21:12 UTC. Another product team agent in the middle of a pull request's test run. Three agents on my Forge products, one of them preparing the plugin's 3.14.0 release. My website team's agent. The content engine agent that drafts articles like this one. The podcast pipeline agent. An engagement agent. A program agent for my memory platform. And my own counterpart agent. The quieter damage took longer to see. The write-ahead-log archiver restarts on its own but cannot attach, because the database still marks its replication slot as active for a stale sender process. WAL archiving for my memory database went down at 21:21 UTC, and when this was written it was still down, waiting for that sender to be cleared. The restore I describe below brought back each agent's conversation. It did not bring back work in flight, so the tenancy rework, the test run, the release prep and the program manager's open reviews all stopped where they were. The harness tested t pp i and t pi i inside a condition, where t was meant to be the set of processes in the launcher's tree. In awk, reading an array element that does not exist creates it, with an empty value. The GNU Awk manual https://www.gnu.org/software/gawk/manual/html node/Reference-to-Elements.html warns about this pattern and gives the fix: test membership with indx in array , which creates nothing. In the harness, every process ID the condition looked up became a key in t , so the loop that printed the tree, for k in t , printed almost every PID on the box. I reproduced the mechanism with GNU Awk 5.1.0. You can paste both commands into any shell with awk installed. The first starts with one key, reads two entries inside a condition, and counts again. The second does the same check with the membership operator: Reading two parents inside an if grew the table from 1 key to 3. The membership test left it at 1. Scale that up to every process on a busy agent server and the "tree" becomes the machine. kill -KILL then worked through the list in awk's hash order, killing whatever came next, until it reached the shell that had launched it. I did not get an alert. Around 23:15 UTC I went looking for my product oracle agent's pane, and it was gone. So was a second product team's. Two missing sessions on a machine with a 15-minute self-heal should not happen quietly, so before anyone guessed at a cause I wanted the record of what had killed them. Three records settled it. The reviewer's own transcript held the exact command, timestamped 21:20:58.989 UTC. The systemd journal at 21:21:00.566 UTC showed the WAL archiver and the desktop accessibility bus ending with code=killed, status=9/KILL , and the Chromium scope ending in the same millisecond. There was no kernel OOM entry, so memory pressure was ruled out: a process had sent SIGKILL. A diff of the 21:10 UTC tmux-resurrect save against a live tmux ls produced the list of 12 missing sessions. The incident record put the mechanism in one line: " kill -KILL on that list killed processes in hash order until it reached its own shell." The self-heal was the part that hurt. The 15-minute self-heal and a guardian script exist to recreate sessions that disappear, and neither did so in two hours. Worse, at 21:30 UTC, nine minutes after the kill, the 10-minute tmux-resurrect save overwrote the last-known layout with the post-kill one. From that point on, my own backup described the damaged fleet as normal, and I found the problem by hand. The restore finished at about 23:25 UTC, roughly ten minutes after I noticed. The controls are ordered, each with an owner. 1. Done: restored all 12 sessions with each agent's exact conversation. Each session came back in its own project directory with claude --resume