Compare commits

..

4 Commits

Author SHA1 Message Date
StellaOps Bot
7df0677e34 up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Airgap Sealed CI Smoke / sealed-smoke (push) Has been cancelled
Console CI / console-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
2025-11-30 22:36:03 +02:00
StellaOps Bot
b39eb34226 sprints up 2025-11-30 22:35:50 +02:00
StellaOps Bot
808ab87b21 up 2025-11-30 21:01:00 +02:00
StellaOps Bot
25254e3831 news advisories 2025-11-30 21:00:38 +02:00
123 changed files with 10491 additions and 488 deletions

View File

@@ -0,0 +1,15 @@
{
"files": {
"src/app.js": {
"lines_covered": [
5,
6,
7,
13,
18,
19
],
"lines_total": 40
}
}
}

View File

@@ -0,0 +1,10 @@
{
"entry": "POST /api/admin/exec",
"path": [
"app.js::createServer",
"handler",
"eval(code)"
],
"sink": "ExpressEval::exec",
"notes": "Admin exec reached"
}

View File

@@ -0,0 +1,16 @@
{
"files": {
"src/app.js": {
"lines_covered": [
5,
6,
7,
12,
13,
14,
15
],
"lines_total": 50
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /api/admin/exec",
"path": [
"app.js::createServer",
"guard: ALLOW_EXEC!=true"
],
"sink": "ExpressGuarded::exec",
"notes": "Guard blocked sink"
}

View File

@@ -0,0 +1,15 @@
{
"files": {
"src/app.js": {
"lines_covered": [
5,
6,
7,
13,
18,
20
],
"lines_total": 45
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /api/render",
"path": [
"app.js::createServer",
"render template"
],
"sink": "FastifyTemplate::render",
"notes": "Template rendered with user input"
}

View File

@@ -0,0 +1,15 @@
{
"files": {
"src/app.js": {
"lines_covered": [
5,
6,
7,
9,
10,
11
],
"lines_total": 32
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /api/exec",
"path": [
"app.js:handleRequest",
"guard: FEATURE_ENABLE != 1"
],
"sink": "GuardedEval::handleRequest",
"notes": "Guard prevented sink execution"
}

View File

@@ -0,0 +1,14 @@
{
"files": {
"src/app.js": {
"lines_covered": [
5,
6,
7,
12,
15
],
"lines_total": 30
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /api/exec",
"path": [
"app.js:handleRequest",
"eval(code)"
],
"sink": "UnsafeEval::handleRequest",
"notes": "Test-driven dynamic trace"
}

View File

@@ -0,0 +1,16 @@
{
"files": {
"src/app.py": {
"lines_covered": [
3,
4,
5,
7,
8,
9,
10
],
"lines_total": 38
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /render",
"path": [
"app.py::handle_request",
"render"
],
"sink": "DjangoSSTI::render",
"notes": "Template rendered (autoescape off)"
}

View File

@@ -0,0 +1,15 @@
{
"files": {
"src/app.py": {
"lines_covered": [
3,
4,
5,
8,
9,
11
],
"lines_total": 40
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /exec",
"path": [
"app.py::handle_request",
"guard: ALLOW_EXEC!=true"
],
"sink": "FastApiGuarded::handle_request",
"notes": "Guard blocked eval"
}

View File

@@ -0,0 +1,16 @@
{
"files": {
"src/app.py": {
"lines_covered": [
4,
5,
6,
8,
9,
10,
11
],
"lines_total": 40
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /render",
"path": [
"app.py::handle_request",
"render"
],
"sink": "FlaskTemplate::render",
"notes": "Template rendered"
}

View File

@@ -0,0 +1,15 @@
{
"files": {
"src/app.py": {
"lines_covered": [
3,
4,
5,
8,
9,
11
],
"lines_total": 34
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /api/exec",
"path": [
"app.py::handle_request",
"guard: FEATURE_ENABLE != 1"
],
"sink": "PyGuardedExec::handle_request",
"notes": "Guard blocked eval"
}

View File

@@ -0,0 +1,14 @@
{
"files": {
"src/app.py": {
"lines_covered": [
3,
4,
5,
8,
10
],
"lines_total": 30
}
}
}

View File

@@ -0,0 +1,9 @@
{
"entry": "POST /api/exec",
"path": [
"app.py::handle_request",
"eval(code)"
],
"sink": "PyUnsafeExec::handle_request",
"notes": "Eval reached"
}

View File

@@ -21,8 +21,9 @@
1. **Value in context** [Overview](overview.md) compresses the “Why” + “What” stories and shows how StellaOps stands apart.
2. **Try it fast** [Quickstart](quickstart.md) walks through fetching the signed bundles, configuring `.env`, and verifying the first scan.
3. **Feature confidence** [Key Features](key-features.md) gives five capability cards covering Delta SBOM, VEXfirst policy, Sovereign crypto, Deterministic replay, and Transparent quotas.
4. **Up-next checkpoints** [Evaluation checklist](evaluate/checklist.md) helps teams plan Day0 to Day30 adoption milestones.
3. **Feature confidence** [Key Features](key-features.md) gives five capability cards covering Delta SBOM, VEX-first policy, Sovereign crypto, Deterministic replay, and Transparent quotas.
4. **Up-next checkpoints** [Evaluation checklist](evaluate/checklist.md) helps teams plan Day-0 to Day-30 adoption milestones.
5. **Be dev-ready** [Developer Quickstart](onboarding/dev-quickstart.md) (29-Nov-2025 advisory) walks through the core repos, determinism tests, attestations, and starter issues for a mid-level .NET engineer.
## Key capabilities that define StellaOps

View File

@@ -20,7 +20,7 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | TASKRUN-AIRGAP-56-001 | DONE (2025-11-30) | Delivered sealed-mode plan validation via AirGap egress policy binding in WebService. | Task Runner Guild · AirGap Policy Guild | Enforce plan-time validation rejecting non-allowlisted network calls in sealed mode; surface remediation errors. |
| 2 | TASKRUN-AIRGAP-56-002 | BLOCKED (2025-11-30) | Depends on 56-001. | Task Runner Guild · AirGap Importer Guild | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. |
| 2 | TASKRUN-AIRGAP-56-002 | DOING (2025-11-30) | Depends on 56-001. | Task Runner Guild · AirGap Importer Guild | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. |
| 3 | TASKRUN-AIRGAP-57-001 | BLOCKED (2025-11-30) | Depends on 56-002. | Task Runner Guild · AirGap Controller Guild | Refuse to execute plans when environment sealed=false but declared sealed install; emit advisory timeline events. |
| 4 | TASKRUN-AIRGAP-58-001 | BLOCKED (2025-11-30) | Depends on 57-001. | Task Runner Guild · Evidence Locker Guild | Capture bundle import job transcripts, hashed inputs/outputs into portable evidence bundles. |
| 5 | TASKRUN-42-001 | BLOCKED (2025-11-25) | Continue execution engine upgrades (loops/conditionals/maxParallel), simulation mode, policy gate integration, deterministic failure recovery. | Task Runner Guild (`src/TaskRunner/StellaOps.TaskRunner`) | Execution engine enhancements + simulation API/CLI. Blocked: TaskPack loop/conditional semantics and policy-gate evaluation contract not published. |
@@ -56,6 +56,7 @@
| 2025-11-30 | TASKRUN-41-001 delivered in blockers sprint; run API/storage/provenance contract now active (see `docs/modules/taskrunner/architecture.md`). | Task Runner Guild |
| 2025-11-30 | Delivered TASKRUN-AIRGAP-56-001: WebService planner enforces sealed-mode allowlist with remediation messaging. | Task Runner Guild |
| 2025-11-30 | Updated dependencies: AIRGAP chain blocked on helper design (56-002) and downstream evidence work; OAS chain blocked pending TaskPack control-flow addendum (due 2025-12-05); OBS chain blocked on timeline/evidence schema; 41-001 no longer a blocker. | Project Mgmt |
| 2025-12-01 | Started TASKRUN-AIRGAP-56-002: bundle ingestion helper executor added (checksum verify + deterministic staging). Worker wired; awaiting importer specs/fixture paths before marking DONE. | Task Runner Guild |
| 2025-11-30 | Added Wave Coordination, Interlocks, and Action Tracker sections per docs/implplan/AGENTS.md template; no scope change. | Project Mgmt |
| 2025-11-30 | Synced TaskRunner task rows in tasks-all/archived indexes to reflect canonical sprint name and BLOCKED status where applicable. | Project Mgmt |
| 2025-11-30 | Refreshed Decisions & Risks with risk table and aligned checkpoint wording. | Project Mgmt |

View File

@@ -93,4 +93,5 @@
| 2025-11-30 | Set Delivery Tracker tasks to BLOCKED pending Sprint 0163 artefacts; expanded interlocks/action tracker for gating signals. | Implementer |
| 2025-11-30 | Added KMS envelope-handling pattern doc and closed Action 2; encryption risk now covered. | Implementer |
| 2025-11-30 | Added risk-bundle provider matrix/signing baseline doc and closed Action 3; Wave 3 still waits on Sprint 0163 outputs. | Implementer |
| 2025-11-30 | Wired RiskBundle worker DI/options, added filesystem store + signer config, and enabled host service scaffold; RiskBundle tests passing. | Implementer |
| 2025-11-30 | Implemented risk-bundle builder/signing/object store scaffolding and unit tests; set RISK-BUNDLE-69-001 to DOING pending upstream provider artefacts; `dotnet test --filter RiskBundle` passing. | Implementer |

View File

@@ -71,6 +71,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Ran TimelineIndexer unit tests (TimelineIndexer.Tests) successfully after ingestion worker + query option fixes; still waiting on transport schema to wire NATS/Redis. | Implementer |
| 2025-11-30 | Implemented TimelineIngestionWorker with subscriber abstraction, session dedupe, and metrics counters; awaiting NATS/Redis subject schema to wire real transports. | Implementer |
| 2025-11-30 | Started TIMELINE-OBS-52-002: added ingestion service, Postgres store, and deterministic payload hashing; queue bindings pending schema alignment. | Implementer |
| 2025-11-30 | Normalized sprint to AGENTS template (Wave/Interlocks/Action tracker) while keeping prior content intact. | Implementer |

View File

@@ -29,7 +29,7 @@
| 5 | SIGN-CORE-186-005 | DONE (2025-11-26) | SignerStatementBuilder refactored with StellaOps predicate types and CanonicalJson from Provenance library. | Signing Guild | Refactor `SignerStatementBuilder` to support StellaOps predicate types and delegate canonicalisation to Provenance library when available. |
| 6 | SIGN-TEST-186-006 | DONE (2025-11-26) | Integration tests upgraded with real crypto providers and fixture predicates. | Signing Guild · QA Guild | Upgrade signer integration tests to real crypto abstraction + fixture predicates (promotion, SBOM, replay); deterministic test data. |
| 7 | AUTH-VERIFY-186-007 | BLOCKED (2025-11-30) | BLOCKED by 186-003. | Authority Guild · Provenance Guild | Authority-side helper/service validating DSSE signatures and Rekor proofs for promotion attestations using trusted checkpoints; offline audit flow. |
| 8 | SCAN-DETER-186-008 | DOING (2025-11-26) | Parallel with 186-002. | Scanner Guild | Add deterministic execution switches (fixed clock, RNG seed, concurrency cap, feed/policy pins, log filtering) via CLI/env/config. |
| 8 | SCAN-DETER-186-008 | DONE (2025-11-30) | Parallel with 186-002. | Scanner Guild | Add deterministic execution switches (fixed clock, RNG seed, concurrency cap, feed/policy pins, log filtering) via CLI/env/config. |
| 9 | SCAN-DETER-186-009 | BLOCKED (2025-11-30) | BLOCKED by 186-008 completion. | Scanner Guild · QA Guild | Determinism harness to replay scans, canonicalise outputs, record hash matrices (`docs/modules/scanner/determinism-score.md`). |
| 10 | SCAN-DETER-186-010 | BLOCKED (2025-11-30) | BLOCKED by 186-009. | Scanner Guild · Export Center Guild | Emit/publish `determinism.json` with scores/hashes/diffs alongside each scanner release via CAS/object storage; document in release guide. |
| 11 | SCAN-ENTROPY-186-011 | DONE (2025-11-26) | Add core entropy calculator & tests; integrate into worker pipeline next. | Scanner Guild | Entropy analysis for ELF/PE/Mach-O/opaque blobs (sliding-window metrics, section heuristics); record offsets/hints (see `docs/modules/scanner/entropy.md`). |
@@ -65,12 +65,13 @@
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_186_record_deterministic_execution.md` to `SPRINT_0186_0001_0001_record_deterministic_execution.md`; content preserved. | Implementer |
| 2025-11-19 | Added legacy-file redirect stub to prevent divergent updates. | Implementer |
| 2025-11-30 | Realigned statuses: blocked SCAN-REPLAY-186-002/003/009/010/014, AUTH-VERIFY-186-007 on upstream contracts; blocked SPDX 15a15f/DOCS-SBOM-186-017 due to working-directory scope gap (`src/Sbomer` not in sprint). | Implementer |
| 2025-11-30 | SCAN-DETER-186-008 DONE: added determinism payload test coverage and determinism context wiring validation; determinism toggles (fixed clock, RNG seed, log filter, concurrency cap, feed/policy pins) now exercised via determinism.json payload. | Scanner Guild |
## Decisions & Risks
| Item | Impact | Mitigation / Next Step | Status |
| --- | --- | --- | --- |
| Replay Core dependency (0185) | Blocks replay record/consume tasks. | Keep 186-001 BLOCKED until pipeline contract delivered. | OPEN |
| Fixed clock/RNG/log filtering required | Deterministic execution harness correctness. | SCAN-DETER-186-008 in DOING; unblock 009/010 after 008 completes. | OPEN |
| Fixed clock/RNG/log filtering required | Deterministic execution harness correctness. | SCAN-DETER-186-008 DONE; unblock 009/010 after 008 completion. | OPEN |
| Provenance library alignment for signing/verification | Signing/Authority changes must stay compatible. | Rebase once Provenance library available; keep 186-003/007 BLOCKED. | OPEN |
| BLOCKER (186-001): WebService lacks worker inputs (sealed bundles, hashes, CAS locations). | Replay record cannot assemble manifests. | Require pipeline contract from Worker; keep 186-001/002/003 BLOCKED. | OPEN |
| BLOCKER (186-012): Worker lacks HTTP contract to POST entropy snapshots. | Entropy evidence cannot flow to WebService. | Define transport after Policy build fix; keep 186-012 BLOCKED. | OPEN |

View File

@@ -0,0 +1,75 @@
# Sprint 0202-0001-0001 · CLI II (Experience & SDKs 180.A)
## Topic & Scope
- CLI phase II: exports pipeline (profiles/distribution/scheduling/verification) and Notify command surface (rules/simulate/ack/escalations) on top of CLI core from Sprint 180.A.
- Consolidate already-delivered CLI work (exceptions, forensics, promotion, determinism, advisory/VEX) and keep export/notify chains ready once contracts land.
- **Working directory:** `src/Cli/StellaOps.Cli`.
## Dependencies & Concurrency
- Upstream: Sprint 180.A (CLI I) delivered core/bootstrap.
- Concurrency: two chains run independently but sequentially inside each chain: Export (35-001 → 36-001 → 37-001) and Notify (38-001 → 39-001 → 40-001).
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/modules/cli/architecture.md
- src/Cli/StellaOps.Cli/AGENTS.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | CLI-CORE-41-001 | DONE (2025-11-28) | None | DevEx/CLI Guild | CLI core: OutputRenderer (json/yaml/table), profiles, error codes, global options. |
| 2 | CLI-EXC-25-001 | DONE (2025-11-28) | None | DevEx/CLI Guild | `stella exceptions` CRUD/import/export commands + HTTP client/models. |
| 3 | CLI-EXC-25-002 | DONE (2025-11-28) | 25-001 | DevEx/CLI Guild | Policy simulate flags `--with-exception/--without-exception`. |
| 4 | CLI-EXPORT-35-001 | BLOCKED (2025-10-29) | Await export profiles API/spec (task definition incomplete in legacy doc). | DevEx/CLI Guild | Implement `stella export profiles` (full description pending). |
| 5 | CLI-EXPORT-36-001 | TODO | Depends on 35-001. | DevEx/CLI Guild | Distribution commands `stella export distribute`, `run download --resume`, progress bars. |
| 6 | CLI-EXPORT-37-001 | TODO | Depends on 36-001. | DevEx/CLI Guild | Scheduling/retention + `export verify` (signature/hash validation). |
| 7 | CLI-FORENSICS-53-001 | DONE (2025-11-28) | None | DevEx/CLI · Evidence Locker Guild | Forensic snapshot create/list/show commands + models/clients. |
| 8 | CLI-FORENSICS-54-001 | DONE (2025-11-28) | None | DevEx/CLI · Provenance Guild | `stella forensic verify` checksums/DSSE/timeline validation. |
| 9 | CLI-FORENSICS-54-002 | DONE (2025-11-28) | None | DevEx/CLI · Provenance Guild | `stella forensic attest show` for DSSE/in-toto attestations. |
| 10 | CLI-PROMO-70-001 | DONE (2025-11-28) | None | DevEx/CLI · Provenance Guild | `stella promotion assemble` payload generation. |
| 11 | CLI-DETER-70-003 | DONE (2025-11-28) | None | DevEx/CLI · Scanner Guild | Determinism harness runner `stella detscore run`. |
| 12 | CLI-LNM-22-001 | DONE (2025-11-28) | None | DevEx/CLI Guild | Advisory observations commands `obs get/linkset show/export`. |
| 13 | CLI-LNM-22-002 | DONE (2025-11-28) | None | DevEx/CLI Guild | VEX observations commands `vex obs get/linkset show`. |
| 14 | CLI-NOTIFY-38-001 | BLOCKED (2025-10-29) | Await Notify rules API/contract. | DevEx/CLI Guild | Implement `stella notify rules ...` (spec pending). |
| 15 | CLI-NOTIFY-39-001 | BLOCKED (2025-10-29) | Depends on 38-001. | DevEx/CLI Guild | `stella notify simulate`/digest/diff/schedule with dry-run. |
| 16 | CLI-NOTIFY-40-001 | TODO | Depends on 39-001. | DevEx/CLI Guild | Ack token redemption, escalations, localization previews, channel health checks. |
| 17 | CLI-OBS-50-001 | DONE (2025-11-28) | None | DevEx/CLI Guild | Traceparent propagation handler and logging. |
## Wave Coordination
- Wave A: Export chain (35-001 → 36-001 → 37-001). Await export profiles spec before starting.
- Wave B: Notify chain (38-001 → 39-001 → 40-001). Await Notify rules/simulate contracts.
- Wave C: Completed backlog (core/exceptions/forensics/promo/determ/obs) no further action.
## Wave Detail Snapshots
| Wave | Entry criteria | Exit evidence | Notes |
| --- | --- | --- | --- |
| A Export | Export profiles API/spec published; CLI auth scopes confirmed. | `stella export profiles/distribute/schedule/verify` commands shipped with tests and docs. | Keep outputs deterministic; resume-safe downloads. |
| B Notify | Notify rules/simulate contracts published; webhook payload schema fixed. | `stella notify rules/simulate/ack` commands with escalation + localization previews validated. | Add dry-run, diff, and ack token flows; align with Notifier API versioning. |
## Interlocks
- Export profiles/distribution/scheduling contracts from Export Center/DevOps owners.
- Notify rules/simulation/digest payload schema from Notifier team.
- CLI auth scopes for export/notify surfaces.
## Upcoming Checkpoints
- Set once export/notify specs drop (target dates TBD from owning teams).
## Action Tracker
- None; populate when export/notify contract dates are provided.
## Decisions & Risks
- Blocked tasks lack published API/contract details (export profiles; notify rules/simulation). Cannot start without specs.
- Task definitions for CLI-EXPORT-35-001 and CLI-NOTIFY-38-001 are incomplete in legacy doc; require spec drop before refinement.
| Risk | Impact | Mitigation |
| --- | --- | --- |
| Export profiles/spec not published | Export chain cannot start; delivery slips. | Track spec drop; schedule kickoff after publication. |
| Notify rules/simulate schema missing | Notify chain blocked; downstream ack/escalation work delayed. | Coordinate with Notifier team; add action once date known. |
| Ambiguous legacy task definitions | Risk of rework/misalignment. | Hold implementation until specs clarify scope; update sprint once received. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized sprint to standard template; renamed to `SPRINT_0202_0001_0001_cli_ii.md`; added waves/interlocks/risks; preserved statuses. | Project Mgmt |

View File

@@ -22,10 +22,10 @@
| --- | --- | --- | --- | --- | --- |
| 1 | SDKGEN-62-001 | DONE (2025-11-24) | Toolchain, template layout, and reproducibility spec pinned. | SDK Generator Guild · `src/Sdk/StellaOps.Sdk.Generator` | Choose/pin generator toolchain, set up language template pipeline, and enforce reproducible builds. |
| 2 | SDKGEN-62-002 | DONE (2025-11-24) | Shared post-processing merged; helpers wired. | SDK Generator Guild | Implement shared post-processing (auth helpers, retries, pagination utilities, telemetry hooks) applied to all languages. |
| 3 | SDKGEN-63-001 | DOING | Shared layer ready; TS generator script + fixture + packaging templates added; awaiting frozen OAS to generate. Scaffold + smoke + hash guard ready. | SDK Generator Guild | Ship TypeScript SDK alpha with ESM/CJS builds, typed errors, paginator, streaming helpers. |
| 4 | SDKGEN-63-002 | DOING | Scaffold added; waiting on frozen OAS to generate alpha. Scaffold + smoke + hash guard ready. | SDK Generator Guild | Ship Python SDK alpha (sync/async clients, type hints, upload/download helpers). |
| 5 | SDKGEN-63-003 | DOING | Scaffold added (config, driver script, smoke test, README); awaiting frozen OAS to generate alpha. | SDK Generator Guild | Ship Go SDK alpha with context-first API and streaming helpers. |
| 6 | SDKGEN-63-004 | DOING | Scaffold added (config, driver script, smoke test, README); OkHttp selected as HTTP client; awaiting frozen OAS to generate alpha. | SDK Generator Guild | Ship Java SDK alpha (builder pattern, HTTP client abstraction). |
| 3 | SDKGEN-63-001 | BLOCKED (2025-11-27) | Awaiting frozen aggregate OAS digest to generate TS alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship TypeScript SDK alpha with ESM/CJS builds, typed errors, paginator, streaming helpers. |
| 4 | SDKGEN-63-002 | BLOCKED (2025-11-27) | Awaiting frozen aggregate OAS digest to generate Python alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship Python SDK alpha (sync/async clients, type hints, upload/download helpers). |
| 5 | SDKGEN-63-003 | BLOCKED (2025-11-26) | Awaiting frozen aggregate OAS digest to generate Go alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship Go SDK alpha with context-first API and streaming helpers. |
| 6 | SDKGEN-63-004 | BLOCKED (2025-11-26) | Awaiting frozen aggregate OAS digest to generate Java alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship Java SDK alpha (builder pattern, HTTP client abstraction). |
| 7 | SDKGEN-64-001 | BLOCKED (2025-11-30) | Depends on 63-004; waiting for frozen aggregate OAS and Java alpha before mapping CLI surfaces. | SDK Generator Guild · CLI Guild | Switch CLI to consume TS or Go SDK; ensure parity once Wave B artifacts land. |
| 8 | SDKGEN-64-002 | BLOCKED (2025-11-30) | Depends on 64-001; blocked until SDKGEN-64-001 completes. | SDK Generator Guild · Console Guild | Integrate SDKs into Console data providers where feasible. |
| 9 | SDKREL-63-001 | TODO | Set up signing keys/provenance; stage CI pipelines across registries. | SDK Release Guild · `src/Sdk/StellaOps.Sdk.Release` | Configure CI pipelines for npm, PyPI, Maven Central staging, and Go proxies with signing and provenance attestations. |
@@ -60,25 +60,26 @@
## Action Tracker
| # | Action | Owner | Due (UTC) | Status |
| --- | --- | --- | --- | --- |
| 1 | Confirm registry signing keys and provenance workflow per language | SDK Release Guild | 2025-11-29 | Open |
| 1 | Confirm registry signing keys and provenance workflow per language | SDK Release Guild | 2025-11-29 | BLOCKED (awaiting sovereign crypto key provisioning; overdue) |
| 2 | Publish SDK language support matrix to CLI/UI guilds. Evidence: `docs/modules/sdk/language-support-matrix.md`. | SDK Generator Guild | 2025-12-03 | DONE (2025-11-26) |
| 3 | Align CLI adoption scope with SPRINT_0201_0001_0001_cli_i and schedule SDK drop integration | SDK Generator Guild · CLI Guild | 2025-12-10 | Open |
| 4 | Define devportal offline bundle manifest with Export Center per SPRINT_0206_0001_0001_devportal. Evidence: `docs/modules/export-center/devportal-offline-manifest.md`. | SDK Release Guild · Export Center Guild | 2025-12-12 | DONE (2025-11-26) |
| 5 | Deliver parity matrix and SDK drop to UI data providers per SPRINT_0209_0001_0001_ui_i | SDK Generator Guild · UI Guild | 2025-12-16 | Open |
## Decisions & Risks
- Toolchain pinned (OpenAPI Generator 7.4.0, JDK 21) and recorded in repo (`TOOLCHAIN.md`, `toolchain.lock.yaml`); downstream tracks must honor lock file for determinism.
- Dependencies on upstream API/portal contracts may delay generator pinning; mitigation: align with APIG0101 / DEVL0101 milestones.
- Release automation requires registry credentials and signing infra; mitigation: reuse sovereign crypto enablement (SPRINT_0514_0001_0001_sovereign_crypto_enablement.md) practices and block releases until keys are validated.
- Toolchain pinned (OpenAPI Generator 7.4.0, JDK 21) and recorded in repo (`TOOLCHAIN.md`, `toolchain.lock.yaml`); downstream tracks must honor lock file for determinism.
- Dependencies on upstream API/portal contracts may delay generator pinning; mitigation: align with APIG0101 / DEVL0101 milestones.
- Release automation requires registry credentials and signing infra; keys still pending (Action Tracker #1 overdue). Mitigation: reuse sovereign crypto enablement (SPRINT_0514_0001_0001_sovereign_crypto_enablement.md) practices, escalate key provisioning by 2025-12-02, and block releases until keys are validated.
- Offline bundle job (SDKREL-64-002) depends on Export Center artifacts; track alongside Export Center sprints; remains BLOCKED until SDKGEN-64-001 completes.
- Shared postprocess helpers copy only when CI sets `STELLA_POSTPROCESS_ROOT` and `STELLA_POSTPROCESS_LANG`; ensure generation jobs export these to keep helpers present in artifacts.
- Shared postprocess helpers copy only when CI sets `STELLA_POSTPROCESS_ROOT` and `STELLA_POSTPROCESS_LANG`; ensure generation jobs export these to keep helpers present in artifacts.
### Risk Register
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Upstream APIs change after generator pin | Rework across four SDKs | Freeze spec version before SDKGEN-63-x; gate via API governance sign-off | SDK Generator Guild | Open |
| Registry signing not provisioned | Cannot ship to npm/PyPI/Maven/Go | Coordinate with sovereign crypto enablement; dry-run staging before prod | SDK Release Guild | Open |
| Offline bundle inputs unavailable | Air-gapped delivery slips | Pull docs/specs from devportal cache; coordinate with Export Center | SDK Release Guild | Open |
| Upstream APIs change after generator pin | Rework across four SDKs | Freeze spec version before SDKGEN-63-x; gate via API governance sign-off | SDK Generator Guild | Open |
| Aggregate OpenAPI freeze delayed | Wave B and downstream adoption blocked | Track APIG0101 schedule; request interim tagged snapshot with SHA; re-run hash guard once frozen | SDK Generator Guild | Open |
| Registry signing not provisioned | Cannot ship to npm/PyPI/Maven/Go | Coordinate with sovereign crypto enablement; dry-run staging before prod | SDK Release Guild | Open |
| Offline bundle inputs unavailable | Air-gapped delivery slips | Pull docs/specs from devportal cache; coordinate with Export Center | SDK Release Guild | Open |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -102,9 +103,10 @@
| 2025-11-26 | Added CI workflow `.gitea/workflows/sdk-generator.yml` to run `npm run sdk:smoke` on SDK generator changes (TS/Python/Go/Java). | SDK Generator Guild |
| 2025-11-27 | Marked SDKGEN-63-001/002 BLOCKED pending frozen aggregate OAS digest; scaffolds and smokes remain ready. | SDK Generator Guild |
| 2025-11-30 | Marked SDKGEN-64-001 and SDKGEN-64-002 BLOCKED pending Wave B (SDKGEN-63-004) OAS freeze/Java alpha; CLI/UI adoption cannot proceed without generated SDK artifacts. | Project Mgmt |
| 2025-11-24 | Added fixture OpenAPI (`ts/fixtures/ping.yaml`) and smoke test (`ts/test_generate_ts.sh`) to validate TypeScript pipeline locally; skips if generator jar absent. | SDK Generator Guild |
| 2025-11-24 | Vendored `tools/openapi-generator-cli-7.4.0.jar` and `tools/jdk-21.0.1.tar.gz` with SHA recorded in `toolchain.lock.yaml`; adjusted TS script to ensure helper copy post-run and verified generation against fixture. | SDK Generator Guild |
| 2025-11-24 | Ran `ts/test_generate_ts.sh` with vendored JDK/JAR and fixture spec; smoke test passes (helpers present). | SDK Generator Guild |
| 2025-11-30 | Status audit: set SDKGEN-63-001..004 to BLOCKED per aggregate OAS freeze; flagged registry signing key action overdue; added OAS-freeze risk entry. | PM |
| 2025-11-24 | Added fixture OpenAPI (`ts/fixtures/ping.yaml`) and smoke test (`ts/test_generate_ts.sh`) to validate TypeScript pipeline locally; skips if generator jar absent. | SDK Generator Guild |
| 2025-11-24 | Vendored `tools/openapi-generator-cli-7.4.0.jar` and `tools/jdk-21.0.1.tar.gz` with SHA recorded in `toolchain.lock.yaml`; adjusted TS script to ensure helper copy post-run and verified generation against fixture. | SDK Generator Guild |
| 2025-11-24 | Ran `ts/test_generate_ts.sh` with vendored JDK/JAR and fixture spec; smoke test passes (helpers present). | SDK Generator Guild |
| 2025-11-24 | Added deterministic TS packaging templates (package.json, tsconfig base/cjs/esm, README, sdk-error) copied via postprocess; updated helper exports and lock hash. | SDK Generator Guild |
| 2025-11-24 | Began SDKGEN-63-002: added Python generator config/script/README + smoke test (reuses ping fixture); awaiting frozen OAS to emit alpha. | SDK Generator Guild |
| 2025-11-27 | Began SDKGEN-63-003: added Go SDK generator scaffold with config (`go/config.yaml`), driver script (`go/generate-go.sh`), smoke test (`go/test_generate_go.sh`), and README; context-first API design documented; awaiting frozen OAS to generate alpha. | SDK Generator Guild |

View File

@@ -0,0 +1,78 @@
# Sprint 0210.0001.0002 - Experience & SDKs · UI II
## Topic & Scope
- Phase II UI uplift for Experience & SDKs: linkset filters, VEX evidence surfaces, permalinks, and Policy Studio authoring flows.
- Keep VEX-first decisioning aligned with `SPRINT_0215_0001_0001_vuln_triage_ux.md` and advisory "28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md".
- Accessibility and determinism remain gating: high-contrast support, deterministic diff outputs, and RBAC-consistent token handling.
- Active items only; completed work lives in `docs/implplan/archived/tasks.md` (updated 2025-11-08).
- **Working directory:** `src/UI/StellaOps.UI`.
## Dependencies & Concurrency
- Upstream: Sprint 0209.0001.0001 (UI I) for shared components and UI-LNM-22-001 filters; VEX schema and workflows from `SPRINT_0215_0001_0001_vuln_triage_ux.md` plus `docs/schemas/vex-decision.schema.json` and `docs/schemas/audit-bundle-index.schema.json`.
- Advisory alignment: "28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md" governs VEX tab semantics.
- Concurrency: UI III (Sprint 0211) may proceed in parallel if VEX tab API contracts remain backward compatible.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/ui/architecture.md`
- `docs/modules/ui/README.md`
- `docs/modules/ui/implementation_plan.md`
- `docs/15_UI_GUIDE.md`
- `docs/18_CODING_STANDARDS.md`
- `docs/schemas/vex-decision.schema.json`
- `docs/schemas/audit-bundle-index.schema.json`
- Advisory: "28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md"
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | UI-LNM-22-002 | TODO | UI-LNM-22-001 contracts; finalize filter UX | UI Guild (src/UI/StellaOps.UI) | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. |
| 2 | UI-LNM-22-003 | TODO | 1; align VEX tab with sprint 0215 schema | UI Guild; Excititor Guild (src/UI/StellaOps.UI) | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. |
| 3 | UI-LNM-22-004 | TODO | 2; confirm permalink format | UI Guild (src/UI/StellaOps.UI) | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. |
| 4 | UI-ORCH-32-001 | TODO | Orch scope contract; token flows | UI Guild; Console Guild (src/UI/StellaOps.UI) | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. |
| 5 | UI-POLICY-13-007 | TODO | Policy confidence metadata source | UI Guild (src/UI/StellaOps.UI) | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. |
| 6 | UI-POLICY-20-001 | TODO | 5; DSL schema for Monaco | UI Guild (src/UI/StellaOps.UI) | Ship Monaco-based policy editor with DSL syntax highlighting, inline diagnostics, and compliance checklist sidebar. |
| 7 | UI-POLICY-20-002 | TODO | 6; simulation inputs wired | UI Guild (src/UI/StellaOps.UI) | Build simulation panel showing before/after counts, severity deltas, and rule hit summaries with deterministic diff rendering. |
| 8 | UI-POLICY-20-003 | TODO | 7; RBAC roles ready | UI Guild; Product Ops (src/UI/StellaOps.UI) | Implement submit/review/approve workflow with comments, approvals log, and RBAC checks aligned to new Policy Studio roles (`policy:author`/`policy:review`/`policy:approve`/`policy:operate`). |
| 9 | UI-POLICY-20-004 | TODO | 8; run viewer APIs | UI Guild; Observability Guild (src/UI/StellaOps.UI) | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filter/search and export. |
| 10 | UI-POLICY-23-001 | TODO | 9; pack list contract | UI Guild; Policy Guild (src/UI/StellaOps.UI) | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. |
| 11 | UI-POLICY-23-002 | TODO | 10; schema + lints ready | UI Guild (src/UI/StellaOps.UI) | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. |
| 12 | UI-POLICY-23-003 | TODO | 11; rule builder inputs | UI Guild (src/UI/StellaOps.UI) | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. |
| 13 | UI-POLICY-23-004 | TODO | 12; approval routing | UI Guild (src/UI/StellaOps.UI) | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. |
| 14 | UI-POLICY-23-005 | TODO | 13; simulator services | UI Guild (src/UI/StellaOps.UI) | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. |
| 15 | UI-POLICY-23-006 | TODO | 14; export targets confirmed | UI Guild (src/UI/StellaOps.UI) | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. |
## Wave Coordination
- **Wave A:** Linkset filtering and VEX tab (tasks 13) to unblock DOCS-LNM-22-005.
- **Wave B:** Orchestrator RBAC surfacing (task 4) aligned with `orch:*` scope rollout.
- **Wave C:** Policy Studio authoring/review/simulation (tasks 515) in sequential unlock order; keep Monaco/editor artifacts backward compatible for UI III.
## Wave Detail Snapshots
- Wave A output: deterministic filter UX, VEX tab aligned to sprint 0215 schema, permalink pattern documented.
- Wave B output: updated RBAC mappings, token request scope changes, dashboard gating copy.
- Wave C output: Monaco editor, simulator, approvals, dashboards, explain exports wired to policy evidence APIs.
## Interlocks
- VEX decision model and schemas from `SPRINT_0215_0001_0001_vuln_triage_ux.md` must stabilize before tasks 23.
- Orchestrator scope contract (`orch:read`, `Orch.Viewer`) required before task 4.
- Policy DSL schema and simulator APIs needed before tasks 67 and downstream Policy Studio tasks.
## Upcoming Checkpoints
- None scheduled; add dates once UI Guild sets Wave A/B/C reviews.
## Action Tracker
- Pending: record permalink format decision once linkset filter UX is signed off.
## Decisions & Risks
| Risk | Impact | Mitigation | Owner / Signal |
| --- | --- | --- | --- |
| VEX schema changes post-sprint 0215 | Rework of tasks 23 | Gate VEX tab behind feature flag; align early with sprint 0215 owners | UI Guild · VEX lead |
| `orch:read` scope contract slips | Task 4 blocked; dashboard gating incomplete | Coordinate with Orchestrator guild; mock scope locally until contract lands | UI Guild · Console Guild |
| Policy DSL/simulator API churn | Tasks 615 blocked or reworked | Freeze DSL schema before Monaco editor; stage simulator APIs with contract tests | UI Guild · Policy Guild |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalised sprint to standard template and renamed file from `SPRINT_210_ui_ii.md` to `SPRINT_0210_0001_0002_ui_ii.md`; preserved task list and advisory links. | Planning |

View File

@@ -0,0 +1,70 @@
# Sprint 0211.0001.0003 - Experience & SDKs · UI III
## Topic & Scope
- Phase III UI uplift focusing on Policy Studio RBAC updates and reachability-first experiences across Vulnerability Explorer, Why drawer, SBOM Graph, and the new Reachability Center.
- Surface reachability evidence (columns, badges, call paths, timelines, halos) and align Console policy workspace with scopes `policy:author/review/approve/operate/audit/simulate`.
- Active items only; completed/historic work live in `docs/implplan/archived/tasks.md` (updated 2025-11-08).
- **Working directory:** `src/UI/StellaOps.UI`.
- Continues UI stream after `SPRINT_0210_0001_0002_ui_ii.md` (UI II).
## Dependencies & Concurrency
- Upstream: `SPRINT_0210_0001_0002_ui_ii.md` for Policy Studio explain view (UI-POLICY-23-006) and shared components.
- Signals/Reachability contracts for SIG-26 chain (call paths, timelines, coverage, overlay states) provided by Signals & Graph guilds.
- Concurrency: SIG-26 tasks are sequential (001 → 002 → 003 → 004); policy RBAC task can proceed in parallel once scopes finalized.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/ui/architecture.md`
- `docs/modules/ui/README.md`
- `docs/modules/ui/implementation_plan.md`
- `docs/modules/policy/architecture.md`
- `docs/modules/graph/architecture.md`
- `docs/modules/signals/architecture.md`
- `docs/15_UI_GUIDE.md`
- `docs/18_CODING_STANDARDS.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | UI-POLICY-27-001 | TODO | UI-POLICY-23-006 results; scope strings finalised | UI Guild; Product Ops (src/UI/StellaOps.UI) | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. |
| 2 | UI-SIG-26-001 | TODO | Reachability columns spec + signals feed schema | UI Guild; Signals Guild (src/UI/StellaOps.UI) | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. |
| 3 | UI-SIG-26-002 | TODO | 2; call path data availability | UI Guild (src/UI/StellaOps.UI) | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. |
| 4 | UI-SIG-26-003 | TODO | 3; overlay state/legend finalized | UI Guild (src/UI/StellaOps.UI) | Add reachability overlay halos/time slider to SBOM Graph along with state legend. |
| 5 | UI-SIG-26-004 | TODO | 4; coverage metrics stitched | UI Guild (src/UI/StellaOps.UI) | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. |
## Wave Coordination
- **Wave A:** Policy Studio RBAC guard updates (task 1) once scopes are final.
- **Wave B:** Sequential reachability surfaces (tasks 25) building on the SIG-26 evidence chain.
## Wave Detail Snapshots
- Wave A output: updated RBAC guardrails, scope requests, and UX copy aligned to `policy:*` scopes with Cypress auth fixtures.
- Wave B output: reachability columns/badges, Why drawer call paths and timeline, SBOM Graph halos/time slider with legend, and Reachability Center with coverage/sensor freshness views.
## Interlocks
- Policy Engine to publish final `policy:*` scope list and explain view outputs (UI-POLICY-23-006) to unblock task 1.
- Signals/Graph guilds to provide deterministic reachability evidence fixtures (call paths, timelines, overlays) for SIG-26 tasks.
- Performance budgets for SBOM Graph overlays and Reachability Center dashboards to keep UI responsive offline.
## Upcoming Checkpoints
- None scheduled; set dates once reachability fixtures and policy scope contracts are confirmed.
## Action Tracker
| # | Action | Owner | Due | Status |
| --- | --- | --- | --- | --- |
| 1 | Confirm final Policy Studio scopes and RBAC copy with Policy Engine owners. | UI Guild · Policy Guild | 2025-12-03 | TODO |
| 2 | Deliver reachability evidence fixture (columns, call paths, overlays) for SIG-26 chain. | Signals Guild | 2025-12-04 | TODO |
| 3 | Define SBOM Graph overlay performance budget (FPS target, node count, halo rendering limits). | UI Guild | 2025-12-05 | TODO |
## Decisions & Risks
| Risk | Impact | Mitigation | Owner / Signal |
| --- | --- | --- | --- |
| Policy scope strings change late | Rework of RBAC guards, auth stubs, and messaging (task 1) | Freeze scope list before Cypress fixtures; keep feature flag until policy contract stable. | UI Guild · Policy Guild |
| Reachability evidence incomplete or non-deterministic | Tasks 25 blocked or produce noisy UI | Require deterministic fixtures from Signals/Graph; stage behind feature flag and contract tests. | Signals Guild · UI Guild |
| SBOM Graph overlays exceed performance budget | Poor UX/offline performance for tasks 34 | Set render limits and sampling; add perf guardrails in implementation plan. | UI Guild |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalised sprint to standard template and renamed file from `SPRINT_211_ui_iii.md` to `SPRINT_0211_0001_0003_ui_iii.md`; no task status changes. | Planning |

View File

@@ -24,7 +24,7 @@
| 1 | WEB-AIAI-31-001 | BLOCKED (2025-11-22) | Gateway policy/contract for `/advisory/ai/*` not present in Web workspace; need backend gateway service location + policy spec to proceed. | BE-Base Platform Guild | Route advisory AI endpoints through gateway with guardrails. |
| 2 | WEB-AIAI-31-002 | BLOCKED (2025-11-22) | Blocked by WEB-AIAI-31-001; batching/streaming cannot start until gateway contract exists. | BE-Base Platform Guild | Streaming responses for CLI automation with job orchestration. |
| 3 | WEB-AIAI-31-003 | BLOCKED (2025-11-22) | Blocked by WEB-AIAI-31-002; telemetry targets depend on routing/batching contract. | BE-Base Platform Guild; Observability Guild | Telemetry + audit for advisory AI, guardrail block visibility. |
| 4 | WEB-AOC-19-002 | TODO | Depends on WEB-AOC-19-001; align DSSE/CMS helper APIs. | BE-Base Platform Guild | Ship `ProvenanceBuilder`, checksum utilities, signature verification helper with tests. |
| 4 | WEB-AOC-19-002 | DONE (2025-11-30) | Depends on WEB-AOC-19-001; align DSSE/CMS helper APIs. | BE-Base Platform Guild | Ship `ProvenanceBuilder`, checksum utilities, signature verification helper with tests. |
| 5 | WEB-AOC-19-003 | TODO | Depends on WEB-AOC-19-002; confirm Roslyn analyzer rules. | QA Guild; BE-Base Platform Guild | Analyzer to prevent forbidden key writes; shared guard-validation fixtures. |
| 6 | WEB-CONSOLE-23-001 | DONE (2025-11-28) | `/console/dashboard` and `/console/filters` endpoints implemented with tenant-scoped aggregates. | BE-Base Platform Guild; Product Analytics Guild | Tenant-scoped aggregates for findings, VEX overrides, advisory deltas, run health, policy change log. |
| 7 | CONSOLE-VULN-29-001 | BLOCKED (2025-11-19) | Blocked on WEB-CONSOLE-23-001 contract and Concelier graph schema freeze. | Console Guild; BE-Base Platform Guild | `/console/vuln/*` workspace endpoints with filters/reachability badges and DTOs once schemas stabilize. |
@@ -50,18 +50,19 @@
- Policy guild input needed for evidence export scoping (WEB-CONSOLE-23-003) and exceptions workflow (WEB-EXC-25-001).
## Upcoming Checkpoints
- 2025-11-25 (tentative): Contract freeze review for WEB-CONSOLE-23-001 with Concelier and Excititor owners.
- 2025-11-27 (tentative): Scheduler/Signals alignment on SSE topics for WEB-CONSOLE-23-002.
- 2025-12-03 (rescheduled): Contract freeze review for WEB-CONSOLE-23-001 with Concelier and Excititor owners; capture schema snapshot in `docs/api/console/workspaces.md`.
- 2025-12-04 (rescheduled): Scheduler/Signals alignment on SSE topics + heartbeat/backoff defaults for WEB-CONSOLE-23-002.
## Action Tracker
- Concelier graph schema freeze date confirmation (owner: Console Guild; due: 2025-11-25).
- Excititor SSE payload validation session scheduled with Scheduler Guild (owner: BE-Base Platform; due: 2025-11-27).
- Concelier graph schema freeze outcome + published snapshot (owner: Console Guild; due: 2025-12-02; status: follow-up for missed 2025-11-25 review).
- Excititor SSE payload validation and topic alignment session rebooked (owner: BE-Base Platform; due: 2025-12-04; status: rescheduled from 2025-11-27).
- Advisory AI gateway policy/contract snapshot for `/advisory/ai/*` routes (owner: BE-Base Platform; due: 2025-12-05; status: new action to unblock WEB-AIAI-31-001/002/003).
## Decisions & Risks
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Console contract freeze slips past 2025-11-25 | Blocks CONSOLE-VULN-29-001 and CONSOLE-VEX-30-001, delays console workspaces | Hold contract review on 2025-11-25; publish schema snapshot to `docs/api/console/workspaces.md`; keep blockers logged | Console Guild | Open |
| SSE topic alignment delayed | WEB-CONSOLE-23-002/003/004 latency and reliability uncertain | Schedule alignment with Scheduler/Signals by 2025-11-27; add heartbeat/backoff defaults; capture examples in samples directory | BE-Base Platform Guild | Open |
| Console contract freeze slips past 2025-11-25 | Blocks CONSOLE-VULN-29-001 and CONSOLE-VEX-30-001, delays console workspaces | Rescheduled review to 2025-12-03; publish schema snapshot to `docs/api/console/workspaces.md`; keep blockers logged | Console Guild | Open (rescheduled 2025-11-30) |
| SSE topic alignment delayed | WEB-CONSOLE-23-002/003/004 latency and reliability uncertain | Rescheduled alignment with Scheduler/Signals to 2025-12-04; add heartbeat/backoff defaults; capture examples in samples directory | BE-Base Platform Guild | Open (rescheduled 2025-11-30) |
| Advisory AI gateway contract missing | WEB-AIAI-31-001/002/003 cannot start without gateway location, RBAC/ABAC rules, and rate-limit policy spec | Request gateway contract snapshot + policy doc; replan once provided | BE-Base Platform Guild | Open |
## Execution Log
@@ -80,3 +81,5 @@
| 2025-11-22 | Added completion dates in `tasks-all` for WEB-CONTAINERS-44/45/46 and aligned BLOCKED dates for VULN-29-001/VEX-30-001. | Planning |
| 2025-11-22 | Harmonized all `CONTAINERS-44/45/46` rows in `tasks-all` to DONE with dates to match sprint status. | Planning |
| 2025-11-28 | Completed WEB-CONSOLE-23-001: Implemented `/console/dashboard` and `/console/filters` endpoints in Authority module. Dashboard returns tenant-scoped aggregates (findings summary, VEX overrides, advisory deltas, run health, policy change log) with 30-day trend data. Filters endpoint returns deterministic filter categories with counts and cache-validation hash. Added 8 unit tests for dashboard/filters endpoints. Implementation in `src/Authority/StellaOps.Authority/StellaOps.Authority/Console/`. | Policy Guild |
| 2025-11-30 | Rescheduled missed 2025-11-25/27 checkpoints to 2025-12-03/04, added follow-up actions (schema snapshot, SSE alignment, advisory AI gateway contract) and noted reschedule in risk statuses. | Planning |
| 2025-11-30 | Completed WEB-AOC-19-002: added deterministic provenance builder, checksum utilities, and DSSE/CMS signature verification helpers with unit tests under `src/Web/StellaOps.Web/src/app/core/aoc`. Added Web TASKS board and marked task DONE. | BE-Base Platform Guild |

View File

@@ -0,0 +1,79 @@
# Sprint 0213-0001-0002 · Web II (Experience & SDKs 180.F)
## Topic & Scope
- Phase II web gateway work: exceptions workflow surfaces, Export Center routing, and Graph overlay/asset proxying.
- Active items only; completed/historic work reside in `docs/implplan/archived/tasks.md` (updated 2025-11-08).
- Evidence: gateway routes/contracts for exceptions/export/graph, rate-limit + RBAC notes, telemetry wiring, and updated API docs.
- **Working directory:** `src/Web/StellaOps.Web`.
## Dependencies & Concurrency
- Upstream: Sprint 0212-0001-0001 Web I; Graph Platform overlay schema ratification; Export Center API contract freeze.
- Concurrency: Graph chain must follow spec ratification; export and exception tracks can proceed in parallel but respect per-task dependencies.
- Avoid parallel merges on Graph tasks until duplicate IDs (WEB-GRAPH-24-001/24-004 variants) are clarified.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/policy/architecture.md`
- `docs/modules/graph/architecture.md`
- `docs/modules/export-center/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | WEB-EXC-25-002 | TODO | Depends on WEB-EXC-25-001; align exception metadata schema for `/policy/*`. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Extend `/policy/effective` and `/policy/simulate` to include exception metadata and allow simulation overrides; audit logging + pagination limits preserved. |
| 2 | WEB-EXC-25-003 | TODO | Wait for WEB-EXC-25-002 output and notification hook contracts. | BE-Base Platform Guild; Platform Events Guild (`src/Web/StellaOps.Web`) | Publish `exception.*` events, integrate notification hooks, enforce rate limits. |
| 3 | WEB-EXPORT-35-001 | TODO | Need Export Center profile/run/download contracts confirmed. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Surface Export Center APIs with tenant scoping, streaming support, viewer/operator scope checks. |
| 4 | WEB-EXPORT-36-001 | TODO | Depends on WEB-EXPORT-35-001 and storage signer inputs. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add distribution routes (OCI/object storage), manifest/provenance proxies, signed URL generation. |
| 5 | WEB-EXPORT-37-001 | TODO | Depends on WEB-EXPORT-36-001; finalize retention/encryption params. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose scheduling, retention, encryption parameters, verification endpoints with admin scope enforcement and audit logs. |
| 6 | WEB-GRAPH-SPEC-21-000 | BLOCKED (2025-11-30) | Await Graph Platform ratification of overlay format + cache schema. | BE-Base Platform Guild; Graph Platform Guild (`src/Web/StellaOps.Web`) | Graph API/overlay spec drop; stub exists but not ratified. |
| 7 | WEB-GRAPH-21-001 | BLOCKED (2025-11-30) | Blocked by WEB-GRAPH-SPEC-21-000. | BE-Base Platform Guild; Graph Platform Guild (`src/Web/StellaOps.Web`) | Graph endpoints proxy with tenant enforcement, scope checks, streaming. |
| 8 | WEB-GRAPH-21-002 | BLOCKED (2025-11-30) | Blocked by WEB-GRAPH-21-001 and final overlay schema. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Request validation (bbox/zoom/path), pagination tokens, deterministic ordering; contract tests. |
| 9 | WEB-GRAPH-21-003 | TODO | Start once WEB-GRAPH-21-002 unblocks. | BE-Base Platform Guild; QA Guild (`src/Web/StellaOps.Web`) | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, document rate limits. |
| 10 | WEB-GRAPH-21-004 | TODO | Requires WEB-GRAPH-21-003 outputs. | BE-Base Platform Guild; Policy Guild (`src/Web/StellaOps.Web`) | Overlay pass-through; maintain streaming budgets while gateway stays stateless. |
| 11 | WEB-GRAPH-24-001 | TODO | WEB-GRAPH-21-004; cache/pagination strategy confirmation. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Gateway proxy refresh for Graph API + Policy overlays with RBAC, caching, pagination, ETags, streaming; zero business logic. |
| 12 | WEB-GRAPH-24-001 (Graph endpoints) | TODO | Depends on WEB-GRAPH-24-001; clarify duplicate ID scope. | BE-Base Platform Guild; SBOM Service Guild (`src/Web/StellaOps.Web`) | `/graph/assets/*` endpoints (snapshots, adjacency, search) with pagination, ETags, tenant scoping as pure proxy. |
| 13 | WEB-GRAPH-24-004 | TODO | Needs WEB-GRAPH-24-001 responses; overlay service AOC feed. | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Embed AOC summaries from overlay services; gateway does not compute derived severity/hints. |
| 14 | WEB-GRAPH-24-004 (Telemetry) | TODO | Depends on WEB-GRAPH-24-004; pick sampling strategy. | BE-Base Platform Guild; Observability Guild (`src/Web/StellaOps.Web`) | Collect gateway metrics/logs (tile latency, proxy errors, overlay cache stats) and forward to dashboards; document sampling. |
| 15 | WEB-LNM-21-001 | TODO | Need advisory service schema; confirm RBAC scopes. | BE-Base Platform Guild; Concelier WebService Guild (`src/Web/StellaOps.Web`) | Surface `/advisories/*` APIs via gateway with caching, pagination, RBAC enforcement (`advisory:read`). |
| 16 | WEB-LNM-21-002 | TODO | Depends on WEB-LNM-21-001 contract. | BE-Base Platform Guild; Excititor WebService Guild (`src/Web/StellaOps.Web`) | Expose `/vex/*` read APIs with evidence routes/export handlers; map `ERR_AGG_*` codes. |
## Wave Coordination
- Single wave covering Graph overlays/assets, Export Center routing, and exception workflows; follow dependency order noted above.
## Wave Detail Snapshots
- Not required; Delivery Tracker captures task-level state.
## Interlocks
- Graph overlay schema ratification required before tasks 612 can progress.
- Export Center contract (profiles/runs/download/distribution) must freeze before tasks 35 advance.
- Notification hooks/rate-limit policy needed for WEB-EXC-25-003; coordinate with Platform Events Guild.
- Duplicate IDs in Graph chain (24-001, 24-004 variants) risk status drift; needs resolution.
## Upcoming Checkpoints
- 2025-12-02 (UTC): Graph Platform review to ratify overlay/cache schema for WEB-GRAPH-SPEC-21-000.
- 2025-12-03 (UTC): Export Center contract freeze review for WEB-EXPORT-35-001/36-001.
- 2025-12-04 (UTC): Platform Events alignment on exception event shapes and rate limits for WEB-EXC-25-003.
## Action Tracker
| Item | Owner | Due (UTC) | Status / Notes |
| --- | --- | --- | --- |
| Publish ratified Graph overlay/cache schema snapshot to sprint attachments | Graph Platform Guild | 2025-12-02 | Open |
| Confirm Export Center streaming/range limits and signed URL policy for gateway | Export Center Guild | 2025-12-03 | Open |
| Clarify duplicate task IDs (WEB-GRAPH-24-001 variants and WEB-GRAPH-24-004 variants) and assign distinct IDs | Planning | 2025-12-01 | Open |
## Decisions & Risks
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Graph overlay schema not ratified (WEB-GRAPH-SPEC-21-000) | Blocks tasks 612; prevents gateway proxy wiring | Schedule 2025-12-02 ratification; publish schema snapshot; keep tasks 712 BLOCKED until done | Graph Platform Guild | Open |
| Duplicate task IDs in Graph chain (24-001, 24-004) | Tracking ambiguity; risk of parallel conflicting changes | Planning to assign distinct IDs and update sprint + tasks-all once clarified (Action Tracker item) | Planning | Open |
| Export Center contract churn | Rework for tasks 35; risk of incompatible scopes/streaming limits | Freeze contract on 2025-12-03 checkpoint; capture signed URL + retention params in API doc | Export Center Guild | Open |
| Notification/rate-limit policy gaps for exception events | Could block WEB-EXC-25-003 or cause unsafe fan-out | Align with Platform Events Guild on 2025-12-04; codify rate-limit + event schema in docs | BE-Base Platform Guild | Open |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized sprint to standard template, expanded dependencies/checkpoints, and carried over all tasks from prior list. | Project Mgmt |
| 2025-11-30 | Renamed file from `SPRINT_213_web_ii.md` to `SPRINT_0213_0001_0002_web_ii.md`; pending cross-references updated. | Project Mgmt |

View File

@@ -0,0 +1,53 @@
# Sprint 0214-0001-0001 · Web III (Experience & SDKs 180.F)
## Topic & Scope
- Phase III gateway delivery for Experience & SDKs: evidence aggregation, notifier routing, OAS alignment, and observability surfaces.
- Keep Web gateway contracts aligned with upstream services (Policy, Notifier, Timeline/Log stores) while maintaining offline/deterministic posture.
- Prep orchestrator read-only routes to unblock control-plane features in Web IV.
- **Working directory:** `src/Web/StellaOps.Web`.
## Dependencies & Concurrency
- Upstream: Sprint 180.F · Web II must land shared policy/VEX observation contracts before this work proceeds.
- Notifier chain is sequential (WEB-NOTIFY-38-001 → 39-001 → 40-001); avoid parallel merges to keep scopes coherent.
- OAS alignment must follow order WEB-OAS-61-001 → 61-002 → 62-001 → 63-001.
- Observability work is sequential (WEB-OBS-50-001 → 51-001 → 52-001 → 54-001 → 55-001 → 56-001); keep guardrails consistent across steps.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `src/Web/StellaOps.Web/AGENTS.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | WEB-LNM-21-003 | TODO | WEB-LNM-21-002 | BE-Base Platform Guild · Policy Guild (`src/Web/StellaOps.Web`) | Provide combined endpoint for Console to fetch policy result plus advisory/VEX evidence linksets for a component. |
| 2 | WEB-NOTIFY-38-001 | TODO | Align notifier gateway routes and tenant scopes | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Route notifier APIs (`/notifications/*`) and WS feed through gateway with tenant scoping, viewer/operator scope enforcement, and SSE/WebSocket bridging. |
| 3 | WEB-NOTIFY-39-001 | TODO | WEB-NOTIFY-38-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Surface digest scheduling, quiet-hour/throttle management, and simulation APIs; ensure rate limits and audit logging. |
| 4 | WEB-NOTIFY-40-001 | TODO | WEB-NOTIFY-39-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose escalation, localization, channel health, and ack verification endpoints with admin scope enforcement and signed token validation. |
| 5 | WEB-OAS-61-001 | TODO | Finalize gateway spec metadata | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Implement `GET /.well-known/openapi` returning gateway spec with version metadata, cache headers, and signed ETag. |
| 6 | WEB-OAS-61-002 | TODO | WEB-OAS-61-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Migrate gateway errors to standard envelope and update examples; ensure telemetry logs include `error.code`. |
| 7 | WEB-OAS-62-001 | TODO | WEB-OAS-61-002 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Normalize endpoints to cursor pagination, expose `Idempotency-Key` support, and document rate-limit headers. |
| 8 | WEB-OAS-63-001 | TODO | WEB-OAS-62-001 | BE-Base Platform Guild · API Governance Guild (`src/Web/StellaOps.Web`) | Add deprecation header middleware, Sunset link emission, and observability metrics for deprecated routes. |
| 9 | WEB-OBS-50-001 | TODO | Integrate StellaOps.Telemetry.Core into gateway host | BE-Base Platform Guild · Observability Guild (`src/Web/StellaOps.Web`) | Replace ad-hoc logging; ensure routes emit trace/span IDs, tenant context, and scrubbed payload previews. |
| 10 | WEB-OBS-51-001 | TODO | WEB-OBS-50-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Implement `/obs/health` and `/obs/slo` aggregations pulling Prometheus/collector metrics with burn-rate signals and exemplar links for Console widgets. |
| 11 | WEB-OBS-52-001 | TODO | WEB-OBS-51-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Deliver `/obs/trace/:id` and `/obs/logs` proxy endpoints with guardrails (time window limits, tenant scoping) forwarding to timeline indexer + log store with signed URLs. |
| 12 | WEB-OBS-54-001 | TODO | WEB-OBS-52-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Provide `/evidence/*` and `/attestations/*` pass-through endpoints, enforce `timeline:read`, `evidence:read`, `attest:read` scopes, append provenance headers, and surface verification summaries. |
| 13 | WEB-OBS-55-001 | TODO | WEB-OBS-54-001 | BE-Base Platform Guild · Ops Guild (`src/Web/StellaOps.Web`) | Add `/obs/incident-mode` API (enable/disable/status) with audit trail, sampling override, retention bump preview, and CLI/Console hooks. |
| 14 | WEB-OBS-56-001 | TODO | WEB-OBS-55-001 | BE-Base Platform Guild · AirGap Guild (`src/Web/StellaOps.Web`) | Extend telemetry core integration to expose sealed/unsealed status APIs, drift metrics, and Console widgets without leaking sealed-mode secrets. |
| 15 | WEB-ORCH-32-001 | TODO | Confirm orchestrator read-only API contract | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose read-only orchestrator APIs (e.g., `/orchestrator/sources`) via gateway with tenant scoping, caching headers, and rate limits. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized sprint to standard template and renamed from `SPRINT_214_web_iii.md`; preserved existing task list. | Project Mgmt |
## Decisions & Risks
- Notify, OAS, and Observability tracks are strictly sequential; later tasks should not start until predecessors complete to avoid schema drift.
- WEB-LNM-21-003 remains gated on WEB-LNM-21-002 delivering stable policy/VEX observation contracts.
- WEB-ORCH-32-001 depends on orchestrator API clarity; block if contracts are not published to avoid misaligned caching/rate-limit behavior.
- Ensure telemetry/error envelope updates are synchronized with downstream Console/CLI consumers to prevent breaking dashboards.
## Next Checkpoints
- Schedule dependency sync once WEB-LNM-21-002 contract drops (target week of 2025-12-02).
- Set notifier gateway review after WEB-NOTIFY-38-001 implementation notes are ready (target week of 2025-12-04).

View File

@@ -6,7 +6,7 @@
- **Working directory:** `src/UI/StellaOps.UI`
## Dependencies & Concurrency
- Upstream sprints: SPRINT_0209_0001_0001_ui_i (UI I), SPRINT_210_ui_ii (UI II - VEX tab).
- Upstream sprints: SPRINT_0209_0001_0001_ui_i (UI I), SPRINT_0210_0001_0002_ui_ii (UI II - VEX tab).
- Backend dependencies: Vuln Explorer APIs (`/v1/findings`, `/v1/vex-decisions`), Attestor service, Export Center.
- Parallel tracks: Can run alongside UI II/III for shared component work.
- Blockers to flag: VEX decision API schema finalization, Attestation viewer predicates.
@@ -26,7 +26,7 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | UI-TRIAGE-01-001 | TODO | - | UI Guild (src/UI/StellaOps.UI) | Create Artifacts List view with columns: Artifact, Type, Environment(s), Open/Total vulns, Max severity, Attestations badge, Last scan. Include sorting, filtering, and "View vulnerabilities" primary action. |
| 1 | UI-TRIAGE-01-001 | BLOCKED | UI workspace missing (src/UI/StellaOps.UI has no Angular project files) | UI Guild (src/UI/StellaOps.UI) | Create Artifacts List view with columns: Artifact, Type, Environment(s), Open/Total vulns, Max severity, Attestations badge, Last scan. Include sorting, filtering, and "View vulnerabilities" primary action. |
| 2 | UI-TRIAGE-01-002 | TODO | UI-TRIAGE-01-001 | UI Guild (src/UI/StellaOps.UI) | Build Vulnerability Workspace split layout: left panel with finding cards (CVE, package, severity, path), right panel with Explainability tabs (Overview, Reachability, Policy, Attestations). |
| 3 | UI-TRIAGE-01-003 | TODO | UI-TRIAGE-01-002 | UI Guild (src/UI/StellaOps.UI) | Implement evidence-first Finding Card component with severity badge, package info, location path, and primary actions (Fix PR, VEX, Attach Evidence). Include `New`, `VEX: Not affected`, `Policy: blocked` badges. |
| 4 | UI-TRIAGE-01-004 | TODO | UI-TRIAGE-01-003 | UI Guild (src/UI/StellaOps.UI) | Build Explainability Panel Overview tab: title, severity, package/version, scanner+DB date, finding history timeline, current VEX decision summary. |
@@ -61,9 +61,12 @@
| 33 | DTO-09-001 | TODO | SCHEMA-08-001 | API Guild | Create VexDecisionDto, SubjectRefDto, EvidenceRefDto, VexScopeDto, ValidForDto C# DTOs per advisory. |
| 34 | DTO-09-002 | TODO | SCHEMA-08-002 | API Guild | Create VulnScanAttestationDto, AttestationSubjectDto, VulnScanPredicateDto C# DTOs per advisory. |
| 35 | DTO-09-003 | TODO | SCHEMA-08-003 | API Guild | Create AuditBundleIndexDto, BundleArtifactDto, BundleVexDecisionEntryDto C# DTOs per advisory. |
| 36 | TS-10-001 | TODO | SCHEMA-08-001 | UI Guild | Create TypeScript interfaces for VexDecision, SubjectRef, EvidenceRef, VexScope, ValidFor per advisory. |
| 37 | TS-10-002 | TODO | SCHEMA-08-002 | UI Guild | Create TypeScript interfaces for VulnScanAttestation, AttestationSubject, VulnScanPredicate per advisory. |
| 38 | TS-10-003 | TODO | SCHEMA-08-003 | UI Guild | Create TypeScript interfaces for AuditBundleIndex, BundleArtifact, BundleVexDecisionEntry per advisory. |
| 36 | TS-10-001 | BLOCKED | UI workspace missing; schemas not present locally | UI Guild | Create TypeScript interfaces for VexDecision, SubjectRef, EvidenceRef, VexScope, ValidFor per advisory. |
| 37 | TS-10-002 | BLOCKED | UI workspace missing; schemas not present locally | UI Guild | Create TypeScript interfaces for VulnScanAttestation, AttestationSubject, VulnScanPredicate per advisory. |
| 38 | TS-10-003 | BLOCKED | UI workspace missing; schemas not present locally | UI Guild | Create TypeScript interfaces for AuditBundleIndex, BundleArtifact, BundleVexDecisionEntry per advisory. |
| 39 | DOC-11-001 | TODO | Product advisory doc sync | Docs Guild (docs/) | Update high-level positioning for VEX-first triage: refresh docs/key-features.md and docs/07_HIGH_LEVEL_ARCHITECTURE.md with UX/audit bundle narrative; link 28-Nov-2025 advisory. |
| 40 | DOC-11-002 | TODO | DOC-11-001 | Docs Guild; UI Guild | Update docs/modules/ui/architecture.md with triage workspace + VEX modal flows; add schema links and advisory cross-references. |
| 41 | DOC-11-003 | TODO | DOC-11-001 | Docs Guild; Vuln Explorer Guild; Export Center Guild | Update docs/modules/vuln-explorer/architecture.md and docs/modules/export-center/architecture.md with VEX decision/audit bundle API surfaces and schema references. |
## Wave Coordination
- **Wave A (Schemas & DTOs):** SCHEMA-08-*, DTO-09-*, TS-10-* - Foundation work
@@ -113,11 +116,15 @@
| Attestation service not ready | UI-ATT-* tasks blocked | Mock attestation data; feature flag attestation views |
| Export Center capacity | Audit bundle generation slow | Async generation with progress; queue management |
| Bulk VEX operations performance | UI-VEX-02-007 slow for large selections | Batch API endpoint; pagination; background processing |
| Advisory doc sync lag | Docs drift from UX/API decisions | Track DOC-11-* tasks; block release sign-off until docs updated |
| UI workspace absent | Blocks UI-TRIAGE-* and TS-10-* tasks | Restore Angular project under src/UI/StellaOps.UI or provide module path; rebaseline mocks |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint created from product advisory `28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md`. 38 tasks defined across 5 UI task groups, 2 API task groups, 3 schema tasks, 3 DTO tasks, 3 TS interface tasks. | Project mgmt |
| 2025-11-30 | Added DOC-11-* doc-sync tasks per advisory handling rules; no scope change to delivery waves. | Project mgmt |
| 2025-11-30 | Marked UI-TRIAGE-01-001 and TS-10-* tasks BLOCKED because src/UI/StellaOps.UI lacks Angular workspace; awaiting restoration to proceed. | UI Guild |
---
*Sprint created: 2025-11-28*

View File

@@ -1,54 +1,92 @@
# Sprint 0215-0001-0001 · Web IV (Experience & SDKs 180.F)
## Topic & Scope
- Phase IV web gateway work: orchestrator controls and Policy Studio CRUD/simulation endpoints aligned with Policy Engine.
- Complete policy pack lifecycle (CRUD → activation → publish/promote) with deterministic pagination, RBAC, and telemetry.
- Wire console/CLI consumers by keeping API docs and rate limits in sync with Sprint 180.F deliverables.
- **Working directory:** `src/Web/StellaOps.Web`.
## Dependencies & Concurrency
- Upstream Sprint 180.F (Web III) must land shared components before these endpoints go live.
- Policy endpoints (20-001 → 20-004) must complete in order; Policy pack tracks (23-001/002) stay BLOCKED until 20-004 ships.
- Policy registry/Studio extensions (27-001…27-005) are sequential; avoid parallel development without shared schema updates.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/policy/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | WEB-ORCH-33-001 | TODO | WEB-ORCH-32-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add POST action routes (pause/resume/backfill) for orchestrator-run control, honoring RBAC and audit logging. |
| 2 | WEB-ORCH-34-001 | TODO | WEB-ORCH-33-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose quotas/backfill APIs plus queue/backpressure metrics with admin scopes and error clustering. |
# Sprint 0215-0001-0001 · Web IV (Experience & SDKs 180.F)
## Topic & Scope
- Phase IV web gateway work: orchestrator controls and Policy Studio CRUD/simulation endpoints aligned with Policy Engine.
- Complete policy pack lifecycle (CRUD → activation → publish/promote) with deterministic pagination, RBAC, and telemetry.
- Wire console/CLI consumers by keeping API docs and rate limits in sync with Sprint 180.F deliverables.
- **Working directory:** `src/Web/StellaOps.Web`.
## Dependencies & Concurrency
- Upstream Sprint 180.F (Web III) must land shared components before these endpoints go live.
- Policy endpoints (20-001 → 20-004) must complete in order; Policy pack tracks (23-001/002) stay BLOCKED until 20-004 ships.
- Policy registry/Studio extensions (27-001…27-005) are sequential; avoid parallel development without shared schema updates.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/policy/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | WEB-ORCH-33-001 | TODO | WEB-ORCH-32-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add POST action routes (pause/resume/backfill) for orchestrator-run control, honoring RBAC and audit logging. |
| 2 | WEB-ORCH-34-001 | TODO | WEB-ORCH-33-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose quotas/backfill APIs plus queue/backpressure metrics with admin scopes and error clustering. |
| 3 | WEB-POLICY-20-001 | BLOCKED (2025-11-25) | Await Policy Engine REST contract + tenant/RBAC spec | BE-Base Platform Guild · Policy Guild (`src/Web/StellaOps.Web`) | Implement Policy CRUD/compile/run/simulate/findings/explain endpoints with OpenAPI + tenant scoping. |
| 4 | WEB-POLICY-20-002 | TODO | WEB-POLICY-20-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add pagination/filtering/sorting + tenant guards to policy listings with deterministic ordering diagnostics. |
| 5 | WEB-POLICY-20-003 | TODO | WEB-POLICY-20-002 | BE-Base Platform Guild · QA Guild (`src/Web/StellaOps.Web`) | Map engine errors to `ERR_POL_*` payloads with contract tests and correlation IDs. |
| 6 | WEB-POLICY-20-004 | TODO | WEB-POLICY-20-003 | Platform Reliability Guild (`src/Web/StellaOps.Web`) | Introduce adaptive rate limits/quotas for simulations, expose metrics, and document retry headers. |
| 7 | WEB-POLICY-23-001 | BLOCKED (2025-10-29) | WEB-POLICY-20-004 | BE-Base Platform Guild · Policy Guild (`src/Web/StellaOps.Web`) | Create/list/fetch policy packs and revisions with pagination, RBAC, and AOC metadata exposure. |
| 8 | WEB-POLICY-23-002 | BLOCKED (2025-10-29) | WEB-POLICY-23-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add activation endpoints with scope windows, conflict checks, optional two-person approvals, and events. |
| 9 | WEB-POLICY-23-003 | TODO | WEB-POLICY-23-002 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Provide `/policy/simulate` + `/policy/evaluate` streaming APIs with rate limiting and error mapping. |
| 10 | WEB-POLICY-23-004 | TODO | WEB-POLICY-23-003 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose explain history endpoints showing decision trees, consulted sources, and AOC chain. |
| 11 | WEB-POLICY-27-001 | TODO | WEB-POLICY-23-004 | BE-Base Platform Guild · Policy Registry Guild (`src/Web/StellaOps.Web`) | Proxy Policy Registry APIs (workspaces/versions/reviews) with tenant scoping, RBAC, and streaming downloads. |
| 12 | WEB-POLICY-27-002 | TODO | WEB-POLICY-27-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Implement review lifecycle endpoints (open/comment/approve/reject) with audit headers and pagination. |
| 13 | WEB-POLICY-27-003 | TODO | WEB-POLICY-27-002 | BE-Base Platform Guild · Scheduler Guild (`src/Web/StellaOps.Web`) | Expose quick/batch simulation endpoints with SSE progress streams, cursor pagination, and manifest downloads. |
| 14 | WEB-POLICY-27-004 | TODO | WEB-POLICY-27-003 | BE-Base Platform Guild · Security Guild (`src/Web/StellaOps.Web`) | Add publish/sign/promote/rollback endpoints with idempotent IDs, canary params, environment bindings, and events. |
| 15 | WEB-POLICY-27-005 | TODO | WEB-POLICY-27-004 | BE-Base Platform Guild · Observability Guild (`src/Web/StellaOps.Web`) | Instrument Policy Studio metrics/logs (compile latency, simulation queue depth, approvals, promotions) and dashboards. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-25 | Marked WEB-POLICY-20-001 BLOCKED: need Policy Engine REST contract + tenant/RBAC spec before wiring Angular/Web gateway endpoints. | Implementer |
| 2025-11-19 | Normalized sprint to standard template and migrated content from `SPRINT_215_web_iv.md`. | Project Mgmt |
| 4 | WEB-POLICY-20-002 | BLOCKED (2025-11-30) | WEB-POLICY-20-001 (blocked) | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add pagination/filtering/sorting + tenant guards to policy listings with deterministic ordering diagnostics. |
| 5 | WEB-POLICY-20-003 | BLOCKED (2025-11-30) | WEB-POLICY-20-002 (blocked) | BE-Base Platform Guild · QA Guild (`src/Web/StellaOps.Web`) | Map engine errors to `ERR_POL_*` payloads with contract tests and correlation IDs. |
| 6 | WEB-POLICY-20-004 | BLOCKED (2025-11-30) | WEB-POLICY-20-003 (blocked) | Platform Reliability Guild (`src/Web/StellaOps.Web`) | Introduce adaptive rate limits/quotas for simulations, expose metrics, and document retry headers. |
| 7 | WEB-POLICY-23-001 | BLOCKED (2025-10-29) | WEB-POLICY-20-004 | BE-Base Platform Guild · Policy Guild (`src/Web/StellaOps.Web`) | Create/list/fetch policy packs and revisions with pagination, RBAC, and AOC metadata exposure. |
| 8 | WEB-POLICY-23-002 | BLOCKED (2025-10-29) | WEB-POLICY-23-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add activation endpoints with scope windows, conflict checks, optional two-person approvals, and events. |
| 9 | WEB-POLICY-23-003 | BLOCKED (2025-11-30) | WEB-POLICY-23-002 (blocked until WEB-POLICY-20-004 ships) | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Provide `/policy/simulate` + `/policy/evaluate` streaming APIs with rate limiting and error mapping. |
| 10 | WEB-POLICY-23-004 | BLOCKED (2025-11-30) | WEB-POLICY-23-003 (blocked) | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose explain history endpoints showing decision trees, consulted sources, and AOC chain. |
| 11 | WEB-POLICY-27-001 | BLOCKED (2025-11-30) | WEB-POLICY-23-004 (blocked) | BE-Base Platform Guild · Policy Registry Guild (`src/Web/StellaOps.Web`) | Proxy Policy Registry APIs (workspaces/versions/reviews) with tenant scoping, RBAC, and streaming downloads. |
| 12 | WEB-POLICY-27-002 | BLOCKED (2025-11-30) | WEB-POLICY-27-001 (blocked) | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Implement review lifecycle endpoints (open/comment/approve/reject) with audit headers and pagination. |
| 13 | WEB-POLICY-27-003 | BLOCKED (2025-11-30) | WEB-POLICY-27-002 (blocked) | BE-Base Platform Guild · Scheduler Guild (`src/Web/StellaOps.Web`) | Expose quick/batch simulation endpoints with SSE progress streams, cursor pagination, and manifest downloads. |
| 14 | WEB-POLICY-27-004 | BLOCKED (2025-11-30) | WEB-POLICY-27-003 (blocked) | BE-Base Platform Guild · Security Guild (`src/Web/StellaOps.Web`) | Add publish/sign/promote/rollback endpoints with idempotent IDs, canary params, environment bindings, and events. |
| 15 | WEB-POLICY-27-005 | BLOCKED (2025-11-30) | WEB-POLICY-27-004 (blocked) | BE-Base Platform Guild · Observability Guild (`src/Web/StellaOps.Web`) | Instrument Policy Studio metrics/logs (compile latency, simulation queue depth, approvals, promotions) and dashboards. |
## Wave Coordination
- Wave 1: Orchestrator run-control (WEB-ORCH-33/34) follows WEB-ORCH-32-001 and can proceed independently of policy work.
- Wave 2: Policy Engine CRUD/simulation (WEB-POLICY-20-001…004) is strictly sequential and blocked on the REST contract + tenant/RBAC spec.
- Wave 3: Policy pack lifecycle (WEB-POLICY-23-001…004) begins only after Wave 2 exits with rate-limit design approved.
- Wave 4: Registry/Studio proxy and publishing (WEB-POLICY-27-001…005) proceeds after Wave 3 to avoid schema drift.
## Wave Detail Snapshots
| Wave | Covered tasks | Current state | Exit criteria | Blockers |
| --- | --- | --- | --- | --- |
| 1 | WEB-ORCH-33-001, WEB-ORCH-34-001 | TODO | POST run-control routes plus quotas/backfill metrics deployed with RBAC + audit logging | WEB-ORCH-32-001 readiness |
| 2 | WEB-POLICY-20-001…004 | BLOCKED | Policy CRUD/simulate endpoints with rate limits and error mapping published in OpenAPI | Policy Engine REST contract + tenant/RBAC spec; rate-limit design approval |
| 3 | WEB-POLICY-23-001…004 | BLOCKED | Policy pack CRUD/activation/simulate/evaluate with streaming responses and explain history | WEB-POLICY-20-004 completion and approval workflow design |
| 4 | WEB-POLICY-27-001…005 | BLOCKED | Registry proxy with reviews, publish/promote/rollback, and Studio observability dashboards | Wave 3 exit + shared registry schema/versioning plan |
## Interlocks
- Policy Engine REST contract + tenant/RBAC specification is required before any WEB-POLICY-20-* implementation.
- Platform Reliability must approve adaptive rate-limit design for simulations before publishing retry headers and CLI docs.
- Policy Registry schema/versioning alignment is needed to avoid rework in WEB-POLICY-27-001…005.
- Security Guild audit/RBAC checklist must be applied to orchestrator control routes prior to release.
## Upcoming Checkpoints
- 2025-12-02 · Receive Policy Engine REST contract + tenant/RBAC spec (Policy Guild) to unblock WEB-POLICY-20-001…004.
- 2025-12-03 · Platform Reliability rate-limit design review for simulations (slipped from 2025-11-22) to enable WEB-POLICY-20-004.
- 2025-12-06 · Go/no-go on policy pack CRUD/activation kickoff (WEB-POLICY-23-001/002) contingent on rate-limit approval.
- 2025-12-09 · Registry schema/versioning alignment for Studio proxy stream (WEB-POLICY-27-001 owner: Policy Registry Guild).
## Action Tracker
| # | Action | Owner | Due (UTC) | Status | Notes |
| --- | --- | --- | --- | --- | --- |
| 1 | Deliver Policy Engine REST contract + tenant/RBAC spec for web gateway | Policy Guild | 2025-12-02 | OPEN | Unblocks WEB-POLICY-20-001…004; required before any Angular wiring. |
| 2 | Confirm adaptive rate-limit design for simulations | Platform Reliability Guild | 2025-12-03 | OPEN | Gates WEB-POLICY-20-004 retry headers and quotas. |
| 3 | Publish RBAC/tenant alignment note for web gateway once contract lands | BE-Base Platform Guild | 2025-12-05 | PENDING | Follows Action #1; must precede policy pack work. |
| 4 | Lock Policy Registry schema/versioning plan for Studio proxy | Policy Registry Guild | 2025-12-09 | OPEN | Required before WEB-POLICY-27-001 streaming proxy. |
## Decisions & Risks
- Policy pack CRUD/activation (WEB-POLICY-23-001/002) remain BLOCKED until WEB-POLICY-20-004 rate-limit work lands.
- Registry/Studio chain (WEB-POLICY-27-001..005) must stay in order to keep schemas stable; avoid parallel merges without shared reviews.
- Ensure RBAC + tenant-scoping docs stay aligned with Policy Engine contracts to prevent drift during promotions.
- WEB-POLICY-20-001 blocked pending Policy Engine REST contract + tenant/RBAC specification; cannot scaffold Angular/web gateway endpoints without it.
## Next Checkpoints
- 2025-11-22 · Verify WEB-POLICY-20-004 rate-limit design review completed (Platform Reliability Guild).
- 2025-11-25 · Policy pack CRUD kickoff pending unblock from WEB-POLICY-20-004 (Policy Guild + BE-Base Platform Guild).
| ID | Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- | --- |
| R1 | Policy Engine REST contract/RBAC spec slips past 2025-12-02 | Blocks WEB-POLICY-20-001…004 and downstream pack work | Track Action #1; escalate to Policy Guild; keep OpenAPI placeholders out of main until contract arrives | Policy Guild | OPEN |
| R2 | Rate-limit design review delayed past 2025-12-03 | Simulation endpoints cannot expose quotas/headers; CLI docs drift | Track Action #2; freeze public docs until design approved; backfill metrics before enablement | Platform Reliability Guild | OPEN |
| R3 | Registry schema/versioning diverges from web proxy | Rework for WEB-POLICY-27-001…005; potential outage on streaming downloads | Track Action #4; pin schema versions and add contract tests before merge | Policy Registry Guild | OPEN |
| R4 | Orchestrator run-control released without audit/RBAC alignment | Post-release security gap and incomplete audit trail | Apply Security Guild checklist; add acceptance tests for RBAC + audit logging before Wave 1 exit | BE-Base Platform Guild | OPEN |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized to docs/implplan template (added waves, interlocks, action tracker); propagated BLOCKED statuses to downstream tasks and refreshed checkpoints. | Project Mgmt |
| 2025-11-25 | Marked WEB-POLICY-20-001 BLOCKED: need Policy Engine REST contract + tenant/RBAC spec before wiring Angular/Web gateway endpoints. | Implementer |
| 2025-11-19 | Normalized sprint to standard template and migrated content from `SPRINT_215_web_iv.md`. | Project Mgmt |

View File

@@ -0,0 +1,71 @@
# Sprint 0216-0001-0001 · Web V (Experience & SDKs 180.F)
## Topic & Scope
- Phase V gateway uplift: risk routing, signals reachability overlays, tenant scoping/ABAC, VEX consensus streaming, and vuln proxy/export telemetry.
- Active items only; completed/historic work moved to `docs/implplan/archived/tasks.md` (last updated 2025-11-08).
- Evidence: routed APIs with RBAC/ABAC, signed URL handling, reachability filters, notifier/ledger hooks, and gateway telemetry.
- **Working directory:** `src/Web/StellaOps.Web`.
## Dependencies & Concurrency
- Upstream: Sprint 180.F · Web IV must land shared gateway components before Web V endpoints ship.
- Respect chains: RISK (66-001 → 66-002 → 67-001 → 68-001), SIG (26-001 → 26-002 → 26-003), TENANT (47-001 → 48-001 → 49-001), VULN (29-001 → 29-002 → 29-003 → 29-004). Avoid parallel merges that violate these orders.
- Interlocks: Policy Engine contracts for ABAC overlay and reachability scoring; Notifications bus schema for severity transition events; Findings Ledger idempotency/correlation headers for vuln workflow forwarding.
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/ui/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | WEB-RISK-66-001 | TODO | Baseline gateway routing contract | BE-Base Platform Guild; Policy Guild (`src/Web/StellaOps.Web`) | Expose risk profile/results endpoints through gateway with tenant scoping, pagination, and rate limiting. |
| 2 | WEB-RISK-66-002 | TODO | WEB-RISK-66-001 | BE-Base Platform Guild; Risk Engine Guild (`src/Web/StellaOps.Web`) | Add signed URL handling for explanation blobs and enforce scope checks. |
| 3 | WEB-RISK-67-001 | TODO | WEB-RISK-66-002 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Provide aggregated risk stats (`/risk/status`) for Console dashboards (counts per severity, last computation). |
| 4 | WEB-RISK-68-001 | TODO | WEB-RISK-67-001; notifier bus schema | BE-Base Platform Guild; Notifications Guild (`src/Web/StellaOps.Web`) | Emit events on severity transitions via gateway to notifier bus with trace metadata. |
| 5 | WEB-SIG-26-001 | TODO | Signals API contract confirmation | BE-Base Platform Guild; Signals Guild (`src/Web/StellaOps.Web`) | Surface `/signals/callgraphs`, `/signals/facts` read/write endpoints with pagination, ETags, and RBAC. |
| 6 | WEB-SIG-26-002 | TODO | WEB-SIG-26-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Extend `/policy/effective` and `/vuln/explorer` responses to include reachability scores/states and allow filtering. |
| 7 | WEB-SIG-26-003 | TODO | WEB-SIG-26-002 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add reachability override parameters to `/policy/simulate` and related APIs for what-if analysis. |
| 8 | WEB-TEN-47-001 | TODO | JWT + tenant header contract freeze | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Implement JWT verification, tenant activation from headers, scope matching, and decision audit emission for all API endpoints. |
| 9 | WEB-TEN-48-001 | TODO | WEB-TEN-47-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Set DB session `stella.tenant_id`, enforce tenant/project checks on persistence, prefix object storage paths, and stamp audit metadata. |
| 10 | WEB-TEN-49-001 | TODO | WEB-TEN-48-001; Policy Engine ABAC overlay | BE-Base Platform Guild; Policy Guild (`src/Web/StellaOps.Web`) | Integrate optional ABAC overlay with Policy Engine, expose `/audit/decisions` API, and support service token minting endpoints. |
| 11 | WEB-VEX-30-007 | TODO | Tenant RBAC/ABAC policy definitions | BE-Base Platform Guild; VEX Lens Guild (`src/Web/StellaOps.Web`) | Route `/vex/consensus` APIs with tenant RBAC/ABAC, caching, and streaming; surface telemetry and trace IDs without gateway-side overlay logic. |
| 12 | WEB-VULN-29-001 | TODO | Tenant scoping model | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose `/vuln/*` endpoints via gateway with tenant scoping, RBAC/ABAC enforcement, anti-forgery headers, and request logging. |
| 13 | WEB-VULN-29-002 | TODO | WEB-VULN-29-001; Findings Ledger idempotency headers | BE-Base Platform Guild; Findings Ledger Guild (`src/Web/StellaOps.Web`) | Forward workflow actions to Findings Ledger with idempotency headers and correlation IDs; handle retries/backoff. |
| 14 | WEB-VULN-29-003 | TODO | WEB-VULN-29-002; export/simulation orchestrator | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Provide simulation and export orchestration routes with SSE/progress headers, signed download links, and request budgeting. |
| 15 | WEB-VULN-29-004 | TODO | WEB-VULN-29-003; observability dashboard specs | BE-Base Platform Guild; Observability Guild (`src/Web/StellaOps.Web`) | Emit gateway metrics/logs (latency, error rates, export duration), propagate query hashes for analytics dashboards. |
## Wave Coordination
- Single wave (Web V gateway + tenant hardening). Keep task order per dependency chains above; no parallel merges that alter schema/telemetry without shared reviews.
## Wave Detail Snapshots
- Not required (single wave). Progress captured in Delivery Tracker and Execution Log.
## Interlocks
- Policy Engine: ABAC overlay contract and reachability scoring must be stable before WEB-TEN-49-001 and WEB-SIG-26-002 proceed.
- Notifications: event schema for severity transitions required ahead of WEB-RISK-68-001.
- Findings Ledger: idempotency/correlation header contract required before WEB-VULN-29-002.
## Upcoming Checkpoints
- 2025-12-02 (UTC) · JWT/tenant header + ABAC overlay contract review (BE-Base Platform Guild · Policy Guild).
- 2025-12-04 (UTC) · Findings Ledger idempotency/correlation header alignment (BE-Base Platform Guild · Findings Ledger Guild).
- 2025-12-06 (UTC) · Notifications event schema review for severity transitions (BE-Base Platform Guild · Notifications Guild).
## Action Tracker
- Publish gateway routing/tenant header contract for WEB-TEN-47-001 (owner: BE-Base Platform Guild; due: 2025-12-02).
- Deliver Findings Ledger contract note (idempotency + correlation headers) for WEB-VULN-29-002 (owner: Findings Ledger Guild; due: 2025-12-04).
- Confirm notifier bus event schema for WEB-RISK-68-001 (owner: Notifications Guild; due: 2025-12-06).
## Decisions & Risks
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Tenant header/ABAC contract slips | Blocks WEB-TEN-47-001/48-001/49-001 and delays RBAC enforcement across routes | Lock contract by 2025-12-02; record in `docs/api/gateway/tenant-auth.md`; add blocking status if slip persists | BE-Base Platform Guild | Open |
| Findings Ledger idempotency headers unclear | WEB-VULN-29-002/003 cannot forward workflow actions safely | Obtain contract on 2025-12-04 checkpoint; add retries/backoff defaults once confirmed | Findings Ledger Guild | Open |
| Notifications event schema not finalized | WEB-RISK-68-001 cannot emit severity transition events with trace metadata | Schema review on 2025-12-06; use placeholder event name only after review | Notifications Guild | Open |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized sprint to standard template and renamed file from `SPRINT_216_web_v.md` to `SPRINT_0216_0001_0001_web_v.md`; no task status changes. | Project Mgmt |

View File

@@ -7,7 +7,7 @@
## Dependencies & Concurrency
- Upstream: Sprint 140 Runtime Signals, Sprint 185 Replay Core, Sprint 186 Scanner Record Mode, Sprint 187 Evidence & CLI Replay.
- reachbench fixture packs staged at repo root; must be relocated to `tests/reachability/fixtures/` during QA tasks.
- reachbench fixture packs relocated to `tests/reachability/fixtures/`; keep root staging clean and reuse deterministic manifests for CI.
## Documentation Prerequisites
- docs/11_DATA_SCHEMAS.md
@@ -21,21 +21,21 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | ZASTAVA-REACH-201-001 | DONE (2025-11-26) | Runtime facts emitter shipped in Observer | Zastava Observer Guild | Implement runtime symbol sampling in `StellaOps.Zastava.Observer` (EntryTrace-aware shell AST + build-id capture) and stream ND-JSON batches to Signals `/runtime-facts`, including CAS pointers for traces. Update runbook + config references. |
| 9 | GAP-ZAS-002 | BLOCKED (2025-11-26) | Align with task 1; runtime NDJSON schema | Zastava Observer Guild | Stream runtime NDJSON batches carrying `{symbol_id, code_id, hit_count, loader_base}` plus CAS URIs, capture build-ids/entrypoints, and draft the operator runbook (`docs/runbooks/reachability-runtime.md`). Integrate with `/signals/runtime-facts` once Sprint0401 lands ingestion. |
| 2 | SCAN-REACH-201-002 | DONE (2025-11-26) | Schema published: `docs/reachability/runtime-static-union-schema.md` (v0.1). Node + .NET lifters shipped with tests. | Scanner Worker Guild | Ship language-aware static lifters (JVM, .NET/Roslyn+IL, Go SSA, Node/Deno TS AST, Rust MIR, Swift SIL, shell/binary analyzers) in Scanner Worker; emit canonical SymbolIDs, CAS-stored graphs, and attach reachability tags to SBOM components. |
| 3 | SIGNALS-REACH-201-003 | DONE (2025-11-25) | Consume schema `docs/reachability/runtime-static-union-schema.md`; wire ingestion + CAS storage. | Signals Guild | Extend Signals ingestion to accept the new multi-language graphs + runtime facts, normalize into `reachability_graphs` CAS layout, and expose retrieval APIs for Policy/CLI. |
| 4 | SIGNALS-REACH-201-004 | DONE (2025-11-25) | Unblocked by 201-003; scoring engine can proceed using schema v0.1. | Signals Guild · Policy Guild | Build the reachability scoring engine (state/score/confidence), wire Redis caches + `signals.fact.updated` events, and integrate reachability weights defined in `docs/11_DATA_SCHEMAS.md`. |
| 5 | REPLAY-REACH-201-005 | DONE (2025-11-26) | Schema v0.1 available; update replay manifest/bundle to include CAS namespace + hashes per spec. | BE-Base Platform Guild | Update `StellaOps.Replay.Core` manifest schema + bundle writer so replay packs capture reachability graphs, runtime traces, analyzer versions, and evidence hashes; document new CAS namespace. |
| 6 | DOCS-REACH-201-006 | DONE (2025-11-26) | Requires outputs from 15 | Docs Guild | Author the reachability doc set (`docs/reachability/reachability.md`, `callgraph-formats.md`, `runtime-facts.md`, CLI/UI appendices) plus update Zastava + Replay guides with the new evidence and operator workflows. |
| 7 | QA-REACH-201-007 | DONE (2025-11-25) | Move fixtures + create evaluator harness | QA Guild | Integrate `reachbench-2025-expanded` fixture pack under `tests/reachability/fixtures/`, add evaluator harness tests that validate reachable vs unreachable cases, and wire CI guidance for deterministic runs. |
| 8 | GAP-SCAN-001 | BLOCKED (2025-11-26) | Richgraph-v1 schema not final; Scanner workspace currently dirty, unsafe to land symbolizer changes. | Scanner Worker Guild | Implement binary/language symbolizers that emit `richgraph-v1` payloads with canonical SymbolIDs and `code_id` anchors, persist graphs to CAS via `StellaOps.Scanner.Reachability`, and refresh analyzer docs/fixtures. |
| 8 | GAP-SCAN-001 | BLOCKED (2025-11-27) | Richgraph-v1 schema not final; Scanner workspace currently dirty, unsafe to land symbolizer changes. | Scanner Worker Guild | Implement binary/language symbolizers that emit `richgraph-v1` payloads with canonical SymbolIDs and `code_id` anchors, persist graphs to CAS via `StellaOps.Scanner.Reachability`, and refresh analyzer docs/fixtures. |
| 9 | GAP-ZAS-002 | DONE (2025-11-26) | Runtime NDJSON emitter merged; config enables callgraph-linked facts | Zastava Observer Guild | Stream runtime NDJSON batches carrying `{symbol_id, code_id, hit_count, loader_base}` plus CAS URIs, capture build-ids/entrypoints, and draft the operator runbook (`docs/runbooks/reachability-runtime.md`). Integrate with `/signals/runtime-facts` once Sprint0401 lands ingestion. |
| 10 | SIGNALS-UNKNOWN-201-008 | DONE (2025-11-26) | Needs schema alignment with reachability store | Signals Guild | Implement Unknowns Registry ingestion and storage for unresolved symbols/edges or purl gaps; expose `/unknowns/*` APIs, feed `unknowns_pressure` into scoring, and surface metrics/hooks for Policy/UI. |
| 11 | GRAPH-PURL-201-009 | BLOCKED (2025-11-26) | Depends on GAP-SCAN-001 and final richgraph-v1; pending stable symbolizer outputs. | Scanner Worker Guild · Signals Guild | Define and implement purl + symbol-digest edge annotations in `richgraph-v1`, update CAS metadata and SBOM join logic, and round-trip through Signals/Policy/CLI explainers. |
| 11 | GRAPH-PURL-201-009 | BLOCKED (2025-11-27) | Depends on GAP-SCAN-001 and final richgraph-v1; pending stable symbolizer outputs. | Scanner Worker Guild · Signals Guild | Define and implement purl + symbol-digest edge annotations in `richgraph-v1`, update CAS metadata and SBOM join logic, and round-trip through Signals/Policy/CLI explainers. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalised Delivery Tracker numbering, removed duplicate GAP-ZAS-002 row, and aligned statuses with Execution Log. | Project Mgmt |
| 2025-11-26 | Validated runtime facts builder: `dotnet test src/Zastava/__Tests/StellaOps.Zastava.Observer.Tests/StellaOps.Zastava.Observer.Tests.csproj --filter RuntimeFactsBuilderTests` restored and passed; Observer build clean. | Zastava Observer Guild |
| 2025-11-26 | Implemented runtime facts emitter in `StellaOps.Zastava.Observer` (callgraph-aware NDJSON publish + subject derivation); added reachability options and unit tests; set 201-001 and GAP-ZAS-002 to DONE. | Zastava Observer Guild |
| 2025-11-26 | Drafted runtime sampler runbook updates (config knobs, sampler rules, CAS trace pointers) in `docs/runbooks/reachability-runtime.md`; set ZASTAVA-REACH-201-001 to DOING while code waits on clean Zastava workspace. | Zastava Observer Guild |
@@ -61,7 +61,7 @@
## Decisions & Risks
- Schema v0.1 published at `docs/reachability/runtime-static-union-schema.md` (2025-11-23); treat as add-only. Breaking changes require version bump and mirrored updates in Signals/Replay.
- reachbench fixtures not yet relocated into tests tree; QA task 201-007 must complete before CI enablement.
- reachbench fixtures relocated to `tests/reachability/fixtures/` via QA-REACH-201-007; keep deterministic seeds and rerun CI guidance to confirm reproducibility on shared runners.
- Offline posture: ensure reachability pipelines avoid external downloads; rely on sealed/mock bundles.
- Unknowns Registry shipped (201-008): unknowns pressure applied to scoring; monitor schema adjustments from policy team for purl/digest merge (201-009) to avoid churn.
- purl + symbol-digest edge schema (201-009) depends on `richgraph-v1` finalization; may require updates to SBOM resolver and CLI explain flows.

View File

@@ -112,6 +112,7 @@
- Competitive/vision docs updated with reachability moat and vendor comparison; ensure sales/PMM references live in `docs/market/competitive-landscape.md` and `docs/reachability/lead.md`.
## Upcoming Checkpoints
- 2025-12-02 · richgraph-v1 schema/hash alignment (tasks 1, 11, 19) — Scanner, Platform, Replay guilds.
- Schedule go/no-go once Sprint 0400 readiness is confirmed (TBD, Planning).
- Align DSSE predicate review across Authority/Signer/Policy once task 12 schema draft is ready (TBD, Authority Guild).
@@ -120,6 +121,7 @@
| --- | --- | --- | --- | --- | --- |
| 1 | Capture checkpoint dates after Sprint 0400 closure signal. | Planning | TBD | Open | Waiting on Sprint 0400 readiness update. |
| 2 | Confirm CAS hash alignment (BLAKE3 + sha256 addressing) across Scanner/Replay/Signals. | Platform Guild | TBD | Open | Coordinate tasks 1 and 19. |
| 3 | Schedule richgraph-v1 schema/hash alignment and rebaseline sprint dates. | Planning · Platform Guild | 2025-12-02 | Open | Needed to unblock tasks 1, 11, 19 and address elapsed sprint window. |
## Decisions & Risks
- File renamed to `SPRINT_0401_0001_0001_reachability_evidence_chain.md` and normalized to template on 2025-11-22; scope unchanged.
@@ -132,10 +134,12 @@
| R4 | Edge-bundle Rekor volume or bundle count spikes. | Rekor congestion/cost; slower pipelines; CAS bloat. | Cap Rekor publishes per graph (task 54), default to CAS-only for bulk bundles, monitor Signals ingest size; add CI perf guard after task 55. |
| R5 | Bench/dataset tasks start before feed-freeze and schema alignment. | Non-replayable results; wasted bench runs. | Block tasks 5761 on published feed hashes + `richgraph-v1`/Unknowns schema; add gating checklist in task definitions. |
| R6 | Bench/dataset code not materialized (docs only). | Docs drift; no executable evidence for claims. | Tasks 5760 must produce runnable harnesses/fixtures under `docs/benchmarks/**` or `tests/**`; Execution Log to confirm artifact paths. |
| R7 | Sprint window (2025-11-11 → 2025-11-22) elapsed with key tasks still TODO/BLOCKED. | Scope drift and delayed handoff to Sprint 0402 polish. | Rebaseline schedule and checkpoints by 2025-12-02; gate starts on schema/hash decisions; Planning + Platform guilds. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Added R7 for elapsed sprint window, scheduled 2025-12-02 schema/hash alignment checkpoint, and logged Action Tracker item 3; no task status changes. | Project Mgmt |
| 2025-11-27 | Marked GRAPH-CAS-401-001, GAP-SYM-007, SCAN-REACH-401-009, and SCANNER-NATIVE-401-015 BLOCKED pending richgraph schema + Symbols Server contracts. | Project Mgmt |
| 2025-11-27 | Completed AUTH-REACH-401-005: added `StellaOps.Attestation` reference to Authority project; created `AuthoritySignerAdapter` to wrap ICryptoSigner as IAuthoritySigner; created `IAuthorityDsseStatementSigner` interface and `AuthorityDsseStatementSigner` service for signing In-toto statements with Authority's signing keys; service reuses existing DsseHelper.WrapAsync for DSSE envelope creation; fixed null-reference issue in DsseHelper.cs. Rekor mirroring leverages existing Attestor `IRekorClient` infrastructure. | Authority Guild |
| 2025-11-27 | Completed DSSE-LIB-401-020: `StellaOps.Attestation` library now packages Envelope primitives. Added `DsseEnvelopeExtensions.cs` with conversion utilities (`ToSerializableDict`, `FromBase64`, `GetPayloadString`, `GetPayloadBase64`). Envelope types (`DsseEnvelope`, `DsseSignature`, etc.) are exposed as transitive dependencies; consumers only need to reference `StellaOps.Attestation` to access both high-level InToto/DSSE helpers and low-level envelope primitives. Build verified. | Attestor Guild |

View File

@@ -32,7 +32,7 @@
| 4 | BENCH-CASES-PY-513-004 | DONE (2025-11-30) | Depends on 513-002. | Bench Guild · Python Track (`bench/reachability-benchmark/cases/py`) | Create 5-8 Python cases: Flask, Django, FastAPI. Include requirements.txt pinned, pytest oracles, coverage.py output. Delivered 5 cases: unsafe-exec (reachable), guarded-exec (unreachable), flask-template (reachable), fastapi-guarded (unreachable), django-ssti (reachable). |
| 5 | BENCH-CASES-JAVA-513-005 | BLOCKED (2025-11-30) | Depends on 513-002. | Bench Guild · Java Track (`bench/reachability-benchmark/cases/java`) | Create 5-8 Java cases: Spring Boot, Micronaut. Include pom.xml locked, JUnit oracles, JaCoCo coverage. Progress: 2/5 seeded (`spring-deserialize` reachable, `spring-guarded` unreachable); build/test blocked by missing JDK (`javac` not available in runner). |
| 6 | BENCH-CASES-C-513-006 | TODO | Depends on 513-002. | Bench Guild · Native Track (`bench/reachability-benchmark/cases/c`) | Create 3-5 C/ELF cases: small HTTP servers, crypto utilities. Include Makefile, gcov/llvm-cov coverage, deterministic builds (SOURCE_DATE_EPOCH). |
| 7 | BENCH-BUILD-513-007 | DOING | Depends on 513-003 through 513-006. | Bench Guild · DevOps Guild | Implement `build_all.py` and `validate_builds.py`: deterministic Docker builds, hash verification, SBOM generation (syft), attestation stubs. Progress: added scripts (hash check, deterministic ordering); SBOM/attestation stubs pending. |
| 7 | BENCH-BUILD-513-007 | DOING | Depends on 513-003 through 513-006. | Bench Guild · DevOps Guild | Implement `build_all.py` and `validate_builds.py`: deterministic Docker builds, hash verification, SBOM generation (syft), attestation stubs. Progress: added scripts (hash check, deterministic ordering) + README; added deterministic SBOM/attestation stubs; real syft/signing still pending. |
| 8 | BENCH-SCORER-513-008 | DONE (2025-11-30) | Depends on 513-002. | Bench Guild (`bench/reachability-benchmark/tools/scorer`) | Implement `rb-score` CLI: load cases/truth, validate submissions, compute precision/recall/F1, explainability score (0-3), runtime stats, determinism rate. |
| 9 | BENCH-EXPLAIN-513-009 | DONE (2025-11-30) | Depends on 513-008. | Bench Guild | Implement explainability scoring rules: 0=no context, 1=path with ≥2 nodes, 2=entry+≥3 nodes, 3=guards/constraints included. Unit tests for each level. |
| 10 | BENCH-BASELINE-SEMGREP-513-010 | TODO | Depends on 513-008 and cases. | Bench Guild | Semgrep baseline runner: `baselines/semgrep/run_case.sh`, rule config, output normalization to submission format. |
@@ -47,12 +47,19 @@
## Wave Coordination
| Wave | Guild owners | Shared prerequisites | Status | Notes |
| --- | --- | --- | --- | --- |
| W1 Foundation | Bench Guild · DevOps Guild | None | TODO | Tasks 1-2: Repo, schemas. |
| W2 Dataset | Bench Guild (per language track) | W1 complete | TODO | Tasks 3-7: Cases, builds. |
| W3 Scoring | Bench Guild | W1 complete | TODO | Tasks 8-9: Scorer, explainability (parallel with W2). |
| W1 Foundation | Bench Guild · DevOps Guild | None | DONE (2025-11-29) | Tasks 1-2 shipped: repo + schemas. |
| W2 Dataset | Bench Guild (per language track) | W1 complete | DOING | JS/PY cases DONE; Java BLOCKED (JDK); C TODO; builds DOING (SBOM stubs pending). |
| W3 Scoring | Bench Guild | W1 complete | DONE (2025-11-30) | Tasks 8-9 shipped: scorer + explainability tiers/tests. |
| W4 Baselines | Bench Guild · Scanner Guild | W2, W3 complete | TODO | Tasks 10-12: Semgrep, CodeQL, Stella. |
| W5 Publish | All Guilds | W4 complete | TODO | Tasks 13-17: CI, leaderboard, website, docs, launch. |
## Wave Detail Snapshots
- **W1 Foundation (DONE 2025-11-29):** Repo skeleton, licensing, schemas, validators landed; prerequisites satisfied for downstream tracks.
- **W2 Dataset (DOING):** JS/PY tracks complete; Java blocked on JDK>=17 in runner/CI; C track not started; build pipeline scripts exist but need SBOM/attestation stubs.
- **W3 Scoring (DONE 2025-11-30):** `rb-score` CLI, explainability tiers, and tests complete; ready to support baselines.
- **W4 Baselines (TODO):** Semgrep, CodeQL, and Stella runners not started; waiting on dataset/build stability and Sprint 0401 reachability for Stella.
- **W5 Publish (TODO):** CI, leaderboard, website, docs, and launch materials pending completion of baselines and build hardening.
## Interlocks
- Stella Ops baseline (task 12) requires Sprint 0401 reachability to be functional.
- Legal review needed for open-source licensing and third-party tool inclusion.
@@ -98,3 +105,5 @@
| 2025-11-30 | BLOCKED BENCH-CASES-JAVA-513-005: `javac`/JDK not available in runner; Java builds/tests cannot execute. Need JDK (>=17) in CI/runner before unblocking. | Implementer |
| 2025-11-30 | BENCH-EXPLAIN-513-009 DONE: added explainability tier tests (03) to scorer; tiers already implemented (guards→3, entry+path>=3→2, path>=2→1, else 0). | Implementer |
| 2025-11-30 | BENCH-BUILD-513-007 DOING: added `tools/build/build_all.py` and `tools/build/validate_builds.py` for deterministic builds and hash checks; SBOM/attestation stubs still pending. | Implementer |
| 2025-11-30 | Normalised sprint doc to template: updated wave statuses to reflect task reality and added Wave Detail Snapshots. | PM |
| 2025-11-30 | BENCH-BUILD-513-007: build_all/validate_builds run; all JS/PY cases deterministic, Java cases fail due to missing `javac` (same blocker as task 5). | Implementer |

View File

@@ -1,33 +1,60 @@
# Sprint 187 - Replay Delivery · 187.A) Evidence Locker & CLI Integration
# Sprint 0187-0001-0001 · Evidence Locker & CLI Integration (Replay Delivery 187.A)
[Replay Delivery] 187.A) Evidence Locker & CLI Integration
Depends on: Sprint 186 Scanner Record Mode, Sprint 160 Export & Evidence, Sprint 180 Experience & SDKs
Summary: Persist replay bundles in Evidence Locker, expose ledger-backed verification, and ship offline-ready CLI workflows.
## Topic & Scope
- Persist replay bundles in Evidence Locker, expose ledger-backed verification, and ship offline-ready CLI workflows.
- Cover ingestion/retention APIs, CLI replay/verify/diff commands, attestor anchoring, ops runbook, and validation harness.
- **Working directory:** `docs/implplan` (coordination); code paths: `src/EvidenceLocker`, `src/Cli`, `src/Attestor`, `docs/**`.
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
EVID-REPLAY-187-001 | TODO | Implement replay bundle ingestion/retention APIs in Evidence Locker (WebService + Worker) and document storage/retention rules in `docs/modules/evidence-locker/architecture.md`, referencing `docs/replay/DETERMINISTIC_REPLAY.md` Sections 2 & 8. | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, `docs/modules/evidence-locker/architecture.md`)
CLI-REPLAY-187-002 | TODO | Add `scan --record`, `verify`, `replay`, `diff` commands to the CLI with offline bundle resolution; update `docs/modules/cli/architecture.md` and add a replay commands appendix citing `docs/replay/DEVS_GUIDE_REPLAY.md`. | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, `docs/modules/cli/architecture.md`)
ATTEST-REPLAY-187-003 | TODO | Wire Attestor/Rekor anchoring for replay manifests and capture verification APIs; extend `docs/modules/attestor/architecture.md` with a replay ledger flow referencing `docs/replay/DETERMINISTIC_REPLAY.md` Section 9. | Attestor Guild (`src/Attestor/StellaOps.Attestor`, `docs/modules/attestor/architecture.md`)
RUNBOOK-REPLAY-187-004 | TODO | Publish `/docs/runbooks/replay_ops.md` covering retention enforcement, RootPack rotation, offline kits, and verification drills; cross-link from replay specification summary. | Docs Guild, Ops Guild (`docs`)
VALIDATE-BUNDLE-187-005 | TODO | Deliver `VALIDATION_PLAN.md`, harness scripts (A/B quiet vs baseline, provenance bundle export), and a `stella bundle verify` CLI subcommand that checks DSSE/Rekor/SBOM/policy/replay claims end-to-end for offline audits. | QA Guild · CLI Guild · Docs Guild (`docs/validation`, `scripts/validation`, `src/Cli/StellaOps.Cli`)
EVID-CRYPTO-90-001 | TODO | Route Evidence Locker hashing/signing (manifest digests, DSSE assembly, bundle encryption) through `ICryptoProviderRegistry`/`ICryptoHash` so sovereign profiles (e.g., `ru-offline`) can swap providers per `docs/security/crypto-routing-audit-2025-11-07.md`. | Evidence Locker Guild, Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`)
## Dependencies & Concurrency
- Upstream: Sprint 0186 (Scanner Record Mode) payload stability; Sprint 0160/0161 EvidenceLocker schema freeze; Orchestrator/Notifications capsules.
- Sovereign crypto readiness review (2025-11-18) must approve provider registry usage.
- Concurrency: run tasks after EvidenceLocker API/schema freeze; Attestor/CLI depend on EvidenceLocker APIs; validation harness last.
> 2025-11-03: `/docs/runbooks/replay_ops.md` created — Evidence Locker, CLI, Attestor teams can transition replay delivery tasks to **DOING** alongside Ops runbook rehearsals.
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/modules/evidence-locker/architecture.md
- docs/modules/cli/architecture.md
- docs/modules/attestor/architecture.md
- docs/replay/DETERMINISTIC_REPLAY.md
## Task snapshot (2025-11-12)
- EvidenceLocker: `EVID-REPLAY-187-001` (replay ingestion/retention) and `EVID-CRYPTO-90-001` (sovereign crypto).
- CLI/Docs: `CLI-REPLAY-187-002` plus `RUNBOOK-REPLAY-187-004` ensure offline workflows + ops readiness.
- Attestor: `RUNBOOK-REPLAY-187-003` documents replay ledger integration with DSSE/attest flows.
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | EVID-REPLAY-187-001 | BLOCKED (2025-11-30) | Blocked by Scanner record payload + EvidenceLocker schema freeze (Sprint 0161) and orchestrator capsules. | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, `docs/modules/evidence-locker/architecture.md`) | Implement replay bundle ingestion/retention APIs in Evidence Locker (WebService + Worker) and document storage/retention rules in `docs/modules/evidence-locker/architecture.md`, referencing `docs/replay/DETERMINISTIC_REPLAY.md` §§2,8. |
| 2 | CLI-REPLAY-187-002 | BLOCKED (2025-11-30) | Blocked by 187-001 API schema freeze and Scanner record payloads. | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, `docs/modules/cli/architecture.md`) | Add `scan --record`, `verify`, `replay`, `diff` commands to the CLI with offline bundle resolution; update CLI architecture and replay appendix citing `docs/replay/DEVS_GUIDE_REPLAY.md`. |
| 3 | ATTEST-REPLAY-187-003 | BLOCKED (2025-11-30) | Blocked by 187-001; needs EvidenceLocker manifest schema for anchoring. | Attestor Guild (`src/Attestor/StellaOps.Attestor`, `docs/modules/attestor/architecture.md`) | Wire Attestor/Rekor anchoring for replay manifests and capture verification APIs; extend Attestor architecture with replay ledger flow referencing `docs/replay/DETERMINISTIC_REPLAY.md` §9. |
| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED (2025-11-30) | Blocked by 187-001/002 outputs to document final workflows. | Docs Guild · Ops Guild (`docs/runbooks/replay_ops.md`) | Publish replay ops runbook covering retention enforcement, RootPack rotation, offline kits, and verification drills; cross-link from replay spec summary. |
| 5 | VALIDATE-BUNDLE-187-005 | BLOCKED (2025-11-30) | Blocked by 187-001/002 schema and attestor anchoring decisions. | QA Guild · CLI Guild · Docs Guild (`docs/validation`, `scripts/validation`, `src/Cli/StellaOps.Cli`) | Deliver `VALIDATION_PLAN.md`, harness scripts (A/B quiet vs baseline, provenance bundle export), and `stella bundle verify` CLI subcommand that checks DSSE/Rekor/SBOM/policy/replay claims end-to-end for offline audits. |
| 6 | EVID-CRYPTO-90-001 | BLOCKED (2025-11-30) | Await crypto registry readiness signal (Nov-18 review) and EvidenceLocker schema alignment. | Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Route Evidence Locker hashing/signing (manifest digests, DSSE assembly, bundle encryption) through `ICryptoProviderRegistry`/`ICryptoHash` per `docs/security/crypto-routing-audit-2025-11-07.md`. |
## Dependencies & blockers
- Tied to Sprint 160 wave progress (EvidenceLocker DSSE schema + orchestrator capsule events).
- Requires Scanner Record Mode (Sprint 186) payload stability to drive replay ingestion.
- CLI/Attestor work depends on EvidenceLocker API schema freeze.
- Sovereign crypto readiness review on 2025-11-18 must approve provider registry usage.
## Interlocks & Readiness Signals
| Dependency | Impacts | Status / Next signal |
| --- | --- | --- |
| Scanner record payload/schema (Sprint 0186) | Tasks 15 | Pending; need stable replay manifest and bundle layout to proceed. |
| EvidenceLocker DSSE/manifest schema (Sprint 0161) + orchestrator/notification capsules | Tasks 15 | Pending; require frozen schema/envelopes. |
| Sovereign crypto routing review (2025-11-18) | Task 6 | Pending confirmation of provider registry usage. |
## Action Tracker
| # | Action | Owner | Due (UTC) | Status |
| --- | --- | --- | --- | --- |
| 1 | Pull stable replay bundle sample from Scanner (Sprint 0186) and attach to sprint doc. | Evidence Locker Guild | 2025-12-03 | OPEN |
| 2 | Capture EvidenceLocker replay API draft (paths, payloads) once schema freezes and link here. | Evidence Locker Guild | 2025-12-04 | OPEN |
| 3 | Align CLI command surface with replay API/manifest sample; note offline behaviors. | DevEx/CLI Guild | 2025-12-05 | OPEN |
| 4 | Add validation harness outline with DSSE/Rekor/SBOM/policy checks tied to replay bundle sample. | QA Guild | 2025-12-05 | OPEN |
## Decisions & Risks
| Risk / Decision | Impact | Mitigation / Next Step | Status |
| --- | --- | --- | --- |
| Replay payloads/schemas not yet frozen (Scanner 0186, EvidenceLocker 0161). | Blocks all 187 tasks. | Track Actions 12; keep tasks BLOCKED until sample + schema land. | OPEN |
| CLI surface cannot be finalized without replay manifest structure. | Blocks CLI-REPLAY-187-002 and VALIDATE-BUNDLE-187-005. | Action 3; attach schema once available. | OPEN |
| Validation harness depends on attestor anchoring flow. | Blocks VALIDATE-BUNDLE-187-005. | Align after Actions 13; keep BLOCKED. | OPEN |
| Sovereign crypto routing not confirmed for replay bundles. | Blocks EVID-CRYPTO-90-001. | Await 2025-11-18 review outcome; mirror decisions into EvidenceLocker options. | OPEN |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized sprint to standard template; set all tasks to BLOCKED pending Scanner/EvidenceLocker schema and crypto readiness; added interlocks/actions/risks. | Implementer |
| 2025-11-03 | `/docs/runbooks/replay_ops.md` created — teams may start ops rehearsal once schemas land. | Ops Guild |
## Ready-to-start checklist
1. Capture sample replay bundle payloads from Scanner record mode for CLI + Attestor reference.
2. Align EvidenceLocker API design with Replay Delivery + Ops teams, documenting endpoints before coding.
3. Schedule joint review covering `/docs/runbooks/replay_ops.md` with EvidenceLocker, CLI, Attestor, Ops.
4. Confirm `ICryptoProviderRegistry` coverage for replay bundle signing/encryption ahead of the Nov-18 review.

View File

@@ -1,16 +1,71 @@
# Sprint 200 - Experience & SDKs
# Sprint 0200-0001-0001 · Experience & SDKs Snapshot
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
## Topic & Scope
- Snapshot of Experience & SDKs stream (waves 180.AF); active backlog now lives in later sprints (201+).
- Maintain visibility of wave readiness while upstream dependencies land.
- **Working directory:** `docs/implplan` (coordination only).
This file now only tracks the Experience & SDKs status snapshot. Active backlog lives in Sprint 201 and later files.
## Dependencies & Concurrency
- Upstream gating sprints: 120.A (AirGap), 130.A (Scanner), 150.A (Orchestrator), 170.A (Notifier), 141 (Graph Indexer for 180.C).
- All waves remain TODO until upstream APIs/contracts finalize; no concurrent execution planned.
## Wave coordination
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/implplan/AGENTS.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | EXP-SNAPSHOT-200 | TODO | Keep wave readiness current; migrate active items to sprint 201+. | Project Mgmt · Experience Guild | Maintain Experience & SDKs status snapshot; no implementation tracked here. |
## Wave Coordination
| Wave | Guild owners | Shared prerequisites | Status | Notes |
| --- | --- | --- | --- | --- |
| 180.A CLI | DevEx/CLI Guild · Advisory AI Guild (for CLI verbs) · Evidence Locker Guild | Sprint 120.A AirGap; Sprint 130.A Scanner; Sprint 150.A Orchestrator; Sprint 170.A Notifier | TODO | Commands stay blocked on orchestrator + notifier scopes; finalize auth/output scaffolding so we can flip to DOING quickly. |
| 180.B DevPortal | Developer Portal Guild · SDK Generator Guild · Platform Guild | Sprint 120.A AirGap; Sprint 130.A Scanner; Sprint 150.A Orchestrator; Sprint 170.A Notifier | TODO | Static site generator selection is pending; coordinate with CLI/SDK teams for shared examples. |
| 180.C Graph Experiences (CLI/SDK) | Graph Guild · SDK Generator Guild · Policy Guild | Sprint 120.A AirGap; Sprint 130.A Scanner; Sprint 150.A Orchestrator; Sprint 170.A Notifier | TODO | Wait on Graph Indexer APIs from Sprint 141 before wiring SDK quickstarts. |
| 180.D SDK | SDK Generator Guild · Service Guilds providing OpenAPI | Sprint 120.A AirGap; Sprint 130.A Scanner; Sprint 150.A Orchestrator; Sprint 170.A Notifier | TODO | Downstream of orchestrator/export OAS consolidation; keep templates updated. |
| 180.E UI | UI Guild · Console Guild · Notifications Guild | Sprint 120.A AirGap; Sprint 130.A Scanner; Sprint 150.A Orchestrator; Sprint 170.A Notifier | TODO | Exception center & graph canvas rely on policy/graph APIs; hold until upstream signals stabilize. |
| 180.F Web | BE-Base Platform Guild · Platform Events Guild · Notifications Guild | Sprint 120.A AirGap; Sprint 130.A Scanner; Sprint 150.A Orchestrator; Sprint 170.A Notifier | TODO | Gateway routing can start once AdvisoryAI/Export endpoints finalize; prepare guard helpers now. |
| 180.A CLI | DevEx/CLI Guild · Advisory AI Guild · Evidence Locker Guild | Sprint 120.A AirGap; 130.A Scanner; 150.A Orchestrator; 170.A Notifier | TODO | Commands blocked on orchestrator + notifier scopes; finalize auth/output scaffolding to flip to DOING. |
| 180.B DevPortal | Developer Portal Guild · SDK Generator Guild · Platform Guild | Same as above | TODO | Static site generator selection pending; align examples with CLI/SDK teams. |
| 180.C Graph Experiences (CLI/SDK) | Graph Guild · SDK Generator Guild · Policy Guild | Same as above + Sprint 141 Graph Indexer APIs | TODO | Wait on Graph Indexer APIs before wiring SDK quickstarts. |
| 180.D SDK | SDK Generator Guild · Service Guilds providing OpenAPI | Same as above | TODO | Downstream of orchestrator/export OAS consolidation; keep templates updated. |
| 180.E UI | UI Guild · Console Guild · Notifications Guild | Same as above | TODO | Exception center & graph canvas rely on policy/graph APIs; hold until upstream signals stabilize. |
| 180.F Web | BE-Base Platform Guild · Platform Events Guild · Notifications Guild | Same as above | TODO | Gateway routing can start once AdvisoryAI/Export endpoints finalize; prepare guard helpers now. |
## Wave Detail Snapshots
| Wave | Entry criteria | Exit evidence | Notes |
| --- | --- | --- | --- |
| 180.A CLI | Orchestrator + Notifier scopes finalized; auth/output scaffolding approved. | CLI verbs implemented for new scopes; determinism tests passing; docs synced. | Track in Sprint 201+. |
| 180.B DevPortal | Static site generator chosen; shared examples sourced; platform routing approved. | DevPortal sections published with examples; CI build green. | Track in Sprint 201+. |
| 180.C Graph Exp | Graph Indexer APIs (Sprint 141) stable; policy contracts approved. | SDK/CLI quickstarts for graph queries published; regression tests passing. | Track in Sprint 201+. |
| 180.D SDK | Consolidated OAS from services published; SDK templates refreshed. | SDKs generated with pinned versions and offline bundles; smoke tests pass. | Track in Sprint 201+. |
| 180.E UI | Policy/graph APIs stable; notifier integration contract signed. | Exception center & graph canvas shipped behind feature flag; UX docs updated. | Track in Sprint 201+. |
| 180.F Web | AdvisoryAI/Export endpoints finalized; gateway guard helpers ready. | Web gateway routing committed with guards; incident/webhook paths tested. | Track in Sprint 201+. |
## Interlocks
- Orchestrator + Notifier scopes for CLI verbs.
- Graph Indexer API availability (Sprint 141) for 180.C.
- OAS consolidation for SDK generation (180.D).
- Platform routing/guards for Web/UI experiences (180.E/F).
## Upcoming Checkpoints
- 2025-12-07 · Review upstream sprint signals (141/150/170) and decide which waves move to Sprint 201.
## Action Tracker
| ID | Action | Owner | Due (UTC) | Status | Notes |
| --- | --- | --- | --- | --- | --- |
| AT-01 | Collect upstream readiness signals (141/150/170) and propose Sprint 201 wave starts. | Project Mgmt | 2025-12-07 | TODO | Source signals from sprint execution logs. |
| AT-02 | Confirm static site generator choice for DevPortal wave. | DevPortal Guild | 2025-12-07 | TODO | Needed before moving wave 180.B to DOING. |
## Decisions & Risks
- Experience waves remain paused pending upstream API/contracts; track readiness rather than implementation here.
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Upstream Orchestrator/Notifier scopes slip. | Delays CLI/Web experience delivery. | Pull scope signals weekly; shift to Sprint 201 once stable. | Project Mgmt | OPEN |
| Graph Indexer APIs unstable. | SDK/CLI graph quickstarts would rework. | Gate 180.C until Sprint 141 publishes stable APIs. | Project Mgmt | OPEN |
| DevPortal generator choice stalls content. | Docs/SDK examples miss deadlines. | AT-02 to choose generator; reuse CLI/SDK examples for consistency. | DevPortal Guild | OPEN |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalized to docs/implplan template; added delivery tracker placeholder, wave details, interlocks, actions, risks. | Project Mgmt |
| 2025-11-08 | Archived completed items to `docs/implplan/archived/tasks.md`; file now tracks status snapshot only. | Project Mgmt |

View File

@@ -1,26 +1,5 @@
# Sprint 202 - Experience & SDKs · 180.A) Cli.II
# Redirect Notice · Sprint 202
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
This sprint was normalized and renamed to `docs/implplan/SPRINT_0202_0001_0001_cli_ii.md` (2025-11-30).
[Experience & SDKs] 180.A) Cli.II
Depends on: Sprint 180.A - Cli.I
Summary: Experience & SDKs focus on Cli (phase II).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
CLI-CORE-41-001 | DONE (2025-11-28) | Implemented CLI core features: `OutputRenderer` (json/yaml/table), `CliProfile`/`CliProfileManager` (profiles/contexts), `CliError`/`CliErrorCodes` (error mapping), `GlobalOptions` (global flags with --profile, --output, --verbose, --quiet, --no-color, --dry-run). Config precedence already exists in `CliBootstrapper`. Auth flows already exist via `StellaOps.Auth.Client`. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-EXC-25-001 | DONE (2025-11-28) | Implemented `stella exceptions list/show/create/promote/revoke/import/export` commands for exception governance. Created `ExceptionModels.cs` with full models for exception instances, scopes, effects, evidence refs, lifecycle states (draft/staged/active/expired/revoked), and request/response types. Created `IExceptionClient.cs` interface and `ExceptionClient.cs` HTTP client with token caching for all CRUD operations plus import/export. Added command handlers with JSON/table output, status-colored rendering, verbose mode with evidence/approval details, and `ERR_EXC_*` error codes (exit code 16). | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-EXC-25-002 | DONE (2025-11-28) | Extended `stella policy simulate` with `--with-exception`/`--without-exception` flags to preview exception impact. Added repeatable options for exception IDs, validation to prevent overlapping IDs in both lists, verbose logging of exception preview mode, and OpenTelemetry tracing of exception counts. Updated `PolicySimulationInput` record with optional `WithExceptions`/`WithoutExceptions` fields. Dependencies: CLI-EXC-25-001. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-EXPORT-35-001 | BLOCKED (2025-10-29) | Implement `stella export profiles | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-EXPORT-36-001 | TODO | Add distribution commands (`stella export distribute`, `run download --resume` enhancements) and improved status polling with progress bars. Dependencies: CLI-EXPORT-35-001. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-EXPORT-37-001 | TODO | Provide scheduling (`stella export schedule`), retention, and `export verify` commands performing signature/hash validation. Dependencies: CLI-EXPORT-36-001. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-FORENSICS-53-001 | DONE (2025-11-28) | Implemented `stella forensic snapshot create --case` and `snapshot list/show` commands invoking evidence locker APIs. Created `ForensicSnapshotModels.cs` with full document/manifest/artifact models, `IForensicSnapshotClient.cs` interface, `ForensicSnapshotClient.cs` HTTP client with token caching, and command handlers in `CommandHandlers.cs` with JSON/table output. | DevEx/CLI Guild, Evidence Locker Guild (src/Cli/StellaOps.Cli)
CLI-FORENSICS-54-001 | DONE (2025-11-28) | Implemented `stella forensic verify <bundle>` command validating checksums, DSSE signatures, and timeline chain-of-custody. Created `ForensicVerificationModels.cs` with verification result models, `IForensicVerifier.cs` interface, `ForensicVerifier.cs` with SHA256/384/512 checksum verification, RSA-PSS signature verification, and chain-of-custody timeline validation. Added `ERR_FORENSIC_*` error codes (exit code 12), JSON/pretty output, and verbose mode with detailed tables. | DevEx/CLI Guild, Provenance Guild (src/Cli/StellaOps.Cli)
CLI-FORENSICS-54-002 | DONE (2025-11-28) | Implemented `stella forensic attest show <artifact>` listing attestation details (signer, timestamp, subjects) and verifying signatures. Created `AttestationModels.cs` with DSSE/in-toto models, `IAttestationReader.cs` interface, `AttestationReader.cs` with PAE encoding, RSA-PSS verification, predicate parsing (SLSA/VEX), and rich console output with subject/signature tables. | DevEx/CLI Guild, Provenance Guild (src/Cli/StellaOps.Cli)
CLI-PROMO-70-001 | DONE (2025-11-28) | Implemented `stella promotion assemble` command that resolves image digests (via crane/cosign), hashes SBOM/VEX artifacts with format detection (CycloneDX/SPDX, OpenVEX/CSAF), and emits the `stella.ops/promotion@v1` JSON payload. Created `PromotionModels.cs` with full predicate/subject/material/metadata models, `IPromotionAssembler.cs` interface, `PromotionAssembler.cs` with image digest resolution, SHA256 file hashing, SBOM/VEX format detection, and JSON output. Command supports `--image`, `--sbom`, `--vex`, `--from/--to` environment, `--actor`, `--ticket`, `--notes`, `--skip-rekor`, and `--output` options. | DevEx/CLI Guild, Provenance Guild (src/Cli/StellaOps.Cli)
CLI-DETER-70-003 | DONE (2025-11-28) | Implemented `stella detscore run` command that executes the determinism harness locally with fixed clock, seeded RNG, and canonical hashes. Created `DeterminismModels.cs` with manifest/request/result models per SCAN-DETER-186-010 schema, `IDeterminismHarness.cs` interface, `DeterminismHarness.cs` with Docker container execution, SHA256 artifact hashing, score calculation, and threshold verification. Command supports `--image`, `--scanner`, `--policy-bundle`, `--feeds-bundle`, `--runs`, `--fixed-clock`, `--rng-seed`, `--max-concurrency`, `--memory`, `--cpuset`, `--platform`, `--image-threshold`, `--overall-threshold`, `--output-dir`, `--release`, and `--json` options. Added `ERR_DETER_*` error codes (exit code 13). | DevEx/CLI Guild, Scanner Guild (src/Cli/StellaOps.Cli)
CLI-LNM-22-001 | DONE (2025-11-28) | Implemented `stella advisory obs get/linkset show/export` commands with JSON/OSV output, pagination, conflict display, and `ERR_AGG_*` error code mapping. Added `AdvisoryLinksetModels.cs` with OSV format support, extended `IConcelierObservationsClient` with `GetLinksetAsync`/`GetObservationByIdAsync`, and added command handlers for all three subcommands. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-LNM-22-002 | DONE (2025-11-28) | Implemented `stella vex obs get/linkset show` commands with product/status/provider filters, pagination, and JSON output for CI usage. Created `VexObservationModels.cs` with query/response/linkset models, `IVexObservationsClient.cs` interface, `VexObservationsClient.cs` HTTP client with VexRead scope, and command handlers with rich table output, conflict detection, and aggregate summaries. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-NOTIFY-38-001 | BLOCKED (2025-10-29) | Implement `stella notify rules | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-NOTIFY-39-001 | BLOCKED (2025-10-29) | Add simulation (`stella notify simulate`) and digest commands with diff output and schedule triggering, including dry-run mode. Dependencies: CLI-NOTIFY-38-001. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-NOTIFY-40-001 | TODO | Provide ack token redemption workflow, escalation management, localization previews, and channel health checks. Dependencies: CLI-NOTIFY-39-001. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
CLI-OBS-50-001 | DONE (2025-11-28) | Implemented `TraceparentHttpMessageHandler` that propagates W3C Trace Context headers for all HTTP requests, logs correlation IDs on failure, records trace IDs in verbose logs (scrubbed), and includes `AddTraceparentPropagation()` extension method for IHttpClientBuilder. | DevEx/CLI Guild (src/Cli/StellaOps.Cli)
Please edit the canonical file only. This legacy filename is retained to prevent divergent updates.

View File

@@ -1,32 +0,0 @@
# Sprint 210 - Experience & SDKs · 180.E) UI.II
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.E) UI.II
Depends on: Sprint 180.E - UI.I
Summary: Experience & SDKs focus on UI (phase II).
## Related Sprints & Advisories
- **SPRINT_0215_0001_0001_vuln_triage_ux.md** - Comprehensive vulnerability triage UX with VEX-first decisioning
- **Advisory:** `28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md`
- **Schemas:** `docs/schemas/vex-decision.schema.json`, `docs/schemas/audit-bundle-index.schema.json`
Note: UI-LNM-22-003 (VEX tab) should align with VEX decision model defined in SPRINT_0215. The VEX modal and decision workflows are detailed in the new sprint.
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
UI-LNM-22-002 | TODO | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | UI Guild (src/UI/StellaOps.UI)
UI-LNM-22-003 | TODO | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | UI Guild, Excititor Guild (src/UI/StellaOps.UI)
UI-LNM-22-004 | TODO | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | UI Guild (src/UI/StellaOps.UI)
UI-ORCH-32-001 | TODO | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | UI Guild, Console Guild (src/UI/StellaOps.UI)
UI-POLICY-13-007 | TODO | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-20-001 | TODO | Ship Monaco-based policy editor with DSL syntax highlighting, inline diagnostics, and compliance checklist sidebar. Dependencies: UI-POLICY-13-007. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-20-002 | TODO | Build simulation panel showing before/after counts, severity deltas, and rule hit summaries with deterministic diff rendering. Dependencies: UI-POLICY-20-001. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-20-003 | TODO | Implement submit/review/approve workflow with comments, approvals log, and RBAC checks aligned to new Policy Studio roles (`policy:author`/`policy:review`/`policy:approve`/`policy:operate`). Dependencies: UI-POLICY-20-002. | UI Guild, Product Ops (src/UI/StellaOps.UI)
UI-POLICY-20-004 | TODO | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filter/search and export. Dependencies: UI-POLICY-20-003. | UI Guild, Observability Guild (src/UI/StellaOps.UI)
UI-POLICY-23-001 | TODO | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | UI Guild, Policy Guild (src/UI/StellaOps.UI)
UI-POLICY-23-002 | TODO | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-23-003 | TODO | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-23-004 | TODO | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-23-005 | TODO | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | UI Guild (src/UI/StellaOps.UI)
UI-POLICY-23-006 | TODO | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | UI Guild (src/UI/StellaOps.UI)

View File

@@ -1,14 +0,0 @@
# Sprint 211 - Experience & SDKs · 180.E) UI.III
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.E) UI.III
Depends on: Sprint 180.E - UI.II
Summary: Experience & SDKs focus on UI (phase III).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
UI-POLICY-27-001 | TODO | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | UI Guild, Product Ops (src/UI/StellaOps.UI)
UI-SIG-26-001 | TODO | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | UI Guild, Signals Guild (src/UI/StellaOps.UI)
UI-SIG-26-002 | TODO | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | UI Guild (src/UI/StellaOps.UI)
UI-SIG-26-003 | TODO | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | UI Guild (src/UI/StellaOps.UI)
UI-SIG-26-004 | TODO | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | UI Guild (src/UI/StellaOps.UI)

View File

@@ -1,25 +0,0 @@
# Sprint 213 - Experience & SDKs · 180.F) Web.II
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.F) Web.II
Depends on: Sprint 180.F - Web.I
Summary: Experience & SDKs focus on Web (phase II).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
WEB-EXC-25-002 `Policy integration surfaces` | TODO | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-EXC-25-003 `Notifications & events` | TODO | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web)
WEB-EXPORT-35-001 `Export routing` | TODO | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-EXPORT-36-001 `Distribution endpoints` | TODO | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-EXPORT-37-001 `Scheduling & verification` | TODO | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-GRAPH-SPEC-21-000 `Graph API/overlay spec drop` | BLOCKED | Draft stub exists; awaiting Graph Platform ratification of overlay format and cache schema. | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web)
WEB-GRAPH-21-001 `Graph endpoints` | BLOCKED | Depends on ratified spec `WEB-GRAPH-SPEC-21-000`. | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web)
WEB-GRAPH-21-002 `Request validation` | BLOCKED | Depends on WEB-GRAPH-21-001 and final overlay schema. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-GRAPH-21-003 `Error mapping & exports` | TODO | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, document rate limits. Dependencies: WEB-GRAPH-21-002. | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web)
WEB-GRAPH-21-004 `Overlay pass-through` | TODO | Proxy Policy Engine overlays while keeping gateway stateless; maintain streaming budgets. Dependencies: WEB-GRAPH-21-003. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web)
WEB-GRAPH-24-001 `Gateway proxy refresh` | TODO | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-GRAPH-24-001 `Graph endpoints` | TODO | Implement `/graph/assets/*` endpoints (snapshots, adjacency, search) with pagination, ETags, and tenant scoping while acting as a pure proxy. Dependencies: WEB-GRAPH-24-001. | BE-Base Platform Guild, SBOM Service Guild (src/Web/StellaOps.Web)
WEB-GRAPH-24-004 `AOC enrichers` | TODO | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-GRAPH-24-004 `Telemetry aggregation` | TODO | Collect gateway metrics/logs (tile latency, proxy errors, overlay cache stats) and forward to dashboards; document sampling strategy. Dependencies: WEB-GRAPH-24-004. | BE-Base Platform Guild, Observability Guild (src/Web/StellaOps.Web)
WEB-LNM-21-001 `Advisory observation endpoints` | TODO | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web)
WEB-LNM-21-002 `VEX observation endpoints` | TODO | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web)

View File

@@ -1,24 +0,0 @@
# Sprint 214 - Experience & SDKs · 180.F) Web.III
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.F) Web.III
Depends on: Sprint 180.F - Web.II
Summary: Experience & SDKs focus on Web (phase III).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
WEB-LNM-21-003 `Policy evidence aggregation` | TODO | Provide combined endpoint for Console to fetch policy result + source evidence (advisory + VEX linksets) for a component. Dependencies: WEB-LNM-21-002. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web)
WEB-NOTIFY-38-001 `Gateway routing` | TODO | Route notifier APIs (`/notifications/*`) and WS feed through gateway with tenant scoping, viewer/operator scope enforcement, and SSE/WebSocket bridging. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-NOTIFY-39-001 `Digest & simulation endpoints` | TODO | Surface digest scheduling, quiet-hour/throttle management, and simulation APIs; ensure rate limits and audit logging. Dependencies: WEB-NOTIFY-38-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-NOTIFY-40-001 `Escalations & localization` | TODO | Expose escalation, localization, channel health, and ack verification endpoints with admin scope enforcement and signed token validation. Dependencies: WEB-NOTIFY-39-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OAS-61-001 `Discovery endpoint` | TODO | Implement `GET /.well-known/openapi` returning gateway spec with version metadata, cache headers, and signed ETag. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OAS-61-002 `Standard error envelope` | TODO | Migrate gateway errors to standard envelope and update examples; ensure telemetry logs include `error.code`. Dependencies: WEB-OAS-61-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OAS-62-001 `Pagination & idempotency alignment` | TODO | Normalize all endpoints to cursor pagination, expose `Idempotency-Key` support, and document rate-limit headers. Dependencies: WEB-OAS-61-002. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OAS-63-001 `Deprecation support` | TODO | Add deprecation header middleware, Sunset link emission, and observability metrics for deprecated routes. Dependencies: WEB-OAS-62-001. | BE-Base Platform Guild, API Governance Guild (src/Web/StellaOps.Web)
WEB-OBS-50-001 `Telemetry core adoption` | TODO | Integrate `StellaOps.Telemetry.Core` into gateway host, replace ad-hoc logging, ensure all routes emit trace/span IDs, tenant context, and scrubbed payload previews. | BE-Base Platform Guild, Observability Guild (src/Web/StellaOps.Web)
WEB-OBS-51-001 `Observability health endpoints` | TODO | Implement `/obs/health` and `/obs/slo` aggregations, pulling metrics from Prometheus/collector APIs, including burn-rate signals and exemplar links for Console widgets. Dependencies: WEB-OBS-50-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OBS-52-001 `Trace & log proxies` | TODO | Deliver `/obs/trace/:id` and `/obs/logs` proxy endpoints with guardrails (time window limits, tenant scoping) forwarding to timeline indexer + log store with signed URLs. Dependencies: WEB-OBS-51-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OBS-54-001 `Evidence & attestation bridges` | TODO | Provide `/evidence/*` and `/attestations/*` pass-through endpoints, enforce `timeline:read`, `evidence:read`, `attest:read` scopes, append provenance headers, and surface verification summaries. Dependencies: WEB-OBS-52-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-OBS-55-001 `Incident mode controls` | TODO | Add `/obs/incident-mode` API (enable/disable/status) with audit trail, sampling override, retention bump preview, and CLI/Console hooks. Dependencies: WEB-OBS-54-001. | BE-Base Platform Guild, Ops Guild (src/Web/StellaOps.Web)
WEB-OBS-56-001 `Sealed status surfaces` | TODO | Extend telemetry core integration to expose sealed/unsealed status APIs, drift metrics, and Console widgets without leaking sealed-mode secrets. Dependencies: WEB-OBS-55-001. | BE-Base Platform Guild, AirGap Guild (src/Web/StellaOps.Web)
WEB-ORCH-32-001 `Read-only routing` | TODO | Expose `/orchestrator/sources | BE-Base Platform Guild (src/Web/StellaOps.Web)

View File

@@ -1,24 +0,0 @@
# Sprint 216 - Experience & SDKs · 180.F) Web.V
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.F) Web.V
Depends on: Sprint 180.F - Web.IV
Summary: Experience & SDKs focus on Web (phase V).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
WEB-RISK-66-001 `Risk API routing` | TODO | Expose risk profile/results endpoints through gateway with tenant scoping, pagination, and rate limiting. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web)
WEB-RISK-66-002 `Explainability downloads` | TODO | Add signed URL handling for explanation blobs and enforce scope checks. Dependencies: WEB-RISK-66-001. | BE-Base Platform Guild, Risk Engine Guild (src/Web/StellaOps.Web)
WEB-RISK-67-001 `Risk status endpoint` | TODO | Provide aggregated risk stats (`/risk/status`) for Console dashboards (counts per severity, last computation). Dependencies: WEB-RISK-66-002. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-RISK-68-001 `Notification hooks` | TODO | Emit events on severity transitions via gateway to notifier bus with trace metadata. Dependencies: WEB-RISK-67-001. | BE-Base Platform Guild, Notifications Guild (src/Web/StellaOps.Web)
WEB-SIG-26-001 `Signals proxy endpoints` | TODO | Surface `/signals/callgraphs`, `/signals/facts` read/write endpoints with pagination, ETags, and RBAC. | BE-Base Platform Guild, Signals Guild (src/Web/StellaOps.Web)
WEB-SIG-26-002 `Reachability joins` | TODO | Extend `/policy/effective` and `/vuln/explorer` responses to include reachability scores/states and allow filtering. Dependencies: WEB-SIG-26-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-SIG-26-003 `Simulation hooks` | TODO | Add reachability override parameters to `/policy/simulate` and related APIs for what-if analysis. Dependencies: WEB-SIG-26-002. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-TEN-47-001 `Auth middleware` | TODO | Implement JWT verification, tenant activation from headers, scope matching, and decision audit emission for all API endpoints. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-TEN-48-001 `Tenant context propagation` | TODO | Set DB session `stella.tenant_id`, enforce tenant/project checks on persistence, prefix object storage paths, and stamp audit metadata. Dependencies: WEB-TEN-47-001. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-TEN-49-001 `ABAC & audit API` | TODO | Integrate optional ABAC overlay with Policy Engine, expose `/audit/decisions` API, and support service token minting endpoints. Dependencies: WEB-TEN-48-001. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web)
WEB-VEX-30-007 `VEX consensus routing` | TODO | Route `/vex/consensus` APIs with tenant RBAC/ABAC, caching, and streaming; surface telemetry and trace IDs without gateway-side overlay logic. | BE-Base Platform Guild, VEX Lens Guild (src/Web/StellaOps.Web)
WEB-VULN-29-001 `Vuln API routing` | TODO | Expose `/vuln/*` endpoints via gateway with tenant scoping, RBAC/ABAC enforcement, anti-forgery headers, and request logging. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-VULN-29-002 `Ledger proxy headers` | TODO | Forward workflow actions to Findings Ledger with idempotency headers and correlation IDs; handle retries/backoff. Dependencies: WEB-VULN-29-001. | BE-Base Platform Guild, Findings Ledger Guild (src/Web/StellaOps.Web)
WEB-VULN-29-003 `Simulation + export routing` | TODO | Provide simulation and export orchestration routes with SSE/progress headers, signed download links, and request budgeting. Dependencies: WEB-VULN-29-002. | BE-Base Platform Guild (src/Web/StellaOps.Web)
WEB-VULN-29-004 `Telemetry aggregation` | TODO | Emit gateway metrics/logs (latency, error rates, export duration), propagate query hashes for analytics dashboards. Dependencies: WEB-VULN-29-003. | BE-Base Platform Guild, Observability Guild (src/Web/StellaOps.Web)

View File

@@ -18,12 +18,34 @@
| --- | --- | --- | --- | --- |
| 200.A Docs Tasks.md ladder (Sprint 301 onwards) | BLOCKED (2025-11-19) | Docs Guild · Ops Guild | Attestor 100.A; Advisory AI 110.A; AirGap 120.A; Scanner 130.A; Graph 140.A; Orchestrator 150.A; EvidenceLocker 160.A; Notifier 170.A; CLI 180.A; Ops Deployment 190.A | Awaiting upstream artefacts (SBOM/CLI/Policy/AirGap determinism) before Md.I template rollout can continue. |
| 200.B Module dossiers (Sprints 312335) | TODO | Docs Guild · Module Guild owners | Docs Tasks Md ladder to at least Md.II; Ops deployment evidence | Stays queued until Docs Tasks Md ladder provides updated process + assets. |
| Developer quickstart advisory sync | TODO | Docs Guild | 29-Nov-2025 advisory + onboarding doc draft | Publish the onboarding quickstart advisory + `docs/onboarding/dev-quickstart.md`, update `docs/README.md`, `modules/platform/architecture-overview.md`, and `ADVISORY_INDEX.md`, and confirm sprint/AGENTS references per the advisory workflow. |
| Acceptance tests guardrails sync | TODO | Docs Guild | 29-Nov-2025 advisory + checklist draft | Publish the Acceptance Tests Pack advisory, cross-link to sprint/guardrail docs, and capture sprint board checklist for CI/DB/rew definitions. |
| CVSS v4.0 momentum sync | TODO | Docs Guild | 29-Nov-2025 advisory + briefing draft | Publish the CVSS v4.0 momentum briefing, highlight adoption signals, and link to sprint decisions for SPRINT_0190.* and docs coverage. |
| SBOM→VEX proof blueprint sync | TODO | Docs Guild | 29-Nov-2025 advisory + blueprint draft | Publish the SBOM→VEX blueprint, link to platform/blueprint docs, and capture diagram/stub updates for DSSE/Rekor/VEX. |
| SCA failure catalogue sync | TODO | Docs Guild | 29-Nov-2025 advisory + catalogue draft | Publish the SCA failure catalogue, reference the concrete regressions, and tie the test-vector guidance back into sprint risk logs. |
| Implementor guidelines sync | TODO | Docs Guild | 30-Nov-2025 advisory + checklist draft | Publish the Implementor Guidelines advisory, note the checklist extraction, and mention the doc in sprint/AGENTS references. |
| Rekor receipt checklist sync | TODO | Docs Guild | 30-Nov-2025 advisory + checklist draft | Publish the Rekor Receipt Checklist, update module docs (Authority/Sbomer/Vexer) with ownership map, highlight offline metadata requirements. |
| Unknowns decay/triage sync | TODO | Docs Guild | 30-Nov-2025 advisory + heuristic draft | Publish the Unknowns Decay & Triage brief, link to UnknownsRegistry docs, and capture UI artifacts for cards + queue exports. |
| Ecosystem reality test cases sync | TODO | Docs Guild | 30-Nov-2025 advisory + test spec draft | Publish the Ecosystem Reality Test Cases advisory, link each incident to an acceptance test, and note exported artifacts/commands. |
| Standup sprint kickstarters sync | TODO | Docs Guild | 30-Nov-2025 advisory + task plan draft | Publish the Standup Sprint Kickstarters advisory, surface ticket names, and tie the tasks into MSC sprint logs. |
| Evidence + suppression pattern sync | TODO | Docs Guild | 30-Nov-2025 advisory + comparison draft | Publish the Comparative Evidence Patterns advisory, highlight the UX/data-model takeaways, and reference doc links per tool. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-13 | Sprint 300 switched to topic-oriented template; Docs Tasks Md ladder marked DOING to reflect ongoing restructuring work. | Docs Guild |
| 2025-11-19 | Marked Docs Tasks Md ladder BLOCKED pending upstream artefacts for Md.I dossier rollouts. | Implementer |
| 2025-11-30 | Added the 29-Nov-2025 Developer Quickstart advisory, `docs/onboarding/dev-quickstart.md`, and cross-links (README/platform/ADVISORY_INDEX); created this advisory sync task row. | Docs Guild |
| 2025-11-30 | Added the 29-Nov-2025 Acceptance Tests Pack advisory and checklist; noted new task row for guardrail sprint artifacts. | Docs Guild |
| 2025-11-30 | Added the 29-Nov-2025 CVSS v4.0 Momentum advisory and indexed the adoption briefing; noted sprint sync row for CVSS momentum context. | Docs Guild |
| 2025-11-30 | Added the 29-Nov-2025 SCA Failure Catalogue advisory and indexed the concrete test vectors; noted sprint sync row for failure catalog references. | Docs Guild |
| 2025-11-30 | Added the 29-Nov-2025 SBOM→VEX Proof Blueprint advisory and outlined diagram/stub follow-up; logged sprint sync row for the blueprint. | Docs Guild |
| 2025-11-30 | Added the 30-Nov-2025 Rekor Receipt Checklist advisory and noted the ownership/action map for Authority/Sbomer/Vexer. | Docs Guild |
| 2025-11-30 | Added the 30-Nov-2025 Ecosystem Reality Test Cases advisory (credential leak, Trivy offline DB, SBOM parity, Grype divergence) and logged the acceptance test intent. | Docs Guild |
| 2025-11-30 | Added the 30-Nov-2025 Unknowns Decay & Triage advisory and noted UI + export artifacts for UnknownsRegistry + queues. | Docs Guild |
| 2025-11-30 | Added the 30-Nov-2025 Standup Sprint Kickstarters advisory, highlighting the three unblocker tasks/tickets and the proposed owners. | Docs Guild |
| 2025-11-30 | Added the 30-Nov-2025 Comparative Evidence Patterns advisory and recorded cross-tool evidence/suppression nuggets for UX designers. | Docs Guild |
| 2025-11-30 | Added the 30-Nov-2025 Implementor Guidelines advisory and checked the docs + sprint sync references; the row stays TODO until docs link updates finish. | Docs Guild |
## Decisions & Risks
| Item | Type | Owner(s) | Due | Notes |

View File

@@ -39,26 +39,42 @@
| 16 | PG-T1.6.2 | DONE | Completed 2025-11-29 | Authority Guild | Implement `IAuditRepository` |
| 17 | PG-T1.7 | DONE | Completed 2025-11-29 | Authority Guild | Add configuration switch in `ServiceCollectionExtensions` |
| 18 | PG-T1.8.1 | DONE | Completed 2025-11-29 | Authority Guild | Write integration tests for all repositories |
| 19 | PG-T1.8.2 | TODO | Depends on PG-T1.8.1 | Authority Guild | Write determinism tests for token generation |
| 20 | PG-T1.9 | TODO | Depends on PG-T1.8 | Authority Guild | Optional: Implement dual-write wrapper for Tier A verification |
| 21 | PG-T1.10 | TODO | Depends on PG-T1.8 | Authority Guild | Run backfill from MongoDB to PostgreSQL |
| 22 | PG-T1.11 | TODO | Depends on PG-T1.10 | Authority Guild | Verify data integrity: row counts, checksums |
| 23 | PG-T1.12 | TODO | Depends on PG-T1.11 | Authority Guild | Switch Authority to PostgreSQL-only |
| 19 | PG-T1.8.2 | TODO | Depends on PG-T1.8.1; blocked pending AGENTS for working dir | Authority Guild | Write determinism tests for token generation |
| 20 | PG-T1.9 | TODO | Depends on PG-T1.8; blocked pending AGENTS for working dir | Authority Guild | Optional: Implement dual-write wrapper for Tier A verification |
| 21 | PG-T1.10 | TODO | Depends on PG-T1.8; blocked pending AGENTS for working dir | Authority Guild | Run backfill from MongoDB to PostgreSQL |
| 22 | PG-T1.11 | TODO | Depends on PG-T1.10; blocked pending AGENTS for working dir | Authority Guild | Verify data integrity: row counts, checksums |
| 23 | PG-T1.12 | TODO | Depends on PG-T1.11; blocked pending AGENTS for working dir | Authority Guild | Switch Authority to PostgreSQL-only |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-29 | All repository implementations completed (PG-T1.1 through PG-T1.6.2) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T1.7) | Claude |
| 2025-11-29 | Integration tests created for all repositories (PG-T1.8.1) | Claude |
## Wave Coordination
- Single-wave sprint (Phase 1). Downstream phases 24 proceed independently once Phase 0 foundations verified.
## Wave Detail Snapshots
- **Phase 1 (current):** Storage project, schema, repositories, and integration tests completed; determinism tests and cutover steps remain.
## Interlocks
- Alignment with Scheduler (Phase 2) for shared tenant/user references before cutover.
- Requires Phase 0 foundations artifacts for migrations and shared abstractions.
- AGENTS file missing for `src/Authority/__Libraries/StellaOps.Authority.Storage.Postgres`; implementers should not start new work until created.
## Action Tracker
| Item | Status | Owner | Next step |
| --- | --- | --- | --- |
| Create AGENTS.md for `src/Authority/__Libraries/StellaOps.Authority.Storage.Postgres` | TODO | Authority PM | Draft minimal charter (roles, prerequisites, test rules) so remaining tasks can move to DOING |
| Plan dual-write verification harness for Tier A data | TODO | Authority Guild | Define wrapper and metrics for PG-T1.9; capture in docs/db/tasks/PHASE_1_AUTHORITY.md |
## Decisions & Risks
**Design decisions**
- Password hashes stored as TEXT; Argon2id parameters in separate columns.
- Token expiry uses `TIMESTAMPTZ` for timezone-aware comparisons.
- Audit log may grow large; consider partitioning by `created_at` in production.
- Dual-write mode optional but recommended for Tier A data verification.
**Risks**
| Risk | Impact | Mitigation |
| --- | --- | --- |
| Audit log growth without partitioning | Large tables degrade query latency | Add time-based partitioning before production cutover (post Phase 1 hardening) |
| Missing AGENTS for working directory | Implementers cannot start PG-T1.8.2+ per charter rules | Create AGENTS.md (see Action Tracker) and link from sprint once published |
| Cutover without determinism tests | Token issuance non-deterministic across dual-write | Complete PG-T1.8.2 determinism tests before PG-T1.9PG-T1.12 |
## Exit Criteria
- [ ] All 12+ repository interfaces implemented
- [ ] Schema migrations idempotent and tested
@@ -66,8 +82,17 @@
- [ ] Data backfill completed and verified
- [ ] Authority running on PostgreSQL in staging
## Next Checkpoints
## Upcoming Checkpoints
- Coordinate with Phase 2 (Scheduler) for any shared user/tenant references.
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-29 | All repository implementations completed (PG-T1.1 through PG-T1.6.2) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T1.7) | Claude |
| 2025-11-29 | Integration tests created for all repositories (PG-T1.8.1) | Claude |
| 2025-11-30 | Normalised sprint to docs/implplan template; added interlocks/action tracker; flagged missing AGENTS for working dir | Codex |
---
*Reference: docs/db/tasks/PHASE_1_AUTHORITY.md*

View File

@@ -37,8 +37,8 @@
| 14 | PG-T2.6.2 | DONE | Completed 2025-11-29 | Scheduler Guild | Implement `IMetricsRepository` |
| 15 | PG-T2.7 | DONE | Completed 2025-11-29 | Scheduler Guild | Add configuration switch in `ServiceCollectionExtensions` |
| 16 | PG-T2.8.1 | DONE | Completed 2025-11-29 | Scheduler Guild | Write integration tests for job queue operations |
| 17 | PG-T2.8.2 | TODO | Depends on PG-T2.8.1 | Scheduler Guild | Write determinism tests for trigger calculations |
| 18 | PG-T2.8.3 | TODO | Depends on PG-T2.8.1 | Scheduler Guild | Write concurrency tests for distributed locking |
| 17 | PG-T2.8.2 | DONE | Completed 2025-11-30 | Scheduler Guild | Write determinism tests for trigger calculations |
| 18 | PG-T2.8.3 | DONE | Completed 2025-11-30 | Scheduler Guild | Write concurrency tests for distributed locking |
| 19 | PG-T2.9 | TODO | Depends on PG-T2.8 | Scheduler Guild | Run backfill from MongoDB to PostgreSQL |
| 20 | PG-T2.10 | TODO | Depends on PG-T2.9 | Scheduler Guild | Verify data integrity and trigger timing |
| 21 | PG-T2.11 | TODO | Depends on PG-T2.10 | Scheduler Guild | Switch Scheduler to PostgreSQL-only |
@@ -50,6 +50,8 @@
| 2025-11-29 | All repository implementations completed (PG-T2.1 through PG-T2.6.2) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T2.7) | Claude |
| 2025-11-29 | Integration tests created for Trigger, DistributedLock, Worker repositories (PG-T2.8.1) | Claude |
| 2025-11-30 | Added deterministic due-trigger ordering and determinism + concurrency test coverage (PG-T2.8.2, PG-T2.8.3) | StellaOps Agent |
| 2025-11-30 | Postgres integration test run failed locally: Docker daemon unavailable (Testcontainers) | StellaOps Agent |
## Decisions & Risks
- PostgreSQL advisory locks replace MongoDB distributed locks.
@@ -57,6 +59,8 @@
- Cron expressions stored as TEXT; next-fire computed in application.
- Job payload stored as JSONB for flexibility.
- Risk: advisory lock key collision; use tenant-scoped hash values.
- Due trigger retrieval is now ordered by `next_fire_at`, `tenant_id`, then `id` to keep scheduling deterministic under ties.
- Risk: Local test runs require Docker for Testcontainers; ensure Docker daemon is available before CI/local execution.
## Exit Criteria
- [ ] All repository interfaces implemented

View File

@@ -16,7 +16,9 @@
- docs/db/README.md
- docs/db/SPECIFICATION.md (Section 5.5 - Notify Schema)
- docs/db/RULES.md
- src/Notify/AGENTS.md (if exists)
- docs/db/VERIFICATION.md
- src/Notify/AGENTS.md
- src/Notify/__Libraries/StellaOps.Notify.Storage.Postgres/AGENTS.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
@@ -49,21 +51,32 @@
| 26 | PG-T3.10.2 | TODO | Depends on PG-T3.10.1 | Notify Guild | Test notification delivery flow end-to-end |
| 27 | PG-T3.10.3 | TODO | Depends on PG-T3.10.1 | Notify Guild | Test escalation handling |
| 28 | PG-T3.10.4 | TODO | Depends on PG-T3.10.1 | Notify Guild | Test digest aggregation |
| 29 | PG-T3.11 | TODO | Depends on PG-T3.10 | Notify Guild | Switch Notify to PostgreSQL-only |
| 29 | PG-T3.11 | TODO | Depends on PG-T3.10.x verification | Notify Guild | Switch Notify to PostgreSQL-only |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-29 | All repository implementations completed (PG-T3.1 through PG-T3.8.3) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T3.9) | Claude |
| 2025-11-29 | Integration tests created for Channel, Delivery, Rule, Template, Inbox, Digest, NotifyAudit repositories (PG-T3.10.1) | Claude |
## Wave Coordination
- Single wave covering Notify Postgres conversion; tasks grouped by repository implementation (PG-T3.1PG-T3.9) followed by verification and cutover (PG-T3.10.xPG-T3.11).
## Wave Detail Snapshots
- Repository implementations (PG-T3.1PG-T3.9): DONE as of 2025-11-29.
- Verification & cutover (PG-T3.10.xPG-T3.11): pending; awaiting PG-T3.10.1 evidence before end-to-end runs.
## Interlocks
- Scheduler trigger integration required before final cutover (PG-T3.11).
- Alignment with db conversion foundations from Sprint 3400 (Phase 0) already satisfied.
- Notify WebService/Worker DI wiring confirmed via PG-T3.9; monitor for downstream impacts in UI regressions.
## Decisions & Risks
- Channel configurations stored as JSONB for flexibility across channel types.
- Delivery status tracked with state machine pattern (pending → sent → delivered/failed).
- Escalation states may need frequent updates; index accordingly.
- Digest aggregation queries may be complex; consider materialized views.
- Decisions:
- Channel configurations stored as JSONB for flexibility across channel types.
- Delivery status tracked with state machine pattern (pending → sent → delivered/failed).
- DI wiring uses `ServiceCollectionExtensions` switch for Postgres enablement.
Risks:
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Escalation state churn can create hot partitions | Elevated write contention and vacuum churn | Index on tenant + escalation key; monitor autovacuum settings and add partial indexes if needed | Notify Guild | Open |
| Digest aggregation queries may be complex/heavy | Slow digest generation or stale digests | Evaluate materialized views with refresh-on-commit for high-volume tenants; add explain plans in PG-T3.10.4 | Notify Guild | Open |
| Cutover depends on successful PG-T3.10.x end-to-end tests | PostgreSQL-only switch (PG-T3.11) blocked | Run end-to-end suites immediately after PG-T3.10.1 evidence; keep Mongo fallback toggles until PG-T3.11 sign-off | Notify Guild | Open |
## Exit Criteria
- [ ] All 15 repository interfaces implemented
@@ -72,8 +85,25 @@
- [ ] All integration tests pass
- [ ] Notify running on PostgreSQL in staging
## Next Checkpoints
- Coordinate with Scheduler for notification trigger integration.
## Upcoming Checkpoints
- 2025-12-02: Kick off end-to-end delivery/escalation/digest runs (PG-T3.10.2PG-T3.10.4).
- 2025-12-04: Cutover readiness review for PG-T3.11 with Scheduler alignment.
## Action Tracker
| # | Action | Owner | Status | Notes |
| --- | --- | --- | --- | --- |
| 1 | Add AGENTS.md for `StellaOps.Notify.Storage.Postgres` working directory | Planning | DONE | Added 2025-11-30 and linked in Documentation Prerequisites |
| 2 | Capture PG-T3.10.1 evidence in repo tests report | Notify Guild | TODO | Needed before starting PG-T3.10.2PG-T3.10.4 |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-29 | All repository implementations completed (PG-T3.1 through PG-T3.8.3) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T3.9) | Claude |
| 2025-11-29 | Integration tests created for Channel, Delivery, Rule, Template, Inbox, Digest, NotifyAudit repositories (PG-T3.10.1) | Claude |
| 2025-11-30 | Normalised sprint to docs/implplan template; added coordination/interlock/action sections | Planning |
| 2025-11-30 | Added AGENTS.md for Postgres storage working directory and linked in prerequisites | Planning |
---
*Reference: docs/db/tasks/PHASE_3_NOTIFY.md*

View File

@@ -48,19 +48,19 @@
| 25 | PG-T4.11 | TODO | Depends on PG-T4.10 | Policy Guild | Verify version numbers and active version settings |
| 26 | PG-T4.12 | TODO | Depends on PG-T4.11 | Policy Guild | Switch Policy to PostgreSQL-only |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-29 | All repository implementations completed (PG-T4.1 through PG-T4.6.4) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T4.7) | Claude |
| 2025-11-29 | Integration tests created for Pack, Rule, Exception, EvaluationRun, RiskProfile, PolicyAudit repositories (PG-T4.8.1) | Claude |
## Wave Coordination
- Single wave covering PG-T4.8.2 through PG-T4.12; sequencing is tests → export → import → verification → cutover.
- Migration window reuses Phase 0 foundations; avoid schema changes once PG-T4.9 starts.
## Decisions & Risks
- Pack versions are immutable once published; new versions create new rows.
- Rego content stored as TEXT; consider compression for large policies.
- Evaluation results may grow rapidly; consider partitioning or archival.
- Risk profile versioning critical for audit trail; never delete old versions.
## Wave Detail Snapshots
| Wave | Scope | Exit evidence |
| --- | --- | --- |
| W1 | Complete tests (PG-T4.8.2PG-T4.8.3), export/import, verification, cutover (PG-T4.9PG-T4.12) | Passing integration tests, successful data export/import, verified active versions, Policy service running on PostgreSQL in staging |
## Interlocks
- Postgres infrastructure from Sprint 3400 must remain stable during export/import (PG-T4.9PG-T4.10).
- Coordinate with Excititor on VEX policy integration to avoid concurrent schema changes during cutover.
- MongoDB write freeze required during PG-T4.9PG-T4.11 to prevent drift while exporting/importing packs.
## Exit Criteria
- [ ] All repository interfaces implemented
@@ -69,8 +69,40 @@
- [ ] All integration tests pass
- [ ] Policy running on PostgreSQL in staging
## Next Checkpoints
- Coordinate with Excititor for VEX policy integration.
## Upcoming Checkpoints
- Schedule alignment with Excititor for VEX policy integration before PG-T4.12 (date TBD).
- Stage export/import dry-run once PG-T4.8.1 evidence is reviewed.
## Action Tracker
| # | Action | Owner | Due | Status | Notes |
| --- | --- | --- | --- | --- | --- |
| 1 | Run pack versioning workflow test suite (PG-T4.8.2) | Policy Guild | After PG-T4.8.1 evidence | TODO | Validates happy-path and rollback |
| 2 | Run risk profile version history tests (PG-T4.8.3) | Policy Guild | After PG-T4.8.1 evidence | TODO | Covers `GetVersionAsync`/`ListVersionsAsync` |
| 3 | Export active packs from MongoDB (PG-T4.9) | Policy Guild | After PG-T4.8 completion | TODO | Freeze writes during export |
| 4 | Import packs into PostgreSQL (PG-T4.10) | Policy Guild | After PG-T4.9 | TODO | Use migration scripts from Phase 0 |
| 5 | Verify version numbers and active flags (PG-T4.11) | Policy Guild | After PG-T4.10 | TODO | Cross-check pack/risk profile parity |
| 6 | Switch Policy to PostgreSQL-only (PG-T4.12) | Policy Guild | After PG-T4.11 | TODO | Flip configuration flag and monitor |
## Decisions & Risks
- Pack versions are immutable once published; new versions create new rows.
- Rego content stored as TEXT; consider compression for large policies.
- Evaluation results may grow rapidly; consider partitioning or archival.
- Risk profile versioning is critical for audit trail; never delete old versions.
| Risk | Impact | Mitigation | Owner | Status |
| --- | --- | --- | --- | --- |
| Large policy bodies inflate storage | Higher storage and I/O costs | Evaluate compression option post-migration; monitor size metrics | Policy Guild | Open |
| Evaluation table growth | Potential performance/retention issues | Plan partitioning/archival after cutover; add retention policy | Policy Guild | Open |
| Drift during export/import | Inconsistent active versions | Enforce MongoDB write freeze during PG-T4.9PG-T4.11; verify counts before cutover | Policy Guild | Open |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-29 | All repository implementations completed (PG-T4.1 through PG-T4.6.4) | Claude |
| 2025-11-29 | ServiceCollectionExtensions updated with all repository registrations (PG-T4.7) | Claude |
| 2025-11-29 | Integration tests created for Pack, Rule, Exception, EvaluationRun, RiskProfile, PolicyAudit repositories (PG-T4.8.1) | Claude |
| 2025-11-30 | Normalised sprint to docs/implplan template; added coordination and action tracker sections | Codex |
---
*Reference: docs/db/tasks/PHASE_4_POLICY.md*

View File

@@ -64,17 +64,18 @@
| 35 | PG-T5b.5 | TODO | Depends on PG-T5b.4 | Concelier Guild | Performance optimization with EXPLAIN ANALYZE |
| 36 | PG-T5b.6 | TODO | Depends on PG-T5b.5 | Concelier Guild | Switch Scanner/Concelier to PostgreSQL-only |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
## Wave Coordination
- Two-wave structure: 5a (schema/repositories) must reach PG-T5a.6 before 5b (conversion/verification) begins.
- Dual-import mode (PG-T5b.3.1) and parity checks (PG-T5b.4.x) gate the Excititor hand-off.
## Decisions & Risks
- PURL stored as TEXT with GIN trigram index for efficient matching.
- Version ranges stored as JSONB; too complex for relational decomposition.
- Full-text search using `tsvector` column with GIN index.
- Risk: matching discrepancies between backends; extensive comparison testing required.
- Expected data volume: 300K+ advisories, 2M+ affected entries.
## Wave Detail Snapshots
- **Wave 5a focus:** project creation, schema migrations, repositories, and integration tests; all tasks currently `TODO`.
- **Wave 5b focus:** converter, importer rewrites, parity runs, and performance tuning; blocked until Wave 5a completes integration tests.
## Interlocks
- Sprint 3400 must be verified as `DONE` before PG-T5a.1 starts.
- Excititor Phase 6 is blocked until parity results from PG-T5b.4.4 are recorded.
- Deterministic matching must be proven across MongoDB and PostgreSQL before switching Scanner/Concelier to PostgreSQL-only (PG-T5b.6).
## Exit Criteria
- [ ] All repository interfaces implemented
@@ -83,8 +84,33 @@
- [ ] Feed imports working on PostgreSQL
- [ ] Concelier running on PostgreSQL in staging
## Next Checkpoints
- Phase 6 (Excititor) depends on this completing successfully.
## Upcoming Checkpoints
| Date (UTC) | Checkpoint | Owner | Notes |
| --- | --- | --- | --- |
| TBD | Schedule parity verification window after PG-T5b.4.3 completes | Concelier Guild | Add date once 5a integration tests are green |
| TBD | Phase 6 (Excititor) kickoff after PostgreSQL-only cutover readiness | Excititor Guild | Dependent on PG-T5b.6 sign-off |
## Action Tracker
| # | Action | Owner | Due | Status | Notes |
| --- | --- | --- | --- | --- | --- |
| 1 | Confirm Sprint 3400 (Phase 0) completion and evidence link | Planning | TBD | TODO | Required before PG-T5a.1 starts |
| 2 | Assign owners and dates for parity verification checkpoints | Concelier Guild | TBD | TODO | Populate Upcoming Checkpoints with dates |
## Decisions & Risks
- PURL stored as TEXT with GIN trigram index for efficient matching.
- Version ranges stored as JSONB; too complex for relational decomposition.
- Full-text search using `tsvector` column with GIN index.
| Risk | Impact | Mitigation | Status |
| --- | --- | --- | --- |
| Matching discrepancies between MongoDB and PostgreSQL backends | Potential false positives/negatives and loss of trust | Run PG-T5b.4 parity checks with fixed SBOM set; require identical results before PG-T5b.6 | Open |
| Data volume (~300K advisories; ~2M affected rows) stresses indexing | Slow imports and lookups | Use partition-friendly schema, analyze after bulk load, validate GIN/GIST index choices during PG-T5b.5 | Open |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
| 2025-11-30 | Normalised to docs/implplan template; added coordination, interlocks, risk table, and action tracker | Planning |
---
*Reference: docs/db/tasks/PHASE_5_VULNERABILITIES.md*

View File

@@ -16,7 +16,26 @@
- docs/db/README.md
- docs/db/SPECIFICATION.md (Section 5.3 - VEX Schema)
- docs/db/RULES.md
- src/Excititor/AGENTS.md (if exists)
- src/Excititor/AGENTS.md
## Wave Coordination
| Wave | Scope | Exit gate | Notes |
| --- | --- | --- | --- |
| 6a | Core schema and repositories | VEX schema migrations + repositories + tests (Tasks 1-16) | Blocks all graph storage work |
| 6b | Graph storage and determinism | Revision_id algorithm captured; node/edge COPY bulk ops proven deterministic (Tasks 17-30) | Requires Wave 6a DONE |
| 6c | Migration & verification | Dual-run parity demonstrated and cutover-ready (Tasks 31-42) | Requires Waves 6a-6b DONE |
## Wave Detail Snapshots
| Wave | Key outputs | Evidence to collect |
| --- | --- | --- |
| 6a | VEX schema migrations; data source; repositories for projects/statements/observations/linksets/consensus | Migration scripts, repository unit/integration tests |
| 6b | Graph revision/node/edge repositories; COPY-based bulk insert; traversal queries; revision determinism tests | Benchmark traces, stability test results (≥5 runs) |
| 6c | Mongo→Postgres conversion services; deterministic extraction order; dual-backend comparisons; cutover plan | Comparison reports (revision_id, counts), migration checklist |
## Interlocks
- Downstream phases (Phase 7 cleanup) cannot start until 6c cutover checks pass.
- Uses COPY; coordinate with DB ops on allowed temp paths/statement timeouts.
- Determinism requirements must align with Excititor module charter (tenant guards, UTC ordering).
## Delivery Tracker
@@ -74,10 +93,12 @@
| 41 | PG-T6c.4 | TODO | Depends on PG-T6c.3 | Excititor Guild | Migrate active projects |
| 42 | PG-T6c.5 | TODO | Depends on PG-T6c.4 | Excititor Guild | Switch Excititor to PostgreSQL-only |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-28 | Sprint file created | Planning |
## Action Tracker
| # | Item | Status | Owner | Notes |
| --- | --- | --- | --- | --- |
| 1 | Confirm Sprints 3400 and 3405 are marked DONE before Wave 6a starts | TODO | Planning | Blocker gate for PG-T6a.1 |
| 2 | Lock agreed revision_id algorithm in docs/db/SPECIFICATION.md addendum | TODO | Excititor Guild | Needed before tasks PG-T6b.4.1-4.4 |
| 3 | Coordinate COPY settings (work_mem, statement_timeout) with DB ops | TODO | Excititor Guild | Required ahead of PG-T6b.2/PG-T6b.3 |
## Decisions & Risks
- Graph nodes/edges use BIGSERIAL for high-volume IDs.
@@ -86,6 +107,18 @@
- Graph traversal indexes on `(from_node_id)` and `(to_node_id)`.
- Estimated volumes: 10M+ nodes, 20M+ edges, 1M+ VEX statements.
| Risk | Impact | Mitigation | Status |
| --- | --- | --- | --- |
| Revision_id instability | High: breaks reproducibility and cutover confidence | Document algorithm; deterministic ordering; 5x stability tests (PG-T6b.4.1-4.4) | Open |
| COPY misconfiguration | Medium: bulk inserts fail or throttle | Pre-negotiate COPY settings with DB ops; reuse infra defaults from Sprint 3400 | Open |
| Dual-run divergence | High: Mongo vs Postgres results mismatch | Use comparison tasks PG-T6c.3.1-3.5; capture deltas and block cutover until resolved | Open |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalised sprint to docs/implplan template (waves/interlocks/action tracker) | Planning |
| 2025-11-28 | Sprint file created | Planning |
## Exit Criteria
- [ ] All repository interfaces implemented
- [ ] Graph storage working efficiently with bulk operations
@@ -94,7 +127,7 @@
- [ ] All comparison tests pass
- [ ] Excititor running on PostgreSQL in staging
## Next Checkpoints
## Upcoming Checkpoints
- This is the most complex phase; allocate extra time for determinism verification.
- Phase 7 (Cleanup) follows after successful cutover.

View File

@@ -30,8 +30,8 @@ Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - A
| DEVOPS-AIRGAP-56-003 | DONE (2025-11-30) | Build Bootstrap Pack pipeline bundling images/charts, generating checksums, and publishing manifest for offline transfer. Dependencies: DEVOPS-AIRGAP-56-002. | DevOps Guild, Container Distribution Guild (ops/devops) |
| DEVOPS-AIRGAP-57-001 | DONE (2025-11-30) | Automate Mirror Bundle creation jobs with dual-control approvals, artifact signing, and checksum publication. Dependencies: DEVOPS-AIRGAP-56-003. | DevOps Guild, Mirror Creator Guild (ops/devops) |
| DEVOPS-AIRGAP-57-002 | BLOCKED (2025-11-18) | Waiting on upstream DEVOPS-AIRGAP-57-001 (mirror bundle automation) to provide artifacts/endpoints for sealed-mode CI; no sealed fixtures available to exercise tests. | DevOps Guild, Authority Guild (ops/devops) |
| DEVOPS-AIRGAP-58-001 | TODO | Provide local SMTP/syslog container templates and health checks for sealed environments; integrate into Bootstrap Pack. Dependencies: DEVOPS-AIRGAP-57-002. | DevOps Guild, Notifications Guild (ops/devops) |
| DEVOPS-AIRGAP-58-002 | TODO | Ship sealed-mode observability stack (Prometheus/Grafana/Tempo/Loki) pre-configured with offline dashboards and no remote exporters. Dependencies: DEVOPS-AIRGAP-58-001. | DevOps Guild, Observability Guild (ops/devops) |
| DEVOPS-AIRGAP-58-001 | DONE (2025-11-30) | Provide local SMTP/syslog container templates and health checks for sealed environments; integrate into Bootstrap Pack. Dependencies: DEVOPS-AIRGAP-57-002. | DevOps Guild, Notifications Guild (ops/devops) |
| DEVOPS-AIRGAP-58-002 | DONE (2025-11-30) | Ship sealed-mode observability stack (Prometheus/Grafana/Tempo/Loki) pre-configured with offline dashboards and no remote exporters. Dependencies: DEVOPS-AIRGAP-58-001. | DevOps Guild, Observability Guild (ops/devops) |
| DEVOPS-AOC-19-001 | BLOCKED (2025-10-26) | Integrate the AOC Roslyn analyzer and guard tests into CI, failing builds when ingestion projects attempt banned writes. | DevOps Guild, Platform Guild (ops/devops) |
| DEVOPS-AOC-19-002 | BLOCKED (2025-10-26) | Add pipeline stage executing `stella aoc verify --since` against seeded Mongo snapshots for Concelier + Excititor, publishing violation report artefacts. Dependencies: DEVOPS-AOC-19-001. | DevOps Guild (ops/devops) |
| DEVOPS-AOC-19-003 | BLOCKED (2025-10-26) | Enforce unit test coverage thresholds for AOC guard suites and ensure coverage exported to dashboards. Dependencies: DEVOPS-AOC-19-002. | DevOps Guild, QA Guild (ops/devops) |
@@ -47,13 +47,15 @@ Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - A
| DEVOPS-CONCELIER-CI-24-101 | DONE (2025-11-25) | Provide clean CI runner + warmed NuGet cache + vstest harness for Concelier WebService & Storage; deliver TRX/binlogs and unblock CONCELIER-GRAPH-24-101/28-102 and LNM-21-004..203. | DevOps Guild, Concelier Core Guild (ops/devops) |
| DEVOPS-SCANNER-CI-11-001 | DONE (2025-11-30) | Supply warmed cache/diag runner for Scanner analyzers (LANG-11-001, JAVA 21-005/008) with binlogs + TRX; unblock restore/test hangs. | DevOps Guild, Scanner EPDR Guild (ops/devops) |
| DEVOPS-SCANNER-JAVA-21-011-REL | TODO | Package/sign Java analyzer plug-in once dev task 21-011 delivers; publish to Offline Kit/CLI release pipelines with provenance. | DevOps Guild, Scanner Release Guild (ops/devops) |
| DEVOPS-SBOM-23-001 | TODO | Publish vetted offline NuGet feed + CI recipe for SbomService; prove with `dotnet test` run and share cache hashes; unblock SBOM-CONSOLE-23-001/002. | DevOps Guild, SBOM Service Guild (ops/devops) |
| DEVOPS-SBOM-23-001 | DONE (2025-11-30) | Publish vetted offline NuGet feed + CI recipe for SbomService; prove with `dotnet test` run and share cache hashes; unblock SBOM-CONSOLE-23-001/002. | DevOps Guild, SBOM Service Guild (ops/devops) |
| FEED-REMEDIATION-1001 | BLOCKED (2025-11-24) | Define remediation scope and runbook for overdue feeds (CCCS/CERTBUND); schedule refresh; depends on PREP-FEEDCONN-ICS-KISA-PLAN. | Concelier Feed Owners (ops/devops) |
| FEEDCONN-ICSCISA-02-012 / FEEDCONN-KISA-02-008 | BLOCKED (2025-11-24) | Publish provenance refresh/connector schedule for ICSCISA/KISA feeds; execute remediation per runbook once owners provide plan. | Concelier Feed Owners (ops/devops) |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Completed DEVOPS-AIRGAP-58-002: added sealed-mode observability compose stack (Prometheus/Grafana/Tempo/Loki) with offline configs plus health script under `ops/devops/airgap/`; ready for sealed-mode bootstrap. | DevOps |
| 2025-11-30 | Completed DEVOPS-SBOM-23-001: added SBOM CI runner (`ops/devops/sbom-ci-runner/run-sbom-ci.sh`) with warmed-cache restore, binlog/TRX outputs, and NuGet cache hash evidence; documented in runner README. | DevOps |
| 2025-11-30 | Completed DEVOPS-SCANNER-CI-11-001: added offline-friendly Scanner CI runner (`ops/devops/scanner-ci-runner/run-scanner-ci.sh`) and README; produces build binlog + TRX outputs from key test projects with warmed NuGet cache. | DevOps |
| 2025-11-30 | Completed DEVOPS-ATTEST-73-001/73-002: added attestor CI stub (`ops/devops/attestation/ci.yml`) and secrets/rotation plan in `ops/devops/attestation/README.md`; pending mirror into `.gitea/workflows/attestor-ci.yml` for live runs. | DevOps |
| 2025-11-30 | Completed DEVOPS-SPANSINK-31-003: added OTLP span sink compose stack + collector config (`docker-compose.spansink.yml`, `otel-spansink.yaml`), run script, and Grafana dashboard stub (`ops/devops/signals/dashboards/excititor-vex-traces.json`). | DevOps |
@@ -68,6 +70,7 @@ Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - A
| 2025-11-24 | Added DEVOPS-SCANNER-JAVA-21-011-REL (moved from SPRINT_0131_0001_0001_scanner_surface.md) to keep DevOps release packaging in ops track. | Project Mgmt |
| 2025-11-24 | Added DEVOPS-SPANSINK-31-003 (Excititor span sink for 31-003 traces) moved from SPRINT_0119_0001_0001_excititor_i per ops-only directive. | Project Mgmt |
| 2025-11-24 | Imported Concelier feed ops items FEED-REMEDIATION-1001 and FEEDCONN-ICSCISA/KISA from Sprint 110; keeping feed remediation in ops track. | Project Mgmt |
| 2025-11-30 | Completed DEVOPS-AIRGAP-58-001: added syslog/SMTP compose stack (`ops/devops/airgap/compose-syslog-smtp.yaml`) and health script (`health_syslog_smtp.sh`); documented in airgap README for sealed environments. | DevOps |
| 2025-11-30 | DEVOPS-AIAI-31-001 DONE: added Advisory AI CI harness (`ops/devops/advisoryai-ci-runner/run-advisoryai-ci.sh`) producing binlog/TRX/summary; warmed local NuGet cache for offline runs; docs in runner README. | DevOps |
## Decisions & Risks

View File

@@ -1074,8 +1074,8 @@
| GO-34-001 | DONE | | SPRINT_0153_0001_0003_orchestrator_iii | Worker SDK Guild | src/Orchestrator/StellaOps.Orchestrator.WorkerSdk.Go | GO-33-002 | GO-33-002 | GOSD0101 |
| GRAPH-21-001 | TODO | | SPRINT_136_scanner_surface | Scanner WebService Guild | src/Scanner/StellaOps.Scanner.WebService | Link-Not-Merge schema | Link-Not-Merge schema | GRSC0101 |
| GRAPH-21-002 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_113_concelier_ii | Concelier Core Guild · Scanner Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 |
| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 |
| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 |
| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 |
| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 |
| GRAPH-21-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_120_excititor_ii | Excititor Storage Guild | src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 |
| GRAPH-24-001 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | GRSC0101 outputs | GRSC0101 outputs | GRUI0101 |
| GRAPH-24-002 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild | src/UI/StellaOps.UI | GRAPH-24-001 | GRAPH-24-001 | GRUI0101 |
@@ -1186,8 +1186,8 @@
| LNM-21-203 | TODO | | SPRINT_113_concelier_ii | CLI Guild | src/Concelier/StellaOps.Concelier.WebService | Export reporting. | LNM-21-202 | LNMC0101 |
| LNM-22-001 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | CLI/UI shared components. | DOLN0101 | LNMC0101 |
| LNM-22-002 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | Additional filters. | LNM-22-001 | LNMC0101 |
| LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 |
| LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 |
| LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 |
| LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 |
| LNM-22-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_305_docs_tasks_md_v | Docs + UI Guild | | Docs update for UI flows. | DOCS-LNM-22-004 | IMPT0101 |
| LNM-22-007 | TODO | | SPRINT_305_docs_tasks_md_v | Docs Guild · Observability Guild | docs/modules/concelier/link-not-merge.md | Publish `/docs/observability/aggregation.md` with metrics/traces/logs/SLOs. Dependencies: DOCS-LNM-22-005. | DOCS-LNM-22-005 | DOLN0102 |
| LNM-22-008 | DONE | 2025-11-03 | SPRINT_117_concelier_vi | Docs Guild · DevOps Guild | docs/modules/concelier/link-not-merge.md | Document Link-Not-Merge migration playbook updates in `docs/migration/no-merge.md`, including rollback guidance. | LNM-22-007 | DOLN0102 |
@@ -1338,16 +1338,16 @@
| PLG7.IMPL-006 | DONE (2025-11-09) | 2025-11-09 | SPRINT_100_identity_signing | BE-Auth Plugin (src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap) | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap | LDAP bootstrap provisioning + health status + docs. | LDAP bootstrap provisioning added (write probe, Mongo audit mirror, capability downgrade + health status) with docs/tests + sample manifest updates. | PLGN0101 |
| POL-005 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild | `src/Policy/StellaOps.Policy.Engine`, `docs/modules/policy/architecture.md`, `docs/reachability/function-level-evidence.md` | Ingest reachability facts, expose `reachability.state/confidence`, auto-suppress low confidence, emit OpenVEX evidence. | GAPG0101 | PORE0101 |
| POLICY-0001 | DONE | 2025-11-10 | SPRINT_0138_0000_0001_scanner_ruby_parity | Policy Guild, Ruby Analyzer Guild (docs/modules/scanner) | docs/modules/scanner | | SCANNER-ENG-0018 | |
| POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-20-001 | TODO | | SPRINT_114_concelier_iii | Concelier WebService Guild | src/Concelier/StellaOps.Concelier.WebService | Provide batch advisory lookup APIs for Policy Engine (purl/advisory filters, tenant scopes, explain metadata). | ATLN0101 | CCPR0102 |
| POLICY-20-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | Expand linkset builders with vendor equivalence tables, NEVRA/PURL normalization, version-range parsing. | POLICY-20-001 | CCPR0102 |
| POLICY-20-003 | TODO | | SPRINT_115_concelier_iv | Concelier Storage Guild | src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo | Introduce advisory selection cursors + change-stream checkpoints with offline migration scripts. | POLICY-20-002 | CCPR0102 |
| POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Implement Policy Studio UI surfaces wiring to new APIs (editor, simulation, dashboards). | ORSC0101 | UIPD0101 |
| POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Implement Policy Studio UI surfaces wiring to new APIs (editor, simulation, dashboards). | ORSC0101 | UIPD0101 |
| POLICY-23-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | Add secondary indexes/materialized views (alias, severity, confidence) for fast policy lookups. | POLICY-20-003 | CCPR0102 |
| POLICY-23-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Platform Events Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | Ensure `advisory.linkset.updated` events carry idempotent IDs/confidence summaries/tenant metadata for replay. | POLICY-23-001 | CCPR0102 |
| POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-004 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | |
| POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-006 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | |
| POLICY-23-007 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, DevEx/CLI Guild (docs) | | | | |
| POLICY-23-008 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, Architecture Guild (docs) | | | | |
@@ -1819,8 +1819,8 @@
| SIG-003 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md`) | `src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md` | | | |
| SIG-26-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Signals Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | |
| SIG-26-002 | TODO | | SPRINT_204_cli_iv | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | |
| SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-005 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, UI Guild (docs) | | | | |
| SIG-26-006 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, DevEx/CLI Guild (docs) | | | | |
| SIG-26-007 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, BE-Base Platform Guild (docs) | | | | |
@@ -1935,7 +1935,7 @@
| SYMS-SERVER-401-011 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Symbols Guild | `src/Symbols/StellaOps.Symbols.Server` | Deliver `StellaOps.Symbols.Server` (REST+gRPC) with DSSE-verified uploads, Mongo/MinIO storage, tenant isolation, and deterministic debugId indexing; publish health/manifest APIs (spec: `docs/specs/SYMBOL_MANIFEST_v1.md`). | Depends on #5 | RBSY0101 |
| TASKRUN-41-001 | DONE (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0002_taskrunner_blockers | Task Runner Guild | src/TaskRunner/StellaOps.TaskRunner | Bootstrap service, define migrations for `pack_runs`, `pack_run_logs`, `pack_artifacts`, implement run API (create/get/log stream), local executor, approvals pause, artifact capture, and provenance manifest generation. | Delivered per Task Pack advisory and architecture contract. | ORTR0101 |
| TASKRUN-AIRGAP-56-001 | DONE (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Policy Guild | src/TaskRunner/StellaOps.TaskRunner | Enforce plan-time validation rejecting steps with non-allowlisted network calls in sealed mode and surface remediation errors. | TASKRUN-41-001 | ORTR0101 |
| TASKRUN-AIRGAP-56-002 | BLOCKED (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Importer Guild | src/TaskRunner/StellaOps.TaskRunner | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. | TASKRUN-AIRGAP-56-001 | ORTR0101 |
| TASKRUN-AIRGAP-56-002 | DOING (2025-12-01) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Importer Guild | src/TaskRunner/StellaOps.TaskRunner | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. | TASKRUN-AIRGAP-56-001 | ORTR0101 |
| TASKRUN-AIRGAP-57-001 | BLOCKED (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Controller Guild | src/TaskRunner/StellaOps.TaskRunner | Refuse to execute plans when environment sealed=false but declared sealed install; emit advisory timeline events. | TASKRUN-AIRGAP-56-002 | ORTR0101 |
| TASKRUN-AIRGAP-58-001 | BLOCKED (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · Evidence Locker Guild | src/TaskRunner/StellaOps.TaskRunner | Capture bundle import job transcripts, hashed inputs, and outputs into portable evidence bundles. | TASKRUN-AIRGAP-57-001 | ORTR0101 |
| TASKRUN-42-001 | BLOCKED (2025-11-25) | 2025-11-25 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild (`src/TaskRunner/StellaOps.TaskRunner`) | src/TaskRunner/StellaOps.TaskRunner | Execution engine enhancements (loops/conditionals/maxParallel), simulation mode, policy gate integration, deterministic failure recovery. Blocked: loop/conditional semantics and policy-gate evaluation contract not published. | | ORTR0102 |
@@ -1995,29 +1995,29 @@
| UI-GRAPH-24-004 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add side panels (Details, What-if, History) with upgrade simulation integration and SBOM diff viewer. Dependencies: UI-GRAPH-24-003. | | |
| UI-GRAPH-24-006 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild, Accessibility Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Ensure accessibility (keyboard nav, screen reader labels, contrast), add hotkeys (`f`,`e`,`.`), and analytics instrumentation. Dependencies: UI-GRAPH-24-004. | | |
| UI-LNM-22-001 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Evidence panel showing policy decision with advisory observations/linksets side-by-side, conflict badges, AOC chain, and raw doc download links. Docs `DOCS-LNM-22-005` waiting on delivered UI for screenshots + flows. | | |
| UI-LNM-22-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | |
| UI-LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | |
| UI-LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | |
| UI-LNM-22-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | |
| UI-LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | |
| UI-LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | |
| UI-OPS-0001 | TODO | | SPRINT_331_docs_modules_ui | Ops Guild (docs/modules/ui) | docs/modules/ui | | | |
| UI-ORCH-32-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | |
| UI-POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | |
| UI-POLICY-20-001 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, diagnostics, and checklist sidebar. | POLICY-13-007 | UIPD0101 |
| UI-POLICY-20-002 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, deterministic diffs. | UI-POLICY-20-001 | UIPD0101 |
| UI-POLICY-20-003 | TODO | | SPRINT_210_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, and RBAC checks aligned to new Policy Studio roles (`policy:author`/`policy:review`/`policy:approve`/`policy:operate`). Dependencies: UI-POLICY-20-002. | Requires 20-002 results | |
| UI-POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filter/search and export. Dependencies: UI-POLICY-20-003. | Depends on 20-003 | |
| UI-POLICY-23-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | |
| UI-POLICY-23-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | |
| UI-POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | |
| UI-POLICY-23-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | |
| UI-POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | |
| UI-POLICY-23-006 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | |
| UI-POLICY-27-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | |
| UI-ORCH-32-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | |
| UI-POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | |
| UI-POLICY-20-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, diagnostics, and checklist sidebar. | POLICY-13-007 | UIPD0101 |
| UI-POLICY-20-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, deterministic diffs. | UI-POLICY-20-001 | UIPD0101 |
| UI-POLICY-20-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, and RBAC checks aligned to new Policy Studio roles (`policy:author`/`policy:review`/`policy:approve`/`policy:operate`). Dependencies: UI-POLICY-20-002. | Requires 20-002 results | |
| UI-POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filter/search and export. Dependencies: UI-POLICY-20-003. | Depends on 20-003 | |
| UI-POLICY-23-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | |
| UI-POLICY-23-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | |
| UI-POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | |
| UI-POLICY-23-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | |
| UI-POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | |
| UI-POLICY-23-006 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | |
| UI-POLICY-27-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | |
| UI-POLICY-DET-01 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Wire policy gate indicators + remediation hints into Release/Policy flows, blocking publishes when determinism checks fail; coordinate with Policy Engine schema updates. Dependencies: UI-SBOM-DET-01. | | |
| UI-SBOM-DET-01 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add a """Determinism""" badge plus drill-down that surfaces fragment hashes, `_composition.json`, and Merkle root consistency when viewing scan details (per `docs/modules/scanner/deterministic-sbom-compose.md`). | | |
| UI-SIG-26-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | |
| UI-SIG-26-002 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | |
| UI-SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | |
| UI-SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | |
| UI-SIG-26-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | |
| UI-SIG-26-002 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | |
| UI-SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | |
| UI-SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | |
| UNCERTAINTY-POLICY-401-026 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild · Concelier Guild (`docs/policy/dsl.md`, `docs/uncertainty/README.md`) | `docs/policy/dsl.md`, `docs/uncertainty/README.md` | Update policy guidance (Concelier/Excitors) with uncertainty gates (U1/U2/U3), sample YAML rules, and remediation actions. | | |
| UNCERTAINTY-SCHEMA-401-024 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md` | Extend Signals findings with `uncertainty.states[]`, entropy fields, and `riskScore`; emit `FindingUncertaintyUpdated` events and persist evidence per docs. | | |
| UNCERTAINTY-SCORER-401-025 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md` | Implement the entropy-aware risk scorer (`riskScore = base × reach × trust × (1 + entropyBoost)`) and wire it into finding writes. | | |
@@ -2100,7 +2100,7 @@
| WEB-AIRGAP-56-002 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AIRGAP-57-001 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild, AirGap Policy Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AIRGAP-58-001 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild, AirGap Importer Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AOC-19-002 | TODO | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ship `ProvenanceBuilder`, checksum utilities, and signature verification helper integrated with guard logging. Cover DSSE/CMS formats with unit tests. Dependencies: WEB-AOC-19-001. | | |
| WEB-AOC-19-002 | DONE (2025-11-30) | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ship `ProvenanceBuilder`, checksum utilities, and signature verification helper integrated with guard logging. Cover DSSE/CMS formats with unit tests. Dependencies: WEB-AOC-19-001. | | |
| WEB-AOC-19-003 | TODO | | SPRINT_116_concelier_v | QA Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AOC-19-004 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild, QA Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AOC-19-005 | TODO | 2025-11-08 | SPRINT_116_concelier_v | Concelier WebService Guild, QA Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
@@ -2115,19 +2115,19 @@
| WEB-CONTAINERS-45-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ensure readiness endpoints reflect DB/queue readiness, add feature flag toggles via config map, and document NetworkPolicy ports. Dependencies: WEB-CONTAINERS-44-001. | | |
| WEB-CONTAINERS-46-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide offline-friendly asset serving (no CDN), allow overriding object store endpoints via env, and document fallback behavior. Dependencies: WEB-CONTAINERS-45-001. | | |
| WEB-EXC-25-001 | TODO | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement `/exceptions` API (create, propose, approve, revoke, list, history) with validation, pagination, and audit logging. | | |
| WEB-EXC-25-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | |
| WEB-EXC-25-003 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | |
| WEB-EXPORT-35-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | |
| WEB-EXPORT-36-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | |
| WEB-EXPORT-37-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | |
| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | |
| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | |
| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | |
| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | |
| WEB-GRAPH-24-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | |
| WEB-GRAPH-24-004 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | |
| WEB-LNM-21-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | |
| WEB-LNM-21-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | |
| WEB-EXC-25-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | |
| WEB-EXC-25-003 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | |
| WEB-EXPORT-35-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | |
| WEB-EXPORT-36-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | |
| WEB-EXPORT-37-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | |
| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | |
| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | |
| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | |
| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | |
| WEB-GRAPH-24-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | |
| WEB-GRAPH-24-004 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | |
| WEB-LNM-21-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | |
| WEB-LNM-21-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | |
| WEB-LNM-21-003 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide combined endpoint for Console to fetch policy result + source evidence (advisory + VEX linksets) for a component. Dependencies: WEB-LNM-21-002. | | |
| WEB-NOTIFY-38-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Route notifier APIs (`/notifications/*`) and WS feed through gateway with tenant scoping, viewer/operator scope enforcement, and SSE/WebSocket bridging. | Depends on #1 for signed ack spec | NOWB0101 |
| WEB-NOTIFY-39-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Surface digest scheduling, quiet-hour/throttle management, and simulation APIs; ensure rate limits and audit logging. Dependencies: WEB-NOTIFY-38-001. | WEB-NOTIFY-38-001 | NOWB0101 |
@@ -3293,8 +3293,8 @@
| GO-34-001 | DONE | | SPRINT_0153_0001_0003_orchestrator_iii | Worker SDK Guild | src/Orchestrator/StellaOps.Orchestrator.WorkerSdk.Go | GO-33-002 | GO-33-002 | GOSD0101 |
| GRAPH-21-001 | TODO | | SPRINT_136_scanner_surface | Scanner WebService Guild | src/Scanner/StellaOps.Scanner.WebService | Link-Not-Merge schema | Link-Not-Merge schema | GRSC0101 |
| GRAPH-21-002 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_113_concelier_ii | Concelier Core Guild · Scanner Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 |
| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 |
| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 |
| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 |
| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 |
| GRAPH-21-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_120_excititor_ii | Excititor Storage Guild | src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 |
| GRAPH-24-005 | TODO | | SPRINT_304_docs_tasks_md_iv | UI Guild | | GRAPH-24-003 | GRAPH-24-003 | GRUI0101 |
| GRAPH-24-007 | TODO | | SPRINT_304_docs_tasks_md_iv | UI Guild | | GRAPH-24-005 | GRAPH-24-005 | GRUI0101 |
@@ -3400,8 +3400,8 @@
| LNM-21-203 | TODO | | SPRINT_113_concelier_ii | CLI Guild | src/Concelier/StellaOps.Concelier.WebService | Export reporting. | LNM-21-202 | LNMC0101 |
| LNM-22-001 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | CLI/UI shared components. | DOLN0101 | LNMC0101 |
| LNM-22-002 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | Additional filters. | LNM-22-001 | LNMC0101 |
| LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 |
| LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 |
| LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 |
| LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 |
| LNM-22-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_305_docs_tasks_md_v | Docs + UI Guild | | Docs update for UI flows. | DOCS-LNM-22-004 | IMPT0101 |
| LNM-22-007 | TODO | | SPRINT_305_docs_tasks_md_v | Docs Guild · Observability Guild | docs/modules/concelier/link-not-merge.md | Publish `/docs/observability/aggregation.md` with metrics/traces/logs/SLOs. Dependencies: DOCS-LNM-22-005. | DOCS-LNM-22-005 | DOLN0102 |
| LNM-22-008 | DONE | 2025-11-03 | SPRINT_117_concelier_vi | Docs Guild · DevOps Guild | docs/modules/concelier/link-not-merge.md | Document Link-Not-Merge migration playbook updates in `docs/migration/no-merge.md`, including rollback guidance. | LNM-22-007 | DOLN0102 |
@@ -3552,16 +3552,16 @@
| PLG7.IMPL-006 | DONE (2025-11-09) | 2025-11-09 | SPRINT_100_identity_signing | BE-Auth Plugin (src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap) | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap | LDAP bootstrap provisioning added (write probe, Mongo audit mirror, capability downgrade + health status) with docs/tests + sample manifest updates. | LDAP bootstrap provisioning added (write probe, Mongo audit mirror, capability downgrade + health status) with docs/tests + sample manifest updates. | |
| POL-005 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild | `src/Policy/StellaOps.Policy.Engine`, `docs/modules/policy/architecture.md`, `docs/reachability/function-level-evidence.md` | Ingest reachability facts, expose SPL signals, auto-suppress <0.30, emit OpenVEX evidence. | Needs reachability feed GAPG0101 | |
| POLICY-0001 | DONE | 2025-11-10 | SPRINT_0138_0000_0001_scanner_ruby_parity | Policy Guild, Ruby Analyzer Guild (docs/modules/scanner) | docs/modules/scanner | | SCANNER-ENG-0018 | |
| POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-20-001 | TODO | | SPRINT_114_concelier_iii | Concelier WebService Guild | src/Concelier/StellaOps.Concelier.WebService | Provide batch advisory lookup APIs for Policy (purl/advisory filters, explain metadata). | Needs latest advisory schemas | |
| POLICY-20-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | Expand linkset builders with vendor equivalence tables, NEVRA/PURL normalization, version-range parsing. | Depends on 20-001 | |
| POLICY-20-003 | TODO | | SPRINT_115_concelier_iv | Concelier Storage Guild | src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo | Introduce advisory selection cursors + change-stream checkpoints with offline migration scripts. | Needs 20-002 index/schema | |
| POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Wire UI to new policy evidence APIs, bridging editor + simulation flows. | Needs ORSC0101 APIs | |
| POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Wire UI to new policy evidence APIs, bridging editor + simulation flows. | Needs ORSC0101 APIs | |
| POLICY-23-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | |
| POLICY-23-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Platform Events Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | |
| POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-004 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | |
| POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| POLICY-23-006 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | |
| POLICY-23-007 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, DevEx/CLI Guild (docs) | | | | |
| POLICY-23-008 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, Architecture Guild (docs) | | | | |
@@ -4031,8 +4031,8 @@
| SIG-003 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md`) | `src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md` | | | |
| SIG-26-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Signals Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | |
| SIG-26-002 | TODO | | SPRINT_204_cli_iv | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | |
| SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | |
| SIG-26-005 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, UI Guild (docs) | | | | |
| SIG-26-006 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, DevEx/CLI Guild (docs) | | | | |
| SIG-26-007 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, BE-Base Platform Guild (docs) | | | | |
@@ -4187,27 +4187,27 @@
| UI-CLI-401-007 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | UI & CLI Guilds (`src/Cli/StellaOps.Cli`, `src/UI/StellaOps.UI`) | `src/Cli/StellaOps.Cli`, `src/UI/StellaOps.UI` | Implement CLI `stella graph explain` + UI explain drawer showing signed call-path, predicates, runtime hits, and DSSE pointers; include counterfactual controls. | | |
| UI-DOCS-0001 | TODO | | SPRINT_331_docs_modules_ui | Docs Guild (docs/modules/ui) | docs/modules/ui | | | |
| UI-ENG-0001 | TODO | | SPRINT_331_docs_modules_ui | Module Team (docs/modules/ui) | docs/modules/ui | | | |
| UI-LNM-22-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | |
| UI-LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | |
| UI-LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | |
| UI-LNM-22-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | |
| UI-LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | |
| UI-LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | |
| UI-OPS-0001 | TODO | | SPRINT_331_docs_modules_ui | Ops Guild (docs/modules/ui) | docs/modules/ui | | | |
| UI-ORCH-32-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | |
| UI-POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | |
| UI-POLICY-20-001 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, inline diagnostics, and compliance checklist sidebar. Dependencies: UI-POLICY-13-007. | Depends on Policy DSL schema | |
| UI-POLICY-20-002 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, and rule hit summaries with deterministic diff rendering. Dependencies: UI-POLICY-20-001. | Needs 20-001 editor events | |
| UI-POLICY-20-003 | TODO | | SPRINT_210_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, RBAC. | UI-POLICY-20-002 | UIPD0101 |
| UI-POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filters/export. | UI-POLICY-20-003 | UIPD0101 |
| UI-POLICY-23-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | |
| UI-POLICY-23-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | |
| UI-POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | |
| UI-POLICY-23-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | |
| UI-POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | |
| UI-POLICY-23-006 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | |
| UI-POLICY-27-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | |
| UI-SIG-26-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | |
| UI-SIG-26-002 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | |
| UI-SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | |
| UI-SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | |
| UI-ORCH-32-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | |
| UI-POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | |
| UI-POLICY-20-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, inline diagnostics, and compliance checklist sidebar. Dependencies: UI-POLICY-13-007. | Depends on Policy DSL schema | |
| UI-POLICY-20-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, and rule hit summaries with deterministic diff rendering. Dependencies: UI-POLICY-20-001. | Needs 20-001 editor events | |
| UI-POLICY-20-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, RBAC. | UI-POLICY-20-002 | UIPD0101 |
| UI-POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filters/export. | UI-POLICY-20-003 | UIPD0101 |
| UI-POLICY-23-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | |
| UI-POLICY-23-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | |
| UI-POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | |
| UI-POLICY-23-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | |
| UI-POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | |
| UI-POLICY-23-006 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | |
| UI-POLICY-27-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | |
| UI-SIG-26-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | |
| UI-SIG-26-002 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | |
| UI-SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | |
| UI-SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | |
| UNCERTAINTY-POLICY-401-026 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild · Concelier Guild (`docs/policy/dsl.md`, `docs/uncertainty/README.md`) | `docs/policy/dsl.md`, `docs/uncertainty/README.md` | Update policy guidance (Concelier/Excitors) with uncertainty gates (U1/U2/U3), sample YAML rules, and remediation actions. | | |
| UNCERTAINTY-SCHEMA-401-024 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md` | Extend Signals findings with `uncertainty.states[]`, entropy fields, and `riskScore`; emit `FindingUncertaintyUpdated` events and persist evidence per docs. | | |
| UNCERTAINTY-SCORER-401-025 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md` | Implement the entropy-aware risk scorer (`riskScore = base × reach × trust × (1 + entropyBoost)`) and wire it into finding writes. | | |
@@ -4290,7 +4290,7 @@
| WEB-AIRGAP-56-002 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AIRGAP-57-001 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild, AirGap Policy Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AIRGAP-58-001 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild, AirGap Importer Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AOC-19-002 | TODO | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ship `ProvenanceBuilder`, checksum utilities, and signature verification helper integrated with guard logging. Cover DSSE/CMS formats with unit tests. Dependencies: WEB-AOC-19-001. | | |
| WEB-AOC-19-002 | DONE (2025-11-30) | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ship `ProvenanceBuilder`, checksum utilities, and signature verification helper integrated with guard logging. Cover DSSE/CMS formats with unit tests. Dependencies: WEB-AOC-19-001. | | |
| WEB-AOC-19-003 | TODO | | SPRINT_116_concelier_v | QA Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AOC-19-004 | TODO | | SPRINT_116_concelier_v | Concelier WebService Guild, QA Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
| WEB-AOC-19-005 | TODO | 2025-11-08 | SPRINT_116_concelier_v | Concelier WebService Guild, QA Guild (src/Concelier/StellaOps.Concelier.WebService) | src/Concelier/StellaOps.Concelier.WebService | | | |
@@ -4305,19 +4305,19 @@
| WEB-CONTAINERS-45-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ensure readiness endpoints reflect DB/queue readiness, add feature flag toggles via config map, and document NetworkPolicy ports. Dependencies: WEB-CONTAINERS-44-001. | | |
| WEB-CONTAINERS-46-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide offline-friendly asset serving (no CDN), allow overriding object store endpoints via env, and document fallback behavior. Dependencies: WEB-CONTAINERS-45-001. | | |
| WEB-EXC-25-001 | TODO | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement `/exceptions` API (create, propose, approve, revoke, list, history) with validation, pagination, and audit logging. | | |
| WEB-EXC-25-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | |
| WEB-EXC-25-003 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | |
| WEB-EXPORT-35-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | |
| WEB-EXPORT-36-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | |
| WEB-EXPORT-37-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | |
| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | |
| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | |
| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | |
| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | |
| WEB-GRAPH-24-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | |
| WEB-GRAPH-24-004 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | |
| WEB-LNM-21-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | |
| WEB-LNM-21-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | |
| WEB-EXC-25-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | |
| WEB-EXC-25-003 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | |
| WEB-EXPORT-35-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | |
| WEB-EXPORT-36-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | |
| WEB-EXPORT-37-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | |
| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | |
| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | |
| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | |
| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | |
| WEB-GRAPH-24-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | |
| WEB-GRAPH-24-004 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | |
| WEB-LNM-21-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | |
| WEB-LNM-21-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | |
| WEB-LNM-21-003 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide combined endpoint for Console to fetch policy result + source evidence (advisory + VEX linksets) for a component. Dependencies: WEB-LNM-21-002. | | |
| WEB-NOTIFY-38-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Route notifier APIs (`/notifications/*`) and WS feed through gateway with tenant scoping, viewer/operator scope enforcement, and SSE/WebSocket bridging. | Depends on #1 for signed ack spec | NOWB0101 |
| WEB-NOTIFY-39-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Surface digest scheduling, quiet-hour/throttle management, and simulation APIs; ensure rate limits and audit logging. Dependencies: WEB-NOTIFY-38-001. | WEB-NOTIFY-38-001 | NOWB0101 |

View File

@@ -8,6 +8,23 @@ This dossier summarises the end-to-end runtime topology after the Aggregation-On
---
> Need a quick orientation? The [Developer Quickstart](../onboarding/dev-quickstart.md) (29-Nov-2025 advisory) captures the core repositories, determinism checks, DSSE conventions, and starter tasks that explain how the platform pieces fit together.
> Planner note: the [SBOM→VEX proof blueprint](../product-advisories/29-Nov-2025 - SBOM to VEX Proof Pipeline Blueprint.md) shows the DSSE → Rekor v2 tiles → VEX linkage, so threat-model and compliance teams can copy the capture/verification checkpoints.
> Working on a feature? Check the [Implementor Guidelines](../product-advisories/30-Nov-2025 - Implementor Guidelines for Stella Ops.md) to align with the SRS + release playbook checklist before you merge anything into main.
> Need to prove Rekor receipts? The [Rekor Receipt Checklist](../product-advisories/30-Nov-2025 - Rekor Receipt Checklist for Stella Ops.md) maps each field to a module owner and explains offline metadata for deterministic re-verification.
> Taming unknowns? The [Unknowns Decay & Triage Heuristics](../product-advisories/30-Nov-2025 - Unknowns Decay & Triage Heuristics.md) explains the confidence decay card, triage queue view, and the daily export artifact for planning.
> Check the [Ecosystem Reality Test Cases](../product-advisories/30-Nov-2025 - Ecosystem Reality Test Cases for StellaOps.md) for reproducible acceptance tests based on credential leaks, offline DB schema issues, SBOM parity drift, and scanner version divergence.
> Need unblocker tasks? The [Standup Sprint Kickstarters](../product-advisories/30-Nov-2025 - Standup Sprint Kickstarters.md) lists three day-0 wins (scanner regressions, Postgres slice, DSSE/Rekor sweep) plus ready-to-copy ticket names.
> Compare how evidence/suppression/audit flows work elsewhere via the [Comparative Evidence Patterns](../product-advisories/30-Nov-2025 - Comparative Evidence Patterns for Stella Ops.md) brief—Snyk, GitHub, Aqua, Anchore/Grype, Prisma Cloud, and the UX trade-offs.
> Evaluate public scanner incidents? The [Ecosystem Test Cases](../product-advisories/30-Nov-2025 - Ecosystem Test Cases for StellaOps.md) document five hardened regressions (Grype credential leak, Trivy offline schema, SBOM parity, Grype instability) that you can turn into acceptance tests today.
## 1·System landscape
```mermaid

View File

@@ -0,0 +1,326 @@
# StellaOps Developer Quickstart
> **Audience:** Mid-level .NET developers
> **Goal:** Get you productive on StellaOps in 12 days, with special focus on determinism, cryptographic attestations, and the canonical data model.
---
This quickstart mirrors the 29-Nov-2025 Developer Onboarding advisory (`docs/product-advisories/29-Nov-2025 - StellaOps Mid-Level .NET Onboarding (Quick Start).md`) and keeps the determinism-first guidance in sync with that release note.
## 1. What Youre Building (Context)
StellaOps is a sovereign, air-gap-friendly platform that turns **SBOMs → VEX** with a fully **replayable, deterministic trust graph**.
Core concepts:
- **Deterministic scans:** Same inputs → same graph, hashes, and verdicts.
- **Cryptographic attestations:** DSSE/in-toto envelopes, optional PQC.
- **Trust lattice:** Merges vendor VEX, runtime signals, configs, etc. into a single deterministic verdict.
- **Audit trail:** Every decision is reproducible from stored inputs and proofs.
If you think “content-addressed trust pipeline for SBOMs + VEX,” youre in the right mental model.
---
## 2. Repository & Docs Map
Start by opening these projects **in order**:
1. `src/StellaOps.Scanner.WebService/`
Scanning endpoints, rule plumbing, and calls into the trust lattice.
2. `src/StellaOps.Vexer/` (a.k.a. *Excititor*)
VEX verdict engine and trust-merge logic.
3. `src/StellaOps.Sbomer/`
SBOM ingest / normalize (CycloneDX, SPDX).
4. `src/StellaOps.Authority/`
Key management, DSSE/in-toto attestations, license tokens, Rekor integration.
5. `src/StellaOps.Scheduler/`
Batch processing, replay orchestration.
6. `src/StellaOps.Shared/CanonicalModel/`
Canonical entities & graph IDs. **Read this carefully** it underpins determinism.
Helpful docs:
- `docs/modules/platform/*` protocols (DSSE envelopes, lattice terms, trust receipts).
- `docs/architecture/*` high-level diagrams and flows.
---
## 3. Local Dev Setup
### 3.1 Prerequisites
- **.NET 10 SDK** (preview as specified in repo).
- **Docker** (for DB, queues, object storage).
- **Node.js** (for Angular UI, if youre touching the frontend).
- **WSL2** (optional but convenient on Windows).
### 3.2 Bring Up Infra
From the repo root:
```bash
# Bring up core infra for offline / air-gap friendly dev
docker compose -f compose/offline-kit.yml up -d
```
This usually includes:
- MongoDB or Postgres (configurable).
- RabbitMQ (or equivalent queue).
- MinIO / object storage (depending on profile).
### 3.3 Configure Environment
```bash
cp env/example.local.env .env
```
Key settings:
- `STELLAOPS_DB=Mongo` or `Postgres`.
- `AUTHORITY_*` key material and config (see comments in `example.local.env`).
- Optional: `AUTHORITY_PQC=on` to enable post-quantum keys (Dilithium).
### 3.4 Build & Run Backend
```bash
# Restore & build everything
dotnet restore
dotnet build -c Debug
# Run a focused slice for development
dotnet run --project src/StellaOps.Authority/StellaOps.Authority.csproj
dotnet run --project src/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj
```
Health checks (adjust ports if needed):
```bash
curl -s http://localhost:5080/health # Authority
curl -s http://localhost:5081/health # Scanner
```
---
## 4. Deterministic Sanity Tests
These tests prove your local environment is configured correctly for **determinism**. If any of these fail due to snapshot mismatch, fix your environment before writing new features.
### 4.1 SBOM → VEX “Not Affected” (Reachability False)
```bash
dotnet test tests/Determinism/Det_SbomToVex_NotAffected.csproj
```
**What it checks:**
- Two consecutive runs with the same SBOM produce identical `GraphRevisionID` and DSSE payload hashes.
If they differ, inspect:
- JSON canonicalization.
- Locale / culture.
- Line endings.
### 4.2 In-toto Chain: Source → Build → Image Attestation
```bash
dotnet test tests/Attestations/Att_InToto_Chain.csproj
```
**What it checks:**
- DSSE envelope canonicalization is stable.
- Signature over CBOR-canonical JSON matches the stored hash.
- Full in-toto chain can be replayed deterministically.
### 4.3 Lattice Merge: Vendor VEX + Runtime Signal
```bash
dotnet test tests/Lattice/Lattice_VendorPlusRuntime.csproj
```
**What it checks:**
- Merge verdict is stable regardless of input set order.
- Resulting `TrustReceipt` is byte-for-byte identical between runs.
If any “golden” snapshots differ, you likely have:
- Non-canonical JSON.
- Unstable enumeration (e.g., iterating `Dictionary<>` directly).
- Locale or newline drift.
---
## 5. Coding Conventions (Determinism & Crypto)
These are **non-negotiable** in code that affects trust graphs, proofs, or attestations.
### 5.1 JSON & Canonicalization
- Use the **`CanonicalJson`** helper whenever a payload is hashed, signed, or used for IDs.
- Rules: UTF-8, sorted keys, no insignificant whitespace, `\n` line endings.
### 5.2 DSSE Envelopes
- `payloadType` must always be `application/vnd.stellaops.trust+json`.
- Sign over the canonicalized bytes.
```csharp
var payload = CanonicalJson.Serialize(trustDoc);
var env = DsseEnvelope.Create("application/vnd.stellaops.trust+json", payload);
var signed = await keyRing.SignAsync(env.CanonicalizeBytes());
await rekor.SubmitAsync(signed, RekorMode.OfflineMirrorIfAirgapped);
```
### 5.3 Hashing
- **BLAKE3** for internal content addressing.
- **SHA-256** where interop demands it.
- Never mix algorithms within the same ID type.
### 5.4 Keys & Algorithms
- Default signatures: **Ed25519** via `Authority.KeyRing`.
- Optional PQC: **Dilithium** when `AUTHORITY_PQC=on`.
- Always go through the keyring abstraction; never manage raw keys manually.
### 5.5 Time & Clocks
- Use `Instant`/`DateTimeOffset` (UTC), truncated to milliseconds.
- Never use `DateTime.Now` or local clocks in canonical data.
### 5.6 IDs & Graph Nodes
- Canonical/public IDs derive from hashes of canonical bytes.
- DB primary keys are implementation details.
- Do not depend on DB auto-increment or implicit sort order when hashing.
### 5.7 VEX Verdicts
Every VEX verdict must:
- Carry `proofs[]` (reachability, config guards, runtime paths).
- Emit a `receipt` signed by Authority, covering verdict, proof hashes, and context.
---
## 6. Daily Workflow
1. Pick a focused issue (see starter tasks below).
2. Write tests first, especially determinism scenarios.
3. Implement changes with canonicalization boundaries explicit and signing centralized.
4. Run `dotnet test --filter Category=Determinism`.
5. Commit with the appropriate prefix (`feat(scanner):`, `feat(vexer):`, `feat(authority):`) and mention the affected `GraphRevisionID` if your change alters the trust graph.
---
## 7. Suggested Starter Tasks
These introduce the canonical data model and determinism mindset.
### 7.1 Normalize CycloneDX Components → Canonical Packages
**Area:** `StellaOps.Sbomer`
**Tests:** `tests/Determinism/Det_SbomMapping`
**Definition of done:**
- Equivalent SBOMs (even if fields shuffle) yield identical package sets and canonical IDs.
- `CanonicalPackageSet.hash` is stable.
- Edge cases covered: missing `purl`, duplicate components, case variation.
### 7.2 Implement “Not-Affected by Configuration” Proof
**Area:** `StellaOps.Vexer/Proofs/ConfigSwitchProof.cs`
**Definition of done:**
- With `FeatureX=false`, CVE-1234 reports `status = not_affected` and the proof records `configPath` + `observed=false`.
- Proof hash is deterministic and included in the DSSE receipt.
- Lattice merge flips the verdict to `not_affected` when the runtime/config proof weight crosses the threshold, even if the vendor says `affected`.
### 7.3 Authority Offline Rekor Mirror Submitter
**Area:** `StellaOps.Authority/Rekor/RekorMirrorClient.cs`
**Definition of done:**
- `RekorMode.OfflineMirrorIfAirgapped` records canonical entries (JSON + hash path) locally.
- `rekor sync` replays entries in order, preserving entry IDs.
- Golden test ensures the same input sequence → same mirror tree hash.
---
## 8. Database Notes (Mongo ↔ Postgres)
- Use `StellaOps.Shared.Persistence` repository interfaces.
- Canonical/public IDs are hash-derived; DB keys are internal details.
- Never rely on DB sort order for anything that affects hashes or verdicts; re-canonicalize before hashing and apply deterministic ordering afterwards.
---
## 9. Common Pitfalls
1. Non-canonical JSON (unsorted keys, extra whitespace, mixed `\r\n`).
2. Local time creeping into proofs (`DateTime.Now`).
3. Unstable GUIDs in tests or canonical entities.
4. Unordered collections (`Dictionary<>` iterations, LINQ without `OrderBy`) while hashing or serializing.
5. Platform drift (Windows vs Linux newline/culture differences) always use invariant culture and `\n` in canonical data.
---
## 10. Useful Commands
### 10.1 Determinism Pack
```bash
# Run determinism-tagged fixtures
dotnet test --filter Category=Determinism
```
Update golden snapshots deliberately:
```bash
dotnet test --filter Category=Determinism -- \
TestRunParameters.Parameter(name="UpdateSnapshots", value="true")
```
### 10.2 Quick API Smoke
```bash
curl -s http://localhost:5080/health
curl -s -X POST \
http://localhost:5081/scan \
-H "Content-Type: application/json" \
-d @samples/nginx.sbom.json
```
### 10.3 Verify DSSE Signature Locally
```bash
dotnet run --project tools/StellaOps.Tools.Verify -- file trust.receipt.json
```
---
## 11. Glossary (Ask-Once)
- **SBOM** Software Bill of Materials (CycloneDX/SPDX).
- **VEX** Vulnerability Exploitability eXchange: verdicts include `affected`, `not_affected`, `under_investigation`.
- **DSSE** Dead Simple Signing Envelope; we sign canonical bytes.
- **In-toto** Supply-chain attestation framework for source → build → artifact chains.
- **Lattice** Rule system merging multiple verdicts/proofs into deterministic outcomes.
- **GraphRevisionID** Hash of the canonical trust graph; acts like a build number for audits.
Welcome aboard. Your best “map” is:
1. Read the CanonicalModel types.
2. Run the determinism tests.
3. Ship one of the starter tasks with deterministic, test-covered changes.
Keep everything **canonical, hashable, and replayable** and youll fit right in.

View File

@@ -375,7 +375,7 @@ Signer: release@stella-ops.io
- **Primary Sprint:** SPRINT_0400_cli_ux.md (NEW)
- **Related Sprints:**
- SPRINT_210_ui_ii.md (UI integration)
- SPRINT_0210_0001_0002_ui_ii.md (UI integration)
- SPRINT_0187_0001_0001_evidence_locker_cli_integration.md (Evidence CLI)
**Key Task IDs:**

View File

@@ -515,7 +515,7 @@ The following schemas should be created/maintained:
This advisory maps to:
- **SPRINT_0215_0001_0001_vuln_triage_ux.md** (NEW) - UI triage workspace implementation
- **SPRINT_210_ui_ii.md** - VEX tab tasks (UI-LNM-22-003)
- **SPRINT_0210_0001_0002_ui_ii.md** - VEX tab tasks (UI-LNM-22-003)
- **SPRINT_0334_docs_modules_vuln_explorer.md** - Module documentation updates
---

View File

@@ -0,0 +1,792 @@
Heres a tight, drop-in acceptance-tests pack for Stella Ops that turns common failure modes into concrete guardrails you can ship this sprint.
---
# 1) Feed outages & integrity drift (e.g., Grype DB / CDN hiccups)
**Lesson:** Never couple scans to a single live feed; pin, verify, and cache.
**Add to acceptance tests**
* **Rollback-safe updaters**
* If a feed update fails checksum or signature, the system keeps using the last “good” bundle.
* On restart, the updater falls back to the last verified bundle without network access.
* **Signed offline bundles**
* Every feed bundle (SBOM catalogs, CVE DB shards, rules) must be DSSE-signed; verification blocks ingestion on mismatch.
* Bundle manifest lists SHA-256 for each file; any deviation = reject.
**Test cases (CI)**
* Simulate 404/timeout from feed URL → scanner still produces results from cached bundle.
* Serve a tampered bundle (wrong hash) → updater logs failure; no swap; previous bundle remains active.
* Air-gap mode: no network → scanner loads from `/var/lib/stellaops/offline-bundles/*` and passes verification.
---
# 2) SBOM quality & schema drift
**Lesson:** Garbage in = garbage VEX. Gate on schema, completeness, and provenance.
**Add to acceptance tests**
* **SBOM schema gating**
* Reject SBOMs not valid CycloneDX 1.6 / SPDX 2.3 (your chosen set).
* Require: component `bom-ref`, supplier, version, hashes, and build provenance (SLSA/in-toto attestation) if provided.
* **Minimum completeness**
* Thresholds: ≥95% components with cryptographic hashes; no unknown package ecosystem fields for top 20 deps.
**Test cases**
* Feed malformed CycloneDX → `400 SBOM_VALIDATION_FAILED` with pointer to failing JSON path.
* SBOM missing hashes for >5% of components → blocked from graph ingestion; actionable error.
* SBOM with unsigned provenance when policy="RequireAttestation" → rejected.
---
# 3) DB/data corruption or operator error
**Lesson:** Snapshots save releases.
**Add to acceptance tests**
* **DB snapshot cadence**
* Postgres: base backup nightly + WAL archiving; RPO ≤ 15 min; automated restore rehearsals.
* Mongo (while still in use): per-collection dumps until conversion completes; checksum each artifact.
* **Deterministic replay**
* Any graph view must be reproducible from snapshot + bundle manifest (same revision hash).
**Test cases**
* Run chaos test that deletes last 24h tables → PITR restore to T-15m succeeds; graph revision IDs match pre-failure.
* Restore rehearsal produces identical VEX verdict counts for a pinned revision.
---
# 4) Reachability engines & graph evaluation flakiness
**Lesson:** When reachability is uncertain, degrade gracefully and be explicit.
**Add to acceptance tests**
* **Reachability fallbacks**
* If call-graph build fails or language analyzer missing, verdict moves to “Potentially Affected (Unproven Reach)” with a reason code.
* Policies must allow “conservative mode” (assume reachable) vs “lenient mode” (assume not-reachable) toggled per environment.
* **Stable graph IDs**
* Graph revision ID is a content hash of inputs (SBOM set + rules + feed versions); identical inputs → identical ID.
**Test cases**
* Remove a language analyzer container at runtime → status flips to fallback code; no 500s; policy evaluation still completes.
* Re-ingest same inputs → same graph revision ID and same verdict distribution.
---
# 5) Update pipelines & job routing
**Lesson:** No single point of truth; isolate, audit, and prove swaps.
**Add to acceptance tests**
* **Two-phase bundle swaps**
* Stage → verify → atomic symlink/label swap; all scanners pick up new label within 1 minute, or roll back.
* **Authority-gated policy changes**
* Any policy change (severity threshold, allowlist) is a signed request via Authority; audit trail must include signer and DSSE envelope hash.
**Test cases**
* Introduce a new CVE ruleset; verification passes → atomic swap; running scans continue; new scans use N+1 bundle.
* Attempt policy change with invalid signature → rejected; audit log entry created; unchanged policy in effect.
---
## How to wire this in Stella Ops (quick pointers)
* **Offline bundle format**
* `bundle.json` (manifest: file list + SHA-256 + DSSE signature), `/sboms/*.json`, `/feeds/cve/*.sqlite` (or shards), `/rules/*.yaml`, `/provenance/*.intoto.jsonl`.
* Verification entrypoint in .NET 10: `StellaOps.Bundle.VerifyAsync(manifest, keyring)` before any ingestion.
* **Authority integration**
* Define `PolicyChangeRequest` (subject, diff, reason, expiry, DSSE envelope).
* Gate `PUT /policies/*` behind `Authority.Verify(envelope) == true` and `envelope.subject == computed_diff_hash`.
* **Graph determinism**
* `GraphRevisionId = SHA256(Sort(JSON([SBOMRefs, RulesetVersion, FeedBundleIds, LatticeConfig, NormalizationVersion])))`.
* **Postgres snapshots (until full conversion)**
* Use `pg_basebackup` nightly + `wal-g` for WAL; GitLab job runs restore rehearsal weekly into `stellaops-restore` namespace and asserts revision parity against prod.
---
## Minimal developer checklist (copy to your sprint board)
* [ ] Add `BundleVerifier` to scanner startup; block if verification fails.
* [ ] Implement `CacheLastGoodBundle()` and atomic label swap (`/current -> /v-YYYYMMDDHHmm`).
* [ ] Add `SbomGate` with JSON-Schema validation + completeness thresholds.
* [ ] Emit reasoned fallbacks: `REACH_FALLBACK_NO_ANALYZER`, `REACH_FALLBACK_TIMEOUT`.
* [ ] Compute and display `GraphRevisionId` everywhere (API + UI + logs).
* [ ] Configure nightly PG backups + weekly restore rehearsal that asserts revision parity.
* [ ] Route all policy mutations through Authority DSSE verification + auditable ledger entry.
If you want, I can turn this into ready-to-merge .NET test fixtures (xUnit) and a GitLab CI job that runs the feed-tamper/air-gap simulations automatically.
Ill take the 5 “miss” areas and turn them into concrete, implementable test plans, with suggested projects, fixtures, and key cases your team can start coding.
Ill keep names aligned to .NET 10/xUnit and your Stella Ops modules.
---
## 0. Test layout proposal
**Solution structure (tests)**
```text
/tests
/StellaOps.Bundle.Tests
BundleVerificationTests.cs
CachedBundleFallbackTests.cs
/StellaOps.SbomGate.Tests
SbomSchemaValidationTests.cs
SbomCompletenessTests.cs
/StellaOps.Scanner.Tests
ScannerOfflineBundleTests.cs
ReachabilityFallbackTests.cs
GraphRevisionDeterminismTests.cs
/StellaOps.DataRecoverability.Tests
PostgresSnapshotRestoreTests.cs
GraphReplayParityTests.cs
/StellaOps.Authority.Tests
PolicyChangeSignatureTests.cs
/StellaOps.System.Acceptance
FeedOutageEndToEndTests.cs
AirGapModeEndToEndTests.cs
BundleSwapEndToEndTests.cs
/testdata
/bundles
/sboms
/graphs
/db
```
Use xUnit + FluentAssertions, plus Testcontainers for Postgres.
---
## 1) Feed outages & integrity drift
### Objectives
1. Scanner never “goes dark” because the CDN/feed is down.
2. Only **verified** bundles are used; tampered bundles are never ingested.
3. Offline/air-gap mode is a first-class, tested behavior.
### Components under test
* `StellaOps.BundleVerifier` (core library)
* `StellaOps.Scanner.Webservice` (scanner, bundle loader)
* Bundle filesystem layout:
`/opt/stellaops/bundles/v-<timestamp>/*` + `/opt/stellaops/bundles/current` symlink
### Test dimensions
* Network: OK / timeout / 404 / TLS failure / DNS failure.
* Remote bundle: correct / tampered (hash mismatch) / wrong signature / truncated.
* Local cache: last-good present / absent / corrupted.
* Mode: online / offline (air-gap).
### Detailed test suites
#### 1.1 Bundle verification unit tests
**Project:** `StellaOps.Bundle.Tests`
**Fixtures:**
* `testdata/bundles/good-bundle/`
* `testdata/bundles/hash-mismatch-bundle/`
* `testdata/bundles/bad-signature-bundle/`
* `testdata/bundles/missing-file-bundle/`
**Key tests:**
1. `VerifyAsync_ValidBundle_ReturnsSuccess`
* Arrange: Load `good-bundle` manifest + DSSE signature.
* Act: `BundleVerifier.VerifyAsync(manifest, keyring)`
* Assert:
* `result.IsValid == true`
* `result.Files.All(f => f.Status == Verified)`
2. `VerifyAsync_HashMismatch_FailsFast`
* Use `hash-mismatch-bundle` where one files SHA256 differs.
* Assert:
* `IsValid == false`
* `Errors` contains `BUNDLE_FILE_HASH_MISMATCH` and the offending path.
3. `VerifyAsync_InvalidSignature_RejectsBundle`
* DSSE envelope signed with unknown key.
* Assert:
* `IsValid == false`
* `Errors` contains `BUNDLE_SIGNATURE_INVALID`.
4. `VerifyAsync_MissingFile_RejectsBundle`
* Manifest lists file that does not exist on disk.
* Assert:
* `IsValid == false`
* `Errors` contains `BUNDLE_FILE_MISSING`.
#### 1.2 Cached bundle fallback logic
**Class under test:** `BundleManager`
Simplified interface:
```csharp
public interface IBundleManager {
Task<BundleRef> GetActiveBundleAsync();
Task<BundleRef> UpdateFromRemoteAsync(CancellationToken ct);
}
```
**Key tests:**
1. `UpdateFromRemoteAsync_RemoteUnavailable_KeepsLastGoodBundle`
* Arrange:
* `lastGood` bundle exists and is marked verified.
* Remote HTTP client always throws `TaskCanceledException` (simulated timeout).
* Act: `UpdateFromRemoteAsync`.
* Assert:
* Returned bundle ID equals `lastGood.Id`.
* No changes to `current` symlink.
2. `UpdateFromRemoteAsync_RemoteTampered_DoesNotReplaceCurrent`
* Remote returns bundle `temp-bundle` which fails `BundleVerifier`.
* Assert:
* `current` still points to `lastGood`.
* An error metric is emitted (e.g. `stellaops_bundle_update_failures_total++`).
3. `GetActiveBundle_NoVerifiedBundle_ThrowsDomainError`
* No bundle is verified on disk.
* `GetActiveBundleAsync` throws a domain exception with code `NO_VERIFIED_BUNDLE_AVAILABLE`.
* Consumption pattern in Scanner: scanner fails fast on startup with clear log.
#### 1.3 Scanner behavior with outages (integration)
**Project:** `StellaOps.Scanner.Tests`
Use in-memory host (`WebApplicationFactory<ScannerProgram>`).
**Scenarios:**
* F1: CDN timeout, last-good present.
* F2: CDN 404, last-good present.
* F3: CDN returns tampered bundle; verification fails.
* F4: Air-gap: network disabled, last-good present.
* F5: Air-gap + no last-good: scanner must refuse to start.
Example test:
```csharp
[Fact]
public async Task Scanner_UsesLastGoodBundle_WhenCdnTimesOut() {
// Arrange: put good bundle under /bundles/v-1, symlink /bundles/current -> v-1
using var host = TestScannerHost.WithBundle("v-1", good: true, simulateCdnTimeout: true);
// Act: call /api/scan with small fixture image
var response = await host.Client.PostAsJsonAsync("/api/scan", scanRequest);
// Assert:
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadFromJsonAsync<ScanResult>();
content.BundleId.Should().Be("v-1");
host.Logs.Should().Contain("Falling back to last verified bundle");
}
```
#### 1.4 System acceptance (GitLab CI)
**Job idea:** `acceptance:feed-resilience`
Steps:
1. Spin up `scanner` + stub `feedser` container.
2. Phase A: feed OK → run baseline scan; capture `bundleId` and `graphRevisionId`.
3. Phase B: re-run with feed stub configured to:
* timeout,
* 404,
* return tampered bundle.
4. For each phase:
* Assert `bundleId` remains the baseline one.
* Assert `graphRevisionId` unchanged.
Failure of any assertion should break the pipeline.
---
## 2) SBOM quality & schema drift
### Objectives
1. Only syntactically valid SBOMs are ingested into the graph.
2. Enforce minimum completeness (hash coverage, supplier etc.).
3. Clear, machine-readable error responses from SBOM ingestion API.
### Components
* `StellaOps.SbomGate` (validation service)
* SBOM ingestion endpoint in Scanner/Concelier: `POST /api/sboms`
### Schema validation tests
**Project:** `StellaOps.SbomGate.Tests`
**Fixtures:**
* `sbom-cdx-1.6-valid.json`
* `sbom-cdx-1.6-malformed.json`
* `sbom-spdx-2.3-valid.json`
* `sbom-unsupported-schema.json`
* `sbom-missing-hashes-10percent.json`
* `sbom-no-supplier.json`
**Key tests:**
1. `Validate_ValidCycloneDx16_Succeeds`
* Assert type `SbomValidationResult.Success`.
* Ensure `DetectedSchema == CycloneDx16`.
2. `Validate_MalformedJson_FailsWithSyntaxError`
* Malformed JSON.
* Assert:
* `IsValid == false`
* `Errors` contains `SBOM_JSON_SYNTAX_ERROR` with path info.
3. `Validate_UnsupportedSchemaVersion_Fails`
* SPDX 2.1 (if you only allow 2.3).
* Expect `SBOM_SCHEMA_UNSUPPORTED` with `schemaUri` echo.
4. `Validate_MissingHashesOverThreshold_Fails`
* SBOM where >5% components lack hashes.
* Policy: `MinHashCoverage = 0.95`.
* Assert:
* `IsValid == false`
* `Errors` contains `SBOM_HASH_COVERAGE_BELOW_THRESHOLD` with actual ratio.
5. `Validate_MissingSupplier_Fails`
* Critical components missing supplier info.
* Expect `SBOM_REQUIRED_FIELD_MISSING` with `component.supplier`.
### API-level tests
**Project:** `StellaOps.Scanner.Tests` (or `StellaOps.Concelier.Tests` depending where SBOM ingestion lives).
Key scenarios:
1. `POST /api/sboms` with malformed JSON
* Request body: `sbom-cdx-1.6-malformed.json`.
* Expected:
* HTTP 400.
* Body: `{ "code": "SBOM_VALIDATION_FAILED", "details": [ ... ], "correlationId": "..." }`.
* At least one detail contains `SBOM_JSON_SYNTAX_ERROR`.
2. `POST /api/sboms` with missing hashes
* Body: `sbom-missing-hashes-10percent.json`.
* HTTP 400 with `SBOM_HASH_COVERAGE_BELOW_THRESHOLD`.
3. `POST /api/sboms` with unsupported schema
* Body: `sbom-unsupported-schema.json`.
* HTTP 400 with `SBOM_SCHEMA_UNSUPPORTED`.
4. `POST /api/sboms` valid
* Body: `sbom-cdx-1.6-valid.json`.
* HTTP 202 or 201 (depending on design).
* Response contains SBOM ID; subsequent graph build sees that SBOM.
---
## 3) DB/data corruption & operator error
### Objectives
1. You can restore Postgres to a point in time and reproduce previous graph results.
2. Graphs are deterministic given bundle + SBOM + rules.
3. Obvious corruptions are detected and surfaced, not silently masked.
### Components
* Postgres cluster (new canonical store)
* `StellaOps.Scanner.Webservice` (graph builder, persistence)
* `GraphRevisionId` computation
### 3.1 Postgres snapshot / WAL tests
**Project:** `StellaOps.DataRecoverability.Tests`
Use Testcontainers to spin up Postgres.
Scenarios:
1. `PITR_Restore_ReplaysGraphsWithSameRevisionIds`
* Arrange:
* Spin DB container with WAL archiving enabled.
* Apply schema migrations.
* Ingest fixed set of SBOMs + bundle refs + rules.
* Trigger graph build → record `graphRevisionIds` from API.
* Take base backup snapshot (simulate daily snapshot).
* Act:
* Destroy container.
* Start new container from base backup + replay WAL up to a specific LSN.
* Start Scanner against restored DB.
* Query graphs again.
* Assert:
* For each known graph: `revisionId_restored == revisionId_original`.
* Number of nodes/edges is identical.
2. `PartialDataLoss_DetectedByHealthCheck`
* After initial load, deliberately delete some rows (e.g. all edges for a given graph).
* Run health check endpoint, e.g. `/health/graph`.
* Expect:
* HTTP 503.
* Body indicates `GRAPH_INTEGRITY_FAILED` with details of missing edges.
This test forces a discipline to implement a basic graph integrity check (e.g. counts by state vs expected).
### 3.2 Deterministic replay tests
**Project:** `StellaOps.Scanner.Tests``GraphRevisionDeterminismTests.cs`
**Precondition:** Graph revision ID computed as:
```csharp
GraphRevisionId = SHA256(
Normalize([
BundleId,
OrderedSbomIds,
RulesetVersion,
FeedBundleIds,
LatticeConfigVersion,
NormalizationVersion
])
);
```
**Scenarios:**
1. `SameInputs_SameRevisionId`
* Run graph build twice for same inputs.
* Assert identical `GraphRevisionId`.
2. `DifferentBundle_DifferentRevisionId`
* Same SBOMs & rules; change vulnerability bundle ID.
* Assert `GraphRevisionId` changes.
3. `DifferentRuleset_DifferentRevisionId`
* Same SBOM & bundle; change ruleset version.
* Assert `GraphRevisionId` changes.
4. `OrderingIrrelevant_StableRevision`
* Provide SBOMs in different order.
* Assert ` GraphRevisionId` same (because of internal sorting).
---
## 4) Reachability engine & graph evaluation flakiness
### Objectives
1. If reachability cannot be computed, you do not break; you downgrade verdicts with explicit reason codes.
2. Deterministic reachability for “golden fixtures”.
3. Graph evaluation remains stable even when analyzers come and go.
### Components
* `StellaOps.Scanner.Webservice` (lattice / reachability engine)
* Language analyzers (sidecar or gRPC microservices)
* Verdict representation, e.g.:
```csharp
public sealed record VulnerabilityVerdict(
string Status, // "NotAffected", "Affected", "PotentiallyAffected"
string ReasonCode, // "REACH_CONFIRMED", "REACH_FALLBACK_NO_ANALYZER", ...
string? AnalyzerId
);
```
### 4.1 Golden reachability fixtures
**Project:** `StellaOps.Scanner.Tests``GoldenReachabilityTests.cs`
**Fixtures directory:** `/testdata/reachability/fixture-*/`
Each fixture:
```text
/testdata/reachability/fixture-01-log4j/
sbom.json
code-snippets/...
expected-vex.json
config.json # language, entrypoints, etc.
```
**Test pattern:**
For each fixture:
1. Load SBOM + configuration.
2. Trigger reachability analysis.
3. Collect raw reachability graph + final VEX verdicts.
4. Compare to `expected-vex.json` (status + reason codes).
5. Store the `GraphRevisionId` and set it as golden as well.
Key cases:
* R1: simple direct call → reachability confirmed → `Status = "Affected", ReasonCode = "REACH_CONFIRMED"`.
* R2: library present but not called → `Status = "NotAffected", ReasonCode = "REACH_ANALYZED_UNREACHABLE"`.
* R3: language analyzer missing → `Status = "PotentiallyAffected", ReasonCode = "REACH_FALLBACK_NO_ANALYZER"`.
* R4: analysis timeout → `Status = "PotentiallyAffected", ReasonCode = "REACH_FALLBACK_TIMEOUT"`.
### 4.2 Analyzer unavailability / fallback behavior
**Project:** `StellaOps.Scanner.Tests``ReachabilityFallbackTests.cs`
Scenarios:
1. `NoAnalyzerRegistered_ForLanguage_UsesFallback`
* Scanner config lists a component in language “go” but no analyzer registered.
* Expect:
* No 500 error from `/api/graphs/...`.
* All applicable vulnerabilities for that component have `Status = "PotentiallyAffected"` and `ReasonCode = "REACH_FALLBACK_NO_ANALYZER"`.
2. `AnalyzerRpcFailure_UsesFallback`
* Analyzer responds with gRPC error or HTTP 500.
* Scanner logs error and keeps going.
* Same semantics as missing analyzer, but with `AnalyzerId` populated and optional `ReasonDetails` (e.g. `RPC_UNAVAILABLE`).
3. `AnalyzerTimeout_UsesTimeoutFallback`
* Force analyzer calls to time out.
* `ReasonCode = "REACH_FALLBACK_TIMEOUT"`.
### 4.3 Concurrency & determinism
Add a test that:
1. Triggers N parallel graph builds for the same inputs.
2. Asserts that:
* All builds succeed.
* All `GraphRevisionId` are identical.
* All reachability reason codes are identical.
This is important for concurrent scanners and ensures lack of race conditions in graph construction.
---
## 5) Update pipelines & job routing
### Objectives
1. Bundle swaps are atomic: scanners see either old or new, never partially written bundles.
2. Policy changes are always signed via Authority; unsigned/invalid changes never apply.
3. Job routing changes (if/when you move to direct microservice pools) remain stateless and testable.
### 5.1 Two-phase bundle swap tests
**Bundle layout:**
* `/opt/stellaops/bundles/current` → symlink to `v-YYYYMMDDHHmmss`
* New bundle:
* Download to `/opt/stellaops/bundles/staging/<temp-id>`
* Verify
* Atomic `ln -s v-new current.tmp && mv -T current.tmp current`
**Project:** `StellaOps.Bundle.Tests``BundleSwapTests.cs`
Scenarios:
1. `Swap_Success_IsAtomic`
* Simulate swap in a temp directory.
* During swap, spawn parallel tasks that repeatedly read `current` and open `manifest.json`.
* Assert:
* Readers never fail with “file not found” / partial manifest.
* Readers only see either `v-old` or `v-new`, no mixed state.
2. `Swap_VerificationFails_NoChangeToCurrent`
* Stage bundle which fails `BundleVerifier`.
* After attempted swap:
* `current` still points to `v-old`.
* No new directory with the name expected for `v-new` is referenced by `current`.
3. `Swap_CrashBetweenVerifyAndMv_LeavesSystemConsistent`
* Simulate crash after creating `current.tmp` but before `mv -T`.
* On “restart”:
* Cleanup code must detect `current.tmp` and remove it.
* Ensure `current` still points to last good.
### 5.2 Authority-gated policy changes
**Component:** `StellaOps.Authority` + any service that exposes `/policies`.
Policy change flow:
1. Client sends DSSE-signed `PolicyChangeRequest` to `/authority/verify`.
2. Authority validates signature, subject hash.
3. Service applies change only if Authority approves.
**Project:** `StellaOps.Authority.Tests` + `StellaOps.Scanner.Tests` (or wherever policies live).
Key tests:
1. `PolicyChange_WithValidSignature_Applies`
* Signed requests `subject` hash matches computed diff of old->new policy.
* Authority returns `Approved`.
* Policy service updates policy; audit log entry recorded.
2. `PolicyChange_InvalidSignature_Rejected`
* Signature verifiable with no trusted key, or corrupted payload.
* Expect:
* HTTP 403 or 400 from policy endpoint.
* No policy change in DB.
* Audit log entry with reason `SIGNATURE_INVALID`.
3. `PolicyChange_SubjectHashMismatch_Rejected`
* Attacker changes policy body but not DSSE subject.
* On verification, recomputed diff doesnt match subject hash.
* Authority rejects with `SUBJECT_MISMATCH`.
4. `PolicyChange_ExpiredEnvelope_Rejected`
* Envelope contains `expiry` in past.
* Authority rejects with `ENVELOPE_EXPIRED`.
5. `PolicyChange_AuditTrail_Complete`
* After valid change:
* Audit log contains: `policyName`, `oldHash`, `newHash`, `signerId`, `envelopeId`, `timestamp`.
### 5.3 Job routing (if/when you use DB-backed routing tables)
You discussed a `routing` table:
```sql
domain text,
instance_id uuid,
last_heartbeat timestamptz,
table_name text
```
Key tests (once implemented):
1. `HeartbeatExpired_DropsRoutingEntry`
* Insert entry with `last_heartbeat` older than 1 minute.
* Routing GC job should remove it.
* API gateway must not route new jobs to that instance.
2. `RoundRobinAcrossAliveInstances`
* Multiple routing rows for same domain with fresh heartbeats.
* Issue M requests via gateway.
* Assert approximately round-robin distribution across `instance_id`.
3. `NoDurabilityRequired_JobsNotReplayedAfterRestart`
* Confirm that in-memory or temp tables are used appropriately where you do not want durable queues.
If you decide to go with “N gateways x M microservices via Docker load balancer only”, then the main tests here move to health-check based routing in the load balancer and become more infra than app tests.
---
## 6) CI wiring summary
To make this actually enforceable:
1. **Unit test job** (`test:unit`)
* Runs `StellaOps.Bundle.Tests`, `StellaOps.SbomGate.Tests`, `StellaOps.Authority.Tests`, `StellaOps.Scanner.Tests`.
2. **DB recoverability job** (`test:db-recoverability`)
* Uses Testcontainers to run `StellaOps.DataRecoverability.Tests`.
* Marked as “required” for `main` branch merges.
3. **Acceptance job** (`test:acceptance-system`)
* Spins up a minimal stack via Docker Compose.
* Executes `StellaOps.System.Acceptance` tests:
* Feed outages & fallback.
* Air-gap modes.
* Bundle swap.
* Can be slower; run on main and release branches.
4. **Nightly chaos job** (`test:nightly-chaos`)
* Optional: run more expensive tests (simulated DB corruption, analyzer outages, etc.).
---
If you want, next step I can generate skeleton xUnit test classes and a `/testdata` layout you can paste directly into your repo (with TODOs where real fixtures are needed).

View File

@@ -0,0 +1,506 @@
You might want to know this — the landscape around CVSS v4.0 is rapidly shifting, and the time is now to treat it as a first-class citizen in vulnerability-management workflows.
![CVSS v4 identity](https://www.first.org/cvss/identity/cvssv4.png)
![CVSS v4 schema](https://www.first.org/cvss/v4-0/media/699c7730c6e9a411584a129153e334f4.png)
![Exploit readiness](https://orca.security/wp-content/uploads/2024/01/image-37.png?w=1200)
---
## 🔎 What is CVSS v4.0 — and why it matters now
* CVSS is the standard framework for scoring software/hardware/firmware vulnerabilities, producing a 010 numeric severity score. ([Wikipedia][1])
* On **November 1 2023**, the maintainers FIRST published version 4.0, replacing older 3.x/2.0 lines. ([FIRST][2])
* v4.0 expands the standard to four metric groups: **Base, Threat, Environmental,** and a new **Supplemental** — enabling far more granular, context-aware scoring. ([Checkmarx][3])
## 🧩 What Changed in v4.0 Compared to 3.x
* The old “Temporal” metrics are renamed to **Threat** metrics; new Base metric **Attack Requirements (AT)** was added. v4.0 also refines **User Interaction (UI)** into more nuanced values (e.g., Passive vs Active). ([FIRST][4])
* The old “Scope” metric was removed, replaced by distinct impact metrics on the *vulnerable system* (VC/VI/VA) vs *subsequent systems* (SC/SI/SA), clarifying real-world risk propagation. ([FIRST][4])
* The **Supplemental** metric group adds flags like “Safety,” “Automatable,” “Recovery,” “Value Density,” “Provider Urgency,” etc. — providing extra context that doesnt alter the numeric score but helps decision-making. ([FIRST][4])
* As a result, the scoring nomenclature also changes: instead of a single “CVSS score,” v4.0 supports combinations like **CVSS-B (Base only)**, **CVSS-BT (Base + Threat)**, **CVSS-BE**, or **CVSS-BTE** (Base + Threat + Environmental). ([FIRST][4])
## ✅ Industry Adoption Is Underway — Not In The Future, Now
* The National Vulnerability Database (NVD) — maintained by NIST — officially supports CVSS v4.0 as of June 2024. ([NVD][5])
* The major code-host & vulnerability platform GitHub Security Advisories began exposing CVSS v4.0 fields in September 2024. ([The GitHub Blog][6])
* On the ecosystem and vendor side: Microsoft Defender Vulnerability Management updated to prefer CVSS v4 in March 2025. ([TECHCOMMUNITY.MICROSOFT.COM][7])
* According to Snyk Open Source, all new advisories now come with both CVSS v4.0 and v3.1 assessments — with v4.0 becoming the default for evaluating severity. ([Snyk Updates][8])
* Several vendor-facing security / vulnerability-management products have signaled or started integrating v4.0 (though rollout is still ongoing) — consistent with the broader industry shift. ([Rapid7 Discuss][9])
## 🎯 What This Means for Your Approach (Given What Youre Building)
Because youre architecting a supply-chain / container / SCA-aware scanning stack (as with your StellaOps plans), this shift matters:
1. **Granular scoring** — v4.0s more detailed metrics help differentiate between a “theoretical high-impact but low-likelihood” flaw versus a “realistic immediate threat.”
2. **Context-aware risk** — using Threat + Environmental + Supplemental metrics lets you layer real-world usage context (e.g. container deployment environment, exposure profile, exploit maturity, safety implications).
3. **Auditability & traceability** — storing full vector strings, metric breakdowns (Base/Threat/Environmental/Supplemental), computed scores (CVSS-B, BT, BE, BTE), timestamp, scorer/source URL — plus legacy v3.1 vector — gives you a full provenance trail. That aligns with your ambition to build a “proof-of-integrity graph” and supply-chain-compliance ledger.
## 🧠 Caveats & What To Watch Out For
* Although v4.0 is supported by core infrastructures (NVD, GitHub, Microsoft, Snyk, etc.), **not all existing CVEs have v4.0 assessments yet**. Many older entries still carry only v3.x scores. ([NVD][10])
* v4.0s increased granularity brings **increased complexity** — more metric fields to collect, store, and evaluate. Without consistent population of Threat, Environmental or Supplemental fields, many scores could default back to “base only,” limiting the advantage over v3.1. ([Checkmarx][3])
* A purely numeric score remains a **partial view of risk** — v4.0 improves it, but still does *not* compute exploitation likelihood. Combining CVSS with external data (e.g. exploit intelligence, usage context, threat modeling) remains critical. ([CrowdStrike][11])
---
Given your goals — supply-chain compliance, auditability, multi-tool integration — adopting CVSS v4.0 now (or planning for it) is absolutely the right move.
If you like, I can check **as of late 2025** which major container/SCA tools (like grype, Trivy, Aqua, GitLab, etc.) already support v4.0 — this may help you decide how quickly to bake v4 support into StellaOps.
[1]: https://en.wikipedia.org/wiki/Common_Vulnerability_Scoring_System?utm_source=chatgpt.com "Common Vulnerability Scoring System"
[2]: https://www.first.org/cvss/specification-document?utm_source=chatgpt.com "CVSS v4.0 Specification Document"
[3]: https://checkmarx.com/blog/cvss4-what-you-need-to-know-about-the-latest-version/?utm_source=chatgpt.com "CVSS v4.0: What You Need to Know about the Latest Version"
[4]: https://www.first.org/cvss/v4-0/?utm_source=chatgpt.com "Common Vulnerability Scoring System Version 4.0"
[5]: https://nvd.nist.gov/general/news/cvss-v4-0-official-support?utm_source=chatgpt.com "CVSS v4.0 Official Support - NVD"
[6]: https://github.blog/changelog/2024-09-13-github-security-advisories-support-cvss-4-0/?utm_source=chatgpt.com "GitHub security advisories support CVSS 4.0"
[7]: https://techcommunity.microsoft.com/blog/vulnerability-management/supporting-cvss-v4-score-for-cve-for-enhanced-vulnerability-assessment/4391439?utm_source=chatgpt.com "Supporting CVSS V4 score for CVE for Enhanced ..."
[8]: https://updates.snyk.io/improved-security-prioritization-with-cvss-version-4-0-295136/?utm_source=chatgpt.com "Improved security prioritization with CVSS version 4.0"
[9]: https://discuss.rapid7.com/t/cvss-4-0-when/29354?utm_source=chatgpt.com "CVSS 4.0 when? - InsightVM"
[10]: https://nvd.nist.gov/vuln/detail/CVE-2025-2024?utm_source=chatgpt.com "CVE-2025-2024 Detail - NVD"
[11]: https://www.crowdstrike.com/en-us/cybersecurity-101/exposure-management/common-vulnerability-scoring-system-cvss/?utm_source=chatgpt.com "Common Vulnerability Scoring System (CVSS)"
Good request. I checked — support for CVSS v4.0 is being gradually adopted in major vulnerability-tracking and container/SCA tools, but **it is not yet ubiquitous**. Heres whats clear today (late 2025), plus what remains uncertain — from a neutral fact-based perspective.
---
## ✅ What we know: CVSS 4.0 is gaining traction
* GitHub Advisory Database — widely used for open source vulnerability advisories — **now supports CVSS v4.0** (in addition to older v3.1). ([GitHub Docs][1])
* The maintainers of the standard, FIRST, define CVSS 4.0 as full suite of metric groups (Base, Threat, Environmental, Supplemental), giving more precise, environment-aware severity scoring. ([first.org][2])
* Some high-profile CVEs (e.g. Trivy-related CVE-2024-35192) already contain CVSS v4.0 vector strings in their official NVD entries, indicating that the community is reporting vulnerabilities under the new standard. ([nvd.nist.gov][3])
---
## 🔎 What modern container/SCA tools do — mixed readiness
* Trivy remains one of the most popular open-source scanners for containers, VMs, filesystems, language dependencies, and Kubernetes environments. ([GitHub][4])
* Documentation and tool descriptions for Trivy (and its ecosystem integrations) emphasize detection of CVEs, generation of SBOMs, license/compliance scanning, IaC misconfigurations, secrets, etc. ([Chainguard Academy][5])
* However — I did **not** find explicit public documentation confirming that Trivy (or other major SCA/container scanners) **fully parse, store, and expose CVSS v4.0 metrics** (Base, Threat, Environmental, Supplemental) across all output formats.
* Many vulnerability-scanning tools still default to older scoring (e.g. CVSS v3.x) because much of the existing CVE ecosystem remains populated with v3.x data.
* Some vulnerabilities (even recent ones) may carry v4.0 vectors, but if the scanning tool or its database backend does not yet support v4.0, the output may degrade to “severity level” (Low/Medium/High/Critical) or rely on legacy score — losing some of the finer granularity.
* A recent academic evaluation of the “VEX tool space” for container-scanning highlighted **low consistency across different scanners**, suggesting divergent capabilities and output semantics. ([arxiv.org][6])
---
## ⚠ What remains uncertain / risk factors
* Lack of uniform adoption: Many older CVEs still carry only CVSS v2 or v3.x scores; full re-scoring with v4.0 is non-trivial and may lag. Without upstream v4 scoring, scanner support is moot.
* Tools may partially support v4.0: Even if a scanner identifies a v4-vector, it may not support all metric groups (e.g. Threat, Environmental, Supplemental) — or may ignore them in summary output.
* Output format issues: For compliance, audit, or traceability (as you plan for with your “proof-of-integrity graph”), you need vector strings, not just severity labels. If scanners only emit severity labels or old-school base scores, you lose auditability.
* Inconsistency among scanners: As shown in recent comparative research, different tools may disagree on which vulnerabilities they detect — and by extension, which CVEs get v4.0 scoring in their data. ([arxiv.org][6])
---
## 🎯 What this means for your build (e.g. Stella Ops)
* You should **design Stella Ops to natively support CVSS v4.0 vectors** — store them as structured data (vector string + separate metric fields) rather than just severity label or numeric base score. That preserves maximum fidelity and auditability.
* Continue to ingest from sources that publish v4.0 data (e.g. GitHub Advisory Database, NVD entries already tagged with v4 vector).
* For scanners (e.g. Trivy) that lack confirmed v4 output support — treat them as legacy feed, and supplement with heuristics or external metadata fetch to reconstruct full context where possible (or fallback to v3.x with clear marking).
* Account for inconsistency among scanners: treat scan output as advisory — use cross-tool correlation, SBOM provenance tracking, and your planned “proof-of-integrity graph” to triangulate real risk rather than trust a single tool.
---
## ✅ Final Assessment — “Yes, but partial”
CVSS 4.0 is **supported in key vulnerability/advisory databases** and **appearing in real CVE entries**, but **full support across container/SCA scanning tools remains uneven**. For a forward-looking, compliance- and audit-oriented platform like Stella Ops, it is rational and recommended to **adopt v4.0 as primary internal standard**, while building fallback paths for legacy data.
If you like — I can run a small **2025-era snapshot** of **710 top container / SCA tools** (open source + commercial) and tabulate which of them already publish full CVSS v4.0 output (vectors + all metric groups). That gives you a practical compatibility map for Stella Ops architecture.
[1]: https://docs.github.com/en/code-security/security-advisories/working-with-global-security-advisories-from-the-github-advisory-database/about-the-github-advisory-database?utm_source=chatgpt.com "About the GitHub Advisory database"
[2]: https://www.first.org/cvss/v4-0/cvss-v40-faq.pdf?utm_source=chatgpt.com "CVSS v4.0 Frequently Asked Questions 2025- ..."
[3]: https://nvd.nist.gov/vuln/detail/CVE-2024-35192?utm_source=chatgpt.com "CVE-2024-35192 Detail - NVD"
[4]: https://github.com/aquasecurity/trivy?utm_source=chatgpt.com "aquasecurity/trivy: Find vulnerabilities, misconfigurations, ..."
[5]: https://edu.chainguard.dev/chainguard/chainguard-images/staying-secure/working-with-scanners/trivy-tutorial/?utm_source=chatgpt.com "Using Trivy to Scan Software Artifacts"
[6]: https://arxiv.org/abs/2503.14388?utm_source=chatgpt.com "Vexed by VEX tools: Consistency evaluation of container vulnerability scanners"
Below is something you can drop into an internal design doc and hand straight to engineering.
---
## 1. Objectives (what “done” looks like)
Developers should aim for:
1. **Firstclass CVSS v4.0 support**
* Parse and store full v4.0 vectors (`CVSS:4.0/...`) including all Base, Threat, Environmental, and Supplemental metrics. ([first.org][1])
* Compute correct CVSSB / CVSSBT / CVSSBE / CVSSBTE scores using the official equations. ([first.org][1])
2. **Versionaware, lossless storage**
* Preserve original vector strings and raw metrics for both v3.x and v4.0.
* Do not downconvert v4.0 to v3.x or blend them into a single number.
3. **Clear separation of concerns**
* CVSS = standardized “severity” input, not your internal “risk score.” ([first.org][1])
* Threat / Environmental / Supplemental metrics feed your risk model, but are stored distinctly.
---
## 2. Data model & schema
### 2.1 Core CVSS entity
For each vulnerability finding (CVE or toolspecific ID), you should support multiple CVSS assessments over time and from different sources.
**Table: `cvss_assessments` (or equivalent)**
Required columns:
* `id` (PK)
* `vuln_id` (FK to CVE/finding table)
* `version` (`'2.0' | '3.0' | '3.1' | '4.0'`)
* `vector_string` (full textual vector, e.g. `CVSS:4.0/AV:N/AC:L/...`)
* `score` (numeric, 0.010.0)
* `score_type` (`'CVSS-B' | 'CVSS-BT' | 'CVSS-BE' | 'CVSS-BTE'`) ([first.org][1])
* `severity_band` (`'None' | 'Low' | 'Medium' | 'High' | 'Critical'`) per official v4 qualitative scale. ([first.org][1])
* `source` (`'NVD' | 'GitHub' | 'Vendor' | 'Internal' | 'Scanner:<name>' | ...`)
* `assessed_at` (timestamp)
* `assessed_by` (user/system id)
### 2.2 Structured metrics (JSON or separate tables)
Store metrics machinereadably, not just in the string:
```jsonc
{
"base": {
"AV": "N", // Attack Vector
"AC": "L", // Attack Complexity
"AT": "N", // Attack Requirements
"PR": "N", // Privileges Required
"UI": "N", // User Interaction: N, P, A in v4.0
"VC": "H",
"VI": "H",
"VA": "H",
"SC": "H",
"SI": "H",
"SA": "H"
},
"threat": {
"E": "A" // Exploit Maturity
},
"environmental": {
"CR": "H", // Confidentiality Requirement
"IR": "H",
"AR": "H",
// plus modified versions of base metrics, per spec
"MAV": "N",
"MAC": "L",
"MPR": "N",
"MUI": "N",
"MVC": "H",
"MVI": "H",
"MVA": "H",
"MSC": "H",
"MSI": "H",
"MSA": "H"
},
"supplemental": {
"S": "S", // Safety
"AU": "Y", // Automatable (v4.0 uses AU in the spec) :contentReference[oaicite:5]{index=5}
"U": "H", // Provider Urgency
"R": "H", // Recovery
"V": "H", // Value Density
"RE": "H" // Vulnerability Response Effort
}
}
```
Implementation guidance:
* Use a JSON column or dedicated tables (`cvss_base_metrics`, `cvss_threat_metrics`, etc.) depending on how heavily you will query by metric.
* Always persist both `vector_string` and parsed metrics; treat parsing as a reversible transformation.
---
## 3. Parsing & ingestion
### 3.1 Recognizing and parsing vectors
Develop a parser library (or adopt an existing wellmaintained one) with these properties:
* Recognizes prefixes: `CVSS:2.0`, `CVSS:3.0`, `CVSS:3.1`, `CVSS:4.0`. ([Wikipedia][2])
* Validates all metric abbreviations and values for the given version.
* Returns:
* `version`
* `metrics` object (structured as above)
* `score` (recalculated from metrics, not blindly trusted)
* `score_type` (B / BT / BE / BTE inferred from which metric groups are defined). ([first.org][1])
Error handling:
* If the vector is syntactically invalid:
* Store it as `vector_string_invalid`.
* Mark assessment as `status = 'invalid'`.
* Do not drop the vulnerability; log and alert.
* If metrics are missing for Threat / Environmental / Supplemental:
* Treat them as “Not Defined” per spec, defaulting them in calculations. ([first.org][1])
### 3.2 Integrating with external feeds
For each source (NVD, GitHub Advisory Database, vendor advisories, scanner outputs):
* Normalize:
* If numeric score + vector provided: always trust the vector, not the numeric; recompute score internally and compare for sanity.
* If only numeric score provided (no vector): store, but mark `vector_string = null` and `is_partial = true`.
* Preserve `source` and `source_reference` (e.g., NVD URL, GHSA ID) for audit.
---
## 4. Scoring engine
### 4.1 Core functions
Implement pure, deterministic functions:
* `Cvss4Result computeCvss4Score(Cvss4Metrics metrics)`
* `Cvss3Result computeCvss3Score(Cvss3Metrics metrics)`
Where `Cvss4Result` includes:
* `score` (0.010.0, properly rounded per spec; one decimal place) ([first.org][1])
* `score_type` (`CVSS-B` / `CVSS-BT` / `CVSS-BE` / `CVSS-BTE`)
* `severity_band` (`None` / `Low` / `Medium` / `High` / `Critical`)
Implementation notes:
* Use the equations from section 8 of the CVSS v4.0 spec; do not invent your own approximations. ([first.org][1])
* Ensure rounding and severity bands exactly match official calculators (run golden tests).
### 4.2 Nomenclature & flags
* Always tag scores with the nomenclature: `CVSS-B`, `CVSS-BT`, `CVSS-BE`, or `CVSS-BTE`. ([first.org][1])
* Default behavior:
* If Threat/Environmental metrics are not explicitly provided, treat them as “Not Defined” (defaults), and still label the score `CVSS-B`.
* Only use `CVSS-BT` / `CVSS-BE` / `CVSS-BTE` when nondefault values are present.
### 4.3 Strict separation from “risk”
* Do not overload CVSS as a risk score. The spec is explicit that base scores measure severity, not risk. ([first.org][1])
* Implement a separate risk model (e.g., `risk_score` 0100) that uses:
* CVSS (v3/v4) as one input
* Asset criticality
* Compensating controls
* Business context
* Threat intel signals
---
## 5. Threat & Environmental automation
You want developers to wire CVSS v4.0 to realworld intel and asset data.
### 5.1 Threat metrics (Exploit Maturity, E)
Threat metrics in v4.0 are largely about Exploit Maturity (E). ([first.org][1])
Implementation guidelines:
* Define a mapping from your threat intel signals to E values:
* `E:X` Not Defined (no data)
* `E:U` Unreported
* `E:P` Proofofconcept only
* `E:F` Functional
* `E:A` Active exploitation
* Data sources:
* Threat intel feeds (CISA KEV, vendor threat bulletins, commercial feeds)
* Public PoC trackers (exploit DB, GitHub PoC repositories)
* Automation:
* Nightly job updates Threat metrics per vuln based on latest intel.
* Recompute `CVSS-BT` / `CVSS-BTE` and store new assessments with `assessed_at` timestamp.
### 5.2 Environmental metrics
Environmental metrics adjust severity to a specific environment. ([first.org][1])
Implementation guidelines:
* Link `vuln_id` to asset(s) via your CMDB / asset inventory.
* For each asset, maintain:
* CIA requirements: `CR`, `IR`, `AR` (Low / Medium / High)
* Key controls: e.g., network segmentation, WAF, EDR, backups, etc.
* Map asset metadata to Environmental metrics:
* For highcritical systems, set `CR/IR/AR = H`.
* For heavily segmented systems, adjust Modified Attack Vector or Impact metrics accordingly.
* Provide:
* A default environment profile (for generic scoring).
* Perasset or perassetgroup overrides.
---
## 6. Supplemental metrics handling
Supplemental metrics do not affect the CVSS score formula but provide critical context: Safety (S), Automatable (AU), Provider Urgency (U), Recovery (R), Value Density (V), Response Effort (RE). ([first.org][3])
Guidelines:
* Always parse and store them for v4.0 vectors.
* Provide an internal risk model that can optionally:
* Upweight vulns with:
* `S = Safety-critical`
* `AU = True` (fully automatable exploitation)
* `V = High` (many assets affected)
* Downweight vulns with very high Response Effort (RE) when there is low business impact.
* Make Supplemental metrics explicitly visible in the UI as “context flags,” not hidden inside a numeric score.
---
## 7. Backward compatibility with CVSS v3.x
You will be living in a dual world for a while.
Guidelines:
1. **Store v3.x assessments asis**
* `version = '3.1'` or `'3.0'`
* `vector_string`, `score`, `severity_band` (using v3 scale).
2. **Never treat v3.x and v4.0 scores as directly comparable**
* 7.5 in v3.x ≠ 7.5 in v4.0.
* For dashboards and filters, compare inside a version, or map both to coarse severity bands.
3. **Do not autoconvert v3 vectors to v4 vectors**
* Mapping is not lossless; misleading conversions are worse than clearly labeled legacy scores.
4. **UI and API**
* Always show `version` and `score_type` next to the numeric score.
* For API clients, include structured metrics so downstream systems can migrate at their own pace.
---
## 8. UI/UX guidelines
Give your designers and frontend devs explicit behaviors.
* On vulnerability detail pages:
* Show:
* `CVSS v4.0 (CVSS-BTE) 9.1 Critical`
* Version and score type are always visible.
* Provide a toggle or tab:
* “View raw vector,” expanding to show all metrics grouped: Base / Threat / Environmental / Supplemental.
* For lists and dashboards:
* Use severity bands (None / Low / Medium / High / Critical) as primary visual grouping.
* For mixed environments:
* Show two columns if available: `CVSS v4.0` and `CVSS v3.1`.
* For analysts:
* Provide a builtin calculator UI that lets them adjust Threat / Environmental metrics and immediately see updated `CVSS-BT/BE/BTE`.
---
## 9. Testing & validation
Define a clean test strategy before implementation.
1. **Golden test cases**
* Use official FIRST examples and calculators (v4.0 spec & user guide) as ground truth. ([first.org][4])
* Build a small public corpus:
* 2050 CVEs with published v4.0 vectors and scores (from NVD / vendors) and confirm byteforbyte matches.
2. **Roundtrip tests**
* `vector_string -> parse -> metrics -> compute -> vector_string`
* Ensure you can reconstruct the same canonical vector.
3. **Regression tests**
* Add tests for:
* Missing Threat / Environmental metrics (defaults).
* Invalid vectors (fail gracefully, log, do not crash pipelines).
* Mixed v3/v4 data in the same views.
4. **Performance**
* CVSS computations are cheap, but in bulk (e.g., 1M+ findings) avoid perrequest recalculation; cache computed results per `(vuln_id, metrics_hash)`.
---
## 10. Rollout / migration plan (high level)
What you can ask engineering to follow:
1. **Phase 1 Data model & parsing**
* Add schema changes for `cvss_assessments`.
* Implement v4.0 parser and scorer, with full unit tests.
2. **Phase 2 Ingestion**
* Update NVD / GitHub / vendor importers to capture v4 vectors when present.
* Backfill existing data with `version` = v3.x or v2.0 as appropriate.
3. **Phase 3 UI & API**
* Expose versioned CVSS data and vector strings.
* Mark all legacy places that assumed “CVSS = single number” and refactor to be versionaware.
4. **Phase 4 Threat & Environmental automation**
* Wire in threat intel feeds and asset metadata.
* Start generating `CVSS-BT` / `CVSS-BTE` scores for key asset groups.
5. **Phase 5 Risk model integration**
* Use CVSS (v3/v4), plus Supplemental metrics, plus your own business logic to output a platformspecific risk score.
---
## 11. Developer checklist (condensed)
You can literally put this as a checklist in Jira/Notion:
* [ ] Schema updated to store:
* [ ] `version`, `vector_string`, `score`, `score_type`, `severity_band`, `source`, timestamps.
* [ ] Structured Base / Threat / Environmental / Supplemental metrics.
* [ ] Parser for `CVSS:4.0/...` with validation and graceful error handling.
* [ ] Scoring engine for v4.0 using official equations; golden tests against FIRST calculator.
* [ ] Support for v3.x preserved; no crossversion conversion.
* [ ] UI shows version and score type; exposes vector and metrics.
* [ ] Threat intel mapping to Exploit Maturity (E) implemented.
* [ ] Environmental mapping from asset metadata implemented (even if initially basic).
* [ ] Supplemental metrics parsed, stored, and surfaced.
* [ ] Risk scoring logic separated from raw CVSS.
* [ ] Regression tests + performance tests in CI.
If you tell me what your current schema and pipeline look like (tables, services, scanners in use), I can produce a concrete migration diff (DDL and servicelevel changes) tailored to your stack.
[1]: https://www.first.org/cvss/v4-0/cvss-v40-specification.pdf "CVSS v4.0 Specification - 2024-06-18"
[2]: https://en.wikipedia.org/wiki/Common_Vulnerability_Scoring_System?utm_source=chatgpt.com "Common Vulnerability Scoring System"
[3]: https://www.first.org/cvss/v4-0/?utm_source=chatgpt.com "Common Vulnerability Scoring System Version 4.0"
[4]: https://www.first.org/cvss/v4-0/user-guide?utm_source=chatgpt.com "CVSS v4.0 User Guide"

View File

@@ -0,0 +1,108 @@
Heres a compact, diagram-first blueprint that shows how to turn a CycloneDX SBOM into signed, replay-safe proofs across DSSE/in-toto, Rekor v2 (tile-backed) receipts, and VEX—plus how to run this with the public instance or fully offline.
---
## 1) Mental model (one line per hop)
```
[SBOM: CycloneDX JSON]
└─(wrap as DSSE payload; predicate = CycloneDX)
└─(optional: in-toto statement for context)
└─(sign → cosign/fulcio or your own CA)
└─(log entry → Rekor v2 / tiles)
└─(checkpoint + inclusion proof + receipt)
└─(VEX attestation references SBOM/log)
└─(Authority anchors/keys + policies)
```
* **CycloneDX SBOM** is your canonical inventory. ([cyclonedx.org][1])
* **DSSE** provides a minimal, standard signing envelope; in-toto statements add supply-chain context. ([JFrog][2])
* **Rekor v2** stores a hash of your attestation in a **tile-backed transparency log** and returns **checkpoint + inclusion proof** (small, verifiable). ([Sigstore Blog][3])
* **VEX** conveys exploitability (e.g., “not affected”) and should reference the SBOM and, ideally, the Rekor receipt. ([cyclonedx.org][4])
---
## 2) Exact capture points (what to store)
* **SBOM artifact**: `sbom.cdx.json` (canonicalized bytes + SHA256). ([cyclonedx.org][1])
* **DSSE envelope** over SBOM (or in-toto statement whose predicate is CycloneDX): keep the full JSON + signature. ([JFrog][2])
* **Rekor v2 receipt**:
* **Checkpoint** (signed tree head)
* **Inclusion proof** (audit path)
* **Entry leaf hash / UUID**
Persist these with your build to enable offline verification. ([Sigstore Blog][3])
* **VEX attestation** (CycloneDX VEX): include references (by digest/URI) to the **SBOM** and the **Rekor entry/receipt** used for the SBOM attestation. ([cyclonedx.org][4])
* **Authority anchors**: publish the verifying keys (or TUF-root if using Sigstore public good), plus your policy describing accepted issuers and algorithms. ([Sigstore][5])
---
## 3) Field-level linkage (IDs youll wire together)
* **`subject.digest`** in DSSE/in-toto ↔ **SBOM SHA256**. ([OpenSSF][6])
* **Rekor entry** ↔ **DSSE envelope digest** (leaf/UUID recorded in receipt). ([GitHub][7])
* **VEX `affects` / `analysis`** entries ↔ **components in SBOM** (use purl/coordinates) and include **`evidence`/`justification`** with **Rekor proof URI**. ([cyclonedx.org][4])
---
## 4) Verification flow (online or air-gapped)
**Online (public good):**
1. Verify DSSE signature against accepted keys/issuers. ([Sigstore][5])
2. Verify Rekor **checkpoint signature** and **inclusion proof** for the logged DSSE digest. ([Go Packages][8])
3. Validate VEX against the same SBOM digest (and optionally that its own attestation is also logged). ([cyclonedx.org][4])
**Air-gapped / sovereign:**
* Mirror/export **Rekor tiles + checkpoints** on a courier medium; keep receipts small by shipping only tiles covering the ranges you need.
* Run **self-hosted Rekor v2** or a **local tile cache**; verifiers check **checkpoint signatures** and **consistency proofs** exactly the same way. ([Sigstore Blog][3])
---
## 5) Public instance vs self-hosted (decision notes)
* **Public**: zero-ops, audited community infra; you still archive receipts with your releases. ([Sigstore][5])
* **Self-hosted Rekor v2 (tiles)**: cheaper/simpler than v1, tile export makes **offline kits** practical; publish your **root keys** as organization anchors. ([Sigstore Blog][3])
---
## 6) Minimal CLI recipe (illustrative)
* Generate SBOM → wrap → attest → log → emit receipt:
* Create CycloneDX JSON; compute digest. ([cyclonedx.org][1])
* Create **DSSE** or **in-toto** attestation for the SBOM; sign (cosign or your CA). ([JFrog][2])
* Submit to **Rekor v2**; store **checkpoint + inclusion proof + UUID** with the build. ([Sigstore Blog][3])
* Emit **VEX** referencing the SBOM digest **and** the Rekor entry (URI/UUID). ([cyclonedx.org][4])
---
## 7) Developer guardrails (to keep proofs replay-safe)
* **Canonical bytes only** (stable JSON ordering/whitespace) before hashing/signing. ([JFrog][2])
* **Pin algorithms** (e.g., SHA-256 + key types) in policy; reject drift. ([Sigstore][5])
* **Always persist**: SBOM, DSSE envelope, Rekor receipt, VEX, and your **accepted-keys manifest** with version. ([Sigstore Blog][3])
* **Test offline**: verification must pass using only tiles + receipts you ship. ([Go Packages][9])
---
## 8) Optional niceties
* Gate deployments on “image must have **signed SBOM** (attestation)”. Sigstore Policy Controller example exists. ([Stackable Documentation][10])
* Track CVE status via **CycloneDX VEX** in your UI (“affected/not affected” with evidence links to Rekor). ([cyclonedx.org][4])
---
If you want, I can turn this into a **Stella Ops** diagram + drop-in `docs/blueprints/sbom-to-vex-rekor.md` with exact JSON stubs for: DSSE envelope, in-toto statement, Rekor receipt example, and a CycloneDX VEX snippet wired to the receipt.
[1]: https://cyclonedx.org/specification/overview/?utm_source=chatgpt.com "Specification Overview"
[2]: https://jfrog.com/blog/introducing-dsse-attestation-online-decoder/?utm_source=chatgpt.com "Introducing the DSSE Attestation Online Decoder"
[3]: https://blog.sigstore.dev/rekor-v2-ga/?utm_source=chatgpt.com "Rekor v2 GA - Cheaper to run, simpler to maintain"
[4]: https://cyclonedx.org/capabilities/vex/?utm_source=chatgpt.com "Vulnerability Exploitability eXchange (VEX)"
[5]: https://docs.sigstore.dev/logging/overview/?utm_source=chatgpt.com "Rekor"
[6]: https://openssf.org/blog/2024/06/26/a-deep-dive-into-sbomit-and-attestations/?utm_source=chatgpt.com "A Deep Dive into SBOMit and Attestations"
[7]: https://github.com/sigstore/rekor?utm_source=chatgpt.com "sigstore/rekor: Software Supply Chain Transparency Log"
[8]: https://pkg.go.dev/github.com/sigstore/rekor-tiles/v2/pkg/verify?utm_source=chatgpt.com "verify package - github.com/sigstore/rekor-tiles/v2/pkg/verify"
[9]: https://pkg.go.dev/github.com/sigstore/rekor-tiles?utm_source=chatgpt.com "rekor-tiles module - github.com/sigstore/rekor-tiles"
[10]: https://docs.stackable.tech/home/stable/guides/viewing-and-verifying-sboms/?utm_source=chatgpt.com "Viewing and verifying SBOMs of the Stackable Data Platform"

View File

@@ -0,0 +1,354 @@
I put together a short “failure-catalogue” of five high-impact real issues or regressions between 20232025 across Trivy / Syft / Grype, Snyk and JFrog — especially focused on reachability, SBOM provenance/gaps, offline/updater problems, and DB-churn noise. I thought you might want concrete test vectors for your StellaOps backlog.
![Image](https://d3g9o9u8re44ak.cloudfront.net/logo/e210b50b-8204-4095-b308-67e4b6097cc2/331f3e36-ea61-4b6a-a40e-1a29e0b70304.png)
![Image](https://repository-images.githubusercontent.com/267054247/c41d4c8f-cd32-4bdd-9f2a-89a82992a359)
![Image](https://syft.com/assets/Meta-images/syft.png)
![Image](https://upload.wikimedia.org/wikipedia/commons/9/97/Syft_Logo.png)
![Image](https://mma.prnewswire.com/media/807259/SYFT_Logo.jpg)
---
## ⚠️ Notable failures & walk-backs
### **1. Trivy fails to detect critical CVEs in JAR files — even when present in DB (2024)**
* In a discussion titled “Trivy not detecting CVE 2022-37734, 2023-28867, 2024-22233 in jar file” (Feb 6, 2024), a user reports that while scanning a container image that includes `graphql-java-codegen-5.9.0.jar` or `spring-core-6.0.14.jar`, Trivy — even with the latest DB — ignores these CVEs. The same CVEs are otherwise picked up by Maven-based scanning. ([GitHub][1])
* This indicates a fundamental mismatch between what the vulnerability DB says and what Trivy actually reports: a “reachability/noise gap” or “false negative in jar unpacking”.
* **Test vector idea for StellaOps**: build a minimal container with `graphql-java-codegen-5.9.0.jar` (or `spring-core-6.0.14.jar`), run Trivy with latest DB, check whether it flags CVE-2022-37734 / 2023-28867 / 2024-22233. If not — this is a confirmed “blind spot”.
### **2. More general “Jar / Java-libs detection” regressions in Trivy (2023)**
* Issue #4046 on Trivys repo (Apr 12, 2023) states that certain Java-based container images show no CVEs detected at all, even though other tools (like Grype) do pick them up. ([GitHub][2])
* Similarly, older but related issues such as #1869 (Mar 2022) and #2089 (May 2022) describe cases where Trivy lists packages inside JARs, but fails to report any vulnerabilities tied to those packages — a direct SBOM-to-vuln mapping failure. ([GitHub][3])
* **Implication**: SBOM-based scanning with Trivy underrepresents Java ecosystem risk (especially for fat-jar or dependency-bundle patterns). That undermines “SBOM completeness” assumptions.
### **3. Discrepancy between SBOM-generation (Syft) and vulnerability scanning (Grype/Trivy) — huge package-count gap (2024)**
* In a discussion from March 2024, a user reports that a fresh build of a patched distro (Rocky Linux 9.3 with GUI) scanned with Syft reports ≈ 6000 packages, but the same system scanned with Trivy reports only ≈ 1300 packages. ([GitHub][4])
* When feeding the Syft SBOM to Grype, the user sees “over 300 vulnerabilities”; but when Grype processes the Trivy-generated SBOM, it reports less than 10 vulnerabilities — a dramatic underreporting. ([GitHub][4])
* **Test vector idea**: for a known-updated Linux distro (e.g. Rocky 9.3), generate SBOMs via Syft and Trivy, then feed both into Grype — compare package counts and vuln counts side-by-side. This tests real-world “SBOM provenance gaps + under-scanning”.
### **4. Regression in Grype (post-v0.87.0) leads to false negatives (Apr 2025)**
* On Apr 30, 2025: issue #2628 reports that a minimal SBOM containing vulnerable artifacts is correctly flagged by Grype v0.87.0 (3 critical + 2 high), but with any later version (incl. latest) it reports no vulnerabilities at all. ([GitHub][5])
* **Implication**: DB-churn + schema changes or scanning logic shifts can regress coverage dramatically, even for simple known cases.
* **Test vector idea**: replicate the minimal SBOM from the issue with vulnerable artifacts, run Grype at v0.87.0 and then at latest; confirm gap. Great candidate for regression monitoring in StellaOps.
### **5. Broader SBOM integrity & trust problems — even if scanning works (2024)**
* Recent academic work (Dec 2024) titled “The Lack of Integrity Protection in SBOM Solutions” shows that many SBOM tools (generation and consumption) lack integrity/integrity-protection: dependencies can be tampered or mislabeled, which can lead to “incorrect SBOM data → vulnerabilities overlooked.” ([arXiv][6])
* Meanwhile, a 2025 empirical study on real-world open-source repos found that downstream scanners using SBOMs produce a ~97.5% false-positive rate (largely due to unreachable code), recommending function-call analysis to prune noise. ([arXiv][7])
* **Implication for StellaOps**: even a “perfect SBOM → perfect scan” pipeline may be fundamentally flawed unless you add provenance validation + reachability analysis. Reliance on SBOM + vuln-scanner alone gives a very noisy, untrustworthy result.
---
## 🎯 Why this matters for StellaOps & your architecture
* These are concrete, high-impact failures in widely used SCA tools (Trivy, Syft, Grype, Snyk ecosystem) — they demonstrate **false negatives**, **SBOM gaps**, **DB/logic regressions**, and **SBOM-integrity weaknesses**.
* Given StellaOps goals (deterministic replayable scans, cryptographic provenance, “Trust Algebra”, remediation prioritization), you should treat each issue above as a **test/sanity vector** or **alarm scenario** to include in your backlog.
* In particular: the jar-file CVE misses, SBOM-generation vs scan divergence, and post-DB-schema regressions represent the kind of toolchain brittleness that StellaOps is designed to mitigate (or detect).
---
If you like, I can expand this into a **10-item catalogue** covering also misconfig scanning, SBOM forgery, offline-updater stale DB incidents and compare across all major SCA tools (Trivy / Grype / Snyk / JFrog / CycloneDX, etc.) — which would be a richer resource for StellaOps testing.
[1]: https://github.com/aquasecurity/trivy/discussions/6074?utm_source=chatgpt.com "Trivy not detecting CVE 2022-37734, 2023-28867, 2024- ..."
[2]: https://github.com/aquasecurity/trivy/issues/4046?utm_source=chatgpt.com "trivy did not detect java libs · Issue #4046 · aquasecurity/trivy"
[3]: https://github.com/aquasecurity/trivy/issues/1869?utm_source=chatgpt.com "Missing vulnerabilities for jar files #1869 - aquasecurity/trivy"
[4]: https://github.com/aquasecurity/trivy/discussions/6325?utm_source=chatgpt.com "and of those detected Trivy sometimes does not report a ..."
[5]: https://github.com/anchore/grype/issues/2628?utm_source=chatgpt.com "Grype false negatives in versions v0.88.0 and later leading ..."
[6]: https://arxiv.org/abs/2412.05138?utm_source=chatgpt.com "Supply Chain Insecurity: The Lack of Integrity Protection in SBOM Solutions"
[7]: https://arxiv.org/abs/2511.20313?utm_source=chatgpt.com "A Reality Check on SBOM-based Vulnerability Management: An Empirical Study and A Path Forward"
Think of this as a short internal directive you can hand to the StellaOps team.
---
## 1. Nonnegotiable principles
Tell the team these are hard constraints, not “nice to haves”:
1. **No silent false negatives.**
* The engine must *never* drop a potential vulnerability just to reduce noise.
* If something is uncertain → label it (`“low confidence”`, `"maybe affected"`) and show it, dont hide it.
2. **Separation of “detection” vs. “prioritization”.**
* Detection layer: “Which CVEs *might* apply?” → exhaustive and conservative.
* Prioritization layer: “Which matter most?” → filters for humans, but never deletes raw matches.
3. **Offline and airgapped are firstclass.**
* Any feature must work in a strictly offline mode or fail *explicitly* with a clear error, not partial silent behavior.
* A `--offline` / `no-network` mode must guarantee **zero network calls** on every code path.
4. **No schema or DB surprises.**
* Engine and DB must have explicit, negotiated versions.
* If a DB is incompatible, the scan must fail loudly with a remediation hint, not degrade silently.
5. **SBOM integrity over convenience.**
* SBOMs must be treated as evidence that can be wrong or tampered with, not as gospel.
* The system should verify SBOMs against artefact digests and highlight discrepancies.
6. **Reachability is a signal, not a gate.**
* Reachability analysis may reprioritize, but never suppress the existence of a vulnerability.
---
## 2. Guardrails mapped to past failure modes
### A. “Missed JAR CVEs” / detectionpriority bugs
**Problem type:** Scanner skipped valid vulnerabilities because matching logic was too strict or defaulted to a “safe” mode that sacrificed coverage.
**Instructions to devs:**
1. **Tristate matching, never binary only.**
* Every candidate CVE should end up in one of:
* `confirmed_affected`
* `potentially_affected` (e.g. upstream advisory, weak match)
* `not_affected`
* *Prohibited:* silently dropping `potentially_affected` to “help” users.
2. **Explicit detection modes with safe defaults.**
* Provide:
* `mode=exhaustive` (default in backend; UI can choose what to show prominently)
* `mode=precise` (for strict production gating, but still storing all candidates)
* Detection mode can change *presentation*, not the underlying recorded facts.
3. **Mandatory explanation fields.**
* For each match, store:
* `why_matched` (e.g. “CPE normalized match via alias map”)
* `why_not_promoted` (e.g. “only upstream advisory, no distro backport”)
* If something is dropped from “confirmed”, it must have a machinereadable reason.
---
### B. SBOM incompleteness (“missing orphan packages”)
**Problem type:** Merge logic or graph logic discarded “orphan” packages → incomplete SBOM → missed CVEs and EOL issues.
**Instructions:**
1. **Invariant: no silent dropping of packages.**
* During SBOM generation/ingestion, any package discovered must be present in the final SBOM *or* explicitly listed in a `dropped_components` section with a reason code.
* Add automated tests asserting: `discovered_count == sbom_components_count + dropped_components_count`.
2. **Crosscheck with package managers.**
* For OS images:
* Compare SBOM against `rpm -qa`, `dpkg -l`, `apk info`, etc.
* Define allowed differences (e.g. virtual packages, metapackages).
* Fail CI if SBOM underreports by more than a small, configurable margin.
3. **Graph vs list separation.**
* Keep a flat **component list** separate from the **dependency graph**.
* Graph logic may exclude outofgraph components from “dependency tree”, but never from the raw component list.
4. **SBOM roundtrip tests.**
* For each supported SBOM format:
* Generate SBOM → reingest → generate again → compare component sets.
* Any component lost in the roundtrip is a bug.
---
### C. Offline DB, Java DB and schemachurn failures
**Problem type:** New DBs introduced (e.g. Java DB) forced online updates despite `--skip-db-update`; schema changes broke offline setups.
**Instructions:**
1. **Strict offline contract.**
* If `offline=true`:
* Absolutely forbidden: network calls, even retries.
* If a DB is missing: abort with an explicit error like
`“Java vulnerability DB not present; run command X on a connected host to fetch it.”`
2. **Version negotiation between engine and DB.**
* DB contains:
* `db_schema_version`
* `min_engine_version` / `max_engine_version`
* Engine on startup:
* If DB schema is unsupported → fail fast with a migration hint.
* *Never* continue with a mismatched DB.
3. **Separate DBs for language ecosystems.**
* Each language/ecosystem DB handled independently:
* Missing Java DB should not break OS scanning.
* Mark those language results as “unavailable due to missing DB”.
4. **Compatibility test matrix.**
* For every release:
* Test with **previous N DB versions** and **newest DB**.
* Test both online and offline flows.
* Regression tests should include:
* Stale DB, corrupted DB, missing DB, wrong schema version.
---
### D. Reachability misclassification (Snykstyle issues)
**Problem type:** “Unreachable” label used where analysis simply lacked coverage → real exploitable bugs downweighted or hidden.
**Instructions:**
1. **Coverageaware reachability labels.**
* Distinguish:
* `reachable` (with proof)
* `not_reachable_within_coverage` (negative proof within known coverage)
* `not_analyzed` (no coverage for this stack/entrypoint)
* **Never** label as “unreachable” if the language/framework isnt supported.
2. **No gating by reachability.**
* Policies may say “ignore nonreachable in dashboard”, but the raw issue must exist and be queryable.
* Any mass change in reachability (due to engine upgrade) must be tracked and explained in release notes.
3. **Reachability regression tests.**
* Maintain a small corpus of apps where:
* Specific vulnerable functions *are* called.
* Specific vulnerable functions are present but deliberately never called.
* CI must ensure reachability engines decisions on this corpus remain stable or improve, never regress.
---
### E. Package identity & provenance (Xraystyle name collision issues)
**Problem type:** Name/version alone used for matching; local/internal components misidentified as public packages (false positives) and vice versa (false negatives).
**Instructions:**
1. **Always prefer fully qualified identifiers.**
* Normalize everything to purllike coordinates:
* e.g. `pkg:npm/float-kit@1.0.0`, `pkg:docker/library/alpine@3.18`, `pkg:maven/com.squareup.okio/okio@3.0.0`
* Name+version alone should be treated as lowconfidence.
2. **Provenance as a firstclass field.**
* Record for each component:
* Source: registry (npm, PyPI, Maven, OS repo), VCS, local, vendored.
* Evidence: lockfile, SBOM, manifest, binary heuristics.
* Only match against the correct source:
* npm advisories apply only to `source=npm` components, etc.
3. **Tiered match confidence.**
* `high` exact purl or CPE match with expected registry.
* `medium` alias mapping, wellknown naming differences.
* `low` name/version only, with no provenance.
* Policy: **high** and **medium** shown normally; **low** flagged as “needs manual review” or hidden behind a specific toggle, never silently treated as truth.
4. **SBOM + runtime fusion.**
* When ingesting external SBOMs, try to confirm:
* Component digest vs actual file.
* If mismatched → downgrade confidence or flag as “SBOM out of sync with artefact”.
---
## 3. Testing & regression harness (what must exist before launch)
Give the team a checklist that must be green before any release:
1. **Golden corpus of images/projects.**
* Include:
* Known vulnerable JARs (like the ones from earlier incidents).
* Distros with thousands of packages (Rocky, Debian, Alpine).
* Mixed stacks (Java + Python + Node).
* For each, store:
* Expected # of components.
* Expected CVEs (per tool / per feed).
* Expected SBOM shape.
2. **Crosstool differential tests.**
* Regularly run StellaOps + Trivy + Grype/Syft + Snyk on the corpus (in a lab).
* Any large deviation:
* More findings: investigate FPs.
* Fewer findings: treat as potential FN until proven otherwise.
3. **Mutation tests for SBOM and metadata.**
* Randomly:
* Remove lockfiles.
* Change versions.
* Make SBOM inconsistent with artefact.
* Verify:
* System flags inconsistencies.
* Doesnt crash.
* Doesnt blindly trust clearly broken data.
4. **Offline chaos tests.**
* Simulate:
* No network.
* Corrupted DB.
* Outdated DB with new engine.
* Required behavior:
* Clear, actionable errors.
* No partial, silent scans.
---
## 4. Concrete acceptance criteria you can mandate
You can literally hand this as a policy:
> A feature or release must **not** ship unless:
>
> 1. Running in offline mode never triggers a network call and does not crash if a languagespecific DB is missing; instead, it emits a clear, actionable error.
> 2. SBOM component counts for golden images are within agreed tolerances vs package manager outputs, with all differences explained.
> 3. For every CVE in the golden corpus, the engine either reports it as `confirmed_affected` / `potentially_affected` or logs a machinereadable justification for `not_affected`.
> 4. Reachability status for golden test apps is stable or improved vs previous release; there are no reclassified “unreachable” issues where coverage is absent.
> 5. Any schema or DB change is accompanied by:
>
> * A migration path.
> * A compatibility test.
> * A failure mode that is explicit and documented.
If you bake those rules into your engineering process (and CI), StellaOps will be structurally protected from the exact classes of failures weve seen in the other tools — and when something *does* go wrong, it will be visible, explainable, and fixable, rather than a silent loss of coverage.

View File

@@ -0,0 +1,637 @@
Heres a compact, nofluff onboarding brief to get a midlevel .NET dev productive on StellaOps in a couple of days.
---
# StellaOps MidLevel .NET Onboarding (Quick Start)
## 0) What youre building (context in one minute)
StellaOps is a sovereign, airgapfriendly SBOM→VEX platform written in .NET 10. Core ideas: deterministic scans, cryptographic attestations (DSSE/intoto; optional PQC), trust lattices for VEX decisions, and a replayable audit trail.
---
## 1) Repos to open first (read in this order)
1. `src/StellaOps.Scanner.WebService/` — scanning surfaces, rules plumbing, lattice calls.
2. `src/StellaOps.Vexer/` (a.k.a. Excititor) — VEX verdict engine & trustmerge logic.
3. `src/StellaOps.Sbomer/` — SBOM ingest/normalize (CycloneDX/SPDX).
4. `src/StellaOps.Authority/` — keys, attestations, license tokens, Rekor integration.
5. `src/StellaOps.Scheduler/` — batch & replay orchestration.
6. `src/StellaOps.Shared/CanonicalModel/` — canonical entities & graph IDs (read carefully).
Tip: keep `docs/modules/platform/*` open for protocol notes (DSSE envelopes, lattice terms).
---
## 2) Local dev up in ~1015 min
* Prereqs: .NET 10 SDK (preview), Docker, Node (for Angular UI if needed), WSL2 optional.
* From repo root:
```bash
# infra
docker compose -f compose/offline-kit.yml up -d # Mongo/Postgres/Rabbit/MinIO per profile
# backend
dotnet restore
dotnet build -c Debug
# run a focused slice (scanner + authority)
dotnet run --project src/StellaOps.Authority/StellaOps.Authority.csproj
dotnet run --project src/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj
```
* Environment: copy `env/example.local.env``.env`, then set `STELLAOPS_DB` provider (`Mongo` or `Postgres`) and `AUTHORITY_*` keys.
---
## 3) Deterministic testcases to run locally (prove your env is correct)
These are “golden” replays: same inputs → same graph & hashes.
1. **HelloSBOM → VEX NotAffected (Reachabilityfalse)**
```bash
dotnet test tests/Determinism/Det_SbomToVex_NotAffected.csproj
```
Checks: identical GraphRevisionID and DSSE payload hash across two consecutive runs.
2. **Intoto chain: source→build→image attestation**
```bash
dotnet test tests/Attestations/Att_InToto_Chain.csproj
```
Checks: DSSE envelope canonicalization stable; signature over CBORcanonical JSON matches stored hash.
3. **Lattice merge: vendor VEX + runtime signal**
```bash
dotnet test tests/Lattice/Lattice_VendorPlusRuntime.csproj
```
Checks: merge verdict is stable with the same input set order; produces identical TrustReceipt.
If any golden snapshot differs, your clock/locale/lineendings or JSON canonicalizer is misconfigured.
---
## 4) Coding conventions (cryptographic attestations & determinism)
* **JSON**: serialize with our `CanonicalJson` (UTF8, sorted keys, no insignificant whitespace, `\n` line endings).
* **DSSE**: always embed `payloadType` = `application/vnd.stellaops.trust+json`.
* **Hashing**: BLAKE3 for internal content addressing, SHA256 where interop requires.
* **Keys**: use `Authority.KeyRing` provider (Ed25519 by default; PQC Dilithium optional flag `AUTHORITY_PQC=on`).
* **Timestamps**: use `Instant` (UTC) with truncation to milliseconds; never `DateTime.Now`.
* **IDs**: graph nodes use `HashStableId` derived from canonical bytes; never database autoinc for public IDs.
* **VEX**: verdicts must include `proofs[]` (e.g., reachability, configguards, runtime path) and a `receipt` signed by Authority.
* **Repro**: any function that affects verdicts must be pure or behind a deterministic adapter.
Snippet (sign a DSSE envelope deterministically):
```csharp
var payload = CanonicalJson.Serialize(trustDoc);
var env = DsseEnvelope.Create("application/vnd.stellaops.trust+json", payload);
var signed = await keyRing.SignAsync(env.CanonicalizeBytes());
await rekor.SubmitAsync(signed, RekorMode.OfflineMirrorIfAirgapped);
```
---
## 5) Minimal daily loop
* Pick one starter issue (below).
* Write unit tests first; ensure golden snapshots match.
* Run `dotnet test --filter Category=Determinism`.
* Commit with `feat(scanner|vexer|authority): …` and include the GraphRevisionID delta in the body.
---
## 6) Three starter issues (teach the canonical data model)
### A) Normalize CycloneDX components → Canonical Packages
**Goal**: map CycloneDX `components` to `CanonicalPackage` with stable IDs.
**Where**: `StellaOps.Sbomer` + tests in `tests/Determinism/Det_SbomMapping`.
**Done when**:
* Two equivalent SBOMs (field order shuffled) map to identical package set & IDs.
* Snapshot `CanonicalPackageSet.hash` is stable.
* Edge cases: missing `purl`, duplicate components, case differences.
### B) Implement “NotAffected by Configuration” proof
**Goal**: add proof generator that marks a CVE as notaffected if a config gate is off.
**Where**: `StellaOps.Vexer/Proofs/ConfigSwitchProof.cs`.
**Done when**:
* Given `FeatureX=false`, CVE1234 becomes `not_affected` with proof payload including `configPath`, `observed=false`.
* Deterministic proof hash and DSSE receipt exist.
* Lattice merge keeps vendor “affected” but flips to `not_affected` when runtime/config proof weight > threshold.
### C) Authority offline Rekor mirror submitter
**Goal**: if airgapped, write DSSE entries to local mirror; sync later.
**Where**: `StellaOps.Authority/Rekor/RekorMirrorClient.cs`.
**Done when**:
* `RekorMode.OfflineMirrorIfAirgapped` stores canonical entry (JSON+hash path).
* `rekor sync` job replays in order, preserving entry IDs.
* Golden test ensures same input sequence → same mirror tree hash.
---
## 7) Database notes (Mongo ↔ Postgres switchability)
* Use repository interfaces in `StellaOps.Shared.Persistence`.
* Canonical/public IDs are hashderived; DB keys are implementationlocal.
* Never rely on DB sort order for any hash or verdict; always recanonicalize before hashing.
---
## 8) Debug checklist (most common slips)
* Noncanonical JSON (unsorted keys, trailing spaces).
* Local time sneaking into proofs.
* Unstable GUIDs in tests.
* Nondeterministic enumeration over `Dictionary<>`.
* Different newline conventions on Windows—enforce `\n` in canonical paths.
---
## 9) Useful commands
```bash
# run determinism pack
dotnet test --filter Category=Determinism
# update golden snapshots (intentional change only)
dotnet test --filter Category=Determinism -- TestRunParameters.Parameter(name=\"UpdateSnapshots\", value=\"true\")
# quick API smoke
curl -s http://localhost:5080/health
curl -s -X POST http://localhost:5081/scan -d @samples/nginx.sbom.json
# verify DSSE signature locally
dotnet run --project tools/StellaOps.Tools.Verify -- file trust.receipt.json
```
---
## 10) Askonce glossary
* **SBOM**: software bill of materials (CycloneDX/SPDX).
* **VEX**: vulnerability exploitability exchange (verdicts: affected / notaffected / underinvestigation).
* **DSSE**: signed payload wrapper; we canonicalize before signing.
* **Lattice**: rule system to merge proofs/verdicts from different sources deterministically.
* **GraphRevisionID**: hash of the canonical trust graph; your “build number” for audits.
---
Want me to turn this into `docs/onboarding/dev-quickstart.md` plus three readytorun GitHub issues and the test scaffolds?
````markdown
# StellaOps Developer Quickstart
> **Audience:** Midlevel .NET developers
> **Goal:** Get you productive on StellaOps in 12 days, with special focus on determinism, cryptographic attestations, and the canonical data model.
---
## 1. What Youre Building (Context)
StellaOps is a sovereign, airgapfriendly platform that turns **SBOMs → VEX** with a fully **replayable, deterministic trust graph**.
Core concepts:
- **Deterministic scans:** Same inputs → same graph, hashes, and verdicts.
- **Cryptographic attestations:** DSSE/intoto envelopes, optional PQC.
- **Trust lattice:** Merges vendor VEX, runtime signals, configs, etc. into a single deterministic verdict.
- **Audit trail:** Every decision is reproducible from stored inputs and proofs.
If you think “contentaddressed trust pipeline for SBOMs + VEX,” youre in the right mental model.
---
## 2. Repository & Docs Map
Start by opening these projects **in order**:
1. `src/StellaOps.Scanner.WebService/`
Scanning endpoints, rule plumbing, and calls into the trust lattice.
2. `src/StellaOps.Vexer/` (a.k.a. *Excititor*)
VEX verdict engine and trustmerge logic.
3. `src/StellaOps.Sbomer/`
SBOM ingest / normalize (CycloneDX, SPDX).
4. `src/StellaOps.Authority/`
Key management, DSSE/intoto attestations, license tokens, Rekor integration.
5. `src/StellaOps.Scheduler/`
Batch processing, replay orchestration.
6. `src/StellaOps.Shared/CanonicalModel/`
Canonical entities & graph IDs. **Read this carefully** it underpins determinism.
Helpful docs:
- `docs/modules/platform/*` protocols (DSSE envelopes, lattice terms, trust receipts).
- `docs/architecture/*` highlevel diagrams and flows (if present).
---
## 3. Local Dev Setup
### 3.1 Prerequisites
- **.NET 10 SDK** (preview as specified in repo)
- **Docker** (for DB, queues, object storage)
- **Node.js** (for Angular UI, if youre touching the frontend)
- **WSL2** (optional, but makes life easier on Windows)
### 3.2 Bring Up Infra
From the repo root:
```bash
# Bring up core infra for offline / airgap friendly dev
docker compose -f compose/offline-kit.yml up -d
````
This usually includes:
* MongoDB or Postgres (configurable)
* RabbitMQ (or equivalent queue)
* MinIO / object storage (depending on profile)
### 3.3 Configure Environment
Copy the example env and tweak:
```bash
cp env/example.local.env .env
```
Key settings:
* `STELLAOPS_DB=Mongo` or `Postgres`
* `AUTHORITY_*` key material and config (see comments in `example.local.env`)
* Optional: `AUTHORITY_PQC=on` to enable postquantum keys (Dilithium).
### 3.4 Build & Run Backend
```bash
# Restore & build everything
dotnet restore
dotnet build -c Debug
# Run a focused slice for development
dotnet run --project src/StellaOps.Authority/StellaOps.Authority.csproj
dotnet run --project src/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj
```
Health checks (adjust ports if needed):
```bash
curl -s http://localhost:5080/health # Authority
curl -s http://localhost:5081/health # Scanner
```
---
## 4. Deterministic Sanity Tests
These tests prove your local environment is configured correctly for **determinism**. If any of these fail due to snapshot mismatch, fix your environment before writing new features.
### 4.1 SBOM → VEX “Not Affected” (Reachability False)
```bash
dotnet test tests/Determinism/Det_SbomToVex_NotAffected.csproj
```
**What it checks:**
* Two consecutive runs with the same SBOM produce:
* Identical `GraphRevisionID`
* Identical DSSE payload hashes
If they differ, inspect:
* JSON canonicalization
* Locale / culture
* Line endings
---
### 4.2 Intoto Chain: Source → Build → Image Attestation
```bash
dotnet test tests/Attestations/Att_InToto_Chain.csproj
```
**What it checks:**
* DSSE envelope canonicalization is stable.
* Signature over CBORcanonical JSON matches the stored hash.
* Full intoto chain can be replayed deterministically.
---
### 4.3 Lattice Merge: Vendor VEX + Runtime Signal
```bash
dotnet test tests/Lattice/Lattice_VendorPlusRuntime.csproj
```
**What it checks:**
* Merge verdict is stable regardless of input set order.
* Resulting `TrustReceipt` is byteforbyte identical between runs.
If any “golden” snapshots differ, you likely have:
* Noncanonical JSON
* Unstable enumeration (e.g., iterating `Dictionary<>` directly)
* Locale or newline drift
---
## 5. Coding Conventions (Determinism & Crypto)
These are **nonnegotiable** when working on code that affects trust graphs, proofs, or attestations.
### 5.1 JSON & Canonicalization
* Use our **`CanonicalJson`** helper for anything that will be:
* Hashed
* Signed
* Used as a canonical ID input
* Rules:
* UTF8
* Sorted keys
* No insignificant whitespace
* `\n` line endings (enforced for canonical paths)
### 5.2 DSSE Envelopes
* `payloadType` must always be:
* `application/vnd.stellaops.trust+json`
* Envelopes are signed over the **canonicalized bytes** of the payload.
Example:
```csharp
var payload = CanonicalJson.Serialize(trustDoc);
var env = DsseEnvelope.Create("application/vnd.stellaops.trust+json", payload);
var signed = await keyRing.SignAsync(env.CanonicalizeBytes());
await rekor.SubmitAsync(signed, RekorMode.OfflineMirrorIfAirgapped);
```
### 5.3 Hashing
* Internal content addressing: **BLAKE3**
* External / interop where required: **SHA256**
Never mix algorithms for the same ID type.
### 5.4 Keys & Algorithms
* Default signatures: **Ed25519** via `Authority.KeyRing`
* Optional PQC: **Dilithium** when `AUTHORITY_PQC=on`
* Never manage keys directly always use the keyring abstraction.
### 5.5 Time & Clocks
* Use `Instant` (UTC) / `DateTimeOffset` in UTC.
* Truncate to **milliseconds** for anything that ends up in canonical data.
* Never use `DateTime.Now` or local time in trustcritical code.
### 5.6 IDs & Graph Nodes
* Public / canonical IDs are derived from **hashes of canonical bytes**.
* DB primary keys are implementation details; do **not** leak them externally.
* Do **not** depend on DB autoincrement or sort order for anything that affects hashing.
### 5.7 VEX Verdicts
Every VEX verdict must:
* Be backed by `proofs[]` (e.g., reachability analysis, config guards, runtime path).
* Emit a `receipt` signed by **Authority**, wrapping:
* Verdict
* Proof hashes
* Context (component, vulnerability, scope, etc.)
---
## 6. Daily Workflow
A minimal loop that keeps you aligned with the platforms guarantees:
1. **Pick a focused issue** (see starter tasks below).
2. **Write tests first**, especially determinism tests where applicable.
3. Implement the change, keeping:
* Canonicalization boundaries explicit
* Hashing and signing centralized
4. Run:
```bash
dotnet test --filter Category=Determinism
```
5. Commit using:
* `feat(scanner): ...`
* `feat(vexer): ...`
* `feat(authority): ...`
* etc.
Include the affected `GraphRevisionID` in the commit body when relevant to trustgraph changes.
---
## 7. Suggested Starter Tasks
These are good first issues that teach the canonical model and determinism expectations.
### 7.1 Normalize CycloneDX Components → Canonical Packages
**Goal:** Map CycloneDX `components` to our `CanonicalPackage` model with stable IDs.
* **Area:** `StellaOps.Sbomer`
* **Tests:** `tests/Determinism/Det_SbomMapping`
**Definition of done:**
* Two equivalent SBOMs (only field order differs) produce:
* Identical package sets
* Identical canonical package IDs
* `CanonicalPackageSet.hash` is stable.
* Edge cases handled:
* Missing `purl`
* Duplicate components
* Case differences in names or versions
---
### 7.2 Implement “NotAffected by Configuration” Proof
**Goal:** Add proof generator that marks a CVE as `not_affected` when a config gate disables the vulnerable path.
* **Area:** `StellaOps.Vexer/Proofs/ConfigSwitchProof.cs`
**Definition of done:**
* Given `FeatureX=false`, CVE1234 yields verdict:
* `status = not_affected`
* `proofs[]` includes a `ConfigSwitchProof` with:
* `configPath`
* `observed=false`
* Proof is hashed deterministically and included in the DSSE receipt.
* Lattice merge behavior:
* Vendor verdict: `affected`
* Runtime/config proof weight > threshold → merged verdict becomes `not_affected` deterministically.
---
### 7.3 Authority Offline Rekor Mirror Submitter
**Goal:** Support airgapped mode: DSSE entries are written to a local Rekor mirror and synced later.
* **Area:** `StellaOps.Authority/Rekor/RekorMirrorClient.cs`
**Definition of done:**
* `RekorMode.OfflineMirrorIfAirgapped`:
* Stores canonical entries (JSON + hashbased path) on disk / object store.
* A `rekor sync` background job (or CLI) replays entries in order to the real Rekor instance.
* Determinism test:
* Same input DSSE sequence → same mirror tree hash and Rekor entry order.
---
## 8. Database Notes (Mongo ↔ Postgres)
StellaOps is designed to be DBagnostic.
* Use repository interfaces from `StellaOps.Shared.Persistence`.
* Keep **canonical/public IDs hashderived**; DB keys are internal.
* Do **not** depend on DB sort order for anything that:
* Affects hashes
* Affects verdicts
* Ends up in canonical data
If you need ordering, sort **after** canonicalization using deterministic criteria.
---
## 9. Common Pitfalls & Debug Checklist
When a determinism test fails, look for these first:
1. **Noncanonical JSON**
* Unsorted keys
* Extra whitespace
* Mixed `\r\n` vs `\n` line endings
2. **Local Time Leaks**
* Any `DateTime.Now` or local time in proofs or receipts.
3. **Random / Unstable IDs**
* New GUIDs in tests or canonical entities.
* Autoincrement IDs leaking into hashes.
4. **Unordered Collections**
* Iterating over `Dictionary<>` or `HashSet<>` without ordering.
* Using LINQ without explicit `OrderBy` when hashing or serializing.
5. **Platform Differences**
* Windows vs Linux newline differences.
* Locale differences (`,` vs `.` for decimals, etc.) always use invariant culture for canonical data.
---
## 10. Useful Commands
### 10.1 Determinism Pack
```bash
# Run only determinismtagged tests
dotnet test --filter Category=Determinism
```
Update golden snapshots when you *intend* to change canonical behavior:
```bash
dotnet test --filter Category=Determinism -- \
TestRunParameters.Parameter(name="UpdateSnapshots", value="true")
```
### 10.2 Quick API Smoke
```bash
curl -s http://localhost:5080/health
curl -s -X POST \
http://localhost:5081/scan \
-H "Content-Type: application/json" \
-d @samples/nginx.sbom.json
```
### 10.3 Verify DSSE Signature Locally
```bash
dotnet run --project tools/StellaOps.Tools.Verify -- file trust.receipt.json
```
---
## 11. Glossary (AskOnce)
* **SBOM** Software Bill of Materials (CycloneDX/SPDX).
* **VEX** Vulnerability Exploitability eXchange:
* Verdicts like `affected`, `not_affected`, `under_investigation`.
* **DSSE** Dead Simple Signing Envelope:
* Wrapper around payload + signature; we sign canonical bytes.
* **Intoto** Supplychain attestation framework; we use it for source→build→artifact chains.
* **Lattice** Rule system that merges multiple verdicts/proofs into a single deterministic verdict.
* **GraphRevisionID** Hash of the canonical trust graph at a point in time; acts like a build number for audits.
---
Welcome aboard. Your best “map” into the system is:
1. Read `CanonicalModel` types.
2. Run the determinism tests.
3. Pick one of the starter tasks and ship a small, welltested change.
If you keep everything **canonical, hashable, and replayable**, youll fit right in.
```
```

View File

@@ -0,0 +1,933 @@
Im sharing this because I think the comparison will help sharpen some of the UI/UX & data-model decisions for StellaOps — especially around how “evidence + suppression + audit/export” flows are implemented in existing tools and which patterns we might want to emulate or avoid.
Heres a compact snapshot (with recent documentation/screens and dates) of how a few major players — Snyk, GitHub (via repo scanning), Aqua Security / container scanning, Anchore/Grype, and Prisma Cloud — handle evidence, ignores (suppression / VEX), and audit/export primitives.
---
## ✅ What works: Evidence & audit flows that provide clarity
**Snyk — good “evidence + data flow + context” for code vulnerabilities**
* In Snyk Code, each issue links to a full “Data flow” trace from source to sink. ([Snyk User Docs][1])
* The UI hyperlinks to the Git repo, providing code-level context and version control traceability. ([Snyk User Docs][1])
* “Fix analysis” surfaces recommended fixes, diff examples, and community-driven suggestions. ([Snyk User Docs][1])
This deep evidence linkage is a valuable pattern for StellaOps triage and remediation.
**Anchore/Grype — VEX-aware suppression + SBOM export readiness**
* Anchore Enterprise documents vulnerability annotations + VEX support (SBOM scanning, annotations, fix statuses). ([Anchore Documentation][2])
* Grype respects VEX statuses (`not_affected`, `fixed`) and can expose suppressed matches via `--show-suppressed`. ([GitHub][3])
* Justifications can be scoped (e.g., `vulnerable_code_not_present` filters) and the API surfaces (Oct 2025) enable automation of SBOM + VEX + diffed results. ([Anchore Documentation][2])
This forms a solid SBOM → vulnerability → VEX → audit/export pipeline.
---
## ⚠️ Where things are brittle
**Snyk — suppression semantics vary across scan types**
* Ignore rules are project/integration-specific; UI ignores may not carry over to CLI import flows. ([Snyk][4])
* Snyk Code uses separate suppression UX (IDE/CLI) from OSS scans, leading to fragmentation. ([Snyk User Docs][5])
**Anchore/Grype — operational caveats**
* Feb 2025 issue: VEX suppression failed for directory scans because the source type wasnt supported. ([GitHub][6])
* Some suppressions require explicit config (`GRYPE_VEX_ADD`). ([GitHub][3])
* Ensuring SBOM + VEX + diffed outputs for audits often needs extra orchestration.
**Prisma Cloud — audit/export primitives are coarse**
* “Suppress Code Issues” feature exists, but no public doc shows an end-to-end SBOM + VEX + audit export flow. ([Prisma Cloud Documentation][7])
* Repo scanning + suppression features exist, but forensic traceability appears limited to “report + suppress”. ([Prisma Cloud Documentation][8])
---
## 🔑 What StellaOps should copy / avoid
**Copy**
* Snyk Code evidence + fix linking provides actionable traceability.
* Anchore/Grype SBOM → VEX suppression → facade for automation is the workflow to engineer.
* Surface suppression metadata (reason, status, justification) for auditing suppressed items.
**Avoid**
* Fragmented ignore rules per scan surface (OSS vs Code vs Container). Instead, keep suppression consistent.
* Hidden suppression; tie it to the main UI instead of a “show suppressed” toggle.
* Incomplete VEX support for certain source types; test across containers, directories, binaries, SBOMs.
If helpful, I can build a spreadsheet (Snyk, GitHub, Aqua, Anchore/Grype, Prisma Cloud) comparing evidence, suppression, APIs, exports, and gaps with doc links.
[1]: https://docs.snyk.io/scan-with-snyk/snyk-code/manage-code-vulnerabilities/breakdown-of-code-analysis?utm_source=chatgpt.com "Breakdown of Code analysis"
[2]: https://docs.anchore.com/current/docs/vulnerability_management/?utm_source=chatgpt.com "Anchore Secure - Vulnerability Management"
[3]: https://github.com/anchore/grype?utm_source=chatgpt.com "anchore/grype: A vulnerability scanner for container ..."
[4]: https://snyk.io/blog/ignoring-vulnerabilities-with-snyk/?utm_source=chatgpt.com "Ignoring vulnerabilities with Snyk"
[5]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/exclude-files-and-ignore-issues-faqs?utm_source=chatgpt.com "Exclude files and ignore issues FAQs"
[6]: https://github.com/anchore/grype/issues/2471?utm_source=chatgpt.com "Support using VEX documents with directory scans and ..."
[7]: https://docs.prismacloud.io/en/enterprise-edition/content-collections/application-security/risk-management/monitor-and-manage-code-build/suppress-code-issues?utm_source=chatgpt.com "Suppress Code Issues - Prisma Cloud Documentation"
[8]: https://docs.prismacloud.io/en/compute-edition/32/admin-guide/vulnerability-management/code-repo-scanning?utm_source=chatgpt.com "Configure code repository scanning"
Matrix built. Ill keep it compact enough to scan quickly, but detailed enough that you can lift it straight into a Google Sheet / Confluence page.
---
## 1. Evidence & context: what a *single finding* looks like
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Code-level evidence** | Snyk Code shows a *Data flow* view (taint graph) from source → sink with step-by-step code lines in the UI and IDE. ([docs.snyk.io][1]) | Code scanning alerts show file/line and, for data-flow rules, a “how data moves through the code” view with **Show paths** for the full flow. ([GitHub Docs][2]) | Trivy is not a SAST engine; evidence is per-file / resource for vulnerabilities & misconfigurations (IaC, K8s, etc.), not data-flow graphs. ([Trivy][3]) | No SAST; evidence is package / image / SBOM level (CVE, package, version, location). Grype is focused on images/filesystems, not code flows. ([Chainguard Academy][4]) | AppSec module shows issues mapped to file & line and offers inline remediation/fix flows; surfaced in console and IDE plugins (JetBrains/VS Code). ([Palo Alto Networks][5]) |
| **Dependency / container evidence** | For OSS & containers, Snyk shows dependency paths and has a **project issue paths** API that returns the introduction chain for a vuln. ([docs.snyk.io][6]) | Dependabot alerts show vulnerable package, version, advisories, and affected functions to help decide if code actually uses them. ([GitHub Docs][7]) | Trivy shows image → layer → package → vuln with installed/fixed versions; same for repos & filesystems in JSON/SARIF. ([GitHub][8]) | Grype output lists artifact, package, version, location, severity; when paired with Syft SBOM, you get full component graph for images and other artifacts. ([Chainguard Academy][4]) | Prismas Vulnerability Explorer & scan reports show image/host, package, severity and compliance IDs for image and host scans. ([docs.prismacloud.io][9]) |
| **SBOM / supply-chain context** | `snyk sbom` generates CycloneDX and SPDX SBOMs for local projects; Snyk also supports SBOM export in enterprise tiers. ([docs.snyk.io][10]) | GitHub builds a dependency graph from manifests and ingests SARIF from external scanners; it is SBOM-adjacent but not an SBOM UI. ([GitHub Docs][11]) | Trivy can output SBOMs (CycloneDX, SPDX, SPDX-JSON) and Kubernetes “KBOM” views, and is often used as the SBOM generator. ([Chainguard Academy][12]) | Anchore Enterprise is explicitly “SBOM-powered”; SBOM management views let you navigate applications and export SBOM-centric vulnerability views. ([docs.anchore.com][13]) | Prisma Cloud is inventory-/RQL-centric; SBOMs are not a first-class UI artifact and there is no public doc for full SBOM navigation comparable to Anchore or Trivy. ([Palo Alto Networks][5]) |
| **Where the evidence appears** | Web UI, CLI, IDEs (VS Code, JetBrains) and PR checks. Ignores for Snyk Code are now “consistent” across UI/CLI/IDE (2025-11 EA). ([docs.snyk.io][14]) | Web UI (Security tab), PR Conversation tab for code scanning reviews, REST & GraphQL APIs, and SARIF imports from many scanners. ([GitHub Docs][15]) | Trivy: CLI / JSON / SARIF / CI integrations (GitHub Actions, etc.). Aqua Platform adds a CNAPP UI with risk-based vulnerability views. ([GitHub][8]) | Grype: CLI & JSON/SARIF outputs; Anchore Enterprise: browser UI (dashboards, SBOM views, reporting) plus REST/GraphQL APIs. ([Chainguard Academy][4]) | Prisma Cloud: web console (AppSec dashboards, Vulnerability Explorer), REST APIs, IDE plugins for JetBrains & VS Code. ([docs.prismacloud.io][16]) |
---
## 2. Suppression / ignore / VEX behavior
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Suppression primitives** | `.snyk` policy file for OSS & container & IaC; `snyk ignore` CLI; “Ignore” in web UI; Snyk Code uses UI/CLI/IDE ignores but *not* `.snyk`. ([docs.snyk.io][17]) | Code scanning and Dependabot alerts can be **dismissed** with reasons; Dependabot has auto-triage rules (auto-dismiss/snooze). ([GitHub Docs][18]) | Trivy: `.trivyignore` / `.trivyignore.yaml` lists vuln IDs; `--ignore-policy` for Rego-based filtering; severity filters. ([aquasecurity.github.io][19]) | Grype: VEX-aware filtering via `--vex` and ignore rules; Anchore Enterprise: UI-driven vulnerability annotations that act as a structured “suppress or re-classify” layer. ([GitHub][20]) | AppSec: “Suppress Code Issues” (per-issue or globally) and more general suppression rules (disable policy / by source / by resource / by tag). ([docs.prismacloud.io][21]) |
| **Metadata captured with suppression** | `snyk ignore` supports `--reason` and `--expiry`; UI shows who ignored and allows editing/unignore; APIs expose `ignoreReasons` on issues. ([docs.snyk.io][17]) | Dismissal reason: `false positive`, `won't fix`, `used in tests`; optional comment. Dismissal requests for code scanning add requester/reviewer, timestamps, status. ([GitHub Docs][22]) | Ignores live in repo-local files (`.trivyignore*`) or Rego policies; VEX documents contribute status metadata (per CVE, per product). No central UI metadata by default. ([aquasecurity.github.io][19]) | Annotations carry VEX-aligned status plus explanatory text; RBAC role `vuln-annotator-editor` controls who can create/modify/delete them. ([docs.anchore.com][23]) | Suppressions include justification text; there is a dedicated API to retrieve suppression justifications by policy ID and query (auditable). ([pan.dev][24]) |
| **Scope & consistency** | Ignores are *local* to project/integration/org; ignoring in a Git repo project does not automatically ignore the same issue imported via CLI. Snyk Code ignore semantics differ from OSS/Container (no `.snyk`). ([Snyk][25]) | Dismissals attach to a specific alert (repo, branch baseline); PRs inherit baseline. Dependabot has repo-level config (`dependabot.yml`) and org-level alert configuration. ([GitHub Docs][7]) | Suppression is run-local: `.trivyignore` travels with source, policies live in config repos; VEX docs are attached per artifact or discovered via VEX Hub / registries. Reproducible but not centralized unless you build it. ([aquasecurity.github.io][19]) | Grype suppression is per scan & VEX document; Anchore Enterprise stores annotations centrally per artifact and exposes them consistently in UI/API and exported VEX. ([GitHub][20]) | Suppression rules can be global, per source, per resource, or tag-scoped; they affect console views and API results consistently when filters are applied. ([pan.dev][24]) |
| **VEX support (ingest + semantics)** | Snyk generates SBOMs but has no documented first-class VEX ingestion or export; VEX is referenced mostly at the SBOM/standards level, not as a product feature. ([Snyk][26]) | No native VEX semantics in alerts; GitHub consumes SARIF only. VEX can exist in repos or external systems but is not interpreted by GHAS. ([GitHub Docs][11]) | Trivy has **explicit VEX support**: supports OpenVEX, CycloneDX VEX, and CSAF VEX, using local files, VEX repositories, SBOM externalReferences, and OCI VEX attestations to filter results. ([Trivy][27]) | Grype has VEX-first behavior: `--vex` to ingest OpenVEX; by default `not_affected`/`fixed` go to an ignore set; `--show-suppressed` exposes them. Anchore Enterprise 5.22+ adds OpenVEX export and CycloneDX VEX export (5.23). ([GitHub][20]) | No public documentation of native VEX ingestion or export; prioritization is via policies/RQL rather than VEX semantics. |
| **Default handling of suppressed items** | Ignored issues are hidden by default in UI/CLI/IDE views to reduce noise; some tools like `snyk-to-html` will still show ignored Snyk Code issues. ([docs.snyk.io][28]) | Dismissed / auto-dismissed alerts are *not* shown by default (`is:open` filter); you must explicitly filter for closed / auto-dismissed alerts. ([GitHub Docs][29]) | When VEX is supplied, non-affected/fixed statuses are filtered out; suppressed entries are generally not shown unless you adjust filters/output. Some edge-cases exist around `.trivyignore.yaml` behavior. ([Trivy][27]) | Grype hides suppressed matches unless `--show-suppressed` is set; community discussions explicitly argue for “suppressed hidden by default” across all formats. ([artifacthub.io][30]) | Suppressed / excluded issues are hidden from normal risk views and searches and only visible via explicit filters or suppression APIs. ([pan.dev][24]) |
| **Known pain points** | Fragmented semantics: Snyk Code vs OSS/Container vs IaC handle ignores differently; ignores are not global across ingest types. ([docs.snyk.io][31]) | Dismissal is per-tool: Dependabot rules dont govern CodeQL and vice-versa; no VEX; you must build cross-tool policy on top. | Some rough edges reported around `.trivyignore.yaml` and SARIF vs exit-code behavior; VEX support is powerful but still labeled experimental in docs. ([GitHub][32]) | VEX support for certain source types (e.g., some directory + SBOM combos) has had bugs; suppressed entries disappear by default unless you remember `--show-suppressed`. ([GitHub][33]) | No VEX, and suppression semantics may diverge across CSPM/AppSec/Compute; complexity of RQL and multiple modules can make suppression strategy opaque without good governance. ([Palo Alto Networks][5]) |
---
## 3. Audit & export primitives
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Built-in UI exports** | Reporting UI lets you export reports as PDF and table data as CSV; you can also download CSV from several report views. ([docs.snyk.io][34]) | UI is mostly “view only”; some security overview exports are available, but reports are usually built via API or marketplace actions (e.g., PDF report GitHub Action). ([GitHub Docs][35]) | Aqua Platform provides CSV exports and API integrations for vulnerability reports; on-prem deployments can export “user policy data, vulnerability data and system settings data.” ([Aqua][36]) | SBOM/Vulnerability views have an **Export CSV** button; the Reports service aggregates via GraphQL into CSV/JSON from pre-built templates and dashboards. ([docs.anchore.com][37]) | Vulnerability Explorer and scan reports allow CSV export; code-build issues can be exported with filters as CSV from the AppSec UI. ([docs.prismacloud.io][16]) |
| **Machine-readable exports / APIs** | REST Issues API; Export API (GA) to create CSV exports via async jobs; SBOM CLI (`snyk sbom`) for CycloneDX/SPDX; audit log export for user actions. ([docs.snyk.io][38]) | SARIF input/output; REST & GraphQL APIs for code scanning & Dependabot; many third-party actions to transform alerts into PDFs/CSVs or send to other systems. ([GitHub Docs][11]) | Trivy outputs JSON, SARIF, CycloneDX, SPDX, SPDX-JSON, GitHub formats; these can be uploaded into GHAS or other platforms. Aqua exposes vulnerability data via API. ([Trivy][39]) | Grype outputs JSON, table, CycloneDX, SARIF, plus Go-template based CSV; Anchore Enterprise exposes APIs for vulnerabilities, policies, and reports. ([Chainguard Academy][4]) | CSPM/AppSec APIs: `vulnerabilities/search` (JSON) and `.../search/download` (GZIP CSV) for RQL queries; broader Prisma Cloud API for automation/integration. ([pan.dev][40]) |
| **VEX / “authoritative statement” export** | No native VEX export; at best you can export SBOMs and issues and post-process into VEX with external tooling. ([Snyk][26]) | None. Vendors can publish VEX separately, but GHAS doesnt emit VEX. | Trivy consumes VEX but does not itself author VEX; Aqua operates VEX Hub as a central repository of vendor VEX documents rather than as a generator. ([Trivy][27]) | Anchore Enterprise 5.22/5.23 is currently the most “productized” VEX exporter: OpenVEX and CycloneDX VEX including annotations, PURLs, metadata about the scanned image. ([docs.anchore.com][41]) | No VEX export; risk posture is expressed via internal policies, not standardized exploitability statements. |
| **Suppression / ignore audit** | Ignored issues can be exported by filtering for “Ignored” in Reporting and downloading CSV; APIs expose ignore reasons; audit log export records user actions such as ignoring issues. ([docs.snyk.io][42]) | Code scanning dismissal requests are full audit records (who requested, who approved, reason, timestamps). Dependabot dismissal comments & auto-dismissed alerts are queryable via GraphQL/REST and UI filters. ([GitHub Docs][43]) | Auditability is repo-driven: `.trivyignore`/VEX/rego live in version control; Aquas own reporting/APIs can include current vulnerability state but do not (publicly) expose a dedicated VEX change log. ([aquasecurity.github.io][19]) | Annotations are first-class objects, controlled via RBAC and exportable as OpenVEX/CycloneDX VEX; this effectively *is* an audit log of “why we suppressed or downgraded this CVE” over time. ([docs.anchore.com][23]) | Suppression justification APIs provide a structured record of why and where policies are suppressed; combined with CSV/API exports of vulns, this gives a workable audit trail for regulators. ([pan.dev][24]) |
---
## 4. What this suggests for StellaOps UX & data-model
### Patterns worth copying
1. **Data-flow & path-level “evidence” as the default detail view**
* Snyk Codes taint-flow UI and GitHubs “Show paths” for CodeQL alerts make a single issue *explain itself* without leaving the tool. ([docs.snyk.io][1])
* For StellaOps:
* For code: provide a path graph (source → sanitizers → sinks) with line-level jumps.
* For SBOM/containers: mirror Snyks Project Issue Paths & Grype/Syft by showing a dependency path or image-layer path for each CVE.
2. **VEX-first suppression semantics**
* Trivy and Grype treat VEX as the *canonical* suppression mechanism; statuses like `not_affected` / `fixed` hide findings by default, with CLI flags to show suppressed. ([Trivy][27])
* Anchore Enterprise adds a full annotation workflow and emits OpenVEX/CycloneDX VEX as the authoritative vendor statement. ([docs.anchore.com][23])
* For StellaOps: make VEX status the **single source of truth** for suppression across all modules, and always be able to reconstruct a proof tree: SBOM → vuln → VEX statement → policy decision.
3. **Rich suppression metadata with explicit justification & expiry**
* Snyk captures reason + expiry; GitHub uses structured reasons + free-form comment; Prisma provides a dedicated suppression-justification API. ([docs.snyk.io][17])
* For StellaOps: require a reason taxonomy + free-text + optional “proof link” (e.g., internal ticket, upstream vendor VEX) for any “Not Affected” or “Wont Fix,” and store that as part of the public proof spine.
4. **Strong export & API stories for regulators**
* Snyks Export API, Anchores Reports service, and Prismas RQL+CSV APIs give customers reliable machine-readable exports for audits and custom BI. ([updates.snyk.io][44])
* Anchores CycloneDX VEX export is the best current model for “signable, portable, regulator-friendly” proofs. ([Security Boulevard][45])
* For StellaOps:
* Treat CSV/JSON/SBOM/VEX exports as *first-class* features, not add-ons.
* Tie them to deterministic scan manifests and graph revision IDs (your “trust algebra” backbone) so an auditor can replay any historical report.
5. **Repo-local suppression files as “policy as code”**
* `.snyk`, `.trivyignore`, Rego policies, and VEX docs living alongside source are proven patterns for reproducible suppression. ([docs.snyk.io][46])
* For StellaOps: mirror this with a small set of declarative files (`stellaops.vexmap.yaml`, `trust-lattice.yaml`) that your engine and UI both honor.
### Patterns to deliberately avoid
1. **Fragmented ignore semantics by scan type**
* Snyks different behavior across Code vs OSS vs Container vs IaC (e.g., `.snyk` not honored for Snyk Code) is a recurring source of confusion. ([docs.snyk.io][31])
* For StellaOps: a single suppression model (VEX+policy) must apply consistently whether the evidence came from SAST, SBOM, container scan, or runtime telemetry.
2. **Making suppressed issues effectively invisible**
* Grype and GitHub both hide suppressed/dismissed issues by default and require extra flags/filters to see them. ([artifacthub.io][30])
* For StellaOps:
* Default UI for any artifact should show a small, always-visible “suppressed” counter with a click-through view.
* Every export format should have an option to include suppressed entries with their VEX status and reasoning.
3. **Lack of a standard “authoritative statement” artifact**
* Snyk, GitHub, Prisma Cloud all rely on internal notions of suppression and policy without emitting a standardized VEX or equivalent artifact. ([Snyk][26])
* For StellaOps: your “Proof-of-Integrity Graph” and VEX exports should be the primary way vendors and customers communicate risk, not just internal UI states.
4. **Over-reliance on informal text for serious decisions**
* Many tools lean heavily on free-form comments (GitHub dismissal comments, Snyk ignore reasons) without tying them to structured policies or verifiable upstream evidence. ([GitHub Docs][22])
* For StellaOps: keep free text, but anchor it in structured fields (VEX status, justification category, linked upstream VEX/SBOM, ticket ID) and make these queryable across the entire system.
If you want, next step can be a **StellaOps UX spec** that maps each of these rows to concrete screens and micro-interactions (e.g., “Finding details drawer,” “Suppression dialog,” “Export / attest dialog”) so your .NET/Angular team has something they can implement directly.
[1]: https://docs.snyk.io/scan-with-snyk/snyk-code/manage-code-vulnerabilities/breakdown-of-code-analysis?utm_source=chatgpt.com "Breakdown of Code analysis"
[2]: https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/about-code-scanning-alerts?utm_source=chatgpt.com "About code scanning alerts"
[3]: https://trivy.dev/docs/v0.56/scanner/misconfiguration/?utm_source=chatgpt.com "Misconfiguration Scanning"
[4]: https://edu.chainguard.dev/chainguard/chainguard-images/staying-secure/working-with-scanners/grype-tutorial/?utm_source=chatgpt.com "Using Grype to Scan Software Artifacts"
[5]: https://www.paloaltonetworks.com/prisma/cloud/cloud-code-security?utm_source=chatgpt.com "Cloud Code Security"
[6]: https://docs.snyk.io/snyk-api/api-endpoints-index-and-tips/project-issue-paths-api-endpoints?utm_source=chatgpt.com "Project issue paths API endpoints"
[7]: https://docs.github.com/en/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts?utm_source=chatgpt.com "Viewing and updating Dependabot alerts"
[8]: https://github.com/aquasecurity/trivy?utm_source=chatgpt.com "aquasecurity/trivy: Find vulnerabilities, misconfigurations, ..."
[9]: https://docs.prismacloud.io/en/compute-edition/32/admin-guide/vulnerability-management/scan-reports?utm_source=chatgpt.com "Vulnerability Scan Reports - Prisma Cloud Documentation"
[10]: https://docs.snyk.io/developer-tools/snyk-cli/commands/sbom?utm_source=chatgpt.com "SBOM"
[11]: https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning?utm_source=chatgpt.com "SARIF support for code scanning"
[12]: https://edu.chainguard.dev/chainguard/chainguard-images/staying-secure/working-with-scanners/trivy-tutorial/?utm_source=chatgpt.com "Using Trivy to Scan Software Artifacts"
[13]: https://docs.anchore.com/current/docs/?utm_source=chatgpt.com "Anchore Enterprise Documentation"
[14]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code?utm_source=chatgpt.com "Consistent Ignores for Snyk Code"
[15]: https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/assessing-code-scanning-alerts-for-your-repository?utm_source=chatgpt.com "Assessing code scanning alerts for your repository"
[16]: https://docs.prismacloud.io/en/enterprise-edition/content-collections/runtime-security/vulnerability-management/vulnerability-explorer?utm_source=chatgpt.com "Vulnerability Explorer - Prisma Cloud Documentation"
[17]: https://docs.snyk.io/developer-tools/snyk-cli/commands/ignore?utm_source=chatgpt.com "Ignore | Snyk User Docs"
[18]: https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/resolving-code-scanning-alerts?utm_source=chatgpt.com "Resolving code scanning alerts"
[19]: https://aquasecurity.github.io/trivy-operator/v0.13.2/docs/vulnerability-scanning/trivy/?utm_source=chatgpt.com "Trivy Scanner - Trivy Operator - Aqua Security"
[20]: https://github.com/anchore/grype?utm_source=chatgpt.com "anchore/grype: A vulnerability scanner for container ..."
[21]: https://docs.prismacloud.io/en/enterprise-edition/content-collections/application-security/risk-management/monitor-and-manage-code-build/suppress-code-issues?utm_source=chatgpt.com "Suppress Code Issues - Prisma Cloud Documentation"
[22]: https://docs.github.com/en/rest/code-scanning/code-scanning?utm_source=chatgpt.com "REST API endpoints for code scanning"
[23]: https://docs.anchore.com/current/docs/vulnerability_management/vuln_annotations/?utm_source=chatgpt.com "Vulnerability Annotations and VEX"
[24]: https://pan.dev/prisma-cloud/api/code/get-suppressions-justifications/?utm_source=chatgpt.com "Get Suppressions Justifications by Policy ID and Query ..."
[25]: https://snyk.io/blog/ignoring-vulnerabilities-with-snyk/?utm_source=chatgpt.com "Ignoring vulnerabilities with Snyk"
[26]: https://snyk.io/blog/advancing-sbom-standards-snyk-spdx/?utm_source=chatgpt.com "Advancing SBOM standards: Snyk and SPDX"
[27]: https://trivy.dev/docs/v0.50/supply-chain/vex/?utm_source=chatgpt.com "VEX"
[28]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues?utm_source=chatgpt.com "Ignore issues | Snyk User Docs"
[29]: https://docs.github.com/en/code-security/dependabot/dependabot-auto-triage-rules/managing-automatically-dismissed-alerts?utm_source=chatgpt.com "Managing automatically dismissed alerts - Dependabot"
[30]: https://artifacthub.io/packages/container/grype/grype?utm_source=chatgpt.com "grype latest · wagoodman@gmail.com/grype"
[31]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/exclude-files-and-ignore-issues-faqs?utm_source=chatgpt.com "Exclude files and ignore issues FAQs"
[32]: https://github.com/aquasecurity/trivy/discussions/7974?utm_source=chatgpt.com ".trivyignore.yaml not allow to ignore multiple vulnerabilities ..."
[33]: https://github.com/anchore/grype/issues/2471?utm_source=chatgpt.com "Support using VEX documents with directory scans and ..."
[34]: https://docs.snyk.io/manage-risk/reporting?utm_source=chatgpt.com "Reporting | Snyk User Docs"
[35]: https://docs.github.com/en/code-security/security-overview/filtering-alerts-in-security-overview?utm_source=chatgpt.com "Filtering alerts in security overview"
[36]: https://www.aquasec.com/blog/container-vulnerability-management-best-practices/?utm_source=chatgpt.com "Cloud Native Security Best Practices: Vulnerability Management"
[37]: https://docs.anchore.com/current/docs/sbom_management/?utm_source=chatgpt.com "SBOM Management"
[38]: https://docs.snyk.io/snyk-api/using-specific-snyk-apis/issues-list-issues-for-a-package?utm_source=chatgpt.com "Issues: List issues for a package"
[39]: https://trivy.dev/docs/latest/configuration/reporting/?utm_source=chatgpt.com "Reporting"
[40]: https://pan.dev/prisma-cloud/api/cspm/vulnerabilities-search-api/?utm_source=chatgpt.com "Get Vulnerabilities by RQL | Develop with Palo Alto Networks"
[41]: https://docs.anchore.com/current/docs/release_notes/enterprise/5220/?utm_source=chatgpt.com "Anchore Enterprise Release Notes - Version 5.22.0"
[42]: https://docs.snyk.io/manage-risk/reporting/available-snyk-reports?utm_source=chatgpt.com "Available Snyk reports | Snyk User Docs"
[43]: https://docs.github.com/en/enterprise-cloud%40latest/rest/code-scanning/alert-dismissal-requests?utm_source=chatgpt.com "REST API endpoints for code scanning alert dismissal ..."
[44]: https://updates.snyk.io/export-api-ga-release-321290/?utm_source=chatgpt.com "Export API GA Release"
[45]: https://securityboulevard.com/2025/11/anchore-enterprise-5-23-cyclonedx-vex-and-vdr-support/?utm_source=chatgpt.com "Anchore Enterprise 5.23: CycloneDX VEX and VDR Support"
[46]: https://docs.snyk.io/manage-risk/policies/the-.snyk-file?utm_source=chatgpt.com "The .snyk file | Snyk User Docs"
Matrix built. Ill keep it compact enough to scan quickly, but detailed enough that you can lift it straight into a Google Sheet / Confluence page.
---
## 1. Evidence & context: what a *single finding* looks like
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
| ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Code-level evidence** | Snyk Code shows a *Data flow* view (taint graph) from source → sink with step-by-step code lines in the UI and IDE. ([docs.snyk.io][1]) | Code scanning alerts show file/line and, for data-flow rules, a “how data moves through the code” view with **Show paths** for the full flow. ([GitHub Docs][2]) | Trivy is not a SAST engine; evidence is per-file / resource for vulnerabilities & misconfigurations (IaC, K8s, etc.), not data-flow graphs. ([Trivy][3]) | No SAST; evidence is package / image / SBOM level (CVE, package, version, location). Grype is focused on images/filesystems, not code flows. ([Chainguard Academy][4]) | AppSec module shows issues mapped to file & line and offers inline remediation/fix flows; surfaced in console and IDE plugins (JetBrains/VS Code). ([Palo Alto Networks][5]) |
| **Dependency / container evidence** | For OSS & containers, Snyk shows dependency paths and has a **project issue paths** API that returns the introduction chain for a vuln. ([docs.snyk.io][6]) | Dependabot alerts show vulnerable package, version, advisories, and affected functions to help decide if code actually uses them. ([GitHub Docs][7]) | Trivy shows image → layer → package → vuln with installed/fixed versions; same for repos & filesystems in JSON/SARIF. ([GitHub][8]) | Grype output lists artifact, package, version, location, severity; when paired with Syft SBOM, you get full component graph for images and other artifacts. ([Chainguard Academy][4]) | Prismas Vulnerability Explorer & scan reports show image/host, package, severity and compliance IDs for image and host scans. ([docs.prismacloud.io][9]) |
| **SBOM / supply-chain context** | `snyk sbom` generates CycloneDX and SPDX SBOMs for local projects; Snyk also supports SBOM export in enterprise tiers. ([docs.snyk.io][10]) | GitHub builds a dependency graph from manifests and ingests SARIF from external scanners; it is SBOM-adjacent but not an SBOM UI. ([GitHub Docs][11]) | Trivy can output SBOMs (CycloneDX, SPDX, SPDX-JSON) and Kubernetes “KBOM” views, and is often used as the SBOM generator. ([Chainguard Academy][12]) | Anchore Enterprise is explicitly “SBOM-powered”; SBOM management views let you navigate applications and export SBOM-centric vulnerability views. ([docs.anchore.com][13]) | Prisma Cloud is inventory-/RQL-centric; SBOMs are not a first-class UI artifact and there is no public doc for full SBOM navigation comparable to Anchore or Trivy. ([Palo Alto Networks][5]) |
| **Where the evidence appears** | Web UI, CLI, IDEs (VS Code, JetBrains) and PR checks. Ignores for Snyk Code are now “consistent” across UI/CLI/IDE (2025-11 EA). ([docs.snyk.io][14]) | Web UI (Security tab), PR Conversation tab for code scanning reviews, REST & GraphQL APIs, and SARIF imports from many scanners. ([GitHub Docs][15]) | Trivy: CLI / JSON / SARIF / CI integrations (GitHub Actions, etc.). Aqua Platform adds a CNAPP UI with risk-based vulnerability views. ([GitHub][8]) | Grype: CLI & JSON/SARIF outputs; Anchore Enterprise: browser UI (dashboards, SBOM views, reporting) plus REST/GraphQL APIs. ([Chainguard Academy][4]) | Prisma Cloud: web console (AppSec dashboards, Vulnerability Explorer), REST APIs, IDE plugins for JetBrains & VS Code. ([docs.prismacloud.io][16]) |
---
## 2. Suppression / ignore / VEX behavior
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Suppression primitives** | `.snyk` policy file for OSS & container & IaC; `snyk ignore` CLI; “Ignore” in web UI; Snyk Code uses UI/CLI/IDE ignores but *not* `.snyk`. ([docs.snyk.io][17]) | Code scanning and Dependabot alerts can be **dismissed** with reasons; Dependabot has auto-triage rules (auto-dismiss/snooze). ([GitHub Docs][18]) | Trivy: `.trivyignore` / `.trivyignore.yaml` lists vuln IDs; `--ignore-policy` for Rego-based filtering; severity filters. ([aquasecurity.github.io][19]) | Grype: VEX-aware filtering via `--vex` and ignore rules; Anchore Enterprise: UI-driven vulnerability annotations that act as a structured “suppress or re-classify” layer. ([GitHub][20]) | AppSec: “Suppress Code Issues” (per-issue or globally) and more general suppression rules (disable policy / by source / by resource / by tag). ([docs.prismacloud.io][21]) |
| **Metadata captured with suppression** | `snyk ignore` supports `--reason` and `--expiry`; UI shows who ignored and allows editing/unignore; APIs expose `ignoreReasons` on issues. ([docs.snyk.io][17]) | Dismissal reason: `false positive`, `won't fix`, `used in tests`; optional comment. Dismissal requests for code scanning add requester/reviewer, timestamps, status. ([GitHub Docs][22]) | Ignores live in repo-local files (`.trivyignore*`) or Rego policies; VEX documents contribute status metadata (per CVE, per product). No central UI metadata by default. ([aquasecurity.github.io][19]) | Annotations carry VEX-aligned status plus explanatory text; RBAC role `vuln-annotator-editor` controls who can create/modify/delete them. ([docs.anchore.com][23]) | Suppressions include justification text; there is a dedicated API to retrieve suppression justifications by policy ID and query (auditable). ([pan.dev][24]) |
| **Scope & consistency** | Ignores are *local* to project/integration/org; ignoring in a Git repo project does not automatically ignore the same issue imported via CLI. Snyk Code ignore semantics differ from OSS/Container (no `.snyk`). ([Snyk][25]) | Dismissals attach to a specific alert (repo, branch baseline); PRs inherit baseline. Dependabot has repo-level config (`dependabot.yml`) and org-level alert configuration. ([GitHub Docs][7]) | Suppression is run-local: `.trivyignore` travels with source, policies live in config repos; VEX docs are attached per artifact or discovered via VEX Hub / registries. Reproducible but not centralized unless you build it. ([aquasecurity.github.io][19]) | Grype suppression is per scan & VEX document; Anchore Enterprise stores annotations centrally per artifact and exposes them consistently in UI/API and exported VEX. ([GitHub][20]) | Suppression rules can be global, per source, per resource, or tag-scoped; they affect console views and API results consistently when filters are applied. ([pan.dev][24]) |
| **VEX support (ingest + semantics)** | Snyk generates SBOMs but has no documented first-class VEX ingestion or export; VEX is referenced mostly at the SBOM/standards level, not as a product feature. ([Snyk][26]) | No native VEX semantics in alerts; GitHub consumes SARIF only. VEX can exist in repos or external systems but is not interpreted by GHAS. ([GitHub Docs][11]) | Trivy has **explicit VEX support**: supports OpenVEX, CycloneDX VEX, and CSAF VEX, using local files, VEX repositories, SBOM externalReferences, and OCI VEX attestations to filter results. ([Trivy][27]) | Grype has VEX-first behavior: `--vex` to ingest OpenVEX; by default `not_affected`/`fixed` go to an ignore set; `--show-suppressed` exposes them. Anchore Enterprise 5.22+ adds OpenVEX export and CycloneDX VEX export (5.23). ([GitHub][20]) | No public documentation of native VEX ingestion or export; prioritization is via policies/RQL rather than VEX semantics. |
| **Default handling of suppressed items** | Ignored issues are hidden by default in UI/CLI/IDE views to reduce noise; some tools like `snyk-to-html` will still show ignored Snyk Code issues. ([docs.snyk.io][28]) | Dismissed / auto-dismissed alerts are *not* shown by default (`is:open` filter); you must explicitly filter for closed / auto-dismissed alerts. ([GitHub Docs][29]) | When VEX is supplied, non-affected/fixed statuses are filtered out; suppressed entries are generally not shown unless you adjust filters/output. Some edge-cases exist around `.trivyignore.yaml` behavior. ([Trivy][27]) | Grype hides suppressed matches unless `--show-suppressed` is set; community discussions explicitly argue for “suppressed hidden by default” across all formats. ([artifacthub.io][30]) | Suppressed / excluded issues are hidden from normal risk views and searches and only visible via explicit filters or suppression APIs. ([pan.dev][24]) |
| **Known pain points** | Fragmented semantics: Snyk Code vs OSS/Container vs IaC handle ignores differently; ignores are not global across ingest types. ([docs.snyk.io][31]) | Dismissal is per-tool: Dependabot rules dont govern CodeQL and vice-versa; no VEX; you must build cross-tool policy on top. | Some rough edges reported around `.trivyignore.yaml` and SARIF vs exit-code behavior; VEX support is powerful but still labeled experimental in docs. ([GitHub][32]) | VEX support for certain source types (e.g., some directory + SBOM combos) has had bugs; suppressed entries disappear by default unless you remember `--show-suppressed`. ([GitHub][33]) | No VEX, and suppression semantics may diverge across CSPM/AppSec/Compute; complexity of RQL and multiple modules can make suppression strategy opaque without good governance. ([Palo Alto Networks][5]) |
---
## 3. Audit & export primitives
| Dimension | Snyk | GitHub Advanced Security | Aqua / Trivy | Anchore / Grype (Anchore Enterprise) | Prisma Cloud |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Built-in UI exports** | Reporting UI lets you export reports as PDF and table data as CSV; you can also download CSV from several report views. ([docs.snyk.io][34]) | UI is mostly “view only”; some security overview exports are available, but reports are usually built via API or marketplace actions (e.g., PDF report GitHub Action). ([GitHub Docs][35]) | Aqua Platform provides CSV exports and API integrations for vulnerability reports; on-prem deployments can export “user policy data, vulnerability data and system settings data.” ([Aqua][36]) | SBOM/Vulnerability views have an **Export CSV** button; the Reports service aggregates via GraphQL into CSV/JSON from pre-built templates and dashboards. ([docs.anchore.com][37]) | Vulnerability Explorer and scan reports allow CSV export; code-build issues can be exported with filters as CSV from the AppSec UI. ([docs.prismacloud.io][16]) |
| **Machine-readable exports / APIs** | REST Issues API; Export API (GA) to create CSV exports via async jobs; SBOM CLI (`snyk sbom`) for CycloneDX/SPDX; audit log export for user actions. ([docs.snyk.io][38]) | SARIF input/output; REST & GraphQL APIs for code scanning & Dependabot; many third-party actions to transform alerts into PDFs/CSVs or send to other systems. ([GitHub Docs][11]) | Trivy outputs JSON, SARIF, CycloneDX, SPDX, SPDX-JSON, GitHub formats; these can be uploaded into GHAS or other platforms. Aqua exposes vulnerability data via API. ([Trivy][39]) | Grype outputs JSON, table, CycloneDX, SARIF, plus Go-template based CSV; Anchore Enterprise exposes APIs for vulnerabilities, policies, and reports. ([Chainguard Academy][4]) | CSPM/AppSec APIs: `vulnerabilities/search` (JSON) and `.../search/download` (GZIP CSV) for RQL queries; broader Prisma Cloud API for automation/integration. ([pan.dev][40]) |
| **VEX / “authoritative statement” export** | No native VEX export; at best you can export SBOMs and issues and post-process into VEX with external tooling. ([Snyk][26]) | None. Vendors can publish VEX separately, but GHAS doesnt emit VEX. | Trivy consumes VEX but does not itself author VEX; Aqua operates VEX Hub as a central repository of vendor VEX documents rather than as a generator. ([Trivy][27]) | Anchore Enterprise 5.22/5.23 is currently the most “productized” VEX exporter: OpenVEX and CycloneDX VEX including annotations, PURLs, metadata about the scanned image. ([docs.anchore.com][41]) | No VEX export; risk posture is expressed via internal policies, not standardized exploitability statements. |
| **Suppression / ignore audit** | Ignored issues can be exported by filtering for “Ignored” in Reporting and downloading CSV; APIs expose ignore reasons; audit log export records user actions such as ignoring issues. ([docs.snyk.io][42]) | Code scanning dismissal requests are full audit records (who requested, who approved, reason, timestamps). Dependabot dismissal comments & auto-dismissed alerts are queryable via GraphQL/REST and UI filters. ([GitHub Docs][43]) | Auditability is repo-driven: `.trivyignore`/VEX/rego live in version control; Aquas own reporting/APIs can include current vulnerability state but do not (publicly) expose a dedicated VEX change log. ([aquasecurity.github.io][19]) | Annotations are first-class objects, controlled via RBAC and exportable as OpenVEX/CycloneDX VEX; this effectively *is* an audit log of “why we suppressed or downgraded this CVE” over time. ([docs.anchore.com][23]) | Suppression justification APIs provide a structured record of why and where policies are suppressed; combined with CSV/API exports of vulns, this gives a workable audit trail for regulators. ([pan.dev][24]) |
---
## 4. What this suggests for StellaOps UX & data-model
### Patterns worth copying
1. **Data-flow & path-level “evidence” as the default detail view**
* Snyk Codes taint-flow UI and GitHubs “Show paths” for CodeQL alerts make a single issue *explain itself* without leaving the tool. ([docs.snyk.io][1])
* For StellaOps:
* For code: provide a path graph (source → sanitizers → sinks) with line-level jumps.
* For SBOM/containers: mirror Snyks Project Issue Paths & Grype/Syft by showing a dependency path or image-layer path for each CVE.
2. **VEX-first suppression semantics**
* Trivy and Grype treat VEX as the *canonical* suppression mechanism; statuses like `not_affected` / `fixed` hide findings by default, with CLI flags to show suppressed. ([Trivy][27])
* Anchore Enterprise adds a full annotation workflow and emits OpenVEX/CycloneDX VEX as the authoritative vendor statement. ([docs.anchore.com][23])
* For StellaOps: make VEX status the **single source of truth** for suppression across all modules, and always be able to reconstruct a proof tree: SBOM → vuln → VEX statement → policy decision.
3. **Rich suppression metadata with explicit justification & expiry**
* Snyk captures reason + expiry; GitHub uses structured reasons + free-form comment; Prisma provides a dedicated suppression-justification API. ([docs.snyk.io][17])
* For StellaOps: require a reason taxonomy + free-text + optional “proof link” (e.g., internal ticket, upstream vendor VEX) for any “Not Affected” or “Wont Fix,” and store that as part of the public proof spine.
4. **Strong export & API stories for regulators**
* Snyks Export API, Anchores Reports service, and Prismas RQL+CSV APIs give customers reliable machine-readable exports for audits and custom BI. ([updates.snyk.io][44])
* Anchores CycloneDX VEX export is the best current model for “signable, portable, regulator-friendly” proofs. ([Security Boulevard][45])
* For StellaOps:
* Treat CSV/JSON/SBOM/VEX exports as *first-class* features, not add-ons.
* Tie them to deterministic scan manifests and graph revision IDs (your “trust algebra” backbone) so an auditor can replay any historical report.
5. **Repo-local suppression files as “policy as code”**
* `.snyk`, `.trivyignore`, Rego policies, and VEX docs living alongside source are proven patterns for reproducible suppression. ([docs.snyk.io][46])
* For StellaOps: mirror this with a small set of declarative files (`stellaops.vexmap.yaml`, `trust-lattice.yaml`) that your engine and UI both honor.
### Patterns to deliberately avoid
1. **Fragmented ignore semantics by scan type**
* Snyks different behavior across Code vs OSS vs Container vs IaC (e.g., `.snyk` not honored for Snyk Code) is a recurring source of confusion. ([docs.snyk.io][31])
* For StellaOps: a single suppression model (VEX+policy) must apply consistently whether the evidence came from SAST, SBOM, container scan, or runtime telemetry.
2. **Making suppressed issues effectively invisible**
* Grype and GitHub both hide suppressed/dismissed issues by default and require extra flags/filters to see them. ([artifacthub.io][30])
* For StellaOps:
* Default UI for any artifact should show a small, always-visible “suppressed” counter with a click-through view.
* Every export format should have an option to include suppressed entries with their VEX status and reasoning.
3. **Lack of a standard “authoritative statement” artifact**
* Snyk, GitHub, Prisma Cloud all rely on internal notions of suppression and policy without emitting a standardized VEX or equivalent artifact. ([Snyk][26])
* For StellaOps: your “Proof-of-Integrity Graph” and VEX exports should be the primary way vendors and customers communicate risk, not just internal UI states.
4. **Over-reliance on informal text for serious decisions**
* Many tools lean heavily on free-form comments (GitHub dismissal comments, Snyk ignore reasons) without tying them to structured policies or verifiable upstream evidence. ([GitHub Docs][22])
* For StellaOps: keep free text, but anchor it in structured fields (VEX status, justification category, linked upstream VEX/SBOM, ticket ID) and make these queryable across the entire system.
If you want, next step can be a **StellaOps UX spec** that maps each of these rows to concrete screens and micro-interactions (e.g., “Finding details drawer,” “Suppression dialog,” “Export / attest dialog”) so your .NET/Angular team has something they can implement directly.
[1]: https://docs.snyk.io/scan-with-snyk/snyk-code/manage-code-vulnerabilities/breakdown-of-code-analysis?utm_source=chatgpt.com "Breakdown of Code analysis"
[2]: https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/about-code-scanning-alerts?utm_source=chatgpt.com "About code scanning alerts"
[3]: https://trivy.dev/docs/v0.56/scanner/misconfiguration/?utm_source=chatgpt.com "Misconfiguration Scanning"
[4]: https://edu.chainguard.dev/chainguard/chainguard-images/staying-secure/working-with-scanners/grype-tutorial/?utm_source=chatgpt.com "Using Grype to Scan Software Artifacts"
[5]: https://www.paloaltonetworks.com/prisma/cloud/cloud-code-security?utm_source=chatgpt.com "Cloud Code Security"
[6]: https://docs.snyk.io/snyk-api/api-endpoints-index-and-tips/project-issue-paths-api-endpoints?utm_source=chatgpt.com "Project issue paths API endpoints"
[7]: https://docs.github.com/en/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts?utm_source=chatgpt.com "Viewing and updating Dependabot alerts"
[8]: https://github.com/aquasecurity/trivy?utm_source=chatgpt.com "aquasecurity/trivy: Find vulnerabilities, misconfigurations, ..."
[9]: https://docs.prismacloud.io/en/compute-edition/32/admin-guide/vulnerability-management/scan-reports?utm_source=chatgpt.com "Vulnerability Scan Reports - Prisma Cloud Documentation"
[10]: https://docs.snyk.io/developer-tools/snyk-cli/commands/sbom?utm_source=chatgpt.com "SBOM"
[11]: https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning?utm_source=chatgpt.com "SARIF support for code scanning"
[12]: https://edu.chainguard.dev/chainguard/chainguard-images/staying-secure/working-with-scanners/trivy-tutorial/?utm_source=chatgpt.com "Using Trivy to Scan Software Artifacts"
[13]: https://docs.anchore.com/current/docs/?utm_source=chatgpt.com "Anchore Enterprise Documentation"
[14]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/consistent-ignores-for-snyk-code?utm_source=chatgpt.com "Consistent Ignores for Snyk Code"
[15]: https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/assessing-code-scanning-alerts-for-your-repository?utm_source=chatgpt.com "Assessing code scanning alerts for your repository"
[16]: https://docs.prismacloud.io/en/enterprise-edition/content-collections/runtime-security/vulnerability-management/vulnerability-explorer?utm_source=chatgpt.com "Vulnerability Explorer - Prisma Cloud Documentation"
[17]: https://docs.snyk.io/developer-tools/snyk-cli/commands/ignore?utm_source=chatgpt.com "Ignore | Snyk User Docs"
[18]: https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/resolving-code-scanning-alerts?utm_source=chatgpt.com "Resolving code scanning alerts"
[19]: https://aquasecurity.github.io/trivy-operator/v0.13.2/docs/vulnerability-scanning/trivy/?utm_source=chatgpt.com "Trivy Scanner - Trivy Operator - Aqua Security"
[20]: https://github.com/anchore/grype?utm_source=chatgpt.com "anchore/grype: A vulnerability scanner for container ..."
[21]: https://docs.prismacloud.io/en/enterprise-edition/content-collections/application-security/risk-management/monitor-and-manage-code-build/suppress-code-issues?utm_source=chatgpt.com "Suppress Code Issues - Prisma Cloud Documentation"
[22]: https://docs.github.com/en/rest/code-scanning/code-scanning?utm_source=chatgpt.com "REST API endpoints for code scanning"
[23]: https://docs.anchore.com/current/docs/vulnerability_management/vuln_annotations/?utm_source=chatgpt.com "Vulnerability Annotations and VEX"
[24]: https://pan.dev/prisma-cloud/api/code/get-suppressions-justifications/?utm_source=chatgpt.com "Get Suppressions Justifications by Policy ID and Query ..."
[25]: https://snyk.io/blog/ignoring-vulnerabilities-with-snyk/?utm_source=chatgpt.com "Ignoring vulnerabilities with Snyk"
[26]: https://snyk.io/blog/advancing-sbom-standards-snyk-spdx/?utm_source=chatgpt.com "Advancing SBOM standards: Snyk and SPDX"
[27]: https://trivy.dev/docs/v0.50/supply-chain/vex/?utm_source=chatgpt.com "VEX"
[28]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues?utm_source=chatgpt.com "Ignore issues | Snyk User Docs"
[29]: https://docs.github.com/en/code-security/dependabot/dependabot-auto-triage-rules/managing-automatically-dismissed-alerts?utm_source=chatgpt.com "Managing automatically dismissed alerts - Dependabot"
[30]: https://artifacthub.io/packages/container/grype/grype?utm_source=chatgpt.com "grype latest · wagoodman@gmail.com/grype"
[31]: https://docs.snyk.io/manage-risk/prioritize-issues-for-fixing/ignore-issues/exclude-files-and-ignore-issues-faqs?utm_source=chatgpt.com "Exclude files and ignore issues FAQs"
[32]: https://github.com/aquasecurity/trivy/discussions/7974?utm_source=chatgpt.com ".trivyignore.yaml not allow to ignore multiple vulnerabilities ..."
[33]: https://github.com/anchore/grype/issues/2471?utm_source=chatgpt.com "Support using VEX documents with directory scans and ..."
[34]: https://docs.snyk.io/manage-risk/reporting?utm_source=chatgpt.com "Reporting | Snyk User Docs"
[35]: https://docs.github.com/en/code-security/security-overview/filtering-alerts-in-security-overview?utm_source=chatgpt.com "Filtering alerts in security overview"
[36]: https://www.aquasec.com/blog/container-vulnerability-management-best-practices/?utm_source=chatgpt.com "Cloud Native Security Best Practices: Vulnerability Management"
[37]: https://docs.anchore.com/current/docs/sbom_management/?utm_source=chatgpt.com "SBOM Management"
[38]: https://docs.snyk.io/snyk-api/using-specific-snyk-apis/issues-list-issues-for-a-package?utm_source=chatgpt.com "Issues: List issues for a package"
[39]: https://trivy.dev/docs/latest/configuration/reporting/?utm_source=chatgpt.com "Reporting"
[40]: https://pan.dev/prisma-cloud/api/cspm/vulnerabilities-search-api/?utm_source=chatgpt.com "Get Vulnerabilities by RQL | Develop with Palo Alto Networks"
[41]: https://docs.anchore.com/current/docs/release_notes/enterprise/5220/?utm_source=chatgpt.com "Anchore Enterprise Release Notes - Version 5.22.0"
[42]: https://docs.snyk.io/manage-risk/reporting/available-snyk-reports?utm_source=chatgpt.com "Available Snyk reports | Snyk User Docs"
[43]: https://docs.github.com/en/enterprise-cloud%40latest/rest/code-scanning/alert-dismissal-requests?utm_source=chatgpt.com "REST API endpoints for code scanning alert dismissal ..."
[44]: https://updates.snyk.io/export-api-ga-release-321290/?utm_source=chatgpt.com "Export API GA Release"
[45]: https://securityboulevard.com/2025/11/anchore-enterprise-5-23-cyclonedx-vex-and-vdr-support/?utm_source=chatgpt.com "Anchore Enterprise 5.23: CycloneDX VEX and VDR Support"
[46]: https://docs.snyk.io/manage-risk/policies/the-.snyk-file?utm_source=chatgpt.com "The .snyk file | Snyk User Docs"
Ill treat this as a concrete UX blueprint your .NET/Angular team can build against, centered on three pillars:
1. Evidence views (how a single finding “explains itself”)
2. Suppression/VEX (how risk decisions are captured)
3. Audit/export (how you prove those decisions later)
---
## 1. Design principles specific to StellaOps
1. **Graph-first:** Every view is anchored to a graph snapshot ID from your trust algebra / proof engine. Users always know “which build / which graph revision” theyre looking at.
2. **Single suppression model:** One suppression semantics layer (VEX + policy) across code, SBOM, containers, and runtime.
3. **Evidence before opinion:** Detail views always show raw evidence (paths, SBOM lines, runtime traces) before risk ratings, policies, or comments.
4. **Audit-ready by default:** Any action that changes risk posture automatically leaves a machine-readable trail that can be exported.
---
## 2. Core information architecture
Primary entities in the UX (mirroring your backend):
* **Organization / Workspace**
* **Application / Service**
* **Artifact**
* Build (commit, tag, CI run)
* Container image
* Binary / package
* SBOM document
* **Scan Result**
* Scanner type (SAST, SCA, container, SBOM-only, IaC, runtime)
* Graph snapshot ID
* **Finding**
* Vulnerability (CVE, GHSA, etc.)
* Misconfiguration / policy violation
* Supply-chain anomaly
* **Evidence**
* Code path(s)
* Dependency path(s)
* SBOM node(s)
* Runtime event(s)
* **VEX Statement**
* Status (`affected`, `not_affected`, `fixed`, `under_investigation`, etc.)
* Justification (standardized + free text)
* **Suppression Decision**
* “Suppressed by VEX”, “De-prioritized by policy”, “Wont fix”, etc.
* **Export Job / Proof Bundle**
* **Audit Event**
* Who, what, when, against which graph snapshot
The UI should surface these without drowning the user in jargon: names can be friendlier but map cleanly to this model.
---
## 3. UX spec by primary flows
### 3.1 Landing: Inventory & posture overview
**Screen: “Inventory & Risk Overview”**
Purpose: Secure default entry point for security engineers and auditors.
Layout:
* **Header bar**
* Org selector
* Global search (by application, artifact, CVE, VEX ID, SBOM component)
* “Exports & Proofs” shortcut
* User menu
* **Left nav (primary)**
* Inventory
* Findings
* VEX & Policies
* Exports & Proofs
* Settings
* **Main content: 3 panels**
1. **Applications list**
* Columns: Name, Owner, #Artifacts, Open findings, Suppressed findings, Last build, Risk score.
* Row click → Application view.
2. **Top risks**
* Cards: “Critical vulns”, “Unsigned artifacts”, “Unknown SBOM coverage”, each showing counts and a “View findings” link (pre-filtered).
3. **Compliance viewpoint**
* Tabs: “Operational”, “Regulatory”, “Attestations”.
* Simple status indicators per framework (e.g., SLSA level, NIST SSDF coverage) if you support that.
Micro-interactions:
* Clicking any numeric count (e.g., “12 suppressed”) opens a pre-filtered Findings list.
* Hover tooltip on risk counts shows breakdown by source (SAST vs SBOM vs runtime).
---
### 3.2 Application & artifact detail: evidence-centric view
**Screen: “Application detail”**
Purpose: Navigate from high level risk to specific artifacts and findings.
Layout:
* Tabs: Overview | Artifacts | Findings | SBOM graph | History
**Overview tab:**
* Top: Application summary (owners, repos, deployment targets).
* Middle: Tiles for “Latest build”, “Prod artifacts”, “SBOM coverage”.
* Bottom: “Recent decisions” timeline (suppression, VEX updates, exports).
**Artifacts tab:**
* Table with:
* Artifact type (image, binary, SBOM-only)
* Identifier (tag/digest, CI job ID)
* Environment (dev, staging, prod)
* Graph snapshot ID
* Findings (open / suppressed chips)
* Last scanned
Selecting a row opens **Artifact detail**.
---
### 3.3 Artifact detail & Finding details drawer
**Screen: “Artifact detail”**
Layout:
* Header:
* Artifact identity (name, version/tag, digest)
* Environment badges
* Graph snapshot ID with “Copy” control
* Primary actions: “Download SBOM”, “Export proof bundle”
* Sub-tabs:
* Findings
* Evidence graph
* SBOM tree
* History
**Findings sub-tab**
* Filters on left:
* Severity, status (Open / Suppressed / Only suppressed), source (SAST/SBOM/container/runtime), VEX status, CWE/CVE.
* Table in center:
* Columns: Severity, Type, ID (CVE-XXXX-XXXX), Component/Code location, Status (Open/Suppressed), VEX status, Last updated.
* Row click opens a **Finding details drawer** sliding from the right.
**Finding details drawer (core evidence UX)**
This is the primary place where “evidence explains itself.”
Structure:
1. **Header area**
* Title: “CVE-2023-XXXX in `openssl`
* Badges: severity, status (Open / Suppressed by VEX), VEX status (`not_affected`, `fixed`, etc.)
* Scope indicator: where this finding appears (e.g., “1 artifact (this), 3 environments, 2 images”).
2. **Tabs within drawer**
* **Evidence** (default)
* Section: “Where this comes from”
* Scanner source, scan timestamp, graph snapshot ID.
* Section: “Code path” (for SAST)
* A vertical list of steps: `source``propagation``sink`.
* Clicking a step shows code snippet with line highlighting.
* “Open in Git” and “Open in IDE (deeplink)” actions.
* Section: “Dependency path” (for SCA / SBOM)
* Path view: `app -> module -> transitive dependency -> vulnerable package`.
* Option to switch between “tree view” and “collapsed chain”.
* Section: “Runtime signals” (if available)
* Call-site frequency, exploit attempts, telemetry tags.
* **Impact & reach**
* A small graph panel: how many artifacts, environments, and applications share this finding.
* Link: “View all affected artifacts” → filtered Findings view.
* **VEX & decisions**
* Shows current VEX statements attached:
* Table: Status, Justification (standardized), Source (vendor vs internal), Effective scope (artifact / app / org), Last changed by.
* Shows local suppression decisions beyond VEX (e.g., “De-prioritized due to compensating controls”).
* Primary action: “Update status / Add VEX decision”.
* **History**
* Timeline of events for this finding:
* Detected
* VEX attached/updated
* Suppression added/edited
* Exported in bundles (with links)
* Each item shows user, timestamp, and delta.
Micro-interactions:
* The drawer should support deep-linking: URL reflects `artifactId + findingId + snapshotId`.
* Keyboard: `Esc` closes drawer, `←` / `→` cycles findings in the table.
---
## 4. Suppression & VEX UX
Goal: one consistent model across all scan types, anchored in VEX semantics.
### 4.1 “Update status / Add VEX decision” dialog
Entry points:
* From Finding details drawer > “VEX & decisions” tab > primary button.
* Bulk selection from Findings table > “Update status”.
Dialog steps (single modal with progressive disclosure):
1. **Select decision type**
Radio options:
* “System is affected”
* Sub-options: `under_investigation`, `affected_no_fix_available`, `affected_fix_available`.
* “System is *not* affected”
* Sub-options (justification): `vulnerable_code_not_present`, `vulnerable_code_not_in_execute_path`, `vulnerable_configuration_not_present`, `inline_mitigation_applied`, `other`.
* “Fixed”
* Sub-options: `fixed_in_this_version`, `fixed_in_downstream`, `fixed_by_vendor`.
* “Wont fix / accepted risk”
* Sub-options: `business_acceptance`, `low_likelihood`, `temporary_exception`.
2. **Scope definition**
Checkboxes + selectors:
* Scope:
* [x] This artifact only
* [ ] All artifacts of this application
* [ ] All artifacts in this org with the same component & version
* For each, display a short estimate: “This will apply to 3 artifacts (click to preview).”
3. **Metadata**
* Required:
* Justification category (if not chosen above).
* Free-text “Reason / supporting evidence” (min length e.g., 20 characters).
* Optional:
* Expiry date (for temporary exceptions).
* Link to ticket / document (URL).
* Attach external VEX file ID or reference (if youve ingested vendor VEX).
4. **Output preview**
A read-only JSON-like preview of the VEX statement(s) to be generated, with a friendly label: “These statements will be added to the proof graph for snapshot XYZ.”
This makes the model transparent to power users.
On submit:
* Show a small toast: “Status updated · VEX statement anchored to snapshot [ID] · Undo” (undo limited to a short window).
* The Finding row and drawer update immediately (status badges, history timeline).
### 4.2 Bulk suppression & policy overlay
**Screen: “VEX & Policies”**
Tabs:
1. **VEX statements**
* Table: VEX ID, CVE/ID, Status, Scope, Created by, Last updated, Source (vendor/internal).
* Filters: status, scope, target (component, application, artifact).
* Bulk actions: Export VEX (OpenVEX / CycloneDX VEX), disable / supersede.
2. **Policies**
* Declarative rules like: “Treat `vulnerable_code_not_present` from vendor X as authoritative” or “Do not auto-suppress based on `inline_mitigation_applied` without internal confirmation.”
* This expresses how raw VEX translates into “suppressed” vs “needs review” in the UI.
UX pattern:
* Each VEX row includes a small indicator: `S` (suppresses findings under current policy) or `R` (requires review).
* Clicking a row opens a side drawer with:
* Statements content (normalized).
* Affected findings count.
* Policy evaluation result (“This statement currently suppresses 47 findings”).
---
## 5. Findings list: global “inbox” for risk
**Screen: “Findings”**
This is the cross-application queue, similar to Snyks project list + GitHubs security tab, but with VEX semantics.
Layout:
* Filters on the left:
* Application / artifact
* Severity
* Status (Open / Suppressed / Only suppressed / Needs review)
* VEX status
* Source (SAST, SBOM, container, runtime)
* Table in center:
* Columns: Severity, ID, Application, Artifact, Status, VEX status, “Decision owner” (user or team), Age.
* Top bar:
* “Assign to…” for workflow
* “Update status / Add VEX decision” for bulk
* “Export current view” (CSV/JSON)
Micro-interactions:
* “Status” column clearly distinguishes:
* Open (no VEX)
* Open (VEX says `affected`)
* Suppressed (VEX says `not_affected` / `fixed`)
* Suppressed (policy exception: “Wont fix”)
* Hover on “Suppressed” shows a tooltip with the justification and who made the decision.
---
## 6. Audit & export / Proof bundles
### 6.1 Exports list
**Screen: “Exports & Proofs”**
Purpose: centralized, auditable place for generating and revisiting proofs.
Layout:
* Top actions:
* “New export / proof bundle”
* Filters: type (CSV, JSON, SBOM, VEX, composite bundle), created by, status.
* Table:
* Name / description
* Type (e.g., “OpenVEX for app payments”, “Proof bundle for prod rollout 2025-03-01”)
* Scope (org / app / artifact / snapshot range)
* Includes suppressed? (Yes/No)
* Status (Complete / Failed)
* Created by, Created at
* Download button
### 6.2 “New export / proof bundle” flow
1. **What do you need?**
Choices:
* SBOM export (CycloneDX/SPDX)
* VEX export (OpenVEX / CycloneDX VEX)
* Findings export (CSV / JSON)
* Proof bundle (zip containing SBOM + VEX + findings + manifest)
2. **Scope**
* Radio:
* A single artifact (picker)
* All artifacts of an application (picker)
* Entire org, limited by:
* Time window (from..to)
* Environments (prod only / all)
* Optional: choose graph snapshot(s) (latest vs explicit ID).
3. **Options**
* Include suppressed findings:
* [x] Yes, include them, with reasons
* [ ] No, only unresolved
* Mask sensitive fields? (e.g., repository URLs)
* Include audit log excerpt:
* [x] VEX & suppression decisions
* [ ] All user actions
4. **Review & create**
* Show a summary:
* N artifacts, M findings, K VEX statements.
* Button: “Create export”.
Once complete:
* Row in the table is updated with a download button.
* Clicking a row opens an **Export detail drawer**:
* Manifest preview (JSON-like).
* Link to the associated graph snapshot IDs.
* Embedded notice that “Regulators can verify this bundle by validating manifest signature and graph snapshot hash” (if you sign them).
Micro-interaction:
* For artifacts and applications, the Artifact detail and Application detail pages should have contextual buttons:
* “Export SBOM”
* “Export VEX”
* “Download proof bundle”
These open the same export dialog pre-populated with the relevant scope.
---
## 7. History & audit trail UX
Audit must be first-class, not buried.
**Pattern: Timeline component**
Used in:
* Application > History
* Artifact > History
* Finding > History
* VEX statement > History
* Export > Details
Timeline item shape:
* Icon (type of action: scan, decision, export)
* Title (short, human readable)
* Metadata:
* User
* Timestamp
* Graph snapshot ID
* Detail:
* Before/after summary (e.g., “VEX status: `affected``not_affected`”)
Filters:
* By actor (user / system)
* By action type (scan, VEX change, suppression, export, policy change)
* By time range
Long-term: this timeline can become your “forensic report” generator.
---
## 8. Role-based slices
You can keep a single UX codebase but offer different “home” experiences per role.
1. **Security engineer**
* Default landing: “Findings” with open & needs-review filters.
* Emphasis on Evidence & VEX decisions.
* Quick actions: create VEX, adjust policies.
2. **Developer**
* Default landing: “My assignments” (subset of Findings where theyre the owner).
* Simplified VEX dialog:
* Emphasis on “Fixed in commit X” and “Provide more evidence” rather than full-blown VEX authoring.
* Tight links to repo/IDE.
3. **Auditor / Compliance**
* Default landing: “Exports & Proofs”.
* Views oriented around applications and time windows, not individual findings.
* Read-only access to VEX & policies; can request evidence rather than editing it.
Role behavior is enforced by RBAC, but the UX is guided by ship-ready presets.
---
## 9. Implementation checklist for your .NET/Angular team
To make this action-ready:
1. **Routes / pages**
* `/inventory`
* `/applications/:appId`
* `/artifacts/:artifactId`
* `/findings`
* `/vex`
* `/exports`
* `/settings`
2. **Core reusable components**
* Graph snapshot badge (with copy & deeplink).
* Findings table (configurable columns, selection).
* Finding details drawer (tabs: Evidence / Impact / VEX & decisions / History).
* VEX status badge.
* Timeline component.
* Export job dialog & list.
3. **API contracts to align with UX**
* `GET /artifacts/:id/findings?snapshot=...`
* `GET /findings/:id?includeEvidence=true`
* `POST /vex/statements` (supports scoped statements).
* `GET /vex/statements?filters...`
* `POST /exports` + `GET /exports/:id`
* `GET /audit?scopeType=&scopeId=&range=...`
4. **Deep-linking**
* URLs should embed at least `snapshotId` for deterministic views:
* `/artifacts/:artifactId/findings/:findingId?snapshot=:snapshotId`
5. **Telemetry for UX refinement**
* Track frequency of:
* Evidence tab switches (Code vs Dependency vs Runtime).
* VEX edits per finding.
* Export jobs by type.
* Use this to prioritize which evidence views to optimize first.
---
If you want a next step, I can translate this into:
* A low-fidelity screen map (per route, per component), or
* An example JSON schema for VEX statements + proof bundles that matches the UIs expectations,
so your backend and frontend teams can converge on a single contract.

View File

@@ -0,0 +1,722 @@
I thought you might appreciate a quick reality-check of public evidence backing up five concrete test cases you could drop into the StellaOps acceptance suite **today** — each rooted in a real issue or behavior in the ecosystem.
---
## 🔎 Recent public incidents & tests matching your list
### • Credential-leak via Grype JSON output
* CVE-2025-65965 / GHSA-6gxw-85q2-q646 allows registry credentials to be written unsanitized into `--output json=…`. ([GitHub][1])
* Affects grype 0.68.00.104.0; patched in 0.104.1. ([GitHub][2])
* Workaround: avoid JSON file output or upgrade. ([GitHub][1])
**Implication for StellaOps**: run Grype with credentials + JSON output + scan the JSON for secrets; the test catches the leak.
---
### • Air-gap / old DB schema issues with Trivy
* `--skip-db-update` supports offline mode. ([Trivy][3])
* Using an old/offline DB with mismatched schema errors out instead of falling back. ([GitHub][4])
**Implication**: capture that deterministic failure (old DB + skip update) or document the exit code as part of offline gating.
---
### • SBOM mismatch between native binary vs container builds (Syft + friends)
* Mixing SBOM sources (Syft vs Trivy) yields wildly different vulnerability counts when fed into Grype. ([GitHub][5])
**Implication**: compare SBOMs from native builds and containers for the same artifact (digests, component counts) to detect provenance divergence.
---
### • Inconsistent vulnerability detection across Grype versions
* The same SBOM under Grype v0.87.0 reported multiple critical+high findings; newer versions reported none. ([GitHub][6])
**Implication**: ingest a stable SBOM/VEX set under multiple DB/scanner versions to detect regressions or nondeterministic outputs.
---
## ✅ Publicly verified vs speculative
| ✅ Publicly verified | ⚠️ Needs controlled testing / assumption-driven |
| ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Credential leak in Grype JSON output (CVE-2025-65965) ([GitHub][2]) | Exact SBOM-digest parity divergence between native & container Syft runs (no formal bug yet) |
| Trivy offline DB schema error ([Trivy][3]) | Custom CVSS/VEX sorting in patched grype-dbs or Snyk workarounds (not publicly reproducible) |
| Grype version divergence on the same SBOM ([GitHub][6]) | VEX evidence mappings from tools like Snyk - plausible but not documented reproducibly |
---
## 🎯 Why this matters for StellaOps
Your goals are deterministic, audit-ready SBOM + VEX pipelines. These public incidents show how fragile tooling can be. Embedding the above tests ensures reliability and reproducibility even under credential leaks, offline scans, or DB/schema churn.
Want a bash/pseudo spec for all five cases (commands + assertions)? I can drop it into your repo as a starting point.
[1]: https://github.com/anchore/grype/security/advisories/GHSA-6gxw-85q2-q646?utm_source=chatgpt.com "Credential disclosure vulnerability in Grype JSON output"
[2]: https://github.com/advisories/GHSA-6gxw-85q2-q646?utm_source=chatgpt.com "Grype has a credential disclosure vulnerability in its JSON ..."
[3]: https://trivy.dev/docs/v0.55/guide/advanced/air-gap/?utm_source=chatgpt.com "Advanced Network Scenarios"
[4]: https://github.com/aquasecurity/trivy/discussions/4838?utm_source=chatgpt.com "trivy offline-db · aquasecurity trivy · Discussion #4838"
[5]: https://github.com/aquasecurity/trivy/discussions/6325?utm_source=chatgpt.com "and of those detected Trivy sometimes does not report a ..."
[6]: https://github.com/anchore/grype/issues/2628?utm_source=chatgpt.com "Grype false negatives in versions v0.88.0 and later leading ..."
Heres a concrete package of **guidelines + five acceptance test specs** for StellaOps implementors, based on the incidents and behaviors we walked through (Grype leak, Trivy offline DB, Syft parity, grype-db / VEX, Snyk exploit maturity).
Ill keep it tool/frameworkagnostic so you can drop this into whatever test runner youre using.
---
## 1. Implementation guidelines for StellaOps integrators
These are the “rules of the road” that every new scanner / SBOM / VEX adapter in StellaOps should follow.
### 1.1. Test layering
For each external tool (Grype, Trivy, Syft, Snyk, …) you should have:
1. **Unit tests**
* Validate argument construction, environment variables, and parsing of raw tool output.
2. **Adapter integration tests**
* Run the real tool (or a pinned container image) on small deterministic fixtures.
3. **Acceptance tests (this doc)**
* Cross-tool workflows and critical invariants: secrets, determinism, offline behavior, VEX mapping.
4. **Golden outputs**
* For key paths, store canonical JSON/CSAF/CycloneDX outputs as fixtures and diff against them.
Each new adapter should add at least one test in each layer.
---
### 1.2. Determinism & reproducibility
**Rule:** *Same inputs (artifact, SBOM, VEX, tool versions) → bitforbit identical StellaOps results.*
Guidelines:
* Pin external tool versions in tests (`GRYPE_VERSION`, `TRIVY_VERSION`, `SYFT_VERSION`, `SNYK_CLI_VERSION`).
* Pin vulnerability DB snapshots (e.g. `GRYPE_DB_SNAPSHOT_ID`, `TRIVY_DB_DIR`).
* Persist the “scan context” alongside results: scanner version, db snapshot id, SBOM hash, VEX hash.
* For sorted outputs, define and test a **stable global sort order**:
* e.g. `effectiveSeverity DESC, exploitEvidence DESC, vulnerabilityId ASC`.
---
### 1.3. Secrets and logs
Recent issues show scanners can leak sensitive data to JSON or logs:
* **Grype**: versions v0.68.0v0.104.0 could embed registry credentials in JSON output files when invoked with `--file` or `--output json=<file>` and credentials are configured. ([GitLab Advisory Database][1])
* **Trivy / Snyk**: both have had edge cases where DB/CLI errors or debug logs printed sensitive info. ([Trivy][2])
Guidelines:
* **Never** enable DEBUG/TRACE logging for thirdparty tools in production mode.
* **Never** use scanner options that write JSON reports directly to disk unless you control the path and sanitize.
* Treat logs and raw reports as **untrusted**: run them through secretscanning / redaction before persistence.
* Build tests that use **fake-but-realistic secrets** (e.g. `stella_USER_123`, `stella_PASS_456`) and assert they never appear in:
* DB rows
* API responses
* UI
* Stored raw reports
---
### 1.4. Offline / airgapped behavior
Trivys offline mode is a good example of fragile behavior:
* Using an old offline DB with `--skip-db-update` can produce fatal “old schema” errors like
`The local DB has an old schema version… --skip-update cannot be specified with the old DB schema`. ([GitHub][3])
* Airgap workflows require explicit flags like `--skip-db-update` and `--skip-java-db-update`. ([aquasecurity.github.io][4])
Guidelines:
* All scanner adapters must have an **explicit offline mode** flag / config.
* In offline mode:
* Do **not** attempt any network DB updates.
* Treat **DB schema mismatch / “old DB schema”** as a *hard* scanner infrastructure error, *not* “zero vulns”.
* Surface offline issues as **typed StellaOps errors**, e.g. `ScannerDatabaseOutOfDate`, `ScannerFirstRunNoDB`.
---
### 1.5. External metadata → internal model
Different tools carry different metadata:
* CVSS v2/v3/v3.1/v4.0 (score & vectors).
* GHSA vs CVE vs SNYKIDs.
* Snyks `exploitMaturity` field (e.g. `no-known-exploit`, `proof-of-concept`, `mature`, `no-data`). ([Postman][5])
Guidelines:
* Normalize all of these into **one internal vulnerability model**:
* `primaryId` (CVE, GHSA, Snyk ID, etc.)
* `aliases[]`
* `cvss[]` (list of metrics with `version`, `baseScore`, `baseSeverity`)
* `exploitEvidence` (internal enum derived from `exploitMaturity`, EPSS, etc.)
* Define **deterministic merge rules** when multiple sources describe the same vuln (CVE+GHSA+SNYK).
---
### 1.6. Contract & fixture hygiene
* Prefer **static fixtures** over dynamic network calls in tests.
* Version every fixture with a semantic name and version, e.g.
`fixtures/grype/2025-credential-leak-v1.json`.
* When you change parsers or normalizers, add a new version of the fixture, but **keep the old one** to guard regressions.
---
## 2. Acceptance test specs (for implementors)
Below are five concrete test cases you can add to a `tests/acceptance/` suite.
Ill name them `STELLA-ACC-00X` so you can turn them into tickets if you want.
---
### STELLA-ACC-001 — Grype JSON credential leak guard
**Goal**
Guarantee that StellaOps never stores or exposes registry credentials even if:
* Grype itself is (or becomes) vulnerable, or
* A user uploads a raw Grype JSON report that contains creds.
This is directly motivated by CVE202565965 / GHSA6gxw85q2q646. ([GitLab Advisory Database][1])
---
#### 001A Adapter CLI usage (no unsafe flags)
**Invariant**
> The Grype adapter must *never* use `--file` or `--output json=<file>` — only `--output json` to stdout.
**Setup**
* Replace `grype` in PATH with a small wrapper script that:
* Records argv and env to a temp file.
* Exits 0 after printing a minimal fake JSON vulnerability report to stdout.
**Steps**
1. Run a standard StellaOps Grypebased scan through the adapter on a dummy image/SBOM.
2. After completion, read the temp “spy” file written by the wrapper.
**Assertions**
* The recorded arguments **do not** contain:
* `--file`
* `--output json=`
* There is exactly one `--output` argument and its value is `json`.
> This test is purely about **command construction**; it never calls the real Grype binary.
---
#### 001B Ingestion of JSON with embedded creds
**Invariant**
> If a Grype JSON report contains credentials, StellaOps must either reject it or scrub credentials before storage/exposure.
**Fixture**
* `fixtures/grype/credential-leak.json`, modeled roughly like the CVE report:
* Include a fake Docker config snippet Grype might accidentally embed, e.g.:
```json
{
"config": {
"auths": {
"registry.example.com": {
"username": "stella_USER_123",
"password": "stella_PASS_456"
}
}
}
}
```
* Plus one small vulnerability record so the ingestion pipeline runs normally.
**Steps**
1. Use a test helper to ingest the fixture as if it were Grype output:
* e.g. `stellaIngestGrypeReport("credential-leak.json")`.
2. Fetch the stored scan result via:
* direct DB access, or
* StellaOps internal API.
**Assertions**
* Nowhere in:
* stored raw report blobs,
* normalized vulnerability records,
* metadata tables,
* logs captured by the test runner,
should the substrings `stella_USER_123` or `stella_PASS_456` appear.
* The ingestion should:
* either succeed and **omit/sanitize** the auth section,
* or fail with a **clear, typed error** like `ReportContainsSensitiveSecrets`.
**Implementation guidelines**
* Implement a **secret scrubber** that runs on:
* any external JSON you store,
* any logs when a scanner fails verbosely.
* Add a generic helper assertion in your test framework:
* `assertNoSecrets(ScanResult, ["stella_USER_123", "stella_PASS_456"])`.
---
### STELLA-ACC-002 — Syft SBOM manifest digest parity (native vs container)
**Goal**
Ensure StellaOps produces the same **artifact identity** (image digest / manifest digest / tags) when SBOMs are generated:
* By Syft installed natively on the host vs
* By Syft run as a container image.
This is about keeping VEX, rescan, and historical analysis aligned even if environments differ.
---
#### Setup
1. Build a small deterministic test image:
```bash
docker build -t stella/parity-image:1.0 tests/fixtures/images/parity-image
```
2. Make both Syft variants available:
* Native binary: `syft` on PATH.
* Container image: `anchore/syft:<pinned-version>` already pulled into your local registry/cache.
3. Decide where you store canonical SBOMs in the pipeline, e.g. under `Scan.artifactIdentity`.
---
#### Steps
1. **Generate SBOM with native Syft**
```bash
syft packages --scope Squashed stella/parity-image:1.0 -o json > sbom-native.json
```
2. **Generate SBOM with containerized Syft**
```bash
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
anchore/syft:<pinned-version> \
packages --scope Squashed stella/parity-image:1.0 -o json \
> sbom-container.json
```
3. Import each SBOM into StellaOps as if they were separate scans:
* `scanNative = stellaIngestSBOM("sbom-native.json")`
* `scanContainer = stellaIngestSBOM("sbom-container.json")`
4. Extract the normalized artifact identity:
* `scanNative.artifactId`
* `scanNative.imageDigest`
* `scanNative.manifestDigest`
* `scanContainer.*` same fields.
---
#### Assertions
* `scanNative.artifactId == scanContainer.artifactId`
* `scanNative.imageDigest == scanContainer.imageDigest`
* If you track manifest digest separately:
`scanNative.manifestDigest == scanContainer.manifestDigest`
* Optional: for extra paranoia, assert that the **set of package coordinates** is identical (ignoring ordering).
**Implementation guidelines**
* Dont trust SBOM metadata blindly; if Syft metadata differs, compute a **canonical image ID** using:
* container runtime inspect,
* or an independent digest calculator.
* Store artifact IDs in a **single, normalized format** across all scanners and SBOM sources.
---
### STELLA-ACC-003 — Trivy airgapped DB schema / skip behavior
**Goal**
In offline mode, Trivy DB schema mismatches must produce a clear, typed failure in StellaOps — never silently “0 vulns”.
Trivy shows specific messages for old DB schema when combined with `--skip-update/--skip-db-update`. ([GitHub][3])
---
#### Fixtures
1. `tests/fixtures/trivy/db-old/`
* A Trivy DB with `metadata.json` `Version: 1` where your pinned Trivy version expects `Version: 2` or greater.
* You can:
* download an old offline DB archive, or
* copy a modern DB and manually set `"Version": 1` in `metadata.json` for test purposes.
2. `tests/fixtures/trivy/db-new/`
* A DB snapshot matching the current Trivy version (pass case).
---
#### 003A Old schema + `--skip-db-update` gives typed error
**Steps**
1. Configure the Trivy adapter for offline scan:
* `TRIVY_CACHE_DIR = tests/fixtures/trivy/db-old`
* Add `--skip-db-update` (or `--skip-update` depending on your adapter) to the CLI args.
2. Run a StellaOps scan using Trivy on a small test image.
3. Capture:
* Trivy exit code.
* Stdout/stderr.
* StellaOps internal `ScanRun` / job status.
**Assertions**
* Trivy exits nonzero.
* Stderr contains both:
* `"The local DB has an old schema version"` and
* `"--skip-update cannot be specified with the old DB schema"` (or localized equivalent). ([GitHub][3])
* StellaOps marks the scan as **failed with error type** `ScannerDatabaseOutOfDate` (or equivalent internal enum).
* **No** vulnerability records are saved for this run.
---
#### 003B New schema + offline flags succeeds
**Steps**
1. Same as above, but:
* `TRIVY_CACHE_DIR = tests/fixtures/trivy/db-new`
2. Run the scan.
**Assertions**
* Scan succeeds.
* A nonempty set of vulnerabilities is stored (assuming the fixture image is intentionally vulnerable).
* Scan metadata records:
* `offlineMode = true`
* `dbSnapshotId` or a hash of `metadata.json`.
**Implementation guidelines**
* Parse known Trivy error strings into **structured error types** instead of treating all nonzero exit codes alike.
* Add a small helper in the adapter like:
```go
func classifyTrivyError(stderr string, exitCode int) ScannerErrorType
```
and unit test it with copies of real Trivy messages from docs/issues.
---
### STELLA-ACC-004 — grypedb / CVSS & VEX sorting determinism
**Goal**
Guarantee that StellaOps:
1. Merges and prioritizes CVSS metrics (v2/v3/v3.1/4.0) deterministically, and
2. Produces a stable, reproducible vulnerability ordering after applying VEX.
This protects you from “randomly reshuffled” critical lists when DBs update or scanners add new metrics.
---
#### Fixture
`fixtures/grype/cvss-vex-sorting.json`:
* Single artifact with three vulnerabilities on the same package:
1. `CVE-2020-AAAA`
* CVSS v2: 7.5 (High)
* CVSS v3.1: 5.0 (Medium)
2. `CVE-2021-BBBB`
* CVSS v3.1: 8.0 (High)
3. `GHSA-xxxx-yyyy-zzzz`
* Alias of `CVE-2021-BBBB` but only v2 score 5.0 (Medium)
* A companion VEX document (CycloneDX VEX or CSAF) that:
* Marks `CVE-2020-AAAA` as `not_affected` for the specific version.
* Leaves `CVE-2021-BBBB` as `affected`.
You dont need real IDs; you just need consistent internal expectations.
---
#### Steps
1. Ingest the Grype report and the VEX document together via StellaOps, producing `scanId`.
2. Fetch the normalized vulnerability list for that artifact:
* e.g. `GET /artifacts/{id}/vulnerabilities?scan={scanId}` or similar internal call.
3. Map it to a simplified view inside the test:
```json
[
{ "id": "CVE-2020-AAAA", "effectiveSeverity": "...", "status": "..."},
{ "id": "CVE-2021-BBBB", "effectiveSeverity": "...", "status": "..."},
...
]
```
---
#### Assertions
* **Deduplication**:
* `GHSA-xxxx-yyyy-zzzz` is **merged** into the same logical vuln as `CVE-2021-BBBB` (i.e. appears once with aliases including both IDs).
* **CVSS selection**:
* For `CVE-2020-AAAA`, `effectiveSeverity` is based on:
* v3.1 over v2 if present, else highest base score.
* For `CVE-2021-BBBB`, `effectiveSeverity` is “High” (from v3.1 8.0).
* **VEX impact**:
* `CVE-2020-AAAA` is marked as `NOT_AFFECTED` (or your internal equivalent) and should:
* either be excluded from the default list, or
* appear but clearly flagged as `not_affected`.
* **Sorting**:
* The vulnerability list is ordered stably, e.g.:
1. `CVE-2021-BBBB` (High, affected)
2. `CVE-2020-AAAA` (Medium, not_affected) — if you show not_affected entries.
* **Reproducibility**:
* Running the same test multiple times yields identical JSON for:
* the vulnerability list (after sorting),
* the computed `effectiveSeverity` values.
**Implementation guidelines**
* Implement explicit merge logic for pervuln metrics:
```text
1. Prefer CVSS v3.1 > 3.0 > 2.0 when computing effectiveSeverity.
2. If multiple metrics of same version exist, pick highest baseScore.
3. When multiple sources (NVD, GHSA, vendor) disagree on baseSeverity,
define your precedence and test it.
```
* Keep VEX application deterministic:
* apply VEX status before sorting,
* optionally remove `not_affected` entries from the “default” list, but still store them.
---
### STELLA-ACC-005 — Snyk exploitmaturity → VEX evidence mapping
**Goal**
Map Snyks `exploitMaturity` metadata into a standardized StellaOps “exploit evidence” / VEX semantic and make this mapping deterministic and testable.
Snyks APIs and webhooks expose an `exploitMaturity` field (e.g. `no-known-exploit`, `proof-of-concept`, etc.). ([Postman][5])
---
#### Fixture
`fixtures/snyk/exploit-maturity.json`:
* Mimic a Snyk test/report response with at least four issues, one per value:
```json
[
{
"id": "SNYK-JS-AAA-1",
"issueType": "vuln",
"severity": "high",
"issueData": {
"exploitMaturity": "no-known-exploit",
"cvssScore": 7.5
}
},
{
"id": "SNYK-JS-BBB-2",
"issueData": {
"exploitMaturity": "proof-of-concept",
"cvssScore": 7.5
}
},
{
"id": "SNYK-JS-CCC-3",
"issueData": {
"exploitMaturity": "mature",
"cvssScore": 5.0
}
},
{
"id": "SNYK-JS-DDD-4",
"issueData": {
"exploitMaturity": "no-data",
"cvssScore": 9.0
}
}
]
```
(Names/IDs dont matter; internal mapping does.)
---
#### Internal mapping (proposed)
Define a StellaOps enum, e.g. `ExploitEvidence`:
* `EXPLOIT_NONE` ← `no-known-exploit`
* `EXPLOIT_POC` ← `proof-of-concept`
* `EXPLOIT_WIDESPREAD` ← `mature`
* `EXPLOIT_UNKNOWN` ← `no-data` or missing
And define how this influences risk (e.g. by factors or direct overrides).
---
#### Steps
1. Ingest the Snyk fixture as a Snyk scan for a dummy project/image.
2. Fetch normalized vulnerabilities from StellaOps for that scan.
In the test, map each vuln to:
```json
{
"id": "SNYK-JS-AAA-1",
"exploitEvidence": "...",
"effectiveSeverity": "..."
}
```
---
#### Assertions
* Mapping:
* `SNYK-JS-AAA-1` → `exploitEvidence == EXPLOIT_NONE`
* `SNYK-JS-BBB-2` → `exploitEvidence == EXPLOIT_POC`
* `SNYK-JS-CCC-3` → `exploitEvidence == EXPLOIT_WIDESPREAD`
* `SNYK-JS-DDD-4` → `exploitEvidence == EXPLOIT_UNKNOWN`
* Risk impact (example; adjust to your policy):
* For equal CVSS, rows with `EXPLOIT_WIDESPREAD` or `EXPLOIT_POC` must rank **above** `EXPLOIT_NONE` in any prioritized listing (e.g. patch queue).
* A high CVSS (9.0) with `EXPLOIT_UNKNOWN` must not be treated as lower risk than a lower CVSS with `EXPLOIT_WIDESPREAD` unless your policy explicitly says so.
Your sorting rule might look like:
```text
ORDER BY
exploitEvidenceRank DESC, -- WIDESPREAD > POC > UNKNOWN > NONE
cvssBaseScore DESC,
vulnerabilityId ASC
```
and the test should assert on the resulting order.
* Any Snyk issue missing `exploitMaturity` explicitly is treated as `EXPLOIT_UNKNOWN`, not silently defaulted to `EXPLOIT_NONE`.
**Implementation guidelines**
* Centralize the mapping in a single function and unit test it:
```ts
function mapSnykExploitMaturity(value: string | null): ExploitEvidence
```
* If you emit VEX (CycloneDX/CSAF) from StellaOps, propagate the internal `ExploitEvidence` into the appropriate field (e.g. as part of justification or additional evidence object) and add a small test that roundtrips this.
---
## 3. How to use this as an implementor checklist
When you add or modify StellaOps integrations, treat this as a living checklist:
1. **Touching Grype?**
* Ensure `STELLA-ACC-001` still passes.
2. **Touching SBOM ingestion / artifact identity?**
* Run `STELLA-ACC-002`.
3. **Touching Trivy adapter or offline mode?**
* Run `STELLA-ACC-003`.
4. **Changing vulnerability normalization / severity logic?**
* Run `STELLA-ACC-004` and `STELLA-ACC-005`.
5. **Adding a new scanner?**
* Clone these patterns:
* one **secret-leak** test,
* one **offline / DB drift** test (if relevant),
* one **identity parity** or **determinism** test,
* one **metadatamapping** test (like exploit maturity).
If you want, next step I can help you translate these into a concrete test skeleton (e.g. Gherkin scenarios or Jest/Go test functions) for the language youre using in StellaOps.
[1]: https://advisories.gitlab.com/pkg/golang/github.com/anchore/grype/CVE-2025-65965/?utm_source=chatgpt.com "Grype has a credential disclosure vulnerability in its JSON ..."
[2]: https://trivy.dev/docs/latest/references/troubleshooting/?utm_source=chatgpt.com "Troubleshooting"
[3]: https://github.com/aquasecurity/trivy-db/issues/186?utm_source=chatgpt.com "trivy-db latest Version has an old schema · Issue #186"
[4]: https://aquasecurity.github.io/trivy/v0.37/docs/advanced/air-gap/?utm_source=chatgpt.com "Air-Gapped Environment"
[5]: https://www.postman.com/api-evangelist/snyk/collection/mppgu5u/snyk-api?utm_source=chatgpt.com "Snyk API | Get Started"

View File

@@ -0,0 +1,328 @@
Heres a compact, diagramfirst blueprint that shows how to turn a CycloneDX SBOM into signed, replaysafe proofs across DSSE/intoto, Rekor v2 (tilebacked) receipts, and VEX—plus how to run this with the public instance or fully offline.
---
## 1) Mental model (one line per hop)
```
[SBOM: CycloneDX JSON]
└─(wrap as DSSE payload; predicate = CycloneDX)
└─(optional: intoto statement for context)
└─(sign → cosign/fulcio or your own CA)
└─(log entry → Rekor v2 / tiles)
└─(checkpoint + inclusion proof + receipt)
└─(VEX attestation references SBOM/log)
└─(Authority anchors/keys + policies)
```
* **CycloneDX SBOM** is your canonical inventory. ([cyclonedx.org][1])
* **DSSE** provides a minimal, standard signing envelope; intoto statements add supplychain context. ([JFrog][2])
* **Rekor v2** stores a hash of your attestation in a **tilebacked transparency log** and returns **checkpoint + inclusion proof** (small, verifiable). ([Sigstore Blog][3])
* **VEX** conveys exploitability (e.g., “not affected”) and should reference the SBOM and, ideally, the Rekor receipt. ([cyclonedx.org][4])
---
## 2) Exact capture points (what to store)
* **SBOM artifact**: `sbom.cdx.json` (canonicalized bytes + SHA256). ([cyclonedx.org][1])
* **DSSE envelope** over SBOM (or intoto statement whose predicate is CycloneDX): keep the full JSON + signature. ([JFrog][2])
* **Rekor v2 receipt**:
* **Checkpoint** (signed tree head)
* **Inclusion proof** (audit path)
* **Entry leaf hash / UUID**
Persist these with your build to enable offline verification. ([Sigstore Blog][3])
* **VEX attestation** (CycloneDX VEX): include references (by digest/URI) to the **SBOM** and the **Rekor entry/receipt** used for the SBOM attestation. ([cyclonedx.org][4])
* **Authority anchors**: publish the verifying keys (or TUFroot if using Sigstore public good), plus your policy describing accepted issuers and algorithms. ([Sigstore][5])
---
## 3) Fieldlevel linkage (IDs youll wire together)
* **`subject.digest`** in DSSE/intoto ↔ **SBOM SHA256**. ([OpenSSF][6])
* **Rekor entry** ↔ **DSSE envelope digest** (leaf/UUID recorded in receipt). ([GitHub][7])
* **VEX `affects` / `analysis`** entries ↔ **components in SBOM** (use purl/coordinates) and include **`evidence`/`justification`** with **Rekor proof URI**. ([cyclonedx.org][4])
---
## 4) Verification flow (online or airgapped)
**Online (public good):**
1. Verify DSSE signature against accepted keys/issuers. ([Sigstore][5])
2. Verify Rekor **checkpoint signature** and **inclusion proof** for the logged DSSE digest. ([Go Packages][8])
3. Validate VEX against the same SBOM digest (and optionally that its own attestation is also logged). ([cyclonedx.org][4])
**Airgapped / sovereign:**
* Mirror/export **Rekor tiles + checkpoints** on a courier medium; keep receipts small by shipping only tiles covering the ranges you need.
* Run **selfhosted Rekor v2** or a **local tile cache**; verifiers check **checkpoint signatures** and **consistency proofs** exactly the same way. ([Sigstore Blog][3])
---
## 5) Public instance vs selfhosted (decision notes)
* **Public**: zeroops, audited community infra; you still archive receipts with your releases. ([Sigstore][5])
* **Selfhosted Rekor v2 (tiles)**: cheaper/simpler than v1, tile export makes **offline kits** practical; publish your **root keys** as organization anchors. ([Sigstore Blog][3])
---
## 6) Minimal CLI recipe (illustrative)
* Generate SBOM → wrap → attest → log → emit receipt:
* Create CycloneDX JSON; compute digest. ([cyclonedx.org][1])
* Create **DSSE** or **intoto** attestation for the SBOM; sign (cosign or your CA). ([JFrog][2])
* Submit to **Rekor v2**; store **checkpoint + inclusion proof + UUID** with the build. ([Sigstore Blog][3])
* Emit **VEX** referencing the SBOM digest **and** the Rekor entry (URI/UUID). ([cyclonedx.org][4])
---
## 7) Developer guardrails (to keep proofs replaysafe)
* **Canonical bytes only** (stable JSON ordering/whitespace) before hashing/signing. ([JFrog][2])
* **Pin algorithms** (e.g., SHA256 + key types) in policy; reject drift. ([Sigstore][5])
* **Always persist**: SBOM, DSSE envelope, Rekor receipt, VEX, and your **acceptedkeys manifest** with version. ([Sigstore Blog][3])
* **Test offline**: verification must pass using only tiles + receipts you ship. ([Go Packages][9])
---
## 8) Optional niceties
* Gate deployments on “image must have **signed SBOM** (attestation)”. Sigstore Policy Controller example exists. ([Stackable Documentation][10])
* Track CVE status via **CycloneDX VEX** in your UI (“affected/not affected” with evidence links to Rekor). ([cyclonedx.org][4])
---
If you want, I can turn this into a **StellaOps** diagram + dropin `docs/blueprints/sbomtovexrekor.md` with exact JSON stubs for: DSSE envelope, intoto statement, Rekor receipt example, and a CycloneDX VEX snippet wired to the receipt.
[1]: https://cyclonedx.org/specification/overview/?utm_source=chatgpt.com "Specification Overview"
[2]: https://jfrog.com/blog/introducing-dsse-attestation-online-decoder/?utm_source=chatgpt.com "Introducing the DSSE Attestation Online Decoder"
[3]: https://blog.sigstore.dev/rekor-v2-ga/?utm_source=chatgpt.com "Rekor v2 GA - Cheaper to run, simpler to maintain"
[4]: https://cyclonedx.org/capabilities/vex/?utm_source=chatgpt.com "Vulnerability Exploitability eXchange (VEX)"
[5]: https://docs.sigstore.dev/logging/overview/?utm_source=chatgpt.com "Rekor"
[6]: https://openssf.org/blog/2024/06/26/a-deep-dive-into-sbomit-and-attestations/?utm_source=chatgpt.com "A Deep Dive into SBOMit and Attestations"
[7]: https://github.com/sigstore/rekor?utm_source=chatgpt.com "sigstore/rekor: Software Supply Chain Transparency Log"
[8]: https://pkg.go.dev/github.com/sigstore/rekor-tiles/v2/pkg/verify?utm_source=chatgpt.com "verify package - github.com/sigstore/rekor-tiles/v2/pkg/verify"
[9]: https://pkg.go.dev/github.com/sigstore/rekor-tiles?utm_source=chatgpt.com "rekor-tiles module - github.com/sigstore/rekor-tiles"
[10]: https://docs.stackable.tech/home/stable/guides/viewing-and-verifying-sboms/?utm_source=chatgpt.com "Viewing and verifying SBOMs of the Stackable Data Platform"
These guidelines are meant for people implementing or extending Stella Ops: core maintainers, external contributors, plug-in authors, and teams wiring Stella Ops into CI/CD and offline environments. They sit under the published docs (SRS, architecture, release playbook, etc.) and try to translate those into a practical checklist. ([Gitea: Git with a cup of tea][1])
---
## 1. Anchor yourself in the canonical docs
Before writing code or designing a new module:
* **Treat the SRS as the contract.** Any feature must trace back to a requirement (or add a new one via ADR + docs). Dont ship behavior that contradicts quota rules, SBOM formats, NFRs, or API shapes defined there. ([Gitea: Git with a cup of tea][1])
* **Respect the existing architecture split**: backend API, CLI, Zastava agent, internal registry, web UI, plug-ins. Dont blur responsibilities (e.g., dont make the UI talk directly to Redis). ([Gitea: Git with a cup of tea][1])
* **Keep docs and code in lock-step.** If you change an endpoint, CLI flag, plug-in contract, or quota behavior, update the corresponding doc page / module dossier before merge. ([Stella Ops][2])
Think of the docs (`docs/`, `modules/`, ADRs) as **source of truth**; code is the implementation detail.
---
## 2. Core principles you must preserve
### 2.1 SBOM-first & VEX-first
Stella Ops exists to be an **SBOM-first, VEX-policy-driven container security platform**. ([Stella Ops][3])
Implementor rules:
* **SBOMs are the system of record.** All new scanners, checks, and policies should operate on SBOMs (Trivy JSON, SPDX JSON, CycloneDX JSON) rather than ad-hoc image inspections. ([Gitea: Git with a cup of tea][1])
* **VEX/OpenVEX is how you express exploitability.** Any feature that mutates “this thing is risky / safe” must do so via VEX-style statements (statuses like *affected*, *not affected*, *fixed*, *under investigation* + justification), not bespoke flags. ([cyclonedx.org][4])
### 2.2 Deterministic & replayable
Docs and the release playbook emphasise **deterministic replay**: given the same SBOM + advisory snapshot + policies, you must get the same verdict, even months later. ([Stella Ops][2])
* No hidden network calls that change behavior over time. If you need remote data, it must be:
* Snapshotted and imported via the Offline Update Kit (OUK), or
* Explicitly modeled as a versioned input in a replay manifest. ([Gitea: Git with a cup of tea][5])
* Avoid nondeterminism: no reliance on wall-clock time (except where specified, e.g., quotas), random IDs in hashes, or unordered iteration when serializing JSON.
### 2.3 Offline-first & sovereign
Stella Ops must run **fully offline** with all dependencies vendored or mirrored, and allow **bring-your-own trust roots, vulnerability sources, and crypto profiles**. ([Gitea: Git with a cup of tea][6])
* Any new integration (scanner, advisory feed, trust store) **MUST have an offline path**:
* Downloaded + signed into OUK, or
* Mirrored into the internal registry / DB.
* Never hard-code URLs to cloud services in core paths. Gate optional online behavior behind explicit config flags, default-off.
### 2.4 Performance, quotas, and transparency
The SRS sets **P95 ≤ 5 s cold, ≤ 1 s warm** and a quota of `{{quota_token}}` scans per token/day with explicit `/quota` APIs and UI banners. ([Gitea: Git with a cup of tea][1])
Implementor rules:
* Any change that touches scanning or advisory evaluation must:
* Preserve P95 targets under the reference hardware profile.
* Not add hidden throttling—only the documented soft quota mechanisms. ([Gitea: Git with a cup of tea][1])
* If you introduce heavier logic (e.g., new reachability analysis), consider:
* Pre-computation in background jobs.
* Caching keyed by SBOM digest + advisory snapshot ID.
### 2.5 Security & SLSA alignment
The release guide already aims at **SLSA ≥ 2, targeting level 3**, with provenance via BuildKit and signed artefacts. ([Gitea: Git with a cup of tea][5])
Implementation rules:
* All new build artefacts (containers, Helm charts, OUK tarballs, plug-ins) **MUST**:
* Have SBOMs attached.
* Be signed (Cosign or equivalent).
* Be compatible with future Rekor logging. ([Gitea: Git with a cup of tea][5])
* Inter-service comms **MUST** use TLS or localhost sockets as per NFRs. ([Gitea: Git with a cup of tea][1])
* Zero telemetry by default. Any metrics must be Prometheus-style, local, and opt-in for anything that could leak sensitive data. ([Gitea: Git with a cup of tea][1])
---
## 3. Cross-cutting implementation guidelines
### 3.1 APIs, CLI, and schemas
* **Respect existing API semantics.** `/scan`, `/layers/missing`, `/quota`, `/policy/*`, `/plugins` are canonical; new endpoints must follow the same patterns (Bearer auth, quota flags, clear error codes). ([Gitea: Git with a cup of tea][1])
* **Keep CLI and API mirrors in sync.** If `stella scan` gains a flag, the `/scan` API should gain a corresponding field (or vice versa); update the API & CLI Reference doc. ([Stella Ops][2])
* **Evolve schemas via versioned contracts.** Any change to SBOM or VEX-related internal schemas must add fields compatibly; never repurpose a fields meaning silently.
### 3.2 Data and storage
* Use Mongo for durable state and Redis for caches as per SRS assumptions; dont introduce new stateful infrastructure lightly. ([Gitea: Git with a cup of tea][1])
* All cache keys must be explicitly invalidated when:
* OUK updates are applied.
* Policies, advisories, or SBOM parsing rules change. ([Gitea: Git with a cup of tea][5])
### 3.3 Observability
* For every new long-running operation or critical decision path:
* Export Prometheus metrics (latency, error counts, queue depth where relevant).
* Emit structured audit events where user-visible risk changes (e.g., VEX status flips, OUK updates). ([Gitea: Git with a cup of tea][1])
---
## 4. Supply-chain evidence: SBOM → SLSA → DSSE → Rekor → VEX
This is where prior work on SBOM/DSSE/Rekor/VEX connects directly to Stella Ops roadmap. ([Gitea: Git with a cup of tea][1])
### 4.1 SBOM handling
* **Ingestion:** Implement parsers for Trivy JSON, SPDX JSON, and CycloneDX JSON, and always auto-detect when `sbomType` is omitted. ([Gitea: Git with a cup of tea][1])
* **Generation:** When building images or plug-ins:
* Use `StellaOps.SBOMBuilder` or equivalent to produce at least SPDX and one additional format.
* Attach SBOMs as OCI artefacts and label images accordingly. ([Gitea: Git with a cup of tea][5])
* **Delta SBOM:** Any new builder or scanner must preserve the delta-SBOM contract: compute layer digests, ask `/layers/missing`, generate SBOM only for missing layers, and hit the 1 s P95 warm scan target. ([Gitea: Git with a cup of tea][1])
### 4.2 SLSA provenance and DSSE
* **Per-SBOM provenance:** For each generated SBOM, produce SLSA-compliant provenance describing builder, sources, inputs, and environment (Build L1+ at minimum, aiming for L2/L3 over time). ([SLSA][7])
* **DSSE envelopes:** Wrap SBOMs and provenance in DSSE envelopes signed with the active crypto profile (Cosign keypair, HSM, or regional provider). ([Sigstore][8])
* **Deterministic hashing:** Always hash canonicalized JSON bytes (stable ordering, no insignificant whitespace) so proofs remain stable no matter the emitter.
### 4.3 Rekor integration (local mirror, future public)
* **Local Rekor mirror first.** Implement the TODO from FR-REKOR-1 and the release playbook: run a Rekor v2 (tile-backed) instance inside the sovereign environment and submit DSSE/SBOM digests there. ([Gitea: Git with a cup of tea][1])
* **Receipts & proofs:**
* Capture Rekor receipts: checkpoint, inclusion proof, and leaf hash/UUID.
* Store them alongside scan results and in replay manifests so they can be verified fully offline. ([Sigstore][8])
* **Offline kits & tiles:** When OUKs are built, include:
* The minimal Rekor tile ranges and recent checkpoints needed to verify new entries.
* A verification job that proves entries are included/consistent before publishing the OUK. ([Gitea: Git with a cup of tea][5])
### 4.4 VEX / OpenVEX
* **Use VEX for exploitability, not ad-hoc flags.** Represent vulnerability status with VEX, ideally OpenVEX (format-agnostic) plus CycloneDX-embedded VEX where useful. ([cyclonedx.org][4])
* **Meet CISA minimum fields:** Ensure VEX documents include:
* Document metadata (ID, version, author, timestamps),
* Statement metadata (IDs, timestamps),
* Product + vulnerability identifiers, and
* Status + justification/impact, following the CISA “Minimum Requirements for VEX” and CycloneDX mappings. ([Medium][9])
* **Link everything:**
* Each VEX statement must reference the SBOM component via BOM-ref/purl and the product/version it applies to.
* Where possible, attach Rekor UUIDs or bundle IDs as evidence so auditors can trace “why we claimed not-affected”. ([Gitea: Git with a cup of tea][1])
---
## 5. Plug-in and module implementors
Stella Ops is designed to be **open & modular**: scanner plug-ins, attestors, registry helpers, etc. ([Gitea: Git with a cup of tea][6])
### 5.1 Plug-in behavior
* **Lifecycle & safety:**
* Plug-ins must be hot-loadable (.NET plug-ins without restarting core services).
* Fail closed: if a plug-in crashes or times out, the verdict must be conservative or clearly marked partial. ([Gitea: Git with a cup of tea][1])
* **Security:**
* No network access by default; if absolutely necessary, go through a vetted HTTP client that obeys offline mode and proxy settings.
* Validate all input from the core platform; treat SBOMs and advisory data as untrusted until parsed/validated.
* **Observability & quotas:**
* Export plug-in specific metrics (latency, error rate).
* Never bypass quotas; the host decides whether a scan is allowed, not the plug-in.
### 5.2 New modules/services
If you add a new service (e.g., runtime probe, custom advisory indexer):
* Put the design through an ADR + “Module dossier” doc (API, data flow, failure modes).
* Integrate into the release pipeline: lint, tests, SBOM, signing, then (future) Rekor. ([Gitea: Git with a cup of tea][5])
* Confirm the service can run **completely offline** in a lab setup using only OUK + mirrored registries.
---
## 6. Release & CI/CD expectations for implementors
The Release Engineering Playbook is canon for how code becomes a signed, air-gap-friendly release. ([Gitea: Git with a cup of tea][5])
As an implementor:
* **Keep `main` always releasable.** Broken builds break the build, not the process: fix or revert quickly.
* **Wire your changes into the pipeline:**
* Lint and tests for any new language/area you introduce.
* SBOM stage updated to include any new image.
* Signing and OUK stages updated if they touch your artefacts. ([Gitea: Git with a cup of tea][5])
* **Guard offline assumptions:** Add/keep tests that:
* Run the full stack without Internet.
* Verify that SBOMs, attestations, and OUK updates all validate successfully.
---
## 7. Licensing, attribution, and governance
Stella Ops is AGPL-3.0-or-later and the governance docs + release playbook set clear expectations. ([Stella Ops][10])
* **AGPL network clause:** If you run a modified Stella Ops for others over a network, you must provide the source of that exact version. Dont introduce proprietary modules that violate this. ([Stella Ops][10])
* **No hidden SaaS reselling:** Re-hosting as a service is disallowed without prior consent; design and documentation should not encourage “stealth SaaS” business models on top of Stella Ops. ([Gitea: Git with a cup of tea][5])
* **Attribution:** Keep the original Stella Ops attribution in the UI and CLI, even in forks; dont strip branding. ([Gitea: Git with a cup of tea][5])
* **Contribution hygiene:** Ensure all MRs:
* Use DCO / Signed-off-by trailers,
* Include tests + docs,
* Record significant architectural changes in ADRs and module docs. ([Gitea: Git with a cup of tea][5])
---
## 8. A practical “before you merge” checklist
When youre about to merge a feature or module, you should be able to answer “yes” to:
1. Does this feature align with a documented requirement or ADR? ([Gitea: Git with a cup of tea][1])
2. Does it preserve offline-first behavior and deterministic replay?
3. Does it operate on SBOMs as the source of truth and, if relevant, express exploitability via VEX/OpenVEX? ([Gitea: Git with a cup of tea][1])
4. Are provenance, DSSE attestations, and (where implemented) Rekor receipts generated or at least planned? ([Gitea: Git with a cup of tea][5])
5. Are performance, quotas, and Prometheus metrics respected? ([Gitea: Git with a cup of tea][1])
6. Are SBOMs, signatures, and licensing for any new dependencies in order? ([Gitea: Git with a cup of tea][5])
7. Are docs updated (API/CLI reference, module dossier, or user guide where appropriate)? ([Stella Ops][2])
If you want, I can next turn this into a short `docs/dev/implementor-guidelines.md` skeleton you can drop straight into the repo.
[1]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/10212d67c0dfa0dd849fd798c24502b773664749/docs/05_SYSTEM_REQUIREMENTS_SPEC.md "git.stella-ops.org/05_SYSTEM_REQUIREMENTS_SPEC.md at 10212d67c0dfa0dd849fd798c24502b773664749 - git.stella-ops.org - Gitea: Git with a cup of tea"
[2]: https://stella-ops.org/docs/ "Stella Ops Open • Sovereign • Modular container security"
[3]: https://stella-ops.org/ "Stella Ops Open • Sovereign • Modular container security"
[4]: https://cyclonedx.org/capabilities/vex/ "Vulnerability Exploitability eXchange (VEX) | CycloneDX"
[5]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/raw/commit/d0c95cf32874e5b2fe5a7b5fac15cd52f17022b1/docs/13_RELEASE_ENGINEERING_PLAYBOOK.md "git.stella-ops.org"
[6]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/a77eb92feeafb9d0dfc75507a01f9c659db19b08/docs/02_WHY.md "git.stella-ops.org/02_WHY.md at a77eb92feeafb9d0dfc75507a01f9c659db19b08 - git.stella-ops.org - Gitea: Git with a cup of tea"
[7]: https://slsa.dev/spec/v1.0/levels "SLSA • Security levels"
[8]: https://docs.sigstore.dev/logging/overview/ "Rekor - Sigstore"
[9]: https://medium.com/@interlynkblog/implementing-minimum-requirements-for-vex-622f073c2f74 "Implementing Minimum Requirements for VEX | by Interlynk | Medium"
[10]: https://stella-ops.org/license/ "Stella Ops Signed Reachability · Deterministic Replay · Sovereign Crypto"

View File

@@ -0,0 +1,582 @@
I thought you might want a sharper picture of whats out there — and whats credible — for building a compact “golden set” of redistributable fixtures to drop into StellaOps deterministic reachability benchmark. Heres a quick breakdown of the main external benchmark sources that map closely to your list, and what youd get from integrating them.
---
## 🔎 Key benchmark suites & what they bring
### **SV-COMP (C reachability / verification tasks)**
* SV-COMP is the canonical benchmark for software verification tools, providing curated C programs + reachability specs (safety, mem-safety, overflow, termination). ([SV-COMP][1])
* Tasks are published via tagged git releases (e.g., `svcomp25`), so you can reproducibly fetch exact sources and property definitions.
* These tasks give deterministic ground truth about reachability/unreachability.
**Why it matters for StellaOps:** plug in real-world-like C code + formal specs.
### **OSS-Fuzz (reproducer corpus for fuzzed bugs)**
* Each OSS-Fuzz issue includes a deterministic reproducer file. ([Google GitHub][2])
* Replaying the reproducer yields the same crash if the binary & sanitizers are consistent.
* Public corpora can become golden fixtures.
**Why it matters:** covers real-world bugs beyond static properties.
---
## ❌ Not perfectly covered (Tier-2 options)
* Juliet / OWASP / Java/Python suites lack a single authoritative, stable distribution.
* Package snapshots (Debian/Alpine) need manual CVE + harness mapping.
* Curated container images (Vulhub) require licensing vetting and orchestration.
* Call-graph corpora (NYXCorpus, SWARM) have no guaranteed stable labels.
**Implication:** Tier-2 fixtures need frozen versions, harness engineering, and license checks.
---
## ✅ Compact “golden set” candidate
| # | Fixture source | Ground truth |
|---|----------------|--------------|
| 1 | SV-COMP ReachSafety / MemSafety / NoOverflows | C programs + formal reachability specs (no `reach_error()` calls, no overflows). |
| 2 | OSS-Fuzz reproducer corpus (C/C++) | Deterministic crash inputs triggering CVEs. |
| 3 | OSS-Fuzz seed corpus | Known-safe vs bug-triggering inputs for stability comparisons. |
| 4 | Additional SV-COMP categories (Heap, Bitvector, Float) | Broader token coverage. |
| 5 | Placeholder: Debian/Alpine package snapshots | Manual metadata + CVEs; build harnesses. |
| 6 | Placeholder: Java/Python OWASP/Juliet-inspired fixtures | Dynamic languages coverage; custom instrumentation required. |
| 7 | Placeholder: Curated vulnerable container images (Vulhub) | Real-world deployment exposures. |
| 8 | Placeholder: Call-graph corpora (NYXCorpus/SWARM) | Dataflow reachability under complex graphs; requires tooling. |
Start with SV-COMP + OSS-Fuzz as Tier-1; add Tier-2 once harnesses & snapshots are ready.
---
## ⚠️ Watch-outs for Tier-2
* Corpus maintenance (OSS-Fuzz seeds can change) requires freezing sources.
* Label ambiguity: container/Java fixtures must have precise success/failure definitions.
* Licensing/distribution for some corpa/containers must be vetted.
* Call-graph/dynamic cases demand instrumentation to produce deterministic labels.
---
## 🎯 Recommendation
Adopt a “Tier-1 Cadre” (SV-COMP + OSS-Fuzz) for deterministic ground truth. Expand Tier-2 (packages, Java/Python, containers, call graphs) as separate projects with frozen fixtures, metadata (CWE/CVE, PURLs, CycloneDX), and verified harnesses.
Want me to draft an 812 fixture “starter pack” (paths, metadata, PURLs) you can copy into StellaOps? Let me know.
[1]: https://sv-comp.sosy-lab.org/2025/benchmarks.php?utm_source=chatgpt.com "Benchmark Verification Tasks - SV-COMP"
[2]: https://google.github.io/oss-fuzz/advanced-topics/reproducing/?utm_source=chatgpt.com "Reproducing OSS-Fuzz issues"
[3]: https://github.com/google/oss-fuzz/discussions/12278?utm_source=chatgpt.com "Corpus management in OSS-Fuzz"
Good, lets design this as a real “v0.1 Golden Set” spec your team can implement, not just a loose starter pack.
Ill give you:
1. Design goals and constraints
2. Repository layout for the benchmark
3. Fixture metadata schema (YAML)
4. A concrete Core-10 Golden Fixture set (each with purpose & ground truth)
5. How to wire this into StellaOps (Scanner/Sbomer/Vexer/UnknownsRegistry/Authority)
6. A short implementation plan for your team
---
## 1. Design goals & constraints
Non-negotiables:
* **Deterministic**: same input → same graph, same verdicts, same logs; no network, no time, no randomness.
* **Compact**: ~10 tiny fixtures, each buildable and runnable in seconds, small SBOMs.
* **Redistributable**: avoid licensing traps by:
* Preferring **synthetic code** owned by you (MIT/BSD-style).
* For “realistic” CVEs, use **fake local IDs** (e.g. `FAKE-CVE-2025-0001`) and local feeds, not NVD data.
* **Complete chain**: every fixture ships with:
* Source + build recipe
* Binary/container
* CycloneDX SBOM
* Local vulnerability feed entries (OSV-like or your own schema)
* Reference VEX document (OpenVEX or CycloneDX VEX)
* Expected graph revision ID + reachability verdicts
* **Coverage of patterns**:
* Safe vs unsafe variants (Not Affected vs Affected)
* Intra-procedural, inter-procedural, transitive dep
* OS package vs app-level deps
* Multi-language (C, .NET, Java, Python)
* Containerized vs bare-metal
---
## 2. Scope of v0: Core-10 Golden Fixtures
Two tiers, but all small:
* **Core-10** (what you ship and depend on for regression):
* 5 native/C fixtures (classic reachability & library shape)
* 1 .NET fixture
* 1 Java fixture
* 1 Python fixture
* 2 container fixtures (OS package style)
* **Extended-X** (optional later): fuzz-style repros, dynamic imports, concurrency, etc.
Below Ill detail the Core-10 so your team can actually implement them.
---
## 3. Repository layout
Recommended layout inside `stella-ops` mono-repo:
```text
benchmarks/
reachability/
golden-v0/
fixtures/
C-REACH-UNSAFE-001/
C-REACH-SAFE-002/
C-MEM-BOUNDS-003/
C-INT-OVERFLOW-004/
C-LIB-TRANSITIVE-005/
CONTAINER-OSPKG-SAFE-006/
CONTAINER-OSPKG-UNSAFE-007/
JAVA-HTTP-UNSAFE-008/
DOTNET-LIB-PAIR-009/
PYTHON-IMPORT-UNSAFE-010/
feeds/
osv-golden.json # “FAKE-CVE-*” style vulnerabilities
authority/
vex-reference-index.json # mapping fixture → reference VEX + expected verdict
README.md
```
Each fixture folder:
```text
fixtures/<ID>/
src/ # source code (C, C#, Java, Python, Dockerfile...)
build/
Dockerfile # if containerised
build.sh # deterministic build commands
artifacts/
binary/ # final exe/jar/dll/image.tar
sbom.cdx.json # CycloneDX SBOM (canonical, normalized)
vex.openvex.json # reference VEX verdicts
manifest.fixture.yaml
graph.reference.json # canonical normalized graph
graph.reference.sha256.txt # hash = "Graph Revision ID"
docs/
explanation.md # human-readable root-cause + reachability explanation
```
---
## 4. Fixture metadata schema (`manifest.fixture.yaml`)
```yaml
id: "C-REACH-UNSAFE-001"
name: "Simple reachable error in C"
version: "0.1.0"
language: "c"
domain: "native"
category:
- "reachability"
- "control-flow"
ground_truth:
vulnerable: true
reachable: true
cwes: ["CWE-754"] # Improper Check for Unusual or Exceptional Conditions
fake_cves: ["FAKE-CVE-2025-0001"]
verdict:
property_type: "reach_error_unreachable"
property_holds: false
explanation_ref: "docs/explanation.md"
build:
type: "local"
environment: "debian:12"
commands:
- "gcc -O0 -g -o app main.c"
outputs:
binary: "artifacts/binary/app"
run:
command: "./artifacts/binary/app"
args: []
env: {}
stdin: ""
expected:
exit_code: 1
stdout_contains: ["REACH_ERROR"]
stderr_contains: []
# Optional coverage or traces you might add later
coverage_file: null
sbom:
path: "artifacts/sbom.cdx.json"
format: "cyclonedx-1.5"
vex:
path: "artifacts/vex.openvex.json"
format: "openvex-0.2"
statement_ids:
- "vex-statement-1"
graph:
reference_path: "artifacts/graph.reference.json"
revision_id_sha256_path: "artifacts/graph.reference.sha256.txt"
stellaops_tags:
difficulty: "easy"
focus:
- "control-flow"
- "single-binary"
used_by:
- "scanner.webservice"
- "sbomer"
- "vexer"
- "excititor"
```
Your team can add more, but this is enough to wire the benchmark into the pipeline.
---
## 5. Core-10 Golden Fixtures (concrete proposal)
Ill describe each with: purpose, pattern, what the code does, and ground truth.
### 5.1 `C-REACH-UNSAFE-001` basic reachable error
* **Purpose**: baseline reachability detection on a tiny C program.
* **Pattern**: single `main`, simple branch, error sink function `reach_error()`.
* **Code shape**:
* `main(int argc, char** argv)` parses integer `x`.
* If `x == 42`, it calls `reach_error()`, which prints `REACH_ERROR` and exits 1.
* **Ground truth**:
* Vulnerable: `true`.
* Reachable: `true` if run with `x=42` (you fix input in `run.args`).
* Property: “reach_error is unreachable” → `false` (counterexample exists).
* **Why its valuable**:
* Exercises simple control flow; used as “hello world” of deterministic reachability.
### 5.2 `C-REACH-SAFE-002` safe twin of 001
* **Purpose**: same SBOM shape, but no reachable error, to test “Not Affected”.
* **Pattern**: identical to 001 but with an added guard.
* **Code shape**:
* For example, check `x != 42` or remove path to `reach_error()`.
* **Ground truth**:
* Vulnerable: false (no call to `reach_error` at all) *or* treat it as “patched”.
* Reachable: false.
* Property “reach_error is unreachable” → `true`.
* **Why**:
* Used to verify that graph revision is different and VEX becomes “Not Affected” for the same fake CVE (if you model it that way).
### 5.3 `C-MEM-BOUNDS-003` out-of-bounds write
* **Purpose**: exercise memory-safety property and CWE mapping.
* **Pattern**: fixed-size buffer + unchecked copy.
* **Code shape**:
* `char buf[16];`
* Copies `argv[1]` into `buf` with `strcpy` or manual loop without bounds check.
* **Ground truth**:
* Vulnerable: true.
* Reachable: true on any input with length > 15 (you fix a triggering arg).
* CWEs: `["CWE-119", "CWE-120"]`.
* **Expected run**:
* With ASAN or similar, exit non-zero, mention heap/buffer overflow; for determinism, you can standardize to exit code 139 and not rely on sanitizer text in tests.
### 5.4 `C-INT-OVERFLOW-004` integer overflow
* **Purpose**: test handling of arithmetic / overflow-related vulnerabilities.
* **Pattern**: multiplication or addition with insufficient bounds checking.
* **Code shape**:
* Function `size_t alloc_size(size_t n)` that does `n * 16` without overflow checks, then allocates and writes.
* **Ground truth**:
* Vulnerable: true.
* Reachable: true with crafted large `n`.
* CWEs: `["CWE-190", "CWE-680"]`.
* **Why**:
* Lets you validate that your vulnerability feed (fake CVE) asserts “affected” on this component, and your reachability engine confirms the path.
### 5.5 `C-LIB-TRANSITIVE-005` vulnerable library, unreachable in app
* **Purpose**: test the core SBOM→VEX story: component is vulnerable, but not used.
* **Pattern**:
* `libvuln.a` with function `void do_unsafe(char* input)` containing the same OOB bug as 003.
* `app.c` links to `libvuln` but never calls `do_unsafe()`.
* **Code shape**:
* Build static library from `libvuln.c`.
* Build `app` that uses only `do_safe()` from `libvuln.c` or that just links but doesnt call anything from the “unsafe” TU.
* **SBOM**:
* SBOM lists `component: "pkg:generic/libvuln@1.0.0"` with `fake_cves: ["FAKE-CVE-2025-0003"]`.
* **Ground truth**:
* Vulnerable component present in SBOM: yes.
* Reachable vulnerable function: no.
* Correct VEX: “Not Affected: vulnerable code not in execution path for this product”.
* **Why**:
* Canonical demonstration of correct VEX semantics on real-world pattern: vulnerable lib, harmless usage.
---
### 5.6 `CONTAINER-OSPKG-SAFE-006` OS package, unused binary
* **Purpose**: simulate vulnerable OS package installed but unused, to test image scanning vs reachability.
* **Pattern**:
* Minimal container (e.g. `debian:12-slim` or `alpine:3.x`) with installed package `vuln-tool` that is never invoked by the entrypoint.
* Your app is a trivial “hello” binary.
* **SBOM**:
* OS-level components include `pkg:generic/vuln-tool@1.0.0`.
* **Ground truth**:
* Vulnerable: the package is flagged by local feed.
* Reachable: false under the specified `CMD` and test scenario.
* VEX: “Not Affected vulnerable code present but not invoked in products operational context.”
* **Why**:
* Tests that StellaOps does not over-report image-level CVEs when nothing in the products execution profile uses them.
### 5.7 `CONTAINER-OSPKG-UNSAFE-007` OS package actually used
* **Purpose**: same as 006 but positive case: vulnerability is reachable.
* **Pattern**:
* Same base image and package.
* Entrypoint script calls `vuln-tool` with crafted input that triggers the bug.
* **Ground truth**:
* Vulnerable: true.
* Reachable: true.
* This should flip the VEX verdict vs 006.
* **Why**:
* Verifies that your reachability engine + runtime behaviour correctly distinguish “installed but unused” from “installed and actively exploited.”
---
### 5.8 `JAVA-HTTP-UNSAFE-008` vulnerable route in minimal Java service
* **Purpose**: test JVM + HTTP + transitive dep reachability.
* **Pattern**:
* Small Spring Boot or JAX-RS service with:
* `/safe` endpoint using only safe methods.
* `/unsafe` endpoint calling a method in `vuln-lib` that has a simple bug (e.g. path traversal or unsafe deserialization).
* **SBOM**:
* Component `pkg:maven/org.stellaops/vuln-lib@1.0.0` linked to `FAKE-CVE-2025-0004`.
* **Ground truth**:
* For an HTTP call to `/unsafe`, vulnerability reachable.
* For `/safe`, not reachable.
* **Benchmark convention**:
* Fixture defines `run.unsafe` and `run.safe` commands in manifest (two separate “scenarios” under one fixture ID, or two sub-cases in `manifest.fixture.yaml`).
* **Why**:
* Exercises language-level dependency resolution, transitive calls, and HTTP entrypoints.
---
### 5.9 `DOTNET-LIB-PAIR-009` .NET assembly with safe & unsafe variants
* **Purpose**: cover your home turf: .NET 10 / C# pipeline + SBOM & VEX.
* **Pattern**:
* `Golden.Banking.Core` library with method:
* `public void Process(string iban)` → suspicious string parsing / regex or overflow.
* Two apps:
* `Golden.Banking.App.Unsafe` that calls `Process()` with unsafe behaviour.
* `Golden.Banking.App.Safe` that never calls `Process()` or uses a safe wrapper.
* **SBOM**:
* Component `pkg:nuget/Golden.Banking.Core@1.0.0` tied to `FAKE-CVE-2025-0005`.
* **Ground truth**:
* For `App.Unsafe`, vulnerability reachable.
* For `App.Safe`, not reachable.
* **Why**:
* Validates your .NET tooling (Sbomer, scanner.webservice) and that your graphs respect assembly boundaries and call sites.
---
### 5.10 `PYTHON-IMPORT-UNSAFE-010` Python optional import pattern
* **Purpose**: basic coverage for dynamic / interpreted language with optional module.
* **Pattern**:
* `app.py`:
* Imports `helper` which conditionally imports `vuln_mod` when `ENABLE_VULN=1`.
* When enabled, calling `/unsafe` function triggers, e.g., `eval(user_input)`.
* **SBOM**:
* Component `pkg:pypi/vuln-mod@1.0.0``FAKE-CVE-2025-0006`.
* **Ground truth**:
* With `ENABLE_VULN=0`, vulnerable module not imported → unreachable.
* With `ENABLE_VULN=1`, reachable.
* **Why**:
* Simple but realistic test for environment-dependent reachability and Python support.
---
## 6. Local vulnerability feed for the Golden Set
To keep everything sovereign and deterministic, define a small internal OSV-like JSON feed, e.g. `benchmarks/reachability/golden-v0/feeds/osv-golden.json`:
```json
{
"vulnerabilities": [
{
"id": "FAKE-CVE-2025-0001",
"summary": "Reachable error in sample C program",
"aliases": [],
"affected": [
{
"package": {
"ecosystem": "generic",
"name": "C-REACH-UNSAFE-001"
},
"ranges": [{ "type": "SEMVER", "events": [{ "introduced": "0" }] }]
}
],
"database_specific": {
"stellaops_fixture_id": "C-REACH-UNSAFE-001"
}
}
// ... more FAKE-CVE defs ...
]
}
```
Scanner/Feedser in “golden mode” should:
* Use **only** this feed.
* Produce deterministic, closed-world graphs and VEX decisions.
---
## 7. Integration hooks with StellaOps
Make sure each module has a clear use of the golden set:
* **Scanner.Webservice**
* Input: SBOM + local feed for a fixture.
* Output: canonical graph JSON and SHA-256 revision.
* For each fixture, compare produced `revision_id` against `graph.reference.sha256.txt`.
* **Sbomer**
* Rebuilds SBOM from source/binaries and compares it to `artifacts/sbom.cdx.json`.
* Fails test if SBOMs differ in canonicalized form.
* **Vexer / Excititor**
* Ingests graph + local feed and produces VEX.
* Compare resulting VEX to `artifacts/vex.openvex.json`.
* **UnknownsRegistry**
* For v0 you can keep unknowns minimal, but:
* At least one fixture (e.g. Python or container) can contain a “deliberately un-PURL-able” file to confirm it enters Unknowns with expected half-life.
* **Authority**
* Signs the reference artifacts:
* SBOM
* Graph
* VEX
* Ensures deterministic attestation for the golden set (you can later publish these as public reference proofs).
---
## 8. Implementation plan for your team
You can drop this straight into a ticket or doc.
1. **Scaffold repo structure**
* Create `benchmarks/reachability/golden-v0/...` layout as above.
* Add a top-level `README.md` describing goals and usage.
2. **Implement the 10 fixtures**
* Each fixture: write minimal code, build scripts, and `manifest.fixture.yaml`.
* Keep code tiny (13 files) and deterministic (no network, no randomness, no wall time).
3. **Generate SBOMs**
* Use your Sbomer for each artifact.
* Normalize / canonicalize SBOMs and commit them as `artifacts/sbom.cdx.json`.
4. **Define FAKE-CVE feed**
* Create `feeds/osv-golden.json` with 12 entries per fixture.
* Map each entry to PURLs used in SBOMs.
5. **Produce reference graphs**
* Run Scanner in “golden mode” on each fixtures SBOM + feed.
* Normalize graphs (sorted JSON, deterministic formatting).
* Compute SHA-256 → store in `graph.reference.sha256.txt`.
6. **Produce reference VEX documents**
* Run Vexer / Excititor with graphs + feed.
* Manually review results, edit as needed.
* Save final accepted VEX as `artifacts/vex.openvex.json`.
7. **Write explanations**
* For each fixture, add `docs/explanation.md`:
* 510 lines explaining root cause, path, and why affected / not affected.
8. **Wire into CI**
* Add a `GoldenReachabilityTests` job that:
* Builds all fixtures.
* Regenerates SBOM, graph, and VEX.
* Compares against reference artifacts.
* Fail CI if any fixture drifts.
9. **Expose as a developer command**
* Add a CLI command, e.g.:
* `stellaops bench reachability --fixture C-REACH-UNSAFE-001`
* So developers can locally re-run single fixtures during development.
---
If you want, next step I can:
* Take 23 of these fixtures (for example `C-REACH-UNSAFE-001`, `C-LIB-TRANSITIVE-005`, and `DOTNET-LIB-PAIR-009`) and draft **actual code sketches + full `manifest.fixture.yaml`** so your devs can literally copy-paste and start implementing.

View File

@@ -0,0 +1,409 @@
Heres a practical, Stella Opsready checklist for **what a Rekor v2 “receipt” must capture**, plus metadata for air-gapped delivery and deterministic re-verification—mapped to the module that must own each field and why it matters.
*(Quick background: Sigstores Rekor v2 is GA and uses a redesigned, cheaper-to-run transparency log; clients (cosign v2.6+) and bundle format are updated. Receipts/inclusion proofs + bundles enable offline verification and replay.)* ([Sigstore Blog][1])
---
# Must-have (atomic, required)
* **tlog URL (authority endpoint)** → **Authority**
Ensures were verifying against the exact Rekor instance (public or private mirror). Needed to fetch/validate inclusion proofs and checkpoints. ([Sigstore Blog][1])
* **Rekor log public key (or key ID/fingerprint)** → **Authority**
Trust root for verifying Signed Tree Heads (STHs)/checkpoints and inclusion proofs. Store pinned key for 2025 Rekor v2 (and rotation support). ([Sigstore Blog][1])
* **Log checkpoint at verification time (STH digest + tree size + timestamp)** → **Scheduler**
Proves append-only consistency window used during verification; enables later consistency proofs. ([Sigstore Blog][2])
* **Entry locator (UUID and/or log index)** → **Sbomer**
Stable handle to the exact log entry for the artifacts signature/attestation. ([Chainguard Academy][3])
* **Inclusion proof (audit path/merkle hashes)** → **Authority**
Cryptographic proof that the entry is included in the log corresponding to the checkpoint. ([Sigstore][4])
* **Sigstore Bundle (embedded signature/attestation + verification material)** → **Sbomer**
Persist the **Sigstore bundle** emitted by clients (cosign, sigstore-python). It carries the DSSE envelope, certs, TSA timestamp, and (when applicable) transparency details for offline replay. ([Sigstore][5])
* **Fulcio certificate chain (PEM, short-lived)** → **Authority**
Needed to validate keyless identities tied to OIDC claims; keep chain alongside bundle for air-gap. ([Sigstore][6])
* **Subject digest(s) (e.g., image/artifact SHA-256)** → **Sbomer**
Binds the receipt to the exact bits we verified; required to re-prove later. ([OpenSSF][7])
* **Verification policy hash (the policy used at verify time)** → **Vexer**
Pin the exact policy (rules, identity matchers, Rekor requirement) so future re-checks are deterministic. ([OKD Documentation][8])
---
# Nice-to-have (repro, forensics, air-gap)
* **TUF snapshot/version for Rekor/Fulcio bundles** → **Authority**
Records which distributed metadata set was trusted when verifying (key rotations, URL rollout timing). ([Sigstore Blog][1])
* **Client + version (cosign/sigstore-python), verify flags** → **Scheduler**
Replays the same client logic/version; helpful when formats/behaviors change across releases. ([Sigstore Blog][1])
* **Identity claims summary** → **Authority**
Compact snapshot (issuer, subject/email, SANs) for audit trails without re-parsing certs. ([Sigstore][6])
* **Timestamp Authority (TSA) evidence (token/counter-signature)** → **Authority**
Anchors signing time within cert validity; crucial for keyless flows. ([OpenSSF][7])
* **Local mirror info** → **Feedser/Concelier**
Mirror URL, sync height/tree size, mirror key for proving private mirror consistency with public instance. ([OpenSSF][9])
* **Repro inputs hash: policy + trust bundle + Rekor key + toolchain** → **Vexer**
One hash to assert the exact verifier environment used.
* **Attestation payload digest + size (DSSE/intoto)** → **Sbomer**
Guard vs payload truncation and size pitfalls. ([GitHub][10])
* **Monitor evidence: last consistency check** → **Scheduler**
Records proof the log remained consistent between checkpoints. ([Sigstore Blog][2])
---
# Ownership map
* **Authority**: Rekor URL/pkey, Fulcio chain/TSA/TUF refs, inclusion proofs, checkpoints, identity summaries.
* **Sbomer**: bundle blob, entry UUID/index, subject digests, attestation digests/sizes.
* **Vexer (Excititor)**: policy hash, repro hash, uses Authority/Sbomer data for verdicts.
* **Feedser/Concelier**: mirror URLs/heights, provenance of snapshots.
* **Scheduler**: client versions/flags, timestamps, monitor checks.
* **UnknownsRegistry**: tracks missing receipt elements or unverifiable fields for follow-up.
---
# Storage conventions
* **Receipt document**: `application/json` with canonical field order + normalized encodings (PEM → base64 DER) + explicit bytes hash (CID/sha256).
* **Bundle storage**: keep raw Sigstore bundle plus a normalized copy for indexing. ([Sigstore][5])
* **Proof linkage**: store `checkpoint_hash`, `inclusion_proof_hash`, and `bundle_hash` so Vexer can verify all before marking “Verified”.
---
# Air-gapped delivery flow
1. **Seed trust**: ship Rekor public key, Fulcio bundle, TSA root, pinned checkpoint. ([Sigstore Blog][1])
2. **Ship artefact**: Sbomer writes bundle; Authority adds proofs; Scheduler stamps tooling metadata.
3. **Verify offline**: Vexer checks DSSE, Fulcio chain, TSA time, and inclusion proof against pinned data.
4. **Mirror**: Feedser syncs private Rekor mirror; consistency proofs keep it honest. ([OpenSSF][9])
---
# Minimal JSON schema (starter)
```json
{
"tlog": {
"url":"https://rekor.sigstore.dev",
"publicKey":{"type":"pem","fingerprint":"…"},
"checkpoint":{"treeSize":123456,"signedNote":"base64","timestamp":"2025-10-10T12:34:56Z"},
"entry":{"uuid":"…","logIndex":987654},
"inclusionProof":{"hashAlgo":"SHA256","auditPath":["…","…"]}
},
"bundle":{"mediaType":"application/vnd.dev.sigstore.bundle+json;version=…","blob":"base64","digest":"sha256:…"},
"subject":[{"name":"registry/org/app@sha256:…","digest":"sha256:…"}],
"fulcio":{"chainPem":["-----BEGIN CERTIFICATE-----…"]},
"tsa":{"rootPem":"-----BEGIN CERTIFICATE-----…","tokenDigest":"sha256:…"},
"policy":{"id":"vexer-policy-v1","sha256":"…"},
"tooling":{"client":"cosign","version":"v2.6.0","flags":["--bundle","--rekor-url=…"]},
"monitor":{"fromTreeSize":120000,"toTreeSize":123456,"consistencyProof":"sha256:…"},
"provenance":{"tufSnapshot":"…","mirror":{"url":"https://rekor.mirror.local","treeSize":123456,"publicKey":"…"}}
}
```
---
If you want, Ill turn this into `docs/security/receipts.md` plus a C# POCO/EF Core entity so Authority/Sbomer/Vexer can plumb it straight into the data model.
[1]: https://blog.sigstore.dev/rekor-v2-ga/?utm_source=chatgpt.com "Rekor v2 GA - Cheaper to run, simpler to maintain"
[2]: https://blog.sigstore.dev/using-rekor-monitor/?utm_source=chatgpt.com "Using rekor-monitor to Scan Your Transparency Logs"
[3]: https://edu.chainguard.dev/open-source/sigstore/rekor/an-introduction-to-rekor/?utm_source=chatgpt.com "An Introduction to Rekor"
[4]: https://docs.sigstore.dev/logging/overview/?utm_source=chatgpt.com "Rekor"
[5]: https://docs.sigstore.dev/about/bundle/?utm_source=chatgpt.com "Sigstore Bundle Format"
[6]: https://docs.sigstore.dev/about/overview/?utm_source=chatgpt.com "Sigstore: Overview"
[7]: https://openssf.org/blog/2024/05/24/introducing-artifact-attestations-now-in-public-beta/?utm_source=chatgpt.com "Introducing Artifact Attestations—Now in Public Beta"
[8]: https://docs.okd.io/latest/nodes/nodes-sigstore-using.html?utm_source=chatgpt.com "Manage secure signatures with sigstore | Nodes | OKD 4"
[9]: https://openssf.org/blog/2025/10/15/announcing-the-sigstore-transparency-log-research-dataset/?utm_source=chatgpt.com "Announcing the Sigstore Transparency Log Research ..."
[10]: https://github.com/sigstore/cosign/issues/3599?utm_source=chatgpt.com "Attestations require uploading entire payload to rekor #3599"
Heres a practical set of guidelines you can use as a north star when **implementing StellaOps**—both for *platform owners/operators* and for *teams building or extending StellaOps modules*.
Ill structure this as:
1. Crosscutting principles (what must never be broken)
2. A phased implementation roadmap
3. Guidelines by concern (auth, data, CI, observability, offline, security)
4. Short checklists you can literally paste into your runbooks
---
## 1. Crosscutting principles
These are baked into the official StellaOps docs and should guide every implementation decision.([Gitea: Git with a cup of tea][1])
**1.1 Determinism & replay first**
* All “facts” (SBOMs, advisories, VEX, reachability, logs) must be **replayable**:
* Stable JSON key ordering, UTC ISO8601 timestamps, contentaddressed bundles, deterministic hashing.
* Avoid wallclock or “now()” in evaluation paths; Policy Engine and analyzers should be deterministic for the same inputs.([Gitea: Git with a cup of tea][1])
* When in doubt: add a hash or bundle and make it verifiable rather than adding a mutable flag.
**1.2 AggregationOnly ingestion**
* **Concelier** and **Excititor** are *aggregationonly*:
* They ingest, normalise, enrich with provenance and linksets, and write immutable `advisory_raw` / `vex_raw` docs.([Gitea: Git with a cup of tea][2])
* They **must not** compute severity, consensus, suppressions, risk scores, or merges—that belongs to Policy Engine and downstream overlays.([Gitea: Git with a cup of tea][2])
**1.3 Thin gateway, smart services**
* Gateway (or API edge) is **proxy only**:
* AuthN/AuthZ, DPoP verification, scope enforcement, routing.
* No policy overlays, no business logic, no joining evidence there—those live in Policy Engine & domain services.([Gitea: Git with a cup of tea][3])
**1.4 Offlinefirst & sovereignty**
* Assume **airgapped or intermittently connected** operation:
* Design for offline bundles, mirrors, and “kit” updates instead of live internet calls.
* BYO trust roots, regional crypto (FIPS/eIDAS/SM/etc.), and Rekor v2 mirroring are firstclass, not afterthoughts.([Gitea: Git with a cup of tea][1])
**1.5 Modular responsibility boundaries**
From the module cheat sheet: each service has a crisp responsibility; implementations should respect that split.([Gitea: Git with a cup of tea][1])
* **Authority** identity, tokens (OpToks), DPoP/mTLS, audit.
* **Scanner (Web + Worker)** SBOM generation, analysis, replay bundles.
* **Signer & Attestor** DSSE signing, PoE enforcement, Rekor v2 anchoring.
* **Concelier & Excititor** raw advisory & VEX ingest (AggregationOnly Contract).
* **Policy Engine & Scheduler** joins, overlays, scheduling remediation work.
* **Notify, Export Center, UI, CLI, Zastava, Registry Token Service, Graph** UX, notifications, exports, runtime admission, tokens, graph views.
When youre “implementing StellaOps,” youre plugging into this map—dont blur the boundaries.
---
## 2. Phased implementation roadmap
Use this as a sequence for a *new* installation. Its compatible with the official highlevel architecture, quickstart, and platform overview docs.([Gitea: Git with a cup of tea][4])
### Phase 0 Plan environments & infra
* Decide on **envs**: at minimum `dev`, `staging`, `prod`. For regulated/orgs, add `airgappreprod`.
* Stand up shared data plane per cluster:
* MongoDB (canonical store, jobs, overlays).([Gitea: Git with a cup of tea][1])
* MinIO or RustFS/object storage for CAS and replay bundles.([Gitea: Git with a cup of tea][4])
* Queue backend (Redis Streams / NATS / RabbitMQ).([Gitea: Git with a cup of tea][4])
* Telemetry stack (logs, metrics, traces) per `docs/modules/telemetry/architecture.md`.([Gitea: Git with a cup of tea][2])
* For `dev`, you can lean on the **dockercompose skeleton** in the highlevel architecture doc; for `staging/prod`, translate that to Kubernetes with the same service graph.([Gitea: Git with a cup of tea][4])
### Phase 1 Core control plane: Authority, Gateway, Licensing
* Deploy **StellaOps.Authority** with its plugin configuration under `etc/authority.plugins/*.yaml`.([Gitea: Git with a cup of tea][5])
* Wire Authority to your IdP or use the Standard plugin for local users, observing:
* Strong password policies + Argon2id hashing (see cryptography updates).([Gitea: Git with a cup of tea][6])
* Shortlived OpToks, DPoP keypairs in OS keychains, no longlived bearer tokens.([Gitea: Git with a cup of tea][7])
* Introduce an **API Gateway** that:
* Verifies JWT + DPoP, enforces scopes, and forwards to backend services.([Gitea: Git with a cup of tea][3])
* Connect to the **Licensing Service** (`www.stella-ops.org`) to obtain ProofofEntitlement (PoE) for attesting installations, or deliberately run in throttled community mode.([Gitea: Git with a cup of tea][4])
### Phase 2 Scanning & attestation path
* Deploy:
* `StellaOps.Scanner.WebService` and `StellaOps.Scanner.Worker`.
* `StellaOps.Signer` and `StellaOps.Attestor` plus Fulcio/Rekor v2 (or mirror).([Gitea: Git with a cup of tea][4])
* Install **stella CLI** for operators/CI:
* Native AOT binaries, config via `config.yaml` & env vars like `STELLAOPS_AUTHORITY`, `STELLAOPS_SCANNER_URL`, etc.([Gitea: Git with a cup of tea][7])
* Enable Buildx SBOM generation via `StellaOps.Scanner.Sbomer.BuildXPlugin`.([Gitea: Git with a cup of tea][8])
* Validate with the official quickstart:
* `stella auth login` (devicecode) → `stella scan image ... --sbom-type cyclonedx-json`.([Gitea: Git with a cup of tea][9])
### Phase 3 Evidence graph & policy
* Add **Concelier** and **Excititor**:
* Configure connectors for upstream feeds (NVD, distro advisories, GHSA, OSV, vendor VEX, etc.).([Gitea: Git with a cup of tea][1])
* Ensure AOC guards (`StellaOps.Aoc`) and Mongo validators are enabled so `advisory_raw` / `vex_raw` are immutable and compliant.([Gitea: Git with a cup of tea][2])
* Deploy **Policy Engine** and **Scheduler**:
* Policy Engine joins SBOM inventory with raw advisories/VEX, produces `effective_finding_*` collections, and exposes simulation APIs.([Gitea: Git with a cup of tea][1])
* Scheduler watches change streams and impact windows, driving rescans and policy reevaluation.([Gitea: Git with a cup of tea][1])
* Bring up **Notify** for email/chat hooks based on policy events.([Gitea: Git with a cup of tea][1])
### Phase 4 UX, exports, runtime
* Deploy **UI** (Angular SPA) and its backend, **Export Center**, and **Registry Token Service**, then **Zastava** (runtime admission / posture).([Gitea: Git with a cup of tea][1])
* Add **Offline Kit / Export** profiles so you can produce offline bundles for airgapped clusters.([Gitea: Git with a cup of tea][2])
You dont have to do all phases at once; but dont violate the dependencies in the highlevel diagram (e.g., dont run Attestor without Authority & Rekor, dont run Policy without AOCcompliant ingest).([Gitea: Git with a cup of tea][4])
---
## 3. Guidelines by concern
### 3.1 Identity, auth, and RBAC
**Use Authority for everything**
* All services and the CLI should authenticate via **StellaOps.Authority** using OpToks (shortlived JWTs) bound to DPoP or mTLS.([Gitea: Git with a cup of tea][1])
* Scopes are your main guardrail:
* Ingestion: `advisory:ingest`, `vex:ingest`.
* Read: `advisory:read`, `vex:read`, `findings:read`.
* Overlay writes: `effective:write` **Policy Engine only**.([Gitea: Git with a cup of tea][2])
**Separate human vs machine identities**
* Humans:
* Use `auth login --device-code`, with scopes limited to what UI/CLI needs (`scanner.read`, `policy.read`, etc.).([Gitea: Git with a cup of tea][7])
* CI/automation:
* Use clientcredentials, service principals, and tightly scoped audiences (e.g. `scanner`, `attestor`, `export-center`).([Gitea: Git with a cup of tea][7])
**Authority plugin hygiene**
* Implement or configure IdP plugins via `IAuthorityPluginRegistrar`; validate config rigorously in `PostConfigure`.([Gitea: Git with a cup of tea][5])
* Never store secrets in git; rely on `.local.yaml`, env vars, or mounted secret files and document which keys are mandatory.([Gitea: Git with a cup of tea][5])
### 3.2 Data, schemas, and AOC
**Raw vs derived is sacred**
* Raw stores:
* `advisory_raw` and `vex_raw` are appendonly and AOCguarded; only Concelier/Excititor can write there through guarded paths.([Gitea: Git with a cup of tea][2])
* Derived:
* `effective_finding_*` collections are produced by Policy Engine only, using `effective:write` scope. No other service should mutate them.([Gitea: Git with a cup of tea][2])
**Enforce via tooling**
* Enable Mongo schema validators for raw collections and overlays as per platform docs.([Gitea: Git with a cup of tea][2])
* Use `stella aoc verify` in CI whenever ingestion schema/guards change, ensuring no violations creep in.([Gitea: Git with a cup of tea][2])
**No sideroutes to Mongo**
* Application teams must **never** talk to Mongo directly; use module APIs (Scanner, Concelier, Excititor, Policy, Graph) as the abstraction. This keeps AOC/rules enforceable and replayable.([Gitea: Git with a cup of tea][2])
### 3.3 CI/CD and developer workflows
**Configure the CLI predictably**
* Honor the CLI precedence rules: flags → env vars → config file → defaults.([Gitea: Git with a cup of tea][8])
* Standardise envs in pipelines:
* `STELLAOPS_AUTHORITY`, `STELLAOPS_SCANNER_URL`, `STELLAOPS_CONCELIER_URL`, `STELLAOPS_EXCITITOR_URL`, etc.([Gitea: Git with a cup of tea][8])
**SBOMs at build time**
* Prefer the **Buildx plugin** (Sbomer) for SBOM generation:
* `buildx install``buildx build` wrapper injects `--attest=type=sbom,generator=stellaops/sbom-indexer`.([Gitea: Git with a cup of tea][8])
* If Buildx isnt available, fall back to postbuild `stella scan image` with a visible warning in CI.([Gitea: Git with a cup of tea][8])
**Use exit codes & JSON for gating**
* In CI, run in `--json` mode and gate on CLI exit codes:
* `0` = success, `2` = policy fail, `3` = verification fail, `4` = auth error, etc.([Gitea: Git with a cup of tea][8])
* Use Policy preview APIs (`/policy/preview`) to test the effect of new policies before promoting them to production.([Gitea: Git with a cup of tea][10])
### 3.4 Observability & SRE
**Standard metrics & logs**
* Emit and dashboard at least:
* `ingestion_write_total`, `aoc_violation_total{code}`, `ingestion_latency_seconds`.([Gitea: Git with a cup of tea][2])
* Scan & policy latencies, queue depths, worker failures, OpTok issuance/error counts.([Gitea: Git with a cup of tea][4])
* Use structured logs with `traceId`, `tenant`, `source.vendor`, `content_hash` as correlation dimensions.([Gitea: Git with a cup of tea][2])
**Adopt the platform SLO hints**
* Take the latency and throughput targets from the highlevel architecture as initial SLOs:
* P95 buildtime ≤ 35 s on warmed images, policy+VEX ≤ 500 ms for 5k components, etc.([Gitea: Git with a cup of tea][4])
### 3.5 Offline & airgapped operation
**Treat offline sites as firstclass**
* Use **Offline Kits**:
* Bundle raw Mongo snapshots for `advisory_raw`/`vex_raw`, guard configs, verifier binaries, and replay bundles.([Gitea: Git with a cup of tea][2])
* For airgapped clusters:
* Deploy the same service graph (Authority, Scanner, Concelier, Excititor, Policy, etc.), seeded via Offline Kits and Export Center exports.([Gitea: Git with a cup of tea][2])
* Practice DR:
* Test restore-fromsnapshot → replay change streams → revalidate AOC compliance per the platform overview.([Gitea: Git with a cup of tea][2])
### 3.6 Security & crypto
**Centralise signing logic**
* Let **Signer** own all DSSE signing and **Attestor** own Rekor v2 anchoring:
* Clients/CI must never sign directly; they request signed bundles from Signer using PoEvalidated entitlements.([Gitea: Git with a cup of tea][1])
* Use KMS/HSM backed key material where possible; use the CLI KMS verbs (`kms export/import`) for local key workflows in line with the CLI architecture.([Gitea: Git with a cup of tea][7])
**Defensive defaults**
* Enforce rate limiting, sender constraints, and safe crypto providers as described in Authority & crypto docs.([Gitea: Git with a cup of tea][6])
* Never bypass `IAuthorityTokenStore` when revoking or mutating identities; supply machinefriendly `revokedReason` codes so revocation bundles are deterministic.([Gitea: Git with a cup of tea][5])
### 3.7 Governance & change management
* Follow the **DevOps governance rules**:
* Gateway stays thin, ingestion is AOConly, Graph replaces older platforms, and rules are versioned in `docs/devops/contracts-and-rules.md`.([Gitea: Git with a cup of tea][3])
* Treat architecture docs (`07_HIGH_LEVEL_ARCHITECTURE.md`, `platform/architecture-overview.md`, module dossiers) as **source of truth**; when behavior changes, update docs + sprint files, not just code.([Gitea: Git with a cup of tea][4])
---
## 4. Short checklists
You can paste these into your internal docs or tickets.
### 4.1 “Ready for first prod scan?” checklist
* [ ] Authority running with hardened defaults and backed by persistent Mongo.([Gitea: Git with a cup of tea][1])
* [ ] Gateway verifies JWT + DPoP and enforces basic scopes.([Gitea: Git with a cup of tea][3])
* [ ] Mongo, MinIO/RustFS, and queue backend deployed and monitored.([Gitea: Git with a cup of tea][4])
* [ ] Scanner Web + Worker healthy; basic `/health` and `/ready` endpoints pass.([Gitea: Git with a cup of tea][1])
* [ ] Signer, Attestor, Fulcio, Rekor v2 reachable; test DSSE signing + inclusion proof.([Gitea: Git with a cup of tea][4])
* [ ] CLI installed; `stella auth login` and `stella scan image` succeed against a test image in `dev`.([Gitea: Git with a cup of tea][9])
### 4.2 “AOC compliant ingestion?” checklist
* [ ] `StellaOps.Aoc` guard wired into all Concelier/Excititor write paths.([Gitea: Git with a cup of tea][2])
* [ ] Mongo validators enabled for `advisory_raw` and `vex_raw`.([Gitea: Git with a cup of tea][2])
* [ ] Policy Engine is the only holder of `effective:write` scope.([Gitea: Git with a cup of tea][2])
* [ ] `stella aoc verify` job added to CI for ingestion schema changes.([Gitea: Git with a cup of tea][2])
---
If you tell me your role (platform owner vs module implementer vs CI owner) and environment shape (Kubernetes/Compose, airgapped or not), I can turn these into a much more concrete “day1/day2” runbook or a set of internal ADRs.
[1]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/raw/commit/56c687253fbacabc25d8e1944f4fd43cb8dcef9c/AGENTS.md "git.stella-ops.org"
[2]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/61f963fd52cd4d6bb2f86afc5a82eac04c04b00e/docs/modules/platform/architecture-overview.md?utm_source=chatgpt.com "StellaOps Architecture Overview (Sprint 19)"
[3]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/raw/commit/13e4b53dda1575ba46c6188c794fd465ec6fdeec/docs/devops/contracts-and-rules.md?utm_source=chatgpt.com "Raw - Stella Ops"
[4]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/efc4f5f761d1b77c370c7d34d3dd58f786fad617/docs/07_HIGH_LEVEL_ARCHITECTURE.md?utm_source=chatgpt.com "git.stella-ops.org/07_HIGH_LEVEL_ARCHITECTURE.md at ..."
[5]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/8da4e12a90fd82f6b2ec870bb73e0499b4ff6343/docs/dev/31_AUTHORITY_PLUGIN_DEVELOPER_GUIDE.md?utm_source=chatgpt.com "Authority Plug-in Developer Guide - Stella Ops"
[6]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/commits/commit/2e89a92d92387b49a0ce17333fcbaf17f00389e3/docs/07_HIGH_LEVEL_ARCHITECTURE.md?utm_source=chatgpt.com "8 Commits - Stella Ops"
[7]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/240e8ff25ddf0f3385b817c30c26a24bff2e5730/docs/modules/cli/architecture.md?utm_source=chatgpt.com "git.stella-ops.org/architecture.md at ..."
[8]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/commit/e2672ba968a7bd2c935cbc4cb572b383b15c8b07?files=docs%2FARCHITECTURE_CLI.md&utm_source=chatgpt.com "Rewrite architecture docs and add Vexer connector template ..."
[9]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org/src/commit/48702191bed7d66b8e29929a8fad4ecdb40b9490/docs/quickstart.md?utm_source=chatgpt.com "Quickstart First Scan in Five Minutes - Stella Ops"
[10]: https://git.stella-ops.org/stella-ops.org/git.stella-ops.org?utm_source=chatgpt.com "stella-ops.org/git.stella-ops.org - git.stella-ops.org - Stella Ops"

View File

@@ -0,0 +1,861 @@
Heres a crisp, no-drama standup plan with three small wins that unblock bigger work. Background first, then exact tasks you can ship in a day.
---
# 1) Scanner post-mortem → 2 reproducible regressions
**Why:** Post-mortems sprawl. Two bullet-proof repros turn theories into fixable tickets.
**Task today**
* Pick the two highest-impact failure modes (e.g., wrong reachability verdict; missed OSV/CVE due to parser).
* For each, produce a 1-command repro script (Docker image + SBOM fixture) and an **expected vs actual** JSON artifact.
* Store under `tests/scanner/regressions/<case-id>/` with `README.md` and `make test` target.
**Definition of done**
* CI job `Scanner-Regression` runs both and fails deterministically if behavior regresses.
---
# 2) Mongo→Postgres slice prototype (pick one)
**Why:** A focused end-to-end slice beats a giant migration plan.
**Candidates**
* `Authority.Tokens` (licensing/entitlements)
* `Scheduler.Jobs` (enqueued/executed metadata)
* `VEX.Verdicts` (append-only history)
**Task today**
* Draft minimal DDL in `db/pg/migrations/0001_<slice>.sql` and EF Core model.
* Add writer + reader paths behind `I<Slice>Store`; toggle backend using `STORE_BACKEND=Mongo|Postgres`.
* Compose a data-parity test: write N records → read from both stores → byte-compare normalized JSON.
**Definition of done**
* Service boots with `STORE_BACKEND=Postgres`, parity test passes locally, migration cleanly creates/drops the slice.
---
# 3) DSSE + Rekor attestation batch sweep
**Plain English:** sign DSSE envelopes, submit to Rekor, and size batches until failures appear.
**Task today**
* Choose an artifact type (e.g., `scanner-report.json`).
* Implement a tiny CLI/script that signs K reports into DSSE, submits to Rekor/mirror, and logs latency + bytes + success.
* Sweep K in {1,5,10,25,50}, output CSV under `experiments/dsse_rekor/`.
**Definition of done**
* Deliver plot/table with recommended batch size and failure threshold (e.g., “use 10; >25 implies 8% retries”).
---
## Suggested assignments (1-day scope)
* **Alex** → #1 repros
* **Mira** → #2 PG slice (Authority.Tokens)
* **Petar** → #3 DSSE/Rekor sweep
## Ready-to-copy tickets
* **SCN-201:** “Create 2 deterministic regression tests for Scanner failures” (include folder layout + CI target).
* **DB-301:** “Prototype Postgres backend for Authority.Tokens with parity test and feature flag.”
* **SEC-411:** “Run DSSE+Rekor batch sweep for scanner reports; publish CSV and default threshold.”
If you want, I can generate the folders, Makefiles, EF Core stubs, and DSSE/Rekor sweep script next.
Good, this helps narrow the scope. Ill go point by point and then expand #3.
---
## 1) How these fit into Stella Ops, concretely
Think in terms of your core promises / moats:
* Deterministic, replayable scans
* Verifiable SBOM → VEX chain with proofs
* Future-proof data layout (Mongo + “recognized” SQL)
* Proof-of-integrity / Rekor-style transparency
The three tasks line up like this:
### Task 1: Scanner post-mortem → 2 reproducible test cases
**Where it lives:** `scanner.webservice` + your test suite.
**Why it matters for Stella Ops:**
* Your brand is: “we dont silently miss things; if we ever do, it becomes a test forever”.
* Each “failure mode” becomes a **fixture** that:
* feeds into reachability heuristics,
* is later used by Vexer/Excititor to show “weve seen this pattern in the wild and we handle it”.
Its not random QA; its the foundation for your **“golden reachability dataset”** idea from the other branch. Every time you study a competitor miss or your own miss, it turns into:
* “Golden fixture #NN known tricky case, guarded forever by CI”.
So this is directly supporting:
* Deterministic scanner behavior
* Trust Algebra Studio later being able to say: “policy X passes all N golden fixtures”.
Very practical outcome: it gives your devs a **concrete target** instead of a vague “scanner is sometimes wrong”.
---
### Task 2: Postgres without migration: why and how
Youre right: there is no migration today, only **shape-finding**.
You said earlier: “conversion, not migration” and “we use PostgreSQL mainly because of recognition”. That can be turned into something useful now, without over-engineering:
**Goal in this phase**
* Define **one** slice of data model in Postgres that:
* is understandable to auditors / integrators,
* is stable enough that, if you later decide to “convert” Mongo → PG, you already know how it should look,
* forces you to create a clean abstraction (`IWhateverStore`) rather than hard-wiring Mongo into every service.
So instead of “migration plan”, think:
> “We are prototyping a **Postgres-friendly façade** for one core concept, behind an interface.”
Example: `Authority.Tokens` or `Scheduler.Jobs`.
* You keep Mongo as the actual source of truth for now.
* You add a minimal Postgres model in EF Core.
* You add a parity test (write/read in both backends, compare).
* You wire a feature flag like `STORE_BACKEND=Mongo|Postgres` so you can switch environments on/off.
This gives you:
* Early signal about “does this data model work in SQL?”
* A future-proof seam where “conversion” can happen when the product stabilizes.
* Something that looks familiar to enterprise customers (“yes, we have Postgres, here is the schema”).
No migration script, no DMS, just **learning and shaping**.
If you prefer, you can drop the CI parity test and only keep:
* Interface
* Two implementations
* A simple console test or integration test
to keep ceremony minimal while still forcing a clean boundary.
---
## 3) DSSE + Rekor attestation experiment: deeper elaboration
Ill treat this as: “Explain what exactly my team should build and why it matters to Stella Ops.”
### 3.1. Why you care at all
This task supports at least three of your moats:
* **Deterministic replayable scans**
The DSSE envelope + Rekor entry is a cryptographic “receipt” for a given scan + SBOM + VEX result.
* **Proof-of-Integrity Graph / Proof-Market Ledger**
If you later build your own Rekor mirror or “Proof-Market Ledger”, you need to know real batch sizes and behavior now.
* **Crypto-sovereign readiness**
Eventually you want GOST / SM / PQC signatures; this small experiment tells you how your stack behaves with any signature scheme you plug in later.
So were doing **one focused measurement**:
> For *one* type of attestation, find the smallest batch size that:
>
> * keeps latency acceptable,
> * doesnt cause excessive timeouts or retries,
> * doesnt make envelopes so large they become awkward.
This becomes your **default configuration** for Scanner → Attestation → Rekor in all future designs.
---
### 3.2. What exactly to build
Propose a tiny .NET 10 console tool, e.g.:
`src/Experiments/StellaOps.Attest.Bench/StellaOps.Attest.Bench.csproj`
Binary: `stella-attest-bench`
**Inputs**
* A directory with scanner reports, e.g.: `artifacts/scanner-reports/*.json`
* Rekor endpoint and credentials (or test/mirror instance)
* Batch sizes to sweep: e.g. `1,5,10,25,50`
**CLI sketch**
```bash
stella-attest-bench \
--reports-dir ./artifacts/scanner-reports \
--rekor-url https://rekor.stella.local \
--batch-sizes 1,5,10,25,50 \
--out ./experiments/dsse_rekor/results.csv
```
**What each run does**
For each batch size `K`:
1. Take `K` reports from the directory.
2. For each report:
* Wrap into a DSSE envelope:
```json
{
"payloadType": "application/vnd.stellaops.scanner-report+json",
"payload": "<base64(report.json)>",
"signatures": [
{
"keyid": "authority-key-1",
"sig": "<base64(signature-by-key-1)>"
}
]
}
```
* Measure size of the envelope in bytes.
3. Submit the `K` envelopes to Rekor:
* Either one by one, or if your client API supports it, in a single batch call.
* Record:
* start timestamp
* end timestamp
* status (success / failure / retry count)
4. Append a row to `results.csv`:
```csv
timestamp,batch_size,envelopes_count,total_bytes,avg_bytes,latency_ms,successes,failures,retries
2025-11-30T14:02:00Z,10,10,123456,12345.6,820,10,0,0
```
You can enrich it later with HTTP codes, Rekor log index, etc., but this is enough to choose a default.
---
### 3.3. Minimal internal structure
Rough C# layout (no full code, just architecture so devs dont wander):
```csharp
// Program.cs
// - Parse args
// - Build IServiceProvider
// - Resolve and run BenchRunner
public sealed class BenchConfig
{
public string ReportsDirectory { get; init; } = default!;
public Uri RekorUrl { get; init; } = default!;
public int[] BatchSizes { get; init; } = Array.Empty<int>();
public string OutputCsvPath { get; init; } = default!;
}
public sealed class BenchRunner
{
private readonly IDsseSigner _signer;
private readonly IRekorClient _rekor;
private readonly IResultsSink _sink;
public async Task RunAsync(BenchConfig config, CancellationToken ct);
}
// IDsseSigner: wraps "payload" (report json bytes) -> DSSE envelope bytes
// IRekorClient: envelope bytes -> result (success/fail, latency, retries)
// IResultsSink: append rows to CSV
```
Later, `IDsseSigner` and `IRekorClient` can be reused inside a proper `StellaOps.Attest` library that the Scanner or Scheduler use.
---
### 3.4. What “done” looks like in a way that matters to Stella Ops
Not just “we have a toy”. You want a **decision** out of this:
* `DEFAULT_DSSE_BATCH_SIZE = 10`
* “For this Rekor setup, we observe:
* ≤10: 100 % success, latency ~X ms
* 25: occasional retries
* 50: frequent 5xx / timeouts; not recommended”
You then:
* Write this into a short markdown note, e.g.
`docs/attestation/dsse-rekor-batch-sizing.md`
* Use it when designing:
* Scanner → “Attestation job” messages (avoid pushing >10 envelopes at once),
* The future “Proof-Market Ledger” so it doesnt assume unbounded batches,
* Air-gap mirror behavior (“we queue up batches of 10 before syncing”).
So the outcome is a **concrete configuration default and a constraint** that all future modules respect.
---
### If you want to simplify further
If this still feels too heavy for current prototyping speed, the absolute minimum to keep the value:
* Hardcode 2 batch sizes: `1` and `10`.
* Only measure:
* latency
* success/fail
* Print results to stdout instead of CSV.
The key is: **one small executable experiment** that turns “DSSE + Rekor is cool” into “our default batch size is X for environment Y”.
---
If you tell me which module names you want to standardize on for this (e.g. `StellaOps.Attest`, `StellaOps.Experiments`, etc.), I can sketch exact folder names, namespaces, and even a first `.csproj` + `Program.cs` your dev can paste in.
Ill rewrite all three as tight internal guidelines you can drop into `docs/dev/`. Think of each as something you can hand to a new engineer and say: “Follow this exactly.”
---
## G1 · Scanner regression fixtures
**File:** `docs/dev/scanner-regressions.md`
**Applies to:** `scanner.webservice` and any libraries it uses.
### 1. Purpose
Any serious scanner failure must become a deterministic regression fixture. Over time this becomes Stella Ops “golden dataset” for reachability and correctness.
Outcomes:
* Bugs dont repeat silently.
* Heuristics and future policies are validated against the same corpus.
* Postmortems always end with a guardrail in CI.
### 2. When to create a regression fixture
Create a fixture when all three hold:
1. The bug affects at least one of:
* Severity ≥ Medium
* Highvolume ecosystems (OS packages, Java, Python, Node, container base images)
* Core behaviors (reachability, deduplication, suppression, parser correctness)
2. The behavior is reproducible from static inputs (image, SBOM, or manifests).
3. The expected correct behavior is agreed by at least one more engineer on the scanner team.
If in doubt: add the fixture. It is cheap, and it strengthens the golden corpus.
### 3. Directory structure & naming
Test project:
```text
tests/
StellaOps.Scanner.RegressionTests/
Regression/
SCN-0001-missed-cve-in-layer/
SCN-0002-wrong-reachability/
...
```
Fixture layout (example):
```text
SCN-0001-missed-cve-in-layer/
input/
image.sbom.json # or image.tar, etc.
config.json # scanner flags, if needed
expected/
findings.json # canonical expected findings
case.metadata.json # machine-readable description
case.md # short human narrative
```
`case.metadata.json` schema:
```json
{
"id": "SCN-0001",
"title": "Missed CVE-2025-12345 in lower layer",
"kind": "vulnerability-missed",
"source": "internal-postmortem",
"severity": "high",
"tags": [
"reachability",
"language:java",
"package:log4j"
]
}
```
`case.md` should answer:
* What failed?
* Why this case is representative / important?
* What is the correct expected behavior?
### 4. Test harness rules
Global rules for all regression tests:
* No network access (fixtures must be fully selfcontained).
* No timedependent logic (use fixed timestamps if necessary).
* No nondeterministic behavior (seed any randomness).
Comparison rules:
* Normalize scanner output before comparison:
* Sort arrays (e.g. findings).
* Remove volatile fields (generated IDs, timestamps, internal debug metadata).
* Compare canonical JSON (e.g. string equality on normalized JSON).
Implementation sketch (xUnit):
```csharp
public class GoldenRegressionTests
{
[Theory]
[MemberData(nameof(RegressionSuite.LoadCases), MemberType = typeof(RegressionSuite))]
public async Task Scanner_matches_expected_findings(RegressionCase @case)
{
var actual = await ScannerTestHost.RunAsync(@case.InputDirectory);
var expectedJson = File.ReadAllText(@case.ExpectedFindingsPath);
var normalizedActual = FindingsNormalizer.Normalize(actual);
var normalizedExpected = FindingsNormalizer.Normalize(expectedJson);
Assert.Equal(normalizedExpected, normalizedActual);
}
}
```
### 5. How to add a new regression case
Checklist for developers:
1. **Reproduce the bug** using local dev tools.
2. **Minimize the input**:
* Prefer a trimmed SBOM or minimal image over full customer artifacts.
* Remove sensitive data; use synthetic equivalents if needed.
3. **Create folder** under `Regression/SCN-XXXX-short-slug/`.
4. Populate:
* `input/` with all needed inputs (SBOMs, manifests, config).
* `expected/findings.json` with the correct canonical output (not the buggy one).
* `case.metadata.json` and `case.md`.
5. **Run tests** locally:
`dotnet test tests/StellaOps.Scanner.RegressionTests`
6. Fix the scanner behavior (if not already fixed).
7. Ensure tests fail without the fix and pass with it.
8. Open PR with:
* Fixture directory.
* Scanner fix.
* Any harness adjustments.
### 6. CI integration & “done” definition
* CI job `Scanner-Regression` runs in PR validation and main.
* A regression case is “live” when:
* Its present under `Regression/`.
* It is picked up by the harness.
* CI fails if the behavior regresses.
---
## G2 · Postgres slice prototype (shapefinding, no migration)
**File:** `docs/dev/authority-store-backends.md`
**Applies to:** Authority (or similar) services that currently use Mongo.
### 1. Purpose
This is not data migration. It is about:
* Designing a clean storage interface.
* Prototyping a Postgresfriendly schema for one bounded slice (e.g. `Authority.Tokens`).
* Being able to run the service with either Mongo or Postgres behind the same interface.
This supports future “conversion” and enterprise expectations (“we speak Postgres”) without blocking current prototyping speed.
### 2. Scope & constraints
* Scope: one slice only (e.g. tokens, jobs, or VEX verdicts).
* Mongo remains the operational source of truth for now.
* Postgres path is optin via configuration.
* No backward migration or synchronization logic.
### 3. Repository layout
Example for `Authority.Tokens`:
```text
src/
StellaOps.Authority/
Domain/
Token.cs
TokenId.cs
...
Stores/
ITokenStore.cs
MongoTokenStore.cs
PostgresTokenStore.cs
Persistence/
AuthorityPgDbContext.cs
Migrations/
0001_AuthTokens_Init.sql
docs/
dev/
authority-store-backends.md
```
### 4. Store interface design
Guidelines:
* Keep the interface narrow and domaincentric.
* Do not leak Mongo or SQL constructs.
Example:
```csharp
public interface ITokenStore
{
Task<Token?> GetByIdAsync(TokenId id, CancellationToken ct = default);
Task<IReadOnlyList<Token>> GetByOwnerAsync(PrincipalId ownerId, CancellationToken ct = default);
Task SaveAsync(Token token, CancellationToken ct = default);
Task RevokeAsync(TokenId id, RevocationReason reason, CancellationToken ct = default);
}
```
Both `MongoTokenStore` and `PostgresTokenStore` must implement this contract.
### 5. Postgres schema guidelines
Principles:
* Use schemas per bounded context, e.g. `authority`.
* Choose stable primary keys (`uuid` or `bigint`), not composite keys unless necessary.
* Index only for known access patterns.
Example DDL:
```sql
CREATE SCHEMA IF NOT EXISTS authority;
CREATE TABLE IF NOT EXISTS authority.tokens (
id uuid PRIMARY KEY,
owner_id uuid NOT NULL,
kind text NOT NULL,
issued_at_utc timestamptz NOT NULL,
expires_at_utc timestamptz NULL,
is_revoked boolean NOT NULL DEFAULT false,
revoked_at_utc timestamptz NULL,
revoked_reason text NULL,
payload_json jsonb NOT NULL,
created_at_utc timestamptz NOT NULL DEFAULT now(),
updated_at_utc timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_tokens_owner_id
ON authority.tokens (owner_id);
CREATE INDEX IF NOT EXISTS ix_tokens_kind
ON authority.tokens (kind);
```
EF Core:
* Map with `ToTable("tokens", "authority")`.
* Use owned types or value converters for `payload_json`.
### 6. Configuration & feature flag
Configuration:
```jsonc
// appsettings.json
{
"Authority": {
"StoreBackend": "Mongo", // or "Postgres"
"Postgres": {
"ConnectionString": "Host=...;Database=stella;..."
},
"Mongo": {
"ConnectionString": "...",
"Database": "stella_authority"
}
}
}
```
Environment override:
* `AUTHORITY_STORE_BACKEND=Postgres`
DI wiring:
```csharp
services.AddSingleton<ITokenStore>(sp =>
{
var cfg = sp.GetRequiredService<IOptions<AuthorityOptions>>().Value;
return cfg.StoreBackend switch
{
"Postgres" => new PostgresTokenStore(
sp.GetRequiredService<AuthorityPgDbContext>()),
"Mongo" => new MongoTokenStore(
sp.GetRequiredService<IMongoDatabase>()),
_ => throw new InvalidOperationException("Unknown store backend")
};
});
```
### 7. Minimal parity / sanity checks
Given you are still prototyping, keep this light.
Recommended:
* A single test or console harness that:
* Creates a small set of `Token` objects.
* Writes via Mongo and via Postgres.
* Reads back from each and compares a JSON representation of the domain object (ignoring DBspecific metadata).
This is not full data migration testing; it is a smoke check that both backends honor the same domain contract.
### 8. “Done” definition for the first slice
For the chosen slice (e.g. `Authority.Tokens`):
* `ITokenStore` exists, with Mongo and Postgres implementations.
* A Postgres DbContext and first migration are present and runnable.
* The service starts cleanly with `StoreBackend=Postgres` against an empty DB.
* There is at least one automated or scripted sanity check that both backends behave equivalently for typical operations.
* This is documented in `docs/dev/authority-store-backends.md`:
* How to switch backends.
* Current state: “Postgres is experimental; Mongo is default.”
---
## G3 · DSSE + Rekor batchsize experiment
**File:** `docs/attestation/dsse-rekor-batch-sizing.md`
**Applies to:** Attestation / integrity pipeline for scanner reports.
### 1. Purpose
Determine a concrete default batch size for DSSE envelopes submitted to Rekor, balancing:
* Reliability (few or no failures / retries).
* Latency (per batch).
* Envelope size (practical for transport and logging).
Outcome: a hard configuration value, e.g. `DefaultDsseRekorBatchSize = 10`, backed by measurement.
### 2. Scope
* Artifact type: scanner report (e.g. `scanner-report.json`).
* Environment: your current Rekor endpoint (or mirror), not production critical path.
* One small experiment tool, later reusable by attestation services.
### 3. Project structure
```text
src/
Experiments/
StellaOps.Attest.Bench/
Program.cs
BenchConfig.cs
BenchRunner.cs
DsseSigner.cs
RekorClient.cs
ResultsCsvSink.cs
experiments/
dsse_rekor/
results.csv
docs/
attestation/
dsse-rekor-batch-sizing.md
```
### 4. CLI contract
Binary: `stella-attest-bench`
Example usage:
```bash
stella-attest-bench \
--reports-dir ./artifacts/scanner-reports \
--rekor-url https://rekor.lab.stella \
--batch-sizes 1,5,10,25,50 \
--out ./experiments/dsse_rekor/results.csv \
--max-retries 3 \
--timeout-ms 10000
```
Required flags:
* `--reports-dir`
* `--rekor-url`
* `--batch-sizes`
* `--out`
Optional:
* `--max-retries` (default 3)
* `--timeout-ms` (default 10000 ms)
### 5. Implementation guidelines
Core config:
```csharp
public sealed class BenchConfig
{
public string ReportsDirectory { get; init; } = default!;
public Uri RekorUrl { get; init; } = default!;
public int[] BatchSizes { get; init; } = Array.Empty<int>();
public string OutputCsvPath { get; init; } = default!;
public int MaxRetries { get; init; } = 3;
public int TimeoutMs { get; init; } = 10_000;
}
```
Interfaces:
```csharp
public interface IDsseSigner
{
byte[] WrapAndSign(byte[] payload, string payloadType);
}
public interface IRekorClient
{
Task<RekorSubmitResult> SubmitAsync(
IReadOnlyList<byte[]> envelopes,
CancellationToken ct);
}
public interface IResultsSink
{
Task AppendAsync(BatchMeasurement measurement, CancellationToken ct);
}
```
Measurement model:
```csharp
public sealed class BatchMeasurement
{
public DateTime TimestampUtc { get; init; }
public int BatchSize { get; init; }
public int EnvelopeCount { get; init; }
public long TotalBytes { get; init; }
public double AverageBytes { get; init; }
public long LatencyMs { get; init; }
public int SuccessCount { get; init; }
public int FailureCount { get; init; }
public int RetryCount { get; init; }
}
```
Runner outline:
1. Enumerate report files in `ReportsDirectory` (e.g. `*.json`).
2. For each `batchSize`:
* Select up to `batchSize` reports.
* For each report:
* Read bytes.
* Call `IDsseSigner.WrapAndSign` with payload type
`application/vnd.stellaops.scanner-report+json`.
* Track envelope sizes.
* Start stopwatch.
* Submit via `IRekorClient.SubmitAsync` with retry logic honoring `MaxRetries` and `TimeoutMs`.
* Record latency, successes, failures, retries.
* Write one `BatchMeasurement` row to `results.csv`.
CSV headers:
```csv
timestamp_utc,batch_size,envelopes_count,total_bytes,avg_bytes,latency_ms,successes,failures,retries
```
Signer:
* For the experiment, use a local dev key (e.g. Ed25519).
* Make signing deterministic (no random salts that affect envelope size unexpectedly).
Rekor client:
* For this experiment, you only need “accepted or not” plus HTTP status codes; inclusion proof verification is out of scope.
### 6. How to run and interpret
Execution steps:
1. Prepare a folder with representative scanner reports:
* At least 2030 reports from different images, to approximate typical size variance.
2. Ensure the Rekor environment is reachable and not ratelimited.
3. Run the tool with a sweep like `1,5,10,25,50`.
4. Inspect `results.csv`:
* For each batch size, look at:
* Average latency.
* Any nonzero failures or elevated retry counts.
* Total and average bytes per envelope.
Decision rules:
* Pick the largest batch size that:
* Shows 0 failures and acceptable retry counts across multiple runs.
* Keeps latency in a reasonable budget for your pipeline (e.g. under a few seconds per batch).
* Define:
* `DefaultBatchSize` = chosen safe value.
* `HardMaxBatchSize` = first size where failures or unacceptable latency appear.
Document in `docs/attestation/dsse-rekor-batch-sizing.md`:
* Environment details (Rekor version, hardware, network).
* Brief description of report corpus.
* A summarized table from `results.csv`.
* The chosen `DefaultBatchSize` and `HardMaxBatchSize` with a clear statement:
* “All production attestation jobs must respect this default and must not exceed the hard max without a new measurement.”
### 7. “Done” definition
The experiment is “done” when:
* `StellaOps.Attest.Bench` builds and runs with the specified CLI.
* It produces a `results.csv` with one row per `(run, batch_size)` combination.
* There is a written default:
* `DefaultDsseRekorBatchSize = X`
* plus rationale in `dsse-rekor-batch-sizing.md`.
* Future attestation designs (e.g. scanner → ledger pipeline) are required to use that default unless they explicitly update the experiment and the document.
---
If you want, next step can be: convert each of these into actual files (including a minimal `csproj` and `Program.cs` for the bench tool) so your team can copypaste and start implementing.

View File

@@ -0,0 +1,497 @@
Here are **three tightly scoped UI micro-interactions** you can drop into the next front-end sprint. Each maps to a single Angular task and reinforces StellaOps auditability, low-noise VEX gating, and evidence provenance for both air-gapped and online users.
---
# 1) Audit Trail “Why am I seeing this?” (per-row expandable reason)
**Goal:** Make every verdict/action explainable at a glance.
* **User flow:** In Tables (Findings, Components, Policies), each row shows a tiny “ⓘ Why?” chip. Clicking expands an inline panel with the explanation capsule (policy that fired, rule hash, data inputs, and the deterministic graph revision ID).
* **Angular task:**
* Add `ReasonCapsuleComponent` (standalone) with inputs: `policyName`, `ruleId`, `graphRevisionId`, `inputsDigest`, `timestamp`, `actor`.
* Drop it into tables via `*ngTemplateOutlet` so no table refactor.
* Keyboard accessible (Enter/Space toggles).
* **Backend contract (read-only):** `GET /api/audit/reasons/:verdictId`
```json
{
"policy":"Default VEX Merge",
"ruleId":"vex.merge.R12",
"graphRevisionId":"grv_2025-11-18T12:03Z_b3e1",
"inputsDigest":"sha256:…",
"actor":"Vexer",
"ts":"2025-11-18T12:03:22Z"
}
```
* **Acceptance criteria:**
* Toggle persists open/closed per row in URL state (`?open=rid1,rid3`).
* Copy-to-clipboard for `graphRevisionId`.
* Works in offline bundle (served from local API).
---
# 2) Low-noise VEX Gate (inline, gated action with 3 evidence tiers)
**Goal:** Reduce false prompts and only block when evidence is meaningful.
* **User flow:** On risky actions (promote image, approve import), the primary button morphs into a **VEX Gate**: a small dropdown right-aligned to the button label showing **Green/Amber/Red** status with the top blocking reason. Clicking opens a concise sheet (not a modal) with the minimal evidence set, and a single “Proceed anyway” path if policy allows.
* **Angular task:**
* Create `VexGateButtonDirective` that decorates existing `<button>` to append status chip + sheet host.
* Create `VexEvidenceSheetComponent` that renders: top finding, reachability hint, last vendor VEX statement, and policy clause that blocks/allows.
* **Backend contract:** `POST /api/vex/gate` with `{artifactId, action}` →
```json
{
"tier":"amber",
"reason":"Reachable CVE with pending vendor statement",
"policyClause":"gates.required.vendor_vex==true",
"allowBypass":true,
"expires":"2025-12-31T00:00:00Z"
}
```
* **Acceptance criteria:**
* Button aria-label reflects state (“Promote — VEX Amber”).
* Gate sheet loads <300ms cached; falls back to last known cache if offline.
* “Proceed anyway” requires typed confirmation only when `allowBypass=true` and logs an audit event.
---
# 3) Evidence Provenance Chip (DSSE/receipt capture w/ one-tap export)
**Goal:** Make provenance obvious and exportable for audits.
* **User flow:** Wherever we render an SBOM, VEX, or Attestation, show a **Provenance chip** (`Signed • Verified • Logged`) with an overflow menu: **View DSSE**, **View Rekor/Receipt**, **Export bundle (.tar.zst)**. In air-gap mode, the “Logged” badge swaps to “Queued” with a tooltip.
* **Angular task:**
* `ProvenanceChipComponent` with inputs: `sigStatus`, `dsseDigest`, `rekorInclusion`, `queued`.
* `ProvenanceDialogComponent` to show DSSE envelope (pretty-printed), inclusion proof (Merkle path), and copy buttons.
* **Backend contract:**
* `GET /api/provenance/:artifactId` → DSSE envelope + receipt (or offline queue record).
* `POST /api/provenance/export` → streams `application/zstd` containing: envelope, payload, receipt, local trust anchors.
* **Acceptance criteria:**
* Chip states: `Unsigned`, `Signed`, `Verified`, `Verified+Logged`; offline shows `Signed+Queued`.
* Export under 5s for 10MB payloads; filename includes `graphRevisionId`.
* All views work with no internet; if Rekor unreachable, show last cached receipt with “not recently synced” hint.
---
## Dev notes (quick drop-in)
* **Module placement:** `apps/console/src/app/shared/micro/…` (standalone components, tree-shakable).
* **Theme:** Consume existing Tailwind tokens; no new colors (use semantic classes).
* **Testing:**
* Unit: input contracts + a11y snapshot.
* E2E: Cypress happy path per interaction (open/close, bypass, export).
* **Telemetry/Audit:** Emit a single `ui_event` per interaction with `graphRevisionId`, `policyClause`, `artifactId`.
* **Offline kits:** All three rely only on local API; Rekor calls are optional/cached.
If you want, I can turn this into three Jira tickets (with checklists) and a PR scaffold (`ng g component` stubs + sample mocks) so your team can start today.
Heres a **v0.1 “StellaOps UX Guidelines”** you can hand to your UX devs and iterate on. Ill keep it concrete and opinionated, tuned to your world: SBOMs, evidence, attestations, VEX, online + airgap.
---
## 0. Who these guidelines are for
These guidelines are for people who:
* Build UI in Angular for the StellaOps console
* Design workflows around **evidence, SBOMs, VEX, and policy decisions**
* Need to keep **highassurance users** (security, compliance, infra) happy without drowning them in noise
Whenever in doubt: **opt for clarity, traceability, and low noise**.
---
## 1. Core StellaOps UX Principles
These are the “north star” rules. Every screen and interaction should support them:
1. **Everything is explainable**
* Every verdict, badge, and gating decision must have an explicit “why” nearby.
* Implement via the *Reason Capsule* (“Why am I seeing this?” expanders) on rows, cards, and actions.
2. **Evidence in one hop**
* The user should never click more than **once** from a verdict to the underlying evidence (SBOM, attestation, DSSE, log receipt).
* Use: side panel / drawer or inline expansion instead of forcing navigation to a separate page.
3. **Noise is a bug**
* Prompts, warnings, and banners are **exceptions**, not the default.
* High-severity blocking states must be rare, justified, and explicitly tied to a policy clause.
4. **Deterministic, not magical**
* If something is inferred or uncertain, label it clearly (“Inferred reachability”, “Heuristic match”).
* Never present a guess as a fact.
5. **Safe by default, reversible when possible**
* Default to the safer path (e.g., “Block promotion” if in doubt).
* If a potentially risky override is allowed, make it:
* Explicit
* Audited
* Slightly “hard” (typed confirmation, not just a single click)
6. **Online and airgapped parity**
* The same mental model must work whether online or airgapped.
* When external services are unavailable, show **degraded but honest** states (“Verified + Queued” vs “Verified + Logged”).
7. **Fast for experts**
* Keyboard accessible, dense data tables, predictable shortcuts.
* Avoid wizards for frequent tasks; use in-place controls and drawers instead.
---
## 2. Domain model in the UI (what users should always see)
Make these concepts feel consistent across all screens:
* **Artifact**: image, package, or component.
* **Evidence**: SBOMs, attestations, VEX docs, logs, receipts, scans.
* **Policy**: the rules that drive decisions.
* **Verdict / Status**: “Allowed / Blocked / Needs Review / Unknown”.
* **Graph Revision ID**: the immutable “snapshot ID” of the decision state.
* **Audit Event**: who did what, when, and based on which graph revision.
**Guideline:** Any place the user sees a **verdict or action**, they should also see:
* The **policy** that drove it
* The **graph revision ID**
* A one-click path to **evidence** and **audit trail**
Our 3 microinteractions (Reason Capsule, VEX Gate, Provenance Chip) exist to make this easy.
---
## 3. Core Interaction Patterns
### 3.1 Reason Capsule: “Why am I seeing this?”
Used in tables, lists, and detail views.
**Where to place**
* In tables: right side of each row as a small chip or icon: `ⓘ Why?`
* In cards/detail headers: as a text link: “Why this verdict?”
**Behavior**
* Click/Enter/Space toggles an **inline expansion** under the row or section.
* Show:
* Policy name (with pill: e.g., `Policy: Default VEX Merge`)
* Rule ID (e.g., `vex.merge.R12`)
* Graph revision ID (copyable)
* Key inputs (SBOM digest, VEX source, relevant CVE IDs)
* Actor (“Vexer”, “User override: [alice@example.com](mailto:alice@example.com)”)
* Timestamp
**UX rules**
* Keep it **35 lines** max by default; use “Show more” for full detail.
* Always lead with a **plain-language sentence**:
* “This artifact is blocked because policy Prod Promotion requires a vendor VEX statement for reachable critical CVEs.”
* Include a **copy-to-clipboard** affordance for graphRevisionId.
* Remember accessibility:
* `aria-expanded` reflects state
* The expander is focusable and operable via keyboard
---
### 3.2 VEX Gate: Gated primary actions
Used on high-impact actions: promote image, approve import, mark as compliant, etc.
**Pattern**
* Primary button is enhanced by a **VEX status chip**:
* Label pattern: `Promote` + `VEX: Green/Amber/Red` chip.
* Clicking the chip or a small caret opens a **compact sheet** anchored to the button.
* The sheet shows:
* Tier: `Green` (no blocking issues), `Amber` (warning), `Red` (blocking)
* Top reason in plain language
* Policy clause that applies
* Minimal evidence summary: 12 key findings, last vendor VEX statement, reachability
* Whether bypass is allowed and what it implies
**Noise rules**
* Dont show a blocking **modal** unless absolutely necessary:
* Prefer anchored sheets or drawers that dont break context.
* Only require **typed confirmation** if:
* Tier is `Red` **and**
* Policy explicitly allows bypass
**Copy guidelines**
* Green:
* “No blocking VEX findings for this artifact under Prod Promotion policy.”
* Amber:
* “Found reachable CVE with pending vendor VEX. Policy allows promotion with review.”
* Red:
* “Blocking: reachable critical CVE without compensating VEX or mitigation documented.”
**Offline/airgapped**
* If gate info is coming from cache:
* Label: “Based on last local evaluation (not recently synced).”
* The action should still be possible if the **policy** says so, even when external VEX feeds are offline.
---
### 3.3 Provenance Chip: Attestations, DSSE, receipts
Appears next to any evidence object (SBOM, attestation, VEX doc) and on artifact details.
**States**
Use a small chip with an icon + label:
* `Unsigned`
* `Signed`
* `Signed • Verified`
* `Signed • Verified • Logged`
* Offline variant: `Signed • Verified • Queued`
**Behavior**
* Clicking opens a **Provenance dialog**:
* DSSE envelope (structured view with collapsing sections)
* Subject digest(s)
* Inclusion proof / log receipt (if online)
* Trust anchor summary (what keys were trusted)
* Export CTA for full bundle
**Rules**
* The chip state must **never lie**. If Rekor (or similar) is unreachable:
* Show last known receipt + “not recently synced” note.
* Export action:
* Single button: “Export provenance bundle (.tar.zst)”
* Filename should include artifactId and graphRevisionId.
---
## 4. Layout & Information Density
### 4.1 Tables and lists
* Default to **tables** for any list of artifacts, findings, or evidence.
* Per row:
* Left side: identity (name, version, image tag)
* Middle: key status chips (severity, policy verdicts, provenance state)
* Right: row actions + Reason Capsule
**Column order guideline**
1. Artifact / Evidence identifier
2. Primary status (Allowed/Blocked/Needs Review)
3. Severity / Risk
4. Provenance status
5. Last updated / source
6. Actions + “Why?”
Avoid more than **7 columns** at once; beyond that, use:
* Column visibility toggles
* A compact “More details” drawer
### 4.2 Detail views (artifact / policy / evidence)
Use a **two-pane layout**:
* Left: core summary; main actions; VEX Gate button
* Right: tabs or sections: `Evidence`, `Policies`, `Audit trail`
In the summary header:
* Show:
* Artifact identity
* Primary verdict
* Graph revision ID
* Provenance chip
* Provide the **one-tap path** to:
* Policy explanation (Reason Capsule)
* Provenance dialog
---
## 5. Copy & Microcopy Guidelines
Your users are experts; dont over-simplify. But also dont write walls of text.
### 5.1 Tone
* Neutral, precise, never blamey.
* Prefer “This artifact is blocked because…” over “You cant do this because…”.
* Avoid overloaded acronyms unless they are **core to the domain** (SBOM, VEX, CVE are fine).
### 5.2 Phrase patterns
**Verdicts**
* “Allowed by policy X.”
* “Blocked by policy X (rule R12: requires vendor VEX for critical CVEs).”
* “Needs review: incomplete evidence for X.”
**Uncertainty**
* “Inferred reachable based on call graph analysis.”
* “Vendor VEX statement not found in local cache.”
**Offline**
* “Using cached results from 20251129. External logs not reachable.”
**Overrides**
* “Override applied by [alice@example.com](mailto:alice@example.com) on 20251118: promotion allowed despite Red VEX gate.”
### 5.3 Donts
* Dont use “Unknown error”. Always say **what** failed (e.g., “Failed to fetch Rekor receipt: TLS handshake error”).
* Dont just show raw IDs without labels (e.g., “grv_...” → always “Graph revision: grv_...”).
* Dont hide **policy names**; they are how users think about business intent.
---
## 6. States: Loading, Errors, Offline, Edge Cases
### 6.1 Loading
* For tables: use **skeleton rows**, not giant spinners.
* For buttons with gates:
* Show inline “Checking VEX…” with a subtle spinner in the chip area only.
* Maximum loading time before showing a message: ~23 seconds; after that, show:
* “Still evaluating VEX; you can proceed with last known result from 20251118, or wait.”
### 6.2 Error states
For any failed fetch related to:
* Provenance
* Log receipts
* Policy evaluation
…show:
* A neutral banner in the relevant area:
* “Could not refresh provenance from log. Using last known verification from 20251110.”
* A clear fallback behavior:
* Block or proceed according to **policy**, not “best guess”.
### 6.3 Offline & Airgapped
**Golden rule:** Never pretend to be online when youre not.
* Make offline clearly visible but not screaming:
* Small badge in the header: `Air-gapped mode` or `Offline mode`
* Provenance chip:
* Use the `Queued` variant when receipts havent been synced.
* Export path:
* Always work without internet (local export).
---
## 7. Accessibility & Keyboard Support
Your users will live in this tool; keyboard and a11y arent nice-to-haves.
**Minimums**
* All interactive chips (Reason Capsule, Provenance Chip, VEX Gate) must:
* Be reachable via Tab
* Be clickable via Enter / Space
* Have descriptive `aria-label`s (e.g., “Explain verdict for artifact nginx:1.24.0”)
* Use **visible focus outlines** that fit your design tokens.
* Do not rely solely on color:
* VEX tiers need both color and text (`Green`, `Amber`, `Red`).
---
## 8. Implementation Handshake (Design ⇄ Dev)
A simple workflow you can standardize on:
1. **Design defines the pattern**
* For each reusable microinteraction (Reason Capsule, VEX Gate, Provenance Chip), the designer:
* Specifies inputs/props
* Lists states (default, loading, error, offline)
* Provides content examples
2. **Dev builds a standalone Angular component**
* One component per pattern:
* `ReasonCapsuleComponent`
* `VexGateButtonDirective + VexEvidenceSheetComponent`
* `ProvenanceChipComponent + ProvenanceDialogComponent`
* All styling via shared tokens (no hardcoded colors).
3. **Shared acceptance criteria**
* Each pattern must have:
* a11y behavior defined
* Loading and error behavior defined
* At least one **offline** scenario defined
* E2E check:
* Can a user go from a verdict to:
1. Why it happened,
2. Evidence that supports it,
3. Audit record of who acted
…in **≤ 2 clicks**?
---
## 9. Quick “Do This, Not That” Cheat Sheet
* **Do:** Show `Blocked • Why?` → inline explanation → evidence link
**Dont:** Show just `Blocked` with no context.
* **Do:** Attach VEX Gate logic to existing primary buttons as a small extension.
**Dont:** Introduce a separate, second “Check VEX” action the user has to remember.
* **Do:** Use small chips for provenance state (`Signed • Verified • Logged`).
**Dont:** Hide signature/log info in a separate “Advanced” tab.
* **Do:** Be honest about offline/cached states.
**Dont:** Fake a “Verified + Logged” status when the log sync actually failed.
---
If youd like, I can also turn this into:
* A one-page **“UX checklist per screen”** your devs can run through before shipping, and
* Concrete Angular interface definitions for each of the shared components so design/dev are literally talking about the same props.

View File

@@ -0,0 +1,716 @@
Heres a compact, low-friction way to tame “unknowns” in Stella Ops without boiling the ocean: two heuristics you can prototype this week—each yields one clear artifact you can show in the UI and wire into the next planning cycle.
---
# 1) Decaying Confidence (Half-Life) for Unknown Reachability
**Idea:** every “unknown” reachability/verdict starts with a confidence score that **decays over time** (exponential half-life). If no new evidence arrives, confidence naturally drifts toward “needs refresh,” preventing stale assumptions from lingering.
**Why it helps (plain English):** unknowns dont stay “probably fine” forever—this makes them self-expiring, so triage resurfaces them at the right time instead of only when something breaks.
**Minimal data model (UnknownsRegistry):**
```json
{
"unknown_id": "URN:unknown:pkg/npm/lodash:4.17.21:CVE-2021-23337:reachability",
"subject_ref": { "type": "package", "purl": "pkg:npm/lodash@4.17.21" },
"vuln_id": "CVE-2021-23337",
"dimension": "reachability",
"confidence": { "value": 0.78, "method": "half_life", "t0": "2025-11-29T12:00:00Z", "half_life_days": 14 },
"evidence": [{ "kind": "static_scan_hint", "hash": "…" }],
"next_review_at": "2025-12-06T12:00:00Z",
"status": "unknown"
}
```
**Update rule (per tick or on read):**
* `confidence_now = confidence_t0 * 0.5^(Δdays / half_life_days)`
* When `confidence_now < threshold_low` → flag for human review (see Queue below).
* When fresh evidence arrives → reset `t0`, optionally raise confidence.
**One UI artifact:**
A **“Confidence Decay Card”** on each unknown, showing:
* sparkline of decay over time,
* next review ETA,
* button “Refresh with latest evidence” (re-run reachability probes).
**One ops hook (planning):**
Export a **daily CSV/JSON of unknowns whose confidence crossed threshold** to feed the triage board.
---
# 2) Human-Review Queue for High-Impact Unknowns
**Idea:** only a subset of unknowns deserve people time. Auto-rank them by potential blast radius + decayed confidence.
**Triage score (simple, transparent):**
`triage_score = impact_score * (1 - confidence_now)`
* `impact_score` (01): runtime exposure, privilege, prevalence, SLA tier.
* `confidence_now`: from heuristic #1.
**Queue item schema (artifact to display & act on):**
```json
{
"queue_item_id": "TRIAGE:unknown:…",
"unknown_id": "URN:unknown:…",
"triage_score": 0.74,
"impact_factors": { "runtime_presence": true, "privilege": "high", "fleet_prevalence": 0.62, "sla_tier": "gold" },
"confidence_now": 0.28,
"assigned_to": "unassigned",
"due_by": "2025-12-02T17:00:00Z",
"actions": [
{ "type": "collect_runtime_trace", "cost": "low" },
{ "type": "symbolic_slice_probe", "cost": "medium" },
{ "type": "vendor_VEX_request", "cost": "low" }
],
"audit": [{ "at": "2025-11-29T12:05:00Z", "who": "system", "what": "enqueued: threshold_low crossed" }]
}
```
**One UI artifact:**
A **“High-Impact Unknowns” queue view** sorted by `triage_score`, showing:
* pill tags for impact factors,
* inline actions (Assign, Probe, Add Evidence, Mark Resolved),
* SLO badge showing `due_by`.
**One ops hook (planning):**
Pull top N items by `triage_score` at sprint start. Each resolved item must attach new evidence or a documented “Not Affected” rationale so the next decay cycle begins from stronger assumptions.
---
## Wiring into Stella Ops quickly (dev notes)
* **Storage:** add `UnknownsRegistry` collection/table; compute decay on read to avoid cron churn.
* **Thresholds:** start with `half_life_days = 14`, `threshold_low = 0.35`; tune later.
* **Impact scoring:** begin with simple weights in config (runtime_presence=0.4, privilege=0.3, prevalence=0.2, SLA=0.1).
* **APIs:**
* `GET /unknowns?stale=true` (confidence < threshold)
* `POST /triage/enqueue` (system-owned)
* `POST /unknowns/{id}/evidence` (resets t0, recomputes next_review_at)
* **Events:** emit `UnknownConfidenceCrossedLow` `TriageItemCreated`.
---
## What youll have after a 12 day spike
* A decay card on each unknown + a simple, sortable triage queue.
* A daily export artifact to drive planning.
* A clear, auditable path from were unsure we gathered evidence were confident (for now).”
If you want, I can generate:
* the C# POCOs/EF mappings,
* a minimal Controller set,
* Angular components (card + queue table),
* and seed data + an evaluator that computes `confidence_now` and `triage_score` from config.
Cool, lets turn those two sketchy heuristics into something you can actually ship and iterate on in StellaOps.
Ill go deeper on:
1. Decaying confidence as a proper firstclass concept
2. The triage queue and workflow around unknowns
3. A lightweight unknown budget / guardrail layer
4. Concrete implementation sketches (data models, formulas, pseudocode)
5. How this feeds planning & metrics
---
## 1) Decaying Confidence: From Idea to Mechanism
### 1.1 What “confidence” actually means
To keep semantics crisp, define **confidence** as:
> “How fresh and wellsupported our knowledge is about this vulnerability in this subject along this dimension (reachability, exploitability, etc.).”
* `1.0` = Recently assessed with strong evidence
* `0.0` = We basically havent looked / our info is ancient
This works for **unknown**, **knownaffected**, and **knownnotaffected**; decay is about **knowledge freshness**, not the verdict itself.
For unknowns, confidence will usually be low and decaying thats what pushes them into the queue.
### 1.2 Data model v2 (UnknownsRegistry)
Extend the earlier object a bit:
```jsonc
{
"unknown_id": "URN:unknown:pkg/npm/lodash:4.17.21:CVE-2021-23337:reachability",
"subject_ref": {
"type": "package", // package | service | container | host | cluster
"purl": "pkg:npm/lodash@4.17.21",
"service_id": "checkout-api",
"env": "prod" // prod | staging | dev
},
"vuln_id": "CVE-2021-23337",
"dimension": "reachability", // reachability | exploitability | fix_validity | other
"state": "unknown", // unknown | known_affected | known_not_affected | ignored
"unknown_cause": "tooling_gap", // data_missing | vendor_silent | tooling_gap | conflicting_evidence
"confidence": {
"value": 0.62, // computed on read
"method": "half_life",
"t0": "2025-11-29T12:00:00Z",
"value_at_t0": 0.9,
"half_life_days": 14,
"threshold_low": 0.35,
"threshold_high": 0.75
},
"impact": {
"runtime_presence": true,
"internet_exposed": true,
"privilege_level": "high",
"data_sensitivity": "pii", // none | internal | pii | financial
"fleet_prevalence": 0.62, // fraction of services using this
"sla_tier": "gold" // bronze | silver | gold
},
"next_review_at": "2025-12-06T12:00:00Z",
"owner": "team-checkout",
"created_at": "2025-11-29T12:00:00Z",
"updated_at": "2025-11-29T12:00:00Z",
"evidence": [
{
"kind": "static_scan_hint",
"summary": "No direct call from public handler to vulnerable sink found.",
"created_at": "2025-11-29T12:00:00Z",
"link": "https://stellaops/ui/evidence/123"
}
]
}
```
Key points:
* `unknown_cause` helps you slice unknowns by why do we not know?” (lack of data vs tooling vs vendor).
* `impact` is embedded here so triage scoring can be local without joining a ton of tables.
* `half_life_days` can be **per dimension & per environment**, e.g.:
* prod + reachability 7 days
* staging + fix_validity 30 days
### 1.3 Decay math & scheduling
Use exponential decay:
```text
confidence(t) = value_at_t0 * 0.5^(Δdays / half_life_days)
```
Where:
* `Δdays = (now - t0) in days`
On write (when you update or create the record), you:
1. Compute `value_now` from any previous state.
2. Apply bump/delta based on new evidence (bounded by 0..1).
3. Set `value_at_t0 = value_now_after_bump`, `t0 = now`.
4. Precompute `next_review_at` = when `confidence(t)` will cross `threshold_low`.
Pseudocode for step 4:
```csharp
double DaysUntilThreshold(double valueAtT0, double threshold, double halfLifeDays)
{
if (valueAtT0 <= threshold) return 0;
// threshold = valueAtT0 * 0.5^(Δ/halfLife)
// Δ = halfLife * log(threshold/valueAtT0) / log(0.5)
return halfLifeDays * Math.Log(threshold / valueAtT0) / Math.Log(0.5);
}
```
Then:
```csharp
var days = DaysUntilThreshold(valueAtT0, thresholdLow, halfLifeDays);
nextReviewAt = now.AddDays(days);
```
**Important:** this gives you a **cheap query** to build the queue:
```sql
SELECT * FROM UnknownsRegistry
WHERE state = 'unknown'
AND next_review_at <= now();
```
No cronbased bulk recomputation necessary.
### 1.4 Events that bump confidence
Any new evidence should refresh knowledge and adjust confidence:
Examples:
* **Runtime traces showing the vulnerable function never called in a hot path**
bump reachability confidence up moderately (e.g. +0.2, capped at 0.9).
* **Symbolic or fuzzing probe explicitly drives execution into the vulnerable code**
flip `state = known_affected`, set confidence close to 1.0 with longer halflife.
* **Vendor VEX: NOT AFFECTED**
flip `state = known_not_affected`, long halflife (6090 days), high confidence.
* **New major release, infra changes, or new internet exposure**
degrade confidence (e.g. 0.3) because architecture changed.
Implement this as a simple rules table:
```jsonc
{
"on_evidence": [
{
"when": { "kind": "runtime_trace", "result": "no_calls_observed" },
"dimension": "reachability",
"delta_confidence": +0.2,
"half_life_days": 14
},
{
"when": { "kind": "runtime_trace", "result": "calls_into_vuln" },
"dimension": "reachability",
"set_state": "known_affected",
"set_confidence": 0.95,
"half_life_days": 21
},
{
"when": { "kind": "vendor_vex", "result": "not_affected" },
"set_state": "known_not_affected",
"set_confidence": 0.98,
"half_life_days": 60
}
]
}
```
### 1.5 UI for decaying confidence
On the **Unknown Detail page**, you can show:
* **Confidence chip**:
* Knowledge freshness: 0.28 (stale)” with a color gradient.
* **Decay sparkline**: small chart showing confidence over the last 30 days.
* **Next review**: Next review recommended by Dec 2, 2025 (in 3 days)”
* **Evidence stack**: timeline of evidence events with icons (static scan, runtime, vendor, etc.).
* **Actions area**: Refresh now Trigger runtime probe / request VEX / open Jira”.
All of that makes the heuristic feel concrete and gives engineers a mental model:
this is decaying; heres when we revisit; heres how to add evidence.”
---
## 2) Triage Queue for HighImpact Unknowns: Making It Useful
The goal: **reduce an ocean of unknowns to a small, actionable queue** that:
* Is **ranked by risk**, not noise
* Has clear **owners and due dates**
* Plugs cleanly into teams existing planning
### 2.1 Impact scoring, more formally
Define a normalized **impact score** `I` between 0 and 1:
```text
I = w_env * EnvExposure
+ w_data * DataSensitivity
+ w_prevalence * Prevalence
+ w_sla * SlaCriticality
+ w_cvss * CvssSeverity
```
Where each factor is also 01:
* `EnvExposure`:
* prod + internet_exposed 1.0
* prod + internal only 0.7
* nonprod 0.3
* `DataSensitivity`:
* none 0.0, internal 0.3, pii 0.7, financial/health 1.0
* `Prevalence`:
* fraction of services/assets affected (0..1)
* `SlaCriticality`:
* bronze 0.3, silver 0.6, gold 1.0
* `CvssSeverity`:
* use CVSS normalized to 0..1 if you have it, otherwise approximate from critical/high/med/low”.
Weights `w_*` configurable, e.g.:
```text
w_env = 0.3
w_data = 0.25
w_prevalence = 0.15
w_sla = 0.15
w_cvss = 0.15
```
These can live in a tenantlevel config.
### 2.2 Triage score
You already had the core idea:
```text
triage_score = Impact * (1 - ConfidenceNow)
```
You can enrich this slightly with recency:
```text
RecencyBoost = min(1.2, 1.0 + DaysSinceCreated / 30 * 0.2)
triage_score = Impact * (1 - ConfidenceNow) * RecencyBoost
```
So very old unknowns with low confidence get a slight bump to avoid being buried forever.
### 2.3 Queue item lifecycle
Represent queue items as a simple workflow:
```jsonc
{
"queue_item_id": "TRIAGE:unknown:…",
"unknown_id": "URN:unknown:…",
"triage_score": 0.81,
"status": "open", // open | in_progress | blocked | resolved | wont_fix
"reason_blocked": null,
"owner_team": "team-checkout",
"assigned_to": "alice",
"created_at": "2025-11-29T12:05:00Z",
"due_by": "2025-12-02T17:00:00Z",
"required_outcome": "add_evidence_or_verdict", // tasks that actually change state
"suggested_actions": [
{ "type": "collect_runtime_trace", "cost": "low" },
{ "type": "symbolic_slice_probe", "cost": "medium" },
{ "type": "vendor_VEX_request", "cost": "low" }
],
"audit": [
{
"at": "2025-11-29T12:05:00Z",
"who": "system",
"what": "enqueued: confidence below threshold_low; I=0.9, C=0.21"
}
]
}
```
Rules:
* Queue item is (re)created automatically when unknowns `next_review_at <= now` **and** impact above a minimum threshold.
* When an engineer **adds evidence** or changes `state` on the underlying unknown, the system:
* Recomputes confidence, impact, triage_score
* Closes the queue item if confidence now > `threshold_high` or state != unknown
* You can allow **reopen** if it decays again later.
### 2.4 Queue UI & ops hooks
In UI, the **“HighImpact Unknowns”** view shows:
Columns:
* Unknown (vuln + subject)
* State (always “unknown” here, but futureproof)
* Impact badge (Low/Med/High/Critical)
* Confidence chip
* Triage score (sortable)
* Owner team
* Due by
* Quick actions
Interactions:
* Default filter: `impact >= High` AND `env = prod`
* Perteam view: filter owner_team = “teamX”
* Bulk ops: “Assign top 10 to me”, “Open Jira for selected” etc.
Ops hooks:
* **Daily digest** to each team: “You have 5 highimpact unknowns due this week.”
* **Planning export**: per sprint, each team looks at “Top N unknowns by triage_score” and picks some into the sprint.
* **SLO integration**: if teams “unknown budget” (see below) is overrun, they must schedule unknown work.
### 2.5 Example: one unknown from signal to closure
1. New CVE hits; SBOM says `checkout-api` uses affected library.
* Unknown created with:
* Impact ≈ 0.9 (prod, internet, PII, critical CVE)
* Confidence = 0.4 (all we know is “it exists”).
* `triage_score ≈ 0.9 * (1 - 0.4) = 0.54` → high enough to enqueue.
2. Engineer collects runtime trace, sees no calls to vulnerable path under normal traffic.
* Evidence added, confidence bumped to 0.75, halflife 14 days.
* Queue item autoresolves if your `threshold_high` is 0.7.
3. Two months later, architecture changes, service gets a new public endpoint.
* Deployment event triggers an automatic “degrade confidence” rule (0.2), sets new `t0` and shorter halflife.
* `next_review_at` moves closer; unknown reenters queue later.
This gives you **continuously updating risk** without manual spreadsheets.
---
## 3) Unknown Budget & Guardrails (Optional but Powerful)
To connect this to leadership/SRE conversations, define an **“unknown budget”** per service/team:
> A target maximum risk mass of unknowns were willing to tolerate.
### 3.1 Perunknown “risk units”
For each unknown, define:
```text
risk_units = Impact * (1 - ConfidenceNow)
```
(Its literally the triage score, but aggregated differently.)
Per team or service:
```text
unknown_risk_budget = sum(risk_units for that team/service)
```
You can then set **guardrails**, e.g.:
* Goldtier service: budget ≤ 5.0
* Silver: ≤ 15.0
* Bronze: ≤ 30.0
### 3.2 Guardrail behaviors
If a team exceeds its budget:
* Show warnings in the StellaOps UI on the service details page.
* Add a banner in the highimpact queue: “Unknown budget exceeded by 3.2 units.”
* Optional: feed into deployment checks:
* Above 2× budget → require security approval before prod deploy.
* Above 1× budget → must plan unknown work in next sprint.
This ties the heuristics to behavior change without being draconian.
---
## 4) Implementation Sketch (API & Code)
### 4.1 C# model sketch
```csharp
public enum UnknownState { Unknown, KnownAffected, KnownNotAffected, Ignored }
public sealed class UnknownRecord
{
public string Id { get; set; } = default!;
public string SubjectType { get; set; } = default!; // "package", "service", ...
public string? Purl { get; set; }
public string? ServiceId { get; set; }
public string Env { get; set; } = "prod";
public string? VulnId { get; set; } // CVE, GHSA, etc.
public string Dimension { get; set; } = "reachability";
public UnknownState State { get; set; } = UnknownState.Unknown;
public string UnknownCause { get; set; } = "data_missing";
// Confidence fields persisted
public double ConfidenceValueAtT0 { get; set; }
public DateTimeOffset ConfidenceT0 { get; set; }
public double HalfLifeDays { get; set; }
public double ThresholdLow { get; set; }
public double ThresholdHigh { get; set; }
public DateTimeOffset NextReviewAt { get; set; }
// Impact factors
public bool RuntimePresence { get; set; }
public bool InternetExposed { get; set; }
public string PrivilegeLevel { get; set; } = "low";
public string DataSensitivity { get; set; } = "none";
public double FleetPrevalence { get; set; }
public string SlaTier { get; set; } = "bronze";
// Ownership & audit
public string OwnerTeam { get; set; } = default!;
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
}
```
Helper to compute `ConfidenceNow`:
```csharp
public static class ConfidenceCalculator
{
public static double ComputeNow(UnknownRecord r, DateTimeOffset now)
{
var deltaDays = (now - r.ConfidenceT0).TotalDays;
if (deltaDays <= 0) return Clamp01(r.ConfidenceValueAtT0);
var factor = Math.Pow(0.5, deltaDays / r.HalfLifeDays);
return Clamp01(r.ConfidenceValueAtT0 * factor);
}
public static (double valueAtT0, DateTimeOffset t0, DateTimeOffset nextReviewAt)
ApplyEvidence(UnknownRecord r, double deltaConfidence, double? newHalfLifeDays, DateTimeOffset now)
{
var current = ComputeNow(r, now);
var updated = Clamp01(current + deltaConfidence);
var halfLife = newHalfLifeDays ?? r.HalfLifeDays;
var daysToThreshold = DaysUntilThreshold(updated, r.ThresholdLow, halfLife);
var nextReview = now.AddDays(daysToThreshold);
return (updated, now, nextReview);
}
private static double DaysUntilThreshold(double valueAtT0, double threshold, double halfLifeDays)
{
if (valueAtT0 <= threshold) return 0;
return halfLifeDays * Math.Log(threshold / valueAtT0) / Math.Log(0.5);
}
private static double Clamp01(double v) => v < 0 ? 0 : (v > 1 ? 1 : v);
}
```
Queue scoring:
```csharp
public sealed class TriageConfig
{
public double WEnv { get; set; } = 0.3;
public double WData { get; set; } = 0.25;
public double WPrev { get; set; } = 0.15;
public double WSla { get; set; } = 0.15;
public double WCvss { get; set; } = 0.15;
public double MinImpactForQueue { get; set; } = 0.4;
public double MaxRecencyBoost { get; set; } = 1.2;
}
public static class TriageScorer
{
public static double ComputeImpact(UnknownRecord r, double cvssNorm, TriageConfig cfg)
{
var env = r.Env == "prod"
? (r.InternetExposed ? 1.0 : 0.7)
: 0.3;
var data = r.DataSensitivity switch
{
"none" => 0.0,
"internal" => 0.3,
"pii" => 0.7,
"financial" => 1.0,
_ => 0.3
};
var sla = r.SlaTier switch
{
"bronze" => 0.3,
"silver" => 0.6,
"gold" => 1.0,
_ => 0.3
};
var prev = Math.Max(0, Math.Min(1, r.FleetPrevalence));
return cfg.WEnv * env
+ cfg.WData * data
+ cfg.WPrev * prev
+ cfg.WSla * sla
+ cfg.WCvss * cvssNorm;
}
public static double ComputeTriageScore(
UnknownRecord r,
double cvssNorm,
DateTimeOffset now,
DateTimeOffset createdAt,
TriageConfig cfg)
{
var impact = ComputeImpact(r, cvssNorm, cfg);
var confidence = ConfidenceCalculator.ComputeNow(r, now);
if (impact < cfg.MinImpactForQueue) return 0;
var ageDays = (now - createdAt).TotalDays;
var recencyBoost = Math.Min(cfg.MaxRecencyBoost, 1.0 + (ageDays / 30.0) * 0.2);
return impact * (1 - confidence) * recencyBoost;
}
}
```
This is all straightforward to wire into your existing C#/Angular stack.
---
## 5) How This Feeds Planning & Metrics
Once this is live, you get a bunch of useful knobs for product and leadership:
### 5.1 Perteam dashboards
For each team/service, show:
* **Unknown count** (total & by dimension)
* **Unknown risk budget** (current vs target)
* **Distribution of confidence** (e.g., histogram buckets: 00.25, 0.250.5, etc.)
* **Average age of unknowns**
* **Queue throughput**:
* # of unknowns investigated this sprint
* Average time from `enqueued → evidence added/ verdict`
These tell you if teams are actually burning down epistemic risk or just tagging things.
### 5.2 Process metrics to tune heuristics
Every quarter, look at:
* How many unknowns **reenter the queue** because decay hits threshold?
* For unknowns that later become **knownaffected incidents**, what were their triage scores?
* If many “incidentcausing unknowns” had low triage scores, adjust weights.
* Are teams routinely ignoring certain impact factors (e.g., low data sensitivity)?
* Maybe reduce weight or adjust scoring.
Because the heuristics are **explicit and simple**, you can iterate: tweak halflives and weights, observe effect on queue size and incident correlation.
---
If youd like, next step I can sketch:
* A REST API surface (`GET /unknowns`, `GET /unknowns/triage`, `POST /unknowns/{id}/evidence`)
* Or specific Angular components for the **Confidence Decay Card** and **HighImpact Unknowns** table, wired to these models.

View File

@@ -11,6 +11,89 @@ These are the authoritative advisories to reference for implementation:
- **Sprint:** SPRINT_0190_0001_0001_cvss_v4_receipts.md
- **Status:** New sprint created
### CVSS v4.0 Momentum Briefing
- **Canonical:** `29-Nov-2025 - CVSS v4.0 Momentum in Vulnerability Management.md`
- **Sprint:** SPRINT_0190_0001_0001_cvss_v4_receipts.md (context)
- **Related Docs:**
- `docs/product-advisories/25-Nov-2025 - Add CVSS v4.0 Score Receipts for Transparency.md` (implementation focus)
- `docs/product-advisories/29-Nov-2025 - CVSS v4.0 Momentum in Vulnerability Management.md` (this briefing)
- **Status:** Summarises the industry adoption signals (NVD/GitHub/Microsoft/Snyk) and why Stella Ops should treat CVSS v4.0 as first-class now.
### SCA Failure Catalogue
- **Canonical:** `29-Nov-2025 - SCA Failure Catalogue for StellaOps Tests.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/29-Nov-2025 - SCA Failure Catalogue for StellaOps Tests.md` (this catalogue)
- `docs/implplan/SPRINT_300_documentation_process.md` (tracking sync)
- **Status:** Captures five real-world regressions/ SBOM gaps for Trivy/Syft/Grype/Snyk and frames test vectors + alarm scenarios for StellaOps acceptance suites.
### Implementor Guidelines
- **Canonical:** `30-Nov-2025 - Implementor Guidelines for Stella Ops.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Implementor Guidelines for Stella Ops.md` (this briefing)
- `docs/05_SYSTEM_REQUIREMENTS_SPEC.md` / `docs/13_RELEASE_ENGINEERING_PLAYBOOK.md` (reference requirements)
- **Status:** Operational checklist for contributors, plug-in authors, and implementors linking SRS/architecture to practical practices.
### SBOM → VEX Proof Blueprint
- **Canonical:** `29-Nov-2025 - SBOM to VEX Proof Pipeline Blueprint.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/29-Nov-2025 - SBOM to VEX Proof Pipeline Blueprint.md` (itself)
- `docs/modules/platform/architecture-overview.md` (platform dossier link)
- **Status:** Diagram-first guide showing DSSE → Rekor v2 tiles → VEX linkage plus online/offline verification notes for StellaOps proofs.
### UI Micro-Interactions
- **Canonical:** `30-Nov-2025 - UI Micro-Interactions for StellaOps.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `apps/console/src/app/shared/micro/`
- `docs/product-advisories/30-Nov-2025 - UI Micro-Interactions for StellaOps.md`
- **Status:** Three Angular tasks covering audit trail reasons, low-noise VEX gating, and evidence provenance chips for air-gapped + online UX.
### Rekor Receipt Checklist
- **Canonical:** `30-Nov-2025 - Rekor Receipt Checklist for Stella Ops.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Rekor Receipt Checklist for Stella Ops.md`
- `docs/modules/platform/architecture-overview.md`
- **Status:** Field-level ownership map for receipts, bundles, and offline metadata so Authority/Sbomer/Vexer keep deterministic proofs.
### Ecosystem Reality Tests
- **Canonical:** `30-Nov-2025 - Ecosystem Reality Test Cases for StellaOps.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Ecosystem Reality Test Cases for StellaOps.md`
- **Status:** Evidence-backed acceptance tests covering credential leaks, offline DB quirks, SBOM parity, and scanner instability.
### Unknowns Decay & Triage Heuristics
- **Canonical:** `30-Nov-2025 - Unknowns Decay & Triage Heuristics.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Unknowns Decay & Triage Heuristics.md`
- **Status:** Confidence decay card + triage queue artifacts that feed UI + ops exports for stale unknowns.
### Standup Sprint Kickstarters
- **Canonical:** `30-Nov-2025 - Standup Sprint Kickstarters.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Standup Sprint Kickstarters.md`
- **Status:** Three day-0 tasks (scanner regressions, Postgres slice, DSSE/Rekor sweep) with ticket names and assignments.
### Evidence + Suppression Patterns
- **Canonical:** `30-Nov-2025 - Comparative Evidence Patterns for Stella Ops.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Comparative Evidence Patterns for Stella Ops.md`
- **Status:** Snapshot of how Snyk, GitHub, Aqua, Anchore/Grype, and Prisma Cloud handle evidence, suppression, and audit/export primitives.
### Reachability Benchmark Fixtures
- **Canonical:** `30-Nov-2025 - Reachability Benchmark Fixtures Snapshot.md`
- **Sprint:** SPRINT_300_documentation_process.md (docs tracker)
- **Related Docs:**
- `docs/product-advisories/30-Nov-2025 - Reachability Benchmark Fixtures Snapshot.md`
- **Status:** SV-COMP + OSS-Fuzz grounded fixture plan plus Tier-2 guidance for Java/Python, packages, containers, call-graph corpora.
### SBOM/VEX Pipeline
- **Canonical:** `27-Nov-2025 - Deep Architecture Brief - SBOMFirst, VEXReady Spine.md`
- **Sprint:** SPRINT_0186_0001_0001_record_deterministic_execution.md (tasks 15a-15f)
@@ -74,7 +157,7 @@ These are the authoritative advisories to reference for implementation:
- **Canonical:** `28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md`
- **Sprint:** SPRINT_0215_0001_0001_vuln_triage_ux.md (NEW)
- **Related Sprints:**
- SPRINT_210_ui_ii.md (UI-LNM-22-003 VEX tab)
- SPRINT_0210_0001_0002_ui_ii.md (UI-LNM-22-003 VEX tab)
- SPRINT_0334_docs_modules_vuln_explorer.md (docs)
- **Related Advisories:**
- `27-Nov-2025 - Explainability Layer for Vulnerability Verdicts.md` (evidence chain)
@@ -107,7 +190,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - consolidates extensibility patterns across modules
### Evidence Bundle & Replay Contracts
- **Canonical:** `29-Nov-2025 - Evidence Bundle and Replay Contracts.md`
- **Canonical:** `28-Nov-2025 - Evidence Bundle and Replay Contracts.md`
- **Sprint:** SPRINT_0161_0001_0001_evidencelocker.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0187_0001_0001_evidence_locker_cli_integration.md (CLI)
@@ -117,9 +200,16 @@ These are the authoritative advisories to reference for implementation:
- `docs/modules/evidence-locker/attestation-contract.md` - DSSE contract
- `docs/modules/evidence-locker/replay-payload-contract.md` - Replay schema
- **Status:** Fills HIGH-priority gap - covers deterministic bundles, attestations, replay, incident mode
### Acceptance Tests Pack for Guardrails
- **Canonical:** `29-Nov-2025 - Acceptance Tests Pack for StellaOps Guardrails.md`
- **Sprint:** SPRINT_300_documentation_process.md (Docs Governance)
- **Related Docs:**
- `docs/product-advisories/29-Nov-2025 - Acceptance Tests Pack for StellaOps Guardrails.md` (itself)
- `docs/implplan/SPRINT_300_documentation_process.md` (tracking the sync)
- **Status:** Captures feed resiliency, SBOM validation, snapshot/replay rehearsals, reachability fallbacks, and pipeline swap guardrails for acceptance tests.
### Mirror & Offline Kit Strategy
- **Canonical:** `29-Nov-2025 - Mirror and Offline Kit Strategy.md`
- **Canonical:** `28-Nov-2025 - Mirror and Offline Kit Strategy.md`
- **Sprint:** SPRINT_0125_0001_0001 (Mirror Bundles)
- **Related Sprints:**
- SPRINT_0150_0001_0001 (DSSE/Time Anchors)
@@ -132,7 +222,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills HIGH-priority gap - covers thin bundles, DSSE/TUF signing, time anchoring
### Task Pack Orchestration & Automation
- **Canonical:** `29-Nov-2025 - Task Pack Orchestration and Automation.md`
- **Canonical:** `28-Nov-2025 - Task Pack Orchestration and Automation.md`
- **Sprint:** SPRINT_0157_0001_0001_taskrunner_i.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0158_0001_0002_taskrunner_ii.md (Phase II)
@@ -144,7 +234,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills HIGH-priority gap - covers pack DSL, approvals, evidence capture
### Authentication & Authorization Architecture
- **Canonical:** `29-Nov-2025 - Authentication and Authorization Architecture.md`
- **Canonical:** `28-Nov-2025 - Authentication and Authorization Architecture.md`
- **Sprint:** Multiple (see below)
- **Related Sprints:**
- SPRINT_100_identity_signing.md (CLOSED - historical)
@@ -158,7 +248,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills HIGH-priority gap - consolidates token model, scopes, multi-tenant isolation
### CLI Developer Experience & Command UX
- **Canonical:** `29-Nov-2025 - CLI Developer Experience and Command UX.md`
- **Canonical:** `28-Nov-2025 - CLI Developer Experience and Command UX.md`
- **Sprint:** SPRINT_0201_0001_0001_cli_i.md (PRIMARY)
- **Related Sprints:**
- SPRINT_203_cli_iii.md
@@ -169,7 +259,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills HIGH-priority gap - covers command surface, auth model, Buildx integration
### Orchestrator Event Model & Job Lifecycle
- **Canonical:** `29-Nov-2025 - Orchestrator Event Model and Job Lifecycle.md`
- **Canonical:** `28-Nov-2025 - Orchestrator Event Model and Job Lifecycle.md`
- **Sprint:** SPRINT_0151_0001_0001_orchestrator_i.md (PRIMARY)
- **Related Sprints:**
- SPRINT_152_orchestrator_ii.md
@@ -179,7 +269,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills HIGH-priority gap - covers job lifecycle, quota governance, replay semantics
### Export Center & Reporting Strategy
- **Canonical:** `29-Nov-2025 - Export Center and Reporting Strategy.md`
- **Canonical:** `28-Nov-2025 - Export Center and Reporting Strategy.md`
- **Sprint:** SPRINT_0160_0001_0001_export_evidence.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0161_0001_0001_evidencelocker.md
@@ -188,7 +278,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers profile system, adapters, distribution channels
### Runtime Posture & Observation (Zastava)
- **Canonical:** `29-Nov-2025 - Runtime Posture and Observation with Zastava.md`
- **Canonical:** `28-Nov-2025 - Runtime Posture and Observation with Zastava.md`
- **Sprint:** SPRINT_0144_0001_0001_zastava_runtime_signals.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0140_0001_0001_runtime_signals.md
@@ -198,7 +288,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers runtime events, admission control, drift detection
### Notification Rules & Alerting Engine
- **Canonical:** `29-Nov-2025 - Notification Rules and Alerting Engine.md`
- **Canonical:** `28-Nov-2025 - Notification Rules and Alerting Engine.md`
- **Sprint:** SPRINT_0170_0001_0001_notify_engine.md (NEW)
- **Related Sprints:**
- SPRINT_0171_0001_0002_notify_connectors.md
@@ -208,7 +298,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers rules engine, channels, noise control, ack tokens
### Graph Analytics & Dependency Insights
- **Canonical:** `29-Nov-2025 - Graph Analytics and Dependency Insights.md`
- **Canonical:** `28-Nov-2025 - Graph Analytics and Dependency Insights.md`
- **Sprint:** SPRINT_0141_0001_0001_graph_indexer.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0401_0001_0001_reachability_evidence_chain.md
@@ -218,7 +308,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers graph model, overlays, analytics, visualization
### Telemetry & Observability Patterns
- **Canonical:** `29-Nov-2025 - Telemetry and Observability Patterns.md`
- **Canonical:** `28-Nov-2025 - Telemetry and Observability Patterns.md`
- **Sprint:** SPRINT_0180_0001_0001_telemetry_core.md (NEW)
- **Related Sprints:**
- SPRINT_0181_0001_0002_telemetry_forensic.md
@@ -228,7 +318,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers collector topology, forensic mode, offline bundles
### Policy Simulation & Shadow Gates
- **Canonical:** `29-Nov-2025 - Policy Simulation and Shadow Gates.md`
- **Canonical:** `28-Nov-2025 - Policy Simulation and Shadow Gates.md`
- **Sprint:** SPRINT_0185_0001_0001_policy_simulation.md (NEW)
- **Related Sprints:**
- SPRINT_0120_0000_0001_policy_reasoning.md
@@ -238,7 +328,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers shadow runs, coverage fixtures, promotion gates
### Findings Ledger & Immutable Audit Trail
- **Canonical:** `29-Nov-2025 - Findings Ledger and Immutable Audit Trail.md`
- **Canonical:** `28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md`
- **Sprint:** SPRINT_0186_0001_0001_record_deterministic_execution.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0120_0000_0001_policy_reasoning.md
@@ -248,7 +338,7 @@ These are the authoritative advisories to reference for implementation:
- **Status:** Fills MEDIUM-priority gap - covers append-only events, Merkle anchoring, projections
### Concelier Advisory Ingestion Model
- **Canonical:** `29-Nov-2025 - Concelier Advisory Ingestion Model.md`
- **Canonical:** `28-Nov-2025 - Concelier Advisory Ingestion Model.md`
- **Sprint:** SPRINT_0115_0001_0004_concelier_iv.md (PRIMARY)
- **Related Sprints:**
- SPRINT_0113_0001_0002_concelier_ii.md
@@ -372,6 +462,15 @@ For each topic, the implementer should read:
| Findings Ledger | `docs/modules/findings-ledger/openapi/` | `src/Findings/*/AGENTS.md` |
| Concelier | `docs/modules/concelier/architecture.md` | `src/Concelier/*/AGENTS.md` |
### Developer Onboarding Quick Start
- **Canonical:** `29-Nov-2025 - StellaOps Mid-Level .NET Onboarding (Quick Start).md`
- **Sprint:** SPRINT_300_documentation_process.md (Docs Governance)
- **Related Docs:**
- `docs/onboarding/dev-quickstart.md` (derived from this advisory)
- `docs/README.md` (new quickstart reference)
- `docs/modules/platform/architecture-overview.md` (platform dossier mention)
- **Status:** Documents deterministic onboarding for mid-level .NET engineers covering repos, determinism tests, DSSE/attestation patterns, and starter issues.
## Topical Gaps (Advisory Needed)
The following topics are mentioned in CLAUDE.md or module docs but lack dedicated product advisories:
@@ -380,20 +479,20 @@ The following topics are mentioned in CLAUDE.md or module docs but lack dedicate
|-----|----------|--------|-------|
| ~~Regional Crypto (eIDAS/FIPS/GOST/SM)~~ | HIGH | **FILLED** | `28-Nov-2025 - Sovereign Crypto for Regional Compliance.md` |
| ~~Plugin Architecture Patterns~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Plugin Architecture & Extensibility Patterns.md` |
| ~~Evidence Bundle Packaging~~ | HIGH | **FILLED** | `29-Nov-2025 - Evidence Bundle and Replay Contracts.md` |
| ~~Mirror/Offline Kit Strategy~~ | HIGH | **FILLED** | `29-Nov-2025 - Mirror and Offline Kit Strategy.md` |
| ~~Task Pack Orchestration~~ | HIGH | **FILLED** | `29-Nov-2025 - Task Pack Orchestration and Automation.md` |
| ~~Auth/AuthZ Architecture~~ | HIGH | **FILLED** | `29-Nov-2025 - Authentication and Authorization Architecture.md` |
| ~~CLI Developer Experience~~ | HIGH | **FILLED** | `29-Nov-2025 - CLI Developer Experience and Command UX.md` |
| ~~Orchestrator Event Model~~ | HIGH | **FILLED** | `29-Nov-2025 - Orchestrator Event Model and Job Lifecycle.md` |
| ~~Export Center Strategy~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Export Center and Reporting Strategy.md` |
| ~~Runtime Posture & Observation~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Runtime Posture and Observation with Zastava.md` |
| ~~Notification Rules Engine~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Notification Rules and Alerting Engine.md` |
| ~~Graph Analytics & Clustering~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Graph Analytics and Dependency Insights.md` |
| ~~Telemetry & Observability~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Telemetry and Observability Patterns.md` |
| ~~Policy Simulation & Shadow Gates~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Policy Simulation and Shadow Gates.md` |
| ~~Findings Ledger & Audit Trail~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Findings Ledger and Immutable Audit Trail.md` |
| ~~Concelier Advisory Ingestion~~ | MEDIUM | **FILLED** | `29-Nov-2025 - Concelier Advisory Ingestion Model.md` |
| ~~Evidence Bundle Packaging~~ | HIGH | **FILLED** | `28-Nov-2025 - Evidence Bundle and Replay Contracts.md` |
| ~~Mirror/Offline Kit Strategy~~ | HIGH | **FILLED** | `28-Nov-2025 - Mirror and Offline Kit Strategy.md` |
| ~~Task Pack Orchestration~~ | HIGH | **FILLED** | `28-Nov-2025 - Task Pack Orchestration and Automation.md` |
| ~~Auth/AuthZ Architecture~~ | HIGH | **FILLED** | `28-Nov-2025 - Authentication and Authorization Architecture.md` |
| ~~CLI Developer Experience~~ | HIGH | **FILLED** | `28-Nov-2025 - CLI Developer Experience and Command UX.md` |
| ~~Orchestrator Event Model~~ | HIGH | **FILLED** | `28-Nov-2025 - Orchestrator Event Model and Job Lifecycle.md` |
| ~~Export Center Strategy~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Export Center and Reporting Strategy.md` |
| ~~Runtime Posture & Observation~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Runtime Posture and Observation with Zastava.md` |
| ~~Notification Rules Engine~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Notification Rules and Alerting Engine.md` |
| ~~Graph Analytics & Clustering~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Graph Analytics and Dependency Insights.md` |
| ~~Telemetry & Observability~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Telemetry and Observability Patterns.md` |
| ~~Policy Simulation & Shadow Gates~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Policy Simulation and Shadow Gates.md` |
| ~~Findings Ledger & Audit Trail~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md` |
| ~~Concelier Advisory Ingestion~~ | MEDIUM | **FILLED** | `28-Nov-2025 - Concelier Advisory Ingestion Model.md` |
| **CycloneDX 1.6 .NET Integration** | LOW | Open | Deep Architecture covers generically; expand with .NET-specific guidance |
## Known Issues (Non-Blocking)
@@ -409,4 +508,4 @@ Several filenames use en-dash (U+2011) instead of regular hyphen (-). This may c
---
*Index created: 2025-11-27*
*Last updated: 2025-11-29 (added 10 new advisories filling all identified gaps)*
*Last updated: 2025-11-30 (added Implementor Guidelines, UI micro-interactions brief, Rekor receipt checklist, Ecosystem test cases, Unknowns decay/triage heuristics, Standup Sprint Kickstarters, Comparative Evidence Patterns, and prior references)*

View File

@@ -10,5 +10,13 @@ Artifacts supporting `DEVOPS-AIRGAP-56-001`:
- `build_bootstrap_pack.py` — Builds a Bootstrap Pack from images/charts/extras listed in a JSON config, writing `bootstrap-manifest.json` + `checksums.sha256` deterministically.
- `build_bootstrap_pack.sh` — Wrapper for the bootstrap pack builder.
- `build_mirror_bundle.py` — Generates mirror bundle manifest + checksums with dual-control approvals; optional cosign signing. Outputs `mirror-bundle-manifest.json`, `checksums.sha256`, and optional signature/cert.
- `compose-syslog-smtp.yaml` — Local SMTP (MailHog) + syslog-ng stack for sealed environments.
- `health_syslog_smtp.sh` — Brings up the syslog/SMTP stack via docker compose and performs health checks (MailHog API + syslog logger).
- `compose-observability.yaml` — Sealed-mode observability stack (Prometheus, Grafana, Tempo, Loki) with offline configs and healthchecks.
- `health_observability.sh` — Starts the observability stack and probes Prometheus/Grafana/Tempo/Loki readiness.
- `compose-syslog-smtp.yaml` + `syslog-ng.conf` — Local SMTP + syslog stack for sealed-mode notifications; run via `scripts/devops/run-smtp-syslog.sh` (health check `health_syslog_smtp.sh`).
- `observability-offline-compose.yml` + `otel-offline.yaml` + `promtail-config.yaml` — Sealed-mode observability stack (Loki, Promtail, OTEL collector with file exporters) to satisfy DEVOPS-AIRGAP-58-002.
- `compose-syslog-smtp.yaml` — Local SMTP (MailHog) + syslog-ng stack for sealed environments.
- `health_syslog_smtp.sh` — Brings up the syslog/SMTP stack via docker compose and performs health checks (MailHog API + syslog logger).
See also `ops/devops/sealed-mode-ci/` for the full sealed-mode compose harness and `egress_probe.py`, which this verification script wraps.

View File

@@ -0,0 +1,77 @@
version: "3.9"
services:
prometheus:
image: prom/prometheus:v2.53.0
container_name: prometheus
command:
- --config.file=/etc/prometheus/prometheus.yml
volumes:
- ./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
ports:
- "9090:9090"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:9090/-/ready"]
interval: 15s
timeout: 5s
retries: 5
start_period: 10s
restart: unless-stopped
loki:
image: grafana/loki:3.0.0
container_name: loki
command: ["-config.file=/etc/loki/config.yaml"]
volumes:
- ./observability/loki-config.yaml:/etc/loki/config.yaml:ro
- ./observability/data/loki:/loki
ports:
- "3100:3100"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3100/ready"]
interval: 15s
timeout: 5s
retries: 5
start_period: 15s
restart: unless-stopped
tempo:
image: grafana/tempo:2.4.1
container_name: tempo
command: ["-config.file=/etc/tempo/tempo.yaml"]
volumes:
- ./observability/tempo-config.yaml:/etc/tempo/tempo.yaml:ro
- ./observability/data/tempo:/var/tempo
ports:
- "3200:3200"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3200/ready"]
interval: 15s
timeout: 5s
retries: 5
start_period: 15s
restart: unless-stopped
grafana:
image: grafana/grafana:10.4.2
container_name: grafana
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_SECURITY_ADMIN_USER=admin
volumes:
- ./observability/grafana/provisioning/datasources:/etc/grafana/provisioning/datasources:ro
ports:
- "3000:3000"
depends_on:
- prometheus
- loki
- tempo
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"]
interval: 15s
timeout: 5s
retries: 5
start_period: 20s
restart: unless-stopped

View File

@@ -0,0 +1,23 @@
version: '3.8'
services:
smtp:
image: bytemark/smtp
restart: unless-stopped
environment:
- MAILNAME=sealed.local
networks: [sealed]
ports:
- "2525:25"
syslog:
image: balabit/syslog-ng:4.7.1
restart: unless-stopped
command: ["syslog-ng", "-F", "--no-caps"]
networks: [sealed]
ports:
- "5514:514/udp"
- "5515:601/tcp"
volumes:
- ./syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro
networks:
sealed:
driver: bridge

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail
# Health check for compose-observability.yaml (DEVOPS-AIRGAP-58-002)
COMPOSE_FILE="$(cd "$(dirname "$0")" && pwd)/compose-observability.yaml"
echo "Starting observability stack (Prometheus/Grafana/Tempo/Loki)..."
docker compose -f "$COMPOSE_FILE" up -d
echo "Waiting for containers to report healthy..."
docker compose -f "$COMPOSE_FILE" wait >/dev/null 2>&1 || true
docker compose -f "$COMPOSE_FILE" ps
echo "Probing Prometheus /-/ready"
curl -sf http://127.0.0.1:9090/-/ready
echo "Probing Grafana /api/health"
curl -sf http://127.0.0.1:3000/api/health
echo "Probing Loki /ready"
curl -sf http://127.0.0.1:3100/ready
echo "Probing Tempo /ready"
curl -sf http://127.0.0.1:3200/ready
echo "All probes succeeded."

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
# Health check for compose-syslog-smtp.yaml (DEVOPS-AIRGAP-58-001)
ROOT=${ROOT:-$(git rev-parse --show-toplevel)}
COMPOSE_FILE="${COMPOSE_FILE:-$ROOT/ops/devops/airgap/compose-syslog-smtp.yaml}"
SMTP_PORT=${SMTP_PORT:-2525}
SYSLOG_TCP=${SYSLOG_TCP:-5515}
SYSLOG_UDP=${SYSLOG_UDP:-5514}
export COMPOSE_FILE
# ensure stack up
if ! docker compose ps >/dev/null 2>&1; then
docker compose up -d
fi
sleep 2
# probe smtp banner
if ! timeout 5 bash -lc "echo QUIT | nc -w2 127.0.0.1 ${SMTP_PORT}" >/dev/null 2>&1; then
echo "smtp service not responding on ${SMTP_PORT}" >&2
exit 1
fi
# probe syslog tcp
if ! echo "test" | nc -w2 127.0.0.1 ${SYSLOG_TCP} >/dev/null 2>&1; then
echo "syslog tcp not responding on ${SYSLOG_TCP}" >&2
exit 1
fi
# probe syslog udp
if ! echo "test" | nc -w2 -u 127.0.0.1 ${SYSLOG_UDP} >/dev/null 2>&1; then
echo "syslog udp not responding on ${SYSLOG_UDP}" >&2
exit 1
fi
echo "smtp/syslog stack healthy"

View File

@@ -0,0 +1,32 @@
version: '3.8'
services:
loki:
image: grafana/loki:3.0.1
command: ["-config.file=/etc/loki/local-config.yaml"]
volumes:
- loki-data:/loki
networks: [sealed]
promtail:
image: grafana/promtail:3.0.1
command: ["-config.file=/etc/promtail/config.yml"]
volumes:
- promtail-data:/var/log
- ./promtail-config.yaml:/etc/promtail/config.yml:ro
networks: [sealed]
otel:
image: otel/opentelemetry-collector-contrib:0.97.0
command: ["--config=/etc/otel/otel-offline.yaml"]
volumes:
- ./otel-offline.yaml:/etc/otel/otel-offline.yaml:ro
- otel-data:/var/otel
ports:
- "4317:4317"
- "4318:4318"
networks: [sealed]
networks:
sealed:
driver: bridge
volumes:
loki-data:
promtail-data:
otel-data:

View File

@@ -0,0 +1,16 @@
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
- name: Loki
type: loki
access: proxy
url: http://loki:3100
- name: Tempo
type: tempo
access: proxy
url: http://tempo:3200

View File

@@ -0,0 +1,35 @@
server:
http_listen_port: 3100
log_level: warn
common:
ring:
instance_addr: loki
kvstore:
store: inmemory
replication_factor: 1
table_manager:
retention_deletes_enabled: true
retention_period: 168h
schema_config:
configs:
- from: 2024-01-01
store: boltdb-shipper
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
storage_config:
filesystem:
directory: /loki/chunks
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/cache
shared_store: filesystem
limits_config:
retention_period: 168h

View File

@@ -0,0 +1,14 @@
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['prometheus:9090']
- job_name: loki
static_configs:
- targets: ['loki:3100']
- job_name: tempo
static_configs:
- targets: ['tempo:3200']

View File

@@ -0,0 +1,26 @@
server:
http_listen_port: 3200
log_level: warn
distributor:
receivers:
jaeger:
protocols:
thrift_http:
otlp:
protocols:
http:
grpc:
zipkin:
storage:
trace:
backend: local
wal:
path: /var/tempo/wal
local:
path: /var/tempo/traces
compactor:
compaction:
block_retention: 168h

View File

@@ -0,0 +1,40 @@
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'self'
static_configs:
- targets: ['localhost:8888']
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 1s
send_batch_size: 512
exporters:
file/metrics:
path: /var/otel/metrics.prom
file/traces:
path: /var/otel/traces.ndjson
loki/offline:
endpoint: http://loki:3100/loki/api/v1/push
labels:
job: sealed-observability
tenant_id: "sealed"
service:
telemetry:
logs:
level: info
pipelines:
metrics:
receivers: [prometheus]
processors: [batch]
exporters: [file/metrics]
traces:
receivers: [otlp]
processors: [batch]
exporters: [file/traces]

Some files were not shown because too many files have changed in this diff Show More