feat: Add VEX compact fixture and implement offline verifier for Findings Ledger exports

- Introduced a new VEX compact fixture for testing purposes.
- Implemented `verify_export.py` script to validate Findings Ledger exports, ensuring deterministic ordering and applying redaction manifests.
- Added a lightweight stub `HarnessRunner` for unit tests to validate ledger hashing expectations.
- Documented tasks related to the Mirror Creator.
- Created models for entropy signals and implemented the `EntropyPenaltyCalculator` to compute penalties based on scanner outputs.
- Developed unit tests for `EntropyPenaltyCalculator` to ensure correct penalty calculations and handling of edge cases.
- Added tests for symbol ID normalization in the reachability scanner.
- Enhanced console status service with comprehensive unit tests for connection handling and error recovery.
- Included Cosign tool version 2.6.0 with checksums for various platforms.
This commit is contained in:
StellaOps Bot
2025-12-02 21:08:01 +02:00
parent 6d049905c7
commit 47168fec38
146 changed files with 4329 additions and 549 deletions

View File

@@ -38,11 +38,13 @@
| 11 | CONCELIER-STORE-AOC-19-005-DEV | BLOCKED (2025-11-04) | Waiting on staging dataset hash + rollback rehearsal using prep doc | Concelier Storage Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo`) | Execute raw-linkset backfill/rollback plan so Mongo reflects Link-Not-Merge data; rehearse rollback (dev/staging). |
| 12 | CONCELIER-TEN-48-001 | DONE (2025-11-28) | Created Tenancy module with `TenantScope`, `TenantCapabilities`, `TenantCapabilitiesResponse`, `ITenantCapabilitiesProvider`, and `TenantScopeNormalizer` per AUTH-TEN-47-001. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Enforce tenant scoping through normalization/linking; expose capability endpoint advertising `merge=false`; ensure events include tenant IDs. |
| 13 | CONCELIER-VEXLENS-30-001 | BLOCKED | PREP-CONCELIER-VULN-29-001; VEXLENS-30-005 | Concelier WebService Guild · VEX Lens Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Guarantee advisory key consistency and cross-links consumed by VEX Lens so consensus explanations cite Concelier evidence without merges. |
| 14 | CONCELIER-GAPS-115-014 | TODO | None; informs tasks 013. | Product Mgmt · Concelier Guild | Address Concelier ingestion gaps CI1CI10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: publish signed observation/linkset schemas and AOC guard, enforce denylist/allowlist via analyzers, require provenance/signature details, feed snapshot governance/staleness, deterministic conflict rules, canonical content-hash/idempotency keys, tenant isolation tests, connector sandbox limits, offline advisory bundle schema/verify, and shared fixtures/CI determinism. |
| 14 | CONCELIER-GAPS-115-014 | DONE (2025-12-02) | None; informs tasks 013. | Product Mgmt · Concelier Guild | Address Concelier ingestion gaps CI1CI10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: publish signed observation/linkset schemas and AOC guard, enforce denylist/allowlist via analyzers, require provenance/signature details, feed snapshot governance/staleness, deterministic conflict rules, canonical content-hash/idempotency keys, tenant isolation tests, connector sandbox limits, offline advisory bundle schema/verify, and shared fixtures/CI determinism. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | Completed CONCELIER-GAPS-115-014: published signed LNM schemas + manifest/signature, added connector HttpClient sandbox analyzer, hardened AOC guard for canonical sha256 + signature metadata, added determinism/tenant isolation tests and offline bundle fixtures. Targeted Core tests passing. | Implementer |
| 2025-12-02 | Started CONCELIER-GAPS-115-014 remediation: schema signing, AOC provenance guard, determinism/tenant isolation tests. | Implementer |
| 2025-11-28 | Completed CONCELIER-RISK-69-001: implemented `AdvisoryFieldChangeNotification`, `AdvisoryFieldChange`, `AdvisoryFieldChangeProvenance` models + `IAdvisoryFieldChangeEmitter` interface + `AdvisoryFieldChangeEmitter` implementation + `IAdvisoryFieldChangeNotificationPublisher` interface + `InMemoryAdvisoryFieldChangeNotificationPublisher`. Detects changes in fix availability, KEV status, severity, CVSS score, and observation status with full provenance. DI registration via `AddConcelierRiskServices()`. Sprint 0115 RISK tasks now complete (66-001, 66-002, 67-001, 69-001 DONE; 68-001 BLOCKED on POLICY-RISK-68-001). | Implementer |
| 2025-12-01 | Added CONCELIER-GAPS-115-014 to capture CI1CI10 remediation from `31-Nov-2025 FINDINGS.md`. | Product Mgmt |
| 2025-11-28 | Completed CONCELIER-RISK-66-002: implemented `FixAvailabilityMetadata`, `FixRelease`, `FixAdvisoryLink` models with provenance anchors + `IFixAvailabilityEmitter` interface + `FixAvailabilityEmitter` implementation for emitting structured fix-availability metadata per observation/linkset. DI registration via `AddConcelierRiskServices()`. Unblocked CONCELIER-RISK-69-001. | Implementer |
@@ -81,6 +83,7 @@
- Raw linkset backfill (STORE-AOC-19-005) must preserve rollback paths to protect Offline Kit deployments; release packaging tracked separately in DevOps planning.
- Tenant-aware linking and notification hooks depend on Authority/Signals contracts; delays could stall AOC compliance and downstream alerts.
- Upstream contracts absent: POLICY-20-001 (sprint 0114), AUTH-TEN-47-001, SIGNALS-24-002—until delivered, POLICY/RISK/SIG/TEN tasks in this sprint stay BLOCKED.
- CI1CI10 remediation shipped: signed schema bundle (`docs/modules/concelier/schemas/*`) with detached signature, AOC guard now enforces canonical sha256 + signature metadata, connector analyzer `CONCELIER0004` guards unsandboxed `HttpClient`, and deterministic fixtures/tests cover idempotency/tenant isolation/offline bundle staleness.
## Next Checkpoints
- Plan backfill rehearsal window for STORE-AOC-19-005 once AUTH/AOC prerequisites clear (date TBD).

View File

@@ -43,11 +43,13 @@
| 6 | LEDGER-OBS-54-001 | DONE (2025-11-22) | `/v1/ledger/attestations` endpoint implemented with deterministic paging + filters hash; schema/OAS updated | Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | Verify attestation references for ledger-derived exports; expose `/ledger/attestations` endpoint returning DSSE verification state and chain-of-custody summary |
| 7 | LEDGER-RISK-66-001 | DONE (2025-11-21) | PREP-LEDGER-RISK-66-001-RISK-ENGINE-SCHEMA-CO | Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Add schema migrations for `risk_score`, `risk_severity`, `profile_version`, `explanation_id`, and supporting indexes |
| 8 | LEDGER-RISK-66-002 | DONE (2025-11-21) | PREP-LEDGER-RISK-66-002-DEPENDS-ON-66-001-MIG | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Implement deterministic upsert of scoring results keyed by finding hash/profile version with history audit |
| 9 | LEDGER-GAPS-121-009 | TODO | Close FL1FL10 gaps from `docs/product-advisories/28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md`; align schemas/exports with advisory; depends on schema catalog refresh | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Remediate FL1FL10: publish versioned schemas/canonical JSON (events/projections/exports), Merkle + external anchor policy doc, tenant isolation + redaction manifest, DSSE/policy hash linkage, deterministic exports + golden fixtures, offline verifier script, replay/rebuild checksum guard, and quotas/backpressure metrics; update docs under `docs/modules/findings-ledger/`. |
| 9 | LEDGER-GAPS-121-009 | DONE (2025-12-02) | Close FL1FL10 gaps from `docs/product-advisories/28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md`; align schemas/exports with advisory; depends on schema catalog refresh | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Remediate FL1FL10: publish versioned schemas/canonical JSON (events/projections/exports), Merkle + external anchor policy doc, tenant isolation + redaction manifest, DSSE/policy hash linkage, deterministic exports + golden fixtures, offline verifier script, replay/rebuild checksum guard, and quotas/backpressure metrics; update docs under `docs/modules/findings-ledger/`. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | Completed LEDGER-GAPS-121-009: added schema catalog + FL1FL10 gap report, Merkle/anchor policy, redaction manifest, DSSE linkage doc, golden export fixtures + checksums, offline verifier script with replay checksum guard, quota/backpressure metrics/code/tests. | Findings Ledger |
| 2025-12-02 | Started LEDGER-GAPS-121-009 (FL1FL10 remediation); status DOING; drafting schema catalog, Merkle/anchor policy, redaction manifest, offline verifier, and backpressure metrics. | Findings Ledger |
| 2025-12-01 | Added LEDGER-GAPS-121-009 to track FL1FL10 remediation from `docs/product-advisories/28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md`; status TODO pending schema catalog refresh. | Project Mgmt |
| 2025-12-02 | Clarified LEDGER-GAPS-121-009 outputs: schema catalog, Merkle/anchor policy, tenant isolation/redaction manifest, DSSE/policy linkage, deterministic exports + golden fixtures, offline verifier, replay checksums, and quotas/backpressure metrics. | Project Mgmt |
| 2025-11-25 | Moved all remaining BLOCKED tasks (OAS, ATTEST, OBS-55, PACKS) to new sprint `SPRINT_0121_0001_0002_policy_reasoning_blockers`; cleansed Delivery Tracker to active/completed items only. | Project Mgmt |
@@ -83,6 +85,7 @@
- Current state: findings export endpoint and paging contracts implemented; VEX/advisory/SBOM endpoints stubbed (auth + shape) but await underlying projection/query schemas. Risk schema/implementation (LEDGER-RISK-66-001/002) delivered. Remaining blockers: OAS/SDK surface (61/62/63), attestation HTTP host (OBS-54/55), and packs time-travel contract (PACKS-42-001).
- Export endpoints now enforce filter hash + page token determinism for VEX/advisory/SBOMs but still return empty sets until backing projections land; downstream SDK/OAS tasks should treat payload shapes as stable.
- New advisory gaps (FL1FL10) tracked via LEDGER-GAPS-121-009; requires schema catalog refresh and alignment of Merkle/anchoring, redaction, DSSE linkage, and offline verify tooling with `docs/product-advisories/28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md` recommendations.
- FL1FL10 remediation shipped: schema catalog + gap report, Merkle/anchor policy, redaction manifest (JSON/YAML), DSSE linkage guidance, golden export fixtures/checksums, offline verify script with replay checksum guard, and quota/backpressure metrics/tests wired into ledger service.
## Next Checkpoints
- Schedule cross-guild kickoff for week of 2025-11-24 once dependency clears.

View File

@@ -15,11 +15,19 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/policy/architecture.md`
## Interlocks
- POLICY-CONSOLE-23-001 (Console export/simulation contract from BE-Base Platform) must be published before POLICY-CONSOLE-23-002 can start.
## Action Tracker
| # | Action | Owner | Due | Status |
| --- | --- | --- | --- | --- |
| 1 | Publish Console export/simulation contract for POLICY-CONSOLE-23-001 to unblock POLICY-CONSOLE-23-002 | BE-Base Platform Guild | — | BLOCKED (awaiting spec) |
## Delivery Tracker
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| P1 | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Deterministic evaluator spec missing. <br><br> Document artefact/deliverable for POLICY-ENGINE-20-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/policy/design/policy-deterministic-evaluator.md`. |
| 1 | POLICY-CONSOLE-23-002 | BLOCKED (2025-11-27) | Waiting on POLICY-CONSOLE-23-001 export/simulation contract. | Policy Guild, Product Ops / `src/Policy/StellaOps.Policy.Engine` |
| 1 | POLICY-CONSOLE-23-002 | BLOCKED (2025-12-02) | POLICY-CONSOLE-23-001 export/simulation contract still not published; waiting on Console API spec from BE-Base Platform. | Policy Guild, Product Ops / `src/Policy/StellaOps.Policy.Engine` |
| 2 | POLICY-ENGINE-20-002 | DONE (2025-11-27) | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 3 | POLICY-ENGINE-20-003 | DONE (2025-11-27) | Depends on 20-002. | Policy · Concelier · Excititor Guilds / `src/Policy/StellaOps.Policy.Engine` |
| 4 | POLICY-ENGINE-20-004 | DONE (2025-11-27) | Depends on 20-003. | Policy · Platform Storage Guild / `src/Policy/StellaOps.Policy.Engine` |
@@ -36,6 +44,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | Rechecked for POLICY-CONSOLE-23-001 contract; none found. Left POLICY-CONSOLE-23-002 BLOCKED (2025-12-02). Added Interlocks and Action Tracker sections to align with sprint template. | Project Mgmt |
| 2025-12-01 | Refactored Mongo exception listing to shared filter/sort helpers (per-tenant and cross-tenant) for lifecycle scans; reran `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests -c Release --no-build` (208/208 pass). | Implementer |
| 2025-12-01 | Completed deterministic evidence summary (big-endian hash → `2025-12-13T05:00:11Z`) and exception lifecycle fixes (multi-tenant activation/expiry, no default tenant); added cross-tenant list overload. `dotnet test src/Policy/__Tests/StellaOps.Policy.Engine.Tests -c Release --no-build` now passes (208 tests, 0 failures). | Implementer |
| 2025-12-01 | Ran `dotnet build src/Policy/StellaOps.Policy.Engine/StellaOps.Policy.Engine.csproj -c Release` successfully (1 warning NU1510). Attempted `dotnet test ...Policy.Engine.Tests` but cancelled mid-run due to prolonged dependency compilation; rerun still needed. | Implementer |
@@ -52,7 +61,7 @@
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Console simulation/export contract (POLICY-CONSOLE-23-001) still outstanding; POLICY-CONSOLE-23-002 remains BLOCKED until published.
- 2025-12-02: Console export/simulation contract (POLICY-CONSOLE-23-001) still outstanding; POLICY-CONSOLE-23-002 remains BLOCKED until BE-Base Platform publishes the spec.
- Release test suite for Policy Engine now green (2025-12-01); keep enforcing deterministic inputs (explicit evaluationTimestamp) on batch evaluation requests to avoid non-deterministic clocks.
## Next Checkpoints

View File

@@ -33,9 +33,9 @@
| 8 | AIRGAP-TIME-57-001 | BLOCKED | MIRROR-CRT-56-001 sample exists; needs DSSE/TUF + time-anchor schema from AirGap Time. | AirGap Time Guild | Provide trusted time-anchor service & policy. |
| 9 | CLI-AIRGAP-56-001 | BLOCKED | MIRROR-CRT-56-002/58-001 pending; offline kit inputs unavailable. | CLI Guild | Extend CLI offline kit tooling to consume mirror bundles. |
| 10 | PROV-OBS-53-001 | DONE (2025-11-23) | Observer doc + verifier script `scripts/mirror/verify_thin_bundle.py` in repo; validates hashes, determinism, and manifest/index digests. | Security Guild | Define provenance observers + verification hooks. |
| 11 | OFFKIT-GAPS-125-011 | TODO | None; informs tasks 49. | Product Mgmt · Mirror/AirGap Guilds | Address offline-kit gaps OK1OK10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: key manifest/rotation + PQ co-sign, tool hashing/signing, DSSE-signed top-level manifest linking all artifacts, checkpoint freshness/mirror metadata, deterministic packaging flags, inclusion of scan/VEX/policy/graph hashes, time anchor bundling, transport/chunking + chain-of-custody, tenant/env scoping, and scripted verify with negative-path guidance. |
| 12 | REKOR-GAPS-125-012 | TODO | None; informs tasks 110. | Product Mgmt · Mirror/AirGap · Attestor Guilds | Address Rekor v2/DSSE gaps RK1RK10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: enforce dsse/hashedrekord only, payload size preflight + chunk manifests, public/private routing policy, shard-aware checkpoints, idempotent submission keys, Sigstore bundles in kits, checkpoint freshness bounds, PQ dual-sign options, error taxonomy/backoff, policy/graph annotations in DSSE/bundles. |
| 13 | MIRROR-GAPS-125-013 | TODO | None; informs tasks 112. | Product Mgmt · Mirror Creator Guild · AirGap Guild | Address mirror/offline strategy gaps MS1MS10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: signed/versioned mirror schemas, DSSE/TUF rotation policy (incl. PQ), delta spec with tombstones/base hash, time-anchor freshness enforcement, tenant/env scoping, distribution integrity for HTTP/OCI/object, chunking/size rules, standard verify script, metrics/alerts for build/import/verify, and SemVer/change log for mirror formats. |
| 11 | OFFKIT-GAPS-125-011 | DONE (2025-12-02) | Bundle meta + offline policy layers + verifier updated; see milestone.json and bundle DSSE. | Product Mgmt · Mirror/AirGap Guilds | Address offline-kit gaps OK1OK10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: key manifest/rotation + PQ co-sign, tool hashing/signing, DSSE-signed top-level manifest linking all artifacts, checkpoint freshness/mirror metadata, deterministic packaging flags, inclusion of scan/VEX/policy/graph hashes, time anchor bundling, transport/chunking + chain-of-custody, tenant/env scoping, and scripted verify with negative-path guidance. |
| 12 | REKOR-GAPS-125-012 | DONE (2025-12-02) | Rekor policy layer + bundle meta/TUF DSSE; refer to `layers/rekor-policy.json`. | Product Mgmt · Mirror/AirGap · Attestor Guilds | Address Rekor v2/DSSE gaps RK1RK10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: enforce dsse/hashedrekord only, payload size preflight + chunk manifests, public/private routing policy, shard-aware checkpoints, idempotent submission keys, Sigstore bundles in kits, checkpoint freshness bounds, PQ dual-sign options, error taxonomy/backoff, policy/graph annotations in DSSE/bundles. |
| 13 | MIRROR-GAPS-125-013 | DONE (2025-12-02) | Mirror policy layer + tenant/env scope + verifier; see mirror-policy.json & bundle meta. | Product Mgmt · Mirror Creator Guild · AirGap Guild | Address mirror/offline strategy gaps MS1MS10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: signed/versioned mirror schemas, DSSE/TUF rotation policy (incl. PQ), delta spec with tombstones/base hash, time-anchor freshness enforcement, tenant/env scoping, distribution integrity for HTTP/OCI/object, chunking/size rules, standard verify script, metrics/alerts for build/import/verify, and SemVer/change log for mirror formats. |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -73,12 +73,15 @@
| 2025-12-01 | Added OFFKIT-GAPS-125-011 to track OK1OK10 remediation from `31-Nov-2025 FINDINGS.md`. | Product Mgmt |
| 2025-12-01 | Added REKOR-GAPS-125-012 to track RK1RK10 remediation from `31-Nov-2025 FINDINGS.md`. | Product Mgmt |
| 2025-12-01 | Added MIRROR-GAPS-125-013 to track MS1MS10 remediation from `31-Nov-2025 FINDINGS.md`. | Product Mgmt |
| 2025-12-02 | Moved OFFKIT/REKOR/MIRROR gap tasks to DOING; created `src/Mirror/StellaOps.Mirror.Creator/TASKS.md` for local tracking and began bundle meta/policy implementation. | Implementer |
| 2025-12-02 | Completed OK/RK/MS gap remediation: added policy layers (transport/rekor/mirror/offline), bundle meta + DSSE, verifier scope/DSSE/tool-hash checks, and refreshed milestone hashes via `scripts/mirror/ci-sign.sh`. | Implementer |
## Decisions & Risks
- **Decisions**
- Assign primary engineer for MIRROR-CRT-56-001 (due 2025-11-17 EOD). Owners: Mirror Creator Guild · Exporter Guild; Security as backup. Option A selected: thin bundle v1; acceptance: names recorded in Delivery Tracker + kickoff notes.
- Confirm DSSE/TUF signing profile (due 2025-11-18). Owners: Security Guild · Attestor Guild. Needed before MIRROR-CRT-56-002 can merge.
- Lock time-anchor authority scope (due 2025-11-19). Owners: AirGap Time Guild · Mirror Creator Guild. Required for MIRROR-CRT-57-002 policy enforcement.
- 2025-12-02: OK/RK/MS gap baseline adopted — bundle meta DSSE (`mirror-thin-v1.bundle.dsse.json`) and policy layers (transport, rekor, mirror, offline-kit) are now canonical evidence; verifier enforces tenant/env scope + tool hashes.
- **Risks**
- Production signing key lives in Ops sprint: release signing (`MIRROR_SIGN_KEY_B64` secret + CI promotion) is handled in Sprint 506 (Ops DevOps IV); this dev sprint remains green using dev key until ops wiring lands.
- Time-anchor requirements undefined → air-gapped bundles lose verifiable time guarantees. Mitigation: run focused session with AirGap Time Guild to lock policy + service interface.

View File

@@ -32,7 +32,7 @@
| 13 | POLICY-ENGINE-70-004 | DONE (2025-12-01) | Depends on 70-003. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Exception metrics/tracing/logging. |
| 14 | POLICY-ENGINE-70-005 | DONE (2025-12-01) | Depends on 70-004. | Policy · Scheduler Worker Guild / `src/Policy/StellaOps.Policy.Engine` | Exception activation/expiry + events. |
| 15 | POLICY-ENGINE-80-001 | DONE (2025-12-01) | Depends on 70-005. | Policy · Signals Guild / `src/Policy/StellaOps.Policy.Engine` | Reachability/exploitability inputs into evaluation. |
| 16 | POLICY-RISK-90-001 | BLOCKED (2025-12-01) | Waiting on Scanner entropy/trust algebra contract. | Policy · Scanner Guild / `src/Policy/StellaOps.Policy.Engine` | Entropy penalty ingestion + trust algebra. |
| 16 | POLICY-RISK-90-001 | DONE (2025-12-02) | Entropy ingestion implemented; monitor scanner payloads + thresholds. | Policy · Scanner Guild / `src/Policy/StellaOps.Policy.Engine` | Entropy penalty ingestion + trust algebra. |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -61,15 +61,16 @@
| 2025-12-01 | POLICY-ENGINE-80-001 marked BLOCKED: reachability/exploitability input contract from Signals guild not yet published; no schema to integrate. | Implementer |
| 2025-12-01 | POLICY-RISK-90-001 marked BLOCKED: Scanner entropy/trust algebra contract still pending; ingestion shape unknown. | Implementer |
| 2025-12-01 | POLICY-ENGINE-80-001 delivered: runtime evaluation now auto-enriches reachability from facts store with overlay cache; batch lookups dedupe per tenant; cache keys include reachability metadata; added reachability-driven rule test. Targeted policy-engine test slice attempted; build fanned out and was aborted—rerun on clean policy-only graph recommended. | Implementer |
| 2025-12-02 | POLICY-RISK-90-001 delivered: added entropy penalty calculator consuming `layer_summary.json`/`entropy.report.json`, configurable caps/thresholds under `PolicyEngine:Entropy`, telemetry (`policy_entropy_penalty_value`, `policy_entropy_image_opaque_ratio`), and unit tests (`EntropyPenaltyCalculatorTests`). Unblocked Scanner dependency based on documented schema. | Implementer |
## Decisions & Risks
- Remaining TODO: POLICY-RISK-90-001 (entropy/trust algebra ingestion) still depends on Scanner contract.
- Entropy penalties now computed inside Policy Engine (`PolicyEngine:Entropy` options; default K=0.5, cap=0.3, block at image opaque ratio >0.15 when provenance is unknown). Telemetry exported as `policy_entropy_penalty_value` and `policy_entropy_image_opaque_ratio`; explanations surface top opaque files.
- Reachability auto-enrichment landed (POLICY-ENGINE-80-001); exploitability signal format still absent—wire once Signals publishes contract.
- Exception lifecycle now auto-activates/auto-expires; configure `ExceptionLifecycle` intervals per deployment and provide Redis if using distributed cache (in-memory defaults remain for offline use).
- In-memory exception repository is registered by default for offline runs; swap to Mongo repository in production to persist lifecycle and review history.
- Telemetry for exception applications added; dashboards should consume `policy_exception_applications_total`, `policy_exception_application_latency_seconds`, and `policy_exception_lifecycle_total`.
- Graph-disabled test slices remain recommended (`DOTNET_DISABLE_BUILTIN_GRAPH=1`) to avoid static graph fan-out during focused test runs.
## Next Checkpoints
- Await Signals reachability/exploitability contract, then implement POLICY-ENGINE-80-001 (evaluation inputs + metrics).
- Await Scanner entropy/trust algebra contract, then implement POLICY-RISK-90-001 (ingestion + trust weighting + telemetry).
- Mirror exception lifecycle/observability changes into `docs/modules/policy/architecture.md` and dashboards.
- Await Signals reachability/exploitability contract, then refine POLICY-ENGINE-80-001 metrics once schema lands.
- Validate entropy penalty outputs against the next Scanner bundle drop; tune `PolicyEngine:Entropy` defaults if ratios shift.
- Mirror exception lifecycle/observability changes into `docs/modules/policy/architecture.md` and dashboards.

View File

@@ -1,13 +1,13 @@
# Sprint 0136-0001-0001 · Scanner & Surface (Phase VII)
## Topic & Scope
- Scanner & Surface phase VII: EntryTrace NDJSON export, process-tree replay, and surface/CLI integration.
- Scanner & Surface phase VII: EntryTrace NDJSON/replay surfacing, deterministic SBOM composition, Surface.FS/Env/Secrets rollout, and downstream consumers (Scheduler, Zastava, Cartographer, Console) enablement.
- Sequential across 130139; start after Sprint 0135.
- **Working directory:** `src/Scanner`.
- **Working directory:** `src/Scanner` (with coordinated touches in Scheduler/Zastava where noted).
## Dependencies & Concurrency
- Upstream: Sprint 0135 (phase VI) must land first.
- Concurrency: tasks are TODO; follow order below.
- Concurrency: honour dependency column; SCANNER-SURFACE/EMIT work must finish before downstream consumers pick up DSSE artifacts.
## Documentation Prerequisites
- docs/README.md
@@ -19,38 +19,117 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 0 | SURFACE-FS-01 | DONE (2025-11-24) | Spec published in `docs/modules/scanner/design/surface-fs.md` v1.1 | Scanner Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS`) | Author Surface.FS cache/manifest specification and cross-module contract (manifests, CAS URIs, cache layout). |
| 1 | SURFACE-FS-02 | DONE (2025-11-24) | Core library implemented; see `src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS` | Scanner Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS`) | Ship FileSurfaceManifestStore/Reader/Writer + cache options, deterministic path builder, and DI registration per `surface-fs.md`. |
| 2 | SCANNER-ENTRYTRACE-18-504 | DONE | Upstream 18-503 delivered; NDJSON emission implemented in worker and surfaced via manifest/CLI/WebService. | EntryTrace Guild (`src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace`) | Emit EntryTrace AOC NDJSON (`entrytrace.entry/node/edge/target/warning/capability`) and wire CLI/service streaming outputs. |
| 3 | SCANNER-ENTRYTRACE-18-505 | DONE | Replay implemented; uses `/proc` snapshots to adjust confidence, collapse wrappers, and emit match/mismatch diagnostics with runtime chains. | EntryTrace Guild | Implement ProcGraph replay to reconcile `/proc` exec chains with static EntryTrace, collapsing wrappers and emitting agreement/conflict diagnostics. |
| 4 | SCANNER-ENTRYTRACE-18-506 | DONE (2025-12-01) | Surfaced via WebService `/scans/{id}/entrytrace` and CLI rendering. | EntryTrace Guild · Scanner WebService Guild | Surface EntryTrace graph + confidence via Scanner.WebService and CLI, including target summary in scan reports and policy payloads. |
| 5 | ZASTAVA-SURFACE-02 | DONE (2025-12-01) | Manifest CAS/sha resolver in Observer drift evidence with failure metrics. | Zastava Observer Guild (`src/Zastava/StellaOps.Zastava.Observer`) | SURFACE-FS-02, ZASTAVA-SURFACE-01; see `docs/modules/scanner/design/surface-fs-consumers.md` §4 |
| 6 | SCANNER-SORT-02 | DONE (2025-12-01) | Layer fragment ordering by digest implemented; deterministic regression test added. | Scanner Core Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Core`) | SCANNER-EMIT-15-001 |
| 7 | SCANNER-EMIT-15-001 | DOING (2025-12-01) | CycloneDX artifacts now carry content hash + merkle root and recipe placeholders; DSSE/recipe persistence pending. | Scanner Emit Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Emit`) | SCANNER-SURFACE-04 |
| 8 | SCANNER-SURFACE-01 | BLOCKED (2025-11-25) | Task definition absent; needs scope/contract before implementation. | Scanner Guild | — |
| 1 | SURFACE-FS-01 | DONE (2025-11-24) | Spec published in `docs/modules/scanner/design/surface-fs.md` v1.1 | Scanner Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS`) | Author Surface.FS cache/manifest specification and cross-module contract (manifests, CAS URIs, cache layout). |
| 2 | SURFACE-FS-02 | DONE (2025-11-24) | Core library implemented | Scanner Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS`) | Ship FileSurfaceManifestStore/Reader/Writer + cache options, deterministic path builder, and DI registration per `surface-fs.md`. |
| 3 | SCANNER-ENTRYTRACE-18-504 | DONE | Depends on 18-503 | EntryTrace Guild (`src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace`) | Emit EntryTrace AOC NDJSON (`entrytrace.entry/node/edge/target/warning/capability`) and wire CLI/service streaming outputs. |
| 4 | SCANNER-ENTRYTRACE-18-505 | DONE | SCANNER-ENTRYTRACE-18-504 | EntryTrace Guild | Implement ProcGraph replay to reconcile `/proc` exec chains with static EntryTrace, collapsing wrappers and emitting diagnostics. |
| 5 | SCANNER-ENTRYTRACE-18-506 | DONE (2025-12-01) | SCANNER-ENTRYTRACE-18-505 | EntryTrace Guild · Scanner WebService Guild | Surface EntryTrace graph + confidence via Scanner.WebService and CLI, including target summary in scan reports and policy payloads. |
| 6 | SCANNER-ENV-01 | DONE (2025-11-18) | — | Scanner Worker Guild (`src/Scanner/StellaOps.Scanner.Worker`) | Wire worker to `AddSurfaceEnvironment`/`ISurfaceEnvironment` for cache roots + CAS endpoints; remove ad-hoc env reads. |
| 7 | SCANNER-ENV-02 | DONE (2025-11-27) | SCANNER-ENV-01 | Scanner WebService Guild, Ops Guild (`src/Scanner/StellaOps.Scanner.WebService`) | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. |
| 8 | SCANNER-ENV-03 | DONE (2025-11-27) | SCANNER-ENV-02 | BuildX Plugin Guild (`src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin`) | Pack Surface.Env, mirror to offline (`offline/packages/nugets`), and wire BuildX to use 0.1.0-alpha.20251123 with updated restore feeds. |
| 9 | SURFACE-ENV-01 | DONE (2025-11-13) | — | Scanner Guild, Zastava Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env`) | Draft `surface-env.md` enumerating environment variables, defaults, and air-gap behaviour for Surface consumers. |
| 10 | SURFACE-ENV-02 | DONE (2025-11-18) | SURFACE-ENV-01 | Scanner Guild | Implement strongly-typed env accessors with validation for required endpoint, bounds, TLS cert path; add regression tests. |
| 11 | SURFACE-ENV-03 | DONE (2025-11-27) | SURFACE-ENV-02 | Scanner Guild | Adopt env helper across Scanner Worker/WebService/BuildX plug-ins. |
| 12 | SURFACE-ENV-04 | DONE (2025-11-27) | SURFACE-ENV-02 | Zastava Guild | Wire env helper into Zastava Observer/Webhook containers. |
| 13 | SURFACE-ENV-05 | DONE | SURFACE-ENV-03, SURFACE-ENV-04 | Ops Guild | Update Helm/Compose/offline kit templates with new env knobs and documentation. |
| 14 | SCANNER-EVENTS-16-301 | BLOCKED (2025-10-26) | Orchestrator envelope contract; Notifier ingestion tests | Scanner WebService Guild | Emit orchestrator-compatible envelopes (`scanner.event.*`) and update integration tests to verify Notifier ingestion (no Redis queue coupling). |
| 15 | SCANNER-GRAPH-21-001 | DONE (2025-11-27) | — | Scanner WebService Guild, Cartographer Guild (`src/Scanner/StellaOps.Scanner.WebService`) | Provide webhook/REST endpoint for Cartographer to request policy overlays and runtime evidence for graph nodes, ensuring determinism and tenant scoping. |
| 16 | SCANNER-LNM-21-001 | BLOCKED (2025-11-27) | Needs Concelier HTTP client/shared library | Scanner WebService Guild, Policy Guild | Update `/reports` and `/policy/runtime` payloads to consume advisory/vex linksets, exposing source severity arrays and conflict summaries alongside effective verdicts. |
| 17 | SCANNER-LNM-21-002 | TODO | SCANNER-LNM-21-001 | Scanner WebService Guild, UI Guild | Add evidence endpoint for Console to fetch linkset summaries with policy overlay for a component/SBOM, including AOC references. |
| 18 | SCANNER-SECRETS-03 | DONE (2025-11-27) | SCANNER-SECRETS-02 | BuildX Plugin Guild, Security Guild (`src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin`) | Use Surface.Secrets to retrieve registry credentials when interacting with CAS/referrers. |
| 19 | SURFACE-SECRETS-01 | DONE (2025-11-23) | — | Scanner Guild, Security Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets`) | Security-approved schema published at `docs/modules/scanner/design/surface-secrets-schema.md`. |
| 20 | SURFACE-SECRETS-02 | DONE (2025-11-23) | SURFACE-SECRETS-01 | Scanner Guild | Provider chain implemented (primary + fallback) with DI wiring; tests updated (`StellaOps.Scanner.Surface.Secrets.Tests`). |
| 21 | SURFACE-SECRETS-03 | DONE (2025-11-27) | SURFACE-SECRETS-02 | Scanner Guild | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. |
| 22 | SURFACE-SECRETS-04 | DONE (2025-11-27) | SURFACE-SECRETS-02 | Scanner Guild | Integrate Surface.Secrets into Scanner Worker/WebService/BuildX for registry + CAS creds. |
| 23 | SURFACE-SECRETS-05 | DONE (2025-11-27) | SURFACE-SECRETS-02 | Zastava Guild | Invoke Surface.Secrets from Zastava Observer/Webhook for CAS & attestation secrets. |
| 24 | SURFACE-SECRETS-06 | BLOCKED (2025-11-27) | SURFACE-SECRETS-03; awaiting Ops Helm/Compose patterns | Ops Guild | Update deployment manifests/offline kit bundles to provision secret references instead of raw values. |
| 25 | SCANNER-ENG-0020 | DONE (2025-11-28) | — | Scanner Guild (`docs/modules/scanner`) | Implement Homebrew collector & fragment mapper per `design/macos-analyzer.md` §3.1. |
| 26 | SCANNER-ENG-0021 | DONE (2025-11-28) | — | Scanner Guild | Implement pkgutil receipt collector per `design/macos-analyzer.md` §3.2. |
| 27 | SCANNER-ENG-0022 | DONE (2025-11-28) | — | Scanner Guild, Policy Guild | Implement macOS bundle inspector & capability overlays per `design/macos-analyzer.md` §3.3. |
| 28 | SCANNER-ENG-0023 | DONE (2025-11-28) | — | Scanner Guild, Offline Kit Guild, Policy Guild | Deliver macOS policy/offline integration per `design/macos-analyzer.md` §56. |
| 29 | SCANNER-ENG-0024 | DONE (2025-11-28) | — | Scanner Guild | Implement Windows MSI collector per `design/windows-analyzer.md` §3.1. |
| 30 | SCANNER-ENG-0025 | DONE (2025-11-28) | — | Scanner Guild | Implement WinSxS manifest collector per `design/windows-analyzer.md` §3.2. |
| 31 | SCANNER-ENG-0026 | DONE (2025-11-28) | — | Scanner Guild | Implement Windows Chocolatey & registry collectors per `design/windows-analyzer.md` §3.33.4. |
| 32 | SCANNER-ENG-0027 | DONE (2025-11-28) | — | Scanner Guild, Policy Guild, Offline Kit Guild | Deliver Windows policy/offline integration per `design/windows-analyzer.md` §56. |
| 33 | SCHED-SURFACE-02 | TODO | SURFACE-FS-02; SCHED-SURFACE-01; see `docs/modules/scanner/design/surface-fs-consumers.md` §3 | Scheduler Worker Guild (`src/Scheduler/__Libraries/StellaOps.Scheduler.Worker`) | Integrate Scheduler worker prefetch using Surface manifest reader and persist manifest pointers with rerun plans. |
| 34 | ZASTAVA-SURFACE-02 | DONE (2025-12-01) | SURFACE-FS-02, ZASTAVA-SURFACE-01 | Zastava Observer Guild (`src/Zastava/StellaOps.Zastava.Observer`) | Surface manifest CAS/sha resolver wired into Observer drift evidence with failure metrics. |
| 35 | SURFACE-FS-03 | DONE (2025-11-27) | SURFACE-FS-02 | Scanner Guild | Integrate Surface.FS writer into Scanner Worker analyzer pipeline to persist layer + entry-trace fragments. |
| 36 | SURFACE-FS-04 | DONE (2025-11-27) | SURFACE-FS-02 | Zastava Guild | Integrate Surface.FS reader into Zastava Observer runtime drift loop. |
| 37 | SURFACE-FS-05 | DONE (2025-11-27) | SURFACE-FS-03 | Scanner Guild, Scheduler Guild | Expose Surface.FS pointers via Scanner WebService reports and coordinate rescan planning with Scheduler. |
| 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). |
| 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 | DOING (2025-12-01) | 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; replace deterministic-local signer with real signing. |
| 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. |
| 45 | SURFACE-VAL-01 | DONE (2025-11-23) | SURFACE-FS-01, SURFACE-ENV-01 | Scanner Guild, Security Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation`) | Validation framework doc aligned with Surface.Env release and secrets schema (`surface-validation.md` v1.1). |
| 46 | SURFACE-VAL-02 | DONE (2025-11-23) | SURFACE-VAL-01, SURFACE-ENV-02, SURFACE-FS-02 | Scanner Guild | Validation library enforces secrets schema, fallback/provider checks, and inline/file guardrails; tests added. |
| 47 | SURFACE-VAL-03 | DONE (2025-11-23) | SURFACE-VAL-02 | Scanner Guild, Analyzer Guild | Validation runner wired into Worker/WebService startup and pre-analyzer paths (OS, language, EntryTrace). |
| 48 | SURFACE-VAL-04 | DONE (2025-11-27) | SURFACE-VAL-02 | Scanner Guild, Zastava Guild | Expose validation helpers to Zastava and other runtime consumers for preflight checks. |
| 49 | SURFACE-VAL-05 | DONE | SURFACE-VAL-02 | Docs Guild | Document validation extensibility, registration, and customization in scanner-engine guides. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-08 | Sprint stub created; awaiting completion of Sprint 0135. | Planning |
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_136_scanner_surface.md` to `SPRINT_0136_0001_0001_scanner_surface.md`; content preserved. | Implementer |
| 2025-11-19 | Converted legacy filename `SPRINT_136_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer |
| 2025-11-24 | Marked SURFACE-FS-01 DONE; spec anchored in `docs/modules/scanner/design/surface-fs.md` v1.1. | Scanner Guild |
| 2025-11-24 | Marked SURFACE-FS-02 DONE; core Surface.FS manifest/cache library implemented and DI-ready. | Scanner Guild |
| 2025-11-25 | Marked EntryTrace chain (18-504/505/506) BLOCKED pending upstream 18-503 outputs from prior phase. | Project Mgmt |
| 2025-11-25 | Added SCANNER-SURFACE-01 to tracker and marked BLOCKED because task definition/scope is missing from sprint/docs; needs contract before work can begin. | Project Mgmt |
| 2025-12-01 | Unblocked EntryTrace NDJSON track: 18-504 set to TODO after 18-503 delivered in Sprint 0135; 18-505/506 remain blocked on 504 completion. | Project Mgmt |
| 2025-12-01 | Completed 18-504: EntryTrace NDJSON emitted via worker (EntryTraceNdjsonWriter) and surfaced in SurfaceManifest payloads; CLI/WebService entrytrace endpoint returns NDJSON alongside graph. | Implementer |
| 2025-12-01 | Completed 18-505: ProcGraph replay reconciles `/proc` snapshot with static EntryTrace, collapsing wrappers and emitting runtime match/mismatch diagnostics with chains; confidence adjusted per runtime evidence. | Implementer |
| 2025-12-01 | Added best-terminal metadata to entrytrace graph/ndjson surface payloads; SurfaceManifestStageExecutor tests updated and passing. | Implementer |
| 2025-12-01 | Completed 18-506: WebService `/scans/{id}/entrytrace` and CLI rendering now expose EntryTrace graph + confidence summaries alongside NDJSON stream. | 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 |
| 2025-12-01 | EntryTrace NDJSON emission, runtime reconciliation, and WebService/CLI exposure completed (18-504/505/506). | EntryTrace Guild |
| 2025-12-01 | ZASTAVA-SURFACE-02: Observer resolves Surface manifest digests and `cas://` URIs, enriches drift evidence with artifact metadata, and counts failures via `zastava_surface_manifest_failures_total`. | Implementer |
| 2025-12-01 | SCANNER-SORT-02: ComponentGraphBuilder sorts layer fragments by digest; regression test added. | Implementer |
| 2025-12-02 | Surface FS determinism plumbing verified: injected ICryptoHash into FileSurfaceManifestStore test harness; `dotnet test …SurfaceManifestDeterminismVerifierTests` (2/2 pass) and full `StellaOps.Scanner.Surface.FS.Tests` suite (7/7 pass). | Implementer |
| 2025-12-01 | SCANNER-EMIT-15-001: CycloneDX artifacts now publish `ContentHash`, carry Merkle/recipe URIs, emit `_composition.json` + DSSE envelopes (recipe & layer.fragments), and Surface manifests reference those attestations. DSSE signer is pluggable (deterministic fallback registered); real signing still pending. | Implementer |
| 2025-12-01 | SCANNER-SORT-02 completed: ComponentGraphBuilder sorts layer fragments by digest with regression test Build_SortsLayersByDigest. | Implementer |
| 2025-12-01 | ZASTAVA-SURFACE-02: Observer now resolves Surface manifest digests and `cas://` URIs, enriches drift evidence with artifact metadata, and counts failures via `zastava_surface_manifest_failures_total`. | Implementer |
| 2025-11-28 | Created `docs/modules/scanner/guides/surface-validation-extensibility.md` covering custom validators, reporters, configuration, and testing; SURFACE-VAL-05 DONE. | Implementer |
| 2025-11-28 | Created `docs/modules/scanner/guides/surface-fs-workflow.md` with end-to-end workflow including artefact generation, storage layout, consumption, and offline kit handling; SURFACE-FS-06 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Homebrew` library with `HomebrewReceiptParser`, `HomebrewPackageAnalyzer`, and `HomebrewAnalyzerPlugin`; 23 tests passing. SCANNER-ENG-0020 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Pkgutil` library with `PkgutilReceiptParser`, `BomParser`, `PkgutilPackageAnalyzer`, and `PkgutilAnalyzerPlugin`; 9 tests passing. SCANNER-ENG-0021 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Windows.Msi` library with `MsiDatabaseParser`, `MsiPackageAnalyzer`, and `MsiAnalyzerPlugin`; 22 tests passing. SCANNER-ENG-0024 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Windows.WinSxS` library with `WinSxSManifestParser`, `WinSxSPackageAnalyzer`, and `WinSxSAnalyzerPlugin`; 18 tests passing. SCANNER-ENG-0025 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey` library with `NuspecParser`, `ChocolateyPackageAnalyzer`, and `ChocolateyAnalyzerPlugin`; 44 tests passing. SCANNER-ENG-0026 DONE. | Implementer |
| 2025-11-28 | Updated `docs/modules/scanner/design/windows-analyzer.md` with implementation status documenting MSI/WinSxS/Chocolatey collectors, PURL formats, and vendor metadata schemas; registry collector deferred, policy predicates pending Policy module integration. SCANNER-ENG-0027 DONE. | Implementer |
| 2025-11-27 | Added missing package references to BuildX plugin (Configuration.EnvironmentVariables, DependencyInjection, Logging); refactored to use public AddSurfaceEnvironment API instead of internal SurfaceEnvironmentFactory; build passes. SCANNER-ENV-03 DONE. | Implementer |
| 2025-11-27 | Created SurfaceFeatureFlagsConfigurator to merge Surface.Env feature flags into WebService FeatureFlagOptions.Experimental dictionary; registered configurator in Program.cs. Cache roots and feature flags now wired from Surface.Env. SCANNER-ENV-02 DONE. | Implementer |
| 2025-11-27 | Verified SURFACE-ENV-03: Scanner Worker (SCANNER-ENV-01), WebService (SCANNER-ENV-02), and BuildX (SCANNER-ENV-03) all wire Surface.Env helpers; task complete. SURFACE-ENV-03 DONE. | Implementer |
| 2025-11-27 | Added CachingSurfaceSecretProvider (deterministic TTL cache), AuditingSurfaceSecretProvider (structured audit logging), and OfflineSurfaceSecretProvider (integrity-verified offline kit support); wired into ServiceCollectionExtensions with configurable options. SURFACE-SECRETS-03 DONE. | Implementer |
| 2025-11-27 | Added Surface.Validation project references to Zastava Observer and Webhook; wired AddSurfaceValidation() in service extensions for preflight checks. SURFACE-VAL-04 DONE. | Implementer |
| 2025-11-27 | Verified Zastava Observer and Webhook already have AddSurfaceEnvironment() wired with ZASTAVA prefixes; SURFACE-ENV-04 DONE. | Implementer |
| 2025-11-27 | Added Surface.Secrets project reference to BuildX plugin; implemented TryResolveAttestationToken() to fetch attestation secrets from Surface.Secrets; Worker/WebService already had configurators for CAS/registry/attestation secrets. SURFACE-SECRETS-04 DONE. | Implementer |
| 2025-11-27 | Verified Zastava Observer/Webhook already have ObserverSurfaceSecrets/WebhookSurfaceSecrets classes using ISurfaceSecretProvider for CAS and attestation secrets. SURFACE-SECRETS-05 DONE. | Implementer |
| 2025-11-27 | SURFACE-SECRETS-06 marked BLOCKED: requires Ops Guild input on Helm/Compose patterns for Surface.Secrets provider configuration (kubernetes/file/inline). Added to Decisions & Risks. | Implementer |
| 2025-11-27 | Integrated ISurfaceManifestWriter into SurfaceManifestStageExecutor to persist manifest documents to file-system store for offline/air-gapped scenarios; build verified. SURFACE-FS-03 DONE. | Implementer |
| 2025-11-27 | Added IRuntimeSurfaceFsClient injection to RuntimePostureEvaluator, enriching drift evidence with manifest digest/artifacts/metadata; added `zastava_surface_manifest_failures_total` metric with reason labels. SURFACE-FS-04 DONE. | Implementer |
| 2025-11-27 | Added TryResolveCasCredentials() to BuildX plugin using Surface.Secrets to fetch CAS access credentials; fixed attestation token resolution to use correct parser method. SCANNER-SECRETS-03 DONE. | Implementer |
| 2025-11-27 | Verified SurfacePointerService already exposes Surface.FS pointers (SurfaceManifestDocument, SurfaceManifestArtifact, manifest URI/digest) via reports endpoint. SURFACE-FS-05 DONE. | Implementer |
| 2025-11-27 | Added POST /policy/overlay endpoint for Cartographer integration: accepts graph nodes, returns deterministic overlays with sha256(tenant|nodeId|overlayKind) IDs, includes runtime evidence. Added PolicyOverlayRequestDto/ResponseDto contracts. SCANNER-GRAPH-21-001 DONE. | Implementer |
| 2025-11-27 | SCANNER-LNM-21-001 marked BLOCKED: Scanner WebService has no existing Concelier integration; requires HTTP client or shared library reference to Concelier.Core for linkset consumption. Added to Decisions & Risks. | Implementer |
| 2025-11-24 | Marked SURFACE-FS-01 DONE; spec anchored in `docs/modules/scanner/design/surface-fs.md` v1.1. | Scanner Guild |
| 2025-11-24 | Marked SURFACE-FS-02 DONE; core Surface.FS manifest/cache library implemented and DI-ready. | Scanner Guild |
| 2025-11-23 | Published Security-approved Surface.Secrets schema; moved SURFACE-SECRETS-01 to DONE, SURFACE-SECRETS-02/SURFACE-VAL-01 to TODO. | Security Guild |
| 2025-11-23 | Implemented Surface.Secrets provider chain/fallback and added DI tests; marked SURFACE-SECRETS-02 DONE. | Scanner Guild |
| 2025-11-23 | Pinned Surface.Env package version `0.1.0-alpha.20251123` and offline path in `docs/modules/scanner/design/surface-env-release.md`; SCANNER-ENV-03 moved to TODO. | BuildX Plugin Guild |
| 2025-11-23 | Updated Surface.Validation doc to v1.1, binding to Surface.Env release and secrets schema; marked SURFACE-VAL-01 DONE. | Scanner Guild |
| 2025-11-23 | Strengthened Surface.Validation secrets checks (provider/fallback/inline/file root) and added unit tests; marked SURFACE-VAL-02 DONE. | Scanner Guild |
| 2025-11-23 | Wired SurfaceValidation runner into Worker/WebService startup to fail fast; SURFACE-VAL-03 in progress. | Scanner Guild |
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_136_scanner_surface.md` to `SPRINT_0136_0001_0001_scanner_surface.md`; content preserved. | Implementer |
| 2025-11-19 | Converted legacy filename `SPRINT_136_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer |
| 2025-11-18 | SCANNER-ENV-01 in progress: added manifest store options configurator in Scanner Worker and unit scaffold (tests pending due to local restore/vstest issues). | Implementer |
| 2025-11-18 | SCANNER-ENV-02 started: wired Surface manifest store options into Scanner WebService and unit scaffold added; tests pending (nuget.org restore cancelled locally). | Implementer |
| 2025-11-18 | Attempted `dotnet test` for Worker Surface manifest configurator; restore failed fetching StackExchange.Redis from nuget.org (network timeout); tests still pending CI. | Implementer |
| 2025-11-18 | SCANNER-ENV-03 started: BuildX plugin now loads Surface.Env defaults for cache root/bucket/tenant when args/env missing; tests not yet added. | Implementer |
| 2025-11-12 | SURFACE-ENV-01 done; SURFACE-ENV-02 started; SURFACE-SECRETS-01/02 in progress. | Scanner Guild |
| 2025-11-08 | Sprint stub created; awaiting completion of Sprint 0135. | Planning |
| 2025-10-26 | Initial sprint plan captured; dependencies noted across Scheduler/Surface/Cartographer. | Planning |
## Decisions & Risks
- EntryTrace NDJSON export and replay completed; relies on deterministic `/proc` capture and preserved ordering for confidence adjustments.
- SCANNER-SURFACE-01 blocked: no task definition/contract present; needs scope before DOING.
- SCANNER-LNM-21-001 remains BLOCKED: Scanner WebService lacks Concelier integration; decision needed on shared client vs new HTTP client. Downstream SCANNER-LNM-21-002 cannot start.
- 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: real DSSE signer still pending; deterministic-local signer only. Surface manifest consumers must not assume transparency until signer is wired.
- Long restore/build times in monorepo runners delayed determinism test runs for SURFACE-FS-07; rerun in CI once signer work lands.
## Next Checkpoints
- Schedule kickoff after Sprint 0135 completion (date TBD).
- Concelier client decision & Ops secrets provisioning pattern review (target scheduling pending owners).

View File

@@ -30,15 +30,16 @@
| 2 | 140.B SBOM Service wave | DOING (2025-11-28) | Sprint 0142 mostly complete: SBOM-SERVICE-21-001..004, SBOM-AIAI-31-001/002, SBOM-ORCH-32/33/34-001, SBOM-VULN-29-001/002 all DONE. Only SBOM-CONSOLE-23-001/002 remain BLOCKED. | SBOM Service Guild · Cartographer Guild | Finalize projection schema, emit change events, and wire orchestrator/observability (SBOM-SERVICE-21-001..004, SBOM-AIAI-31-001/002). |
| 3 | 140.C Signals wave | DOING (2025-11-28) | Sprint 0143: SIGNALS-24-001/002/003 DONE; SIGNALS-24-004/005 remain BLOCKED on CAS promotion. | Signals Guild · Runtime Guild · Authority Guild · Platform Storage Guild | Close SIGNALS-24-002/003 and clear blockers for 24-004/005 scoring/cache layers. |
| 4 | 140.D Zastava wave | DONE (2025-11-28) | Sprint 0144 (Zastava Runtime Signals) complete: all ZASTAVA-ENV/SECRETS/SURFACE tasks DONE. | Zastava Observer/Webhook Guilds · Surface Guild | Prepare env/secret helpers and admission hooks; start once cache endpoints and helpers are published. |
| 5 | DECAY-GAPS-140-005 | BLOCKED (2025-12-02) | cosign binary unavailable in environment; cannot sign `confidence_decay_config.yaml`. Needs cosign (or offline signer) to proceed by 2025-12-05. | Signals Guild · Product Mgmt | Address decay gaps U1U10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: publish signed `confidence_decay_config` (τ governance, floor/freeze/SLA clamps), weighted signals taxonomy, UTC/monotonic time rules, deterministic recompute cadence + checksum, uncertainty linkage, migration/backfill plan, API fields/bands, and observability/alerts. |
| 6 | UNKNOWN-GAPS-140-006 | BLOCKED (2025-12-02) | cosign binary unavailable; cannot sign unknowns scoring manifest. Needs cosign/offline signer before 2025-12-05. | Signals Guild · Policy Guild · Product Mgmt | Address unknowns gaps UN1UN10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: publish signed Unknowns registry schema + scoring manifest (deterministic), decay policy catalog, evidence/provenance capture, SBOM/VEX linkage, SLA/suppression rules, API/CLI contracts, observability/reporting, offline bundle inclusion, and migration/backfill. |
| 7 | UNKNOWN-HEUR-GAPS-140-007 | BLOCKED (2025-12-02) | cosign binary unavailable; cannot sign heuristic catalog/schema + fixtures. Needs cosign/offline signer before 2025-12-05. | Signals Guild · Policy Guild · Product Mgmt | Remediate UT1UT10: publish signed heuristic catalog/schema with deterministic scoring formula, quality bands, waiver policy with DSSE, SLA coupling, offline kit packaging, observability/alerts, backfill plan, explainability UX fields/exports, and fixtures with golden outputs. |
| 9 | COSIGN-INSTALL-140 | TODO | Install/provide cosign binary (or offline signer) in build environment by 2025-12-03 to unblock DSSE signing for tasks 57. | Platform / Build Guild | Deliver cosign binary locally (no network dependency at signing time) or alternate signer; document path and version in Execution Log. |
| 5 | DECAY-GAPS-140-005 | DOING (2025-12-02) | cosign v2.6.0 available at `tools/cosign/cosign` (sha256 `ea5c65f99425d6cfbb5c4b5de5dac035f14d09131c1a0ea7c7fc32eab39364f9`); DSSE signing on 2025-12-05. | Signals Guild · Product Mgmt | Address decay gaps U1U10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: publish signed `confidence_decay_config` (τ governance, floor/freeze/SLA clamps), weighted signals taxonomy, UTC/monotonic time rules, deterministic recompute cadence + checksum, uncertainty linkage, migration/backfill plan, API fields/bands, and observability/alerts. |
| 6 | UNKNOWN-GAPS-140-006 | DOING (2025-12-02) | cosign v2.6.0 available at `tools/cosign/cosign`; sign unknowns scoring manifest and publish DSSE envelope by 2025-12-05. | Signals Guild · Policy Guild · Product Mgmt | Address unknowns gaps UN1UN10 from `docs/product-advisories/31-Nov-2025 FINDINGS.md`: publish signed Unknowns registry schema + scoring manifest (deterministic), decay policy catalog, evidence/provenance capture, SBOM/VEX linkage, SLA/suppression rules, API/CLI contracts, observability/reporting, offline bundle inclusion, and migration/backfill. |
| 7 | UNKNOWN-HEUR-GAPS-140-007 | DOING (2025-12-02) | cosign v2.6.0 available at `tools/cosign/cosign`; prep catalog/schema fixtures for 2025-12-05 signing. | Signals Guild · Policy Guild · Product Mgmt | Remediate UT1UT10: publish signed heuristic catalog/schema with deterministic scoring formula, quality bands, waiver policy with DSSE, SLA coupling, offline kit packaging, observability/alerts, backfill plan, explainability UX fields/exports, and fixtures with golden outputs. |
| 9 | COSIGN-INSTALL-140 | DONE (2025-12-02) | cosign v2.6.0 staged under `tools/cosign` (sha256 `ea5c65f99425d6cfbb5c4b5de5dac035f14d09131c1a0ea7c7fc32eab39364f9`); add `tools/cosign` to PATH for signing 2025-12-05. | Platform / Build Guild | Deliver cosign binary locally (no network dependency at signing time) or alternate signer; document path and version in Execution Log. |
| 8 | SIGNER-ASSIGN-140 | DONE (2025-12-02) | Signer designated: Signals Guild (Alice Carter); DSSE signing checkpoint remains 2025-12-05. | Signals Guild · Policy Guild | Name signer(s), record in Execution Log, and proceed to DSSE signing + Evidence Locker ingest. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | Staged cosign v2.6.0 binary under `tools/cosign` (sha256 `ea5c65f99425d6cfbb5c4b5de5dac035f14d09131c1a0ea7c7fc32eab39364f9`); symlink available at `tools/cosign/cosign`; flipped COSIGN-INSTALL-140 to DONE and tasks 57 back to DOING for 2025-12-05 DSSE signing. | Implementer |
| 2025-12-02 | Refreshed Decisions & Risks after signer assignment; DSSE signing fixed for 2025-12-05 and decay/unknowns/heuristics remain BLOCKED pending `cosign` availability in offline kit. | Project Mgmt |
| 2025-12-02 | Marked DECAY-GAPS-140-005 / UNKNOWN-GAPS-140-006 / UNKNOWN-HEUR-GAPS-140-007 as BLOCKED pending DSSE signer assignment; added task SIGNER-ASSIGN-140 (BLOCKED) and DSSE signing checkpoint (2025-12-05). | Implementer |
| 2025-12-02 | Flagged cascading risk to SPRINT_0143/0144/0150 if signer not assigned by 2025-12-03; will mirror BLOCKED status to dependent tasks if missed. | Implementer |
@@ -79,7 +80,7 @@
- Link-Not-Merge v1 schema frozen 2025-11-17; fixtures staged under `docs/modules/sbomservice/fixtures/lnm-v1/`; AirGap parity review scheduled for 2025-11-23 (see Next Checkpoints) must record hashes to fully unblock.
- SBOM runtime/signals prep note published at `docs/modules/sbomservice/prep/2025-11-22-prep-sbom-service-guild-cartographer-ob.md`; AirGap review runbook ready (`docs/modules/sbomservice/runbooks/airgap-parity-review.md`). Wave moves to TODO pending review completion and fixture hash upload.
- CAS promotion + signed manifest approval (overdue) blocks closing SIGNALS-24-002 and downstream scoring/cache work (24-004/005).
- Decay/Unknowns/heuristics remediation (U1U10, UN1UN10, UT1UT10) remain BLOCKED on missing `cosign` binary even though signer is assigned (Alice Carter); DSSE signing scheduled for 2025-12-05. If the signing tool (or offline alternative) is not available by 2025-12-03, mirror BLOCKED status into SPRINT_0143/0144/0150. Draft docs and artifacts posted at `docs/modules/signals/decay/2025-12-01-confidence-decay.md`, `docs/modules/signals/decay/confidence_decay_config.yaml`, `docs/modules/signals/unknowns/2025-12-01-unknowns-registry.md`, `docs/modules/signals/unknowns/unknowns_scoring_manifest.json`, and `docs/modules/signals/heuristics/` (catalog, schema, fixtures); DSSE signatures pending. Hashes recorded in `docs/modules/signals/SHA256SUMS` for offline/air-gap parity; Evidence Locker ingest plan staged at `docs/modules/signals/evidence/README.md` and will be populated post-signing. COSIGN-INSTALL-140 added to track tool availability.
- Cosign v2.6.0 binary pinned at `tools/cosign/cosign` (sha256 `ea5c65f99425d6cfbb5c4b5de5dac035f14d09131c1a0ea7c7fc32eab39364f9`; see `tools/cosign/README.md`); DSSE signing deadline remains 2025-12-05—decay/unknowns/heuristics teams must sign and ingest envelopes + SHA256SUMS into Evidence Locker the same day or cascade risk into 0143/0144/0150. Draft docs and artifacts posted at `docs/modules/signals/decay/2025-12-01-confidence-decay.md`, `docs/modules/signals/decay/confidence_decay_config.yaml`, `docs/modules/signals/unknowns/2025-12-01-unknowns-registry.md`, `docs/modules/signals/unknowns/unknowns_scoring_manifest.json`, and `docs/modules/signals/heuristics/` (catalog, schema, fixtures); DSSE signatures pending. Hashes recorded in `docs/modules/signals/SHA256SUMS`; Evidence Locker ingest plan in `docs/modules/signals/evidence/README.md`.
- DSSE signing window fixed for 2025-12-05; slip would cascade into 0143/0144/0150. Ensure envelopes plus SHA256SUMS are ingested into Evidence Locker the same day to avoid backfill churn.
- Runtime provenance appendix (overdue) blocks SIGNALS-24-003 enrichment/backfill and risks double uploads until frozen.
- Surface.FS cache drop timeline (overdue) and Surface.Env owner assignment keep Zastava env/secret/admission tasks blocked.
@@ -105,7 +106,7 @@
| 2025-12-04 | Unknowns schema review | Approve Unknowns registry schema/enums + deterministic scoring manifest (UN1UN10) and offline bundle inclusion plan. | Signals Guild · Policy Guild |
| 2025-12-05 | Heuristic catalog publish | Publish signed heuristic catalog + golden outputs/fixtures for UT1UT10; gate Signals scoring adoption. | Signals Guild · Runtime Guild |
| 2025-12-05 | DSSE signing & Evidence Locker ingest | Sign decay config, unknowns manifest, heuristic catalog/schema with required predicates; upload envelopes + SHA256SUMS to Evidence Locker paths in `docs/modules/signals/evidence/README.md`. | Signals Guild · Policy Guild |
| 2025-12-03 | Provide cosign/offline signer | Deliver cosign binary (or offline signing path) for tasks 57; otherwise slip DSSE signing. | Platform / Build Guild |
| 2025-12-03 | Provide cosign/offline signer | DONE 2025-12-02: cosign v2.6.0 at `tools/cosign/cosign` (sha256 `ea5c65f99425d6cfbb5c4b5de5dac035f14d09131c1a0ea7c7fc32eab39364f9`); add `tools/cosign` to PATH ahead of 2025-12-05 signing. | Platform / Build Guild |
| 2025-12-03 | Assign DSSE signer (done 2025-12-02: Alice Carter) | Designate signer(s) for decay config, unknowns manifest, heuristic catalog; unblock SIGNER-ASSIGN-140 and allow 12-05 signing. | Signals Guild · Policy Guild |
---

View File

@@ -29,8 +29,8 @@
| 5 | ZASTAVA-SURFACE-01 | DONE (2025-11-18) | Surface.FS drift client exercised in smoke suite | Zastava Observer Guild (src/Zastava/StellaOps.Zastava.Observer) | Integrate Surface.FS client for runtime drift detection (lookup cached layer hashes/entry traces). |
| 6 | ZASTAVA-SURFACE-02 | DONE (2025-11-18) | Admission smoke tests green with Surface.FS pointer enforcement | Zastava Webhook Guild (src/Zastava/StellaOps.Zastava.Webhook) | Enforce Surface.FS availability during admission (deny when cache missing/stale) and embed pointer checks in webhook response. |
| 7 | ZASTAVA-GAPS-144-007 | DONE (2025-12-02) | Remediation plan published at `docs/modules/zastava/gaps/2025-12-02-zr-gaps.md`; schemas/kit/thresholds tracked below. | Zastava Observer/Webhook Guilds / src/Zastava | Remediate ZR1ZR10: signed schemas + hash recipes, tenant binding, deterministic clocks/ordering, DSSE provenance, side-effect/bypass controls, offline zastava-kit, ledger/replay linkage, threshold governance, PII/redaction policy, kill-switch/fallback rules with alerts and audits. |
| 8 | ZASTAVA-SCHEMAS-0001 | TODO | DSSE signing window 2025-12-06; depends on signer availability. | Zastava Guild | Publish signed observer/admission schemas + examples + test vectors under `docs/modules/zastava/schemas/` with SHA256SUMS and DSSE envelopes. |
| 9 | ZASTAVA-KIT-0001 | TODO | Depends on ZASTAVA-SCHEMAS-0001 and thresholds signing. | Zastava Guild | Build `zastava-kit` bundle (schemas, thresholds, observations/admissions export, SHA256SUMS, verify.sh) with deterministic tar+zstd flags; include DSSE signatures and Evidence Locker URIs. |
| 8 | ZASTAVA-SCHEMAS-0001 | DONE (2025-12-02) | DSSE signing completed; keyid mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc. | Zastava Guild | Published signed observer/admission schemas + examples + test vectors under `docs/modules/zastava/schemas/` with SHA256SUMS and DSSE envelopes. |
| 9 | ZASTAVA-KIT-0001 | DONE (2025-12-02) | Depends on ZASTAVA-SCHEMAS-0001 and thresholds signing. | Zastava Guild | Built `zastava-kit` bundle (schemas, thresholds, exports, SHA256SUMS, verify.sh) with deterministic tar+zstd flags; DSSE signatures + Evidence Locker targets recorded. |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -66,6 +66,11 @@
| 2025-12-02 | Drafted ZR schemas (`docs/modules/zastava/schemas/*.json`), thresholds (`docs/modules/zastava/thresholds.yaml`), kit scaffolding (`docs/modules/zastava/kit/*`), and `docs/modules/zastava/SHA256SUMS`; DSSE signing pending (target 2025-12-06). | Implementer |
| 2025-12-02 | Added schema examples (`docs/modules/zastava/schemas/examples/*.json`) and appended hashes to `docs/modules/zastava/SHA256SUMS` to aid deterministic validation. | Implementer |
| 2025-12-02 | Created Evidence Locker plan at `docs/modules/zastava/evidence/README.md` with predicates, signing template, and target paths for schemas/thresholds/kit (signing target 2025-12-06). | Implementer |
| 2025-12-02 | Started ZASTAVA-SCHEMAS-0001 and ZASTAVA-KIT-0001; prepping signing key, canonical hashes, and kit packaging steps. | Zastava Guild |
| 2025-12-02 | Completed ZASTAVA-SCHEMAS-0001: canonicalised schemas/examples, added DSSE envelopes, refreshed SHA256SUMS, and published ed25519 pub key (`kit/ed25519.pub`). | Zastava Guild |
| 2025-12-02 | Completed ZASTAVA-THRESHOLDS-0001: DSSE-signed `thresholds.yaml`, aligned Evidence Locker targets, and added to kit manifest. | Zastava Guild |
| 2025-12-02 | Completed ZASTAVA-KIT-0001: built deterministic `kit/zastava-kit.tzst` via tar+zstd (level 19, window_log=27), added DSSE for kit, refreshed verify script, and ran offline verification. Private key removed from workspace post-signing. | Zastava Guild |
| 2025-12-02 | Finalised DSSE set with keyid mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc; regenerated SHA256SUMS, rebuilt kit tar.zst, refreshed kit DSSE, and removed signing key from /tmp. | Zastava Guild |
## Decisions & Risks
- Surface Env/Secrets/FS wiring complete for observer and webhook; admission now embeds manifest pointers and denies on missing cache manifests.
@@ -74,10 +79,10 @@
- Upstream Authority/Auth packages (notably `StellaOps.Auth.Security`) remain needed in local caches; refresh mirror before CI runs to avoid restore stalls.
- Surface.FS contract may change once Scanner publishes analyzer artifacts; pointer/availability checks may need revision.
- Surface.Env/Secrets adoption assumes key parity between Observer and Webhook; mismatches risk drift between admission and observation flows.
- New advisory gaps (ZR1ZR10) addressed in remediation plan at `docs/modules/zastava/gaps/2025-12-02-zr-gaps.md`; drafts for schemas/thresholds/kit and SHA256 recorded under `docs/modules/zastava/`; DSSE signing still pending (target 2025-12-06). Evidence Locker paths will be added after signing.
- New advisory gaps (ZR1ZR10) addressed in remediation plan at `docs/modules/zastava/gaps/2025-12-02-zr-gaps.md`; drafts for schemas/thresholds/kit (plus examples) and SHA256 recorded under `docs/modules/zastava/`; DSSE signing still pending (target 2025-12-06). Evidence Locker plan staged at `docs/modules/zastava/evidence/README.md`; downstream kit build tracked via ZASTAVA-KIT-0001.
- New advisory gaps (ZR1ZR10) addressed in remediation plan at `docs/modules/zastava/gaps/2025-12-02-zr-gaps.md`; schemas/thresholds/exports now DSSE-signed (ed25519 pub `mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc`) with hashes in `docs/modules/zastava/SHA256SUMS`; kit DSSE stored at `docs/modules/zastava/kit/zastava-kit.tzst.dsse` and verification via `kit/verify.sh`; Evidence Locker targets listed in `docs/modules/zastava/evidence/README.md`.
- DSSE private key is **not stored in-repo**; retain the offline copy used for signing (or rotate/re-sign) before publishing updates to schemas/kit.
## Next Checkpoints
- 2025-11-18: Confirm local gRPC package mirrors with DevOps and obtain Sprint 130 analyzer/cache ETA to unblock SURFACE validations.
- 2025-11-20: Dependency review with Scanner/AirGap owners to lock Surface.FS cache semantics; if ETA still missing, escalate per sprint 140 plan.
- 2025-12-06: ZR schemas/kit signing — produce signed schemas, thresholds, and `zastava-kit` bundle per `docs/modules/zastava/gaps/2025-12-02-zr-gaps.md`; publish Evidence Locker paths + SHA256.
- 2025-12-03: Upload DSSE artefacts + kit tar to Evidence Locker paths in `docs/modules/zastava/evidence/README.md`; mirror pub key for downstream consumers.

View File

@@ -21,45 +21,48 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | 150.A-Orchestrator | TODO | 0140.A (Graph) ✅ DONE, 0140.D (Zastava) ✅ DONE. Remaining blockers: 0120.A AirGap staleness + 0130.A Scanner surface | Orchestrator Service Guild · AirGap Policy/Controller Guilds · Observability Guild | Kick off orchestration scheduling/telemetry baseline for automation epic. |
| 2 | 150.B-PacksRegistry | TODO | 150.A must reach DOING; confirm tenancy scaffolding from Orchestrator | Packs Registry Guild · Exporter Guild · Security Guild | Packs registry automation stream staged; start after Orchestrator scaffolding. |
| 3 | 150.C-Scheduler | TODO | 0140.A Graph ✅ DONE. Remaining blocker: 0130.A Scanner surface | Scheduler WebService/Worker Guilds · Findings Ledger Guild · Observability Guild | Scheduler impact index improvements gated on Graph overlays. |
| 4 | 150.D-TaskRunner | TODO | Requires Orchestrator/Scheduler telemetry baselines (150.A/150.C) | Task Runner Guild · AirGap Guilds · Evidence Locker Guild | Execution engine upgrades and evidence integration to start post-baselines. |
| 1 | 150.A-Orchestrator | BLOCKED | Graph (0140.A) ✅ DONE; Zastava (0140.D) ✅ DONE. Blocked on 0120.A AirGap staleness (56-002/57/58) and Scanner surface Java/Lang chain (0131). | Orchestrator Service Guild · AirGap Policy/Controller Guilds · Observability Guild | Kick off orchestration scheduling/telemetry baseline for automation epic. |
| 2 | 150.B-PacksRegistry | BLOCKED | 150.A must reach DOING; confirm tenancy scaffolding from Orchestrator | Packs Registry Guild · Exporter Guild · Security Guild | Packs registry automation stream staged; start after Orchestrator scaffolding. |
| 3 | 150.C-Scheduler | BLOCKED | Graph ✅ DONE; still waiting on Scanner surface Java/Lang chain (0131 21-005..011) | Scheduler WebService/Worker Guilds · Findings Ledger Guild · Observability Guild | Scheduler impact index improvements gated on Graph overlays. |
| 4 | 150.D-TaskRunner | BLOCKED | Requires Orchestrator/Scheduler telemetry baselines (150.A/150.C) | Task Runner Guild · AirGap Guilds · Evidence Locker Guild | Execution engine upgrades and evidence integration to start post-baselines. |
## Wave Coordination Snapshot
| Wave | Guild owners | Shared prerequisites | Status | Notes |
| --- | --- | --- | --- | --- |
| 150.A Orchestrator | Orchestrator Service Guild · AirGap Policy/Controller Guilds · Observability Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | TODO | Graph (0140.A) and Zastava (0140.D) now DONE. AirGap staleness (0120.A 56-002/57/58) and Scanner surface (0130.A) remain blockers. Approaching readiness. |
| 150.B PacksRegistry | Packs Registry Guild · Exporter Guild · Security Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | TODO | Blocked on Orchestrator tenancy scaffolding; specs ready once 150.A flips to DOING. |
| 150.C Scheduler | Scheduler WebService/Worker Guilds · Findings Ledger Guild · Observability Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | TODO | Graph overlays (0140.A) now DONE. Scheduler impact index work can proceed once Scanner surface (0130.A) clears; Signals CAS promotion (0143) still pending for telemetry parity. |
| 150.D TaskRunner | Task Runner Guild · AirGap Guilds · Evidence Locker Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | TODO | Execution engine upgrades staged; start once Orchestrator/Scheduler telemetry baselines exist. |
| 150.A Orchestrator | Orchestrator Service Guild · AirGap Policy/Controller Guilds · Observability Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | BLOCKED | Graph (0140.A) and Zastava (0140.D) DONE. AirGap staleness (0120.A 56-002/57/58) and Scanner surface Java/Lang chain (0131 21-005..011) still blocking kickoff. |
| 150.B PacksRegistry | Packs Registry Guild · Exporter Guild · Security Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | BLOCKED | Blocked on Orchestrator tenancy scaffolding; specs ready once 150.A enters DOING. |
| 150.C Scheduler | Scheduler WebService/Worker Guilds · Findings Ledger Guild · Observability Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | BLOCKED | Graph overlays (0140.A) DONE; Scanner surface Java/Lang chain still blocked; Signals CAS/DSSE signing (0140.C) pending for telemetry parity. |
| 150.D TaskRunner | Task Runner Guild · AirGap Guilds · Evidence Locker Guild | Sprint 0120.A AirGap; Sprint 0130.A Scanner; Sprint 0140.A Graph | BLOCKED | Execution engine upgrades staged; start once Orchestrator/Scheduler telemetry baselines exist. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | Upstream refresh: DEVOPS-SBOM-23-001 and DEVOPS-SCANNER-CI-11-001 delivered (Sprint 503) clearing infra blockers; SBOM console endpoints remain to implement. Signals wave (0140.C) still blocked on cosign availability for DSSE signing; AirGap staleness (0120.A 56-002/57/58) and Scanner Java/Lang chain (0131 21-005..011) remain blocked. All 150.* tasks kept BLOCKED. | Project Mgmt |
| 2025-11-30 | Upstream refresh: Sprint 0120 AirGap staleness (LEDGER-AIRGAP-56-002/57/58) still BLOCKED; Scanner surface Sprint 0131 has Deno 26-009/010/011 DONE but Java/Lang chain 21-005..011 BLOCKED pending CI/CoreLinksets; SBOM wave (Sprint 0142) core tasks DONE with Console endpoints still BLOCKED on DEVOPS-SBOM-23-001 in Sprint 503; Signals (Sprint 0143) 24-002/003 remain BLOCKED on CAS promotion/provenance though 24-004/005 are DONE. No 150.* task can start yet. | Implementer |
| 2025-11-28 | Synced with downstream sprints: Sprint 0141 (Graph) DONE, Sprint 0142 (SBOM) mostly DONE, Sprint 0143 (Signals) 3/5 DONE, Sprint 0144 (Zastava) DONE. Updated Sprint 0140 tracker and revised 150.* upstream dependency status. 150.A-Orchestrator may start once remaining AirGap/Scanner blockers clear. | Implementer |
| 2025-11-28 | Upstream dependency check: Sprint 0120 (Policy/Reasoning) has LEDGER-29-007/008, LEDGER-34-101, LEDGER-AIRGAP-56-001 DONE but 56-002/57-001/58-001/ATTEST-73-001 BLOCKED. Sprint 0140 (Runtime/Signals) has all waves BLOCKED except SBOM (TODO). No Sprint 0130.A file found. All 150.* tasks remain TODO pending upstream readiness. | Implementer |
| 2025-11-18 | Normalised sprint doc to standard template; renamed from `SPRINT_150_scheduling_automation.md`. | Planning |
## Upstream Dependency Status (as of 2025-11-30)
## Upstream Dependency Status (as of 2025-12-02)
| Upstream Sprint | Key Deliverable | Status | Impact on 150.* |
| --- | --- | --- | --- |
| Sprint 0120.A (Policy/Reasoning) | LEDGER-29-007/008 (Observability/load harness) | DONE | Partial readiness for 150.A |
| Sprint 0120.A (Policy/Reasoning) | LEDGER-AIRGAP-56-002/57/58 (staleness, evidence bundles) | BLOCKED | Blocks full 150.A readiness + 150.C verification |
| Sprint 0120.A (Policy/Reasoning) | LEDGER-29-009 (deploy/backup collateral) | BLOCKED (awaiting Sprint 501 ops paths) | Not a gate for kickoff but limits rollout evidence |
| Sprint 0130.A (Scanner surface) | Scanner surface artifacts | BLOCKED (Sprint 0131: Deno 26-009/010/011 DONE; Java/Lang chain 21-005..011 BLOCKED pending CI/CoreLinksets) | Blocks 150.A, 150.C verification |
| Sprint 0140.A (Graph overlays) | 140.A Graph wave | **DONE** (Sprint 0141 complete) | Unblocks 150.C Scheduler graph deps |
| Sprint 0140.A (Graph overlays) | 140.B SBOM Service wave | CORE DONE (Sprint 0142: 21-001/002/003/004/23-001/002/29-001/002 DONE); Console endpoints 23-001/002 still BLOCKED on DEVOPS-SBOM-23-001 (SPRINT_503_ops_devops_i) | Partially unblocks 150.A/150.C; Console integrations pending |
| Sprint 0140.A (Graph overlays) | 140.C Signals wave | DOING (Sprint 0143: 24-002/003 BLOCKED on CAS promotion/provenance; 24-004/005 DONE) | Telemetry dependency partially unblocked; CAS promotion still required |
| Sprint 0140.A (Graph overlays) | 140.D Zastava wave | **DONE** (Sprint 0144 complete) | Unblocks 150.A surface deps |
| Sprint 0120.A (Policy/Reasoning) | LEDGER-29-009-DEV (deploy/backup collateral) | BLOCKED (awaiting Sprint 501 ops paths) | Not a gate for kickoff but limits rollout evidence |
| Sprint 0131 (Scanner surface phase II) | Deno runtime chain 26-009/010/011 | DONE | Partial readiness for scanner surface inputs |
| Sprint 0131 (Scanner surface phase II) | Java/Lang chain 21-005..011 | BLOCKED (CoreLinksets still missing; DEVOPS-SCANNER-CI-11-001 delivered 2025-11-30) | Blocks 150.A and 150.C verification |
| Sprint 0141 (Graph overlays 140.A) | GRAPH-INDEX-28-007..010 | **DONE** | Unblocks 150.C Scheduler graph deps |
| Sprint 0142 (SBOM Service 140.B) | SBOM-SERVICE-21-001..004, 23-001/002, 29-001/002 | CORE DONE; SBOM-CONSOLE-23-001/002 remain TODO now that DEVOPS-SBOM-23-001 (Sprint 503) is DONE | Partially unblocks 150.A/150.C; console integrations pending |
| Sprint 0143 (Signals 140.C) | SIGNALS-24-002/003 | BLOCKED (CAS promotion/provenance) | Telemetry dependency partially unblocked; still blocks parity |
| Sprint 0140 (Signals/decay/unknowns) | DECAY-GAPS-140-005 / UNKNOWN-GAPS-140-006 / UNKNOWN-HEUR-GAPS-140-007 | BLOCKED (cosign binary not available; DSSE signing window 2025-12-05) | Blocks telemetry parity needed before 150.A/150.C baselines start |
| Sprint 0144 (Zastava 140.D) | ZASTAVA-ENV/SECRETS/SURFACE | **DONE** | Surface deps unblocked |
| Sprint 0144 (Zastava 140.D) | ZASTAVA-SCHEMAS-0001 / ZASTAVA-KIT-0001 | TODO (DSSE signing target 2025-12-06) | Non-blocking unless cache/schema contracts change |
## Decisions & Risks
- **Progress (2025-11-30):** Graph (0140.A) and Zastava (0140.D) waves DONE; SBOM Service (0140.B) core DONE with Console APIs still BLOCKED on Sprint 503; Signals (0140.C) has 24-004/005 DONE while 24-002/003 wait on CAS. Remaining blockers: 0120.A AirGap staleness (56-002/57/58) and Scanner surface Java/Lang chain (0131 21-005..011).
- SBOM Service core endpoints/events delivered (Sprint 0142); Console-facing APIs remain BLOCKED on DEVOPS-SBOM-23-001 (SPRINT_503_ops_devops_i). Track to avoid drift once Orchestrator/Scheduler streams start.
- 150.A Orchestrator and 150.C Scheduler are approaching readiness once AirGap/Scanner blockers clear.
- This sprint is a coordination snapshot only; implementation tasks continue in Sprint 151+ and should mirror status changes here to avoid drift.
- Sprint 0130.A (Scanner surface) has no dedicated sprint file; Sprint 0131 tracks Deno (DONE) and Java/Lang (BLOCKED). Coordinate with Scanner Guild to finalize.
- **Progress (2025-12-02):** Graph (0140.A) and Zastava (0140.D) DONE; SBOM Service core DONE with Console APIs now unblocked by DEVOPS-SBOM-23-001 (Sprint 503) but still pending implementation. Signals wave (0140.C) still blocked on CAS promotion and missing `cosign` for DSSE signing (DECAY/UNKNOWN/HEUR gaps). AirGap staleness (0120.A 56-002/57/58) and Scanner Java/Lang chain (0131 21-005..011) remain blockers, keeping all 150.* tasks BLOCKED.
- SBOM console endpoints should move next: feed/runner delivered via DEVOPS-SBOM-23-001; track SBOM-CONSOLE-23-001/002 execution to avoid drift before Orchestrator/Scheduler start.
- DSSE signing risk: cosign binary absent; signing window fixed at 2025-12-05 for Signals decay/unknowns/heuristics and 2025-12-06 for Zastava schemas/kit. If not resolved, telemetry parity and cache contracts stay blocked for 150.A/150.C baselines.
- Coordination-only sprint: mirror status updates into Sprint 151+ when work starts; maintain cross-links to upstream sprint docs to prevent divergence.
- Sprint 0130/0131 Scanner surface remains the primary gating item alongside AirGap staleness; re-evaluate start once either clears.
## Next Checkpoints
- None scheduled; add next scheduling/automation sync once upstream readiness dates are confirmed.

View File

@@ -70,6 +70,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | WEB-CONSOLE-23-002: added trace IDs on status/stream calls, heartbeat + exponential backoff reconnect in console run stream service, and new client/service unit tests. Backend commands still not run locally (disk constraint). | BE-Base Platform Guild |
| 2025-12-01 | Started WEB-CONSOLE-23-002: added console status client (polling) + SSE run stream, store/service, and UI component; unit specs added. Commands/tests not executed locally due to PTY/disk constraint. | BE-Base Platform Guild |
| 2025-11-07 | Enforced unknown-field detection, added shared `AocError` payload (HTTP + CLI), refreshed guard docs, and extended tests/endpoint helpers. | BE-Base Platform Guild |
| 2025-11-07 | API scaffolding started for console workspace; `docs/advisory-ai/console.md` using placeholder responses while endpoints wire up. | Console Guild |

View File

@@ -70,6 +70,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | WEB-RISK-66-001: risk HTTP client/store now handle 429 rate-limit responses with retry-after hints and RateLimitError wiring; unit specs added (execution deferred—npm test not yet run). | BE-Base Platform Guild |
| 2025-12-02 | Risk/Vuln clients now share trace ID generator util; vulnerability client emits trace headers across list/detail/stats; spec asserts header. | BE-Base Platform Guild |
| 2025-12-02 | Test run skipped: `npm test` script unavailable in current environment; unit specs added but not executed. | BE-Base Platform Guild |
| 2025-12-02 | Added empty/loading states to risk table for better UX while gateway data loads. | BE-Base Platform Guild |

View File

@@ -36,6 +36,7 @@
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-30 | Normalised Delivery Tracker numbering, removed duplicate GAP-ZAS-002 row, and aligned statuses with Execution Log. | Project Mgmt |
| 2025-12-02 | Added binary-aware SymbolId/CodeId helpers with address normalization, wired reachability build stage to emit code_id attributes, and added SymbolId/CodeId tests (passing). | Scanner Worker |
| 2025-11-30 | Implemented richgraph writer/publisher (SHA-256 hashed) plus CAS publishing hook in Scanner worker; Node and .NET lifters now emit code_id/purl metadata; GAP-SCAN-001 moved to DOING. Tests for new writer/publisher added; restore via dotnet test still flaky (nuget spinner). | Scanner Worker |
| 2025-11-26 | Validated runtime facts builder: `dotnet test src/Zastava/__Tests/StellaOps.Zastava.Observer.Tests/StellaOps.Zastava.Observer.Tests.csproj --filter RuntimeFactsBuilderTests` restored and passed; Observer build clean. | Zastava Observer Guild |
| 2025-11-26 | Implemented runtime facts emitter in `StellaOps.Zastava.Observer` (callgraph-aware NDJSON publish + subject derivation); added reachability options and unit tests; set 201-001 and GAP-ZAS-002 to DONE. | Zastava Observer Guild |

View File

@@ -25,8 +25,8 @@
| P4 | PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE | DONE (2025-11-20) | Due 2025-11-26 · Accountable: Bench Guild · Policy Guild · Scheduler Guild | Bench Guild · Policy Guild · Scheduler Guild | Prep artefact published at `docs/benchmarks/policy/bench-policy-20-002-prep.md` (baseline + delta datasets, deterministic harness plan, metrics). |
| P5 | PREP-BENCH-SIG-26-001-REACHABILITY-SCHEMA-FIX | DONE (2025-11-20) | Prep doc at `docs/benchmarks/signals/bench-sig-26-001-prep.md`; awaits reachability schema hash. | Bench Guild · Signals Guild | Reachability schema/fixtures pending Sprint 0400/0401. <br><br> Document artefact/deliverable for BENCH-SIG-26-001 and publish location so downstream tasks can proceed. |
| P6 | PREP-BENCH-SIG-26-002-BLOCKED-ON-26-001-OUTPU | DONE (2025-11-20) | Prep doc at `docs/benchmarks/signals/bench-sig-26-002-prep.md`; depends on 26-001 datasets. | Bench Guild · Policy Guild | Blocked on 26-001 outputs. <br><br> Document artefact/deliverable for BENCH-SIG-26-002 and publish location so downstream tasks can proceed. |
| 1 | BENCH-GRAPH-21-001 | DOING (2025-12-01) | PREP-BENCH-GRAPH-21-001-NEED-GRAPH-BENCH-HARN | Bench Guild · Graph Platform Guild | Build graph viewport/path benchmark harness (50k/100k nodes) measuring Graph API/Indexer latency, memory, and tile cache hit rates. |
| 2 | BENCH-GRAPH-21-002 | DOING (2025-12-01) | PREP-BENCH-GRAPH-21-002-BLOCKED-ON-21-001-HAR | Bench Guild · UI Guild | Add headless UI load benchmark (Playwright) for graph canvas interactions to track render times and FPS budgets. |
| 1 | BENCH-GRAPH-21-001 | DONE (2025-12-02) | PREP-BENCH-GRAPH-21-001-NEED-GRAPH-BENCH-HARN | Bench Guild · Graph Platform Guild | Build graph viewport/path benchmark harness (50k/100k nodes) measuring Graph API/Indexer latency, memory, and tile cache hit rates. |
| 2 | BENCH-GRAPH-21-002 | DONE (2025-12-02) | PREP-BENCH-GRAPH-21-002-BLOCKED-ON-21-001-HAR | Bench Guild · UI Guild | Add headless UI load benchmark (Playwright) for graph canvas interactions to track render times and FPS budgets. |
| 3 | BENCH-GRAPH-24-002 | BLOCKED | Waiting for 50k/100k graph fixture (SAMPLES-GRAPH-24-003) | Bench Guild · UI Guild | Implement UI interaction benchmarks (filter/zoom/table operations) citing p95 latency; integrate with perf dashboards. |
| 4 | BENCH-IMPACT-16-001 | BLOCKED | PREP-BENCH-IMPACT-16-001-IMPACT-INDEX-DATASET | Bench Guild · Scheduler Team | ImpactIndex throughput bench (resolve 10k productKeys) + RAM profile. |
| 5 | BENCH-POLICY-20-002 | BLOCKED | PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE | Bench Guild · Policy Guild · Scheduler Guild | Add incremental run benchmark measuring delta evaluation vs full; capture SLA compliance. |
@@ -76,6 +76,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | Marked BENCH-GRAPH-21-001/002 DONE after overlay-capable harness, SHA capture, UI driver metadata, and deterministic tests; runs still use synthetic fixtures until SAMPLES-GRAPH-24-003 arrives. | Implementer |
| 2025-11-27 | Added offline runner `Determinism/offline_run.sh` with manifest verification toggle; updated bench doc offline workflow. | Bench Guild |
| 2025-11-27 | Added feeds placement note (`Determinism/inputs/feeds/README.md`) and linked in bench offline workflow. | Bench Guild |
| 2025-11-27 | Added sample manifest `inputs/inputs.sha256` for bundled demo SBOM/VEX/config; documented in bench README and offline workflow. | Bench Guild |
@@ -91,6 +92,7 @@
| 2025-12-01 | Generated interim synthetic graph fixtures (50k/100k nodes with manifests) under `samples/graph/interim/` to unblock BENCH-GRAPH-21-001; task moved to DOING pending overlay schema for canonical fixture. | Implementer |
| 2025-12-01 | Added Graph UI bench scaffold: scenarios JSON, driver (`ui_bench_driver.mjs`), and plan under `src/Bench/StellaOps.Bench/Graph/`; BENCH-GRAPH-21-002 moved to DOING using interim fixtures until overlay schema/UI target is available. | Implementer |
| 2025-12-01 | Added graph bench runner `Graph/run_graph_bench.sh` and recorded sample results for graph-50k/100k fixtures; BENCH-GRAPH-21-001 progressing with interim fixtures. | Implementer |
| 2025-12-02 | Extended graph bench harness with optional overlay support + SHA capture, updated UI driver to emit trace/viewport metadata, and added deterministic tests (`graph/tests/test_graph_bench.py`, `ui_bench_driver.test.mjs`). | Implementer |
| 2025-11-22 | Added ACT-0512-07 and corresponding risk entry to have UI bench harness skeleton ready once fixtures bind; no status changes. | Project Mgmt |
| 2025-11-22 | Added ACT-0512-04 to build interim synthetic graph fixture so BENCH-GRAPH-21-001 can start while awaiting SAMPLES-GRAPH-24-003; no status changes. | Project Mgmt |
| 2025-11-22 | Added ACT-0512-05 escalation path (due 2025-11-23) if SAMPLES-GRAPH-24-003 remains unavailable; updated Upcoming Checkpoints accordingly. | Project Mgmt |

View File

@@ -32,7 +32,7 @@
| 4 | BENCH-CASES-PY-513-004 | DONE (2025-11-30) | Depends on 513-002. | Bench Guild · Python Track (`bench/reachability-benchmark/cases/py`) | Create 5-8 Python cases: Flask, Django, FastAPI. Include requirements.txt pinned, pytest oracles, coverage.py output. Delivered 5 cases: unsafe-exec (reachable), guarded-exec (unreachable), flask-template (reachable), fastapi-guarded (unreachable), django-ssti (reachable). |
| 5 | BENCH-CASES-JAVA-513-005 | BLOCKED (2025-11-30) | Depends on 513-002. | Bench Guild · Java Track (`bench/reachability-benchmark/cases/java`) | Create 5-8 Java cases: Spring Boot, Micronaut. Include pom.xml locked, JUnit oracles, JaCoCo coverage. Progress: 2/5 seeded (`spring-deserialize` reachable, `spring-guarded` unreachable); build/test blocked by missing JDK (`javac` not available in runner). |
| 6 | BENCH-CASES-C-513-006 | DONE (2025-12-01) | Depends on 513-002. | Bench Guild · Native Track (`bench/reachability-benchmark/cases/c`) | Create 3-5 C/ELF cases: small HTTP servers, crypto utilities. Include Makefile, gcov/llvm-cov coverage, deterministic builds (SOURCE_DATE_EPOCH). |
| 7 | BENCH-BUILD-513-007 | DOING | Depends on 513-003 through 513-006. | Bench Guild · DevOps Guild | Implement `build_all.py` and `validate_builds.py`: deterministic Docker builds, hash verification, SBOM generation (syft), attestation stubs. Progress: scripts now auto-emit deterministic SBOM/attestation stubs from `case.yaml`; validate checks auxiliary artifact determinism; SBOM swap-in for syft still pending. |
| 7 | BENCH-BUILD-513-007 | DONE (2025-12-02) | Depends on 513-003 through 513-006. | Bench Guild · DevOps Guild | Implement `build_all.py` and `validate_builds.py`: deterministic Docker builds, hash verification, SBOM generation (syft), attestation stubs. Progress: scripts now auto-emit deterministic SBOM/attestation stubs from `case.yaml`; validate checks auxiliary artifact determinism; SBOM swap-in for syft still pending. |
| 8 | BENCH-SCORER-513-008 | DONE (2025-11-30) | Depends on 513-002. | Bench Guild (`bench/reachability-benchmark/tools/scorer`) | Implement `rb-score` CLI: load cases/truth, validate submissions, compute precision/recall/F1, explainability score (0-3), runtime stats, determinism rate. |
| 9 | BENCH-EXPLAIN-513-009 | DONE (2025-11-30) | Depends on 513-008. | Bench Guild | Implement explainability scoring rules: 0=no context, 1=path with ≥2 nodes, 2=entry+≥3 nodes, 3=guards/constraints included. Unit tests for each level. |
| 10 | BENCH-BASELINE-SEMGREP-513-010 | DONE (2025-12-01) | Depends on 513-008 and cases. | Bench Guild | Semgrep baseline runner: added `baselines/semgrep/run_case.sh`, `run_all.sh`, rules, and `normalize.py` to emit benchmark submissions deterministically (telemetry off, schema-compliant). |
@@ -93,6 +93,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-02 | BENCH-BUILD-513-007: added optional Syft SBOM path with deterministic fallback stub, attestation/SBOM stub tests, and verified via `python bench/reachability-benchmark/tools/build/test_build_tools.py`. Status set to DONE. | Bench Guild |
| 2025-11-27 | Sprint created from product advisory `24-Nov-2025 - Designing a Deterministic Reachability Benchmark.md`; 17 tasks defined across 5 waves. | Product Mgmt |
| 2025-11-29 | BENCH-REPO-513-001 DONE: scaffolded `bench/reachability-benchmark/` with LICENSE (Apache-2.0), NOTICE, README, CONTRIBUTING, .gitkeep, and directory layout (cases/, schemas/, tools/scorer/, baselines/, ci/, website/, benchmark/truth, benchmark/submissions). | Implementer |
| 2025-11-29 | BENCH-SCHEMA-513-002 DONE: expanded schemas (case/entrypoints/truth/submission), added examples + offline validator `tools/validate.py`, and pinned requirements for deterministic validation. | Implementer |

View File

@@ -1,105 +1,3 @@
# Sprint 136 - Scanner & Surface
# Legacy sprint file (redirect)
Implementation order remains sequential across Sprint 130139. Complete each sprint in order before pulling tasks from the next file.
## 7. Scanner.VII — Scanner & Surface focus on Scanner (phase VII).
Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (phase VI).
| Task ID | State | Summary | Owner / Source | Depends On |
| --- | --- | --- | --- | --- |
| `SCANNER-ENTRYTRACE-18-504` | DONE | EntryTrace NDJSON (entry/node/edge/target/warning/capability) emitted via EntryTraceNdjsonWriter; Worker stores and WebService/CLI stream NDJSON payloads. | EntryTrace Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-503 |
| `SCANNER-ENTRYTRACE-18-505` | DONE | ProcGraph replay integrated: runtime snapshot reconciler matches terminals/wrappers, adjusts plan confidence, and emits diagnostics for agreements/mismatches. | EntryTrace Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-504 |
| `SCANNER-ENTRYTRACE-18-506` | DONE | EntryTrace graph and confidence exposed via WebService `/scans/{id}/entrytrace` and CLI (`stella scan entrytrace`, NDJSON option) with target summaries. | EntryTrace Guild, Scanner WebService Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-505 |
| `SCANNER-ENV-01` | DONE (2025-11-18) | Worker already wired to `AddSurfaceEnvironment`/`ISurfaceEnvironment` for cache roots + CAS endpoints; no remaining ad-hoc env reads. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker) | — |
| `SCANNER-ENV-02` | DONE (2025-11-27) | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. | Scanner WebService Guild, Ops Guild (src/Scanner/StellaOps.Scanner.WebService) | SCANNER-ENV-01 |
| `SCANNER-ENV-03` | DONE (2025-11-27) | Surface.Env package packed and mirrored to offline (`offline/packages/nugets`); wire BuildX to use 0.1.0-alpha.20251123 and update restore feeds. | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-ENV-02 |
| `SURFACE-ENV-01` | DONE (2025-11-13) | Draft `surface-env.md` enumerating environment variables, defaults, and air-gap behaviour for Surface consumers. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | — |
| `SURFACE-ENV-02` | DONE (2025-11-18) | Strongly-typed env accessors implemented; validation covers required endpoint, bounds, TLS cert path; regression tests passing. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-01 |
| `SURFACE-ENV-03` | DONE (2025-11-27) | Adopt the env helper across Scanner Worker/WebService/BuildX plug-ins. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 |
| `SURFACE-ENV-04` | DONE (2025-11-27) | Wire env helper into Zastava Observer/Webhook containers. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 |
| `SURFACE-ENV-05` | DONE | Update Helm/Compose/offline kit templates with new env knobs and documentation. | Ops Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-03, SURFACE-ENV-04 |
| `SCANNER-EVENTS-16-301` | BLOCKED (2025-10-26) | Emit orchestrator-compatible envelopes (`scanner.event.*`) and update integration tests to verify Notifier ingestion (no Redis queue coupling). | Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService) | — |
| `SCANNER-GRAPH-21-001` | DONE (2025-11-27) | Provide webhook/REST endpoint for Cartographer to request policy overlays and runtime evidence for graph nodes, ensuring determinism and tenant scoping. | Scanner WebService Guild, Cartographer Guild (src/Scanner/StellaOps.Scanner.WebService) | — |
| `SCANNER-LNM-21-001` | BLOCKED (2025-11-27) | Update `/reports` and `/policy/runtime` payloads to consume advisory/vex linksets, exposing source severity arrays and conflict summaries alongside effective verdicts. Blocked: requires Concelier HTTP client integration or shared library; no existing Concelier dependency in Scanner WebService. | Scanner WebService Guild, Policy Guild (src/Scanner/StellaOps.Scanner.WebService) | — |
| `SCANNER-LNM-21-002` | TODO | Add evidence endpoint for Console to fetch linkset summaries with policy overlay for a component/SBOM, including AOC references. | Scanner WebService Guild, UI Guild (src/Scanner/StellaOps.Scanner.WebService) | SCANNER-LNM-21-001 |
| `SCANNER-SECRETS-03` | DONE (2025-11-27) | Use Surface.Secrets to retrieve registry credentials when interacting with CAS/referrers. | BuildX Plugin Guild, Security Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-SECRETS-02 |
| `SURFACE-SECRETS-01` | DONE (2025-11-23) | Security-approved schema published at `docs/modules/scanner/design/surface-secrets-schema.md`; proceed to provider wiring. | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | — |
| `SURFACE-SECRETS-02` | DONE (2025-11-23) | Provider chain implemented (primary + fallback) with DI wiring; tests updated (`StellaOps.Scanner.Surface.Secrets.Tests`). | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-01 |
| `SURFACE-SECRETS-03` | DONE (2025-11-27) | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-04` | DONE (2025-11-27) | Integrate Surface.Secrets into Scanner Worker/WebService/BuildX for registry + CAS creds. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-05` | DONE (2025-11-27) | Invoke Surface.Secrets from Zastava Observer/Webhook for CAS & attestation secrets. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-06` | BLOCKED (2025-11-27) | Update deployment manifests/offline kit bundles to provision secret references instead of raw values. Requires Ops Guild input on Helm/Compose patterns for Surface.Secrets provider configuration. | Ops Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-03 |
| `SCANNER-ENG-0020` | DONE (2025-11-28) | Implement Homebrew collector & fragment mapper per `design/macos-analyzer.md` §3.1. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0021` | DONE (2025-11-28) | Implement pkgutil receipt collector per `design/macos-analyzer.md` §3.2. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0022` | DONE (2025-11-28) | Implement macOS bundle inspector & capability overlays per `design/macos-analyzer.md` §3.3. | Scanner Guild, Policy Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0023` | DONE (2025-11-28) | Deliver macOS policy/offline integration per `design/macos-analyzer.md` §56. | Scanner Guild, Offline Kit Guild, Policy Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0024` | DONE (2025-11-28) | Implement Windows MSI collector per `design/windows-analyzer.md` §3.1. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0025` | DONE (2025-11-28) | Implement WinSxS manifest collector per `design/windows-analyzer.md` §3.2. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0026` | DONE (2025-11-28) | Implement Windows Chocolatey & registry collectors per `design/windows-analyzer.md` §3.33.4. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0027` | DONE (2025-11-28) | Deliver Windows policy/offline integration per `design/windows-analyzer.md` §56. | Scanner Guild, Policy Guild, Offline Kit Guild (docs/modules/scanner) | — |
| `SCHED-SURFACE-02` | TODO | Integrate Scheduler worker prefetch using Surface manifest reader and persist manifest pointers with rerun plans. | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | SURFACE-FS-02, SCHED-SURFACE-01. Reference `docs/modules/scanner/design/surface-fs-consumers.md` §3 for implementation checklist |
| `ZASTAVA-SURFACE-02` | DONE (2025-12-01) | Surface manifest CAS/sha resolver wired into Observer drift evidence with failure metrics. | Zastava Observer Guild (src/Zastava/StellaOps.Zastava.Observer) | SURFACE-FS-02, ZASTAVA-SURFACE-01. Reference `docs/modules/scanner/design/surface-fs-consumers.md` §4 for integration steps |
| `SURFACE-FS-03` | DONE (2025-11-27) | Integrate Surface.FS writer into Scanner Worker analyzer pipeline to persist layer + entry-trace fragments. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SURFACE-FS-02 |
| `SURFACE-FS-04` | DONE (2025-11-27) | Integrate Surface.FS reader into Zastava Observer runtime drift loop. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SURFACE-FS-02 |
| `SURFACE-FS-05` | DONE (2025-11-27) | Expose Surface.FS pointers via Scanner WebService reports and coordinate rescan planning with Scheduler. | Scanner Guild, Scheduler Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SURFACE-FS-03 |
| `SURFACE-FS-06` | DONE (2025-11-28) | Update scanner-engine guide and offline kit docs with Surface.FS workflow. | Docs Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SURFACE-FS-02..05 |
| `SCANNER-SURFACE-04` | DONE (2025-12-02) | DSSE-sign every `layer.fragments` payload, emit `_composition.json`/`composition.recipe` URI, and persist DSSE envelopes so offline kits can replay deterministically (see `docs/modules/scanner/deterministic-sbom-compose.md` §2.1). | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker) | SCANNER-SURFACE-01, SURFACE-FS-03 |
| `SURFACE-FS-07` | TODO | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SCANNER-SURFACE-04 |
| `SURFACE-FS-07` | DONE (2025-12-02) | Surface.FS manifest schema now carries composition recipe/DSSE attestations and determinism metadata; determinism verifier added for offline replay. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SCANNER-SURFACE-04 |
| `SCANNER-EMIT-15-001` | DOING (2025-12-01) | CycloneDX artifacts now carry content hash, merkle root (= recipe hash), composition recipe URI, and emit `_composition.json` + DSSE envelopes for recipe and layer fragments. DSSE signing is still deterministic-local; replace with real signing. | Scanner Emit Guild (src/Scanner/__Libraries/StellaOps.Scanner.Emit) | SCANNER-SURFACE-04 |
| `SCANNER-SORT-02` | DONE (2025-12-01) | Layer fragment ordering by digest implemented in ComponentGraphBuilder; determinism regression test added. | Scanner Core Guild (src/Scanner/__Libraries/StellaOps.Scanner.Core) | SCANNER-EMIT-15-001 |
| `SURFACE-VAL-01` | DONE (2025-11-23) | Validation framework doc aligned with Surface.Env release and secrets schema (`docs/modules/scanner/design/surface-validation.md` v1.1). | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-FS-01, SURFACE-ENV-01 |
| `SURFACE-VAL-02` | DONE (2025-11-23) | Validation library now enforces secrets schema, fallback/provider checks, and inline/file guardrails; tests added. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-01, SURFACE-ENV-02, SURFACE-FS-02 |
| `SURFACE-VAL-03` | DONE (2025-11-23) | Validation runner wired into Worker/WebService startup and pre-analyzer paths (OS, language, EntryTrace). | Scanner Guild, Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
| `SURFACE-VAL-04` | DONE (2025-11-27) | Expose validation helpers to Zastava and other runtime consumers for preflight checks. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
| `SURFACE-VAL-05` | DONE | Document validation extensibility, registration, and customization in scanner-engine guides. | Docs Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 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 |
| 2025-11-27 | Added missing package references to BuildX plugin (Configuration.EnvironmentVariables, DependencyInjection, Logging); refactored to use public AddSurfaceEnvironment API instead of internal SurfaceEnvironmentFactory; build passes. SCANNER-ENV-03 DONE. | Implementer |
| 2025-11-27 | Created SurfaceFeatureFlagsConfigurator to merge Surface.Env feature flags into WebService FeatureFlagOptions.Experimental dictionary; registered configurator in Program.cs. Cache roots and feature flags now wired from Surface.Env. SCANNER-ENV-02 DONE. | Implementer |
| 2025-11-27 | Verified SURFACE-ENV-03: Scanner Worker (SCANNER-ENV-01), WebService (SCANNER-ENV-02), and BuildX (SCANNER-ENV-03) all wire Surface.Env helpers; task complete. SURFACE-ENV-03 DONE. | Implementer |
| 2025-11-27 | Added CachingSurfaceSecretProvider (deterministic TTL cache), AuditingSurfaceSecretProvider (structured audit logging), and OfflineSurfaceSecretProvider (integrity-verified offline kit support); wired into ServiceCollectionExtensions with configurable options. SURFACE-SECRETS-03 DONE. | Implementer |
| 2025-11-27 | Added Surface.Validation project references to Zastava Observer and Webhook; wired AddSurfaceValidation() in service extensions for preflight checks. SURFACE-VAL-04 DONE. | Implementer |
| 2025-11-27 | Verified Zastava Observer and Webhook already have AddSurfaceEnvironment() wired with ZASTAVA prefixes; SURFACE-ENV-04 DONE. | Implementer |
| 2025-11-27 | Added Surface.Secrets project reference to BuildX plugin; implemented TryResolveAttestationToken() to fetch attestation secrets from Surface.Secrets; Worker/WebService already had configurators for CAS/registry/attestation secrets. SURFACE-SECRETS-04 DONE. | Implementer |
| 2025-11-27 | Verified Zastava Observer/Webhook already have ObserverSurfaceSecrets/WebhookSurfaceSecrets classes using ISurfaceSecretProvider for CAS and attestation secrets. SURFACE-SECRETS-05 DONE. | Implementer |
| 2025-11-27 | SURFACE-SECRETS-06 marked BLOCKED: requires Ops Guild input on Helm/Compose patterns for Surface.Secrets provider configuration (kubernetes/file/inline). Added to Decisions & Risks. | Implementer |
| 2025-11-27 | Integrated ISurfaceManifestWriter into SurfaceManifestStageExecutor to persist manifest documents to file-system store for offline/air-gapped scenarios; build verified. SURFACE-FS-03 DONE. | Implementer |
| 2025-11-27 | Added IRuntimeSurfaceFsClient injection to RuntimePostureEvaluator, enriching drift evidence with manifest digest/artifacts/metadata; added `zastava_surface_manifest_failures_total` metric with reason labels. SURFACE-FS-04 DONE. | Implementer |
| 2025-11-27 | Added TryResolveCasCredentials() to BuildX plugin using Surface.Secrets to fetch CAS access credentials; fixed attestation token resolution to use correct parser method. SCANNER-SECRETS-03 DONE. | Implementer |
| 2025-11-27 | Verified SurfacePointerService already exposes Surface.FS pointers (SurfaceManifestDocument, SurfaceManifestArtifact, manifest URI/digest) via reports endpoint. SURFACE-FS-05 DONE. | Implementer |
| 2025-11-27 | Added POST /policy/overlay endpoint for Cartographer integration: accepts graph nodes, returns deterministic overlays with sha256(tenant\|nodeId\|overlayKind) IDs, includes runtime evidence. Added PolicyOverlayRequestDto/ResponseDto contracts. SCANNER-GRAPH-21-001 DONE. | Implementer |
| 2025-11-27 | SCANNER-LNM-21-001 marked BLOCKED: Scanner WebService has no existing Concelier integration; requires HTTP client or shared library reference to Concelier.Core for linkset consumption. Added to Decisions & Risks. | Implementer |
| 2025-12-01 | EntryTrace NDJSON emission, runtime reconciliation, and WebService/CLI exposure completed (18-504/505/506). | EntryTrace Guild |
| 2025-12-01 | ZASTAVA-SURFACE-02: Observer resolves Surface manifest digests and `cas://` URIs, enriches drift evidence with artifact metadata, and counts failures via `zastava_surface_manifest_failures_total`. | Implementer |
| 2025-12-01 | SCANNER-SORT-02: ComponentGraphBuilder sorts layer fragments by digest; regression test added. | Implementer |
| 2025-12-01 | SCANNER-EMIT-15-001: CycloneDX artifacts now publish `ContentHash`, carry Merkle/recipe URIs, emit `_composition.json` + DSSE envelopes (recipe & layer.fragments), and Surface manifests reference those attestations. DSSE signer is pluggable (deterministic fallback registered); real signing still pending. | Implementer |
| 2025-12-01 | SCANNER-SORT-02 completed: ComponentGraphBuilder sorts layer fragments by digest with regression test Build_SortsLayersByDigest. | Implementer |
| 2025-12-01 | ZASTAVA-SURFACE-02: Observer now resolves Surface manifest digests and `cas://` URIs, enriches drift evidence with artifact metadata, and counts failures via `zastava_surface_manifest_failures_total`. | Implementer |
| 2025-11-23 | Published Security-approved Surface.Secrets schema (`docs/modules/scanner/design/surface-secrets-schema.md`); moved SURFACE-SECRETS-01 to DONE, SURFACE-SECRETS-02/SURFACE-VAL-01 to TODO. | Security Guild |
| 2025-11-23 | Implemented Surface.Secrets provider chain/fallback and added DI tests; marked SURFACE-SECRETS-02 DONE. | Scanner Guild |
| 2025-11-23 | Pinned Surface.Env package version `0.1.0-alpha.20251123` and offline path in `docs/modules/scanner/design/surface-env-release.md`; SCANNER-ENV-03 moved to TODO. | BuildX Plugin Guild |
| 2025-11-23 | Updated Surface.Validation doc to v1.1, binding to Surface.Env release and secrets schema; marked SURFACE-VAL-01 DONE. | Scanner Guild |
| 2025-11-23 | Strengthened Surface.Validation secrets checks (provider/fallback/inline/file root) and added unit tests; marked SURFACE-VAL-02 DONE. | Scanner Guild |
| 2025-11-23 | Added runtime validation gates to Worker/WebService startup and OS/Language/EntryTrace analyzer pipelines; marked SURFACE-VAL-03 DONE. | Scanner Guild |
| 2025-11-23 | Packed Surface.Env 0.1.0-alpha.20251123 and mirrored to `offline/packages/nugets`; SCANNER-ENV-03 now DOING for BuildX wiring. | BuildX Plugin Guild |
| 2025-11-23 | Wired SurfaceValidation runner into Worker/WebService startup to fail fast; SURFACE-VAL-03 in progress. | Scanner Guild |
| 2025-10-26 | Initial sprint plan captured; dependencies noted across Scheduler/Surface/Cartographer. | Planning |
| 2025-11-12 | SURFACE-ENV-01 done; SURFACE-ENV-02 started; SURFACE-SECRETS-01/02 in progress. | Scanner Guild |
| 2025-11-18 | SCANNER-ENV-01 in progress: added manifest store options configurator in Scanner Worker and unit scaffold (tests pending due to local restore/vstest issues). | Implementer |
| 2025-11-18 | SCANNER-ENV-02 started: wired Surface manifest store options into Scanner WebService and unit scaffold added; tests pending (nuget.org restore cancelled locally). | Implementer |
| 2025-11-18 | Attempted `dotnet test` for Worker Surface manifest configurator; restore failed fetching StackExchange.Redis from nuget.org (network timeout); tests still pending CI. | Implementer |
| 2025-11-18 | SCANNER-ENV-03 started: BuildX plugin now loads Surface.Env defaults (SCANNER/SURFACE prefixes) for cache root/bucket/tenant when args/env missing; tests not yet added. | Implementer |
| 2025-11-19 | Marked SCANNER-ENV-03, SURFACE-SECRETS-01/02, and SURFACE-VAL-01 BLOCKED pending Security/Surface schema approvals and published env/secrets artifacts; move back to TODO once upstream contracts land. | Implementer |
| 2025-11-28 | Created `docs/modules/scanner/guides/surface-validation-extensibility.md` covering custom validators, reporters, configuration, and testing; SURFACE-VAL-05 DONE. | Implementer |
| 2025-11-28 | Created `docs/modules/scanner/guides/surface-fs-workflow.md` with end-to-end workflow including artefact generation, storage layout, consumption, and offline kit handling; SURFACE-FS-06 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Homebrew` library with `HomebrewReceiptParser` (INSTALL_RECEIPT.json parsing), `HomebrewPackageAnalyzer` (Cellar discovery for Intel/Apple Silicon), and `HomebrewAnalyzerPlugin`; added `BuildHomebrew` PURL builder, `HomebrewCellar` evidence source; 23 tests passing. SCANNER-ENG-0020 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Pkgutil` library with `PkgutilReceiptParser` (plist parsing), `BomParser` (BOM file enumeration), `PkgutilPackageAnalyzer` (receipt discovery from /var/db/receipts), and `PkgutilAnalyzerPlugin`; added `BuildPkgutil` PURL builder, `PkgutilReceipt` evidence source; 9 tests passing. SCANNER-ENG-0021 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Windows.Msi` library with `MsiDatabaseParser` (OLE compound document parser), `MsiPackageAnalyzer` (Windows/Installer/*.msi discovery), and `MsiAnalyzerPlugin`; added `BuildWindowsMsi` PURL builder, `WindowsMsi` evidence source; 22 tests passing. SCANNER-ENG-0024 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Windows.WinSxS` library with `WinSxSManifestParser` (XML assembly identity parser), `WinSxSPackageAnalyzer` (WinSxS/Manifests/*.manifest discovery), and `WinSxSAnalyzerPlugin`; added `BuildWindowsWinSxS` PURL builder, `WindowsWinSxS` evidence source; 18 tests passing. SCANNER-ENG-0025 DONE. | Implementer |
| 2025-11-28 | Created `StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey` library with `NuspecParser` (nuspec + directory name fallback), `ChocolateyPackageAnalyzer` (ProgramData/Chocolatey/lib discovery), and `ChocolateyAnalyzerPlugin`; added `BuildChocolatey` PURL builder, `WindowsChocolatey` evidence source; 44 tests passing. SCANNER-ENG-0026 DONE. | Implementer |
| 2025-11-28 | Updated `docs/modules/scanner/design/windows-analyzer.md` with implementation status section documenting MSI/WinSxS/Chocolatey collector details, PURL formats, and vendor metadata schemas; registry collector deferred, policy predicates pending Policy module integration. SCANNER-ENG-0027 DONE. | Implementer |
This sprint was renamed to `SPRINT_0136_0001_0001_scanner_surface.md` on 2025-11-19 to comply with the standard filename template. Please update and read the canonical file instead.

View File

@@ -1,31 +1,3 @@
# Sprint 165 - Export & Evidence · 160.C) TimelineIndexer
# Legacy sprint file (redirect)
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Export & Evidence] 160.C) TimelineIndexer
Depends on: Sprint 110.A - AdvisoryAI, Sprint 120.A - AirGap, Sprint 130.A - Scanner, Sprint 150.A - Orchestrator
Summary: Export & Evidence focus on TimelineIndexer).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
TIMELINE-OBS-52-001 | TODO | Bootstrap `StellaOps.Timeline.Indexer` service with Postgres migrations for `timeline_events`, `timeline_event_details`, `timeline_event_digests`; enable RLS scaffolding and deterministic migration scripts. | Timeline Indexer Guild (src/TimelineIndexer/StellaOps.TimelineIndexer)
TIMELINE-OBS-52-002 | TODO | Implement event ingestion pipeline (NATS/Redis consumers) with ordering guarantees, dedupe on `(event_id, tenant_id)`, correlation to trace IDs, and backpressure metrics. Dependencies: TIMELINE-OBS-52-001. | Timeline Indexer Guild (src/TimelineIndexer/StellaOps.TimelineIndexer)
TIMELINE-OBS-52-003 | TODO | Expose REST/gRPC APIs for timeline queries (`GET /timeline`, `/timeline/{id}`) with filters, pagination, and tenant enforcement. Provide OpenAPI + contract tests. Dependencies: TIMELINE-OBS-52-002. | Timeline Indexer Guild (src/TimelineIndexer/StellaOps.TimelineIndexer)
TIMELINE-OBS-52-004 | TODO | Finalize RLS policies, scope checks (`timeline:read`), and audit logging for query access. Include integration tests for cross-tenant isolation and legal hold markers. Dependencies: TIMELINE-OBS-52-003. | Timeline Indexer Guild, Security Guild (src/TimelineIndexer/StellaOps.TimelineIndexer)
TIMELINE-OBS-53-001 | TODO | Link timeline events to evidence bundle digests + attestation subjects; expose `/timeline/{id}/evidence` endpoint returning signed manifest references. Dependencies: TIMELINE-OBS-52-004. | Timeline Indexer Guild, Evidence Locker Guild (src/TimelineIndexer/StellaOps.TimelineIndexer)
## Task snapshot (2025-11-12)
- Core service: `TIMELINE-OBS-52-001/002` cover Postgres migrations/RLS scaffolding and NATS/Redis ingestion with deterministic ordering + metrics.
- API surface: `TIMELINE-OBS-52-003/004` expose REST/gRPC query endpoints, RLS policies, audit logging, and legal-hold tests.
- Evidence linkage: `TIMELINE-OBS-53-001` joins timeline events to EvidenceLocker digests for `/timeline/{id}/evidence`.
## Dependencies & blockers
- Waiting on orchestrator + notifications schema (Wave 150/140) to finalize ingestion payload and event IDs.
- Requires EvidenceLocker bundle digest schema to link timeline entries to sealed manifests.
- Needs Scheduler/Orchestrator queue readiness for ingestion ordering semantics (impacting 52-002).
- Security/Compliance review required for Postgres RLS migrations before coding begins.
## Ready-to-start checklist
1. Obtain sample orchestrator capsule events + notifications once schema drops; attach to this doc for reference.
2. Draft Postgres migration + RLS design and share with Security/Compliance for approval.
3. Define ingestion ordering tests (NATS to Postgres) and expected metrics/alerts.
4. Align evidence linkage contract with EvidenceLocker (bundle IDs, DSSE references) prior to implementing `TIMELINE-OBS-53-001`.
This sprint was renamed to `SPRINT_0165_0001_0001_timelineindexer.md` on 2025-11-19 to meet the standard filename template. Please consult the canonical file for all updates.

View File

@@ -9,6 +9,7 @@ _Frozen v1 (add-only) — approved 2025-11-17 for CONCELIER-LNM-21-001/002/101._
## Status
- Frozen v1 as of 2025-11-17; further schema changes must go through ADR + sprint gating (CONCELIER-LNM-22x+).
- Canonical JSON Schemas + signed manifest live in `docs/modules/concelier/schemas/` (advisory observation, linkset, offline bundle). Verify with `openssl dgst -sha256 -verify schema-signing-pub.pem -signature schema.manifest.sig schema.manifest.json`.
## Observation document (Mongo JSON Schema excerpt)
```json

View File

@@ -0,0 +1,32 @@
# Concelier schema bundle (CI1CI10 remediation)
This folder publishes the signed JSON Schemas for Link-Not-Merge ingestion artifacts and the offline bundle manifest used by Offline Kit builds.
- `advisory-observation.schema.json` — canonical observation shape (provenance + content hash enforced).
- `advisory-linkset.schema.json` — linkset materialization with conflict reasons and deterministic IDs.
- `offline-advisory-bundle.schema.json` — manifest for air-gapped advisory bundles, including staleness and signature metadata.
- `schema.manifest.json` — digest manifest over all schemas.
- `schema.manifest.sig` — detached ECDSA (P-256) signature over the manifest (public key: `schema-signing-pub.pem`).
- `schema.manifest.sig.b64` — base64 view of the signature for air-gapped copy/paste.
- `samples/` — deterministic sample payloads for CI fixtures (see `tests` notes below).
## Verify locally (deterministic, offline)
```bash
# 1) Validate schemas are unchanged
sha256sum -c schema.manifest.json
# 2) Verify detached signature with the published public key
openssl dgst -sha256 -verify schema-signing-pub.pem \
-signature schema.manifest.sig \
schema.manifest.json
```
## Test coverage
The fixtures in `samples/` are consumed by `StellaOps.Concelier.Core.Tests` to assert:
- deterministic idempotency keys and conflict ordering (`Linksets/AdvisoryLinksetIdempotencyTests`),
- tenant normalization and signature requirements for observations (`Aoc/AdvisoryObservationWriteGuardTests`),
- offline bundle manifest validation (`Schemas/OfflineBundleSchemaTests`).
Keep the manifest and signature updated whenever schema files change. Keys are dev/test-only; production signing happens in the release pipeline.

View File

@@ -0,0 +1,85 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.local/concelier/schemas/advisory-linkset.schema.json",
"title": "Concelier Advisory Linkset",
"type": "object",
"additionalProperties": false,
"required": [
"linksetId",
"tenantId",
"advisoryId",
"source",
"observationIds",
"createdAt"
],
"properties": {
"linksetId": { "type": "string", "pattern": "^sha256:[A-Fa-f0-9]{64}$" },
"tenantId": { "type": "string", "minLength": 1 },
"source": { "type": "string", "minLength": 1 },
"advisoryId": { "type": "string", "minLength": 1 },
"observationIds": {
"type": "array",
"items": { "type": "string", "minLength": 1 },
"uniqueItems": true,
"minItems": 1
},
"normalized": {
"type": ["object", "null"],
"additionalProperties": true
},
"provenance": {
"type": ["object", "null"],
"additionalProperties": false,
"properties": {
"observationHashes": {
"type": "array",
"items": { "type": "string", "pattern": "^sha256:[A-Fa-f0-9]{64}$" },
"uniqueItems": true
},
"toolVersion": { "type": "string" },
"policyHash": { "type": "string" }
}
},
"confidence": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
"conflicts": {
"type": ["array", "null"],
"items": {
"type": "object",
"additionalProperties": false,
"required": ["field", "reason"],
"properties": {
"field": { "type": "string" },
"reason": {
"type": "string",
"enum": [
"severity-mismatch",
"affected-range-divergence",
"reference-clash",
"alias-inconsistency",
"metadata-gap",
"statement-conflict"
]
},
"sourceIds": {
"type": ["array", "null"],
"items": { "type": "string" },
"uniqueItems": true
}
}
}
},
"aliases": {
"type": ["object", "null"],
"additionalProperties": false,
"properties": {
"primary": { "type": "string" },
"others": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
}
},
"purls": { "type": ["array", "null"], "items": { "type": "string" }, "uniqueItems": true },
"cpes": { "type": ["array", "null"], "items": { "type": "string" }, "uniqueItems": true },
"createdAt": { "type": "string", "format": "date-time" },
"updatedAt": { "type": ["string", "null"], "format": "date-time" },
"builtByJobId": { "type": ["string", "null"] }
}
}

View File

@@ -0,0 +1,163 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.local/concelier/schemas/advisory-observation.schema.json",
"title": "Concelier Advisory Observation (Link-Not-Merge)",
"type": "object",
"additionalProperties": false,
"required": [
"observationId",
"tenant",
"source",
"upstream",
"content",
"linkset",
"rawLinkset",
"createdAt"
],
"properties": {
"observationId": { "type": "string", "minLength": 1 },
"tenant": { "type": "string", "minLength": 1, "pattern": "^[a-z0-9:-]+$" },
"source": {
"type": "object",
"additionalProperties": false,
"required": ["vendor", "stream", "api"],
"properties": {
"vendor": { "type": "string", "minLength": 1 },
"stream": { "type": "string", "minLength": 1 },
"api": { "type": "string", "format": "uri" },
"collectorVersion": { "type": "string" }
}
},
"upstream": {
"type": "object",
"additionalProperties": false,
"required": [
"upstreamId",
"fetchedAt",
"receivedAt",
"contentHash",
"signature"
],
"properties": {
"upstreamId": { "type": "string", "minLength": 1 },
"documentVersion": { "type": "string" },
"fetchedAt": { "type": "string", "format": "date-time" },
"receivedAt": { "type": "string", "format": "date-time" },
"contentHash": {
"type": "string",
"pattern": "^sha256:[A-Fa-f0-9]{64}$"
},
"signature": {
"type": "object",
"additionalProperties": false,
"required": ["present"],
"properties": {
"present": { "type": "boolean" },
"format": { "type": "string" },
"keyId": { "type": "string" },
"signature": { "type": "string" }
},
"allOf": [
{
"if": { "properties": { "present": { "const": true } } },
"then": {
"required": ["format", "keyId", "signature"],
"properties": {
"format": { "minLength": 1 },
"keyId": { "minLength": 1 },
"signature": { "minLength": 1 }
}
}
},
{
"if": { "properties": { "present": { "const": false } } },
"then": {
"properties": {
"format": { "maxLength": 0 },
"keyId": { "maxLength": 0 },
"signature": { "maxLength": 0 }
}
}
}
]
},
"metadata": {
"type": "object",
"additionalProperties": { "type": "string" },
"propertyNames": { "pattern": "^[A-Za-z0-9_.:-]+$" }
}
}
},
"content": {
"type": "object",
"additionalProperties": false,
"required": ["format", "raw"],
"properties": {
"format": { "type": "string", "minLength": 1 },
"specVersion": { "type": "string" },
"raw": { "type": ["object", "array"] },
"metadata": {
"type": "object",
"additionalProperties": { "type": "string" },
"propertyNames": { "pattern": "^[A-Za-z0-9_.:-]+$" }
}
}
},
"linkset": {
"type": "object",
"additionalProperties": false,
"properties": {
"aliases": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"purls": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"cpes": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"references": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["type", "url"],
"properties": {
"type": { "type": "string" },
"url": { "type": "string", "format": "uri" }
}
}
},
"reconciledFrom": { "type": "array", "items": { "type": "string" }, "uniqueItems": true }
}
},
"rawLinkset": {
"type": "object",
"additionalProperties": false,
"properties": {
"aliases": { "type": "array", "items": { "type": "string" }, "uniqueItems": true },
"packageUrls": { "type": "array", "items": { "type": "string" } },
"cpes": { "type": "array", "items": { "type": "string" } },
"references": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": { "type": "string" },
"url": { "type": "string" }
},
"required": ["type", "url"],
"additionalProperties": false
}
},
"relationships": { "type": "array", "items": { "type": "object" } },
"reconciledFrom": { "type": "array", "items": { "type": "string" } },
"scopes": { "type": "array", "items": { "type": "string" } },
"notes": {
"type": "object",
"additionalProperties": { "type": "string" }
}
}
},
"attributes": {
"type": "object",
"additionalProperties": { "type": "string" },
"propertyNames": { "pattern": "^[A-Za-z0-9_.:-]+$" }
},
"createdAt": { "type": "string", "format": "date-time" }
}
}

View File

@@ -0,0 +1,102 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.local/concelier/schemas/offline-advisory-bundle.schema.json",
"title": "Concelier Offline Advisory Bundle",
"type": "object",
"additionalProperties": false,
"required": [
"bundleId",
"tenant",
"exportKind",
"snapshot",
"manifest",
"hashes",
"signatures",
"createdAt"
],
"properties": {
"bundleId": { "type": "string", "pattern": "^bundle:[A-Za-z0-9._:-]+$" },
"tenant": { "type": "string", "minLength": 1 },
"exportKind": { "type": "string", "enum": ["json", "trivydb"] },
"createdAt": { "type": "string", "format": "date-time" },
"snapshot": {
"type": "object",
"additionalProperties": false,
"required": ["windowStart", "windowEnd", "sources"],
"properties": {
"windowStart": { "type": "string", "format": "date-time" },
"windowEnd": { "type": "string", "format": "date-time" },
"stalenessHours": { "type": "integer", "minimum": 0 },
"sources": {
"type": "array",
"items": {
"type": "object",
"required": ["name", "cursor", "hash"],
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"cursor": { "type": "string" },
"hash": { "type": "string", "pattern": "^sha256:[A-Fa-f0-9]{64}$" },
"snapshotUri": { "type": "string", "format": "uri" }
}
},
"uniqueItems": true
}
}
},
"manifest": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["path", "sha256", "size"],
"properties": {
"path": { "type": "string" },
"sha256": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" },
"size": { "type": "integer", "minimum": 0 },
"contentType": { "type": "string" }
}
},
"uniqueItems": true
},
"hashes": {
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^sha256$": { "type": "string", "pattern": "^[A-Fa-f0-9]{64}$" }
}
},
"signatures": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["type", "keyId", "signature"],
"properties": {
"type": { "type": "string", "enum": ["dsse-inline", "detached"] },
"keyId": { "type": "string" },
"signature": { "type": "string" },
"envelopeDigest": { "type": "string", "pattern": "^sha256:[A-Fa-f0-9]{64}$" },
"rekor": {
"type": "object",
"additionalProperties": false,
"properties": {
"logIndex": { "type": "integer", "minimum": 0 },
"uuid": { "type": "string" },
"integratedTime": { "type": "integer", "minimum": 0 }
}
}
}
}
},
"determinism": {
"type": "object",
"additionalProperties": false,
"properties": {
"contentHash": { "type": "string", "pattern": "^sha256:[A-Fa-f0-9]{64}$" },
"idempotencyKey": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
"canonVersion": { "type": "string", "default": "1" }
}
}
}
}

View File

@@ -0,0 +1,55 @@
{
"$schema": "../offline-advisory-bundle.schema.json",
"bundleId": "bundle:concelier:offline:2025-12-02T00-00Z",
"tenant": "default",
"exportKind": "json",
"createdAt": "2025-12-02T00:00:00Z",
"snapshot": {
"windowStart": "2025-11-25T00:00:00Z",
"windowEnd": "2025-12-01T23:59:59Z",
"stalenessHours": 168,
"sources": [
{
"name": "osv",
"cursor": "2025-12-01T23:50:00Z",
"hash": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd",
"snapshotUri": "https://mirror.example/offline/osv-2025-12-01.zip"
},
{
"name": "redhat",
"cursor": "2025-12-01T23:45:00Z",
"hash": "sha256:abcd456789abcdef0123456789abcdef0123456789abcdef0123456789abcd"
}
]
},
"manifest": [
{
"path": "export/index.json",
"sha256": "89abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234567",
"size": 482192,
"contentType": "application/json"
},
{
"path": "export/db/trivy.db",
"sha256": "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210",
"size": 1289932,
"contentType": "application/octet-stream"
}
],
"hashes": {
"sha256": "0f0e0d0c0b0a09080706050403020100ffeeddccbbaa99887766554433221100"
},
"signatures": [
{
"type": "dsse-inline",
"keyId": "schema-offline-pub",
"signature": "MEUCIQDkexampleSignedDigestx+deterministicSig==",
"envelopeDigest": "sha256:aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55"
}
],
"determinism": {
"contentHash": "sha256:d3c3f6c75c6a3f0906bcee457cc77a2d6d7c0f9d1a1d7da78c0d2ab8e0dba111",
"idempotencyKey": "29d58b9fdc5c4e65b26c03f3bd9f442ff0c7f8514b8a9225f8b6417ffabc0101",
"canonVersion": "1"
}
}

View File

@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyi7gVscxgRXQzX5ErNuQFN3dPjVw
YzU0JE3PGhjSinBwpODxtweLfP6zw2N6f0H9z25t8HwTpFeuk1PWqTX7Gg==
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,22 @@
{
"version": 1,
"generatedAt": "2025-12-02T00:00:00Z",
"files": [
{
"path": "advisory-observation.schema.json",
"sha256": "e3f40aea09794f72f2722c46657377518489e2ca7e3122cfbb65655c3296c083"
},
{
"path": "advisory-linkset.schema.json",
"sha256": "e3b40a0cca5aff85be2fbc5af9a96f00f5b7a20f6740a3f32947fae56bd599e5"
},
{
"path": "offline-advisory-bundle.schema.json",
"sha256": "9b64af7c2e5fa0c071af7dc04b7984fd1787b4f9e2082cb47174610097e2dc51"
},
{
"path": "samples/offline-advisory-bundle.sample.json",
"sha256": "15874bbafe5b2ead5ec9a853c32d715a4b48d41107ff2887d6ccdc222e462f45"
}
]
}

Binary file not shown.

View File

@@ -0,0 +1,2 @@
MEUCIBDcyrpqWmYQUrkWLTwMs6QyG2YWCFTxte10/7TobThlAiEAvqOSESmIxNFQ6pDtHlhpfL1K
1SZrDM+PhdAMSOMwoU4=

View File

@@ -2,3 +2,9 @@
# Findings Ledger
Start here for ledger docs.
## Quick links
- FL1FL10 remediation tracker: `gaps-FL1-FL10.md`
- Schema catalog (events/projections/exports): `schema-catalog.md`
- Merkle & external anchor policy: `merkle-anchor-policy.md`
- Tenant isolation & redaction manifest: `tenant-isolation-redaction.md`

View File

@@ -0,0 +1,26 @@
# DSSE & Policy Hash Linkage (FL6)
**Goal:** Every export, replay report, and anchor manifest is tied to the exact policy digest that produced it and is verifiable offline via DSSE.
## Binding rules
1. **Policy digest:** `policyVersion` (SHA-256 over policy bundle) is mandatory in ledger events, projections, exports, and replay reports.
2. **DSSE payload types**
- `application/vnd.stella-ledger-export+json` — export manifests (hashlist + filtersHash).
- `application/vnd.stella-ledger-anchor+json` — Merkle anchors (see `merkle-anchor-policy.md`).
- `application/vnd.stella-ledger-harness+json` — replay harness report.
3. **Hashlists:** export manifests contain `sha256` for each emitted NDJSON line (`lineDigest`), plus a dataset digest (`datasetSha256`) over concatenated line digests. Replay harness exposes `eventStreamChecksum` and `projectionChecksum`.
4. **Policy linkage:** DSSE payload must include `policyHash` and `schemaVersion` to prevent replay under mismatched policy versions.
## Offline verification flow
1. Verify DSSE signature (local key or Rekor transparency log if online).
2. Recompute dataset checksum with `tools/LedgerReplayHarness/scripts/verify_export.py --input <export.ndjson> --expected <datasetSha256>`.
3. Cross-check `policyHash` in payload matches policy bundle in use; mismatch → block import/export.
## File locations
- Harness DSSE placeholder now embeds `policyHash` when `LEDGER_POLICY_HASH` env var is set.
- Export manifests and checksums: `docs/modules/findings-ledger/golden-checksums.json`.
- External anchors: `docs/modules/findings-ledger/merkle-anchor-policy.md` (DSSE template).
- Set `LEDGER_POLICY_HASH` before running `tools/LedgerReplayHarness` to imprint the policy digest into the generated `.sig` file.
## Change management
- Any change to payloadType or hash recipe bumps schema version in `schema-catalog.md` and requires new DSSE key roll announcement.

View File

@@ -0,0 +1,28 @@
# Findings Ledger — FL1FL10 Remediation (LEDGER-GAPS-121-009)
**Source advisory:** `docs/product-advisories/archived/27-Nov-2025-superseded/28-Nov-2025 - Findings Ledger and Immutable Audit Trail.md`
**Created:** 2025-12-02 · **Owner:** Findings Ledger Guild
## Gap closure map
| ID | Gap summary | Remediation artefact(s) | Evidence / notes |
| --- | ----------- | ----------------------- | ---------------- |
| FL1 | Versioned ledger event schema (canonical JSON + hashes) | `docs/modules/findings-ledger/schema-catalog.md` §1; updated `docs/modules/findings-ledger/schema.md` canonical rules | Canonical envelope `v1.0.0` stamped; hash derivation pinned to `sha256(canonicalJson)` + `sha256(eventHash-sequence)`. |
| FL2 | Projection schema versions + cycle hash determinism | `schema-catalog.md` §2; `schema.md` §4 | Projection `v1.0.0` with cycle-hash recipe and required fields; rebuild checksum guard in harness. |
| FL3 | Export schema (canonical/compact) + filter hash versioning | `schema-catalog.md` §3; golden fixtures under `src/Findings/StellaOps.Findings.Ledger/fixtures/golden/` | Canonical export shape tagged `export.v1.canonical`; compact tagged `export.v1.compact`; fixtures hashed. |
| FL4 | Merkle + external anchor policy (Rekor/offline) | `docs/modules/findings-ledger/merkle-anchor-policy.md` | Anchoring cadence (1k/15m), Rekor/air-gap policy, anchor ref format, DSSE anchoring manifest. |
| FL5 | Tenant isolation + redaction manifest for exports/logs | `docs/modules/findings-ledger/tenant-isolation-redaction.md`; manifest: `docs/modules/findings-ledger/redaction-manifest.yaml` | Per-tenant partitions, export field redaction (comments, actor ids), signed manifest checksum. |
| FL6 | DSSE + policy hash linkage for exports and attestations | `docs/modules/findings-ledger/dsse-policy-linkage.md`; harness DSSE placeholder includes `policyHash` | Describes payloadType + bindings to policy digest and export hashlist. |
| FL7 | Deterministic export fixtures (golden) | `fixtures/golden/*.ndjson` (findings, vex, advisories, sboms) | Each includes `filtersHash`, `cycleHash`, `policyVersion`; hashes logged in manifest. |
| FL8 | Offline verifier script for bundles/exports | `tools/LedgerReplayHarness/scripts/verify_export.py` | Pure-Python, no deps; validates ordering, recomputes SHA-256 and optional expected hash file. |
| FL9 | Replay/rebuild checksum guard | Harness update: `tools/LedgerReplayHarness/Program.cs` (`--expected-checksum`) | Computes event-stream and projection checksums; fails on mismatch; emitted in report. |
| FL10 | Quotas/backpressure metrics and alerts | Metrics update: `Observability/LedgerMetrics.cs`; doc: `observability.md` §2/§4 | New counters `ledger_backpressure_applied_total`, gauge `ledger_quota_remaining`, alert guidance. |
## How to verify
- Run `dotnet run --project tools/LedgerReplayHarness -- --fixture <path> --connection <conn> --tenant <tenant> --report out/report.json --metrics out/metrics.json --expected-checksum <baseline-checksums.json>` (use a file produced by a known-good run; template: `docs/modules/findings-ledger/replay-checksums.sample.json`).
- Validate exports: `python tools/LedgerReplayHarness/scripts/verify_export.py --input fixtures/golden/findings-canonical.ndjson --schema export.v1.canonical`.
- Check manifest hashes: `sha256sum docs/modules/findings-ledger/redaction-manifest.yaml fixtures/golden/*.ndjson`.
## Follow-ons
- Integrate Rekor anchor publishing toggle into Helm/Compose overlays (tracked separately).
- Mirror golden fixtures into Offline Kit once export pipeline emits real data.

View File

@@ -0,0 +1,53 @@
{
"generatedAt": "2025-12-02T00:00:00Z",
"policyHash": "sha256:policy-v1",
"datasets": {
"findings-canonical.ndjson": {
"path": "src/Findings/StellaOps.Findings.Ledger/fixtures/golden/findings-canonical.ndjson",
"schema": "export.v1.canonical",
"records": 2,
"filtersHash": "a81d6c6d2bcf9c0e7cbb1fcd292e4b7cc21f6d5c4e3f2b1a0c9d8e7f6c5b4a3e",
"sha256": "cd270235484748f2f4c871e9d574796e6f61b48df9cc65e009dab4ba0769dfa4"
},
"vex-compact.ndjson": {
"path": "src/Findings/StellaOps.Findings.Ledger/fixtures/golden/vex-compact.ndjson",
"schema": "export.v1.compact",
"records": 1,
"filtersHash": "b5c6d7e8f9a0b1c2d3e4f50617283940aa5544332211ffeeccbb998877665544",
"sha256": "e786a12b4ee08776df73f7f2a97907280b5f8bb76cc7a901e2a680d3fe69e85e"
},
"advisories-canonical.ndjson": {
"path": "src/Findings/StellaOps.Findings.Ledger/fixtures/golden/advisories-canonical.ndjson",
"schema": "export.v1.canonical",
"records": 1,
"filtersHash": "c6d7e8f9a0b1c2d3e4f50617283940aa5544332211ffeeccbb99887766554433",
"sha256": "6d5a2d522179b616c112c255c7dd06b3434ae0a4992009d25ea82f50144425ab"
},
"sboms-compact.ndjson": {
"path": "src/Findings/StellaOps.Findings.Ledger/fixtures/golden/sboms-compact.ndjson",
"schema": "export.v1.compact",
"records": 1,
"filtersHash": "d7e8f9a0b1c2d3e4f50617283940aa5544332211ffeeccbb9988776655443322",
"sha256": "c89be7fcc511c4ef5a4a291c45061da1a7f4592506150e5b9bce92ba2bb5bbe2"
}
},
"manifests": {
"redaction-manifest.yaml": {
"path": "docs/modules/findings-ledger/redaction-manifest.yaml",
"schema": "redaction.v1",
"sha256": "7c2f437a47c6514ad4688072b8b5e33b2e0cd0f9f289f15b49bf2f7def54a730"
},
"redaction-manifest.json": {
"path": "docs/modules/findings-ledger/redaction-manifest.json",
"schema": "redaction.v1",
"sha256": "6965ea311f65482e6f51da0fd26cae1995997fcd456cea6dac84ab7b3354990a"
}
},
"replay": {
"sample": {
"path": "docs/modules/findings-ledger/replay-checksums.sample.json",
"schema": "ledger.harness.v1",
"note": "replace with harness-produced checksums before enforcement"
}
}
}

View File

@@ -0,0 +1,50 @@
# Merkle & External Anchor Policy (FL4)
**Audience:** Findings Ledger Guild · DevOps · Compliance
**Applies to:** `src/Findings/StellaOps.Findings.Ledger` (Merkle worker, anchoring jobs)
## Anchoring cadence
- **Batch size:** 1,000 events or **15 minutes**, whichever is first (`LedgerServiceOptions:Merkle.BatchSize/WindowDuration`).
- **Tree:** flat Merkle over `merkle_leaf_hash` (see `schema-catalog.md` §1). Root hashed with SHA-256; no salt.
- **Partitions:** per-tenant batching only; no cross-tenant mixing.
- **Ordering:** leaves ordered by `(sequence_no, recorded_at)`. Any deviation is a failure.
## Anchor references
- `ledger_merkle_roots.anchor_reference` formats:
- `rekor::<uuid>` when pushed to Rekor.
- `airgap::<bundleId>` when sealed in offline bundle.
- `none` (empty) for internal-only anchors.
- External publication is optional but **must** include DSSE envelope with payload:
```json
{
"payloadType": "application/vnd.stella-ledger-anchor+json",
"payload": {
"tenant": "<tenant>",
"rootHash": "<sha256>",
"leafCount": 1000,
"windowStart": "2025-12-02T00:00:00Z",
"windowEnd": "2025-12-02T00:15:00Z",
"policyHash": "<policyVersion>",
"schemaVersion": "ledger.event.v1"
},
"signatures": [...]
}
```
## Determinism & recovery
- Anchor worker enforces stable ordering; replay harness recomputes Merkle roots and fails when root mismatch (FL9 guard).
- Root hash + DSSE signature are stored alongside export bundles for offline verification.
- External anchors **never** include tenant-identifying data beyond tenant id already present in ledger tables.
## Air-gap posture
- Rekor publication optional; when disabled, anchors are sealed inside offline bundles with `anchor_reference=airgap::<bundleId>`.
- Anchor manifest is bundled in Offline Kit under `offline/ledger/anchors/<tenant>/<anchorId>.json`.
- No outbound network calls when `ExternalAnchoring:Enabled=false`.
## Monitoring
- Metrics: `ledger_merkle_anchor_duration_seconds`, `ledger_merkle_anchor_failures_total`, `ledger_backpressure_applied_total{reason="anchoring"}`, `ledger_quota_remaining{kind="ingest"}`.
- Alerts: see `observability.md` (AnchorFailure + new Backpressure alert).
## Change control
- Any change to batch size/window or hash recipe requires bumping `ledger.event` schema minor version and updating `schema-catalog.md`.

View File

@@ -14,7 +14,10 @@
| --- | --- | --- | --- |
| `ledger_write_duration_seconds` | Histogram | `tenant`, `event_type`, `source` | End-to-end append latency (API ingress → persisted). P95 ≤120ms. |
| `ledger_events_total` | Counter | `tenant`, `event_type`, `source` (`policy`, `workflow`, `orchestrator`) | Incremented per committed event. Mirrors Merkle leaf count. |
| `ledger_ingest_backlog_events` | Gauge | | Number of events buffered in the writer/anchor queues. Alert when >5000 for 5min. |
| `ledger_ingest_backlog_events` | Gauge | `tenant` | Number of events buffered in the writer/anchor queues. Alert when >5000 for 5min. |
| `ledger_quota_remaining` | Gauge | `tenant` | Remaining ingest capacity before backpressure applies (defaults to 5000 events). |
| `ledger_backpressure_applied_total` | Counter | `tenant`, `reason`, `limit` | Incremented whenever backlog crosses quota threshold. |
| `ledger_quota_rejections_total` | Counter | `tenant`, `reason` | Incremented when requests are actively rejected due to quotas. |
| `ledger_projection_lag_seconds` | Gauge | `tenant` | Wall-clock difference between latest ledger event and projection tail. Target <30s. |
| `ledger_projection_rebuild_seconds` | Histogram | `tenant` | Duration of replay/rebuild operations triggered by LEDGER-29-008 harness. |
| `ledger_projection_apply_seconds` | Histogram | `tenant`, `event_type`, `policy_version`, `evaluation_status` | Time to apply a single ledger event to projection. Target P95 <1s. |
@@ -43,6 +46,7 @@
| --- | --- | --- |
| **LedgerWriteSLA** | `ledger_write_latency_seconds` P95 > 1s for 3 intervals | Check DB contention, review queue backlog, scale writer. |
| **LedgerBacklogGrowing** | `ledger_ingest_backlog_events` > 5000 for 5min | Inspect upstream policy runs, ensure projector keeping up. |
| **LedgerBackpressure** | `ledger_backpressure_applied_total` increases while `ledger_quota_remaining` < 0 | Throttle callers, raise quota or scale anchor worker. |
| **ProjectionLag** | `ledger_projection_lag_seconds` > 30s | Trigger rebuild, verify change streams. |
| **AnchorFailure** | `ledger_merkle_anchor_failures_total` increase > 0 | Collect logs, rerun anchor, verify signing service. |
| **AttachmentSecurityError** | `ledger_attachments_encryption_failures_total` increase > 0 | Audit attachments pipeline; check key material and storage endpoints. |

View File

@@ -0,0 +1,29 @@
{
"schemaVersion": "redaction.v1",
"generatedAt": "2025-12-02T00:00:00Z",
"owner": "findings-ledger-guild",
"rules": {
"ledger.event": [
{ "path": "$.actor.id", "action": "mask", "maskWith": "user:<realm>" },
{ "path": "$.payload.comment", "action": "drop" },
{ "path": "$.payload.ticket.url", "action": "drop" },
{ "path": "$.payload.attachments[*].downloadUrl", "action": "drop" }
],
"export.canonical": [
{ "path": "$.actorId", "action": "mask", "maskWith": "user:<realm>" },
{ "path": "$.comment", "action": "drop" },
{ "path": "$.attachments", "action": "drop" }
],
"export.compact": [
{ "path": "$.actorId", "action": "drop" },
{ "path": "$.comment", "action": "drop" },
{ "path": "$.policyRationale", "action": "drop" },
{ "path": "$.attachments", "action": "drop" },
{ "path": "$.labels", "action": "drop" }
],
"observability": [
{ "path": "$.event_body", "action": "drop" },
{ "path": "$.actor_id", "action": "hash", "hashWith": "sha256" }
]
}
}

View File

@@ -0,0 +1,39 @@
schemaVersion: redaction.v1
generatedAt: 2025-12-02T00:00:00Z
owner: findings-ledger-guild
rules:
ledger.event:
- path: $.actor.id
action: mask
maskWith: "user:<realm>"
- path: $.payload.comment
action: drop
- path: $.payload.ticket.url
action: drop
- path: $.payload.attachments[*].downloadUrl
action: drop
export.canonical:
- path: $.actorId
action: mask
maskWith: "user:<realm>"
- path: $.comment
action: drop
- path: $.attachments
action: drop
export.compact:
- path: $.actorId
action: drop
- path: $.comment
action: drop
- path: $.policyRationale
action: drop
- path: $.attachments
action: drop
- path: $.labels
action: drop
observability:
- path: $.event_body
action: drop
- path: $.actor_id
action: hash
hashWith: sha256

View File

@@ -0,0 +1,5 @@
{
"eventStream": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"projection": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"notes": "Replace with real values from harness output before enforcing checksum guard."
}

View File

@@ -0,0 +1,75 @@
# Findings Ledger Schema Catalog (FL1FL3)
**Scope:** Versioned canonical schemas for ledger events, projections, and exports.
**Status:** v1.0.0 sealed (2025-12-02) — breaking changes require new minor/major version tags.
## 1) Ledger event envelope — `ledger.event.v1`
| Field | Type | Notes |
| --- | --- | --- |
| `event.id` | `uuid` | V7 GUID allowed. |
| `event.type` | `string` (`ledger_event_type`) | See `schema.md` §2.2. |
| `event.tenant` | `string` | Partition key. |
| `event.chainId` | `uuid` | Derived when absent (`tenant :: policyVersion`), see `workflow-inference.md`. |
| `event.sequence` | `long` | Gapless per chain, starts at 1. |
| `event.policyVersion` | `string` | SHA-256 digest of policy bundle; propagated into exports and DSSE. |
| `event.finding` | object | `id`, `artifactId`, `vulnId`. |
| `event.actor` | object | `id`, `type` (`system|operator|integration`). |
| `event.occurredAt` | `string` (UTC ISO-8601 ms) | Domain clock. |
| `event.recordedAt` | `string` (UTC ISO-8601 ms) | Service `TimeProvider`. |
| `event.payload` | object | Mutation-specific body. |
| `event.evidenceBundleRef` | `string?` | DSSE/capsule id (optional). |
| `event.airgap.bundle` | object? | See `airgap-provenance.md`. |
| `event_hash` | `char(64)` | `sha256(canonicalJson)` lower-hex. |
| `previous_hash` | `char(64)` | All-zero for chain genesis. |
| `merkle_leaf_hash` | `char(64)` | `sha256(event_hash || "-" || sequence)`. |
Canonicalisation: UTF-8, sorted keys, lower-case enums, ISO-8601 UTC with millisecond precision, arrays stable-order. Any field addition bumps minor version.
## 2) Finding projection — `ledger.projection.v1`
| Field | Type | Notes |
| --- | --- | --- |
| `tenantId` | `string` | Partition key. |
| `findingId` | `string` | Stable identity. |
| `policyVersion` | `string` | Hash of active policy bundle. |
| `status` | `string` | `affected|triaged|accepted_risk|resolved|unknown`. |
| `severity` | `number` | 010, 3 decimal places. |
| `riskScore` | `number` | 010, 3 decimal places. |
| `riskSeverity` | `string` | `low|medium|high|critical|unknown`. |
| `riskProfileVersion` | `string` | Version/hash from Risk Engine. |
| `riskExplanationId` | `uuid?` | Links to explain bundle. |
| `labels` | `json` | KEV/runtime flags, sorted keys. |
| `currentEventId` | `uuid` | Source ledger event. |
| `explainRef` | `string?` | Object storage / DSSE reference. |
| `policyRationale` | `json` | Array of rationale refs. |
| `updatedAt` | `string` UTC | Projection timestamp. |
| `cycleHash` | `char(64)` | `sha256(canonicalProjectionJson)`; used in exports. |
Projection deterministic hash recipe: serialize projection record with sorted keys (excluding `updatedAt` jitter) and hash via SHA-256. The replay harness recomputes and compares.
## 3) Export payloads — `export.v1`
Shapes share headers: `policyVersion`, `projectionVersion` (cycle hash), `filtersHash`, `pageToken`, `observedAt`, `provenance` (`ledgerRoot`, `projectorVersion`, `policyHash`, optional `dsseDigest`).
### Canonical vs compact
- **Canonical (`export.v1.canonical`)** — full provenance fields, evidence refs, DSSE linkage.
- **Compact (`export.v1.compact`)** — drops verbose fields (`policyRationale`, comments, actor ids), keeps `cycleHash` + `filtersHash` for determinism; redaction manifest enforced.
### Record fields
- Findings: `findingId`, `eventSequence`, `status`, `severity`, `risk`, `advisories[]`, `evidenceBundleRef`, `cycleHash`.
- VEX: `vexStatementId`, `product`, `status`, `justification`, `knownExploited`, `cycleHash`.
- Advisories: `advisoryId`, `source`, `cvss{version,vector,baseScore}`, `epss`, `kev`, `cycleHash`.
- SBOMs: `sbomId`, `subject{digest,mediaType}`, `sbomFormat`, `componentsCount`, `materials[]`, `cycleHash`.
Filters hash: `sha256(sortedQueryString)`; stored alongside fixtures for replayability.
## 4) Versioning rules
- Patch: backward-compatible field additions (new optional key) — bump patch digit.
- Minor: additive required fields or canonical rule tweaks — bump minor.
- Major: breaking change (field removal/rename, hash recipe) — bump major and keep prior schema frozen.
## 5) Reference artefacts
- Golden fixtures: `src/Findings/StellaOps.Findings.Ledger/fixtures/golden/*.ndjson`.
- Checksum manifest: `docs/modules/findings-ledger/golden-checksums.json`.
- Offline verifier: `tools/LedgerReplayHarness/scripts/verify_export.py`.

View File

@@ -119,6 +119,11 @@ Canonicalisation rules:
5. Numbers use decimal notation; omit trailing zeros.
6. Arrays maintain supplied order.
### 2.4 Versioning & DSSE linkage (FL1, FL6)
- Canonical schema identifiers are catalogued in `schema-catalog.md` (`ledger.event.v1`, `ledger.projection.v1`, `export.v1.*`).
- Any change to the envelope, hash recipe, or required fields bumps the catalog version; legacy versions remain frozen.
- DSSE artefacts (anchors, exports, replay reports) **must** embed `policyVersion` and `schemaVersion` (see `dsse-policy-linkage.md`).
Hash pipeline:
```
@@ -270,7 +275,7 @@ Ordering and pagination: `ORDER BY recorded_at ASC, attestation_id ASC` with cur
1. Canonical serialize the envelope (§2.3).
2. Compute `event_hash` and store along with `previous_hash`.
3. Build Merkle tree per anchoring window using leaf hash `SHA256(event_hash || '-' || sequence_no)`.
4. Persist root in `ledger_merkle_roots` and, when configured, submit to external transparency log (Rekor v2). Store receipt/UUID in `anchor_reference`.
4. Persist root in `ledger_merkle_roots` and, when configured, submit to external transparency log (Rekor v2). Store receipt/UUID in `anchor_reference` (see `merkle-anchor-policy.md`).
5. Projection rows compute `cycle_hash = SHA256(canonical_projection_json)` where canonical projection includes fields `{tenant_id, finding_id, policy_version, status, severity, labels, current_event_id}` with sorted keys.
Verification flow for auditors:
@@ -284,6 +289,8 @@ Verification flow for auditors:
- Initial migration script: `src/Findings/StellaOps.Findings.Ledger/migrations/001_initial.sql`.
- Sample canonical event: `seed-data/findings-ledger/fixtures/ledger-event.sample.json` (includes pre-computed `eventHash`, `previousHash`, and `merkleLeafHash` values).
- Sample projection row: `seed-data/findings-ledger/fixtures/finding-projection.sample.json` (includes canonical `cycleHash` for replay validation).
- Golden export fixtures (FL7): `src/Findings/StellaOps.Findings.Ledger/fixtures/golden/*.ndjson` with checksums in `docs/modules/findings-ledger/golden-checksums.json`.
- Redaction manifest (FL5): `docs/modules/findings-ledger/redaction-manifest.yaml` governs mask/drop rules for canonical vs compact exports.
Fixtures follow canonical key ordering and include precomputed hashes to validate tooling.

View File

@@ -0,0 +1,28 @@
# Tenant Isolation & Redaction Manifest (FL5)
**Purpose:** Document how Findings Ledger enforces tenant boundaries and which fields are redacted in deterministic exports.
## Isolation controls
- Storage: all ledger, projection, history, and merkle tables are **LIST-partitioned by `tenant_id`** (PostgreSQL). Cross-tenant queries are disallowed at repo level.
- Queueing: Merkle batches and projector pipelines are keyed by `(tenant_id, chain_id)`; no mixing.
- Exports: `/ledger/export/*` requires `X-Stella-Tenant`; service rejects multi-tenant requests.
- Hashing: event/projection hashes include `tenant_id` as part of canonical envelope, preventing replay across tenants.
## Redaction policy
- User-generated content (comments, attachments metadata) is excluded from compact exports and masked in canonical exports per manifest.
- Actor identifiers are truncated to realm (`user:<realm>`); emails/PII never emitted.
- Evidence bundle references are retained, but inline evidence payloads are not stored in ledger.
## Manifest
- Path: `docs/modules/findings-ledger/redaction-manifest.yaml` (JSON twin: `redaction-manifest.json` for offline tooling).
- Content: declarative list of fields redacted or truncated for each export shape.
- The manifest is signed in checksum list `docs/modules/findings-ledger/golden-checksums.json`; sha256 must match before release.
### Applying the manifest
- Canonical exports apply `redact: mask` rules only to PII (`actorId`, `comment`); compact exports drop (`drop: true`) the same fields plus verbose rationale arrays.
- Log pipelines ensure `event_body` is never written to logs; only metadata/hashes appear (see `observability.md`).
## Validation steps
1. `sha256sum docs/modules/findings-ledger/redaction-manifest.yaml` matches `golden-checksums.json`.
2. Run `python tools/LedgerReplayHarness/scripts/verify_export.py --input fixtures/golden/findings-canonical.ndjson --schema export.v1.canonical --manifest docs/modules/findings-ledger/redaction-manifest.json` (script enforces mask/drop rules offline).
3. Confirm export responses in staging omit masked fields for the requesting tenant.

View File

@@ -12,6 +12,7 @@ Applies to `mirror-thin-v1.*` artefacts in `out/mirror/thin/`.
- Payload: `mirror-thin-v1.manifest.json`
- Signature: ed25519 over base64url(payload)
- Envelope path: `out/mirror/thin/mirror-thin-v1.manifest.dsse.json`
- Bundle meta DSSE (OK1/OK3/MS8): payload type `application/vnd.stellaops.mirror.bundle+json`, payload `mirror-thin-v1.bundle.json`, envelope path `mirror-thin-v1.bundle.dsse.json`.
## TUF metadata layout
```
@@ -23,9 +24,10 @@ out/mirror/thin/tuf/
keys/mirror-ed25519-test-1.pub
```
### Targets mapping
- `mirror-thin-v1.tar.gz` → targets entry with sha256 `210dc49e8d3e25509298770a94da277aa2c9d4c387d3c24505a61fe1d7695a49`
- `mirror-thin-v1.manifest.json` → sha256 `0ae51fa87648dae0a54fab950181a3600a8363182d89ad46d70f3a56b997b504`
### Targets mapping (latest dev build 2025-12-02)
- `mirror-thin-v1.tar.gz` → targets entry with sha256 `fb1ce26388a1f1ab2eb90aae6d63ac05de326fbbd947fbf7a17b980232c9fc7d`
- `mirror-thin-v1.manifest.json` → sha256 `1affb0b796ff037117b46aa1f1d8056a9c80755e925af058ea72132ba158becf`
- `mirror-thin-v1.bundle.json` (top-level kit manifest) → sha256 `a3b16f5d1b74ffdf9aedbbfe9282d368dc3dcf70676c8ac7e8cdd984162e7f90`
### Determinism rules
- Sort keys in JSON; indent=2; trailing newline.

View File

@@ -12,6 +12,8 @@
MIRROR_SIGN_KEY_B64: ${{ secrets.MIRROR_SIGN_KEY_B64 }}
REQUIRE_PROD_SIGNING: 1
OCI: 1
TENANT_SCOPE: tenant-demo
ENV_SCOPE: lab
run: |
scripts/mirror/check_signing_prereqs.sh
scripts/mirror/ci-sign.sh
@@ -40,7 +42,9 @@ MIRROR_SIGN_KEY_B64=LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndC
**Do not ship with this key.** Set `REQUIRE_PROD_SIGNING=1` for release/tag builds so they fail without the real key. Add the production key as a Gitea secret (`MIRROR_SIGN_KEY_B64`) and rerun the workflow; remove this temporary key block once rotated.
## Verification
The CI step already runs `scripts/mirror/verify_thin_bundle.py`. For OCI, ensure `out/mirror/thin/oci/index.json` references the manifest digest.
The CI step already runs `scripts/mirror/verify_thin_bundle.py --bundle-meta mirror-thin-v1.bundle.json --tenant $TENANT_SCOPE --environment $ENV_SCOPE --pubkey out/mirror/thin/tuf/keys/ci-ed25519.pub` so offline-kit policies (OK1OK10), Rekor policy (RK1RK10), and mirror-format policy (MS1MS10) are validated alongside the tarball. For OCI, ensure `out/mirror/thin/oci/index.json` references the manifest digest.
`milestone.json` now carries manifest/tar/bundle/bundle-dsse hashes plus policy layer hashes to allow air-gapped import verification.
## Fallback (if secret absent)
- CI can fall back to an embedded test Ed25519 key when `MIRROR_SIGN_KEY_B64` is unset **only when `REQUIRE_PROD_SIGNING` is not set**. This is for dev smoke runs; release/tag jobs must set `REQUIRE_PROD_SIGNING=1` to forbid fallback.

View File

@@ -112,7 +112,7 @@ Key notes:
| **DSL Compiler** (`Dsl/`) | Parse, canonicalise, IR generation, checksum caching. | Uses Roslyn-like pipeline; caches by `policyId+version+hash`. |
| **Selection Layer** (`Selection/`) | Batch SBOM ↔ advisory ↔ VEX joiners; apply equivalence tables; support incremental cursors. | Deterministic ordering (SBOM → advisory → VEX). |
| **Evaluator** (`Evaluation/`) | Execute IR with first-match semantics, compute severity/trust/reachability weights, record rule hits. | Stateless; all inputs provided by selection layer. |
| **Signals** (`Signals/`) | Normalizes reachability, trust, entropy, uncertainty, runtime hits into a single dictionary passed to Evaluator; supplies default `unknown` values when signals missing. | Aligns with `signals.*` namespace in DSL. |
| **Signals** (`Signals/`) | Normalizes reachability, trust, entropy, uncertainty, runtime hits into a single dictionary passed to Evaluator; supplies default `unknown` values when signals missing. Entropy penalties are derived from Scanner `layer_summary.json`/`entropy.report.json` (K=0.5, cap=0.3, block at image opaque ratio &gt; 0.15 w/ unknown provenance) and exported via `policy_entropy_penalty_value` / `policy_entropy_image_opaque_ratio`. | Aligns with `signals.*` namespace in DSL. |
| **Materialiser** (`Materialization/`) | Upsert effective findings, append history, manage explain bundle exports. | Mongo transactions per SBOM chunk. |
| **Orchestrator** (`Runs/`) | Change-stream ingestion, fairness, retry/backoff, queue writer. | Works with Scheduler Models DTOs. |
| **API** (`Api/`) | Minimal API endpoints, DTO validation, problem responses, idempotency. | Generated clients for CLI/UI. |

View File

@@ -2,7 +2,8 @@
Zastava monitors running workloads, verifies supply chain posture, and enforces runtime policy via Kubernetes admission webhooks.
## Latest updates (2025-11-30)
## Latest updates (2025-12-02)
- DSSE-signed schemas, thresholds, exports, and deterministic `zastava-kit` bundle published under `docs/modules/zastava`; verification via `kit/verify.sh` and hashes in `SHA256SUMS`.
- Sprint tracker `docs/implplan/SPRINT_0335_0001_0001_docs_modules_zastava.md` and module `TASKS.md` added to mirror status.
- Observability runbook stub + dashboard placeholder added under `operations/` (offline import).
- Surface.Env/Surface.Secrets adoption remains pending platform contracts; align with platform docs before enabling sealed mode.

View File

@@ -1,7 +1,17 @@
e65d4b68c9bdaa569c6d4c5a9b0a8bc1dc41876f948983011ff6f9d3466565d0 schemas/observer_event.schema.json
f466bf2b399f065558867eaf3c961cff8803f4a1506bae5539c9ce62e9ab005d schemas/webhook_admission.schema.json
1b05f31ab9486f9a03ecf872fa5c681e9acbad2adb71a776c271dbcf997ca2a8 schemas/observer_event.schema.json
99382de0e6a2b9c21146c03640c2e08b0e5e41be11fdbc213f0f071357da5a99 schemas/observer_event.schema.json.dsse
222db5258f5ba1ee720f8df03858263363b8636ff8ec9370f5ad390e8def0b3c schemas/webhook_admission.schema.json
19f108da1a512a488536bc2cd9d9cb1cf9824d748d8fc6a32d0e31c89be9a897 schemas/webhook_admission.schema.json.dsse
da065beabf8e038298a54f04ffa3e140cc149e0d64c301f6fd4c3925f2d64ee6 schemas/examples/observer_event.example.json
7e3cd0c18c9dfaf9001a16a99be7f9ff01e2d21b14eca9fb97c332342ac53c94 schemas/examples/webhook_admission.example.json
e17d36a2a39d748b76994ad3e3e4f3fa8db1b9298a3ce5eaaafb575791c01da3 schemas/README.md
f88bdebaa9858ffe3cd0fbb46e914c933e18709165bfc59f976136097fa8493d exports/observer_events.ndjson
de9b24675a0a758e40647844a31a13a1be1667750a39fe59465b0353fd0dddd9 exports/observer_events.ndjson.dsse
232809cf6a1cc7ba5fa34e0daf00fab9b6f970a613bc822457eef0d841fb2229 exports/webhook_admissions.ndjson
0edf6cabd636c7bb1f210af2aecaf83de3cc21c82113a646429242ae72618b17 exports/webhook_admissions.ndjson.dsse
40fabd4d7bc75c35ae063b2e931e79838c79b447528440456f5f4846951ff59d thresholds.yaml
652fce7d7b622ae762c8fb65a1e592bec14b124c3273312f93a63d2c29a2b989 kit/verify.sh
f3f84fbe780115608268a91a5203d2d3ada50b4317e7641d88430a692e61e1f4 kit/README.md
2411a16a68c98c8fdd402e19b9c29400b469c0054d0b6067541ee343988b85e0 schemas/examples/observer_event.example.json
4ab47977b0717c8bdb39c52f52880742785cbcf0b5ba73d9ecc835155d445dc1 schemas/examples/webhook_admission.example.json
4dc099a742429a7ec300ac4c9eefe2f6b80bc0c10d7a7a3bbaf7f0a0f0ad7f20 thresholds.yaml.dsse
f69f953c78134ef504b870cea47ba62d5e37a7a86ec0043d824dcb6073cd43fb kit/verify.sh
1cf8f0448881d067e5e001a1dfe9734b4cdfcaaf16c3e9a7321ceae56e4af8f2 kit/README.md
eaba054428fa72cd9476cffe7a94450e4345ffe2e294e9079eb7c3703bcf7df0 kit/ed25519.pub
40a40b31480d876cf4487d07ca8d8b5166c7df455bef234e2c1861b7b3dc7e3b evidence/README.md

View File

@@ -5,9 +5,9 @@
| ZASTAVA-DOCS-0001 | DONE (2025-11-30) | Docs Guild | README/architecture refreshed; Surface Env/Secrets and sprint links added. |
| ZASTAVA-ENG-0001 | DONE (2025-11-30) | Module Team | TASKS board created; statuses mirrored with `docs/implplan/SPRINT_0335_0001_0001_docs_modules_zastava.md`. |
| ZASTAVA-OPS-0001 | DONE (2025-11-30) | Ops Guild | Observability runbook stub + Grafana JSON placeholder added under `operations/`. |
| ZASTAVA-SCHEMAS-0001 | TODO | Zastava Guild | Publish signed observer/admission schemas + test vectors under `docs/modules/zastava/schemas/`; DSSE + SHA256 required. |
| ZASTAVA-KIT-0001 | TODO | Zastava Guild | Build signed `zastava-kit` bundle with thresholds.yaml, schemas, observations/admissions export, SHA256SUMS, and verify.sh; ensure offline parity. |
| ZASTAVA-THRESHOLDS-0001 | TODO | Zastava Guild | DSSE-sign `thresholds.yaml` and align with kit; publish Evidence Locker URI and update sprint 0144 checkpoints. |
| ZASTAVA-SCHEMAS-0001 | DONE (2025-12-02) | Zastava Guild | Signed observer/admission schemas + test vectors under `docs/modules/zastava/schemas/`; DSSE + SHA256 published. |
| ZASTAVA-KIT-0001 | DONE (2025-12-02) | Zastava Guild | Built signed `zastava-kit` bundle with thresholds, schemas, exports, SHA256SUMS, verify.sh; offline parity verified. |
| ZASTAVA-THRESHOLDS-0001 | DONE (2025-12-02) | Zastava Guild | DSSE-signed `thresholds.yaml`, recorded Evidence Locker targets, and aligned with kit packaging. |
| ZASTAVA-GAPS-144-007 | DONE (2025-12-02) | Zastava Guild | Remediation plan for ZR1ZR10 published at `docs/modules/zastava/gaps/2025-12-02-zr-gaps.md`; follow-on schemas/kit/thresholds to be produced and signed. |
> Keep this table in lockstep with the sprint Delivery Tracker (TODO/DOING/DONE/BLOCKED updates go to both places).

View File

@@ -1,29 +1,53 @@
# Zastava Evidence Locker Plan (schemas/kit)
# Zastava Evidence Locker (schemas/kit)
Artifacts to sign (target 2025-12-06):
- `schemas/observer_event.schema.json` — predicate `stella.ops/zastavaSchema@v1`
- `schemas/webhook_admission.schema.json` — predicate `stella.ops/zastavaSchema@v1`
- `thresholds.yaml` — predicate `stella.ops/zastavaThresholds@v1`
- `zastava-kit.tzst` + `SHA256SUMS` — predicate `stella.ops/zastavaKit@v1`
Signed 2025-12-02 with Ed25519 key (pub base64url: `mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc`). Private key stored offline; all signatures use DSSEv1 pre-auth encoding.
Public key copy: `docs/modules/zastava/kit/ed25519.pub`.
Planned Evidence Locker paths (fill after signing):
- `evidence-locker/zastava/2025-12-06/observer_event.schema.dsse`
- `evidence-locker/zastava/2025-12-06/webhook_admission.schema.dsse`
- `evidence-locker/zastava/2025-12-06/thresholds.dsse`
- `evidence-locker/zastava/2025-12-06/zastava-kit.tzst`
- `evidence-locker/zastava/2025-12-06/SHA256SUMS`
## Artefacts
- `schemas/observer_event.schema.json.dsse` (payloadType `application/vnd.stellaops.zastava.schema+json;name=observer_event;version=1`)
- `schemas/webhook_admission.schema.json.dsse` (payloadType `application/vnd.stellaops.zastava.schema+json;name=webhook_admission;version=1`)
- `thresholds.yaml.dsse` (payloadType `application/vnd.stellaops.zastava.thresholds+yaml;version=1`)
- `exports/observer_events.ndjson.dsse` (payloadType `application/vnd.stellaops.zastava.observer-events+ndjson;version=1`)
- `exports/webhook_admissions.ndjson.dsse` (payloadType `application/vnd.stellaops.zastava.webhook-admissions+ndjson;version=1`)
- `kit/zastava-kit.tzst.dsse` (payloadType `application/vnd.stellaops.zastava.kit+tzst;version=1`)
Signing template (replace KEY and file):
## Evidence Locker targets
- `evidence-locker/zastava/2025-12-02/observer_event.schema.json.dsse`
- `evidence-locker/zastava/2025-12-02/webhook_admission.schema.json.dsse`
- `evidence-locker/zastava/2025-12-02/thresholds.yaml.dsse`
- `evidence-locker/zastava/2025-12-02/observer_events.ndjson.dsse`
- `evidence-locker/zastava/2025-12-02/webhook_admissions.ndjson.dsse`
- `evidence-locker/zastava/2025-12-02/zastava-kit.tzst`
- `evidence-locker/zastava/2025-12-02/zastava-kit.tzst.dsse`
- `evidence-locker/zastava/2025-12-02/SHA256SUMS`
## Signing template (Python, ed25519)
```bash
cosign sign-blob \
--key cosign.key \
--predicate-type stella.ops/zastavaSchema@v1 \
--output-signature schemas/observer_event.schema.dsse \
schemas/observer_event.schema.json
python - <<'PY'
from pathlib import Path
from base64 import urlsafe_b64encode
import json
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
priv = serialization.load_pem_private_key(Path('/tmp/zastava-ed25519.key').read_bytes(), password=None)
pub = priv.public_key().public_bytes(encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw)
keyid = urlsafe_b64encode(pub).decode().rstrip('=')
pt = '<payload-type>'
payload = Path('<file-to-sign>').read_bytes()
pae = b' '.join([b'DSSEv1', str(len(pt)).encode(), pt.encode(), str(len(payload)).encode(), payload])
sig = priv.sign(pae)
env = {
'payloadType': pt,
'payload': urlsafe_b64encode(payload).decode().rstrip('='),
'signatures': [{'keyid': keyid, 'sig': urlsafe_b64encode(sig).decode().rstrip('=')}],
}
Path('<file-to-sign>.dsse').write_text(json.dumps(env, indent=2, sort_keys=True) + '\n')
print('signed', '<file-to-sign>', 'with keyid', keyid)
PY
```
Post-sign steps:
1) Verify DSSEs with `cosign verify-blob` using `cosign.pub`.
2) Upload DSSEs + SHA256SUMS to Evidence Locker paths above.
3) Update `docs/implplan/SPRINT_0144_0001_0001_zastava_runtime_signals.md` Decisions & Risks and Next Checkpoints with final URIs.
4) Mark tasks ZASTAVA-SCHEMAS-0001 / ZASTAVA-THRESHOLDS-0001 / ZASTAVA-KIT-0001 to DONE in both sprint and TASKS tables.
## Post-sign checklist
1) Run `kit/verify.sh` to validate hashes + DSSE.
2) Upload artefacts + DSSEs + SHA256SUMS to the Evidence Locker paths above.
3) Record URIs in sprint 0144 Decisions & Risks and mark ZASTAVA-SCHEMAS-0001 / ZASTAVA-THRESHOLDS-0001 / ZASTAVA-KIT-0001 as DONE.

View File

@@ -0,0 +1 @@
{"event_type":"runtime_fact","firmware_version":"1.2.3","graph_revision_id":"graph-r1","ledger_id":"ledger-789","monotonic_nanos":123456789,"observed_at":"2025-12-02T12:00:00Z","payload":{"pid":4242,"process":"nginx"},"payload_hash":"sha256:7476a5068a3f0780c552f81c90d061d9e39c37f425a243ecff961b08676546fd","policy_hash":"sha256:deadbeef","project_id":"proj-123","replay_manifest":"manifest-r1","sensor_id":"observer-01","signature":"dsse://observer-events/2025-12-02/observer_events.ndjson.dsse#line1","tenant_id":"tenant-a"}

View File

@@ -0,0 +1,10 @@
{
"payload": "eyJldmVudF90eXBlIjoicnVudGltZV9mYWN0IiwiZmlybXdhcmVfdmVyc2lvbiI6IjEuMi4zIiwiZ3JhcGhfcmV2aXNpb25faWQiOiJncmFwaC1yMSIsImxlZGdlcl9pZCI6ImxlZGdlci03ODkiLCJtb25vdG9uaWNfbmFub3MiOjEyMzQ1Njc4OSwib2JzZXJ2ZWRfYXQiOiIyMDI1LTEyLTAyVDEyOjAwOjAwWiIsInBheWxvYWQiOnsicGlkIjo0MjQyLCJwcm9jZXNzIjoibmdpbngifSwicGF5bG9hZF9oYXNoIjoic2hhMjU2Ojc0NzZhNTA2OGEzZjA3ODBjNTUyZjgxYzkwZDA2MWQ5ZTM5YzM3ZjQyNWEyNDNlY2ZmOTYxYjA4Njc2NTQ2ZmQiLCJwb2xpY3lfaGFzaCI6InNoYTI1NjpkZWFkYmVlZiIsInByb2plY3RfaWQiOiJwcm9qLTEyMyIsInJlcGxheV9tYW5pZmVzdCI6Im1hbmlmZXN0LXIxIiwic2Vuc29yX2lkIjoib2JzZXJ2ZXItMDEiLCJzaWduYXR1cmUiOiJkc3NlOi8vb2JzZXJ2ZXItZXZlbnRzLzIwMjUtMTItMDIvb2JzZXJ2ZXJfZXZlbnRzLm5kanNvbi5kc3NlI2xpbmUxIiwidGVuYW50X2lkIjoidGVuYW50LWEifQo",
"payloadType": "application/vnd.stellaops.zastava.observer-events+ndjson;version=1",
"signatures": [
{
"keyid": "mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc",
"sig": "5DPpjAcyWSeCM_yPCiIsQl92FtUwnccN8J5lY5AxKBE1qfYbU6dEgGQudDWlY2_-FUak6fupQ79vrgGbGiDDDQ"
}
]
}

View File

@@ -0,0 +1 @@
{"bypass_waiver_id":null,"decision":"allow","decision_at":"2025-12-02T12:00:10Z","decision_reason":"surface cache fresh","graph_revision_id":"graph-r1","ledger_id":"ledger-789","manifest_pointer":"surfacefs://cache/sha256:abc","monotonic_nanos":2233445566,"namespace":"prod","payload":{"images":[{"digest":"sha256:abcd","name":"ghcr.io/acme/api:1.2.3","sbom_referrer":true,"signed":true}],"manifest_pointer":"surfacefs://cache/sha256:abc","policy_hash":"sha256:deadbeef","verdict":"allow"},"payload_hash":"sha256:36bfb2bc81b7050bbb508e12cafe7ad5a51336aad397ef3a23b0e258aed73dc6","policy_hash":"sha256:deadbeef","project_id":"proj-123","replay_manifest":"manifest-r1","request_uid":"abcd-1234","resource_kind":"Deployment","side_effect":"none","signature":"dsse://webhook-admissions/2025-12-02/webhook_admissions.ndjson.dsse#line1","tenant_id":"tenant-a","workload_name":"api"}

View File

@@ -0,0 +1,10 @@
{
"payload": "eyJieXBhc3Nfd2FpdmVyX2lkIjpudWxsLCJkZWNpc2lvbiI6ImFsbG93IiwiZGVjaXNpb25fYXQiOiIyMDI1LTEyLTAyVDEyOjAwOjEwWiIsImRlY2lzaW9uX3JlYXNvbiI6InN1cmZhY2UgY2FjaGUgZnJlc2giLCJncmFwaF9yZXZpc2lvbl9pZCI6ImdyYXBoLXIxIiwibGVkZ2VyX2lkIjoibGVkZ2VyLTc4OSIsIm1hbmlmZXN0X3BvaW50ZXIiOiJzdXJmYWNlZnM6Ly9jYWNoZS9zaGEyNTY6YWJjIiwibW9ub3RvbmljX25hbm9zIjoyMjMzNDQ1NTY2LCJuYW1lc3BhY2UiOiJwcm9kIiwicGF5bG9hZCI6eyJpbWFnZXMiOlt7ImRpZ2VzdCI6InNoYTI1NjphYmNkIiwibmFtZSI6ImdoY3IuaW8vYWNtZS9hcGk6MS4yLjMiLCJzYm9tX3JlZmVycmVyIjp0cnVlLCJzaWduZWQiOnRydWV9XSwibWFuaWZlc3RfcG9pbnRlciI6InN1cmZhY2VmczovL2NhY2hlL3NoYTI1NjphYmMiLCJwb2xpY3lfaGFzaCI6InNoYTI1NjpkZWFkYmVlZiIsInZlcmRpY3QiOiJhbGxvdyJ9LCJwYXlsb2FkX2hhc2giOiJzaGEyNTY6MzZiZmIyYmM4MWI3MDUwYmJiNTA4ZTEyY2FmZTdhZDVhNTEzMzZhYWQzOTdlZjNhMjNiMGUyNThhZWQ3M2RjNiIsInBvbGljeV9oYXNoIjoic2hhMjU2OmRlYWRiZWVmIiwicHJvamVjdF9pZCI6InByb2otMTIzIiwicmVwbGF5X21hbmlmZXN0IjoibWFuaWZlc3QtcjEiLCJyZXF1ZXN0X3VpZCI6ImFiY2QtMTIzNCIsInJlc291cmNlX2tpbmQiOiJEZXBsb3ltZW50Iiwic2lkZV9lZmZlY3QiOiJub25lIiwic2lnbmF0dXJlIjoiZHNzZTovL3dlYmhvb2stYWRtaXNzaW9ucy8yMDI1LTEyLTAyL3dlYmhvb2tfYWRtaXNzaW9ucy5uZGpzb24uZHNzZSNsaW5lMSIsInRlbmFudF9pZCI6InRlbmFudC1hIiwid29ya2xvYWRfbmFtZSI6ImFwaSJ9Cg",
"payloadType": "application/vnd.stellaops.zastava.webhook-admissions+ndjson;version=1",
"signatures": [
{
"keyid": "mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc",
"sig": "UwXQm2oZPVIISQecILLkvxvSXZiXeZdPVe5RNqFxZ8Dv5xDT1nEcTq0pn2Tl3unk0sY44Lh-dU_599nxaHD9Aw"
}
]
}

View File

@@ -43,7 +43,8 @@
- Delivery paths for schemas/thresholds/kit will be added when produced; DSSE signatures required for all artefacts.
## Next steps
1) Generate schemas + test vectors and place under `docs/modules/zastava/schemas/`; sign DSSE.
2) Draft `thresholds.yaml` with budgets and sign DSSE.
3) Build `zastava-kit` bundle + `verify.sh`; include Evidence Locker path and SHA256.
1) ✅ Schemas + test vectors generated and DSSE-signed under `docs/modules/zastava/schemas/` (2025-12-02).
2) `thresholds.yaml` DSSE-signed and included in kit (2025-12-02).
3) ✅ Deterministic `zastava-kit` bundle + `verify.sh` built; kit DSSE stored at `docs/modules/zastava/kit/zastava-kit.tzst.dsse` with hashes in `SHA256SUMS` (2025-12-02).
4) Add tenancy/ordering/provenance enforcement to Observer/Webhook validators and tests; mirror changes in sprint and TASKS boards.
5) Upload DSSE artefacts + kit to Evidence Locker paths in `docs/modules/zastava/evidence/README.md` and backfill operations docs with verifier usage.

View File

@@ -1,17 +1,83 @@
# Zastava Kit (offline bundle) Draft
# Zastava Kit (offline bundle)
Contents to include when built:
- Observations and admissions exports (NDJSON) signed via DSSE.
- Schemas: `schemas/observer_event.schema.json`, `schemas/webhook_admission.schema.json`.
- Thresholds: `thresholds.yaml` (DSSE-signed).
- Hash manifest: `SHA256SUMS` (covering all kit files).
- Verify script: `verify.sh` (hash + DSSE verification; fail closed on mismatch).
## Contents
- Schemas + DSSE: `schemas/observer_event.schema.json(.dsse)`, `schemas/webhook_admission.schema.json(.dsse)`.
- Examples: `schemas/examples/*.json` (canonicalised, hashed).
- Thresholds + DSSE: `thresholds.yaml(.dsse)`.
- Exports + DSSE: `exports/observer_events.ndjson(.dsse)`, `exports/webhook_admissions.ndjson(.dsse)`.
- Verification assets: `SHA256SUMS`, `kit/verify.sh`, `kit/ed25519.pub`, `schemas/README.md`, `evidence/README.md`.
Deterministic packaging: `tar --mtime @0 --owner 0 --group 0 --numeric-owner -cf - kit | zstd -19 --long=27 --no-progress > zastava-kit.tzst`.
## Build (deterministic)
From `docs/modules/zastava`:
Pending: fill with signed artefacts and Evidence Locker URIs after DSSE signing.
Planned Evidence Locker paths (post-signing):
- `evidence-locker/zastava/2025-12-06/observer_event.schema.dsse`
- `evidence-locker/zastava/2025-12-06/webhook_admission.schema.dsse`
- `evidence-locker/zastava/2025-12-06/thresholds.dsse`
- `evidence-locker/zastava/2025-12-06/zastava-kit.tzst` + `SHA256SUMS`
```bash
tar --mtime @0 --owner 0 --group 0 --numeric-owner --sort=name \
-cf - \
SHA256SUMS schemas exports thresholds.yaml thresholds.yaml.dsse \
schemas/examples schemas/README.md \
schemas/observer_event.schema.json schemas/observer_event.schema.json.dsse \
schemas/webhook_admission.schema.json schemas/webhook_admission.schema.json.dsse \
exports/observer_events.ndjson exports/observer_events.ndjson.dsse \
exports/webhook_admissions.ndjson exports/webhook_admissions.ndjson.dsse \
evidence/README.md kit/README.md kit/verify.sh kit/ed25519.pub \
| zstd -19 --long=27 --no-progress > kit/zastava-kit.tzst
```
Sign the kit itself with the same Ed25519 key (base64url pub: `mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc`):
```bash
python - <<'PY'
from pathlib import Path
from base64 import urlsafe_b64encode
import json
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization
priv = serialization.load_pem_private_key(Path('/tmp/zastava-ed25519.key').read_bytes(), password=None)
pub = priv.public_key().public_bytes(encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw)
keyid = urlsafe_b64encode(pub).decode().rstrip('=')
pt = 'application/vnd.stellaops.zastava.kit+tzst;version=1'
payload = Path('kit/zastava-kit.tzst').read_bytes()
pae = b' '.join([b'DSSEv1', str(len(pt)).encode(), pt.encode(), str(len(payload)).encode(), payload])
sig = priv.sign(pae)
env = {
'payloadType': pt,
'payload': urlsafe_b64encode(payload).decode().rstrip('='),
'signatures': [{'keyid': keyid, 'sig': urlsafe_b64encode(sig).decode().rstrip('=')}],
}
Path('kit/zastava-kit.tzst.dsse').write_text(json.dumps(env, indent=2, sort_keys=True) + '\n')
print('wrote kit/zastava-kit.tzst.dsse with keyid', keyid)
PY
```
## Verify
1) Verify the kit DSSE before unpacking (optional but recommended) using the public key shipped alongside the kit (run from `docs/modules/zastava`):
```bash
cd docs/modules/zastava
python - <<'PY'
import base64, json, sys
from pathlib import Path
from cryptography.hazmat.primitives.asymmetric import ed25519
root = Path('.')
pub = base64.urlsafe_b64decode((root / 'kit' / 'ed25519.pub').read_text().strip() + '==')
env = json.loads((root / 'kit' / 'zastava-kit.tzst.dsse').read_text())
payload = (root / 'kit' / 'zastava-kit.tzst').read_bytes()
pt = env['payloadType'].encode()
pae = b' '.join([b'DSSEv1', str(len(pt)).encode(), pt, str(len(payload)).encode(), payload])
sig = base64.urlsafe_b64decode(env['signatures'][0]['sig'] + '==')
ed25519.Ed25519PublicKey.from_public_bytes(pub).verify(sig, pae)
decoded_payload = base64.urlsafe_b64decode(env['payload'] + '==')
assert decoded_payload == payload
print('OK: kit DSSE verified')
PY
```
2) Extract and run offline validation of the inner artefacts:
```bash
zstd -d kit/zastava-kit.tzst -c | tar -xf -
./kit/verify.sh
```
## Notes
- Private signing key is held offline; only the public key is shipped.
- All files are deterministic (mtime=0, numeric owners) to keep hashes stable for Evidence Locker ingestion.

View File

@@ -0,0 +1 @@
mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc

View File

@@ -1,24 +1,59 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")" && pwd)"
cd "$ROOT"
if ! command -v sha256sum >/dev/null; then
echo "sha256sum required" >&2; exit 1
fi
ROOT="$(cd "$(dirname "$0")" && pwd)"
MODULE_ROOT="${ROOT}/.."
cd "$MODULE_ROOT"
export MODULE_ROOT
command -v sha256sum >/dev/null || { echo "sha256sum required" >&2; exit 1; }
command -v python >/dev/null || { echo "python required" >&2; exit 1; }
sha256sum --check SHA256SUMS
if command -v cosign >/dev/null && [ -f cosign.pub ]; then
echo "cosign present; DSSE verification placeholders (update paths when signed):"
echo "- observer_event.schema.dsse"
echo "- webhook_admission.schema.dsse"
echo "- thresholds.dsse"
# Example commands (uncomment once DSSE files exist):
# cosign verify-blob --key cosign.pub --signature observer_event.schema.dsse schemas/observer_event.schema.json
# cosign verify-blob --key cosign.pub --signature webhook_admission.schema.dsse schemas/webhook_admission.schema.json
# cosign verify-blob --key cosign.pub --signature thresholds.dsse thresholds.yaml
else
echo "cosign not found or cosign.pub missing; skipped DSSE verification"
fi
echo "OK: hashes verified (DSSE verification pending)"
python - <<'PY'
import base64, json, os, sys
from pathlib import Path
try:
from cryptography.hazmat.primitives.asymmetric import ed25519
except Exception as exc:
raise SystemExit(f"cryptography package required for DSSE verification: {exc}")
root = Path(os.environ['MODULE_ROOT']).resolve()
pub_b64 = (root / "kit" / "ed25519.pub").read_text().strip()
pub = base64.urlsafe_b64decode(pub_b64 + "==")
verifier = ed25519.Ed25519PublicKey.from_public_bytes(pub)
def pae(payload_type: bytes, payload: bytes) -> bytes:
parts = [b"DSSEv1", str(len(payload_type)).encode(), payload_type, str(len(payload)).encode(), payload]
return b" ".join(parts)
def verify(name: str, payload_path: Path, envelope_path: Path, payload_type: str):
payload = payload_path.read_bytes()
envelope = json.loads(envelope_path.read_text())
if envelope.get("payloadType") != payload_type:
raise SystemExit(f"{name}: payloadType mismatch ({envelope.get('payloadType')} != {payload_type})")
if not envelope.get("signatures"):
raise SystemExit(f"{name}: missing signatures")
sig_entry = envelope["signatures"][0]
sig = base64.urlsafe_b64decode(sig_entry["sig"] + "==")
decoded_payload = base64.urlsafe_b64decode(envelope["payload"] + "==")
if decoded_payload != payload:
raise SystemExit(f"{name}: payload body mismatch vs envelope")
verifier.verify(sig, pae(payload_type.encode(), payload))
print(f"OK: {name}")
targets = [
("observer schema", root / "schemas" / "observer_event.schema.json", root / "schemas" / "observer_event.schema.json.dsse", "application/vnd.stellaops.zastava.schema+json;name=observer_event;version=1"),
("webhook schema", root / "schemas" / "webhook_admission.schema.json", root / "schemas" / "webhook_admission.schema.json.dsse", "application/vnd.stellaops.zastava.schema+json;name=webhook_admission;version=1"),
("thresholds", root / "thresholds.yaml", root / "thresholds.yaml.dsse", "application/vnd.stellaops.zastava.thresholds+yaml;version=1"),
("observer exports", root / "exports" / "observer_events.ndjson", root / "exports" / "observer_events.ndjson.dsse", "application/vnd.stellaops.zastava.observer-events+ndjson;version=1"),
("webhook exports", root / "exports" / "webhook_admissions.ndjson", root / "exports" / "webhook_admissions.ndjson.dsse", "application/vnd.stellaops.zastava.webhook-admissions+ndjson;version=1"),
]
for name, payload_path, envelope_path, ptype in targets:
verify(name, payload_path, envelope_path, ptype)
PY
echo "OK: SHA256 + DSSE signatures verified"

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
# Zastava schemas (runtime & admission)
## Canonicalisation & hashing
- JSON is stored with sorted keys and two-space indentation; hashes use **JCS-style** encoding: `json.dumps(payload, separators=(',', ':'), sort_keys=True)`.
- `payload_hash` fields in examples and exports are computed from the canonical payload bytes and formatted as `sha256:<hex>`.
- Schema negotiation stays on the `zastava.*@v1.x` line; breaking changes bump the major version.
## DSSE signing
- Payload types:
- `application/vnd.stellaops.zastava.schema+json;name=observer_event;version=1`
- `application/vnd.stellaops.zastava.schema+json;name=webhook_admission;version=1`
- Ed25519 public key (base64url, no padding): `mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc`.
- Signatures are emitted as `<file>.dsse` with DSSEv1 pre-auth encoding over the raw file bytes.
- Regenerate signatures with `docs/modules/zastava/kit/verify.sh` prerequisites (Python + cryptography) and the private key held offline.
## Test vectors
- Example payloads: `schemas/examples/*.json`.
- Signed exports: `exports/observer_events.ndjson(.dsse)` and `exports/webhook_admissions.ndjson(.dsse)`.
- Kit verification aggregates all signatures via `kit/verify.sh`.

View File

@@ -1,19 +1,19 @@
{
"tenant_id": "tenant-a",
"project_id": "proj-123",
"sensor_id": "observer-01",
"event_type": "runtime_fact",
"firmware_version": "1.2.3",
"policy_hash": "sha256:deadbeef",
"graph_revision_id": "graph-r1",
"ledger_id": "ledger-789",
"replay_manifest": "manifest-r1",
"event_type": "runtime_fact",
"observed_at": "2025-12-02T00:00:00Z",
"monotonic_nanos": 123456789,
"observed_at": "2025-12-02T00:00:00Z",
"payload": {
"process": "nginx",
"pid": 4242
"pid": 4242,
"process": "nginx"
},
"payload_hash": "sha256:payloadhash",
"signature": "dsse://observer-event"
"payload_hash": "sha256:7476a5068a3f0780c552f81c90d061d9e39c37f425a243ecff961b08676546fd",
"policy_hash": "sha256:deadbeef",
"project_id": "proj-123",
"replay_manifest": "manifest-r1",
"sensor_id": "observer-01",
"signature": "dsse://observer-events/2025-12-02/observer_events.ndjson.dsse#line1",
"tenant_id": "tenant-a"
}

View File

@@ -1,21 +1,34 @@
{
"tenant_id": "tenant-a",
"project_id": "proj-123",
"request_uid": "abcd-1234",
"resource_kind": "Deployment",
"namespace": "prod",
"workload_name": "api",
"policy_hash": "sha256:deadbeef",
"bypass_waiver_id": null,
"decision": "allow",
"decision_at": "2025-12-02T00:00:00Z",
"decision_reason": "surface cache fresh",
"graph_revision_id": "graph-r1",
"ledger_id": "ledger-789",
"replay_manifest": "manifest-r1",
"manifest_pointer": "surfacefs://cache/sha256:abc",
"decision": "allow",
"decision_reason": "surface cache fresh",
"decision_at": "2025-12-02T00:00:00Z",
"monotonic_nanos": 2233445566,
"namespace": "prod",
"payload": {
"images": [
{
"digest": "sha256:abcd",
"name": "ghcr.io/acme/api:1.2.3",
"sbom_referrer": true,
"signed": true
}
],
"manifest_pointer": "surfacefs://cache/sha256:abc",
"policy_hash": "sha256:deadbeef",
"verdict": "allow"
},
"payload_hash": "sha256:36bfb2bc81b7050bbb508e12cafe7ad5a51336aad397ef3a23b0e258aed73dc6",
"policy_hash": "sha256:deadbeef",
"project_id": "proj-123",
"replay_manifest": "manifest-r1",
"request_uid": "abcd-1234",
"resource_kind": "Deployment",
"side_effect": "none",
"bypass_waiver_id": null,
"payload_hash": "sha256:payloadhash",
"signature": "dsse://webhook-admission"
"signature": "dsse://webhook-admissions/2025-12-02/webhook_admissions.ndjson.dsse#line1",
"tenant_id": "tenant-a",
"workload_name": "api"
}

View File

@@ -1,8 +1,67 @@
{
"$id": "https://stella-ops.org/schemas/zastava/observer_event.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Zastava Observer Event",
"type": "object",
"properties": {
"event_type": {
"enum": [
"runtime_fact",
"drift",
"policy_violation",
"heartbeat"
]
},
"firmware_version": {
"minLength": 1,
"type": "string"
},
"graph_revision_id": {
"minLength": 1,
"type": "string"
},
"ledger_id": {
"type": "string"
},
"monotonic_nanos": {
"type": "integer"
},
"observed_at": {
"format": "date-time",
"type": "string"
},
"payload": {
"description": "Canonical runtime payload (JCS) used for hashing.",
"type": "object"
},
"payload_hash": {
"description": "sha256 over canonical JSON (JCS) of payload",
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
},
"policy_hash": {
"minLength": 1,
"type": "string"
},
"project_id": {
"minLength": 1,
"type": "string"
},
"replay_manifest": {
"type": "string"
},
"sensor_id": {
"minLength": 1,
"type": "string"
},
"signature": {
"description": "DSSE envelope reference",
"pattern": "^dsse://[A-Za-z0-9._:/-]+$",
"type": "string"
},
"tenant_id": {
"minLength": 1,
"type": "string"
}
},
"required": [
"tenant_id",
"project_id",
@@ -12,23 +71,10 @@
"graph_revision_id",
"event_type",
"observed_at",
"payload",
"payload_hash",
"signature"
"signature"
],
"properties": {
"tenant_id": { "type": "string" },
"project_id": { "type": "string" },
"sensor_id": { "type": "string" },
"firmware_version": { "type": "string" },
"policy_hash": { "type": "string" },
"graph_revision_id": { "type": "string" },
"ledger_id": { "type": "string" },
"replay_manifest": { "type": "string" },
"event_type": { "enum": ["runtime_fact", "drift", "policy_violation", "heartbeat"] },
"observed_at": { "type": "string", "format": "date-time" },
"monotonic_nanos": { "type": "integer" },
"payload": { "type": "object" },
"payload_hash": { "type": "string", "description": "sha256 over canonical JSON (JCS) of payload" },
"signature": { "type": "string", "description": "DSSE envelope reference" }
}
"title": "Zastava Observer Event",
"type": "object"
}

View File

@@ -0,0 +1,10 @@
{
"payload": "ewogICIkaWQiOiAiaHR0cHM6Ly9zdGVsbGEtb3BzLm9yZy9zY2hlbWFzL3phc3RhdmEvb2JzZXJ2ZXJfZXZlbnQuc2NoZW1hLmpzb24iLAogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInByb3BlcnRpZXMiOiB7CiAgICAiZXZlbnRfdHlwZSI6IHsKICAgICAgImVudW0iOiBbCiAgICAgICAgInJ1bnRpbWVfZmFjdCIsCiAgICAgICAgImRyaWZ0IiwKICAgICAgICAicG9saWN5X3Zpb2xhdGlvbiIsCiAgICAgICAgImhlYXJ0YmVhdCIKICAgICAgXQogICAgfSwKICAgICJmaXJtd2FyZV92ZXJzaW9uIjogewogICAgICAibWluTGVuZ3RoIjogMSwKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJncmFwaF9yZXZpc2lvbl9pZCI6IHsKICAgICAgIm1pbkxlbmd0aCI6IDEsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAibGVkZ2VyX2lkIjogewogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgIm1vbm90b25pY19uYW5vcyI6IHsKICAgICAgInR5cGUiOiAiaW50ZWdlciIKICAgIH0sCiAgICAib2JzZXJ2ZWRfYXQiOiB7CiAgICAgICJmb3JtYXQiOiAiZGF0ZS10aW1lIiwKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJwYXlsb2FkIjogewogICAgICAiZGVzY3JpcHRpb24iOiAiQ2Fub25pY2FsIHJ1bnRpbWUgcGF5bG9hZCAoSkNTKSB1c2VkIGZvciBoYXNoaW5nLiIsCiAgICAgICJ0eXBlIjogIm9iamVjdCIKICAgIH0sCiAgICAicGF5bG9hZF9oYXNoIjogewogICAgICAiZGVzY3JpcHRpb24iOiAic2hhMjU2IG92ZXIgY2Fub25pY2FsIEpTT04gKEpDUykgb2YgcGF5bG9hZCIsCiAgICAgICJwYXR0ZXJuIjogIl5zaGEyNTY6WzAtOWEtZl17NjR9JCIsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAicG9saWN5X2hhc2giOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInByb2plY3RfaWQiOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInJlcGxheV9tYW5pZmVzdCI6IHsKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJzZW5zb3JfaWQiOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInNpZ25hdHVyZSI6IHsKICAgICAgImRlc2NyaXB0aW9uIjogIkRTU0UgZW52ZWxvcGUgcmVmZXJlbmNlIiwKICAgICAgInBhdHRlcm4iOiAiXmRzc2U6Ly9bQS1aYS16MC05Ll86Ly1dKyQiLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInRlbmFudF9pZCI6IHsKICAgICAgIm1pbkxlbmd0aCI6IDEsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0KICB9LAogICJyZXF1aXJlZCI6IFsKICAgICJ0ZW5hbnRfaWQiLAogICAgInByb2plY3RfaWQiLAogICAgInNlbnNvcl9pZCIsCiAgICAiZmlybXdhcmVfdmVyc2lvbiIsCiAgICAicG9saWN5X2hhc2giLAogICAgImdyYXBoX3JldmlzaW9uX2lkIiwKICAgICJldmVudF90eXBlIiwKICAgICJvYnNlcnZlZF9hdCIsCiAgICAicGF5bG9hZCIsCiAgICAicGF5bG9hZF9oYXNoIiwKICAgICJzaWduYXR1cmUiCiAgXSwKICAidGl0bGUiOiAiWmFzdGF2YSBPYnNlcnZlciBFdmVudCIsCiAgInR5cGUiOiAib2JqZWN0Igp9Cg",
"payloadType": "application/vnd.stellaops.zastava.schema+json;name=observer_event;version=1",
"signatures": [
{
"keyid": "mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc",
"sig": "axmdd1ucHyZyJMAyLzWmpuai7VrS20QenSDQyXRKlmtsAF4Zl4Ke_cHy8konBStBCoJgGA3SM2236QgAbkQMBw"
}
]
}

View File

@@ -1,8 +1,91 @@
{
"$id": "https://stella-ops.org/schemas/zastava/webhook_admission.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Zastava Webhook Admission",
"type": "object",
"properties": {
"bypass_waiver_id": {
"type": "string"
},
"decision": {
"enum": [
"allow",
"deny",
"dry-run"
]
},
"decision_at": {
"format": "date-time",
"type": "string"
},
"decision_reason": {
"minLength": 1,
"type": "string"
},
"graph_revision_id": {
"minLength": 1,
"type": "string"
},
"ledger_id": {
"type": "string"
},
"manifest_pointer": {
"description": "Surface.FS manifest pointer",
"type": "string"
},
"monotonic_nanos": {
"type": "integer"
},
"namespace": {
"minLength": 1,
"type": "string"
},
"payload": {
"description": "AdmissionReview payload (canonical JSON) hashed via payload_hash",
"type": "object"
},
"payload_hash": {
"pattern": "^sha256:[0-9a-f]{64}$",
"type": "string"
},
"policy_hash": {
"minLength": 1,
"type": "string"
},
"project_id": {
"minLength": 1,
"type": "string"
},
"replay_manifest": {
"type": "string"
},
"request_uid": {
"minLength": 1,
"type": "string"
},
"resource_kind": {
"minLength": 1,
"type": "string"
},
"side_effect": {
"enum": [
"none",
"mutating",
"bypass"
]
},
"signature": {
"description": "DSSE envelope reference",
"pattern": "^dsse://[A-Za-z0-9._:/-]+$",
"type": "string"
},
"tenant_id": {
"minLength": 1,
"type": "string"
},
"workload_name": {
"minLength": 1,
"type": "string"
}
},
"required": [
"tenant_id",
"project_id",
@@ -16,27 +99,10 @@
"decision_reason",
"decision_at",
"manifest_pointer",
"payload",
"payload_hash",
"signature"
],
"properties": {
"tenant_id": { "type": "string" },
"project_id": { "type": "string" },
"request_uid": { "type": "string" },
"resource_kind": { "type": "string" },
"namespace": { "type": "string" },
"workload_name": { "type": "string" },
"policy_hash": { "type": "string" },
"graph_revision_id": { "type": "string" },
"ledger_id": { "type": "string" },
"replay_manifest": { "type": "string" },
"manifest_pointer": { "type": "string", "description": "Surface.FS manifest pointer" },
"decision": { "enum": ["allow", "deny", "dry-run"] },
"decision_reason": { "type": "string" },
"decision_at": { "type": "string", "format": "date-time" },
"monotonic_nanos": { "type": "integer" },
"side_effect": { "enum": ["none", "mutating", "bypass"] },
"bypass_waiver_id": { "type": "string" },
"payload_hash": { "type": "string" },
"signature": { "type": "string", "description": "DSSE envelope reference" }
}
"title": "Zastava Webhook Admission",
"type": "object"
}

View File

@@ -0,0 +1,10 @@
{
"payload": "ewogICIkaWQiOiAiaHR0cHM6Ly9zdGVsbGEtb3BzLm9yZy9zY2hlbWFzL3phc3RhdmEvd2ViaG9va19hZG1pc3Npb24uc2NoZW1hLmpzb24iLAogICIkc2NoZW1hIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDcvc2NoZW1hIyIsCiAgInByb3BlcnRpZXMiOiB7CiAgICAiYnlwYXNzX3dhaXZlcl9pZCI6IHsKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJkZWNpc2lvbiI6IHsKICAgICAgImVudW0iOiBbCiAgICAgICAgImFsbG93IiwKICAgICAgICAiZGVueSIsCiAgICAgICAgImRyeS1ydW4iCiAgICAgIF0KICAgIH0sCiAgICAiZGVjaXNpb25fYXQiOiB7CiAgICAgICJmb3JtYXQiOiAiZGF0ZS10aW1lIiwKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJkZWNpc2lvbl9yZWFzb24iOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgImdyYXBoX3JldmlzaW9uX2lkIjogewogICAgICAibWluTGVuZ3RoIjogMSwKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJsZWRnZXJfaWQiOiB7CiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAibWFuaWZlc3RfcG9pbnRlciI6IHsKICAgICAgImRlc2NyaXB0aW9uIjogIlN1cmZhY2UuRlMgbWFuaWZlc3QgcG9pbnRlciIsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAibW9ub3RvbmljX25hbm9zIjogewogICAgICAidHlwZSI6ICJpbnRlZ2VyIgogICAgfSwKICAgICJuYW1lc3BhY2UiOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInBheWxvYWQiOiB7CiAgICAgICJkZXNjcmlwdGlvbiI6ICJBZG1pc3Npb25SZXZpZXcgcGF5bG9hZCAoY2Fub25pY2FsIEpTT04pIGhhc2hlZCB2aWEgcGF5bG9hZF9oYXNoIiwKICAgICAgInR5cGUiOiAib2JqZWN0IgogICAgfSwKICAgICJwYXlsb2FkX2hhc2giOiB7CiAgICAgICJwYXR0ZXJuIjogIl5zaGEyNTY6WzAtOWEtZl17NjR9JCIsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAicG9saWN5X2hhc2giOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInByb2plY3RfaWQiOiB7CiAgICAgICJtaW5MZW5ndGgiOiAxLAogICAgICAidHlwZSI6ICJzdHJpbmciCiAgICB9LAogICAgInJlcGxheV9tYW5pZmVzdCI6IHsKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJyZXF1ZXN0X3VpZCI6IHsKICAgICAgIm1pbkxlbmd0aCI6IDEsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAicmVzb3VyY2Vfa2luZCI6IHsKICAgICAgIm1pbkxlbmd0aCI6IDEsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAic2lkZV9lZmZlY3QiOiB7CiAgICAgICJlbnVtIjogWwogICAgICAgICJub25lIiwKICAgICAgICAibXV0YXRpbmciLAogICAgICAgICJieXBhc3MiCiAgICAgIF0KICAgIH0sCiAgICAic2lnbmF0dXJlIjogewogICAgICAiZGVzY3JpcHRpb24iOiAiRFNTRSBlbnZlbG9wZSByZWZlcmVuY2UiLAogICAgICAicGF0dGVybiI6ICJeZHNzZTovL1tBLVphLXowLTkuXzovLV0rJCIsCiAgICAgICJ0eXBlIjogInN0cmluZyIKICAgIH0sCiAgICAidGVuYW50X2lkIjogewogICAgICAibWluTGVuZ3RoIjogMSwKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfSwKICAgICJ3b3JrbG9hZF9uYW1lIjogewogICAgICAibWluTGVuZ3RoIjogMSwKICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgfQogIH0sCiAgInJlcXVpcmVkIjogWwogICAgInRlbmFudF9pZCIsCiAgICAicHJvamVjdF9pZCIsCiAgICAicmVxdWVzdF91aWQiLAogICAgInJlc291cmNlX2tpbmQiLAogICAgIm5hbWVzcGFjZSIsCiAgICAid29ya2xvYWRfbmFtZSIsCiAgICAicG9saWN5X2hhc2giLAogICAgImdyYXBoX3JldmlzaW9uX2lkIiwKICAgICJkZWNpc2lvbiIsCiAgICAiZGVjaXNpb25fcmVhc29uIiwKICAgICJkZWNpc2lvbl9hdCIsCiAgICAibWFuaWZlc3RfcG9pbnRlciIsCiAgICAicGF5bG9hZCIsCiAgICAicGF5bG9hZF9oYXNoIiwKICAgICJzaWduYXR1cmUiCiAgXSwKICAidGl0bGUiOiAiWmFzdGF2YSBXZWJob29rIEFkbWlzc2lvbiIsCiAgInR5cGUiOiAib2JqZWN0Igp9Cg",
"payloadType": "application/vnd.stellaops.zastava.schema+json;name=webhook_admission;version=1",
"signatures": [
{
"keyid": "mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc",
"sig": "Vk0mACAjBtUuVn_S2M5HU81zMbH8wDCQYOHVsft7cmxl0JbDrSIA9z3xlTI5JiT7DYOGsDUc96dlC1njldN4Aw"
}
]
}

View File

@@ -0,0 +1,10 @@
{
"payload": "dmVyc2lvbjogMQp1cGRhdGVkX2F0OiAyMDI1LTEyLTAyVDAwOjAwOjAwWgpidWRnZXRzOgogIGxhdGVuY3lfbXNfcDk1OiAyNTAKICBlcnJvcl9yYXRlOiAwLjAxCiAgZHJvcF9yYXRlOiAwLjAwNQpidXJuX3JhdGVzOgogIGFkbWlzc2lvbl9kZW5pZXNfcGVyX21pbjogNQogIG9ic2VydmVyX2RyaWZ0c19wZXJfaG91cjogMgogIGhlYXJ0YmVhdF9taXNzX21pbnV0ZXM6IDMKYWxlcnRzOgogIHRocmVzaG9sZF9jaGFuZ2U6IHRydWUKICBidXJuX3JhdGVfZXhjZWVkZWQ6IHRydWUKICBraWxsX3N3aXRjaF90cmlnZ2VyZWQ6IHRydWUKc2lnbmluZzoKICBwcmVkaWNhdGU6IHN0ZWxsYS5vcHMvemFzdGF2YVRocmVzaG9sZHNAdjEKICBkc3NlX3JlcXVpcmVkOiB0cnVlCg",
"payloadType": "application/vnd.stellaops.zastava.thresholds+yaml;version=1",
"signatures": [
{
"keyid": "mpIEbYRL1q5yhN6wBRvkZ_0xXz3QUJPueJJ8sn__GGc",
"sig": "uQFBmx7vF4fj8uQsCiCN6VbxNS2m3XM-vJNFrj3rexL1PPzHH6IVtWRGexF7CsLrrpUV8U0AmS02S37vOk3zDA"
}
]
}

View File

@@ -44,6 +44,42 @@ This advisory consolidates late-November gap findings across Scanner, SBOM/VEX s
9. **CM9 — Ecosystem coverage**: Track coverage per ecosystem (container, Java, Python, .NET, Go, OS packages) and gaps for ingest support.
10. **CM10 — Error resilience & retries**: Standardize retry/backoff/error classification for ingest pipeline; surface diagnostics deterministically.
## OK (Offline Kit) Gaps — OK1OK10
1. **OK1 — Key manifest + PQ co-sign**: Record key IDs and PQ dual-sign toggle in bundle meta; rotate keys ≤90 days. Evidence: `out/mirror/thin/mirror-thin-v1.bundle.json` (`chain_of_custody.keyid`) and `layers/offline-kit-policy.json`.
2. **OK2 — Tool hashing/signing**: Hash build/sign/verify tools and pin them in bundle meta (`tooling.*`); DSSE envelopes cover manifest + bundle meta.
3. **OK3 — DSSE top-level manifest**: Ship DSSE for bundle meta (`mirror-thin-v1.bundle.dsse.json`) linking manifest, tarball, policies, and optional OCI layout.
4. **OK4 — Checkpoint freshness + mirror metadata**: Enforce `checkpoint_freshness_seconds` and timestamped `created` in bundle meta; require checkpoints in `transport-plan.json`.
5. **OK5 — Deterministic packaging flags**: Capture tar/gzip flags in `layers/offline-kit-policy.json` and verify via `scripts/mirror/verify_thin_bundle.py` determinism checks.
6. **OK6 — Scan/VEX/policy/graph hashes**: Include `layers/artifact-hashes.json` with digests for scan/vex/policy/graph fixtures and reference from bundle meta.
7. **OK7 — Time anchor bundling**: Embed `layers/time-anchor.json` digest in bundle meta and surface trust-root path for AIRGAP-TIME.
8. **OK8 — Transport/chunking + chain-of-custody**: Define chunk sizing, retry policy, and signed chain-of-custody in `layers/transport-plan.json` (includes build/sign digests + keyid).
9. **OK9 — Tenant/environment scoping**: Require `tenant`/`environment` fields in bundle meta; verifier enforces via `--tenant/--environment` flags.
10. **OK10 — Scripted verify + negative paths**: `scripts/mirror/verify_thin_bundle.py` validates required layers, DSSE, sidecars, tool hashes, and scope; fails fast on missing/stale artefacts.
## RK (Rekor) Gaps — RK1RK10
1. **RK1 — DSSE/hashedrekord only**: `layers/rekor-policy.json` sets `rk1_enforceDsse=true` and routes both public/private to hashedrekord.
2. **RK2 — Payload size preflight + chunks**: `rk2_payloadMaxBytes=1048576` with chunking guidance in `transport-plan.json`.
3. **RK3 — Public/private routing policy**: Explicit routing map (`rk3_routing`) for shard-aware submission.
4. **RK4 — Shard-aware checkpoints**: `rk4_shardCheckpoint="per-tenant-per-day"` plus checkpoint freshness from bundle meta.
5. **RK5 — Idempotent submission keys**: `rk5_idempotentKeys=true` to prevent duplicate entries.
6. **RK6 — Sigstore bundles in kits**: `rk6_sigstoreBundleIncluded=true`; bundle meta lists DSSE artefacts for offline kits.
7. **RK7 — Checkpoint freshness bounds**: `rk7_checkpointFreshnessSeconds` mirrors bundle freshness budget.
8. **RK8 — PQ dual-sign options**: `rk8_pqDualSign` mirrors PQ toggle (env `PQ_CO_SIGN_REQUIRED`).
9. **RK9 — Error taxonomy/backoff**: Enumerated in `rk9_errorTaxonomy` and retried per `transport-plan.json` retry policy.
10. **RK10 — Policy/graph annotations**: `rk10_annotations` require policy + graph context inside DSSE/bundle records.
## MS (Mirror Strategy) Gaps — MS1MS10
1. **MS1 — Signed/versioned mirror schemas**: `layers/mirror-policy.json` tracks `schemaVersion` + semver; DSSE of bundle meta ties schema to artefacts.
2. **MS2 — DSSE/TUF rotation policy (incl. PQ)**: `dsseTufRotationDays=30` and `pqDualSign` toggle documented in mirror policy and bundle meta.
3. **MS3 — Delta spec with tombstones/base hash**: Mirror policy `delta` enforces tombstones and base-hash requirements for deltas.
4. **MS4 — Time-anchor freshness enforcement**: `timeAnchorFreshnessSeconds` plus bundled `time-anchor.json` digest.
5. **MS5 — Tenant/env scoping**: Tenant/environment fields required in bundle meta; verifier flags mismatches.
6. **MS6 — Distribution integrity (HTTP/OCI/object)**: `distributionIntegrity` enumerates integrity strategies for each transport.
7. **MS7 — Chunking/size rules**: `chunking.sizeBytes` + `maxChunks` pinned in mirror policy and reflected in transport plan.
8. **MS8 — Standard verify script**: `verifyScript` references `scripts/mirror/verify_thin_bundle.py`; bundle meta recorded in DSSE envelope.
9. **MS9 — Metrics/alerts**: Mirror policy `metrics` marks build/import/verify signals required for observability.
10. **MS10 — SemVer/change log**: `changelog` block declares current format version; future bumps must be appended with deterministic notes.
## Pending Families (to be expanded)
The following gap families were referenced in November indices and still need detailed findings written out:
- CV1CV10 (CVSS v4 receipts), CVM1CVM10 (momentum), FC1FC10 (SCA fixture gaps), OB1OB10 (onboarding), IG1IG10 (implementor guidance), RR1RR10 (Rekor receipts), SK1SK10 (standups), MI1MI10 (UI micro-interactions), PVX1PVX10 (Proof-linked VEX UI), TTE1TTE10 (Time-to-Evidence), AR-EP1…AR-VB1 (archived advisories revival), BP1BP10 (SBOM→VEX proof pipeline), UT1UT10 (unknown heuristics), CE1CE10 (evidence patterns), ET1ET10 (ecosystem fixtures), RB1RB10 (reachability fixtures), G1G12 / RD1RD10 (reachability benchmark/dataset), UN1UN10 (unknowns registry), U1U10 (decay), EX1EX10 (explainability), VEX1VEX10 (VEX claims), BR1BR10 (binary reachability), VT1VT10 (triage), PL1PL10 (plugin arch), EB1EB10 (evidence baseline), EC1EC10 (export center), AT1AT10 (automation), OK1OK10 / RK1RK10 / MS1MS10 (offline/mirror/Rekor kits), TP1TP10 (task packs), AU1AU10 (auth), CL1CL10 (CLI), OR1OR10 (orchestrator), ZR1ZR10 (Zastava), NR1NR10 (Notify), GA1GA10 (graph analytics), TO1TO10 (telemetry), PS1PS10 (policy), FL1FL10 (ledger), CI1CI10 (Concelier ingest).

View File

@@ -42,6 +42,7 @@ Out of scope: implementing disassemblers or symbol servers; those will be handle
* Update analyzer contracts so every analyzer returns both `symbol_id` and `code_id`, with demangled names stored under the new `symbol` block.
* Persist the data into `richgraph-v1` payloads and attach CAS URIs via `StellaOps.Scanner.Reachability`.
* Deliver fixtures in `tests/reachability/StellaOps.ScannerSignals.IntegrationTests` that prove determinism (same hash when analyzer flags reorder).
* **Helper status (2025-12-02):** `SymbolId.ForBinaryAddressed` + `CodeId.ForBinarySegment` now encode `{file_hash, section, addr, name, linkage, length, code_block_hash}` with normalized hex addresses. Analyzers should start emitting these tuples instead of ad-hoc hashes.
### 3.2 Runtime + Signals (GAP-ZAS-002 / GAP-SIG-003)