Extracts structured requirements from existing source code via iterative subagent review for re-implementation, tech migration, or undocumented codebases.
How this skill is triggered — by the user, by Claude, or both
Slash command
/powerups-requirements:reverse-engineering-requirementsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Extract what an existing system *actually does* — and what it *should* do in a
Extract what an existing system actually does — and what it should do in a reimplementation — by reading source code, iteratively reviewing with fresh-eyes subagents, and separating genuine requirements from implementation accidents.
This is harder than greenfield elicitation because the code contains everything: requirements, design decisions, style choices, workarounds, dead code, and accidental complexity from previous technology constraints. Your job is to separate signal from noise.
You do: Orchestrate the process. Dispatch subagents. Facilitate discussion between the human and the review findings. Draft and refine the requirements doc. Identify non-goals.
The human does: Provide context about the system's purpose and users. Confirm or reject your interpretations. Identify which behaviours are intentional vs accidental. Make priority calls.
Subagents do: Read source code with fresh eyes. Compare spec against code. Find omissions, inaccuracies, and things that don't belong. They bring no prior assumptions — that's their value.
You never: Assume every behaviour in the code is a requirement. Treat implementation details as requirements. Skip the human's judgment on what matters.
The same filtering from gathering-requirements applies, but with an extra category that dominates in reverse-engineering work:
Requirement = behaviour observable from outside. "Display client name in task list." Decision = how the system achieves it. "Store config at ~/.cu/config.json." Style = formatting/presentation. "Truncate names at 45 characters." Non-Goal = something present in the old system that we explicitly don't want. "Font size adjustment buttons (unnecessary on web — the old WinForms app couldn't resize or rescale)."
The litmus test for non-goals: "Is this behaviour in the old code because of a genuine user need, or because of a constraint that no longer exists?" If the constraint is gone, the behaviour is a non-goal candidate. Confirm with the human.
The most common form of spec-leaking-into-requirements when reverse-engineering GUI applications. UI elements look user-observable (the user literally sees them!) so they pass a naive litmus test. But they're answers to unstated questions:
| What the code has | What it looks like | What the requirement actually is |
|---|---|---|
| Three side-by-side panels | "Display data in three panels" | Operator needs to see unbilled time, invoices, and line detail simultaneously to cross-reference them |
| Checkbox selection on rows | "Users select items via checkboxes" | Operator needs hierarchical multi-select (pick a ticket, get all its entries) |
| Right-click context menu | "Context menu with actions X, Y, Z" | Certain actions are available per-entity (per invoice, per ticket) |
| Color-coded rows | "Display rows in PeachPuff/LightGreen/..." | Operator needs to visually triage hundreds of rows at scanning speed |
| Save button on a form | "Batch save with Save button" | Some edits need atomic consistency (description + type together) |
The fix: Write capability requirements ("the operator shall be able to..."). The underlying need survives the platform change. The specific UI affordance doesn't belong in the requirements doc — it anchors the new design toward the old one, which is exactly what you're trying to avoid.
The one exception: when the UI pattern IS the requirement. High-density data work with simultaneous cross-referencing across multiple datasets is a genuine constraint — you can't solve it with a wizard or sequential screens. But "three fixed panels in a row" is still just one solution to that constraint.
Subagents will over-describe UI. Every review iteration, check: "Is this describing what the user needs to accomplish, or how the old app looked?" Rewrite the latter as the former.
Get the human to describe what the system does in their own words. Don't read the code yet. You need their mental model first because:
Ask:
The answer to #3 seeds your Non-Goals section.
Dispatch a subagent to read the source code and produce a first-draft requirements.md. The subagent should:
Subagent prompt pattern:
Read
skills/requirements-management/SKILL.mdto understand our requirements philosophy — especially the Requirements vs Spec vs Style section, the litmus test, and the Scenarios section. Then read [source files]. Produce arequirements.mdfollowingassets/requirements-template.md. For each behaviour you find, apply the litmus test: "If I changed this, would the user notice a different capability?" Record requirements, decisions, and style separately. Things you're unsure about go in Open Questions. For eachmust-priority FR, extract at least one concrete scenario from the code — a specific input/output example that illustrates the business rule. Use Given/When/Then or examples tables as appropriate. Derive scenarios from test cases, sample data, or representative code paths. Scenarios must describe business behaviour, not implementation steps.
Present the draft to the human. Expect significant corrections — the first pass always over-includes implementation details as requirements.
This is the core of the process. Each iteration has three steps:
Dispatch a new subagent (fresh context, no prior assumptions) to review the current requirements.md against the source code. The subagent looks for:
Subagent prompt pattern:
Read
skills/requirements-management/SKILL.mdfor our requirements philosophy (including the Scenarios section). Then readrequirements.md(our current spec) and [source files]. With completely fresh eyes, identify:
- Behaviours in the code not captured in requirements (omissions)
- Requirements that contradict what the code does (inaccuracies)
- Items in requirements that fail the litmus test — they're decisions, style, or non-goals, not requirements (misclassifications)
- UI descriptions posing as requirements — "three panels", "Save button", "context menu" describe the old UI, not the user need. Rewrite as capabilities.
- Code patterns that look like requirements but are probably platform workarounds or accumulated cruft (non-goal candidates)
must-priority FRs missing concrete scenarios, or scenarios that are scripts (UI flow descriptions) rather than specifications (business rules)- Scenarios that don't match the code's actual behaviour — the scenario says X but the code does Y Report findings grouped by category. Be specific — cite code locations.
Review the subagent's findings with the human. For each finding:
If a finding needs deeper investigation, dispatch a subagent to research it rather than guessing.
Delegate the agreed changes to the requirements-editor subagent. It handles the mechanics: ID sequencing, cross-references, validation.
You're done when a fresh-eyes review comes back with only minor findings — nothing structural, no missing capabilities, no misclassified items. Two to three iterations is typical.
If the old system connects to external systems (databases, APIs, file shares), document the topology in systems.md. The source code is your best source here — connection strings, API endpoints, credential paths. But confirm with the human because the new system may connect differently.
Present the complete requirements.md, systems.md, and non-goals to the human.
Check:
must-priority FR has at least one scenario with concrete datamust-priority workEach review subagent must start with a clean context. If you reuse a subagent that already read the requirements, it develops the same blind spots you have. The value is in the fresh perspective — a reader who sees the spec and code for the first time and notices what you've stopped noticing.
Every review subagent needs:
Don't transcribe the code. The biggest risk is turning every function into a requirement. The code has hundreds of behaviours — most are implementation mechanics, not user-facing capabilities.
Don't skip the human. The subagent will flag things it thinks are non-goals, but only the human knows whether "font size buttons" were a beloved feature or a workaround. Always confirm.
Don't reuse review subagents. Each review needs fresh eyes. A subagent that reviewed iteration 1 has already formed opinions that compromise iteration 2.
Don't rush to three iterations. If iteration 2 still finds major omissions, do iteration 3 and maybe 4. The number isn't magic — convergence is.
Don't confuse "the code does X" with "the system needs X." The code might handle a scenario that never actually occurs, or handle it in a way that was a bug nobody noticed. The human's workflow is the ground truth for what matters.
Don't describe the old UI as requirements. "Three panels", "Save button", "right-click context menu" are how the old app looked, not what the user needs. Ask: what need does this UI element serve? Write that need as the requirement.
The requirements.md should be ready for the requirements-management skill to maintain during development, and for a coding agent to build the new system from.
npx claudepluginhub njt/powerups-requirements --plugin powerups-requirementsReverse-engineers legacy or undocumented codebases: scopes boundaries, explores with Glob/Grep/Read/Bash, traces data flows, documents in EARS format, flags uncertainties. For archaeology, onboarding, requirements extraction.
Reverse-engineers specifications from legacy, undocumented, or inherited codebases. Maps dependencies, generates API docs, identifies business logic, and produces architecture documentation.
Reverse-engineers codebases into clean specifications capturing what a system does and why, excluding how. Distills domain logic, behaviors, and implicit state machines from source files.