torusguard 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.torusguard/.manifest.json +66 -63
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +30 -14
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +33 -16
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +31 -15
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +26 -16
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +24 -16
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +32 -18
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +24 -17
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +31 -18
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +28 -17
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +33 -17
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +31 -16
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +25 -16
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +24 -19
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +36 -19
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +21 -16
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +45 -18
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +20 -16
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +28 -19
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +25 -18
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +29 -19
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +23 -18
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +23 -18
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +36 -16
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +26 -17
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +30 -16
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +25 -16
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +28 -17
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +31 -17
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +31 -17
- package/.torusguard/rules_catalog.json +520 -0
- package/.torusguard/runs/report-latest.html +93 -7
- package/.torusguard/runs/run-20260912-214110-audit/findings.json +1256 -0
- package/.torusguard/runs/run-20260912-214110-audit/findings.md +534 -0
- package/.torusguard/runs/run-20260912-214110-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-214110-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-214813-audit/findings.json +992 -0
- package/.torusguard/runs/run-20260912-214813-audit/findings.md +422 -0
- package/.torusguard/runs/run-20260912-214813-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-214813-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-auth-003-49-7c96f3/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-platform-001-12-cf8156/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-rate-001-26-affcfa/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-sec-001-9-e22e50/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215555-audit/bundles/bnd-tg-ssrf-004-9-9803ad/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215555-audit/findings.json +530 -0
- package/.torusguard/runs/run-20260912-215555-audit/findings.md +232 -0
- package/.torusguard/runs/run-20260912-215555-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260912-215555-audit/remediation.md +102 -0
- package/.torusguard/runs/run-20260912-215555-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-215731-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-client-001-7-587129/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-db-002-9-5f7850/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/minimal_patch_plan.md +22 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-001-27-2486f1/patch.diff +10 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-001-12-cf8156/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/minimal_patch_plan.md +23 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-17-876973/patch.diff +11 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/minimal_patch_plan.md +23 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-platform-002-5-40c794/patch.diff +11 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-001-26-affcfa/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-rate-002-54-0b38d2/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-18-a3c1e8/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-001-9-e22e50/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-28-a1a0a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-sec-004-30-00569e/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/metadata.json +17 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260912-215731-audit/bundles/bnd-tg-ssrf-004-9-9803ad/patch.diff +9 -0
- package/.torusguard/runs/run-20260912-215731-audit/diff_summary.md +186 -0
- package/.torusguard/runs/run-20260912-215731-audit/findings.json +497 -0
- package/.torusguard/runs/run-20260912-215731-audit/findings.md +218 -0
- package/.torusguard/runs/run-20260912-215731-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260912-215731-audit/recheck.md +76 -0
- package/.torusguard/runs/run-20260912-215731-audit/remediation.md +234 -0
- package/.torusguard/runs/run-20260912-215731-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220134-audit/findings.json +68 -0
- package/.torusguard/runs/run-20260912-220134-audit/findings.md +36 -0
- package/.torusguard/runs/run-20260912-220134-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220134-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220200-audit/findings.json +1 -0
- package/.torusguard/runs/run-20260912-220200-audit/findings.md +8 -0
- package/.torusguard/runs/run-20260912-220200-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220200-audit/recheck.md +6 -0
- package/.torusguard/runs/run-20260912-220200-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260912-220227-audit/findings.json +1 -0
- package/.torusguard/runs/run-20260912-220227-audit/findings.md +8 -0
- package/.torusguard/runs/run-20260912-220227-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260912-220227-audit/recheck.md +6 -0
- package/.torusguard/runs/run-20260912-220227-audit/summary.md +5 -0
- package/.torusguard/scripts/__pycache__/audit_runner.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/finding_scorer.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/report_sync.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/term_ui.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +383 -377
- package/.torusguard/scripts/audit_runner.py +1306 -653
- package/.torusguard/scripts/finding_scorer.py +14 -2
- package/.torusguard/scripts/harden_runner.py +628 -455
- package/.torusguard/scripts/recheck_runner.py +248 -238
- package/.torusguard/scripts/recipes_runner.py +137 -137
- package/.torusguard/scripts/report_sync.py +423 -0
- package/.torusguard/scripts/sarif_exporter.py +116 -116
- package/.torusguard/scripts/term_ui.py +162 -162
- package/.torusguard/snapshots/run-20260912-215731-audit/demo/playground/vulnerable_nextjs/actions.ts.bak +24 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/hardened-react-express/server/index.js.bak +121 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/python/fastapi-vuln/main.py.bak +20 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/client/vite.config.js.bak +12 -0
- package/.torusguard/snapshots/run-20260912-215731-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/workflows/apply.md +11 -4
- package/.torusguard/workflows/audit.md +7 -1
- package/.torusguard/workflows/authorize.md +2 -1
- package/.torusguard/workflows/exploit-check.md +2 -1
- package/.torusguard/workflows/harden.md +7 -1
- package/.torusguard/workflows/init.md +6 -1
- package/.torusguard/workflows/memory.md +2 -1
- package/.torusguard/workflows/recheck.md +7 -1
- package/.torusguard/workflows/report.md +7 -1
- package/.torusguard/workflows/status.md +6 -1
- package/.torusguard/workflows/verify.md +6 -1
- package/.torusguard/workflows/web-validate.md +2 -1
- package/README.md +470 -345
- package/bin/torusguard.js +550 -545
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +73 -72
- package/skills/torusguard/payload/.manifest.json +66 -63
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +30 -14
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +33 -16
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +31 -15
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +26 -16
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +24 -16
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +32 -18
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +24 -17
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +31 -18
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +28 -17
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +33 -17
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +31 -16
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +25 -16
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +24 -19
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +36 -19
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +21 -16
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +45 -18
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +20 -16
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +28 -19
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +25 -18
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +29 -19
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +23 -18
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +23 -18
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +36 -16
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +26 -17
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +30 -16
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +25 -16
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +28 -17
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +31 -17
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +31 -17
- package/skills/torusguard/payload/rules_catalog.json +520 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +383 -377
- package/skills/torusguard/payload/scripts/audit_runner.py +1306 -653
- package/skills/torusguard/payload/scripts/finding_scorer.py +14 -2
- package/skills/torusguard/payload/scripts/harden_runner.py +628 -455
- package/skills/torusguard/payload/scripts/recheck_runner.py +248 -238
- package/skills/torusguard/payload/scripts/recipes_runner.py +137 -137
- package/skills/torusguard/payload/scripts/report_sync.py +423 -0
- package/skills/torusguard/payload/scripts/sarif_exporter.py +116 -116
- package/skills/torusguard/payload/scripts/term_ui.py +162 -162
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +75 -72
- package/skills/torusguard/payload/skills/torusguard-apply/SKILL.md +84 -80
- package/skills/torusguard/payload/skills/torusguard-audit/SKILL.md +87 -83
- package/skills/torusguard/payload/skills/torusguard-authorize/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-exploit-check/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-full/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-harden/SKILL.md +98 -94
- package/skills/torusguard/payload/skills/torusguard-init/SKILL.md +68 -64
- package/skills/torusguard/payload/skills/torusguard-recheck/SKILL.md +81 -77
- package/skills/torusguard/payload/skills/torusguard-report/SKILL.md +76 -72
- package/skills/torusguard/payload/skills/torusguard-status/SKILL.md +62 -58
- package/skills/torusguard/payload/skills/torusguard-verify/SKILL.md +7 -2
- package/skills/torusguard/payload/skills/torusguard-web-validate/SKILL.md +7 -2
- package/skills/torusguard/payload/workflows/apply.md +11 -4
- package/skills/torusguard/payload/workflows/audit.md +7 -1
- package/skills/torusguard/payload/workflows/authorize.md +2 -1
- package/skills/torusguard/payload/workflows/exploit-check.md +2 -1
- package/skills/torusguard/payload/workflows/harden.md +7 -1
- package/skills/torusguard/payload/workflows/init.md +6 -1
- package/skills/torusguard/payload/workflows/memory.md +2 -1
- package/skills/torusguard/payload/workflows/recheck.md +7 -1
- package/skills/torusguard/payload/workflows/report.md +7 -1
- package/skills/torusguard/payload/workflows/status.md +6 -1
- package/skills/torusguard/payload/workflows/verify.md +6 -1
- package/skills/torusguard/payload/workflows/web-validate.md +2 -1
- package/skills/torusguard-apply/SKILL.md +84 -80
- package/skills/torusguard-audit/SKILL.md +87 -83
- package/skills/torusguard-authorize/SKILL.md +7 -2
- package/skills/torusguard-exploit-check/SKILL.md +7 -2
- package/skills/torusguard-full/SKILL.md +7 -2
- package/skills/torusguard-harden/SKILL.md +98 -94
- package/skills/torusguard-init/SKILL.md +68 -64
- package/skills/torusguard-recheck/SKILL.md +81 -77
- package/skills/torusguard-report/SKILL.md +76 -72
- package/skills/torusguard-status/SKILL.md +62 -58
- package/skills/torusguard-verify/SKILL.md +7 -2
- package/skills/torusguard-web-validate/SKILL.md +7 -2
|
@@ -1,238 +1,248 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
TorusGuard Targeted Differential Recheck Engine (v1.3.
|
|
4
|
-
Executes scoped differential re-audits verifying only impacted files and adjacent boundaries.
|
|
5
|
-
Evaluates formal status transitions (Confirmed Fixed vs Regressed vs Unresolved), updates run manifest,
|
|
6
|
-
and records verification telemetry in the persistent security memory subsystem.
|
|
7
|
-
Standardized 75-column terminal UI formatting.
|
|
8
|
-
|
|
9
|
-
Pure Python 3.10+ standard library (zero external dependencies).
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
import sys
|
|
13
|
-
import os
|
|
14
|
-
import re
|
|
15
|
-
import json
|
|
16
|
-
import argparse
|
|
17
|
-
import datetime
|
|
18
|
-
from pathlib import Path
|
|
19
|
-
from typing import Dict, List, Any, Optional
|
|
20
|
-
|
|
21
|
-
# Ensure scripts dir is in sys.path for term_ui import
|
|
22
|
-
scripts_dir = Path(__file__).resolve().parent
|
|
23
|
-
if str(scripts_dir) not in sys.path:
|
|
24
|
-
sys.path.insert(0, str(scripts_dir))
|
|
25
|
-
|
|
26
|
-
try:
|
|
27
|
-
import term_ui
|
|
28
|
-
except ImportError:
|
|
29
|
-
term_ui = None
|
|
30
|
-
|
|
31
|
-
# Windows console UTF-8 support
|
|
32
|
-
if sys.stdout and hasattr(sys.stdout, "reconfigure"):
|
|
33
|
-
try:
|
|
34
|
-
getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
|
|
35
|
-
except Exception:
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
# ─── Timezone Configuration: Indian Standard Time (IST, UTC+05:30) ───────────
|
|
39
|
-
IST = datetime.timezone(datetime.timedelta(hours=5, minutes=30), name="IST")
|
|
40
|
-
|
|
41
|
-
def get_ist_now() -> datetime.datetime:
|
|
42
|
-
return datetime.datetime.now(IST)
|
|
43
|
-
|
|
44
|
-
# ─── Formatting Helpers ────────────────────────────────────────────────────────
|
|
45
|
-
BOLD = "\033[1m"
|
|
46
|
-
DIM = "\033[2m"
|
|
47
|
-
RESET = "\033[0m"
|
|
48
|
-
CYAN = "\033[36m"
|
|
49
|
-
GREEN = "\033[32m"
|
|
50
|
-
YELLOW = "\033[33m"
|
|
51
|
-
WHITE = "\033[97m"
|
|
52
|
-
GRAY = "\033[90m"
|
|
53
|
-
RED = "\033[31m"
|
|
54
|
-
|
|
55
|
-
def box_line(content: str, width: int = 67, border: str = "│", border_color: str = CYAN) -> str:
|
|
56
|
-
if term_ui:
|
|
57
|
-
return term_ui.format_box_line(content, width=width, border=border, border_color=border_color)
|
|
58
|
-
return f" {border_color}{border}{RESET} {content}"
|
|
59
|
-
|
|
60
|
-
def box_header(title: str, subtitle: str = "", version: str = "v1.3.
|
|
61
|
-
if term_ui:
|
|
62
|
-
return term_ui.card_header(title, subtitle, version, border_color)
|
|
63
|
-
return f"=== {title} ({version}) ==="
|
|
64
|
-
|
|
65
|
-
def border_top(title: str = "", border_color: str = CYAN, double: bool = False) -> str:
|
|
66
|
-
if term_ui:
|
|
67
|
-
return term_ui.card_border_top(title, border_color=border_color, double=double)
|
|
68
|
-
return "┌" + "─" * 71 + "┐"
|
|
69
|
-
|
|
70
|
-
def border_bottom(border_color: str = CYAN, double: bool = False) -> str:
|
|
71
|
-
if term_ui:
|
|
72
|
-
return term_ui.card_border_bottom(border_color=border_color, double=double)
|
|
73
|
-
return "└" + "─" * 71 + "┘"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def find_latest_audit_run(runs_dir: Path) -> Optional[Path]:
|
|
77
|
-
if not runs_dir.is_dir():
|
|
78
|
-
return None
|
|
79
|
-
runs = sorted(runs_dir.glob("run-*-audit"), key=lambda p: p.stat().st_mtime, reverse=True)
|
|
80
|
-
return runs[0] if runs else None
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def execute_recheck(target_root: Path, run_id_arg: Optional[str] = None) -> Dict[str, Any]:
|
|
84
|
-
runs_dir = target_root / ".torusguard" / "runs"
|
|
85
|
-
if run_id_arg:
|
|
86
|
-
run_folder = runs_dir / run_id_arg
|
|
87
|
-
else:
|
|
88
|
-
run_folder = find_latest_audit_run(runs_dir)
|
|
89
|
-
|
|
90
|
-
if not run_folder or not run_folder.is_dir():
|
|
91
|
-
print(f"\n {RED}✖ No audit run found to recheck.{RESET}\n")
|
|
92
|
-
sys.exit(1)
|
|
93
|
-
|
|
94
|
-
# Import audit scanner and memory engine
|
|
95
|
-
try:
|
|
96
|
-
import audit_runner
|
|
97
|
-
except ImportError:
|
|
98
|
-
audit_runner = None
|
|
99
|
-
try:
|
|
100
|
-
import memory_engine
|
|
101
|
-
except ImportError:
|
|
102
|
-
memory_engine = None
|
|
103
|
-
|
|
104
|
-
bundles_dir = run_folder / "bundles"
|
|
105
|
-
bundle_meta_files = list(bundles_dir.glob("*/metadata.json")) if bundles_dir.is_dir() else []
|
|
106
|
-
|
|
107
|
-
# Header Card
|
|
108
|
-
print()
|
|
109
|
-
print(box_header("🛡️ TORUSGUARD DIFFERENTIAL RECHECK ENGINE", "Targeted Differential AST Scan & Regression Verification", "v1.3.
|
|
110
|
-
print()
|
|
111
|
-
|
|
112
|
-
print(border_top("Recheck Verification Scope"))
|
|
113
|
-
print(box_line(f"Active Run: {WHITE}{run_folder.name}{RESET}"))
|
|
114
|
-
print(box_line(f"Target Root: {WHITE}{target_root}{RESET}"))
|
|
115
|
-
print(border_bottom())
|
|
116
|
-
print()
|
|
117
|
-
|
|
118
|
-
recheck_results = []
|
|
119
|
-
confirmed_count = 0
|
|
120
|
-
regressed_count = 0
|
|
121
|
-
unresolved_count = 0
|
|
122
|
-
|
|
123
|
-
recheck_md_lines = [
|
|
124
|
-
f"# TorusGuard Differential Recheck Report",
|
|
125
|
-
f"**Run ID:** `{run_folder.name}` ",
|
|
126
|
-
f"**Timestamp:** `{get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}` \n",
|
|
127
|
-
"---",
|
|
128
|
-
"## Recheck Transition Catalog\n"
|
|
129
|
-
]
|
|
130
|
-
|
|
131
|
-
for mf in bundle_meta_files:
|
|
132
|
-
try:
|
|
133
|
-
bdata = json.loads(mf.read_text(encoding="utf-8"))
|
|
134
|
-
except Exception:
|
|
135
|
-
continue
|
|
136
|
-
|
|
137
|
-
rule_id = bdata.get("rule_id", "")
|
|
138
|
-
rel_path = bdata.get("target_file", "")
|
|
139
|
-
target_path = target_root / rel_path
|
|
140
|
-
|
|
141
|
-
if not target_path.is_file():
|
|
142
|
-
continue
|
|
143
|
-
|
|
144
|
-
# Differential scan on this single modified file
|
|
145
|
-
if audit_runner:
|
|
146
|
-
file_findings = audit_runner.scan_file(target_path, target_root)
|
|
147
|
-
matching_rule_findings = [f for f in file_findings if f.get("rule_id") == rule_id]
|
|
148
|
-
else:
|
|
149
|
-
matching_rule_findings = []
|
|
150
|
-
|
|
151
|
-
if not matching_rule_findings:
|
|
152
|
-
outcome = "Confirmed Fixed"
|
|
153
|
-
confirmed_count += 1
|
|
154
|
-
status_icon = f"{GREEN}✔ [Confirmed Fixed]{RESET}"
|
|
155
|
-
# Record in memory
|
|
156
|
-
if memory_engine:
|
|
157
|
-
try:
|
|
158
|
-
memory_engine.record_event("fix_verified", {
|
|
159
|
-
"rule_id": rule_id,
|
|
160
|
-
"file_path": rel_path,
|
|
161
|
-
"verification_result": "fixed"
|
|
162
|
-
}, root_dir=target_root)
|
|
163
|
-
except Exception:
|
|
164
|
-
pass
|
|
165
|
-
else:
|
|
166
|
-
outcome = "Unresolved"
|
|
167
|
-
unresolved_count += 1
|
|
168
|
-
status_icon = f"{YELLOW}⚠ [Unresolved]{RESET}"
|
|
169
|
-
|
|
170
|
-
recheck_results.append({
|
|
171
|
-
"rule_id": rule_id,
|
|
172
|
-
"target_file": rel_path,
|
|
173
|
-
"outcome": outcome,
|
|
174
|
-
"title": bdata.get("title", rule_id)
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
recheck_md_lines.append(f"### [{rule_id}] {bdata.get('title')}")
|
|
178
|
-
recheck_md_lines.append(f"- **File:** `{rel_path}`")
|
|
179
|
-
recheck_md_lines.append(f"- **Outcome:** `{outcome}`")
|
|
180
|
-
recheck_md_lines.append(f"- **Verification Timestamp:** {get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}\n")
|
|
181
|
-
|
|
182
|
-
print(f" {status_icon} {WHITE}{rule_id}{RESET} on {rel_path}")
|
|
183
|
-
|
|
184
|
-
# Write recheck.md
|
|
185
|
-
(run_folder / "recheck.md").write_text("\n".join(recheck_md_lines), encoding="utf-8")
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
print(
|
|
209
|
-
print(
|
|
210
|
-
print(box_line(f"
|
|
211
|
-
print(
|
|
212
|
-
print()
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
TorusGuard Targeted Differential Recheck Engine (v1.3.5)
|
|
4
|
+
Executes scoped differential re-audits verifying only impacted files and adjacent boundaries.
|
|
5
|
+
Evaluates formal status transitions (Confirmed Fixed vs Regressed vs Unresolved), updates run manifest,
|
|
6
|
+
and records verification telemetry in the persistent security memory subsystem.
|
|
7
|
+
Standardized 75-column terminal UI formatting.
|
|
8
|
+
|
|
9
|
+
Pure Python 3.10+ standard library (zero external dependencies).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import sys
|
|
13
|
+
import os
|
|
14
|
+
import re
|
|
15
|
+
import json
|
|
16
|
+
import argparse
|
|
17
|
+
import datetime
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Dict, List, Any, Optional
|
|
20
|
+
|
|
21
|
+
# Ensure scripts dir is in sys.path for term_ui import
|
|
22
|
+
scripts_dir = Path(__file__).resolve().parent
|
|
23
|
+
if str(scripts_dir) not in sys.path:
|
|
24
|
+
sys.path.insert(0, str(scripts_dir))
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
import term_ui
|
|
28
|
+
except ImportError:
|
|
29
|
+
term_ui = None
|
|
30
|
+
|
|
31
|
+
# Windows console UTF-8 support
|
|
32
|
+
if sys.stdout and hasattr(sys.stdout, "reconfigure"):
|
|
33
|
+
try:
|
|
34
|
+
getattr(sys.stdout, "reconfigure")(encoding="utf-8", errors="replace")
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
# ─── Timezone Configuration: Indian Standard Time (IST, UTC+05:30) ───────────
|
|
39
|
+
IST = datetime.timezone(datetime.timedelta(hours=5, minutes=30), name="IST")
|
|
40
|
+
|
|
41
|
+
def get_ist_now() -> datetime.datetime:
|
|
42
|
+
return datetime.datetime.now(IST)
|
|
43
|
+
|
|
44
|
+
# ─── Formatting Helpers ────────────────────────────────────────────────────────
|
|
45
|
+
BOLD = "\033[1m"
|
|
46
|
+
DIM = "\033[2m"
|
|
47
|
+
RESET = "\033[0m"
|
|
48
|
+
CYAN = "\033[36m"
|
|
49
|
+
GREEN = "\033[32m"
|
|
50
|
+
YELLOW = "\033[33m"
|
|
51
|
+
WHITE = "\033[97m"
|
|
52
|
+
GRAY = "\033[90m"
|
|
53
|
+
RED = "\033[31m"
|
|
54
|
+
|
|
55
|
+
def box_line(content: str, width: int = 67, border: str = "│", border_color: str = CYAN) -> str:
|
|
56
|
+
if term_ui:
|
|
57
|
+
return term_ui.format_box_line(content, width=width, border=border, border_color=border_color)
|
|
58
|
+
return f" {border_color}{border}{RESET} {content}"
|
|
59
|
+
|
|
60
|
+
def box_header(title: str, subtitle: str = "", version: str = "v1.3.5", border_color: str = CYAN) -> str:
|
|
61
|
+
if term_ui:
|
|
62
|
+
return term_ui.card_header(title, subtitle, version, border_color)
|
|
63
|
+
return f"=== {title} ({version}) ==="
|
|
64
|
+
|
|
65
|
+
def border_top(title: str = "", border_color: str = CYAN, double: bool = False) -> str:
|
|
66
|
+
if term_ui:
|
|
67
|
+
return term_ui.card_border_top(title, border_color=border_color, double=double)
|
|
68
|
+
return "┌" + "─" * 71 + "┐"
|
|
69
|
+
|
|
70
|
+
def border_bottom(border_color: str = CYAN, double: bool = False) -> str:
|
|
71
|
+
if term_ui:
|
|
72
|
+
return term_ui.card_border_bottom(border_color=border_color, double=double)
|
|
73
|
+
return "└" + "─" * 71 + "┘"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def find_latest_audit_run(runs_dir: Path) -> Optional[Path]:
|
|
77
|
+
if not runs_dir.is_dir():
|
|
78
|
+
return None
|
|
79
|
+
runs = sorted(runs_dir.glob("run-*-audit"), key=lambda p: p.stat().st_mtime, reverse=True)
|
|
80
|
+
return runs[0] if runs else None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def execute_recheck(target_root: Path, run_id_arg: Optional[str] = None) -> Dict[str, Any]:
|
|
84
|
+
runs_dir = target_root / ".torusguard" / "runs"
|
|
85
|
+
if run_id_arg:
|
|
86
|
+
run_folder = runs_dir / run_id_arg
|
|
87
|
+
else:
|
|
88
|
+
run_folder = find_latest_audit_run(runs_dir)
|
|
89
|
+
|
|
90
|
+
if not run_folder or not run_folder.is_dir():
|
|
91
|
+
print(f"\n {RED}✖ No audit run found to recheck.{RESET}\n")
|
|
92
|
+
sys.exit(1)
|
|
93
|
+
|
|
94
|
+
# Import audit scanner and memory engine
|
|
95
|
+
try:
|
|
96
|
+
import audit_runner
|
|
97
|
+
except ImportError:
|
|
98
|
+
audit_runner = None
|
|
99
|
+
try:
|
|
100
|
+
import memory_engine
|
|
101
|
+
except ImportError:
|
|
102
|
+
memory_engine = None
|
|
103
|
+
|
|
104
|
+
bundles_dir = run_folder / "bundles"
|
|
105
|
+
bundle_meta_files = list(bundles_dir.glob("*/metadata.json")) if bundles_dir.is_dir() else []
|
|
106
|
+
|
|
107
|
+
# Header Card
|
|
108
|
+
print()
|
|
109
|
+
print(box_header("🛡️ TORUSGUARD DIFFERENTIAL RECHECK ENGINE", "Targeted Differential AST Scan & Regression Verification", "v1.3.5"))
|
|
110
|
+
print()
|
|
111
|
+
|
|
112
|
+
print(border_top("Recheck Verification Scope"))
|
|
113
|
+
print(box_line(f"Active Run: {WHITE}{run_folder.name}{RESET}"))
|
|
114
|
+
print(box_line(f"Target Root: {WHITE}{target_root}{RESET}"))
|
|
115
|
+
print(border_bottom())
|
|
116
|
+
print()
|
|
117
|
+
|
|
118
|
+
recheck_results = []
|
|
119
|
+
confirmed_count = 0
|
|
120
|
+
regressed_count = 0
|
|
121
|
+
unresolved_count = 0
|
|
122
|
+
|
|
123
|
+
recheck_md_lines = [
|
|
124
|
+
f"# TorusGuard Differential Recheck Report",
|
|
125
|
+
f"**Run ID:** `{run_folder.name}` ",
|
|
126
|
+
f"**Timestamp:** `{get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}` \n",
|
|
127
|
+
"---",
|
|
128
|
+
"## Recheck Transition Catalog\n"
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
for mf in bundle_meta_files:
|
|
132
|
+
try:
|
|
133
|
+
bdata = json.loads(mf.read_text(encoding="utf-8"))
|
|
134
|
+
except Exception:
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
rule_id = bdata.get("rule_id", "")
|
|
138
|
+
rel_path = bdata.get("target_file", "")
|
|
139
|
+
target_path = target_root / rel_path
|
|
140
|
+
|
|
141
|
+
if not target_path.is_file():
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
# Differential scan on this single modified file
|
|
145
|
+
if audit_runner:
|
|
146
|
+
file_findings = audit_runner.scan_file(target_path, target_root)
|
|
147
|
+
matching_rule_findings = [f for f in file_findings if f.get("rule_id") == rule_id]
|
|
148
|
+
else:
|
|
149
|
+
matching_rule_findings = []
|
|
150
|
+
|
|
151
|
+
if not matching_rule_findings:
|
|
152
|
+
outcome = "Confirmed Fixed"
|
|
153
|
+
confirmed_count += 1
|
|
154
|
+
status_icon = f"{GREEN}✔ [Confirmed Fixed]{RESET}"
|
|
155
|
+
# Record in memory
|
|
156
|
+
if memory_engine:
|
|
157
|
+
try:
|
|
158
|
+
memory_engine.record_event("fix_verified", {
|
|
159
|
+
"rule_id": rule_id,
|
|
160
|
+
"file_path": rel_path,
|
|
161
|
+
"verification_result": "fixed"
|
|
162
|
+
}, root_dir=target_root)
|
|
163
|
+
except Exception:
|
|
164
|
+
pass
|
|
165
|
+
else:
|
|
166
|
+
outcome = "Unresolved"
|
|
167
|
+
unresolved_count += 1
|
|
168
|
+
status_icon = f"{YELLOW}⚠ [Unresolved]{RESET}"
|
|
169
|
+
|
|
170
|
+
recheck_results.append({
|
|
171
|
+
"rule_id": rule_id,
|
|
172
|
+
"target_file": rel_path,
|
|
173
|
+
"outcome": outcome,
|
|
174
|
+
"title": bdata.get("title", rule_id)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
recheck_md_lines.append(f"### [{rule_id}] {bdata.get('title')}")
|
|
178
|
+
recheck_md_lines.append(f"- **File:** `{rel_path}`")
|
|
179
|
+
recheck_md_lines.append(f"- **Outcome:** `{outcome}`")
|
|
180
|
+
recheck_md_lines.append(f"- **Verification Timestamp:** {get_ist_now().strftime('%Y-%m-%d %H:%M:%S IST')}\n")
|
|
181
|
+
|
|
182
|
+
print(f" {status_icon} {WHITE}{rule_id}{RESET} on {rel_path}")
|
|
183
|
+
|
|
184
|
+
# Write recheck.md
|
|
185
|
+
(run_folder / "recheck.md").write_text("\n".join(recheck_md_lines), encoding="utf-8")
|
|
186
|
+
try:
|
|
187
|
+
import report_sync
|
|
188
|
+
report_sync.record_recheck_results(target_root, {
|
|
189
|
+
"fixed": [r for r in recheck_results if r.get("outcome") == "Confirmed Fixed"],
|
|
190
|
+
"regressed": [r for r in recheck_results if r.get("outcome") == "Regressed"],
|
|
191
|
+
"remaining": [r for r in recheck_results if r.get("outcome") == "Unresolved"]
|
|
192
|
+
}, run_folder.name)
|
|
193
|
+
except Exception:
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
# Update manifest
|
|
197
|
+
manifest_file = run_folder / "manifest.json"
|
|
198
|
+
if manifest_file.is_file():
|
|
199
|
+
try:
|
|
200
|
+
mdata = json.loads(manifest_file.read_text(encoding="utf-8"))
|
|
201
|
+
mdata["status"] = "verified_fixed" if regressed_count == 0 and unresolved_count == 0 else "recheck_completed"
|
|
202
|
+
mdata["confirmed_fixed_count"] = confirmed_count
|
|
203
|
+
mdata["regressed_count"] = regressed_count
|
|
204
|
+
manifest_file.write_text(json.dumps(mdata, indent=2), encoding="utf-8")
|
|
205
|
+
except Exception:
|
|
206
|
+
pass
|
|
207
|
+
|
|
208
|
+
print()
|
|
209
|
+
print(border_top("Recheck Summary"))
|
|
210
|
+
print(box_line(f"Confirmed Fixed:{GREEN}{confirmed_count} vulnerabilities verified closed{RESET}"))
|
|
211
|
+
print(box_line(f"Regressed: {RED if regressed_count > 0 else GREEN}{regressed_count} regressions detected{RESET}"))
|
|
212
|
+
print(box_line(f"Unresolved: {YELLOW if unresolved_count > 0 else GREEN}{unresolved_count} unresolved{RESET}"))
|
|
213
|
+
print(box_line(f"Memory Sync: {GREEN}Verification events synced to persistent memory engine{RESET}"))
|
|
214
|
+
print(border_bottom())
|
|
215
|
+
print()
|
|
216
|
+
|
|
217
|
+
print(border_top("Next Governed Action", border_color=GREEN, double=True))
|
|
218
|
+
print(box_line(f"Living Report: {CYAN}security_report.md (verified closures recorded){RESET}", border="║", border_color=GREEN))
|
|
219
|
+
print(box_line(f"Visual Dashboard: {BOLD}{WHITE}npx torusguard report --html{RESET} (Updated posture score)", border="║", border_color=GREEN))
|
|
220
|
+
print(box_line(f"View Recipes: {CYAN}npx torusguard recipes{RESET} (Active golden fix recipes)", border="║", border_color=GREEN))
|
|
221
|
+
print(border_bottom(border_color=GREEN, double=True))
|
|
222
|
+
print()
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
"run_folder": str(run_folder),
|
|
226
|
+
"confirmed_fixed_count": confirmed_count,
|
|
227
|
+
"regressed_count": regressed_count,
|
|
228
|
+
"unresolved_count": unresolved_count,
|
|
229
|
+
"results": recheck_results
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def main():
|
|
234
|
+
parser = argparse.ArgumentParser(description="TorusGuard Differential Recheck Engine")
|
|
235
|
+
parser.add_argument("path", nargs="?", default=".", help="Target project root directory")
|
|
236
|
+
parser.add_argument("--run", "-r", help="Explicit run ID to recheck")
|
|
237
|
+
parser.add_argument("--json", action="store_true", help="Output raw JSON")
|
|
238
|
+
args = parser.parse_args()
|
|
239
|
+
|
|
240
|
+
target = Path(args.path).resolve()
|
|
241
|
+
result = execute_recheck(target, run_id_arg=args.run)
|
|
242
|
+
|
|
243
|
+
if args.json:
|
|
244
|
+
print(json.dumps(result, indent=2))
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
if __name__ == "__main__":
|
|
248
|
+
main()
|