Policy Runtime & Evaluation
Audience: Policy Engine operators, platform engineers, and tooling authors integrating with the runtime. Scope: How SPL policies are compiled, cached, and executed, how results surface via API/CLI/UI, and the runtime’s determinism, observability, and offline guarantees.
Imposed rule: Runtime evaluations must use frozen inputs (SBOM, advisories, VEX, reachability, signals) and emit explain traces plus DSSE/attestation metadata; no live feed calls during evaluation.
This guide describes how stella-dsl@1 policies are compiled, cached, and executed, and how results are surfaced via APIs, the CLI, the Console UI, and observability. For the full authoring-to-archival flow, see the Policy Lifecycle & Approvals guide; for batch and scheduled execution, see Policy Runs & Orchestration.
Lifecycle source boundary — verified at
05534daa6eb60609d9b716f7a7c1db38adb74551(2026-08-31): the registered Engine pack API follows explicit Draft metadata → bundle → Approved metadata → activation. Registry simulation/shadow/review/publication is unavailable. The flow/SLO examples below describe broader run-system requirements, not proof that those Registry capabilities are deployed or enforced. Re-verify with the lifecycle source commands.
1. Components
- Compiler: converts SPL (
stella-dsl@1) into canonical representation and a digest. Compilation is not a coverage run or approval; the Engine persists bundle source for reconstruction. - Engine: deterministic evaluator that consumes IR + inputs (SBOM, advisory, VEX, signals) and emits findings + explain traces.
- Caches:
- IR cache keyed by
policyId/version/IR hash. - Input cursors (SBOM/advisory/VEX snapshots, reachability graphs) to guarantee replay.
- Explain trace cache for recently queried runs (TTL, tenant-scoped).
- IR cache keyed by
- Attestation boundary: a separate verdict/export attestation must be verified through its actual path. The pack compilation signature stub is not DSSE approval or publication evidence.
2. Execution flow
- Resolve active policy version for tenant (or specified version for simulate).
- Load IR from cache; verify hash matches attested value if provided.
- Fetch frozen inputs via cursors: SBOM digest, advisory snapshot id, VEX set, reachability graph hash, signals bundle.
- Evaluate rules in priority order; record explain entries (rule, because, inputs, signals).
- Persist findings, explain traces, and run metadata (
runId,policyVersion, hashes) to storage. - Verify the actual run’s recorded completion/events. Registry shadow events remain a design requirement; a
settings.shadowfield is not evidence of a registered shadow backend.
3. Caching & determinism
- The registered pack path loads its persisted source/bundle. No Registry publish-cache warmup is established by that operation.
- Input cursors are mandatory; if missing, run is blocked (returns
inputs_unfrozen). - Explain trace storage keeps deterministic ordering; capped by tenant quotas.
- Shadow and coverage remain required governance evidence for relevant changes, but the Registry shadow/promotion backend is not registered. Do not credit explicit revision evaluation as shadow acceptance.
4. Lifecycle API boundary
- Use
POST /api/policy/packs/{packId}/revisions/{version}/evaluatewith matchingpackId,versionandsubjectfor explicit bundle evaluation (policy:read). It does not require Active status and is not a shadow run. - Read
GET /policy/capabilities; Registry simulation/shadow defaults are unavailable and compatibility handlers return 501. Do not substitute the former/policies/{id}/simulatedesign path. - For metadata/activation and CLI limitations, use the API reference and CLI guide. Tenant identity is validated identity, not a tenant header override.
5. Observability & SLOs
- Metrics:
policy_runs_total{status},policy_run_duration_seconds,policy_explain_cache_hits,policy_inputs_unfrozen_total,policy_shadow_runs_total. - Logs include
policyId,version,runId,tenant,shadow,input_cursorhashes. - Traces: span per run with events for rule evaluation batches; attributes include counts of rules fired and unknowns encountered.
- SLOs (suggested):
- p95 policy run latency < 2s for simulate, < 10s for full run.
- Error budget: <0.5% failed runs per rolling 7d.
- Explain cache hit rate >80% for repeated queries.
6. Failure modes & handling
- Inputs unfrozen: return 409 with required cursors; emit
policy.inputs_unfrozenevent. - Hash mismatch: IR hash differs from attested; block run and emit
policy.ir_hash_mismatchalert. - Unknown signals: if required signals missing, downgrade to
unknownand optionally setstatus=under_investigation; flag in explain trace. - Exceeded quotas: explain storage or run count caps → 429 with
Retry-After; run not executed.
7. Offline / air-gap
- Frozen-input/no-network replay is a required offline property to prove for the selected run path, not something granted by activation or a CLI flag.
- The registered lifecycle requires its local owner service/store. Offline mode does not implement absent Registry shadow/review/publication or automatically produce signed approval records.
8. Data model (high level)
policy_runs:runId,policyId,version,tenant,shadow,input_cursors,ir_hash,attestation_ref,started_at,completed_at,status,stats(rules fired, explains, unknowns),storage_refs(findings, explains).policy_findings: flattened findings with references to explain entries.policy_explains: rule-level explain traces with inputs, signals, because text.
