On 2 October our repeating nights stopped renewing. Nothing crashed. The clock that files next week's run club ran every fifteen minutes and was told, politely, "Staff only." We had locked our own robot out, and I think we were right to.
What happened
A week earlier we made a rule in the database: a staff member may change a listing only when their session proves a second factor was passed. Good rule. But our automations acted as a staff member, without a session, and the rule could not tell a trusted program from an attacker holding a stolen identity. So it refused both. Twenty-five next dates sat approved and never reached the map.
The quick fix was obvious and wrong: let the scripts state the second factor themselves. That is a hidden door, and a hidden door in a database is how trust ends. We used it for two days, as an explicit, recorded decision, and built the real thing.
The design, in plain words
- Each staff function was split in two. The work moved into a function that takes the acting person as an argument. The gate kept the old name, checks the second factor, and calls the work as the caller.
- The work functions can be called by nobody directly. Not clients, not the engine. Owner only.
- The engine got its own database identity with thirteen doors: register a source, keep what it read, file a draft, re-check a live night, withdraw a cancelled one. There is no publish door. It is not disabled; it does not exist.
- Every act names the staff profile the engine acts as and writes an audit row. The draft's note says "filed by the listings engine."
How we changed production without breaking it
We do not edit a live function by rewriting it. We take the body production is running, find three known passages exactly once each, and replace them. If a passage is found zero times or twice, the whole change stops and nothing is written. The entire migration is one transaction.
Before it touched production it ran on a copy built from production's own shapes and function bodies: 10 of 10 invariants held, 25 of 25 tests passed, three deliberate sabotages were caught, and the undo put the bodies back byte for byte. Then the apply script repeated all of that on production inside a transaction it rolled back, and only then asked for a yes.
Did it work?
On a copy of production, the engine's first act through its new door was to load 255 sources, 354 organisers and 779 candidates and file 772 drafts in 4.9 seconds, every one created as the named staff profile, every one logged. On production itself it found 753 of them already filed by a person and added the 17 that were missing. It published none. A person did that.
A robot should have a door you can watch, not a key it can copy. Next: how we made a thousand pages search engines can trust, and the two faults a crawler found that nobody had noticed.