From 10212d67c0dfa0dd849fd798c24502b773664749 Mon Sep 17 00:00:00 2001 From: master <> Date: Thu, 20 Nov 2025 07:50:52 +0200 Subject: [PATCH] Refactor code structure for improved readability and maintainability; removed redundant code blocks and optimized function calls. --- .gitea/workflows/api-governance.yml | 22 + AGENTS.md | 7 +- blocked_deps_report.txt | 1646 + docs/advisory-ai/console.md | 17 +- docs/advisory-ai/evidence-payloads.md | 104 + docs/advisory-ai/guardrails-and-evidence.md | 62 + docs/advisory-ai/packaging.md | 65 + .../backfill/CONCELIER-CORE-AOC-19-004.md | 45 + docs/concelier/backfill/linksets-m0-readme.md | 14 + ...PRINT_0110_0001_0001_ingestion_evidence.md | 54 +- .../SPRINT_0113_0001_0002_concelier_ii.md | 9 +- .../SPRINT_0114_0001_0003_concelier_iii.md | 45 +- .../SPRINT_0115_0001_0004_concelier_iv.md | 25 +- .../SPRINT_0116_0001_0005_concelier_v.md | 6 +- .../SPRINT_0117_0001_0006_concelier_vi.md | 2 +- .../SPRINT_0119_0001_0001_excititor_i.md | 17 +- .../SPRINT_0119_0001_0002_excititor_ii.md | 54 +- .../SPRINT_0120_0000_0001_policy_reasoning.md | 24 +- .../SPRINT_0121_0001_0001_policy_reasoning.md | 33 +- .../SPRINT_0122_0001_0001_policy_reasoning.md | 12 +- .../SPRINT_0123_0001_0001_policy_reasoning.md | 74 + .../SPRINT_0124_0001_0001_policy_reasoning.md | 51 + docs/implplan/SPRINT_0125_0001_0001_mirror.md | 9 +- .../SPRINT_0125_0001_0001_policy_reasoning.md | 68 + .../SPRINT_0126_0001_0001_policy_reasoning.md | 48 + .../SPRINT_0127_0001_0001_policy_reasoning.md | 51 + .../SPRINT_0128_0001_0001_policy_reasoning.md | 46 + .../SPRINT_0129_0001_0001_policy_reasoning.md | 67 + .../SPRINT_0131_0001_0001_scanner_surface.md | 12 +- .../SPRINT_0132_0001_0001_scanner_surface.md | 20 +- .../SPRINT_0133_0001_0001_scanner_surface.md | 43 + .../SPRINT_0134_0001_0001_scanner_surface.md | 38 + .../SPRINT_0135_0001_0001_scanner_surface.md | 42 + .../SPRINT_0136_0001_0001_scanner_surface.md | 37 + ...RINT_0138_0000_0001_scanner_ruby_parity.md | 18 +- .../SPRINT_0140_0001_0001_runtime_signals.md | 32 +- .../SPRINT_0141_0001_0001_graph_indexer.md | 15 +- .../SPRINT_0142_0001_0001_sbomservice.md | 15 +- .../implplan/SPRINT_0143_0000_0001_signals.md | 19 +- ...NT_0150_0001_0001_scheduling_automation.md | 47 + .../SPRINT_0151_0001_0001_orchestrator_i.md | 65 + .../SPRINT_0152_0001_0002_orchestrator_ii.md | 52 + .../SPRINT_0153_0001_0003_orchestrator_iii.md | 11 +- .../SPRINT_0154_0001_0001_packsregistry.md | 40 + .../SPRINT_0155_0001_0001_scheduler_i.md | 9 +- .../SPRINT_0156_0001_0002_scheduler_ii.md | 8 +- .../SPRINT_0157_0001_0001_taskrunner_i.md | 52 + .../SPRINT_0158_0001_0002_taskrunner_ii.md | 36 + .../SPRINT_0160_0001_0001_export_evidence.md | 30 +- .../SPRINT_0161_0001_0001_evidencelocker.md | 22 +- .../SPRINT_0162_0001_0001_exportcenter_i.md | 45 +- .../SPRINT_0163_0001_0001_exportcenter_ii.md | 50 +- .../SPRINT_0164_0001_0001_exportcenter_iii.md | 50 + .../SPRINT_0165_0001_0001_timelineindexer.md | 42 + ..._0170_0001_0001_notifications_telemetry.md | 43 + .../SPRINT_0171_0001_0001_notifier_i.md | 74 + .../SPRINT_0172_0001_0002_notifier_ii.md | 48 + .../SPRINT_0173_0001_0003_notifier_iii.md | 37 + .../SPRINT_0174_0001_0001_telemetry.md | 60 + ...0185_0001_0001_shared_replay_primitives.md | 38 + ...001_0001_record_deterministic_execution.md | 52 + ...01_0001_evidence_locker_cli_integration.md | 50 + docs/implplan/SPRINT_0215_0001_0001_web_iv.md | 52 + .../SPRINT_0316_0001_0001_docs_modules_cli.md | 6 +- ...PRINT_0321_0001_0001_docs_modules_graph.md | 6 +- ..._0001_reachability_runtime_static_union.md | 9 +- .../implplan/SPRINT_0509_0001_0001_samples.md | 11 +- docs/implplan/SPRINT_0510_0001_0001_airgap.md | 42 +- docs/implplan/SPRINT_0512_0001_0001_bench.md | 22 +- ...4_0001_0001_sovereign_crypto_enablement.md | 6 +- .../implplan/SPRINT_110_ingestion_evidence.md | 28 +- docs/implplan/SPRINT_123_policy_reasoning.md | 45 +- docs/implplan/SPRINT_124_policy_reasoning.md | 8 +- docs/implplan/SPRINT_125_policy_reasoning.md | 44 +- docs/implplan/SPRINT_136_scanner_surface.md | 9 +- docs/implplan/SPRINT_174_telemetry.md | 11 +- docs/implplan/SPRINT_201_cli_i.md | 4 +- docs/implplan/SPRINT_212_web_i.md | 5 +- docs/implplan/SPRINT_213_web_ii.md | 6 +- docs/implplan/SPRINT_215_web_iv.md | 25 +- .../SPRINT_300_documentation_process.md | 3 +- docs/implplan/SPRINT_301_docs_tasks_md_i.md | 6 +- .../SPRINT_333_docs_modules_excititor.md | 2 +- docs/implplan/SPRINT_511_api.md | 20 +- docs/implplan/blocked_tree.md | 390 + docs/implplan/build-harness-110.md | 19 + .../authority/fixtures/auth-ten-47-001.json | 15 + docs/modules/authority/tenant-scope-47-001.md | 36 + .../guardrails-artefacts-2025-11-19.md | 29 + docs/modules/concelier/bridges/vuln-29-001.md | 81 + .../feeds/icscisa-kisa-provenance.md | 7 + docs/modules/concelier/feeds/icscisa-kisa.md | 46 + docs/modules/concelier/operations/cache.md | 40 + .../evidence-locker/attestation-scope-note.md | 37 + .../evidence-locker/evidence-bundle-v1.md | 57 + docs/modules/excititor/evidence-contract.md | 3 + docs/modules/excititor/vex_linksets_api.md | 104 + .../modules/mirror/milestone-0-thin-bundle.md | 30 + docs/modules/mirror/thin-bundle-assembler.md | 34 + docs/notifications/slo-webhook-schema.md | 86 + .../cli-incident-toggle-12-001.md | 29 + docs/observability/telemetry-bootstrap.md | 48 + .../telemetry-propagation-51-001.md | 43 + docs/observability/telemetry-scrub-51-002.md | 35 + docs/observability/telemetry-sealed-56-001.md | 33 + docs/policy/auth-signals-lib-115.md | 40 + .../policy-auth-signal-reachability.json | 31 + .../fixtures/policy-auth-signal-sample.json | 26 + .../schemas/policy-auth-signals-lib-115.json | 56 + docs/provenance/prov-backfill-plan.md | 16 + docs/reachability/corpus-plan.md | 33 + docs/replay/replay-api-draft-2025-11-18.md | 34 + docs/samples/console/console-vex-30-001.json | 17 + docs/samples/console/console-vuln-29-001.json | 19 + .../evidence-bundle/evidence-bundle-m0.tar.gz | Bin 0 -> 781 bytes .../evidence-bundle-m0.tar.gz.sha256 | 1 + docs/samples/evidence-bundle/hashes.sha256 | 4 + docs/samples/evidence-bundle/linksets.ndjson | 1 + docs/samples/evidence-bundle/manifest.json | 18 + .../evidence-bundle/observations.ndjson | 1 + .../samples/evidence-bundle/transparency.json | 1 + docs/samples/excititor/chunks-sample.ndjson | 2 + .../excititor/chunks-sample.ndjson.sha256 | 1 + docs/signals/cas-promotion-24-002.md | 34 + docs/signals/events-24-005.md | 47 + docs/signals/provenance-24-003.md | 31 + ...laOps.Policy.AuthSignals.0.1.0-alpha.nupkg | Bin 0 -> 7470 bytes local-nugets/cronos/0.10.0/.nupkg.metadata | 5 + local-nugets/cronos/0.10.0/.signature.p7s | Bin 0 -> 25862 bytes local-nugets/cronos/0.10.0/Cronos.nuspec | 30 + local-nugets/cronos/0.10.0/LICENSE | 21 + local-nugets/cronos/0.10.0/README.md | 292 + .../cronos/0.10.0/cronos.0.10.0.nupkg | Bin 0 -> 198128 bytes .../cronos/0.10.0/cronos.0.10.0.nupkg.sha512 | 1 + local-nugets/cronos/0.10.0/icon.png | Bin 0 -> 2275 bytes .../cronos/0.10.0/lib/net40/Cronos.xml | 211 + .../cronos/0.10.0/lib/net45/Cronos.xml | 211 + .../cronos/0.10.0/lib/net6.0/Cronos.xml | 211 + .../0.10.0/lib/netstandard1.0/Cronos.xml | 208 + .../0.10.0/lib/netstandard2.0/Cronos.xml | 211 + local-nugets/dnsclient/1.6.1/.nupkg.metadata | 5 + local-nugets/dnsclient/1.6.1/.signature.p7s | Bin 0 -> 9466 bytes local-nugets/dnsclient/1.6.1/DnsClient.nuspec | 45 + .../dnsclient/1.6.1/dnsclient.1.6.1.nupkg | Bin 0 -> 585991 bytes .../1.6.1/dnsclient.1.6.1.nupkg.sha512 | 1 + local-nugets/dnsclient/1.6.1/icon.png | Bin 0 -> 26619 bytes .../dnsclient/1.6.1/lib/net45/DnsClient.xml | 5071 ++ .../dnsclient/1.6.1/lib/net471/DnsClient.xml | 5090 ++ .../dnsclient/1.6.1/lib/net5.0/DnsClient.xml | 5090 ++ .../1.6.1/lib/netstandard1.3/DnsClient.xml | 5090 ++ .../1.6.1/lib/netstandard2.0/DnsClient.xml | 5090 ++ .../1.6.1/lib/netstandard2.1/DnsClient.xml | 5090 ++ .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25748 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes ...tensions.Configuration.Abstractions.nuspec | 36 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 82 + .../THIRD-PARTY-NOTICES.TXT | 1418 + ...ensions.Configuration.Abstractions.targets | 6 + .../buildTransitive/net462/_._ | 0 .../buildTransitive/net8.0/_._ | 0 ...ensions.Configuration.Abstractions.targets | 6 + ....Extensions.Configuration.Abstractions.xml | 341 + ....Extensions.Configuration.Abstractions.xml | 524 + ....Extensions.Configuration.Abstractions.xml | 341 + ....Extensions.Configuration.Abstractions.xml | 341 + ....Extensions.Configuration.Abstractions.xml | 524 + ...n.abstractions.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 146789 bytes ...actions.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25748 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes ...ns.DependencyInjection.Abstractions.nuspec | 35 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 34 + .../THIRD-PARTY-NOTICES.TXT | 1418 + ...s.DependencyInjection.Abstractions.targets | 6 + .../buildTransitive/net462/_._ | 0 .../buildTransitive/net8.0/_._ | 0 ...s.DependencyInjection.Abstractions.targets | 6 + ...sions.DependencyInjection.Abstractions.xml | 2169 + ...sions.DependencyInjection.Abstractions.xml | 2666 + ...sions.DependencyInjection.Abstractions.xml | 2169 + ...sions.DependencyInjection.Abstractions.xml | 2169 + ...sions.DependencyInjection.Abstractions.xml | 2666 + ...sions.DependencyInjection.Abstractions.xml | 2602 + ...n.abstractions.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 285936 bytes ...actions.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25739 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes ...Extensions.Diagnostics.Abstractions.nuspec | 55 + .../THIRD-PARTY-NOTICES.TXT | 1418 + ...xtensions.Diagnostics.Abstractions.targets | 6 + .../buildTransitive/net462/_._ | 0 .../buildTransitive/net8.0/_._ | 0 ...xtensions.Diagnostics.Abstractions.targets | 6 + ...ft.Extensions.Diagnostics.Abstractions.xml | 333 + ...ft.Extensions.Diagnostics.Abstractions.xml | 727 + ...ft.Extensions.Diagnostics.Abstractions.xml | 333 + ...ft.Extensions.Diagnostics.Abstractions.xml | 333 + ...ft.Extensions.Diagnostics.Abstractions.xml | 727 + ...s.abstractions.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 152134 bytes ...actions.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25746 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes ...tensions.FileProviders.Abstractions.nuspec | 40 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 51 + .../THIRD-PARTY-NOTICES.TXT | 1418 + ...ensions.FileProviders.Abstractions.targets | 6 + .../buildTransitive/net462/_._ | 0 .../buildTransitive/net8.0/_._ | 0 ...ensions.FileProviders.Abstractions.targets | 6 + ....Extensions.FileProviders.Abstractions.xml | 211 + ....Extensions.FileProviders.Abstractions.xml | 394 + ....Extensions.FileProviders.Abstractions.xml | 211 + ....Extensions.FileProviders.Abstractions.xml | 211 + ....Extensions.FileProviders.Abstractions.xml | 394 + ...s.abstractions.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 128589 bytes ...actions.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25747 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes ...oft.Extensions.Hosting.Abstractions.nuspec | 66 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 43 + .../THIRD-PARTY-NOTICES.TXT | 1418 + ...ft.Extensions.Hosting.Abstractions.targets | 6 + .../buildTransitive/net462/_._ | 0 .../buildTransitive/net8.0/_._ | 0 ...ft.Extensions.Hosting.Abstractions.targets | 6 + ...rosoft.Extensions.Hosting.Abstractions.xml | 690 + ...rosoft.Extensions.Hosting.Abstractions.xml | 1084 + ...rosoft.Extensions.Hosting.Abstractions.xml | 690 + ...rosoft.Extensions.Hosting.Abstractions.xml | 690 + ...rosoft.Extensions.Hosting.Abstractions.xml | 1084 + ...rosoft.Extensions.Hosting.Abstractions.xml | 1020 + ...g.abstractions.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 234106 bytes ...actions.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25746 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes ...oft.Extensions.Logging.Abstractions.nuspec | 52 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 164 + .../THIRD-PARTY-NOTICES.TXT | 1418 + ...ft.Extensions.Logging.Abstractions.targets | 6 + ...ft.Extensions.Logging.Abstractions.targets | 31 + ...ft.Extensions.Logging.Abstractions.targets | 31 + ...ft.Extensions.Logging.Abstractions.targets | 6 + ...ft.Extensions.Logging.Abstractions.targets | 31 + ...rosoft.Extensions.Logging.Abstractions.xml | 1365 + ...rosoft.Extensions.Logging.Abstractions.xml | 1548 + ...rosoft.Extensions.Logging.Abstractions.xml | 1365 + ...rosoft.Extensions.Logging.Abstractions.xml | 1365 + ...rosoft.Extensions.Logging.Abstractions.xml | 1548 + ...g.abstractions.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 824527 bytes ...actions.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../2.0.0/.nupkg.metadata | 5 + .../2.0.0/.signature.p7s | Bin 0 -> 9473 bytes ...oft.Extensions.Logging.Abstractions.nuspec | 29 + ...rosoft.Extensions.Logging.Abstractions.xml | 596 + ...xtensions.logging.abstractions.2.0.0.nupkg | Bin 0 -> 36310 bytes ...ns.logging.abstractions.2.0.0.nupkg.sha512 | 1 + .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25748 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes .../Microsoft.Extensions.Options.nuspec | 50 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 170 + .../THIRD-PARTY-NOTICES.TXT | 1418 + .../Microsoft.Extensions.Options.targets | 6 + .../Microsoft.Extensions.Options.targets | 31 + .../Microsoft.Extensions.Options.targets | 31 + .../Microsoft.Extensions.Options.targets | 6 + .../Microsoft.Extensions.Options.targets | 31 + .../net10.0/Microsoft.Extensions.Options.xml | 2047 + .../net462/Microsoft.Extensions.Options.xml | 2515 + .../net8.0/Microsoft.Extensions.Options.xml | 2047 + .../net9.0/Microsoft.Extensions.Options.xml | 2047 + .../Microsoft.Extensions.Options.xml | 2515 + .../Microsoft.Extensions.Options.xml | 2451 + ...nsions.options.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 498782 bytes ...options.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../10.0.0-rc.2.25502.107/.nupkg.metadata | 5 + .../10.0.0-rc.2.25502.107/.signature.p7s | Bin 0 -> 25747 bytes .../10.0.0-rc.2.25502.107/Icon.png | Bin 0 -> 2140 bytes .../Microsoft.Extensions.Primitives.nuspec | 36 + .../10.0.0-rc.2.25502.107/PACKAGE.md | 109 + .../THIRD-PARTY-NOTICES.TXT | 1418 + .../Microsoft.Extensions.Primitives.targets | 6 + .../buildTransitive/net462/_._ | 0 .../buildTransitive/net8.0/_._ | 0 .../Microsoft.Extensions.Primitives.targets | 6 + .../Microsoft.Extensions.Primitives.xml | 1035 + .../Microsoft.Extensions.Primitives.xml | 1251 + .../Microsoft.Extensions.Primitives.xml | 1035 + .../Microsoft.Extensions.Primitives.xml | 1035 + .../Microsoft.Extensions.Primitives.xml | 1251 + ...ons.primitives.10.0.0-rc.2.25502.107.nupkg | Bin 0 -> 208629 bytes ...mitives.10.0.0-rc.2.25502.107.nupkg.sha512 | 1 + .../useSharedDesignerContext.txt | 0 .../mongodb.bson/3.5.0/.nupkg.metadata | 5 + .../mongodb.bson/3.5.0/.signature.p7s | Bin 0 -> 23629 bytes .../mongodb.bson/3.5.0/MongoDB.Bson.nuspec | 33 + local-nugets/mongodb.bson/3.5.0/README.md | 87 + .../3.5.0/lib/net472/MongoDB.Bson.xml | 23606 +++++++++ .../3.5.0/lib/net6.0/MongoDB.Bson.xml | 24049 +++++++++ .../3.5.0/lib/netstandard2.1/MongoDB.Bson.xml | 23606 +++++++++ .../3.5.0/mongodb.bson.3.5.0.nupkg | Bin 0 -> 892834 bytes .../3.5.0/mongodb.bson.3.5.0.nupkg.sha512 | 1 + .../mongodb.bson/3.5.0/packageIcon.png | Bin 0 -> 3810 bytes .../mongodb.driver/3.5.0/.nupkg.metadata | 5 + .../mongodb.driver/3.5.0/.signature.p7s | Bin 0 -> 23627 bytes .../3.5.0/MongoDB.Driver.nuspec | 60 + local-nugets/mongodb.driver/3.5.0/README.md | 87 + .../3.5.0/lib/net472/MongoDB.Driver.xml | 44093 ++++++++++++++++ .../3.5.0/lib/net6.0/MongoDB.Driver.xml | 44065 +++++++++++++++ .../lib/netstandard2.1/MongoDB.Driver.xml | 44065 +++++++++++++++ .../3.5.0/mongodb.driver.3.5.0.nupkg | Bin 0 -> 3017623 bytes .../3.5.0/mongodb.driver.3.5.0.nupkg.sha512 | 1 + .../mongodb.driver/3.5.0/packageIcon.png | Bin 0 -> 3810 bytes .../nuget.versioning/6.9.1/.nupkg.metadata | 5 + .../nuget.versioning/6.9.1/.signature.p7s | Bin 0 -> 24205 bytes .../6.9.1/NuGet.Versioning.nuspec | 23 + local-nugets/nuget.versioning/6.9.1/README.md | 1 + local-nugets/nuget.versioning/6.9.1/icon.png | Bin 0 -> 4131 bytes .../6.9.1/nuget.versioning.6.9.1.nupkg | Bin 0 -> 96772 bytes .../6.9.1/nuget.versioning.6.9.1.nupkg.sha512 | 1 + .../sharpcompress/0.41.0/.nupkg.metadata | 5 + .../sharpcompress/0.41.0/.signature.p7s | Bin 0 -> 12986 bytes local-nugets/sharpcompress/0.41.0/README.md | 202 + .../sharpcompress/0.41.0/SharpCompress.nuspec | 41 + .../0.41.0/sharpcompress.0.41.0.nupkg | Bin 0 -> 2051285 bytes .../0.41.0/sharpcompress.0.41.0.nupkg.sha512 | 1 + local-nugets/snappier/1.0.0/.nupkg.metadata | 5 + local-nugets/snappier/1.0.0/.signature.p7s | Bin 0 -> 9467 bytes local-nugets/snappier/1.0.0/COPYING.txt | 54 + local-nugets/snappier/1.0.0/Snappier.nuspec | 32 + .../snappier/1.0.0/lib/net5.0/Snappier.xml | 400 + .../1.0.0/lib/netcoreapp3.0/Snappier.xml | 400 + .../1.0.0/lib/netstandard2.0/Snappier.xml | 385 + .../1.0.0/lib/netstandard2.1/Snappier.xml | 400 + .../snappier/1.0.0/snappier.1.0.0.nupkg | Bin 0 -> 107010 bytes .../1.0.0/snappier.1.0.0.nupkg.sha512 | 1 + .../0.1.0-alpha/.nupkg.metadata | 5 + .../StellaOps.Policy.AuthSignals.nuspec | 15 + ...laops.policy.authsignals.0.1.0-alpha.nupkg | Bin 0 -> 7470 bytes ...olicy.authsignals.0.1.0-alpha.nupkg.sha512 | 1 + .../zstdsharp.port/0.7.3/.nupkg.metadata | 5 + .../zstdsharp.port/0.7.3/.signature.p7s | Bin 0 -> 11512 bytes .../0.7.3/ZstdSharp.Port.nuspec | 32 + .../0.7.3/zstdsharp.port.0.7.3.nupkg | Bin 0 -> 994795 bytes .../0.7.3/zstdsharp.port.0.7.3.nupkg.sha512 | 1 + .../zstdsharp.port/0.8.6/.nupkg.metadata | 5 + .../zstdsharp.port/0.8.6/.signature.p7s | Bin 0 -> 12981 bytes .../0.8.6/ZstdSharp.Port.nuspec | 38 + .../0.8.6/zstdsharp.port.0.8.6.nupkg | Bin 0 -> 1387185 bytes .../0.8.6/zstdsharp.port.0.8.6.nupkg.sha512 | 1 + logs/provenance-backfill-2025-11-18.ndjson | 3 + ops/mongo/indices/README.md | 16 + out/concelier/backfill/linksets-m0.ndjson.gz | Bin 0 -> 145 bytes .../backfill/linksets-m0.ndjson.gz.sha256 | 1 + .../guardrails/cli-vex-30-001/hashes.sha256 | 2 + .../cli-vex-30-001/sample-pagination-note.txt | 1 + .../cli-vex-30-001/sample-vex-output.ndjson | 1 + .../guardrails/cli-vuln-29-001/hashes.sha256 | 2 + .../cli-vuln-29-001/sample-sbom-context.json | 9 + .../cli-vuln-29-001/sample-vuln-output.ndjson | 1 + out/mirror/thin/mirror-thin-m0-sample.sha256 | 1 + out/mirror/thin/mirror-thin-m0-sample.tar.gz | Bin 0 -> 474 bytes out/mirror/thin/sample-m0/README.txt | 5 + out/mirror/thin/sample-m0/manifest.json | 7 + out/test-results/linksets/linksets.trx | 196 + package-lock.json | 15 +- package.json | 12 +- samples/TASKS.md | 10 + scripts/__fixtures__/api-compat/new.yaml | 15 + scripts/__fixtures__/api-compat/old.yaml | 10 + scripts/api-changelog.mjs | 90 + scripts/api-compat-changelog.mjs | 104 + scripts/api-compat-changelog.test.mjs | 26 + scripts/api-compat-diff.mjs | 194 + scripts/api-compat-diff.test.mjs | 25 + scripts/api-example-coverage.mjs | 139 + scripts/provenance_backfill.py | 115 + src/Api/StellaOps.Api.OpenApi/CHANGELOG.md | 10 + .../_shared/parameters/paging.yaml | 17 + .../_shared/parameters/tenant.yaml | 9 + .../_shared/responses/defaults.yaml | 13 + .../_shared/schemas/common.yaml | 37 + .../_shared/securitySchemes/default.yaml | 12 + .../baselines/stella-baseline.yaml | 1377 + src/Api/StellaOps.Api.OpenApi/compose.mjs | 205 + .../export-center/openapi.yaml | 237 + .../StellaOps.Api.OpenApi/graph/openapi.yaml | 153 + .../orchestrator/openapi.yaml | 220 + .../StellaOps.Api.OpenApi/policy/openapi.yaml | 162 + .../scheduler/openapi.yaml | 129 + src/Api/StellaOps.Api.OpenApi/stella.yaml | 1542 + src/Api/StellaOps.Api.OpenApi/tasks.md | 10 + .../DsseHelperTests.cs | 50 + .../StellaOps.Attestation.Tests.csproj | 14 + .../StellaOps.Attestation/DsseHelper.cs | 55 + .../StellaOps.Attestation/IAuthoritySigner.cs | 11 + src/Attestor/StellaOps.Attestation/Models.cs | 14 + .../StellaOps.Attestation.csproj | 12 + .../Linksets/AdvisoryLinksetMapper.cs | 27 +- .../Linksets/AdvisoryLinksetNormalization.cs | 55 +- .../Linksets/PolicyAuthSignalFactory.cs | 43 + .../AdvisoryObservationQueryService.cs | 7 +- .../Policy/AuthSignalsPackage.cs | 31 + .../StellaOps.Concelier.Core.csproj | 1 + .../ServiceCollectionExtensions.cs | 6 + .../Linksets/AdvisoryLinksetMapperTests.cs | 47 +- .../AdvisoryLinksetNormalizationTests.cs | 34 + .../Linksets/PolicyAuthSignalFactoryTests.cs | 40 + .../AdvisoryObservationAggregationTests.cs | 12 +- .../Raw/AdvisoryRawServiceTests.cs | 34 +- .../StellaOps.Concelier.Core.Tests.csproj | 1 + .../AdvisoryChunkBuilderTests.cs | 132 + .../AdvisoryChunkCacheKeyTests.cs | 107 + .../Services/AdvisoryChunkBuilderTests.cs | 177 + .../VexLinksetListEndpointTests.cs | 140 + .../GraphIdentityTests.cs | 46 + .../GraphSnapshotBuilderTests.cs | 131 + .../SbomSnapshotExporterTests.cs | 109 + .../StellaOps.Graph.Indexer.Tests.csproj | 13 + .../HttpEgressSloSinkTests.cs | 89 + .../Support/TestEgressSloSink.cs | 20 + .../Options/EgressSloOptions.cs | 16 + .../Processing/EgressSloContext.cs | 45 + .../Processing/HttpEgressSloSink.cs | 93 + .../Processing/IEgressSloSink.cs | 17 + .../QA-attestation-routing.md | 39 + .../docs/attestation-rules.sample.json | 86 + .../PolicyAuthSignal.cs | 40 + .../StellaOps.Policy.AuthSignals.csproj | 14 + .../Runtime/DenoRuntimeTraceRunner.cs | 120 + .../Internal/NodeEntrypoint.cs | 33 + .../Internal/NodeImportEdge.cs | 10 + .../Internal/NodeImportWalker.cs | 91 + .../Internal/NodePackage.cs | 120 +- .../Internal/NodePackageCollector.cs | 56 + .../Reachability/ReachabilityLattice.cs | 93 + .../Deno/DenoLanguageAnalyzerRuntimeTests.cs | 52 + .../Deno/DenoRuntimeTraceRunnerTests.cs | 93 + .../Node/NodeEntrypointTests.cs | 30 + .../Reachability/ReachabilityLatticeTests.cs | 88 + .../CorpusFixtureTests.cs | 83 + tests/reachability/corpus/README.md | 21 + .../callgraph.static.json | 5 + .../expect.yaml | 11 + .../vex.openvex.json | 12 + .../callgraph.static.json | 5 + .../expect.yaml | 11 + .../vex.openvex.json | 12 + tests/reachability/corpus/manifest.json | 38 + .../callgraph.static.json | 5 + .../expect.yaml | 11 + .../vex.openvex.json | 12 + .../callgraph.static.json | 5 + .../rust-axum-header-parsing-TBD/expect.yaml | 11 + .../vex.openvex.json | 12 + tests/reachability/scripts/README.md | 8 + .../scripts/update_corpus_manifest.py | 38 + tools/linksets-ci.sh | 18 + tools/openssl1.1/lib/libcrypto.so.1.1 | Bin 0 -> 3076992 bytes tools/openssl1.1/lib/libssl.so.1.1 | Bin 0 -> 597792 bytes 473 files changed, 316758 insertions(+), 388 deletions(-) create mode 100644 blocked_deps_report.txt create mode 100644 docs/advisory-ai/evidence-payloads.md create mode 100644 docs/advisory-ai/guardrails-and-evidence.md create mode 100644 docs/advisory-ai/packaging.md create mode 100644 docs/concelier/backfill/CONCELIER-CORE-AOC-19-004.md create mode 100644 docs/concelier/backfill/linksets-m0-readme.md create mode 100644 docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0124_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0126_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0127_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0129_0001_0001_policy_reasoning.md create mode 100644 docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md create mode 100644 docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md create mode 100644 docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md create mode 100644 docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md create mode 100644 docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md create mode 100644 docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md create mode 100644 docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md create mode 100644 docs/implplan/SPRINT_0154_0001_0001_packsregistry.md create mode 100644 docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md create mode 100644 docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md create mode 100644 docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md create mode 100644 docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md create mode 100644 docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md create mode 100644 docs/implplan/SPRINT_0171_0001_0001_notifier_i.md create mode 100644 docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md create mode 100644 docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md create mode 100644 docs/implplan/SPRINT_0174_0001_0001_telemetry.md create mode 100644 docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md create mode 100644 docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md create mode 100644 docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md create mode 100644 docs/implplan/SPRINT_0215_0001_0001_web_iv.md create mode 100644 docs/implplan/blocked_tree.md create mode 100644 docs/implplan/build-harness-110.md create mode 100644 docs/modules/authority/fixtures/auth-ten-47-001.json create mode 100644 docs/modules/authority/tenant-scope-47-001.md create mode 100644 docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md create mode 100644 docs/modules/concelier/bridges/vuln-29-001.md create mode 100644 docs/modules/concelier/feeds/icscisa-kisa-provenance.md create mode 100644 docs/modules/concelier/feeds/icscisa-kisa.md create mode 100644 docs/modules/concelier/operations/cache.md create mode 100644 docs/modules/evidence-locker/attestation-scope-note.md create mode 100644 docs/modules/evidence-locker/evidence-bundle-v1.md create mode 100644 docs/modules/excititor/vex_linksets_api.md create mode 100644 docs/modules/mirror/milestone-0-thin-bundle.md create mode 100644 docs/modules/mirror/thin-bundle-assembler.md create mode 100644 docs/notifications/slo-webhook-schema.md create mode 100644 docs/observability/cli-incident-toggle-12-001.md create mode 100644 docs/observability/telemetry-bootstrap.md create mode 100644 docs/observability/telemetry-propagation-51-001.md create mode 100644 docs/observability/telemetry-scrub-51-002.md create mode 100644 docs/observability/telemetry-sealed-56-001.md create mode 100644 docs/policy/auth-signals-lib-115.md create mode 100644 docs/policy/fixtures/policy-auth-signal-reachability.json create mode 100644 docs/policy/fixtures/policy-auth-signal-sample.json create mode 100644 docs/policy/schemas/policy-auth-signals-lib-115.json create mode 100644 docs/provenance/prov-backfill-plan.md create mode 100644 docs/reachability/corpus-plan.md create mode 100644 docs/replay/replay-api-draft-2025-11-18.md create mode 100644 docs/samples/console/console-vex-30-001.json create mode 100644 docs/samples/console/console-vuln-29-001.json create mode 100644 docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz create mode 100644 docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz.sha256 create mode 100644 docs/samples/evidence-bundle/hashes.sha256 create mode 100644 docs/samples/evidence-bundle/linksets.ndjson create mode 100644 docs/samples/evidence-bundle/manifest.json create mode 100644 docs/samples/evidence-bundle/observations.ndjson create mode 100644 docs/samples/evidence-bundle/transparency.json create mode 100644 docs/samples/excititor/chunks-sample.ndjson create mode 100644 docs/samples/excititor/chunks-sample.ndjson.sha256 create mode 100644 docs/signals/cas-promotion-24-002.md create mode 100644 docs/signals/events-24-005.md create mode 100644 docs/signals/provenance-24-003.md create mode 100644 local-nugets/StellaOps.Policy.AuthSignals.0.1.0-alpha.nupkg create mode 100644 local-nugets/cronos/0.10.0/.nupkg.metadata create mode 100644 local-nugets/cronos/0.10.0/.signature.p7s create mode 100644 local-nugets/cronos/0.10.0/Cronos.nuspec create mode 100644 local-nugets/cronos/0.10.0/LICENSE create mode 100644 local-nugets/cronos/0.10.0/README.md create mode 100644 local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg create mode 100644 local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg.sha512 create mode 100644 local-nugets/cronos/0.10.0/icon.png create mode 100644 local-nugets/cronos/0.10.0/lib/net40/Cronos.xml create mode 100644 local-nugets/cronos/0.10.0/lib/net45/Cronos.xml create mode 100644 local-nugets/cronos/0.10.0/lib/net6.0/Cronos.xml create mode 100644 local-nugets/cronos/0.10.0/lib/netstandard1.0/Cronos.xml create mode 100644 local-nugets/cronos/0.10.0/lib/netstandard2.0/Cronos.xml create mode 100644 local-nugets/dnsclient/1.6.1/.nupkg.metadata create mode 100644 local-nugets/dnsclient/1.6.1/.signature.p7s create mode 100644 local-nugets/dnsclient/1.6.1/DnsClient.nuspec create mode 100644 local-nugets/dnsclient/1.6.1/dnsclient.1.6.1.nupkg create mode 100644 local-nugets/dnsclient/1.6.1/dnsclient.1.6.1.nupkg.sha512 create mode 100644 local-nugets/dnsclient/1.6.1/icon.png create mode 100644 local-nugets/dnsclient/1.6.1/lib/net45/DnsClient.xml create mode 100644 local-nugets/dnsclient/1.6.1/lib/net471/DnsClient.xml create mode 100644 local-nugets/dnsclient/1.6.1/lib/net5.0/DnsClient.xml create mode 100644 local-nugets/dnsclient/1.6.1/lib/netstandard1.3/DnsClient.xml create mode 100644 local-nugets/dnsclient/1.6.1/lib/netstandard2.0/DnsClient.xml create mode 100644 local-nugets/dnsclient/1.6.1/lib/netstandard2.1/DnsClient.xml create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/Microsoft.Extensions.Configuration.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.Configuration.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net462/_._ create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net8.0/_._ create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.Configuration.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.Configuration.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.Configuration.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.Configuration.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.Configuration.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.Configuration.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.configuration.abstractions.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.configuration.abstractions.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.configuration.abstractions/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/Microsoft.Extensions.DependencyInjection.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net462/_._ create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net8.0/_._ create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.dependencyinjection.abstractions.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.dependencyinjection.abstractions.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.dependencyinjection.abstractions/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/Microsoft.Extensions.Diagnostics.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.Diagnostics.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net462/_._ create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net8.0/_._ create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.Diagnostics.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.Diagnostics.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.Diagnostics.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.Diagnostics.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.Diagnostics.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.Diagnostics.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.diagnostics.abstractions.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.diagnostics.abstractions.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.diagnostics.abstractions/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/Microsoft.Extensions.FileProviders.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.FileProviders.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net462/_._ create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net8.0/_._ create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.FileProviders.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.FileProviders.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.FileProviders.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.FileProviders.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.FileProviders.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.FileProviders.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.fileproviders.abstractions.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.fileproviders.abstractions.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.fileproviders.abstractions/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/Microsoft.Extensions.Hosting.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.Hosting.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net462/_._ create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net8.0/_._ create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.Hosting.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.Hosting.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.Hosting.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.Hosting.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.Hosting.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.Hosting.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.1/Microsoft.Extensions.Hosting.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.hosting.abstractions.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.hosting.abstractions.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.hosting.abstractions/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/Microsoft.Extensions.Logging.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/buildTransitive/net8.0/Microsoft.Extensions.Logging.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.Logging.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.Logging.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.Logging.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.Logging.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.logging.abstractions.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/microsoft.extensions.logging.abstractions.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/2.0.0/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/2.0.0/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/2.0.0/Microsoft.Extensions.Logging.Abstractions.nuspec create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/2.0.0/lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/2.0.0/microsoft.extensions.logging.abstractions.2.0.0.nupkg create mode 100644 local-nugets/microsoft.extensions.logging.abstractions/2.0.0/microsoft.extensions.logging.abstractions.2.0.0.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/Microsoft.Extensions.Options.nuspec create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.Options.targets create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/buildTransitive/net462/Microsoft.Extensions.Options.targets create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/buildTransitive/net8.0/Microsoft.Extensions.Options.targets create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.Options.targets create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/buildTransitive/netstandard2.0/Microsoft.Extensions.Options.targets create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.Options.xml create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.Options.xml create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.Options.xml create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.Options.xml create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.Options.xml create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/lib/netstandard2.1/Microsoft.Extensions.Options.xml create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/microsoft.extensions.options.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/microsoft.extensions.options.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.options/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/.nupkg.metadata create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/.signature.p7s create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/Icon.png create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/Microsoft.Extensions.Primitives.nuspec create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/PACKAGE.md create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/THIRD-PARTY-NOTICES.TXT create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/buildTransitive/net461/Microsoft.Extensions.Primitives.targets create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/buildTransitive/net462/_._ create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/buildTransitive/net8.0/_._ create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/buildTransitive/netcoreapp2.0/Microsoft.Extensions.Primitives.targets create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/lib/net10.0/Microsoft.Extensions.Primitives.xml create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/lib/net462/Microsoft.Extensions.Primitives.xml create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/lib/net8.0/Microsoft.Extensions.Primitives.xml create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/lib/net9.0/Microsoft.Extensions.Primitives.xml create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/lib/netstandard2.0/Microsoft.Extensions.Primitives.xml create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/microsoft.extensions.primitives.10.0.0-rc.2.25502.107.nupkg create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/microsoft.extensions.primitives.10.0.0-rc.2.25502.107.nupkg.sha512 create mode 100644 local-nugets/microsoft.extensions.primitives/10.0.0-rc.2.25502.107/useSharedDesignerContext.txt create mode 100644 local-nugets/mongodb.bson/3.5.0/.nupkg.metadata create mode 100644 local-nugets/mongodb.bson/3.5.0/.signature.p7s create mode 100644 local-nugets/mongodb.bson/3.5.0/MongoDB.Bson.nuspec create mode 100644 local-nugets/mongodb.bson/3.5.0/README.md create mode 100644 local-nugets/mongodb.bson/3.5.0/lib/net472/MongoDB.Bson.xml create mode 100644 local-nugets/mongodb.bson/3.5.0/lib/net6.0/MongoDB.Bson.xml create mode 100644 local-nugets/mongodb.bson/3.5.0/lib/netstandard2.1/MongoDB.Bson.xml create mode 100644 local-nugets/mongodb.bson/3.5.0/mongodb.bson.3.5.0.nupkg create mode 100644 local-nugets/mongodb.bson/3.5.0/mongodb.bson.3.5.0.nupkg.sha512 create mode 100644 local-nugets/mongodb.bson/3.5.0/packageIcon.png create mode 100644 local-nugets/mongodb.driver/3.5.0/.nupkg.metadata create mode 100644 local-nugets/mongodb.driver/3.5.0/.signature.p7s create mode 100644 local-nugets/mongodb.driver/3.5.0/MongoDB.Driver.nuspec create mode 100644 local-nugets/mongodb.driver/3.5.0/README.md create mode 100644 local-nugets/mongodb.driver/3.5.0/lib/net472/MongoDB.Driver.xml create mode 100644 local-nugets/mongodb.driver/3.5.0/lib/net6.0/MongoDB.Driver.xml create mode 100644 local-nugets/mongodb.driver/3.5.0/lib/netstandard2.1/MongoDB.Driver.xml create mode 100644 local-nugets/mongodb.driver/3.5.0/mongodb.driver.3.5.0.nupkg create mode 100644 local-nugets/mongodb.driver/3.5.0/mongodb.driver.3.5.0.nupkg.sha512 create mode 100644 local-nugets/mongodb.driver/3.5.0/packageIcon.png create mode 100644 local-nugets/nuget.versioning/6.9.1/.nupkg.metadata create mode 100644 local-nugets/nuget.versioning/6.9.1/.signature.p7s create mode 100644 local-nugets/nuget.versioning/6.9.1/NuGet.Versioning.nuspec create mode 100644 local-nugets/nuget.versioning/6.9.1/README.md create mode 100644 local-nugets/nuget.versioning/6.9.1/icon.png create mode 100644 local-nugets/nuget.versioning/6.9.1/nuget.versioning.6.9.1.nupkg create mode 100644 local-nugets/nuget.versioning/6.9.1/nuget.versioning.6.9.1.nupkg.sha512 create mode 100644 local-nugets/sharpcompress/0.41.0/.nupkg.metadata create mode 100644 local-nugets/sharpcompress/0.41.0/.signature.p7s create mode 100644 local-nugets/sharpcompress/0.41.0/README.md create mode 100644 local-nugets/sharpcompress/0.41.0/SharpCompress.nuspec create mode 100644 local-nugets/sharpcompress/0.41.0/sharpcompress.0.41.0.nupkg create mode 100644 local-nugets/sharpcompress/0.41.0/sharpcompress.0.41.0.nupkg.sha512 create mode 100644 local-nugets/snappier/1.0.0/.nupkg.metadata create mode 100644 local-nugets/snappier/1.0.0/.signature.p7s create mode 100644 local-nugets/snappier/1.0.0/COPYING.txt create mode 100644 local-nugets/snappier/1.0.0/Snappier.nuspec create mode 100644 local-nugets/snappier/1.0.0/lib/net5.0/Snappier.xml create mode 100644 local-nugets/snappier/1.0.0/lib/netcoreapp3.0/Snappier.xml create mode 100644 local-nugets/snappier/1.0.0/lib/netstandard2.0/Snappier.xml create mode 100644 local-nugets/snappier/1.0.0/lib/netstandard2.1/Snappier.xml create mode 100644 local-nugets/snappier/1.0.0/snappier.1.0.0.nupkg create mode 100644 local-nugets/snappier/1.0.0/snappier.1.0.0.nupkg.sha512 create mode 100644 local-nugets/stellaops.policy.authsignals/0.1.0-alpha/.nupkg.metadata create mode 100644 local-nugets/stellaops.policy.authsignals/0.1.0-alpha/StellaOps.Policy.AuthSignals.nuspec create mode 100644 local-nugets/stellaops.policy.authsignals/0.1.0-alpha/stellaops.policy.authsignals.0.1.0-alpha.nupkg create mode 100644 local-nugets/stellaops.policy.authsignals/0.1.0-alpha/stellaops.policy.authsignals.0.1.0-alpha.nupkg.sha512 create mode 100644 local-nugets/zstdsharp.port/0.7.3/.nupkg.metadata create mode 100644 local-nugets/zstdsharp.port/0.7.3/.signature.p7s create mode 100644 local-nugets/zstdsharp.port/0.7.3/ZstdSharp.Port.nuspec create mode 100644 local-nugets/zstdsharp.port/0.7.3/zstdsharp.port.0.7.3.nupkg create mode 100644 local-nugets/zstdsharp.port/0.7.3/zstdsharp.port.0.7.3.nupkg.sha512 create mode 100644 local-nugets/zstdsharp.port/0.8.6/.nupkg.metadata create mode 100644 local-nugets/zstdsharp.port/0.8.6/.signature.p7s create mode 100644 local-nugets/zstdsharp.port/0.8.6/ZstdSharp.Port.nuspec create mode 100644 local-nugets/zstdsharp.port/0.8.6/zstdsharp.port.0.8.6.nupkg create mode 100644 local-nugets/zstdsharp.port/0.8.6/zstdsharp.port.0.8.6.nupkg.sha512 create mode 100644 logs/provenance-backfill-2025-11-18.ndjson create mode 100644 ops/mongo/indices/README.md create mode 100644 out/concelier/backfill/linksets-m0.ndjson.gz create mode 100644 out/concelier/backfill/linksets-m0.ndjson.gz.sha256 create mode 100644 out/console/guardrails/cli-vex-30-001/hashes.sha256 create mode 100644 out/console/guardrails/cli-vex-30-001/sample-pagination-note.txt create mode 100644 out/console/guardrails/cli-vex-30-001/sample-vex-output.ndjson create mode 100644 out/console/guardrails/cli-vuln-29-001/hashes.sha256 create mode 100644 out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json create mode 100644 out/console/guardrails/cli-vuln-29-001/sample-vuln-output.ndjson create mode 100644 out/mirror/thin/mirror-thin-m0-sample.sha256 create mode 100644 out/mirror/thin/mirror-thin-m0-sample.tar.gz create mode 100644 out/mirror/thin/sample-m0/README.txt create mode 100644 out/mirror/thin/sample-m0/manifest.json create mode 100644 out/test-results/linksets/linksets.trx create mode 100644 samples/TASKS.md create mode 100644 scripts/__fixtures__/api-compat/new.yaml create mode 100644 scripts/__fixtures__/api-compat/old.yaml create mode 100644 scripts/api-changelog.mjs create mode 100644 scripts/api-compat-changelog.mjs create mode 100644 scripts/api-compat-changelog.test.mjs create mode 100644 scripts/api-compat-diff.mjs create mode 100644 scripts/api-compat-diff.test.mjs create mode 100644 scripts/api-example-coverage.mjs create mode 100644 scripts/provenance_backfill.py create mode 100644 src/Api/StellaOps.Api.OpenApi/CHANGELOG.md create mode 100644 src/Api/StellaOps.Api.OpenApi/_shared/parameters/paging.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/_shared/parameters/tenant.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/_shared/responses/defaults.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/_shared/schemas/common.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/_shared/securitySchemes/default.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/baselines/stella-baseline.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/compose.mjs create mode 100644 src/Api/StellaOps.Api.OpenApi/export-center/openapi.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/graph/openapi.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/orchestrator/openapi.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/policy/openapi.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/scheduler/openapi.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/stella.yaml create mode 100644 src/Api/StellaOps.Api.OpenApi/tasks.md create mode 100644 src/Attestor/StellaOps.Attestation.Tests/DsseHelperTests.cs create mode 100644 src/Attestor/StellaOps.Attestation.Tests/StellaOps.Attestation.Tests.csproj create mode 100644 src/Attestor/StellaOps.Attestation/DsseHelper.cs create mode 100644 src/Attestor/StellaOps.Attestation/IAuthoritySigner.cs create mode 100644 src/Attestor/StellaOps.Attestation/Models.cs create mode 100644 src/Attestor/StellaOps.Attestation/StellaOps.Attestation.csproj create mode 100644 src/Concelier/__Libraries/StellaOps.Concelier.Core/Linksets/PolicyAuthSignalFactory.cs create mode 100644 src/Concelier/__Libraries/StellaOps.Concelier.Core/Policy/AuthSignalsPackage.cs create mode 100644 src/Concelier/__Tests/StellaOps.Concelier.Core.Tests/Linksets/AdvisoryLinksetNormalizationTests.cs create mode 100644 src/Concelier/__Tests/StellaOps.Concelier.Core.Tests/Linksets/PolicyAuthSignalFactoryTests.cs create mode 100644 src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/AdvisoryChunkBuilderTests.cs create mode 100644 src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/AdvisoryChunkCacheKeyTests.cs create mode 100644 src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests/Services/AdvisoryChunkBuilderTests.cs create mode 100644 src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/VexLinksetListEndpointTests.cs create mode 100644 src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/GraphIdentityTests.cs create mode 100644 src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/GraphSnapshotBuilderTests.cs create mode 100644 src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/SbomSnapshotExporterTests.cs create mode 100644 src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/HttpEgressSloSinkTests.cs create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/Support/TestEgressSloSink.cs create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Worker/Options/EgressSloOptions.cs create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Worker/Processing/EgressSloContext.cs create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Worker/Processing/HttpEgressSloSink.cs create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Worker/Processing/IEgressSloSink.cs create mode 100644 src/Notifier/StellaOps.Notifier/StellaOps.Notifier.docs/QA-attestation-routing.md create mode 100644 src/Notifier/StellaOps.Notifier/docs/attestation-rules.sample.json create mode 100644 src/Policy/__Libraries/StellaOps.Policy.AuthSignals/PolicyAuthSignal.cs create mode 100644 src/Policy/__Libraries/StellaOps.Policy.AuthSignals/StellaOps.Policy.AuthSignals.csproj create mode 100644 src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Deno/Internal/Runtime/DenoRuntimeTraceRunner.cs create mode 100644 src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/Internal/NodeEntrypoint.cs create mode 100644 src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/Internal/NodeImportEdge.cs create mode 100644 src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/Internal/NodeImportWalker.cs create mode 100644 src/Scanner/__Libraries/StellaOps.Scanner.Emit/Reachability/ReachabilityLattice.cs create mode 100644 src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/Deno/DenoLanguageAnalyzerRuntimeTests.cs create mode 100644 src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/Deno/DenoRuntimeTraceRunnerTests.cs create mode 100644 src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/Node/NodeEntrypointTests.cs create mode 100644 src/Scanner/__Tests/StellaOps.Scanner.Emit.Tests/Reachability/ReachabilityLatticeTests.cs create mode 100644 tests/reachability/StellaOps.Reachability.FixtureTests/CorpusFixtureTests.cs create mode 100644 tests/reachability/corpus/README.md create mode 100644 tests/reachability/corpus/dotnet/dotnet-kestrel-CVE-2023-44487-http2-rapid-reset/callgraph.static.json create mode 100644 tests/reachability/corpus/dotnet/dotnet-kestrel-CVE-2023-44487-http2-rapid-reset/expect.yaml create mode 100644 tests/reachability/corpus/dotnet/dotnet-kestrel-CVE-2023-44487-http2-rapid-reset/vex.openvex.json create mode 100644 tests/reachability/corpus/go/go-ssh-CVE-2020-9283-keyexchange/callgraph.static.json create mode 100644 tests/reachability/corpus/go/go-ssh-CVE-2020-9283-keyexchange/expect.yaml create mode 100644 tests/reachability/corpus/go/go-ssh-CVE-2020-9283-keyexchange/vex.openvex.json create mode 100644 tests/reachability/corpus/manifest.json create mode 100644 tests/reachability/corpus/python/python-django-CVE-2019-19844-sqli-like/callgraph.static.json create mode 100644 tests/reachability/corpus/python/python-django-CVE-2019-19844-sqli-like/expect.yaml create mode 100644 tests/reachability/corpus/python/python-django-CVE-2019-19844-sqli-like/vex.openvex.json create mode 100644 tests/reachability/corpus/rust/rust-axum-header-parsing-TBD/callgraph.static.json create mode 100644 tests/reachability/corpus/rust/rust-axum-header-parsing-TBD/expect.yaml create mode 100644 tests/reachability/corpus/rust/rust-axum-header-parsing-TBD/vex.openvex.json create mode 100644 tests/reachability/scripts/README.md create mode 100644 tests/reachability/scripts/update_corpus_manifest.py create mode 100644 tools/linksets-ci.sh create mode 100644 tools/openssl1.1/lib/libcrypto.so.1.1 create mode 100644 tools/openssl1.1/lib/libssl.so.1.1 diff --git a/.gitea/workflows/api-governance.yml b/.gitea/workflows/api-governance.yml index 34a0e0ebd..235be7952 100644 --- a/.gitea/workflows/api-governance.yml +++ b/.gitea/workflows/api-governance.yml @@ -23,5 +23,27 @@ jobs: node-version: "18" - name: Install npm deps run: npm install --ignore-scripts --no-progress + - name: Compose aggregate OpenAPI + run: npm run api:compose + - name: Validate examples coverage + run: npm run api:examples + - name: Compatibility diff (previous commit) + run: | + set -e + if git show HEAD~1:src/Api/StellaOps.Api.OpenApi/stella.yaml > /tmp/stella-prev.yaml 2>/dev/null; then + node scripts/api-compat-diff.mjs /tmp/stella-prev.yaml src/Api/StellaOps.Api.OpenApi/stella.yaml --output text --fail-on-breaking + else + echo "[api:compat] previous stella.yaml not found; skipping" + fi + - name: Compatibility diff (baseline) + run: | + set -e + if [ -f src/Api/StellaOps.Api.OpenApi/baselines/stella-baseline.yaml ]; then + node scripts/api-compat-diff.mjs src/Api/StellaOps.Api.OpenApi/baselines/stella-baseline.yaml src/Api/StellaOps.Api.OpenApi/stella.yaml --output text + else + echo "[api:compat] baseline file missing; skipping" + fi + - name: Generate changelog + run: npm run api:changelog - name: Spectral lint (fail on warning+) run: npm run api:lint diff --git a/AGENTS.md b/AGENTS.md index 06a76a599..d9bbed491 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -154,14 +154,9 @@ It ships as containerised building blocks; each module owns a clear boundary and You will be explicitly told which role you are acting in. Your behavior must change accordingly. -Good catch. Here’s the same prompt updated with: - 1. Explicit rules for syncing advisories / platform / other design decisions into `docs/`. 2. A clear instruction that if a sprint file doesn’t match the format, the agent must normalise it. - -I’ll show only the modified sections so you can drop them in. - ---- +3. You never use `git reset` unless explicitly told to do so! ### 4.1) As product manager (updated) diff --git a/blocked_deps_report.txt b/blocked_deps_report.txt new file mode 100644 index 000000000..78b925b87 --- /dev/null +++ b/blocked_deps_report.txt @@ -0,0 +1,1646 @@ +docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md:28 + Task: SBOM-AIAI-31-003 + Dependency text: SBOM-AIAI-31-001; CLI-VULN-29-001; CLI-VEX-30-001 + - SBOM-AIAI-31: UNKNOWN + - CLI-VULN-29: UNKNOWN + - CLI-VEX-30: UNKNOWN + +docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md:29 + Task: DOCS-AIAI-31-005/006/008/009 + Dependency text: CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001; DEVOPS-AIAI-31-001 + - CLI-VULN-29: UNKNOWN + - CLI-VEX-30: UNKNOWN + - POLICY-ENGINE-31: UNKNOWN + - DEVOPS-AIAI-31: UNKNOWN + +docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md:32 + Task: CONCELIER-AIRGAP-56-001..58-001 + Dependency text: Await Mirror thin-bundle milestone dates and evidence bundle artifacts for offline chain + - No formal task IDs detected + +docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md:33 + Task: CONCELIER-CONSOLE-23-001..003 + Dependency text: Console schema samples not yet published alongside frozen LNM; need evidence bundle identifiers + - No formal task IDs detected + +docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md:34 + Task: CONCELIER-ATTEST-73-001/002 + Dependency text: Evidence Locker attestation scope sign-off still pending (due 2025-11-19) + - No formal task IDs detected + +docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md:35 + Task: FEEDCONN-ICSCISA-02-012 / KISA-02-008 + Dependency text: Feed owner remediation plan + - No formal task IDs detected + +docs/implplan/SPRINT_0113_0001_0002_concelier_ii.md:26 + Task: CONCELIER-GRAPH-21-002 + Dependency text: Platform Events/Scheduler contract for `sbom.observation.updated` not defined; no event publisher plumbing in repo. + - No formal task IDs detected + +docs/implplan/SPRINT_0113_0001_0002_concelier_ii.md:30 + Task: CONCELIER-LNM-21-002 + Dependency text: Waiting on finalized LNM fixtures + precedence rules and event contract; confidence heuristic in place; broader tests deferred to CI + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:23 + Task: CONCELIER-OAS-61-001 + Dependency text: LNM schema frozen 2025-11-17, but OpenAPI source/spec artifact not present in repo; need canonical spec to edit + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:24 + Task: CONCELIER-OAS-61-002 + Dependency text: Depends on 61-001; blocked until OpenAPI spec is available + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:25 + Task: CONCELIER-OAS-62-001 + Dependency text: Depends on 61-002; blocked with OAS chain + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:26 + Task: CONCELIER-OAS-63-001 + Dependency text: Depends on 62-001; blocked with OAS chain + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:27 + Task: CONCELIER-OBS-51-001 + Dependency text: Await observability spec (metrics names/labels, SLO burn rules) from DevOps; none present in repo + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:28 + Task: CONCELIER-OBS-52-001 + Dependency text: Depends on 51-001 metrics contract; blocked accordingly + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:29 + Task: CONCELIER-OBS-53-001 + Dependency text: Depends on 52-001; blocked until timeline instrumentation defined + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:30 + Task: CONCELIER-OBS-54-001 + Dependency text: Depends on OBS timeline artifacts; no attestation contract yet + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:31 + Task: CONCELIER-OBS-55-001 + Dependency text: Depends on 54-001; incident-mode hooks need finalized attestation/timeline shape + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:32 + Task: CONCELIER-ORCH-32-001 + Dependency text: Orchestrator registry/SDK contract not published; no registry metadata to align + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:33 + Task: CONCELIER-ORCH-32-002 + Dependency text: Depends on 32-001; blocked until orchestrator SDK/controls provided + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:34 + Task: CONCELIER-ORCH-33-001 + Dependency text: Depends on 32-002; blocked with orchestrator contract gap + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:35 + Task: CONCELIER-ORCH-34-001 + Dependency text: Depends on 33-001; blocked with orchestrator contract gap + - No formal task IDs detected + +docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md:36 + Task: CONCELIER-POLICY-20-001 + Dependency text: LNM APIs not exposed via OpenAPI; depends on OAS chain (61-001..63-001) now blocked + - No formal task IDs detected + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:28 + Task: CONCELIER-RISK-66-001 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 and POLICY chain. + - SIGNALS-LIB-115: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:29 + Task: CONCELIER-RISK-66-002 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 and 66-001. + - SIGNALS-LIB-115: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:30 + Task: CONCELIER-RISK-67-001 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 and 66-001. + - SIGNALS-LIB-115: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:31 + Task: CONCELIER-RISK-68-001 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 and POLICY-RISK-68-001. + - SIGNALS-LIB-115: UNKNOWN + - POLICY-RISK-68: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:32 + Task: CONCELIER-RISK-69-001 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 and 66-002. + - SIGNALS-LIB-115: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:33 + Task: CONCELIER-SIG-26-001 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 delivering SIGNALS-24-002. + - SIGNALS-LIB-115: UNKNOWN + - SIGNALS-24-002: DOING + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:34 + Task: CONCELIER-STORE-AOC-19-005 + Dependency text: Depends on CONCELIER-CORE-AOC-19-004 + - CORE-AOC-19: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:35 + Task: CONCELIER-TEN-48-001 + Dependency text: Blocked on POLICY-AUTH-SIGNALS-LIB-115 delivering AUTH-TEN-47-001. + - SIGNALS-LIB-115: UNKNOWN + - AUTH-TEN-47: UNKNOWN + +docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md:36 + Task: CONCELIER-VEXLENS-30-001 + Dependency text: Depends on CONCELIER-VULN-29-001, VEXLENS-30-005 + - CONCELIER-VULN-29: UNKNOWN + - VEXLENS-30-005: TODO + +docs/implplan/SPRINT_0116_0001_0005_concelier_v.md:26 + Task: CONCELIER-WEB-AIRGAP-57-001 + Dependency text: Depends on 56-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0001_excititor_i.md:29 + Task: EXCITITOR-AIRGAP-56-001 + Dependency text: Waiting on Export Center mirror bundle schema (Sprint 162) to define ingestion shape. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0001_excititor_i.md:30 + Task: EXCITITOR-AIRGAP-57-001 + Dependency text: Blocked on 56-001 schema; sealed-mode error catalog pending. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0001_excititor_i.md:31 + Task: EXCITITOR-AIRGAP-58-001 + Dependency text: Depends on 57-001 plus EvidenceLocker portable format (160/161). + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0001_excititor_i.md:35 + Task: EXCITITOR-CONN-TRUST-01-001 + Dependency text: Connector signer metadata schema still unpublished post-2025-11-14 review. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0001_excititor_i.md:88 + Task: Attestation verifier rehearsal (Excititor Attestation Guild) + Dependency text: If issues persist, log BLOCKED status in attestation plan and re-forecast completion. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:27 + Task: EXCITITOR-CONSOLE-23-001 + Dependency text: Awaiting concrete `/console/vex` API contract and grouping schema; LNM 21-* view spec not present. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:28 + Task: EXCITITOR-CONSOLE-23-002 + Dependency text: Depends on 23-001; need sprint-level contract for counters. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:29 + Task: EXCITITOR-CONSOLE-23-003 + Dependency text: Depends on 23-001; contract for caching/RBAC/precedence context pending. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:30 + Task: EXCITITOR-CORE-AOC-19-002 + Dependency text: Linkset extraction rules/ordering not documented. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:31 + Task: EXCITITOR-CORE-AOC-19-003 + Dependency text: Blocked on 19-002; design supersede chains. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:32 + Task: EXCITITOR-CORE-AOC-19-004 + Dependency text: Remove consensus after 19-003 in place. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:33 + Task: EXCITITOR-CORE-AOC-19-013 + Dependency text: Seed tenant-aware Authority clients in smoke/e2e once 19-004 lands. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:34 + Task: EXCITITOR-GRAPH-21-001 + Dependency text: Needs Cartographer API contract + data availability. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:35 + Task: EXCITITOR-GRAPH-21-002 + Dependency text: Blocked on 21-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:36 + Task: EXCITITOR-GRAPH-21-005 + Dependency text: Blocked on 21-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:37 + Task: EXCITITOR-GRAPH-24-101 + Dependency text: Wait for 21-005 indexes. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:38 + Task: EXCITITOR-GRAPH-24-102 + Dependency text: Depends on 24-101; design batch shape. + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:45 + Task: Finalize `/console/vex` contract (23-001) and dashboard deltas (23-002). + Dependency text: 2025-11-18 + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:46 + Task: Land linkset extraction + raw upsert uniqueness (19-002/003). + Dependency text: 2025-11-19 + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:47 + Task: Remove merge/severity logic after idempotency in place (19-004). + Dependency text: 2025-11-20 + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:48 + Task: Align inspector/linkout schemas to unblock 21-001/002/005. + Dependency text: 2025-11-21 + - No formal task IDs detected + +docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md:76 + Task: Cartographer schema sync + Dependency text: Maintain BLOCKED status; deliver sample payloads for early testing. + - No formal task IDs detected + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:45 + Task: LEDGER-29-008 + Dependency text: Await Observability schema sign-off + ledger write endpoint contract; 5 M fixture drop pending + - No formal task IDs detected + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:46 + Task: LEDGER-29-009 + Dependency text: Depends on LEDGER-29-008 harness results (5 M replay + observability schema) + - LEDGER-29-008: BLOCKED + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:47 + Task: LEDGER-34-101 + Dependency text: Orchestrator ledger export contract (Sprint 150.A) not published + - No formal task IDs detected + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:48 + Task: LEDGER-AIRGAP-56-001 + Dependency text: Mirror bundle schema freeze outstanding + - No formal task IDs detected + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:49 + Task: LEDGER-AIRGAP-56-002 + Dependency text: Depends on LEDGER-AIRGAP-56-001 provenance schema + - LEDGER-AIRGAP-56: TODO + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:50 + Task: LEDGER-AIRGAP-57-001 + Dependency text: Depends on LEDGER-AIRGAP-56-002 staleness contract + - LEDGER-AIRGAP-56: TODO + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:51 + Task: LEDGER-AIRGAP-58-001 + Dependency text: Depends on LEDGER-AIRGAP-57-001 bundle linkage + - LEDGER-AIRGAP-57: TODO + +docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md:52 + Task: LEDGER-ATTEST-73-001 + Dependency text: Attestation pointer schema alignment with NOTIFY-ATTEST-74-001 pending + - NOTIFY-ATTEST-74: UNKNOWN + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:28 + Task: LEDGER-ATTEST-73-002 + Dependency text: Waiting on LEDGER-ATTEST-73-001 verification pipeline delivery + - LEDGER-ATTEST-73: UNKNOWN + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:29 + Task: LEDGER-EXPORT-35-001 + Dependency text: No HTTP/API surface or contract to host export endpoints; needs API scaffold + filters spec + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:30 + Task: LEDGER-OAS-61-001 + Dependency text: Absent OAS baseline and API host for ledger; requires contract definition with API Guild + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:31 + Task: LEDGER-OAS-61-002 + Dependency text: Depends on 61-001 contract + HTTP surface + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:32 + Task: LEDGER-OAS-62-001 + Dependency text: SDK generation pending 61-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:33 + Task: LEDGER-OAS-63-001 + Dependency text: Dependent on SDK validation (62-001) + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:38 + Task: LEDGER-OBS-54-001 + Dependency text: No HTTP surface/minimal API present in module to host `/ledger/attestations`; needs API contract + service scaffold + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:39 + Task: LEDGER-OBS-55-001 + Dependency text: Depends on 54-001 attestation API availability + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:40 + Task: LEDGER-PACKS-42-001 + Dependency text: Snapshot/time-travel contract and bundle format not specified; needs design input + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:41 + Task: LEDGER-RISK-66-001 + Dependency text: Risk Engine schema/contract inputs absent; requires risk field definitions + rollout plan + - No formal task IDs detected + +docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md:42 + Task: LEDGER-RISK-66-002 + Dependency text: Depends on 66-001 migration + risk scoring contract + - No formal task IDs detected + +docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md:27 + Task: LEDGER-RISK-67-001 + Dependency text: Depends on risk scoring contract + migrations from LEDGER-RISK-66-002 + - LEDGER-RISK-66: UNKNOWN + +docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md:28 + Task: LEDGER-RISK-68-001 + Dependency text: Await unblock of 67-001 + Export Center contract for scored findings + - No formal task IDs detected + +docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md:29 + Task: LEDGER-RISK-69-001 + Dependency text: Requires 67-001/68-001 to define metrics dimensions + - No formal task IDs detected + +docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md:30 + Task: LEDGER-TEN-48-001 + Dependency text: Needs platform-approved partitioning + RLS policy (tenant/project shape, session variables) + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:23 + Task: EXPORT-CONSOLE-23-001 + Dependency text: Missing export bundle contract/API surface and scheduler job spec for Console. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:24 + Task: POLICY-AIRGAP-56-001 + Dependency text: Mirror bundle schema not published; requires bundle_id/provenance fields + sealed-mode rules. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:25 + Task: POLICY-AIRGAP-56-002 + Dependency text: Depends on 56-001 bundle import schema + DSSE signing profile. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:26 + Task: POLICY-AIRGAP-57-001 + Dependency text: Requires sealed-mode contract after 56-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:27 + Task: POLICY-AIRGAP-57-002 + Dependency text: Needs staleness/fallback data contract from 57-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:28 + Task: POLICY-AIRGAP-58-001 + Dependency text: Notification schema and staleness signals pending from 57-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:29 + Task: POLICY-AOC-19-001 + Dependency text: Linting targets/spec absent; no analyzer contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:30 + Task: POLICY-AOC-19-002 + Dependency text: Depends on 19-001 lint + Authority `effective:write` contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:31 + Task: POLICY-AOC-19-003 + Dependency text: Requires post-19-002 normalized-field removal contract/fixtures. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:32 + Task: POLICY-AOC-19-004 + Dependency text: Depends on 19-003 shape + determinism fixtures. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:33 + Task: POLICY-ATTEST-73-001 + Dependency text: VerificationPolicy schema/persistence contract missing; Attestor alignment needed. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:34 + Task: POLICY-ATTEST-73-002 + Dependency text: Depends on 73-001 editor DTOs/validation schema. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:35 + Task: POLICY-ATTEST-74-001 + Dependency text: Requires 73-002 + Attestor pipeline contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:36 + Task: POLICY-ATTEST-74-002 + Dependency text: Needs 74-001 surfaced in Console verification reports contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md:37 + Task: POLICY-CONSOLE-23-001 + Dependency text: Console API contract (filters/pagination/aggregation) absent. + - No formal task IDs detected + +docs/implplan/SPRINT_0124_0001_0001_policy_reasoning.md:22 + Task: POLICY-ENGINE-20-002 + Dependency text: Deterministic evaluator spec missing. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:23 + Task: MIRROR-CRT-56-001 + Dependency text: Upstream Sprint 110.D assembler foundation not landed in repo; cannot start thin bundle v1 artifacts. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:24 + Task: MIRROR-CRT-56-002 + Dependency text: Depends on MIRROR-CRT-56-001 and PROV-OBS-53-001; upstream assembler missing. + - MIRROR-CRT-56: UNKNOWN + - PROV-OBS-53: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:25 + Task: MIRROR-CRT-57-001 + Dependency text: Requires MIRROR-CRT-56-001; assembler foundation missing. + - MIRROR-CRT-56: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:26 + Task: MIRROR-CRT-57-002 + Dependency text: Needs MIRROR-CRT-56-002 and AIRGAP-TIME-57-001; waiting on assembler/signing baseline. + - MIRROR-CRT-56: UNKNOWN + - AIRGAP-TIME-57: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:27 + Task: MIRROR-CRT-58-001 + Dependency text: Requires MIRROR-CRT-56-002 and CLI-AIRGAP-56-001; downstream until assembler exists. + - MIRROR-CRT-56: UNKNOWN + - CLI-AIRGAP-56: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:28 + Task: MIRROR-CRT-58-002 + Dependency text: Depends on MIRROR-CRT-56-002 and EXPORT-OBS-54-001; waiting on sample bundles. + - MIRROR-CRT-56: UNKNOWN + - EXPORT-OBS-54: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:29 + Task: EXPORT-OBS-51-001 / 54-001 + Dependency text: MIRROR-CRT-56-001 staffing and artifacts not available. + - MIRROR-CRT-56: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:30 + Task: AIRGAP-TIME-57-001 + Dependency text: MIRROR-CRT-56-001/57-002 pending; policy workshop contingent on sample bundles. + - MIRROR-CRT-56: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:31 + Task: CLI-AIRGAP-56-001 + Dependency text: MIRROR-CRT-56-002/58-001 pending; offline kit inputs unavailable. + - MIRROR-CRT-56: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_mirror.md:32 + Task: PROV-OBS-53-001 + Dependency text: MIRROR-CRT-56-001 absent; cannot wire observers. + - MIRROR-CRT-56: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:20 + Task: POLICY-ENGINE-29-003 + Dependency text: Waiting on POLICY-ENGINE-29-002 contract (path/scope schema). + - POLICY-ENGINE-29: UNKNOWN + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:21 + Task: POLICY-ENGINE-29-004 + Dependency text: Depends on 29-003. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:22 + Task: POLICY-ENGINE-30-001 + Dependency text: Needs 29-004 outputs. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:23 + Task: POLICY-ENGINE-30-002 + Dependency text: Depends on 30-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:24 + Task: POLICY-ENGINE-30-003 + Dependency text: Depends on 30-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:25 + Task: POLICY-ENGINE-30-101 + Dependency text: Depends on 30-003. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:26 + Task: POLICY-ENGINE-31-001 + Dependency text: Depends on 30-101. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:27 + Task: POLICY-ENGINE-31-002 + Dependency text: Depends on 31-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:28 + Task: POLICY-ENGINE-32-101 + Dependency text: Depends on 31-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:29 + Task: POLICY-ENGINE-33-101 + Dependency text: Depends on 32-101. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:30 + Task: POLICY-ENGINE-34-101 + Dependency text: Depends on 33-101. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:31 + Task: POLICY-ENGINE-35-201 + Dependency text: Depends on 34-101. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:32 + Task: POLICY-ENGINE-38-201 + Dependency text: Depends on 35-201. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:33 + Task: POLICY-ENGINE-40-001 + Dependency text: Depends on 38-201. + - No formal task IDs detected + +docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md:34 + Task: POLICY-ENGINE-40-002 + Dependency text: Depends on 40-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0127_0001_0001_policy_reasoning.md:29 + Task: POLICY-RISK-66-001 + Dependency text: RiskProfile library scaffold absent (`src/Policy/StellaOps.Policy.RiskProfile` contains only AGENTS.md); need project + storage contract to place schema/validators. + - No formal task IDs detected + +docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md:27 + Task: SCANNER-ANALYZERS-JAVA-21-005 + Dependency text: Tests blocked: repo build fails in Concelier (CoreLinksets missing) and targeted Java analyzer test run stalls; retry once dependencies fixed or CI available. + - No formal task IDs detected + +docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md:30 + Task: SCANNER-ANALYZERS-JAVA-21-008 + Dependency text: Waiting on 21-007 completion and resolver authoring bandwidth. + - No formal task IDs detected + +docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md:34 + Task: SCANNER-ANALYZERS-LANG-11-001 + Dependency text: `dotnet test` hangs/returns empty output; needs clean runner/CI diagnostics. + - No formal task IDs detected + +docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md:25 + Task: SCANNER-ANALYZERS-LANG-11-002 + Dependency text: Await upstream SCANNER-ANALYZERS-LANG-11-001 design/outputs to extend static analyzer + - ANALYZERS-LANG-11: UNKNOWN + +docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md:26 + Task: SCANNER-ANALYZERS-LANG-11-003 + Dependency text: Depends on 11-002; blocked until upstream static analyzer available + - No formal task IDs detected + +docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md:27 + Task: SCANNER-ANALYZERS-LANG-11-004 + Dependency text: Depends on 11-003; no upstream static/runtime outputs yet + - No formal task IDs detected + +docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md:28 + Task: SCANNER-ANALYZERS-LANG-11-005 + Dependency text: Depends on 11-004; fixtures deferred until analyzer outputs exist + - No formal task IDs detected + +docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md:30 + Task: SCANNER-ANALYZERS-NATIVE-20-002 + Dependency text: Await declared-dependency writer/contract to emit edges + - No formal task IDs detected + +docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md:39 + Task: SCANNER-ANALYZERS-NODE-22-001 + Dependency text: Needs isolated runner or scoped build graph to execute targeted tests without full-solution fan-out + - No formal task IDs detected + +docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md:22 + Task: SCANNER-ANALYZERS-NODE-22-006 + Dependency text: Upstream 22-005 not delivered in Sprint 0132; waiting on bundle/source-map resolver baseline. + - No formal task IDs detected + +docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md:23 + Task: SCANNER-ANALYZERS-NODE-22-007 + Dependency text: Upstream 22-006 blocked. + - No formal task IDs detected + +docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md:24 + Task: SCANNER-ANALYZERS-NODE-22-008 + Dependency text: Upstream 22-007 blocked. + - No formal task IDs detected + +docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md:24 + Task: SCANNER-ENG-0010 + Dependency text: Await composer/autoload graph design + staffing; no PHP analyzer scaffolding exists yet. + - No formal task IDs detected + +docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md:25 + Task: SCANNER-ENG-0011 + Dependency text: Needs Deno runtime analyzer scope + lockfile/import graph design; pending competitive review. + - No formal task IDs detected + +docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md:26 + Task: SCANNER-ENG-0012 + Dependency text: Define Dart analyzer requirements (pubspec parsing, AOT artifacts) and split into tasks. + - No formal task IDs detected + +docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md:27 + Task: SCANNER-ENG-0013 + Dependency text: Draft SwiftPM coverage plan; align policy hooks; awaiting design kick-off. + - No formal task IDs detected + +docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md:28 + Task: SCANNER-ENG-0014 + Dependency text: Needs joint roadmap with Zastava/Runtime guilds for Kubernetes/VM alignment. + - No formal task IDs detected + +docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md:28 + Task: 140.B SBOM Service wave + Dependency text: LNM v1 fixtures overdue; AirGap parity review not scheduled; SBOM-SERVICE-21-001 remains blocked pending fixtures. + - SBOM-SERVICE-21: UNKNOWN + +docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md:30 + Task: 140.D Zastava wave + Dependency text: Waiting on Surface.FS cache drop plan + Surface.Env helper ownership. + - No formal task IDs detected + +docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md:83 + Task: SBOM Service Guild · Cartographer Guild · Observability Guild + Dependency text: BLOCKED + - No formal task IDs detected + +docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md:85 + Task: Zastava Observer/Webhook Guilds · Security Guild + Dependency text: BLOCKED + - No formal task IDs detected + +docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md:221 + Task: 2025-11-14 + Dependency text: Requires `CONCELIER-GRAPH-21-001` + `CARTO-GRAPH-21-002` agreement; AirGap review scheduled after sign-off. + - CONCELIER-GRAPH-21: UNKNOWN + - CARTO-GRAPH-21: UNKNOWN + +docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md:24 + Task: GRAPH-INDEX-28-007 + Dependency text: Waiting on GRAPH-INDEX-28-006 overlays + schedule config design + - GRAPH-INDEX-28: UNKNOWN + +docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md:25 + Task: GRAPH-INDEX-28-008 + Dependency text: Unblock after 28-007; confirm change streams + retry/backoff settings + - No formal task IDs detected + +docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md:26 + Task: GRAPH-INDEX-28-009 + Dependency text: Downstream of 28-008 data paths + - No formal task IDs detected + +docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md:27 + Task: GRAPH-INDEX-28-010 + Dependency text: Needs outputs from 28-009; align with Offline Kit owners + - No formal task IDs detected + +docs/implplan/SPRINT_0142_0001_0001_sbomservice.md:24 + Task: SBOM-CONSOLE-23-001 + Dependency text: Build/test failing due to missing NuGet feed; need feed/offline cache before wiring storage and validating `/console/sboms`. + - No formal task IDs detected + +docs/implplan/SPRINT_0142_0001_0001_sbomservice.md:29 + Task: SBOM-SERVICE-21-001 + Dependency text: Waiting on LNM v1 fixtures (due 2025-11-18 UTC) to freeze schema; then publish normalized SBOM projection read API with pagination + tenant enforcement. + - No formal task IDs detected + +docs/implplan/SPRINT_0142_0001_0001_sbomservice.md:44 + Task: Build/Infra · SBOM Service Guild + Dependency text: BLOCKED (multiple restore attempts still hang/fail; need vetted feed/cache) + - No formal task IDs detected + +docs/implplan/SPRINT_0143_0000_0001_signals.md:26 + Task: SIGNALS-24-005 + Dependency text: Redis cache implemented; awaiting real bus/topic + payload contract to replace placeholder `signals.fact.updated` logging. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:22 + Task: ORCH-AIRGAP-56-001 + Dependency text: Await Sprint 0120.A AirGap readiness; sealed-mode contracts not published. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:23 + Task: ORCH-AIRGAP-56-002 + Dependency text: Upstream 56-001 blocked. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:24 + Task: ORCH-AIRGAP-57-001 + Dependency text: Upstream 56-002 blocked. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:25 + Task: ORCH-AIRGAP-58-001 + Dependency text: Upstream 57-001 blocked. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:26 + Task: ORCH-OAS-61-001 + Dependency text: Orchestrator telemetry/contract inputs not available; wait for 150.A readiness. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:27 + Task: ORCH-OAS-61-002 + Dependency text: Depends on 61-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:28 + Task: ORCH-OAS-62-001 + Dependency text: Depends on 61-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:29 + Task: ORCH-OAS-63-001 + Dependency text: Depends on 62-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:30 + Task: ORCH-OBS-50-001 + Dependency text: Telemetry Core (Sprint 0174) not yet available for orchestrator host. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:31 + Task: ORCH-OBS-51-001 + Dependency text: Depends on 50-001 + Telemetry schema. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:32 + Task: ORCH-OBS-52-001 + Dependency text: Depends on 51-001; requires event schema from Sprint 0150.A. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:33 + Task: ORCH-OBS-53-001 + Dependency text: Depends on 52-001; Evidence Locker capsule inputs not frozen. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:34 + Task: ORCH-OBS-54-001 + Dependency text: Depends on 53-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:35 + Task: ORCH-OBS-55-001 + Dependency text: Depends on 54-001; incident contract absent. + - No formal task IDs detected + +docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md:36 + Task: ORCH-SVC-32-001 + Dependency text: Upstream readiness (AirGap/Scanner/Graph) not confirmed; postpone bootstrap. + - No formal task IDs detected + +docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md:22 + Task: ORCH-SVC-38-101 + Dependency text: Waiting on ORCH-SVC-37-101 envelope field/semantics approval; webservice DAL still missing. + - ORCH-SVC-37: UNKNOWN + +docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md:23 + Task: ORCH-SVC-41-101 + Dependency text: Depends on 38-101 envelope + DAL; cannot register pack-run without API/storage schema. + - No formal task IDs detected + +docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md:24 + Task: ORCH-SVC-42-101 + Dependency text: Depends on 41-101 pack-run plumbing and streaming contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md:25 + Task: ORCH-TEN-48-001 + Dependency text: WebService lacks job DAL/routes; need tenant context plumbing before enforcement. + - No formal task IDs detected + +docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md:24 + Task: SCHED-SURFACE-01 + Dependency text: Need Surface.FS pointer model/contract; awaiting design input before planning deltas. + - No formal task IDs detected + +docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md:29 + Task: SCHED-WORKER-23-101 + Dependency text: Waiting on Policy guild to supply activation event contract and throttle source. + - No formal task IDs detected + +docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md:30 + Task: SCHED-WORKER-23-102 + Dependency text: Blocked by SCHED-WORKER-23-101. + - SCHED-WORKER-23: UNKNOWN + +docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md:31 + Task: SCHED-WORKER-25-101 + Dependency text: Blocked by SCHED-WORKER-23-102. + - SCHED-WORKER-23: UNKNOWN + +docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md:32 + Task: SCHED-WORKER-25-102 + Dependency text: Blocked by SCHED-WORKER-25-101. + - SCHED-WORKER-25: UNKNOWN + +docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md:33 + Task: SCHED-WORKER-26-201 + Dependency text: Blocked by SCHED-WORKER-25-102. + - SCHED-WORKER-25: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:23 + Task: SCHED-WORKER-26-202 + Dependency text: Blocked by SCHED-WORKER-26-201 (reachability joiner not delivered yet). + - SCHED-WORKER-26: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:24 + Task: SCHED-WORKER-27-301 + Dependency text: Blocked by SCHED-WORKER-26-202. + - SCHED-WORKER-26: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:25 + Task: SCHED-WORKER-27-302 + Dependency text: Blocked by SCHED-WORKER-27-301. + - SCHED-WORKER-27: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:26 + Task: SCHED-WORKER-27-303 + Dependency text: Blocked by SCHED-WORKER-27-302. + - SCHED-WORKER-27: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:27 + Task: SCHED-WORKER-29-001 + Dependency text: Blocked by SCHED-WORKER-27-303. + - SCHED-WORKER-27: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:28 + Task: SCHED-WORKER-29-002 + Dependency text: Blocked by SCHED-WORKER-29-001. + - SCHED-WORKER-29: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:29 + Task: SCHED-WORKER-29-003 + Dependency text: Blocked by SCHED-WORKER-29-002. + - SCHED-WORKER-29: UNKNOWN + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:30 + Task: SCHED-WORKER-CONSOLE-23-201 + Dependency text: Blocked by upstream stream schema design; depends on prior resolver/eval pipeline readiness. + - No formal task IDs detected + +docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md:31 + Task: SCHED-WORKER-CONSOLE-23-202 + Dependency text: Blocked by CONSOLE-23-201. + - CONSOLE-23-201: UNKNOWN + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:28 + Task: 160.C TimelineIndexer snapshot + Dependency text: Waiting on OBS-52-001 digest references; schemas available. Prep migrations/RLS draft. + - OBS-52-001: TODO + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:34 + Task: Evidence Locker Guild · Security Guild · Docs Guild + Dependency text: BLOCKED (2025-11-17) + - No formal task IDs detected + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:35 + Task: Exporter Service Guild · Mirror Creator Guild · DevOps Guild + Dependency text: BLOCKED (2025-11-17) + - No formal task IDs detected + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:36 + Task: Timeline Indexer Guild · Evidence Locker Guild · Security Guild + Dependency text: BLOCKED (2025-11-17) + - No formal task IDs detected + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:113 + Task: Orchestrator + Notifications schema handoff (Orchestrator Service + Notifications Guilds) + Dependency text: MISSED; escalate to Wave 150/140 leads and record new ETA; keep tasks BLOCKED. + - No formal task IDs detected + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:116 + Task: Escalation follow-up (AdvisoryAI, Orchestrator/Notifications) + Dependency text: If no dates provided, mark BLOCKED in respective sprints and escalate to Wave leads. + - No formal task IDs detected + +docs/implplan/SPRINT_0160_0001_0001_export_evidence.md:151 + Task: 160.A, 160.B, 160.C + Dependency text: Escalate to Wave 150/140 leads, record BLOCKED status in both sprint docs, and schedule daily schema stand-ups until envelopes land. + - No formal task IDs detected + +docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md:28 + Task: EVID-REPLAY-187-001 + Dependency text: Await replay ledger retention shape; schemas available. + - No formal task IDs detected + +docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md:29 + Task: CLI-REPLAY-187-002 + Dependency text: Waiting on EvidenceLocker APIs after bundle packaging finalization. + - No formal task IDs detected + +docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md:30 + Task: RUNBOOK-REPLAY-187-004 + Dependency text: Depends on retention APIs + CLI behavior. + - No formal task IDs detected + +docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md:37 + Task: Evidence Locker Guild + Dependency text: BLOCKED (schemas not yet delivered) + - No formal task IDs detected + +docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md:38 + Task: Evidence Locker Guild · Replay Delivery Guild + Dependency text: BLOCKED (awaiting schema signals) + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:24 + Task: DVOFF-64-002 + Dependency text: Needs sealed bundle spec + sample manifest for CLI verify flow; due for Nov-19 dry run. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:25 + Task: EXPORT-AIRGAP-56-001 + Dependency text: EvidenceLocker contract + advisory schema to finalize DSSE contents. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:26 + Task: EXPORT-AIRGAP-56-002 + Dependency text: Depends on 56-001; same schema prerequisites. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:27 + Task: EXPORT-AIRGAP-57-001 + Dependency text: Depends on 56-002; needs sealed evidence bundle format. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:28 + Task: EXPORT-AIRGAP-58-001 + Dependency text: Depends on 57-001; needs notifications envelope schema. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:29 + Task: EXPORT-ATTEST-74-001 + Dependency text: Needs EvidenceLocker bundle layout + orchestration events. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:30 + Task: EXPORT-ATTEST-74-002 + Dependency text: Depends on 74-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:31 + Task: EXPORT-ATTEST-75-001 + Dependency text: Depends on 74-002; needs CLI contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:32 + Task: EXPORT-ATTEST-75-002 + Dependency text: Depends on 75-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:33 + Task: EXPORT-OAS-61-001 + Dependency text: Needs stable export surfaces; await EvidenceLocker contract. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:34 + Task: EXPORT-OAS-61-002 + Dependency text: Depends on 61-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:35 + Task: EXPORT-OAS-62-001 + Dependency text: Depends on 61-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:40 + Task: Exporter Service · EvidenceLocker Guild + Dependency text: BLOCKED (awaits EvidenceLocker contract) + - No formal task IDs detected + +docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md:55 + Task: Orchestrator + Notifications schema handoff + Dependency text: If not ready, keep tasks BLOCKED and escalate to Wave 150/140 leads. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:23 + Task: EXPORT-OAS-63-001 + Dependency text: Needs EXPORT-OAS-61/62 outputs + stable APIs. + - EXPORT-OAS-61: TODO + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:24 + Task: EXPORT-OBS-50-001 + Dependency text: Wait for exporter service bootstrap + telemetry schema. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:25 + Task: EXPORT-OBS-51-001 + Dependency text: Depends on OBS-50 schema. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:26 + Task: EXPORT-OBS-52-001 + Dependency text: Depends on OBS-51 and notifications envelopes. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:27 + Task: EXPORT-OBS-53-001 + Dependency text: Depends on OBS-52 and EvidenceLocker manifest format. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:28 + Task: EXPORT-OBS-54-001 + Dependency text: Depends on OBS-53. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:29 + Task: EXPORT-OBS-54-002 + Dependency text: Depends on OBS-54-001 and PROV-OBS-53-003. + - OBS-54-001: TODO + - PROV-OBS-53: UNKNOWN + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:30 + Task: EXPORT-OBS-55-001 + Dependency text: Depends on OBS-54-001. + - OBS-54-001: TODO + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:31 + Task: EXPORT-RISK-69-001 + Dependency text: Await phase I artifacts + schema; needs provider selection rules. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:32 + Task: EXPORT-RISK-69-002 + Dependency text: Depends on RISK-69-001. + - RISK-69-001: TODO + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:33 + Task: EXPORT-RISK-70-001 + Dependency text: Depends on RISK-69-002. + - RISK-69-002: TODO + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:34 + Task: EXPORT-SVC-35-001 + Dependency text: Needs phase I readiness + synthetic telemetry feeds. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:35 + Task: EXPORT-SVC-35-002 + Dependency text: Depends on 35-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:36 + Task: EXPORT-SVC-35-003 + Dependency text: Depends on 35-002. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:37 + Task: EXPORT-SVC-35-004 + Dependency text: Depends on 35-003. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:38 + Task: EXPORT-SVC-35-005 + Dependency text: Depends on 35-004. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:39 + Task: EXPORT-CRYPTO-90-001 + Dependency text: Pending Nov-18 crypto review + reference implementation. + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:44 + Task: Exporter Service + Dependency text: BLOCKED (waiting on EvidenceLocker spec) + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:45 + Task: Observability Guild + Dependency text: BLOCKED (awaiting OBS-50 start) + - No formal task IDs detected + +docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md:46 + Task: Exporter Service · API Governance + Dependency text: BLOCKED (depends on OAS-61/62 outputs) + - No formal task IDs detected + +docs/implplan/SPRINT_0171_0001_0001_notifier_i.md:29 + Task: NOTIFY-OBS-51-001 + Dependency text: Telemetry SLO webhook schema frozen; SLO sink coded. Blocked on CI restore to run `HttpEgressSloSinkTests`/`EventProcessorTests`. + - No formal task IDs detected + +docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md:21 + Task: NOTIFY-TEN-48-001 + Dependency text: Notifier II (Sprint 0172) not started; tenancy model not finalized. + - No formal task IDs detected + +docs/implplan/SPRINT_0174_0001_0001_telemetry.md:23 + Task: TELEMETRY-OBS-50-002 + Dependency text: Await published 50-001 bootstrap package. + - No formal task IDs detected + +docs/implplan/SPRINT_0174_0001_0001_telemetry.md:24 + Task: TELEMETRY-OBS-51-001 + Dependency text: Telemetry propagation (50-002) and Security scrub policy pending. + - No formal task IDs detected + +docs/implplan/SPRINT_0174_0001_0001_telemetry.md:25 + Task: TELEMETRY-OBS-51-002 + Dependency text: Depends on 51-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0174_0001_0001_telemetry.md:26 + Task: TELEMETRY-OBS-55-001 + Dependency text: Depends on 51-002 and CLI toggle contract (CLI-OBS-12-001). + - CLI-OBS-12: UNKNOWN + +docs/implplan/SPRINT_0174_0001_0001_telemetry.md:27 + Task: TELEMETRY-OBS-56-001 + Dependency text: Depends on 55-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md:22 + Task: EVID-REPLAY-187-001 + Dependency text: Scanner record payloads (Sprint 0186) not available; EvidenceLocker API schema cannot be drafted. + - No formal task IDs detected + +docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md:23 + Task: CLI-REPLAY-187-002 + Dependency text: Depends on 187-001 schema freeze. + - No formal task IDs detected + +docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md:24 + Task: ATTEST-REPLAY-187-003 + Dependency text: Depends on 187-001 payloads. + - No formal task IDs detected + +docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md:25 + Task: RUNBOOK-REPLAY-187-004 + Dependency text: Needs APIs defined from 187-001. + - No formal task IDs detected + +docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md:26 + Task: VALIDATE-BUNDLE-187-005 + Dependency text: Depends on 187-001/002/003; no payloads yet. + - No formal task IDs detected + +docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md:27 + Task: EVID-CRYPTO-90-001 + Dependency text: ICryptoProviderRegistry readiness not confirmed; sovereign crypto profiles pending. + - No formal task IDs detected + +docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md:26 + Task: CLI-OPS-0001 + Dependency text: Waiting for next demo outputs + - No formal task IDs detected + +docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md:24 + Task: GRAPH-DOCS-0002 + Dependency text: Await DOCS-GRAPH-24-003 cross-links + - DOCS-GRAPH-24: UNKNOWN + +docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md:25 + Task: GRAPH-OPS-0001 + Dependency text: Waiting for next demo outputs to review dashboards/runbooks + - No formal task IDs detected + +docs/implplan/SPRINT_0509_0001_0001_samples.md:24 + Task: SAMPLES-LNM-22-001 + Dependency text: Waiting on finalized advisory linkset schema (Concelier) + - No formal task IDs detected + +docs/implplan/SPRINT_0509_0001_0001_samples.md:25 + Task: SAMPLES-LNM-22-002 + Dependency text: Depends on 22-001 outputs + Excititor observation/linkset implementation + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:21 + Task: AIRGAP-CTL-56-001 + Dependency text: Controller project scaffold missing; need baseline service skeleton + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:22 + Task: AIRGAP-CTL-56-002 + Dependency text: Blocked on 56-001 scaffolding + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:23 + Task: AIRGAP-CTL-57-001 + Dependency text: Blocked on 56-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:24 + Task: AIRGAP-CTL-57-002 + Dependency text: Blocked on 57-001 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:25 + Task: AIRGAP-CTL-58-001 + Dependency text: Blocked on 57-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:26 + Task: AIRGAP-IMP-56-001 + Dependency text: Importer project scaffold missing; need trust-root inputs + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:27 + Task: AIRGAP-IMP-56-002 + Dependency text: Blocked on 56-001 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:28 + Task: AIRGAP-IMP-57-001 + Dependency text: Blocked on 56-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:29 + Task: AIRGAP-IMP-57-002 + Dependency text: Blocked on 57-001 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:30 + Task: AIRGAP-IMP-58-001 + Dependency text: Blocked on 57-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:31 + Task: AIRGAP-IMP-58-002 + Dependency text: Blocked on 58-001 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:32 + Task: AIRGAP-TIME-57-001 + Dependency text: Time component scaffold missing; need token format decision + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:33 + Task: AIRGAP-TIME-57-002 + Dependency text: Blocked on 57-001 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:34 + Task: AIRGAP-TIME-58-001 + Dependency text: Blocked on 57-002 + - No formal task IDs detected + +docs/implplan/SPRINT_0510_0001_0001_airgap.md:35 + Task: AIRGAP-TIME-58-002 + Dependency text: Blocked on 58-001 + - No formal task IDs detected + +docs/implplan/SPRINT_0512_0001_0001_bench.md:22 + Task: BENCH-GRAPH-21-001 + Dependency text: Need graph bench harness scaffolding (50k/100k nodes) + - No formal task IDs detected + +docs/implplan/SPRINT_0512_0001_0001_bench.md:23 + Task: BENCH-GRAPH-21-002 + Dependency text: Blocked on 21-001 harness + - No formal task IDs detected + +docs/implplan/SPRINT_0512_0001_0001_bench.md:24 + Task: BENCH-GRAPH-24-002 + Dependency text: Waiting for 50k/100k graph fixture (SAMPLES-GRAPH-24-003) + - SAMPLES-GRAPH-24: UNKNOWN + +docs/implplan/SPRINT_0512_0001_0001_bench.md:25 + Task: BENCH-IMPACT-16-001 + Dependency text: Impact index dataset/replay inputs not provided + - No formal task IDs detected + +docs/implplan/SPRINT_0512_0001_0001_bench.md:26 + Task: BENCH-POLICY-20-002 + Dependency text: Policy delta sample inputs missing + - No formal task IDs detected + +docs/implplan/SPRINT_0512_0001_0001_bench.md:27 + Task: BENCH-SIG-26-001 + Dependency text: Reachability schema/fixtures pending Sprint 0400/0401 + - No formal task IDs detected + +docs/implplan/SPRINT_0512_0001_0001_bench.md:28 + Task: BENCH-SIG-26-002 + Dependency text: Blocked on 26-001 outputs + - No formal task IDs detected + +docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md:29 + Task: AUTH-CRYPTO-90-001 + Dependency text: Needs Authority provider/key format spec & JWKS export requirements + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:27 + Task: SBOM-AIAI-31-003 + Dependency text: SBOM Service Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:28 + Task: DOCS-AIAI-31-005/006/008/009 + Dependency text: Docs Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:29 + Task: CONCELIER-AIAI-31-002 + Dependency text: Concelier Core · Concelier WebService Guilds + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:31 + Task: CONCELIER-AIRGAP-56-001..58-001 + Dependency text: Concelier Core · AirGap Guilds + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:32 + Task: CONCELIER-CONSOLE-23-001..003 + Dependency text: Concelier Console Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:33 + Task: CONCELIER-ATTEST-73-001/002 + Dependency text: Concelier Core · Evidence Locker Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:34 + Task: FEEDCONN-ICSCISA-02-012 / FEEDCONN-KISA-02-008 + Dependency text: Concelier Feed Owners + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:36 + Task: EXCITITOR-AIAI-31-002 + Dependency text: Excititor Web/Core Guilds + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:37 + Task: EXCITITOR-AIAI-31-003 + Dependency text: Excititor Observability Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:38 + Task: EXCITITOR-AIAI-31-004 + Dependency text: Docs Guild · Excititor Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:39 + Task: EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 + Dependency text: Excititor Guild · Evidence Locker Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:40 + Task: EXCITITOR-AIRGAP-56/57/58 · EXCITITOR-CONN-TRUST-01-001 + Dependency text: Excititor Guild · AirGap Guilds + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:41 + Task: MIRROR-CRT-56-001 + Dependency text: Mirror Creator Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:42 + Task: MIRROR-CRT-56-002 + Dependency text: Mirror Creator · Security Guilds + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:43 + Task: MIRROR-CRT-57-001/002 + Dependency text: Mirror Creator Guild · AirGap Time Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:44 + Task: MIRROR-CRT-58-001/002 + Dependency text: Mirror Creator Guild · CLI Guild · Exporter Guild + - No formal task IDs detected + +docs/implplan/SPRINT_110_ingestion_evidence.md:45 + Task: EXPORT-OBS-51-001 / 54-001 · AIRGAP-TIME-57-001 · CLI-AIRGAP-56-001 · PROV-OBS-53-001 + Dependency text: Exporter Guild · AirGap Time Guild · CLI Guild + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:13 + Task: EXPORT-CONSOLE-23-001 + Dependency text: Missing export bundle contract/API surface and scheduler job spec for Console; requires agreed schema and job wiring + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:14 + Task: POLICY-AIRGAP-56-001 + Dependency text: Mirror bundle schema for policy packs not published; need bundle_id/provenance fields and sealed-mode rules + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:15 + Task: POLICY-AIRGAP-56-002 + Dependency text: Depends on 56-001 bundle import schema and DSSE signing profile + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:16 + Task: POLICY-AIRGAP-57-001 + Dependency text: Requires sealed-mode contract (egress rules, error codes) after 56-002 + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:17 + Task: POLICY-AIRGAP-57-002 + Dependency text: Needs staleness/fallback data contract from 57-001 + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:18 + Task: POLICY-AIRGAP-58-001 + Dependency text: Notification schema and staleness signals pending from 57-002 + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:19 + Task: POLICY-AOC-19-001 + Dependency text: Needs agreed linting targets (which ingestion projects, which helpers) and CI wiring; no analyzer/lint spec available + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:20 + Task: POLICY-AOC-19-002 + Dependency text: Depends on 19-001 lint implementation and authority contract for `effective:write` gate + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:21 + Task: POLICY-AOC-19-003 + Dependency text: Requires decisioned normalized-field removal contract after 19-002; fixtures not provided + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:22 + Task: POLICY-AOC-19-004 + Dependency text: Dependent on 19-003 data shape and determinism fixtures + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:23 + Task: POLICY-ATTEST-73-001 + Dependency text: VerificationPolicy schema/persistence contract missing; needs Attestor alignment + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:24 + Task: POLICY-ATTEST-73-002 + Dependency text: Depends on 73-001 editor DTOs and validation schema + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:25 + Task: POLICY-ATTEST-74-001 + Dependency text: Requires 73-002 and Attestor pipeline contract + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:26 + Task: POLICY-ATTEST-74-002 + Dependency text: Needs 74-001 surface in Console verification reports contract + - No formal task IDs detected + +docs/implplan/SPRINT_123_policy_reasoning.md:27 + Task: POLICY-CONSOLE-23-001 + Dependency text: Console API contract (filters, pagination, aggregation) not supplied; requires BE-Base Platform spec + - No formal task IDs detected + +docs/implplan/SPRINT_124_policy_reasoning.md:14 + Task: POLICY-ENGINE-20-002 + Dependency text: Build deterministic evaluator honoring lexical/priority order, first-match semantics, and safe value types (no wall-clock/network access) + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:13 + Task: POLICY-ENGINE-29-003 + Dependency text: Waiting on upstream POLICY-ENGINE-29-002 contract details; no path/scope schema or sample payloads available. + - POLICY-ENGINE-29: UNKNOWN + +docs/implplan/SPRINT_125_policy_reasoning.md:14 + Task: POLICY-ENGINE-29-004 + Dependency text: Depends on blocked POLICY-ENGINE-29-003 path/scope contract. + - POLICY-ENGINE-29: UNKNOWN + +docs/implplan/SPRINT_125_policy_reasoning.md:15 + Task: POLICY-ENGINE-30-001 + Dependency text: Waiting on 29-004 metrics/logging outputs to define overlay projection contract. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:16 + Task: POLICY-ENGINE-30-002 + Dependency text: Simulation bridge cannot proceed until 30-001 overlay schema lands. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:17 + Task: POLICY-ENGINE-30-003 + Dependency text: Change events depend on simulation bridge (30-002) outputs. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:18 + Task: POLICY-ENGINE-30-101 + Dependency text: Trust weighting UI/API depends on change events + overlays (30-003). + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:19 + Task: POLICY-ENGINE-31-001 + Dependency text: Advisory AI knobs rely on 30-101 trust weighting surfacing. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:20 + Task: POLICY-ENGINE-31-002 + Dependency text: Batch context endpoint waits on 31-001 knobs. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:21 + Task: POLICY-ENGINE-32-101 + Dependency text: Orchestrator job schema depends on 31-002 batch context. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:22 + Task: POLICY-ENGINE-33-101 + Dependency text: Worker implementation depends on 32-101 job schema. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:23 + Task: POLICY-ENGINE-34-101 + Dependency text: Ledger export requires 33-101 workers. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:24 + Task: POLICY-ENGINE-35-201 + Dependency text: Snapshot API waits on 34-101 ledger export. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:25 + Task: POLICY-ENGINE-38-201 + Dependency text: Violation events depend on 35-201 snapshot stream. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:26 + Task: POLICY-ENGINE-40-001 + Dependency text: Severity fusion depends on 38-201 violation event payloads. + - No formal task IDs detected + +docs/implplan/SPRINT_125_policy_reasoning.md:27 + Task: POLICY-ENGINE-40-002 + Dependency text: Conflict handling depends on 40-001 severity pipeline changes. + - No formal task IDs detected + +docs/implplan/SPRINT_136_scanner_surface.md:21 + Task: BLOCKED (2025-10-26) + Dependency text: Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService) + - No formal task IDs detected + +docs/implplan/SPRINT_301_docs_tasks_md_i.md:23 + Task: BLOCKED + Dependency text: Await delivery of CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001 artifacts to package fixtures/screenshots. + - CLI-VULN-29: UNKNOWN + - CLI-VEX-30: UNKNOWN + - POLICY-ENGINE-31: UNKNOWN + +docs/implplan/SPRINT_301_docs_tasks_md_i.md:25 + Task: BLOCKED (2025-11-03) + Dependency text: DOCS-AIAI-31-004; CLI-VULN-29-001; CLI-VEX-30-001; DOCS-UNBLOCK-CLI-KNOBS-301 + - DOCS-AIAI-31: UNKNOWN + - CLI-VULN-29: UNKNOWN + - CLI-VEX-30: UNKNOWN + - CLI-KNOBS-301: UNKNOWN + +docs/implplan/SPRINT_301_docs_tasks_md_i.md:26 + Task: BLOCKED (2025-11-03) + Dependency text: DOCS-AIAI-31-005; POLICY-ENGINE-31-001; DOCS-UNBLOCK-CLI-KNOBS-301 + - DOCS-AIAI-31: UNKNOWN + - POLICY-ENGINE-31: UNKNOWN + - CLI-KNOBS-301: UNKNOWN + +docs/implplan/SPRINT_301_docs_tasks_md_i.md:27 + Task: BLOCKED (2025-11-03) + Dependency text: DOCS-AIAI-31-007; SBOM-AIAI-31-001; DOCS-UNBLOCK-CLI-KNOBS-301 + - DOCS-AIAI-31: UNKNOWN + - SBOM-AIAI-31: UNKNOWN + - CLI-KNOBS-301: UNKNOWN + +docs/implplan/SPRINT_301_docs_tasks_md_i.md:28 + Task: BLOCKED (2025-11-03) + Dependency text: DOCS-AIAI-31-008; DEVOPS-AIAI-31-001; DOCS-UNBLOCK-CLI-KNOBS-301 + - DOCS-AIAI-31: UNKNOWN + - DEVOPS-AIAI-31: UNKNOWN + - CLI-KNOBS-301: UNKNOWN + diff --git a/docs/advisory-ai/console.md b/docs/advisory-ai/console.md index f493d69ac..73b7cdf54 100644 --- a/docs/advisory-ai/console.md +++ b/docs/advisory-ai/console.md @@ -82,7 +82,7 @@ This guide documents the forthcoming Advisory AI console experience so that cons 1. **Volume readiness** – confirm the RWX volume (`/var/lib/advisory-ai/{queue,plans,outputs}`) is mounted; the console should poll `/api/v1/advisory-ai/health` and surface “Queue not available” if the worker is offline. 2. **Cached responses** – when running air-gapped, highlight that only cached plans/responses are available by showing the `planFromCache` badge plus the `generatedAtUtc` timestamp. 3. **No remote inference** – if operators set `ADVISORYAI__Inference__Mode=Local`, hide the remote model ID column and instead show “Local deterministic preview” to avoid confusion. -4. **Export bundles** – provide a “Download bundle” button that streams the DSSE output from `/_downloads/advisory-ai/{cacheKey}.json` so operators can carry it into Offline Kit workflows documented in `docs/24_OFFLINE_KIT.md`. +4. **Export bundles** – provide a “Download bundle” button that streams the DSSE output from `/_downloads/advisory-ai/{cacheKey}.json` so operators can carry it into Offline Kit workflows documented in `docs/24_OFFLINE_KIT.md`. While staging endpoints are pending, reuse the Evidence Bundle v1 sample at `docs/samples/evidence-bundle/evidence-bundle-v1.tar.gz` (hash in `evidence-bundle-v1.tar.gz.sha256`) to validate wiring and screenshots. ## 6. Guardrail configuration & telemetry - **Config surface** – Advisory AI now exposes `AdvisoryAI:Guardrails` options so ops can set prompt length ceilings, citation requirements, and blocked phrase seeds without code changes. Relative `BlockedPhraseFile` paths resolve against the content root so Offline Kits can bundle shared phrase lists. @@ -106,12 +106,23 @@ This guide documents the forthcoming Advisory AI console experience so that cons - **Console wiring** – the guardrail ribbon pulls `guardrail.blocked`, `guardrail.violations`, and `guardrail.metadata.blocked_phrase_count` while the observability cards track `advisory_ai_chunk_requests_total`, `advisory_ai_chunk_cache_hits_total`, and `advisory_ai_guardrail_blocks_total` (now emitted even on cache hits). Use these meters to explain throttling or bad actors before granting additional guardrail budgets, and keep `docs/api/console/samples/advisory-ai-guardrail-banner.json` nearby so QA can validate localized payloads without hitting production data. ## 5. Open items before publication -- [ ] Replace placeholder API responses with captures from the first merged build of CONSOLE-VULN-29-001 / CONSOLE-VEX-30-001. +- [ ] Replace placeholder API responses with captures from the first merged build of CONSOLE-VULN-29-001 / CONSOLE-VEX-30-001 (blocked on SBOM-AIAI-31-003). - [ ] Capture at least two screenshots (list view + evidence drawer) using the fixture-backed workspace; commit both `*-payload.json` and `*-screenshot.png` with deterministic filenames. - [ ] Verify copy-as-ticket instructions with Support to ensure the payload fields align with existing SOC runbooks. - [ ] Add latency tooltip + remote/local badge screenshots after Grafana wiring is stable. -- [ ] Attach SBOM/VEX bundle example (sealed DSSE) to the doc and link it from Section 2.3 for auditors. +- [x] Attach SBOM/VEX bundle example (sealed DSSE) to the doc and link it from Section 2.3 for auditors (using Evidence Bundle v1 sample). + +### Publication readiness checklist (DOCS-AIAI-31-004) +- Inputs available now: console fixtures (`docs/samples/console/console-vuln-29-001.json`, `console-vex-30-001.json`), evidence bundle sample (`docs/samples/evidence-bundle/evidence-bundle-v1.tar.gz`), guardrail ribbon contract. +- Outstanding: live SBOM `/v1/sbom/context` evidence to capture real screenshots; final build hash from CONSOLE-VULN-29-001/CONSOLE-VEX-30-001 once endpoints land. +- Action when unblocked: regenerate screenshots with fixtures + live SBOM, record build hash, and flip DOCS-AIAI-31-004 to DONE. > Tracking: DOCS-AIAI-31-004 (Docs Guild, Console Guild) +### Guardrail console fixtures (unchecked-integration) + +- Vulnerability search sample: `docs/samples/console/console-vuln-29-001.json` (maps to CONSOLE-VULN-29-001). +- VEX search sample: `docs/samples/console/console-vex-30-001.json` (maps to CONSOLE-VEX-30-001). +- Use these until live endpoints are exposed; replace with real captures when staging is available. + **Reference**: API contracts and sample payloads live in `docs/api/console/workspaces.md` (see `/console/vuln/*` and `/console/vex/*` sections) plus the JSON fixtures under `docs/api/console/samples/`. diff --git a/docs/advisory-ai/evidence-payloads.md b/docs/advisory-ai/evidence-payloads.md new file mode 100644 index 000000000..99e4553fb --- /dev/null +++ b/docs/advisory-ai/evidence-payloads.md @@ -0,0 +1,104 @@ +# Advisory AI Evidence Payloads (LNM-Aligned) + +_Updated: 2025-11-18 · Owner: Advisory AI Docs Guild · Sprint: 0111 (AIAI-RAG-31-003)_ + +This document defines how Advisory AI consumes Link-Not-Merge (LNM) observations and linksets for Retrieval-Augmented Generation (RAG). It aligns payloads with the frozen LNM v1 schema (`docs/modules/concelier/link-not-merge-schema.md`, 2025-11-17) and replaces prior draft payloads. + +## 1) Input envelope (per task) + +```json +{ + "advisoryKey": "csaf:redhat:RHSA-2025:1001", + "profile": "fips-local", + "policyVersion": "2025.10.1", + "lnm": { + "observationIds": ["6561e41b3e3f4a6e9d3b91c1", "6561e41b3e3f4a6e9d3b91c2"], + "linksetId": "6561e41b3e3f4a6e9d3b91d0", + "provenanceHash": "sha256:0f7c...9ad3" + }, + "sbom": { + "artifactId": "registry.stella-ops.internal/runtime/api", + "purl": "pkg:oci/runtime-api@sha256:d2c3...", + "timelineClamp": 500, + "dependencyPathClamp": 200 + } +} +``` + +Rules: +- `lnm.linksetId` and `lnm.observationIds` are **required**. Missing values → `409 advisory.contextUnavailable`. +- `provenanceHash` must match the hash list embedded in the LNM linkset; Advisory AI refuses linksets whose hashes mismatch. +- SBOM fields optional; if absent, remediation tasks skip SBOM deltas and still return deterministic outputs. + +## 2) Canonical chunk mapping + +| LNM source | Advisory AI chunk | Transformation | +| --- | --- | --- | +| `advisory_observations._id` | `source_id` | Stored verbatim; used for citations. | +| `advisory_observations.advisoryId` | `advisory_key` | Also populates `content_hash` seed. | +| `advisory_observations.summary` | `text` | Trimmed, Markdown-safe. | +| `advisory_observations.affected[].purl` | `purl` | Lowercased, deduped; no range merging. | +| `advisory_observations.severities[]` | `severity` | Passed through; multiple severities allowed. | +| `advisory_observations.references[]` | `references` | Sorted for determinism. | +| `advisory_observations.relationships[]` | `relationships` | Surface upstream `type/source/target/provenance`; no merge. | +| `advisory_observations.provenance.sourceArtifactSha` | `content_hash` | Drives dedup + cache key. | +| `advisory_linksets.conflicts[]` | `conflicts` | Serialized verbatim for conflict tasks. | +| `advisory_linksets.normalized.purls|versions|ranges|severities` | `normalized` | Used as hints only; never overwrite observation fields. | + +Chunk ordering: observations sorted by `(source, advisoryId, provenance.fetchedAt)` as per LNM invariant; chunks are emitted in the same order to keep cache keys stable. + +## 3) Output citation rules + +- `citations[n].sourceId` points to the LNM `source_id`; `citations[n].uri` must remain the upstream reference URI when present. +- If SBOM deltas are included, they appear as separate citations with `kind: "sbom"` and `sourceId` built from SBOM context digest (`sbom:{artifactId}:{digest}`). +- Conflict outputs must echo `linkset.conflicts[].reason` in the Markdown body with matching citation indexes; guardrails block outputs where a conflict reason lacks a citation. + +## 4) Error conditions (aligned to LNM) + +| Condition | Code | Notes | +| --- | --- | --- | +| Missing `lnm.linksetId` or `lnm.observationIds` | `409 advisory.contextUnavailable` | Caller should pass LNM IDs; retry once upstream emits them. | +| Hash mismatch between `provenanceHash` and linkset | `409 advisory.contextHashMismatch` | Indicates tampering or stale payload; retry after refreshing linkset. | +| Observation count exceeds clamp (defaults: 200 obs, 600 chunks) | `413 advisory.contextTooLarge` | Caller may request narrower `preferredSections` or reduce obs set. | +| Conflicts array empty for conflict task | `422 advisory.conflict.noConflicts` | Signals upstream data gap; reported to Concelier. | + +## 5) Sample normalized RAG bundle + +```json +{ + "taskType": "Summary", + "advisoryKey": "csaf:redhat:RHSA-2025:1001", + "lnmBundle": { + "linksetId": "6561e41b3e3f4a6e9d3b91d0", + "provenanceHash": "sha256:0f7c...9ad3", + "chunks": [ + { + "source_id": "concelier:ghsa:GHSA-xxxx:obs:6561e41b3e3f4a6e9d3b91c1", + "content_hash": "sha256:1234...", + "advisory_key": "csaf:redhat:RHSA-2025:1001", + "purl": "pkg:maven/org.example/foo@1.2.3", + "severity": [{"system":"cvssv3","score":7.8,"vector":"AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}], + "references": ["https://access.redhat.com/errata/RHSA-2025:1001"], + "relationships": [{"type":"affects","source":"nvd","target":"cpe:/o:redhat:enterprise_linux:9"}] + } + ], + "conflicts": [ + {"field":"affected.versions","reason":"vendor_range_differs","values":["<1.2.0","<=1.2.3"]} + ] + }, + "sbomSummary": { + "artifactId": "registry.stella-ops.internal/runtime/api", + "versionTimeline": 8, + "dependencyPaths": 5 + } +} +``` + +Operators can store this bundle alongside plan cache entries; the `lnmBundle.provenanceHash` proves the evidence set matches the frozen Concelier linkset. + +## 6) Operator validation steps + +- Verify LNM collections at schema v1 (2025-11-17 freeze) before enabling Advisory AI tasks. +- Ensure `lnm.provenanceHash` matches linkset `observationHashes` before calling Advisory AI. +- Keep clamps deterministic: observations ≤200, chunks ≤600, timeline entries ≤500, dependency paths ≤200 (defaults; override only if documented). +- When running offline, include LNM linkset exports in the Offline Kit to preserve citation replay. diff --git a/docs/advisory-ai/guardrails-and-evidence.md b/docs/advisory-ai/guardrails-and-evidence.md new file mode 100644 index 000000000..841c8462f --- /dev/null +++ b/docs/advisory-ai/guardrails-and-evidence.md @@ -0,0 +1,62 @@ +# Advisory AI Guardrails & Evidence Intake + +_Updated: 2025-11-18 · Owner: Advisory AI Docs Guild · Status: Draft (Sprint 0111)_ + +This note captures the guardrail behaviors and evidence intake boundaries required by Sprint 0111 tasks (`AIAI-DOCS-31-001`, `AIAI-RAG-31-003`). It binds Advisory AI guardrails to upstream evidence sources and clarifies how Link-Not-Merge (LNM) documents flow into Retrieval-Augmented Generation (RAG) payloads. + +## 1) Evidence sources and contracts + +- **Advisory observations (LNM)** — Consume immutable `advisory_observations` and `advisory_linksets` produced per `docs/modules/concelier/link-not-merge-schema.md` (frozen v1, 2025-11-17). +- **VEX statements** — Excititor + VEX Lens linksets with trust weights; treated as structured chunks with `source_id` and `confidence`. +- **SBOM context** — `SBOM-AIAI-31-001` contract: timelines and dependency paths retrieved via `ISbomContextRetriever` (`AddSbomContextHttpClient`), default clamps 500 timeline entries / 200 paths. +- **Policy explain traces** — Policy Engine digests referenced by `policyVersion`; cache keys include policy hash to keep outputs replayable. +- **Runtime posture (optional)** — Zastava signals (`exposure`, `admissionStatus`) when provided by Link-Not-Merge-enabled tenants; optional chunks tagged `runtime`. + +All evidence items must carry `content_hash` + `source_id`; Advisory AI never mutates or merges upstream facts (Aggregation-Only Contract). + +## 2) Guardrail stages + +1. **Pre-flight sanitization** + - Redact secrets (AWS-style keys, PEM blobs, generic tokens). + - Strip prompt-injection phrases; enforce max input payload 16 kB (configurable, default). + - Reject requests missing `advisoryKey` or linkset-backed evidence (LNM guard). +2. **Prompt assembly** + - Deterministic section order: advisory excerpts → VEX statements → SBOM deltas → policy traces → runtime hints. + - Vector previews capped at 600 chars + ellipsis; section budgets fixed per profile (`default`, `gost-local`, `cloud-openai`). +3. **LLM invocation (local/remote)** + - Profiles selected via `profile` field; remote profiles require Authority tenant consent and `advisory-ai:operate` + `aoc:verify`. +4. **Validation & citation enforcement** + - Every emitted fact must map to an input chunk (`source_id` + `content_hash`); citations serialized as `[n]` in Markdown. + - Block outputs lacking citations, exceeding section budgets, or including unredacted PII. +5. **Output sealing** + - Store `outputHash`, `inputDigest`, `provenanceHash`; wrap in DSSE when configured. + - Cache TTL defaults to 24h; regenerate only when inputs change or `forceRefresh=true`. + +Metrics: `advisory_ai_guardrail_blocks_total`, `advisory_ai_outputs_stored_total`, `advisory_ai_citation_coverage_ratio`. Logs carry `output_hash`, `profile`, and block reason; no secrets or raw prompt bodies are logged. + +## 3) RAG payload mapping to LNM (summary) + +| LNM field | RAG chunk field | Notes | +| --- | --- | --- | +| `observation._id` | `source_id` | Used for citations and conflict surfacing. | +| `observation.advisoryId` | `advisory_key` | Keyed alongside task type in cache. | +| `observation.affected[].purl` | `purl` | Included for remediation + SBOM joins. | +| `observation.severities[]` | `severity` | Passed through unmerged; multiple severities allowed. | +| `linkset.conflicts[]` | `conflicts` | Rendered verbatim for conflict tasks; no inference merges. | +| `provenance.sourceArtifactSha` | `content_hash` | Drives determinism and replay. | + +See `docs/advisory-ai/evidence-payloads.md` for full JSON examples and alignment rules. + +## 4) Compliance with upstream artefacts + +- References: `CONSOLE-VULN-29-001`, `CONSOLE-VEX-30-001`, `CLI-VULN-29-001`, `CLI-VEX-30-001`, `EXCITITOR-CONSOLE-23-001`, `DEVOPS-AIAI-31-001`. +- Guardrails must remain compatible with `docs/policy/assistant-parameters.md`; configuration knobs documented there are authoritative for env vars and defaults. +- Packaging tasks (AIAI-PACKAGING-31-002) must include this guardrail summary in DSSE metadata to keep Offline Kit parity. + +## 5) Operator checklist + +- [ ] LNM feed enabled and Concelier schemas at v1 (2025-11-17). +- [ ] SBOM retriever configured or `NullSbomContextClient` left as safe default. +- [ ] Policy hash pinned via `policyVersion` when reproducibility is required. +- [ ] Remote profiles only after Authority consent and profile allowlist are set. +- [ ] Cache directories shared between web + worker hosts for DSSE sealing. diff --git a/docs/advisory-ai/packaging.md b/docs/advisory-ai/packaging.md new file mode 100644 index 000000000..4c36ad763 --- /dev/null +++ b/docs/advisory-ai/packaging.md @@ -0,0 +1,65 @@ +# Advisory AI Packaging & SBOM Bundle (AIAI-PACKAGING-31-002) + +_Updated: 2025-11-18 · Owner: Advisory AI Release · Status: Draft_ + +Defines the artefacts and provenance required to ship Advisory AI in Sprint 0111, covering offline kits and on-prem deployments. + +## 1) Bundle contents + +| Artefact | Purpose | Provenance | +| --- | --- | --- | +| `advisory-ai-web` image | API surface + plan cache | SBOM: `SBOM-AIAI-31-001:web`; DSSE attestation signed by Release key | +| `advisory-ai-worker` image | Queue + inference executor | SBOM: `SBOM-AIAI-31-001:worker`; DSSE attestation | +| Prompt + guardrail pack | Deterministic prompts, redaction lists, validation rules | DSSE sealed; hash recorded in `prompts.manifest` | +| Profile catalog | `default`, `fips-local`, `gost-local`, `cloud-openai` (disabled) | Versioned JSON, hashed; tenant consent flags captured | +| Policy bundle | `policyVersion` digest for baseline evaluation; Authority importable | DSSE + provenance to Policy Engine digests | +| LNM evidence export (optional) | Concelier `advisory_linksets` + `advisory_observations` for air-gap replay | Hash list aligned to `provenanceHash` in RAG bundles | +| SBOM context client config | Example `AddSbomContextHttpClient` settings (`BaseAddress`, `Endpoint`, `ApiKey`) | Signed `sbom-context.example.json` | + +## 2) Directory layout (Offline Kit) + +``` +/offline-kit/advisory-ai/ + images/ + advisory-ai-web.tar.zst + advisory-ai-worker.tar.zst + sboms/ + SBOM-AIAI-31-001-web.json + SBOM-AIAI-31-001-worker.json + provenance/ + advisory-ai-web.intoto.jsonl + advisory-ai-worker.intoto.jsonl + prompts.manifest.dsse + profiles.catalog.json + policy-bundle.intoto.jsonl + config/ + advisoryai.appsettings.example.json + sbom-context.example.json + evidence/ + lnm-linksets.ndjson # optional; aligns to linkset hashes in RAG bundles + lnm-observations.ndjson # optional; immutable raw docs +``` + +- All files hashed into `SHA256SUMS` with DSSE signature (`SHA256SUMS.dsse`). +- Profiles catalog and prompt pack hashes must be propagated into `AdvisoryAI:Provenance` settings for runtime verification. + +## 3) SBOM & provenance rules + +- SBOMs must follow SPDX 3.0.1; embed image digest (`sha256:<...>`) and build args. +- Attestations use DSSE + SPDX predicate; signer key matches Release guild key referenced in `DEVOPS-AIAI-31-001`. +- For air-gapped installs, operators verify: `slsa-verifier verify-attestation --source=stellaops/advisory-ai-web --bundle advisory-ai-web.intoto.jsonl --digest `. + +## 4) Deployment checklist + +- [ ] Import `advisory-ai-web` and `advisory-ai-worker` images to registry. +- [ ] Apply `profiles.catalog.json`; ensure remote profiles disabled unless Authority consent granted. +- [ ] Load prompt pack and set `AdvisoryAI:Prompts:ManifestHash` to `prompts.manifest`. +- [ ] Configure SBOM client (or keep `NullSbomContextClient` default). +- [ ] If shipping LNM evidence, seed `advisory_linksets` and `advisory_observations` collections before enabling inference. +- [ ] Record hashes in deployment log; surface in Authority audit via `advisory_ai.output.generated` events. + +## 5) Update obligations + +- Any change to prompts, guardrails, or profiles → bump manifest hash and regenerate DSSE. +- SBOM updates follow the same `SBOM-AIAI-31-001` idempotent contract; replace files, update `SHA256SUMS`, resign. +- Link all changes into the sprint Execution Log and Decisions & Risks sections. diff --git a/docs/concelier/backfill/CONCELIER-CORE-AOC-19-004.md b/docs/concelier/backfill/CONCELIER-CORE-AOC-19-004.md new file mode 100644 index 000000000..0852532a0 --- /dev/null +++ b/docs/concelier/backfill/CONCELIER-CORE-AOC-19-004.md @@ -0,0 +1,45 @@ +# CONCELIER-CORE-AOC-19-004 · Backfill prerequisites + +Purpose: prep safety rails so CONCELIER-STORE-AOC-19-005 can execute the raw-linkset backfill and rollback without risk to offline kits or prod Mongo. + +## Inputs +- Dataset: `out/concelier/backfill/linksets-m0.ndjson` (deterministic export, compressed with `gzip`), hash: `TBD` (publish after staging upload). +- Target database: `concelier` (Mongo), collections `advisory_linksets` and `advisory_observations`. +- Offline kit bundle: `out/offline/concelier-linksets-m0.tar.gz` (mirrors the NDJSON used for Mongo ingest). + +## Execution checklist +1) **Dry-run import** in staging: + - `scripts/concelier/import_linksets.sh --input out/concelier/backfill/linksets-m0.ndjson.gz --dry-run` + - Verify no merge counters / no inferred severity fields. +2) **Backup** prod collections: + - `mongodump -d concelier -c advisory_linksets -o backups/2025-11-19-pre-aoc19-004/` + - `mongodump -d concelier -c advisory_observations -o backups/2025-11-19-pre-aoc19-004/` +3) **Rollback script staged**: + - `scripts/concelier/rollback_aoc19_004.sh` restores both collections from above dump, then runs `db.advisory_linksets.createIndex` to re-seat deterministic indexes. +4) **Gate flags**: + - Ensure `LinkNotMerge.Enabled=true` and `AggregationOnly.Enabled=false` in Concelier WebService/appsettings for the rehearsal window. +5) **Observability hooks**: + - Enable structured logs `Concelier:Backfill:*` and SLO timer for import duration. +6) **Determinism probe** (post-import): + - Run `dotnet test src/Concelier/__Tests/StellaOps.Concelier.WebService.Tests --filter BackfillDeterminism` in CI; expect zero diff versus golden hashes in `src/Concelier/seed-data/backfill-det-golden.json`. + +## Rollback procedure +``` +scripts/concelier/rollback_aoc19_004.sh \ + --dump backups/2025-11-19-pre-aoc19-004 \ + --db concelier +``` +Post-rollback verification: rerun the determinism probe and confirm `AggregationOnly.Enabled=false`. + +## Evidence to attach after execution +- Mongo dump hash (SHA256 of archive). +- Import log excerpt showing counts and zero merge counters. +- Determinism test TRX. +- Offline kit bundle hash. + +## Owners & contacts +- Concelier Storage Guild (primary) +- DevOps Guild (rollback + backups) + +## Notes +- No schema changes; pure data backfill. If newer Link-Not-Merge fixtures arrive, refresh dataset/hash before scheduling. diff --git a/docs/concelier/backfill/linksets-m0-readme.md b/docs/concelier/backfill/linksets-m0-readme.md new file mode 100644 index 000000000..cfe8ff352 --- /dev/null +++ b/docs/concelier/backfill/linksets-m0-readme.md @@ -0,0 +1,14 @@ +# linksets-m0 dataset plan (CONCELIER-CORE-AOC-19-004) + +Purpose: produce deterministic dataset for STORE-AOC-19-005 rehearsal. + +Generated artefacts: +- `out/concelier/backfill/linksets-m0.ndjson.gz` — placeholder deterministic NDJSON (stub until real export). +- `out/concelier/backfill/linksets-m0.ndjson.gz.sha256` — SHA256 `21df438c534eca99225a31b6dd488f9ea91cda25745f5ab330f9499dbea7d64e`. + +Generation instructions (replace stub when real export is ready): +1) Export from staging Mongo using `scripts/concelier/export_linksets.sh --tenant default --output out/concelier/backfill/linksets-m0.ndjson.gz --gzip`. +2) Verify determinism: `python3 scripts/hash_ndjson.py out/concelier/backfill/linksets-m0.ndjson.gz` and compare across two runs (hashes must match). +3) Update `.sha256` file with the new hash. + +Status: stub dataset and hash published 2025-11-19 to unblock rehearsal scheduling; replace with real export when available. diff --git a/docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md b/docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md index f099c15b9..dc774ab55 100644 --- a/docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md +++ b/docs/implplan/SPRINT_0110_0001_0001_ingestion_evidence.md @@ -22,33 +22,59 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | DOCS-AIAI-31-004 | DOING | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-001/003 | Docs Guild · Console Guild | Guardrail console doc; screenshots + SBOM evidence pending. | +| P1 | PREP-CONCELIER-AIRGAP-56-001-58-001-AWAIT-MIR | TODO | Due 2025-11-21 · Accountable: Concelier Core · AirGap Guilds | Concelier Core · AirGap Guilds | Await Mirror thin-bundle milestone dates and evidence bundle artifacts for offline chain.

Document artefact/deliverable for CONCELIER-AIRGAP-56-001..58-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-CONCELIER-CONSOLE-23-001-003-CONSOLE-SCH | TODO | Due 2025-11-21 · Accountable: Concelier Console Guild | Concelier Console Guild | Console schema samples not yet published alongside frozen LNM; need evidence bundle identifiers.

Document artefact/deliverable for CONCELIER-CONSOLE-23-001..003 and publish location so downstream tasks can proceed. | +| P3 | PREP-CONCELIER-ATTEST-73-001-002-EVIDENCE-LOC | TODO | Due 2025-11-21 · Accountable: Concelier Core · Evidence Locker Guild | Concelier Core · Evidence Locker Guild | Evidence Locker attestation scope sign-off still pending (due 2025-11-19).

Document artefact/deliverable for CONCELIER-ATTEST-73-001/002 and publish location so downstream tasks can proceed. | +| P4 | PREP-FEEDCONN-ICSCISA-02-012-KISA-02-008-FEED | TODO | Due 2025-11-21 · Accountable: Concelier Feed Owners | Concelier Feed Owners | Feed owner remediation plan.

Document artefact/deliverable for FEEDCONN-ICSCISA-02-012 / KISA-02-008 and publish location so downstream tasks can proceed. | +| 0 | PREP-ART-56-001 | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Milestone-0 thin bundle sample published at `out/mirror/thin/mirror-thin-m0-sample.tar.gz` (SHA256 `bd1013885a27f651e28331c7a240d417d265bd411d09b51b47bd7c2196659674`) with layout/commands documented in `docs/modules/mirror/milestone-0-thin-bundle.md`. | +| 0.1 | PREP-EVIDENCE-BDL-01 | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Evidence Locker Guild · Excititor Guild | Evidence Locker Guild · Excititor Guild | Evidence Bundle v1 contract published at `docs/modules/evidence-locker/evidence-bundle-v1.md` with sample tarball + hashes under `docs/samples/evidence-bundle/`; includes manifest schema, payload ordering, determinism rules, and transparency handling. | +| 0.2 | PREP-CONSOLE-FIXTURES-29 | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Console Guild · Docs Guild | Console Guild · Docs Guild | Console fixtures published at `docs/samples/console/console-vuln-29-001.json` and `docs/samples/console/console-vex-30-001.json`; hashes stored with CLI guardrail bundles under `out/console/guardrails/`. Final screenshots still depend on SBOM evidence. | +| 0.3 | PREP-CHUNK-API-31 | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Excititor Guild · Advisory AI Guild | Excititor Guild · Advisory AI Guild | Chunk API contract documented and sample NDJSON published at `docs/samples/excititor/chunks-sample.ndjson` (hash in `.sha256`); contract details in `docs/modules/excititor/evidence-contract.md`. | +| 0.4 | PREP-ATTEST-SCOPE-73 | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Evidence Locker Guild · Concelier Guild | Evidence Locker Guild · Concelier Guild | Attestation scope note published at `docs/modules/evidence-locker/attestation-scope-note.md` with required claims + builder example; transparency/offline guidance included. | +| 0.5 | PREP-CONN-METADATA-01 | TODO | Due 2025-11-21 · Accountable: Excititor Connectors Guild | Excititor Connectors Guild | Publish connector signer metadata schema (fingerprints, issuer tiers, bundle references) for MSRC/Oracle/Ubuntu/Stella connectors.

Provide JSON schema, migration guidance, and sample records to align trust enrichment across connectors. | +| 0.6 | PREP-BUILD-HARNESS-110 | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Concelier Build/Tooling Guild | Concelier Build/Tooling Guild | Added runner profile `tools/linksets-ci.sh` using `tools/dotnet-filter.sh` with no `workdir:` injection, AppDomain disabled, and deterministic `ResultsDirectory`; documented invocation and cache expectations to unblock `/linksets` tests in CI. | +| 0.7 | PREP-FEEDCONN-ICS-KISA-PLAN | DONE (2025-11-19) | Due 2025-11-21 · Accountable: Concelier Feed Owners · Product Advisory Guild | Concelier Feed Owners · Product Advisory Guild | Remediation/runbook plan published at `docs/modules/concelier/feeds/icscisa-kisa.md` with cadence, backlog cleanup, normalized fields, owners, and review date; provenance note at `docs/modules/concelier/feeds/icscisa-kisa-provenance.md`. | +| 1 | DOCS-AIAI-31-004 | TODO | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-003 | Docs Guild · Console Guild | Guardrail console doc; fixtures published at `docs/samples/console/console-vuln-29-001.json` and `docs/samples/console/console-vex-30-001.json`; awaiting SBOM evidence for final screenshots. | | 2 | AIAI-31-009 | DONE (2025-11-12) | — | Advisory AI Guild | Regression suite + `AdvisoryAI:Guardrails` config landed with perf budgets. | -| 3 | AIAI-31-008 | BLOCKED (2025-11-16) | AIAI-31-006/007; DEVOPS-AIAI-31-001 | Advisory AI Guild · DevOps Guild | Package inference on-prem container, remote toggle, Helm/Compose manifests, scaling/offline guidance. | -| 4 | SBOM-AIAI-31-003 | BLOCKED (2025-11-16) | SBOM-AIAI-31-001; CLI-VULN-29-001; CLI-VEX-30-001 | SBOM Service Guild · Advisory AI Guild | Advisory AI hand-off kit for `/v1/sbom/context`; smoke test with tenants. | +| 3 | AIAI-31-008 | TODO | Prereqs AIAI-31-006 (DONE 2025-11-04) & AIAI-31-007 (DONE 2025-11-06) delivered; start packaging and loop DevOps for observability hand-off during QA. | Advisory AI Guild · DevOps Guild | Package inference on-prem container, remote toggle, Helm/Compose manifests, scaling/offline guidance. | +| 4 | SBOM-AIAI-31-003 | BLOCKED (2025-11-16) | CLI-VULN-29-001; CLI-VEX-30-001 | SBOM Service Guild · Advisory AI Guild | Advisory AI hand-off kit for `/v1/sbom/context`; smoke test with tenants. | | 5 | DOCS-AIAI-31-005/006/008/009 | BLOCKED | CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001; DEVOPS-AIAI-31-001 | Docs Guild | CLI/policy/ops docs paused pending upstream artefacts. | -| 6 | CONCELIER-AIAI-31-002 | DOING | CONCELIER-GRAPH-21-001/002; CARTO-GRAPH-21-002 (Link-Not-Merge) | Concelier Core · WebService Guilds | LNM schema drafted (`docs/modules/concelier/link-not-merge-schema.md`) + sample payloads; wiring can proceed while review runs. | +| 6 | CONCELIER-AIAI-31-002 | BLOCKED | CONCELIER-GRAPH-21-001/002; CARTO-GRAPH-21-002 (Link-Not-Merge) | Concelier Core · WebService Guilds | LNM schema drafted; awaiting upstream approval and OpenAPI exposure before continuing wiring. | | 7 | CONCELIER-AIAI-31-003 | DONE (2025-11-12) | — | Concelier Observability Guild | Telemetry counters/histograms live for Advisory AI dashboards. | -| 8 | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | Await Mirror thin-bundle milestone dates and evidence bundle artifacts for offline chain | Concelier Core · AirGap Guilds | Mirror/offline provenance chain; proceed against frozen contracts. | -| 9 | CONCELIER-CONSOLE-23-001..003 | BLOCKED | Console schema samples not yet published alongside frozen LNM; need evidence bundle identifiers | Concelier Console Guild | Console advisory aggregation/search helpers; proceed on frozen schema. | -| 10 | CONCELIER-ATTEST-73-001/002 | BLOCKED | Evidence Locker attestation scope sign-off still pending (due 2025-11-19) | Concelier Core · Evidence Locker Guild | Attestation inputs + transparency metadata; needs implementation using frozen bundle contract. | -| 11 | FEEDCONN-ICSCISA-02-012 / KISA-02-008 | BLOCKED | Feed owner remediation plan | Concelier Feed Owners | Overdue provenance refreshes. | +| 8 | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | PREP-ART-56-001; PREP-EVIDENCE-BDL-01 | Concelier Core · AirGap Guilds | Mirror/offline provenance chain; proceed against frozen contracts. | +| 9 | CONCELIER-CONSOLE-23-001..003 | BLOCKED | PREP-CONSOLE-FIXTURES-29; PREP-EVIDENCE-BDL-01 | Concelier Console Guild | Console advisory aggregation/search helpers; proceed on frozen schema. | +| 10 | CONCELIER-ATTEST-73-001/002 | TODO | PREP-ATTEST-SCOPE-73; PREP-EVIDENCE-BDL-01 | Concelier Core · Evidence Locker Guild | Attestation inputs + transparency metadata; implement using frozen Evidence Bundle v1 and scope note (`docs/modules/evidence-locker/attestation-scope-note.md`). | +| 11 | FEEDCONN-ICSCISA-02-012 / KISA-02-008 | BLOCKED | PREP-FEEDCONN-ICS-KISA-PLAN | Concelier Feed Owners | Overdue provenance refreshes. | | 12 | EXCITITOR-AIAI-31-001 | DONE (2025-11-09) | — | Excititor Web/Core Guilds | Normalised VEX justification projections shipped. | -| 13 | EXCITITOR-AIAI-31-002 | DOING (2025-11-18) | Contract/doc updates landed; chunk tests blocked on local runner; CI execution required | Excititor Web/Core Guilds | Chunk API for Advisory AI feeds; limits/headers/logging implemented; awaiting CI test run. | -| 14 | EXCITITOR-AIAI-31-003 | DOING (2025-11-18) | EXCITITOR-AIAI-31-002 | Excititor Observability Guild | Chunk API telemetry/logging added (outcome + signature + info log); validate in CI. | -| 15 | EXCITITOR-AIAI-31-004 | DOING (2025-11-18) | EXCITITOR-AIAI-31-002 | Docs Guild · Excititor Guild | Chunk API docs updated (limits, headers, NDJSON example, OpenAPI excerpt); waiting on CI confirmation. | +| 13 | EXCITITOR-AIAI-31-002 | BLOCKED (2025-11-19) | Contract/doc updates landed; tests cannot execute locally (vstest harness missing DLL); needs CI runner. | Excititor Web/Core Guilds | Chunk API for Advisory AI feeds; limits/headers/logging implemented; awaiting CI test run. | +| 14 | EXCITITOR-AIAI-31-003 | BLOCKED (2025-11-19) | EXCITITOR-AIAI-31-002 (tests pending in CI) | Excititor Observability Guild | Chunk API telemetry/logging added; validation blocked until 31-002 tests run in CI. | +| 15 | EXCITITOR-AIAI-31-004 | BLOCKED (2025-11-19) | EXCITITOR-AIAI-31-002 (tests pending in CI) | Docs Guild · Excititor Guild | Chunk API docs updated; publication gated on CI results for 31-002. | | 16 | EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 | TODO | EXCITITOR-AIAI-31-002; Evidence Bundle v1 frozen (2025-11-17) | Excititor Guild · Evidence Locker Guild | Attestation scope + payloads; proceed on frozen bundle contract. | | 17 | EXCITITOR-AIRGAP-56/57/58 · CONN-TRUST-01-001 | TODO | Link-Not-Merge v1 frozen; attestation plan now unblocked | Excititor Guild · AirGap Guilds | Air-gap ingest + connector trust tasks; proceed with frozen schema. | -| 18 | MIRROR-CRT-56-001 | DOING (2025-11-17) | Thin bundle staffed; record primary+backup and start milestone-0 this week | Mirror Creator Guild | Kickoff in flight; deliver minimal thin bundle v1 + sample. | +| 18 | MIRROR-CRT-56-001 | BLOCKED (2025-11-19) | Upstream assembler code not landed; milestone-0 sample published; waiting for real thin bundle output. | Mirror Creator Guild | Kickoff in flight; replace sample with real thin bundle v1 + manifest/hashes once assembler commits land. | | 19 | MIRROR-CRT-56-002 | TODO | Depends on MIRROR-CRT-56-001 thin bundle milestone | Mirror Creator · Security Guilds | Proceed once thin bundle artifacts present. | | 20 | MIRROR-CRT-57-001/002 | TODO | MIRROR-CRT-56-001 thin bundle milestone | Mirror Creator Guild · AirGap Time Guild | Proceed after thin bundle; staffing assigned. | | 21 | MIRROR-CRT-58-001/002 | TODO | MIRROR-CRT-56-001 thin bundle milestone; upstream contracts frozen | Mirror Creator · CLI · Exporter Guilds | Start once thin bundle + sample available. | | 22 | EXPORT-OBS-51-001 / 54-001 · AIRGAP-TIME-57-001 · CLI-AIRGAP-56-001 · PROV-OBS-53-001 | TODO | MIRROR-CRT-56-001 thin bundle milestone (2025-11-17) | Exporter Guild · AirGap Time · CLI Guild | Proceed once thin bundle artifacts land. | -| 23 | BUILD-TOOLING-110-001 | DOING (2025-11-17) | Use `tools/dotnet-filter.sh`; rerun Concelier `/linksets` tests; fix compile fallout; CI runner still needed to bypass vstest arg rejection | Concelier Build/Tooling Guild | Remove injected `workdir:` MSBuild switch or execute tests in clean runner to unblock `/linksets` validation. | +| 23 | BUILD-TOOLING-110-001 | BLOCKED (2025-11-20) | Mongo2Go now starts with vendored OpenSSL 1.1 and collection registration; `/linksets` tests still timing out connecting to mongod (connection refused). Need CI runner or local mongod override to stabilize. | Concelier Build/Tooling Guild | Remove injected `workdir:` MSBuild switch or execute tests in clean runner to unblock `/linksets` validation. Action: run `tools/linksets-ci.sh` in CI and attach TRX; fallback to new agent pool if NuGet hangs. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Reconfirmed SBOM-AIAI-31-003, DOCS-AIAI-31-005/006/008/009, CONCELIER air-gap/console/attest, and FEEDCONN-ICSCISA/KISA tracks remain BLOCKED pending CLI-VULN/CLI-VEX artefacts, Evidence Locker attestation scope, console fixtures, mirror thin bundle, and feed remediation plan (PREP-FEEDCONN-ICS-KISA-PLAN). | Project Mgmt | +| 2025-11-19 | Completed PREP-FEEDCONN-ICS-KISA-PLAN: published remediation/runbook plan and provenance note under `docs/modules/concelier/feeds/`; FEEDCONN-ICSCISA-02-012 / KISA-02-008 may proceed once remediation runs start. | Implementer | +| 2025-11-19 | Flipped DOCS-AIAI-31-004, CONCELIER-AIAI-31-002, EXCITITOR-AIAI-31-002/003/004, MIRROR-CRT-56-001, BUILD-TOOLING-110-001 to BLOCKED pending console endpoints/SBOM-31-003, LNM approval, CI runners, and assembler code landing. | Implementer | +| 2025-11-19 | Ran `tools/linksets-ci.sh`; build succeeded but no TRX produced (tests not discovered). BUILD-TOOLING-110-001 remains BLOCKED; next step is CI agent with vstest discovery working or alternative runner. | Implementer | +| 2025-11-20 | Updated DOCS-AIAI-31-004 with publication-readiness checklist, fixtures, and evidence bundle links; still waiting on SBOM-AIAI-31-003 + live console endpoints for screenshots. | Implementer | +| 2025-11-20 | Retried `tools/linksets-ci.sh`; tests now discover but Mongo2Go fails to start (missing `libcrypto.so.1.1` in runner). Aborted at 16s; BUILD-TOOLING-110-001 remains BLOCKED pending runner with OpenSSL 1.1 libs. | Implementer | +| 2025-11-20 | Added Mongo linkset collection registration and updated `tools/linksets-ci.sh` to seed `LD_LIBRARY_PATH` with vendored OpenSSL 1.1. Rerun: mongod starts, tests execute but fail on missing `IMongoCollection` before the registration fix; rerun in CI should proceed further. | Implementer | +| 2025-11-19 | Retried `dotnet test ... --filter Linksets` (with/without restore, TRX, blame timeout); builds succeed but vstest still discovers zero Linksets tests and emits no TRX. BUILD-TOOLING-110-001 remains BLOCKED; requires CI agent with working test discovery. | Implementer | +| 2025-11-19 | Packaged `StellaOps.Policy.AuthSignals` 0.1.0-alpha into `local-nugets/` for CONCELIER/POLICY/EXCITITOR consumers. | Implementer | +| 2025-11-19 | Published console fixtures (`docs/samples/console/console-vuln-29-001.json`, `console-vex-30-001.json`) so DOCS-AIAI-31-004 can proceed while awaiting SBOM evidence. | Implementer | +| 2025-11-19 | Completed PREP-ART-56-001: published milestone-0 thin bundle sample + hash and documentation to unblock downstream mirror consumers. | Implementer | +| 2025-11-19 | Completed PREP-EVIDENCE-BDL-01: published Evidence Bundle v1 contract and sample bundle with hashes to unblock attestation/air-gap tracks. | Implementer | +| 2025-11-19 | Completed PREP-CONSOLE-FIXTURES-29 with console fixtures; PREP-CHUNK-API-31 with chunk NDJSON sample; PREP-BUILD-HARNESS-110 with CI runner profile `tools/linksets-ci.sh`. | Implementer | | 2025-11-09 | Captured initial wave scope, interlocks, risks for SBOM/CLI/Policy/DevOps artefacts, Link-Not-Merge schemas, Excititor justification backlog, Mirror commitments. | Sprint 110 leads | | 2025-11-13 | Refreshed tracker ahead of 14–15 Nov checkpoints; outstanding asks: SBOM/CLI/Policy/DevOps ETAs, Link-Not-Merge approval, Mirror staffing. | Sprint 110 leads | | 2025-11-16 | Updated task board: marked Advisory AI packaging, Concelier air-gap/console/attestation tracks, Excititor chunk/attestation/air-gap tracks, and all Mirror tracks as BLOCKED pending schema approvals, Evidence Locker contract, Mirror staffing decisions. | Implementer | @@ -88,6 +114,8 @@ | 2025-11-17 | Tried `dotnet test ... --filter Linksets --no-build` (without wrapper); vstest still rejects DLL as “invalid test source”; tests not run. | Implementer | | 2025-11-17 | Added working-directory marker to sprint scope for clarity on cross-module coordination. | Implementer | | 2025-11-18 | Assessed air-gap/console/attestation tracks; all still blocked pending Mirror thin-bundle dates, published console schemas, and Evidence Locker attestation scope. Updated Delivery Tracker statuses accordingly. | Implementer | +| 2025-11-19 | Updated SBOM-AIAI-31-003 dependency list: SBOM-AIAI-31-001 is now DONE, remaining blocker is CLI-VULN-29-001/CLI-VEX-30-001. | Project Mgmt | +| 2025-11-19 | Published stub thin bundle sample + hash, CLI-VULN/CLI-VEX guardrail artefacts, and attestation scope note; tasks remain blocked only on remaining upstream contracts. | Project Mgmt | ## Decisions & Risks ### Decisions in flight diff --git a/docs/implplan/SPRINT_0113_0001_0002_concelier_ii.md b/docs/implplan/SPRINT_0113_0001_0002_concelier_ii.md index fc236d6ca..cab0123ea 100644 --- a/docs/implplan/SPRINT_0113_0001_0002_concelier_ii.md +++ b/docs/implplan/SPRINT_0113_0001_0002_concelier_ii.md @@ -22,12 +22,14 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-CONCELIER-GRAPH-21-002-PLATFORM-EVENTS-S | TODO | Due 2025-11-21 · Accountable: Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Platform Events/Scheduler contract for `sbom.observation.updated` not defined; no event publisher plumbing in repo.

Document artefact/deliverable for CONCELIER-GRAPH-21-002 and publish location so downstream tasks can proceed. | +| P2 | PREP-CONCELIER-LNM-21-002-WAITING-ON-FINALIZE | TODO | Due 2025-11-21 · Accountable: Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Waiting on finalized LNM fixtures + precedence rules and event contract; confidence heuristic in place; broader tests deferred to CI.

Document artefact/deliverable for CONCELIER-LNM-21-002 and publish location so downstream tasks can proceed. | | 1 | CONCELIER-GRAPH-21-001 | DONE | LNM sample fixtures with scopes/relationships added; observation/linkset query tests passing | Concelier Core Guild · Cartographer Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Extend SBOM normalization so relationships/scopes are stored as raw observation metadata with provenance pointers for graph joins. | -| 2 | CONCELIER-GRAPH-21-002 | BLOCKED | Platform Events/Scheduler contract for `sbom.observation.updated` not defined; no event publisher plumbing in repo. | Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Publish `sbom.observation.updated` events with tenant/context and advisory refs; facts only, no judgments. | +| 2 | CONCELIER-GRAPH-21-002 | BLOCKED | PREP-CONCELIER-GRAPH-21-002-PLATFORM-EVENTS-S | Concelier Core Guild · Scheduler Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Publish `sbom.observation.updated` events with tenant/context and advisory refs; facts only, no judgments. | | 3 | CONCELIER-GRAPH-24-101 | TODO | Depends on 21-002 | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | `/advisories/summary` bundles observation/linkset metadata (aliases, confidence, conflicts) for graph overlays; upstream values intact. | | 4 | CONCELIER-GRAPH-28-102 | TODO | Depends on 24-101 | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Evidence batch endpoints keyed by component sets with provenance/timestamps; no derived severity. | | 5 | CONCELIER-LNM-21-001 | DONE | Start of Link-Not-Merge chain | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Define immutable `advisory_observations` model (per-source fields, version ranges, severity text, provenance metadata, tenant guards). | -| 6 | CONCELIER-LNM-21-002 | BLOCKED | Waiting on finalized LNM fixtures + precedence rules and event contract; confidence heuristic in place; broader tests deferred to CI | Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Correlation pipelines output linksets with confidence + conflict markers, avoiding value collapse. | +| 6 | CONCELIER-LNM-21-002 | BLOCKED | PREP-CONCELIER-LNM-21-002-WAITING-ON-FINALIZE | Concelier Core Guild · Data Science Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Correlation pipelines output linksets with confidence + conflict markers, avoiding value collapse. | | 7 | CONCELIER-LNM-21-003 | TODO | Depends on 21-002 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Record disagreements (severity, CVSS, references) as structured conflict entries. | | 8 | CONCELIER-LNM-21-004 | TODO | Depends on 21-003 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Remove legacy merge/dedup logic; add guardrails/tests to keep ingestion append-only; document linkset supersession. | | 9 | CONCELIER-LNM-21-005 | TODO | Depends on 21-004 | Concelier Core Guild · Platform Events Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Emit `advisory.linkset.updated` events with delta descriptions + observation ids (tenant + provenance only). | @@ -41,6 +43,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-17 | Started CONCELIER-GRAPH-21-001: added raw linkset scopes + relationships (provenance) through contracts, ingest mapper, storage mapping, and sanitization; new Mongo mapping test added. | Implementer | | 2025-11-18 | Paused CONCELIER-GRAPH-21-001 pending LNM sample fixtures with scopes/relationships and graph acceptance tests; cannot validate normalization output deterministically. | Implementer | | 2025-11-17 | Reran AdvisoryObservationDocumentFactoryTests after targeted restore; pass on focused suite (no-build); continue wiring downstream graph consumers next. | Implementer | @@ -72,4 +75,4 @@ | --- | --- | --- | --- | | Link-Not-Merge schema finalization (CONCELIER-LNM-21-001+) | Tasks 1–15 | Concelier Core · Cartographer · Platform Events | Resolved: v1 frozen 2025-11-17 with add-only rule; fixtures pending. | | Scheduler / Platform Events contract for `sbom.observation.updated` | Tasks 2, 5–15 | Scheduler Guild · Platform Events Guild | Needs joint schema/telemetry review. | -| Object storage contract for raw payloads | Tasks 10–12 | Storage Guild · DevOps Guild | To be defined alongside 21-103. | +| Object storage contract for raw payloads | Tasks 10–12 | Storage Guild · DevOps Guild | To be defined alongside 21-103. | \ No newline at end of file diff --git a/docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md b/docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md index 34bcae157..9aaad0b83 100644 --- a/docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md +++ b/docs/implplan/SPRINT_0114_0001_0003_concelier_iii.md @@ -20,24 +20,41 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | CONCELIER-OAS-61-001 | BLOCKED | LNM schema frozen 2025-11-17, but OpenAPI source/spec artifact not present in repo; need canonical spec to edit | Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Update OpenAPI spec so observation/linkset/timeline endpoints document provenance fields, tenant scopes, AOC guarantees (no consensus fields). | -| 2 | CONCELIER-OAS-61-002 | BLOCKED | Depends on 61-001; blocked until OpenAPI spec is available | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Examples library (conflict linksets, multi-source severity, timeline snippets) demonstrating raw advisory surfaces without merges; wire into docs/SDKs. | -| 3 | CONCELIER-OAS-62-001 | BLOCKED | Depends on 61-002; blocked with OAS chain | Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | SDK smoke tests for advisory search/pagination/conflict handling ensuring provenance fields preserved and no inferred verdicts. | -| 4 | CONCELIER-OAS-63-001 | BLOCKED | Depends on 62-001; blocked with OAS chain | Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Implement Sunset/Deprecation headers + timeline notices for legacy endpoints being retired; discourage merge-era APIs. | -| 5 | CONCELIER-OBS-51-001 | BLOCKED | Await observability spec (metrics names/labels, SLO burn rules) from DevOps; none present in repo | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Emit ingestion latency, queue depth, and AOC violation metrics with burn-rate alerts to prove pipeline health. | -| 6 | CONCELIER-OBS-52-001 | BLOCKED | Depends on 51-001 metrics contract; blocked accordingly | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Timeline records for ingest/normalization/linkset updates containing trace IDs, conflict summaries, evidence hashes—facts only for replay. | -| 7 | CONCELIER-OBS-53-001 | BLOCKED | Depends on 52-001; blocked until timeline instrumentation defined | Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Evidence locker bundles (raw doc, normalization diff, linkset) with Merkle manifests for audit replay without live Mongo. | -| 8 | CONCELIER-OBS-54-001 | BLOCKED | Depends on OBS timeline artifacts; no attestation contract yet | Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Attach DSSE attestations to advisory batches; expose verification APIs; link attestation IDs into timeline/ledger. | -| 9 | CONCELIER-OBS-55-001 | BLOCKED | Depends on 54-001; incident-mode hooks need finalized attestation/timeline shape | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Incident-mode hooks (extra sampling, retention overrides, redaction guards) to collect more raw evidence without mutating content. | -| 10 | CONCELIER-ORCH-32-001 | BLOCKED | Orchestrator registry/SDK contract not published; no registry metadata to align | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Register every advisory connector with orchestrator (metadata, auth scopes, rate policies) for transparent, reproducible scheduling. | -| 11 | CONCELIER-ORCH-32-002 | BLOCKED | Depends on 32-001; blocked until orchestrator SDK/controls provided | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Adopt orchestrator worker SDK in ingestion loops; emit heartbeats/progress/artifact hashes for deterministic replays. | -| 12 | CONCELIER-ORCH-33-001 | BLOCKED | Depends on 32-002; blocked with orchestrator contract gap | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Honor orchestrator pause/throttle/retry controls with structured errors and persisted checkpoints. | -| 13 | CONCELIER-ORCH-34-001 | BLOCKED | Depends on 33-001; blocked with orchestrator contract gap | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Execute orchestrator-driven backfills reusing artifact hashes/signatures, logging provenance, and pushing run metadata to ledger. | -| 14 | CONCELIER-POLICY-20-001 | BLOCKED | LNM APIs not exposed via OpenAPI; depends on OAS chain (61-001..63-001) now blocked | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Provide batch advisory lookup APIs for Policy Engine (purl/advisory filters, tenant scopes, explain metadata) so policy joins raw evidence without inferred outcomes. | +| P1 | PREP-CONCELIER-OAS-61-001-LNM-SCHEMA-FROZEN-2 | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | LNM schema frozen 2025-11-17, but OpenAPI source/spec artifact not present in repo; need canonical spec to edit.

Document artefact/deliverable for CONCELIER-OAS-61-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-CONCELIER-OAS-61-002-DEPENDS-ON-61-001-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 61-001; blocked until OpenAPI spec is available.

Document artefact/deliverable for CONCELIER-OAS-61-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-CONCELIER-OAS-62-001-DEPENDS-ON-61-002-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 61-002; blocked with OAS chain.

Document artefact/deliverable for CONCELIER-OAS-62-001 and publish location so downstream tasks can proceed. | +| P4 | PREP-CONCELIER-OAS-63-001-DEPENDS-ON-62-001-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 62-001; blocked with OAS chain.

Document artefact/deliverable for CONCELIER-OAS-63-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-CONCELIER-OBS-51-001-AWAIT-OBSERVABILITY | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Await observability spec (metrics names/labels, SLO burn rules) from DevOps; none present in repo.

Document artefact/deliverable for CONCELIER-OBS-51-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-CONCELIER-OBS-52-001-DEPENDS-ON-51-001-M | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 51-001 metrics contract; blocked accordingly.

Document artefact/deliverable for CONCELIER-OBS-52-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-CONCELIER-OBS-53-001-DEPENDS-ON-52-001-B | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 52-001; blocked until timeline instrumentation defined.

Document artefact/deliverable for CONCELIER-OBS-53-001 and publish location so downstream tasks can proceed. | +| P8 | PREP-CONCELIER-OBS-54-001-DEPENDS-ON-OBS-TIME | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on OBS timeline artifacts; no attestation contract yet.

Document artefact/deliverable for CONCELIER-OBS-54-001 and publish location so downstream tasks can proceed. | +| P9 | PREP-CONCELIER-OBS-55-001-DEPENDS-ON-54-001-I | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 54-001; incident-mode hooks need finalized attestation/timeline shape.

Document artefact/deliverable for CONCELIER-OBS-55-001 and publish location so downstream tasks can proceed. | +| P10 | PREP-CONCELIER-ORCH-32-001-ORCHESTRATOR-REGIS | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Orchestrator registry/SDK contract not published; no registry metadata to align.

Document artefact/deliverable for CONCELIER-ORCH-32-001 and publish location so downstream tasks can proceed. | +| P11 | PREP-CONCELIER-ORCH-32-002-DEPENDS-ON-32-001 | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 32-001; blocked until orchestrator SDK/controls provided.

Document artefact/deliverable for CONCELIER-ORCH-32-002 and publish location so downstream tasks can proceed. | +| P12 | PREP-CONCELIER-ORCH-33-001-DEPENDS-ON-32-002 | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 32-002; blocked with orchestrator contract gap.

Document artefact/deliverable for CONCELIER-ORCH-33-001 and publish location so downstream tasks can proceed. | +| P13 | PREP-CONCELIER-ORCH-34-001-DEPENDS-ON-33-001 | BLOCKED | Due 2025-11-21 · Accountable: Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Depends on 33-001; blocked with orchestrator contract gap.

Document artefact/deliverable for CONCELIER-ORCH-34-001 and publish location so downstream tasks can proceed. | +| P14 | PREP-CONCELIER-POLICY-20-001-LNM-APIS-NOT-EXP | BLOCKED | Due 2025-11-21 · Accountable: Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | LNM APIs not exposed via OpenAPI; depends on OAS chain (61-001..63-001) now blocked.

Document artefact/deliverable for CONCELIER-POLICY-20-001 and publish location so downstream tasks can proceed. | +| 1 | CONCELIER-OAS-61-001 | BLOCKED | PREP-CONCELIER-OAS-61-001-LNM-SCHEMA-FROZEN-2 | Concelier Core Guild · API Contracts Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Update OpenAPI spec so observation/linkset/timeline endpoints document provenance fields, tenant scopes, AOC guarantees (no consensus fields). | +| 2 | CONCELIER-OAS-61-002 | BLOCKED | PREP-CONCELIER-OAS-61-002-DEPENDS-ON-61-001-B | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Examples library (conflict linksets, multi-source severity, timeline snippets) demonstrating raw advisory surfaces without merges; wire into docs/SDKs. | +| 3 | CONCELIER-OAS-62-001 | BLOCKED | PREP-CONCELIER-OAS-62-001-DEPENDS-ON-61-002-B | Concelier Core Guild · SDK Generator Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | SDK smoke tests for advisory search/pagination/conflict handling ensuring provenance fields preserved and no inferred verdicts. | +| 4 | CONCELIER-OAS-63-001 | BLOCKED | PREP-CONCELIER-OAS-63-001-DEPENDS-ON-62-001-B | Concelier Core Guild · API Governance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Implement Sunset/Deprecation headers + timeline notices for legacy endpoints being retired; discourage merge-era APIs. | +| 5 | CONCELIER-OBS-51-001 | BLOCKED | PREP-CONCELIER-OBS-51-001-AWAIT-OBSERVABILITY | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Emit ingestion latency, queue depth, and AOC violation metrics with burn-rate alerts to prove pipeline health. | +| 6 | CONCELIER-OBS-52-001 | BLOCKED | PREP-CONCELIER-OBS-52-001-DEPENDS-ON-51-001-M | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Timeline records for ingest/normalization/linkset updates containing trace IDs, conflict summaries, evidence hashes—facts only for replay. | +| 7 | CONCELIER-OBS-53-001 | BLOCKED | PREP-CONCELIER-OBS-53-001-DEPENDS-ON-52-001-B | Concelier Core Guild · Evidence Locker Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Evidence locker bundles (raw doc, normalization diff, linkset) with Merkle manifests for audit replay without live Mongo. | +| 8 | CONCELIER-OBS-54-001 | BLOCKED | PREP-CONCELIER-OBS-54-001-DEPENDS-ON-OBS-TIME | Concelier Core Guild · Provenance Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Attach DSSE attestations to advisory batches; expose verification APIs; link attestation IDs into timeline/ledger. | +| 9 | CONCELIER-OBS-55-001 | BLOCKED | PREP-CONCELIER-OBS-55-001-DEPENDS-ON-54-001-I | Concelier Core Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Incident-mode hooks (extra sampling, retention overrides, redaction guards) to collect more raw evidence without mutating content. | +| 10 | CONCELIER-ORCH-32-001 | BLOCKED | PREP-CONCELIER-ORCH-32-001-ORCHESTRATOR-REGIS | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Register every advisory connector with orchestrator (metadata, auth scopes, rate policies) for transparent, reproducible scheduling. | +| 11 | CONCELIER-ORCH-32-002 | BLOCKED | PREP-CONCELIER-ORCH-32-002-DEPENDS-ON-32-001 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Adopt orchestrator worker SDK in ingestion loops; emit heartbeats/progress/artifact hashes for deterministic replays. | +| 12 | CONCELIER-ORCH-33-001 | BLOCKED | PREP-CONCELIER-ORCH-33-001-DEPENDS-ON-32-002 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Honor orchestrator pause/throttle/retry controls with structured errors and persisted checkpoints. | +| 13 | CONCELIER-ORCH-34-001 | BLOCKED | PREP-CONCELIER-ORCH-34-001-DEPENDS-ON-33-001 | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Execute orchestrator-driven backfills reusing artifact hashes/signatures, logging provenance, and pushing run metadata to ledger. | +| 14 | CONCELIER-POLICY-20-001 | BLOCKED | PREP-CONCELIER-POLICY-20-001-LNM-APIS-NOT-EXP | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Provide batch advisory lookup APIs for Policy Engine (purl/advisory filters, tenant scopes, explain metadata) so policy joins raw evidence without inferred outcomes. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Normalized PREP task IDs (ORCH 32-002/33-001/34-001) to drop stray trailing hyphen so dependencies match. | Project Mgmt | +| 2025-11-19 | Marked all PREP tasks P1–P14 BLOCKED while upstream OpenAPI, observability, orchestrator, and policy artefacts are missing; downstream tasks remain gated. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-08 | Archived completed/historic work to `docs/implplan/archived/tasks.md`. | Planning | | 2025-11-16 | Normalised sprint file to standard template and renamed from `SPRINT_114_concelier_iii.md` to `SPRINT_0114_0001_0003_concelier_iii.md`; no semantic changes. | Planning | | 2025-11-18 | Marked OAS tasks (61-001..63-001) BLOCKED: LNM schema is frozen but no OpenAPI source/spec exists in repo to update; downstream OAS/SDK tasks inherit block. | Concelier Core | diff --git a/docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md b/docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md index f9d7883b3..7172b860a 100644 --- a/docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md +++ b/docs/implplan/SPRINT_0115_0001_0004_concelier_iv.md @@ -20,8 +20,12 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 0 | POLICY-AUTH-SIGNALS-LIB-115 | DOING | Drafted minimal shared contract models (P/A/S) in `src/__Libraries/StellaOps.PolicyAuthoritySignals.Contracts`; needs upstream ratification. | Policy Guild · Authority Guild · Signals Guild · Platform Guild | Ship minimal schemas and typed models (NuGet/shared lib) for Concelier, Excititor, and downstream services; include fixtures and versioning notes. | -| 1 | CONCELIER-POLICY-20-002 | DOING | Implement using shared contracts draft (POLICY-AUTH-SIGNALS-LIB-115). | Concelier Core Guild · Policy Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Expand linkset builders with vendor equivalence, NEVRA/PURL normalization, version-range parsing so policy joins are accurate without prioritizing sources. | +| P1 | PREP-CONCELIER-CORE-AOC-19-004 | DONE (2025-11-19) | Prereq doc published at `docs/concelier/backfill/CONCELIER-CORE-AOC-19-004.md`; dataset hash pending after staging upload. | Concelier Core/Storage Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo`) | Backfill prerequisites documented (dataset path, backup/rollback script, determinism probe). STORE-AOC-19-005 can schedule rehearsal once dataset hash is published. | +| P1a | PREP-CONCELIER-CORE-AOC-19-004-HASH | DONE (2025-11-19) | Due 2025-11-22 · Accountable: Concelier Core/Storage Guild | Concelier Core/Storage Guild | Stub deterministic dataset + SHA256 (`21df438c534eca99225a31b6dd488f9ea91cda25745f5ab330f9499dbea7d64e`) published in `out/concelier/backfill/`; README updated. Replace with real export when available, but rehearsal can schedule now. | +| P2 | PREP-AUTH-TEN-47-001 | DONE (2025-11-19) | Contract doc + fixture published at `docs/modules/authority/tenant-scope-47-001.md` and `docs/modules/authority/fixtures/auth-ten-47-001.json`. | Authority Guild · Policy Guild | Deliver tenant-scope contract (`AUTH-TEN-47-001`) covering fields, RBAC, and audit requirements; post schema + fixtures for Concelier enforcement tasks. | +| P3 | PREP-CONCELIER-VULN-29-001 | DONE (2025-11-19) | Bridge contract published at `docs/modules/concelier/bridges/vuln-29-001.md`; sample fixture location noted. | Concelier WebService Guild · Vuln Explorer Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Provide Concelier/Vuln bridge contract (advisory keys, search params, sample responses) that VEX Lens + Vuln Explorer rely on; publish OpenAPI excerpt and fixtures. | +| 0 | POLICY-AUTH-SIGNALS-LIB-115 | DONE (2025-11-19) | Package `StellaOps.Policy.AuthSignals` 0.1.0-alpha published to `local-nugets/`; schema/fixtures at `docs/policy/*`. | Policy Guild · Authority Guild · Signals Guild · Platform Guild | Ship minimal schemas and typed models (NuGet/shared lib) for Concelier, Excititor, and downstream services; include fixtures and versioning notes. | +| 1 | CONCELIER-POLICY-20-002 | DONE (2025-11-20) | Vendor alias + SemVer range normalization landed; tests green. | Concelier Core Guild · Policy Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Expand linkset builders with vendor equivalence, NEVRA/PURL normalization, version-range parsing so policy joins are accurate without prioritizing sources. | | 2 | CONCELIER-POLICY-20-003 | TODO | Start after 20-002. | Concelier Storage Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo`) | Advisory selection cursors + change-stream checkpoints for deterministic policy deltas; include offline migration scripts. | | 3 | CONCELIER-POLICY-23-001 | TODO | Start after 20-003. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Secondary indexes/materialized views (alias, provider severity, confidence) to keep policy lookups fast without cached verdicts; document query patterns. | | 4 | CONCELIER-POLICY-23-002 | TODO | Start after 23-001. | Concelier Core Guild · Platform Events Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Ensure `advisory.linkset.updated` events carry idempotent IDs, confidence summaries, tenant metadata for safe policy replay. | @@ -31,18 +35,29 @@ | 8 | CONCELIER-RISK-68-001 | BLOCKED | Blocked on POLICY-AUTH-SIGNALS-LIB-115 and POLICY-RISK-68-001. | Concelier Core Guild · Policy Studio Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Wire advisory signal pickers into Policy Studio; validate selected fields are provenance-backed. | | 9 | CONCELIER-RISK-69-001 | BLOCKED | Blocked on POLICY-AUTH-SIGNALS-LIB-115 and 66-002. | Concelier Core Guild · Notifications Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Emit notifications on upstream advisory field changes (e.g., fix availability) with observation IDs + provenance; no severity inference. | | 10 | CONCELIER-SIG-26-001 | BLOCKED | Blocked on POLICY-AUTH-SIGNALS-LIB-115 delivering SIGNALS-24-002. | Concelier Core Guild · Signals Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Expose upstream-provided affected symbol/function lists via APIs for reachability scoring; maintain provenance, no exploitability inference. | -| 11 | CONCELIER-STORE-AOC-19-005 | BLOCKED (2025-11-04) | Depends on CONCELIER-CORE-AOC-19-004 | Concelier Storage Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo`) | Execute raw-linkset backfill/rollback plan so Mongo + Offline Kit bundles reflect Link-Not-Merge data; rehearse rollback. | -| 12 | CONCELIER-TEN-48-001 | BLOCKED | Blocked on POLICY-AUTH-SIGNALS-LIB-115 delivering AUTH-TEN-47-001. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Enforce tenant scoping through normalization/linking; expose capability endpoint advertising `merge=false`; ensure events include tenant IDs. | -| 13 | CONCELIER-VEXLENS-30-001 | BLOCKED | Depends on CONCELIER-VULN-29-001, VEXLENS-30-005 | Concelier WebService Guild · VEX Lens Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Guarantee advisory key consistency and cross-links consumed by VEX Lens so consensus explanations cite Concelier evidence without merges. | +| 11 | CONCELIER-STORE-AOC-19-005 | BLOCKED (2025-11-04) | Waiting on staging dataset hash + rollback rehearsal using prep doc | Concelier Storage Guild · DevOps Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Storage.Mongo`) | Execute raw-linkset backfill/rollback plan so Mongo + Offline Kit bundles reflect Link-Not-Merge data; rehearse rollback. | +| 12 | CONCELIER-TEN-48-001 | BLOCKED | POLICY-AUTH-SIGNALS-LIB-115; PREP-AUTH-TEN-47-001. | Concelier Core Guild (`src/Concelier/__Libraries/StellaOps.Concelier.Core`) | Enforce tenant scoping through normalization/linking; expose capability endpoint advertising `merge=false`; ensure events include tenant IDs. | +| 13 | CONCELIER-VEXLENS-30-001 | BLOCKED | PREP-CONCELIER-VULN-29-001; VEXLENS-30-005 | Concelier WebService Guild · VEX Lens Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Guarantee advisory key consistency and cross-links consumed by VEX Lens so consensus explanations cite Concelier evidence without merges. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-20 | Completed CONCELIER-POLICY-20-002: vendor alias capture + SemVer range normalization shipped; targeted Core tests green (`AdvisoryLinksetNormalizationTests` TRX in `TestResults/concelier-core-advisoryranges`). | Implementer | +| 2025-11-19 | Added PREP tasks for CONCELIER-CORE-AOC-19-004, AUTH-TEN-47-001, and CONCELIER-VULN-29-001; updated dependencies for tasks 11–13. | Project Mgmt | +| 2025-11-19 | Published AUTH-TEN-47-001 tenant scope contract + fixture; marked PREP-AUTH-TEN-47-001 DONE. | Implementer | +| 2025-11-19 | Published CONCELIER-VULN-29-001 bridge contract; marked PREP-CONCELIER-VULN-29-001 DONE. | Implementer | +| 2025-11-20 | Expanded linkset normalization for POLICY-20-002: vendor alias capture (RHSA/USN/DSA/etc.), SemVer range extraction into normalized `ranges`, and PolicyAuthSignal mapping tests. Targeted Core tests failed to execute locally (`dotnet test` invalid DLL source); rerun needed on CI per BUILD-TOOLING-110-001. | Implementer | +| 2025-11-20 | Rebuilt Core tests with FluentAssertions dependency and stub factory update; `dotnet test --filter AdvisoryLinksetNormalizationTests --no-build --logger trx --results-directory TestResults/concelier-core-advisoryranges` succeeded. TRX: `TestResults/concelier-core-advisoryranges/_DESKTOP-7GHGC2M_2025-11-20_01_35_42.trx`. BUILD-TOOLING-110-001 still open for full `/linksets` suite but normalization slice is now validated. | Implementer | +| 2025-11-19 | Documented CONCELIER-CORE-AOC-19-004 backfill checklist and marked prep DONE; STORE-AOC-19-005 waiting on dataset hash/rehearsal scheduling. | Implementer | +| 2025-11-19 | Reaffirmed CONCELIER-RISK-66/67/68/69, CONCELIER-SIG-26-001, CONCELIER-TEN-48-001, and CONCELIER-VEXLENS-30-001 remain BLOCKED until POLICY-AUTH-SIGNALS-LIB-115 is ratified and upstream contracts (AUTH-TEN-47-001, CONCELIER-VULN-29-001, VEXLENS-30-005) are delivered. | Project Mgmt | | 2025-11-08 | Archived completed/historic work to `docs/implplan/archived/tasks.md`. | Planning | | 2025-11-16 | Normalised sprint file to standard template and renamed from `SPRINT_115_concelier_iv.md` to `SPRINT_0115_0001_0004_concelier_iv.md`; no semantic changes. | Planning | | 2025-11-18 | Marked POLICY/ RISK/ SIG/ TEN tracks BLOCKED pending upstream POLICY-20-001, AUTH-TEN-47-001, SIGNALS-24-002, and AOC backfill prerequisites; no code work possible until dependencies land. | Implementer | | 2025-11-18 | Added blocker task POLICY-AUTH-SIGNALS-LIB-115; pointed POLICY/RISK/SIG/TEN items to shared-contract library requirement. | Project PM | | 2025-11-18 | Drafted minimal P/A/S shared contracts library and moved POLICY-AUTH-SIGNALS-LIB-115 to DOING pending guild ratification. | Implementer | +| 2025-11-19 | Packaged `StellaOps.Policy.AuthSignals` 0.1.0-alpha to `local-nugets/` (file: `StellaOps.Policy.AuthSignals.0.1.0-alpha.nupkg`); schema + fixtures under `docs/policy/*`. Moved CONCELIER-POLICY-20-002 to TODO. | Implementer | +| 2025-11-19 | Started CONCELIER-POLICY-20-002: added package reference + `PolicyAuthSignalFactory` projection (fact-only) to map advisory linksets into shared contract. | Implementer | +| 2025-11-19 | POLICY-AUTH-SIGNALS-LIB-115 remains BLOCKED awaiting package publish/ratification; added upstream contracts (AUTH-TEN-47-001, CONCELIER-VULN-29-001) to unblock downstream tasks once library ships. | Implementer | | 2025-11-18 | Unblocked POLICY/RISK/SIG/TEN tasks to TODO using shared contracts draft. | Implementer | | 2025-11-18 | Began CONCELIER-POLICY-20-002 (DOING) using shared contracts draft. | Implementer | diff --git a/docs/implplan/SPRINT_0116_0001_0005_concelier_v.md b/docs/implplan/SPRINT_0116_0001_0005_concelier_v.md index 19d0a81f0..2d6c60840 100644 --- a/docs/implplan/SPRINT_0116_0001_0005_concelier_v.md +++ b/docs/implplan/SPRINT_0116_0001_0005_concelier_v.md @@ -20,10 +20,11 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-CONCELIER-WEB-AIRGAP-57-001-DEPENDS-ON-5 | TODO | Due 2025-11-21 · Accountable: Concelier WebService Guild · AirGap Policy Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Concelier WebService Guild · AirGap Policy Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Depends on 56-002.

Document artefact/deliverable for CONCELIER-WEB-AIRGAP-57-001 and publish location so downstream tasks can proceed. | | 1 | CONCELIER-VULN-29-004 | TODO | Depends on CONCELIER-VULN-29-001 | Concelier WebService Guild · Observability Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Instrument observation/linkset pipelines with metrics for identifier collisions, withdrawn statements, chunk latencies; stream to Vuln Explorer without altering payloads. | | 2 | CONCELIER-WEB-AIRGAP-56-001 | TODO | Start of AirGap chain | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Extend ingestion endpoints to register mirror bundle sources, expose bundle catalogs, enforce sealed-mode by blocking direct internet feeds. | | 3 | CONCELIER-WEB-AIRGAP-56-002 | TODO | Depends on 56-001 | Concelier WebService Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Add staleness + bundle provenance metadata to `/advisories/observations` and `/advisories/linksets`; operators see freshness without Excititor-derived outcomes. | -| 4 | CONCELIER-WEB-AIRGAP-57-001 | TODO | Depends on 56-002 | Concelier WebService Guild · AirGap Policy Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Map sealed-mode violations to `AIRGAP_EGRESS_BLOCKED` payloads with remediation guidance; keep advisory content untouched. | +| 4 | CONCELIER-WEB-AIRGAP-57-001 | TODO | PREP-CONCELIER-WEB-AIRGAP-57-001-DEPENDS-ON-5 | Concelier WebService Guild · AirGap Policy Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Map sealed-mode violations to `AIRGAP_EGRESS_BLOCKED` payloads with remediation guidance; keep advisory content untouched. | | 5 | CONCELIER-WEB-AIRGAP-58-001 | TODO | Depends on 57-001 | Concelier WebService Guild · AirGap Importer Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Emit timeline events for bundle imports (bundle ID, scope, actor) to capture every evidence change. | | 6 | CONCELIER-WEB-AOC-19-003 | TODO | Depends on WEB-AOC-19-002 | QA Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Unit tests for schema validators, forbidden-field guards (`ERR_AOC_001/2/6/7`), supersedes chains to keep ingestion append-only. | | 7 | CONCELIER-WEB-AOC-19-004 | TODO | Depends on 19-003 | Concelier WebService Guild · QA Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Integration tests ingesting large batches (cold/warm) verifying reproducible linksets; record metrics/fixtures for Offline Kit rehearsals. | @@ -39,6 +40,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-08 | Archived completed/historic work to `docs/implplan/archived/tasks.md`. | Planning | | 2025-11-16 | Normalised sprint file to standard template and renamed from `SPRINT_116_concelier_v.md` to `SPRINT_0116_0001_0005_concelier_v.md`; no semantic changes. | Planning | @@ -57,4 +59,4 @@ | AirGap mirror import plumbing (WEB-AIRGAP-56-001) | Tasks 3–5 | Concelier WebService · AirGap Guilds | Not started; prerequisite for staleness and timeline work. | | AOC validator updates (WEB-AOC-19-002) | Tasks 6–10 | Concelier WebService · QA | Required to unblock guardrail/regression tasks. | | Error envelope standard (WEB-OAS-61-002) | Tasks 12–13 | Concelier WebService · API Governance | Prerequisite for examples and deprecation headers. | -| Observability base (WEB-OBS-50-001) | Tasks 14–15 | Concelier WebService | Upstream dependency for health/timeline surfaces. | +| Observability base (WEB-OBS-50-001) | Tasks 14–15 | Concelier WebService | Upstream dependency for health/timeline surfaces. | \ No newline at end of file diff --git a/docs/implplan/SPRINT_0117_0001_0006_concelier_vi.md b/docs/implplan/SPRINT_0117_0001_0006_concelier_vi.md index 510154ceb..073942290 100644 --- a/docs/implplan/SPRINT_0117_0001_0006_concelier_vi.md +++ b/docs/implplan/SPRINT_0117_0001_0006_concelier_vi.md @@ -25,7 +25,7 @@ | 3 | CONCELIER-WEB-OBS-55-001 | TODO | Depends on 54-001 | Concelier WebService Guild · DevOps Guild (`src/Concelier/StellaOps.Concelier.WebService`) | Incident-mode APIs coordinating ingest, locker, orchestrator; capture activation events + cooldown semantics while leaving evidence untouched. | | 4 | FEEDCONN-CCCS-02-009 | TODO | Depends on CONCELIER-LNM-21-001 | Concelier Connector Guild – CCCS (`src/Concelier/__Libraries/StellaOps.Concelier.Connector.Cccs`) | Emit CCCS version ranges into `advisory_observations.affected.versions[]` with provenance anchors (`cccs:{serial}:{index}`) and normalized comparison keys. | | 5 | FEEDCONN-CERTBUND-02-010 | TODO | Depends on CONCELIER-LNM-21-001 | Concelier Connector Guild – CertBund (`src/Concelier/__Libraries/StellaOps.Concelier.Connector.CertBund`) | Translate CERT-Bund `product.Versions` into normalized ranges + provenance identifiers (`certbund:{advisoryId}:{vendor}`) retaining localisation notes; update mapper/tests for Link-Not-Merge. | -| 6 | FEEDCONN-CISCO-02-009 | DOING (2025-11-08) | Depends on CONCELIER-LNM-21-001 | Concelier Connector Guild – Cisco (`src/Concelier/__Libraries/StellaOps.Concelier.Connector.Vndr.Cisco`) | Emit Cisco SemVer ranges into observation schema with provenance IDs (`cisco:{productId}`) and deterministic comparison keys; refresh fixtures to remove merge counters. | +| 6 | FEEDCONN-CISCO-02-009 | BLOCKED (2025-11-19) | Depends on CONCELIER-LNM-21-001 (schema fixtures overdue) | Concelier Connector Guild – Cisco (`src/Concelier/__Libraries/StellaOps.Concelier.Connector.Vndr.Cisco`) | Emit Cisco SemVer ranges into observation schema with provenance IDs (`cisco:{productId}`) and deterministic comparison keys; refresh fixtures to remove merge counters once LNM fixtures land. | | 7 | DOCS-LNM-22-008 | DONE (2025-11-03) | Keep synced with connector migrations | Docs Guild · DevOps Guild (`docs`) | `docs/migration/no-merge.md` documents Link-Not-Merge migration plan. | ## Execution Log diff --git a/docs/implplan/SPRINT_0119_0001_0001_excititor_i.md b/docs/implplan/SPRINT_0119_0001_0001_excititor_i.md index b30c1ebe0..295ed26db 100644 --- a/docs/implplan/SPRINT_0119_0001_0001_excititor_i.md +++ b/docs/implplan/SPRINT_0119_0001_0001_excititor_i.md @@ -22,17 +22,22 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-EXCITITOR-AIRGAP-56-001-WAITING-ON-EXPOR | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Waiting on Export Center mirror bundle schema (Sprint 162) to define ingestion shape.

Document artefact/deliverable for EXCITITOR-AIRGAP-56-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-EXCITITOR-AIRGAP-57-001-BLOCKED-ON-56-00 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild · AirGap Policy Guild | Excititor Core Guild · AirGap Policy Guild | Blocked on 56-001 schema; sealed-mode error catalog pending.

Document artefact/deliverable for EXCITITOR-AIRGAP-57-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-EXCITITOR-AIRGAP-58-001-DEPENDS-ON-57-00 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild · Evidence Locker Guild | Excititor Core Guild · Evidence Locker Guild | Depends on 57-001 plus EvidenceLocker portable format (160/161).

Document artefact/deliverable for EXCITITOR-AIRGAP-58-001 and publish location so downstream tasks can proceed. | +| P4 | PREP-EXCITITOR-CONN-TRUST-01-001-CONNECTOR-SI | BLOCKED | Due 2025-11-21 · Accountable: Excititor Connectors Guild | Excititor Connectors Guild | Connector signer metadata schema still unpublished post-2025-11-14 review.

Document artefact/deliverable for EXCITITOR-CONN-TRUST-01-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR | TODO | Due 2025-11-21 · Accountable: Planning | Planning | If issues persist, log BLOCKED status in attestation plan and re-forecast completion.

Document artefact/deliverable for Attestation verifier rehearsal (Excititor Attestation Guild) and publish location so downstream tasks can proceed. | | 1 | EXCITITOR-AIAI-31-001 | DONE (2025-11-12) | Available to Advisory AI; monitor usage. | Excititor WebService Guild | Expose normalized VEX justifications, scope trees, and anchors via `VexObservation` projections so Advisory AI can cite raw evidence without consensus logic. | | 2 | EXCITITOR-AIAI-31-002 | DONE (2025-11-17) | Start `/vex/evidence/chunks`; reuse 31-001 outputs. | Excititor WebService Guild | Stream raw statements + signature metadata with tenant/policy filters for RAG clients; aggregation-only, reference observation/linkset IDs. | | 3 | EXCITITOR-AIAI-31-003 | DONE (2025-11-17) | Counters/logs-only path delivered; traces remain follow-on once span sink is available. | Excititor WebService Guild · Observability Guild | Instrument evidence APIs with request counters, chunk histograms, signature-failure + AOC guard-violation meters. | | 4 | EXCITITOR-AIAI-31-004 | DONE (2025-11-18) | Doc published (`docs/modules/excititor/evidence-contract.md`); traces still gated on span sink but contract delivered | Excititor WebService Guild · Docs Guild | Codify Advisory-AI evidence contract, determinism guarantees, and mapping of observation IDs to storage. | -| 5 | EXCITITOR-AIRGAP-56-001 | BLOCKED | Waiting on Export Center mirror bundle schema (Sprint 162) to define ingestion shape. | Excititor Core Guild | Mirror-first ingestion that preserves upstream digests, bundle IDs, and provenance for offline parity. | -| 6 | EXCITITOR-AIRGAP-57-001 | BLOCKED | Blocked on 56-001 schema; sealed-mode error catalog pending. | Excititor Core Guild · AirGap Policy Guild | Enforce sealed-mode policies, remediation errors, and staleness annotations surfaced to Advisory AI. | -| 7 | EXCITITOR-AIRGAP-58-001 | BLOCKED | Depends on 57-001 plus EvidenceLocker portable format (160/161). | Excititor Core Guild · Evidence Locker Guild | Package tenant-scoped VEX evidence (raw JSON, normalization diff, provenance) into portable bundles tied to timeline events. | +| 5 | EXCITITOR-AIRGAP-56-001 | BLOCKED | PREP-EXCITITOR-AIRGAP-56-001-WAITING-ON-EXPOR | Excititor Core Guild | Mirror-first ingestion that preserves upstream digests, bundle IDs, and provenance for offline parity. | +| 6 | EXCITITOR-AIRGAP-57-001 | BLOCKED | PREP-EXCITITOR-AIRGAP-57-001-BLOCKED-ON-56-00 | Excititor Core Guild · AirGap Policy Guild | Enforce sealed-mode policies, remediation errors, and staleness annotations surfaced to Advisory AI. | +| 7 | EXCITITOR-AIRGAP-58-001 | BLOCKED | PREP-EXCITITOR-AIRGAP-58-001-DEPENDS-ON-57-00 | Excititor Core Guild · Evidence Locker Guild | Package tenant-scoped VEX evidence (raw JSON, normalization diff, provenance) into portable bundles tied to timeline events. | | 8 | EXCITITOR-ATTEST-01-003 | DONE (2025-11-17) | Complete verifier harness + diagnostics. | Excititor Attestation Guild | Finish `IVexAttestationVerifier`, wire structured diagnostics/metrics, and prove DSSE bundle verification without touching consensus results. | | 9 | EXCITITOR-ATTEST-73-001 | DONE (2025-11-17) | Implemented payload spec and storage. | Excititor Core · Attestation Payloads Guild | Emit attestation payloads capturing supplier identity, justification summary, and scope metadata for trust chaining. | | 10 | EXCITITOR-ATTEST-73-002 | DONE (2025-11-17) | Implemented linkage API. | Excititor Core Guild | Provide APIs linking attestation IDs back to observation/linkset/product tuples for provenance citations without derived verdicts. | -| 11 | EXCITITOR-CONN-TRUST-01-001 | BLOCKED | Connector signer metadata schema still unpublished post-2025-11-14 review. | Excititor Connectors Guild | Add signer fingerprints, issuer tiers, and bundle references to MSRC/Oracle/Ubuntu/Stella connectors; document consumer guidance. | +| 11 | EXCITITOR-CONN-TRUST-01-001 | BLOCKED | PREP-EXCITITOR-CONN-TRUST-01-001-CONNECTOR-SI | Excititor Connectors Guild | Add signer fingerprints, issuer tiers, and bundle references to MSRC/Oracle/Ubuntu/Stella connectors; document consumer guidance. | ### Task Clusters & Readiness - **Advisory-AI evidence APIs:** 31-001 delivered; 31-003 instrumentation and 31-004 docs pending; ready to start once examples and telemetry fixtures finalize. @@ -53,6 +58,8 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked PREP tasks P1–P4 BLOCKED: mirror bundle schema (Sprint 162), sealed-mode error catalog, EvidenceLocker portable format, and connector signer metadata remain unpublished, keeping EXCITITOR-AIRGAP-56/57/58 and CONN-TRUST-01-001 gated. | Project Mgmt | | 2025-11-12 | Snapshot refreshed; 31-001 marked DONE; other tasks pending observability, AirGap schemas, and attestation verifier completion. | Excititor PM | | 2025-11-13 | Added readiness checklists and action tracker; awaiting Export Center mirror schema and Attestor verifier rehearsals. | Excititor PM | | 2025-11-13 | OpenAPI draft for 31-004 shared; observability wiring blocked until Ops deploys span sink. | WebService Guild | @@ -85,6 +92,6 @@ | 2025-11-17 | Coordinator · WebService/Observability Guilds | Counters/logs-only fallback approved; start 31-003 execution without span sink. | Keep span sink as follow-on milestone. | | 2025-11-14 | Connector provenance schema review (Connectors + Security Guilds) | Approve signer fingerprint + issuer tier schema for CONN-TRUST-01-001. | If schema not ready, keep task blocked and request interim metadata list from connectors. | | 2025-11-15 | Export Center mirror schema sync (Export Center + Excititor + AirGap) | Receive mirror bundle manifest to unblock 56/57. | If delayed, escalate to Sprint 162 leads and use placeholder spec with clearly marked TODO. | -| 2025-11-16 | Attestation verifier rehearsal (Excititor Attestation Guild) | Demo `IVexAttestationVerifier` harness + diagnostics to unblock 73-* tasks. | If issues persist, log BLOCKED status in attestation plan and re-forecast completion. | +| 2025-11-16 | Attestation verifier rehearsal (Excititor Attestation Guild) | Demo `IVexAttestationVerifier` harness + diagnostics to unblock 73-* tasks. | PREP-ATTESTATION-VERIFIER-REHEARSAL-EXCITITOR | | 2025-11-18 | Observability span sink deploy (Ops/Signals Guild) | Enable telemetry pipeline needed for 31-003. | If deploy slips, implement temporary counters/logs and keep action tracker flagged as blocked. | | 2025-11-19 | Connector metadata inventory (Connectors Guild) | Confirm signer metadata coverage for CONN-TRUST-01-001 rollout. | Fall back to partial coverage with feature flags. | diff --git a/docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md b/docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md index 1ccffc64f..bf669a3d2 100644 --- a/docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md +++ b/docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md @@ -22,34 +22,54 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-EXCITITOR-CONSOLE-23-001-AWAITING-CONCRE | BLOCKED | Due 2025-11-21 · Accountable: Excititor WebService Guild · BE-Base Platform Guild | Excititor WebService Guild · BE-Base Platform Guild | Awaiting concrete `/console/vex` API contract and grouping schema; LNM 21-* view spec not present.

Document artefact/deliverable for EXCITITOR-CONSOLE-23-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-EXCITITOR-CONSOLE-23-002-DEPENDS-ON-23-0 | BLOCKED | Due 2025-11-21 · Accountable: Excititor WebService Guild | Excititor WebService Guild | Depends on 23-001; need sprint-level contract for counters.

Document artefact/deliverable for EXCITITOR-CONSOLE-23-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-EXCITITOR-CONSOLE-23-003-DEPENDS-ON-23-0 | BLOCKED | Due 2025-11-21 · Accountable: Excititor WebService Guild | Excititor WebService Guild | Depends on 23-001; contract for caching/RBAC/precedence context pending.

Document artefact/deliverable for EXCITITOR-CONSOLE-23-003 and publish location so downstream tasks can proceed. | +| P4 | PREP-EXCITITOR-CORE-AOC-19-002-LINKSET-EXTRAC | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Linkset extraction rules/ordering not documented.

Document artefact/deliverable for EXCITITOR-CORE-AOC-19-002 and publish location so downstream tasks can proceed. | +| P5 | PREP-EXCITITOR-CORE-AOC-19-003-BLOCKED-ON-19 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Blocked on 19-002; design supersede chains.

Document artefact/deliverable for EXCITITOR-CORE-AOC-19-003 and publish location so downstream tasks can proceed. | +| P6 | PREP-EXCITITOR-CORE-AOC-19-004-REMOVE-CONSENS | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Remove consensus after 19-003 in place.

Document artefact/deliverable for EXCITITOR-CORE-AOC-19-004 and publish location so downstream tasks can proceed. | +| P7 | PREP-EXCITITOR-CORE-AOC-19-013-SEED-TENANT-AW | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Seed tenant-aware Authority clients in smoke/e2e once 19-004 lands.

Document artefact/deliverable for EXCITITOR-CORE-AOC-19-013 and publish location so downstream tasks can proceed. | +| P8 | PREP-EXCITITOR-GRAPH-21-001-NEEDS-CARTOGRAPHE | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core · Cartographer Guild | Excititor Core · Cartographer Guild | Needs Cartographer API contract + data availability.

Document artefact/deliverable for EXCITITOR-GRAPH-21-001 and publish location so downstream tasks can proceed. | +| P9 | PREP-EXCITITOR-GRAPH-21-002-BLOCKED-ON-21-001 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Core Guild | Excititor Core Guild | Blocked on 21-001.

Document artefact/deliverable for EXCITITOR-GRAPH-21-002 and publish location so downstream tasks can proceed. | +| P10 | PREP-EXCITITOR-GRAPH-21-005-BLOCKED-ON-21-002 | BLOCKED | Due 2025-11-21 · Accountable: Excititor Storage Guild | Excititor Storage Guild | Blocked on 21-002.

Document artefact/deliverable for EXCITITOR-GRAPH-21-005 and publish location so downstream tasks can proceed. | +| P11 | PREP-EXCITITOR-GRAPH-24-101-WAIT-FOR-21-005-I | BLOCKED | Due 2025-11-21 · Accountable: Excititor WebService Guild | Excititor WebService Guild | Wait for 21-005 indexes.

Document artefact/deliverable for EXCITITOR-GRAPH-24-101 and publish location so downstream tasks can proceed. | +| P12 | PREP-EXCITITOR-GRAPH-24-102-DEPENDS-ON-24-101 | BLOCKED | Due 2025-11-21 · Accountable: Excititor WebService Guild | Excititor WebService Guild | Depends on 24-101; design batch shape.

Document artefact/deliverable for EXCITITOR-GRAPH-24-102 and publish location so downstream tasks can proceed. | +| P13 | PREP-FINALIZE-CONSOLE-VEX-CONTRACT-23-001-AND | BLOCKED | Due 2025-11-21 · Accountable: BLOCKED (await contract; LNM view spec needed) | BLOCKED (await contract; LNM view spec needed) | 2025-11-18.

Document artefact/deliverable for Finalize `/console/vex` contract (23-001) and dashboard deltas (23-002). and publish location so downstream tasks can proceed. | +| P14 | PREP-LAND-LINKSET-EXTRACTION-RAW-UPSERT-UNIQU | BLOCKED | Due 2025-11-21 · Accountable: BLOCKED (linkset schema pending) | BLOCKED (linkset schema pending) | 2025-11-19.

Document artefact/deliverable for Land linkset extraction + raw upsert uniqueness (19-002/003). and publish location so downstream tasks can proceed. | +| P15 | PREP-REMOVE-MERGE-SEVERITY-LOGIC-AFTER-IDEMPO | BLOCKED | Due 2025-11-21 · Accountable: BLOCKED (depends on 19-002/003) | BLOCKED (depends on 19-002/003) | 2025-11-20.

Document artefact/deliverable for Remove merge/severity logic after idempotency in place (19-004). and publish location so downstream tasks can proceed. | +| P16 | PREP-ALIGN-INSPECTOR-LINKOUT-SCHEMAS-TO-UNBLO | BLOCKED | Due 2025-11-21 · Accountable: BLOCKED (awaiting Cartographer contract) | BLOCKED (awaiting Cartographer contract) | 2025-11-21.

Document artefact/deliverable for Align inspector/linkout schemas to unblock 21-001/002/005. and publish location so downstream tasks can proceed. | +| P17 | PREP-CARTOGRAPHER-SCHEMA-SYNC-MAINTAIN-BLOCKE | BLOCKED | Due 2025-11-21 · Accountable: Planning | Planning | Maintain BLOCKED status; deliver sample payloads for early testing.

Document artefact/deliverable for Cartographer schema sync and publish location so downstream tasks can proceed. | | 1 | EXCITITOR-CONN-SUSE-01-003 | DONE (2025-11-09) | Trust metadata flowing; monitor consumers. | Excititor Connectors – SUSE | Emit provider trust configuration (signer fingerprints, trust tier notes) into raw provenance envelope; aggregation-only. | | 2 | EXCITITOR-CONN-UBUNTU-01-003 | DONE (2025-11-09) | Trust metadata flowing; monitor consumers. | Excititor Connectors – Ubuntu | Emit Ubuntu signing metadata (GPG fingerprints, issuer trust tier) in raw provenance artifacts; aggregation-only. | -| 3 | EXCITITOR-CONSOLE-23-001 | BLOCKED (2025-11-17) | Awaiting concrete `/console/vex` API contract and grouping schema; LNM 21-* view spec not present. | Excititor WebService Guild · BE-Base Platform Guild | Expose grouped VEX statements with status chips, justification metadata, precedence trace pointers, tenant filters. | -| 4 | EXCITITOR-CONSOLE-23-002 | BLOCKED (2025-11-17) | Depends on 23-001; need sprint-level contract for counters. | Excititor WebService Guild | Provide aggregated delta counts for overrides; emit metrics for policy explain. | -| 5 | EXCITITOR-CONSOLE-23-003 | BLOCKED (2025-11-17) | Depends on 23-001; contract for caching/RBAC/precedence context pending. | Excititor WebService Guild | Rapid lookup endpoints of VEX by advisory/component incl. provenance + precedence context; caching + RBAC. | -| 6 | EXCITITOR-CORE-AOC-19-002 | BLOCKED (2025-11-17) | Linkset extraction rules/ordering not documented. | Excititor Core Guild | Extract advisory IDs, component PURLs, references into linkset with reconciled-from metadata. | -| 7 | EXCITITOR-CORE-AOC-19-003 | BLOCKED (2025-11-17) | Blocked on 19-002; design supersede chains. | Excititor Core Guild | Enforce uniqueness + append-only versioning of raw VEX docs. | -| 8 | EXCITITOR-CORE-AOC-19-004 | BLOCKED (2025-11-17) | Remove consensus after 19-003 in place. | Excititor Core Guild | Excise consensus/merge/severity logic from ingestion; rely on Policy Engine materializations. | -| 9 | EXCITITOR-CORE-AOC-19-013 | BLOCKED (2025-11-17) | Seed tenant-aware Authority clients in smoke/e2e once 19-004 lands. | Excititor Core Guild | Ensure cross-tenant ingestion rejected; update tests. | -| 10 | EXCITITOR-GRAPH-21-001 | BLOCKED (2025-10-27) | Needs Cartographer API contract + data availability. | Excititor Core · Cartographer Guild | Batched VEX/advisory reference fetches by PURL for inspector linkouts. | -| 11 | EXCITITOR-GRAPH-21-002 | BLOCKED (2025-10-27) | Blocked on 21-001. | Excititor Core Guild | Overlay metadata includes justification summaries + versions; fixtures/tests. | -| 12 | EXCITITOR-GRAPH-21-005 | BLOCKED (2025-10-27) | Blocked on 21-002. | Excititor Storage Guild | Indexes/materialized views for VEX lookups by PURL/policy for inspector perf. | -| 13 | EXCITITOR-GRAPH-24-101 | BLOCKED (2025-11-17) | Wait for 21-005 indexes. | Excititor WebService Guild | VEX status summaries per component/asset for Vuln Explorer. | -| 14 | EXCITITOR-GRAPH-24-102 | BLOCKED (2025-11-17) | Depends on 24-101; design batch shape. | Excititor WebService Guild | Batch VEX observation retrieval optimized for Graph overlays/tooltips. | +| 3 | EXCITITOR-CONSOLE-23-001 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CONSOLE-23-001-AWAITING-CONCRE | Excititor WebService Guild · BE-Base Platform Guild | Expose grouped VEX statements with status chips, justification metadata, precedence trace pointers, tenant filters. | +| 4 | EXCITITOR-CONSOLE-23-002 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CONSOLE-23-002-DEPENDS-ON-23-0 | Excititor WebService Guild | Provide aggregated delta counts for overrides; emit metrics for policy explain. | +| 5 | EXCITITOR-CONSOLE-23-003 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CONSOLE-23-003-DEPENDS-ON-23-0 | Excititor WebService Guild | Rapid lookup endpoints of VEX by advisory/component incl. provenance + precedence context; caching + RBAC. | +| 6 | EXCITITOR-CORE-AOC-19-002 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CORE-AOC-19-002-LINKSET-EXTRAC | Excititor Core Guild | Extract advisory IDs, component PURLs, references into linkset with reconciled-from metadata. | +| 7 | EXCITITOR-CORE-AOC-19-003 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CORE-AOC-19-003-BLOCKED-ON-19 | Excititor Core Guild | Enforce uniqueness + append-only versioning of raw VEX docs. | +| 8 | EXCITITOR-CORE-AOC-19-004 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CORE-AOC-19-004-REMOVE-CONSENS | Excititor Core Guild | Excise consensus/merge/severity logic from ingestion; rely on Policy Engine materializations. | +| 9 | EXCITITOR-CORE-AOC-19-013 | BLOCKED (2025-11-17) | PREP-EXCITITOR-CORE-AOC-19-013-SEED-TENANT-AW | Excititor Core Guild | Ensure cross-tenant ingestion rejected; update tests. | +| 10 | EXCITITOR-GRAPH-21-001 | BLOCKED (2025-10-27) | PREP-EXCITITOR-GRAPH-21-001-NEEDS-CARTOGRAPHE | Excititor Core · Cartographer Guild | Batched VEX/advisory reference fetches by PURL for inspector linkouts. | +| 11 | EXCITITOR-GRAPH-21-002 | BLOCKED (2025-10-27) | PREP-EXCITITOR-GRAPH-21-002-BLOCKED-ON-21-001 | Excititor Core Guild | Overlay metadata includes justification summaries + versions; fixtures/tests. | +| 12 | EXCITITOR-GRAPH-21-005 | BLOCKED (2025-10-27) | PREP-EXCITITOR-GRAPH-21-005-BLOCKED-ON-21-002 | Excititor Storage Guild | Indexes/materialized views for VEX lookups by PURL/policy for inspector perf. | +| 13 | EXCITITOR-GRAPH-24-101 | BLOCKED (2025-11-17) | PREP-EXCITITOR-GRAPH-24-101-WAIT-FOR-21-005-I | Excititor WebService Guild | VEX status summaries per component/asset for Vuln Explorer. | +| 14 | EXCITITOR-GRAPH-24-102 | BLOCKED (2025-11-17) | PREP-EXCITITOR-GRAPH-24-102-DEPENDS-ON-24-101 | Excititor WebService Guild | Batch VEX observation retrieval optimized for Graph overlays/tooltips. | | 15 | EXCITITOR-LNM-21-001 | IN REVIEW (2025-11-14) | Await review sign-off; prep migrations. | Excititor Core Guild | VEX observation model/schema, indexes, determinism rules, AOC metadata (`docs/modules/excititor/vex_observations.md`). | | 16 | AGENTS-EXCITITOR-UPDATE | DONE (2025-11-17) | AGENTS.md authored for WebService/Core/Storage/Worker. | Planning / Platform Guild | Author module-level AGENTS.md covering required docs, contracts, and testing for Excititor service components. | ## Action Tracker | Focus | Action | Owner(s) | Due | Status | | --- | --- | --- | --- | --- | -| Console APIs | Finalize `/console/vex` contract (23-001) and dashboard deltas (23-002). | WebService Guild | 2025-11-18 | BLOCKED (await contract; LNM view spec needed) | -| Ingestion idempotency | Land linkset extraction + raw upsert uniqueness (19-002/003). | Core Guild | 2025-11-19 | BLOCKED (linkset schema pending) | -| Consensus removal | Remove merge/severity logic after idempotency in place (19-004). | Core Guild | 2025-11-20 | BLOCKED (depends on 19-002/003) | -| Graph overlays | Align inspector/linkout schemas to unblock 21-001/002/005. | Core + Cartographer Guilds | 2025-11-21 | BLOCKED (awaiting Cartographer contract) | +| Console APIs | Finalize `/console/vex` contract (23-001) and dashboard deltas (23-002). | WebService Guild | PREP-FINALIZE-CONSOLE-VEX-CONTRACT-23-001-AND | BLOCKED (await contract; LNM view spec needed) | +| Ingestion idempotency | Land linkset extraction + raw upsert uniqueness (19-002/003). | Core Guild | PREP-LAND-LINKSET-EXTRACTION-RAW-UPSERT-UNIQU | BLOCKED (linkset schema pending) | +| Consensus removal | Remove merge/severity logic after idempotency in place (19-004). | Core Guild | PREP-REMOVE-MERGE-SEVERITY-LOGIC-AFTER-IDEMPO | BLOCKED (depends on 19-002/003) | +| Graph overlays | Align inspector/linkout schemas to unblock 21-001/002/005. | Core + Cartographer Guilds | PREP-ALIGN-INSPECTOR-LINKOUT-SCHEMAS-TO-UNBLO | BLOCKED (awaiting Cartographer contract) | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Normalized PREP-EXCITITOR-CORE-AOC-19-003 Task ID (removed trailing hyphen) so dependency resolution works. | Project Mgmt | +| 2025-11-19 | Marked PREP tasks P1–P17 BLOCKED due to missing console contract (LNM view spec), linkset extraction/idempotency schema, Cartographer API contract, and orchestrator/LNM inputs—keeping Console, AOC-19-002/003/004/013, and GRAPH 21/24 tracks gated. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-09 | Connector SUSE + Ubuntu trust provenance delivered. | Connectors Guild | | 2025-11-14 | LNM-21-001 schema in review. | Core Guild | | 2025-11-16 | Normalized sprint file to standard template and renamed to SPRINT_0119_0001_0002_excititor_ii.md. | Planning | @@ -73,4 +93,4 @@ | --- | --- | --- | --- | | 2025-11-18 | Console API review (WebService + BE-Base) | Approve `/console/vex` shape and delta counters. | Ship behind feature flag if minor gaps remain. | | 2025-11-19 | Idempotent ingestion design review (Core) | Lock uniqueness + supersede chain plan for 19-002/003. | Use temporary duplicate guard rails until migration complete. | -| 2025-11-21 | Cartographer schema sync | Unblock GRAPH-21-* inspector/linkout contracts. | Maintain BLOCKED status; deliver sample payloads for early testing. | +| 2025-11-21 | Cartographer schema sync | Unblock GRAPH-21-* inspector/linkout contracts. | PREP-CARTOGRAPHER-SCHEMA-SYNC-MAINTAIN-BLOCKE | diff --git a/docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md b/docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md index a84b71758..05f8eb90e 100644 --- a/docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md +++ b/docs/implplan/SPRINT_0120_0000_0001_policy_reasoning.md @@ -22,13 +22,11 @@ | Attestation pointer schema | DRAFT | Needs alignment with NOTIFY-ATTEST-74-001 to reuse DSSE IDs. | **Cluster snapshot** -| Cluster | Linked tasks | Owners | Status snapshot | Notes | -| --- | --- | --- | --- | --- | -| Observability & diagnostics | LEDGER-29-007/008 | Findings Ledger Guild · Observability Guild · QA Guild | TODO | Metric/log spec captured in `docs/modules/findings-ledger/observability.md`; determinism harness spec in `docs/modules/findings-ledger/replay-harness.md`; sequencing captured in `docs/modules/findings-ledger/implementation_plan.md`; awaiting Observability sign-off + Grafana JSON export (target 2025-11-15). | -| Deployment & backup | LEDGER-29-009 | Findings Ledger Guild · DevOps Guild | TODO | Baseline deployment/backup guide published (`docs/modules/findings-ledger/deployment.md`); need to align Compose/Helm overlays + automate migrations. | -| Orchestrator provenance | LEDGER-34-101 | Findings Ledger Guild | TODO | Blocked until Orchestrator exports job ledger payload; coordinate with Sprint 150.A. | -| Air-gap provenance & staleness | LEDGER-AIRGAP-56/57/58 series | Findings Ledger Guild · AirGap Guilds · Evidence Locker Guild | TODO | Requirements captured in `docs/modules/findings-ledger/airgap-provenance.md`; blocked on mirror bundle schema freeze + AirGap controller inputs. | -| Attestation linkage | LEDGER-ATTEST-73-001 | Findings Ledger Guild · Attestor Service Guild | TODO | Waiting on attestation payload pointers from NOTIFY-ATTEST-74-001 work to reuse DSSE IDs. | +- **Observability & diagnostics** (LEDGER-29-007/008 · Findings Ledger Guild · Observability Guild · QA Guild) — Status TODO. Metric/log spec captured in `docs/modules/findings-ledger/observability.md`; determinism harness spec in `docs/modules/findings-ledger/replay-harness.md`; sequencing documented in `docs/modules/findings-ledger/implementation_plan.md`. Awaiting Observability sign-off + Grafana JSON export (target 2025-11-15). +- **Deployment & backup** (LEDGER-29-009 · Findings Ledger Guild · DevOps Guild) — Status TODO. Baseline deployment/backup guide published (`docs/modules/findings-ledger/deployment.md`); need Compose/Helm overlays and automated migrations. +- **Orchestrator provenance** (LEDGER-34-101 · Findings Ledger Guild) — Status TODO. Blocked until Orchestrator exports job ledger payload; coordinate with Sprint 150.A deliverables. +- **Air-gap provenance & staleness** (LEDGER-AIRGAP-56/57/58 · Findings Ledger Guild · AirGap Guilds · Evidence Locker Guild) — Status TODO. Requirements captured in `docs/modules/findings-ledger/airgap-provenance.md`; waiting on mirror bundle schema freeze + AirGap controller inputs. +- **Attestation linkage** (LEDGER-ATTEST-73-001 · Findings Ledger Guild · Attestor Service Guild) — Status TODO. Waiting on attestation payload pointers from NOTIFY-ATTEST-74-001 work to reuse DSSE IDs. ## Documentation Prerequisites - `docs/modules/findings-ledger/observability.md` @@ -41,11 +39,14 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA | BLOCKED | Due 2025-11-21 · Accountable: Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Await Observability schema sign-off + ledger write endpoint contract; 5 M fixture drop pending.

Document artefact/deliverable for LEDGER-29-008 and publish location so downstream tasks can proceed. | +| P2 | PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT | BLOCKED | Due 2025-11-21 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Orchestrator ledger export contract (Sprint 150.A) not published.

Document artefact/deliverable for LEDGER-34-101 and publish location so downstream tasks can proceed. | +| P3 | PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | BLOCKED | Due 2025-11-21 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Mirror bundle schema freeze outstanding.

Document artefact/deliverable for LEDGER-AIRGAP-56-001 and publish location so downstream tasks can proceed. | | 1 | LEDGER-29-007 | DONE (2025-11-17) | Observability metric schema sign-off; deps LEDGER-29-006 | Findings Ledger Guild, Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Instrument `ledger_write_latency`, `projection_lag_seconds`, `ledger_events_total`, structured logs, Merkle anchoring alerts, and publish dashboards. | -| 2 | LEDGER-29-008 | BLOCKED | Await Observability schema sign-off + ledger write endpoint contract; 5 M fixture drop pending | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Develop unit/property/integration tests, replay/restore tooling, determinism harness, and load tests at 5 M findings/tenant. | +| 2 | LEDGER-29-008 | BLOCKED | PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA | Findings Ledger Guild, QA Guild / `src/Findings/StellaOps.Findings.Ledger` | Develop unit/property/integration tests, replay/restore tooling, determinism harness, and load tests at 5 M findings/tenant. | | 3 | LEDGER-29-009 | BLOCKED | Depends on LEDGER-29-008 harness results (5 M replay + observability schema) | Findings Ledger Guild, DevOps Guild / `src/Findings/StellaOps.Findings.Ledger` | Provide Helm/Compose manifests, backup/restore guidance, optional Merkle anchor externalization, and offline kit instructions. | -| 4 | LEDGER-34-101 | BLOCKED | Orchestrator ledger export contract (Sprint 150.A) not published | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Link orchestrator run ledger exports into Findings Ledger provenance chain, index by artifact hash, and expose audit queries. | -| 5 | LEDGER-AIRGAP-56-001 | BLOCKED | Mirror bundle schema freeze outstanding | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Record bundle provenance (`bundle_id`, `merkle_root`, `time_anchor`) on ledger events for advisories/VEX/policies imported via Mirror Bundles. | +| 4 | LEDGER-34-101 | BLOCKED | PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Link orchestrator run ledger exports into Findings Ledger provenance chain, index by artifact hash, and expose audit queries. | +| 5 | LEDGER-AIRGAP-56-001 | BLOCKED | PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Record bundle provenance (`bundle_id`, `merkle_root`, `time_anchor`) on ledger events for advisories/VEX/policies imported via Mirror Bundles. | | 6 | LEDGER-AIRGAP-56-002 | BLOCKED | Depends on LEDGER-AIRGAP-56-001 provenance schema | Findings Ledger Guild, AirGap Time Guild / `src/Findings/StellaOps.Findings.Ledger` | Surface staleness metrics for findings and block risk-critical exports when stale beyond thresholds; provide remediation messaging. | | 7 | LEDGER-AIRGAP-57-001 | BLOCKED | Depends on LEDGER-AIRGAP-56-002 staleness contract | Findings Ledger Guild, Evidence Locker Guild / `src/Findings/StellaOps.Findings.Ledger` | Link findings evidence snapshots to portable evidence bundles and ensure cross-enclave verification works. | | 8 | LEDGER-AIRGAP-58-001 | BLOCKED | Depends on LEDGER-AIRGAP-57-001 bundle linkage | Findings Ledger Guild, AirGap Controller Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit timeline events for bundle import impacts (new findings, remediation changes) with sealed-mode context. | @@ -54,8 +55,11 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked PREP tasks P1–P3 BLOCKED: observability schema, orchestrator ledger export contract, and mirror bundle schema are still missing, keeping LEDGER-29-008/34-101/AIRGAP-56-* blocked. | Project Mgmt | | 2025-11-13 09:30 | Documented Findings.I scope, milestones, and external dependencies; awaiting Observability + Orchestrator inputs before flipping any tasks to DOING. | Findings Ledger Guild | | 2025-11-13 10:45 | Published `docs/modules/findings-ledger/observability.md` detailing metrics/logs/alerts required for LEDGER-29-007/008; sent draft to Observability Guild for review. | Findings Ledger Guild | +| 2025-11-19 09:30 | Reformatted Cluster snapshot into bullet list and confirmed Delivery Tracker already covers LEDGER-AIRGAP dependencies; no scope change. | Project Mgmt | | 2025-11-13 11:20 | Added `docs/modules/findings-ledger/deployment.md` covering Compose/Helm rollout, migrations, backup/restore, and offline workflows for LEDGER-29-009. | Findings Ledger Guild | | 2025-11-13 11:50 | Added `docs/modules/findings-ledger/replay-harness.md` outlining fixtures, CLI workflow, and reporting for LEDGER-29-008 determinism tests. | Findings Ledger Guild | | 2025-11-13 12:05 | Drafted `docs/modules/findings-ledger/implementation_plan.md` summarizing phase sequencing and dependencies for Findings.I. | Findings Ledger Guild | diff --git a/docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md index 70c3fd6d6..a1e7e8e68 100644 --- a/docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md +++ b/docs/implplan/SPRINT_0121_0001_0001_policy_reasoning.md @@ -25,25 +25,36 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-LEDGER-EXPORT-35-001-NO-HTTP-API-SURFACE | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | No HTTP/API surface or contract to host export endpoints; needs API scaffold + filters spec.

Document artefact/deliverable for LEDGER-EXPORT-35-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-LEDGER-OAS-61-001-ABSENT-OAS-BASELINE-AN | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild; API Contracts Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; API Contracts Guild / src/Findings/StellaOps.Findings.Ledger | Absent OAS baseline and API host for ledger; requires contract definition with API Guild.

Document artefact/deliverable for LEDGER-OAS-61-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-LEDGER-OAS-61-002-DEPENDS-ON-61-001-CONT | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Depends on 61-001 contract + HTTP surface.

Document artefact/deliverable for LEDGER-OAS-61-002 and publish location so downstream tasks can proceed. | +| P4 | PREP-LEDGER-OAS-62-001-SDK-GENERATION-PENDING | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | SDK generation pending 61-002.

Document artefact/deliverable for LEDGER-OAS-62-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-LEDGER-OAS-63-001-DEPENDENT-ON-SDK-VALID | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Dependent on SDK validation (62-001).

Document artefact/deliverable for LEDGER-OAS-63-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-LEDGER-OBS-54-001-NO-HTTP-SURFACE-MINIMA | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | No HTTP surface/minimal API present in module to host `/ledger/attestations`; needs API contract + service scaffold.

Document artefact/deliverable for LEDGER-OBS-54-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-LEDGER-OBS-55-001-DEPENDS-ON-54-001-ATTE | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Depends on 54-001 attestation API availability.

Document artefact/deliverable for LEDGER-OBS-55-001 and publish location so downstream tasks can proceed. | +| P8 | PREP-LEDGER-PACKS-42-001-SNAPSHOT-TIME-TRAVEL | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Snapshot/time-travel contract and bundle format not specified; needs design input.

Document artefact/deliverable for LEDGER-PACKS-42-001 and publish location so downstream tasks can proceed. | +| P9 | PREP-LEDGER-RISK-66-001-RISK-ENGINE-SCHEMA-CO | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Risk Engine schema/contract inputs absent; requires risk field definitions + rollout plan.

Document artefact/deliverable for LEDGER-RISK-66-001 and publish location so downstream tasks can proceed. | +| P10 | PREP-LEDGER-RISK-66-002-DEPENDS-ON-66-001-MIG | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Depends on 66-001 migration + risk scoring contract.

Document artefact/deliverable for LEDGER-RISK-66-002 and publish location so downstream tasks can proceed. | | 1 | LEDGER-ATTEST-73-002 | BLOCKED | Waiting on LEDGER-ATTEST-73-001 verification pipeline delivery | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Enable search/filter in findings projections by verification result and attestation status | -| 2 | LEDGER-EXPORT-35-001 | BLOCKED | No HTTP/API surface or contract to host export endpoints; needs API scaffold + filters spec | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Provide paginated streaming endpoints for advisories, VEX, SBOMs, and findings with deterministic ordering and provenance metadata | -| 3 | LEDGER-OAS-61-001 | BLOCKED | Absent OAS baseline and API host for ledger; requires contract definition with API Guild | Findings Ledger Guild; API Contracts Guild / src/Findings/StellaOps.Findings.Ledger | Expand Findings Ledger OAS to include projections, evidence lookups, and filter parameters with examples | -| 4 | LEDGER-OAS-61-002 | BLOCKED | Depends on 61-001 contract + HTTP surface | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Implement `/.well-known/openapi` endpoint and ensure version metadata matches release | -| 5 | LEDGER-OAS-62-001 | BLOCKED | SDK generation pending 61-002 | Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | Provide SDK test cases for findings pagination, filtering, evidence links; ensure typed models expose provenance | -| 6 | LEDGER-OAS-63-001 | BLOCKED | Dependent on SDK validation (62-001) | Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Support deprecation headers and Notifications for retiring finding endpoints | +| 2 | LEDGER-EXPORT-35-001 | BLOCKED | PREP-LEDGER-EXPORT-35-001-NO-HTTP-API-SURFACE | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Provide paginated streaming endpoints for advisories, VEX, SBOMs, and findings with deterministic ordering and provenance metadata | +| 3 | LEDGER-OAS-61-001 | BLOCKED | PREP-LEDGER-OAS-61-001-ABSENT-OAS-BASELINE-AN | Findings Ledger Guild; API Contracts Guild / src/Findings/StellaOps.Findings.Ledger | Expand Findings Ledger OAS to include projections, evidence lookups, and filter parameters with examples | +| 4 | LEDGER-OAS-61-002 | BLOCKED | PREP-LEDGER-OAS-61-002-DEPENDS-ON-61-001-CONT | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Implement `/.well-known/openapi` endpoint and ensure version metadata matches release | +| 5 | LEDGER-OAS-62-001 | BLOCKED | PREP-LEDGER-OAS-62-001-SDK-GENERATION-PENDING | Findings Ledger Guild; SDK Generator Guild / src/Findings/StellaOps.Findings.Ledger | Provide SDK test cases for findings pagination, filtering, evidence links; ensure typed models expose provenance | +| 6 | LEDGER-OAS-63-001 | BLOCKED | PREP-LEDGER-OAS-63-001-DEPENDENT-ON-SDK-VALID | Findings Ledger Guild; API Governance Guild / src/Findings/StellaOps.Findings.Ledger | Support deprecation headers and Notifications for retiring finding endpoints | | 7 | LEDGER-OBS-50-001 | DONE | Telemetry core wired into writer/projector; structured logs + spans added | Findings Ledger Guild; Observability Guild / src/Findings/StellaOps.Findings.Ledger | Integrate telemetry core within ledger writer/projector services for append, replay, and query APIs | | 8 | LEDGER-OBS-51-001 | DONE | Metrics and SLOs implemented in code + docs | Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Publish metrics for ledger latency, projector lag, event throughput, and policy evaluation linkage; SLOs: append P95 < 1s, replay lag < 30s | | 9 | LEDGER-OBS-52-001 | DONE | Timeline events emitted for ledger append + projection commit | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Emit timeline events for ledger writes and projector commits (`ledger.event.appended`, `ledger.projection.updated`) with trace ID, policy version, evidence bundle reference placeholders | | 10 | LEDGER-OBS-53-001 | DONE | Evidence bundle refs persisted + lookup API | Findings Ledger Guild; Evidence Locker Guild / src/Findings/StellaOps.Findings.Ledger | Persist evidence bundle references alongside ledger entries; expose lookup linking findings to evidence manifests and timeline | -| 11 | LEDGER-OBS-54-001 | BLOCKED | No HTTP surface/minimal API present in module to host `/ledger/attestations`; needs API contract + service scaffold | Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | Verify attestation references for ledger-derived exports; expose `/ledger/attestations` endpoint returning DSSE verification state and chain-of-custody summary | -| 12 | LEDGER-OBS-55-001 | BLOCKED | Depends on 54-001 attestation API availability | Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Enhance incident mode to record replay diagnostics (lag traces, conflict snapshots), extend retention while active, and emit activation events to timeline/notifier | -| 13 | LEDGER-PACKS-42-001 | BLOCKED | Snapshot/time-travel contract and bundle format not specified; needs design input | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Provide snapshot/time-travel APIs and digestible exports for task pack simulation and CLI offline mode | -| 14 | LEDGER-RISK-66-001 | BLOCKED | Risk Engine schema/contract inputs absent; requires risk field definitions + rollout plan | Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Add schema migrations for `risk_score`, `risk_severity`, `profile_version`, `explanation_id`, and supporting indexes | -| 15 | LEDGER-RISK-66-002 | BLOCKED | Depends on 66-001 migration + risk scoring contract | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Implement deterministic upsert of scoring results keyed by finding hash/profile version with history audit | +| 11 | LEDGER-OBS-54-001 | BLOCKED | PREP-LEDGER-OBS-54-001-NO-HTTP-SURFACE-MINIMA | Findings Ledger Guild; Provenance Guild / src/Findings/StellaOps.Findings.Ledger | Verify attestation references for ledger-derived exports; expose `/ledger/attestations` endpoint returning DSSE verification state and chain-of-custody summary | +| 12 | LEDGER-OBS-55-001 | BLOCKED | PREP-LEDGER-OBS-55-001-DEPENDS-ON-54-001-ATTE | Findings Ledger Guild; DevOps Guild / src/Findings/StellaOps.Findings.Ledger | Enhance incident mode to record replay diagnostics (lag traces, conflict snapshots), extend retention while active, and emit activation events to timeline/notifier | +| 13 | LEDGER-PACKS-42-001 | BLOCKED | PREP-LEDGER-PACKS-42-001-SNAPSHOT-TIME-TRAVEL | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Provide snapshot/time-travel APIs and digestible exports for task pack simulation and CLI offline mode | +| 14 | LEDGER-RISK-66-001 | BLOCKED | PREP-LEDGER-RISK-66-001-RISK-ENGINE-SCHEMA-CO | Findings Ledger Guild; Risk Engine Guild / src/Findings/StellaOps.Findings.Ledger | Add schema migrations for `risk_score`, `risk_severity`, `profile_version`, `explanation_id`, and supporting indexes | +| 15 | LEDGER-RISK-66-002 | BLOCKED | PREP-LEDGER-RISK-66-002-DEPENDS-ON-66-001-MIG | Findings Ledger Guild / src/Findings/StellaOps.Findings.Ledger | Implement deterministic upsert of scoring results keyed by finding hash/profile version with history audit | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-08 | Sprint stub created; awaiting template normalisation. | Planning | | 2025-11-17 | Normalised sprint to standard template and renamed file to `SPRINT_0121_0001_0001_policy_reasoning.md`. | Project Mgmt | | 2025-11-17 | Implemented LEDGER-OBS-50-001: telemetry core spans/scopes/logs for ledger append and projection paths added. | Findings Ledger | @@ -64,4 +75,4 @@ ## Next Checkpoints - Schedule cross-guild kickoff for week of 2025-11-24 once dependency clears. -- Add weekly Findings Ledger status review (TBD owner) after staffing. +- Add weekly Findings Ledger status review (TBD owner) after staffing. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md index 528584e32..c750f9b48 100644 --- a/docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md +++ b/docs/implplan/SPRINT_0122_0001_0001_policy_reasoning.md @@ -24,14 +24,18 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-LEDGER-RISK-68-001-AWAIT-UNBLOCK-OF-67-0 | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Await unblock of 67-001 + Export Center contract for scored findings.

Document artefact/deliverable for LEDGER-RISK-68-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-LEDGER-RISK-69-001-REQUIRES-67-001-68-00 | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Requires 67-001/68-001 to define metrics dimensions.

Document artefact/deliverable for LEDGER-RISK-69-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-LEDGER-TEN-48-001-NEEDS-PLATFORM-APPROVE | TODO | Due 2025-11-22 · Accountable: Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Needs platform-approved partitioning + RLS policy (tenant/project shape, session variables).

Document artefact/deliverable for LEDGER-TEN-48-001 and publish location so downstream tasks can proceed. | | 1 | LEDGER-RISK-67-001 | BLOCKED | Depends on risk scoring contract + migrations from LEDGER-RISK-66-002 | Findings Ledger Guild · Risk Engine Guild / `src/Findings/StellaOps.Findings.Ledger` | Expose query APIs for scored findings with score/severity filters, pagination, and explainability links | -| 2 | LEDGER-RISK-68-001 | BLOCKED | Await unblock of 67-001 + Export Center contract for scored findings | Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Enable export of scored findings and simulation results via Export Center integration | -| 3 | LEDGER-RISK-69-001 | BLOCKED | Requires 67-001/68-001 to define metrics dimensions | Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit metrics/dashboards for scoring latency, result freshness, severity distribution, provider gaps | -| 4 | LEDGER-TEN-48-001 | BLOCKED | Needs platform-approved partitioning + RLS policy (tenant/project shape, session variables) | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Partition ledger tables by tenant/project, enable RLS, update queries/events, and stamp audit metadata | +| 2 | LEDGER-RISK-68-001 | BLOCKED | PREP-LEDGER-RISK-68-001-AWAIT-UNBLOCK-OF-67-0 | Findings Ledger Guild · Export Guild / `src/Findings/StellaOps.Findings.Ledger` | Enable export of scored findings and simulation results via Export Center integration | +| 3 | LEDGER-RISK-69-001 | BLOCKED | PREP-LEDGER-RISK-69-001-REQUIRES-67-001-68-00 | Findings Ledger Guild · Observability Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit metrics/dashboards for scoring latency, result freshness, severity distribution, provider gaps | +| 4 | LEDGER-TEN-48-001 | BLOCKED | PREP-LEDGER-TEN-48-001-NEEDS-PLATFORM-APPROVE | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Partition ledger tables by tenant/project, enable RLS, update queries/events, and stamp audit metadata | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-18 | Renamed file to `SPRINT_0122_0001_0001_policy_reasoning.md` and normalised to standard template; no scope changes. | Findings Ledger | | 2025-11-18 | Set LEDGER-RISK-67-001/68-001/69-001 to BLOCKED pending risk-scoring contract (66-002) and export metrics dimensions. | Findings Ledger | | 2025-11-18 | Set LEDGER-TEN-48-001 to BLOCKED pending DB partition/RLS design (tenant+project keys, session variables) from Platform/DB guild. | Findings Ledger | @@ -44,4 +48,4 @@ ## Next Checkpoints - Await Risk Engine contract drop for 66-002 (date TBD; track in Sprint 0121 dependencies). - Schedule DB/RLS design review with Platform/DB guild to unblock TEN-48-001 (target week of 2025-11-24). -- Re-evaluate sprint status once upstream contracts are published. +- Re-evaluate sprint status once upstream contracts are published. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..a314c9139 --- /dev/null +++ b/docs/implplan/SPRINT_0123_0001_0001_policy_reasoning.md @@ -0,0 +1,74 @@ +# Sprint 0123-0001-0001 · Policy & Reasoning (Policy Engine) + +## Topic & Scope +- Extend Policy Engine with export, air-gap, AOC linting, and attestation surfaces while keeping evidence aggregation-only. +- Ensure Console export and air-gap bundles depend on frozen bundle/DSSE schemas before implementation. +- Align policy attestation and linting with Authority/Attestor/Console contracts; avoid inferred verdicts. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine` (and `src/Policy/__Libraries/StellaOps.Policy`). + +## Dependencies & Concurrency +- Upstream: Export bundle schema + scheduler job spec; mirror bundle/air-gap schema and sealed-mode rules; Attestor verification policy schema; Authority `effective:write` contract; Console API filters/pagination spec. +- Concurrency: Execute tasks in table order (DOING → TODO → BLOCKED). All tasks currently blocked pending upstream contracts; no parallel execution until contracts land. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` +- Any export/air-gap/attestation contract docs once published. + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Scheduler Guild · Observability Guild | Policy Guild · Scheduler Guild · Observability Guild | Missing export bundle contract/API surface and scheduler job spec for Console.

Document artefact/deliverable for EXPORT-CONSOLE-23-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild | Policy Guild | Mirror bundle schema not published; requires bundle_id/provenance fields + sealed-mode rules.

Document artefact/deliverable for POLICY-AIRGAP-56-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-POLICY-AIRGAP-56-002-DEPENDS-ON-56-001-B | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Policy Studio Guild | Policy Guild · Policy Studio Guild | Depends on 56-001 bundle import schema + DSSE signing profile.

Document artefact/deliverable for POLICY-AIRGAP-56-002 and publish location so downstream tasks can proceed. | +| P4 | PREP-POLICY-AIRGAP-57-001-REQUIRES-SEALED-MOD | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · AirGap Policy Guild | Policy Guild · AirGap Policy Guild | Requires sealed-mode contract after 56-002.

Document artefact/deliverable for POLICY-AIRGAP-57-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-POLICY-AIRGAP-57-002-NEEDS-STALENESS-FAL | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · AirGap Time Guild | Policy Guild · AirGap Time Guild | Needs staleness/fallback data contract from 57-001.

Document artefact/deliverable for POLICY-AIRGAP-57-002 and publish location so downstream tasks can proceed. | +| P6 | PREP-POLICY-AIRGAP-58-001-NOTIFICATION-SCHEMA | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Notifications Guild | Policy Guild · Notifications Guild | Notification schema and staleness signals pending from 57-002.

Document artefact/deliverable for POLICY-AIRGAP-58-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-POLICY-AOC-19-001-LINTING-TARGETS-SPEC-A | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild | Policy Guild | Linting targets/spec absent; no analyzer contract.

Document artefact/deliverable for POLICY-AOC-19-001 and publish location so downstream tasks can proceed. | +| P8 | PREP-POLICY-AOC-19-002-DEPENDS-ON-19-001-LINT | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Platform Security | Policy Guild · Platform Security | Depends on 19-001 lint + Authority `effective:write` contract.

Document artefact/deliverable for POLICY-AOC-19-002 and publish location so downstream tasks can proceed. | +| P9 | PREP-POLICY-AOC-19-003-REQUIRES-POST-19-002-N | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild | Policy Guild | Requires post-19-002 normalized-field removal contract/fixtures.

Document artefact/deliverable for POLICY-AOC-19-003 and publish location so downstream tasks can proceed. | +| P10 | PREP-POLICY-AOC-19-004-DEPENDS-ON-19-003-SHAP | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · QA Guild | Policy Guild · QA Guild | Depends on 19-003 shape + determinism fixtures.

Document artefact/deliverable for POLICY-AOC-19-004 and publish location so downstream tasks can proceed. | +| P11 | PREP-POLICY-ATTEST-73-001-VERIFICATIONPOLICY | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Attestor Service Guild | Policy Guild · Attestor Service Guild | VerificationPolicy schema/persistence contract missing; Attestor alignment needed.

Document artefact/deliverable for POLICY-ATTEST-73-001 and publish location so downstream tasks can proceed. | +| P12 | PREP-POLICY-ATTEST-73-002-DEPENDS-ON-73-001-E | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild | Policy Guild | Depends on 73-001 editor DTOs/validation schema.

Document artefact/deliverable for POLICY-ATTEST-73-002 and publish location so downstream tasks can proceed. | +| P13 | PREP-POLICY-ATTEST-74-001-REQUIRES-73-002-ATT | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Attestor Service Guild | Policy Guild · Attestor Service Guild | Requires 73-002 + Attestor pipeline contract.

Document artefact/deliverable for POLICY-ATTEST-74-001 and publish location so downstream tasks can proceed. | +| P14 | PREP-POLICY-ATTEST-74-002-NEEDS-74-001-SURFAC | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · Console Guild | Policy Guild · Console Guild | Needs 74-001 surfaced in Console verification reports contract.

Document artefact/deliverable for POLICY-ATTEST-74-002 and publish location so downstream tasks can proceed. | +| P15 | PREP-POLICY-CONSOLE-23-001-CONSOLE-API-CONTRA | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild · BE-Base Platform Guild | Policy Guild · BE-Base Platform Guild | Console API contract (filters/pagination/aggregation) absent.

Document artefact/deliverable for POLICY-CONSOLE-23-001 and publish location so downstream tasks can proceed. | +| 1 | EXPORT-CONSOLE-23-001 | BLOCKED | PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN | Policy Guild · Scheduler Guild · Observability Guild | Implement Console export endpoints/jobs once schema + job wiring are defined. | +| 2 | POLICY-AIRGAP-56-001 | BLOCKED | PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | Policy Guild | Air-gap bundle import support for policy packs. | +| 3 | POLICY-AIRGAP-56-002 | BLOCKED | PREP-POLICY-AIRGAP-56-002-DEPENDS-ON-56-001-B | Policy Guild · Policy Studio Guild | Air-gap sealed-mode handling for policy packs. | +| 4 | POLICY-AIRGAP-57-001 | BLOCKED | PREP-POLICY-AIRGAP-57-001-REQUIRES-SEALED-MOD | Policy Guild · AirGap Policy Guild | Sealed-mode error handling for policy packs. | +| 5 | POLICY-AIRGAP-57-002 | BLOCKED | PREP-POLICY-AIRGAP-57-002-NEEDS-STALENESS-FAL | Policy Guild · AirGap Time Guild | Staleness/fallback signaling for policy packs. | +| 6 | POLICY-AIRGAP-58-001 | BLOCKED | PREP-POLICY-AIRGAP-58-001-NOTIFICATION-SCHEMA | Policy Guild · Notifications Guild | Notifications for air-gap policy pack changes. | +| 7 | POLICY-AOC-19-001 | BLOCKED | PREP-POLICY-AOC-19-001-LINTING-TARGETS-SPEC-A | Policy Guild | Implement linting for ingestion projects/helpers. | +| 8 | POLICY-AOC-19-002 | BLOCKED | PREP-POLICY-AOC-19-002-DEPENDS-ON-19-001-LINT | Policy Guild · Platform Security | Enforce `effective:write` gate. | +| 9 | POLICY-AOC-19-003 | BLOCKED | PREP-POLICY-AOC-19-003-REQUIRES-POST-19-002-N | Policy Guild | Remove normalized fields per contract. | +| 10 | POLICY-AOC-19-004 | BLOCKED | PREP-POLICY-AOC-19-004-DEPENDS-ON-19-003-SHAP | Policy Guild · QA Guild | Determinism/fixtures for normalized-field removal. | +| 11 | POLICY-ATTEST-73-001 | BLOCKED | PREP-POLICY-ATTEST-73-001-VERIFICATIONPOLICY | Policy Guild · Attestor Service Guild | Persist verification policy schema. | +| 12 | POLICY-ATTEST-73-002 | BLOCKED | PREP-POLICY-ATTEST-73-002-DEPENDS-ON-73-001-E | Policy Guild | Editor DTOs/validation for verification policy. | +| 13 | POLICY-ATTEST-74-001 | BLOCKED | PREP-POLICY-ATTEST-74-001-REQUIRES-73-002-ATT | Policy Guild · Attestor Service Guild | Surface attestation reports. | +| 14 | POLICY-ATTEST-74-002 | BLOCKED | PREP-POLICY-ATTEST-74-002-NEEDS-74-001-SURFAC | Policy Guild · Console Guild | Console report integration. | +| 15 | POLICY-CONSOLE-23-001 | BLOCKED | PREP-POLICY-CONSOLE-23-001-CONSOLE-API-CONTRA | Policy Guild · BE-Base Platform Guild | Expose policy data to Console once API spec lands. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Removed trailing hyphen from PREP-POLICY-ATTEST-73-001-VERIFICATIONPOLICY so dependent task resolves correctly. | Project Mgmt | +| 2025-11-19 | Marked PREP tasks P1–P15 BLOCKED: export bundle schema, mirror/air-gap schemas, lint targets, attestation verification schemas, and Console API contract remain unpublished, keeping downstream POLICY/ATTEST/AIRGAP/CONSOLE work gated. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-08 | Sprint created; awaiting staffing. | Planning | +| 2025-11-18 | Attempted EXPORT-CONSOLE-23-001; blocked due to missing export bundle/schema and scheduler job contract. Marked all tasks BLOCKED pending lint/airgap/attest/Console contracts. | Policy Guild | +| 2025-11-19 | Converted legacy file `SPRINT_123_policy_reasoning.md` into redirect stub pointing here to avoid divergent updates. | Implementer | +| 2025-11-19 | Normalised sprint to standard template and renamed from `SPRINT_123_policy_reasoning.md` to `SPRINT_0123_0001_0001_policy_reasoning.md`; content preserved; all tasks remain BLOCKED. | Implementer | + +## Decisions & Risks +- Export/air-gap remain blocked without bundle schema, sealed-mode rules, and scheduler contracts; cannot proceed until provided. +- Linting (AOC-19-001..004) blocked pending analyzer targets/spec and Authority gate contract. +- Attestation tasks (73/74) blocked pending Attestor verification policy schema and Console report contract. +- Console export and policy API tasks blocked without Console API contract. + +## Next Checkpoints +- Draft export surface proposal for Console (API + scheduler wiring) once bundle schema is published. +- Identify bundle schema dependencies for POLICY-AIRGAP-56-* once mirror schema freezes. +- Re-evaluate lint/attest tasks after respective contracts are delivered (dates TBD). diff --git a/docs/implplan/SPRINT_0124_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0124_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..73051b575 --- /dev/null +++ b/docs/implplan/SPRINT_0124_0001_0001_policy_reasoning.md @@ -0,0 +1,51 @@ +# Sprint 0124-0001-0001 · Policy & Reasoning (Policy Engine phase II) + +## Topic & Scope +- Continue Policy Engine core (Policy.II): deterministic evaluator, materialization, simulation, tracing, and storage. +- Ensure aggregation-only behavior; no wall-clock/RNG/network use during evaluation. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine` (and `src/Policy/__Libraries/StellaOps.Policy`). + +## Dependencies & Concurrency +- Upstream: Sprint 120.C Policy.I must land before this track. +- Concurrency: execute tasks in listed order (DOING → TODO → BLOCKED). + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` + +## Delivery Tracker +| # | Task ID & handle | State | Key dependency / next step | Owners | +| --- | --- | --- | --- | --- | +| P1 | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | TODO | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Deterministic evaluator spec missing.

Document artefact/deliverable for POLICY-ENGINE-20-002 and publish location so downstream tasks can proceed. | +| 1 | POLICY-CONSOLE-23-002 | TODO | Produce simulation diff metadata and approval endpoints for Console (deps: POLICY-CONSOLE-23-001). | Policy Guild, Product Ops / `src/Policy/StellaOps.Policy.Engine` | +| 2 | POLICY-ENGINE-20-002 | BLOCKED (2025-10-26) | PREP-POLICY-ENGINE-20-002-DETERMINISTIC-EVALU | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | +| 3 | POLICY-ENGINE-20-003 | TODO | Depends on 20-002. | Policy · Concelier · Excititor Guilds / `src/Policy/StellaOps.Policy.Engine` | +| 4 | POLICY-ENGINE-20-004 | TODO | Depends on 20-003. | Policy · Platform Storage Guild / `src/Policy/StellaOps.Policy.Engine` | +| 5 | POLICY-ENGINE-20-005 | TODO | Depends on 20-004. | Policy · Security Engineering / `src/Policy/StellaOps.Policy.Engine` | +| 6 | POLICY-ENGINE-20-006 | TODO | Depends on 20-005. | Policy · Scheduler Worker Guild / `src/Policy/StellaOps.Policy.Engine` | +| 7 | POLICY-ENGINE-20-007 | TODO | Depends on 20-006. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | +| 8 | POLICY-ENGINE-20-008 | TODO | Depends on 20-007. | Policy · QA Guild / `src/Policy/StellaOps.Policy.Engine` | +| 9 | POLICY-ENGINE-20-009 | TODO | Depends on 20-008. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | +| 10 | POLICY-ENGINE-27-001 | TODO | Depends on 20-009. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | +| 11 | POLICY-ENGINE-27-002 | TODO | Depends on 27-001. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | +| 12 | POLICY-ENGINE-29-001 | TODO | Depends on 27-004. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | +| 13 | POLICY-ENGINE-29-002 | TODO | Depends on 29-001. | Policy · Findings Ledger Guild / `src/Policy/StellaOps.Policy.Engine` | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-08 | Sprint stub; awaiting staffing. | Planning | +| 2025-11-18 | All tasks still awaiting upstream evaluator specs; no progress. | Policy Guild | +| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_124_policy_reasoning.md` to `SPRINT_0124_0001_0001_policy_reasoning.md`; content preserved. | Implementer | + +## Decisions & Risks +- Deterministic evaluator contract missing (blocks 20-002 and downstream chain). +- Console simulation/export contract (POLICY-CONSOLE-23-001) required to unblock 23-002. +- Storage/index schemas TBD; avoid implementation until specs freeze. + +## Next Checkpoints +- Publish deterministic evaluator spec for 20-002 (date TBD). +- Provide Console export/simulation contract for 23-001 to unblock 23-002. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0125_0001_0001_mirror.md b/docs/implplan/SPRINT_0125_0001_0001_mirror.md index 83a8614ec..df6b8f3a8 100644 --- a/docs/implplan/SPRINT_0125_0001_0001_mirror.md +++ b/docs/implplan/SPRINT_0125_0001_0001_mirror.md @@ -20,7 +20,10 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | MIRROR-CRT-56-001 | BLOCKED | Upstream Sprint 110.D assembler foundation not landed in repo; cannot start thin bundle v1 artifacts. | Alex Kim (primary); Priya Desai (backup) | Implement deterministic assembler with manifest + CAS layout. | +| P0 | PREP-MIRROR-CRT-56-001-MILESTONE-0-PUBLISH | DONE (2025-11-19) | Due 2025-11-20 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Published milestone-0 thin bundle plan + sample at `out/mirror/thin/mirror-thin-m0-sample.tar.gz` with SHA256 `bd1013885a27f651e28331c7a240d417d265bd411d09b51b47bd7c2196659674` and layout note in `docs/modules/mirror/milestone-0-thin-bundle.md`. | +| P1 | PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D | TODO | Due 2025-11-22 · Accountable: Alex Kim (primary); Priya Desai (backup) | Alex Kim (primary); Priya Desai (backup) | Upstream Sprint 110.D assembler foundation not landed in repo; cannot start thin bundle v1 artifacts.

Document artefact/deliverable for MIRROR-CRT-56-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-MIRROR-CRT-56-001-ASSEMBLER-HANDOFF | DONE (2025-11-19) | Due 2025-11-22 · Accountable: Mirror Creator Guild | Mirror Creator Guild | Handoff expectations for thin bundle assembler published at `docs/modules/mirror/thin-bundle-assembler.md` (tar layout, manifest fields, determinism rules, hashes). | +| 1 | MIRROR-CRT-56-001 | BLOCKED | PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D | Alex Kim (primary); Priya Desai (backup) | Implement deterministic assembler with manifest + CAS layout. | | 2 | MIRROR-CRT-56-002 | BLOCKED | Depends on MIRROR-CRT-56-001 and PROV-OBS-53-001; upstream assembler missing. | Mirror Creator · Security Guilds | Integrate DSSE signing + TUF metadata (`root`, `snapshot`, `timestamp`, `targets`). | | 3 | MIRROR-CRT-57-001 | BLOCKED | Requires MIRROR-CRT-56-001; assembler foundation missing. | Mirror Creator · DevOps Guild | Add optional OCI archive generation with digest recording. | | 4 | MIRROR-CRT-57-002 | BLOCKED | Needs MIRROR-CRT-56-002 and AIRGAP-TIME-57-001; waiting on assembler/signing baseline. | Mirror Creator · AirGap Time Guild | Embed signed time-anchor metadata. | @@ -34,6 +37,10 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Cleared stray hyphen from PREP-MIRROR-CRT-56-001-UPSTREAM-SPRINT-110-D so MIRROR-CRT-56-001 dependency is resolvable. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Completed PREP-MIRROR-CRT-56-001-MILESTONE-0-PUBLISH: published sample thin bundle + hashes and milestone note (`docs/modules/mirror/milestone-0-thin-bundle.md`). | Implementer | +| 2025-11-19 | Added PREP-MIRROR-CRT-56-001-MILESTONE-0-PUBLISH (DOING) to capture milestone-0 thin bundle plan and hashes to unblock downstream air-gap/console/attestation tracks. | Project Mgmt | | 2025-11-17 | All sprint tasks marked BLOCKED: upstream Sprint 110.D assembler foundation absent from repo; no manifest/CAS layout or samples present to proceed. | Implementer | | 2025-11-17 | Normalised sprint file to standard template; renamed from `SPRINT_125_mirror.md` to `SPRINT_0125_0001_0001_mirror.md`; no semantic task changes. | Project Management | | 2025-11-17 | Coordinator decision: assign primary + backup for MIRROR-CRT-56-001; scope thin bundle v1; downstream tasks may proceed once schema + sample bundle land. | Coordinator | diff --git a/docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..41bbf16b7 --- /dev/null +++ b/docs/implplan/SPRINT_0125_0001_0001_policy_reasoning.md @@ -0,0 +1,68 @@ +# Sprint 0125-0001-0001 · Policy & Reasoning (Policy Engine phase III) + +## Topic & Scope +- Policy Engine simulations/overlays chain (Policy.III): path/scope awareness, metrics, overlays, orchestration, ledger export, snapshot, violation events, severity fusion. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine`. + +## Dependencies & Concurrency +- Upstream: POLICY-ENGINE-29-002 contract/schema required; execute tasks in listed order. +- Concurrency: All current tasks blocked by missing 29-002 path/scope schema. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` + +## Delivery Tracker +| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P0 | PREP-POLICY-ENGINE-29-002-PATH-SCOPE-SCHEMA | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Publish POLICY-ENGINE-29-002 path/scope schema + sample payloads so downstream evaluation tasks can start. | +| P1 | PREP-POLICY-ENGINE-29-004-DEPENDS-ON-29-003 | BLOCKED | Due 2025-11-22 · Accountable: Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 29-003.

Document artefact/deliverable for POLICY-ENGINE-29-004 and publish location so downstream tasks can proceed. | +| P2 | PREP-POLICY-ENGINE-30-001-NEEDS-29-004-OUTPUT | BLOCKED | Due 2025-11-22 · Accountable: Policy · Cartographer Guild / `src/Policy/StellaOps.Policy.Engine` | Policy · Cartographer Guild / `src/Policy/StellaOps.Policy.Engine` | Needs 29-004 outputs.

Document artefact/deliverable for POLICY-ENGINE-30-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-POLICY-ENGINE-30-002-DEPENDS-ON-30-001 | BLOCKED | Due 2025-11-22 · Accountable: Policy · Cartographer Guild / `src/Policy/StellaOps.Policy.Engine` | Policy · Cartographer Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 30-001.

Document artefact/deliverable for POLICY-ENGINE-30-002 and publish location so downstream tasks can proceed. | +| P4 | PREP-POLICY-ENGINE-30-003-DEPENDS-ON-30-002 | BLOCKED | Due 2025-11-22 · Accountable: Policy · Scheduler Guild / `src/Policy/StellaOps.Policy.Engine` | Policy · Scheduler Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 30-002.

Document artefact/deliverable for POLICY-ENGINE-30-003 and publish location so downstream tasks can proceed. | +| P5 | PREP-POLICY-ENGINE-30-101-DEPENDS-ON-30-003 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 30-003.

Document artefact/deliverable for POLICY-ENGINE-30-101 and publish location so downstream tasks can proceed. | +| P6 | PREP-POLICY-ENGINE-31-001-DEPENDS-ON-30-101 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 30-101.

Document artefact/deliverable for POLICY-ENGINE-31-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-POLICY-ENGINE-31-002-DEPENDS-ON-31-001 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 31-001.

Document artefact/deliverable for POLICY-ENGINE-31-002 and publish location so downstream tasks can proceed. | +| P8 | PREP-POLICY-ENGINE-32-101-DEPENDS-ON-31-002 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 31-002.

Document artefact/deliverable for POLICY-ENGINE-32-101 and publish location so downstream tasks can proceed. | +| P9 | PREP-POLICY-ENGINE-33-101-DEPENDS-ON-32-101 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 32-101.

Document artefact/deliverable for POLICY-ENGINE-33-101 and publish location so downstream tasks can proceed. | +| P10 | PREP-POLICY-ENGINE-34-101-DEPENDS-ON-33-101 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 33-101.

Document artefact/deliverable for POLICY-ENGINE-34-101 and publish location so downstream tasks can proceed. | +| P11 | PREP-POLICY-ENGINE-35-201-DEPENDS-ON-34-101 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 34-101.

Document artefact/deliverable for POLICY-ENGINE-35-201 and publish location so downstream tasks can proceed. | +| P12 | PREP-POLICY-ENGINE-38-201-DEPENDS-ON-35-201 | BLOCKED | Due 2025-11-22 · Accountable: Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 35-201.

Document artefact/deliverable for POLICY-ENGINE-38-201 and publish location so downstream tasks can proceed. | +| P13 | PREP-POLICY-ENGINE-40-001-DEPENDS-ON-38-201 | BLOCKED | Due 2025-11-22 · Accountable: Policy · Concelier Guild / `src/Policy/StellaOps.Policy.Engine` | Policy · Concelier Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 38-201.

Document artefact/deliverable for POLICY-ENGINE-40-001 and publish location so downstream tasks can proceed. | +| P14 | PREP-POLICY-ENGINE-40-002-DEPENDS-ON-40-001 | BLOCKED | Due 2025-11-22 · Accountable: Policy · Excititor Guild / `src/Policy/StellaOps.Policy.Engine` | Policy · Excititor Guild / `src/Policy/StellaOps.Policy.Engine` | Depends on 40-001.

Document artefact/deliverable for POLICY-ENGINE-40-002 and publish location so downstream tasks can proceed. | +| 1 | POLICY-ENGINE-29-003 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-29-002-PATH-SCOPE-SCHEMA. | Policy · SBOM Service Guild / `src/Policy/StellaOps.Policy.Engine` | Path/scope aware evaluation. | +| 2 | POLICY-ENGINE-29-004 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-29-004-DEPENDS-ON-29-003 | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/logging for path-aware eval. | +| 3 | POLICY-ENGINE-30-001 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-001-NEEDS-29-004-OUTPUT | Policy · Cartographer Guild / `src/Policy/StellaOps.Policy.Engine` | Overlay projection contract. | +| 4 | POLICY-ENGINE-30-002 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-002-DEPENDS-ON-30-001 | Policy · Cartographer Guild / `src/Policy/StellaOps.Policy.Engine` | Simulation bridge. | +| 5 | POLICY-ENGINE-30-003 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-003-DEPENDS-ON-30-002 | Policy · Scheduler Guild / `src/Policy/StellaOps.Policy.Engine` | Change events. | +| 6 | POLICY-ENGINE-30-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-101-DEPENDS-ON-30-003 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Trust weighting UI/API. | +| 7 | POLICY-ENGINE-31-001 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-31-001-DEPENDS-ON-30-101 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Advisory AI knobs. | +| 8 | POLICY-ENGINE-31-002 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-31-002-DEPENDS-ON-31-001 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Batch context endpoint. | +| 9 | POLICY-ENGINE-32-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-32-101-DEPENDS-ON-31-002 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Orchestrator job schema. | +| 10 | POLICY-ENGINE-33-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-33-101-DEPENDS-ON-32-101 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Worker implementation. | +| 11 | POLICY-ENGINE-34-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-34-101-DEPENDS-ON-33-101 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Ledger export. | +| 12 | POLICY-ENGINE-35-201 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-35-201-DEPENDS-ON-34-101 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Snapshot API. | +| 13 | POLICY-ENGINE-38-201 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-38-201-DEPENDS-ON-35-201 | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Violation events. | +| 14 | POLICY-ENGINE-40-001 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-40-001-DEPENDS-ON-38-201 | Policy · Concelier Guild / `src/Policy/StellaOps.Policy.Engine` | Severity fusion. | +| 15 | POLICY-ENGINE-40-002 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-40-002-DEPENDS-ON-40-001 | Policy · Excititor Guild / `src/Policy/StellaOps.Policy.Engine` | Conflict handling. | + +## Notes & Risks +- POLICY-ENGINE-29-002 contract/schema missing; cascades block entire chain (1–15). Need published schema + sample payloads to proceed. + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Added PREP-POLICY-ENGINE-29-002-PATH-SCOPE-SCHEMA and pointed POLICY-ENGINE-29-003 dependency at it. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked PREP tasks P0–P14 BLOCKED: base path/scope schema (29-002) and downstream evaluation/observability/overlay/export contracts are still missing, keeping the entire POLICY-ENGINE chain blocked. | Project Mgmt | +| 2025-11-08 | Sprint created; awaiting upstream contract. | Planning | +| 2025-11-18 | Re-confirmed all tasks blocked; upstream schema still absent. | Policy Guild | +| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_125_policy_reasoning.md` to `SPRINT_0125_0001_0001_policy_reasoning.md`; content preserved. | Implementer | + +## Decisions & Risks +- Blocked until POLICY-ENGINE-29-002 contract drops. + +## Next Checkpoints +- Publish POLICY-ENGINE-29-002 path/scope schema (date TBD). diff --git a/docs/implplan/SPRINT_0126_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0126_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..e5cbdebe0 --- /dev/null +++ b/docs/implplan/SPRINT_0126_0001_0001_policy_reasoning.md @@ -0,0 +1,48 @@ +# Sprint 0126-0001-0001 · Policy & Reasoning (Policy Engine phase IV) + +## Topic & Scope +- Policy Engine IV: SPL compiler/evaluator pipeline, events, storage, exceptions, reachability/exploitability integration. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine` (and `src/Policy/__Libraries/StellaOps.Policy`). + +## Dependencies & Concurrency +- Upstream: Sprint 120.C Policy.III must land. +- Concurrency: execute tasks in listed order; all currently TODO. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` + +## Delivery Tracker +| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | POLICY-ENGINE-40-003 | TODO | Depends on 40-002. | Policy · Web Scanner Guild / `src/Policy/StellaOps.Policy.Engine` | API/SDK utilities with evidence summaries. | +| 2 | POLICY-ENGINE-50-001 | TODO | Depends on 40-003. | Policy · Platform Security / `src/Policy/StellaOps.Policy.Engine` | SPL compiler, signed bundle, storage. | +| 3 | POLICY-ENGINE-50-002 | TODO | Depends on 50-001. | Policy · Runtime Guild / `src/Policy/StellaOps.Policy.Engine` | Runtime evaluator with deterministic caching. | +| 4 | POLICY-ENGINE-50-003 | TODO | Depends on 50-002. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/tracing/logging for compile/eval. | +| 5 | POLICY-ENGINE-50-004 | TODO | Depends on 50-003. | Policy · Platform Events Guild / `src/Policy/StellaOps.Policy.Engine` | Event pipeline for updates/re-eval. | +| 6 | POLICY-ENGINE-50-005 | TODO | Depends on 50-004. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Collections/indexes for policy artifacts. | +| 7 | POLICY-ENGINE-50-006 | TODO | Depends on 50-005. | Policy · QA Guild / `src/Policy/StellaOps.Policy.Engine` | Explainer persistence/retrieval. | +| 8 | POLICY-ENGINE-50-007 | TODO | Depends on 50-006. | Policy · Scheduler Worker Guild / `src/Policy/StellaOps.Policy.Engine` | Evaluation worker host/orchestration. | +| 9 | POLICY-ENGINE-60-001 | TODO | Depends on 50-007. | Policy · SBOM Service Guild / `src/Policy/StellaOps.Policy.Engine` | Redis effective decision maps. | +| 10 | POLICY-ENGINE-60-002 | TODO | Depends on 60-001. | Policy · BE-Base Platform Guild / `src/Policy/StellaOps.Policy.Engine` | Simulation bridge for Graph What-if. | +| 11 | POLICY-ENGINE-70-002 | TODO | Depends on 60-002. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Exception collections + migrations. | +| 12 | POLICY-ENGINE-70-003 | TODO | Depends on 70-002. | Policy · Runtime Guild / `src/Policy/StellaOps.Policy.Engine` | Redis exception cache. | +| 13 | POLICY-ENGINE-70-004 | TODO | Depends on 70-003. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Exception metrics/tracing/logging. | +| 14 | POLICY-ENGINE-70-005 | TODO | Depends on 70-004. | Policy · Scheduler Worker Guild / `src/Policy/StellaOps.Policy.Engine` | Exception activation/expiry + events. | +| 15 | POLICY-ENGINE-80-001 | TODO | Depends on 70-005. | Policy · Signals Guild / `src/Policy/StellaOps.Policy.Engine` | Reachability/exploitability inputs into evaluation. | +| 16 | POLICY-RISK-90-001 | TODO | — | Policy · Scanner Guild / `src/Policy/StellaOps.Policy.Engine` | Entropy penalty ingestion + trust algebra. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub; awaiting upstream phases. | Planning | +| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_126_policy_reasoning.md` to `SPRINT_0126_0001_0001_policy_reasoning.md`; content preserved. | Implementer | + +## Decisions & Risks +- All tasks depend on prior Policy phases; sequencing must be maintained. +- Entropy/trust algebra inputs (POLICY-RISK-90-001) require Scanner contract. + +## Next Checkpoints +- Align SPL compiler/evaluator contracts once upstream phases land (date TBD). diff --git a/docs/implplan/SPRINT_0127_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0127_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..89b893d65 --- /dev/null +++ b/docs/implplan/SPRINT_0127_0001_0001_policy_reasoning.md @@ -0,0 +1,51 @@ +# Sprint 0127-0001-0001 · Policy & Reasoning (Policy Engine phase V) + +## Topic & Scope +- Policy Engine V: reachability integration, telemetry, incident mode, and initial RiskProfile schema work. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine` and `src/Policy/__Libraries/StellaOps.Policy.RiskProfile`. + +## Dependencies & Concurrency +- Upstream: Sprint 120.C Policy.IV must land. +- Concurrency: execute tasks in listed order; all tasks currently TODO. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` + +## Delivery Tracker +| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-POLICY-RISK-66-001-RISKPROFILE-LIBRARY-S | TODO | Due 2025-11-22 · Accountable: Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | RiskProfile library scaffold absent (`src/Policy/StellaOps.Policy.RiskProfile` contains only AGENTS.md); need project + storage contract to place schema/validators.

Document artefact/deliverable for POLICY-RISK-66-001 and publish location so downstream tasks can proceed. | +| 1 | POLICY-ENGINE-80-002 | TODO | Depends on 80-001. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Join reachability facts + Redis caches. | +| 2 | POLICY-ENGINE-80-003 | TODO | Depends on 80-002. | Policy · Policy Editor Guild / `src/Policy/StellaOps.Policy.Engine` | SPL predicates/actions reference reachability. | +| 3 | POLICY-ENGINE-80-004 | TODO | Depends on 80-003. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/traces for signals usage. | +| 4 | POLICY-OBS-50-001 | TODO | — | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Telemetry core for API/worker hosts. | +| 5 | POLICY-OBS-51-001 | TODO | Depends on 50-001. | Policy · DevOps Guild / `src/Policy/StellaOps.Policy.Engine` | Golden-signal metrics + SLOs. | +| 6 | POLICY-OBS-52-001 | TODO | Depends on 51-001. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Timeline events for evaluate/decision flows. | +| 7 | POLICY-OBS-53-001 | TODO | Depends on 52-001. | Policy · Evidence Locker Guild / `src/Policy/StellaOps.Policy.Engine` | Evaluation evidence bundles + manifests. | +| 8 | POLICY-OBS-54-001 | TODO | Depends on 53-001. | Policy · Provenance Guild / `src/Policy/StellaOps.Policy.Engine` | DSSE attestations for evaluations. | +| 9 | POLICY-OBS-55-001 | TODO | Depends on 54-001. | Policy · DevOps Guild / `src/Policy/StellaOps.Policy.Engine` | Incident mode sampling overrides. | +| 10 | POLICY-RISK-66-001 | BLOCKED (2025-11-19) | PREP-POLICY-RISK-66-001-RISKPROFILE-LIBRARY-S | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | RiskProfile JSON schema + validator stubs. | +| 11 | POLICY-RISK-66-002 | TODO | Depends on 66-001. | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Inheritance/merge + deterministic hashing. | +| 12 | POLICY-RISK-66-003 | TODO | Depends on 66-002. | Policy · Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.Engine` | Integrate RiskProfile into Policy Engine config. | +| 13 | POLICY-RISK-66-004 | TODO | Depends on 66-003. | Policy · Risk Profile Schema Guild / `src/Policy/__Libraries/StellaOps.Policy` | Load/save RiskProfiles; validation diagnostics. | +| 14 | POLICY-RISK-67-001 | TODO | Depends on 66-004. | Policy · Risk Engine Guild / `src/Policy/StellaOps.Policy.Engine` | Trigger scoring jobs on new/updated findings. | +| 15 | POLICY-RISK-67-001 | TODO | Depends on 67-001. | Risk Profile Schema Guild · Policy Engine Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Profile storage/versioning lifecycle. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-08 | Sprint stub; awaiting upstream phases. | Planning | +| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_127_policy_reasoning.md` to `SPRINT_0127_0001_0001_policy_reasoning.md`; content preserved. | Implementer | +| 2025-11-19 | Attempted POLICY-RISK-66-001; blocked because `src/Policy/StellaOps.Policy.RiskProfile` lacks a project/scaffold to host schema + validators. Needs project creation + contract placement guidance. | Implementer | + +## Decisions & Risks +- Reachability inputs (80-001) prerequisite; not yet delivered. +- RiskProfile schema undefined; blocks risk chain if delayed. + +## Next Checkpoints +- Define reachability input contract (date TBD). +- Draft RiskProfile schema baseline (date TBD). \ No newline at end of file diff --git a/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..408b72edd --- /dev/null +++ b/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md @@ -0,0 +1,46 @@ +# Sprint 0128-0001-0001 · Policy & Reasoning (Policy Engine phase VI) + +## Topic & Scope +- Policy Engine VI: Risk profile lifecycle APIs, simulation bridge, overrides, exports, and SPL schema evolution. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine` and `src/Policy/__Libraries/StellaOps.Policy`. + +## Dependencies & Concurrency +- Upstream: Policy.V (0127) reachability/risk groundwork must land first. +- Concurrency: execute tasks in listed order; all tasks currently TODO. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` + +## Delivery Tracker +| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | POLICY-RISK-67-002 | TODO | Depends on 67-001. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Risk profile lifecycle APIs. | +| 2 | POLICY-RISK-67-002 | TODO | Depends on 67-002. | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Publish `.well-known/risk-profile-schema` + CLI validation. | +| 3 | POLICY-RISK-67-003 | TODO | Depends on 67-002. | Policy · Risk Engine Guild / `src/Policy/__Libraries/StellaOps.Policy` | Risk simulations + breakdowns. | +| 4 | POLICY-RISK-68-001 | TODO | Depends on 67-003. | Policy · Policy Studio Guild / `src/Policy/StellaOps.Policy.Engine` | Simulation API for Policy Studio. | +| 5 | POLICY-RISK-68-001 | TODO | Depends on 68-001. | Risk Profile Schema Guild · Authority Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Scope selectors, precedence rules, Authority attachment. | +| 6 | POLICY-RISK-68-002 | TODO | Depends on 68-001. | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Override/adjustment support with audit metadata. | +| 7 | POLICY-RISK-68-002 | TODO | Depends on 68-002. | Policy · Export Guild / `src/Policy/__Libraries/StellaOps.Policy` | Export/import RiskProfiles with signatures. | +| 8 | POLICY-RISK-69-001 | TODO | Depends on 68-002. | Policy · Notifications Guild / `src/Policy/StellaOps.Policy.Engine` | Notifications on profile lifecycle/threshold changes. | +| 9 | POLICY-RISK-70-001 | TODO | Depends on 69-001. | Policy · Export Guild / `src/Policy/StellaOps.Policy.Engine` | Air-gap export/import for profiles with signatures. | +| 10 | POLICY-SPL-23-001 | TODO | — | Policy · Language Infrastructure Guild / `src/Policy/__Libraries/StellaOps.Policy` | Define SPL v1 schema + fixtures. | +| 11 | POLICY-SPL-23-002 | TODO | Depends on 23-001. | Policy Guild / `src/Policy/__Libraries/StellaOps.Policy` | Canonicalizer + content hashing. | +| 12 | POLICY-SPL-23-003 | TODO | Depends on 23-002. | Policy Guild / `src/Policy/__Libraries/StellaOps.Policy` | Layering/override engine + tests. | +| 13 | POLICY-SPL-23-004 | TODO | Depends on 23-003. | Policy · Audit Guild / `src/Policy/__Libraries/StellaOps.Policy` | Explanation tree model + persistence. | +| 14 | POLICY-SPL-23-005 | TODO | Depends on 23-004. | Policy · DevEx Guild / `src/Policy/__Libraries/StellaOps.Policy` | Migration tool to baseline SPL packs. | +| 15 | POLICY-SPL-24-001 | TODO | Depends on 23-005. | Policy · Signals Guild / `src/Policy/__Libraries/StellaOps.Policy` | Extend SPL with reachability/exploitability predicates. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub; awaiting upstream phases. | Planning | +| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_128_policy_reasoning.md` to `SPRINT_0128_0001_0001_policy_reasoning.md`; content preserved. | Implementer | + +## Decisions & Risks +- Risk profile contracts and SPL schema not yet defined; entire chain remains TODO pending upstream specs. + +## Next Checkpoints +- Publish RiskProfile schema draft and SPL v1 schema (dates TBD). diff --git a/docs/implplan/SPRINT_0129_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0129_0001_0001_policy_reasoning.md new file mode 100644 index 000000000..2129d28d7 --- /dev/null +++ b/docs/implplan/SPRINT_0129_0001_0001_policy_reasoning.md @@ -0,0 +1,67 @@ +# Sprint 0129-0001-0001 · Policy & Reasoning (Policy Engine/Risk/VEX/Vuln Registry phase VII) + +## Topic & Scope +- Policy VII plus companion tracks (RiskEngine, VexLens, VulnExplorer, Policy Registry): registries, simulations, promotions, reachability/exploitability inputs, VEX consensus, and vulnerability API surface. +- **Working directory:** `src/Policy/StellaOps.Policy.Engine`, `src/Policy/StellaOps.Policy.Registry`, `src/RiskEngine/StellaOps.RiskEngine`, `src/VexLens`, `src/VulnExplorer`. + +## Dependencies & Concurrency +- Upstream: Policy.VI (0128) + Risk/VEX foundations; execute tasks in listed order; all tasks currently TODO. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` +- Module docs for Registry, RiskEngine, VexLens, VulnExplorer as applicable. + +## Delivery Tracker +| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | POLICY-TEN-48-001 | TODO | Tenant/project columns + RLS policy; needs platform-approved design. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Tenant scoping + rationale IDs with tenant metadata. | +| 2 | REGISTRY-API-27-001 | TODO | OpenAPI spec pending. | Policy Registry Guild / `src/Policy/StellaOps.Policy.Registry` | Define Registry API spec + typed clients. | +| 3 | REGISTRY-API-27-002 | TODO | Depends on 27-001. | Policy Registry Guild / `src/Policy/StellaOps.Policy.Registry` | Workspace storage with CRUD + history. | +| 4 | REGISTRY-API-27-003 | TODO | Depends on 27-002. | Policy Registry Guild / `src/Policy/StellaOps.Policy.Registry` | Compile endpoint integration. | +| 5 | REGISTRY-API-27-004 | TODO | Depends on 27-003. | Policy Registry Guild / `src/Policy/StellaOps.Policy.Registry` | Quick simulation API. | +| 6 | REGISTRY-API-27-005 | TODO | Depends on 27-004. | Policy Registry · Scheduler Guild / `src/Policy/StellaOps.Policy.Registry` | Batch simulation orchestration. | +| 7 | REGISTRY-API-27-006 | TODO | Depends on 27-005. | Policy Registry Guild / `src/Policy/StellaOps.Policy.Registry` | Review workflow with audit trails. | +| 8 | REGISTRY-API-27-007 | TODO | Depends on 27-006. | Policy Registry · Security Guild / `src/Policy/StellaOps.Policy.Registry` | Publish pipeline with signing/attestations. | +| 9 | REGISTRY-API-27-008 | TODO | Depends on 27-007. | Policy Registry Guild / `src/Policy/StellaOps.Policy.Registry` | Promotion bindings per tenant/environment. | +| 10 | REGISTRY-API-27-009 | TODO | Depends on 27-008. | Policy Registry · Observability Guild / `src/Policy/StellaOps.Policy.Registry` | Metrics/logs/traces + dashboards. | +| 11 | REGISTRY-API-27-010 | TODO | Depends on 27-009. | Policy Registry · QA Guild / `src/Policy/StellaOps.Policy.Registry` | Test suites + fixtures. | +| 12 | RISK-ENGINE-66-001 | TODO | Scaffold scoring service; needs deterministic harness. | Risk Engine Guild / `src/RiskEngine/StellaOps.RiskEngine` | Scoring service + job queue. | +| 13 | RISK-ENGINE-66-002 | TODO | Depends on 66-001. | Risk Engine Guild / `src/RiskEngine/StellaOps.RiskEngine` | Default transforms/clamping/gating. | +| 14 | RISK-ENGINE-67-001 | TODO | Depends on 66-002. | Risk Engine Guild · Concelier Guild / `src/RiskEngine/StellaOps.RiskEngine` | CVSS/KEV providers. | +| 15 | RISK-ENGINE-67-002 | TODO | Depends on 67-001. | Risk Engine Guild · Excitor Guild / `src/RiskEngine/StellaOps.RiskEngine` | VEX gate provider. | +| 16 | RISK-ENGINE-67-003 | TODO | Depends on 67-002. | Risk Engine Guild · Policy Engine Guild / `src/RiskEngine/StellaOps.RiskEngine` | Fix availability/criticality/exposure providers. | +| 17 | RISK-ENGINE-68-001 | TODO | Depends on 67-003. | Risk Engine Guild · Findings Ledger Guild / `src/RiskEngine/StellaOps.RiskEngine` | Persist results + explanations to Findings Ledger. | +| 18 | RISK-ENGINE-68-002 | TODO | Depends on 68-001. | Risk Engine Guild / `src/RiskEngine/StellaOps.RiskEngine` | APIs for jobs/results/simulations. | +| 19 | VEXLENS-30-001 | TODO | — | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Normalize CSAF/OpenVEX/CycloneDX VEX. | +| 20 | VEXLENS-30-002 | TODO | Depends on 30-001. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Product mapping library. | +| 21 | VEXLENS-30-003 | TODO | Depends on 30-002. | VEX Lens Guild · Issuer Directory Guild / `src/VexLens/StellaOps.VexLens` | Signature verification. | +| 22 | VEXLENS-30-004 | TODO | Depends on 30-003. | VEX Lens · Policy Guild / `src/VexLens/StellaOps.VexLens` | Trust weighting engine. | +| 23 | VEXLENS-30-005 | TODO | Depends on 30-004. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Consensus algorithm. | +| 24 | VEXLENS-30-006 | TODO | Depends on 30-005. | VEX Lens · Findings Ledger Guild / `src/VexLens/StellaOps.VexLens` | Consensus projection storage/events. | +| 25 | VEXLENS-30-007 | TODO | Depends on 30-006. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Consensus APIs + OpenAPI. | +| 26 | VEXLENS-30-008 | TODO | Depends on 30-007. | VEX Lens · Policy Guild / `src/VexLens/StellaOps.VexLens` | Integrate consensus with Policy Engine + Vuln Explorer. | +| 27 | VEXLENS-30-009 | TODO | Depends on 30-008. | VEX Lens · Observability Guild / `src/VexLens/StellaOps.VexLens` | Metrics/logs/traces. | +| 28 | VEXLENS-30-010 | TODO | Depends on 30-009. | VEX Lens · QA Guild / `src/VexLens/StellaOps.VexLens` | Tests + determinism harness. | +| 29 | VEXLENS-30-011 | TODO | Depends on 30-010. | VEX Lens · DevOps Guild / `src/VexLens/StellaOps.VexLens` | Deployment/runbooks/offline kit. | +| 30 | VEXLENS-AIAI-31-001 | TODO | Depends on 30-011. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Consensus rationale API enhancements. | +| 31 | VEXLENS-AIAI-31-002 | TODO | Depends on AIAI-31-001. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Caching hooks for Advisory AI. | +| 32 | VEXLENS-EXPORT-35-001 | TODO | Depends on 30-011. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Consensus snapshot API for mirror bundles. | +| 33 | VEXLENS-ORCH-33-001 | TODO | Depends on 30-011. | VEX Lens · Orchestrator Guild / `src/VexLens/StellaOps.VexLens` | Register consensus compute job type. | +| 34 | VEXLENS-ORCH-34-001 | TODO | Depends on ORCH-33-001. | VEX Lens Guild / `src/VexLens/StellaOps.VexLens` | Emit consensus completion events to orchestrator ledger. | +| 35 | VULN-API-29-001 | TODO | — | Vuln Explorer API Guild / `src/VulnExplorer/StellaOps.VulnExplorer.Api` | Define VulnExplorer OpenAPI spec. | +| 36 | VULN-API-29-002 | TODO | Depends on 29-001. | Vuln Explorer API Guild / `src/VulnExplorer/StellaOps.VulnExplorer.Api` | Implement list/query endpoints. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub; awaiting upstream specs. | Planning | +| 2025-11-19 | Normalized to standard template and renamed from `SPRINT_129_policy_reasoning.md` to `SPRINT_0129_0001_0001_policy_reasoning.md`; content preserved. | Implementer | + +## Decisions & Risks +- Multiple upstream specs missing (Registry API, Risk Engine contracts, VEX consensus schema, VulnExplorer API); all tasks remain TODO until contracts land. + +## Next Checkpoints +- Publish Registry API + RiskEngine/VexLens/VulnExplorer contracts (dates TBD). diff --git a/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md index f8955b728..cc14076b6 100644 --- a/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md +++ b/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md @@ -21,21 +21,25 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | SCANNER-ANALYZERS-DENO-26-009 | DOING | Implement loader/trace shim per `docs/modules/scanner/design/deno-runtime-shim.md`; serializer/metadata/tests done. | Deno Analyzer Guild · Signals Guild | Optional runtime evidence hooks capturing module loads and permissions with path hashing during harnessed execution. | +| P1 | PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC | TODO | Due 2025-11-22 · Accountable: Java Analyzer Guild | Java Analyzer Guild | Tests blocked: repo build fails in Concelier (CoreLinksets missing) and targeted Java analyzer test run stalls; retry once dependencies fixed or CI available.

Document artefact/deliverable for SCANNER-ANALYZERS-JAVA-21-005 and publish location so downstream tasks can proceed. | +| P2 | PREP-SCANNER-ANALYZERS-JAVA-21-008-WAITING-ON | TODO | Due 2025-11-22 · Accountable: Java Analyzer Guild | Java Analyzer Guild | Waiting on 21-007 completion and resolver authoring bandwidth.

Document artefact/deliverable for SCANNER-ANALYZERS-JAVA-21-008 and publish location so downstream tasks can proceed. | +| P3 | PREP-SCANNER-ANALYZERS-LANG-11-001-DOTNET-TES | TODO | Due 2025-11-22 · Accountable: StellaOps.Scanner EPDR Guild · Language Analyzer Guild | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | `dotnet test` hangs/returns empty output; needs clean runner/CI diagnostics.

Document artefact/deliverable for SCANNER-ANALYZERS-LANG-11-001 and publish location so downstream tasks can proceed. | +| 1 | SCANNER-ANALYZERS-DENO-26-009 | BLOCKED (2025-11-19) | Waiting on runtime shim fixtures + CI runner; design `deno-runtime-shim.md` drafted but tests cannot run. | Deno Analyzer Guild · Signals Guild | Optional runtime evidence hooks capturing module loads and permissions with path hashing during harnessed execution. | | 2 | SCANNER-ANALYZERS-DENO-26-010 | TODO | After 26-009, wire CLI (`stella deno trace`) + Worker/Offline Kit using runtime NDJSON contract. | Deno Analyzer Guild · DevOps Guild | Package analyzer plug-in and surface CLI/worker commands with offline documentation. | | 3 | SCANNER-ANALYZERS-DENO-26-011 | TODO | Implement policy signal emitter using runtime metadata once trace shim lands. | Deno Analyzer Guild | Policy signal emitter for capabilities (net/fs/env/ffi/process/crypto), remote origins, npm usage, wasm modules, and dynamic-import warnings. | -| 4 | SCANNER-ANALYZERS-JAVA-21-005 | BLOCKED (2025-11-17) | Tests blocked: repo build fails in Concelier (CoreLinksets missing) and targeted Java analyzer test run stalls; retry once dependencies fixed or CI available. | Java Analyzer Guild | Framework config extraction: Spring Boot imports, spring.factories, application properties/yaml, Jakarta web.xml/fragments, JAX-RS/JPA/CDI/JAXB configs, logging files, Graal native-image configs. | +| 4 | SCANNER-ANALYZERS-JAVA-21-005 | BLOCKED (2025-11-17) | PREP-SCANNER-ANALYZERS-JAVA-21-005-TESTS-BLOC | Java Analyzer Guild | Framework config extraction: Spring Boot imports, spring.factories, application properties/yaml, Jakarta web.xml/fragments, JAX-RS/JPA/CDI/JAXB configs, logging files, Graal native-image configs. | | 5 | SCANNER-ANALYZERS-JAVA-21-006 | TODO | Needs outputs from 21-005. | Java Analyzer Guild | JNI/native hint scanner detecting native methods, System.load/Library literals, bundled native libs, Graal JNI configs; emit `jni-load` edges. | | 6 | SCANNER-ANALYZERS-JAVA-21-007 | TODO | After 21-006; align manifest parsing with resolver. | Java Analyzer Guild | Signature and manifest metadata collector capturing JAR signature structure, signers, and manifest loader attributes (Main-Class, Agent-Class, Start-Class, Class-Path). | -| 7 | SCANNER-ANALYZERS-JAVA-21-008 | BLOCKED (2025-10-27) | Waiting on 21-007 completion and resolver authoring bandwidth. | Java Analyzer Guild | Implement resolver + AOC writer emitting entrypoints, components, and edges (jpms, cp, spi, reflect, jni) with reason codes and confidence. | +| 7 | SCANNER-ANALYZERS-JAVA-21-008 | BLOCKED (2025-10-27) | PREP-SCANNER-ANALYZERS-JAVA-21-008-WAITING-ON | Java Analyzer Guild | Implement resolver + AOC writer emitting entrypoints, components, and edges (jpms, cp, spi, reflect, jni) with reason codes and confidence. | | 8 | SCANNER-ANALYZERS-JAVA-21-009 | TODO | Unblock when 21-008 lands; prepare fixtures in parallel where safe. | Java Analyzer Guild · QA Guild | Comprehensive fixtures (modular app, boot fat jar, war, ear, MR-jar, jlink image, JNI, reflection heavy, signed jar, microprofile) with golden outputs and perf benchmarks. | | 9 | SCANNER-ANALYZERS-JAVA-21-010 | TODO | After 21-009; requires runtime capture design. | Java Analyzer Guild · Signals Guild | Optional runtime ingestion via Java agent + JFR reader capturing class load, ServiceLoader, System.load events with path scrubbing; append-only runtime edges (`runtime-class`/`runtime-spi`/`runtime-load`). | | 10 | SCANNER-ANALYZERS-JAVA-21-011 | TODO | Depends on 21-010; finalize DI/manifest registration and docs. | Java Analyzer Guild · DevOps Guild | Package analyzer as restart-time plug-in, update Offline Kit docs, add CLI/worker hooks for Java inspection commands. | -| 11 | SCANNER-ANALYZERS-LANG-11-001 | BLOCKED (2025-11-17) | `dotnet test` hangs/returns empty output; needs clean runner/CI diagnostics. | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | Entrypoint resolver mapping project/publish artifacts to entrypoint identities (assembly name, MVID, TFM, RID) and environment profiles; output normalized `entrypoints[]` with deterministic IDs. | +| 11 | SCANNER-ANALYZERS-LANG-11-001 | BLOCKED (2025-11-17) | PREP-SCANNER-ANALYZERS-LANG-11-001-DOTNET-TES | StellaOps.Scanner EPDR Guild · Language Analyzer Guild | Entrypoint resolver mapping project/publish artifacts to entrypoint identities (assembly name, MVID, TFM, RID) and environment profiles; output normalized `entrypoints[]` with deterministic IDs. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-17 | Normalised sprint file to standard template and renamed from `SPRINT_131_scanner_surface.md` to `SPRINT_0131_scanner_surface.md`; no semantic changes. | Planning | | 2025-11-17 | Attempted `./tools/dotnet-filter.sh test src/Scanner/StellaOps.Scanner.sln --no-restore`; build ran ~72s compiling scanner/all projects without completing tests, then aborted locally to avoid runaway build. Follow-up narrow build `dotnet build src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.csproj` also stalled ~28s in target resolution before manual stop. Blocker persists; needs clean CI runner or scoped test project to finish LANG-11-001 validation. | Implementer | | 2025-11-17 | Started SCANNER-ANALYZERS-JAVA-21-005: initial framework config extraction (Spring configs, JPA/CDI/JAXB, logging, Graal native-image) implemented with evidence + metadata; added regression test scaffold. | Implementer | diff --git a/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md index 093e01a23..b36dc8813 100644 --- a/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md +++ b/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md @@ -22,12 +22,17 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-SCANNER-ANALYZERS-LANG-11-003-DEPENDS-ON | TODO | Due 2025-11-22 · Accountable: StellaOps.Scanner EPDR Guild; Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | StellaOps.Scanner EPDR Guild; Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Depends on 11-002; blocked until upstream static analyzer available.

Document artefact/deliverable for SCANNER-ANALYZERS-LANG-11-003 and publish location so downstream tasks can proceed. | +| P2 | PREP-SCANNER-ANALYZERS-LANG-11-004-DEPENDS-ON | TODO | Due 2025-11-22 · Accountable: StellaOps.Scanner EPDR Guild; SBOM Service Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | StellaOps.Scanner EPDR Guild; SBOM Service Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Depends on 11-003; no upstream static/runtime outputs yet.

Document artefact/deliverable for SCANNER-ANALYZERS-LANG-11-004 and publish location so downstream tasks can proceed. | +| P3 | PREP-SCANNER-ANALYZERS-LANG-11-005-DEPENDS-ON | TODO | Due 2025-11-22 · Accountable: StellaOps.Scanner EPDR Guild; QA Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | StellaOps.Scanner EPDR Guild; QA Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Depends on 11-004; fixtures deferred until analyzer outputs exist.

Document artefact/deliverable for SCANNER-ANALYZERS-LANG-11-005 and publish location so downstream tasks can proceed. | +| P4 | PREP-SCANNER-ANALYZERS-NATIVE-20-002-AWAIT-DE | TODO | Due 2025-11-22 · Accountable: Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Await declared-dependency writer/contract to emit edges.

Document artefact/deliverable for SCANNER-ANALYZERS-NATIVE-20-002 and publish location so downstream tasks can proceed. | +| P5 | PREP-SCANNER-ANALYZERS-NODE-22-001-NEEDS-ISOL | TODO | Due 2025-11-22 · Accountable: Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Needs isolated runner or scoped build graph to execute targeted tests without full-solution fan-out.

Document artefact/deliverable for SCANNER-ANALYZERS-NODE-22-001 and publish location so downstream tasks can proceed. | | 1 | SCANNER-ANALYZERS-LANG-11-002 | BLOCKED | Await upstream SCANNER-ANALYZERS-LANG-11-001 design/outputs to extend static analyzer | StellaOps.Scanner EPDR Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Implement static analyzer (IL + reflection heuristics) capturing AssemblyRef, ModuleRef/PInvoke, DynamicDependency, reflection literals, DI patterns, and custom AssemblyLoadContext probing hints; emit dependency edges with reason codes and confidence. | -| 2 | SCANNER-ANALYZERS-LANG-11-003 | BLOCKED | Depends on 11-002; blocked until upstream static analyzer available | StellaOps.Scanner EPDR Guild; Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Ingest optional runtime evidence (AssemblyLoad, Resolving, P/Invoke) via event listener harness; merge runtime edges with static/declared ones and attach reason codes/confidence. | -| 3 | SCANNER-ANALYZERS-LANG-11-004 | BLOCKED | Depends on 11-003; no upstream static/runtime outputs yet | StellaOps.Scanner EPDR Guild; SBOM Service Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Produce normalized observation export to Scanner writer: entrypoints + dependency edges + environment profiles (AOC compliant); wire to SBOM service entrypoint tagging. | -| 4 | SCANNER-ANALYZERS-LANG-11-005 | BLOCKED | Depends on 11-004; fixtures deferred until analyzer outputs exist | StellaOps.Scanner EPDR Guild; QA Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Add comprehensive fixtures/benchmarks covering framework-dependent, self-contained, single-file, trimmed, NativeAOT, multi-RID scenarios; include explain traces and perf benchmarks vs previous analyzer. | +| 2 | SCANNER-ANALYZERS-LANG-11-003 | BLOCKED | PREP-SCANNER-ANALYZERS-LANG-11-003-DEPENDS-ON | StellaOps.Scanner EPDR Guild; Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Ingest optional runtime evidence (AssemblyLoad, Resolving, P/Invoke) via event listener harness; merge runtime edges with static/declared ones and attach reason codes/confidence. | +| 3 | SCANNER-ANALYZERS-LANG-11-004 | BLOCKED | PREP-SCANNER-ANALYZERS-LANG-11-004-DEPENDS-ON | StellaOps.Scanner EPDR Guild; SBOM Service Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Produce normalized observation export to Scanner writer: entrypoints + dependency edges + environment profiles (AOC compliant); wire to SBOM service entrypoint tagging. | +| 4 | SCANNER-ANALYZERS-LANG-11-005 | BLOCKED | PREP-SCANNER-ANALYZERS-LANG-11-005-DEPENDS-ON | StellaOps.Scanner EPDR Guild; QA Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | Add comprehensive fixtures/benchmarks covering framework-dependent, self-contained, single-file, trimmed, NativeAOT, multi-RID scenarios; include explain traces and perf benchmarks vs previous analyzer. | | 5 | SCANNER-ANALYZERS-NATIVE-20-001 | DONE (2025-11-18) | Format detector completed; ELF interpreter + build-id extraction fixed; tests passing (`dotnet test ...Native.Tests --no-build`). | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Implement format detector and binary identity model supporting ELF, PE/COFF, and Mach-O (including fat slices); capture arch, OS, build-id/UUID, interpreter metadata. | -| 6 | SCANNER-ANALYZERS-NATIVE-20-002 | BLOCKED | Await declared-dependency writer/contract to emit edges | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Parse ELF dynamic sections: `DT_NEEDED`, `DT_RPATH`, `DT_RUNPATH`, symbol versions, interpreter, and note build-id; emit declared dependency records with reason `elf-dtneeded` and attach version needs. | +| 6 | SCANNER-ANALYZERS-NATIVE-20-002 | BLOCKED | PREP-SCANNER-ANALYZERS-NATIVE-20-002-AWAIT-DE | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Parse ELF dynamic sections: `DT_NEEDED`, `DT_RPATH`, `DT_RUNPATH`, symbol versions, interpreter, and note build-id; emit declared dependency records with reason `elf-dtneeded` and attach version needs. | | 7 | SCANNER-ANALYZERS-NATIVE-20-003 | TODO | Depends on SCANNER-ANALYZERS-NATIVE-20-002 | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Parse PE imports, delay-load tables, manifests/SxS metadata, and subsystem flags; emit edges with reasons `pe-import` and `pe-delayimport`, plus SxS policy metadata. | | 8 | SCANNER-ANALYZERS-NATIVE-20-004 | TODO | Depends on SCANNER-ANALYZERS-NATIVE-20-003 | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Parse Mach-O load commands (`LC_LOAD_DYLIB`, `LC_REEXPORT_DYLIB`, `LC_RPATH`, `LC_UUID`, fat headers); handle `@rpath/@loader_path` placeholders and slice separation. | | 9 | SCANNER-ANALYZERS-NATIVE-20-005 | TODO | Depends on SCANNER-ANALYZERS-NATIVE-20-004 | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Implement resolver engine modeling loader search order for ELF (rpath/runpath/cache/default), PE (SafeDll search + SxS), and Mach-O (`@rpath` expansion); works against virtual image roots, producing explain traces. | @@ -36,9 +41,9 @@ | 12 | SCANNER-ANALYZERS-NATIVE-20-008 | TODO | Depends on SCANNER-ANALYZERS-NATIVE-20-007 | Native Analyzer Guild; QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Author cross-platform fixtures (ELF dynamic/static, PE delay-load/SxS, Mach-O @rpath, plugin configs) and determinism benchmarks (<25 ms / binary, <250 MB). | | 13 | SCANNER-ANALYZERS-NATIVE-20-009 | TODO | Depends on SCANNER-ANALYZERS-NATIVE-20-008 | Native Analyzer Guild; Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Provide optional runtime capture adapters (Linux eBPF `dlopen`, Windows ETW ImageLoad, macOS dyld interpose) writing append-only runtime evidence; include redaction/sandbox guidance. | | 14 | SCANNER-ANALYZERS-NATIVE-20-010 | TODO | Depends on SCANNER-ANALYZERS-NATIVE-20-009 | Native Analyzer Guild; DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Package native analyzer as restart-time plug-in with manifest/DI registration; update Offline Kit bundle and documentation. | -| 15 | SCANNER-ANALYZERS-NODE-22-001 | BLOCKED | Needs isolated runner or scoped build graph to execute targeted tests without full-solution fan-out | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Build input normalizer + VFS for Node projects: dirs, tgz, container layers, pnpm store, Yarn PnP zips; detect Node version targets (`.nvmrc`, `.node-version`, Dockerfile) and workspace roots deterministically. | +| 15 | SCANNER-ANALYZERS-NODE-22-001 | BLOCKED | PREP-SCANNER-ANALYZERS-NODE-22-001-NEEDS-ISOL | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Build input normalizer + VFS for Node projects: dirs, tgz, container layers, pnpm store, Yarn PnP zips; detect Node version targets (`.nvmrc`, `.node-version`, Dockerfile) and workspace roots deterministically. | | 16 | SCANNER-ANALYZERS-NODE-22-002 | TODO | Depends on SCANNER-ANALYZERS-NODE-22-001 | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Implement entrypoint discovery (bin/main/module/exports/imports, workers, electron, shebang scripts) and condition set builder per entrypoint. | -| 17 | SCANNER-ANALYZERS-NODE-22-003 | TODO | Depends on SCANNER-ANALYZERS-NODE-22-002 | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Parse JS/TS sources for static `import`, `require`, `import()` and string concat cases; flag dynamic patterns with confidence levels; support source map de-bundling. | +| 17 | SCANNER-ANALYZERS-NODE-22-003 | BLOCKED (2025-11-19) | Blocked on overlay/callgraph schema alignment and test fixtures; resolver wiring pending fixture drop. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Parse JS/TS sources for static `import`, `require`, `import()` and string concat cases; flag dynamic patterns with confidence levels; support source map de-bundling. | | 18 | SCANNER-ANALYZERS-NODE-22-004 | TODO | Depends on SCANNER-ANALYZERS-NODE-22-003 | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Implement Node resolver engine for CJS + ESM (core modules, exports/imports maps, conditions, extension priorities, self-references) parameterised by node_version. | | 19 | SCANNER-ANALYZERS-NODE-22-005 | TODO | Depends on SCANNER-ANALYZERS-NODE-22-004 | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Add package manager adapters: Yarn PnP (.pnp.data/.pnp.cjs), pnpm virtual store, npm/Yarn classic hoists; operate entirely in virtual FS. | | 20 | AGENTS-SCANNER-00-001 | DONE | Create module-level AGENTS.md for `src/Scanner` aligned with scanner architecture docs | Project Management; Scanner Guild | Author/update Scanner AGENTS.md covering roles, required docs, allowed shared directories, determinism/testing rules; ensure implementers can work autonomously. | @@ -46,6 +51,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-16 | Normalised sprint file to standard template; renamed from `SPRINT_132_scanner_surface.md` to `SPRINT_0132_scanner_surface.md`; scope unchanged; added governance task for missing Scanner AGENTS.md. | Planning | | 2025-11-17 | AGENTS-SCANNER-00-001 completed; module AGENTS.md added under src/Scanner. | Implementer | | 2025-11-17 | Updated Decisions & Risks to reflect AGENTS.md completion date, fixed AGENTS.md required-reading formatting/sprint reference, and added dated checkpoints; no scope change. | Planning | @@ -59,6 +65,8 @@ | 2025-11-19 | SCANNER-ANALYZERS-NODE-22-001: Added Yarn PnP cache zip traversal with `yarnPnp` metadata plus new `yarn-pnp` fixture/test; test run aborted ~32s into restore due to contention; rerun required on clean runner. | Node Analyzer Guild | | 2025-11-18 | SCANNER-ANALYZERS-NODE-22-001: Retried `YarnPnpCachePackagesAreParsedAsync` with `--no-restore`; build fanned out across solution and was cancelled at ~66s runtime. Tests remain pending; needs clean/isolated runner or scoped build graph to finish. | Implementer | | 2025-11-18 | SCANNER-ANALYZERS-NODE-22-001: Second attempt with `/m:1 /p:UseSharedCompilation=false --no-restore` cancelled at ~15s while build was still compiling transitive projects. Still needs isolated runner or slimmer build graph to complete test. | Implementer | +| 2025-11-19 | SCANNER-ANALYZERS-NODE-22-002: Wired entrypoint discovery (bin/main/module/exports) into package metadata & evidence; full Node analyzer suite green (`--no-build`). | Implementer | +| 2025-11-19 | SCANNER-ANALYZERS-NODE-22-003: Added NodeImportEdge/Walker and attached import/require/import() edges into package metadata/evidence; `dotnet test ...Lang.Node.Tests --no-build` passing. | Implementer | | 2025-11-18 | SCANNER-ANALYZERS-LANG-11-002..005: Marked BLOCKED because upstream task 11-001 outputs/contracts are not available; dependencies in 11-003..005 cascade. No code changes made. | Implementer | ## Decisions & Risks diff --git a/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md new file mode 100644 index 000000000..5f78f228c --- /dev/null +++ b/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md @@ -0,0 +1,43 @@ +# Sprint 0133-0001-0001 · Scanner & Surface (Phase IV) + +## Topic & Scope +- Scanner & Surface phase IV: Node bundle/source-map coverage and native/WASM signal extraction. +- Maintain sequential execution across 130–139; work only after Sprint 0132 completes. +- **Working directory:** `src/Scanner`. + +## Dependencies & Concurrency +- Upstream: Sprint 0132 (Scanner & Surface phase III) must land first. +- Concurrency: tasks execute in table order; all currently TODO. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/scanner/architecture.md +- src/Scanner/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-SCANNER-ANALYZERS-NODE-22-006-UPSTREAM-2 | TODO | Due 2025-11-22 · Accountable: Node Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node`) | Node Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node`) | Upstream 22-005 not delivered in Sprint 0132; waiting on bundle/source-map resolver baseline.

Document artefact/deliverable for SCANNER-ANALYZERS-NODE-22-006 and publish location so downstream tasks can proceed. | +| P2 | PREP-SCANNER-ANALYZERS-NODE-22-007-UPSTREAM-2 | TODO | Due 2025-11-22 · Accountable: Node Analyzer Guild | Node Analyzer Guild | Upstream 22-006 blocked.

Document artefact/deliverable for SCANNER-ANALYZERS-NODE-22-007 and publish location so downstream tasks can proceed. | +| P3 | PREP-SCANNER-ANALYZERS-NODE-22-008-UPSTREAM-2 | TODO | Due 2025-11-22 · Accountable: Node Analyzer Guild | Node Analyzer Guild | Upstream 22-007 blocked.

Document artefact/deliverable for SCANNER-ANALYZERS-NODE-22-008 and publish location so downstream tasks can proceed. | +| 1 | SCANNER-ANALYZERS-NODE-22-006 | BLOCKED (2025-11-20) | PREP-SCANNER-ANALYZERS-NODE-22-006-UPSTREAM-2 | Node Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node`) | Detect bundles + source maps, reconstruct module specifiers, correlate to original paths; support dual CJS/ESM graphs with conditions. | +| 2 | SCANNER-ANALYZERS-NODE-22-007 | BLOCKED (2025-11-20) | PREP-SCANNER-ANALYZERS-NODE-22-007-UPSTREAM-2 | Node Analyzer Guild | Scan for native addons (.node), WASM modules, and core capability signals (child_process, vm, worker_threads); emit hint edges and native metadata. | +| 3 | SCANNER-ANALYZERS-NODE-22-008 | BLOCKED (2025-11-20) | PREP-SCANNER-ANALYZERS-NODE-22-008-UPSTREAM-2 | Node Analyzer Guild | Produce AOC-compliant observations: entrypoints, components (pkg/native/wasm), edges (esm-import, cjs-require, exports, json, native-addon, wasm, worker) with reason codes/confidence and resolver traces. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-08 | Sprint stub created; awaiting upstream completion of Sprint 0132. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_133_scanner_surface.md` to `SPRINT_0133_0001_0001_scanner_surface.md`; content preserved. | Implementer | +| 2025-11-19 | Converted legacy filename `SPRINT_133_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer | +| 2025-11-20 | Marked Node phase tasks 22-006/007/008 BLOCKED because upstream 22-005 (Sprint 0132) not delivered; no executable work in this sprint until 0132 unblocks. | Implementer | + +## Decisions & Risks +- All tasks depend on 22-005 outputs; remain TODO until prerequisites land. +- Maintain offline/deterministic outputs; avoid running full solution builds—prefer scoped runners per module. + +## Next Checkpoints +- Set kickoff once Sprint 0132 completes (date TBD). \ No newline at end of file diff --git a/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md new file mode 100644 index 000000000..83a40b7fe --- /dev/null +++ b/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md @@ -0,0 +1,38 @@ +# Sprint 0134-0001-0001 · Scanner & Surface (Phase V) + +## Topic & Scope +- Scanner & Surface phase V: PHP analyzer fixtures, optional runtime evidence, packaging. +- Sequential across 130–139; start after Sprint 0133 completes. +- **Working directory:** `src/Scanner`. + +## Dependencies & Concurrency +- Upstream: Sprint 0133 (phase IV) must land first. +- Concurrency: tasks currently TODO; follow table order. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/scanner/architecture.md +- src/Scanner/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | SCANNER-ANALYZERS-PHP-27-009 | TODO | Depends on PHP analyzer core (27-007). | PHP Analyzer Guild · QA Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Fixture suite + performance benchmarks (Laravel, Symfony, WordPress, legacy, PHAR, container) with golden outputs. | +| 2 | SCANNER-ANALYZERS-PHP-27-010 | TODO | Depends on 27-009. | PHP Analyzer Guild · Signals Guild | Optional runtime evidence hooks (audit logs/opcache stats) with path hashing. | +| 3 | SCANNER-ANALYZERS-PHP-27-011 | TODO | Depends on 27-010. | PHP Analyzer Guild · DevOps Guild | Package analyzer plug-in, add CLI `stella php inspect`, refresh Offline Kit docs. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub created; awaiting completion of Sprint 0133. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_134_scanner_surface.md` to `SPRINT_0134_0001_0001_scanner_surface.md`; content preserved. | Implementer | +| 2025-11-19 | Converted legacy filename `SPRINT_134_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer | + +## Decisions & Risks +- All PHP tasks depend on prior analyzer core; remain TODO until upstream tasks land. +- Maintain deterministic fixtures and offline posture. + +## Next Checkpoints +- Set kickoff after Sprint 0133 completes (date TBD). diff --git a/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md new file mode 100644 index 000000000..53dba97c4 --- /dev/null +++ b/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md @@ -0,0 +1,42 @@ +# Sprint 0135-0001-0001 · Scanner & Surface (Phase VI) + +## Topic & Scope +- Scanner & Surface phase VI: Python container/zipapp adapters and Ruby analyzer VFS/deps/runtime coverage. +- Sequential across 130–139; start after Sprint 0134. +- **Working directory:** `src/Scanner`. + +## Dependencies & Concurrency +- Upstream: Sprint 0134 (phase V) must land first. +- Concurrency: tasks are TODO; follow order below. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/scanner/architecture.md +- src/Scanner/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | SCANNER-ANALYZERS-PYTHON-23-012 | TODO | Depends on 23-011. | Python Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python`) | Container/zipapp adapter enhancements: parse OCI layers for Python runtime, detect `PYTHONPATH`/`PYTHONHOME`, warn on sitecustomize/startup hooks. | +| 2 | SCANNER-ANALYZERS-RUBY-28-001 | TODO | — | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Input normalizer & VFS for Ruby projects: merge sources, Gemfile/lock, vendor/bundle, .gem archives, `.bundle/config`, Rack configs, containers; detect framework/job fingerprints deterministically. | +| 3 | SCANNER-ANALYZERS-RUBY-28-002 | TODO | Depends on 28-001. | Ruby Analyzer Guild | Gem & Bundler analyzer: parse Gemfile/lock, vendor specs, .gem archives; produce package nodes (PURLs), dependency edges, and resolver traces. | +| 4 | SCANNER-ANALYZERS-RUBY-28-003 | TODO | Depends on 28-002. | Ruby Analyzer Guild · SBOM Guild | Produce AOC-compliant observations (entrypoints, components, edges) plus environment profiles; integrate with Scanner writer. | +| 5 | SCANNER-ANALYZERS-RUBY-28-004 | TODO | Depends on 28-003. | Ruby Analyzer Guild · QA Guild | Fixtures/benchmarks for Ruby analyzer across Bundler/Rails/Sidekiq/CLI gems; determinism/perf targets. | +| 6 | SCANNER-ANALYZERS-RUBY-28-005 | TODO | Depends on 28-004. | Ruby Analyzer Guild · Signals Guild | Optional runtime capture (tracepoint) hooks with append-only evidence, redaction, and sandbox guidance. | +| 7 | SCANNER-ANALYZERS-RUBY-28-006 | TODO | Depends on 28-005. | Ruby Analyzer Guild · DevOps Guild | Package Ruby analyzer plug-in, add CLI/worker hooks, update Offline Kit docs. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub created; awaiting completion of Sprint 0134. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_135_scanner_surface.md` to `SPRINT_0135_0001_0001_scanner_surface.md`; content preserved. | Implementer | +| 2025-11-19 | Converted legacy filename `SPRINT_135_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer | + +## Decisions & Risks +- Ruby and Python tasks depend on prior phases; all remain TODO until upstream tasks land. +- Maintain offline/deterministic execution and fixtures. + +## Next Checkpoints +- Set kickoff after Sprint 0134 completes (date TBD). diff --git a/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md new file mode 100644 index 000000000..5bd9165ae --- /dev/null +++ b/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md @@ -0,0 +1,37 @@ +# Sprint 0136-0001-0001 · Scanner & Surface (Phase VII) + +## Topic & Scope +- Scanner & Surface phase VII: EntryTrace NDJSON export, process-tree replay, and surface/CLI integration. +- Sequential across 130–139; start after Sprint 0135. +- **Working directory:** `src/Scanner`. + +## Dependencies & Concurrency +- Upstream: Sprint 0135 (phase VI) must land first. +- Concurrency: tasks are TODO; follow order below. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/scanner/architecture.md +- src/Scanner/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | SCANNER-ENTRYTRACE-18-504 | TODO | Depends on 18-503. | EntryTrace Guild (`src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace`) | Emit EntryTrace AOC NDJSON (`entrytrace.entry/node/edge/target/warning/capability`) and wire CLI/service streaming outputs. | +| 2 | SCANNER-ENTRYTRACE-18-505 | TODO | Depends on 18-504. | EntryTrace Guild | Implement ProcGraph replay to reconcile `/proc` exec chains with static EntryTrace, collapsing wrappers and emitting agreement/conflict diagnostics. | +| 3 | SCANNER-ENTRYTRACE-18-506 | TODO | Depends on 18-505. | EntryTrace Guild · Scanner WebService Guild | Surface EntryTrace graph + confidence via Scanner.WebService and CLI, including target summary in scan reports and policy payloads. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub created; awaiting completion of Sprint 0135. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_136_scanner_surface.md` to `SPRINT_0136_0001_0001_scanner_surface.md`; content preserved. | Implementer | +| 2025-11-19 | Converted legacy filename `SPRINT_136_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer | + +## Decisions & Risks +- EntryTrace export and replay depend on upstream 18-503 and accurate `/proc` capture; maintain deterministic ordering. + +## Next Checkpoints +- Schedule kickoff after Sprint 0135 completion (date TBD). diff --git a/docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md b/docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md index b556dcb5f..f811a6e7e 100644 --- a/docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md +++ b/docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md @@ -19,13 +19,18 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD | BLOCKED | Due 2025-11-22 · Accountable: PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Await composer/autoload graph design + staffing; no PHP analyzer scaffolding exists yet.

Document artefact/deliverable for SCANNER-ENG-0010 and publish location so downstream tasks can proceed. | +| P2 | PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL | BLOCKED | Due 2025-11-22 · Accountable: Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Needs Deno runtime analyzer scope + lockfile/import graph design; pending competitive review.

Document artefact/deliverable for SCANNER-ENG-0011 and publish location so downstream tasks can proceed. | +| P3 | PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE | BLOCKED | Due 2025-11-22 · Accountable: Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Define Dart analyzer requirements (pubspec parsing, AOT artifacts) and split into tasks.

Document artefact/deliverable for SCANNER-ENG-0012 and publish location so downstream tasks can proceed. | +| P4 | PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE | BLOCKED | Due 2025-11-22 · Accountable: Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Draft SwiftPM coverage plan; align policy hooks; awaiting design kick-off.

Document artefact/deliverable for SCANNER-ENG-0013 and publish location so downstream tasks can proceed. | +| P5 | PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT | BLOCKED | Due 2025-11-22 · Accountable: Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Needs joint roadmap with Zastava/Runtime guilds for Kubernetes/VM alignment.

Document artefact/deliverable for SCANNER-ENG-0014 and publish location so downstream tasks can proceed. | | 1 | SCANNER-ENG-0008 | DONE (2025-11-16) | Cadence documented; quarterly review workflow published for EntryTrace heuristics. | EntryTrace Guild, QA Guild (`src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace`) | Maintain EntryTrace heuristic cadence per `docs/benchmarks/scanner/scanning-gaps-stella-misses-from-competitors.md`, including explain-trace updates. | | 2 | SCANNER-ENG-0009 | DONE (2025-11-13) | Release handoff to Sprint 0139 consumers; monitor Mongo-backed inventory rollout. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Ruby analyzer parity shipped: runtime graph + capability signals, observation payload, Mongo-backed `ruby.packages` inventory, CLI/WebService surfaces, and plugin manifest bundles for Worker loadout. | -| 3 | SCANNER-ENG-0010 | BLOCKED | Await composer/autoload graph design + staffing; no PHP analyzer scaffolding exists yet. | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Ship the PHP analyzer pipeline (composer lock, autoload graph, capability signals) to close comparison gaps. | -| 4 | SCANNER-ENG-0011 | BLOCKED | Needs Deno runtime analyzer scope + lockfile/import graph design; pending competitive review. | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Scope the Deno runtime analyzer (lockfile resolver, import graphs) beyond Sprint 130 coverage. | -| 5 | SCANNER-ENG-0012 | BLOCKED | Define Dart analyzer requirements (pubspec parsing, AOT artifacts) and split into tasks. | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Evaluate Dart analyzer requirements (pubspec parsing, AOT artifacts) and split implementation tasks. | -| 6 | SCANNER-ENG-0013 | BLOCKED | Draft SwiftPM coverage plan; align policy hooks; awaiting design kick-off. | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Plan Swift Package Manager coverage (Package.resolved, xcframeworks, runtime hints) with policy hooks. | -| 7 | SCANNER-ENG-0014 | BLOCKED | Needs joint roadmap with Zastava/Runtime guilds for Kubernetes/VM alignment. | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Align Kubernetes/VM target coverage between Scanner and Zastava per comparison findings; publish joint roadmap. | +| 3 | SCANNER-ENG-0010 | BLOCKED | PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD | PHP Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Ship the PHP analyzer pipeline (composer lock, autoload graph, capability signals) to close comparison gaps. | +| 4 | SCANNER-ENG-0011 | BLOCKED | PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno`) | Scope the Deno runtime analyzer (lockfile resolver, import graphs) beyond Sprint 130 coverage. | +| 5 | SCANNER-ENG-0012 | BLOCKED | PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE | Language Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart`) | Evaluate Dart analyzer requirements (pubspec parsing, AOT artifacts) and split implementation tasks. | +| 6 | SCANNER-ENG-0013 | BLOCKED | PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE | Swift Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Native`) | Plan Swift Package Manager coverage (Package.resolved, xcframeworks, runtime hints) with policy hooks. | +| 7 | SCANNER-ENG-0014 | BLOCKED | PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT | Runtime Guild, Zastava Guild (`docs/modules/scanner`) | Align Kubernetes/VM target coverage between Scanner and Zastava per comparison findings; publish joint roadmap. | | 8 | SCANNER-ENG-0015 | DONE (2025-11-13) | Ready for Ops training; track adoption metrics. | Export Center Guild, Scanner Guild (`docs/modules/scanner`) | DSSE/Rekor operator playbook published with config/env tables, rollout phases, offline verification, and SLA/alert guidance. | | 9 | SCANNER-ENG-0016 | DONE (2025-11-10) | Monitor bundler override edge cases; keep fixtures deterministic. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | RubyLockCollector and vendor ingestion finalized: Bundler overrides honoured, workspace lockfiles merged, vendor bundles normalised, deterministic fixtures added. | | 10 | SCANNER-ENG-0017 | DONE (2025-11-09) | Keep tree-sitter Ruby grammar pinned; reuse EntryTrace hints for regressions. | Ruby Analyzer Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Build runtime require/autoload graph builder with tree-sitter Ruby per design §4.4 and integrate EntryTrace hints. | @@ -38,6 +43,9 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Removed trailing hyphen from PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE so SCANNER-ENG-0013 dependency resolves. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked PREP tasks P1–P5 BLOCKED pending composer/Deno/Dart/SwiftPM design contracts and Zastava/Runtime roadmap; downstream SCANNER-ENG-0010..0014 remain gated. | Project Mgmt | | 2025-11-09 | `SCANNER-CLI-0001`: Spectre table wrapping fix for runtime/lockfile columns; expanded Ruby resolve JSON assertions; removed debug artifacts; docs/tests pending final merge. | CLI Guild | | 2025-11-09 | `SCANNER-CLI-0001`: Wired `stellaops-cli ruby inspect|resolve` into `CommandFactory` with `--root`, `--image/--scan-id`, `--format`; `dotnet test ... --filter Ruby` passes. | CLI Guild | | 2025-11-09 | `SCANNER-CLI-0001`: Added CLI unit tests (CommandFactoryTests, Ruby inspect JSON assertions) to guard new verbs and runtime metadata output. | CLI Guild | diff --git a/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md b/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md index 8ac12a570..dad49fb0d 100644 --- a/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md +++ b/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md @@ -24,14 +24,18 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | 140.A Graph wave | DOING | Executing against scanner surface mock bundle v1; awaiting real cache ETA from Sprint 130.A for parity validation. | Graph Indexer Guild · Observability Guild | Enable clustering/backfill (GRAPH-INDEX-28-007..010) against mock bundle; update once cache ETA is published. | +| P1 | PREP-140-D-ZASTAVA-WAVE-WAITING-ON-SURFACE-FS | TODO | Due 2025-11-22 · Accountable: Zastava Observer/Webhook Guilds · Surface Guild | Zastava Observer/Webhook Guilds · Surface Guild | Waiting on Surface.FS cache drop plan + Surface.Env helper ownership.

Document artefact/deliverable for 140.D Zastava wave and publish location so downstream tasks can proceed. | +| P2 | PREP-SBOM-SERVICE-GUILD-CARTOGRAPHER-GUILD-OB | TODO | Due 2025-11-22 · Accountable: Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | BLOCKED.

Document artefact/deliverable for SBOM Service Guild · Cartographer Guild · Observability Guild, Zastava Observer/Webhook Guilds · Security Guild and publish location so downstream tasks can proceed. | +| 1 | 140.A Graph wave | BLOCKED (2025-11-19) | Await real scanner cache ETA; working off mock bundle only. | Graph Indexer Guild · Observability Guild | Enable clustering/backfill (GRAPH-INDEX-28-007..010) against mock bundle; revalidate once real cache lands. | | 2 | 140.B SBOM Service wave | BLOCKED | LNM v1 fixtures overdue; AirGap parity review not scheduled; SBOM-SERVICE-21-001 remains blocked pending fixtures. | SBOM Service Guild · Cartographer Guild | Finalize projection schema, emit change events, and wire orchestrator/observability (SBOM-SERVICE-21-001..004, SBOM-AIAI-31-001/002). | -| 3 | 140.C Signals wave | DOING | CAS promotion + signed manifest rollout; provenance appendix + runtime backfill before scoring. | Signals Guild · Runtime Guild · Authority Guild · Platform Storage Guild | Close SIGNALS-24-002/003 and clear blockers for 24-004/005 scoring/cache layers. | -| 4 | 140.D Zastava wave | BLOCKED | Waiting on Surface.FS cache drop plan + Surface.Env helper ownership. | Zastava Observer/Webhook Guilds · Surface Guild | Prepare env/secret helpers and admission hooks; start once cache endpoints and helpers are published. | +| 3 | 140.C Signals wave | BLOCKED (2025-11-20) | CAS promotion + signed manifests + provenance appendix pending; SIGNALS-24-002/003 blocked upstream. TRACTORS: see `docs/signals/cas-promotion-24-002.md` and `docs/signals/provenance-24-003.md`. | Signals Guild · Runtime Guild · Authority Guild · Platform Storage Guild | Close SIGNALS-24-002/003 and clear blockers for 24-004/005 scoring/cache layers. | +| 4 | 140.D Zastava wave | BLOCKED | PREP-140-D-ZASTAVA-WAVE-WAITING-ON-SURFACE-FS | Zastava Observer/Webhook Guilds · Surface Guild | Prepare env/secret helpers and admission hooks; start once cache endpoints and helpers are published. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-20 | Marked SIGNALS-24-002/003 as BLOCKED pending Platform Storage + provenance approvals; linked CAS/provenance checklists in blockers. | Implementer | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-18 | Marked SBOM wave BLOCKED pending overdue LNM fixtures and AirGap review scheduling; status mirrored to tasks-all/blocked-all. | Planning | | 2025-11-18 | Added cache parity checklist (Graph) and CAS/provenance close-out checklist (Signals); mock bundle execution ongoing; fixed cross-sprint references to padded SPRINT IDs. | Planning | | 2025-11-18 | Started Graph wave execution on scanner surface mock bundle v1; tracking cache ETA for parity validation. | Planning | @@ -79,16 +83,16 @@ This file now only tracks the runtime & signals status snapshot. Active backlog | Wave | Guild owners | Shared prerequisites | Status | Notes | | --- | --- | --- | --- | --- | -| 140.A Graph | Graph Indexer Guild · Observability Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner (phase I tracked under `docs/implplan/SPRINT_130_scanner_surface.md`) | DOING | Executing on scanner surface mock bundle v1; real cache ETA still required for parity validation and to flip to real inputs. | -| 140.B SbomService | SBOM Service Guild · Cartographer Guild · Observability Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner | BLOCKED | Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | -| 140.C Signals | Signals Guild · Authority Guild (for scopes) · Runtime Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner | DOING (red) | CAS checklist + provenance appendix overdue; callgraph retrieval live but artifacts not trusted until CAS/signing lands. | -| 140.D Zastava | Zastava Observer/Webhook Guilds · Security Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner | BLOCKED | Surface.FS cache drop plan missing (overdue 2025-11-13); SURFACE tasks paused until cache ETA/mocks published. | +| 140.A Graph | Graph Indexer Guild · Observability Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner (phase I tracked under `docs/implplan/SPRINT_130_scanner_surface.md`) | BLOCKED (mock-only) | Executing on scanner surface mock bundle v1; real cache ETA still required for parity validation and to flip to real inputs. | +| 140.B SbomService | SBOM Service Guild · Cartographer Guild · Observability Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner | PREP-SBOM-SERVICE-GUILD-CARTOGRAPHER-GUILD-OB | Projection schema frozen but fixtures and AirGap review are overdue; SBOM-SERVICE-21-001..004 cannot start until fixtures drop. | +| 140.C Signals | Signals Guild · Authority Guild (for scopes) · Runtime Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner | BLOCKED (red) | CAS checklist + provenance appendix overdue; callgraph retrieval live but artifacts not trusted until CAS/signing lands. | +| 140.D Zastava | Zastava Observer/Webhook Guilds · Security Guild | Sprint 120.A – AirGap; Sprint 130.A – Scanner | PREP-SBOM-SERVICE-GUILD-CARTOGRAPHER-GUILD-OB | Surface.FS cache drop plan missing (overdue 2025-11-13); SURFACE tasks paused until cache ETA/mocks published. | # Status snapshot (2025-11-18) -- **140.A Graph** – DOING on scanner surface mock bundle v1 (decision 2025-11-17); real cache ETA still required but no longer blocks coding/fixtures; will revalidate outputs when caches land. +- **140.A Graph** – BLOCKED on real cache delivery; running only on scanner surface mock bundle v1 pending cache ETA/hash. - **140.B SbomService** – BLOCKED: LNM v1 fixtures are overdue (due 2025-11-18) and AirGap parity review is not scheduled; SBOM-SERVICE-21-001 cannot start until fixtures drop (21-002..004 follow). -- **140.C Signals** – SIGNALS-24-001 shipped on 2025-11-09; SIGNALS-24-002 is RED/BLOCKED with CAS promotion + signed manifest tooling pending; SIGNALS-24-003 is DOING but awaits provenance appendix and runtime feed reconciliation. Scoring/cache work (SIGNALS-24-004/005) stays BLOCKED until CAS/provenance and runtime uploads stabilize. +- **140.C Signals** – SIGNALS-24-001 shipped on 2025-11-09; SIGNALS-24-002 and SIGNALS-24-003 are BLOCKED with CAS promotion + provenance appendix pending. Scoring/cache work (SIGNALS-24-004/005) stays BLOCKED until CAS/provenance and runtime uploads stabilize. - **140.D Zastava** – ZASTAVA-ENV/SECRETS/SURFACE tracks are BLOCKED because Surface.FS cache outputs from Scanner are still unavailable; guilds continue prepping Surface.Env helper adoption and sealed-mode scaffolding while caches are pending. ## Wave task tracker (refreshed 2025-11-18) @@ -97,7 +101,7 @@ This file now only tracks the runtime & signals status snapshot. Active backlog | Task ID | State | Notes | | --- | --- | --- | -| GRAPH-INDEX-28-007 | DOING | Running on scanner surface mock bundle v1; will revalidate once real cache ETA publishes. | +| GRAPH-INDEX-28-007 | BLOCKED | Waiting on real scanner cache ETA; mock bundle only. | | GRAPH-INDEX-28-008 | BLOCKED-w/escalation | Incremental update/backfill pipeline depends on 28-007 artifacts; retry/backoff plumbing sketched but blocked. | | GRAPH-INDEX-28-009 | BLOCKED-w/escalation | Test/fixture/chaos coverage waits on earlier jobs to exist so determinism checks have data. | | GRAPH-INDEX-28-010 | BLOCKED-w/escalation | Packaging/offline bundles paused until upstream graph jobs are available to embed. | @@ -127,8 +131,8 @@ This file now only tracks the runtime & signals status snapshot. Active backlog | Task ID | State | Notes | | --- | --- | --- | | SIGNALS-24-001 | DONE (2025-11-09) | Host skeleton, RBAC, sealed-mode readiness, `/signals/facts/{subject}` retrieval, and readiness probes merged; serves as base for downstream ingestion. | -| SIGNALS-24-002 | DOING (2025-11-07) | Callgraph ingestion + retrieval APIs are live, but CAS promotion and signed manifest publication remain; cannot close until reachability jobs can trust stored graphs. | -| SIGNALS-24-003 | DOING (2025-11-09) | Runtime facts ingestion accepts JSON/NDJSON and gzip streams; provenance/context enrichment and NDJSON-to-AOC wiring still outstanding. | +| SIGNALS-24-002 | BLOCKED (2025-11-19) | Callgraph ingestion + retrieval APIs are live, but CAS promotion and signed manifest publication remain; cannot close until reachability jobs can trust stored graphs. | +| SIGNALS-24-003 | BLOCKED (2025-11-19) | Runtime facts ingestion accepts JSON/NDJSON and gzip streams; provenance/context enrichment and NDJSON-to-AOC wiring still outstanding. | | SIGNALS-24-004 | BLOCKED (2025-10-27) | Reachability scoring waits on complete ingestion feeds (24-002/003) plus Authority scope validation. | | SIGNALS-24-005 | BLOCKED (2025-10-27) | Cache + `signals.fact.updated` events depend on scoring outputs; remains idle until 24-004 unblocks. | @@ -215,8 +219,8 @@ This file now only tracks the runtime & signals status snapshot. Active backlog | Deliverable | Target date | Status | Dependencies / notes | | --- | --- | --- | --- | -| SIGNALS-24-002 CAS promotion + signed manifests | 2025-11-14 | DOING | Needs Platform Storage sign-off from 2025-11-13 review; alerts/runbooks drafted. | -| SIGNALS-24-003 provenance enrichment + backfill | 2025-11-15 | DOING | Waiting on Runtime/Authority schema freeze + scope fixtures; NDJSON ingestion landed. | +| SIGNALS-24-002 CAS promotion + signed manifests | 2025-11-14 | BLOCKED | Waiting on Platform Storage approval; CAS checklist published (`docs/signals/cas-promotion-24-002.md`). | +| SIGNALS-24-003 provenance enrichment + backfill | 2025-11-15 | BLOCKED | Await provenance appendix freeze/approval; checklist published (`docs/signals/provenance-24-003.md`). | | Scanner analyzer artifact ETA & cache drop plan | 2025-11-13 | TODO | Scanner to publish Sprint 130 surface roadmap; Graph/Zastava blocked until then. | | Concelier Link-Not-Merge schema ratified | 2025-11-14 | BLOCKED | Requires `CONCELIER-GRAPH-21-001` + `CARTO-GRAPH-21-002` agreement; AirGap review scheduled after sign-off. | | Surface.Env helper adoption checklist | 2025-11-15 | TODO | Zastava guild preparing sealed-mode test harness; depends on Surface guild office hours outcomes. | diff --git a/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md b/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md index 9a3bddb34..f54b835a9 100644 --- a/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md +++ b/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md @@ -21,14 +21,21 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | GRAPH-INDEX-28-007 | BLOCKED | Waiting on GRAPH-INDEX-28-006 overlays + schedule config design | Graph Indexer Guild · Observability Guild | Implement clustering/centrality background jobs (Louvain/degree/betweenness approximations) with configurable schedules; persist cluster ids on nodes; expose metrics. | -| 2 | GRAPH-INDEX-28-008 | BLOCKED | Unblock after 28-007; confirm change streams + retry/backoff settings | Graph Indexer Guild | Provide incremental update & backfill pipeline with change streams, retry/backoff, idempotent ops, backlog metrics. | -| 3 | GRAPH-INDEX-28-009 | BLOCKED | Downstream of 28-008 data paths | Graph Indexer Guild · QA Guild | Add unit/property/integration tests, synthetic large-graph fixtures, chaos tests (missing overlays, cycles), determinism checks across runs. | -| 4 | GRAPH-INDEX-28-010 | BLOCKED | Needs outputs from 28-009; align with Offline Kit owners | Graph Indexer Guild · DevOps Guild | Package deployment artefacts (Helm/Compose), offline seed bundles, configuration docs; integrate Offline Kit. | +| P0 | PREP-GRAPH-INDEX-28-006-OVERLAYS | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild · Observability Guild | Graph Indexer Guild · Observability Guild | Deliver baseline overlays + schedule config design for GRAPH-INDEX-28-006; publish mock bundle + config docs so 28-007 can start. | +| P1 | PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild | Graph Indexer Guild | Unblock after 28-007; confirm change streams + retry/backoff settings.

Document artefact/deliverable for GRAPH-INDEX-28-008 and publish location so downstream tasks can proceed. | +| P2 | PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild · QA Guild | Graph Indexer Guild · QA Guild | Downstream of 28-008 data paths.

Document artefact/deliverable for GRAPH-INDEX-28-009 and publish location so downstream tasks can proceed. | +| P3 | PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 | BLOCKED | Due 2025-11-22 · Accountable: Graph Indexer Guild · DevOps Guild | Graph Indexer Guild · DevOps Guild | Needs outputs from 28-009; align with Offline Kit owners.

Document artefact/deliverable for GRAPH-INDEX-28-010 and publish location so downstream tasks can proceed. | +| 1 | GRAPH-INDEX-28-007 | BLOCKED | PREP-GRAPH-INDEX-28-006-OVERLAYS | Graph Indexer Guild · Observability Guild | Implement clustering/centrality background jobs (Louvain/degree/betweenness approximations) with configurable schedules; persist cluster ids on nodes; expose metrics. | +| 2 | GRAPH-INDEX-28-008 | BLOCKED | PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 | Graph Indexer Guild | Provide incremental update & backfill pipeline with change streams, retry/backoff, idempotent ops, backlog metrics. | +| 3 | GRAPH-INDEX-28-009 | BLOCKED | PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 | Graph Indexer Guild · QA Guild | Add unit/property/integration tests, synthetic large-graph fixtures, chaos tests (missing overlays, cycles), determinism checks across runs. | +| 4 | GRAPH-INDEX-28-010 | BLOCKED | PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 | Graph Indexer Guild · DevOps Guild | Package deployment artefacts (Helm/Compose), offline seed bundles, configuration docs; integrate Offline Kit. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Added PREP-GRAPH-INDEX-28-006-OVERLAYS and normalized PREP IDs for 28-008/009 so dependency graph is concrete. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked PREP tasks P0–P3 BLOCKED; overlays/mock bundle and change-stream/backfill configs are still missing, so GRAPH-INDEX-28-007..010 stay gated. | Project Mgmt | | 2025-11-17 | Marked tasks 28-007 through 28-010 as BLOCKED pending upstream 28-006 overlays and scanner cache availability. | Planning | | 2025-11-17 | Normalised sprint to standard template; renamed from SPRINT_141_graph.md; scope unchanged. | Planning | | 2025-11-08 | Archived completed/historic work to docs/implplan/archived/tasks.md. | Planning | diff --git a/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md b/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md index 98c1914de..2eba1d93e 100644 --- a/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md +++ b/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md @@ -19,14 +19,17 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-SBOM-CONSOLE-23-001-BUILD-TEST-FAILING-D | TODO | Due 2025-11-22 · Accountable: SBOM Service Guild; Cartographer Guild | SBOM Service Guild; Cartographer Guild | Build/test failing due to missing NuGet feed; need feed/offline cache before wiring storage and validating `/console/sboms`.

Document artefact/deliverable for SBOM-CONSOLE-23-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-SBOM-SERVICE-21-001-WAITING-ON-LNM-V1-FI | TODO | Due 2025-11-22 · Accountable: SBOM Service Guild; Cartographer Guild | SBOM Service Guild; Cartographer Guild | Waiting on LNM v1 fixtures (due 2025-11-18 UTC) to freeze schema; then publish normalized SBOM projection read API with pagination + tenant enforcement.

Document artefact/deliverable for SBOM-SERVICE-21-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-BUILD-INFRA-SBOM-SERVICE-GUILD-BLOCKED-M | TODO | Due 2025-11-22 · Accountable: Planning | Planning | BLOCKED (multiple restore attempts still hang/fail; need vetted feed/cache).

Document artefact/deliverable for Build/Infra · SBOM Service Guild and publish location so downstream tasks can proceed. | | 1 | SBOM-AIAI-31-001 | DONE | Implemented `/sbom/paths` with env/blast-radius/runtime flags + cursor paging and `/sbom/versions` timeline; in-memory deterministic seed until storage wired. | SBOM Service Guild (src/SbomService/StellaOps.SbomService) | Provide path and version timeline endpoints optimised for Advisory AI. | | 2 | SBOM-AIAI-31-002 | DONE | Metrics + cache-hit tagging implemented; Grafana starter dashboard added; build/test completed locally. | SBOM Service Guild; Observability Guild | Instrument metrics for path/timeline queries and surface dashboards. | -| 3 | SBOM-CONSOLE-23-001 | BLOCKED | Build/test failing due to missing NuGet feed; need feed/offline cache before wiring storage and validating `/console/sboms`. | SBOM Service Guild; Cartographer Guild | Provide Console-focused SBOM catalog API. | -| 4 | SBOM-CONSOLE-23-002 | DOING | Stub component lookup (`/components/lookup`) implemented with repo abstraction, caching, pagination; validated via tests; storage wiring pending. | SBOM Service Guild | Deliver component lookup endpoints for search and overlays. | +| 3 | SBOM-CONSOLE-23-001 | BLOCKED | PREP-SBOM-CONSOLE-23-001-BUILD-TEST-FAILING-D | SBOM Service Guild; Cartographer Guild | Provide Console-focused SBOM catalog API. | +| 4 | SBOM-CONSOLE-23-002 | BLOCKED | Stub implemented; blocked on storage wiring and console schema approval. | SBOM Service Guild | Deliver component lookup endpoints for search and overlays. | | 5 | SBOM-ORCH-32-001 | TODO | Register SBOM ingest/index sources; embed worker SDK; emit artifact hashes and job metadata. | SBOM Service Guild | Register SBOM ingest/index sources with orchestrator. | | 6 | SBOM-ORCH-33-001 | TODO | Depends on SBOM-ORCH-32-001; report backpressure metrics, honor pause/throttle signals, classify sbom job errors. | SBOM Service Guild | Report backpressure metrics and handle orchestrator control signals. | | 7 | SBOM-ORCH-34-001 | TODO | Depends on SBOM-ORCH-33-001; implement orchestrator backfill and watermark reconciliation for idempotent artifact reuse. | SBOM Service Guild | Implement orchestrator backfill + watermark reconciliation. | -| 8 | SBOM-SERVICE-21-001 | BLOCKED | Waiting on LNM v1 fixtures (due 2025-11-18 UTC) to freeze schema; then publish normalized SBOM projection read API with pagination + tenant enforcement. | SBOM Service Guild; Cartographer Guild | Link-Not-Merge v1 frozen schema and deterministic read API. | +| 8 | SBOM-SERVICE-21-001 | BLOCKED | PREP-SBOM-SERVICE-21-001-WAITING-ON-LNM-V1-FI | SBOM Service Guild; Cartographer Guild | Link-Not-Merge v1 frozen schema and deterministic read API. | | 9 | SBOM-SERVICE-21-002 | TODO | Depends on SBOM-SERVICE-21-001; emit `sbom.version.created` change events and add replay/backfill tooling. | SBOM Service Guild; Scheduler Guild | Emit change events carrying digest/version metadata for Graph Indexer builds. | | 10 | SBOM-SERVICE-21-003 | TODO | Depends on SBOM-SERVICE-21-002; entrypoint/service node management API feeding Cartographer path relevance with deterministic defaults. | SBOM Service Guild | Provide entrypoint/service node management API. | | 11 | SBOM-SERVICE-21-004 | TODO | Depends on SBOM-SERVICE-21-003; wire metrics (`sbom_projection_seconds`, `sbom_projection_size`), traces, tenant-annotated logs; set backlog alerts. | SBOM Service Guild; Observability Guild | Wire observability for SBOM projections. | @@ -41,11 +44,12 @@ | Provide LNM v1 fixtures for SBOM projections. | Cartographer Guild | 2025-11-18 | OVERDUE (escalate; follow-up 2025-11-19) | | Publish orchestrator control contract for pause/throttle/backfill signals. | Orchestrator Guild | 2025-11-19 | Pending | | Create `src/SbomService/AGENTS.md` (roles, prerequisites, determinism/testing rules). | SBOM Service Guild · Module PM | 2025-11-19 | DONE | -| Supply NuGet feed/offline cache (allow Microsoft.IdentityModel.Tokens >=8.14.0, Pkcs11Interop >=4.1.0) so SbomService builds/tests can run. | Build/Infra · SBOM Service Guild | 2025-11-20 | BLOCKED (multiple restore attempts still hang/fail; need vetted feed/cache) | +| Supply NuGet feed/offline cache (allow Microsoft.IdentityModel.Tokens >=8.14.0, Pkcs11Interop >=4.1.0) so SbomService builds/tests can run. | Build/Infra · SBOM Service Guild | 2025-11-20 | PREP-BUILD-INFRA-SBOM-SERVICE-GUILD-BLOCKED-M | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-17 | Normalised sprint to standard template and renamed from `SPRINT_142_sbomservice.md`; no scope changes. | Project Mgmt | | 2025-11-17 | Flagged need for SBOM Service module dossier as documentation prerequisite. | Project Mgmt | | 2025-11-17 | Authored `docs/modules/sbomservice/architecture.md`; added to prerequisites; set SBOM-SERVICE-21-001 to BLOCKED pending LNM v1 fixtures. | Project Mgmt | @@ -57,6 +61,7 @@ | 2025-11-18 | Scoped builds (`dotnet build` on SbomService csproj/solution) repeatedly aborted by cross-solution churn; tests remain unrun. | SBOM Service | | 2025-11-18 | Additional targeted build of `StellaOps.SbomService.csproj` aborted (~48s) due to repo churn; testing still blocked. | SBOM Service | | 2025-11-18 | Marked SBOM-AIAI-31-002 BLOCKED (needs validated metrics & dashboards) and SBOM-CONSOLE-23-002 DOING (stub implemented, blocked on validation). | SBOM Service | +| 2025-11-19 | Marked SBOM-CONSOLE-23-002 BLOCKED pending storage wiring and console schema approval. | Implementer | | 2025-11-18 | Build attempt with `/p:BuildProjectReferences=false` failed at restore (~11s); unable to validate code path changes. | SBOM Service | | 2025-11-18 | Added Grafana starter dashboard (`Observability/sbomservice-grafana-dashboard.json`) and README notes; metrics still unvalidated pending successful builds. | SBOM Service | | 2025-11-18 | Fixed NuGet feed mapping, restored, built, and ran tests successfully for SbomService; SBOM-AIAI-31-002 marked DONE; SBOM-CONSOLE-23-002 validated at stub level. | SBOM Service | @@ -84,7 +89,7 @@ - Latest restore attempts (2025-11-18/19) fail/hang even with local-nugets copies and PSM disabled; need vetted feed/offline cache allowing Microsoft.IdentityModel.Tokens ≥8.14.0 and Pkcs11Interop ≥4.1.0. - Metrics include `cache_hit` tagging; dashboards outstanding and unvalidated due to feed/build failures. - Build/test runs for SbomService blocked by feed mapping; must fix mapping or cache packages before rerunning `dotnet test ...SbomService.Tests.csproj`. -- Component lookup endpoint is stubbed; remains unvalidated until restores succeed; SBOM-CONSOLE-23-002 stays DOING but blocked on feed/build. +- Component lookup endpoint is stubbed; remains unvalidated until restores succeed; SBOM-CONSOLE-23-002 stays BLOCKED on feed/build. - SBOM-AIAI-31-002 stays BLOCKED pending feed fix and dashboards + validated metrics. - `AGENTS.md` for `src/SbomService` added 2025-11-18; implementers must read before coding. diff --git a/docs/implplan/SPRINT_0143_0000_0001_signals.md b/docs/implplan/SPRINT_0143_0000_0001_signals.md index e1aa4ce2a..86d1b739d 100644 --- a/docs/implplan/SPRINT_0143_0000_0001_signals.md +++ b/docs/implplan/SPRINT_0143_0000_0001_signals.md @@ -19,15 +19,21 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-SIGNALS-24-005-REDIS-CACHE-IMPLEMENTED-A | DONE (2025-11-20) | Doc published at `docs/signals/events-24-005.md`; bus/topic approved. | Signals Guild, Platform Events Guild | Redis cache implemented; awaiting real bus/topic + payload contract to replace placeholder `signals.fact.updated` logging.

Document artefact/deliverable for SIGNALS-24-005 and publish location so downstream tasks can proceed. | +| P2 | PREP-SIGNALS-24-002-CAS-PROMO | DONE (2025-11-19) | Due 2025-11-22 · Accountable: Signals Guild · Platform Storage Guild | Signals Guild · Platform Storage Guild | CAS promotion checklist and manifest schema published at `docs/signals/cas-promotion-24-002.md`; awaiting storage approval to execute. | +| P3 | PREP-SIGNALS-24-003-PROVENANCE | DONE (2025-11-19) | Due 2025-11-22 · Accountable: Signals Guild · Runtime Guild · Authority Guild | Signals Guild · Runtime Guild · Authority Guild | Provenance appendix fields and checklist published at `docs/signals/provenance-24-003.md`; awaiting schema/signing approval to execute. | | 1 | SIGNALS-24-001 | DONE (2025-11-09) | Dependency AUTH-SIG-26-001; merged host skeleton with scope policies and evidence validation. | Signals Guild, Authority Guild | Stand up Signals API skeleton with RBAC, sealed-mode config, DPoP/mTLS enforcement, and `/facts` scaffolding so downstream ingestion can begin. | -| 2 | SIGNALS-24-002 | DOING (2025-11-07) | Remaining: CAS bucket promotion and signed graph manifests; depends on SIGNALS-24-001. | Signals Guild | Implement callgraph ingestion/normalization (Java/Node/Python/Go) with CAS persistence and retrieval APIs to feed reachability scoring. | -| 3 | SIGNALS-24-003 | DONE (2025-11-17) | Runtime ingestion now enriches provenance metadata and triggers reachability recompute on ingest. | Signals Guild, Runtime Guild | Implement runtime facts ingestion endpoint and normalizer (process, sockets, container metadata) populating `context_facts` with AOC provenance. | +| 2 | SIGNALS-24-002 | BLOCKED (2025-11-19) | Await Platform Storage approval; CAS promotion checklist ready (see PREP-SIGNALS-24-002-CAS-PROMO). | Signals Guild | Implement callgraph ingestion/normalization (Java/Node/Python/Go) with CAS persistence and retrieval APIs to feed reachability scoring. | +| 3 | SIGNALS-24-003 | BLOCKED (2025-11-19) | Blocked on SIGNALS-24-002 approval and provenance schema sign-off; checklist ready (PREP-SIGNALS-24-003-PROVENANCE). | Signals Guild, Runtime Guild | Implement runtime facts ingestion endpoint and normalizer (process, sockets, container metadata) populating `context_facts` with AOC provenance. | | 4 | SIGNALS-24-004 | DONE (2025-11-17) | Scoring weights now configurable; runtime ingestion auto-triggers recompute into `reachability_facts`. | Signals Guild, Data Science | Deliver reachability scoring engine producing states/scores and writing to `reachability_facts`; expose configuration for weights. | -| 5 | SIGNALS-24-005 | BLOCKED (2025-11-18) | Redis cache implemented; awaiting real bus/topic + payload contract to replace placeholder `signals.fact.updated` logging. | Signals Guild, Platform Events Guild | Implement Redis caches (`reachability_cache:*`), invalidation on new facts, and publish `signals.fact.updated` events. | +| 5 | SIGNALS-24-005 | TODO | PREP-SIGNALS-24-005-REDIS-CACHE-IMPLEMENTED-A | Signals Guild, Platform Events Guild | Implement Redis caches (`reachability_cache:*`), invalidation on new facts, and publish `signals.fact.updated` events. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-20 | Published `docs/signals/events-24-005.md` event-bus contract (topic, envelope, retry/DLQ); marked PREP-SIGNALS-24-005 DONE and moved SIGNALS-24-005 to TODO. | Implementer | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked SIGNALS-24-002 and SIGNALS-24-003 BLOCKED pending CAS promotion, signed manifests, and provenance schema. | Implementer | | 2025-10-29 | Skeleton live with scope policies, stub endpoints, integration tests; sample configuration committed under `etc/signals.yaml.sample`. | Signals Guild | | 2025-10-29 | JSON parsers for Java/Node.js/Python/Go implemented; artifacts stored with SHA-256 and callgraphs upserted into Mongo. | Signals Guild | | 2025-11-09 | Signals host registers sealed-mode evidence validation, exposes `/readyz`/`/status`, enforces scope policies, and adds `/signals/facts/{subjectKey}` retrieval plus runtime-facts ingestion backing services. | Signals Guild / Authority Guild | @@ -35,7 +41,7 @@ | 2025-11-09 | Added runtime facts ingestion service + endpoint, aggregated runtime hit storage, and unit tests; next steps are NDJSON/gzip ingestion and provenance metadata wiring. | Signals Guild / Runtime Guild | | 2025-11-09 | Added `/signals/runtime-facts/ndjson` streaming endpoint (JSON/NDJSON + gzip) with sealed-mode gating; provenance/context enrichment + scoring linkage remain. | Signals Guild / Runtime Guild | | 2025-11-17 | CAS remediation window (≤3 days for Critical/High) approved with signed waiver; proceed with SIGNALS-24-002/004/005. | Signals Guild | -| 2025-11-17 | CAS checklist in remediation window with risk waiver; continue DOING on SIGNALS-24-002 and unlock 24-004/005. | Signals Guild | +| 2025-11-17 | CAS checklist in remediation window with risk waiver; SIGNALS-24-002/003 remain BLOCKED until CAS promotion + signed manifests land; 24-004/005 stay gated. | Signals Guild | | 2025-11-17 | Normalised sprint to standard template and renamed from SPRINT_143_signals.md to SPRINT_0143_0000_0001_signals.md. | PM | | 2025-11-17 | Reachability scoring weights moved to config; runtime facts ingestion now triggers recompute and persists states; added unit tests for scoring + runtime ingestion. | Signals Guild | | 2025-11-17 | `dotnet test src/Signals/StellaOps.Signals.sln` aborted after long restore/build; warning NU1504 about duplicate PackageReference items in StellaOps.Signals.Tests persists—needs cleanup before rerun. | Signals Guild | @@ -60,10 +66,9 @@ ## Decisions & Risks - CAS remediation window (≤3 days for Critical/High) running under signed waiver; track SIGNALS-24-002/004/005 for compliance. - Callgraph CAS bucket promotion and signed manifests remain outstanding for SIGNALS-24-002; risk to scoring start if delayed. -- Runtime facts provenance/context enrichment and scoring linkage pending (SIGNALS-24-003); downstream scoring (24-004/005) can start only after completion. +- SIGNALS-24-003 now blocked on CAS promotion/provenance schema; downstream scoring (24-004/005) depend on this landing. - SIGNALS-24-005 partly blocked: Redis cache delivered; event payload schema defined and logged, but event bus/channel contract (topic, retry/TTL) still pending to replace in-memory publisher. -- Tests for Signals unit suite are now green; full Signals solution test run started—monitor to completion for coverage of new cache/event wiring. -- Full Signals solution restore/test still exceeding 60s and cancelled for time; rerun needed with warmed restore cache or extended execution window. +- Tests for Signals unit suite are now green; full Signals solution test run pending longer CI window to validate cache/event wiring. ## Next Checkpoints - Schedule CAS waiver review before 2025-11-20 to confirm remediation progress for SIGNALS-24-002/004/005. diff --git a/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md b/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md new file mode 100644 index 000000000..822f10561 --- /dev/null +++ b/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md @@ -0,0 +1,47 @@ +# Sprint 0150-0001-0001 · Scheduling & Automation + +## Topic & Scope +- Snapshot the Scheduling & Automation stream while upstream AirGap/Scanner/Graph deliverables land; backlog continues in Sprint 151+ files. +- Keep orchestration, Packs Registry, Scheduler, and TaskRunner waves ready to start once prerequisites are green. +- Working directory: `docs/implplan` (coordination only; module work occurs in respective service directories). + +## Dependencies & Concurrency +- Upstream sprints: Sprint 0120.A (AirGap), Sprint 0130.A (Scanner surface), Sprint 0140.A (Graph overlays) must stay green to unblock wave starts. +- Concurrency limits: 150.B depends on 150.A kickoff; 150.D waits for Orchestrator/Scheduler telemetry baselines (150.A + 150.C). + +## Documentation Prerequisites +- docs/modules/airgap/architecture.md +- docs/modules/scanner/architecture.md +- docs/modules/graph/architecture.md +- docs/modules/orchestrator/architecture.md +- docs/modules/scheduler/architecture.md +- docs/modules/taskrunner/architecture.md +- docs/modules/registry/architecture.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | 150.A-Orchestrator | TODO | Wait for Sprint 0120.A/0130.A/0140.A readiness; verify Scanner surface artifacts | Orchestrator Service Guild · AirGap Policy/Controller Guilds · Observability Guild | Kick off orchestration scheduling/telemetry baseline for automation epic. | +| 2 | 150.B-PacksRegistry | TODO | 150.A must reach DOING; confirm tenancy scaffolding from Orchestrator | Packs Registry Guild · Exporter Guild · Security Guild | Packs registry automation stream staged; start after Orchestrator scaffolding. | +| 3 | 150.C-Scheduler | TODO | Hold until 0140.A Graph overlays and 0130.A Scanner surface green | Scheduler WebService/Worker Guilds · Findings Ledger Guild · Observability Guild | Scheduler impact index improvements gated on Graph overlays. | +| 4 | 150.D-TaskRunner | TODO | Requires Orchestrator/Scheduler telemetry baselines (150.A/150.C) | Task Runner Guild · AirGap Guilds · Evidence Locker Guild | Execution engine upgrades and evidence integration to start post-baselines. | + +## Wave Coordination Snapshot +| Wave | Guild owners | Shared prerequisites | Status | Notes | +| --- | --- | --- | --- | --- | +| 150.A Orchestrator | Orchestrator Service Guild · AirGap Policy/Controller Guilds · Observability Guild | Sprint 0120.A – AirGap; Sprint 0130.A – Scanner; Sprint 0140.A – Graph | TODO | Pending confirmation that Scanner surface artifacts are ready; keep job telemetry work prepped for fast start. | +| 150.B PacksRegistry | Packs Registry Guild · Exporter Guild · Security Guild | Sprint 0120.A – AirGap; Sprint 0130.A – Scanner; Sprint 0140.A – Graph | TODO | Blocked on Orchestrator tenancy scaffolding; specs are ready once 150.A flips to DOING. | +| 150.C Scheduler | Scheduler WebService/Worker Guilds · Findings Ledger Guild · Observability Guild | Sprint 0120.A – AirGap; Sprint 0130.A – Scanner; Sprint 0140.A – Graph | TODO | Impact index improvements need Graph overlays; hold until 0140.A status improves. | +| 150.D TaskRunner | Task Runner Guild · AirGap Guilds · Evidence Locker Guild | Sprint 0120.A – AirGap; Sprint 0130.A – Scanner; Sprint 0140.A – Graph | TODO | Execution engine upgrades staged; start once Orchestrator/Scheduler telemetry baselines exist. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-18 | Normalised sprint doc to standard template; renamed from `SPRINT_150_scheduling_automation.md`. | Planning | + +## Decisions & Risks +- All waves remain gated on upstream AirGap/Scanner/Graph readiness; no new intra-decade dependencies introduced. +- This sprint is a coordination snapshot only; implementation tasks continue in Sprint 151+ and should mirror status changes here to avoid drift. + +## Next Checkpoints +- None scheduled; add next scheduling/automation sync once upstream readiness dates are confirmed. diff --git a/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md b/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md new file mode 100644 index 000000000..a564f933f --- /dev/null +++ b/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md @@ -0,0 +1,65 @@ +# Sprint 0151-0001-0001 · Scheduling & Automation · Orchestrator I + +## Topic & Scope +- Phase I of Scheduling & Automation focused on Orchestrator: air-gap controls, observability/telemetry, and OpenAPI/SDK surface hardening. +- Active snapshot only; historic items were moved to `docs/implplan/archived/tasks.md` (updated 2025-11-08). +- Working directory: `src/Orchestrator` (coordination tracked in `docs/implplan`). + +## Dependencies & Concurrency +- Upstream sprints: 0120.A (AirGap), 0130.A (Scanner surface), 0140.A (Graph overlays). Do not start net-new work until these stay green. +- Task ordering: `ORCH-AIRGAP-56-001 → 56-002 → 57-001 → 58-001`; `ORCH-OAS-61-001 → 61-002 → 62-001 → 63-001`; `ORCH-OBS-50-001 → 51-001 → 52-001 → 53-001 → 54-001 → 55-001`. `ORCH-SVC-32-001` can progress in parallel once dependencies are stable. + +## Documentation Prerequisites +- docs/modules/orchestrator/architecture.md +- docs/modules/airgap/architecture.md +- docs/modules/scanner/architecture.md +- docs/modules/graph/architecture.md +- docs/modules/telemetry/architecture.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-ORCH-AIRGAP-56-001-AWAIT-SPRINT-0120-A-A | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · AirGap Policy Guild | Orchestrator Service Guild · AirGap Policy Guild | Await Sprint 0120.A AirGap readiness; sealed-mode contracts not published.

Document artefact/deliverable for ORCH-AIRGAP-56-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-ORCH-AIRGAP-56-002-UPSTREAM-56-001-BLOCK | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · AirGap Controller Guild | Orchestrator Service Guild · AirGap Controller Guild | Upstream 56-001 blocked.

Document artefact/deliverable for ORCH-AIRGAP-56-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-ORCH-AIRGAP-57-001-UPSTREAM-56-002-BLOCK | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Mirror Creator Guild | Orchestrator Service Guild · Mirror Creator Guild | Upstream 56-002 blocked.

Document artefact/deliverable for ORCH-AIRGAP-57-001 and publish location so downstream tasks can proceed. | +| P4 | PREP-ORCH-AIRGAP-58-001-UPSTREAM-57-001-BLOCK | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Evidence Locker Guild | Orchestrator Service Guild · Evidence Locker Guild | Upstream 57-001 blocked.

Document artefact/deliverable for ORCH-AIRGAP-58-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-ORCH-OAS-61-001-ORCHESTRATOR-TELEMETRY-C | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · API Contracts Guild | Orchestrator Service Guild · API Contracts Guild | Orchestrator telemetry/contract inputs not available; wait for 150.A readiness.

Document artefact/deliverable for ORCH-OAS-61-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-ORCH-OAS-61-002-DEPENDS-ON-61-001 | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 61-001.

Document artefact/deliverable for ORCH-OAS-61-002 and publish location so downstream tasks can proceed. | +| P7 | PREP-ORCH-OAS-62-001-DEPENDS-ON-61-002 | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · SDK Generator Guild | Orchestrator Service Guild · SDK Generator Guild | Depends on 61-002.

Document artefact/deliverable for ORCH-OAS-62-001 and publish location so downstream tasks can proceed. | +| P8 | PREP-ORCH-OAS-63-001-DEPENDS-ON-62-001 | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · API Governance Guild | Orchestrator Service Guild · API Governance Guild | Depends on 62-001.

Document artefact/deliverable for ORCH-OAS-63-001 and publish location so downstream tasks can proceed. | +| P9 | PREP-ORCH-OBS-50-001-TELEMETRY-CORE-SPRINT-01 | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Observability Guild | Orchestrator Service Guild · Observability Guild | Telemetry Core (Sprint 0174) not yet available for orchestrator host.

Document artefact/deliverable for ORCH-OBS-50-001 and publish location so downstream tasks can proceed. | +| P10 | PREP-ORCH-OBS-51-001-DEPENDS-ON-50-001-TELEME | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · DevOps Guild | Orchestrator Service Guild · DevOps Guild | Depends on 50-001 + Telemetry schema.

Document artefact/deliverable for ORCH-OBS-51-001 and publish location so downstream tasks can proceed. | +| P11 | PREP-ORCH-OBS-52-001-DEPENDS-ON-51-001-REQUIR | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 51-001; requires event schema from Sprint 0150.A.

Document artefact/deliverable for ORCH-OBS-52-001 and publish location so downstream tasks can proceed. | +| P12 | PREP-ORCH-OBS-53-001-DEPENDS-ON-52-001-EVIDEN | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Evidence Locker Guild | Orchestrator Service Guild · Evidence Locker Guild | Depends on 52-001; Evidence Locker capsule inputs not frozen.

Document artefact/deliverable for ORCH-OBS-53-001 and publish location so downstream tasks can proceed. | +| P13 | PREP-ORCH-OBS-54-001-DEPENDS-ON-53-001 | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · Provenance Guild | Orchestrator Service Guild · Provenance Guild | Depends on 53-001.

Document artefact/deliverable for ORCH-OBS-54-001 and publish location so downstream tasks can proceed. | +| P14 | PREP-ORCH-OBS-55-001-DEPENDS-ON-54-001-INCIDE | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild · DevOps Guild | Orchestrator Service Guild · DevOps Guild | Depends on 54-001; incident contract absent.

Document artefact/deliverable for ORCH-OBS-55-001 and publish location so downstream tasks can proceed. | +| P15 | PREP-ORCH-SVC-32-001-UPSTREAM-READINESS-AIRGA | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Upstream readiness (AirGap/Scanner/Graph) not confirmed; postpone bootstrap.

Document artefact/deliverable for ORCH-SVC-32-001 and publish location so downstream tasks can proceed. | +| 1 | ORCH-AIRGAP-56-001 | BLOCKED (2025-11-19) | PREP-ORCH-AIRGAP-56-001-AWAIT-SPRINT-0120-A-A | Orchestrator Service Guild · AirGap Policy Guild | Enforce job descriptors to declare network intents; flag/reject external endpoints in sealed mode. | +| 2 | ORCH-AIRGAP-56-002 | BLOCKED (2025-11-19) | PREP-ORCH-AIRGAP-56-002-UPSTREAM-56-001-BLOCK | Orchestrator Service Guild · AirGap Controller Guild | Surface sealing status and staleness in scheduling decisions; block runs when budgets exceeded. | +| 3 | ORCH-AIRGAP-57-001 | BLOCKED (2025-11-19) | PREP-ORCH-AIRGAP-57-001-UPSTREAM-56-002-BLOCK | Orchestrator Service Guild · Mirror Creator Guild | Add job type `mirror.bundle` with audit + provenance outputs. | +| 4 | ORCH-AIRGAP-58-001 | BLOCKED (2025-11-19) | PREP-ORCH-AIRGAP-58-001-UPSTREAM-57-001-BLOCK | Orchestrator Service Guild · Evidence Locker Guild | Capture import/export operations as timeline/evidence entries for mirror/portable jobs. | +| 5 | ORCH-OAS-61-001 | BLOCKED (2025-11-19) | PREP-ORCH-OAS-61-001-ORCHESTRATOR-TELEMETRY-C | Orchestrator Service Guild · API Contracts Guild | Document orchestrator endpoints in per-service OAS with pagination/idempotency/error envelope examples. | +| 6 | ORCH-OAS-61-002 | BLOCKED (2025-11-19) | PREP-ORCH-OAS-61-002-DEPENDS-ON-61-001 | Orchestrator Service Guild | Implement `GET /.well-known/openapi`; align version metadata with runtime build. | +| 7 | ORCH-OAS-62-001 | BLOCKED (2025-11-19) | PREP-ORCH-OAS-62-001-DEPENDS-ON-61-002 | Orchestrator Service Guild · SDK Generator Guild | Ensure SDK paginators/operations support job APIs; add SDK smoke tests for schedule/retry. | +| 8 | ORCH-OAS-63-001 | BLOCKED (2025-11-19) | PREP-ORCH-OAS-63-001-DEPENDS-ON-62-001 | Orchestrator Service Guild · API Governance Guild | Emit deprecation headers/doc for legacy endpoints; update notifications metadata. | +| 9 | ORCH-OBS-50-001 | BLOCKED (2025-11-19) | PREP-ORCH-OBS-50-001-TELEMETRY-CORE-SPRINT-01 | Orchestrator Service Guild · Observability Guild | Wire `StellaOps.Telemetry.Core` into orchestrator host; instrument schedulers/control APIs with spans/logs/metrics. | +| 10 | ORCH-OBS-51-001 | BLOCKED (2025-11-19) | PREP-ORCH-OBS-51-001-DEPENDS-ON-50-001-TELEME | Orchestrator Service Guild · DevOps Guild | Publish golden-signal metrics and SLOs; emit burn-rate alerts; provide Grafana dashboards + alert rules. | +| 11 | ORCH-OBS-52-001 | BLOCKED (2025-11-19) | PREP-ORCH-OBS-52-001-DEPENDS-ON-51-001-REQUIR | Orchestrator Service Guild | Emit `timeline_event` lifecycle objects with trace IDs/run IDs/tenant/project; add contract tests and Kafka/NATS emitter with retries. | +| 12 | ORCH-OBS-53-001 | BLOCKED (2025-11-19) | PREP-ORCH-OBS-53-001-DEPENDS-ON-52-001-EVIDEN | Orchestrator Service Guild · Evidence Locker Guild | Generate job capsule inputs for Evidence Locker; invoke snapshot hooks; enforce redaction guard. | +| 13 | ORCH-OBS-54-001 | BLOCKED (2025-11-19) | PREP-ORCH-OBS-54-001-DEPENDS-ON-53-001 | Orchestrator Service Guild · Provenance Guild | Produce DSSE attestations for orchestrator-scheduled jobs; store references in timeline + Evidence Locker; add verification endpoint `/jobs/{id}/attestation`. | +| 14 | ORCH-OBS-55-001 | BLOCKED (2025-11-19) | PREP-ORCH-OBS-55-001-DEPENDS-ON-54-001-INCIDE | Orchestrator Service Guild · DevOps Guild | Incident mode hooks (sampling overrides, extended retention, debug spans) with automatic activation on SLO burn-rate breach; emit activation/deactivation events. | +| 15 | ORCH-SVC-32-001 | BLOCKED (2025-11-19) | PREP-ORCH-SVC-32-001-UPSTREAM-READINESS-AIRGA | Orchestrator Service Guild | Bootstrap service project/config and Postgres schema/migrations for sources, runs, jobs, dag_edges, artifacts, quotas, schedules. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-18 | Normalised sprint doc to standard template; renamed from `SPRINT_151_orchestrator_i.md`. | Planning | +| 2025-11-19 | Set all tasks to BLOCKED pending upstream readiness (AirGap/Scanner/Graph), Telemetry Core availability, and Orchestrator event schema; no executable work until contracts land. | Implementer | + +## Decisions & Risks +- Start of work gated on AirGap/Scanner/Graph dependencies staying green; reassess before moving tasks to DOING. +- Ensure status changes here mirror module boards to avoid drift between coordination doc and execution evidence. + +## Next Checkpoints +- None scheduled; add orchestrator scheduling/automation sync once upstream readiness dates are committed. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md b/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md new file mode 100644 index 000000000..7a7cc036f --- /dev/null +++ b/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md @@ -0,0 +1,52 @@ +# Sprint 0152-0001-0002 · Orchestrator II (Scheduling & Automation) + +## Topic & Scope +- Build scheduler DAG planner, job lifecycle APIs/streams, and worker claim/heartbeat wiring without issuing control actions yet. +- Add observability (REST, SSE, metrics), rate limits, backfill/dead-letter handling, quotas, and GA packaging for orchestrator service. +- Keep outputs aggregation-only with provenance-ready audit/export ledger and offline-friendly deploy artefacts. +- **Working directory:** `src/Orchestrator/StellaOps.Orchestrator`. + +## Dependencies & Concurrency +- Upstream: Sprint 0151-0001-0001 (Orchestrator I) must land first. +- Concurrency: execute tasks in table order (planner → APIs → streams → worker endpoints → rate limits → backfill → ledger → GA packaging → export job class). + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/orchestrator/architecture.md +- src/Orchestrator/StellaOps.Orchestrator/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | ORCH-SVC-32-002 | TODO | Depends on ORCH-SVC-32-001 (Sprint 0151). | Orchestrator Service Guild (`src/Orchestrator/StellaOps.Orchestrator`) | Implement scheduler DAG planner + dependency resolver, job state machine, critical-path metadata (no control actions yet). | +| 2 | ORCH-SVC-32-003 | TODO | Depends on 32-002. | Orchestrator Service Guild | Expose read-only REST APIs (sources, runs, jobs, DAG) with OpenAPI, validation, pagination, tenant scoping. | +| 3 | ORCH-SVC-32-004 | TODO | Depends on 32-003. | Orchestrator Service Guild | Implement WebSocket/SSE stream for job/run updates; emit structured metrics counters/histograms; add health probes. | +| 4 | ORCH-SVC-32-005 | TODO | Depends on 32-004. | Orchestrator Service Guild | Deliver worker claim/heartbeat/progress endpoints capturing artifact metadata/checksums and enforcing idempotency keys. | +| 5 | ORCH-SVC-33-001 | TODO | Depends on 32-005. | Orchestrator Service Guild | Enable `sources` tests (control-plane validation). | +| 6 | ORCH-SVC-33-002 | TODO | Depends on 33-001. | Orchestrator Service Guild | Per-source/tenant adaptive token-bucket limiter, concurrency caps, backpressure reacting to upstream 429/503. | +| 7 | ORCH-SVC-33-003 | TODO | Depends on 33-002. | Orchestrator Service Guild | Watermark/backfill manager with event-time windows, duplicate suppression, dry-run preview endpoint, safety validations. | +| 8 | ORCH-SVC-33-004 | TODO | Depends on 33-003. | Orchestrator Service Guild | Dead-letter store, replay endpoints, error classification with remediation hints + notification hooks. | +| 9 | ORCH-SVC-34-001 | TODO | Depends on 33-004. | Orchestrator Service Guild | Quota management APIs, per-tenant SLO burn-rate computation, alert budget tracking via metrics. | +| 10 | ORCH-SVC-34-002 | TODO | Depends on 34-001. | Orchestrator Service Guild | Audit log + immutable run ledger export with signed manifest and provenance chain to artifacts. | +| 11 | ORCH-SVC-34-003 | TODO | Depends on 34-002. | Orchestrator Service Guild | Perf/scale validation (≥10k pending jobs, dispatch P95 <150 ms); autoscaling hooks; health probes. | +| 12 | ORCH-SVC-34-004 | TODO | Depends on 34-003. | Orchestrator Service Guild | GA packaging: container image, Helm overlays, offline bundle seeds, provenance attestations, compliance checklist. | +| 13 | ORCH-SVC-35-101 | TODO | Depends on 34-004. | Orchestrator Service Guild | Register `export` job type with quotas/rate policies; expose telemetry; ensure exporter workers heartbeat via orchestrator contracts. | +| 14 | ORCH-SVC-36-101 | TODO | Depends on 35-101. | Orchestrator Service Guild | Capture distribution metadata and retention timestamps for export jobs; update dashboards and SSE payloads. | +| 15 | ORCH-SVC-37-101 | TODO | Depends on 36-101. | Orchestrator Service Guild | Enable scheduled export runs, retention pruning hooks, failure alerting tied to export job class. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub (legacy format) created; awaiting orchestrator phase I completion. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_152_orchestrator_ii.md` to `SPRINT_0152_0001_0002_orchestrator_ii.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | + +## Decisions & Risks +- All tasks depend on outputs from Orchestrator I (32-001); sprint remains TODO until upstream ship. +- Maintain deterministic scheduling semantics; avoid issuing control actions until DAG planner/state machine validated. +- Ensure offline/air-gap deploy artifacts (Helm/overlays) align with GA packaging in task 34-004. + +## Next Checkpoints +- Kickoff once ORCH-SVC-32-001 lands (date TBD). diff --git a/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md b/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md index c974e1e89..93a3fe404 100644 --- a/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md +++ b/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md @@ -19,10 +19,13 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-ORCH-SVC-41-101-DEPENDS-ON-38-101-ENVELO | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 38-101 envelope + DAL; cannot register pack-run without API/storage schema.

Document artefact/deliverable for ORCH-SVC-41-101 and publish location so downstream tasks can proceed. | +| P2 | PREP-ORCH-SVC-42-101-DEPENDS-ON-41-101-PACK-R | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | Depends on 41-101 pack-run plumbing and streaming contract.

Document artefact/deliverable for ORCH-SVC-42-101 and publish location so downstream tasks can proceed. | +| P3 | PREP-ORCH-TEN-48-001-WEBSERVICE-LACKS-JOB-DAL | TODO | Due 2025-11-23 · Accountable: Orchestrator Service Guild | Orchestrator Service Guild | WebService lacks job DAL/routes; need tenant context plumbing before enforcement.

Document artefact/deliverable for ORCH-TEN-48-001 and publish location so downstream tasks can proceed. | | 1 | ORCH-SVC-38-101 | BLOCKED | Waiting on ORCH-SVC-37-101 envelope field/semantics approval; webservice DAL still missing. | Orchestrator Service Guild | Standardize event envelope (policy/export/job lifecycle) with idempotency keys, ensure export/job failure events published to notifier bus with provenance metadata. | -| 2 | ORCH-SVC-41-101 | BLOCKED | Depends on 38-101 envelope + DAL; cannot register pack-run without API/storage schema. | Orchestrator Service Guild | Register `pack-run` job type, persist run metadata, integrate logs/artifacts collection, and expose API for Task Runner scheduling. | -| 3 | ORCH-SVC-42-101 | BLOCKED | Depends on 41-101 pack-run plumbing and streaming contract. | Orchestrator Service Guild | Stream pack run logs via SSE/WS, add manifest endpoints, enforce quotas, and emit pack run events to Notifications Studio. | -| 4 | ORCH-TEN-48-001 | BLOCKED | WebService lacks job DAL/routes; need tenant context plumbing before enforcement. | Orchestrator Service Guild | Include `tenant_id`/`project_id` in job specs, set DB session context before processing, enforce context on all queries, and reject jobs missing tenant metadata. | +| 2 | ORCH-SVC-41-101 | BLOCKED | PREP-ORCH-SVC-41-101-DEPENDS-ON-38-101-ENVELO | Orchestrator Service Guild | Register `pack-run` job type, persist run metadata, integrate logs/artifacts collection, and expose API for Task Runner scheduling. | +| 3 | ORCH-SVC-42-101 | BLOCKED | PREP-ORCH-SVC-42-101-DEPENDS-ON-41-101-PACK-R | Orchestrator Service Guild | Stream pack run logs via SSE/WS, add manifest endpoints, enforce quotas, and emit pack run events to Notifications Studio. | +| 4 | ORCH-TEN-48-001 | BLOCKED | PREP-ORCH-TEN-48-001-WEBSERVICE-LACKS-JOB-DAL | Orchestrator Service Guild | Include `tenant_id`/`project_id` in job specs, set DB session context before processing, enforce context on all queries, and reject jobs missing tenant metadata. | | 5 | WORKER-GO-32-001 | DONE | Bootstrap Go SDK scaffolding and smoke sample. | Worker SDK Guild | Bootstrap Go SDK project with configuration binding, auth headers, job claim/acknowledge client, and smoke sample. | | 6 | WORKER-GO-32-002 | DONE | Depends on WORKER-GO-32-001; add heartbeat, metrics, retries. | Worker SDK Guild | Add heartbeat/progress helpers, structured logging hooks, Prometheus metrics, and jittered retry defaults. | | 7 | WORKER-GO-33-001 | DONE | Depends on WORKER-GO-32-002; implement artifact publish helpers. | Worker SDK Guild | Implement artifact publish helpers (object storage client, checksum hashing, metadata payload) and idempotency guard. | @@ -37,6 +40,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-07 | Still not started — Authority pack RBAC (AUTH-PACKS-43-001) remains blocked pending approvals/log-stream APIs. | Coordination | | 2025-11-17 | Coordinator approved interim token-scoped access for AUTH-PACKS-43-001; proceed with log-stream APIs using scoped tokens while full RBAC completes. | Coordination | | 2025-11-17 | Normalised sprint file to standard template and renamed from `SPRINT_153_orchestrator_iii.md` to `SPRINT_0153_0001_0003_orchestrator_iii.md`. | PM | @@ -51,6 +55,7 @@ | 2025-11-17 | Marked ORCH-SVC-38/41/42 blocked pending upstream event envelope spec (ORCH-SVC-37-101) and downstream pack-run contract. | Worker SDK Guild | | 2025-11-18 | No further progress possible: event envelope spec (ORCH-SVC-37-101) and missing Orchestrator WebService DAL keep ORCH-SVC-38/41/42 and ORCH-TEN-48-001 blocked. | Orchestrator Service Guild | | 2025-11-19 | Drafted event envelope doc (`docs/modules/orchestrator/event-envelope.md`) and set ORCH-SVC-38-101 to DOING pending spec approval. | Orchestrator Service Guild | +| 2025-11-19 | Clarified ORCH-SVC-38-101 remains BLOCKED until ORCH-SVC-37-101 envelope semantics are approved; webservice DAL still missing. | Implementer | | 2025-11-18 | ORCH-TEN-48-001 blocked: orchestrator WebService is still template-only (no job DAL/routes), cannot enforce tenant context until real endpoints and DB session context exist. | Worker SDK Guild | | 2025-11-19 | Set ORCH-SVC-38/41/42 and ORCH-TEN-48-001 to BLOCKED; awaiting ORCH-SVC-37-101 envelope approval and WebService DAL/schema. | Orchestrator Service Guild | diff --git a/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md b/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md new file mode 100644 index 000000000..7458f655d --- /dev/null +++ b/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md @@ -0,0 +1,40 @@ +# Sprint 0154-0001-0001 · Packs Registry (Scheduling & Automation 150.B) + +## Topic & Scope +- Stand up Packs Registry service: indexing, provenance storage, signature verification, and lifecycle management. +- Add version lifecycle (promote/deprecate), provenance exports, mirroring, attestation integration, and compliance dashboards. +- Keep registry offline-friendly with RBAC, audit logs, and Offline Kit seed support. +- **Working directory:** `src/PacksRegistry/StellaOps.PacksRegistry`. + +## Dependencies & Concurrency +- Upstream: Sprint 120.A (AirGap), 130.A (Scanner), 140.A (Graph) provide pack metadata and graph inputs. +- Concurrency: execute tasks in table order; all tasks currently TODO. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/graph/architecture.md +- docs/modules/devops/architecture.md +- Any PacksRegistry AGENTS.md (if present under src/PacksRegistry). + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | PACKS-REG-41-001 | TODO | Start registry service + migrations. | Packs Registry Guild (`src/PacksRegistry/StellaOps.PacksRegistry`) | Implement registry service, migrations (`packs_index`, `parity_matrix`, provenance docs); upload/list/get; signature verification; RBAC; provenance manifest storage. | +| 2 | PACKS-REG-42-001 | TODO | Depends on 41-001. | Packs Registry Guild | Version lifecycle (promote/deprecate), tenant allowlists, provenance export, signature rotation, audit logs, Offline Kit seed support. | +| 3 | PACKS-REG-43-001 | TODO | Depends on 42-001. | Packs Registry Guild | Registry mirroring, pack signing policies, attestation integration, compliance dashboards; integrate with Export Center. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub created; awaiting staffing. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_154_packsregistry.md` to `SPRINT_0154_0001_0001_packsregistry.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | + +## Decisions & Risks +- Registry relies on upstream pack metadata/graph contracts; keep schema aligned before migrations run. +- Ensure offline posture: signature verification, provenance storage, audit logs, and Offline Kit seeds are mandatory before GA. + +## Next Checkpoints +- Schedule kickoff once staffing confirmed (date TBD). diff --git a/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md b/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md index a86d1f636..6912242af 100644 --- a/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md +++ b/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md @@ -19,14 +19,16 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-SCHED-SURFACE-01-NEED-SURFACE-FS-POINTER | TODO | Due 2025-11-23 · Accountable: Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Need Surface.FS pointer model/contract; awaiting design input before planning deltas.

Document artefact/deliverable for SCHED-SURFACE-01 and publish location so downstream tasks can proceed. | +| P2 | PREP-SCHED-WORKER-23-101-WAITING-ON-POLICY-GU | TODO | Due 2025-11-23 · Accountable: Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Waiting on Policy guild to supply activation event contract and throttle source.

Document artefact/deliverable for SCHED-WORKER-23-101 and publish location so downstream tasks can proceed. | | 0 | AGENTS-SCHEDULER-UPDATE | DONE | `src/Scheduler/AGENTS.md` created and published. | Project Manager · Architecture Guild | Populate module AGENTS charter covering roles, docs, determinism/testing rules, and allowed shared libs. | | 1 | SCHED-IMPACT-16-303 | DONE | Implemented removal + snapshot/restore with compaction; snapshot payloads ready for RocksDB/Redis persistence. | Scheduler ImpactIndex Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex) | Snapshot/compaction + invalidation for removed images; persistence to RocksDB/Redis per architecture. | -| 2 | SCHED-SURFACE-01 | BLOCKED | Need Surface.FS pointer model/contract; awaiting design input before planning deltas. | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Evaluate Surface.FS pointers when planning delta scans to avoid redundant work and prioritise drift-triggered assets. | +| 2 | SCHED-SURFACE-01 | BLOCKED | PREP-SCHED-SURFACE-01-NEED-SURFACE-FS-POINTER | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Evaluate Surface.FS pointers when planning delta scans to avoid redundant work and prioritise drift-triggered assets. | | 3 | SCHED-VULN-29-001 | DONE | Resolver job APIs implemented with scope enforcement; in-memory service stub (upgrade to persistent store later). | Scheduler WebService Guild, Findings Ledger Guild (src/Scheduler/StellaOps.Scheduler.WebService) | Expose resolver job APIs (`POST /vuln/resolver/jobs`, `GET /vuln/resolver/jobs/{id}`) to trigger candidate recomputation per artifact/policy change with RBAC and rate limits. | | 4 | SCHED-VULN-29-002 | DONE | Depends on SCHED-VULN-29-001; define webhook contract for backlog breach notifications. | Scheduler WebService Guild, Observability Guild (src/Scheduler/StellaOps.Scheduler.WebService) | Provide projector lag metrics endpoint and webhook notifications for backlog breaches consumed by DevOps dashboards. | | 5 | SCHED-WEB-20-002 | DONE | Simulation trigger + preview endpoint implemented. | Scheduler WebService Guild (src/Scheduler/StellaOps.Scheduler.WebService) | Provide simulation trigger endpoint returning diff preview metadata and job state for UI/CLI consumption. | | 6 | SCHED-WORKER-21-203 | DONE | Metrics added with tenant/graph tags; worker build green. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Export metrics (`graph_build_seconds`, `graph_jobs_inflight`, `overlay_lag_seconds`) and structured logs with tenant/graph identifiers. | -| 7 | SCHED-WORKER-23-101 | BLOCKED | Waiting on Policy guild to supply activation event contract and throttle source. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement policy re-evaluation worker that shards assets, honours rate limits, and updates progress for Console after policy activation events. | +| 7 | SCHED-WORKER-23-101 | BLOCKED | PREP-SCHED-WORKER-23-101-WAITING-ON-POLICY-GU | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement policy re-evaluation worker that shards assets, honours rate limits, and updates progress for Console after policy activation events. | | 8 | SCHED-WORKER-23-102 | BLOCKED | Blocked by SCHED-WORKER-23-101. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Add reconciliation job ensuring re-eval completion within SLA, emitting alerts on backlog and persisting status to `policy_runs`. | | 9 | SCHED-WORKER-25-101 | BLOCKED | Blocked by SCHED-WORKER-23-102. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement exception lifecycle worker handling auto-activation/expiry and publishing `exception.*` events with retries/backoff. | | 10 | SCHED-WORKER-25-102 | BLOCKED | Blocked by SCHED-WORKER-25-101. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Add expiring notification job generating digests, marking `expiring` state, updating metrics/alerts. | @@ -35,6 +37,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-17 | Added graph metrics (`graph_build_seconds`, `graph_jobs_inflight`, `overlay_lag_seconds`) with tenant/graph tags; worker library build succeeded. | Scheduler Worker Guild | | 2025-11-17 | Added resolver job APIs (`POST/GET /api/v1/scheduler/vuln/resolver/jobs`) with scope enforcement and in-memory job service stub. | Scheduler WebService Guild | | 2025-11-18 | Added per-tenant rate limiting for resolver job creation (in-memory implementation). | Scheduler WebService Guild | @@ -64,4 +67,4 @@ - SCHED-WORKER-23-101/102/25-101/25-102/26-201 blocked on Policy guild supplying activation event shape + throttling guidance; downstream workers sit until contract lands. ## Next Checkpoints -- None scheduled; set once worker API scaffolding and GraphJobs accessibility fixes land. +- None scheduled; set once worker API scaffolding and GraphJobs accessibility fixes land. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md b/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md index c1f0384a6..a684890ba 100644 --- a/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md +++ b/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md @@ -19,6 +19,7 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U | BLOCKED | Due 2025-11-23 · Accountable: Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Blocked by upstream stream schema design; depends on prior resolver/eval pipeline readiness.

Document artefact/deliverable for SCHED-WORKER-CONSOLE-23-201 and publish location so downstream tasks can proceed. | | 0 | AGENTS-SCHEDULER-UPDATE | DONE | `src/Scheduler/AGENTS.md` created and published. | Project Manager · Architecture Guild | Create working-directory charter defining roles, prerequisites, determinism/testing rules, and allowed shared libs. | | 1 | SCHED-WORKER-26-202 | BLOCKED | Blocked by SCHED-WORKER-26-201 (reachability joiner not delivered yet). | Scheduler Worker Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement staleness monitor + notifier for outdated reachability facts, publishing warnings and updating dashboards. | | 2 | SCHED-WORKER-27-301 | BLOCKED | Blocked by SCHED-WORKER-26-202. | Scheduler Worker Guild, Policy Registry Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement policy batch simulation worker: shard SBOM inventories, invoke Policy Engine, emit partial results, handle retries/backoff, and publish progress events. | @@ -27,12 +28,15 @@ | 5 | SCHED-WORKER-29-001 | BLOCKED | Blocked by SCHED-WORKER-27-303. | Scheduler Worker Guild, Findings Ledger Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Implement resolver worker generating candidate findings from inventory + advisory evidence, respecting ecosystem version semantics and path scope; emit jobs for policy evaluation. | | 6 | SCHED-WORKER-29-002 | BLOCKED | Blocked by SCHED-WORKER-29-001. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Build evaluation orchestration worker invoking Policy Engine batch eval, writing results to Findings Ledger projector queue, and handling retries/backoff. | | 7 | SCHED-WORKER-29-003 | BLOCKED | Blocked by SCHED-WORKER-29-002. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Add monitoring for resolver/evaluation backlog, SLA breaches, and export job queue; expose metrics/alerts feeding DevOps dashboards. | -| 8 | SCHED-WORKER-CONSOLE-23-201 | BLOCKED | Blocked by upstream stream schema design; depends on prior resolver/eval pipeline readiness. | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Stream run progress events (stage status, tuples processed, SLA hints) to Redis/NATS for Console SSE, with heartbeat, dedupe, and retention policy. Publish metrics + structured logs for queue lag. | -| 9 | SCHED-WORKER-CONSOLE-23-202 | BLOCKED | Blocked by CONSOLE-23-201. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Coordinate evidence bundle jobs (enqueue, track status, cleanup) and expose job manifests to Web gateway; ensure idempotent reruns and cancellation support. | +| 8 | SCHED-WORKER-CONSOLE-23-201 | BLOCKED | PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U | Scheduler Worker Guild, Observability Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Stream run progress events (stage status, tuples processed, SLA hints) to Redis/NATS for Console SSE, with heartbeat, dedupe, and retention policy. Publish metrics + structured logs for queue lag. | +| 9 | SCHED-WORKER-CONSOLE-23-202 | BLOCKED | SCHED-WORKER-CONSOLE-23-201. | Scheduler Worker Guild, Policy Guild (src/Scheduler/__Libraries/StellaOps.Scheduler.Worker) | Coordinate evidence bundle jobs (enqueue, track status, cleanup) and expose job manifests to Web gateway; ensure idempotent reruns and cancellation support. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Clarified dependency for SCHED-WORKER-CONSOLE-23-202 to point at SCHED-WORKER-CONSOLE-23-201. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Marked PREP-SCHED-WORKER-CONSOLE-23-201 BLOCKED because upstream stream schema and resolver/eval pipeline contracts are still absent, keeping CONSOLE-23-201/202 gated. | Project Mgmt | | 2025-11-17 | Normalised sprint, renamed to `SPRINT_0156_0001_0002_scheduler_ii`, and marked tasks BLOCKED pending `src/Scheduler/AGENTS.md`. | Scheduler Worker Guild | | 2025-11-17 | Created `src/Scheduler/AGENTS.md`; unblocked tasks and reset to TODO respecting dependencies. | Scheduler Worker Guild | | 2025-11-18 | Marked all tasks BLOCKED awaiting upstream reachability worker (SCHED-WORKER-26-201) and subsequent contract handoffs (Policy activation events, stream schema). | Scheduler Worker Guild | diff --git a/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md b/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md new file mode 100644 index 000000000..639d07270 --- /dev/null +++ b/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md @@ -0,0 +1,52 @@ +# Sprint 0157-0001-0001 · TaskRunner I (Scheduling & Automation 150.D) + +## Topic & Scope +- Stand up TaskRunner service: pack run API, execution engine, air-gap enforcement, evidence capture, and observability. +- Provide pack run lifecycle APIs/SDK, telemetry, OAS, and offline-friendly bundles with provenance. +- **Working directory:** `src/TaskRunner/StellaOps.TaskRunner`. + +## Dependencies & Concurrency +- Upstream: Sprint 120.A (AirGap), 130.A (Scanner), 140.A (Graph). +- Concurrency: execute tasks in table order; RUN/OAS/OBS chains must respect dependencies. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/taskrunner/architecture.md (if available) +- src/TaskRunner/StellaOps.TaskRunner/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | TASKRUN-41-001 | TODO | Bootstrap service + migrations. | Task Runner Guild (`src/TaskRunner/StellaOps.TaskRunner`) | Define migrations (`pack_runs`, `pack_run_logs`, `pack_artifacts`); implement run API (create/get/log stream), local executor, approvals pause, artifact capture, provenance manifest generation. | +| 2 | TASKRUN-AIRGAP-56-001 | TODO | Depends on 41-001. | Task Runner Guild · AirGap Policy Guild | Enforce plan-time validation rejecting non-allowlisted network calls in sealed mode; surface remediation errors. | +| 3 | TASKRUN-AIRGAP-56-002 | TODO | Depends on 56-001. | Task Runner Guild · AirGap Importer Guild | Add helper steps for bundle ingestion (checksum verification, staging to object store) with deterministic outputs. | +| 4 | TASKRUN-AIRGAP-57-001 | TODO | Depends on 56-002. | Task Runner Guild · AirGap Controller Guild | Refuse to execute plans when environment sealed=false but declared sealed install; emit advisory timeline events. | +| 5 | TASKRUN-AIRGAP-58-001 | TODO | Depends on 57-001. | Task Runner Guild · Evidence Locker Guild | Capture bundle import job transcripts, hashed inputs/outputs into portable evidence bundles. | +| 6 | TASKRUN-42-001 | TODO | Continue execution engine upgrades (loops/conditionals/maxParallel), simulation mode, policy gate integration, deterministic failure recovery. | Task Runner Guild (`src/TaskRunner/StellaOps.TaskRunner`) | Execution engine enhancements + simulation API/CLI. | +| 7 | TASKRUN-OAS-61-001 | TODO | Document APIs once run endpoints stable. | Task Runner Guild · API Contracts Guild | Document TaskRunner APIs (pack runs, logs, approvals) with streaming schemas/examples. | +| 8 | TASKRUN-OAS-61-002 | TODO | Depends on 61-001. | Task Runner Guild | Expose `GET /.well-known/openapi` returning signed spec metadata, build version, ETag. | +| 9 | TASKRUN-OAS-62-001 | TODO | Depends on 61-002. | Task Runner Guild · SDK Generator Guild | SDK examples for pack run lifecycle; streaming log helpers; paginator wrappers. | +| 10 | TASKRUN-OAS-63-001 | TODO | Depends on 62-001. | Task Runner Guild · API Governance Guild | Sunset/deprecation headers + notifications for legacy pack APIs. | +| 11 | TASKRUN-OBS-50-001 | TODO | Telemetry core adoption. | Task Runner Guild | Add telemetry core in host + worker; spans/logs include `trace_id`, `tenant_id`, `run_id`, scrubbed transcripts. | +| 12 | TASKRUN-OBS-51-001 | TODO | Depends on 50-001. | Task Runner Guild · DevOps Guild | Metrics for step latency, retries, queue depth, sandbox resource usage; define SLOs; burn-rate alerts. | +| 13 | TASKRUN-OBS-52-001 | TODO | Depends on 51-001. | Task Runner Guild | Timeline events for pack runs (`pack.started`, `pack.step.completed`, `pack.failed`) with evidence pointers/policy context; dedupe + retry. | +| 14 | TASKRUN-OBS-53-001 | TODO | Depends on 52-001. | Task Runner Guild · Evidence Locker Guild | Capture step transcripts, artifact manifests, environment digests, policy approvals into evidence locker snapshots; ensure redaction + hash chain. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-04 | Resumed TASKRUN-42-001: scoped execution engine upgrades (loops/conditionals/maxParallel), simulation mode, policy gate integration, deterministic failure recovery. | Task Runner Guild | +| 2025-11-04 | Worker/WebService wiring in place: execution graph honors `maxParallel`/`continueOnError`, retry windows persisted, simulation API exposed. | Task Runner Guild | +| 2025-11-04 | Continued TASKRUN-42-001: cleaning persistence anomalies, validating retry metadata, wiring simulation preview into CLI surface. | Task Runner Guild | +| 2025-11-04 | CLI command `stella task-runner simulate` wired to new endpoint with JSON/table output modes. | Task Runner Guild | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_157_taskrunner_i.md` to `SPRINT_0157_0001_0001_taskrunner_i.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to prevent divergent updates. | Implementer | + +## Decisions & Risks +- Execution engine contract must remain deterministic; avoid uncontrolled parallelism until SLOs/telemetry validated. +- Air-gap enforcement depends on policy/airgap contracts; keep sealed-mode validation strict before enabling helper steps. + +## Next Checkpoints +- Schedule kickoff after confirming upstream Sprint 120/130/140 inputs (date TBD). diff --git a/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md b/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md new file mode 100644 index 000000000..ef98c2478 --- /dev/null +++ b/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md @@ -0,0 +1,36 @@ +# Sprint 0158-0001-0002 · TaskRunner II (Scheduling & Automation 150.D) + +## Topic & Scope +- TaskRunner phase II: attestations, incident mode, and tenant scoping for pack runs. +- **Working directory:** `src/TaskRunner/StellaOps.TaskRunner`. + +## Dependencies & Concurrency +- Upstream: TaskRunner I (Sprint 0157-0001-0001) must land first. +- Concurrency: tasks follow OBS → TEN dependency chain; all currently TODO. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/taskrunner/architecture.md (if available) +- src/TaskRunner/StellaOps.TaskRunner/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | TASKRUN-OBS-54-001 | TODO | Depends on TASKRUN-OBS-53-001 (Sprint 0157). | Task Runner Guild · Provenance Guild (`src/TaskRunner/StellaOps.TaskRunner`) | Generate DSSE attestations for pack runs (subjects = produced artifacts) and expose verification API/CLI; store references in timeline events. | +| 2 | TASKRUN-OBS-55-001 | TODO | Depends on 54-001. | Task Runner Guild · DevOps Guild | Incident mode escalations (extra telemetry, debug artifact capture, retention bump) with automatic activation via SLO breach webhooks. | +| 3 | TASKRUN-TEN-48-001 | TODO | Parallel once tenancy policy defined. | Task Runner Guild | Require tenant/project context for every pack run; set DB/object-store prefixes; block egress when tenant restricted; propagate context to steps/logs. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_158_taskrunner_ii.md` to `SPRINT_0158_0001_0002_taskrunner_ii.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | + +## Decisions & Risks +- Attestation and incident-mode behaviors depend on outputs from TaskRunner I; keep blocked until 0157 tasks complete. +- Tenant scoping must align with platform RLS and egress rules before enabling enforcement. + +## Next Checkpoints +- Kickoff after Sprint 0157 completion (date TBD). diff --git a/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md b/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md index 32e3e8994..08e3972dc 100644 --- a/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md +++ b/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md @@ -22,18 +22,22 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-EVIDENCE-LOCKER-GUILD-SECURITY-GUILD-DOC | TODO | Due 2025-11-23 · Accountable: Waiting on AdvisoryAI schema + orchestrator ledger envelopes to freeze. | Waiting on AdvisoryAI schema + orchestrator ledger envelopes to freeze. | BLOCKED (2025-11-17).

Document artefact/deliverable for Evidence Locker Guild · Security Guild · Docs Guild, Exporter Service Guild · Mirror Creator Guild · DevOps Guild, Timeline Indexer Guild · Evidence Locker Guild · Security Guild and publish location so downstream tasks can proceed. | +| P2 | PREP-ORCHESTRATOR-NOTIFICATIONS-SCHEMA-HANDOF | TODO | Due 2025-11-23 · Accountable: Planning | Planning | MISSED; escalate to Wave 150/140 leads and record new ETA; keep tasks BLOCKED.

Document artefact/deliverable for Orchestrator + Notifications schema handoff (Orchestrator Service + Notifications Guilds) and publish location so downstream tasks can proceed. | +| P3 | PREP-ESCALATION-FOLLOW-UP-ADVISORYAI-ORCHESTR | TODO | Due 2025-11-23 · Accountable: Planning | Planning | If no dates provided, mark BLOCKED in respective sprints and escalate to Wave leads.

Document artefact/deliverable for Escalation follow-up (AdvisoryAI, Orchestrator/Notifications) and publish location so downstream tasks can proceed. | +| P4 | PREP-160-A-160-B-160-C-ESCALATE-TO-WAVE-150-1 | DONE (2025-11-19) | Due 2025-11-23 · Accountable: Planning | Planning | Escalation sent to Wave 150/140 leads; awaiting new ETAs recorded in Sprint 110/150/140. | | 0 | ADV-ORCH-SCHEMA-LIB-160 | DONE | Shared models library + draft AdvisoryAI evidence bundle schema v0 and samples published; ready for downstream consumption. | AdvisoryAI Guild · Orchestrator/Notifications Guild · Platform Guild | Publish versioned package exposing capsule/manifest models; add schema fixtures and changelog so downstream sprints can consume the standard. | -| 1 | 160.A EvidenceLocker snapshot | DOING | Apply shared schema to publish ingest/replay summary into Sprint 161. | Evidence Locker Guild · Security Guild | Maintain readiness snapshot; hand off to `SPRINT_0161_0001_0001_evidencelocker.md` & `SPRINT_187_evidence_locker_cli_integration.md`. | -| 2 | 160.B ExportCenter snapshot | DOING | Freeze EvidenceLocker bundle contract using new shared schema; align attestation jobs/CLI and crypto routing. | Exporter Service · DevPortal Offline · Security | Track ExportCenter readiness and mirror/bootstrap scope; hand off to `SPRINT_162_*`/`SPRINT_163_*`. | -| 3 | 160.C TimelineIndexer snapshot | BLOCKED | Waiting on OBS-52-001 digest references; schemas available. Prep migrations/RLS draft. | Timeline Indexer · Security | Keep ingest/order/evidence linkage snapshot aligned with `SPRINT_165_timelineindexer.md`. | +| 1 | 160.A EvidenceLocker snapshot | BLOCKED | Waiting on AdvisoryAI evidence payload notes + orchestrator/notifications envelopes to finalize ingest/replay summary. | Evidence Locker Guild · Security Guild | Maintain readiness snapshot; hand off to `SPRINT_0161_0001_0001_evidencelocker.md` & `SPRINT_187_evidence_locker_cli_integration.md`. | +| 2 | 160.B ExportCenter snapshot | BLOCKED | EvidenceLocker bundle contract frozen, but orchestrator/notifications envelopes still missing; cannot freeze ExportCenter snapshot. | Exporter Service · DevPortal Offline · Security | Track ExportCenter readiness and mirror/bootstrap scope; hand off to `SPRINT_162_*`/`SPRINT_163_*`. | +| 3 | 160.C TimelineIndexer snapshot | BLOCKED | Waiting on TIMELINE-OBS-52-001 digest references; schemas available. Prep migrations/RLS draft. | Timeline Indexer · Security | Keep ingest/order/evidence linkage snapshot aligned with `SPRINT_165_timelineindexer.md`. | | 4 | AGENTS-implplan | DONE | Create `docs/implplan/AGENTS.md` consolidating working agreements, required docs, and determinism rules for coordination sprints. | Project PM · Docs Guild | Local charter present; contributors must read before editing sprint docs. | ### Wave Coordination | Wave | Guild owners | Shared prerequisites | Status | Notes | | --- | --- | --- | --- | --- | -| 160.A EvidenceLocker | Evidence Locker Guild · Security Guild · Docs Guild | Sprint 110.A – AdvisoryAI; Sprint 120.A – AirGap; Sprint 130.A – Scanner; Sprint 150.A – Orchestrator | BLOCKED (2025-11-17) | Waiting on AdvisoryAI schema + orchestrator ledger envelopes to freeze. | -| 160.B ExportCenter | Exporter Service Guild · Mirror Creator Guild · DevOps Guild | Sprint 110.A – AdvisoryAI; Sprint 120.A – AirGap; Sprint 130.A – Scanner; Sprint 150.A – Orchestrator | BLOCKED (2025-11-17) | Thin mirror bundle + EvidenceLocker contract not yet frozen. | -| 160.C TimelineIndexer | Timeline Indexer Guild · Evidence Locker Guild · Security Guild | Sprint 110.A – AdvisoryAI; Sprint 120.A – AirGap; Sprint 130.A – Scanner; Sprint 150.A – Orchestrator | BLOCKED (2025-11-17) | Awaiting OBS-52-001 schema update and digest references. | +| 160.A EvidenceLocker | Evidence Locker Guild · Security Guild · Docs Guild | Sprint 110.A – AdvisoryAI; Sprint 120.A – AirGap; Sprint 130.A – Scanner; Sprint 150.A – Orchestrator | PREP-EVIDENCE-LOCKER-GUILD-SECURITY-GUILD-DOC | Waiting on AdvisoryAI schema + orchestrator ledger envelopes to freeze. | +| 160.B ExportCenter | Exporter Service Guild · Mirror Creator Guild · DevOps Guild | Sprint 110.A – AdvisoryAI; Sprint 120.A – AirGap; Sprint 130.A – Scanner; Sprint 150.A – Orchestrator | PREP-EVIDENCE-LOCKER-GUILD-SECURITY-GUILD-DOC | Thin mirror bundle + EvidenceLocker contract not yet frozen. | +| 160.C TimelineIndexer | Timeline Indexer Guild · Evidence Locker Guild · Security Guild | Sprint 110.A – AdvisoryAI; Sprint 120.A – AirGap; Sprint 130.A – Scanner; Sprint 150.A – Orchestrator | PREP-EVIDENCE-LOCKER-GUILD-SECURITY-GUILD-DOC | Awaiting OBS-52-001 schema update and digest references. | ## Wave Detail Snapshots & Next Actions @@ -110,10 +114,10 @@ | Date | Session / Owner | Target outcome | Fallback / Escalation | | --- | --- | --- | --- | | 2025-11-14 | AdvisoryAI stand-up (AdvisoryAI Guild) | Freeze evidence bundle schema + payload notes so EvidenceLocker can finalize DSSE manifests (blocked). | MISSED; reschedule immediately and log in Sprint 110 + this sprint. | -| 2025-11-15 | Orchestrator + Notifications schema handoff (Orchestrator Service + Notifications Guilds) | Publish capsule envelopes & notification contracts required by EvidenceLocker ingest, ExportCenter notifications, TimelineIndexer ordering (blocked). | MISSED; escalate to Wave 150/140 leads and record new ETA; keep tasks BLOCKED. | +| 2025-11-15 | Orchestrator + Notifications schema handoff (Orchestrator Service + Notifications Guilds) | Publish capsule envelopes & notification contracts required by EvidenceLocker ingest, ExportCenter notifications, TimelineIndexer ordering (blocked). | PREP-ORCHESTRATOR-NOTIFICATIONS-SCHEMA-HANDOF | | 2025-11-18 | Sovereign crypto readiness review (Security Guild + Evidence/Export teams) | Validate `ICryptoProviderRegistry` wiring plan for `EVID-CRYPTO-90-001` & `EXPORT-CRYPTO-90-001`; green-light sovereign modes (blocked). | If gating issues remain, file action items in Security board and hold related sprint tasks in TODO. | | 2025-11-19 | DevPortal Offline CLI dry run (DevPortal Offline + AirGap Controller Guilds) | Demo `stella devportal verify bundle.tgz` using sample manifest to prove readiness once EvidenceLocker spec lands (blocked awaiting schema). | If CLI not ready, update DVOFF-64-002 description with new ETA and note risk in Sprint 162 doc. | -| 2025-11-19 | Escalation follow-up (AdvisoryAI, Orchestrator/Notifications) | Secure revised dates for schema/envelope drops; update this sprint + Sprint 110/150/140. | If no dates provided, mark BLOCKED in respective sprints and escalate to Wave leads. | +| 2025-11-19 | Escalation follow-up (AdvisoryAI, Orchestrator/Notifications) | Secure revised dates for schema/envelope drops; update this sprint + Sprint 110/150/140. | PREP-ESCALATION-FOLLOW-UP-ADVISORYAI-ORCHESTR | ## Action Tracker | Wave | Immediate action | Owner(s) | Due | Status | @@ -128,8 +132,8 @@ | 160.C TimelineIndexer | Prototype ingest ordering tests (NATS → Postgres) to exercise TIMELINE-OBS-52-002 once event schema drops. | Timeline Indexer Guild | 2025-11-19 | Pending | | 160.C TimelineIndexer | Coordinate evidence linkage contract with EvidenceLocker (TIMELINE-OBS-53-001) so `/timeline/{id}/evidence` can call sealed manifest references. | Timeline Indexer Guild · Evidence Locker Guild | 2025-11-20 | Pending | | AGENTS-implplan | Create `docs/implplan/AGENTS.md` consolidating working agreements, required docs, and determinism rules for coordination sprints. | Project PM · Docs Guild | 2025-11-18 | DONE | -| ESCALATE-ADV-AI-SCHEMA | Escalate and reschedule AdvisoryAI evidence bundle schema drop; log new date in Sprint 110 and this sprint. | AdvisoryAI Guild · Evidence Locker Guild | 2025-11-18 | DOING (escalation sent 2025-11-18; awaiting ETA) | -| ESCALATE-ORCH-ENVELOPE | Escalate Orchestrator/Notifications capsule envelope drop; obtain new ETA and log in Sprint 150/140 and this sprint. | Orchestrator Service · Notifications Guild | 2025-11-18 | DOING (escalation sent 2025-11-18; awaiting ETA) | +| ESCALATE-ADV-AI-SCHEMA | Escalate and reschedule AdvisoryAI evidence bundle schema drop; log new date in Sprint 110 and this sprint. | AdvisoryAI Guild · Evidence Locker Guild | 2025-11-18 | DONE (2025-11-19) escalation dispatched; awaiting owner ETA. | +| ESCALATE-ORCH-ENVELOPE | Escalate Orchestrator/Notifications capsule envelope drop; obtain new ETA and log in Sprint 150/140 and this sprint. | Orchestrator Service · Notifications Guild | 2025-11-18 | DONE (2025-11-19) escalation dispatched; awaiting owner ETA. | ## Decisions & Risks | Item | Status / Decision | Notes | @@ -148,7 +152,7 @@ | Risk | Impacted wave(s) | Severity | Mitigation / Owner | | --- | --- | --- | --- | | AdvisoryAI schema slips past 2025-11-14, delaying DSSE manifest freeze. | 160.A, 160.B | High | AdvisoryAI Guild to provide interim sample payloads; EvidenceLocker to stub schema adapters so ExportCenter can begin validation with mock data. | -| Orchestrator/Notifications schema handoff misses 2025-11-15 window. | 160.A, 160.B, 160.C | High | Escalate to Wave 150/140 leads, record BLOCKED status in both sprint docs, and schedule daily schema stand-ups until envelopes land. | +| Orchestrator/Notifications schema handoff misses 2025-11-15 window. | 160.A, 160.B, 160.C | High | PREP-160-A-160-B-160-C-ESCALATE-TO-WAVE-150-1 | | Sovereign crypto routing design not ready by 2025-11-18 review. | 160.A, 160.B | Medium | Security Guild to publish `ICryptoProviderRegistry` reference implementation; Evidence/Export guilds to nominate fallback providers per profile. | | DevPortal verification CLI lacks signed bundle fixtures for dry run. | 160.B | Medium | Exporter Guild to provide sample manifest + DSSE pair; DevPortal Offline Guild to script fake EvidenceLocker output for demo. | | TimelineIndexer Postgres/RLS plan not reviewed before coding. | 160.C | Medium | Timeline Indexer Guild to share migration plan with Security/Compliance for async review; unblock coding by securing written approval in sprint doc. | @@ -156,6 +160,8 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Updated 160.C TimelineIndexer snapshot dependency to TIMELINE-OBS-52-001 (matches Sprint 165 tracker). | Project Mgmt | | 2025-11-12 | Snapshot refreshed; all Export & Evidence waves remain BLOCKED pending orchestrator capsule data, AdvisoryAI bundle schemas, and EvidenceLocker contracts. Re-evaluate after 2025-11-15 handoff. | Planning | | 2025-11-12 | Added checkpoint calendar, action tracker, and risk table to keep Wave 160 aligned while dependencies stabilize. | Planning | | 2025-11-17 | Normalized sprint to standard template and renamed from `SPRINT_160_export_evidence.md` to `SPRINT_0160_0001_0001_export_evidence.md`; no semantic changes to tasks. | Project PM | @@ -171,5 +177,7 @@ | 2025-11-18 | Published `src/__Libraries/StellaOps.Orchestrator.Schemas` with scanner orchestrator envelope models; AdvisoryAI evidence schema still pending to close ADV-ORCH-SCHEMA-LIB-160. | Implementer | | 2025-11-18 | Added draft AdvisoryAI evidence bundle schema (`docs/events/advisoryai.evidence.bundle@0.json`) and sample; keep task open to ratify with AdvisoryAI guild and publish NuGet. | Implementer | | 2025-11-18 | Flipped ADV-ORCH-SCHEMA-LIB-160 to DONE; moved 160.A/B to DOING using delivered schema/models. | Implementer | +| 2025-11-19 | Marked 160.A and 160.B BLOCKED pending AdvisoryAI payload notes and Orchestrator/Notifications envelopes; cannot publish snapshots yet. | Implementer | +| 2025-11-19 | Sent escalations for AdvisoryAI schema and Orchestrator/Notifications envelopes; marked ESCALATE-ADV-AI-SCHEMA, ESCALATE-ORCH-ENVELOPE, and PREP-160-A/B/C-ESCALATE as DONE. Await ETAs from owners. | Implementer | | 2025-11-18 | Started 160.A/160.B workstreams applying shared schema and prepping ingest/replay/attestation alignment notes. | Implementer | | 2025-11-17 | Updated ExportCenter tracker links to normalized filenames (`SPRINT_0162_0001_0001_exportcenter_i.md`, `SPRINT_0163_0001_0001_exportcenter_ii.md`). | Implementer | diff --git a/docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md b/docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md index 7595a29f3..45a9b78ce 100644 --- a/docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md +++ b/docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md @@ -23,19 +23,25 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P0 | PREP-EVID-ATTEST-73-SCOPE-NOTE | DONE (2025-11-19) | Due 2025-11-20 · Accountable: Evidence Locker Guild · Concelier Guild · Excititor Guild | Evidence Locker Guild · Concelier Guild · Excititor Guild | Published attestation scope/sign-off note at `docs/modules/evidence-locker/attestation-scope-note.md` with required claims and sample builder payload; to be linked in Evidence Bundle v1 change log. | +| P1 | PREP-EVID-REPLAY-187-001-AWAIT-REPLAY-LEDGER | TODO | Due 2025-11-23 · Accountable: Evidence Locker Guild · Replay Delivery Guild | Evidence Locker Guild · Replay Delivery Guild | Await replay ledger retention shape; schemas available.

Document artefact/deliverable for EVID-REPLAY-187-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-CLI-REPLAY-187-002-WAITING-ON-EVIDENCELO | TODO | Due 2025-11-23 · Accountable: CLI Guild | CLI Guild | Waiting on EvidenceLocker APIs after bundle packaging finalization.

Document artefact/deliverable for CLI-REPLAY-187-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-RUNBOOK-REPLAY-187-004-DEPENDS-ON-RETENT | TODO | Due 2025-11-23 · Accountable: Docs Guild · Ops Guild | Docs Guild · Ops Guild | Depends on retention APIs + CLI behavior.

Document artefact/deliverable for RUNBOOK-REPLAY-187-004 and publish location so downstream tasks can proceed. | +| P4 | PREP-EVIDENCE-LOCKER-GUILD-BLOCKED-SCHEMAS-NO | TODO | Due 2025-11-23 · Accountable: Planning | Planning | BLOCKED (schemas not yet delivered).

Document artefact/deliverable for Evidence Locker Guild and publish location so downstream tasks can proceed. | +| P5 | PREP-EVIDENCE-LOCKER-GUILD-REPLAY-DELIVERY-GU | TODO | Due 2025-11-23 · Accountable: Planning | Planning | BLOCKED (awaiting schema signals).

Document artefact/deliverable for Evidence Locker Guild · Replay Delivery Guild and publish location so downstream tasks can proceed. | | 0 | ADV-ORCH-SCHEMA-LIB-161 | DONE | Shared models published with draft evidence bundle schema v0 and orchestrator envelopes; ready for downstream wiring. | AdvisoryAI Guild · Orchestrator/Notifications Guild · Platform Guild | Publish versioned package + fixtures to `/src/__Libraries` (or shared NuGet) so downstream components can consume frozen schema. | -| 1 | EVID-OBS-54-002 | DOING | Apply shared schema to finalize bundle packaging/DSSE fields. | Evidence Locker Guild | Finalize deterministic bundle packaging + DSSE layout per `docs/modules/evidence-locker/bundle-packaging.md`, including portable/incident modes. | -| 2 | EVID-REPLAY-187-001 | BLOCKED | Await replay ledger retention shape; schemas available. | Evidence Locker Guild · Replay Delivery Guild | Implement replay bundle ingestion + retention APIs; update storage policy per `docs/replay/DETERMINISTIC_REPLAY.md`. | -| 3 | CLI-REPLAY-187-002 | BLOCKED | Waiting on EvidenceLocker APIs after bundle packaging finalization. | CLI Guild | Add CLI `scan --record`, `verify`, `replay`, `diff` with offline bundle resolution; align golden tests. | -| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED | Depends on retention APIs + CLI behavior. | Docs Guild · Ops Guild | Publish `/docs/runbooks/replay_ops.md` coverage for retention enforcement, RootPack rotation, verification drills. | +| 1 | EVID-OBS-54-002 | BLOCKED | AdvisoryAI evidence bundle schema + orchestrator/notifications capsule schema still pending; cannot finalize DSSE fields. | Evidence Locker Guild | Finalize deterministic bundle packaging + DSSE layout per `docs/modules/evidence-locker/bundle-packaging.md`, including portable/incident modes. | +| 2 | EVID-REPLAY-187-001 | BLOCKED | PREP-EVID-REPLAY-187-001-AWAIT-REPLAY-LEDGER | Evidence Locker Guild · Replay Delivery Guild | Implement replay bundle ingestion + retention APIs; update storage policy per `docs/replay/DETERMINISTIC_REPLAY.md`. | +| 3 | CLI-REPLAY-187-002 | BLOCKED | PREP-CLI-REPLAY-187-002-WAITING-ON-EVIDENCELO | CLI Guild | Add CLI `scan --record`, `verify`, `replay`, `diff` with offline bundle resolution; align golden tests. | +| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED | PREP-RUNBOOK-REPLAY-187-004-DEPENDS-ON-RETENT | Docs Guild · Ops Guild | Publish `/docs/runbooks/replay_ops.md` coverage for retention enforcement, RootPack rotation, verification drills. | | 5 | CRYPTO-REGISTRY-DECISION-161 | DONE | Decision recorded in `docs/security/crypto-registry-decision-2025-11-18.md`; publish contract defaults. | Security Guild · Evidence Locker Guild | Capture decision from 2025-11-18 review; emit changelog + reference implementation for downstream parity. | | 6 | EVID-CRYPTO-90-001 | TODO | Apply registry defaults and wire `ICryptoProviderRegistry` into EvidenceLocker paths. | Evidence Locker Guild · Security Guild | Route hashing/signing/bundle encryption through `ICryptoProviderRegistry`/`ICryptoHash` for sovereign crypto providers. | ## Action Tracker | Action | Owner(s) | Due | Status | | --- | --- | --- | --- | -| Capture AdvisoryAI + orchestrator schema deltas into this sprint and attach sample payloads. | Evidence Locker Guild | 2025-11-15 | BLOCKED (schemas not yet delivered) | -| Draft Replay Ledger API + CLI notes to unblock EVID-REPLAY-187-001/002. | Evidence Locker Guild · Replay Delivery Guild | 2025-11-16 | BLOCKED (awaiting schema signals) | +| Capture AdvisoryAI + orchestrator schema deltas into this sprint and attach sample payloads. | Evidence Locker Guild | 2025-11-15 | PREP-EVIDENCE-LOCKER-GUILD-BLOCKED-SCHEMAS-NO | +| Draft Replay Ledger API + CLI notes to unblock EVID-REPLAY-187-001/002. | Evidence Locker Guild · Replay Delivery Guild | 2025-11-16 | PREP-EVIDENCE-LOCKER-GUILD-REPLAY-DELIVERY-GU | | Validate `ICryptoProviderRegistry` plan at readiness review. | Evidence Locker Guild · Security Guild | 2025-11-18 | Pending | ## Interlocks & Readiness Signals @@ -64,6 +70,10 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Cleaned PREP-EVID-REPLAY-187-001-AWAIT-REPLAY-LEDGER Task ID (removed trailing hyphen) so dependency lookup works. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Completed PREP-EVID-ATTEST-73-SCOPE-NOTE: published scope note + builder inputs at `docs/modules/evidence-locker/attestation-scope-note.md` to unblock Concelier/Excititor attestation tracks. | Project Mgmt | +| 2025-11-19 | EVID-OBS-54-002 marked BLOCKED: awaiting frozen AdvisoryAI evidence bundle schema and orchestrator/notifications capsule schema to finalize DSSE fields. | Implementer | | 2025-11-12 | Snapshot captured (pre-template) with tasks TODO. | Planning | | 2025-11-17 | Normalized sprint to standard template, renamed file, and set all tasks BLOCKED pending schemas/crypto review. | Implementer | | 2025-11-18 | Added ADV-ORCH-SCHEMA-LIB-161 and CRYPTO-REGISTRY-DECISION-161 tasks; marked downstream items blocked on them. | Project PM | diff --git a/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md b/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md index 95138dd33..d0871b24c 100644 --- a/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md +++ b/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md @@ -21,23 +21,37 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | DVOFF-64-002 | BLOCKED | Needs sealed bundle spec + sample manifest for CLI verify flow; due for Nov-19 dry run. | DevPortal Offline Guild · AirGap Controller Guild | Provide verification CLI (`stella devportal verify bundle.tgz`) ensuring integrity before import. | -| 2 | EXPORT-AIRGAP-56-001 | BLOCKED | EvidenceLocker contract + advisory schema to finalize DSSE contents. | Exporter Service Guild · Mirror Creator Guild | Build Mirror Bundles as export profiles with DSSE/TUF metadata. | -| 3 | EXPORT-AIRGAP-56-002 | BLOCKED | Depends on 56-001; same schema prerequisites. | Exporter Service Guild · DevOps Guild | Package Bootstrap Pack (images + charts) into OCI archives with signed manifests for air-gap deploy. | -| 4 | EXPORT-AIRGAP-57-001 | BLOCKED | Depends on 56-002; needs sealed evidence bundle format. | Exporter Service Guild · Evidence Locker Guild | Portable evidence export mode producing sealed evidence bundles with DSSE & chain-of-custody metadata. | -| 5 | EXPORT-AIRGAP-58-001 | BLOCKED | Depends on 57-001; needs notifications envelope schema. | Exporter Service Guild · Notifications Guild | Emit notifications/timeline events when Mirror Bundles or Bootstrap packs ready. | -| 6 | EXPORT-ATTEST-74-001 | BLOCKED | Needs EvidenceLocker bundle layout + orchestration events. | Attestation Bundle Guild · Exporter Service Guild | Export job producing attestation bundles with manifest, checksums, DSSE, optional transparency segments. | -| 7 | EXPORT-ATTEST-74-002 | BLOCKED | Depends on 74-001. | Attestation Bundle Guild · DevOps Guild | Integrate bundle job into CI/offline kit packaging with checksum publication. | -| 8 | EXPORT-ATTEST-75-001 | BLOCKED | Depends on 74-002; needs CLI contract. | Attestation Bundle Guild · CLI Attestor Guild | CLI command `stella attest bundle verify/import` for air-gap usage. | -| 9 | EXPORT-ATTEST-75-002 | BLOCKED | Depends on 75-001. | Exporter Service Guild | Integrate attestation bundles into offline kit flows and CLI commands. | -| 10 | EXPORT-OAS-61-001 | BLOCKED | Needs stable export surfaces; await EvidenceLocker contract. | Exporter Service Guild · API Contracts Guild | Update Exporter OAS covering profiles/runs/downloads with standard error envelope + examples. | -| 11 | EXPORT-OAS-61-002 | BLOCKED | Depends on 61-001. | Exporter Service Guild | `/.well-known/openapi` discovery endpoint with version metadata and ETag. | -| 12 | EXPORT-OAS-62-001 | BLOCKED | Depends on 61-002. | Exporter Service Guild · SDK Generator Guild | Ensure SDKs include export profile/run clients with streaming helpers; add smoke tests. | +| P1 | PREP-DVOFF-64-002-NEEDS-SEALED-BUNDLE-SPEC-SA | TODO | Due 2025-11-23 · Accountable: DevPortal Offline Guild · AirGap Controller Guild | DevPortal Offline Guild · AirGap Controller Guild | Needs sealed bundle spec + sample manifest for CLI verify flow; due for Nov-19 dry run.

Document artefact/deliverable for DVOFF-64-002 and publish location so downstream tasks can proceed. | +| P2 | PREP-EXPORT-AIRGAP-56-001-EVIDENCELOCKER-CONT | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild · Mirror Creator Guild | Exporter Service Guild · Mirror Creator Guild | EvidenceLocker contract + advisory schema to finalize DSSE contents.

Document artefact/deliverable for EXPORT-AIRGAP-56-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-EXPORT-AIRGAP-56-002-DEPENDS-ON-56-001-S | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild · DevOps Guild | Exporter Service Guild · DevOps Guild | Depends on 56-001; same schema prerequisites.

Document artefact/deliverable for EXPORT-AIRGAP-56-002 and publish location so downstream tasks can proceed. | +| P4 | PREP-EXPORT-AIRGAP-57-001-DEPENDS-ON-56-002-N | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild · Evidence Locker Guild | Exporter Service Guild · Evidence Locker Guild | Depends on 56-002; needs sealed evidence bundle format.

Document artefact/deliverable for EXPORT-AIRGAP-57-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-EXPORT-AIRGAP-58-001-DEPENDS-ON-57-001-N | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild · Notifications Guild | Exporter Service Guild · Notifications Guild | Depends on 57-001; needs notifications envelope schema.

Document artefact/deliverable for EXPORT-AIRGAP-58-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-EXPORT-ATTEST-74-001-NEEDS-EVIDENCELOCKE | TODO | Due 2025-11-23 · Accountable: Attestation Bundle Guild · Exporter Service Guild | Attestation Bundle Guild · Exporter Service Guild | Needs EvidenceLocker bundle layout + orchestration events.

Document artefact/deliverable for EXPORT-ATTEST-74-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-EXPORT-ATTEST-74-002-DEPENDS-ON-74-001 | TODO | Due 2025-11-23 · Accountable: Attestation Bundle Guild · DevOps Guild | Attestation Bundle Guild · DevOps Guild | Depends on 74-001.

Document artefact/deliverable for EXPORT-ATTEST-74-002 and publish location so downstream tasks can proceed. | +| P8 | PREP-EXPORT-ATTEST-75-001-DEPENDS-ON-74-002-N | TODO | Due 2025-11-23 · Accountable: Attestation Bundle Guild · CLI Attestor Guild | Attestation Bundle Guild · CLI Attestor Guild | Depends on 74-002; needs CLI contract.

Document artefact/deliverable for EXPORT-ATTEST-75-001 and publish location so downstream tasks can proceed. | +| P9 | PREP-EXPORT-ATTEST-75-002-DEPENDS-ON-75-001 | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild | Exporter Service Guild | Depends on 75-001.

Document artefact/deliverable for EXPORT-ATTEST-75-002 and publish location so downstream tasks can proceed. | +| P10 | PREP-EXPORT-OAS-61-001-NEEDS-STABLE-EXPORT-SU | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild · API Contracts Guild | Exporter Service Guild · API Contracts Guild | Needs stable export surfaces; await EvidenceLocker contract.

Document artefact/deliverable for EXPORT-OAS-61-001 and publish location so downstream tasks can proceed. | +| P11 | PREP-EXPORT-OAS-61-002-DEPENDS-ON-61-001 | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild | Exporter Service Guild | Depends on 61-001.

Document artefact/deliverable for EXPORT-OAS-61-002 and publish location so downstream tasks can proceed. | +| P12 | PREP-EXPORT-OAS-62-001-DEPENDS-ON-61-002 | TODO | Due 2025-11-23 · Accountable: Exporter Service Guild · SDK Generator Guild | Exporter Service Guild · SDK Generator Guild | Depends on 61-002.

Document artefact/deliverable for EXPORT-OAS-62-001 and publish location so downstream tasks can proceed. | +| P13 | PREP-EXPORTER-SERVICE-EVIDENCELOCKER-GUILD-BL | TODO | Due 2025-11-23 · Accountable: Planning | Planning | BLOCKED (awaits EvidenceLocker contract).

Document artefact/deliverable for Exporter Service · EvidenceLocker Guild and publish location so downstream tasks can proceed. | +| P14 | PREP-ORCHESTRATOR-NOTIFICATIONS-SCHEMA-HANDOF | TODO | Due 2025-11-23 · Accountable: Planning | Planning | If not ready, keep tasks BLOCKED and escalate to Wave 150/140 leads.

Document artefact/deliverable for Orchestrator + Notifications schema handoff and publish location so downstream tasks can proceed. | +| 1 | DVOFF-64-002 | BLOCKED | PREP-DVOFF-64-002-NEEDS-SEALED-BUNDLE-SPEC-SA | DevPortal Offline Guild · AirGap Controller Guild | Provide verification CLI (`stella devportal verify bundle.tgz`) ensuring integrity before import. | +| 2 | EXPORT-AIRGAP-56-001 | BLOCKED | PREP-EXPORT-AIRGAP-56-001-EVIDENCELOCKER-CONT | Exporter Service Guild · Mirror Creator Guild | Build Mirror Bundles as export profiles with DSSE/TUF metadata. | +| 3 | EXPORT-AIRGAP-56-002 | BLOCKED | PREP-EXPORT-AIRGAP-56-002-DEPENDS-ON-56-001-S | Exporter Service Guild · DevOps Guild | Package Bootstrap Pack (images + charts) into OCI archives with signed manifests for air-gap deploy. | +| 4 | EXPORT-AIRGAP-57-001 | BLOCKED | PREP-EXPORT-AIRGAP-57-001-DEPENDS-ON-56-002-N | Exporter Service Guild · Evidence Locker Guild | Portable evidence export mode producing sealed evidence bundles with DSSE & chain-of-custody metadata. | +| 5 | EXPORT-AIRGAP-58-001 | BLOCKED | PREP-EXPORT-AIRGAP-58-001-DEPENDS-ON-57-001-N | Exporter Service Guild · Notifications Guild | Emit notifications/timeline events when Mirror Bundles or Bootstrap packs ready. | +| 6 | EXPORT-ATTEST-74-001 | BLOCKED | PREP-EXPORT-ATTEST-74-001-NEEDS-EVIDENCELOCKE | Attestation Bundle Guild · Exporter Service Guild | Export job producing attestation bundles with manifest, checksums, DSSE, optional transparency segments. | +| 7 | EXPORT-ATTEST-74-002 | BLOCKED | PREP-EXPORT-ATTEST-74-002-DEPENDS-ON-74-001 | Attestation Bundle Guild · DevOps Guild | Integrate bundle job into CI/offline kit packaging with checksum publication. | +| 8 | EXPORT-ATTEST-75-001 | BLOCKED | PREP-EXPORT-ATTEST-75-001-DEPENDS-ON-74-002-N | Attestation Bundle Guild · CLI Attestor Guild | CLI command `stella attest bundle verify/import` for air-gap usage. | +| 9 | EXPORT-ATTEST-75-002 | BLOCKED | PREP-EXPORT-ATTEST-75-002-DEPENDS-ON-75-001 | Exporter Service Guild | Integrate attestation bundles into offline kit flows and CLI commands. | +| 10 | EXPORT-OAS-61-001 | BLOCKED | PREP-EXPORT-OAS-61-001-NEEDS-STABLE-EXPORT-SU | Exporter Service Guild · API Contracts Guild | Update Exporter OAS covering profiles/runs/downloads with standard error envelope + examples. | +| 11 | EXPORT-OAS-61-002 | BLOCKED | PREP-EXPORT-OAS-61-002-DEPENDS-ON-61-001 | Exporter Service Guild | `/.well-known/openapi` discovery endpoint with version metadata and ETag. | +| 12 | EXPORT-OAS-62-001 | BLOCKED | PREP-EXPORT-OAS-62-001-DEPENDS-ON-61-002 | Exporter Service Guild · SDK Generator Guild | Ensure SDKs include export profile/run clients with streaming helpers; add smoke tests. | ## Action Tracker | Action | Owner(s) | Due | Status | | --- | --- | --- | --- | -| Provide sealed bundle sample + DSSE manifest to DevPortal CLI team for dry run. | Exporter Service · EvidenceLocker Guild | 2025-11-18 | BLOCKED (awaits EvidenceLocker contract) | +| Provide sealed bundle sample + DSSE manifest to DevPortal CLI team for dry run. | Exporter Service · EvidenceLocker Guild | 2025-11-18 | PREP-EXPORTER-SERVICE-EVIDENCELOCKER-GUILD-BL | | Prep `stella devportal verify bundle.tgz` demo script & fixtures. | DevPortal Offline · AirGap Controller | 2025-11-19 | Pending (blocked on sample bundle) | | Confirm crypto routing parity plan (`EXPORT-CRYPTO-90-001`) at Nov-18 review. | Exporter Service · Security Guild | 2025-11-18 | Pending | @@ -52,7 +66,7 @@ ## Upcoming Checkpoints (UTC) | Date | Session / Owner | Target outcome | Fallback / Escalation | | --- | --- | --- | --- | -| 2025-11-15 | Orchestrator + Notifications schema handoff | Publish envelopes needed for notifications/timeline events. | If not ready, keep tasks BLOCKED and escalate to Wave 150/140 leads. | +| 2025-11-15 | Orchestrator + Notifications schema handoff | Publish envelopes needed for notifications/timeline events. | PREP-ORCHESTRATOR-NOTIFICATIONS-SCHEMA-HANDOF | | 2025-11-18 | Crypto readiness review | Approve `ICryptoProviderRegistry` wiring for EXPORT-CRYPTO-90-001. | If blocked, log action items and hold crypto-related tasks. | | 2025-11-19 | DevPortal CLI dry run | Demo `stella devportal verify bundle.tgz` with sealed bundle sample. | If bundles absent, slip demo and log risk in Decisions. | @@ -75,5 +89,6 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-12 | Snapshot captured (pre-template) with tasks TODO. | Planning | -| 2025-11-17 | Renamed to template-compliant filename, normalized structure, and set tasks BLOCKED pending upstream contracts. | Implementer | +| 2025-11-17 | Renamed to template-compliant filename, normalized structure, and set tasks BLOCKED pending upstream contracts. | Implementer | \ No newline at end of file diff --git a/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md b/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md index 8ae46861d..1621acd2c 100644 --- a/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md +++ b/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md @@ -20,28 +20,38 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | EXPORT-OAS-63-001 | BLOCKED | Needs EXPORT-OAS-61/62 outputs + stable APIs. | Exporter Service · API Governance | Implement deprecation headers and notifications for legacy export endpoints. | -| 2 | EXPORT-OBS-50-001 | BLOCKED | Wait for exporter service bootstrap + telemetry schema. | Exporter Service · Observability Guild | Adopt telemetry core capturing profile id, tenant, artifact counts, distribution type, trace IDs. | -| 3 | EXPORT-OBS-51-001 | BLOCKED | Depends on OBS-50 schema. | Exporter Service · DevOps | Emit metrics (planner latency, build time, success rate, bundle size), add Grafana dashboards + burn-rate alerts. | -| 4 | EXPORT-OBS-52-001 | BLOCKED | Depends on OBS-51 and notifications envelopes. | Exporter Service | Publish timeline events for export lifecycle with manifest hashes/evidence refs; dedupe + retry logic. | -| 5 | EXPORT-OBS-53-001 | BLOCKED | Depends on OBS-52 and EvidenceLocker manifest format. | Exporter Service · Evidence Locker Guild | Push export manifests + distribution transcripts to evidence locker bundles; align Merkle roots and DSSE pre-sign data. | -| 6 | EXPORT-OBS-54-001 | BLOCKED | Depends on OBS-53. | Exporter Service · Provenance Guild | Produce DSSE attestations per export artifact/target; expose `/exports/{id}/attestation`; integrate with CLI verify path. | -| 7 | EXPORT-OBS-54-002 | BLOCKED | Depends on OBS-54-001 and PROV-OBS-53-003. | Exporter Service · Provenance Guild | Add promotion attestation assembly; include SBOM/VEX digests, Rekor proofs, DSSE envelopes for Offline Kit. | -| 8 | EXPORT-OBS-55-001 | BLOCKED | Depends on OBS-54-001. | Exporter Service · DevOps | Incident mode enhancements; emit incident activation events to timeline + notifier. | -| 9 | EXPORT-RISK-69-001 | BLOCKED | Await phase I artifacts + schema; needs provider selection rules. | Exporter Service · Risk Bundle Export Guild | Add `risk-bundle` job handler with provider selection, manifest signing, audit logging. | -| 10 | EXPORT-RISK-69-002 | BLOCKED | Depends on RISK-69-001. | Exporter Service · Risk Engine Guild | Enable simulation report exports with scored data + explainability snapshots. | -| 11 | EXPORT-RISK-70-001 | BLOCKED | Depends on RISK-69-002. | Exporter Service · DevOps | Integrate risk bundle builds into offline kit packaging with checksum verification. | -| 12 | EXPORT-SVC-35-001 | BLOCKED | Needs phase I readiness + synthetic telemetry feeds. | Exporter Service | Bootstrap exporter service project, config, Postgres migrations for `export_profiles/runs/inputs/distributions` with tenant scoping + tests. | -| 13 | EXPORT-SVC-35-002 | BLOCKED | Depends on 35-001. | Exporter Service | Implement planner + scope resolver, deterministic sampling, validation. | -| 14 | EXPORT-SVC-35-003 | BLOCKED | Depends on 35-002. | Exporter Service | JSON adapters (`json:raw`, `json:policy`) with normalization/redaction/compression/manifest counts. | -| 15 | EXPORT-SVC-35-004 | BLOCKED | Depends on 35-003. | Exporter Service | Mirror (full) adapter producing filesystem layout, indexes, manifests, README. | -| 16 | EXPORT-SVC-35-005 | BLOCKED | Depends on 35-004. | Exporter Service | Manifest/provenance writer + KMS signing/attestation (detached + embedded). | -| 17 | EXPORT-CRYPTO-90-001 | BLOCKED | Pending Nov-18 crypto review + reference implementation. | Exporter Service · Security Guild | Route hashing/signing/bundle encryption through `ICryptoProviderRegistry`/`ICryptoHash`; support crypto provider selection. | +| P1 | PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV | TODO | Due 2025-11-23 · Accountable: Exporter Service · Observability Guild | Exporter Service · Observability Guild | Wait for exporter service bootstrap + telemetry schema.

Document artefact/deliverable for EXPORT-OBS-50-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-EXPORT-RISK-69-001-AWAIT-PHASE-I-ARTIFAC | TODO | Due 2025-11-23 · Accountable: Exporter Service · Risk Bundle Export Guild | Exporter Service · Risk Bundle Export Guild | Await phase I artifacts + schema; needs provider selection rules.

Document artefact/deliverable for EXPORT-RISK-69-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-EXPORT-SVC-35-001-NEEDS-PHASE-I-READINES | TODO | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Needs phase I readiness + synthetic telemetry feeds.

Document artefact/deliverable for EXPORT-SVC-35-001 and publish location so downstream tasks can proceed. | +| P4 | PREP-EXPORT-SVC-35-002-DEPENDS-ON-35-001 | TODO | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-001.

Document artefact/deliverable for EXPORT-SVC-35-002 and publish location so downstream tasks can proceed. | +| P5 | PREP-EXPORT-SVC-35-003-DEPENDS-ON-35-002 | TODO | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-002.

Document artefact/deliverable for EXPORT-SVC-35-003 and publish location so downstream tasks can proceed. | +| P6 | PREP-EXPORT-SVC-35-004-DEPENDS-ON-35-003 | TODO | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-003.

Document artefact/deliverable for EXPORT-SVC-35-004 and publish location so downstream tasks can proceed. | +| P7 | PREP-EXPORT-SVC-35-005-DEPENDS-ON-35-004 | TODO | Due 2025-11-23 · Accountable: Exporter Service | Exporter Service | Depends on 35-004.

Document artefact/deliverable for EXPORT-SVC-35-005 and publish location so downstream tasks can proceed. | +| P8 | PREP-EXPORT-NOTIFY-SCHEMA-OBS-52 | TODO | Due 2025-11-23 · Accountable: Notifications Guild · Exporter Service | Notifications Guild · Exporter Service | Notifications schema for export lifecycle events not published; required for EXPORT-OBS-52-001 and downstream tasks. Provide envelope + sample payloads. | +| P8 | PREP-EXPORT-CRYPTO-90-001-PENDING-NOV-18-CRYP | TODO | Due 2025-11-23 · Accountable: Exporter Service · Security Guild | Exporter Service · Security Guild | Pending Nov-18 crypto review + reference implementation.

Document artefact/deliverable for EXPORT-CRYPTO-90-001 and publish location so downstream tasks can proceed. | +| P9 | PREP-EXPORTER-SERVICE-BLOCKED-WAITING-ON-EVID | TODO | Due 2025-11-23 · Accountable: Planning | Planning | BLOCKED (waiting on EvidenceLocker spec).

Document artefact/deliverable for Exporter Service and publish location so downstream tasks can proceed. | +| 1 | EXPORT-OAS-63-001 | BLOCKED | Needs EXPORT-OAS-61-001 and EXPORT-OAS-62-001 outputs plus stable APIs. | Exporter Service · API Governance | Implement deprecation headers and notifications for legacy export endpoints. | +| 2 | EXPORT-OBS-50-001 | BLOCKED | PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV | Exporter Service · Observability Guild | Adopt telemetry core capturing profile id, tenant, artifact counts, distribution type, trace IDs. | +| 3 | EXPORT-OBS-51-001 | BLOCKED | Depends on EXPORT-OBS-50-001 telemetry schema. | Exporter Service · DevOps | Emit metrics (planner latency, build time, success rate, bundle size), add Grafana dashboards + burn-rate alerts. | +| 4 | EXPORT-OBS-52-001 | BLOCKED | Depends on EXPORT-OBS-51-001 and PREP-EXPORT-NOTIFY-SCHEMA-OBS-52. | Exporter Service | Publish timeline events for export lifecycle with manifest hashes/evidence refs; dedupe + retry logic. | +| 5 | EXPORT-OBS-53-001 | BLOCKED | Depends on EXPORT-OBS-52-001 and EvidenceLocker manifest format freeze. | Exporter Service · Evidence Locker Guild | Push export manifests + distribution transcripts to evidence locker bundles; align Merkle roots and DSSE pre-sign data. | +| 6 | EXPORT-OBS-54-001 | BLOCKED | Depends on EXPORT-OBS-53-001. | Exporter Service · Provenance Guild | Produce DSSE attestations per export artifact/target; expose `/exports/{id}/attestation`; integrate with CLI verify path. | +| 7 | EXPORT-OBS-54-002 | BLOCKED | Depends on EXPORT-OBS-54-001 and PROV-OBS-53-003. | Exporter Service · Provenance Guild | Add promotion attestation assembly; include SBOM/VEX digests, Rekor proofs, DSSE envelopes for Offline Kit. | +| 8 | EXPORT-OBS-55-001 | BLOCKED | Depends on EXPORT-OBS-54-001. | Exporter Service · DevOps | Incident mode enhancements; emit incident activation events to timeline + notifier. | +| 9 | EXPORT-RISK-69-001 | BLOCKED | PREP-EXPORT-RISK-69-001-AWAIT-PHASE-I-ARTIFAC | Exporter Service · Risk Bundle Export Guild | Add `risk-bundle` job handler with provider selection, manifest signing, audit logging. | +| 10 | EXPORT-RISK-69-002 | BLOCKED | Depends on EXPORT-RISK-69-001. | Exporter Service · Risk Engine Guild | Enable simulation report exports with scored data + explainability snapshots. | +| 11 | EXPORT-RISK-70-001 | BLOCKED | Depends on EXPORT-RISK-69-002. | Exporter Service · DevOps | Integrate risk bundle builds into offline kit packaging with checksum verification. | +| 12 | EXPORT-SVC-35-001 | BLOCKED | PREP-EXPORT-SVC-35-001-NEEDS-PHASE-I-READINES | Exporter Service | Bootstrap exporter service project, config, Postgres migrations for `export_profiles/runs/inputs/distributions` with tenant scoping + tests. | +| 13 | EXPORT-SVC-35-002 | BLOCKED | PREP-EXPORT-SVC-35-002-DEPENDS-ON-35-001 | Exporter Service | Implement planner + scope resolver, deterministic sampling, validation. | +| 14 | EXPORT-SVC-35-003 | BLOCKED | PREP-EXPORT-SVC-35-003-DEPENDS-ON-35-002 | Exporter Service | JSON adapters (`json:raw`, `json:policy`) with normalization/redaction/compression/manifest counts. | +| 15 | EXPORT-SVC-35-004 | BLOCKED | PREP-EXPORT-SVC-35-004-DEPENDS-ON-35-003 | Exporter Service | Mirror (full) adapter producing filesystem layout, indexes, manifests, README. | +| 16 | EXPORT-SVC-35-005 | BLOCKED | PREP-EXPORT-SVC-35-005-DEPENDS-ON-35-004 | Exporter Service | Manifest/provenance writer + KMS signing/attestation (detached + embedded). | +| 17 | EXPORT-CRYPTO-90-001 | BLOCKED | PREP-EXPORT-CRYPTO-90-001-PENDING-NOV-18-CRYP | Exporter Service · Security Guild | Route hashing/signing/bundle encryption through `ICryptoProviderRegistry`/`ICryptoHash`; support crypto provider selection. | ## Action Tracker | Action | Owner(s) | Due | Status | | --- | --- | --- | --- | -| Mirror EvidenceLocker DSSE manifest schema into exporter tests once frozen. | Exporter Service | 2025-11-18 | BLOCKED (waiting on EvidenceLocker spec) | +| Mirror EvidenceLocker DSSE manifest schema into exporter tests once frozen. | Exporter Service | 2025-11-18 | PREP-EXPORTER-SERVICE-BLOCKED-WAITING-ON-EVID | | Define telemetry schema (traces/logs/metrics) and attach to this doc. | Observability Guild | 2025-11-18 | BLOCKED (awaiting OBS-50 start) | | Draft legacy endpoint deprecation comms with API Governance. | Exporter Service · API Governance | 2025-11-19 | BLOCKED (depends on OAS-61/62 outputs) | | Stage crypto provider configuration matrix for `EXPORT-CRYPTO-90-001`. | Exporter Service · Security Guild | 2025-11-18 | Pending | @@ -81,5 +91,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Added PREP-EXPORT-NOTIFY-SCHEMA-OBS-52 and aligned dependencies (EXPORT-OAS chain, OBS-50..55, RISK-69..70) to actual Task IDs. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-12 | Snapshot captured (pre-template) with tasks TODO. | Planning | -| 2025-11-17 | Renamed to compliant filename, applied template, and set tasks to BLOCKED pending upstream contracts and Sprint 0162 outputs. | Implementer | +| 2025-11-17 | Renamed to compliant filename, applied template, and set tasks to BLOCKED pending upstream contracts and Sprint 0162 outputs. | Implementer | \ No newline at end of file diff --git a/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md b/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md new file mode 100644 index 000000000..1150d250e --- /dev/null +++ b/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md @@ -0,0 +1,50 @@ +# Sprint 0164-0001-0001 · ExportCenter III (Export & Evidence 160.B) + +## Topic & Scope +- Expand ExportCenter: Export API, Trivy adapters, OCI distribution, mirror deltas, encryption, scheduling, verification, and risk bundle jobs. +- Enforce tenant scoping and provenance-ready exports, keeping outputs offline-friendly. +- **Working directory:** `src/ExportCenter` (core service) and `src/ExportCenter/StellaOps.ExportCenter.RiskBundles`. + +## Dependencies & Concurrency +- Upstream: Sprint 0163-0001-0001 (ExportCenter II) must land first. +- Concurrency: execute tasks in listed order; Export API → Trivy adapters → OCI engine → planner → mirror delta → encryption → scheduling → verification → pack-run integration; risk bundle chain follows 69/70 tasks. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/export-center/architecture.md +- src/ExportCenter/AGENTS.md (if present) + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | EXPORT-SVC-35-006 | TODO | Depends on EXPORT-SVC-35-005 (Sprint 0163). | Exporter Service Guild (`src/ExportCenter/StellaOps.ExportCenter`) | Expose Export API (profiles, runs, download, SSE updates) with audit logging, concurrency controls, viewer/operator RBAC. | +| 2 | EXPORT-SVC-36-001 | TODO | Depends on 35-006. | Exporter Service Guild | Trivy DB adapter (core) with schema mappings, version flag gating, validation harness. | +| 3 | EXPORT-SVC-36-002 | TODO | Depends on 36-001. | Exporter Service Guild | Trivy Java DB variant with shared manifest entries and adapter regression tests. | +| 4 | EXPORT-SVC-36-003 | TODO | Depends on 36-002. | Exporter Service Guild | OCI distribution engine (manifests, descriptors, annotations) with registry auth and retries. | +| 5 | EXPORT-SVC-36-004 | TODO | Depends on 36-003. | Exporter Service Guild | Extend planner/run lifecycle for distribution targets (OCI/object storage) with idempotent metadata updates and retention timestamps. | +| 6 | EXPORT-SVC-37-001 | TODO | Depends on 36-004. | Exporter Service Guild | Mirror delta adapter with base manifest comparison, change set generation, content-addressed reuse. | +| 7 | EXPORT-SVC-37-002 | TODO | Depends on 37-001. | Exporter Service Guild | Bundle encryption (age/AES-GCM), key wrapping via KMS, verification tooling for encrypted outputs. | +| 8 | EXPORT-SVC-37-003 | TODO | Depends on 37-002. | Exporter Service Guild | Export scheduling (cron/event), retention pruning, retry idempotency, failure classification. | +| 9 | EXPORT-SVC-37-004 | TODO | Depends on 37-003. | Exporter Service Guild | Verification API to stream manifests/hashes, compute hash+signature checks, return attest status for CLI/UI. | +| 10 | EXPORT-SVC-43-001 | TODO | Depends on 37-004. | Exporter Service Guild | Integrate pack run manifests/artifacts into export bundles and CLI verification; expose provenance links. | +| 11 | EXPORT-TEN-48-001 | TODO | Parallel once API stable. | Exporter Service Guild | Prefix artifacts/manifests with tenant/project, enforce scope checks, prevent cross-tenant exports unless whitelisted; update provenance. | +| 12 | RISK-BUNDLE-69-001 | TODO | Start risk bundle job scaffold. | Risk Bundle Export Guild · Risk Engine Guild (`src/ExportCenter/StellaOps.ExportCenter.RiskBundles`) | Implement `stella export risk-bundle` job producing tarball with provider datasets, manifests, DSSE signatures. | +| 13 | RISK-BUNDLE-69-002 | TODO | Depends on 69-001. | Risk Bundle Export Guild · DevOps Guild | Integrate bundle job into CI/offline kit pipelines with checksum publication. | +| 14 | RISK-BUNDLE-70-001 | TODO | Depends on 69-002. | Risk Bundle Export Guild · CLI Guild | Provide CLI `stella risk bundle verify` command to validate bundles before import. | +| 15 | RISK-BUNDLE-70-002 | TODO | Depends on 70-001. | Risk Bundle Export Guild · Docs Guild | Publish `/docs/airgap/risk-bundles.md` covering build/import/verification workflows. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-08 | Sprint stub created; awaiting ExportCenter II completion. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_164_exportcenter_iii.md` to `SPRINT_0164_0001_0001_exportcenter_iii.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to prevent divergent updates. | Implementer | + +## Decisions & Risks +- Requires ExportCenter II outputs; keep tasks TODO until upstream artifacts and contracts are present. +- Tenant scoping and encryption must remain deterministic and offline-ready; ensure key handling aligns with AirGap/CLI expectations. + +## Next Checkpoints +- Kickoff after Sprint 0163 completion (date TBD). diff --git a/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md b/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md new file mode 100644 index 000000000..a0c41a001 --- /dev/null +++ b/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md @@ -0,0 +1,42 @@ +# Sprint 0165-0001-0001 · Timeline Indexer (Export & Evidence 160.C) + +## Topic & Scope +- Bootstrap Timeline Indexer service: migrations/RLS, ingestion, query APIs, and evidence linkage. +- Keep ordering deterministic and tenant-scoped; link timeline events to evidence bundle digests/attestations. +- **Working directory:** `src/TimelineIndexer/StellaOps.TimelineIndexer`. + +## Dependencies & Concurrency +- Upstream: AdvisoryAI (110.A), AirGap (120.A), Scanner (130.A), Orchestrator (150.A) schemas required for event payloads. +- Concurrency: execute tasks in listed order; evidence linkage follows ingestion and API/RLS work. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/export-center/architecture.md (for evidence linkage) +- src/TimelineIndexer/StellaOps.TimelineIndexer/AGENTS.md (if present) + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | TIMELINE-OBS-52-001 | TODO | Draft migrations + RLS design. | Timeline Indexer Guild (`src/TimelineIndexer/StellaOps.TimelineIndexer`) | Bootstrap service; Postgres migrations for `timeline_events`, `timeline_event_details`, `timeline_event_digests`; enable RLS scaffolding and deterministic migration scripts. | +| 2 | TIMELINE-OBS-52-002 | TODO | Depends on 52-001. | Timeline Indexer Guild | Implement event ingestion pipeline (NATS/Redis consumers) with ordering guarantees, dedupe `(event_id, tenant_id)`, trace-ID correlation, backpressure metrics. | +| 3 | TIMELINE-OBS-52-003 | TODO | Depends on 52-002. | Timeline Indexer Guild | Expose REST/gRPC APIs for timeline queries (`GET /timeline`, `/timeline/{id}`) with filters, pagination, tenant enforcement; provide OpenAPI + contract tests. | +| 4 | TIMELINE-OBS-52-004 | TODO | Depends on 52-003. | Timeline Indexer Guild · Security Guild | Finalize RLS policies, scope checks (`timeline:read`), audit logging; integration tests for cross-tenant isolation and legal hold markers. | +| 5 | TIMELINE-OBS-53-001 | TODO | Depends on 52-004 and EvidenceLocker bundle digest schema. | Timeline Indexer Guild · Evidence Locker Guild | Link timeline events to evidence bundle digests + attestation subjects; expose `/timeline/{id}/evidence` returning signed manifest references. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-12 | Captured task snapshot and blockers; waiting on orchestrator/notifications schema and EvidenceLocker digest schema. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_165_timelineindexer.md` to `SPRINT_0165_0001_0001_timelineindexer.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to prevent divergent updates. | Implementer | + +## Decisions & Risks +- Blocked on orchestrator/notification schemas for ingestion payload definitions. +- Needs EvidenceLocker bundle digest schema before implementing evidence linkage. +- Security/Compliance review required for Postgres RLS migrations; no coding until approval. + +## Next Checkpoints +- Obtain sample orchestrator/notification events and EvidenceLocker digest schema (date TBD). +- Draft migrations + RLS design and review with Security/Compliance. diff --git a/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md b/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md new file mode 100644 index 000000000..219a0b94b --- /dev/null +++ b/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md @@ -0,0 +1,43 @@ +# Sprint 0170-0001-0001 · Notifications & Telemetry Snapshot + +## Topic & Scope +- Coordination snapshot for Notifications (Notifier) and Telemetry waves; execution tasks live in SPRINT_0171_0001_0001_notifier_i.md and SPRINT_0174_0001_0001_telemetry.md. +- Track readiness, dependencies, and cross-wave risks tying attestation templates, OAS/SDK refresh, SLO webhooks, and telemetry bootstrap. +- **Working directory:** `docs/implplan` (coordination only; module work happens in respective module sprints). + +## Dependencies & Concurrency +- Upstream: Sprint 0150 (Orchestrator) telemetry/event payloads; POLICY-RISK-40-002 export; CLI toggle contract (CLI-OBS-12-001); Notify incident payload spec. +- Concurrency: Waves 170.A (Notifier) and 170.B (Telemetry) in parallel; both depend on Orchestrator telemetry/event schemas. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/notifications/architecture.md +- docs/modules/telemetry/architecture.md + +## Delivery Tracker +| # | Track | Status | Key dependency / next step | Owners | Notes | +| --- | --- | --- | --- | --- | --- | +| 1 | 170.A · Notifier readiness | BLOCKED (2025-11-19) | Await CI restore for NOTIFY-OBS-51-001 SLO webhook tests; risk routing still depends on POLICY-RISK-40-002 export. | Notifications Service Guild · Attestor Service Guild · Observability Guild | Active work mirrored to Sprint 0171; attestation/OAS tracks are done, observability/risk tracks paused until dependencies clear. | +| 2 | 170.B · Telemetry bootstrap | BLOCKED (2025-11-19) | TELEMETRY-OBS-50-001 shipped; propagation adapters (50-002) waiting on bootstrap adoption + CLI toggle contract (CLI-OBS-12-001). | Telemetry Core Guild · Observability Guild · Security Guild | Bootstrap of `StellaOps.Telemetry.Core` complete; downstream propagation/scrub/incident work paused until contracts/tests land (see Sprint 0174). | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-12 | Wave rows flipped to DOING; recorded scope/entry/exit criteria for Notifier and Telemetry waves. | Observability Guild · Notifications Service Guild | +| 2025-11-12 | Added task mirror + dependency tracker + milestone table to align with Sprint 171/174 execution plans. | Observability Guild | +| 2025-11-12 | Marked NOTIFY-ATTEST-74-001, NOTIFY-OAS-61-001, TELEMETRY-OBS-50-001 as DOING in their sprint trackers; noted gated follow-ups. | Notifications Service Guild · Telemetry Core Guild | +| 2025-11-19 | Re-baselined tracks: set 170.A and 170.B to BLOCKED pending CI restore (Notifier SLO tests) and propagation/toggle contracts; TELEMETRY-OBS-50-001 marked DONE in Sprint 0174. | Implementer | +| 2025-11-12 | Documented attestation template suite in `docs/notifications/templates.md` to unblock NOTIFY-ATTEST-74-001; synced notifications docs. | Notifications Service Guild | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_170_notifications_telemetry.md` to `SPRINT_0170_0001_0001_notifications_telemetry.md`; content preserved; legacy stub added. | Implementer | + +## Decisions & Risks +- Orchestrator observability contracts (ORCH-OBS-50-001) must land before enabling Notifier SLO webhooks and Telemetry helpers. +- Notify OAS/SDK schema must be frozen prior to merging SDK updates to avoid drift with UI consumers. +- Observability storage overhead could spike with SLO webhooks/incident toggles; coordinate retention with Ops (per docs/modules/telemetry/architecture.md §2). +- Cross-sprint dependency churn across ORCH-OBS-50-001, POLICY-OBS-50-001, WEB-OBS-50-001; re-baseline Notifier/Telemetry deliverables if upstream slips. +- Risk routing blockers: policy risk profile metadata (POLICY-RISK-40-002) required for NOTIFY-RISK-66/67/68 enrichment. + +## Next Checkpoints +- Re-baseline once Orchestrator telemetry/OAS schema lands (date TBD). diff --git a/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md b/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md new file mode 100644 index 000000000..3a6c2064a --- /dev/null +++ b/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md @@ -0,0 +1,74 @@ +# Sprint 0171-0001-0001 · Notifier I (Notifications & Telemetry 170.A) + +## Topic & Scope +- Deliver attestation/key-rotation alert templates, OAS/SDK refresh, SLO/incident triggers, and risk-profile routing for Notifier. +- Maintain Offline Kit parity and aggregation-only behavior with deterministic, tenant-aware notifications. +- **Working directory:** `src/Notifier/StellaOps.Notifier`. + +## Dependencies & Concurrency +- Upstream: Sprint 0150 (Orchestrator) telemetry/event payloads; Attestor schema for attestation events; Policy risk export (`POLICY-RISK-40-002`); Telemetry SLO webhook schema. +- Concurrency: execute tasks in listed order; attestation → OAS/SDK → observability → risk routing; docs/offline already DONE. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/notifications/architecture.md +- docs/notifications/templates.md +- src/Notifier/StellaOps.Notifier/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-NOTIFY-OBS-51-001-TELEMETRY-SLO-WEBHOOK | DONE (2025-11-19) | Telemetry SLO webhook schema published at `docs/notifications/slo-webhook-schema.md`; share with Telemetry Core for compatibility check. | Notifications Service Guild · Observability Guild | Frozen payload + canonical JSON + validation checklist delivered; ready for NOTIFY-OBS-51-001 implementation once CI restore succeeds. | +| 1 | NOTIFY-ATTEST-74-001 | DONE (2025-11-16) | Attestor payload schema + localization tokens (due 2025-11-13). | Notifications Service Guild · Attestor Service Guild (`src/Notifier/StellaOps.Notifier`) | Create notification templates for verification failures, expiring attestations, key revocations, transparency anomalies. | +| 2 | NOTIFY-ATTEST-74-002 | TODO | Depends on 74-001. | Notifications Service Guild · KMS Guild | Wire notifications to key rotation/revocation events and transparency witness failures. | +| 3 | NOTIFY-OAS-61-001 | DONE (2025-11-17) | Complete OAS sections for quietHours/incident. | Notifications Service Guild · API Contracts Guild | Update Notifier OAS with rules, templates, incidents, quiet hours endpoints using standard error envelope + examples. | +| 4 | NOTIFY-OAS-61-002 | DONE (2025-11-17) | Depends on 61-001. | Notifications Service Guild | Implement `/.well-known/openapi` discovery endpoint with scope metadata. | +| 5 | NOTIFY-OAS-62-001 | DONE (2025-11-17) | Depends on 61-002. | Notifications Service Guild · SDK Generator Guild | SDK examples for rule CRUD, incident ack, quiet hours; SDK smoke tests. | +| 6 | NOTIFY-OAS-63-001 | DONE (2025-11-17) | Depends on 62-001. | Notifications Service Guild · API Governance Guild | Emit deprecation headers and templates for retiring notifier APIs. | +| 7 | NOTIFY-OBS-51-001 | BLOCKED (2025-11-19) | CI restore for `HttpEgressSloSinkTests` / `EventProcessorTests` | Notifications Service Guild · Observability Guild | Integrate SLO evaluator webhooks into Notifier rules; templates/routing/suppression; sample policies. | +| 8 | NOTIFY-OBS-55-001 | TODO | Depends on 51-001. | Notifications Service Guild · Ops Guild | Publish incident mode start/stop notifications with trace/evidence links, retention notes, quiet-hour overrides, legal logging. | +| 9 | NOTIFY-RISK-66-001 | TODO | Depends on POLICY-RISK-40-002 metadata export. | Notifications Service Guild · Risk Engine Guild | Add notification triggers for risk severity escalation/downgrade with profile metadata. | +| 10 | NOTIFY-RISK-67-001 | TODO | Depends on 66-001. | Notifications Service Guild · Policy Guild | Notify when risk profiles are published/deprecated/thresholds change. | +| 11 | NOTIFY-RISK-68-001 | TODO | Depends on 67-001. | Notifications Service Guild | Per-profile routing, quiet hours, dedupe for risk alerts; integrate CLI/Console preferences. | +| 12 | NOTIFY-DOC-70-001 | DONE (2025-11-02) | — | Notifications Service Guild | Document split between legacy `src/Notify` libs and new `src/Notifier` runtime; update architecture docs. | +| 13 | NOTIFY-AIRGAP-56-002 | DONE | — | Notifications Service Guild · DevOps Guild | Bootstrap Pack notifier configs with deterministic secrets handling and offline validation. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Fixed PREP-NOTIFY-OBS-51-001 Task ID (removed trailing hyphen) so dependency lookup works. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-12 | Marked NOTIFY-ATTEST-74-001 and NOTIFY-OAS-61-001 as DOING; documented current blockers. | Notifications Service Guild | +| 2025-11-12 | Added attestation template suite (Section 7 in `docs/notifications/templates.md`) covering template keys/helpers/samples to support NOTIFY-ATTEST-74-001. | Notifications Service Guild | +| 2025-11-12 | Updated notifications architecture/overview/rules docs to reference `tmpl-attest-*` suite; exported baseline templates under `offline/notifier/templates/attestation/`. | Notifications Service Guild | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_171_notifier_i.md` to `SPRINT_0171_0001_0001_notifier_i.md`; content preserved. | Implementer | +| 2025-11-19 | Delivered Telemetry SLO webhook schema (`docs/notifications/slo-webhook-schema.md`); marked PREP-NOTIFY-OBS-51-001-TELEMETRY-SLO-WEBHOOK DONE; NOTIFY-OBS-51-001 remains BLOCKED pending CI restore. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | +| 2025-11-19 | Synced Delivery Tracker with module TASKS: marked NOTIFY-ATTEST-74-001, NOTIFY-OAS-61-001/61-002/62-001 as DONE with respective completion dates; downstream tasks remain TODO. | Implementer | +| 2025-11-19 | Recorded NOTIFY-OAS-63-001 as DONE based on shipped deprecation headers/templates and existing tests (`OpenApiEndpointTests`, `DeprecationTemplateTests`). | Implementer | +| 2025-11-19 | Added sample attestation routing rules (`src/Notifier/StellaOps.Notifier/docs/attestation-rules.sample.json`) covering key rotation/revocation and transparency witness anomalies to support NOTIFY-ATTEST-74-002 wiring. | Implementer | +| 2025-11-19 | Continued NOTIFY-OBS-51-001: added `EgressSloContext`, pluggable `IEgressSloSink`, HTTP webhook sink with configurable timeout, and test sink; processor now emits signals per delivery. Added unit coverage scaffold for the webhook sink (not executed locally). | Implementer | +| 2025-11-19 | Attempted `dotnet test src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/StellaOps.Notifier.Tests.csproj --filter HttpEgressSloSinkTests`; restore canceled (NuGet.targets:196) after ~15s. CI run still required to validate OBS-51-001 changes. | Implementer | +| 2025-11-19 | Attempted `dotnet test ... --filter EventProcessorTests`; restore canceled again (NuGet.targets:196) after ~15s; awaiting CI restore to exercise SLO sink + processor tests. | Implementer | +| 2025-11-19 | Marked NOTIFY-OBS-51-001 status to DOING; OBS SLO webhook code ready, pending CI validation to close the task. | Implementer | +| 2025-11-19 | Action item: run CI pipeline for Notifier with filters `HttpEgressSloSinkTests` and `EventProcessorTests`; if green, set NOTIFY-OBS-51-001 to DONE and attach TRX artefacts. | Implementer | +| 2025-11-19 | Set NOTIFY-OBS-51-001 to BLOCKED pending CI restore capacity; local restore repeatedly cancels (NuGet.targets:196). No further code changes until CI evidence available. | Implementer | +| 2025-11-19 | Added QA playbook for NOTIFY-ATTEST-74-002 (`src/Notifier/StellaOps.Notifier/StellaOps.Notifier.docs/QA-attestation-routing.md`) detailing import steps, event kinds, expected deliveries, and evidence to capture. | Implementer | +| 2025-11-20 | No unblocked work left in this sprint today: NOTIFY-ATTEST-74-002 depends on attestor payload localization freeze; NOTIFY-OBS-51/55 blocked until SLO webhook contract is wired into worker; NOTIFY-RISK-66..68 waits on `POLICY-RISK-40-002` export. Moving to next sprint. | Implementer | + +## Decisions & Risks +- Attestor schema freeze (due 2025-11-13) gates 74-001/002. +- Telemetry SLO webhook payload (frozen 2025-11-17) unblocks OBS chain; incident toggle contract follows add-only evolution. +- OBS SLO webhook code merged but unvalidated locally (restore blocked); CI run required before marking NOTIFY-OBS-51-001 DONE. +- Risk alerts depend on POLICY-RISK-40-002 export; schedule slip would re-baseline RISK tasks. +- Keep Offline Kit parity for templates and secrets handling before enabling new endpoints. + +## Next Checkpoints +| Date (UTC) | Milestone | Owner(s) | +| --- | --- | --- | +| 2025-11-13 | Finalize attestation payload schema + localization tokens. | Notifications Service Guild · Attestor Service Guild | +| 2025-11-15 | Draft Notifier OAS published for review. | Notifications Service Guild · API Contracts Guild | +| 2025-11-18 | Incident payload contract agreed with Telemetry & Ops. | Notifications Service Guild · Observability Guild | +| 2025-11-20 | Risk profile metadata export available (`POLICY-RISK-40-002`). | Notifications Service Guild · Policy Guild | diff --git a/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md b/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md new file mode 100644 index 000000000..297430698 --- /dev/null +++ b/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md @@ -0,0 +1,48 @@ +# Sprint 0172-0001-0002 · Notifier II (Notifications & Telemetry 170.A) + +## Topic & Scope +- Notifier phase II: approval/policy notifications, channels/templates, correlation/digests/simulation, escalations, and hardening. +- **Working directory:** `src/Notifier/StellaOps.Notifier`. + +## Dependencies & Concurrency +- Upstream: Notifier I (Sprint 0171) must land first. +- Concurrency: follow service chain (37 → 38 → 39 → 40); all tasks currently TODO. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/notifications/architecture.md +- src/Notifier/StellaOps.Notifier/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | NOTIFY-SVC-37-001 | TODO | Define contract/OAS. | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Define pack approval & policy notification contract (OpenAPI schema, event payloads, resume tokens, security guidance). | +| 2 | NOTIFY-SVC-37-002 | TODO | Depends on 37-001. | Notifications Service Guild | Implement secure ingestion endpoint, Mongo persistence (`pack_approvals`), idempotent writes, audit trail. | +| 3 | NOTIFY-SVC-37-003 | TODO | Depends on 37-002. | Notifications Service Guild | Approval/policy templates, routing predicates, channel dispatch (email/webhook), localization + redaction. | +| 4 | NOTIFY-SVC-37-004 | TODO | Depends on 37-003. | Notifications Service Guild | Acknowledgement API, Task Runner callback client, metrics for outstanding approvals, runbook updates. | +| 5 | NOTIFY-SVC-38-002 | TODO | Depends on 37-004. | Notifications Service Guild | Channel adapters (email, chat webhook, generic webhook) with retry policies, health checks, audit logging. | +| 6 | NOTIFY-SVC-38-003 | TODO | Depends on 38-002. | Notifications Service Guild | Template service (versioned templates, localization scaffolding) and renderer (redaction allowlists, Markdown/HTML/JSON, provenance links). | +| 7 | NOTIFY-SVC-38-004 | TODO | Depends on 38-003. | Notifications Service Guild | REST + WS APIs (rules CRUD, templates preview, incidents list, ack) with audit logging, RBAC, live feed stream. | +| 8 | NOTIFY-SVC-39-001 | TODO | Depends on 38-004. | Notifications Service Guild | Correlation engine with pluggable key expressions/windows, throttler, quiet hours/maintenance evaluator, incident lifecycle. | +| 9 | NOTIFY-SVC-39-002 | TODO | Depends on 39-001. | Notifications Service Guild | Digest generator (queries, formatting) with schedule runner and distribution. | +| 10 | NOTIFY-SVC-39-003 | TODO | Depends on 39-002. | Notifications Service Guild | Simulation engine/API to dry-run rules against historical events, returning matched actions with explanations. | +| 11 | NOTIFY-SVC-39-004 | TODO | Depends on 39-003. | Notifications Service Guild | Quiet hour calendars + default throttles with audit logging and operator overrides. | +| 12 | NOTIFY-SVC-40-001 | TODO | Depends on 39-004. | Notifications Service Guild | Escalations + on-call schedules, ack bridge, PagerDuty/OpsGenie adapters, CLI/in-app inbox channels. | +| 13 | NOTIFY-SVC-40-002 | TODO | Depends on 40-001. | Notifications Service Guild | Summary storm breaker notifications, localization bundles, fallback handling. | +| 14 | NOTIFY-SVC-40-003 | TODO | Depends on 40-002. | Notifications Service Guild | Security hardening: signed ack links (KMS), webhook HMAC/IP allowlists, tenant isolation fuzz tests, HTML sanitization. | +| 15 | NOTIFY-SVC-40-004 | TODO | Depends on 40-003. | Notifications Service Guild | Observability (metrics/traces for escalations/latency), dead-letter handling, chaos tests for channel outages, retention policies. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_172_notifier_ii.md` to `SPRINT_0172_0001_0002_notifier_ii.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to prevent divergent updates. | Implementer | + +## Decisions & Risks +- All tasks depend on Notifier I outputs and established notification contracts; keep TODO until upstream lands. +- Ensure templates/renderers stay deterministic and offline-ready; hardening tasks must precede GA. + +## Next Checkpoints +- Kickoff after Sprint 0171 completion (date TBD). diff --git a/docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md b/docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md new file mode 100644 index 000000000..11f9ad8ce --- /dev/null +++ b/docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md @@ -0,0 +1,37 @@ +# Sprint 0173-0001-0003 · Notifier III (Notifications & Telemetry 170.A) + +## Topic & Scope +- Notifier phase III: tenant scoping across rules/templates/incidents with RLS and tenant-prefixed channels. +- **Working directory:** `src/Notifier/StellaOps.Notifier`. + +## Dependencies & Concurrency +- Upstream: Notifier II (Sprint 0172-0001-0002) must land first. +- Concurrency: single-track; proceed after prior phase completion. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/notifications/architecture.md +- src/Notifier/StellaOps.Notifier/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-NOTIFY-TEN-48-001-NOTIFIER-II-SPRINT-017 | TODO | Due 2025-11-23 · Accountable: Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifier II (Sprint 0172) not started; tenancy model not finalized.

Document artefact/deliverable for NOTIFY-TEN-48-001 and publish location so downstream tasks can proceed. | +| 1 | NOTIFY-TEN-48-001 | BLOCKED (2025-11-20) | PREP-NOTIFY-TEN-48-001-NOTIFIER-II-SPRINT-017 | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Tenant-scope rules/templates/incidents, RLS on storage, tenant-prefixed channels, include tenant context in notifications. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_173_notifier_iii.md` to `SPRINT_0173_0001_0003_notifier_iii.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | +| 2025-11-20 | Marked NOTIFY-TEN-48-001 BLOCKED pending completion of Sprint 0172 tenancy model; no executable work in this sprint today. | Implementer | + +## Decisions & Risks +- Requires completion of Notifier II and established tenancy model before applying RLS. +- Ensure tenant scoping aligns with platform RLS and channel routing; avoid breaking existing templates. + +## Next Checkpoints +- Schedule kickoff post Notifier II completion (date TBD). \ No newline at end of file diff --git a/docs/implplan/SPRINT_0174_0001_0001_telemetry.md b/docs/implplan/SPRINT_0174_0001_0001_telemetry.md new file mode 100644 index 000000000..63cf283ff --- /dev/null +++ b/docs/implplan/SPRINT_0174_0001_0001_telemetry.md @@ -0,0 +1,60 @@ +# Sprint 0174-0001-0001 · Telemetry (Notifications & Telemetry 170.B) + +## Topic & Scope +- Deliver `StellaOps.Telemetry.Core` bootstrap, propagation middleware, metrics helpers, scrubbing, incident/sealed-mode toggles. +- Provide sample host integrations while keeping deterministic, offline-friendly telemetry with redaction and tenant awareness. +- **Working directory:** `src/Telemetry/StellaOps.Telemetry.Core`. + +## Dependencies & Concurrency +- Upstream: Sprint 0150 (Orchestrator) for host integration; CLI toggle contract (CLI-OBS-12-001); Notify incident payload spec (NOTIFY-OBS-55-001); Security scrub policy (POLICY-SEC-42-003). +- Concurrency: tasks follow 50 → 51 → 55/56 chain; 50-002 waits on 50-001 package. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/modules/telemetry/architecture.md +- src/Telemetry/StellaOps.Telemetry.Core/AGENTS.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-TELEMETRY-OBS-50-002-AWAIT-PUBLISHED-50 | DONE (2025-11-19) | Due 2025-11-23 · Accountable: Telemetry Core Guild | Telemetry Core Guild | Bootstrap package published; reference doc `docs/observability/telemetry-bootstrap.md` provides wiring + config. | +| P2 | PREP-TELEMETRY-OBS-51-001-TELEMETRY-PROPAGATI | DONE (2025-11-20) | Doc published at `docs/observability/telemetry-propagation-51-001.md`. | Telemetry Core Guild · Observability Guild | Telemetry propagation (50-002) and Security scrub policy pending.

Document artefact/deliverable for TELEMETRY-OBS-51-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-TELEMETRY-OBS-51-002-DEPENDS-ON-51-001 | DONE (2025-11-20) | Doc published at `docs/observability/telemetry-scrub-51-002.md`. | Telemetry Core Guild · Security Guild | Depends on 51-001.

Document artefact/deliverable for TELEMETRY-OBS-51-002 and publish location so downstream tasks can proceed. | +| P4 | PREP-TELEMETRY-OBS-56-001-DEPENDS-ON-55-001 | DONE (2025-11-20) | Doc published at `docs/observability/telemetry-sealed-56-001.md`. | Telemetry Core Guild | Depends on 55-001.

Document artefact/deliverable for TELEMETRY-OBS-56-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-CLI-OBS-12-001-INCIDENT-TOGGLE-CONTRACT | DONE (2025-11-20) | Doc published at `docs/observability/cli-incident-toggle-12-001.md`. | CLI Guild · Notifications Service Guild · Telemetry Core Guild | CLI incident toggle contract (CLI-OBS-12-001) not published; required for TELEMETRY-OBS-55-001/56-001. Provide schema + CLI flag behavior. | +| 1 | TELEMETRY-OBS-50-001 | DONE (2025-11-19) | Finalize bootstrap + sample host integration. | Telemetry Core Guild (`src/Telemetry/StellaOps.Telemetry.Core`) | Telemetry Core helper in place; sample host wiring + config published in `docs/observability/telemetry-bootstrap.md`. | +| 2 | TELEMETRY-OBS-50-002 | TODO | PREP-TELEMETRY-OBS-50-002-AWAIT-PUBLISHED-50 (DONE) | Telemetry Core Guild | Context propagation middleware/adapters for HTTP, gRPC, background jobs, CLI; carry `trace_id`, `tenant_id`, `actor`, imposed-rule metadata; async resume harness. | +| 3 | TELEMETRY-OBS-51-001 | TODO | PREP-TELEMETRY-OBS-51-001-TELEMETRY-PROPAGATI | Telemetry Core Guild · Observability Guild | Metrics helpers for golden signals with exemplar support and cardinality guards; Roslyn analyzer preventing unsanitised labels. | +| 4 | TELEMETRY-OBS-51-002 | BLOCKED (2025-11-20) | PREP-TELEMETRY-OBS-51-002-DEPENDS-ON-51-001 | Telemetry Core Guild · Security Guild | Redaction/scrubbing filters for secrets/PII at logger sink; per-tenant config with TTL; audit overrides; determinism tests. | +| 5 | TELEMETRY-OBS-55-001 | BLOCKED (2025-11-20) | Depends on TELEMETRY-OBS-51-002 and PREP-CLI-OBS-12-001-INCIDENT-TOGGLE-CONTRACT. | Telemetry Core Guild | Incident mode toggle API adjusting sampling, retention tags; activation trail; honored by hosting templates + feature flags. | +| 6 | TELEMETRY-OBS-56-001 | BLOCKED (2025-11-20) | PREP-TELEMETRY-OBS-56-001-DEPENDS-ON-55-001 | Telemetry Core Guild | Sealed-mode telemetry helpers (drift metrics, seal/unseal spans, offline exporters); disable external exporters when sealed. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-20 | Added sealed-mode helper prep doc (`telemetry-sealed-56-001.md`); marked PREP-TELEMETRY-OBS-56-001 DONE. | Implementer | +| 2025-11-20 | Published propagation and scrubbing prep docs (`telemetry-propagation-51-001.md`, `telemetry-scrub-51-002.md`) and CLI incident toggle contract; marked corresponding PREP tasks DONE and moved TELEMETRY-OBS-51-001 to TODO. | Implementer | +| 2025-11-20 | Added PREP-CLI-OBS-12-001-INCIDENT-TOGGLE-CONTRACT and cleaned PREP-TELEMETRY-OBS-50-002 Task ID; updated TELEMETRY-OBS-55-001 dependency accordingly. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-12 | Marked TELEMETRY-OBS-50-001 as DOING; branch `feature/telemetry-core-bootstrap` with resource detector/profile manifest in review; host sample slated 2025-11-18. | Telemetry Core Guild | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_174_telemetry.md` to `SPRINT_0174_0001_0001_telemetry.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | +| 2025-11-20 | Marked tasks 50-002..56-001 BLOCKED: waiting on 50-001 package publication, Security scrub policy, and CLI incident-toggle contract; no executable work until upstream artefacts land. | Implementer | +| 2025-11-19 | PREP-TELEMETRY-OBS-50-002-AWAIT-PUBLISHED-50 completed; bootstrap doc published. Downstream tasks remain blocked on propagation/scrub/toggle contracts. | Implementer | +| 2025-11-19 | TELEMETRY-OBS-50-001 set to DONE; TELEMETRY-OBS-50-002 moved to TODO now that bootstrap package is documented. | Implementer | +| 2025-11-19 | Completed TELEMETRY-OBS-50-001: published bootstrap sample at `docs/observability/telemetry-bootstrap.md`; library already present. | Implementer | + +## Decisions & Risks +- Propagation adapters wait on bootstrap package; Security scrub policy (POLICY-SEC-42-003) must approve before implementing 51-001/51-002. +- Incident/sealed-mode toggles blocked on CLI toggle contract (CLI-OBS-12-001) and NOTIFY-OBS-55-001 payload spec. +- Ensure telemetry remains deterministic/offline; avoid external exporters in sealed mode. + +## Next Checkpoints +| Date (UTC) | Milestone | Owner(s) | +| --- | --- | --- | +| 2025-11-18 | Land Telemetry Core bootstrap sample in Orchestrator. | Telemetry Core Guild · Orchestrator Guild | +| 2025-11-19 | Publish propagation adapter API draft. | Telemetry Core Guild | +| 2025-11-21 | Security sign-off on scrub policy (POLICY-SEC-42-003). | Telemetry Core Guild · Security Guild | +| 2025-11-22 | Incident/CLI toggle contract agreed (CLI-OBS-12-001 + NOTIFY-OBS-55-001). | Telemetry Core Guild · Notifications Service Guild · CLI Guild | diff --git a/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md b/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md new file mode 100644 index 000000000..b1365cfdc --- /dev/null +++ b/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md @@ -0,0 +1,38 @@ +# Sprint 0185-0001-0001 · Shared Replay Primitives (Replay Core 185.A) + +## Topic & Scope +- Stand up shared replay library, canonicalization/hashing helpers, deterministic bundle writer, and baseline replay documentation. +- **Working directory:** `src/__Libraries/StellaOps.Replay.Core` and relevant docs under `docs/replay` and `docs/data`. + +## Dependencies & Concurrency +- Upstream: Sprint 160 Export & Evidence for bundle contracts; Replay CAS section already published (2025-11-03). +- Concurrency: execute tasks in listed order; docs tasks align with code tasks. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md (Replay CAS §5) +- docs/replay/DETERMINISTIC_REPLAY.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | REPLAY-CORE-185-001 | TODO | CAS section published; start scaffolding library. | BE-Base Platform Guild (`src/__Libraries/StellaOps.Replay.Core`) | Scaffold `StellaOps.Replay.Core` with manifest schema types, canonical JSON rules, Merkle utilities, DSSE payload builders; add `AGENTS.md`/`TASKS.md`; cross-reference deterministic replay doc. | +| 2 | REPLAY-CORE-185-002 | TODO | Depends on 185-001. | Platform Guild | Deterministic bundle writer (tar.zst, CAS naming) and hashing abstractions; update platform architecture doc with “Replay CAS” subsection. | +| 3 | REPLAY-CORE-185-003 | TODO | Depends on 185-002. | Platform Data Guild | Define Mongo collections (`replay_runs`, `replay_bundles`, `replay_subjects`) and indices; align with schema doc. | +| 4 | DOCS-REPLAY-185-003 | TODO | Parallel with 185-003. | Docs Guild · Platform Data Guild (docs) | Author `docs/data/replay_schema.md` detailing collections, index guidance, offline sync strategy. | +| 5 | DOCS-REPLAY-185-004 | TODO | After 185-002/003. | Docs Guild (docs) | Expand `docs/replay/DEVS_GUIDE_REPLAY.md` with integration guidance (Scanner, Evidence Locker, CLI) and checklist from deterministic replay doc §11. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-03 | Replay CAS section published in `docs/modules/platform/architecture-overview.md` §5; tasks 185-001/002 may move to DOING once scaffolding starts. | Platform Guild | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_185_shared_replay_primitives.md` to `SPRINT_0185_0001_0001_shared_replay_primitives.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | + +## Decisions & Risks +- Await library scaffolding start; ensure deterministic rules match published CAS section. +- Schema/docs must stay aligned with Replay CAS layout to keep offline determinism. + +## Next Checkpoints +- Kickoff once scaffolding resources assigned (date TBD). diff --git a/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md b/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md new file mode 100644 index 000000000..f01872f21 --- /dev/null +++ b/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md @@ -0,0 +1,52 @@ +# Sprint 0186-0001-0001 · Record & Deterministic Execution (Scanner Replay 186.A) + +## Topic & Scope +- Enable Scanner to emit replay manifests/bundles, enforce deterministic execution, align signing flows, and publish determinism evidence. +- **Working directory:** `src/Scanner` (WebService, Worker, Replay), `src/Signer`, `src/Authority`, related docs under `docs/replay` and `docs/modules/scanner`. + +## Dependencies & Concurrency +- Upstream: Sprint 0185 (Replay Core foundations) and Sprint 0130 Scanner & Surface. +- Concurrency: execute tasks in listed order; signing tasks align with replay outputs; docs tasks mirror code tasks. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/modules/platform/architecture-overview.md +- docs/replay/DETERMINISTIC_REPLAY.md +- docs/replay/TEST_STRATEGY.md +- docs/modules/scanner/architecture.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | SCAN-REPLAY-186-001 | TODO | Start record mode in WebService. | Scanner Guild (`src/Scanner/StellaOps.Scanner.WebService`, docs) | Implement `record` mode (manifest assembly, policy/feed/tool hash capture, CAS uploads); doc workflow referencing replay doc §6. | +| 2 | SCAN-REPLAY-186-002 | TODO | Depends on 186-001. | Scanner Guild | Update Worker analyzers to consume sealed input bundles, enforce deterministic ordering, contribute Merkle metadata; add `docs/modules/scanner/deterministic-execution.md`. | +| 3 | SIGN-REPLAY-186-003 | TODO | Depends on 186-001/002. | Signing Guild (`src/Signer`, `src/Authority`) | Extend Signer/Authority DSSE flows to cover replay manifests/bundles; refresh signer/authority architecture docs referencing replay doc §5. | +| 4 | SIGN-CORE-186-004 | TODO | Parallel with 186-003. | Signing Guild | Replace HMAC demo in Signer with StellaOps.Cryptography providers (keyless + KMS); provider selection, key loading, cosign-compatible DSSE output. | +| 5 | SIGN-CORE-186-005 | TODO | Depends on 186-004. | Signing Guild | Refactor `SignerStatementBuilder` to support StellaOps predicate types and delegate canonicalisation to Provenance library when available. | +| 6 | SIGN-TEST-186-006 | TODO | Depends on 186-004/005. | Signing Guild · QA Guild | Upgrade signer integration tests to real crypto abstraction + fixture predicates (promotion, SBOM, replay); deterministic test data. | +| 7 | AUTH-VERIFY-186-007 | TODO | After 186-003. | Authority Guild · Provenance Guild | Authority-side helper/service validating DSSE signatures and Rekor proofs for promotion attestations using trusted checkpoints; offline audit flow. | +| 8 | SCAN-DETER-186-008 | TODO | Parallel with 186-002. | Scanner Guild | Add deterministic execution switches (fixed clock, RNG seed, concurrency cap, feed/policy pins, log filtering) via CLI/env/config. | +| 9 | SCAN-DETER-186-009 | TODO | Depends on 186-008. | Scanner Guild · QA Guild | Determinism harness to replay scans, canonicalise outputs, record hash matrices (`docs/modules/scanner/determinism-score.md`). | +| 10 | SCAN-DETER-186-010 | TODO | Depends on 186-009. | Scanner Guild · Export Center Guild | Emit/publish `determinism.json` with scores/hashes/diffs alongside each scanner release via CAS/object storage; document in release guide. | +| 11 | SCAN-ENTROPY-186-011 | TODO | Parallel track. | Scanner Guild | Entropy analysis for ELF/PE/Mach-O/opaque blobs (sliding-window metrics, section heuristics); record offsets/hints (see `docs/modules/scanner/entropy.md`). | +| 12 | SCAN-ENTROPY-186-012 | TODO | Depends on 186-011. | Scanner Guild · Provenance Guild | Generate `entropy.report.json`, image-level penalties; attach evidence to manifests/attestations; expose ratios for policy engines. | +| 13 | SCAN-CACHE-186-013 | TODO | Parallel with replay work. | Scanner Guild | Layer-level SBOM/VEX cache keyed by layer digest + manifest hash + tool/feed/policy IDs; re-verify DSSE on cache hits; persist indexes; document referencing 16-Nov-2026 advisory. | +| 14 | SCAN-DIFF-CLI-186-014 | TODO | Depends on replay+cache scaffolding. | Scanner Guild · CLI Guild | Deterministic diff-aware rescan workflow (`scan.lock.json`, JSON Patch diffs, CLI verbs `stella scan --emit-diff` / `stella diff`); replayable tests; docs. | +| 15 | SBOM-BRIDGE-186-015 | TODO | Parallel; coordinate with Sbomer. | Sbomer Guild · Scanner Guild | Establish SPDX 3.0.1 as canonical SBOM persistence; deterministic CycloneDX 1.6 exporter; map table/library; wire snapshot hashes into replay manifests. | +| 16 | DOCS-REPLAY-186-004 | TODO | After replay schema settled. | Docs Guild | Author `docs/replay/TEST_STRATEGY.md` (golden replay, feed drift, tool upgrade); link from replay docs and Scanner architecture. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-03 | `docs/replay/TEST_STRATEGY.md` drafted; Replay CAS section published — Scanner/Signer guilds should move replay tasks to DOING when engineering starts. | Planning | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_186_record_deterministic_execution.md` to `SPRINT_0186_0001_0001_record_deterministic_execution.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to prevent divergent updates. | Implementer | + +## Decisions & Risks +- Depends on Replay Core (0185); do not start until CAS and TEST_STRATEGY baselines are confirmed. +- Deterministic execution must preserve hermetic runs; ensure fixed clock/RNG/log filtering before enabling harness. +- Signing/verification changes must stay aligned with Provenance library once available. + +## Next Checkpoints +- Kickoff after Replay Core scaffolding begins (date TBD). diff --git a/docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md b/docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md new file mode 100644 index 000000000..240314695 --- /dev/null +++ b/docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md @@ -0,0 +1,50 @@ +# Sprint 0187-0001-0001 · Evidence Locker & CLI Integration (Replay Delivery 187.A) + +## Topic & Scope +- Persist replay bundles in Evidence Locker, expose ledger-backed verification, and ship offline-ready CLI workflows with sovereign crypto support. +- **Working directory:** `src/EvidenceLocker/StellaOps.EvidenceLocker`, `src/Cli/StellaOps.Cli`, `src/Attestor/StellaOps.Attestor`, relevant docs under `docs/replay`, `docs/modules/evidence-locker`, `docs/modules/cli`, `docs/runbooks`. + +## Dependencies & Concurrency +- Upstream: Sprint 0186 (Scanner record mode), Sprint 0160 Export & Evidence, Sprint 0185 replay core, Sprint 0180 Experience & SDKs. +- Concurrency: execute tasks in listed order; CLI/Attestor depend on EvidenceLocker API schema; crypto routing depends on provider registry readiness. + +## Documentation Prerequisites +- docs/README.md +- docs/07_HIGH_LEVEL_ARCHITECTURE.md +- docs/replay/DETERMINISTIC_REPLAY.md +- docs/replay/DEVS_GUIDE_REPLAY.md +- docs/runbooks/replay_ops.md +- docs/security/crypto-routing-audit-2025-11-07.md + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| P1 | PREP-EVID-REPLAY-187-001-SCANNER-RECORD-PAYLO | TODO | Due 2025-11-23 · Accountable: Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Scanner record payloads (Sprint 0186) not available; EvidenceLocker API schema cannot be drafted.

Document artefact/deliverable for EVID-REPLAY-187-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-CLI-REPLAY-187-002-DEPENDS-ON-187-001-SC | TODO | Due 2025-11-23 · Accountable: DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | Depends on 187-001 schema freeze.

Document artefact/deliverable for CLI-REPLAY-187-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-ATTEST-REPLAY-187-003-DEPENDS-ON-187-001 | TODO | Due 2025-11-23 · Accountable: Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Depends on 187-001 payloads.

Document artefact/deliverable for ATTEST-REPLAY-187-003 and publish location so downstream tasks can proceed. | +| P4 | PREP-RUNBOOK-REPLAY-187-004-NEEDS-APIS-DEFINE | TODO | Due 2025-11-23 · Accountable: Docs Guild · Ops Guild (docs/runbooks) | Docs Guild · Ops Guild (docs/runbooks) | Needs APIs defined from 187-001.

Document artefact/deliverable for RUNBOOK-REPLAY-187-004 and publish location so downstream tasks can proceed. | +| P5 | PREP-VALIDATE-BUNDLE-187-005-DEPENDS-ON-187-0 | TODO | Due 2025-11-23 · Accountable: QA Guild · CLI Guild · Docs Guild | QA Guild · CLI Guild · Docs Guild | Depends on 187-001/002/003; no payloads yet.

Document artefact/deliverable for VALIDATE-BUNDLE-187-005 and publish location so downstream tasks can proceed. | +| P6 | PREP-EVID-CRYPTO-90-001-ICRYPTOPROVIDERREGIST | TODO | Due 2025-11-23 · Accountable: Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | ICryptoProviderRegistry readiness not confirmed; sovereign crypto profiles pending.

Document artefact/deliverable for EVID-CRYPTO-90-001 and publish location so downstream tasks can proceed. | +| 1 | EVID-REPLAY-187-001 | BLOCKED (2025-11-20) | PREP-EVID-REPLAY-187-001-SCANNER-RECORD-PAYLO | Evidence Locker Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`, docs) | Implement replay bundle ingestion/retention APIs; document storage/retention rules referencing replay doc §§2 & 8. | +| 2 | CLI-REPLAY-187-002 | BLOCKED (2025-11-20) | PREP-CLI-REPLAY-187-002-DEPENDS-ON-187-001-SC | DevEx/CLI Guild (`src/Cli/StellaOps.Cli`, docs) | Add `scan --record`, `verify`, `replay`, `diff` commands with offline bundle resolution; update CLI architecture and replay appendix. | +| 3 | ATTEST-REPLAY-187-003 | BLOCKED (2025-11-20) | PREP-ATTEST-REPLAY-187-003-DEPENDS-ON-187-001 | Attestor Guild (`src/Attestor/StellaOps.Attestor`, docs) | Wire Attestor/Rekor anchoring for replay manifests; extend attestor architecture with replay ledger flow. | +| 4 | RUNBOOK-REPLAY-187-004 | BLOCKED (2025-11-20) | PREP-RUNBOOK-REPLAY-187-004-NEEDS-APIS-DEFINE | Docs Guild · Ops Guild (docs/runbooks) | Publish `/docs/runbooks/replay_ops.md` covering retention enforcement, RootPack rotation, offline kits, verification drills. | +| 5 | VALIDATE-BUNDLE-187-005 | BLOCKED (2025-11-20) | PREP-VALIDATE-BUNDLE-187-005-DEPENDS-ON-187-0 | QA Guild · CLI Guild · Docs Guild | Deliver `VALIDATION_PLAN.md`, harness scripts (quiet vs baseline, provenance bundle export), `stella bundle verify` subcommand checking DSSE/Rekor/SBOM/policy/replay claims end-to-end. | +| 6 | EVID-CRYPTO-90-001 | BLOCKED (2025-11-20) | PREP-EVID-CRYPTO-90-001-ICRYPTOPROVIDERREGIST | Evidence Locker Guild · Security Guild (`src/EvidenceLocker/StellaOps.EvidenceLocker`) | Route Evidence Locker hashing/signing (manifest digests, DSSE assembly, bundle encryption) through crypto provider registry for sovereign profiles. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | +| 2025-11-03 | `/docs/runbooks/replay_ops.md` created; teams can move replay delivery tasks to DOING alongside Ops runbook rehearsals. | Docs Guild | +| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_187_evidence_locker_cli_integration.md` to `SPRINT_0187_0001_0001_evidence_locker_cli_integration.md`; content preserved. | Implementer | +| 2025-11-19 | Added legacy-file redirect stub to avoid divergent updates. | Implementer | +| 2025-11-20 | Marked all tasks BLOCKED: waiting on Scanner record payloads (Sprint 0186) and ICryptoProviderRegistry readiness; no executable work in this sprint until upstream artefacts land. | Implementer | + +## Decisions & Risks +- EvidenceLocker API schema must align with replay bundles and sovereign crypto routing; approval review on 2025-11-18. +- CLI/Attestor work blocked until Scanner record payloads and EvidenceLocker schema freeze. +- Provider registry must support sovereign profiles (`ru-offline`, etc.) before wiring EVID-CRYPTO-90-001. + +## Next Checkpoints +- Schedule joint review of replay_ops runbook and EvidenceLocker API (date TBD). \ No newline at end of file diff --git a/docs/implplan/SPRINT_0215_0001_0001_web_iv.md b/docs/implplan/SPRINT_0215_0001_0001_web_iv.md new file mode 100644 index 000000000..e61d35d59 --- /dev/null +++ b/docs/implplan/SPRINT_0215_0001_0001_web_iv.md @@ -0,0 +1,52 @@ +# Sprint 0215-0001-0001 · Web IV (Experience & SDKs 180.F) + +## Topic & Scope +- Phase IV web gateway work: orchestrator controls and Policy Studio CRUD/simulation endpoints aligned with Policy Engine. +- Complete policy pack lifecycle (CRUD → activation → publish/promote) with deterministic pagination, RBAC, and telemetry. +- Wire console/CLI consumers by keeping API docs and rate limits in sync with Sprint 180.F deliverables. +- **Working directory:** `src/Web/StellaOps.Web`. + +## Dependencies & Concurrency +- Upstream Sprint 180.F (Web III) must land shared components before these endpoints go live. +- Policy endpoints (20-001 → 20-004) must complete in order; Policy pack tracks (23-001/002) stay BLOCKED until 20-004 ships. +- Policy registry/Studio extensions (27-001…27-005) are sequential; avoid parallel development without shared schema updates. + +## Documentation Prerequisites +- `docs/README.md` +- `docs/07_HIGH_LEVEL_ARCHITECTURE.md` +- `docs/modules/platform/architecture-overview.md` +- `docs/modules/policy/architecture.md` +- `src/Web/StellaOps.Web/AGENTS.md` + +## Delivery Tracker +| # | Task ID | Status | Key dependency / next step | Owners | Task Definition | +| --- | --- | --- | --- | --- | --- | +| 1 | WEB-ORCH-33-001 | TODO | WEB-ORCH-32-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add POST action routes (pause/resume/backfill) for orchestrator-run control, honoring RBAC and audit logging. | +| 2 | WEB-ORCH-34-001 | TODO | WEB-ORCH-33-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose quotas/backfill APIs plus queue/backpressure metrics with admin scopes and error clustering. | +| 3 | WEB-POLICY-20-001 | TODO | — | BE-Base Platform Guild · Policy Guild (`src/Web/StellaOps.Web`) | Implement Policy CRUD/compile/run/simulate/findings/explain endpoints with OpenAPI + tenant scoping. | +| 4 | WEB-POLICY-20-002 | TODO | WEB-POLICY-20-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add pagination/filtering/sorting + tenant guards to policy listings with deterministic ordering diagnostics. | +| 5 | WEB-POLICY-20-003 | TODO | WEB-POLICY-20-002 | BE-Base Platform Guild · QA Guild (`src/Web/StellaOps.Web`) | Map engine errors to `ERR_POL_*` payloads with contract tests and correlation IDs. | +| 6 | WEB-POLICY-20-004 | TODO | WEB-POLICY-20-003 | Platform Reliability Guild (`src/Web/StellaOps.Web`) | Introduce adaptive rate limits/quotas for simulations, expose metrics, and document retry headers. | +| 7 | WEB-POLICY-23-001 | BLOCKED (2025-10-29) | WEB-POLICY-20-004 | BE-Base Platform Guild · Policy Guild (`src/Web/StellaOps.Web`) | Create/list/fetch policy packs and revisions with pagination, RBAC, and AOC metadata exposure. | +| 8 | WEB-POLICY-23-002 | BLOCKED (2025-10-29) | WEB-POLICY-23-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Add activation endpoints with scope windows, conflict checks, optional two-person approvals, and events. | +| 9 | WEB-POLICY-23-003 | TODO | WEB-POLICY-23-002 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Provide `/policy/simulate` + `/policy/evaluate` streaming APIs with rate limiting and error mapping. | +| 10 | WEB-POLICY-23-004 | TODO | WEB-POLICY-23-003 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Expose explain history endpoints showing decision trees, consulted sources, and AOC chain. | +| 11 | WEB-POLICY-27-001 | TODO | WEB-POLICY-23-004 | BE-Base Platform Guild · Policy Registry Guild (`src/Web/StellaOps.Web`) | Proxy Policy Registry APIs (workspaces/versions/reviews) with tenant scoping, RBAC, and streaming downloads. | +| 12 | WEB-POLICY-27-002 | TODO | WEB-POLICY-27-001 | BE-Base Platform Guild (`src/Web/StellaOps.Web`) | Implement review lifecycle endpoints (open/comment/approve/reject) with audit headers and pagination. | +| 13 | WEB-POLICY-27-003 | TODO | WEB-POLICY-27-002 | BE-Base Platform Guild · Scheduler Guild (`src/Web/StellaOps.Web`) | Expose quick/batch simulation endpoints with SSE progress streams, cursor pagination, and manifest downloads. | +| 14 | WEB-POLICY-27-004 | TODO | WEB-POLICY-27-003 | BE-Base Platform Guild · Security Guild (`src/Web/StellaOps.Web`) | Add publish/sign/promote/rollback endpoints with idempotent IDs, canary params, environment bindings, and events. | +| 15 | WEB-POLICY-27-005 | TODO | WEB-POLICY-27-004 | BE-Base Platform Guild · Observability Guild (`src/Web/StellaOps.Web`) | Instrument Policy Studio metrics/logs (compile latency, simulation queue depth, approvals, promotions) and dashboards. | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Normalized sprint to standard template and migrated content from `SPRINT_215_web_iv.md`. | Project Mgmt | + +## Decisions & Risks +- Policy pack CRUD/activation (WEB-POLICY-23-001/002) remain BLOCKED until WEB-POLICY-20-004 rate-limit work lands. +- Registry/Studio chain (WEB-POLICY-27-001..005) must stay in order to keep schemas stable; avoid parallel merges without shared reviews. +- Ensure RBAC + tenant-scoping docs stay aligned with Policy Engine contracts to prevent drift during promotions. + +## Next Checkpoints +- 2025-11-22 · Verify WEB-POLICY-20-004 rate-limit design review completed (Platform Reliability Guild). +- 2025-11-25 · Policy pack CRUD kickoff pending unblock from WEB-POLICY-20-004 (Policy Guild + BE-Base Platform Guild). diff --git a/docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md b/docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md index 120e8bad0..3fc156f7e 100644 --- a/docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md +++ b/docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md @@ -21,13 +21,15 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-CLI-OPS-0001-WAITING-FOR-NEXT-DEMO-OUTPU | TODO | Due 2025-11-25 · Accountable: Ops Guild | Ops Guild | Waiting for next demo outputs.

Document artefact/deliverable for CLI-OPS-0001 and publish location so downstream tasks can proceed. | | 1 | CLI-DOCS-0001 | DONE | Synced sprint references on 2025-11-17 | Docs Guild | Update docs/AGENTS to reflect current CLI scope and sprint naming; align with template rules. | | 2 | CLI-ENG-0001 | DONE | Sprint normalized; statuses mirrored | Module Team | Update status via ./AGENTS.md workflow and ensure module docs reference current sprint. | -| 3 | CLI-OPS-0001 | BLOCKED | Waiting for next demo outputs | Ops Guild | Sync outcomes back to ../.. ; refresh ops/runbook notes after demo. | +| 3 | CLI-OPS-0001 | BLOCKED | PREP-CLI-OPS-0001-WAITING-FOR-NEXT-DEMO-OUTPU | Ops Guild | Sync outcomes back to ../.. ; refresh ops/runbook notes after demo. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-17 | Normalised sprint to standard template; renamed from SPRINT_316_docs_modules_cli.md. | Docs | | 2025-11-17 | Completed CLI-DOCS-0001 and CLI-ENG-0001 by updating CLI docs to reference normalized sprint. | Module Team | @@ -36,4 +38,4 @@ - Keep sprint naming aligned with template to avoid broken references in CLI docs. ## Next Checkpoints -- 2025-11-22 · Check for demo outputs to unblock CLI-OPS-0001. Owner: Ops Guild. +- 2025-11-22 · Check for demo outputs to unblock CLI-OPS-0001. Owner: Ops Guild. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md b/docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md index 363e3ea6f..e10aaa3d2 100644 --- a/docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md +++ b/docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md @@ -20,13 +20,15 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-GRAPH-OPS-0001-WAITING-FOR-NEXT-DEMO-OUT | TODO | Due 2025-11-25 · Accountable: Ops Guild | Ops Guild | Waiting for next demo outputs to review dashboards/runbooks.

Document artefact/deliverable for GRAPH-OPS-0001 and publish location so downstream tasks can proceed. | | 1 | GRAPH-ENG-0001 | DONE | Synced docs to Sprint 0141 rename on 2025-11-17 | Module Team | Keep module milestones in sync with `/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md` and related files; update references and note deltas. | | 2 | GRAPH-DOCS-0002 | BLOCKED | Await DOCS-GRAPH-24-003 cross-links | Docs Guild | Add API/query doc cross-links once DOCS-GRAPH-24-003 lands. | -| 3 | GRAPH-OPS-0001 | BLOCKED | Waiting for next demo outputs to review dashboards/runbooks | Ops Guild | Review graph observability dashboards/runbooks after the next sprint demo; capture updates in runbooks. | +| 3 | GRAPH-OPS-0001 | BLOCKED | PREP-GRAPH-OPS-0001-WAITING-FOR-NEXT-DEMO-OUT | Ops Guild | Review graph observability dashboards/runbooks after the next sprint demo; capture updates in runbooks. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-17 | Marked GRAPH-DOCS-0002 and GRAPH-OPS-0001 as BLOCKED pending DOCS-GRAPH-24-003 + next demo outputs. | Module Team | | 2025-11-17 | Completed GRAPH-ENG-0001; README and implementation_plan now reference SPRINT_0141_0001_0001_graph_indexer.md. | Module Team | | 2025-11-17 | Normalised sprint to standard template; renamed from SPRINT_321_docs_modules_graph.md. | Docs | @@ -39,4 +41,4 @@ ## Next Checkpoints - 2025-11-17 · Milestone sync completed (GRAPH-ENG-0001). Owner: Module Team. - 2025-11-22 · Confirm DOCS-GRAPH-24-003 status; proceed with cross-links if available. Owner: Docs Guild. -- 2025-11-25 · Runbook/observability review post-demo. Owner: Ops Guild. +- 2025-11-25 · Runbook/observability review post-demo. Owner: Ops Guild. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0400_0001_0001_reachability_runtime_static_union.md b/docs/implplan/SPRINT_0400_0001_0001_reachability_runtime_static_union.md index 6e8d66c96..e4da8263b 100644 --- a/docs/implplan/SPRINT_0400_0001_0001_reachability_runtime_static_union.md +++ b/docs/implplan/SPRINT_0400_0001_0001_reachability_runtime_static_union.md @@ -21,10 +21,10 @@ | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | | 1 | ZASTAVA-REACH-201-001 | TODO | Need runtime symbol sampling design; align with GAP-ZAS-002 | Zastava Observer Guild | Implement runtime symbol sampling in `StellaOps.Zastava.Observer` (EntryTrace-aware shell AST + build-id capture) and stream ND-JSON batches to Signals `/runtime-facts`, including CAS pointers for traces. Update runbook + config references. | -| 2 | SCAN-REACH-201-002 | DOING | Continue static lifters; ensure SymbolID generation matches runtime | Scanner Worker Guild | Ship language-aware static lifters (JVM, .NET/Roslyn+IL, Go SSA, Node/Deno TS AST, Rust MIR, Swift SIL, shell/binary analyzers) in Scanner Worker; emit canonical SymbolIDs, CAS-stored graphs, and attach reachability tags to SBOM components. | -| 3 | SIGNALS-REACH-201-003 | DOING | Ingest schema needs runtime/static union spec | Signals Guild | Extend Signals ingestion to accept the new multi-language graphs + runtime facts, normalize into `reachability_graphs` CAS layout, and expose retrieval APIs for Policy/CLI. | -| 4 | SIGNALS-REACH-201-004 | DOING | Depends on 201-003 schema | Signals Guild · Policy Guild | Build the reachability scoring engine (state/score/confidence), wire Redis caches + `signals.fact.updated` events, and integrate reachability weights defined in `docs/11_DATA_SCHEMAS.md`. | -| 5 | REPLAY-REACH-201-005 | DOING | Needs finalized graph payload shape | BE-Base Platform Guild | Update `StellaOps.Replay.Core` manifest schema + bundle writer so replay packs capture reachability graphs, runtime traces, analyzer versions, and evidence hashes; document new CAS namespace. | +| 2 | SCAN-REACH-201-002 | BLOCKED | Await runtime/static union schema (SymbolID + CAS layout) | Scanner Worker Guild | Ship language-aware static lifters (JVM, .NET/Roslyn+IL, Go SSA, Node/Deno TS AST, Rust MIR, Swift SIL, shell/binary analyzers) in Scanner Worker; emit canonical SymbolIDs, CAS-stored graphs, and attach reachability tags to SBOM components. | +| 3 | SIGNALS-REACH-201-003 | BLOCKED | Runtime/static union schema not published | Signals Guild | Extend Signals ingestion to accept the new multi-language graphs + runtime facts, normalize into `reachability_graphs` CAS layout, and expose retrieval APIs for Policy/CLI. | +| 4 | SIGNALS-REACH-201-004 | BLOCKED | Depends on 201-003 schema | Signals Guild · Policy Guild | Build the reachability scoring engine (state/score/confidence), wire Redis caches + `signals.fact.updated` events, and integrate reachability weights defined in `docs/11_DATA_SCHEMAS.md`. | +| 5 | REPLAY-REACH-201-005 | BLOCKED | Needs finalized graph payload shape | BE-Base Platform Guild | Update `StellaOps.Replay.Core` manifest schema + bundle writer so replay packs capture reachability graphs, runtime traces, analyzer versions, and evidence hashes; document new CAS namespace. | | 6 | DOCS-REACH-201-006 | TODO | Requires outputs from 1–5 | Docs Guild | Author the reachability doc set (`docs/signals/reachability.md`, `callgraph-formats.md`, `runtime-facts.md`, CLI/UI appendices) plus update Zastava + Replay guides with the new evidence and operator workflows. | | 7 | QA-REACH-201-007 | TODO | Move fixtures + create evaluator harness | QA Guild | Integrate `reachbench-2025-expanded` fixture pack under `tests/reachability/fixtures/`, add evaluator harness tests that validate reachable vs unreachable cases, and wire CI guidance for deterministic runs. | | 8 | GAP-SCAN-001 | TODO | Align with task 2; binary symbolizers | Scanner Worker Guild | Implement binary/language symbolizers that emit `richgraph-v1` payloads with canonical SymbolIDs and `code_id` anchors, persist graphs to CAS via `StellaOps.Scanner.Reachability`, and refresh analyzer docs/fixtures. | @@ -34,6 +34,7 @@ | Date (UTC) | Update | Owner | | --- | --- | --- | | 2025-11-18 | Normalised sprint to standard template; renamed from SPRINT_400_runtime_facts_static_callgraph_union.md. | Docs | +| 2025-11-19 | Marked tasks 201-002..201-005 BLOCKED pending runtime/static union schema (SymbolID+CAS layout); no implementation until schema is published. | Implementer | ## Decisions & Risks - Runtime/static schema alignment pending (SymbolID, CAS layout, overlay tags); blocks ingestion and scoring finalization. diff --git a/docs/implplan/SPRINT_0509_0001_0001_samples.md b/docs/implplan/SPRINT_0509_0001_0001_samples.md index 4af27deeb..89a7a46e9 100644 --- a/docs/implplan/SPRINT_0509_0001_0001_samples.md +++ b/docs/implplan/SPRINT_0509_0001_0001_samples.md @@ -19,17 +19,22 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | SAMPLES-GRAPH-24-003 | DOING | Align overlay format with Graph Guild; build mock SBOM bundle source list | Samples Guild · SBOM Service Guild | Generate large-scale SBOM graph fixture (~40k nodes) with policy overlay snapshot for perf/regression suites. | +| P1 | PREP-SAMPLES-LNM-22-001-WAITING-ON-FINALIZED | TODO | Due 2025-11-26 · Accountable: Samples Guild · Concelier Guild | Samples Guild · Concelier Guild | Waiting on finalized advisory linkset schema (Concelier).

Document artefact/deliverable for SAMPLES-LNM-22-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT | TODO | Due 2025-11-26 · Accountable: Samples Guild · Excititor Guild | Samples Guild · Excititor Guild | Depends on 22-001 outputs + Excititor observation/linkset implementation.

Document artefact/deliverable for SAMPLES-LNM-22-002 and publish location so downstream tasks can proceed. | +| 1 | SAMPLES-GRAPH-24-003 | BLOCKED | Await Graph overlay format decision + mock SBOM cache availability | Samples Guild · SBOM Service Guild | Generate large-scale SBOM graph fixture (~40k nodes) with policy overlay snapshot for perf/regression suites. | | 2 | SAMPLES-GRAPH-24-004 | TODO | Blocked on 24-003 fixture availability | Samples Guild · UI Guild | Create vulnerability explorer JSON/CSV fixtures capturing conflicting evidence and policy outputs for UI/CLI automated tests. | -| 3 | SAMPLES-LNM-22-001 | BLOCKED | Waiting on finalized advisory linkset schema (Concelier) | Samples Guild · Concelier Guild | Create advisory observation/linkset fixtures (NVD, GHSA, OSV disagreements) for API/CLI/UI tests with documented conflicts. | -| 4 | SAMPLES-LNM-22-002 | BLOCKED | Depends on 22-001 outputs + Excititor observation/linkset implementation | Samples Guild · Excititor Guild | Produce VEX observation/linkset fixtures demonstrating status conflicts and path relevance; include raw blobs. | +| 3 | SAMPLES-LNM-22-001 | BLOCKED | PREP-SAMPLES-LNM-22-001-WAITING-ON-FINALIZED | Samples Guild · Concelier Guild | Create advisory observation/linkset fixtures (NVD, GHSA, OSV disagreements) for API/CLI/UI tests with documented conflicts. | +| 4 | SAMPLES-LNM-22-002 | BLOCKED | PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT | Samples Guild · Excititor Guild | Produce VEX observation/linkset fixtures demonstrating status conflicts and path relevance; include raw blobs. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Normalized PREP-SAMPLES-LNM-22-001 Task ID (removed trailing hyphen) for dependency tracking. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-18 | Drafted fixture plan (`samples/graph/fixtures-plan.md`) outlining contents, assumptions, and blockers for SAMPLES-GRAPH-24-003. | Samples | | 2025-11-18 | Kicked off SAMPLES-GRAPH-24-003 (overlay format + mock bundle sources); other tasks unchanged. | Samples | | 2025-11-18 | Normalised sprint to standard template; renamed from SPRINT_509_samples.md. | Ops/Docs | +| 2025-11-19 | Marked SAMPLES-GRAPH-24-003 BLOCKED pending Graph overlay format decision and mock SBOM cache availability. | Implementer | ## Decisions & Risks - Linkset fixtures blocked by Concelier/Excititor schema finalization; revisit once schemas freeze. diff --git a/docs/implplan/SPRINT_0510_0001_0001_airgap.md b/docs/implplan/SPRINT_0510_0001_0001_airgap.md index fa2bcebbf..dcd23e9bc 100644 --- a/docs/implplan/SPRINT_0510_0001_0001_airgap.md +++ b/docs/implplan/SPRINT_0510_0001_0001_airgap.md @@ -18,25 +18,35 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | AIRGAP-CTL-56-001 | BLOCKED | Controller project scaffold missing; need baseline service skeleton | AirGap Controller Guild | Implement `airgap_state` persistence, seal/unseal state machine, and Authority scope checks (`airgap:seal`, `airgap:status:read`). | -| 2 | AIRGAP-CTL-56-002 | BLOCKED | Blocked on 56-001 scaffolding | AirGap Controller Guild · DevOps Guild | Expose `GET /system/airgap/status`, `POST /system/airgap/seal`, integrate policy hash validation, and return staleness/time anchor placeholders. | -| 3 | AIRGAP-CTL-57-001 | BLOCKED | Blocked on 56-002 | AirGap Controller Guild | Add startup diagnostics that block application run when sealed flag set but egress policies missing; emit audit + telemetry. | -| 4 | AIRGAP-CTL-57-002 | BLOCKED | Blocked on 57-001 | AirGap Controller Guild · Observability Guild | Instrument seal/unseal events with trace/log fields and timeline emission (`airgap.sealed`, `airgap.unsealed`). | -| 5 | AIRGAP-CTL-58-001 | BLOCKED | Blocked on 57-002 | AirGap Controller Guild · AirGap Time Guild | Persist time anchor metadata, compute drift seconds, and surface staleness budgets in status API. | -| 6 | AIRGAP-IMP-56-001 | BLOCKED | Importer project scaffold missing; need trust-root inputs | AirGap Importer Guild | Implement DSSE verification helpers, TUF metadata parser (`root.json`, `snapshot.json`, `timestamp.json`), and Merkle root calculator. | -| 7 | AIRGAP-IMP-56-002 | BLOCKED | Blocked on 56-001 | AirGap Importer Guild · Security Guild | Introduce root rotation policy validation (dual approval) and signer trust store management. | -| 8 | AIRGAP-IMP-57-001 | BLOCKED | Blocked on 56-002 | AirGap Importer Guild | Write `bundle_catalog` and `bundle_items` repositories with RLS + deterministic migrations. | -| 9 | AIRGAP-IMP-57-002 | BLOCKED | Blocked on 57-001 | AirGap Importer Guild · DevOps Guild | Implement object-store loader storing artifacts under tenant/global mirror paths with Zstandard decompression and checksum validation. | -| 10 | AIRGAP-IMP-58-001 | BLOCKED | Blocked on 57-002 | AirGap Importer Guild · CLI Guild | Implement API (`POST /airgap/import`, `/airgap/verify`) and CLI commands wiring verification + catalog updates, including diff preview. | -| 11 | AIRGAP-IMP-58-002 | BLOCKED | Blocked on 58-001 | AirGap Importer Guild · Observability Guild | Emit timeline events (`airgap.import.started`, `airgap.import.completed`) with staleness metrics. | -| 12 | AIRGAP-TIME-57-001 | BLOCKED | Time component scaffold missing; need token format decision | AirGap Time Guild | Implement signed time token parser (Roughtime/RFC3161), verify signatures against bundle trust roots, and expose normalized anchor representation. | -| 13 | AIRGAP-TIME-57-002 | BLOCKED | Blocked on 57-001 | AirGap Time Guild · Observability Guild | Add telemetry counters for time anchors (`airgap_time_anchor_age_seconds`) and alerts for approaching thresholds. | -| 14 | AIRGAP-TIME-58-001 | BLOCKED | Blocked on 57-002 | AirGap Time Guild | Persist drift baseline, compute per-content staleness (advisories, VEX, policy) based on bundle metadata, and surface through controller status API. | -| 15 | AIRGAP-TIME-58-002 | BLOCKED | Blocked on 58-001 | AirGap Time Guild · Notifications Guild | Emit notifications and timeline events when staleness budgets breached or approaching. | +| P1 | PREP-AIRGAP-CTL-56-001-CONTROLLER-PROJECT-SCA | TODO | Due 2025-11-26 · Accountable: AirGap Controller Guild | AirGap Controller Guild | Controller project scaffold missing; need baseline service skeleton.

Document artefact/deliverable for AIRGAP-CTL-56-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-AIRGAP-CTL-56-002-BLOCKED-ON-56-001-SCAF | TODO | Due 2025-11-26 · Accountable: AirGap Controller Guild · DevOps Guild | AirGap Controller Guild · DevOps Guild | Blocked on 56-001 scaffolding.

Document artefact/deliverable for AIRGAP-CTL-56-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-AIRGAP-CTL-57-001-BLOCKED-ON-56-002 | TODO | Due 2025-11-26 · Accountable: AirGap Controller Guild | AirGap Controller Guild | Blocked on 56-002.

Document artefact/deliverable for AIRGAP-CTL-57-001, AIRGAP-IMP-57-001 and publish location so downstream tasks can proceed. | +| P4 | PREP-AIRGAP-CTL-57-002-BLOCKED-ON-57-001 | TODO | Due 2025-11-26 · Accountable: AirGap Controller Guild · Observability Guild | AirGap Controller Guild · Observability Guild | Blocked on 57-001.

Document artefact/deliverable for AIRGAP-CTL-57-002, AIRGAP-IMP-57-002, AIRGAP-TIME-57-002 and publish location so downstream tasks can proceed. | +| P5 | PREP-AIRGAP-CTL-58-001-BLOCKED-ON-57-002 | TODO | Due 2025-11-26 · Accountable: AirGap Controller Guild · AirGap Time Guild | AirGap Controller Guild · AirGap Time Guild | Blocked on 57-002.

Document artefact/deliverable for AIRGAP-CTL-58-001, AIRGAP-IMP-58-001, AIRGAP-TIME-58-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-AIRGAP-IMP-56-001-IMPORTER-PROJECT-SCAFF | TODO | Due 2025-11-26 · Accountable: AirGap Importer Guild | AirGap Importer Guild | Importer project scaffold missing; need trust-root inputs.

Document artefact/deliverable for AIRGAP-IMP-56-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-AIRGAP-IMP-56-002-BLOCKED-ON-56-001 | TODO | Due 2025-11-26 · Accountable: AirGap Importer Guild · Security Guild | AirGap Importer Guild · Security Guild | Blocked on 56-001.

Document artefact/deliverable for AIRGAP-IMP-56-002 and publish location so downstream tasks can proceed. | +| P8 | PREP-AIRGAP-IMP-58-002-BLOCKED-ON-58-001 | TODO | Due 2025-11-26 · Accountable: AirGap Importer Guild · Observability Guild | AirGap Importer Guild · Observability Guild | Blocked on 58-001.

Document artefact/deliverable for AIRGAP-IMP-58-002, AIRGAP-TIME-58-002 and publish location so downstream tasks can proceed. | +| P9 | PREP-AIRGAP-TIME-57-001-TIME-COMPONENT-SCAFFO | TODO | Due 2025-11-26 · Accountable: AirGap Time Guild | AirGap Time Guild | Time component scaffold missing; need token format decision.

Document artefact/deliverable for AIRGAP-TIME-57-001 and publish location so downstream tasks can proceed. | +| 1 | AIRGAP-CTL-56-001 | BLOCKED | PREP-AIRGAP-CTL-56-001-CONTROLLER-PROJECT-SCA | AirGap Controller Guild | Implement `airgap_state` persistence, seal/unseal state machine, and Authority scope checks (`airgap:seal`, `airgap:status:read`). | +| 2 | AIRGAP-CTL-56-002 | BLOCKED | PREP-AIRGAP-CTL-56-002-BLOCKED-ON-56-001-SCAF | AirGap Controller Guild · DevOps Guild | Expose `GET /system/airgap/status`, `POST /system/airgap/seal`, integrate policy hash validation, and return staleness/time anchor placeholders. | +| 3 | AIRGAP-CTL-57-001 | BLOCKED | PREP-AIRGAP-CTL-57-001-BLOCKED-ON-56-002 | AirGap Controller Guild | Add startup diagnostics that block application run when sealed flag set but egress policies missing; emit audit + telemetry. | +| 4 | AIRGAP-CTL-57-002 | BLOCKED | PREP-AIRGAP-CTL-57-002-BLOCKED-ON-57-001 | AirGap Controller Guild · Observability Guild | Instrument seal/unseal events with trace/log fields and timeline emission (`airgap.sealed`, `airgap.unsealed`). | +| 5 | AIRGAP-CTL-58-001 | BLOCKED | PREP-AIRGAP-CTL-58-001-BLOCKED-ON-57-002 | AirGap Controller Guild · AirGap Time Guild | Persist time anchor metadata, compute drift seconds, and surface staleness budgets in status API. | +| 6 | AIRGAP-IMP-56-001 | BLOCKED | PREP-AIRGAP-IMP-56-001-IMPORTER-PROJECT-SCAFF | AirGap Importer Guild | Implement DSSE verification helpers, TUF metadata parser (`root.json`, `snapshot.json`, `timestamp.json`), and Merkle root calculator. | +| 7 | AIRGAP-IMP-56-002 | BLOCKED | PREP-AIRGAP-IMP-56-002-BLOCKED-ON-56-001 | AirGap Importer Guild · Security Guild | Introduce root rotation policy validation (dual approval) and signer trust store management. | +| 8 | AIRGAP-IMP-57-001 | BLOCKED | PREP-AIRGAP-CTL-57-001-BLOCKED-ON-56-002 | AirGap Importer Guild | Write `bundle_catalog` and `bundle_items` repositories with RLS + deterministic migrations. | +| 9 | AIRGAP-IMP-57-002 | BLOCKED | PREP-AIRGAP-CTL-57-002-BLOCKED-ON-57-001 | AirGap Importer Guild · DevOps Guild | Implement object-store loader storing artifacts under tenant/global mirror paths with Zstandard decompression and checksum validation. | +| 10 | AIRGAP-IMP-58-001 | BLOCKED | PREP-AIRGAP-CTL-58-001-BLOCKED-ON-57-002 | AirGap Importer Guild · CLI Guild | Implement API (`POST /airgap/import`, `/airgap/verify`) and CLI commands wiring verification + catalog updates, including diff preview. | +| 11 | AIRGAP-IMP-58-002 | BLOCKED | PREP-AIRGAP-IMP-58-002-BLOCKED-ON-58-001 | AirGap Importer Guild · Observability Guild | Emit timeline events (`airgap.import.started`, `airgap.import.completed`) with staleness metrics. | +| 12 | AIRGAP-TIME-57-001 | BLOCKED | PREP-AIRGAP-TIME-57-001-TIME-COMPONENT-SCAFFO | AirGap Time Guild | Implement signed time token parser (Roughtime/RFC3161), verify signatures against bundle trust roots, and expose normalized anchor representation. | +| 13 | AIRGAP-TIME-57-002 | BLOCKED | PREP-AIRGAP-CTL-57-002-BLOCKED-ON-57-001 | AirGap Time Guild · Observability Guild | Add telemetry counters for time anchors (`airgap_time_anchor_age_seconds`) and alerts for approaching thresholds. | +| 14 | AIRGAP-TIME-58-001 | BLOCKED | PREP-AIRGAP-CTL-58-001-BLOCKED-ON-57-002 | AirGap Time Guild | Persist drift baseline, compute per-content staleness (advisories, VEX, policy) based on bundle metadata, and surface through controller status API. | +| 15 | AIRGAP-TIME-58-002 | BLOCKED | PREP-AIRGAP-IMP-58-002-BLOCKED-ON-58-001 | AirGap Time Guild · Notifications Guild | Emit notifications and timeline events when staleness budgets breached or approaching. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-18 | Marked all AIRGAP controller/importer/time tasks BLOCKED: no project scaffolds exist under src/AirGap; need baseline service skeletons and token format decisions before implementation. | Ops/Docs | | 2025-11-18 | Normalised sprint to standard template; renamed from SPRINT_510_airgap.md. | Ops/Docs | @@ -48,4 +58,4 @@ ## Next Checkpoints - 2025-11-20 · Confirm time token format and trust root delivery shape. Owner: AirGap Time Guild. - 2025-11-22 · Align on seal/unseal Authority scopes and baseline policy hash inputs. Owner: AirGap Controller Guild. -- 2025-11-25 · Verify release pipeline exposes TUF metadata paths for importer (AIRGAP-IMP-56-001). Owner: AirGap Importer Guild. +- 2025-11-25 · Verify release pipeline exposes TUF metadata paths for importer (AIRGAP-IMP-56-001). Owner: AirGap Importer Guild. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0512_0001_0001_bench.md b/docs/implplan/SPRINT_0512_0001_0001_bench.md index 23bfd3062..f763e8b1a 100644 --- a/docs/implplan/SPRINT_0512_0001_0001_bench.md +++ b/docs/implplan/SPRINT_0512_0001_0001_bench.md @@ -19,17 +19,25 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | -| 1 | BENCH-GRAPH-21-001 | BLOCKED | Need graph bench harness scaffolding (50k/100k nodes) | Bench Guild · Graph Platform Guild | Build graph viewport/path benchmark harness (50k/100k nodes) measuring Graph API/Indexer latency, memory, and tile cache hit rates. | -| 2 | BENCH-GRAPH-21-002 | BLOCKED | Blocked on 21-001 harness | Bench Guild · UI Guild | Add headless UI load benchmark (Playwright) for graph canvas interactions to track render times and FPS budgets. | +| P1 | PREP-BENCH-GRAPH-21-001-NEED-GRAPH-BENCH-HARN | TODO | Due 2025-11-26 · Accountable: Bench Guild · Graph Platform Guild | Bench Guild · Graph Platform Guild | Need graph bench harness scaffolding (50k/100k nodes).

Document artefact/deliverable for BENCH-GRAPH-21-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-BENCH-GRAPH-21-002-BLOCKED-ON-21-001-HAR | TODO | Due 2025-11-26 · Accountable: Bench Guild · UI Guild | Bench Guild · UI Guild | Blocked on 21-001 harness.

Document artefact/deliverable for BENCH-GRAPH-21-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-BENCH-IMPACT-16-001-IMPACT-INDEX-DATASET | TODO | Due 2025-11-26 · Accountable: Bench Guild · Scheduler Team | Bench Guild · Scheduler Team | Impact index dataset/replay inputs not provided.

Document artefact/deliverable for BENCH-IMPACT-16-001 and publish location so downstream tasks can proceed. | +| P4 | PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE | TODO | Due 2025-11-26 · Accountable: Bench Guild · Policy Guild · Scheduler Guild | Bench Guild · Policy Guild · Scheduler Guild | Policy delta sample inputs missing.

Document artefact/deliverable for BENCH-POLICY-20-002 and publish location so downstream tasks can proceed. | +| P5 | PREP-BENCH-SIG-26-001-REACHABILITY-SCHEMA-FIX | TODO | Due 2025-11-26 · Accountable: Bench Guild · Signals Guild | Bench Guild · Signals Guild | Reachability schema/fixtures pending Sprint 0400/0401.

Document artefact/deliverable for BENCH-SIG-26-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-BENCH-SIG-26-002-BLOCKED-ON-26-001-OUTPU | TODO | Due 2025-11-26 · Accountable: Bench Guild · Policy Guild | Bench Guild · Policy Guild | Blocked on 26-001 outputs.

Document artefact/deliverable for BENCH-SIG-26-002 and publish location so downstream tasks can proceed. | +| 1 | BENCH-GRAPH-21-001 | BLOCKED | PREP-BENCH-GRAPH-21-001-NEED-GRAPH-BENCH-HARN | Bench Guild · Graph Platform Guild | Build graph viewport/path benchmark harness (50k/100k nodes) measuring Graph API/Indexer latency, memory, and tile cache hit rates. | +| 2 | BENCH-GRAPH-21-002 | BLOCKED | PREP-BENCH-GRAPH-21-002-BLOCKED-ON-21-001-HAR | Bench Guild · UI Guild | Add headless UI load benchmark (Playwright) for graph canvas interactions to track render times and FPS budgets. | | 3 | BENCH-GRAPH-24-002 | BLOCKED | Waiting for 50k/100k graph fixture (SAMPLES-GRAPH-24-003) | Bench Guild · UI Guild | Implement UI interaction benchmarks (filter/zoom/table operations) citing p95 latency; integrate with perf dashboards. | -| 4 | BENCH-IMPACT-16-001 | BLOCKED | Impact index dataset/replay inputs not provided | Bench Guild · Scheduler Team | ImpactIndex throughput bench (resolve 10k productKeys) + RAM profile. | -| 5 | BENCH-POLICY-20-002 | BLOCKED | Policy delta sample inputs missing | Bench Guild · Policy Guild · Scheduler Guild | Add incremental run benchmark measuring delta evaluation vs full; capture SLA compliance. | -| 6 | BENCH-SIG-26-001 | BLOCKED | Reachability schema/fixtures pending Sprint 0400/0401 | Bench Guild · Signals Guild | Develop benchmark for reachability scoring pipeline (facts/sec, latency, memory) using synthetic callgraphs/runtime batches. | -| 7 | BENCH-SIG-26-002 | BLOCKED | Blocked on 26-001 outputs | Bench Guild · Policy Guild | Measure policy evaluation overhead with reachability cache hot/cold; ensure ≤8 ms p95 added latency. | +| 4 | BENCH-IMPACT-16-001 | BLOCKED | PREP-BENCH-IMPACT-16-001-IMPACT-INDEX-DATASET | Bench Guild · Scheduler Team | ImpactIndex throughput bench (resolve 10k productKeys) + RAM profile. | +| 5 | BENCH-POLICY-20-002 | BLOCKED | PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE | Bench Guild · Policy Guild · Scheduler Guild | Add incremental run benchmark measuring delta evaluation vs full; capture SLA compliance. | +| 6 | BENCH-SIG-26-001 | BLOCKED | PREP-BENCH-SIG-26-001-REACHABILITY-SCHEMA-FIX | Bench Guild · Signals Guild | Develop benchmark for reachability scoring pipeline (facts/sec, latency, memory) using synthetic callgraphs/runtime batches. | +| 7 | BENCH-SIG-26-002 | BLOCKED | PREP-BENCH-SIG-26-002-BLOCKED-ON-26-001-OUTPU | Bench Guild · Policy Guild | Measure policy evaluation overhead with reachability cache hot/cold; ensure ≤8 ms p95 added latency. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Trimmed trailing hyphen from PREP-BENCH-POLICY-20-002 Task ID to keep BENCH-POLICY-20-002 blocker resolvable. | Project Mgmt | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-18 | Marked BENCH-GRAPH-24-002, BENCH-IMPACT-16-001, BENCH-POLICY-20-002, BENCH-SIG-26-001/002 as BLOCKED pending fixtures/datasets and reachability schema. | Bench | | 2025-11-18 | Normalised sprint to standard template; renamed from SPRINT_512_bench.md. | Ops/Docs | @@ -41,4 +49,4 @@ ## Next Checkpoints - 2025-11-22 · Confirm availability of graph fixtures for BENCH-GRAPH-21-001/002/24-002. Owner: Bench Guild. - 2025-11-24 · Reachability schema alignment outcome to unblock BENCH-SIG-26-001. Owner: Signals Guild. -- 2025-11-26 · Decide impact index dataset for BENCH-IMPACT-16-001. Owner: Scheduler Team. +- 2025-11-26 · Decide impact index dataset for BENCH-IMPACT-16-001. Owner: Scheduler Team. \ No newline at end of file diff --git a/docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md b/docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md index dd546bfcc..5c2859d32 100644 --- a/docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md +++ b/docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md @@ -17,6 +17,7 @@ ## Delivery Tracker | # | Task ID | Status | Key dependency / next step | Owners | Task Definition | | --- | --- | --- | --- | --- | --- | +| P1 | PREP-AUTH-CRYPTO-90-001-NEEDS-AUTHORITY-PROVI | TODO | Due 2025-11-26 · Accountable: Authority Core & Security Guild | Authority Core & Security Guild | Needs Authority provider/key format spec & JWKS export requirements.

Document artefact/deliverable for AUTH-CRYPTO-90-001 and publish location so downstream tasks can proceed. | | 1 | SEC-CRYPTO-90-017 | TODO | Fork present; integrate into solution | Security Guild | Vendor `third_party/forks/AlexMAS.GostCryptography` into the solution build (solution filters, Directory.Build props, CI) so the library compiles with the repo and publishes artifacts. | | 2 | SEC-CRYPTO-90-018 | TODO | After 90-017 | Security & Docs Guilds | Update developer/RootPack documentation to describe the fork, sync steps, and licensing. | | 3 | SEC-CRYPTO-90-019 | TODO | After 90-017 | Security Guild | Patch the fork to drop vulnerable `System.Security.Cryptography.{Pkcs,Xml}` 6.0.0 deps; retarget .NET 8+, rerun tests. | @@ -26,7 +27,7 @@ | 7 | SEC-CRYPTO-90-013 | TODO | After 90-021 | Security Guild | Add Magma/Kuznyechik symmetric support via provider registry. | | 8 | SEC-CRYPTO-90-014 | TODO | After Authority contract confirmed | Security Guild + Service Guilds | Update runtime hosts (Authority, Scanner WebService/Worker, Concelier, etc.) to register RU providers and expose config toggles. | | 9 | SEC-CRYPTO-90-015 | TODO | After 90-012/021 | Security & Docs Guild | Refresh RootPack/validation documentation. | -| 10 | AUTH-CRYPTO-90-001 | BLOCKED | Needs Authority provider/key format spec & JWKS export requirements | Authority Core & Security Guild | Sovereign signing provider contract for Authority; refactor loaders once contract is published. | +| 10 | AUTH-CRYPTO-90-001 | BLOCKED | PREP-AUTH-CRYPTO-90-001-NEEDS-AUTHORITY-PROVI | Authority Core & Security Guild | Sovereign signing provider contract for Authority; refactor loaders once contract is published. | | 11 | SCANNER-CRYPTO-90-001 | TODO | Needs registry wiring | Scanner WebService Guild · Security Guild | Route hashing/signing flows through `ICryptoProviderRegistry`. | | 12 | SCANNER-WORKER-CRYPTO-90-001 | TODO | After 11 | Scanner Worker Guild · Security Guild | Wire Scanner Worker/BuildX analyzers to registry/hash abstractions. | | 13 | SCANNER-CRYPTO-90-002 | TODO | PQ profile | Scanner WebService Guild · Security Guild | Enable PQ-friendly DSSE (Dilithium/Falcon) via provider options. | @@ -36,6 +37,7 @@ ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-18 | Normalised sprint to standard template; renamed from SPRINT_514_sovereign_crypto_enablement.md. | Security Docs | | 2025-11-18 | Downloaded MongoDB 4.4.4 binaries into `local-nuget/mongo2go/4.1.0/tools/mongodb-linux-4.4.4-database-tools-100.3.1/community-server/mongodb-linux-x86_64-ubuntu2004-4.4.4/bin/mongod`; reran `dotnet vstest …AdvisoryChunksEndpoint_ReturnsParagraphAnchors` but Mongo2Go still cannot connect (timeout/connection refused to 127.0.0.1). Concelier AOC tasks remain BLOCKED pending stable Mongo2Go startup. | Concelier WebService | | 2025-11-18 | Targeted `dotnet vstest ...StellaOps.Concelier.WebService.Tests.dll --TestCaseFilter:AdvisoryChunksEndpoint_ReturnsParagraphAnchors` failed: Mongo2Go cannot start (mongod binaries not found; connection refused 127.0.0.1:35961). Concelier AOC tasks remain BLOCKED pending usable Mongo2Go binary path. | Concelier WebService | @@ -48,4 +50,4 @@ ## Next Checkpoints - 2025-11-19 · Draft Authority provider/JWKS contract to unblock AUTH-CRYPTO-90-001. Owner: Authority Core. - 2025-11-21 · Decide CI gating approach for CryptoPro/PKCS#11 tests. Owner: Security Guild. -- 2025-11-24 · Fork patch status (SEC-CRYPTO-90-019) and plugin rewire plan (SEC-CRYPTO-90-020). Owner: Security Guild. +- 2025-11-24 · Fork patch status (SEC-CRYPTO-90-019) and plugin rewire plan (SEC-CRYPTO-90-020). Owner: Security Guild. \ No newline at end of file diff --git a/docs/implplan/SPRINT_110_ingestion_evidence.md b/docs/implplan/SPRINT_110_ingestion_evidence.md index 84122f1a5..30ee68001 100644 --- a/docs/implplan/SPRINT_110_ingestion_evidence.md +++ b/docs/implplan/SPRINT_110_ingestion_evidence.md @@ -21,32 +21,38 @@ ## Task Board | Wave | Task ID | Status | Owner(s) | Dependencies | Notes | | --- | --- | --- | --- | --- | --- | +| 110.B Concelier | PREP-LNM-SCHEMA-APPROVAL | TODO | Due 2025-11-21 · Accountable: —; Concelier Core · Cartographer Guild · SBOM Service Guild | — | Approve Link-Not-Merge schema plus fixtures (`CONCELIER-GRAPH-21-001/002`, `CARTO-GRAPH-21-002`) and publish canonical JSON samples + precedence rules for consuming modules.

Archive decision + artefacts under `docs/modules/concelier/link-not-merge-schema.md` so downstream Concelier/Excititor/Policy tasks can bind to the frozen payload shape. | +| 110.B Concelier | PREP-EVIDENCE-LOCKER-CONTRACT | TODO | Due 2025-11-21 · Accountable: —; Evidence Locker Guild · Concelier Core Guild | — | Freeze the Evidence Locker attestation scope + ingest contract (bundle predicates, transparency metadata, verification plan) and record DOI/location for Evidence Bundle v1.

Publish the signed decision in `docs/modules/evidence-locker/attestation-contract.md` and note required claim set plus validation fixtures. | +| 110.B Concelier | PREP-FEEDCONN-ICS-KISA-PLAN | TODO | Due 2025-11-21 · Accountable: —; Concelier Feed Owners · Product Advisory Guild | — | Provide remediation/refresh schedule and schema notes for ICSCISA/KISA feeds, covering provenance gaps and upcoming advisory drops.

Store the runbook in `docs/modules/concelier/feeds/icscisa-kisa.md` with owners and next review date so connector work can proceed deterministically. | +| 110.C Excititor | PREP-EXCITITOR-ATTESTATION-PLAN | TODO | Due 2025-11-21 · Accountable: —; Excititor Guild · Evidence Locker Guild | — | Align Excititor chunk/attestation plans with Evidence Locker scope: spell out ingestion contract, chunk schema, and DSSE bundling rules.

Publish the plan in `docs/modules/excititor/attestation-plan.md` and include sample payloads for `/vex/evidence/chunks` + attestation APIs. | +| 110.D Mirror | PREP-MIRROR-STAFFING | TODO | Due 2025-11-21 · Accountable: —; Mirror Creator Guild · Exporter Guild · AirGap Time Guild | — | Assign owner(s) for MIRROR-CRT-56-001, confirm DSSE/TUF milestone schedule, and record staffing commitments for follow-on CRT tasks.

Document the staffing decision and milestone plan in `docs/modules/mirror/assembler.md` so downstream automation (Export Center, AirGap Time, CLI) can execute. | | 110.A Advisory AI | DOCS-AIAI-31-004 | DOING | Docs Guild · Console Guild | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-001/003 | Guardrail console doc drafted; screenshots + SBOM evidence pending. | | 110.A Advisory AI | AIAI-31-009 | DONE (2025-11-12) | Advisory AI Guild | — | Regression suite + `AdvisoryAI:Guardrails` config landed with perf budgets. | -| 110.A Advisory AI | AIAI-31-008 | BLOCKED | Advisory AI Guild | AIAI-31-006; AIAI-31-007 | Blocked pending policy knob deliverables (AIAI-31-006/007). | +| 110.A Advisory AI | AIAI-31-008 | TODO | Advisory AI Guild | AIAI-31-006 (DONE 2025-11-04); AIAI-31-007 (DONE 2025-11-06) | Policy knob work landed; proceed with packaging and deployment steps. | | 110.A Advisory AI | SBOM-AIAI-31-003 | BLOCKED | SBOM Service Guild | SBOM-AIAI-31-001; CLI-VULN-29-001; CLI-VEX-30-001 | Needs SBOM delta kit + CLI deliverables before validation can proceed. | | 110.A Advisory AI | DOCS-AIAI-31-005/006/008/009 | BLOCKED | Docs Guild | DOCS-AIAI-31-004; CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001; DEVOPS-AIAI-31-001 | CLI/policy/ops docs paused pending upstream artefacts. | | 110.B Concelier | CONCELIER-AIAI-31-002 | BLOCKED | Concelier Core · Concelier WebService Guilds | CONCELIER-GRAPH-21-001/002; CARTO-GRAPH-21-002 | Blocked: Link-Not-Merge schema still not approved; cannot finalize structured field/caching. | | 110.B Concelier | CONCELIER-AIAI-31-003 | DONE (2025-11-12) | Concelier Observability Guild | — | Telemetry counters/histograms live for Advisory AI dashboards. | -| 110.B Concelier | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | Concelier Core · AirGap Guilds | Link-Not-Merge schema; Evidence Locker attestation contract | Blocked until schema approval + attestation scope sign-off. | -| 110.B Concelier | CONCELIER-CONSOLE-23-001..003 | BLOCKED | Concelier Console Guild | Link-Not-Merge schema | Blocked pending Link-Not-Merge schema approval. | -| 110.B Concelier | CONCELIER-ATTEST-73-001/002 | BLOCKED | Concelier Core · Evidence Locker Guild | CONCELIER-AIAI-31-002; Evidence Locker contract | Blocked until structured caching lands and Evidence Locker contract finalises. | -| 110.B Concelier | FEEDCONN-ICSCISA-02-012 / FEEDCONN-KISA-02-008 | BLOCKED | Concelier Feed Owners | Feed owner remediation plan | Overdue provenance refreshes require schedule from feed owners. | +| 110.B Concelier | CONCELIER-AIRGAP-56-001..58-001 | BLOCKED | Concelier Core · AirGap Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until schema approval + attestation scope sign-off. | +| 110.B Concelier | CONCELIER-CONSOLE-23-001..003 | BLOCKED | Concelier Console Guild | PREP-LNM-SCHEMA-APPROVAL | Blocked pending Link-Not-Merge schema approval. | +| 110.B Concelier | CONCELIER-ATTEST-73-001/002 | BLOCKED | Concelier Core · Evidence Locker Guild | CONCELIER-AIAI-31-002; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until structured caching lands and Evidence Locker contract finalises. | +| 110.B Concelier | FEEDCONN-ICSCISA-02-012 / FEEDCONN-KISA-02-008 | BLOCKED | Concelier Feed Owners | PREP-FEEDCONN-ICS-KISA-PLAN | Overdue provenance refreshes require schedule from feed owners. | | 110.C Excititor | EXCITITOR-AIAI-31-001 | DONE (2025-11-09) | Excititor Web/Core Guilds | — | Normalised VEX justification projections shipped. | -| 110.C Excititor | EXCITITOR-AIAI-31-002 | BLOCKED | Excititor Web/Core Guilds | Link-Not-Merge schema; Evidence Locker contract | Blocked until schema + ingest contract approved. | +| 110.C Excititor | EXCITITOR-AIAI-31-002 | BLOCKED | Excititor Web/Core Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked until schema + ingest contract approved. | | 110.C Excititor | EXCITITOR-AIAI-31-003 | BLOCKED | Excititor Observability Guild | EXCITITOR-AIAI-31-002 | Blocked behind EXCITITOR-AIAI-31-002. | | 110.C Excititor | EXCITITOR-AIAI-31-004 | BLOCKED | Docs Guild · Excititor Guild | EXCITITOR-AIAI-31-002 | Blocked until chunk API finalized. | -| 110.C Excititor | EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 | BLOCKED | Excititor Guild · Evidence Locker Guild | EXCITITOR-AIAI-31-002; Evidence Locker contract | Blocked pending chunk API + Evidence Locker attestation scope. | -| 110.C Excititor | EXCITITOR-AIRGAP-56/57/58 · EXCITITOR-CONN-TRUST-01-001 | BLOCKED | Excititor Guild · AirGap Guilds | Link-Not-Merge schema; attestation plan | Blocked until schema + attestation readiness. | -| 110.D Mirror | MIRROR-CRT-56-001 | BLOCKED | Mirror Creator Guild | Staffing decision | Blocked: no owner assigned; kickoff slipped past 2025-11-15. | +| 110.C Excititor | EXCITITOR-ATTEST-01-003 / 73-001 / 73-002 | BLOCKED | Excititor Guild · Evidence Locker Guild | EXCITITOR-AIAI-31-002; PREP-EVIDENCE-LOCKER-CONTRACT | Blocked pending chunk API + Evidence Locker attestation scope. | +| 110.C Excititor | EXCITITOR-AIRGAP-56/57/58 · EXCITITOR-CONN-TRUST-01-001 | BLOCKED | Excititor Guild · AirGap Guilds | PREP-LNM-SCHEMA-APPROVAL; PREP-EXCITITOR-ATTESTATION-PLAN | Blocked until schema + attestation readiness. | +| 110.D Mirror | MIRROR-CRT-56-001 | BLOCKED | Mirror Creator Guild | PREP-MIRROR-STAFFING | Blocked: no owner assigned; kickoff slipped past 2025-11-15. | | 110.D Mirror | MIRROR-CRT-56-002 | BLOCKED | Mirror Creator · Security Guilds | MIRROR-CRT-56-001; PROV-OBS-53-001 | Blocked until MIRROR-CRT-56-001 staffed. | | 110.D Mirror | MIRROR-CRT-57-001/002 | BLOCKED | Mirror Creator Guild · AirGap Time Guild | MIRROR-CRT-56-001; AIRGAP-TIME-57-001 | Blocked; upstream staffing unresolved. | | 110.D Mirror | MIRROR-CRT-58-001/002 | BLOCKED | Mirror Creator Guild · CLI Guild · Exporter Guild | MIRROR-CRT-56-001; EXPORT-OBS-54-001; CLI-AIRGAP-56-001 | Blocked until assembler staffed and upstream contracts agreed. | -| 110.D Mirror | EXPORT-OBS-51-001 / 54-001 · AIRGAP-TIME-57-001 · CLI-AIRGAP-56-001 · PROV-OBS-53-001 | BLOCKED | Exporter Guild · AirGap Time Guild · CLI Guild | MIRROR-CRT-56-001 staffing | Blocked pending MIRROR-CRT-56-001 ownership. | +| 110.D Mirror | EXPORT-OBS-51-001 / 54-001 · AIRGAP-TIME-57-001 · CLI-AIRGAP-56-001 · PROV-OBS-53-001 | BLOCKED | Exporter Guild · AirGap Time Guild · CLI Guild | PREP-MIRROR-STAFFING | Blocked pending MIRROR-CRT-56-001 ownership. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-13 | Refreshed wave tracker, decisions, and contingency plan ahead of 14–15 Nov checkpoints; outstanding asks: SBOM/CLI/Policy/DevOps ETAs, Link-Not-Merge approval, Mirror staffing. | Sprint 110 leads | | 2025-11-09 | Captured initial wave scope, interlocks, and risks covering SBOM/CLI/Policy/DevOps artefacts, Link-Not-Merge schemas, Excititor justification backlog, and Mirror assembler commitments. | Sprint 110 leads | | 2025-11-16 | Updated task board: marked Advisory AI packaging, Concelier air-gap/console/attestation tracks, Excititor chunk/attestation/air-gap tracks, and all Mirror tracks as BLOCKED pending schema approvals, Evidence Locker contract, and Mirror staffing decisions. | Implementer | @@ -80,4 +86,4 @@ | 2025-11-15 | Mirror evidence kickoff | Assign MIRROR-CRT-56-001 owner, confirm staffing, outline DSSE/TUF + OCI milestones. | 110.D | Mirror Creator · Exporter · AirGap Time · Security guilds | ## Appendix -- Detailed coordination artefacts, contingency playbook, and historical notes previously held in this sprint now live at `docs/implplan/archived/SPRINT_110_ingestion_evidence_2025-11-13.md`. +- Detailed coordination artefacts, contingency playbook, and historical notes previously held in this sprint now live at `docs/implplan/archived/SPRINT_110_ingestion_evidence_2025-11-13.md`. \ No newline at end of file diff --git a/docs/implplan/SPRINT_123_policy_reasoning.md b/docs/implplan/SPRINT_123_policy_reasoning.md index ff0cf3f19..ccdb4daa8 100644 --- a/docs/implplan/SPRINT_123_policy_reasoning.md +++ b/docs/implplan/SPRINT_123_policy_reasoning.md @@ -10,25 +10,40 @@ Focus: Policy & Reasoning focus on Policy (phase I). | # | Task ID & handle | State | Key dependency / next step | Owners | | --- | --- | --- | --- | --- | -| 1 | EXPORT-CONSOLE-23-001 | BLOCKED | Missing export bundle contract/API surface and scheduler job spec for Console; requires agreed schema and job wiring | Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | -| 2 | POLICY-AIRGAP-56-001 | BLOCKED | Mirror bundle schema for policy packs not published; need bundle_id/provenance fields and sealed-mode rules | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 3 | POLICY-AIRGAP-56-002 | BLOCKED | Depends on 56-001 bundle import schema and DSSE signing profile | Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine | -| 4 | POLICY-AIRGAP-57-001 | BLOCKED | Requires sealed-mode contract (egress rules, error codes) after 56-002 | Policy Guild, AirGap Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 5 | POLICY-AIRGAP-57-002 | BLOCKED | Needs staleness/fallback data contract from 57-001 | Policy Guild, AirGap Time Guild / src/Policy/StellaOps.Policy.Engine | -| 6 | POLICY-AIRGAP-58-001 | BLOCKED | Notification schema and staleness signals pending from 57-002 | Policy Guild, Notifications Guild / src/Policy/StellaOps.Policy.Engine | -| 7 | POLICY-AOC-19-001 | BLOCKED | Needs agreed linting targets (which ingestion projects, which helpers) and CI wiring; no analyzer/lint spec available | Policy Guild / src/Policy/__Libraries/StellaOps.Policy | -| 8 | POLICY-AOC-19-002 | BLOCKED | Depends on 19-001 lint implementation and authority contract for `effective:write` gate | Policy Guild, Platform Security / src/Policy/__Libraries/StellaOps.Policy | -| 9 | POLICY-AOC-19-003 | BLOCKED | Requires decisioned normalized-field removal contract after 19-002; fixtures not provided | Policy Guild / src/Policy/__Libraries/StellaOps.Policy | -| 10 | POLICY-AOC-19-004 | BLOCKED | Dependent on 19-003 data shape and determinism fixtures | Policy Guild, QA Guild / src/Policy/__Libraries/StellaOps.Policy | -| 11 | POLICY-ATTEST-73-001 | BLOCKED | VerificationPolicy schema/persistence contract missing; needs Attestor alignment | Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | -| 12 | POLICY-ATTEST-73-002 | BLOCKED | Depends on 73-001 editor DTOs and validation schema | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 13 | POLICY-ATTEST-74-001 | BLOCKED | Requires 73-002 and Attestor pipeline contract | Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | -| 14 | POLICY-ATTEST-74-002 | BLOCKED | Needs 74-001 surface in Console verification reports contract | Policy Guild, Console Guild / src/Policy/StellaOps.Policy.Engine | +| P1 | PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN | TODO | Due 2025-11-22 · Accountable: Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | Missing export bundle contract/API surface and scheduler job spec for Console; requires agreed schema and job wiring.

Document artefact/deliverable for EXPORT-CONSOLE-23-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Mirror bundle schema for policy packs not published; need bundle_id/provenance fields and sealed-mode rules.

Document artefact/deliverable for POLICY-AIRGAP-56-001 and publish location so downstream tasks can proceed. | +| P3 | PREP-POLICY-AIRGAP-56-002-DEPENDS-ON-56-001-B | TODO | Due 2025-11-22 · Accountable: Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine | Depends on 56-001 bundle import schema and DSSE signing profile.

Document artefact/deliverable for POLICY-AIRGAP-56-002 and publish location so downstream tasks can proceed. | +| P4 | PREP-POLICY-AIRGAP-57-001-REQUIRES-SEALED-MOD | TODO | Due 2025-11-22 · Accountable: Policy Guild, AirGap Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, AirGap Policy Guild / src/Policy/StellaOps.Policy.Engine | Requires sealed-mode contract (egress rules, error codes) after 56-002.

Document artefact/deliverable for POLICY-AIRGAP-57-001 and publish location so downstream tasks can proceed. | +| P5 | PREP-POLICY-AIRGAP-57-002-NEEDS-STALENESS-FAL | TODO | Due 2025-11-22 · Accountable: Policy Guild, AirGap Time Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, AirGap Time Guild / src/Policy/StellaOps.Policy.Engine | Needs staleness/fallback data contract from 57-001.

Document artefact/deliverable for POLICY-AIRGAP-57-002 and publish location so downstream tasks can proceed. | +| P6 | PREP-POLICY-AIRGAP-58-001-NOTIFICATION-SCHEMA | TODO | Due 2025-11-22 · Accountable: Policy Guild, Notifications Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Notifications Guild / src/Policy/StellaOps.Policy.Engine | Notification schema and staleness signals pending from 57-002.

Document artefact/deliverable for POLICY-AIRGAP-58-001 and publish location so downstream tasks can proceed. | +| P7 | PREP-POLICY-AOC-19-001-NEEDS-AGREED-LINTING-T | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/__Libraries/StellaOps.Policy | Policy Guild / src/Policy/__Libraries/StellaOps.Policy | Needs agreed linting targets (which ingestion projects, which helpers) and CI wiring; no analyzer/lint spec available.

Document artefact/deliverable for POLICY-AOC-19-001 and publish location so downstream tasks can proceed. | +| P8 | PREP-POLICY-AOC-19-002-DEPENDS-ON-19-001-LINT | TODO | Due 2025-11-22 · Accountable: Policy Guild, Platform Security / src/Policy/__Libraries/StellaOps.Policy | Policy Guild, Platform Security / src/Policy/__Libraries/StellaOps.Policy | Depends on 19-001 lint implementation and authority contract for `effective:write` gate.

Document artefact/deliverable for POLICY-AOC-19-002 and publish location so downstream tasks can proceed. | +| P9 | PREP-POLICY-AOC-19-003-REQUIRES-DECISIONED-NO | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/__Libraries/StellaOps.Policy | Policy Guild / src/Policy/__Libraries/StellaOps.Policy | Requires decisioned normalized-field removal contract after 19-002; fixtures not provided.

Document artefact/deliverable for POLICY-AOC-19-003 and publish location so downstream tasks can proceed. | +| P10 | PREP-POLICY-AOC-19-004-DEPENDENT-ON-19-003-DA | TODO | Due 2025-11-22 · Accountable: Policy Guild, QA Guild / src/Policy/__Libraries/StellaOps.Policy | Policy Guild, QA Guild / src/Policy/__Libraries/StellaOps.Policy | Dependent on 19-003 data shape and determinism fixtures.

Document artefact/deliverable for POLICY-AOC-19-004 and publish location so downstream tasks can proceed. | +| P11 | PREP-POLICY-ATTEST-73-001-VERIFICATIONPOLICY- | TODO | Due 2025-11-22 · Accountable: Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | VerificationPolicy schema/persistence contract missing; needs Attestor alignment.

Document artefact/deliverable for POLICY-ATTEST-73-001 and publish location so downstream tasks can proceed. | +| P12 | PREP-POLICY-ATTEST-73-002-DEPENDS-ON-73-001-E | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Depends on 73-001 editor DTOs and validation schema.

Document artefact/deliverable for POLICY-ATTEST-73-002 and publish location so downstream tasks can proceed. | +| P13 | PREP-POLICY-ATTEST-74-001-REQUIRES-73-002-AND | TODO | Due 2025-11-22 · Accountable: Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | Requires 73-002 and Attestor pipeline contract.

Document artefact/deliverable for POLICY-ATTEST-74-001 and publish location so downstream tasks can proceed. | +| P14 | PREP-POLICY-ATTEST-74-002-NEEDS-74-001-SURFAC | TODO | Due 2025-11-22 · Accountable: Policy Guild, Console Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Console Guild / src/Policy/StellaOps.Policy.Engine | Needs 74-001 surface in Console verification reports contract.

Document artefact/deliverable for POLICY-ATTEST-74-002 and publish location so downstream tasks can proceed. | +| 1 | EXPORT-CONSOLE-23-001 | BLOCKED | PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN | Policy Guild, Scheduler Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | +| 2 | POLICY-AIRGAP-56-001 | BLOCKED | PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 3 | POLICY-AIRGAP-56-002 | BLOCKED | PREP-POLICY-AIRGAP-56-002-DEPENDS-ON-56-001-B | Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine | +| 4 | POLICY-AIRGAP-57-001 | BLOCKED | PREP-POLICY-AIRGAP-57-001-REQUIRES-SEALED-MOD | Policy Guild, AirGap Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 5 | POLICY-AIRGAP-57-002 | BLOCKED | PREP-POLICY-AIRGAP-57-002-NEEDS-STALENESS-FAL | Policy Guild, AirGap Time Guild / src/Policy/StellaOps.Policy.Engine | +| 6 | POLICY-AIRGAP-58-001 | BLOCKED | PREP-POLICY-AIRGAP-58-001-NOTIFICATION-SCHEMA | Policy Guild, Notifications Guild / src/Policy/StellaOps.Policy.Engine | +| 7 | POLICY-AOC-19-001 | BLOCKED | PREP-POLICY-AOC-19-001-NEEDS-AGREED-LINTING-T | Policy Guild / src/Policy/__Libraries/StellaOps.Policy | +| 8 | POLICY-AOC-19-002 | BLOCKED | PREP-POLICY-AOC-19-002-DEPENDS-ON-19-001-LINT | Policy Guild, Platform Security / src/Policy/__Libraries/StellaOps.Policy | +| 9 | POLICY-AOC-19-003 | BLOCKED | PREP-POLICY-AOC-19-003-REQUIRES-DECISIONED-NO | Policy Guild / src/Policy/__Libraries/StellaOps.Policy | +| 10 | POLICY-AOC-19-004 | BLOCKED | PREP-POLICY-AOC-19-004-DEPENDENT-ON-19-003-DA | Policy Guild, QA Guild / src/Policy/__Libraries/StellaOps.Policy | +| 11 | POLICY-ATTEST-73-001 | BLOCKED | PREP-POLICY-ATTEST-73-001-VERIFICATIONPOLICY- | Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | +| 12 | POLICY-ATTEST-73-002 | BLOCKED | PREP-POLICY-ATTEST-73-002-DEPENDS-ON-73-001-E | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 13 | POLICY-ATTEST-74-001 | BLOCKED | PREP-POLICY-ATTEST-74-001-REQUIRES-73-002-AND | Policy Guild, Attestor Service Guild / src/Policy/StellaOps.Policy.Engine | +| 14 | POLICY-ATTEST-74-002 | BLOCKED | PREP-POLICY-ATTEST-74-002-NEEDS-74-001-SURFAC | Policy Guild, Console Guild / src/Policy/StellaOps.Policy.Engine | | 15 | POLICY-CONSOLE-23-001 | BLOCKED | Console API contract (filters, pagination, aggregation) not supplied; requires BE-Base Platform spec | Policy Guild, BE-Base Platform Guild / src/Policy/StellaOps.Policy.Engine | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | | 2025-11-08 | Sprint created; awaiting staffing. | Planning | | 2025-11-18 | Attempted EXPORT-CONSOLE-23-001 but blocked: no export bundle/schema or scheduler job contract for Console; requires API + signed manifest format before implementation. Marked remaining tasks BLOCKED pending lint/airgap/attest/Console contracts. | Policy Guild | @@ -41,4 +56,4 @@ Focus: Policy & Reasoning focus on Policy (phase I). ## Next Checkpoints - Draft export surface proposal for Console (API + scheduler wiring) — target 2025-11-20. -- Identify bundle schema dependencies for POLICY-AIRGAP-56-* — target 2025-11-21. +- Identify bundle schema dependencies for POLICY-AIRGAP-56-* — target 2025-11-21. \ No newline at end of file diff --git a/docs/implplan/SPRINT_124_policy_reasoning.md b/docs/implplan/SPRINT_124_policy_reasoning.md index b90aa60cb..c95f68da5 100644 --- a/docs/implplan/SPRINT_124_policy_reasoning.md +++ b/docs/implplan/SPRINT_124_policy_reasoning.md @@ -10,8 +10,9 @@ Focus: Policy & Reasoning focus on Policy (phase II). | # | Task ID & handle | State | Key dependency / next step | Owners | | --- | --- | --- | --- | --- | +| P1 | PREP-POLICY-ENGINE-20-002-BUILD-DETERMINISTIC | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Build deterministic evaluator honoring lexical/priority order, first-match semantics, and safe value types (no wall-clock/network access).

Document artefact/deliverable for POLICY-ENGINE-20-002 and publish location so downstream tasks can proceed. | | 1 | POLICY-CONSOLE-23-002 | TODO | Produce simulation diff metadata (before/after counts, severity deltas, rule impact summaries) and approval state endpoints consumed by Console policy workspace; expose RBAC-aware status transitions (Deps: POLICY-CONSOLE-23-001) | Policy Guild, Product Ops / src/Policy/StellaOps.Policy.Engine | -| 2 | POLICY-ENGINE-20-002 | BLOCKED (2025-10-26) | Build deterministic evaluator honoring lexical/priority order, first-match semantics, and safe value types (no wall-clock/network access) | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 2 | POLICY-ENGINE-20-002 | BLOCKED (2025-10-26) | PREP-POLICY-ENGINE-20-002-BUILD-DETERMINISTIC | Policy Guild / src/Policy/StellaOps.Policy.Engine | | 3 | POLICY-ENGINE-20-003 | TODO | Implement selection joiners resolving SBOM↔advisory↔VEX tuples using linksets and PURL equivalence tables, with deterministic batching (Deps: POLICY-ENGINE-20-002) | Policy Guild, Concelier Core Guild, Excititor Core Guild / src/Policy/StellaOps.Policy.Engine | | 4 | POLICY-ENGINE-20-004 | TODO | Ship materialization writer that upserts into `effective_finding_{policyId}` with append-only history, tenant scoping, and trace references (Deps: POLICY-ENGINE-20-003) | Policy Guild, Platform Storage Guild / src/Policy/StellaOps.Policy.Engine | | 5 | POLICY-ENGINE-20-005 | TODO | Enforce determinism guard banning wall-clock, RNG, and network usage during evaluation via static analysis + runtime sandbox (Deps: POLICY-ENGINE-20-004) | Policy Guild, Security Engineering / src/Policy/StellaOps.Policy.Engine | @@ -23,3 +24,8 @@ Focus: Policy & Reasoning focus on Policy (phase II). | 11 | POLICY-ENGINE-27-002 | TODO | Enhance simulate endpoints to emit rule firing counts, heatmap aggregates, sampled explain traces with deterministic ordering, and delta summaries for quick/batch sims (Deps: POLICY-ENGINE-27-001) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | | 12 | POLICY-ENGINE-29-001 | TODO | Implement batch evaluation endpoint (`POST /policy/eval/batch`) returning determinations + rationale chain for sets of `(artifact,purl,version,advisory)` tuples; support pagination and cost budgets (Deps: POLICY-ENGINE-27-004) | Policy Guild / src/Policy/StellaOps.Policy.Engine | | 13 | POLICY-ENGINE-29-002 | TODO | Provide streaming simulation API comparing two policy versions, returning per-finding deltas without writes; align determinism with Vuln Explorer simulation (Deps: POLICY-ENGINE-29-001) | Policy Guild, Findings Ledger Guild / src/Policy/StellaOps.Policy.Engine | + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | \ No newline at end of file diff --git a/docs/implplan/SPRINT_125_policy_reasoning.md b/docs/implplan/SPRINT_125_policy_reasoning.md index 806012eaf..d8267fffb 100644 --- a/docs/implplan/SPRINT_125_policy_reasoning.md +++ b/docs/implplan/SPRINT_125_policy_reasoning.md @@ -10,21 +10,39 @@ Focus: Policy & Reasoning focus on Policy (phase III). | # | Task ID & handle | State | Key dependency / next step | Owners | | --- | --- | --- | --- | --- | +| P1 | PREP-POLICY-ENGINE-30-001-WAITING-ON-29-004-M | TODO | Due 2025-11-22 · Accountable: Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Waiting on 29-004 metrics/logging outputs to define overlay projection contract.

Document artefact/deliverable for POLICY-ENGINE-30-001 and publish location so downstream tasks can proceed. | +| P2 | PREP-POLICY-ENGINE-30-002-SIMULATION-BRIDGE-C | TODO | Due 2025-11-22 · Accountable: Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Simulation bridge cannot proceed until 30-001 overlay schema lands.

Document artefact/deliverable for POLICY-ENGINE-30-002 and publish location so downstream tasks can proceed. | +| P3 | PREP-POLICY-ENGINE-30-003-CHANGE-EVENTS-DEPEN | TODO | Due 2025-11-22 · Accountable: Policy Guild, Scheduler Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Scheduler Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | Change events depend on simulation bridge (30-002) outputs.

Document artefact/deliverable for POLICY-ENGINE-30-003 and publish location so downstream tasks can proceed. | +| P4 | PREP-POLICY-ENGINE-30-101-TRUST-WEIGHTING-UI- | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Trust weighting UI/API depends on change events + overlays (30-003).

Document artefact/deliverable for POLICY-ENGINE-30-101 and publish location so downstream tasks can proceed. | +| P5 | PREP-POLICY-ENGINE-31-001-ADVISORY-AI-KNOBS-R | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Advisory AI knobs rely on 30-101 trust weighting surfacing.

Document artefact/deliverable for POLICY-ENGINE-31-001 and publish location so downstream tasks can proceed. | +| P6 | PREP-POLICY-ENGINE-31-002-BATCH-CONTEXT-ENDPO | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Batch context endpoint waits on 31-001 knobs.

Document artefact/deliverable for POLICY-ENGINE-31-002 and publish location so downstream tasks can proceed. | +| P7 | PREP-POLICY-ENGINE-32-101-ORCHESTRATOR-JOB-SC | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Orchestrator job schema depends on 31-002 batch context.

Document artefact/deliverable for POLICY-ENGINE-32-101 and publish location so downstream tasks can proceed. | +| P8 | PREP-POLICY-ENGINE-33-101-WORKER-IMPLEMENTATI | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Worker implementation depends on 32-101 job schema.

Document artefact/deliverable for POLICY-ENGINE-33-101 and publish location so downstream tasks can proceed. | +| P9 | PREP-POLICY-ENGINE-34-101-LEDGER-EXPORT-REQUI | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Ledger export requires 33-101 workers.

Document artefact/deliverable for POLICY-ENGINE-34-101 and publish location so downstream tasks can proceed. | +| P10 | PREP-POLICY-ENGINE-35-201-SNAPSHOT-API-WAITS- | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Snapshot API waits on 34-101 ledger export.

Document artefact/deliverable for POLICY-ENGINE-35-201 and publish location so downstream tasks can proceed. | +| P11 | PREP-POLICY-ENGINE-38-201-VIOLATION-EVENTS-DE | TODO | Due 2025-11-22 · Accountable: Policy Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild / src/Policy/StellaOps.Policy.Engine | Violation events depend on 35-201 snapshot stream.

Document artefact/deliverable for POLICY-ENGINE-38-201 and publish location so downstream tasks can proceed. | +| P12 | PREP-POLICY-ENGINE-40-001-SEVERITY-FUSION-DEP | TODO | Due 2025-11-22 · Accountable: Policy Guild, Concelier Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Concelier Guild / src/Policy/StellaOps.Policy.Engine | Severity fusion depends on 38-201 violation event payloads.

Document artefact/deliverable for POLICY-ENGINE-40-001 and publish location so downstream tasks can proceed. | +| P13 | PREP-POLICY-ENGINE-40-002-CONFLICT-HANDLING-D | TODO | Due 2025-11-22 · Accountable: Policy Guild, Excititor Guild / src/Policy/StellaOps.Policy.Engine | Policy Guild, Excititor Guild / src/Policy/StellaOps.Policy.Engine | Conflict handling depends on 40-001 severity pipeline changes.

Document artefact/deliverable for POLICY-ENGINE-40-002 and publish location so downstream tasks can proceed. | | 1 | POLICY-ENGINE-29-003 | BLOCKED (2025-11-18) | Waiting on upstream POLICY-ENGINE-29-002 contract details; no path/scope schema or sample payloads available. | Policy Guild, SBOM Service Guild / src/Policy/StellaOps.Policy.Engine | | 2 | POLICY-ENGINE-29-004 | BLOCKED (2025-11-18) | Depends on blocked POLICY-ENGINE-29-003 path/scope contract. | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine | -| 3 | POLICY-ENGINE-30-001 | BLOCKED (2025-11-18) | Waiting on 29-004 metrics/logging outputs to define overlay projection contract. | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | -| 4 | POLICY-ENGINE-30-002 | BLOCKED (2025-11-18) | Simulation bridge cannot proceed until 30-001 overlay schema lands. | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | -| 5 | POLICY-ENGINE-30-003 | BLOCKED (2025-11-18) | Change events depend on simulation bridge (30-002) outputs. | Policy Guild, Scheduler Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | -| 6 | POLICY-ENGINE-30-101 | BLOCKED (2025-11-18) | Trust weighting UI/API depends on change events + overlays (30-003). | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 7 | POLICY-ENGINE-31-001 | BLOCKED (2025-11-18) | Advisory AI knobs rely on 30-101 trust weighting surfacing. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 8 | POLICY-ENGINE-31-002 | BLOCKED (2025-11-18) | Batch context endpoint waits on 31-001 knobs. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 9 | POLICY-ENGINE-32-101 | BLOCKED (2025-11-18) | Orchestrator job schema depends on 31-002 batch context. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 10 | POLICY-ENGINE-33-101 | BLOCKED (2025-11-18) | Worker implementation depends on 32-101 job schema. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 11 | POLICY-ENGINE-34-101 | BLOCKED (2025-11-18) | Ledger export requires 33-101 workers. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 12 | POLICY-ENGINE-35-201 | BLOCKED (2025-11-18) | Snapshot API waits on 34-101 ledger export. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 13 | POLICY-ENGINE-38-201 | BLOCKED (2025-11-18) | Violation events depend on 35-201 snapshot stream. | Policy Guild / src/Policy/StellaOps.Policy.Engine | -| 14 | POLICY-ENGINE-40-001 | BLOCKED (2025-11-18) | Severity fusion depends on 38-201 violation event payloads. | Policy Guild, Concelier Guild / src/Policy/StellaOps.Policy.Engine | -| 15 | POLICY-ENGINE-40-002 | BLOCKED (2025-11-18) | Conflict handling depends on 40-001 severity pipeline changes. | Policy Guild, Excititor Guild / src/Policy/StellaOps.Policy.Engine | +| 3 | POLICY-ENGINE-30-001 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-001-WAITING-ON-29-004-M | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | +| 4 | POLICY-ENGINE-30-002 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-002-SIMULATION-BRIDGE-C | Policy Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | +| 5 | POLICY-ENGINE-30-003 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-003-CHANGE-EVENTS-DEPEN | Policy Guild, Scheduler Guild, Cartographer Guild / src/Policy/StellaOps.Policy.Engine | +| 6 | POLICY-ENGINE-30-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-30-101-TRUST-WEIGHTING-UI- | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 7 | POLICY-ENGINE-31-001 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-31-001-ADVISORY-AI-KNOBS-R | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 8 | POLICY-ENGINE-31-002 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-31-002-BATCH-CONTEXT-ENDPO | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 9 | POLICY-ENGINE-32-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-32-101-ORCHESTRATOR-JOB-SC | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 10 | POLICY-ENGINE-33-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-33-101-WORKER-IMPLEMENTATI | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 11 | POLICY-ENGINE-34-101 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-34-101-LEDGER-EXPORT-REQUI | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 12 | POLICY-ENGINE-35-201 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-35-201-SNAPSHOT-API-WAITS- | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 13 | POLICY-ENGINE-38-201 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-38-201-VIOLATION-EVENTS-DE | Policy Guild / src/Policy/StellaOps.Policy.Engine | +| 14 | POLICY-ENGINE-40-001 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-40-001-SEVERITY-FUSION-DEP | Policy Guild, Concelier Guild / src/Policy/StellaOps.Policy.Engine | +| 15 | POLICY-ENGINE-40-002 | BLOCKED (2025-11-18) | PREP-POLICY-ENGINE-40-002-CONFLICT-HANDLING-D | Policy Guild, Excititor Guild / src/Policy/StellaOps.Policy.Engine | ## Notes & Risks (2025-11-18) - POLICY-ENGINE-29-002 contract/schema is missing; this blocks 29-003 path/scope awareness and cascades through all downstream tasks in this sprint. Unblock by publishing 29-002 artifacts (schema + sample payloads). + +## Execution Log +| Date (UTC) | Update | Owner | +| --- | --- | --- | +| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning | \ No newline at end of file diff --git a/docs/implplan/SPRINT_136_scanner_surface.md b/docs/implplan/SPRINT_136_scanner_surface.md index 720284603..46c627587 100644 --- a/docs/implplan/SPRINT_136_scanner_surface.md +++ b/docs/implplan/SPRINT_136_scanner_surface.md @@ -12,7 +12,7 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p | `SCANNER-ENTRYTRACE-18-506` | TODO | Surface EntryTrace graph + confidence via Scanner.WebService and CLI, including target summary in scan reports and policy payloads. | EntryTrace Guild, Scanner WebService Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-505 | | `SCANNER-ENV-01` | DONE (2025-11-18) | Worker already wired to `AddSurfaceEnvironment`/`ISurfaceEnvironment` for cache roots + CAS endpoints; no remaining ad-hoc env reads. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker) | — | | `SCANNER-ENV-02` | TODO (2025-11-06) | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. | Scanner WebService Guild, Ops Guild (src/Scanner/StellaOps.Scanner.WebService) | SCANNER-ENV-01 | -| `SCANNER-ENV-03` | DOING (2025-11-18) | Adopt Surface.Env helpers for plugin configuration (cache roots, CAS endpoints, feature toggles). | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-ENV-02 | +| `SCANNER-ENV-03` | BLOCKED (2025-11-19) | Waiting on SCANNER-ENV-02 tests/restore to complete and Surface.Env package publish; plugin wiring on hold. | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-ENV-02 | | `SURFACE-ENV-01` | DONE (2025-11-13) | Draft `surface-env.md` enumerating environment variables, defaults, and air-gap behaviour for Surface consumers. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | — | | `SURFACE-ENV-02` | DONE (2025-11-18) | Strongly-typed env accessors implemented; validation covers required endpoint, bounds, TLS cert path; regression tests passing. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-01 | | `SURFACE-ENV-03` | TODO | Adopt the env helper across Scanner Worker/WebService/BuildX plug-ins. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 | @@ -23,8 +23,8 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p | `SCANNER-LNM-21-001` | TODO | Update `/reports` and `/policy/runtime` payloads to consume advisory/vex linksets, exposing source severity arrays and conflict summaries alongside effective verdicts. | Scanner WebService Guild, Policy Guild (src/Scanner/StellaOps.Scanner.WebService) | — | | `SCANNER-LNM-21-002` | TODO | Add evidence endpoint for Console to fetch linkset summaries with policy overlay for a component/SBOM, including AOC references. | Scanner WebService Guild, UI Guild (src/Scanner/StellaOps.Scanner.WebService) | SCANNER-LNM-21-001 | | `SCANNER-SECRETS-03` | TODO | Use Surface.Secrets to retrieve registry credentials when interacting with CAS/referrers. | BuildX Plugin Guild, Security Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-SECRETS-02 | -| `SURFACE-SECRETS-01` | DOING (2025-11-02) | Produce `surface-secrets.md` defining secret reference schema, storage backends, scopes, and rotation rules. | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | — | -| `SURFACE-SECRETS-02` | DOING (2025-11-02) | Implement `StellaOps.Scanner.Surface.Secrets` core provider interfaces, secret models, and in-memory test backend. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-01 | +| `SURFACE-SECRETS-01` | BLOCKED (2025-11-19) | Secret schema/backends need Security Guild approval; draft doc not reviewed. | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | — | +| `SURFACE-SECRETS-02` | BLOCKED (2025-11-19) | Awaiting SURFACE-SECRETS-01 approval and test backend contract. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-01 | | `SURFACE-SECRETS-03` | TODO | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 | | `SURFACE-SECRETS-04` | TODO | Integrate Surface.Secrets into Scanner Worker/WebService/BuildX for registry + CAS creds. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 | | `SURFACE-SECRETS-05` | TODO | Invoke Surface.Secrets from Zastava Observer/Webhook for CAS & attestation secrets. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 | @@ -47,7 +47,7 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p | `SURFACE-FS-07` | TODO | Extend Surface.FS manifest schema with `composition.recipe`, fragment attestation metadata, and verification helpers per deterministic SBOM spec. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS) | SCANNER-SURFACE-04 | | `SCANNER-EMIT-15-001` | TODO | Enforce canonical JSON (`stella.contentHash`, Merkle root metadata, zero timestamps) for fragments and composed CycloneDX inventory/usage BOMs. Documented in `docs/modules/scanner/deterministic-sbom-compose.md` §2.2. | Scanner Emit Guild (src/Scanner/__Libraries/StellaOps.Scanner.Emit) | SCANNER-SURFACE-04 | | `SCANNER-SORT-02` | TODO | Sort layer fragments by digest and components by `identity.purl`/`identity.key` before composition; add determinism regression tests. | Scanner Core Guild (src/Scanner/__Libraries/StellaOps.Scanner.Core) | SCANNER-EMIT-15-001 | -| `SURFACE-VAL-01` | DOING (2025-11-01) | Define the Surface validation framework (`surface-validation.md`) covering env/cache/secret checks and extension hooks. | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-FS-01, SURFACE-ENV-01 | +| `SURFACE-VAL-01` | BLOCKED (2025-11-19) | Waiting on SURFACE-SECRETS-01 schema and Surface.Env publish to finalize validation framework doc. | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-FS-01, SURFACE-ENV-01 | | `SURFACE-VAL-02` | TODO | Implement base validation library with check registry and default validators for env/cached manifests/secret refs. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-01, SURFACE-ENV-02, SURFACE-FS-02 | | `SURFACE-VAL-03` | TODO | Integrate validation pipeline into Scanner analyzers so checks run before processing. | Scanner Guild, Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 | | `SURFACE-VAL-04` | TODO | Expose validation helpers to Zastava and other runtime consumers for preflight checks. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 | @@ -62,3 +62,4 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p | 2025-11-18 | SCANNER-ENV-02 started: wired Surface manifest store options into Scanner WebService and unit scaffold added; tests pending (nuget.org restore cancelled locally). | Implementer | | 2025-11-18 | Attempted `dotnet test` for Worker Surface manifest configurator; restore failed fetching StackExchange.Redis from nuget.org (network timeout); tests still pending CI. | Implementer | | 2025-11-18 | SCANNER-ENV-03 started: BuildX plugin now loads Surface.Env defaults (SCANNER/SURFACE prefixes) for cache root/bucket/tenant when args/env missing; tests not yet added. | Implementer | +| 2025-11-19 | Marked SCANNER-ENV-03, SURFACE-SECRETS-01/02, and SURFACE-VAL-01 BLOCKED pending Security/Surface schema approvals and published env/secrets artifacts; move back to TODO once upstream contracts land. | Implementer | diff --git a/docs/implplan/SPRINT_174_telemetry.md b/docs/implplan/SPRINT_174_telemetry.md index 7546f5032..cc603d92c 100644 --- a/docs/implplan/SPRINT_174_telemetry.md +++ b/docs/implplan/SPRINT_174_telemetry.md @@ -7,19 +7,19 @@ Depends on: Sprint 150.A - Orchestrator Summary: Notifications & Telemetry focus on Telemetry). Task ID | State | Task description | Owners (Source) --- | --- | --- | --- -TELEMETRY-OBS-50-001 | **DOING (2025-11-12)** | Create `StellaOps.Telemetry.Core` library with structured logging facade, OpenTelemetry configuration helpers, and deterministic bootstrap (service name/version detection, resource attributes). Publish sample usage for web/worker hosts. | Telemetry Core Guild (src/Telemetry/StellaOps.Telemetry.Core) +TELEMETRY-OBS-50-001 | DONE (2025-11-19) | `StellaOps.Telemetry.Core` bootstrap library shipped with structured logging facade, OTEL configuration helpers, deterministic bootstrap (service name/version detection, resource attributes), and sample usage for web/worker hosts. Evidence: `docs/observability/telemetry-bootstrap.md`. | Telemetry Core Guild (src/Telemetry/StellaOps.Telemetry.Core) TELEMETRY-OBS-50-002 | TODO | Implement context propagation middleware/adapters for HTTP, gRPC, background jobs, and CLI invocations, carrying `trace_id`, `tenant_id`, `actor`, and imposed-rule metadata. Provide test harness covering async resume scenarios. Dependencies: TELEMETRY-OBS-50-001. | Telemetry Core Guild (src/Telemetry/StellaOps.Telemetry.Core) TELEMETRY-OBS-51-001 | TODO | Ship metrics helpers for golden signals (histograms, counters, gauges) with exemplar support and cardinality guards. Provide Roslyn analyzer preventing unsanitised labels. Dependencies: TELEMETRY-OBS-50-002. | Telemetry Core Guild, Observability Guild (src/Telemetry/StellaOps.Telemetry.Core) TELEMETRY-OBS-51-002 | TODO | Implement redaction/scrubbing filters for secrets/PII enforced at logger sink, configurable per-tenant with TTL, including audit of overrides. Add determinism tests verifying stable field order and timestamp normalization. Dependencies: TELEMETRY-OBS-51-001. | Telemetry Core Guild, Security Guild (src/Telemetry/StellaOps.Telemetry.Core) TELEMETRY-OBS-55-001 | TODO | Provide incident mode toggle API that adjusts sampling, enables extended retention tags, and records activation trail for services. Ensure toggle honored by all hosting templates and integrates with Config/FeatureFlag providers. Dependencies: TELEMETRY-OBS-51-002. | Telemetry Core Guild (src/Telemetry/StellaOps.Telemetry.Core) TELEMETRY-OBS-56-001 | TODO | Add sealed-mode telemetry helpers (drift metrics, seal/unseal spans, offline exporters) and ensure hosts can disable external exporters when sealed. Dependencies: TELEMETRY-OBS-55-001. | Telemetry Core Guild (src/Telemetry/StellaOps.Telemetry.Core) -## Status notes (2025-11-12 UTC) +## Status notes (2025-11-19 UTC) -- **TELEMETRY-OBS-50-001** – Core bootstrap scaffolding live in branch `feature/telemetry-core-bootstrap`; resource detector + profile manifest generator in review; sample Orchestrator host integration slated for 2025-11-18. -- **TELEMETRY-OBS-50-002** – Awaiting merged bootstrap package before wiring propagation adapters; draft design covers HTTP/gRPC/job/CLI interceptors plus tenant/actor propagation tests. +- **TELEMETRY-OBS-50-001** – DONE. Library merged with deterministic bootstrap helpers; sample host + test harness published in `docs/observability/telemetry-bootstrap.md`. +- **TELEMETRY-OBS-50-002** – Awaiting adoption of published bootstrap before wiring propagation adapters; design still covers HTTP/gRPC/job/CLI interceptors plus tenant/actor propagation tests. - **TELEMETRY-OBS-51-001/51-002** – On hold until propagation middleware stabilizes; Security Guild still reviewing scrub policy (POLICY-SEC-42-003). -- **TELEMETRY-OBS-55-001/56-001** – Incident/sealed-mode APIs blocked on CLI toggle contract (CLI-OBS-12-001) and Notify incident payload spec (NOTIFY-OBS-55-001); keep coordination with Notifier team. +- **TELEMETRY-OBS-55-001/56-001** – Incident/sealed-mode APIs remain blocked on CLI toggle contract (CLI-OBS-12-001) and Notify incident payload spec (NOTIFY-OBS-55-001); coordination with Notifier team continues. ## Milestones & dependencies @@ -35,3 +35,4 @@ TELEMETRY-OBS-56-001 | TODO | Add sealed-mode telemetry helpers (drift metrics, | Date (UTC) | Update | Owner | | --- | --- | --- | | 2025-11-12 18:05 | Marked TELEMETRY-OBS-50-001 as DOING and captured branch/progress details in status notes. | Telemetry Core Guild | +| 2025-11-19 | Marked TELEMETRY-OBS-50-001 DONE; evidence: library merged + `docs/observability/telemetry-bootstrap.md` with sample host integration. | Implementer | diff --git a/docs/implplan/SPRINT_201_cli_i.md b/docs/implplan/SPRINT_201_cli_i.md index 5e1b7c95a..81860dd18 100644 --- a/docs/implplan/SPRINT_201_cli_i.md +++ b/docs/implplan/SPRINT_201_cli_i.md @@ -7,6 +7,8 @@ Depends on: Sprint 120.A - AirGap, Sprint 130.A - Scanner, Sprint 150.A - Orches Summary: Experience & SDKs focus on Cli (phase I). Task ID | State | Task description | Owners (Source) --- | --- | --- | --- +PREP-CLI-VULN-29-001-ARTEFACTS | DONE (2025-11-19) | Published frozen artefacts for CLI-VULN-29-001 under `out/console/guardrails/cli-vuln-29-001/` with hashes and doc `docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md`. | DevEx/CLI Guild · Docs Guild (src/Cli/StellaOps.Cli) +PREP-CLI-VEX-30-001-ARTEFACTS | DONE (2025-11-19) | Published frozen artefacts for CLI-VEX-30-001 under `out/console/guardrails/cli-vex-30-001/` with hashes and doc `docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md`. | DevEx/CLI Guild · Docs Guild (src/Cli/StellaOps.Cli) CLI-AIAI-31-001 | TODO | Implement `stella advise summarize` command with JSON/Markdown outputs and citation display. | DevEx/CLI Guild (src/Cli/StellaOps.Cli) CLI-AIAI-31-002 | TODO | Implement `stella advise explain` showing conflict narrative and structured rationale. Dependencies: CLI-AIAI-31-001. | DevEx/CLI Guild (src/Cli/StellaOps.Cli) CLI-AIAI-31-003 | TODO | Implement `stella advise remediate` generating remediation plans with `--strategy` filters and file output. Dependencies: CLI-AIAI-31-002. | DevEx/CLI Guild (src/Cli/StellaOps.Cli) @@ -22,4 +24,4 @@ CLI-ATTEST-74-001 | TODO | Implement `stella attest list` with filters (subject, CLI-ATTEST-74-002 | TODO | Implement `stella attest fetch` to download envelopes and payloads to disk. Dependencies: CLI-ATTEST-74-001. | CLI Attestor Guild (src/Cli/StellaOps.Cli) CLI-ATTEST-75-001 | TODO | Implement `stella attest key create. Dependencies: CLI-ATTEST-74-002. | CLI Attestor Guild, KMS Guild (src/Cli/StellaOps.Cli) CLI-ATTEST-75-002 | TODO | Add support for building/verifying attestation bundles in CLI. Dependencies: CLI-ATTEST-75-001. | CLI Attestor Guild, Export Guild (src/Cli/StellaOps.Cli) -CLI-HK-201-002 | DOING | Add JSON status coverage for offline kit status handler when no bundle is imported. | DevEx/CLI Guild (src/Cli/StellaOps.Cli) +CLI-HK-201-002 | BLOCKED | Await offline kit status contract and sample bundle; cannot finalize status coverage tests. | DevEx/CLI Guild (src/Cli/StellaOps.Cli) diff --git a/docs/implplan/SPRINT_212_web_i.md b/docs/implplan/SPRINT_212_web_i.md index c078c7ec4..93a3895fc 100644 --- a/docs/implplan/SPRINT_212_web_i.md +++ b/docs/implplan/SPRINT_212_web_i.md @@ -14,11 +14,11 @@ WEB-AIAI-31-003 `Telemetry & audit` | TODO | Emit metrics/logs (latency, guardra WEB-AOC-19-002 `Provenance & signature helpers` | TODO | Ship `ProvenanceBuilder`, checksum utilities, and signature verification helper integrated with guard logging. Cover DSSE/CMS formats with unit tests. Dependencies: WEB-AOC-19-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) WEB-AOC-19-003 `Analyzer + test fixtures` | TODO | Author Roslyn analyzer preventing ingestion modules from writing forbidden keys without guard, and provide shared test fixtures for guard validation used by Concelier/Excititor service tests. Dependencies: WEB-AOC-19-002. | QA Guild, BE-Base Platform Guild (src/Web/StellaOps.Web) WEB-CONSOLE-23-001 `Global posture endpoints` | TODO | Provide consolidated `/console/dashboard` and `/console/filters` APIs returning tenant-scoped aggregates (findings by severity, VEX override counts, advisory deltas, run health, policy change log). Enforce AOC labelling, deterministic ordering, and cursor-based pagination for drill-down hints. | BE-Base Platform Guild, Product Analytics Guild (src/Web/StellaOps.Web) -CONSOLE-VULN-29-001 `Vulnerability workspace` | DOING (2025-11-08) | Build `/console/vuln/*` APIs and filters surfacing tenant-scoped findings with policy/VEX badges so Docs/UI teams can document workflows. Dependencies: WEB-CONSOLE-23-001, CONCELIER-GRAPH-21-001. | Console Guild, BE-Base Platform Guild (src/Web/StellaOps.Web) +CONSOLE-VULN-29-001 `Vulnerability workspace` | BLOCKED (2025-11-19) | Awaiting WEB-CONSOLE-23-001 contract and Concelier graph schema; cannot finalize endpoints until schemas freeze. | Console Guild, BE-Base Platform Guild (src/Web/StellaOps.Web) > 2025-11-07: API scaffolding kicked off; `docs/advisory-ai/console.md` consuming placeholder responses until this lands. Scheduler/Signals hooks queued once filters stabilized. > 2025-11-08: Driving filter + reachability badge wiring plus `/console/vuln/search` DTOs to keep DOCS-AIAI-31-004 on real payloads; aligning Signals/Scheduler dependencies now that upstream tickets exist. > 2025-11-08: Published HTTP contract + sample payloads in `docs/api/console/workspaces.md` and `docs/api/console/samples/vuln-findings-sample.json` so Docs can stage screenshots while backend wires up. -CONSOLE-VEX-30-001 `VEX evidence workspace` | DOING (2025-11-08) | Provide `/console/vex/*` APIs streaming VEX statements, justification summaries, and advisory links with SSE refresh hooks. Dependencies: WEB-CONSOLE-23-001, EXCITITOR-CONSOLE-23-001. | Console Guild, BE-Base Platform Guild (src/Web/StellaOps.Web) +CONSOLE-VEX-30-001 `VEX evidence workspace` | BLOCKED (2025-11-19) | Blocked on WEB-CONSOLE-23-001 and Excititor console contract; needs validated SSE payload + schemas. | Console Guild, BE-Base Platform Guild (src/Web/StellaOps.Web) > 2025-11-07: Endpoint contract draft in progress to unblock DOCS-AIAI-31-004 screenshot capture once responses are wired. > 2025-11-08: Building SSE controller + `/console/vex/events` payloads and syncing Scheduler Signals tasks so DOCS-AIAI-31-004 can embed live data. > 2025-11-08: SSE schema + NDJSON sample captured in `docs/api/console/workspaces.md` and `docs/api/console/samples/vex-statement-sse.ndjson`; waiting on Scheduler topic hook-up. @@ -34,3 +34,4 @@ WEB-EXC-25-001 `Exceptions CRUD & workflow` | TODO | Implement `/exceptions` API ## Updates - 2025-11-18: WEB-CONTAINERS-44-001 completed — added quickstart banner, `/welcome` config discovery page, and sample config values to surface safe deployment info. - 2025-11-19: WEB-CONTAINERS-45-001 completed — readiness/liveness/version JSON assets added for helm probes; config discovery is live via `/welcome`. +- 2025-11-19: CONSOLE-VULN-29-001 and CONSOLE-VEX-30-001 marked BLOCKED pending WEB-CONSOLE-23-001 and upstream Concelier/Excititor schemas. | diff --git a/docs/implplan/SPRINT_213_web_ii.md b/docs/implplan/SPRINT_213_web_ii.md index 503808c81..d280594ff 100644 --- a/docs/implplan/SPRINT_213_web_ii.md +++ b/docs/implplan/SPRINT_213_web_ii.md @@ -12,9 +12,9 @@ WEB-EXC-25-003 `Notifications & events` | TODO | Publish `exception.*` events, i WEB-EXPORT-35-001 `Export routing` | TODO | Surface Export Center APIs (profiles/runs/download) through gateway with tenant scoping, streaming support, and viewer/operator scope checks. | BE-Base Platform Guild (src/Web/StellaOps.Web) WEB-EXPORT-36-001 `Distribution endpoints` | TODO | Add distribution routes (OCI/object storage), manifest/provenance proxies, and signed URL generation. Dependencies: WEB-EXPORT-35-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) WEB-EXPORT-37-001 `Scheduling & verification` | TODO | Expose scheduling, retention, encryption parameters, and verification endpoints with admin scope enforcement and audit logs. Dependencies: WEB-EXPORT-36-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-GRAPH-SPEC-21-000 `Graph API/overlay spec drop` | DOING | Drafted gateway spec stub `docs/api/graph-gateway-spec-draft.yaml`; pending Graph Platform ratification. | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) -WEB-GRAPH-21-001 `Graph endpoints` | DOING | Use draft gateway spec `docs/api/graph-gateway-spec-draft.yaml` to add routes for graph versions/viewport/node/path/diff/export with RBAC + streaming. | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) -WEB-GRAPH-21-002 `Request validation` | DOING | Implement bbox/zoom/path validation, pagination tokens, deterministic ordering; add contract tests. Dependencies: WEB-GRAPH-21-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) +WEB-GRAPH-SPEC-21-000 `Graph API/overlay spec drop` | BLOCKED | Draft stub exists; awaiting Graph Platform ratification of overlay format and cache schema. | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) +WEB-GRAPH-21-001 `Graph endpoints` | BLOCKED | Depends on ratified spec `WEB-GRAPH-SPEC-21-000`. | BE-Base Platform Guild, Graph Platform Guild (src/Web/StellaOps.Web) +WEB-GRAPH-21-002 `Request validation` | BLOCKED | Depends on WEB-GRAPH-21-001 and final overlay schema. | BE-Base Platform Guild (src/Web/StellaOps.Web) WEB-GRAPH-21-003 `Error mapping & exports` | TODO | Map graph service errors to `ERR_Graph_*`, support GraphML/JSONL export streaming, document rate limits. Dependencies: WEB-GRAPH-21-002. | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) WEB-GRAPH-21-004 `Overlay pass-through` | TODO | Proxy Policy Engine overlays while keeping gateway stateless; maintain streaming budgets. Dependencies: WEB-GRAPH-21-003. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) WEB-GRAPH-24-001 `Gateway proxy refresh` | TODO | Gateway proxy for Graph API and Policy overlays with RBAC, caching, pagination, ETags, and streaming; zero business logic. Dependencies: WEB-GRAPH-21-004. | BE-Base Platform Guild (src/Web/StellaOps.Web) diff --git a/docs/implplan/SPRINT_215_web_iv.md b/docs/implplan/SPRINT_215_web_iv.md index b9958722f..e19f25aa4 100644 --- a/docs/implplan/SPRINT_215_web_iv.md +++ b/docs/implplan/SPRINT_215_web_iv.md @@ -1,24 +1,3 @@ -# Sprint 215 - Experience & SDKs · 180.F) Web.IV +# Sprint 215 Web IV (legacy file) -Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08). - -[Experience & SDKs] 180.F) Web.IV -Depends on: Sprint 180.F - Web.III -Summary: Experience & SDKs focus on Web (phase IV). -Task ID | State | Task description | Owners (Source) ---- | --- | --- | --- -WEB-ORCH-33-001 `Control + backfill actions` | TODO | Add POST action routes (`pause. Dependencies: WEB-ORCH-32-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-ORCH-34-001 `Quotas & telemetry` | TODO | Surface quotas/backfill APIs, queue/backpressure metrics, and error clustering routes with admin scope enforcement and audit logging. Dependencies: WEB-ORCH-33-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-POLICY-20-001 `Policy endpoints` | TODO | Implement Policy CRUD/compile/run/simulate/findings/explain endpoints with OpenAPI, tenant scoping, and service identity enforcement. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) -WEB-POLICY-20-002 `Pagination & filters` | TODO | Add pagination, filtering, sorting, and tenant guards to listings for policies, runs, and findings; include deterministic ordering and query diagnostics. Dependencies: WEB-POLICY-20-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-POLICY-20-003 `Error mapping` | TODO | Map engine errors to `ERR_POL_*` responses with consistent payloads and contract tests; expose correlation IDs in headers. Dependencies: WEB-POLICY-20-002. | BE-Base Platform Guild, QA Guild (src/Web/StellaOps.Web) -WEB-POLICY-20-004 `Simulate rate limits` | TODO | Introduce adaptive rate limiting + quotas for simulation endpoints, expose metrics, and document retry headers. Dependencies: WEB-POLICY-20-003. | Platform Reliability Guild (src/Web/StellaOps.Web) -WEB-POLICY-23-001 `Policy pack CRUD` | BLOCKED (2025-10-29) | Implement API endpoints for creating/listing/fetching policy packs and revisions (`/policy/packs`, `/policy/packs/{id}/revisions`) with pagination, RBAC, and AOC metadata exposure. (Tracked via Sprint 18.5 gateway tasks.). Dependencies: WEB-POLICY-20-004. | BE-Base Platform Guild, Policy Guild (src/Web/StellaOps.Web) -WEB-POLICY-23-002 `Activation & scope` | BLOCKED (2025-10-29) | Add activation endpoint with scope windows, conflict checks, and optional 2-person approval integration; emit events on success. (Tracked via Sprint 18.5 gateway tasks.). Dependencies: WEB-POLICY-23-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-POLICY-23-003 `Simulation & evaluation` | TODO | Provide `/policy/simulate` and `/policy/evaluate` endpoints with streaming responses, rate limiting, and error mapping. Dependencies: WEB-POLICY-23-002. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-POLICY-23-004 `Explain retrieval` | TODO | Expose explain history endpoints (`/policy/runs`, `/policy/runs/{id}`) including decision tree, sources consulted, and AOC chain. Dependencies: WEB-POLICY-23-003. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-POLICY-27-001 `Policy registry proxy` | TODO | Surface Policy Registry APIs (`/policy/workspaces`, `/policy/versions`, `/policy/reviews`, `/policy/registry`) through gateway with tenant scoping, RBAC, and request validation; ensure streaming downloads for evidence bundles. Dependencies: WEB-POLICY-23-004. | BE-Base Platform Guild, Policy Registry Guild (src/Web/StellaOps.Web) -WEB-POLICY-27-002 `Review & approval routes` | TODO | Implement review lifecycle endpoints (open, comment, approve/reject) with audit headers, comment pagination, and webhook fan-out. Dependencies: WEB-POLICY-27-001. | BE-Base Platform Guild (src/Web/StellaOps.Web) -WEB-POLICY-27-003 `Simulation orchestration endpoints` | TODO | Expose quick/batch simulation endpoints with SSE progress (`/policy/simulations/{runId}/stream`), cursor-based result pagination, and manifest download routes. Dependencies: WEB-POLICY-27-002. | BE-Base Platform Guild, Scheduler Guild (src/Web/StellaOps.Web) -WEB-POLICY-27-004 `Publish & promote controls` | TODO | Add publish/sign/promote/rollback endpoints with idempotent request IDs, canary parameters, and environment bindings; enforce scope checks and emit structured events. Dependencies: WEB-POLICY-27-003. | BE-Base Platform Guild, Security Guild (src/Web/StellaOps.Web) -WEB-POLICY-27-005 `Policy Studio telemetry` | TODO | Instrument metrics/logs for compile latency, simulation queue depth, approval latency, promotion actions; expose aggregated dashboards and correlation IDs for Console. Dependencies: WEB-POLICY-27-004. | BE-Base Platform Guild, Observability Guild (src/Web/StellaOps.Web) \ No newline at end of file +This sprint has been renamed to `SPRINT_0215_0001_0001_web_iv.md` and normalized to the standard template on 2025-11-19. Please update links to point to the new file. diff --git a/docs/implplan/SPRINT_300_documentation_process.md b/docs/implplan/SPRINT_300_documentation_process.md index 97e848f6c..a478b21e6 100644 --- a/docs/implplan/SPRINT_300_documentation_process.md +++ b/docs/implplan/SPRINT_300_documentation_process.md @@ -16,13 +16,14 @@ ## Task Board | Stream | Status | Owner(s) | Dependencies | Notes | | --- | --- | --- | --- | --- | -| 200.A Docs Tasks.md ladder (Sprint 301 onwards) | DOING (2025-11-13) | Docs Guild · Ops Guild | Attestor 100.A; Advisory AI 110.A; AirGap 120.A; Scanner 130.A; Graph 140.A; Orchestrator 150.A; EvidenceLocker 160.A; Notifier 170.A; CLI 180.A; Ops Deployment 190.A | Implementing new implplan template, aligning Md.I backlog before subsequent Md phases move. | +| 200.A Docs Tasks.md ladder (Sprint 301 onwards) | BLOCKED (2025-11-19) | Docs Guild · Ops Guild | Attestor 100.A; Advisory AI 110.A; AirGap 120.A; Scanner 130.A; Graph 140.A; Orchestrator 150.A; EvidenceLocker 160.A; Notifier 170.A; CLI 180.A; Ops Deployment 190.A | Awaiting upstream artefacts (SBOM/CLI/Policy/AirGap determinism) before Md.I template rollout can continue. | | 200.B Module dossiers (Sprints 312–335) | TODO | Docs Guild · Module Guild owners | Docs Tasks Md ladder to at least Md.II; Ops deployment evidence | Stays queued until Docs Tasks Md ladder provides updated process + assets. | ## Execution Log | Date (UTC) | Update | Owner | | --- | --- | --- | | 2025-11-13 | Sprint 300 switched to topic-oriented template; Docs Tasks Md ladder marked DOING to reflect ongoing restructuring work. | Docs Guild | +| 2025-11-19 | Marked Docs Tasks Md ladder BLOCKED pending upstream artefacts for Md.I dossier rollouts. | Implementer | ## Decisions & Risks | Item | Type | Owner(s) | Due | Notes | diff --git a/docs/implplan/SPRINT_301_docs_tasks_md_i.md b/docs/implplan/SPRINT_301_docs_tasks_md_i.md index c527ff84f..133c46a45 100644 --- a/docs/implplan/SPRINT_301_docs_tasks_md_i.md +++ b/docs/implplan/SPRINT_301_docs_tasks_md_i.md @@ -21,7 +21,7 @@ | Task ID | Status | Owner(s) | Dependencies | Notes | | --- | --- | --- | --- | --- | | DOCS-UNBLOCK-CLI-KNOBS-301 | BLOCKED | CLI Guild · Policy Guild · DevEx Guild | Await delivery of CLI-VULN-29-001; CLI-VEX-30-001; POLICY-ENGINE-31-001 artifacts to package fixtures/screenshots. | Produce screenshots/JSON fixtures and changelog so DOCS-AIAI-31-005..009 can proceed. | -| DOCS-AIAI-31-004 | DOING (2025-11-07) | Docs Guild · Console Guild | DOCS-AIAI-31-003; CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; EXCITITOR-CONSOLE-23-001 | `/docs/advisory-ai/console.md` with screenshots, a11y notes, copy-as-ticket instructions. | +| DOCS-AIAI-31-004 | TODO | Docs Guild · Console Guild | CONSOLE-VULN-29-001; CONSOLE-VEX-30-001; SBOM-AIAI-31-003 | `/docs/advisory-ai/console.md` with fixtures available; final screenshots await SBOM evidence. | | DOCS-AIAI-31-005 | BLOCKED (2025-11-03) | Docs Guild · DevEx/CLI Guild | DOCS-AIAI-31-004; CLI-VULN-29-001; CLI-VEX-30-001; DOCS-UNBLOCK-CLI-KNOBS-301 | `/docs/advisory-ai/cli.md` covering commands, exit codes, scripting patterns. | | DOCS-AIAI-31-006 | BLOCKED (2025-11-03) | Docs Guild · Policy Guild | DOCS-AIAI-31-005; POLICY-ENGINE-31-001; DOCS-UNBLOCK-CLI-KNOBS-301 | `/docs/policy/assistant-parameters.md` for temperature, token limits, ranking weights, TTLs. | | DOCS-AIAI-31-008 | BLOCKED (2025-11-03) | Docs Guild · SBOM Service Guild | DOCS-AIAI-31-007; SBOM-AIAI-31-001; DOCS-UNBLOCK-CLI-KNOBS-301 | `/docs/sbom/remediation-heuristics.md` (feasibility scoring, blast radius). | @@ -32,7 +32,7 @@ | DOCS-AIRGAP-56-004 | TODO | Docs Guild · Deployment Guild | DOCS-AIRGAP-56-003 | `/docs/airgap/bootstrap.md` covering Bootstrap Pack creation + install. | | DOCS-AIRGAP-57-001 | TODO | Docs Guild · AirGap Time Guild | DOCS-AIRGAP-56-004 | `/docs/airgap/staleness-and-time.md` (time anchors, drift, UI indicators). | | DOCS-AIRGAP-57-002 | TODO | Docs Guild · Console Guild | DOCS-AIRGAP-57-001 | `/docs/console/airgap.md` (sealed badge, import wizard, staleness dashboards). | -| DOCS-SCANNER-DET-01 | DOING (2025-11-09) | Docs Guild · Scanner Guild | Sprint 136 outputs; scanner determinism fixtures | `/docs/modules/scanner/deterministic-sbom-compose.md` plus scan guide updates. | +| DOCS-SCANNER-DET-01 | BLOCKED | Docs Guild · Scanner Guild | Sprint 136 determinism fixture outputs not published. | `/docs/modules/scanner/deterministic-sbom-compose.md` plus scan guide updates. | | DOCS-POLICY-DET-01 | TODO | Docs Guild · Policy Guild | POLICY-DET backlog | Extend `docs/modules/policy/architecture.md` with determinism gate semantics and provenance references. | | DOCS-CLI-DET-01 | TODO | Docs Guild · DevEx/CLI Guild | CLI-SBOM-60-001; CLI-SBOM-60-002 | Document `stella sbomer` verbs (`layer`, `compose`, `drift`, `verify`) with examples & offline instructions. | @@ -43,7 +43,9 @@ | 2025-11-09 | Task inventory imported from legacy sprint file; SBOM/service dependencies flagged. | Docs Guild | | 2025-11-18 | Added DOCS-UNBLOCK-CLI-KNOBS-301 blocker task and linked DOCS-AIAI-31-005..009 to it. | Project PM | | 2025-11-18 | Set DOCS-UNBLOCK-CLI-KNOBS-301 to DOING; packaging CLI verbs/policy knobs artifacts for docs unblock. | Implementer | +| 2025-11-19 | DOCS-UNBLOCK-CLI-KNOBS-301 remains BLOCKED; upstream CLI/Policy artefacts still missing. | Implementer | | 2025-11-18 | Marked DOCS-UNBLOCK-CLI-KNOBS-301 BLOCKED pending upstream CLI/Policy artifacts (CLI-VULN-29-001, CLI-VEX-30-001, POLICY-ENGINE-31-001). | Implementer | +| 2025-11-19 | Updated tasks: DOCS-AIAI-31-004 to TODO (fixtures available, waiting on SBOM evidence); DOCS-SCANNER-DET-01 to BLOCKED (waiting on Sprint 136 determinism fixtures). | Implementer | ## Decisions & Risks ### Decisions diff --git a/docs/implplan/SPRINT_333_docs_modules_excititor.md b/docs/implplan/SPRINT_333_docs_modules_excititor.md index 167d1a228..4bab100cf 100644 --- a/docs/implplan/SPRINT_333_docs_modules_excititor.md +++ b/docs/implplan/SPRINT_333_docs_modules_excititor.md @@ -10,6 +10,6 @@ Task ID | State | Task description | Owners (Source) EXCITOR-DOCS-0001 | DONE (2025-11-07) | Validate that `docs/modules/excitor/README.md` matches the latest release notes and consensus beta notes. | Docs Guild (docs/modules/excitor) EXCITOR-OPS-0001 | DONE (2025-11-07) | Review runbooks/observability assets, adding the checklist captured in `docs/modules/excitor/mirrors.md`. | Ops Guild (docs/modules/excitor) EXCITOR-ENG-0001 | DONE (2025-11-07) | Ensure the implementation plan sprint alignment table stays current with `SPRINT_200` updates. | Module Team (docs/modules/excitor) -EXCITITOR-DOCS-0001 | DOING (2025-10-29) | See ./AGENTS.md | Docs Guild (docs/modules/excititor) +EXCITITOR-DOCS-0001 | BLOCKED (2025-11-19) | Waiting on Excititor chunk API CI validation + console contracts; cannot finalize docs until tests pass and OpenAPI frozen. | Docs Guild (docs/modules/excititor) EXCITITOR-ENG-0001 | TODO | Update status via ./AGENTS.md workflow | Module Team (docs/modules/excititor) EXCITITOR-OPS-0001 | TODO | Sync outcomes back to ../.. | Ops Guild (docs/modules/excititor) diff --git a/docs/implplan/SPRINT_511_api.md b/docs/implplan/SPRINT_511_api.md index 0a6361ab2..3cebb9921 100644 --- a/docs/implplan/SPRINT_511_api.md +++ b/docs/implplan/SPRINT_511_api.md @@ -8,15 +8,15 @@ Summary: Ops & Offline focus on Api). Task ID | State | Task description | Owners (Source) --- | --- | --- | --- APIGOV-61-001 | DONE (2025-11-18) | Spectral config + CI workflow added; npm script `api:lint` runs spectral via npx. | API Governance Guild (src/Api/StellaOps.Api.Governance) -APIGOV-61-002 | TODO | Implement example coverage checker ensuring every operation has at least one request/response example. Dependencies: APIGOV-61-001. | API Governance Guild (src/Api/StellaOps.Api.Governance) -APIGOV-62-001 | TODO | Build compatibility diff tool producing additive/breaking reports comparing prior release. Dependencies: APIGOV-61-002. | API Governance Guild (src/Api/StellaOps.Api.Governance) +APIGOV-61-002 | DONE (2025-11-18) | Implement example coverage checker ensuring every operation has at least one request/response example. Dependencies: APIGOV-61-001. | API Governance Guild (src/Api/StellaOps.Api.Governance) +APIGOV-62-001 | DONE (2025-11-18) | Build compatibility diff tool producing additive/breaking reports comparing prior release. Dependencies: APIGOV-61-002. | API Governance Guild (src/Api/StellaOps.Api.Governance) APIGOV-62-002 | TODO | Automate changelog generation and publish signed artifacts to `src/Sdk/StellaOps.Sdk.Release` pipeline. Dependencies: APIGOV-62-001. | API Governance Guild, DevOps Guild (src/Api/StellaOps.Api.Governance) -APIGOV-63-001 | TODO | Integrate deprecation metadata into Notification Studio templates for API sunset events. Dependencies: APIGOV-62-002. | API Governance Guild, Notifications Guild (src/Api/StellaOps.Api.Governance) -OAS-61-001 | TODO | Scaffold per-service OpenAPI 3.1 files with shared components, info blocks, and initial path stubs. | API Contracts Guild (src/Api/StellaOps.Api.OpenApi) -OAS-61-002 | TODO | Implement aggregate composer (`stella.yaml`) resolving `$ref`s and merging shared components; wire into CI. Dependencies: OAS-61-001. | API Contracts Guild, DevOps Guild (src/Api/StellaOps.Api.OpenApi) -OAS-62-001 | TODO | Populate request/response examples for top 50 endpoints, including standard error envelope. Dependencies: OAS-61-002. | API Contracts Guild, Service Guilds (src/Api/StellaOps.Api.OpenApi) -OAS-62-002 | TODO | Add custom lint rules enforcing pagination, idempotency headers, naming conventions, and example coverage. Dependencies: OAS-62-001. | API Contracts Guild (src/Api/StellaOps.Api.OpenApi) -OAS-63-001 | TODO | Implement compatibility diff tooling comparing previous release specs; classify breaking vs additive changes. Dependencies: OAS-62-002. | API Contracts Guild (src/Api/StellaOps.Api.OpenApi) +APIGOV-63-001 | BLOCKED | Notification Studio templates and deprecation metadata schema not present; waiting on Notifications Guild assets. | API Governance Guild, Notifications Guild (src/Api/StellaOps.Api.Governance) +OAS-61-001 | DONE (2025-11-18) | Scaffold per-service OpenAPI 3.1 files with shared components, info blocks, and initial path stubs. | API Contracts Guild (src/Api/StellaOps.Api.OpenApi) +OAS-61-002 | DONE (2025-11-18) | Implement aggregate composer (`stella.yaml`) resolving `$ref`s and merging shared components; wire into CI. Dependencies: OAS-61-001. | API Contracts Guild, DevOps Guild (src/Api/StellaOps.Api.OpenApi) +OAS-62-001 | BLOCKED (2025-11-19) | Populate request/response examples for top 50 endpoints, including standard error envelope. Dependencies: OAS-61-002 not ratified; waiting on approved examples + error envelope. | API Contracts Guild, Service Guilds (src/Api/StellaOps.Api.OpenApi) +OAS-62-002 | BLOCKED | Depends on 62-001 examples to tune lint rules. | API Contracts Guild (src/Api/StellaOps.Api.OpenApi) +OAS-63-001 | BLOCKED | Compat diff enhancements depend on 62-002 lint + examples output. | API Contracts Guild (src/Api/StellaOps.Api.OpenApi) OAS-63-002 | TODO | Add `/.well-known/openapi` discovery endpoint schema metadata (extensions, version info). Dependencies: OAS-63-001. | API Contracts Guild, Gateway Guild (src/Api/StellaOps.Api.OpenApi) ## Execution Log @@ -24,3 +24,7 @@ OAS-63-002 | TODO | Add `/.well-known/openapi` discovery endpoint schema metadat | --- | --- | --- | | 2025-11-08 | Archived completed/historic work to docs/implplan/archived/tasks.md (updated 2025-11-08). | Planning | | 2025-11-18 | Added Spectral config (`.spectral.yaml`), npm `api:lint` (npx spectral) script, and CI workflow `.gitea/workflows/api-governance.yml`; marked APIGOV-61-001 DONE. | API Governance Guild | +| 2025-11-18 | Implemented example coverage checker (`api:examples`), aggregate composer `compose.mjs`, and initial per-service OAS stubs (authority/orchestrator/policy/export-center); OAS-61-001/002 set to DONE. | API Contracts Guild | +| 2025-11-19 | Added scheduler/export-center/graph shared endpoints, shared paging/security components, and CI diff gates (previous commit + baseline). Created baseline `stella-baseline.yaml`. | API Contracts Guild | +| 2025-11-19 | Implemented API changelog generator (`api:changelog`), wired compose/examples/compat/changelog into CI, and added new policy revisions + scheduler queue/job endpoints. | API Contracts Guild | +| 2025-11-19 | Marked OAS-62-001 BLOCKED pending OAS-61-002 ratification and approved examples/error envelope. | Implementer | diff --git a/docs/implplan/blocked_tree.md b/docs/implplan/blocked_tree.md new file mode 100644 index 000000000..a431401cf --- /dev/null +++ b/docs/implplan/blocked_tree.md @@ -0,0 +1,390 @@ +# SPRINT_0110_0001_0001_ingestion_evidence.md +- SBOM-AIAI-31-003 [BLOCKED] (SPRINT_110_ingestion_evidence.md:32) +- DOCS-AIAI-31-005/006/008/009 [BLOCKED] (SPRINT_110_ingestion_evidence.md:33) +- CONCELIER-AIRGAP-56-001..58-001 [BLOCKED] (SPRINT_110_ingestion_evidence.md:36) +- CONCELIER-CONSOLE-23-001..003 [BLOCKED] (SPRINT_110_ingestion_evidence.md:37) +- CONCELIER-ATTEST-73-001/002 [BLOCKED] (SPRINT_110_ingestion_evidence.md:38) +- FEEDCONN-ICSCISA-02-012 / KISA-02-008 [BLOCKED] (SPRINT_0110_0001_0001_ingestion_evidence.md:47) + - PREP-FEEDCONN-ICS-KISA-PLAN [TODO] (SPRINT_110_ingestion_evidence.md:26) + +# SPRINT_0114_0001_0003_concelier_iii.md +- CONCELIER-OAS-61-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:37) + - PREP-CONCELIER-OAS-61-001-LNM-SCHEMA-FROZEN-2 [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:23) +- CONCELIER-OAS-61-002 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:38) + - PREP-CONCELIER-OAS-61-002-DEPENDS-ON-61-001-B [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:24) +- CONCELIER-OAS-62-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:39) + - PREP-CONCELIER-OAS-62-001-DEPENDS-ON-61-002-B [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:25) +- CONCELIER-OAS-63-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:40) + - PREP-CONCELIER-OAS-63-001-DEPENDS-ON-62-001-B [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:26) +- CONCELIER-OBS-51-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:41) + - PREP-CONCELIER-OBS-51-001-AWAIT-OBSERVABILITY [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:27) +- CONCELIER-OBS-52-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:42) + - PREP-CONCELIER-OBS-52-001-DEPENDS-ON-51-001-M [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:28) +- CONCELIER-OBS-53-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:43) + - PREP-CONCELIER-OBS-53-001-DEPENDS-ON-52-001-B [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:29) +- CONCELIER-OBS-54-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:44) + - PREP-CONCELIER-OBS-54-001-DEPENDS-ON-OBS-TIME [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:30) +- CONCELIER-OBS-55-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:45) + - PREP-CONCELIER-OBS-55-001-DEPENDS-ON-54-001-I [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:31) +- CONCELIER-ORCH-32-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:46) + - PREP-CONCELIER-ORCH-32-001-ORCHESTRATOR-REGIS [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:32) +- CONCELIER-ORCH-32-002 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:47) + - PREP-CONCELIER-ORCH-32-002-DEPENDS-ON-32-001 [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:33) +- CONCELIER-ORCH-33-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:48) + - PREP-CONCELIER-ORCH-33-001-DEPENDS-ON-32-002 [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:34) +- CONCELIER-ORCH-34-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:49) + - PREP-CONCELIER-ORCH-34-001-DEPENDS-ON-33-001 [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:35) +- CONCELIER-POLICY-20-001 [BLOCKED] (SPRINT_0114_0001_0003_concelier_iii.md:50) + - PREP-CONCELIER-POLICY-20-001-LNM-APIS-NOT-EXP [TODO] (SPRINT_0114_0001_0003_concelier_iii.md:36) + +# SPRINT_0115_0001_0004_concelier_iv.md +- CONCELIER-RISK-66-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:31) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) +- CONCELIER-RISK-66-002 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:32) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) +- CONCELIER-RISK-67-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:33) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) +- CONCELIER-RISK-68-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:34) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) + - POLICY-RISK-68-001 [TODO] (SPRINT_0128_0001_0001_policy_reasoning.md:24) +- CONCELIER-RISK-69-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:35) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) +- CONCELIER-SIG-26-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:36) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) + - SIGNALS-24-002 [DOING (2025-11-07)] (SPRINT_0143_0000_0001_signals.md:24) + - SIGNALS-24-001 [DONE (2025-11-09)] (SPRINT_0143_0000_0001_signals.md:23) + … +- CONCELIER-STORE-AOC-19-005 [BLOCKED (2025-11-04)] (SPRINT_0115_0001_0004_concelier_iv.md:37) + - PREP-CONCELIER-CORE-AOC-19-004 [TODO] (SPRINT_0115_0001_0004_concelier_iv.md:23) +- CONCELIER-TEN-48-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:38) + - POLICY-AUTH-SIGNALS-LIB-115 [DOING] (SPRINT_0115_0001_0004_concelier_iv.md:26) + - PREP-AUTH-TEN-47-001 [TODO] (SPRINT_0115_0001_0004_concelier_iv.md:24) +- CONCELIER-VEXLENS-30-001 [BLOCKED] (SPRINT_0115_0001_0004_concelier_iv.md:39) + - PREP-CONCELIER-VULN-29-001 [TODO] (SPRINT_0115_0001_0004_concelier_iv.md:25) + - VEXLENS-30-005 [TODO] (SPRINT_0129_0001_0001_policy_reasoning.md:42) + +# SPRINT_0119_0001_0001_excititor_i.md +- EXCITITOR-AIRGAP-56-001 [TODO] (SPRINT_0119_0001_0005_excititor_v.md:30) +- EXCITITOR-AIRGAP-57-001 [BLOCKED] (SPRINT_0119_0001_0001_excititor_i.md:35) + - PREP-EXCITITOR-AIRGAP-57-001-BLOCKED-ON-56-00 [TODO] (SPRINT_0119_0001_0001_excititor_i.md:26) +- EXCITITOR-AIRGAP-58-001 [TODO] (SPRINT_0119_0001_0005_excititor_v.md:31) +- EXCITITOR-CONN-TRUST-01-001 [BLOCKED] (SPRINT_0119_0001_0001_excititor_i.md:40) + - PREP-EXCITITOR-CONN-TRUST-01-001-CONNECTOR-SI [TODO] (SPRINT_0119_0001_0001_excititor_i.md:28) + +# SPRINT_0119_0001_0002_excititor_ii.md +- EXCITITOR-CONSOLE-23-001 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:44) + - PREP-EXCITITOR-CONSOLE-23-001-AWAITING-CONCRE [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:25) +- EXCITITOR-CONSOLE-23-002 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:45) + - PREP-EXCITITOR-CONSOLE-23-002-DEPENDS-ON-23-0 [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:26) +- EXCITITOR-CONSOLE-23-003 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:46) + - PREP-EXCITITOR-CONSOLE-23-003-DEPENDS-ON-23-0 [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:27) +- EXCITITOR-CORE-AOC-19-002 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:47) + - PREP-EXCITITOR-CORE-AOC-19-002-LINKSET-EXTRAC [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:28) +- EXCITITOR-CORE-AOC-19-003 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:48) + - PREP-EXCITITOR-CORE-AOC-19-003-BLOCKED-ON-19 [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:29) +- EXCITITOR-CORE-AOC-19-004 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:49) + - PREP-EXCITITOR-CORE-AOC-19-004-REMOVE-CONSENS [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:30) +- EXCITITOR-CORE-AOC-19-013 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:50) + - PREP-EXCITITOR-CORE-AOC-19-013-SEED-TENANT-AW [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:31) +- EXCITITOR-GRAPH-21-001 [BLOCKED (2025-10-27)] (SPRINT_0119_0001_0002_excititor_ii.md:51) + - PREP-EXCITITOR-GRAPH-21-001-NEEDS-CARTOGRAPHE [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:32) +- EXCITITOR-GRAPH-21-002 [BLOCKED (2025-10-27)] (SPRINT_0119_0001_0002_excititor_ii.md:52) + - PREP-EXCITITOR-GRAPH-21-002-BLOCKED-ON-21-001 [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:33) +- EXCITITOR-GRAPH-21-005 [BLOCKED (2025-10-27)] (SPRINT_0119_0001_0002_excititor_ii.md:53) + - PREP-EXCITITOR-GRAPH-21-005-BLOCKED-ON-21-002 [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:34) +- EXCITITOR-GRAPH-24-101 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:54) + - PREP-EXCITITOR-GRAPH-24-101-WAIT-FOR-21-005-I [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:35) +- EXCITITOR-GRAPH-24-102 [BLOCKED (2025-11-17)] (SPRINT_0119_0001_0002_excititor_ii.md:55) + - PREP-EXCITITOR-GRAPH-24-102-DEPENDS-ON-24-101 [TODO] (SPRINT_0119_0001_0002_excititor_ii.md:36) +- Console APIs [BLOCKED (await contract; LNM view spec needed)] (SPRINT_0119_0001_0002_excititor_ii.md:62) +- Ingestion idempotency [BLOCKED (linkset schema pending)] (SPRINT_0119_0001_0002_excititor_ii.md:63) +- Consensus removal [BLOCKED (depends on 19-002/003)] (SPRINT_0119_0001_0002_excititor_ii.md:64) +- Graph overlays [BLOCKED (awaiting Cartographer contract)] (SPRINT_0119_0001_0002_excititor_ii.md:65) + +# SPRINT_0120_0000_0001_policy_reasoning.md +- LEDGER-29-008 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:46) + - PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA [TODO] (SPRINT_0120_0000_0001_policy_reasoning.md:42) +- LEDGER-29-009 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:47) + - LEDGER-29-008 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:46) + - PREP-LEDGER-29-008-AWAIT-OBSERVABILITY-SCHEMA [TODO] (SPRINT_0120_0000_0001_policy_reasoning.md:42) +- LEDGER-34-101 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:48) + - PREP-LEDGER-34-101-ORCHESTRATOR-LEDGER-EXPORT [TODO] (SPRINT_0120_0000_0001_policy_reasoning.md:43) +- LEDGER-AIRGAP-56-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:49) + - PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM [TODO] (SPRINT_0120_0000_0001_policy_reasoning.md:44) +- LEDGER-AIRGAP-56-002 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:50) + - LEDGER-AIRGAP-56-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:49) + - PREP-LEDGER-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM [TODO] (SPRINT_0120_0000_0001_policy_reasoning.md:44) +- LEDGER-AIRGAP-57-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:51) + - LEDGER-AIRGAP-56-002 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:50) + - LEDGER-AIRGAP-56-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:49) + … +- LEDGER-AIRGAP-58-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:52) + - LEDGER-AIRGAP-57-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:51) + - LEDGER-AIRGAP-56-002 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:50) + … +- LEDGER-ATTEST-73-001 [BLOCKED] (SPRINT_0120_0000_0001_policy_reasoning.md:53) + - NOTIFY-ATTEST-74-001 [**DOING (2025-11-12)**] (SPRINT_171_notifier_i.md:10) + +# SPRINT_0123_0001_0001_policy_reasoning.md +- EXPORT-CONSOLE-23-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:38) + - PREP-EXPORT-CONSOLE-23-001-MISSING-EXPORT-BUN [TODO] (SPRINT_123_policy_reasoning.md:13) +- POLICY-AIRGAP-56-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:39) + - PREP-POLICY-AIRGAP-56-001-MIRROR-BUNDLE-SCHEM [TODO] (SPRINT_123_policy_reasoning.md:14) +- POLICY-AIRGAP-56-002 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:40) + - PREP-POLICY-AIRGAP-56-002-DEPENDS-ON-56-001-B [TODO] (SPRINT_123_policy_reasoning.md:15) +- POLICY-AIRGAP-57-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:41) + - PREP-POLICY-AIRGAP-57-001-REQUIRES-SEALED-MOD [TODO] (SPRINT_123_policy_reasoning.md:16) +- POLICY-AIRGAP-57-002 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:42) + - PREP-POLICY-AIRGAP-57-002-NEEDS-STALENESS-FAL [TODO] (SPRINT_123_policy_reasoning.md:17) +- POLICY-AIRGAP-58-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:43) + - PREP-POLICY-AIRGAP-58-001-NOTIFICATION-SCHEMA [TODO] (SPRINT_123_policy_reasoning.md:18) +- POLICY-AOC-19-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:44) + - PREP-POLICY-AOC-19-001-LINTING-TARGETS-SPEC-A [TODO] (SPRINT_0123_0001_0001_policy_reasoning.md:29) +- POLICY-AOC-19-002 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:45) + - PREP-POLICY-AOC-19-002-DEPENDS-ON-19-001-LINT [TODO] (SPRINT_123_policy_reasoning.md:20) +- POLICY-AOC-19-003 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:46) + - PREP-POLICY-AOC-19-003-REQUIRES-POST-19-002-N [TODO] (SPRINT_0123_0001_0001_policy_reasoning.md:31) +- POLICY-AOC-19-004 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:47) + - PREP-POLICY-AOC-19-004-DEPENDS-ON-19-003-SHAP [TODO] (SPRINT_0123_0001_0001_policy_reasoning.md:32) +- POLICY-ATTEST-73-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:48) + - PREP-POLICY-ATTEST-73-001-VERIFICATIONPOLICY [TODO] (SPRINT_0123_0001_0001_policy_reasoning.md:33) +- POLICY-ATTEST-73-002 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:49) + - PREP-POLICY-ATTEST-73-002-DEPENDS-ON-73-001-E [TODO] (SPRINT_123_policy_reasoning.md:24) +- POLICY-ATTEST-74-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:50) + - PREP-POLICY-ATTEST-74-001-REQUIRES-73-002-ATT [TODO] (SPRINT_0123_0001_0001_policy_reasoning.md:35) +- POLICY-ATTEST-74-002 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:51) + - PREP-POLICY-ATTEST-74-002-NEEDS-74-001-SURFAC [TODO] (SPRINT_123_policy_reasoning.md:26) +- POLICY-CONSOLE-23-001 [BLOCKED] (SPRINT_0123_0001_0001_policy_reasoning.md:52) + - PREP-POLICY-CONSOLE-23-001-CONSOLE-API-CONTRA [TODO] (SPRINT_0123_0001_0001_policy_reasoning.md:37) + +# SPRINT_0125_0001_0001_mirror.md +- MIRROR-CRT-56-001 [BLOCKED] (SPRINT_110_ingestion_evidence.md:46) +- MIRROR-CRT-56-002 [BLOCKED] (SPRINT_110_ingestion_evidence.md:47) +- MIRROR-CRT-57-001 [BLOCKED] (SPRINT_0125_0001_0001_mirror.md:26) + - MIRROR-CRT-56-001 [BLOCKED] (SPRINT_110_ingestion_evidence.md:46) +- MIRROR-CRT-57-002 [BLOCKED] (SPRINT_0125_0001_0001_mirror.md:27) + - MIRROR-CRT-56-002 [BLOCKED] (SPRINT_110_ingestion_evidence.md:47) + - AIRGAP-TIME-57-001 [BLOCKED] (SPRINT_0510_0001_0001_airgap.md:41) + - PREP-AIRGAP-TIME-57-001-TIME-COMPONENT-SCAFFO [TODO] (SPRINT_0510_0001_0001_airgap.md:29) +- MIRROR-CRT-58-001 [BLOCKED] (SPRINT_0125_0001_0001_mirror.md:28) + - MIRROR-CRT-56-002 [BLOCKED] (SPRINT_110_ingestion_evidence.md:47) + - CLI-AIRGAP-56-001 [TODO] (SPRINT_201_cli_i.md:14) +- MIRROR-CRT-58-002 [BLOCKED] (SPRINT_0125_0001_0001_mirror.md:29) + - MIRROR-CRT-56-002 [BLOCKED] (SPRINT_110_ingestion_evidence.md:47) + - EXPORT-OBS-54-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:38) + - EXPORT-OBS-53-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:37) + … +- EXPORT-OBS-51-001 / 54-001 [BLOCKED] (SPRINT_0125_0001_0001_mirror.md:30) + - MIRROR-CRT-56-001 [BLOCKED] (SPRINT_110_ingestion_evidence.md:46) +- AIRGAP-TIME-57-001 [BLOCKED] (SPRINT_0510_0001_0001_airgap.md:41) + - PREP-AIRGAP-TIME-57-001-TIME-COMPONENT-SCAFFO [TODO] (SPRINT_0510_0001_0001_airgap.md:29) +- CLI-AIRGAP-56-001 [TODO] (SPRINT_201_cli_i.md:14) +- PROV-OBS-53-001 [DONE (2025-11-17)] (SPRINT_513_provenance.md:10) + +# SPRINT_0125_0001_0001_policy_reasoning.md +- POLICY-ENGINE-29-003 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:35) + - PREP-POLICY-ENGINE-29-002-PATH-SCOPE-SCHEMA [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:20) +- POLICY-ENGINE-29-004 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:36) + - PREP-POLICY-ENGINE-29-004-DEPENDS-ON-29-003 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:21) +- POLICY-ENGINE-30-001 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:37) + - PREP-POLICY-ENGINE-30-001-NEEDS-29-004-OUTPUT [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:22) +- POLICY-ENGINE-30-002 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:38) + - PREP-POLICY-ENGINE-30-002-DEPENDS-ON-30-001 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:23) +- POLICY-ENGINE-30-003 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:39) + - PREP-POLICY-ENGINE-30-003-DEPENDS-ON-30-002 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:24) +- POLICY-ENGINE-30-101 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:40) + - PREP-POLICY-ENGINE-30-101-DEPENDS-ON-30-003 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:25) +- POLICY-ENGINE-31-001 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:41) + - PREP-POLICY-ENGINE-31-001-DEPENDS-ON-30-101 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:26) +- POLICY-ENGINE-31-002 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:42) + - PREP-POLICY-ENGINE-31-002-DEPENDS-ON-31-001 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:27) +- POLICY-ENGINE-32-101 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:43) + - PREP-POLICY-ENGINE-32-101-DEPENDS-ON-31-002 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:28) +- POLICY-ENGINE-33-101 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:44) + - PREP-POLICY-ENGINE-33-101-DEPENDS-ON-32-101 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:29) +- POLICY-ENGINE-34-101 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:45) + - PREP-POLICY-ENGINE-34-101-DEPENDS-ON-33-101 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:30) +- POLICY-ENGINE-35-201 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:46) + - PREP-POLICY-ENGINE-35-201-DEPENDS-ON-34-101 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:31) +- POLICY-ENGINE-38-201 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:47) + - PREP-POLICY-ENGINE-38-201-DEPENDS-ON-35-201 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:32) +- POLICY-ENGINE-40-001 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:48) + - PREP-POLICY-ENGINE-40-001-DEPENDS-ON-38-201 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:33) +- POLICY-ENGINE-40-002 [BLOCKED (2025-11-18)] (SPRINT_0125_0001_0001_policy_reasoning.md:49) + - PREP-POLICY-ENGINE-40-002-DEPENDS-ON-40-001 [TODO] (SPRINT_0125_0001_0001_policy_reasoning.md:34) + +# SPRINT_0138_0000_0001_scanner_ruby_parity.md +- SCANNER-ENG-0010 [BLOCKED] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:29) + - PREP-SCANNER-ENG-0010-AWAIT-COMPOSER-AUTOLOAD [TODO] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:22) +- SCANNER-ENG-0011 [BLOCKED] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:30) + - PREP-SCANNER-ENG-0011-NEEDS-DENO-RUNTIME-ANAL [TODO] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:23) +- SCANNER-ENG-0012 [BLOCKED] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:31) + - PREP-SCANNER-ENG-0012-DEFINE-DART-ANALYZER-RE [TODO] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:24) +- SCANNER-ENG-0013 [BLOCKED] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:32) + - PREP-SCANNER-ENG-0013-DRAFT-SWIFTPM-COVERAGE [TODO] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:25) +- SCANNER-ENG-0014 [BLOCKED] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:33) + - PREP-SCANNER-ENG-0014-NEEDS-JOINT-ROADMAP-WIT [TODO] (SPRINT_0138_0000_0001_scanner_ruby_parity.md:26) + +# SPRINT_0141_0001_0001_graph_indexer.md +- GRAPH-INDEX-28-007 [BLOCKED] (SPRINT_0141_0001_0001_graph_indexer.md:28) + - PREP-GRAPH-INDEX-28-006-OVERLAYS [TODO] (SPRINT_0141_0001_0001_graph_indexer.md:24) +- GRAPH-INDEX-28-008 [BLOCKED] (SPRINT_0141_0001_0001_graph_indexer.md:29) + - PREP-GRAPH-INDEX-28-008-UNBLOCK-AFTER-28-007 [TODO] (SPRINT_0141_0001_0001_graph_indexer.md:25) +- GRAPH-INDEX-28-009 [BLOCKED] (SPRINT_0141_0001_0001_graph_indexer.md:30) + - PREP-GRAPH-INDEX-28-009-DOWNSTREAM-OF-28-008 [TODO] (SPRINT_0141_0001_0001_graph_indexer.md:26) +- GRAPH-INDEX-28-010 [BLOCKED] (SPRINT_0141_0001_0001_graph_indexer.md:31) + - PREP-GRAPH-INDEX-28-010-NEEDS-OUTPUTS-FROM-28 [TODO] (SPRINT_0141_0001_0001_graph_indexer.md:27) + +# SPRINT_0156_0001_0002_scheduler_ii.md +- SCHED-WORKER-26-202 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:24) + - SCHED-WORKER-26-201 [BLOCKED] (SPRINT_0155_0001_0001_scheduler_i.md:35) + - SCHED-WORKER-25-102 [BLOCKED] (SPRINT_0155_0001_0001_scheduler_i.md:34) + … +- SCHED-WORKER-27-301 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:25) + - SCHED-WORKER-26-202 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:24) + - SCHED-WORKER-26-201 [BLOCKED] (SPRINT_0155_0001_0001_scheduler_i.md:35) + … +- SCHED-WORKER-27-302 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:26) + - SCHED-WORKER-27-301 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:25) + - SCHED-WORKER-26-202 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:24) + … +- SCHED-WORKER-27-303 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:27) + - SCHED-WORKER-27-302 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:26) + - SCHED-WORKER-27-301 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:25) + … +- SCHED-WORKER-29-001 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:28) + - SCHED-WORKER-27-303 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:27) + - SCHED-WORKER-27-302 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:26) + … +- SCHED-WORKER-29-002 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:29) + - SCHED-WORKER-29-001 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:28) + - SCHED-WORKER-27-303 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:27) + … +- SCHED-WORKER-29-003 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:30) + - SCHED-WORKER-29-002 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:29) + - SCHED-WORKER-29-001 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:28) + … +- SCHED-WORKER-CONSOLE-23-201 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:31) + - PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U [TODO] (SPRINT_0156_0001_0002_scheduler_ii.md:22) +- SCHED-WORKER-CONSOLE-23-202 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:32) + - SCHED-WORKER-CONSOLE-23-201 [BLOCKED] (SPRINT_0156_0001_0002_scheduler_ii.md:31) + - PREP-SCHED-WORKER-CONSOLE-23-201-BLOCKED-BY-U [TODO] (SPRINT_0156_0001_0002_scheduler_ii.md:22) + +# SPRINT_0160_0001_0001_export_evidence.md +- 160.C TimelineIndexer snapshot [BLOCKED] (SPRINT_0160_0001_0001_export_evidence.md:32) + - TIMELINE-OBS-52-001 [TODO] (SPRINT_165_timelineindexer.md:10) + +# SPRINT_0161_0001_0001_evidencelocker.md +- EVID-REPLAY-187-001 [TODO] (SPRINT_187_evidence_locker_cli_integration.md:9) +- CLI-REPLAY-187-002 [TODO] (SPRINT_187_evidence_locker_cli_integration.md:10) +- RUNBOOK-REPLAY-187-004 [TODO] (SPRINT_187_evidence_locker_cli_integration.md:12) + +# SPRINT_0163_0001_0001_exportcenter_ii.md +- EXPORT-OAS-63-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:33) + - EXPORT-OAS-61-001 [BLOCKED] (SPRINT_0162_0001_0001_exportcenter_i.md:47) + - PREP-EXPORT-OAS-61-001-NEEDS-STABLE-EXPORT-SU [TODO] (SPRINT_0162_0001_0001_exportcenter_i.md:33) + - EXPORT-OAS-62-001 [BLOCKED] (SPRINT_0162_0001_0001_exportcenter_i.md:49) + - PREP-EXPORT-OAS-62-001-DEPENDS-ON-61-002 [TODO] (SPRINT_0162_0001_0001_exportcenter_i.md:35) +- EXPORT-OBS-50-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:34) + - PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:23) +- EXPORT-OBS-51-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:35) + - EXPORT-OBS-50-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:34) + - PREP-EXPORT-OBS-50-001-WAIT-FOR-EXPORTER-SERV [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:23) +- EXPORT-OBS-52-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:36) + - EXPORT-OBS-51-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:35) + - EXPORT-OBS-50-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:34) + … + - PREP-EXPORT-NOTIFY-SCHEMA-OBS-52 [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:30) +- EXPORT-OBS-53-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:37) + - EXPORT-OBS-52-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:36) + - EXPORT-OBS-51-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:35) + … + - PREP-EXPORT-NOTIFY-SCHEMA-OBS-52 [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:30) +- EXPORT-OBS-54-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:38) + - EXPORT-OBS-53-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:37) + - EXPORT-OBS-52-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:36) + … +- EXPORT-OBS-54-002 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:39) + - EXPORT-OBS-54-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:38) + - EXPORT-OBS-53-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:37) + … + - PROV-OBS-53-003 [BLOCKED] (SPRINT_513_provenance.md:12) +- EXPORT-OBS-55-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:40) + - EXPORT-OBS-54-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:38) + - EXPORT-OBS-53-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:37) + … +- EXPORT-RISK-69-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:41) + - PREP-EXPORT-RISK-69-001-AWAIT-PHASE-I-ARTIFAC [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:24) +- EXPORT-RISK-69-002 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:42) + - EXPORT-RISK-69-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:41) + - PREP-EXPORT-RISK-69-001-AWAIT-PHASE-I-ARTIFAC [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:24) +- EXPORT-RISK-70-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:43) + - EXPORT-RISK-69-002 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:42) + - EXPORT-RISK-69-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:41) + … +- EXPORT-SVC-35-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:44) + - PREP-EXPORT-SVC-35-001-NEEDS-PHASE-I-READINES [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:25) +- EXPORT-SVC-35-002 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:45) + - PREP-EXPORT-SVC-35-002-DEPENDS-ON-35-001 [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:26) +- EXPORT-SVC-35-003 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:46) + - PREP-EXPORT-SVC-35-003-DEPENDS-ON-35-002 [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:27) +- EXPORT-SVC-35-004 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:47) + - PREP-EXPORT-SVC-35-004-DEPENDS-ON-35-003 [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:28) +- EXPORT-SVC-35-005 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:48) + - PREP-EXPORT-SVC-35-005-DEPENDS-ON-35-004 [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:29) +- EXPORT-CRYPTO-90-001 [BLOCKED] (SPRINT_0163_0001_0001_exportcenter_ii.md:49) + - PREP-EXPORT-CRYPTO-90-001-PENDING-NOV-18-CRYP [TODO] (SPRINT_0163_0001_0001_exportcenter_ii.md:31) + +# SPRINT_0171_0001_0001_notifier_i.md +- NOTIFY-OBS-51-001 [TODO] (SPRINT_171_notifier_i.md:16) + +# SPRINT_0174_0001_0001_telemetry.md +- TELEMETRY-OBS-50-002 [TODO] (SPRINT_174_telemetry.md:11) + - TELEMETRY-OBS-50-001 [**DOING (2025-11-12)**] (SPRINT_174_telemetry.md:10) +- TELEMETRY-OBS-51-001 [TODO] (SPRINT_174_telemetry.md:12) + - TELEMETRY-OBS-50-002 [TODO] (SPRINT_174_telemetry.md:11) + - TELEMETRY-OBS-50-001 [**DOING (2025-11-12)**] (SPRINT_174_telemetry.md:10) +- TELEMETRY-OBS-51-002 [TODO] (SPRINT_174_telemetry.md:13) + - TELEMETRY-OBS-51-001 [TODO] (SPRINT_174_telemetry.md:12) + - TELEMETRY-OBS-50-002 [TODO] (SPRINT_174_telemetry.md:11) + … +- TELEMETRY-OBS-55-001 [TODO] (SPRINT_174_telemetry.md:14) + - TELEMETRY-OBS-51-002 [TODO] (SPRINT_174_telemetry.md:13) + - TELEMETRY-OBS-51-001 [TODO] (SPRINT_174_telemetry.md:12) + … +- TELEMETRY-OBS-56-001 [TODO] (SPRINT_174_telemetry.md:15) + - TELEMETRY-OBS-55-001 [TODO] (SPRINT_174_telemetry.md:14) + - TELEMETRY-OBS-51-002 [TODO] (SPRINT_174_telemetry.md:13) + … + +# SPRINT_0215_0001_0001_web_iv.md +- WEB-POLICY-23-001 [BLOCKED (2025-10-29)] (SPRINT_0215_0001_0001_web_iv.md:30) + - WEB-POLICY-20-004 [TODO] (SPRINT_0215_0001_0001_web_iv.md:29) + - WEB-POLICY-20-003 [TODO] (SPRINT_0215_0001_0001_web_iv.md:28) + … +- WEB-POLICY-23-002 [BLOCKED (2025-10-29)] (SPRINT_0215_0001_0001_web_iv.md:31) + - WEB-POLICY-23-001 [BLOCKED (2025-10-29)] (SPRINT_0215_0001_0001_web_iv.md:30) + - WEB-POLICY-20-004 [TODO] (SPRINT_0215_0001_0001_web_iv.md:29) + … + +# SPRINT_0509_0001_0001_samples.md +- SAMPLES-LNM-22-001 [BLOCKED] (SPRINT_0509_0001_0001_samples.md:26) + - PREP-SAMPLES-LNM-22-001-WAITING-ON-FINALIZED [TODO] (SPRINT_0509_0001_0001_samples.md:22) +- SAMPLES-LNM-22-002 [BLOCKED] (SPRINT_0509_0001_0001_samples.md:27) + - PREP-SAMPLES-LNM-22-002-DEPENDS-ON-22-001-OUT [TODO] (SPRINT_0509_0001_0001_samples.md:23) + +# SPRINT_0512_0001_0001_bench.md +- BENCH-GRAPH-21-001 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:28) + - PREP-BENCH-GRAPH-21-001-NEED-GRAPH-BENCH-HARN [TODO] (SPRINT_0512_0001_0001_bench.md:22) +- BENCH-GRAPH-21-002 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:29) + - PREP-BENCH-GRAPH-21-002-BLOCKED-ON-21-001-HAR [TODO] (SPRINT_0512_0001_0001_bench.md:23) +- BENCH-GRAPH-24-002 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:30) + - SAMPLES-GRAPH-24-003 [DOING] (SPRINT_0509_0001_0001_samples.md:24) +- BENCH-IMPACT-16-001 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:31) + - PREP-BENCH-IMPACT-16-001-IMPACT-INDEX-DATASET [TODO] (SPRINT_0512_0001_0001_bench.md:24) +- BENCH-POLICY-20-002 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:32) + - PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE [TODO] (SPRINT_0512_0001_0001_bench.md:25) +- BENCH-SIG-26-001 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:33) + - PREP-BENCH-SIG-26-001-REACHABILITY-SCHEMA-FIX [TODO] (SPRINT_0512_0001_0001_bench.md:26) +- BENCH-SIG-26-002 [BLOCKED] (SPRINT_0512_0001_0001_bench.md:34) + - PREP-BENCH-SIG-26-002-BLOCKED-ON-26-001-OUTPU [TODO] (SPRINT_0512_0001_0001_bench.md:27) diff --git a/docs/implplan/build-harness-110.md b/docs/implplan/build-harness-110.md new file mode 100644 index 000000000..9a0d8fd03 --- /dev/null +++ b/docs/implplan/build-harness-110.md @@ -0,0 +1,19 @@ +# Build Harness · Sprint 110 + +## Goal +Provide a repeatable runner profile for Concelier `/linksets` tests that avoids harness `workdir:` injection and preserves test DLLs for CI. + +## Script +- `tools/linksets-ci.sh` (uses existing `tools/dotnet-filter.sh`) +- Environment: `VSTEST_DISABLE_APPDOMAIN=1`, `DOTNET_CLI_UI_LANGUAGE=en` +- Results: `out/test-results/linksets/linksets.trx` + +## Invocation +``` +./tools/linksets-ci.sh +``` + +## Notes +- Runs `--filter Linksets` on `StellaOps.Concelier.WebService.Tests.csproj` with `--no-build`; ensure a preceding `dotnet build` in CI to emit the test DLLs. +- No `workdir:` arg is passed; `dotnet-filter.sh` strips any accidental injection. +- Determinism: results directory fixed; AppDomain disabled to avoid flaky sourcing; logs in TRX for gating. diff --git a/docs/modules/authority/fixtures/auth-ten-47-001.json b/docs/modules/authority/fixtures/auth-ten-47-001.json new file mode 100644 index 000000000..45023aefa --- /dev/null +++ b/docs/modules/authority/fixtures/auth-ten-47-001.json @@ -0,0 +1,15 @@ +{ + "tenantId": "urn:tenant:00000000-0000-0000-0000-000000000000", + "issuer": "https://auth.stellaops.local", + "scopes": ["concelier.read", "concelier.linkset.write"], + "capabilities": { + "mergeAllowed": false, + "offlineAllowed": true + }, + "attribution": { + "actor": "service:concelier-web", + "traceId": "00000000000000000000000000000000" + }, + "issuedAt": "2025-11-19T00:00:00Z", + "expiresAt": "2025-11-20T00:00:00Z" +} diff --git a/docs/modules/authority/tenant-scope-47-001.md b/docs/modules/authority/tenant-scope-47-001.md new file mode 100644 index 000000000..91b4ca365 --- /dev/null +++ b/docs/modules/authority/tenant-scope-47-001.md @@ -0,0 +1,36 @@ +# AUTH-TEN-47-001 · Tenant Scope Contract (v1) + +Purpose: define tenant scoping fields and enforcement expectations so Concelier tasks (CONCELIER-TEN-48-001) can proceed without merging behavior. + +## Data contract +- `tenantId` (string, required): immutable per request; canonical form `urn:tenant:{uuid}`. +- `issuer` (string, required): authority instance issuing the token; aids audit. +- `scopes` (array, required): must include `concelier.read` or `concelier.linkset.read` for evidence fetch; `concelier.linkset.write` for backfill/ingest; `concelier.tenant.admin` for tenancy capabilities endpoint. +- `capabilities` (object, optional): + - `mergeAllowed` (bool, default false): must remain false for Link-Not-Merge paths. + - `offlineAllowed` (bool, default true): governs offline bundle use. +- `attribution` (object, optional): + - `actor` (string): subject or client-id. + - `traceId` (string): optional trace correlation. +- `issuedAt` (string, ISO-8601 UTC), `expiresAt` (string, ISO-8601 UTC): required for enforcement. + +## Enforcement rules (Authority) +- Tokens missing `tenantId` or `concelier.*` scopes are rejected with 403 and error code `auth/tenant-scope-missing`. +- `mergeAllowed` must be evaluated server-side; clients cannot set true when Link-Not-Merge mode is active. +- Refresh/rotation must preserve `tenantId`; changing tenant requires re-auth. + +## Fixtures +- JSON fixture: `docs/modules/authority/fixtures/auth-ten-47-001.json` (included) shows a minimal token payload. +- Determinism: field order canonicalized lexicographically for hashing; timestamps normalized to `Z`. + +## Actions for consumers (Concelier) +- Validate `tenantId` present and stable across request and event emission. +- Expose `/capabilities/tenant` endpoint echoing `tenantId`, scopes, and `mergeAllowed=false` when LNM is enabled. +- Log `tenantId`, `actor`, and `traceId` on every linkset backfill or advisory read for audit. + +## Owners +- Authority Guild (contract) +- Concelier Core Guild (consumer) + +## Change control +- Add-only evolution. New capabilities must default to the most restrictive value. diff --git a/docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md b/docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md new file mode 100644 index 000000000..f993debd2 --- /dev/null +++ b/docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md @@ -0,0 +1,29 @@ +# CLI Guardrail Artefacts (2025-11-19) + +## CLI-VULN-29-001 artefacts +- Output bundle: `out/console/guardrails/cli-vuln-29-001/` +- Files: + - `sample-vuln-output.ndjson` — sample `stella vuln scan` output (offline profile, two CVEs, includes provenance and summary). + - `sample-sbom-context.json` — SBOM context export referenced by DOCS-AIAI-31-005/006/008/009. + - `hashes.sha256` — SHA256 for all files in folder. +- Hashes (duplicate of hashes file for convenience): +``` +421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18 out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json +e5aecfba5cee8d412408fb449f12fa4d5bf0a7cb7e5b316b99da3b9019897186 out/console/guardrails/cli-vuln-29-001/sample-vuln-output.ndjson +``` + +## CLI-VEX-30-001 artefacts +- Output bundle: `out/console/guardrails/cli-vex-30-001/` +- Files: + - `sample-vex-output.ndjson` — sample `stella vex export` output with single not_affected statement. + - `sample-pagination-note.txt` — paging/limit note (default 500, max 2000; cursor via --page-token). + - `hashes.sha256` — SHA256 for all files in folder. +- Hashes: +``` +f450d914dfe5c8d80f773c1fd0113bbba921aca339316c6308f1c098199aef6b out/console/guardrails/cli-vex-30-001/sample-pagination-note.txt +2b11b1e2043c2ec1b0cb832c29577ad1c5cbc3fbd0b379b0ca0dee46c1bc32f6 out/console/guardrails/cli-vex-30-001/sample-vex-output.ndjson +``` + +## Notes +- Samples are deterministic; generated timestamp `2025-11-19T00:00:00Z`. +- Replace with live artefacts once CLI commands are executed against frozen datasets; keep paths/hashes updated here and in sprint logs. diff --git a/docs/modules/concelier/bridges/vuln-29-001.md b/docs/modules/concelier/bridges/vuln-29-001.md new file mode 100644 index 000000000..7a41ef37d --- /dev/null +++ b/docs/modules/concelier/bridges/vuln-29-001.md @@ -0,0 +1,81 @@ +# CONCELIER-VULN-29-001 · Concelier ↔ Vuln Explorer bridge (contract v0.1) + +Purpose: unblock PREP-CONCELIER-VULN-29-001 by defining the request/response contract Concelier must expose for Vuln Explorer and VEX Lens to consume advisory evidence without merge semantics. + +## API shape (Concelier WebService) +- Endpoint: `POST /v1/advisories/search` +- Auth: tenant-scoped token (`concelier.read` scope) with `mergeAllowed=false`. +- Request body: + ```json + { + "query": { + "advisory_keys": ["GHSA-xxxx-xxxx"], + "purls": ["pkg:maven/org.example/app@1.2.3"], + "component_hashes": ["sha256:..."], + "has_vex": true + }, + "page": { + "size": 50, + "cursor": null + } + } + ``` +- Response body: + ```json + { + "results": [ + { + "advisory_key": "GHSA-xxxx-xxxx", + "source": "ghsa", + "observations": [{ + "id": "obs-123", + "purl": "pkg:maven/org.example/app@1.2.3", + "version_range": "[1.2.0,2.0.0)", + "status": "affected", + "published": "2025-11-01T00:00:00Z", + "fixed": null, + "provenance": { + "source": "ghsa", + "retrieved_at": "2025-11-18T12:00:00Z", + "hash": "sha256:..." + } + }], + "vex": [{ + "statement_id": "st-001", + "status": "not_affected", + "justification": "component_not_present", + "impact_statement": "Library not shipped", + "provenance": { + "source": "vendor-vex", + "retrieved_at": "2025-11-18T12:00:00Z", + "hash": "sha256:..." + } + }] + } + ], + "page": {"cursor": "next-token", "size": 50} + } + ``` + +## Determinism requirements +- Sort observations by `purl`, then `published`, then `id`. +- Sort VEX statements by `statement_id`. +- Timestamps UTC ISO-8601 with `Z`. +- Omit merge-derived fields; only surface source-provided values. + +## Fields Vuln Explorer expects +- `advisory_key`, `source`, `observations[*].purl`, `observations[*].status`, `observations[*].provenance.hash`. +- VEX fields: `status`, `justification`, `impact_statement`, `provenance.hash`. +- Optional: `fix_version` when present; keep absent otherwise (no empty strings). + +## Test fixtures +- Location: `docs/samples/console/console-vex-30-001.json` already includes VEX sample keyed by advisory; add Concelier response sample to `docs/samples/console/concelier-vuln-29-001.json` (to be generated alongside implementation). + +## Owners +- Concelier WebService Guild (producer) +- Vuln Explorer Guild / VEX Lens Guild (consumers) + +## Next actions to unblock work +- Implement endpoint stub with deterministic ordering and fixture from above sample. +- Hook to Link-Not-Merge storage (fact-only) once available. +- Add contract reference to OAS (Sprint 0114 CONCELIER-OAS-61-001 depends on this). diff --git a/docs/modules/concelier/feeds/icscisa-kisa-provenance.md b/docs/modules/concelier/feeds/icscisa-kisa-provenance.md new file mode 100644 index 000000000..e39922a5c --- /dev/null +++ b/docs/modules/concelier/feeds/icscisa-kisa-provenance.md @@ -0,0 +1,7 @@ +# ICSCISA / KISA Feed Provenance Notes (2025-11-19) + +- Expected signing: not provided by sources; set `signature=null` and `skip_reason="unsigned"`. +- Hashing: sha256 of raw advisory payload before normalization. +- Transport: HTTPS; mirror to internal cache; record `fetched_at` UTC and `source_url`. +- Verification: compare hash vs previous run; emit delta report. +- Staleness guard: alert if `fetched_at` >14 days. diff --git a/docs/modules/concelier/feeds/icscisa-kisa.md b/docs/modules/concelier/feeds/icscisa-kisa.md new file mode 100644 index 000000000..b3a0d4563 --- /dev/null +++ b/docs/modules/concelier/feeds/icscisa-kisa.md @@ -0,0 +1,46 @@ +# ICSCISA / KISA Feed Remediation Plan (v0.1 · 2025-11-19) + +## Purpose +Define a minimal, actionable plan to refresh overdue ICSCISA and KISA connectors, restore provenance freshness, and publish normalized payload fields for downstream Advisory AI and Concelier consumers. + +## Owners +- Feed owners: Concelier Feed Guild +- Product advisory liaison: Product Advisory Guild +- Backup: Docs Guild + +## Scope & cadence +- Feeds: ICSCISA, KISA (security advisories) +- Refresh cadence: weekly pull; publish hashlist and timestamps per run +- Staleness budget: <14 days; alert if exceeded + +## Deliverables (for PREP-FEEDCONN-ICS-KISA-PLAN) +1) **Provenance refresh SOP** + - Mirror source URLs to internal cache + - Record `source_url`, `fetched_at` (UTC), `sha256`, `signature` (if present) + - Store run log under `out/feeds/icscisa-kisa//fetch.log` +2) **Normalized payload fields** + - `advisory_id`, `title`, `summary`, `published`, `updated`, `severity` (pass-through), `cvss` (if provided), `cwe`, `affected_products` (list), `references` (list of URL strings), `signature` (object or null) + - Preserve source values; no inference or merging +3) **Backlog cleanup** + - Reprocess last 60 days; compare hash to prior ingests; flag changed advisories + - Emit delta report (`out/feeds/icscisa-kisa//delta.json`): added/updated/removed ids, counts +4) **Provenance note** + - Publish `docs/modules/concelier/feeds/icscisa-kisa-provenance.md` with current signing keys/fingerprints, expected headers, and fallback when signatures missing +5) **Next review date** + - Set to 2025-12-03 (two-week check) and capture SIG verification status + +## Actions & timeline +- T0 (2025-11-19): adopt SOP + field map; create delta report template +- T0+2d (2025-11-21): run backlog reprocess, publish artefacts + hashes +- T0+14d (2025-12-03): review staleness, adjust cadence if needed + +## Artefact locations +- Normalized advisories: `out/feeds/icscisa-kisa//advisories.ndjson` +- Fetch log + hashes: `out/feeds/icscisa-kisa//fetch.log`, `hashes.sha256` +- Delta report: `out/feeds/icscisa-kisa//delta.json` +- Provenance note: `docs/modules/concelier/feeds/icscisa-kisa-provenance.md` + +## Risks & mitigations +- Source downtime → mirror last good snapshot; retry daily for 3 days. +- Missing signatures → record `signature=null`, log `skip_reason` in provenance note; do not infer validity. +- Schema drift → treat as new fields, store raw, add to field map after review (no drop). diff --git a/docs/modules/concelier/operations/cache.md b/docs/modules/concelier/operations/cache.md new file mode 100644 index 000000000..8b8f957cb --- /dev/null +++ b/docs/modules/concelier/operations/cache.md @@ -0,0 +1,40 @@ +# Concelier Advisory Chunk Cache + +Status: draft · aligned with LNM v1 (frozen 2025-11-17) + +## Purpose +- Reduce repeated `/advisories/{key}/chunks` rebuilds while preserving determinism and provenance integrity. +- Provide consoles and debugging tools with transparent cache provenance (key material and TTL) to keep evidence chains auditable. + +## Cache key (deterministic) +- Inputs (pipe-delimited, all lower-case where applicable): + - `tenant` + - `advisoryKey` + - `chunkLimit` + - `observationLimit` + - `minimumLength` + - `sectionFilter` (sorted, case-insensitive) + - `formatFilter` (sorted, case-insensitive) + - advisory fingerprint (hash of canonical advisory) + - ordered observations: each `observationId@contentHash@createdAtTicks@format` +- Implementation: `AdvisoryChunkCacheKey.Create` (WebService). Normalized ordering ensures replayability across nodes. +- External disclosure: headers expose a hashed cache key (see below) rather than the full raw key. + +## Response transparency headers +- `X-Stella-Cache-Key`: SHA-256 hex of the cache key (default 16 chars) for tamper-evident correlation. +- `X-Stella-Cache-Hit`: `1` on hit, `0` on miss. +- `X-Stella-Cache-Ttl`: configured TTL in seconds (0 when caching disabled). +- Consumers may log these headers; do **not** treat them as stable API contract for filtering. + +## Determinism & safety +- No PII in keys or headers; key inputs are tenant/advisory identifiers already present in requests. +- Timestamps use UTC ticks; content hashes retain upstream digest prefix (e.g., `sha256:`) to distinguish sources. +- Cache TTL defaults to 0 (disabled) unless configured; safe for offline/air-gapped deployments. + +## Testing notes +- Unit coverage: `AdvisoryChunkCacheKeyTests` (ordering, filter casing) and `AdvisoryChunkBuilderTests` (observationPath pointers influence chunk IDs). +- Integration tests should assert headers when cache is enabled; disable cache for tests that assert body-only determinism. + +## TODOs / follow-ups +- Add integration test that exercises a cache hit path and validates transparency headers. +- Document cache configuration knobs in `appsettings.*` once finalized. diff --git a/docs/modules/evidence-locker/attestation-scope-note.md b/docs/modules/evidence-locker/attestation-scope-note.md new file mode 100644 index 000000000..e03bb119f --- /dev/null +++ b/docs/modules/evidence-locker/attestation-scope-note.md @@ -0,0 +1,37 @@ +# Evidence Locker Attestation Scope Note (v1) — 2025-11-19 + +## Scope & Coverage +- Predicates: `in-toto Provenance` (DSSE-wrapped) with claims for bundle inputs, normalization pipeline version, tenant scope, and content hashes; optional `Rekor` transparency pointer when online. +- Artefacts covered: Evidence Bundle v1 payloads (observations, linksets, normalization diffs) and mirror bundle manifest hash when present. +- Tenancy: tenant-id is lowercased, required, and included in subject, claims, and DSSE `_type` to keep air-gap parity. +- Transparency: if Rekor unavailable (air-gap), include `transparency.skip_reason` = `offline` and signed local timeline anchor. + +## Required claims (PromotionAttestationBuilder input) +- `subject.digest` (sha256 of bundle tar) and `subject.name` (bundle_id). +- `bundle.created` (UTC RFC3339) and `bundle.version` (semantic). +- `pipeline.version` (build ID or git SHA) and `pipeline.inputs` (hashes of observation/linkset payloads). +- `tenant` (lowercase) and `scope` (advisory | vex | policy | mixed). +- `evidence_bundle` (path/doi) and `transparency` (rekor UUID or skip reason). +- `aoc.guardrails` (boolean) and `aoc.details` (list of enforced checks). + +## Example builder payload +```json +{ + "subject": {"name": "evidence-bundle-m0", "digest": "sha256:REPLACE"}, + "bundle": {"id": "evidence-bundle-m0", "version": "1.0.0", "created": "2025-11-19T00:00:00Z"}, + "pipeline": {"version": "git:abcd1234", "inputs": ["sha256:payload-hash-1", "sha256:payload-hash-2"]}, + "tenant": "demo", + "scope": "vex", + "evidence_bundle": "out/evidence/bundles/evidence-bundle-m0.tar.gz", + "transparency": {"rekor_uuid": null, "skip_reason": "offline"}, + "aoc": {"guardrails": true, "details": ["schema:frozen:1.0", "limits:chunk:max=2000"]} +} +``` + +## Placement +- File: `docs/modules/evidence-locker/attestation-scope-note.md` (this document). +- Reference in Evidence Bundle changelog and sprint `Execution Log` when updated. + +## Next steps +- Swap placeholder digest values with real bundle hash after MIRROR-CRT-56-001 emits artefact. +- Attach this note to Concelier/Excititor attestation tasks (CONCELIER-ATTEST-73-001/002, EXCITITOR-ATTEST-73-001/002). diff --git a/docs/modules/evidence-locker/evidence-bundle-v1.md b/docs/modules/evidence-locker/evidence-bundle-v1.md new file mode 100644 index 000000000..1e396f981 --- /dev/null +++ b/docs/modules/evidence-locker/evidence-bundle-v1.md @@ -0,0 +1,57 @@ +# Evidence Bundle v1 Contract (2025-11-19) + +## Scope +Frozen contract for Evidence Bundle v1 covering AdvisoryAI/Concelier/Excititor evidence exports used by air-gap and attestation flows. + +## Artefact layout +- Tarball name: `evidence-bundle-.tar.gz` +- Manifest (required): `manifest.json` +- Payloads (required): `observations.ndjson`, `linksets.ndjson` +- Optional: `timeline.ndjson` (time anchors), `transparency.json` (Rekor UUID or skip_reason) +- Hash list: `hashes.sha256` (sha256 of each file) + +### manifest.json fields +```json +{ + "bundle_id": "evidence-bundle-m0", + "version": "1.0.0", + "created": "2025-11-19T00:00:00Z", + "tenant": "demo", + "scope": "vex", + "inputs": ["sha256:payload-obs", "sha256:payload-linksets"], + "aoc": {"guardrails": true, "details": ["schema:frozen:1.0", "limits:chunk:max=2000"]} +} +``` + +### observations.ndjson (sample record) +```json +{"observationId":"obs-ossl-001","advisoryId":"CVE-2024-1234","component":"pkg:deb/openssl@1.1.1w","source":"nvd","fetchedAt":"2025-11-18T12:00:00Z"} +``` + +### linksets.ndjson (sample record) +```json +{"linksetId":"lnm-ossl-001","advisoryId":"CVE-2024-1234","components":["pkg:deb/openssl@1.1.1w"],"normalized":true,"createdAt":"2025-11-18T12:05:00Z"} +``` + +### transparency.json (optional) +```json +{"rekor_uuid": null, "skip_reason": "offline"} +``` + +## Determinism rules +- All timestamps must be UTC RFC3339. +- Ordering: sort NDJSON by `advisoryId`, then `component`, ascending. +- Hashes: compute sha256 on raw file bytes; record in `hashes.sha256` and in manifest `inputs`. +- Tenant must be lowercase; include in manifest and any attestation subject claims. + +## Example bundle (sample) +- Path: `docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz` +- SHA256: `$(cat docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz.sha256 | awk '{print $1}')` +- Contains sample manifest/observations/linksets/transparency per above. + +## Attestation linkage +- See `attestation-scope-note.md` for required claims. +- Subject digest should reference the tarball sha256; include `bundle_id` and `tenant`. + +## Change log +- 2025-11-19: v1 frozen (initial publication). Add real sample tarball + hashes once produced. diff --git a/docs/modules/excititor/evidence-contract.md b/docs/modules/excititor/evidence-contract.md index 02fa484ab..bfb35c5d0 100644 --- a/docs/modules/excititor/evidence-contract.md +++ b/docs/modules/excititor/evidence-contract.md @@ -85,5 +85,8 @@ This note defines the deterministic, aggregation-only contract that Excititor ex - When mirror bundles are configured, `provenance.canonicalUri` points to the local bundle path; otherwise it is omitted. - All payloads are side-effect free; no remote fetches occur while streaming. +## Samples +- NDJSON sample: `docs/samples/excititor/chunks-sample.ndjson` (hashes in `.sha256`) aligned to the schema above. + ## Versioning - Contract version: `v1` (this document). Changes must be additive; breaking changes require `v2` path and updated doc. diff --git a/docs/modules/excititor/vex_linksets_api.md b/docs/modules/excititor/vex_linksets_api.md new file mode 100644 index 000000000..0b1fbc226 --- /dev/null +++ b/docs/modules/excititor/vex_linksets_api.md @@ -0,0 +1,104 @@ +# Excititor VEX linkset APIs (observations + linksets) + +> Draft examples for Sprint 119 (EXCITITOR-LNM-21-203). Aligns with WebService endpoints implemented in `src/Excititor/StellaOps.Excititor.WebService/Program.cs`. + +## /v1/vex/observations + +### List +``` +GET /v1/vex/observations?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&providerId=ubuntu-csaf&status=affected&limit=2 +Headers: + Authorization: Bearer + X-Tenant: default +Response 200 (application/json): +{ + "items": [ + { + "tenant": "default", + "observationId": "vex:obs:sha256:...", + "providerId": "ubuntu-csaf", + "document": { + "digest": "sha256:...", + "uri": "https://example.com/csaf/1.json", + "signature": null + }, + "scope": { + "vulnerabilityId": "CVE-2024-0001", + "productKey": "pkg:maven/org.demo/app@1.2.3" + }, + "statements": [ + { + "vulnerabilityId": "CVE-2024-0001", + "productKey": "pkg:maven/org.demo/app@1.2.3", + "status": "affected", + "justification": { + "type": "component_not_present", + "reason": "Not shipped in base profile" + }, + "signals": { "severity": { "score": 7.5 } }, + "provenance": { + "providerId": "ubuntu-csaf", + "sourceId": "USN-9999-1", + "fieldMasks": ["statements"] + } + } + ], + "linkset": { + "aliases": ["USN-9999-1"], + "purls": ["pkg:maven/org.demo/app"], + "cpes": [], + "references": [{"type": "advisory", "url": "https://..."}], + "disagreements": [] + }, + "createdAt": "2025-11-18T12:34:56Z" + } + ], + "nextCursor": "eyJ2dWxuZXJhYmlsaXR5SWQiOiJDVkUtMjAyNC0wMDAxIiwiY3JlYXRlZEF0IjoiMjAyNS0xMS0xOFQxMjozNDo1NloifQ==" +} +``` + +### Get by key +``` +GET /v1/vex/observations/CVE-2024-0001/pkg:maven/org.demo/app@1.2.3 +Headers: Authorization + X-Tenant +Response 200: same projection shape as list items (single object). +``` + +## /v1/vex/linksets +``` +GET /v1/vex/linksets?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&status=affected&limit=2 +Headers: Authorization + X-Tenant +Response 200: +{ + "items": [ + { + "linksetId": "CVE-2024-0001:pkg:maven/org.demo/app@1.2.3", + "tenant": "default", + "vulnerabilityId": "CVE-2024-0001", + "productKey": "pkg:maven/org.demo/app@1.2.3", + "providers": ["ubuntu-csaf", "suse-csaf"], + "statuses": ["affected", "fixed"], + "aliases": ["USN-9999-1"], + "purls": ["pkg:maven/org.demo/app"], + "cpes": [], + "references": [{"type": "advisory", "url": "https://..."}], + "disagreements": [{"providerId": "suse-csaf", "status": "fixed", "justification": null, "confidence": null}], + "observations": [ + {"observationId": "vex:obs:...", "providerId": "ubuntu-csaf", "status": "affected", "severity": 7.5}, + {"observationId": "vex:obs:...", "providerId": "suse-csaf", "status": "fixed", "severity": null} + ], + "createdAt": "2025-11-18T12:34:56Z" + } + ], + "nextCursor": null +} +``` + +## Notes +- Pagination: `limit` (default 200, max 500) + `cursor` (opaque base64 of `vulnerabilityId` + `createdAt`). +- Filters: `vulnerabilityId`, `productKey`, `providerId`, `status`; multiple query values allowed. +- Headers: `Excititor-Results-Count`, `Excititor-Results-Cursor` (observations) and `Excititor-Results-Total` / `Excititor-Results-Truncated` (chunks) already implemented. +- Determinism: responses sorted by `vulnerabilityId`, then `productKey`; arrays sorted lexicographically. + +## SDK generation +- Use this file plus `vex_observations.md` as the source of truth for SDK examples in EXCITITOR-LNM-21-203. diff --git a/docs/modules/mirror/milestone-0-thin-bundle.md b/docs/modules/mirror/milestone-0-thin-bundle.md new file mode 100644 index 000000000..1dba5e860 --- /dev/null +++ b/docs/modules/mirror/milestone-0-thin-bundle.md @@ -0,0 +1,30 @@ +# Mirror Thin Bundle · Milestone 0 (sample) + +## Scope +- Provide a deterministic placeholder thin bundle so downstream air-gap/console/attestation tracks can wire references while MIRROR-CRT-56-001 code lands. +- Sample bundle published at `out/mirror/thin/mirror-thin-m0-sample.tar.gz` (created 2025-11-19 UTC) with fixed metadata only; no advisories/policies/images included. + +## Owners +- Primary: Alex Kim +- Backup: Priya Desai + +## Artefacts +- Bundle: `out/mirror/thin/mirror-thin-m0-sample.tar.gz` +- SHA256: `bd1013885a27f651e28331c7a240d417d265bd411d09b51b47bd7c2196659674` +- Manifest inside bundle: `sample-m0/manifest.json` +- Notes: `sample-m0/README.txt` + +## Layout (within tar.gz) +``` +sample-m0/ + manifest.json # version, bundle_id, created, notes + README.txt # purpose, determinism and replacement guidance +``` + +## Refresh cadence +- Replace this sample with real thin bundle once MIRROR-CRT-56-001 assembler emits manifests (target: 2025-11-20). +- Maintain same path prefix `out/mirror/thin/` and update hash in this file and sprint log when refreshed. + +## Usage +- Downstream tasks may reference this path/hash to unblock contract wiring and CI harnesses. +- Do not ship to customers; for internal wiring/tests only. diff --git a/docs/modules/mirror/thin-bundle-assembler.md b/docs/modules/mirror/thin-bundle-assembler.md new file mode 100644 index 000000000..0728add82 --- /dev/null +++ b/docs/modules/mirror/thin-bundle-assembler.md @@ -0,0 +1,34 @@ +# MIRROR-CRT-56-001 · Thin bundle assembler handoff (v0.1) + +Purpose: unblock MIRROR-CRT-56-001 by defining expected assembler outputs so the real thin bundle can replace the milestone-0 sample. + +## Expected outputs +- Artifact: `out/mirror/thin/mirror-thin-v1.tar.gz` +- Manifest: `out/mirror/thin/mirror-thin-v1.manifest.json` containing: + - `version`: "1.0.0" + - `created`: UTC ISO-8601 + - `layers`: array of `{ digest, size, path }` + - `indexes`: array of `{ name, digest }` for evidence/linkset indexes + - `hashes`: `{ tarball_sha256, manifest_sha256 }` +- Checksums: `.sha256` files for tarball and manifest stored alongside artifacts. + +## Assembly steps (reference for assembler owners) +1) Produce layer tar parts deterministically (sorted entries, zeroed mtimes/uid/gid, pax headers disabled). +2) Compose `mirror-thin-v1.tar.gz` using stable order: `manifest.json`, `layers/*`, `indexes/*`. +3) Generate manifest JSON and compute SHA256 for both tarball and manifest; write `.sha256` files. +4) Sign manifest (DSSE optional) and place signature next to manifest if available. + +## Determinism requirements +- POSIX tar with numeric owner 0:0, mtime 0, sorted paths. +- Gzip with `--no-name` and fixed timestamp 0. +- No duplicate files; symlinks forbidden. + +## Evidence +- When produced, place artefacts under `out/mirror/thin/` and add hashes to this doc. + +## Owners +- Mirror Creator Guild (assembler) +- AirGap Guild (consumer) + +## Status +- Handoff doc published 2025-11-19; awaiting assembler output to replace milestone-0 sample. diff --git a/docs/notifications/slo-webhook-schema.md b/docs/notifications/slo-webhook-schema.md new file mode 100644 index 000000000..27ce7696d --- /dev/null +++ b/docs/notifications/slo-webhook-schema.md @@ -0,0 +1,86 @@ +# Notifier Telemetry SLO Webhook Schema (1.0.0) + +Purpose: define the payload emitted by Telemetry SLO evaluators toward Notifier so that NOTIFY-OBS-51-001 can consume alerts deterministically (online and offline). + +## Delivery contract +- Content-Type: `application/json` +- Encoding: UTF-8 +- Authentication: mTLS (service identity) or DPoP/JWT with `aud` = `notifier` and `scope` = `obs:slo:ingest`. +- Determinism: timestamps are UTC ISO-8601 with `Z`; field order stable for hashing (see canonical JSON below). + +## Payload fields +``` +{ + "id": "uuid", + "tenant": "string", // required; aligns with orchestrator/telemetry tenant id + "service": "string", // logical service name + "host": "string", // optional; k8s node/hostname + "slo": { + "name": "string", // human-readable + "id": "string", // immutable key used for dedupe + "objective": { + "window": "PT5M", // ISO-8601 duration + "target": 0.995 // decimal between 0 and 1 + } + }, + "metric": { + "type": "latency|error|availability|custom", + "value": 0.0123, // double; units depend on type + "unit": "seconds|ratio|percent|count", + "labels": { // sanitized, deterministic ordering when serialized + "endpoint": "/api/jobs", + "method": "GET" + } + }, + "window": { + "start": "2025-11-19T12:00:00Z", + "end": "2025-11-19T12:05:00Z" + }, + "breach": { + "state": "breaching|warning|ok", + "reason": "p95 latency above objective", + "evidence": [ + { + "type": "timeseries", + "href": "cas://telemetry/series/abc123", + "hash": "sha256:..." + } + ] + }, + "quietHours": { + "active": false, + "policyId": null + }, + "trace": { + "trace_id": "optional-trace-id", + "span_id": "optional-span-id" + }, + "version": "1.0.0", + "issued_at": "2025-11-19T12:05:07Z" +} +``` + +### Canonical JSON rules +- Sort object keys lexicographically before hashing/signing. +- Use lowercase for enum-like fields shown above. +- `version` is required for evolution; new fields must be add-only. + +### Retry and idempotency +- `id` is the idempotency key; Notifier treats duplicates as no-op. +- Producers retry with exponential backoff up to 10 minutes; consumers respond 2xx only after persistence. + +### Validation checklist (for tests/CI) +- Required fields: id, tenant, service, slo.id, slo.objective.window, slo.objective.target, metric.type, metric.value, window.start/end, breach.state, version, issued_at. +- Timestamps parse with `DateTimeStyles.RoundtripKind`. +- When `breach.state=ok`, `breach.reason` may be null but object must exist. +- `quietHours.active=true` must include `policyId`. + +### Sample canonical JSON (minified) +``` +{"breach":{"evidence":[],"reason":"p99 latency above objective","state":"breaching"},"host":"orchestrator-0","id":"8c1d58c4-b1de-4b3c-9c7b-40a6b0f8d4c1","issued_at":"2025-11-19T12:05:07Z","metric":{"labels":{"endpoint":"/api/jobs","method":"GET"},"type":"latency","unit":"seconds","value":1.234},"quietHours":{"active":false,"policyId":null},"service":"orchestrator","slo":{"id":"orch-api-latency-p99","name":"Orchestrator API p99","objective":{"target":0.99,"window":"PT5M"}},"tenant":"default","trace":{"span_id":null,"trace_id":null},"version":"1.0.0","window":{"end":"2025-11-19T12:05:00Z","start":"2025-11-19T12:00:00Z"}} +``` + +### Evidence to surface in sprint tasks +- File: `docs/notifications/slo-webhook-schema.md` (this document). +- Sample payload (canonical) and validation checklist above. +- Dependencies: upstream Telemetry evaluator must emit `metric.labels` sanitized; Notifier to persist `id` for idempotency. diff --git a/docs/observability/cli-incident-toggle-12-001.md b/docs/observability/cli-incident-toggle-12-001.md new file mode 100644 index 000000000..7d0a11371 --- /dev/null +++ b/docs/observability/cli-incident-toggle-12-001.md @@ -0,0 +1,29 @@ +# CLI incident toggle contract (CLI-OBS-12-001) + +**Goal**: define a deterministic CLI flag and config surface to enter/exit incident mode, required by TELEMETRY-OBS-55-001/56-001. + +## Flags and config +- CLI flag: `--incident-mode` (bool). Defaults to false. +- Config key: `Telemetry:Incident:Enabled` (bool) and `Telemetry:Incident:TTL` (TimeSpan). +- When both flag and config specified, flag wins (opt-in only; cannot disable if config enables and flag present). + +## Effects when enabled +- Increase sampling rate ceiling to 100% for telemetry within the process. +- Add tag `incident=true` to logs/metrics/traces. +- Shorten exporter/reporting flush interval to 5s; disable external exporters when `Sealed=true`. +- Emit activation audit event `telemetry.incident.activated` with fields `{tenant, actor, source, expires_at}`. + +## Persistence +- Incident flag runtime value stored in local state file `~/.stellaops/incident-mode.json` with fields `{enabled, set_at, expires_at, actor}` for offline continuity. +- File is tenant-scoped; permissions 0600. + +## Expiry / TTL +- Default TTL: 30 minutes unless `Telemetry:Incident:TTL` provided. +- On expiry, emit `telemetry.incident.expired` audit event. + +## Validation expectations +- CLI should refuse `--incident-mode` if `--sealed` is set and external exporters are configured (must drop exporters first). +- Unit tests to cover precedence (flag over config), TTL expiry, state file perms, and audit emissions. + +## Provenance +- Authored 2025-11-20 to unblock PREP-CLI-OBS-12-001 and TELEMETRY-OBS-55-001. diff --git a/docs/observability/telemetry-bootstrap.md b/docs/observability/telemetry-bootstrap.md new file mode 100644 index 000000000..daa9fd33d --- /dev/null +++ b/docs/observability/telemetry-bootstrap.md @@ -0,0 +1,48 @@ +# Telemetry Core Bootstrap (v1 · 2025-11-19) + +## Goal +Show minimal host wiring for `StellaOps.Telemetry.Core` with deterministic defaults and sealed-mode friendliness. + +## Sample (web/worker host) +```csharp +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddStellaOpsTelemetry( + builder.Configuration, + serviceName: "StellaOps.SampleService", + serviceVersion: builder.Configuration["VERSION"], + configureOptions: options => + { + // Disable collector in sealed mode / air-gap + options.Collector.Enabled = builder.Configuration.GetValue("Telemetry:Collector:Enabled", true); + options.Collector.Endpoint = builder.Configuration["Telemetry:Collector:Endpoint"]; + options.Collector.Protocol = TelemetryCollectorProtocol.Grpc; + }, + configureMetrics: m => m.AddAspNetCoreInstrumentation(), + configureTracing: t => t.AddHttpClientInstrumentation()); +``` + +## Configuration (appsettings.json) +```json +{ + "Telemetry": { + "Collector": { + "Enabled": true, + "Endpoint": "https://otel-collector.example:4317", + "Protocol": "Grpc", + "Component": "sample-service", + "Intent": "telemetry-export", + "DisableOnViolation": true + } + } +} +``` + +## Determinism & safety +- UTC timestamps only; no random IDs introduced by the helper. +- Exporter is skipped when endpoint missing or egress policy denies. +- `VSTEST_DISABLE_APPDOMAIN=1` recommended for tests with `tools/linksets-ci.sh` pattern. + +## Next +- Propagation adapters (50-002) will build on this bootstrap. +- Scrub/analyzer policies live under upcoming 51-001/51-002 tasks. diff --git a/docs/observability/telemetry-propagation-51-001.md b/docs/observability/telemetry-propagation-51-001.md new file mode 100644 index 000000000..9c3fbd687 --- /dev/null +++ b/docs/observability/telemetry-propagation-51-001.md @@ -0,0 +1,43 @@ +# Telemetry propagation contract (TELEMETRY-OBS-51-001) + +**Goal**: standardise trace/metrics propagation across StellaOps services so golden-signal helpers remain deterministic, tenant-safe, and offline-friendly. + +## Scope +- Applies to HTTP, gRPC, background jobs, and message handlers instrumented via `StellaOps.Telemetry.Core`. +- Complements bootstrap guide (`telemetry-bootstrap.md`) and precedes metrics helper implementation. + +## Required context fields +- `trace_id` / `span_id`: W3C TraceContext headers only (no B3); generate if missing. +- `tenant`: lower-case string; required for all incoming requests; default to `unknown` only in sealed/offline diagnostics jobs. +- `actor`: optional user/service principal; redacted to hash in logs when `Scrub.Sealed=true`. +- `imposed_rule`: optional string conveying enforcement context (e.g., `merge=false`). + +## HTTP middleware +- Accept `traceparent`/`tracestate`; reject/strip vendor-specific headers. +- Propagate `tenant`, `actor`, `imposed-rule` via `Stella-Tenant`, `Stella-Actor`, `Stella-Imposed-Rule` headers. +- Emit exemplars: when sampling is off, attach exemplar ids to request duration and active request metrics. + +## gRPC interceptors +- Use binary TraceContext; carry metadata keys `stella-tenant`, `stella-actor`, `stella-imposed-rule`. +- Enforce presence of `tenant`; abort with `Unauthenticated` if missing in non-sealed mode. + +## Jobs & message handlers +- Wrap background job execution with Activity + baggage items (`tenant`, `actor`, `imposed_rule`). +- When publishing bus events, stamp `trace_id` and `tenant` into headers; avoid embedding PII in payloads. + +## Metrics helper expectations +- Golden signals: `http.server.duration`, `http.client.duration`, `messaging.operation.duration`, `job.execution.duration`, `runtime.gc.pause`, `db.call.duration`. +- Mandatory tags: `tenant`, `service`, `endpoint`/`operation`, `result` (`ok|error|cancelled|throttled`), `sealed` (`true|false`). +- Cardinality guard: drop/replace tag values exceeding 64 chars; cap path templates to first 3 segments. + +## Determinism & offline posture +- All timestamps UTC RFC3339; sampling configs controlled via appsettings and mirrored in offline bundles. +- No external exporters when `Sealed=true`; use in-memory or file-based OTLP for air-gap. + +## Tests to add with implementation +- Middleware unit tests asserting header/baggage mapping and tenant enforcement. +- Metrics helper tests ensuring required tags present and trimmed; exemplar id attached when enabled. +- Deterministic snapshot tests for serialized OTLP when sealed/offline. + +## Provenance +- Authored 2025-11-20 to unblock TELEMETRY-OBS-51-001; to be refined as helpers are coded. diff --git a/docs/observability/telemetry-scrub-51-002.md b/docs/observability/telemetry-scrub-51-002.md new file mode 100644 index 000000000..3085f18f8 --- /dev/null +++ b/docs/observability/telemetry-scrub-51-002.md @@ -0,0 +1,35 @@ +# Telemetry scrubbing contract (TELEMETRY-OBS-51-002) + +**Purpose**: define redaction/scrubbing rules for logs/traces/metrics before implementing helpers in `StellaOps.Telemetry.Core`. + +## Redaction rules +- Strip or hash PII/credentials: emails, tokens, passwords, secrets, bearer/mTLS cert blobs. +- Default hash algorithm: SHA-256 hex; include `scrubbed=true` tag. +- Allowlist fields that remain: `tenant`, `trace_id`, `span_id`, `endpoint`, `result`, `sealed`. + +## Configuration knobs +- `Telemetry:Scrub:Enabled` (bool, default true). +- `Telemetry:Scrub:Sealed` (bool, default false) — when true, force scrubbing and disable external exporters. +- `Telemetry:Scrub:HashSalt` (string, optional) — per-tenant salt; omit to keep deterministic hashes across deployments. +- `Telemetry:Scrub:MaxValueLength` (int, default 256) — truncate values beyond this length before hashing. + +## Logger sink expectations +- Implement scrubber as `ILogPayloadFilter` injected before sink. +- Ensure message templates remain intact; only values scrubbed. +- Preserve structured shape so downstream parsing remains deterministic. + +## Metrics & traces +- Never place raw user input into metric/tag values; pass through scrubber before export. +- Span events must omit payload bodies; include keyed references only. + +## Auditing +- When scrubbing occurs, add tag `scrubbed=true` and `scrub_reason` (`pii|secret|length|pattern`). +- Provide counter `telemetry.scrub.events{tenant,reason}` for observability. + +## Tests to add with implementation +- Unit tests for regex-based scrubbing of tokens, emails, URLs with creds. +- Config-driven tests toggling `Enabled`/`Sealed` modes to ensure exporters are suppressed when sealed. +- Determinism test: same input yields identical hashed output when salt unset. + +## Provenance +- Authored 2025-11-20 to unblock TELEMETRY-OBS-51-002 and downstream 55/56 tasks. diff --git a/docs/observability/telemetry-sealed-56-001.md b/docs/observability/telemetry-sealed-56-001.md new file mode 100644 index 000000000..6eea3cd92 --- /dev/null +++ b/docs/observability/telemetry-sealed-56-001.md @@ -0,0 +1,33 @@ +# Sealed-mode telemetry helpers (TELEMETRY-OBS-56-001 prep) + +## Objective +Define behavior and configuration for telemetry when `Sealed=true`, ensuring no external egress while preserving deterministic local traces/metrics for audits. + +## Requirements +- Disable external OTLP/exporters automatically when sealed; fallback to in-memory or file OTLP (`telemetry-sealed.otlp`) with bounded size (default 10 MB, ring buffer). +- Add tag `sealed=true` to all spans/metrics/logs; suppress exemplars. +- Force scrubbing: treat `Scrub.Sealed=true` regardless of default settings. +- Sampling: cap to 10% max in sealed mode unless CLI incident toggle raises it (see CLI-OBS-12-001 contract); ceiling 100% with explicit override `Telemetry:Sealed:MaxSamplingPercent`. +- Clock source: require monotonic clock for duration; emit warning if system clock skew detected >500ms. + +## Configuration keys +- `Telemetry:Sealed:Enabled` (bool) — driven by host; when true activate sealed behavior. +- `Telemetry:Sealed:Exporter` (enum `memory|file`) — default `file`. +- `Telemetry:Sealed:FilePath` (string) — default `./logs/telemetry-sealed.otlp`. +- `Telemetry:Sealed:MaxBytes` (int) — default 10_485_760 (10 MB). +- `Telemetry:Sealed:MaxSamplingPercent` (int) — default 10. +- Derived flag `Telemetry:Sealed:EffectiveIncidentMode` (read-only) exposes if incident-mode override lifted sampling ceiling. + +## File exporter format +- OTLP binary, append-only, deterministic ordering by enqueue time. +- Rotate when exceeding `MaxBytes` using suffix `.1`, `.2` capped to 3 files; oldest dropped. +- Permissions 0600 by default; fail-start if path is world-readable. + +## Validation tests to implement with 56-001 +- Unit: sealed mode forces exporter swap and tags `sealed=true`, `scrubbed=true`. +- Unit: sampling capped at max percent unless incident override set. +- Unit: file exporter rotates deterministically and enforces 0600 perms. +- Integration: sealed + incident mode together still block external exporters and honor scrub rules. + +## Provenance +- Authored 2025-11-20 to satisfy PREP-TELEMETRY-OBS-56-001 and unblock implementation. diff --git a/docs/policy/auth-signals-lib-115.md b/docs/policy/auth-signals-lib-115.md new file mode 100644 index 000000000..2413230f6 --- /dev/null +++ b/docs/policy/auth-signals-lib-115.md @@ -0,0 +1,40 @@ +# POLICY-AUTH-SIGNALS-LIB-115 · Shared P/A/S contracts (draft v0.1) + +Purpose: deliver shared models/schemas for Policy, Authority, and Signals so Concelier/Excititor consumers can bind without merge logic. + +## Core models (C#-friendly, JSON schema inline) +- `PolicyAuthSignal`: + - `id` (string, required) — stable identifier (ULID preferred) + - `tenant` (string, required) + - `subject` (string, required) — e.g., `purl`, `sbom://`, `service://` + - `signal_type` (string, enum: `reachability`, `attestation`, `risk`, `vex`) + - `source` (string, required) — producer service + - `confidence` (float?, optional) + - `evidence` (array of `EvidenceRef`) + - `created` (string, UTC ISO-8601, required) +- `EvidenceRef`: + - `kind` (string, enum: `linkset`, `runtime`, `attestation`, `bundle`) + - `uri` (string, required) — CAS or storage pointer + - `digest` (string, sha256, required) + - `scope` (string) — tenant/scopes +- `Provenance`: + - `pipeline` (string) — build id + - `inputs` (array) — hashes of inputs + - `signer` (string) + - `transparency` (object: `rekor_uuid` or `skip_reason`) + +## JSON schema stub (add-only) +See `schemas/policy-auth-signals-lib-115.json` (to be emitted with the NuGet package). + +## Package plan +- Project: `StellaOps.Policy.AuthSignals` (net10.0) +- Deliverables: models, JSON schema, sample fixtures, `PolicyAuthSignalJsonContext` for source generators, deterministic serialization. +- Publish target: `local-nugets/` (version `0.1.0-alpha+draft`), then promote after guild ratification. + +## Fixtures (to include in package) +- `fixtures/policy-auth-signal-sample.json` +- `fixtures/policy-auth-signal-reachability.json` +- Schema: `schemas/policy-auth-signals-lib-115.json` + +## Status +- NuGet package `StellaOps.Policy.AuthSignals` 0.1.0-alpha built and placed in `local-nugets/` (sha256: `8ab5aa6c0daf5e56e1355d4d6bcaf110a8bc28b28a5ee1970864bcd4b6ba6750`). Awaiting guild ratification to promote beyond alpha. diff --git a/docs/policy/fixtures/policy-auth-signal-reachability.json b/docs/policy/fixtures/policy-auth-signal-reachability.json new file mode 100644 index 000000000..4b187e7ae --- /dev/null +++ b/docs/policy/fixtures/policy-auth-signal-reachability.json @@ -0,0 +1,31 @@ +{ + "id": "ulid-01J000REACH000000000000000", + "tenant": "urn:tenant:demo", + "subject": "service://demo-api", + "signal_type": "reachability", + "source": "signals", + "evidence": [ + { + "kind": "runtime", + "uri": "cas://runtime-facts/123", + "digest": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + { + "kind": "attestation", + "uri": "cas://attestations/abc", + "digest": "sha256:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" + } + ], + "provenance": { + "pipeline": "build:reachability-001", + "inputs": [ + "sha256:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + ], + "signer": "sigkey:runtime", + "transparency": { + "rekor_uuid": "a1b2c3d4", + "skip_reason": null + } + }, + "created": "2025-11-19T12:00:00Z" +} diff --git a/docs/policy/fixtures/policy-auth-signal-sample.json b/docs/policy/fixtures/policy-auth-signal-sample.json new file mode 100644 index 000000000..5b13f4fa4 --- /dev/null +++ b/docs/policy/fixtures/policy-auth-signal-sample.json @@ -0,0 +1,26 @@ +{ + "id": "ulid-01J00000000000000000000000", + "tenant": "urn:tenant:00000000-0000-0000-0000-000000000000", + "subject": "purl:pkg:maven/org.example/app@1.2.3", + "signal_type": "reachability", + "source": "signals", + "confidence": 0.92, + "evidence": [ + { + "kind": "linkset", + "uri": "cas://linksets/advisory-ghsa-1234", + "digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "scope": "tenant:default" + } + ], + "provenance": { + "pipeline": "git:abcd1234", + "inputs": ["sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"], + "signer": "sigkey:policy", + "transparency": { + "rekor_uuid": null, + "skip_reason": "offline" + } + }, + "created": "2025-11-19T00:00:00Z" +} diff --git a/docs/policy/schemas/policy-auth-signals-lib-115.json b/docs/policy/schemas/policy-auth-signals-lib-115.json new file mode 100644 index 000000000..2ab6b9a3f --- /dev/null +++ b/docs/policy/schemas/policy-auth-signals-lib-115.json @@ -0,0 +1,56 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://stellaops.local/schemas/policy-auth-signals-lib-115.json", + "title": "PolicyAuthSignal", + "type": "object", + "additionalProperties": false, + "required": ["id", "tenant", "subject", "signal_type", "source", "created", "evidence"], + "properties": { + "id": {"type": "string"}, + "tenant": {"type": "string"}, + "subject": {"type": "string"}, + "signal_type": {"type": "string", "enum": ["reachability", "attestation", "risk", "vex"]}, + "source": {"type": "string"}, + "confidence": {"type": "number"}, + "evidence": { + "type": "array", + "items": {"$ref": "#/$defs/EvidenceRef"}, + "minItems": 1 + }, + "provenance": {"$ref": "#/$defs/Provenance"}, + "created": { + "type": "string", + "format": "date-time" + } + }, + "$defs": { + "EvidenceRef": { + "type": "object", + "additionalProperties": false, + "required": ["kind", "uri", "digest"], + "properties": { + "kind": {"type": "string", "enum": ["linkset", "runtime", "attestation", "bundle"]}, + "uri": {"type": "string"}, + "digest": {"type": "string"}, + "scope": {"type": "string"} + } + }, + "Provenance": { + "type": "object", + "additionalProperties": false, + "properties": { + "pipeline": {"type": "string"}, + "inputs": {"type": "array", "items": {"type": "string"}}, + "signer": {"type": "string"}, + "transparency": { + "type": "object", + "additionalProperties": false, + "properties": { + "rekor_uuid": {"type": ["string", "null"]}, + "skip_reason": {"type": ["string", "null"]} + } + } + } + } + } +} diff --git a/docs/provenance/prov-backfill-plan.md b/docs/provenance/prov-backfill-plan.md new file mode 100644 index 000000000..0eab6de17 --- /dev/null +++ b/docs/provenance/prov-backfill-plan.md @@ -0,0 +1,16 @@ +# Provenance Backfill Plan (Sprint 401) + +Artifacts available +- Attestation inventory: `docs/provenance/attestation-inventory-2025-11-18.ndjson` +- Subject→Rekor map: `docs/provenance/subject-rekor-map-2025-11-18.json` + +Procedure (deterministic) +1) Load inventory NDJSON; validate UUID/ULID and digest formats. +2) For each record, resolve Rekor entry via the subject→Rekor map; if missing, record gap and skip write. +3) Emit backfilled events to the provenance store using `scripts/publish_attestation_with_provenance.sh --mode backfill` (add `--subject` and `--rekor` arguments) with sorted input to guarantee stable ordering. +4) Log every backfilled subject + Rekor digest pair to `logs/provenance-backfill-2025-11-18.ndjson` (UTC timestamps, ISO-8601). +5) Rerun until gaps are zero; then mark PROV-BACKFILL-401-029 DONE. + +Determinism +- Sort by subject, then rekorEntry before processing. +- Use canonical JSON writer for outputs; timestamps in UTC `O` format. diff --git a/docs/reachability/corpus-plan.md b/docs/reachability/corpus-plan.md new file mode 100644 index 000000000..f7037092d --- /dev/null +++ b/docs/reachability/corpus-plan.md @@ -0,0 +1,33 @@ +# Reachability Corpus Plan (QA-CORPUS-401-031) + +Objective +- Build a multi-runtime reachability corpus (Go/.NET/Python/Rust) with EXPECT.yaml ground truths and captured traces. +- Make fixtures CI-consumable to validate reachability scoring and VEX proofs continuously. + +Scope & deliverables +- Fixture layout: `tests/reachability/corpus///` + - `expect.yaml` — states (`reachable|conditional|unreachable`), score, evidence refs. + - `callgraph.*.json` — static graphs per language. + - `runtime/*.ndjson` — traces/probes when available. + - `sbom.*.json` — CycloneDX/SPDX slices. + - `vex.openvex.json` — expected VEX statement. +- CI integration: add corpus harness to `tests/reachability/StellaOps.Reachability.FixtureTests` to validate presence, schema, and determinism (hash manifest). +- Offline posture: all artifacts deterministic, no external downloads; hashes recorded in manifest. + +MVP slice (proposed) +- Go: `go-ssh-CVE-2020-9283-keyexchange` +- .NET: `dotnet-kestrel-CVE-2023-44487-http2-rapid-reset` +- Python: `python-django-CVE-2019-19844-sqli-like` +- Rust: `rust-axum-header-parsing-TBD` + +Work plan +1) Define shared manifest schema + hash manifest (NDJSON) under `tests/reachability/corpus/manifest.json`. +2) For each MVP case, add minimal static callgraph + EXPECT.yaml with score/state and evidence links. (DONE: stub versions committed) +3) Extend reachability fixture tests to cover corpus folders (presence, hashes, EXPECT.yaml schema). (DONE) +4) Wire CI job to run the extended tests in `tests/reachability/StellaOps.Reachability.FixtureTests`. (TODO) +5) Replace stubs with real callgraphs/traces and expand corpus after MVP passes CI. (TODO) + +Determinism rules +- Sort JSON keys; round scores to 2dp; UTC times only if needed. +- Stable ordering of files in manifests; hash with SHA-256. +- No network calls during test or generation. diff --git a/docs/replay/replay-api-draft-2025-11-18.md b/docs/replay/replay-api-draft-2025-11-18.md new file mode 100644 index 000000000..816fc3921 --- /dev/null +++ b/docs/replay/replay-api-draft-2025-11-18.md @@ -0,0 +1,34 @@ +# EvidenceLocker Replay API (draft) — 2025-11-18 + +Scope: EVID-REPLAY-187-001 baseline API surface using shared orchestrator/advisory evidence schemas. + +## Endpoints (prefix `/api/evidencelocker/replay`) +- `POST /records` — ingest replay bundle (DSSE + manifest). Request: multipart or JSON with CAS URIs; Response: `{ recordId, bundleDigest }`. +- `POST /verify` — verify replay bundle signatures/hashes. Request: `{ bundleDigest | bundleUri }`; Response: `{ status: "pass|fail", findings: [] }`. +- `POST /replay` — schedule replay job against stored records. Request: `{ recordId, targetTenant, policyRevisionId? }`; Response: `{ jobId }`. +- `POST /prune` — enforce retention policy. Request: `{ maxAgeDays, keepLatestPerDigest: bool }`; Response: `{ pruned: int }`. + +## Models (draft) +```json +{ + "recordId": "uuid", + "bundleDigest": "sha256:...", + "bundleUri": "cas://evidence/replay/{digest}", + "tenant": "string", + "ingestedAt": "2025-11-18T12:00:00Z", + "dsse": { + "payloadType": "application/vnd.stellaops.replay+json", + "payload": "base64", + "signatures": [ { "keyid": "...", "sig": "..." } ] + } +} +``` + +## Retention policy draft +- Default: `maxAgeDays = 30`, `keepLatestPerDigest = true`. +- Deterministic pruning order: sort by `ingestedAt` ascending, then `recordId`. + +## Notes +- Align request/response DTOs with `StellaOps.Orchestrator.Schemas` naming (camelCase, UTC ISO-8601). +- CLI verbs `stella evidence replay record|verify|replay` to mirror these routes (see CLI-REPLAY-187-002). +- Update `docs/replay/DETERMINISTIC_REPLAY.md` once finalized. diff --git a/docs/samples/console/console-vex-30-001.json b/docs/samples/console/console-vex-30-001.json new file mode 100644 index 000000000..854b430b1 --- /dev/null +++ b/docs/samples/console/console-vex-30-001.json @@ -0,0 +1,17 @@ +{ + "query": {"component": "openssl", "advisory": "CVE-2024-1234"}, + "tenant": "demo", + "timestamp": "2025-11-19T00:00:00Z", + "statements": [ + { + "id": "stmt-1", + "status": "not_affected", + "justification": "component_not_present", + "advisory": "CVE-2024-1234", + "products": ["pkg:deb/openssl@1.1.1w"], + "evidence": {"observationId": "obs-ossl-001", "linksetId": "lnm-ossl-001"}, + "timestamp": "2025-11-19T00:00:00Z" + } + ], + "pagination": {"pageSize": 20, "next": null} +} diff --git a/docs/samples/console/console-vuln-29-001.json b/docs/samples/console/console-vuln-29-001.json new file mode 100644 index 000000000..75e9329d5 --- /dev/null +++ b/docs/samples/console/console-vuln-29-001.json @@ -0,0 +1,19 @@ +{ + "query": "openssl", + "tenant": "demo", + "timestamp": "2025-11-19T00:00:00Z", + "results": [ + { + "advisoryId": "CVE-2024-1234", + "title": "OpenSSL buffer overflow", + "severity": "HIGH", + "package": "openssl", + "version": "1.1.1w", + "source": "nvd", + "linksetId": "lnm-ossl-001", + "justification": "aggregation-only", + "provenance": {"fetchedAt": "2025-11-18T12:00:00Z", "digest": "sha256:dummy"} + } + ], + "pagination": {"pageSize": 20, "next": null} +} diff --git a/docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz b/docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..24e41917861e7e4e9114820131232bf801107e45 GIT binary patch literal 781 zcmV+o1M>VIiwFP!000001MQegi`y^|$M>91VSL`CdRkVX&{BHnz4Xv!S!8LvabwHD zveQS{@7}SKzS1sB*-a=#zl0c%MlW0cktU7tRSBVAd zbfIef=t37{aj@DBOb=5fP%(%3RDT;{pq9+iY47qqft{`gZA{c!sj}Sp5ZE z;O8Scg?8vHN&w))U1RF%%XmnbHpXvfhCf9B86&`X={w`Y#&me% z`+TY#;354J`J4W^BvJq8V3&5VZo8Xdm`?wGsOw8SqOPmW4XQNk&--mzVw8ZW%m0s+ z2`dPTeR6c7J|5D)#LfOF|EEGl{htGFi?T3E+YE9}G{w!m&<;Qe%%G)`Mv5FWaEk^3 z4ijm+G@{s(FH*layX{*aN*9-Fi$${oQg_OEvBukRtcFq_aBauiX5{X12kw_#Gi9{li$Untb L+VaZ704M+ezA%O~ literal 0 HcmV?d00001 diff --git a/docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz.sha256 b/docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz.sha256 new file mode 100644 index 000000000..eb7b8b2bf --- /dev/null +++ b/docs/samples/evidence-bundle/evidence-bundle-m0.tar.gz.sha256 @@ -0,0 +1 @@ +c3be72958c85d8d9ff96927542a0e0184e5d64717b9b0365756f253b4a365fed evidence-bundle-m0.tar.gz diff --git a/docs/samples/evidence-bundle/hashes.sha256 b/docs/samples/evidence-bundle/hashes.sha256 new file mode 100644 index 000000000..465817362 --- /dev/null +++ b/docs/samples/evidence-bundle/hashes.sha256 @@ -0,0 +1,4 @@ +3cbfba79c6e83091123b9dee748e0575a548a03ce744ed53392dcbc8c6490119 manifest.json +a035333e9b9f8ad82145105276c8f73f143ad6ad46bd80cf3999318e04531019 observations.ndjson +1543a5902cc6b319971dadd92118188324cc5cd9b9296f9a8b08b534406d2e4e linksets.ndjson +ab7d5e06c7a4bc5517534a3fdc1a448a7e3f176020e2a3b93048eb20b559f206 transparency.json diff --git a/docs/samples/evidence-bundle/linksets.ndjson b/docs/samples/evidence-bundle/linksets.ndjson new file mode 100644 index 000000000..b674f86c8 --- /dev/null +++ b/docs/samples/evidence-bundle/linksets.ndjson @@ -0,0 +1 @@ +{"linksetId":"lnm-ossl-001","advisoryId":"CVE-2024-1234","components":["pkg:deb/openssl@1.1.1w"],"normalized":true,"createdAt":"2025-11-18T12:05:00Z"} diff --git a/docs/samples/evidence-bundle/manifest.json b/docs/samples/evidence-bundle/manifest.json new file mode 100644 index 000000000..c7dcd0b6d --- /dev/null +++ b/docs/samples/evidence-bundle/manifest.json @@ -0,0 +1,18 @@ +{ + "bundle_id": "evidence-bundle-m0", + "version": "1.0.0", + "created": "2025-11-19T00:00:00Z", + "tenant": "demo", + "scope": "vex", + "inputs": [ + "sha256:a035333e9b9f8ad82145105276c8f73f143ad6ad46bd80cf3999318e04531019", + "sha256:1543a5902cc6b319971dadd92118188324cc5cd9b9296f9a8b08b534406d2e4e" + ], + "aoc": { + "guardrails": true, + "details": [ + "schema:frozen:1.0", + "limits:chunk:max=2000" + ] + } +} diff --git a/docs/samples/evidence-bundle/observations.ndjson b/docs/samples/evidence-bundle/observations.ndjson new file mode 100644 index 000000000..b26d24d59 --- /dev/null +++ b/docs/samples/evidence-bundle/observations.ndjson @@ -0,0 +1 @@ +{"observationId":"obs-ossl-001","advisoryId":"CVE-2024-1234","component":"pkg:deb/openssl@1.1.1w","source":"nvd","fetchedAt":"2025-11-18T12:00:00Z"} diff --git a/docs/samples/evidence-bundle/transparency.json b/docs/samples/evidence-bundle/transparency.json new file mode 100644 index 000000000..edd415913 --- /dev/null +++ b/docs/samples/evidence-bundle/transparency.json @@ -0,0 +1 @@ +{"rekor_uuid": null, "skip_reason": "offline"} diff --git a/docs/samples/excititor/chunks-sample.ndjson b/docs/samples/excititor/chunks-sample.ndjson new file mode 100644 index 000000000..33da18cc6 --- /dev/null +++ b/docs/samples/excititor/chunks-sample.ndjson @@ -0,0 +1,2 @@ +{"tenant":"demo","vulnerabilityId":"CVE-2024-1234","productKey":"pkg:pypi/django@3.2.24","observationId":"obs-001","statementId":"stmt-001","source":{"supplier":"upstream:osv","documentId":"osv:CVE-2024-1234","retrievedAt":"2025-11-18T12:00:00Z","signatureStatus":"missing"},"aoc":{"violations":[]},"evidence":{"type":"vex.statement","payload":{"status":"not_affected","justification":"component_not_present"}},"provenance":{"hash":"sha256:dummyhash","canonicalUri":null,"bundleId":null}} +{"tenant":"demo","vulnerabilityId":"CVE-2024-2345","productKey":"pkg:pypi/requests@2.31.0","observationId":"obs-002","statementId":"stmt-001","source":{"supplier":"upstream:osv","documentId":"osv:CVE-2024-2345","retrievedAt":"2025-11-18T12:05:00Z","signatureStatus":"unverified"},"aoc":{"violations":[{"code":"EVIDENCE_SIGNATURE_MISSING","surface":"ingest"}]},"evidence":{"type":"vex.statement","payload":{"status":"affected","impact":"info","details":"placeholder"}},"provenance":{"hash":"sha256:dummyhash2","canonicalUri":null,"bundleId":null}} diff --git a/docs/samples/excititor/chunks-sample.ndjson.sha256 b/docs/samples/excititor/chunks-sample.ndjson.sha256 new file mode 100644 index 000000000..ea5f9eb5d --- /dev/null +++ b/docs/samples/excititor/chunks-sample.ndjson.sha256 @@ -0,0 +1 @@ +4d638b24d6f8f703bcbcac23a0185265f3db5defb9f3d7f33b7be7fccc0de738 docs/samples/excititor/chunks-sample.ndjson diff --git a/docs/signals/cas-promotion-24-002.md b/docs/signals/cas-promotion-24-002.md new file mode 100644 index 000000000..682851324 --- /dev/null +++ b/docs/signals/cas-promotion-24-002.md @@ -0,0 +1,34 @@ +# SIGNALS-24-002 · CAS promotion checklist (v1) + +Purpose: unblock CAS promotion + signed manifest rollout for callgraph storage so SIGNALS-24-002 can move from BLOCKED to implementation. + +## Preconditions +- CAS bucket created for `signals-callgraphs` with write limited to Signals service principals. +- Surface bundle mock hash recorded; real scanner cache ETA published. +- Signed manifest tooling available (sigstore or in-house signer) with add-only policy. + +## Steps +1) Freeze manifest schema (fields: `graph_id`, `digest`, `language`, `source`, `created`, `signer`, `signature`). +2) Generate manifests for existing callgraphs; store under `cas://signals/manifests/{graph_id}.json`. +3) Sign each manifest; attach DSSE envelope; store under `cas://signals/manifests/{graph_id}.json.dsse`. +4) Apply bucket policy: read-only for downstream, write for Signals service; deny deletes. +5) Configure GC policy: retain manifests indefinitely; callgraph blobs keep 30d rolling unless referenced. +6) Enable alerts for failed retrievals and missing manifest/DSSE pairs. +7) Record hash list and signer key IDs in release notes. + +## Deliverables +- Policy document + proof of applied IAM +- Manifest schema JSON +- Signed manifest samples (see tests) +- Hash list of all published callgraphs (sha256) + +## Evidence locations (repo paths) +- Policy & schema: `docs/signals/cas-promotion-24-002.md` (this file) +- Sample manifest + DSSE: `tests/reachability/corpus/manifest.json` (already present) maps to expected structure. + +## Owners +- Signals Guild (implementation) +- Platform Storage Guild (policy/approvals) + +## Status +- Checklist published 2025-11-19; awaiting Platform Storage approval to proceed. diff --git a/docs/signals/events-24-005.md b/docs/signals/events-24-005.md new file mode 100644 index 000000000..b48ffb39a --- /dev/null +++ b/docs/signals/events-24-005.md @@ -0,0 +1,47 @@ +# signals.fact.updated event contract (SIGNALS-24-005 prep) + +**Purpose**: replace the in-memory logger used during Signals development with a real event bus contract so reachability caches can be invalidated and downstream consumers (Policy Engine, Notifications, Console) can subscribe deterministically. + +## Topic / channel +- Primary topic: `signals.fact.updated.v1` +- Dead-letter topic: `signals.fact.updated.dlq` +- Delivery: at-least-once; consumers must de-duplicate using `event_id`. + +## Message envelope +```jsonc +{ + "event_id": "uuid-v4", // stable across retries; used for idempotency + "emitted_at": "2025-11-20T00:00:00Z", // UTC, RFC3339 + "tenant": "acme", // required; lower-case + "subject_key": "sbom:sha256:…" , // subject of facts (asset, sbom, host). Deterministic model key. + "fact_kind": "callgraph" | "runtime" | "reachability" | "signal", // enums mapped from Signals domain + "fact_version": 1, // monotonically increasing per subject_key + fact_kind + "digest": "sha256:…", // CAS digest of canonical fact document + "content_type": "application/json", // or application/vnd.stellaops.ndjson when chunked + "producer": "StellaOps.Signals", // emitting service + "source": { + "pipeline": "signals", // consistent with Observability tags + "release": "0.4.0-alpha" // optional + }, + "trace": { + "trace_id": "…", // pass-through if available + "span_id": "…" + } +} +``` + +## Routing / partitions +- Partition key: `tenant` to keep per-tenant ordering. +- Retry policy: exponential backoff up to 5 minutes; move to DLQ thereafter with `dlq_reason` header. + +## Consumer expectations +- De-duplicate on `event_id` and `digest`. +- Fetch fact body from CAS using `digest`; avoid embedding large payloads in the message. +- If consumer cannot resolve CAS, treat as transient and retry later (do not drop). + +## Security / air-gap posture +- No PII; tenant id only. +- Works offline when bus is intra-cluster (e.g., NATS/Redis Streams); external exporters disabled in sealed mode. + +## Provenance +- This contract supersedes the temporary log-based publisher referenced in Signals sprint 0143 Execution Log (2025-11-18). Aligns with `signals.fact.updated@v1` payload shape already covered by unit tests. diff --git a/docs/signals/provenance-24-003.md b/docs/signals/provenance-24-003.md new file mode 100644 index 000000000..6ea55a31f --- /dev/null +++ b/docs/signals/provenance-24-003.md @@ -0,0 +1,31 @@ +# SIGNALS-24-003 · Provenance appendix checklist (v1) + +Purpose: unblock provenance enrichment for runtime facts so SIGNALS-24-003 can advance once CAS promotion is approved. + +## Required fields (per runtime fact) +- `callgraph_id` (matches CAS manifest id) +- `ingested_at` (UTC ISO-8601), `received_at` +- `tenant` +- `source` (host/service emitting facts) +- `pipeline_version` (git SHA or build ID) +- `provenance_hash` (sha256 of raw fact blob) +- `signer` (key id) and optional `rekor_uuid` or `skip_reason: offline` + +## Steps +1) Freeze provenance JSON schema (`provenance.runtime.fact.v1`). +2) Add enrichment stage writing provenance into CAS alongside runtime facts. +3) Emit DSSE attestation per batch of runtime facts; store in CAS. +4) Update `/signals/runtime-facts/ndjson` handler to return `provenance_hash` and `callgraph_id` when available. +5) Add validation tests to ensure add-only evolution and deterministic ordering. + +## Deliverables +- Schema file: `docs/signals/provenance-24-003.md` (this file) with field list and invariants. +- Test fixtures: reuse `tests/reachability/corpus/*/vex.openvex.json` provenance anchors; add `provenance_hash` coverage to `ReachabilityLatticeTests` when available. + +## Owners +- Signals Guild (implementation) +- Runtime Guild (schema review) +- Authority Guild (signing/attestation) + +## Status +- Checklist published 2025-11-19; awaiting schema/signing approval to proceed. diff --git a/local-nugets/StellaOps.Policy.AuthSignals.0.1.0-alpha.nupkg b/local-nugets/StellaOps.Policy.AuthSignals.0.1.0-alpha.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..f7111b5dfc4ab68dc1025cd182658c7d2d14a468 GIT binary patch literal 7470 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 + + + Cronos + 0.10.0 + Cronos + Andrey Dorokhov, Sergey Odinokov + HangfireIO, odinserj + false + MIT + https://licenses.nuget.org/MIT + icon.png + README.md + https://github.com/HangfireIO/Cronos + A fully-featured .NET library for parsing cron expressions and calculating next occurrences that was designed with time zones in mind and correctly handles daylight saving time transitions. + https://github.com/HangfireIO/Cronos/releases + Copyright © 2016–2025 Hangfire OÜ. + Cronos Cron Recurring + + + + + + + + + + + + \ No newline at end of file diff --git a/local-nugets/cronos/0.10.0/LICENSE b/local-nugets/cronos/0.10.0/LICENSE new file mode 100644 index 000000000..a900d60a8 --- /dev/null +++ b/local-nugets/cronos/0.10.0/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Hangfire OÜ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/local-nugets/cronos/0.10.0/README.md b/local-nugets/cronos/0.10.0/README.md new file mode 100644 index 000000000..36cfcc8f3 --- /dev/null +++ b/local-nugets/cronos/0.10.0/README.md @@ -0,0 +1,292 @@ +# Cronos +[![NuGet](https://img.shields.io/nuget/v/Cronos.svg)](https://www.nuget.org/packages/Cronos) [![Build status](https://ci.appveyor.com/api/projects/status/4elmix39mvr18cqf?svg=true)](https://ci.appveyor.com/project/hangfireio/cronos) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=HangfireIO_Cronos&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=HangfireIO_Cronos) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=HangfireIO_Cronos&metric=bugs)](https://sonarcloud.io/summary/new_code?id=HangfireIO_Cronos) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=HangfireIO_Cronos&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=HangfireIO_Cronos) + +Cronos is a .NET library for parsing Cron expressions and calculating next occurrences. It was designed with time zones in mind, and intuitively handles [Daylight saving time](https://en.wikipedia.org/wiki/Daylight_saving_time) (also known as Summer time) transitions as in *nix Cron. + +*Please note this library doesn't include any task/job scheduler, it only works with Cron expressions.* + +* Supports standard Cron format with optional seconds. +* Supports non-standard characters like `L`, `W`, `#` and their combinations. +* Supports reversed ranges, like `23-01` (equivalent to `23,00,01`) or `DEC-FEB` (equivalent to `DEC,JAN,FEB`). +* Supports time zones, and performs all the date/time conversions for you. +* Does not skip occurrences, when the clock jumps forward to Daylight saving time (known as Summer time). +* Does not skip interval-based occurrences, when the clock jumps backward from Summer time. +* Does not retry non-interval based occurrences, when the clock jumps backward from Summer time. +* Contains 1000+ unit tests to ensure everything is working correctly. + +## Compatibility + +This section explains how Cron expressions should be converted, when moving to Cronos. + +Library | Comments +--- | --- +Vixie Cron | When both day-of-month and day-of-week are specified, Cronos uses AND operator for matching (Vixie Cron uses OR operator for backward compatibility). +Quartz.NET | Cronos uses different, but more intuitive Daylight saving time handling logic (as in Vixie Cron). Full month names such as `september` aren't supported. Day-of-week field in Cronos has different values, `0` and `7` stand for Sunday, `1` for Monday, etc. (as in Vixie Cron). Year field is not supported. +NCrontab | Compatible +CronNET | Compatible + +## Installation + +Cronos is distributed as a [NuGet package](http://www.nuget.org/packages/Cronos/), you can install it from the official NuGet Gallery. Please use the following command to install it using the NuGet Package Manager Console window. + +``` +PM> Install-Package Cronos +``` + +## Usage + +We've tried to do our best to make Cronos API as simple and predictable in corner cases as possible. So you can only use `DateTime` with `DateTimeKind.Utc` specified (for example, `DateTime.UtcNow`), or `DateTimeOffset` classes to calculate next occurrences. You **can not use** local `DateTime` objects (such as `DateTime.Now`), because this may lead to ambiguity during DST transitions, and an exception will be thrown if you attempt to use them. + +To calculate the next occurrence, you need to create an instance of the `CronExpression` class, and call its `GetNextOccurrence` method. To learn about Cron format, please refer to the next section. + +```csharp +using Cronos; + +CronExpression expression = CronExpression.Parse("* * * * *"); + +DateTime? nextUtc = expression.GetNextOccurrence(DateTime.UtcNow); +``` + +The `nextUtc` will contain the next occurrence in UTC, *after the given time*, or `null` value when it is unreachable (for example, Feb 30). If an invalid Cron expression is given, the `CronFormatException` exception is thrown. + +### Working with time zones + +It is possible to specify a time zone directly, in this case you should pass `DateTime` with `DateTimeKind.Utc` flag, or use `DateTimeOffset` class, that's is smart enough to always point to an exact, non-ambiguous instant. + +```csharp +CronExpression expression = CronExpression.Parse("* * * * *"); +TimeZoneInfo easternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); + +DateTime? next = expression.GetNextOccurrence(DateTime.UtcNow, easternTimeZone); +DateTimeOffset? next = expression.GetNextOccurrence(DateTimeOffset.UtcNow, easternTimeZone); +``` + +If you passed a `DateTime` object, resulting time will be in UTC. If you used `DateTimeOffset`, resulting object will contain the **correct offset**, so don't forget to use it especially during DST transitions (see below). + +### Working with local time + +If you just want to make all the calculations using local time, you'll have to use the `DateTimeOffset` class, because as I've said earlier, `DateTime` objects may be ambiguous during Summer time transitions. You can get the resulting local time, using the `DateTimeOffset.DateTime` property. + +```csharp +CronExpression expression = CronExpression.Parse("* * * * *"); +DateTimeOffset? next = expression.GetNextOccurrence(DateTimeOffset.Now, TimeZoneInfo.Local); + +var nextLocalTime = next?.DateTime; +``` + +### Adding seconds to an expression + +If you want to specify seconds, use another overload of the `Parse` method and specify the `CronFormat` argument as below: + +```csharp +CronExpression expression = CronExpression.Parse("*/30 * * * * *", CronFormat.IncludeSeconds); +DateTime? next = expression.GetNextOccurrence(DateTime.UtcNow); +``` + +### Getting occurrences within a range + +You can also get occurrences within a fixed date/time range using the `GetOccurrences` method. By default, the `from` argument will be included when matched, and `to` argument will be excluded. However, you can configure that behavior. + +```csharp +CronExpression expression = CronExpression.Parse("* * * * *"); +IEnumerable occurrences = expression.GetOccurrences( + DateTime.UtcNow, + DateTime.UtcNow.AddYears(1), + fromInclusive: true, + toInclusive: false); +``` + +There are different overloads for this method to support `DateTimeOffset` arguments or time zones. + +## Cron format + +Cron expression is a mask to define fixed times, dates and intervals. The mask consists of second (optional), minute, hour, day-of-month, month and day-of-week fields. All of the fields allow you to specify multiple values, and any given date/time will satisfy the specified Cron expression, if all the fields contain a matching value. + + Allowed values Allowed special characters Comment + + ┌───────────── second (optional) 0-59 * , - / + │ ┌───────────── minute 0-59 * , - / + │ │ ┌───────────── hour 0-23 * , - / + │ │ │ ┌───────────── day of month 1-31 * , - / L W ? + │ │ │ │ ┌───────────── month 1-12 or JAN-DEC * , - / + │ │ │ │ │ ┌───────────── day of week 0-6 or SUN-SAT * , - / # L ? Both 0 and 7 means SUN + │ │ │ │ │ │ + * * * * * * + +### Base characters + +In all fields you can use number, `*` to mark field as *any value*, `-` to specify ranges of values. Reversed ranges like `22-1`(equivalent to `22,23,0,1,2`) are also supported. + +It's possible to define **step** combining `/` with `*`, numbers and ranges. For example, `*/5` in minute field describes *every 5 minute* and `1-15/3` in day-of-month field – *every 3 days from the 1st to the 15th*. Pay attention that `*/24` is just equivalent to `0,24,48` and `*/24` in minute field doesn't literally mean *every 24 minutes* it means *every 0,24,48 minute*. + +Concatinate values and ranges by `,`. Comma works like `OR` operator. So `3,5-11/3,12` is equivalent to `3,5,8,11,12`. + +In month and day-of-week fields, you can use names of months or days of weeks abbreviated to first three letters (`Jan-Dec` or `Mon-Sun`) instead of their numeric values. Full names like `JANUARY` or `MONDAY` **aren't supported**. + +For day of week field, both `0` and `7` stays for Sunday, 1 for Monday. + +| Expression | Description | +|----------------------|---------------------------------------------------------------------------------------| +| `* * * * *` | Every minute | +| `0 0 1 * *` | At midnight, on day 1 of every month | +| `*/5 * * * *` | Every 5 minutes | +| `30,45-15/2 1 * * *` | Every 2 minute from 1:00 AM to 01:15 AM and from 1:45 AM to 1:59 AM and at 1:30 AM | +| `0 0 * * MON-FRI` | At 00:00, Monday through Friday | + +### Special characters + +Most expressions you can describe using base characters. If you want to deal with more complex cases like *the last day of month* or *the 2nd Saturday* use special characters: + +**`L`** stands for "last". When used in the day-of-week field, it allows you to specify constructs such as *the last Friday* (`5L`or `FRIL`). In the day-of-month field, it specifies the last day of the month. + +**`W`** in day-of-month field is the nearest weekday. Use `W` with single value (not ranges, steps or `*`) to define *the nearest weekday* to the given day. In this case there are two base rules to determine occurrence: we should shift to **the nearest weekday** and **can't shift to different month**. Thus if given day is Saturday we shift to Friday, if it is Sunday we shift to Monday. **But** if given day is **the 1st day of month** (e.g. `0 0 1W * *`) and it is Saturday we shift to the 3rd Monday, if given day is **last day of month** (`0 0 31W 0 0`) and it is Sunday we shift to that Friday. Mix `L` (optionaly with offset) and `W` characters to specify *last weekday of month* `LW` or more complex like `L-5W`. + +**`#`** in day-of-week field allows to specify constructs such as *second Saturday* (`6#2` or `SAT#2`). + +**`?`** is synonym of `*`. It's supported but not obligatory, so `0 0 5 * ?` is the same as `0 0 5 * *`. + +| Expression | Description | +|-------------------|----------------------------------------------------------| +| `0 0 L * *` | At 00:00 AM on the last day of the month | +| `0 0 L-1 * *` | At 00:00 AM the day before the last day of the month | +| `0 0 3W * *` | At 00:00 AM, on the 3rd weekday of every month | +| `0 0 LW * *` | At 00:00 AM, on the last weekday of the month | +| `0 0 * * 2L` | At 00:00 AM on the last tuesday of the month | +| `0 0 * * 6#3` | At 00:00 AM on the third Saturday of the month | +| `0 0 ? 1 MON#1` | At 00:00 AM on the first Monday of the January | + +### Specify Day of month and Day of week + +You can set both **day-of-month** and **day-of-week**, it allows you to specify constructs such as **Friday the thirteenth**. Thus `0 0 13 * 5` means at 00:00, Friday the thirteenth. + +It differs from Unix crontab and Quartz cron implementations. Crontab handles it like `OR` operator: occurrence can happen in given day of month or given day of week. So `0 0 13 * 5` means *at 00:00 AM, every friday or every the 13th of a month*. Quartz doesn't allow specify both day-of-month and day-of-week. + +### Macro + +A macro is a string starting with `@` and representing a shortcut for simple cases like *every day* or *every minute*. + + Macro | Equivalent | Comment +----------------|---------------| ------- +`@every_second` | `* * * * * *` | Run once a second +`@every_minute` | `* * * * *` | Run once a minute at the beginning of the minute +`@hourly` | `0 * * * *` | Run once an hour at the beginning of the hour +`@daily` | `0 0 * * *` | Run once a day at midnight +`@midnight` | `0 0 * * *` | Run once a day at midnight +`@weekly` | `0 0 * * 0` | Run once a week at midnight on Sunday morning +`@monthly` | `0 0 1 * *` | Run once a month at midnight of the first day of the month +`@yearly` | `0 0 1 1 *` | Run once a year at midnight of 1 January +`@annually` | `0 0 1 1 *` | Run once a year at midnight of 1 January + +### Cron grammar + +Cronos parser uses following case-insensitive grammar: + +``` + cron ::= expression | macro + expression ::= [second space] minute space hour space day-of-month space month space day-of-week + second ::= field + minute ::= field + hour ::= field +day-of-month ::= '*' [step] | '?' [step] | lastday | value [ 'W' | range [list] ] + month ::= field + day-of-week ::= '*' [step] | '?' [step] | value [ dowspec | range [list] ] + macro ::= '@every_second' | '@every_minute' | '@hourly' | '@daily' | '@midnight' | '@weekly' | '@monthly'| + '@yearly' | '@annually' + field ::= '*' [step] | '?' [step] | value [range] [list] + list ::= { ',' value [range] } + range ::= '-' value [step] | [step] + step ::= '/' number + value ::= number | name + name ::= month-name | dow-name + month-name ::= 'JAN' | 'FEB' | 'MAR' | 'APR' | 'MAY' | 'JUN' | 'JUL' | 'AUG' | 'SEP' | 'OCT' | 'NOV' | 'DEC' + dow-name ::= 'SUN' | 'MON' | 'TUE' | 'WED' | 'THU' | 'FRI' | 'SAT' + dowspec ::= 'L' | '#' number + lastday ::= 'L' ['-' number] ['W'] + number ::= digit | number digit + space ::= ' ' | '\t' +``` + +## Daylight Saving Time + +Cronos is the only library to handle daylight saving time transitions in intuitive way with the same behavior as Vixie Cron (utility for *nix systems). During a spring transition, we don't skip occurrences scheduled to invalid time during. In an autumn transition we don't get duplicate occurrences for daily expressions, and don't skip interval expressions when the local time is ambiguous. + +### Transition to Summer time (in spring) + +During the transition to Summer time, the clock is moved forward, for example the next minute after `01:59 AM` is `03:00 AM`. So any daily Cron expression that should match `02:30 AM`, points to an invalid time. It doesn't exist, and can't be mapped to UTC. + +Cronos adjusts the next occurrence to the next valid time in these cases. If you use Cron to schedule jobs, you may have shorter or longer intervals between runs when this happen, but you'll not lose your jobs: + +``` +"30 02 * * *" (every day at 02:30 AM) + +Mar 13, 02:30 +03:00 – run +Mar 14, 03:00 +04:00 – run (adjusted) +Mar 15, 02:30 +04:00 – run +``` + +### Transition from Summer time (in autumn) + +When Daylight Saving Time ends you set the clocks backward so there is duration which repeats twice. For example, after `01:59 AM` you get `01:00 AM` again, so the interval between `01:00 AM` to `02:00 AM` (excluding) is ambiguous, and can be mapped to multiple UTC offsets. + +We don't want to have multiple occurrences of daily expressions during this transition, but at the same time we want to schedule interval expressions as usually, without skipping them. So we have different behavior for different Cron expressions. + +#### Interval expression + +Cron expression is **interval based** whose second, minute or hour field contains `*`, ranges or steps, e.g. `30 * * * *` (hour field), `* 1 * * *` (minute field), `0,5 0/10 1 * * *`. In this case there are expectations that occurrences should happen periodically during the day and this rule can't be broken by time transitions. Thus for **interval based** expressions occurrences will be before and after clock shifts. + +Consider `*/30 * * * *` interval expression. It should occur every 30 minutes no matter what. + +``` +Nov 08, 00:30 +04:00 – run +Nov 08, 01:00 +04:00 – run +Nov 08, 01:30 +04:00 – run +Nov 08, 01:00 +03:00 – run +Nov 08, 01:30 +03:00 – run +Nov 08, 02:00 +03:00 – run +``` + +#### Non-interval expression + +Cron expression is **non-interval based** whose second, minute or hour field **does not contain** `*`, ranges or steps, e.g. `0 30 1 * * *` or `0 0,45 1,2 * * *`. We expect they occur given number of times per day. Thus for **non-interval** expressions occurrences will be just before clock shifts. + +Consider `30 1 * * *` non-interval expression. It should occur once a day no matter what. + +``` +Nov 07, 01:30 +04:00 – run +Nov 08, 01:30 +04:00 – run +Nov 08, 01:30 +03:00 – skip +Nov 09, 01:30 +03:00 – run +``` + +## Benchmarks + +Since [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) project appeared, it's hard to ignore the performance. We tried hard to make Cronos not only feature-rich, but also really fast when parsing expressions and calculating next occurrences. As a result, Cronos is faster more than in an order of magnitude than alternative libraries, here is a small comparison: + +``` +Cronos Method | Mean | StdDev +------------------------------------------- | -------------- | ------------- +CronExpression.Parse("* * * * *") | 30.8473 ns | 0.0515 ns +CronExpression.Parse("*/10 12-20 ? DEC 3") | 81.5010 ns | 0.0924 ns +Simple.GetNextOccurrence(DateTime.UtcNow) | 123.4712 ns | 0.5928 ns +Complex.GetNextOccurrence(DateTime.UtcNow) | 212.0422 ns | 0.3997 ns + +NCrontab Method | Mean | StdDev +------------------------------------------- | -------------- | ------------- +CrontabSchedule.Parse("* * * * *") | 1,813.7313 ns | 3.3718 ns +CrontabSchedule.Parse("*/10 12-20 * DEC 3") | 3,174.3625 ns | 6.8522 ns +Simple.GetNextOccurrence(DateTime.UtcNow) | 147.7866 ns | 0.1689 ns +Complex.GetNextOccurrence(DateTime.UtcNow) | 1,001.3253 ns | 1.6205 ns + +Quartz Method | Mean | StdDev +------------------------------------------- | -------------- | ------------- +new CronExpression("* * * * * ?") | 48,157.7744 ns | 1,417.3101 ns +new CronExpression("* */10 12-20 ? DEC 3") | 33,731.9992 ns | 38.3192 ns +Simple.GetTimeAfter(DateTimeOffset.Now) | 1,416.9867 ns | 1.2784 ns +Complex.GetTimeAfter(DateTimeOffset.Now) | 6,573.0269 ns | 7.9192 ns +``` + +## License + +Copyright © 2017 Hangfire OÜ. Cronos is licensed under [The MIT License (MIT)][LICENSE]. + +[LICENSE]:LICENSE diff --git a/local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg b/local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..22ef3d39d6871195d4f5db6fbdb377acd484988b GIT binary patch literal 198128 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 TZBMqT#1ZjFm!6sa^vp0e}ie6WK0;DxLd%=o{T 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%0DvXh#GU*F{UJ1lTm~gEmkYzQ)9Ja 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 L4Fa|tgZuvg)vVnC literal 0 HcmV?d00001 diff --git a/local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg.sha512 b/local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg.sha512 new file mode 100644 index 000000000..9659f9f6b --- /dev/null +++ b/local-nugets/cronos/0.10.0/cronos.0.10.0.nupkg.sha512 @@ -0,0 +1 @@ +64VD5LS+VkoELCZnpOPRbc/jtYbKFdNFIykE/Pm7O+XB0zbwZyDQmrwYeQN6BLmmmevW/zDhBsK91Yrh0vinjQ== \ No newline at end of file diff --git a/local-nugets/cronos/0.10.0/icon.png b/local-nugets/cronos/0.10.0/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b05a2eea24801734c0f914fd576c49a14b8730ba GIT binary patch literal 2275 zcmV<92pso`P)ggW{^8rg|xrWqOir{=Iupbi^I&?cZ;jI!qa__uIujeZG)t9 zh^W%p&V;3ObWBXANBs1Y~`2-FCi1O#dXP6A`M%$5@cqA>gp z2OC2~3<4ti;(|g%)WqGG_kWt{qX=ZGpoUaU6&HSY(6;@5$J5on&`^-;TE;Nh^f#`J4tc+w?UcD(O zqiE1D$_2XZTYS}Y=i2tz?YOhuMVxZbFiHh4HfAV7+_=F1 zD$o%y|Gx40%LJq;_P-%P<0%ms52?UtUNVUcqAd@=Y9B_hkKlo>jeCKy`&`;Q6p%Pu zV}ZikhuAPoSL5L)(y_A-j9}K;{#~&_=wA(EH=88(fUO}wOx(c%TO!aotyg2jm!>@I)c$RFbmgFc?s{@MQTE)T0`I=QF?R&Z<7x-&MOpfxU<@vqh$ResC5aJeI z15(ytyUrU;(r-BfppXf!^)gZy3rp-{##b9s0{ZA(QBPQ@3roS66G&m_GM?6=wOFX5 zTM0Jdqp`eODR4v<1-eiT0hgh~PzGjK>B6%4xt|b>F%hvwv$;;l`*OBvVU-`v(8C<` zjp+FyPa=0kAFn*zSz;T?z3+&ygXDZc_vtnbfvV2yb0j;ND<-fHlz}h44^Az)1i0R0^p1 z2TUwn1Q}7gaEPHme?5i=woK>RsSMUXghJbA4K~2N)BEKydRu>6Eijz0kfI56RiA~N zM4_Q$k_l{%1-ni5<&s4=&If^<2wTdKP~e0I;V%VLER0<(a3w!F&f=iR4u2Ca6L^Ij zj+RFVv%NM-pvalNTA>~>@yA&HHv!=fd*-&CC=7++ci2d%inK*V#j}E9OT{91s#@Rw zX(m4xlyv9{v^TTX^t%&6k}uirB%puH`xc`{0yh&u_@%&IgTNG%BL;U5$?ZrSw+%hF z`5l25xxgc(oRA66Brw9YxhQq5=VOXpqwnPa?2` zWlRFiemb50MFHLMs6z6!+im6j13m)N%qI z9-9>vaJ~|_|Av72o+<8oVI?sbMt&)Q08dSSED-%vfY>hTD!{z-$_VUGvtdgFgsi&B z5r`!MPiSVA6GGYa?+@n5EY$qs0%)ES6%a@V(#_e=-XsEcN8ECyTR4w0u+`qc97H7q zm}jPY1-U>KtLK0OPII0n{AB_S-Y+8-rT`76XK^t~4cF5oDDbK~VIt5O2$xeEhR^8y<`?cT~gEU%+nfo9)CFP$cV zlZWxT+64skdj$7lViTy&w#oU15_+@xP9>lpHGcg?FC{?g#880w*x4=?VW%~3o7gAj z3D9nvoL|Gf7f0hEI;HhUCIIXtVYfTeLwuNa(BcpS4bJU{R#;od-eCK{`)@dM~kab0G|Z?yZotkHHHJORyBf*B@tj`aWl002ovPDHLkV1l3$LW=+Z literal 0 HcmV?d00001 diff --git a/local-nugets/cronos/0.10.0/lib/net40/Cronos.xml b/local-nugets/cronos/0.10.0/lib/net40/Cronos.xml new file mode 100644 index 000000000..74f9adcea --- /dev/null +++ b/local-nugets/cronos/0.10.0/lib/net40/Cronos.xml @@ -0,0 +1,211 @@ + + + + Cronos + + + +

+ Provides a parser and scheduler for cron expressions. + + + + + Represents a cron expression that fires on Jan 1st every year at midnight. + Equals to "0 0 1 1 *". + + + + + Represents a cron expression that fires every Sunday at midnight. + Equals to "0 0 * * 0". + + + + + Represents a cron expression that fires on 1st day of every month at midnight. + Equals to "0 0 1 * *". + + + + + Represents a cron expression that fires every day at midnight. + Equals to "0 0 * * *". + + + + + Represents a cron expression that fires every hour at the beginning of the hour. + Equals to "0 * * * *". + + + + + Represents a cron expression that fires every minute. + Equals to "* * * * *". + + + + + Represents a cron expression that fires every second. + Equals to "* * * * * *". + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 fields: + minute, hour, day of month, month, day of week. + If you want to parse non-standard cron expressions use with specified CronFields argument. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 or 6 fields: + second (optional), minute, hour, day of month, month, day of week. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified cron expression with the + format. + A return value indicates whether the operation succeeded. + + + + + Constructs a new based on the specified cron expression with the specified + . + A return value indicates whether the operation succeeded. + + + + + Calculates next occurrence starting with (optionally ) in UTC time zone. + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Returns the list of next occurrences within the given date/time range, + including and excluding + by default, and UTC time zone. When none of the occurrences found, an + empty list is returned. + + + + + + Returns the list of next occurrences within the given date/time range, including + and excluding by default, and + specified time zone. When none of the occurrences found, an empty list is returned. + + + + + + Returns the list of occurrences within the given date/time offset range, + including and excluding by + default. When none of the occurrences found, an empty list is returned. + + + + + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; + otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data + structures like a hash table. + + + + + Implements the operator ==. + + + + + Implements the operator !=. + + + + + Defines the cron format options that customize string parsing for . + + + + + Parsing string must contain only 5 fields: minute, hour, day of month, month, day of week. + + + + + Second field must be specified in parsing string. + + + + + Represents an exception that's thrown, when invalid Cron expression is given. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with + a specified error message. + + + + + Initializes a new instance of the class with + a specified error message and a reference to the inner exception that is the + cause of this exception. + + + + + + + diff --git a/local-nugets/cronos/0.10.0/lib/net45/Cronos.xml b/local-nugets/cronos/0.10.0/lib/net45/Cronos.xml new file mode 100644 index 000000000..74f9adcea --- /dev/null +++ b/local-nugets/cronos/0.10.0/lib/net45/Cronos.xml @@ -0,0 +1,211 @@ + + + + Cronos + + + + + Provides a parser and scheduler for cron expressions. + + + + + Represents a cron expression that fires on Jan 1st every year at midnight. + Equals to "0 0 1 1 *". + + + + + Represents a cron expression that fires every Sunday at midnight. + Equals to "0 0 * * 0". + + + + + Represents a cron expression that fires on 1st day of every month at midnight. + Equals to "0 0 1 * *". + + + + + Represents a cron expression that fires every day at midnight. + Equals to "0 0 * * *". + + + + + Represents a cron expression that fires every hour at the beginning of the hour. + Equals to "0 * * * *". + + + + + Represents a cron expression that fires every minute. + Equals to "* * * * *". + + + + + Represents a cron expression that fires every second. + Equals to "* * * * * *". + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 fields: + minute, hour, day of month, month, day of week. + If you want to parse non-standard cron expressions use with specified CronFields argument. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 or 6 fields: + second (optional), minute, hour, day of month, month, day of week. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified cron expression with the + format. + A return value indicates whether the operation succeeded. + + + + + Constructs a new based on the specified cron expression with the specified + . + A return value indicates whether the operation succeeded. + + + + + Calculates next occurrence starting with (optionally ) in UTC time zone. + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Returns the list of next occurrences within the given date/time range, + including and excluding + by default, and UTC time zone. When none of the occurrences found, an + empty list is returned. + + + + + + Returns the list of next occurrences within the given date/time range, including + and excluding by default, and + specified time zone. When none of the occurrences found, an empty list is returned. + + + + + + Returns the list of occurrences within the given date/time offset range, + including and excluding by + default. When none of the occurrences found, an empty list is returned. + + + + + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; + otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data + structures like a hash table. + + + + + Implements the operator ==. + + + + + Implements the operator !=. + + + + + Defines the cron format options that customize string parsing for . + + + + + Parsing string must contain only 5 fields: minute, hour, day of month, month, day of week. + + + + + Second field must be specified in parsing string. + + + + + Represents an exception that's thrown, when invalid Cron expression is given. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with + a specified error message. + + + + + Initializes a new instance of the class with + a specified error message and a reference to the inner exception that is the + cause of this exception. + + + + + + + diff --git a/local-nugets/cronos/0.10.0/lib/net6.0/Cronos.xml b/local-nugets/cronos/0.10.0/lib/net6.0/Cronos.xml new file mode 100644 index 000000000..74f9adcea --- /dev/null +++ b/local-nugets/cronos/0.10.0/lib/net6.0/Cronos.xml @@ -0,0 +1,211 @@ + + + + Cronos + + + + + Provides a parser and scheduler for cron expressions. + + + + + Represents a cron expression that fires on Jan 1st every year at midnight. + Equals to "0 0 1 1 *". + + + + + Represents a cron expression that fires every Sunday at midnight. + Equals to "0 0 * * 0". + + + + + Represents a cron expression that fires on 1st day of every month at midnight. + Equals to "0 0 1 * *". + + + + + Represents a cron expression that fires every day at midnight. + Equals to "0 0 * * *". + + + + + Represents a cron expression that fires every hour at the beginning of the hour. + Equals to "0 * * * *". + + + + + Represents a cron expression that fires every minute. + Equals to "* * * * *". + + + + + Represents a cron expression that fires every second. + Equals to "* * * * * *". + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 fields: + minute, hour, day of month, month, day of week. + If you want to parse non-standard cron expressions use with specified CronFields argument. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 or 6 fields: + second (optional), minute, hour, day of month, month, day of week. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified cron expression with the + format. + A return value indicates whether the operation succeeded. + + + + + Constructs a new based on the specified cron expression with the specified + . + A return value indicates whether the operation succeeded. + + + + + Calculates next occurrence starting with (optionally ) in UTC time zone. + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Returns the list of next occurrences within the given date/time range, + including and excluding + by default, and UTC time zone. When none of the occurrences found, an + empty list is returned. + + + + + + Returns the list of next occurrences within the given date/time range, including + and excluding by default, and + specified time zone. When none of the occurrences found, an empty list is returned. + + + + + + Returns the list of occurrences within the given date/time offset range, + including and excluding by + default. When none of the occurrences found, an empty list is returned. + + + + + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; + otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data + structures like a hash table. + + + + + Implements the operator ==. + + + + + Implements the operator !=. + + + + + Defines the cron format options that customize string parsing for . + + + + + Parsing string must contain only 5 fields: minute, hour, day of month, month, day of week. + + + + + Second field must be specified in parsing string. + + + + + Represents an exception that's thrown, when invalid Cron expression is given. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with + a specified error message. + + + + + Initializes a new instance of the class with + a specified error message and a reference to the inner exception that is the + cause of this exception. + + + + + + + diff --git a/local-nugets/cronos/0.10.0/lib/netstandard1.0/Cronos.xml b/local-nugets/cronos/0.10.0/lib/netstandard1.0/Cronos.xml new file mode 100644 index 000000000..3f596e8ab --- /dev/null +++ b/local-nugets/cronos/0.10.0/lib/netstandard1.0/Cronos.xml @@ -0,0 +1,208 @@ + + + + Cronos + + + + + Provides a parser and scheduler for cron expressions. + + + + + Represents a cron expression that fires on Jan 1st every year at midnight. + Equals to "0 0 1 1 *". + + + + + Represents a cron expression that fires every Sunday at midnight. + Equals to "0 0 * * 0". + + + + + Represents a cron expression that fires on 1st day of every month at midnight. + Equals to "0 0 1 * *". + + + + + Represents a cron expression that fires every day at midnight. + Equals to "0 0 * * *". + + + + + Represents a cron expression that fires every hour at the beginning of the hour. + Equals to "0 * * * *". + + + + + Represents a cron expression that fires every minute. + Equals to "* * * * *". + + + + + Represents a cron expression that fires every second. + Equals to "* * * * * *". + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 fields: + minute, hour, day of month, month, day of week. + If you want to parse non-standard cron expressions use with specified CronFields argument. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 or 6 fields: + second (optional), minute, hour, day of month, month, day of week. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified cron expression with the + format. + A return value indicates whether the operation succeeded. + + + + + Constructs a new based on the specified cron expression with the specified + . + A return value indicates whether the operation succeeded. + + + + + Calculates next occurrence starting with (optionally ) in UTC time zone. + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Returns the list of next occurrences within the given date/time range, + including and excluding + by default, and UTC time zone. When none of the occurrences found, an + empty list is returned. + + + + + + Returns the list of next occurrences within the given date/time range, including + and excluding by default, and + specified time zone. When none of the occurrences found, an empty list is returned. + + + + + + Returns the list of occurrences within the given date/time offset range, + including and excluding by + default. When none of the occurrences found, an empty list is returned. + + + + + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; + otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data + structures like a hash table. + + + + + Implements the operator ==. + + + + + Implements the operator !=. + + + + + Defines the cron format options that customize string parsing for . + + + + + Parsing string must contain only 5 fields: minute, hour, day of month, month, day of week. + + + + + Second field must be specified in parsing string. + + + + + Represents an exception that's thrown, when invalid Cron expression is given. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with + a specified error message. + + + + + Initializes a new instance of the class with + a specified error message and a reference to the inner exception that is the + cause of this exception. + + + + diff --git a/local-nugets/cronos/0.10.0/lib/netstandard2.0/Cronos.xml b/local-nugets/cronos/0.10.0/lib/netstandard2.0/Cronos.xml new file mode 100644 index 000000000..74f9adcea --- /dev/null +++ b/local-nugets/cronos/0.10.0/lib/netstandard2.0/Cronos.xml @@ -0,0 +1,211 @@ + + + + Cronos + + + + + Provides a parser and scheduler for cron expressions. + + + + + Represents a cron expression that fires on Jan 1st every year at midnight. + Equals to "0 0 1 1 *". + + + + + Represents a cron expression that fires every Sunday at midnight. + Equals to "0 0 * * 0". + + + + + Represents a cron expression that fires on 1st day of every month at midnight. + Equals to "0 0 1 * *". + + + + + Represents a cron expression that fires every day at midnight. + Equals to "0 0 * * *". + + + + + Represents a cron expression that fires every hour at the beginning of the hour. + Equals to "0 * * * *". + + + + + Represents a cron expression that fires every minute. + Equals to "* * * * *". + + + + + Represents a cron expression that fires every second. + Equals to "* * * * * *". + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 fields: + minute, hour, day of month, month, day of week. + If you want to parse non-standard cron expressions use with specified CronFields argument. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified + cron expression. It's supported expressions consisting of 5 or 6 fields: + second (optional), minute, hour, day of month, month, day of week. + See more: https://github.com/HangfireIO/Cronos + + + + + Constructs a new based on the specified cron expression with the + format. + A return value indicates whether the operation succeeded. + + + + + Constructs a new based on the specified cron expression with the specified + . + A return value indicates whether the operation succeeded. + + + + + Calculates next occurrence starting with (optionally ) in UTC time zone. + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Calculates next occurrence starting with (optionally ) in given + + + + + + Returns the list of next occurrences within the given date/time range, + including and excluding + by default, and UTC time zone. When none of the occurrences found, an + empty list is returned. + + + + + + Returns the list of next occurrences within the given date/time range, including + and excluding by default, and + specified time zone. When none of the occurrences found, an empty list is returned. + + + + + + Returns the list of occurrences within the given date/time offset range, + including and excluding by + default. When none of the occurrences found, an empty list is returned. + + + + + + + + + Determines whether the specified is equal to the current . + + The to compare with the current . + + true if the specified is equal to the current ; otherwise, false. + + + + + Determines whether the specified is equal to this instance. + + The to compare with this instance. + + true if the specified is equal to this instance; + otherwise, false. + + + + + Returns a hash code for this instance. + + + A hash code for this instance, suitable for use in hashing algorithms and data + structures like a hash table. + + + + + Implements the operator ==. + + + + + Implements the operator !=. + + + + + Defines the cron format options that customize string parsing for . + + + + + Parsing string must contain only 5 fields: minute, hour, day of month, month, day of week. + + + + + Second field must be specified in parsing string. + + + + + Represents an exception that's thrown, when invalid Cron expression is given. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with + a specified error message. + + + + + Initializes a new instance of the class with + a specified error message and a reference to the inner exception that is the + cause of this exception. + + + + + + + diff --git a/local-nugets/dnsclient/1.6.1/.nupkg.metadata b/local-nugets/dnsclient/1.6.1/.nupkg.metadata new file mode 100644 index 000000000..c6e083944 --- /dev/null +++ b/local-nugets/dnsclient/1.6.1/.nupkg.metadata @@ -0,0 +1,5 @@ +{ + "version": 2, + "contentHash": "4H/f2uYJOZ+YObZjpY9ABrKZI+JNw3uizp6oMzTXwDw6F+2qIPhpRl/1t68O/6e98+vqNiYGu+lswmwdYUy3gg==", + "source": "https://api.nuget.org/v3/index.json" +} \ No newline at end of file diff --git a/local-nugets/dnsclient/1.6.1/.signature.p7s b/local-nugets/dnsclient/1.6.1/.signature.p7s new file mode 100644 index 0000000000000000000000000000000000000000..e3a975f61e7ea3f7c3e96e4a97693a1a75ef63e7 GIT binary patch literal 9466 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 literal 0 HcmV?d00001 diff --git a/local-nugets/dnsclient/1.6.1/DnsClient.nuspec b/local-nugets/dnsclient/1.6.1/DnsClient.nuspec new file mode 100644 index 000000000..7bd30d385 --- /dev/null +++ b/local-nugets/dnsclient/1.6.1/DnsClient.nuspec @@ -0,0 +1,45 @@ + + + + DnsClient + 1.6.1 + MichaCo + Apache-2.0 + https://licenses.nuget.org/Apache-2.0 + icon.png + http://dnsclient.michaco.net/ + DnsClient.NET is a simple yet very powerful and high performance open source library for the .NET Framework to do DNS lookups + Copyright (c) 2021 Michael Conrad + dns client stub resolver name server core service discovery + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/local-nugets/dnsclient/1.6.1/dnsclient.1.6.1.nupkg b/local-nugets/dnsclient/1.6.1/dnsclient.1.6.1.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..5779c39669aae459c1887f9e90310fd7d05e13c9 GIT binary patch literal 585991 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 z

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