@clear-capabilities/agentic-security-scanner 0.161.0 → 0.163.0

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.
Files changed (182) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/bin/agentic-security.js +98 -2
  3. package/dist/1340.index.js +1871 -0
  4. package/dist/3477.index.js +727 -0
  5. package/dist/3499.index.js +23 -3
  6. package/dist/4113.index.js +59 -8
  7. package/dist/5014.index.js +833 -0
  8. package/dist/5756.index.js +2 -2
  9. package/dist/6257.index.js +1 -1
  10. package/dist/6907.index.js +248 -0
  11. package/dist/6994.index.js +1 -1
  12. package/dist/7033.index.js +33 -5
  13. package/dist/7439.index.js +1822 -0
  14. package/dist/7838.index.js +38 -2
  15. package/dist/8798.index.js +1 -1
  16. package/dist/9207.index.js +5 -0
  17. package/dist/9560.index.js +2336 -27
  18. package/dist/957.index.js +1 -1
  19. package/dist/{1905.index.js → 9999.index.js} +306 -13
  20. package/dist/agentic-security.mjs +12 -12
  21. package/dist/agentic-security.mjs.sha256 +1 -1
  22. package/package.json +39 -7
  23. package/src/capabilities/CLAUDE.md +114 -0
  24. package/src/capabilities/address.js +73 -0
  25. package/src/capabilities/attack-coverage.js +93 -0
  26. package/src/capabilities/decide.js +256 -0
  27. package/src/capabilities/delegate.js +69 -0
  28. package/src/capabilities/egress.js +20 -0
  29. package/src/capabilities/hook-advice.js +50 -0
  30. package/src/capabilities/index.js +32 -0
  31. package/src/capabilities/manifest.js +344 -0
  32. package/src/capabilities/outbound.js +189 -0
  33. package/src/capabilities/paths.js +57 -0
  34. package/src/capabilities/probes.js +211 -0
  35. package/src/capabilities/proxy.js +182 -0
  36. package/src/capabilities/reasons.js +67 -0
  37. package/src/capabilities/receipts.js +356 -0
  38. package/src/capabilities/records.js +58 -0
  39. package/src/capabilities/recovery.js +367 -0
  40. package/src/capabilities/report.js +81 -0
  41. package/src/capabilities/runner.js +236 -0
  42. package/src/capabilities/secrets.js +26 -0
  43. package/src/capabilities/tool-gate.js +119 -0
  44. package/src/capabilities/tool-registry.js +60 -0
  45. package/src/dataflow/CLAUDE.md +29 -0
  46. package/src/dataflow/catalog.js +21 -0
  47. package/src/dataflow/engine.js +20 -0
  48. package/src/dataflow/guard-dominance.js +352 -0
  49. package/src/discovery/CLAUDE.md +18 -0
  50. package/src/discovery/index.js +43 -1
  51. package/src/discovery/lenses.js +18 -0
  52. package/src/discovery/memory.js +7 -5
  53. package/src/engine.js +80 -15
  54. package/src/fix/apply-fix-service.js +33 -3
  55. package/src/integrations/index.js +5 -2
  56. package/src/ir/CLAUDE.md +14 -0
  57. package/src/ir/implicit-handler-params.js +74 -0
  58. package/src/ir/parser-cs.js +20 -0
  59. package/src/ir/parser-go.js +30 -13
  60. package/src/ir/parser-java.js +11 -0
  61. package/src/language/nix-eval-isolation.js +33 -5
  62. package/src/lineage/CLAUDE.md +31 -0
  63. package/src/lineage/deployment/adapter-cloud.js +202 -0
  64. package/src/lineage/deployment/adapter-compose.js +90 -0
  65. package/src/lineage/deployment/adapter-kit.js +142 -0
  66. package/src/lineage/deployment/adapter-kubernetes.js +247 -0
  67. package/src/lineage/deployment/attack-paths.js +443 -0
  68. package/src/lineage/deployment/boundaries-run.js +223 -0
  69. package/src/lineage/deployment/boundary-graph.js +567 -0
  70. package/src/lineage/deployment/cross-repo.js +253 -0
  71. package/src/lineage/deployment/drift.js +383 -0
  72. package/src/lineage/deployment/ingest.js +221 -0
  73. package/src/lineage/deployment/projection.js +244 -0
  74. package/src/lineage/deployment/trace-correlation.js +541 -0
  75. package/src/lineage/source-registry.js +19 -0
  76. package/src/mcp/CLAUDE.md +14 -3
  77. package/src/mcp/invariant-tools.js +64 -0
  78. package/src/mcp/portfolio-tools.js +79 -0
  79. package/src/mcp/redact.js +15 -0
  80. package/src/mcp/server.js +24 -3
  81. package/src/mcp/tools.js +30 -5
  82. package/src/posture/CLAUDE.md +505 -0
  83. package/src/posture/accuracy-scorecard.js +95 -4
  84. package/src/posture/assurance/baseline-inventory.js +218 -0
  85. package/src/posture/assurance/baseline.js +322 -0
  86. package/src/posture/assurance/bounded-io.js +145 -0
  87. package/src/posture/assurance/config.js +299 -0
  88. package/src/posture/assurance/contracts.js +315 -0
  89. package/src/posture/assurance/identity.js +62 -0
  90. package/src/posture/assurance/migrations.js +259 -0
  91. package/src/posture/assurance/rollback.js +214 -0
  92. package/src/posture/assurance/rollout.js +200 -0
  93. package/src/posture/assurance/schema-kit.js +111 -0
  94. package/src/posture/assurance/verification-record.js +258 -0
  95. package/src/posture/attestation.js +5 -0
  96. package/src/posture/autopilot.js +28 -1
  97. package/src/posture/business-logic.js +26 -4
  98. package/src/posture/evaluation/bakeoff.js +148 -0
  99. package/src/posture/evaluation/custody.js +200 -0
  100. package/src/posture/evaluation/deployment-ablation.js +416 -0
  101. package/src/posture/evaluation/dev-cases.js +65 -0
  102. package/src/posture/evaluation/economics.js +85 -0
  103. package/src/posture/evaluation/gates.js +161 -0
  104. package/src/posture/evaluation/grouping.js +101 -0
  105. package/src/posture/evaluation/interval.js +132 -0
  106. package/src/posture/evaluation/invariant-ablation.js +325 -0
  107. package/src/posture/evaluation/labels.js +200 -0
  108. package/src/posture/evaluation/protocol.js +308 -0
  109. package/src/posture/evaluation/release-gate.js +209 -0
  110. package/src/posture/evaluation/report.js +158 -0
  111. package/src/posture/evaluation/runner.js +273 -0
  112. package/src/posture/evaluation/scan-child.js +80 -0
  113. package/src/posture/evaluation/score.js +174 -0
  114. package/src/posture/evaluation/synthetic.js +90 -0
  115. package/src/posture/evaluation/why-missed.js +219 -0
  116. package/src/posture/evidence-bundle.js +93 -7
  117. package/src/posture/execution-proof.js +11 -1
  118. package/src/posture/fix-verify-loop.js +20 -6
  119. package/src/posture/fix-verify.js +37 -2
  120. package/src/posture/fleet.js +11 -2
  121. package/src/posture/invariants/cli.js +95 -0
  122. package/src/posture/invariants/coverage.js +164 -0
  123. package/src/posture/invariants/export.js +178 -0
  124. package/src/posture/invariants/expressions.js +46 -0
  125. package/src/posture/invariants/lifecycle.js +289 -0
  126. package/src/posture/invariants/project-input.js +55 -0
  127. package/src/posture/invariants/repair.js +340 -0
  128. package/src/posture/invariants/run.js +45 -0
  129. package/src/posture/invariants/scenarios.js +311 -0
  130. package/src/posture/invariants/schema.js +167 -0
  131. package/src/posture/invariants/shrink.js +407 -0
  132. package/src/posture/invariants/state-assertions.js +165 -0
  133. package/src/posture/logic-claims.js +12 -0
  134. package/src/posture/model-routing.js +40 -0
  135. package/src/posture/oracles/adapters.js +531 -0
  136. package/src/posture/oracles/conformance.js +276 -0
  137. package/src/posture/oracles/oracle.js +453 -0
  138. package/src/posture/oracles/registry.js +76 -0
  139. package/src/posture/oracles/scenario-classes.js +223 -0
  140. package/src/posture/portfolio/backend.js +279 -0
  141. package/src/posture/portfolio/bundle.js +314 -0
  142. package/src/posture/portfolio/cli.js +142 -0
  143. package/src/posture/portfolio/manifest.js +263 -0
  144. package/src/posture/portfolio/progress.js +267 -0
  145. package/src/posture/portfolio/resume.js +130 -0
  146. package/src/posture/portfolio/retention.js +207 -0
  147. package/src/posture/portfolio/scheduler.js +488 -0
  148. package/src/posture/portfolio/signing.js +155 -0
  149. package/src/posture/portfolio/wording.js +59 -0
  150. package/src/posture/portfolio/work-units.js +405 -0
  151. package/src/posture/replay/replay.js +250 -0
  152. package/src/posture/routing/adapter.js +140 -0
  153. package/src/posture/routing/calibration.js +278 -0
  154. package/src/posture/routing/canary.js +141 -0
  155. package/src/posture/routing/control.js +35 -0
  156. package/src/posture/routing/decide.js +211 -0
  157. package/src/posture/routing/drift.js +137 -0
  158. package/src/posture/routing/economics.js +185 -0
  159. package/src/posture/routing/feedback.js +207 -0
  160. package/src/posture/routing/index.js +31 -0
  161. package/src/posture/routing/outcomes.js +281 -0
  162. package/src/posture/routing/promotion.js +291 -0
  163. package/src/posture/routing/receipts.js +59 -0
  164. package/src/posture/routing/report.js +142 -0
  165. package/src/posture/routing/shadow.js +53 -0
  166. package/src/posture/specification-mining.js +26 -0
  167. package/src/posture/verification/advisory-state.js +71 -0
  168. package/src/posture/verification/emit.js +257 -0
  169. package/src/posture/verification/hypothesis-promotion.js +211 -0
  170. package/src/posture/verification/patch-negative.js +226 -0
  171. package/src/posture/verification/patch-promotion.js +113 -0
  172. package/src/posture/verification/projection.js +183 -0
  173. package/src/posture/verification/repair-records.js +124 -0
  174. package/src/posture/verifier.js +16 -0
  175. package/src/report/index.js +100 -1
  176. package/src/sandbox/CLAUDE.md +51 -0
  177. package/src/sandbox/backend-namespace.js +7 -0
  178. package/src/sandbox/backend-userspace.js +151 -34
  179. package/src/sandbox/control-probes.js +215 -0
  180. package/src/sandbox/supervise.js +201 -0
  181. package/src/sandbox/trust-boundary.js +113 -0
  182. package/src/sandbox/trust-domains.js +171 -0
@@ -1 +1 @@
1
- faee309bc53830c682a4e967147e6dbc6073b046d2220278b30e64f2e19b1675 agentic-security.mjs
1
+ b91f501cdd42eeeb4a4d813733871bce13c44067381e17def7a7230f66638f6a agentic-security.mjs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clear-capabilities/agentic-security-scanner",
3
- "version": "0.161.0",
3
+ "version": "0.163.0",
4
4
  "description": "Scanner engine for the agentic-security Claude Code plugin: SAST, SCA with reachability and CISA KEV, secrets, IaC, Haskell and Nix/NixOS, prompt-injection, MCP/agent-tool audit, authZ analysis, SBOM, compliance attestation, and more.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -52,7 +52,7 @@
52
52
  "z3-solver": "^5.2.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@types/node": "^26.6.4",
55
+ "@types/node": "^26.6.5",
56
56
  "@vercel/ncc": "^0.45.0",
57
57
  "java-parser": "^3.0.1"
58
58
  },
@@ -67,15 +67,16 @@
67
67
  "test": "node ../scripts/run-unit-tests.mjs",
68
68
  "test:extras": "AGENTIC_SECURITY_CPP_DATAFLOW=1 node --test test/cpp-dataflow.test.js && node --experimental-test-module-mocks --test test/fault-injection.test.js && node --experimental-test-module-mocks --test test/detector-fault-injection.test.js && node --experimental-test-module-mocks --test test/detector-fault-injection-k8s-admission.test.js && node --experimental-test-module-mocks --test test/lineage-fault-injection.test.js && npm run test:python",
69
69
  "loop": "node ../scripts/loop-engineering/run.mjs",
70
- "test:loop": "node --test --test-concurrency=1 ../scripts/loop-engineering/test/loop-manifest.test.js ../scripts/loop-engineering/test/loop-watchdog.test.js ../scripts/loop-engineering/test/loop-background.test.js ../scripts/loop-engineering/test/loop-dashboard.test.js ../scripts/loop-engineering/test/loop-evidence.test.js ../scripts/loop-engineering/test/loop-recovery.test.js ../scripts/loop-engineering/test/loop-remote.test.js ../scripts/loop-engineering/test/loop-runbook.test.js",
70
+ "test:loop-real-prd": "node --test ../scripts/loop-engineering/test/loop-real-prd.test.js",
71
+ "test:loop": "node --test --test-concurrency=1 ../scripts/loop-engineering/test/loop-manifest.test.js ../scripts/loop-engineering/test/loop-watchdog.test.js ../scripts/loop-engineering/test/loop-background.test.js ../scripts/loop-engineering/test/loop-dashboard.test.js ../scripts/loop-engineering/test/loop-evidence.test.js ../scripts/loop-engineering/test/loop-recovery.test.js ../scripts/loop-engineering/test/loop-remote.test.js ../scripts/loop-engineering/test/loop-runbook.test.js ../scripts/loop-engineering/test/loop-assurance-profile.test.js ../scripts/loop-engineering/test/loop-assurance-runtime.test.js",
71
72
  "test:python": "node ../scripts/run-python-tests.mjs",
72
73
  "test:smoke": "node --test test/smoke.test.js test/demo-app.test.js",
73
74
  "test:ollama-e2e": "AGENTIC_SECURITY_OLLAMA_E2E=1 node --test test/ollama-e2e.test.js",
74
75
  "test:glob": "node --test test/glob-compat.test.js",
75
76
  "test:sast": "node --test test/cpp-hardcoded-secret.test.js test/sibling-guard.test.js test/comment-blindness.test.js test/crypto-specialist.test.js test/llm.test.js test/llm-cost-advisor.test.js test/llm-owasp.test.js test/logic.test.js test/authz.test.js test/model-load.test.js test/prompt-template.test.js test/business-logic.test.js test/python-sinks.test.js test/phase1-detectors.test.js test/phase2-detectors.test.js test/phase3-v3.test.js test/phase7-extensions.test.js test/phase8-extensions.test.js test/new-cwe-detectors.test.js test/file-upload.test.js test/llmsecops-detectors.test.js test/db-taint.test.js test/dart-swift.test.js test/zip-slip-containment-guard.test.js test/redos-anchoring.test.js test/path-guard-validator-call.test.js test/redos-nfa.test.js test/weak-randomness.test.js test/csharp-pipeline.test.js test/csharp-cross-file.test.js test/post-quantum-crypto.test.js test/web3-advanced.test.js test/cloud-iam-k8s.test.js test/crypto-protocol.test.js test/ml-supply-chain.test.js test/mcp-audit-scan.test.js test/wrong-context-sanitizer.test.js test/sanitizer-context.test.js test/frontend-hygiene.test.js test/csv-injection.test.js test/stored-taint.test.js test/tree-sitter-sinks.test.js test/kotlin-structural.test.js test/ruby-php-structural.test.js test/java-csharp-structural.test.js test/java-structural-cross-file.test.js test/guard-recognition.test.js test/guard-window-identifier-correlation.test.js test/js-python-framework-structural.test.js test/go-structural.test.js test/secret-concat.test.js test/secret-redaction.test.js test/xss-reflected-multilang.test.js test/code-injection-multilang.test.js test/xxe-multilang.test.js test/xpath-injection-multilang.test.js test/gapfill-batch13.test.js test/agent-untrusted-flow.test.js test/api-authz.test.js test/event-entrypoint.test.js test/iac-terraform.test.js test/cross-service.test.js test/rbac-consistency.test.js test/adversarial-robustness.test.js test/secret-entropy.test.js test/comment-strip.test.js test/juliet-path-filter-gate.test.js test/java-bench-shape-opt-in.test.js test/java-ast-folding.test.js test/java-bench-extras.test.js test/reachability-missing-callgraph-data.test.js test/rate-limit.test.js test/auth-signals.test.js test/convention-deviation.test.js test/resource-exhaustion.test.js test/resource-exhaustion-realworld.test.js test/redirect-toctou.test.js test/redirect-toctou-realworld.test.js test/codegen-sink.test.js test/ownership-authz.test.js test/ownership-authz-realworld.test.js test/t21-precision-audit.test.js test/secrets-coverage.test.js test/prompt-injection-payloads.test.js test/iac-cloud-templates.test.js test/ruby-path-join.test.js test/sast/manifest-line-tracking.test.js test/rust-sast.test.js test/java-deserialization-precision.test.js test/pipeline-env-secret.test.js test/mark-used-vuln-functions.test.js",
76
- "test:posture": "node --test test/threat-model.test.js test/git-hardening.test.js test/privacy-framework.test.js test/material-change.test.js test/drift.test.js test/scorecard.test.js test/accuracy-scorecard.test.js test/scorecard-gate.test.js test/predeploy-gate.test.js test/release-check.test.js test/pre-push-gate.test.js test/dependency-currency.test.js test/package-contents-check.test.js test/gate-verdict-cache.test.js test/run-unit-tests.test.js test/temp-leak-guard.test.js test/release-workflow.test.js test/release-workflow-structure.test.js test/independent-population.test.js test/why-missed.test.js test/independent-scoring.test.js test/evidence-bundle.test.js test/obligation-evidence-pack.test.js test/policy-bundle.test.js test/discovery-memory.test.js test/mttr.test.js test/license-policy.test.js test/aibom.test.js test/sbom.test.js test/api-inventory.test.js test/iam-policy.test.js test/container.test.js test/container-runtime.test.js test/image-packages.test.js test/kev.test.js test/dep-confusion.test.js test/sca-deprecated.test.js test/sca-batch.test.js test/composite-risk.test.js test/epss-enrich.test.js test/sca-coverage.test.js test/gradle-deps.test.js test/sca-route-reachable.test.js test/sca-policy.test.js test/sca-verdict.test.js test/install-script.test.js test/sca-linked-findings.test.js test/packs.test.js test/flow-narration.test.js test/regression-test-gen.test.js test/deterministic-fix.test.js test/falsification.test.js test/verification-separation.test.js test/logic-claims.test.js test/attestation.test.js test/verify-attestation-cli.test.js test/comparison.test.js test/determinism-cross-machine.test.js test/fix-honesty-gate.test.js test/model-routing.test.js test/root-cause-sweep.test.js test/entrypoint-inventory.test.js test/relevance.test.js test/untrusted.test.js test/agent-hardening.test.js test/rule-synthesis.test.js test/policy-gate.test.js test/agents-memory.test.js test/cve-lookup.test.js test/cve-alert-daemon.test.js test/fix-verify-loop.test.js test/fix-verify-tests.test.js test/fix-acceptance.test.js test/exploitability-probability.test.js test/history-scan.test.js test/viral-features.test.js test/viral-v074.test.js test/state-dir.test.js test/ignore-pragma.test.js test/license-graph.test.js test/secret-live-check.test.js test/attack-taxonomy.test.js test/triage-memory.test.js test/pr-augment.test.js test/chat-batch2.test.js test/chat-batch3.test.js test/chat-batch4.test.js test/chat-batch5.test.js test/chat-batch6.test.js test/risk-scenario-disclosure.test.js test/egress-policy.test.js test/egress-policy-completeness.test.js test/egress-policy-integration.test.js test/router.test.js test/legacy-alias-redirect.test.js test/cache-economics.test.js test/coverage-report.test.js test/corpus-status.test.js test/provenance.test.js test/secret-history.test.js test/execution-proof.test.js test/fix-metrics.test.js test/corpus-enroll.test.js test/prove-findings.test.js test/corpus-match.test.js test/corpus-provenance.test.js test/learning-quorum.test.js test/llm-cache-integrity.test.js test/proof-artifact.test.js test/providers.test.js test/fleet.test.js test/autopilot.test.js test/autopilot-cli.test.js test/verifier-independence.test.js test/integrity-legacy-key.test.js test/suppression-visibility.test.js test/cost-ceiling.test.js test/local-endpoint.test.js test/ollama-provider.test.js test/ollama-capabilities.test.js test/ollama-offline-egress.test.js test/ollama-fix-proposal.test.js test/ollama-explain-proposal.test.js test/ollama-poc-proposal.test.js test/ollama-model-probe.test.js test/ollama-agent-tools.test.js test/ollama-agent-loop.test.js test/ollama-e2e.test.js test/ollama-oom-feedback.test.js test/ollama-doc-drift.test.js test/model-trust.test.js test/vuln-archaeology.test.js test/scan-checkpoint.test.js test/llm-redact.test.js test/world-class-batch2.test.js test/world-class-modules.test.js test/privacy-ir-adapter.test.js test/privacy-taxonomy.test.js test/privacy-sink-policy.test.js test/privacy-governance.test.js test/privacy-inventory.test.js test/integration-end-to-end.test.js test/streak-cli-wiring.test.js test/stack-playbook.test.js test/machine-output-flag.test.js test/stdout-flush.test.js test/format-determinism.test.js test/only-flag-channels.test.js test/confidence.test.js test/security-trend.test.js test/calibration-drift.test.js test/validator-metrics.test.js test/clustering-ir-taint-line.test.js test/concurrency-cwe.test.js test/compliance-mapping-liveness.test.js test/module-artifact-liveness.test.js test/supply-chain-provenance-completeness.test.js test/compliance-severity-threshold.test.js test/compliance-severity-policy.test.js test/compliance-evidence-binding.test.js test/compliance-evidence-signing.test.js test/compliance-file-contains.test.js test/label-isolation.test.js test/evidence-grade-wording.test.js test/llm-model-status.test.js test/egress-policy-constraints.test.js test/egress-redact.test.js test/egress-audit.test.js test/egress-approved-providers.test.js test/family-registry.test.js test/coverage-strength.test.js test/framework-provenance.test.js test/framework-provenance-controlrefs.test.js test/third-party-verification.test.js test/proof-coverage.test.js test/calibration-holdout.test.js test/independent-population-gate.test.js test/catalog-freshness.test.js test/incremental-parity.test.js test/surface-smoke.test.js test/fix-coverage.test.js test/raw-source-carveout.test.js test/mlbom-conformance.test.js test/deploy-gate-replay.test.js test/sbom-conformance.test.js test/unscored-claims.test.js test/mcp-rug-pull.test.js test/agent-boundary-taint.test.js test/confinement-adversarial.test.js test/comment-strip-cost.test.js test/reachability-claim.test.js test/entrypoint-breadth.test.js test/dep-file-admission.test.js test/custom-rules-freshness.test.js test/posture/provenance-schema.test.js test/posture/provenance-cache.test.js test/helpers/build-git-fixture.test.js test/posture/provenance-git-evidence.test.js test/posture/provenance-dag-walk.test.js test/posture/provenance-confidence.test.js test/posture/provenance-predicate-replay.test.js test/posture/provenance-origin-resolver.test.js test/posture/provenance-ai-authorship.test.js test/posture/provenance-branch-entry.test.js test/posture/provenance-evidence-attribution.test.js test/posture/provenance-lifecycle.test.js test/posture/provenance-missing-control-resolver.test.js test/posture/provenance-missing-control-wiring.test.js test/posture/provenance-coordinator.test.js test/posture/provenance-sca-origin.test.js test/posture/provenance-transitive-sca.test.js test/posture/provenance-coordinator-sca.test.js test/posture/provenance-providers.test.js test/posture/provenance-evidence-bundle.test.js test/posture/provenance-repo-lineage.test.js test/posture/provenance-secrets-logic.test.js test/cli/provenance-flags.test.js test/cli/attest-provenance.test.js test/cli/attest-obligations.test.js test/cli/models.test.js test/cli/setup-llm.test.js test/cli/fix-retry.test.js test/cli/compliance-walkthrough-lineage.test.js test/cli/dataflow-export-privacy.test.js test/cli/dataflow-export-briefing.test.js test/cli/lineage-snapshot-persist.test.js test/cli/dataflow-diff.test.js test/cli/dataflow-watch.test.js test/cli/dataflow-recipients.test.js test/cli/dataflow-coverage.test.js test/security/provenance-safety.test.js test/security/provenance-injection.test.js test/posture/remediation-ledger.test.js",
77
- "test:dataflow": "node --test test/privacy-catalog.test.js test/privacy-deep-walker.test.js test/privacy-deep-e2e.test.js test/container-taint.test.js test/stored-taint-families.test.js test/py-annotation-sources.test.js test/fn-reach.test.js test/deep-taint.test.js test/calibration.test.js test/holdout-eval.test.js test/cross-lang-meta.test.js test/cross-lang-queues.test.js test/phase5-xlang.test.js test/phase5-coverage.test.js test/phase6-taint.test.js test/llm-validator-consistency.test.js test/llm-validator-default-on.test.js test/llm-validator-preset.test.js test/parser-py-cst.test.js test/chrome-probe.test.js test/parser-cs-kt.test.js test/parser-cs-annotations.test.js test/parser-cs-control-flow.test.js test/parser-kt-control-flow.test.js test/parser-js-annotations.test.js test/parser-java-annotations.test.js test/parser-java-control-flow.test.js test/parser-java-calls.test.js test/parser-go.test.js test/parser-rust.test.js test/rust-taint-flow.test.js test/parser-php-rb.test.js test/parser-php-control-flow.test.js test/interproc-k2.test.js test/proven-clean.test.js test/backward-default.test.js test/incremental-cache.test.js test/string-regex-lattice.test.js test/closure-capture.test.js test/points-to.test.js test/type-stubs.test.js test/soft-taint.test.js test/ifds.test.js test/symbolic-exec-proof.test.js test/ifds-summary-edges.test.js test/stub-aware-filter.test.js test/cross-repo.test.js test/proof-gate.test.js test/layer-recall.test.js test/java-taint-flow.test.js test/kt-taint-flow.test.js test/sanitizer-typed-flow.test.js test/sanitizer-gate-unit.test.js test/proof-safe.test.js test/collection-taint.test.js test/kcfa-context.test.js test/kcfa-callstring.test.js test/flow-parity.test.js test/callgraph-resolve.test.js test/import-reachability.test.js test/ir-stats.test.js test/parser-cpp.test.js test/parser-js-decorators.test.js test/parser-js-if-else-cfg.test.js test/cpp-integration.test.js test/engine-reconnect.test.js test/phase2-scoping.test.js test/engine-recall.test.js test/catalog-annotation-source.test.js test/catalog-cs-p1.test.js test/catalog-expanded.test.js test/builtin-summaries.test.js test/interproc-mutation-crash.test.js test/mutated-param-taint.test.js test/return-sink-check.test.js test/higher-order-inline-callback.test.js test/interproc-findings-discard.test.js test/runscan-deep-option.test.js test/summary-cache-convergence.test.js test/parser-rb-calls.test.js test/parser-rb-module-level.test.js test/balanced-call.test.js test/destructuring-taint.test.js test/computed-member-taint.test.js test/string-interpolation-taint.test.js test/dataflow-deadcode-severity.test.js test/catalog-dotted-callee-lookup.test.js test/builtin-summary-family-blind-kill.test.js test/deep-mode-annotator-pipeline.test.js test/receiver-type-and-nested-calls.test.js test/member-write-and-loop-taint.test.js test/parser-py-module-level.test.js test/parser-php-module-level.test.js test/r14b-module-level-e2e.test.js test/annotation-taint-engine.test.js test/interproc-nested-call-taint.test.js test/catalog-xpath-injection.test.js test/catalog-ldap-injection.test.js test/catalog-xxe.test.js test/catalog-response-splitting.test.js test/catalog-code-injection.test.js test/parser-rb-control-flow.test.js test/catalog-ruby-p1.test.js test/callee-receiver-taint.test.js test/catalog-command-injection-p4.test.js test/catalog-xss-p4.test.js test/catalog-path-ssrf-p3.test.js test/catalog-ai-model-provider-precision.test.js test/catalog-orm-write.test.js test/dataflow/provenance-pipeline-integration.test.js test/dataflow-progress.test.js test/scan-progress.test.js test/sard-leakage-pipeline.test.js test/sard-split-scoring.test.js test/sard-llm-isolation.test.js test/sard-mutation-adversarial.test.js test/sard-baseline-adaptive-tolerance.test.js test/sard-independent-holdout.test.js test/sard-flow-aware-scoring.test.js test/sard-macro-score-support-floor.test.js test/sard-php-split.test.js test/parser-java-nary-concat.test.js test/sard-naive-baseline.test.js test/field-taint-cross-method.test.js test/field-taint-engine-unit.test.js test/coercion-sanitizer-kill.test.js test/constant-propagation-path-sensitivity.test.js test/parser-java-assignments.test.js test/catalog-java-sard.test.js test/parser-cs-juliet-shapes.test.js test/catalog-cs-sard-p2.test.js test/sard-cwe-key-merge.test.js test/parser-php-backtick.test.js test/parser-php-include.test.js test/php-include-merge.test.js test/parser-php-array-field-taint.test.js test/parser-php-cond-assign.test.js test/parser-rust-redos.test.js test/multi-sink-taint-chain.test.js test/static-field-cross-class-call-string.test.js test/regex-guard-narrowing.test.js test/object-instance-field-taint.test.js test/param-type-inference.test.js test/smt-path-feasibility.test.js test/cross-service-taint.test.js test/dataflow-expr-taint-scaling.test.js",
78
- "test:mcp": "node --test test/mcp.test.js test/mcp-apply-fix-multifile.test.js test/mcp-protocol-smoke.test.js test/mcp-audit.test.js test/audit-cli.test.js test/mcp-scratchpad.test.js test/mcp-offload.test.js test/sca-upgrade.test.js test/lsp-server.test.js test/mcp-dataflow-tools.test.js test/cli/governance-propose-edit.test.js test/cli/remediation-open-update.test.js test/cli/remediation-verify-reopen.test.js test/cli/dataflow-observations.test.js test/cli/federate-declare-list.test.js",
77
+ "test:posture": "node --test test/threat-model.test.js test/git-hardening.test.js test/privacy-framework.test.js test/material-change.test.js test/drift.test.js test/scorecard.test.js test/accuracy-scorecard.test.js test/scorecard-gate.test.js test/predeploy-gate.test.js test/release-check.test.js test/pre-push-gate.test.js test/dependency-currency.test.js test/package-contents-check.test.js test/gate-verdict-cache.test.js test/run-unit-tests.test.js test/temp-leak-guard.test.js test/release-workflow.test.js test/release-workflow-structure.test.js test/independent-population.test.js test/why-missed.test.js test/independent-scoring.test.js test/evidence-bundle.test.js test/obligation-evidence-pack.test.js test/policy-bundle.test.js test/discovery-memory.test.js test/mttr.test.js test/license-policy.test.js test/aibom.test.js test/sbom.test.js test/api-inventory.test.js test/iam-policy.test.js test/container.test.js test/container-runtime.test.js test/image-packages.test.js test/kev.test.js test/dep-confusion.test.js test/sca-deprecated.test.js test/sca-batch.test.js test/composite-risk.test.js test/epss-enrich.test.js test/sca-coverage.test.js test/gradle-deps.test.js test/sca-route-reachable.test.js test/sca-policy.test.js test/sca-verdict.test.js test/install-script.test.js test/sca-linked-findings.test.js test/packs.test.js test/flow-narration.test.js test/regression-test-gen.test.js test/deterministic-fix.test.js test/falsification.test.js test/verification-separation.test.js test/logic-claims.test.js test/attestation.test.js test/verify-attestation-cli.test.js test/comparison.test.js test/determinism-cross-machine.test.js test/fix-honesty-gate.test.js test/model-routing.test.js test/root-cause-sweep.test.js test/entrypoint-inventory.test.js test/relevance.test.js test/untrusted.test.js test/agent-hardening.test.js test/rule-synthesis.test.js test/policy-gate.test.js test/agents-memory.test.js test/cve-lookup.test.js test/cve-alert-daemon.test.js test/fix-verify-loop.test.js test/fix-verify-tests.test.js test/fix-acceptance.test.js test/exploitability-probability.test.js test/history-scan.test.js test/viral-features.test.js test/viral-v074.test.js test/state-dir.test.js test/ignore-pragma.test.js test/license-graph.test.js test/secret-live-check.test.js test/attack-taxonomy.test.js test/triage-memory.test.js test/pr-augment.test.js test/chat-batch2.test.js test/chat-batch3.test.js test/chat-batch4.test.js test/chat-batch5.test.js test/chat-batch6.test.js test/risk-scenario-disclosure.test.js test/egress-policy.test.js test/egress-policy-completeness.test.js test/egress-policy-integration.test.js test/router.test.js test/legacy-alias-redirect.test.js test/cache-economics.test.js test/coverage-report.test.js test/corpus-status.test.js test/provenance.test.js test/secret-history.test.js test/execution-proof.test.js test/fix-metrics.test.js test/corpus-enroll.test.js test/prove-findings.test.js test/corpus-match.test.js test/corpus-provenance.test.js test/learning-quorum.test.js test/llm-cache-integrity.test.js test/proof-artifact.test.js test/providers.test.js test/fleet.test.js test/autopilot.test.js test/autopilot-cli.test.js test/verifier-independence.test.js test/integrity-legacy-key.test.js test/suppression-visibility.test.js test/cost-ceiling.test.js test/local-endpoint.test.js test/ollama-provider.test.js test/ollama-capabilities.test.js test/ollama-offline-egress.test.js test/ollama-fix-proposal.test.js test/ollama-explain-proposal.test.js test/ollama-poc-proposal.test.js test/ollama-model-probe.test.js test/ollama-agent-tools.test.js test/ollama-agent-loop.test.js test/ollama-e2e.test.js test/ollama-oom-feedback.test.js test/ollama-doc-drift.test.js test/model-trust.test.js test/vuln-archaeology.test.js test/scan-checkpoint.test.js test/llm-redact.test.js test/world-class-batch2.test.js test/world-class-modules.test.js test/privacy-ir-adapter.test.js test/privacy-taxonomy.test.js test/privacy-sink-policy.test.js test/privacy-governance.test.js test/privacy-inventory.test.js test/integration-end-to-end.test.js test/streak-cli-wiring.test.js test/stack-playbook.test.js test/machine-output-flag.test.js test/stdout-flush.test.js test/format-determinism.test.js test/only-flag-channels.test.js test/confidence.test.js test/security-trend.test.js test/calibration-drift.test.js test/validator-metrics.test.js test/clustering-ir-taint-line.test.js test/concurrency-cwe.test.js test/compliance-mapping-liveness.test.js test/module-artifact-liveness.test.js test/supply-chain-provenance-completeness.test.js test/compliance-severity-threshold.test.js test/compliance-severity-policy.test.js test/compliance-evidence-binding.test.js test/compliance-evidence-signing.test.js test/compliance-file-contains.test.js test/label-isolation.test.js test/evidence-grade-wording.test.js test/llm-model-status.test.js test/egress-policy-constraints.test.js test/egress-redact.test.js test/egress-audit.test.js test/egress-approved-providers.test.js test/family-registry.test.js test/coverage-strength.test.js test/framework-provenance.test.js test/framework-provenance-controlrefs.test.js test/third-party-verification.test.js test/proof-coverage.test.js test/calibration-holdout.test.js test/independent-population-gate.test.js test/catalog-freshness.test.js test/incremental-parity.test.js test/surface-smoke.test.js test/fix-coverage.test.js test/raw-source-carveout.test.js test/mlbom-conformance.test.js test/deploy-gate-replay.test.js test/sbom-conformance.test.js test/unscored-claims.test.js test/mcp-rug-pull.test.js test/agent-boundary-taint.test.js test/confinement-adversarial.test.js test/comment-strip-cost.test.js test/reachability-claim.test.js test/entrypoint-breadth.test.js test/dep-file-admission.test.js test/custom-rules-freshness.test.js test/posture/provenance-schema.test.js test/posture/provenance-cache.test.js test/helpers/build-git-fixture.test.js test/posture/provenance-git-evidence.test.js test/posture/provenance-dag-walk.test.js test/posture/provenance-confidence.test.js test/posture/provenance-predicate-replay.test.js test/posture/provenance-origin-resolver.test.js test/posture/provenance-ai-authorship.test.js test/posture/provenance-branch-entry.test.js test/posture/provenance-evidence-attribution.test.js test/posture/provenance-lifecycle.test.js test/posture/provenance-missing-control-resolver.test.js test/posture/provenance-missing-control-wiring.test.js test/posture/provenance-coordinator.test.js test/posture/provenance-sca-origin.test.js test/posture/provenance-transitive-sca.test.js test/posture/provenance-coordinator-sca.test.js test/posture/provenance-providers.test.js test/posture/provenance-evidence-bundle.test.js test/posture/provenance-repo-lineage.test.js test/posture/provenance-secrets-logic.test.js test/cli/provenance-flags.test.js test/cli/attest-provenance.test.js test/cli/attest-obligations.test.js test/cli/models.test.js test/cli/setup-llm.test.js test/cli/fix-retry.test.js test/cli/compliance-walkthrough-lineage.test.js test/cli/dataflow-export-privacy.test.js test/cli/dataflow-export-briefing.test.js test/cli/lineage-snapshot-persist.test.js test/cli/dataflow-diff.test.js test/cli/dataflow-watch.test.js test/cli/dataflow-recipients.test.js test/cli/dataflow-coverage.test.js test/security/provenance-safety.test.js test/security/provenance-injection.test.js test/posture/remediation-ledger.test.js test/posture/assurance-baseline.test.js test/posture/assurance-contracts.test.js test/posture/assurance-config.test.js test/evidence-issuer.test.js test/load-factor.test.js",
78
+ "test:dataflow": "node --test test/privacy-catalog.test.js test/privacy-deep-walker.test.js test/privacy-deep-e2e.test.js test/container-taint.test.js test/stored-taint-families.test.js test/py-annotation-sources.test.js test/fn-reach.test.js test/deep-taint.test.js test/calibration.test.js test/holdout-eval.test.js test/cross-lang-meta.test.js test/cross-lang-queues.test.js test/phase5-xlang.test.js test/phase5-coverage.test.js test/phase6-taint.test.js test/llm-validator-consistency.test.js test/llm-validator-default-on.test.js test/llm-validator-preset.test.js test/parser-py-cst.test.js test/chrome-probe.test.js test/parser-cs-kt.test.js test/parser-cs-annotations.test.js test/parser-cs-control-flow.test.js test/parser-kt-control-flow.test.js test/parser-js-annotations.test.js test/parser-java-annotations.test.js test/parser-java-control-flow.test.js test/parser-java-calls.test.js test/parser-go.test.js test/parser-rust.test.js test/rust-taint-flow.test.js test/parser-php-rb.test.js test/parser-php-control-flow.test.js test/interproc-k2.test.js test/proven-clean.test.js test/backward-default.test.js test/incremental-cache.test.js test/string-regex-lattice.test.js test/closure-capture.test.js test/points-to.test.js test/type-stubs.test.js test/soft-taint.test.js test/ifds.test.js test/symbolic-exec-proof.test.js test/ifds-summary-edges.test.js test/stub-aware-filter.test.js test/cross-repo.test.js test/proof-gate.test.js test/layer-recall.test.js test/java-taint-flow.test.js test/kt-taint-flow.test.js test/sanitizer-typed-flow.test.js test/sanitizer-gate-unit.test.js test/proof-safe.test.js test/collection-taint.test.js test/kcfa-context.test.js test/kcfa-callstring.test.js test/flow-parity.test.js test/callgraph-resolve.test.js test/import-reachability.test.js test/ir-stats.test.js test/parser-cpp.test.js test/parser-js-decorators.test.js test/parser-js-if-else-cfg.test.js test/cpp-integration.test.js test/engine-reconnect.test.js test/phase2-scoping.test.js test/engine-recall.test.js test/catalog-annotation-source.test.js test/catalog-cs-p1.test.js test/catalog-expanded.test.js test/builtin-summaries.test.js test/interproc-mutation-crash.test.js test/mutated-param-taint.test.js test/return-sink-check.test.js test/higher-order-inline-callback.test.js test/interproc-findings-discard.test.js test/runscan-deep-option.test.js test/summary-cache-convergence.test.js test/parser-rb-calls.test.js test/parser-rb-module-level.test.js test/balanced-call.test.js test/destructuring-taint.test.js test/computed-member-taint.test.js test/string-interpolation-taint.test.js test/dataflow-deadcode-severity.test.js test/catalog-dotted-callee-lookup.test.js test/builtin-summary-family-blind-kill.test.js test/deep-mode-annotator-pipeline.test.js test/receiver-type-and-nested-calls.test.js test/member-write-and-loop-taint.test.js test/parser-py-module-level.test.js test/parser-php-module-level.test.js test/r14b-module-level-e2e.test.js test/annotation-taint-engine.test.js test/interproc-nested-call-taint.test.js test/catalog-xpath-injection.test.js test/catalog-ldap-injection.test.js test/catalog-xxe.test.js test/catalog-response-splitting.test.js test/catalog-code-injection.test.js test/parser-rb-control-flow.test.js test/catalog-ruby-p1.test.js test/callee-receiver-taint.test.js test/catalog-command-injection-p4.test.js test/catalog-xss-p4.test.js test/catalog-path-ssrf-p3.test.js test/catalog-ai-model-provider-precision.test.js test/catalog-orm-write.test.js test/dataflow/provenance-pipeline-integration.test.js test/dataflow-progress.test.js test/scan-progress.test.js test/sard-leakage-pipeline.test.js test/sard-split-scoring.test.js test/sard-llm-isolation.test.js test/sard-mutation-adversarial.test.js test/sard-baseline-adaptive-tolerance.test.js test/sard-independent-holdout.test.js test/sard-flow-aware-scoring.test.js test/sard-macro-score-support-floor.test.js test/sard-php-split.test.js test/parser-java-nary-concat.test.js test/sard-naive-baseline.test.js test/field-taint-cross-method.test.js test/field-taint-engine-unit.test.js test/coercion-sanitizer-kill.test.js test/constant-propagation-path-sensitivity.test.js test/parser-java-assignments.test.js test/catalog-java-sard.test.js test/parser-cs-juliet-shapes.test.js test/catalog-cs-sard-p2.test.js test/sard-cwe-key-merge.test.js test/parser-php-backtick.test.js test/parser-php-include.test.js test/php-include-merge.test.js test/parser-php-array-field-taint.test.js test/parser-php-cond-assign.test.js test/parser-rust-redos.test.js test/multi-sink-taint-chain.test.js test/static-field-cross-class-call-string.test.js test/regex-guard-narrowing.test.js test/object-instance-field-taint.test.js test/param-type-inference.test.js test/smt-path-feasibility.test.js test/cross-service-taint.test.js test/dataflow-expr-taint-scaling.test.js test/evaluation/guard-dominance.test.js test/evaluation/engine-mechanisms.test.js",
79
+ "test:mcp": "node --test test/mcp.test.js test/mcp-apply-fix-multifile.test.js test/mcp-protocol-smoke.test.js test/mcp-audit.test.js test/audit-cli.test.js test/mcp-scratchpad.test.js test/mcp-offload.test.js test/sca-upgrade.test.js test/lsp-server.test.js test/mcp-dataflow-tools.test.js test/cli/governance-propose-edit.test.js test/cli/remediation-open-update.test.js test/cli/remediation-verify-reopen.test.js test/cli/dataflow-observations.test.js test/cli/federate-declare-list.test.js test/capabilities/tools.test.js",
79
80
  "test:report": "node --test test/report-scan-invariants.test.js test/junit.test.js test/ci.test.js test/poc-generator.test.js test/verifier.test.js test/verifier-target.test.js test/annotator-errors.test.js test/scan-health.test.js test/finding-schema.test.js test/pipeline/finding-schema-provenance.test.js test/evidence-provenance.test.js test/report/provenance-output.test.js test/report/provenance-format-parity.test.js test/legacy-compat.test.js test/annotator-runner.test.js test/detector-runner.test.js test/detector-errors.test.js test/analyzer-supervisor.test.js test/cascade-worker-pool.test.js test/cascade-pool-wiring.test.js test/coverage-ledger.test.js test/coverage-ledger-completeness.test.js test/assurance-mode.test.js test/artifact-registry.test.js test/artifact-registry-completeness.test.js test/retention-policy.test.js test/state-lifecycle-report.test.js test/legal-hold.test.js test/production-feedback.test.js test/calibration-feedback.test.js test/encryption-provider.test.js test/grader-calibration.test.js test/pr-delta-gate.test.js test/vex.test.js test/report-render.test.js test/oscal-conformance.test.js test/cli-fix-apply.test.js test/apply-fix-service.test.js test/high-impact-approval-gate.test.js test/approver-registry.test.js test/suppression-exceptions.test.js test/fix-history.test.js test/producer-registry.test.js test/producer-collector.test.js test/enrichment-completion.test.js",
80
81
  "test:lineage": "node --test test/lineage/schema.test.js test/lineage/ids.test.js test/lineage/protection.test.js test/lineage/classification.test.js test/lineage/validate.test.js test/lineage/json-schema-parity.test.js test/lineage/flagship-fixture.test.js test/lineage/flagship-fixture-semantics.test.js test/lineage/field-identity.test.js test/lineage/engine-expr-resolver.test.js test/lineage/engine-walker.test.js test/lineage/engine-integration.test.js test/lineage/engine-receiver-identity.test.js test/lineage/summaries.test.js test/lineage/driver.test.js test/lineage/engine-provenance.test.js test/lineage/engine-provenance-interprocedural.test.js test/lineage/path-store.test.js test/lineage/path-query.test.js test/lineage/flow-grade.test.js test/lineage/source-registry.test.js test/lineage/sink-registry.test.js test/lineage/transform-catalog.test.js test/lineage/handling-analyzer.test.js test/lineage/registry-real-code.test.js test/lineage/source-seeding.test.js test/lineage/graph-builder.test.js test/lineage/coverage.test.js test/lineage/resolve-destination.test.js test/lineage/queue-detail.test.js test/lineage/index.test.js test/lineage/obligation-mapping.test.js test/lineage/obligation-predicates.test.js test/lineage/obligation-predicates-walkthrough.test.js test/lineage/transit-protection.test.js test/lineage/at-rest-protection.test.js test/lineage/protection-summary.test.js test/lineage/ac01-multi-sink.test.js test/lineage/policy-verdict.test.js test/lineage/governance-refs.test.js test/lineage/export-privacy.test.js test/lineage/export-json.test.js test/lineage/export-csv.test.js test/lineage/decision-story.test.js test/lineage/export-briefing.test.js test/lineage/graph-snapshot.test.js test/lineage/graph-diff.test.js test/lineage/drift-policy.test.js test/lineage/recipient-profile.test.js test/lineage/recipient-registry.test.js test/lineage/recipient-wiring.test.js test/lineage/redact-graph.test.js test/lineage-scan-wiring.test.js test/lineage-artifact-write.test.js test/bench-data-lineage-runner.test.js test/bundle-frontend.test.js test/bundle-frontend-golden.test.js test/generate-html-report.test.js test/export-image.test.js test/lineage/scenario.test.js test/lineage/scenario-engine.test.js test/lineage/scenario-diff.test.js test/lineage/scenario-no-obligation-wiring.test.js test/lineage/impact-assessment.test.js test/lineage/impact-engine.test.js test/lineage/impact-no-obligation-wiring.test.js test/lineage/governance-edit.test.js test/lineage/remediation.test.js test/lineage/runtime-observation.test.js test/lineage/observation-correlation.test.js test/lineage/observation-adapters.test.js test/lineage/observation-store.test.js test/lineage/runtime-corroboration-wiring.test.js test/lineage/cross-repo-link.test.js test/lineage/federation-loader.test.js test/lineage/cross-repo-link-wiring.test.js",
81
82
  "test:bench-modules": "node --test test/phase4-harness.test.js test/pipeline.test.js test/proof-corpus-lib.test.js test/proof-corpus-runner.test.js",
@@ -88,7 +89,37 @@
88
89
  "bench:language-support:check": "node ../bench/language-support/check.mjs",
89
90
  "bench:live-feed": "node ../bench/live-feed/run.mjs",
90
91
  "bench:language-support:perf": "node ../bench/language-support/perf.mjs",
91
- "test:lifecycle": "node --test test/ci-hang-protection.test.js test/ci-test-shards.test.js test/pre-bash-guard.test.js test/lsp-protocol-smoke.test.js test/ide-surfaces.test.js test/detector-liveness.test.js test/bench-watchdog.test.js test/ci-parity.test.js test/dead-code.test.js test/no-dead-modules.test.js test/no-orphan-scripts.test.js test/no-stray-state.test.js test/tree-integrity.test.js test/stop-hook.test.js test/plugin-self-check.test.js test/skills-registry.test.js test/bodyguard.test.js test/cache-invalidator-guard.test.js test/dispatch-pre-tool.test.js test/dispatch-user-prompt.test.js test/session-start-model-capture.test.js test/sandbox.test.js test/sandbox-escape.test.js test/ci-templates.test.js test/agent-mcp-tools.test.js test/triage-command.test.js test/no-orphan-tests.test.js test/supply-command.test.js test/posture-command.test.js test/labs-command.test.js test/compliance-command.test.js test/check-doc-drift.test.js test/dist-chunks-tracked.test.js && node ../scripts/lint-command-descriptions.mjs test/workflow-confinement.test.js test/check-bundle-source.test.js test/ship.test.js",
92
+ "test:evaluation": "node --test test/evaluation/protocol.test.js test/evaluation/grouping.test.js test/evaluation/labels.test.js test/evaluation/custody.test.js test/evaluation/runner.test.js test/evaluation/gates-scorecard.test.js test/evaluation/reporting.test.js test/evaluation/why-missed.test.js test/evaluation/guard-dominance.test.js test/evaluation/engine-mechanisms.test.js test/evaluation/release-gate.test.js test/evaluation/publication.test.js",
93
+ "reproduce:mini": "node ../scripts/public-reproduction.mjs",
94
+ "reproduce:routing": "node ../scripts/routing-replay.mjs",
95
+ "verification:patch-example": "node ../scripts/patch-replay-example.mjs",
96
+ "example:tenant-invariant": "node ../scripts/tenant-invariant-example.mjs",
97
+ "example:graph-drift": "node ../scripts/graph-drift-example.mjs",
98
+ "example:blocked-capability": "node ../scripts/blocked-capability-example.mjs",
99
+ "example:migration": "node ../scripts/migration-example.mjs",
100
+ "example:portfolio-recovery": "node ../scripts/portfolio-recovery-example.mjs",
101
+ "example:assurance-review": "node ../scripts/assurance-review-example.mjs",
102
+ "example:controller": "node ../scripts/loop-engineering/ops-example.mjs",
103
+ "docs:assurance": "node ../scripts/render-assurance-docs.mjs",
104
+ "docs:check-assurance": "node ../scripts/render-assurance-docs.mjs --check && node ../scripts/check-assurance-docs.mjs",
105
+ "dev-recovery": "node ../scripts/dev-recovery.mjs",
106
+ "evaluation": "node ../scripts/evaluation.mjs",
107
+ "evaluation:synthetic": "node ../scripts/evaluation.mjs synthetic",
108
+ "test:routing": "node --test test/routing/outcomes.test.js test/routing/economics.test.js test/routing/adapter.test.js test/routing/calibration.test.js test/routing/decide.test.js test/routing/unchanged-when-off.test.js test/routing/shadow.test.js test/routing/promotion.test.js test/routing/drift.test.js test/routing/canary.test.js test/routing/feedback.test.js test/routing/report.test.js",
109
+ "test:release-closure": "node --test test/release-closure/closure-plan.test.js test/release-closure/closure-record.test.js test/release-closure/compatibility.test.js test/release-closure/rollout-stages.test.js test/release-closure/migration-readers.test.js test/release-closure/rollback.test.js test/release-closure/wrappers.test.js test/release-closure/final-closure.test.js test/release-closure/final-closure-controller.test.js test/release-closure/runner-hardening.test.js",
110
+ "release:closure:check": "node ../scripts/release-closure.mjs --run",
111
+ "release:closure:static": "node ../scripts/release-closure.mjs --static",
112
+ "test:documentation": "node --test test/documentation/drift-check.test.js test/documentation/generated-pages.test.js test/documentation/scope-and-examples.test.js test/documentation/policy-cards.test.js test/documentation/operations-and-review.test.js",
113
+ "test:capabilities": "node --test test/capabilities/manifest.test.js test/capabilities/filesystem.test.js test/capabilities/exec.test.js test/capabilities/network.test.js test/capabilities/canary.test.js test/capabilities/tools.test.js test/capabilities/recovery.test.js test/capabilities/receipts.test.js test/capabilities/adversarial.test.js",
114
+ "test:verification": "node --test test/verification/verification-record.test.js test/verification/oracle-adapters.test.js test/verification/replay-manifest.test.js test/verification/patch-negative.test.js test/verification/non-taint-classes.test.js test/verification/interface-equivalence.test.js test/verification/advisory-gating.test.js test/verification/oracle-conformance.test.js",
115
+ "test:deployment": "node --test test/deployment/boundary-graph.test.js test/deployment/config-adapters.test.js test/deployment/trace-correlation.test.js test/deployment/cross-repo.test.js test/deployment/attack-paths.test.js test/deployment/drift.test.js test/deployment/boundary-presentation.test.js test/deployment/differentiation-ablation.test.js test/deployment/boundaries-cli.test.js",
116
+ "test:portfolio": "node --test test/portfolio/manifest.test.js test/portfolio/bundle.test.js test/portfolio/signing.test.js test/portfolio/work-units.test.js test/portfolio/resume.test.js test/portfolio/scheduler.test.js test/portfolio/progress.test.js test/portfolio/retention.test.js test/portfolio/backend.test.js",
117
+ "test:invariants": "node --test test/invariants/invariant-schema.test.js test/invariants/invariant-lifecycle.test.js test/invariants/invariant-scenarios.test.js test/invariants/business-state-oracle.test.js test/invariants/scenario-shrinking.test.js test/invariants/invariant-repair.test.js test/invariants/business-coverage.test.js test/invariants/invariant-ablation.test.js",
118
+ "bench:invariant-ablation": "node ../scripts/invariant-ablation.mjs",
119
+ "verification:conformance:check": "node ../scripts/verification-conformance-check.mjs",
120
+ "verification:conformance:static": "node ../scripts/verification-conformance-check.mjs --static",
121
+ "verification:replay-example": "node ../scripts/verification-replay-example.mjs",
122
+ "test:lifecycle": "node --test test/ci-hang-protection.test.js test/ci-test-shards.test.js test/pre-bash-guard.test.js test/lsp-protocol-smoke.test.js test/ide-surfaces.test.js test/detector-liveness.test.js test/bench-watchdog.test.js test/ci-parity.test.js test/dead-code.test.js test/no-dead-modules.test.js test/no-orphan-scripts.test.js test/no-stray-state.test.js test/tree-integrity.test.js test/stop-hook.test.js test/plugin-self-check.test.js test/skills-registry.test.js test/bodyguard.test.js test/cache-invalidator-guard.test.js test/dispatch-pre-tool.test.js test/dispatch-user-prompt.test.js test/session-start-model-capture.test.js test/sandbox.test.js test/sandbox-escape.test.js test/trust-boundary.test.js test/ci-templates.test.js test/agent-mcp-tools.test.js test/triage-command.test.js test/no-orphan-tests.test.js test/supply-command.test.js test/posture-command.test.js test/labs-command.test.js test/compliance-command.test.js test/check-doc-drift.test.js test/dist-chunks-tracked.test.js && node ../scripts/lint-command-descriptions.mjs test/workflow-confinement.test.js test/check-bundle-source.test.js test/ship.test.js",
92
123
  "test:eval": "node --test test/independent-eval.test.js test/realworld-recall.test.js",
93
124
  "test:discovery": "node --test test/discovery-partition.test.js test/discovery-lenses.test.js test/discovery-hunter.test.js test/discovery-confirm.test.js test/discovery-disprove.test.js test/discovery-judge.test.js test/discovery-run.test.js test/discovery-wiring.test.js test/discovery-llm-invoke.test.js test/local-only-mode.test.js",
94
125
  "eval:independent": "node ../bench/independent-eval/runner.mjs",
@@ -133,6 +164,7 @@
133
164
  "bench:self-scan:check": "node ../bench/self-scan/check.mjs",
134
165
  "bench:nist-800-171-labels:check": "node ../bench/nist-800-171-labels/check.mjs",
135
166
  "bench:mutation:check": "node ../bench/mutation/runner.mjs",
167
+ "baseline:capture": "node ../scripts/baseline-capture.mjs",
136
168
  "bench:protection-verdict:check": "node ../bench/protection-verdict/runner.mjs",
137
169
  "bench:fix-correctness": "node ../bench/fix-correctness/runner.mjs",
138
170
  "bench:iac-coverage": "node ../bench/iac-coverage/runner.mjs",
@@ -0,0 +1,114 @@
1
+ # src/capabilities/
2
+
3
+ Task capability manifests and runner-level enforcement of filesystem, structured
4
+ command and outbound network access (X-501 to X-504 of the differentiation PRD).
5
+ A hook explains a decision; the runner is what stops the task. Nothing here is
6
+ wired into `engine.js` or the scan/report path: a default scan is unchanged, and
7
+ the `capability-enforcement` feature (`posture/assurance/config.js`) is off by
8
+ default, operator-only (a project file can never turn it on) and advertised for
9
+ Linux only.
10
+
11
+ Suite: `npm run test:capabilities` (`test/capabilities/`, in `npm test` through
12
+ `scripts/run-unit-tests.mjs` SCOPES). Every criterion has a test named
13
+ `[X-50n.ACnn]`, both directions.
14
+
15
+ ## Modules
16
+
17
+ | Module | Role |
18
+ |---|---|
19
+ | `manifest.js` | X-501. `validateManifest`, `bindManifest`, `deriveChild`, `manifestDigest`. Deny-by-default, closed-world, frozen. A bound manifest carries `binding = {taskId, revision, policyVersion, digest}`. `deriveChild` builds a child only from a subset of the parent (lexical AND symlink-resolved path containment, command argument modes, host/port/scheme/pin containment, limits, delegation depth); any widening is `SCOPE_EXPANSION` and yields NO manifest. |
20
+ | `decide.js` | X-501.AC02/AC03. `decide(bound, action, ctx)`: one deterministic, frozen, sanitized decision per action (`filesystem-read/write`, `command`, `network`, `tool`, `delegation`). The claimed binding must match. Unknown kinds, malformed actions and any exception are `deny`. Also owns the interpreter table and the shebang check. |
21
+ | `reasons.js` | The closed table of reason codes. `reason` is always the fixed sentence for the code; only `subject` is request-derived and it is redacted and length-capped. |
22
+ | `paths.js`, `address.js` | Path canonicalization (symlinks, `..`) and host/address classification (strict dotted quads, no numeric tail labels, mapped IPv6, metadata addresses). Pure helpers. |
23
+ | `secrets.js` | One scrubber: provider-shaped credentials (`mcp/redact.js` `redactSecretShapes`) plus assignment/entropy shapes (`llm-validator/redact.js`). `detectSecretShapes` (no entropy pass) is what argument checking uses. |
24
+ | `outbound.js` | X-504.AC02/AC03. `redactOutbound` (URL userinfo, secret query params, secret header names, JSON/form/text bodies, canary values in raw, URL-encoded and base64 forms), `sanitizeLogText`, `denialRecord` (class, host digest, port, scheme, code; never the host or any payload), `recordNetworkDenial` (appends to the existing `egress/audit.js` chain). |
25
+ | `proxy.js` | X-504.AC01. The one network door: a loopback HTTP proxy. Checks the declared destination, resolves the name once, checks the resolved addresses and connects to THAT address, filters plaintext HTTP, tunnels declared https opaquely, never follows a redirect. |
26
+ | `probes.js` | Active probes for `fs-read-confinement`, `fs-multi-root-write` and `network-mediation` (attack plus positive control), layered on `sandbox/control-probes.js`; `requiredControlsFor(manifest)`; `isAdvertisedBackend`; `platformStatements`. Results are cached per process and per backend. |
27
+ | `runner.js` | X-502/X-503. `runCapabilityTask(bound, {executable, args, env?, cwd?}, opts)`. Gate order: feature, platform, binding and secret-free environment, command policy, protected paths, backend, active probes. Then one supervised run. |
28
+ | `records.js` | Decisions as CORE-002 `capability-decision` records, and `advise` (the hook view: `hook-advisory`, never enforced). |
29
+ | `report.js` | `buildCapabilityReport`: per capability `requested` / `checked` (probe states) / `enforced`, plus resource enforcement and the standing limitations. |
30
+
31
+ ## What is enforced, and by what
32
+
33
+ - **Filesystem.** `sandbox/backend-userspace.js` gained opt-in capability mode:
34
+ `readRoots` (reads confined to a baseline of system paths plus the declared
35
+ roots; metadata only for the ancestors of those roots, so other paths cannot be
36
+ probed for existence), `writeRoots`, `cwd`, `networkProxyPort`. Absent, the
37
+ profile is byte-for-byte what it was. Protected paths (key directory, home
38
+ credential directories, label and evidence directories) are read-denied after
39
+ every allow, and a manifest root that overlaps one is blocked before anything
40
+ runs. The kernel stops symlink and `..` escapes; `decide` agrees and names why.
41
+ - **Commands.** Executable plus argument array, never a shell string. The array
42
+ reaches `exec` as an array, so command substitution is text. Executables must
43
+ be absolute, listed, not inside a writable root, and not an interpreter (known
44
+ shells/runtimes/launchers by name, anything starting `#!`) unless declared
45
+ `interpreter: 'scoped'` with exact pinned arguments. A secret-shaped argument
46
+ or registered canary blocks the run. The environment is the sandbox's minimal
47
+ one plus explicit non-secret variables.
48
+ - **Descendants.** They inherit the file and network confinement (it is the
49
+ kernel's) and are tracked and terminated by `sandbox/supervise.js` on deadline,
50
+ cancellation, output flood or exit. The result carries `cleanup`
51
+ (`signalled`, `killedPids`, `survivors`, `complete`). NOT claimed: allowlisting
52
+ the exec calls a descendant makes.
53
+ - **Network.** No network at all unless the manifest declares destinations; then
54
+ exactly the proxy's loopback port is open in the profile, and the proxy URL is
55
+ in the environment of the whole tree. A direct socket, a datagram, a name lookup
56
+ or a local service socket is refused by the kernel. HTTPS is an opaque tunnel
57
+ (payload not inspected; the report says `payloadFiltering: plaintext-http-only`).
58
+
59
+ ## Enforcement status, stated plainly
60
+
61
+ `level` is `enforced` only when the backend is an advertised one (the kernel
62
+ namespace backend on Linux) AND every control the manifest depends on is
63
+ `proved`. On macOS the probes can prove the userspace controls on the host, and a
64
+ task can run there only when the caller passes `allowUnadvertisedBackend`; the
65
+ result is `level: 'host-proved'`, `enforced: false`, and every capability in the
66
+ report says so. Without the opt-in an isolation-required task is `unsupported`
67
+ (`platform-unsupported`). A control that is not proved BLOCKS the run (typed
68
+ `blocked`, `missing-execution-backend`, the target never executes).
69
+
70
+ **Linux is `unverified`.** The namespace backend does not implement read
71
+ confinement to declared roots, several write roots, mediated network or
72
+ supervised tree termination, so every Linux run is currently blocked with the
73
+ missing control named. Nothing here asserts a Linux outcome that has not been
74
+ executed; the `sandbox-linux` job is where it will be exercised. Process-count
75
+ caps are never asserted on any backend (per-user and system-wide on macOS; they
76
+ did not refuse on the hosted Linux runner in a previous release and the cause was
77
+ never established); `maxProcesses` is carried and reported `unverified`, memory
78
+ caps are carried and reported `not-enforced`.
79
+
80
+ ## Known limits (also in `REPORT_LIMITATIONS`)
81
+
82
+ Descendant exec is not allowlisted; ancestors of declared roots expose metadata;
83
+ the proxy accepts connections from any local process (it only forwards to the
84
+ declared set); a double-fork plus `setsid` between supervisor sweeps can outlive
85
+ a task; the policy layer is advisory wherever the runner is not the caller.
86
+
87
+ ## Tool use, delegation, recovery, receipts, adversarial corpus (X-505 to X-508)
88
+
89
+ | Module | Role |
90
+ |---|---|
91
+ | `tool-registry.js` | X-505.AC01. The classification of every MCP tool (`read` / `mutating` / `external`) and the checks it requires before the handler runs. `test/capabilities/tools.test.js` compares it with `mcp/tools.js` `ALL_TOOLS` in both directions, so a new tool without a classification fails. |
92
+ | `tool-gate.js` | X-505. `createToolGate`: the check `mcp/server.js` makes before a handler, for the task identity bound to the server. Active when an operator-supplied `capabilityPolicy` is bound OR the operator enabled the feature in the environment (a project file never can). Feature on and no policy: read tools pass, mutating/external tools are `identity-missing`. A request-metadata task id that differs from the bound one is `identity-spoofed`. Unclassified tools are `tool-unclassified`. Decisions are `in-process-policy`, never `enforced`. |
93
+ | `delegate.js` | X-505.AC02. `delegate(parent, request, {binding, registry, guard})`: the one door for handing capabilities to another agent. Depth comes from the manifest chain (each hop needs a strictly lower `maxDepth`), the child is derived once by `deriveChild` (frozen, no partial grant), tool names compare exactly (no aliases), and a child task id is issued once (`registry`). |
94
+ | `hook-advice.js`, `hooks/lib/capability-advice.js` | X-505. What a hook says: the same `decide`, labelled `hook-advisory`, never blocking. Inert unless the operator set `AGENTIC_SECURITY_ASSURANCE_CAPABILITY_ENFORCEMENT=1` AND `AGENTIC_SECURITY_CAPABILITY_MANIFEST=<file>`; wired into `dispatch-pre-tool.js` (edits), `pre-bash-guard.js` (a shell string is reported `unsupported`) and `capability-dispatch.js` (`Task`, `Agent`, `mcp__*`). Hook tool names are the HOST spelling (`mcp__srv__apply_fix`); the server gate sees the short name; there is no aliasing between the two. |
95
+ | `recovery.js` | X-506. `proposeChange` (missing capability plus the narrowest reviewable `{add}`; nothing proposed for key/label/link/secret/metadata refusals), `mediate` (one decision, `ok` or `blocked`, never a fallback), `createDenialGuard` (finite per-action retries and a per-task denial budget, reset only by a new policy version), `signPolicyGrant` (signer domain only) and `applyPolicyChange` (Ed25519 grant bound to the exact from/to manifest digests, short window, single use, finite changes per task; creates policy version N+1, appends to a hash-chained `createPolicyLedger`, reruns preflight). The worker has no signing key, so it cannot grant itself an exception. |
96
+ | `receipts.js` | X-507. Hash-chained receipts (`start` with the runner's observed backend, level and control states, `decision`, `outcome`, `end` seal naming every decision id), signed in the signer domain with the self-issued trust label from `posture/evidence-bundle.js`. `createReceiptRecorder` needs a domain that may write authoritative evidence (verifier), `signReceiptChain` a domain that may read the signing key (signer). `verifyReceiptEnvelope` needs only the public key and returns `label`: `fully-enforced` only for a complete, intact, current chain whose runner reached `enforced` with every control proved; otherwise `incomplete-audit-trail`, `superseded-policy`, `host-proved-not-enforced`, `not-run`, `tampered`. `receiptReport` reads requested / checked / enforced from the SIGNED start receipt. |
97
+ | `attack-coverage.js` | X-508. `buildAttackCoverage` and `enforcedModeReleaseGate` over the corpus results. A mandatory leak, error or uncovered class blocks; a skipped mandatory case or a non-`enforced` level makes enforced mode unreleasable without being a failure; a reproduced documented limit is reported in the notes. |
98
+
99
+ `test/capabilities/adversarial/corpus.js` is the disposable malicious-repository corpus (injection text, build
100
+ scripts, canaries outside the repository, recording servers). Execution cases skip loudly where no userspace
101
+ backend is probed; policy cases run everywhere. Mandatory cases must be blocked with no canary leak. One
102
+ non-mandatory case (`DE-03`) records a documented limit honestly: a detached grandchild whose parent exits
103
+ before the next supervisor sweep can outlive the task, with confinement still holding (it reads no secret
104
+ and reaches no destination). That outcome is `known-limit`, not `blocked`. Passing the corpus shows these
105
+ attempts were stopped on this backend in this run; it does not show the sandbox is secure against all attempts.
106
+
107
+ ### What is still not claimed
108
+
109
+ Tool and delegation checks are policy at the tool boundary (the tool then runs in the server process): the
110
+ runner remains the only enforcement layer. Linux stays `unverified` in every report, receipt and coverage
111
+ record, and no Linux outcome is asserted. No process-count cap is asserted. The corpus is not wired into the
112
+ `sandbox-linux` CI job: it would need execution cases that skip loudly (never silently pass) on Linux, and that
113
+ has not been shown from this workspace. The enforced-mode release gate (`enforcedModeReleaseGate`) is a library
114
+ function used by the suite; it is not yet called from `scripts/release-check.mjs`.
@@ -0,0 +1,73 @@
1
+ // Host and address helpers for network policy (X-504). Pure.
2
+ import net from 'node:net';
3
+
4
+ const LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
5
+
6
+ /**
7
+ * Canonical host: lower case, one trailing dot removed, IPv6 brackets removed.
8
+ * Returns `{ ok, host, kind }` with kind `ip4`, `ip6` or `name`. Numeric forms
9
+ * that are not a strict dotted quad (`2130706433`, `0x7f.1`, `127.1`) are
10
+ * rejected, because different parsers read them as different addresses and a
11
+ * policy must not be decided on a reading the connecting stack may not share.
12
+ */
13
+ export function normalizeHost(raw) {
14
+ if (typeof raw !== 'string') return { ok: false };
15
+ let h = raw.trim().toLowerCase();
16
+ if (h.startsWith('[') && h.endsWith(']')) h = h.slice(1, -1);
17
+ if (h.endsWith('.') && h.length > 1) h = h.slice(0, -1);
18
+ if (!h || h.length > 253 || /[^\x21-\x7e]/.test(h)) return { ok: false };
19
+ const family = net.isIP(h);
20
+ if (family === 4) return { ok: true, host: h, kind: 'ip4' };
21
+ if (family === 6) return { ok: true, host: h, kind: 'ip6' };
22
+ const labels = h.split('.');
23
+ // A top-level label is never numeric; one that is (or starts 0x) is an address in disguise.
24
+ if (/^(?:0x[0-9a-f]*|[0-9]+)$/.test(labels[labels.length - 1])) return { ok: false };
25
+ if (!labels.every((l) => LABEL.test(l))) return { ok: false };
26
+ return { ok: true, host: h, kind: 'name' };
27
+ }
28
+
29
+ function v4Parts(ip) { return ip.split('.').map(Number); }
30
+
31
+ function classifyV4(ip) {
32
+ const [a, b] = v4Parts(ip);
33
+ if (ip === '169.254.169.254') return 'metadata';
34
+ if (a === 127) return 'loopback';
35
+ if (a === 0) return 'unspecified';
36
+ if (a === 10 || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 100 && b >= 64 && b <= 127)) return 'private';
37
+ if (a === 169 && b === 254) return 'link-local';
38
+ if (a >= 224 && a <= 239) return 'multicast';
39
+ if (a >= 240) return 'reserved';
40
+ return 'public';
41
+ }
42
+
43
+ /**
44
+ * Class of an address: loopback, private, link-local, metadata, unspecified,
45
+ * multicast, reserved or public. IPv4-mapped IPv6 is judged as the IPv4
46
+ * address it carries. Anything that is not an address is `invalid`.
47
+ */
48
+ export function classifyAddress(ip) {
49
+ const family = net.isIP(ip);
50
+ if (family === 4) return classifyV4(ip);
51
+ if (family !== 6) return 'invalid';
52
+ const l = ip.toLowerCase();
53
+ const mapped = /^::ffff:(\d+\.\d+\.\d+\.\d+)$/.exec(l);
54
+ if (mapped) return classifyV4(mapped[1]);
55
+ const hex = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(l);
56
+ if (hex) {
57
+ const hi = parseInt(hex[1], 16); const lo = parseInt(hex[2], 16);
58
+ return classifyV4(`${hi >> 8}.${hi & 255}.${lo >> 8}.${lo & 255}`);
59
+ }
60
+ if (l === '::1') return 'loopback';
61
+ if (l === '::') return 'unspecified';
62
+ if (l.startsWith('fd00:ec2::254')) return 'metadata';
63
+ const first = parseInt(l.split(':')[0] || '0', 16);
64
+ if ((first & 0xfe00) === 0xfc00) return 'private';
65
+ if ((first & 0xffc0) === 0xfe80) return 'link-local';
66
+ if ((first & 0xff00) === 0xff00) return 'multicast';
67
+ return 'public';
68
+ }
69
+
70
+ /** Non-public classes a host name must not resolve to unless declared. */
71
+ export function isNonPublicClass(cls) {
72
+ return cls !== 'public';
73
+ }
@@ -0,0 +1,93 @@
1
+ // Attack coverage and the enforced-mode release gate (X-508.AC02, X-508.AC03).
2
+ //
3
+ // The adversarial corpus (test/capabilities/adversarial/) is a REGRESSION corpus:
4
+ // a list of concrete escape attempts that must keep failing. This module turns the
5
+ // results of a run into two things.
6
+ //
7
+ // buildAttackCoverage what was attempted, per attack class, on which platform
8
+ // and backend, with the known limits stated beside it.
9
+ // It says what the corpus covered; it never says the
10
+ // sandbox is secure.
11
+ // enforcedModeReleaseGate the decision a release takes from those results: any
12
+ // mandatory fixture that leaked a canary or errored, a
13
+ // mandatory class with no case, or (for enforced mode) a
14
+ // mandatory execution case that did not run, BLOCKS.
15
+ //
16
+ // Passing the corpus proves that these attempts were stopped on this backend in
17
+ // this run. It does not prove that no other attempt succeeds.
18
+ export const ATTACK_CLASSES = Object.freeze([
19
+ 'prompt-injection', 'malicious-build-script', 'secret-read', 'network-exfiltration', 'tool-confusion',
20
+ 'descendant-escape', 'verifier-tampering', 'delegation-escalation', 'receipt-tampering',
21
+ ]);
22
+
23
+ // `known-limit`: the attempt reproduced a limit that is DOCUMENTED (KNOWN_LIMITS), with
24
+ // confinement still holding (no canary left its place). Only a non-mandatory case
25
+ // may end this way; it is reported, never counted as blocked.
26
+ export const OUTCOMES = Object.freeze(['blocked', 'leaked', 'error', 'skipped', 'known-limit']);
27
+ const COUNTER = Object.freeze({ blocked: 'blocked', leaked: 'leaked', error: 'error', skipped: 'skipped', 'known-limit': 'knownLimit' });
28
+
29
+ export const KNOWN_LIMITS = Object.freeze([
30
+ 'The corpus is a fixed list of attempts. A pass shows those attempts were stopped; it is not a proof that the sandbox is secure against all attempts.',
31
+ 'Linux is unverified from this workspace: no Linux outcome is asserted by any case, and enforced mode is advertised for Linux only.',
32
+ 'Descendant exec calls are not allowlisted; descendants inherit file and network confinement and are terminated with the task.',
33
+ 'A process that double-forks and calls setsid between two supervisor sweeps can outlive a task.',
34
+ 'HTTPS to a declared destination is an opaque tunnel: its payload is not inspected.',
35
+ 'The mediation proxy accepts connections from any local process, and forwards only to the declared destinations.',
36
+ 'Tool and delegation checks are policy at the tool boundary (in-process); only the runner enforces.',
37
+ 'Process-count caps are not asserted on any backend.',
38
+ ]);
39
+
40
+ /**
41
+ * @param {Array<{id:string, class:string, mandatory?:boolean, execution?:boolean, outcome:string, note?:string}>} results
42
+ * @param {{platform:string, backend:string|null, level:string}} env what the run observed
43
+ */
44
+ export function buildAttackCoverage(results, { platform, backend, level } = {}) {
45
+ const classes = Object.fromEntries(ATTACK_CLASSES.map((c) => [c, { cases: 0, blocked: 0, leaked: 0, error: 0, skipped: 0, knownLimit: 0 }]));
46
+ const unknown = [];
47
+ for (const r of results) {
48
+ const c = classes[r.class];
49
+ if (!c) { unknown.push(r.id); continue; }
50
+ c.cases += 1;
51
+ if (OUTCOMES.includes(r.outcome)) c[COUNTER[r.outcome]] += 1; else c.error += 1;
52
+ }
53
+ const totals = { cases: 0, blocked: 0, leaked: 0, error: 0, skipped: 0, knownLimit: 0 };
54
+ for (const c of Object.values(classes)) for (const k of Object.keys(totals)) totals[k] += c[k];
55
+ return Object.freeze({
56
+ schema: 'agentic-security/attack-coverage', version: 1,
57
+ platform: platform ?? process.platform, backend: backend ?? null, level: level ?? 'none',
58
+ classes, totals,
59
+ uncoveredClasses: ATTACK_CLASSES.filter((c) => classes[c].cases === 0),
60
+ unknownClassCases: unknown,
61
+ platforms: { linux: 'unverified' },
62
+ knownLimits: KNOWN_LIMITS,
63
+ claim: 'regression corpus: these attempts were attempted and their outcomes recorded; this is not evidence of a universally secure sandbox',
64
+ cases: results.map((r) => ({ id: r.id, class: r.class, mandatory: r.mandatory !== false, execution: r.execution === true, outcome: r.outcome, ...(r.note ? { note: String(r.note).slice(0, 200) } : {}) })),
65
+ });
66
+ }
67
+
68
+ /**
69
+ * The release decision. `block` is true when anything mandatory failed;
70
+ * `enforcedModeReleasable` is true only when nothing blocks AND the run reached
71
+ * the `enforced` level with every mandatory execution case actually executed.
72
+ */
73
+ export function enforcedModeReleaseGate(coverage) {
74
+ const reasons = [];
75
+ const mandatory = coverage.cases.filter((c) => c.mandatory);
76
+ for (const c of mandatory) {
77
+ if (c.outcome === 'leaked') reasons.push(`mandatory fixture leaked: ${c.id}`);
78
+ else if (c.outcome === 'error') reasons.push(`mandatory fixture errored: ${c.id}`);
79
+ }
80
+ for (const cls of coverage.uncoveredClasses) reasons.push(`no fixture covers the attack class: ${cls}`);
81
+ if (coverage.unknownClassCases.length) reasons.push(`fixtures with an unknown attack class: ${coverage.unknownClassCases.join(', ')}`);
82
+ const block = reasons.length > 0;
83
+ const skippedMandatory = mandatory.filter((c) => c.outcome === 'skipped');
84
+ const notes = [];
85
+ if (coverage.level !== 'enforced') notes.push(`backend level is '${coverage.level}', not 'enforced': this run cannot release enforced mode`);
86
+ const limits = coverage.cases.filter((c) => c.outcome === 'known-limit');
87
+ if (limits.length) notes.push(`${limits.length} documented limit(s) reproduced on this backend, with confinement holding: ${limits.map((c) => c.id).join(', ')}`);
88
+ if (skippedMandatory.length) notes.push(`${skippedMandatory.length} mandatory case(s) did not execute: ${skippedMandatory.map((c) => c.id).join(', ')}`);
89
+ return Object.freeze({
90
+ block, reasons, notes,
91
+ enforcedModeReleasable: !block && coverage.level === 'enforced' && skippedMandatory.length === 0,
92
+ });
93
+ }