Case Study: Architecture Recovery
Background
ClaimForge — insurance claims processing. Core: Java 11, Spring Boot 2.x, Oracle 19c, ~380k LOC across seven Maven modules, oldest packages dating to 2014. Original architects gone. Current team of eight shipping features by superstition: "don't touch LegacyAdjudicator," "batch jobs must run in this order or Oracle deadlocks." Leadership asked for an architecture refresh proposal. The team could not describe the as-is system well enough to propose a to-be.
Engagement: three weeks of architecture recovery — document what exists with evidence, produce ADRs for load-bearing decisions, identify seams for future extraction. Claude Code as archaeologist, not as rewriter.
Initial vague prompt
Analyze this Java/Spring/Oracle codebase and write an architecture
document explaining how claims processing works, the main components,
data model, and recommendations for modernization.The agent produced a beautiful 12-page Architecture.md: hexagonal diagrams, a "ClaimsDomainService" that did not exist under that name, a description of CQRS "patterns" inferred from one read-only view, and modernization recommendations that started with "migrate to microservices and PostgreSQL." Three cited class names were wrong; four were plausible inventions.
Why it failed
Architecture fiction is worse than ignorance — teams start making decisions against a map of a different city.
| Claim in Architecture.md | Evidence check |
|---|---|
| "Event-driven adjudication via Kafka" | Kafka client on classpath; zero producers in src/; leftover dependency |
| "Oracle used only as system of record" | PL/SQL packages mutate claims; Java sometimes reads stale state |
| "Stateless API tier" | HttpSession holds partial claim drafts |
| "Batch module is isolated" | Shares mutable static caches with API module |
The vague prompt rewarded a coherent narrative. Coherence is the enemy of archaeology. You want citations, including "unknown," not a smooth story.
The improved spec
specs/arch-recovery.md abridged:
## Architecture recovery rules
### Output format
- Every claim must cite path:line or SQL object name
- If evidence is weak, label Confidence: high|medium|low|unknown
- Forbidden: recommendations in phase 1
- Forbidden: inventing component names — use real class names
### Phase 1 deliverables
1. Module map: Maven modules → responsibilities (cited)
2. Runtime flows: submit claim, adjudicate, pay — sequence diagrams with real types
3. Data ownership: which tables are written by Java vs PL/SQL
4. Decision candidates: list of "this looks intentional" for ADR drafting
### Phase 2
- ADRs for top 10 load-bearing decisions, each with Evidence section
- Seams document: extractable boundaries with test gaps noted
### Method
- Prefer ripgrep + reading over "summarize the architecture"
- Run the app locally; trace one claim ID through logs and DBPrompt pattern:
Trace claim submission from ClaimController to DB write. List every class
and PL/SQL call with file:line. Do not summarize until the trace table is
complete. If you cannot find a link, write UNKNOWN — do not guess.Agent workflow
They used Claude Code plan mode for inventory, then separate sessions per flow trace. A session that started writing recommendations early was stopped; phase gates were enforced by humans, not vibes.
Evidence table format they required (and pasted into every ADR):
| Claim | Path:line or object | Confidence | Notes |
|---|---|---|---|
| Payment amount computed in Java | PaymentCalculator.java:144 | high | |
| Payment amount sometimes adjusted in DB | PKG_PAY.ADJUST | high | called from batch only |
| Kafka used for adjudication | — | unknown | dep present, no producers found |Anything still unknown after two sessions became a human spike with a debugger — not another "summarize" prompt. That rule alone prevented a second fiction document.
Human intervention points
- Reject narrative docs without citations — default disposition for agent architecture prose. "Looks right" is not a merge criterion.
- Runtime validation — humans submitted a test claim and compared the agent's sequence diagram to logs/DB. Two diagram arrows were wrong; fixed before ADRs.
- DBA partnership — PL/SQL ownership map required a DBA; the agent could list packages, not explain tribal runtime order ("never run ADJ after PAY on the same day").
- ADR acceptance — staff engineer signed each ADR; agent drafts, human owns. Unsigned drafts stayed in
/drafts. - Modernization deferred — explicitly after as-is ADRs, so recommendations couldn't rewrite history.
Mistakes made
- Trusting classpath evidence. Kafka on the classpath became "event-driven architecture." Cost: a wrong steering-committee slide that had to be retracted publicly.
- One-shot "write the architecture doc." Even with better prompts, a single session drifts to story mode as context fills. Cost: half a day of citation cleanup.
- Letting the agent name things.
ClaimsDomainServiceentered Slack vocabulary for a week; onboarding engineers grepped for it and found nothing. Ban inventing names in the recovery spec. - Skipping PL/SQL. First draft treated Oracle as dumb storage. Two "impossible" Java bugs were triggers. Added a dedicated PL/SQL archaeology session — should have been day one.
- Over-trusting sequence diagrams. Mermaid from the agent looked authoritative. They now require the evidence table above the diagram in every flow doc; diagram without table is incomplete.
Final outcome
Deliverables: 9 ADRs with evidence, 3 flow traces, a data-ownership matrix, a seams list with 5 candidates. Modernization proposal (phase 3) recommended extracting payment calculation first — not a full microservice split — because the ADRs showed PL/SQL + Java co-ownership made a big-bang cut suicidal. Three weeks well spent; the earlier 12-page fiction would have burned a quarter.
Agent strength: tireless ripgrep, drafting ADR skeletons, listing call graphs. Agent weakness: filling gaps with architectural tropes. Net: archaeology is one of the highest-ROI agent uses if you constrain the output format to citations.
Onboarding time for a new engineer reading the recovery pack: ~2 days to productive fear (knowing what not to touch) vs ~3 weeks of folklore before.
Lessons
- Make agents cite file:line (or SQL object) for every architectural claim; reject coherent docs that don't.
- Separate recovery from recommendations — same session will smuggle tropes ("CQRS," "Kafka," "microservices") into as-is descriptions.
- Classpath and dependencies are not runtime evidence; prove producers/consumers exist.
- Include the database procedural layer in archaeology for Oracle/Spring systems; Java-only maps lie.
- Ban invented component names during recovery — use only identifiers that grep finds.
- Put evidence tables above diagrams; pretty Mermaid without citations is how fiction spreads.
Related
- Decision Records — ADR shape with evidence
- Architecture and Research Prompts — trace-and-cite prompts
- Exploring Options — only after as-is is pinned
- Hallucination and False Confidence — coherent false maps
- Playbook: Recovery — when docs and reality diverge