Specify an inherited codebase's business rules
Two independently-authored extractors emitting the same Given/When/Then shape, so disagreement between them is signal rather than noise.
Also usesclaude-plugins-official
Specifying an inherited codebase's rules only works if the second extractor runs after the first, not instead of it — the cross-check needs an independent read to disagree with, not a second pass over the same output. Characterization tests then pin down what both extractors agree the code does, before any transformation gets a chance to invalidate the read.
Start here
Extract this inherited codebase's real business rules -- read it structurally and behaviorally first, map its real module boundaries rather than trusting directory names, mine the rules from the executable code as Given/When/Then specs, then run a second independent extractor afterward as a genuine cross-check, and pin the agreed behavior down with characterization tests before any rewrite starts.Needscode-modernization, self-assess
Beats
Run these in order. Each prompt is copy-pasteable straight into Claude Code.
code-modernization:legacy-analystStructural and behavioral read plus dead-code detection, before anyone asserts what the system actually does.
Run this beat on its own
promptread this inherited codebase and build a structural and behavioral map before we assert anything about what it doesself-assess:self-assess-stage-mapClusters by shallowest package boundary, never by manifest directory — the correction a directory-shaped read of an inherited repo needs first.
self-assess:self-assess-extract-rulesMines rules from executable code, never comments; loops to convergence; requires a two-judge panel for any P0-rated rule.
Run this beat on its own
promptextract this codebase's real business rules as Given/When/Then specs, from the executable code, not from comments or docscode-modernization:business-rules-extractorAn independent second extractor with the same output shape — what the business requires, not how the old code happened to implement it. Run after the first extractor so it's a cross-check, not an anchor.
code-modernization:test-engineerCharacterization tests pin the behavior down before any transformation starts; useless once the rewrite has already begun.
Worked example
Grounded in — why this beat order is trustworthy
This is the exact scope overlap docs/orchestration/references/routing.md governs: this recipe dispatches code-modernization leaves directly and must not be run alongside a signed /modernize-* brief, which owns the same territory as a whole pipeline.
Do / Don't
- Build a structural and behavioral map of the inherited code before asserting anything about what it does.
- Cluster the real module boundaries by shallowest package boundary, not by manifest directory, before mining rules.
- Mine rules from the executable code itself, never from comments or docs.
- Run the second extractor after the first, specifically so it can disagree with it, not repeat it.
- Pin the agreed behavior down with characterization tests before any transformation starts -- they're useless once the rewrite has already begun.
- Don't assert what an inherited system does before reading it structurally and behaviorally.
- Don't run both extractors expecting them to reconcile automatically -- the value is in an independent second read that can disagree.
- Don't run this recipe alongside a signed /modernize-* brief -- it dispatches code-modernization leaves directly and the two own the same territory.
- Don't wait until after the rewrite starts to write characterization tests -- by then they're useless.