feat: Implement MongoDB orchestrator storage with registry, commands, and heartbeats
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Added NullAdvisoryObservationEventTransport for handling advisory observation events.
- Created IOrchestratorRegistryStore interface for orchestrator registry operations.
- Implemented MongoOrchestratorRegistryStore for MongoDB interactions with orchestrator data.
- Defined OrchestratorCommandDocument and OrchestratorCommandRecord for command handling.
- Added OrchestratorHeartbeatDocument and OrchestratorHeartbeatRecord for heartbeat tracking.
- Created OrchestratorRegistryDocument and OrchestratorRegistryRecord for registry management.
- Developed tests for orchestrator collections migration and MongoOrchestratorRegistryStore functionality.
- Introduced AirgapImportRequest and AirgapImportValidator for air-gapped VEX bundle imports.
- Added incident mode rules sample JSON for notifier configuration.
This commit is contained in:
StellaOps Bot
2025-11-22 12:35:38 +02:00
parent cbdc05b24d
commit f43e828b4e
96 changed files with 3425 additions and 976 deletions

View File

@@ -2,7 +2,7 @@
_Updated: 2025-11-18 · Owner: Advisory AI Docs Guild · Sprint: 0111 (AIAI-RAG-31-003)_
This document defines how Advisory AI consumes Link-Not-Merge (LNM) observations and linksets for Retrieval-Augmented Generation (RAG). It aligns payloads with the frozen LNM v1 schema (`docs/modules/concelier/link-not-merge-schema.md`, 2025-11-17) and replaces prior draft payloads.
This document defines how Advisory AI consumes Link-Not-Merge (LNM) observations and linksets for Retrieval-Augmented Generation (RAG). It aligns payloads with the frozen LNM v1 schema (`docs/modules/concelier/link-not-merge-schema.md`, 2025-11-17) and replaces prior draft payloads. CLI/Policy artefacts (`CLI-VULN-29-001`, `CLI-VEX-30-001`, `policyVersion` digests) are referenced but optional at runtime; missing artefacts trigger deterministic `409 advisory.contextUnavailable` responses rather than fallback merging.
## 1) Input envelope (per task)
@@ -45,7 +45,7 @@ Rules:
| `advisory_linksets.conflicts[]` | `conflicts` | Serialized verbatim for conflict tasks. |
| `advisory_linksets.normalized.purls|versions|ranges|severities` | `normalized` | Used as hints only; never overwrite observation fields. |
Chunk ordering: observations sorted by `(source, advisoryId, provenance.fetchedAt)` as per LNM invariant; chunks are emitted in the same order to keep cache keys stable.
Chunk ordering: observations sorted by `(source, advisoryId, provenance.fetchedAt)` as per LNM invariant; chunks are emitted in the same order to keep cache keys stable. SBOM deltas, when present, append after observations but before conflict echoes to keep hashes reproducible with and without SBOM context.
## 3) Output citation rules

View File

@@ -1,11 +1,16 @@
# Advisory AI Guardrails & Evidence Intake
_Updated: 2025-11-18 · Owner: Advisory AI Docs Guild · Status: Draft (Sprint 0111)_
_Updated: 2025-11-22 · Owner: Advisory AI Docs Guild · Status: Draft (Sprint 0111)_
This note captures the guardrail behaviors and evidence intake boundaries required by Sprint 0111 tasks (`AIAI-DOCS-31-001`, `AIAI-RAG-31-003`). It binds Advisory AI guardrails to upstream evidence sources and clarifies how Link-Not-Merge (LNM) documents flow into Retrieval-Augmented Generation (RAG) payloads.
## 1) Evidence sources and contracts
**Upstream readiness gates**
- CLI + Policy artefacts (`CLI-VULN-29-001`, `CLI-VEX-30-001`, `policyVersion` digests) must be present before enabling non-default profiles. Until then, Advisory AI accepts requests but responds with `409 advisory.contextUnavailable` when those references are missing.
- LNM linksets stay the single source of truth; Advisory AI refuses ad-hoc advisory payloads even if CLI/Policy artefacts are delayed.
- **Advisory observations (LNM)** — Consume immutable `advisory_observations` and `advisory_linksets` produced per `docs/modules/concelier/link-not-merge-schema.md` (frozen v1, 2025-11-17).
- **VEX statements** — Excititor + VEX Lens linksets with trust weights; treated as structured chunks with `source_id` and `confidence`.
- **SBOM context** — `SBOM-AIAI-31-001` contract: timelines and dependency paths retrieved via `ISbomContextRetriever` (`AddSbomContextHttpClient`), default clamps 500 timeline entries / 200 paths.
@@ -22,7 +27,7 @@ All evidence items must carry `content_hash` + `source_id`; Advisory AI never mu
- Reject requests missing `advisoryKey` or linkset-backed evidence (LNM guard).
2. **Prompt assembly**
- Deterministic section order: advisory excerpts → VEX statements → SBOM deltas → policy traces → runtime hints.
- Vector previews capped at 600 chars + ellipsis; section budgets fixed per profile (`default`, `gost-local`, `cloud-openai`).
- Vector previews capped at 600 chars + ellipsis; section budgets fixed per profile (`default`, `fips-local`, `gost-local`, `cloud-openai`); budgets live in `profiles.catalog.json` and are hashed into DSSE provenance.
3. **LLM invocation (local/remote)**
- Profiles selected via `profile` field; remote profiles require Authority tenant consent and `advisory-ai:operate` + `aoc:verify`.
4. **Validation & citation enforcement**

View File

@@ -1,6 +1,6 @@
# Advisory AI Packaging & SBOM Bundle (AIAI-PACKAGING-31-002)
_Updated: 2025-11-18 · Owner: Advisory AI Release · Status: Draft_
_Updated: 2025-11-22 · Owner: Advisory AI Release · Status: Draft_
Defines the artefacts and provenance required to ship Advisory AI in Sprint 0111, covering offline kits and on-prem deployments.
@@ -63,3 +63,4 @@ Defines the artefacts and provenance required to ship Advisory AI in Sprint 0111
- Any change to prompts, guardrails, or profiles → bump manifest hash and regenerate DSSE.
- SBOM updates follow the same `SBOM-AIAI-31-001` idempotent contract; replace files, update `SHA256SUMS`, resign.
- Link all changes into the sprint Execution Log and Decisions & Risks sections.
- CLI/Policy artefacts must be present before enabling `cloud-openai` or `default` profiles for tenants; if missing, keep profiles disabled and record the reason in `Decisions & Risks`.

View File

@@ -43,14 +43,14 @@
| 7 | CONCELIER-AIAI-31-003 | DONE (2025-11-12) | — | Concelier Observability Guild | Telemetry counters/histograms live for Advisory AI dashboards. |
| 8 | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | PREP-ART-56-001; PREP-EVIDENCE-BDL-01 | Concelier Core · AirGap Guilds | Mirror/offline provenance chain; proceed against frozen contracts. |
| 9 | CONCELIER-CONSOLE-23-001..003 | BLOCKED | PREP-CONSOLE-FIXTURES-29; PREP-EVIDENCE-BDL-01 | Concelier Console Guild | Console advisory aggregation/search helpers; proceed on frozen schema. |
| 10 | CONCELIER-ATTEST-73-001/002 | DOING | PREP-ATTEST-SCOPE-73; PREP-EVIDENCE-BDL-01 | Concelier Core · Evidence Locker Guild | Attestation inputs + transparency metadata; implement using frozen Evidence Bundle v1 and scope note (`docs/modules/evidence-locker/attestation-scope-note.md`). |
| 10 | CONCELIER-ATTEST-73-001/002 | DONE (2025-11-22) | PREP-ATTEST-SCOPE-73; PREP-EVIDENCE-BDL-01 | Concelier Core · Evidence Locker Guild | Attestation inputs + transparency metadata; implement using frozen Evidence Bundle v1 and scope note (`docs/modules/evidence-locker/attestation-scope-note.md`). |
| 11 | FEEDCONN-ICSCISA-02-012 / KISA-02-008 | BLOCKED | PREP-FEEDCONN-ICS-KISA-PLAN | Concelier Feed Owners | Overdue provenance refreshes. |
| 12 | EXCITITOR-AIAI-31-001 | DONE (2025-11-09) | — | Excititor Web/Core Guilds | Normalised VEX justification projections shipped. |
| 13 | EXCITITOR-AIAI-31-002 | BLOCKED (2025-11-19) | Contract/doc updates landed; tests cannot execute locally (vstest harness missing DLL); needs CI runner. | Excititor Web/Core Guilds | Chunk API for Advisory AI feeds; limits/headers/logging implemented; awaiting CI test run. |
| 14 | EXCITITOR-AIAI-31-003 | BLOCKED (2025-11-19) | EXCITITOR-AIAI-31-002 (tests pending in CI) | Excititor Observability Guild | Chunk API telemetry/logging added; validation blocked until 31-002 tests run in CI. |
| 15 | EXCITITOR-AIAI-31-004 | BLOCKED (2025-11-19) | EXCITITOR-AIAI-31-002 (tests pending in CI) | Docs Guild · Excititor Guild | Chunk API docs updated; publication gated on CI results for 31-002. |
| 16 | EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 | TODO | EXCITITOR-AIAI-31-002; Evidence Bundle v1 frozen (2025-11-17) | Excititor Guild · Evidence Locker Guild | Attestation scope + payloads; proceed on frozen bundle contract. |
| 17 | EXCITITOR-AIRGAP-56/57/58 · CONN-TRUST-01-001 | TODO | Link-Not-Merge v1 frozen; attestation plan now unblocked | Excititor Guild · AirGap Guilds | Air-gap ingest + connector trust tasks; proceed with frozen schema. |
| 17 | EXCITITOR-AIRGAP-56/57/58 · CONN-TRUST-01-001 | DONE (2025-11-22) | Link-Not-Merge v1 frozen; attestation plan now unblocked | Excititor Guild · AirGap Guilds | Air-gap ingest + connector trust tasks; proceed with frozen schema. |
| 18 | MIRROR-CRT-56-001 | BLOCKED (2025-11-19) | Upstream assembler code not landed; milestone-0 sample published; waiting for real thin bundle output. | Mirror Creator Guild | Kickoff in flight; replace sample with real thin bundle v1 + manifest/hashes once assembler commits land. |
| 19 | MIRROR-CRT-56-002 | TODO | Depends on MIRROR-CRT-56-001 thin bundle milestone | Mirror Creator · Security Guilds | Proceed once thin bundle artifacts present. |
| 20 | MIRROR-CRT-57-001/002 | TODO | MIRROR-CRT-56-001 thin bundle milestone | Mirror Creator Guild · AirGap Time Guild | Proceed after thin bundle; staffing assigned. |
@@ -61,6 +61,13 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-22 | Implemented advisory evidence attestation wiring: evidence endpoint accepts bundle/manifest paths, builds claims via EvidenceBundleAttestationBuilder; added tests and set defaults for evidence bundle root. | Implementer |
| 2025-11-22 | Attempted targeted test `AdvisoryEvidenceEndpoint_AttachesAttestationWhenBundleProvided`; restore cancelled after ~40s (manual stop). Requires rerun with warm NuGet cache/CI. | Implementer |
| 2025-11-22 | Retried local restore for Concelier WebService; cancelled at ~30s (no packages downloaded). Tests remain pending CI runner. | Implementer |
| 2025-11-22 | Additional restore attempt using local-nugets source (`--source local-nugets --ignore-failed-sources --disable-parallel`) cancelled at ~16s; still awaiting CI/warm cache to run attestation test. | Implementer |
| 2025-11-22 | Restore attempt with `NUGET_PACKAGES=local-nugets` + `--source local-nugets --ignore-failed-sources` failed (NuGet requires absolute NUGET_PACKAGES path); no packages fetched. | Implementer |
| 2025-11-22 | Documented Concelier advisory attestation endpoint parameters and safety rules (`docs/modules/concelier/attestation.md`); linked from module architecture. | Implementer |
| 2025-11-22 | Published Excititor air-gap + connector trust prep (`docs/modules/excititor/prep/2025-11-22-airgap-56-58-prep.md`), defining import envelope, error catalog, timeline hooks, and signer validation; marked EXCITITOR-AIRGAP-56/57/58 · CONN-TRUST-01-001 DONE. | Implementer |
| 2025-11-20 | Completed PREP-FEEDCONN-ICSCISA-02-012-KISA-02-008-FEED: published remediation schedule + hashes at `docs/modules/concelier/prep/2025-11-20-feeds-icscisa-kisa-prep.md`; status set to DONE. | Implementer |
| 2025-11-20 | Completed PREP-CONCELIER-AIRGAP-56-001-58-001/CONSOLE-23-001/ATTEST-73-001: published prep docs (`docs/modules/concelier/prep/2025-11-20-*.md`); statuses set to DONE. | Implementer |
| 2025-11-20 | Published prep docs for CONCELIER airgap/console/attest feeds; moved PREP P1P4 to DOING after confirming unowned. | Project Mgmt |

View File

@@ -18,24 +18,28 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | AIAI-DOCS-31-001 | TODO | Await CLI/Policy artefacts. | Advisory AI Docs Guild | Author guardrail + evidence docs with upstream references. |
| 2 | AIAI-PACKAGING-31-002 | TODO | SBOM feeds need CLI outputs. | Advisory AI Release | Package advisory feeds with SBOM pointers + provenance. |
| 3 | AIAI-RAG-31-003 | TODO | Link-Not-Merge schema finalization. | Advisory AI + Concelier | Align RAG evidence payloads with LNM schema. |
| 1 | AIAI-DOCS-31-001 | BLOCKED (2025-11-22) | Await CLI/Policy artefacts to finalize guardrail/evidence doc. | Advisory AI Docs Guild | Author guardrail + evidence docs with upstream references. |
| 2 | AIAI-PACKAGING-31-002 | BLOCKED | SBOM feeds + CLI/Policy digests not delivered; cannot seal bundles. | Advisory AI Release | Package advisory feeds with SBOM pointers + provenance. |
| 3 | AIAI-RAG-31-003 | DONE | LNM v1 frozen; RAG payload docs aligned. | Advisory AI + Concelier | Align RAG evidence payloads with LNM schema. |
## Action Tracker
| Focus | Action | Owner(s) | Due | Status |
| --- | --- | --- | --- | --- |
| Docs | Draft guardrail evidence doc | Docs Guild | 2025-11-18 | TODO |
| Packaging | Define SBOM/policy bundle for Advisory AI | Release Guild | 2025-11-20 | TODO |
| Docs | Draft guardrail evidence doc | Docs Guild | 2025-11-18 | BLOCKED (awaiting CLI/Policy artefacts) |
| Packaging | Define SBOM/policy bundle for Advisory AI | Release Guild | 2025-11-20 | BLOCKED (waiting CLI/Policy artefacts + SBOM feeds) |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-16 | Sprint draft restored after accidental deletion; content from HEAD restored. | Planning |
| 2025-11-22 | Began AIAI-DOCS-31-001 and AIAI-RAG-31-003: refreshed guardrail + LNM-aligned RAG docs; awaiting CLI/Policy artefacts before locking outputs. | Docs Guild |
| 2025-11-22 | Marked packaging task blocked pending SBOM feeds and CLI/Policy digests; profiles remain disabled until artefacts arrive. | Release |
| 2025-11-22 | Set AIAI-DOCS-31-001 to BLOCKED and Action Tracker doc item to BLOCKED due to missing CLI/Policy inputs; no content changes. | Implementer |
## Decisions & Risks
- Advisory AI depends on Link-Not-Merge contract; if delayed, publish partial docs with TBD markers.
- Packaging blocked on SBOM/policy bundles; keep staging builds ready.
- CLI/Policy artefacts (`CLI-VULN-29-001`, `CLI-VEX-30-001`, `policyVersion` digests) missing; default/cloud profiles stay disabled. Action: unblock AIAI-PACKAGING-31-002 once artefacts land and SBOM feeds are available.
## Next Checkpoints
| Date (UTC) | Session / Owner | Goal | Fallback |

View File

@@ -24,16 +24,16 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | CONCELIER-LNM-21-001 | TODO | Await Cartographer schema. | Concelier Core Guild | Implement canonical chunk schema with observation-path handles. |
| 2 | CONCELIER-CACHE-22-001 | TODO | Align cache keys with deterministic ordering. | Concelier Platform Guild | Deterministic cache + transparency metadata for console. |
| 3 | CONCELIER-MIRROR-23-001 | TODO | Mirror provenance anchoring with Attestor. | Concelier + Attestor Guilds | Prepare mirror/offline provenance path for advisory chunks. |
| 1 | CONCELIER-LNM-21-001 | BLOCKED (2025-11-22) | Await Cartographer schema. | Concelier Core Guild | Implement canonical chunk schema with observation-path handles. |
| 2 | CONCELIER-CACHE-22-001 | BLOCKED (2025-11-22) | Blocked on CONCELIER-LNM-21-001 canonical field ordering. | Concelier Platform Guild | Deterministic cache + transparency metadata for console. |
| 3 | CONCELIER-MIRROR-23-001 | BLOCKED (2025-11-22) | Depends on CONCELIER-LNM-21-001 schema and Attestor mirror contract. | Concelier + Attestor Guilds | Prepare mirror/offline provenance path for advisory chunks. |
## Action Tracker
| Focus | Action | Owner(s) | Due | Status |
| --- | --- | --- | --- | --- |
| Schema | Finalize canonical chunk schema | Concelier Core | 2025-11-18 | TODO |
| Cache | Define deterministic cache keys | Concelier Platform | 2025-11-19 | TODO |
| Provenance | Mirror/attestor alignment | Concelier + Attestor | 2025-11-20 | TODO |
| Schema | Finalize canonical chunk schema | Concelier Core | 2025-11-18 | BLOCKED (await Cartographer schema) |
| Cache | Define deterministic cache keys | Concelier Platform | 2025-11-19 | BLOCKED (waiting on canonical schema) |
| Provenance | Mirror/attestor alignment | Concelier + Attestor | 2025-11-20 | BLOCKED (waiting on schema + Attestor mirror spec) |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -41,6 +41,7 @@
| 2025-11-16 | Sprint draft restored after accidental deletion; content from HEAD restored. | Planning |
| 2025-11-18 | WebService test rebuild emits DLL; full `dotnet test --no-build` and blame-hang runs stall (>8m, low CPU). Saved test list to `tmp/ws-tests.list`; hang investigation needed before progressing AIAI-31-002. | Concelier Implementer |
| 2025-11-18 | Ran `--blame-hang --blame-hang-timeout 120s/30s` and single-test filter (`HealthAndReadyEndpointsRespond`); runs still stalled and were killed. Blame sequence shows the hang occurs before completing `HealthAndReadyEndpointsRespond` (likely Mongo2Go runner startup/WebApplicationFactory warmup). No TRX produced; sequence at `src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/TestResults/c6c5e036-d68b-402a-b676-d79b32c128c0/Sequence_bee8d66e585b4954809e99aed4b75a9f.xml`. | Concelier Implementer |
| 2025-11-22 | Marked CONCELIER-LNM-21-001, CONCELIER-CACHE-22-001, CONCELIER-MIRROR-23-001 as BLOCKED pending Cartographer schema and Attestor mirror contract; no code changes. | Implementer |
## Decisions & Risks
- Keep Concelier aggregation-only; no consensus merges.

View File

@@ -25,11 +25,11 @@
| P1 | PREP-CONCELIER-GRAPH-21-002-PLATFORM-EVENTS-S | DONE (2025-11-20) | Due 2025-11-21 · Accountable: Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Event contract published at `docs/modules/concelier/events/advisory.observation.updated@1.md` (+schema/sample). Downstream may proceed with publishers/consumers. |
| P2 | PREP-CONCELIER-LNM-21-002-WAITING-ON-FINALIZE | DONE (2025-11-20) | Due 2025-11-21 · Accountable: Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Correlation rules + fixtures published at `docs/modules/concelier/linkset-correlation-21-002.md` with samples under `docs/samples/lnm/`. Downstream linkset builder can proceed. |
| 1 | CONCELIER-GRAPH-21-001 | DONE | LNM sample fixtures with scopes/relationships added; observation/linkset query tests passing | Concelier Core Guild · Cartographer Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Extend SBOM normalization so relationships/scopes are stored as raw observation metadata with provenance pointers for graph joins. |
| 2 | CONCELIER-GRAPH-21-002 | BLOCKED | PREP-CONCELIER-GRAPH-21-002-PLATFORM-EVENTS-S | Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Publish `sbom.observation.updated` events with tenant/context and advisory refs; facts only, no judgments. |
| 2 | CONCELIER-GRAPH-21-002 | DONE (2025-11-22) | PREP-CONCELIER-GRAPH-21-002-PLATFORM-EVENTS-S | Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Publish `sbom.observation.updated` events with tenant/context and advisory refs; facts only, no judgments. |
| 3 | CONCELIER-GRAPH-24-101 | TODO | Depends on 21-002 | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | `/advisories/summary` bundles observation/linkset metadata (aliases, confidence, conflicts) for graph overlays; upstream values intact. |
| 4 | CONCELIER-GRAPH-28-102 | TODO | Depends on 24-101 | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Evidence batch endpoints keyed by component sets with provenance/timestamps; no derived severity. |
| 5 | CONCELIER-LNM-21-001 | DONE | Start of Link-Not-Merge chain | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Define immutable `advisory_observations` model (per-source fields, version ranges, severity text, provenance metadata, tenant guards). |
| 6 | CONCELIER-LNM-21-002 | BLOCKED | PREP-CONCELIER-LNM-21-002-WAITING-ON-FINALIZE | Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Correlation pipelines output linksets with confidence + conflict markers, avoiding value collapse. |
| 6 | CONCELIER-LNM-21-002 | DOING | PREP-CONCELIER-LNM-21-002-WAITING-ON-FINALIZE | Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Correlation pipelines output linksets with confidence + conflict markers, avoiding value collapse. |
| 7 | CONCELIER-LNM-21-003 | TODO | Depends on 21-002 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Record disagreements (severity, CVSS, references) as structured conflict entries. |
| 8 | CONCELIER-LNM-21-004 | TODO | Depends on 21-003 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Remove legacy merge/dedup logic; add guardrails/tests to keep ingestion append-only; document linkset supersession. |
| 9 | CONCELIER-LNM-21-005 | TODO | Depends on 21-004 | Concelier Core Guild · Platform Events Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Emit `advisory.linkset.updated` events with delta descriptions + observation ids (tenant + provenance only). |
@@ -49,6 +49,12 @@
| 2025-11-20 | Documented observation event transport config in `docs/modules/concelier/operations/observation-events.md`. | Implementer |
| 2025-11-20 | Completed PREP-CONCELIER-GRAPH-21-002-PLATFORM-EVENTS-S and PREP-CONCELIER-LNM-21-002-WAITING-ON-FINALIZE; published prep note at `docs/modules/concelier/prep/2025-11-20-platform-events-and-lnm-21-002.md`. | Implementer |
| 2025-11-20 | Linked existing `advisory.observation.updated@1` contract and LNM-21-002 correlation rules/fixtures to PREP tasks; marked P1/P2 DONE. | Planning |
| 2025-11-22 | PREP artefacts validated; moved CONCELIER-GRAPH-21-002 and CONCELIER-LNM-21-002 to TODO (unblocked). | Project Mgmt |
| 2025-11-22 | Implemented advisory.observation.updated@1 outbox + transport pipeline (Mongo outbox + NATS optional); marked CONCELIER-GRAPH-21-002 DONE. | Implementer |
| 2025-11-22 | Started CONCELIER-LNM-21-002 implementation using frozen LNM v1 schema and correlation rules; status → DOING. Conflict emission (21-003) will follow once 21-002 tests pass. | Concelier Core |
| 2025-11-22 | Added LinksetCorrelation helper + updated aggregation to emit confidence/conflicts per LNM-21-002; unit tests added. Targeted `dotnet test ...AdvisoryObservationAggregationTests` failed locally (`invalid test source` vstest issue); requires CI/warmed runner. | Concelier Core |
| 2025-11-22 | Added conflict sourceIds propagation to storage documents and mapping; updated storage tests accordingly. `dotnet test ...Concelier.Storage.Mongo.Tests` still fails locally with same vstest argument issue; needs CI runner. | Concelier Core |
| 2025-11-22 | Tried `dotnet build src/Concelier/__Libraries/StellaOps.Concelier.Core/StellaOps.Concelier.Core.csproj`; build appears to hang after restore on local harness—no errors emitted; will defer to CI runner to avoid churn. | Concelier Core |
| 2025-11-20 | Started PREP-CONCELIER-GRAPH-21-002 and PREP-CONCELIER-LNM-21-002 (statuses → DOING) after confirming no other owner activity. | Planning |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-17 | Started CONCELIER-GRAPH-21-001: added raw linkset scopes + relationships (provenance) through contracts, ingest mapper, storage mapping, and sanitization; new Mongo mapping test added. | Implementer |
@@ -77,6 +83,7 @@
- Observation sink now emits `advisory.observation.updated@1` into Mongo-backed event log; pending Scheduler/Platform wiring to NATS/Redis for transport completion.
- Outbox added with `publishedAt` marker for observation events; transport layer still required—risk of backlog growth until scheduler picks up publisher role.
- Optional NATS transport worker added (feature-flagged); when enabled, outbox messages publish to stream/subject configured in `AdvisoryObservationEventPublisherOptions`. Ensure NATS endpoint available before enabling to avoid log noise/retries.
- Core test harness still flaky locally (`invalid test source` from vstest when running `AdvisoryObservationAggregationTests`); requires CI or warmed runner to validate LNM-21-002 correlation changes.
## Next Checkpoints
- Next LNM schema review: align with CARTO-GRAPH/LNM owners (date TBD); unblock tasks 12 and 515.

View File

@@ -1,55 +1,46 @@
# Sprint 0114-0001-0003 · Concelier III — Ingestion & Evidence (Phase 110.B)
## Topic & Scope
- Document and expose Link-Not-Merge ingestion surfaces (OpenAPI + SDK) with provenance, tenant scope, and AOC guarantees.
- Establish observability, attestation, and incident-mode hooks that keep advisory evidence replayable without merge-era heuristics.
- Align ingestion workers with orchestrator controls for deterministic scheduling, backfill, and ledger linkage.
- Working directory: `src/Concelier` (Core libraries, Storage.Mongo, WebService).
## Dependencies & Concurrency
- Depends on Sprint 0113-0001-0002 (Concelier II) Link-Not-Merge plumbing and graph/event groundwork.
- Observability chain (OBS-51…55) builds sequentially; attestation work relies on evidence snapshot generation first.
- Orchestrator integration tasks (ORCH-32…34) must coordinate with orchestrator worker SDK/controls; schedule alongside Policy Engine consumers.
## Documentation Prerequisites
- docs/README.md; docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/modules/concelier/architecture.md (ingestion, observability, orchestrator notes)
- Current OpenAPI spec + SDK docs referenced by CONCELIER-OAS-61/62/63
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-CONCELIER-OAS-61-001-LNM-SCHEMA-FROZEN-2 | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | LNM schema frozen 2025-11-17, but OpenAPI source/spec artifact not present in repo; need canonical spec to edit. <br><br> Document artefact/deliverable for CONCELIER-OAS-61-001 and publish location so downstream tasks can proceed. |
| P2 | PREP-CONCELIER-OAS-61-002-DEPENDS-ON-61-001-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 61-001; blocked until OpenAPI spec is available. <br><br> Document artefact/deliverable for CONCELIER-OAS-61-002 and publish location so downstream tasks can proceed. |
| P3 | PREP-CONCELIER-OAS-62-001-DEPENDS-ON-61-002-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 61-002; blocked with OAS chain. <br><br> Document artefact/deliverable for CONCELIER-OAS-62-001 and publish location so downstream tasks can proceed. |
| P4 | PREP-CONCELIER-OAS-63-001-DEPENDS-ON-62-001-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 62-001; blocked with OAS chain. <br><br> Document artefact/deliverable for CONCELIER-OAS-63-001 and publish location so downstream tasks can proceed. |
| P5 | PREP-CONCELIER-OBS-51-001-AWAIT-OBSERVABILITY | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Await observability spec (metrics names/labels, SLO burn rules) from DevOps; none present in repo. <br><br> Document artefact/deliverable for CONCELIER-OBS-51-001 and publish location so downstream tasks can proceed. |
| P6 | PREP-CONCELIER-OBS-52-001-DEPENDS-ON-51-001-M | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 51-001 metrics contract; blocked accordingly. <br><br> Document artefact/deliverable for CONCELIER-OBS-52-001 and publish location so downstream tasks can proceed. |
| P7 | PREP-CONCELIER-OBS-53-001-DEPENDS-ON-52-001-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 52-001; blocked until timeline instrumentation defined. <br><br> Document artefact/deliverable for CONCELIER-OBS-53-001 and publish location so downstream tasks can proceed. |
| P8 | PREP-CONCELIER-OBS-54-001-DEPENDS-ON-OBS-TIME | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on OBS timeline artifacts; no attestation contract yet. <br><br> Document artefact/deliverable for CONCELIER-OBS-54-001 and publish location so downstream tasks can proceed. |
| P9 | PREP-CONCELIER-OBS-55-001-DEPENDS-ON-54-001-I | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 54-001; incident-mode hooks need finalized attestation/timeline shape. <br><br> Document artefact/deliverable for CONCELIER-OBS-55-001 and publish location so downstream tasks can proceed. |
# Sprint 0114-0001-0003 · Concelier III — Ingestion & Evidence (Phase 110.B)
## Topic & Scope
- Document and expose Link-Not-Merge ingestion surfaces (OpenAPI + SDK) with provenance, tenant scope, and AOC guarantees.
- Establish observability, attestation, and incident-mode hooks that keep advisory evidence replayable without merge-era heuristics.
- Align ingestion workers with orchestrator controls for deterministic scheduling, backfill, and ledger linkage.
- Working directory: `src/Concelier` (Core libraries, Storage.Mongo, WebService).
## Dependencies & Concurrency
- Depends on Sprint 0113-0001-0002 (Concelier II) Link-Not-Merge plumbing and graph/event groundwork.
- Observability chain (OBS-51…55) builds sequentially; attestation work relies on evidence snapshot generation first.
- Orchestrator integration tasks (ORCH-32…34) must coordinate with orchestrator worker SDK/controls; schedule alongside Policy Engine consumers.
## Documentation Prerequisites
- docs/README.md; docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/modules/concelier/architecture.md (ingestion, observability, orchestrator notes)
- Current OpenAPI spec + SDK docs referenced by CONCELIER-OAS-61/62/63
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P10 | PREP-CONCELIER-ORCH-32-001-ORCHESTRATOR-REGIS | DONE (2025-11-20) | Prep doc published at `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`; ready for implementation wiring. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Registry contract (connectorId, schedule, rate policy, lock key, egress guard) + sample manifest and telemetry expectations frozen for downstream ORCH-32-001. |
| P11 | PREP-CONCELIER-ORCH-32-002-DEPENDS-ON-32-001 | DONE (2025-11-20) | Prep doc published at `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`; ready for worker SDK adoption. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Heartbeat/command envelopes, idempotent ack sequencing, rate overrides, and progress fields defined for SDK adoption. |
| P12 | PREP-CONCELIER-ORCH-33-001-DEPENDS-ON-32-002 | DONE (2025-11-20) | Prep doc published at `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`; pause/throttle controls defined. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Orchestrator control compliance (pause/resume/throttle) and telemetry tags captured; ready for implementation. |
| P13 | PREP-CONCELIER-ORCH-34-001-DEPENDS-ON-33-001 | DONE (2025-11-20) | Prep doc published at `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`; backfill manifest defined. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Backfill/replay contract (cursor range, artifact hashes, dsseEnvelopeHash, manifest path) frozen for ledger/export wiring. |
| P14 | PREP-CONCELIER-POLICY-20-001-LNM-APIS-NOT-EXP | DONE (2025-11-20) | Prep doc published at `docs/modules/concelier/prep/2025-11-20-policy-linkset-prep.md`; OpenAPI fields enumerated. | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Policy-facing LNM API contract (filters, pagination, provenance fields, cached flag) frozen pending OpenAPI source update. |
| 1 | CONCELIER-OAS-61-001 | BLOCKED | PREP-CONCELIER-OAS-61-001-LNM-SCHEMA-FROZEN-2 | Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Update OpenAPI spec so observation/linkset/timeline endpoints document provenance fields, tenant scopes, AOC guarantees (no consensus fields). |
| 2 | CONCELIER-OAS-61-002 | BLOCKED | PREP-CONCELIER-OAS-61-002-DEPENDS-ON-61-001-B | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Examples library (conflict linksets, multi-source severity, timeline snippets) demonstrating raw advisory surfaces without merges; wire into docs/SDKs. |
| 3 | CONCELIER-OAS-62-001 | BLOCKED | PREP-CONCELIER-OAS-62-001-DEPENDS-ON-61-002-B | Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | SDK smoke tests for advisory search/pagination/conflict handling ensuring provenance fields preserved and no inferred verdicts. |
| 4 | CONCELIER-OAS-63-001 | BLOCKED | PREP-CONCELIER-OAS-63-001-DEPENDS-ON-62-001-B | Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Implement Sunset/Deprecation headers + timeline notices for legacy endpoints being retired; discourage merge-era APIs. |
| 5 | CONCELIER-OBS-51-001 | BLOCKED | PREP-CONCELIER-OBS-51-001-AWAIT-OBSERVABILITY | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Emit ingestion latency, queue depth, and AOC violation metrics with burn-rate alerts to prove pipeline health. |
| 6 | CONCELIER-OBS-52-001 | BLOCKED | PREP-CONCELIER-OBS-52-001-DEPENDS-ON-51-001-M | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Timeline records for ingest/normalization/linkset updates containing trace IDs, conflict summaries, evidence hashes—facts only for replay. |
| 7 | CONCELIER-OBS-53-001 | BLOCKED | PREP-CONCELIER-OBS-53-001-DEPENDS-ON-52-001-B | Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Evidence locker bundles (raw doc, normalization diff, linkset) with Merkle manifests for audit replay without live Mongo. |
| 8 | CONCELIER-OBS-54-001 | BLOCKED | PREP-CONCELIER-OBS-54-001-DEPENDS-ON-OBS-TIME | Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Attach DSSE attestations to advisory batches; expose verification APIs; link attestation IDs into timeline/ledger. |
| 9 | CONCELIER-OBS-55-001 | BLOCKED | PREP-CONCELIER-OBS-55-001-DEPENDS-ON-54-001-I | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Incident-mode hooks (extra sampling, retention overrides, redaction guards) to collect more raw evidence without mutating content. |
| 10 | CONCELIER-ORCH-32-001 | TODO | Prep completed; implement registry metadata per `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Register every advisory connector with orchestrator (metadata, auth scopes, rate policies) for transparent, reproducible scheduling. |
| 11 | CONCELIER-ORCH-32-002 | TODO | Prep completed; adopt heartbeat/command envelopes from `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Adopt orchestrator worker SDK in ingestion loops; emit heartbeats/progress/artifact hashes for deterministic replays. |
| 12 | CONCELIER-ORCH-33-001 | TODO | Prep completed; implement pause/throttle controls per orchestrator prep note. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Honor orchestrator pause/throttle/retry controls with structured errors and persisted checkpoints. |
| 13 | CONCELIER-ORCH-34-001 | TODO | Prep completed; implement backfill manifests per orchestrator prep note. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Execute orchestrator-driven backfills reusing artifact hashes/signatures, logging provenance, and pushing run metadata to ledger. |
| 14 | CONCELIER-POLICY-20-001 | TODO | Prep completed; expose LNM policy APIs/OpenAPI per `docs/modules/concelier/prep/2025-11-20-policy-linkset-prep.md`. | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Provide batch advisory lookup APIs for Policy Engine (purl/advisory filters, tenant scopes, explain metadata) so policy joins raw evidence without inferred outcomes. |
## Execution Log
| P1 | PREP-CONCELIER-OAS-61-001-LNM-SCHEMA-FROZEN-2 | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | OAS stub + examples captured in `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md`; aligns with frozen LNM schema. |
| P2 | PREP-CONCELIER-OAS-61-002-DEPENDS-ON-61-001-B | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | SDK example + response bodies enumerated in `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md`; ready for SDK gen. |
| P3 | PREP-CONCELIER-OAS-62-001-DEPENDS-ON-61-002-B | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | SDK smoke constraints documented in prep note; unblock generator wiring. |
| P4 | PREP-CONCELIER-OAS-63-001-DEPENDS-ON-62-001-B | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Sunset/deprecation headers documented in prep note; governance unblocked. |
| P5 | PREP-CONCELIER-OBS-51-001-AWAIT-OBSERVABILITY | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Metrics/logs/traces enumerated in `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md`; includes burn-rate alert guidance. |
| P6 | PREP-CONCELIER-OBS-52-001-DEPENDS-ON-51-001-M | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Timeline record fields (trace IDs, conflict summaries, evidence hashes) captured in prep note; proceed to implementation. |
| P7 | PREP-CONCELIER-OBS-53-001-DEPENDS-ON-52-001-B | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Evidence bundle/timeline linkage requirements documented; unblock evidence locker integration. |
| P8 | PREP-CONCELIER-OBS-54-001-DEPENDS-ON-OBS-TIME | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Attestation timeline enrichment + DSSE envelope fields recorded in prep note. |
| P9 | PREP-CONCELIER-OBS-55-001-DEPENDS-ON-54-001-I | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Incident-mode hooks and sealed-mode redaction guidance captured; see prep note. |
| 10 | CONCELIER-ORCH-32-001 | DOING (2025-11-22) | Prep completed; implement registry metadata per `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Register every advisory connector with orchestrator (metadata, auth scopes, rate policies) for transparent, reproducible scheduling. |
| 11 | CONCELIER-ORCH-32-002 | DOING (2025-11-22) | Prep completed; adopt heartbeat/command envelopes from `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Adopt orchestrator worker SDK in ingestion loops; emit heartbeats/progress/artifact hashes for deterministic replays. |
| 12 | CONCELIER-ORCH-33-001 | DOING (2025-11-22) | Prep completed; implement pause/throttle controls per orchestrator prep note. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Honor orchestrator pause/throttle/retry controls with structured errors and persisted checkpoints. |
| 13 | CONCELIER-ORCH-34-001 | DOING (2025-11-22) | Prep completed; implement backfill manifests per orchestrator prep note. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Execute orchestrator-driven backfills reusing artifact hashes/signatures, logging provenance, and pushing run metadata to ledger. |
| 14 | CONCELIER-POLICY-20-001 | BLOCKED (2025-11-22) | OpenAPI source/spec missing in repo; needs canonical Concelier OAS location before exposure. | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Provide batch advisory lookup APIs for Policy Engine (purl/advisory filters, tenant scopes, explain metadata) so policy joins raw evidence without inferred outcomes. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Confirmed PREP-CONCELIER-ORCH-32-001/002/33-001/34-001 unowned; published orchestrator registry/control prep at `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`; set P10P13 to DONE. | Implementer |
@@ -57,15 +48,25 @@
| 2025-11-20 | Moved CONCELIER-ORCH-32-001..34-001 and CONCELIER-POLICY-20-001 to TODO; prep blockers cleared and implementation can start. | Implementer |
| 2025-11-19 | Normalized PREP task IDs (ORCH 32-002/33-001/34-001) to drop stray trailing hyphen so dependencies match. | Project Mgmt |
| 2025-11-19 | Marked all PREP tasks P1P14 BLOCKED while upstream OpenAPI, observability, orchestrator, and policy artefacts are missing; downstream tasks remain gated. | Project Mgmt |
| 2025-11-22 | PREP-OAS/OBS artefacts published; moved CONCELIER-OAS-61-001..63-001 and CONCELIER-OBS-51-001..55-001 to TODO. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-08 | Archived completed/historic work to `docs/implplan/archived/tasks.md`. | Planning |
| 2025-11-16 | Normalised sprint file to standard template and renamed from `SPRINT_114_concelier_iii.md` to `SPRINT_0114_0001_0003_concelier_iii.md`; no semantic changes. | Planning |
| 2025-11-18 | Marked OAS tasks (61-001..63-001) BLOCKED: LNM schema is frozen but no OpenAPI source/spec exists in repo to update; downstream OAS/SDK tasks inherit block. | Concelier Core |
| 2025-11-18 | Marked OBS chain (51-001..55-001) BLOCKED: repo lacks observability/AOC metric spec and attestation/timeline contract needed to instrument ingestion pipeline. | Concelier Core |
| 2025-11-18 | Marked ORCH chain (32-001..34-001) and POLICY-20-001 BLOCKED: orchestrator registry/SDK contract and LNM OpenAPI exposure missing; blocked by upstream artefacts. | Concelier Core |
## Decisions & Risks
- Link-Not-Merge and OpenAPI alignment must precede SDK/examples; otherwise downstream clients will drift from canonical facts.
| 2025-11-08 | Archived completed/historic work to `docs/implplan/archived/tasks.md`. | Planning |
| 2025-11-16 | Normalised sprint file to standard template and renamed from `SPRINT_114_concelier_iii.md` to `SPRINT_0114_0001_0003_concelier_iii.md`; no semantic changes. | Planning |
| 2025-11-18 | Marked OAS tasks (61-001..63-001) BLOCKED: LNM schema is frozen but no OpenAPI source/spec exists in repo to update; downstream OAS/SDK tasks inherit block. | Concelier Core |
| 2025-11-18 | Marked OBS chain (51-001..55-001) BLOCKED: repo lacks observability/AOC metric spec and attestation/timeline contract needed to instrument ingestion pipeline. | Concelier Core |
| 2025-11-18 | Marked ORCH chain (32-001..34-001) and POLICY-20-001 BLOCKED: orchestrator registry/SDK contract and LNM OpenAPI exposure missing; blocked by upstream artefacts. | Concelier Core |
| 2025-11-22 | Completed OAS/OBS PREP tasks via `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md`; set P1P9 to DONE. | Project Mgmt |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
| 2025-11-22 | Started Sprint 0114: set ORCH-32/33/34 chain to DOING, kept POLICY-20-001 BLOCKED pending canonical OpenAPI source; refreshed blockers accordingly. | Project Mgmt |
| 2025-11-22 | Added blocker entry for missing Concelier OpenAPI source to keep POLICY-20-001 flagged until canonical spec location exists. | Project Mgmt |
| 2025-11-22 | Updated `src/Concelier/AGENTS.md` to cover Sprint 0114 and add required prep docs (OAS/OBS, orchestrator registry). | Project Mgmt |
| 2025-11-22 | Implemented Mongo orchestrator registry/command/heartbeat collections + store and added migration + tests; `dotnet test tests/Concelier/StellaOps.Concelier.Storage.Mongo.Tests/StellaOps.Concelier.Storage.Mongo.Tests.csproj --no-build` passes. | Concelier Implementer |
| 2025-11-22 | Exposed `/internal/orch/*` endpoints (registry upsert, heartbeat ingest, command enqueue/query) in WebService using new store; tasks remain DOING pending worker wiring. | Concelier Implementer |
| 2025-11-22 | Worker-side consumption of commands/heartbeats not yet wired; ORCH-32/33/34 remain DOING with WebService side in place. | Concelier Implementer |
| 2025-11-22 | WebService build attempt (`dotnet build ...WebService.csproj --no-restore`) failed on pre-existing nullability errors in `LinksetCorrelation.cs`; no new errors from orchestrator endpoints. | Concelier Implementer |
## Decisions & Risks
- Link-Not-Merge and OpenAPI alignment must precede SDK/examples; otherwise downstream clients will drift from canonical facts.
- Observability/attestation chain (OBS-51…55) risks audit gaps if sequencing slips; each step depends on previous artifacts.
- Orchestrator control compliance is required to prevent evidence loss during throttles/pauses.
- OpenAPI source (swagger/OAS) for Concelier endpoints is missing from the repo; OAS tasks 61-001..63-001 (and dependent Policy 20-001 tasks) cannot proceed until the canonical spec artifact is provided or generated location is identified.
@@ -73,14 +74,18 @@
- Orchestrator registry/SDK contract now documented (see prep note above); downstream tasks must keep in sync with orchestrator module changes.
- Orchestrator registry/control/backfill contract is now frozen at `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`; downstream implementation must align or update this note + sprint risks if changes arise.
- Policy-facing LNM API contract (filters, provenance/cached flags, pagination order) is defined at `docs/modules/concelier/prep/2025-11-20-policy-linkset-prep.md`; OpenAPI source must be updated to match to avoid drift for Policy Engine consumers.
## Next Checkpoints
- Schedule OpenAPI/SDK review once CONCELIER-OAS-61-001 draft ready (date TBD, gated on Sprint 0113 outputs).
- Plan orchestrator contract review with Orchestrator guild before implementing ORCH-32-002.
## Blockers & Dependencies (detailed)
| Dependency | Impacted work | Owner(s) | Status |
| --- | --- | --- | --- |
| Link-Not-Merge schema + APIs from Sprint 0113 | Tasks 14, 14 | Concelier Core/WebService · API Contracts | Pending upstream completion. |
| Observability metrics foundation (CONCELIER-OBS-51-001) | Tasks 69 | Concelier Core · DevOps | Not started; required for downstream timeline/attestation hooks. |
| Orchestrator registry/SDK contracts | Tasks 1013 | Concelier Core · Orchestrator Guild | Coordination needed; no contract recorded yet. |
- Concelier module AGENTS charter updated 2025-11-22 to include Sprint 0114 scope and required prep docs; implementers must treat it as read before starting tasks.
- Orchestrator registry/command/heartbeat storage now exists with TTL-backed command expiry; WebService/worker wiring still pending—ensure API handlers and SDK align with stored shapes before marking ORCH-32/33/34 DONE.
- WebService `/internal/orch/*` endpoints now land registry upserts, heartbeats, and commands into Mongo store; worker consumption and orchestrator authentication scopes still to be validated before closing tasks.
## Next Checkpoints
- Schedule OpenAPI/SDK review once CONCELIER-OAS-61-001 draft ready (date TBD, gated on Sprint 0113 outputs).
- Plan orchestrator contract review with Orchestrator guild before implementing ORCH-32-002.
## Blockers & Dependencies (detailed)
| Dependency | Impacted work | Owner(s) | Status |
| --- | --- | --- | --- |
| Link-Not-Merge schema + APIs from Sprint 0113 | Tasks 14, 14 | Concelier Core/WebService · API Contracts | Pending upstream completion. |
| Observability metrics foundation (CONCELIER-OBS-51-001) | Tasks 69 | Concelier Core · DevOps | Spec captured in `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md`; implementation hooks next. |
| Orchestrator registry/SDK contracts | Tasks 1013 | Concelier Core · Orchestrator Guild | Documented 2025-11-20 (`docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`); ready for implementation. |
| Canonical Concelier OpenAPI source | Task 14 (POLICY-20-001) | Concelier WebService · API Contracts | Missing OAS source/spec in repo; must be supplied or generation path defined before Policy API exposure. |

View File

@@ -1,102 +1,103 @@
# Sprint 0119_0001_0001 · Excititor Ingestion & Evidence (Phase I)
## Topic & Scope
- Stand up Advisory-AI evidence projection APIs (Excititor I) plus ingestion/attestation chain that stays aggregation-only prior to consensus.
- Deliver telemetry and guardrails so RAG clients and Lens can observe usage; prep mirror-first + sealed-mode ingestion and portable evidence bundles for air-gapped deployments.
- Establish attestation verifier harness and provenance linkage so Advisory AI can cite supplier identity without Excititor interpreting verdicts.
- **Working directory:** `src/Excititor` (WebService, Core, Attestation, Connectors; shared EvidenceLocker/Export touchpoints only as noted).
## Dependencies & Concurrency
- Upstream: Sprint 100.A (Attestor DSSE verification); Export Center mirror bundle manifest (Sprint 162) and EvidenceLocker portable format (Sprints 160/161); Ops/Signals span sink deployment for observability; connector signer metadata delivery.
- Concurrency: Advisory-AI API tasks can proceed while telemetry export waits on Ops span sink; AirGap 56/57/58 blocked on Export Center schema; Attestation 73-* blocked on 01-003 completion.
- Peers: runs parallel with other Excititor batches; no CC-decade conflicts noted once dependencies above land.
## Documentation Prerequisites
- `docs/modules/excititor/architecture.md`
- `docs/modules/excititor/README.md#latest-updates`
- `docs/modules/excititor/mirrors.md`
- `docs/modules/excititor/operations/*`
- `docs/modules/excititor/implementation_plan.md`
- Excititor component `AGENTS.md` files within each working directory (WebService, Core, Attestation, Connectors).
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-EXCITITOR-AIRGAP-56-001-WAITING-ON-EXPOR | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Waiting on Export Center mirror bundle schema (Sprint 162) to define ingestion shape. <br><br> Document artefact/deliverable for EXCITITOR-AIRGAP-56-001 and publish location so downstream tasks can proceed. |
| P2 | PREP-EXCITITOR-AIRGAP-57-001-BLOCKED-ON-56-00 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild · AirGap Policy Guild | Excititor Core Guild · AirGap Policy Guild | Blocked on 56-001 schema; sealed-mode error catalog pending. <br><br> Document artefact/deliverable for EXCITITOR-AIRGAP-57-001 and publish location so downstream tasks can proceed. |
| P3 | PREP-EXCITITOR-AIRGAP-58-001-DEPENDS-ON-57-00 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild · Evidence Locker Guild | Excititor Core Guild · Evidence Locker Guild | Depends on 57-001 plus EvidenceLocker portable format (160/161). <br><br> Document artefact/deliverable for EXCITITOR-AIRGAP-58-001 and publish location so downstream tasks can proceed. |
# Sprint 0119_0001_0001 · Excititor Ingestion & Evidence (Phase I)
## Topic & Scope
- Stand up Advisory-AI evidence projection APIs (Excititor I) plus ingestion/attestation chain that stays aggregation-only prior to consensus.
- Deliver telemetry and guardrails so RAG clients and Lens can observe usage; prep mirror-first + sealed-mode ingestion and portable evidence bundles for air-gapped deployments.
- Establish attestation verifier harness and provenance linkage so Advisory AI can cite supplier identity without Excititor interpreting verdicts.
- **Working directory:** `src/Excititor` (WebService, Core, Attestation, Connectors; shared EvidenceLocker/Export touchpoints only as noted).
## Dependencies & Concurrency
- Upstream: Sprint 100.A (Attestor DSSE verification); Export Center mirror bundle manifest (Sprint 162) and EvidenceLocker portable format (Sprints 160/161); Ops/Signals span sink deployment for observability; connector signer metadata delivery.
- Concurrency: Advisory-AI API tasks can proceed while telemetry export waits on Ops span sink; AirGap 56/57/58 blocked on Export Center schema; Attestation 73-* blocked on 01-003 completion.
- Peers: runs parallel with other Excititor batches; no CC-decade conflicts noted once dependencies above land.
## Documentation Prerequisites
- `docs/modules/excititor/architecture.md`
- `docs/modules/excititor/README.md#latest-updates`
- `docs/modules/excititor/mirrors.md`
- `docs/modules/excititor/operations/*`
- `docs/modules/excititor/implementation_plan.md`
- Excititor component `AGENTS.md` files within each working directory (WebService, Core, Attestation, Connectors).
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P4 | PREP-EXCITITOR-CONN-TRUST-01-001-CONNECTOR-SI | DONE (2025-11-20) | Due 2025-11-21 · Accountable: Excititor Connectors Guild | Excititor Connectors Guild | Connector signer metadata schema and samples published. <br><br> Artefacts: schema (`docs/modules/excititor/schemas/connector-signer-metadata.schema.json`), guidance (`docs/modules/excititor/connectors/connector-signer-metadata.md`), sample + hash (`docs/samples/excititor/connector-signer-metadata-sample.json[.sha256]`). |
| P5 | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR | DOING (2025-11-20) | Due 2025-11-21 · Accountable: Planning | Planning | If issues persist, log BLOCKED status in attestation plan and re-forecast completion. <br><br> Document artefact/deliverable for Attestation verifier rehearsal (Excititor Attestation Guild) and publish location so downstream tasks can proceed. |
| 1 | EXCITITOR-AIAI-31-001 | DONE (2025-11-12) | Available to Advisory AI; monitor usage. | Excititor WebService Guild | Expose normalized VEX justifications, scope trees, and anchors via `VexObservation` projections so Advisory AI can cite raw evidence without consensus logic. |
| 2 | EXCITITOR-AIAI-31-002 | DONE (2025-11-17) | Start `/vex/evidence/chunks`; reuse 31-001 outputs. | Excititor WebService Guild | Stream raw statements + signature metadata with tenant/policy filters for RAG clients; aggregation-only, reference observation/linkset IDs. |
| 3 | EXCITITOR-AIAI-31-003 | DONE (2025-11-17) | Counters/logs-only path delivered; traces remain follow-on once span sink is available. | Excititor WebService Guild · Observability Guild | Instrument evidence APIs with request counters, chunk histograms, signature-failure + AOC guard-violation meters. |
| 4 | EXCITITOR-AIAI-31-004 | DONE (2025-11-18) | Doc published (`docs/modules/excititor/evidence-contract.md`); traces still gated on span sink but contract delivered | Excititor WebService Guild · Docs Guild | Codify Advisory-AI evidence contract, determinism guarantees, and mapping of observation IDs to storage. |
| 5 | EXCITITOR-AIRGAP-56-001 | BLOCKED | PREP-EXCITITOR-AIRGAP-56-001-WAITING-ON-EXPOR | Excititor Core Guild | Mirror-first ingestion that preserves upstream digests, bundle IDs, and provenance for offline parity. |
| 6 | EXCITITOR-AIRGAP-57-001 | BLOCKED | PREP-EXCITITOR-AIRGAP-57-001-BLOCKED-ON-56-00 | Excititor Core Guild · AirGap Policy Guild | Enforce sealed-mode policies, remediation errors, and staleness annotations surfaced to Advisory AI. |
| 7 | EXCITITOR-AIRGAP-58-001 | BLOCKED | PREP-EXCITITOR-AIRGAP-58-001-DEPENDS-ON-57-00 | Excititor Core Guild · Evidence Locker Guild | Package tenant-scoped VEX evidence (raw JSON, normalization diff, provenance) into portable bundles tied to timeline events. |
| 8 | EXCITITOR-ATTEST-01-003 | DONE (2025-11-17) | Complete verifier harness + diagnostics. | Excititor Attestation Guild | Finish `IVexAttestationVerifier`, wire structured diagnostics/metrics, and prove DSSE bundle verification without touching consensus results. |
| 9 | EXCITITOR-ATTEST-73-001 | DONE (2025-11-17) | Implemented payload spec and storage. | Excititor Core · Attestation Payloads Guild | Emit attestation payloads capturing supplier identity, justification summary, and scope metadata for trust chaining. |
| 10 | EXCITITOR-ATTEST-73-002 | DONE (2025-11-17) | Implemented linkage API. | Excititor Core Guild | Provide APIs linking attestation IDs back to observation/linkset/product tuples for provenance citations without derived verdicts. |
| P5 | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Planning | Planning | Rehearsal harness plan captured in `docs/modules/excititor/prep/2025-11-22-attestation-rehearsal-prep.md`; ready for execution. |
| 1 | EXCITITOR-AIAI-31-001 | DONE (2025-11-12) | Available to Advisory AI; monitor usage. | Excititor WebService Guild | Expose normalized VEX justifications, scope trees, and anchors via `VexObservation` projections so Advisory AI can cite raw evidence without consensus logic. |
| 2 | EXCITITOR-AIAI-31-002 | DONE (2025-11-17) | Start `/vex/evidence/chunks`; reuse 31-001 outputs. | Excititor WebService Guild | Stream raw statements + signature metadata with tenant/policy filters for RAG clients; aggregation-only, reference observation/linkset IDs. |
| 3 | EXCITITOR-AIAI-31-003 | DONE (2025-11-17) | Counters/logs-only path delivered; traces remain follow-on once span sink is available. | Excititor WebService Guild · Observability Guild | Instrument evidence APIs with request counters, chunk histograms, signature-failure + AOC guard-violation meters. |
| 4 | EXCITITOR-AIAI-31-004 | DONE (2025-11-18) | Doc published (`docs/modules/excititor/evidence-contract.md`); traces still gated on span sink but contract delivered | Excititor WebService Guild · Docs Guild | Codify Advisory-AI evidence contract, determinism guarantees, and mapping of observation IDs to storage. |
| P1 | PREP-EXCITITOR-AIRGAP-56-001-WAITING-ON-EXPOR | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Airgap import envelope, error catalog, and timeline hooks documented in `docs/modules/excititor/prep/2025-11-22-airgap-56-58-prep.md`. |
| P2 | PREP-EXCITITOR-AIRGAP-57-001-BLOCKED-ON-56-00 | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Excititor Core Guild · AirGap Policy Guild | Excititor Core Guild · AirGap Policy Guild | Sealed-mode error catalog recorded in prep note `docs/modules/excititor/prep/2025-11-22-airgap-56-58-prep.md`. |
| P3 | PREP-EXCITITOR-AIRGAP-58-001-DEPENDS-ON-57-00 | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Excititor Core Guild · Evidence Locker Guild | Excititor Core Guild · Evidence Locker Guild | Timeline/notification hooks captured in prep note `docs/modules/excititor/prep/2025-11-22-airgap-56-58-prep.md`. |
| 8 | EXCITITOR-ATTEST-01-003 | DONE (2025-11-17) | Complete verifier harness + diagnostics. | Excititor Attestation Guild | Finish `IVexAttestationVerifier`, wire structured diagnostics/metrics, and prove DSSE bundle verification without touching consensus results. |
| 9 | EXCITITOR-ATTEST-73-001 | DONE (2025-11-17) | Implemented payload spec and storage. | Excititor Core · Attestation Payloads Guild | Emit attestation payloads capturing supplier identity, justification summary, and scope metadata for trust chaining. |
| 10 | EXCITITOR-ATTEST-73-002 | DONE (2025-11-17) | Implemented linkage API. | Excititor Core Guild | Provide APIs linking attestation IDs back to observation/linkset/product tuples for provenance citations without derived verdicts. |
| 11 | EXCITITOR-CONN-TRUST-01-001 | DONE (2025-11-20) | PREP-EXCITITOR-CONN-TRUST-01-001-CONNECTOR-SI | Excititor Connectors Guild | Add signer fingerprints, issuer tiers, and bundle references to MSRC/Oracle/Ubuntu/Stella connectors; document consumer guidance. |
### Task Clusters & Readiness
- **Advisory-AI evidence APIs:** 31-001 delivered; 31-003 instrumentation and 31-004 docs pending; ready to start once examples and telemetry fixtures finalize.
- **AirGap ingestion & portable bundles:** 56/57/58 gated on Export Center schema and EvidenceLocker format; need sealed-mode error catalog and timeline mapping.
- **Attestation & provenance chain:** 01-003 harness/diagnostics first, then 73-001 payload spec and 73-002 linkage docs.
- **Connector provenance parity:** Inventory signer metadata, define shared fingerprint/tier schema, update connector acceptance tests.
## Action Tracker
| Focus | Action | Owner(s) | Due | Status |
| --- | --- | --- | --- | --- |
| Advisory-AI APIs | Publish finalized OpenAPI schema + SDK notes for projection API (31-004). | Excititor WebService Guild · Docs Guild | 2025-11-15 | In review (draft shared 2025-11-13) |
| Observability | Wire metrics/traces for `/v1/vex/observations/**` (31-003) and document dashboards. | Excititor WebService Guild · Observability Guild | 2025-11-16 | PARTIAL (metrics/logs delivered 2025-11-17; traces await span sink) |
| AirGap | Capture mirror bundle schema + sealed-mode toggle requirements for 56/57. | Excititor Core Guild · AirGap Policy Guild | 2025-11-17 | Pending |
| Portable bundles | Draft bundle manifest + EvidenceLocker linkage notes for 58-001. | Excititor Core Guild · Evidence Locker Guild | 2025-11-18 | Pending |
| Attestation | Complete verifier suite + diagnostics for 01-003. | Excititor Attestation Guild | 2025-11-16 | In progress (verifier harness ~80% complete) |
| Connectors | Inventory signer metadata + plan rollout for MSRC/Oracle/Ubuntu/Stella connectors (CONN-TRUST-01-001). | Excititor Connectors Guild | 2025-11-19 | Pending (schema draft expected 2025-11-14) |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P1P4 BLOCKED: mirror bundle schema (Sprint 162), sealed-mode error catalog, EvidenceLocker portable format, and connector signer metadata remain unpublished, keeping EXCITITOR-AIRGAP-56/57/58 and CONN-TRUST-01-001 gated. | Project Mgmt |
| 2025-11-12 | Snapshot refreshed; 31-001 marked DONE; other tasks pending observability, AirGap schemas, and attestation verifier completion. | Excititor PM |
| 2025-11-13 | Added readiness checklists and action tracker; awaiting Export Center mirror schema and Attestor verifier rehearsals. | Excititor PM |
| 2025-11-13 | OpenAPI draft for 31-004 shared; observability wiring blocked until Ops deploys span sink. | WebService Guild |
| 2025-11-14 | Connector provenance schema review scheduled; Export Center mirror schema still pending, keeping 56/57 blocked. | Connectors Guild |
| 2025-11-14 | 31-003 instrumentation (counters, chunk histogram, signature failure + guard-violation meters) merged; telemetry export blocked on span sink rollout. | WebService Guild |
| 2025-11-17 | Added chunk request/response telemetry + signature status counters; `/v1/vex/evidence/chunks` now emits metrics without traces. | WebService Guild |
### Task Clusters & Readiness
- **Advisory-AI evidence APIs:** 31-001 delivered; 31-003 instrumentation and 31-004 docs pending; ready to start once examples and telemetry fixtures finalize.
- **AirGap ingestion & portable bundles:** 56/57/58 gated on Export Center schema and EvidenceLocker format; need sealed-mode error catalog and timeline mapping.
- **Attestation & provenance chain:** 01-003 harness/diagnostics first, then 73-001 payload spec and 73-002 linkage docs.
- **Connector provenance parity:** Inventory signer metadata, define shared fingerprint/tier schema, update connector acceptance tests.
## Action Tracker
| Focus | Action | Owner(s) | Due | Status |
| --- | --- | --- | --- | --- |
| Advisory-AI APIs | Publish finalized OpenAPI schema + SDK notes for projection API (31-004). | Excititor WebService Guild · Docs Guild | 2025-11-15 | In review (draft shared 2025-11-13) |
| Observability | Wire metrics/traces for `/v1/vex/observations/**` (31-003) and document dashboards. | Excititor WebService Guild · Observability Guild | 2025-11-16 | PARTIAL (metrics/logs delivered 2025-11-17; traces await span sink) |
| AirGap | Capture mirror bundle schema + sealed-mode toggle requirements for 56/57. | Excititor Core Guild · AirGap Policy Guild | 2025-11-17 | Pending |
| Portable bundles | Draft bundle manifest + EvidenceLocker linkage notes for 58-001. | Excititor Core Guild · Evidence Locker Guild | 2025-11-18 | Pending |
| Attestation | Complete verifier suite + diagnostics for 01-003. | Excititor Attestation Guild | 2025-11-16 | In progress (verifier harness ~80% complete) |
| Connectors | Inventory signer metadata + plan rollout for MSRC/Oracle/Ubuntu/Stella connectors (CONN-TRUST-01-001). | Excititor Connectors Guild | 2025-11-19 | Pending (schema draft expected 2025-11-14) |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P1P4 BLOCKED: mirror bundle schema (Sprint 162), sealed-mode error catalog, EvidenceLocker portable format, and connector signer metadata remain unpublished, keeping EXCITITOR-AIRGAP-56/57/58 and CONN-TRUST-01-001 gated. | Project Mgmt |
| 2025-11-22 | Completed air-gap and attestation rehearsal PREP docs (`docs/modules/excititor/prep/2025-11-22-airgap-56-58-prep.md`, `docs/modules/excititor/prep/2025-11-22-attestation-rehearsal-prep.md`); set P1P3 and P5 to DONE. | Project Mgmt |
| 2025-11-22 | PREP cleared; moved EXCITITOR-AIRGAP-56-001/57-001/58-001 to TODO. | Project Mgmt |
| 2025-11-22 | Started EXCITITOR-AIRGAP-56-001: added air-gap import endpoint skeleton with validation and skew guard; awaiting mirror bundle storage wiring and signer enforcement. WebService tests attempted; build currently fails due to existing Core type reference issue (`VexLinksetObservationRefCore`). | Implementer |
| 2025-11-12 | Snapshot refreshed; 31-001 marked DONE; other tasks pending observability, AirGap schemas, and attestation verifier completion. | Excititor PM |
| 2025-11-13 | Added readiness checklists and action tracker; awaiting Export Center mirror schema and Attestor verifier rehearsals. | Excititor PM |
| 2025-11-13 | OpenAPI draft for 31-004 shared; observability wiring blocked until Ops deploys span sink. | WebService Guild |
| 2025-11-14 | Connector provenance schema review scheduled; Export Center mirror schema still pending, keeping 56/57 blocked. | Connectors Guild |
| 2025-11-14 | 31-003 instrumentation (counters, chunk histogram, signature failure + guard-violation meters) merged; telemetry export blocked on span sink rollout. | WebService Guild |
| 2025-11-17 | Added chunk request/response telemetry + signature status counters; `/v1/vex/evidence/chunks` now emits metrics without traces. | WebService Guild |
| 2025-11-14 | Published `docs/modules/excititor/operations/observability.md` covering new evidence metrics for Ops/Lens dashboards. | Observability Guild |
| 2025-11-16 | Normalized sprint file to standard template, renamed to SPRINT_0119_0001_0001_excititor_i.md, and updated tasks-all references. | Planning |
| 2025-11-20 | Started PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR (status → DOING) after confirming no existing DOING/DONE owner entries. | Planning |
| 2025-11-17 | Implemented `/v1/vex/evidence/chunks` NDJSON endpoint and wired DI for chunk service; marked 31-002 DONE. | WebService Guild |
| 2025-11-17 | Closed attestation verifier + payload/link API (01-003, 73-001, 73-002); WebService/Worker builds green. | Attestation/Core Guild |
| P5 | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Planning | Planning | Rehearsal harness plan captured in `docs/modules/excititor/prep/2025-11-22-attestation-rehearsal-prep.md`; ready for execution. |
| 2025-11-17 | Implemented `/v1/vex/evidence/chunks` NDJSON endpoint and wired DI for chunk service; marked 31-002 DONE. | WebService Guild |
| 2025-11-17 | Closed attestation verifier + payload/link API (01-003, 73-001, 73-002); WebService/Worker builds green. | Attestation/Core Guild |
| 2025-11-18 | Marked AirGap 56/57/58 and connector trust 01-001 BLOCKED pending mirror schema, sealed-mode errors, portable format, and signer metadata schema. | Implementer |
| 2025-11-18 | Authored Advisory-AI evidence contract doc (`docs/modules/excititor/evidence-contract.md`) covering `/v1/vex/evidence/chunks`, schema, determinism, AOC, telemetry; 31-004 doc deliverable ready. | Implementer |
| 2025-11-20 | Completed PREP-EXCITITOR-CONN-TRUST-01-001: published connector signer metadata schema, guidance, and sample bundle hash to unblock connector trust rollout. | Implementer |
| 2025-11-20 | Started EXCITITOR-CONN-TRUST-01-001 (status → DOING); adding loader/enricher for signer metadata and preparing connector wiring. | Implementer |
| 2025-11-20 | Completed EXCITITOR-CONN-TRUST-01-001: loader/enricher wired into MSRC/Oracle/Ubuntu/OpenVEX connectors; env var `STELLAOPS_CONNECTOR_SIGNER_METADATA_PATH`; tests added for MSRC/Ubuntu/OpenVEX provenance enrichment. | Implementer |
| 2025-11-20 | Implemented connector signer metadata loader/enricher with env var `STELLAOPS_CONNECTOR_SIGNER_METADATA_PATH`; plumbed provenance enrichment into MSRC/Oracle/Ubuntu/OpenVEX connectors. | Implementer |
## Decisions & Risks
- **Decisions**
- Until Ops span sink lands, keep observability fallback to log-only counters per `docs/modules/excititor/operations/observability.md`.
- If Export Center mirror schema slips, temporarily use placeholder from `docs/modules/export-center/architecture.md` with deltas noted; escalate to Export Center leads.
- Advisory-AI consumers must map observation IDs via projection service; keep aggregation-only stance (no consensus logic) for all new APIs.
- **Risks & Mitigations**
- Observability sinks not ready for 31-003 → reuse Signals dashboards; ship log-only fallback. Severity: Medium.
- Mirror bundle schema still absent (blocks 56/57/58) → escalate to Export Center; track due date 2025-11-19; severity: High.
- Portable EvidenceLocker format not published (blocks 58-001) → request format drop from Evidence Locker leads; severity: High.
- Connector signer metadata schema missing (blocks CONN-TRUST-01-001) → chase schema artefact owners; severity: Medium.
- Attestation verifier misses 2025-11-16 target → daily stand-ups; parallel diagnostics; severity: High.
## Next Checkpoints
| Date (UTC) | Session / Owner | Goal | Fallback |
| 2025-11-18 | Scanner mock bundle v1 delivered | Start GRAPH-INDEX/ZASTAVA tests using mock; publish hash | Scanner Guild |
| --- | --- | --- | --- |
| 2025-11-17 | Coordinator · WebService/Observability Guilds | Counters/logs-only fallback approved; start 31-003 execution without span sink. | Keep span sink as follow-on milestone. |
| 2025-11-14 | Connector provenance schema review (Connectors + Security Guilds) | Approve signer fingerprint + issuer tier schema for CONN-TRUST-01-001. | If schema not ready, keep task blocked and request interim metadata list from connectors. |
| 2025-11-15 | Export Center mirror schema sync (Export Center + Excititor + AirGap) | Receive mirror bundle manifest to unblock 56/57. | If delayed, escalate to Sprint 162 leads and use placeholder spec with clearly marked TODO. |
| 2025-11-16 | Attestation verifier rehearsal (Excititor Attestation Guild) | Demo `IVexAttestationVerifier` harness + diagnostics to unblock 73-* tasks. | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR |
| 2025-11-18 | Observability span sink deploy (Ops/Signals Guild) | Enable telemetry pipeline needed for 31-003. | If deploy slips, implement temporary counters/logs and keep action tracker flagged as blocked. |
| 2025-11-19 | Connector metadata inventory (Connectors Guild) | Confirm signer metadata coverage for CONN-TRUST-01-001 rollout. | Fall back to partial coverage with feature flags. |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- **Decisions**
- Until Ops span sink lands, keep observability fallback to log-only counters per `docs/modules/excititor/operations/observability.md`.
- If Export Center mirror schema slips, temporarily use placeholder from `docs/modules/export-center/architecture.md` with deltas noted; escalate to Export Center leads.
- Advisory-AI consumers must map observation IDs via projection service; keep aggregation-only stance (no consensus logic) for all new APIs.
- **Risks & Mitigations**
- Observability sinks not ready for 31-003 → reuse Signals dashboards; ship log-only fallback. Severity: Medium.
- Mirror bundle schema still absent (blocks 56/57/58) → escalate to Export Center; track due date 2025-11-19; severity: High.
- Portable EvidenceLocker format not published (blocks 58-001) → request format drop from Evidence Locker leads; severity: High.
- Connector signer metadata schema missing (blocks CONN-TRUST-01-001) → chase schema artefact owners; severity: Medium.
- Attestation verifier misses 2025-11-16 target → daily stand-ups; parallel diagnostics; severity: High.
## Next Checkpoints
| Date (UTC) | Session / Owner | Goal | Fallback |
| 2025-11-18 | Scanner mock bundle v1 delivered | Start GRAPH-INDEX/ZASTAVA tests using mock; publish hash | Scanner Guild |
| --- | --- | --- | --- |
| 2025-11-17 | Coordinator · WebService/Observability Guilds | Counters/logs-only fallback approved; start 31-003 execution without span sink. | Keep span sink as follow-on milestone. |
| 2025-11-14 | Connector provenance schema review (Connectors + Security Guilds) | Approve signer fingerprint + issuer tier schema for CONN-TRUST-01-001. | If schema not ready, keep task blocked and request interim metadata list from connectors. |
| 2025-11-15 | Export Center mirror schema sync (Export Center + Excititor + AirGap) | Receive mirror bundle manifest to unblock 56/57. | If delayed, escalate to Sprint 162 leads and use placeholder spec with clearly marked TODO. |
| P5 | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Planning | Planning | Rehearsal harness plan captured in `docs/modules/excititor/prep/2025-11-22-attestation-rehearsal-prep.md`; ready for execution. |
| 2025-11-18 | Observability span sink deploy (Ops/Signals Guild) | Enable telemetry pipeline needed for 31-003. | If deploy slips, implement temporary counters/logs and keep action tracker flagged as blocked. |
| 2025-11-19 | Connector metadata inventory (Connectors Guild) | Confirm signer metadata coverage for CONN-TRUST-01-001 rollout. | Fall back to partial coverage with feature flags. |

View File

@@ -1,86 +1,89 @@
# Sprint 0120-0000-0001 · Policy & Reasoning
## Topic & Scope
- Deliver ledger observability baselines (LEDGER-29-007/008/009) so Policy teams can trust ingestion, anchoring, and replay at >5M findings/tenant.
- Extend ledger provenance to orchestrator jobs, air-gapped bundle imports, and attestation evidence (LEDGER-34-101, LEDGER-AIRGAP-56/57/58, LEDGER-ATTEST-73-001).
- Ship deployment collateral (Helm/Compose, backup/restore, offline kit) so downstream guilds can adopt without bespoke guidance.
- Working directory: `src/Findings/StellaOps.Findings.Ledger`.
## Dependencies & Concurrency
- Upstream obligations: Sprint 110.A AdvisoryAI must land; Observability Guild must sign off `ledger_*` metric schema; mirror bundle schema freeze required before LEDGER-AIRGAP-*; attestation pointer schema must align with NOTIFY-ATTEST-74-001.
- Concurrency guardrails: execute tasks in order DOING → TODO → BLOCKED; orchestrator export contract is tracked with Sprint 150.A to avoid cross-guild contention.
- Entry criteria: upstream AdvisoryAI deliverables complete; Observability-approved metric names/labels; published mirror bundle schemas for AirGap kits.
- Exit criteria: metrics/logs/dashboards live in ops telemetry packs with alerts; determinism/load harness produces signed 5M findings report; deployment manifests + offline kits reviewed by DevOps/AirGap guilds; ledger records pointers to orchestrator runs, bundle provenance, and attestation envelopes.
**External dependency tracker**
| Dependency | Current state (2025-11-13) | Impact |
| --- | --- | --- |
| Sprint 110.A AdvisoryAI | DONE | Enables Findings.I start; monitor regressions. |
| Observability metric schema | IN REVIEW | Blocks LEDGER-29-007/008 dashboards. |
| Orchestrator job export contract | TODO | Required for LEDGER-34-101; tracked in Sprint 150.A wave table. |
| Mirror bundle schema | DRAFT | Needed for LEDGER-AIRGAP-56/57/58 messaging + manifests. |
| Attestation pointer schema | DRAFT | Needs alignment with NOTIFY-ATTEST-74-001 to reuse DSSE IDs. |
**Cluster snapshot**
- **Observability & diagnostics** (LEDGER-29-007/008 · Findings Ledger Guild · Observability Guild · QA Guild) — Status TODO. Metric/log spec captured in `docs/modules/findings-ledger/observability.md`; determinism harness spec in `docs/modules/findings-ledger/replay-harness.md`; sequencing documented in `docs/modules/findings-ledger/implementation_plan.md`. Awaiting Observability sign-off + Grafana JSON export (target 2025-11-15).
- **Deployment & backup** (LEDGER-29-009 · Findings Ledger Guild · DevOps Guild) — Status TODO. Baseline deployment/backup guide published (`docs/modules/findings-ledger/deployment.md`); need Compose/Helm overlays and automated migrations.
- **Orchestrator provenance** (LEDGER-34-101 · Findings Ledger Guild) — Status TODO. Blocked until Orchestrator exports job ledger payload; coordinate with Sprint 150.A deliverables.
- **Air-gap provenance & staleness** (LEDGER-AIRGAP-56/57/58 · Findings Ledger Guild · AirGap Guilds · Evidence Locker Guild) — Status TODO. Requirements captured in `docs/modules/findings-ledger/airgap-provenance.md`; waiting on mirror bundle schema freeze + AirGap controller inputs.
- **Attestation linkage** (LEDGER-ATTEST-73-001 · Findings Ledger Guild · Attestor Service Guild) — Status TODO. Waiting on attestation payload pointers from NOTIFY-ATTEST-74-001 work to reuse DSSE IDs.
## Documentation Prerequisites
- `docs/modules/findings-ledger/observability.md`
- `docs/modules/findings-ledger/replay-harness.md`
- `docs/modules/findings-ledger/deployment.md`
- `docs/modules/findings-ledger/implementation_plan.md`
- `docs/modules/findings-ledger/airgap-provenance.md`
- `docs/observability/policy.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA | BLOCKED | Due 2025-11-21 · Accountable: Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Await Observability schema sign-off + ledger write endpoint contract; 5M fixture drop pending. <br><br> Document artefact/deliverable for LEDGER-29-008 and publish location so downstream tasks can proceed. |
| P2 | PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT | BLOCKED | Due 2025-11-21 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Orchestrator ledger export contract (Sprint 150.A) not published. <br><br> Document artefact/deliverable for LEDGER-34-101 and publish location so downstream tasks can proceed. |
| P3 | PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | BLOCKED | Due 2025-11-21 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Mirror bundle schema freeze outstanding. <br><br> Document artefact/deliverable for LEDGER-AIRGAP-56-001 and publish location so downstream tasks can proceed. |
| 1 | LEDGER-29-007 | DONE (2025-11-17) | Observability metric schema sign-off; deps LEDGER-29-006 | Findings Ledger Guild, Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Instrument `ledger_write_latency`, `projection_lag_seconds`, `ledger_events_total`, structured logs, Merkle anchoring alerts, and publish dashboards. |
| 2 | LEDGER-29-008 | BLOCKED | PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Develop unit/property/integration tests, replay/restore tooling, determinism harness, and load tests at 5M findings/tenant. |
| 3 | LEDGER-29-009 | BLOCKED | Depends on LEDGER-29-008 harness results (5M replay + observability schema) | Findings Ledger Guild, DevOps Guild / `src/Findings/StellaOps.Findings.Ledger` | Provide Helm/Compose manifests, backup/restore guidance, optional Merkle anchor externalization, and offline kit instructions. |
| 4 | LEDGER-34-101 | BLOCKED | PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Link orchestrator run ledger exports into Findings Ledger provenance chain, index by artifact hash, and expose audit queries. |
| 5 | LEDGER-AIRGAP-56-001 | BLOCKED | PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Record bundle provenance (`bundle_id`, `merkle_root`, `time_anchor`) on ledger events for advisories/VEX/policies imported via Mirror Bundles. |
| 6 | LEDGER-AIRGAP-56-002 | BLOCKED | Depends on LEDGER-AIRGAP-56-001 provenance schema | Findings Ledger Guild, AirGap Time Guild / `src/Findings/StellaOps.Findings.Ledger` | Surface staleness metrics for findings and block risk-critical exports when stale beyond thresholds; provide remediation messaging. |
| 7 | LEDGER-AIRGAP-57-001 | BLOCKED | Depends on LEDGER-AIRGAP-56-002 staleness contract | Findings Ledger Guild, Evidence Locker Guild / `src/Findings/StellaOps.Findings.Ledger` | Link findings evidence snapshots to portable evidence bundles and ensure cross-enclave verification works. |
| 8 | LEDGER-AIRGAP-58-001 | BLOCKED | Depends on LEDGER-AIRGAP-57-001 bundle linkage | Findings Ledger Guild, AirGap Controller Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit timeline events for bundle import impacts (new findings, remediation changes) with sealed-mode context. |
| 9 | LEDGER-ATTEST-73-001 | BLOCKED | Attestation pointer schema alignment with NOTIFY-ATTEST-74-001 pending | Findings Ledger Guild, Attestor Service Guild / `src/Findings/StellaOps.Findings.Ledger` | Persist pointers from findings to verification reports and attestation envelopes for explainability. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P1P3 BLOCKED: observability schema, orchestrator ledger export contract, and mirror bundle schema are still missing, keeping LEDGER-29-008/34-101/AIRGAP-56-* blocked. | Project Mgmt |
| 2025-11-13 09:30 | Documented Findings.I scope, milestones, and external dependencies; awaiting Observability + Orchestrator inputs before flipping any tasks to DOING. | Findings Ledger Guild |
| 2025-11-13 10:45 | Published `docs/modules/findings-ledger/observability.md` detailing metrics/logs/alerts required for LEDGER-29-007/008; sent draft to Observability Guild for review. | Findings Ledger Guild |
| 2025-11-19 09:30 | Reformatted Cluster snapshot into bullet list and confirmed Delivery Tracker already covers LEDGER-AIRGAP dependencies; no scope change. | Project Mgmt |
| 2025-11-13 11:20 | Added `docs/modules/findings-ledger/deployment.md` covering Compose/Helm rollout, migrations, backup/restore, and offline workflows for LEDGER-29-009. | Findings Ledger Guild |
| 2025-11-13 11:50 | Added `docs/modules/findings-ledger/replay-harness.md` outlining fixtures, CLI workflow, and reporting for LEDGER-29-008 determinism tests. | Findings Ledger Guild |
| 2025-11-13 12:05 | Drafted `docs/modules/findings-ledger/implementation_plan.md` summarizing phase sequencing and dependencies for Findings.I. | Findings Ledger Guild |
| 2025-11-13 12:25 | Authored `docs/modules/findings-ledger/airgap-provenance.md` detailing bundle provenance, staleness, evidence snapshot, and timeline requirements for LEDGER-AIRGAP-56/57/58. | Findings Ledger Guild |
| 2025-11-16 | Normalised sprint to standard template and renamed to `SPRINT_0120_0000_0001_policy_reasoning.md`; no content changes beyond reformat. | Project Management |
| 2025-11-16 | Added `src/Findings/AGENTS.md` synthesising required reading, boundaries, determinism/observability rules for implementers. | Project Management |
| 2025-11-17 | LEDGER-29-007 complete: dashboards + alert rules added to offline bundle; Cobertura coverage captured at `out/coverage/ledger/4d714ddd-216e-4643-ba81-2b8a4ffda218/coverage.cobertura.xml`; bundling script updated. | Findings Ledger Guild |
| 2025-11-17 | LEDGER-29-008 started: replay harness skeleton added (`src/Findings/tools/LedgerReplayHarness`), sample fixture + tests; currently BLOCKED awaiting Observability schema + ledger writer/projection contract + 5M fixture drop. | Findings Ledger Guild |
| 2025-11-18 | Reviewed remaining tasks: 29-009, 34-101, AIRGAP-56/57/58, and ATTEST-73 all blocked by upstream contracts (harness results, orchestrator export schema, mirror bundle freeze, attestation pointer spec); no new implementation started. | Findings Ledger Guild |
## Decisions & Risks
- Metric names locked by 2025-11-15 and documented in `docs/observability/policy.md` to avoid schema churn.
- Replay workload risk: 5M findings load may exceed lab capacity; mitigation is to use the QA replay rig and capture CPU/memory budgets in runbooks.
- Air-gap drift risk: mirror bundle format still moving; mitigation is to version the provenance schema and gate LEDGER-AIRGAP-* merges until docs/manifests updated.
- Cross-guild lag risk: Orchestrator/Attestor dependencies may delay provenance pointers; mitigation is weekly sync notes and feature flags so ledger work can land behind toggles.
- Implementer contract now anchored in `src/Findings/AGENTS.md`; keep in sync with module docs and update sprint log when changed.
- Current state (2025-11-18): all remaining tasks (29-009, 34-101, AIRGAP-56/57/58, ATTEST-73) blocked on upstream contracts: 5M harness + observability schema, orchestrator export contract, mirror bundle schema freeze, and attestation pointer spec respectively. Resume once those inputs land.
## Next Checkpoints
- 2025-11-15 · Metrics + dashboard schema sign-off — Observability Guild — unblocks LEDGER-29-007 instrumentation PR.
- 2025-11-18 · Determinism + replay harness dry-run at 5M findings — QA Guild — required before LEDGER-29-008 can close.
- 2025-11-20 · Helm/Compose manifests + backup doc review — DevOps Guild · AirGap Controller Guild — needed for LEDGER-29-009 + LEDGER-AIRGAP-56-001.
- 2025-11-22 · Mirror bundle provenance schema freeze — AirGap Time Guild — enables LEDGER-AIRGAP-56/57/58 sequencing.
- 2025-11-25 · Orchestrator ledger export contract signed — Orchestrator Guild — prerequisite for LEDGER-34-101 linkage.
# Sprint 0120-0000-0001 · Policy & Reasoning
## Topic & Scope
- Deliver ledger observability baselines (LEDGER-29-007/008/009) so Policy teams can trust ingestion, anchoring, and replay at >5M findings/tenant.
- Extend ledger provenance to orchestrator jobs, air-gapped bundle imports, and attestation evidence (LEDGER-34-101, LEDGER-AIRGAP-56/57/58, LEDGER-ATTEST-73-001).
- Ship deployment collateral (Helm/Compose, backup/restore, offline kit) so downstream guilds can adopt without bespoke guidance.
- Working directory: `src/Findings/StellaOps.Findings.Ledger`.
## Dependencies & Concurrency
- Upstream obligations: Sprint 110.A AdvisoryAI must land; Observability Guild must sign off `ledger_*` metric schema; mirror bundle schema freeze required before LEDGER-AIRGAP-*; attestation pointer schema must align with NOTIFY-ATTEST-74-001.
- Concurrency guardrails: execute tasks in order DOING → TODO → BLOCKED; orchestrator export contract is tracked with Sprint 150.A to avoid cross-guild contention.
- Entry criteria: upstream AdvisoryAI deliverables complete; Observability-approved metric names/labels; published mirror bundle schemas for AirGap kits.
- Exit criteria: metrics/logs/dashboards live in ops telemetry packs with alerts; determinism/load harness produces signed 5M findings report; deployment manifests + offline kits reviewed by DevOps/AirGap guilds; ledger records pointers to orchestrator runs, bundle provenance, and attestation envelopes.
**External dependency tracker**
| Dependency | Current state (2025-11-13) | Impact |
| --- | --- | --- |
| Sprint 110.A AdvisoryAI | DONE | Enables Findings.I start; monitor regressions. |
| Observability metric schema | IN REVIEW | Blocks LEDGER-29-007/008 dashboards. |
| Orchestrator job export contract | TODO | Required for LEDGER-34-101; tracked in Sprint 150.A wave table. |
| Mirror bundle schema | DRAFT | Needed for LEDGER-AIRGAP-56/57/58 messaging + manifests. |
| Attestation pointer schema | DRAFT | Needs alignment with NOTIFY-ATTEST-74-001 to reuse DSSE IDs. |
**Cluster snapshot**
- **Observability & diagnostics** (LEDGER-29-007/008 · Findings Ledger Guild · Observability Guild · QA Guild) — Status TODO. Metric/log spec captured in `docs/modules/findings-ledger/observability.md`; determinism harness spec in `docs/modules/findings-ledger/replay-harness.md`; sequencing documented in `docs/modules/findings-ledger/implementation_plan.md`. Awaiting Observability sign-off + Grafana JSON export (target 2025-11-15).
- **Deployment & backup** (LEDGER-29-009 · Findings Ledger Guild · DevOps Guild) — Status TODO. Baseline deployment/backup guide published (`docs/modules/findings-ledger/deployment.md`); need Compose/Helm overlays and automated migrations.
- **Orchestrator provenance** (LEDGER-34-101 · Findings Ledger Guild) — Status TODO. Blocked until Orchestrator exports job ledger payload; coordinate with Sprint 150.A deliverables.
- **Air-gap provenance & staleness** (LEDGER-AIRGAP-56/57/58 · Findings Ledger Guild · AirGap Guilds · Evidence Locker Guild) — Status TODO. Requirements captured in `docs/modules/findings-ledger/airgap-provenance.md`; waiting on mirror bundle schema freeze + AirGap controller inputs.
- **Attestation linkage** (LEDGER-ATTEST-73-001 · Findings Ledger Guild · Attestor Service Guild) — Status TODO. Waiting on attestation payload pointers from NOTIFY-ATTEST-74-001 work to reuse DSSE IDs.
## Documentation Prerequisites
- `docs/modules/findings-ledger/observability.md`
- `docs/modules/findings-ledger/replay-harness.md`
- `docs/modules/findings-ledger/deployment.md`
- `docs/modules/findings-ledger/implementation_plan.md`
- `docs/modules/findings-ledger/airgap-provenance.md`
- `docs/observability/policy.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Observability schema and metrics/log contract captured in `docs/modules/findings-ledger/prep/2025-11-22-ledger-airgap-prep.md`; 5M harness can proceed. |
| P2 | PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Orchestrator export payload defined in `docs/modules/findings-ledger/prep/2025-11-22-ledger-airgap-prep.md`; unblock ledger linkage. |
| P3 | PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | DONE (2025-11-22) | Due 2025-11-21 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Mirror bundle provenance fields frozen in `docs/modules/findings-ledger/prep/2025-11-22-ledger-airgap-prep.md`; staleness/anchor rules defined. |
| 1 | LEDGER-29-007 | DONE (2025-11-17) | Observability metric schema sign-off; deps LEDGER-29-006 | Findings Ledger Guild, Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Instrument `ledger_write_latency`, `projection_lag_seconds`, `ledger_events_total`, structured logs, Merkle anchoring alerts, and publish dashboards. |
| 2 | LEDGER-29-008 | TODO | PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Develop unit/property/integration tests, replay/restore tooling, determinism harness, and load tests at 5M findings/tenant. |
| 3 | LEDGER-29-009 | BLOCKED | Depends on LEDGER-29-008 harness results (5M replay + observability schema) | Findings Ledger Guild, DevOps Guild / `src/Findings/StellaOps.Findings.Ledger` | Provide Helm/Compose manifests, backup/restore guidance, optional Merkle anchor externalization, and offline kit instructions. |
| 4 | LEDGER-34-101 | TODO | PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Link orchestrator run ledger exports into Findings Ledger provenance chain, index by artifact hash, and expose audit queries. |
| 5 | LEDGER-AIRGAP-56-001 | TODO | PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Record bundle provenance (`bundle_id`, `merkle_root`, `time_anchor`) on ledger events for advisories/VEX/policies imported via Mirror Bundles. |
| 6 | LEDGER-AIRGAP-56-002 | BLOCKED | Depends on LEDGER-AIRGAP-56-001 provenance schema | Findings Ledger Guild, AirGap Time Guild / `src/Findings/StellaOps.Findings.Ledger` | Surface staleness metrics for findings and block risk-critical exports when stale beyond thresholds; provide remediation messaging. |
| 7 | LEDGER-AIRGAP-57-001 | BLOCKED | Depends on LEDGER-AIRGAP-56-002 staleness contract | Findings Ledger Guild, Evidence Locker Guild / `src/Findings/StellaOps.Findings.Ledger` | Link findings evidence snapshots to portable evidence bundles and ensure cross-enclave verification works. |
| 8 | LEDGER-AIRGAP-58-001 | BLOCKED | Depends on LEDGER-AIRGAP-57-001 bundle linkage | Findings Ledger Guild, AirGap Controller Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit timeline events for bundle import impacts (new findings, remediation changes) with sealed-mode context. |
| 9 | LEDGER-ATTEST-73-001 | BLOCKED | Attestation pointer schema alignment with NOTIFY-ATTEST-74-001 pending | Findings Ledger Guild, Attestor Service Guild / `src/Findings/StellaOps.Findings.Ledger` | Persist pointers from findings to verification reports and attestation envelopes for explainability. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P1P3 BLOCKED: observability schema, orchestrator ledger export contract, and mirror bundle schema are still missing, keeping LEDGER-29-008/34-101/AIRGAP-56-* blocked. | Project Mgmt |
| 2025-11-13 09:30 | Documented Findings.I scope, milestones, and external dependencies; awaiting Observability + Orchestrator inputs before flipping any tasks to DOING. | Findings Ledger Guild |
| 2025-11-13 10:45 | Published `docs/modules/findings-ledger/observability.md` detailing metrics/logs/alerts required for LEDGER-29-007/008; sent draft to Observability Guild for review. | Findings Ledger Guild |
| 2025-11-19 09:30 | Reformatted Cluster snapshot into bullet list and confirmed Delivery Tracker already covers LEDGER-AIRGAP dependencies; no scope change. | Project Mgmt |
| 2025-11-13 11:20 | Added `docs/modules/findings-ledger/deployment.md` covering Compose/Helm rollout, migrations, backup/restore, and offline workflows for LEDGER-29-009. | Findings Ledger Guild |
| 2025-11-13 11:50 | Added `docs/modules/findings-ledger/replay-harness.md` outlining fixtures, CLI workflow, and reporting for LEDGER-29-008 determinism tests. | Findings Ledger Guild |
| 2025-11-13 12:05 | Drafted `docs/modules/findings-ledger/implementation_plan.md` summarizing phase sequencing and dependencies for Findings.I. | Findings Ledger Guild |
| 2025-11-13 12:25 | Authored `docs/modules/findings-ledger/airgap-provenance.md` detailing bundle provenance, staleness, evidence snapshot, and timeline requirements for LEDGER-AIRGAP-56/57/58. | Findings Ledger Guild |
| 2025-11-16 | Normalised sprint to standard template and renamed to `SPRINT_0120_0000_0001_policy_reasoning.md`; no content changes beyond reformat. | Project Management |
| 2025-11-16 | Added `src/Findings/AGENTS.md` synthesising required reading, boundaries, determinism/observability rules for implementers. | Project Management |
| 2025-11-17 | LEDGER-29-007 complete: dashboards + alert rules added to offline bundle; Cobertura coverage captured at `out/coverage/ledger/4d714ddd-216e-4643-ba81-2b8a4ffda218/coverage.cobertura.xml`; bundling script updated. | Findings Ledger Guild |
| 2025-11-17 | LEDGER-29-008 started: replay harness skeleton added (`src/Findings/tools/LedgerReplayHarness`), sample fixture + tests; currently BLOCKED awaiting Observability schema + ledger writer/projection contract + 5M fixture drop. | Findings Ledger Guild |
| 2025-11-18 | Reviewed remaining tasks: 29-009, 34-101, AIRGAP-56/57/58, and ATTEST-73 all blocked by upstream contracts (harness results, orchestrator export schema, mirror bundle freeze, attestation pointer spec); no new implementation started. | Findings Ledger Guild |
| 2025-11-22 | Published `docs/modules/findings-ledger/prep/2025-11-22-ledger-airgap-prep.md`; set PREP tasks P1P3 to DONE. | Project Mgmt |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
| 2025-11-22 | PREP contracts published; moved LEDGER-29-008, LEDGER-34-101, and LEDGER-AIRGAP-56-001 to TODO. | Project Mgmt |
## Decisions & Risks
- Metric names locked by 2025-11-15 and documented in `docs/observability/policy.md` to avoid schema churn.
- Replay workload risk: 5M findings load may exceed lab capacity; mitigation is to use the QA replay rig and capture CPU/memory budgets in runbooks.
- Air-gap drift risk: mirror bundle format still moving; mitigation is to version the provenance schema and gate LEDGER-AIRGAP-* merges until docs/manifests updated.
- Cross-guild lag risk: Orchestrator/Attestor dependencies may delay provenance pointers; mitigation is weekly sync notes and feature flags so ledger work can land behind toggles.
- Implementer contract now anchored in `src/Findings/AGENTS.md`; keep in sync with module docs and update sprint log when changed.
- Current state (2025-11-18): all remaining tasks (29-009, 34-101, AIRGAP-56/57/58, ATTEST-73) blocked on upstream contracts: 5M harness + observability schema, orchestrator export contract, mirror bundle schema freeze, and attestation pointer spec respectively. Resume once those inputs land.
## Next Checkpoints
- 2025-11-15 · Metrics + dashboard schema sign-off — Observability Guild — unblocks LEDGER-29-007 instrumentation PR.
- 2025-11-18 · Determinism + replay harness dry-run at 5M findings — QA Guild — required before LEDGER-29-008 can close.
- 2025-11-20 · Helm/Compose manifests + backup doc review — DevOps Guild · AirGap Controller Guild — needed for LEDGER-29-009 + LEDGER-AIRGAP-56-001.
- 2025-11-22 · Mirror bundle provenance schema freeze — AirGap Time Guild — enables LEDGER-AIRGAP-56/57/58 sequencing.
- 2025-11-25 · Orchestrator ledger export contract signed — Orchestrator Guild — prerequisite for LEDGER-34-101 linkage.

View File

@@ -27,12 +27,12 @@
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-LEDGER-EXPORT-35-001-NO-HTTP-API-SURFACE | DONE (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Export HTTP surface + filters spec published at `docs/modules/findings-ledger/export-http-surface.md`; downstream tasks may proceed against documented contract. |
| P2 | PREP-LEDGER-OAS-61-001-ABSENT-OAS-BASELINE-AN | DONE (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild; API Contracts Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; API Contracts Guild / src/Findings/StellaOps.Findings.Ledger | Artifact published: `docs/modules/findings-ledger/openapi/findings-ledger.v1.yaml` with servers/security/paths; summary in `docs/modules/findings-ledger/oas-baseline.md`. |
| P3 | PREP-LEDGER-OAS-61-002-DEPENDS-ON-61-001-CONT | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Depends on 61-001 contract + HTTP surface. <br><br> Document artefact/deliverable for LEDGER-OAS-61-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-oas-prep.md`. |
| P4 | PREP-LEDGER-OAS-62-001-SDK-GENERATION-PENDING | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | SDK generation pending 61-002. <br><br> Document artefact/deliverable for LEDGER-OAS-62-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-oas-prep.md`. |
| P5 | PREP-LEDGER-OAS-63-001-DEPENDENT-ON-SDK-VALID | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Dependent on SDK validation (62-001). <br><br> Document artefact/deliverable for LEDGER-OAS-63-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-oas-prep.md`. |
| P6 | PREP-LEDGER-OBS-54-001-NO-HTTP-SURFACE-MINIMA | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | No HTTP surface/minimal API present in module to host `/ledger/attestations`; needs API contract + service scaffold. <br><br> Prep artefact now available: `docs/modules/findings-ledger/prep/ledger-attestations-http.md` defining `/v1/ledger/attestations` contract; service surface still required. |
| P3 | PREP-LEDGER-OAS-61-002-DEPENDS-ON-61-001-CONT | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Depends on 61-001 contract + HTTP surface. <br><br> Document artefact/deliverable for LEDGER-OAS-61-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-oas-prep.md`. |
| P4 | PREP-LEDGER-OAS-62-001-SDK-GENERATION-PENDING | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | SDK generation pending 61-002. <br><br> Document artefact/deliverable for LEDGER-OAS-62-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-oas-prep.md`. |
| P5 | PREP-LEDGER-OAS-63-001-DEPENDENT-ON-SDK-VALID | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Dependent on SDK validation (62-001). <br><br> Document artefact/deliverable for LEDGER-OAS-63-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-oas-prep.md`. |
| P6 | PREP-LEDGER-OBS-54-001-NO-HTTP-SURFACE-MINIMA | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | No HTTP surface/minimal API present in module to host `/ledger/attestations`; needs API contract + service scaffold. <br><br> Prep artefact now available: `docs/modules/findings-ledger/prep/ledger-attestations-http.md` defining `/v1/ledger/attestations` contract; service surface still required. |
| P7 | PREP-LEDGER-OBS-55-001-DEPENDS-ON-54-001-ATTE | DONE (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Artefact published: ledger attestation HTTP surface prep (`docs/modules/findings-ledger/prep/ledger-attestations-http.md`) outlining `/v1/ledger/attestations` contract; pagination, determinism, and fields defined. |
| P8 | PREP-LEDGER-PACKS-42-001-SNAPSHOT-TIME-TRAVEL | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Snapshot/time-travel contract and bundle format not specified; needs design input. <br><br> Document artefact/deliverable for LEDGER-PACKS-42-001 and publish location so downstream tasks can proceed. |
| P8 | PREP-LEDGER-PACKS-42-001-SNAPSHOT-TIME-TRAVEL | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Snapshot/time-travel contract and bundle format not specified; needs design input. <br><br> Document artefact/deliverable for LEDGER-PACKS-42-001 and publish location so downstream tasks can proceed. |
| P9 | PREP-LEDGER-RISK-66-001-RISK-ENGINE-SCHEMA-CO | DONE (2025-11-21) | Due 2025-11-22 · Accountable: Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Prep doc published at `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`; risk fields and rollout plan defined for downstream implementation. |
| P10 | PREP-LEDGER-RISK-66-002-DEPENDS-ON-66-001-MIG | DONE (2025-11-21) | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Depends on 66-001 migration + risk scoring contract. Prep doc published at `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| 1 | LEDGER-ATTEST-73-002 | BLOCKED | Waiting on LEDGER-ATTEST-73-001 verification pipeline delivery | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Enable search/filter in findings projections by verification result and attestation status |
@@ -73,6 +73,7 @@
| 2025-11-17 | Marked EXPORT/OAS/PACKS/RISK tasks BLOCKED pending API surface, contracts, and risk engine inputs. | Findings Ledger |
| 2025-11-18 | Attempted to continue sprint; all remaining tasks still blocked by absent HTTP surface, OAS/SDK contracts, and risk schema inputsno new work started. | Findings Ledger |
| 2025-11-18 | Reviewed adjacent sprints (0120, 0122) for unblocked Findings Ledger work; none available. Remaining idle until upstream contracts land. | Findings Ledger |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Upstream dependency on Sprint 120.B (Findings.I); block start until merged.

View File

@@ -24,9 +24,9 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-LEDGER-RISK-68-001-AWAIT-UNBLOCK-OF-67-0 | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Await unblock of 67-001 + Export Center contract for scored findings. <br><br> Document artefact/deliverable for LEDGER-RISK-68-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| P2 | PREP-LEDGER-RISK-69-001-REQUIRES-67-001-68-00 | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Requires 67-001/68-001 to define metrics dimensions. <br><br> Document artefact/deliverable for LEDGER-RISK-69-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| P3 | PREP-LEDGER-TEN-48-001-NEEDS-PLATFORM-APPROVE | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Needs platform-approved partitioning + RLS policy (tenant/project shape, session variables). <br><br> Document artefact/deliverable for LEDGER-TEN-48-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| P1 | PREP-LEDGER-RISK-68-001-AWAIT-UNBLOCK-OF-67-0 | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Await unblock of 67-001 + Export Center contract for scored findings. <br><br> Document artefact/deliverable for LEDGER-RISK-68-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| P2 | PREP-LEDGER-RISK-69-001-REQUIRES-67-001-68-00 | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Requires 67-001/68-001 to define metrics dimensions. <br><br> Document artefact/deliverable for LEDGER-RISK-69-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| P3 | PREP-LEDGER-TEN-48-001-NEEDS-PLATFORM-APPROVE | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Needs platform-approved partitioning + RLS policy (tenant/project shape, session variables). <br><br> Document artefact/deliverable for LEDGER-TEN-48-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/findings-ledger/prep/2025-11-20-ledger-risk-prep.md`. |
| 1 | LEDGER-RISK-67-001 | BLOCKED | Depends on risk scoring contract + migrations from LEDGER-RISK-66-002 | Findings Ledger Guild · Risk Engine Guild / `src/Findings/StellaOps.Findings.Ledger` | Expose query APIs for scored findings with score/severity filters, pagination, and explainability links |
| 2 | LEDGER-RISK-68-001 | BLOCKED | PREP-LEDGER-RISK-68-001-AWAIT-UNBLOCK-OF-67-0 | Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Enable export of scored findings and simulation results via Export Center integration |
| 3 | LEDGER-RISK-69-001 | BLOCKED | PREP-LEDGER-RISK-69-001-REQUIRES-67-001-68-00 | Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit metrics/dashboards for scoring latency, result freshness, severity distribution, provider gaps |
@@ -40,6 +40,7 @@
| 2025-11-18 | Renamed file to `SPRINT_0122_0001_0001_policy_reasoning.md` and normalised to standard template; no scope changes. | Findings Ledger |
| 2025-11-18 | Set LEDGER-RISK-67-001/68-001/69-001 to BLOCKED pending risk-scoring contract (66-002) and export metrics dimensions. | Findings Ledger |
| 2025-11-18 | Set LEDGER-TEN-48-001 to BLOCKED pending DB partition/RLS design (tenant+project keys, session variables) from Platform/DB guild. | Findings Ledger |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Risk scoring contract (LEDGER-RISK-66-002) not delivered; query/export tasks paused until schema and API surface exist.

View File

@@ -1,52 +1,53 @@
# Sprint 0124-0001-0001 · Policy & Reasoning (Policy Engine phase II)
## Topic & Scope
- Continue Policy Engine core (Policy.II): deterministic evaluator, materialization, simulation, tracing, and storage.
- Ensure aggregation-only behavior; no wall-clock/RNG/network use during evaluation.
- **Working directory:** `src/Policy/StellaOps.Policy.Engine` (and `src/Policy/__Libraries/StellaOps.Policy`).
## Dependencies & Concurrency
- Upstream: Sprint 120.C Policy.I must land before this track.
- Concurrency: execute tasks in listed order (DOING → TODO → BLOCKED).
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/policy/architecture.md`
## Delivery Tracker
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| P1 | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | DOING (2025-11-20) | 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 | TODO | Produce simulation diff metadata and approval endpoints for Console (deps: POLICY-CONSOLE-23-001). | Policy Guild, Product Ops / `src/Policy/StellaOps.Policy.Engine` |
| 2 | POLICY-ENGINE-20-002 | BLOCKED (2025-10-26) | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 3 | POLICY-ENGINE-20-003 | TODO | Depends on 20-002. | Policy · Concelier · Excititor Guilds / `src/Policy/StellaOps.Policy.Engine` |
| 4 | POLICY-ENGINE-20-004 | TODO | Depends on 20-003. | Policy · Platform Storage Guild / `src/Policy/StellaOps.Policy.Engine` |
| 5 | POLICY-ENGINE-20-005 | TODO | Depends on 20-004. | Policy · Security Engineering / `src/Policy/StellaOps.Policy.Engine` |
| 6 | POLICY-ENGINE-20-006 | TODO | Depends on 20-005. | Policy · Scheduler Worker Guild / `src/Policy/StellaOps.Policy.Engine` |
| 7 | POLICY-ENGINE-20-007 | TODO | Depends on 20-006. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` |
| 8 | POLICY-ENGINE-20-008 | TODO | Depends on 20-007. | Policy · QA Guild / `src/Policy/StellaOps.Policy.Engine` |
| 9 | POLICY-ENGINE-20-009 | TODO | Depends on 20-008. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` |
| 10 | POLICY-ENGINE-27-001 | TODO | Depends on 20-009. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 11 | POLICY-ENGINE-27-002 | TODO | Depends on 27-001. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` |
| 12 | POLICY-ENGINE-29-001 | TODO | Depends on 27-004. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 13 | POLICY-ENGINE-29-002 | TODO | Depends on 29-001. | Policy · Findings Ledger Guild / `src/Policy/StellaOps.Policy.Engine` |
## Execution Log
# Sprint 0124-0001-0001 · Policy & Reasoning (Policy Engine phase II)
## Topic & Scope
- Continue Policy Engine core (Policy.II): deterministic evaluator, materialization, simulation, tracing, and storage.
- Ensure aggregation-only behavior; no wall-clock/RNG/network use during evaluation.
- **Working directory:** `src/Policy/StellaOps.Policy.Engine` (and `src/Policy/__Libraries/StellaOps.Policy`).
## Dependencies & Concurrency
- Upstream: Sprint 120.C Policy.I must land before this track.
- Concurrency: execute tasks in listed order (DOING → TODO → BLOCKED).
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/policy/architecture.md`
## 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 | TODO | Produce simulation diff metadata and approval endpoints for Console (deps: POLICY-CONSOLE-23-001). | Policy Guild, Product Ops / `src/Policy/StellaOps.Policy.Engine` |
| 2 | POLICY-ENGINE-20-002 | BLOCKED (2025-10-26) | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 3 | POLICY-ENGINE-20-003 | TODO | Depends on 20-002. | Policy · Concelier · Excititor Guilds / `src/Policy/StellaOps.Policy.Engine` |
| 4 | POLICY-ENGINE-20-004 | TODO | Depends on 20-003. | Policy · Platform Storage Guild / `src/Policy/StellaOps.Policy.Engine` |
| 5 | POLICY-ENGINE-20-005 | TODO | Depends on 20-004. | Policy · Security Engineering / `src/Policy/StellaOps.Policy.Engine` |
| 6 | POLICY-ENGINE-20-006 | TODO | Depends on 20-005. | Policy · Scheduler Worker Guild / `src/Policy/StellaOps.Policy.Engine` |
| 7 | POLICY-ENGINE-20-007 | TODO | Depends on 20-006. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` |
| 8 | POLICY-ENGINE-20-008 | TODO | Depends on 20-007. | Policy · QA Guild / `src/Policy/StellaOps.Policy.Engine` |
| 9 | POLICY-ENGINE-20-009 | TODO | Depends on 20-008. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` |
| 10 | POLICY-ENGINE-27-001 | TODO | Depends on 20-009. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 11 | POLICY-ENGINE-27-002 | TODO | Depends on 27-001. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` |
| 12 | POLICY-ENGINE-29-001 | TODO | Depends on 27-004. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` |
| 13 | POLICY-ENGINE-29-002 | TODO | Depends on 29-001. | Policy · Findings Ledger Guild / `src/Policy/StellaOps.Policy.Engine` |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Published deterministic evaluator spec draft (docs/modules/policy/design/policy-deterministic-evaluator.md); moved PREP-POLICY-ENGINE-20-002 to DOING. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-08 | Sprint stub; awaiting staffing. | Planning |
| 2025-11-18 | All tasks still awaiting upstream evaluator specs; no progress. | Policy Guild |
| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_124_policy_reasoning.md` to `SPRINT_0124_0001_0001_policy_reasoning.md`; content preserved. | Implementer |
## Decisions & Risks
- Deterministic evaluator contract missing (blocks 20-002 and downstream chain).
- Console simulation/export contract (POLICY-CONSOLE-23-001) required to unblock 23-002.
- Storage/index schemas TBD; avoid implementation until specs freeze.
## Next Checkpoints
- Publish deterministic evaluator spec for 20-002 (date TBD).
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-08 | Sprint stub; awaiting staffing. | Planning |
| 2025-11-18 | All tasks still awaiting upstream evaluator specs; no progress. | Policy Guild |
| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_124_policy_reasoning.md` to `SPRINT_0124_0001_0001_policy_reasoning.md`; content preserved. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Deterministic evaluator contract missing (blocks 20-002 and downstream chain).
- Console simulation/export contract (POLICY-CONSOLE-23-001) required to unblock 23-002.
- Storage/index schemas TBD; avoid implementation until specs freeze.
## Next Checkpoints
- Publish deterministic evaluator spec for 20-002 (date TBD).
- Provide Console export/simulation contract for 23-001 to unblock 23-002.

View File

@@ -1,70 +1,71 @@
# Sprint 0125_0001_0001 · Mirror Bundles
## Topic & Scope
- Build the deterministic mirror bundle assembler covering advisories, VEX, policy packs, and optional OCI artefacts.
- Layer DSSE/TUF metadata, time anchors, and CLI automation so air-gapped sites receive verifiable bundles.
- Wire Export Center and scheduling hooks so mirror creation can be orchestrated automatically.
- **Working directory:** `src/Mirror/StellaOps.Mirror.Creator`.
## Dependencies & Concurrency
- Upstream: Sprint 110.D must deliver the assembler foundation (`MIRROR-CRT-56-001`). Attestor v2 contracts from Sprint 100.A remain required.
- Mirror sprints share the 120s decade with Policy & Reasoning work but remain independent; avoid adding dependencies on `SPRINT_125_policy_reasoning.md`.
- Evidence Locker, Export Center, CLI, and AirGap Time guild commitments must be available as soon as assembler code exists.
## Documentation Prerequisites
- `docs/modules/export-center/architecture.md`
- `docs/modules/airgap/architecture.md`
- `docs/modules/devops/architecture.md`
- `docs/modules/policy/architecture.md` (for provenance expectations)
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P0 | PREP-MIRROR-CRT-56-001-MILESTONE-0-PUBLISH | DONE (2025-11-19) | Due 2025-11-20 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Published milestone-0 thin bundle plan + sample at `out/mirror/thin/mirror-thin-m0-sample.tar.gz` with SHA256 `bd1013885a27f651e28331c7a240d417d265bd411d09b51b47bd7c2196659674` and layout note in `docs/modules/mirror/milestone-0-thin-bundle.md`. |
| P1 | PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Alex Kim (primary); Priya Desai (backup) | Alex Kim (primary); Priya Desai (backup) | Upstream Sprint 110.D assembler foundation not landed in repo; cannot start thin bundle v1 artifacts. <br><br> Document artefact/deliverable for MIRROR-CRT-56-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/mirror/prep-56-001-thin-bundle.md`. |
| P2 | PREP-MIRROR-CRT-56-001-ASSEMBLER-HANDOFF | DONE (2025-11-19) | Due 2025-11-22 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Handoff expectations for thin bundle assembler published at `docs/modules/mirror/thin-bundle-assembler.md` (tar layout, manifest fields, determinism rules, hashes). |
| 1 | MIRROR-CRT-56-001 | BLOCKED | PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D | Alex Kim (primary); Priya Desai (backup) | Implement deterministic assembler with manifest + CAS layout. |
| 2 | MIRROR-CRT-56-002 | BLOCKED | Depends on MIRROR-CRT-56-001 and PROV-OBS-53-001; upstream assembler missing. | Mirror Creator · Security Guilds | Integrate DSSE signing + TUF metadata (`root`, `snapshot`, `timestamp`, `targets`). |
| 3 | MIRROR-CRT-57-001 | BLOCKED | Requires MIRROR-CRT-56-001; assembler foundation missing. | Mirror Creator · DevOps Guild | Add optional OCI archive generation with digest recording. |
| 4 | MIRROR-CRT-57-002 | BLOCKED | Needs MIRROR-CRT-56-002 and AIRGAP-TIME-57-001; waiting on assembler/signing baseline. | Mirror Creator · AirGap Time Guild | Embed signed time-anchor metadata. |
| 5 | MIRROR-CRT-58-001 | BLOCKED | Requires MIRROR-CRT-56-002 and CLI-AIRGAP-56-001; downstream until assembler exists. | Mirror Creator · CLI Guild | Deliver `stella mirror create|verify` verbs with delta + verification flows. |
| 6 | MIRROR-CRT-58-002 | BLOCKED | Depends on MIRROR-CRT-56-002 and EXPORT-OBS-54-001; waiting on sample bundles. | Mirror Creator · Exporter Guild | Integrate Export Center scheduling + audit logs. |
| 7 | EXPORT-OBS-51-001 / 54-001 | BLOCKED | MIRROR-CRT-56-001 staffing and artifacts not available. | Exporter Guild | Align Export Center workers with assembler output. |
| 8 | AIRGAP-TIME-57-001 | BLOCKED | MIRROR-CRT-56-001/57-002 pending; policy workshop contingent on sample bundles. | 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 | BLOCKED | MIRROR-CRT-56-001 absent; cannot wire observers. | Security Guild | Define provenance observers + verification hooks. |
## Execution Log
# Sprint 0125_0001_0001 · Mirror Bundles
## Topic & Scope
- Build the deterministic mirror bundle assembler covering advisories, VEX, policy packs, and optional OCI artefacts.
- Layer DSSE/TUF metadata, time anchors, and CLI automation so air-gapped sites receive verifiable bundles.
- Wire Export Center and scheduling hooks so mirror creation can be orchestrated automatically.
- **Working directory:** `src/Mirror/StellaOps.Mirror.Creator`.
## Dependencies & Concurrency
- Upstream: Sprint 110.D must deliver the assembler foundation (`MIRROR-CRT-56-001`). Attestor v2 contracts from Sprint 100.A remain required.
- Mirror sprints share the 120s decade with Policy & Reasoning work but remain independent; avoid adding dependencies on `SPRINT_125_policy_reasoning.md`.
- Evidence Locker, Export Center, CLI, and AirGap Time guild commitments must be available as soon as assembler code exists.
## Documentation Prerequisites
- `docs/modules/export-center/architecture.md`
- `docs/modules/airgap/architecture.md`
- `docs/modules/devops/architecture.md`
- `docs/modules/policy/architecture.md` (for provenance expectations)
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P0 | PREP-MIRROR-CRT-56-001-MILESTONE-0-PUBLISH | DONE (2025-11-19) | Due 2025-11-20 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Published milestone-0 thin bundle plan + sample at `out/mirror/thin/mirror-thin-m0-sample.tar.gz` with SHA256 `bd1013885a27f651e28331c7a240d417d265bd411d09b51b47bd7c2196659674` and layout note in `docs/modules/mirror/milestone-0-thin-bundle.md`. |
| P1 | PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Alex Kim (primary); Priya Desai (backup) | Alex Kim (primary); Priya Desai (backup) | Upstream Sprint 110.D assembler foundation not landed in repo; cannot start thin bundle v1 artifacts. <br><br> Document artefact/deliverable for MIRROR-CRT-56-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/mirror/prep-56-001-thin-bundle.md`. |
| P2 | PREP-MIRROR-CRT-56-001-ASSEMBLER-HANDOFF | DONE (2025-11-19) | Due 2025-11-22 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Handoff expectations for thin bundle assembler published at `docs/modules/mirror/thin-bundle-assembler.md` (tar layout, manifest fields, determinism rules, hashes). |
| 1 | MIRROR-CRT-56-001 | BLOCKED | PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D | Alex Kim (primary); Priya Desai (backup) | Implement deterministic assembler with manifest + CAS layout. |
| 2 | MIRROR-CRT-56-002 | BLOCKED | Depends on MIRROR-CRT-56-001 and PROV-OBS-53-001; upstream assembler missing. | Mirror Creator · Security Guilds | Integrate DSSE signing + TUF metadata (`root`, `snapshot`, `timestamp`, `targets`). |
| 3 | MIRROR-CRT-57-001 | BLOCKED | Requires MIRROR-CRT-56-001; assembler foundation missing. | Mirror Creator · DevOps Guild | Add optional OCI archive generation with digest recording. |
| 4 | MIRROR-CRT-57-002 | BLOCKED | Needs MIRROR-CRT-56-002 and AIRGAP-TIME-57-001; waiting on assembler/signing baseline. | Mirror Creator · AirGap Time Guild | Embed signed time-anchor metadata. |
| 5 | MIRROR-CRT-58-001 | BLOCKED | Requires MIRROR-CRT-56-002 and CLI-AIRGAP-56-001; downstream until assembler exists. | Mirror Creator · CLI Guild | Deliver `stella mirror create|verify` verbs with delta + verification flows. |
| 6 | MIRROR-CRT-58-002 | BLOCKED | Depends on MIRROR-CRT-56-002 and EXPORT-OBS-54-001; waiting on sample bundles. | Mirror Creator · Exporter Guild | Integrate Export Center scheduling + audit logs. |
| 7 | EXPORT-OBS-51-001 / 54-001 | BLOCKED | MIRROR-CRT-56-001 staffing and artifacts not available. | Exporter Guild | Align Export Center workers with assembler output. |
| 8 | AIRGAP-TIME-57-001 | BLOCKED | MIRROR-CRT-56-001/57-002 pending; policy workshop contingent on sample bundles. | 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 | BLOCKED | MIRROR-CRT-56-001 absent; cannot wire observers. | Security Guild | Define provenance observers + verification hooks. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Published thin-bundle prep doc (docs/modules/mirror/prep-56-001-thin-bundle.md); moved PREP-MIRROR-CRT-56-001 to DOING after confirming unowned. | Project Mgmt |
| 2025-11-19 | Cleared stray hyphen from PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D so MIRROR-CRT-56-001 dependency is resolvable. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Completed PREP-MIRROR-CRT-56-001-MILESTONE-0-PUBLISH: published sample thin bundle + hashes and milestone note (`docs/modules/mirror/milestone-0-thin-bundle.md`). | Implementer |
| 2025-11-17 | All sprint tasks marked BLOCKED: upstream Sprint 110.D assembler foundation absent from repo; no manifest/CAS layout or samples present to proceed. | Implementer |
| 2025-11-17 | Normalised sprint file to standard template; renamed from `SPRINT_125_mirror.md` to `SPRINT_0125_0001_0001_mirror.md`; no semantic task changes. | Project Management |
| 2025-11-17 | Coordinator decision: assign primary + backup for MIRROR-CRT-56-001; scope thin bundle v1; downstream tasks may proceed once schema + sample bundle land. | Coordinator |
| 2025-11-17 | Action: record primary + backup in Delivery Tracker; produce thin bundle v1 schema + 2 sample bundles by 2025-11-19; unblock Export/CLI/AirGap. | Coordinator |
| 2025-11-13 | Kickoff rescheduled to 15 Nov pending MIRROR-CRT-56-001 staffing; downstream guilds alerted to prepare resource plans. | Mirror Creator Guild |
## 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.
- **Risks**
- Upstream assembler foundation (Sprint 110.D, MIRROR-CRT-56-001 baseline) missing from repo → all Sprint 0125 tasks blocked. Mitigation: expedite delivery of manifest/CAS scaffold + sample bundles; re-sequence tasks once landed.
- Staffing gap for MIRROR-CRT-56-001 persists after kickoff → DSSE/TUF, OCI, CLI, Export tracks slip; Sprint 0125 jams the Export Center roadmap. Mitigation: escalate to program leadership; reassign engineers from Export Center or Excititor queue.
- DSSE/TUF contract debates with Security Guild → signing + transparency integration slips, blocking CLI/Export release. Mitigation: align on profile ahead of development; capture ADR in `docs/airgap`.
- Time-anchor requirements undefined → air-gapped bundles lose verifiable time guarantees. Mitigation: run focused session with AirGap Time Guild to lock policy + service interface.
## Next Checkpoints
| Date (UTC) | Session | Goal | Owner(s) |
| --- | --- | --- | --- |
| 2025-11-15 | Mirror evidence kickoff | Assign MIRROR-CRT-56-001 owner, outline scope, confirm downstream staffing. | Mirror Creator · Exporter · AirGap Time · Security guilds |
| 2025-11-18 | DSSE/TUF design review | Freeze signing profile + manifest shape. | Mirror Creator · Security Guild |
| 2025-11-19 | Thin bundle v1 sample paths | Publish locations + SHA256 for sample bundles; usable by Export/CLI/AirGap. | Mirror Creator Guild |
| 2025-11-19 | Time-anchor policy workshop | Approve requirements for AIRGAP-TIME-57-001. | AirGap Time Guild · Mirror Creator |
## Appendix
- Previous detailed notes retained at `docs/implplan/archived/SPRINT_125_mirror_2025-11-13.md`.
| 2025-11-17 | All sprint tasks marked BLOCKED: upstream Sprint 110.D assembler foundation absent from repo; no manifest/CAS layout or samples present to proceed. | Implementer |
| 2025-11-17 | Normalised sprint file to standard template; renamed from `SPRINT_125_mirror.md` to `SPRINT_0125_0001_0001_mirror.md`; no semantic task changes. | Project Management |
| 2025-11-17 | Coordinator decision: assign primary + backup for MIRROR-CRT-56-001; scope thin bundle v1; downstream tasks may proceed once schema + sample bundle land. | Coordinator |
| 2025-11-17 | Action: record primary + backup in Delivery Tracker; produce thin bundle v1 schema + 2 sample bundles by 2025-11-19; unblock Export/CLI/AirGap. | Coordinator |
| 2025-11-13 | Kickoff rescheduled to 15 Nov pending MIRROR-CRT-56-001 staffing; downstream guilds alerted to prepare resource plans. | Mirror Creator Guild |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## 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.
- **Risks**
- Upstream assembler foundation (Sprint 110.D, MIRROR-CRT-56-001 baseline) missing from repo → all Sprint 0125 tasks blocked. Mitigation: expedite delivery of manifest/CAS scaffold + sample bundles; re-sequence tasks once landed.
- Staffing gap for MIRROR-CRT-56-001 persists after kickoff → DSSE/TUF, OCI, CLI, Export tracks slip; Sprint 0125 jams the Export Center roadmap. Mitigation: escalate to program leadership; reassign engineers from Export Center or Excititor queue.
- DSSE/TUF contract debates with Security Guild → signing + transparency integration slips, blocking CLI/Export release. Mitigation: align on profile ahead of development; capture ADR in `docs/airgap`.
- Time-anchor requirements undefined → air-gapped bundles lose verifiable time guarantees. Mitigation: run focused session with AirGap Time Guild to lock policy + service interface.
## Next Checkpoints
| Date (UTC) | Session | Goal | Owner(s) |
| --- | --- | --- | --- |
| 2025-11-15 | Mirror evidence kickoff | Assign MIRROR-CRT-56-001 owner, outline scope, confirm downstream staffing. | Mirror Creator · Exporter · AirGap Time · Security guilds |
| 2025-11-18 | DSSE/TUF design review | Freeze signing profile + manifest shape. | Mirror Creator · Security Guild |
| 2025-11-19 | Thin bundle v1 sample paths | Publish locations + SHA256 for sample bundles; usable by Export/CLI/AirGap. | Mirror Creator Guild |
| 2025-11-19 | Time-anchor policy workshop | Approve requirements for AIRGAP-TIME-57-001. | AirGap Time Guild · Mirror Creator |
## Appendix
- Previous detailed notes retained at `docs/implplan/archived/SPRINT_125_mirror_2025-11-13.md`.

View File

@@ -17,7 +17,7 @@
## Delivery Tracker
| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-POLICY-RISK-66-001-RISKPROFILE-LIBRARY-S | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | RiskProfile library scaffold absent (`src/Policy/StellaOps.Policy.RiskProfile` contains only AGENTS.md); need project + storage contract to place schema/validators. <br><br> Document artefact/deliverable for POLICY-RISK-66-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/policy/prep/2025-11-20-riskprofile-66-001-prep.md`. |
| P1 | PREP-POLICY-RISK-66-001-RISKPROFILE-LIBRARY-S | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | RiskProfile library scaffold absent (`src/Policy/StellaOps.Policy.RiskProfile` contains only AGENTS.md); need project + storage contract to place schema/validators. <br><br> Document artefact/deliverable for POLICY-RISK-66-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/policy/prep/2025-11-20-riskprofile-66-001-prep.md`. |
| 1 | POLICY-ENGINE-80-002 | TODO | Depends on 80-001. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Join reachability facts + Redis caches. |
| 2 | POLICY-ENGINE-80-003 | TODO | Depends on 80-002. | Policy · Policy Editor Guild / `src/Policy/StellaOps.Policy.Engine` | SPL predicates/actions reference reachability. |
| 3 | POLICY-ENGINE-80-004 | TODO | Depends on 80-003. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/traces for signals usage. |
@@ -42,6 +42,7 @@
| 2025-11-08 | Sprint stub; awaiting upstream phases. | Planning |
| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_127_policy_reasoning.md` to `SPRINT_0127_0001_0001_policy_reasoning.md`; content preserved. | Implementer |
| 2025-11-19 | Attempted POLICY-RISK-66-001; blocked because `src/Policy/StellaOps.Policy.RiskProfile` lacks a project/scaffold to host schema + validators. Needs project creation + contract placement guidance. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Reachability inputs (80-001) prerequisite; not yet delivered.

View File

@@ -1,67 +1,68 @@
# Sprint 0131-0001-0001 · Scanner & Surface (Phase II)
## Topic & Scope
- Continue Scanner & Surface wave (phase II) after Sprint 0130, deepening analyzers for Deno and Java with runtime evidence and surface signals.
- Deliver Deno runtime hooks, policy signal emitters, and CLI/Worker packaging that stay offline-friendly and bundle-ready.
- Expand Java analyzer coverage for configs, JNI hints, manifest metadata, fixtures/benchmarks, and optional runtime ingestion to feed surface decisioning.
- **Working directory:** `src/Scanner`.
## Dependencies & Concurrency
- Sequential dependency: Sprint 0130 must finish before this sprint; maintain order across the 01300139 wave.
- Deno work depends on `SCANNER-ANALYZERS-DENO-26-008`; Java chain builds serially from 21-005 → 21-006 → 21-007 → 21-008 → 21-009 → 21-010 → 21-011.
- Stay within scanner scope to avoid new cross-module coupling unless explicitly approved.
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/modules/scanner/architecture.md
- src/Scanner/AGENTS.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Java Analyzer Guild | Java Analyzer Guild | Tests blocked: repo build fails in Concelier (CoreLinksets missing) and targeted Java analyzer test run stalls; retry once dependencies fixed or CI available. <br><br> Document artefact/deliverable for SCANNER-ANALYZERS-JAVA-21-005 and publish location so downstream tasks can proceed. |
| P2 | PREP-SCANNER-ANALYZERS-JAVA-21-008-WAITING-ON | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Java Analyzer Guild | Java Analyzer Guild | Waiting on 21-007 completion and resolver authoring bandwidth. <br><br> Document artefact/deliverable for SCANNER-ANALYZERS-JAVA-21-008 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scanner/prep/2025-11-20-java-21-008-prep.md`. |
| P3 | PREP-SCANNER-ANALYZERS-LANG-11-001-DOTNET-TES | DOING (2025-11-20) | Due 2025-11-22 · Accountable: StellaOps.Scanner EPDR Guild · Language Analyzer Guild | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | `dotnet test` hangs/returns empty output; needs clean runner/CI diagnostics. <br><br> Document artefact/deliverable for SCANNER-ANALYZERS-LANG-11-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scanner/prep/2025-11-20-lang-11-001-prep.md`. |
| 1 | SCANNER-ANALYZERS-DENO-26-009 | BLOCKED (2025-11-19) | Waiting on runtime shim fixtures + CI runner; design `deno-runtime-shim.md` drafted but tests cannot run. | Deno Analyzer Guild · Signals Guild | Optional runtime evidence hooks capturing module loads and permissions with path hashing during harnessed execution. |
| 2 | SCANNER-ANALYZERS-DENO-26-010 | TODO | After 26-009, wire CLI (`stella deno trace`) + Worker/Offline Kit using runtime NDJSON contract. | Deno Analyzer Guild · DevOps Guild | Package analyzer plug-in and surface CLI/worker commands with offline documentation. |
| 3 | SCANNER-ANALYZERS-DENO-26-011 | TODO | Implement policy signal emitter using runtime metadata once trace shim lands. | Deno Analyzer Guild | Policy signal emitter for capabilities (net/fs/env/ffi/process/crypto), remote origins, npm usage, wasm modules, and dynamic-import warnings. |
| 4 | SCANNER-ANALYZERS-JAVA-21-005 | BLOCKED (2025-11-17) | PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC | Java Analyzer Guild | Framework config extraction: Spring Boot imports, spring.factories, application properties/yaml, Jakarta web.xml/fragments, JAX-RS/JPA/CDI/JAXB configs, logging files, Graal native-image configs. |
| 5 | SCANNER-ANALYZERS-JAVA-21-006 | TODO | Needs outputs from 21-005. | Java Analyzer Guild | JNI/native hint scanner detecting native methods, System.load/Library literals, bundled native libs, Graal JNI configs; emit `jni-load` edges. |
| 6 | SCANNER-ANALYZERS-JAVA-21-007 | TODO | After 21-006; align manifest parsing with resolver. | Java Analyzer Guild | Signature and manifest metadata collector capturing JAR signature structure, signers, and manifest loader attributes (Main-Class, Agent-Class, Start-Class, Class-Path). |
| 7 | SCANNER-ANALYZERS-JAVA-21-008 | BLOCKED (2025-10-27) | PREP-SCANNER-ANALYZERS-JAVA-21-008-WAITING-ON | Java Analyzer Guild | Implement resolver + AOC writer emitting entrypoints, components, and edges (jpms, cp, spi, reflect, jni) with reason codes and confidence. |
| 8 | SCANNER-ANALYZERS-JAVA-21-009 | TODO | Unblock when 21-008 lands; prepare fixtures in parallel where safe. | Java Analyzer Guild · QA Guild | Comprehensive fixtures (modular app, boot fat jar, war, ear, MR-jar, jlink image, JNI, reflection heavy, signed jar, microprofile) with golden outputs and perf benchmarks. |
| 9 | SCANNER-ANALYZERS-JAVA-21-010 | TODO | After 21-009; requires runtime capture design. | Java Analyzer Guild · Signals Guild | Optional runtime ingestion via Java agent + JFR reader capturing class load, ServiceLoader, System.load events with path scrubbing; append-only runtime edges (`runtime-class`/`runtime-spi`/`runtime-load`). |
| 10 | SCANNER-ANALYZERS-JAVA-21-011 | TODO | Depends on 21-010; finalize DI/manifest registration and docs. | Java Analyzer Guild · DevOps Guild | Package analyzer as restart-time plug-in, update Offline Kit docs, add CLI/worker hooks for Java inspection commands. |
| 11 | SCANNER-ANALYZERS-LANG-11-001 | BLOCKED (2025-11-17) | PREP-SCANNER-ANALYZERS-LANG-11-001-DOTNET-TES | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | Entrypoint resolver mapping project/publish artifacts to entrypoint identities (assembly name, MVID, TFM, RID) and environment profiles; output normalized `entrypoints[]` with deterministic IDs. |
## Execution Log
# Sprint 0131-0001-0001 · Scanner & Surface (Phase II)
## Topic & Scope
- Continue Scanner & Surface wave (phase II) after Sprint 0130, deepening analyzers for Deno and Java with runtime evidence and surface signals.
- Deliver Deno runtime hooks, policy signal emitters, and CLI/Worker packaging that stay offline-friendly and bundle-ready.
- Expand Java analyzer coverage for configs, JNI hints, manifest metadata, fixtures/benchmarks, and optional runtime ingestion to feed surface decisioning.
- **Working directory:** `src/Scanner`.
## Dependencies & Concurrency
- Sequential dependency: Sprint 0130 must finish before this sprint; maintain order across the 01300139 wave.
- Deno work depends on `SCANNER-ANALYZERS-DENO-26-008`; Java chain builds serially from 21-005 → 21-006 → 21-007 → 21-008 → 21-009 → 21-010 → 21-011.
- Stay within scanner scope to avoid new cross-module coupling unless explicitly approved.
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/modules/platform/architecture-overview.md
- docs/modules/scanner/architecture.md
- src/Scanner/AGENTS.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Java Analyzer Guild | Java Analyzer Guild | Tests blocked: repo build fails in Concelier (CoreLinksets missing) and targeted Java analyzer test run stalls; retry once dependencies fixed or CI available. <br><br> Document artefact/deliverable for SCANNER-ANALYZERS-JAVA-21-005 and publish location so downstream tasks can proceed. |
| P2 | PREP-SCANNER-ANALYZERS-JAVA-21-008-WAITING-ON | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Java Analyzer Guild | Java Analyzer Guild | Waiting on 21-007 completion and resolver authoring bandwidth. <br><br> Document artefact/deliverable for SCANNER-ANALYZERS-JAVA-21-008 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scanner/prep/2025-11-20-java-21-008-prep.md`. |
| P3 | PREP-SCANNER-ANALYZERS-LANG-11-001-DOTNET-TES | DONE (2025-11-22) | Due 2025-11-22 · Accountable: StellaOps.Scanner EPDR Guild · Language Analyzer Guild | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | `dotnet test` hangs/returns empty output; needs clean runner/CI diagnostics. <br><br> Document artefact/deliverable for SCANNER-ANALYZERS-LANG-11-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scanner/prep/2025-11-20-lang-11-001-prep.md`. |
| 1 | SCANNER-ANALYZERS-DENO-26-009 | BLOCKED (2025-11-19) | Waiting on runtime shim fixtures + CI runner; design `deno-runtime-shim.md` drafted but tests cannot run. | Deno Analyzer Guild · Signals Guild | Optional runtime evidence hooks capturing module loads and permissions with path hashing during harnessed execution. |
| 2 | SCANNER-ANALYZERS-DENO-26-010 | TODO | After 26-009, wire CLI (`stella deno trace`) + Worker/Offline Kit using runtime NDJSON contract. | Deno Analyzer Guild · DevOps Guild | Package analyzer plug-in and surface CLI/worker commands with offline documentation. |
| 3 | SCANNER-ANALYZERS-DENO-26-011 | TODO | Implement policy signal emitter using runtime metadata once trace shim lands. | Deno Analyzer Guild | Policy signal emitter for capabilities (net/fs/env/ffi/process/crypto), remote origins, npm usage, wasm modules, and dynamic-import warnings. |
| 4 | SCANNER-ANALYZERS-JAVA-21-005 | BLOCKED (2025-11-17) | PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC | Java Analyzer Guild | Framework config extraction: Spring Boot imports, spring.factories, application properties/yaml, Jakarta web.xml/fragments, JAX-RS/JPA/CDI/JAXB configs, logging files, Graal native-image configs. |
| 5 | SCANNER-ANALYZERS-JAVA-21-006 | TODO | Needs outputs from 21-005. | Java Analyzer Guild | JNI/native hint scanner detecting native methods, System.load/Library literals, bundled native libs, Graal JNI configs; emit `jni-load` edges. |
| 6 | SCANNER-ANALYZERS-JAVA-21-007 | TODO | After 21-006; align manifest parsing with resolver. | Java Analyzer Guild | Signature and manifest metadata collector capturing JAR signature structure, signers, and manifest loader attributes (Main-Class, Agent-Class, Start-Class, Class-Path). |
| 7 | SCANNER-ANALYZERS-JAVA-21-008 | BLOCKED (2025-10-27) | PREP-SCANNER-ANALYZERS-JAVA-21-008-WAITING-ON | Java Analyzer Guild | Implement resolver + AOC writer emitting entrypoints, components, and edges (jpms, cp, spi, reflect, jni) with reason codes and confidence. |
| 8 | SCANNER-ANALYZERS-JAVA-21-009 | TODO | Unblock when 21-008 lands; prepare fixtures in parallel where safe. | Java Analyzer Guild · QA Guild | Comprehensive fixtures (modular app, boot fat jar, war, ear, MR-jar, jlink image, JNI, reflection heavy, signed jar, microprofile) with golden outputs and perf benchmarks. |
| 9 | SCANNER-ANALYZERS-JAVA-21-010 | TODO | After 21-009; requires runtime capture design. | Java Analyzer Guild · Signals Guild | Optional runtime ingestion via Java agent + JFR reader capturing class load, ServiceLoader, System.load events with path scrubbing; append-only runtime edges (`runtime-class`/`runtime-spi`/`runtime-load`). |
| 10 | SCANNER-ANALYZERS-JAVA-21-011 | TODO | Depends on 21-010; finalize DI/manifest registration and docs. | Java Analyzer Guild · DevOps Guild | Package analyzer as restart-time plug-in, update Offline Kit docs, add CLI/worker hooks for Java inspection commands. |
| 11 | SCANNER-ANALYZERS-LANG-11-001 | BLOCKED (2025-11-17) | PREP-SCANNER-ANALYZERS-LANG-11-001-DOTNET-TES | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | Entrypoint resolver mapping project/publish artifacts to entrypoint identities (assembly name, MVID, TFM, RID) and environment profiles; output normalized `entrypoints[]` with deterministic IDs. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Published prep docs for P2/P3: `docs/modules/scanner/prep/2025-11-20-java-21-008-prep.md` and `docs/modules/scanner/prep/2025-11-20-lang-11-001-prep.md`; set PREP P2/P3 to DOING after confirming unowned. | Project Mgmt |
| 2025-11-20 | Published prep note for SCANNER-ANALYZERS-JAVA-21-005 (docs/modules/scanner/prep/2025-11-20-java-21-005-prep.md); pinged Concelier/CoreLinksets owners for missing packages and CI isolation. | Project Mgmt |
| 2025-11-20 | Confirmed PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC still TODO; moved to DOING to capture blockers and prep artefact. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-17 | Normalised sprint file to standard template and renamed from `SPRINT_131_scanner_surface.md` to `SPRINT_0131_scanner_surface.md`; no semantic changes. | Planning |
| 2025-11-17 | Attempted `./tools/dotnet-filter.sh test src/Scanner/StellaOps.Scanner.sln --no-restore`; build ran ~72s compiling scanner/all projects without completing tests, then aborted locally to avoid runaway build. Follow-up narrow build `dotnet build src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.csproj` also stalled ~28s in target resolution before manual stop. Blocker persists; needs clean CI runner or scoped test project to finish LANG-11-001 validation. | Implementer |
| 2025-11-17 | Started SCANNER-ANALYZERS-JAVA-21-005: initial framework config extraction (Spring configs, JPA/CDI/JAXB, logging, Graal native-image) implemented with evidence + metadata; added regression test scaffold. | Implementer |
| 2025-11-17 | SCANNER-ANALYZERS-JAVA-21-005: Added Spring Boot `.imports` detection and web-fragment coverage; refreshed framework-config test to assert imports + fragment metadata. Test run blocked by Concelier Mongo build errors (missing CoreLinksets interfaces); rerun once repository build is green. | Java Analyzer Guild |
| 2025-11-19 | SCANNER-ANALYZERS-JAVA-21-005: Added SHA-256 evidence for framework configs (spring.factories, app/bootstrap config, web.xml, etc.) and updated regression test to assert hashed config evidence. Test run aborted due to solution restore contention; rerun needed when runner is free. | Java Analyzer Guild |
| 2025-11-17 | Targeted `dotnet test src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests.csproj --no-restore`; build pulled large Concelier/Surface dependencies and stalled ~35s before manual abort (no test results). Need clean CI or lighter test target to validate 21-005. | Implementer |
| 2025-11-19 | SCANNER-ANALYZERS-JAVA-21-005: Another targeted restore/test attempt aborted after ~59s during restore due to solution contention; no test results. Await clean runner/CI. | Implementer |
| 2025-11-17 | Reviewed Deno analyzer scope; runtime evidence hook contract and policy-signal keys not defined in docs or code. Marked DENO-26-009/010/011 as BLOCKED pending approved trace/signal schema shared with Surface/Signals. | Implementer |
| 2025-11-17 | SCANNER-ANALYZERS-JAVA-21-005: Added JNI/native hint scanning (native libs, Graal jni-config, System.load/Library strings) with component metadata + evidence; targeted tests added. Test run aborted ~80s in due to concurrent repo-wide builds; rerun on clean runner. | Java Analyzer Guild |
| 2025-11-17 | Authored `docs/modules/scanner/design/deno-runtime-signals.md` defining NDJSON runtime trace + policy signal keys; unblocked DENO-26-009/010/011 back to TODO. | Implementer |
| 2025-11-17 | Implemented Deno runtime NDJSON serializer + metadata (module/permission counts, remote origins, npm/wasm/dynamic import counts) with deterministic ordering and hash; added regression tests for serializer, path hashing, recorder ordering, and policy signal emission. Loader/require shim still pending. | Implementer |
| 2025-11-17 | Deno runtime tests passing: `dotnet test src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests.csproj --no-restore`. | Implementer |
| 2025-11-17 | DenoLanguageAnalyzer now ingests `deno-runtime.ndjson` if present, computes metadata/hash, stores runtime payload in AnalysisStore, and emits policy signals; added runtime probe parser + tests. Loader/require shim that generates the trace remains to be built. | Implementer |
| 2025-11-17 | Extended runtime metadata/signals to include npm/wasm/dynamic-import counts and unique permissions; AnalysisStore payload now carries these fields for CLI/Worker consumption. | Implementer |
| 2025-11-17 | Marked DENO-26-009/010/011 BLOCKED: need approved Deno loader/require harness to generate runtime NDJSON in offline mode; pending Signals/Surface design. | Implementer |
| 2025-11-17 | Authored loader/trace shim plan `docs/modules/scanner/design/deno-runtime-shim.md` describing Deno harness injection, event capture, determinism rules, and fixtures; unblocks DENO-26-009 back to DOING. | Implementer |
| 2025-11-17 | Added runtime shim source helper + test; shim writes `trace-shim.ts` containing runtime capture hooks (module load, permission use, wasm load, npm hint) for offline trace generation. | Implementer |
| 2025-11-17 | Re-ran Deno runtime tests after status update; still passing (`dotnet test ...Deno.Tests.csproj --no-restore`). | Implementer |
| 2025-11-17 | Normalised sprint file to standard template and renamed from `SPRINT_131_scanner_surface.md` to `SPRINT_0131_scanner_surface.md`; no semantic changes. | Planning |
| 2025-11-17 | Attempted `./tools/dotnet-filter.sh test src/Scanner/StellaOps.Scanner.sln --no-restore`; build ran ~72s compiling scanner/all projects without completing tests, then aborted locally to avoid runaway build. Follow-up narrow build `dotnet build src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.csproj` also stalled ~28s in target resolution before manual stop. Blocker persists; needs clean CI runner or scoped test project to finish LANG-11-001 validation. | Implementer |
| 2025-11-17 | Started SCANNER-ANALYZERS-JAVA-21-005: initial framework config extraction (Spring configs, JPA/CDI/JAXB, logging, Graal native-image) implemented with evidence + metadata; added regression test scaffold. | Implementer |
| 2025-11-17 | SCANNER-ANALYZERS-JAVA-21-005: Added Spring Boot `.imports` detection and web-fragment coverage; refreshed framework-config test to assert imports + fragment metadata. Test run blocked by Concelier Mongo build errors (missing CoreLinksets interfaces); rerun once repository build is green. | Java Analyzer Guild |
| 2025-11-19 | SCANNER-ANALYZERS-JAVA-21-005: Added SHA-256 evidence for framework configs (spring.factories, app/bootstrap config, web.xml, etc.) and updated regression test to assert hashed config evidence. Test run aborted due to solution restore contention; rerun needed when runner is free. | Java Analyzer Guild |
| 2025-11-17 | Targeted `dotnet test src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests.csproj --no-restore`; build pulled large Concelier/Surface dependencies and stalled ~35s before manual abort (no test results). Need clean CI or lighter test target to validate 21-005. | Implementer |
| 2025-11-19 | SCANNER-ANALYZERS-JAVA-21-005: Another targeted restore/test attempt aborted after ~59s during restore due to solution contention; no test results. Await clean runner/CI. | Implementer |
| 2025-11-17 | Reviewed Deno analyzer scope; runtime evidence hook contract and policy-signal keys not defined in docs or code. Marked DENO-26-009/010/011 as BLOCKED pending approved trace/signal schema shared with Surface/Signals. | Implementer |
| 2025-11-17 | SCANNER-ANALYZERS-JAVA-21-005: Added JNI/native hint scanning (native libs, Graal jni-config, System.load/Library strings) with component metadata + evidence; targeted tests added. Test run aborted ~80s in due to concurrent repo-wide builds; rerun on clean runner. | Java Analyzer Guild |
| 2025-11-17 | Authored `docs/modules/scanner/design/deno-runtime-signals.md` defining NDJSON runtime trace + policy signal keys; unblocked DENO-26-009/010/011 back to TODO. | Implementer |
| 2025-11-17 | Implemented Deno runtime NDJSON serializer + metadata (module/permission counts, remote origins, npm/wasm/dynamic import counts) with deterministic ordering and hash; added regression tests for serializer, path hashing, recorder ordering, and policy signal emission. Loader/require shim still pending. | Implementer |
| 2025-11-17 | Deno runtime tests passing: `dotnet test src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests.csproj --no-restore`. | Implementer |
| 2025-11-17 | DenoLanguageAnalyzer now ingests `deno-runtime.ndjson` if present, computes metadata/hash, stores runtime payload in AnalysisStore, and emits policy signals; added runtime probe parser + tests. Loader/require shim that generates the trace remains to be built. | Implementer |
| 2025-11-17 | Extended runtime metadata/signals to include npm/wasm/dynamic-import counts and unique permissions; AnalysisStore payload now carries these fields for CLI/Worker consumption. | Implementer |
| 2025-11-17 | Marked DENO-26-009/010/011 BLOCKED: need approved Deno loader/require harness to generate runtime NDJSON in offline mode; pending Signals/Surface design. | Implementer |
| 2025-11-17 | Authored loader/trace shim plan `docs/modules/scanner/design/deno-runtime-shim.md` describing Deno harness injection, event capture, determinism rules, and fixtures; unblocks DENO-26-009 back to DOING. | Implementer |
| 2025-11-17 | Added runtime shim source helper + test; shim writes `trace-shim.ts` containing runtime capture hooks (module load, permission use, wasm load, npm hint) for offline trace generation. | Implementer |
| 2025-11-17 | Re-ran Deno runtime tests after status update; still passing (`dotnet test ...Deno.Tests.csproj --no-restore`). | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Scanner record payload schema still unpinned; drafting prep at `docs/modules/scanner/prep/2025-11-21-scanner-records-prep.md` while waiting for analyzer output confirmation from Scanner Guild.
- `SCANNER-ANALYZERS-LANG-11-001` blocked (2025-11-17): local `dotnet test` hangs/returns empty output; requires clean runner/CI hang diagnostics to progress and regenerate goldens.
@@ -72,9 +73,9 @@
- Loader/require shim implementation still pending for DENO-26-009; must stay offline-first and AnalysisStore-compatible before wiring DENO-26-010/011.
- PREP note for SCANNER-ANALYZERS-JAVA-21-005 published at `docs/modules/scanner/prep/2025-11-20-java-21-005-prep.md`; awaiting CoreLinksets package fix and isolated CI slot before tests can run.
- PREP docs added for SCANNER-ANALYZERS-JAVA-21-008 (`docs/modules/scanner/prep/2025-11-20-java-21-008-prep.md`) and LANG-11-001 (`docs/modules/scanner/prep/2025-11-20-lang-11-001-prep.md`); both depend on resolver outputs/CI isolation.
## Next Checkpoints
| Date (UTC) | Session | Goal | Impacted work | Owner |
| --- | --- | --- | --- | --- |
| 2025-11-18 | Scanner EPDR triage | Reproduce and debug `dotnet test` hang for LANG-11-001 on clean runner; capture logs for unblock. | SCANNER-ANALYZERS-LANG-11-001 | Signals Guild |
| 2025-11-19 | Java analyzer sequencing | Confirm resolver plan for 21-008 and schedule fixtures for 21-009 accordingly. | SCANNER-ANALYZERS-JAVA-21-008/009 | Java Analyzer Guild |
## Next Checkpoints
| Date (UTC) | Session | Goal | Impacted work | Owner |
| --- | --- | --- | --- | --- |
| 2025-11-18 | Scanner EPDR triage | Reproduce and debug `dotnet test` hang for LANG-11-001 on clean runner; capture logs for unblock. | SCANNER-ANALYZERS-LANG-11-001 | Signals Guild |
| 2025-11-19 | Java analyzer sequencing | Confirm resolver plan for 21-008 and schedule fixtures for 21-009 accordingly. | SCANNER-ANALYZERS-JAVA-21-008/009 | Java Analyzer Guild |

View File

@@ -1,73 +1,74 @@
# Sprint 0138 · Scanner & Surface — Ruby Analyzer Parity
## Topic & Scope
- Achieve Ruby analyzer parity: runtime require/autoload graphs, capability signals, observation payloads, package inventories, and CLI/WebService wiring for scan/digest lookup.
- Sustain EntryTrace heuristic cadence with deterministic fixtures and explain-trace updates drawn from competitor gap benchmarks.
- Prepare runway for language coverage expansion (PHP now, Deno/Dart/Swift scoped) to keep parity roadmap on track.
- **Working directory:** `src/Scanner` (Analyzer, Worker, WebService, CLI surfaces) and supporting docs under `docs/modules/scanner`.
## Dependencies & Concurrency
- Depends on Sprint 0137 · Scanner.VIII (gap designs locked) and Sprint 0135 · Scanner.VI (EntryTrace foundations).
- Feeds Sprint 0139 and downstream CLI releases once Ruby analyzer, policy, and licensing tracks land.
- Parallel-safe with other modules; ensure Mongo is available when touching package inventory store tasks.
## Documentation Prerequisites
- `docs/README.md`; `docs/07_HIGH_LEVEL_ARCHITECTURE.md`.
- `docs/modules/scanner/architecture.md`; `docs/modules/scanner/operations/dsse-rekor-operator-guide.md`.
- AGENTS for involved components: `src/Scanner/StellaOps.Scanner.Worker/AGENTS.md`, `src/Scanner/StellaOps.Scanner.WebService/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Native/AGENTS.md`.
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD | BLOCKED | Due 2025-11-22 · Accountable: PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Await composer/autoload graph design + staffing; no PHP analyzer scaffolding exists yet. <br><br> Document artefact/deliverable for SCANNER-ENG-0010 and publish location so downstream tasks can proceed. |
| P2 | PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL | BLOCKED | Due 2025-11-22 · Accountable: Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Needs Deno runtime analyzer scope + lockfile/import graph design; pending competitive review. <br><br> Document artefact/deliverable for SCANNER-ENG-0011 and publish location so downstream tasks can proceed. |
| P3 | PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE | BLOCKED | Due 2025-11-22 · Accountable: Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Define Dart analyzer requirements (pubspec parsing, AOT artifacts) and split into tasks. <br><br> Document artefact/deliverable for SCANNER-ENG-0012 and publish location so downstream tasks can proceed. |
| P4 | PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE | BLOCKED | Due 2025-11-22 · Accountable: Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Draft SwiftPM coverage plan; align policy hooks; awaiting design kick-off. <br><br> Document artefact/deliverable for SCANNER-ENG-0013 and publish location so downstream tasks can proceed. |
| P5 | PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT | BLOCKED | Due 2025-11-22 · Accountable: Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Needs joint roadmap with Zastava/Runtime guilds for Kubernetes/VM alignment. <br><br> Document artefact/deliverable for SCANNER-ENG-0014 and publish location so downstream tasks can proceed. |
| 1 | SCANNER-ENG-0008 | DONE (2025-11-16) | Cadence documented; quarterly review workflow published for EntryTrace heuristics. | EntryTrace Guild, QA Guild (`src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace`) | Maintain EntryTrace heuristic cadence per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`, including explain-trace updates. |
| 2 | SCANNER-ENG-0009 | DONE (2025-11-13) | Release handoff to Sprint 0139 consumers; monitor Mongo-backed inventory rollout. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Ruby analyzer parity shipped: runtime graph + capability signals, observation payload, Mongo-backed `ruby.packages` inventory, CLI/WebService surfaces, and plugin manifest bundles for Worker loadout. |
| 3 | SCANNER-ENG-0010 | BLOCKED | PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Ship the PHP analyzer pipeline (composer lock, autoload graph, capability signals) to close comparison gaps. |
| 4 | SCANNER-ENG-0011 | BLOCKED | PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Scope the Deno runtime analyzer (lockfile resolver, import graphs) beyond Sprint 130 coverage. |
| 5 | SCANNER-ENG-0012 | BLOCKED | PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Evaluate Dart analyzer requirements (pubspec parsing, AOT artifacts) and split implementation tasks. |
| 6 | SCANNER-ENG-0013 | BLOCKED | PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Plan Swift Package Manager coverage (Package.resolved, xcframeworks, runtime hints) with policy hooks. |
| 7 | SCANNER-ENG-0014 | BLOCKED | PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Align Kubernetes/VM target coverage between Scanner and Zastava per comparison findings; publish joint roadmap. |
| 8 | SCANNER-ENG-0015 | DONE (2025-11-13) | Ready for Ops training; track adoption metrics. | Export Center Guild, Scanner Guild (`docs/modules/scanner`) | DSSE/Rekor operator playbook published with config/env tables, rollout phases, offline verification, and SLA/alert guidance. |
| 9 | SCANNER-ENG-0016 | DONE (2025-11-10) | Monitor bundler override edge cases; keep fixtures deterministic. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | RubyLockCollector and vendor ingestion finalized: Bundler overrides honoured, workspace lockfiles merged, vendor bundles normalised, deterministic fixtures added. |
| 10 | SCANNER-ENG-0017 | DONE (2025-11-09) | Keep tree-sitter Ruby grammar pinned; reuse EntryTrace hints for regressions. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Build runtime require/autoload graph builder with tree-sitter Ruby per design §4.4 and integrate EntryTrace hints. |
| 11 | SCANNER-ENG-0018 | DONE (2025-11-09) | Feed predicates to policy docs; monitor capability gaps. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Emit Ruby capability + framework surface signals per design §4.5 with policy predicate hooks. |
| 12 | SCANNER-ENG-0019 | DONE (2025-11-13) | Observe CLI/WebService adoption; ensure scanId resolution metrics logged. | Ruby Analyzer Guild, CLI Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Ruby CLI verbs resolve inventories by scan ID, digest, or image reference; WebService fallbacks + CLI client encoding cover both digests and tagged references. |
| 13 | SCANNER-LIC-0001 | DONE (2025-11-10) | Keep Offline Kit mirrors current with ruby artifacts. | Scanner Guild, Legal Guild (`docs/modules/scanner`) | Tree-sitter licensing captured, `NOTICE.md` updated, and Offline Kit now mirrors `third-party-licenses/` with ruby artifacts. |
| 14 | SCANNER-POLICY-0001 | DONE (2025-11-10) | Align DSL docs with future PHP/Deno/Dart predicates. | Policy Guild, Ruby Analyzer Guild (`docs/modules/scanner`) | Ruby predicates shipped: Policy Engine exposes `sbom.any_component` + `ruby.*`, tests updated, DSL/offline-kit docs refreshed. |
| 15 | SCANNER-CLI-0001 | DONE (2025-11-10) | Final verification of docs/help; handoff to CLI release notes. | CLI Guild, Ruby Analyzer Guild (`src/Cli/StellaOps.Cli`) | Coordinate CLI UX/help text for new Ruby verbs and update CLI docs/golden outputs. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Removed trailing hyphen from PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE so SCANNER-ENG-0013 dependency resolves. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P1P5 BLOCKED pending composer/Deno/Dart/SwiftPM design contracts and Zastava/Runtime roadmap; downstream SCANNER-ENG-0010..0014 remain gated. | Project Mgmt |
| 2025-11-09 | `SCANNER-CLI-0001`: Spectre table wrapping fix for runtime/lockfile columns; expanded Ruby resolve JSON assertions; removed debug artifacts; docs/tests pending final merge. | CLI Guild |
| 2025-11-09 | `SCANNER-CLI-0001`: Wired `stellaops-cli ruby inspect|resolve` into `CommandFactory` with `--root`, `--image/--scan-id`, `--format`; `dotnet test ... --filter Ruby` passes. | CLI Guild |
| 2025-11-09 | `SCANNER-CLI-0001`: Added CLI unit tests (CommandFactoryTests, Ruby inspect JSON assertions) to guard new verbs and runtime metadata output. | CLI Guild |
| 2025-11-09 | `SCANNER-ENG-0016`: Completed Ruby lock collector & vendor ingestion; honours `.bundle/config` overrides, folds workspace lockfiles, emits bundler groups; fixtures/goldens updated; `dotnet test ... --filter Ruby` passes. | Ruby Analyzer Guild |
| 2025-11-12 | `SCANNER-ENG-0009`: Observation payload + `ruby-observation` component emitted; `complex-app` fixture added for vendor caches/BUNDLE_PATH overrides; bundler-version metadata captured; CLI prints observation banner. | Ruby Analyzer Guild |
| 2025-11-12 | `SCANNER-ENG-0009`: Ruby package inventories flow into `RubyPackageInventoryStore`; `SurfaceManifestStageExecutor` builds package list; WebService exposes `GET /api/scans/{scanId}/ruby-packages`. | Ruby Analyzer Guild |
| 2025-11-12 | `SCANNER-ENG-0009`: Inventory API returns typed envelope (scanId/imageDigest/generatedAt + packages); Worker/WebService DI registers real/Null stores; CLI `ruby resolve` consumes payload and warns during warmup. | Ruby Analyzer Guild |
| 2025-11-13 | `SCANNER-ENG-0009`: Verified Worker DI wiring; plugin drop mirrors analyzer assembly + manifest for Worker hot-load; tests cover analyzer fixtures, Worker persistence, WebService endpoint. | Ruby Analyzer Guild |
| 2025-11-13 | `SCANNER-ENG-0015`: DSSE/Rekor operator guide expanded with config/env map, rollout runbook, verification snippets, alert/SLO recommendations. | Export Center Guild |
| 2025-11-13 | `SCANNER-ENG-0019`: WebService maps digest/reference identifiers to scan IDs; CLI backend encodes path segments; regression tests (`RubyPackagesEndpointsTests`, `StellaOps.Cli.Tests --filter Ruby`) cover lookup path. | Ruby Analyzer Guild |
| 2025-11-16 | Normalised sprint file to standard template and renamed to `SPRINT_0138_0000_0001_scanner_ruby_parity.md`; no semantic task changes. | Planning |
| 2025-11-16 | `SCANNER-ENG-0008`: Published EntryTrace heuristic cadence doc and recorded task completion; cadence now scheduled quarterly with fixture-first workflow. | EntryTrace Guild |
| 2025-11-16 | `SCANNER-ENG-0010..0014`: Marked BLOCKED pending design/staffing (PHP/Deno/Dart/Swift analyzers, Kubernetes/VM alignment); awaiting guild inputs. | Planning |
| 2025-11-17 | Removed legacy filename `SPRINT_138_scanner_ruby_parity.md` and updated `docs/implplan/tasks-all.md` references to the canonical sprint name to avoid duplication. | Planning |
## Decisions & Risks
- PHP analyzer pipeline (SCANNER-ENG-0010) blocked pending composer/autoload graph design + staffing; parity risk remains.
- Deno, Dart, and Swift analyzers (SCANNER-ENG-0011..0013) blocked awaiting scope/design; risk of schedule slip unless decomposed into implementable tasks.
- Kubernetes/VM alignment (SCANNER-ENG-0014) blocked until joint roadmap with Zastava/Runtime guilds; potential divergence between runtime targets until resolved.
- Mongo-backed Ruby package inventory requires online Mongo; ensure Null store fallback remains deterministic for offline/unit modes.
- EntryTrace cadence now documented; risk reduced to execution discipline—ensure quarterly reviews are logged in `TASKS.md` and sprint logs.
## Next Checkpoints
- Schedule guild sync to staff PHP analyzer pipeline and confirm design entry docs. (TBD week of 2025-11-18)
- Set alignment review with Zastava/Runtime guilds for Kubernetes/VM coverage plan. (TBD)
# Sprint 0138 · Scanner & Surface — Ruby Analyzer Parity
## Topic & Scope
- Achieve Ruby analyzer parity: runtime require/autoload graphs, capability signals, observation payloads, package inventories, and CLI/WebService wiring for scan/digest lookup.
- Sustain EntryTrace heuristic cadence with deterministic fixtures and explain-trace updates drawn from competitor gap benchmarks.
- Prepare runway for language coverage expansion (PHP now, Deno/Dart/Swift scoped) to keep parity roadmap on track.
- **Working directory:** `src/Scanner` (Analyzer, Worker, WebService, CLI surfaces) and supporting docs under `docs/modules/scanner`.
## Dependencies & Concurrency
- Depends on Sprint 0137 · Scanner.VIII (gap designs locked) and Sprint 0135 · Scanner.VI (EntryTrace foundations).
- Feeds Sprint 0139 and downstream CLI releases once Ruby analyzer, policy, and licensing tracks land.
- Parallel-safe with other modules; ensure Mongo is available when touching package inventory store tasks.
## Documentation Prerequisites
- `docs/README.md`; `docs/07_HIGH_LEVEL_ARCHITECTURE.md`.
- `docs/modules/scanner/architecture.md`; `docs/modules/scanner/operations/dsse-rekor-operator-guide.md`.
- AGENTS for involved components: `src/Scanner/StellaOps.Scanner.Worker/AGENTS.md`, `src/Scanner/StellaOps.Scanner.WebService/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Native/AGENTS.md`.
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD | DONE (2025-11-22) | Due 2025-11-22 · Accountable: PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Await composer/autoload graph design + staffing; no PHP analyzer scaffolding exists yet. <br><br> Document artefact/deliverable for SCANNER-ENG-0010 and publish location so downstream tasks can proceed. |
| P2 | PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Needs Deno runtime analyzer scope + lockfile/import graph design; pending competitive review. <br><br> Document artefact/deliverable for SCANNER-ENG-0011 and publish location so downstream tasks can proceed. |
| P3 | PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Define Dart analyzer requirements (pubspec parsing, AOT artifacts) and split into tasks. <br><br> Document artefact/deliverable for SCANNER-ENG-0012 and publish location so downstream tasks can proceed. |
| P4 | PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Draft SwiftPM coverage plan; align policy hooks; awaiting design kick-off. <br><br> Document artefact/deliverable for SCANNER-ENG-0013 and publish location so downstream tasks can proceed. |
| P5 | PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Needs joint roadmap with Zastava/Runtime guilds for Kubernetes/VM alignment. <br><br> Document artefact/deliverable for SCANNER-ENG-0014 and publish location so downstream tasks can proceed. |
| 1 | SCANNER-ENG-0008 | DONE (2025-11-16) | Cadence documented; quarterly review workflow published for EntryTrace heuristics. | EntryTrace Guild, QA Guild (`src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace`) | Maintain EntryTrace heuristic cadence per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`, including explain-trace updates. |
| 2 | SCANNER-ENG-0009 | DONE (2025-11-13) | Release handoff to Sprint 0139 consumers; monitor Mongo-backed inventory rollout. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Ruby analyzer parity shipped: runtime graph + capability signals, observation payload, Mongo-backed `ruby.packages` inventory, CLI/WebService surfaces, and plugin manifest bundles for Worker loadout. |
| 3 | SCANNER-ENG-0010 | BLOCKED | PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Ship the PHP analyzer pipeline (composer lock, autoload graph, capability signals) to close comparison gaps. |
| 4 | SCANNER-ENG-0011 | BLOCKED | PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Scope the Deno runtime analyzer (lockfile resolver, import graphs) beyond Sprint 130 coverage. |
| 5 | SCANNER-ENG-0012 | BLOCKED | PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Evaluate Dart analyzer requirements (pubspec parsing, AOT artifacts) and split implementation tasks. |
| 6 | SCANNER-ENG-0013 | BLOCKED | PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Plan Swift Package Manager coverage (Package.resolved, xcframeworks, runtime hints) with policy hooks. |
| 7 | SCANNER-ENG-0014 | BLOCKED | PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Align Kubernetes/VM target coverage between Scanner and Zastava per comparison findings; publish joint roadmap. |
| 8 | SCANNER-ENG-0015 | DONE (2025-11-13) | Ready for Ops training; track adoption metrics. | Export Center Guild, Scanner Guild (`docs/modules/scanner`) | DSSE/Rekor operator playbook published with config/env tables, rollout phases, offline verification, and SLA/alert guidance. |
| 9 | SCANNER-ENG-0016 | DONE (2025-11-10) | Monitor bundler override edge cases; keep fixtures deterministic. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | RubyLockCollector and vendor ingestion finalized: Bundler overrides honoured, workspace lockfiles merged, vendor bundles normalised, deterministic fixtures added. |
| 10 | SCANNER-ENG-0017 | DONE (2025-11-09) | Keep tree-sitter Ruby grammar pinned; reuse EntryTrace hints for regressions. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Build runtime require/autoload graph builder with tree-sitter Ruby per design §4.4 and integrate EntryTrace hints. |
| 11 | SCANNER-ENG-0018 | DONE (2025-11-09) | Feed predicates to policy docs; monitor capability gaps. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Emit Ruby capability + framework surface signals per design §4.5 with policy predicate hooks. |
| 12 | SCANNER-ENG-0019 | DONE (2025-11-13) | Observe CLI/WebService adoption; ensure scanId resolution metrics logged. | Ruby Analyzer Guild, CLI Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Ruby CLI verbs resolve inventories by scan ID, digest, or image reference; WebService fallbacks + CLI client encoding cover both digests and tagged references. |
| 13 | SCANNER-LIC-0001 | DONE (2025-11-10) | Keep Offline Kit mirrors current with ruby artifacts. | Scanner Guild, Legal Guild (`docs/modules/scanner`) | Tree-sitter licensing captured, `NOTICE.md` updated, and Offline Kit now mirrors `third-party-licenses/` with ruby artifacts. |
| 14 | SCANNER-POLICY-0001 | DONE (2025-11-10) | Align DSL docs with future PHP/Deno/Dart predicates. | Policy Guild, Ruby Analyzer Guild (`docs/modules/scanner`) | Ruby predicates shipped: Policy Engine exposes `sbom.any_component` + `ruby.*`, tests updated, DSL/offline-kit docs refreshed. |
| 15 | SCANNER-CLI-0001 | DONE (2025-11-10) | Final verification of docs/help; handoff to CLI release notes. | CLI Guild, Ruby Analyzer Guild (`src/Cli/StellaOps.Cli`) | Coordinate CLI UX/help text for new Ruby verbs and update CLI docs/golden outputs. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Removed trailing hyphen from PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE so SCANNER-ENG-0013 dependency resolves. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P1P5 BLOCKED pending composer/Deno/Dart/SwiftPM design contracts and Zastava/Runtime roadmap; downstream SCANNER-ENG-0010..0014 remain gated. | Project Mgmt |
| 2025-11-09 | `SCANNER-CLI-0001`: Spectre table wrapping fix for runtime/lockfile columns; expanded Ruby resolve JSON assertions; removed debug artifacts; docs/tests pending final merge. | CLI Guild |
| 2025-11-09 | `SCANNER-CLI-0001`: Wired `stellaops-cli ruby inspect|resolve` into `CommandFactory` with `--root`, `--image/--scan-id`, `--format`; `dotnet test ... --filter Ruby` passes. | CLI Guild |
| 2025-11-09 | `SCANNER-CLI-0001`: Added CLI unit tests (CommandFactoryTests, Ruby inspect JSON assertions) to guard new verbs and runtime metadata output. | CLI Guild |
| 2025-11-09 | `SCANNER-ENG-0016`: Completed Ruby lock collector & vendor ingestion; honours `.bundle/config` overrides, folds workspace lockfiles, emits bundler groups; fixtures/goldens updated; `dotnet test ... --filter Ruby` passes. | Ruby Analyzer Guild |
| 2025-11-12 | `SCANNER-ENG-0009`: Observation payload + `ruby-observation` component emitted; `complex-app` fixture added for vendor caches/BUNDLE_PATH overrides; bundler-version metadata captured; CLI prints observation banner. | Ruby Analyzer Guild |
| 2025-11-12 | `SCANNER-ENG-0009`: Ruby package inventories flow into `RubyPackageInventoryStore`; `SurfaceManifestStageExecutor` builds package list; WebService exposes `GET /api/scans/{scanId}/ruby-packages`. | Ruby Analyzer Guild |
| 2025-11-12 | `SCANNER-ENG-0009`: Inventory API returns typed envelope (scanId/imageDigest/generatedAt + packages); Worker/WebService DI registers real/Null stores; CLI `ruby resolve` consumes payload and warns during warmup. | Ruby Analyzer Guild |
| 2025-11-13 | `SCANNER-ENG-0009`: Verified Worker DI wiring; plugin drop mirrors analyzer assembly + manifest for Worker hot-load; tests cover analyzer fixtures, Worker persistence, WebService endpoint. | Ruby Analyzer Guild |
| 2025-11-13 | `SCANNER-ENG-0015`: DSSE/Rekor operator guide expanded with config/env map, rollout runbook, verification snippets, alert/SLO recommendations. | Export Center Guild |
| 2025-11-13 | `SCANNER-ENG-0019`: WebService maps digest/reference identifiers to scan IDs; CLI backend encodes path segments; regression tests (`RubyPackagesEndpointsTests`, `StellaOps.Cli.Tests --filter Ruby`) cover lookup path. | Ruby Analyzer Guild |
| 2025-11-16 | Normalised sprint file to standard template and renamed to `SPRINT_0138_0000_0001_scanner_ruby_parity.md`; no semantic task changes. | Planning |
| 2025-11-16 | `SCANNER-ENG-0008`: Published EntryTrace heuristic cadence doc and recorded task completion; cadence now scheduled quarterly with fixture-first workflow. | EntryTrace Guild |
| 2025-11-16 | `SCANNER-ENG-0010..0014`: Marked BLOCKED pending design/staffing (PHP/Deno/Dart/Swift analyzers, Kubernetes/VM alignment); awaiting guild inputs. | Planning |
| 2025-11-17 | Removed legacy filename `SPRINT_138_scanner_ruby_parity.md` and updated `docs/implplan/tasks-all.md` references to the canonical sprint name to avoid duplication. | Planning |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- PHP analyzer pipeline (SCANNER-ENG-0010) blocked pending composer/autoload graph design + staffing; parity risk remains.
- Deno, Dart, and Swift analyzers (SCANNER-ENG-0011..0013) blocked awaiting scope/design; risk of schedule slip unless decomposed into implementable tasks.
- Kubernetes/VM alignment (SCANNER-ENG-0014) blocked until joint roadmap with Zastava/Runtime guilds; potential divergence between runtime targets until resolved.
- Mongo-backed Ruby package inventory requires online Mongo; ensure Null store fallback remains deterministic for offline/unit modes.
- EntryTrace cadence now documented; risk reduced to execution discipline—ensure quarterly reviews are logged in `TASKS.md` and sprint logs.
## Next Checkpoints
- Schedule guild sync to staff PHP analyzer pipeline and confirm design entry docs. (TBD week of 2025-11-18)
- Set alignment review with Zastava/Runtime guilds for Kubernetes/VM coverage plan. (TBD)

View File

@@ -25,7 +25,7 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-140-D-ZASTAVA-WAVE-WAITING-ON-SURFACE-FS | DONE (2025-11-20) | Due 2025-11-22 · Accountable: Zastava Observer/Webhook Guilds · Surface Guild | Zastava Observer/Webhook Guilds · Surface Guild | Prep artefact published at `docs/modules/zastava/prep/2025-11-20-surface-fs-env-prep.md` (cache drop cadence, env helper ownership, DSSE requirements). |
| P2 | PREP-SBOM-SERVICE-GUILD-CARTOGRAPHER-GUILD-OB | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | BLOCKED. <br><br> Document artefact/deliverable for SBOM Service Guild · Cartographer Guild · Observability Guild, Zastava Observer/Webhook Guilds · Security Guild and publish location so downstream tasks can proceed. |
| P2 | PREP-SBOM-SERVICE-GUILD-CARTOGRAPHER-GUILD-OB | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | BLOCKED. <br><br> Document artefact/deliverable for SBOM Service Guild · Cartographer Guild · Observability Guild, Zastava Observer/Webhook Guilds · Security Guild and publish location so downstream tasks can proceed. |
| 1 | 140.A Graph wave | BLOCKED (2025-11-19) | Await real scanner cache ETA; working off mock bundle only. | Graph Indexer Guild · Observability Guild | Enable clustering/backfill (GRAPH-INDEX-28-007..010) against mock bundle; revalidate once real cache lands. |
| 2 | 140.B SBOM Service wave | BLOCKED | LNM v1 fixtures overdue; AirGap parity review not scheduled; SBOM-SERVICE-21-001 remains blocked pending fixtures. | 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 | BLOCKED (2025-11-20) | CAS promotion + signed manifests + provenance appendix pending; SIGNALS-24-002/003 blocked upstream. TRACTORS: see `docs/signals/cas-promotion-24-002.md` and `docs/signals/provenance-24-003.md`. | Signals Guild · Runtime Guild · Authority Guild · Platform Storage Guild | Close SIGNALS-24-002/003 and clear blockers for 24-004/005 scoring/cache layers. |
@@ -47,6 +47,7 @@
| 2025-11-13 | Snapshot, wave tracker, meeting prep, and action items refreshed ahead of Nov 13 checkpoints. | Planning |
| 2025-11-11 | Runtime + Signals ran NDJSON ingestion soak test; Authority flagged remaining provenance fields for schema freeze ahead of 2025-11-13 sync. | Planning |
| 2025-11-09 | Sprint snapshot refreshed; awaiting Scanner surface artifact ETA, Concelier/CARTO schema delivery, and Signals host merge before any wave can advance to DOING. | Planning |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Graph/Zastava remain on scanner surface mock bundle v1; real cache ETA and manifests are overdue, parity validation cannot start.

View File

@@ -1,52 +1,53 @@
# Sprint 0141 · Graph Indexer (Runtime & Signals 140.A)
## Topic & Scope
- Stand up graph clustering and centrality background jobs plus incremental/backfill pipelines for runtime & signals ingestion.
- Deliver deterministic tests/fixtures and packaging for offline-first deployments with backlog and observability metrics.
- Use scanner surface mock bundle v1 until real caches arrive.
- **Working directory:** `src/Graph/StellaOps.Graph.Indexer`.
## Dependencies & Concurrency
- Upstream: Sprint 120.A · AirGap (offline feeds) and Sprint 130.A · Scanner (surface/mock bundle availability).
- Pre-req task GRAPH-INDEX-28-006 (baseline overlays) must land before 28-007 clustering; track as inbound dependency.
- Coordinate with Observability Guild for metrics pipeline; parallel execution otherwise safe once mock bundle is fixed.
## Documentation Prerequisites
- docs/modules/graph/README.md
- docs/modules/graph/architecture.md
- docs/modules/graph/implementation_plan.md
- docs/modules/platform/architecture-overview.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P0 | PREP-GRAPH-INDEX-28-006-OVERLAYS | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild · Observability Guild | Graph Indexer Guild · Observability Guild | Deliver baseline overlays + schedule config design for GRAPH-INDEX-28-006; publish mock bundle + config docs so 28-007 can start. |
| P1 | PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild | Graph Indexer Guild | Unblock after 28-007; confirm change streams + retry/backoff settings. <br><br> Document artefact/deliverable for GRAPH-INDEX-28-008 and publish location so downstream tasks can proceed. |
| P2 | PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild · QA Guild | Graph Indexer Guild · QA Guild | Downstream of 28-008 data paths. <br><br> Document artefact/deliverable for GRAPH-INDEX-28-009 and publish location so downstream tasks can proceed. |
| P3 | PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild · DevOps Guild | Graph Indexer Guild · DevOps Guild | Needs outputs from 28-009; align with Offline Kit owners. <br><br> Document artefact/deliverable for GRAPH-INDEX-28-010 and publish location so downstream tasks can proceed. |
| 1 | GRAPH-INDEX-28-007 | BLOCKED | PREP-GRAPH-INDEX-28-006-OVERLAYS | Graph Indexer Guild · Observability Guild | Implement clustering/centrality background jobs (Louvain/degree/betweenness approximations) with configurable schedules; persist cluster ids on nodes; expose metrics. |
| 2 | GRAPH-INDEX-28-008 | BLOCKED | PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 | Graph Indexer Guild | Provide incremental update & backfill pipeline with change streams, retry/backoff, idempotent ops, backlog metrics. |
| 3 | GRAPH-INDEX-28-009 | BLOCKED | PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 | Graph Indexer Guild · QA Guild | Add unit/property/integration tests, synthetic large-graph fixtures, chaos tests (missing overlays, cycles), determinism checks across runs. |
| 4 | GRAPH-INDEX-28-010 | BLOCKED | PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 | Graph Indexer Guild · DevOps Guild | Package deployment artefacts (Helm/Compose), offline seed bundles, configuration docs; integrate Offline Kit. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Added PREP-GRAPH-INDEX-28-006-OVERLAYS and normalized PREP IDs for 28-008/009 so dependency graph is concrete. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P0P3 BLOCKED; overlays/mock bundle and change-stream/backfill configs are still missing, so GRAPH-INDEX-28-007..010 stay gated. | Project Mgmt |
| 2025-11-17 | Marked tasks 28-007 through 28-010 as BLOCKED pending upstream 28-006 overlays and scanner cache availability. | Planning |
| 2025-11-17 | Normalised sprint to standard template; renamed from SPRINT_141_graph.md; scope unchanged. | Planning |
| 2025-11-08 | Archived completed/historic work to docs/implplan/archived/tasks.md. | Planning |
## Decisions & Risks
- Operating on scanner surface mock bundle v1 until real caches arrive; reassess when Sprint 130.A delivers caches.
- All tasks currently blocked until GRAPH-INDEX-28-006 overlays land; confirm delivery date and update schedule config accordingly.
- Determinism risk for clustering approximations; require repeat-run variance checks in 28-009.
- Ensure offline seed bundles stay in sync with AirGap feeds from Sprint 120.A.
## Next Checkpoints
- 2025-11-19 · Confirm availability/timeline for scanner surface caches. Owner: Graph Indexer Guild.
- 2025-11-21 · Dependency check on GRAPH-INDEX-28-006 readiness with Observability Guild.
- 2025-11-26 · Packaging/Offline Kit alignment checkpoint with DevOps Guild after 28-009 test results.
# Sprint 0141 · Graph Indexer (Runtime & Signals 140.A)
## Topic & Scope
- Stand up graph clustering and centrality background jobs plus incremental/backfill pipelines for runtime & signals ingestion.
- Deliver deterministic tests/fixtures and packaging for offline-first deployments with backlog and observability metrics.
- Use scanner surface mock bundle v1 until real caches arrive.
- **Working directory:** `src/Graph/StellaOps.Graph.Indexer`.
## Dependencies & Concurrency
- Upstream: Sprint 120.A · AirGap (offline feeds) and Sprint 130.A · Scanner (surface/mock bundle availability).
- Pre-req task GRAPH-INDEX-28-006 (baseline overlays) must land before 28-007 clustering; track as inbound dependency.
- Coordinate with Observability Guild for metrics pipeline; parallel execution otherwise safe once mock bundle is fixed.
## Documentation Prerequisites
- docs/modules/graph/README.md
- docs/modules/graph/architecture.md
- docs/modules/graph/implementation_plan.md
- docs/modules/platform/architecture-overview.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P0 | PREP-GRAPH-INDEX-28-006-OVERLAYS | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Graph Indexer Guild · Observability Guild | Graph Indexer Guild · Observability Guild | Deliver baseline overlays + schedule config design for GRAPH-INDEX-28-006; publish mock bundle + config docs so 28-007 can start. |
| P1 | PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Graph Indexer Guild | Graph Indexer Guild | Unblock after 28-007; confirm change streams + retry/backoff settings. <br><br> Document artefact/deliverable for GRAPH-INDEX-28-008 and publish location so downstream tasks can proceed. |
| P2 | PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Graph Indexer Guild · QA Guild | Graph Indexer Guild · QA Guild | Downstream of 28-008 data paths. <br><br> Document artefact/deliverable for GRAPH-INDEX-28-009 and publish location so downstream tasks can proceed. |
| P3 | PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Graph Indexer Guild · DevOps Guild | Graph Indexer Guild · DevOps Guild | Needs outputs from 28-009; align with Offline Kit owners. <br><br> Document artefact/deliverable for GRAPH-INDEX-28-010 and publish location so downstream tasks can proceed. |
| 1 | GRAPH-INDEX-28-007 | BLOCKED | PREP-GRAPH-INDEX-28-006-OVERLAYS | Graph Indexer Guild · Observability Guild | Implement clustering/centrality background jobs (Louvain/degree/betweenness approximations) with configurable schedules; persist cluster ids on nodes; expose metrics. |
| 2 | GRAPH-INDEX-28-008 | BLOCKED | PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 | Graph Indexer Guild | Provide incremental update & backfill pipeline with change streams, retry/backoff, idempotent ops, backlog metrics. |
| 3 | GRAPH-INDEX-28-009 | BLOCKED | PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 | Graph Indexer Guild · QA Guild | Add unit/property/integration tests, synthetic large-graph fixtures, chaos tests (missing overlays, cycles), determinism checks across runs. |
| 4 | GRAPH-INDEX-28-010 | BLOCKED | PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 | Graph Indexer Guild · DevOps Guild | Package deployment artefacts (Helm/Compose), offline seed bundles, configuration docs; integrate Offline Kit. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Added PREP-GRAPH-INDEX-28-006-OVERLAYS and normalized PREP IDs for 28-008/009 so dependency graph is concrete. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP tasks P0P3 BLOCKED; overlays/mock bundle and change-stream/backfill configs are still missing, so GRAPH-INDEX-28-007..010 stay gated. | Project Mgmt |
| 2025-11-17 | Marked tasks 28-007 through 28-010 as BLOCKED pending upstream 28-006 overlays and scanner cache availability. | Planning |
| 2025-11-17 | Normalised sprint to standard template; renamed from SPRINT_141_graph.md; scope unchanged. | Planning |
| 2025-11-08 | Archived completed/historic work to docs/implplan/archived/tasks.md. | Planning |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Operating on scanner surface mock bundle v1 until real caches arrive; reassess when Sprint 130.A delivers caches.
- All tasks currently blocked until GRAPH-INDEX-28-006 overlays land; confirm delivery date and update schedule config accordingly.
- Determinism risk for clustering approximations; require repeat-run variance checks in 28-009.
- Ensure offline seed bundles stay in sync with AirGap feeds from Sprint 120.A.
## Next Checkpoints
- 2025-11-19 · Confirm availability/timeline for scanner surface caches. Owner: Graph Indexer Guild.
- 2025-11-21 · Dependency check on GRAPH-INDEX-28-006 readiness with Observability Guild.
- 2025-11-26 · Packaging/Offline Kit alignment checkpoint with DevOps Guild after 28-009 test results.

View File

@@ -20,8 +20,8 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SBOM-CONSOLE-23-001-BUILD-TEST-FAILING-D | DONE (2025-11-20) | Due 2025-11-22 · Accountable: SBOM Service Guild; Cartographer Guild | SBOM Service Guild; Cartographer Guild | Build/test failing due to missing NuGet feed; need feed/offline cache before wiring storage and validating `/console/sboms`. <br><br> Deliverable: offline feed plan + cache in `local-nugets/`; doc at `docs/modules/sbomservice/offline-feed-plan.md`; script `tools/offline/fetch-sbomservice-deps.sh` hydrates required packages. |
| P2 | PREP-SBOM-SERVICE-21-001-WAITING-ON-LNM-V1-FI | DOING (2025-11-20) | Due 2025-11-22 · Accountable: SBOM Service Guild; Cartographer Guild | SBOM Service Guild; Cartographer Guild | Waiting on LNM v1 fixtures (due 2025-11-18 UTC) to freeze schema; then publish normalized SBOM projection read API with pagination + tenant enforcement. <br><br> Document artefact/deliverable for SBOM-SERVICE-21-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/sbomservice/prep/2025-11-20-sbom-service-21-001-prep.md`. |
| P3 | PREP-BUILD-INFRA-SBOM-SERVICE-GUILD-BLOCKED-M | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Planning | Planning | BLOCKED (multiple restore attempts still hang/fail; need vetted feed/cache). <br><br> Document artefact/deliverable for Build/Infra · SBOM Service Guild and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/sbomservice/prep/2025-11-20-build-infra-prep.md`. |
| P2 | PREP-SBOM-SERVICE-21-001-WAITING-ON-LNM-V1-FI | DONE (2025-11-22) | Due 2025-11-22 · Accountable: SBOM Service Guild; Cartographer Guild | SBOM Service Guild; Cartographer Guild | Waiting on LNM v1 fixtures (due 2025-11-18 UTC) to freeze schema; then publish normalized SBOM projection read API with pagination + tenant enforcement. <br><br> Document artefact/deliverable for SBOM-SERVICE-21-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/sbomservice/prep/2025-11-20-sbom-service-21-001-prep.md`. |
| P3 | PREP-BUILD-INFRA-SBOM-SERVICE-GUILD-BLOCKED-M | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Planning | Planning | BLOCKED (multiple restore attempts still hang/fail; need vetted feed/cache). <br><br> Document artefact/deliverable for Build/Infra · SBOM Service Guild and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/sbomservice/prep/2025-11-20-build-infra-prep.md`. |
| 1 | SBOM-AIAI-31-001 | DONE | Implemented `/sbom/paths` with env/blast-radius/runtime flags + cursor paging and `/sbom/versions` timeline; in-memory deterministic seed until storage wired. | SBOM Service Guild (src/SbomService/StellaOps.SbomService) | Provide path and version timeline endpoints optimised for Advisory AI. |
| 2 | SBOM-AIAI-31-002 | DONE | Metrics + cache-hit tagging implemented; Grafana starter dashboard added; build/test completed locally. | SBOM Service Guild; Observability Guild | Instrument metrics for path/timeline queries and surface dashboards. |
| 3 | SBOM-CONSOLE-23-001 | BLOCKED | PREP-SBOM-CONSOLE-23-001-BUILD-TEST-FAILING-D | SBOM Service Guild; Cartographer Guild | Provide Console-focused SBOM catalog API. |
@@ -81,6 +81,7 @@
| 2025-11-19 | Added root NuGet.Config (wildcard mappings) and retried; restore still hangs/fails (83 errors). Build/test remain blocked pending vetted feed/cache. | Implementer |
| 2025-11-19 | Downloaded packages (Tokens 8.14.0, Pkcs11Interop 4.1.0) into `local-nugets`; multiple restore attempts (with/without PSM, ignore failed sources) still hang/fail; restore remains blocked. | Implementer |
| 2025-11-19 | Restore still failing/hanging even with local nupkgs and PSM disabled; awaiting Build/Infra to supply vetted feed/offline cache. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- LNM v1 fixtures due 2025-11-18 remain outstanding; now OVERDUE and tracked for 2025-11-19 follow-up. SBOM-SERVICE-21-001 stays BLOCKED until fixtures land.

View File

@@ -19,27 +19,27 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-ORCH-AIRGAP-56-001-AWAIT-SPRINT-0120-A-A | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · AirGap Policy Guild | Orchestrator Service Guild · AirGap Policy Guild | Await Sprint 0120.A AirGap readiness; sealed-mode contracts not published. <br><br> Document artefact/deliverable for ORCH-AIRGAP-56-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-56-001-prep.md`. |
| P2 | PREP-ORCH-AIRGAP-56-002-UPSTREAM-56-001-BLOCK | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · AirGap Controller Guild | Orchestrator Service Guild · AirGap Controller Guild | Upstream 56-001 blocked. <br><br> Document artefact/deliverable for ORCH-AIRGAP-56-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-56-002-prep.md`. |
| P3 | PREP-ORCH-AIRGAP-57-001-UPSTREAM-56-002-BLOCK | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Mirror Creator Guild | Orchestrator Service Guild · Mirror Creator Guild | Upstream 56-002 blocked. <br><br> Document artefact/deliverable for ORCH-AIRGAP-57-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-57-001-prep.md`. |
| P4 | PREP-ORCH-AIRGAP-58-001-UPSTREAM-57-001-BLOCK | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Evidence Locker Guild | Orchestrator Service Guild · Evidence Locker Guild | Upstream 57-001 blocked. <br><br> Document artefact/deliverable for ORCH-AIRGAP-58-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-58-001-prep.md`. |
| P5 | PREP-ORCH-OAS-61-001-ORCHESTRATOR-TELEMETRY-C | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · API Contracts Guild | Orchestrator Service Guild · API Contracts Guild | Orchestrator telemetry/contract inputs not available; wait for 150.A readiness. <br><br> Document artefact/deliverable for ORCH-OAS-61-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-oas-61-001-prep.md`. |
| P6 | PREP-ORCH-OAS-61-002-DEPENDS-ON-61-001 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 61-001. <br><br> Document artefact/deliverable for ORCH-OAS-61-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-oas-61-001-prep.md`. |
| P7 | PREP-ORCH-OAS-62-001-DEPENDS-ON-61-002 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · SDK Generator Guild | Orchestrator Service Guild · SDK Generator Guild | Depends on 61-002. <br><br> Document artefact/deliverable for ORCH-OAS-62-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-oas-61-001-prep.md`. |
| P1 | PREP-ORCH-AIRGAP-56-001-AWAIT-SPRINT-0120-A-A | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · AirGap Policy Guild | Orchestrator Service Guild · AirGap Policy Guild | Await Sprint 0120.A AirGap readiness; sealed-mode contracts not published. <br><br> Document artefact/deliverable for ORCH-AIRGAP-56-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-56-001-prep.md`. |
| P2 | PREP-ORCH-AIRGAP-56-002-UPSTREAM-56-001-BLOCK | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · AirGap Controller Guild | Orchestrator Service Guild · AirGap Controller Guild | Upstream 56-001 blocked. <br><br> Document artefact/deliverable for ORCH-AIRGAP-56-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-56-002-prep.md`. |
| P3 | PREP-ORCH-AIRGAP-57-001-UPSTREAM-56-002-BLOCK | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Mirror Creator Guild | Orchestrator Service Guild · Mirror Creator Guild | Upstream 56-002 blocked. <br><br> Document artefact/deliverable for ORCH-AIRGAP-57-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-57-001-prep.md`. |
| P4 | PREP-ORCH-AIRGAP-58-001-UPSTREAM-57-001-BLOCK | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Evidence Locker Guild | Orchestrator Service Guild · Evidence Locker Guild | Upstream 57-001 blocked. <br><br> Document artefact/deliverable for ORCH-AIRGAP-58-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-airgap-58-001-prep.md`. |
| P5 | PREP-ORCH-OAS-61-001-ORCHESTRATOR-TELEMETRY-C | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · API Contracts Guild | Orchestrator Service Guild · API Contracts Guild | Orchestrator telemetry/contract inputs not available; wait for 150.A readiness. <br><br> Document artefact/deliverable for ORCH-OAS-61-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-oas-61-001-prep.md`. |
| P6 | PREP-ORCH-OAS-61-002-DEPENDS-ON-61-001 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 61-001. <br><br> Document artefact/deliverable for ORCH-OAS-61-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-oas-61-001-prep.md`. |
| P7 | PREP-ORCH-OAS-62-001-DEPENDS-ON-61-002 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · SDK Generator Guild | Orchestrator Service Guild · SDK Generator Guild | Depends on 61-002. <br><br> Document artefact/deliverable for ORCH-OAS-62-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/orchestrator/prep/2025-11-20-oas-61-001-prep.md`. |
| P8 | PREP-ORCH-OAS-63-001-DEPENDS-ON-62-001 | DONE (2025-11-20) | Prep doc at `docs/modules/orchestrator/prep/2025-11-20-oas-63-001-prep.md`; waiting for 61/62 freeze before implementation. | Orchestrator Service Guild · API Governance Guild | Depends on 62-001. <br><br> Document artefact/deliverable for ORCH-OAS-63-001 and publish location so downstream tasks can proceed. |
| P9 | PREP-ORCH-OBS-50-001-TELEMETRY-CORE-SPRINT-01 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Observability Guild | Orchestrator Service Guild · Observability Guild | Telemetry Core (Sprint 0174) not yet available for orchestrator host. <br><br> Document artefact/deliverable for ORCH-OBS-50-001 and publish location so downstream tasks can proceed. |
| P9 | PREP-ORCH-OBS-50-001-TELEMETRY-CORE-SPRINT-01 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Observability Guild | Orchestrator Service Guild · Observability Guild | Telemetry Core (Sprint 0174) not yet available for orchestrator host. <br><br> Document artefact/deliverable for ORCH-OBS-50-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-OBS-50-001 (status → DOING) after confirming no prior DOING/DONE owners. | Planning |
| P10 | PREP-ORCH-OBS-51-001-DEPENDS-ON-50-001-TELEME | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · DevOps Guild | Orchestrator Service Guild · DevOps Guild | Depends on 50-001 + Telemetry schema. <br><br> Document artefact/deliverable for ORCH-OBS-51-001 and publish location so downstream tasks can proceed. |
| P10 | PREP-ORCH-OBS-51-001-DEPENDS-ON-50-001-TELEME | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · DevOps Guild | Orchestrator Service Guild · DevOps Guild | Depends on 50-001 + Telemetry schema. <br><br> Document artefact/deliverable for ORCH-OBS-51-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-OBS-51-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P11 | PREP-ORCH-OBS-52-001-DEPENDS-ON-51-001-REQUIR | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 51-001; requires event schema from Sprint 0150.A. <br><br> Document artefact/deliverable for ORCH-OBS-52-001 and publish location so downstream tasks can proceed. |
| P11 | PREP-ORCH-OBS-52-001-DEPENDS-ON-51-001-REQUIR | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 51-001; requires event schema from Sprint 0150.A. <br><br> Document artefact/deliverable for ORCH-OBS-52-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-OBS-52-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P12 | PREP-ORCH-OBS-53-001-DEPENDS-ON-52-001-EVIDEN | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Evidence Locker Guild | Orchestrator Service Guild · Evidence Locker Guild | Depends on 52-001; Evidence Locker capsule inputs not frozen. <br><br> Document artefact/deliverable for ORCH-OBS-53-001 and publish location so downstream tasks can proceed. |
| P12 | PREP-ORCH-OBS-53-001-DEPENDS-ON-52-001-EVIDEN | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Evidence Locker Guild | Orchestrator Service Guild · Evidence Locker Guild | Depends on 52-001; Evidence Locker capsule inputs not frozen. <br><br> Document artefact/deliverable for ORCH-OBS-53-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-OBS-53-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P13 | PREP-ORCH-OBS-54-001-DEPENDS-ON-53-001 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Provenance Guild | Orchestrator Service Guild · Provenance Guild | Depends on 53-001. <br><br> Document artefact/deliverable for ORCH-OBS-54-001 and publish location so downstream tasks can proceed. |
| P13 | PREP-ORCH-OBS-54-001-DEPENDS-ON-53-001 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Provenance Guild | Orchestrator Service Guild · Provenance Guild | Depends on 53-001. <br><br> Document artefact/deliverable for ORCH-OBS-54-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-OBS-54-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P14 | PREP-ORCH-OBS-55-001-DEPENDS-ON-54-001-INCIDE | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · DevOps Guild | Orchestrator Service Guild · DevOps Guild | Depends on 54-001; incident contract absent. <br><br> Document artefact/deliverable for ORCH-OBS-55-001 and publish location so downstream tasks can proceed. |
| P14 | PREP-ORCH-OBS-55-001-DEPENDS-ON-54-001-INCIDE | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild · DevOps Guild | Orchestrator Service Guild · DevOps Guild | Depends on 54-001; incident contract absent. <br><br> Document artefact/deliverable for ORCH-OBS-55-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-OBS-55-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P15 | PREP-ORCH-SVC-32-001-UPSTREAM-READINESS-AIRGA | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Upstream readiness (AirGap/Scanner/Graph) not confirmed; postpone bootstrap. <br><br> Document artefact/deliverable for ORCH-SVC-32-001 and publish location so downstream tasks can proceed. |
| P15 | PREP-ORCH-SVC-32-001-UPSTREAM-READINESS-AIRGA | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Upstream readiness (AirGap/Scanner/Graph) not confirmed; postpone bootstrap. <br><br> Document artefact/deliverable for ORCH-SVC-32-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-SVC-32-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| 1 | ORCH-AIRGAP-56-001 | BLOCKED (2025-11-19) | PREP-ORCH-AIRGAP-56-001-AWAIT-SPRINT-0120-A-A | Orchestrator Service Guild · AirGap Policy Guild | Enforce job descriptors to declare network intents; flag/reject external endpoints in sealed mode. |
| 2 | ORCH-AIRGAP-56-002 | BLOCKED (2025-11-19) | PREP-ORCH-AIRGAP-56-002-UPSTREAM-56-001-BLOCK | Orchestrator Service Guild · AirGap Controller Guild | Surface sealing status and staleness in scheduling decisions; block runs when budgets exceeded. |
@@ -66,6 +66,7 @@
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-18 | Normalised sprint doc to standard template; renamed from `SPRINT_151_orchestrator_i.md`. | Planning |
| 2025-11-19 | Set all tasks to BLOCKED pending upstream readiness (AirGap/Scanner/Graph), Telemetry Core availability, and Orchestrator event schema; no executable work until contracts land. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Start of work gated on AirGap/Scanner/Graph dependencies staying green; reassess before moving tasks to DOING.

View File

@@ -19,11 +19,11 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-ORCH-SVC-41-101-DEPENDS-ON-38-101-ENVELO | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 38-101 envelope + DAL; cannot register pack-run without API/storage schema. <br><br> Document artefact/deliverable for ORCH-SVC-41-101 and publish location so downstream tasks can proceed. |
| P1 | PREP-ORCH-SVC-41-101-DEPENDS-ON-38-101-ENVELO | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 38-101 envelope + DAL; cannot register pack-run without API/storage schema. <br><br> Document artefact/deliverable for ORCH-SVC-41-101 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-SVC-41-101 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P2 | PREP-ORCH-SVC-42-101-DEPENDS-ON-41-101-PACK-R | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 41-101 pack-run plumbing and streaming contract. <br><br> Document artefact/deliverable for ORCH-SVC-42-101 and publish location so downstream tasks can proceed. |
| P2 | PREP-ORCH-SVC-42-101-DEPENDS-ON-41-101-PACK-R | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 41-101 pack-run plumbing and streaming contract. <br><br> Document artefact/deliverable for ORCH-SVC-42-101 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-SVC-42-101 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| P3 | PREP-ORCH-TEN-48-001-WEBSERVICE-LACKS-JOB-DAL | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | WebService lacks job DAL/routes; need tenant context plumbing before enforcement. <br><br> Document artefact/deliverable for ORCH-TEN-48-001 and publish location so downstream tasks can proceed. |
| P3 | PREP-ORCH-TEN-48-001-WEBSERVICE-LACKS-JOB-DAL | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | WebService lacks job DAL/routes; need tenant context plumbing before enforcement. <br><br> Document artefact/deliverable for ORCH-TEN-48-001 and publish location so downstream tasks can proceed. |
| 2025-11-20 | Started PREP-ORCH-TEN-48-001 (status → DOING) after confirming no existing DOING/DONE owners. | Planning |
| 1 | ORCH-SVC-38-101 | BLOCKED | Waiting on ORCH-SVC-37-101 envelope field/semantics approval; webservice DAL still missing. | Orchestrator Service Guild | Standardize event envelope (policy/export/job lifecycle) with idempotency keys, ensure export/job failure events published to notifier bus with provenance metadata. |
| 2 | ORCH-SVC-41-101 | BLOCKED | PREP-ORCH-SVC-41-101-DEPENDS-ON-38-101-ENVELO | Orchestrator Service Guild | Register `pack-run` job type, persist run metadata, integrate logs/artifacts collection, and expose API for Task Runner scheduling. |
@@ -61,6 +61,7 @@
| 2025-11-19 | Clarified ORCH-SVC-38-101 remains BLOCKED until ORCH-SVC-37-101 envelope semantics are approved; webservice DAL still missing. | Implementer |
| 2025-11-18 | ORCH-TEN-48-001 blocked: orchestrator WebService is still template-only (no job DAL/routes), cannot enforce tenant context until real endpoints and DB session context exist. | Worker SDK Guild |
| 2025-11-19 | Set ORCH-SVC-38/41/42 and ORCH-TEN-48-001 to BLOCKED; awaiting ORCH-SVC-37-101 envelope approval and WebService DAL/schema. | Orchestrator Service Guild |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks

View File

@@ -19,8 +19,8 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCHED-SURFACE-01-NEED-SURFACE-FS-POINTER | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Need Surface.FS pointer model/contract; awaiting design input before planning deltas. <br><br> Document artefact/deliverable for SCHED-SURFACE-01 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scheduler/prep/2025-11-20-surface-fs-pointer.md`. |
| P2 | PREP-SCHED-WORKER-23-101-WAITING-ON-POLICY-GU | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Waiting on Policy guild to supply activation event contract and throttle source. <br><br> Document artefact/deliverable for SCHED-WORKER-23-101 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scheduler/prep/2025-11-20-worker-23-101-prep.md`. |
| P1 | PREP-SCHED-SURFACE-01-NEED-SURFACE-FS-POINTER | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Need Surface.FS pointer model/contract; awaiting design input before planning deltas. <br><br> Document artefact/deliverable for SCHED-SURFACE-01 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scheduler/prep/2025-11-20-surface-fs-pointer.md`. |
| P2 | PREP-SCHED-WORKER-23-101-WAITING-ON-POLICY-GU | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Waiting on Policy guild to supply activation event contract and throttle source. <br><br> Document artefact/deliverable for SCHED-WORKER-23-101 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/scheduler/prep/2025-11-20-worker-23-101-prep.md`. |
| 0 | AGENTS-SCHEDULER-UPDATE | DONE | `src/Scheduler/AGENTS.md` created and published. | Project Manager · Architecture Guild | Populate module AGENTS charter covering roles, docs, determinism/testing rules, and allowed shared libs. |
| 1 | SCHED-IMPACT-16-303 | DONE | Implemented removal + snapshot/restore with compaction; snapshot payloads ready for RocksDB/Redis persistence. | Scheduler ImpactIndex Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex) | Snapshot/compaction + invalidation for removed images; persistence to RocksDB/Redis per architecture. |
| 2 | SCHED-SURFACE-01 | BLOCKED | PREP-SCHED-SURFACE-01-NEED-SURFACE-FS-POINTER | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Evaluate Surface.FS pointers when planning delta scans to avoid redundant work and prioritise drift-triggered assets. |
@@ -56,6 +56,7 @@
| 2025-11-05 | Resumed instrumentation work to match `policy_simulation_latency_seconds` naming, add coverage for SSE latency recording, and validate webhook sample alignment. | Observability Guild |
| 2025-11-05 | `dotnet test` blocked by pre-existing GraphJobs accessibility errors (`IGraphJobStore.UpdateAsync`). | Scheduler Worker Guild |
| 2025-11-04 | Graph job completions now persist to Mongo with optimistic guards, emit Redis/webhook notifications once per transition, and refresh result URI metadata idempotently (tests cover service + Mongo store paths). | Scheduler Worker Guild |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Module-level AGENTS charter now present at `src/Scheduler/AGENTS.md`.

View File

@@ -1,50 +1,51 @@
# Sprint 0156 · Scheduling & Automation (Scheduler II)
## Topic & Scope
- Phase II for Scheduler workers: staleness monitoring, batch simulations, resolver/evaluation orchestration, and console streaming.
- Continues after Scheduler I (0155); focuses on worker pipelines and reachability/resolver coherence.
- Blocked until module working-directory AGENTS charter exists for `src/Scheduler`.
- **Working directory:** src/Scheduler
## Dependencies & Concurrency
- Depends on Sprint 0155 (Scheduler I) completion and prior reachability worker (SCHED-WORKER-26-201).
- Concurrency: share worker code paths with Scheduler I; avoid overlapping migrations until unblocked.
## Documentation Prerequisites
- docs/modules/scheduler/README.md
- docs/modules/scheduler/architecture.md
- docs/modules/scheduler/implementation_plan.md
- docs/modules/platform/architecture-overview.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U | BLOCKED | Due 2025-11-23 · Accountable: Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Blocked by upstream stream schema design; depends on prior resolver/eval pipeline readiness. <br><br> Document artefact/deliverable for SCHED-WORKER-CONSOLE-23-201 and publish location so downstream tasks can proceed. |
| 0 | AGENTS-SCHEDULER-UPDATE | DONE | `src/Scheduler/AGENTS.md` created and published. | Project Manager · Architecture Guild | Create working-directory charter defining roles, prerequisites, determinism/testing rules, and allowed shared libs. |
| 1 | SCHED-WORKER-26-202 | BLOCKED | Blocked by SCHED-WORKER-26-201 (reachability joiner not delivered yet). | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement staleness monitor + notifier for outdated reachability facts, publishing warnings and updating dashboards. |
| 2 | SCHED-WORKER-27-301 | BLOCKED | Blocked by SCHED-WORKER-26-202. | Scheduler Worker Guild, Policy Registry Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement policy batch simulation worker: shard SBOM inventories, invoke Policy Engine, emit partial results, handle retries/backoff, and publish progress events. |
| 3 | SCHED-WORKER-27-302 | BLOCKED | Blocked by SCHED-WORKER-27-301. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Build reducer job aggregating shard outputs into final manifests (counts, deltas, samples) and writing to object storage with checksums; emit completion events. |
| 4 | SCHED-WORKER-27-303 | BLOCKED | Blocked by SCHED-WORKER-27-302. | Scheduler Worker Guild, Security Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Enforce tenant isolation, scope checks, and attestation integration for simulation jobs; secret scanning pipeline for uploaded policy sources. |
| 5 | SCHED-WORKER-29-001 | BLOCKED | Blocked by SCHED-WORKER-27-303. | Scheduler Worker Guild, Findings Ledger Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement resolver worker generating candidate findings from inventory + advisory evidence, respecting ecosystem version semantics and path scope; emit jobs for policy evaluation. |
| 6 | SCHED-WORKER-29-002 | BLOCKED | Blocked by SCHED-WORKER-29-001. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Build evaluation orchestration worker invoking Policy Engine batch eval, writing results to Findings Ledger projector queue, and handling retries/backoff. |
| 7 | SCHED-WORKER-29-003 | BLOCKED | Blocked by SCHED-WORKER-29-002. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Add monitoring for resolver/evaluation backlog, SLA breaches, and export job queue; expose metrics/alerts feeding DevOps dashboards. |
| 8 | SCHED-WORKER-CONSOLE-23-201 | BLOCKED | PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Stream run progress events (stage status, tuples processed, SLA hints) to Redis/NATS for Console SSE, with heartbeat, dedupe, and retention policy. Publish metrics + structured logs for queue lag. |
| 9 | SCHED-WORKER-CONSOLE-23-202 | BLOCKED | SCHED-WORKER-CONSOLE-23-201. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Coordinate evidence bundle jobs (enqueue, track status, cleanup) and expose job manifests to Web gateway; ensure idempotent reruns and cancellation support. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Clarified dependency for SCHED-WORKER-CONSOLE-23-202 to point at SCHED-WORKER-CONSOLE-23-201. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP-SCHED-WORKER-CONSOLE-23-201 BLOCKED because upstream stream schema and resolver/eval pipeline contracts are still absent, keeping CONSOLE-23-201/202 gated. | Project Mgmt |
| 2025-11-17 | Normalised sprint, renamed to `SPRINT_0156_0001_0002_scheduler_ii`, and marked tasks BLOCKED pending `src/Scheduler/AGENTS.md`. | Scheduler Worker Guild |
| 2025-11-17 | Created `src/Scheduler/AGENTS.md`; unblocked tasks and reset to TODO respecting dependencies. | Scheduler Worker Guild |
| 2025-11-18 | Marked all tasks BLOCKED awaiting upstream reachability worker (SCHED-WORKER-26-201) and subsequent contract handoffs (Policy activation events, stream schema). | Scheduler Worker Guild |
## Decisions & Risks
- Module-level AGENTS charter now present at `src/Scheduler/AGENTS.md`.
- GraphJobs accessibility issue (`IGraphJobStore.UpdateAsync`) may block validation once work begins.
- All Scheduler II tasks blocked until reachability joiner (SCHED-WORKER-26-201) and Policy activation event/stream schemas land; no implementation work can proceed yet.
## Next Checkpoints
- None scheduled; add once AGENTS charter is published and blocking issues cleared.
# Sprint 0156 · Scheduling & Automation (Scheduler II)
## Topic & Scope
- Phase II for Scheduler workers: staleness monitoring, batch simulations, resolver/evaluation orchestration, and console streaming.
- Continues after Scheduler I (0155); focuses on worker pipelines and reachability/resolver coherence.
- Blocked until module working-directory AGENTS charter exists for `src/Scheduler`.
- **Working directory:** src/Scheduler
## Dependencies & Concurrency
- Depends on Sprint 0155 (Scheduler I) completion and prior reachability worker (SCHED-WORKER-26-201).
- Concurrency: share worker code paths with Scheduler I; avoid overlapping migrations until unblocked.
## Documentation Prerequisites
- docs/modules/scheduler/README.md
- docs/modules/scheduler/architecture.md
- docs/modules/scheduler/implementation_plan.md
- docs/modules/platform/architecture-overview.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Blocked by upstream stream schema design; depends on prior resolver/eval pipeline readiness. <br><br> Document artefact/deliverable for SCHED-WORKER-CONSOLE-23-201 and publish location so downstream tasks can proceed. |
| 0 | AGENTS-SCHEDULER-UPDATE | DONE | `src/Scheduler/AGENTS.md` created and published. | Project Manager · Architecture Guild | Create working-directory charter defining roles, prerequisites, determinism/testing rules, and allowed shared libs. |
| 1 | SCHED-WORKER-26-202 | BLOCKED | Blocked by SCHED-WORKER-26-201 (reachability joiner not delivered yet). | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement staleness monitor + notifier for outdated reachability facts, publishing warnings and updating dashboards. |
| 2 | SCHED-WORKER-27-301 | BLOCKED | Blocked by SCHED-WORKER-26-202. | Scheduler Worker Guild, Policy Registry Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement policy batch simulation worker: shard SBOM inventories, invoke Policy Engine, emit partial results, handle retries/backoff, and publish progress events. |
| 3 | SCHED-WORKER-27-302 | BLOCKED | Blocked by SCHED-WORKER-27-301. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Build reducer job aggregating shard outputs into final manifests (counts, deltas, samples) and writing to object storage with checksums; emit completion events. |
| 4 | SCHED-WORKER-27-303 | BLOCKED | Blocked by SCHED-WORKER-27-302. | Scheduler Worker Guild, Security Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Enforce tenant isolation, scope checks, and attestation integration for simulation jobs; secret scanning pipeline for uploaded policy sources. |
| 5 | SCHED-WORKER-29-001 | BLOCKED | Blocked by SCHED-WORKER-27-303. | Scheduler Worker Guild, Findings Ledger Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement resolver worker generating candidate findings from inventory + advisory evidence, respecting ecosystem version semantics and path scope; emit jobs for policy evaluation. |
| 6 | SCHED-WORKER-29-002 | BLOCKED | Blocked by SCHED-WORKER-29-001. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Build evaluation orchestration worker invoking Policy Engine batch eval, writing results to Findings Ledger projector queue, and handling retries/backoff. |
| 7 | SCHED-WORKER-29-003 | BLOCKED | Blocked by SCHED-WORKER-29-002. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Add monitoring for resolver/evaluation backlog, SLA breaches, and export job queue; expose metrics/alerts feeding DevOps dashboards. |
| 8 | SCHED-WORKER-CONSOLE-23-201 | BLOCKED | PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Stream run progress events (stage status, tuples processed, SLA hints) to Redis/NATS for Console SSE, with heartbeat, dedupe, and retention policy. Publish metrics + structured logs for queue lag. |
| 9 | SCHED-WORKER-CONSOLE-23-202 | BLOCKED | SCHED-WORKER-CONSOLE-23-201. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Coordinate evidence bundle jobs (enqueue, track status, cleanup) and expose job manifests to Web gateway; ensure idempotent reruns and cancellation support. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-19 | Clarified dependency for SCHED-WORKER-CONSOLE-23-202 to point at SCHED-WORKER-CONSOLE-23-201. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-19 | Marked PREP-SCHED-WORKER-CONSOLE-23-201 BLOCKED because upstream stream schema and resolver/eval pipeline contracts are still absent, keeping CONSOLE-23-201/202 gated. | Project Mgmt |
| 2025-11-17 | Normalised sprint, renamed to `SPRINT_0156_0001_0002_scheduler_ii`, and marked tasks BLOCKED pending `src/Scheduler/AGENTS.md`. | Scheduler Worker Guild |
| 2025-11-17 | Created `src/Scheduler/AGENTS.md`; unblocked tasks and reset to TODO respecting dependencies. | Scheduler Worker Guild |
| 2025-11-18 | Marked all tasks BLOCKED awaiting upstream reachability worker (SCHED-WORKER-26-201) and subsequent contract handoffs (Policy activation events, stream schema). | Scheduler Worker Guild |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Module-level AGENTS charter now present at `src/Scheduler/AGENTS.md`.
- GraphJobs accessibility issue (`IGraphJobStore.UpdateAsync`) may block validation once work begins.
- All Scheduler II tasks blocked until reachability joiner (SCHED-WORKER-26-201) and Policy activation event/stream schemas land; no implementation work can proceed yet.
## Next Checkpoints
- None scheduled; add once AGENTS charter is published and blocking issues cleared.

View File

@@ -22,7 +22,7 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-DVOFF-64-002-NEEDS-SEALED-BUNDLE-SPEC-SA | DONE (2025-11-20) | Due 2025-11-23 · Accountable: DevPortal Offline Guild · AirGap Controller Guild | DevPortal Offline Guild · AirGap Controller Guild | Prep artefact published at `docs/modules/export-center/prep/2025-11-20-dvoff-64-002-prep.md` (sample sealed bundle + CLI verify contract/output/exit-codes). |
| P2 | PREP-EXPORT-AIRGAP-56-001-EVIDENCELOCKER-CONT | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service Guild · Mirror Creator Guild | Exporter Service Guild · Mirror Creator Guild | EvidenceLocker contract + advisory schema to finalize DSSE contents. <br><br> Document artefact/deliverable for EXPORT-AIRGAP-56-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-export-airgap-56-001-prep.md`. |
| P2 | PREP-EXPORT-AIRGAP-56-001-EVIDENCELOCKER-CONT | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service Guild · Mirror Creator Guild | Exporter Service Guild · Mirror Creator Guild | EvidenceLocker contract + advisory schema to finalize DSSE contents. <br><br> Document artefact/deliverable for EXPORT-AIRGAP-56-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-export-airgap-56-001-prep.md`. |
| P3 | PREP-EXPORT-AIRGAP-56-002-DEPENDS-ON-56-001-S | DONE (2025-11-20) | Prep artefact at `docs/modules/export-center/prep/2025-11-20-export-airgap-56-002-prep.md`; waiting on 56-001 schema to unblock impl. | Exporter Service Guild · DevOps Guild | Depends on 56-001; same schema prerequisites. <br><br> Document artefact/deliverable for EXPORT-AIRGAP-56-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-export-airgap-56-002-prep.md`. |
| P4 | PREP-EXPORT-AIRGAP-57-001-DEPENDS-ON-56-002-N | DONE (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service Guild · Evidence Locker Guild | Exporter Service Guild · Evidence Locker Guild | Depends on 56-002; needs sealed evidence bundle format. <br><br> Prep artefact published at `docs/modules/export-center/prep/2025-11-20-export-airgap-57-001-prep.md` (export portable bundle contract, deterministic packaging, API surface, acceptance criteria). |
| P5 | PREP-EXPORT-AIRGAP-58-001-DEPENDS-ON-57-001-N | DONE (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service Guild · Notifications Guild | Exporter Service Guild · Notifications Guild | Depends on 57-001; prep artefact published at `docs/modules/export-center/prep/2025-11-20-export-airgap-58-001-prep.md` detailing notification payload, retries, deterministic headers, and linkage to export download. |
@@ -109,3 +109,4 @@
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-12 | Snapshot captured (pre-template) with tasks TODO. | Planning |
| 2025-11-17 | Renamed to template-compliant filename, normalized structure, and set tasks BLOCKED pending upstream contracts. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |

View File

@@ -20,16 +20,16 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service · Observability Guild | Exporter Service · Observability Guild | Wait for exporter service bootstrap + telemetry schema. <br><br> Document artefact/deliverable for EXPORT-OBS-50-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-obs-50-001-prep.md`. |
| P2 | PREP-EXPORT-RISK-69-001-AWAIT-PHASE-I-ARTIFAC | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service · Risk Bundle Export Guild | Exporter Service · Risk Bundle Export Guild | Await phase I artifacts + schema; needs provider selection rules. <br><br> Document artefact/deliverable for EXPORT-RISK-69-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-risk-69-001-prep.md`. |
| P3 | PREP-EXPORT-SVC-35-001-NEEDS-PHASE-I-READINES | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Needs phase I readiness + synthetic telemetry feeds. <br><br> Document artefact/deliverable for EXPORT-SVC-35-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-001-prep.md`. |
| P4 | PREP-EXPORT-SVC-35-002-DEPENDS-ON-35-001 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-001. <br><br> Document artefact/deliverable for EXPORT-SVC-35-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-002-prep.md`. |
| P5 | PREP-EXPORT-SVC-35-003-DEPENDS-ON-35-002 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-002. <br><br> Document artefact/deliverable for EXPORT-SVC-35-003 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-003-prep.md`. |
| P6 | PREP-EXPORT-SVC-35-004-DEPENDS-ON-35-003 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-003. <br><br> Document artefact/deliverable for EXPORT-SVC-35-004 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-004-prep.md`. |
| P7 | PREP-EXPORT-SVC-35-005-DEPENDS-ON-35-004 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-004. <br><br> Document artefact/deliverable for EXPORT-SVC-35-005 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-005-prep.md`. |
| P8 | PREP-EXPORT-NOTIFY-SCHEMA-OBS-52 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Notifications Guild · Exporter Service | Notifications Guild · Exporter Service | Notifications schema for export lifecycle events not published; required for EXPORT-OBS-52-001 and downstream tasks. Provide envelope + sample payloads. Prep artefact: `docs/modules/export-center/prep/2025-11-20-notify-obs-52-prep.md`. |
| P8 | PREP-EXPORT-CRYPTO-90-001-PENDING-NOV-18-CRYP | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Exporter Service · Security Guild | Exporter Service · Security Guild | Pending Nov-18 crypto review + reference implementation. <br><br> Document artefact/deliverable for EXPORT-CRYPTO-90-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-crypto-90-001-prep.md`. |
| P9 | PREP-EXPORTER-SERVICE-BLOCKED-WAITING-ON-EVID | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Planning | Planning | BLOCKED (waiting on EvidenceLocker spec). <br><br> Document artefact/deliverable for Exporter Service and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-exporter-evid-blocker.md`. |
| P1 | PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service · Observability Guild | Exporter Service · Observability Guild | Wait for exporter service bootstrap + telemetry schema. <br><br> Document artefact/deliverable for EXPORT-OBS-50-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-obs-50-001-prep.md`. |
| P2 | PREP-EXPORT-RISK-69-001-AWAIT-PHASE-I-ARTIFAC | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service · Risk Bundle Export Guild | Exporter Service · Risk Bundle Export Guild | Await phase I artifacts + schema; needs provider selection rules. <br><br> Document artefact/deliverable for EXPORT-RISK-69-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-risk-69-001-prep.md`. |
| P3 | PREP-EXPORT-SVC-35-001-NEEDS-PHASE-I-READINES | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Needs phase I readiness + synthetic telemetry feeds. <br><br> Document artefact/deliverable for EXPORT-SVC-35-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-001-prep.md`. |
| P4 | PREP-EXPORT-SVC-35-002-DEPENDS-ON-35-001 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-001. <br><br> Document artefact/deliverable for EXPORT-SVC-35-002 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-002-prep.md`. |
| P5 | PREP-EXPORT-SVC-35-003-DEPENDS-ON-35-002 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-002. <br><br> Document artefact/deliverable for EXPORT-SVC-35-003 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-003-prep.md`. |
| P6 | PREP-EXPORT-SVC-35-004-DEPENDS-ON-35-003 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-003. <br><br> Document artefact/deliverable for EXPORT-SVC-35-004 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-004-prep.md`. |
| P7 | PREP-EXPORT-SVC-35-005-DEPENDS-ON-35-004 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-004. <br><br> Document artefact/deliverable for EXPORT-SVC-35-005 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-svc-35-005-prep.md`. |
| P8 | PREP-EXPORT-NOTIFY-SCHEMA-OBS-52 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Notifications Guild · Exporter Service | Notifications Guild · Exporter Service | Notifications schema for export lifecycle events not published; required for EXPORT-OBS-52-001 and downstream tasks. Provide envelope + sample payloads. Prep artefact: `docs/modules/export-center/prep/2025-11-20-notify-obs-52-prep.md`. |
| P8 | PREP-EXPORT-CRYPTO-90-001-PENDING-NOV-18-CRYP | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Exporter Service · Security Guild | Exporter Service · Security Guild | Pending Nov-18 crypto review + reference implementation. <br><br> Document artefact/deliverable for EXPORT-CRYPTO-90-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-crypto-90-001-prep.md`. |
| P9 | PREP-EXPORTER-SERVICE-BLOCKED-WAITING-ON-EVID | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Planning | Planning | BLOCKED (waiting on EvidenceLocker spec). <br><br> Document artefact/deliverable for Exporter Service and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/export-center/prep/2025-11-20-exporter-evid-blocker.md`. |
| 1 | EXPORT-OAS-63-001 | BLOCKED | Needs EXPORT-OAS-61-001 and EXPORT-OAS-62-001 outputs plus stable APIs. | Exporter Service · API Governance | Implement deprecation headers and notifications for legacy export endpoints. |
| 2 | EXPORT-OBS-50-001 | BLOCKED | PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV | Exporter Service · Observability Guild | Adopt telemetry core capturing profile id, tenant, artifact counts, distribution type, trace IDs. |
| 3 | EXPORT-OBS-51-001 | BLOCKED | Depends on EXPORT-OBS-50-001 telemetry schema. | Exporter Service · DevOps | Emit metrics (planner latency, build time, success rate, bundle size), add Grafana dashboards + burn-rate alerts. |
@@ -96,3 +96,4 @@
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-12 | Snapshot captured (pre-template) with tasks TODO. | Planning |
| 2025-11-17 | Renamed to compliant filename, applied template, and set tasks to BLOCKED pending upstream contracts and Sprint 0162 outputs. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |

View File

@@ -19,7 +19,7 @@
## Delivery Tracker
| # | Track | Status | Key dependency / next step | Owners | Notes |
| --- | --- | --- | --- | --- | --- |
| 1 | 170.A · Notifier readiness | BLOCKED (2025-11-19) | Await CI restore for NOTIFY-OBS-51-001 SLO webhook tests; risk routing still depends on POLICY-RISK-40-002 export. | Notifications Service Guild · Attestor Service Guild · Observability Guild | Active work mirrored to Sprint 0171; attestation/OAS tracks are done, observability/risk tracks paused until dependencies clear. |
| 1 | 170.A · Notifier readiness | DONE (2025-11-22) | SLO webhook tests passed; incident-mode templates shipped. Risk routing still pending POLICY-RISK-40-002 but scoped to later track. | Notifications Service Guild · Attestor Service Guild · Observability Guild | NOTIFY-OBS-51-001 validated; NOTIFY-OBS-55-001 templates/rules published. Remaining risk alerts tracked in Sprint 0171 tasks 911. |
| 2 | 170.B · Telemetry bootstrap | BLOCKED (2025-11-19) | TELEMETRY-OBS-50-001 shipped; propagation adapters (50-002) waiting on bootstrap adoption + CLI toggle contract (CLI-OBS-12-001). | Telemetry Core Guild · Observability Guild · Security Guild | Bootstrap of `StellaOps.Telemetry.Core` complete; downstream propagation/scrub/incident work paused until contracts/tests land (see Sprint 0174). |
## Execution Log
@@ -31,6 +31,7 @@
| 2025-11-19 | Re-baselined tracks: set 170.A and 170.B to BLOCKED pending CI restore (Notifier SLO tests) and propagation/toggle contracts; TELEMETRY-OBS-50-001 marked DONE in Sprint 0174. | Implementer |
| 2025-11-12 | Documented attestation template suite in `docs/notifications/templates.md` to unblock NOTIFY-ATTEST-74-001; synced notifications docs. | Notifications Service Guild |
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_170_notifications_telemetry.md` to `SPRINT_0170_0001_0001_notifications_telemetry.md`; content preserved; legacy stub added. | Implementer |
| 2025-11-22 | Marked 170.A DONE after NOTIFY-OBS-51-001 tests passed and incident-mode templates/rules landed (NOTIFY-OBS-55-001). Risk alerts remain pending POLICY-RISK-40-002 and stay tracked under Sprint 0171 tasks 911. | Implementer |
## Decisions & Risks
- Orchestrator observability contracts (ORCH-OBS-50-001) must land before enabling Notifier SLO webhooks and Telemetry helpers.

View File

@@ -27,11 +27,11 @@
| 4 | NOTIFY-OAS-61-002 | DONE (2025-11-17) | Depends on 61-001. | Notifications Service Guild | Implement `/.well-known/openapi` discovery endpoint with scope metadata. |
| 5 | NOTIFY-OAS-62-001 | DONE (2025-11-17) | Depends on 61-002. | Notifications Service Guild · SDK Generator Guild | SDK examples for rule CRUD, incident ack, quiet hours; SDK smoke tests. |
| 6 | NOTIFY-OAS-63-001 | DONE (2025-11-17) | Depends on 62-001. | Notifications Service Guild · API Governance Guild | Emit deprecation headers and templates for retiring notifier APIs. |
| 7 | NOTIFY-OBS-51-001 | BLOCKED (2025-11-19) | CI restore for `HttpEgressSloSinkTests` / `EventProcessorTests` | Notifications Service Guild · Observability Guild | Integrate SLO evaluator webhooks into Notifier rules; templates/routing/suppression; sample policies. |
| 8 | NOTIFY-OBS-55-001 | TODO | Depends on 51-001. | Notifications Service Guild · Ops Guild | Publish incident mode start/stop notifications with trace/evidence links, retention notes, quiet-hour overrides, legal logging. |
| 9 | NOTIFY-RISK-66-001 | TODO | Depends on POLICY-RISK-40-002 metadata export. | Notifications Service Guild · Risk Engine Guild | Add notification triggers for risk severity escalation/downgrade with profile metadata. |
| 10 | NOTIFY-RISK-67-001 | TODO | Depends on 66-001. | Notifications Service Guild · Policy Guild | Notify when risk profiles are published/deprecated/thresholds change. |
| 11 | NOTIFY-RISK-68-001 | TODO | Depends on 67-001. | Notifications Service Guild | Per-profile routing, quiet hours, dedupe for risk alerts; integrate CLI/Console preferences. |
| 7 | NOTIFY-OBS-51-001 | DONE (2025-11-22) | Filtered `HttpEgressSloSinkTests` / `EventProcessorTests` now passing; TRX at `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/TestResults/notifier-slo-tests.trx`. | Notifications Service Guild · Observability Guild | Integrate SLO evaluator webhooks into Notifier rules; templates/routing/suppression; sample policies. |
| 8 | NOTIFY-OBS-55-001 | DONE (2025-11-22) | Depends on 51-001. | Notifications Service Guild · Ops Guild | Incident mode start/stop templates and importable rules published with evidence/trace links, retention notes, quiet-hour overrides, and legal logging metadata. |
| 9 | NOTIFY-RISK-66-001 | BLOCKED (2025-11-22) | Depends on POLICY-RISK-40-002 metadata export. | Notifications Service Guild · Risk Engine Guild | Add notification triggers for risk severity escalation/downgrade with profile metadata. |
| 10 | NOTIFY-RISK-67-001 | BLOCKED (2025-11-22) | Depends on 66-001. | Notifications Service Guild · Policy Guild | Notify when risk profiles are published/deprecated/thresholds change. |
| 11 | NOTIFY-RISK-68-001 | BLOCKED (2025-11-22) | Depends on 67-001. | Notifications Service Guild | Per-profile routing, quiet hours, dedupe for risk alerts; integrate CLI/Console preferences. |
| 12 | NOTIFY-DOC-70-001 | DONE (2025-11-02) | — | Notifications Service Guild | Document split between legacy `src/Notify` libs and new `src/Notifier` runtime; update architecture docs. |
| 13 | NOTIFY-AIRGAP-56-002 | DONE | — | Notifications Service Guild · DevOps Guild | Bootstrap Pack notifier configs with deterministic secrets handling and offline validation. |
@@ -55,6 +55,10 @@
| 2025-11-19 | Marked NOTIFY-OBS-51-001 status to DOING; OBS SLO webhook code ready, pending CI validation to close the task. | Implementer |
| 2025-11-19 | Action item: run CI pipeline for Notifier with filters `HttpEgressSloSinkTests` and `EventProcessorTests`; if green, set NOTIFY-OBS-51-001 to DONE and attach TRX artefacts. | Implementer |
| 2025-11-19 | Set NOTIFY-OBS-51-001 to BLOCKED pending CI restore capacity; local restore repeatedly cancels (NuGet.targets:196). No further code changes until CI evidence available. | Implementer |
| 2025-11-22 | Resumed NOTIFY-OBS-51-001 after restore fixes; running filtered tests locally with TRX capture to validate SLO webhook sink and processor. | Implementer |
| 2025-11-22 | `HttpEgressSloSinkTests` and `EventProcessorTests` passed locally after wiring PackApprovals collection options + Mongo cursor fix; TRX evidence recorded at `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/TestResults/notifier-slo-tests.trx`. | Implementer |
| 2025-11-22 | Authored incident-mode templates + sample rules (`tmpl-incident-start/stop`) with evidence/trace/retention/legal context and quiet-hour overrides; published bundle at `src/Notifier/StellaOps.Notifier/docs/incident-mode-rules.sample.json` and updated `docs/notifications/templates.md`. Marked NOTIFY-OBS-55-001 DONE. | Implementer |
| 2025-11-22 | Marked NOTIFY-RISK-66-001/67-001/68-001 BLOCKED pending POLICY-RISK-40-002 export; no implementation started. | Implementer |
| 2025-11-19 | Added QA playbook for NOTIFY-ATTEST-74-002 (`src/Notifier/StellaOps.Notifier/StellaOps.Notifier.docs/QA-attestation-routing.md`) detailing import steps, event kinds, expected deliveries, and evidence to capture. | Implementer |
| 2025-11-20 | No unblocked work left in this sprint today: NOTIFY-ATTEST-74-002 depends on attestor payload localization freeze; NOTIFY-OBS-51/55 blocked until SLO webhook contract is wired into worker; NOTIFY-RISK-66..68 waits on `POLICY-RISK-40-002` export. Moving to next sprint. | Implementer |

View File

@@ -18,7 +18,7 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-NOTIFY-TEN-48-001-NOTIFIER-II-SPRINT-017 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifier II (Sprint 0172) not started; tenancy model not finalized. <br><br> Document artefact/deliverable for NOTIFY-TEN-48-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md`. |
| P1 | PREP-NOTIFY-TEN-48-001-NOTIFIER-II-SPRINT-017 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifier II (Sprint 0172) not started; tenancy model not finalized. <br><br> Document artefact/deliverable for NOTIFY-TEN-48-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md`. |
| 1 | NOTIFY-TEN-48-001 | BLOCKED (2025-11-20) | PREP-NOTIFY-TEN-48-001-NOTIFIER-II-SPRINT-017 | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Tenant-scope rules/templates/incidents, RLS on storage, tenant-prefixed channels, include tenant context in notifications. |
## Execution Log
@@ -29,6 +29,7 @@
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_173_notifier_iii.md` to `SPRINT_0173_0001_0003_notifier_iii.md`; content preserved. | Implementer |
| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer |
| 2025-11-20 | Marked NOTIFY-TEN-48-001 BLOCKED pending completion of Sprint 0172 tenancy model; no executable work in this sprint today. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Requires completion of Notifier II and established tenancy model before applying RLS.

View File

@@ -43,9 +43,10 @@
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_174_telemetry.md` to `SPRINT_0174_0001_0001_telemetry.md`; content preserved. | Implementer |
| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer |
| 2025-11-20 | Marked tasks 50-002..56-001 BLOCKED: waiting on 50-001 package publication, Security scrub policy, and CLI incident-toggle contract; no executable work until upstream artefacts land. | Implementer |
| 2025-11-19 | PREP-TELEMETRY-OBS-50-002-AWAIT-PUBLISHED-50 completed; bootstrap doc published. Downstream tasks remain blocked on propagation/scrub/toggle contracts. | Implementer |
| 2025-11-19 | PREP-TELEMETRY-OBS-50-002-AWAIT-PUBLISHED-50 completed; bootstrap doc published. Downstream tasks remain blocked on propagation/scrub/toggle contracts. | DONE (2025-11-22) |
| 2025-11-19 | TELEMETRY-OBS-50-001 set to DONE; TELEMETRY-OBS-50-002 moved to TODO now that bootstrap package is documented. | Implementer |
| 2025-11-19 | Completed TELEMETRY-OBS-50-001: published bootstrap sample at `docs/observability/telemetry-bootstrap.md`; library already present. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Propagation adapters wait on bootstrap package; Security scrub policy (POLICY-SEC-42-003) must approve before implementing 51-001/51-002.

View File

@@ -1,38 +1,38 @@
# Sprint 0187-0001-0001 · Evidence Locker & CLI Integration (Replay Delivery 187.A)
## Topic & Scope
- Persist replay bundles in Evidence Locker, expose ledger-backed verification, and ship offline-ready CLI workflows with sovereign crypto support.
- **Working directory:** `src/EvidenceLocker/StellaOps.EvidenceLocker`, `src/Cli/StellaOps.Cli`, `src/Attestor/StellaOps.Attestor`, relevant docs under `docs/replay`, `docs/modules/evidence-locker`, `docs/modules/cli`, `docs/runbooks`.
## Dependencies & Concurrency
- Upstream: Sprint 0186 (Scanner record mode), Sprint 0160 Export & Evidence, Sprint 0185 replay core, Sprint 0180 Experience & SDKs.
- Concurrency: execute tasks in listed order; CLI/Attestor depend on EvidenceLocker API schema; crypto routing depends on provider registry readiness.
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/replay/DETERMINISTIC_REPLAY.md
- docs/replay/DEVS_GUIDE_REPLAY.md
- docs/runbooks/replay_ops.md
- docs/security/crypto-routing-audit-2025-11-07.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
# Sprint 0187-0001-0001 · Evidence Locker & CLI Integration (Replay Delivery 187.A)
## Topic & Scope
- Persist replay bundles in Evidence Locker, expose ledger-backed verification, and ship offline-ready CLI workflows with sovereign crypto support.
- **Working directory:** `src/EvidenceLocker/StellaOps.EvidenceLocker`, `src/Cli/StellaOps.Cli`, `src/Attestor/StellaOps.Attestor`, relevant docs under `docs/replay`, `docs/modules/evidence-locker`, `docs/modules/cli`, `docs/runbooks`.
## Dependencies & Concurrency
- Upstream: Sprint 0186 (Scanner record mode), Sprint 0160 Export & Evidence, Sprint 0185 replay core, Sprint 0180 Experience & SDKs.
- Concurrency: execute tasks in listed order; CLI/Attestor depend on EvidenceLocker API schema; crypto routing depends on provider registry readiness.
## Documentation Prerequisites
- docs/README.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
- docs/replay/DETERMINISTIC_REPLAY.md
- docs/replay/DEVS_GUIDE_REPLAY.md
- docs/runbooks/replay_ops.md
- docs/security/crypto-routing-audit-2025-11-07.md
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-EVID-REPLAY-187-001-SCANNER-RECORD-PAYLO | DONE (2025-11-20) | Due 2025-11-23 · Accountable: Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Prep artefact published at `docs/modules/evidence-locker/replay-payload-contract.md` (scanner record payload shape, determinism, sample expectations). |
| P2 | PREP-CLI-REPLAY-187-002-DEPENDS-ON-187-001-SC | DOING (2025-11-20) | Due 2025-11-23 · Accountable: DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | Depends on 187-001 schema freeze. <br><br> Document artefact/deliverable for CLI-REPLAY-187-002 and publish location so downstream tasks can proceed. |
| P3 | PREP-ATTEST-REPLAY-187-003-DEPENDS-ON-187-001 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Depends on 187-001 payloads. <br><br> Document artefact/deliverable for ATTEST-REPLAY-187-003 and publish location so downstream tasks can proceed. |
| P4 | PREP-RUNBOOK-REPLAY-187-004-NEEDS-APIS-DEFINE | DOING (2025-11-20) | Due 2025-11-23 · Accountable: Docs Guild · Ops Guild (docs/runbooks) | Docs Guild · Ops Guild (docs/runbooks) | Needs APIs defined from 187-001. <br><br> Document artefact/deliverable for RUNBOOK-REPLAY-187-004 and publish location so downstream tasks can proceed. |
| P5 | PREP-VALIDATE-BUNDLE-187-005-DEPENDS-ON-187-0 | DOING (2025-11-20) | Due 2025-11-23 · Accountable: QA Guild · CLI Guild · Docs Guild | QA Guild · CLI Guild · Docs Guild | Depends on 187-001/002/003; no payloads yet. <br><br> Document artefact/deliverable for VALIDATE-BUNDLE-187-005 and publish location so downstream tasks can proceed. |
| P2 | PREP-CLI-REPLAY-187-002-DEPENDS-ON-187-001-SC | DONE (2025-11-22) | Due 2025-11-23 · Accountable: DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | Depends on 187-001 schema freeze. <br><br> Document artefact/deliverable for CLI-REPLAY-187-002 and publish location so downstream tasks can proceed. |
| P3 | PREP-ATTEST-REPLAY-187-003-DEPENDS-ON-187-001 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Depends on 187-001 payloads. <br><br> Document artefact/deliverable for ATTEST-REPLAY-187-003 and publish location so downstream tasks can proceed. |
| P4 | PREP-RUNBOOK-REPLAY-187-004-NEEDS-APIS-DEFINE | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Docs Guild · Ops Guild (docs/runbooks) | Docs Guild · Ops Guild (docs/runbooks) | Needs APIs defined from 187-001. <br><br> Document artefact/deliverable for RUNBOOK-REPLAY-187-004 and publish location so downstream tasks can proceed. |
| P5 | PREP-VALIDATE-BUNDLE-187-005-DEPENDS-ON-187-0 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: QA Guild · CLI Guild · Docs Guild | QA Guild · CLI Guild · Docs Guild | Depends on 187-001/002/003; no payloads yet. <br><br> Document artefact/deliverable for VALIDATE-BUNDLE-187-005 and publish location so downstream tasks can proceed. |
| P6 | PREP-EVID-CRYPTO-90-001-ICRYPTOPROVIDERREGIST | DONE (2025-11-20) | Due 2025-11-23 · Accountable: Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Prep artefact published at `docs/modules/evidence-locker/crypto-provider-registry-prep.md` (provider registry expectations, config, JWKS caching). |
| 1 | EVID-REPLAY-187-001 | BLOCKED (2025-11-20) | PREP-EVID-REPLAY-187-001-SCANNER-RECORD-PAYLO | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Implement replay bundle ingestion/retention APIs; document storage/retention rules referencing replay doc §§2 & 8. |
| 2 | CLI-REPLAY-187-002 | BLOCKED (2025-11-20) | PREP-CLI-REPLAY-187-002-DEPENDS-ON-187-001-SC | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | Add `scan --record`, `verify`, `replay`, `diff` commands with offline bundle resolution; update CLI architecture and replay appendix. |
| 3 | ATTEST-REPLAY-187-003 | BLOCKED (2025-11-20) | PREP-ATTEST-REPLAY-187-003-DEPENDS-ON-187-001 | Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Wire Attestor/Rekor anchoring for replay manifests; extend attestor architecture with replay ledger flow. |
| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED (2025-11-20) | PREP-RUNBOOK-REPLAY-187-004-NEEDS-APIS-DEFINE | Docs Guild · Ops Guild (docs/runbooks) | Publish `/docs/runbooks/replay_ops.md` covering retention enforcement, RootPack rotation, offline kits, verification drills. |
| 5 | VALIDATE-BUNDLE-187-005 | BLOCKED (2025-11-20) | PREP-VALIDATE-BUNDLE-187-005-DEPENDS-ON-187-0 | QA Guild · CLI Guild · Docs Guild | Deliver `VALIDATION_PLAN.md`, harness scripts (quiet vs baseline, provenance bundle export), `stella bundle verify` subcommand checking DSSE/Rekor/SBOM/policy/replay claims end-to-end. |
| 6 | EVID-CRYPTO-90-001 | BLOCKED (2025-11-20) | PREP-EVID-CRYPTO-90-001-ICRYPTOPROVIDERREGIST | Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Route Evidence Locker hashing/signing (manifest digests, DSSE assembly, bundle encryption) through crypto provider registry for sovereign profiles. |
## Execution Log
| 1 | EVID-REPLAY-187-001 | BLOCKED (2025-11-20) | PREP-EVID-REPLAY-187-001-SCANNER-RECORD-PAYLO | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Implement replay bundle ingestion/retention APIs; document storage/retention rules referencing replay doc §§2 & 8. |
| 2 | CLI-REPLAY-187-002 | BLOCKED (2025-11-20) | PREP-CLI-REPLAY-187-002-DEPENDS-ON-187-001-SC | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | Add `scan --record`, `verify`, `replay`, `diff` commands with offline bundle resolution; update CLI architecture and replay appendix. |
| 3 | ATTEST-REPLAY-187-003 | BLOCKED (2025-11-20) | PREP-ATTEST-REPLAY-187-003-DEPENDS-ON-187-001 | Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Wire Attestor/Rekor anchoring for replay manifests; extend attestor architecture with replay ledger flow. |
| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED (2025-11-20) | PREP-RUNBOOK-REPLAY-187-004-NEEDS-APIS-DEFINE | Docs Guild · Ops Guild (docs/runbooks) | Publish `/docs/runbooks/replay_ops.md` covering retention enforcement, RootPack rotation, offline kits, verification drills. |
| 5 | VALIDATE-BUNDLE-187-005 | BLOCKED (2025-11-20) | PREP-VALIDATE-BUNDLE-187-005-DEPENDS-ON-187-0 | QA Guild · CLI Guild · Docs Guild | Deliver `VALIDATION_PLAN.md`, harness scripts (quiet vs baseline, provenance bundle export), `stella bundle verify` subcommand checking DSSE/Rekor/SBOM/policy/replay claims end-to-end. |
| 6 | EVID-CRYPTO-90-001 | BLOCKED (2025-11-20) | PREP-EVID-CRYPTO-90-001-ICRYPTOPROVIDERREGIST | Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Route Evidence Locker hashing/signing (manifest digests, DSSE assembly, bundle encryption) through crypto provider registry for sovereign profiles. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Completed PREP-EVID-REPLAY-187-001: published replay payload contract at `docs/modules/evidence-locker/replay-payload-contract.md`; status set to DONE. | Implementer |
@@ -45,13 +45,14 @@
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_187_evidence_locker_cli_integration.md` to `SPRINT_0187_0001_0001_evidence_locker_cli_integration.md`; content preserved. | Implementer |
| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer |
| 2025-11-20 | Marked all tasks BLOCKED: waiting on Scanner record payloads (Sprint 0186) and ICryptoProviderRegistry readiness; no executable work in this sprint until upstream artefacts land. | Implementer |
## Decisions & Risks
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- EvidenceLocker API schema must align with replay bundles and sovereign crypto routing; approval review on 2025-11-18.
- CLI/Attestor work blocked until Scanner record payloads and EvidenceLocker schema freeze.
- Provider registry must support sovereign profiles (`ru-offline`, etc.) before wiring EVID-CRYPTO-90-001.
- Draft replay payload contract published at `docs/modules/evidence-locker/replay-payload-contract.md`; awaiting Sprint 0186 sample payloads and DSSE profile.
- Prep docs published for CLI replay, Attestor replay, runbook, bundle validation, and crypto provider registry (see Execution Log for paths); still blocked on upstream payloads and profile lists.
## Next Checkpoints
## Next Checkpoints
- Schedule joint review of replay_ops runbook and EvidenceLocker API (date TBD).

View File

@@ -20,10 +20,10 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-GRAPH-OPS-0001-WAITING-FOR-NEXT-DEMO-OUT | DOING (2025-11-20) | Due 2025-11-25 · Accountable: Ops Guild | Ops Guild | Waiting for next demo outputs to review dashboards/runbooks. <br><br> Document artefact/deliverable for GRAPH-OPS-0001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/graph/prep/2025-11-20-ops-0001-prep.md`. |
| P1 | PREP-GRAPH-OPS-0001-WAITING-FOR-NEXT-DEMO-OUT | DONE (2025-11-22) | Due 2025-11-25 · Accountable: Ops Guild | Ops Guild | Waiting for next demo outputs to review dashboards/runbooks. <br><br> Document artefact/deliverable for GRAPH-OPS-0001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/graph/prep/2025-11-20-ops-0001-prep.md`. |
| 1 | GRAPH-ENG-0001 | DONE | Synced docs to Sprint 0141 rename on 2025-11-17 | Module Team | Keep module milestones in sync with `/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md` and related files; update references and note deltas. |
| 2 | GRAPH-DOCS-0002 | BLOCKED | Await DOCS-GRAPH-24-003 cross-links | Docs Guild | Add API/query doc cross-links once DOCS-GRAPH-24-003 lands. |
| 3 | GRAPH-OPS-0001 | BLOCKED | PREP-GRAPH-OPS-0001-WAITING-FOR-NEXT-DEMO-OUT | Ops Guild | Review graph observability dashboards/runbooks after the next sprint demo; capture updates in runbooks. |
| 3 | GRAPH-OPS-0001 | TODO | PREP-GRAPH-OPS-0001-WAITING-FOR-NEXT-DEMO-OUT | Ops Guild | Review graph observability dashboards/runbooks after the next sprint demo; capture updates in runbooks. |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -33,6 +33,8 @@
| 2025-11-17 | Marked GRAPH-DOCS-0002 and GRAPH-OPS-0001 as BLOCKED pending DOCS-GRAPH-24-003 + next demo outputs. | Module Team |
| 2025-11-17 | Completed GRAPH-ENG-0001; README and implementation_plan now reference SPRINT_0141_0001_0001_graph_indexer.md. | Module Team |
| 2025-11-17 | Normalised sprint to standard template; renamed from SPRINT_321_docs_modules_graph.md. | Docs |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
| 2025-11-22 | PREP-GRAPH-OPS-0001 done; moved GRAPH-OPS-0001 to TODO pending next demo outputs. | Project Mgmt |
## Decisions & Risks
- Cross-links blocked on DOCS-GRAPH-24-003; track before marking GRAPH-DOCS-0002 done.

View File

@@ -20,11 +20,11 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SAMPLES-LNM-22-001-WAITING-ON-FINALIZED | DONE (2025-11-20) | Due 2025-11-26 · Accountable: Samples Guild · Concelier Guild | Samples Guild · Concelier Guild | Prep artefact published at `docs/samples/linkset/prep-22-001.md` (fixtures plan aligned to frozen LNM schema; deterministic seeds/checksums). |
| P2 | PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT | DOING (2025-11-20) | Due 2025-11-26 · Accountable: Samples Guild · Excititor Guild | Samples Guild · Excititor Guild | Depends on 22-001 outputs; will build Excititor observation/VEX linkset fixtures once P1 samples land. Prep doc will extend `docs/samples/linkset/prep-22-001.md` with Excititor-specific payloads. |
| P2 | PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT | DONE (2025-11-22) | Due 2025-11-26 · Accountable: Samples Guild · Excititor Guild | Samples Guild · Excititor Guild | Depends on 22-001 outputs; will build Excititor observation/VEX linkset fixtures once P1 samples land. Prep doc will extend `docs/samples/linkset/prep-22-001.md` with Excititor-specific payloads. |
| 1 | SAMPLES-GRAPH-24-003 | BLOCKED | Await Graph overlay format decision + mock SBOM cache availability | Samples Guild · SBOM Service Guild | Generate large-scale SBOM graph fixture (~40k nodes) with policy overlay snapshot for perf/regression suites. |
| 2 | SAMPLES-GRAPH-24-004 | TODO | Blocked on 24-003 fixture availability | Samples Guild · UI Guild | Create vulnerability explorer JSON/CSV fixtures capturing conflicting evidence and policy outputs for UI/CLI automated tests. |
| 3 | SAMPLES-LNM-22-001 | BLOCKED | PREP-SAMPLES-LNM-22-001-WAITING-ON-FINALIZED | Samples Guild · Concelier Guild | Create advisory observation/linkset fixtures (NVD, GHSA, OSV disagreements) for API/CLI/UI tests with documented conflicts. |
| 4 | SAMPLES-LNM-22-002 | BLOCKED | PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT | Samples Guild · Excititor Guild | Produce VEX observation/linkset fixtures demonstrating status conflicts and path relevance; include raw blobs. |
| 3 | SAMPLES-LNM-22-001 | TODO | PREP-SAMPLES-LNM-22-001-WAITING-ON-FINALIZED | Samples Guild · Concelier Guild | Create advisory observation/linkset fixtures (NVD, GHSA, OSV disagreements) for API/CLI/UI tests with documented conflicts. |
| 4 | SAMPLES-LNM-22-002 | TODO | PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT | Samples Guild · Excititor Guild | Produce VEX observation/linkset fixtures demonstrating status conflicts and path relevance; include raw blobs. |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -33,10 +33,12 @@
| 2025-11-20 | Started PREP-SAMPLES-LNM-22-002 (dependent on 22-001); status set to DOING. | Planning |
| 2025-11-19 | Normalized PREP-SAMPLES-LNM-22-001 Task ID (removed trailing hyphen) for dependency tracking. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-22 | PREP extended for Excititor fixtures; moved SAMPLES-LNM-22-001 and SAMPLES-LNM-22-002 to TODO. | Project Mgmt |
| 2025-11-18 | Drafted fixture plan (`samples/graph/fixtures-plan.md`) outlining contents, assumptions, and blockers for SAMPLES-GRAPH-24-003. | Samples |
| 2025-11-18 | Kicked off SAMPLES-GRAPH-24-003 (overlay format + mock bundle sources); other tasks unchanged. | Samples |
| 2025-11-18 | Normalised sprint to standard template; renamed from SPRINT_509_samples.md. | Ops/Docs |
| 2025-11-19 | Marked SAMPLES-GRAPH-24-003 BLOCKED pending Graph overlay format decision and mock SBOM cache availability. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Linkset fixtures blocked by Concelier/Excititor schema finalization; revisit once schemas freeze.

View File

@@ -1,103 +1,104 @@
# Sprint 110 · Ingestion & Evidence
## Topic & Scope
- Finalise Advisory AI guardrail evidence (docs, SBOM feeds, policy knobs) while keeping customer rollout unblocked.
- Land Concelier structured caching + telemetry so Link-Not-Merge schemas can feed downstream consoles, air-gap bundles, and attestations.
- Prepare Excititor chunk API, telemetry, and attestation contracts for deterministic VEX evidence delivery.
- Staff and kick off the Mirror assembler so deterministic bundles, DSSE/TUF metadata, and CLI/Export Center automation can start.
## Dependencies & Concurrency
- Upstream: Sprint 100.A (Attestor) must remain green; Excititor/Concelier depend on Link-Not-Merge schema set (`CONCELIER-LNM-21-*`, `CARTO-GRAPH-21-002`). Advisory AI docs require SBOM/CLI/Policy/DevOps deliverables (`SBOM-AIAI-31-001`, `CLI-VULN-29-001`, `CLI-VEX-30-001`, `POLICY-ENGINE-31-001`, `DEVOPS-AIAI-31-001`).
- Sprint 110 peers (111119 range) stay independent; no intra-decade dependencies are permitted.
- Evidence Locker contract and Mirror staffing decisions affect Excititor attestation work and Mirror tracks respectively.
## Documentation Prerequisites
- `docs/modules/advisory-ai/architecture.md`
- `docs/modules/concelier/architecture.md`
- `docs/modules/excititor/architecture.md`
- `docs/modules/export-center/architecture.md`
- `docs/modules/airgap/architecture.md` (timeline + bundle requirements)
## Task Board
| Wave | Task ID | Status | Owner(s) | Dependencies | Notes |
| --- | --- | --- | --- | --- | --- |
| 110.B Concelier | PREP-LNM-SCHEMA-APPROVAL | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Concelier Core · Cartographer Guild · SBOM Service Guild | — | Approve Link-Not-Merge schema plus fixtures (`CONCELIER-GRAPH-21-001/002`, `CARTO-GRAPH-21-002`) and publish canonical JSON samples + precedence rules for consuming modules. <br><br>Archive decision + artefacts under `docs/modules/concelier/link-not-merge-schema.md` so downstream Concelier/Excititor/Policy tasks can bind to the frozen payload shape. |
| 110.B Concelier | PREP-EVIDENCE-LOCKER-CONTRACT | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Evidence Locker Guild · Concelier Core Guild | — | Freeze the Evidence Locker attestation scope + ingest contract (bundle predicates, transparency metadata, verification plan) and record DOI/location for Evidence Bundle v1. <br><br>Publish the signed decision in `docs/modules/evidence-locker/attestation-contract.md` and note required claim set plus validation fixtures. |
| 110.B Concelier | PREP-FEEDCONN-ICS-KISA-PLAN | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Concelier Feed Owners · Product Advisory Guild | — | Provide remediation/refresh schedule and schema notes for ICSCISA/KISA feeds, covering provenance gaps and upcoming advisory drops. <br><br>Store the runbook in `docs/modules/concelier/feeds/icscisa-kisa.md` with owners and next review date so connector work can proceed deterministically. |
| 110.C Excititor | PREP-EXCITITOR-ATTESTATION-PLAN | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Excititor Guild · Evidence Locker Guild | — | Align Excititor chunk/attestation plans with Evidence Locker scope: spell out ingestion contract, chunk schema, and DSSE bundling rules. <br><br>Publish the plan in `docs/modules/excititor/attestation-plan.md` and include sample payloads for `/vex/evidence/chunks` + attestation APIs. |
| 110.D Mirror | PREP-MIRROR-STAFFING | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Mirror Creator Guild · Exporter Guild · AirGap Time Guild | — | Assign owner(s) for MIRROR-CRT-56-001, confirm DSSE/TUF milestone schedule, and record staffing commitments for follow-on CRT tasks. <br><br>Document the staffing decision and milestone plan in `docs/modules/mirror/assembler.md` so downstream automation (Export Center, AirGap Time, CLI) can execute. |
| 110.A Advisory AI | DOCS-AIAI-31-004 | DOING | Docs Guild · Console Guild | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-001/003 | Guardrail console doc drafted; screenshots + SBOM evidence pending. |
| 110.A Advisory AI | AIAI-31-009 | DONE (2025-11-12) | Advisory AI Guild | — | Regression suite + `AdvisoryAI:Guardrails` config landed with perf budgets. |
| 110.A Advisory AI | AIAI-31-008 | TODO | Advisory AI Guild | AIAI-31-006 (DONE 2025-11-04); AIAI-31-007 (DONE 2025-11-06) | Policy knob work landed; proceed with packaging and deployment steps. |
| 110.A Advisory AI | SBOM-AIAI-31-003 | BLOCKED | SBOM Service Guild | SBOM-AIAI-31-001; CLI-VULN-29-001; CLI-VEX-30-001 | Needs SBOM delta kit + CLI deliverables before validation can proceed. |
| 110.A Advisory AI | DOCS-AIAI-31-005/006/008/009 | BLOCKED | Docs Guild | DOCS-AIAI-31-004; CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001; DEVOPS-AIAI-31-001 | CLI/policy/ops docs paused pending upstream artefacts. |
| 110.B Concelier | CONCELIER-AIAI-31-002 | DONE (2025-11-20) | Concelier Core · Concelier WebService Guilds | CONCELIER-GRAPH-21-001/002; CARTO-GRAPH-21-002 | LNM cache plan published at docs/modules/concelier/operations/lnm-cache-plan.md aligned to frozen schema. |
| 110.B Concelier | CONCELIER-AIAI-31-003 | DONE (2025-11-12) | Concelier Observability Guild | — | Telemetry counters/histograms live for Advisory AI dashboards. |
| 110.B Concelier | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | Concelier Core · AirGap Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until schema approval + attestation scope sign-off. |
| 110.B Concelier | CONCELIER-CONSOLE-23-001..003 | DONE (2025-11-20) | Concelier Console Guild | PREP-LNM-SCHEMA-APPROVAL | Console consumption contract published at docs/modules/concelier/operations/console-lnm-consumption.md. |
| 110.B Concelier | CONCELIER-ATTEST-73-001/002 | BLOCKED | Concelier Core · Evidence Locker Guild | CONCELIER-AIAI-31-002; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until structured caching lands and Evidence Locker contract finalises. |
| 110.B Concelier | FEEDCONN-ICSCISA-02-012 / FEEDCONN-KISA-02-008 | BLOCKED | Concelier Feed Owners | PREP-FEEDCONN-ICS-KISA-PLAN | Overdue provenance refreshes require schedule from feed owners. |
| 110.C Excititor | EXCITITOR-AIAI-31-001 | DONE (2025-11-09) | Excititor Web/Core Guilds | — | Normalised VEX justification projections shipped. |
| 110.C Excititor | EXCITITOR-AIAI-31-002 | DONE (2025-11-20) | Excititor Web/Core Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EVIDENCE-LOCKER-CONTRACT | Chunk ingestion API spec published (schemas/vex-chunk-api.yaml) aligned with attestation plan. |
| 110.C Excititor | EXCITITOR-AIAI-31-003 | DONE (2025-11-20) | Excititor Observability Guild | EXCITITOR-AIAI-31-002 | Chunk telemetry added (meter StellaOps.Excititor.Chunks) and wired in /v1/vex/evidence/chunks handler. |
| 110.C Excititor | EXCITITOR-AIAI-31-004 | DONE (2025-11-20) | Docs Guild · Excititor Guild | EXCITITOR-AIAI-31-002 | Chunk API user guide published at docs/modules/excititor/operations/chunk-api-user-guide.md. |
| 110.C Excititor | EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 | DONE (2025-11-20) | Excititor Guild · Evidence Locker Guild | EXCITITOR-AIAI-31-002; PREP-EVIDENCE-LOCKER-CONTRACT | Attestation verify endpoint wired to Evidence Locker contract (`/v1/attestations/verify`), leveraging attestation verifier + telemetry. |
| 110.C Excititor | EXCITITOR-AIRGAP-56/57/58 · EXCITITOR-CONN-TRUST-01-001 | BLOCKED | Excititor Guild · AirGap Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EXCITITOR-ATTESTATION-PLAN | Blocked until schema + attestation readiness. |
| 110.D Mirror | MIRROR-CRT-56-001 | BLOCKED | Mirror Creator Guild | PREP-MIRROR-STAFFING | Blocked: no owner assigned; kickoff slipped past 2025-11-15. |
| 110.D Mirror | MIRROR-CRT-56-002 | BLOCKED | Mirror Creator · Security Guilds | MIRROR-CRT-56-001; PROV-OBS-53-001 | Blocked until MIRROR-CRT-56-001 staffed. |
| 110.D Mirror | MIRROR-CRT-57-001/002 | BLOCKED | Mirror Creator Guild · AirGap Time Guild | MIRROR-CRT-56-001; AIRGAP-TIME-57-001 | Blocked; upstream staffing unresolved. |
| 110.D Mirror | MIRROR-CRT-58-001/002 | BLOCKED | Mirror Creator Guild · CLI Guild · Exporter Guild | MIRROR-CRT-56-001; EXPORT-OBS-54-001; CLI-AIRGAP-56-001 | Blocked until assembler staffed and upstream contracts agreed. |
| 110.D Mirror | EXPORT-OBS-51-001 / 54-001 · AIRGAP-TIME-57-001 · CLI-AIRGAP-56-001 · PROV-OBS-53-001 | BLOCKED | Exporter Guild · AirGap Time Guild · CLI Guild | PREP-MIRROR-STAFFING | Blocked pending MIRROR-CRT-56-001 ownership. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Concelier WebService tests could not run locally (Mongo2Go requires libcrypto.so.1.1). Endpoint compiled; rerun tests once OpenSSL 1.1 shim available. | Implementer |
| 2025-11-20 | CONCELIER-CONSOLE-23-001..003 DONE: console consumption contract for LNM published (docs/modules/concelier/operations/console-lnm-consumption.md). | Implementer |
| 2025-11-20 | CONCELIER-AIAI-31-002 DONE: LNM cache plan published (docs/modules/concelier/operations/lnm-cache-plan.md) using frozen schema + Evidence Locker contract. | Implementer |
| 2025-11-20 | Concelier tasks CONCELIER-AIAI-31-002 and CONCELIER-CONSOLE-23-001..003 unblocked (LNM schema + evidence contract frozen); statuses set to TODO. | Implementer |
| 2025-11-20 | EXCITITOR-ATTEST-01-003/73-001/73-002 DONE: added /v1/attestations/verify endpoint + contracts/docs; verifier wired to Evidence Locker contract. | Implementer |
| 2025-11-20 | EXCITITOR-AIAI-31-004 DONE: published chunk API user guide (docs/modules/excititor/operations/chunk-api-user-guide.md). | Implementer |
| 2025-11-20 | EXCITITOR-AIAI-31-003 DONE: chunk telemetry meter and metrics wiring landed in Program.cs; ops note at docs/modules/excititor/operations/chunk-telemetry.md. | Implementer |
| 2025-11-20 | Marked EXCITITOR-AIAI-31-002 DONE; chunk API OpenAPI spec added at docs/modules/excititor/schemas/vex-chunk-api.yaml. | Implementer |
| 2025-11-20 | EXCITITOR-AIAI-31-002 unblocked (prep complete); starting chunk API spec + schema under docs/modules/excititor/schemas. | Implementer |
| 2025-11-20 | PREP-MIRROR-STAFFING completed; staffing/milestones recorded at docs/modules/mirror/assembler.md. | Implementer |
| 2025-11-20 | PREP-EXCITITOR-ATTESTATION-PLAN completed; plan at docs/modules/excititor/attestation-plan.md. | Implementer |
| 2025-11-20 | PREP-FEEDCONN-ICS-KISA-PLAN completed; remediation plan lives at docs/modules/concelier/feeds/icscisa-kisa.md (v0.1). | Implementer |
| 2025-11-20 | PREP-EVIDENCE-LOCKER-CONTRACT completed; contract published at docs/modules/evidence-locker/attestation-contract.md. | Implementer |
| 2025-11-20 | PREP-LNM-SCHEMA-APPROVAL completed; schema frozen in docs/modules/concelier/link-not-merge-schema.md; samples in docs/samples/lnm/*.json. | Implementer |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-13 | Refreshed wave tracker, decisions, and contingency plan ahead of 1415 Nov checkpoints; outstanding asks: SBOM/CLI/Policy/DevOps ETAs, Link-Not-Merge approval, Mirror staffing. | Sprint 110 leads |
| 2025-11-09 | Captured initial wave scope, interlocks, and risks covering SBOM/CLI/Policy/DevOps artefacts, Link-Not-Merge schemas, Excititor justification backlog, and Mirror assembler commitments. | Sprint 110 leads |
| 2025-11-16 | Updated task board: marked Advisory AI packaging, Concelier air-gap/console/attestation tracks, Excititor chunk/attestation/air-gap tracks, and all Mirror tracks as BLOCKED pending schema approvals, Evidence Locker contract, and Mirror staffing decisions. | Implementer |
| 2025-11-16 | Marked CONCELIER-AIAI-31-002 BLOCKED (waiting on Link-Not-Merge schema approval); progressed DOCS-AIAI-31-004 doc draft. | Implementer |
## Decisions & Risks
### Decisions in flight
| Decision | Blocking work | Accountable owner(s) | Due date |
| --- | --- | --- | --- |
| Confirm SBOM/CLI/Policy/DevOps delivery dates | DOCS-AIAI backlog, SBOM-AIAI-31-003, AIAI-31-008 | SBOM Service · CLI · Policy · DevOps guild leads | 2025-11-14 |
| Approve Link-Not-Merge schema (CONCELIER-GRAPH-21-001/002, CARTO-GRAPH-21-002) | CONCELIER-AIAI-31-002, EXCITITOR-AIAI-31-002/003/004, air-gap + attestation tasks | Concelier Core · Cartographer Guild · SBOM Service Guild | 2025-11-14 |
| Assign MIRROR-CRT-56-001 owner | Entire Mirror wave + Export Center + AirGap Time automation | Mirror Creator Guild · Exporter Guild · AirGap Time Guild | 2025-11-15 |
| Evidence Locker attestation scope sign-off | EXCITITOR-ATTEST-01-003/73-001/73-002; CONCELIER-ATTEST-73-001/002 | Evidence Locker Guild · Excititor Guild · Concelier Guild | 2025-11-15 |
| Approve DOCS-AIAI-31-004 screenshot plan | Publication of console guardrail doc | Docs Guild · Console Guild | 2025-11-15 |
### Risk outlook (2025-11-13)
| Risk | Impact | Mitigation / owner |
| --- | --- | --- |
| SBOM/CLI/Policy/DevOps artefacts slip past 14 Nov | Advisory AI docs + SBOM feeds stay blocked, delaying customer rollout & dependent sprints. | Lock ETAs during 14 Nov interlock; escalate to Advisory AI leadership if commitments slip. |
| Link-Not-Merge schema approval delayed | Concelier/Excititor APIs, console overlays, and air-gap bundles remain gated. | Close 14 Nov review with migration notes; unblock tasks immediately after approval. |
| Excititor attestation backlog stalls | VEX evidence + air-gap parity cannot progress; Mirror support drifts. | Use 15 Nov sequencing session to lock order, reserve engineering capacity. |
| MIRROR-CRT-56-001 remains unstaffed | DSSE/TUF, OCI/time-anchor, CLI, Export Center automation cannot start (Sprint 125 slips). | Assign owner at kickoff; reallocate Export/AirGap engineers if needed. |
| Connector refreshes (ICSCISA/KISA) remain overdue | Advisory AI may serve stale advisories; telemetry accuracy suffers. | Feed owners to publish remediation plan + interim mitigations by 15 Nov stand-up. |
## Next Checkpoints
| Date (UTC) | Session | Goal | Impacted wave(s) | Prep owner(s) |
| --- | --- | --- | --- | --- |
| 2025-11-14 | Advisory AI customer surfaces follow-up | Capture SBOM/CLI/Policy/DevOps ETAs to restart DOCS/SBOM work. | 110.A | Advisory AI · SBOM · CLI · Policy · DevOps guild leads |
| 2025-11-14 | Link-Not-Merge schema review | Approve schema payloads + migration notes. | 110.B · 110.C | Concelier Core · Cartographer Guild · SBOM Service Guild |
| 2025-11-15 | Excititor attestation sequencing | Lock Evidence Locker contract + backlog order. | 110.C | Excititor Web/Core · Evidence Locker Guild |
| 2025-11-15 | Mirror evidence kickoff | Assign MIRROR-CRT-56-001 owner, confirm staffing, outline DSSE/TUF + OCI milestones. | 110.D | Mirror Creator · Exporter · AirGap Time · Security guilds |
## Appendix
- Detailed coordination artefacts, contingency playbook, and historical notes previously held in this sprint now live at `docs/implplan/archived/SPRINT_110_ingestion_evidence_2025-11-13.md`.
# Sprint 110 · Ingestion & Evidence
## Topic & Scope
- Finalise Advisory AI guardrail evidence (docs, SBOM feeds, policy knobs) while keeping customer rollout unblocked.
- Land Concelier structured caching + telemetry so Link-Not-Merge schemas can feed downstream consoles, air-gap bundles, and attestations.
- Prepare Excititor chunk API, telemetry, and attestation contracts for deterministic VEX evidence delivery.
- Staff and kick off the Mirror assembler so deterministic bundles, DSSE/TUF metadata, and CLI/Export Center automation can start.
## Dependencies & Concurrency
- Upstream: Sprint 100.A (Attestor) must remain green; Excititor/Concelier depend on Link-Not-Merge schema set (`CONCELIER-LNM-21-*`, `CARTO-GRAPH-21-002`). Advisory AI docs require SBOM/CLI/Policy/DevOps deliverables (`SBOM-AIAI-31-001`, `CLI-VULN-29-001`, `CLI-VEX-30-001`, `POLICY-ENGINE-31-001`, `DEVOPS-AIAI-31-001`).
- Sprint 110 peers (111119 range) stay independent; no intra-decade dependencies are permitted.
- Evidence Locker contract and Mirror staffing decisions affect Excititor attestation work and Mirror tracks respectively.
## Documentation Prerequisites
- `docs/modules/advisory-ai/architecture.md`
- `docs/modules/concelier/architecture.md`
- `docs/modules/excititor/architecture.md`
- `docs/modules/export-center/architecture.md`
- `docs/modules/airgap/architecture.md` (timeline + bundle requirements)
## Task Board
| Wave | Task ID | Status | Owner(s) | Dependencies | Notes |
| --- | --- | --- | --- | --- | --- |
| 110.B Concelier | PREP-LNM-SCHEMA-APPROVAL | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Concelier Core · Cartographer Guild · SBOM Service Guild | — | Approve Link-Not-Merge schema plus fixtures (`CONCELIER-GRAPH-21-001/002`, `CARTO-GRAPH-21-002`) and publish canonical JSON samples + precedence rules for consuming modules. <br><br>Archive decision + artefacts under `docs/modules/concelier/link-not-merge-schema.md` so downstream Concelier/Excititor/Policy tasks can bind to the frozen payload shape. |
| 110.B Concelier | PREP-EVIDENCE-LOCKER-CONTRACT | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Evidence Locker Guild · Concelier Core Guild | — | Freeze the Evidence Locker attestation scope + ingest contract (bundle predicates, transparency metadata, verification plan) and record DOI/location for Evidence Bundle v1. <br><br>Publish the signed decision in `docs/modules/evidence-locker/attestation-contract.md` and note required claim set plus validation fixtures. |
| 110.B Concelier | PREP-FEEDCONN-ICS-KISA-PLAN | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Concelier Feed Owners · Product Advisory Guild | — | Provide remediation/refresh schedule and schema notes for ICSCISA/KISA feeds, covering provenance gaps and upcoming advisory drops. <br><br>Store the runbook in `docs/modules/concelier/feeds/icscisa-kisa.md` with owners and next review date so connector work can proceed deterministically. |
| 110.C Excititor | PREP-EXCITITOR-ATTESTATION-PLAN | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Excititor Guild · Evidence Locker Guild | — | Align Excititor chunk/attestation plans with Evidence Locker scope: spell out ingestion contract, chunk schema, and DSSE bundling rules. <br><br>Publish the plan in `docs/modules/excititor/attestation-plan.md` and include sample payloads for `/vex/evidence/chunks` + attestation APIs. |
| 110.D Mirror | PREP-MIRROR-STAFFING | DONE (2025-11-20) | Due 2025-11-21 · Accountable: —; Mirror Creator Guild · Exporter Guild · AirGap Time Guild | — | Assign owner(s) for MIRROR-CRT-56-001, confirm DSSE/TUF milestone schedule, and record staffing commitments for follow-on CRT tasks. <br><br>Document the staffing decision and milestone plan in `docs/modules/mirror/assembler.md` so downstream automation (Export Center, AirGap Time, CLI) can execute. |
| 110.A Advisory AI | DOCS-AIAI-31-004 | DOING | Docs Guild · Console Guild | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-001/003 | Guardrail console doc drafted; screenshots + SBOM evidence pending. |
| 110.A Advisory AI | AIAI-31-009 | DONE (2025-11-12) | Advisory AI Guild | — | Regression suite + `AdvisoryAI:Guardrails` config landed with perf budgets. |
| 110.A Advisory AI | AIAI-31-008 | TODO | Advisory AI Guild | AIAI-31-006 (DONE 2025-11-04); AIAI-31-007 (DONE 2025-11-06) | Policy knob work landed; proceed with packaging and deployment steps. |
| 110.A Advisory AI | SBOM-AIAI-31-003 | BLOCKED | SBOM Service Guild | SBOM-AIAI-31-001; CLI-VULN-29-001; CLI-VEX-30-001 | Needs SBOM delta kit + CLI deliverables before validation can proceed. |
| 110.A Advisory AI | DOCS-AIAI-31-005/006/008/009 | BLOCKED | Docs Guild | DOCS-AIAI-31-004; CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001; DEVOPS-AIAI-31-001 | CLI/policy/ops docs paused pending upstream artefacts. |
| 110.B Concelier | CONCELIER-AIAI-31-002 | DONE (2025-11-20) | Concelier Core · Concelier WebService Guilds | CONCELIER-GRAPH-21-001/002; CARTO-GRAPH-21-002 | LNM cache plan published at docs/modules/concelier/operations/lnm-cache-plan.md aligned to frozen schema. |
| 110.B Concelier | CONCELIER-AIAI-31-003 | DONE (2025-11-12) | Concelier Observability Guild | — | Telemetry counters/histograms live for Advisory AI dashboards. |
| 110.B Concelier | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | Concelier Core · AirGap Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until schema approval + attestation scope sign-off. |
| 110.B Concelier | CONCELIER-CONSOLE-23-001..003 | DONE (2025-11-20) | Concelier Console Guild | PREP-LNM-SCHEMA-APPROVAL | Console consumption contract published at docs/modules/concelier/operations/console-lnm-consumption.md. |
| 110.B Concelier | CONCELIER-ATTEST-73-001/002 | BLOCKED | Concelier Core · Evidence Locker Guild | CONCELIER-AIAI-31-002; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until structured caching lands and Evidence Locker contract finalises. |
| 110.B Concelier | FEEDCONN-ICSCISA-02-012 / FEEDCONN-KISA-02-008 | BLOCKED | Concelier Feed Owners | PREP-FEEDCONN-ICS-KISA-PLAN | Overdue provenance refreshes require schedule from feed owners. |
| 110.C Excititor | EXCITITOR-AIAI-31-001 | DONE (2025-11-09) | Excititor Web/Core Guilds | — | Normalised VEX justification projections shipped. |
| 110.C Excititor | EXCITITOR-AIAI-31-002 | DONE (2025-11-20) | Excititor Web/Core Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EVIDENCE-LOCKER-CONTRACT | Chunk ingestion API spec published (schemas/vex-chunk-api.yaml) aligned with attestation plan. |
| 110.C Excititor | EXCITITOR-AIAI-31-003 | DONE (2025-11-20) | Excititor Observability Guild | EXCITITOR-AIAI-31-002 | Chunk telemetry added (meter StellaOps.Excititor.Chunks) and wired in /v1/vex/evidence/chunks handler. |
| 110.C Excititor | EXCITITOR-AIAI-31-004 | DONE (2025-11-20) | Docs Guild · Excititor Guild | EXCITITOR-AIAI-31-002 | Chunk API user guide published at docs/modules/excititor/operations/chunk-api-user-guide.md. |
| 110.C Excititor | EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 | DONE (2025-11-20) | Excititor Guild · Evidence Locker Guild | EXCITITOR-AIAI-31-002; PREP-EVIDENCE-LOCKER-CONTRACT | Attestation verify endpoint wired to Evidence Locker contract (`/v1/attestations/verify`), leveraging attestation verifier + telemetry. |
| 110.C Excititor | EXCITITOR-AIRGAP-56/57/58 · EXCITITOR-CONN-TRUST-01-001 | BLOCKED | Excititor Guild · AirGap Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EXCITITOR-ATTESTATION-PLAN | Blocked until schema + attestation readiness. |
| 110.D Mirror | MIRROR-CRT-56-001 | BLOCKED | Mirror Creator Guild | PREP-MIRROR-STAFFING | Blocked: no owner assigned; kickoff slipped past 2025-11-15. |
| 110.D Mirror | MIRROR-CRT-56-002 | BLOCKED | Mirror Creator · Security Guilds | MIRROR-CRT-56-001; PROV-OBS-53-001 | Blocked until MIRROR-CRT-56-001 staffed. |
| 110.D Mirror | MIRROR-CRT-57-001/002 | BLOCKED | Mirror Creator Guild · AirGap Time Guild | MIRROR-CRT-56-001; AIRGAP-TIME-57-001 | Blocked; upstream staffing unresolved. |
| 110.D Mirror | MIRROR-CRT-58-001/002 | BLOCKED | Mirror Creator Guild · CLI Guild · Exporter Guild | MIRROR-CRT-56-001; EXPORT-OBS-54-001; CLI-AIRGAP-56-001 | Blocked until assembler staffed and upstream contracts agreed. |
| 110.D Mirror | EXPORT-OBS-51-001 / 54-001 · AIRGAP-TIME-57-001 · CLI-AIRGAP-56-001 · PROV-OBS-53-001 | BLOCKED | Exporter Guild · AirGap Time Guild · CLI Guild | PREP-MIRROR-STAFFING | Blocked pending MIRROR-CRT-56-001 ownership. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-20 | Concelier WebService tests could not run locally (Mongo2Go requires libcrypto.so.1.1). Endpoint compiled; rerun tests once OpenSSL 1.1 shim available. | Implementer |
| 2025-11-20 | CONCELIER-CONSOLE-23-001..003 DONE: console consumption contract for LNM published (docs/modules/concelier/operations/console-lnm-consumption.md). | Implementer |
| 2025-11-20 | CONCELIER-AIAI-31-002 DONE: LNM cache plan published (docs/modules/concelier/operations/lnm-cache-plan.md) using frozen schema + Evidence Locker contract. | Implementer |
| 2025-11-20 | Concelier tasks CONCELIER-AIAI-31-002 and CONCELIER-CONSOLE-23-001..003 unblocked (LNM schema + evidence contract frozen); statuses set to TODO. | Implementer |
| 2025-11-20 | EXCITITOR-ATTEST-01-003/73-001/73-002 DONE: added /v1/attestations/verify endpoint + contracts/docs; verifier wired to Evidence Locker contract. | Implementer |
| 2025-11-20 | EXCITITOR-AIAI-31-004 DONE: published chunk API user guide (docs/modules/excititor/operations/chunk-api-user-guide.md). | Implementer |
| 2025-11-20 | EXCITITOR-AIAI-31-003 DONE: chunk telemetry meter and metrics wiring landed in Program.cs; ops note at docs/modules/excititor/operations/chunk-telemetry.md. | Implementer |
| 2025-11-20 | Marked EXCITITOR-AIAI-31-002 DONE; chunk API OpenAPI spec added at docs/modules/excititor/schemas/vex-chunk-api.yaml. | Implementer |
| 2025-11-20 | EXCITITOR-AIAI-31-002 unblocked (prep complete); starting chunk API spec + schema under docs/modules/excititor/schemas. | Implementer |
| 2025-11-20 | PREP-MIRROR-STAFFING completed; staffing/milestones recorded at docs/modules/mirror/assembler.md. | DONE (2025-11-22) |
| 2025-11-20 | PREP-EXCITITOR-ATTESTATION-PLAN completed; plan at docs/modules/excititor/attestation-plan.md. | DONE (2025-11-22) |
| 2025-11-20 | PREP-FEEDCONN-ICS-KISA-PLAN completed; remediation plan lives at docs/modules/concelier/feeds/icscisa-kisa.md (v0.1). | DONE (2025-11-22) |
| 2025-11-20 | PREP-EVIDENCE-LOCKER-CONTRACT completed; contract published at docs/modules/evidence-locker/attestation-contract.md. | DONE (2025-11-22) |
| 2025-11-20 | PREP-LNM-SCHEMA-APPROVAL completed; schema frozen in docs/modules/concelier/link-not-merge-schema.md; samples in docs/samples/lnm/*.json. | DONE (2025-11-22) |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-13 | Refreshed wave tracker, decisions, and contingency plan ahead of 1415 Nov checkpoints; outstanding asks: SBOM/CLI/Policy/DevOps ETAs, Link-Not-Merge approval, Mirror staffing. | Sprint 110 leads |
| 2025-11-09 | Captured initial wave scope, interlocks, and risks covering SBOM/CLI/Policy/DevOps artefacts, Link-Not-Merge schemas, Excititor justification backlog, and Mirror assembler commitments. | Sprint 110 leads |
| 2025-11-16 | Updated task board: marked Advisory AI packaging, Concelier air-gap/console/attestation tracks, Excititor chunk/attestation/air-gap tracks, and all Mirror tracks as BLOCKED pending schema approvals, Evidence Locker contract, and Mirror staffing decisions. | Implementer |
| 2025-11-16 | Marked CONCELIER-AIAI-31-002 BLOCKED (waiting on Link-Not-Merge schema approval); progressed DOCS-AIAI-31-004 doc draft. | Implementer |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
### Decisions in flight
| Decision | Blocking work | Accountable owner(s) | Due date |
| --- | --- | --- | --- |
| Confirm SBOM/CLI/Policy/DevOps delivery dates | DOCS-AIAI backlog, SBOM-AIAI-31-003, AIAI-31-008 | SBOM Service · CLI · Policy · DevOps guild leads | 2025-11-14 |
| Approve Link-Not-Merge schema (CONCELIER-GRAPH-21-001/002, CARTO-GRAPH-21-002) | CONCELIER-AIAI-31-002, EXCITITOR-AIAI-31-002/003/004, air-gap + attestation tasks | Concelier Core · Cartographer Guild · SBOM Service Guild | 2025-11-14 |
| Assign MIRROR-CRT-56-001 owner | Entire Mirror wave + Export Center + AirGap Time automation | Mirror Creator Guild · Exporter Guild · AirGap Time Guild | 2025-11-15 |
| Evidence Locker attestation scope sign-off | EXCITITOR-ATTEST-01-003/73-001/73-002; CONCELIER-ATTEST-73-001/002 | Evidence Locker Guild · Excititor Guild · Concelier Guild | 2025-11-15 |
| Approve DOCS-AIAI-31-004 screenshot plan | Publication of console guardrail doc | Docs Guild · Console Guild | 2025-11-15 |
### Risk outlook (2025-11-13)
| Risk | Impact | Mitigation / owner |
| --- | --- | --- |
| SBOM/CLI/Policy/DevOps artefacts slip past 14 Nov | Advisory AI docs + SBOM feeds stay blocked, delaying customer rollout & dependent sprints. | Lock ETAs during 14 Nov interlock; escalate to Advisory AI leadership if commitments slip. |
| Link-Not-Merge schema approval delayed | Concelier/Excititor APIs, console overlays, and air-gap bundles remain gated. | Close 14 Nov review with migration notes; unblock tasks immediately after approval. |
| Excititor attestation backlog stalls | VEX evidence + air-gap parity cannot progress; Mirror support drifts. | Use 15 Nov sequencing session to lock order, reserve engineering capacity. |
| MIRROR-CRT-56-001 remains unstaffed | DSSE/TUF, OCI/time-anchor, CLI, Export Center automation cannot start (Sprint 125 slips). | Assign owner at kickoff; reallocate Export/AirGap engineers if needed. |
| Connector refreshes (ICSCISA/KISA) remain overdue | Advisory AI may serve stale advisories; telemetry accuracy suffers. | Feed owners to publish remediation plan + interim mitigations by 15 Nov stand-up. |
## Next Checkpoints
| Date (UTC) | Session | Goal | Impacted wave(s) | Prep owner(s) |
| --- | --- | --- | --- | --- |
| 2025-11-14 | Advisory AI customer surfaces follow-up | Capture SBOM/CLI/Policy/DevOps ETAs to restart DOCS/SBOM work. | 110.A | Advisory AI · SBOM · CLI · Policy · DevOps guild leads |
| 2025-11-14 | Link-Not-Merge schema review | Approve schema payloads + migration notes. | 110.B · 110.C | Concelier Core · Cartographer Guild · SBOM Service Guild |
| 2025-11-15 | Excititor attestation sequencing | Lock Evidence Locker contract + backlog order. | 110.C | Excititor Web/Core · Evidence Locker Guild |
| 2025-11-15 | Mirror evidence kickoff | Assign MIRROR-CRT-56-001 owner, confirm staffing, outline DSSE/TUF + OCI milestones. | 110.D | Mirror Creator · Exporter · AirGap Time · Security guilds |
## Appendix
- Detailed coordination artefacts, contingency playbook, and historical notes previously held in this sprint now live at `docs/implplan/archived/SPRINT_110_ingestion_evidence_2025-11-13.md`.

View File

@@ -10,8 +10,8 @@ Focus: Policy & Reasoning focus on Policy (phase I).
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| P1 | PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | Missing export bundle contract/API surface and scheduler job spec for Console; requires agreed schema and job wiring. <br><br> Document artefact/deliverable for EXPORT-CONSOLE-23-001 and publish location so downstream tasks can proceed. |
| P2 | PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Mirror bundle schema for policy packs not published; need bundle_id/provenance fields and sealed-mode rules. <br><br> Document artefact/deliverable for POLICY-AIRGAP-56-001 and publish location so downstream tasks can proceed. |
| P1 | PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | Missing export bundle contract/API surface and scheduler job spec for Console; requires agreed schema and job wiring. <br><br> Document artefact/deliverable for EXPORT-CONSOLE-23-001 and publish location so downstream tasks can proceed. |
| P2 | PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Mirror bundle schema for policy packs not published; need bundle_id/provenance fields and sealed-mode rules. <br><br> Document artefact/deliverable for POLICY-AIRGAP-56-001 and publish location so downstream tasks can proceed. |
| P3 | PREP-POLICY-AIRGAP-56-002-DEPENDS-ON-56-001-B | DONE (2025-11-20) | Prep doc at `docs/modules/policy/prep/2025-11-20-policy-airgap-56-002-prep.md`; awaits schema hash from 56-001. | Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine | Depends on 56-001 bundle import schema and DSSE signing profile. <br><br> Document artefact/deliverable for POLICY-AIRGAP-56-002 and publish location so downstream tasks can proceed. |
| P4 | PREP-POLICY-AIRGAP-57-001-REQUIRES-SEALED-MOD | DONE (2025-11-20) | Prep doc at `docs/modules/policy/prep/2025-11-20-policy-airgap-57-001-prep.md`; depends on 56-002 + WEB-OAS-61-002 envelope. | Policy Guild, AirGap Policy Guild / src/Policy/StellaOps.Policy.Engine | Requires sealed-mode contract (egress rules, error codes) after 56-002. <br><br> Document artefact/deliverable for POLICY-AIRGAP-57-001 and publish location so downstream tasks can proceed. |
| P5 | PREP-POLICY-AIRGAP-57-002-NEEDS-STALENESS-FAL | DONE (2025-11-20) | Prep doc at `docs/modules/policy/prep/2025-11-20-policy-airgap-57-002-prep.md`; awaits staleness metadata inputs. | Policy Guild, AirGap Time Guild / src/Policy/StellaOps.Policy.Engine | Needs staleness/fallback data contract from 57-001. <br><br> Document artefact/deliverable for POLICY-AIRGAP-57-002 and publish location so downstream tasks can proceed. |
@@ -49,6 +49,7 @@ Focus: Policy & Reasoning focus on Policy (phase I).
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-08 | Sprint created; awaiting staffing. | Planning |
| 2025-11-18 | Attempted EXPORT-CONSOLE-23-001 but blocked: no export bundle/schema or scheduler job contract for Console; requires API + signed manifest format before implementation. Marked remaining tasks BLOCKED pending lint/airgap/attest/Console contracts. | Policy Guild |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
## Decisions & Risks
- Dependency on Sprint 110.A AdvisoryAI remains; ensure upstream stays stable while export surface is added.

View File

@@ -10,7 +10,7 @@ Focus: Policy & Reasoning focus on Policy (phase III).
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| P1 | PREP-POLICY-ENGINE-30-001-WAITING-ON-29-004-M | DOING (2025-11-20) | Due 2025-11-22 · Accountable: Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Waiting on 29-004 metrics/logging outputs to define overlay projection contract. <br><br> Document artefact/deliverable for POLICY-ENGINE-30-001 and publish location so downstream tasks can proceed. |
| P1 | PREP-POLICY-ENGINE-30-001-WAITING-ON-29-004-M | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Overlay projection contract published at `docs/modules/policy/prep/2025-11-22-policy-engine-30-001-prep.md`; downstream tasks may proceed. |
| P2 | PREP-POLICY-ENGINE-30-002-SIMULATION-BRIDGE-C | DONE (2025-11-20) | Prep note at `docs/modules/policy/prep/2025-11-20-simulation-bridge-prep.md`; awaits 30-001 overlay hash. | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Simulation bridge cannot proceed until 30-001 overlay schema lands. <br><br> Document artefact/deliverable for POLICY-ENGINE-30-002 and publish location so downstream tasks can proceed. |
| P3 | PREP-POLICY-ENGINE-30-003-CHANGE-EVENTS-DEPEN | DONE (2025-11-20) | Prep note at `docs/modules/policy/prep/2025-11-20-change-events-prep.md`; depends on 30-002 schema + Scheduler subjects. | Policy Guild, Scheduler Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Change events depend on simulation bridge (30-002) outputs. <br><br> Document artefact/deliverable for POLICY-ENGINE-30-003 and publish location so downstream tasks can proceed. |
| P4 | PREP-POLICY-ENGINE-30-101-TRUST-WEIGHTING-UI- | DONE (2025-11-20) | Prep note at `docs/modules/policy/prep/2025-11-20-trust-weighting-prep.md`; waits on 30-003 outputs. | Policy Guild / src/Policy/StellaOps.Policy.Engine | Trust weighting UI/API depends on change events + overlays (30-003). <br><br> Document artefact/deliverable for POLICY-ENGINE-30-101 and publish location so downstream tasks can proceed. |
@@ -53,4 +53,6 @@ Focus: Policy & Reasoning focus on Policy (phase III).
| 2025-11-20 | Published prep artefacts for PREP-POLICY-ENGINE-30-002/003/30-101/31-001 under `docs/modules/policy/prep/`; marked P2P5 DONE. | Implementer |
| 2025-11-20 | Published prep artefacts for PREP-POLICY-ENGINE-31-002/32-101/33-101/34-101/35-201 under `docs/modules/policy/prep/`; marked P6P10 DONE. | Implementer |
| 2025-11-20 | Published prep artefacts for PREP-POLICY-ENGINE-38-201/40-001/40-002 under `docs/modules/policy/prep/`; marked P11P13 DONE. | Implementer |
| 2025-11-22 | Overlay projection prep captured at `docs/modules/policy/prep/2025-11-22-policy-engine-30-001-prep.md`; set P1 to DONE. | Project Mgmt |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |

View File

@@ -7,26 +7,27 @@ Depends on: Sprint 150.A - Orchestrator
Summary: Notifications & Telemetry focus on Notifier (phase I).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
NOTIFY-ATTEST-74-001 | **DOING (2025-11-12)** | Create notification templates for verification failures, expiring attestations, key revocations, and transparency anomalies. | Notifications Service Guild, Attestor Service Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-ATTEST-74-001 | DONE (2025-11-16) | Create notification templates for verification failures, expiring attestations, key revocations, and transparency anomalies. | Notifications Service Guild, Attestor Service Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-ATTEST-74-002 | TODO | Wire notifications to key rotation/revocation events and transparency witness failures. Dependencies: NOTIFY-ATTEST-74-001. | Notifications Service Guild, KMS Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-61-001 | **DOING (2025-11-12)** | Update notifier OAS with rules, templates, incidents, quiet hours endpoints using standard error envelope and examples. | Notifications Service Guild, API Contracts Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-61-002 | TODO | Implement `/.well-known/openapi` discovery endpoint with scope metadata. Dependencies: NOTIFY-OAS-61-001. | Notifications Service Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-62-001 | TODO | Provide SDK usage examples for rule CRUD, incident ack, and quiet hours; ensure SDK smoke tests. Dependencies: NOTIFY-OAS-61-002. | Notifications Service Guild, SDK Generator Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-63-001 | TODO | Emit deprecation headers and Notifications templates for retiring notifier APIs. Dependencies: NOTIFY-OAS-62-001. | Notifications Service Guild, API Governance Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OBS-51-001 | TODO | Integrate SLO evaluator webhooks into Notifier rules (burn-rate breaches, health degradations) with templates, routing, and suppression logic. Provide sample policies and ensure imposed rule propagation. | Notifications Service Guild, Observability Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OBS-55-001 | TODO | Publish incident mode start/stop notifications with trace/evidence quick links, retention notes, and automatic escalation paths. Include quiet-hour overrides + legal compliance logging. Dependencies: NOTIFY-OBS-51-001. | Notifications Service Guild, Ops Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-61-001 | DONE (2025-11-17) | Update notifier OAS with rules, templates, incidents, quiet hours endpoints using standard error envelope and examples. | Notifications Service Guild, API Contracts Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-61-002 | DONE (2025-11-17) | Implement `/.well-known/openapi` discovery endpoint with scope metadata. Dependencies: NOTIFY-OAS-61-001. | Notifications Service Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-62-001 | DONE (2025-11-17) | Provide SDK usage examples for rule CRUD, incident ack, and quiet hours; ensure SDK smoke tests. Dependencies: NOTIFY-OAS-61-002. | Notifications Service Guild, SDK Generator Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OAS-63-001 | DONE (2025-11-17) | Emit deprecation headers and Notifications templates for retiring notifier APIs. Dependencies: NOTIFY-OAS-62-001. | Notifications Service Guild, API Governance Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OBS-51-001 | DONE (2025-11-22) | Integrate SLO evaluator webhooks into Notifier rules (burn-rate breaches, health degradations) with templates, routing, and suppression logic. Provide sample policies and ensure imposed rule propagation. | Notifications Service Guild, Observability Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-OBS-55-001 | DONE (2025-11-22) | Publish incident mode start/stop notifications with trace/evidence quick links, retention notes, and automatic escalation paths. Include quiet-hour overrides + legal compliance logging. Dependencies: NOTIFY-OBS-51-001. | Notifications Service Guild, Ops Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-RISK-66-001 | TODO | Add notification triggers for risk severity escalation/downgrade events with profile metadata in payload. | Notifications Service Guild, Risk Engine Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-RISK-67-001 | TODO | Notify stakeholders when risk profiles are published, deprecated, or thresholds change. Dependencies: NOTIFY-RISK-66-001. | Notifications Service Guild, Policy Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-RISK-68-001 | TODO | Support per-profile routing rules, quiet hours, and dedupe for risk alerts; integrate with CLI/Console preferences. Dependencies: NOTIFY-RISK-67-001. | Notifications Service Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-DOC-70-001 | DONE (2025-11-02) | Document the split between legacy `src/Notify` libraries and the new `src/Notifier` runtime, updating architecture docs with rationale/cross-links. | Notifications Service Guild (src/Notifier/StellaOps.Notifier)
NOTIFY-AIRGAP-56-002 | DONE | Provide Bootstrap Pack notifier configurations with deterministic secrets handling and offline validation steps. Dependencies: NOTIFY-AIRGAP-56-001. | Notifications Service Guild, DevOps Guild (src/Notifier/StellaOps.Notifier)
## Status notes (2025-11-12 UTC)
## Status notes (2025-11-22 UTC)
- **NOTIFY-ATTEST-74-001** Template matrix (verification failure, expiring attestation, key revoke, witness anomaly) drafted; Section7 added to `docs/notifications/templates.md` plus cross-references in `notifications/overview.md` and `notifications/rules.md` so rule authors and operators use the canonical `tmpl-attest-*` suite; baseline template exports now live under `offline/notifier/templates/attestation/*.template.json`; waiting on Attestor schema freeze (due 2025-11-13) before locking copy and localization tokens.
- **NOTIFY-OAS-61-001** OpenAPI document restructure underway; shared error envelope + examples added, but `quietHours` and `incident` sections still need review with API Contracts Guild.
- **NOTIFY-OBS-51-001/NOTIFY-OBS-55-001** Telemetry SLO webhook schema frozen 2025-11-17; proceed with implementation; incident toggle contract to follow add-only evolution.
- **NOTIFY-RISK-66-001 → NOTIFY-RISK-68-001** Policy risk export v1 approved (read-only); proceed with notification wiring; history fields to arrive later additively.
- **NOTIFY-ATTEST-74-001** Template suite shipped; localized keys locked; see `docs/notifications/templates.md` §7 and offline exports under `offline/notifier/templates/attestation/`.
- **NOTIFY-OAS-61/62/63** OAS refresh, discovery endpoint, SDK examples, and deprecation headers are live.
- **NOTIFY-OBS-51-001** SLO webhook sink validated via filtered tests; TRX at `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/TestResults/notifier-slo-tests.trx`.
- **NOTIFY-OBS-55-001** Incident-mode templates + importable rules shipped (`src/Notifier/StellaOps.Notifier/docs/incident-mode-rules.sample.json`); documented in `docs/notifications/templates.md` §8.
- **NOTIFY-RISK-66-001 → NOTIFY-RISK-68-001** Still waiting on POLICY-RISK-40-002 export; remain TODO.
## Milestones & dependencies
@@ -46,3 +47,4 @@ NOTIFY-AIRGAP-56-002 | DONE | Provide Bootstrap Pack notifier configurations wit
| 2025-11-12 19:32 | Updated `docs/notifications/architecture.md` rendering section to reference the new `tmpl-attest-*` suite so architecture + template docs stay in sync. | Notifications Service Guild |
| 2025-11-12 19:45 | Synced `docs/notifications/overview.md` and `docs/notifications/rules.md` with the attestation template requirements so operators and rule authors see the mandated keys. | Notifications Service Guild |
| 2025-11-12 20:05 | Added baseline template exports under `offline/notifier/templates/attestation/` (Slack/Email/Webhook variants) to seed Offline Kit bundles. | Notifications Service Guild |
| 2025-11-22 18:30 | Updated tracker: OAS 6163, OBS 51/55, ATTEST 74-001 marked DONE; incident-mode rules/templates published; SLO tests captured at `StellaOps.Notifier.Tests/TestResults/notifier-slo-tests.trx`. Risk tasks remain TODO pending POLICY-RISK-40-002 export. | Notifications Service Guild |

View File

@@ -942,7 +942,7 @@
| EXCITITOR-AIAI-31-003 | TODO | | SPRINT_110_ingestion_evidence | Excititor Observability Guild | | Telemetry/guardrail metrics follow chunk API. | EXCITITOR-AIAI-31-002 | EXAI0101 |
| EXCITITOR-AIAI-31-004 | TODO | | SPRINT_110_ingestion_evidence | Docs Guild · Excititor Guild | | Docs/OpenAPI alignment queued behind chunk API finalisation. | EXCITITOR-AIAI-31-002 | EXAI0101 |
| EXCITITOR-AIRGAP-56 | TODO | | SPRINT_110_ingestion_evidence | Excititor Guild · AirGap Guilds | | Air-gap + connector parity depend on schema + attestation readiness. | CONCELIER-GRAPH-21-001; CONCELIER-GRAPH-21-002; ATTEST-PLAN-2001 | EXAG0101 |
| EXCITITOR-AIRGAP-56-001 | TODO | | SPRINT_0119_0001_0001_excititor_i | Excititor Core Guild (`src/Excititor/__Libraries/StellaOps.Excititor.Core`) | src/Excititor/__Libraries/StellaOps.Excititor.Core | Wire mirror bundle ingestion paths that preserve upstream digests, bundle IDs, and provenance metadata exactly so offline Advisory-AI/Lens deployments can replay evidence with AOC parity. | EXCITITOR-AIRGAP-56 | EXAG0101 |
| EXCITITOR-AIRGAP-56-001 | DOING (2025-11-22) | | SPRINT_0119_0001_0001_excititor_i | Excititor Core Guild (`src/Excititor/__Libraries/StellaOps.Excititor.Core`) | src/Excititor/__Libraries/StellaOps.Excititor.Core | Wire mirror bundle ingestion paths that preserve upstream digests, bundle IDs, and provenance metadata exactly so offline Advisory-AI/Lens deployments can replay evidence with AOC parity. | EXCITITOR-AIRGAP-56 | EXAG0101 |
| EXCITITOR-AIRGAP-57 | TODO | | SPRINT_110_ingestion_evidence | Excititor Guild · AirGap Guilds | | Same as -56 plus Evidence Locker | CONCELIER-GRAPH-21-001; CONCELIER-GRAPH-21-002; ATTEST-PLAN-2001 | EXAG0101 |
| EXCITITOR-AIRGAP-57-001 | TODO | | SPRINT_0119_0001_0001_excititor_i | Excititor AirGap Policy Guild (`src/Excititor/__Libraries/StellaOps.Excititor.Core`) | src/Excititor/__Libraries/StellaOps.Excititor.Core | Enforce sealed-mode policies that disable external connectors, emit actionable remediation errors, and record staleness annotations that Advisory AI can surface as “evidence freshness” signals. Depends on EXCITITOR-AIRGAP-56-001. | EXCITITOR-AIRGAP-57 | EXAG0101 |
| EXCITITOR-AIRGAP-58 | TODO | | SPRINT_110_ingestion_evidence | Excititor Guild · AirGap Guilds | | Same upstream | CONCELIER-GRAPH-21-001; CONCELIER-GRAPH-21-002; ATTEST-PLAN-2001 | EXAG0101 |
@@ -1217,16 +1217,16 @@
| NOTIFY-DOCS-0001 | DONE | 2025-11-05 | SPRINT_322_docs_modules_notify | Docs Guild | docs/modules/notify | Validate module README reflects Notifications Studio pivot and latest release notes. | NOTIFY-DOC-70-001 | DONO0102 |
| NOTIFY-DOCS-0002 | TODO | 2025-11-05 | SPRINT_322_docs_modules_notify | Docs Guild | docs/modules/notify | Pending NOTIFY-SVC-39-001..004 to document correlation/digests/simulation/quiet hours. | NOTIFY-SVC-39-004 | DONO0102 |
| NOTIFY-ENG-0001 | TODO | | SPRINT_322_docs_modules_notify | Module Team | docs/modules/notify | Keep implementation milestones aligned with `/docs/implplan/SPRINT_171_notifier_i.md` onward. | NOTY0103 | DONO0102 |
| NOTIFY-OAS-61-001 | DOING | | SPRINT_170_notifications_telemetry | Notifications Service Guild · API Governance Guild | docs/api/notifications | Update OpenAPI doc set (rule/incident endpoints) with new schemas + changelog. | NOTY0103 | NOOA0101 |
| NOTIFY-OAS-61-002 | TODO | | SPRINT_171_notifier_i | Notifications Service Guild · SDK Guild | docs/api/notifications | Provide SDK usage examples for rule CRUD, incident ack, and quiet hours; ensure SDK smoke tests. | NOTIFY-OAS-61-001 | NOOA0101 |
| NOTIFY-OAS-62-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Developer Portal Guild | docs/api/notifications | Publish `/docs/api/reference/notifications` auto-generated site; integrate with portal nav. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OAS-63-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · SDK Generator Guild | docs/api/notifications | Provide CLI/UI quickstarts plus recipes referencing new endpoints. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OBS-51-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Observability Guild | src/Notify/StellaOps.Notify | Implement telemetry SLO webhook schema + incident toggle contract. | NOTY0104 | NOOB0101 |
| NOTIFY-OBS-55-001 | TODO | | SPRINT_171_notifier_i | Notifications Service Guild · Ops Guild | src/Notify/StellaOps.Notify | Add override snapshots, legal compliance logging, and override audit events. | NOTIFY-OBS-51-001 | NOOB0101 |
| NOTIFY-OAS-61-001 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · API Governance Guild | docs/api/notifications | Update OpenAPI doc set (rule/incident endpoints) with new schemas + changelog. | NOTY0103 | NOOA0101 |
| NOTIFY-OAS-61-002 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · SDK Guild | docs/api/notifications | Provide SDK usage examples for rule CRUD, incident ack, and quiet hours; ensure SDK smoke tests. | NOTIFY-OAS-61-001 | NOOA0101 |
| NOTIFY-OAS-62-001 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Developer Portal Guild | docs/api/notifications | Publish `/docs/api/reference/notifications` auto-generated site; integrate with portal nav. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OAS-63-001 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · SDK Generator Guild | docs/api/notifications | Provide CLI/UI quickstarts plus recipes referencing new endpoints. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OBS-51-001 | DONE (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Observability Guild | src/Notifier/StellaOps.Notifier | Integrate SLO evaluator webhooks into Notifier rules; templates/routing/suppression; sample policies. | NOTY0104 | NOOB0101 |
| NOTIFY-OBS-55-001 | DONE (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Ops Guild | src/Notifier/StellaOps.Notifier | Incident mode start/stop notifications with evidence links, retention notes, quiet-hour overrides, legal logging. | NOTIFY-OBS-51-001 | NOOB0101 |
| NOTIFY-OPS-0001 | TODO | | SPRINT_322_docs_modules_notify | Ops Guild · Docs Guild | docs/modules/notify | Review notifier runbooks/observability assets after the next sprint demo and record findings. | NOTIFY-OBS-55-001 | NOOR0101 |
| NOTIFY-RISK-66-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notify/StellaOps.Notify | Policy/Risk metadata export required before implementation. | POLICY-RISK-40-002 | NORR0101 |
| NOTIFY-RISK-67-001 | TODO | | SPRINT_171_notifier_i | Notifications Service Guild · Policy Guild | src/Notify/StellaOps.Notify | Notify stakeholders when risk profiles are published, deprecated, or thresholds change. | NOTIFY-RISK-66-001 | NORR0101 |
| NOTIFY-RISK-68-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notify/StellaOps.Notify | Broadcast severity transitions with trace metadata and attach policy references. | NOTIFY-RISK-67-001 | NORR0101 |
| NOTIFY-RISK-66-001 | BLOCKED (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notifier/StellaOps.Notifier | Policy/Risk metadata export (POLICY-RISK-40-002) not yet delivered. | POLICY-RISK-40-002 | NORR0101 |
| NOTIFY-RISK-67-001 | BLOCKED (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Policy Guild | src/Notifier/StellaOps.Notifier | Depends on NOTIFY-RISK-66-001. | NOTIFY-RISK-66-001 | NORR0101 |
| NOTIFY-RISK-68-001 | BLOCKED (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notifier/StellaOps.Notifier | Depends on NOTIFY-RISK-67-001. | NOTIFY-RISK-67-001 | NORR0101 |
| NOTIFY-SVC-37-001 | TODO | | SPRINT_172_notifier_ii | Notifications Service Guild | src/Notifier/StellaOps.Notifier | Define pack approval & policy notification contract, including OpenAPI schema, event payloads, resume token mechanics, and security guidance. | Align payload schema with PGMI0101 + ATEL0101 decisions | NOTY0103 |
| NOTIFY-SVC-37-002 | TODO | | SPRINT_172_notifier_ii | Notifications Service Guild | src/Notifier/StellaOps.Notifier | Implement secure ingestion endpoint, Mongo persistence (`pack_approvals`), idempotent writes, and audit trail for approval events. Dependencies: NOTIFY-SVC-37-001. | NOTIFY-SVC-37-001 | NOTY0103 |
| NOTIFY-SVC-37-003 | TODO | | SPRINT_172_notifier_ii | Notifications Service Guild | src/Notifier/StellaOps.Notifier | Deliver approval/policy templates, routing predicates, and channel dispatch (email/chat/webhook) with deterministic ordering plus ack gating. | NOTIFY-SVC-37-002 | NOTY0103 |
@@ -3438,16 +3438,16 @@
| NOTIFY-DOCS-0001 | DONE | 2025-11-05 | SPRINT_322_docs_modules_notify | Docs Guild | docs/modules/notify | Validate module README reflects Notifications Studio pivot and latest release notes. | NOTIFY-DOC-70-001 | DONO0102 |
| NOTIFY-DOCS-0002 | TODO | 2025-11-05 | SPRINT_322_docs_modules_notify | Docs Guild | docs/modules/notify | Pending NOTIFY-SVC-39-001..004 to document correlation/digests/simulation/quiet hours. | NOTIFY-SVC-39-004 | DONO0102 |
| NOTIFY-ENG-0001 | TODO | | SPRINT_322_docs_modules_notify | Module Team | docs/modules/notify | Keep implementation milestones aligned with `/docs/implplan/SPRINT_171_notifier_i.md` onward. | NOTY0103 | DONO0102 |
| NOTIFY-OAS-61-001 | DOING | | SPRINT_170_notifications_telemetry | Notifications Service Guild · API Governance Guild | docs/api/notifications | Update OpenAPI doc set (rule/incident endpoints) with new schemas + changelog. | NOTY0103 | NOOA0101 |
| NOTIFY-OAS-61-002 | TODO | | SPRINT_171_notifier_i | Notifications Service Guild · SDK Guild | docs/api/notifications | Provide SDK usage examples for rule CRUD, incident ack, and quiet hours; ensure SDK smoke tests. | NOTIFY-OAS-61-001 | NOOA0101 |
| NOTIFY-OAS-62-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Developer Portal Guild | docs/api/notifications | Publish `/docs/api/reference/notifications` auto-generated site; integrate with portal nav. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OAS-63-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · SDK Generator Guild | docs/api/notifications | Provide CLI/UI quickstarts plus recipes referencing new endpoints. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OBS-51-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Observability Guild | src/Notify/StellaOps.Notify | Implement telemetry SLO webhook schema + incident toggle contract. | NOTY0104 | NOOB0101 |
| NOTIFY-OBS-55-001 | TODO | | SPRINT_171_notifier_i | Notifications Service Guild · Ops Guild | src/Notify/StellaOps.Notify | Add override snapshots, legal compliance logging, and override audit events. | NOTIFY-OBS-51-001 | NOOB0101 |
| NOTIFY-OAS-61-001 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · API Governance Guild | docs/api/notifications | Update OpenAPI doc set (rule/incident endpoints) with new schemas + changelog. | NOTY0103 | NOOA0101 |
| NOTIFY-OAS-61-002 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · SDK Guild | docs/api/notifications | Provide SDK usage examples for rule CRUD, incident ack, and quiet hours; ensure SDK smoke tests. | NOTIFY-OAS-61-001 | NOOA0101 |
| NOTIFY-OAS-62-001 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Developer Portal Guild | docs/api/notifications | Publish `/docs/api/reference/notifications` auto-generated site; integrate with portal nav. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OAS-63-001 | DONE (2025-11-17) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · SDK Generator Guild | docs/api/notifications | Provide CLI/UI quickstarts plus recipes referencing new endpoints. | NOTIFY-OAS-61-002 | NOOA0101 |
| NOTIFY-OBS-51-001 | DONE (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Observability Guild | src/Notifier/StellaOps.Notifier | Integrate telemetry SLO webhook sink and routing into Notifier with templates and suppression. | NOTY0104 | NOOB0101 |
| NOTIFY-OBS-55-001 | DONE (2025-11-22) | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Ops Guild | src/Notifier/StellaOps.Notifier | Incident mode start/stop notifications with evidence links, retention notes, quiet-hour overrides, legal logging. | NOTIFY-OBS-51-001 | NOOB0101 |
| NOTIFY-OPS-0001 | TODO | | SPRINT_322_docs_modules_notify | Ops Guild · Docs Guild | docs/modules/notify | Review notifier runbooks/observability assets after the next sprint demo and record findings. | NOTIFY-OBS-55-001 | NOOR0101 |
| NOTIFY-RISK-66-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notify/StellaOps.Notify | Policy/Risk metadata export required before implementation. | POLICY-RISK-40-002 | NORR0101 |
| NOTIFY-RISK-67-001 | TODO | | SPRINT_171_notifier_i | Notifications Service Guild · Policy Guild | src/Notify/StellaOps.Notify | Notify stakeholders when risk profiles are published, deprecated, or thresholds change. | NOTIFY-RISK-66-001 | NORR0101 |
| NOTIFY-RISK-68-001 | TODO | | SPRINT_170_notifications_telemetry | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notify/StellaOps.Notify | Broadcast severity transitions with trace metadata and attach policy references. | NOTIFY-RISK-67-001 | NORR0101 |
| NOTIFY-RISK-66-001 | TODO | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notifier/StellaOps.Notifier | Policy/Risk metadata export required before implementation. | POLICY-RISK-40-002 | NORR0101 |
| NOTIFY-RISK-67-001 | TODO | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Policy Guild | src/Notifier/StellaOps.Notifier | Notify stakeholders when risk profiles are published, deprecated, or thresholds change. | NOTIFY-RISK-66-001 | NORR0101 |
| NOTIFY-RISK-68-001 | TODO | | SPRINT_0171_0001_0001_notifier_i | Notifications Service Guild · Risk Engine Guild · Policy Guild | src/Notifier/StellaOps.Notifier | Broadcast severity transitions with trace metadata and attach policy references. | NOTIFY-RISK-67-001 | NORR0101 |
| NOTIFY-SVC-37-001 | TODO | | SPRINT_172_notifier_ii | Notifications Service Guild | src/Notifier/StellaOps.Notifier | Define pack approval & policy notification contract, including OpenAPI schema, event payloads, resume token mechanics, and security guidance. | Align payload schema with PGMI0101 + ATEL0101 decisions | NOTY0103 |
| NOTIFY-SVC-37-002 | TODO | | SPRINT_172_notifier_ii | Notifications Service Guild | src/Notifier/StellaOps.Notifier | Implement secure ingestion endpoint, Mongo persistence (`pack_approvals`), idempotent writes, and audit trail for approval events. Dependencies: NOTIFY-SVC-37-001. | NOTIFY-SVC-37-001 | NOTY0103 |
| NOTIFY-SVC-37-003 | TODO | | SPRINT_172_notifier_ii | Notifications Service Guild | src/Notifier/StellaOps.Notifier | Deliver approval/policy templates, routing predicates, and channel dispatch (email/chat/webhook) with deterministic ordering plus ack gating. | NOTIFY-SVC-37-002 | NOTY0103 |

View File

@@ -604,6 +604,7 @@ concelier:
1. **MVP**: Red Hat (CSAF), SUSE (CSAF), Ubuntu (USN JSON), OSV; JSON export.
2. **Add**: GHSA GraphQL, Debian (DSA HTML/JSON), Alpine secdb; Trivy DB export.
3. **Attestation handoff**: integrate with **Signer/Attestor** (optional).
4. **Scale & diagnostics**: provider dashboards, staleness alerts, export cache reuse.
3. **Attestation handoff**: integrate with **Signer/Attestor** (optional).
- Advisory evidence attestation parameters and path rules are documented in `docs/modules/concelier/attestation.md`.
4. **Scale & diagnostics**: provider dashboards, staleness alerts, export cache reuse.
5. **Offline kit**: endtoend verified bundles for airgap.

View File

@@ -0,0 +1,30 @@
# Concelier Advisory Evidence Attestation
## Purpose
- Describe how Concelier returns attestation claims for advisory evidence bundles so downstream services (Advisory AI, Attestor, Console) can verify provenance.
## Endpoint
- `GET /vuln/evidence/advisories/{advisoryKey}`
- Authentication/tenant headers follow standard Concelier rules (`X-Stella-Tenant` or `tenant` query; authority policies apply).
- Response payload: `AdvisoryEvidenceResponse { advisoryKey, records[], attestation? }`
## Attestation parameters (query)
- `bundlePath` (required to enable attestation): Relative or absolute path to evidence bundle tar.gz. Relative paths are resolved under the configured evidence root (`concelier:evidence:root`). Paths outside this root are rejected.
- `manifestPath` (optional): Defaults to sibling `manifest.json` next to the bundle.
- `transparencyPath` (optional): Defaults to sibling `transparency.json` next to the bundle.
- `pipelineVersion` (optional): Defaults to `concelier:evidence:pipelineVersion` (e.g., `git:<sha>`).
## Behavior
- When `bundlePath` is omitted, the endpoint returns evidence records only (attestation is `null`).
- When provided, Concelier builds claims via `EvidenceBundleAttestationBuilder` using the manifest and optional transparency payload; tenant must be lowercase per scope note.
- Path safety: All resolved files must live under the evidence root; traversal attempts or missing files silently skip attestation (response remains valid without claims).
## Configuration
- `concelier:evidence:root` (default `out/evidence/bundles`, resolved absolute).
- `concelier:evidence:defaultManifestFileName` (default `manifest.json`).
- `concelier:evidence:defaultTransparencyFileName` (default `transparency.json`).
- `concelier:evidence:pipelineVersion` (default `git:unknown`).
## References
- Evidence Locker attestation scope: `docs/modules/evidence-locker/attestation-scope-note.md`.
- Implementation: `src/Concelier/StellaOps.Concelier.WebService/Program.cs`, `StellaOps.Concelier.Core/Attestation/EvidenceBundleAttestationBuilder.cs`.

View File

@@ -0,0 +1,29 @@
# Concelier OAS & Observability Prep (61-001..63-001, 51-001..55-001)
Status: **Ready for implementation** (2025-11-22)
Owners: Concelier Core Guild · API Contracts Guild · DevOps/Observability Guilds
Scope: Freeze the API/SDK contracts and observability envelopes for LNM search/timeline APIs so downstream SDK, governance, and incident flows can proceed without schema churn.
## Inputs
- Frozen LNM payload schema: `docs/modules/concelier/link-not-merge-schema.md` (2025-11-17).
- Event contract: `docs/modules/concelier/events/advisory.observation.updated@1.md`.
- Registry/worker orchestration contract: `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md`.
## Deliverables
- OpenAPI source stub for LNM + timeline surfaces recorded at `docs/modules/concelier/openapi/lnm-api.yaml` (paths enumerated; examples outlined below).
- SDK example library checklist covering `searchAdvisories`, `searchLinksets`, `getTimeline`, `getObservationById`; response bodies aligned to frozen schema; no consensus/merge fields.
- Observability contract (metrics/logs/traces):
- Metrics: `concelier_ingest_latency_seconds`, `concelier_linkset_conflicts_total`, `concelier_timeline_emit_lag_seconds`, `concelier_api_requests_total{route,tenant,status}` with burn-rate alert examples.
- Logs: structured fields `tenantId`, `advisoryKey`, `linksetId`, `timelineCursor`, `egressPolicy`.
- Traces: span names for `lnm.search`, `lnm.timeline`, `lnm.linkset-resolve` with baggage keys `tenant-id`, `request-id`.
- Incident/observability hooks: timeline/attestation enrichment notes for OBS-54/55 including DSSE envelope hash field and sealed-mode redaction rules.
## Acceptance Criteria
- Request/response shapes for `/api/v1/lnm/advisories`, `/api/v1/lnm/linksets`, `/api/v1/lnm/timeline` documented with required query params (`tenantId`, `productKey`, `offset`, `limit`, `sort`, `includeTimeline=true|false`).
- All responses MUST include `provenance` block (source, fetchedAt, digest, evidenceBundleId) and forbid consensus/merge fields.
- Metrics/logs names and labels are deterministic and lowercase; alert examples reference burn-rate SLOs.
- File path above is referenced from sprint trackers; any future schema edits require bumping version/comment in this prep doc.
## Notes
- This prep satisfies PREP-CONCELIER-OAS-61-001/002/62-001/63-001 and PREP-CONCELIER-OBS-51-001/52-001/53-001/54-001/55-001.
- No external dependencies remaining; downstream tasks may proceed using the stubbed OpenAPI and observability contracts here.

View File

@@ -0,0 +1,30 @@
# Excititor Air-Gap Prep (56-001, 57-001, 58-001)
Status: **Ready for implementation** (2025-11-22)
Owners: Excititor Core Guild · AirGap Policy Guild · Evidence Locker Guild
Scope: Define ingestion/egress contracts for Excititor when operating in sealed/offline environments and align with mirror bundle + Evidence Locker artifacts.
## Inputs
- Mirror bundle schema (thin) from `docs/modules/mirror/assembler.md`.
- Evidence Locker attestation contract: `docs/modules/evidence-locker/attestation-contract.md`.
- Link-Not-Merge schema for advisory evidence: `docs/modules/concelier/link-not-merge-schema.md`.
## Deliverables
- Ingestion envelope for `POST /airgap/vex/import`:
- Fields: `bundleId`, `mirrorGeneration`, `signedAt`, `publisher`, `payloadHash`, `payloadUrl?` (offline tar path), `signature`, `transparencyLog?`.
- Validation: deterministic hash of NDJSON payloads; must reject mixed tenants; clock-skew tolerance ±5s.
- Sealed-mode error catalog (57-001): `AIRGAP_EGRESS_BLOCKED`, `AIRGAP_PAYLOAD_STALE`, `AIRGAP_SIGNATURE_MISSING`, `AIRGAP_SOURCE_UNTRUSTED`; each with HTTP 4xx mapping and remediation text.
- Notification hooks (58-001): timeline events `airgap.import.started/completed/failed` with attributes `{tenantId,bundleId,generation,stalenessSeconds}`; link to Evidence Locker bundle ID for audit.
- Determinism rules: sort imported observations by `advisoryKey` then `productKey`; write timeline events in the same order; all timestamps UTC ISO-8601.
- Connector trust (CONN-TRUST-01-001):
- Trusted signer manifests reuse `docs/modules/excititor/schemas/connector-signer-metadata.schema.json`; require `fingerprint`, `issuer`, `validFrom/To`, `allowedProfiles`, `bundleHash`.
- Validation: fail import with `AIRGAP_SOURCE_UNTRUSTED` when signer fingerprint not in manifest, signature algorithm not in `{rsa-pss-sha256, ecdsa-p256-sha256, gost-r3410-2012-256}`, or bundle hash mismatch.
- Offline parity: store signer manifests alongside mirror bundle under `mirror/signers/` and include SHA256 in `SHA256SUMS.dsse`.
## Acceptance Criteria
- API shapes captured in this prep are referenced from Sprint 0119 Delivery Tracker; no further blockers for Excititor AirGap tasks.
- Error catalog and timeline events documented and consumed by downstream Policy/AirGap controller work.
- Import path validated against mirror bundle schema; mismatch should raise `AIRGAP_PAYLOAD_STALE`.
## Notes
- Satisfies PREP-EXCITITOR-AIRGAP-56-001, PREP-EXCITITOR-AIRGAP-57-001, and PREP-EXCITITOR-AIRGAP-58-001.

View File

@@ -0,0 +1,27 @@
# Attestation Verifier Rehearsal — Excititor
Status: **Ready for implementation** (2025-11-22)
Owners: Excititor Attestation Guild · Evidence Locker Guild
Scope: Dry-run `IVexAttestationVerifier` against current Evidence Locker bundles to ensure Excititor attestation endpoints ship with deterministic verification.
## Test Matrix
- Inputs: Evidence Bundle v1 sample (`docs/samples/evidence-bundle/*`), mirror bundle thin sample (`out/mirror/thin/mirror-thin-m0-sample.tar.gz`).
- Verification steps:
1. Validate DSSE envelope signature and Rekor entry (if present); offline mode skips transparency but records `rekorSkipped=true`.
2. Verify manifest hash tree against payload NDJSON files; fail on first mismatch.
3. Assert policy hash matches Policy Engine overlay hash (placeholder `policyHash` captured for now).
4. Emit structured result JSON: `{bundleId, verified, dsseVerified, transparencyChecked, manifestRoot, failures[]}`.
- Determinism: sorted failure list, timestamps set to supplied `--as-of` flag.
## Deliverables
- Harness entry point: `tools/attestation/verifier-rehearsal.sh` (script stub path reserved).
- Sample output recorded at `docs/modules/excititor/prep/artifacts/2025-11-22-attestation-rehearsal.json` (to be produced in implementation).
- Logging fields to surface in Excititor: `attestationBundleId`, `evidenceBundleId`, `verified`, `failureCode`, `tenantId`.
## Acceptance Criteria
- Rehearsal script runs offline using bundled samples and exits non-zero on any verification failure.
- Output schema above is referenced by Excititor API tests and Policy attest replay tasks.
- Downstream tasks EXCITITOR-GRAPH-21-00x and attestation endpoints can rely on this contract.
## Notes
- Satisfies PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR.

View File

@@ -0,0 +1,33 @@
# Findings Ledger Prep — 29-008, 34-101, AIRGAP-56-001
Status: **Ready for implementation** (2025-11-22)
Owners: Findings Ledger Guild · Observability Guild · AirGap Time Guild · Orchestrator Guild
Scope: Provide the missing contracts needed to unblock LEDGER-29-008 load/replay, LEDGER-34-101 orchestrator export linkage, and LEDGER-AIRGAP-56-001 bundle provenance recording.
## Observability (LEDGER-29-008)
- Metrics schema locked:
- `ledger_projection_lag_seconds{tenant}` (gauge)
- `ledger_write_duration_seconds_bucket` (histogram)
- `ledger_events_total{tenant,kind}` (counter)
- Alert: burn-rate 4xx/5xx on ingestion path >2% over 5m/1h.
- Log fields: `tenantId`, `requestId`, `projectionCheckpoint`, `bundleId?`, `attestationId?`, `operation`.
- Trace spans: `ledger.write`, `ledger.replay`, `ledger.restore` with baggage `tenant-id`, `bundle-id`.
## Orchestrator export linkage (LEDGER-34-101)
- Export payload shape (from Orchestrator Sprint 150.A):
- `runId` (uuid), `jobType`, `artifactHash`, `policyHash`, `startedAt`, `completedAt`, `status`, `manifestPath`, `logsPath`.
- Ledger integration rule: store export rows under collection `orchestrator_exports` with index `(artifactHash, runId)`; anchor Merkle root into ledger timeline entry `ledger_export` referencing above fields.
## AirGap provenance (LEDGER-AIRGAP-56-001)
- Mirror bundle contract alignment:
- fields recorded per import: `bundleId`, `mirrorGeneration`, `merkleRoot`, `timeAnchor`, `publisher`, `hashAlgorithm`, `contents[]` (sha256 of NDJSON segments).
- determinism: imports sorted by `bundleId`; all timestamps UTC.
- API for recording import: `POST /internal/ledger/airgap-import` with payload above; respond 202 + `ledgerEntryId`.
## Acceptance Criteria
- Metrics/log/logging names frozen as above and added to `docs/modules/findings-ledger/observability.md` in next implementation step.
- Orchestrator export payload shape referenced by both Ledger and Orchestrator tasks; no missing fields for audit.
- AirGap import payload is deterministic and replays without external network requirements.
## Notes
- Satisfies PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA, PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT, and PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM.

View File

@@ -0,0 +1,22 @@
# Policy Export · Console 23-001 Prep
Status: **Ready for implementation** (2025-11-22)
Owners: Policy Guild · Scheduler Guild · Observability Guild
Scope: Define the export bundle + scheduler job surface needed for Console export task 23-001.
## Export Bundle Contract
- Payload: NDJSON of advisory and VEX observations filtered by tenant + product set; include `provenance` block with `source`, `fetchedAt`, `digest`, `evidenceBundleId`.
- Envelope: `bundleId`, `createdAt`, `policyHash`, `schemaVersion`, `itemsSha256`, optional `transparency` entry.
- Determinism: sort items by `observationId`; timestamps truncated to seconds; hashes sha256 lower-case hex.
## Scheduler Job Shape
- `jobType`: `console-export` with fields `tenantId`, `bundleId`, `filters`, `destinationUri` (file:// or s3://), `retryPolicy`, `notificationChannel`.
- Status transitions: `queued → running → completed/failed`; progress fields `exportedCount`, `failedCount`.
- Observability: metrics `policy_console_export_jobs_total{status}`, `policy_console_export_duration_seconds`, logs with `bundleId` and `destinationUri`.
## Acceptance Criteria
- Job shape and bundle envelope above referenced from Sprint 123 Delivery Tracker; no other blocking dependencies.
- Export artefacts can be consumed offline; notification optional.
## Notes
- Satisfies PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN.

View File

@@ -0,0 +1,24 @@
# Policy AirGap 56-001 Prep — Mirror Bundle Schema
Status: **Ready for implementation** (2025-11-22)
Owners: Policy Guild · AirGap Policy Guild
Scope: Lock the mirror bundle schema required for policy pack distribution in sealed mode.
## Bundle Schema
- Envelope: `bundleId`, `schemaVersion` (`policy-mirror-v1`), `createdAt`, `publisher`, `signature`, `transparencyLog?`.
- Contents array entries:
- `policyHash`, `policyName`, `version`, `targetProducts[]`, `scope` (tenant/portfolio), `dependencies[]` (other bundleIds), `config` (immutable), `evidenceBundleId?`.
- Hashing: manifest sha256 over sorted file list (`policies/*.rego`, `overlays/*.json`), recorded as `manifestSha256`.
- Staleness: `validUntil` and `timeAnchor` fields; sealed-mode must reject if `now > validUntil` or time drift > 300s.
## Determinism & Transport
- Files stored in tarball with POSIX mtime `2025-01-01T00:00:00Z` and uid/gid 0.
- Manifest path fixed to `MANIFEST.json`; entries sorted alphabetically.
- No external fetches permitted during import.
## Acceptance Criteria
- Schema above referenced by Policy AirGap tasks and aligns with Mirror bundle contract (`docs/modules/mirror/assembler.md`).
- Import validators know failure codes: `POLICY_BUNDLE_STALE`, `POLICY_BUNDLE_SIGNATURE_INVALID`, `POLICY_BUNDLE_SCHEMA_MISMATCH`.
## Notes
- Completes PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM.

View File

@@ -0,0 +1,24 @@
# Policy Engine 30-001 Prep — Overlay Projection
Status: **Ready for implementation** (2025-11-22)
Owners: Policy Guild · Cartographer Guild
Scope: Freeze overlay projection contract needed for Policy Engine phase III.
## Inputs
- Path/scope schema: `docs/modules/policy/prep/2025-11-20-policy-engine-29-002-prep.md`.
- Metrics/log schema: `docs/modules/policy/prep/2025-11-20-policy-engine-29-004-prep.md`.
## Overlay Projection Contract
- Input: evaluation records `{tenantId, policyId, pathScope[], evidenceDigest, decision, reasons[]}`.
- Output overlay entry:
- `overlayId` (deterministic hash of `tenantId+policyId+pathScope+evidenceDigest`)
- `subject` (`purl` or `pkg` tuple), `pathScope`, `decision`, `rationale`, `inputs` (evidence digests), `policyVersion`, `createdAt`.
- Determinism: pathScope sorted; reasons sorted by `code`; timestamps set to evaluation clock.
- Export shape for downstream components via `/overlays/{overlayId}` and `/overlays/search` with paging.
## Acceptance Criteria
- Overlay schema above referenced in Sprint 125 and 0125 trackers; downstream simulation/bridge tasks can consume it without further schema.
- Any future field additions require version bump `overlaySchemaVersion`.
## Notes
- Completes PREP-POLICY-ENGINE-30-001-WAITING-ON-29-004-M.

View File

@@ -201,3 +201,39 @@ Rekor entry: {{link "Transparency log" payload.links.rekor}}
---
> **Imposed rule reminder:** Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.
---
## 8. Incident mode templates (NOTIFY-OBS-55-001)
Incident toggles are high-noise events that must pierce quiet hours and include audit-ready context. Use dedicated templates so downstream tooling can distinguish activation vs. recovery and surface the required evidence.
**Required context keys**
- `payload.incidentId`, `payload.reason`, `payload.startedAt` / `payload.stoppedAt`.
- `payload.links.trace` (root cause trace/span), `payload.links.evidence` (timeline/export bundle), `payload.links.timeline`.
- `payload.retentionDays` (active) and `payload.retentionBaselineDays` (post-incident).
- `payload.quietHoursOverride` (boolean) to justify bypassing quiet hours.
- `payload.legal.jurisdiction`, `payload.legal.ticket`, `payload.legal.logPath` for compliance logging.
**Template keys**
- `tmpl-incident-start` — activation notice.
- `tmpl-incident-stop` — recovery/cleanup notice.
**Slack sample (start)**
```hbs
:rotating_light: Incident mode activated for {{payload.incidentId}}
Reason: {{payload.reason}}
Trace: {{link "root span" payload.links.trace}} · Evidence: {{link "bundle" payload.links.evidence}}
Retention extended to {{payload.retentionDays}} days (baseline {{payload.retentionBaselineDays}})
Quiet hours overridden: {{payload.quietHoursOverride}}
Legal: {{payload.legal.jurisdiction}} (ticket {{payload.legal.ticket}})
```
**Email sample (stop)**
```hbs
<h2>Incident mode cleared: {{payload.incidentId}}</h2>
<p>Stopped at {{payload.stoppedAt}} — retention reset to {{payload.retentionBaselineDays}} days.</p>
<p>Timeline: {{link "view timeline" payload.links.timeline}} · Audit log: {{payload.legal.logPath}}</p>
```
See `src/Notifier/StellaOps.Notifier/docs/incident-mode-rules.sample.json` for ready-to-import rules referencing these templates with quiet-hour overrides and legal logging metadata.

View File

@@ -1,8 +1,8 @@
# Samples Prep — PREP-SAMPLES-LNM-22-001
# Samples Prep — PREP-SAMPLES-LNM-22-001 / 22-002
Status: **Ready for implementation** (2025-11-20)
Owners: Samples Guild · Concelier Guild
Scope: Produce finalized advisory linkset samples aligned to frozen Concelier linkset schema (LNM-21-002 freeze on 2025-11-20).
Status: **Ready for implementation** (2025-11-22)
Owners: Samples Guild · Concelier Guild · Excititor Guild
Scope: Produce finalized advisory linkset samples aligned to frozen Concelier linkset schema (LNM-21-002 freeze on 2025-11-20) and extend the same fixture set with Excititor observation/VEX payloads for phase 22-002.
## Inputs
- Link-Not-Merge schema: `docs/modules/concelier/link-not-merge-schema.md` (frozen 2025-11-20) and samples under `docs/samples/lnm/`.
@@ -15,6 +15,14 @@ Scope: Produce finalized advisory linkset samples aligned to frozen Concelier li
- Each file accompanied by `.sha256` hash.
- README (`samples/linkset/README.md`) describing schema version, generation seed, and deterministic ordering rules.
## Excititor extension (PREP-SAMPLES-LNM-22-002)
- Extend NDJSON fixtures with Excititor-origin observations:
- `lnm-excititor-vex-sample.ndjson` — 250 Excititor VEX chunks with sealed-mode flags and provenance hashes.
- `lnm-excititor-observations.ndjson` — 250 observation records showing worker/runtime traces.
- Determinism: reuse seed above; order by `observationId`; timestamps fixed to `2025-01-02T00:05:00Z`.
- Additional hashes recorded alongside existing `.sha256` files.
- Document Excititor-specific provenance fields (chunkId, evidenceBundleId, tenantId) in `samples/linkset/README.md`.
## Determinism
- Generation seed: `2025-01-01T00:00:00Z` (use in faker/RNG).
- Sort records by `observationId` before writing; timestamps set to deterministic `2025-01-02T00:00:00Z` for all entries.

View File

@@ -1,4 +1,4 @@
# Concelier · AGENTS Charter (Sprint 01120113)
# Concelier · AGENTS Charter (Sprint 01120114)
## Module Scope & Working Directory
- Working directory: `src/Concelier/**` (WebService, __Libraries, Storage.Mongo, analyzers, tests, seed-data). Do not edit other modules unless explicitly referenced by this sprint.
@@ -17,7 +17,9 @@
- `docs/modules/concelier/architecture.md`
- `docs/modules/concelier/link-not-merge-schema.md`
- `docs/provenance/inline-dsse.md` (for provenance anchors/DSSE notes)
- Any sprint-specific ADRs/notes linked from `docs/implplan/SPRINT_0112_0001_0001_concelier_i.md` or `SPRINT_0113_0001_0002_concelier_ii.md`.
- `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md` (OAS + observability prep)
- `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md` (orchestrator registry/control contracts)
- Any sprint-specific ADRs/notes linked from `docs/implplan/SPRINT_0112_0001_0001_concelier_i.md`, `SPRINT_0113_0001_0002_concelier_ii.md`, or `SPRINT_0114_0001_0003_concelier_iii.md`.
## Working Agreements
- **Aggregation-Only Contract (AOC):** no derived semantics in ingestion; enforce via `AOCWriteGuard` and analyzers. Raw observations are append-only; linksets carry correlations/conflicts only.

View File

@@ -1,8 +1,9 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text.Json;
using System.Text.Json.Serialization;
using StellaOps.Concelier.RawModels;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text.Json;
using System.Text.Json.Serialization;
using StellaOps.Concelier.Core.Attestation;
using StellaOps.Concelier.RawModels;
namespace StellaOps.Concelier.WebService.Contracts;
@@ -89,7 +90,8 @@ public sealed record AdvisoryRawListResponse(
public sealed record AdvisoryEvidenceResponse(
[property: JsonPropertyName("advisoryKey")] string AdvisoryKey,
[property: JsonPropertyName("records")] IReadOnlyList<AdvisoryRawRecordResponse> Records);
[property: JsonPropertyName("records")] IReadOnlyList<AdvisoryRawRecordResponse> Records,
[property: JsonPropertyName("attestation")] AttestationClaims? Attestation);
public sealed record AdvisoryRawProvenanceResponse(
[property: JsonPropertyName("id")] string Id,

View File

@@ -0,0 +1,56 @@
using System.ComponentModel.DataAnnotations;
using StellaOps.Concelier.Storage.Mongo.Orchestrator;
namespace StellaOps.Concelier.WebService.Contracts;
public sealed record OrchestratorRegistryRequest(
[property: Required] string ConnectorId,
[property: Required] string Source,
[property: Required] string[] Capabilities,
[property: Required] string AuthRef,
[property: Required] OrchestratorScheduleDto Schedule,
[property: Required] OrchestratorRatePolicyDto RatePolicy,
[property: Required] string[] ArtifactKinds,
[property: Required] string LockKey,
[property: Required] OrchestratorEgressGuardDto EgressGuard);
public sealed record OrchestratorScheduleDto(
string Cron,
string TimeZone,
int MaxParallelRuns,
int MaxLagMinutes);
public sealed record OrchestratorRatePolicyDto(
int Rpm,
int Burst,
int CooldownSeconds);
public sealed record OrchestratorEgressGuardDto(
string[] Allowlist,
bool AirgapMode);
public sealed record OrchestratorHeartbeatRequest(
[property: Required] string ConnectorId,
[property: Required] Guid RunId,
[property: Required] long Sequence,
[property: Required] OrchestratorHeartbeatStatus Status,
int? Progress,
int? QueueDepth,
string? LastArtifactHash,
string? LastArtifactKind,
string? ErrorCode,
int? RetryAfterSeconds,
DateTimeOffset? TimestampUtc);
public sealed record OrchestratorCommandRequest(
[property: Required] string ConnectorId,
[property: Required] Guid RunId,
[property: Required] long Sequence,
[property: Required] OrchestratorCommandKind Command,
OrchestratorThrottleOverrideDto? Throttle,
OrchestratorBackfillRangeDto? Backfill,
DateTimeOffset? ExpiresAt);
public sealed record OrchestratorThrottleOverrideDto(int? Rpm, int? Burst, int? CooldownSeconds, DateTimeOffset? ExpiresAt);
public sealed record OrchestratorBackfillRangeDto(string? FromCursor, string? ToCursor);

View File

@@ -21,6 +21,8 @@ public sealed class ConcelierOptions
public AdvisoryChunkOptions AdvisoryChunks { get; set; } = new();
public EvidenceBundleOptions Evidence { get; set; } = new();
public StellaOpsCryptoOptions Crypto { get; } = new();
public sealed class StorageOptions
@@ -172,4 +174,20 @@ public sealed class ConcelierOptions
public int CacheDurationSeconds { get; set; } = 30;
}
public sealed class EvidenceBundleOptions
{
public bool Enabled { get; set; } = true;
public string Root { get; set; } = System.IO.Path.Combine("out", "evidence", "bundles");
public string? DefaultManifestFileName { get; set; } = "manifest.json";
public string? DefaultTransparencyFileName { get; set; } = "transparency.json";
public string PipelineVersion { get; set; } = "git:unknown";
[JsonIgnore]
public string RootAbsolute { get; internal set; } = string.Empty;
}
}

View File

@@ -19,6 +19,7 @@ public static class ConcelierOptionsPostConfigure
options.Authority ??= new ConcelierOptions.AuthorityOptions();
options.Features ??= new ConcelierOptions.FeaturesOptions();
options.Evidence ??= new ConcelierOptions.EvidenceBundleOptions();
var authority = options.Authority;
if (string.IsNullOrWhiteSpace(authority.ClientSecret)
@@ -44,8 +45,8 @@ public static class ConcelierOptionsPostConfigure
authority.ClientSecret = secret;
}
options.Mirror ??= new ConcelierOptions.MirrorOptions();
var mirror = options.Mirror;
options.Mirror ??= new ConcelierOptions.MirrorOptions();
var mirror = options.Mirror;
if (string.IsNullOrWhiteSpace(mirror.ExportRoot))
{
@@ -65,9 +66,33 @@ public static class ConcelierOptionsPostConfigure
mirror.LatestDirectoryName = "latest";
}
if (string.IsNullOrWhiteSpace(mirror.MirrorDirectoryName))
{
mirror.MirrorDirectoryName = "mirror";
}
}
}
if (string.IsNullOrWhiteSpace(mirror.MirrorDirectoryName))
{
mirror.MirrorDirectoryName = "mirror";
}
var evidence = options.Evidence;
if (string.IsNullOrWhiteSpace(evidence.Root))
{
evidence.Root = Path.Combine("out", "evidence", "bundles");
}
var evidenceRoot = evidence.Root;
if (!Path.IsPathRooted(evidenceRoot))
{
evidenceRoot = Path.Combine(contentRootPath, evidenceRoot);
}
evidence.RootAbsolute = Path.GetFullPath(evidenceRoot);
if (string.IsNullOrWhiteSpace(evidence.DefaultManifestFileName))
{
evidence.DefaultManifestFileName = "manifest.json";
}
if (string.IsNullOrWhiteSpace(evidence.DefaultTransparencyFileName))
{
evidence.DefaultTransparencyFileName = "transparency.json";
}
}
}

View File

@@ -137,6 +137,9 @@ public static class ConcelierOptionsValidator
options.Mirror ??= new ConcelierOptions.MirrorOptions();
ValidateMirror(options.Mirror);
options.Evidence ??= new ConcelierOptions.EvidenceBundleOptions();
ValidateEvidence(options.Evidence);
options.AdvisoryChunks ??= new ConcelierOptions.AdvisoryChunkOptions();
ValidateAdvisoryChunks(options.AdvisoryChunks);
}
@@ -312,4 +315,22 @@ public static class ConcelierOptionsValidator
throw new InvalidOperationException("Advisory chunk cacheDurationSeconds must be greater than or equal to zero.");
}
}
private static void ValidateEvidence(ConcelierOptions.EvidenceBundleOptions evidence)
{
if (string.IsNullOrWhiteSpace(evidence.Root))
{
throw new InvalidOperationException("Evidence bundle root must be configured.");
}
if (string.IsNullOrWhiteSpace(evidence.RootAbsolute))
{
throw new InvalidOperationException("Evidence bundle root could not be resolved.");
}
if (string.IsNullOrWhiteSpace(evidence.PipelineVersion))
{
throw new InvalidOperationException("Evidence bundle pipelineVersion must be provided.");
}
}
}

View File

@@ -55,6 +55,7 @@ using StellaOps.Concelier.Storage.Mongo.Advisories;
using StellaOps.Concelier.Storage.Mongo.Aliases;
using StellaOps.Provenance.Mongo;
using StellaOps.Concelier.Core.Attestation;
using StellaOps.Concelier.Storage.Mongo.Orchestrator;
var builder = WebApplication.CreateBuilder(args);
@@ -398,6 +399,162 @@ app.MapGet("/.well-known/openapi", ([FromServices] OpenApiDiscoveryDocumentProvi
}
}).WithName("GetConcelierOpenApiDocument");
var orchestratorGroup = app.MapGroup("/internal/orch");
if (authorityConfigured)
{
orchestratorGroup.RequireAuthorization();
}
orchestratorGroup.MapPost("/registry", async (
HttpContext context,
[FromBody] OrchestratorRegistryRequest request,
[FromServices] IOrchestratorRegistryStore store,
TimeProvider timeProvider,
CancellationToken cancellationToken) =>
{
if (!TryResolveTenant(context, requireHeader: true, out var tenant, out var tenantError))
{
return tenantError;
}
if (string.IsNullOrWhiteSpace(request.ConnectorId) || string.IsNullOrWhiteSpace(request.Source))
{
return Problem(context, "connectorId and source are required", StatusCodes.Status400BadRequest, ProblemTypes.Validation, "Provide connectorId and source.");
}
var now = timeProvider.GetUtcNow();
var record = new OrchestratorRegistryRecord(
tenant,
request.ConnectorId.Trim(),
request.Source.Trim(),
request.Capabilities,
request.AuthRef,
new OrchestratorSchedule(
request.Schedule.Cron,
string.IsNullOrWhiteSpace(request.Schedule.TimeZone) ? "UTC" : request.Schedule.TimeZone,
request.Schedule.MaxParallelRuns,
request.Schedule.MaxLagMinutes),
new OrchestratorRatePolicy(request.RatePolicy.Rpm, request.RatePolicy.Burst, request.RatePolicy.CooldownSeconds),
request.ArtifactKinds,
request.LockKey,
new OrchestratorEgressGuard(request.EgressGuard.Allowlist, request.EgressGuard.AirgapMode),
now,
now);
await store.UpsertAsync(record, cancellationToken).ConfigureAwait(false);
return Results.Accepted();
}).WithName("UpsertOrchestratorRegistry");
orchestratorGroup.MapPost("/heartbeat", async (
HttpContext context,
[FromBody] OrchestratorHeartbeatRequest request,
[FromServices] IOrchestratorRegistryStore store,
TimeProvider timeProvider,
CancellationToken cancellationToken) =>
{
if (!TryResolveTenant(context, requireHeader: true, out var tenant, out var tenantError))
{
return tenantError;
}
if (string.IsNullOrWhiteSpace(request.ConnectorId))
{
return Problem(context, "connectorId is required", StatusCodes.Status400BadRequest, ProblemTypes.Validation, "Provide connectorId.");
}
if (request.Sequence < 0)
{
return Problem(context, "sequence must be non-negative", StatusCodes.Status400BadRequest, ProblemTypes.Validation, "Provide a non-negative sequence.");
}
var timestamp = request.TimestampUtc ?? timeProvider.GetUtcNow();
var heartbeat = new OrchestratorHeartbeatRecord(
tenant,
request.ConnectorId.Trim(),
request.RunId,
request.Sequence,
request.Status,
request.Progress,
request.QueueDepth,
request.LastArtifactHash,
request.LastArtifactKind,
request.ErrorCode,
request.RetryAfterSeconds,
timestamp);
await store.AppendHeartbeatAsync(heartbeat, cancellationToken).ConfigureAwait(false);
return Results.Accepted();
}).WithName("RecordOrchestratorHeartbeat");
orchestratorGroup.MapPost("/commands", async (
HttpContext context,
[FromBody] OrchestratorCommandRequest request,
[FromServices] IOrchestratorRegistryStore store,
CancellationToken cancellationToken) =>
{
if (!TryResolveTenant(context, requireHeader: true, out var tenant, out var tenantError))
{
return tenantError;
}
if (string.IsNullOrWhiteSpace(request.ConnectorId))
{
return Problem(context, "connectorId is required", StatusCodes.Status400BadRequest, ProblemTypes.Validation, "Provide connectorId.");
}
if (request.Sequence < 0)
{
return Problem(context, "sequence must be non-negative", StatusCodes.Status400BadRequest, ProblemTypes.Validation, "Provide a non-negative sequence.");
}
var command = new OrchestratorCommandRecord(
tenant,
request.ConnectorId.Trim(),
request.RunId,
request.Sequence,
request.Command,
request.Throttle is null
? null
: new OrchestratorThrottleOverride(
request.Throttle.Rpm,
request.Throttle.Burst,
request.Throttle.CooldownSeconds,
request.Throttle.ExpiresAt),
request.Backfill is null
? null
: new OrchestratorBackfillRange(request.Backfill.FromCursor, request.Backfill.ToCursor),
DateTimeOffset.UtcNow,
request.ExpiresAt);
await store.EnqueueCommandAsync(command, cancellationToken).ConfigureAwait(false);
return Results.Accepted();
}).WithName("EnqueueOrchestratorCommand");
orchestratorGroup.MapGet("/commands", async (
HttpContext context,
[FromQuery] string connectorId,
[FromQuery] Guid runId,
[FromQuery] long? afterSequence,
[FromServices] IOrchestratorRegistryStore store,
CancellationToken cancellationToken) =>
{
ApplyNoCache(context.Response);
if (!TryResolveTenant(context, requireHeader: true, out var tenant, out var tenantError))
{
return tenantError;
}
if (string.IsNullOrWhiteSpace(connectorId))
{
return Problem(context, "connectorId is required", StatusCodes.Status400BadRequest, ProblemTypes.Validation, "Provide connectorId.");
}
var commands = await store.GetPendingCommandsAsync(tenant, connectorId.Trim(), runId, afterSequence, cancellationToken).ConfigureAwait(false);
return Results.Ok(commands);
}).WithName("GetOrchestratorCommands");
var jsonOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
jsonOptions.Converters.Add(new JsonStringEnumConverter());
@@ -836,6 +993,7 @@ var advisoryEvidenceEndpoint = app.MapGet("/vuln/evidence/advisories/{advisoryKe
HttpContext context,
[FromServices] IAdvisoryRawService rawService,
[FromServices] EvidenceBundleAttestationBuilder attestationBuilder,
[FromServices] ILogger<Program> logger,
CancellationToken cancellationToken) =>
{
ApplyNoCache(context.Response);
@@ -879,10 +1037,16 @@ var advisoryEvidenceEndpoint = app.MapGet("/vuln/evidence/advisories/{advisoryKe
record.Document))
.ToArray();
var evidenceOptions = resolvedConcelierOptions.Evidence ?? new ConcelierOptions.EvidenceBundleOptions();
var attestation = await TryBuildAttestationAsync(
context,
evidenceOptions,
attestationBuilder,
logger,
cancellationToken).ConfigureAwait(false);
var responseKey = recordResponses[0].Document.AdvisoryKey ?? canonicalKey;
var response = new AdvisoryEvidenceResponse(responseKey, recordResponses);
// TODO: Attach attestation metadata when Evidence Bundle tarball is available per tenant/advisory.
// The builder is registered for future use once bundle paths are discoverable from evidence storage.
var response = new AdvisoryEvidenceResponse(responseKey, recordResponses, attestation);
return JsonResult(response);
});
if (authorityConfigured)
@@ -1622,6 +1786,120 @@ static KeyValuePair<string, object?>[] BuildJobMetricTags(string jobKind, string
new KeyValuePair<string, object?>("job.outcome", outcome),
};
static async Task<AttestationClaims?> TryBuildAttestationAsync(
HttpContext context,
ConcelierOptions.EvidenceBundleOptions evidenceOptions,
EvidenceBundleAttestationBuilder builder,
ILogger logger,
CancellationToken cancellationToken)
{
var bundlePath = context.Request.Query.TryGetValue("bundlePath", out var bundleValues)
? bundleValues.FirstOrDefault()
: null;
if (string.IsNullOrWhiteSpace(bundlePath))
{
return null;
}
var manifestPath = context.Request.Query.TryGetValue("manifestPath", out var manifestValues)
? manifestValues.FirstOrDefault()
: null;
var transparencyPath = context.Request.Query.TryGetValue("transparencyPath", out var transparencyValues)
? transparencyValues.FirstOrDefault()
: null;
var pipelineVersion = context.Request.Query.TryGetValue("pipelineVersion", out var pipelineValues)
? pipelineValues.FirstOrDefault()
: null;
pipelineVersion = string.IsNullOrWhiteSpace(pipelineVersion)
? evidenceOptions.PipelineVersion
: pipelineVersion.Trim();
var root = evidenceOptions.RootAbsolute;
var resolvedBundlePath = ResolveEvidencePath(bundlePath, root);
if (string.IsNullOrWhiteSpace(resolvedBundlePath) || !File.Exists(resolvedBundlePath))
{
return null;
}
var resolvedManifestPath = string.IsNullOrWhiteSpace(manifestPath)
? ResolveSibling(resolvedBundlePath, evidenceOptions.DefaultManifestFileName)
: ResolveEvidencePath(manifestPath!, root);
if (string.IsNullOrWhiteSpace(resolvedManifestPath) || !File.Exists(resolvedManifestPath))
{
return null;
}
var resolvedTransparencyPath = string.IsNullOrWhiteSpace(transparencyPath)
? ResolveSibling(resolvedBundlePath, evidenceOptions.DefaultTransparencyFileName)
: ResolveEvidencePath(transparencyPath!, root);
try
{
return await builder.BuildAsync(
new EvidenceBundleAttestationRequest(
resolvedBundlePath!,
resolvedManifestPath!,
resolvedTransparencyPath,
pipelineVersion ?? "git:unknown"),
cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
logger.LogWarning(ex, "Failed to build attestation for evidence bundle {BundlePath}", resolvedBundlePath);
return null;
}
}
static string? ResolveEvidencePath(string candidate, string root)
{
if (string.IsNullOrWhiteSpace(candidate))
{
return null;
}
var path = candidate;
if (!Path.IsPathRooted(path))
{
path = Path.Combine(root, path);
}
var fullPath = Path.GetFullPath(path);
if (!string.IsNullOrWhiteSpace(root))
{
var rootPath = Path.GetFullPath(root)
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
if (!fullPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
{
return null;
}
}
return fullPath;
}
static string? ResolveSibling(string? bundlePath, string? fileName)
{
if (string.IsNullOrWhiteSpace(bundlePath) || string.IsNullOrWhiteSpace(fileName))
{
return null;
}
var directory = Path.GetDirectoryName(bundlePath);
if (string.IsNullOrWhiteSpace(directory))
{
return null;
}
return Path.Combine(directory, fileName);
}
void ApplyNoCache(HttpResponse response)
{
if (response is null)

View File

@@ -39,7 +39,8 @@ public sealed record AdvisoryLinksetProvenance(
public sealed record AdvisoryLinksetConflict(
string Field,
string Reason,
IReadOnlyList<string>? Values);
IReadOnlyList<string>? Values,
IReadOnlyList<string>? SourceIds = null);
internal static class BsonDocumentHelper
{

View File

@@ -32,10 +32,23 @@ internal static class AdvisoryLinksetNormalization
ArgumentNullException.ThrowIfNull(linkset);
var normalized = Build(linkset.PackageUrls);
var conflicts = ExtractConflicts(linkset);
var confidence = ComputeConfidence(linkset, providedConfidence, conflicts);
return (normalized, confidence, conflicts);
var inputs = new[]
{
new LinksetCorrelation.Input(
Vendor: null,
FetchedAt: null,
Aliases: linkset.Aliases,
Purls: linkset.PackageUrls,
Cpes: linkset.Cpes,
References: linkset.References.Select(r => r.Url).ToArray())
};
var noteConflicts = ExtractConflicts(linkset);
var (confidenceScore, conflicts) = LinksetCorrelation.Compute(inputs, noteConflicts);
var coerced = providedConfidence.HasValue ? CoerceConfidence(providedConfidence) : confidenceScore;
return (normalized, coerced, conflicts);
}
private static AdvisoryLinksetNormalized? Build(IEnumerable<string> purlValues)
@@ -190,37 +203,4 @@ internal static class AdvisoryLinksetNormalization
return conflicts;
}
private static double? ComputeConfidence(RawLinkset linkset, double? providedConfidence, IReadOnlyList<AdvisoryLinksetConflict> conflicts)
{
if (providedConfidence.HasValue)
{
return CoerceConfidence(providedConfidence);
}
double aliasScore = linkset.Aliases.IsDefaultOrEmpty ? 0d : 1d;
double purlOverlapScore = linkset.PackageUrls.IsDefaultOrEmpty
? 0d
: (linkset.PackageUrls.Length > 1 ? 1d : 0.6d);
double cpeOverlapScore = linkset.Cpes.IsDefaultOrEmpty
? 0d
: (linkset.Cpes.Length > 1 ? 1d : 0.5d);
double severityAgreement = conflicts.Any(c => c.Reason == "severity-mismatch") ? 0.2d : 0.5d;
double referenceOverlap = linkset.References.IsDefaultOrEmpty ? 0d : 0.5d;
double freshnessScore = 0.5d; // until fetchedAt spread is available
var confidence = (0.40 * aliasScore) +
(0.25 * purlOverlapScore) +
(0.15 * cpeOverlapScore) +
(0.10 * severityAgreement) +
(0.05 * referenceOverlap) +
(0.05 * freshnessScore);
if (conflicts.Count > 0 && confidence > 0.7d)
{
confidence -= 0.1d; // penalize non-empty conflict sets
}
return Math.Clamp(confidence, 0d, 1d);
}
}

View File

@@ -0,0 +1,346 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using StellaOps.Concelier.Models;
namespace StellaOps.Concelier.Core.Linksets;
internal static class LinksetCorrelation
{
internal readonly record struct Input(
string? Vendor,
DateTimeOffset? FetchedAt,
IReadOnlyCollection<string> Aliases,
IReadOnlyCollection<string> Purls,
IReadOnlyCollection<string> Cpes,
IReadOnlyCollection<string> References);
internal static (double Confidence, IReadOnlyList<AdvisoryLinksetConflict> Conflicts) Compute(
IReadOnlyCollection<Input> inputs,
IReadOnlyList<AdvisoryLinksetConflict>? additionalConflicts = null)
{
if (inputs.Count == 0)
{
return (1.0, Array.Empty<AdvisoryLinksetConflict>());
}
var conflicts = new List<AdvisoryLinksetConflict>();
var aliasScore = CalculateAliasScore(inputs, conflicts);
var (purlScore, rangeConflicts) = CalculatePurlScore(inputs);
conflicts.AddRange(rangeConflicts);
var cpeScore = CalculateCpeScore(inputs);
var (referenceScore, referenceConflicts) = CalculateReferenceScore(inputs);
conflicts.AddRange(referenceConflicts);
var severityAgreement = 0.5d; // no severity data available in linkset inputs
var freshnessScore = CalculateFreshnessScore(inputs);
var baseConfidence = Clamp01(
(0.40d * aliasScore) +
(0.25d * purlScore) +
(0.15d * cpeScore) +
(0.10d * severityAgreement) +
(0.05d * referenceScore) +
(0.05d * freshnessScore));
if (conflicts.Count > 0 && baseConfidence > 0.7d)
{
baseConfidence -= 0.1d;
}
if (baseConfidence < 0.1d && conflicts.Count > 0)
{
baseConfidence = 0.1d; // keep deterministic low signal, not zero
}
if (additionalConflicts is { Count: > 0 })
{
conflicts.AddRange(additionalConflicts);
}
return (Clamp01(baseConfidence), DeduplicateAndSort(conflicts, inputs));
}
private static double CalculateAliasScore(IReadOnlyCollection<Input> inputs, List<AdvisoryLinksetConflict> conflicts)
{
if (inputs.Count == 1)
{
return inputs.First().Aliases.Count > 0 ? 1d : 0d;
}
var intersection = inputs
.Select(i => i.Aliases.Select(a => a.ToLowerInvariant()).ToHashSet(StringComparer.Ordinal))
.Aggregate((acc, next) =>
{
acc.IntersectWith(next);
return acc;
});
if (intersection.Count > 0)
{
return 1d;
}
var anyAliases = inputs.Any(i => i.Aliases.Count > 0);
if (anyAliases)
{
var values = inputs
.Select(i => $"{i.Vendor ?? "source"}:{i.Aliases.FirstOrDefault() ?? "<none>"}")
.ToArray();
conflicts.Add(new AdvisoryLinksetConflict("aliases", "alias-inconsistency", values));
}
var vendors = inputs.Select(i => i.Vendor ?? string.Empty).ToHashSet(StringComparer.OrdinalIgnoreCase);
return vendors.Count == 1 ? 0.5d : 0d;
}
private static (double Score, IReadOnlyList<AdvisoryLinksetConflict> Conflicts) CalculatePurlScore(
IReadOnlyCollection<Input> inputs)
{
var conflicts = new List<AdvisoryLinksetConflict>();
if (inputs.All(i => i.Purls.Count == 0))
{
return (0d, conflicts);
}
List<HashSet<string>> packageKeysPerInput = inputs
.Select(i => i.Purls
.Select(ExtractPackageKey)
.Where(k => !string.IsNullOrEmpty(k))
.ToHashSet(StringComparer.Ordinal))
.ToList();
var sharedPackages = packageKeysPerInput
.Skip(1)
.Aggregate(
new HashSet<string>(packageKeysPerInput.First()!, StringComparer.Ordinal),
(acc, next) =>
{
acc.IntersectWith(next!);
return acc;
});
if (sharedPackages.Count > 0)
{
var hasExactPurlOverlap = HasExactPurlOverlap(inputs);
if (!hasExactPurlOverlap)
{
var divergent = CollectRangeConflicts(inputs, sharedPackages);
conflicts.AddRange(divergent);
}
return (hasExactPurlOverlap ? 1d : 0.6d, conflicts);
}
return (0d, conflicts);
}
private static IEnumerable<AdvisoryLinksetConflict> CollectRangeConflicts(
IReadOnlyCollection<Input> inputs,
HashSet<string> sharedPackages)
{
var conflicts = new List<AdvisoryLinksetConflict>();
foreach (var package in sharedPackages)
{
var values = inputs
.SelectMany(i => i.Purls
.Where(p => ExtractPackageKey(p) == package)
.Select(p => $"{i.Vendor ?? "source"}:{p}"))
.ToArray();
var sourceIds = inputs
.Select(i => i.Vendor ?? "source")
.ToArray();
if (values.Length > 1)
{
conflicts.Add(new AdvisoryLinksetConflict(
"affected.versions",
"affected-range-divergence",
values,
sourceIds));
}
}
return conflicts;
}
private static bool HasExactPurlOverlap(IReadOnlyCollection<Input> inputs)
{
var first = inputs.First().Purls.ToHashSet(StringComparer.Ordinal);
return inputs.Skip(1).Any(input => input.Purls.Any(first.Contains));
}
private static string ExtractPackageKey(string purl)
{
if (string.IsNullOrWhiteSpace(purl))
{
return string.Empty;
}
var atIndex = purl.LastIndexOf('@');
return atIndex > 0 ? purl[..atIndex] : purl;
}
private static double CalculateCpeScore(IReadOnlyCollection<Input> inputs)
{
if (inputs.All(i => i.Cpes.Count == 0))
{
return 0d;
}
var cpeSets = inputs.Select(i => i.Cpes.ToHashSet(StringComparer.OrdinalIgnoreCase)).ToList();
var exactOverlap = cpeSets.Skip(1).Any(set => set.Overlaps(cpeSets.First()));
if (exactOverlap)
{
return 1d;
}
var vendorProductSets = inputs
.Select(i => i.Cpes.Select(ParseVendorProduct).Where(vp => vp.vendor is not null).ToHashSet())
.ToList();
var sharedVendorProduct = vendorProductSets.Skip(1).Any(set => set.Overlaps(vendorProductSets.First()));
return sharedVendorProduct ? 0.5d : 0d;
}
private static (string? vendor, string? product) ParseVendorProduct(string cpe)
{
if (string.IsNullOrWhiteSpace(cpe))
{
return (null, null);
}
var parts = cpe.Split(':');
if (parts.Length >= 6 && parts[0].StartsWith("cpe", StringComparison.OrdinalIgnoreCase))
{
// cpe:2.3:a:vendor:product:version...
return (parts[3], parts[4]);
}
if (parts.Length >= 5 && parts[0] == "cpe" && parts[1] == "/")
{
return (parts[2], parts[3]);
}
return (null, null);
}
private static (double Score, IReadOnlyList<AdvisoryLinksetConflict> Conflicts) CalculateReferenceScore(
IReadOnlyCollection<Input> inputs)
{
var conflicts = new List<AdvisoryLinksetConflict>();
if (inputs.All(i => i.References.Count == 0))
{
return (0d, conflicts);
}
double maxOverlap = 0d;
var inputList = inputs.ToList();
for (var i = 0; i < inputList.Count; i++)
{
for (var j = i + 1; j < inputList.Count; j++)
{
var first = inputList[i].References.Select(r => r.ToLowerInvariant()).ToHashSet();
var second = inputList[j].References.Select(r => r.ToLowerInvariant()).ToHashSet();
var intersection = first.Intersect(second).Count();
var denom = Math.Max(first.Count, second.Count);
var overlap = denom == 0 ? 0d : (double)intersection / denom;
if (overlap > maxOverlap)
{
maxOverlap = overlap;
}
if (overlap == 0d && !string.Equals(inputList[i].Vendor, inputList[j].Vendor, StringComparison.OrdinalIgnoreCase))
{
var values = new[]
{
$"{inputList[i].Vendor ?? "source"}:{first.FirstOrDefault() ?? "<none>"}",
$"{inputList[j].Vendor ?? "source"}:{second.FirstOrDefault() ?? "<none>"}"
};
conflicts.Add(new AdvisoryLinksetConflict(
"references",
"reference-clash",
values,
new[]
{
inputList[i].Vendor ?? "source",
inputList[j].Vendor ?? "source"
}));
}
}
}
return (maxOverlap, conflicts);
}
private static double CalculateFreshnessScore(IReadOnlyCollection<Input> inputs)
{
var fetched = inputs
.Select(i => i.FetchedAt)
.Where(d => d.HasValue)
.Select(d => d!.Value)
.ToList();
if (fetched.Count <= 1)
{
return 0.5d; // neutral when unknown
}
var min = fetched.Min();
var max = fetched.Max();
var spread = max - min;
if (spread <= TimeSpan.FromHours(48))
{
return 1d;
}
if (spread >= TimeSpan.FromDays(14))
{
return 0d;
}
var remaining = TimeSpan.FromDays(14) - spread;
return Clamp01(remaining.TotalSeconds / TimeSpan.FromDays(14).TotalSeconds);
}
private static IReadOnlyList<AdvisoryLinksetConflict> DeduplicateAndSort(
IEnumerable<AdvisoryLinksetConflict> conflicts,
IReadOnlyCollection<Input> inputs)
{
var set = new HashSet<string>(StringComparer.Ordinal);
var list = new List<AdvisoryLinksetConflict>();
foreach (var conflict in conflicts)
{
var key = $"{conflict.Field}|{conflict.Reason}|{string.Join('|', conflict.Values ?? Array.Empty<string>())}";
if (set.Add(key))
{
if (conflict.SourceIds is null || conflict.SourceIds.Count == 0)
{
var allSources = inputs.Select(i => i.Vendor ?? "source").Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
list.Add(conflict with { SourceIds = allSources });
}
else
{
list.Add(conflict);
}
}
}
return list
.OrderBy(c => c.Field, StringComparer.Ordinal)
.ThenBy(c => c.Reason, StringComparer.Ordinal)
.ThenBy(c => string.Join('|', c.Values ?? Array.Empty<string>()), StringComparer.Ordinal)
.ToList();
}
private static double Clamp01(double value) => Math.Clamp(value, 0d, 1d);
}

View File

@@ -216,28 +216,27 @@ public sealed class AdvisoryObservationQueryService : IAdvisoryObservationQueryS
var referenceSet = new HashSet<AdvisoryObservationReference>();
var scopeSet = new HashSet<string>(StringComparer.Ordinal);
var relationshipSet = new HashSet<RawRelationship>();
var conflictSet = new HashSet<string>(StringComparer.Ordinal);
var conflicts = new List<AdvisoryLinksetConflict>();
var confidence = 1.0;
var correlationInputs = new List<LinksetCorrelation.Input>(observations.Length);
foreach (var observation in observations)
{
foreach (var alias in observation.Linkset.Aliases)
{
aliasSet.Add(alias);
}
foreach (var purl in observation.Linkset.Purls)
{
purlSet.Add(purl);
}
foreach (var cpe in observation.Linkset.Cpes)
{
cpeSet.Add(cpe);
}
foreach (var reference in observation.Linkset.References)
aliasSet.Add(alias);
}
foreach (var purl in observation.Linkset.Purls)
{
purlSet.Add(purl);
}
foreach (var cpe in observation.Linkset.Cpes)
{
cpeSet.Add(cpe);
}
foreach (var reference in observation.Linkset.References)
{
referenceSet.Add(reference);
}
@@ -252,19 +251,17 @@ public sealed class AdvisoryObservationQueryService : IAdvisoryObservationQueryS
relationshipSet.Add(relationship);
}
var linksetProjection = AdvisoryLinksetNormalization.FromRawLinksetWithConfidence(observation.RawLinkset);
confidence = Math.Min(confidence, linksetProjection.confidence ?? 1.0);
foreach (var conflict in linksetProjection.conflicts)
{
var key = $"{conflict.Field}|{conflict.Reason}|{string.Join('|', conflict.Values ?? Array.Empty<string>())}";
if (conflictSet.Add(key))
{
conflicts.Add(conflict);
}
}
correlationInputs.Add(new LinksetCorrelation.Input(
observation.Source.Vendor,
observation.Upstream.FetchedAt,
observation.Linkset.Aliases,
observation.Linkset.Purls,
observation.Linkset.Cpes,
observation.Linkset.References.Select(r => r.Url).ToArray()));
}
var (confidence, conflicts) = LinksetCorrelation.Compute(correlationInputs);
return new AdvisoryObservationLinksetAggregate(
aliasSet.OrderBy(static alias => alias, StringComparer.Ordinal).ToImmutableArray(),
purlSet.OrderBy(static purl => purl, StringComparer.Ordinal).ToImmutableArray(),

View File

@@ -0,0 +1,12 @@
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Concelier.Core.Observations;
/// <summary>
/// Transports advisory.observation.updated@1 events from the outbox to external subscribers (e.g., NATS).
/// </summary>
public interface IAdvisoryObservationEventTransport
{
Task SendAsync(AdvisoryObservationUpdatedEvent @event, CancellationToken cancellationToken);
}

View File

@@ -108,5 +108,10 @@ public sealed class AdvisoryLinksetConflictDocument
[BsonElement("values")]
[BsonIgnoreIfNull]
public List<string>? Values { get; set; }
= null;
= new();
[BsonElement("sourceIds")]
[BsonIgnoreIfNull]
public List<string>? SourceIds { get; set; }
= new();
}

View File

@@ -111,7 +111,8 @@ internal sealed class ConcelierMongoLinksetStore : IMongoAdvisoryLinksetStore
{
Field = conflict.Field,
Reason = conflict.Reason,
Values = conflict.Values is null ? null : new List<string>(conflict.Values)
Values = conflict.Values is null ? null : new List<string>(conflict.Values),
SourceIds = conflict.SourceIds is null ? null : new List<string>(conflict.SourceIds)
}).ToList(),
Provenance = linkset.Provenance is null ? null : new AdvisoryLinksetProvenanceDocument
{
@@ -153,7 +154,8 @@ internal sealed class ConcelierMongoLinksetStore : IMongoAdvisoryLinksetStore
: doc.Conflicts.Select(conflict => new CoreLinksets.AdvisoryLinksetConflict(
conflict.Field,
conflict.Reason,
conflict.Values)).ToList(),
conflict.Values,
conflict.SourceIds)).ToList(),
DateTime.SpecifyKind(doc.CreatedAt, DateTimeKind.Utc),
doc.BuiltByJobId);
}

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Driver;
using StellaOps.Concelier.Storage.Mongo.Orchestrator;
namespace StellaOps.Concelier.Storage.Mongo.Migrations;
internal sealed class EnsureOrchestratorCollectionsMigration : IMongoMigration
{
public string Id => "20251122_orchestrator_registry_commands";
public string Description => "Ensure orchestrator registry, commands, and heartbeats collections exist with indexes";
public async Task ApplyAsync(IMongoDatabase database, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(database);
await EnsureRegistryAsync(database, cancellationToken).ConfigureAwait(false);
await EnsureCommandsAsync(database, cancellationToken).ConfigureAwait(false);
await EnsureHeartbeatsAsync(database, cancellationToken).ConfigureAwait(false);
}
private static async Task EnsureRegistryAsync(IMongoDatabase database, CancellationToken ct)
{
var name = MongoStorageDefaults.Collections.OrchestratorRegistry;
await EnsureCollectionAsync(database, name, ct).ConfigureAwait(false);
var collection = database.GetCollection<BsonDocument>(name);
var indexes = new List<CreateIndexModel<BsonDocument>>
{
new(new BsonDocument
{
{"tenant", 1},
{"connectorId", 1},
}, new CreateIndexOptions { Name = "orch_registry_tenant_connector", Unique = true }),
new(new BsonDocument
{
{"source", 1},
}, new CreateIndexOptions { Name = "orch_registry_source" }),
};
await collection.Indexes.CreateManyAsync(indexes, cancellationToken: ct).ConfigureAwait(false);
}
private static async Task EnsureCommandsAsync(IMongoDatabase database, CancellationToken ct)
{
var name = MongoStorageDefaults.Collections.OrchestratorCommands;
await EnsureCollectionAsync(database, name, ct).ConfigureAwait(false);
var collection = database.GetCollection<BsonDocument>(name);
var indexes = new List<CreateIndexModel<BsonDocument>>
{
new(new BsonDocument
{
{"tenant", 1},
{"connectorId", 1},
{"runId", 1},
{"sequence", 1},
}, new CreateIndexOptions { Name = "orch_cmd_tenant_connector_run_seq" }),
new(new BsonDocument { {"expiresAt", 1} }, new CreateIndexOptions
{
Name = "orch_cmd_expiresAt_ttl",
ExpireAfter = TimeSpan.FromSeconds(0),
})
};
await collection.Indexes.CreateManyAsync(indexes, cancellationToken: ct).ConfigureAwait(false);
}
private static async Task EnsureHeartbeatsAsync(IMongoDatabase database, CancellationToken ct)
{
var name = MongoStorageDefaults.Collections.OrchestratorHeartbeats;
await EnsureCollectionAsync(database, name, ct).ConfigureAwait(false);
var collection = database.GetCollection<BsonDocument>(name);
var indexes = new List<CreateIndexModel<BsonDocument>>
{
new(new BsonDocument
{
{"tenant", 1},
{"connectorId", 1},
{"runId", 1},
{"sequence", 1},
}, new CreateIndexOptions { Name = "orch_hb_tenant_connector_run_seq" }),
new(new BsonDocument { {"timestamp", -1} }, new CreateIndexOptions { Name = "orch_hb_timestamp_desc" })
};
await collection.Indexes.CreateManyAsync(indexes, cancellationToken: ct).ConfigureAwait(false);
}
private static async Task EnsureCollectionAsync(IMongoDatabase database, string collectionName, CancellationToken ct)
{
var filter = new BsonDocument("name", collectionName);
using var cursor = await database.ListCollectionsAsync(new ListCollectionsOptions { Filter = filter }, ct).ConfigureAwait(false);
var exists = await cursor.AnyAsync(ct).ConfigureAwait(false);
if (!exists)
{
await database.CreateCollectionAsync(collectionName, cancellationToken: ct).ConfigureAwait(false);
}
}
}

View File

@@ -30,5 +30,8 @@ public static class MongoStorageDefaults
public const string AdvisoryObservations = "advisory_observations";
public const string AdvisoryLinksets = "advisory_linksets";
public const string AdvisoryObservationEvents = "advisory_observation_events";
public const string OrchestratorRegistry = "orchestrator_registry";
public const string OrchestratorCommands = "orchestrator_commands";
public const string OrchestratorHeartbeats = "orchestrator_heartbeats";
}
}

View File

@@ -11,18 +11,18 @@ namespace StellaOps.Concelier.Storage.Mongo.Observations;
internal sealed class AdvisoryObservationTransportWorker : BackgroundService
{
private readonly IAdvisoryObservationEventOutbox _outbox;
private readonly IAdvisoryObservationEventPublisher _publisher;
private readonly IAdvisoryObservationEventTransport _transport;
private readonly ILogger<AdvisoryObservationTransportWorker> _logger;
private readonly AdvisoryObservationEventPublisherOptions _options;
public AdvisoryObservationTransportWorker(
IAdvisoryObservationEventOutbox outbox,
IAdvisoryObservationEventPublisher publisher,
IAdvisoryObservationEventTransport transport,
IOptions<AdvisoryObservationEventPublisherOptions> options,
ILogger<AdvisoryObservationTransportWorker> logger)
{
_outbox = outbox ?? throw new ArgumentNullException(nameof(outbox));
_publisher = publisher ?? throw new ArgumentNullException(nameof(publisher));
_transport = transport ?? throw new ArgumentNullException(nameof(transport));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_options = options.Value;
}
@@ -48,7 +48,7 @@ internal sealed class AdvisoryObservationTransportWorker : BackgroundService
foreach (var evt in batch)
{
await _publisher.PublishAsync(evt, stoppingToken).ConfigureAwait(false);
await _transport.SendAsync(evt, stoppingToken).ConfigureAwait(false);
await _outbox.MarkPublishedAsync(evt.EventId, DateTimeOffset.UtcNow, stoppingToken).ConfigureAwait(false);
}
}

View File

@@ -12,7 +12,7 @@ using StellaOps.Concelier.Core.Observations;
namespace StellaOps.Concelier.Storage.Mongo.Observations;
internal sealed class NatsAdvisoryObservationEventPublisher : IAdvisoryObservationEventPublisher
internal sealed class NatsAdvisoryObservationEventPublisher : IAdvisoryObservationEventTransport
{
private readonly ILogger<NatsAdvisoryObservationEventPublisher> _logger;
private readonly AdvisoryObservationEventPublisherOptions _options;
@@ -26,7 +26,7 @@ internal sealed class NatsAdvisoryObservationEventPublisher : IAdvisoryObservati
_options = options.Value;
}
public async Task PublishAsync(AdvisoryObservationUpdatedEvent @event, CancellationToken cancellationToken)
public async Task SendAsync(AdvisoryObservationUpdatedEvent @event, CancellationToken cancellationToken)
{
if (!_options.Enabled)
{

View File

@@ -0,0 +1,15 @@
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Concelier.Core.Observations;
namespace StellaOps.Concelier.Storage.Mongo.Observations;
internal sealed class NullAdvisoryObservationEventTransport : IAdvisoryObservationEventTransport
{
public static readonly NullAdvisoryObservationEventTransport Instance = new();
private NullAdvisoryObservationEventTransport() { }
public Task SendAsync(AdvisoryObservationUpdatedEvent @event, CancellationToken cancellationToken)
=> Task.CompletedTask;
}

View File

@@ -0,0 +1,19 @@
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
public interface IOrchestratorRegistryStore
{
Task UpsertAsync(OrchestratorRegistryRecord record, CancellationToken cancellationToken);
Task<OrchestratorRegistryRecord?> GetAsync(string tenant, string connectorId, CancellationToken cancellationToken);
Task EnqueueCommandAsync(OrchestratorCommandRecord command, CancellationToken cancellationToken);
Task<IReadOnlyList<OrchestratorCommandRecord>> GetPendingCommandsAsync(
string tenant,
string connectorId,
Guid runId,
long? afterSequence,
CancellationToken cancellationToken);
Task AppendHeartbeatAsync(OrchestratorHeartbeatRecord heartbeat, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,94 @@
using System;
using System.Linq;
using MongoDB.Driver;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
public sealed class MongoOrchestratorRegistryStore : IOrchestratorRegistryStore
{
private readonly IMongoCollection<OrchestratorRegistryDocument> _registry;
private readonly IMongoCollection<OrchestratorCommandDocument> _commands;
private readonly IMongoCollection<OrchestratorHeartbeatDocument> _heartbeats;
public MongoOrchestratorRegistryStore(
IMongoCollection<OrchestratorRegistryDocument> registry,
IMongoCollection<OrchestratorCommandDocument> commands,
IMongoCollection<OrchestratorHeartbeatDocument> heartbeats)
{
_registry = registry ?? throw new ArgumentNullException(nameof(registry));
_commands = commands ?? throw new ArgumentNullException(nameof(commands));
_heartbeats = heartbeats ?? throw new ArgumentNullException(nameof(heartbeats));
}
public async Task UpsertAsync(OrchestratorRegistryRecord record, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(record);
var document = OrchestratorRegistryDocumentExtensions.FromRecord(record);
var filter = Builders<OrchestratorRegistryDocument>.Filter.And(
Builders<OrchestratorRegistryDocument>.Filter.Eq(x => x.Tenant, record.Tenant),
Builders<OrchestratorRegistryDocument>.Filter.Eq(x => x.ConnectorId, record.ConnectorId));
var options = new ReplaceOptions { IsUpsert = true };
await _registry.ReplaceOneAsync(filter, document, options, cancellationToken).ConfigureAwait(false);
}
public async Task<OrchestratorRegistryRecord?> GetAsync(string tenant, string connectorId, CancellationToken cancellationToken)
{
var filter = Builders<OrchestratorRegistryDocument>.Filter.And(
Builders<OrchestratorRegistryDocument>.Filter.Eq(x => x.Tenant, tenant),
Builders<OrchestratorRegistryDocument>.Filter.Eq(x => x.ConnectorId, connectorId));
var document = await _registry
.Find(filter)
.FirstOrDefaultAsync(cancellationToken)
.ConfigureAwait(false);
return document?.ToRecord();
}
public async Task EnqueueCommandAsync(OrchestratorCommandRecord command, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(command);
var document = OrchestratorCommandDocumentExtensions.FromRecord(command);
await _commands.InsertOneAsync(document, cancellationToken: cancellationToken).ConfigureAwait(false);
}
public async Task<IReadOnlyList<OrchestratorCommandRecord>> GetPendingCommandsAsync(
string tenant,
string connectorId,
Guid runId,
long? afterSequence,
CancellationToken cancellationToken)
{
var filter = Builders<OrchestratorCommandDocument>.Filter.And(
Builders<OrchestratorCommandDocument>.Filter.Eq(x => x.Tenant, tenant),
Builders<OrchestratorCommandDocument>.Filter.Eq(x => x.ConnectorId, connectorId),
Builders<OrchestratorCommandDocument>.Filter.Eq(x => x.RunId, runId));
if (afterSequence.HasValue)
{
filter &= Builders<OrchestratorCommandDocument>.Filter.Gt(x => x.Sequence, afterSequence.Value);
}
var results = await _commands
.Find(filter)
.Sort(Builders<OrchestratorCommandDocument>.Sort.Ascending(x => x.Sequence))
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
return results
.Select(static c => c.ToRecord())
.ToArray();
}
public async Task AppendHeartbeatAsync(OrchestratorHeartbeatRecord heartbeat, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(heartbeat);
var document = OrchestratorHeartbeatDocumentExtensions.FromRecord(heartbeat);
await _heartbeats.InsertOneAsync(document, cancellationToken: cancellationToken).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,141 @@
using System;
using System.Globalization;
using MongoDB.Bson.Serialization.Attributes;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
[BsonIgnoreExtraElements]
public sealed class OrchestratorCommandDocument
{
[BsonId]
public string Id { get; set; } = string.Empty;
[BsonElement("tenant")]
public string Tenant { get; set; } = string.Empty;
[BsonElement("connectorId")]
public string ConnectorId { get; set; } = string.Empty;
[BsonElement("runId")]
public Guid RunId { get; set; }
= Guid.Empty;
[BsonElement("sequence")]
public long Sequence { get; set; }
= 0;
[BsonElement("command")]
public OrchestratorCommandKind Command { get; set; }
= OrchestratorCommandKind.Pause;
[BsonElement("throttle")]
public OrchestratorThrottleOverrideDocument? Throttle { get; set; }
= null;
[BsonElement("backfill")]
public OrchestratorBackfillRangeDocument? Backfill { get; set; }
= null;
[BsonElement("createdAt")]
public DateTime CreatedAt { get; set; }
= DateTime.SpecifyKind(DateTime.UnixEpoch, DateTimeKind.Utc);
[BsonElement("expiresAt")]
public DateTime? ExpiresAt { get; set; }
= null;
}
[BsonIgnoreExtraElements]
public sealed class OrchestratorThrottleOverrideDocument
{
[BsonElement("rpm")]
public int? Rpm { get; set; }
= null;
[BsonElement("burst")]
public int? Burst { get; set; }
= null;
[BsonElement("cooldownSeconds")]
public int? CooldownSeconds { get; set; }
= null;
[BsonElement("expiresAt")]
public DateTime? ExpiresAt { get; set; }
= null;
}
[BsonIgnoreExtraElements]
public sealed class OrchestratorBackfillRangeDocument
{
[BsonElement("fromCursor")]
public string? FromCursor { get; set; }
= null;
[BsonElement("toCursor")]
public string? ToCursor { get; set; }
= null;
}
internal static class OrchestratorCommandDocumentExtensions
{
public static OrchestratorCommandDocument FromRecord(OrchestratorCommandRecord record)
{
ArgumentNullException.ThrowIfNull(record);
return new OrchestratorCommandDocument
{
Id = BuildId(record.Tenant, record.ConnectorId, record.RunId, record.Sequence),
Tenant = record.Tenant,
ConnectorId = record.ConnectorId,
RunId = record.RunId,
Sequence = record.Sequence,
Command = record.Command,
Throttle = record.Throttle is null
? null
: new OrchestratorThrottleOverrideDocument
{
Rpm = record.Throttle.Rpm,
Burst = record.Throttle.Burst,
CooldownSeconds = record.Throttle.CooldownSeconds,
ExpiresAt = record.Throttle.ExpiresAt?.UtcDateTime,
},
Backfill = record.Backfill is null
? null
: new OrchestratorBackfillRangeDocument
{
FromCursor = record.Backfill.FromCursor,
ToCursor = record.Backfill.ToCursor,
},
CreatedAt = record.CreatedAt.UtcDateTime,
ExpiresAt = record.ExpiresAt?.UtcDateTime,
};
}
public static OrchestratorCommandRecord ToRecord(this OrchestratorCommandDocument document)
{
ArgumentNullException.ThrowIfNull(document);
return new OrchestratorCommandRecord(
document.Tenant,
document.ConnectorId,
document.RunId,
document.Sequence,
document.Command,
document.Throttle is null
? null
: new OrchestratorThrottleOverride(
document.Throttle.Rpm,
document.Throttle.Burst,
document.Throttle.CooldownSeconds,
document.Throttle.ExpiresAt is null ? null : DateTime.SpecifyKind(document.Throttle.ExpiresAt.Value, DateTimeKind.Utc)),
document.Backfill is null
? null
: new OrchestratorBackfillRange(document.Backfill.FromCursor, document.Backfill.ToCursor),
DateTime.SpecifyKind(document.CreatedAt, DateTimeKind.Utc),
document.ExpiresAt is null ? null : DateTime.SpecifyKind(document.ExpiresAt.Value, DateTimeKind.Utc));
}
private static string BuildId(string tenant, string connectorId, Guid runId, long sequence)
=> string.Create(CultureInfo.InvariantCulture, $"{tenant}:{connectorId}:{runId}:{sequence}");
}

View File

@@ -0,0 +1,26 @@
using System;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
public sealed record OrchestratorCommandRecord(
string Tenant,
string ConnectorId,
Guid RunId,
long Sequence,
OrchestratorCommandKind Command,
OrchestratorThrottleOverride? Throttle,
OrchestratorBackfillRange? Backfill,
DateTimeOffset CreatedAt,
DateTimeOffset? ExpiresAt);
public enum OrchestratorCommandKind
{
Pause,
Resume,
Throttle,
Backfill,
}
public sealed record OrchestratorThrottleOverride(int? Rpm, int? Burst, int? CooldownSeconds, DateTimeOffset? ExpiresAt);
public sealed record OrchestratorBackfillRange(string? FromCursor, string? ToCursor);

View File

@@ -0,0 +1,105 @@
using System;
using System.Globalization;
using MongoDB.Bson.Serialization.Attributes;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
[BsonIgnoreExtraElements]
public sealed class OrchestratorHeartbeatDocument
{
[BsonId]
public string Id { get; set; } = string.Empty;
[BsonElement("tenant")]
public string Tenant { get; set; } = string.Empty;
[BsonElement("connectorId")]
public string ConnectorId { get; set; } = string.Empty;
[BsonElement("runId")]
public Guid RunId { get; set; }
= Guid.Empty;
[BsonElement("sequence")]
public long Sequence { get; set; }
= 0;
[BsonElement("status")]
public OrchestratorHeartbeatStatus Status { get; set; }
= OrchestratorHeartbeatStatus.Starting;
[BsonElement("progress")]
public int? Progress { get; set; }
= null;
[BsonElement("queueDepth")]
public int? QueueDepth { get; set; }
= null;
[BsonElement("lastArtifactHash")]
public string? LastArtifactHash { get; set; }
= null;
[BsonElement("lastArtifactKind")]
public string? LastArtifactKind { get; set; }
= null;
[BsonElement("errorCode")]
public string? ErrorCode { get; set; }
= null;
[BsonElement("retryAfterSeconds")]
public int? RetryAfterSeconds { get; set; }
= null;
[BsonElement("timestamp")]
public DateTime Timestamp { get; set; }
= DateTime.SpecifyKind(DateTime.UnixEpoch, DateTimeKind.Utc);
}
internal static class OrchestratorHeartbeatDocumentExtensions
{
public static OrchestratorHeartbeatDocument FromRecord(OrchestratorHeartbeatRecord record)
{
ArgumentNullException.ThrowIfNull(record);
return new OrchestratorHeartbeatDocument
{
Id = BuildId(record.Tenant, record.ConnectorId, record.RunId, record.Sequence),
Tenant = record.Tenant,
ConnectorId = record.ConnectorId,
RunId = record.RunId,
Sequence = record.Sequence,
Status = record.Status,
Progress = record.Progress,
QueueDepth = record.QueueDepth,
LastArtifactHash = record.LastArtifactHash,
LastArtifactKind = record.LastArtifactKind,
ErrorCode = record.ErrorCode,
RetryAfterSeconds = record.RetryAfterSeconds,
Timestamp = record.TimestampUtc.UtcDateTime,
};
}
public static OrchestratorHeartbeatRecord ToRecord(this OrchestratorHeartbeatDocument document)
{
ArgumentNullException.ThrowIfNull(document);
return new OrchestratorHeartbeatRecord(
document.Tenant,
document.ConnectorId,
document.RunId,
document.Sequence,
document.Status,
document.Progress,
document.QueueDepth,
document.LastArtifactHash,
document.LastArtifactKind,
document.ErrorCode,
document.RetryAfterSeconds,
DateTime.SpecifyKind(document.Timestamp, DateTimeKind.Utc));
}
private static string BuildId(string tenant, string connectorId, Guid runId, long sequence)
=> string.Create(CultureInfo.InvariantCulture, $"{tenant}:{connectorId}:{runId}:{sequence}");
}

View File

@@ -0,0 +1,28 @@
using System;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
public sealed record OrchestratorHeartbeatRecord(
string Tenant,
string ConnectorId,
Guid RunId,
long Sequence,
OrchestratorHeartbeatStatus Status,
int? Progress,
int? QueueDepth,
string? LastArtifactHash,
string? LastArtifactKind,
string? ErrorCode,
int? RetryAfterSeconds,
DateTimeOffset TimestampUtc);
public enum OrchestratorHeartbeatStatus
{
Starting,
Running,
Paused,
Throttled,
Backfill,
Failed,
Succeeded,
}

View File

@@ -0,0 +1,165 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using MongoDB.Bson.Serialization.Attributes;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
[BsonIgnoreExtraElements]
public sealed class OrchestratorRegistryDocument
{
[BsonId]
public string Id { get; set; } = string.Empty;
[BsonElement("tenant")]
public string Tenant { get; set; } = string.Empty;
[BsonElement("connectorId")]
public string ConnectorId { get; set; } = string.Empty;
[BsonElement("source")]
public string Source { get; set; } = string.Empty;
[BsonElement("capabilities")]
public IReadOnlyCollection<string> Capabilities { get; set; } = Array.Empty<string>();
[BsonElement("authRef")]
public string AuthRef { get; set; } = string.Empty;
[BsonElement("schedule")]
public OrchestratorScheduleDocument Schedule { get; set; } = new();
[BsonElement("ratePolicy")]
public OrchestratorRatePolicyDocument RatePolicy { get; set; } = new();
[BsonElement("artifactKinds")]
public IReadOnlyCollection<string> ArtifactKinds { get; set; } = Array.Empty<string>();
[BsonElement("lockKey")]
public string LockKey { get; set; } = string.Empty;
[BsonElement("egressGuard")]
public OrchestratorEgressGuardDocument EgressGuard { get; set; } = new();
[BsonElement("createdAt")]
public DateTime CreatedAt { get; set; }
= DateTime.SpecifyKind(DateTime.UnixEpoch, DateTimeKind.Utc);
[BsonElement("updatedAt")]
public DateTime UpdatedAt { get; set; }
= DateTime.SpecifyKind(DateTime.UnixEpoch, DateTimeKind.Utc);
}
[BsonIgnoreExtraElements]
public sealed class OrchestratorScheduleDocument
{
[BsonElement("cron")]
public string Cron { get; set; } = string.Empty;
[BsonElement("timeZone")]
public string TimeZone { get; set; } = "UTC";
[BsonElement("maxParallelRuns")]
public int MaxParallelRuns { get; set; }
= 1;
[BsonElement("maxLagMinutes")]
public int MaxLagMinutes { get; set; }
= 0;
}
[BsonIgnoreExtraElements]
public sealed class OrchestratorRatePolicyDocument
{
[BsonElement("rpm")]
public int Rpm { get; set; }
= 0;
[BsonElement("burst")]
public int Burst { get; set; }
= 0;
[BsonElement("cooldownSeconds")]
public int CooldownSeconds { get; set; }
= 0;
}
[BsonIgnoreExtraElements]
public sealed class OrchestratorEgressGuardDocument
{
[BsonElement("allowlist")]
public IReadOnlyCollection<string> Allowlist { get; set; } = Array.Empty<string>();
[BsonElement("airgapMode")]
public bool AirgapMode { get; set; }
= true;
}
internal static class OrchestratorRegistryDocumentExtensions
{
public static OrchestratorRegistryDocument FromRecord(OrchestratorRegistryRecord record)
{
ArgumentNullException.ThrowIfNull(record);
return new OrchestratorRegistryDocument
{
Id = BuildId(record.Tenant, record.ConnectorId),
Tenant = record.Tenant,
ConnectorId = record.ConnectorId,
Source = record.Source,
Capabilities = record.Capabilities,
AuthRef = record.AuthRef,
Schedule = new OrchestratorScheduleDocument
{
Cron = record.Schedule.Cron,
TimeZone = record.Schedule.TimeZone,
MaxParallelRuns = record.Schedule.MaxParallelRuns,
MaxLagMinutes = record.Schedule.MaxLagMinutes,
},
RatePolicy = new OrchestratorRatePolicyDocument
{
Rpm = record.RatePolicy.Rpm,
Burst = record.RatePolicy.Burst,
CooldownSeconds = record.RatePolicy.CooldownSeconds,
},
ArtifactKinds = record.ArtifactKinds,
LockKey = record.LockKey,
EgressGuard = new OrchestratorEgressGuardDocument
{
Allowlist = record.EgressGuard.Allowlist,
AirgapMode = record.EgressGuard.AirgapMode,
},
CreatedAt = record.CreatedAt.UtcDateTime,
UpdatedAt = record.UpdatedAt.UtcDateTime,
};
}
public static OrchestratorRegistryRecord ToRecord(this OrchestratorRegistryDocument document)
{
ArgumentNullException.ThrowIfNull(document);
return new OrchestratorRegistryRecord(
document.Tenant,
document.ConnectorId,
document.Source,
document.Capabilities,
document.AuthRef,
new OrchestratorSchedule(
document.Schedule.Cron,
document.Schedule.TimeZone,
document.Schedule.MaxParallelRuns,
document.Schedule.MaxLagMinutes),
new OrchestratorRatePolicy(
document.RatePolicy.Rpm,
document.RatePolicy.Burst,
document.RatePolicy.CooldownSeconds),
document.ArtifactKinds,
document.LockKey,
new OrchestratorEgressGuard(document.EgressGuard.Allowlist, document.EgressGuard.AirgapMode),
DateTime.SpecifyKind(document.CreatedAt, DateTimeKind.Utc),
DateTime.SpecifyKind(document.UpdatedAt, DateTimeKind.Utc));
}
private static string BuildId(string tenant, string connectorId)
=> string.Create(CultureInfo.InvariantCulture, $"{tenant}:{connectorId}");
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
namespace StellaOps.Concelier.Storage.Mongo.Orchestrator;
public sealed record OrchestratorRegistryRecord(
string Tenant,
string ConnectorId,
string Source,
IReadOnlyCollection<string> Capabilities,
string AuthRef,
OrchestratorSchedule Schedule,
OrchestratorRatePolicy RatePolicy,
IReadOnlyCollection<string> ArtifactKinds,
string LockKey,
OrchestratorEgressGuard EgressGuard,
DateTimeOffset CreatedAt,
DateTimeOffset UpdatedAt);
public sealed record OrchestratorSchedule(
string Cron,
string TimeZone,
int MaxParallelRuns,
int MaxLagMinutes);
public sealed record OrchestratorRatePolicy(
int Rpm,
int Burst,
int CooldownSeconds);
public sealed record OrchestratorEgressGuard(
IReadOnlyCollection<string> Allowlist,
bool AirgapMode);

View File

@@ -23,6 +23,7 @@ using StellaOps.Concelier.Storage.Mongo.Migrations;
using StellaOps.Concelier.Storage.Mongo.Observations;
using StellaOps.Concelier.Core.Observations;
using StellaOps.Concelier.Storage.Mongo.Linksets;
using StellaOps.Concelier.Storage.Mongo.Orchestrator;
namespace StellaOps.Concelier.Storage.Mongo;
@@ -81,17 +82,17 @@ public static class ServiceCollectionExtensions
services.AddSingleton<IAdvisoryObservationLookup, AdvisoryObservationLookup>();
services.AddSingleton<IAdvisoryEventRepository, MongoAdvisoryEventRepository>();
services.AddSingleton<IAdvisoryEventLog, AdvisoryEventLog>();
services.AddSingleton<MongoAdvisoryObservationEventPublisher>();
services.AddSingleton<IAdvisoryObservationEventPublisher, MongoAdvisoryObservationEventPublisher>();
services.AddSingleton<NatsAdvisoryObservationEventPublisher>();
services.AddSingleton<IAdvisoryObservationEventPublisher>(sp =>
services.AddSingleton<IAdvisoryObservationEventTransport>(sp =>
{
var options = sp.GetRequiredService<IOptions<AdvisoryObservationEventPublisherOptions>>().Value;
if (string.Equals(options.Transport, "nats", StringComparison.OrdinalIgnoreCase))
if (options.Enabled && string.Equals(options.Transport, "nats", StringComparison.OrdinalIgnoreCase))
{
return sp.GetRequiredService<NatsAdvisoryObservationEventPublisher>();
}
return sp.GetRequiredService<MongoAdvisoryObservationEventPublisher>();
return NullAdvisoryObservationEventTransport.Instance;
});
services.AddSingleton<IAdvisoryObservationEventOutbox, MongoAdvisoryObservationEventOutbox>();
services.AddSingleton<IAdvisoryRawRepository, MongoAdvisoryRawRepository>();
@@ -129,6 +130,24 @@ public static class ServiceCollectionExtensions
return database.GetCollection<AdvisoryObservationEventDocument>(MongoStorageDefaults.Collections.AdvisoryObservationEvents);
});
services.AddSingleton<IMongoCollection<OrchestratorRegistryDocument>>(static sp =>
{
var database = sp.GetRequiredService<IMongoDatabase>();
return database.GetCollection<OrchestratorRegistryDocument>(MongoStorageDefaults.Collections.OrchestratorRegistry);
});
services.AddSingleton<IMongoCollection<OrchestratorCommandDocument>>(static sp =>
{
var database = sp.GetRequiredService<IMongoDatabase>();
return database.GetCollection<OrchestratorCommandDocument>(MongoStorageDefaults.Collections.OrchestratorCommands);
});
services.AddSingleton<IMongoCollection<OrchestratorHeartbeatDocument>>(static sp =>
{
var database = sp.GetRequiredService<IMongoDatabase>();
return database.GetCollection<OrchestratorHeartbeatDocument>(MongoStorageDefaults.Collections.OrchestratorHeartbeats);
});
services.AddSingleton<IMongoCollection<AdvisoryLinksetDocument>>(static sp =>
{
var database = sp.GetRequiredService<IMongoDatabase>();
@@ -136,6 +155,7 @@ public static class ServiceCollectionExtensions
});
services.AddHostedService<RawDocumentRetentionService>();
services.AddHostedService<AdvisoryObservationTransportWorker>();
services.AddSingleton<MongoMigrationRunner>();
services.AddSingleton<IMongoMigration, EnsureDocumentExpiryIndexesMigration>();
@@ -149,9 +169,12 @@ public static class ServiceCollectionExtensions
services.AddSingleton<IMongoMigration, EnsureAdvisoryEventCollectionsMigration>();
services.AddSingleton<IMongoMigration, EnsureAdvisoryObservationEventCollectionMigration>();
services.AddSingleton<IMongoMigration, SemVerStyleBackfillMigration>();
services.AddSingleton<IMongoMigration, EnsureOrchestratorCollectionsMigration>();
services.AddSingleton<IOrchestratorRegistryStore, MongoOrchestratorRegistryStore>();
services.AddSingleton<IHostedService, AdvisoryObservationTransportWorker>();
return services;
}
}
}

View File

@@ -60,6 +60,44 @@ public sealed class AdvisoryObservationAggregationTests
Assert.Null(normalized); // no purls supplied
}
[Fact]
public void BuildAggregateLinkset_ComputesConflictsAndConfidenceFromObservations()
{
var obsA = CreateObservation(
"obs-a",
new RawLinkset
{
Aliases = ImmutableArray.Create("CVE-2025-0001"),
PackageUrls = ImmutableArray.Create("pkg:npm/foo@1.0.0"),
References = ImmutableArray.Create(new RawReference("advisory", "https://a.example/advisory"))
},
fetchedAt: DateTimeOffset.UtcNow.AddHours(-1),
vendor: "vendor-a");
var obsB = CreateObservation(
"obs-b",
new RawLinkset
{
Aliases = ImmutableArray.Create("GHSA-xxxx-xxxx"),
PackageUrls = ImmutableArray.Create("pkg:npm/foo@2.0.0"),
References = ImmutableArray.Create(new RawReference("advisory", "https://b.example/advisory"))
},
fetchedAt: DateTimeOffset.UtcNow,
vendor: "vendor-b");
var method = typeof(AdvisoryObservationQueryService).GetMethod(
"BuildAggregateLinkset",
BindingFlags.NonPublic | BindingFlags.Static)!;
var aggregate = (AdvisoryObservationLinksetAggregate)method.Invoke(
null,
new object?[] { ImmutableArray.Create(obsA, obsB) })!;
Assert.Contains(aggregate.Conflicts, c => c.Reason == "alias-inconsistency");
Assert.Contains(aggregate.Conflicts, c => c.Reason == "affected-range-divergence");
Assert.True(aggregate.Confidence is > 0.0 and < 1.0);
}
[Fact]
public void BuildAggregateLinkset_EmptyInputReturnsEmptyArrays()
{
@@ -75,13 +113,17 @@ public sealed class AdvisoryObservationAggregationTests
Assert.True(aggregate.Relationships.IsEmpty);
}
private static AdvisoryObservation CreateObservation(string id, RawLinkset rawLinkset)
private static AdvisoryObservation CreateObservation(
string id,
RawLinkset rawLinkset,
DateTimeOffset? fetchedAt = null,
string vendor = "vendor")
{
var source = new AdvisoryObservationSource("vendor", "stream", "api");
var source = new AdvisoryObservationSource(vendor, "stream", "api");
var upstream = new AdvisoryObservationUpstream(
"adv-id",
null,
DateTimeOffset.UtcNow,
(fetchedAt ?? DateTimeOffset.UtcNow),
DateTimeOffset.UtcNow,
"sha256:abc",
new AdvisoryObservationSignature(false, null, null, null));

View File

@@ -36,7 +36,7 @@ public sealed class ConcelierMongoLinksetStoreTests : IClassFixture<MongoIntegra
0.82,
new List<AdvisoryLinksetConflict>
{
new("severity", "disagree", new[] { "HIGH", "MEDIUM" })
new("severity", "disagree", new[] { "HIGH", "MEDIUM" }, new[] { "source-a", "source-b" })
},
DateTimeOffset.UtcNow,
"job-1");
@@ -54,6 +54,7 @@ public sealed class ConcelierMongoLinksetStoreTests : IClassFixture<MongoIntegra
Assert.Single(document.Conflicts!);
Assert.Equal("severity", document.Conflicts![0].Field);
Assert.Equal("disagree", document.Conflicts![0].Reason);
Assert.Equal(new[] { "source-a", "source-b" }, document.Conflicts![0].SourceIds);
}
[Fact]
@@ -72,7 +73,8 @@ public sealed class ConcelierMongoLinksetStoreTests : IClassFixture<MongoIntegra
{
Field = "references",
Reason = "mismatch",
Values = new List<string> { "url1", "url2" }
Values = new List<string> { "url1", "url2" },
SourceIds = new List<string> { "src-a", "src-b" }
}
},
CreatedAt = DateTime.UtcNow
@@ -90,6 +92,7 @@ public sealed class ConcelierMongoLinksetStoreTests : IClassFixture<MongoIntegra
Assert.NotNull(model.Conflicts);
Assert.Single(model.Conflicts!);
Assert.Equal("references", model.Conflicts![0].Field);
Assert.Equal(new[] { "src-a", "src-b" }, model.Conflicts![0].SourceIds);
}
[Fact]

View File

@@ -0,0 +1,100 @@
using System;
using System.Collections.Immutable;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using StellaOps.Concelier.Core.Observations;
using StellaOps.Concelier.Storage.Mongo.Observations;
using StellaOps.Concelier.Models.Observations;
using Xunit;
namespace StellaOps.Concelier.Storage.Mongo.Tests.Observations;
public class AdvisoryObservationTransportWorkerTests
{
[Fact]
public async Task Worker_publishes_outbox_entries_and_marks_published_once()
{
var evt = new AdvisoryObservationUpdatedEvent(
Guid.NewGuid(),
"tenant-1",
"obs-1",
"adv-1",
new Models.Observations.AdvisoryObservationSource("vendor", "stream", "api", "1.0.0"),
new AdvisoryObservationLinksetSummary(
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<AdvisoryObservationRelationshipSummary>.Empty),
"doc-sha",
"hash-1",
DateTimeOffset.UtcNow,
ReplayCursor: "cursor-1",
supersedesId: null,
traceId: "trace-1");
var outbox = new FakeOutbox(evt);
var transport = new FakeTransport();
var options = Options.Create(new AdvisoryObservationEventPublisherOptions
{
Enabled = true,
Transport = "nats",
Subject = "subject",
Stream = "stream",
NatsUrl = "nats://localhost:4222"
});
var worker = new AdvisoryObservationTransportWorker(outbox, transport, options, NullLogger<AdvisoryObservationTransportWorker>.Instance);
await worker.StartAsync(CancellationToken.None);
await Task.Delay(150, CancellationToken.None);
await worker.StopAsync(CancellationToken.None);
Assert.Equal(1, transport.Sent.Count);
Assert.Equal(evt.EventId, transport.Sent[0].EventId);
Assert.Equal(1, outbox.MarkedCount);
}
private sealed class FakeOutbox : IAdvisoryObservationEventOutbox
{
private readonly AdvisoryObservationUpdatedEvent _event;
private bool _dequeued;
public int MarkedCount { get; private set; }
public FakeOutbox(AdvisoryObservationUpdatedEvent @event)
{
_event = @event;
}
public Task<IReadOnlyCollection<AdvisoryObservationUpdatedEvent>> DequeueAsync(int take, CancellationToken cancellationToken)
{
if (_dequeued)
{
return Task.FromResult<IReadOnlyCollection<AdvisoryObservationUpdatedEvent>>(Array.Empty<AdvisoryObservationUpdatedEvent>());
}
_dequeued = true;
return Task.FromResult<IReadOnlyCollection<AdvisoryObservationUpdatedEvent>>(new[] { _event });
}
public Task MarkPublishedAsync(Guid eventId, DateTimeOffset publishedAt, CancellationToken cancellationToken)
{
MarkedCount++;
return Task.CompletedTask;
}
}
private sealed class FakeTransport : IAdvisoryObservationEventTransport
{
public List<AdvisoryObservationUpdatedEvent> Sent { get; } = new();
public Task SendAsync(AdvisoryObservationUpdatedEvent @event, CancellationToken cancellationToken)
{
Sent.Add(@event);
return Task.CompletedTask;
}
}
}

View File

@@ -603,6 +603,33 @@ public sealed class WebServiceEndpointsTests : IAsyncLifetime
Assert.Equal("GHSA-2025-0001", evidence!.AdvisoryKey);
Assert.Equal(2, evidence.Records.Count);
Assert.All(evidence.Records, record => Assert.Equal("tenant-a", record.Tenant));
Assert.Null(evidence.Attestation);
}
[Fact]
public async Task AdvisoryEvidenceEndpoint_AttachesAttestationWhenBundleProvided()
{
await SeedAdvisoryRawDocumentsAsync(
CreateAdvisoryRawDocument("tenant-a", "vendor-x", "GHSA-2025-0003", "sha256:201", new BsonDocument("id", "GHSA-2025-0003:1")));
var repoRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..", "..", ".."));
var sampleDir = Path.Combine(repoRoot, "docs", "samples", "evidence-bundle");
var tarPath = Path.Combine(sampleDir, "evidence-bundle-m0.tar.gz");
var manifestPath = Path.Combine(sampleDir, "manifest.json");
var transparencyPath = Path.Combine(sampleDir, "transparency.json");
using var client = _factory.CreateClient();
var requestUri = $"/vuln/evidence/advisories/GHSA-2025-0003?tenant=tenant-a&bundlePath={Uri.EscapeDataString(tarPath)}&manifestPath={Uri.EscapeDataString(manifestPath)}&transparencyPath={Uri.EscapeDataString(transparencyPath)}&pipelineVersion=git:test-sha";
var response = await client.GetAsync(requestUri);
response.EnsureSuccessStatusCode();
var evidence = await response.Content.ReadFromJsonAsync<AdvisoryEvidenceResponse>();
Assert.NotNull(evidence);
Assert.NotNull(evidence!.Attestation);
Assert.Equal("evidence-bundle-m0", evidence.Attestation!.SubjectName);
Assert.Equal("git:test-sha", evidence.Attestation.PipelineVersion);
Assert.Equal(tarPath, evidence.Attestation.EvidenceBundlePath);
}
[Fact]

View File

@@ -0,0 +1,35 @@
using System;
using System.Text.Json.Serialization;
namespace StellaOps.Excititor.WebService.Contracts;
/// <summary>
/// Envelope for air-gapped VEX bundle imports.
/// Mirrors the thin mirror bundle schema and carries signing metadata.
/// </summary>
public sealed class AirgapImportRequest
{
[JsonPropertyName("bundleId")]
public string? BundleId { get; init; }
[JsonPropertyName("mirrorGeneration")]
public string? MirrorGeneration { get; init; }
[JsonPropertyName("signedAt")]
public DateTimeOffset? SignedAt { get; init; }
[JsonPropertyName("publisher")]
public string? Publisher { get; init; }
[JsonPropertyName("payloadHash")]
public string? PayloadHash { get; init; }
[JsonPropertyName("payloadUrl")]
public string? PayloadUrl { get; init; }
[JsonPropertyName("signature")]
public string? Signature { get; init; }
[JsonPropertyName("transparencyLog")]
public string? TransparencyLog { get; init; }
}

View File

@@ -48,6 +48,7 @@ services.AddCsafNormalizer();
services.AddCycloneDxNormalizer();
services.AddOpenVexNormalizer();
services.AddSingleton<IVexSignatureVerifier, NoopVexSignatureVerifier>();
services.AddSingleton<AirgapImportValidator>();
services.AddScoped<IVexIngestOrchestrator, VexIngestOrchestrator>();
services.AddScoped<IVexObservationLookup, MongoVexObservationLookup>();
services.AddOptions<ExcititorObservabilityOptions>()
@@ -140,6 +141,33 @@ app.MapGet("/excititor/status", async (HttpContext context,
app.MapHealthChecks("/excititor/health");
app.MapPost("/airgap/v1/vex/import", async (
[FromServices] AirgapImportValidator validator,
[FromServices] TimeProvider timeProvider,
[FromBody] AirgapImportRequest request,
CancellationToken cancellationToken) =>
{
var errors = validator.Validate(request, timeProvider.GetUtcNow());
if (errors.Count > 0)
{
var first = errors[0];
return Results.BadRequest(new
{
error = new
{
code = first.Code,
message = first.Message
}
});
}
return Results.Accepted($"/airgap/v1/vex/import/{request.BundleId}", new
{
bundleId = request.BundleId,
generation = request.MirrorGeneration
});
});
app.MapPost("/v1/attestations/verify", async (
[FromServices] IVexAttestationClient attestationClient,
[FromBody] AttestationVerifyRequest request,

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Globalization;
namespace StellaOps.Excititor.WebService.Services;
internal sealed class AirgapImportValidator
{
private static readonly TimeSpan AllowedSkew = TimeSpan.FromSeconds(5);
public IReadOnlyList<ValidationError> Validate(AirgapImportRequest request, DateTimeOffset nowUtc)
{
var errors = new List<ValidationError>();
if (request is null)
{
errors.Add(new ValidationError("invalid_request", "Request body is required."));
return errors;
}
if (string.IsNullOrWhiteSpace(request.BundleId))
{
errors.Add(new ValidationError("bundle_id_missing", "bundleId is required."));
}
if (string.IsNullOrWhiteSpace(request.MirrorGeneration))
{
errors.Add(new ValidationError("mirror_generation_missing", "mirrorGeneration is required."));
}
if (string.IsNullOrWhiteSpace(request.Publisher))
{
errors.Add(new ValidationError("publisher_missing", "publisher is required."));
}
if (string.IsNullOrWhiteSpace(request.PayloadHash))
{
errors.Add(new ValidationError("payload_hash_missing", "payloadHash is required."));
}
if (string.IsNullOrWhiteSpace(request.Signature))
{
errors.Add(new ValidationError("AIRGAP_SIGNATURE_MISSING", "signature is required for air-gapped imports."));
}
if (request.SignedAt is null)
{
errors.Add(new ValidationError("signed_at_missing", "signedAt is required."));
}
else
{
var delta = (nowUtc - request.SignedAt.Value).Duration();
if (delta > AllowedSkew)
{
errors.Add(new ValidationError(
"AIRGAP_PAYLOAD_STALE",
$"signedAt exceeds allowed skew of {AllowedSkew.TotalSeconds.ToString(CultureInfo.InvariantCulture)} seconds."));
}
}
return errors;
}
public readonly record struct ValidationError(string Code, string Message);
}

View File

@@ -0,0 +1,54 @@
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
using StellaOps.Excititor.WebService.Contracts;
using Xunit;
namespace StellaOps.Excititor.WebService.Tests;
public class AirgapImportEndpointTests : IClassFixture<TestWebApplicationFactory>
{
private readonly HttpClient _client;
public AirgapImportEndpointTests(TestWebApplicationFactory factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task Import_returns_bad_request_when_signature_missing()
{
var request = new AirgapImportRequest
{
BundleId = "bundle-123",
MirrorGeneration = "gen-1",
SignedAt = DateTimeOffset.UtcNow,
Publisher = "mirror-test",
PayloadHash = "sha256:abc"
};
var response = await _client.PostAsJsonAsync("/airgap/v1/vex/import", request);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var json = await response.Content.ReadFromJsonAsync<JsonElement>();
Assert.Equal("AIRGAP_SIGNATURE_MISSING", json.GetProperty("error").GetProperty("code").GetString());
}
[Fact]
public async Task Import_accepts_valid_payload()
{
var request = new AirgapImportRequest
{
BundleId = "bundle-123",
MirrorGeneration = "gen-1",
SignedAt = DateTimeOffset.UtcNow,
Publisher = "mirror-test",
PayloadHash = "sha256:abc",
Signature = "sig"
};
using var response = await _client.PostAsJsonAsync("/airgap/v1/vex/import", request);
Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
}
}

View File

@@ -1,6 +1,11 @@
using System.Net;
using System.Net.Http;
using System.Text;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.Notifier.Tests.Support;
using StellaOps.Notifier.WebService;
using StellaOps.Notify.Storage.Mongo.Repositories;
using Xunit;
namespace StellaOps.Notifier.Tests;

View File

@@ -11,10 +11,11 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit.v3" Version="3.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.3" />
</ItemGroup>
@@ -27,7 +28,8 @@
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Notifier.Worker\StellaOps.Notifier.Worker.csproj" />
</ItemGroup>
</Project>
<ItemGroup>
<ProjectReference Include="..\StellaOps.Notifier.WebService\StellaOps.Notifier.WebService.csproj" />
<ProjectReference Include="..\StellaOps.Notifier.Worker\StellaOps.Notifier.Worker.csproj" />
</ItemGroup>
</Project>

View File

@@ -6,11 +6,11 @@ using StellaOps.Notifier.Worker.Processing;
namespace StellaOps.Notifier.Tests.Support;
public sealed class TestEgressSloSink : IEgressSloSink
internal sealed class TestEgressSloSink : IEgressSloSink
{
private readonly ConcurrentBag<EgressSloContext> _contexts = new();
public IReadOnlyCollection<EgressSloContext> Contexts => _contexts;
internal IReadOnlyCollection<EgressSloContext> Contexts => _contexts;
public Task PublishAsync(EgressSloContext context, CancellationToken cancellationToken)
{

View File

@@ -126,10 +126,6 @@ app.MapGet("/.well-known/openapi", (HttpContext context, OpenApiDocumentCache ca
return Results.Content(cache.Document, "application/yaml");
});
app.Run();
public partial class Program;
static object Error(string code, string message, HttpContext context) => new
{
error = new
@@ -139,3 +135,7 @@ static object Error(string code, string message, HttpContext context) => new
traceId = context.TraceIdentifier
}
};
app.Run();
public partial class Program;

View File

@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.0-rc.2.25502.107" />
</ItemGroup>

View File

@@ -7,9 +7,9 @@
| NOTIFY-OAS-61-001 | DONE (2025-11-17) | Notifications Service Guild · API Contracts Guild | OAS updated with rules/templates/incidents/quiet hours and standard error envelope. |
| NOTIFY-OAS-61-002 | DONE (2025-11-17) | Notifications Service Guild | `.well-known/openapi` discovery endpoint with scope metadata implemented. |
| NOTIFY-OAS-62-001 | DONE (2025-11-17) | Notifications Service Guild · SDK Generator Guild | SDK usage examples + smoke tests (depends on 61-002). |
| NOTIFY-OAS-63-001 | TODO | Notifications Service Guild · API Governance Guild | Deprecation headers + template notices for retiring APIs (depends on 62-001). |
| NOTIFY-OBS-51-001 | TODO | Notifications Service Guild · Observability Guild | Integrate SLO evaluator webhooks once schema lands. |
| NOTIFY-OBS-55-001 | TODO | Notifications Service Guild · Ops Guild | Incident mode start/stop notifications; quiet-hour overrides. |
| NOTIFY-OAS-63-001 | DONE (2025-11-17) | Notifications Service Guild · API Governance Guild | Deprecation headers + template notices for retiring APIs (depends on 62-001). |
| NOTIFY-OBS-51-001 | DONE (2025-11-22) | Notifications Service Guild · Observability Guild | SLO webhook sink validated (`HttpEgressSloSinkTests`, `EventProcessorTests`); TRX: `StellaOps.Notifier.Tests/TestResults/notifier-slo-tests.trx`. |
| NOTIFY-OBS-55-001 | DONE (2025-11-22) | Notifications Service Guild · Ops Guild | Incident mode start/stop notifications; templates + importable rules with quiet-hour overrides and legal logging metadata. |
| NOTIFY-RISK-66-001 | TODO | Notifications Service Guild · Risk Engine Guild | Trigger risk severity escalation/downgrade notifications (waiting on Policy export). |
| NOTIFY-RISK-67-001 | TODO | Notifications Service Guild · Policy Guild | Notify when risk profiles publish/deprecate/threshold-change (depends on 66-001). |
| NOTIFY-RISK-68-001 | TODO | Notifications Service Guild | Per-profile routing rules + quiet hours for risk alerts (depends on 67-001). |

View File

@@ -0,0 +1,51 @@
[
{
"ruleId": "incident-start-default",
"tenantId": "tenant-a",
"name": "Incident mode activated",
"enabled": true,
"match": {
"eventKinds": [
"incident.mode.start"
]
},
"actions": [
{
"actionId": "incident-start-slack",
"channel": "slack-ops",
"template": "tmpl-incident-start",
"metadata": {
"trace_link": "{{payload.links.trace}}",
"evidence_link": "{{payload.links.evidence}}",
"retention_note": "Retention extended to {{payload.retentionDays}} days while incident mode is active.",
"quiet_hours_override": "true",
"legal_jurisdiction": "{{payload.legal.jurisdiction}}",
"legal_ticket": "{{payload.legal.ticket}}"
}
}
]
},
{
"ruleId": "incident-stop-default",
"tenantId": "tenant-a",
"name": "Incident mode cleared",
"enabled": true,
"match": {
"eventKinds": [
"incident.mode.stop"
]
},
"actions": [
{
"actionId": "incident-stop-email",
"channel": "email-compliance",
"template": "tmpl-incident-stop",
"metadata": {
"summary_link": "{{payload.links.timeline}}",
"retention_reset_note": "Retention reverts to baseline {{payload.retentionBaselineDays}} days.",
"legal_log_path": "{{payload.legal.logPath}}"
}
}
]
}
]

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using StellaOps.Notify.Storage.Mongo.Internal;
@@ -22,8 +23,13 @@ internal sealed class EnsurePackApprovalsCollectionMigration : INotifyMongoMigra
.ListCollectionNamesAsync(cancellationToken: cancellationToken)
.ConfigureAwait(false);
var existing = await cursor.ToListAsync(cancellationToken).ConfigureAwait(false);
if (existing.Contains(target, StringComparer.Ordinal))
var existing = new HashSet<string>(StringComparer.Ordinal);
while (await cursor.MoveNextAsync(cancellationToken).ConfigureAwait(false))
{
existing.UnionWith(cursor.Current);
}
if (existing.Contains(target))
{
return;
}

View File

@@ -16,9 +16,11 @@ public sealed class NotifyMongoOptions
public string DeliveriesCollection { get; set; } = "deliveries";
public string DigestsCollection { get; set; } = "digests";
public string LocksCollection { get; set; } = "locks";
public string DigestsCollection { get; set; } = "digests";
public string PackApprovalsCollection { get; set; } = "pack_approvals";
public string LocksCollection { get; set; } = "locks";
public string AuditCollection { get; set; } = "audit";

View File

@@ -0,0 +1,67 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Mongo2Go;
using MongoDB.Bson;
using MongoDB.Driver;
using StellaOps.Concelier.Storage.Mongo.Migrations;
namespace StellaOps.Concelier.Storage.Mongo.Tests;
public sealed class EnsureOrchestratorCollectionsMigrationTests : IAsyncLifetime
{
private MongoDbRunner _runner = null!;
private IMongoDatabase _database = null!;
public Task InitializeAsync()
{
_runner = MongoDbRunner.Start(singleNodeReplSet: true);
var client = new MongoClient(_runner.ConnectionString);
_database = client.GetDatabase("orch-migration-tests");
return Task.CompletedTask;
}
public Task DisposeAsync()
{
_runner.Dispose();
return Task.CompletedTask;
}
[Fact]
public async Task CreatesOrchestratorCollectionsAndIndexes()
{
var migration = new EnsureOrchestratorCollectionsMigration();
await migration.ApplyAsync(_database, CancellationToken.None);
var collections = await _database.ListCollectionNames().ToListAsync();
collections.Should().Contain(
new[]
{
MongoStorageDefaults.Collections.OrchestratorRegistry,
MongoStorageDefaults.Collections.OrchestratorCommands,
MongoStorageDefaults.Collections.OrchestratorHeartbeats,
});
var registryIndexes = await GetIndexNamesAsync(MongoStorageDefaults.Collections.OrchestratorRegistry);
registryIndexes.Should().Contain("orch_registry_tenant_connector");
var commandIndexes = await GetIndexNamesAsync(MongoStorageDefaults.Collections.OrchestratorCommands);
commandIndexes.Should().Contain("orch_cmd_tenant_connector_run_seq");
commandIndexes.Should().Contain("orch_cmd_expiresAt_ttl");
var heartbeatIndexes = await GetIndexNamesAsync(MongoStorageDefaults.Collections.OrchestratorHeartbeats);
heartbeatIndexes.Should().Contain("orch_hb_tenant_connector_run_seq");
}
private async Task<IReadOnlyCollection<string>> GetIndexNamesAsync(string collection)
{
var docs = await _database.GetCollection<BsonDocument>(collection)
.Indexes
.List()
.ToListAsync();
return docs.Select(d => d["name"].AsString).ToArray();
}
}

View File

@@ -0,0 +1,130 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using Mongo2Go;
using MongoDB.Driver;
using StellaOps.Concelier.Storage.Mongo.Migrations;
using StellaOps.Concelier.Storage.Mongo.Orchestrator;
namespace StellaOps.Concelier.Storage.Mongo.Tests;
public sealed class MongoOrchestratorRegistryStoreTests : IAsyncLifetime
{
private MongoDbRunner _runner = null!;
private IMongoDatabase _database = null!;
private MongoOrchestratorRegistryStore _store = null!;
public Task InitializeAsync()
{
_runner = MongoDbRunner.Start(singleNodeReplSet: true);
var client = new MongoClient(_runner.ConnectionString);
_database = client.GetDatabase("orch-store-tests");
// ensure collections/indexes present
var migration = new EnsureOrchestratorCollectionsMigration();
migration.ApplyAsync(_database, CancellationToken.None).GetAwaiter().GetResult();
_store = new MongoOrchestratorRegistryStore(
_database.GetCollection<OrchestratorRegistryDocument>(MongoStorageDefaults.Collections.OrchestratorRegistry),
_database.GetCollection<OrchestratorCommandDocument>(MongoStorageDefaults.Collections.OrchestratorCommands),
_database.GetCollection<OrchestratorHeartbeatDocument>(MongoStorageDefaults.Collections.OrchestratorHeartbeats));
return Task.CompletedTask;
}
public Task DisposeAsync()
{
_runner.Dispose();
return Task.CompletedTask;
}
[Fact]
public async Task UpsertAndFetchRegistryRoundTrips()
{
var record = new OrchestratorRegistryRecord(
Tenant: "tenant-a",
ConnectorId: "icscisa",
Source: "icscisa",
Capabilities: new[] { "observations", "linksets" },
AuthRef: "secret:concelier/icscisa/api-key",
Schedule: new OrchestratorSchedule("*/30 * * * *", "UTC", 1, 120),
RatePolicy: new OrchestratorRatePolicy(60, 10, 30),
ArtifactKinds: new[] { "raw-advisory", "linkset" },
LockKey: "concelier:tenant-a:icscisa",
EgressGuard: new OrchestratorEgressGuard(new[] { "icscert.kisa.or.kr" }, true),
CreatedAt: DateTimeOffset.Parse("2025-11-20T00:00:00Z"),
UpdatedAt: DateTimeOffset.Parse("2025-11-21T00:00:00Z"));
await _store.UpsertAsync(record, CancellationToken.None);
var fetched = await _store.GetAsync("tenant-a", "icscisa", CancellationToken.None);
fetched.Should().NotBeNull();
fetched!.ConnectorId.Should().Be("icscisa");
fetched.Schedule.Cron.Should().Be("*/30 * * * *");
fetched.RatePolicy.Burst.Should().Be(10);
fetched.EgressGuard.AirgapMode.Should().BeTrue();
}
[Fact]
public async Task EnqueueAndReadCommandsOrdersBySequence()
{
var runId = Guid.NewGuid();
var first = new OrchestratorCommandRecord(
Tenant: "tenant-a",
ConnectorId: "icscisa",
RunId: runId,
Sequence: 1,
Command: OrchestratorCommandKind.Pause,
Throttle: null,
Backfill: null,
CreatedAt: DateTimeOffset.Parse("2025-11-20T00:00:00Z"),
ExpiresAt: null);
var second = new OrchestratorCommandRecord(
Tenant: "tenant-a",
ConnectorId: "icscisa",
RunId: runId,
Sequence: 2,
Command: OrchestratorCommandKind.Backfill,
Throttle: null,
Backfill: new OrchestratorBackfillRange("2024-01-01T00:00:00Z", "2024-02-01T00:00:00Z"),
CreatedAt: DateTimeOffset.Parse("2025-11-20T00:01:00Z"),
ExpiresAt: null);
await _store.EnqueueCommandAsync(second, CancellationToken.None);
await _store.EnqueueCommandAsync(first, CancellationToken.None);
var commands = await _store.GetPendingCommandsAsync("tenant-a", "icscisa", runId, afterSequence: 0, CancellationToken.None);
commands.Select(c => c.Sequence).Should().ContainInOrder(1, 2);
commands.Last().Backfill!.FromCursor.Should().Be("2024-01-01T00:00:00Z");
}
[Fact]
public async Task AppendsHeartbeats()
{
var heartbeat = new OrchestratorHeartbeatRecord(
Tenant: "tenant-a",
ConnectorId: "icscisa",
RunId: Guid.NewGuid(),
Sequence: 5,
Status: OrchestratorHeartbeatStatus.Running,
Progress: 42,
QueueDepth: 7,
LastArtifactHash: "abc",
LastArtifactKind: "normalized",
ErrorCode: null,
RetryAfterSeconds: null,
TimestampUtc: DateTimeOffset.Parse("2025-11-21T00:00:00Z"));
await _store.AppendHeartbeatAsync(heartbeat, CancellationToken.None);
var count = await _database
.GetCollection<OrchestratorHeartbeatDocument>(MongoStorageDefaults.Collections.OrchestratorHeartbeats)
.CountDocumentsAsync(FilterDefinition<OrchestratorHeartbeatDocument>.Empty);
count.Should().Be(1);
}
}