Add sample proof bundle configurations and verification script
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Console CI / console-ci (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
VEX Proof Bundles / verify-bundles (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Console CI / console-ci (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
VEX Proof Bundles / verify-bundles (push) Has been cancelled
- Introduced sample proof bundle configuration files for testing, including `sample-proof-bundle-config.dsse.json`, `sample-proof-bundle.dsse.json`, and `sample-proof-bundle.json`. - Implemented a verification script `test_verify_sample.sh` to validate proof bundles against specified schemas and catalogs. - Updated existing proof bundle configurations with new metadata, including versioning, created timestamps, and justification details. - Enhanced evidence entries with expiration dates and hashes for better integrity checks. - Ensured all new configurations adhere to the defined schema for consistency and reliability in testing.
This commit is contained in:
@@ -1,34 +1,26 @@
|
||||
# Docs & Enablement Guild
|
||||
# AGENTS · Documentation Working Directory
|
||||
|
||||
## Mission
|
||||
Produce and maintain offline-friendly documentation for StellaOps modules, covering architecture, configuration, operator workflows, and developer onboarding.
|
||||
## Scope & Roles
|
||||
- Working directory: `docs/` (includes `docs/assets/**` fixtures and `docs/api/console/samples/**`).
|
||||
- Roles: Documentation author (primary), QA/fixtures reviewer, module SMEs (Console/UI, Advisory AI, Policy/Airgap) for accuracy checks.
|
||||
- Only documentation and fixture assets live here; code changes belong to module repos and must be coordinated via the owning sprint.
|
||||
|
||||
## Scope Highlights
|
||||
- Authority docs (`docs/dev/31_AUTHORITY_PLUGIN_DEVELOPER_GUIDE.md`, upcoming `docs/11_AUTHORITY.md`).
|
||||
- Concelier quickstarts, CLI guides, Offline Kit manuals.
|
||||
- Release notes and migration playbooks.
|
||||
## Required Reading (treat as read before DOING)
|
||||
- `docs/README.md` and `docs/07_HIGH_LEVEL_ARCHITECTURE.md`.
|
||||
- Module dossiers relevant to the document being edited (e.g., `docs/modules/advisory-ai/architecture.md`, `docs/modules/ui/architecture.md`, `docs/modules/airgap/architecture.md`, `docs/modules/platform/architecture-overview.md`).
|
||||
- Active sprint file: `docs/implplan/SPRINT_0301_0001_0001_docs_md_i.md` (Docs Tasks Md.I).
|
||||
|
||||
## Operating Principles
|
||||
- Keep guides deterministic and in sync with shipped configuration samples.
|
||||
- Prefer tables/checklists for operator steps; flag security-sensitive actions.
|
||||
- When work involves a specific `StellaOps.<Component>` project, consult both `docs/07_HIGH_LEVEL_ARCHITECTURE.md` and the matching dossier `docs/modules/<component>/architecture.md` before drafting or editing content.
|
||||
- Update `docs/TASKS.md` whenever work items change status (TODO/DOING/REVIEW/DONE/BLOCKED).
|
||||
## Working Agreements
|
||||
- Determinism: Keep fixtures and captures reproducible. Store payload JSON alongside SVG/PNG captures; record sha256 hashes in the doc and verify with `sha256sum` before publishing.
|
||||
- Offline posture: Use sealed/fixture data only; no external fonts/CDNs or live calls in regeneration scripts. Capture timestamps in UTC.
|
||||
- Status discipline: Update task status in the sprint Delivery Tracker (`TODO → DOING → DONE/BLOCKED`) and log changes in the sprint Execution Log.
|
||||
- Cross-links: When documentation applies a design/advisory change, update the relevant module doc and link it from the sprint’s **Decisions & Risks**.
|
||||
- Testing: For regeneration scripts, keep them self-contained (stdlib-only) and record expected hashes so QA can diff outputs deterministically.
|
||||
|
||||
## Coordination
|
||||
- Authority Core & Plugin teams for auth-related changes.
|
||||
- Security Guild for threat-model outputs and mitigations.
|
||||
- DevEx for tooling diagrams and documentation pipeline.
|
||||
## Boundaries
|
||||
- Do not edit source code outside `docs/` without an explicit sprint note.
|
||||
- Asset placement: use `docs/assets/<area>/` for captures and `docs/api/<area>/samples/` for JSON fixtures. Name captures `yyyyMMdd-HHmmss-<view>-<build>.<ext>` in UTC.
|
||||
|
||||
## Required Reading
|
||||
- `docs/README.md`
|
||||
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
|
||||
- `docs/modules/platform/architecture-overview.md`
|
||||
- `docs/dev/31_AUTHORITY_PLUGIN_DEVELOPER_GUIDE.md`
|
||||
- Module-specific README and architecture dossiers for the area you are updating (for example, `docs/modules/concelier/README.md` and `docs/modules/concelier/architecture.md`)
|
||||
|
||||
## Working Agreement
|
||||
- 1. Update task status to `DOING`/`DONE` in both correspoding sprint file `../implplan/SPRINT_*.md` and the local `TASKS.md` when you start or finish work.
|
||||
- 2. Review this charter and the Required Reading documents before coding; confirm prerequisites are met.
|
||||
- 3. Keep changes deterministic (stable ordering, timestamps, hashes) and align with offline/air-gap expectations.
|
||||
- 4. Coordinate doc updates, tests, and cross-guild communication whenever contracts or workflows change.
|
||||
- 5. Revert to `TODO` if you pause the task without shipping changes; leave notes in commit/PR descriptions for context.
|
||||
## Escalation / Blockers
|
||||
- Missing fixtures or conflicting contracts → mark the task `BLOCKED` in the sprint file, describe the needed artifact or contract in **Decisions & Risks**, then continue with other unblocked work.
|
||||
- If new advisories land, run the advisory-sync workflow: update high-level docs, deep area docs, add sprint tasks, and carry code samples into fixtures/tests immediately.
|
||||
|
||||
8
docs/advisory-ai/console-fixtures.sha256
Normal file
8
docs/advisory-ai/console-fixtures.sha256
Normal file
@@ -0,0 +1,8 @@
|
||||
bd85eb2ab4528825c17cd0549b547c2d1a6a5e8ee697a6b4615119245665cc02 docs/api/console/samples/advisory-ai-guardrail-banner.json
|
||||
57d7bf9ab226b561e19b3e23e3c8d6c88a3a1252c1ea471ef03bf7a237de8079 docs/api/console/samples/vex-statement-sse.ndjson
|
||||
af3459e8cf7179c264d1ac1f82a968e26e273e7e45cd103c8966d0dd261c3029 docs/api/console/samples/vuln-findings-sample.json
|
||||
336c55d72abea77bf4557f1e3dcaa4ab8366d79008670d87020f900dcfc833c0 docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2-payload.json
|
||||
c55217e8526700c2d303677a66351a706007381219adab99773d4728cc61f293 docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2.svg
|
||||
9bc89861ba873c7f470c5a30c97fb2cd089d6af23b085fba2095e88f8d1f8ede docs/assets/advisory-ai/console/evidence-drawer-b1820ad.svg
|
||||
f6093257134f38033abb88c940d36f7985b48f4f79870d5b6310d70de5a586f9 docs/samples/console/console-vex-30-001.json
|
||||
921bcb360454e801bb006a3df17f62e1fcfecaaccda471ae66f167147539ad1e docs/samples/console/console-vuln-29-001.json
|
||||
@@ -1,6 +1,6 @@
|
||||
# Advisory AI Console Workflows
|
||||
|
||||
_Last updated: 2025-12-03_
|
||||
_Last updated: 2025-12-04_
|
||||
|
||||
This guide documents the forthcoming Advisory AI console experience so that console, docs, and QA guilds share a single reference while the new endpoints finish landing.
|
||||
|
||||
@@ -65,10 +65,24 @@ This guide documents the forthcoming Advisory AI console experience so that cons
|
||||
- VEX statement SSE stream: `docs/api/console/samples/vex-statement-sse.ndjson`.
|
||||
- Guardrail banner projection: `docs/api/console/samples/advisory-ai-guardrail-banner.json` (fixed to valid JSON on 2025-12-03).
|
||||
- Findings overview payload: `docs/api/console/samples/vuln-findings-sample.json`.
|
||||
- Deterministic list-view capture + payload: `docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2.{svg,json}`. Payload sha256: `336c55d72abea77bf4557f1e3dcaa4ab8366d79008670d87020f900dcfc833c0`; svg sha256: `c55217e8526700c2d303677a66351a706007381219adab99773d4728cc61f293`.
|
||||
- Deterministic list-view capture + payload: `docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2.{svg,json}` (hashes in table below).
|
||||
- When capturing screenshots, point the console to a dev workspace seeded with the above fixtures and record the build hash displayed in the footer to keep captures reproducible.
|
||||
- Store captures under `docs/assets/advisory-ai/console/` using the scheme `yyyyMMdd-HHmmss-<view>-<build>.png` (UTC clock) so regeneration is deterministic. Keep the original JSON alongside each screenshot by saving the response as `…-payload.json` in the same folder.
|
||||
|
||||
#### Fixture hashes (run from repo root)
|
||||
- Verify deterministically: `sha256sum --check docs/advisory-ai/console-fixtures.sha256`.
|
||||
|
||||
| Fixture | sha256 | Notes |
|
||||
| --- | --- | --- |
|
||||
| `docs/api/console/samples/advisory-ai-guardrail-banner.json` | `bd85eb2ab4528825c17cd0549b547c2d1a6a5e8ee697a6b4615119245665cc02` | Guardrail ribbon projection. |
|
||||
| `docs/api/console/samples/vex-statement-sse.ndjson` | `57d7bf9ab226b561e19b3e23e3c8d6c88a3a1252c1ea471ef03bf7a237de8079` | SSE stream sample. |
|
||||
| `docs/api/console/samples/vuln-findings-sample.json` | `af3459e8cf7179c264d1ac1f82a968e26e273e7e45cd103c8966d0dd261c3029` | Findings overview payload. |
|
||||
| `docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2-payload.json` | `336c55d72abea77bf4557f1e3dcaa4ab8366d79008670d87020f900dcfc833c0` | List-view sealed payload. |
|
||||
| `docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2.svg` | `c55217e8526700c2d303677a66351a706007381219adab99773d4728cc61f293` | Deterministic list-view capture. |
|
||||
| `docs/assets/advisory-ai/console/evidence-drawer-b1820ad.svg` | `9bc89861ba873c7f470c5a30c97fb2cd089d6af23b085fba2095e88f8d1f8ede` | Evidence drawer mock (keep until live capture). |
|
||||
| `docs/samples/console/console-vex-30-001.json` | `f6093257134f38033abb88c940d36f7985b48f4f79870d5b6310d70de5a586f9` | Console VEX search fixture. |
|
||||
| `docs/samples/console/console-vuln-29-001.json` | `921bcb360454e801bb006a3df17f62e1fcfecaaccda471ae66f167147539ad1e` | Console vuln search fixture. |
|
||||
|
||||
## 3. Accessibility & offline requirements
|
||||
- Console screens must pass WCAG 2.2 AA contrast and provide focus order that matches the keyboard shortcuts planned for Advisory AI (see `docs/advisory-ai/overview.md`).
|
||||
- All screenshots captured for this doc must come from sealed-mode bundles (no external fonts/CDNs). Store them under `docs/assets/advisory-ai/console/` with hashed filenames.
|
||||
@@ -117,7 +131,7 @@ This guide documents the forthcoming Advisory AI console experience so that cons
|
||||
|
||||
- **Console wiring** – the guardrail ribbon pulls `guardrail.blocked`, `guardrail.violations`, and `guardrail.metadata.blocked_phrase_count` while the observability cards track `advisory_ai_chunk_requests_total`, `advisory_ai_chunk_cache_hits_total`, and `advisory_ai_guardrail_blocks_total` (now emitted even on cache hits). Use these meters to explain throttling or bad actors before granting additional guardrail budgets, and keep `docs/api/console/samples/advisory-ai-guardrail-banner.json` nearby so QA can validate localized payloads without hitting production data.
|
||||
|
||||
## 5. Publication state
|
||||
## 7. Publication state
|
||||
- [x] Fixture-backed payloads and captures committed (`20251203-0000-list-view-build-r2.svg`, `evidence-drawer-b1820ad.svg`).
|
||||
- [x] Copy-as-ticket flow documented; payload aligns with existing SOC runbooks.
|
||||
- [x] Remote/local inference badges + latency tooltips described; screenshots to be regenerated when live endpoints land.
|
||||
@@ -203,4 +217,13 @@ svg = f"""<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1280\" height=\"720\
|
||||
PY
|
||||
```
|
||||
|
||||
- Verify the regenerated outputs match the sealed fixtures before publishing:
|
||||
|
||||
```bash
|
||||
sha256sum docs/assets/advisory-ai/console/20251203-0000-list-view-build-r2.{svg,payload.json}
|
||||
# expected:
|
||||
# c55217e8526700c2d303677a66351a706007381219adab99773d4728cc61f293 ...-build-r2.svg
|
||||
# 336c55d72abea77bf4557f1e3dcaa4ab8366d79008670d87020f900dcfc833c0 ...-build-r2-payload.json
|
||||
```
|
||||
|
||||
**Reference**: API contracts and sample payloads live in `docs/api/console/workspaces.md` (see `/console/vuln/*` and `/console/vex/*` sections) plus the JSON fixtures under `docs/api/console/samples/`.
|
||||
|
||||
@@ -1,26 +1,37 @@
|
||||
# VEX Evidence Playbook (VEX1–VEX10)
|
||||
|
||||
Status: Draft · Date: 2025-12-03
|
||||
Status: Frozen · Date: 2025-12-04
|
||||
Scope: Define deterministic VEX evidence bundles, justification catalog, and verification workflow for reachability evidence chain (Sprint 0401 tasks 62, 64, 65).
|
||||
|
||||
## Artifacts (frozen)
|
||||
- Schema: `docs/benchmarks/vex-evidence-playbook.schema.json`
|
||||
- Justification catalog (+ DSSE): `docs/benchmarks/vex-justifications.catalog.json`, `docs/benchmarks/vex-justifications.catalog.dsse.json`
|
||||
- Proof bundle fixtures (+ DSSE): `tests/Vex/ProofBundles/sample-proof-bundle.json`, `tests/Vex/ProofBundles/sample-proof-bundle.dsse.json`, `tests/Vex/ProofBundles/sample-proof-bundle-config.json`, `tests/Vex/ProofBundles/sample-proof-bundle-config.dsse.json`
|
||||
- CAS evidence set: `tests/Vex/ProofBundles/cas/` (graph, coverage, negative tests, runtime trace, config, flags + DSSE for graph/coverage)
|
||||
- OpenVEX statement: `tests/Vex/ProofBundles/openvex-sample.json`
|
||||
- OpenVEX config fixture: `tests/Vex/ProofBundles/openvex-config.json`
|
||||
- Verifier + tests: `scripts/vex/verify_proof_bundle.py`, `tests/Vex/ProofBundles/test_verify_sample.sh`
|
||||
- CI guard: `.gitea/workflows/vex-proof-bundles.yml`
|
||||
|
||||
## Goals
|
||||
- Publish signed VEX justification catalog with DSSE predicates and canonical hashes.
|
||||
- Require entry-point coverage %, negative tests, and config/flag hash enforcement for each justification.
|
||||
- Provide offline-friendly proof bundle format with CAS paths and DSSE envelopes.
|
||||
- Require entry-point coverage %, negative tests, and config/flag hash enforcement for each justification; re-evaluate on SBOM/graph/runtime change.
|
||||
- Provide offline-friendly proof bundle format with CAS paths and DSSE envelopes; mandate OpenVEX canonical serialization and Rekor-ready signature digests.
|
||||
|
||||
## Bundle schema (draft)
|
||||
- `proofBundle.schema.json` (to be placed under `docs/benchmarks/vex-evidence-playbook.schema.json`):
|
||||
- `id`, `version`, `createdAt`, `createdBy`.
|
||||
- `graph_hash` (BLAKE3-256), `graph_dsse` (sha256 of envelope).
|
||||
- `entrypoints[]` with `id`, `coverage_percent`, `negative_tests` (bool), `config_hash` (sha256), `flags_hash` (sha256).
|
||||
- `justification_id` (must exist in justification catalog), `justification_dsse` (optional hash).
|
||||
- `evidence[]` items with `type` (`trace`, `coverage`, `sbom`, `scan`, `policy`), `cas_uri`, `hash`, `dsse` (optional), `expiresAt`.
|
||||
- `signatures[]` DSSE/JWS entries with `keyId`, `sig`, `envelopeDigest`.
|
||||
## Bundle schema (frozen)
|
||||
- `docs/benchmarks/vex-evidence-playbook.schema.json` (JSON Schema 2020-12):
|
||||
- `graph.hash` (BLAKE3-256 preferred) + `graph.dsse`.
|
||||
- `openvex` block with canonical SHA-256 + BLAKE3 and statement id.
|
||||
- `justification.id` (must exist in catalog) + optional DSSE ref.
|
||||
- `entrypoints[]`: `coverage_percent` (must meet min threshold), `negative_tests`, `config_hash`, `flags_hash`.
|
||||
- `evidence[]` (graph, coverage, runtime_trace, negative_test, config, flags, sbom, scan, policy) with CAS URI + hash + optional DSSE.
|
||||
- `rbac` approvals, `reevaluation` triggers (sbom/graph/runtime true), `uncertainty` state (U0–U3), optional `policy` summary.
|
||||
- `signatures[]` with DSSE/JWS envelope digest and optional Rekor metadata.
|
||||
|
||||
## Justification catalog
|
||||
- Canonical JSON, JCS normalized; BLAKE3 + SHA-256 recorded.
|
||||
- Fields: `id`, `title`, `description`, `applicability` (list of predicates), `required_evidence` (array of types/hashes), `expiry`, `policy_links`.
|
||||
- Signed with DSSE predicate `stella.ops/vexJustification@v1`.
|
||||
- Canonical JSON, JCS normalized; BLAKE3 + SHA-256 recorded; DSSE sidecar at `docs/benchmarks/vex-justifications.catalog.dsse.json`.
|
||||
- Fields per entry: `id`, `title`, `description`, `applicability`, `required_evidence`, `expiry_days`, `reevaluate_on`, `rbac`, `policy_links`, `uncertainty_gate`.
|
||||
- Covers VEX1–VEX10 (vulnerable_code_not_present, component_not_present, config_not_vulnerable, unreachable, runtime guard, compensating control, update staged, analysis ongoing, EOL scope, false positive proven).
|
||||
|
||||
## Determinism rules
|
||||
- Canonical JSON with sorted keys; arrays sorted by `id`.
|
||||
@@ -29,14 +40,9 @@ Scope: Define deterministic VEX evidence bundles, justification catalog, and ver
|
||||
- DSSE subject = canonical JSON hash; verifier must check hash + signature.
|
||||
|
||||
## Offline verification
|
||||
- `scripts/vex/verify_proof_bundle.py` (to be authored) validates schema, hashes, DSSE, and CAS availability.
|
||||
- No network calls; CAS paths resolved locally via `--cas-root`.
|
||||
- `scripts/vex/verify_proof_bundle.py` validates schema, catalog membership, DSSE references, CAS hashes, entrypoint coverage/negative tests, RBAC, reevaluation triggers, and uncertainty gates. No network calls; CAS paths resolved via `--cas-root`.
|
||||
- Quick check: `tests/Vex/ProofBundles/test_verify_sample.sh`
|
||||
|
||||
## Fixtures (to add)
|
||||
- `tests/Vex/ProofBundles/sample-proof-bundle.json` with matching DSSE.
|
||||
- `docs/benchmarks/vex-justifications.catalog.json` with 5 sample justifications (VEX1–VEX5).
|
||||
|
||||
## Next steps
|
||||
- Freeze `proofBundle.schema.json` and justification catalog hashes.
|
||||
- Implement `verify_proof_bundle.py` and add CI job to run it over fixtures.
|
||||
- Wire sprint 0401 tasks 62/64/65 to these artifacts; update Decisions & Risks once frozen.
|
||||
## Fixtures
|
||||
- `tests/Vex/ProofBundles/sample-proof-bundle.json` (+ DSSE) grounded in CAS artefacts under `tests/Vex/ProofBundles/cas/`.
|
||||
- `docs/benchmarks/vex-justifications.catalog.json` with VEX1–VEX10 entries and DSSE sidecar.
|
||||
|
||||
225
docs/benchmarks/vex-evidence-playbook.schema.json
Normal file
225
docs/benchmarks/vex-evidence-playbook.schema.json
Normal file
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.local/docs/benchmarks/vex-evidence-playbook.schema.json",
|
||||
"title": "StellaOps VEX Proof Bundle",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"version",
|
||||
"created_at",
|
||||
"created_by",
|
||||
"graph",
|
||||
"openvex",
|
||||
"justification",
|
||||
"entrypoints",
|
||||
"evidence",
|
||||
"rbac",
|
||||
"reevaluation",
|
||||
"uncertainty",
|
||||
"signatures"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Stable proof bundle identifier (URN recommended)."
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"description": "Semantic version of the bundle payload schema."
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "UTC timestamp when the bundle was produced."
|
||||
},
|
||||
"created_by": {
|
||||
"type": "string",
|
||||
"description": "Issuer of the bundle (service, user, or automation identity)."
|
||||
},
|
||||
"graph": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["hash"],
|
||||
"properties": {
|
||||
"hash": {
|
||||
"$ref": "#/definitions/digest",
|
||||
"description": "BLAKE3-256 (preferred) or SHA-256 hash of the reachability graph."
|
||||
},
|
||||
"dsse": { "$ref": "#/definitions/dsseRef" },
|
||||
"revision_id": {
|
||||
"type": "string",
|
||||
"description": "Optional graph revision identifier or CAS key."
|
||||
}
|
||||
}
|
||||
},
|
||||
"openvex": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "statement_id", "canonical_sha256", "canonical_blake3", "serialization"],
|
||||
"properties": {
|
||||
"path": { "type": "string" },
|
||||
"statement_id": { "type": "string" },
|
||||
"canonical_sha256": { "$ref": "#/definitions/sha256" },
|
||||
"canonical_blake3": { "$ref": "#/definitions/blake3" },
|
||||
"serialization": {
|
||||
"type": "string",
|
||||
"enum": ["canonical-json", "csaf", "cyclonedx"],
|
||||
"description": "Serialization strategy for the OpenVEX payload."
|
||||
}
|
||||
}
|
||||
},
|
||||
"justification": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id"],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Justification catalog identifier (e.g., VEX1.vulnerable_code_not_present)."
|
||||
},
|
||||
"dsse": { "$ref": "#/definitions/dsseRef" }
|
||||
}
|
||||
},
|
||||
"entrypoints": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["id", "coverage_percent", "negative_tests", "config_hash", "flags_hash"],
|
||||
"properties": {
|
||||
"id": { "type": "string" },
|
||||
"coverage_percent": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 100
|
||||
},
|
||||
"negative_tests": { "type": "boolean" },
|
||||
"config_hash": { "$ref": "#/definitions/sha256" },
|
||||
"flags_hash": { "$ref": "#/definitions/sha256" },
|
||||
"evidence_links": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"evidence": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["type", "cas_uri", "hash", "expires_at"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": ["graph", "coverage", "runtime_trace", "negative_test", "config", "flags", "sbom", "scan", "policy"]
|
||||
},
|
||||
"cas_uri": { "type": "string" },
|
||||
"hash": { "$ref": "#/definitions/digest" },
|
||||
"dsse": { "$ref": "#/definitions/dsseRef" },
|
||||
"expires_at": { "type": "string", "format": "date-time" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"rbac": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["roles_allowed", "approvals_required"],
|
||||
"properties": {
|
||||
"roles_allowed": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"approvals_required": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"enforcement": {
|
||||
"type": "string",
|
||||
"description": "How RBAC is enforced (policy, signer, or both)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"reevaluation": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["on_sbom_change", "on_graph_change", "on_runtime_change"],
|
||||
"properties": {
|
||||
"on_sbom_change": { "type": "boolean" },
|
||||
"on_graph_change": { "type": "boolean" },
|
||||
"on_runtime_change": { "type": "boolean" },
|
||||
"ttl_days": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "Maximum lifetime before forced reevaluation."
|
||||
}
|
||||
}
|
||||
},
|
||||
"uncertainty": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["state", "entropy"],
|
||||
"properties": {
|
||||
"state": { "type": "string", "enum": ["U0-none", "U1-low", "U2-medium", "U3-high"] },
|
||||
"entropy": { "type": "number", "minimum": 0, "maximum": 1 },
|
||||
"notes": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"policy": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"decision": { "type": "string" },
|
||||
"decision_reason": { "type": "string" },
|
||||
"openvex_serialization": { "type": "string" },
|
||||
"canonical_encoding": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"signatures": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["type", "key_id", "envelope_digest"],
|
||||
"properties": {
|
||||
"type": { "type": "string", "enum": ["dsse", "jws"] },
|
||||
"key_id": { "type": "string" },
|
||||
"sig": { "type": "string" },
|
||||
"envelope_digest": { "$ref": "#/definitions/sha256" },
|
||||
"rekor_log_id": { "type": "string" },
|
||||
"rekor_entry_uuid": { "type": "string" },
|
||||
"transparency_checkpoint": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^sha256:[A-Fa-f0-9]{64}$"
|
||||
},
|
||||
"blake3": {
|
||||
"type": "string",
|
||||
"pattern": "^blake3:[A-Fa-f0-9]{64}$"
|
||||
},
|
||||
"digest": {
|
||||
"type": "string",
|
||||
"pattern": "^(sha256|blake3):[A-Fa-f0-9]{64}$"
|
||||
},
|
||||
"dsseRef": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["path", "sha256"],
|
||||
"properties": {
|
||||
"path": { "type": "string" },
|
||||
"sha256": { "$ref": "#/definitions/sha256" },
|
||||
"payload_sha256": { "$ref": "#/definitions/sha256" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
docs/benchmarks/vex-justifications.catalog.dsse.json
Normal file
19
docs/benchmarks/vex-justifications.catalog.dsse.json
Normal file
File diff suppressed because one or more lines are too long
265
docs/benchmarks/vex-justifications.catalog.json
Normal file
265
docs/benchmarks/vex-justifications.catalog.json
Normal file
@@ -0,0 +1,265 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"generated_at": "2025-12-04T00:00:00Z",
|
||||
"entries": [
|
||||
{
|
||||
"id": "VEX1.vulnerable_code_not_present",
|
||||
"title": "Vulnerable code removed or not shipped",
|
||||
"description": "Binary artifacts do not contain the vulnerable code paths; validated via reachability graph and reproducible build metadata.",
|
||||
"applicability": [
|
||||
"not_affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"graph_hash",
|
||||
"entrypoint_coverage>=95",
|
||||
"negative_tests",
|
||||
"config_hash"
|
||||
],
|
||||
"expiry_days": 90,
|
||||
"reevaluate_on": [
|
||||
"sbom_change",
|
||||
"graph_change",
|
||||
"runtime_change"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author",
|
||||
"policy-admin"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/policy/dsl.md#requirevex"
|
||||
],
|
||||
"uncertainty_gate": "U1-low"
|
||||
},
|
||||
{
|
||||
"id": "VEX2.component_not_present",
|
||||
"title": "Component not present in runtime image",
|
||||
"description": "SBOM and runtime inventory confirm the vulnerable component is absent from the shipped artifact.",
|
||||
"applicability": [
|
||||
"not_affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"sbom_digest",
|
||||
"runtime_inventory",
|
||||
"config_hash"
|
||||
],
|
||||
"expiry_days": 60,
|
||||
"reevaluate_on": [
|
||||
"sbom_change",
|
||||
"runtime_change"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/modules/excititor/architecture.md#normalization"
|
||||
],
|
||||
"uncertainty_gate": "U1-low"
|
||||
},
|
||||
{
|
||||
"id": "VEX3.config_not_vulnerable",
|
||||
"title": "Configuration disables vulnerable feature",
|
||||
"description": "Configuration and feature flags disable the vulnerable execution path; enforced by config/flag hashing and negative tests.",
|
||||
"applicability": [
|
||||
"not_affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"config_hash",
|
||||
"flags_hash",
|
||||
"negative_tests"
|
||||
],
|
||||
"expiry_days": 45,
|
||||
"reevaluate_on": [
|
||||
"config_change",
|
||||
"flags_change",
|
||||
"runtime_change"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author",
|
||||
"release-manager"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/benchmarks/vex-evidence-playbook.md"
|
||||
],
|
||||
"uncertainty_gate": "U2-medium"
|
||||
},
|
||||
{
|
||||
"id": "VEX4.vulnerable_code_not_in_execute_path",
|
||||
"title": "Code not reachable from declared entrypoints",
|
||||
"description": "Reachability analysis shows no call paths from declared entrypoints to vulnerable functions; runtime probes corroborate.",
|
||||
"applicability": [
|
||||
"not_affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"graph_hash",
|
||||
"entrypoint_coverage>=95",
|
||||
"runtime_traces"
|
||||
],
|
||||
"expiry_days": 45,
|
||||
"reevaluate_on": [
|
||||
"graph_change",
|
||||
"runtime_change"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author",
|
||||
"signals-operator"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/reachability/function-level-evidence.md"
|
||||
],
|
||||
"uncertainty_gate": "U1-low"
|
||||
},
|
||||
{
|
||||
"id": "VEX5.mitigated_by_runtime_guard",
|
||||
"title": "Runtime guard blocks exploitation",
|
||||
"description": "Exploit is prevented by runtime guardrails (WAF/sandbox/feature flag) proven via negative test and telemetry.",
|
||||
"applicability": [
|
||||
"not_affected",
|
||||
"affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"runtime_traces",
|
||||
"negative_tests",
|
||||
"guard_policy"
|
||||
],
|
||||
"expiry_days": 30,
|
||||
"reevaluate_on": [
|
||||
"runtime_change",
|
||||
"policy_change"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author",
|
||||
"security-ops"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/uncertainty/README.md"
|
||||
],
|
||||
"uncertainty_gate": "U2-medium"
|
||||
},
|
||||
{
|
||||
"id": "VEX6.compensating_control_documented",
|
||||
"title": "Compensating control accepted",
|
||||
"description": "A documented compensating control reduces exploitability; requires approval evidence and expiry.",
|
||||
"applicability": [
|
||||
"affected",
|
||||
"under_investigation"
|
||||
],
|
||||
"required_evidence": [
|
||||
"control_record",
|
||||
"rbac_approval",
|
||||
"expiry"
|
||||
],
|
||||
"expiry_days": 30,
|
||||
"reevaluate_on": [
|
||||
"policy_change",
|
||||
"expiry"
|
||||
],
|
||||
"rbac": [
|
||||
"policy-admin",
|
||||
"risk-owner"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/migration/exception-governance.md"
|
||||
],
|
||||
"uncertainty_gate": "U3-high"
|
||||
},
|
||||
{
|
||||
"id": "VEX7.update_available",
|
||||
"title": "Update available and staged",
|
||||
"description": "Fix is available and staged for rollout; VEX documents status and planned activation window.",
|
||||
"applicability": [
|
||||
"affected",
|
||||
"fixed"
|
||||
],
|
||||
"required_evidence": [
|
||||
"fixed_version",
|
||||
"staging_hash",
|
||||
"rollout_window"
|
||||
],
|
||||
"expiry_days": 15,
|
||||
"reevaluate_on": [
|
||||
"rollout_change"
|
||||
],
|
||||
"rbac": [
|
||||
"release-manager"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/ui/advisories-and-vex.md"
|
||||
],
|
||||
"uncertainty_gate": "U2-medium"
|
||||
},
|
||||
{
|
||||
"id": "VEX8.analysis_ongoing",
|
||||
"title": "Analysis ongoing with SLA",
|
||||
"description": "Investigation underway with defined SLA and evidence collection plan.",
|
||||
"applicability": [
|
||||
"under_investigation"
|
||||
],
|
||||
"required_evidence": [
|
||||
"investigation_plan",
|
||||
"sla_date",
|
||||
"owner"
|
||||
],
|
||||
"expiry_days": 7,
|
||||
"reevaluate_on": [
|
||||
"sla_date"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/modules/excititor/architecture.md#normalization"
|
||||
],
|
||||
"uncertainty_gate": "U3-high"
|
||||
},
|
||||
{
|
||||
"id": "VEX9.eol_not_applicable",
|
||||
"title": "Product out of scope / EOL",
|
||||
"description": "Asset is out of scope or end-of-life and isolated; policy enforces quarantine rather than blanket ignore.",
|
||||
"applicability": [
|
||||
"not_affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"asset_scope",
|
||||
"quarantine_policy",
|
||||
"rbac_approval"
|
||||
],
|
||||
"expiry_days": 30,
|
||||
"reevaluate_on": [
|
||||
"asset_change"
|
||||
],
|
||||
"rbac": [
|
||||
"policy-admin"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/observability/policy.md"
|
||||
],
|
||||
"uncertainty_gate": "U2-medium"
|
||||
},
|
||||
{
|
||||
"id": "VEX10.false_positive_proven",
|
||||
"title": "Scanner false positive disproven",
|
||||
"description": "Deterministic reproduction shows the vulnerability is not actually present; includes counter-evidence and replay seed.",
|
||||
"applicability": [
|
||||
"not_affected"
|
||||
],
|
||||
"required_evidence": [
|
||||
"replay_manifest",
|
||||
"negative_tests",
|
||||
"sbom_digest"
|
||||
],
|
||||
"expiry_days": 45,
|
||||
"reevaluate_on": [
|
||||
"scanner_update",
|
||||
"sbom_change"
|
||||
],
|
||||
"rbac": [
|
||||
"vex-author",
|
||||
"qa"
|
||||
],
|
||||
"policy_links": [
|
||||
"docs/replay/DETERMINISTIC_REPLAY.md"
|
||||
],
|
||||
"uncertainty_gate": "U1-low"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -43,10 +43,12 @@
|
||||
| 13 | CONCELIER-WEB-OAS-63-001 | BLOCKED | Depends on 62-001 | WebService · API Governance | Emit deprecation headers/notifications steering clients to LNM APIs. |
|
||||
| 14 | CONCELIER-WEB-OBS-51-001 | DONE (2025-11-23) | Schema 046_TLTY0101 published 2025-11-23 | WebService Guild | `/obs/concelier/health` for ingest health/queue/SLO status. |
|
||||
| 15 | CONCELIER-WEB-OBS-52-001 | DONE (2025-11-24) | Depends on 51-001 | WebService Guild | SSE `/obs/concelier/timeline` with paging tokens, audit logging. |
|
||||
| 16 | CONCELIER-AIAI-31-002 | BLOCKED (2025-12-04) | No linkset store/cache backend exists; choose Mongo vs Postgres target and add cache collection/index + read-through wiring. | Concelier Core · Concelier WebService Guilds | Implement Link-Not-Merge linkset cache per `docs/modules/concelier/operations/lnm-cache-plan.md`, expose read-through on `/v1/lnm/linksets`, add metrics `lnm.cache.*`, and cover with deterministic tests. |
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | Added CONCELIER-AIAI-31-002 to Delivery Tracker and marked BLOCKED; cache plan exists but no linkset store/cache backend (Mongo/Postgres) is registered, so Link-Not-Merge cache cannot be implemented yet. | Project Mgmt |
|
||||
| 2025-12-03 | Added Wave Coordination (A observability done; B AirGap blocked; C AOC regression blocked on validator; D OAS alignment blocked). No status changes. | Project Mgmt |
|
||||
| 2025-11-25 | AOC validator (WEB-AOC-19-002) missing; blocked chain noted. | Implementer |
|
||||
| 2025-11-23 | OBS-52-001 done: SSE timeline stream shipped; audit logging active. | WebService |
|
||||
@@ -58,6 +60,7 @@
|
||||
- AirGap tasks blocked until sealed-mode + staleness metadata defined; do not expose bundles without provenance.
|
||||
- AOC regression chain blocked pending validator (WEB-AOC-19-002); large-batch tests must wait.
|
||||
- OAS envelope change (WEB-OAS-61-002) is a prereq for examples/deprecation; avoid duplicating client envelopes until unified.
|
||||
- Linkset cache (CONCELIER-AIAI-31-002) cannot proceed until a concrete store exists (Mongo vs Postgres) and cache collection/index contract is picked; current services register only `NullLinksetLookup`, so `/v1/lnm/linksets` lacks cache backing.
|
||||
|
||||
## Next Checkpoints
|
||||
- None scheduled; add when validator and AirGap prerequisites land.
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | Removed deprecated duplicate sprint file `docs/implplan/SPRINT_124_policy_reasoning.md`; canonical remains `docs/implplan/SPRINT_0124_0001_0001_policy_reasoning.md`. Updated console diff determinism test to compare serialized payloads; reran `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj -c Release --filter ConsoleSimulationDiffServiceTests` (pass: 1/1, 0.5s). | Implementer |
|
||||
| 2025-12-03 | Added Wave Coordination (Wave A core/storages done; Wave B Console simulation/export done; no open tasks). No status changes. | Project Mgmt |
|
||||
| 2025-12-02 | Fixed selection join canonical ordering (PurlEquivalence canonical now derived from sorted list, not hashset); `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj -c Release --no-build` now passes (211/211, 5.0s). | Implementer |
|
||||
| 2025-12-02 | Reran `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj -c Release --no-build`; failed 1/211 tests (`SelectionJoinTests.GetCanonical_ReturnsFirstLexicographically` expected `pkg:npm/a-package` but returned `pkg:npm/b-package`). Build duration 13.5s. Needs follow-up fix. | Implementer |
|
||||
@@ -70,11 +71,12 @@
|
||||
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
|
||||
|
||||
## Decisions & Risks
|
||||
- 2025-12-04: Console simulation diff determinism test now asserts serialized equality; targeted test run succeeded (1/1). Duplicate sprint file removed to enforce single source of truth.
|
||||
- 2025-12-02: POLICY-CONSOLE-23-001 contract published (`docs/modules/policy/contracts/policy-console-23-001-console-api.md`); POLICY-CONSOLE-23-002 unblocked—implement per contract with deterministic cursors/aggregates.
|
||||
- 2025-12-02: Selection join canonical ordering fixed (lexicographic first via ordered list). Regression resolved; full Policy Engine tests now passing.
|
||||
- Release test suite for Policy Engine now green (2025-12-02); keep enforcing deterministic inputs (explicit evaluationTimestamp) on batch evaluation requests to avoid non-deterministic clocks.
|
||||
- 2025-12-02: Targeted test run for new Console diff endpoint aborted after prolonged initial build; rerun `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj -c Release --filter ConsoleSimulationDiffServiceTests` once build cache is warm.
|
||||
|
||||
## Next Checkpoints
|
||||
- Provide Console export/simulation contract for 23-001 to unblock 23-002.
|
||||
- Rerun `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests` after workspace cleanup; capture results in Execution Log.
|
||||
- No pending checkpoints; Console contract delivered and console diff regression test rerun on 2025-12-04.
|
||||
- Monitor future advisories or Console contract deltas; open new wave if scope changes.
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
| 38 | SURFACE-FS-06 | DONE (2025-11-28) | SURFACE-FS-02..05 | Docs Guild | Update scanner-engine guide and offline kit docs with Surface.FS workflow. |
|
||||
| 39 | SCANNER-SURFACE-01 | BLOCKED (2025-11-25) | Task definition absent | Scanner Guild | Placeholder task; scope/contract required before implementation. |
|
||||
| 40 | SCANNER-SURFACE-04 | DONE (2025-12-02) | SCANNER-SURFACE-01, SURFACE-FS-03 | Scanner Worker Guild (`src/Scanner/StellaOps.Scanner.Worker`) | DSSE-sign every `layer.fragments` payload, emit `_composition.json`/`composition.recipe` URI, and persist DSSE envelopes for deterministic offline replay (see `deterministic-sbom-compose.md` §2.1). |
|
||||
| 41 | SURFACE-FS-07 | TODO | SCANNER-SURFACE-04 | Scanner Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS`) | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec (legacy TODO; superseded by row 42). |
|
||||
| 41 | SURFACE-FS-07 | DONE (2025-12-02, superseded by #42) | SCANNER-SURFACE-04 | Scanner Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS`) | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec (legacy TODO; superseded by row 42). |
|
||||
| 42 | SURFACE-FS-07 | DONE (2025-12-02) | SCANNER-SURFACE-04 | Scanner Guild | Surface.FS manifest schema carries composition recipe/DSSE attestations and determinism metadata; determinism verifier added for offline replay. |
|
||||
| 43 | SCANNER-EMIT-15-001 | DONE (2025-12-02) | SCANNER-SURFACE-04 | Scanner Emit Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Emit`) | CycloneDX artifacts carry content hash + Merkle root (= recipe hash), composition recipe URI, emit `_composition.json` + DSSE envelopes; DSSE signing now uses HMAC secret (Surface.Secrets or appsettings) with deterministic fallback logging. |
|
||||
| 44 | SCANNER-SORT-02 | DONE (2025-12-01) | SCANNER-EMIT-15-001 | Scanner Core Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Core`) | Layer fragment ordering by digest implemented in ComponentGraphBuilder; determinism regression test added. |
|
||||
@@ -72,6 +72,7 @@
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | Ran `dotnet test` for `StellaOps.Scanner.Surface.FS.Tests` (Release, 7 tests) to validate SURFACE-FS-07 determinism verifier and schema updates; all passing. | Implementer |
|
||||
| 2025-12-02 | Merged legacy `SPRINT_136_scanner_surface.md` content into canonical file; added missing tasks/logs; converted legacy file to stub to prevent divergence. | Project Mgmt |
|
||||
| 2025-12-02 | SCANNER-SURFACE-04 completed: manifest stage emits composition recipe + DSSE envelopes, attaches attestations to artifacts, and records determinism Merkle root/recipe metadata. | Implementer |
|
||||
| 2025-12-02 | SURFACE-FS-07 completed: Surface.FS manifest schema now includes determinism metadata, composition recipe attestation fields, determinism verifier, and docs updated. Targeted determinism tests added; test run pending due to long restore/build in monorepo runner. | Implementer |
|
||||
@@ -128,12 +129,12 @@
|
||||
| 2025-10-26 | Initial sprint plan captured; dependencies noted across Scheduler/Surface/Cartographer. | Planning |
|
||||
|
||||
## Decisions & Risks
|
||||
- SCANNER-LNM-21-001 delivered with Concelier shared-library resolver; linkset enrichment returns data when Concelier linkset store is configured, otherwise responses omit the `linksets` field (fallback null provider).
|
||||
- SCANNER-LNM-21-001 delivered with Concelier shared-library resolver; linkset enrichment returns data when Concelier linkset store is configured, otherwise responses omit the `linksets` field (fallback null provider).
|
||||
- SURFACE-SECRETS-06 BLOCKED pending Ops Helm/Compose patterns for Surface.Secrets provider configuration (kubernetes/file/inline).
|
||||
- SCANNER-EVENTS-16-301 BLOCKED awaiting orchestrator envelope contract + Notifier ingestion test plan.
|
||||
- SCANNER-SURFACE-01 lacks scoped contract; placeholder must be defined or retired before new dependencies are added.
|
||||
- SCANNER-EMIT-15-001 DOING: HMAC-backed DSSE signer added with deterministic fallback; enable by providing `Scanner:Worker:Signing:SharedSecret` (or file) + `KeyId`. Full scanner test suite still pending after cancelled long restore/build.
|
||||
- Long restore/build times in monorepo runners delayed determinism test runs for SURFACE-FS-07 and new signer; rerun targeted scanner worker tests in CI.
|
||||
- Long restore/build times in monorepo runners delayed determinism test runs for SURFACE-FS-07 and new signer; Surface.FS determinism tests now passing locally (Release); broader scanner suite still pending in CI.
|
||||
- Scheduler worker build/tests not run locally after manifest prefetch wiring (NuGet restore timeout); verify in CI.
|
||||
|
||||
## Next Checkpoints
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
| 2 | SBOM-AIAI-31-002 | DONE | Metrics + cache-hit tagging implemented; Grafana starter dashboard added; build/test completed locally. | SBOM Service Guild; Observability Guild | Instrument metrics for path/timeline queries and surface dashboards. |
|
||||
| 3 | SBOM-CONSOLE-23-001 | DONE (2025-12-03) | DEVOPS-SBOM-23-001 feed delivered; console catalog endpoint implemented and tested (`dotnet test ... --filter Console_`). | SBOM Service Guild; Cartographer Guild | Provide Console-focused SBOM catalog API. |
|
||||
| 4 | SBOM-CONSOLE-23-002 | DONE (2025-12-03) | Component lookup endpoint validated (tests passing with pagination/filtering); using vetted feed and seeded data until storage wiring lands. | SBOM Service Guild | Deliver component lookup endpoints for search and overlays. |
|
||||
| 16 | SBOM-CONSOLE-23-101-STORAGE | TODO | Follow-up to replace seeded catalog/component lookup with Mongo-backed storage and update docs/tests. | SBOM Service Guild | Wire console catalog + component lookup to storage/outbox and refresh fixtures/docs for release. |
|
||||
| 16 | SBOM-CONSOLE-23-101-STORAGE | DONE (2025-12-04) | Follow-up to replace seeded catalog/component lookup with Mongo-backed storage and update docs/tests. | SBOM Service Guild | Wire console catalog + component lookup to storage/outbox and refresh fixtures/docs for release. |
|
||||
| 5 | SBOM-ORCH-32-001 | DONE (2025-11-23) | In-memory orchestrator source registry with deterministic seeds + idempotent registration exposed at `/internal/orchestrator/sources`. | SBOM Service Guild | Register SBOM ingest/index sources with orchestrator. |
|
||||
| 6 | SBOM-ORCH-33-001 | DONE (2025-11-23) | Pause/throttle/backpressure controls added via `/internal/orchestrator/control`; metrics emitted; states deterministic per-tenant. | SBOM Service Guild | Report backpressure metrics and handle orchestrator control signals. |
|
||||
| 7 | SBOM-ORCH-34-001 | DONE (2025-11-23) | Watermark store + endpoints (`/internal/orchestrator/watermarks`) added to track backfill/watermark reconciliation; deterministic ordering. | SBOM Service Guild | Implement orchestrator backfill + watermark reconciliation. |
|
||||
@@ -52,6 +52,8 @@
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | SBOM-CONSOLE-23-101-STORAGE marked DONE: Mongo-backed catalog + component lookup with configurable collections; docs updated; tests (`dotnet test src/SbomService/StellaOps.SbomService.Tests/StellaOps.SbomService.Tests.csproj --nologo`) pass. | Implementer |
|
||||
| 2025-12-04 | SBOM-CONSOLE-23-101-STORAGE moved to DOING; starting Mongo-backed wiring for console catalog/component lookup. | Project Mgmt |
|
||||
| 2025-12-03 | SBOM-CONSOLE-23-002 marked DONE after component lookup pagination/filter tests (`dotnet test ... --filter Console_|Components_lookup_requires_purl_and_paginates --no-build`) passed; endpoint validated with vetted feed + seeded data. | Project Mgmt |
|
||||
| 2025-12-03 | SBOM-CONSOLE-23-001 marked DONE after console endpoint tests (`dotnet test src/SbomService/StellaOps.SbomService.Tests/StellaOps.SbomService.Tests.csproj --no-build --filter Console_`) passed. SBOM-CONSOLE-23-002 moved to DOING. | Project Mgmt |
|
||||
| 2025-12-03 | Ran targeted console endpoint test (`dotnet test ... --filter Console_sboms_supports_filters_and_cursor --no-build`); passes. SBOM-CONSOLE-23-001 remains DOING. | Implementer |
|
||||
@@ -111,8 +113,8 @@
|
||||
|
||||
## Decisions & Risks
|
||||
- LNM v1 fixtures staged (2025-11-22) and approved; hash recorded in `docs/modules/sbomservice/fixtures/lnm-v1/SHA256SUMS`. SBOM-SERVICE-21-001/002/003/004 are DONE.
|
||||
- DEVOPS-SBOM-23-001 delivered 2025-11-30 (Sprint 503) providing vetted offline feed + CI proof; SBOM-CONSOLE-23-001 and SBOM-CONSOLE-23-002 are DONE (2025-12-03) using vetted feed + seeded data; storage-backed version still to follow.
|
||||
- Console endpoints validated via tests; current implementation uses in-memory/catalog seeds—replace with Mongo-backed projections before release and update docs accordingly. Track storage wiring as follow-up (new task below).
|
||||
- DEVOPS-SBOM-23-001 delivered 2025-11-30 (Sprint 503) providing vetted offline feed + CI proof; SBOM-CONSOLE-23-001 and SBOM-CONSOLE-23-002 are DONE (2025-12-03) using vetted feed + seeded data.
|
||||
- SBOM-CONSOLE-23-101-STORAGE (2025-12-04): `/console/sboms` and `/components/lookup` now use Mongo-backed repositories when `SbomService:Mongo:ConnectionString` is set (configurable database/collection names); fallback to fixture/in-memory seeds remains for air-gapped runs. Docs updated in `docs/modules/sbomservice/architecture.md`.
|
||||
- Projection endpoint validated (400 without tenant, 200 with fixture data) via WebApplicationFactory; WAF configured with fixture path + in-memory component repo fallback.
|
||||
- `sbom.version.created` now emitted via in-memory publisher with `/internal/sbom/events` + backfill endpoint; production outbox/queue wiring still required before release.
|
||||
- Component lookup pagination now returns deterministic `nextCursor` for seeded data (fixed null cursor bug).
|
||||
@@ -123,8 +125,6 @@
|
||||
- Orchestrator control/backpressure/watermarks implemented in-memory; replace with real orchestrator contract before release.
|
||||
- Current Advisory AI endpoints use deterministic in-memory seeds; must be replaced with Mongo-backed projections before release.
|
||||
- Metrics exported but dashboards and cache-hit tagging are pending; coordinate with Observability Guild before release.
|
||||
- Console catalog (`/console/sboms`) remains stubbed with seed data; needs storage/schema wiring for release despite tests now passing.
|
||||
- Component lookup endpoint is stubbed; SBOM-CONSOLE-23-002 remains blocked on storage wiring rather than build/test infra.
|
||||
- SBOM-AIAI-31-002 stays pending dashboards + validated metrics; feeds/builds now healthy after offline cache fixes.
|
||||
- `AGENTS.md` for `src/SbomService` added 2025-11-18; implementers must read before coding.
|
||||
- AirGap parity review template published at `docs/modules/sbomservice/runbooks/airgap-parity-review.md`; review execution still required for air-gapped signoff on SBOM-SERVICE-21-002..004 (21-001 implementation validated locally).
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED | PREP-RUNBOOK-REPLAY-187-004-DEPENDS-ON-RETENT | Docs Guild · Ops Guild | Publish `/docs/runbooks/replay_ops.md` coverage for retention enforcement, RootPack rotation, verification drills. |
|
||||
| 5 | CRYPTO-REGISTRY-DECISION-161 | DONE | Decision recorded in `docs/security/crypto-registry-decision-2025-11-18.md`; publish contract defaults. | Security Guild · Evidence Locker Guild | Capture decision from 2025-11-18 review; emit changelog + reference implementation for downstream parity. |
|
||||
| 6 | EVID-CRYPTO-90-001 | DONE | Implemented; `MerkleTreeCalculator` now uses `ICryptoProviderRegistry` for sovereign crypto routing. | Evidence Locker Guild · Security Guild | Route hashing/signing/bundle encryption through `ICryptoProviderRegistry`/`ICryptoHash` for sovereign crypto providers. |
|
||||
| 7 | EVID-GAPS-161-007 | TODO | None; informs tasks 1–6. | Product Mgmt · Evidence Locker Guild · CLI Guild | Address EB1–EB10 from `docs/product-advisories/28-Nov-2025 - Evidence Bundle and Replay Contracts.md`: publish `bundle.manifest.schema.json` + `checksums.schema.json` (canonical JSON), hash/Merkle recipe doc, mandatory DSSE predicate/log policy, replay provenance block, chunking/CAS rules, incident-mode signed activation/exit, tenant isolation + redaction manifest, offline verifier script (`docs/modules/evidence-locker/verify-offline.md`), golden bundles/replay fixtures under `tests/EvidenceLocker/Bundles/Golden`, and SemVer/change-log updates. |
|
||||
| 7 | EVID-GAPS-161-007 | DOING (2025-12-04) | See EB1–EB10 plan `docs/modules/evidence-locker/eb-gaps-161-007-plan.md`; schemas + offline guide drafted. | Product Mgmt · Evidence Locker Guild · CLI Guild | Address EB1–EB10 from `docs/product-advisories/28-Nov-2025 - Evidence Bundle and Replay Contracts.md`: publish `bundle.manifest.schema.json` + `checksums.schema.json` (canonical JSON), hash/Merkle recipe doc, mandatory DSSE predicate/log policy, replay provenance block, chunking/CAS rules, incident-mode signed activation/exit, tenant isolation + redaction manifest, offline verifier script (`docs/modules/evidence-locker/verify-offline.md`), golden bundles/replay fixtures under `tests/EvidenceLocker/Bundles/Golden`, and SemVer/change-log updates. |
|
||||
|
||||
## Action Tracker
|
||||
| Action | Owner(s) | Due | Status |
|
||||
@@ -59,6 +59,7 @@
|
||||
| Schema readiness | BLOCKED | Waiting on AdvisoryAI + orchestrator envelopes; no DOING until frozen. |
|
||||
| Crypto routing approval | DONE | Defaults recorded in `docs/security/crypto-registry-decision-2025-11-18.md`; implement in EvidenceLocker/CLI. |
|
||||
| Template & filename normalization | DONE (2025-11-17) | Renamed to `SPRINT_0161_0001_0001_evidencelocker.md`; structure aligned to sprint template. |
|
||||
| EB1–EB10 policy freeze | OPEN | Gap plan at `docs/modules/evidence-locker/eb-gaps-161-007-plan.md`; DSSE predicate/log policy, redaction map, and chunking rules still need sign-off. |
|
||||
|
||||
### Risk table
|
||||
| Risk | Severity | Mitigation / Owner |
|
||||
@@ -88,3 +89,4 @@
|
||||
| 2025-11-27 | Completed EVID-CRYPTO-90-001: Extended `ICryptoProviderRegistry` with `ContentHashing` capability and `ResolveHasher` method; created `ICryptoHasher` interface with `DefaultCryptoHasher` implementation; wired `MerkleTreeCalculator` to use crypto registry for sovereign crypto routing; added `EvidenceCryptoOptions` for algorithm/provider configuration. | Implementer |
|
||||
| 2025-12-01 | Added EVID-GAPS-161-007 to capture EB1–EB10 remediation from `docs/product-advisories/28-Nov-2025 - Evidence Bundle and Replay Contracts.md`. | Product Mgmt |
|
||||
| 2025-12-02 | Scoped EVID-GAPS-161-007 deliverables: schemas + DSSE, Merkle recipe, replay provenance, chunk/CAS rules, incident governance, tenant redaction, offline verifier doc, golden fixtures path, and SemVer/change-log updates. | Project Mgmt |
|
||||
| 2025-12-04 | Moved EVID-GAPS-161-007 to DOING; drafted EB1/EB2 schemas, offline verifier guide, gap plan, and golden fixtures path. | Project Mgmt |
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
| 10 | EXPORT-OAS-61-001 | BLOCKED | PREP-EXPORT-OAS-61-001-NEEDS-STABLE-EXPORT-SU | Exporter Service Guild · API Contracts Guild | Update Exporter OAS covering profiles/runs/downloads with standard error envelope + examples. |
|
||||
| 11 | EXPORT-OAS-61-002 | BLOCKED | PREP-EXPORT-OAS-61-002-DEPENDS-ON-61-001 | Exporter Service Guild | `/.well-known/openapi` discovery endpoint with version metadata and ETag. |
|
||||
| 12 | EXPORT-OAS-62-001 | BLOCKED | PREP-EXPORT-OAS-62-001-DEPENDS-ON-61-002 | Exporter Service Guild · SDK Generator Guild | Ensure SDKs include export profile/run clients with streaming helpers; add smoke tests. |
|
||||
| 13 | EXPORT-GAPS-162-013 | TODO | None; informs tasks 1–12. | Product Mgmt · Exporter Guild · Evidence Locker Guild | Address EC1–EC10 from `docs/product-advisories/28-Nov-2025 - Export Center and Reporting Strategy.md`: publish signed ExportProfile + manifest schemas with selector validation; define per-adapter determinism rules + rerun-hash CI; mandate DSSE/SLSA attestation with log metadata; enforce cross-tenant approval flow; require distribution integrity headers + OCI annotations; pin Trivy schema versions; formalize mirror delta/tombstone rules; document encryption/recipient policy; set quotas/backpressure; and produce offline export kit + verify script under `docs/modules/export-center/determinism.md` with fixtures in `src/ExportCenter/__fixtures`. |
|
||||
| 13 | EXPORT-GAPS-162-013 | DONE (2025-12-04) | None; informs tasks 1–12. | Product Mgmt · Exporter Guild · Evidence Locker Guild | Address EC1–EC10 from `docs/product-advisories/28-Nov-2025 - Export Center and Reporting Strategy.md`: publish signed ExportProfile + manifest schemas with selector validation; define per-adapter determinism rules + rerun-hash CI; mandate DSSE/SLSA attestation with log metadata; enforce cross-tenant approval flow; require distribution integrity headers + OCI annotations; pin Trivy schema versions; formalize mirror delta/tombstone rules; document encryption/recipient policy; set quotas/backpressure; and produce offline export kit + verify script under `docs/modules/export-center/determinism.md` with fixtures in `src/ExportCenter/__fixtures`. |
|
||||
|
||||
## Action Tracker
|
||||
| Action | Owner(s) | Due | Status |
|
||||
@@ -82,6 +82,7 @@
|
||||
| EvidenceLocker contract dependency | BLOCKED | All export tasks wait on sealed bundle spec + DSSE layout. |
|
||||
| Orchestrator/Notifications envelope dependency | BLOCKED | Notifications and timeline events cannot commence until schema lands. |
|
||||
| Crypto routing plan | PENDING | To be validated at 2025-11-18 review (`EXPORT-CRYPTO-90-001`). |
|
||||
| EC1–EC10 remediation | DONE (2025-12-04) | Schemas, determinism rules, Trivy pinning, mirror delta tombstones, approval/quotas, integrity headers, and offline verify script with fixtures recorded. |
|
||||
|
||||
### Risk table
|
||||
| Risk | Severity | Mitigation / Owner |
|
||||
@@ -113,3 +114,4 @@
|
||||
| 2025-11-12 | Snapshot captured (pre-template) with tasks TODO. | Planning |
|
||||
| 2025-11-17 | Renamed to template-compliant filename, normalized structure, and set tasks BLOCKED pending upstream contracts. | Implementer |
|
||||
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
|
||||
| 2025-12-04 | Closed EXPORT-GAPS-162-013: added signed profile/manifest schemas, determinism + rerun-hash rules, DSSE/SLSA log metadata, cross-tenant approval/quotas, mirror delta tombstone policy, Trivy schema pinning, and offline verify script with fixtures. | Project Mgmt |
|
||||
|
||||
@@ -34,11 +34,12 @@
|
||||
| 11 | NOTIFY-RISK-68-001 | BLOCKED (2025-11-22) | Depends on 67-001. | Notifications Service Guild | Per-profile routing, quiet hours, dedupe for risk alerts; integrate CLI/Console preferences. |
|
||||
| 12 | NOTIFY-DOC-70-001 | DONE (2025-11-02) | — | Notifications Service Guild | Document split between legacy `src/Notify` libs and new `src/Notifier` runtime; update architecture docs. |
|
||||
| 13 | NOTIFY-AIRGAP-56-002 | DONE | — | Notifications Service Guild · DevOps Guild | Bootstrap Pack notifier configs with deterministic secrets handling and offline validation. |
|
||||
| 14 | NOTIFY-GAPS-171-014 | TODO | Close NR1–NR10 from `31-Nov-2025 FINDINGS.md`; depends on schema/catalog refresh | Notifications Service Guild / src/Notifier/StellaOps.Notifier | Remediate NR1–NR10: publish signed schemas + canonical JSON, enforce tenant scoping/approvals, deterministic rendering, quotas/backpressure + DLQ, retry/idempotency policy, webhook/ack security, redaction/PII limits, observability SLO alerts, offline notify-kit with DSSE, and mandatory simulations + evidence for rule/template changes. |
|
||||
| 14 | NOTIFY-GAPS-171-014 | BLOCKED (2025-12-04) | Waiting on NR1–NR10 details in `31-Nov-2025 FINDINGS.md` + schema/catalog refresh | Notifications Service Guild / src/Notifier/StellaOps.Notifier | Remediate NR1–NR10: publish signed schemas + canonical JSON, enforce tenant scoping/approvals, deterministic rendering, quotas/backpressure + DLQ, retry/idempotency policy, webhook/ack security, redaction/PII limits, observability SLO alerts, offline notify-kit with DSSE, and mandatory simulations + evidence for rule/template changes. |
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | Marked NOTIFY-GAPS-171-014 BLOCKED pending publication of NR1–NR10 details in `31-Nov-2025 FINDINGS.md` and schema/catalog refresh. | Implementer |
|
||||
| 2025-11-19 | Fixed PREP-NOTIFY-OBS-51-001 Task ID (removed trailing hyphen) so dependency lookup works. | Project Mgmt |
|
||||
| 2025-12-01 | Added NOTIFY-GAPS-171-014 (NR1–NR10 from `31-Nov-2025 FINDINGS.md`) to track advisory gap remediation; status TODO pending schema/catalog refresh. | Project Mgmt |
|
||||
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
|
||||
@@ -71,6 +72,7 @@
|
||||
- Risk alerts depend on POLICY-RISK-40-002 export; schedule slip would re-baseline RISK tasks.
|
||||
- Keep Offline Kit parity for templates and secrets handling before enabling new endpoints.
|
||||
- Advisory gap remediation (NR1–NR10) added as NOTIFY-GAPS-171-014; requires schema/catalog refresh, tenant/approval enforcement, deterministic rendering, quotas/backpressure/DLQ, retry/idempotency policy, webhook/ack security, redaction/PII limits, observability SLO alerts, offline notify-kit with DSSE, and mandatory simulation evidence before activation.
|
||||
- NOTIFY-GAPS-171-014 is currently blocked because NR1–NR10 findings are not yet defined in `31-Nov-2025 FINDINGS.md`; schema/catalog refresh must accompany that publication before remediation can start.
|
||||
|
||||
## Next Checkpoints
|
||||
| Date (UTC) | Milestone | Owner(s) |
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
| 17 | UI-POLICY-DET-01 | DONE | UI-SBOM-DET-01 | UI Guild; Policy Guild (src/UI/StellaOps.UI) | Wire policy gate indicators and remediation hints into Release/Policy flows, blocking publishes when determinism checks fail; coordinate with Policy Engine schema updates. |
|
||||
| 18 | UI-ENTROPY-40-001 | DONE | - | UI Guild (src/UI/StellaOps.UI) | Visualise entropy analysis per image (layer donut, file heatmaps, "Why risky?" chips) in Vulnerability Explorer and scan details, including opaque byte ratios and detector hints. |
|
||||
| 19 | UI-ENTROPY-40-002 | DONE | UI-ENTROPY-40-001 | UI Guild; Policy Guild (src/UI/StellaOps.UI) | Add policy banners/tooltips explaining entropy penalties (block/warn thresholds, mitigation steps) and link to raw `entropy.report.json` evidence downloads. |
|
||||
| 20 | UI-MICRO-GAPS-0209-011 | TODO | 30-Nov-2025 Micro-Interactions advisory; requires token catalog and a11y test harness | UI Guild; UX Guild; Accessibility Guild | Close MI1–MI10: define motion tokens + reduced-motion rules, perf budgets, offline/latency/error patterns, component mapping, telemetry schema/flags, deterministic seeds/snapshots, micro-copy localisation, and theme/contrast guidance; add Storybook/Playwright checks. |
|
||||
| 20 | UI-MICRO-GAPS-0209-011 | BLOCKED | Canonical 30-Nov-2025 UI Micro-Interactions advisory missing; Angular workspace absent; requires token catalog and a11y test harness | UI Guild; UX Guild; Accessibility Guild | Close MI1–MI10: define motion tokens + reduced-motion rules, perf budgets, offline/latency/error patterns, component mapping, telemetry schema/flags, deterministic seeds/snapshots, micro-copy localisation, and theme/contrast guidance; add Storybook/Playwright checks. |
|
||||
|
||||
## Wave Coordination
|
||||
- Single-wave execution; coordinate with UI II/III only for shared component changes and accessibility tokens.
|
||||
@@ -74,6 +74,8 @@
|
||||
| 3 | Deliver entropy evidence fixture snapshot for UI-ENTROPY-40-001 | Scanner Guild | 2025-11-28 | BLOCKED (fixtures unavailable locally; workspace missing) |
|
||||
| 4 | Provide AOC verifier endpoint parity notes for UI-AOC-19-003 | Notifier Guild | 2025-11-27 | BLOCKED (UI workspace unavailable to consume parity notes) |
|
||||
| 5 | Receive SDK parity matrix (Wave B, SPRINT_0208_0001_0001_sdk) to unblock Console data providers and scope exports | UI Guild · SDK Generator Guild | 2025-12-16 | BLOCKED (awaiting SDK parity delivery + workspace restore) |
|
||||
| 6 | Publish canonical UI Micro-Interactions advisory (MI1–MI10) with motion tokens, reduced-motion rules, and fixtures referenced by this sprint | Product Mgmt · UX Guild | 2025-12-06 | TODO |
|
||||
| 7 | Restore Angular workspace under `src/UI/StellaOps.UI` to enable Storybook/Playwright harness and token catalog | UI Guild | 2025-12-05 | TODO |
|
||||
|
||||
## Decisions & Risks
|
||||
| Risk | Impact | Mitigation / Next Step |
|
||||
@@ -82,10 +84,12 @@
|
||||
| Policy determinism schema changes late | UI-POLICY-DET-01 cannot ship with gates | Coordinate with Policy Engine owners (Action #2) and keep UI feature-flagged. |
|
||||
| Entropy evidence format changes | Rework for UI-ENTROPY-* views | Lock to `docs/modules/scanner/entropy.md`; add contract test fixtures before UI wiring. |
|
||||
| Angular workspace missing | UI-GRAPH-24-* blocked | Restore Angular workspace under `src/UI/StellaOps.UI` and deliver generated `graph:*` scope exports before continuing Graph UI work. |
|
||||
| Canonical UI Micro-Interactions advisory missing | UI-MICRO-GAPS-0209-011 cannot be scoped; MI1–MI10 acceptance unclear | Action #6 to publish advisory; keep task BLOCKED until canonical document and fixtures land. |
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | Began UI-MICRO-GAPS-0209-011; canonical 30-Nov-2025 UI Micro-Interactions advisory is missing and Angular workspace `src/UI/StellaOps.UI` is empty. Marked task BLOCKED; added Actions #6–#7 to publish advisory and restore workspace before scoping MI1–MI10 tokens/tests. | Project mgmt |
|
||||
| 2025-12-03 | Marked UI-GRAPH-24-001/002/003/004/006 BLOCKED: Angular workspace is absent under `src/UI/StellaOps.UI` and generated `graph:*` scope SDK exports are missing; cannot render canvas or overlays until workspace and SDK parity land. | Implementer |
|
||||
| 2025-11-27 | UI-GRAPH-21-001: Created stub `StellaOpsScopes` exports and integrated auth configuration into Graph Explorer. Created `scopes.ts` with: typed scope constants (`GRAPH_READ`, `GRAPH_WRITE`, `GRAPH_ADMIN`, `GRAPH_EXPORT`, `GRAPH_SIMULATE` and scopes for SBOM, Scanner, Policy, Exception, Release, AOC, Admin domains), scope groupings (`GRAPH_VIEWER`, `GRAPH_EDITOR`, `GRAPH_ADMIN`, `RELEASE_MANAGER`, `SECURITY_ADMIN`), human-readable labels, and helper functions (`hasScope`, `hasAllScopes`, `hasAnyScope`). Created `auth.service.ts` with `AuthService` interface and `MockAuthService` implementation providing: user info with tenant context, scope-based permission methods (`canViewGraph`, `canEditGraph`, `canExportGraph`, `canSimulate`). Integrated into `GraphExplorerComponent` via `AUTH_SERVICE` injection token: added computed signals for scope-based permissions (`canViewGraph`, `canEditGraph`, `canExportGraph`, `canSimulate`, `canCreateException`), current user info, and user scopes list. Stub implementation allows Graph Explorer development to proceed; will be replaced by generated SDK exports from SPRINT_0208_0001_0001_sdk. Files added: `src/app/core/auth/scopes.ts`, `src/app/core/auth/auth.service.ts`, `src/app/core/auth/index.ts`. Files updated: `graph-explorer.component.ts`. | UI Guild |
|
||||
| 2025-11-27 | UI-AOC-19-001/002/003: Implemented Sources dashboard with AOC metrics tiles, violation drill-down, and "Verify last 24h" action. Created domain models (`aoc.models.ts`) for AocDashboardSummary, AocPassFailSummary, AocViolationCode, IngestThroughput, AocSource, AocCheckResult, VerificationRequest, ViolationDetail, OffendingField, and ProvenanceMetadata. Created mock API service (`aoc.client.ts`) with fixtures showing pass/fail metrics, 5 violation codes (AOC-001 through AOC-020), 4 tenant throughput records, 4 sources (registry, pipeline, manual), and sample check results. Built `AocDashboardComponent` (`/sources` route) with 3 tiles: (1) Pass/Fail tile with large pass rate percentage, trend indicator (improving/stable/degrading), mini 7-day chart, passed/failed/pending counts; (2) Recent Violations tile with severity badges, violation codes, names, counts, and modal detail view; (3) Ingest Throughput tile with total documents/bytes and per-tenant breakdown table. Added Sources section showing source cards with type icons, pass rates, recent violation chips, and last check time. Implemented "Verify Last 24h" button triggering verification endpoint with progress feedback and CLI parity command display (`stella aoc verify --since 24h --output json`). Created `ViolationDetailComponent` (`/sources/violations/:code` route) showing all occurrences of a violation code with: offending fields list (JSON path, expected vs actual values, reason), provenance metadata (source type/URI, build ID, commit SHA, pipeline URL), and suggested fix. Files added: `src/app/core/api/aoc.{models,client}.ts`, `src/app/features/sources/aoc-dashboard.component.{ts,html,scss}`, `violation-detail.component.ts`, `index.ts`. Routes registered at `/sources` and `/sources/violations/:code`. | UI Guild |
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
- Establish the first milestone (`Md.I`) for docs process reform covering Advisory AI guardrails, air-gap guides, and deterministic scanner documentation.
|
||||
- Capture cross-guild prerequisites so downstream module dossiers can start once Md.I closes.
|
||||
- Keep deliverables deterministic (golden outputs, reproducible screenshots, signed fixtures).
|
||||
- **Working directory:** `docs/` (fixtures under `docs/assets/advisory-ai/console/`; JSON samples under `docs/api/console/samples/`).
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- Requires upstream artefacts from Sprint 110.A (Advisory AI), Sprint 120 (Policy knobs), Sprint 136 (Scanner determinism), Sprint 160 (Evidence Locker), and Sprint 190 (Ops deployment).
|
||||
@@ -21,7 +22,7 @@
|
||||
| Task ID | Status | Owner(s) | Dependencies | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| DOCS-UNBLOCK-CLI-KNOBS-301 | DONE (2025-11-25) | CLI Guild · Policy Guild · DevEx Guild | CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001 delivered 2025-11-24. | Packaged fixtures/changelogs consumed by DOCS-AIAI-31-005..009. |
|
||||
| DOCS-AIAI-31-004 | DONE (2025-12-03) | Docs Guild · Console Guild | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-003 delivered. | Guardrail console guide refreshed with deterministic capture/payload + hashes (`docs/advisory-ai/console.md`). |
|
||||
| DOCS-AIAI-31-004 | DONE (2025-12-04) | Docs Guild · Console Guild | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-003 delivered. | Guardrail console guide refreshed with deterministic capture/payload + consolidated hash manifest (`docs/advisory-ai/console-fixtures.sha256`) and verification steps. |
|
||||
| DOCS-AIAI-31-005 | DONE (2025-11-25) | Docs Guild · DevEx/CLI Guild | DOCS-AIAI-31-004; CLI-VULN-29-001; CLI-VEX-30-001 | CLI guide published with exit codes + offline hashes (`docs/advisory-ai/cli.md`). |
|
||||
| DOCS-AIAI-31-006 | DONE (2025-11-25) | Docs Guild · Policy Guild | DOCS-AIAI-31-005; POLICY-ENGINE-31-001 | Assistant parameter doc refreshed (`docs/policy/assistant-parameters.md`). |
|
||||
| DOCS-AIAI-31-008 | DONE (2025-11-25) | Docs Guild · SBOM Service Guild | DOCS-AIAI-31-007; SBOM-AIAI-31-001 | Remediation heuristics documented with fixtures (`docs/sbom/remediation-heuristics.md`). |
|
||||
@@ -39,6 +40,9 @@
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | DOCS-AIAI-31-004 DONE: added `docs/advisory-ai/console-fixtures.sha256`, hash table + verification snippet to console guide. | Docs Guild |
|
||||
| 2025-12-04 | Moved DOCS-AIAI-31-004 to DOING to add hash manifest/table for console fixtures; kept determinism protocol. | Docs Guild |
|
||||
| 2025-12-04 | Reopened DOCS-AIAI-31-004 to add fixture hash verification and renumber publication section; added `docs/AGENTS.md` for docs working directory; republished doc and kept task at DONE. | Docs Guild |
|
||||
| 2025-12-03 | Renamed sprint file to `SPRINT_0301_0001_0001_docs_md_i.md` to match naming template; no content removed. | Project Mgmt |
|
||||
| 2025-12-03 | Reopened DOCS-AIAI-31-004 and DOCS-SCANNER-DET-01 for final publication using newly generated deterministic fixtures/captures. | Project Mgmt |
|
||||
| 2025-12-03 | DOCS-AIAI-31-004 DONE: guardrail console doc updated with validated guardrail sample, deterministic list-view payload/svg + hashes, and regeneration steps. | Docs Guild |
|
||||
@@ -63,6 +67,7 @@
|
||||
### Decisions
|
||||
| Decision | Owner(s) | Due | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| Documented docs working agreement | Docs Guild | 2025-12-04 | Added `docs/AGENTS.md` covering scope, determinism, and sprint status rules for docs work. |
|
||||
| Confirm Advisory AI asset delivery dates | SBOM Service · CLI · Policy · DevOps Guilds | 2025-11-14 | Closed 2025-11-25: SBOM/CLI/Policy/DevOps artefacts delivered; DOCS-AIAI-31-004/005/006/008/009 published (see Execution Log 2025-12-03). |
|
||||
| Approve Scanner determinism fixture scope | Scanner Guild | 2025-11-16 | Closed 2025-12-03: fixture bundle published at `docs/modules/scanner/fixtures/deterministic-compose/`; DOCS-SCANNER-DET-01 signed off. |
|
||||
| Provide AirGap time anchor policy draft | AirGap Time Guild | 2025-11-19 | Closed 2025-11-23: inputs delivered for DOCS-AIRGAP-57-001/002 publication. |
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
| 59 | NATIVE-CALLGRAPH-INGEST-401-059 | BLOCKED (2025-11-30) | Depends on task 1 graph schema + native symbolizer readiness; hold until 2025-12-02 checkpoint. | Scanner Guild (`src/Scanner/StellaOps.Scanner.CallGraph.Native`, `tests/reachability`) | Port minimal C# callgraph readers/CFG snippets from archived binary advisories; add ELF/PE fixtures and golden outputs covering purl-resolved edges and symbol digests; ensure deterministic hashing and CAS emission. |
|
||||
| 60 | CORPUS-MERGE-401-060 | BLOCKED (2025-11-30) | After 58 schema settled; blocked until dataset freeze post 2025-12-02 checkpoint. | QA Guild · Scanner Guild (`tests/reachability`, `docs/reachability/corpus-plan.md`) | Merge archived multi-runtime corpus (Go/.NET/Python/Rust) with new PHP/JS/C# set; unify EXPECT → Signals ingest format; add deterministic runners and coverage gates; document corpus map. |
|
||||
| 61 | DOCS-BENCH-401-061 | DONE (2025-11-26) | Blocks on outputs from 57–60. | Docs Guild (`docs/benchmarks/signals/bench-determinism.md`, `docs/reachability/corpus-plan.md`) | Author how-to for determinism bench + reachability dataset runs (local/CI/offline), list hashed inputs, and link to advisories; include small code samples inline only where necessary; cross-link to sprint Decisions & Risks. |
|
||||
| 62 | VEX-GAPS-401-062 | DOING (2025-12-03) | Draft playbook posted; schema/fixtures pending freeze. | Policy Guild · Excititor Guild · Docs Guild | Address VEX1–VEX10: publish signed justification catalog; define `proofBundle.schema.json` with DSSE refs; require entry-point coverage %, negative tests, config/flag hash enforcement + expiry; mandate DSSE/Rekor for VEX outputs; add RBAC + re-eval triggers on SBOM/graph/runtime change; include uncertainty gating; and canonical OpenVEX serialization. Draft playbook at `docs/benchmarks/vex-evidence-playbook.md`; fixtures to land under `tests/Vex/ProofBundles/`. |
|
||||
| 62 | VEX-GAPS-401-062 | DONE (2025-12-04) | Schema/catalog frozen; fixtures + verifier landed. | Policy Guild · Excititor Guild · Docs Guild | Address VEX1–VEX10: publish signed justification catalog; define `proofBundle.schema.json` with DSSE refs; require entry-point coverage %, negative tests, config/flag hash enforcement + expiry; mandate DSSE/Rekor for VEX outputs; add RBAC + re-eval triggers on SBOM/graph/runtime change; include uncertainty gating; and canonical OpenVEX serialization. Playbook + schema at `docs/benchmarks/vex-evidence-playbook.{md,schema.json}`; catalog at `docs/benchmarks/vex-justifications.catalog.json` (+ DSSE); fixtures under `tests/Vex/ProofBundles/`; offline verifier `scripts/vex/verify_proof_bundle.py`; CI guard `.gitea/workflows/vex-proof-bundles.yml`. |
|
||||
| 63 | GRAPHREV-GAPS-401-063 | TODO | None; informs tasks 1, 11, 37–41. | Platform Guild · Scanner Guild · Policy Guild · UI/CLI Guilds | Address graph revision gaps GR1–GR10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: manifest schema + canonical hash rules, mandated BLAKE3-256 encoding, append-only storage, lineage/diff metadata, cross-artifact digests (SBOM/VEX/policy/tool), UI/CLI surfacing of full/short IDs, shard/tenant context, pin/audit governance, retention/tombstones, and inclusion in offline kits. |
|
||||
| 64 | EXPLAIN-GAPS-401-064 | TODO | None; informs tasks 13–15, 21, 47. | Policy Guild · UI/CLI Guild · Docs Guild · Signals Guild | Address explainability gaps EX1–EX10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: schema/canonicalization + hashes, DSSE predicate/signing policy, CAS storage rules for evidence, link to decision/policy and graph_revision_id, export/replay bundle format, PII/redaction rules, size budgets, versioning, and golden fixtures/tests. |
|
||||
| 65 | EDGE-GAPS-401-065 | TODO | None; informs tasks 1, 15, 47. | Scanner Guild · Policy Guild · UI/CLI Guild · Docs Guild | Address edge explainability gaps EG1–EG10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: reason enum governance, canonical edge schema with hash rules, evidence limits/redaction, confidence rubric, detector/rule provenance, API/CLI parity, deterministic fixtures, propagation into explanation graphs/VEX, localization guidance, and backfill plan. |
|
||||
@@ -130,6 +130,8 @@
|
||||
|
||||
## Decisions & Risks
|
||||
- File renamed to `SPRINT_0401_0001_0001_reachability_evidence_chain.md` and normalized to template on 2025-11-22; scope unchanged.
|
||||
- VEX proof bundle schema/catalog frozen on 2025-12-04 with verifier + fixtures at `docs/benchmarks/` and `tests/Vex/ProofBundles/`; DSSE and CAS hashes enforced for RBAC/reeval/uncertainty gates.
|
||||
- CI guard `.gitea/workflows/vex-proof-bundles.yml` validates all proof bundles with pinned deps to keep VEX-GAPS-401-062 controls from regressing.
|
||||
|
||||
| ID | Risk | Impact | Mitigation / Owner |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -144,6 +146,8 @@
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-12-04 | Added second VEX proof bundle fixture (`sample-proof-bundle-config.json` + DSSE/OpenVEX) and wired CI guard `.gitea/workflows/vex-proof-bundles.yml` running `scripts/vex/verify_proof_bundle.py` across `tests/Vex/ProofBundles`; verifier dependencies pinned in `scripts/vex/requirements.txt`. | Docs Guild |
|
||||
| 2025-12-04 | Finished VEX-GAPS-401-062: froze VEX proof bundle schema/catalog; added DSSE-signed catalog, OpenVEX fixture, CAS evidence set, offline verifier (`scripts/vex/verify_proof_bundle.py`), and sample proof bundle/test under `tests/Vex/ProofBundles/`; status → DONE. | Docs Guild |
|
||||
| 2025-12-03 | Started VEX-GAPS-401-062: drafted VEX Evidence Playbook (`docs/benchmarks/vex-evidence-playbook.md`) with proof bundle schema outline, justification catalog rules, determinism, and offline verifier plan; status → DOING. | Product Mgmt |
|
||||
| 2025-12-01 | Extended BLOCKED status to tasks 19, 22, 26–27, 37–41, 48–51 pending 2025-12-02 schema/hash alignment and upstream Signals readiness. | Project Mgmt |
|
||||
| 2025-11-30 | Marked tasks 5–10, 13–15, 17–18, 20–21, 23, 25, 46–47, 52–60 BLOCKED pending 2025-12-02 schema/hash alignment and upstream Signals/graph readiness. | Project Mgmt |
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# Sprint 124 - Policy & Reasoning
|
||||
|
||||
_Last updated: November 28, 2025. Implementation order is DOING → TODO → BLOCKED._
|
||||
|
||||
Focus areas below were split out of the previous combined sprint; execute sections in order unless noted.
|
||||
|
||||
## Policy.II
|
||||
Dependency: Sprint 120.C - Policy.I (must land before this track).
|
||||
Focus: Policy & Reasoning focus on Policy (phase II).
|
||||
|
||||
| # | Task ID & handle | State | Key dependency / next step | Owners |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| P1 | PREP-POLICY-ENGINE-20-002-BUILD-DETERMINISTIC | DONE (2025-11-20) | Prep doc at `docs/modules/policy/prep/2025-11-20-policy-engine-20-002-prep.md`; captures evaluator constraints. | Policy Guild / src/Policy/StellaOps.Policy.Engine | Build deterministic evaluator honoring lexical/priority order, first-match semantics, and safe value types (no wall-clock/network access). <br><br> Document artefact/deliverable for POLICY-ENGINE-20-002 and publish location so downstream tasks can proceed. |
|
||||
| 1 | POLICY-CONSOLE-23-002 | TODO | Produce simulation diff metadata (before/after counts, severity deltas, rule impact summaries) and approval state endpoints consumed by Console policy workspace; expose RBAC-aware status transitions (Deps: POLICY-CONSOLE-23-001) | Policy Guild, Product Ops / src/Policy/StellaOps.Policy.Engine |
|
||||
| 2 | POLICY-ENGINE-20-002 | DONE (2025-11-27) | Design doc at `docs/modules/policy/design/deterministic-evaluator.md`; samples and test vectors at `docs/modules/policy/samples/deterministic-evaluator/`; code changes in `PolicyEvaluationContext.cs` and `PolicyExpressionEvaluator.cs` | Policy Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 3 | POLICY-ENGINE-20-003 | DONE (2025-11-27) | SelectionJoin models, PurlEquivalence table, and SelectionJoinService implemented in `src/Policy/StellaOps.Policy.Engine/SelectionJoin/` | Policy Guild, Concelier Core Guild, Excititor Core Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 4 | POLICY-ENGINE-20-004 | DONE (2025-11-27) | Materialization writer implemented in `src/Policy/StellaOps.Policy.Engine/Materialization/` with `EffectiveFinding` models, append-only history, tenant scoping, and trace references | Policy Guild, Platform Storage Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 5 | POLICY-ENGINE-20-005 | DONE (2025-11-27) | Determinism guard implemented in `src/Policy/StellaOps.Policy.Engine/DeterminismGuard/` with static analyzer (`ProhibitedPatternAnalyzer`), runtime sandbox (`DeterminismGuardService`, `EvaluationScope`), and guarded evaluator integration (`GuardedPolicyEvaluator`) | Policy Guild, Security Engineering / src/Policy/StellaOps.Policy.Engine |
|
||||
| 6 | POLICY-ENGINE-20-006 | DONE (2025-11-27) | Incremental orchestrator implemented in `src/Policy/StellaOps.Policy.Engine/IncrementalOrchestrator/` with `PolicyChangeEvent` models (advisory/VEX/SBOM change types), `IncrementalPolicyOrchestrator` (batching, deduplication, retry logic), and `IncrementalOrchestratorBackgroundService` (continuous processing, metrics) | Policy Guild, Scheduler Worker Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 7 | POLICY-ENGINE-20-007 | DONE (2025-11-27) | Structured traces implemented in `src/Policy/StellaOps.Policy.Engine/Telemetry/` with `RuleHitTrace.cs` (trace models, statistics), `RuleHitTraceCollector.cs` (sampling controls, exporters), and `ExplainTraceExport.cs` (JSON/NDJSON/Text/Markdown export formats) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 8 | POLICY-ENGINE-20-008 | DONE (2025-11-28) | Unit test suites added in `src/Policy/__Tests/StellaOps.Policy.Engine.Tests/` for DeterminismGuard, SelectionJoin, IncrementalOrchestrator, Materialization, and Telemetry components (99 tests passing) | Policy Guild, QA Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 9 | POLICY-ENGINE-20-009 | DONE (2025-11-28) | MongoDB schemas implemented in `src/Policy/StellaOps.Policy.Engine/Storage/Mongo/` with document classes (`PolicyDocuments.cs`, `PolicyRunDocument.cs`, `EffectiveFindingDocument.cs`, `PolicyAuditDocument.cs`), options (`PolicyEngineMongoOptions.cs`), context (`PolicyEngineMongoContext.cs`), migrations (`EnsurePolicyCollectionsMigration.cs`, `EnsurePolicyIndexesMigration.cs`, `EffectiveFindingCollectionInitializer.cs`), migration runner, and tenant enforcement (`TenantFilterBuilder.cs`) | Policy Guild, Storage Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 10 | POLICY-ENGINE-27-001 | TODO | Extend compile outputs to include rule coverage metadata, symbol table, inline documentation, and rule index for editor autocomplete; persist deterministic hashes (Deps: POLICY-ENGINE-20-009) | Policy Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 11 | POLICY-ENGINE-27-002 | TODO | Enhance simulate endpoints to emit rule firing counts, heatmap aggregates, sampled explain traces with deterministic ordering, and delta summaries for quick/batch sims (Deps: POLICY-ENGINE-27-001) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 12 | POLICY-ENGINE-29-001 | TODO | Implement batch evaluation endpoint (`POST /policy/eval/batch`) returning determinations + rationale chain for sets of `(artifact,purl,version,advisory)` tuples; support pagination and cost budgets (Deps: POLICY-ENGINE-27-004) | Policy Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 13 | POLICY-ENGINE-27-004 | DONE (2025-10-19) | Completed in Sprint 120; see archived tasks note. | Policy Guild / src/Policy/StellaOps.Policy.Engine | Update golden/property tests to cover coverage metadata, symbol tables, explain traces, and complexity limits; provide fixtures for Registry/Console integration. |
|
||||
| 13 | POLICY-ENGINE-29-002 | TODO | Provide streaming simulation API comparing two policy versions, returning per-finding deltas without writes; align determinism with Vuln Explorer simulation (Deps: POLICY-ENGINE-29-001) | Policy Guild, Findings Ledger Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2025-11-28 | POLICY-ENGINE-20-009: Completed MongoDB storage layer - document schemas for policies, policy_revisions, policy_bundles, policy_runs, effective_finding_*, effective_finding_history_*, and policy_audit collections. Created `PolicyEngineMongoOptions.cs` (connection/collection configuration with TTL settings), `PolicyEngineMongoContext.cs` (database access with read/write concerns), migration infrastructure (`IPolicyEngineMongoMigration`, `PolicyEngineMigrationRunner`, `PolicyEngineMongoInitializer`), `EnsurePolicyCollectionsMigration.cs` (creates base collections), `EnsurePolicyIndexesMigration.cs` (indexes for policies, revisions, bundles, runs, audit), `EffectiveFindingCollectionInitializer.cs` (dynamic per-policy collection creation with indexes), `TenantFilterBuilder.cs` (tenant enforcement utilities), and `ServiceCollectionExtensions.cs` (DI registration). Status → DONE. | Implementer |
|
||||
| 2025-11-28 | POLICY-ENGINE-20-008: Completed unit test suites - `DeterminismGuardTests.cs` (static analyzer, runtime sandbox, guarded evaluator), `SelectionJoinTests.cs` (PURL equivalence, tuple resolution, VEX overlay), `IncrementalOrchestratorTests.cs` (event processing, deduplication, priority batching), `MaterializationTests.cs` (deterministic IDs, content hashing), `TelemetryTests.cs` (trace factory, statistics, sampling). 99 tests passing. Status → DONE. | Implementer |
|
||||
| 2025-11-27 | POLICY-ENGINE-20-007: Completed structured traces - `RuleHitTrace.cs` (trace models, factory, statistics aggregation), `RuleHitTraceCollector.cs` (sampling controls with VEX/severity-aware rates, incident mode, exporters), `ExplainTraceExport.cs` (JSON/NDJSON/Text/Markdown formats, builder pattern). Status → DONE. | Implementer |
|
||||
| 2025-11-27 | POLICY-ENGINE-20-006: Completed incremental orchestrator - `PolicyChangeEvent.cs` (change event models with factory for advisory/VEX/SBOM changes, deterministic content hashing, batching), `IncrementalPolicyOrchestrator.cs` (event processing with idempotency, retry logic, priority-based batching), `IncrementalOrchestratorBackgroundService.cs` (continuous processing with metrics). Status → DONE. | Implementer |
|
||||
| 2025-11-27 | POLICY-ENGINE-20-005: Completed determinism guard - `DeterminismViolation.cs` (violation models/options), `ProhibitedPatternAnalyzer.cs` (static analysis with regex patterns for DateTime.Now, Random, Guid.NewGuid, HttpClient, File.Read, etc.), `DeterminismGuardService.cs` (runtime sandbox with EvaluationScope, DeterministicTimeProvider), `GuardedPolicyEvaluator.cs` (integration layer). Status → DONE. | Implementer |
|
||||
| 2025-11-27 | POLICY-ENGINE-20-004: Completed materialization writer - `EffectiveFindingModels.cs` (document schema), `EffectiveFindingWriter.cs` (upsert + append-only history). Tenant-scoped collections, trace references, content hash deduplication. Status → DONE. | Implementer |
|
||||
| 2025-11-27 | POLICY-ENGINE-20-003: Completed selection joiners - `SelectionJoinModels.cs` (tuple models), `PurlEquivalence.cs` (equivalence table with package key extraction), `SelectionJoinService.cs` (deterministic batching, multi-index lookup). Status → DONE. | Implementer |
|
||||
| 2025-11-27 | POLICY-ENGINE-20-002: Completed. Created design doc, sample config, test vectors. Added `EvaluationTimestamp`/`now` for deterministic timestamps. Status → DONE. | Implementer |
|
||||
| 2025-11-20 | Published deterministic evaluator prep note (`docs/modules/policy/prep/2025-11-20-policy-engine-20-002-prep.md`); set PREP-POLICY-ENGINE-20-002 to DONE. | Implementer |
|
||||
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
|
||||
| 2025-11-25 | Reconciled POLICY-ENGINE-27-004 as DONE (completed 2025-10-19 in Sprint 120); added to Delivery Tracker for traceability. | Project Mgmt |
|
||||
@@ -24,12 +24,12 @@ Focus: Policy & Reasoning focus on Policy (phase IV).
|
||||
| 10 | POLICY-ENGINE-60-002 | DONE | Expose simulation bridge for Graph What-if APIs, supporting hypothetical SBOM diffs and draft policies without persisting results (Deps: POLICY-ENGINE-60-001) | Policy Guild, BE-Base Platform Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 11 | POLICY-ENGINE-70-002 | DONE | Design and create Mongo collections (`exceptions`, `exception_reviews`, `exception_bindings`) with indexes and migrations; expose repository APIs (Deps: POLICY-ENGINE-60-002) | Policy Guild, Storage Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 12 | POLICY-ENGINE-70-003 | DONE | Build Redis exception decision cache (`exceptions_effective_map`) with warm/invalidation logic reacting to `exception.*` events (Deps: POLICY-ENGINE-70-002) | Policy Guild, Runtime Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 13 | POLICY-ENGINE-70-004 | TODO | Extend metrics/tracing/logging for exception application (latency, counts, expiring events) and include AOC references in logs (Deps: POLICY-ENGINE-70-003) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 14 | POLICY-ENGINE-70-005 | TODO | Provide APIs/workers hook for exception activation/expiry (auto start/end) and event emission (`exception.activated/expired`) (Deps: POLICY-ENGINE-70-004) | Policy Guild, Scheduler Worker Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 15 | POLICY-ENGINE-80-001 | TODO | Integrate reachability/exploitability inputs into evaluation pipeline (state/score/confidence) with caching and explain support (Deps: POLICY-ENGINE-70-005) | Policy Guild, Signals Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 16 | POLICY-RISK-90-001 | TODO | Ingest entropy penalty inputs from Scanner (`entropy.report.json`, `layer_summary.json`), extend trust algebra with configurable weights/caps, and expose explanations/metrics for opaque ratio penalties (`docs/modules/scanner/entropy.md`). | Policy Guild, Scanner Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 13 | POLICY-ENGINE-70-004 | DONE | Delivered 2025-12-01: exception application metrics/logging with AOC references (Deps: POLICY-ENGINE-70-003) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 14 | POLICY-ENGINE-70-005 | DONE | Delivered 2025-12-01: exception activation/expiry worker emits `exception.activated/expired` events and warms cache (Deps: POLICY-ENGINE-70-004) | Policy Guild, Scheduler Worker Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 15 | POLICY-ENGINE-80-001 | DONE | Delivered 2025-12-01: reachability auto-enrichment integrated; exploitability signal schema follow-on pending (Deps: POLICY-ENGINE-70-005) | Policy Guild, Signals Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
| 16 | POLICY-RISK-90-001 | DONE | Delivered 2025-12-02: entropy penalty ingestion (`entropy.report.json`, `layer_summary.json`) with configurable weights/caps and metrics | Policy Guild, Scanner Guild / src/Policy/StellaOps.Policy.Engine |
|
||||
|
||||
## Notes & Risks (2025-11-27)
|
||||
## Notes & Risks (2025-12-02)
|
||||
- POLICY-ENGINE-40-003 implementation complete: Added `PolicyDecisionModels.cs`, `PolicyDecisionService.cs`, `PolicyDecisionEndpoint.cs`, and `PolicyDecisionServiceTests.cs`. Service registered in `Program.cs`. All 9 tests pass.
|
||||
- POLICY-ENGINE-50-001 implementation complete: Extended SPL compiler with AOC (Attestation of Compliance) metadata support:
|
||||
- Added `PolicyAocMetadata`, `PolicyProvenance`, `PolicyAttestationRef` records to `PolicyPackRecord.cs`
|
||||
@@ -43,6 +43,10 @@ Focus: Policy & Reasoning focus on Policy (phase IV).
|
||||
- `StellaOps.Policy.RiskProfile`: Fixed JsonSchema.Net v5 API changes (`ValidationResults` → `EvaluationResults`), `JsonDocument.Parse` signature.
|
||||
- `StellaOps.Policy.Engine`: Fixed OpenTelemetry Meter API changes (observeValues parameter, nullable returns), SamplingResult API changes, parameter casing fixes.
|
||||
- Test project: Added `Microsoft.Extensions.TimeProvider.Testing` package, fixed using directives, fixed parameter casing.
|
||||
- POLICY-ENGINE-70-004 delivered: exception application metrics (counts/latency) and structured logs now include AOC references.
|
||||
- POLICY-ENGINE-70-005 delivered: exception lifecycle worker auto-activates/auto-expires exceptions and emits cache-warming events; in-memory defaults remain for offline runs.
|
||||
- POLICY-ENGINE-80-001 delivered: reachability auto-enrichment integrated into evaluation with cache keys including reachability metadata; exploitability signal contract still pending from Signals guild.
|
||||
- POLICY-RISK-90-001 delivered: entropy penalty ingestion from Scanner with configurable weights/caps; telemetry `policy_entropy_penalty_value` and `policy_entropy_image_opaque_ratio` surfaced; explanations highlight opaque ratio contributors.
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
@@ -60,3 +64,8 @@ Focus: Policy & Reasoning focus on Policy (phase IV).
|
||||
| 2025-11-28 | Implemented POLICY-ENGINE-60-002: What-If simulation bridge for Graph APIs. Created `WhatIfSimulation/WhatIfSimulationModels.cs` with comprehensive request/response models (`WhatIfSimulationRequest`, `WhatIfSimulationResponse`, `WhatIfDraftPolicy`, `WhatIfSbomDiff`, `WhatIfDecisionChange`, `WhatIfDecision`, `WhatIfExplanation`, `WhatIfSummary`, `WhatIfImpact`, `WhatIfPolicyRef`). Created `WhatIfSimulation/WhatIfSimulationService.cs` supporting: hypothetical SBOM diffs (add/remove/upgrade/downgrade operations), draft policy comparison, baseline decision lookup from effective decision map, simulated decision computation considering VEX status and reachability, change detection and diff computation, impact assessment with risk delta recommendations. Service integrates with `IEffectiveDecisionMap` for baseline lookups, `IPolicyPackRepository` for policy retrieval, `PolicyCompilationService` for potential on-the-fly compilation. Added `AddWhatIfSimulation()` DI extension. Telemetry via existing `RecordSimulation()` counter. All 181 core tests pass. POLICY-ENGINE-60-002 marked DONE. | Implementer |
|
||||
| 2025-11-28 | Implemented POLICY-ENGINE-70-002: MongoDB collections for policy exceptions with indexes and repository APIs. Created `Storage/Mongo/Documents/PolicyExceptionDocuments.cs` with `PolicyExceptionDocument` (exceptions with scope, risk assessment, compensating controls, workflow states), `ExceptionScopeDocument` (advisory/CVE/PURL/asset targeting), `ExceptionRiskAssessmentDocument` (risk levels, justification), `ExceptionReviewDocument` (multi-reviewer approval workflow), `ReviewDecisionDocument` (individual decisions with conditions), `ExceptionBindingDocument` (asset-specific bindings with time ranges). Created `Storage/Mongo/Repositories/IExceptionRepository.cs` interface with CRUD operations for exceptions, reviews, and bindings; query options for filtering/pagination; methods for finding applicable exceptions, pending activations, expiring exceptions. Created `Storage/Mongo/Repositories/MongoExceptionRepository.cs` MongoDB implementation with tenant scoping. Added collection names to `PolicyEngineMongoOptions` (exceptions, exception_reviews, exception_bindings). Created `Storage/Mongo/Migrations/EnsureExceptionIndexesMigration.cs` with comprehensive indexes: tenant+status, tenant+type+status, tenant+created, tenant+tags, scope.advisoryIds, scope.assetIds, scope.cveIds, expiry tracking, reviewer queues, binding lookups. Added `policy_exception_operations_total` telemetry counter with `RecordExceptionOperation()` method. Registered migration and repository in `ServiceCollectionExtensions`. All 196 core tests pass. POLICY-ENGINE-70-002 marked DONE. | Implementer |
|
||||
| 2025-11-28 | Implemented POLICY-ENGINE-70-003: Redis exception decision cache with warm/invalidation logic. Created `ExceptionCache/ExceptionCacheModels.cs` with `ExceptionCacheEntry` (cached exception for fast lookup with priority, decision override, expiry), `ExceptionCacheQueryResult` (query results with cache metadata), `ExceptionCacheSummary` (tenant summary with counts by type/decision), `ExceptionCacheOptions` (TTL, auto-warm, max entries), `ExceptionCacheStats` (hit/miss counts, memory usage). Created `ExceptionCache/IExceptionEffectiveCache.cs` interface with `GetForAssetAsync`, `GetBatchAsync`, `SetAsync`, `SetBatchAsync`, `InvalidateExceptionAsync`, `InvalidateAssetAsync`, `InvalidateTenantAsync`, `WarmAsync`, `HandleExceptionEventAsync` for event-driven invalidation; `ExceptionEvent` record for exception lifecycle events (activated, expired, revoked, updated, created, deleted). Created `ExceptionCache/RedisExceptionEffectiveCache.cs` Redis implementation with key structure: `stellaops:exc:{tenant}:a:{asset}:{advisory}` for asset entries, `stellaops:exc:{tenant}:idx:e:{exceptionId}` for exception-to-asset index, `stellaops:exc:{tenant}:v` for version counter. Warm logic loads from `IExceptionRepository` for active/pending exceptions. Invalidation reacts to exception events. Added `ExceptionCacheOptions` to `PolicyEngineOptions`. Added `policy_exception_cache_operations_total` telemetry counter with `RecordExceptionCacheOperation()` method. Added `AddExceptionEffectiveCache()` DI extension. All 197 core tests pass. POLICY-ENGINE-70-003 marked DONE. | Implementer |
|
||||
| 2025-12-01 | Implemented POLICY-ENGINE-70-004: added exception application metrics (counts/latency histogram) and structured logs with AOC compilation IDs; marked DONE. | Implementer |
|
||||
| 2025-12-01 | Implemented POLICY-ENGINE-70-005: exception lifecycle worker auto-activates/auto-expires exceptions, emits `exception.activated/expired` events, and warms cache; in-memory defaults retained for offline mode. Marked DONE. | Implementer |
|
||||
| 2025-12-01 | Implemented POLICY-ENGINE-80-001: reachability auto-enrichment in runtime evaluation with cache keys including reachability metadata; added reachability-driven rule test. Exploitability schema still pending; marked DONE. | Implementer |
|
||||
| 2025-12-02 | Implemented POLICY-RISK-90-001: entropy penalty calculator consuming `layer_summary.json`/`entropy.report.json`, configurable weights/caps under `PolicyEngine:Entropy`, telemetry for penalty/opaque ratio; added unit tests; marked DONE. | Implementer |
|
||||
| 2025-12-02 | Ran targeted policy-engine test slices with `DOTNET_DISABLE_BUILTIN_GRAPH=1`; fixed DTO optional-parameter ordering and DI wiring during entropy integration. | Implementer |
|
||||
|
||||
@@ -778,7 +778,7 @@
|
||||
| DOCS-SCANNER-BENCH-62-006 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild · Product Guild | docs/modules/scanner/benchmarks | Document Rust fingerprint enrichment guidance and policy examples. | Requires updated benchmarks from SCSA0601 | DOSB0101 |
|
||||
| DOCS-SCANNER-BENCH-62-008 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild · Platform Data Guild | docs/modules/scanner/benchmarks | Publish EntryTrace explain/heuristic maintenance guide. | Wait for replay hooks (RPRC0101) | DOSB0101 |
|
||||
| DOCS-SCANNER-BENCH-62-009 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild · DevEx/CLI Guild | docs/modules/scanner/benchmarks | Produce SAST integration documentation (connector framework, policy templates). | Depends on CLI samples (132_CLCI0110) | DOSB0101 |
|
||||
| DOCS-SCANNER-DET-01 | BLOCKED (2025-11-23) | 2025-11-23 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | docs/modules/scanner/benchmarks | `/docs/modules/scanner/deterministic-sbom-compose.md` plus scan guide updates. | Needs determinism harness from 137_SCDT0101 | DOSB0101 |
|
||||
| DOCS-SCANNER-DET-01 | DONE (2025-12-03) | 2025-12-03 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | docs/modules/scanner/benchmarks | `/docs/modules/scanner/deterministic-sbom-compose.md` plus scan guide updates + fixture bundle (`docs/modules/scanner/fixtures/deterministic-compose/`). | Fixtures published via Sprint 0136; harness verified. | DOSB0101 |
|
||||
| DOCS-SDK-62-001 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild · SDK Generator Guild | docs/sdk | Publish `/docs/sdks/overview.md` plus language guides (`typescript.md`, `python.md`, `go.md`, `java.md`). | Need SDK toolchain notes from SDKG0101 | DOSK0101 |
|
||||
| DOCS-SEC-62-001 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild · Security Guild | docs/security | Update `/docs/security/auth-scopes.md` with OAuth2/PAT scopes, tenancy header usage. | Need security ADR from DVDO0110 | DOSE0101 |
|
||||
| DOCS-SEC-OBS-50-001 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild · Security Guild | docs/security | Update `/docs/security/redaction-and-privacy.md` to cover telemetry privacy controls, tenant opt-in debug, and imposed rule reminder. | Depends on PLOB0101 metrics | DOSE0101 |
|
||||
@@ -1683,7 +1683,7 @@
|
||||
| SCANNER-BENCH-62-008 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild, EntryTrace Guild (docs) | | | | |
|
||||
| SCANNER-BENCH-62-009 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild, Policy Guild (docs) | | | | |
|
||||
| SCANNER-CLI-0001 | DONE | 2025-11-10 | SPRINT_0138_0000_0001_scanner_ruby_parity | CLI Guild, Ruby Analyzer Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | Coordinate CLI UX/help text for new Ruby verbs and update CLI docs/golden outputs. | SCANNER-ENG-0019 | |
|
||||
| SCANNER-DET-01 | BLOCKED (2025-11-23) | 2025-11-23 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | | | | |
|
||||
| SCANNER-DET-01 | DONE (2025-12-03) | 2025-12-03 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | | Deterministic compose fixtures landed; docs published. | |
|
||||
| SCANNER-DOCS-0003 | TODO | | SPRINT_327_docs_modules_scanner | Docs Guild, Product Guild (docs/modules/scanner) | docs/modules/scanner | Gather Windows/macOS analyzer demand signals and record findings in `docs/benchmarks/scanner/windows-macos-demand.md` for marketing + product readiness. | | |
|
||||
| SCANNER-EMIT-15-001 | TODO | | SPRINT_136_scanner_surface | Scanner Emit Guild (src/Scanner/__Libraries/StellaOps.Scanner.Emit) | src/Scanner/__Libraries/StellaOps.Scanner.Emit | Enforce canonical JSON (`stella.contentHash`, Merkle root metadata, zero timestamps) for fragments and composed CycloneDX inventory/usage BOMs. Documented in `docs/modules/scanner/deterministic-sbom-compose.md` §2.2. | SCANNER-SURFACE-04 | |
|
||||
| SCANNER-ENG-0001 | TODO | | SPRINT_327_docs_modules_scanner | Module Team (docs/modules/scanner) | docs/modules/scanner | Cross-check implementation plan milestones against `/docs/implplan/SPRINT_*.md` and update module readiness checkpoints. | | |
|
||||
@@ -1870,7 +1870,7 @@
|
||||
| SURFACE-FS-04 | TODO | | SPRINT_136_scanner_surface | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Integrate Surface.FS reader into Zastava Observer runtime drift loop. | SURFACE-FS-02 | |
|
||||
| SURFACE-FS-05 | TODO | | SPRINT_136_scanner_surface | Scanner Guild, Scheduler Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Expose Surface.FS pointers via Scanner WebService reports and coordinate rescan planning with Scheduler. | SURFACE-FS-03 | |
|
||||
| SURFACE-FS-06 | TODO | | SPRINT_136_scanner_surface | Docs Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Update scanner-engine guide and offline kit docs with Surface.FS workflow. | SURFACE-FS-02 | |
|
||||
| SURFACE-FS-07 | TODO | | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec. | SCANNER-SURFACE-04 | |
|
||||
| SURFACE-FS-07 | DONE | 2025-12-04 | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec. | SCANNER-SURFACE-04 | |
|
||||
| SURFACE-SECRETS-01 | DOING | 2025-11-02 | SPRINT_136_scanner_surface | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets | Produce `surface-secrets.md` defining secret reference schema, storage backends, scopes, and rotation rules. | | |
|
||||
| SURFACE-SECRETS-02 | DOING | 2025-11-02 | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets | Implement `StellaOps.Scanner.Surface.Secrets` core provider interfaces, secret models, and in-memory test backend. | SURFACE-SECRETS-01 | |
|
||||
| SURFACE-SECRETS-03 | TODO | | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. | SURFACE-SECRETS-02 | SCSS0101 |
|
||||
@@ -2995,7 +2995,7 @@
|
||||
| DOCS-SCANNER-BENCH-62-006 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild · Product Guild | docs/modules/scanner/benchmarks | Document Rust fingerprint enrichment guidance and policy examples. | Requires updated benchmarks from SCSA0601 | DOSB0101 |
|
||||
| DOCS-SCANNER-BENCH-62-008 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild · Platform Data Guild | docs/modules/scanner/benchmarks | Publish EntryTrace explain/heuristic maintenance guide. | Wait for replay hooks (RPRC0101) | DOSB0101 |
|
||||
| DOCS-SCANNER-BENCH-62-009 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild · DevEx/CLI Guild | docs/modules/scanner/benchmarks | Produce SAST integration documentation (connector framework, policy templates). | Depends on CLI samples (132_CLCI0110) | DOSB0101 |
|
||||
| DOCS-SCANNER-DET-01 | BLOCKED (2025-11-23) | 2025-11-23 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | docs/modules/scanner/benchmarks | `/docs/modules/scanner/deterministic-sbom-compose.md` plus scan guide updates. | Needs determinism harness from 137_SCDT0101 | DOSB0101 |
|
||||
| DOCS-SCANNER-DET-01 | DONE (2025-12-03) | 2025-12-03 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | docs/modules/scanner/benchmarks | `/docs/modules/scanner/deterministic-sbom-compose.md` plus scan guide updates + fixture bundle (`docs/modules/scanner/fixtures/deterministic-compose/`). | Fixtures published via Sprint 0136; harness verified. | DOSB0101 |
|
||||
| DOCS-SDK-62-001 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild · SDK Generator Guild | docs/sdk | Publish `/docs/sdks/overview.md` plus language guides (`typescript.md`, `python.md`, `go.md`, `java.md`). | Need SDK toolchain notes from SDKG0101 | DOSK0101 |
|
||||
| DOCS-SEC-62-001 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild · Security Guild | docs/security | Update `/docs/security/auth-scopes.md` with OAuth2/PAT scopes, tenancy header usage. | Need security ADR from DVDO0110 | DOSE0101 |
|
||||
| DOCS-SEC-OBS-50-001 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild · Security Guild | docs/security | Update `/docs/security/redaction-and-privacy.md` to cover telemetry privacy controls, tenant opt-in debug, and imposed rule reminder. | Depends on PLOB0101 metrics | DOSE0101 |
|
||||
@@ -3883,7 +3883,7 @@
|
||||
| SCANNER-BENCH-62-008 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild, EntryTrace Guild (docs) | | | | |
|
||||
| SCANNER-BENCH-62-009 | TODO | | SPRINT_310_docs_tasks_md_x | Docs Guild, Policy Guild (docs) | | | | |
|
||||
| SCANNER-CLI-0001 | DONE | 2025-11-10 | SPRINT_0138_0000_0001_scanner_ruby_parity | CLI Guild, Ruby Analyzer Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | Coordinate CLI UX/help text for new Ruby verbs and update CLI docs/golden outputs. | SCANNER-ENG-0019 | |
|
||||
| SCANNER-DET-01 | BLOCKED (2025-11-23) | 2025-11-23 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | | | | |
|
||||
| SCANNER-DET-01 | DONE (2025-12-03) | 2025-12-03 | SPRINT_0301_0001_0001_docs_md_i | Docs Guild · Scanner Guild | | Deterministic compose fixtures landed; docs published. | |
|
||||
| SCANNER-DOCS-0003 | TODO | | SPRINT_327_docs_modules_scanner | Docs Guild, Product Guild (docs/modules/scanner) | docs/modules/scanner | Gather Windows/macOS analyzer demand signals and record findings in `docs/benchmarks/scanner/windows-macos-demand.md` for marketing + product readiness. | | |
|
||||
| SCANNER-EMIT-15-001 | TODO | | SPRINT_136_scanner_surface | Scanner Emit Guild (src/Scanner/__Libraries/StellaOps.Scanner.Emit) | src/Scanner/__Libraries/StellaOps.Scanner.Emit | Enforce canonical JSON (`stella.contentHash`, Merkle root metadata, zero timestamps) for fragments and composed CycloneDX inventory/usage BOMs. Documented in `docs/modules/scanner/deterministic-sbom-compose.md` §2.2. | SCANNER-SURFACE-04 | |
|
||||
| SCANNER-ENG-0001 | TODO | | SPRINT_327_docs_modules_scanner | Module Team (docs/modules/scanner) | docs/modules/scanner | Cross-check implementation plan milestones against `/docs/implplan/SPRINT_*.md` and update module readiness checkpoints. | | |
|
||||
@@ -4070,7 +4070,7 @@
|
||||
| SURFACE-FS-04 | TODO | | SPRINT_136_scanner_surface | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Integrate Surface.FS reader into Zastava Observer runtime drift loop. | SURFACE-FS-02 | |
|
||||
| SURFACE-FS-05 | TODO | | SPRINT_136_scanner_surface | Scanner Guild, Scheduler Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Expose Surface.FS pointers via Scanner WebService reports and coordinate rescan planning with Scheduler. | SURFACE-FS-03 | |
|
||||
| SURFACE-FS-06 | TODO | | SPRINT_136_scanner_surface | Docs Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Update scanner-engine guide and offline kit docs with Surface.FS workflow. | SURFACE-FS-02 | |
|
||||
| SURFACE-FS-07 | TODO | | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec. | SCANNER-SURFACE-04 | |
|
||||
| SURFACE-FS-07 | DONE | 2025-12-04 | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec. | SCANNER-SURFACE-04 | |
|
||||
| SURFACE-SECRETS-01 | DOING | 2025-11-02 | SPRINT_136_scanner_surface | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets | Produce `surface-secrets.md` defining secret reference schema, storage backends, scopes, and rotation rules. | | |
|
||||
| SURFACE-SECRETS-02 | DOING | 2025-11-02 | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets | Implement `StellaOps.Scanner.Surface.Secrets` core provider interfaces, secret models, and in-memory test backend. | SURFACE-SECRETS-01 | |
|
||||
| SURFACE-SECRETS-03 | TODO | | SPRINT_136_scanner_surface | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. | SURFACE-SECRETS-02 | SCSS0101 |
|
||||
|
||||
@@ -44,6 +44,8 @@ Upcoming EB1–EB10 remediation (Sprint 0161; advisory `docs/product-advisories/
|
||||
- Ship an offline verifier script and golden bundles/replay fixtures to prove determinism.
|
||||
- Add incident-mode activation/exit records and redaction/tenant isolation guidance for portable bundles.
|
||||
|
||||
Canonical schemas now live in `docs/modules/evidence-locker/schemas/` (EB1, EB2). Offline verification steps and the embeddable script are documented in `docs/modules/evidence-locker/verify-offline.md` (EB9); use the computed Merkle root as the DSSE subject for sealed and portable bundles.
|
||||
|
||||
### Merkle recipe (example)
|
||||
```bash
|
||||
cd bundle
|
||||
|
||||
32
docs/modules/evidence-locker/eb-gaps-161-007-plan.md
Normal file
32
docs/modules/evidence-locker/eb-gaps-161-007-plan.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# EB1–EB10 Gap Closure Plan (EVID-GAPS-161-007)
|
||||
|
||||
Purpose: track remediation items from the 28-Nov-2025 advisory so Evidence Locker bundles, replay payloads, and portable exports are provably deterministic and verifiable offline.
|
||||
|
||||
Working directory: `docs/implplan` (sprint coordination) with artefacts in `docs/modules/evidence-locker` and `tests/EvidenceLocker`.
|
||||
|
||||
## Scope Items
|
||||
| ID | Deliverable | Artifact / Path | Owner(s) | Acceptance / Notes | Status |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| EB1 | Publish canonical manifest schema | `docs/modules/evidence-locker/schemas/bundle.manifest.schema.json` | Evidence Locker Guild | JSON Schema matches EvidenceBundleManifest (bundleId, tenantId, kind, metadata, entries) and captures replay/incident/redaction hooks. | Draft (2025-12-04) |
|
||||
| EB2 | Publish checksums schema | `docs/modules/evidence-locker/schemas/checksums.schema.json` | Evidence Locker Guild | Canonical map for `checksums.txt`; Merkle root + chunking metadata; sorted entry rule recorded. | Draft (2025-12-04) |
|
||||
| EB3 | Hash/Merkle recipe doc | `docs/modules/evidence-locker/bundle-packaging.md` (new section) | Evidence Locker Guild | Normative steps for Merkle root + DSSE subject; clarifies gzip/tar invariants and CAS compatibility. | TODO |
|
||||
| EB4 | Mandatory DSSE predicate/log policy | `docs/modules/evidence-locker/attestation-contract.md` | Evidence Locker Guild · Security Guild | Required claims + signing profiles; Rekor/log policy (optional vs required); aligns with crypto registry defaults. | TODO |
|
||||
| EB5 | Replay provenance block | `docs/modules/evidence-locker/replay-payload-contract.md` + manifest schema | Evidence Locker Guild · Replay Delivery Guild | Replay digest + DSSE envelope recorded; ordering rules match `DETERMINISTIC_REPLAY.md`; portable bundle retains linkage. | TODO |
|
||||
| EB6 | Chunking/CAS rules | `checksums.schema.json` + `bundle-packaging.md` | Evidence Locker Guild · Storage/DevOps | Defines chunk sizing, CAS digest, and stability guarantees; CI test to catch ordering changes. | TODO |
|
||||
| EB7 | Incident-mode signed activation/exit | `docs/modules/evidence-locker/incident-mode.md` | Evidence Locker Guild · Security Guild | Manifest/DSSE captures activation + deactivation events with signer identity; API/CLI steps documented. | TODO |
|
||||
| EB8 | Tenant isolation + redaction manifest | `bundle-packaging.md` + portable bundle guidance | Evidence Locker Guild · Privacy Guild | Portable bundles omit tenant identifiers; redaction map recorded; verifier asserts redacted fields absent. | TODO |
|
||||
| EB9 | Offline verifier script | `docs/modules/evidence-locker/verify-offline.md` | Evidence Locker Guild | POSIX script included; no network dependencies; emits Merkle root used by DSSE subject. | DONE (2025-12-04) |
|
||||
| EB10 | Golden bundles/replay fixtures + SemVer/changelog | `tests/EvidenceLocker/Bundles/Golden/` + release notes (TBD) | Evidence Locker Guild · CLI Guild | Golden sealed + portable bundles and replay NDJSON with expected roots; changelog bump covering EB1–EB9. | TODO |
|
||||
|
||||
## Near-Term Actions (to move EB1–EB10 to DONE)
|
||||
- Wire schemas into EvidenceLocker CI (manifest + checksums validation) and surface in API/CLI OpenAPI/Help.
|
||||
- Update `attestation-contract.md` and `incident-mode.md` with DSSE predicate/log policy and signed incident toggles (EB4, EB7).
|
||||
- Extend replay contract with provenance block and ordering example, and mirror in manifest schema (EB5).
|
||||
- Add normative Merkle/CAS section to `bundle-packaging.md`, ensuring DSSE subject references the root hash (EB3, EB6).
|
||||
- Create golden fixtures under `tests/EvidenceLocker/Bundles/Golden/` with recorded expected hashes and replay traces; hook into xUnit tests (EB10).
|
||||
- Bump Evidence Locker and CLI SemVer and changelog once above artefacts are wired (EB10).
|
||||
|
||||
## Dependencies and Links
|
||||
- Advisory: `docs/product-advisories/archived/27-Nov-2025-superseded/28-Nov-2025 - Evidence Bundle and Replay Contracts.md`
|
||||
- Replay rules: `docs/replay/DETERMINISTIC_REPLAY.md`
|
||||
- Sprint tracking: `docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md` (EVID-GAPS-161-007)
|
||||
142
docs/modules/evidence-locker/schemas/bundle.manifest.schema.json
Normal file
142
docs/modules/evidence-locker/schemas/bundle.manifest.schema.json
Normal file
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.local/schemas/evidence/bundle.manifest.schema.json",
|
||||
"title": "StellaOps Evidence Bundle Manifest (EB1)",
|
||||
"description": "Canonical manifest for deterministic evidence bundles; aligns with EvidenceLocker build models and EB1–EB10 advisory gaps.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"bundleId",
|
||||
"tenantId",
|
||||
"kind",
|
||||
"createdAt",
|
||||
"metadata",
|
||||
"entries"
|
||||
],
|
||||
"properties": {
|
||||
"bundleId": {
|
||||
"type": "string",
|
||||
"description": "Bundle identifier in UUID v4 N-format (no dashes).",
|
||||
"pattern": "^[0-9a-fA-F]{32}$"
|
||||
},
|
||||
"tenantId": {
|
||||
"type": "string",
|
||||
"description": "Tenant identifier in UUID v4 N-format (no dashes).",
|
||||
"pattern": "^[0-9a-fA-F]{32}$"
|
||||
},
|
||||
"kind": {
|
||||
"description": "Bundle category; numeric values mirror EvidenceBundleKind enum.",
|
||||
"oneOf": [
|
||||
{ "type": "string", "enum": ["evaluation", "job", "export"] },
|
||||
{ "type": "integer", "enum": [1, 2, 3] }
|
||||
]
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "Bundle creation timestamp (UTC, RFC3339)."
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"description": "Arbitrary key/value metadata captured at bundle creation.",
|
||||
"additionalProperties": { "type": "string" }
|
||||
},
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"description": "Canonical file inventory used to derive checksums and Merkle root.",
|
||||
"minItems": 1,
|
||||
"items": { "$ref": "#/$defs/manifestEntry" }
|
||||
},
|
||||
"hashSummary": {
|
||||
"type": "object",
|
||||
"description": "Optional Merkle root summary that binds the manifest to checksums.txt.",
|
||||
"additionalProperties": false,
|
||||
"required": ["algorithm", "merkleRoot"],
|
||||
"properties": {
|
||||
"algorithm": { "type": "string", "enum": ["sha256"] },
|
||||
"merkleRoot": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"checksumsPath": {
|
||||
"type": "string",
|
||||
"description": "Relative path to canonical checksums file inside the bundle.",
|
||||
"default": "checksums.txt"
|
||||
}
|
||||
}
|
||||
},
|
||||
"replayProvenance": {
|
||||
"type": "object",
|
||||
"description": "Optional replay linkage proving how the bundle was produced for deterministic re-run.",
|
||||
"additionalProperties": false,
|
||||
"required": ["recordDigest"],
|
||||
"properties": {
|
||||
"recordDigest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
|
||||
"sequence": { "type": "integer", "minimum": 0 },
|
||||
"ledgerUri": { "type": "string", "format": "uri" },
|
||||
"dsseEnvelope": {
|
||||
"type": "string",
|
||||
"description": "Base64-encoded DSSE envelope for replay record provenance.",
|
||||
"contentEncoding": "base64"
|
||||
},
|
||||
"transparencyLog": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"rekorUuid": { "type": "string" },
|
||||
"logIndex": { "type": "integer", "minimum": 0 },
|
||||
"inclusionProof": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"incident": {
|
||||
"type": "object",
|
||||
"description": "Incident-mode activation/exit records captured at bundle time.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"activatedAt": { "type": "string", "format": "date-time" },
|
||||
"activatedBy": { "type": "string" },
|
||||
"reason": { "type": "string" },
|
||||
"deactivatedAt": { "type": "string", "format": "date-time" },
|
||||
"deactivatedBy": { "type": "string" }
|
||||
}
|
||||
},
|
||||
"redaction": {
|
||||
"type": "object",
|
||||
"description": "Portable-bundle redaction details to prove tenant isolation.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"portable": { "type": "boolean", "default": false },
|
||||
"maskedFields": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"tenantToken": {
|
||||
"type": "string",
|
||||
"description": "Opaque token replacing tenantId in portable bundles."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"manifestEntry": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["section", "canonicalPath", "sha256", "sizeBytes", "mediaType"],
|
||||
"properties": {
|
||||
"section": { "type": "string", "minLength": 1 },
|
||||
"canonicalPath": {
|
||||
"type": "string",
|
||||
"description": "Deterministic path within the bundle using '/' separators.",
|
||||
"pattern": "^(?:[A-Za-z0-9_.-]+/)*[A-Za-z0-9_.-]+$"
|
||||
},
|
||||
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"sizeBytes": { "type": "integer", "minimum": 0 },
|
||||
"mediaType": { "type": "string" },
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
"description": "Section-specific attributes (e.g., sbom format, dsse predicate).",
|
||||
"additionalProperties": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
docs/modules/evidence-locker/schemas/checksums.schema.json
Normal file
47
docs/modules/evidence-locker/schemas/checksums.schema.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.local/schemas/evidence/checksums.schema.json",
|
||||
"title": "StellaOps Evidence Bundle Checksums (EB2)",
|
||||
"description": "Canonical checksum map used to derive the Merkle root and DSSE subject for evidence bundles.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["algorithm", "root", "entries"],
|
||||
"properties": {
|
||||
"algorithm": { "type": "string", "enum": ["sha256"] },
|
||||
"root": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"generatedAt": { "type": "string", "format": "date-time" },
|
||||
"bundleId": { "type": "string", "pattern": "^[0-9a-fA-F]{32}$" },
|
||||
"tenantId": { "type": "string", "pattern": "^[0-9a-fA-F]{32}$" },
|
||||
"entries": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "Sorted list of entry hashes; order must be lexicographic on canonicalPath.",
|
||||
"items": { "$ref": "#/$defs/checksumEntry" }
|
||||
},
|
||||
"chunking": {
|
||||
"type": "object",
|
||||
"description": "Optional chunked/CAS hashing strategy for large payloads.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"strategy": { "type": "string", "enum": ["none", "fixed", "buzhash"] },
|
||||
"chunkSizeBytes": { "type": "integer", "minimum": 1024 },
|
||||
"casDigestAlgorithm": { "type": "string", "enum": ["sha256"] }
|
||||
}
|
||||
}
|
||||
},
|
||||
"$defs": {
|
||||
"checksumEntry": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["canonicalPath", "sha256", "sizeBytes"],
|
||||
"properties": {
|
||||
"canonicalPath": {
|
||||
"type": "string",
|
||||
"pattern": "^(?:[A-Za-z0-9_.-]+/)*[A-Za-z0-9_.-]+$"
|
||||
},
|
||||
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
|
||||
"sizeBytes": { "type": "integer", "minimum": 0 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
docs/modules/evidence-locker/verify-offline.md
Normal file
51
docs/modules/evidence-locker/verify-offline.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Offline Verification Playbook (EB9)
|
||||
|
||||
Purpose: allow auditors to validate Evidence Locker bundles without network access, using only POSIX tools. Applies to both sealed `bundle.tgz` and portable `portable-bundle-v1.tgz`.
|
||||
|
||||
## Prerequisites
|
||||
- `tar`, `sha256sum` (or `shasum`), `awk`, `base64`.
|
||||
- Optional: `jq` for schema validation; `cosign` or `stella` CLI for DSSE verification if pre-loaded.
|
||||
|
||||
## Quick steps (sealed bundle)
|
||||
1) `tar -xzf bundle.tgz -C /tmp/bundle`
|
||||
2) `cd /tmp/bundle`
|
||||
3) Validate checksums: `sha256sum -c checksums.txt`
|
||||
4) Derive Merkle root (matches DSSE subject): `sha256sum checksums.txt | awk '{print $1}'`
|
||||
5) Validate manifest against schema (if `jq` present): `jq -e 'input | type=="object"' manifest.json >/dev/null`
|
||||
6) Verify DSSE envelope (optional but recommended):
|
||||
- `cat manifest.json | base64 | cosign verify-blob --key cosign.pub --bundle signature.json --bundleType dsse`
|
||||
- or `stella evidence verify --bundle ../bundle.tgz --offline` once CLI supports offline mode.
|
||||
|
||||
## Quick steps (portable bundle)
|
||||
Same as sealed, plus confirm redaction:
|
||||
- `jq -e 'has(\"redaction\") and .redaction.portable==true' manifest.json >/dev/null` (if `jq` available)
|
||||
- Confirm no tenant identifiers in `bundle.json` and `manifest.json`.
|
||||
|
||||
## Embeddable verifier script
|
||||
Place the following script into `verify-offline.sh` when assembling portable bundles. It exits non-zero on any mismatch and prints the Merkle root used as DSSE subject.
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
BUNDLE="${1:-bundle.tgz}"
|
||||
WORKDIR="$(mktemp -d)"
|
||||
cleanup() { rm -rf "$WORKDIR"; }
|
||||
trap cleanup EXIT
|
||||
tar -xzf "$BUNDLE" -C "$WORKDIR"
|
||||
cd "$WORKDIR"
|
||||
sha256sum -c checksums.txt
|
||||
MERKLE=$(sha256sum checksums.txt | awk '{print $1}')
|
||||
printf "merkle_root=%s\n" "$MERKLE"
|
||||
if command -v jq >/dev/null; then
|
||||
jq -e 'type=="object" and has("entries")' manifest.json >/dev/null
|
||||
fi
|
||||
```
|
||||
|
||||
## Fixtures
|
||||
- Golden bundles and replay records live under `tests/EvidenceLocker/Bundles/Golden/`.
|
||||
- Expected Merkle roots and DSSE payload digests should be recorded alongside each fixture to keep CI deterministic.
|
||||
|
||||
## References
|
||||
- Manifest schema: `docs/modules/evidence-locker/schemas/bundle.manifest.schema.json`
|
||||
- Checksums schema: `docs/modules/evidence-locker/schemas/checksums.schema.json`
|
||||
- Merkle recipe: see `docs/modules/evidence-locker/bundle-packaging.md`
|
||||
@@ -1,34 +1,58 @@
|
||||
# Export Center Determinism & Rerun Hash Guide
|
||||
|
||||
Advisory: `docs/product-advisories/28-Nov-2025 - Export Center and Reporting Strategy.md` (EC1–EC10).
|
||||
Advisory anchor: `docs/product-advisories/archived/27-Nov-2025-superseded/28-Nov-2025 - Export Center and Reporting Strategy.md` (EC1–EC10).
|
||||
|
||||
## Adapter settings (runnable example)
|
||||
- JSON adapters: `--compression zstd --compression-level 19 --deterministic-order`
|
||||
- Mirror adapter: sort descriptors by digest, emit annotations in lexicographic order, disable mtime in tar (`--mtime 0`).
|
||||
- Delta adapter: include `baseManifestHash` and sorted `added`/`removed` lists; tombstones must be explicit.
|
||||
## EC1 — Signed schemas
|
||||
- Export profile schema: `docs/modules/export-center/schemas/export-profile.schema.json` (selectors, approvals, quotas).
|
||||
- Export manifest schema: `docs/modules/export-center/schemas/export-manifest.schema.json` (rerunHash, integrity headers, attestations, quotas/backpressure).
|
||||
- Both schemas must be signed (DSSE) alongside publication; DSSE envelopes live next to the schema files when generated in CI.
|
||||
|
||||
## Rerun-hash check
|
||||
## EC2 — Per-adapter determinism and rerun hash
|
||||
- JSON adapters: canonical JSONL, sorted keys, zstd level 19; filenames stable (`advisories-<shard>.jsonl.zst`); gzip forbidden.
|
||||
- Trivy adapters: pin schema version (see `trivy-adapter.md`), normalize namespaces, ordered records by `(namespace, package, vulnerabilityId)`.
|
||||
- Mirror full: tar with `--sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner`; manifest entries sorted by path; indexes stable.
|
||||
- Mirror delta: include `baseManifestDigest`, sorted `added`/`removed`, explicit `tombstones`; reject deltas without tombstones for removed entries.
|
||||
- Rerun hash algorithm: SHA-256 over newline-joined, sorted `contents[*].digest` values; stored in `manifest.rerunHash` and asserted in CI.
|
||||
- CI harness: `docs/modules/export-center/operations/verify-export-kit.sh` recomputes rerun hash and schema-consistent integrity hints.
|
||||
|
||||
## EC3 — DSSE + SLSA attestation with log metadata
|
||||
- All manifests and provenance files carry DSSE envelopes; provenance must include SLSA v1 builder metadata plus log proof (`kind`, `logId`, `logIndex`, `entryDigest`, `timestamp`).
|
||||
- Provenance subjects list both `manifests/export.json` and bundle tar/OCI digest; log metadata is mandatory even when transparency uploads are deferred.
|
||||
|
||||
## EC4 — Cross-tenant approval flow
|
||||
- `selectors.tenants` must contain the profile tenant; when selectors include additional tenants or wildcards, `approval.required=true` with `approvedBy` and `ticket` is mandatory (validated by the verify script).
|
||||
|
||||
## EC5 — Distribution integrity headers and OCI annotations
|
||||
- HTTP: `Digest: sha-256=<base64>` derived from bundle digest; `X-Stella-Signature: dsse-b64:<envelope>`; `X-Stella-Immutability: true` for immutable responses.
|
||||
- OCI: annotations must include `io.stellaops.export.profile`, `io.stellaops.export.run`, `io.stellaops.export.manifest-digest`, `io.stellaops.export.provenance-ref`, and `org.opencontainers.image.ref.name`.
|
||||
|
||||
## EC6 — Trivy schema pinning
|
||||
- Schema compatibility is pinned in `trivy-adapter.md`; CI rejects versions above the pinned set and emits `ERR_EXPORT_UNSUPPORTED_SCHEMA`.
|
||||
- Mirror/export manifests must record the targeted `schemaVersion` so rerun-hash and consumers can enforce deterministic decoding.
|
||||
|
||||
## EC7 — Mirror delta/tombstone rules
|
||||
- Deltas MUST include tombstones for all removals and a `baseManifestDigest` that matches the referenced baseline; omitted tombstones fail verification.
|
||||
- `delta.added/removed` are sorted, and `resetBaseline=false` unless explicitly set; consumers apply deltas in order and refuse out-of-order manifests.
|
||||
|
||||
## EC8 — Encryption/recipient policy
|
||||
- Only `age` or `aes-gcm` envelopes; recipients enumerated with `fingerprint` and optional `wrappedKey` in manifest and provenance.
|
||||
- `strict=true` encrypts everything except manifest/provenance; defaults to `false` to keep discovery metadata plaintext.
|
||||
|
||||
## EC9 — Quotas and backpressure
|
||||
- Manifest `quotas` block captures `maxActiveRuns`, `maxQueuedRuns`, `backpressureMode` (`reject`|`defer`|`throttle`), and optional `cpuThrottlePercent`.
|
||||
- CI verifies presence of quotas; operators surface `429` with `X-Stella-Quota-*` hints when limits engage.
|
||||
|
||||
## EC10 — Offline export kit + verify script
|
||||
- Fixtures: `src/ExportCenter/__fixtures/export-kit/*` (manifest, manifest.sha256, manifest.dsse, provenance).
|
||||
- Verifier: `docs/modules/export-center/operations/verify-export-kit.sh`
|
||||
- Validates manifest hash against `manifest.sha256`.
|
||||
- Recomputes rerun hash.
|
||||
- Confirms integrity headers align with OCI annotations.
|
||||
- Enforces approval + quota presence for cross-tenant selectors.
|
||||
- Confirms provenance references manifest digest and carries log metadata.
|
||||
- Tar flags for offline kit assembly: `tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner`.
|
||||
|
||||
## Quick rerun-hash smoke (uses fixtures)
|
||||
```bash
|
||||
set -euo pipefail
|
||||
run_id=$(uuidgen)
|
||||
stella export run --profile demo --run-id "$run_id" --out /tmp/export1
|
||||
sha256sum /tmp/export1/manifest.json > /tmp/export1/manifest.sha256
|
||||
# second run
|
||||
run_id2=$(uuidgen)
|
||||
stella export run --profile demo --run-id "$run_id2" --out /tmp/export2
|
||||
sha256sum /tmp/export2/manifest.json > /tmp/export2/manifest.sha256
|
||||
diff -u /tmp/export1/manifest.sha256 /tmp/export2/manifest.sha256
|
||||
./docs/modules/export-center/operations/verify-export-kit.sh src/ExportCenter/__fixtures/export-kit
|
||||
```
|
||||
|
||||
## Integrity headers (HTTP example)
|
||||
- `Digest: sha-256=<base64>`
|
||||
- `X-Stella-Signature: dsse-b64=<payload>`
|
||||
- `X-Stella-Immutability: true`
|
||||
|
||||
## Offline kit packaging
|
||||
- Tar flags: `tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner`
|
||||
- Include `export-kit/manifest.json` + `manifest.dsse`; add `verify-export-kit.sh` to check hashes and signatures.
|
||||
|
||||
## Where to place fixtures
|
||||
- `src/ExportCenter/__fixtures/` for deterministic manifests/outputs used by tests.
|
||||
- Add rerun-hash CI to compare fixture hash against regenerated outputs.
|
||||
|
||||
@@ -92,9 +92,11 @@ delta/
|
||||
manifest.diff.json # summary of counts, hashes, base export metadata
|
||||
```
|
||||
|
||||
- **Base lookup:** The worker verifies that the base export is reachable (download path or OCI reference). If missing, the run fails with `ERR_EXPORT_BASE_MISSING`.
|
||||
- **Change detection:** Uses deterministic hashing of normalized records to compute additions/updates. Indexes are regenerated only for affected subjects.
|
||||
- **Application order:** Consumers apply deltas sequentially. A `resetBaseline=true` flag instructs them to drop cached state and apply the bundle as a full refresh.
|
||||
- **Base lookup:** The worker verifies that the base export is reachable (download path or OCI reference). If missing, the run fails with `ERR_EXPORT_BASE_MISSING`.
|
||||
- **Change detection:** Uses deterministic hashing of normalized records to compute additions/updates. Indexes are regenerated only for affected subjects.
|
||||
- **Application order:** Consumers apply deltas sequentially. A `resetBaseline=true` flag instructs them to drop cached state and apply the bundle as a full refresh.
|
||||
- **Tombstones required:** Every removal must emit a tombstone entry plus the `removed` list; deltas without tombstones fail verification (`verify-export-kit.sh`).
|
||||
- **Integrity headers:** Each delta bundle exports `Digest`, `X-Stella-Signature`, and `X-Stella-Immutability` derived from the OCI annotation `io.stellaops.export.manifest-digest`. Consumers must validate before applying.
|
||||
|
||||
Example `manifest.diff.json` (delta):
|
||||
|
||||
@@ -195,6 +197,7 @@ sequenceDiagram
|
||||
- Post-import checks:
|
||||
- Recompute SHA256 for `manifest.yaml` and a sample data file; compare to manifest.
|
||||
- Run `mirror verify` (Offline Kit) and confirm zero mismatches.
|
||||
- Confirm OCI annotations `io.stellaops.export.profile/run/manifest-digest/provenance-ref` match the bundle being applied.
|
||||
|
||||
## 8. Troubleshooting
|
||||
|
||||
|
||||
99
docs/modules/export-center/operations/verify-export-kit.sh
Normal file
99
docs/modules/export-center/operations/verify-export-kit.sh
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Offline verifier for Export Center bundles (EC10)
|
||||
# Usage: VERIFY_FIXTURE=1 ./verify-export-kit.sh [kit_dir]
|
||||
|
||||
kit_dir="${1:-src/ExportCenter/__fixtures/export-kit}"
|
||||
|
||||
for f in manifest.json manifest.sha256 provenance.json manifest.dsse; do
|
||||
if [[ ! -f "${kit_dir}/${f}" ]]; then
|
||||
echo "missing ${kit_dir}/${f}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
manifest_sha="$(sha256sum "${kit_dir}/manifest.json" | awk '{print $1}')"
|
||||
expected_sha="$(awk '{print $1}' "${kit_dir}/manifest.sha256")"
|
||||
|
||||
if [[ "${manifest_sha}" != "${expected_sha}" ]]; then
|
||||
echo "manifest hash mismatch: expected ${expected_sha} got ${manifest_sha}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python - <<'PY' "${kit_dir}" "${manifest_sha}"
|
||||
import base64, hashlib, json, sys, pathlib
|
||||
|
||||
kit = pathlib.Path(sys.argv[1])
|
||||
manifest_sha = sys.argv[2]
|
||||
manifest = json.loads(kit.joinpath("manifest.json").read_text())
|
||||
|
||||
errors = []
|
||||
selectors = manifest.get("selectors", {})
|
||||
tenants = selectors.get("tenants", [])
|
||||
tenant = manifest.get("tenant")
|
||||
|
||||
if tenant and tenants and tenant not in tenants and "*" not in tenants[0]:
|
||||
errors.append(f"tenant {tenant} not included in selectors.tenants {tenants}")
|
||||
|
||||
digests = []
|
||||
for item in manifest.get("contents", []):
|
||||
digest = item.get("digest", "")
|
||||
if not digest.startswith("sha256:"):
|
||||
errors.append(f"invalid digest format for {item.get('path')}")
|
||||
continue
|
||||
digests.append(digest.split("sha256:")[1])
|
||||
|
||||
rerun_calc = hashlib.sha256("\n".join(sorted(digests)).encode()).hexdigest()
|
||||
rerun_expected = manifest.get("rerunHash")
|
||||
if rerun_expected != f"sha256:{rerun_calc}":
|
||||
errors.append(f"rerunHash mismatch: expected sha256:{rerun_calc} got {rerun_expected}")
|
||||
|
||||
annotations = manifest["integrity"]["oci"]["annotations"]
|
||||
manifest_digest_hex = annotations["io.stellaops.export.manifest-digest"].split("sha256:")[1]
|
||||
digest_hdr = manifest["integrity"]["httpHeaders"]["Digest"]
|
||||
expected_hdr = "sha-256=" + base64.b64encode(bytes.fromhex(manifest_digest_hex)).decode()
|
||||
if digest_hdr != expected_hdr:
|
||||
errors.append("Digest header does not match manifest digest annotation")
|
||||
|
||||
log_meta = manifest.get("attestations", {}).get("log")
|
||||
if not log_meta:
|
||||
errors.append("attestation log metadata missing")
|
||||
|
||||
if not manifest.get("quotas"):
|
||||
errors.append("quotas/backpressure block missing")
|
||||
|
||||
if len(set(tenants)) > 1 and not manifest.get("approval", {}).get("required"):
|
||||
errors.append("cross-tenant approval required but not present")
|
||||
|
||||
if errors:
|
||||
for err in errors:
|
||||
print(err)
|
||||
sys.exit(1)
|
||||
|
||||
print("manifest checks ok")
|
||||
PY
|
||||
|
||||
python - <<'PY' "${kit_dir}" "${manifest_sha}"
|
||||
import json, sys, pathlib
|
||||
|
||||
kit = pathlib.Path(sys.argv[1])
|
||||
manifest_sha = sys.argv[2]
|
||||
prov = json.loads(kit.joinpath("provenance.json").read_text())
|
||||
|
||||
manifest_subject = prov["subject"][0]["digest"]["sha256"]
|
||||
if manifest_subject != manifest_sha:
|
||||
print(f"provenance manifest digest mismatch: {manifest_subject} vs {manifest_sha}")
|
||||
sys.exit(1)
|
||||
|
||||
log = prov["predicate"]["environment"]["logs"]
|
||||
required = ["kind", "logId", "logIndex", "entryDigest", "timestamp"]
|
||||
missing = [k for k in required if k not in log]
|
||||
if missing:
|
||||
print(f"provenance log metadata missing keys: {missing}")
|
||||
sys.exit(1)
|
||||
|
||||
print("provenance checks ok")
|
||||
PY
|
||||
|
||||
echo "verify-export-kit: PASS"
|
||||
@@ -102,12 +102,12 @@ Selectors (time windows, tenants, products, SBOM subjects, ecosystems) are suppl
|
||||
- **Constraints:** Requires the base manifest to exist in object storage or artifact registry accessible to the worker. Fails with `ERR_EXPORT_BASE_MISSING` otherwise.
|
||||
- **Workflow:** Ideal for frequent updates to mirrored environments with limited bandwidth.
|
||||
|
||||
## Compatibility and guardrails
|
||||
- **Aggregation-Only Contract:** All profiles respect AOC boundaries: raw evidence is never mutated. Policy outputs are appended separately with clear provenance.
|
||||
- **Tenant scoping:** Profiles are tenant-specific. Cross-tenant exports require explicit administrative approval and signed justification.
|
||||
- **Retriable runs:** Re-running a profile with identical selectors yields matching manifests and hashes, facilitating verify-on-download workflows.
|
||||
- **Offline operation:** JSON and mirror profiles function in offline mode without additional configuration. Trivy profiles require pre-seeded schema metadata shipped via Offline Kit.
|
||||
- **Quota integration:** Profiles can define run quotas (per tenant per day). Quota exhaustion surfaces as `429 Too Many Requests` with `X-Stella-Quota-*` hints.
|
||||
## Compatibility and guardrails
|
||||
- **Aggregation-Only Contract:** All profiles respect AOC boundaries: raw evidence is never mutated. Policy outputs are appended separately with clear provenance.
|
||||
- **Tenant scoping + approvals:** Profiles are tenant-specific. When `selectors.tenants` includes additional tenants or wildcards, `approval.required=true` plus `approvedBy` and `ticket` must be present (validated by `verify-export-kit.sh` and schema).
|
||||
- **Retriable runs:** Re-running a profile with identical selectors yields matching manifests and hashes, facilitating verify-on-download workflows.
|
||||
- **Offline operation:** JSON and mirror profiles function in offline mode without additional configuration. Trivy profiles require pre-seeded schema metadata shipped via Offline Kit.
|
||||
- **Quota integration and backpressure:** Profiles declare `limits.maxActiveRuns`, `limits.maxQueuedRuns`, and `backpressureMode` (`reject`|`defer`|`throttle`). When limits trigger, exporters emit `429` with `X-Stella-Quota-*` plus `Retry-After` to keep retries deterministic.
|
||||
|
||||
## Example profile definition (CLI)
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ Export Center runs emit deterministic manifests, provenance records, and signatu
|
||||
- **Traceability.** Provenance links each bundle to the inputs that produced it: tenant, findings ledger queries, policy snapshots, SBOM identifiers, adapter versions, and encryption recipients.
|
||||
- **Determinism.** Canonical JSON (sorted keys, RFC 3339 UTC timestamps, normalized numbers) guarantees byte-for-byte stability across reruns with identical input.
|
||||
- **Portability.** Signatures and attestations travel with filesystem bundles, OCI artefacts, and Offline Kit staging trees. Verification does not require online Authority access when the bundle includes the cosign public key.
|
||||
- **Transparency metadata.** DSSE/SLSA artefacts must embed log metadata (hashedrekord/rekor-style `logId`, `logIndex`, `entryDigest`, `timestamp`) so offline kits can prove submission intent even without online verification.
|
||||
|
||||
---
|
||||
|
||||
@@ -38,8 +39,9 @@ All digests use lowercase hex SHA-256 (`sha256:<digest>`). When bundle encryptio
|
||||
- Provenance `subjects[]` contains both manifest hash and bundle/archive hash.
|
||||
3. **Key retrieval.** Worker obtains a short-lived signing token from Authority’s KMS client using tenant-scoped credentials (`export.sign` scope). Keys live in Authority or tenant-specific HSMs depending on deployment.
|
||||
4. **Signature emission.** Cosign generates detached signatures (`*.sig`). If DSSE is enabled, cosign wraps payload bytes in a DSSE envelope (`*.dsse`). Attestations follow the SLSA Level 2 provenance template; Level 3 requires builder metadata (`EXPORT-SVC-37-002` optional feature flag).
|
||||
5. **Storage & distribution.** Signatures and attestations are written alongside manifests in object storage, included in filesystem bundles, and attached as OCI artefact layers/annotations.
|
||||
6. **Audit trail.** Run metadata captures signer identity (`signing_key_id`), cosign certificate serial, signature timestamps, and verification hints. Console/CLI surface these details for downstream automation.
|
||||
5. **Log metadata.** DSSE/SLSA outputs record log hints: `{kind: "hashedrekord", logId, logIndex, entryDigest, timestamp}`. For air-gap deployments the hints ride inside the attestation; when online, the same values come from Rekor receipts.
|
||||
6. **Storage & distribution.** Signatures and attestations are written alongside manifests in object storage, included in filesystem bundles, and attached as OCI artefact layers/annotations.
|
||||
7. **Audit trail.** Run metadata captures signer identity (`signing_key_id`), cosign certificate serial, signature timestamps, log hints, and verification outcomes. Console/CLI surface these details for downstream automation.
|
||||
|
||||
> **Key management.** Secrets and key references are configured per tenant via `export.signing`, pointing to Authority clients or external HSM aliases. Offline deployments pre-load cosign public keys into the bundle (`signatures/pubkeys/{tenant}.pem`).
|
||||
|
||||
@@ -61,6 +63,7 @@ All digests use lowercase hex SHA-256 (`sha256:<digest>`). When bundle encryptio
|
||||
| `predicate.metadata.reproducible` | Always `true`—workers guarantee determinism. |
|
||||
| `predicate.environment.encryption` | Records encryption recipients, wrapped keys, algorithm (`age` or `aes-gcm`). |
|
||||
| `predicate.environment.kms` | Signing key identifier (`authority://tenant/export-signing-key`) and certificate chain fingerprints. |
|
||||
| `predicate.environment.logs` | Transparency metadata `{kind,logId,logIndex,entryDigest,timestamp}` required by EC3 to keep DSSE verifiable offline. |
|
||||
|
||||
Sample (abridged):
|
||||
|
||||
|
||||
254
docs/modules/export-center/schemas/export-manifest.schema.json
Normal file
254
docs/modules/export-center/schemas/export-manifest.schema.json
Normal file
@@ -0,0 +1,254 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.io/schemas/export-center/export-manifest.schema.json",
|
||||
"title": "StellaOps Export Manifest",
|
||||
"description": "Schema for run manifests, attestations, integrity headers, and quota/backpressure metadata (EC2–EC9).",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"schema",
|
||||
"version",
|
||||
"exportId",
|
||||
"profile",
|
||||
"tenant",
|
||||
"selectors",
|
||||
"generatedAt",
|
||||
"contents"
|
||||
],
|
||||
"properties": {
|
||||
"schema": { "type": "string", "const": "https://stellaops.io/export-center/manifest/v1alpha2" },
|
||||
"version": { "type": "string", "pattern": "^1\\.1\\.[0-9]+$" },
|
||||
"exportId": { "type": "string", "pattern": "^[a-z0-9-]{6,64}$" },
|
||||
"runId": { "type": "string", "pattern": "^[a-z0-9-]{6,64}$" },
|
||||
"profile": {
|
||||
"type": "object",
|
||||
"required": ["kind", "variant", "name"],
|
||||
"properties": {
|
||||
"kind": { "type": "string", "enum": ["json", "trivy", "mirror", "devportal", "attestation"] },
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": ["raw", "policy", "db", "java-db", "full", "delta", "offline", "bundle"]
|
||||
},
|
||||
"name": { "type": "string", "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$" },
|
||||
"revision": { "type": "string", "pattern": "^r[0-9]+$" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"tenant": { "type": "string", "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$" },
|
||||
"selectors": { "$ref": "#/$defs/selectors" },
|
||||
"generatedAt": { "type": "string", "format": "date-time" },
|
||||
"rerunHash": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
|
||||
"contents": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["path", "digest", "bytes"],
|
||||
"properties": {
|
||||
"path": { "type": "string", "pattern": "^[A-Za-z0-9._/-]+$" },
|
||||
"digest": { "$ref": "#/$defs/digest" },
|
||||
"bytes": { "type": "integer", "minimum": 0 },
|
||||
"records": { "type": "integer", "minimum": 0 },
|
||||
"contentType": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"delta": {
|
||||
"type": "object",
|
||||
"required": ["baseExportId", "baseManifestDigest", "tombstones"],
|
||||
"properties": {
|
||||
"baseExportId": { "type": "string", "pattern": "^[a-z0-9-]{6,64}$" },
|
||||
"baseManifestDigest": { "$ref": "#/$defs/digest" },
|
||||
"tombstones": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^[A-Za-z0-9._/-]+$" }
|
||||
},
|
||||
"added": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^[A-Za-z0-9._/-]+$" }
|
||||
},
|
||||
"removed": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^[A-Za-z0-9._/-]+$" }
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"integrity": {
|
||||
"type": "object",
|
||||
"required": ["httpHeaders", "oci"],
|
||||
"properties": {
|
||||
"httpHeaders": {
|
||||
"type": "object",
|
||||
"required": ["Digest", "X-Stella-Signature"],
|
||||
"properties": {
|
||||
"Digest": { "type": "string", "pattern": "^sha-256=[A-Za-z0-9+/=]+$" },
|
||||
"X-Stella-Signature": { "type": "string" },
|
||||
"X-Stella-Immutability": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"oci": {
|
||||
"type": "object",
|
||||
"required": ["annotations"],
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"io.stellaops.export.profile",
|
||||
"io.stellaops.export.run",
|
||||
"io.stellaops.export.manifest-digest",
|
||||
"io.stellaops.export.provenance-ref"
|
||||
],
|
||||
"properties": {
|
||||
"io.stellaops.export.profile": { "type": "string" },
|
||||
"io.stellaops.export.run": { "type": "string" },
|
||||
"io.stellaops.export.manifest-digest": { "$ref": "#/$defs/digest" },
|
||||
"io.stellaops.export.provenance-ref": { "type": "string" },
|
||||
"org.opencontainers.image.ref.name": { "type": "string" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"attestations": {
|
||||
"type": "object",
|
||||
"required": ["provenanceRef", "dsseEnvelope", "slsaLevel", "log"],
|
||||
"properties": {
|
||||
"provenanceRef": { "type": "string" },
|
||||
"dsseEnvelope": { "type": "string" },
|
||||
"slsaLevel": { "type": "string" },
|
||||
"log": {
|
||||
"type": "object",
|
||||
"required": ["kind", "logId", "logIndex", "entryDigest", "timestamp"],
|
||||
"properties": {
|
||||
"kind": { "type": "string", "enum": ["hashedrekord", "rekor"] },
|
||||
"logId": { "type": "string" },
|
||||
"logIndex": { "type": "integer", "minimum": 0 },
|
||||
"entryDigest": { "$ref": "#/$defs/digest" },
|
||||
"timestamp": { "type": "string", "format": "date-time" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"distribution": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"http": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" },
|
||||
"retentionDays": { "type": "integer", "minimum": 1, "maximum": 3650 },
|
||||
"etag": { "type": "string" },
|
||||
"rangeRequests": { "type": "boolean" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"oci": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" },
|
||||
"reference": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"object": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" },
|
||||
"bucket": { "type": "string" },
|
||||
"prefix": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"encryption": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mode": { "type": "string", "enum": ["age", "aes-gcm"] },
|
||||
"recipients": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["keyId", "fingerprint"],
|
||||
"properties": {
|
||||
"keyId": { "type": "string" },
|
||||
"fingerprint": { "type": "string" },
|
||||
"wrappedKey": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"strict": { "type": "boolean" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"approval": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"required": { "type": "boolean" },
|
||||
"reason": { "type": "string" },
|
||||
"approvedBy": { "type": "string" },
|
||||
"ticket": { "type": "string" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"quotas": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxActiveRuns": { "type": "integer", "minimum": 1, "maximum": 32 },
|
||||
"maxQueuedRuns": { "type": "integer", "minimum": 1, "maximum": 512 },
|
||||
"backpressureMode": {
|
||||
"type": "string",
|
||||
"enum": ["reject", "defer", "throttle"]
|
||||
},
|
||||
"cpuThrottlePercent": { "type": "integer", "minimum": 1, "maximum": 100 }
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"digest": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" },
|
||||
"selectors": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tenants": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^[a-z0-9*.-]+$" },
|
||||
"uniqueItems": true
|
||||
},
|
||||
"products": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "pattern": "^pkg:[A-Za-z0-9.+\\-_/:@*]+$" }
|
||||
},
|
||||
"timeWindow": {
|
||||
"oneOf": [
|
||||
{ "type": "string", "pattern": "^[0-9]+d$" },
|
||||
{ "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}/[0-9]{4}-[0-9]{2}-[0-9]{2}$" }
|
||||
]
|
||||
},
|
||||
"severities": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "enum": ["critical", "high", "medium", "low", "info"] },
|
||||
"uniqueItems": true
|
||||
},
|
||||
"ecosystems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["npm", "maven", "pypi", "nuget", "go", "cargo", "rpm", "deb", "apk", "java"]
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
206
docs/modules/export-center/schemas/export-profile.schema.json
Normal file
206
docs/modules/export-center/schemas/export-profile.schema.json
Normal file
@@ -0,0 +1,206 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://stellaops.io/schemas/export-center/export-profile.schema.json",
|
||||
"title": "StellaOps ExportProfile",
|
||||
"description": "Canonical schema for Export Center profile definitions with selector and approval guardrails (EC1, EC4, EC9).",
|
||||
"type": "object",
|
||||
"required": ["apiVersion", "kind", "metadata", "spec"],
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"const": "stellaops.io/export.v1"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"const": "ExportProfile"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"required": ["name", "tenant"],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 3,
|
||||
"maxLength": 64,
|
||||
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
|
||||
},
|
||||
"tenant": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"
|
||||
},
|
||||
"revision": {
|
||||
"type": "string",
|
||||
"pattern": "^r[0-9]+$"
|
||||
},
|
||||
"labels": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"maxLength": 128
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"spec": {
|
||||
"type": "object",
|
||||
"required": ["kind", "variant", "distribution"],
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": ["json", "trivy", "mirror", "devportal", "attestation"]
|
||||
},
|
||||
"variant": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"raw",
|
||||
"policy",
|
||||
"db",
|
||||
"java-db",
|
||||
"full",
|
||||
"delta",
|
||||
"offline",
|
||||
"bundle"
|
||||
]
|
||||
},
|
||||
"distribution": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["http", "oci", "object"]
|
||||
},
|
||||
"uniqueItems": true,
|
||||
"minItems": 1
|
||||
},
|
||||
"compression": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"codec": {
|
||||
"type": "string",
|
||||
"enum": ["zstd", "gzip", "none"]
|
||||
},
|
||||
"level": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 22
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"encryption": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enabled": { "type": "boolean" },
|
||||
"mode": { "type": "string", "enum": ["age", "aes-gcm"] },
|
||||
"recipientKeys": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^(age1|kms://)"
|
||||
}
|
||||
},
|
||||
"strict": { "type": "boolean" }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"retention": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mode": { "type": "string", "enum": ["days", "never"] },
|
||||
"value": { "type": "integer", "minimum": 1, "maximum": 3650 }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"limits": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"maxActiveRuns": { "type": "integer", "minimum": 1, "maximum": 32 },
|
||||
"maxQueuedRuns": { "type": "integer", "minimum": 1, "maximum": 512 },
|
||||
"backpressureMode": {
|
||||
"type": "string",
|
||||
"enum": ["reject", "defer", "throttle"]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"selectors": { "$ref": "#/$defs/selectors" },
|
||||
"approval": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"required": { "type": "boolean" },
|
||||
"reason": { "type": "string", "maxLength": 256 },
|
||||
"ticket": { "type": "string", "maxLength": 64 },
|
||||
"approver": { "type": "string", "maxLength": 64 }
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"schemaVersion": {
|
||||
"type": "string",
|
||||
"enum": ["1.1.0"],
|
||||
"default": "1.1.0"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"$defs": {
|
||||
"selectors": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^[a-z0-9*.-]+$"
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"products": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^pkg:[A-Za-z0-9.+\\-_/:@*]+$"
|
||||
}
|
||||
},
|
||||
"ecosystems": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"npm",
|
||||
"maven",
|
||||
"pypi",
|
||||
"nuget",
|
||||
"go",
|
||||
"cargo",
|
||||
"rpm",
|
||||
"deb",
|
||||
"apk",
|
||||
"java"
|
||||
]
|
||||
},
|
||||
"uniqueItems": true
|
||||
},
|
||||
"timeWindow": {
|
||||
"oneOf": [
|
||||
{ "type": "string", "pattern": "^[0-9]+d$" },
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}/[0-9]{4}-[0-9]{2}-[0-9]{2}$"
|
||||
}
|
||||
]
|
||||
},
|
||||
"severities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["critical", "high", "medium", "low", "info"]
|
||||
},
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,11 +152,11 @@ The Java supplement only includes ecosystems `maven`, `gradle`, `sbt`. Additiona
|
||||
|
||||
## 4. Compatibility matrix
|
||||
|
||||
| Trivy version | Schema version | Supported by adapter | Notes |
|
||||
|---------------|----------------|----------------------|-------|
|
||||
| 0.46.x | 2 | Yes | Baseline compatibility target. |
|
||||
| 0.50.x | 2 | Yes | Default validation target in CI. |
|
||||
| 0.51.x+ | 3 | Pending | Adapter throws `ERR_EXPORT_UNSUPPORTED_SCHEMA` until implemented. |
|
||||
| Trivy version | Schema version | Supported by adapter | Notes |
|
||||
|---------------|----------------|----------------------|-------|
|
||||
| 0.46.x | 2 (pinned) | Yes | Baseline compatibility target. |
|
||||
| 0.50.x | 2 (pinned) | Yes | Default validation target in CI and fixtures. |
|
||||
| 0.51.x+ | 3 | Pending | Adapter throws `ERR_EXPORT_UNSUPPORTED_SCHEMA` until implemented or explicitly overridden. |
|
||||
|
||||
Schema mismatches emit `adapter.trivy.unsupported_schema_version` and abort the run. Operators can pin the schema via `ExportCenter:Adapters:Trivy:SchemaVersion`.
|
||||
|
||||
@@ -169,10 +169,13 @@ Schema mismatches emit `adapter.trivy.unsupported_schema_version` and abort the
|
||||
- Generate bundle from fixture dataset.
|
||||
- Run `trivy module db import <bundle>` (Trivy CLI) to ensure the bundle is accepted.
|
||||
- For Java DB, run `trivy java-repo --db <bundle>` against sample repository.
|
||||
3. **CI smoke (`DEVOPS-EXPORT-36-001`)**:
|
||||
- Validate metadata fields using `jq`.
|
||||
- Ensure signatures verify with `cosign`.
|
||||
- Check runtime by invoking `trivy fs --cache-dir <temp> --skip-update --custom-db <bundle> fixtures/image`.
|
||||
3. **CI smoke (`DEVOPS-EXPORT-36-001`)**:
|
||||
- Validate metadata fields using `jq`.
|
||||
- Ensure signatures verify with `cosign`.
|
||||
- Check runtime by invoking `trivy fs --cache-dir <temp> --skip-update --custom-db <bundle> fixtures/image`.
|
||||
4. **Schema pinning (EC6)**:
|
||||
- CI enforces `ExportCenter:Adapters:Trivy:SchemaVersion=2`; higher versions fail fast with `adapter.trivy.unsupported_schema_version`.
|
||||
- Export manifests/OCI annotations record the pinned schema for rerun-hash stability.
|
||||
|
||||
Failures set the run status to `failed` with `errorCode="adapter-trivy"` so Console/CLI expose the reason.
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
- `sbom_snapshots` (immutable versions; tenant + artifact + digest + createdAt)
|
||||
- `sbom_projections` (materialised views keyed by snapshotId, entrypoint/service node flags)
|
||||
- `sbom_assets` (asset metadata, criticality/owner/env/exposure; append-only history)
|
||||
- `sbom_catalog` (console catalog surface; indexed by artifact, scope, license, assetTags.*, createdAt for deterministic pagination)
|
||||
- `sbom_component_neighbors` (component lookup graph edges; indexed by purl+artifact for cursor pagination)
|
||||
- `sbom_paths` (resolved dependency paths with runtime flags, blast-radius hints)
|
||||
- `sbom_events` (outbox for event delivery + watermark/backfill tracking)
|
||||
|
||||
@@ -84,7 +86,12 @@ Operational rules:
|
||||
- Logs: structured, include tenant + artifact digest + sbomVersion; classify ingest failures (schema, storage, orchestrator, validation).
|
||||
- Alerts: backlog thresholds for outbox/event delivery; high latency on path/timeline endpoints.
|
||||
|
||||
## 9) Open questions / dependencies
|
||||
## 9) Configuration (Mongo-backed catalog & lookup)
|
||||
- Enable Mongo storage for `/console/sboms` and `/components/lookup` by setting `SbomService:Mongo:ConnectionString` (env: `SBOM_SbomService__Mongo__ConnectionString`).
|
||||
- Optional overrides: `SbomService:Mongo:Database`, `SbomService:Mongo:CatalogCollection`, `SbomService:Mongo:ComponentLookupCollection`; defaults are `sbom_service`, `sbom_catalog`, `sbom_component_neighbors`.
|
||||
- When the connection string is absent the service falls back to fixture JSON or deterministic in-memory seeds to keep air-gapped workflows alive.
|
||||
|
||||
## 10) Open questions / dependencies
|
||||
- Confirm orchestrator pause/backfill contract (shared with Runtime & Signals 140-series).
|
||||
- Finalise storage collection names and indexes (compound on tenant+artifactDigest+version, TTL for transient staging).
|
||||
- Publish canonical LNM v1 fixtures and JSON schemas for projections and asset metadata.
|
||||
|
||||
Reference in New Issue
Block a user