torusguard 1.3.0 → 1.3.2
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 +113 -9
- package/.torusguard/rules/README.md +93 -62
- package/.torusguard/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/.torusguard/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/.torusguard/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/.torusguard/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/.torusguard/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/.torusguard/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/.torusguard/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/.torusguard/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/.torusguard/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/.torusguard/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/.torusguard/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/.torusguard/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/.torusguard/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/.torusguard/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/.torusguard/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/.torusguard/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/.torusguard/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/.torusguard/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/.torusguard/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/.torusguard/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/.torusguard/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/.torusguard/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/.torusguard/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/.torusguard/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/.torusguard/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/.torusguard/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/.torusguard/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/.torusguard/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/.torusguard/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/.torusguard/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/.torusguard/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/.torusguard/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/.torusguard/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/.torusguard/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/.torusguard/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/.torusguard/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/.torusguard/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/.torusguard/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/.torusguard/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/.torusguard/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/.torusguard/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/.torusguard/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/.torusguard/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/.torusguard/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/.torusguard/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/.torusguard/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/.torusguard/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/.torusguard/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/.torusguard/runs/report-latest.html +62 -20
- package/.torusguard/runs/run-20260908-112648-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112648-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112648-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112648-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-112722-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-112722-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-112722-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113004-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113004-audit/manifest.json +12 -0
- package/.torusguard/runs/run-20260908-113004-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-113127-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.json +1520 -0
- package/.torusguard/runs/run-20260908-113127-audit/findings.md +560 -0
- package/.torusguard/runs/run-20260908-113127-audit/manifest.json +13 -0
- package/.torusguard/runs/run-20260908-113127-audit/remediation.md +262 -0
- package/.torusguard/runs/run-20260908-113127-audit/summary.md +5 -0
- package/.torusguard/runs/run-20260908-115240-audit/apply_plan.md +6 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-115-9a059e/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-119-61557c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-265-996ca3/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-334-cb819d/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-503-d11cf8/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-db-004-79-91f41f/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-107-516a40/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-128-7809a1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-002-232-1b45d1/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-input-003-53-d167b4/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-platform-001-168-5027cb/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-209-4f6424/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-257-89bf34/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-341-ce228c/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-355-7b190b/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-64-5af31a/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/metadata.json +15 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/minimal_patch_plan.md +21 -0
- package/.torusguard/runs/run-20260908-115240-audit/bundles/bnd-tg-sec-001-9-f51467/patch.diff +9 -0
- package/.torusguard/runs/run-20260908-115240-audit/diff_summary.md +221 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.json +1553 -0
- package/.torusguard/runs/run-20260908-115240-audit/findings.md +572 -0
- package/.torusguard/runs/run-20260908-115240-audit/manifest.json +14 -0
- package/.torusguard/runs/run-20260908-115240-audit/recheck.md +91 -0
- package/.torusguard/runs/run-20260908-115240-audit/remediation.md +278 -0
- package/.torusguard/runs/run-20260908-115240-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__/memory_engine.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/monorepo_detector.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/run_manager.cpython-311.pyc +0 -0
- package/.torusguard/scripts/__pycache__/stack_detect.cpython-311.pyc +0 -0
- package/.torusguard/scripts/apply_runner.py +339 -0
- package/.torusguard/scripts/audit_runner.py +550 -0
- package/.torusguard/scripts/diff_guard.py +52 -4
- package/.torusguard/scripts/finding_scorer.py +58 -0
- package/.torusguard/scripts/harden_runner.py +375 -0
- package/.torusguard/scripts/html_reporter.py +25 -10
- package/.torusguard/scripts/manifest_builder.py +2 -0
- package/.torusguard/scripts/memory_engine.py +4 -0
- package/.torusguard/scripts/recheck_runner.py +221 -0
- package/.torusguard/scripts/recipes_runner.py +130 -0
- package/.torusguard/scripts/run_manager.py +17 -5
- package/.torusguard/skills/torusguard/SKILL.md +42 -42
- package/.torusguard/skills/torusguard/bootstrap.py +149 -70
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/client/src/App.jsx.bak +63 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/examples/vulnerable-react-express/server/index.js.bak +82 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/engine/fixture_manager.py.bak +245 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/master_validation.py.bak +698 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/runner.py.bak +551 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_e2e.py.bak +498 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_qa_v0_6_0.py.bak +572 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_1_scale.py.bak +371 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_2_modern_stacks.py.bak +462 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v0_6_3_hardening.py.bak +444 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_0_0_memory.py.bak +302 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/harness/validate_v1_1_0_advanced_memory.py.bak +342 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/skills/torusguard/payload/scripts/harden_runner.py.bak +353 -0
- package/.torusguard/snapshots/run-20260908-115240-audit/tests/test_v0_6_0_governed_remediation.py.bak +353 -0
- package/README.md +70 -33
- package/bin/torusguard.js +92 -22
- package/package.json +1 -1
- package/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/bootstrap.py +147 -68
- package/skills/torusguard/payload/.manifest.json +113 -9
- package/skills/torusguard/payload/rules/README.md +93 -62
- package/skills/torusguard/payload/rules/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-001-weak-password-storage.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-002-client-only-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-003-missing-object-authorization.md +85 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-004-insecure-session-cookie.md +96 -0
- package/skills/torusguard/payload/rules/active/TG-AUTH-005-unsafe-password-reset.md +104 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-001-public-production-source-maps.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-CLIENT-002-sensitive-client-bundle-content.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-DB-001-frontend-database-query.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-DB-002-privileged-database-credential.md +86 -0
- package/skills/torusguard/payload/rules/active/TG-DB-003-frontend-admin-sdk.md +91 -0
- package/skills/torusguard/payload/rules/active/TG-DB-004-missing-tenant-query-isolation.md +103 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-001-missing-server-validation.md +98 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-002-raw-sql-concatenation.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-003-unsafe-html-or-code-execution.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-004-unrestricted-file-upload.md +92 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-005-unsafe-template-rendering-and-escaping.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-INPUT-006-unsafe-file-path-traversal.md +131 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-001-wildcard-cors-with-credentials.md +101 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-002-missing-security-headers.md +95 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-003-production-stack-trace-exposure.md +94 -0
- package/skills/torusguard/payload/rules/active/TG-PLATFORM-004-missing-request-size-limits.md +102 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-001-unlimited-auth-endpoint.md +112 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-002-unlimited-public-write-endpoint.md +109 -0
- package/skills/torusguard/payload/rules/active/TG-RATE-003-unbounded-resource-consumption.md +105 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-001-hardcoded-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-002-public-environment-secrets.md +83 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-003-tracked-env-file.md +79 -0
- package/skills/torusguard/payload/rules/active/TG-SEC-004-sensitive-logging.md +83 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-001-prompt-injection-system-context.md +56 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-002-unsafe-tool-dispatch-unsandboxed-execution.md +68 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-003-broad-mcp-tool-scoping.md +53 -0
- package/skills/torusguard/payload/rules/agent/TG-AGENT-004-persistent-memory-cross-session-leakage.md +67 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-006-mass-assignment.md +70 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-007-missing-property-level-authorization.md +71 -0
- package/skills/torusguard/payload/rules/authorization/TG-AUTH-008-untrusted-role-header-injection.md +112 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-001-client-controlled-sensitive-business-value.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-002-replayable-one-time-operation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-003-missing-workflow-state-validation.md +37 -0
- package/skills/torusguard/payload/rules/business-logic/TG-BIZ-004-unrestricted-sensitive-business-flow.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-001-sensitive-response-publicly-cacheable.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-002-missing-user-cache-isolation.md +37 -0
- package/skills/torusguard/payload/rules/cache/TG-CACHE-003-sensitive-data-in-url.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-001-missing-csrf-protection.md +37 -0
- package/skills/torusguard/payload/rules/csrf/TG-CSRF-002-unsafe-credentialed-cross-origin-request.md +37 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-001-serverless-global-state-leak.md +83 -0
- package/skills/torusguard/payload/rules/edge/TG-EDGE-003-aws-lambda-ephemeral-cold-start.md +76 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-001-missing-query-depth-or-complexity-limits.md +64 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-002-resolver-missing-authorization.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-003-unbounded-graphql-pagination-or-batching.md +37 -0
- package/skills/torusguard/payload/rules/graphql/TG-GQL-004-unnecessary-production-introspection.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-005-secret-in-git-history.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-006-secret-in-build-artifact.md +37 -0
- package/skills/torusguard/payload/rules/secrets/TG-SEC-007-secret-in-test-or-example-fixture.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-001-user-controlled-server-side-url-fetch.md +68 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-002-missing-internal-network-protection.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-003-unsafe-redirect-following.md +37 -0
- package/skills/torusguard/payload/rules/ssrf/TG-SSRF-004-unbounded-outbound-request.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-001-missing-or-ignored-dependency-lockfile.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-002-vulnerable-dependency-review-missing.md +94 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-003-unsafe-ci-cd-secret-exposure.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-004-unpinned-ci-action.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-005-unsafe-dependency-install-script.md +37 -0
- package/skills/torusguard/payload/rules/supply-chain/TG-SUPPLY-006-container-build-secret-persistence.md +61 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-001-missing-webhook-signature-verification.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-002-replayable-webhook.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-003-missing-webhook-idempotency.md +37 -0
- package/skills/torusguard/payload/rules/webhook/TG-WEBHOOK-004-unvalidated-webhook-event-type.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-001-unauthenticated-websocket-handshake.md +82 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-002-missing-channel-level-authorization.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-003-unvalidated-websocket-message.md +37 -0
- package/skills/torusguard/payload/rules/websocket/TG-WS-004-unbounded-websocket-connections.md +37 -0
- package/skills/torusguard/payload/scripts/apply_runner.py +339 -0
- package/skills/torusguard/payload/scripts/audit_runner.py +550 -0
- package/skills/torusguard/payload/scripts/diff_guard.py +52 -4
- package/skills/torusguard/payload/scripts/finding_scorer.py +58 -0
- package/skills/torusguard/payload/scripts/harden_runner.py +375 -0
- package/skills/torusguard/payload/scripts/html_reporter.py +25 -10
- package/skills/torusguard/payload/scripts/manifest_builder.py +2 -0
- package/skills/torusguard/payload/scripts/memory_engine.py +4 -0
- package/skills/torusguard/payload/scripts/recheck_runner.py +221 -0
- package/skills/torusguard/payload/scripts/recipes_runner.py +130 -0
- package/skills/torusguard/payload/scripts/run_manager.py +17 -5
- package/skills/torusguard/payload/skills/torusguard/SKILL.md +42 -42
- package/skills/torusguard/payload/skills/torusguard/bootstrap.py +147 -68
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TorusGuard v0.6.0 Governed Remediation Test Suite
|
|
3
|
+
Tests:
|
|
4
|
+
1. Run Folder System & Manifest Generation
|
|
5
|
+
2. Stable Finding Identity Across Line Shifts
|
|
6
|
+
3. Root-Cause Clustering across Django, FastAPI, Flask, SQLAlchemy
|
|
7
|
+
4. Structured Remediation Bundle Generation
|
|
8
|
+
5. Minimal Patch Governance (Line churn, file count, high-risk escalation)
|
|
9
|
+
6. Targeted Recheck Status Transitions (Confirmed Fixed, Partially Fixed, Regressed, Needs Manual Review)
|
|
10
|
+
7. SARIF v2.1.0 JSON Structured Export
|
|
11
|
+
8. End-to-End v0.6.0 Governed Remediation Workflow Execution
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import unittest
|
|
15
|
+
import tempfile
|
|
16
|
+
import shutil
|
|
17
|
+
import json
|
|
18
|
+
import sys
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
|
|
21
|
+
# Add project root to sys.path
|
|
22
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
23
|
+
|
|
24
|
+
from core.identity import IdentityEngine, FindingFingerprint
|
|
25
|
+
from core.clustering import ClusteringEngine, RootCauseCluster
|
|
26
|
+
from core.bundle import BundleManager, RemediationBundle
|
|
27
|
+
from core.governance import PatchGovernor, PatchPolicyDecision
|
|
28
|
+
from core.rechecker import TargetedRechecker, TargetedRecheckResult, RecheckOutcome
|
|
29
|
+
from core.run_manager import RunManager
|
|
30
|
+
from core.sarif import SarifExporter
|
|
31
|
+
from core.v6_workflow import V6Workflow
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TestTorusGuardV060(unittest.TestCase):
|
|
35
|
+
|
|
36
|
+
def setUp(self):
|
|
37
|
+
self.test_dir = Path(tempfile.mkdtemp(prefix="torusguard-v0-6-test-"))
|
|
38
|
+
|
|
39
|
+
def tearDown(self):
|
|
40
|
+
shutil.rmtree(self.test_dir, ignore_errors=True)
|
|
41
|
+
|
|
42
|
+
def test_run_folder_creation_and_manifest(self):
|
|
43
|
+
"""Verify RunManager initializes isolated run folder with all standard artifacts."""
|
|
44
|
+
run_mgr = RunManager(
|
|
45
|
+
base_dir=self.test_dir,
|
|
46
|
+
target_name="django-core",
|
|
47
|
+
command="audit",
|
|
48
|
+
run_id="run-20260831-test-01"
|
|
49
|
+
)
|
|
50
|
+
self.assertTrue(run_mgr.run_path.exists())
|
|
51
|
+
self.assertTrue(run_mgr.logs_dir.exists())
|
|
52
|
+
self.assertTrue(run_mgr.patches_dir.exists())
|
|
53
|
+
self.assertTrue(run_mgr.bundles_dir.exists())
|
|
54
|
+
|
|
55
|
+
# Write manifest and verify
|
|
56
|
+
run_mgr.write_manifest(
|
|
57
|
+
status_counts={
|
|
58
|
+
"total_findings": 2,
|
|
59
|
+
"confirmed": 1,
|
|
60
|
+
"high_confidence": 1,
|
|
61
|
+
"needs_review": 0,
|
|
62
|
+
"remediated": 0,
|
|
63
|
+
"verified_fixed": 0,
|
|
64
|
+
"regressed": 0,
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
self.assertTrue(run_mgr.manifest_file.exists())
|
|
68
|
+
with open(run_mgr.manifest_file, "r", encoding="utf-8") as f:
|
|
69
|
+
data = json.load(f)
|
|
70
|
+
self.assertEqual(data["version"], "v0.6.3")
|
|
71
|
+
self.assertEqual(data["run_id"], "run-20260831-test-01")
|
|
72
|
+
self.assertEqual(data["status_counts"]["total_findings"], 2)
|
|
73
|
+
|
|
74
|
+
def test_stable_finding_identity_across_line_shifts(self):
|
|
75
|
+
"""Verify Finding Fingerprint remains stable when comments or surrounding lines shift."""
|
|
76
|
+
code_v1 = """
|
|
77
|
+
def get_invoice(request, invoice_id):
|
|
78
|
+
# Fetch invoice directly without tenant filter
|
|
79
|
+
invoice = Invoice.objects.get(id=invoice_id)
|
|
80
|
+
return JsonResponse({"id": invoice.id})
|
|
81
|
+
"""
|
|
82
|
+
code_v2_shifted = """
|
|
83
|
+
# Added extra docstring at the top of file
|
|
84
|
+
# Lines shifted down by 10 lines
|
|
85
|
+
def get_invoice(request, invoice_id):
|
|
86
|
+
invoice = Invoice.objects.get(id=invoice_id)
|
|
87
|
+
return JsonResponse({"id": invoice.id})
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
fp1 = IdentityEngine.generate_identity(
|
|
91
|
+
rule_id="TG-DB-004",
|
|
92
|
+
file_path="invoices/views.py",
|
|
93
|
+
code_snippet=code_v1,
|
|
94
|
+
sink_signature="Invoice.objects.get",
|
|
95
|
+
framework_marker="django",
|
|
96
|
+
)
|
|
97
|
+
fp2 = IdentityEngine.generate_identity(
|
|
98
|
+
rule_id="TG-DB-004",
|
|
99
|
+
file_path="invoices/views.py",
|
|
100
|
+
code_snippet=code_v2_shifted,
|
|
101
|
+
sink_signature="Invoice.objects.get",
|
|
102
|
+
framework_marker="django",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
self.assertEqual(fp1.fingerprint_id, fp2.fingerprint_id)
|
|
106
|
+
self.assertEqual(fp1.region_hash, fp2.region_hash)
|
|
107
|
+
self.assertTrue(fp1.fingerprint_id.startswith("TG-DB-"))
|
|
108
|
+
|
|
109
|
+
def test_root_cause_clustering(self):
|
|
110
|
+
"""Verify grouping of disparate findings into systemic root-cause clusters."""
|
|
111
|
+
findings = [
|
|
112
|
+
{
|
|
113
|
+
"finding_id": "fnd-01",
|
|
114
|
+
"rule_id": "TG-DB-004",
|
|
115
|
+
"title": "Missing Tenant Filter",
|
|
116
|
+
"severity": "High",
|
|
117
|
+
"target": {"file_path": "backend/api/users.py", "line_start": 20, "line_end": 25},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"finding_id": "fnd-02",
|
|
121
|
+
"rule_id": "TG-DB-004",
|
|
122
|
+
"title": "Missing Tenant Filter on Invoices",
|
|
123
|
+
"severity": "Critical",
|
|
124
|
+
"target": {"file_path": "backend/api/invoices.py", "line_start": 45, "line_end": 50},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"finding_id": "fnd-03",
|
|
128
|
+
"rule_id": "TG-INPUT-006",
|
|
129
|
+
"title": "Unsafe Upload Path",
|
|
130
|
+
"severity": "High",
|
|
131
|
+
"target": {"file_path": "backend/services/uploader.py", "line_start": 12, "line_end": 18},
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
|
|
135
|
+
clusters = ClusteringEngine.cluster_findings(findings)
|
|
136
|
+
self.assertEqual(len(clusters), 2)
|
|
137
|
+
|
|
138
|
+
cluster_map = {c.cluster_id: c for c in clusters}
|
|
139
|
+
self.assertIn("cluster-tenant-isolation", cluster_map)
|
|
140
|
+
self.assertIn("cluster-path-traversal", cluster_map)
|
|
141
|
+
|
|
142
|
+
tenant_cluster = cluster_map["cluster-tenant-isolation"]
|
|
143
|
+
self.assertEqual(len(tenant_cluster.finding_ids), 2)
|
|
144
|
+
self.assertEqual(len(tenant_cluster.affected_files), 2)
|
|
145
|
+
self.assertEqual(tenant_cluster.risk_severity, "Critical")
|
|
146
|
+
|
|
147
|
+
def test_remediation_bundle_generation(self):
|
|
148
|
+
"""Verify structured remediation bundle creates all 5 expected artifacts."""
|
|
149
|
+
finding = {
|
|
150
|
+
"finding_id": "TG-AUTH-008-abc123",
|
|
151
|
+
"rule_id": "TG-AUTH-008",
|
|
152
|
+
"title": "Untrusted Role Header Injection",
|
|
153
|
+
"severity": "High",
|
|
154
|
+
"target": {"file_path": "middleware/auth.py"},
|
|
155
|
+
"what_is_wrong": "Role is read directly from unauthenticated header X-Role.",
|
|
156
|
+
"why_it_matters": "Allows unprivileged users to escalate to Admin role.",
|
|
157
|
+
"what_should_change": "Derive role from verified JWT session payload.",
|
|
158
|
+
"proposed_diff": "--- a/middleware/auth.py\n+++ b/middleware/auth.py\n@@ -1,2 +1,2 @@\n-role = req.headers.get('X-Role')\n+role = req.user.role\n",
|
|
159
|
+
"verification_steps": "Send X-Role header and assert 403 Forbidden.",
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
bundle = BundleManager.create_bundle(finding, cluster_id="cluster-header-trust")
|
|
163
|
+
bundle_dir = bundle.write_to_directory(self.test_dir)
|
|
164
|
+
|
|
165
|
+
self.assertTrue((bundle_dir / "finding.md").exists())
|
|
166
|
+
self.assertTrue((bundle_dir / "remediation.md").exists())
|
|
167
|
+
self.assertTrue((bundle_dir / "minimal_patch_plan.md").exists())
|
|
168
|
+
self.assertTrue((bundle_dir / "verify-after-change.md").exists())
|
|
169
|
+
self.assertTrue((bundle_dir / "metadata.json").exists())
|
|
170
|
+
|
|
171
|
+
with open(bundle_dir / "metadata.json", "r", encoding="utf-8") as f:
|
|
172
|
+
meta = json.load(f)
|
|
173
|
+
self.assertEqual(meta["bundle_id"], "bundle-TG-AUTH-008-abc123")
|
|
174
|
+
self.assertEqual(meta["cluster_id"], "cluster-header-trust")
|
|
175
|
+
|
|
176
|
+
def test_minimal_patch_governance(self):
|
|
177
|
+
"""Verify governance policy checks on line churn, file limits, and high-risk escalation."""
|
|
178
|
+
governor = PatchGovernor(max_additions_per_file=15, max_deletions_per_file=10)
|
|
179
|
+
|
|
180
|
+
# 1. Clean minimal patch
|
|
181
|
+
clean_diff = """--- a/services/helper.py
|
|
182
|
+
+++ b/services/helper.py
|
|
183
|
+
@@ -10,3 +10,3 @@
|
|
184
|
+
-val = raw_input
|
|
185
|
+
+val = sanitize(raw_input)
|
|
186
|
+
"""
|
|
187
|
+
decision_clean = governor.evaluate_diff(clean_diff, "services/helper.py")
|
|
188
|
+
self.assertTrue(decision_clean.allowed_auto_apply)
|
|
189
|
+
self.assertFalse(decision_clean.escalation_required)
|
|
190
|
+
self.assertEqual(decision_clean.line_additions, 1)
|
|
191
|
+
|
|
192
|
+
# 2. Oversized patch (exceeds line additions)
|
|
193
|
+
oversized_lines = ["--- a/services/helper.py", "+++ b/services/helper.py"]
|
|
194
|
+
for i in range(25):
|
|
195
|
+
oversized_lines.append(f"+line_{i} = True")
|
|
196
|
+
oversized_diff = "\n".join(oversized_lines)
|
|
197
|
+
|
|
198
|
+
decision_oversized = governor.evaluate_diff(oversized_diff, "services/helper.py")
|
|
199
|
+
self.assertFalse(decision_oversized.allowed_auto_apply)
|
|
200
|
+
self.assertTrue(any("exceed threshold" in r for r in decision_oversized.rejection_reasons))
|
|
201
|
+
|
|
202
|
+
# 3. High-risk context (touching auth file with non-trivial churn)
|
|
203
|
+
high_risk_lines = ["--- a/backend/auth/login.py", "+++ b/backend/auth/login.py"]
|
|
204
|
+
for i in range(12):
|
|
205
|
+
high_risk_lines.append(f"+auth_check_{i}()")
|
|
206
|
+
high_risk_diff = "\n".join(high_risk_lines)
|
|
207
|
+
|
|
208
|
+
decision_high_risk = governor.evaluate_diff(high_risk_diff, "backend/auth/login.py")
|
|
209
|
+
self.assertTrue(decision_high_risk.escalation_required)
|
|
210
|
+
self.assertFalse(decision_high_risk.allowed_auto_apply)
|
|
211
|
+
|
|
212
|
+
def test_targeted_recheck_outcomes(self):
|
|
213
|
+
"""Verify recheck transitions: Confirmed Fixed, Regressed, Needs Manual Review."""
|
|
214
|
+
# 1. Confirmed Fixed
|
|
215
|
+
res_fixed = TargetedRechecker.verify_finding(
|
|
216
|
+
finding_id="fnd-01",
|
|
217
|
+
rule_id="TG-DB-004",
|
|
218
|
+
target_file="models/query.py",
|
|
219
|
+
original_code_snippet="return Model.objects.all()",
|
|
220
|
+
post_fix_code_snippet="return Model.objects.filter(tenant=request.tenant)",
|
|
221
|
+
is_safe_pattern_present=True,
|
|
222
|
+
is_unsafe_pattern_present=False,
|
|
223
|
+
)
|
|
224
|
+
self.assertEqual(res_fixed.outcome, RecheckOutcome.CONFIRMED_FIXED)
|
|
225
|
+
self.assertEqual(len(res_fixed.regressions_detected), 0)
|
|
226
|
+
|
|
227
|
+
# 2. Regressed (introduced new vulnerability)
|
|
228
|
+
res_regressed = TargetedRechecker.verify_finding(
|
|
229
|
+
finding_id="fnd-02",
|
|
230
|
+
rule_id="TG-INPUT-006",
|
|
231
|
+
target_file="views/upload.py",
|
|
232
|
+
original_code_snippet="file.save(filename)",
|
|
233
|
+
post_fix_code_snippet="os.system(f'cp {filename} /tmp')",
|
|
234
|
+
is_safe_pattern_present=False,
|
|
235
|
+
is_unsafe_pattern_present=True,
|
|
236
|
+
introduced_new_flaws=["TG-CMD-001: Command Injection in upload handler"],
|
|
237
|
+
)
|
|
238
|
+
self.assertEqual(res_regressed.outcome, RecheckOutcome.REGRESSED)
|
|
239
|
+
self.assertIn("Command Injection", res_regressed.regressions_detected[0])
|
|
240
|
+
|
|
241
|
+
# 3. Needs Manual Review
|
|
242
|
+
res_manual = TargetedRechecker.verify_finding(
|
|
243
|
+
finding_id="fnd-03",
|
|
244
|
+
rule_id="TG-WEBHOOK-001",
|
|
245
|
+
target_file="webhooks/receiver.py",
|
|
246
|
+
original_code_snippet="verify_sig()",
|
|
247
|
+
post_fix_code_snippet="verify_sig()",
|
|
248
|
+
requires_manual_context=True,
|
|
249
|
+
)
|
|
250
|
+
self.assertEqual(res_manual.outcome, RecheckOutcome.NEEDS_MANUAL_REVIEW)
|
|
251
|
+
|
|
252
|
+
def test_sarif_v210_export(self):
|
|
253
|
+
"""Verify valid SARIF v2.1.0 output structure and stable fingerprints."""
|
|
254
|
+
findings = [
|
|
255
|
+
{
|
|
256
|
+
"finding_id": "TG-DB-123456",
|
|
257
|
+
"fingerprint_id": "TG-DB-123456",
|
|
258
|
+
"rule_id": "TG-DB-004",
|
|
259
|
+
"title": "Missing Tenant Query Isolation",
|
|
260
|
+
"severity": "High",
|
|
261
|
+
"confidence_score": 95,
|
|
262
|
+
"confidence_band": "Confirmed",
|
|
263
|
+
"cluster_id": "cluster-tenant-isolation",
|
|
264
|
+
"target": {"file_path": "backend/models.py", "line_start": 40, "line_end": 45},
|
|
265
|
+
"evidence": {"code_snippet": "return self.query()"},
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
|
|
269
|
+
sarif_obj = SarifExporter.generate_sarif(findings, tool_version="6.0.0")
|
|
270
|
+
self.assertEqual(sarif_obj["version"], "2.1.0")
|
|
271
|
+
self.assertEqual(len(sarif_obj["runs"]), 1)
|
|
272
|
+
|
|
273
|
+
driver = sarif_obj["runs"][0]["tool"]["driver"]
|
|
274
|
+
self.assertEqual(driver["name"], "TorusGuard")
|
|
275
|
+
self.assertEqual(driver["semanticVersion"], "6.0.0")
|
|
276
|
+
|
|
277
|
+
result = sarif_obj["runs"][0]["results"][0]
|
|
278
|
+
self.assertEqual(result["ruleId"], "TG-DB-004")
|
|
279
|
+
self.assertEqual(result["level"], "error")
|
|
280
|
+
self.assertEqual(result["fingerprints"]["torusguard/v6/stable_identity"], "TG-DB-123456")
|
|
281
|
+
|
|
282
|
+
def test_end_to_end_v6_workflow(self):
|
|
283
|
+
"""Verify full end-to-end v6 workflow: audit -> harden -> apply -> recheck."""
|
|
284
|
+
workflow = V6Workflow(
|
|
285
|
+
target_root=self.test_dir,
|
|
286
|
+
output_base=self.test_dir / "runs",
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
raw_findings = [
|
|
290
|
+
{
|
|
291
|
+
"rule_id": "TG-INPUT-006",
|
|
292
|
+
"title": "Unsafe File Path Traversal",
|
|
293
|
+
"severity": "High",
|
|
294
|
+
"confidence_score": 92,
|
|
295
|
+
"confidence_band": "Confirmed",
|
|
296
|
+
"target": {"file_path": "uploader.py", "line_start": 10, "line_end": 15},
|
|
297
|
+
"evidence": {"code_snippet": "open(os.path.join(DIR, filename), 'wb')"},
|
|
298
|
+
"what_is_wrong": "Filename from client is not sanitized with secure_filename().",
|
|
299
|
+
"what_should_change": "Sanitize with werkzeug secure_filename.",
|
|
300
|
+
"proposed_diff": "--- a/uploader.py\n+++ b/uploader.py\n@@ -1,2 +1,2 @@\n-path = os.path.join(DIR, filename)\n+path = os.path.join(DIR, secure_filename(filename))\n",
|
|
301
|
+
"verification_steps": "Send ../etc/passwd in filename parameter.",
|
|
302
|
+
}
|
|
303
|
+
]
|
|
304
|
+
|
|
305
|
+
# 1. Audit Phase
|
|
306
|
+
run_mgr = workflow.execute_audit(
|
|
307
|
+
raw_findings=raw_findings,
|
|
308
|
+
target_name="flask-uploader",
|
|
309
|
+
run_id="run-e2e-01",
|
|
310
|
+
export_sarif=True,
|
|
311
|
+
)
|
|
312
|
+
self.assertTrue(run_mgr.manifest_file.exists())
|
|
313
|
+
self.assertTrue(run_mgr.summary_file.exists())
|
|
314
|
+
self.assertTrue(run_mgr.findings_file.exists())
|
|
315
|
+
self.assertTrue(run_mgr.sarif_file.exists())
|
|
316
|
+
|
|
317
|
+
# 2. Harden Phase
|
|
318
|
+
with open(run_mgr.manifest_file, "r", encoding="utf-8") as f:
|
|
319
|
+
manifest_data = json.load(f)
|
|
320
|
+
self.assertEqual(manifest_data["status_counts"]["total_findings"], 1)
|
|
321
|
+
|
|
322
|
+
bundles = workflow.execute_harden(run_mgr, raw_findings)
|
|
323
|
+
self.assertEqual(len(bundles), 1)
|
|
324
|
+
self.assertTrue(run_mgr.remediation_file.exists())
|
|
325
|
+
|
|
326
|
+
# 3. Apply Phase
|
|
327
|
+
decisions = workflow.execute_apply(run_mgr, bundles)
|
|
328
|
+
self.assertEqual(len(decisions), 1)
|
|
329
|
+
self.assertTrue(decisions[0][1].allowed_auto_apply)
|
|
330
|
+
self.assertTrue(run_mgr.apply_plan_file.exists())
|
|
331
|
+
self.assertTrue(run_mgr.diff_summary_file.exists())
|
|
332
|
+
self.assertTrue(run_mgr.changed_files_file.exists())
|
|
333
|
+
|
|
334
|
+
# 4. Recheck Phase
|
|
335
|
+
recheck_scenarios = [
|
|
336
|
+
{
|
|
337
|
+
"finding_id": bundles[0].finding_id,
|
|
338
|
+
"rule_id": "TG-INPUT-006",
|
|
339
|
+
"target_file": "uploader.py",
|
|
340
|
+
"orig_snippet": "path = os.path.join(DIR, filename)",
|
|
341
|
+
"post_snippet": "path = os.path.join(DIR, secure_filename(filename))",
|
|
342
|
+
"is_safe": True,
|
|
343
|
+
"is_unsafe": False,
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
recheck_results = workflow.execute_recheck(run_mgr, recheck_scenarios)
|
|
347
|
+
self.assertEqual(len(recheck_results), 1)
|
|
348
|
+
self.assertEqual(recheck_results[0].outcome, RecheckOutcome.CONFIRMED_FIXED)
|
|
349
|
+
self.assertTrue(run_mgr.recheck_file.exists())
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
if __name__ == "__main__":
|
|
353
|
+
unittest.main()
|
package/README.md
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
**Autonomous Security Guardrails, Governed Remediation, and Authorized Runtime Validation for AI-Built Web Applications.**
|
|
7
7
|
|
|
8
|
-
[](https://www.npmjs.com/package/torusguard)
|
|
9
|
+
[](https://github.com/githubmofo/TorusGuard/pkgs/npm/torusguard)
|
|
10
|
+
[](https://github.com/githubmofo/TorusGuard/releases/latest)
|
|
11
11
|
[](LICENSE)
|
|
12
12
|
[](https://python.org)
|
|
13
13
|
[](https://nodejs.org)
|
|
14
14
|
[](.torusguard/schemas/)
|
|
15
|
-
[-teal.svg?style=flat-square)](.torusguard/.manifest.json)
|
|
16
16
|
[](docs/architecture/SECURITY_ARCHITECTURE.md)
|
|
17
17
|
</div>
|
|
18
18
|
|
|
@@ -100,20 +100,20 @@ flowchart TD
|
|
|
100
100
|
|
|
101
101
|
---
|
|
102
102
|
|
|
103
|
-
### 2. The 7-Stage Finding Lifecycle
|
|
104
|
-
Every finding follows a strict closed-loop state machine with an unskippable **Human Gate** and
|
|
103
|
+
### 2. The 7-Stage Finding Lifecycle (Dual-Strategy Governance)
|
|
104
|
+
Every finding follows a strict closed-loop state machine supported equally via **Terminal CLI** (`npx torusguard ...`) and **AI Chat Workflows** (`/torusguard-...`) with an unskippable **Human Gate** and automatic `.bak` snapshots before disk modification:
|
|
105
105
|
|
|
106
106
|
```mermaid
|
|
107
107
|
flowchart LR
|
|
108
|
-
Detect["1. DETECT<br/>Static AST Signal"] --> Classify["2. CLASSIFY<br/>0–100 Confidence"]
|
|
109
|
-
Classify --> Verify["3. VERIFY<br/>Authorized Probe"]
|
|
110
|
-
Verify --> Remediate["4. REMEDIATE<br/>Ponytail Patch Plan"]
|
|
111
|
-
Remediate --> Gate{"👤 Human Gate<br/>Approved?"}
|
|
112
|
-
Gate -- Yes --> Apply["5. APPLY<br/>Backup & Surgical Patch"]
|
|
108
|
+
Detect["1. DETECT<br/>Static AST Signal<br/><code>audit · /audit</code>"] --> Classify["2. CLASSIFY<br/>0–100 Confidence"]
|
|
109
|
+
Classify --> Verify["3. VERIFY<br/>Authorized Probe<br/><code>verify · /verify</code>"]
|
|
110
|
+
Verify --> Remediate["4. REMEDIATE<br/>Ponytail Patch Plan<br/><code>harden · /harden</code>"]
|
|
111
|
+
Remediate --> Gate{"👤 Human Gate<br/>Approved? [y/N]"}
|
|
112
|
+
Gate -- Yes --> Apply["5. APPLY<br/>Backup & Surgical Patch<br/><code>apply · /apply</code>"]
|
|
113
113
|
Gate -- No --> Reject["❌ Discarded"]
|
|
114
|
-
Apply --> Recheck["6. RE-CHECK<br/>Differential AST Audit"]
|
|
115
|
-
Recheck -- Fixed --> Archive["7. ARCHIVE<br/>Golden Recipe Distilled"]
|
|
116
|
-
Recheck -- Regressed --> Rollback["⏪ Instant Rollback<br
|
|
114
|
+
Apply --> Recheck["6. RE-CHECK<br/>Differential AST Audit<br/><code>recheck · /recheck</code>"]
|
|
115
|
+
Recheck -- Fixed --> Archive["7. ARCHIVE<br/>Golden Recipe Distilled<br/><code>recipes</code>"]
|
|
116
|
+
Recheck -- Regressed --> Rollback["⏪ Instant Rollback<br/><code>rollback (.bak)</code>"]
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
---
|
|
@@ -198,27 +198,44 @@ flowchart TD
|
|
|
198
198
|
|
|
199
199
|
---
|
|
200
200
|
|
|
201
|
-
## 🚀 60-Second Quickstart
|
|
201
|
+
## 🚀 60-Second Quickstart (Dual-Strategy: CLI & Chat)
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
TorusGuard works natively in both standard terminal environments (Cursor, VS Code, CI/CD runners) and AI chat workflows:
|
|
204
|
+
|
|
205
|
+
### Method A: Via Node.js / NPX (Full 7-Stage Governance Lifecycle)
|
|
204
206
|
```bash
|
|
205
|
-
# 1. Initialize TorusGuard in your workspace
|
|
207
|
+
# 1. Initialize TorusGuard in your workspace (or /torusguard init)
|
|
206
208
|
npx torusguard init
|
|
207
209
|
|
|
208
|
-
# 2. Run static security audit
|
|
210
|
+
# 2. Run static security audit (or /torusguard audit)
|
|
209
211
|
npx torusguard audit
|
|
210
212
|
|
|
211
|
-
# 3.
|
|
213
|
+
# 3. Formulate minimal Ponytail candidate patches (or /torusguard harden)
|
|
214
|
+
npx torusguard harden
|
|
215
|
+
|
|
216
|
+
# 4. Review interactive Human Gate & apply with pre-apply rollback snapshots (.bak) (or /torusguard apply)
|
|
217
|
+
npx torusguard apply
|
|
218
|
+
|
|
219
|
+
# 5. Targeted differential re-scan verifying fix closure (or /torusguard recheck)
|
|
220
|
+
npx torusguard recheck
|
|
221
|
+
|
|
222
|
+
# 6. Explore distilled Golden Fix Recipes
|
|
223
|
+
npx torusguard recipes
|
|
224
|
+
|
|
225
|
+
# 7. Generate visual dark-mode HTML posture report (or /torusguard report)
|
|
212
226
|
npx torusguard report --html
|
|
213
227
|
|
|
214
|
-
#
|
|
228
|
+
# 8. (Optional) Revert to pre-apply snapshot at any time
|
|
229
|
+
npx torusguard rollback
|
|
230
|
+
|
|
231
|
+
# 9. Install Git Pre-Commit Diff Guard Hook (blocks dangerous commits)
|
|
215
232
|
npx torusguard diff-guard --install-hook
|
|
216
233
|
|
|
217
|
-
#
|
|
234
|
+
# 10. Synchronize prompt guardrails across AI editors (<= 300 tokens)
|
|
218
235
|
npx torusguard rules sync
|
|
219
236
|
```
|
|
220
237
|
|
|
221
|
-
### Method B: Via Pure Python 3.10+ (Standard Library)
|
|
238
|
+
### Method B: Via Pure Python 3.10+ (Zero-Dependency Standard Library)
|
|
222
239
|
```bash
|
|
223
240
|
# 1. Initialize workspace
|
|
224
241
|
python .torusguard/scripts/bootstrap.py --workspace .
|
|
@@ -226,10 +243,28 @@ python .torusguard/scripts/bootstrap.py --workspace .
|
|
|
226
243
|
# 2. Run static audit
|
|
227
244
|
python .torusguard/scripts/finding_scorer.py --dir .
|
|
228
245
|
|
|
229
|
-
# 3.
|
|
246
|
+
# 3. Formulate candidate patch plans (Ponytail Protocol <= 35 add, <= 25 del)
|
|
247
|
+
python .torusguard/scripts/harden_runner.py
|
|
248
|
+
|
|
249
|
+
# 4. Interactive Human Gate patch applier with pre-apply byte snapshots
|
|
250
|
+
python .torusguard/scripts/apply_runner.py
|
|
251
|
+
|
|
252
|
+
# 5. Targeted differential recheck
|
|
253
|
+
python .torusguard/scripts/recheck_runner.py
|
|
254
|
+
|
|
255
|
+
# 6. Explore distilled Golden Fix Recipes
|
|
256
|
+
python .torusguard/scripts/recipes_runner.py
|
|
257
|
+
|
|
258
|
+
# 7. Generate single-file visual HTML posture report
|
|
259
|
+
python .torusguard/scripts/html_reporter.py
|
|
260
|
+
|
|
261
|
+
# 8. Rollback pre-apply snapshots
|
|
262
|
+
python .torusguard/scripts/apply_runner.py --rollback
|
|
263
|
+
|
|
264
|
+
# 9. Install Pre-Commit Diff Guard
|
|
230
265
|
python .torusguard/scripts/diff_guard.py --install-hook
|
|
231
266
|
|
|
232
|
-
#
|
|
267
|
+
# 10. Sync AI IDE rules
|
|
233
268
|
python .torusguard/scripts/rules_sync.py --workspace . --format all
|
|
234
269
|
```
|
|
235
270
|
|
|
@@ -239,15 +274,17 @@ python .torusguard/scripts/rules_sync.py --workspace . --format all
|
|
|
239
274
|
|
|
240
275
|
| Command | Subcommands & Flags | Description |
|
|
241
276
|
|---|---|---|
|
|
242
|
-
| `torusguard init` | `[--stack <name>] [--profile <type>]` | Scaffolds `.torusguard/` with active security rules and workflows. |
|
|
243
|
-
| `torusguard audit` | `[--scope <path>] [--format md\|json]` | Audits source code against active rules and emits run folder. |
|
|
277
|
+
| `torusguard init` | `[--stack <name>] [--profile <type>]` | Scaffolds `.torusguard/` with active security rules, schemas, and workflows. |
|
|
278
|
+
| `torusguard audit` | `[--scope <path>] [--format md\|json]` | Audits source code against active rules, scores confidence, and emits run folder. |
|
|
244
279
|
| `torusguard verify` | `[--id <finding_id>]` | Probes authorized endpoints with automated credential masking. |
|
|
245
|
-
| `torusguard harden` | `[--
|
|
246
|
-
| `torusguard apply` | `[--
|
|
247
|
-
| `torusguard
|
|
248
|
-
| `torusguard
|
|
280
|
+
| `torusguard harden` | `[--scope <path>] [--format md\|json]` | Formulates surgical candidate patch bundles adhering to Ponytail bounds ($\le 35$ additions, $\le 25$ deletions). |
|
|
281
|
+
| `torusguard apply` | `[--bundle <id>] [--yes \| -y]` | Interactive terminal Human Gate (`[y/N/all/quit]`) with syntax diffs, creates `.bak` snapshots, applies patches, and distills Golden Recipes. |
|
|
282
|
+
| `torusguard rollback` | `[--run <run_id>]` | Restores all files from `.torusguard/snapshots/<run_id>/` back to disk instantly. |
|
|
283
|
+
| `torusguard recheck`| `[--scope <path>]` | Differentially re-evaluates AST sinks over modified scopes (`Confirmed Fixed` vs `Regressed`). |
|
|
284
|
+
| `torusguard recipes`| `[--rule <id>] [--json]` | Interactive explorer for distilled, verified Golden Fix Recipes stored in persistent memory. |
|
|
285
|
+
| `torusguard report` | `[--sarif] [--html] [--out <path>]` | Exports OASIS SARIF v2.1.0 or single-file visual HTML posture dashboard. |
|
|
249
286
|
| `torusguard status` | `[--json]` | Displays stack detection, active rule count, memory metrics, and run history. |
|
|
250
|
-
| `torusguard diff-guard`| `[--install-hook] [--diff <file>]` | Scans git diff for bypasses (`TG-DIFF-001..004`) or installs pre-commit hook. |
|
|
287
|
+
| `torusguard diff-guard`| `[--install-hook] [--uninstall-hook] [--diff <file>]` | Scans git diff for bypasses (`TG-DIFF-001..004`) or installs pre-commit hook. |
|
|
251
288
|
| `torusguard rules sync`| `[--format all\|cursor\|claude\|agent\|windsurf]` | Compiles project rules into AI IDE configs within $\le 300$ prompt tokens. |
|
|
252
289
|
| `torusguard memory` | `status \| context \| export \| learn` | Inspects adaptive memory, generates proximity cards, or exports team packs. |
|
|
253
290
|
|
|
@@ -280,8 +317,8 @@ AI coding models often destroy working applications by attempting full-file rewr
|
|
|
280
317
|
|
|
281
318
|
- **Strict Churn Limits:** Every fix is capped at $\le 35$ additions and $\le 25$ deletions.
|
|
282
319
|
- **Full-File Rewrite Ban:** Large destructive edits are rejected by the patch engine.
|
|
283
|
-
- **Rollback Snapshot Guarantee:** Before any file is modified, a byte-for-byte snapshot is saved to
|
|
284
|
-
- **Instant Rollback:** Restoring
|
|
320
|
+
- **Rollback Snapshot Guarantee:** Before any file is modified, a byte-for-byte snapshot is saved to `.torusguard/snapshots/<run_id>/<path>.bak`.
|
|
321
|
+
- **Instant Rollback:** Restoring original files takes 1 command (`npx torusguard rollback`).
|
|
285
322
|
|
|
286
323
|
---
|
|
287
324
|
|