AI became more useful when it stopped being the runtime
Today we were trying to finish what should have been a fairly boring technical task: move a governed set of evidence rows from a locked source into a development database.
The rules were already clear. Existing rows could not be changed or deleted. Nothing could become public. The source had to stay fixed. Every write had to be verifiable.
Still, the work kept stalling.
The conversational loop became the problem. A long sequence of reads, transformations, database calls and checks repeatedly ran into timeouts and additional safety checks. What should have been a deterministic operation started consuming attention, retries and model capacity.
My first instinct was to make the prompts smaller and the batches safer.
That was not the real fix.
The important realization was that we were asking the AI conversation to be the runtime for work that no longer required conversation.
So we changed the shape of the job.
Instead of asking the AI to repeatedly move the next batch, we built a small deterministic runner. The AI defined the boundaries, inspected the existing system, designed the fail-closed checks, interpreted failures and reviewed the result. The software did the repetition.
The workflow became:
lock the source → reconcile the real state → dry-run → prove rollback → execute only what is missing → reconcile again
That change solved more than the timeout problem.
We stopped using a remembered row number as progress. The runner reconstructed the entire target every time and compared it with what actually existed in the database. That mattered because 38 older rows had historically different deterministic keys even though their governed content was identical. A simple key comparison would either have duplicated them or forced us to rewrite history. Exact semantic reconciliation let us preserve them and still prove completeness.
We also stopped treating "the source has not changed" as an assumption. The source was pinned by its reviewed revision, modified-time boundary and an exact hash of the relevant range. The runner read the canonical Google Sheets values rather than relying on a spreadsheet export whose serialization could subtly differ.
Credentials became part of the design as well. The database connection and a short-lived Google token lived in GitHub Actions secrets rather than in the conversation. When the migration was finished, the temporary Google token was deleted.
Then the review process found something important that the successful migration itself had not exposed. Our database guard initially checked whether the development project identifier appeared somewhere in the connection string. That sounded safe, but it was not strong enough. A correctly scoped username could theoretically be paired with the wrong host. We changed the guard to require the exact allowed Supabase endpoint, the exact project-scoped user and the expected database before the runner could connect.
That is another lesson from today: the most useful review findings often sit at the boundary, not in the main algorithm.
The final result was almost boring, which is exactly what we wanted. The runner started with 758 existing governed rows, identified 1,780 genuinely missing rows, proved a 100-row transaction could be rolled back without changing persistent state, then completed the remaining population in 18 batches. The final reconciliation showed 2,538 rows, 2,538 unique keys, 2,538 unique fingerprints, zero missing rows and zero public rows. We ran it once more after completion and it performed zero inserts.
That last run may be the most satisfying part. The system did not merely finish the task. It knew there was nothing left to do.
The broader lesson for me is that "use AI for the task" is often the wrong abstraction.
When the work is ambiguous, AI can be excellent at interpretation, reasoning, design and review. When the work has become repetitive and deterministic, keeping the AI inside every iteration can make the system slower, more expensive and less reliable. At that point the better move may be to let AI design the machine, then let the machine run.
There is also a useful response to friction here. When safety checks repeatedly interrupted an authorized and benign workflow, we did not try to outsmart the checks with cleverer wording. We changed the architecture so the repetitive operation no longer depended on a conversational loop at all.
What changed: We moved AI from being the runtime of a repetitive migration to being the designer, reviewer and exception handler around a deterministic, resume-safe runner.
What I think matters: Good AI workflows need a clear handoff point between judgment and repetition. Once a process can be made deterministic, the AI should often stop doing the repetitions and start governing the system that does them.
What remains uncertain: I do not yet know where that handoff point sits for every kind of knowledge work. But I suspect a useful question is becoming: *Which parts of this task still need intelligence, and which parts are only waiting for software?*