Compare commits

...

192 Commits

Author SHA1 Message Date
Mohamed Hegazy
e7fe15d9ba security-guidance: pip --target fallback when venv can't bootstrap pip (2.0.4 → 2.0.5)
Option A, the data-gated fix for venv_ensurepip_fail (#2154 follow-up).

v2.0.4 telemetry made the call: of the venv_ensurepip_fail cohort, ~95%
HAVE pip (sdk_has_pip=true) and run Python 3.11–3.14 — so it's not the
Apple-3.9 problem; it's modern interpreters where `python -m venv` can't
bootstrap pip (Debian python3-venv absent, or python.org/pyenv builds
without ensurepip) but pip itself works. `pip install --target` needs only
pip, so it recovers the agentic reviewer for them instead of degrading to
pattern + single-shot review.

Producer (ensure_agent_sdk.py):
  - New outcomes BUILT_TARGET=7, NOOP_TARGET=8; new phase pip_target=5.
  - _build_via_target(): `pip install --target <state>/agent-sdk-libs
    --upgrade --prefer-binary claude-agent-sdk`. Failures categorized via
    _pip_err_from_stderr (sibling of main()'s pip chain — kept separate to
    avoid disturbing the working venv categorizer); errno embedded for
    OSError-family exceptions.
  - _target_sdk_importable(): probes a prior target install → NOOP_TARGET.
    Dir-check short-circuits before any subprocess, and it's only reached
    when there's no working venv, so the 81% NOOP_VENV cohort never pays.
  - main() falls through to the target build ONLY on venv_ensurepip_fail;
    every other venv/pip failure stays terminal BUILD_FAILED. The sentinel
    is released before the target build so a retry isn't seen as SKIP_SENTINEL.

Consumer (llm.py):
  - _inject_agent_sdk_venv_into_syspath() adds the flat agent-sdk-libs dir
    (packages sit directly in it, not under site-packages). The existing
    pywin32 .pth bootstrap applies (target installs don't run .pth either).

No change to the happy path — the new branch is taken only on the
ensurepip failure, and the extra candidate dir is a no-op when absent.

Verified locally on macOS Python 3.13:
  - py_compile clean.
  - 30 new tests (test_venv_target_fallback.py): outcome/phase codes
    (append-only, 4 stays retired), _pip_err_from_stderr categories,
    _build_via_target success/CalledProcessError/timeout/exc+errno (mocked
    subprocess), _target_sdk_importable dir-short-circuit, main() wiring
    (ensurepip→target fallthrough + NOOP_TARGET probe + sentinel release),
    consumer adds the flat dir. Full suite 533/533 pass + 2 skipped.
  - END-TO-END harness (real install, simulated ensurepip failure):
    main() → BUILT_TARGET, target dir has claude_agent_sdk; 2nd run →
    NOOP_TARGET; consumer _inject → `import claude_agent_sdk` resolves
    FROM the --target dir. Full chain proven without needing a
    broken-ensurepip box.
  - Real `pip install --target` + import confirmed independently (exit 0,
    SDK imports from the flat layout).

NOT validated in tmux: the ensurepip failure can't be reproduced on macOS
(working ensurepip), so the fallback was proven via the real-install
harness above instead. The happy path (NOOP_VENV / normal agentic review)
is unchanged and covered by the existing hook-smoke suite.

Version 2.0.4 -> 2.0.5 per the per-PR-bump policy (#2114).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-11 23:31:55 -07:00
github-actions[bot]
e97f9a40b9 bump(zapier): 770167c5 → ea8ed6b4 (#2695)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-12 00:46:01 -05:00
github-actions[bot]
78fa3df8d6 bump(sentry-cli): a5f26c33 → a55d2a80 (#2675)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:30:11 -05:00
github-actions[bot]
56fd6abb97 bump(auth0): bdf0dc23 → b595bdb9 (#2652)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:23:13 -05:00
github-actions[bot]
c9b8f92b53 bump(cloudflare): c5b7b06b → 12520fd6 (#2662)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:23:04 -05:00
github-actions[bot]
7279412e77 bump(aws-startup-advisor): 3c5d6a7d → 944e5b17 (#2656)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:22:24 -05:00
github-actions[bot]
484653886e bump(chrome-devtools-mcp): 4f8eb7ad → 228cf393 (#2661)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:21:59 -05:00
github-actions[bot]
c7af5e02bc bump(carta-investors): fd503bbc → ab95e738 (#2660)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:21:23 -05:00
github-actions[bot]
8ea0761c82 bump(nvidia-skills): 24806dbd → 071d2fe0 (#2672)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:20:57 -05:00
github-actions[bot]
600c99b404 bump(knowledge-catalog): 8aa886f1 → b3df58e8 (#2667)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:20:31 -05:00
github-actions[bot]
d28241b7ef bump(netlify-skills): 99b990ce → c594226e (#2671)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:20:03 -05:00
github-actions[bot]
46c72e981f bump(huggingface-skills): d7223848 → 7bf59b7f (#2665)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:19:35 -05:00
github-actions[bot]
3f8fc630b8 bump(codspeed): 7e86f11b → 41f4db99 (#2663)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:19:24 -05:00
github-actions[bot]
fbd57be8e5 bump(carta-cap-table): fd503bbc → ab95e738 (#2659)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:19:01 -05:00
github-actions[bot]
413d293096 bump(aikido): 79ac524f → 603d5eac (#2651)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:18:48 -05:00
github-actions[bot]
e4a454a7eb bump(crowdstrike-falcon-foundry): 7e73f691 → a7e6a75a (#2664)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:18:13 -05:00
github-actions[bot]
d30ef44d74 bump(migration-to-aws): 3c5d6a7d → 944e5b17 (#2670)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:17:40 -05:00
github-actions[bot]
6ee4f1e1df bump(aws-agents): e089489e → f5ba8108 (#2653)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:17:08 -05:00
github-actions[bot]
c4b91a6e24 bump(aws-core): e089489e → f5ba8108 (#2654)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:16:34 -05:00
github-actions[bot]
e656f87725 bump(brightdata-plugin): bd5bd76b → 8d427e98 (#2658)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:16:00 -05:00
github-actions[bot]
eaa69c48cb bump(looker): e912c034 → ef389645 (#2668)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:15:46 -05:00
github-actions[bot]
46dc6920be bump(bigdata-com): 67c30be9 → 76a043a0 (#2657)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:15:40 -05:00
github-actions[bot]
92954b1b92 bump(hyperframes): 83662c11 → c52165d1 (#2666)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:15:12 -05:00
github-actions[bot]
0784122e63 bump(lusha): 8fc71d54 → affbc76b (#2669)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:14:59 -05:00
github-actions[bot]
7465bdcc27 bump(oracle-ai-data-platform-workbench-spark-connectors): 00cedef3 → deadf8f8 (#2673)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:13:58 -05:00
github-actions[bot]
7209a2ca09 bump(sap-fiori-mcp-server): 372f7644 → cf2d1ef7 (#2674)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:13:14 -05:00
github-actions[bot]
71941bb301 bump(aws-data-analytics): e089489e → f5ba8108 (#2655)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:12:28 -05:00
github-actions[bot]
eeb3316d51 bump(wix): 8cbffb9c → def21835 (#2676)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 13:11:57 -05:00
github-actions[bot]
66bca6b6f6 bump(data-agent-kit-starter-pack): c125eaea → 6f60c83a (#2639)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:54:40 -05:00
github-actions[bot]
be8b438e1a bump(sap-fiori-mcp-server): 67ad23a4 → 372f7644 (#2646)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:54:18 -05:00
github-actions[bot]
43297b9419 bump(aws-data-analytics): c0991f46 → e089489e (#2637)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:53:56 -05:00
github-actions[bot]
b110a96045 bump(crowdstrike-falcon-foundry): 2f34384c → 7e73f691 (#2638)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:53:33 -05:00
github-actions[bot]
9087f2c348 bump(databases-on-aws): f985fddc → 58373593 (#2640)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:53:08 -05:00
github-actions[bot]
9277728768 bump(deploy-on-aws): f985fddc → 58373593 (#2641)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:52:43 -05:00
github-actions[bot]
5518e4b87d bump(aws-agents): c0991f46 → e089489e (#2635)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:52:17 -05:00
github-actions[bot]
2bf67d3cfd bump(aws-core): c0991f46 → e089489e (#2636)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:51:51 -05:00
github-actions[bot]
c5fd33161c bump(knowledge-catalog): 317e96fd → 8aa886f1 (#2643)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:51:23 -05:00
github-actions[bot]
2b58efffc3 bump(quarkus-agent): f5c0dd4c → 0ecd6237 (#2644)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:50:53 -05:00
github-actions[bot]
f4cf218b9b bump(atlan): 789507c0 → 86bb1ad2 (#2634)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:50:26 -05:00
github-actions[bot]
db5b3d5999 bump(hyperframes): 868c56fd → 83662c11 (#2642)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:49:58 -05:00
github-actions[bot]
5316ced830 bump(railway): 72299c62 → 836d42c1 (#2645)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:49:29 -05:00
github-actions[bot]
13ac3cb075 bump(wix): cda44c29 → 8cbffb9c (#2647)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:48:59 -05:00
github-actions[bot]
5a20d10780 bump(zscaler): f84ce4f0 → a2162c38 (#2648)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-11 07:48:28 -05:00
github-actions[bot]
9eae436aa2 bump(valtown): 02631f99 → 1f792839 (#2633)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:15:46 -05:00
github-actions[bot]
ee7ce490f9 bump(carta-cap-table): 4b579651 → fd503bbc (#2622)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:15:09 -05:00
github-actions[bot]
460bc2b3a4 bump(crowdstrike-falcon-foundry): 57ae73b4 → 2f34384c (#2625)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:14:47 -05:00
github-actions[bot]
1a7db730cb bump(snowflake-cortex-code): 7d2c7e7e → 5a8f277f (#2632)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:14:25 -05:00
github-actions[bot]
3ebb9c7a85 bump(aws-amplify): f985fddc → 58373593 (#2620)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:14:03 -05:00
github-actions[bot]
9ef08d32aa bump(aws-serverless): f985fddc → 58373593 (#2621)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:13:39 -05:00
github-actions[bot]
b8e4462957 bump(carta-investors): 4b579651 → fd503bbc (#2624)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:13:13 -05:00
github-actions[bot]
2f9c3234ab bump(firestore-native): f88103bd → d7f42424 (#2626)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:12:47 -05:00
github-actions[bot]
c5660ed060 bump(netlify-skills): 22025ef6 → 99b990ce (#2628)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:12:22 -05:00
github-actions[bot]
9ecfe41bdd bump(sagemaker-ai): f985fddc → 58373593 (#2630)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:11:56 -05:00
github-actions[bot]
d5265b0377 bump(amplitude): e9b4e151 → fb22979d (#2619)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:11:30 -05:00
github-actions[bot]
c7f3eb4b8f bump(hyperframes): 8fcbb63a → 868c56fd (#2627)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:11:02 -05:00
github-actions[bot]
3b46b04964 bump(outputai): f8d698ea → be9352cb (#2629)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:10:30 -05:00
github-actions[bot]
a379ddd580 bump(sanity): be762f2f → 2d7b7c08 (#2631)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:09:49 -05:00
github-actions[bot]
8a0797c1eb bump(42crunch-api-security-testing): b7e131e3 → 5cfa510f (#2617)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:09:25 -05:00
github-actions[bot]
447aef7de0 bump(amazon-location-service): f985fddc → 58373593 (#2618)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:08:42 -05:00
github-actions[bot]
7e9d5e46d1 bump(deploy-on-aws): b13ce7f0 → f985fddc (#2595)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:07:53 -05:00
github-actions[bot]
14e6461b03 bump(databases-on-aws): b13ce7f0 → f985fddc (#2594)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 19:07:37 -05:00
Mohamed Hegazy
634ea8dfdf Merge pull request #2313 from anthropics/exc-failure-encoding
security-guidance: encode exception type + errno + ensurepip instrumentation for venv BUILD_FAILED (#2154 follow-up) — 2.0.3 → 2.0.4
2026-06-10 14:28:05 -07:00
github-actions[bot]
fa5b2907d3 bump(qt-development-skills): a7189a7b → 2be55aaf (#2604)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:30:13 -05:00
github-actions[bot]
f0a6e581ab bump(carta-crm): 4b60ca66 → 4b579651 (#2589)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:24:12 -05:00
github-actions[bot]
820c25f30e bump(carta-investors): 4b60ca66 → 4b579651 (#2590)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:23:59 -05:00
github-actions[bot]
62e1eee8ba bump(pydantic-ai): ddc7d005 → 1e7a4567 (#2603)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:23:30 -05:00
github-actions[bot]
1266fa54fe bump(sagemaker-ai): d8243e5f → f985fddc (#2605)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:23:01 -05:00
github-actions[bot]
662eb2a84d bump(sentry-cli): 18111b95 → a5f26c33 (#2609)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:22:31 -05:00
github-actions[bot]
b9fcf71aa3 bump(togetherai-skills): 8aa08ca1 → 86bdd662 (#2610)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:21:59 -05:00
github-actions[bot]
276c66d983 bump(figma): 54ad1560 → 2efd0e37 (#2597)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:21:27 -05:00
github-actions[bot]
96627692d8 bump(hyperframes): 81416ab3 → 8fcbb63a (#2598)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:20:56 -05:00
github-actions[bot]
2dad4fb0e9 bump(logfire): ddc7d005 → 1e7a4567 (#2599)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:20:24 -05:00
github-actions[bot]
764c85b81b bump(neon): 9695a225 → 58b84dfb (#2600)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:19:50 -05:00
github-actions[bot]
0fc58e49d1 bump(posthog): db4a8663 → f674efef (#2602)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:19:17 -05:00
github-actions[bot]
14207a6858 bump(sap-fiori-mcp-server): 81b88637 → 67ad23a4 (#2607)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:18:27 -05:00
github-actions[bot]
51081f898a bump(amazon-location-service): b13ce7f0 → f985fddc (#2584)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:17:53 -05:00
github-actions[bot]
c6cd307f91 bump(save-to-spotify): cd4ea681 → a62408bc (#2608)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:17:46 -05:00
github-actions[bot]
1f41ee16b7 bump(ui5-typescript-conversion): 6d72751f → 80f2d932 (#2612)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:17:12 -05:00
github-actions[bot]
0590b22bed bump(aws-amplify): b13ce7f0 → f985fddc (#2585)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:16:35 -05:00
github-actions[bot]
c0e06a05f0 bump(aws-serverless): b13ce7f0 → f985fddc (#2586)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:15:58 -05:00
github-actions[bot]
cb3f6930c7 bump(crowdstrike-falcon-foundry): 0a651a14 → 57ae73b4 (#2592)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:15:43 -05:00
github-actions[bot]
481d531f7d bump(base44): ec420cf2 → aef0fa35 (#2587)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:15:26 -05:00
github-actions[bot]
9d53eaee3b bump(outputai): 83742db5 → f8d698ea (#2601)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:15:19 -05:00
github-actions[bot]
887f70cb5d bump(codspeed): c6112f16 → 7e86f11b (#2591)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:15:13 -05:00
github-actions[bot]
a96db3dd4d bump(dash0): 5ff7aa5b → 37fd498b (#2593)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:14:43 -05:00
github-actions[bot]
5a4b44267a bump(expo): c3886024 → 1a5693e0 (#2596)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:14:04 -05:00
github-actions[bot]
627d4dd3c4 bump(carta-cap-table): 4b60ca66 → 4b579651 (#2588)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:13:37 -05:00
github-actions[bot]
4902efd113 bump(sanity): 66f0ec5d → be762f2f (#2606)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 13:13:17 -05:00
github-actions[bot]
cf6decf9e8 bump(data-agent-kit-starter-pack): b47cae53 → c125eaea (#2571)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:59:42 -05:00
github-actions[bot]
088593ec3b bump(sap-fiori-mcp-server): b9127510 → 81b88637 (#2576)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:59:20 -05:00
github-actions[bot]
206d02f684 bump(carta-cap-table): 7b4e568d → 4b60ca66 (#2568)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:58:57 -05:00
github-actions[bot]
e2be9a8197 bump(carta-crm): 7b4e568d → 4b60ca66 (#2569)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:58:34 -05:00
github-actions[bot]
68a97f85ba bump(carta-investors): 7b4e568d → 4b60ca66 (#2570)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:58:10 -05:00
github-actions[bot]
f1aaa8e4ce bump(qdrant-skills): 82337ccd → 0814a087 (#2573)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:57:45 -05:00
github-actions[bot]
5b6b55808d bump(quarkus-agent): 9700cfee → f5c0dd4c (#2574)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:57:20 -05:00
github-actions[bot]
db71168abe bump(neon): bd9ec7ff → 9695a225 (#2572)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:56:55 -05:00
github-actions[bot]
1f761e4c37 bump(sentry): 87de81a1 → 9780bfc1 (#2577)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:56:28 -05:00
github-actions[bot]
8f09d55614 bump(stripe): b8f6adcb → d076d055 (#2578)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:56:01 -05:00
github-actions[bot]
d0419b8ad5 bump(wix): 9666bc8d → cda44c29 (#2579)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:55:33 -05:00
github-actions[bot]
09404ab125 bump(hyperframes): acd8e117 → 81416ab3 (#2558)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 07:53:11 -05:00
github-actions[bot]
de573bd846 bump(outputai): 65cd0871 → 83742db5 (#2560)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:28:45 -05:00
github-actions[bot]
f92fc04666 bump(railway): 1df604eb → 72299c62 (#2562)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:28:39 -05:00
github-actions[bot]
2b8ae0bc72 bump(sonarqube): 712b9328 → 8c46904b (#2563)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:28:18 -05:00
github-actions[bot]
1b3d7c29eb bump(ui5): 9b3d7d80 → 6d72751f (#2564)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:27:56 -05:00
github-actions[bot]
26e06be79b bump(amazon-location-service): d8243e5f → b13ce7f0 (#2543)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:27:35 -05:00
github-actions[bot]
5e14a52052 bump(astronomer-data-agents): 7ce4a12d → 789b4544 (#2544)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:27:12 -05:00
github-actions[bot]
640704824b bump(carta-cap-table): c39482a4 → 7b4e568d (#2549)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:26:49 -05:00
github-actions[bot]
e53f64964b bump(chrome-devtools-mcp): 6bd8c916 → 4f8eb7ad (#2552)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:26:23 -05:00
github-actions[bot]
a9310efd27 bump(databases-on-aws): d8243e5f → b13ce7f0 (#2555)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:25:59 -05:00
github-actions[bot]
b6a4ea1f6a bump(datarobot-agent-skills): b5a8f7a4 → ec2ecdd4 (#2556)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:25:34 -05:00
github-actions[bot]
2057bc4652 bump(deploy-on-aws): d8243e5f → b13ce7f0 (#2557)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:25:08 -05:00
github-actions[bot]
0bcd12a7d1 bump(ui5-typescript-conversion): 9b3d7d80 → 6d72751f (#2565)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:24:41 -05:00
github-actions[bot]
f2691c1439 bump(aws-amplify): d8243e5f → b13ce7f0 (#2547)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:24:13 -05:00
github-actions[bot]
330492c3d6 bump(aws-serverless): d8243e5f → b13ce7f0 (#2548)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:23:44 -05:00
github-actions[bot]
e7e1e791cb bump(carta-crm): c39482a4 → 7b4e568d (#2550)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:23:14 -05:00
github-actions[bot]
0714e5b202 bump(carta-investors): c39482a4 → 7b4e568d (#2551)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:22:44 -05:00
github-actions[bot]
623b6704d3 bump(data-engineering): 7ce4a12d → 789b4544 (#2554)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:22:15 -05:00
github-actions[bot]
f5e552802c bump(nvidia-skills): fd1e6fd1 → 24806dbd (#2559)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:21:46 -05:00
github-actions[bot]
e69b3a26ef bump(quarkus-agent): 91c7986e → 9700cfee (#2561)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:21:15 -05:00
github-actions[bot]
475e5fe15f bump(atlassian): 9b52fb18 → f4911dba (#2545)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:20:44 -05:00
github-actions[bot]
b61e11909c bump(data): 7ce4a12d → 789b4544 (#2553)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:20:13 -05:00
github-actions[bot]
7eb80c4f5b bump(sap-fiori-mcp-server): 604f2895 → b9127510 (#2531)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:20:05 -05:00
github-actions[bot]
1e0be923c5 bump(aws-startup-advisor): b3e5ee48 → 3c5d6a7d (#2512)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 20:02:11 -05:00
github-actions[bot]
df5224ba07 bump(aws-data-analytics): 7a1422d5 → c0991f46 (#2511)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:30:10 -05:00
github-actions[bot]
e832e2bf0d bump(carta-cap-table): 732981ca → c39482a4 (#2514)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:24:04 -05:00
github-actions[bot]
9895dfca58 bump(ai-plugins): 975f0ce4 → a6737fcf (#2507)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:23:54 -05:00
github-actions[bot]
83d32aefd5 bump(aws-core): 7a1422d5 → c0991f46 (#2510)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:23:28 -05:00
github-actions[bot]
2804bac441 bump(forge-skills): 02103cca → c7df9561 (#2522)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:23:02 -05:00
github-actions[bot]
a1936eee01 bump(nvidia-skills): d0e07bd3 → fd1e6fd1 (#2528)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:22:34 -05:00
github-actions[bot]
b8ecaf01a6 bump(pydantic-ai): e412b6d8 → ddc7d005 (#2530)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:22:07 -05:00
github-actions[bot]
d2bae5e20b bump(firecrawl): 6768fb78 → b3344758 (#2521)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:21:38 -05:00
github-actions[bot]
e96f539e2d bump(hunter): 494b0bd6 → 06bcb94a (#2523)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:21:10 -05:00
github-actions[bot]
77c424ab52 bump(hyperframes): 24279c8c → acd8e117 (#2524)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:20:41 -05:00
github-actions[bot]
a771b69148 bump(jfrog): 117febaa → 6788fe15 (#2525)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:20:11 -05:00
github-actions[bot]
301dfbc752 bump(logfire): e412b6d8 → ddc7d005 (#2526)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:19:41 -05:00
github-actions[bot]
6f5b19f93b bump(outputai): fc6a93e6 → 65cd0871 (#2529)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:19:10 -05:00
github-actions[bot]
85d6e100e2 bump(42crunch-api-security-testing): a5172167 → b7e131e3 (#2506)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:18:23 -05:00
github-actions[bot]
6829c593c8 bump(chrome-devtools-mcp): 702d3734 → 6bd8c916 (#2517)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:18:15 -05:00
github-actions[bot]
0c33859bd9 bump(fastly-agent-toolkit): 6bd17d68 → 73af5b94 (#2520)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:17:42 -05:00
github-actions[bot]
1c5aba82fb bump(migration-to-aws): b3e5ee48 → 3c5d6a7d (#2527)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:17:08 -05:00
github-actions[bot]
2092653e18 bump(snowflake-cortex-code): 2462e1ba → 7d2c7e7e (#2534)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:16:29 -05:00
github-actions[bot]
7ba21d89e2 bump(aws-agents): 7a1422d5 → c0991f46 (#2509)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:16:23 -05:00
github-actions[bot]
0445ef3cf4 bump(crowdstrike-falcon-foundry): c542c932 → 0a651a14 (#2518)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:15:50 -05:00
github-actions[bot]
190a64c2ed bump(carta-crm): 732981ca → c39482a4 (#2515)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:15:41 -05:00
github-actions[bot]
f7ac27f10c bump(togetherai-skills): fb94cc14 → 8aa08ca1 (#2535)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:15:36 -05:00
github-actions[bot]
488e71feb9 bump(carta-investors): 732981ca → c39482a4 (#2516)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:15:30 -05:00
github-actions[bot]
2e5bcca08e bump(sentry-cli): dc99b4d1 → 18111b95 (#2533)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:15:15 -05:00
github-actions[bot]
8681d8d6d1 bump(airtable): 21d2fe52 → 295ab93b (#2508)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:14:55 -05:00
github-actions[bot]
0ec0005a3c bump(azure): 02a614f6 → 966330ee (#2513)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:14:16 -05:00
github-actions[bot]
7f680b8500 bump(dataproc): 20eec06e → 80d126d2 (#2519)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:13:35 -05:00
github-actions[bot]
8f005f9b76 bump(sentry): 030b01fb → 87de81a1 (#2532)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 13:13:25 -05:00
Morgan Lunt
746c982737 Merge pull request #2467 from anthropics/morganl/code-mod-secrets-redaction
code-modernization: never write discovered credential values into findings
2026-06-09 08:49:47 -07:00
Morgan Lunt
88233b24ba Merge pull request #2468 from anthropics/morganl/code-mod-interactive-map
code-modernization: interactive topology map, preflight command, persona flows
2026-06-09 08:49:38 -07:00
Morgan Lunt
ecc5139c30 code-modernization: legacy toolchain is advisory, not a transform blocker
Legacy code often cannot build locally by nature — CICS/IMS programs
have no local translator and the real runtime may be a mainframe the
user doesn't have. Stopping transform on a failed legacy smoke compile
would block exactly those systems.

- transform Step 0a: the target toolchain remains required (its tests
  cannot run without it); a failed or impossible legacy compile no
  longer stops the run — the equivalence strategy switches to recorded
  traces / golden-master fixtures, and that downgrade is stated in the
  plan and in TRANSFORMATION_NOTES.md so reviewers know the strength of
  the proof
- preflight: a red legacy toolchain now yields Ready-with-gaps for
  transform/reimagine instead of Not-ready
2026-06-09 08:48:05 -07:00
Morgan Lunt
a7e1f99070 code-modernization: limit marketplace.json change to the one description line
The previous commit round-tripped the catalog through a JSON serializer,
which escaped non-ASCII characters in every other plugin's description.
Restore the file from main and change only the code-modernization entry.
2026-06-09 08:48:04 -07:00
Morgan Lunt
0c40a74425 code-modernization: add topology viewer screenshot to README
Rendered from AWS CardDemo (the public mainframe sample app) by running
/modernize-map end to end and capturing the resulting TOPOLOGY.html.
2026-06-09 08:48:04 -07:00
Morgan Lunt
bec8d7c93a code-modernization: vendor d3, viewer robustness, status command, pipeline fixes
Viewer (assets/topology-viewer.html):
- inline a minified d3 subset (hierarchy/pack, zoom, selection,
  interpolateZoom, ease; ISC license) instead of loading from a CDN —
  the page is now fully self-contained and works on air-gapped networks
- handle duplicate node ids (unique-suffix; edges bind to the first
  occurrence) and store parent references directly, fixing
  level-of-detail and selection corruption with messy generated data
- share one reveal rule between drawing, edge culling, and hit-testing
  so edges no longer draw into collapsed containers
- pre-bucket edges by kind and keep a per-node adjacency map; the
  hover/selection pass no longer scans every edge each frame
- cancel in-flight fly-to animations when a new one starts; clamp
  fly-to zoom to the zoom extent; derive max zoom from the smallest
  leaf so deep estates stay reachable
- render dead-end candidates (new deadEnds field) with a dashed
  outline and a sidebar badge
- clicking a node during a flow walkthrough exits the walkthrough;
  search results clear on selection and Escape; surrogate-safe label
  truncation; clearer stats line; explicit empty-topology message

Commands:
- new /modernize-status: read-only progress report — artifact inventory
  with timestamps, staleness flags, secrets-hygiene checks, next step
- map: deadEnds in the topology schema; datastore names must be logical
  identifiers with credentials stripped from URLs/DSNs
- brief: read topology.json + .mmd files (not the interactive HTML);
  staleness check against inputs; effort unit aligned to person-months
- transform: secret-safe characterization-test prompt; diff -y fallback
  when delta is missing; credential-safe diff selection
- reimagine: target vision is everything after the first argument (was
  silently truncated to one word); masking rules in spec/scaffold/
  handoff prompts
- brief/transform/reimagine: human-approval gates phrased as explicit
  stop-and-wait instead of 'enter plan mode'
- preflight: delta in the tool table; brief added to the verdict list
- README: preflight/status in the workflow; legacy/ deny list also
  covers Write; plugin + marketplace descriptions updated
2026-06-09 08:48:04 -07:00
Morgan Lunt
8745968186 code-modernization: harden topology viewer and template injection
Fixes from an adversarial review of the new viewer:

- pin d3 to 7.9.0 and load it via dynamic import with an explicit
  error panel when the CDN is unreachable (previously a blocked CDN
  produced a silent dark page — a real concern for restricted networks)
- coerce ids/names/loc at intake: a single missing name or non-numeric
  loc previously threw inside the render loop or propagated NaN through
  the pack layout, blanking the canvas with no error
- normalize flows/steps/edges defensively (null entries, missing steps,
  numeric ids vs string lookups)
- mirror the level-of-detail reveal rule in the hit test so clicks
  can't select nodes that aren't drawn
- scope the Escape shortcut so clearing the search box doesn't reset
  the viewport; set zoom clickDistance(4) so trackpad jitter doesn't
  swallow selection clicks
- round canvas backing-store size (fractional devicePixelRatio caused
  a reallocation every frame on 125%/150% display scaling)
- modernize-map: use braced ${CLAUDE_PLUGIN_ROOT} so substitution
  actually happens, assert the injection marker exists in the template,
  and correct the documented failure mode
2026-06-09 08:48:04 -07:00
Morgan Lunt
1c4a5cfded code-modernization: interactive topology map, preflight command, persona flows
modernize-map previously rendered the call graph and data lineage as
static Mermaid diagrams, which become unreadable once a node has ~10+
edges — exactly the shape of real legacy systems. It now builds an
interactive viewer from a shipped template (assets/topology-viewer.html):
a zoomable circle-pack of domains/modules sized by LOC, rendered to
canvas with level-of-detail reveal, dependency edges with per-kind
toggles, search with fly-to, a per-node detail sidebar, and a flow
walkthrough mode. Small domain-level .mmd exports remain for docs.

- topology.json now has a documented schema (hierarchy + edges + entry
  points + observations + flows) consumed by the viewer
- map traces 2-4 business flows anchored to personas (claimant,
  operator, auditor), each step in plain business language mapped to
  the modules that implement it; the viewer plays them as numbered
  paths
- brief gains a Business Walkthroughs section connecting each persona
  flow to the phase that replaces it
- new modernize-preflight command: detects the stack, checks analysis
  tooling, smoke-compiles a real source file with the legacy toolchain,
  inventories missing copybooks/descriptors/binary-only artifacts, and
  writes a per-command readiness verdict
- transform now verifies legacy + target toolchains before its plan
  gate instead of failing at test time
- README: commands updated, optional-tooling section reframed as 'what
  to give Claude'
2026-06-09 08:48:04 -07:00
github-actions[bot]
379a00dba5 bump(sap-fiori-mcp-server): fbfe8c32 → 604f2895 (#2500)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:53:05 -05:00
github-actions[bot]
0161a176c7 bump(airwallex): a903ab76 → a49ef1ec (#2499)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:52:43 -05:00
github-actions[bot]
7dd654e4ea bump(wix): 188ed338 → 9666bc8d (#2502)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:52:20 -05:00
github-actions[bot]
b167faa74a bump(data-agent-kit-starter-pack): fb908645 → b47cae53 (#2481)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:51:57 -05:00
github-actions[bot]
bdde825b98 bump(42crunch-api-security-testing): db2fb7e5 → a5172167 (#2469)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:51:45 -05:00
github-actions[bot]
cd49446ad3 bump(databases-on-aws): fc54dfa2 → d8243e5f (#2482)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:51:17 -05:00
github-actions[bot]
b667e7f193 bump(deploy-on-aws): fc54dfa2 → d8243e5f (#2484)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:51:06 -05:00
github-actions[bot]
a3a7e77735 bump(migration-to-aws): 1dd90935 → b3e5ee48 (#2488)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:59 -05:00
github-actions[bot]
6ab6953eee bump(snowflake-cortex-code): 6a22eb1f → 2462e1ba (#2495)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:48 -05:00
github-actions[bot]
27524414d8 bump(amazon-location-service): fc54dfa2 → d8243e5f (#2471)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:37 -05:00
github-actions[bot]
336212b41d bump(aws-data-analytics): 55b9acfe → 7a1422d5 (#2475)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:26 -05:00
github-actions[bot]
dd7fcb43f2 bump(carta-cap-table): 9eb31290 → 732981ca (#2478)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:15 -05:00
github-actions[bot]
ebecea5c95 bump(aws-startup-advisor): 1dd90935 → b3e5ee48 (#2477)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:11 -05:00
github-actions[bot]
8525d71094 bump(adobe-for-creativity): e23271f6 → 253f5690 (#2470)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:50:01 -05:00
github-actions[bot]
8288a4a320 bump(sagemaker-ai): fc54dfa2 → d8243e5f (#2493)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:49:30 -05:00
github-actions[bot]
0d91490722 bump(quarkus-agent): e711107a → 91c7986e (#2492)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:49:23 -05:00
github-actions[bot]
de6b8cf296 bump(carta-investors): 9eb31290 → 732981ca (#2480)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:49:11 -05:00
github-actions[bot]
b4f01b62bf bump(carta-crm): 9eb31290 → 732981ca (#2479)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:48:59 -05:00
github-actions[bot]
d7d03756e2 bump(nvidia-skills): 0482ebce → d0e07bd3 (#2490)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:48:47 -05:00
github-actions[bot]
54eb24e9d6 bump(netlify-skills): 5f777ba6 → 22025ef6 (#2489)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:48:35 -05:00
github-actions[bot]
8acfe8b3cb bump(aws-core): 55b9acfe → 7a1422d5 (#2474)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:48:23 -05:00
github-actions[bot]
1fb5d16181 bump(aws-serverless): fc54dfa2 → d8243e5f (#2476)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:48:12 -05:00
github-actions[bot]
8aac392a4d bump(aws-amplify): fc54dfa2 → d8243e5f (#2473)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:48:00 -05:00
github-actions[bot]
eeb0e11315 bump(aws-agents): 55b9acfe → 7a1422d5 (#2472)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:47:53 -05:00
github-actions[bot]
22be09177b bump(sentry-cli): 9e9fe0fb → dc99b4d1 (#2494)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:47:34 -05:00
github-actions[bot]
1f5ce124fa bump(hyperframes): 25420bf4 → 24279c8c (#2487)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:44:01 -05:00
github-actions[bot]
30f8e267a1 bump(dataverse): 2d50cf65 → 2c373943 (#2483)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:43:23 -05:00
github-actions[bot]
7be381f4cf bump(exa): f0838825 → 9ea4ba3e (#2485)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 07:05:31 -05:00
github-actions[bot]
3175a58228 bump(figma): a742f0a7 → 54ad1560 (#2486)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 06:30:13 -05:00
github-actions[bot]
c78c61e117 bump(outputai): 2cc4685e → fc6a93e6 (#2491)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 05:05:03 -05:00
github-actions[bot]
e7710f24ba bump(sumup): 715464b4 → 5b9b2d72 (#2496)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 04:21:58 -05:00
github-actions[bot]
2fe8c1d7ad bump(workos): e8900cc5 → 2c3acef6 (#2497)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-09 03:21:25 -05:00
Mohamed Hegazy
43fcf6d513 security-guidance: encode exception type + errno + ensurepip instrumentation for venv BUILD_FAILED (2.0.3 → 2.0.4)
Follow-up to #2154. v2.0.3 telemetry showed the venv BUILD_FAILED bucket
splits into two unexplained groups; this PR instruments both.

## 1. The exc: bucket — exception type + errno

The dominant remaining venv BUILD_FAILED (phase=venv, err=99) is ~99%
sdk_bootstrap_stderr_sig=NULL — Python exceptions caught by the generic
`except Exception` ("exc:<TypeName>"), not CalledProcessErrors with
categorizable stderr. ~56k/30h, all opaque (stderr_sig only covers
"other:<tail>").

  - Handler embeds errno for OSError-family: "exc:OSError:28", etc.
  - SDK_BOOTSTRAP_EXC_CODES maps the type → sdk_bootstrap_exc
    (FileNotFoundError=1 … OSError=6 … 99=other).
  - errno decoded → sdk_bootstrap_errno (ENOENT/EACCES/ENOSPC/…).

## 2. venv_ensurepip_fail instrumentation (the other category)

venv_ensurepip_fail (code 11) is the top categorizable venv failure, and
telemetry flipped the naive assumption: it's NOT just Debian/Ubuntu —
macOS has the MOST distinct affected users (466 vs 121 linux), and linux
is a retry storm (~172 fires/user). Before committing to a `pip install
--target` fallback (Option A) we need to know (a) which interpreter these
users run and (b) whether that interpreter even has pip (→ whether
--target would work, vs needing a system package).

  - sdk_hook_py (always emitted): interpreter version as major*100+minor
    (309/312). Disambiguates Apple-3.9 vs a 3.10+-with-broken-ensurepip,
    and also recovers the version for HOOK_PY_INCOMPATIBLE (whose "py_3.9"
    err_kind otherwise collapses to err=99).
  - sdk_has_pip (only on err==11, to avoid an extra subprocess per healthy
    session): whether `<interpreter> -m pip --version` works. has_pip=true
    → the --target fallback would fix them; has_pip=false → they need a
    system package (python3-venv / a complete Python).

Both #1 and #2 are purely additive telemetry on the existing BUILD_FAILED
path — no behavior change to the bootstrap. They de-risk the Option A
decision: ship A only if the affected cohort has pip.

Verified locally on macOS Python 3.13:
  - py_compile clean.
  - 39 tests in test_exc_failure_encoding.py (34 exc/errno + 5 ensurepip
    instrumentation): type-code map, errno extraction + round-trip,
    APPEND-ONLY stability, handler-embeds-errno, _probe_has_pip returns
    bool + true-on-this-machine, sdk_hook_py always-emitted as
    major*100+minor, sdk_has_pip gated on err==11.
  - Full suite: 503/503 pass + 2 skipped.

Version 2.0.3 -> 2.0.4 per the per-PR-bump policy (#2114).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 14:55:55 -07:00
14 changed files with 1215 additions and 151 deletions

View File

@@ -19,7 +19,7 @@
"url": "https://github.com/42Crunch-AI/claude-plugins.git",
"path": "plugins/api-security-testing",
"ref": "v1.5.5",
"sha": "db2fb7e53e3d93a863930b6f6b7895be5ee01f21"
"sha": "5cfa510f7ea4d940f0ff5f6688a21e4ea0db0a18"
},
"homepage": "https://42crunch.com"
},
@@ -35,7 +35,7 @@
"url": "https://github.com/adobe/skills.git",
"path": "plugins/creative-cloud/adobe-for-creativity",
"ref": "main",
"sha": "e23271f65aa7572f567d085d6baec5c2408e2ad5"
"sha": "253f56901e058800ccb97ffd5bf1e3329d5f2e00"
},
"homepage": "https://github.com/adobe/skills/tree/main/plugins/creative-cloud/adobe-for-creativity"
},
@@ -67,7 +67,7 @@
"source": {
"source": "url",
"url": "https://github.com/endorlabs/ai-plugins.git",
"sha": "975f0ce422b1f2677681ffd085aef34ea1826b70"
"sha": "a6737fcf72336399e212e45cd25a250c2df3b7b4"
},
"homepage": "https://www.endorlabs.com"
},
@@ -77,7 +77,7 @@
"source": {
"source": "url",
"url": "https://github.com/AikidoSec/aikido-claude-plugin.git",
"sha": "79ac524f87c9faa9a356ff3d495b8a5b77e01bbd"
"sha": "603d5eac5ef00d9db65fa4f15058345e7bce3352"
},
"homepage": "https://github.com/AikidoSec/aikido-claude-plugin"
},
@@ -93,7 +93,7 @@
"url": "https://github.com/Airtable/skills.git",
"path": "plugins/airtable",
"ref": "main",
"sha": "21d2fe52774d861e2f2f997eeac2bf965e8590b8"
"sha": "295ab93b7d765912ee1a0dc7f1abb0ecaf73f138"
},
"homepage": "https://www.airtable.com"
},
@@ -109,7 +109,7 @@
"url": "https://github.com/airwallex/airwallex-marketplace.git",
"path": "plugins/airwallex",
"ref": "master",
"sha": "a903ab7693a5f6d46f2fab6f895a2f96a879ee0f"
"sha": "a49ef1ec801fd776adc4db9f2bb4a78463981bc9"
},
"homepage": "https://www.airwallex.com/docs"
},
@@ -150,7 +150,7 @@
"url": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/amazon-location-service",
"ref": "main",
"sha": "fc54dfa24a1f05095b9fcbb4baa4750996bb171d"
"sha": "58373593c6ed2e4684181f81369c0b7a4c916423"
},
"homepage": "https://github.com/awslabs/agent-plugins"
},
@@ -161,7 +161,7 @@
"url": "https://github.com/amplitude/mcp-marketplace.git",
"path": "plugins/amplitude",
"ref": "main",
"sha": "e9b4e15193666e1b513b5652ded23fab160bdc4e"
"sha": "fb22979da93d27dcb17b832dbd473e6b0caf2ca8"
},
"description": "Use Amplitude as an expert analyst — instrument Amplitude, discover product opportunities, analyze charts, create dashboards, manage experiments, and understand users and accounts.",
"category": "monitoring",
@@ -223,7 +223,7 @@
"source": {
"source": "url",
"url": "https://github.com/astronomer/agents.git",
"sha": "7ce4a12d3cabb506294134c91a1b876d4b166a70"
"sha": "789b4544b85a989694501e4f405b522f2d711cf6"
},
"homepage": "https://github.com/astronomer/agents"
},
@@ -233,7 +233,7 @@
"source": {
"source": "url",
"url": "https://github.com/atlanhq/agent-toolkit.git",
"sha": "789507c02d2495235240d10d67aaac8b2051023a"
"sha": "86bb1ad27f80e189b328333d2271b360ae579f2b"
},
"homepage": "https://docs.atlan.com/"
},
@@ -244,7 +244,7 @@
"source": {
"source": "url",
"url": "https://github.com/atlassian/atlassian-mcp-server.git",
"sha": "9b52fb18e184edc307ce33f8bf4cdf148dedf1f2"
"sha": "f4911dba81f25782c88815b03deabf444cd46e0d"
},
"homepage": "https://github.com/atlassian/atlassian-mcp-server"
},
@@ -275,7 +275,7 @@
"url": "https://github.com/auth0/agent-skills.git",
"path": "plugins/auth0",
"ref": "main",
"sha": "bdf0dc23f8b17446b2c94bc9f2e5a58d3f1bc114"
"sha": "b595bdb9b574569e864eef86c3d48c06e2cf414c"
},
"homepage": "https://auth0.com/docs/quickstart/agent-skills"
},
@@ -291,7 +291,7 @@
"url": "https://github.com/aws/agent-toolkit-for-aws.git",
"path": "plugins/aws-agents",
"ref": "main",
"sha": "55b9acfefdcf0866b6bc6cc56c16e6e18e65bd2b"
"sha": "f5ba81082aafe865ffe947ceabc574a7a0353e57"
},
"homepage": "https://github.com/aws/agent-toolkit-for-aws"
},
@@ -304,7 +304,7 @@
"url": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/aws-amplify",
"ref": "main",
"sha": "fc54dfa24a1f05095b9fcbb4baa4750996bb171d"
"sha": "58373593c6ed2e4684181f81369c0b7a4c916423"
},
"homepage": "https://github.com/awslabs/agent-plugins"
},
@@ -320,7 +320,7 @@
"url": "https://github.com/aws/agent-toolkit-for-aws.git",
"path": "plugins/aws-core",
"ref": "main",
"sha": "55b9acfefdcf0866b6bc6cc56c16e6e18e65bd2b"
"sha": "f5ba81082aafe865ffe947ceabc574a7a0353e57"
},
"homepage": "https://github.com/aws/agent-toolkit-for-aws"
},
@@ -336,7 +336,7 @@
"url": "https://github.com/aws/agent-toolkit-for-aws.git",
"path": "plugins/aws-data-analytics",
"ref": "main",
"sha": "55b9acfefdcf0866b6bc6cc56c16e6e18e65bd2b"
"sha": "f5ba81082aafe865ffe947ceabc574a7a0353e57"
},
"homepage": "https://github.com/aws/agent-toolkit-for-aws"
},
@@ -365,7 +365,7 @@
"url": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/aws-serverless",
"ref": "main",
"sha": "fc54dfa24a1f05095b9fcbb4baa4750996bb171d"
"sha": "58373593c6ed2e4684181f81369c0b7a4c916423"
},
"homepage": "https://github.com/awslabs/agent-plugins"
},
@@ -381,7 +381,7 @@
"url": "https://github.com/awslabs/startups.git",
"path": "advisor/plugins/aws-startup-advisor",
"ref": "main",
"sha": "1dd909352dc228f978c2685724cb38e64efe6be4"
"sha": "944e5b17bb4b6a84a76b6382e3f5d7fa9abd7bbd"
},
"homepage": "https://github.com/awslabs/startups"
},
@@ -392,7 +392,7 @@
"source": {
"source": "url",
"url": "https://github.com/microsoft/azure-skills.git",
"sha": "02a614f6ee1f052826f834d65c61e430ad152c8e"
"sha": "966330ee4fc61978b6e324993687e917125a1f36"
},
"homepage": "https://github.com/microsoft/azure-skills"
},
@@ -414,7 +414,7 @@
"source": {
"source": "url",
"url": "https://github.com/base44/skills.git",
"sha": "ec420cf2edd2c7e9a523d5afe2e71498a6357fa4"
"sha": "aef0fa35f21b3c0c000d5ab8c0b068e6188618b6"
},
"homepage": "https://docs.base44.com"
},
@@ -430,7 +430,7 @@
"url": "https://github.com/Bigdata-com/bigdata-plugins-marketplace.git",
"path": "plugins/bigdata-com",
"ref": "main",
"sha": "67c30be97a0a3f46bc6e8d56df449ae108eda9c5"
"sha": "76a043a08c0a10eb73756d04031a613568017067"
},
"homepage": "https://docs.bigdata.com"
},
@@ -472,7 +472,7 @@
"source": {
"source": "url",
"url": "https://github.com/brightdata/skills.git",
"sha": "bd5bd76bc889f54b744bab3db3cbd42751a1e5b0"
"sha": "8d427e9871566efe3f0a1c8888f98b6fe8288831"
},
"homepage": "https://docs.brightdata.com"
},
@@ -502,7 +502,7 @@
"url": "https://github.com/carta/plugins.git",
"path": "plugins/carta-cap-table",
"ref": "main",
"sha": "9eb312908f4a2e2d15e4e935320981433a549f77"
"sha": "ab95e738e5fa8945d0e0faa1e43b7d618980ac76"
},
"homepage": "https://carta.com"
},
@@ -518,7 +518,7 @@
"url": "https://github.com/carta/plugins.git",
"path": "plugins/carta-crm",
"ref": "main",
"sha": "9eb312908f4a2e2d15e4e935320981433a549f77"
"sha": "4b5796517b62c4aeaac1a0bb6ccdaebeb73475a5"
},
"homepage": "https://carta.com"
},
@@ -534,7 +534,7 @@
"url": "https://github.com/carta/plugins.git",
"path": "plugins/carta-investors",
"ref": "main",
"sha": "9eb312908f4a2e2d15e4e935320981433a549f77"
"sha": "ab95e738e5fa8945d0e0faa1e43b7d618980ac76"
},
"homepage": "https://carta.com"
},
@@ -561,7 +561,7 @@
"source": {
"source": "url",
"url": "https://github.com/ChromeDevTools/chrome-devtools-mcp.git",
"sha": "702d3734f276a18efd67561ae00b88ce954cc515"
"sha": "228cf3936ad99d9e0c09b43d77fbbac8712f2357"
},
"homepage": "https://github.com/ChromeDevTools/chrome-devtools-mcp"
},
@@ -720,7 +720,7 @@
"source": {
"source": "url",
"url": "https://github.com/cloudflare/skills.git",
"sha": "c5b7b06b073fa0b4abbd63964630f97d81da69c4"
"sha": "12520fd63a1e958be217a93f48ce1f04bc9055f3"
},
"description": "Skills for the Cloudflare developer platform: Workers, Durable Objects, Agents SDK, MCP servers, Wrangler CLI, and web performance.",
"category": "deployment",
@@ -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"
@@ -804,7 +804,7 @@
"source": {
"source": "url",
"url": "https://github.com/CodSpeedHQ/codspeed.git",
"sha": "c6112f168b405df8e7310b12a9b80484cd01ac14"
"sha": "41f4db99123434f3e24d0b9caca3e2b65d7ee24d"
},
"homepage": "https://codspeed.io"
},
@@ -872,7 +872,7 @@
"source": {
"source": "url",
"url": "https://github.com/CrowdStrike/foundry-skills.git",
"sha": "c542c932956fd19177a62b94577f288c832d4680"
"sha": "a7e6a75ad2d9aa4093771e8c07d455c1ce39aae1"
},
"homepage": "https://github.com/CrowdStrike/foundry-skills"
},
@@ -918,7 +918,7 @@
"source": {
"source": "url",
"url": "https://github.com/dash0hq/dash0-agent-plugin.git",
"sha": "5ff7aa5b8e52e10d10e45ea8e2f7cbebc86758bf"
"sha": "37fd498b0775d98fcd27ff3c0fe3f68e412482a4"
},
"homepage": "https://dash0.com/"
},
@@ -929,7 +929,7 @@
"source": {
"source": "url",
"url": "https://github.com/astronomer/agents.git",
"sha": "7ce4a12d3cabb506294134c91a1b876d4b166a70"
"sha": "789b4544b85a989694501e4f405b522f2d711cf6"
},
"homepage": "https://github.com/astronomer/agents"
},
@@ -943,7 +943,7 @@
"source": {
"source": "url",
"url": "https://github.com/gemini-cli-extensions/data-agent-kit-starter-pack.git",
"sha": "fb9086456d5fbc780edf86f0ac413345ba628173"
"sha": "6f60c83ad13436f953224a61477d6380c199214b"
},
"homepage": "https://github.com/gemini-cli-extensions/data-agent-kit-starter-pack"
},
@@ -953,7 +953,7 @@
"source": {
"source": "url",
"url": "https://github.com/astronomer/agents.git",
"sha": "7ce4a12d3cabb506294134c91a1b876d4b166a70"
"sha": "789b4544b85a989694501e4f405b522f2d711cf6"
},
"homepage": "https://github.com/astronomer/agents"
},
@@ -966,7 +966,7 @@
"url": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/databases-on-aws",
"ref": "main",
"sha": "fc54dfa24a1f05095b9fcbb4baa4750996bb171d"
"sha": "58373593c6ed2e4684181f81369c0b7a4c916423"
},
"homepage": "https://github.com/awslabs/agent-plugins"
},
@@ -1008,7 +1008,7 @@
"source": {
"source": "url",
"url": "https://github.com/gemini-cli-extensions/dataproc.git",
"sha": "20eec06eee7683311689f4a1437cbb14ac8cd33e"
"sha": "80d126d27d84ded752c84668472dd6f75896fc59"
},
"homepage": "https://github.com/gemini-cli-extensions/dataproc"
},
@@ -1022,7 +1022,7 @@
"source": {
"source": "url",
"url": "https://github.com/datarobot-oss/datarobot-agent-skills.git",
"sha": "b5a8f7a4bc4d31a1f139a232efbba6127af0474a"
"sha": "ec2ecdd49d54ef490b344a850cff1feb1230c409"
},
"homepage": "https://datarobot.com"
},
@@ -1035,7 +1035,7 @@
"url": "https://github.com/microsoft/Dataverse-skills.git",
"path": ".github/plugins/dataverse",
"ref": "main",
"sha": "2d50cf65f80efc17ac50632222d61fb374115a70"
"sha": "2c37394346be1afc1db12cc5b89f5dee3617c45c"
},
"homepage": "https://github.com/microsoft/Dataverse-skills"
},
@@ -1048,7 +1048,7 @@
"url": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/deploy-on-aws",
"ref": "main",
"sha": "fc54dfa24a1f05095b9fcbb4baa4750996bb171d"
"sha": "58373593c6ed2e4684181f81369c0b7a4c916423"
},
"homepage": "https://github.com/awslabs/agent-plugins"
},
@@ -1126,7 +1126,7 @@
"source": {
"source": "url",
"url": "https://github.com/exa-labs/exa-mcp-server.git",
"sha": "f08388256c5806f457fae777b5528eb02a48e703"
"sha": "9ea4ba3e67f87c462c3e06b192470e837ed9009e"
},
"homepage": "https://exa.ai/docs/reference/exa-mcp"
},
@@ -1150,7 +1150,7 @@
"url": "https://github.com/expo/skills.git",
"path": "plugins/expo",
"ref": "main",
"sha": "c38860242118df93d4ec4381a34f4144fff61928"
"sha": "1a5693e0acc95a0829ff1656b4426fee2f2c1167"
},
"homepage": "https://github.com/expo/skills/blob/main/plugins/expo/README.md"
},
@@ -1166,7 +1166,7 @@
"source": {
"source": "url",
"url": "https://github.com/fastly/fastly-agent-toolkit.git",
"sha": "6bd17d685a1b361a2b368bf0236f39efb1be62d6"
"sha": "73af5b94a98448ffeed6e2993495dc83c9a597be"
},
"homepage": "https://github.com/fastly/fastly-agent-toolkit/blob/main/README.md"
},
@@ -1198,7 +1198,7 @@
"source": {
"source": "url",
"url": "https://github.com/figma/mcp-server-guide.git",
"sha": "a742f0a700a7772ff5ed85f7c9fc1dad5afa9fcc"
"sha": "2efd0e37d10c35c4a7cf6d2b7381c9dc1a569bd4"
},
"homepage": "https://github.com/figma/mcp-server-guide"
},
@@ -1216,7 +1216,7 @@
"source": {
"source": "url",
"url": "https://github.com/firecrawl/firecrawl-claude-plugin.git",
"sha": "6768fb78185aab9e5b5a04777f84703863fb025b"
"sha": "b33447585ac521b091eae672bd4cad4ec1d093f6"
},
"homepage": "https://github.com/firecrawl/firecrawl-claude-plugin.git"
},
@@ -1230,7 +1230,7 @@
"source": {
"source": "url",
"url": "https://github.com/gemini-cli-extensions/firestore-native.git",
"sha": "f88103bd0ccfe9e1e7a3a7d849de26d197978c9a"
"sha": "d7f42424cfddfb567efbae100023b94dfb4571be"
},
"homepage": "https://github.com/gemini-cli-extensions/firestore-native"
},
@@ -1244,7 +1244,7 @@
"source": {
"source": "url",
"url": "https://github.com/atlassian/forge-skills.git",
"sha": "02103cca4addb4c42d64d4e18a9d1a7f186edf6c"
"sha": "c7df956176eb1c2a10ffabc4eaacc5d843d8bede"
},
"homepage": "https://developer.atlassian.com/platform/forge/"
},
@@ -1333,7 +1333,7 @@
"source": {
"source": "url",
"url": "https://github.com/huggingface/skills.git",
"sha": "d7223848c3895fbd447faf2aec73e0a6cdd7fdcd"
"sha": "7bf59b7f85b79c74207b10d5e425934514e8b089"
},
"homepage": "https://github.com/huggingface/skills.git"
},
@@ -1347,7 +1347,7 @@
"source": {
"source": "url",
"url": "https://github.com/hunter-io/claude-plugin.git",
"sha": "494b0bd6ac252c7c8d78402cb51c7f635b1469ad"
"sha": "06bcb94a4e6498d8557a4543f8d5c4ea429b0c0a"
},
"homepage": "https://hunter.io"
},
@@ -1361,7 +1361,7 @@
"source": {
"source": "url",
"url": "https://github.com/heygen-com/hyperframes.git",
"sha": "25420bf4cfc37b179b4efeace9db25a7178b61bf"
"sha": "c52165d1b63cf11955ceb4e2265cbe34b0718852"
},
"homepage": "https://hyperframes.heygen.com"
},
@@ -1415,7 +1415,7 @@
"source": "github",
"repo": "jfrog/claude-plugin",
"commit": "259c8e718266c16e99b4f30ae9b1ed0f9f00d98d",
"sha": "117febaa29cbe9449cfb42d1c39b83b858d801a1"
"sha": "6788fe15d4a63d47f038c05e58ae533aeb2dadb6"
},
"homepage": "https://jfrog.com"
},
@@ -1429,7 +1429,7 @@
"source": {
"source": "url",
"url": "https://github.com/gemini-cli-extensions/knowledge-catalog.git",
"sha": "317e96fdd12aa61778b950192aff627efdc21099"
"sha": "b3df58e81ae46a1497a1186fc82119d328ec730c"
},
"homepage": "https://github.com/gemini-cli-extensions/knowledge-catalog"
},
@@ -1540,7 +1540,7 @@
"url": "https://github.com/pydantic/skills.git",
"path": "plugins/logfire",
"ref": "main",
"sha": "e412b6d8d4b6199ac577c5ee8653dcff840b3e92"
"sha": "1e7a4567d8375e8ef07ad078d7f38bc03ce5e944"
},
"homepage": "https://github.com/pydantic/skills/tree/main/plugins/logfire"
},
@@ -1554,7 +1554,7 @@
"source": {
"source": "url",
"url": "https://github.com/gemini-cli-extensions/looker.git",
"sha": "e912c0342f1bfd436e9236aaef7cc732239c80f7"
"sha": "ef38964514c9b6634ac9a211d3987222bb36bf6e"
},
"homepage": "https://github.com/gemini-cli-extensions/looker"
},
@@ -1602,7 +1602,7 @@
"source": {
"source": "url",
"url": "https://github.com/lusha-oss/lusha-mcp-plugin.git",
"sha": "8fc71d5473ea40e01a92001787f0f3caaf5ca30e"
"sha": "affbc76b03c1a46c0dffc5b7a374cf7af17b26e8"
},
"homepage": "https://www.lusha.com"
},
@@ -1708,7 +1708,7 @@
"url": "https://github.com/awslabs/startups.git",
"path": "migrate/plugins/migration-to-aws",
"ref": "main",
"sha": "1dd909352dc228f978c2685724cb38e64efe6be4"
"sha": "944e5b17bb4b6a84a76b6382e3f5d7fa9abd7bbd"
},
"homepage": "https://github.com/awslabs/startups"
},
@@ -1759,7 +1759,7 @@
"url": "https://github.com/neondatabase/agent-skills.git",
"path": "plugins/neon-postgres",
"ref": "main",
"sha": "bd9ec7ff273ce54bdd3ebe581d5b0802a3479618"
"sha": "58b84dfb0815cca6dbb2f40bfdb23ddf934d2b5f"
},
"homepage": "https://github.com/neondatabase/agent-skills/tree/main/plugins/neon-postgres"
},
@@ -1770,7 +1770,7 @@
"source": {
"source": "url",
"url": "https://github.com/netlify/context-and-tools.git",
"sha": "5f777ba63df12f4eb189be4c58bd35d0c8316505"
"sha": "c594226e29e05cd6da81b73e8d5a67c6742b4437"
},
"homepage": "https://github.com/netlify/context-and-tools"
},
@@ -1839,7 +1839,7 @@
"url": "https://github.com/NVIDIA/skills.git",
"path": "plugins/nvidia-skills",
"ref": "main",
"sha": "0482ebce81bd8f2d39990317bb3cfb07637e39fd"
"sha": "071d2fe0ef34b77a56f2f1401c223848572d5a97"
},
"homepage": "https://github.com/NVIDIA/skills"
},
@@ -1855,7 +1855,7 @@
"url": "https://github.com/oracle-samples/oracle-aidp-samples.git",
"path": "ai/claude-code-plugins/oracle-ai-data-platform-workbench-spark-connectors",
"ref": "main",
"sha": "00cedef34c99d642d969f87965736768de01cbd6"
"sha": "deadf8f862f1360e08fd7de470ad1af38c3edb31"
},
"homepage": "https://docs.oracle.com/en/cloud/paas/ai-data-platform/index.html"
},
@@ -1885,7 +1885,7 @@
"url": "https://github.com/growthxai/output.git",
"path": "coding_assistants/claude/plugins/outputai",
"ref": "main",
"sha": "2cc4685ebadfba9586f01890df48e1b25bd1049a"
"sha": "be9352cb3cb4bd7c204be0150db8c205dd939d9e"
},
"homepage": "https://output.ai"
},
@@ -1995,7 +1995,7 @@
"source": {
"source": "url",
"url": "https://github.com/PostHog/ai-plugin.git",
"sha": "db4a86632293ca66eec9a6d278786ddb22c1787e"
"sha": "f674efefafeff7152294642f8559906eed885210"
},
"homepage": "https://posthog.com/docs/model-context-protocol"
},
@@ -2050,7 +2050,7 @@
"url": "https://github.com/pydantic/skills.git",
"path": "plugins/ai",
"ref": "main",
"sha": "e412b6d8d4b6199ac577c5ee8653dcff840b3e92"
"sha": "1e7a4567d8375e8ef07ad078d7f38bc03ce5e944"
},
"homepage": "https://github.com/pydantic/skills/tree/main/plugins/ai"
},
@@ -2088,7 +2088,7 @@
"source": {
"source": "url",
"url": "https://github.com/qdrant/skills.git",
"sha": "82337ccd4be601e52871f101844d57b2adbac52b"
"sha": "0814a0875db7a31bf29e46821668ef1b07f9f696"
},
"homepage": "https://skills.qdrant.tech"
},
@@ -2113,7 +2113,7 @@
"source": {
"source": "url",
"url": "https://github.com/TheQtCompanyRnD/agent-skills.git",
"sha": "a7189a7bc17e616b725e7ce4e46a4f5ebd50d94f"
"sha": "2be55aaf050cf0e5d92d62966c473d2c5f6d780a"
},
"homepage": "https://www.qt.io/"
},
@@ -2127,7 +2127,7 @@
"source": {
"source": "url",
"url": "https://github.com/quarkusio/quarkus-agent-mcp.git",
"sha": "e711107a1171507212dd0edd17b5a922212c3a97"
"sha": "0ecd6237518001b92da64499f0b43103a278f95f"
},
"homepage": "https://quarkus.io"
},
@@ -2140,7 +2140,7 @@
"url": "https://github.com/railwayapp/railway-skills.git",
"path": "plugins/railway",
"ref": "main",
"sha": "1df604ebd18f528ff16b84975125ecff944cc036"
"sha": "836d42c1b652953c17a4523a07f1b8a68cc22064"
},
"homepage": "https://docs.railway.com/ai/claude-code-plugin"
},
@@ -2300,7 +2300,7 @@
"url": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/sagemaker-ai",
"ref": "main",
"sha": "fc54dfa24a1f05095b9fcbb4baa4750996bb171d"
"sha": "58373593c6ed2e4684181f81369c0b7a4c916423"
},
"homepage": "https://github.com/awslabs/agent-plugins"
},
@@ -2314,7 +2314,7 @@
"source": {
"source": "url",
"url": "https://github.com/sanity-io/agent-toolkit.git",
"sha": "66f0ec5d9167b3ccb8b3450e5ec34f3b523d4139"
"sha": "2d7b7c08a31a6e5b613e33a9edc76456e4d7c052"
},
"homepage": "https://www.sanity.io"
},
@@ -2348,7 +2348,7 @@
"url": "https://github.com/SAP/open-ux-tools.git",
"path": "packages/fiori-mcp-server",
"ref": "main",
"sha": "fbfe8c32fb9fc64583aa72ac03ab64f553c407ee"
"sha": "cf2d1ef7f5641416c8f3ce7da7afac6c9271ad39"
},
"homepage": "https://github.com/SAP/open-ux-tools/tree/main/packages/fiori-mcp-server"
},
@@ -2380,14 +2380,14 @@
"url": "https://github.com/spotify/save-to-spotify.git",
"path": "plugin",
"ref": "main",
"sha": "cd4ea68111d96769b09c0b0d2199e692cf00a73c"
"sha": "a62408bcfb5e5be686e1fdcc361398493b8c4160"
},
"homepage": "https://github.com/spotify/save-to-spotify"
},
{
"name": "security-guidance",
"description": "Security review for Claude-generated code. Pattern-based warnings on edits, LLM-powered diff review on Stop, and an agentic commit reviewer that catches injection, XSS, SSRF, hardcoded secrets, and 25+ other vulnerability classes.",
"version": "2.0.3",
"version": "2.0.5",
"author": {
"name": "Anthropic",
"email": "support@anthropic.com"
@@ -2415,7 +2415,7 @@
"source": {
"source": "url",
"url": "https://github.com/getsentry/sentry-for-claude.git",
"sha": "030b01fb76b21f5d7ef6af5a3c3dfa658a9b5024"
"sha": "9780bfc111f97b359893169e79c33d1e393891e5"
},
"homepage": "https://github.com/getsentry/sentry-for-claude/tree/main"
},
@@ -2431,7 +2431,7 @@
"url": "https://github.com/getsentry/cli.git",
"path": "plugins/sentry-cli",
"ref": "main",
"sha": "9e9fe0fb6444f18ed109058b2749cced3c21f87e"
"sha": "a55d2a805aea69f6abb3fe58ed162377867ba2c5"
},
"homepage": "https://sentry.io"
},
@@ -2534,7 +2534,7 @@
"url": "https://github.com/Snowflake-Labs/snowflake-ai-kit.git",
"path": "plugins/cortex-code",
"ref": "main",
"sha": "6a22eb1ff3b451c35e40468a118bbee54610c9bd"
"sha": "5a8f277f623394838ee76399261f4704c19eaba7"
},
"homepage": "https://docs.snowflake.com/en/user-guide/cortex-code"
},
@@ -2548,7 +2548,7 @@
"source": {
"source": "url",
"url": "https://github.com/SonarSource/sonarqube-agent-plugins.git",
"sha": "712b93281f4e67c16ed9b81dde090e1f73f8bfc8"
"sha": "8c46904b2c21eb98d827c185e15ef5f6dd820312"
},
"homepage": "https://www.sonarsource.com"
},
@@ -2608,7 +2608,7 @@
"url": "https://github.com/stripe/ai.git",
"path": "providers/claude/plugin",
"ref": "main",
"sha": "b8f6adcb5d05f6ff01334411561ee8cb1ec014c6"
"sha": "d076d0558c3b3d86149c2dddc84054fe9c6dd3e0"
},
"homepage": "https://github.com/stripe/ai/tree/main/providers/claude/plugin"
},
@@ -2620,7 +2620,7 @@
"source": "url",
"url": "https://github.com/sumup/sumup-skills.git",
"path": "providers/claude/plugin",
"sha": "715464b459def2d16e930e9ec8008f60e18a8b4d"
"sha": "5b9b2d72c63fefd9038db0a9c571d3d64ff6353c"
},
"homepage": "https://www.sumup.com/"
},
@@ -2707,7 +2707,7 @@
"source": {
"source": "url",
"url": "https://github.com/togethercomputer/skills.git",
"sha": "fb94cc1402900eb608c31e7102fc23566f8b0363"
"sha": "86bdd6627675eac3f2055f028e4acdd4d1b03fb0"
},
"homepage": "https://www.together.ai"
},
@@ -2769,7 +2769,7 @@
"url": "https://github.com/UI5/plugins-coding-agents.git",
"path": "plugins/ui5",
"ref": "main",
"sha": "9b3d7d80356f687725f9584988e4038dbead0d53"
"sha": "6d72751f0b2983c379aaa457fe4c7cf4a075a66d"
},
"homepage": "https://github.com/UI5/plugins-coding-agents"
},
@@ -2787,7 +2787,7 @@
"url": "https://github.com/UI5/plugins-coding-agents.git",
"path": "plugins/ui5-typescript-conversion",
"ref": "main",
"sha": "9b3d7d80356f687725f9584988e4038dbead0d53"
"sha": "80f2d93287054f9d30dd990e842e15bcfca581c9"
},
"homepage": "https://github.com/UI5/plugins-coding-agents"
},
@@ -2803,7 +2803,7 @@
"url": "https://github.com/val-town/plugins.git",
"path": "plugin",
"ref": "main",
"sha": "02631f998eda9b88d73d699703b062db059d506b"
"sha": "1f7928397349f2ccb228302d8b062c7f20745871"
},
"homepage": "https://val.town"
},
@@ -2881,7 +2881,7 @@
"source": {
"source": "url",
"url": "https://github.com/wix/skills.git",
"sha": "188ed338f39d70e5aef7f9a2582bbf338f223b78"
"sha": "def21835af3e6f0d86bf8c18acb1aaad7fdc9cd8"
},
"homepage": "https://dev.wix.com/docs/wix-cli/guides/development/about-wix-skills"
},
@@ -2907,7 +2907,7 @@
"url": "https://github.com/workos/skills.git",
"path": "plugins/workos",
"ref": "main",
"sha": "e8900cc504fd759407d1a963d13f59383fa39ebc"
"sha": "2c3acef61ea29296cb6e73e0c59fb5e98f0b1847"
},
"homepage": "https://workos.com"
},
@@ -2934,7 +2934,7 @@
"url": "https://github.com/zapier/zapier-mcp.git",
"path": "plugins/zapier",
"ref": "main",
"sha": "770167c572deaf74c588b45d88003ddf2145d608"
"sha": "ea8ed6b4de66e9bb46c12b3a38da8286e3770ad9"
},
"homepage": "https://github.com/zapier/zapier-mcp/tree/main/plugins/zapier"
},
@@ -2988,7 +2988,7 @@
"source": {
"source": "url",
"url": "https://github.com/zscaler/zscaler-mcp-server.git",
"sha": "f84ce4f0ed48047614a4202ac311cbdf00ea9a10"
"sha": "a2162c384e1ffb68b3bf14783ea9a1a762c85ff5"
},
"homepage": "https://github.com/zscaler/zscaler-mcp-server"
}

View File

@@ -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"

View File

@@ -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/<system>/`. 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,9 +20,14 @@ Commands take a `<system-dir>` 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 <system-dir>` 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.
## Secret handling
@@ -32,17 +37,23 @@ Legacy systems routinely contain live credentials, and assessment artifacts get
The commands are designed to be run in order, but each produces a standalone artifact so you can stop, review, and resume.
### `/modernize-preflight <system-dir> [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/<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`.
### `/modernize-map <system-dir>`
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/<system>/topology.json` (machine-readable), `analysis/<system>/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 24 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/<system>/topology.json` plus `analysis/<system>/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 <system-dir> [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/<system>/BUSINESS_RULES.md` and `analysis/<system>/DATA_OBJECTS.md`.
### `/modernize-brief <system-dir> [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/<system>/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/<system>/MODERNIZATION_BRIEF.md` and enters plan mode as a human-in-the-loop gate.
### `/modernize-reimagine <system-dir> <target-vision>`
Greenfield rebuild from extracted intent rather than a structural port. Mines a spec (`analysis/<system>/AI_NATIVE_SPEC.md`), designs a target architecture and has it adversarially reviewed (`analysis/<system>/REIMAGINED_ARCHITECTURE.md`), then **scaffolds services with executable acceptance tests** under `modernized/<system>-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.
@@ -50,6 +61,9 @@ Greenfield rebuild from extracted intent rather than a structural port. Mines a
### `/modernize-transform <system-dir> <module> <target-stack>`
Surgical, single-module strangler-fig rewrite. Plans first (HITL gate), then writes characterization tests via `test-engineer`, then an idiomatic target implementation under `modernized/<system>/<module>/`, 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 <system-dir>`
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 <system-dir>`
Security hardening pass on the **legacy** system: OWASP/CWE scan, dependency CVEs, secrets, injection. Spawns `security-auditor`. Produces `analysis/<system>/SECURITY_FINDINGS.md` ranked Critical / High / Medium / Low and a reviewed `analysis/<system>/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.
@@ -85,17 +99,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
@@ -116,6 +134,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

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

File diff suppressed because one or more lines are too long

View File

@@ -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 23 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.

View File

@@ -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 `<h2>`/accents, `system-ui` font, all CSS **inline** (no
external stylesheets). Load Mermaid from a CDN in `<head>`:
```html
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true, theme: 'dark' });
</script>
```json
{
"system": "<display name>",
"root": {
"id": "sys", "name": "<system>", "kind": "system",
"children": [
{ "id": "dom:<domain>", "name": "<Domain>", "kind": "domain",
"children": [
{ "id": "<MODULE>", "name": "<MODULE>", "kind": "module",
"language": "cobol", "loc": 1234, "file": "src/MODULE.cbl" }
] },
{ "id": "dom:data", "name": "Data stores", "kind": "domain",
"children": [
{ "id": "ds:<NAME>", "name": "<NAME>", "kind": "datastore" }
] }
]
},
"edges": [
{ "source": "<id>", "target": "<id>", "kind": "call" }
],
"entryPoints": ["<id>", "..."],
"deadEnds": ["<id>", "..."],
"observations": ["<architect observation>", "..."],
"flows": [
{ "name": "<business flow>", "persona": "<who experiences it>",
"description": "<one sentence, plain language>",
"steps": [
{ "label": "<business-language step>", "nodes": ["<id>", "<id>"] }
] }
]
}
```
Each diagram goes in a `<pre class="mermaid">...</pre>` 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`: 37 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 **24 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`: 38 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 `<pre class="mermaid">` block in TOPOLOGY.html, add a `<ul>`
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.

View File

@@ -0,0 +1,98 @@
---
description: Environment readiness check — analysis tools, build toolchain, source completeness, telemetry access
argument-hint: <system-dir> [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 12 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.

View File

@@ -3,7 +3,11 @@ description: Multi-agent greenfield rebuild — extract specs from legacy, desig
argument-hint: <system-dir> <target-vision>
---
**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, `<vision>` means that full remainder.
**Reimagine** `legacy/$1` as: <vision>
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 "<vision>":
- 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,
<vision> 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/<service-name>/."
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/<service-name>/."
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.

View File

@@ -0,0 +1,54 @@
---
description: Where am I in the modernization workflow — artifact inventory, staleness, secrets hygiene, next step
argument-hint: <system-dir>
---
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*/<module>/` 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 -- <path>`, 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.

View File

@@ -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 0aToolchain 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: <appropriate for $3>. 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 '<lines>p' legacy/$1/<file>) modernized/$1/$2/src/main/<file>
```
(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

View File

@@ -1,6 +1,6 @@
{
"name": "security-guidance",
"version": "2.0.3",
"version": "2.0.5",
"description": "Security review for Claude-generated code. Pattern-based warnings on edits, LLM-powered diff review on Stop, and an agentic commit reviewer that catches injection, XSS, SSRF, hardcoded secrets, and 25+ other vulnerability classes.",
"author": {
"name": "David Dworken",

View File

@@ -40,6 +40,15 @@ BUILD_FAILED = 3 # venv create or pip install raised/timed out
SKIP_SENTINEL = 5 # another SessionStart is currently building
HOOK_PY_INCOMPATIBLE = 6 # hook interpreter is <3.10 — SDK syntax can't load
# here no matter how the venv was built. See #2071.
# --target fallback: when `python -m venv` can't bootstrap pip (ensurepip
# missing — Debian python3-venv not installed, or a python.org/pyenv build
# without ensurepip), fall back to `pip install --target <dir>` which needs
# only the system pip, not venv/ensurepip. Telemetry (v2.0.4 sdk_has_pip
# probe) confirmed ~95% of venv_ensurepip_fail users HAVE pip, so this
# recovers the agentic reviewer for them instead of degrading to pattern +
# single-shot review. See #2154 follow-up.
BUILT_TARGET = 7 # venv ensurepip failed → SDK pip-installed via --target
NOOP_TARGET = 8 # --target libs already present and importable
# Phase + err-kind integer encoding for sdk_bootstrap_phase / sdk_bootstrap_err.
@@ -63,6 +72,7 @@ SDK_BOOTSTRAP_PHASE_CODES = {
"venv": 2, # python -m venv --clear
"pip": 3, # pip install
"main": 4, # uncaught exception above main()
"pip_target": 5, # `pip install --target` fallback (venv ensurepip failed)
}
SDK_BOOTSTRAP_ERR_CODES = {
"pip_no_match": 1,
@@ -102,6 +112,41 @@ SDK_BOOTSTRAP_ERR_CODES = {
"_uncategorized": 99,
}
# Exception-type encoding for the "exc:<TypeName>" err_kinds (the generic
# `except Exception` path — venv/pip raised a Python exception rather than
# a CalledProcessError with categorizable stderr).
#
# #2154 telemetry surfaced that the dominant remaining venv BUILD_FAILED
# bucket (phase=venv, err=99) is ~99% `exc:` with stderr_sig=NULL — i.e.
# exceptions, not stderr-bearing subprocess failures — so the stderr_sig
# hash couldn't distinguish them. This maps the exception TYPE to a stable
# code so BQ can tell FileNotFoundError (python/venv binary missing) from
# PermissionError (read-only home) from a bare OSError, etc.
#
# All the FileNotFoundError/PermissionError/etc. entries are OSError
# subclasses, so they ALSO carry an errno (see _encode_errno) — the type
# code gives the Python class, errno gives the OS-level cause. APPEND-ONLY.
SDK_BOOTSTRAP_EXC_CODES = {
"FileNotFoundError": 1, # interpreter/venv path component missing
"PermissionError": 2, # read-only home, sandboxed FS
"NotADirectoryError": 3,
"IsADirectoryError": 4,
"FileExistsError": 5, # (sentinel race is handled separately; this
# is FileExistsError from elsewhere in venv)
"OSError": 6, # bare OSError — errno carries the real cause
"BlockingIOError": 7,
"BrokenPipeError": 8,
"ConnectionError": 9,
"TimeoutError": 10, # distinct from subprocess.TimeoutExpired
"InterruptedError": 11,
"MemoryError": 12,
"UnicodeDecodeError": 13,
"ValueError": 14,
"RuntimeError": 15,
# 1698 reserved; APPEND-ONLY.
"_other_exc": 99, # an exception type not in this map
}
def _encode_phase(s):
"""Map err_phase string to its telemetry integer code, or 0 if unset.
@@ -158,6 +203,145 @@ def _encode_stderr_sig(err_kind):
return int.from_bytes(h[:2], "big") % 1000
def _encode_exc_kind(err_kind):
"""Map an "exc:<TypeName>[:errno]" err_kind to its exception-type code
(SDK_BOOTSTRAP_EXC_CODES). Returns 0 for non-exc err_kinds (so the
sdk_bootstrap_exc field auto-omits on stderr/categorized failures).
Unmapped exception types → 99 (_other_exc)."""
if not err_kind or not err_kind.startswith("exc:"):
return 0
# "exc:OSError:28" → "OSError"; "exc:RuntimeError" → "RuntimeError"
name = err_kind[len("exc:"):].split(":", 1)[0].strip()
if not name:
return 0
return SDK_BOOTSTRAP_EXC_CODES.get(name, SDK_BOOTSTRAP_EXC_CODES["_other_exc"])
def _encode_errno(err_kind):
"""Extract the OS errno from an "exc:<TypeName>:<errno>" err_kind.
OSError-family exceptions embed their errno (ENOENT=2, EACCES=13,
ENOSPC=28, …) — the OS-level cause is far more actionable than the
Python class alone. Returns 0 when absent/non-numeric (field omitted)."""
if not err_kind or not err_kind.startswith("exc:"):
return 0
parts = err_kind.split(":")
if len(parts) < 3:
return 0
try:
return int(parts[2])
except (ValueError, IndexError):
return 0
def _probe_has_pip() -> bool:
"""True iff the current interpreter can run pip (`-m pip --version`).
Probed only on the venv_ensurepip_fail path (see __main__), NOT on the
happy path — it's an extra subprocess we only want when diagnosing a
failure. The result decides whether a `pip install --target` fallback
(Option A) is even viable for this machine: ensurepip/venv missing but
pip present → --target would work; pip also missing → it wouldn't, and
the user needs a system package (python3-venv / a complete Python)."""
try:
r = subprocess.run(
[sys.executable, "-m", "pip", "--version"],
capture_output=True, timeout=10,
)
return r.returncode == 0
except Exception:
return False
def _pip_err_from_stderr(stderr_b):
"""Categorize a pip-install stderr into a known err_kind (the pip subset
of SDK_BOOTSTRAP_ERR_CODES). Used by the --target fallback; mirrors the
pip branches of main()'s inline categorizer. Kept as a sibling rather
than extracting main()'s chain (which also has venv-phase branches) to
avoid disturbing the working venv categorization."""
if isinstance(stderr_b, bytes):
s = stderr_b.decode("utf-8", errors="replace")
else:
s = str(stderr_b or "")
low = s.lower()
if "no matching distribution" in low or "could not find a version" in low:
return "pip_no_match"
if ("name or service not known" in low or "name resolution" in low
or "nodename nor servname" in low or "temporary failure in name" in low):
return "dns_fail"
if "connection refused" in low or "connection reset" in low:
return "conn_refused"
if "ssl" in low and ("verify" in low or "certificate" in low):
return "ssl_verify"
if "permission denied" in low or "read-only file system" in low:
return "perm_denied"
if "no module named pip" in low or "no module named ensurepip" in low:
return "no_pip"
if "no space left" in low or "disk quota" in low:
return "disk_full"
if "proxy" in low and ("authent" in low or "tunnel" in low or "407" in low):
return "proxy_auth"
if "timeout" in low or "timed out" in low:
return "stderr_timeout"
tail = next((ln.strip() for ln in reversed(s.splitlines()) if ln.strip()), "")[:60]
return f"other:{tail}" if tail else "other"
def _target_dir(state_dir) -> Path:
return Path(state_dir) / "agent-sdk-libs"
def _target_sdk_importable(state_dir) -> bool:
"""True iff the --target libs dir has an importable claude_agent_sdk,
probed with THIS interpreter (the one llm.py will import it from) and the
target dir prepended to sys.path. Cheap dir-check first to avoid a
subprocess on the common no-target path."""
target = _target_dir(state_dir)
if not (target / "claude_agent_sdk").is_dir():
return False
try:
r = subprocess.run(
[sys.executable, "-c",
"import sys; sys.path.insert(0, sys.argv[1]); import claude_agent_sdk",
str(target)],
capture_output=True, timeout=10,
)
return r.returncode == 0
except Exception:
return False
def _build_via_target(state_dir) -> tuple[int, str, str]:
"""Fallback install when `python -m venv` can't bootstrap pip (ensurepip
missing — Debian python3-venv absent, or a python.org/pyenv build without
ensurepip). `pip install --target <dir>` needs only the system pip, not
venv/ensurepip. v2.0.4 telemetry (sdk_has_pip) confirmed ~95% of
venv_ensurepip_fail users have pip. The consumer (llm.py) adds this flat
dir to sys.path. Returns (outcome, err_phase, err_kind).
--upgrade so a stale/partial target dir from a prior failed attempt
doesn't make pip refuse; --prefer-binary mirrors the venv path's wheel
preference (ARM64 Windows cryptography)."""
target = _target_dir(state_dir)
try:
subprocess.run(
[sys.executable, "-m", "pip", "install",
"--target", str(target), "--upgrade",
"--disable-pip-version-check", "--prefer-binary",
"claude-agent-sdk"],
capture_output=True, timeout=120, check=True,
)
return BUILT_TARGET, "", ""
except subprocess.CalledProcessError as e:
return BUILD_FAILED, "pip_target", _pip_err_from_stderr(e.stderr)
except subprocess.TimeoutExpired:
return BUILD_FAILED, "pip_target", "subprocess_timeout"
except Exception as e:
errno = getattr(e, "errno", None)
if isinstance(errno, int):
return BUILD_FAILED, "pip_target", f"exc:{type(e).__name__}:{errno}"
return BUILD_FAILED, "pip_target", f"exc:{type(e).__name__}"
def _sdk_on_syspath() -> bool:
# find_spec is ~10ms; actually importing the SDK pulls in
# transitive deps and costs ~800ms — too heavy for a
@@ -246,6 +430,12 @@ def main() -> tuple[int, str, str]:
except Exception:
pass # broken venv; rebuild below
# If a prior run installed the SDK via the --target fallback (ensurepip
# path), reuse it. Only reached when there's no working venv, so healthy
# NOOP_VENV users never pay for this probe.
if _target_sdk_importable(state_dir):
return NOOP_TARGET, "", ""
err_phase = ""
err_kind = ""
we_own_sentinel = False
@@ -360,10 +550,27 @@ def main() -> tuple[int, str, str]:
"",
)[:60]
err_kind = f"other:{tail}" if tail else "other"
# venv couldn't bootstrap pip (ensurepip missing) but pip itself may
# work — fall back to a flat `pip install --target`. Only this one
# category falls through; every other venv/pip failure is terminal.
# The finally block unlinks our sentinel first (so the target build
# isn't blocked by it); _build_via_target does the target install.
if err_kind == "venv_ensurepip_fail":
if we_own_sentinel:
sentinel.unlink(missing_ok=True)
we_own_sentinel = False
return _build_via_target(state_dir)
return BUILD_FAILED, err_phase, err_kind
except subprocess.TimeoutExpired:
return BUILD_FAILED, err_phase, "subprocess_timeout"
except Exception as e:
# Embed errno for OSError-family exceptions ("exc:OSError:28") so
# telemetry can decode the OS-level cause (ENOENT/EACCES/ENOSPC/…),
# not just the Python class. #2154 follow-up: this is the dominant
# remaining venv BUILD_FAILED bucket. See _encode_exc_kind/_encode_errno.
errno = getattr(e, "errno", None)
if isinstance(errno, int):
return BUILD_FAILED, err_phase, f"exc:{type(e).__name__}:{errno}"
return BUILD_FAILED, err_phase, f"exc:{type(e).__name__}"
finally:
# Only remove the sentinel if THIS process created it. The
@@ -467,6 +674,30 @@ if __name__ == "__main__":
sig = _encode_stderr_sig(err_kind)
if sig:
metrics["sdk_bootstrap_stderr_sig"] = sig
# Exception-type + errno for the "exc:" bucket (the dominant
# remaining venv BUILD_FAILED mode per #2154 telemetry). Both
# auto-omit (0) on stderr/categorized failures.
exc = _encode_exc_kind(err_kind)
if exc:
metrics["sdk_bootstrap_exc"] = exc
exc_errno = _encode_errno(err_kind)
if exc_errno:
metrics["sdk_bootstrap_errno"] = exc_errno
# venv_ensurepip_fail (code 11) is the top categorizable venv
# failure, and telemetry shows it's NOT just Debian — macOS has the
# most distinct affected users. Probe whether this interpreter has
# pip so we know if a `pip install --target` fallback (Option A)
# would actually help, vs the user needing a system package. Probed
# only here (not on the happy path) to avoid an extra subprocess
# per healthy session.
if _encode_err_kind(err_kind) == 11:
metrics["sdk_has_pip"] = _probe_has_pip()
# Interpreter version (major*100 + minor, e.g. 309 / 312), emitted on
# every bootstrap. Disambiguates the macOS cohort (Apple 3.9 vs a 3.10+
# with broken ensurepip) for both venv_ensurepip_fail AND
# HOOK_PY_INCOMPATIBLE (whose "py_3.9" err_kind otherwise collapses to
# err=99, losing the version). Cheap — no subprocess, just sys.version_info.
metrics["sdk_hook_py"] = sys.version_info[0] * 100 + sys.version_info[1]
pv = _plugin_version_int()
if pv:
metrics["pv"] = pv

View File

@@ -55,6 +55,12 @@ def _inject_agent_sdk_venv_into_syspath(state_dir):
candidates = (
glob.glob(os.path.join(venv_root, "lib", "python*", "site-packages"))
+ glob.glob(os.path.join(venv_root, "Lib", "site-packages"))
# `pip install --target` fallback (ensure_agent_sdk BUILT_TARGET, used
# when venv can't bootstrap pip): a FLAT layout — packages sit directly
# in agent-sdk-libs/, not under a site-packages subdir. See #2154
# follow-up. The pywin32 .pth bootstrap below applies here too (target
# installs don't process .pth at runtime, same as a manual venv insert).
+ [os.path.join(state_dir, "agent-sdk-libs")]
)
added = False
for sp in candidates: