Skip to content

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

text
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.mdEvidence 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:

markdown
## 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 DB

Prompt pattern:

text
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):

markdown
| 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

  1. Reject narrative docs without citations — default disposition for agent architecture prose. "Looks right" is not a merge criterion.
  2. 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.
  3. 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").
  4. ADR acceptance — staff engineer signed each ADR; agent drafts, human owns. Unsigned drafts stayed in /drafts.
  5. 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. ClaimsDomainService entered 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

  1. Make agents cite file:line (or SQL object) for every architectural claim; reject coherent docs that don't.
  2. Separate recovery from recommendations — same session will smuggle tropes ("CQRS," "Kafka," "microservices") into as-is descriptions.
  3. Classpath and dependencies are not runtime evidence; prove producers/consumers exist.
  4. Include the database procedural layer in archaeology for Oracle/Spring systems; Java-only maps lie.
  5. Ban invented component names during recovery — use only identifiers that grep finds.
  6. Put evidence tables above diagrams; pretty Mermaid without citations is how fiction spreads.

A field manual for AI-native software engineering.