In ideal development guides, it's always assumed that you're building a shiny project from scratch. In real life, you join a team and find a system that has been running for years, a monolith that mixes three different architectural patterns, and a mountain of legacy code that nobody dares to touch in case the whole thing collapses.
If you also try to coordinate the development of several complex features estimated at several days of work, things get complicated. In a company's day-to-day, Git pipelines and Jira or Agility conventions rule. You can't simply use a random sequential number for your branches if you have a specifically named ticket assigned on your board.
Today we are going to see how to tackle legacy code without dying trying, using reverse engineering to document old systems, how the "Delta-Spec" pattern works in depth, and how to govern multiple specifications in parallel by adapting Spec Kit's default behavior to your Jira or Git branch naming conventions.
1. Reverse Engineering Legacy Code: The art of rebuilding Specs
When you face a complex and messy legacy feature that you need to refactor or extend, trying to guess what it does by reading thousands of lines of spaghetti JavaScript is a waste of time. Instead, we can use AI to reverse-engineer it so that it extracts a structured logical contract in Markdown for us.
Imagine you have a highly convoluted payment fee calculation function written in an old JS file, full of nested conditionals and variables with incomprehensible names like temp_val or res2.
The first step is not to write modern TypeScript code. The first step is to open the chat of your agentic editor (like Google Antigravity) and toss it a structured reverse engineering prompt:
"I want you to analyze this legacy fee calculation logic. Your goal is to reconstruct the underlying business logic contract and output it into a
spec.mdfile structured with EARS syntax. Identify all hidden business rules, edge cases, fixed and variable rates, and error conditions. Do not write new code yet; I only want the logical specification."
The agent will process that gibberish of old code and generate a clean, perfectly readable specification:
# specs/legacy-fees/spec.md
## Business Rules (EARS Syntax)
WHEN the merchant's monthly transaction volume exceeds €50,000, THEN the system SHALL apply a variable fee of 1.2% plus a fixed rate of €0.10 per transaction.
IF the merchant is marked with the 'VIP Partner' tag, THEN the system SHALL waive the €0.10 fixed rate, applying only the reduced variable fee of 0.9%.
IF the source currency of the transaction is different from the destination currency, THEN the system SHALL add an additional currency exchange fee of 0.5% to the base calculation.
From this Markdown, you already have an executable contract. Now you can refactor that legacy function super safely: you let the agent rewrite the code in clean TypeScript based on this reconstructed specification, ensuring that not a single one of the subtle original business rules hidden in the labyrinth of old code is lost.
2. The "Delta-Spec" Pattern in Depth
A very common mistake when a team tries to adopt Spec-Driven Development is thinking they have to document absolutely the entire system before they can code anything. This is technical and organizational suicide.
In production, the Delta-Spec (Specification of Delta) approach is used. The rule is very simple: the old code remains in Read-Only mode for the AI, and we only specify the change we are going to make.
┌────────────────────────────────────────────────────────────────────────┐
│ Delta-Spec Strategy │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Monolith Legacy Code (Read-Only for AI) │
│ - Serves only as integration context and interfaces. │
│ │
│ ▲ │
│ │ (Touchpoints and contracts) │
│ ▼ │
│ │
│ Delta Specification (specs/discounts.md) │
│ - Only describes the NEW behavior (e.g., coupon system). │
│ - New code isolated in independent modules (Wrappers/Adapters). │
│ │
└────────────────────────────────────────────────────────────────────────┘
By limiting the AI's write context exclusively to the "delta" (the current change), you achieve three brutal things:
- Zero token inflation: The AI does not saturate reading or processing gigantic specifications of parts of the application that are irrelevant.
- Entropy isolation: The new code is implemented under a standard of maximum quality (clean architecture, exhaustive unit tests), while the old monolith keeps running in its corner without being dangerously altered.
- Clear boundary definition: In your delta specification, you focus solely on describing how the new communicates with the old using explicit contracts.
3. Control and Governance of Multiple Specs with Jira and Git
In any serious engineering team, you will have several developers working on different features in parallel. It is inevitable to wonder: What happens if my Jira or Agility board demands strict naming conventions for branches? How do I prevent the AI from suffering amnesia or parallel specs from stepping on each other?
Adjusting default sequential numbers to your Jira nomenclature
By default, when you run the /speckit.specify command, Spec Kit's out-of-the-box templates scan the specs/ folder and assign an automatic sequential number (like 001-, 002-) followed by the slug extracted from the prompt.
However, in a company's day-to-day where you have a ticket assigned on your board (for example, the feature/S-143562_payment-gateway branch), what you want is to maintain that exact traceability without relying on a numerical sequential counter.
To align Spec Kit's behavior with your active Git branch, you have three very simple alternatives in practice:
- Pass the explicit slug in the prompt:
You can tell the command the exact name of the folder you want to create:
/speckit.specify slug=S-143562_payment-gateway Design the card payment flow...
- Rename the generated folder (The immediate solution):
If the Spec Kit template defaults to creating the specs/001-payment-gateway folder, you can manually rename it in your editor or terminal to specs/S-143562_payment-gateway. All subsequent commands (/speckit.plan, /speckit.tasks) will work perfectly by reading the specification that is active inside that renamed folder.
- Customize the Workflow in
.agents/workflows/(The ultimate automation):
Since Spec Kit workflows are simple editable Markdown files inside your own repository, you can open .agents/workflows/speckit.specify.md (or the template in .specify/templates/) and add a strict rule:
"Before assigning a sequential number (001-, 002...), run
git branch --show-current. If you are located in a feature branch, use the exact name of the active branch as the subfolder name insidespecs/."
This way, your specifications will be cleanly saved in specs/S-143562_payment-gateway/, maintaining a 1:1 traceability between your business task manager and the repository code.
The "Single-Shot Rifle" Methodology
Having several multi-day development specs coexisting in parallel can end in disaster if AI agents start reading half-finished code or stepping on local files. To avoid this, production teams strictly apply the "Single-Shot Rifle" methodology:
- Rule 1: One spec per Git branch (Absolute context isolation). Never mix the development of two different specs in the same local branch. When you change branches in Git (
git checkout), you completely change context. AI agents from editors like Antigravity will only consume thespecs/S-143562_payment-gateway/folder corresponding to your active branch. The rest of the specification folders remain invisible or are ignored, protecting the AI from context saturation amnesia. - Rule 2: The linear and focused lifecycle. The agent performs outstandingly when you give it a single, closed objective. The recommended flow is to completely finish the cycle of your current feature (Spec → Plan → Tasks → Implement → Analyze) until you get the convergence "OK", open the Pull Request on GitHub or GitLab, pass the human review, merge to the main branch (
main), and only then delete your local branch and create the next one from the clean state ofmain. - Rule 3: Kill the "Contract Drift" in Continuous Integration (CI). If Developer A modifies the user database in their spec and Developer B assumes in their payment gateway spec that this table remains the same in another branch, the integration clash can be painful. To solve this, before allowing a branch to merge into
main, the CI pipeline automatically runs the/speckit.analyzecommand. This validator crosses the branch's contracts with the state of the main branch; if it detects that the payment gateway API assumes fields that no longer exist, the CI build fails immediately before the broken code reaches production.
Learning Summary
If you are going to lead development with SDD in real codebases, stick with these three production pillars:
- Rebuild with Reverse Engineering: Use the technical sparring prompt so the AI reads the code of that convoluted legacy feature and drafts the
spec.mdin Markdown for you. You will save hours of manual analysis. - Don't over-document, use "Delta-Specs": Leave the old monolith in read-only mode for the agents and implement new stories in isolated modules with explicit contracts.
- Take control with Git and Jira: Adjust or customize the Spec Kit workflow to use your branch nomenclature. Spec Kit will adapt the specs hierarchy to your branch transparently, maintaining impeccable context organization with no AI amnesia.
In the next article, Google Antigravity and MCP: Sandboxing, Self-Correction and the Cloud, the definitive conclusion of this series, we will make the leap to the most professional execution environment in the industry. We will dive fully into Google Antigravity to explain how its Agentic Local Sandbox (isolated Linux containers) works and how to configure MCP (Model Context Protocol) servers like Playwright MCP so your agents run interactive visual tests in a real browser and autonomously self-correct console errors before handing you the Pull Request. See you in the final installment!
📚 Spec-Driven Development (SDD) Series
- Spec-Driven Development (SDD): AI Agent Governance and the End of 'Vibe Coding'
- The Governance Chassis: Constitution vs. AGENTS.md (And how not to drown in sync debt)
- The SDD Pipeline in Practice: From EARS Syntax to Atomic Tasks
- The Requirements Interview and the 'SpecOps' Loop: How to Use AI Sparring and Rewrite Code Painlessly
- The Challenge of Existing Code (Brownfield) and Managing Multiple Specs with Jira/Git
- Google Antigravity and MCP: Sandboxing, Self-Correction and the Cloud