Legacy discovery
Making Legacy Projects Safer for Vibe Coding. AI适老化改造,让老项目更适合 Vibe Coding。
npx -y skills add ForeverSc/ai-handrail --skill legacy-discoveryAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when starting work on an unfamiliar legacy project, inherited codebase, or large old system. Triggers when user says "understand this project", "what does this codebase do", "analyze this legacy system", "map this project", or wants to explore an existing codebase before making changes.
SKILL.md
9.9 KB, as published. Nobody here has run it
Legacy Discovery
Understand a legacy project without touching any code. Produce a structured analysis that subsequent skills can consume.
Goal
Build a mental model of the project: what it does, how it's structured, what's critical, what's risky, and what's unknown — all without modifying a single file.
When to Use
- First contact with a legacy codebase
- Onboarding to an inherited project
- Before planning any modernization work
- When the user says "help me understand this project"
Mandatory Workflow
Step 1: Establish Boundaries
Before reading any code, determine scope with the user:
- Ask: which domain / feature / subsystem should we focus on?
- If user says "the whole thing" — push back. Negotiate one starting area.
- Confirm: we will analyze [specific area] this round. Everything else is out of scope.
Step 2: Identify Project Type
Before deep reconnaissance, determine the project's technical profile:
- Scan project metadata files (
package.json,go.mod,pom.xml,pyproject.toml, etc.) - Match against detection signals defined in
profiles/:
| Signal | Profile |
|---|---|
package.json with react/vue/angular/svelte | profiles/frontend.md |
package.json with express/koa/fastify/nestjs | profiles/backend-node.md |
pom.xml or build.gradle with Spring/Quarkus/Micronaut | profiles/backend-java.md |
requirements.txt/pyproject.toml with django/flask/fastapi | profiles/backend-python.md |
go.mod with web framework or net/http usage | profiles/backend-go.md |
| Both frontend AND backend signals present | profiles/fullstack.md |
- Load the matched profile. The profile provides additional reconnaissance items, critical path patterns, risk factors, structural analysis tools, and stack-specific risk labels.
- If no profile matches (CLI tool, data pipeline, library, etc.), proceed with base workflow only.
- Record the detected project type in outputs:
Project Type: [frontend | backend-node | backend-java | backend-python | backend-go | fullstack | unclassified]
Step 3: Reconnaissance (read-only)
Gather facts. Do NOT interpret yet.
Base reconnaissance (all project types):
- Project metadata:
package.json,Makefile,Dockerfile, CI configs, build scripts - Dependency snapshot: Read lockfile. Record actual versions of key dependencies (framework, router, state management, test runner, bundler).
- Entry points:
main,index,app, route definitions, CLI entry - Directory structure: Top-level layout, naming conventions, module organization
- Configuration: Environment files, feature flags, config objects
Profile-specific reconnaissance: If a profile was loaded in Step 2, also complete the profile's reconnaissance checklist. The profile checklist extends (not replaces) the base items above.
Step 4: Identify Critical Paths (80/20)
Find the P0 flows — the paths that, if broken, cause revenue loss or user-facing failures:
- Trace 1-3 core user journeys through the code
- Mark every file/module touched by these journeys
- Identify shared utilities and data stores these paths depend on
- Note external integrations (APIs, databases, message queues)
If a profile is loaded, consult its Critical Path Patterns section for stack-specific guidance on where P0 flows typically live.
Step 5: Risk Assessment
For each area in scope, evaluate:
- Complexity: cyclomatic complexity, deep nesting, god files/classes
- Test coverage: existing tests? what kind? what's missing?
- Documentation: inline comments, READMEs, ADRs, wiki links
- Coupling: how tangled is this with other modules?
- Staleness: dead code, deprecated APIs, TODO/FIXME/HACK comments
- Non-standard behavior: direct state mutation, hidden global writes, order-dependent behavior, or legacy side effects that defeat normal intuition
Assign risk labels: P0-CRITICAL, HIGH-RISK, LEGACY-SEALED, SAFE-TO-EXTRACT, DOC-MISSING, TEST-MISSING, HUMAN-REVIEW, DEAD-CODE, CIRCULAR-DEP, HOTSPOT.
If a profile is loaded, also evaluate the profile's Risk Assessment Focus table and assign any profile-specific risk labels where applicable.
Step 6: Structural Analysis
Run targeted analyses to reveal hidden risks. See docs/methodology.md → Advanced Techniques for full details. If a profile is loaded, prefer the tools listed in its Structural Analysis Tools table.
Dependency graph analysis:
- Use project-appropriate tools (madge, dependency-cruiser, etc.) to generate import graphs
- Identify circular dependencies → tag
CIRCULAR-DEP - Identify god modules (high fan-in) — dangerous to change, many callers affected
- Identify orphan modules (zero imports) — potential dead code
Hotspot analysis (knowledge archaeology):
git log --format=format: --name-only | sort | uniq -c | sort -rn— find high-churn filesgit log --followon critical files to trace decision historygit blameon business-critical sections to find when/why rules were introduced- High churn + high complexity =
HOTSPOTlabel
Dead code detection:
- Use static analysis tools appropriate to the stack (ts-prune, knip, vulture, deadcode, etc.)
- Mark unused exports, unreachable branches, never-called functions →
DEAD-CODE - Do NOT delete — only mark. Dead code removal is a refactor task.
Seam identification:
- Find points where behavior can be altered without editing surrounding code
- Examples: function boundaries, DI injection points, interface implementations, middleware hooks, config switches
- Mark seams in module map:
SEAM: [description] - These are where future adapters/wrappers will attach
Complex-logic capture:
- For state-heavy, branch-heavy, or multi-module flows, produce a flowchart in addition to prose notes
- Prefer
mermaidwhen the target docs can render it - Use the flowchart to show surprising branches, retries, fallbacks, and side effects
Dependency verification:
- For high-impact outdated packages, you must record the pinned version, project-local usages, and package source inspection
- If the API cannot be confirmed from code or matching-version docs, mark it
UNVERIFIED
Step 7: Map Unknowns
Explicitly list:
- Business rules that are unclear from code alone
- Implicit behaviors that might be relied upon downstream
- Magic numbers, unexplained conditions, commented-out code blocks
- Areas where you'd need human confirmation before proceeding
Step 8: Produce Outputs
Generate the required outputs (see below). Write to docs/legacy-modernization/. Discovery produces analysis documents only — it does NOT modify project source code.
Required Outputs
Each discovery round MUST produce:
| Output | Description |
|---|---|
| Project type | Detected profile (frontend, backend-node, backend-java, backend-python, backend-go, fullstack, or unclassified) |
| Scope statement | What was analyzed, what was excluded |
| Project objective | What this project/domain does (in business terms) |
| Critical path map | P0 user journeys with file/module trace |
| Dependency snapshot | Key deps with actual versions from lockfile |
| Complex flowchart set | Flowchart output for complex logic in scope |
| Risk inventory | Per-module risk labels with justification |
| Structural analysis | Dependency graph, circular deps, hotspots, dead code, seams |
| Unknown registry | Explicit list of things not yet understood |
| Human decision points | Questions that require human answers |
| Next-round recommendation | What to analyze next and why |
Use templates from templates/project-overview.md and templates/domain-overview.md.
Hard Rules
- Read-only. Do not create, modify, or delete any project files. Only create documentation files.
- One area per round. Never attempt to understand the entire project at once.
- No assumptions. If you can't verify something from code, mark it
UNKNOWN. - Lockfile over docs. Real dependency versions come from lockfiles, not READMEs or external sites.
- Existing code over examples. When understanding how a library is used, look at the project's own usage first.
- Complex logic needs a flowchart. If prose alone would hide branching or state, add a flowchart.
- Hidden traps must be surfaced. Non-standard legacy behavior should be documented as an explicit risk, not buried in narrative text.
- High-impact old dependencies require source inspection. Do not rely on generic memory when the pinned API may differ.
- Surface unknowns. It's acceptable to not know something. It's unacceptable to hide that you don't know.
- Ask before assuming business intent. When code logic implies a business rule, flag it as
HUMAN-REVIEWrather than interpreting it.
Anti-Patterns
| Don't | Do instead |
|---|---|
| Scan every file in a large project | Pick one domain, trace one critical path |
| Assume latest API docs apply | Read the lockfile, check project's actual usage |
| Skip dependency version identification | Always record framework/library versions from lockfile |
| Guess at business rules | Mark them UNKNOWN + HUMAN-REVIEW |
| Produce a single massive analysis doc | Produce focused outputs per the template structure |
| Claim "analysis complete" after one round | State what was covered AND what wasn't |
Round Completion
Before ending a round, answer:
- Analyzed: [specific area/path]
- Confirmed: [list of confirmed facts]
- Unknown: [list of unresolved items]
- Next: [recommended next area + rationale]