Codebase audit
Skill Siddharth00/agent-revamp-skills/skills/01-audit/codebase-audit
Production-grade migration skills for AI coding agents. Revamp any product, module, or feature from one stack to another.
npx -y skills add Siddharth00/agent-revamp-skills --skill codebase-auditAssembled 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
Produces AUDIT.md committed to the repo root — a structured seven-section report covering dependencies, dead code, coupling, coverage, performance baselines, CVEs, and implicit contracts — the mandatory input for all Phase 2 strategy decisions.
SKILL.md
39.4 KB, as published. Nobody here has run it
1. Purpose
This skill produces AUDIT.md — a single structured document committed to the repo root
that captures the ground truth of a codebase before any migration decision is made. It is
the mandatory first step on every revamp project: Phase 2 (Strategize) cannot begin without
it, because a migration plan built on assumed knowledge is a migration plan built on fiction.
The audit covers seven domains in a fixed order — dependency health, dead code surface, module
coupling, test coverage state, performance baselines, known CVEs, and implicit contracts —
and concludes with a risk register and a stakeholder sign-off block. The sign-off block is
not ceremonial: it is the formal gate between audit and strategy, and it records who reviewed
the findings and when. AUDIT.md is a human-readable document intended to be read and
debated by engineers and stakeholders, not a CI artifact or a tool output — every section
must be written in plain English with tool output as supporting evidence, not as the primary
content.
2. Trigger Conditions
Use when:
- A decision has been made to migrate or significantly revamp a codebase and no
AUDIT.mdexists atrepo_root. AUDIT.mdexists but is more than 90 days old — dependencies, CVEs, and coverage decay; a stale audit is worse than none because it creates false confidence.- The team disagrees about the scope, risk, or sequence of a migration — the audit produces objective data (coupling counts, CVE counts, dead code estimates) to resolve the disagreement.
- A Phase 2 strategy is being planned and the planner cannot name the top five highest-fan-in files in the codebase — that is a signal the audit has not been done.
Do NOT use when:
AUDIT.mdexists atrepo_root, is less than 90 days old, and covers the sametarget_modulescope — review and update individual sections rather than regenerating from scratch.- The scope is a single small utility (<500 LOC, no external consumers) — the audit overhead exceeds its value. Run the specific section tools (e.g., just
depcheck) instead. - A partial audit already exists for one section — update that section in place rather than re-running the full skill. Each section is independently updatable.
- Phase 2 has already begun and architectural decisions have been committed — the audit is a prerequisite for Phase 2, not a companion to it. Running it mid-strategy produces findings that cannot be cleanly acted on without restarting the strategy process.
3. Inputs
Required:
| Input | Type | Description |
|---|---|---|
repo_root | file-path | Absolute path to the repository root. All commands run from here. |
language | enum(javascript, typescript, python, ruby, go, java, other) | Primary language of the codebase. Determines which tools are invoked for each audit section. For polyglot repos, use the dominant language and note secondary languages in the audit. |
stakeholders | string | Comma-separated names or handles of reviewers who must sign off before Phase 2 begins. Example: "@alice, @bob, Engineering Lead". These names populate the Sign-off table in AUDIT.md. |
Optional:
| Input | Type | Default | Description |
|---|---|---|---|
package_manager | enum(npm, yarn, pnpm, pip, pipenv, poetry, bundler, go-modules, maven, gradle, other) | auto-detect | Determines dependency and CVE scan commands. Auto-detected from lockfile presence: package-lock.json → npm, yarn.lock → yarn, pnpm-lock.yaml → pnpm, Pipfile.lock → pipenv, poetry.lock → poetry. |
entry_points | string | auto-detect | Comma-separated list of entry point files relative to repo_root (e.g., src/index.ts,src/worker.ts). Used to scope dead-code and bundle analyses. Auto-detected from package.json main/exports or framework conventions. |
audit_depth | enum(shallow, deep) | shallow | shallow: tool-based analysis only — fast, suitable for large codebases. deep: adds agent-assisted manual code reading for implicit contracts, untraceable coupling, and undocumented behaviors. Always use deep for systems >3 years old or with no documentation. |
bundle_tool | enum(webpack-bundle-analyzer, source-map-explorer, vite-bundle-visualizer, rollup-plugin-visualizer, none) | none | Bundle analysis tool already configured in the project. none skips bundle size reporting and notes the gap in Section 5. |
trivy_enabled | boolean | false | Whether trivy (container/filesystem CVE scanner) is available and should be run in addition to language-native CVE tools. Adds OS-level and container vulnerability data to Section 6. |
4. Steps
-
Detect
languageandpackage_managerif not provided. Run the following detection sequence fromrepo_root:# Language detection (in priority order) ls package.json tsconfig.json # → typescript ls package.json # → javascript ls setup.py pyproject.toml Pipfile # → python ls Gemfile # → ruby ls go.mod # → go ls pom.xml build.gradle # → javaRecord
detected_languageanddetected_package_managerin the migration log. If detection is ambiguous (multiple indicators), ask the user before proceeding. -
Write the
AUDIT.mdskeleton to<repo_root>/AUDIT.mdusing the template below. Every section is pre-populated with its heading, subsection structure, and<!-- TODO -->placeholders. Steps 3–10 replace each placeholder with real content. Do not fill in any section speculatively — only recorded tool output and verified findings.# AUDIT — <project-name> > Generated by `skills/01-audit/codebase-audit` · agent-revamp-skills > **Do not edit the section headings or subsection structure** — downstream skills > reference this document by heading name. | Field | Value | |-------|-------| | **Audited by** | <!-- agent: Claude Code + reviewer: <stakeholders> --> | | **Audit date** | <!-- ISO 8601 date of this run --> | | **Repo root** | <!-- absolute path --> | | **Language** | <!-- primary language detected in Step 1 --> | | **Audit depth** | <!-- shallow \| deep --> | | **Skill version** | `skills/01-audit/codebase-audit` · v0.1.0 | --- ## 1. Dependency Inventory > **Purpose:** Know what you depend on before you move it. > A dependency you didn't know existed cannot be migrated safely. ### 1.1 Direct Dependencies <!-- Populate from package.json / requirements.txt / go.mod / Gemfile. One row per direct dependency. Flag any with: (a) no updates in >12 months, (b) a known EOL date within 18 months, (c) a single maintainer. --> | Package | Pinned Version | Latest Stable | EOL Date | Type | Flag | |---------|---------------|---------------|----------|------|------| | <!-- name --> | <!-- version --> | <!-- latest --> | <!-- date or N/A --> | prod \| dev \| peer | <!-- EOL \| abandoned \| single-maintainer \| ok --> | **Total direct dependencies:** <!-- N prod, N dev --> ### 1.2 Notable Transitive Dependencies <!-- Do not list all transitives — only those that are: high fan-in (depended on by many direct deps), EOL, or carrying CVEs flagged in Section 6. Source: `npm ls --all --json | jq` or `pip show <pkg>` for the relevant packages. --> | Package | Pulled in by | Version in Use | Latest | Risk | |---------|-------------|----------------|--------|------| | <!-- name --> | <!-- direct dep name(s) --> | <!-- version --> | <!-- latest --> | <!-- EOL \| CVE \| pinned-old \| ok --> | ### 1.3 EOL & Maintenance Summary <!-- Packages EOL now or within 18 months from audit date. --> | Package | EOL Date | Days Until EOL | Replacement | |---------|----------|----------------|-------------| | <!-- name --> | <!-- date --> | <!-- N --> | <!-- known replacement or "unknown" --> | **Dependency health verdict:** <!-- Green (all current) \| Yellow (some outdated, no EOL) \| Red (EOL or abandoned packages in prod) --> --- ## 2. Dead Code Surface > **Purpose:** Don't migrate code that can be deleted. > Dead code in the source is dead code in the target — migrate it and you double the work. ### 2.1 Unused Exports <!-- Source: ts-prune (TS), knip (JS/TS), vulture (Python), unused (Go). List files with unused exports, not individual symbols — the Phase 4 skill will decide which symbols to delete vs. migrate. --> | File | Unused Export Count | Tool Used | Confidence | |------|--------------------|-----------| -----------| | <!-- path --> | <!-- N --> | <!-- tool --> | High \| Medium \| Low | **Total unused export candidates:** <!-- N symbols across N files --> ### 2.2 Unused Dependencies <!-- Source: depcheck (JS/TS), pip-extra-reqs (Python), go mod tidy (Go). List packages that appear in the manifest but are not imported anywhere. --> | Package | Listed in | Imported Anywhere | Safe to Remove | |---------|-----------|-------------------|----------------| | <!-- name --> | <!-- package.json / requirements.txt --> | No | <!-- Yes \| Verify first --> | ### 2.3 Dead Code Estimate **Estimated removable lines:** <!-- N LOC (roughly N% of total source) --> **Recommended action before migration:** <!-- Remove confirmed dead code in a dedicated PR before Phase 4 begins. Migrating dead code wastes effort and preserves bugs. --> --- ## 3. Coupling Map > **Purpose:** Know which files will hurt the most if you touch them. > High fan-in files are migration multipliers — one change breaks many things. > High fan-out files are migration risk accumulators — they depend on many things that may change. ### 3.1 Fan-out Hot Spots (imports the most modules) <!-- Files that import from the highest number of other internal modules. High fan-out = highly dependent; changing any of its dependencies affects this file. Source: code-archaeologist coupling report. --> | File | Fan-out Count | Top 5 Imports | Migration Risk | |------|--------------|---------------|----------------| | <!-- path --> | <!-- N --> | <!-- a, b, c, d, e --> | High \| Medium \| Low | ### 3.2 Fan-in Hot Spots (most imported by others) <!-- Files that are imported by the highest number of other internal modules. High fan-in = high blast radius; changes here break many consumers. Migrate these LAST or extract a stable interface first. --> | File | Fan-in Count | Imported By (sample) | Migration Risk | |------|-------------|----------------------|----------------| | <!-- path --> | <!-- N --> | <!-- a, b, c --> | High \| Medium \| Low | ### 3.3 Circular Dependencies <!-- Circular imports prevent clean module extraction. Each cycle listed here must be broken before the involved files can be migrated in isolation. Source: madge (JS/TS), pydeps (Python), go vet (Go). --> | Cycle | Length | Files Involved | Breakable? | |-------|--------|----------------|------------| | <!-- cycle ID --> | <!-- N files --> | <!-- a → b → c → a --> | Yes \| Requires refactor first | **Circular dependency count:** <!-- N cycles --> ### 3.4 Coupling Risk Summary **Highest-risk files for migration (top 5 by combined fan-in + fan-out):** <!-- Ordered list. These files should be migrated last or given their own skill invocation. --> 1. <!-- path → reason --> --- ## 4. Test Coverage > **Purpose:** Know where you're blind before you start moving things. > Modules below 70% line coverage require `skills/03-prepare/test-coverage-baseline` > before any Phase 4 migration skill may run against them. ### 4.1 Coverage by Module <!-- Source: last CI coverage run. If no coverage data exists, note that and record 0%. Do not run a new coverage pass here — capture what CI already has. --> | Module | Line % | Branch % | Tool | Last Run | |--------|--------|----------|------|----------| | <!-- path --> | <!-- N% --> | <!-- N% --> | <!-- jest/pytest/go test --> | <!-- date --> | ### 4.2 Coverage Gaps <!-- Modules below 70% line coverage. Each flagged module must have `skills/03-prepare/test-coverage-baseline` run before its Phase 4 migration. --> | Module | Current Line % | Gap to 70% Threshold | Priority | |--------|---------------|----------------------|----------| | <!-- path --> | <!-- N% --> | <!-- N pp --> | High \| Medium \| Low | ### 4.3 Test Suite Characterization **Total tests:** <!-- N --> **Test type breakdown:** <!-- N unit / N integration / N e2e --> **Snapshot test count:** <!-- N (high snapshot counts are migration risk — snapshots break on any rendering change) --> **Mock-heavy tests (mocking >2 internal modules):** <!-- N (these tests will not survive a stack change) --> **Tests with no assertions (`expect(true).toBe(true)` or similar):** <!-- N --> --- ## 5. Performance Baselines > **Purpose:** Establish measurable benchmarks now, so Phase 5 (Validate) can prove > the new stack does not regress. Numbers without a timestamp are not baselines. ### 5.1 Bundle Size <!-- Frontend / Node.js only. Skip for backend-only Python, Ruby, Go services. Record gzipped sizes — that is what the user downloads. --> | Entry Point | Raw Size | Gzip Size | Brotli Size | Tool | |-------------|----------|-----------|-------------|------| | <!-- file --> | <!-- N KB --> | <!-- N KB --> | <!-- N KB --> | <!-- source-map-explorer \| webpack-bundle-analyzer \| none --> | **Bundle size measurement date:** <!-- ISO 8601 --> ### 5.2 Startup Time <!-- Cold start only. Measure 3 times and record median. --> | Environment | Median Cold Start | Tool | Date | |-------------|------------------|------|------| | Development | <!-- N ms --> | <!-- /usr/bin/time \| node --prof \| hyperfine --> | <!-- date --> | | Production (staging) | <!-- N ms --> | <!-- same --> | <!-- date --> | ### 5.3 Request Latency Baselines <!-- API services only. Record p50 and p99 for the 3 highest-traffic routes. Source: existing APM (Datadog, New Relic, Grafana) or a k6 run against staging. Skip if no APM and staging is not available. --> | Route | p50 (ms) | p99 (ms) | Measured From | Date | |-------|----------|----------|---------------|------| | <!-- METHOD /path --> | <!-- N --> | <!-- N --> | <!-- APM name \| k6 \| none --> | <!-- date --> | ### 5.4 Core Web Vitals <!-- Frontend only. Source: Lighthouse CI, PageSpeed, or CrUX data. Skip if server-rendered only. --> | Metric | Value | Source | URL | Date | |--------|-------|--------|-----|------| | LCP | <!-- N s --> | <!-- Lighthouse \| PageSpeed \| CrUX --> | <!-- URL --> | <!-- date --> | | CLS | <!-- N --> | <!-- same --> | <!-- URL --> | <!-- date --> | | FID / INP | <!-- N ms --> | <!-- same --> | <!-- URL --> | <!-- date --> | --- ## 6. CVE Report > **Purpose:** Know the security debt before the migration inherits it. > A migration that moves CVEs to a new stack has not fixed them — it has renamed them. ### 6.1 Critical and High Severity <!-- Source: npm audit --json / pip-audit / bundler-audit / govulncheck / trivy. List only CRITICAL and HIGH severity. Include only CVEs with a fix available — CVEs with no fix are logged but cannot block migration. --> | Package | CVE ID | Severity | CVSS Score | Fix Available In | Exploitable Via | |---------|--------|----------|-----------|-----------------|-----------------| | <!-- name --> | <!-- CVE-YYYY-XXXXX --> | CRITICAL \| HIGH | <!-- N.N --> | <!-- version --> | <!-- direct dep \| transitive --> | **Critical CVE count:** <!-- N with fix / N total --> **High CVE count:** <!-- N with fix / N total --> ### 6.2 Medium and Low Severity **Medium count:** <!-- N --> **Low count:** <!-- N --> **Full list:** `output/codebase-audit-cve-<timestamp>.json` (raw tool output) ### 6.3 CVE Risk Verdict **Security posture:** <!-- Green (no critical/high with fix) \| Yellow (high with fix, not critical) \| Red (critical CVEs with fix available — must be resolved before migration begins) --> > If Red: do not begin Phase 4 migration. Apply security fixes in a dedicated PR first. > Moving critical CVEs to a new stack with a migration PR makes them harder to track and audit. --- ## 7. Implicit Contracts > **Purpose:** Name the things that are not in the code. > Implicit contracts are the most common cause of post-migration production incidents — > they work on the old stack by accident and break on the new stack by surprise. ### 7.1 Magic Environment Variables <!-- Env vars read by the application (process.env.X, os.environ.get('X'), ENV['X']) that are NOT documented in .env.example, README, or an explicit config schema. Source: code-archaeologist implicit-contracts report. --> | Variable Name | Read In (file:line) | Default If Absent | Documented? | Risk | |--------------|---------------------|-------------------|-------------|------| | <!-- VAR_NAME --> | <!-- path:N --> | <!-- value \| crashes \| undefined --> | Yes \| No | <!-- Low \| Medium \| High --> | ### 7.2 Runtime-Only Configuration <!-- Config that exists only at runtime: secrets manager values, DB-sourced config, feature flags fetched at startup, env-specific config injected by the orchestrator. These do not appear in source code and must be discovered from logs or runbooks. --> | Config Key | Source | Set By | Documented? | Notes | |-----------|--------|--------|-------------|-------| | <!-- key --> | <!-- secrets manager \| DB \| env injector --> | <!-- team/system --> | Yes \| No | <!-- e.g., required in prod, optional in dev --> | ### 7.3 Undocumented Behaviors <!-- Behaviors that exist in production but have no test, no documentation, and no obvious implementation path — discovered via: log analysis, code comments marked HACK/FIXME/TODO, tribal knowledge captured in interviews. --> | Behavior | Discovered Via | File (if traceable) | Risk if Lost in Migration | |----------|---------------|---------------------|--------------------------| | <!-- description --> | <!-- log \| comment \| interview --> | <!-- path:N or "unknown" --> | High \| Medium \| Low | ### 7.4 External Integration Points <!-- Services, APIs, queues, cron jobs, webhooks, and file system contracts that the application depends on but that do not appear in package.json or import statements. These must be accounted for in Phase 2 (Strategize) sequencing. --> | Integration | Type | Direction | Protocol | Documented? | Owner | |------------|------|-----------|----------|-------------|-------| | <!-- name --> | <!-- HTTP API \| queue \| cron \| webhook \| filesystem --> | in \| out \| bidirectional | <!-- REST \| gRPC \| AMQP \| etc. --> | Yes \| No | <!-- team or external vendor --> | --- ## 8. Migration Risk Register > Synthesized from Sections 1–7. Ordered by severity (Critical → High → Medium → Low). > This register is the primary input for Phase 2 (Strategize) sequencing decisions. > Every row here should map to a mitigation action in the Phase 2 migration manifest. | # | Risk | Source Section | Severity | Likelihood | Mitigation | |---|------|---------------|----------|------------|------------| | 1 | <!-- description --> | § <!-- N --> | Critical \| High \| Medium \| Low | High \| Medium \| Low | <!-- specific action --> | **Overall migration risk level:** <!-- Critical \| High \| Medium \| Low --> **Recommended Phase 4 start date:** <!-- Not before [date] — pending: list any blockers (CVE fixes, test baseline, dead code removal) --> --- ## Sign-off > This section must be completed before Phase 2 (Strategize) begins. > The audit findings are only as useful as the people who have read and agreed with them. | Role | Name | Date | Notes | |------|------|------|-------| | <!-- Engineering Lead --> | | | | | <!-- Product / Project Owner --> | | | | | <!-- Security (if Red CVE verdict) --> | | | | **Status:** <!-- PENDING \| APPROVED --> > **Migration may proceed to Phase 2 only when Status is APPROVED and all rows above have a Date.** -
Populate Section 1 (Dependency Inventory). Run the appropriate commands for
languageandpackage_manager:npm / yarn / pnpm:
# List all direct dependencies with current and latest versions npm outdated --json > output/codebase-audit-deps-<timestamp>.json # Get full transitive tree for fan-in analysis npm ls --all --json >> output/codebase-audit-deps-<timestamp>.jsonpip / pipenv / poetry:
pip list --outdated --format=json > output/codebase-audit-deps-<timestamp>.json pip-licenses --format=json >> output/codebase-audit-deps-<timestamp>.jsonGo modules:
go list -m -u -json all > output/codebase-audit-deps-<timestamp>.jsonBundler (Ruby):
bundle outdated --parseable > output/codebase-audit-deps-<timestamp>.jsonRead
output/codebase-audit-deps-<timestamp>.json. For each direct dependency:- Record pinned version and latest stable version in the table.
- Check
endoflife.dateAPI or known EOL calendars for runtime EOL dates (Node.js, Python, Ruby). Flag dependencies that have reached EOL or will within 18 months. - Flag packages with no release in >12 months as
abandoned. Write populated Section 1 intoAUDIT.md.
-
Populate Section 2 (Dead Code Surface). Run the appropriate dead-code tools:
TypeScript:
# ts-prune: finds unused exports npx ts-prune --error 2>&1 | tee output/codebase-audit-dead-ts-<timestamp>.txt # knip: finds unused files, exports, and dependencies npx knip --reporter json > output/codebase-audit-knip-<timestamp>.jsonJavaScript:
npx knip --reporter json > output/codebase-audit-knip-<timestamp>.json npx depcheck --json > output/codebase-audit-depcheck-<timestamp>.jsonPython:
# vulture: finds unused code vulture <target_module> --min-confidence 80 > output/codebase-audit-dead-py-<timestamp>.txt # pip-extra-reqs: finds unused packages pip-extra-reqs . > output/codebase-audit-depcheck-<timestamp>.txtGo:
go mod tidy -v 2>&1 | tee output/codebase-audit-dead-go-<timestamp>.txtRead tool outputs. Aggregate unused export counts by file (do not list individual symbols — the Phase 4 skill handles per-symbol decisions). Calculate an estimated removable LOC using
wc -lon files with >50% unused exports. Write populated Section 2 intoAUDIT.md.- If this fails because the tool is not installed: note in the migration log, write
Tool not available — install <tool> and rerunin the section, and continue. Do not leave the section empty.
- If this fails because the tool is not installed: note in the migration log, write
-
→ Hand off to
code-archaeologistfor the coupling map (see Section 5. Agent Handoffs —coupling-map). Wait foroutput/codebase-audit-coupling-<timestamp>.jsonbefore continuing. Read the coupling report and populate Section 3 (Coupling Map). For the fan-out and fan-in hot spots: list the top 10 files by count, not all files — the section is a decision aid, not a full graph dump. Write populated Section 3 intoAUDIT.md. -
Populate Section 4 (Test Coverage). Do not run a new coverage pass — read whatever coverage data CI has already produced:
# Jest / c8 / istanbul: look for existing coverage reports ls coverage/coverage-summary.json coverage/coverage-final.json # pytest-cov: look for existing reports ls coverage.xml .coverage # Go: look for coverage profile ls coverage.outIf no coverage data exists at all: record 0% for all modules and flag every module in the gaps table. This is a common finding on legacy codebases and is not a skill failure — it is an audit result.
Read the test files to characterize the test suite (Step 4 of this skill). Count:
- Total test files and test cases.
- Tests with >2 internal module mocks (grep for
jest.mock\|unittest.mock\|stub\|spy— each file with >2 occurrences is counted). - Snapshot files (
__snapshots__/or*.snapcount). Write populated Section 4 intoAUDIT.md.
-
Populate Section 6 (CVE Report) — run before Section 5 so that critical CVE findings can influence the risk register. Run CVE tools:
npm / yarn / pnpm:
npm audit --json > output/codebase-audit-cve-<timestamp>.jsonpip / pipenv / poetry:
pip-audit --format=json > output/codebase-audit-cve-<timestamp>.jsonBundler (Ruby):
bundle-audit check --update --format json > output/codebase-audit-cve-<timestamp>.jsonGo:
govulncheck -json ./... > output/codebase-audit-cve-<timestamp>.jsonTrivy (if
trivy_enabledis true — adds OS and container layer CVEs):trivy fs --format json --output output/codebase-audit-trivy-<timestamp>.json <repo_root>Read the CVE JSON. For Section 6.1: list only CRITICAL and HIGH severity CVEs that have a fix available in a published version. For CVEs with no fix: log them in the migration log but note them in the section text rather than the table (they cannot be actioned). Compute the CVE Risk Verdict: Red if any CRITICAL with a fix exists. Write populated Section 6 into
AUDIT.md. -
Populate Section 5 (Performance Baselines). Run bundle analysis if
bundle_tool≠none:source-map-explorer:
npm run build -- --sourcemap npx source-map-explorer build/static/js/*.js --json > output/codebase-audit-bundle-<timestamp>.jsonwebpack-bundle-analyzer (non-interactive):
npx webpack-bundle-analyzer dist/stats.json --mode static --no-open \ --report output/codebase-audit-bundle-<timestamp>.htmlvite-bundle-visualizer:
npx vite-bundle-visualizer --outFile output/codebase-audit-bundle-<timestamp>.jsonMeasure startup time (3 runs, record median):
# Node.js for i in 1 2 3; do /usr/bin/time -f "%e seconds" node <entry_point> &; sleep 2; kill $!; done # Python for i in 1 2 3; do python -c "import time, <module>; print(time.time())"; doneIf APM data (Datadog, Grafana, New Relic) is accessible, pull p50/p99 latency for the 3 highest-traffic routes. If not accessible, note in the section:
No APM configured — baseline latency unavailable. Recommend k6 run against staging before Phase 4.Write populated Section 5 intoAUDIT.md. -
→ Hand off to
code-archaeologistfor the implicit contracts inventory (see Section 5. Agent Handoffs —implicit-contracts). Wait foroutput/codebase-audit-implicit-<timestamp>.mdbefore continuing. Read the inventory and populate Section 7 (Implicit Contracts). For each env var found: cross-reference against.env.example,README.md, and any config schema file to determine if it is documented. Write populated Section 7 intoAUDIT.md. -
Write Section 8 (Migration Risk Register) by synthesizing Sections 1–7. For each finding that represents a migration risk, create one row. Order rows by severity descending. Assign overall migration risk level as the highest severity of any row. Determine the recommended Phase 4 start date: "Not before [date]" if there are Critical CVEs with fixes, modules below 70% coverage, or circular dependencies that block extraction; otherwise "Immediately pending sign-off."
-
Write the Sign-off block with one row per name in
stakeholders. Leave the Date and Notes columns empty — stakeholders fill these in. Set Status toPENDING. Add a note at the bottom ofAUDIT.md: "To approve: fill in your Date and Notes, then change Status to APPROVED." -
Write all outputs declared in Section 7. Run every Equivalence Test in Section 6 and record results in
output/codebase-audit-equiv-<timestamp>.md. Evaluate every item in Section 9 Done Criteria; report pass/fail inline, then print the final verdict.
5. Agent Handoffs
code-archaeologist (coupling-map)
- File:
agents/code-archaeologist.md - Triggered by: Step 5
- Prompt template:
TASK: Produce a module coupling map for the entire repository. For each source file in SCOPE, report: - fan-out: count of unique internal modules it imports from - fan-in: count of unique internal modules that import it - top 5 outgoing imports (file path) - top 5 incoming importers (file path) Additionally, detect circular dependency chains of length ≥ 2 and list each chain as an ordered sequence of file paths (a → b → c → a). Do not include external package imports in fan-in/fan-out counts — only count imports of internal files (relative imports or path-aliased imports). REPO_ROOT: <repo_root> SCOPE: <repo_root>/src OUTPUT_FILE: output/codebase-audit-coupling-<timestamp>.json FORMAT: json
code-archaeologist (implicit-contracts)
- File:
agents/code-archaeologist.md - Triggered by: Step 9
- Prompt template:
TASK: Inventory all implicit contracts in the repository — things the application depends on that are not declared in the package manifest or type system. Specifically, find and report: (a) Every process.env.X / os.environ.get('X') / ENV['X'] call in SCOPE, with file path and line number. Flag any that have no default value (the application will crash or behave incorrectly if absent). (b) Any configuration fetched via HTTP at startup (service discovery, remote config, LaunchDarkly / feature flag SDK init). (c) Any file system paths that are read or written but not derived from an env var (hardcoded paths are implicit contracts with the OS layout). (d) Any comment in the codebase containing HACK, FIXME, WORKAROUND, or DO NOT REMOVE — these are signals of undocumented behaviors. (e) Any HTTP call to an external service where the URL is hardcoded rather than read from an env var — these are implicit contracts with external APIs. If audit_depth === 'shallow': report only (a) and (d). If audit_depth === 'deep': report all five categories. REPO_ROOT: <repo_root> SCOPE: <repo_root>/src OUTPUT_FILE: output/codebase-audit-implicit-<timestamp>.md FORMAT: markdown
6. Equivalence Tests
<!-- This skill produces a baseline, not a migration. Section 6 verifies that AUDIT.md itself is complete, accurate, and committed — not that two stacks are equivalent. -->| Test Name | Input | Expected Output | Tool |
|---|---|---|---|
audit-md-exists | ls <repo_root>/AUDIT.md | File exists and is non-empty (>1 KB). | Bash |
all-sections-populated | Read <repo_root>/AUDIT.md; grep for <!-- TODO --> | Zero matches — no placeholder text remains in any section. A single remaining TODO is a fail. | Bash: grep -c '<!-- TODO' <repo_root>/AUDIT.md must return 0. |
seven-sections-present | Read <repo_root>/AUDIT.md; grep for ^## [1-7]\. | Exactly 7 section headings matching ## 1. through ## 7. are present, in order. | Bash: grep -c '^## [1-7]\.' <repo_root>/AUDIT.md must return 7. |
risk-register-present | Read <repo_root>/AUDIT.md; grep for ^## 8\. Migration Risk Register | Section 8 heading is present and the risk table has at least one data row (beyond the header). | Bash + Read |
sign-off-present | Read <repo_root>/AUDIT.md; grep for ^## Sign-off | Sign-off section is present and contains a table with one row per stakeholder name from stakeholders input. | Bash: grep -c '<stakeholder_name>' <repo_root>/AUDIT.md ≥ 1 per name. |
raw-data-committed | git log --oneline -- output/codebase-audit-deps-<timestamp>.json output/codebase-audit-cve-<timestamp>.json output/codebase-audit-coupling-<timestamp>.json | All three raw data files appear in git history in the same commit as AUDIT.md. | Bash |
cve-verdict-not-suppressed | Read Section 6.3 of AUDIT.md | CVE Risk Verdict is one of Green, Yellow, or Red — not blank, not "N/A", not "skipped". Even if no CVEs were found, the verdict must be Green. | Read |
7. Outputs
| Artifact | Path Pattern | Format | Description |
|---|---|---|---|
| Audit document | AUDIT.md (repo root) | markdown | The primary deliverable. Human-readable, structured, stakeholder-facing. Committed at repo root so it is the first thing any engineer sees when cloning. |
| Dependency data | output/codebase-audit-deps-<timestamp>.json | json | Raw output from npm outdated, pip list --outdated, go list -m -u, etc. Supporting evidence for Section 1. |
| Dead code data | output/codebase-audit-knip-<timestamp>.json and/or output/codebase-audit-dead-<lang>-<timestamp>.txt | json / text | Raw output from ts-prune, knip, vulture, or equivalent. Supporting evidence for Section 2. |
| Coupling map | output/codebase-audit-coupling-<timestamp>.json | json | Produced by code-archaeologist (coupling-map). Fan-in/fan-out counts and circular dependency chains per file. Supporting evidence for Section 3. |
| CVE data | output/codebase-audit-cve-<timestamp>.json | json | Raw output from npm audit, pip-audit, govulncheck, or trivy. Full CVE list including medium/low. Supporting evidence for Section 6. |
| Implicit contracts | output/codebase-audit-implicit-<timestamp>.md | markdown | Produced by code-archaeologist (implicit-contracts). Env vars, hardcoded paths, HACK comments, external calls. Supporting evidence for Section 7. |
| Bundle data | output/codebase-audit-bundle-<timestamp>.json | json | Raw output from bundle analyzer tool. Only present if bundle_tool ≠ none. Supporting evidence for Section 5. |
| Migration log | output/codebase-audit-log-<timestamp>.md | markdown | Tool invocation results (exit codes, any tool not available), gap dispositions, confidence level, and numbered assumptions list. |
| Equivalence test results | output/codebase-audit-equiv-<timestamp>.md | markdown | Pass/fail verdict for every row in Section 6. Required by Section 9 Done Criteria. |
8. References
references/migration-anti-patterns.md— "Confidence Without Evidence" (§7) is the failure mode this skill exists to prevent. Every finding in AUDIT.md must cite a tool output or a file:line — no assertions without evidence.references/strangler-fig-pattern.md— the coupling map from Section 3 informs which modules can be extracted behind a seam and which must be migrated as a unit.skills/02-strategize/— consumes AUDIT.md as its primary input. The migration risk register in Section 8 maps directly to the Phase 2 migration manifest entries.skills/03-prepare/test-coverage-baseline/— every module flagged in Section 4.2 (Coverage Gaps) must have this skill run against it before any Phase 4 migration.agents/code-archaeologist.md— invoked twice in this skill (Steps 5 and 9); the two invocations have different TASK scopes — do not merge them.https://endoflife.date/— authoritative EOL calendar for runtimes and frameworks. Used in Step 3 to populate Section 1.3.https://github.com/webpro/knip— knip documentation; the primary dead-code tool for JS/TS projects. Covers unused files, exports, and dependencies in a single pass.
9. Done Criteria
<!-- Claude evaluates each item and reports pass/fail before declaring this skill complete. Any unchecked item means the skill is NOT complete and Phase 2 may not begin. This is the entry gate for all migration work — its threshold is deliberately high. -->-
AUDIT.mdexists at<repo_root>/AUDIT.mdand is greater than 1 KB —audit-md-existsequivalence test recorded as pass. A file that exists but contains only the skeleton template is a fail. - All seven numbered sections (1–7) are present and populated —
all-sections-populatedandseven-sections-presentequivalence tests recorded as pass. Zero<!-- TODO -->strings remaining. - Section 8 (Migration Risk Register) contains at least one data row — every non-trivial codebase has at least one migration risk. A risk register with zero rows means no findings were recorded, not that there are no risks.
- Section Sign-off table contains one row per name in
stakeholders—sign-off-presentequivalence test recorded as pass. - CVE Risk Verdict in Section 6.3 is explicitly
Green,Yellow, orRed—cve-verdict-not-suppressedequivalence test recorded as pass. - If CVE verdict is
Red(critical CVEs with fix available): the migration log contains a note that Phase 4 is blocked pending CVE remediation. Proceeding to Phase 4 with a Red verdict requires explicit user override recorded in the migration log. - All raw data files declared in Section 7 exist at their output paths — verify each with a file read. Bundle data is only required if
bundle_tool≠none. -
AUDIT.mdand all raw data output files are committed in a single git commit —raw-data-committedequivalence test recorded as pass. - The coupling report (
output/codebase-audit-coupling-<timestamp>.json) identifies at least the top 3 files by fan-in — if the file is empty or contains fewer than 3 entries, the coupling analysis did not run correctly. Re-invoke the code-archaeologist agent. - Every module below 70% line coverage is listed in Section 4.2 with a note that
skills/03-prepare/test-coverage-baselineis required before its Phase 4 migration. - All output files listed in Section 7 exist at their declared paths — verify each with a file read.
- Every equivalence test in Section 6 has a recorded result in
output/codebase-audit-equiv-<timestamp>.md— no test name is missing. - No equivalence test in Section 6 is recorded as fail — grep the results file for
fail; zero matches required. - The migration log includes a confidence level (High / Medium / Low) — grep
output/codebase-audit-log-<timestamp>.mdforConfidence:. - The migration log includes a numbered assumptions list — grep
output/codebase-audit-log-<timestamp>.mdforAssumptions:.