Topic: Part 13. Supporting an Existing Project
Difficulty level: Medium
Estimated study time: 6-8 hours (theory + practice)
Prerequisites: Basic understanding of SDD (Spec-Driven Development)
Experience working with Git and version control systems
Familiarity with TypeScript/JavaScript and web frameworks
Understanding of project structure (package.json, routes, tests)
Experience working with AI assistants (Qwen Code or equivalents)
Learning objectives: Restore project constitution (mission.md, tech-stack.md, roadmap.md) from existing code and documentation without rewriting the application
Distinguish facts, assumptions, and unknown zones when analyzing legacy code and formulate clarifying questions for the team
Transform unstructured TODOs and tracker tasks into a phased roadmap with clear priorities
Apply the standard SDD cycle for implementing new features in an existing project, preserving existing code conventions
Identify and minimize SDD risks in an existing project: outdated README, accidental code as rule, tests that lock in bugs
Overview: This part of the course is devoted to applying the Spec-Driven Development (SDD) approach not to a new, but to an already existing project. The key idea: SDD is useful not only for greenfield projects. In an existing project, specifications can be recovered from code, README, TODOs, task trackers, changelogs, tests, and architectural documents. This is not "rewrite old code" — it is adding a layer of intent that was previously missing. You will learn to conduct code archaeology: extract facts, separate them from assumptions, form a project constitution through an interview with an AI assistant, and then continue the standard SDD cycle. Special attention is paid to risks: outdated documentation, accidental code taken as architectural rule, and the temptation to "clean up" the project in a feature branch without explicit permission.
Key concepts: Constitution recovery: The process of creating specs/mission.md, specs/tech-stack.md, and specs/roadmap.md based on analysis of an existing project without rewriting it. The constitution adds a layer of intent that was previously missing and serves as the foundation for further SDD work.
Facts vs. assumptions vs. unknown: A critically important distinction when analyzing an existing project. Facts are what can be proven from code (e.g., TypeScript is used). Assumptions are interpretations requiring verification (e.g., "this is a microservices architecture"). Unknowns are gaps that need to be filled with questions (e.g., deployment target).
Recovery process: A structured approach: existing project → recovery (constitution) → continuation of standard SDD cycle. This ensures continuity: the project does not stop for a "big refactoring" but gradually accumulates specifications.
Interview with AI assistant: A method of working with Qwen Code where the assistant asks clarifying questions before writing files. Three groups of questions: gaps in mission, assumptions in tech stack, roadmap priorities. This protects against invented architecture.
Roadmap from TODO: Transforming an unstructured list of tasks into a phased plan with clear boundaries. Each phase contains specific, verifiable steps. Helps avoid "infinite TODO" and provides decision points.
Existing code conventions: Patterns found in project structure (where routes, components, tests, migrations live). Key rule: do not add new architecture when connecting SDD to an existing project; preserve behavior of existing routes.
SDD risks in existing project: Specific dangers: accidental old code is taken as architectural rule; README is outdated; TODO does not reflect current priority; tests lock in bugs; temptation to "clean up" project in feature branch. Antidote — explicit separation of "observed," "resolved," and "unknown."
Feature specification for existing project: After constitution recovery, the standard SDD cycle is applied: find the next incomplete phase in roadmap.md, create feature specification, use existing conventions, ask about boundaries before writing files.
Practice exercises: Name: Exercise 1: Code Archaeology — Fact Gathering
Problem: You are given an existing AgentClinic MVP project without a specs/ folder. Using the provided prompt for Qwen Code, conduct project analysis. The project contains: README.md with general clinic description, TODO.md with 8 items, package.json with dependencies, folders src/routes, src/components, src/db/migrations, tests/. Your task is to compile a list of facts only, separating them from assumptions. Then formulate 3 questions in each of three groups (mission, tech stack, roadmap).
Solution: Step 1: Launch analysis with the prompt "Study the project and compile a list of facts only...". Step 2: Check the resulting list for assumptions (e.g., if the agent wrote "uses microservices architecture" — this is an assumption; fact: "single entry point in src/index.ts"). Step 3: Group facts: runtime (Node.js 18 from package.json), framework (Hono from dependencies), scripts (dev, build, test from package.json), storage (better-sqlite3 in dependencies, migrations folder), routes (files in src/routes), tests (Vitest from devDependencies). Step 4: Formulate questions for Group 1 (mission): "What is the target audience — private patients or corporate clients?", "Are there plans for a mobile app?", "Which jurisdiction regulates medical data processing?". Group 2 (tech stack): "Where is the application deployed — VPS, cloud, on-premise?", "Is there a CI/CD pipeline?", "Which linter and formatter are used — ESLint, Prettier, Biome?". Group 3 (roadmap): "Which TODO item blocks other tasks?", "Are there deadlines from regulators?", "Which items have already been started in code but not marked in TODO?". Step 5: Compare your questions with answers from a mentor or colleague, refine the constitution.
Complexity: beginner
Name: Exercise 2: Recovering tech-stack.md
Problem: Based on facts gathered in Exercise 1, create a specs/tech-stack.md file for the existing project. The project uses: TypeScript, Hono with server-side JSX rendering, better-sqlite3 for SQLite, Vitest for tests. Structure: src/routes, src/components, src/db/migrations, tests/. Unknown: deployment target, CI configuration, linting policy. Also discovered in code: a non-standard pattern where some routes use direct SQL, others use an abstraction from src/db/queries.ts.
Complexity: intermediate
Name: Exercise 3: Converting TODO to Phased Roadmap
Problem: Given a project TODO.md: "Add feedback form", "Add about company page", "Add customer reviews", "Add map to about company page", "Add online booking", "Telegram bot integration for reminders". Business priorities: feedback form is needed for license (legal requirement), online booking is main MVP goal, Telegram bot is nice-to-have. About company page and reviews are marketing. Convert to a roadmap with phases, considering dependencies and priorities.
Solution: Step 1: Analyze dependencies between tasks. Map depends on about company page. Reviews can be added to about company page or separately. Online booking does not depend on other tasks but is critical for business. Step 2: Set priorities considering business goals: Phase 0 (legal minimum): feedback form. Phase 1 (main value): online booking. Phase 2 (marketing foundation): about company page. Phase 3 (page extension): map on about company page. Phase 4 (social proof): customer reviews. Phase 5 (convenience): Telegram bot for reminders. Step 3: Detail each phase with verifiable steps. Example for Phase 1: "Add appointments table with statuses", "Add /booking route with specialist selection", "Add validation for slot overlap", "Add tests for edge cases (midnight crossing, time zones)". Step 4: Add phase transition criteria: feedback form approved by lawyer, online booking tested by 5 real users. Step 5: Record in roadmap.md with priority and blocking notes.
Complexity: intermediate
Name: Exercise 4: Feature Implementation with Existing Conventions
Problem: Implement "Phase 1: feedback form" from roadmap.md. Existing project conventions: routes in src/routes with [feature].ts naming, form components in src/components/forms, validation via Zod (already used in one route), integration tests in tests/routes. A conflict discovered in code: one developer used direct SQL in routes, another used queries.ts abstraction. The feature specification does not require resolving this conflict. What do you do?
Solution: Step 1: Create feature specification with explicit statement: "Use existing conventions; do not resolve architectural conflict SQL vs. queries.ts within this feature." Step 2: Choose approach consistent with majority of existing code. If 70% of routes use queries.ts — use it; if majority use direct SQL — use direct SQL with comment "follow pattern of existing routes." Step 3: Create specs/features/feedback-form.md with boundaries: input data (name, email, phone, message, consent to processing), validation (Zod schema), route POST /api/feedback, page /feedback, tests (successful submission, validation errors, XSS protection). Step 4: Before writing files, ask clarifying questions: "Where do notifications go — admin email, Telegram, CRM?", "Is captcha needed?", "Should failed attempts be saved for spam analysis?". Step 5: Implement feature, preserving behavior of existing routes. Step 6: Record technical debt: "Architectural conflict SQL vs. queries.ts requires separate refactoring specification."
Complexity: advanced
Name: Exercise 5: Protecting Against "Tests Lock in Bugs" Risk
Problem: During project analysis discovered: test tests/routes/appointment.test.ts passes but checks incorrect behavior — when slots overlap, two records are created instead of an error. This is known bug #47 in tracker, deferred for 3 months. Test was written before bug discovery and locks in current (erroneous) behavior. You are preparing specification for "online booking" feature that touches this area. What to do?
Solution: Step 1: Record fact in tech-stack.md in "Risky zones" section: "tests/routes/appointment.test.ts: test #3 checks creation of overlapping slots, which is bug #47. Test passes, locking in erroneous behavior." Step 2: In "online booking" feature specification explicitly state boundary: "Unless specification requires otherwise, preserve behavior of existing routes. Bug #47 is out of scope for this feature." Step 3: If specification requires correct behavior (logical for online booking), create separate refactoring specification: "Bug #47 fix: slot overlap should return 409 Conflict." Step 4: In refactoring specification state: update test #3 to check for error, add test for edge case (slot ends exactly when another begins — not counted as overlap). Step 5: Get explicit permission for refactoring from responsible person, as this changes existing behavior. Step 6: Never "clean up" bug "along the way" in feature branch — this violates atomic change principle and complicates code review.
Complexity: advanced
Case studies: Name: Case: SDD Implementation in Legacy Medical Clinic Project
Scenario: Company "HealthPlus" has been developing a web application for a private clinic since 2022. Project is written in TypeScript + Hono, uses SQLite, deployed on VPS. Over 2 years, 4 developers came and went, each leaving their mark: different code styles, conflicting SQL approaches, outdated README (still from first developer, mentions Express instead of Hono). TODO.md contains 23 items, some completed, some outdated, some duplicated in task tracker. New CTO wants to implement SDD without stopping development. Team of 2 developers fears "big refactoring."
Challenge: Main problems: (1) README outdated by 18 months and misleading — new developers waste time; (2) architectural decisions not documented, each developer interpreted structure their own way; (3) TODO.md and task tracker not synchronized, priorities unclear; (4) tests cover 40% of code, yet 3 tests lock in known bugs (developers "didn't have time" to fix them); (5) temptation to "clean up" code when adding new features — already twice led to production regressions.
Solution: CTO applied approach from Part 13. Step 1: Used Qwen Code with fact-gathering prompt — got objective picture in 30 minutes instead of weeks of "onboarding." Step 2: Conducted interview with assistant on three question groups, clarifying mission (target audience shifted from private patients to corporate), tech stack (discovered undocumented Redis for sessions), priorities (legal requirement — feedback form — was forgotten in tracker). Step 3: Created constitution with explicit separation: "Discovered," "Found conventions," "Unknown," "Constraints." In tech-stack.md recorded architectural conflict SQL vs. abstraction and marked it as "do not resolve without refactoring specification." Step 4: Converted TODO to phased roadmap: Phase 0 (legal minimum), Phase 1 (online booking — main value for corporate clients), Phases 2-4 (marketing, integrations). Step 5: Implemented Phase 0 via feature specification, explicitly preserving existing conventions. Step 6: For bugs locked by tests, created separate refactoring specifications with explicit priority and approval.
Result: In 2 weeks project got working constitution. New developer joining on week 3, understood project in 2 days instead of 2 weeks. Feedback form implemented in 3 days without regressions. SQL architectural conflict scheduled for Q2 with separate specification and budget. CTO noted: "We finally see what's happening, instead of fearing the code."
Lessons learned: Outdated README is worse than absent — it actively harms new developers. Constitution recovery must start with checking relevance of existing documents.
AI assistant interview on three question groups reveals gaps that a person immersed in the project stops noticing. External "naive" view is critically important.
Explicit separation of facts, assumptions, and unknown protects against "invented architecture" — the main risk when working with legacy code.
Temptation to "clean up along the way" is never justified. Separate refactoring specifications with explicit priority and budget — the only sustainable path.
Tests that lock in bugs must be explicitly marked in constitution as "risky zones" — otherwise they will reproduce errors indefinitely.
Related concepts: Constitution recovery
Facts vs. assumptions vs. unknown
Interview with AI assistant
Roadmap from TODO
SDD risks in existing project
Feature specification for existing project
Name: Case: Failed Attempt at "Quick SDD" and Return to Process
Scenario: Startup "FastMed" decided to accelerate SDD implementation in existing project, skipping constitution recovery phase. Tech lead assigned developer to "just start writing feature specifications" for new functionality — laboratory integration. Developer studied code for half a day and wrote specs/features/lab-integration.md.
Challenge: Developer did not conduct interview on three question groups, did not separate facts from assumptions. In specification they assumed project uses REST API for all integrations (in fact, existing pharmacy integration used SOAP due to partner requirements). They also didn't notice that in src/db/ there are two migration systems: knex migrations (outdated) and manual SQL files (current). In specification they proposed using Prisma — a new ORM not in the project. During implementation conflicts arose: laboratory SOAP requirement was missed, Prisma migration broke existing schema, tests started failing due to changed behavior of old pharmacy routes.
Solution: After 2 weeks of "firefighting" team returned to process from Part 13. Stopped new feature development for 3 days (not for refactoring, but for constitution recovery). Used Qwen Code for fact gathering — discovered SOAP integration, dual migration system, undocumented cron for stock synchronization. Conducted interview, clarified priorities: laboratory required SOAP, refusal impossible. Created tech-stack.md with explicit constraint: "Do not add new ORMs or frameworks." Converted laboratory integration to Phase 2 of roadmap, after unification of integration approach (Phase 1).
Result: Project lost 2 weeks on fixes, but saved months of future problems. Unification of integration approach (SOAP wrapper for all medical partners) became architectural decision documented in constitution. Tech lead implemented rule: "No feature specifications without current constitution."
Lessons learned: Skipping constitution recovery phase seems like time saving, but always leads to costly mistakes. "Quick SDD" is not SDD.
Assumptions about "modern" technologies (REST, Prisma) are dangerous in existing projects where historical decisions are conditioned by external requirements (SOAP per partner requirement).
Dual migration systems, undocumented crons, and other "technical secrets" surface only during systematic fact gathering, not superficial code study.
Constraint "do not add new framework" in tech-stack.md protects against technological bloat and preserves team cognitive load.
Sometimes you must accept a 3-day pause for constitution recovery — this is investment, not loss.
Related concepts: Constitution recovery
Facts vs. assumptions vs. unknown
SDD risks in existing project
Existing code conventions
Recovery process
Study tips: Practice on a real project: take your old pet project or work project, delete/rename specs/, and go through full recovery cycle. Theory without practice on real code doesn't stick.
Keep an "archaeologist's diary" during fact gathering: record what you thought before analysis and what you discovered. This develops metacognitive skill of recognizing your own assumptions.
Use "teaching" technique: explain recovered constitution to a colleague or record video. If you don't understand why "Unknown" section in tech-stack.md is important — you haven't mastered the material.
For visual learners: create a diagram of process "Existing project → Recovery → Continuation" and hang it near your workspace. Mark which stage you are currently at.
For auditory learners: dictate Qwen Code prompts aloud before sending. This helps reveal vague formulations and extra assumptions.
For kinesthetic learners: physically highlight three zones in constitution with different colors (green — facts, yellow — assumptions, red — unknown). Color coding accelerates pattern recognition.
Practice formulating "bad" questions and turning them into "good" ones. Bad: "Why is this written so poorly?" Good: "What intention stood behind this decision, and does it still hold?"
Create a checklist for constitution readiness before first feature specification: README checked for relevance, tests checked for "bug locking," architectural conflicts explicitly marked as "not to resolve in feature."
Use "red team" technique: ask a colleague to find assumptions in your constitution, presenting them as facts. This simulates the danger of "invented architecture."
Conduct regular "constitution audits": once a quarter restart fact gathering and compare with current constitution. Projects live, constitution must live too.
Additional resources: Original course document (part 13): Main material the guide is built on. Re-read after each practical exercise — understanding will deepen.
Book "Working Effectively with Legacy Code" by Michael Feathers: Classic on working with legacy code. Complements SDD with technical techniques for safe code change (seams, characterization tests).
Article "Archaeology of Code: Reading the Layers" by Marina Zakharova: Methodology of reading code as archaeological layers — useful for developing skill of separating facts from assumptions.
Qwen Code documentation on contextual prompts: Official examples of working with @-references to files and code tree. Critical for accurate fact gathering.
Project constitution templates (mission.md, tech-stack.md, roadmap.md): Create your own templates based on course examples. Standardization accelerates recovery on new projects.
Interactive simulator: AgentClinic MVP without specs/: Training scenario from course. Practice in safe environment before applying to work project.
Checklist "SDD risks in existing project": Self-created document based on "Special risks" section. Use before each feature specification.
Summary: Supporting an existing project through SDD is code archaeology, not rewriting. Key principles: separate facts from assumptions and unknowns; restore constitution through structured interview with AI assistant; transform chaotic TODOs into phased roadmap; apply standard SDD cycle for new features with respect for existing conventions; explicitly mark and defer architectural conflicts instead of "cleaning up along the way." Main risks — outdated documentation, accidental code as rule, tests that lock in bugs, and temptation to refactor without specification. Antidote — discipline of separating "observed," "resolved," and "unknown" in every constitution document. Having mastered this part, you will be able to apply SDD to any project, regardless of its age and documentation state, turning chaos into managed evolution.