Last time I wrote about locking down what a Sparra build is allowed to run. Since then the work has been quieter and stranger: teaching the loop to improve itself. Every build run ends with a reflect phase where the model writes down what actually went wrong that cycle, a wasted round, a wrong grade, a contract that outlawed its own fix. I have been folding those findings back into Sparra's built-in role prompts, run after run, so the next build starts from the last one's lessons instead of relearning them.
That created its own problem. The reflect inbox accumulated. Every run dropped its findings as new files with no memory of what was already there, so a known recurring issue re-entered as a fresh duplicate each cycle. The inbox could never stay small, and chasing zero was a treadmill. The fix was to stop treating recurrence as churn and start treating it as priority. A re-observed issue now bumps a counter on the existing finding instead of piling up a duplicate, and the inbox ranks by how often something has come back. The signal I was trying to suppress turned out to be the useful one.
The part that still makes me grin is what happened when I pointed Sparra at Sparra, one model building while another grades. It surfaced a bug that only exists because the tool was inspecting itself. Five tests asserted that a durable cache path was not the throwaway scratch directory, and they checked that by pattern-matching the scratch dir's name, sprj- followed by hex. But when Sparra grades Sparra, the judge runs in a sandbox whose own temp dir is named exactly that way, so the real cache path inherited the token and the assertion false-failed every single grading round. The tool's own test suite was being poisoned by the tool grading itself. The fix was to assert the path's structure, its parent directory name, instead of a fragile substring. A few smaller things came along the way: the orient phase was asked to write a codebase map but ran under a read-only guard with no way to save it, and a builder working in a worktree kept burning turns reading paths that only existed in the main checkout. None of these came from me imagining failures. They came from the tool watching its own runs and handing me the list.