diff --git a/docs/implplan/tasks-all.md b/docs/implplan/tasks-all.md index 2769fe78a..636214569 100644 --- a/docs/implplan/tasks-all.md +++ b/docs/implplan/tasks-all.md @@ -1074,8 +1074,8 @@ | GO-34-001 | DONE | | SPRINT_0153_0001_0003_orchestrator_iii | Worker SDK Guild | src/Orchestrator/StellaOps.Orchestrator.WorkerSdk.Go | GO-33-002 | GO-33-002 | GOSD0101 | | GRAPH-21-001 | TODO | | SPRINT_136_scanner_surface | Scanner WebService Guild | src/Scanner/StellaOps.Scanner.WebService | Link-Not-Merge schema | Link-Not-Merge schema | GRSC0101 | | GRAPH-21-002 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_113_concelier_ii | Concelier Core Guild · Scanner Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 | -| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 | -| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 | +| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 | +| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 | | GRAPH-21-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_120_excititor_ii | Excititor Storage Guild | src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 | | GRAPH-24-001 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | GRSC0101 outputs | GRSC0101 outputs | GRUI0101 | | GRAPH-24-002 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild | src/UI/StellaOps.UI | GRAPH-24-001 | GRAPH-24-001 | GRUI0101 | @@ -1186,8 +1186,8 @@ | LNM-21-203 | TODO | | SPRINT_113_concelier_ii | CLI Guild | src/Concelier/StellaOps.Concelier.WebService | Export reporting. | LNM-21-202 | LNMC0101 | | LNM-22-001 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | CLI/UI shared components. | DOLN0101 | LNMC0101 | | LNM-22-002 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | Additional filters. | LNM-22-001 | LNMC0101 | -| LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 | -| LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 | +| LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 | +| LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 | | LNM-22-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_305_docs_tasks_md_v | Docs + UI Guild | | Docs update for UI flows. | DOCS-LNM-22-004 | IMPT0101 | | LNM-22-007 | TODO | | SPRINT_305_docs_tasks_md_v | Docs Guild · Observability Guild | docs/modules/concelier/link-not-merge.md | Publish `/docs/observability/aggregation.md` with metrics/traces/logs/SLOs. Dependencies: DOCS-LNM-22-005. | DOCS-LNM-22-005 | DOLN0102 | | LNM-22-008 | DONE | 2025-11-03 | SPRINT_117_concelier_vi | Docs Guild · DevOps Guild | docs/modules/concelier/link-not-merge.md | Document Link-Not-Merge migration playbook updates in `docs/migration/no-merge.md`, including rollback guidance. | LNM-22-007 | DOLN0102 | @@ -1338,16 +1338,16 @@ | PLG7.IMPL-006 | DONE (2025-11-09) | 2025-11-09 | SPRINT_100_identity_signing | BE-Auth Plugin (src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap) | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap | LDAP bootstrap provisioning + health status + docs. | LDAP bootstrap provisioning added (write probe, Mongo audit mirror, capability downgrade + health status) with docs/tests + sample manifest updates. | PLGN0101 | | POL-005 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild | `src/Policy/StellaOps.Policy.Engine`, `docs/modules/policy/architecture.md`, `docs/reachability/function-level-evidence.md` | Ingest reachability facts, expose `reachability.state/confidence`, auto-suppress low confidence, emit OpenVEX evidence. | GAPG0101 | PORE0101 | | POLICY-0001 | DONE | 2025-11-10 | SPRINT_0138_0000_0001_scanner_ruby_parity | Policy Guild, Ruby Analyzer Guild (docs/modules/scanner) | docs/modules/scanner | | SCANNER-ENG-0018 | | -| POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | POLICY-20-001 | TODO | | SPRINT_114_concelier_iii | Concelier WebService Guild | src/Concelier/StellaOps.Concelier.WebService | Provide batch advisory lookup APIs for Policy Engine (purl/advisory filters, tenant scopes, explain metadata). | ATLN0101 | CCPR0102 | | POLICY-20-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | Expand linkset builders with vendor equivalence tables, NEVRA/PURL normalization, version-range parsing. | POLICY-20-001 | CCPR0102 | | POLICY-20-003 | TODO | | SPRINT_115_concelier_iv | Concelier Storage Guild | src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo | Introduce advisory selection cursors + change-stream checkpoints with offline migration scripts. | POLICY-20-002 | CCPR0102 | -| POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Implement Policy Studio UI surfaces wiring to new APIs (editor, simulation, dashboards). | ORSC0101 | UIPD0101 | +| POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Implement Policy Studio UI surfaces wiring to new APIs (editor, simulation, dashboards). | ORSC0101 | UIPD0101 | | POLICY-23-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | Add secondary indexes/materialized views (alias, severity, confidence) for fast policy lookups. | POLICY-20-003 | CCPR0102 | | POLICY-23-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Platform Events Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | Ensure `advisory.linkset.updated` events carry idempotent IDs/confidence summaries/tenant metadata for replay. | POLICY-23-001 | CCPR0102 | -| POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | POLICY-23-004 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | | -| POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | POLICY-23-006 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | | | POLICY-23-007 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, DevEx/CLI Guild (docs) | | | | | | POLICY-23-008 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, Architecture Guild (docs) | | | | | @@ -1819,8 +1819,8 @@ | SIG-003 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md`) | `src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md` | | | | | SIG-26-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Signals Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | | | SIG-26-002 | TODO | | SPRINT_204_cli_iv | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | | -| SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | -| SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | SIG-26-005 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, UI Guild (docs) | | | | | | SIG-26-006 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, DevEx/CLI Guild (docs) | | | | | | SIG-26-007 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, BE-Base Platform Guild (docs) | | | | | @@ -1935,7 +1935,7 @@ | SYMS-SERVER-401-011 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Symbols Guild | `src/Symbols/StellaOps.Symbols.Server` | Deliver `StellaOps.Symbols.Server` (REST+gRPC) with DSSE-verified uploads, Mongo/MinIO storage, tenant isolation, and deterministic debugId indexing; publish health/manifest APIs (spec: `docs/specs/SYMBOL_MANIFEST_v1.md`). | Depends on #5 | RBSY0101 | | TASKRUN-41-001 | DONE (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0002_taskrunner_blockers | Task Runner Guild | src/TaskRunner/StellaOps.TaskRunner | Bootstrap service, define migrations for `pack_runs`, `pack_run_logs`, `pack_artifacts`, implement run API (create/get/log stream), local executor, approvals pause, artifact capture, and provenance manifest generation. | Delivered per Task Pack advisory and architecture contract. | ORTR0101 | | TASKRUN-AIRGAP-56-001 | DONE (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Policy Guild | src/TaskRunner/StellaOps.TaskRunner | Enforce plan-time validation rejecting steps with non-allowlisted network calls in sealed mode and surface remediation errors. | TASKRUN-41-001 | ORTR0101 | -| TASKRUN-AIRGAP-56-002 | BLOCKED (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Importer Guild | src/TaskRunner/StellaOps.TaskRunner | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. | TASKRUN-AIRGAP-56-001 | ORTR0101 | +| TASKRUN-AIRGAP-56-002 | DOING (2025-12-01) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Importer Guild | src/TaskRunner/StellaOps.TaskRunner | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. | TASKRUN-AIRGAP-56-001 | ORTR0101 | | TASKRUN-AIRGAP-57-001 | BLOCKED (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · AirGap Controller Guild | src/TaskRunner/StellaOps.TaskRunner | Refuse to execute plans when environment sealed=false but declared sealed install; emit advisory timeline events. | TASKRUN-AIRGAP-56-002 | ORTR0101 | | TASKRUN-AIRGAP-58-001 | BLOCKED (2025-11-30) | 2025-11-30 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild · Evidence Locker Guild | src/TaskRunner/StellaOps.TaskRunner | Capture bundle import job transcripts, hashed inputs, and outputs into portable evidence bundles. | TASKRUN-AIRGAP-57-001 | ORTR0101 | | TASKRUN-42-001 | BLOCKED (2025-11-25) | 2025-11-25 | SPRINT_0157_0001_0001_taskrunner_i | Task Runner Guild (`src/TaskRunner/StellaOps.TaskRunner`) | src/TaskRunner/StellaOps.TaskRunner | Execution engine enhancements (loops/conditionals/maxParallel), simulation mode, policy gate integration, deterministic failure recovery. Blocked: loop/conditional semantics and policy-gate evaluation contract not published. | | ORTR0102 | @@ -1995,29 +1995,29 @@ | UI-GRAPH-24-004 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add side panels (Details, What-if, History) with upgrade simulation integration and SBOM diff viewer. Dependencies: UI-GRAPH-24-003. | | | | UI-GRAPH-24-006 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild, Accessibility Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Ensure accessibility (keyboard nav, screen reader labels, contrast), add hotkeys (`f`,`e`,`.`), and analytics instrumentation. Dependencies: UI-GRAPH-24-004. | | | | UI-LNM-22-001 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Evidence panel showing policy decision with advisory observations/linksets side-by-side, conflict badges, AOC chain, and raw doc download links. Docs `DOCS-LNM-22-005` waiting on delivered UI for screenshots + flows. | | | -| UI-LNM-22-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | | -| UI-LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | | -| UI-LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | | +| UI-LNM-22-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | | +| UI-LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | | +| UI-LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | | | UI-OPS-0001 | TODO | | SPRINT_331_docs_modules_ui | Ops Guild (docs/modules/ui) | docs/modules/ui | | | | -| UI-ORCH-32-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | | -| UI-POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | | -| UI-POLICY-20-001 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, diagnostics, and checklist sidebar. | POLICY-13-007 | UIPD0101 | -| UI-POLICY-20-002 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, deterministic diffs. | UI-POLICY-20-001 | UIPD0101 | -| UI-POLICY-20-003 | TODO | | SPRINT_210_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, and RBAC checks aligned to new Policy Studio roles (`policy:author`/`policy:review`/`policy:approve`/`policy:operate`). Dependencies: UI-POLICY-20-002. | Requires 20-002 results | | -| UI-POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filter/search and export. Dependencies: UI-POLICY-20-003. | Depends on 20-003 | | -| UI-POLICY-23-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | | -| UI-POLICY-23-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | | -| UI-POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | | -| UI-POLICY-23-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | | -| UI-POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | | -| UI-POLICY-23-006 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | | -| UI-POLICY-27-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | | +| UI-ORCH-32-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | | +| UI-POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | | +| UI-POLICY-20-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, diagnostics, and checklist sidebar. | POLICY-13-007 | UIPD0101 | +| UI-POLICY-20-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, deterministic diffs. | UI-POLICY-20-001 | UIPD0101 | +| UI-POLICY-20-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, and RBAC checks aligned to new Policy Studio roles (`policy:author`/`policy:review`/`policy:approve`/`policy:operate`). Dependencies: UI-POLICY-20-002. | Requires 20-002 results | | +| UI-POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filter/search and export. Dependencies: UI-POLICY-20-003. | Depends on 20-003 | | +| UI-POLICY-23-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | | +| UI-POLICY-23-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | | +| UI-POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | | +| UI-POLICY-23-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | | +| UI-POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | | +| UI-POLICY-23-006 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | | +| UI-POLICY-27-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | | | UI-POLICY-DET-01 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Wire policy gate indicators + remediation hints into Release/Policy flows, blocking publishes when determinism checks fail; coordinate with Policy Engine schema updates. Dependencies: UI-SBOM-DET-01. | | | | UI-SBOM-DET-01 | TODO | | SPRINT_0209_0001_0001_ui_i | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add a """Determinism""" badge plus drill-down that surfaces fragment hashes, `_composition.json`, and Merkle root consistency when viewing scan details (per `docs/modules/scanner/deterministic-sbom-compose.md`). | | | -| UI-SIG-26-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | | -| UI-SIG-26-002 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | | -| UI-SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | | -| UI-SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | | +| UI-SIG-26-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | | +| UI-SIG-26-002 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | | +| UI-SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | | +| UI-SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | | | UNCERTAINTY-POLICY-401-026 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild · Concelier Guild (`docs/policy/dsl.md`, `docs/uncertainty/README.md`) | `docs/policy/dsl.md`, `docs/uncertainty/README.md` | Update policy guidance (Concelier/Excitors) with uncertainty gates (U1/U2/U3), sample YAML rules, and remediation actions. | | | | UNCERTAINTY-SCHEMA-401-024 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md` | Extend Signals findings with `uncertainty.states[]`, entropy fields, and `riskScore`; emit `FindingUncertaintyUpdated` events and persist evidence per docs. | | | | UNCERTAINTY-SCORER-401-025 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md` | Implement the entropy-aware risk scorer (`riskScore = base × reach × trust × (1 + entropyBoost)`) and wire it into finding writes. | | | @@ -2115,19 +2115,19 @@ | WEB-CONTAINERS-45-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ensure readiness endpoints reflect DB/queue readiness, add feature flag toggles via config map, and document NetworkPolicy ports. Dependencies: WEB-CONTAINERS-44-001. | | | | WEB-CONTAINERS-46-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide offline-friendly asset serving (no CDN), allow overriding object store endpoints via env, and document fallback behavior. Dependencies: WEB-CONTAINERS-45-001. | | | | WEB-EXC-25-001 | TODO | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement `/exceptions` API (create, propose, approve, revoke, list, history) with validation, pagination, and audit logging. | | | -| WEB-EXC-25-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | | -| WEB-EXC-25-003 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | | -| WEB-EXPORT-35-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | | -| WEB-EXPORT-36-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | | -| WEB-EXPORT-37-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | | -| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | | -| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | | -| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | | -| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | | -| WEB-GRAPH-24-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | | -| WEB-GRAPH-24-004 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | | -| WEB-LNM-21-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | | -| WEB-LNM-21-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | | +| WEB-EXC-25-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | | +| WEB-EXC-25-003 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | | +| WEB-EXPORT-35-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | | +| WEB-EXPORT-36-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | | +| WEB-EXPORT-37-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | | +| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | | +| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | | +| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | | +| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | | +| WEB-GRAPH-24-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | | +| WEB-GRAPH-24-004 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | | +| WEB-LNM-21-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | | +| WEB-LNM-21-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | | | WEB-LNM-21-003 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide combined endpoint for Console to fetch policy result + source evidence (advisory + VEX linksets) for a component. Dependencies: WEB-LNM-21-002. | | | | WEB-NOTIFY-38-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Route notifier APIs (`/notifications/*`) and WS feed through gateway with tenant scoping, viewer/operator scope enforcement, and SSE/WebSocket bridging. | Depends on #1 for signed ack spec | NOWB0101 | | WEB-NOTIFY-39-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Surface digest scheduling, quiet-hour/throttle management, and simulation APIs; ensure rate limits and audit logging. Dependencies: WEB-NOTIFY-38-001. | WEB-NOTIFY-38-001 | NOWB0101 | @@ -3293,8 +3293,8 @@ | GO-34-001 | DONE | | SPRINT_0153_0001_0003_orchestrator_iii | Worker SDK Guild | src/Orchestrator/StellaOps.Orchestrator.WorkerSdk.Go | GO-33-002 | GO-33-002 | GOSD0101 | | GRAPH-21-001 | TODO | | SPRINT_136_scanner_surface | Scanner WebService Guild | src/Scanner/StellaOps.Scanner.WebService | Link-Not-Merge schema | Link-Not-Merge schema | GRSC0101 | | GRAPH-21-002 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_113_concelier_ii | Concelier Core Guild · Scanner Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 | -| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 | -| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_213_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 | +| GRAPH-21-003 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-001 | GRAPH-21-001 | GRSC0101 | +| GRAPH-21-004 | TODO | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | Scanner WebService Guild | src/Web/StellaOps.Web | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 | | GRAPH-21-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_120_excititor_ii | Excititor Storage Guild | src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo | GRAPH-21-002 | GRAPH-21-002 | GRSC0101 | | GRAPH-24-005 | TODO | | SPRINT_304_docs_tasks_md_iv | UI Guild | | GRAPH-24-003 | GRAPH-24-003 | GRUI0101 | | GRAPH-24-007 | TODO | | SPRINT_304_docs_tasks_md_iv | UI Guild | | GRAPH-24-005 | GRAPH-24-005 | GRUI0101 | @@ -3400,8 +3400,8 @@ | LNM-21-203 | TODO | | SPRINT_113_concelier_ii | CLI Guild | src/Concelier/StellaOps.Concelier.WebService | Export reporting. | LNM-21-202 | LNMC0101 | | LNM-22-001 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | CLI/UI shared components. | DOLN0101 | LNMC0101 | | LNM-22-002 | TODO | | SPRINT_202_cli_ii | CLI Guild | src/Cli/StellaOps.Cli | Additional filters. | LNM-22-001 | LNMC0101 | -| LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 | -| LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 | +| LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (`src/UI/StellaOps.UI`) | src/UI/StellaOps.UI | UI ingestion view. | LNM-22-001 | LNMC0101 | +| LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | UI remediation workflow. | LNM-22-003 | IMPT0101 | | LNM-22-005 | BLOCKED (2025-10-27) | 2025-10-27 | SPRINT_305_docs_tasks_md_v | Docs + UI Guild | | Docs update for UI flows. | DOCS-LNM-22-004 | IMPT0101 | | LNM-22-007 | TODO | | SPRINT_305_docs_tasks_md_v | Docs Guild · Observability Guild | docs/modules/concelier/link-not-merge.md | Publish `/docs/observability/aggregation.md` with metrics/traces/logs/SLOs. Dependencies: DOCS-LNM-22-005. | DOCS-LNM-22-005 | DOLN0102 | | LNM-22-008 | DONE | 2025-11-03 | SPRINT_117_concelier_vi | Docs Guild · DevOps Guild | docs/modules/concelier/link-not-merge.md | Document Link-Not-Merge migration playbook updates in `docs/migration/no-merge.md`, including rollback guidance. | LNM-22-007 | DOLN0102 | @@ -3552,16 +3552,16 @@ | PLG7.IMPL-006 | DONE (2025-11-09) | 2025-11-09 | SPRINT_100_identity_signing | BE-Auth Plugin (src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap) | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap | LDAP bootstrap provisioning added (write probe, Mongo audit mirror, capability downgrade + health status) with docs/tests + sample manifest updates. | LDAP bootstrap provisioning added (write probe, Mongo audit mirror, capability downgrade + health status) with docs/tests + sample manifest updates. | | | POL-005 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild | `src/Policy/StellaOps.Policy.Engine`, `docs/modules/policy/architecture.md`, `docs/reachability/function-level-evidence.md` | Ingest reachability facts, expose SPL signals, auto-suppress <0.30, emit OpenVEX evidence. | Needs reachability feed GAPG0101 | | | POLICY-0001 | DONE | 2025-11-10 | SPRINT_0138_0000_0001_scanner_ruby_parity | Policy Guild, Ruby Analyzer Guild (docs/modules/scanner) | docs/modules/scanner | | SCANNER-ENG-0018 | | -| POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | POLICY-20-001 | TODO | | SPRINT_114_concelier_iii | Concelier WebService Guild | src/Concelier/StellaOps.Concelier.WebService | Provide batch advisory lookup APIs for Policy (purl/advisory filters, explain metadata). | Needs latest advisory schemas | | | POLICY-20-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild | src/Concelier/__Libraries/StellaOps.Concelier.Core | Expand linkset builders with vendor equivalence tables, NEVRA/PURL normalization, version-range parsing. | Depends on 20-001 | | | POLICY-20-003 | TODO | | SPRINT_115_concelier_iv | Concelier Storage Guild | src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo | Introduce advisory selection cursors + change-stream checkpoints with offline migration scripts. | Needs 20-002 index/schema | | -| POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Wire UI to new policy evidence APIs, bridging editor + simulation flows. | Needs ORSC0101 APIs | | +| POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Wire UI to new policy evidence APIs, bridging editor + simulation flows. | Needs ORSC0101 APIs | | | POLICY-23-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | | | POLICY-23-002 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Platform Events Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | | -| POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | POLICY-23-004 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | | -| POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | POLICY-23-006 | TODO | | SPRINT_203_cli_iii | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | | | POLICY-23-007 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, DevEx/CLI Guild (docs) | | | | | | POLICY-23-008 | TODO | | SPRINT_307_docs_tasks_md_vii | Docs Guild, Architecture Guild (docs) | | | | | @@ -4031,8 +4031,8 @@ | SIG-003 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md`) | `src/Signals/StellaOps.Signals`, `docs/reachability/function-level-evidence.md` | | | | | SIG-26-001 | TODO | | SPRINT_115_concelier_iv | Concelier Core Guild, Signals Guild (src/Concelier/__Libraries/StellaOps.Concelier.Core) | src/Concelier/__Libraries/StellaOps.Concelier.Core | | | | | SIG-26-002 | TODO | | SPRINT_204_cli_iv | DevEx/CLI Guild (src/Cli/StellaOps.Cli) | src/Cli/StellaOps.Cli | | | | -| SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | -| SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | +| SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | | | | | SIG-26-005 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, UI Guild (docs) | | | | | | SIG-26-006 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, DevEx/CLI Guild (docs) | | | | | | SIG-26-007 | TODO | | SPRINT_309_docs_tasks_md_ix | Docs Guild, BE-Base Platform Guild (docs) | | | | | @@ -4187,27 +4187,27 @@ | UI-CLI-401-007 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | UI & CLI Guilds (`src/Cli/StellaOps.Cli`, `src/UI/StellaOps.UI`) | `src/Cli/StellaOps.Cli`, `src/UI/StellaOps.UI` | Implement CLI `stella graph explain` + UI explain drawer showing signed call-path, predicates, runtime hits, and DSSE pointers; include counterfactual controls. | | | | UI-DOCS-0001 | TODO | | SPRINT_331_docs_modules_ui | Docs Guild (docs/modules/ui) | docs/modules/ui | | | | | UI-ENG-0001 | TODO | | SPRINT_331_docs_modules_ui | Module Team (docs/modules/ui) | docs/modules/ui | | | | -| UI-LNM-22-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | | -| UI-LNM-22-003 | TODO | | SPRINT_210_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | | -| UI-LNM-22-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | | +| UI-LNM-22-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement filters (source, severity bucket, conflict-only, CVSS vector presence) and pagination/lazy loading for large linksets. Docs depend on finalized filtering UX. Dependencies: UI-LNM-22-001. | | | +| UI-LNM-22-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Excititor Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add VEX tab with status/justification summaries, conflict indicators, and export actions. Required for `DOCS-LNM-22-005` coverage of VEX evidence tab. Dependencies: UI-LNM-22-002. | | | +| UI-LNM-22-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Provide permalink + copy-to-clipboard for selected component/linkset/policy combination; ensure high-contrast theme support. Dependencies: UI-LNM-22-003. | | | | UI-OPS-0001 | TODO | | SPRINT_331_docs_modules_ui | Ops Guild (docs/modules/ui) | docs/modules/ui | | | | -| UI-ORCH-32-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | | -| UI-POLICY-13-007 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | | -| UI-POLICY-20-001 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, inline diagnostics, and compliance checklist sidebar. Dependencies: UI-POLICY-13-007. | Depends on Policy DSL schema | | -| UI-POLICY-20-002 | TODO | | SPRINT_210_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, and rule hit summaries with deterministic diff rendering. Dependencies: UI-POLICY-20-001. | Needs 20-001 editor events | | -| UI-POLICY-20-003 | TODO | | SPRINT_210_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, RBAC. | UI-POLICY-20-002 | UIPD0101 | -| UI-POLICY-20-004 | TODO | | SPRINT_210_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filters/export. | UI-POLICY-20-003 | UIPD0101 | -| UI-POLICY-23-001 | TODO | | SPRINT_210_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | | -| UI-POLICY-23-002 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | | -| UI-POLICY-23-003 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | | -| UI-POLICY-23-004 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | | -| UI-POLICY-23-005 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | | -| UI-POLICY-23-006 | TODO | | SPRINT_210_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | | -| UI-POLICY-27-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | | -| UI-SIG-26-001 | TODO | | SPRINT_211_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | | -| UI-SIG-26-002 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | | -| UI-SIG-26-003 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | | -| UI-SIG-26-004 | TODO | | SPRINT_211_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | | +| UI-ORCH-32-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Console Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console RBAC mappings to surface `Orch.Viewer`, request `orch:read` scope in token flows, and gate dashboard access/messaging accordingly. | | | +| UI-POLICY-13-007 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Surface policy confidence metadata (band, age, quiet provenance) on preview and report views. | | | +| UI-POLICY-20-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Ship Monaco-based policy editor with DSL syntax highlighting, inline diagnostics, and compliance checklist sidebar. Dependencies: UI-POLICY-13-007. | Depends on Policy DSL schema | | +| UI-POLICY-20-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild | src/UI/StellaOps.UI | Build simulation panel showing before/after counts, severity deltas, and rule hit summaries with deterministic diff rendering. Dependencies: UI-POLICY-20-001. | Needs 20-001 editor events | | +| UI-POLICY-20-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI/ProdOps Guild | src/UI/StellaOps.UI | Implement submit/review/approve workflow with comments, approvals log, RBAC. | UI-POLICY-20-002 | UIPD0101 | +| UI-POLICY-20-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild · Observability Guild | src/UI/StellaOps.UI | Add run viewer dashboards (rule heatmap, VEX wins, suppressions) with filters/export. | UI-POLICY-20-003 | UIPD0101 | +| UI-POLICY-23-001 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild, Policy Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Deliver Policy Editor workspace with pack list, revision history, and scoped metadata cards. Dependencies: UI-POLICY-20-004. | | | +| UI-POLICY-23-002 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement YAML editor with schema validation, lint diagnostics, and live canonicalization preview. Dependencies: UI-POLICY-23-001. | | | +| UI-POLICY-23-003 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build guided rule builder (source preferences, severity mapping, VEX precedence, exceptions) with preview JSON output. Dependencies: UI-POLICY-23-002. | | | +| UI-POLICY-23-004 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add review/approval workflow UI: checklists, comments, two-person approval indicator, scope scheduling. Dependencies: UI-POLICY-23-003. | | | +| UI-POLICY-23-005 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Integrate simulator panel (SBOM/component/advisory selection), run diff vs active policy, show explain tree and overlays. Dependencies: UI-POLICY-23-004. | | | +| UI-POLICY-23-006 | TODO | | SPRINT_0210_0001_0002_ui_ii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Implement explain view linking to evidence overlays and exceptions; provide export to JSON/PDF. Dependencies: UI-POLICY-23-005. | | | +| UI-POLICY-27-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Product Ops (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Update Console policy workspace RBAC guards, scope requests, and user messaging to reflect the new Policy Studio roles/scopes (`policy:author/review/approve/operate/audit/simulate`), including Cypress auth stubs and help text. Dependencies: UI-POLICY-23-006. | | | +| UI-SIG-26-001 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild, Signals Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability columns/badges to Vulnerability Explorer with filters and tooltips. | | | +| UI-SIG-26-002 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Enhance “Why” drawer with call path visualization, reachability timeline, and evidence list. Dependencies: UI-SIG-26-001. | | | +| UI-SIG-26-003 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Add reachability overlay halos/time slider to SBOM Graph along with state legend. Dependencies: UI-SIG-26-002. | | | +| UI-SIG-26-004 | TODO | | SPRINT_0211_0001_0003_ui_iii | UI Guild (src/UI/StellaOps.UI) | src/UI/StellaOps.UI | Build Reachability Center view showing asset coverage, missing sensors, and stale facts. Dependencies: UI-SIG-26-003. | | | | UNCERTAINTY-POLICY-401-026 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Policy Guild · Concelier Guild (`docs/policy/dsl.md`, `docs/uncertainty/README.md`) | `docs/policy/dsl.md`, `docs/uncertainty/README.md` | Update policy guidance (Concelier/Excitors) with uncertainty gates (U1/U2/U3), sample YAML rules, and remediation actions. | | | | UNCERTAINTY-SCHEMA-401-024 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals`, `docs/uncertainty/README.md` | Extend Signals findings with `uncertainty.states[]`, entropy fields, and `riskScore`; emit `FindingUncertaintyUpdated` events and persist evidence per docs. | | | | UNCERTAINTY-SCORER-401-025 | TODO | | SPRINT_0401_0001_0001_reachability_evidence_chain | Signals Guild (`src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md`) | `src/Signals/StellaOps.Signals.Application`, `docs/uncertainty/README.md` | Implement the entropy-aware risk scorer (`riskScore = base × reach × trust × (1 + entropyBoost)`) and wire it into finding writes. | | | @@ -4305,19 +4305,19 @@ | WEB-CONTAINERS-45-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Ensure readiness endpoints reflect DB/queue readiness, add feature flag toggles via config map, and document NetworkPolicy ports. Dependencies: WEB-CONTAINERS-44-001. | | | | WEB-CONTAINERS-46-001 | DONE | 2025-11-19 | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide offline-friendly asset serving (no CDN), allow overriding object store endpoints via env, and document fallback behavior. Dependencies: WEB-CONTAINERS-45-001. | | | | WEB-EXC-25-001 | TODO | | SPRINT_0212_0001_0001_web_i | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement `/exceptions` API (create, propose, approve, revoke, list, history) with validation, pagination, and audit logging. | | | -| WEB-EXC-25-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | | -| WEB-EXC-25-003 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | | -| WEB-EXPORT-35-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | | -| WEB-EXPORT-36-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | | -| WEB-EXPORT-37-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | | -| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | | -| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | | -| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | | -| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_213_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | | -| WEB-GRAPH-24-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | | -| WEB-GRAPH-24-004 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | | -| WEB-LNM-21-001 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | | -| WEB-LNM-21-002 | TODO | | SPRINT_213_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | | +| WEB-EXC-25-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Extend `/policy/effective` and `/policy/simulate` responses to include exception metadata and accept overrides for simulations. Dependencies: WEB-EXC-25-001. | | | +| WEB-EXC-25-003 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Platform Events Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Publish `exception.*` events, integrate with notification hooks, enforce rate limits. Dependencies: WEB-EXC-25-002. | | | +| WEB-EXPORT-35-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | | | +| WEB-EXPORT-36-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | | | +| WEB-EXPORT-37-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | | | +| WEB-GRAPH-21-001 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Add gateway routes for graph versions/viewport/node/path/diff/export endpoints with tenant enforcement, scope checks, and streaming responses; proxy Policy Engine diff toggles without inline logic. Adopt `StellaOpsScopes` constants for RBAC enforcement. | | | +| WEB-GRAPH-21-002 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Implement bbox/zoom/path parameter validation, pagination tokens, and deterministic ordering; add contract tests for boundary conditions. Dependencies: WEB-GRAPH-21-001. | | | +| WEB-GRAPH-21-003 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, and document rate limits. Dependencies: WEB-GRAPH-21-002. | | | +| WEB-GRAPH-21-004 | BLOCKED | 2025-10-27 | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Proxy Policy Engine overlay responses for graph endpoints while keeping gateway stateless; maintain streaming budgets and latency SLOs. Dependencies: WEB-GRAPH-21-003. | | | +| WEB-GRAPH-24-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | | | +| WEB-GRAPH-24-004 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Embed AOC summaries sourced from overlay services; ensure gateway does not compute derived severity or hints. Dependencies: WEB-GRAPH-24-001. | | | +| WEB-LNM-21-001 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Concelier WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Surface new `/advisories/*` APIs through gateway with caching, pagination, and RBAC enforcement (`advisory:read`). | | | +| WEB-LNM-21-002 | TODO | | SPRINT_0213_0001_0002_web_ii | BE-Base Platform Guild, Excititor WebService Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Expose `/vex/*` read APIs with evidence routes and export handlers; map `ERR_AGG_*` codes. Dependencies: WEB-LNM-21-001. | | | | WEB-LNM-21-003 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) | src/Web/StellaOps.Web | Provide combined endpoint for Console to fetch policy result + source evidence (advisory + VEX linksets) for a component. Dependencies: WEB-LNM-21-002. | | | | WEB-NOTIFY-38-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Route notifier APIs (`/notifications/*`) and WS feed through gateway with tenant scoping, viewer/operator scope enforcement, and SSE/WebSocket bridging. | Depends on #1 for signed ack spec | NOWB0101 | | WEB-NOTIFY-39-001 | TODO | | SPRINT_214_web_iii | BE-Base Platform Guild | src/Web/StellaOps.Web | Surface digest scheduling, quiet-hour/throttle management, and simulation APIs; ensure rate limits and audit logging. Dependencies: WEB-NOTIFY-38-001. | WEB-NOTIFY-38-001 | NOWB0101 | diff --git a/docs/product-advisories/28-Nov-2025 - CLI Developer Experience and Command UX.md b/docs/product-advisories/28-Nov-2025 - CLI Developer Experience and Command UX.md index 5a8807959..9b491fc6a 100644 --- a/docs/product-advisories/28-Nov-2025 - CLI Developer Experience and Command UX.md +++ b/docs/product-advisories/28-Nov-2025 - CLI Developer Experience and Command UX.md @@ -375,7 +375,7 @@ Signer: release@stella-ops.io - **Primary Sprint:** SPRINT_0400_cli_ux.md (NEW) - **Related Sprints:** - - SPRINT_210_ui_ii.md (UI integration) + - SPRINT_0210_0001_0002_ui_ii.md (UI integration) - SPRINT_0187_0001_0001_evidence_locker_cli_integration.md (Evidence CLI) **Key Task IDs:** diff --git a/docs/product-advisories/28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md b/docs/product-advisories/28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md index 008ffbb38..72399a0bf 100644 --- a/docs/product-advisories/28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md +++ b/docs/product-advisories/28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md @@ -515,7 +515,7 @@ The following schemas should be created/maintained: This advisory maps to: - **SPRINT_0215_0001_0001_vuln_triage_ux.md** (NEW) - UI triage workspace implementation -- **SPRINT_210_ui_ii.md** - VEX tab tasks (UI-LNM-22-003) +- **SPRINT_0210_0001_0002_ui_ii.md** - VEX tab tasks (UI-LNM-22-003) - **SPRINT_0334_docs_modules_vuln_explorer.md** - Module documentation updates --- diff --git a/docs/product-advisories/ADVISORY_INDEX.md b/docs/product-advisories/ADVISORY_INDEX.md index 03c2a8769..f5e1f72d0 100644 --- a/docs/product-advisories/ADVISORY_INDEX.md +++ b/docs/product-advisories/ADVISORY_INDEX.md @@ -157,7 +157,7 @@ These are the authoritative advisories to reference for implementation: - **Canonical:** `28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md` - **Sprint:** SPRINT_0215_0001_0001_vuln_triage_ux.md (NEW) - **Related Sprints:** - - SPRINT_210_ui_ii.md (UI-LNM-22-003 VEX tab) + - SPRINT_0210_0001_0002_ui_ii.md (UI-LNM-22-003 VEX tab) - SPRINT_0334_docs_modules_vuln_explorer.md (docs) - **Related Advisories:** - `27-Nov-2025 - Explainability Layer for Vulnerability Verdicts.md` (evidence chain) diff --git a/ops/devops/airgap/README.md b/ops/devops/airgap/README.md index 8d446bf1c..e675fad29 100644 --- a/ops/devops/airgap/README.md +++ b/ops/devops/airgap/README.md @@ -12,5 +12,11 @@ Artifacts supporting `DEVOPS-AIRGAP-56-001`: - `build_mirror_bundle.py` — Generates mirror bundle manifest + checksums with dual-control approvals; optional cosign signing. Outputs `mirror-bundle-manifest.json`, `checksums.sha256`, and optional signature/cert. - `compose-syslog-smtp.yaml` — Local SMTP (MailHog) + syslog-ng stack for sealed environments. - `health_syslog_smtp.sh` — Brings up the syslog/SMTP stack via docker compose and performs health checks (MailHog API + syslog logger). +- `compose-observability.yaml` — Sealed-mode observability stack (Prometheus, Grafana, Tempo, Loki) with offline configs and healthchecks. +- `health_observability.sh` — Starts the observability stack and probes Prometheus/Grafana/Tempo/Loki readiness. +- `compose-syslog-smtp.yaml` + `syslog-ng.conf` — Local SMTP + syslog stack for sealed-mode notifications; run via `scripts/devops/run-smtp-syslog.sh` (health check `health_syslog_smtp.sh`). +- `observability-offline-compose.yml` + `otel-offline.yaml` + `promtail-config.yaml` — Sealed-mode observability stack (Loki, Promtail, OTEL collector with file exporters) to satisfy DEVOPS-AIRGAP-58-002. +- `compose-syslog-smtp.yaml` — Local SMTP (MailHog) + syslog-ng stack for sealed environments. +- `health_syslog_smtp.sh` — Brings up the syslog/SMTP stack via docker compose and performs health checks (MailHog API + syslog logger). See also `ops/devops/sealed-mode-ci/` for the full sealed-mode compose harness and `egress_probe.py`, which this verification script wraps. diff --git a/ops/devops/airgap/compose-observability.yaml b/ops/devops/airgap/compose-observability.yaml new file mode 100644 index 000000000..8b1a6865f --- /dev/null +++ b/ops/devops/airgap/compose-observability.yaml @@ -0,0 +1,77 @@ +version: "3.9" + +services: + prometheus: + image: prom/prometheus:v2.53.0 + container_name: prometheus + command: + - --config.file=/etc/prometheus/prometheus.yml + volumes: + - ./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro + ports: + - "9090:9090" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:9090/-/ready"] + interval: 15s + timeout: 5s + retries: 5 + start_period: 10s + restart: unless-stopped + + loki: + image: grafana/loki:3.0.0 + container_name: loki + command: ["-config.file=/etc/loki/config.yaml"] + volumes: + - ./observability/loki-config.yaml:/etc/loki/config.yaml:ro + - ./observability/data/loki:/loki + ports: + - "3100:3100" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:3100/ready"] + interval: 15s + timeout: 5s + retries: 5 + start_period: 15s + restart: unless-stopped + + tempo: + image: grafana/tempo:2.4.1 + container_name: tempo + command: ["-config.file=/etc/tempo/tempo.yaml"] + volumes: + - ./observability/tempo-config.yaml:/etc/tempo/tempo.yaml:ro + - ./observability/data/tempo:/var/tempo + ports: + - "3200:3200" + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:3200/ready"] + interval: 15s + timeout: 5s + retries: 5 + start_period: 15s + restart: unless-stopped + + grafana: + image: grafana/grafana:10.4.2 + container_name: grafana + environment: + - GF_AUTH_ANONYMOUS_ENABLED=true + - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin + - GF_SECURITY_ADMIN_PASSWORD=admin + - GF_SECURITY_ADMIN_USER=admin + volumes: + - ./observability/grafana/provisioning/datasources:/etc/grafana/provisioning/datasources:ro + ports: + - "3000:3000" + depends_on: + - prometheus + - loki + - tempo + healthcheck: + test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/health"] + interval: 15s + timeout: 5s + retries: 5 + start_period: 20s + restart: unless-stopped diff --git a/ops/devops/airgap/compose-syslog-smtp.yaml b/ops/devops/airgap/compose-syslog-smtp.yaml index 55d630445..5cb9e0359 100644 --- a/ops/devops/airgap/compose-syslog-smtp.yaml +++ b/ops/devops/airgap/compose-syslog-smtp.yaml @@ -1,31 +1,23 @@ -version: "3.9" - +version: '3.8' services: smtp: - image: mailhog/mailhog:v1.0.1 - container_name: mailhog - ports: - - "1025:1025" # SMTP (plain) - - "8025:8025" # Web UI - healthcheck: - test: ["CMD", "wget", "-qO-", "http://localhost:8025/api/v2/health"] - interval: 10s - timeout: 3s - retries: 5 - start_period: 5s + image: bytemark/smtp restart: unless-stopped - + environment: + - MAILNAME=sealed.local + networks: [sealed] + ports: + - "2525:25" syslog: image: balabit/syslog-ng:4.7.1 - container_name: syslog-ng - ports: - - "514:514/udp" - - "514:514/tcp" - command: ["/usr/sbin/syslog-ng", "-F", "-p", "/var/run/syslogd.pid"] - healthcheck: - test: ["CMD", "syslog-ng-ctl", "stats"] - interval: 10s - timeout: 3s - retries: 5 - start_period: 5s restart: unless-stopped + command: ["syslog-ng", "-F", "--no-caps"] + networks: [sealed] + ports: + - "5514:514/udp" + - "5515:601/tcp" + volumes: + - ./syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf:ro +networks: + sealed: + driver: bridge diff --git a/ops/devops/airgap/health_observability.sh b/ops/devops/airgap/health_observability.sh new file mode 100644 index 000000000..2a3f89ed2 --- /dev/null +++ b/ops/devops/airgap/health_observability.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Health check for compose-observability.yaml (DEVOPS-AIRGAP-58-002) + +COMPOSE_FILE="$(cd "$(dirname "$0")" && pwd)/compose-observability.yaml" + +echo "Starting observability stack (Prometheus/Grafana/Tempo/Loki)..." +docker compose -f "$COMPOSE_FILE" up -d + +echo "Waiting for containers to report healthy..." +docker compose -f "$COMPOSE_FILE" wait >/dev/null 2>&1 || true + +docker compose -f "$COMPOSE_FILE" ps + +echo "Probing Prometheus /-/ready" +curl -sf http://127.0.0.1:9090/-/ready + +echo "Probing Grafana /api/health" +curl -sf http://127.0.0.1:3000/api/health + +echo "Probing Loki /ready" +curl -sf http://127.0.0.1:3100/ready + +echo "Probing Tempo /ready" +curl -sf http://127.0.0.1:3200/ready + +echo "All probes succeeded." diff --git a/ops/devops/airgap/health_syslog_smtp.sh b/ops/devops/airgap/health_syslog_smtp.sh index 1383b2357..29b4f6ccf 100644 --- a/ops/devops/airgap/health_syslog_smtp.sh +++ b/ops/devops/airgap/health_syslog_smtp.sh @@ -1,23 +1,33 @@ #!/usr/bin/env bash set -euo pipefail - # Health check for compose-syslog-smtp.yaml (DEVOPS-AIRGAP-58-001) +ROOT=${ROOT:-$(git rev-parse --show-toplevel)} +COMPOSE_FILE="${COMPOSE_FILE:-$ROOT/ops/devops/airgap/compose-syslog-smtp.yaml}" +SMTP_PORT=${SMTP_PORT:-2525} +SYSLOG_TCP=${SYSLOG_TCP:-5515} +SYSLOG_UDP=${SYSLOG_UDP:-5514} -COMPOSE_FILE="$(cd "$(dirname "$0")" && pwd)/compose-syslog-smtp.yaml" +export COMPOSE_FILE +# ensure stack up +if ! docker compose ps >/dev/null 2>&1; then + docker compose up -d +fi +sleep 2 -echo "Starting syslog+smtp stack..." -docker compose -f "$COMPOSE_FILE" up -d +# probe smtp banner +if ! timeout 5 bash -lc "echo QUIT | nc -w2 127.0.0.1 ${SMTP_PORT}" >/dev/null 2>&1; then + echo "smtp service not responding on ${SMTP_PORT}" >&2 + exit 1 +fi +# probe syslog tcp +if ! echo "test" | nc -w2 127.0.0.1 ${SYSLOG_TCP} >/dev/null 2>&1; then + echo "syslog tcp not responding on ${SYSLOG_TCP}" >&2 + exit 1 +fi +# probe syslog udp +if ! echo "test" | nc -w2 -u 127.0.0.1 ${SYSLOG_UDP} >/dev/null 2>&1; then + echo "syslog udp not responding on ${SYSLOG_UDP}" >&2 + exit 1 +fi -echo "Waiting for health checks..." -docker compose -f "$COMPOSE_FILE" wait >/dev/null 2>&1 || true - -echo "Current health status:" -docker compose -f "$COMPOSE_FILE" ps - -echo "Sending test syslog message (UDP)..." -logger -n 127.0.0.1 -P 514 -d "test syslog message $(date -u +%s)" - -echo "SMTP health endpoint:" -curl -sf http://127.0.0.1:8025/api/v2/health || exit 1 - -echo "Done." +echo "smtp/syslog stack healthy" diff --git a/ops/devops/airgap/observability-offline-compose.yml b/ops/devops/airgap/observability-offline-compose.yml new file mode 100644 index 000000000..1d7662c25 --- /dev/null +++ b/ops/devops/airgap/observability-offline-compose.yml @@ -0,0 +1,32 @@ +version: '3.8' +services: + loki: + image: grafana/loki:3.0.1 + command: ["-config.file=/etc/loki/local-config.yaml"] + volumes: + - loki-data:/loki + networks: [sealed] + promtail: + image: grafana/promtail:3.0.1 + command: ["-config.file=/etc/promtail/config.yml"] + volumes: + - promtail-data:/var/log + - ./promtail-config.yaml:/etc/promtail/config.yml:ro + networks: [sealed] + otel: + image: otel/opentelemetry-collector-contrib:0.97.0 + command: ["--config=/etc/otel/otel-offline.yaml"] + volumes: + - ./otel-offline.yaml:/etc/otel/otel-offline.yaml:ro + - otel-data:/var/otel + ports: + - "4317:4317" + - "4318:4318" + networks: [sealed] +networks: + sealed: + driver: bridge +volumes: + loki-data: + promtail-data: + otel-data: diff --git a/ops/devops/airgap/observability/grafana/provisioning/datasources/datasources.yaml b/ops/devops/airgap/observability/grafana/provisioning/datasources/datasources.yaml new file mode 100644 index 000000000..5d0e6fc33 --- /dev/null +++ b/ops/devops/airgap/observability/grafana/provisioning/datasources/datasources.yaml @@ -0,0 +1,16 @@ +apiVersion: 1 + +datasources: + - name: Prometheus + type: prometheus + access: proxy + url: http://prometheus:9090 + isDefault: true + - name: Loki + type: loki + access: proxy + url: http://loki:3100 + - name: Tempo + type: tempo + access: proxy + url: http://tempo:3200 diff --git a/ops/devops/airgap/observability/loki-config.yaml b/ops/devops/airgap/observability/loki-config.yaml new file mode 100644 index 000000000..1342fda3b --- /dev/null +++ b/ops/devops/airgap/observability/loki-config.yaml @@ -0,0 +1,35 @@ +server: + http_listen_port: 3100 + log_level: warn + +common: + ring: + instance_addr: loki + kvstore: + store: inmemory + replication_factor: 1 + +table_manager: + retention_deletes_enabled: true + retention_period: 168h + +schema_config: + configs: + - from: 2024-01-01 + store: boltdb-shipper + object_store: filesystem + schema: v13 + index: + prefix: index_ + period: 24h + +storage_config: + filesystem: + directory: /loki/chunks + boltdb_shipper: + active_index_directory: /loki/index + cache_location: /loki/cache + shared_store: filesystem + +limits_config: + retention_period: 168h diff --git a/ops/devops/airgap/observability/prometheus.yml b/ops/devops/airgap/observability/prometheus.yml new file mode 100644 index 000000000..1b49895e8 --- /dev/null +++ b/ops/devops/airgap/observability/prometheus.yml @@ -0,0 +1,14 @@ +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: prometheus + static_configs: + - targets: ['prometheus:9090'] + - job_name: loki + static_configs: + - targets: ['loki:3100'] + - job_name: tempo + static_configs: + - targets: ['tempo:3200'] diff --git a/ops/devops/airgap/observability/tempo-config.yaml b/ops/devops/airgap/observability/tempo-config.yaml new file mode 100644 index 000000000..4b43e2195 --- /dev/null +++ b/ops/devops/airgap/observability/tempo-config.yaml @@ -0,0 +1,26 @@ +server: + http_listen_port: 3200 + log_level: warn + +distributor: + receivers: + jaeger: + protocols: + thrift_http: + otlp: + protocols: + http: + grpc: + zipkin: + +storage: + trace: + backend: local + wal: + path: /var/tempo/wal + local: + path: /var/tempo/traces + +compactor: + compaction: + block_retention: 168h diff --git a/ops/devops/airgap/otel-offline.yaml b/ops/devops/airgap/otel-offline.yaml new file mode 100644 index 000000000..7879cb072 --- /dev/null +++ b/ops/devops/airgap/otel-offline.yaml @@ -0,0 +1,40 @@ +receivers: + prometheus: + config: + scrape_configs: + - job_name: 'self' + static_configs: + - targets: ['localhost:8888'] + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 +processors: + batch: + timeout: 1s + send_batch_size: 512 +exporters: + file/metrics: + path: /var/otel/metrics.prom + file/traces: + path: /var/otel/traces.ndjson + loki/offline: + endpoint: http://loki:3100/loki/api/v1/push + labels: + job: sealed-observability + tenant_id: "sealed" +service: + telemetry: + logs: + level: info + pipelines: + metrics: + receivers: [prometheus] + processors: [batch] + exporters: [file/metrics] + traces: + receivers: [otlp] + processors: [batch] + exporters: [file/traces] diff --git a/ops/devops/airgap/promtail-config.yaml b/ops/devops/airgap/promtail-config.yaml new file mode 100644 index 000000000..8cf66b98f --- /dev/null +++ b/ops/devops/airgap/promtail-config.yaml @@ -0,0 +1,14 @@ +server: + http_listen_port: 9080 + grpc_listen_port: 0 +positions: + filename: /tmp/positions.yaml +clients: + - url: http://loki:3100/loki/api/v1/push +scrape_configs: + - job_name: promtail + static_configs: + - targets: [localhost] + labels: + job: promtail + __path__: /var/log/*.log diff --git a/ops/devops/airgap/syslog-ng.conf b/ops/devops/airgap/syslog-ng.conf new file mode 100644 index 000000000..89292a704 --- /dev/null +++ b/ops/devops/airgap/syslog-ng.conf @@ -0,0 +1,19 @@ +@version: 4.7 +@include "scl.conf" + +options { + time-reopen(10); + log-msg-size(8192); + ts-format(iso); +}; + +source s_net { + tcp(port(601)); + udp(port(514)); +}; + +destination d_file { + file("/var/log/syslog-ng/sealed.log" create-dirs(yes) perm(0644)); +}; + +log { source(s_net); destination(d_file); }; diff --git a/scripts/devops/run-smtp-syslog.sh b/scripts/devops/run-smtp-syslog.sh new file mode 100644 index 000000000..8af3bd397 --- /dev/null +++ b/scripts/devops/run-smtp-syslog.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail +# Bring up local SMTP+syslog stack for sealed-mode tests (DEVOPS-AIRGAP-58-001) +ROOT=${ROOT:-$(git rev-parse --show-toplevel)} +COMPOSE_FILE=${COMPOSE_FILE:-$ROOT/ops/devops/airgap/smtp-syslog-compose.yml} +export COMPOSE_FILE +exec docker compose up -d diff --git a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/Program.cs b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/Program.cs index f6d801251..b370a65dd 100644 --- a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/Program.cs +++ b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/Program.cs @@ -1,8 +1,10 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; using StellaOps.ExportCenter.Core.DevPortalOffline; using StellaOps.ExportCenter.Infrastructure.DevPortalOffline; using StellaOps.ExportCenter.Worker; +using StellaOps.ExportCenter.RiskBundles; var builder = Host.CreateApplicationBuilder(args); @@ -11,12 +13,27 @@ builder.Services.AddSingleton(TimeProvider.System); builder.Services.Configure(builder.Configuration.GetSection("DevPortalOffline")); builder.Services.Configure(builder.Configuration.GetSection("DevPortalOffline:Signing")); builder.Services.Configure(builder.Configuration.GetSection("DevPortalOffline:Storage")); +builder.Services.Configure(builder.Configuration.GetSection("RiskBundles")); +builder.Services.Configure(builder.Configuration.GetSection("RiskBundles:Signing")); +builder.Services.Configure(builder.Configuration.GetSection("RiskBundles:Storage")); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(sp => +{ + var signing = sp.GetRequiredService>().Value; + var key = string.IsNullOrWhiteSpace(signing.Key) ? throw new InvalidOperationException("Risk bundle signing key is not configured.") : signing.Key; + var keyId = string.IsNullOrWhiteSpace(signing.KeyId) ? "risk-bundle-hmac" : signing.KeyId!; + return new HmacRiskBundleManifestSigner(key, keyId); +}); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); + builder.Services.AddHostedService(); +builder.Services.AddHostedService(); var host = builder.Build(); host.Run(); diff --git a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/RiskBundleWorker.cs b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/RiskBundleWorker.cs new file mode 100644 index 000000000..b48351e59 --- /dev/null +++ b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/RiskBundleWorker.cs @@ -0,0 +1,81 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using StellaOps.ExportCenter.RiskBundles; + +namespace StellaOps.ExportCenter.Worker; + +public sealed class RiskBundleWorker : BackgroundService +{ + private readonly ILogger _logger; + private readonly RiskBundleJob _job; + private readonly IOptions _options; + + public RiskBundleWorker( + ILogger logger, + RiskBundleJob job, + IOptions options) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _job = job ?? throw new ArgumentNullException(nameof(job)); + _options = options ?? throw new ArgumentNullException(nameof(options)); + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + var opts = _options.Value ?? new RiskBundleWorkerOptions(); + + if (!opts.Enabled) + { + _logger.LogInformation("Risk bundle worker disabled. Idling."); + await Task.Delay(Timeout.Infinite, stoppingToken).ConfigureAwait(false); + return; + } + + try + { + var request = BuildRequest(opts); + var outcome = await _job.ExecuteAsync(request, stoppingToken).ConfigureAwait(false); + + _logger.LogInformation( + "Risk bundle built with {ProviderCount} providers. Stored bundle={BundleKey} manifest={ManifestKey} signature={SignatureKey}.", + outcome.Manifest.Providers.Count, + outcome.BundleStorage.StorageKey, + outcome.ManifestStorage.StorageKey, + outcome.ManifestSignatureStorage.StorageKey); + } + catch (Exception ex) when (!stoppingToken.IsCancellationRequested) + { + _logger.LogError(ex, "Risk bundle job failed."); + throw; + } + + await Task.Delay(Timeout.Infinite, stoppingToken).ConfigureAwait(false); + } + + private static RiskBundleJobRequest BuildRequest(RiskBundleWorkerOptions options) + { + if (options.Providers is not { Count: > 0 }) + { + throw new InvalidOperationException("Risk bundle worker requires at least one provider entry."); + } + + var bundleId = options.BundleId ?? Guid.NewGuid(); + var providers = options.Providers + .Select(p => p.ToInput()) + .ToArray(); + + var build = new RiskBundleBuildRequest( + bundleId, + providers, + BundleFileName: options.BundleFileName ?? "risk-bundle.tar.gz", + BundlePrefix: options.StoragePrefix ?? "risk-bundles", + ManifestFileName: options.ManifestFileName ?? "provider-manifest.json", + ManifestDsseFileName: options.ManifestDsseFileName ?? "provider-manifest.dsse", + AllowMissingOptional: options.AllowMissingOptional); + + return new RiskBundleJobRequest( + build, + StoragePrefix: options.StoragePrefix ?? "risk-bundles", + BundleFileName: options.BundleFileName ?? "risk-bundle.tar.gz"); + } +} diff --git a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/RiskBundleWorkerOptions.cs b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/RiskBundleWorkerOptions.cs new file mode 100644 index 000000000..4bc62e8e9 --- /dev/null +++ b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/RiskBundleWorkerOptions.cs @@ -0,0 +1,69 @@ +using System.ComponentModel.DataAnnotations; +using StellaOps.ExportCenter.RiskBundles; + +namespace StellaOps.ExportCenter.Worker; + +public sealed class RiskBundleWorkerOptions +{ + public bool Enabled { get; set; } = false; + + public Guid? BundleId { get; set; } + + public string? StoragePrefix { get; set; } = "risk-bundles"; + + public string? BundleFileName { get; set; } = "risk-bundle.tar.gz"; + + public string? ManifestFileName { get; set; } = "provider-manifest.json"; + + public string? ManifestDsseFileName { get; set; } = "provider-manifest.dsse"; + + public bool AllowMissingOptional { get; set; } = true; + + [MinLength(1)] + public List Providers { get; set; } = new(); +} + +public sealed class RiskBundleProviderOption +{ + public string? ProviderId { get; set; } + public string? SourcePath { get; set; } + public string? Source { get; set; } + public bool Optional { get; set; } + public DateOnly? SnapshotDate { get; set; } + + public RiskBundleProviderInput ToInput() + { + if (string.IsNullOrWhiteSpace(ProviderId)) + { + throw new ValidationException("ProviderId is required for risk bundle provider options."); + } + + if (string.IsNullOrWhiteSpace(SourcePath)) + { + throw new ValidationException("SourcePath is required for risk bundle provider options."); + } + + if (string.IsNullOrWhiteSpace(Source)) + { + throw new ValidationException("Source descriptor is required for risk bundle provider options."); + } + + return new RiskBundleProviderInput( + ProviderId, + SourcePath, + Source, + Optional, + SnapshotDate); + } +} + +public sealed class RiskBundleManifestSigningOptions +{ + public string? Key { get; set; } + public string? KeyId { get; set; } +} + +public sealed class RiskBundleStorageOptions +{ + public string? RootPath { get; set; } +} diff --git a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/StellaOps.ExportCenter.Worker.csproj b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/StellaOps.ExportCenter.Worker.csproj index 32868f402..8eb91277f 100644 --- a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/StellaOps.ExportCenter.Worker.csproj +++ b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/StellaOps.ExportCenter.Worker.csproj @@ -28,16 +28,19 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.Development.json b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.Development.json index 690176464..13ec84395 100644 --- a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.Development.json +++ b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.Development.json @@ -1,8 +1,26 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.Hosting.Lifetime": "Information" - } - } -} + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "RiskBundles": { + "Enabled": false, + "Storage": { + "RootPath": "./out/risk-bundles-dev" + }, + "Signing": { + "Key": "dev-risk-bundle-key", + "KeyId": "risk-bundle-hmac" + }, + "Providers": [ + { + "ProviderId": "cisa-kev", + "SourcePath": "./inputs/kev.json", + "Source": "CISA KEV", + "Optional": false + } + ] + } +} diff --git a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.json b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.json index 695eae252..d8f062127 100644 --- a/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.json +++ b/src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/appsettings.json @@ -5,6 +5,35 @@ "Microsoft.Hosting.Lifetime": "Information" } }, + "RiskBundles": { + "Enabled": false, + "StoragePrefix": "risk-bundles", + "BundleFileName": "risk-bundle.tar.gz", + "ManifestFileName": "provider-manifest.json", + "ManifestDsseFileName": "provider-manifest.dsse", + "AllowMissingOptional": true, + "Storage": { + "RootPath": "./out/risk-bundles" + }, + "Signing": { + "Key": "change-me-risk-bundle-key", + "KeyId": "risk-bundle-hmac" + }, + "Providers": [ + { + "ProviderId": "cisa-kev", + "SourcePath": "./inputs/kev.json", + "Source": "CISA KEV", + "Optional": false + }, + { + "ProviderId": "first-epss", + "SourcePath": "./inputs/epss.csv", + "Source": "FIRST EPSS", + "Optional": true + } + ] + }, "DevPortalOffline": { "Enabled": false, "StoragePrefix": "devportal/offline", diff --git a/src/Notify/__Libraries/StellaOps.Notify.Storage.Postgres/AGENTS.md b/src/Notify/__Libraries/StellaOps.Notify.Storage.Postgres/AGENTS.md new file mode 100644 index 000000000..68507617e --- /dev/null +++ b/src/Notify/__Libraries/StellaOps.Notify.Storage.Postgres/AGENTS.md @@ -0,0 +1,19 @@ +# StellaOps.Notify.Storage.Postgres — Agent Charter + +## Mission +Deliver PostgreSQL-backed persistence for Notify (channels, rules, templates, deliveries, digests, quiet hours, maintenance windows, escalations, inbox, incidents, audit) per `docs/db/SPECIFICATION.md` §5.5 and enable the Mongo → Postgres cutover. + +## Required Reading +- docs/modules/notify/architecture.md +- docs/db/README.md +- docs/db/SPECIFICATION.md (Notify schema §5.5) +- docs/db/RULES.md +- docs/db/VERIFICATION.md +- docs/modules/platform/architecture-overview.md + +## Working Agreement +- Update related sprint rows in `docs/implplan/SPRINT_*.md` when starting/finishing work; keep statuses `TODO → DOING → DONE/BLOCKED`. +- Follow deterministic/offline posture: stable ordering, UTC timestamps, idempotent migrations; use the curated NuGet cache at `local-nugets/`. +- Keep schema/migrations aligned with `docs/db/SPECIFICATION.md`; add/extend tests under this project to cover repository contracts against PostgreSQL. +- Mirror any contract change (schema, repository signatures, DI wiring) into the appropriate docs (`docs/db/SPECIFICATION.md`, module architecture) and note it in sprint Decisions & Risks. +- Coordinate with `StellaOps.Notify.Engine` and channel connectors for behavioural changes; avoid cross-module edits unless the sprint explicitly allows and logs them. diff --git a/src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/SurfaceManifestStageExecutorTests.cs b/src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/SurfaceManifestStageExecutorTests.cs index 208a873f4..0429624a5 100644 --- a/src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/SurfaceManifestStageExecutorTests.cs +++ b/src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/SurfaceManifestStageExecutorTests.cs @@ -228,9 +228,9 @@ public sealed class SurfaceManifestStageExecutorTests Assert.Equal(3, cache.Entries.Count); } - private static ScanJobContext CreateContext() + private static ScanJobContext CreateContext(Dictionary? metadata = null) { - var lease = new FakeJobLease(); + var lease = new FakeJobLease(metadata); return new ScanJobContext(lease, TimeProvider.System, DateTimeOffset.UtcNow, CancellationToken.None); } @@ -379,6 +379,60 @@ public sealed class SurfaceManifestStageExecutorTests Assert.Contains(cache.Entries.Keys, key => key.Namespace == "surface.artifacts.deno.observation"); } + [Fact] + public async Task ExecuteAsync_WritesDeterminismPayloadWithPinsAndSettings() + { + var metrics = new ScannerWorkerMetrics(); + var publisher = new TestSurfaceManifestPublisher("tenant-a"); + var cache = new RecordingSurfaceCache(); + var environment = new TestSurfaceEnvironment("tenant-a"); + var hash = CreateCryptoHash(); + var determinism = new DeterminismContext( + fixedClock: true, + fixedInstantUtc: DateTimeOffset.Parse("2025-11-30T12:00:00Z"), + rngSeed: 4242, + filterLogs: true, + concurrencyLimit: 2); + + var executor = new SurfaceManifestStageExecutor( + publisher, + cache, + environment, + metrics, + NullLogger.Instance, + hash, + new NullRubyPackageInventoryStore(), + determinism); + + var leaseMetadata = new Dictionary + { + ["determinism.feed"] = "sha256:feed", + ["determinism.policy"] = "sha256:policy" + }; + + var context = CreateContext(leaseMetadata); + PopulateAnalysis(context); + + await executor.ExecuteAsync(context, CancellationToken.None); + + var determinismPayload = Assert.Single(publisher.LastRequest!.Payloads, p => p.Kind == "determinism.json"); + using var document = JsonDocument.Parse(determinismPayload.Content); + var root = document.RootElement; + + Assert.True(root.GetProperty("fixedClock").GetBoolean()); + Assert.Equal("2025-11-30T12:00:00+00:00", root.GetProperty("fixedInstantUtc").GetString()); + Assert.Equal(4242, root.GetProperty("rngSeed").GetInt32()); + Assert.True(root.GetProperty("filterLogs").GetBoolean()); + Assert.Equal(2, root.GetProperty("concurrencyLimit").GetInt32()); + + var pins = root.GetProperty("pins"); + Assert.Equal("sha256:feed", pins.GetProperty("feed").GetString()); + Assert.Equal("sha256:policy", pins.GetProperty("policy").GetString()); + + Assert.True(root.TryGetProperty("merkleRoot", out var merkle)); + Assert.False(string.IsNullOrWhiteSpace(merkle.GetString())); + } + private sealed class RecordingSurfaceCache : ISurfaceCache { private readonly Dictionary _entries = new(); @@ -601,11 +655,24 @@ public sealed class SurfaceManifestStageExecutorTests private sealed class FakeJobLease : IScanJobLease { - private readonly Dictionary _metadata = new() + private readonly Dictionary _metadata; + + public FakeJobLease(Dictionary? extraMetadata = null) { - ["queue"] = "tests", - ["job.kind"] = "unit" - }; + _metadata = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["queue"] = "tests", + ["job.kind"] = "unit" + }; + + if (extraMetadata is not null) + { + foreach (var kvp in extraMetadata) + { + _metadata[kvp.Key] = kvp.Value; + } + } + } public string JobId { get; } = Guid.NewGuid().ToString("n"); diff --git a/src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Postgres/Repositories/TriggerRepository.cs b/src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Postgres/Repositories/TriggerRepository.cs index f456b6ae4..9f63ceecd 100644 --- a/src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Postgres/Repositories/TriggerRepository.cs +++ b/src/Scheduler/__Libraries/StellaOps.Scheduler.Storage.Postgres/Repositories/TriggerRepository.cs @@ -93,7 +93,7 @@ public sealed class TriggerRepository : RepositoryBase, ITr metadata, created_at, updated_at, created_by FROM scheduler.triggers WHERE enabled = TRUE AND next_fire_at <= NOW() - ORDER BY next_fire_at + ORDER BY next_fire_at, tenant_id, id LIMIT @limit """; diff --git a/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/DistributedLockRepositoryTests.cs b/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/DistributedLockRepositoryTests.cs index c486fd35a..df32729c8 100644 --- a/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/DistributedLockRepositoryTests.cs +++ b/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/DistributedLockRepositoryTests.cs @@ -126,4 +126,56 @@ public sealed class DistributedLockRepositoryTests : IAsyncLifetime // Assert locks.Should().HaveCount(2); } + + [Fact] + public async Task TryAcquire_IsExclusiveAcrossConcurrentCallers() + { + // Arrange + var lockKey = $"concurrent-lock-{Guid.NewGuid()}"; + var duration = TimeSpan.FromSeconds(5); + + // Act + var attempts = Enumerable.Range(0, 8) + .Select(i => Task.Run(() => _repository.TryAcquireAsync(_tenantId, lockKey, $"worker-{i}", duration))) + .ToArray(); + + var results = await Task.WhenAll(attempts); + + // Assert + var successIndexes = results + .Select((acquired, index) => (acquired, index)) + .Where(tuple => tuple.acquired) + .Select(tuple => tuple.index) + .ToList(); + + successIndexes.Should().HaveCount(1); + var winningHolder = $"worker-{successIndexes.Single()}"; + + var persisted = await _repository.GetAsync(lockKey); + persisted.Should().NotBeNull(); + persisted!.HolderId.Should().Be(winningHolder); + } + + [Fact] + public async Task TryAcquire_AllowsReacquireAfterExpiration() + { + // Arrange + var lockKey = $"expiring-lock-{Guid.NewGuid()}"; + var shortDuration = TimeSpan.FromMilliseconds(500); + + await _repository.TryAcquireAsync(_tenantId, lockKey, "worker-initial", shortDuration); + + // Wait for expiration with a small safety buffer. + await Task.Delay(1100); + + // Act + var reacquired = await _repository.TryAcquireAsync(_tenantId, lockKey, "worker-retry", TimeSpan.FromSeconds(5)); + + // Assert + reacquired.Should().BeTrue(); + + var persisted = await _repository.GetAsync(lockKey); + persisted.Should().NotBeNull(); + persisted!.HolderId.Should().Be("worker-retry"); + } } diff --git a/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/TriggerRepositoryTests.cs b/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/TriggerRepositoryTests.cs index 9de5360a2..8c4dc0f49 100644 --- a/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/TriggerRepositoryTests.cs +++ b/src/Scheduler/__Tests/StellaOps.Scheduler.Storage.Postgres.Tests/TriggerRepositoryTests.cs @@ -185,14 +185,55 @@ public sealed class TriggerRepositoryTests : IAsyncLifetime fetched.Should().BeNull(); } - private TriggerEntity CreateTrigger(string name, string cron) => new() + [Fact] + public async Task GetDueTriggers_IsDeterministicForEqualNextFire() { - Id = Guid.NewGuid(), - TenantId = _tenantId, + // Arrange + var baseTime = DateTimeOffset.UtcNow.AddMinutes(-5); + var dueAt = new DateTimeOffset( + baseTime.Ticks - (baseTime.Ticks % TimeSpan.TicksPerMillisecond), + baseTime.Offset); + + const string tenantA = "tenant-a"; + const string tenantB = "tenant-b"; + + var triggerA = CreateTrigger("deterministic-a", "* * * * *", Guid.Parse("11111111-1111-1111-1111-111111111111"), dueAt, tenantA); + var triggerB = CreateTrigger("deterministic-b", "* * * * *", Guid.Parse("22222222-2222-2222-2222-222222222222"), dueAt, tenantA); + var triggerC = CreateTrigger("deterministic-c", "* * * * *", Guid.Parse("33333333-3333-3333-3333-333333333333"), dueAt, tenantB); + + await _repository.CreateAsync(triggerB); + await _repository.CreateAsync(triggerC); + await _repository.CreateAsync(triggerA); // Insert out of order on purpose + + var expectedOrder = new[] + { + triggerA.Id, + triggerB.Id, + triggerC.Id + }; + + // Act + var first = await _repository.GetDueTriggersAsync(limit: 10); + var second = await _repository.GetDueTriggersAsync(limit: 10); + + // Assert + first.Select(t => t.Id).Should().Equal(expectedOrder); + second.Select(t => t.Id).Should().Equal(expectedOrder); + } + + private TriggerEntity CreateTrigger( + string name, + string cron, + Guid? id = null, + DateTimeOffset? nextFireAt = null, + string? tenantId = null) => new() + { + Id = id ?? Guid.NewGuid(), + TenantId = tenantId ?? _tenantId, Name = name, JobType = "test-job", CronExpression = cron, Enabled = true, - NextFireAt = DateTimeOffset.UtcNow.AddHours(1) + NextFireAt = nextFireAt ?? DateTimeOffset.UtcNow.AddHours(1) }; } diff --git a/src/TaskRunner/StellaOps.TaskRunner/TASKS.md b/src/TaskRunner/StellaOps.TaskRunner/TASKS.md index fad5fafd7..60087b152 100644 --- a/src/TaskRunner/StellaOps.TaskRunner/TASKS.md +++ b/src/TaskRunner/StellaOps.TaskRunner/TASKS.md @@ -4,7 +4,7 @@ | --- | --- | --- | --- | --- | | TASKRUN-41-001 | DONE (2025-11-30) | SPRINT_0157_0001_0001_taskrunner_i | — | Implemented run API, Mongo/file stores, approvals, provenance manifest per architecture contract. | | TASKRUN-AIRGAP-56-001 | DONE (2025-11-30) | SPRINT_0157_0001_0001_taskrunner_i | TASKRUN-41-001 | Sealed-mode plan validation; depends on 41-001. | -| TASKRUN-AIRGAP-56-002 | BLOCKED (2025-11-30) | SPRINT_0157_0001_0001_taskrunner_i | TASKRUN-AIRGAP-56-001 | Bundle ingestion helpers; depends on 56-001. | +| TASKRUN-AIRGAP-56-002 | DOING (2025-12-01) | SPRINT_0157_0001_0001_taskrunner_i | TASKRUN-AIRGAP-56-001 | Bundle ingestion helpers; depends on 56-001. | | TASKRUN-AIRGAP-57-001 | BLOCKED (2025-11-30) | SPRINT_0157_0001_0001_taskrunner_i | TASKRUN-AIRGAP-56-002 | Sealed install enforcement; depends on 56-002. | | TASKRUN-AIRGAP-58-001 | BLOCKED (2025-11-30) | SPRINT_0157_0001_0001_taskrunner_i | TASKRUN-AIRGAP-57-001 | Evidence bundles for imports; depends on 57-001. | | TASKRUN-42-001 | BLOCKED (2025-11-25) | SPRINT_0157_0001_0001_taskrunner_i | — | Execution engine enhancements (loops/conditionals/maxParallel), simulation mode, policy gate integration. Blocked: loop/conditional semantics and policy-gate evaluation contract not published. | diff --git a/src/UI/StellaOps.UI/TASKS.md b/src/UI/StellaOps.UI/TASKS.md new file mode 100644 index 000000000..32632beaa --- /dev/null +++ b/src/UI/StellaOps.UI/TASKS.md @@ -0,0 +1,8 @@ +# UI Sprint Tasks (Vulnerability Triage UX) + +| Task ID | Status | Notes | Updated (UTC) | +| --- | --- | --- | --- | +| UI-TRIAGE-01-001 | BLOCKED | src/UI/StellaOps.UI contains no Angular workspace; need project files restored before UI list view can be built. | 2025-11-30 | +| TS-10-001 | BLOCKED | TypeScript interface generation blocked: workspace missing and schemas not present locally. | 2025-11-30 | +| TS-10-002 | BLOCKED | Same as TS-10-001; waiting on schemas + workspace. | 2025-11-30 | +| TS-10-003 | BLOCKED | Same as TS-10-001; waiting on schemas + workspace. | 2025-11-30 |