This commit is contained in:
StellaOps Bot
2025-11-23 23:40:10 +02:00
parent c13355923f
commit 029002ad05
93 changed files with 2160 additions and 285 deletions

View File

@@ -0,0 +1,114 @@
# 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)
```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
}
}
```
- `schemaVersion` pinned 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 `target` required. Each target binds evidence to scope (derived from PREP docs `2025-11-20-policy-engine-29-002-prep.md`).
### Derived Scope Normalisation
For each target:
- `pathMatch` resolution order: `exact` > `prefix` > `glob`; tie-breaker by higher `confidence`, then lexical `filePath`.
- `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:
```json
{
"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`, then `finding.id`, then `finding.ruleId`. No other ordering allowed.
- Absent optional fields must be omitted (not null).
## Error Envelope
Errors surface as NDJSON line with `type: "error"`:
```json
{ "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,verdict` defined 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.json` and `...-response.ndjson` (to be added when engine implements).
## Compatibility Notes
- Extends PREP docs `2025-11-20-policy-engine-29-002-prep.md` and `2025-11-21-policy-path-scope-29-002-prep.md`; supersedes their draft status.
- Downstream tasks 29-003..40-002 must consume `target` shape above; any change requires bumping `schemaVersion` and updating sprint risks.