agentleFS
aws-solutionsaws-solutions/konductor/skills/legacy-to-agentic-estimate/SKILL.md

legacy-to-agentic-estimate

Skill11 starsChanged 50 days agoApache-2.0View on GitHub

Convert legacy all-human-coding effort estimates into agentic SDLC estimates that account for AI toolchains and agents. Use to convert legacy estimate(s), produce an agentic estimate, re-baseline LOE for AI, build an AI-assisted estimate, or do effort estimation from a legacy value plus a task description (single item or a batch/table). The tier is always inferred from the description (keyword first, model fallback for ambiguous cases); output is a banded low/mid/high Markdown table with a roll-up.

The file

Show its rules and text

We split this skill into the rules it gives an agent

25 rules. About 0 are common, 18 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈18

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use it to re-baseline an existing backlog without re-estimating every item by hand.

    line 19
  2. Very specific:

    Never apply the AI speedup to the invariant fraction — that is what (1 − v) protects.

    line 83
  3. Distinctive:

    Every item's tier comes from its description via a hybrid, two-stage classifier.

    line 99
  4. Very specific:

    If none matches, the block prints an error and exits 1 instead of running python3 against an empty path.

    line 139
  5. Distinctive:

    On failure: if any item lacks a description, ask the user to supply one for that item — do not guess or default it.

    line 148
  6. Distinctive:

    Run the deterministic Phase-1 seam.

    line 154
  7. Very specific:

    If a description is genuinely too vague, assign medium at a deliberately low confidence so the band widens.

    line 187
  8. Distinctive:

    Validate: all outputs positive; low ≤ mid ≤ high.

    line 216
  9. Distinctive:

    Add a brief interpretation calling out:

    line 244
  10. Distinctive:

    Always include the measured-vs-assumed caveat.

    line 255
  11. Distinctive:

    All four are a 40-unit task, showing how the same legacy number diverges by tier — and, in the fourth case, purely by capability maturity.

    line 259
  12. Distinctive:

    Treat the presets as a starting point and calibrate against reality:

    line 296
  13. Distinctive:

    Keep the input minimal: a legacy value and a description per item.

    line 321
  14. Distinctive:

    Use the hybrid classifier: keyword first (fast, deterministic), model fallback only for low-confidence items.

    line 323
  15. Very specific:

    Always emit a band (low/mid/high), never a single number.

    line 328
  16. Very specific:

    Treat capability maturity (C) as the dominant lever — the same task swings from big savings (−42%) to nearly break-even (−2%) purely by …

    line 329
  17. Very specific:

    Always include the caveat that L, τ, v, and C must be measured from your own cycle-time telemetry to be credible.

    line 332
  18. Distinctive:

    Don't accept an item with no description — raise/ask rather than defaulting a tier.

    line 337
  19. Distinctive:

    Don't collapse the method into a single "AI discount %" — it discards the tiering that keeps it honest.

    line 339
  20. Distinctive:

    Don't run the model classifier inside the sandboxed script — it has no network access.

    line 341
  21. Distinctive:

    Don't apply the AI speedup to the invariant fraction (review, integration, security) — it doesn't shrink.

    line 343
  22. Distinctive:

    Don't present low-leverage increases as errors — a novel/security task costing more is a correct result.

    line 345
  23. Distinctive:

    Don't treat the output as an oracle — its credibility rests entirely on parameters measured from your own history.

    line 347
  24. Distinctive:

    When an item arrives with no description — always ask.

    line 363
  25. Very specific:

    When many items land as inferred-llm at low confidence — offer to have the user confirm tiers before trusting the roll-up.

    line 364

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Legacy → Agentic Estimate Converter

Overview

This skill converts effort estimates produced under the legacy assumption that all code is authored and verified by a human into estimates that reflect developers working with AI toolchains and agents in an agentic SDLC. It works on a single estimate or a batch. Each item is just a legacy value plus a task description; the skill infers everything else and returns banded (low/mid/high) agentic estimates plus a roll-up and delta vs. legacy.

Use it to re-baseline an existing backlog without re-estimating every item by hand.

The most important output is not the converted number — it is that capability maturity is the dominant lever. Every mature, evaluator-backed capability you ship raises realized leverage (L_eff) and lowers the verification tax (τ). Treat this skill as a transitional tool, not an oracle: its credibility rests entirely on parameters measured from your own history.

Input contract

The input is deliberately minimal. Every item is { E_legacy, description }:

  • E_legacy — the legacy all-human estimate (required, numeric). A missing or non-numeric value is a validation error (InvalidELegacyError) — the agent will ask the user to clarify that row rather than failing with a stack trace.
  • description — a task description (required). The tier is derived from it. A missing or empty description is a validation error (MissingDescriptionError), not a silent default.
  • C — capability-maturity modifier (optional, decimal in (0, 1]). When supplied, it overrides the tier preset's default C for that item. Use this to express "high-leverage work, but no mature packaged capability yet" — the tier still infers v, L, and τ; only C is overridden. Values outside (0, 1] are a validation error with a friendly message.

There is no way to pass an explicit tier or to override v/L/τ — tiering stays honest and inferred from the description. An item with no description or a bad E_legacy value raises a clean error rather than silently defaulting.

Items are passed to the bundled script as a JSON array, e.g. [{"E_legacy": 24, "description": "Add CRUD endpoints for the settings API"}].

Per-item C override example (high-leverage work, immature capability): [{"E_legacy": 40, "description": "Add CRUD endpoints", "C": 0.20}]

Core method

A legacy estimate bundles two kinds of work that AI affects very differently. The conversion unbundles them and compresses only the AI-amenable part. The key intermediate is L_eff = L × C — leverage is realized only to the degree a mature, evaluator-backed capability actually exists:

E_agentic = E_legacy × [ (1 − v) + v × (1 − L_eff) ] × (1 + τ)     where  L_eff = L × C
SymbolMeaningTypical rangeSource
vvariable/authoring fraction of the legacy estimate (compressible)0.40–0.75measured from work-type history
Lleverage factor — AI compression of the variable part at full capability0.30–0.80measured from cycle-time telemetry
Ccapability-maturity modifier — how much of L is actually realized0.20–1.0maturity of the packaged capability
τverification-tax uplift — added review/validation overhead0.05–0.25measured; shrinks as evaluators mature
L_effeffective leverage = L × Cderivedrealized leverage given the capability's maturity

Agent-variable vs. agent-invariant work

The v fraction is the work AI actually compresses; the rest does not shrink.

  • Agent-variable (compressible): authoring, boilerplate, scaffolding, test-writing, docs.
  • Agent-invariant (does NOT shrink): requirements, review, integration, verification, security judgment, stakeholder alignment.

Never apply the AI speedup to the invariant fraction — that is what (1 − v) protects.

Tier presets (the profile applied once a tier is inferred):

TiervLτCCharacter
🟢 high0.700.750.100.90undifferentiated/patterned authoring: CRUD, boilerplate, scaffolding, migration
🟡 medium0.550.500.150.70clear intent, novel integration: integration, API, webhook
🔴 low0.350.300.200.50novel architecture / security / failover; high blast radius, little compressible content

The output is always a range, not a point — agentic work has higher oversight variance. The bundled convert_estimates.py script implements all of this.

Tier resolution (always inferred from the description)

Every item's tier comes from its description via a hybrid, two-stage classifier. There is no explicit-tier or assumed fallback path.

  1. Inferred (keyword) — the script classifies from weighted keyword signals (CRUD/boilerplate/migration/refactor → high; integration/API/webhook → medium; architecture/security/failover/novel → low), producing a tier + confidence + rationale. tier_source = inferred-kw.
  2. Inferred (model fallback) — when keyword confidence is below LLM_ESCALATION_THRESHOLD (0.55), the agent reads the description and classifies it against the tier definitions with judgment. tier_source = inferred-llm. This handles vocabulary the keyword list doesn't cover, or mixed-signal descriptions.

Confidence controls the band. Low-confidence classifications carry more uncertainty, so the band parameter widens as confidence drops (from ±15% _BASE_BAND at full confidence up to ±45% _MAX_BAND at zero confidence — these values perturb the formula inputs to compute the low/high corners; the realized output spread is narrower for low-leverage items and can be well below ±15% even at base confidence). Surface the guess, never hide it.

Why the model step lives in the agent, not the script: the bundled script is deterministic and sandboxed (stdlib only, no network/LLM access). It exposes a seam — prepare_batch flags low-confidence items, the agent classifies them, and finalize_batch merges the results. Deterministic math in the script; semantic judgment from the model; a clean handoff between them.

Why this matters: never silently convert a backlog at one blanket tier — that collapses into the "single AI discount %" anti-pattern. Inference + confidence + band-widening surfaces the guess instead of hiding it.

Workflow

The agent drives the bundled script with the Bash tool and python3, resolving the script path at runtime. Each command block below takes the first match of: ${CLAUDE_SKILL_DIR} (substituted by Claude Code for a plugin install and a .claude/skills/ install), a global Kiro CLI install (${SKILLS_HOME:-$HOME/.konductor/skills}), a project install at the git root (only with konductor's .konductor/manifest), then a konductor source checkout (only when .claude-plugin/marketplace.json names konductor). If none matches, the block prints an error and exits 1 instead of running python3 against an empty path. Every command block below is one that was run against this script.

Step 1 — Parse the input estimates

  • Normalize the input into a JSON array of items, each { E_legacy (numeric), description (non-empty) }. A single estimate is a one-item batch.
  • Validate that every item has BOTH a numeric legacy value AND a description.
  • On failure: if any item lacks a description, ask the user to supply one for that item — do not guess or default it. If a value is non-numeric, ask the user to clarify that row.

Step 2 — Resolve tiers (keyword) and find escalations

Run the deterministic Phase-1 seam. It validates descriptions, resolves each item's tier by keyword, and reports which items need model judgment.

ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
PROJECT="" CHECKOUT=""
[ -n "$ROOT" ] && [ -f "$ROOT/.konductor/manifest" ] && PROJECT="$ROOT/.konductor/skills/legacy-to-agentic-estimate"
[ -n "$ROOT" ] && grep -qs '"name": *"konductor"' "$ROOT/.claude-plugin/marketplace.json" && CHECKOUT="$ROOT/skills/legacy-to-agentic-estimate"
SCRIPT=""
for d in "${CLAUDE_SKILL_DIR}" "${SKILLS_HOME:-$HOME/.konductor/skills}/legacy-to-agentic-estimate" "$PROJECT" "$CHECKOUT"; do
  [ -n "$d" ] && [ -f "$d/scripts/convert_estimates.py" ] && { SCRIPT="$d/scripts/convert_estimates.py"; break; }
done
[ -n "$SCRIPT" ] || { echo "ERROR: convert_estimates.py not found; stopping" >&2; exit 1; }
python3 "$SCRIPT" \
  prepare --items '[{"E_legacy":30,"description":"Revamp the onboarding flow"}]'
  • Output: JSON { resolutions, needs_llm }. resolutions are the per-item keyword resolution dicts; needs_llm lists {index, description, kw_tier, kw_confidence} for items whose keyword confidence fell below 0.55.
  • A MissingDescriptionError (non-zero exit) means Step 1 let an item through without a description — go back and fix it.

Step 3 — Classify escalated items (model judgment)

For each entry in needs_llm, the agent (not the script) reads the description and decides tier (high/medium/low), a confidence (0–1), and a one-line rationale grounded in the tier definitions: high = undifferentiated / patterned authoring; medium = clear intent, novel integration; low = novel architecture, security, cross-system, high blast radius.

  • Produce llm_results: a list of {index, tier, confidence, rationale}, one per needs_llm entry.
  • If a description is genuinely too vague, assign medium at a deliberately low confidence so the band widens.
  • Skip when needs_llm is empty — go straight to Step 4 (or use the keyword-only shortcut in the note below).

Step 4 — Finalize the conversion

Merge the agent's judgment back in and compute the bands.

ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
PROJECT="" CHECKOUT=""
[ -n "$ROOT" ] && [ -f "$ROOT/.konductor/manifest" ] && PROJECT="$ROOT/.konductor/skills/legacy-to-agentic-estimate"
[ -n "$ROOT" ] && grep -qs '"name": *"konductor"' "$ROOT/.claude-plugin/marketplace.json" && CHECKOUT="$ROOT/skills/legacy-to-agentic-estimate"
SCRIPT=""
for d in "${CLAUDE_SKILL_DIR}" "${SKILLS_HOME:-$HOME/.konductor/skills}/legacy-to-agentic-estimate" "$PROJECT" "$CHECKOUT"; do
  [ -n "$d" ] && [ -f "$d/scripts/convert_estimates.py" ] && { SCRIPT="$d/scripts/convert_estimates.py"; break; }
done
[ -n "$SCRIPT" ] || { echo "ERROR: convert_estimates.py not found; stopping" >&2; exit 1; }
python3 "$SCRIPT" \
  finalize \
  --items '[{"E_legacy":30,"description":"Revamp the onboarding flow"}]' \
  --resolutions '[{"tier":"medium","tier_source":"inferred-kw","confidence":0.0,"rationale":"no tiering keywords found","needs_llm":true,"description":"Revamp the onboarding flow"}]' \
  --llm-results '[{"index":0,"tier":"medium","confidence":0.6,"rationale":"clear intent, UI rework over existing flow"}]'

Pass --llm-results null (or []) when Step 3 was skipped. --resolutions is the array printed by prepare.

  • Validate: all outputs positive; low ≤ mid ≤ high; low-leverage items may exceed the legacy value (expected — not an error).
  • Note: for a keyword-only run with no escalations, convert does Steps 2 + 4 in one call (it wraps convert_batch → render_markdown):
ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
PROJECT="" CHECKOUT=""
[ -n "$ROOT" ] && [ -f "$ROOT/.konductor/manifest" ] && PROJECT="$ROOT/.konductor/skills/legacy-to-agentic-estimate"
[ -n "$ROOT" ] && grep -qs '"name": *"konductor"' "$ROOT/.claude-plugin/marketplace.json" && CHECKOUT="$ROOT/skills/legacy-to-agentic-estimate"
SCRIPT=""
for d in "${CLAUDE_SKILL_DIR}" "${SKILLS_HOME:-$HOME/.konductor/skills}/legacy-to-agentic-estimate" "$PROJECT" "$CHECKOUT"; do
  [ -n "$d" ] && [ -f "$d/scripts/convert_estimates.py" ] && { SCRIPT="$d/scripts/convert_estimates.py"; break; }
done
[ -n "$SCRIPT" ] || { echo "ERROR: convert_estimates.py not found; stopping" >&2; exit 1; }
python3 "$SCRIPT" \
  convert --items '[{"E_legacy":24,"description":"Add CRUD endpoints and DTOs for the settings API"},{"E_legacy":60,"description":"Design multi-region failover architecture for the datastore"}]'

Step 5 — Render the output

The convert and finalize subcommands already print the Markdown table (render_markdown with show_source=True, so the "Tier source" column shows kw vs. llm and the confidence). Present that table plus a totals row. Markdown is the only output — there is no Excel/workbook path.

Step 6 — Explain and caveat

Add a brief interpretation calling out:

  • (a) savings concentrate in high-leverage work backed by a mature capability;
  • (b) low-leverage items can cost more — a novel/security task costing more is a correct result, not an error;
  • (c) which tiers were escalated to model judgment (inferred-llm) and should be reviewed;
  • (d) that L, τ, v, and C must be recalibrated from the team's own telemetry to be credible.

Always include the measured-vs-assumed caveat; always flag escalated rows.

Worked examples

All four are a 40-unit task, showing how the same legacy number diverges by tier — and, in the fourth case, purely by capability maturity.

Scenariov / L / τ / CLow / Mid / HighΔ (mid)
high + mature capability0.70 / 0.75 / 0.10 / 0.9019.8 / 23.2 / 26.7−42%
medium / novel integration0.55 / 0.50 / 0.15 / 0.7035.1 / 37.1 / 39.2−7%
low / novel arch + security0.35 / 0.30 / 0.20 / 0.5044.0 / 45.5 / 47.0+14% (low-leverage costs MORE)
high tier but NO packaged capability yet0.70 / 0.75 / 0.10 / 0.2038.2 / 39.4 / 40.6−2% (C dropped 0.90 → 0.20; τ stays at 0.10)

The fourth case is the headline: the same high-tier task swings from −42% to −2% purely by dropping C from 0.90 to 0.20, with τ held constant at the tier default. A ~40-point swing in the delta, driven entirely by capability maturity. Capability maturity dominates.

Note: the methodology's fully-unpackaged scenario additionally recalibrates the verification tax τ at the tier level (0.10→0.15), which is what pushes a fully-unpackaged high-leverage task into net-penalty territory. τ is a tier-level calibration, not a per-item input, so the per-item C override alone does not cross into penalty territory — it collapses the savings without reversing them.

Output

A Markdown table of converted estimates (the "Tier source" column shows how each tier was reached), with a totals roll-up row:

ItemLegacyTierTier sourceLowMidHighΔ (mid)
Add CRUD endpoints for settings API24🟢 highinferred·kw (82%)11.213.916.8−42%
Design multi-region failover arch.60🔴 lowinferred·kw (100%)6668.270.5+14%
Total84…………

Plus a short interpretation and the recalibration caveat.

Operationalization lifecycle

Treat the presets as a starting point and calibrate against reality:

  1. Seed conservative — start with the default presets (lower C, higher τ) until you have data.
  2. Feed {legacy, description} items for the work you are re-baselining.
  3. Convert through the prepare → classify → finalize seam.
  4. Track actual effort vs. predicted per item.
  5. Recalibrate v / L / τ / C per work-type from your own cycle-time telemetry.
  6. Repeat — the estimates get more credible as the parameters converge on your history.

Guardrails

  • Weight the tail. Agents accelerate the first ~90%; the last 10% (integration, edge cases, prod-hardening) can grow. That growth lives in τ — don't zero it out.
  • Account for skill dispersion. Realized leverage depends on how well a developer drives the agent; expect per-developer variance. The band reflects oversight variance, not a promise.

Lessons Learned

Do

  • Keep the input minimal: a legacy value and a description per item. The description is required — the whole method hinges on inferring the tier from it.
  • Use the hybrid classifier: keyword first (fast, deterministic), model fallback only for low-confidence items. Don't spend model judgment when the keyword signal is already strong.
  • Surface the guess — always show tier source (kw/llm) and confidence, and widen the band when confidence is low.
  • Always emit a band (low/mid/high), never a single number.
  • Treat capability maturity (C) as the dominant lever — the same task swings from big savings (−42%) to nearly break-even (−2%) purely by dropping C, with τ still held at the tier default.
  • Always include the caveat that L, τ, v, and C must be measured from your own cycle-time telemetry to be credible.

Don't

  • Don't accept an item with no description — raise/ask rather than defaulting a tier.
  • Don't collapse the method into a single "AI discount %" — it discards the tiering that keeps it honest.
  • Don't run the model classifier inside the sandboxed script — it has no network access. Use the prepare → classify → finalize seam.
  • Don't apply the AI speedup to the invariant fraction (review, integration, security) — it doesn't shrink.
  • Don't present low-leverage increases as errors — a novel/security task costing more is a correct result.
  • Don't treat the output as an oracle — its credibility rests entirely on parameters measured from your own history.

Common Failures

  • Item missing a description → MissingDescriptionError (non-zero exit); go back to Step 1 and ask the user for the description.
  • Ambiguous description, no keyword hit → prepare flags it in needs_llm; classify it in Step 3. If skipped, it stays medium at a wide band (safe, just less precise).
  • Non-numeric legacy value → ask the user to clarify only that row.
  • Malformed JSON in --items → the CLI exits non-zero with a parse error; re-check the array shape and quoting.

When to Ask the User

  • When an item arrives with no description — always ask; never default.
  • When many items land as inferred-llm at low confidence — offer to have the user confirm tiers before trusting the roll-up.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.