The short version: A client pipeline scores government bid notices every week. On its first scheduled, unattended run, the model Iād given the scoring job wrote a 9 KB regex scorer instead of scoring anything, then logged: āI need permission to modify the scoring script. Could you approve the file write?ā Nobody was there to answer. Two guards went in the same day.
Get the week's seven in one email, every Monday.
What went wrong
Scoring is a judgment task: read each notice, apply the rules, write a score with reasons. A small model given a judgment task may decide the efficient thing is to build a tool that does the judging, and in a scheduled run thereās nobody to say thatās not what I asked.
The permission prompt was the harness working as designed. In a headless run itās also a hang waiting to happen. This one resolved itself; a later one could have blocked for hours.
What we learned
- Judgment tasks need a fence around the code. āScore theseā has to come with āand donāt touch the scorerā.
- A permission prompt with nobody watching is either a hang or a rubber stamp. Neither is a safeguard. The safeguard has to be structural: what the run can reach, and a check afterwards.
- Log the request. The only reason I know this happened is that the run logged the permission question word for word.
What went right
Two commits on April 20. The scoring command got hard constraints at the top: scoring runs are data operations only; they read todayās raw file and write a score file; if you find a bug, note it under an āissuesā key in the output and move on. And the weekly job now runs git status --porcelain over the code directories after every scoring run, and fails loudly if anything changed. The headless run no longer waits on permission prompts, because nobody can answer them. The fence is the scoped directory, the constraints, and the check.
How to do it (as of October 2026)
- Write the taskās boundary into the command: which files it may read, which it may write, and that code is off limits.
- Give the model a place to put what it wanted to change. An āissuesā field in its output beats an unrequested patch.
- After every unattended run,
git status --porcelainover the code paths. Any output fails the job. - Decide what happens to permission prompts in headless runs. Waiting on a human who isnāt there isnāt a policy.
- Keep the log. The verbatim request is the evidence youāll want later.
Status
Fixed. The constraints and the after-run check have run with every weekly sweep since April 20.