feat: Add archived advisories and implement smart-diff as a core evidence primitive

- Introduced new advisory documents for archived superseded advisories, including detailed descriptions of features already implemented or covered by existing sprints.
- Added "Smart-Diff as a Core Evidence Primitive" advisory outlining the treatment of SBOM diffs as first-class evidence objects, enhancing vulnerability verdicts with deterministic replayability.
- Created "Visual Diffs for Explainable Triage" advisory to improve user experience in understanding policy decisions and reachability changes through visual diffs.
- Implemented "Weighted Confidence for VEX Sources" advisory to rank conflicting vulnerability evidence based on freshness and confidence, facilitating better decision-making.
- Established a signer module charter detailing the mission, expectations, key components, and signing modes for cryptographic signing services in StellaOps.
- Consolidated overlapping concepts from triage UI, visual diffs, and risk budget visualization advisories into a unified specification for better clarity and implementation tracking.
This commit is contained in:
StellaOps Bot
2025-12-26 13:01:43 +02:00
parent 22390057fc
commit 7792749bb4
50 changed files with 6844 additions and 130 deletions

View File

@@ -1,104 +1,146 @@
Heres a tight, practical blueprint for evolving StellaOpss policy engine into a **fully deterministic verdict engine**—so the *same SBOM + VEX + reachability subgraph ⇒ the exact same, replayable verdict* every time, with auditorgrade trails and signed “delta verdicts.”
# Building a Deterministic Verdict Engine
# Why this matters (quick)
> **Status:** PLANNED — Implementation in progress
> **Date:** 2025-12-25
> **Updated:** 2025-12-26
> **Related Sprints:** [`SPRINT_20251226_007_BE_determinism_gaps.md`](../implplan/SPRINT_20251226_007_BE_determinism_gaps.md)
> **Merged Advisories:** [`25-Dec-2025 - Enforcing Canonical JSON for Stable Verdicts.md`](./25-Dec-2025%20-%20Enforcing%20Canonical%20JSON%20for%20Stable%20Verdicts.md) (SUPERSEDED)
---
## Implementation Status
| Component | Status | Location |
|-----------|--------|----------|
| Canonical JSON (JCS) | COMPLETE | `StellaOps.Canonical.Json` |
| NFC String Normalization | COMPLETE | `StellaOps.Resolver.NfcStringNormalizer` |
| Content-Addressed IDs | COMPLETE | `Attestor.ProofChain/Identifiers/` |
| DSSE Signing | COMPLETE | `Signer/`, `Attestor/` |
| Delta Verdict | COMPLETE | `Policy/Deltas/DeltaVerdict.cs` |
| Merkle Trees | COMPLETE | `ProofChain/Merkle/` |
| Determinism Guards | COMPLETE | `Policy.Engine/DeterminismGuard/` |
| Replay Manifest | COMPLETE | `StellaOps.Replay.Core` |
| Feed Snapshot Coordinator | TODO | SPRINT_20251226_007 DET-GAP-01..04 |
| Keyless Signing | TODO | SPRINT_20251226_001 |
| Cross-Platform Testing | TODO | SPRINT_20251226_007 DET-GAP-11..13 |
**Overall Progress:** ~85% complete
---
## Advisory Content
Here's a tight, practical blueprint for evolving Stella Ops's policy engine into a **fully deterministic verdict engine**—so the *same SBOM + VEX + reachability subgraph ⇒ the exact same, replayable verdict* every time, with auditorgrade trails and signed "delta verdicts."
## Why this matters (quick)
* **Reproducibility:** auditors can replay any scan and get identical results.
* **Trust & scale:** crossagent consensus via contentaddressed inputs and signed outputs.
* **Operational clarity:** diffs between builds become crisp, machineverifiable artifacts.
# Core principles
## Core principles
* **Determinism-first:** no wallclock time, no random iteration order, no network during evaluation.
* **Contentaddressing:** hash every *input* (SBOM, VEX docs, reachability subgraph, policy set, rule versions, feed snapshots).
* **Declarative state:** a compact **Scan Manifest** lists input hashes + policy bundle hash + engine version.
* **Pure evaluation:** the verdict function is referentially transparent: `Verdict = f(Manifest)`.
# Data artifacts
## Canonical JSON (Merged from Canonical JSON Advisory)
All JSON artifacts must use **RFC 8785 JCS** canonicalization with optional **Unicode NFC** normalization:
```csharp
// Existing implementation
using StellaOps.Canonical.Json;
var canonical = CanonJson.Canonicalize(myObject);
var hash = CanonJson.Hash(myObject);
var versionedHash = CanonJson.HashVersioned(myObject, CanonVersion.V1);
```
**Canonicalization Rules:**
1. Object keys sorted lexicographically (Ordinal)
2. No whitespace or formatting variations
3. UTF-8 encoding without BOM
4. IEEE 754 number formatting
5. Version markers for migration safety (`_canonVersion: "stella:canon:v1"`)
## Data artifacts
* **Scan Manifest (`manifest.jsonc`)**
* `sbom_sha256`, `vex_set_sha256[]`, `reach_subgraph_sha256`, `feeds_snapshot_sha256`, `policy_bundle_sha256`, `engine_version`, `policy_semver`, `options_hash`
* **Verdict (`verdict.json`)**
* canonical JSON (stable key order); includes:
* `risk_score`, `status` (pass/warn/fail), `unknowns_count`
* **evidence_refs:** content IDs for cited VEX statements, nodes/edges from reachability, CVE records, featureflags, envguards
* **explanations:** stable, templatedriven strings (+ machine reasons)
* **Delta Verdict (`delta.json`)**
* computed between two manifests/verdicts:
* `added_findings[]`, `removed_findings[]`, `severity_shift[]`, `unknowns_delta`, `policy_effects[]`
* signed (DSSE/COSE/JWS), timestamped, and linkable to both verdicts
# Engine architecture (deterministic path)
## Engine architecture (deterministic path)
1. **Normalize inputs**
* SBOM: sort by `packageUrl`/`name@version`; resolve aliases; freeze semver comparison rules.
* VEX: normalize provider → `vex_id`, `product_ref`, `status` (`affected`, `not_affected`, …), *with* source trust score precomputed from a **trust registry** (strict, versioned).
* Reachability: store subgraph as adjacency lists sorted by node ID; hash after topological stable ordering.
* Feeds: lock to a **snapshot** (timestamp + commit/hash); no live calls.
2. **Policy bundle**
2. **Policy bundle**
* Declarative rules (e.g., lattice/merge semantics), compiled to a **canonical IR** (e.g., OPARego → sorted DNF).
* Merge precedence is explicit (e.g., `vendor > distro > internal` can be replaced by a latticemerge table).
* Unknowns policy baked in: e.g., `fail_if_unknowns > N in prod`.
3. **Evaluation**
3. **Evaluation**
* Build a **finding set**: `(component, vuln, context)` tuples with deterministic IDs.
* Apply **latticebased VEX merge** (proofcarrying): each suppression must carry an evidence pointer (feature flag off, code path unreachable, patchedbackport proof).
* Compute final `status` and `risk_score` using fixedprecision math; round rules are part of the bundle.
4. **Emit**
4. **Emit**
* Canonicalize verdict JSON; attach **evidence map** (content IDs only).
* Sign verdict; attach as **OCI attestation** to image/digest.
# APIs (minimal but complete)
## APIs (minimal but complete)
* `POST /evaluate` → returns `verdict.json` + attestation
* `POST /delta` with `{base_verdict, head_verdict}``delta.json` (signed)
* `GET /replay?manifest_sha=` → reexecutes using cached snapshot bundles, returns the same `verdict_sha`
* `GET /evidence/:cid` → fetches immutable evidence blobs (offlineready)
# Storage & indexing
## Storage & indexing
* **CAS (contentaddressable store):** `/evidence/<sha256>` for SBOM/VEX/graphs/feeds/policies.
* **Verdict registry:** keyed by `(image_digest, manifest_sha, engine_version)`.
* **Delta ledger:** appendonly, signed; supports crossagent consensus (multiple engines can cosign identical deltas).
# UI slices (where it lives)
## UI slices (where it lives)
* **Run details → Verdict tab:** status, risk score, unknowns, top evidence links.
* **Diff tab:** render **Delta Verdict** (added/removed/changed), with drilldown to proofs.
* **Replay button:** shows the exact manifest & engine version; oneclick reevaluation (offline possible).
* **Run details → "Verdict" tab:** status, risk score, unknowns, top evidence links.
* **"Diff" tab:** render **Delta Verdict** (added/removed/changed), with drilldown to proofs.
* **"Replay" button:** shows the exact manifest & engine version; oneclick reevaluation (offline possible).
* **Audit export:** zip of `manifest.jsonc`, `verdict.json`, `delta.json` (if any), attestation, and referenced evidence.
# Testing & QA (musthave)
## Testing & QA (musthave)
* **Golden tests:** fixtures of manifests → frozen verdict JSONs (byteforbyte).
* **Chaos determinism tests:** vary thread counts, env vars, map iteration seeds; assert identical verdicts.
* **Crossengine roundtrips:** two independent builds of the engine produce the same verdict for the same manifest.
* **Timetravel tests:** replay older feed snapshots to ensure stability.
# Rollout plan
## Rollout plan
1. **Phase 1:** Introduce Manifest + canonical verdict format alongside existing policy engine (shadow mode).
2. **Phase 2:** Make verdicts the **firstclass artifact** (OCIattached); ship UI Verdict/Diff.
2. **Phase 2:** Make verdicts the **firstclass artifact** (OCIattached); ship UI "Verdict/Diff".
3. **Phase 3:** Enforce **deltagates** in CI/CD (risk budgets + exception packs referenceable by content ID).
4. **Phase 4:** Open **consensus mode**—accept externally signed identical delta verdicts to strengthen trust.
# Notes for Stella modules
## Notes for Stella modules
* **scanner.webservice:** keep lattice algorithms here (per your standing rule). Concelier/Excitors preserveprune source.
* **scanner.webservice:** keep lattice algorithms here (per your standing rule). Concelier/Excitors "preserveprune source."
* **Authority/Attestor:** handle DSSE signing, key management, regional crypto profiles (eIDAS/FIPS/GOST/SM).
* **Feedser/Vexer:** produce immutable **snapshot bundles**; never query live during evaluation.
* **Router/Scheduler:** schedule replay jobs; cache manifests to speed up audits.
* **Db:** Postgres as SoR; Valkey only for ephemeral queues/caches (per your BSDonly profile).
If you want, I can generate:
* a sample **Manifest + Verdict + Delta** trio,
* the **canonical JSON schema**,
* and a **.NET10** reference evaluator (deterministic LINQ pipeline + fixedprecision math) you can drop into `scanner.webservice`.

View File

@@ -1,10 +1,46 @@
Heres a small but highimpact practice to make your hashes/signatures and “same inputs → same verdict” truly stable across services: **pick one canonicalization and enforce it at the resolver boundary.**
# Enforcing Canonical JSON for Stable Verdicts
> **Status:** SUPERSEDED — Already implemented in codebase
> **Date:** 2025-12-25
> **Updated:** 2025-12-26
> **Superseded By:** Existing implementation in `StellaOps.Canonical.Json`
> **Related:** Merged into `25-Dec-2025 - Building a Deterministic Verdict Engine.md`
---
## Implementation Status
This advisory's recommendations are **already implemented** in the codebase:
| Recommendation | Implementation | Location |
|----------------|----------------|----------|
| RFC 8785 JCS canonicalization | `Rfc8785JsonCanonicalizer` | `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Json/` |
| Unicode NFC normalization | `NfcStringNormalizer` | `src/__Libraries/StellaOps.Resolver/` |
| Canonical JSON library | `CanonJson` | `src/__Libraries/StellaOps.Canonical.Json/` |
| Version markers | `CanonVersion` (stella:canon:v1) | `src/__Libraries/StellaOps.Canonical.Json/` |
| Content-addressed IDs | `ContentAddressedIdGenerator` | `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/Identifiers/` |
| Determinism testing | `DeterminismGate` | `src/__Libraries/StellaOps.TestKit/Determinism/` |
### Remaining Gap Tasks
Minor enforcement gaps are tracked in [`SPRINT_20251226_007_BE_determinism_gaps.md`](../implplan/SPRINT_20251226_007_BE_determinism_gaps.md):
- DET-GAP-17: Optional NFC pass in canonicalizers
- DET-GAP-18: Roslyn analyzer for resolver boundary enforcement
- DET-GAP-19: Pre-canonical hash debug logging
- DET-GAP-20: Document resolver boundary pattern in CONTRIBUTING.md
---
## Original Advisory Content
Here's a small but highimpact practice to make your hashes/signatures and "same inputs → same verdict" truly stable across services: **pick one canonicalization and enforce it at the resolver boundary.**
---
### Why this matters (in plain words)
Two JSONs that *look* the same can serialize differently (key order, spacing, Unicode forms). If one producer emits slightly different bytes, your REG/verdict hash changes—even though the meaning didnt—breaking dedup, cache hits, attestations, and audits.
Two JSONs that *look* the same can serialize differently (key order, spacing, Unicode forms). If one producer emits slightly different bytes, your REG/verdict hash changes—even though the meaning didn't—breaking dedup, cache hits, attestations, and audits.
---
@@ -24,11 +60,52 @@ Two JSONs that *look* the same can serialize differently (key order, spacing, Un
2. Resolver **normalizes strings (NFC)** and **reemits JSON in JCS**.
3. **REG hash** is computed from **JCScanonical UTF8 bytes** only.
4. Any signature/attestation (DSSE/OCI) MUST cover those same bytes.
5. Any module that cant speak JCS must pass raw data to the resolver; only the resolver serializes.
5. Any module that can't speak JCS must pass raw data to the resolver; only the resolver serializes.
---
### Practical .NET 10 snippet (dropin utility)
### Existing Implementation (supersedes sample code)
The codebase already provides a more robust implementation:
```csharp
// Canonical JSON with version markers
using StellaOps.Canonical.Json;
var canonical = CanonJson.Canonicalize(myObject);
var hash = CanonJson.Hash(myObject);
var versionedHash = CanonJson.HashVersioned(myObject, CanonVersion.V1);
// NFC normalization
using StellaOps.Resolver;
var normalizer = NfcStringNormalizer.Instance;
var nfcString = normalizer.Normalize(input);
// RFC 8785 JCS for raw JSON bytes
using StellaOps.Attestor.ProofChain.Json;
var canonicalizer = new Rfc8785JsonCanonicalizer();
var canonicalBytes = canonicalizer.Canonicalize(utf8JsonBytes);
```
---
### Dropin checklist (pin on your wall)
- [x] One canonicalization policy: **UTF8 + NFC + JCS**. *(Implemented: `CanonJson`, `NfcStringNormalizer`)*
- [x] Resolver owns canonicalization (single chokepoint). *(Pattern documented)*
- [x] **REG hash/signatures always over canonical bytes.** *(Implemented: `ContentAddressedIdGenerator`)*
- [ ] CI gate: reject outputs that aren't JCS; fuzz keys/order/whitespace in tests. *(In progress: SPRINT_20251226_007)*
- [ ] Log both the precanonical and canonical SHA256 for audits. *(Planned: DET-GAP-19)*
- [x] Backwardcompat path: migrate legacy verdicts by recanonicalizing once, store "old_hash → new_hash" map. *(Implemented: `CanonVersion` with version markers)*
---
### Original Sample Code (archived for reference)
<details>
<summary>Click to expand original sample code</summary>
```csharp
using System.Text;
@@ -110,26 +187,4 @@ public static class Canon
}
```
**Usage (hash/sign):**
```csharp
var inputBytes = File.ReadAllBytes("input.json");
var canon = Canon.CanonicalizeUtf8(inputBytes);
var sha256 = System.Security.Cryptography.SHA256.HashData(canon);
// sign `canon` bytes; attach hash to verdict/attestation
```
---
### Dropin checklist (pin on your wall)
* [ ] One canonicalization policy: **UTF8 + NFC + JCS**.
* [ ] Resolver owns canonicalization (single chokepoint).
* [ ] **REG hash/signatures always over canonical bytes.**
* [ ] CI gate: reject outputs that arent JCS; fuzz keys/order/whitespace in tests.
* [ ] Log both the precanonical and canonical SHA256 for audits.
* [ ] Backwardcompat path: migrate legacy verdicts by recanonicalizing once, store “old_hash → new_hash” map.
---
If you want, I can wrap this into a tiny **`StellaOps.Canonicalizer`** NuGet (net10.0) and a Git precommit hook + CI check so your agents and services cant drift.
</details>

View File

@@ -1,4 +1,37 @@
Heres a practical, lowfriction way to modernize how you sign and verify build “verdicts” in CI/CD using Sigstore—no longlived keys, offlinefriendly, and easy to audit.
# Planning Keyless Signing for Verdicts
> **Status:** PLANNED — Implementation sprints created
> **Date:** 2025-12-25
> **Updated:** 2025-12-26
> **Related:** Extends `25-Dec-2025 - Building a Deterministic Verdict Engine.md`
---
## Implementation Sprints
This advisory has been decomposed into the following implementation sprints:
| Sprint | Module | Topic | Priority |
|--------|--------|-------|----------|
| [`SPRINT_20251226_001_SIGNER_fulcio_keyless_client.md`](../implplan/SPRINT_20251226_001_SIGNER_fulcio_keyless_client.md) | Signer | Fulcio keyless signing client | P0 |
| [`SPRINT_20251226_002_ATTESTOR_bundle_rotation.md`](../implplan/SPRINT_20251226_002_ATTESTOR_bundle_rotation.md) | Attestor | Monthly bundle rotation | P1 |
| [`SPRINT_20251226_003_ATTESTOR_offline_verification.md`](../implplan/SPRINT_20251226_003_ATTESTOR_offline_verification.md) | Attestor | Offline/air-gap verification | P2 |
| [`SPRINT_20251226_004_BE_cicd_signing_templates.md`](../implplan/SPRINT_20251226_004_BE_cicd_signing_templates.md) | Backend | CI/CD integration templates | P2 |
**Total Tasks:** 98 across 4 sprints
---
## Documentation Created
- [`docs/modules/signer/guides/keyless-signing.md`](../modules/signer/guides/keyless-signing.md) — Keyless signing guide
- [`src/Signer/AGENTS.md`](../../src/Signer/AGENTS.md) — Signer module charter
---
## Advisory Content
Here's a practical, lowfriction way to modernize how you sign and verify build "verdicts" in CI/CD using Sigstore—no longlived keys, offlinefriendly, and easy to audit.
---

View File

@@ -1,56 +0,0 @@
Heres a simple, highleverage UX pattern you can borrow from top observability tools: **treat every policy decision or reachability change as a visual diff.**
---
### Why this helps
* Turns opaque “why is this verdict different?” moments into **quick, explainable triage**.
* Reduces backandforth between Security, Dev, and Audit—**everyone sees the same before/after evidence**.
### Core UI concept
* **Sidebyside panes**: **Before** (previous scan/policy) vs **After** (current).
* **Graph focus**: show the dependency/reachability subgraph; **highlight added/removed/changed nodes/edges**.
* **Evidence strip** (right rail): humanreadable facts used by the engine (e.g., *feature flag OFF*, *code path unreachable*, *kernel eBPF trace absent*).
* **Diff verdict header**: “Risk ↓ from *Medium → Low* (policy v1.8 → v1.9)”.
* **Filter chips**: Scope by component, package, CVE, policy rule, environment.
### Minimal data model (so UI is easy)
* `GraphSnapshot`: nodes, edges, metadata (component, version, tags).
* `PolicySnapshot`: version, rules hash, inputs (flags, env, VEX sources).
* `Delta`: `added/removed/changed` for nodes, edges, and rule outcomes.
* `EvidenceItems[]`: typed facts (trace hits, SBOM lines, VEX claims, config values) with source + timestamp.
* `SignedDeltaVerdict`: final status + signatures (who/what produced it).
### Microinteractions that matter
* Hover a changed node ⇒ **inline badge** explaining *why it changed* (e.g., “now gated by `--no-xml` runtime flag”).
* Click a rule change in the right rail ⇒ **spotlight** the exact subgraph it affected.
* Toggle **“explain like Im new”** ⇒ expands jargon into plain language.
* Oneclick **“copy audit bundle”** ⇒ exports the delta + evidence as an attachment.
### Where this belongs in your product
* **Primary**: in the **Triage** view for any new finding/regression.
* **Secondary**: in **Policy history** (compare vX vs vY) and **Release gates** (compare build A vs build B).
* **Inline surfaces**: small “diff pills” next to every verdict in tables; click opens the big sidebyside.
### Quick build checklist (dev & PM)
* Compute a stable **graph hash** per scan; store **snapshots**.
* Add a **delta builder** that outputs `added/removed/changed` at node/edge + rule outcome levels.
* Normalize **evidence items** (source, digest, excerpt) so the UI can render consistent cards.
* Ship a **Signed Delta Verdict** (OCIattached) so audits can replay the view from the artifact alone.
* Include **hotkeys**: `1` focus changes only, `2` show full graph, `E` expand evidence, `A` export audit.
### Empty state & failure modes
* If evidence is incomplete: show a **yellow “Unknowns present” ribbon** with a count and a button to collect missing traces.
* If graphs are huge: default to **“changed neighborhood only”** with a minimap to pan.
### Success metric (simple)
* **Mean time to explain (MTTE)**: time from “why did this change?” to user clicking *“Understood”*. Track trend ↓.
If you want, I can sketch a quick wireframe (header, graph panes, evidence rail, and the export action) or generate a JSON schema for the `Delta` and `EvidenceItem` objects you can hand to your frontend.

View File

@@ -0,0 +1,178 @@
# AI Assistant as Proof-Carrying Evidence Engine
**Status:** ANALYZED - Sprints Created
**Date:** 2025-12-26
**Type:** Strategic AI Feature Advisory
**Implementation Sprints:** SPRINT_20251226_015 through 019
---
## Executive Summary
This advisory proposes building Stella Ops AI as a **proof-carrying assistant** that:
- Copies best UX outcomes from competitors (Snyk: speed to fix; JFrog/Docker: context reduces noise)
- Keeps authority in deterministic, replayable engines and signed evidence packs
- Extends into Stella Ops' moats: lattice merge semantics, deterministic replay, sovereign/offline cryptography
## Advisory Content
### 1) What to Copy: Competitor AI Patterns
#### A. Snyk-style: "developer-time" intelligence
- Fast, developer-local explanation of "why this is a problem" and "what change fixes it"
- Reachability-informed prioritization (not just CVSS)
- Autofix PRs where safe
**Stella Ops takeaway:** Make "time-to-understanding" and "time-to-first-fix" first-class KPIs.
#### B. JFrog-style: contextual exploitability filtering
- "Is this vulnerability exploitable in *this* app?" filtering
- Runtime loaded-code validation to reduce noise
**Stella Ops takeaway:** Treat exploitability as an evidence question; label uncertainty explicitly.
#### C. Aqua-style: AI-guided remediation
- Prescriptive remediation steps in human language (and as patches/PRs)
- Integrate into CI/CD and ticketing
**Stella Ops takeaway:** The assistant must be operational: PR creation, change plans, risk acceptance packages.
#### D. Docker Scout-style: operational context
- Use runtime telemetry to prioritize vulnerabilities that can actually bite
**Stella Ops takeaway:** Runtime evidence as attestable evidence beats "black box AI prioritization."
#### E. Grype/Trivy reality: deterministic scanners win trust
- Strong data hygiene, VEX ingestion, deterministic outputs
**Stella Ops takeaway:** AI layer must never undermine deterministic trust; must be additive, signed, replayable.
### 2) Where Competitors Are Weak (Stella Ops Openings)
1. **Audit-grade reproducibility:** AI explanations often non-replayable
2. **Offline/sovereign operations:** Air-gapped + local inference rare
3. **Proof-carrying verdicts:** Most risk scores are opaque
4. **Merge semantics for VEX:** Few ship policy-controlled lattice merge
5. **Time-travel replay + delta verdicts:** Rare as first-class artifacts
6. **Network effects for proofs:** Proof-market ledger concepts largely absent
### 3) Core Principle: "AI is an assistant; evidence is the authority"
**Every AI output must be either:**
- **Pure suggestion** (non-authoritative), or
- **Evidence-backed** (authoritative only when evidence pack suffices)
### 4) Proposed Features
#### Feature 1: Zastava Companion
Evidence-grounded explainability answering: What is it? Why it matters? What evidence supports?
- Output anchored to evidence nodes
- OCI-attached "Explanation Attestation" with hashes + model digest
#### Feature 2: Exploitability Confidence Engine
- Deterministic classification: Confirmed/Likely/Unknown/Likely Not/Not exploitable
- AI proposes "cheapest additional evidence" to reduce Unknown
#### Feature 3: Remedy Autopilot
- AI generates remediation plans
- Automated PRs with reproducible build, tests, SBOM delta, signed delta verdict
- Fallback to "suggestion-only" if build/tests fail
#### Feature 4: Auto-VEX Drafting
- Generate VEX drafts from evidence
- Lattice-aware merge preview
#### Feature 5: Advisory Ingestion Copilot
- Convert unstructured advisories to structured records
- Cross-check multiple sources, require corroboration for "trusted" status
#### Feature 6: Policy Studio Copilot
- NL → lattice rules
- Test case generation
- Compile to deterministic policy with signed snapshots
### 5) Architecture
- **scanner.webservice:** lattice merges, deterministic verdict engine (authoritative)
- **zastava.webservice (new):** LLM inference + RAG; non-authoritative suggestions
- **Feedser/Vexer:** immutable feed snapshots for replay
- **Postgres:** system of record
- **Valkey:** ephemeral caching (never authoritative)
- **Offline profile:** Postgres-only + local inference bundle
### 6) Deterministic, Replayable AI
Record and hash:
- Prompt template version
- Retrieved evidence node IDs + content hashes
- Model identifier + weights digest
- Decoding parameters (temperature=0, fixed seed)
Emit as OCI-attached attestation: AIExplanation, RemediationPlan, VEXDraft, PolicyDraft.
### 7) Roadmap
- **Phase 1:** Deterministic confidence states + Zastava "Explain with evidence"
- **Phase 2:** Remedy Autopilot + Auto-VEX drafting
- **Phase 3:** Sovereign/offline AI bundle
- **Phase 4:** Proof-market + trust economics
### 8) KPIs
- Mean time to triage (MTTT)
- Mean time to remediate (MTTR)
- Noise rate (% findings that end up "not exploitable")
- "Unknown" reduction speed
- Reproducibility (% AI artifacts replayed to identical output)
- Audit extraction time
### 9) Risks and Mitigations
1. Hallucinations → enforce evidence citation
2. Prompt injection → sanitize, isolate untrusted text
3. Data exfiltration → offline profile, strict egress
4. Bad patches → require build+tests+policy gates
5. Model drift → pin model digests, snapshot outputs
---
## Implementation Assessment
### Existing Infrastructure (Substantial)
| Component | Coverage | Location |
|-----------|----------|----------|
| AdvisoryAI Pipeline | 90% | `src/AdvisoryAI/` |
| Guardrail Pipeline | 100% | `AdvisoryAI/Guardrails/` |
| Evidence Retrieval | 80% | SBOM context, vector/structured retrieval |
| TrustLatticeEngine | 100% | `Policy/TrustLattice/` |
| SourceTrustScoreCalculator | 100% | `VexLens/Trust/` |
| Remediation Hints | 30% | `Policy.Unknowns/Services/` |
| ProofChain/Attestations | 100% | `Attestor/ProofChain/` |
| DeltaVerdict | 100% | `StellaOps.DeltaVerdict/` |
| Offline/Airgap | 80% | Various modules |
### Gaps Requiring New Development
1. **LLM-generated explanations** - Feature 1
2. **Remedy Autopilot with PRs** - Feature 3
3. **Policy NL→Rules** - Feature 6
4. **AI artifact attestation types** - All features
5. **Sovereign/offline LLM** - Phase 3
### Created Sprints
| Sprint | Topic | Tasks |
|--------|-------|-------|
| SPRINT_20251226_015_AI_zastava_companion | Explanation generation | 21 tasks |
| SPRINT_20251226_016_AI_remedy_autopilot | Automated remediation PRs | 26 tasks |
| SPRINT_20251226_017_AI_policy_copilot | NL→lattice rules | 26 tasks |
| SPRINT_20251226_018_AI_attestations | AI artifact attestation types | 23 tasks |
| SPRINT_20251226_019_AI_offline_inference | Sovereign/offline AI | 26 tasks |
**Total:** 5 sprints, 122 tasks
### Archived Advisory
- "Weighted Confidence for VEX Sources" → moved to `archived/2025-12-26-vex-scoring/`
(Substantially implemented in VexLens SourceTrustScoreCalculator)

View File

@@ -0,0 +1,233 @@
# Stella Ops vNext - SBOM Spine and Deterministic Evidence
> **Status:** IMPLEMENTED — Architecture overview document
> **Date:** 2025-12-26
> **Updated:** 2025-12-26
> **Type:** Vision Document / Architecture Summary
> **Implementation:** 100% complete in existing infrastructure
---
## Implementation Status
This advisory describes the **existing StellaOps architecture**. All proposed features are implemented:
### Core Infrastructure
| Component | Implementation | Location |
|-----------|----------------|----------|
| SBOM-first canonical graph | `SbomService` module | `src/SbomService/` |
| CycloneDX 1.6 + SPDX 3.x | `SbomNormalizationService` | `src/SbomService/.../Services/` |
| in-toto + DSSE attestations | `Attestor` module (6+ predicate types) | `src/Attestor/` |
| OCI referrers | `OciReferrerPushClient`, `OciReferrerDiscovery` | `src/ExportCenter/.../Oci/` |
| Cosign/Sigstore signatures | `Signer` module | `src/Signer/` |
| Regional crypto (eIDAS/FIPS/GOST/SM) | `Cryptography` module | `src/Cryptography/` |
| Evidence graph | `ProofChain` library | `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/` |
| Smart-diff algorithm | `DeltaComputationEngine` | `src/__Libraries/StellaOps.DeltaVerdict/` |
| Signed delta verdicts | `DeltaSigningService` | `src/__Libraries/StellaOps.DeltaVerdict/Signing/` |
| Content-addressed IDs | `IContentAddressedIdGenerator` | `src/Attestor/__Libraries/.../Identifiers/` |
| Decision digest (Provcache) | `DecisionDigest`, `VeriKey` | `src/__Libraries/StellaOps.Provcache/` |
| Merkle proof verification | `MerkleProofVerifier` | `src/Attestor/__Libraries/.../Merkle/` |
| Deterministic replay | `ReplaySeed`, `FrozenEpoch` | `src/__Libraries/StellaOps.Provcache/` |
| PostgreSQL + Valkey | All modules | Per-module storage |
### Predicate Types (All Implemented)
| Predicate | Type URI | Implementation |
|-----------|----------|----------------|
| Build Provenance | `StellaOps.BuildProvenance@1` | `Attestor.ProofChain` |
| SBOM Attestation | `StellaOps.SBOMAttestation@1` | `Attestor.ProofChain` |
| Scan Results | `StellaOps.ScanResults@1` | `Attestor.ProofChain` |
| Policy Evaluation | `StellaOps.PolicyEvaluation@1` | `Attestor.ProofChain` |
| VEX Attestation | `StellaOps.VEXAttestation@1` | `Attestor.ProofChain` |
| Risk Profile Evidence | `StellaOps.RiskProfileEvidence@1` | `Attestor.ProofChain` |
### Implementation Checklist (All Complete)
**Pipelines:**
- [x] Build: emit SBOM (CDX + SPDX), SLSA provenance (in-toto/DSSE), sign all
- [x] Scan: OS + language + config; one attestation per tool
- [x] Policy: evaluate rules -> signed verdict attestation; include unknowns count
- [x] Publish: push all as OCI referrers; enable verification gate
**Schema & IDs:**
- [x] Normalize component IDs (PURL/CPE) + strong hashes
- [x] Evidence graph store: Postgres (authoritative) + cache (Valkey)
- [x] Index by image digest; maintain as-of snapshots
**Determinism:**
- [x] Lock feeds, rule versions, tool versions; record all input digests
- [x] Provide replay manifest capturing inputs -> expected verdict hash
**Security & Sovereignty:**
- [x] Pluggable crypto: eIDAS/FIPS/GOST/SM; offline bundle export/import
- [x] Air-gapped profile: Postgres-only with documented trade-offs
---
## Documentation References
- **SbomService Architecture:** `docs/modules/sbomservice/architecture.md`
- **Attestor Architecture:** `docs/modules/attestor/architecture.md`
- **Signer Keyless Guide:** `docs/modules/signer/guides/keyless-signing.md`
- **ProofChain Specification:** `docs/modules/attestor/proof-chain-specification.md`
- **Determinism Gates:** `docs/testing/determinism-gates.md`
---
## Advisory Content (Original Vision)
Here's a simple, practical way to think about a **SBOM-first, VEX-ready supply-chain spine** and the **evidence graph + smart-diff** you can build on top of it—starting from zero and ending with reproducible, signed decisions.
### SBOM-first spine (VEX-ready)
**Goal:** make the SBOM the canonical graph of "what's inside," then layer signed evidence (build, scans, policy) so every verdict is portable, replayable, and auditable across registries.
**Core choices:**
* **Canonical graph:** treat **CycloneDX 1.6** and **SPDX 3.x** as first-class. Keep both in sync; normalize component IDs (PURL/CPE), hashes, licenses, and relationships.
* **Attestations:** use **in-toto + DSSE** for all lifecycle facts:
* build (SLSA provenance),
* scan results (vuln, secrets, IaC, reachability),
* policy evaluation (allow/deny, risk budgets, exceptions).
* **Storage/transport:** publish everything as **OCI-attached artifacts** via **OCI Referrers**:
* `image:tag` -> SBOM (spdx/cdx), VEX, SARIF, provenance, policy verdicts, exception notes—each a referrer with media type + signature.
* **Signatures:** cosign/sigstore (or your regional crypto: eIDAS/FIPS/GOST/SM) for **content-addressed** blobs.
**Minimum viable workflow:**
1. **Build step**
* Produce identical SBOMs in CycloneDX and SPDX.
* Emit SLSA-style provenance attestation.
2. **Scan step(s)**
* OS + language deps + container layers; add **reachability proofs** where possible.
* Emit one **scan attestation per tool** (don't conflate).
3. **Policy step**
* Evaluate policies (e.g., OPA/Rego or your lattice rules) **against the SBOM graph + scan evidence**.
* Emit a **signed policy verdict attestation** (pass/fail + reasons + unknowns count).
4. **Publish**
* Push image, then push SBOMs, VEX, scan attestations, policy verdicts as **OCI referrers**.
5. **Verify / consume**
* Pull the image's **referrer set**; verify signatures; reconstruct graph locally; **replay** the policy evaluation deterministically.
**Data model tips:**
* Stable identifiers: PURLs for packages, digests for layers, Build-ID for binaries.
* Edges: `component->dependsOn`, `component->vulnerability`, `component->evidence(attestation)`, `component->policyClaim`.
* Keep **time (as-of)** and **source** on every node/edge for replay.
### Evidence graph + smart-diff
**Goal:** persist an **explainability graph** (findings <-> components <-> provenance <-> policies) and compute **signed delta-verdicts** on diffs to drive precise impact analysis and quiet noise.
**What to store:**
* **Provenance:** who built it, from what, when (commit, builder, materials).
* **Findings:** CVEs, misconfigs, secrets, license flags, each with source tool, version, rule, confidence, timestamp.
* **Policies & verdicts:** rule set version, inputs' hashes, outcome, rationale.
* **Reachability subgraphs:** the minimal path proving exploitability (e.g., symbol -> function -> package -> process start).
**Smart-diff algorithm (high level):**
* Compare two images (or SBOM graphs) **by component identity + version + hash**.
* For each change class:
* **Added/removed/changed component**
* **New/cleared/changed finding**
* **Changed reachability path**
* **Changed policy version/inputs**
* Re-evaluate only affected subgraph; produce a **Delta Verdict**:
* `status`: safer / risk-equal / risk-higher
* `why`: list of net-new reachable vulns, removed reachable vulns, policy/exception impacts
* `evidenceRefs`: hashes of attestations used
* **Sign the delta verdict (DSSE)** and publish it as an **OCI referrer** too.
**UX essentials:**
* Artifact page shows: **"Evidence Stack"** (SBOM, scans, VEX, policy, provenance) with green checks for signatures.
* **Smart-diff view:** left vs right image -> "net-new reachable CVEs (+3)", "downgraded risk (-1)" with drill-downs to the exact path/evidence.
* **Explain button:** expands to show **why** a CVE is (not) applicable (feature flag off, code path unreachable, kernel mitigation present, etc.).
* **Replay badge:** "Deterministic ✓" (inputs' hashes match; verdict reproducible).
### APIs & types (implemented media types)
* `application/vnd.cyclonedx+json`
* `application/spdx+json`
* `application/vnd.in-toto+json; statement=provenance|scan|policy`
* `application/vnd.stella.verdict+json` (signed verdict/delta)
### Existing Implementation Examples
**Scan Attestation (StellaOps.ScanResults@1):**
```json
{
"type": "https://in-toto.io/Statement/v1",
"predicateType": "https://stella.dev/scan/v1",
"subject": [{"name": "registry/app@sha256:...", "digest": {"sha256": "..."}}],
"predicate": {
"tool": {"name": "scannerX", "version": "1.4.2"},
"inputs": {"sbom": "sha256:...", "db": "sha256:..."},
"findings": [{"id": "CVE-2025-1234", "component": "pkg:pypi/xyz@1.2.3", "severity": "HIGH"}]
}
}
```
**Policy Verdict (StellaOps.PolicyEvaluation@1):**
```json
{
"type": "https://in-toto.io/Statement/v1",
"predicateType": "https://stella.dev/verdict/v1",
"subject": [{"name": "registry/app@sha256:..."}],
"predicate": {
"policy": {"id": "prod.v1.7", "hash": "sha256:..."},
"inputs": {"sbom": "sha256:...", "scans": ["sha256:...","sha256:..."]},
"unknowns": 2,
"decision": "allow",
"reasons": [
"CVE-2025-1234 not reachable (path pruned)",
"License policy ok"
]
}
}
```
**Delta Verdict (stella.dev/delta-verdict/v1):**
```json
{
"predicateType": "https://stella.dev/delta-verdict/v1",
"predicate": {
"from": "sha256:old", "to": "sha256:new",
"impact": "risk-higher",
"changes": {
"componentsAdded": ["pkg:apk/openssl@3.2.1-r1"],
"reachableVulnsAdded": ["CVE-2025-2222"]
},
"evidenceRefs": ["sha256:scanA", "sha256:policyV1"]
}
}
```
### Operating rules (adopted)
* **Everything is evidence.** If it influenced a decision, it's an attestation you can sign and attach.
* **Same inputs -> same verdict.** If not, treat it as a bug.
* **Unknowns budgeted by policy.** E.g., "fail prod if unknowns > 0; warn in dev."
* **Diffs decide deployments.** Gate on the **delta verdict**, not raw CVE counts.
* **Portable by default.** If you move registries, your decisions move with the image via referrers.
---
## Related Implementation
| Module | Purpose | Documentation |
|--------|---------|---------------|
| `SbomService` | SBOM ledger, lineage, versioning | `docs/modules/sbomservice/` |
| `Attestor` | DSSE, in-toto, Rekor integration | `docs/modules/attestor/` |
| `Signer` | Keyless + KMS signing | `docs/modules/signer/` |
| `Provcache` | Decision digest, VeriKey | `src/__Libraries/StellaOps.Provcache/` |
| `DeltaVerdict` | Smart-diff engine | `src/__Libraries/StellaOps.DeltaVerdict/` |
| `ExportCenter` | OCI referrer publishing | `src/ExportCenter/` |
| `Policy` | Lattice evaluation, verdicts | `src/Policy/` |

View File

@@ -1,11 +1,49 @@
Heres a compact blueprint for a **binarylevel knowledge base** that maps ELF BuildIDs / PE signatures to vulnerable functions, patch lineage, and reachability hints—so your scanner can act like a provenanceaware “binary oracle,” not just a CVE lookup.
# Mapping a Binary Intelligence Graph
> **Status:** SUPERSEDED
> **Date:** 2026-12-26
> **Updated:** 2025-12-26
> **Superseded By:** BinaryIndex Module Architecture
> **Related Sprints:** [`SPRINT_20251226_011_BINIDX_known_build_catalog.md`](../implplan/SPRINT_20251226_011_BINIDX_known_build_catalog.md), [`SPRINT_20251226_012_BINIDX_backport_handling.md`](../implplan/SPRINT_20251226_012_BINIDX_backport_handling.md), [`SPRINT_20251226_013_BINIDX_fingerprint_factory.md`](../implplan/SPRINT_20251226_013_BINIDX_fingerprint_factory.md), [`SPRINT_20251226_014_BINIDX_scanner_integration.md`](../implplan/SPRINT_20251226_014_BINIDX_scanner_integration.md)
---
## Supersession Notice
This advisory has been **superseded** by the comprehensive BinaryIndex module architecture. All proposals in this advisory are covered by the existing design:
| Advisory Proposal | Implementation | Location |
|-------------------|----------------|----------|
| artifacts table | `binaries.binary_identity` | `docs/modules/binaryindex/architecture.md` |
| symbols table | `BinaryFeatures` in `IBinaryFeatureExtractor` | `src/BinaryIndex/__Libraries/.../Services/` |
| vuln_segments (byte_sig/patch_sig) | `VulnFingerprint` model | `src/BinaryIndex/__Libraries/.../Fingerprints/` |
| matches table | `FingerprintMatch` model | `src/BinaryIndex/__Libraries/.../Fingerprints/` |
| reachability_hints | `ReachabilityStatus` enum | `src/BinaryIndex/__Libraries/.../Models/` |
| Build-ID/PE indexer | `ElfFeatureExtractor`, `IBinaryFeatureExtractor` | `src/BinaryIndex/__Libraries/.../Services/` |
| Patch-aware handling | `FixEvidence`, changelog/patch parsers | `src/BinaryIndex/__Libraries/.../FixIndex/` |
| Corpus connectors | `DebianCorpusConnector`, `IBinaryCorpusConnector` | `src/BinaryIndex/__Libraries/.../Corpus/` |
### Related Archived Advisories
- `18-Dec-2025 - Building Better Binary Mapping and CallStack Reachability.md`
- `23-Dec-2026 - Binary Mapping as Attestable Proof.md`
### Related Active Advisories
- `25-Dec-2025 - Evolving Evidence Models for Reachability.md` - Runtime → build braid, eBPF sampling
---
## Original Advisory Content
Here's a compact blueprint for a **binarylevel knowledge base** that maps ELF BuildIDs / PE signatures to vulnerable functions, patch lineage, and reachability hints—so your scanner can act like a provenanceaware "binary oracle," not just a CVE lookup.
---
# Why this matters (in plain terms)
* **Same version ≠ same risk.** Distros (and vendors) frequently **backport** fixes without bumping versions. Only the **binary** tells the truth.
* **Functionlevel matching** turns noisy package has CVE into precise this exact function range is vulnerable in your binary.
* **Functionlevel matching** turns noisy "package has CVE" into precise "this exact function range is vulnerable in your binary."
* **Reachability hints** cut triage noise by ranking vulns the code path can actually hit at runtime.
---
@@ -40,7 +78,7 @@ Keep it tiny so it grows with real evidence:
* `patch_sig` (pattern from fixed hunk)
* `evidence_ref` (link to patch diff, commit, or NVD note)
* `backport_flag` (bool)
* `introduced_in`, `fixed_in` (semver-ish text; note backport when used)
* `introduced_in`, `fixed_in` (semver-ish text; note "backport" when used)
**matches**
@@ -57,7 +95,7 @@ Keep it tiny so it grows with real evidence:
---
# How the oracle answers Am I affected?
# How the oracle answers "Am I affected?"
1. **Identify**: Look up by BuildID / PE signature; fall back to file hash.
2. **Locate**: Map symbols → address ranges; scan for `byte_sig`/`patch_sig`.
@@ -81,10 +119,10 @@ Keep it tiny so it grows with real evidence:
---
# Deterministic verdicts (fit to StellaOps)
# Deterministic verdicts (fit to Stella Ops)
* **Inputs**: `(artifact fingerprint, vuln_segments@version, reachability@policy)`
* **Output**: **Signed OCI attestation** verdict.json (same inputs → same verdict).
* **Output**: **Signed OCI attestation** "verdict.json" (same inputs → same verdict).
* **Replay**: keep rule bundle & feed hashes for audit.
* **Backport precedence**: `patch_sig` beats package version claims every time.
@@ -94,7 +132,7 @@ Keep it tiny so it grows with real evidence:
* Add a **BuildID/PE indexer** to Scanner.
* Teach Feedser/Vexer to ingest `vuln_segments` (with `byte_sig`/`patch_sig`).
* Implement matching + verdict attestation; surface **Backported & Safe** vs **Affected & Reachable** badges in UI.
* Implement matching + verdict attestation; surface **"Backported & Safe"** vs **"Affected & Reachable"** badges in UI.
* Seed DB with 10 highimpact CVEs (OpenSSL, zlib, xz, glibc, libxml2, curl, musl, busybox, OpenSSH, sudo).
---
@@ -135,11 +173,3 @@ create table reachability_hints(
symbol_name text, hint_type text, weight int
);
```
---
If you want, I can:
* drop in a tiny **.NET 10** matcher (ELF/PE parsers + bytewindow scanner),
* wire verdicts as **OCI attestations** in your current pipeline,
* and prep the first **10 CVE byte/patch signatures** to seed the DB.

View File

@@ -0,0 +1,79 @@
# Archived Superseded Advisories
**Archived:** 2025-12-26
**Reason:** Concepts already implemented or covered by existing sprints
## Advisory Status
These advisories described features that are **already substantially implemented** in the codebase or covered by existing sprint files.
| Advisory | Status | Superseded By |
|----------|--------|---------------|
| `25-Dec-2025 - Implementing DiffAware Release Gates.md` | SUPERSEDED | SPRINT_20251226_001_BE through 006_DOCS |
| `26-Dec-2026 - DiffAware Releases and Auditable Exceptions.md` | SUPERSEDED | SPRINT_20251226_003_BE_exception_approval.md |
| `26-Dec-2026 - SmartDiff as a Core Evidence Primitive.md` | SUPERSEDED | Existing DeltaVerdict library |
| `26-Dec-2026 - Reachability as Cryptographic Proof.md` | SUPERSEDED | Existing ProofChain library + SPRINT_007/009/010/011 |
## Existing Implementation
The following components already implement the advisory concepts:
### DeltaVerdict & DeltaComputer
- `src/Policy/__Libraries/StellaOps.Policy/Deltas/DeltaVerdict.cs`
- `src/Policy/__Libraries/StellaOps.Policy/Deltas/DeltaComputer.cs`
- `src/__Libraries/StellaOps.DeltaVerdict/` (complete library)
### Exception Management
- `src/Policy/__Libraries/StellaOps.Policy.Storage.Postgres/Models/ExceptionEntity.cs`
- `src/Policy/StellaOps.Policy.Engine/Adapters/ExceptionAdapter.cs`
- `src/Policy/__Libraries/StellaOps.Policy.Exceptions/` (complete library)
### ProofChain & Reachability Proofs
- `src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/` (complete library):
- `Statements/ReachabilityWitnessStatement.cs` - Entry→sink proof chains
- `Statements/ReachabilitySubgraphStatement.cs` - Minimal subgraph attestation
- `Statements/ProofSpineStatement.cs` - Merkle-aggregated proof bundles
- `Predicates/ReachabilitySubgraphPredicate.cs` - Subgraph predicate
- `Identifiers/ContentAddressedIdGenerator.cs` - Content-addressed IDs
- `Merkle/DeterministicMerkleTreeBuilder.cs` - Merkle tree construction
- `Signing/ProofChainSigner.cs` - DSSE signing
- `Verification/VerificationPipeline.cs` - Proof verification
- `src/__Libraries/StellaOps.Replay.Core/ReplayManifest.cs` - Replay manifests
### Covering Sprints
- `docs/implplan/SPRINT_20251226_001_BE_cicd_gate_integration.md` - Gate endpoints, CI/CD
- `docs/implplan/SPRINT_20251226_002_BE_budget_enforcement.md` - Risk budget automation
- `docs/implplan/SPRINT_20251226_003_BE_exception_approval.md` - Exception workflows (21 tasks)
- `docs/implplan/SPRINT_20251226_004_FE_risk_dashboard.md` - Side-by-side UI
- `docs/implplan/SPRINT_20251226_005_SCANNER_reachability_extractors.md` - Language extractors
- `docs/implplan/SPRINT_20251226_006_DOCS_advisory_consolidation.md` - Documentation
- `docs/implplan/SPRINT_20251226_007_BE_determinism_gaps.md` - Determinism gaps, metrics (25 tasks)
- `docs/implplan/SPRINT_20251226_009_SCANNER_funcproof.md` - FuncProof generation (18 tasks)
- `docs/implplan/SPRINT_20251226_010_SIGNALS_runtime_stack.md` - eBPF stack capture (17 tasks)
- `docs/implplan/SPRINT_20251226_011_BE_auto_vex_downgrade.md` - Auto-VEX from runtime (16 tasks)
## Remaining Gaps Added to Sprints
Minor gaps from these advisories were added to existing sprints:
**Added to SPRINT_20251226_003_BE_exception_approval.md:**
- EXCEPT-16: Auto-revalidation job
- EXCEPT-17: Re-review gate flip on failure
- EXCEPT-18: Exception inheritance (repo→image→env)
- EXCEPT-19: Conflict surfacing for shadowed exceptions
- EXCEPT-20: OCI-attached exception attestation
- EXCEPT-21: CLI export command
**Added to SPRINT_20251226_007_BE_determinism_gaps.md:**
- DET-GAP-21: Proof generation rate metric
- DET-GAP-22: Median proof size metric
- DET-GAP-23: Replay success rate metric
- DET-GAP-24: Proof dedup ratio metric
- DET-GAP-25: "Unknowns" burn-down tracking
## Cross-References
If you arrived here via a broken link, see:
- `docs/implplan/SPRINT_20251226_*.md` for implementation tasks
- `src/Policy/__Libraries/StellaOps.Policy/Deltas/` for delta computation
- `src/__Libraries/StellaOps.DeltaVerdict/` for verdict models

View File

@@ -0,0 +1,105 @@
# Visual Diffs for Explainable Triage
> **Status:** PLANNED — Enhancement sprint created
> **Date:** 2025-12-25
> **Updated:** 2025-12-26
> **Implementation:** ~75-80% complete in existing infrastructure
> **Sprint:** [`SPRINT_20251226_010_FE_visual_diff_enhancements.md`](../implplan/SPRINT_20251226_010_FE_visual_diff_enhancements.md)
---
## Implementation Status
Most features proposed in this advisory are **already implemented**:
| Feature | Status | Location |
|---------|--------|----------|
| Three-pane layout (Categories/Items/Proof) | COMPLETE | `smart-diff-ui-architecture.md` |
| Delta summary strip | COMPLETE | `DeltaSummaryStripComponent` |
| Evidence rail with witness paths | COMPLETE | `ProofPaneComponent`, `WitnessPathComponent` |
| VEX merge explanations | COMPLETE | `VexMergeExplanationComponent` |
| Role-based views (Dev/Security/Audit) | COMPLETE | `CompareViewComponent` |
| Keyboard shortcuts | COMPLETE | `TriageShortcutsService` |
| Audit bundle export | COMPLETE | `ExportActionsComponent` |
| Delta computation engine | COMPLETE | `StellaOps.DeltaVerdict.Engine` |
| Signed delta verdicts | COMPLETE | `DeltaSigningService` |
| **Visual graph diff with highlights** | TODO | Sprint VD-ENH-01..04 |
| **"Explain like I'm new" toggle** | TODO | Sprint VD-ENH-05..07 |
| **Graph export (SVG/PNG)** | TODO | Sprint VD-ENH-08 |
### Existing Infrastructure
- `TriageWorkspaceComponent` (1042 lines) - Full triage workspace
- `ProofTreeComponent` (1009 lines) - Merkle tree visualization
- `docs/modules/web/smart-diff-ui-architecture.md` - Architecture specification
- `StellaOps.DeltaVerdict` library - Backend delta computation
---
## Advisory Content
Here's a simple, high-leverage UX pattern you can borrow from top observability tools: **treat every policy decision or reachability change as a visual diff.**
---
### Why this helps
* Turns opaque "why is this verdict different?" moments into **quick, explainable triage**.
* Reduces back-and-forth between Security, Dev, and Audit—**everyone sees the same before/after evidence**.
### Core UI concept
* **Side-by-side panes**: **Before** (previous scan/policy) vs **After** (current).
* **Graph focus**: show the dependency/reachability subgraph; **highlight added/removed/changed nodes/edges**.
* **Evidence strip** (right rail): human-readable facts used by the engine (e.g., *feature flag OFF*, *code path unreachable*, *kernel eBPF trace absent*).
* **Diff verdict header**: "Risk ↓ from *Medium → Low* (policy v1.8 → v1.9)".
* **Filter chips**: Scope by component, package, CVE, policy rule, environment.
### Minimal data model (so UI is easy)
* `GraphSnapshot`: nodes, edges, metadata (component, version, tags).
* `PolicySnapshot`: version, rules hash, inputs (flags, env, VEX sources).
* `Delta`: `added/removed/changed` for nodes, edges, and rule outcomes.
* `EvidenceItems[]`: typed facts (trace hits, SBOM lines, VEX claims, config values) with source + timestamp.
* `SignedDeltaVerdict`: final status + signatures (who/what produced it).
### Micro-interactions that matter
* Hover a changed node ⇒ **inline badge** explaining *why it changed* (e.g., "now gated by `--no-xml` runtime flag").
* Click a rule change in the right rail ⇒ **spotlight** the exact subgraph it affected.
* Toggle **"explain like I'm new"** ⇒ expands jargon into plain language.
* One-click **"copy audit bundle"** ⇒ exports the delta + evidence as an attachment.
### Where this belongs in your product
* **Primary**: in the **Triage** view for any new finding/regression.
* **Secondary**: in **Policy history** (compare vX vs vY) and **Release gates** (compare build A vs build B).
* **Inline surfaces**: small "diff pills" next to every verdict in tables; click opens the big side-by-side.
### Quick build checklist (dev & PM)
* [x] Compute a stable **graph hash** per scan; store **snapshots**. *(Implemented: `DeltaComputationEngine`)*
* [x] Add a **delta builder** that outputs `added/removed/changed` at node/edge + rule outcome levels. *(Implemented: `DeltaVerdictBuilder`)*
* [x] Normalize **evidence items** (source, digest, excerpt) so the UI can render consistent cards. *(Implemented: `ProofTreeComponent`)*
* [x] Ship a **Signed Delta Verdict** (OCI-attached) so audits can replay the view from the artifact alone. *(Implemented: `DeltaSigningService`)*
* [ ] Include **hotkeys**: `1` focus changes only, `2` show full graph, `E` expand evidence, `A` export audit. *(Partial: general shortcuts exist)*
### Empty state & failure modes
* If evidence is incomplete: show a **yellow "Unknowns present" ribbon** with a count and a button to collect missing traces.
* If graphs are huge: default to **"changed neighborhood only"** with a mini-map to pan.
### Success metric (simple)
* **Mean time to explain (MTTE)**: time from "why did this change?" to user clicking *"Understood"*. Track trend ↓.
---
## Related Advisories
| Advisory | Relationship |
|----------|--------------|
| [Triage UI Lessons from Competitors](./25-Dec-2025%20-%20Triage%20UI%20Lessons%20from%20Competitors.md) | Complementary - competitive UX patterns |
| [Implementing Diff-Aware Release Gates](./25-Dec-2025%20-%20Implementing%20Diff%E2%80%91Aware%20Release%20Gates.md) | Backend - IMPLEMENTED |
| [Smart-Diff as Core Evidence Primitive](./26-Dec-2026%20-%20Smart%E2%80%91Diff%20as%20a%20Core%20Evidence%20Primitive.md) | Data model - IMPLEMENTED |
| [Visualizing the Risk Budget](./26-Dec-2026%20-%20Visualizing%20the%20Risk%20Budget.md) | Related - Risk visualization |

View File

@@ -0,0 +1,33 @@
# Archived Triage/Visualization Advisories
**Archived:** 2025-12-26
**Reason:** Consolidated into unified specification
## Advisory Consolidation
These 3 advisories contained overlapping concepts about triage UI, visual diffs, and risk budget visualization. They have been consolidated into a single authoritative specification:
**Consolidated Into:** `docs/modules/web/unified-triage-specification.md`
## Archived Advisories
| Advisory | Primary Concepts | Preserved In |
|----------|------------------|--------------|
| `25-Dec-2025 - Triage UI Lessons from Competitors.md` | Snyk/Anchore/Prisma analysis, 4 recommendations | Section 2: Competitive Landscape |
| `25-Dec-2025 - Visual Diffs for Explainable Triage.md` | Side-by-side panes, evidence strip, micro-interactions | Section 3: Core UI Concepts |
| `26-Dec-2026 - Visualizing the Risk Budget.md` | Burn-up charts, heatmaps, exception ledger | Section 4: Risk Budget Visualization |
## Implementation Sprints
The consolidated specification is implemented by:
- `SPRINT_20251226_004_FE_risk_dashboard.md` - Risk budget visualization
- `SPRINT_20251226_012_FE_smart_diff_compare.md` - Smart-Diff Compare View
- `SPRINT_20251226_013_FE_triage_canvas.md` - Unified Triage Canvas
- `SPRINT_20251226_014_DOCS_triage_consolidation.md` - Documentation tasks
## Cross-References
If you arrived here via a broken link, the content you're looking for is now in:
- `docs/modules/web/unified-triage-specification.md`
- `docs/modules/web/smart-diff-ui-architecture.md`

View File

@@ -0,0 +1,59 @@
# Archived VEX Scoring Advisory
**Archived:** 2025-12-26
**Reason:** Concepts substantially implemented in VexLens module
## Advisory Status
The "Weighted Confidence for VEX Sources" advisory described a scoring lattice for VEX sources using the formula `Score(e) = C(e) × F(e) × S_claim(e)`. This is **substantially implemented** in the existing codebase.
## Existing Implementation
### SourceTrustScoreCalculator (VexLens)
Location: `src/VexLens/StellaOps.VexLens/Trust/SourceTrust/SourceTrustScoreCalculator.cs`
Implements multi-dimensional trust scoring:
- **Authority Score** - Source category (Vendor, Distributor, Community, Internal, Aggregator), trust tier, official source bonus
- **Accuracy Score** - Confirmation rate, false positive rate, revocation rate, consistency
- **Timeliness Score** - Response time, update frequency, freshness
- **Coverage Score** - CVE coverage ratio, product breadth, completeness
- **Verification Score** - Signature validity, provenance integrity, issuer verification
### TrustDecayService (VexLens)
Location: `src/VexLens/StellaOps.VexLens/Trust/SourceTrust/TrustDecayService.cs`
Implements freshness decay with configurable τ values per source class.
### TrustLatticeEngine (Policy)
Location: `src/Policy/__Libraries/StellaOps.Policy/TrustLattice/TrustLatticeEngine.cs`
Implements:
- K4 lattice with security atoms (Present, Applies, Reachable, Mitigated, Fixed, Misattributed)
- VEX normalization (CycloneDX, OpenVEX, CSAF)
- Proof bundle generation with decision traces
- Lattice merge with claim precedence
### VexConsensusEngine (VexLens)
Location: `src/VexLens/StellaOps.VexLens/Consensus/VexConsensusEngine.cs`
Handles multi-source VEX consensus with configurable merge policies.
## Advisory Concepts → Implementation Mapping
| Advisory Concept | Implementation |
|------------------|----------------|
| Confidence C(e) factors | `SourceTrustScoreCalculator` with 5 component scores |
| Freshness F(e) decay | `TrustDecayService` with configurable τ per source |
| Claim strength S_claim | `TrustLatticeEngine` security atoms + disposition selector |
| Lattice merge ordering | `K4Lattice` with precedence rules |
| Signature strength | `VerificationScoreCalculator` with signature/provenance scoring |
| Consensus bonus | `VexConsensusEngine` with multi-source corroboration |
| Policy hooks | `PolicyBundle` with override rules |
| Replay/determinism | `ProofBundle` with decision traces |
## Cross-References
If you arrived here via a broken link, see:
- `src/VexLens/StellaOps.VexLens/Trust/` for trust scoring
- `src/Policy/__Libraries/StellaOps.Policy/TrustLattice/` for lattice logic
- `docs/modules/vexlens/` for VexLens documentation