@clear-capabilities/agentic-security-scanner 0.195.25 → 0.195.27
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/CHANGELOG.md +27 -0
- package/bin/agentic-security.js +13 -3
- package/dist/396.index.js +936 -0
- package/dist/5752.index.js +15 -2
- package/dist/7838.index.js +22 -0
- package/dist/8218.index.js +19 -2
- package/dist/{809c900a90284017aaff.json → 90ebba38d8860ec77376.json} +4 -4
- package/dist/9382.index.js +315 -174
- package/dist/9560.index.js +19 -2
- package/dist/agentic-security.mjs +9 -9
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +4 -4
- package/src/context-intelligence/CLAUDE.md +4 -0
- package/src/context-intelligence/entrypoints.js +141 -9
- package/src/context-intelligence/imports.js +1 -1
- package/src/context-intelligence/review.js +8 -3
- package/src/engine.js +10 -0
- package/src/lineage/CLAUDE.md +4 -0
- package/src/lineage/graph-builder.js +8 -0
- package/src/lineage/index.js +2 -0
- package/src/posture/CLAUDE.md +10 -2
- package/src/posture/custom-rules.js +7 -2
- package/src/posture/dag-commands.js +15 -2
- package/src/posture/provenance/coordinator.js +6 -2
- package/src/posture/provenance/dag-walk.js +7 -3
- package/src/posture/provenance/git-evidence.js +21 -0
- package/src/posture/provenance/origin-resolver.js +16 -2
- package/src/posture/provenance/providers/github.js +6 -3
- package/src/posture/provenance/providers/gitlab.js +5 -3
- package/src/posture/rule-compiler/cli.js +76 -21
- package/src/posture/rule-compiler/negative-corpus.js +39 -0
- package/src/posture/rule-compiler/promotion.js +21 -0
- package/src/posture/rule-compiler/regression.js +39 -9
- package/src/posture/rule-compiler/store.js +72 -6
- package/src/server/graph-loader.js +19 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
b1cf360cafbd8aeec59db25fb8e523f29104e005863aff5d6d00be22d3c1c58f agentic-security.mjs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clear-capabilities/agentic-security-scanner",
|
|
3
|
-
"version": "0.195.
|
|
3
|
+
"version": "0.195.27",
|
|
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",
|
|
@@ -86,11 +86,11 @@
|
|
|
86
86
|
"test:ollama-e2e": "AGENTIC_SECURITY_OLLAMA_E2E=1 node --test test/ollama-e2e.test.js",
|
|
87
87
|
"test:glob": "node --test test/glob-compat.test.js",
|
|
88
88
|
"test:sast": "node --test test/dag-precision.test.js test/cpp-hardcoded-secret.test.js test/sibling-guard.test.js test/comment-blindness.test.js test/todo-marker-words.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/zip-slip-go.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/vendor-java-parser-current.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",
|
|
89
|
-
"test:posture": "node --test test/contracts/root-cause-sweep.contract.test.js test/contracts/model-validation.contract.test.js test/contracts/agentic-discovery.contract.test.js test/contracts/local-models.contract.test.js test/contracts/dependency-finding.contract.test.js test/contracts/taint-flow.contract.test.js test/contracts/runtime-corroboration.contract.test.js test/compliance-coverage.test.js test/contracts/blast-radius.contract.test.js test/contracts/federation.contract.test.js test/contracts/eval-lab-report.contract.test.js test/contracts/fleet.contract.test.js test/contracts/rule-compiler.contract.test.js test/contracts/release-assurance.contract.test.js test/contracts/dnr.contract.test.js test/contracts/strategic-metrics.contract.test.js test/contracts/exploit-proof.contract.test.js test/contracts/artifact-provenance.contract.test.js test/dnr/artifact-join.test.js test/rule-pack-signing.test.js 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-transport.test.js test/local-preset-callers.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/api-contract-scope.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 test/fleet/job-store.test.js test/fleet/enterprise-graph.test.js test/fleet/discover-edges.test.js test/fleet/code-boundaries.test.js test/fleet/job-runner.test.js test/fleet/accounting.test.js test/fleet/fleet-org-cli.test.js test/eval-lab/dataset-neutralize.test.js test/eval-lab/arms-score-stats.test.js test/eval-lab/run-report.test.js test/eval-lab/router.test.js test/eval-lab/arm-ollama.test.js test/eval-lab/import-independent.test.js test/cli/eval-lab-cli.test.js test/dnr/ir-and-outputs.test.js test/dnr/logs-and-hunt.test.js test/dnr/window-store-view.test.js test/dnr/exploit-correlation.test.js test/cli/dnr-cli.test.js test/proof-fabric/core.test.js test/proof-fabric/container.test.js test/proof-fabric/generate.test.js test/proof-fabric/siblings.test.js test/proof-fabric/generate-python.test.js test/proof-fabric/generate-haskell.test.js test/proof-fabric/generate-haskell-widened.test.js test/cli/proof-lifecycle-demo.test.js test/mcp-proof.test.js test/proof-fabric/fix-store-runner.test.js test/proof-fabric/fixtures.test.js test/cli/proof-fabric-cli.test.js test/rule-compiler/core.test.js test/rule-compiler/gates.test.js test/rule-compiler/synthesis.test.js test/rule-compiler/structure.test.js test/cli/rule-compiler-cli.test.js test/fleet/fleet-graph.test.js test/fleet/fleet-manifest.test.js test/fleet/fleet-cli.test.js test/artifact/safe-tar.test.js test/artifact/image-archive.test.js test/artifact/filesystem.test.js test/artifact/layer-secrets.test.js test/artifact/inventory.test.js test/artifact/vuln-correlate.test.js test/artifact/signature.test.js test/artifact/provenance-graph.test.js test/artifact/mismatch.test.js test/artifact/vex.test.js test/artifact/registry.test.js test/artifact/sources-cosign-evidence.test.js test/cli/artifact-sources-cli.test.js test/cli/artifact-provenance-cli.test.js test/witness-bundle.test.js",
|
|
89
|
+
"test:posture": "node --test test/contracts/finding-provenance.contract.test.js test/contracts/root-cause-sweep.contract.test.js test/contracts/model-validation.contract.test.js test/contracts/agentic-discovery.contract.test.js test/contracts/local-models.contract.test.js test/contracts/dependency-finding.contract.test.js test/contracts/taint-flow.contract.test.js test/contracts/runtime-corroboration.contract.test.js test/compliance-coverage.test.js test/contracts/blast-radius.contract.test.js test/contracts/federation.contract.test.js test/contracts/eval-lab-report.contract.test.js test/contracts/fleet.contract.test.js test/contracts/rule-compiler.contract.test.js test/contracts/release-assurance.contract.test.js test/contracts/dnr.contract.test.js test/contracts/strategic-metrics.contract.test.js test/contracts/exploit-proof.contract.test.js test/contracts/artifact-provenance.contract.test.js test/dnr/artifact-join.test.js test/rule-pack-signing.test.js 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-transport.test.js test/local-preset-callers.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/api-contract-scope.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 test/fleet/job-store.test.js test/fleet/enterprise-graph.test.js test/fleet/discover-edges.test.js test/fleet/code-boundaries.test.js test/fleet/job-runner.test.js test/fleet/accounting.test.js test/fleet/fleet-org-cli.test.js test/eval-lab/dataset-neutralize.test.js test/eval-lab/arms-score-stats.test.js test/eval-lab/run-report.test.js test/eval-lab/router.test.js test/eval-lab/arm-ollama.test.js test/eval-lab/import-independent.test.js test/cli/eval-lab-cli.test.js test/dnr/ir-and-outputs.test.js test/dnr/logs-and-hunt.test.js test/dnr/window-store-view.test.js test/dnr/exploit-correlation.test.js test/cli/dnr-cli.test.js test/proof-fabric/core.test.js test/proof-fabric/container.test.js test/proof-fabric/generate.test.js test/proof-fabric/siblings.test.js test/proof-fabric/generate-python.test.js test/proof-fabric/generate-haskell.test.js test/proof-fabric/generate-haskell-widened.test.js test/cli/proof-lifecycle-demo.test.js test/mcp-proof.test.js test/proof-fabric/fix-store-runner.test.js test/proof-fabric/fixtures.test.js test/cli/proof-fabric-cli.test.js test/rule-compiler/core.test.js test/rule-compiler/gates.test.js test/rule-compiler/ci-regression.test.js test/rule-compiler/synthesis.test.js test/rule-compiler/structure.test.js test/cli/rule-compiler-cli.test.js test/fleet/fleet-graph.test.js test/fleet/fleet-manifest.test.js test/fleet/fleet-cli.test.js test/artifact/safe-tar.test.js test/artifact/image-archive.test.js test/artifact/filesystem.test.js test/artifact/layer-secrets.test.js test/artifact/inventory.test.js test/artifact/vuln-correlate.test.js test/artifact/signature.test.js test/artifact/provenance-graph.test.js test/artifact/mismatch.test.js test/artifact/vex.test.js test/artifact/registry.test.js test/artifact/sources-cosign-evidence.test.js test/cli/artifact-sources-cli.test.js test/cli/artifact-provenance-cli.test.js test/witness-bundle.test.js",
|
|
90
90
|
"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 test/rx-exec-receiver.test.js test/incremental-dependency.test.js test/incremental-integrity.test.js test/demand-query.test.js test/ir-cache.test.js test/canonicalize-parity.test.js test/dataflow-source-attribution.test.js",
|
|
91
91
|
"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",
|
|
92
92
|
"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/git-history-batch.test.js test/default-scan-drift.test.js test/bundle-optional-deps.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",
|
|
93
|
-
"test:lineage": "node --test test/lineage/analysis-completion.test.js 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/seeding-across-calls.test.js test/lineage/boundary-join.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 test/lineage/runtime-assurance.test.js test/lineage/runtime-edge-states.test.js test/lineage/runtime-explorer-view.test.js test/cli/runtime-explorer-cli.test.js test/cli/runtime-identity-cli.test.js test/cli/runtime-twin-cli.test.js test/lineage/cut-planner.test.js test/lineage/scc.test.js test/lineage/scc-solver.test.js test/graph/graph-views.test.js test/lineage/dag07-completion.test.js test/lineage/owned-build.test.js test/dataflow/boundary-propagation.test.js test/lineage/boundary-contract.test.js test/lineage/correlation-v2.test.js test/lineage/path-control-evidence.test.js test/lineage/smt-z3-backend.test.js test/cli/dag-commands.test.js",
|
|
93
|
+
"test:lineage": "node --test test/lineage/analysis-completion.test.js 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/seeding-across-calls.test.js test/lineage/boundary-join.test.js test/contracts/code-boundaries.contract.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 test/lineage/runtime-assurance.test.js test/lineage/runtime-edge-states.test.js test/lineage/runtime-explorer-view.test.js test/cli/runtime-explorer-cli.test.js test/cli/runtime-identity-cli.test.js test/cli/runtime-twin-cli.test.js test/lineage/cut-planner.test.js test/lineage/scc.test.js test/lineage/scc-solver.test.js test/graph/graph-views.test.js test/lineage/dag07-completion.test.js test/lineage/owned-build.test.js test/dataflow/boundary-propagation.test.js test/lineage/boundary-contract.test.js test/lineage/correlation-v2.test.js test/lineage/path-control-evidence.test.js test/lineage/smt-z3-backend.test.js test/cli/dag-commands.test.js",
|
|
94
94
|
"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",
|
|
95
95
|
"test:server": "node --test test/server/graph-loader.test.js test/server/security.test.js test/server/routes.test.js test/server/http-server.test.js test/server/cmd-explore.test.js test/server/cmd-dataflow-export.test.js test/server/static-assets.test.js test/server/dataflow-scenario-cli.test.js test/server/dataflow-impact-cli.test.js",
|
|
96
96
|
"test:haskell": "node --test test/haskell/haskell-reachability.test.js test/haskell/haskell-real-code-shapes.test.js test/haskell/haskell-unseen-v5-shapes.test.js test/haskell/haskell-unseen-v4-shapes.test.js test/haskell/haskell-alias-taint.test.js test/haskell/haskell-weak-hash-names.test.js test/haskell/haskell-models-extended.test.js test/haskell/haskell-rules-extended.test.js test/haskell/haskell-injection.test.js test/haskell/haskell-ir.test.js test/haskell/haskell-manifests.test.js test/haskell/haskell-parser.test.js test/haskell/haskell-remediation.test.js test/haskell/haskell-remediation-0190.test.js test/haskell/haskell-remediation-kdf.test.js test/haskell/haskell-remediation-html-text.test.js test/haskell/haskell-remediation-scotty-body.test.js test/haskell/haskell-remediation-entropy.test.js test/haskell/haskell-remediation-text-command.test.js test/haskell/haskell-remediation-path-contain.test.js test/haskell/haskell-remediation-0195-16.test.js test/haskell/haskell-taint-shapes.test.js test/haskell/haskell-real-advisory-shapes.test.js test/haskell/haskell-discovery-shapes.test.js test/haskell/haskell-quasiquote-interp.test.js test/haskell/haskell-record-dot.test.js test/haskell/haskell-global-cell.test.js test/haskell/haskell-syntax-extensions.test.js test/haskell/haskell-rule-precision.test.js test/haskell/haskell-resolved-graph.test.js test/haskell/haskell-sca.test.js test/haskell/haskell-sca-severity.test.js test/haskell/haskell-web-guards.test.js test/haskell/haskell-advisory-feed.test.js test/haskell/haskell-security-rules.test.js test/haskell/haskell-taint.test.js test/haskell/haskell-boundaries.test.js test/haskell/haskell-live-feed-scan.test.js test/haskell/haskell-supply-bounds.test.js test/haskell/haskell-ir-scaling.test.js test/haskell/haskell-boundary-propagation.test.js test/haskell/haskell-generalization.test.js test/haskell/haskell-trust-boundary.test.js test/haskell/haskell-trust-fixed-file.test.js test/haskell/haskell-predictable-random-flow.test.js test/haskell/haskell-comment-invariance.test.js test/haskell/haskell-remediation-classes.test.js test/haskell/haskell-trust-boundary-frameworks.test.js test/haskell/haskell-generic-detectors.test.js",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"verification:replay-example": "node ../scripts/verification-replay-example.mjs",
|
|
134
134
|
"test:lifecycle": "node --test test/ci-hang-protection.test.js test/gate-select.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/gate-warm.test.js test/docs-positioning.test.js test/dist-chunks-tracked.test.js test/ga-program.test.js test/workflow-confinement.test.js test/check-bundle-source.test.js test/ship.test.js test/release-prepare.test.js && node ../scripts/lint-command-descriptions.mjs",
|
|
135
135
|
"test:eval": "node --test test/independent-eval.test.js test/realworld-recall.test.js",
|
|
136
|
-
"test:discovery": "node --test test/discovery-spec-synthesis.test.js 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 test/context-intelligence/build-js.test.js test/context-intelligence/build-python-haskell.test.js test/context-intelligence/hie-adapter.test.js test/context-intelligence/store.test.js test/context-intelligence/review-queue.test.js test/context-intelligence/packer-egress.test.js test/context-intelligence/evaluation.test.js test/context-intelligence/queue-diff.test.js test/context-intelligence/cli.test.js test/context-intelligence/resilience.test.js test/context-intelligence/frameworks.test.js test/context-intelligence/skew-git-rls.test.js test/context-intelligence/premortem.test.js test/context-intelligence/git-diff-candidates.test.js",
|
|
136
|
+
"test:discovery": "node --test test/discovery-spec-synthesis.test.js 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 test/context-intelligence/build-js.test.js test/context-intelligence/build-python-haskell.test.js test/context-intelligence/hie-adapter.test.js test/context-intelligence/store.test.js test/context-intelligence/review-queue.test.js test/context-intelligence/route-mounts.test.js test/context-intelligence/packer-egress.test.js test/context-intelligence/evaluation.test.js test/context-intelligence/queue-diff.test.js test/context-intelligence/cli.test.js test/context-intelligence/resilience.test.js test/context-intelligence/frameworks.test.js test/context-intelligence/skew-git-rls.test.js test/context-intelligence/premortem.test.js test/context-intelligence/git-diff-candidates.test.js",
|
|
137
137
|
"eval:independent": "node ../bench/independent-eval/runner.mjs",
|
|
138
138
|
"eval:independent:gate": "node ../bench/independent-eval/runner.mjs --gate default",
|
|
139
139
|
"smoke": "node bin/agentic-security.js scan test/fixtures/vulnerable-js",
|
|
@@ -23,3 +23,7 @@ See the module table in the architecture doc. Tests: `test/context-intelligence/
|
|
|
23
23
|
## Reuse, do not fork
|
|
24
24
|
|
|
25
25
|
Model calls go through `discovery/llm-invoke.js` and the egress policy. Confirmation, refutation and judging are `discovery/{confirm,disprove,judge}.js`. Grouped intervals come from `posture/evaluation/interval.js`. State paths come from `posture/state-dir.js`.
|
|
26
|
+
|
|
27
|
+
## Router mounts and stale citations (GA-03.2, 0.195.26)
|
|
28
|
+
|
|
29
|
+
`entrypoints.js` composes router mounts: `router.get('/:id')` with `app.use('/api', auth, router)` is the entry point `/api/:id` (`pathTemplate`), with `registeredPath` keeping `/:id` and `mount` recording the chain (root first) and the number of alternatives. A mount is found in the same file, through the import map (`import users from './users.js'`, `const users = require('./users')`) or an inline `require('./users')`, when the target module's `module.exports` / `export default` receiver registers routes or mounts; mounts compose through intermediate routers (depth 4, at most 8 paths); a router mounted at several prefixes is one entry point per prefix; the mount statement's other identifier arguments are inherited middleware scoped to that mount (`viaMount: true`), per chain. A dynamic prefix (`app.use(prefixFor(), router)`) mounts nothing and the route keeps `router-mount-not-resolved`. `review.js`'s `resolveCitation` refuses `stale-context` when the cited lines sit in a segment whose current text no longer hashes to the segment's `spanHash`. Tests: `test/context-intelligence/route-mounts.test.js`.
|
|
@@ -16,6 +16,7 @@ import { hashOf, safeLabel } from './canonical.js';
|
|
|
16
16
|
import { callStatement, inlineBlockSpan, splitArgs } from './spans.js';
|
|
17
17
|
import { dependencyParams, signatureText } from './controls.js';
|
|
18
18
|
import { buildEntrypointInventory } from '../posture/entrypoint-inventory.js';
|
|
19
|
+
import { buildImportMap, resolveViaImports, resolveJsModule } from './imports.js';
|
|
19
20
|
|
|
20
21
|
export const DISPOSITIONS = Object.freeze(['resolved', 'partially_resolved', 'unresolved', 'excluded_by_policy']);
|
|
21
22
|
export const ENTRYPOINT_KINDS = Object.freeze(['http', 'webhook', 'queue', 'cron', 'upload', 'cli']);
|
|
@@ -88,8 +89,11 @@ function collectUses(fileContents) {
|
|
|
88
89
|
let rest = args;
|
|
89
90
|
const q = args[0] && /^(['"`])(.*)\1$/.exec(args[0]);
|
|
90
91
|
if (q) { prefix = q[2]; rest = args.slice(1); }
|
|
92
|
+
// GA-03.2: a first argument that is a call, a template with interpolation or a concatenation is a prefix
|
|
93
|
+
// the scan cannot read; the use still records its middleware, but nothing is mounted under a guessed '/'.
|
|
94
|
+
const prefixDynamic = !q && !!args[0] && (/^[A-Za-z_$][\w$.]*\s*\(/.test(args[0]) && !/^require\s*\(/.test(args[0]) || /\$\{|\+/.test(args[0]));
|
|
91
95
|
const names = rest.map(a => { const id = IDENT_CHAIN.exec(a.replace(/^\[|\]$/g, '')); return id ? { name: id[0], text: a } : { name: null, text: a }; });
|
|
92
|
-
uses.push({ file, line: i + 1, receiver: m[1], prefix, args: names });
|
|
96
|
+
uses.push({ file, line: i + 1, receiver: m[1], prefix, prefixDynamic, args: names });
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
return uses;
|
|
@@ -212,6 +216,107 @@ function resolveHandler(route, ctx) {
|
|
|
212
216
|
return out;
|
|
213
217
|
}
|
|
214
218
|
|
|
219
|
+
// ── Router mounts (GA-03.2, 0.195.26) ──────────────────────────────────────
|
|
220
|
+
//
|
|
221
|
+
// `router.get('/:id', h)` is reachable at `/users/:id` only through `app.use('/users', router)`, and that mount
|
|
222
|
+
// can sit in another file (`app.use('/users', require('./users'))`, `import users from './users.js'`). Before
|
|
223
|
+
// this, every route on a router-looking receiver was `partially_resolved` with `router-mount-not-resolved` and
|
|
224
|
+
// its path was the local one. Now a mount is found when the mounted argument is (a) a receiver with routes in
|
|
225
|
+
// the same file, (b) a name imported from a file whose `module.exports` / `export default` is that file's
|
|
226
|
+
// router receiver, or (c) an inline `require('./x')` of such a file. Mounts compose: `app.use('/api', v1)` and
|
|
227
|
+
// `v1.use('/users', users)` make `/api/users/:id`. A router mounted at several prefixes is reachable at each,
|
|
228
|
+
// so it yields one entry point per prefix (sorted; at most MAX_MOUNT_PATHS). Depth is bounded; a cycle stops.
|
|
229
|
+
// A mount's other identifier arguments (`app.use('/api', auth, router)`) are middleware every mounted route
|
|
230
|
+
// inherits, recorded with the mount's prefix as their scope. What stays unresolved: a router passed through a
|
|
231
|
+
// variable the import map cannot follow, a mount whose prefix is not a string literal, a dynamic
|
|
232
|
+
// `app.use(prefixVar, router)`, and anything registered outside the scanned files.
|
|
233
|
+
const MAX_MOUNT_DEPTH = 4;
|
|
234
|
+
const MAX_MOUNT_PATHS = 8;
|
|
235
|
+
const ROUTE_RECEIVER_RE = /([A-Za-z_$][\w$]*)\.(?:get|post|put|patch|delete|all|options|head|route)\s*\(/;
|
|
236
|
+
const ROUTER_NAME_RE = /^(?:router|routes?|r|api|\w*Router)$/i;
|
|
237
|
+
|
|
238
|
+
function routeReceiver(fileContents, route) {
|
|
239
|
+
if (!JS_FILE.test(route.file)) return null;
|
|
240
|
+
const line = (fileContents[route.file] || '').split('\n')[route.line - 1] || '';
|
|
241
|
+
const m = ROUTE_RECEIVER_RE.exec(line);
|
|
242
|
+
return m ? m[1] : null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/** The receiver a file exports as its module (`module.exports = router`, `export default router`), or null. */
|
|
246
|
+
function exportedReceiver(text) {
|
|
247
|
+
const t = String(text || '');
|
|
248
|
+
const m = /\bmodule\.exports\s*=\s*([A-Za-z_$][\w$]*)\s*;?/.exec(t) || /\bexport\s+default\s+([A-Za-z_$][\w$]*)\s*;?/.exec(t);
|
|
249
|
+
return m ? m[1] : null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function joinMountPath(prefix, routePath) {
|
|
253
|
+
const p = String(prefix || '/').replace(/\/+$/, '');
|
|
254
|
+
const r = String(routePath || '');
|
|
255
|
+
if (!p) return r.startsWith('/') ? r : '/' + r;
|
|
256
|
+
if (!r || r === '/') return p;
|
|
257
|
+
return p + (r.startsWith('/') ? r : '/' + r);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Every mount of a router: key `${file}|${receiver}` -> [{ prefix, file, line, receiver, middleware }], where
|
|
262
|
+
* `receiver` is the receiver the router was mounted ON (so a chain can be followed upward).
|
|
263
|
+
*/
|
|
264
|
+
function buildMountIndex(fileContents, uses, routes) {
|
|
265
|
+
const files = new Set(Object.keys(fileContents));
|
|
266
|
+
const imports = buildImportMap(fileContents);
|
|
267
|
+
const receiversByFile = new Map();
|
|
268
|
+
for (const r of routes) {
|
|
269
|
+
const recv = routeReceiver(fileContents, r);
|
|
270
|
+
if (!recv) continue;
|
|
271
|
+
if (!receiversByFile.has(r.file)) receiversByFile.set(r.file, new Set());
|
|
272
|
+
receiversByFile.get(r.file).add(recv);
|
|
273
|
+
}
|
|
274
|
+
// a receiver that mounts something is a router too (an intermediate `v1.use('/users', users)`)
|
|
275
|
+
for (const u of uses) { if (!receiversByFile.has(u.file)) receiversByFile.set(u.file, new Set()); receiversByFile.get(u.file).add(u.receiver); }
|
|
276
|
+
const index = new Map();
|
|
277
|
+
const add = (file, receiver, mount) => { const k = `${file}|${receiver}`; if (!index.has(k)) index.set(k, []); index.get(k).push(mount); };
|
|
278
|
+
// a module is a router module only when its exported receiver registers routes or mounts in that file
|
|
279
|
+
const isRouter = (file, receiver) => !!receiver && (receiversByFile.get(file) || new Set()).has(receiver);
|
|
280
|
+
for (const u of uses) {
|
|
281
|
+
if (u.prefixDynamic) continue;
|
|
282
|
+
const middleware = [];
|
|
283
|
+
for (const a of u.args) {
|
|
284
|
+
let target = null;
|
|
285
|
+
const req = /^require\(\s*(['"])([^'"]+)\1\s*\)$/.exec(String(a.text || '').trim());
|
|
286
|
+
if (req) {
|
|
287
|
+
const res = resolveJsModule(u.file, req[2], files);
|
|
288
|
+
const recv = res && res.target && files.has(res.target) ? exportedReceiver(fileContents[res.target]) : null;
|
|
289
|
+
if (recv && isRouter(res.target, recv)) target = { file: res.target, receiver: recv };
|
|
290
|
+
} else if (a.name && a.name !== u.receiver && isRouter(u.file, a.name)) {
|
|
291
|
+
target = { file: u.file, receiver: a.name };
|
|
292
|
+
} else if (a.name) {
|
|
293
|
+
const via = resolveViaImports(imports, u.file, a.name);
|
|
294
|
+
const recv = via && via.kind === 'exact-import' && via.targetFile && files.has(via.targetFile) ? exportedReceiver(fileContents[via.targetFile]) : null;
|
|
295
|
+
if (recv && isRouter(via.targetFile, recv)) target = { file: via.targetFile, receiver: recv };
|
|
296
|
+
}
|
|
297
|
+
if (target) add(target.file, target.receiver, { prefix: u.prefix, file: u.file, line: u.line, receiver: u.receiver, middleware: [...middleware] });
|
|
298
|
+
else if (a.name && !req) middleware.push(a.name);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return index;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** The mount chains (root first) through which (file, receiver) is reachable; [] when it is mounted nowhere. */
|
|
305
|
+
function mountChains(index, file, receiver, depth = 0, seen = new Set()) {
|
|
306
|
+
const key = `${file}|${receiver}`;
|
|
307
|
+
const mounts = index.get(key) || [];
|
|
308
|
+
if (!mounts.length || depth >= MAX_MOUNT_DEPTH || seen.has(key)) return [];
|
|
309
|
+
const out = [];
|
|
310
|
+
const next = new Set(seen); next.add(key);
|
|
311
|
+
for (const m of mounts) {
|
|
312
|
+
const parents = mountChains(index, m.file, m.receiver, depth + 1, next);
|
|
313
|
+
if (!parents.length) out.push([m]);
|
|
314
|
+
else for (const pc of parents) out.push([...pc, m]);
|
|
315
|
+
if (out.length >= MAX_MOUNT_PATHS) break;
|
|
316
|
+
}
|
|
317
|
+
return out.slice(0, MAX_MOUNT_PATHS);
|
|
318
|
+
}
|
|
319
|
+
|
|
215
320
|
function pathMatchesPrefix(routePath, prefix) {
|
|
216
321
|
if (prefix === '/' || prefix === '') return true;
|
|
217
322
|
const p = prefix.replace(/\/+$/, '');
|
|
@@ -226,23 +331,24 @@ export async function collectEntrypoints({ fileContents, graph, config = {} }) {
|
|
|
226
331
|
const kinds = new Set(config.entrypointKinds && config.entrypointKinds.length ? config.entrypointKinds : ['http']);
|
|
227
332
|
const idx = symbolIndexes(graph);
|
|
228
333
|
const uses = collectUses(fileContents);
|
|
334
|
+
const routes = (kinds.has('http') || kinds.has('webhook')) ? await collectRoutes(fileContents) : [];
|
|
335
|
+
const mountIndex = buildMountIndex(fileContents, uses, routes);
|
|
229
336
|
const exclude = (config.exclude || []).map(globToRe);
|
|
230
337
|
const cap = Number.isInteger(config.maxEntrypoints) && config.maxEntrypoints > 0 ? config.maxEntrypoints : 5000;
|
|
231
338
|
const ctx = { fileContents, idx, graph };
|
|
232
339
|
const records = [];
|
|
233
340
|
|
|
234
341
|
if (kinds.has('http') || kinds.has('webhook')) {
|
|
235
|
-
for (const route of
|
|
342
|
+
for (const route of routes) {
|
|
236
343
|
const isWebhook = /webhook/i.test(route.path || '');
|
|
237
344
|
if (isWebhook && !kinds.has('webhook') && !kinds.has('http')) continue;
|
|
238
345
|
const h = resolveHandler(route, ctx);
|
|
239
346
|
const reasons = [...h.reasons];
|
|
240
347
|
const middleware = [...h.middleware];
|
|
348
|
+
const receiver = routeReceiver(fileContents, route);
|
|
349
|
+
const chains = receiver ? mountChains(mountIndex, route.file, receiver) : [];
|
|
241
350
|
// inherited middleware registered with `X.use(...)` on the same receiver, earlier in the same file
|
|
242
351
|
if (JS_FILE.test(route.file)) {
|
|
243
|
-
const lines = fileContents[route.file].split('\n');
|
|
244
|
-
const recvM = /([A-Za-z_$][\w$]*)\.(?:get|post|put|patch|delete|all|options|head|route)\s*\(/.exec(lines[route.line - 1] || '');
|
|
245
|
-
const receiver = recvM ? recvM[1] : null;
|
|
246
352
|
for (const u of uses) {
|
|
247
353
|
if (u.file !== route.file || u.line >= route.line || u.receiver !== receiver) continue;
|
|
248
354
|
if (!pathMatchesPrefix(String(route.path || ''), u.prefix)) continue;
|
|
@@ -253,17 +359,35 @@ export async function collectEntrypoints({ fileContents, graph, config = {} }) {
|
|
|
253
359
|
if (!r.symbol) reasons.push(`inherited-middleware-${r.resolution}:${a.name}`);
|
|
254
360
|
}
|
|
255
361
|
}
|
|
256
|
-
if (receiver &&
|
|
257
|
-
reasons.push('router-mount-not-resolved');
|
|
258
|
-
}
|
|
362
|
+
if (receiver && !chains.length && ROUTER_NAME_RE.test(receiver)) reasons.push('router-mount-not-resolved');
|
|
259
363
|
}
|
|
364
|
+
// middleware the mount statements apply to everything mounted under them (`app.use('/api', auth, router)`):
|
|
365
|
+
// per chain, so a router mounted twice inherits each mount's own middleware and not the other's
|
|
366
|
+
const chainMiddleware = (chain) => {
|
|
367
|
+
const mw = []; const why = [];
|
|
368
|
+
for (const hop of chain) {
|
|
369
|
+
for (const name of hop.middleware) {
|
|
370
|
+
const r = resolveName(name, hop.file, idx);
|
|
371
|
+
mw.push({ name, symbolId: r.symbol ? r.symbol.id : null, resolution: r.resolution, line: hop.line, scope: hop.prefix, inherited: true, viaMount: true });
|
|
372
|
+
if (!r.symbol) why.push(`inherited-middleware-${r.resolution}:${name}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
return { mw, why };
|
|
376
|
+
};
|
|
260
377
|
const authScheme = route.webModel
|
|
261
378
|
? { status: route.webModel.auth.status, kind: route.webModel.auth.kind || null, basis: 'haskell-web-model', role: route.webModel.role.status, ownership: route.webModel.ownership || null, idLookups: route.webModel.idLookups || [], csrf: !!route.webModel.csrf }
|
|
262
379
|
: { status: route.hasAuth ? 'authenticated' : 'none', basis: 'route-scan-heuristic', note: 'authentication seen near the registration; says nothing about ownership' };
|
|
380
|
+
const mountsOf = chains.map(chain => ({
|
|
381
|
+
prefix: chain.reduce((acc, hop) => joinMountPath(acc, hop.prefix), '/'),
|
|
382
|
+
chain: chain.map(hop => ({ file: hop.file, line: hop.line, receiver: hop.receiver, prefix: hop.prefix })),
|
|
383
|
+
...chainMiddleware(chain),
|
|
384
|
+
})).sort((a, b) => (a.prefix < b.prefix ? -1 : a.prefix > b.prefix ? 1 : 0));
|
|
263
385
|
const base = {
|
|
264
386
|
kind: isWebhook ? 'webhook' : 'http',
|
|
265
387
|
method: String(route.method || 'GET'),
|
|
266
388
|
pathTemplate: String(route.path || ''),
|
|
389
|
+
registeredPath: String(route.path || ''),
|
|
390
|
+
mount: null,
|
|
267
391
|
framework: route.framework || null,
|
|
268
392
|
language: route.language === 'haskell' ? 'haskell' : (JS_FILE.test(route.file) ? 'javascript' : (route.file.split('.').pop())),
|
|
269
393
|
registrationSite: { file: route.file, line: route.line },
|
|
@@ -276,7 +400,15 @@ export async function collectEntrypoints({ fileContents, graph, config = {} }) {
|
|
|
276
400
|
externalDependencies: [],
|
|
277
401
|
resolutionReasons: [...new Set(reasons)].sort(),
|
|
278
402
|
};
|
|
279
|
-
records.push(base);
|
|
403
|
+
if (!mountsOf.length) { records.push(base); continue; }
|
|
404
|
+
for (const m of mountsOf) {
|
|
405
|
+
const { mw, why, ...mount } = m;
|
|
406
|
+
records.push({
|
|
407
|
+
...base, pathTemplate: joinMountPath(mount.prefix, base.registeredPath), mount: { ...mount, alternatives: mountsOf.length },
|
|
408
|
+
middleware: [...base.middleware.map(x => ({ ...x })), ...mw],
|
|
409
|
+
resolutionReasons: [...new Set([...base.resolutionReasons, ...why])].sort(),
|
|
410
|
+
});
|
|
411
|
+
}
|
|
280
412
|
}
|
|
281
413
|
}
|
|
282
414
|
|
|
@@ -17,7 +17,7 @@ import * as path from 'node:path';
|
|
|
17
17
|
|
|
18
18
|
const JS_EXTS = ['', '.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx', '/index.js', '/index.mjs', '/index.ts', '/index.tsx'];
|
|
19
19
|
|
|
20
|
-
function resolveJsModule(fromFile, source, files) {
|
|
20
|
+
export function resolveJsModule(fromFile, source, files) {
|
|
21
21
|
if (!source.startsWith('.')) return { kind: 'third-party', target: null };
|
|
22
22
|
const base = path.posix.normalize(path.posix.join(path.posix.dirname(fromFile), source));
|
|
23
23
|
for (const ext of JS_EXTS) if (files.has(base + ext)) return { kind: 'repo', target: base + ext };
|
|
@@ -20,7 +20,7 @@ import { redactPayload } from '../egress/redact.js';
|
|
|
20
20
|
import { evaluateEgress } from '../egress/policy.js';
|
|
21
21
|
import { resolveProvider } from '../llm-validator/providers.js';
|
|
22
22
|
import { resolveLlmInvokeWithDecision } from '../discovery/llm-invoke.js';
|
|
23
|
-
import { hashOf, safeLabel, safeRelPath, sha256 } from './canonical.js';
|
|
23
|
+
import { hashOf, safeLabel, safeRelPath, sha256, sliceLines } from './canonical.js';
|
|
24
24
|
import { estimateTokens } from './packer.js';
|
|
25
25
|
import { REVIEW_SCHEMA_VERSION, packRef } from './prompts/packs.js';
|
|
26
26
|
|
|
@@ -249,8 +249,13 @@ export function resolveCitation(c, segments, fileContents) {
|
|
|
249
249
|
if (typeof text !== 'string') return 'file-not-in-snapshot';
|
|
250
250
|
const fileLines = text.split('\n');
|
|
251
251
|
if (c.endLine > fileLines.length) return 'beyond-end-of-file';
|
|
252
|
-
const inside = segments.
|
|
253
|
-
if (!inside) return 'outside-provided-context';
|
|
252
|
+
const inside = segments.filter(s => s.file === c.file && c.startLine >= s.startLine && c.endLine <= s.endLine);
|
|
253
|
+
if (!inside.length) return 'outside-provided-context';
|
|
254
|
+
// GA-03.2 (0.195.26): the citation is bound to the exact lines the bundle was built from. A segment carries the
|
|
255
|
+
// hash of its span at build time; if the snapshot's lines no longer hash to it, the model reviewed text that is
|
|
256
|
+
// not what is on disk now, and the citation is stale rather than evidence. A segment with no recorded hash
|
|
257
|
+
// (a hand-built one) cannot be judged and is not refused for that reason.
|
|
258
|
+
if (inside.every(s => typeof s.spanHash === 'string' && sha256(sliceLines(text, s.startLine, s.endLine)) !== s.spanHash)) return 'stale-context';
|
|
254
259
|
return claimGrounded(c.claim, fileLines.slice(c.startLine - 1, c.endLine).join('\n')) ? null : 'claim-not-grounded-in-cited-lines';
|
|
255
260
|
}
|
|
256
261
|
|
package/src/engine.js
CHANGED
|
@@ -222,6 +222,7 @@ import { createStringMemo } from './util/string-memo.js';
|
|
|
222
222
|
import { collectIrStats, irStatsTarget, writeIrStats } from './ir/ir-stats.js';
|
|
223
223
|
import { runDeepAnalysis } from './dataflow/index.js';
|
|
224
224
|
import { buildLineageGraph } from './lineage/index.js';
|
|
225
|
+
import { getRepoState, worktreeDirtyExcluding } from './posture/provenance/git-evidence.js';
|
|
225
226
|
import { buildLineageGraphOwned, resolveLineageDeadlineMs } from './lineage/owned-build.js';
|
|
226
227
|
import { completionOfGraph, summarizeForHealth as summarizeCompletionForHealth } from './lineage/completion.js';
|
|
227
228
|
// v3 next-gen — Pillars 1, 4, 5, 6, 8, 9.
|
|
@@ -9747,6 +9748,12 @@ function _deterministicFileTimings(timings) {
|
|
|
9747
9748
|
const _lineageDeadlineMs = resolveLineageDeadlineMs();
|
|
9748
9749
|
const { perFile, callGraph } = _lineageDeadlineMs ? {} : (_sharedIR || (_sharedIR = await _buildIR()));
|
|
9749
9750
|
const _lineageT0 = Date.now();
|
|
9751
|
+
let _lineageRepo = null;
|
|
9752
|
+
try {
|
|
9753
|
+
_lineageRepo = scanRoot ? getRepoState(scanRoot) : null;
|
|
9754
|
+
// The scanner's own state directory must not make an unchanged tree read as dirty between two scans.
|
|
9755
|
+
if (_lineageRepo) _lineageRepo = { ..._lineageRepo, dirty: worktreeDirtyExcluding(scanRoot) };
|
|
9756
|
+
} catch { _lineageRepo = null; }
|
|
9750
9757
|
setProgress({ phase: 'Lineage graph', current: 0, total: 0, file: `starting (budget ${Math.round(_lineageBudgetMs / 1000)}s)` });
|
|
9751
9758
|
const _lineageOpts = {
|
|
9752
9759
|
// Live per-function progress from the field-identity driver's own
|
|
@@ -9777,6 +9784,9 @@ function _deterministicFileTimings(timings) {
|
|
|
9777
9784
|
// GA-03.3 (0.195.25): cross-service handoff joins in the lineage
|
|
9778
9785
|
// graph, opt-in. Off, the graph is the one 0.195.24 built.
|
|
9779
9786
|
...(process.env.AGENTIC_SECURITY_LINEAGE_BOUNDARIES === '1' ? { boundaries: { enabled: true } } : {}),
|
|
9787
|
+
// GA-03.7 (0.195.26): the revision the graph is built from, so a
|
|
9788
|
+
// consumer can refuse a graph from another one. Null outside git.
|
|
9789
|
+
...(_lineageRepo && _lineageRepo.head ? { commit: _lineageRepo.head, worktreeDirty: _lineageRepo.dirty } : {}),
|
|
9780
9790
|
};
|
|
9781
9791
|
// DAG-07 R07.7: with AGENTIC_SECURITY_LINEAGE_DEADLINE_MS set, the build runs in an
|
|
9782
9792
|
// owned worker with a watchdog. Unset: the in-process call, exactly as before.
|
package/src/lineage/CLAUDE.md
CHANGED
|
@@ -1353,3 +1353,7 @@ A value leaving one function through a queue publish or a store write and re-ent
|
|
|
1353
1353
|
| `index.js` / `engine.js` (scan) | `AGENTIC_SECURITY_LINEAGE_BOUNDARIES=1` sets `boundaries.enabled`; `index.js` reads `.agentic-security/boundary-contracts.json` (the file `dataflow contracts` reads) once, existence-gated, a malformed file printed and treated as no contracts. `bench/dag/lib/scan-unit.mjs` forces the variable on, as it does deep mode. |
|
|
1354
1354
|
|
|
1355
1355
|
Measured on the multi-service fixture, scan path (`node bench/dag/run.mjs --only=fixture`): flow labels 6 of 6 positive and 3 of 3 negative, where 0.195.24 found 3 of 6; the two site labels (stored value into HTML) stay FN, they need a storage-read source in the taint engine; one reported flow matches no label (`qty` into `orders.total`, a derived numeric write the label set does not list; left unlabelled under the no-relabelling rule). Precision of the join rests on three things stated above: a literal identity on both sides, the ids that really reached the producer site, and outermost-path field mapping. What it does not do: a queue consumed through a callback (`consumer.on('message', cb)`), a store read through an ORM model, a batch send's per-entry bodies, an identity that is a template string or a concatenation, and a producer in another repository (that is `cross-repo-link.js`'s declared edge, unchanged).
|
|
1356
|
+
|
|
1357
|
+
## Frozen artifact contracts and the scanned revision (GA-03.7, 0.195.26)
|
|
1358
|
+
|
|
1359
|
+
`docs/reference/code-boundaries-contract.md` freezes the shape of the signed lineage graph, witness bundles, boundary contracts, context bundles, sink query keys and cut plans, and `test/contracts/code-boundaries.contract.test.js` holds every table in both directions and exercises each rule with a real tamper, a real wrong revision and a real partial analysis (it is the `contractTest` of the `code-boundaries`, `graph-precision` and `context-intelligence` registry rows, so `check-ga-contracts` runs it). Two things changed in code for it: `graph-builder.js` records `graph.scope.revision = { commit, worktreeDirty }` when the caller passes `commit` (the scan passes the repository head from `getRepoState`; a build without one is byte-identical to before), and `server/graph-loader.js`'s `loadSignedGraph(root, { expectRevision })` refuses with `wrong-revision` a graph that records another commit, or none (`dataflow view --expect-revision <sha|HEAD>`). The incremental 3x end-to-end target (GA-03.6) was measured, not met, and the measured reason is under "Open items" in `docs/implementation-status/dag-improvements.md`.
|
|
@@ -602,6 +602,14 @@ export function buildDataFlowGraph(callGraph, opts = {}) {
|
|
|
602
602
|
// module ever passed `undefined`/omitted the key entirely).
|
|
603
603
|
generatedAt: opts.generatedAt ?? '1970-01-01T00:00:00.000Z',
|
|
604
604
|
});
|
|
605
|
+
// GA-03.7 (0.195.26): the revision the graph was built from, when the
|
|
606
|
+
// caller knows it (a scan passes the repository head). A consumer can then
|
|
607
|
+
// refuse a graph built from another revision (`loadSignedGraph`'s
|
|
608
|
+
// `expectRevision`). Absent when no commit was given, so a build without
|
|
609
|
+
// one is byte-identical to before.
|
|
610
|
+
if (typeof opts.commit === 'string' && opts.commit) {
|
|
611
|
+
graph.scope.revision = { commit: opts.commit, worktreeDirty: typeof opts.worktreeDirty === 'boolean' ? opts.worktreeDirty : null };
|
|
612
|
+
}
|
|
605
613
|
|
|
606
614
|
const nodesById = new Map();
|
|
607
615
|
const edgesById = new Map();
|
package/src/lineage/index.js
CHANGED
|
@@ -301,6 +301,8 @@ export function buildLineageGraph(callGraph, opts = {}) {
|
|
|
301
301
|
const built = buildGraphWithCoverage(lineageCallGraph, {
|
|
302
302
|
repository: opts.repository,
|
|
303
303
|
...(boundaries ? { boundaries } : {}),
|
|
304
|
+
// GA-03.7: the scanned revision, recorded in `graph.scope.revision` and in the graph id.
|
|
305
|
+
...(typeof opts.commit === 'string' && opts.commit ? { commit: opts.commit, worktreeDirty: opts.worktreeDirty } : {}),
|
|
304
306
|
generatedAt: opts.deterministic ? undefined : new Date().toISOString(),
|
|
305
307
|
perFile: opts.perFile,
|
|
306
308
|
parseFailures: opts.parseFailures,
|
package/src/posture/CLAUDE.md
CHANGED
|
@@ -906,7 +906,7 @@ are both pre-existing unrelated fields.
|
|
|
906
906
|
| `coordinator.js` | the integration point — budget, cache, per-finding dispatch, the terminal-status guarantee |
|
|
907
907
|
| `git-evidence.js` | the only Git wrapper (`getRepoState`, `blameLine`, `candidateCommitsForLine`, `getBlobAtCommit`, `commitMeta`) |
|
|
908
908
|
| `origin-resolver.js` | which commit introduced a SAST finding |
|
|
909
|
-
| `dag-walk.js` | (M3 §3.1) non-first-parent DAG walk + revert/cherry-pick detection for `--provenance deep` |
|
|
909
|
+
| `dag-walk.js` | (M3 §3.1) non-first-parent DAG walk + revert/cherry-pick detection for `--provenance deep`. Since 0.195.27 (GA-05) `origin-resolver.js` applies the revert and cherry-pick annotation to EVERY origin deep mode resolves, not only the ones the retry loop found, and a `Reapply "..."` subject (git's name for a revert of a revert since 2.43) counts as a revert; the diff inversion still decides. The corpus `bench/provenance-accuracy` holds ten adverse histories (revert, cherry-pick, squash, amend, `git mv`, dirty file, first-parent merge, conflict resolution, transitive lockfile, unreachable provider) and the contract is `docs/reference/finding-provenance-contract.md` |
|
|
910
910
|
| `predicate-replay.js` | was this finding's condition true at commit X (calls `runFullScan` on that commit's blobs) |
|
|
911
911
|
| `sca-origin.js` | which commit moved a directly-declared dependency version into an advisory's vulnerable range |
|
|
912
912
|
| `transitive-sca.js` | (M3 §3.2) the same question for a TRANSITIVE dependency, re-deriving lockfile ancestry per historical commit |
|
|
@@ -918,7 +918,7 @@ are both pre-existing unrelated fields.
|
|
|
918
918
|
| `schema.js` | the status/method/role/confidence enums, `emptyProvenance`, `redactFindingProvenance`, `isProvenanceHealthy` |
|
|
919
919
|
| `validate.js` | shape assertion for tests |
|
|
920
920
|
| `missing-control-resolver.js` | (M3 §3.3, FR-PROV-017) when a previously-observed safeguard disappeared — **wired into `coordinator.js`**: `resolveMissingControlOrigin` calls `resolveMissingControl` for any finding with `missingControlCandidate:true` (today, `sast/rate-limit.js`'s findings) |
|
|
921
|
-
| `providers/config.js`, `providers/github.js`, `providers/gitlab.js` | (M3 §3.4, FR-PROV-022) GitHub/GitLab PR-metadata + CODEOWNERS fetch, config resolved from `.agentic-security/provenance-providers.yml` / token env vars — **wired into `coordinator.js`**: `resolveProviderConfig` is resolved once per scan in `annotateGitProvenance`, and `fetchPRMetadata`/`fetchCodeowners` are called per `complete`-status finding (capped, see `MAX_PROVIDER_ENRICHMENTS_PER_SCAN`), landing on `findingProvenance.providerEnrichment` |
|
|
921
|
+
| `providers/config.js`, `providers/github.js`, `providers/gitlab.js` | (M3 §3.4, FR-PROV-022) GitHub/GitLab PR-metadata + CODEOWNERS fetch, config resolved from `.agentic-security/provenance-providers.yml` / token env vars — **wired into `coordinator.js`**: `resolveProviderConfig` is resolved once per scan in `annotateGitProvenance`, and `fetchPRMetadata`/`fetchCodeowners` are called per `complete`-status finding (capped, see `MAX_PROVIDER_ENRICHMENTS_PER_SCAN`), landing on `findingProvenance.providerEnrichment`. Since 0.195.27 a provider that errs or does not answer returns `{unavailable, reason}` instead of `null`, and the coordinator records a limitation naming the provider and the reason; `null` means "no pull request names this commit" and nothing else |
|
|
922
922
|
| `repo-lineage.js` | (M4 §4.2) loads + fully verifies an operator-declared `.agentic-security/repo-lineage.json` cross-repo link (local clones only, no remote fetch) — used by `origin-resolver.js`'s root-commit case, not a standalone-unwired module |
|
|
923
923
|
| `ai-authorship.js` | (M4 §4.3) extensible AI-authorship verifier registry (`registerAIAuthorshipVerifier`/`resolveAIAuthorship`), defaults to `{status:'unknown', verifier:null}` with nothing registered (today's real state) — wired into `origin-resolver.js`'s `originFrom`, so every SAST `findingOrigin` carries `aiAuthorship`; scoped to SAST only, not direct/transitive SCA origins |
|
|
924
924
|
|
|
@@ -1014,6 +1014,14 @@ Turns a PROVEN finding into a validated detection, hunts local historical logs f
|
|
|
1014
1014
|
* **Redaction before persistence or display** (`redact.js`), on top of the proof store's secret scrubber. Records live under `.agentic-security/dnr/` (registered in `artifact-registry.js`, evidence class, encrypted by policy, tamper-evident).
|
|
1015
1015
|
* **Names:** a detection is not a finding rule. `rule-compiler/` promotes DETECTION rules for the scanner; `dnr/` produces RESPONSE rules for a SIEM, a WAF or a log search. Do not merge them.
|
|
1016
1016
|
|
|
1017
|
+
## Finding-to-rule compiler: `rule-compiler/` (PRD 3, GA-07)
|
|
1018
|
+
|
|
1019
|
+
`cli.js` (`rules synthesize|evaluate|promote|status|rollback|deprecate|cost|regress`), `ir.js`, `corpus.js`, `mutation.js`, `promotion.js`, `proposal.js`, `lifecycle.js`, `store.js`, `regression.js` and `eligibility.js`; contract `docs/reference/rule-compiler-contract.md`, guide `docs/guides/rule-compiler.md`, tests `test/rule-compiler/` and `test/cli/rule-compiler-cli.test.js` (`test:posture`). Since 0.195.27 (GA-07 §2 and §3):
|
|
1020
|
+
|
|
1021
|
+
* **`negative-corpus.js`** is the shared negative corpus shipped with the scanner: safe snippets as strings in a module (no build step, identical everywhere) that `regression.js` puts in front of the shared false-positive corpus, so every evaluation, promotion and regression is held to it. Keep every entry free of the unsafe form; a vulnerable snippet here fails a correct rule. Directories named in `AGENTIC_SECURITY_RULES_FP_CORPUS` are held to as well.
|
|
1022
|
+
* **The ledger is portable.** `store.js` `saveLedger(root, ledger, { authorKey })` writes `ledger.json.author.sig` (Ed25519, the key `promote --sign-key` takes) beside the per-install HMAC signature, and `loadLedger` accepts a ledger whose chain verifies and whose author signature verifies against `AGENTIC_SECURITY_RULES_PUBLIC_KEY` or the rule-pack trust store when the HMAC does not (another install, a CI runner). A project-local key file alone is not trust. The ledger object carries `verifiedBy` (`install-key`, `author-key`, `unsigned-accepted`), stripped before it is written.
|
|
1023
|
+
* **Promotion records what was reviewed.** `--scope` is required; the ledger entry and `promotionEvent.evidence` carry digests of the evaluation, the provenance and both corpus halves (`regression.js` `corpusHash`), and `regress` reports a rule whose corpus changed after the review. `promotion.js` `dependentExamples` refuses an independent example that equals the original, its patch or a generated mutation after whitespace is collapsed.
|
|
1024
|
+
|
|
1017
1025
|
## Eval Lab and the policy router: `evaluation/lab/`, `routing/policy-router.js` (PRD 6)
|
|
1018
1026
|
|
|
1019
1027
|
Measures a deterministic baseline and model arms, and routes tasks from the measurements. Entry points `evaluation/lab/cli.js` (`cmdEval`, `cmdModelsLab`) and `routing/policy-router.js`; guide `docs/guides/eval-lab.md`; tests `test/eval-lab/`, `test/cli/eval-lab-cli.test.js`.
|
|
@@ -436,6 +436,7 @@ export async function runRuleTests(scanRoot, fixtureGlob) {
|
|
|
436
436
|
const files = await globFiles(fixtureGlob);
|
|
437
437
|
console.log(`Loaded ${rules.length} rule(s); testing against ${files.length} file(s).\n`);
|
|
438
438
|
let fired = 0;
|
|
439
|
+
let failures = 0;
|
|
439
440
|
for (const fp of files) {
|
|
440
441
|
let content = '';
|
|
441
442
|
try { content = fs.readFileSync(fp, 'utf8'); } catch { continue; }
|
|
@@ -446,12 +447,16 @@ export async function runRuleTests(scanRoot, fixtureGlob) {
|
|
|
446
447
|
if (findings.length) {
|
|
447
448
|
fired++;
|
|
448
449
|
const verdict = expectClean ? 'FAIL (false positive)' : 'PASS';
|
|
450
|
+
if (expectClean) failures++;
|
|
449
451
|
console.log(` [${verdict}] ${r.id} → ${fp}:${findings[0].line}`);
|
|
450
452
|
} else if (expectFire) {
|
|
453
|
+
failures++;
|
|
451
454
|
console.log(` [FAIL (missed)] ${r.id} → ${fp}`);
|
|
452
455
|
}
|
|
453
456
|
}
|
|
454
457
|
}
|
|
455
|
-
|
|
456
|
-
|
|
458
|
+
// GA-07 §3 (0.195.27): `ok` reports the verdicts, not merely that the run finished. It used to be `true` whatever the fixtures
|
|
459
|
+
// said, so `rule test` could never fail a build; a missed vulnerable fixture or a hit on a clean one is now a failure.
|
|
460
|
+
console.log(`\n${fired} match(es) across ${files.length} file(s)${failures ? `, ${failures} FAILED` : ''}.`);
|
|
461
|
+
return { ok: failures === 0, rules: rules.length, fired, failures };
|
|
457
462
|
}
|
|
@@ -79,7 +79,7 @@ async function loadProgram(root) {
|
|
|
79
79
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
* agentic-security dataflow view [path] [--node <id> [--direction in|out|both] [--relations a,b] [--origins a,b]] [--output <file>]
|
|
82
|
+
* agentic-security dataflow view [path] [--node <id> [--direction in|out|both] [--relations a,b] [--origins a,b]] [--expect-revision <sha|HEAD>] [--output <file>]
|
|
83
83
|
* Read-only over the signed lineage graph. Without --node it reports the view identity, counts, completion and the SCC
|
|
84
84
|
* condensation of the data-flow relation. With --node it lists the neighbours the filter allows.
|
|
85
85
|
*/
|
|
@@ -95,7 +95,18 @@ export async function cmdDataflowView(args) {
|
|
|
95
95
|
if (f.node === undefined && (f.direction || f.relations || f.origins)) { err(`${who}: --direction, --relations and --origins apply to --node.`); return 2; }
|
|
96
96
|
|
|
97
97
|
const { loadSignedGraph } = await import('../server/graph-loader.js');
|
|
98
|
-
|
|
98
|
+
// GA-03.7: `--expect-revision <sha|HEAD>` refuses a graph built from another revision (or from none).
|
|
99
|
+
let expectRevision = null;
|
|
100
|
+
if (f['expect-revision'] !== undefined) {
|
|
101
|
+
if (typeof f['expect-revision'] !== 'string' || !f['expect-revision']) { err(`${who}: --expect-revision needs a commit or HEAD.`); return 2; }
|
|
102
|
+
if (f['expect-revision'] === 'HEAD') {
|
|
103
|
+
const { getRepoState } = await import('./provenance/git-evidence.js');
|
|
104
|
+
const st = getRepoState(root);
|
|
105
|
+
if (!st || !st.head) { err(`${who}: --expect-revision HEAD needs a git repository at ${root}.`); return 2; }
|
|
106
|
+
expectRevision = st.head;
|
|
107
|
+
} else expectRevision = f['expect-revision'];
|
|
108
|
+
}
|
|
109
|
+
const loaded = loadSignedGraph(root, { expectRevision });
|
|
99
110
|
if (!loaded.ok) { err(`${who}: ${loaded.message}`); return 1; }
|
|
100
111
|
const { dataflowView, GraphViewError } = await import('../graph/index.js');
|
|
101
112
|
const { computeScc, verifyScc } = await import('../graph/scc.js');
|
|
@@ -107,6 +118,8 @@ export async function cmdDataflowView(args) {
|
|
|
107
118
|
schema: 'agentic-security/graph-view-report@1',
|
|
108
119
|
maturity: 'preview',
|
|
109
120
|
identity: view.identity,
|
|
121
|
+
revision: loaded.graph.scope && loaded.graph.scope.revision ? loaded.graph.scope.revision : null,
|
|
122
|
+
expectedRevision: expectRevision,
|
|
110
123
|
metadata: view.metadata(),
|
|
111
124
|
viewCompletion: view.completion(),
|
|
112
125
|
note: 'A view is a read-only lens over the signed graph. An absent edge means the model has no such edge, not that the software has none.',
|
|
@@ -101,7 +101,7 @@ const MAX_CONCURRENCY = 4;
|
|
|
101
101
|
// quotient: a 200-finding scan under a 60s global budget divides to 300ms,
|
|
102
102
|
// which is less than a single `git blame`'s own 2s timeout and would starve
|
|
103
103
|
// every finding equally instead of a few. 2s is one blame's worth of work.
|
|
104
|
-
const MIN_PER_FINDING_BUDGET_MS = 2000;
|
|
104
|
+
export const MIN_PER_FINDING_BUDGET_MS = 2000;
|
|
105
105
|
|
|
106
106
|
// FR-PROV-022: an 8s-timeout-capped network call per finding is not
|
|
107
107
|
// automatically bounded by the scan's own deadlineAt -- N findings x up to
|
|
@@ -563,7 +563,11 @@ async function resolveAndCache(finding, ctx, cacheKey, isSca, isTransitiveSca, i
|
|
|
563
563
|
const fetchPRFn = ctx.providerName === 'github' ? fetchPRMetadataGithub : fetchPRMetadataGitlab;
|
|
564
564
|
const fetchCodeownersFn = ctx.providerName === 'github' ? fetchCodeownersGithub : fetchCodeownersGitlab;
|
|
565
565
|
const pr = await fetchPRFn(scanRoot, originResult.findingOrigin.commit, ctx.remoteUrl, ctx.providerConfig);
|
|
566
|
-
if (pr) {
|
|
566
|
+
if (pr && pr.unavailable) {
|
|
567
|
+
// GA-05 (0.195.27): forge metadata that could not be fetched is recorded, never silently absent. The origin,
|
|
568
|
+
// status and confidence above are unaffected: they come from local history, which the provider cannot change.
|
|
569
|
+
provenance.limitations.push(`provider metadata unavailable (${ctx.providerName}: ${pr.reason}); the origin commit is unaffected, only the pull request and code owner enrichment is missing`);
|
|
570
|
+
} else if (pr) {
|
|
567
571
|
const codeowners = await fetchCodeownersFn(scanRoot, ctx.remoteUrl, ctx.providerConfig);
|
|
568
572
|
provenance.providerEnrichment = {
|
|
569
573
|
provider: ctx.providerName,
|