code-modernization: COCOMO is a complexity index, never a modernization timeline

COCOMO's constants encode human-team productivity; presenting its
person-months as how long an agentic modernization will take (or cost) is
a claim we should not make. Reframe COCOMO everywhere as a RELATIVE
complexity/scale index for ranking and sequencing systems only:

- assess: capture COCOMO as a complexity index; explicitly ignore scc's
  'Estimated Schedule Effort' and cost-in-dollars; ASSESSMENT 'Effort
  Estimation' section becomes 'Relative Scale' with a not-a-timeline note;
  portfolio heat-map column renamed Complexity (COCOMO index).
- brief: phase plan uses relative T-shirt sizing, not person-months/weeks;
  phases render as a dependency flowchart, not a gantt (gantt = calendar).
- portfolio-assess.js: field cocomoPm -> complexityIndex; return label
  carries the not-a-duration caveat.
- README: 'A note on COCOMO' explains the index framing and points at
  better intrinsic-complexity proxies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Morgan Westlee Lunt 2026-06-09 21:21:50 +00:00
parent d44da81146
commit e5939029ec
No known key found for this signature in database
5 changed files with 46 additions and 20 deletions

View File

@ -40,7 +40,7 @@ to direct subagent fan-out on older builds — no configuration needed.
|---|---|
| `/modernize-extract-rules` | Extraction loops until two consecutive rounds find nothing new; every rule's `file:line` citation is verified by an independent referee before entering the catalog; P0 rules face a two-judge panel before they can anchor the behavior contract. |
| `/modernize-harden` | Five class-scoped finders in parallel; every finding is adversarially refuted (Critical/High double-judged), so false positives die before `SECURITY_FINDINGS.md`. |
| `/modernize-assess --portfolio` | One survey agent per system, pipelined independently; COCOMO computed uniformly in code; crashed sweeps resume from cache. |
| `/modernize-assess --portfolio` | One survey agent per system, pipelined independently; the COCOMO complexity index computed uniformly in code; crashed sweeps resume from cache. |
| `/modernize-reimagine` (Phase E) | The 3-service scaffolding cap is lifted — the runtime queues one agent per approved service. |
These fan out more agents than the fallback path (tens, on a large estate) —
@ -86,7 +86,9 @@ The commands are designed to be run in order, but each produces a standalone art
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/<system>/PREFLIGHT.md` with a per-command Ready / Ready-with-gaps / Not-ready verdict.
### `/modernize-assess <system-dir>` — or — `/modernize-assess --portfolio <parent-dir>`
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/<system>/ASSESSMENT.md` and `analysis/<system>/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`.
Inventory the legacy codebase: languages, line counts, complexity, build system, integrations, technical debt, security posture, documentation gaps, and a COCOMO-derived **relative complexity index** (a size/scale signal for ranking systems — explicitly *not* a modernization timeline or cost; see "A note on COCOMO" below). Produces `analysis/<system>/ASSESSMENT.md` and `analysis/<system>/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`.
> **A note on COCOMO.** Both `assess` modes derive a COCOMO-II figure from code size. This plugin uses it **only as a relative complexity/scale index** — to rank and sequence systems and to size the legacy estate. It is deliberately **not** presented as a modernization timeline or cost, and the commands are instructed never to convert it to person-months, weeks, dates, or dollars. COCOMO's constants encode historical human-team productivity; agentic transformation does not follow those curves, so any duration derived from it would be wrong. If you have a better intrinsic-complexity proxy (cyclomatic-complexity density, coupling/fan-out, the topology's edge density, or the count of extracted P0 business rules), prefer it — COCOMO is the portable default, not the ceiling.
### `/modernize-map <system-dir>`

View File

@ -1,5 +1,5 @@
---
description: Full discovery & portfolio analysis of a legacy system — inventory, complexity, debt, effort estimation
description: Full discovery & portfolio analysis of a legacy system — inventory, complexity, debt, relative scale
argument-hint: <system-dir> [--show-secrets] | --portfolio <parent-dir>
---
@ -62,11 +62,19 @@ cyclomatic complexity (CCN). For dependency freshness, locate the
manifest (`package.json`, `pom.xml`, `*.csproj`, `requirements*.txt`,
copybook dir) and note its age / pinned-version count.
## Step P2 — COCOMO-II effort
## Step P2 — COCOMO-II complexity index
Compute person-months per system using COCOMO-II basic:
`PM = 2.94 × (KSLOC)^1.10` (nominal scale factors). Show the formula and
inputs so the figure is defensible, not a guess.
Compute the COCOMO-II basic figure per system: `2.94 × (KSLOC)^1.10`
(nominal scale factors). Show the formula and inputs so it is defensible,
not a guess.
**Use this only as a relative complexity/scale index** for ranking and
sequencing systems — bigger number = bigger, more complex estate. **It is
not a modernization timeline or cost.** The COCOMO person-month figure
assumes traditional human-team productivity; agentic transformation does
not follow those productivity curves, so do not present it (or convert it)
as how long the work will take or what it will cost. Label the column as an
index, not "person-months", and never attach a date or duration to it.
## Step P3 — Documentation coverage
@ -79,7 +87,7 @@ Report coverage % and the top undocumented subsystems.
Write `analysis/portfolio.html` (dark `#1e1e1e` bg, `#d4d4d4` text,
`#cc785c` accent, system-ui font, all CSS inline). One row per system;
columns: **System · Lang · KSLOC · Files · Mean CCN · Max CCN · Dep
Freshness · Doc Coverage % · COCOMO PM · Risk**. Color-grade the PM and
Freshness · Doc Coverage % · Complexity (COCOMO index) · Risk**. Color-grade the index and
Risk cells (green→amber→red). Below the table, a 2-3 sentence
sequencing recommendation: which system first and why.
@ -101,11 +109,15 @@ Run and show the output of:
scc legacy/$1
```
Then run `scc --by-file -s complexity legacy/$1 | head -25` to identify the
highest-complexity files. Capture the COCOMO effort/cost estimate scc provides.
highest-complexity files. Capture scc's COCOMO figure **only as a relative
complexity/scale index** — and **ignore scc's "Estimated Schedule Effort"
and cost-in-dollars lines**: those project a human-team timeline and budget,
which are invalid for agentic modernization (see the not-a-timeline note in
Step 6).
If `scc` is not installed, fall back in order:
1. `cloc legacy/$1` for the LOC table, then compute COCOMO-II effort
yourself: `PM = 2.94 × (KSLOC)^1.10` (nominal scale factors). Show the
1. `cloc legacy/$1` for the LOC table, then compute the COCOMO-II index
yourself: `2.94 × (KSLOC)^1.10` (nominal scale factors). Show the
inputs.
2. If `cloc` is also missing, use `find` + `wc -l` grouped by extension
for LOC, and rank file complexity by counting decision keywords
@ -208,7 +220,7 @@ Create `analysis/$1/ASSESSMENT.md` with these sections:
- **Technical Debt** (top 10, ranked)
- **Security Findings** (CWE table)
- **Documentation Gaps** (top 5)
- **Effort Estimation** (COCOMO-derived person-months, ±range, key cost drivers)
- **Relative Scale** (the COCOMO-II index + KSLOC as a complexity/scale signal for ranking this system against others. **Not a timeline:** state plainly that this is a relative size measure, not an estimate of how long modernization will take or what it will cost — it assumes traditional human-team productivity, which agentic transformation does not follow. Do not print person-months, a schedule, a cost, or a date.)
- **Recommended Modernization Pattern** (one of: Rehost / Replatform / Refactor / Rearchitect / Rebuild / Replace — with one-paragraph rationale)
Also create `analysis/$1/ARCHITECTURE.mmd` containing the Mermaid domain

View File

@ -40,11 +40,18 @@ 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-months, same unit as the assessment's COCOMO
figure — convert deliberately if you present weeks)
- Relative scale (T-shirt size — S/M/L/XL — anchored to the phase's share
of the assessment's COCOMO complexity index. This ranks phases by size
against each other; it is **not** a duration. Do **not** state
person-months, weeks, calendar dates, or a delivery estimate — agentic
transformation does not follow the human-team productivity curves those
units assume, so any time figure here would be misleading.)
- Risk level + top 2 risks + mitigation
Render the phases as a Mermaid `gantt` chart.
Render the phases as a Mermaid `flowchart LR` showing **sequence and
dependencies** (Phase 1 → Phase 2 → …, with branches where phases are
independent). Do **not** use a `gantt` chart — gantt encodes calendar
durations, and this plan deliberately makes no time claims.
### 4. Business Walkthroughs
For each persona flow in `analysis/$1/topology.json` (`flows` — produced

View File

@ -27,7 +27,7 @@ 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 |
| `scc` (or `cloc`) | assess | LOC/complexity fall back to `find`+`wc`; the COCOMO complexity index 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` |

View File

@ -82,17 +82,22 @@ if (failed.length) {
}
// COCOMO-II basic, computed here so every row uses the identical formula:
// PM = 2.94 × (KSLOC)^1.10 (nominal scale factors).
// 2.94 × (KSLOC)^1.10 (nominal scale factors). This is a RELATIVE
// complexity/scale index for ranking systems — NOT a duration or cost.
// The calling command must render it as an index and never convert it to
// person-months / weeks / dates (agentic transformation breaks COCOMO's
// human-team productivity assumptions).
for (const r of surveyed) {
const ksloc = r.sloc / 1000
r.cocomoPm = Math.round(2.94 * Math.pow(ksloc, 1.1) * 10) / 10
r.complexityIndex = Math.round(2.94 * Math.pow(ksloc, 1.1) * 10) / 10
}
surveyed.sort((a, b) => b.cocomoPm - a.cocomoPm)
surveyed.sort((a, b) => b.complexityIndex - a.complexityIndex)
return {
parentDir,
rows: surveyed,
unmeasured: failed,
formula: 'PM = 2.94 × (KSLOC)^1.10 (COCOMO-II basic, nominal scale factors) — computed by the workflow, not estimated by agents',
complexityIndexFormula:
'2.94 × (KSLOC)^1.10 (COCOMO-II basic, nominal scale factors) — a RELATIVE complexity/scale index for ranking systems, computed by the workflow. NOT a duration or cost: do not render it as person-months/weeks/dates; agentic transformation does not follow COCOMO human-team productivity.',
}