Spec-driven engineering means writing down what an agent should build before it writes code. I still believe in it: a spec is the difference between directing an engineer and hoping a competent one appears in the diff.
Then the work became autonomous: reading the spec, splitting tasks, writing code, running tests, and deciding when to continue. The spec answered what to build, but not what could be skipped, what “done” meant, or whether the model could grade its own homework.
Why does an AI agent stop following instructions in a long session?
Not because the model is careless or dishonest: attention isn't memory. A written rule must be recalled and reapplied at every relevant moment, while a long session keeps putting new demands in front of it.
I wrote rules for it: never commit straight to main; never call a test passing without running it; never skip a step because it looks trivial. Reasonable rules still remained sentences in markdown, vulnerable to drift deep into an autonomous run.
"An instruction like ‘never do X’ in a markdown file is still just an instruction."
Is a better-written spec enough to control an agent?
No. Clearer wording does not turn an instruction into enforcement. If I mean never, wanting isn't a mechanism; the rule must run whether the model remembers it or not.
How do you enforce a rule an agent will actually follow?
Move it out of the prompt: a skill defines the discipline, a hook blocks disallowed actions, a gate checks evidence, and an independent model reviews the draft.
A skill defines how a kind of work gets done. A database change needs a different discipline from a security or UI review, and the matching skill loads that process automatically.
Hooks make “never” enforceable. Running outside the conversation, a hook can block a destructive command, an unchecked deploy, or an out-of-scope commit before it happens.
A gate checks facts between phases: the artifact exists, the test genuinely ran, and the criteria are met. A status update cannot substitute for evidence.
The writer does not approve its own code. An independent model checks the diff against the requirement, without the first draft's blind spot.