Spec-Driven Development in Practice: Setting Rules for a Scanner

Using Spec-Driven Development to constrain AI agents, making intent explicit before code and avoiding review collapse.
The article describes the author's shift from the review collapse of Agile development to Spec-Driven Development. Through building a small port scanner, the author shows how to write intent into specs, let agents question requirements, and constrain behavior via Git rules, AGENTS.md, a .ai directory, a glossary, and rule analysis. Key findings: agents proactively discover rule omissions, glossaries enforce upfront consultation, and rule changes need analysis and approval. But strict processes create output burden, and the author stresses only approving small, inspectable steps. Setup takes about half a day, with some work reusable as templates.
Agile development can produce code quickly, but problems arise when your review speed can't keep up with the speed at which AI writes code. In this article, the author shares their experience building a small port scanner to demonstrate how to use Spec-Driven Development to constrain AI behavior, making intent explicit before code exists.
From Review Collapse to Spec-First
In a previous article, "When Agile Is Not Enough," the author mentioned that an agent team was producing pull requests (PRs) faster than he could review them. The root cause: he hadn't written down his expectations for the software clearly, so the agent made decisions on his behalf. He could only discover these decisions in the diff, while also having to review both the implementation and the decisions he hadn't even realized needed to be made.
The solution is to move the conversation to before the code exists: write intent into the spec, let the agent question it, and reach agreement on "what to build." Drawing on his background in platform engineering and security, the author chose to develop a small port scanner for authorized penetration testing.
According to analyses from Bilibili creators and YouTube channels, the industry's current discussion of Spec-Driven Development centers on approaches like GitHub Spec Kit and Anatoly Volkhover's "Agentic Spec-Driven Development." Spec Kit describes the concept as an "inversion": the spec no longer serves the code; the code serves the spec. The author chose Volkhover's book as a starting point because Spec Kit's many folders and commands felt overwhelming.

Spec-Driven Development is a development methodology that treats the software specification as the single source of truth, emphasizing writing the spec first and then generating code, with code never being manually edited. Unlike Agile development, which emphasizes "working software over comprehensive documentation," Spec-Driven Development holds that the involvement of AI agents makes documentation central again—because agents need explicit, executable intent to constrain their behavior. GitHub Spec Kit describes it as an "inversion": in traditional development, the spec serves the code, whereas in Spec-Driven Development, the code serves the spec. This methodology is closely tied to making intent explicit: all decisions must be written into the spec before code exists, preventing agents from deciding on their own within the diff. Anatoly Volkhover's "Agentic Spec-Driven Development" further proposes that the spec is not merely documentation but a contract between the agent and the human, and that the agent has the right to question omissions and conflicts in the spec.
Letting the Agent Use Git: A Complete Analysis of One Rule
Volkhover's workflow specifies that the spec is the single source of truth, code is generated from the spec, and it cannot be manually edited. The agent has a set of persistent rules in the repository that govern how it works and how the rules themselves change.
The first thing the author wanted to change was the Git restrictions. The book doesn't let AI touch Git, but the author reasoned that if a change has been reviewed and approved, why not let the agent commit it? He required the agent to work on feature branches, one commit per logical step, using Conventional Commits, while reserving push and merge to main for himself.
In this workflow, instead of directly editing the rules file, the author tells the agent the requirements and has it first analyze the proposed rules. The agent reads rule-analysis.md, analyzes what is allowed and forbidden, checks for conflicts with existing rules, and resolves file reference issues.
The agent's response pointed out several omissions: there was no explicit prohibition on merging to main (even though the author intended to reserve that for himself); the "no reset" rule also covered unstaging, so git restore --staged should be used; and the first version of the rule format bundled multiple requirements together, so it was rewritten into twelve rules. After the author approved, he added a condition: no discarding uncommitted work without asking, processed through the same analysis flow.
Conventional Commits is a commit message specification with the format <type>(<scope>): <description>, where common types include feat, fix, docs, chore, etc. It makes commit history readable and enables automated changelog generation. In a spec-driven workflow, the agent's use of Conventional Commits means each commit carries semantic information, making it easier for humans to review and trace rule changes. A feature branch is an independent line of development branched off from the main branch in Git; the agent commits on this branch, while the human retains the authority to push and merge to main. A fixup commit is a small commit used to correct an unmerged commit, generated via git commit --fixup and later squashed with git rebase --autosquash, keeping history clean. Together, these Git mechanisms form the permission boundary between the agent and the human: the agent can commit freely within a branch, but operations involving history rewriting and the main branch must be controlled by the human.
Managing Rule Files: AGENTS.md and the .ai Directory
The bootstrap file used CLAUDE.md, but the author switched to AGENTS.md because he didn't want the name tied to a specific tool. Claude Code has supported this file since version 2.1.277, loading AGENTS.md by default when there is no project CLAUDE.md.
The author also moved supporting files into a .ai/ directory, including rule-analysis.md (checks before rule changes), rule-conflict-protocol.md (conflict handling procedures), a logs/ directory, and glossary.md (project glossary).
AGENTS.md opens with a brief description of the project's goals. If the agent is asked to do something inconsistent with those goals, it should ask about the connection. It also contains instructions for handling undefined terms and conflicting rules: when two rules cannot be followed simultaneously, the agent records the conflict and asks how to proceed.
The file registry is placed at the bottom, explaining the purpose of each file and what operations the agent may perform on it. The agent can edit certain files, can only read others, and can only append to logs. Before creating a file, it must propose a registry entry and get approval—it cannot quietly invent new file types or handling protocols.
AGENTS.md is a tool-agnostic bootstrap file format designed to replace tool-specific names like CLAUDE.md. Claude Code has supported this file since version 2.1.277, automatically loading AGENTS.md when there is no CLAUDE.md in the project. This design allows the same set of agent instructions to be reused across multiple AI coding tools, avoiding vendor lock-in. The rule-conflict-protocol is the procedure for when two rules cannot be followed simultaneously: the agent must record the conflict and ask how to proceed, rather than choosing one on its own. The file registry is located at the bottom of AGENTS.md, specifying the purpose of each file and the agent's permissions (edit, read-only, append). Before creating a new file, the agent must propose a registry entry and get approval, preventing it from quietly inventing new file types or handling protocols. Together, these mechanisms ensure the agent's behavioral boundaries are clear and auditable.
souvlaki-case: A Mini Experiment with a Glossary
The glossary gave the author a chance to observe how the agent handles content that cannot be looked up from general knowledge. The familiar foo-bar convention is called kebab-case; the author prefers to call it souvlaki-case (same hyphens, different lunch).
The agent stopped and asked the author what he meant—fair enough, since the author gave the name but not the definition. The book's glossary records both meaning and anti-meaning. For souvlaki-case, the meaning is lowercase letters and digits connected by hyphens; snake_case and camelCase are explicitly excluded.
The author also added a rule: consult the glossary before asking about unclear terms. Afterward, the agent looked up the definition instead of asking. This small example demonstrates what the author expects for project terminology: once an agreed meaning is reached, record it where the agent will consult it.
According to GitHub Spec Kit documentation and Volkhover's independent analysis, this approach of explicitly defining terms is common in Spec-Driven Development, but making it a mandatory precondition for the agent is the author's own improvement.
kebab-case is a naming convention that uses hyphens to connect lowercase words, such as my-variable-name. snake_case uses underscores to connect lowercase words, such as my_variable_name. camelCase lowercases the first word and capitalizes the first letter of subsequent words, such as myVariableName. A glossary in Spec-Driven Development records the meanings and anti-meanings (explicitly excluded interpretations) of project-specific terms, ensuring the agent doesn't make incorrect assumptions based on general knowledge. The author's naming experiment of substituting souvlaki-case for kebab-case shows that when the agent encounters a term it cannot look up from general knowledge, it will proactively ask; once the glossary records a definition, the agent will consult the glossary before asking. This mandatory "check the glossary before asking" precondition turns terminology management from passive recording into active constraint, reducing the cost of repeated clarification.
History and Traceability
Each approved rule change has its own commit. For example: chore: bootstrap from agentic-spec.com, docs(agents): add version control rules, docs(agents): require fixup commits for unmerged corrections, etc.
If you need to know when the agent was given commit permissions, you can find that change and read the conditions. As the spec grows, the author wants the same traceability for the software: why a feature exists, what we agreed it should do, and how it changed. This matters for audits and compliance, and it's also useful when reviewing your own project months later.
Is This Process Worth Using in Every Repository?
Setup took about half a day. The bootstrap is generic, so part of the time went to adapting it for software development and part to formulating his own rules. The author wouldn't repeat all of this work for every tool. In an enterprise environment or when building multiple tools, it makes sense to put shared setup in a reusable template, including conventions for Python, Go, or Java. If there's a platform team, maintaining that template should be part of its responsibilities.
Working within your own rules also takes adjustment. The author made the process strict enough that even renaming a folder requires analysis and approval—that part is his own doing. The more familiar problem is output volume—an agent can produce long rule analyses as easily as it produces long diffs, and you still have to read them before approving. The author asked for smaller steps. Moving the conversation into Markdown didn't give him more time or attention.
"I can only approve what I can inspect, and I can only inspect small steps." This is the author's core conclusion.
Next Step: Scanner Spec
The setup gave the author a place to record decisions and a process for questioning them before they become rules. The Git example already caught omissions in the instructions. Next, the author wants to see how this works for actual scanner requirements. In part two, the author adds what's needed for code generation and writes the first feature spec. Before writing a single line of code, the coding agent comes back with eight questions.
One-line Summary
Using Spec-Driven Development to constrain AI agents, making intent explicit before code and avoiding review collapse.
Paragraph Summary
The article describes the author's shift from the review collapse of Agile development to the practice of Spec-Driven Development. Through the case of building a small port scanner, the author shows how to write intent into the spec, have the agent question requirements, and constrain AI behavior through Git rules, the AGENTS.md bootstrap file, a .ai directory, a glossary, and a rule analysis process. Key findings include: the agent can proactively discover rule omissions, the glossary can enforce upfront consultation, and rule changes require analysis and approval. But the strict process also brings an output volume burden, and the author emphasizes "only approve small steps you can inspect." Setup takes about half a day, and part of the work can be reused as a template.
Related articles

Random Pruning of the DPO Computation Graph: 1.4x Training Speedup and Lower Peak Memory
DPO training too slow and memory-hungry? This paper proposes a random pruning framework for the DPO computation graph, sampling independently across position, sequence, and branch dimensions; branch pruning achieves a 1.426x step-time speedup and cuts training time by about 30%, with in-depth attribution of memory and time gains.

Why Does JEPA Underperform MLM in Longitudinal EHR Representation Learning?
New study compares JEPA and MLM for longitudinal EHR representation learning on MIMIC-IV: three JEPA variants train stably without collapse but underperform MLM; target size, not heterogeneity, drives prediction error.

Transfer Learning + Visible Light Communication: A New Approach to Energy-Efficient Indoor Positioning
A study proposes a transfer learning-based visible light communication indoor positioning method, achieving 47% accuracy improvement on the BOSCH factory dataset, 67.5% model efficiency under high noise, and introducing the ME composite metric for energy-efficient positioning in energy-constrained industrial IoT scenarios.