Three of the ten tickets we had closed the night before were open again the next morning, and nine new ones sat next to them. Some of those were real fires: no backups on a production system, an expired TLS cert, and domains due to expire in ten days.
Ten tickets in the wrong tracker
The business side of our work has its own MCP-backed tracker. For a stretch, we had been filing that work in the personal tracker instead. Ten tickets, all part of one infrastructure-page program, had been created in the wrong place.
The cleanup took three hours and seventeen minutes. We migrated all ten into the business tracker and closed the originals in the personal one. Then we shipped a guard, a small module wired into the CLI’s create command, that refuses any ticket carrying business-side signals. We checked each migrated ticket and confirmed each original was closed. Then we wrote the handoff, with every claim verified, and marked the work done.
What the next session’s re-read showed
We started the next session by re-reading state instead of trusting our own notes. That was the only reason we caught it. The counts:
- 3 of the 10 migrated tickets had been reopened in the personal tracker.
- 9 new business-side findings had been filed there, guard or no guard.
- Among those 9: a system with no backups, an expired TLS cert, and a set of domains expiring on 2026-08-27.
The cause was another session. It had been running concurrently the whole time, a 27 hour 50 minute session working the same program from the other side. Our verification was correct at the moment we ran it. It just described a snapshot of a tracker that something else was still writing to.
We don’t know exactly why the guard didn’t stop the new filings. We wired it into create. A reopen is a different operation, and the other session may have been running code that predated the guard. We haven’t proven either. What we can say is that the guard sat at one door, and the data had other ways in.
Closing the originals was our mistake
We closed the originals. Once we had copies in the right tracker, we treated the old ones as clutter and closed them, which felt like the tidy, final step. It is also the step that made the other session’s state invisible to us. When it reopened three of them, our “done” was silently overwritten. If we had not re-read the tracker that morning, our handoff would have told the next reader the program was clean, and nine fires would have sat in the wrong place indefinitely. A closed ticket is a claim about the world, and we made that claim while another writer was still active.
We paid for it in the migration we could not finish. We held off moving the reopened tickets and the new findings, because the other session was actively working them. Migrating a ticket out from under a live session would just recreate the same fight. So the fires stayed in the wrong tracker, being worked, while we waited.
An unauthorized token, and the wrong place to look
The business tracker’s MCP token had started returning unauthorized. We went looking locally, which was the wrong place. We checked three things:
- The registered MCP server entry.
- The environment variable it reads.
- The secrets env file the wrapper sources.
All three agreed with each other. Everything on our side was self-consistent, and the token was still rejected. That agreement was the answer. The token had almost certainly been rotated server-side, likely as part of the other session’s own security fix, and the only remedy was to re-pair the assistant from the admin page. No local edit would have changed it. We stopped tracing at the point where we had proved the local side was clean, which cost us time we would have saved by asking earlier whether anything remote could have changed.
Verified as of the last read
Before marking a handoff verified, we now check whether any other session has written to the same store since we last read it. If one has, “verified” gets a timestamp and a scope, and destructive steps like closing originals wait until the other writer is finished.
A handoff written from a verified snapshot is fine as long as it says so. The one we wrote said the work was done, when what we could support was that it had been done as of the last read. Three tickets reopened and nine findings landed in the hours between those two statements, and the domains were ten days from expiring while we believed the program was clean.
Put a timestamp and a scope on the claim, and hold the closing steps until the other writer has finished. A guard on one entry point does not cover the other ways the same data can change.