5.1 KiB
5.1 KiB
POLICY-ENGINE-29-002 — Streaming Simulation (Path/Scope) Contract
Status: Final · 2025-11-23
Owners: Policy Guild · SBOM Service Guild · Findings Ledger Guild
Working directory: src/Policy/StellaOps.Policy.Engine
Purpose
Define the canonical request/response contract for streaming comparisons between two policy versions with path/scope awareness. Output is explainable per-finding deltas without writes, suitable for Console simulation, Ledger projections, and Advisory AI consumers.
Request Schema (JSON)
{
"schemaVersion": "1.0.0",
"tenant": "acme", // required
"basePolicyRef": "policy://acme/main@sha256:abcd", // required
"candidatePolicyRef": "policy://acme/feature@sha256:ef01", // required
"subject": {
"purl": "pkg:npm/lodash@4.17.21", // or cpe; at least one
"packagePath": "lib/isEqual.js", // optional, POSIX
"osImage": "ghcr.io/acme/app@sha256:..." // optional
},
"targets": [
{
"filePath": "src/lib/isEqual.js", // required, POSIX
"digest": "c1ab...", // optional hex sha256
"treeDigest": "7ff0...", // optional Merkle root
"pathMatch": "prefix", // exact|prefix|glob
"pattern": "src/lib/", // required with pathMatch
"confidence": 0.92, // 0..1
"depthLimit": 3, // optional int
"evidenceHash": "4f9b...", // optional hex (stable over sorted JSON)
"ingestedAt": "2025-11-20T00:00:00Z", // optional ISO-8601 UTC
"connectorId": "excititor-ghsa" // optional string
}
],
"options": {
"sort": "path,finding,verdict", // required enum; default shown
"maxFindings": 1000, // optional int
"includeTrace": true, // include rule trace fragments
"deterministic": true // must be true; rejects false
}
}
schemaVersionpinned to semantic version; breaking changes require bump.- All string comparisons are case-sensitive except
policy://refs, which normalise to lowercase host/path. - At least one
targetrequired. Each target binds evidence to scope (derived from PREP docs2025-11-20-policy-engine-29-002-prep.md).
Derived Scope Normalisation
For each target:
pathMatchresolution order:exact>prefix>glob; tie-breaker by higherconfidence, then lexicalfilePath.evidenceHash= SHA-256 of canonical JSON object with properties sorted ASCII and nulls removed.
Response Schema (streamed NDJSON)
Each line is a JSON object with stable ordering:
{
"tenant": "acme",
"subject": { "purl": "pkg:npm/lodash@4.17.21", "packagePath": "lib/isEqual.js" },
"target": {
"filePath": "src/lib/isEqual.js",
"pattern": "src/lib/",
"pathMatch": "prefix",
"confidence": 0.92,
"evidenceHash": "4f9b..."
},
"finding": {
"id": "GHSA-35jh-r3h4-6jhm",
"ruleId": "policy.rules.javascript.unsafe-merge",
"severity": "high",
"verdict": {
"base": "deny", // allow|deny|warn|info|not-applicable
"candidate": "warn",
"delta": "softened" // added|removed|hardened|softened|unchanged
},
"evidence": {
"locator": { "filePath": "src/lib/isEqual.js", "digest": "c1ab..." },
"provenance": { "ingestedAt": "2025-11-20T00:00:00Z", "connectorId": "excititor-ghsa" }
}
},
"trace": [
{ "step": "match", "rule": "unsafe-merge", "path": "src/lib/isEqual.js" },
{ "step": "decision", "effect": "warn" }
],
"metrics": {
"evalTicks": 128, // deterministic instruction counter
"rulesEvaluated": 12,
"bindings": 3
}
}
- Lines are sorted by
target.filePath, thenfinding.id, thenfinding.ruleId. No other ordering allowed. - Absent optional fields must be omitted (not null).
Error Envelope
Errors surface as NDJSON line with type: "error":
{ "type": "error", "code": "POLICY_29_002_SCHEMA", "message": "target[0].pattern required" }
Codes: POLICY_29_002_SCHEMA, POLICY_29_002_UNSUPPORTED_VERSION, POLICY_29_002_SCOPE_MISMATCH, POLICY_29_002_TOO_MANY_FINDINGS.
Determinism Rules
- No wall-clock, RNG, or network access during evaluation.
- All hashes use SHA-256 over canonical JSON (sorted properties, UTF-8, no insignificant whitespace).
- Stable ordering: request-specified sort or default
path,finding,verdictdefined above. - Trace fragments trimmed to deterministic steps only (no timestamps or hostnames).
Validation & Conformance
- JSON Schema published at
schemas/policy/29-002-streaming-simulation.schema.json(to be mirrored in Offline Kit); engines must validate requests before execution. - CI fixtures:
tests/policy/fixtures/29-002-sample-request.jsonand...-response.ndjson(to be added when engine implements).
Compatibility Notes
- Extends PREP docs
2025-11-20-policy-engine-29-002-prep.mdand2025-11-21-policy-path-scope-29-002-prep.md; supersedes their draft status. - Downstream tasks 29-003..40-002 must consume
targetshape above; any change requires bumpingschemaVersionand updating sprint risks.