diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 97d715c3..cd0078f3 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -752,7 +752,7 @@ }, { "name": "code-modernization", - "description": "Modernize legacy codebases (COBOL, legacy Java/C++, monolith web apps) with a structured assess / map / extract-rules / reimagine / transform / harden workflow and specialist review agents", + "description": "Modernize legacy codebases (COBOL, legacy Java/C++, monolith web apps) with a structured preflight / assess / map / extract-rules / brief / reimagine / transform / harden workflow, an interactive topology viewer, and specialist review agents", "author": { "name": "Anthropic", "email": "support@anthropic.com" diff --git a/plugins/code-modernization/.claude-plugin/plugin.json b/plugins/code-modernization/.claude-plugin/plugin.json index 6ccb1718..9bc35ac2 100644 --- a/plugins/code-modernization/.claude-plugin/plugin.json +++ b/plugins/code-modernization/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "code-modernization", - "description": "Modernize legacy codebases (COBOL, legacy Java/C++, monolith web apps) with a structured assess → map → extract-rules → brief → reimagine/transform → harden workflow and specialist review agents", + "description": "Modernize legacy codebases (COBOL, legacy Java/C++, monolith web apps) with a structured preflight / assess / map / extract-rules / brief / reimagine / transform / harden workflow, an interactive topology viewer, and specialist review agents", "author": { "name": "Anthropic", "email": "support@anthropic.com" diff --git a/plugins/code-modernization/README.md b/plugins/code-modernization/README.md index 8678d696..1de150cb 100644 --- a/plugins/code-modernization/README.md +++ b/plugins/code-modernization/README.md @@ -7,7 +7,7 @@ A structured workflow and set of specialist agents for modernizing legacy codeba Legacy modernization fails most often not because the target technology is wrong, but because teams skip steps: they transform code before understanding it, reimagine architecture before extracting business rules, or ship without a harness that would catch behavior drift. This plugin enforces a sequence: ``` -assess → map → extract-rules → brief → reimagine | transform → harden +preflight → assess → map → extract-rules → brief → reimagine | transform → harden ``` The discovery commands (`assess`, `map`, `extract-rules`) build artifacts under `analysis//`. The `brief` command synthesizes them into an approval gate. The build commands (`reimagine`, `transform`) write new code under `modernized/`. The `harden` command audits the legacy system and produces a reviewable remediation patch. Each step has a dedicated slash command, and specialist agents (legacy analyst, business rules extractor, architecture critic, security auditor, test engineer) are invoked from within those commands — or directly — to keep the work honest. @@ -20,25 +20,36 @@ Commands take a `` argument and assume the system being modernized l mkdir -p legacy && ln -s /path/to/your/legacy/codebase legacy/billing ``` -## Optional tooling +## What to give Claude -`/modernize-assess` works best with [`scc`](https://github.com/boyter/scc) (LOC + complexity + COCOMO) or [`cloc`](https://github.com/AlDanial/cloc), and falls back to `find`/`wc` if neither is installed. Portfolio mode also benefits from [`lizard`](https://github.com/terryyin/lizard) (cyclomatic complexity). The commands degrade gracefully without them, but the metrics will be coarser. +The commands degrade gracefully, but each of these makes the output meaningfully better — run `/modernize-preflight ` to check all of them at once and get a readiness report: + +- **Analysis tools**: [`scc`](https://github.com/boyter/scc) (LOC + complexity + COCOMO) or [`cloc`](https://github.com/AlDanial/cloc); [`lizard`](https://github.com/terryyin/lizard) for portfolio mode. Without them, metrics fall back to `find`/`wc` and get coarser. +- **A working build toolchain** for the legacy stack (e.g. GnuCOBOL for COBOL) — required before `/modernize-transform` can prove behavioral equivalence, and verified by preflight with a real smoke compile against your code. +- **The whole system in the tree**: deployment descriptors (JCL, CICS definitions, route configs), copybooks/includes, and DDL/schemas. Entry-point detection and data lineage in `/modernize-map` are guesswork without them. +- **Production telemetry** (optional): an observability MCP server or batch job logs enable the runtime overlay in `/modernize-assess` and timing annotations on critical paths. ## Commands The commands are designed to be run in order, but each produces a standalone artifact so you can stop, review, and resume. +### `/modernize-preflight [target-stack]` +Environment readiness check, meant to run first: detects the legacy stack, checks analysis tooling, **smoke-compiles a real source file** with the legacy toolchain (the errors this surfaces — missing copybooks, wrong dialect flags — are the ones that otherwise appear mid-transform), inventories missing includes / deployment descriptors / binary-only artifacts, and probes for telemetry. Produces `analysis//PREFLIGHT.md` with a per-command Ready / Ready-with-gaps / Not-ready verdict. + ### `/modernize-assess ` — or — `/modernize-assess --portfolio ` Inventory the legacy codebase: languages, line counts, complexity, build system, integrations, technical debt, security posture, documentation gaps, and a COCOMO-derived effort estimate. Produces `analysis//ASSESSMENT.md` and `analysis//ARCHITECTURE.mmd`. Spawns `legacy-analyst` (×2) and `security-auditor` in parallel for deep reads. With `--portfolio`, sweeps every subdirectory of a parent directory and writes a sequencing heat-map to `analysis/portfolio.html`. ### `/modernize-map ` -Build a dependency and topology map of the **legacy** system: program/module call graph, data lineage (programs ↔ data stores), entry points, dead-end candidates, and one traced critical-path business flow. Writes a re-runnable extraction script and produces `analysis//topology.json` (machine-readable), `analysis//TOPOLOGY.html` (rendered Mermaid + architect observations), and standalone `call-graph.mmd`, `data-lineage.mmd`, and `critical-path.mmd`. + +![Interactive topology map of AWS CardDemo — domains as containers, modules sized by lines of code, dependency edges colored by kind, entry points ringed](assets/topology-viewer-screenshot.jpg) + +Build a dependency and topology map of the **legacy** system: program/module call graph, data lineage (programs ↔ data stores), entry points, dead-end candidates, and 2–4 traced business flows each anchored to a persona (the claimant, the operator, the auditor — not the maintainer). Writes a re-runnable extraction script and produces `analysis//topology.json` plus `analysis//TOPOLOGY.html` — an **interactive zoomable map** (circle-pack of domains/modules sized by LOC, dependency edges with per-kind toggles, search, click-for-details sidebar, and a walkthrough mode that plays each persona flow as a numbered path with a plain-language narrative). Built from a template shipped with the plugin, so it works on systems far too dense for a static diagram. Small domain-level `call-graph.mmd`, `data-lineage.mmd`, and `critical-path.mmd` are still exported for docs and PRs. ### `/modernize-extract-rules [module-pattern]` Mine the business rules embedded in the legacy code — calculations, validations, eligibility, state transitions, policies — into Given/When/Then "Rule Cards" with `file:line` citations and confidence ratings. Spawns three `business-rules-extractor` agents in parallel (calculations, validations, lifecycle). Produces `analysis//BUSINESS_RULES.md` and `analysis//DATA_OBJECTS.md`. ### `/modernize-brief [target-stack]` -Synthesize the discovery artifacts into a phased **Modernization Brief** — the single document a steering committee approves and engineering executes: target architecture, strangler-fig phase plan with entry/exit criteria, behavior contract, validation strategy, open questions, and an approval block. Reads `ASSESSMENT.md`, `TOPOLOGY.html`, and `BUSINESS_RULES.md` and **stops if any are missing** — run the discovery commands first. Produces `analysis//MODERNIZATION_BRIEF.md` and enters plan mode as a human-in-the-loop gate. +Synthesize the discovery artifacts into a phased **Modernization Brief** — the single document a steering committee approves and engineering executes: target architecture, strangler-fig phase plan with entry/exit criteria, persona-based business walkthroughs (the section non-technical approvers actually read), behavior contract, validation strategy, open questions, and an approval block. Reads `ASSESSMENT.md`, `TOPOLOGY.html`, and `BUSINESS_RULES.md` and **stops if any are missing** — run the discovery commands first. Produces `analysis//MODERNIZATION_BRIEF.md` and enters plan mode as a human-in-the-loop gate. ### `/modernize-reimagine ` Greenfield rebuild from extracted intent rather than a structural port. Mines a spec (`analysis//AI_NATIVE_SPEC.md`), designs a target architecture and has it adversarially reviewed (`analysis//REIMAGINED_ARCHITECTURE.md`), then **scaffolds services with executable acceptance tests** under `modernized/-reimagined/` and writes a `CLAUDE.md` knowledge handoff for the new system. Two human-in-the-loop checkpoints. Spawns `business-rules-extractor`, `legacy-analyst` (×2), `architecture-critic`, and general-purpose scaffolding agents. @@ -46,6 +57,9 @@ Greenfield rebuild from extracted intent rather than a structural port. Mines a ### `/modernize-transform ` Surgical, single-module strangler-fig rewrite. Plans first (HITL gate), then writes characterization tests via `test-engineer`, then an idiomatic target implementation under `modernized///`, proves equivalence by running the tests, and produces `TRANSFORMATION_NOTES.md` mapping legacy → modern with deliberate deviations called out. Reviewed by `architecture-critic`. +### `/modernize-status ` +Read-only progress report: artifact inventory with timestamps per workflow stage, staleness flags (e.g. a brief older than the assessment it was built from), secrets-hygiene checks (quarantine file gitignored and never committed), and the single most useful next command. Run it anytime you come back to a modernization after a break. + ### `/modernize-harden ` Security hardening pass on the **legacy** system: OWASP/CWE scan, dependency CVEs, secrets, injection. Spawns `security-auditor`. Produces `analysis//SECURITY_FINDINGS.md` ranked Critical / High / Medium / Low and a reviewed `analysis//security_remediation.patch` with minimal fixes for the Critical/High findings. The patch is reviewed by a second `security-auditor` pass before you see it. **Never edits `legacy/`** — you review and apply the patch yourself when ready, then re-run to verify. Useful as a pre-modernization step when the legacy system will keep running in production during the migration. @@ -81,17 +95,21 @@ This plugin ships commands and agents, but modernization projects benefit from a "Edit(modernized/**)" ], "deny": [ - "Edit(legacy/**)" + "Edit(legacy/**)", + "Write(legacy/**)" ] } } ``` -Adjust `legacy/` and `modernized/` to match your actual layout. The key invariants: `Edit` under `legacy/` is denied, and writes are scoped to `analysis/` (for documents) and `modernized/` (for the new code). Every command in this plugin respects this — `/modernize-harden` writes a patch to `analysis/` rather than editing `legacy/` in place. +Adjust `legacy/` and `modernized/` to match your actual layout. The key invariants: `Edit`/`Write` under `legacy/` are denied, and writes are scoped to `analysis/` (for documents) and `modernized/` (for the new code). Note this guards the file tools — shell commands that mutate files (`sed -i`, `git apply`) still go through the normal Bash permission prompt, so review those prompts with the same invariant in mind. Every command in this plugin respects this — `/modernize-harden` writes a patch to `analysis/` rather than editing `legacy/` in place. ## Typical Workflow ```bash +# 0. Check the environment is ready (tools, toolchain, source completeness) +/modernize-preflight billing + # 1. Inventory the legacy system (or sweep a portfolio of them) /modernize-assess billing @@ -112,6 +130,9 @@ Adjust `legacy/` and `modernized/` to match your actual layout. The key invarian # 6. Security-harden the legacy system that's still in production /modernize-harden billing + +# Anytime: where am I, what's stale, what's next +/modernize-status billing ``` ## License diff --git a/plugins/code-modernization/assets/topology-viewer-screenshot.jpg b/plugins/code-modernization/assets/topology-viewer-screenshot.jpg new file mode 100644 index 00000000..4407f6c8 Binary files /dev/null and b/plugins/code-modernization/assets/topology-viewer-screenshot.jpg differ diff --git a/plugins/code-modernization/assets/topology-viewer.html b/plugins/code-modernization/assets/topology-viewer.html new file mode 100644 index 00000000..70575d5b --- /dev/null +++ b/plugins/code-modernization/assets/topology-viewer.html @@ -0,0 +1,514 @@ + + + + + +System topology + + + + + +
+
+

System topology

+
+
+
+ +
+
+
+ + +
+ + +
scroll to zoom · drag to pan · click a node · double-click to zoom in · Esc to reset
+

No topology data found in this file.
+Re-run /modernize-map to regenerate it.

+ + + + + diff --git a/plugins/code-modernization/commands/modernize-brief.md b/plugins/code-modernization/commands/modernize-brief.md index 28eeb624..5daa611e 100644 --- a/plugins/code-modernization/commands/modernize-brief.md +++ b/plugins/code-modernization/commands/modernize-brief.md @@ -8,10 +8,19 @@ single document a steering committee approves and engineering executes. Target stack: `$2` (if blank, recommend one based on the assessment findings). -Read `analysis/$1/ASSESSMENT.md`, `analysis/$1/TOPOLOGY.html` (and the `.mmd` -files alongside it), and `analysis/$1/BUSINESS_RULES.md` first. If any are -missing, say so and stop — they come from `/modernize-assess`, `/modernize-map`, -and `/modernize-extract-rules` respectively. Run those first. +Read `analysis/$1/ASSESSMENT.md`, `analysis/$1/topology.json` (plus the +`.mmd` files alongside it — do NOT read `TOPOLOGY.html`, it's an +interactive viewer with the data minified inside), and +`analysis/$1/BUSINESS_RULES.md` first. If any are missing, say so and +stop — they come from `/modernize-assess`, `/modernize-map`, and +`/modernize-extract-rules` respectively. Run those first. + +**Staleness check:** compare modification times. If any input is newer +than an existing `MODERNIZATION_BRIEF.md`, the brief is being justifiably +regenerated; but if an existing brief is newer than all inputs and the +user re-ran this command anyway, ask what changed. Either way, note the +input timestamps in the brief's header so reviewers can see what it was +built from. ## The Brief @@ -31,28 +40,38 @@ fewest-dependencies first. For each phase: - Scope (which legacy modules, which target services) - Entry criteria (what must be true to start) - Exit criteria (what tests/metrics prove it's done) -- Estimated effort (person-weeks, derived from COCOMO + complexity data) +- Estimated effort (person-months, same unit as the assessment's COCOMO + figure — convert deliberately if you present weeks) - Risk level + top 2 risks + mitigation Render the phases as a Mermaid `gantt` chart. -### 4. Behavior Contract +### 4. Business Walkthroughs +For each persona flow in `analysis/$1/topology.json` (`flows` — produced +by `/modernize-map`), a short narrative table: persona, what happens in +business language, which legacy modules implement it today, and which +phase from §3 replaces each. This is the section non-technical approvers +actually read — it connects "Phase 2" to "what happens when a customer +files a claim". If topology.json has no flows, derive 2–3 walkthroughs +from the entry points and say they need SME confirmation. + +### 5. Behavior Contract List the **P0 rules** from BUSINESS_RULES.md (the ones tagged `Priority: P0` — money, regulatory, data integrity) that MUST be proven equivalent before any phase ships. These become the regression suite. Flag any P0 rule with Confidence < High as a blocker requiring SME confirmation before its phase starts. -### 5. Validation Strategy +### 6. Validation Strategy State which combination applies: characterization tests, contract tests, parallel-run / dual-execution diff, property-based tests, manual UAT. Justify per phase. -### 6. Open Questions +### 7. Open Questions Anything requiring human/SME decision before Phase 1 starts. Each as a checkbox the approver must tick. -### 7. Approval Block +### 8. Approval Block ``` Approved by: ________________ Date: __________ Approval covers: Phase 1 only | Full plan @@ -60,6 +79,7 @@ Approval covers: Phase 1 only | Full plan ## Present -Enter **plan mode** and present a summary of the brief. Do NOT proceed to any -transformation until the user explicitly approves. This gate is the -human-in-the-loop control point. +Present a summary of the brief and **stop — write nothing further until +the user explicitly approves** (use plan mode if the session supports +it). This gate is the human-in-the-loop control point; "no objection" is +not approval. diff --git a/plugins/code-modernization/commands/modernize-map.md b/plugins/code-modernization/commands/modernize-map.md index 406b74c0..53668ca6 100644 --- a/plugins/code-modernization/commands/modernize-map.md +++ b/plugins/code-modernization/commands/modernize-map.md @@ -55,50 +55,124 @@ re-run and audited. Have it write a machine-readable `analysis/$1/topology.json` and print a human summary. Run it; show the summary (cap at ~200 lines for very large estates). -## Render +`topology.json` must follow this schema — it feeds the interactive viewer: -From the extracted data, generate **three Mermaid diagrams** and write them -to `analysis/$1/TOPOLOGY.html` as a self-contained page that renders in any -browser. - -The HTML page must use: dark `#1e1e1e` background, `#d4d4d4` text, -`#cc785c` for `

`/accents, `system-ui` font, all CSS **inline** (no -external stylesheets). Load Mermaid from a CDN in ``: - -```html - +```json +{ + "system": "", + "root": { + "id": "sys", "name": "", "kind": "system", + "children": [ + { "id": "dom:", "name": "", "kind": "domain", + "children": [ + { "id": "", "name": "", "kind": "module", + "language": "cobol", "loc": 1234, "file": "src/MODULE.cbl" } + ] }, + { "id": "dom:data", "name": "Data stores", "kind": "domain", + "children": [ + { "id": "ds:", "name": "", "kind": "datastore" } + ] } + ] + }, + "edges": [ + { "source": "", "target": "", "kind": "call" } + ], + "entryPoints": ["", "..."], + "deadEnds": ["", "..."], + "observations": ["", "..."], + "flows": [ + { "name": "", "persona": "", + "description": "", + "steps": [ + { "label": "", "nodes": ["", ""] } + ] } + ] +} ``` -Each diagram goes in a `
...
` block. Do **not** -wrap diagrams in markdown ` ``` ` fences inside the HTML. +- Group leaf modules under `domain` containers (use the domains from + `/modernize-assess` if available). Leaf kinds: `module`, `datastore`, + `job`, `screen`. `loc` drives circle size — include it for modules. +- Edge kinds: `call` (direct), `dispatch` (dynamic/router), `read`, + `write`. Every edge endpoint must be a leaf id that exists in the tree. +- `deadEnds`: the dead-end candidates from the extraction, rendered with + a dashed outline in the viewer. Apply the suppression rules above — + anything that could be the target of an unresolved dynamic call does + NOT belong here; record that uncertainty in `observations` instead. +- **Datastore ids and names must be logical identifiers** — DD name, + dataset name, table/schema name, at most host:port. If the resolved + config value is a URL or DSN, strip userinfo and credential query + params before it goes anywhere in topology.json: the file gets + committed and the viewer displays names verbatim. Never copy raw + config values into `observations`. +- `observations`: 3–7 architect observations — tight coupling clusters, + single points of failure, service-extraction candidates, data stores + with too many writers, dispatch targets the extraction could not + resolve. +- `flows` is the **persona walkthrough** section — see below. -1. **`graph TD` — Module call graph.** Cluster by domain (use `subgraph`). - Highlight entry points in a distinct style. Cap at ~40 nodes — if larger, - show domain-level with one expanded domain. +## Persona flows -2. **`graph LR` — Data lineage.** Programs → data stores. - Mark read vs write edges. +Trace **2–4 end-to-end business flows**, each anchored to a persona — +the people who experience the system, not the people who maintain it +(e.g. for a benefits system: the claimant, the caseworker, the auditor; +for billing: the customer, the billing operator). For each flow: -3. **`flowchart TD` — Critical path.** Trace ONE end-to-end business flow - (e.g., "monthly billing run" or "process payment") through every program - and data store it touches, in execution order. If production telemetry is - available (see `/modernize-assess` Step 4), annotate each step with its - p50/p99 wall-clock. +- `name` + one-sentence `description` in plain business language — + something a steering committee member relates to ("a claimant files a + weekly claim"), not a data-flow label ("CLM batch ingest"). +- `steps`: 3–8 steps, each with a business-language `label` and the + `nodes` (programs + data stores) that implement that step, in + execution order. -Also export the three diagrams as standalone `.mmd` files for re-use: -`analysis/$1/call-graph.mmd`, `analysis/$1/data-lineage.mmd`, -`analysis/$1/critical-path.mmd`. +This is the bridge between the technical map and non-technical +stakeholders: the same diagram answers "which program does X" for +engineers and "what happens when someone files a claim" for everyone else. -## Annotate +## Render -Below each `
` block in TOPOLOGY.html, add a `
    ` -with 3-5 **architect observations**: tight coupling clusters, single -points of failure, candidates for service extraction, data stores -touched by too many writers. +`analysis/$1/TOPOLOGY.html` is an **interactive map**: a zoomable +circle-pack of the whole system (domains as containers, modules sized by +LOC) with dependency edges, search, per-node detail sidebar, edge-kind +toggles, and a flow-walkthrough mode that plays each persona flow as a +numbered path. Build it from the template that ships with this plugin — +do not hand-write the viewer: + +```bash +python3 - "${CLAUDE_PLUGIN_ROOT}/assets/topology-viewer.html" analysis/$1 <<'EOF' +import json, sys +tpl_path, out_dir = sys.argv[1], sys.argv[2] +tpl = open(tpl_path).read() +marker = "/*__TOPOLOGY_DATA__*/ null" +assert marker in tpl, f"injection marker not found in {tpl_path}" +data = json.dumps(json.load(open(f"{out_dir}/topology.json"))) +open(f"{out_dir}/TOPOLOGY.html", "w").write( + tpl.replace(marker, "/*__TOPOLOGY_DATA__*/ " + data)) +print(f"wrote {out_dir}/TOPOLOGY.html") +EOF +``` + +The viewer is fully self-contained (the d3 subset it needs is inlined in +the template) — it works offline and on air-gapped networks. If the +`python3` invocation fails to find the template, +`${CLAUDE_PLUGIN_ROOT}` was not substituted — report that rather than +hand-writing a viewer. + +Mermaid stays for **small, exportable** diagrams. Generate standalone +`.mmd` files for reuse in docs and PRs — but keep each under ~40 edges; +collapse to domain level if the full graph is bigger (dense Mermaid +becomes unreadable, which is exactly what the interactive map is for): + +- `analysis/$1/call-graph.mmd` — domain-level `graph TD`, entry points + highlighted +- `analysis/$1/data-lineage.mmd` — `graph LR`, programs → data stores, + read vs write marked +- `analysis/$1/critical-path.mmd` — `flowchart TD` of the primary flow + from `flows`, annotated with p50/p99 wall-clock if telemetry is + available (see `/modernize-assess` Step 4) ## Present -Tell the user to open `analysis/$1/TOPOLOGY.html` in a browser. +Tell the user to open `analysis/$1/TOPOLOGY.html` in a browser, and to +try: search for a module, click it to see its connections, and pick a +persona flow from the walkthrough dropdown. diff --git a/plugins/code-modernization/commands/modernize-preflight.md b/plugins/code-modernization/commands/modernize-preflight.md new file mode 100644 index 00000000..ed283ea3 --- /dev/null +++ b/plugins/code-modernization/commands/modernize-preflight.md @@ -0,0 +1,98 @@ +--- +description: Environment readiness check — analysis tools, build toolchain, source completeness, telemetry access +argument-hint: [target-stack] +--- + +Check whether this environment is ready to analyze — and eventually +transform — `legacy/$1`, and tell the user exactly what to fix before the +other commands run into it. Modernization sessions fail late and +confusingly when this isn't done: assessment metrics silently degrade +without analysis tools, characterization tests can't run without a build +toolchain, and dependency maps come out wrong when half the source isn't +in the tree. + +Run every check even when an early one fails — the point is one complete +readiness report, not the first error. + +## Check 1 — Detect the stack + +Fingerprint `legacy/$1` from file extensions and manifests: languages, +build system, deployment/config descriptors. This drives which checks +below apply. Report what was detected and the rough file split. + +## Check 2 — Analysis tooling + +For each, check availability (`command -v`) and report version, what it's +used for, and what degrades without it: + +| Tool | Used by | Without it | +|---|---|---| +| `scc` (or `cloc`) | assess | LOC/complexity fall back to `find`+`wc`; COCOMO estimate gets coarser | +| `lizard` | assess --portfolio | complexity estimated from decision-keyword counts | +| `glow` | all | markdown artifacts render as plain text | +| `delta` | transform | side-by-side diffs fall back to `diff -y` | + +Include the platform's install one-liner for anything missing +(`brew install scc`, `apt install cloc`, `pip install lizard`, …). + +## Check 3 — Build toolchain (smoke test, not just presence) + +Identify the compiler/interpreter for the detected legacy stack — e.g. +GnuCOBOL (`cobc`) for COBOL, JDK + Maven/Gradle for Java, `cc`/`make` for +C, `dotnet` for .NET. Then **prove it works on this codebase**: pick one +representative source file and run a syntax-only compile +(`cobc -fsyntax-only`, `javac`, `gcc -fsyntax-only`, …). + +A failed smoke test is the most valuable output of this command — report +the actual error and diagnose it: missing copybook/include path, missing +dialect flag (`-std=ibm` etc.), fixed vs free format, missing dependency +jar. These are the errors that otherwise surface mid-`/modernize-transform` +with much less context. + +If the user passed a `[target-stack]`, do the same for it: runtime, +package manager, test framework (`mvn -v`, `npm -v`, `pytest --version`, …). + +## Check 4 — Source completeness + +The dependency map is only as good as what's in the tree. Check for the +detected stack's equivalents of: + +- **Referenced-but-missing includes** — copybooks (`COPY X` with no + `X.cpy`), headers, imports that resolve nowhere. Count and list the top + missing names. +- **Deployment/config descriptors** — JCL for batch COBOL, CICS CSD + definitions, `web.xml`/route configs, cron/scheduler definitions. + Without these, entry-point detection and the code↔storage join in + `/modernize-map` are guesswork. +- **Data definitions** — DDL, schemas, copybook record layouts, ORM + mappings. +- **Binary-only artifacts** — load modules, jars, DLLs with no matching + source. These become unmappable black boxes; flag them now. + +## Check 5 — Optional context + +- **Production telemetry** — is an observability/APM MCP server connected, + or are batch job logs / runtime exports available? (Enables the runtime + overlay in `/modernize-assess` Step 4 and timing annotations in + `/modernize-map`.) +- **Version control history** — is `legacy/$1` under git with meaningful + history? (Change-frequency data sharpens risk ranking.) + +## Report + +Write `analysis/$1/PREFLIGHT.md`: a status table — one row per check, +status ✅ / ⚠️ / ❌, what was found, and the fix for anything not green — +followed by a **Ready / Ready-with-gaps / Not ready** verdict per command: + +- `assess` + `map` + `extract-rules` — need Checks 1–2 green-ish and + Check 4's missing-include count low +- `brief` — needs only the three discovery artifacts; no tooling +- `transform` + `reimagine` — additionally need Check 3 green for the + **target** stack. A red legacy toolchain downgrades these to + Ready-with-gaps, not Not-ready: equivalence testing falls back to + recorded traces / golden-master fixtures instead of dual execution + (common and expected for CICS/IMS code that has no local runtime) +- `harden` — needs Check 2 plus any stack-specific SAST tooling found + +Print the table in the session too, and end with the single most +important fix if anything is red. diff --git a/plugins/code-modernization/commands/modernize-reimagine.md b/plugins/code-modernization/commands/modernize-reimagine.md index c16523ab..ce91724c 100644 --- a/plugins/code-modernization/commands/modernize-reimagine.md +++ b/plugins/code-modernization/commands/modernize-reimagine.md @@ -3,7 +3,11 @@ description: Multi-agent greenfield rebuild — extract specs from legacy, desig argument-hint: --- -**Reimagine** `legacy/$1` as: $2 +The first token of `$ARGUMENTS` is the system dir (`$1`); **everything +after it is the target vision** — it is usually multiple words, so do not +truncate it to one token. Below, `` means that full remainder. + +**Reimagine** `legacy/$1` as: This is not a port — it's a rebuild from extracted intent. The legacy system becomes the *specification source*, not the structural template. This command @@ -19,7 +23,8 @@ Spawn concurrently and show the user that all three are running: 2. **legacy-analyst** — "Catalog every external interface of legacy/$1: inbound (screens, APIs, batch triggers, queues) and outbound (reports, files, downstream calls, DB writes). For each: name, direction, payload - shape, frequency/SLA if discernible." + shape, frequency/SLA if discernible. Mask any credential embedded in + endpoints or payload examples per your secret-handling rules." 3. **legacy-analyst** — "Identify the core domain entities in legacy/$1 and their relationships. Return as an entity list + Mermaid erDiagram." @@ -32,6 +37,9 @@ Collect results. Write `analysis/$1/AI_NATIVE_SPEC.md` containing: - **Non-functional requirements** inferred from legacy (batch windows, volumes) - **Behavior Contract** (the Given/When/Then rules — these are the acceptance tests) +Credential values are masked everywhere in the spec; connection details +appear as env-var placeholders (`${DATABASE_URL}`), never literals. + ## Phase B — HITL checkpoint #1 Present the spec summary. Ask the user **one focused question**: "Which of @@ -40,20 +48,21 @@ should deliberately drop?" Wait for the answer. Record it in the spec. ## Phase C — Architecture (single agent, then critique) -Design the target architecture for "$2": +Design the target architecture for "": - Mermaid C4 Container diagram - Service boundaries with rationale (which rules/entities live where) - Technology choices with one-line justification each - Data migration approach from legacy stores Then spawn **architecture-critic**: "Review this proposed architecture for -$2 against the spec in analysis/$1/AI_NATIVE_SPEC.md. Identify over-engineering, + against the spec in analysis/$1/AI_NATIVE_SPEC.md. Identify over-engineering, missed requirements, scaling risks, and simpler alternatives." Incorporate the critique. Write the result to `analysis/$1/REIMAGINED_ARCHITECTURE.md`. ## Phase D — HITL checkpoint #2 -Enter plan mode. Present the architecture. Wait for approval. +Present the architecture and **stop — scaffold nothing until the user +explicitly approves** (use plan mode if the session supports it). ## Phase E — Parallel scaffolding @@ -65,7 +74,9 @@ in parallel**: and AI_NATIVE_SPEC.md. Create: project skeleton, domain model, API stubs matching the interface contracts, and **executable acceptance tests** for every behavior-contract rule assigned to this service (mark unimplemented ones as -expected-failure/skip with the rule ID). Write to modernized/$1-reimagined//." +expected-failure/skip with the rule ID). No credential literal from legacy +code becomes a test fixture or config default — use fake same-shape values +and env-var placeholders. Write to modernized/$1-reimagined//." Show the agents' progress. When all complete, run the acceptance test suites and report: total tests, passing (scaffolded behavior), pending (rule IDs @@ -77,7 +88,9 @@ Write `modernized/$1-reimagined/CLAUDE.md` — the persistent context file for the new system, containing: architecture summary, service responsibilities, where the spec lives, how to run tests, and the legacy→modern traceability map. This file IS the knowledge graph that future agents and engineers will -load. +load — and it gets committed: connection details and credentials appear +only as env-var names with a pointer to where they're provisioned, never +as values. Report: services scaffolded, acceptance tests defined, % behaviors with a home, location of all artifacts. diff --git a/plugins/code-modernization/commands/modernize-status.md b/plugins/code-modernization/commands/modernize-status.md new file mode 100644 index 00000000..d5fd7594 --- /dev/null +++ b/plugins/code-modernization/commands/modernize-status.md @@ -0,0 +1,54 @@ +--- +description: Where am I in the modernization workflow — artifact inventory, staleness, secrets hygiene, next step +argument-hint: +--- + +Report where the modernization of `$1` stands, in one screen. This is a +read-only command — inspect, never modify. + +## 1 — Artifact inventory + +Check `analysis/$1/` and `modernized/$1*/` and build a table — one row per +workflow stage, with the artifact's presence and modification time: + +| Stage | Artifacts | +|---|---| +| preflight | `PREFLIGHT.md` | +| assess | `ASSESSMENT.md`, `ARCHITECTURE.mmd` | +| map | `topology.json`, `TOPOLOGY.html`, `*.mmd`, `extract_topology.*` | +| extract-rules | `BUSINESS_RULES.md`, `DATA_OBJECTS.md` | +| brief | `MODERNIZATION_BRIEF.md` (note whether the approval block is signed) | +| harden | `SECURITY_FINDINGS.md`, `security_remediation.patch` | +| transform / reimagine | each `modernized/$1*//` dir — note test presence and whether `TRANSFORMATION_NOTES.md` exists | + +## 2 — Staleness + +Flag any artifact older than an upstream artifact it derives from: + +- `MODERNIZATION_BRIEF.md` older than `ASSESSMENT.md`, `topology.json`, + or `BUSINESS_RULES.md` → the brief no longer reflects discovery; + recommend re-running `/modernize-brief`. +- `TOPOLOGY.html` older than `topology.json` → re-run the injection step + from `/modernize-map`. +- Any `TRANSFORMATION_NOTES.md` older than `BUSINESS_RULES.md` → the + module may not implement the latest rule set; list which. + +## 3 — Secrets hygiene + +- Does `analysis/.gitignore` exist and cover `SECRETS.local.md` / + `*.local.patch`? (`git check-ignore` when in a git repo.) +- If `SECRETS.local.md` exists: confirm it is NOT tracked + (`git ls-files --error-unmatch`, expect failure) and has never been + committed (`git log --all --oneline -- `, expect empty). If + either check fails, say so prominently and recommend rotation plus + history scrubbing. + +## 4 — Verdict + +End with three lines: +- **Where you are** — the furthest completed stage and roughly how much + of the system it covers (e.g. "mapped 100%, 2 of 14 modules + transformed"). +- **What's stale** — or "nothing". +- **Next command** — the single most useful next step, with a one-line + reason. diff --git a/plugins/code-modernization/commands/modernize-transform.md b/plugins/code-modernization/commands/modernize-transform.md index 86ba4ef1..8183fd46 100644 --- a/plugins/code-modernization/commands/modernize-transform.md +++ b/plugins/code-modernization/commands/modernize-transform.md @@ -9,10 +9,37 @@ equivalence. This is a surgical, single-module transformation — one vertical slice of the strangler fig. Output goes to `modernized/$1/$2/`. -## Step 0 — Plan (HITL gate) +## Step 0a — Toolchain check (fail fast on target, adapt on legacy) + +Verify the build environment **before** planning, not when the tests +first run: + +- **Target stack ($3) — required.** Runtime, package manager, and test + framework all respond (`java -version` + `mvn -v`, `node -v` + `npm -v`, + `python3 -V` + `pytest --version`, …). If any are missing, stop and + report what to install — the new code and its tests cannot run without + them, so a plan gate now would just defer the failure an hour. Suggest + `/modernize-preflight $1 $3` for the full readiness report. +- **Legacy stack — advisory, never a blocker.** Try a syntax-only compile + of the module being transformed (e.g. `cobc -fsyntax-only`). Legacy + code often *cannot* build locally by nature, not by misconfiguration — + CICS/IMS programs have no local translator, and the real runtime may be + a mainframe you don't have. A failed or impossible legacy compile does + **not** stop the transform; it changes the equivalence strategy: + - dual-execution proof is off the table — characterization tests + assert against **recorded traces / golden-master fixtures** (real + production outputs, captured reports/screens, SME-confirmed + examples) instead of live legacy runs + - say so explicitly in the Step 0b plan and later in + TRANSFORMATION_NOTES.md ("equivalence is trace-based; legacy was not + executable in this environment"), so reviewers know the strength of + the proof they're approving + +## Step 0b — Plan (HITL gate) Read the source module and any business rules in `analysis/$1/BUSINESS_RULES.md` -that reference it. Then **enter plan mode** and present: +that reference it. Then present the plan and **stop — write no code until +the user explicitly approves** (use plan mode if the session supports it): - Which source files are in scope - The target module structure (packages/classes/files you'll create) - Which business rules / behaviors this module implements @@ -30,7 +57,9 @@ identify every observable behavior, and encode each as a test case with concrete input → expected output pairs derived from the legacy logic. Target framework: . Write to `modernized/$1/$2/src/test/`. These tests define 'done' — the new code -must pass all of them." +must pass all of them. Follow your secret-handling rules: no credential +literal from legacy code becomes a fixture; substitute fake same-shape +values and read anything genuinely live from environment variables." Show the user the test file. Get a 👍 before proceeding. @@ -68,6 +97,10 @@ Then show a visual diff of one representative behavior, legacy vs modern: ```bash delta --side-by-side <(sed -n 'p' legacy/$1/) modernized/$1/$2/src/main/ ``` +(Fall back to `diff -y --width=160` if `delta` isn't installed.) Never +pick a credential-bearing line range for this diff, and mask any +credential-like literal quoted in TRANSFORMATION_NOTES.md — the notes +live in `modernized/` and get committed. ## Step 5 — Architecture review