@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.
- package/CHANGELOG.md +46 -0
- package/bin/agentic-security.js +98 -2
- package/dist/1340.index.js +1871 -0
- package/dist/3477.index.js +727 -0
- package/dist/3499.index.js +23 -3
- package/dist/4113.index.js +59 -8
- package/dist/5014.index.js +833 -0
- package/dist/5756.index.js +2 -2
- package/dist/6257.index.js +1 -1
- package/dist/6907.index.js +248 -0
- package/dist/6994.index.js +1 -1
- package/dist/7033.index.js +33 -5
- package/dist/7439.index.js +1822 -0
- package/dist/7838.index.js +38 -2
- package/dist/8798.index.js +1 -1
- package/dist/9207.index.js +5 -0
- package/dist/9560.index.js +2336 -27
- package/dist/957.index.js +1 -1
- package/dist/{1905.index.js → 9999.index.js} +306 -13
- package/dist/agentic-security.mjs +12 -12
- package/dist/agentic-security.mjs.sha256 +1 -1
- package/package.json +39 -7
- package/src/capabilities/CLAUDE.md +114 -0
- package/src/capabilities/address.js +73 -0
- package/src/capabilities/attack-coverage.js +93 -0
- package/src/capabilities/decide.js +256 -0
- package/src/capabilities/delegate.js +69 -0
- package/src/capabilities/egress.js +20 -0
- package/src/capabilities/hook-advice.js +50 -0
- package/src/capabilities/index.js +32 -0
- package/src/capabilities/manifest.js +344 -0
- package/src/capabilities/outbound.js +189 -0
- package/src/capabilities/paths.js +57 -0
- package/src/capabilities/probes.js +211 -0
- package/src/capabilities/proxy.js +182 -0
- package/src/capabilities/reasons.js +67 -0
- package/src/capabilities/receipts.js +356 -0
- package/src/capabilities/records.js +58 -0
- package/src/capabilities/recovery.js +367 -0
- package/src/capabilities/report.js +81 -0
- package/src/capabilities/runner.js +236 -0
- package/src/capabilities/secrets.js +26 -0
- package/src/capabilities/tool-gate.js +119 -0
- package/src/capabilities/tool-registry.js +60 -0
- package/src/dataflow/CLAUDE.md +29 -0
- package/src/dataflow/catalog.js +21 -0
- package/src/dataflow/engine.js +20 -0
- package/src/dataflow/guard-dominance.js +352 -0
- package/src/discovery/CLAUDE.md +18 -0
- package/src/discovery/index.js +43 -1
- package/src/discovery/lenses.js +18 -0
- package/src/discovery/memory.js +7 -5
- package/src/engine.js +80 -15
- package/src/fix/apply-fix-service.js +33 -3
- package/src/integrations/index.js +5 -2
- package/src/ir/CLAUDE.md +14 -0
- package/src/ir/implicit-handler-params.js +74 -0
- package/src/ir/parser-cs.js +20 -0
- package/src/ir/parser-go.js +30 -13
- package/src/ir/parser-java.js +11 -0
- package/src/language/nix-eval-isolation.js +33 -5
- package/src/lineage/CLAUDE.md +31 -0
- package/src/lineage/deployment/adapter-cloud.js +202 -0
- package/src/lineage/deployment/adapter-compose.js +90 -0
- package/src/lineage/deployment/adapter-kit.js +142 -0
- package/src/lineage/deployment/adapter-kubernetes.js +247 -0
- package/src/lineage/deployment/attack-paths.js +443 -0
- package/src/lineage/deployment/boundaries-run.js +223 -0
- package/src/lineage/deployment/boundary-graph.js +567 -0
- package/src/lineage/deployment/cross-repo.js +253 -0
- package/src/lineage/deployment/drift.js +383 -0
- package/src/lineage/deployment/ingest.js +221 -0
- package/src/lineage/deployment/projection.js +244 -0
- package/src/lineage/deployment/trace-correlation.js +541 -0
- package/src/lineage/source-registry.js +19 -0
- package/src/mcp/CLAUDE.md +14 -3
- package/src/mcp/invariant-tools.js +64 -0
- package/src/mcp/portfolio-tools.js +79 -0
- package/src/mcp/redact.js +15 -0
- package/src/mcp/server.js +24 -3
- package/src/mcp/tools.js +30 -5
- package/src/posture/CLAUDE.md +505 -0
- package/src/posture/accuracy-scorecard.js +95 -4
- package/src/posture/assurance/baseline-inventory.js +218 -0
- package/src/posture/assurance/baseline.js +322 -0
- package/src/posture/assurance/bounded-io.js +145 -0
- package/src/posture/assurance/config.js +299 -0
- package/src/posture/assurance/contracts.js +315 -0
- package/src/posture/assurance/identity.js +62 -0
- package/src/posture/assurance/migrations.js +259 -0
- package/src/posture/assurance/rollback.js +214 -0
- package/src/posture/assurance/rollout.js +200 -0
- package/src/posture/assurance/schema-kit.js +111 -0
- package/src/posture/assurance/verification-record.js +258 -0
- package/src/posture/attestation.js +5 -0
- package/src/posture/autopilot.js +28 -1
- package/src/posture/business-logic.js +26 -4
- package/src/posture/evaluation/bakeoff.js +148 -0
- package/src/posture/evaluation/custody.js +200 -0
- package/src/posture/evaluation/deployment-ablation.js +416 -0
- package/src/posture/evaluation/dev-cases.js +65 -0
- package/src/posture/evaluation/economics.js +85 -0
- package/src/posture/evaluation/gates.js +161 -0
- package/src/posture/evaluation/grouping.js +101 -0
- package/src/posture/evaluation/interval.js +132 -0
- package/src/posture/evaluation/invariant-ablation.js +325 -0
- package/src/posture/evaluation/labels.js +200 -0
- package/src/posture/evaluation/protocol.js +308 -0
- package/src/posture/evaluation/release-gate.js +209 -0
- package/src/posture/evaluation/report.js +158 -0
- package/src/posture/evaluation/runner.js +273 -0
- package/src/posture/evaluation/scan-child.js +80 -0
- package/src/posture/evaluation/score.js +174 -0
- package/src/posture/evaluation/synthetic.js +90 -0
- package/src/posture/evaluation/why-missed.js +219 -0
- package/src/posture/evidence-bundle.js +93 -7
- package/src/posture/execution-proof.js +11 -1
- package/src/posture/fix-verify-loop.js +20 -6
- package/src/posture/fix-verify.js +37 -2
- package/src/posture/fleet.js +11 -2
- package/src/posture/invariants/cli.js +95 -0
- package/src/posture/invariants/coverage.js +164 -0
- package/src/posture/invariants/export.js +178 -0
- package/src/posture/invariants/expressions.js +46 -0
- package/src/posture/invariants/lifecycle.js +289 -0
- package/src/posture/invariants/project-input.js +55 -0
- package/src/posture/invariants/repair.js +340 -0
- package/src/posture/invariants/run.js +45 -0
- package/src/posture/invariants/scenarios.js +311 -0
- package/src/posture/invariants/schema.js +167 -0
- package/src/posture/invariants/shrink.js +407 -0
- package/src/posture/invariants/state-assertions.js +165 -0
- package/src/posture/logic-claims.js +12 -0
- package/src/posture/model-routing.js +40 -0
- package/src/posture/oracles/adapters.js +531 -0
- package/src/posture/oracles/conformance.js +276 -0
- package/src/posture/oracles/oracle.js +453 -0
- package/src/posture/oracles/registry.js +76 -0
- package/src/posture/oracles/scenario-classes.js +223 -0
- package/src/posture/portfolio/backend.js +279 -0
- package/src/posture/portfolio/bundle.js +314 -0
- package/src/posture/portfolio/cli.js +142 -0
- package/src/posture/portfolio/manifest.js +263 -0
- package/src/posture/portfolio/progress.js +267 -0
- package/src/posture/portfolio/resume.js +130 -0
- package/src/posture/portfolio/retention.js +207 -0
- package/src/posture/portfolio/scheduler.js +488 -0
- package/src/posture/portfolio/signing.js +155 -0
- package/src/posture/portfolio/wording.js +59 -0
- package/src/posture/portfolio/work-units.js +405 -0
- package/src/posture/replay/replay.js +250 -0
- package/src/posture/routing/adapter.js +140 -0
- package/src/posture/routing/calibration.js +278 -0
- package/src/posture/routing/canary.js +141 -0
- package/src/posture/routing/control.js +35 -0
- package/src/posture/routing/decide.js +211 -0
- package/src/posture/routing/drift.js +137 -0
- package/src/posture/routing/economics.js +185 -0
- package/src/posture/routing/feedback.js +207 -0
- package/src/posture/routing/index.js +31 -0
- package/src/posture/routing/outcomes.js +281 -0
- package/src/posture/routing/promotion.js +291 -0
- package/src/posture/routing/receipts.js +59 -0
- package/src/posture/routing/report.js +142 -0
- package/src/posture/routing/shadow.js +53 -0
- package/src/posture/specification-mining.js +26 -0
- package/src/posture/verification/advisory-state.js +71 -0
- package/src/posture/verification/emit.js +257 -0
- package/src/posture/verification/hypothesis-promotion.js +211 -0
- package/src/posture/verification/patch-negative.js +226 -0
- package/src/posture/verification/patch-promotion.js +113 -0
- package/src/posture/verification/projection.js +183 -0
- package/src/posture/verification/repair-records.js +124 -0
- package/src/posture/verifier.js +16 -0
- package/src/report/index.js +100 -1
- package/src/sandbox/CLAUDE.md +51 -0
- package/src/sandbox/backend-namespace.js +7 -0
- package/src/sandbox/backend-userspace.js +151 -34
- package/src/sandbox/control-probes.js +215 -0
- package/src/sandbox/supervise.js +201 -0
- package/src/sandbox/trust-boundary.js +113 -0
- package/src/sandbox/trust-domains.js +171 -0
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,50 @@
|
|
|
9
9
|
> make the history less accurate, not more.
|
|
10
10
|
|
|
11
11
|
|
|
12
|
+
## 0.163.0 - the rest of the differentiation programme: deployment graph, invariants, capability enforcement, routing, portfolio assurance, evaluation machinery, loop controller and closure
|
|
13
|
+
|
|
14
|
+
This completes the **implementation** of the Agentic Security Differentiation PRD (all 70 requirements are built, each with tests named by criterion id and deliberate-breakage checks). It does **not** close the PRD: the controller's real final verification ends `blocked`, and several gates need data or hosts this repository cannot supply. Read the status section before relying on anything here. Every new execution-capable feature is off by default and gated by the assurance feature flags.
|
|
15
|
+
|
|
16
|
+
**Status, measured by the controller's own final verification (disposable checkout, scripted worker, no model calls, no spend).** All 70 requirements verified on the first pass; the final phase then did not close. The unmet items were the committed bundle being stale against source (rebuilt in this release), the self-scan baseline having drifted (reviewed and rebaselined in this release), a documentation walk-through that raced the controller's exit (made deterministic in this release), the Haskell toolchain step needing `ghc` (not available on the verifying host), and two measured gates that read insufficient-population or unmeasured because **no independently adjudicated real-code population exists**. None of the PRD's real-code accuracy targets (per-language F1 of at least 0.80 and the rest of section 5) has been measured or met; every number produced by this programme is synthetic and labelled so.
|
|
17
|
+
|
|
18
|
+
**Deployment-aware boundaries (X-301 to X-308).** A typed boundary graph built only from local deployment files (Kubernetes, compose, Terraform plan JSON, identity policy), runtime traces with an allowlisted import, cross-repository links bound to exact revisions, deployment-conditioned attack paths, drift between revisions with dependency-aware invalidation, and presentation additive to the existing outputs. New operator command `agentic-security boundaries --from <dir>` (read-only, off by default). On a frozen synthetic paired set the graph removed 3 false positives, added 3 confirmed defects, lost none, and added 1 false positive; only the Kubernetes and compose adapters are claimed as validated.
|
|
19
|
+
|
|
20
|
+
**Executable invariants (X-401 to X-408).** Reviewer-approved tenant and business-state contracts (inferred contracts stay advisory), bounded seed-deterministic stateful scenarios, a durable-effect oracle, shrinking with linked hashes, repair verification against invariants, bounded coverage reporting and a scenario-export tool. Evaluated on synthetic fixtures only.
|
|
21
|
+
|
|
22
|
+
**Capability enforcement (X-501 to X-508).** Task capability manifests enforced at the runner for filesystem, structured commands and outbound network, tool and delegation binding (a child can only receive a subset), operator-signed explicit recovery, hash-chained receipts, and an adversarial corpus. **On macOS the confinement is host-proved, not an advertised enforced backend; Linux is unverified and no process-count cap is claimed on any platform.** A detached grandchild can outlive a task between supervisor sweeps; that known limit is recorded.
|
|
23
|
+
|
|
24
|
+
**Routing (X-601 to X-608).** Outcome records with provenance-backed labels, auditable economics (unknown stays unknown, never zero), calibration that refuses a reliable label below the preregistered minimum, constrained decisions with explanations and bounded fallback, shadow mode and paired replay with the section 5 promotion gate, drift and canary rollback, protected feedback, and a repeatable offline replay (`npm run reproduce:routing`). No cost or quality improvement is claimed.
|
|
25
|
+
|
|
26
|
+
**Portfolio assurance (X-701 to X-708).** A release assurance manifest, offline-verifiable evidence bundles, bounded claims signed with a self-issued local key (never presented as independent certification), durable leased work units with stable ids and dependency-aware resume, a fair bounded scheduler with scoped cancellation, coverage-aware progress views, and retention with legal holds over local and customer-operated shared backends. Consistency is verified for processes sharing one local filesystem only.
|
|
27
|
+
|
|
28
|
+
**Evaluation machinery and engine repairs (QA-001 to QA-008).** A frozen, hash-pinned evaluation protocol that cannot be amended after results exist, custody and leakage controls, layer ablations, grouped-bootstrap intervals, cost accounting, custodian-signed release gates, why-missed diagnostics, and an offline miniature reproduction. Five real engine repairs, with ablations: implicit handler parameters (C# MVC, Spring), Laravel request sources, a static-prefix gate for redirect headers plus Go redirect helpers, Go statement line attribution, and suppression only by a guard that dominates the sink. Measured by the layer-recall bench: taint-attributed entries 122 to 126 of 220 (c# 12 to 13, go 13 to 14, php 13 to 15); corpus raw alerts 326 to 315 with root causes unchanged at 305. The self-scan precision on hand-reviewed targets got slightly worse (hooks 19 to 20, scripts 53 to 54) as the price of the dominance rule.
|
|
29
|
+
|
|
30
|
+
**Loop controller (LOOP-001 to LOOP-004) and closure (REL-001 to REL-003).** The supervised controller now has an independent heartbeat, finite worker stops, controller-issued evidence only, crash recovery, drift freezing, a signed final verification and a resumable report; the assurance profile runs all eleven suites. A closure judge counts a criterion only inside a passing, fresh, controller-issued receipt, and was shown to fail for every kind of unmet criterion and pass only on a synthetic fixture. Release checks bind suite versions and logs to an exact commit; staged rollout and rollback keep earlier evidence.
|
|
31
|
+
|
|
32
|
+
**Documentation.** Twelve guides under `docs/guides` generated from or tested against the code, with runnable local examples, policy cards that keep historical baselines, new synthetic measurements and aspirational targets in separate sections, and a drift check that rejects universal safe, certified or fully-covered claims.
|
|
33
|
+
|
|
34
|
+
**Known issues, not fixed here.** The taint engine still reports a regular expression's `.exec()` on request data as command injection (present since at least 0.161.0). The Linux process-cap assertion remains macOS-only. Several controller limits (subprocess wall time, network limits, the provider envelope) are listed as unenforced in the profile.
|
|
35
|
+
|
|
36
|
+
## 0.162.0 - first slice of the differentiation programme: versioned evidence contracts, an enforced trust boundary, one verification record, trusted oracles, patch-negative verification, and a conformance gate
|
|
37
|
+
|
|
38
|
+
This is the foundation and verification slice of the Agentic Security Differentiation PRD (CORE-001 to 004, CORE-003 trust boundary, LOOP-001, X-201 to X-208). It is **not** the whole programme: the evaluation work (QA-001 to 008, which holds the accuracy gates), the deployment graph, tenant invariants, capability enforcement, model routing and portfolio assurance are unstarted, and no accuracy number is claimed or changed by this release. The new capabilities that execute anything are off by default.
|
|
39
|
+
|
|
40
|
+
**Evidence contracts (CORE-001, 002).** Versioned schemas, validators, stable identities and legacy migration adapters for verification records, observation bindings, capability decisions, routing labels and release evidence. A model verdict can only ever be an inference: `confirmed` needs trusted runtime proof or independent adjudication, and the six states (not-run, unsupported, inconclusive, error, refuted, confirmed) stay distinct through every round trip. A baseline capture tool (`npm run baseline:capture`) records source and bundle digests, dirty paths and an inventory of 18 existing capabilities, each checked against real paths and symbols; it invalidates only the capabilities whose files changed and never modifies source.
|
|
41
|
+
|
|
42
|
+
**Trust boundary (CORE-003).** Four trust domains (target, worker, verifier, signer) with a default-deny policy. `runInBoundary` runs a target only after active probes prove the controls it needs, and returns `blocked` (target never run) otherwise; target output is untrusted and never sets a status. Process trees are killed on timeout or cancel, with a descendant sweep and an orphan check. Signed evidence bundles now carry an `issuance` block that labels them `self-issued-local-key`, never independently certified. **Compatibility:** bundles signed before this release still verify and report no declared trust basis, but a verifier older than this release rejects newly signed bundles (strict unknown-key rule).
|
|
43
|
+
|
|
44
|
+
**One verification record, oracles, replay (X-201 to X-203).** Every verification surface emits the same record. Seven oracle adapters (injection execution, authorization decision, state transition, side-effect reachability, parser/resource behaviour, replay/idempotency, functional regression) each have positive, negative and inconclusive fixtures; an unavailable prerequisite is `unsupported`, never a pass. Replay manifests pin commit, patch, fixture, toolchain, oracle and budgets and reject any that fail validation.
|
|
45
|
+
|
|
46
|
+
**Patch-negative verification and non-taint classes (X-204, X-205).** A fix reaches `verified-fix` only with an exploit-positive original, an exploit-negative patched revision and a passing functional check; the specific incomplete step is recorded otherwise, and promotion requires receipts bound to the exact diff and revision. Tenant authorization, privileged action, workflow order, replay/idempotency and bounded resource exhaustion have executable oracles; taint absence never refutes them.
|
|
47
|
+
|
|
48
|
+
**Parity, gating and conformance (X-206 to X-208).** CLI JSON, MCP, reports and the autopilot response now share one projection (`verificationView`, additive; previous output fields are pinned by fixtures; migration notes in `docs/guides/verification-schema-migration.md`). Advisory hunt hypotheses cannot touch authoritative scan state and are promoted only with a verified receipt and an explicit policy, never on confidence or model agreement. A conformance suite over all oracle adapters runs as a new release check (`verification-conformance-gate`).
|
|
49
|
+
|
|
50
|
+
**Loop registration (LOOP-001).** `assurance-differentiation` profile for the supervised controller: the unmodified importer parses all 70 requirements, 269 weight and 210 criteria. Preflight on the real profile refuses launch, by design, until the other suites have runnable wrappers. Several limits the PRD names (heartbeat setting, subprocess wall time, network limits, provider envelope) are not enforced by the controller and are listed as unenforced.
|
|
51
|
+
|
|
52
|
+
**Known issue, not fixed here (present since at least 0.161.0).** The taint engine reports a regular expression's `.exec()` called on request data as a high-severity command injection (`child_process.exec`), for example `SEMVER.exec(req.query.v)`. This is a false positive that will appear in ordinary JavaScript. Fixing the sink model touches the corpus and recall gates, so it is left for its own change. The self-scan baseline records the two such findings in this repository as reviewed false positives.
|
|
53
|
+
|
|
54
|
+
**Not verified here.** Everything that executes targets was exercised on macOS only; Linux enforcement is declared unverified in every manifest, and on a host where the boundary cannot run the conformance gate reports execution as not-run, never passed. Receipts are unsigned and valid only within the verifier's process. The patch-negative ledger and the promotion audit record are returned, not persisted.
|
|
55
|
+
|
|
12
56
|
## 0.161.0 - the first honest out-of-sample numbers, a ReDoS in the scanner itself fixed, large Haskell projects now finish, multi-file fixes over MCP, auth-guard order proved structurally, sturdier tests and a sharded CI
|
|
13
57
|
|
|
14
58
|
**Measured, and not flattering.** The unseen shape set the engine had been tuned against (v2) was retired and a fresh one (v3: 13 Haskell and 12 Nix families, 300 cases, written without reading the engine's rules) was measured exactly once, with nothing tuned afterwards. On it: Haskell SAST precision 75.0% / recall 50.0% / F1 60.0% (24 TP, 8 FP, 24 FN); Haskell taint 84.6% / 73.3% / 78.6%; Nix config-SAST 100% / 87.9% / 93.5%; Nix config-taint precision 60.0% (all four false positives are duplicate findings on scripts the new set's author wrote with two sinks each, an authoring artefact, not an engine fault). The previous set had scored the Haskell rows 91.7% and 93.3% after being tuned against. All four generalization rows are now below target and the published support tables say so. The misses are concrete and listed in `docs/language-support.md` (for example session cookies set without Secure, missing ownership checks in Yesod and Servant handlers, `randomIO` as a CSRF token, `printf` logging a secret, some HDBC, Scotty `file` and `Network.HTTP.Req` shapes). Closing them is a tuning round that consumes this set; it was deliberately not done here, so the numbers stand as measured. The retired set is kept as a development set (`shape-dev-2`), which now scores 96% to 100%: that is a tuned-on set and is not a generalization number.
|
|
@@ -25,6 +69,8 @@
|
|
|
25
69
|
|
|
26
70
|
**Tests and CI.** The PR `test` job is sharded four ways behind an aggregator that keeps the required check name `test` and fails unless every shard and the bundle check succeed (the speedup is estimated at 4 to 6 minutes against 13 to 14, and is not yet measured). The `--list-shard` output could lose its last lines when stdout was a pipe under load and turned `main` red; it now exits from the write callback. Load-sensitive tests (the sandbox process cap, the 300 ms witness probe, a lock-reaping loop that could spin past its deadline) are made deterministic without weakening what they prove; the Nix permission-model probe works in a git worktree; and the suite runs in one private temp root that it removes, instead of leaving thousands of directories behind. `scripts/ship.mjs` no longer prints a stale failure after a resumed run, prints the exact resume command and per-phase timings, and defaults the gate's temp directory to a fresh one.
|
|
27
71
|
|
|
72
|
+
**Hosted release gate.** The release workflow's closure leg runs only the static closure on the hosted Linux runner, because the trust boundary is unverified there and the execution suites correctly skip; the execution closure is established by `ship.mjs` on the maintainer's host before a tag is created, and the hosted leg states that it does not claim it. The controller tests no longer depend on the untracked PRD documents (they use committed structural fixtures; the comparison with the real documents is the separate `npm run test:loop-real-prd`).
|
|
73
|
+
|
|
28
74
|
**Not verified here.** On the hosted Linux runner a process cap of 1 did not refuse a command (the new refusing-direction assertion in `test/sandbox.test.js` failed there while passing on macOS, and the cause was not established), so that assertion now runs on macOS only; Linux process-cap enforcement is not asserted by any test. The sharded CI job and the aarch64 NixOS changes have not yet run as real CI; the unseen-set misses above are not fixed; the live nixpkgs feed has only been exercised against a fake feed plus a few real requests.
|
|
29
75
|
|
|
30
76
|
## 0.160.0 - a faster, sturdier release path: a parallel hosted gate, a one-command release orchestrator, and fixes for the failing workflow runs
|
package/bin/agentic-security.js
CHANGED
|
@@ -175,6 +175,12 @@ Commands:
|
|
|
175
175
|
scan-baseline --current <f> --previous <f>
|
|
176
176
|
Finding-level diff between two scan JSON outputs.
|
|
177
177
|
Reports added / removed / changed findings.
|
|
178
|
+
boundaries --from <dir> [--findings <last-scan.json>] [--environment <name>] [--out <file>] [--json]
|
|
179
|
+
Build a deployment boundary graph from local configuration
|
|
180
|
+
(and optional sanitized traces) and attach a boundary context
|
|
181
|
+
to each finding of a scan result. Read-only, local files only.
|
|
182
|
+
Off by default: set AGENTIC_SECURITY_ASSURANCE_DEPLOYMENT_BOUNDARIES=1.
|
|
183
|
+
Exit: 0 ok, 1 failed, 2 usage, 3 feature off or blocked.
|
|
178
184
|
explore [path] [--port <n>] [--keep-open]
|
|
179
185
|
Start a local, read-only server over an
|
|
180
186
|
already-scanned lineage graph (run
|
|
@@ -216,6 +222,30 @@ Commands:
|
|
|
216
222
|
federate list [path] [--output <file>]
|
|
217
223
|
List every declared cross-repo link, reporting
|
|
218
224
|
whether each side still resolves.
|
|
225
|
+
invariants export --invariant <file> --fixture <dir> [--ledger <file>] [--commit <sha>] [--seed <n>] [--output <file>]
|
|
226
|
+
Reproducible bounded business-logic scenario package for
|
|
227
|
+
one contract (no fixture source, no secrets, not a proof
|
|
228
|
+
of correctness). Needs the invariant-scenarios feature.
|
|
229
|
+
invariants coverage --invariant <file> | --invariants-dir <dir> [--ledger <file>] [--results <file>] [--json]
|
|
230
|
+
Bounded business coverage: approved vs proposed contracts,
|
|
231
|
+
exercised actors/states/transitions, explicit gaps.
|
|
232
|
+
portfolio progress --store <file> [--budgets <file>] [--findings <file>] [--blocking-severity <s>] [--json]
|
|
233
|
+
Coverage-aware portfolio progress: verified units, blocked/failed/stale
|
|
234
|
+
units, repository coverage, remaining budget, pending human review and
|
|
235
|
+
stale workers. A finished controller is never reported as passed.
|
|
236
|
+
Needs the portfolio-assurance feature.
|
|
237
|
+
portfolio retention plan|apply|verify-log --records <file> --root <dir> [--policy <file>] [--holds <file>] [--store <file>] [--log <file> --actor <name>]
|
|
238
|
+
Retention by class (replay evidence, metadata, model traces, secrets)
|
|
239
|
+
with legal holds; a required current receipt is never deleted and
|
|
240
|
+
every deletion is logged first.
|
|
241
|
+
portfolio backend probe --mode local|shared --dir <dir>
|
|
242
|
+
Is a storage backend usable? An unavailable shared backend is the
|
|
243
|
+
typed blocked state; nothing falls back to a local write.
|
|
244
|
+
portfolio export --store <file> --out <file> | portfolio import --from <file> --mode <m> --dir <d>
|
|
245
|
+
One self-checking, secret-free state file for an air-gapped machine.
|
|
246
|
+
invariants regress <artifact.json>
|
|
247
|
+
Re-execute a verified-repair regression artifact from the
|
|
248
|
+
file alone. Exit 0 passed, 1 failed, 3 not run.
|
|
219
249
|
remediation open [path] --assessment <impact-report.json> --owner <id> --due <YYYY-MM-DD>
|
|
220
250
|
--control <text> --required-evidence <flowId,...>
|
|
221
251
|
[--id <itemId>] [--snapshot <commit>] [--allow-manual-attestation]
|
|
@@ -2290,7 +2320,7 @@ async function cmdVerify(args) {
|
|
|
2290
2320
|
process.env.AGENTIC_SECURITY_VERIFY_LIVE = '1';
|
|
2291
2321
|
process.env.AGENTIC_SECURITY_VERIFY_TARGET = targetFlag;
|
|
2292
2322
|
}
|
|
2293
|
-
const { annotateVerifierVerdicts, verifierCoverageSummary, recordVerifierRun } = await import('../src/posture/verifier.js');
|
|
2323
|
+
const { annotateVerifierVerdicts, verifierCoverageSummary, recordVerifierRun, verifierVerificationRecords } = await import('../src/posture/verifier.js');
|
|
2294
2324
|
const filter = args.flags.finding ? findings.filter(f => f.id === args.flags.finding || f.stableId === args.flags.finding) : findings;
|
|
2295
2325
|
if (!filter.length) {
|
|
2296
2326
|
console.error(`No matching findings (use --finding <id>).`);
|
|
@@ -2319,7 +2349,13 @@ async function cmdVerify(args) {
|
|
|
2319
2349
|
// Adversarial premortem Q1: a durable record that a security assessment of
|
|
2320
2350
|
// findings actually happened, so module:verifier has something real to
|
|
2321
2351
|
// point at (see verifier.js's recordVerifierRun header comment).
|
|
2322
|
-
|
|
2352
|
+
// X-201: one version-1 verification record per verified finding, in the durable run record (never on the findings,
|
|
2353
|
+
// which are written back to last-scan.json below).
|
|
2354
|
+
const { headCommit } = await import('../src/posture/verification/emit.js');
|
|
2355
|
+
recordVerifierRun(scanRoot, {
|
|
2356
|
+
findingCount: filter.length, live: liveFlag, target: targetFlag || null, summary: sum,
|
|
2357
|
+
verificationRecords: verifierVerificationRecords(filter, { commit: headCommit(scanRoot) }),
|
|
2358
|
+
});
|
|
2323
2359
|
if (args.flags.verbose || args.flags.finding) {
|
|
2324
2360
|
for (const f of filter) {
|
|
2325
2361
|
console.log(` ${f.file}:${f.line} ${f.vuln}`);
|
|
@@ -3289,6 +3325,9 @@ async function cmdVerifyAttestation(args) {
|
|
|
3289
3325
|
console.log('');
|
|
3290
3326
|
console.log(` proves: ${bundle.proves}`);
|
|
3291
3327
|
console.log(` does NOT prove: ${bundle.doesNotProve}`);
|
|
3328
|
+
// CORE-003.AC03: who vouches. Informational only; the exit code is unchanged.
|
|
3329
|
+
console.log(` trust basis: ${r.trustBasis}${r.issuer ? ` (issuer ${r.issuer.id})` : ''}`);
|
|
3330
|
+
console.log(` ${r.trustNote}`);
|
|
3292
3331
|
return 0;
|
|
3293
3332
|
}
|
|
3294
3333
|
|
|
@@ -3889,6 +3928,48 @@ Do not suppress anything you are not certain is a false positive. When in doubt,
|
|
|
3889
3928
|
return 0;
|
|
3890
3929
|
}
|
|
3891
3930
|
|
|
3931
|
+
// `agentic-security boundaries --from <dir> [--findings <last-scan.json>] ...` (differentiation PRD, X-308 wiring).
|
|
3932
|
+
// Builds a deployment boundary graph from LOCAL configuration (and optional sanitized traces) and attaches a boundary context to
|
|
3933
|
+
// each finding of an existing scan result. Read-only and local: no network, no scan, no execution of configuration; the only
|
|
3934
|
+
// write is the report file named by --out. Behind the `deployment-boundaries` feature, which is OFF by default.
|
|
3935
|
+
// Exit codes: 0 report produced; 1 failed (invalid or unreadable input, ingest refused, --out refused); 2 usage error;
|
|
3936
|
+
// 3 the feature is disabled, blocked or unsupported on this platform (nothing was read).
|
|
3937
|
+
async function cmdBoundaries(args) {
|
|
3938
|
+
const f = args.flags;
|
|
3939
|
+
const usage = 'Usage: agentic-security boundaries --from <dir> [--findings <last-scan.json>] [--environment <name>] [--repository <name>] [--revision <sha>] [--root <project>] [--out <file>] [--json] [--now <iso>]';
|
|
3940
|
+
if (typeof f.from !== 'string' || !f.from) { console.error(usage); return 2; }
|
|
3941
|
+
for (const k of ['findings', 'environment', 'repository', 'revision', 'out', 'now', 'root']) {
|
|
3942
|
+
if (f[k] !== undefined && (typeof f[k] !== 'string' || !f[k])) { console.error(`agentic-security boundaries: --${k} needs a value\n${usage}`); return 2; }
|
|
3943
|
+
}
|
|
3944
|
+
const scanRoot = path.resolve(f.root || '.');
|
|
3945
|
+
const { resolveAssuranceConfig } = await import('../src/posture/assurance/config.js');
|
|
3946
|
+
const { runBoundaries, renderBoundariesText } = await import('../src/lineage/deployment/boundaries-run.js');
|
|
3947
|
+
const config = resolveAssuranceConfig({ scanRoot });
|
|
3948
|
+
const result = runBoundaries({
|
|
3949
|
+
config, from: path.resolve(f.from), environment: f.environment || 'prod', repository: f.repository || null, revision: f.revision || null,
|
|
3950
|
+
findingsFile: f.findings ? path.resolve(f.findings) : null, verifySignature: _verifyLastScan, now: f.now,
|
|
3951
|
+
});
|
|
3952
|
+
if (result.status === 'disabled' || result.status === 'blocked' || result.status === 'unsupported') {
|
|
3953
|
+
console.error(`agentic-security boundaries: not run (${result.status}): ${result.reason}`);
|
|
3954
|
+
if (result.status === 'disabled') console.error('The deployment-boundaries feature is off by default. Enable it for one run with AGENTIC_SECURITY_ASSURANCE_DEPLOYMENT_BOUNDARIES=1.');
|
|
3955
|
+
return 3;
|
|
3956
|
+
}
|
|
3957
|
+
if (result.status !== 'ok') { console.error(`agentic-security boundaries: ${result.reason}`); return 1; }
|
|
3958
|
+
const report = result.report;
|
|
3959
|
+
const body = f.json ? `${JSON.stringify(report, null, 2)}\n` : renderBoundariesText(report);
|
|
3960
|
+
if (f.out) {
|
|
3961
|
+
const outPath = path.resolve(f.out);
|
|
3962
|
+
try {
|
|
3963
|
+
let st = null;
|
|
3964
|
+
try { st = fs.lstatSync(outPath); } catch { /* absent */ }
|
|
3965
|
+
if (st && !st.isFile()) throw new Error('the output path is a symbolic link or not a regular file');
|
|
3966
|
+
fs.writeFileSync(outPath, body, { mode: 0o644 });
|
|
3967
|
+
} catch (e) { console.error(`agentic-security boundaries: cannot write ${outPath}: ${e.message}`); return 1; }
|
|
3968
|
+
console.log(`agentic-security boundaries: wrote ${outPath}`);
|
|
3969
|
+
} else writeStdout(body);
|
|
3970
|
+
return 0;
|
|
3971
|
+
}
|
|
3972
|
+
|
|
3892
3973
|
// `agentic-security explore [path] [--port <n>] [--keep-open]` — Milestone 3,
|
|
3893
3974
|
// sub-project Server, increment 1. Starts a local, read-only, loopback-only
|
|
3894
3975
|
// HTTP server over an already-built, signed lineage graph
|
|
@@ -7064,6 +7145,7 @@ async function main() {
|
|
|
7064
7145
|
startLspServer();
|
|
7065
7146
|
return;
|
|
7066
7147
|
}
|
|
7148
|
+
case 'boundaries': process.exit(await cmdBoundaries(args));
|
|
7067
7149
|
case 'explore': process.exit(await cmdExplore(args));
|
|
7068
7150
|
case 'dataflow': {
|
|
7069
7151
|
const sub = args._[1];
|
|
@@ -7141,6 +7223,20 @@ async function main() {
|
|
|
7141
7223
|
}
|
|
7142
7224
|
break;
|
|
7143
7225
|
}
|
|
7226
|
+
case 'portfolio': {
|
|
7227
|
+
// X-707, X-708: coverage-aware portfolio progress, evidence retention and offline operation. The logic is in
|
|
7228
|
+
// src/posture/portfolio/cli.js so tests run it without spawning this file. Off unless `portfolio-assurance` is on.
|
|
7229
|
+
const { runPortfolioCommand } = await import('../src/posture/portfolio/cli.js');
|
|
7230
|
+
process.exit(await runPortfolioCommand(args));
|
|
7231
|
+
break;
|
|
7232
|
+
}
|
|
7233
|
+
case 'invariants': {
|
|
7234
|
+
// X-405 to X-407: scenario export, bounded coverage and regression-artifact replay. The logic is in
|
|
7235
|
+
// src/posture/invariants/cli.js so tests run it without spawning this file.
|
|
7236
|
+
const { runInvariantsCommand } = await import('../src/posture/invariants/cli.js');
|
|
7237
|
+
process.exit(await runInvariantsCommand(args));
|
|
7238
|
+
break;
|
|
7239
|
+
}
|
|
7144
7240
|
case 'federate': {
|
|
7145
7241
|
// NOT a `dataflow` subcommand — this writes operator-declared
|
|
7146
7242
|
// config (cross-repo-links.json), never the scanned graph. Same
|