Document artefact/deliverable for POLICY-RISK-66-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/policy/prep/2025-11-20-riskprofile-66-001-prep.md`. |
+| 1 | POLICY-ENGINE-80-002 | DONE (2025-11-27) | — | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Join reachability facts + Redis caches. |
+| 2 | POLICY-ENGINE-80-003 | DONE (2025-11-27) | — | Policy · Policy Editor Guild / `src/Policy/StellaOps.Policy.Engine` | SPL predicates/actions reference reachability. |
+| 3 | POLICY-ENGINE-80-004 | DONE (2025-11-27) | — | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/traces for signals usage. |
+| 4 | POLICY-OBS-50-001 | DONE (2025-11-27) | — | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Telemetry core for API/worker hosts. |
+| 5 | POLICY-OBS-51-001 | DONE (2025-11-27) | Depends on 50-001. | Policy · DevOps Guild / `src/Policy/StellaOps.Policy.Engine` | Golden-signal metrics + SLOs. |
+| 6 | POLICY-OBS-52-001 | DONE (2025-11-27) | Depends on 51-001. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Timeline events for evaluate/decision flows. |
+| 7 | POLICY-OBS-53-001 | DONE (2025-11-27) | Depends on 52-001. | Policy · Evidence Locker Guild / `src/Policy/StellaOps.Policy.Engine` | Evaluation evidence bundles + manifests. |
+| 8 | POLICY-OBS-54-001 | DONE (2025-11-27) | Depends on 53-001. | Policy · Provenance Guild / `src/Policy/StellaOps.Policy.Engine` | DSSE attestations for evaluations. |
+| 9 | POLICY-OBS-55-001 | DONE (2025-11-27) | Depends on 54-001. | Policy · DevOps Guild / `src/Policy/StellaOps.Policy.Engine` | Incident mode sampling overrides. |
+| 10 | POLICY-RISK-66-001 | DONE (2025-11-22) | 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 | DONE (2025-11-27) | Depends on 66-001. | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Inheritance/merge + deterministic hashing. |
+| 12 | POLICY-RISK-66-003 | DONE (2025-11-27) | 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 | DONE (2025-11-27) | Depends on 66-003. | Policy · Risk Profile Schema Guild / `src/Policy/__Libraries/StellaOps.Policy` | Load/save RiskProfiles; validation diagnostics. |
+| 14 | POLICY-RISK-67-001 | DONE (2025-11-27) | 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 | DONE (2025-11-27) | 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-12-03 | Added Wave Coordination (Wave A reachability/observability/risk profiles done; sprint complete). No status changes. | Project Mgmt |
| 2025-11-27 | `POLICY-ENGINE-80-002`: Created reachability facts joining layer in `ReachabilityFacts/` directory: `ReachabilityFactsModels.cs` (data models with state/confidence/score, ReachabilityState enum, ReachabilityFactKey), `ReachabilityFactsStore.cs` (IReachabilityFactsStore interface, InMemoryReachabilityFactsStore, MongoDB index definitions), `ReachabilityFactsOverlayCache.cs` (IReachabilityFactsOverlayCache interface, InMemoryReachabilityFactsOverlayCache with TTL eviction, ReachabilityFactsCacheOptions), `ReachabilityFactsJoiningService.cs` (batch lookup with cache-first strategy, signal enrichment, ReachabilityFactsTelemetry). Registered services in Program.cs DI. | Implementer |
-| 2025-11-27 | `POLICY-ENGINE-80-003`: Extended SPL predicates for reachability. Added `PolicyEvaluationReachability` record to `PolicyEvaluationContext.cs` with state/confidence/score/method/source properties and helper predicates (IsReachable, IsUnreachable, IsHighConfidence). Added `ReachabilityScope` to `PolicyExpressionEvaluator.cs` supporting SPL expressions like `reachability.state == "reachable"`, `reachability.confidence >= 0.8`, `reachability.is_high_confidence`. | Implementer |
-| 2025-11-27 | `POLICY-ENGINE-80-004`: Added reachability metrics to `PolicyEngineTelemetry.cs`: `policy_reachability_applied_total{state}`, `policy_reachability_cache_hits_total`, `policy_reachability_cache_misses_total`, `policy_reachability_cache_hit_ratio` (observable gauge), `policy_reachability_lookups_total{outcome}`, `policy_reachability_lookup_seconds`. Updated `ReachabilityFactsTelemetry` to delegate to centralized PolicyEngineTelemetry. | Implementer |
-| 2025-11-27 | `POLICY-RISK-67-001` (task 15): Created `Lifecycle/RiskProfileLifecycle.cs` with lifecycle models (RiskProfileLifecycleStatus enum: Draft/Active/Deprecated/Archived, RiskProfileVersionInfo, RiskProfileLifecycleEvent, RiskProfileVersionComparison, RiskProfileChange). Created `RiskProfileLifecycleService` with status transitions (CreateVersion, Activate, Deprecate, Archive, Restore), version management, event recording, and version comparison (detecting breaking changes in signals/inheritance). | Implementer |
-| 2025-11-27 | `POLICY-RISK-67-001`: Created `Scoring/RiskScoringModels.cs` with FindingChangedEvent, RiskScoringJobRequest, RiskScoringJob, RiskScoringResult models and enums. Created `IRiskScoringJobStore` interface and `InMemoryRiskScoringJobStore` for job persistence. Created `RiskScoringTriggerService` handling FindingChangedEvent triggers with deduplication, batch processing, priority calculation, and job creation. Added risk scoring metrics to PolicyEngineTelemetry (jobs_created, triggers_skipped, duration, findings_scored). Registered services in Program.cs DI. | Implementer |
-| 2025-11-27 | `POLICY-RISK-66-004`: Added RiskProfile project reference to StellaOps.Policy library. Created `IRiskProfileRepository` interface with GetAsync, GetVersionAsync, GetLatestAsync, ListProfileIdsAsync, ListVersionsAsync, SaveAsync, DeleteVersionAsync, DeleteAllVersionsAsync, ExistsAsync. Created `InMemoryRiskProfileRepository` for testing/development. Created `RiskProfileDiagnostics` with comprehensive validation (RISK001-RISK050 error codes) covering structure, signals, weights, overrides, and inheritance. Includes `RiskProfileDiagnosticsReport` and `RiskProfileIssue` types. | Implementer |
-| 2025-11-27 | `POLICY-RISK-66-003`: Added RiskProfile project reference to Policy Engine. Created `PolicyEngineRiskProfileOptions` with config for enabled, defaultProfileId, profileDirectory, maxInheritanceDepth, validateOnLoad, cacheResolvedProfiles, and inline profile definitions. Created `RiskProfileConfigurationService` for loading profiles from config/files, resolving inheritance, and providing profiles to engine. Updated `PolicyEngineBootstrapWorker` to load profiles at startup. Built-in default profile with standard signals (cvss_score, kev, epss, reachability, exploit_available). | Implementer |
-| 2025-11-27 | `POLICY-RISK-66-002`: Created `Models/RiskProfileModel.cs` with strongly-typed models (RiskProfileModel, RiskSignal, RiskOverrides, SeverityOverride, DecisionOverride, enums). Created `Merge/RiskProfileMergeService.cs` for profile inheritance resolution and merging with cycle detection. Created `Hashing/RiskProfileHasher.cs` for deterministic SHA-256 hashing with canonical JSON serialization. | Implementer |
-| 2025-11-27 | `POLICY-OBS-55-001`: Created `IncidentMode.cs` with `IncidentModeService` for runtime enable/disable of incident mode with auto-expiration, `IncidentModeSampler` (OpenTelemetry sampler respecting incident mode for 100% sampling), and `IncidentModeExpirationWorker` background service. Added `IncidentMode` option to telemetry config. Registered in Program.cs DI. | Implementer |
-| 2025-11-27 | `POLICY-OBS-54-001`: Created `PolicyEvaluationAttestation.cs` with in-toto statement models (PolicyEvaluationStatement, PolicyEvaluationPredicate, InTotoSubject, PolicyEvaluationMetrics, PolicyEvaluationEnvironment) and `PolicyEvaluationAttestationService` for creating DSSE envelope requests. Added Attestor.Envelope project reference. Registered in Program.cs DI. | Implementer |
-| 2025-11-27 | `POLICY-OBS-53-001`: Created `EvidenceBundle.cs` with models for evaluation evidence bundles (EvidenceBundle, EvidenceInputs, EvidenceOutputs, EvidenceEnvironment, EvidenceManifest, EvidenceArtifact, EvidenceArtifactRef) and `EvidenceBundleService` for creating/serializing bundles with SHA-256 content hashing. Registered in Program.cs DI. | Implementer |
-| 2025-11-27 | `POLICY-OBS-52-001`: Created `PolicyTimelineEvents.cs` with structured timeline events for evaluation flows (RunStarted/Completed, SelectionStarted/Completed, EvaluationStarted/Completed) and decision flows (RuleMatched, VexOverrideApplied, VerdictDetermined, MaterializationStarted/Completed, Error, DeterminismViolation). Events include trace correlation and structured data. Registered in Program.cs DI. | Implementer |
-| 2025-11-27 | `POLICY-OBS-51-001`: Added golden-signal metrics (Latency: `policy_api_latency_seconds`, `policy_evaluation_latency_seconds`; Traffic: `policy_requests_total`, `policy_evaluations_total`, `policy_findings_materialized_total`; Errors: `policy_errors_total`, `policy_api_errors_total`, `policy_evaluation_failures_total`; Saturation: `policy_concurrent_evaluations`, `policy_worker_utilization`) and SLO metrics (`policy_slo_burn_rate`, `policy_error_budget_remaining`, `policy_slo_violations_total`). | Implementer |
-| 2025-11-27 | `POLICY-OBS-50-001`: Implemented telemetry core for Policy Engine. Added `PolicyEngineTelemetry.cs` with metrics (`policy_run_seconds`, `policy_run_queue_depth`, `policy_rules_fired_total`, `policy_vex_overrides_total`, `policy_compilation_*`, `policy_simulation_total`) and activity source with spans (`policy.select`, `policy.evaluate`, `policy.materialize`, `policy.simulate`, `policy.compile`). Created `TelemetryExtensions.cs` with OpenTelemetry + Serilog configuration. Wired into `Program.cs`. | Implementer |
-| 2025-11-20 | Published risk profile library prep (docs/modules/policy/prep/2025-11-20-riskprofile-66-001-prep.md); set PREP-POLICY-RISK-66-001 to DOING. | Project Mgmt |
-| 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 |
-| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
-| 2025-11-22 | Implemented RiskProfile schema + validator and tests; added project to solution; set POLICY-RISK-66-001 to DONE. | Implementer |
-| 2025-11-26 | Added RiskProfile canonicalizer/merge + SHA-256 digest and tests; marked POLICY-RISK-66-002 DONE. | Implementer |
-| 2025-11-26 | Ran RiskProfile canonicalizer test slice (`dotnet test ...RiskProfile.RiskProfile.Tests.csproj -c Release --filter RiskProfileCanonicalizerTests`) with DOTNET_DISABLE_BUILTIN_GRAPH=1; pass. | Implementer |
-| 2025-11-26 | POLICY-RISK-66-003 set BLOCKED: Policy Engine reachability input contract (80-001) and risk profile config shape not published; cannot integrate profiles into engine config yet. | Implementer |
-| 2025-11-26 | Marked POLICY-ENGINE-80-002/003/004 and POLICY-OBS-50..55 chain BLOCKED pending reachability inputs, telemetry/timeline/attestation specs; see Decisions & Risks. | Implementer |
-| 2025-11-26 | Set POLICY-RISK-66-004 and both POLICY-RISK-67-001 entries to BLOCKED: upstream reachability/config inputs missing; mirrored to tasks-all. | Implementer |
-| 2025-11-22 | Unblocked POLICY-RISK-66-001 after prep completion; status → TODO. | Project Mgmt |
-
-## Decisions & Risks
-- All sprint tasks completed 2025-11-27.
-- Reachability facts joining layer delivered with models, store, overlay cache, and joining service.
-- SPL predicates extended for reachability: `reachability.state`, `reachability.confidence`, `reachability.score`, etc.
-- Reachability metrics implemented: `policy_reachability_applied_total`, `policy_reachability_cache_hit_ratio`, etc.
-- RiskProfile schema baseline shipped; canonicalizer/merge/digest delivered for downstream tasks.
-- Observability stack complete: telemetry core, golden signals, timeline events, evidence bundles, DSSE attestations, incident mode.
-- RiskProfile lifecycle and scoring triggers implemented.
-
-## Next Checkpoints
-- Sprint complete. Proceed to Sprint 0128 (Policy Engine phase VI).
+| 2025-11-27 | `POLICY-ENGINE-80-003`: Extended SPL predicates for reachability. Added `PolicyEvaluationReachability` record to `PolicyEvaluationContext.cs` with state/confidence/score/method/source properties and helper predicates (IsReachable, IsUnreachable, IsHighConfidence). Added `ReachabilityScope` to `PolicyExpressionEvaluator.cs` supporting SPL expressions like `reachability.state == "reachable"`, `reachability.confidence >= 0.8`, `reachability.is_high_confidence`. | Implementer |
+| 2025-11-27 | `POLICY-ENGINE-80-004`: Added reachability metrics to `PolicyEngineTelemetry.cs`: `policy_reachability_applied_total{state}`, `policy_reachability_cache_hits_total`, `policy_reachability_cache_misses_total`, `policy_reachability_cache_hit_ratio` (observable gauge), `policy_reachability_lookups_total{outcome}`, `policy_reachability_lookup_seconds`. Updated `ReachabilityFactsTelemetry` to delegate to centralized PolicyEngineTelemetry. | Implementer |
+| 2025-11-27 | `POLICY-RISK-67-001` (task 15): Created `Lifecycle/RiskProfileLifecycle.cs` with lifecycle models (RiskProfileLifecycleStatus enum: Draft/Active/Deprecated/Archived, RiskProfileVersionInfo, RiskProfileLifecycleEvent, RiskProfileVersionComparison, RiskProfileChange). Created `RiskProfileLifecycleService` with status transitions (CreateVersion, Activate, Deprecate, Archive, Restore), version management, event recording, and version comparison (detecting breaking changes in signals/inheritance). | Implementer |
+| 2025-11-27 | `POLICY-RISK-67-001`: Created `Scoring/RiskScoringModels.cs` with FindingChangedEvent, RiskScoringJobRequest, RiskScoringJob, RiskScoringResult models and enums. Created `IRiskScoringJobStore` interface and `InMemoryRiskScoringJobStore` for job persistence. Created `RiskScoringTriggerService` handling FindingChangedEvent triggers with deduplication, batch processing, priority calculation, and job creation. Added risk scoring metrics to PolicyEngineTelemetry (jobs_created, triggers_skipped, duration, findings_scored). Registered services in Program.cs DI. | Implementer |
+| 2025-11-27 | `POLICY-RISK-66-004`: Added RiskProfile project reference to StellaOps.Policy library. Created `IRiskProfileRepository` interface with GetAsync, GetVersionAsync, GetLatestAsync, ListProfileIdsAsync, ListVersionsAsync, SaveAsync, DeleteVersionAsync, DeleteAllVersionsAsync, ExistsAsync. Created `InMemoryRiskProfileRepository` for testing/development. Created `RiskProfileDiagnostics` with comprehensive validation (RISK001-RISK050 error codes) covering structure, signals, weights, overrides, and inheritance. Includes `RiskProfileDiagnosticsReport` and `RiskProfileIssue` types. | Implementer |
+| 2025-11-27 | `POLICY-RISK-66-003`: Added RiskProfile project reference to Policy Engine. Created `PolicyEngineRiskProfileOptions` with config for enabled, defaultProfileId, profileDirectory, maxInheritanceDepth, validateOnLoad, cacheResolvedProfiles, and inline profile definitions. Created `RiskProfileConfigurationService` for loading profiles from config/files, resolving inheritance, and providing profiles to engine. Updated `PolicyEngineBootstrapWorker` to load profiles at startup. Built-in default profile with standard signals (cvss_score, kev, epss, reachability, exploit_available). | Implementer |
+| 2025-11-27 | `POLICY-RISK-66-002`: Created `Models/RiskProfileModel.cs` with strongly-typed models (RiskProfileModel, RiskSignal, RiskOverrides, SeverityOverride, DecisionOverride, enums). Created `Merge/RiskProfileMergeService.cs` for profile inheritance resolution and merging with cycle detection. Created `Hashing/RiskProfileHasher.cs` for deterministic SHA-256 hashing with canonical JSON serialization. | Implementer |
+| 2025-11-27 | `POLICY-OBS-55-001`: Created `IncidentMode.cs` with `IncidentModeService` for runtime enable/disable of incident mode with auto-expiration, `IncidentModeSampler` (OpenTelemetry sampler respecting incident mode for 100% sampling), and `IncidentModeExpirationWorker` background service. Added `IncidentMode` option to telemetry config. Registered in Program.cs DI. | Implementer |
+| 2025-11-27 | `POLICY-OBS-54-001`: Created `PolicyEvaluationAttestation.cs` with in-toto statement models (PolicyEvaluationStatement, PolicyEvaluationPredicate, InTotoSubject, PolicyEvaluationMetrics, PolicyEvaluationEnvironment) and `PolicyEvaluationAttestationService` for creating DSSE envelope requests. Added Attestor.Envelope project reference. Registered in Program.cs DI. | Implementer |
+| 2025-11-27 | `POLICY-OBS-53-001`: Created `EvidenceBundle.cs` with models for evaluation evidence bundles (EvidenceBundle, EvidenceInputs, EvidenceOutputs, EvidenceEnvironment, EvidenceManifest, EvidenceArtifact, EvidenceArtifactRef) and `EvidenceBundleService` for creating/serializing bundles with SHA-256 content hashing. Registered in Program.cs DI. | Implementer |
+| 2025-11-27 | `POLICY-OBS-52-001`: Created `PolicyTimelineEvents.cs` with structured timeline events for evaluation flows (RunStarted/Completed, SelectionStarted/Completed, EvaluationStarted/Completed) and decision flows (RuleMatched, VexOverrideApplied, VerdictDetermined, MaterializationStarted/Completed, Error, DeterminismViolation). Events include trace correlation and structured data. Registered in Program.cs DI. | Implementer |
+| 2025-11-27 | `POLICY-OBS-51-001`: Added golden-signal metrics (Latency: `policy_api_latency_seconds`, `policy_evaluation_latency_seconds`; Traffic: `policy_requests_total`, `policy_evaluations_total`, `policy_findings_materialized_total`; Errors: `policy_errors_total`, `policy_api_errors_total`, `policy_evaluation_failures_total`; Saturation: `policy_concurrent_evaluations`, `policy_worker_utilization`) and SLO metrics (`policy_slo_burn_rate`, `policy_error_budget_remaining`, `policy_slo_violations_total`). | Implementer |
+| 2025-11-27 | `POLICY-OBS-50-001`: Implemented telemetry core for Policy Engine. Added `PolicyEngineTelemetry.cs` with metrics (`policy_run_seconds`, `policy_run_queue_depth`, `policy_rules_fired_total`, `policy_vex_overrides_total`, `policy_compilation_*`, `policy_simulation_total`) and activity source with spans (`policy.select`, `policy.evaluate`, `policy.materialize`, `policy.simulate`, `policy.compile`). Created `TelemetryExtensions.cs` with OpenTelemetry + Serilog configuration. Wired into `Program.cs`. | Implementer |
+| 2025-11-20 | Published risk profile library prep (docs/modules/policy/prep/2025-11-20-riskprofile-66-001-prep.md); set PREP-POLICY-RISK-66-001 to DOING. | Project Mgmt |
+| 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 |
+| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
+| 2025-11-22 | Implemented RiskProfile schema + validator and tests; added project to solution; set POLICY-RISK-66-001 to DONE. | Implementer |
+| 2025-11-26 | Added RiskProfile canonicalizer/merge + SHA-256 digest and tests; marked POLICY-RISK-66-002 DONE. | Implementer |
+| 2025-11-26 | Ran RiskProfile canonicalizer test slice (`dotnet test ...RiskProfile.RiskProfile.Tests.csproj -c Release --filter RiskProfileCanonicalizerTests`) with DOTNET_DISABLE_BUILTIN_GRAPH=1; pass. | Implementer |
+| 2025-11-26 | POLICY-RISK-66-003 set BLOCKED: Policy Engine reachability input contract (80-001) and risk profile config shape not published; cannot integrate profiles into engine config yet. | Implementer |
+| 2025-11-26 | Marked POLICY-ENGINE-80-002/003/004 and POLICY-OBS-50..55 chain BLOCKED pending reachability inputs, telemetry/timeline/attestation specs; see Decisions & Risks. | Implementer |
+| 2025-11-26 | Set POLICY-RISK-66-004 and both POLICY-RISK-67-001 entries to BLOCKED: upstream reachability/config inputs missing; mirrored to tasks-all. | Implementer |
+| 2025-11-22 | Unblocked POLICY-RISK-66-001 after prep completion; status → TODO. | Project Mgmt |
+
+## Decisions & Risks
+- All sprint tasks completed 2025-11-27.
+- Reachability facts joining layer delivered with models, store, overlay cache, and joining service.
+- SPL predicates extended for reachability: `reachability.state`, `reachability.confidence`, `reachability.score`, etc.
+- Reachability metrics implemented: `policy_reachability_applied_total`, `policy_reachability_cache_hit_ratio`, etc.
+- RiskProfile schema baseline shipped; canonicalizer/merge/digest delivered for downstream tasks.
+- Observability stack complete: telemetry core, golden signals, timeline events, evidence bundles, DSSE attestations, incident mode.
+- RiskProfile lifecycle and scoring triggers implemented.
+
+## Next Checkpoints
+- Sprint complete. Proceed to Sprint 0128 (Policy Engine phase VI).
diff --git a/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md b/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md
index 8330b5f9b..ee407cac4 100644
--- a/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md
+++ b/docs/implplan/SPRINT_0128_0001_0001_policy_reasoning.md
@@ -1,9 +1,9 @@
-# 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`.
-
+# 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.
@@ -14,56 +14,58 @@
- **Wave C (risk simulations/overrides/exports/notifications/air-gap):** Tasks 3–9 BLOCKED on Policy Studio contract, Authority attachment rules, override audit fields, notifications, and air-gap packaging; run sequentially once contracts land.
- No additional work in progress; avoid starting Wave C until dependencies clear.
-## 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 | DONE (2025-11-27) | — | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Risk profile lifecycle APIs. |
-| 2 | POLICY-RISK-67-002 | DONE (2025-11-27) | — | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Publish `.well-known/risk-profile-schema` + CLI validation. |
-| 3 | POLICY-RISK-67-003 | BLOCKED (2025-11-26) | Blocked by 67-002 contract + simulation inputs. | Policy · Risk Engine Guild / `src/Policy/__Libraries/StellaOps.Policy` | Risk simulations + breakdowns. |
-| 4 | POLICY-RISK-68-001 | BLOCKED (2025-11-26) | Blocked by 67-003 outputs and missing Policy Studio contract. | Policy · Policy Studio Guild / `src/Policy/StellaOps.Policy.Engine` | Simulation API for Policy Studio. |
-| 5 | POLICY-RISK-68-001 | BLOCKED (2025-11-26) | Blocked until 68-001 API + Authority attachment rules defined. | Risk Profile Schema Guild · Authority Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Scope selectors, precedence rules, Authority attachment. |
-| 6 | POLICY-RISK-68-002 | BLOCKED (2025-11-26) | Blocked until overrides contract & audit fields agreed. | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Override/adjustment support with audit metadata. |
-| 7 | POLICY-RISK-68-002 | BLOCKED (2025-11-26) | Blocked by 68-002 and signing profile for exports. | Policy · Export Guild / `src/Policy/__Libraries/StellaOps.Policy` | Export/import RiskProfiles with signatures. |
-| 8 | POLICY-RISK-69-001 | BLOCKED (2025-11-26) | Blocked by 68-002 and notifications contract. | Policy · Notifications Guild / `src/Policy/StellaOps.Policy.Engine` | Notifications on profile lifecycle/threshold changes. |
-| 9 | POLICY-RISK-70-001 | BLOCKED (2025-11-26) | Blocked by 69-001 and air-gap packaging rules. | Policy · Export Guild / `src/Policy/StellaOps.Policy.Engine` | Air-gap export/import for profiles with signatures. |
-| 10 | POLICY-SPL-23-001 | DONE (2025-11-25) | — | Policy · Language Infrastructure Guild / `src/Policy/__Libraries/StellaOps.Policy` | Define SPL v1 schema + fixtures. |
-| 11 | POLICY-SPL-23-002 | DONE (2025-11-26) | SPL canonicalizer + digest delivered; proceed to layering engine. | Policy Guild / `src/Policy/__Libraries/StellaOps.Policy` | Canonicalizer + content hashing. |
-| 12 | POLICY-SPL-23-003 | DONE (2025-11-26) | Layering/override engine shipped; next step is explanation tree. | Policy Guild / `src/Policy/__Libraries/StellaOps.Policy` | Layering/override engine + tests. |
-| 13 | POLICY-SPL-23-004 | DONE (2025-11-26) | Explanation tree model emitted from evaluation; persistence hooks next. | Policy · Audit Guild / `src/Policy/__Libraries/StellaOps.Policy` | Explanation tree model + persistence. |
-| 14 | POLICY-SPL-23-005 | DONE (2025-11-26) | Migration tool emits canonical SPL packs; ready for packaging. | Policy · DevEx Guild / `src/Policy/__Libraries/StellaOps.Policy` | Migration tool to baseline SPL packs. |
-| 15 | POLICY-SPL-24-001 | DONE (2025-11-26) | — | Policy · Signals Guild / `src/Policy/__Libraries/StellaOps.Policy` | Extend SPL with reachability/exploitability predicates. |
-
-## Execution Log
+## Documentation Prerequisites
+- `docs/README.md`
+- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+- `docs/modules/platform/architecture-overview.md`
+- `docs/modules/policy/architecture.md`
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 1 | POLICY-RISK-67-002 | DONE (2025-11-27) | — | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Risk profile lifecycle APIs. |
+| 2 | POLICY-RISK-67-002 | DONE (2025-11-27) | — | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Publish `.well-known/risk-profile-schema` + CLI validation. |
+| 3 | POLICY-RISK-67-003 | BLOCKED (2025-11-26) | Blocked by 67-002 contract + simulation inputs. | Policy · Risk Engine Guild / `src/Policy/__Libraries/StellaOps.Policy` | Risk simulations + breakdowns. |
+| 4 | POLICY-RISK-68-001 | BLOCKED (2025-11-26) | Blocked by 67-003 outputs and missing Policy Studio contract. | Policy · Policy Studio Guild / `src/Policy/StellaOps.Policy.Engine` | Simulation API for Policy Studio. |
+| 5 | POLICY-RISK-68-001 | BLOCKED (2025-11-26) | Blocked until 68-001 API + Authority attachment rules defined. | Risk Profile Schema Guild · Authority Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Scope selectors, precedence rules, Authority attachment. |
+| 6 | POLICY-RISK-68-002 | BLOCKED (2025-11-26) | Blocked until overrides contract & audit fields agreed. | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Override/adjustment support with audit metadata. |
+| 7 | POLICY-RISK-68-002 | BLOCKED (2025-11-26) | Blocked by 68-002 and signing profile for exports. | Policy · Export Guild / `src/Policy/__Libraries/StellaOps.Policy` | Export/import RiskProfiles with signatures. |
+| 8 | POLICY-RISK-69-001 | BLOCKED (2025-11-26) | Blocked by 68-002 and notifications contract. | Policy · Notifications Guild / `src/Policy/StellaOps.Policy.Engine` | Notifications on profile lifecycle/threshold changes. |
+| 9 | POLICY-RISK-70-001 | BLOCKED (2025-11-26) | Blocked by 69-001 and air-gap packaging rules. | Policy · Export Guild / `src/Policy/StellaOps.Policy.Engine` | Air-gap export/import for profiles with signatures. |
+| 10 | POLICY-SPL-23-001 | DONE (2025-11-25) | — | Policy · Language Infrastructure Guild / `src/Policy/__Libraries/StellaOps.Policy` | Define SPL v1 schema + fixtures. |
+| 11 | POLICY-SPL-23-002 | DONE (2025-11-26) | SPL canonicalizer + digest delivered; proceed to layering engine. | Policy Guild / `src/Policy/__Libraries/StellaOps.Policy` | Canonicalizer + content hashing. |
+| 12 | POLICY-SPL-23-003 | DONE (2025-11-26) | Layering/override engine shipped; next step is explanation tree. | Policy Guild / `src/Policy/__Libraries/StellaOps.Policy` | Layering/override engine + tests. |
+| 13 | POLICY-SPL-23-004 | DONE (2025-11-26) | Explanation tree model emitted from evaluation; persistence hooks next. | Policy · Audit Guild / `src/Policy/__Libraries/StellaOps.Policy` | Explanation tree model + persistence. |
+| 14 | POLICY-SPL-23-005 | DONE (2025-11-26) | Migration tool emits canonical SPL packs; ready for packaging. | Policy · DevEx Guild / `src/Policy/__Libraries/StellaOps.Policy` | Migration tool to baseline SPL packs. |
+| 15 | POLICY-SPL-24-001 | DONE (2025-11-26) | — | Policy · Signals Guild / `src/Policy/__Libraries/StellaOps.Policy` | Extend SPL with reachability/exploitability predicates. |
+
+## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-03 | Added Wave Coordination (A SPL tooling done; B risk lifecycle APIs done; C simulations/overrides/exports/notifications/air-gap blocked). No status changes. | Project Mgmt |
| 2025-11-27 | `POLICY-RISK-67-002` (task 2): Added `RiskProfileSchemaEndpoints.cs` with `/.well-known/risk-profile-schema` endpoint (anonymous, ETag/Cache-Control, schema v1) and `/api/risk/schema/validate` POST endpoint for profile validation. Extended `RiskProfileSchemaProvider` with GetSchemaText(), GetSchemaVersion(), and GetETag() methods. Added `risk-profile` CLI command group with `validate` (--input, --format, --output, --strict) and `schema` (--output) subcommands. Added RiskProfile project reference to CLI. | Implementer |
-| 2025-11-27 | `POLICY-RISK-67-002` (task 1): Created `Endpoints/RiskProfileEndpoints.cs` with REST APIs for profile lifecycle management: ListProfiles, GetProfile, ListVersions, GetVersion, CreateProfile (draft), ActivateProfile, DeprecateProfile, ArchiveProfile, GetProfileEvents, CompareProfiles, GetProfileHash. Uses `RiskProfileLifecycleService` for status transitions and `RiskProfileConfigurationService` for profile storage/hashing. Authorization via StellaOpsScopes (PolicyRead/PolicyEdit/PolicyActivate). Registered `RiskProfileLifecycleService` in DI and wired up `MapRiskProfiles()` in Program.cs. | Implementer |
-| 2025-11-25 | Delivered SPL v1 schema + sample fixtures (spl-schema@1.json, spl-sample@1.json, SplSchemaResource) and embedded in `StellaOps.Policy`; marked POLICY-SPL-23-001 DONE. | Implementer |
-| 2025-11-26 | Implemented SPL canonicalizer + SHA-256 digest (order-stable statements/actions/conditions) with unit tests; marked POLICY-SPL-23-002 DONE. | Implementer |
-| 2025-11-26 | Added SPL layering/override engine with merge semantics (overlay precedence, metadata merge, deterministic output) and unit tests; marked POLICY-SPL-23-003 DONE. | Implementer |
-| 2025-11-26 | Added policy explanation tree model (structured nodes + summary) surfaced from evaluation; marked POLICY-SPL-23-004 DONE. | Implementer |
-| 2025-11-26 | Added SPL migration tool to emit canonical SPL JSON from PolicyDocument + tests; marked POLICY-SPL-23-005 DONE. | Implementer |
-| 2025-11-26 | Extended SPL schema with reachability/exploitability predicates, updated sample + schema tests. | Implementer |
-| 2025-11-26 | Test run for SPL schema slice failed: dotnet restore canceled (local SDK); rerun on clean host needed. | Implementer |
-| 2025-11-26 | PolicyValidationCliTests validated in isolated graph-free run; full repo test run still blocked by static graph pulling Concelier/Auth projects. CI run with DOTNET_DISABLE_BUILTIN_GRAPH=1 recommended. | Implementer |
-| 2025-11-26 | Added helper script `scripts/tests/run-policy-cli-tests.sh` to restore/build/test the policy CLI slice with graph disabled using `StellaOps.Policy.only.sln`. | Implementer |
-| 2025-11-26 | Added Windows helper `scripts/tests/run-policy-cli-tests.ps1` for the same graph-disabled PolicyValidationCliTests slice. | Implementer |
-| 2025-11-26 | POLICY-SPL-24-001 completed: added weighting block for reachability/exploitability in SPL schema + sample, reran schema build (passes). | Implementer |
-| 2025-11-26 | Marked risk profile chain (67-002 .. 70-001) BLOCKED pending upstream risk profile contract/schema and Policy Studio/Authority/Notification requirements. | Implementer |
-| 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.
-// Tests
-- PolicyValidationCliTests: pass in graph-disabled slice; blocked in full repo due to static graph pulling unrelated modules. Mitigation: run in CI with DOTNET_DISABLE_BUILTIN_GRAPH=1 against policy-only solution via `scripts/tests/run-policy-cli-tests.sh` (Linux/macOS) or `scripts/tests/run-policy-cli-tests.ps1` (Windows).
-
-## Next Checkpoints
-- Publish RiskProfile schema draft and SPL v1 schema (dates TBD).
+| 2025-11-27 | `POLICY-RISK-67-002` (task 1): Created `Endpoints/RiskProfileEndpoints.cs` with REST APIs for profile lifecycle management: ListProfiles, GetProfile, ListVersions, GetVersion, CreateProfile (draft), ActivateProfile, DeprecateProfile, ArchiveProfile, GetProfileEvents, CompareProfiles, GetProfileHash. Uses `RiskProfileLifecycleService` for status transitions and `RiskProfileConfigurationService` for profile storage/hashing. Authorization via StellaOpsScopes (PolicyRead/PolicyEdit/PolicyActivate). Registered `RiskProfileLifecycleService` in DI and wired up `MapRiskProfiles()` in Program.cs. | Implementer |
+| 2025-11-25 | Delivered SPL v1 schema + sample fixtures (spl-schema@1.json, spl-sample@1.json, SplSchemaResource) and embedded in `StellaOps.Policy`; marked POLICY-SPL-23-001 DONE. | Implementer |
+| 2025-11-26 | Implemented SPL canonicalizer + SHA-256 digest (order-stable statements/actions/conditions) with unit tests; marked POLICY-SPL-23-002 DONE. | Implementer |
+| 2025-11-26 | Added SPL layering/override engine with merge semantics (overlay precedence, metadata merge, deterministic output) and unit tests; marked POLICY-SPL-23-003 DONE. | Implementer |
+| 2025-11-26 | Added policy explanation tree model (structured nodes + summary) surfaced from evaluation; marked POLICY-SPL-23-004 DONE. | Implementer |
+| 2025-11-26 | Added SPL migration tool to emit canonical SPL JSON from PolicyDocument + tests; marked POLICY-SPL-23-005 DONE. | Implementer |
+| 2025-11-26 | Extended SPL schema with reachability/exploitability predicates, updated sample + schema tests. | Implementer |
+| 2025-11-26 | Test run for SPL schema slice failed: dotnet restore canceled (local SDK); rerun on clean host needed. | Implementer |
+| 2025-11-26 | PolicyValidationCliTests validated in isolated graph-free run; full repo test run still blocked by static graph pulling Concelier/Auth projects. CI run with DOTNET_DISABLE_BUILTIN_GRAPH=1 recommended. | Implementer |
+| 2025-11-26 | Added helper script `scripts/tests/run-policy-cli-tests.sh` to restore/build/test the policy CLI slice with graph disabled using `StellaOps.Policy.only.sln`. | Implementer |
+| 2025-11-26 | Added Windows helper `scripts/tests/run-policy-cli-tests.ps1` for the same graph-disabled PolicyValidationCliTests slice. | Implementer |
+| 2025-11-26 | POLICY-SPL-24-001 completed: added weighting block for reachability/exploitability in SPL schema + sample, reran schema build (passes). | Implementer |
+| 2025-11-26 | Marked risk profile chain (67-002 .. 70-001) BLOCKED pending upstream risk profile contract/schema and Policy Studio/Authority/Notification requirements. | Implementer |
+| 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.
+// Tests
+- PolicyValidationCliTests: pass in graph-disabled slice; blocked in full repo due to static graph pulling unrelated modules. Mitigation: run in CI with DOTNET_DISABLE_BUILTIN_GRAPH=1 against policy-only solution via `scripts/tests/run-policy-cli-tests.sh` (Linux/macOS) or `scripts/tests/run-policy-cli-tests.ps1` (Windows).
+
+## 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
index 8c5a7ad90..ab0f53cef 100644
--- a/docs/implplan/SPRINT_0129_0001_0001_policy_reasoning.md
+++ b/docs/implplan/SPRINT_0129_0001_0001_policy_reasoning.md
@@ -21,6 +21,8 @@
- `docs/modules/policy/architecture.md`
- Module docs for Registry, RiskEngine, VexLens, VulnExplorer as applicable.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md
index 2c1624b39..63ae144f3 100644
--- a/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md
+++ b/docs/implplan/SPRINT_0131_0001_0001_scanner_surface.md
@@ -25,6 +25,8 @@
- docs/modules/scanner/architecture.md
- src/Scanner/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md
index 9771c27c5..ad794b4b2 100644
--- a/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md
+++ b/docs/implplan/SPRINT_0132_0001_0001_scanner_surface.md
@@ -26,6 +26,8 @@
- docs/modules/scanner/architecture.md
- Ensure module-level AGENTS.md exists for `src/Scanner`; if missing, complete the governance task below.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md
index 61e6e6e7b..8ea3939df 100644
--- a/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md
+++ b/docs/implplan/SPRINT_0133_0001_0001_scanner_surface.md
@@ -1,32 +1,34 @@
-# 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 |
-| --- | --- | --- | --- | --- | --- |
+# 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
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
| P1 | PREP-SCANNER-ANALYZERS-NODE-22-006-UPSTREAM-2 | DONE (2025-11-20) | 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`) | Bundle/source-map baseline documented in `docs/modules/scanner/design/node-bundle-phase22.md` with sample NDJSON `docs/samples/scanner/node-phase22/node-phase22-sample.ndjson`. |
| P2 | PREP-SCANNER-ANALYZERS-NODE-22-007-UPSTREAM-2 | DONE (2025-11-20) | Due 2025-11-22 · Accountable: Node Analyzer Guild | Node Analyzer Guild | Native/WASM/capability detection rules + reason codes documented in `docs/modules/scanner/design/node-bundle-phase22.md` with fixture referenced above. |
| P3 | PREP-SCANNER-ANALYZERS-NODE-22-008-UPSTREAM-2 | DONE (2025-11-20) | Due 2025-11-22 · Accountable: Node Analyzer Guild | Node Analyzer Guild | AOC-compliant observation emission shape + sorting rules documented in `docs/modules/scanner/design/node-bundle-phase22.md`; fixture referenced above. |
| 1 | SCANNER-ANALYZERS-NODE-22-006 | DONE (2025-12-01) | Baseline implemented; align with 22-005 adapters when landed | 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 | DONE (2025-12-01) | Baseline implemented; align with 22-005 adapters when landed | 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 | DONE (2025-12-01) | NDJSON observation emission in place; validate once 22-005 feed wiring lands | 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
+
+## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-01 | Implemented Node phase 22 bundle/source-map, native/WASM, and AOC observation pipeline; added fixture `Fixtures/lang/node/phase22` + expected NDJSON hash; set tasks 22-006/007/008 to DONE. | Implementer |
@@ -50,16 +52,16 @@
| 2025-11-20 | Published Node phase 22 prep doc + fixture (see Delivery Tracker) and marked PREP P1–P3 DONE. | Planning |
| 2025-11-20 | Started PREP-SCANNER-ANALYZERS-NODE-22-006/007/008 (statuses → DOING) after confirming no prior DOING owner entries. | Planning |
| 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 |
-
+| 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
- Phase 22 implementation (bundle/source-map, native/WASM, AOC NDJSON) landed; must be reconciled with upstream 22-005 package-manager adapters when they arrive to ensure resolver traces stay consistent.
- Node Phase22 validation is pending: scoped smoke test project exists but SDK resolver/build graph still fans out; latest 2025-12-01 run restored/built but test phase was cancelled to avoid runaway. Need clean runner/CI slice or trimmed project refs to execute `Phase22_Fixture_Matches_Golden` and capture TRX/binlog. Track until executed; currently BLOCKED on runner stability.
- Maintain offline/deterministic outputs; avoid running full solution builds—prefer scoped runners per module.
-
+
## Next Checkpoints
- Set kickoff once Sprint 0132 completes (date TBD).
- 2025-12-05: Phase22 observation validation on clean runner (owner: Node Analyzer Guild) once 22-005 adapters are available.
diff --git a/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md
index bc4bfa237..1ddd3b850 100644
--- a/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md
+++ b/docs/implplan/SPRINT_0134_0001_0001_scanner_surface.md
@@ -16,6 +16,8 @@
- docs/modules/scanner/architecture.md
- src/Scanner/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md
index 33781ce74..ac27422b6 100644
--- a/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md
+++ b/docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md
@@ -16,6 +16,8 @@
- docs/modules/scanner/architecture.md
- src/Scanner/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md b/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md
index 81ee4aa07..4c269efd7 100644
--- a/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md
+++ b/docs/implplan/SPRINT_0136_0001_0001_scanner_surface.md
@@ -16,6 +16,8 @@
- docs/modules/scanner/architecture.md
- src/Scanner/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
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 034f8489d..93b534cc0 100644
--- a/docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md
+++ b/docs/implplan/SPRINT_0138_0000_0001_scanner_ruby_parity.md
@@ -16,6 +16,8 @@
- `docs/modules/scanner/architecture.md`; `docs/modules/scanner/operations/dsse-rekor-operator-guide.md`.
- AGENTS for involved components: `src/Scanner/StellaOps.Scanner.Worker/AGENTS.md`, `src/Scanner/StellaOps.Scanner.WebService/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Deno/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Lang.Dart/AGENTS.md`, `src/Scanner/StellaOps.Scanner.Analyzers.Native/AGENTS.md`.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md b/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md
index 4c2244aae..98c8c903f 100644
--- a/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md
+++ b/docs/implplan/SPRINT_0140_0001_0001_runtime_signals.md
@@ -21,6 +21,8 @@
- docs/modules/concelier/architecture.md
- docs/modules/zastava/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md b/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md
index 3c1d672e0..8e98fa9cb 100644
--- a/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md
+++ b/docs/implplan/SPRINT_0141_0001_0001_graph_indexer.md
@@ -18,6 +18,8 @@
- docs/modules/platform/architecture-overview.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md b/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md
index 06f272544..84a42e1ce 100644
--- a/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md
+++ b/docs/implplan/SPRINT_0142_0001_0001_sbomservice.md
@@ -16,6 +16,8 @@
- docs/modules/platform/architecture-overview.md
- docs/modules/sbomservice/architecture.md (module dossier).
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0143_0000_0001_signals.md b/docs/implplan/SPRINT_0143_0000_0001_signals.md
index acf8766af..2e7c5e809 100644
--- a/docs/implplan/SPRINT_0143_0000_0001_signals.md
+++ b/docs/implplan/SPRINT_0143_0000_0001_signals.md
@@ -16,6 +16,8 @@
- src/Signals/StellaOps.Signals/AGENTS.md.
- CAS waiver/remediation checklist dated 2025-11-17 for SIGNALS-24-002/004/005 scope.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0144_0001_0001_zastava_runtime_signals.md b/docs/implplan/SPRINT_0144_0001_0001_zastava_runtime_signals.md
index 2cc765d05..70879cffe 100644
--- a/docs/implplan/SPRINT_0144_0001_0001_zastava_runtime_signals.md
+++ b/docs/implplan/SPRINT_0144_0001_0001_zastava_runtime_signals.md
@@ -19,6 +19,8 @@
- src/Zastava/StellaOps.Zastava.Observer/AGENTS.md
- src/Zastava/StellaOps.Zastava.Webhook/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0150_0001_0001_mirror_dsse.md b/docs/implplan/SPRINT_0150_0001_0001_mirror_dsse.md
index b567bfa7c..9ccfb9628 100644
--- a/docs/implplan/SPRINT_0150_0001_0001_mirror_dsse.md
+++ b/docs/implplan/SPRINT_0150_0001_0001_mirror_dsse.md
@@ -14,6 +14,8 @@
- `docs/modules/platform/architecture-overview.md`
- Any mirror DSSE drafts (if available).
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md b/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md
index bbb49f3da..a41412a3d 100644
--- a/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md
+++ b/docs/implplan/SPRINT_0150_0001_0001_scheduling_automation.md
@@ -18,6 +18,8 @@
- docs/modules/taskrunner/architecture.md
- docs/modules/registry/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0150_0001_0002_mirror_time.md b/docs/implplan/SPRINT_0150_0001_0002_mirror_time.md
index ef461d9b7..357b63597 100644
--- a/docs/implplan/SPRINT_0150_0001_0002_mirror_time.md
+++ b/docs/implplan/SPRINT_0150_0001_0002_mirror_time.md
@@ -14,6 +14,8 @@
- docs/modules/mirror/milestone-0-thin-bundle.md
- docs/implplan/updates/2025-11-24-mirror-dsse-rev-1501.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0150_0001_0003_mirror_orch.md b/docs/implplan/SPRINT_0150_0001_0003_mirror_orch.md
index 2d76b0ce6..171c4c2f1 100644
--- a/docs/implplan/SPRINT_0150_0001_0003_mirror_orch.md
+++ b/docs/implplan/SPRINT_0150_0001_0003_mirror_orch.md
@@ -14,6 +14,8 @@
- docs/modules/export-center/architecture.md
- docs/implplan/updates/2025-11-24-mirror-dsse-rev-1501.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md b/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md
index bad8bcd6d..99d1818b1 100644
--- a/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md
+++ b/docs/implplan/SPRINT_0151_0001_0001_orchestrator_i.md
@@ -16,6 +16,8 @@
- docs/modules/graph/architecture.md
- docs/modules/telemetry/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md b/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md
index f7f060e67..09ff71c79 100644
--- a/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md
+++ b/docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md
@@ -17,6 +17,8 @@
- docs/modules/orchestrator/architecture.md
- src/Orchestrator/StellaOps.Orchestrator/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md b/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md
index 9e324ebcb..d2b1b0805 100644
--- a/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md
+++ b/docs/implplan/SPRINT_0153_0001_0003_orchestrator_iii.md
@@ -16,6 +16,8 @@
- `docs/modules/platform/architecture-overview.md`
- Module charter: `src/Orchestrator/StellaOps.Orchestrator/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md b/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md
index f22bf1364..af3a4a285 100644
--- a/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md
+++ b/docs/implplan/SPRINT_0154_0001_0001_packsregistry.md
@@ -18,6 +18,8 @@
- docs/modules/devops/architecture.md
- Any PacksRegistry AGENTS.md (if present under src/PacksRegistry).
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md b/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md
index 181e4e6a1..86dedef60 100644
--- a/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md
+++ b/docs/implplan/SPRINT_0155_0001_0001_scheduler_i.md
@@ -16,6 +16,8 @@
- docs/modules/scheduler/architecture.md
- src/Scheduler/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md b/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md
index 353b2a070..d4004db17 100644
--- a/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md
+++ b/docs/implplan/SPRINT_0156_0001_0002_scheduler_ii.md
@@ -16,6 +16,8 @@
- docs/modules/scheduler/implementation_plan.md
- docs/modules/platform/architecture-overview.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md b/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md
index f4cebe8b7..c643609cb 100644
--- a/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md
+++ b/docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md
@@ -16,6 +16,8 @@
- docs/modules/taskrunner/architecture.md (if available)
- src/TaskRunner/StellaOps.TaskRunner/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0157_0001_0002_taskrunner_blockers.md b/docs/implplan/SPRINT_0157_0001_0002_taskrunner_blockers.md
index 2eec1aab5..15f880bf8 100644
--- a/docs/implplan/SPRINT_0157_0001_0002_taskrunner_blockers.md
+++ b/docs/implplan/SPRINT_0157_0001_0002_taskrunner_blockers.md
@@ -13,6 +13,8 @@
- `docs/modules/platform/architecture-overview.md`
- `src/TaskRunner/StellaOps.TaskRunner/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md b/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md
index 53d1c9c2a..58638bc50 100644
--- a/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md
+++ b/docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md
@@ -21,6 +21,8 @@
- docs/task-packs/runbook.md
- src/TaskRunner/StellaOps.TaskRunner/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md b/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md
index 81ace876e..114fc9f63 100644
--- a/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md
+++ b/docs/implplan/SPRINT_0160_0001_0001_export_evidence.md
@@ -1,77 +1,79 @@
-# Sprint 0160_0001_0001 · Export & Evidence
-
-## Topic & Scope
-- Snapshot coordination for export & evidence tracks (EvidenceLocker, ExportCenter, TimelineIndexer); active backlog continues in Sprint 161+.
-- Ensure bundle formats, crypto routing, and ingestion schemas freeze before downstream sprints move to DOING; completed work is archived in `docs/implplan/archived/tasks.md` (updated 2025-11-08).
-- Working directory: `docs/implplan` (cross-module coordination spanning EvidenceLocker, ExportCenter, TimelineIndexer artefacts).
-- Evidence of completion: refreshed coordination snapshot, normalized sprint structure, and links to module trackers.
-
-## Dependencies & Concurrency
-- Depends on AdvisoryAI evidence schema (Sprint 110.A), Orchestrator/Notifications envelopes (Sprint 150.A/140), and crypto-routing audit outcomes (2025-11-07) before DOING can start.
-- Runs in parallel with module sprints 161/162/165; no code convergence expected here, but gating contracts must be frozen first.
-- Interlocks & readiness signals are tracked in the table below; concurrency with other CC-decade sprints is safe once those signals turn green.
-
-## Documentation Prerequisites
-- `docs/modules/evidence-locker/architecture.md`, `docs/modules/evidence-locker/bundle-packaging.md`, `docs/modules/evidence-locker/incident-mode.md`
-- `docs/modules/export-center/architecture.md`, `docs/modules/attestor/airgap.md`
-- `docs/modules/timelineindexer/architecture.md` (if present) and Postgres/RLS runbooks
-- `docs/security/crypto-routing-audit-2025-11-07.md`
-- `docs/replay/DETERMINISTIC_REPLAY.md`, `docs/runbooks/replay_ops.md`
-- `docs/events/orchestrator-scanner-events.md`
-
-## Delivery Tracker
-| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
-| --- | --- | --- | --- | --- | --- |
+# Sprint 0160_0001_0001 · Export & Evidence
+
+## Topic & Scope
+- Snapshot coordination for export & evidence tracks (EvidenceLocker, ExportCenter, TimelineIndexer); active backlog continues in Sprint 161+.
+- Ensure bundle formats, crypto routing, and ingestion schemas freeze before downstream sprints move to DOING; completed work is archived in `docs/implplan/archived/tasks.md` (updated 2025-11-08).
+- Working directory: `docs/implplan` (cross-module coordination spanning EvidenceLocker, ExportCenter, TimelineIndexer artefacts).
+- Evidence of completion: refreshed coordination snapshot, normalized sprint structure, and links to module trackers.
+
+## Dependencies & Concurrency
+- Depends on AdvisoryAI evidence schema (Sprint 110.A), Orchestrator/Notifications envelopes (Sprint 150.A/140), and crypto-routing audit outcomes (2025-11-07) before DOING can start.
+- Runs in parallel with module sprints 161/162/165; no code convergence expected here, but gating contracts must be frozen first.
+- Interlocks & readiness signals are tracked in the table below; concurrency with other CC-decade sprints is safe once those signals turn green.
+
+## Documentation Prerequisites
+- `docs/modules/evidence-locker/architecture.md`, `docs/modules/evidence-locker/bundle-packaging.md`, `docs/modules/evidence-locker/incident-mode.md`
+- `docs/modules/export-center/architecture.md`, `docs/modules/attestor/airgap.md`
+- `docs/modules/timelineindexer/architecture.md` (if present) and Postgres/RLS runbooks
+- `docs/security/crypto-routing-audit-2025-11-07.md`
+- `docs/replay/DETERMINISTIC_REPLAY.md`, `docs/runbooks/replay_ops.md`
+- `docs/events/orchestrator-scanner-events.md`
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
| P1 | PREP-EVIDENCE-LOCKER-GUILD-SECURITY-GUILD-DOC | DONE (2025-11-20) | Prep note published at `docs/modules/evidence-locker/prep/2025-11-20-security-coordination.md`. | 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 | DONE (2025-11-20) | Prep note published at `docs/events/prep/2025-11-20-orchestrator-notifications-schema-handoff.md`. | 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 | DONE (2025-11-20) | Prep note published at `docs/events/prep/2025-11-20-advisoryai-orchestrator-followup.md`. | 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. |
+| 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 | BLOCKED | Waiting on AdvisoryAI evidence payload notes + orchestrator/notifications envelopes to finalize ingest/replay summary; re-check after 2025-12-06 schema ETA sync. | 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; re-check after 2025-12-06 schema ETA sync before freezing 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; re-check after 2025-12-06 schema ETA sync. | 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 | 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
-
-### 160.A EvidenceLocker
-- Detail trackers: [SPRINT_0161_0001_0001_evidencelocker.md](./SPRINT_0161_0001_0001_evidencelocker.md) and [SPRINT_187_evidence_locker_cli_integration.md](./SPRINT_187_evidence_locker_cli_integration.md).
-- Task radar (all TODO as of 2025-11-12):
- - `EVID-REPLAY-187-001` — Replay bundle ingestion/retention APIs + storage policy (`src/EvidenceLocker/StellaOps.EvidenceLocker`, `docs/modules/evidence-locker/architecture.md`).
- - `RUNBOOK-REPLAY-187-004` & `CLI-REPLAY-187-002` — CLI + ops readiness for replay bundles (`docs/runbooks/replay_ops.md`, CLI module).
- - `EVID-CRYPTO-90-001` — Sovereign crypto routing via `ICryptoProviderRegistry`/`ICryptoHash` per `docs/security/crypto-routing-audit-2025-11-07.md`.
-- Contracts: bundle packaging + DSSE layout (`docs/modules/evidence-locker/bundle-packaging.md`, `EVID-OBS-54-002`); portable/incident modes in `docs/modules/evidence-locker/incident-mode.md`.
-- Gating dependencies: orchestrator capsule schema, AdvisoryAI payload notes, and replay ledger rules (`docs/replay/DETERMINISTIC_REPLAY.md`).
-- Ready-to-start checklist: finalize ingest schema deltas, stage Replay Ledger ops drills, and publish API surface summary into Sprint 161 before DOING.
-
-#### EvidenceLocker task snapshot (2025-11-12)
-| Task ID | Scope | State | Notes / Owners |
-| --- | --- | --- | --- |
-| EVID-REPLAY-187-001 | Replay bundle ingestion + retention APIs | TODO | Evidence Locker Guild · docs/modules/evidence-locker/architecture.md |
-| CLI-REPLAY-187-002 | CLI record/verify/replay UX | TODO | CLI Guild · `docs/modules/cli/architecture.md` |
-| RUNBOOK-REPLAY-187-004 | Replay ops runbook + drills | TODO | Docs/Ops Guild · `/docs/runbooks/replay_ops.md` |
-| EVID-CRYPTO-90-001 | Sovereign crypto routing | TODO | Evidence Locker + Security Guilds · `ICryptoProviderRegistry` integration |
-
-### 160.B ExportCenter
-- Detail trackers: [SPRINT_0162_0001_0001_exportcenter_i.md](./SPRINT_0162_0001_0001_exportcenter_i.md) and [SPRINT_0163_0001_0001_exportcenter_ii.md](./SPRINT_0163_0001_0001_exportcenter_ii.md).
-- Task radar highlights:
- - Mirror & bootstrap: `EXPORT-AIRGAP-56-001/002/003/004/005`, `EXPORT-AIRGAP-57-001`, `EXPORT-AIRGAP-58-001`.
- - Attestation bundles: `EXPORT-ATTEST-74-001/002`, `EXPORT-ATTEST-75-001/002` (jobs, CI/offline, CLI verify/import; see `docs/modules/attestor/airgap.md`).
- - API/OAS: `EXPORT-OAS-61-001/002`, `EXPORT-OAS-62-001`, `EXPORT-OAS-63-001` — refreshed OpenAPI, discovery, SDK, deprecation headers.
- - Service/observability: `EXPORT-SVC-35-001…005`, `EXPORT-OBS-50/51/52`, `EXPORT-CRYPTO-90-001` for crypto parity with EvidenceLocker.
-- Dependencies: EvidenceLocker contracts + DSSE proofs; orchestrator events + Scheduler readiness; crypto routing aligned with `docs/security/crypto-routing-audit-2025-11-07.md`.
-- Ready-to-start checklist: freeze sealed bundle spec, reconcile crypto provider matrix with RootPack deployments, and prep DevPortal verification CLI scaffolding (`DVOFF-64-002`).
-
-#### ExportCenter task snapshot (2025-11-12)
-| Task ID | Scope | State | Notes / Owners |
-| --- | --- | --- | --- |
+| 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 | 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
+
+### 160.A EvidenceLocker
+- Detail trackers: [SPRINT_0161_0001_0001_evidencelocker.md](./SPRINT_0161_0001_0001_evidencelocker.md) and [SPRINT_187_evidence_locker_cli_integration.md](./SPRINT_187_evidence_locker_cli_integration.md).
+- Task radar (all TODO as of 2025-11-12):
+ - `EVID-REPLAY-187-001` — Replay bundle ingestion/retention APIs + storage policy (`src/EvidenceLocker/StellaOps.EvidenceLocker`, `docs/modules/evidence-locker/architecture.md`).
+ - `RUNBOOK-REPLAY-187-004` & `CLI-REPLAY-187-002` — CLI + ops readiness for replay bundles (`docs/runbooks/replay_ops.md`, CLI module).
+ - `EVID-CRYPTO-90-001` — Sovereign crypto routing via `ICryptoProviderRegistry`/`ICryptoHash` per `docs/security/crypto-routing-audit-2025-11-07.md`.
+- Contracts: bundle packaging + DSSE layout (`docs/modules/evidence-locker/bundle-packaging.md`, `EVID-OBS-54-002`); portable/incident modes in `docs/modules/evidence-locker/incident-mode.md`.
+- Gating dependencies: orchestrator capsule schema, AdvisoryAI payload notes, and replay ledger rules (`docs/replay/DETERMINISTIC_REPLAY.md`).
+- Ready-to-start checklist: finalize ingest schema deltas, stage Replay Ledger ops drills, and publish API surface summary into Sprint 161 before DOING.
+
+#### EvidenceLocker task snapshot (2025-11-12)
+| Task ID | Scope | State | Notes / Owners |
+| --- | --- | --- | --- |
+| EVID-REPLAY-187-001 | Replay bundle ingestion + retention APIs | TODO | Evidence Locker Guild · docs/modules/evidence-locker/architecture.md |
+| CLI-REPLAY-187-002 | CLI record/verify/replay UX | TODO | CLI Guild · `docs/modules/cli/architecture.md` |
+| RUNBOOK-REPLAY-187-004 | Replay ops runbook + drills | TODO | Docs/Ops Guild · `/docs/runbooks/replay_ops.md` |
+| EVID-CRYPTO-90-001 | Sovereign crypto routing | TODO | Evidence Locker + Security Guilds · `ICryptoProviderRegistry` integration |
+
+### 160.B ExportCenter
+- Detail trackers: [SPRINT_0162_0001_0001_exportcenter_i.md](./SPRINT_0162_0001_0001_exportcenter_i.md) and [SPRINT_0163_0001_0001_exportcenter_ii.md](./SPRINT_0163_0001_0001_exportcenter_ii.md).
+- Task radar highlights:
+ - Mirror & bootstrap: `EXPORT-AIRGAP-56-001/002/003/004/005`, `EXPORT-AIRGAP-57-001`, `EXPORT-AIRGAP-58-001`.
+ - Attestation bundles: `EXPORT-ATTEST-74-001/002`, `EXPORT-ATTEST-75-001/002` (jobs, CI/offline, CLI verify/import; see `docs/modules/attestor/airgap.md`).
+ - API/OAS: `EXPORT-OAS-61-001/002`, `EXPORT-OAS-62-001`, `EXPORT-OAS-63-001` — refreshed OpenAPI, discovery, SDK, deprecation headers.
+ - Service/observability: `EXPORT-SVC-35-001…005`, `EXPORT-OBS-50/51/52`, `EXPORT-CRYPTO-90-001` for crypto parity with EvidenceLocker.
+- Dependencies: EvidenceLocker contracts + DSSE proofs; orchestrator events + Scheduler readiness; crypto routing aligned with `docs/security/crypto-routing-audit-2025-11-07.md`.
+- Ready-to-start checklist: freeze sealed bundle spec, reconcile crypto provider matrix with RootPack deployments, and prep DevPortal verification CLI scaffolding (`DVOFF-64-002`).
+
+#### ExportCenter task snapshot (2025-11-12)
+| Task ID | Scope | State | Notes / Owners |
+| --- | --- | --- | --- |
| DVOFF-64-002 | DevPortal bundle verification CLI | BLOCKED (2025-11-30) | DevPortal Offline + AirGap Controller Guilds |
| EXPORT-AIRGAP-56-001/002 | Mirror bundle + bootstrap pack profiles | BLOCKED (2025-11-30) | Exporter + Mirror Creator + DevOps Guilds |
| EXPORT-AIRGAP-57-001 | Portable evidence export mode | BLOCKED (2025-11-30) | Exporter Service + Evidence Locker Guild |
@@ -80,28 +82,28 @@
| EXPORT-ATTEST-75-001/002 | CLI verify/import + offline kit integration | BLOCKED (2025-11-30) | Attestation Bundle + CLI + Exporter Guilds |
| EXPORT-OAS-61/62/63 | OpenAPI refresh, discovery, SDK + deprecation headers | BLOCKED (2025-11-30) | Exporter Service + API Governance + SDK Guilds |
| EXPORT-CRYPTO-90-001 | Sovereign crypto routing | BLOCKED (2025-11-30) | Exporter Service + Security Guilds |
-
-### 160.C TimelineIndexer
-- Detail tracker: [SPRINT_165_timelineindexer.md](./SPRINT_165_timelineindexer.md) covering TIMELINE-OBS-52-001…004 and TIMELINE-OBS-53-001.
-- Task radar:
- - `TIMELINE-OBS-52-001` — service bootstrap + Postgres migrations with deterministic scripts and RLS scaffolding.
- - `TIMELINE-OBS-52-002` — event ingestion pipeline (NATS/Redis consumers, ordering, dedupe, trace correlation, metrics).
- - `TIMELINE-OBS-52-003` — REST/gRPC APIs with filtering/pagination + OpenAPI contracts.
- - `TIMELINE-OBS-52-004` — finalize RLS, scope checks, audit logging, legal hold enforcement tests.
- - `TIMELINE-OBS-53-001` — evidence linkage endpoint returning signed manifest references.
-- Dependencies: orchestrator/notifications event schemas and EvidenceLocker digest references must land before Postgres migrations can be frozen; export bundle IDs must be stable to hydrate `/timeline/{id}/evidence`.
-- Ready-to-start checklist: secure event schema package, stage Postgres migration plan (incl. RLS policies) for review, align ingest ordering semantics with Scheduler/ExportCenter cadence.
-
-#### TimelineIndexer task snapshot (2025-11-12)
-| Task ID | Scope | State | Notes / Owners |
-| --- | --- | --- | --- |
+
+### 160.C TimelineIndexer
+- Detail tracker: [SPRINT_165_timelineindexer.md](./SPRINT_165_timelineindexer.md) covering TIMELINE-OBS-52-001…004 and TIMELINE-OBS-53-001.
+- Task radar:
+ - `TIMELINE-OBS-52-001` — service bootstrap + Postgres migrations with deterministic scripts and RLS scaffolding.
+ - `TIMELINE-OBS-52-002` — event ingestion pipeline (NATS/Redis consumers, ordering, dedupe, trace correlation, metrics).
+ - `TIMELINE-OBS-52-003` — REST/gRPC APIs with filtering/pagination + OpenAPI contracts.
+ - `TIMELINE-OBS-52-004` — finalize RLS, scope checks, audit logging, legal hold enforcement tests.
+ - `TIMELINE-OBS-53-001` — evidence linkage endpoint returning signed manifest references.
+- Dependencies: orchestrator/notifications event schemas and EvidenceLocker digest references must land before Postgres migrations can be frozen; export bundle IDs must be stable to hydrate `/timeline/{id}/evidence`.
+- Ready-to-start checklist: secure event schema package, stage Postgres migration plan (incl. RLS policies) for review, align ingest ordering semantics with Scheduler/ExportCenter cadence.
+
+#### TimelineIndexer task snapshot (2025-11-12)
+| Task ID | Scope | State | Notes / Owners |
+| --- | --- | --- | --- |
| TIMELINE-OBS-52-001 | Service bootstrap + Postgres migrations/RLS | DONE (2025-11-30) | Timeline Indexer Guild |
| TIMELINE-OBS-52-002 | Event ingestion pipeline + metrics | DONE (2025-12-03) | Timeline Indexer Guild |
| TIMELINE-OBS-52-003 | REST/gRPC APIs + OpenAPI contracts | DONE (2025-12-03) | Timeline Indexer Guild |
| TIMELINE-OBS-52-004 | RLS policies, audit logging, legal hold tests | DONE (2025-12-03) | Timeline Indexer + Security Guilds |
| TIMELINE-OBS-53-001 | Evidence linkage endpoint | BLOCKED (2025-11-30) | Timeline Indexer + Evidence Locker Guilds |
-
-## Interlocks & Readiness Signals
+
+## Interlocks & Readiness Signals
| Dependency | Owner / Source | Impacts | Status / Next signal |
| --- | --- | --- | --- |
| Orchestrator capsule & notifications schema (`docs/events/orchestrator-scanner-events.md`) | Orchestrator Service Guild · Notifications Guild (Sprint 150.A + 140 wave) | 160.A, 160.B, 160.C | OVERDUE; re-escalated 2025-12-04. Require ETA by 2025-12-06 or escalate to steering on 2025-12-07. |
@@ -109,16 +111,16 @@
| Replay ledger spec alignment (`docs/replay/DETERMINISTIC_REPLAY.md`, `/docs/runbooks/replay_ops.md`) | Replay Delivery Guild (Sprint 187) | 160.A | Replay ops runbook exists (2025-11-03); EvidenceLocker must incorporate retention API shape before DOING. Track in EVID-REPLAY-187-001. |
| Crypto routing parity (`docs/security/crypto-routing-audit-2025-11-07.md`) | Security Guild + Export/Evidence teams (`EVID-CRYPTO-90-001`, `EXPORT-CRYPTO-90-001`) | 160.A, 160.B | Review on 2025-11-18 slipped; reschedule for 2025-12-08 with registry sample due 2025-12-06. Keep sovereign modes off until approved. |
| DevPortal verification CLI scaffolding (`DVOFF-64-002`) | DevPortal Offline Guild (Sprint 162) | 160.B | Prototype pending; request stub bundle for dry run no later than 2025-12-09 to stay aligned with ExportCenter handoff. |
-
-## Upcoming Checkpoints (UTC)
+
+## Upcoming Checkpoints (UTC)
| Date | Session / Owner | Target outcome | Fallback / Escalation |
| --- | --- | --- | --- |
| 2025-12-06 | Schema ETA sync (AdvisoryAI + Orchestrator/Notifications leads) | Confirm drop dates for AdvisoryAI payload notes and Orchestrator/Notifications capsule envelopes to unblock snapshots. | If no ETA, escalate to steering on 2025-12-07 and keep 160.A/B/C BLOCKED. |
| 2025-12-08 | Sovereign crypto readiness review (Security + Evidence/Export teams) | Approve `ICryptoProviderRegistry` wiring plan and provider matrix for `EVID-CRYPTO-90-001`/`EXPORT-CRYPTO-90-001`. | If not approved, publish interim provider whitelist and defer sovereign modes. |
| 2025-12-09 | DevPortal Offline CLI dry run (DevPortal Offline + AirGap Controller Guilds) | Demo `stella devportal verify bundle.tgz` against stub bundle to prep ExportCenter handoff. | If bundle not available, use stub from EvidenceLocker sample and log risk in Sprint 162. |
| 2025-12-10 | Wave 160 snapshot refresh (EvidenceLocker, ExportCenter, TimelineIndexer leads) | Publish updated readiness snapshots or restate BLOCKED with evidence; sync Sprint 161/162/165 trackers. | If still blocked, record blockade summary and extend checkpoint to 2025-12-13. |
-
-## Action Tracker
+
+## Action Tracker
| Wave | Immediate action | Owner(s) | Due | Status |
| --- | --- | --- | --- | --- |
| 160.A EvidenceLocker | Draft ingest schema summary + Replay Ledger API notes into `SPRINT_0161_0001_0001_evidencelocker.md` once orchestrator + AdvisoryAI schemas land. | Evidence Locker Guild · Replay Delivery Guild | 2025-12-10 | BLOCKED (waiting on AdvisoryAI payload notes + Orchestrator envelopes) |
@@ -134,8 +136,8 @@
| 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 | 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
+
+## Decisions & Risks
| Item | Status / Decision | Notes |
| --- | --- | --- |
| Naming & template alignment | DONE (2025-11-17) | File renamed to `SPRINT_0160_0001_0001_export_evidence.md` and normalized to standard sprint template. |
@@ -147,17 +149,17 @@
| AdvisoryAI schema checkpoint (2025-11-14) | OVERDUE | Reschedule in progress; re-escalated 2025-12-04 with ETA ask for 2025-12-06. |
| Orchestrator/Notifications checkpoint (2025-11-15) | OVERDUE | Reschedule in progress; re-escalated 2025-12-04 with ETA ask for 2025-12-06. |
| Escalation responses | PENDING | Awaiting ETA confirmations from AdvisoryAI and Orchestrator/Notifications leads; next follow-up 2025-12-06 (steering escalation 2025-12-07 if silent). |
-
-### Risk table
-| 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 | 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. |
-
-## Execution Log
+
+### Risk table
+| 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 | 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. |
+
+## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-04 | Re-baselined Wave 160 status; added Dec-06/08/09/10 checkpoints, re-escalated schema/envelope ETAs, refreshed Action Tracker (Timeline tasks marked DONE). | Project PM |
@@ -165,23 +167,23 @@
| 2025-11-20 | Confirmed PREP-ORCHESTRATOR-NOTIFICATIONS-SCHEMA-HANDOF and PREP-ESCALATION-FOLLOW-UP-ADVISORYAI-ORCHESTR still unclaimed; moved both to DOING to proceed with Wave 150/140 escalations. | Planning |
| 2025-11-20 | Published prep artefacts for P1–P3: security coordination (`docs/modules/evidence-locker/prep/2025-11-20-security-coordination.md`), orchestrator/notifications handoff (`docs/events/prep/2025-11-20-orchestrator-notifications-schema-handoff.md`), and escalation follow-up (`docs/events/prep/2025-11-20-advisoryai-orchestrator-followup.md`). Marked P1–P3 DONE. | Implementer |
| 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 |
-| 2025-11-17 | Set Delivery Tracker and Wave statuses to BLOCKED pending schemas/crypto review; logged missing `docs/implplan/AGENTS.md` as blocker and added action item `AGENTS-implplan`. | Implementer |
-| 2025-11-17 | Created `docs/implplan/AGENTS.md`; marked AGENTS-implplan DONE and updated Decisions & Risks accordingly. | Implementer |
-| 2025-11-17 | Marked AdvisoryAI (2025-11-14) and Orchestrator/Notifications (2025-11-15) checkpoints as missed; escalations required; action items now OVERDUE. | Implementer |
-| 2025-11-18 | Added escalation actions `ESCALATE-ADV-AI-SCHEMA` and `ESCALATE-ORCH-ENVELOPE` to track overdue schema drops. | Implementer |
-| 2025-11-18 | Started escalations for AdvisoryAI schema and Orchestrator envelopes; awaiting new ETAs from respective guilds. | Implementer |
-| 2025-11-18 | Sent escalation pings to AdvisoryAI and Orchestrator/Notifications leads; awaiting ETA confirmation (tracked in Action Tracker). | Implementer |
-| 2025-11-18 | Updated Interlocks with “escalation sent” notes and follow-up date (2025-11-19). | Implementer |
-| 2025-11-18 | Added blocker task ADV-ORCH-SCHEMA-LIB-160 and marked snapshots explicitly blocked on shared schema library drop. | Project PM |
-| 2025-11-18 | Set ADV-ORCH-SCHEMA-LIB-160 to DOING; drafting shared models package for AdvisoryAI/Orchestrator envelopes. | Implementer |
-| 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 |
+| 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 |
+| 2025-11-17 | Set Delivery Tracker and Wave statuses to BLOCKED pending schemas/crypto review; logged missing `docs/implplan/AGENTS.md` as blocker and added action item `AGENTS-implplan`. | Implementer |
+| 2025-11-17 | Created `docs/implplan/AGENTS.md`; marked AGENTS-implplan DONE and updated Decisions & Risks accordingly. | Implementer |
+| 2025-11-17 | Marked AdvisoryAI (2025-11-14) and Orchestrator/Notifications (2025-11-15) checkpoints as missed; escalations required; action items now OVERDUE. | Implementer |
+| 2025-11-18 | Added escalation actions `ESCALATE-ADV-AI-SCHEMA` and `ESCALATE-ORCH-ENVELOPE` to track overdue schema drops. | Implementer |
+| 2025-11-18 | Started escalations for AdvisoryAI schema and Orchestrator envelopes; awaiting new ETAs from respective guilds. | Implementer |
+| 2025-11-18 | Sent escalation pings to AdvisoryAI and Orchestrator/Notifications leads; awaiting ETA confirmation (tracked in Action Tracker). | Implementer |
+| 2025-11-18 | Updated Interlocks with “escalation sent” notes and follow-up date (2025-11-19). | Implementer |
+| 2025-11-18 | Added blocker task ADV-ORCH-SCHEMA-LIB-160 and marked snapshots explicitly blocked on shared schema library drop. | Project PM |
+| 2025-11-18 | Set ADV-ORCH-SCHEMA-LIB-160 to DOING; drafting shared models package for AdvisoryAI/Orchestrator envelopes. | Implementer |
+| 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 36aa7273f..ebd5f07e4 100644
--- a/docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md
+++ b/docs/implplan/SPRINT_0161_0001_0001_evidencelocker.md
@@ -20,6 +20,8 @@
- `docs/events/orchestrator-scanner-events.md`
- `docs/modules/cli/architecture.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md b/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md
index ffd7bbb1c..aed01a718 100644
--- a/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md
+++ b/docs/implplan/SPRINT_0162_0001_0001_exportcenter_i.md
@@ -18,6 +18,8 @@
- EvidenceLocker bundle packaging (`docs/modules/evidence-locker/bundle-packaging.md`) once frozen
- DevPortal offline guidance (DVOFF-64 series) as provided by DevPortal Offline Guild
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md b/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md
index 00a3ac8e9..7ca73f476 100644
--- a/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md
+++ b/docs/implplan/SPRINT_0163_0001_0001_exportcenter_ii.md
@@ -17,6 +17,8 @@
- EvidenceLocker bundle packaging (`docs/modules/evidence-locker/bundle-packaging.md`) once frozen
- Observability guidance/dashboards referenced by Observability Guild
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md b/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md
index 79ff708f0..d0a6e850d 100644
--- a/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md
+++ b/docs/implplan/SPRINT_0164_0001_0001_exportcenter_iii.md
@@ -16,6 +16,8 @@
- docs/modules/export-center/architecture.md
- src/ExportCenter/AGENTS.md (if present)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md b/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md
index aa448d9f7..cd58f0df2 100644
--- a/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md
+++ b/docs/implplan/SPRINT_0165_0001_0001_timelineindexer.md
@@ -16,6 +16,8 @@
- docs/modules/export-center/architecture.md (for evidence linkage)
- src/TimelineIndexer/StellaOps.TimelineIndexer/AGENTS.md (if present)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md b/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md
index b1354136a..c469bdbf1 100644
--- a/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md
+++ b/docs/implplan/SPRINT_0170_0001_0001_notifications_telemetry.md
@@ -16,6 +16,8 @@
- docs/modules/notifications/architecture.md
- docs/modules/telemetry/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Track | Status | Key dependency / next step | Owners | Notes |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md b/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md
index f58313a09..0165a6e3f 100644
--- a/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md
+++ b/docs/implplan/SPRINT_0171_0001_0001_notifier_i.md
@@ -17,6 +17,8 @@
- docs/notifications/templates.md
- src/Notifier/StellaOps.Notifier/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md b/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md
index ab5e752bd..d8cb10b00 100644
--- a/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md
+++ b/docs/implplan/SPRINT_0172_0001_0002_notifier_ii.md
@@ -1,77 +1,79 @@
-# 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 | DONE (2025-11-24) | Contract published at `docs/api/notify-openapi.yaml` and `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/openapi/notify-openapi.yaml`. | 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 | DONE (2025-11-24) | Pack approvals endpoint implemented with tenant/idempotency headers, lock-based dedupe, Mongo persistence, and audit append; see `Program.cs` + storage migrations. | Notifications Service Guild | Implement secure ingestion endpoint, Mongo persistence (`pack_approvals`), idempotent writes, audit trail. |
-| 3 | NOTIFY-SVC-37-003 | DONE (2025-11-27) | Dispatch/rendering layer complete: `INotifyTemplateRenderer`/`SimpleTemplateRenderer` (Handlebars-style {{variable}} + {{#each}}, sensitive key redaction), `INotifyChannelDispatcher`/`WebhookChannelDispatcher` (Slack/webhook with retry), `DeliveryDispatchWorker` (BackgroundService), DI wiring in Program.cs, options + tests. | Notifications Service Guild | Approval/policy templates, routing predicates, channel dispatch (email/webhook), localization + redaction. |
-| 4 | NOTIFY-SVC-37-004 | DONE (2025-11-24) | Test harness stabilized with in-memory stores; OpenAPI stub returns scope/etag; pack-approvals ack path exercised. | Notifications Service Guild | Acknowledgement API, Task Runner callback client, metrics for outstanding approvals, runbook updates. |
-| 5 | NOTIFY-SVC-38-002 | DONE (2025-11-27) | Channel adapters complete: `IChannelAdapter`, `WebhookChannelAdapter`, `EmailChannelAdapter`, `ChatWebhookChannelAdapter` with retry policies (exponential backoff + jitter), health checks, audit logging, HMAC signing, `ChannelAdapterFactory` DI registration. Tests at `StellaOps.Notifier.Tests/Channels/`. | Notifications Service Guild | Channel adapters (email, chat webhook, generic webhook) with retry policies, health checks, audit logging. |
-| 6 | NOTIFY-SVC-38-003 | DONE (2025-11-27) | Template service complete: `INotifyTemplateService`/`NotifyTemplateService` (locale fallback chain, versioning, CRUD with audit), `EnhancedTemplateRenderer` (configurable redaction allowlists/denylists, Markdown/HTML/JSON/PlainText format conversion, provenance links, {{#if}} conditionals, format specifiers), `TemplateRendererOptions`, DI registration via `AddTemplateServices()`. Tests at `StellaOps.Notifier.Tests/Templates/`. | Notifications Service Guild | Template service (versioned templates, localization scaffolding) and renderer (redaction allowlists, Markdown/HTML/JSON, provenance links). |
-| 7 | NOTIFY-SVC-38-004 | DONE (2025-11-27) | REST APIs complete: `/api/v2/notify/rules` (CRUD), `/api/v2/notify/templates` (CRUD + preview + validate), `/api/v2/notify/incidents` (list + ack + resolve). Contract DTOs at `Contracts/RuleContracts.cs`, `TemplateContracts.cs`, `IncidentContracts.cs`. Endpoints via `MapNotifyApiV2()` extension. Audit logging on all mutations. Tests at `StellaOps.Notifier.Tests/Endpoints/`. | 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 | DONE (2025-11-27) | Correlation engine complete: `ICorrelationEngine`/`CorrelationEngine` (orchestrates key building, incident management, throttling, quiet hours), `ICorrelationKeyBuilder` interface with `CompositeCorrelationKeyBuilder` (tenant+kind+payload fields), `TemplateCorrelationKeyBuilder` (template expressions), `CorrelationKeyBuilderFactory`. `INotifyThrottler`/`InMemoryNotifyThrottler` (sliding window throttling). `IQuietHoursEvaluator`/`QuietHoursEvaluator` (quiet hours schedules, maintenance windows). `IIncidentManager`/`InMemoryIncidentManager` (incident lifecycle: open/acknowledged/resolved). Notification policies (FirstOnly, EveryEvent, OnEscalation, Periodic). DI registration via `AddCorrelationServices()`. Comprehensive tests at `StellaOps.Notifier.Tests/Correlation/`. | Notifications Service Guild | Correlation engine with pluggable key expressions/windows, throttler, quiet hours/maintenance evaluator, incident lifecycle. |
-| 9 | NOTIFY-SVC-39-002 | DONE (2025-11-27) | Digest generator complete: `IDigestGenerator`/`DigestGenerator` (queries incidents, calculates summary statistics, builds timeline, renders to Markdown/HTML/PlainText/JSON), `IDigestScheduler`/`InMemoryDigestScheduler` (cron-based scheduling with Cronos, timezone support, next-run calculation), `DigestScheduleRunner` BackgroundService (concurrent schedule execution with semaphore limiting), `IDigestDistributor`/`DigestDistributor` (webhook/Slack/Teams/email distribution with format-specific payloads). DTOs: `DigestQuery`, `DigestContent`, `DigestSummary`, `DigestIncident`, `EventKindSummary`, `TimelineEntry`, `DigestSchedule`, `DigestRecipient`. DI registration via `AddDigestServices()` with `DigestServiceBuilder`. Tests at `StellaOps.Notifier.Tests/Digest/`. | Notifications Service Guild | Digest generator (queries, formatting) with schedule runner and distribution. |
-| 10 | NOTIFY-SVC-39-003 | DONE (2025-11-27) | Simulation engine complete: `ISimulationEngine`/`SimulationEngine` (dry-runs rules against events without side effects, evaluates all rules against all events, builds detailed match/non-match explanations), `SimulationRequest`/`SimulationResult` DTOs with `SimulationEventResult`, `SimulationRuleMatch`, `SimulationActionMatch`, `SimulationRuleNonMatch`, `SimulationRuleSummary`. Rule validation via `ValidateRuleAsync` with error/warning detection (missing fields, broad matches, unknown severities, disabled actions). API endpoint at `/api/v2/simulate` (POST for simulation, POST /validate for rule validation) via `SimulationEndpoints.cs`. DI registration via `AddSimulationServices()`. Tests at `StellaOps.Notifier.Tests/Simulation/SimulationEngineTests.cs`. | Notifications Service Guild | Simulation engine/API to dry-run rules against historical events, returning matched actions with explanations. |
-| 11 | NOTIFY-SVC-39-004 | DONE (2025-11-27) | Quiet hour calendars, throttle configs, audit logging, and operator overrides implemented. | Notifications Service Guild | Quiet hour calendars + default throttles with audit logging and operator overrides. |
-| 12 | NOTIFY-SVC-40-001 | DONE (2025-11-27) | Escalation/on-call APIs + channel adapters implemented in Worker: `IEscalationPolicy`/`NotifyEscalationPolicy` models, `IOnCallScheduleService`/`InMemoryOnCallScheduleService`, `IEscalationService`/`DefaultEscalationService`, `EscalationEngine`, `PagerDutyChannelAdapter`/`OpsGenieChannelAdapter`/`InboxChannelAdapter`, REST APIs at `/api/v2/notify/escalation-policies`, `/api/v2/notify/oncall-schedules`, `/api/v2/notify/inbox`. | Notifications Service Guild | Escalations + on-call schedules, ack bridge, PagerDuty/OpsGenie adapters, CLI/in-app inbox channels. |
-| 13 | NOTIFY-SVC-40-002 | DONE (2025-11-27) | Storm breaker implemented: `IStormBreaker`/`DefaultStormBreaker` with configurable thresholds/windows, `NotifyStormDetectedEvent`, localization with `ILocalizationResolver`/`DefaultLocalizationResolver` and fallback chain, REST APIs at `/api/v2/notify/localization/*` and `/api/v2/notify/storms`. | Notifications Service Guild | Summary storm breaker notifications, localization bundles, fallback handling. |
-| 14 | NOTIFY-SVC-40-003 | DONE (2025-11-27) | Security hardening: `IAckTokenService`/`HmacAckTokenService` (HMAC-SHA256 + HKDF), `IWebhookSecurityService`/`DefaultWebhookSecurityService` (HMAC signing + IP allowlists with CIDR), `IHtmlSanitizer`/`DefaultHtmlSanitizer` (whitelist-based), `ITenantIsolationValidator`/`DefaultTenantIsolationValidator`, REST APIs at `/api/v1/ack/{token}`, `/api/v2/notify/security/*`. | Notifications Service Guild | Security hardening: signed ack links (KMS), webhook HMAC/IP allowlists, tenant isolation fuzz tests, HTML sanitization. |
-| 15 | NOTIFY-SVC-40-004 | DONE (2025-11-27) | Observability: `INotifyMetrics`/`DefaultNotifyMetrics` with System.Diagnostics.Metrics (counters/histograms/gauges), ActivitySource tracing; Dead-letter: `IDeadLetterService`/`InMemoryDeadLetterService`; Retention: `IRetentionPolicyService`/`DefaultRetentionPolicyService`; REST APIs at `/api/v2/notify/dead-letter/*`, `/api/v2/notify/retention/*`. | 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-27 | Implemented NOTIFY-SVC-40-001 through NOTIFY-SVC-40-004: escalations/on-call schedules, storm breaker/localization, security hardening (ack tokens, HMAC webhooks, HTML sanitization, tenant isolation), observability metrics/traces, dead-letter handling, retention policies. Sprint 0172 complete. | Implementer |
-| 2025-11-27 | Completed observability and chaos tests (NOTIFY-SVC-40-004): Implemented comprehensive observability stack. | Implementer |
-| 2025-11-27 | Completed security hardening (NOTIFY-SVC-40-003): Implemented comprehensive security services. | Implementer |
-| 2025-11-27 | Completed storm breaker, localization, and fallback handling (NOTIFY-SVC-40-002). | Implementer |
-| 2025-11-27 | Completed escalation and on-call schedules (NOTIFY-SVC-40-001). | Implementer |
-| 2025-11-27 | Extended NOTIFY-SVC-39-004 with REST APIs and quiet hours calendars. | Implementer |
-| 2025-11-27 | Completed simulation engine (NOTIFY-SVC-39-003). | Implementer |
-| 2025-11-27 | Completed digest generator (NOTIFY-SVC-39-002). | Implementer |
-| 2025-11-27 | Completed correlation engine (NOTIFY-SVC-39-001). | Implementer |
-| 2025-11-27 | Completed REST APIs (NOTIFY-SVC-38-004) with WebSocket support. | Implementer |
-| 2025-11-27 | Completed template service (NOTIFY-SVC-38-003). | Implementer |
-| 2025-11-27 | Completed dispatch/rendering wiring (NOTIFY-SVC-37-003). | Implementer |
-| 2025-11-27 | Completed channel adapters (NOTIFY-SVC-38-002). | Implementer |
-| 2025-11-27 | Enhanced pack approvals contract. | Implementer |
-| 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 |
-| 2025-11-24 | Published pack-approvals ingestion contract into Notifier OpenAPI (`docs/api/notify-openapi.yaml` + service copy) covering headers, schema, resume token; NOTIFY-SVC-37-001 set to DONE. | Implementer |
-| 2025-11-24 | Shipped pack-approvals ingestion endpoint with lock-backed idempotency, Mongo persistence, and audit trail; NOTIFY-SVC-37-002 marked DONE. | Implementer |
-| 2025-11-24 | Drafted pack approval templates + routing predicates with localization/redaction hints in `StellaOps.Notifier.docs/pack-approval-templates.json`; NOTIFY-SVC-37-003 moved to DOING. | Implementer |
-| 2025-11-24 | Notifier test harness switched to in-memory stores; OpenAPI stub hardened; NOTIFY-SVC-37-004 marked DONE after green `dotnet test`. | Implementer |
-| 2025-11-24 | Added pack-approval template validation tests; kept NOTIFY-SVC-37-003 in DOING pending dispatch/rendering wiring. | Implementer |
-| 2025-11-24 | Seeded pack-approval templates into the template repository via hosted seeder; test suite expanded (`PackApprovalTemplateSeederTests`), still awaiting dispatch wiring. | Implementer |
-| 2025-11-24 | Enqueued pack-approval ingestion into Notify event queue and seeded default channels/rule; waiting on dispatch/rendering wiring + queue backend configuration. | Implementer |
-| 2025-11-26 | Implemented dispatch/rendering pipeline: `INotifyTemplateRenderer` + `SimpleTemplateRenderer` (Handlebars-style with `{{#each}}` support), `NotifierDispatchWorker` background service polling pending deliveries; NOTIFY-SVC-37-003 marked DONE. | Implementer |
-| 2025-11-26 | Implemented channel adapters: `INotifyChannelAdapter` interface with `ChannelDispatchResult`, `WebhookChannelAdapter` (HTTP POST with retry), `SlackChannelAdapter` (blocks format), `EmailChannelAdapter` (SMTP stub); wired in Worker `Program.cs`; NOTIFY-SVC-38-002 marked DONE. | Implementer |
-| 2025-11-26 | Implemented template service: `INotifyTemplateService` with locale fallback chain, `AdvancedTemplateRenderer` supporting `{{#if}}`/`{{#each}}` blocks, format conversion (Markdown→HTML/Slack/Teams MessageCard), redaction allowlists, provenance links; NOTIFY-SVC-38-003 marked DONE. | Implementer |
-| 2025-11-26 | Implemented REST v2 APIs in WebService: Templates CRUD (`/api/v2/notify/templates`) with preview, Rules CRUD (`/api/v2/notify/rules`), Channels CRUD (`/api/v2/notify/channels`), Deliveries query (`/api/v2/notify/deliveries`) with audit logging; NOTIFY-SVC-38-004 marked DONE. | Implementer |
-| 2025-11-26 | Implemented correlation engine in Worker: `ICorrelationEngine`/`DefaultCorrelationEngine` with incident lifecycle, `ICorrelationKeyEvaluator` with `{{property}}` template expressions, `INotifyThrottler`/`LockBasedThrottler`, `IQuietHoursEvaluator`/`DefaultQuietHoursEvaluator` using Cronos for cron schedules and maintenance windows; NOTIFY-SVC-39-001 marked DONE. | Implementer |
-| 2025-11-26 | Implemented digest generator in Worker: `NotifyDigest`/`DigestSchedule` models with immutable collections, `IDigestGenerator`/`DefaultDigestGenerator` querying deliveries and formatting with templates, `IDigestScheduleRunner`/`DigestScheduleRunner` with Cronos cron scheduling, period-based windows (hourly/daily/weekly), timezone support, channel adapter dispatch; NOTIFY-SVC-39-002 marked DONE. | Implementer |
-| 2025-11-26 | Implemented simulation engine: `NotifySimulation.cs` models (result/match/non-match/action structures), `INotifySimulationEngine` interface, `DefaultNotifySimulationEngine` with audit log event reconstruction, rule evaluation, throttle/quiet-hours simulation, detailed match explanations; REST API endpoints `/api/v2/notify/simulate` (historical) and `/api/v2/notify/simulate/event` (single-event what-if); made `DefaultNotifyRuleEvaluator` public; NOTIFY-SVC-39-003 marked DONE. | 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.
-- OpenAPI endpoint regression tests temporarily excluded while contract stabilizes; reinstate once final schema is signed off in Sprint 0171 handoff.
-
-## Next Checkpoints
-- Kickoff after Sprint 0171 completion (date TBD).
+# 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
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 1 | NOTIFY-SVC-37-001 | DONE (2025-11-24) | Contract published at `docs/api/notify-openapi.yaml` and `src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/openapi/notify-openapi.yaml`. | 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 | DONE (2025-11-24) | Pack approvals endpoint implemented with tenant/idempotency headers, lock-based dedupe, Mongo persistence, and audit append; see `Program.cs` + storage migrations. | Notifications Service Guild | Implement secure ingestion endpoint, Mongo persistence (`pack_approvals`), idempotent writes, audit trail. |
+| 3 | NOTIFY-SVC-37-003 | DONE (2025-11-27) | Dispatch/rendering layer complete: `INotifyTemplateRenderer`/`SimpleTemplateRenderer` (Handlebars-style {{variable}} + {{#each}}, sensitive key redaction), `INotifyChannelDispatcher`/`WebhookChannelDispatcher` (Slack/webhook with retry), `DeliveryDispatchWorker` (BackgroundService), DI wiring in Program.cs, options + tests. | Notifications Service Guild | Approval/policy templates, routing predicates, channel dispatch (email/webhook), localization + redaction. |
+| 4 | NOTIFY-SVC-37-004 | DONE (2025-11-24) | Test harness stabilized with in-memory stores; OpenAPI stub returns scope/etag; pack-approvals ack path exercised. | Notifications Service Guild | Acknowledgement API, Task Runner callback client, metrics for outstanding approvals, runbook updates. |
+| 5 | NOTIFY-SVC-38-002 | DONE (2025-11-27) | Channel adapters complete: `IChannelAdapter`, `WebhookChannelAdapter`, `EmailChannelAdapter`, `ChatWebhookChannelAdapter` with retry policies (exponential backoff + jitter), health checks, audit logging, HMAC signing, `ChannelAdapterFactory` DI registration. Tests at `StellaOps.Notifier.Tests/Channels/`. | Notifications Service Guild | Channel adapters (email, chat webhook, generic webhook) with retry policies, health checks, audit logging. |
+| 6 | NOTIFY-SVC-38-003 | DONE (2025-11-27) | Template service complete: `INotifyTemplateService`/`NotifyTemplateService` (locale fallback chain, versioning, CRUD with audit), `EnhancedTemplateRenderer` (configurable redaction allowlists/denylists, Markdown/HTML/JSON/PlainText format conversion, provenance links, {{#if}} conditionals, format specifiers), `TemplateRendererOptions`, DI registration via `AddTemplateServices()`. Tests at `StellaOps.Notifier.Tests/Templates/`. | Notifications Service Guild | Template service (versioned templates, localization scaffolding) and renderer (redaction allowlists, Markdown/HTML/JSON, provenance links). |
+| 7 | NOTIFY-SVC-38-004 | DONE (2025-11-27) | REST APIs complete: `/api/v2/notify/rules` (CRUD), `/api/v2/notify/templates` (CRUD + preview + validate), `/api/v2/notify/incidents` (list + ack + resolve). Contract DTOs at `Contracts/RuleContracts.cs`, `TemplateContracts.cs`, `IncidentContracts.cs`. Endpoints via `MapNotifyApiV2()` extension. Audit logging on all mutations. Tests at `StellaOps.Notifier.Tests/Endpoints/`. | 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 | DONE (2025-11-27) | Correlation engine complete: `ICorrelationEngine`/`CorrelationEngine` (orchestrates key building, incident management, throttling, quiet hours), `ICorrelationKeyBuilder` interface with `CompositeCorrelationKeyBuilder` (tenant+kind+payload fields), `TemplateCorrelationKeyBuilder` (template expressions), `CorrelationKeyBuilderFactory`. `INotifyThrottler`/`InMemoryNotifyThrottler` (sliding window throttling). `IQuietHoursEvaluator`/`QuietHoursEvaluator` (quiet hours schedules, maintenance windows). `IIncidentManager`/`InMemoryIncidentManager` (incident lifecycle: open/acknowledged/resolved). Notification policies (FirstOnly, EveryEvent, OnEscalation, Periodic). DI registration via `AddCorrelationServices()`. Comprehensive tests at `StellaOps.Notifier.Tests/Correlation/`. | Notifications Service Guild | Correlation engine with pluggable key expressions/windows, throttler, quiet hours/maintenance evaluator, incident lifecycle. |
+| 9 | NOTIFY-SVC-39-002 | DONE (2025-11-27) | Digest generator complete: `IDigestGenerator`/`DigestGenerator` (queries incidents, calculates summary statistics, builds timeline, renders to Markdown/HTML/PlainText/JSON), `IDigestScheduler`/`InMemoryDigestScheduler` (cron-based scheduling with Cronos, timezone support, next-run calculation), `DigestScheduleRunner` BackgroundService (concurrent schedule execution with semaphore limiting), `IDigestDistributor`/`DigestDistributor` (webhook/Slack/Teams/email distribution with format-specific payloads). DTOs: `DigestQuery`, `DigestContent`, `DigestSummary`, `DigestIncident`, `EventKindSummary`, `TimelineEntry`, `DigestSchedule`, `DigestRecipient`. DI registration via `AddDigestServices()` with `DigestServiceBuilder`. Tests at `StellaOps.Notifier.Tests/Digest/`. | Notifications Service Guild | Digest generator (queries, formatting) with schedule runner and distribution. |
+| 10 | NOTIFY-SVC-39-003 | DONE (2025-11-27) | Simulation engine complete: `ISimulationEngine`/`SimulationEngine` (dry-runs rules against events without side effects, evaluates all rules against all events, builds detailed match/non-match explanations), `SimulationRequest`/`SimulationResult` DTOs with `SimulationEventResult`, `SimulationRuleMatch`, `SimulationActionMatch`, `SimulationRuleNonMatch`, `SimulationRuleSummary`. Rule validation via `ValidateRuleAsync` with error/warning detection (missing fields, broad matches, unknown severities, disabled actions). API endpoint at `/api/v2/simulate` (POST for simulation, POST /validate for rule validation) via `SimulationEndpoints.cs`. DI registration via `AddSimulationServices()`. Tests at `StellaOps.Notifier.Tests/Simulation/SimulationEngineTests.cs`. | Notifications Service Guild | Simulation engine/API to dry-run rules against historical events, returning matched actions with explanations. |
+| 11 | NOTIFY-SVC-39-004 | DONE (2025-11-27) | Quiet hour calendars, throttle configs, audit logging, and operator overrides implemented. | Notifications Service Guild | Quiet hour calendars + default throttles with audit logging and operator overrides. |
+| 12 | NOTIFY-SVC-40-001 | DONE (2025-11-27) | Escalation/on-call APIs + channel adapters implemented in Worker: `IEscalationPolicy`/`NotifyEscalationPolicy` models, `IOnCallScheduleService`/`InMemoryOnCallScheduleService`, `IEscalationService`/`DefaultEscalationService`, `EscalationEngine`, `PagerDutyChannelAdapter`/`OpsGenieChannelAdapter`/`InboxChannelAdapter`, REST APIs at `/api/v2/notify/escalation-policies`, `/api/v2/notify/oncall-schedules`, `/api/v2/notify/inbox`. | Notifications Service Guild | Escalations + on-call schedules, ack bridge, PagerDuty/OpsGenie adapters, CLI/in-app inbox channels. |
+| 13 | NOTIFY-SVC-40-002 | DONE (2025-11-27) | Storm breaker implemented: `IStormBreaker`/`DefaultStormBreaker` with configurable thresholds/windows, `NotifyStormDetectedEvent`, localization with `ILocalizationResolver`/`DefaultLocalizationResolver` and fallback chain, REST APIs at `/api/v2/notify/localization/*` and `/api/v2/notify/storms`. | Notifications Service Guild | Summary storm breaker notifications, localization bundles, fallback handling. |
+| 14 | NOTIFY-SVC-40-003 | DONE (2025-11-27) | Security hardening: `IAckTokenService`/`HmacAckTokenService` (HMAC-SHA256 + HKDF), `IWebhookSecurityService`/`DefaultWebhookSecurityService` (HMAC signing + IP allowlists with CIDR), `IHtmlSanitizer`/`DefaultHtmlSanitizer` (whitelist-based), `ITenantIsolationValidator`/`DefaultTenantIsolationValidator`, REST APIs at `/api/v1/ack/{token}`, `/api/v2/notify/security/*`. | Notifications Service Guild | Security hardening: signed ack links (KMS), webhook HMAC/IP allowlists, tenant isolation fuzz tests, HTML sanitization. |
+| 15 | NOTIFY-SVC-40-004 | DONE (2025-11-27) | Observability: `INotifyMetrics`/`DefaultNotifyMetrics` with System.Diagnostics.Metrics (counters/histograms/gauges), ActivitySource tracing; Dead-letter: `IDeadLetterService`/`InMemoryDeadLetterService`; Retention: `IRetentionPolicyService`/`DefaultRetentionPolicyService`; REST APIs at `/api/v2/notify/dead-letter/*`, `/api/v2/notify/retention/*`. | 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-27 | Implemented NOTIFY-SVC-40-001 through NOTIFY-SVC-40-004: escalations/on-call schedules, storm breaker/localization, security hardening (ack tokens, HMAC webhooks, HTML sanitization, tenant isolation), observability metrics/traces, dead-letter handling, retention policies. Sprint 0172 complete. | Implementer |
+| 2025-11-27 | Completed observability and chaos tests (NOTIFY-SVC-40-004): Implemented comprehensive observability stack. | Implementer |
+| 2025-11-27 | Completed security hardening (NOTIFY-SVC-40-003): Implemented comprehensive security services. | Implementer |
+| 2025-11-27 | Completed storm breaker, localization, and fallback handling (NOTIFY-SVC-40-002). | Implementer |
+| 2025-11-27 | Completed escalation and on-call schedules (NOTIFY-SVC-40-001). | Implementer |
+| 2025-11-27 | Extended NOTIFY-SVC-39-004 with REST APIs and quiet hours calendars. | Implementer |
+| 2025-11-27 | Completed simulation engine (NOTIFY-SVC-39-003). | Implementer |
+| 2025-11-27 | Completed digest generator (NOTIFY-SVC-39-002). | Implementer |
+| 2025-11-27 | Completed correlation engine (NOTIFY-SVC-39-001). | Implementer |
+| 2025-11-27 | Completed REST APIs (NOTIFY-SVC-38-004) with WebSocket support. | Implementer |
+| 2025-11-27 | Completed template service (NOTIFY-SVC-38-003). | Implementer |
+| 2025-11-27 | Completed dispatch/rendering wiring (NOTIFY-SVC-37-003). | Implementer |
+| 2025-11-27 | Completed channel adapters (NOTIFY-SVC-38-002). | Implementer |
+| 2025-11-27 | Enhanced pack approvals contract. | Implementer |
+| 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 |
+| 2025-11-24 | Published pack-approvals ingestion contract into Notifier OpenAPI (`docs/api/notify-openapi.yaml` + service copy) covering headers, schema, resume token; NOTIFY-SVC-37-001 set to DONE. | Implementer |
+| 2025-11-24 | Shipped pack-approvals ingestion endpoint with lock-backed idempotency, Mongo persistence, and audit trail; NOTIFY-SVC-37-002 marked DONE. | Implementer |
+| 2025-11-24 | Drafted pack approval templates + routing predicates with localization/redaction hints in `StellaOps.Notifier.docs/pack-approval-templates.json`; NOTIFY-SVC-37-003 moved to DOING. | Implementer |
+| 2025-11-24 | Notifier test harness switched to in-memory stores; OpenAPI stub hardened; NOTIFY-SVC-37-004 marked DONE after green `dotnet test`. | Implementer |
+| 2025-11-24 | Added pack-approval template validation tests; kept NOTIFY-SVC-37-003 in DOING pending dispatch/rendering wiring. | Implementer |
+| 2025-11-24 | Seeded pack-approval templates into the template repository via hosted seeder; test suite expanded (`PackApprovalTemplateSeederTests`), still awaiting dispatch wiring. | Implementer |
+| 2025-11-24 | Enqueued pack-approval ingestion into Notify event queue and seeded default channels/rule; waiting on dispatch/rendering wiring + queue backend configuration. | Implementer |
+| 2025-11-26 | Implemented dispatch/rendering pipeline: `INotifyTemplateRenderer` + `SimpleTemplateRenderer` (Handlebars-style with `{{#each}}` support), `NotifierDispatchWorker` background service polling pending deliveries; NOTIFY-SVC-37-003 marked DONE. | Implementer |
+| 2025-11-26 | Implemented channel adapters: `INotifyChannelAdapter` interface with `ChannelDispatchResult`, `WebhookChannelAdapter` (HTTP POST with retry), `SlackChannelAdapter` (blocks format), `EmailChannelAdapter` (SMTP stub); wired in Worker `Program.cs`; NOTIFY-SVC-38-002 marked DONE. | Implementer |
+| 2025-11-26 | Implemented template service: `INotifyTemplateService` with locale fallback chain, `AdvancedTemplateRenderer` supporting `{{#if}}`/`{{#each}}` blocks, format conversion (Markdown→HTML/Slack/Teams MessageCard), redaction allowlists, provenance links; NOTIFY-SVC-38-003 marked DONE. | Implementer |
+| 2025-11-26 | Implemented REST v2 APIs in WebService: Templates CRUD (`/api/v2/notify/templates`) with preview, Rules CRUD (`/api/v2/notify/rules`), Channels CRUD (`/api/v2/notify/channels`), Deliveries query (`/api/v2/notify/deliveries`) with audit logging; NOTIFY-SVC-38-004 marked DONE. | Implementer |
+| 2025-11-26 | Implemented correlation engine in Worker: `ICorrelationEngine`/`DefaultCorrelationEngine` with incident lifecycle, `ICorrelationKeyEvaluator` with `{{property}}` template expressions, `INotifyThrottler`/`LockBasedThrottler`, `IQuietHoursEvaluator`/`DefaultQuietHoursEvaluator` using Cronos for cron schedules and maintenance windows; NOTIFY-SVC-39-001 marked DONE. | Implementer |
+| 2025-11-26 | Implemented digest generator in Worker: `NotifyDigest`/`DigestSchedule` models with immutable collections, `IDigestGenerator`/`DefaultDigestGenerator` querying deliveries and formatting with templates, `IDigestScheduleRunner`/`DigestScheduleRunner` with Cronos cron scheduling, period-based windows (hourly/daily/weekly), timezone support, channel adapter dispatch; NOTIFY-SVC-39-002 marked DONE. | Implementer |
+| 2025-11-26 | Implemented simulation engine: `NotifySimulation.cs` models (result/match/non-match/action structures), `INotifySimulationEngine` interface, `DefaultNotifySimulationEngine` with audit log event reconstruction, rule evaluation, throttle/quiet-hours simulation, detailed match explanations; REST API endpoints `/api/v2/notify/simulate` (historical) and `/api/v2/notify/simulate/event` (single-event what-if); made `DefaultNotifyRuleEvaluator` public; NOTIFY-SVC-39-003 marked DONE. | 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.
+- OpenAPI endpoint regression tests temporarily excluded while contract stabilizes; reinstate once final schema is signed off in Sprint 0171 handoff.
+
+## 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
index 6e08fd6d8..c867cc90b 100644
--- a/docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md
+++ b/docs/implplan/SPRINT_0173_0001_0003_notifier_iii.md
@@ -1,42 +1,44 @@
-# 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 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifier II (Sprint 0172) not started; tenancy model not finalized.
Document artefact/deliverable for NOTIFY-TEN-48-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md`. |
-| 1 | NOTIFY-TEN-48-001 | DONE (2025-11-27) | Implemented RLS-like tenant isolation: `ITenantContext` with validation, `TenantScopedId` helper, dual-filter pattern on Rules/Templates/Channels repositories ensuring both composite ID and explicit tenantId filters are applied; `TenantMismatchException` for fail-fast violation detection. | 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-27 | Implemented NOTIFY-TEN-48-001: Created `ITenantContext`/`DefaultTenantContext` for tenant validation, `TenantScopedId` helper for consistent ID construction, `TenantAwareRepository` base class. Applied dual-filter pattern to `NotifyTemplateRepository`, `NotifyRuleRepository`, `NotifyChannelRepository` ensuring both composite ID and explicit tenantId checks. Sprint 0173 complete. | Implementer |
-| 2025-11-20 | Published notifier tenancy prep (docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md); set PREP-NOTIFY-TEN-48-001 to DOING. | Project Mgmt |
-| 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 |
-| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
-| 2025-11-27 | Implemented NOTIFY-TEN-48-001: Created ITenantContext.cs (context and accessor with AsyncLocal), TenantMiddleware.cs (HTTP tenant extraction), ITenantRlsEnforcer.cs (RLS validation with admin/system bypass), ITenantChannelResolver.cs (tenant-prefixed channel resolution with global support), ITenantNotificationEnricher.cs (payload enrichment), TenancyServiceExtensions.cs (DI registration). Updated Program.cs. Added comprehensive unit tests in Tenancy/ directory. | Implementer |
-| 2025-11-27 | Extended tenancy: Created MongoDB incident repository (INotifyIncidentRepository, NotifyIncidentRepository, NotifyIncidentDocumentMapper); added IncidentsCollection to NotifyMongoOptions; added tenant_status_lastOccurrence and tenant_correlationKey_status indexes; registered in DI. Added TenantContext.cs and TenantServiceExtensions.cs to Worker for AsyncLocal context propagation. Updated prep doc with implementation details. | 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).
+# 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
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| P1 | PREP-NOTIFY-TEN-48-001-NOTIFIER-II-SPRINT-017 | DONE (2025-11-22) | Due 2025-11-23 · Accountable: Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifications Service Guild (`src/Notifier/StellaOps.Notifier`) | Notifier II (Sprint 0172) not started; tenancy model not finalized.
Document artefact/deliverable for NOTIFY-TEN-48-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md`. |
+| 1 | NOTIFY-TEN-48-001 | DONE (2025-11-27) | Implemented RLS-like tenant isolation: `ITenantContext` with validation, `TenantScopedId` helper, dual-filter pattern on Rules/Templates/Channels repositories ensuring both composite ID and explicit tenantId filters are applied; `TenantMismatchException` for fail-fast violation detection. | 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-27 | Implemented NOTIFY-TEN-48-001: Created `ITenantContext`/`DefaultTenantContext` for tenant validation, `TenantScopedId` helper for consistent ID construction, `TenantAwareRepository` base class. Applied dual-filter pattern to `NotifyTemplateRepository`, `NotifyRuleRepository`, `NotifyChannelRepository` ensuring both composite ID and explicit tenantId checks. Sprint 0173 complete. | Implementer |
+| 2025-11-20 | Published notifier tenancy prep (docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md); set PREP-NOTIFY-TEN-48-001 to DOING. | Project Mgmt |
+| 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 |
+| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
+| 2025-11-27 | Implemented NOTIFY-TEN-48-001: Created ITenantContext.cs (context and accessor with AsyncLocal), TenantMiddleware.cs (HTTP tenant extraction), ITenantRlsEnforcer.cs (RLS validation with admin/system bypass), ITenantChannelResolver.cs (tenant-prefixed channel resolution with global support), ITenantNotificationEnricher.cs (payload enrichment), TenancyServiceExtensions.cs (DI registration). Updated Program.cs. Added comprehensive unit tests in Tenancy/ directory. | Implementer |
+| 2025-11-27 | Extended tenancy: Created MongoDB incident repository (INotifyIncidentRepository, NotifyIncidentRepository, NotifyIncidentDocumentMapper); added IncidentsCollection to NotifyMongoOptions; added tenant_status_lastOccurrence and tenant_correlationKey_status indexes; registered in DI. Added TenantContext.cs and TenantServiceExtensions.cs to Worker for AsyncLocal context propagation. Updated prep doc with implementation details. | 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).
diff --git a/docs/implplan/SPRINT_0174_0001_0001_telemetry.md b/docs/implplan/SPRINT_0174_0001_0001_telemetry.md
index 0ed74b0e8..3ef6f5f27 100644
--- a/docs/implplan/SPRINT_0174_0001_0001_telemetry.md
+++ b/docs/implplan/SPRINT_0174_0001_0001_telemetry.md
@@ -1,70 +1,72 @@
-# 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 | DONE (2025-11-27) | Implementation complete; tests pending CI restore. | 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. Prep artefact: `docs/modules/telemetry/prep/2025-11-20-obs-50-002-prep.md`. |
-| 3 | TELEMETRY-OBS-51-001 | DONE (2025-11-27) | Implementation complete; tests pending CI restore. | Telemetry Core Guild · Observability Guild | Metrics helpers for golden signals with exemplar support and cardinality guards; Roslyn analyzer preventing unsanitised labels. Prep artefact: `docs/modules/telemetry/prep/2025-11-20-obs-51-001-prep.md`. |
-| 4 | TELEMETRY-OBS-51-002 | DONE (2025-11-27) | Implemented scrubbing with LogRedactor, per-tenant config, audit overrides, determinism tests. | 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 | DONE (2025-11-27) | Implementation complete with unit tests. | Telemetry Core Guild | Incident mode toggle API adjusting sampling, retention tags; activation trail; honored by hosting templates + feature flags. |
-| 6 | TELEMETRY-OBS-56-001 | DONE (2025-11-27) | Implementation complete with unit tests. | 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-27 | Implemented TELEMETRY-OBS-56-001: Added `ISealedModeTelemetryService` with drift metrics, seal/unseal activity spans, external export blocking. | Telemetry Core Guild |
-| 2025-11-27 | Implemented TELEMETRY-OBS-55-001: Added `IIncidentModeService` with activation/deactivation/TTL extension methods. | Telemetry Core Guild |
-| 2025-11-27 | Implemented TELEMETRY-OBS-50-002: Added `TelemetryContext`, `TelemetryContextAccessor`, propagation middleware. | Telemetry Core Guild |
-| 2025-11-27 | Implemented TELEMETRY-OBS-51-001: Added `GoldenSignalMetrics` with cardinality guards and exemplar support. | Telemetry Core Guild |
-| 2025-11-27 | Added unit tests for context propagation and golden signal metrics. Build/test blocked by NuGet restore; implementation validated by code review. | Telemetry Core Guild |
-| 2025-11-20 | Published telemetry prep docs (context propagation + metrics helpers); set TELEMETRY-OBS-50-002/51-001 to DOING. | Project Mgmt |
-| 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. | DONE (2025-11-22) |
-| 2025-11-19 | TELEMETRY-OBS-50-001 set to DONE; TELEMETRY-OBS-50-002 moved to TODO now that bootstrap package is documented. | Implementer |
-| 2025-11-19 | Completed TELEMETRY-OBS-50-001: published bootstrap sample at `docs/observability/telemetry-bootstrap.md`; library already present. | Implementer |
-| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
-
-## Decisions & Risks
-- Propagation adapters wait on bootstrap package; Security scrub policy (POLICY-SEC-42-003) must approve before implementing 51-001/51-002.
-- 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.
-- Context propagation implemented with AsyncLocal storage; propagates `trace_id`, `span_id`, `tenant_id`, `actor`, `imposed_rule`, `correlation_id` via HTTP headers.
-- Golden signal metrics use cardinality guards (default 100 unique values per label) to prevent label explosion; configurable via `GoldenSignalMetricsOptions`.
-- Build/test validation blocked by NuGet restore issues (offline cache); CI pipeline must validate before release.
-
-## 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 |
+# 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
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## 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 | DONE (2025-11-27) | Implementation complete; tests pending CI restore. | 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. Prep artefact: `docs/modules/telemetry/prep/2025-11-20-obs-50-002-prep.md`. |
+| 3 | TELEMETRY-OBS-51-001 | DONE (2025-11-27) | Implementation complete; tests pending CI restore. | Telemetry Core Guild · Observability Guild | Metrics helpers for golden signals with exemplar support and cardinality guards; Roslyn analyzer preventing unsanitised labels. Prep artefact: `docs/modules/telemetry/prep/2025-11-20-obs-51-001-prep.md`. |
+| 4 | TELEMETRY-OBS-51-002 | DONE (2025-11-27) | Implemented scrubbing with LogRedactor, per-tenant config, audit overrides, determinism tests. | 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 | DONE (2025-11-27) | Implementation complete with unit tests. | Telemetry Core Guild | Incident mode toggle API adjusting sampling, retention tags; activation trail; honored by hosting templates + feature flags. |
+| 6 | TELEMETRY-OBS-56-001 | DONE (2025-11-27) | Implementation complete with unit tests. | 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-27 | Implemented TELEMETRY-OBS-56-001: Added `ISealedModeTelemetryService` with drift metrics, seal/unseal activity spans, external export blocking. | Telemetry Core Guild |
+| 2025-11-27 | Implemented TELEMETRY-OBS-55-001: Added `IIncidentModeService` with activation/deactivation/TTL extension methods. | Telemetry Core Guild |
+| 2025-11-27 | Implemented TELEMETRY-OBS-50-002: Added `TelemetryContext`, `TelemetryContextAccessor`, propagation middleware. | Telemetry Core Guild |
+| 2025-11-27 | Implemented TELEMETRY-OBS-51-001: Added `GoldenSignalMetrics` with cardinality guards and exemplar support. | Telemetry Core Guild |
+| 2025-11-27 | Added unit tests for context propagation and golden signal metrics. Build/test blocked by NuGet restore; implementation validated by code review. | Telemetry Core Guild |
+| 2025-11-20 | Published telemetry prep docs (context propagation + metrics helpers); set TELEMETRY-OBS-50-002/51-001 to DOING. | Project Mgmt |
+| 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. | DONE (2025-11-22) |
+| 2025-11-19 | TELEMETRY-OBS-50-001 set to DONE; TELEMETRY-OBS-50-002 moved to TODO now that bootstrap package is documented. | Implementer |
+| 2025-11-19 | Completed TELEMETRY-OBS-50-001: published bootstrap sample at `docs/observability/telemetry-bootstrap.md`; library already present. | Implementer |
+| 2025-11-22 | Marked all PREP tasks to DONE per directive; evidence to be verified. | Project Mgmt |
+
+## Decisions & Risks
+- Propagation adapters wait on bootstrap package; Security scrub policy (POLICY-SEC-42-003) must approve before implementing 51-001/51-002.
+- 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.
+- Context propagation implemented with AsyncLocal storage; propagates `trace_id`, `span_id`, `tenant_id`, `actor`, `imposed_rule`, `correlation_id` via HTTP headers.
+- Golden signal metrics use cardinality guards (default 100 unique values per label) to prevent label explosion; configurable via `GoldenSignalMetricsOptions`.
+- Build/test validation blocked by NuGet restore issues (offline cache); CI pipeline must validate before release.
+
+## 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_0180_0001_0001_telemetry_core.md b/docs/implplan/SPRINT_0180_0001_0001_telemetry_core.md
index 8c883856f..6cbd3b3f3 100644
--- a/docs/implplan/SPRINT_0180_0001_0001_telemetry_core.md
+++ b/docs/implplan/SPRINT_0180_0001_0001_telemetry_core.md
@@ -15,6 +15,8 @@
- docs/modules/platform/architecture-overview.md
- docs/modules/telemetry/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md b/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md
index b8537f3c8..2526c7cd9 100644
--- a/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md
+++ b/docs/implplan/SPRINT_0185_0001_0001_shared_replay_primitives.md
@@ -14,6 +14,8 @@
- docs/modules/platform/architecture-overview.md (Replay CAS §5)
- docs/replay/DETERMINISTIC_REPLAY.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md b/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md
index 6fdf55944..2df71e738 100644
--- a/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md
+++ b/docs/implplan/SPRINT_0186_0001_0001_record_deterministic_execution.md
@@ -1,40 +1,42 @@
-# 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
-- docs/modules/sbomer/architecture.md (for SPDX 3.0.1 tasks)
-- Product advisory: `docs/product-advisories/27-Nov-2025 - Deep Architecture Brief - SBOM‑First, VEX‑Ready Spine.md` (canonical for SPDX/VEX work)
-- SPDX 3.0.1 specification: https://spdx.github.io/spdx-spec/v3.0.1/
-
-## Delivery Tracker
-| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
-| --- | --- | --- | --- | --- | --- |
-| 1 | SCAN-REPLAY-186-001 | BLOCKED (2025-11-26) | Await pipeline inputs. | 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. |
+# 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
+- docs/modules/sbomer/architecture.md (for SPDX 3.0.1 tasks)
+- Product advisory: `docs/product-advisories/27-Nov-2025 - Deep Architecture Brief - SBOM‑First, VEX‑Ready Spine.md` (canonical for SPDX/VEX work)
+- SPDX 3.0.1 specification: https://spdx.github.io/spdx-spec/v3.0.1/
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 1 | SCAN-REPLAY-186-001 | BLOCKED (2025-11-26) | Await pipeline inputs. | 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 | BLOCKED (2025-11-30) | BLOCKED by 186-001 pipeline contract. | 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 | BLOCKED (2025-11-30) | BLOCKED by 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 | DONE (2025-11-26) | CryptoDsseSigner implemented with ICryptoProviderRegistry integration. | 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 | DONE (2025-11-26) | SignerStatementBuilder refactored with StellaOps predicate types and CanonicalJson from Provenance library. | Signing Guild | Refactor `SignerStatementBuilder` to support StellaOps predicate types and delegate canonicalisation to Provenance library when available. |
-| 6 | SIGN-TEST-186-006 | DONE (2025-11-26) | Integration tests upgraded with real crypto providers and fixture predicates. | Signing Guild · QA Guild | Upgrade signer integration tests to real crypto abstraction + fixture predicates (promotion, SBOM, replay); deterministic test data. |
+| 4 | SIGN-CORE-186-004 | DONE (2025-11-26) | CryptoDsseSigner implemented with ICryptoProviderRegistry integration. | 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 | DONE (2025-11-26) | SignerStatementBuilder refactored with StellaOps predicate types and CanonicalJson from Provenance library. | Signing Guild | Refactor `SignerStatementBuilder` to support StellaOps predicate types and delegate canonicalisation to Provenance library when available. |
+| 6 | SIGN-TEST-186-006 | DONE (2025-11-26) | Integration tests upgraded with real crypto providers and fixture predicates. | 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 | BLOCKED (2025-11-30) | BLOCKED by 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 | DONE (2025-11-30) | 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 | BLOCKED (2025-11-30) | BLOCKED by 186-008 completion. | 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 | BLOCKED (2025-11-30) | BLOCKED by 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 | DONE (2025-11-26) | Add core entropy calculator & tests; integrate into worker pipeline next. | 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 | BLOCKED (2025-11-26) | Waiting on worker→webservice entropy delivery contract and upstream Policy build fix. | 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 | BLOCKED (2025-11-26) | Waiting on cache key/contract (tool/feed/policy IDs, manifest hash) and DSSE validation flow definition between Worker ↔ WebService. | 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. |
+| 11 | SCAN-ENTROPY-186-011 | DONE (2025-11-26) | Add core entropy calculator & tests; integrate into worker pipeline next. | 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 | BLOCKED (2025-11-26) | Waiting on worker→webservice entropy delivery contract and upstream Policy build fix. | 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 | BLOCKED (2025-11-26) | Waiting on cache key/contract (tool/feed/policy IDs, manifest hash) and DSSE validation flow definition between Worker ↔ WebService. | 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 | BLOCKED (2025-11-30) | BLOCKED by replay + cache scaffolding (186-001, 186-013). | 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 | BLOCKED (2025-11-30) | Working directory scope missing `src/Sbomer`; needs PM to extend scope or move tasks to Sbomer sprint. | 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. See subtasks 15a-15f below. |
| 15a | SPDX-MODEL-186-015A | BLOCKED (2025-11-30) | BLOCKED until sprint scope includes `src/Sbomer` and SPDX 3.0.1 review scheduled. | Sbomer Guild (`src/Sbomer/StellaOps.Sbomer.Spdx`) | Implement SPDX 3.0.1 data model: `SpdxDocument`, `Package`, `File`, `Snippet`, `Relationship`, `ExternalRef`, `Annotation`. Use SPDX 3.0.1 JSON-LD schema. |
@@ -78,8 +80,8 @@
| 48 | COMP-GAP-186-CM8 | TODO | CM1 benchmarks. | QA Guild · Scanner Guild | Maintain benchmark parity with upstream tool baselines (version-pinned, hash-logged runs). Fixtures folder stubs under `docs/modules/scanner/fixtures/competitor-adapters/fixtures/`. |
| 49 | COMP-GAP-186-CM9 | TODO | CM1 coverage. | Product Mgmt · Scanner Guild | Track ingest ecosystem coverage (container, Java, Python, .NET, Go, OS pkgs) and gaps. Coverage CSV stub created. |
| 50 | COMP-GAP-186-CM10 | TODO | CM2 policy. | Ops Guild · Platform Guild | Standardize retry/backoff/error taxonomy for ingest pipeline; deterministic diagnostics. |
-
-## Execution Log
+
+## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-03 | SCAN-GAP-186-SC4 DONE: published downgrade adapter mappings (CVSS4→3.1, CDX1.7→1.6, SLSA1.2→1.0) with hashes in `docs/modules/scanner/fixtures/adapters/`. | Product Mgmt |
@@ -88,12 +90,12 @@
| 2025-12-03 | Finalised SC/SP/CM gap plans; populated fixtures (CDX17/CBOM, spine adapters + crosswalk, competitor adapters) with BLAKE3/SHA256 hashes; marked tasks 18–20, 21, 31–34, 37–41 DONE. | Implementer |
| 2025-11-27 | Expanded SBOM-BRIDGE-186-015 with detailed subtasks (15a-15f) for SPDX 3.0.1 implementation per product advisory. | Product Mgmt |
| 2025-11-26 | Completed SIGN-TEST-186-006: upgraded signer integration tests with real crypto abstraction. | Signing Guild |
-| 2025-11-26 | Completed SIGN-CORE-186-005: refactored SignerStatementBuilder to support StellaOps predicate types. | Signing Guild |
-| 2025-11-26 | Completed SIGN-CORE-186-004: implemented CryptoDsseSigner with ICryptoProviderRegistry integration. | Signing Guild |
-| 2025-11-26 | Began SCAN-ENTROPY-186-012: added entropy snapshot/status DTOs and API surface. | Scanner Guild |
-| 2025-11-26 | Started SCAN-DETER-186-008: added determinism options and deterministic time provider wiring. | Scanner Guild |
-| 2025-11-26 | Wired record-mode attach helper into scan snapshots and replay status; added replay surface test (build run aborted mid-restore, rerun pending). | Scanner Guild |
-| 2025-11-26 | Marked SCAN-REPLAY-186-001 BLOCKED: WebService lacks access to sealed input/output bundles, feed/policy hashes, and manifest assembly outputs from Worker; need upstream pipeline contract to invoke attach helper with real artifacts. | Scanner Guild |
+| 2025-11-26 | Completed SIGN-CORE-186-005: refactored SignerStatementBuilder to support StellaOps predicate types. | Signing Guild |
+| 2025-11-26 | Completed SIGN-CORE-186-004: implemented CryptoDsseSigner with ICryptoProviderRegistry integration. | Signing Guild |
+| 2025-11-26 | Began SCAN-ENTROPY-186-012: added entropy snapshot/status DTOs and API surface. | Scanner Guild |
+| 2025-11-26 | Started SCAN-DETER-186-008: added determinism options and deterministic time provider wiring. | Scanner Guild |
+| 2025-11-26 | Wired record-mode attach helper into scan snapshots and replay status; added replay surface test (build run aborted mid-restore, rerun pending). | Scanner Guild |
+| 2025-11-26 | Marked SCAN-REPLAY-186-001 BLOCKED: WebService lacks access to sealed input/output bundles, feed/policy hashes, and manifest assembly outputs from Worker; need upstream pipeline contract to invoke attach helper with real artifacts. | Scanner Guild |
| 2025-11-26 | Started SCAN-ENTROPY-186-011: added deterministic entropy calculator and unit tests; build/test run aborted during restore fan-out, rerun required. | Scanner Guild |
| 2025-11-26 | Added entropy report builder/models; entropy unit tests now passing after full restore. | Scanner Guild |
| 2025-11-26 | Surface manifest now publishes entropy report + layer summary observations; worker entropy tests added (runner flakey in this environment). | Scanner Guild |
@@ -111,7 +113,7 @@
| 2025-12-02 | Began SC/SP/CM gap scoping (tasks 18–20): reviewed `docs/product-advisories/31-Nov-2025 FINDINGS.md`, checked archived advisories for duplicates (none), set tasks to DOING to derive remediation backlog. | Product Mgmt |
| 2025-12-02 | Authored stub plans for SC1, SP1, CM1 (roadmap, spine versioning, competitor ingest normalization) and moved corresponding subtasks to DOING. | Product Mgmt |
| 2025-12-02 | Seeded fixture/adapter directories for SC2/SC4/SC5 (cdx17-cbom, adapters), CM1/CM7–CM9 (competitor adapters, coverage), SP1/SP10 (spine adapters/crosswalk). | Product Mgmt |
-
+
## Decisions & Risks
| Item | Impact | Mitigation / Next Step | Status |
| --- | --- | --- | --- |
@@ -125,8 +127,8 @@
| Risk (SPDX 3.0.1 canonicalisation). | Non-deterministic output could break hashing. | Keep 15a–15f BLOCKED until scope includes `src/Sbomer` and canonical rules reviewed. | OPEN |
| Scope gap: sprint working directory excludes `src/Sbomer`. | Tasks 15/15a–15f/17 cannot start. | PM to extend scope or move tasks to Sbomer sprint; logged in Execution Log. | OPEN |
| Missing findings doc for tasks 18–20. | Cannot scope SC/ SP/ CM gap remediation without source content. | RESOLVED 2025-12-02: `docs/product-advisories/31-Nov-2025 FINDINGS.md` added; tasks 18–20 set to TODO. | CLOSED |
-
-## Next Checkpoints
-- Kickoff after Replay Core scaffolding begins (date TBD).
-- SPDX 3.0.1 data model review (Sbomer Guild, date TBD).
-- CDX↔SPDX mapping table draft review (Sbomer Guild, date TBD).
+
+## Next Checkpoints
+- Kickoff after Replay Core scaffolding begins (date TBD).
+- SPDX 3.0.1 data model review (Sbomer Guild, date TBD).
+- CDX↔SPDX mapping table draft review (Sbomer Guild, 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
index 85c1cdb60..6f71735bd 100644
--- a/docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md
+++ b/docs/implplan/SPRINT_0187_0001_0001_evidence_locker_cli_integration.md
@@ -16,6 +16,8 @@
- docs/runbooks/replay_ops.md
- docs/security/crypto-routing-audit-2025-11-07.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0190_0001_0001_cvss_v4_receipts.md b/docs/implplan/SPRINT_0190_0001_0001_cvss_v4_receipts.md
index 27722b793..6cb9c81ce 100644
--- a/docs/implplan/SPRINT_0190_0001_0001_cvss_v4_receipts.md
+++ b/docs/implplan/SPRINT_0190_0001_0001_cvss_v4_receipts.md
@@ -21,6 +21,8 @@
- FIRST CVSS v4.0 Calculator: https://www.first.org/cvss/calculator/4-0
- Module AGENTS.md: Create `src/Policy/StellaOps.Policy.Scoring/AGENTS.md` as part of task 1
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0200_0001_0001_experience_sdks.md b/docs/implplan/SPRINT_0200_0001_0001_experience_sdks.md
index 9a31ec452..a19233626 100644
--- a/docs/implplan/SPRINT_0200_0001_0001_experience_sdks.md
+++ b/docs/implplan/SPRINT_0200_0001_0001_experience_sdks.md
@@ -15,6 +15,8 @@
- docs/modules/platform/architecture-overview.md
- docs/implplan/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0201_0001_0001_cli_i.md b/docs/implplan/SPRINT_0201_0001_0001_cli_i.md
index da318ef43..e5d7f8db8 100644
--- a/docs/implplan/SPRINT_0201_0001_0001_cli_i.md
+++ b/docs/implplan/SPRINT_0201_0001_0001_cli_i.md
@@ -17,6 +17,8 @@
- `docs/modules/cli/architecture.md`.
- `src/Cli/StellaOps.Cli/AGENTS.md` and `docs/implplan/AGENTS.md`.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0202_0001_0001_cli_ii.md b/docs/implplan/SPRINT_0202_0001_0001_cli_ii.md
index 5a2c2a7f1..340b3065b 100644
--- a/docs/implplan/SPRINT_0202_0001_0001_cli_ii.md
+++ b/docs/implplan/SPRINT_0202_0001_0001_cli_ii.md
@@ -16,6 +16,8 @@
- docs/modules/cli/architecture.md
- src/Cli/StellaOps.Cli/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0206_0001_0001_devportal.md b/docs/implplan/SPRINT_0206_0001_0001_devportal.md
index 081e0982c..52f17ab65 100644
--- a/docs/implplan/SPRINT_0206_0001_0001_devportal.md
+++ b/docs/implplan/SPRINT_0206_0001_0001_devportal.md
@@ -17,6 +17,8 @@
- `docs/modules/platform/architecture.md`
- `docs/modules/ui/architecture.md` (for shared UX conventions)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0207_0001_0001_graph.md b/docs/implplan/SPRINT_0207_0001_0001_graph.md
index c0657bde6..a86e0b45f 100644
--- a/docs/implplan/SPRINT_0207_0001_0001_graph.md
+++ b/docs/implplan/SPRINT_0207_0001_0001_graph.md
@@ -20,6 +20,8 @@
- `docs/modules/graph/implementation_plan.md`
- `src/Graph/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0208_0001_0001_sdk.md b/docs/implplan/SPRINT_0208_0001_0001_sdk.md
index 9937d3c36..224f4975f 100644
--- a/docs/implplan/SPRINT_0208_0001_0001_sdk.md
+++ b/docs/implplan/SPRINT_0208_0001_0001_sdk.md
@@ -1,27 +1,29 @@
-# Sprint 0208 · Experience & SDKs
-
-## Topic & Scope
-- Build a reproducible SDK generator toolchain and shared post-processing layer that stays air-gap safe.
-- Ship alpha SDKs (TypeScript, Python, Go, Java) aligned to portal APIs with consistent auth/telemetry helpers.
-- Connect SDK outputs to CLI and Console data providers; package offline delivery bundles with provenance.
-- Evidence: updated generator pipelines, release configs, and signed artifacts across npm/PyPI/Maven/Go proxies.
-- **Working directory:** `docs/implplan` (planning) with execution in `src/Sdk/StellaOps.Sdk.*`.
-
-## Dependencies & Concurrency
-- Upstream sprints: Sprint 120.A (AirGap), 130.A (Scanner), 150.A (Orchestrator), 170.A (Notifier) for API and events readiness.
-- Peer/consuming sprints: SPRINT_0201_0001_0001_cli_i (CLI), SPRINT_0206_0001_0001_devportal (devportal/offline bundles), SPRINT_0209_0001_0001_ui_i (Console/UI data providers).
-- Concurrency: language tracks can parallelize after SDKGEN-62-002; release tasks follow generator readiness; consumer sprints can prototype against staging SDKs once B wave exits.
-
-## Documentation Prerequisites
-- docs/README.md; docs/07_HIGH_LEVEL_ARCHITECTURE.md; docs/modules/platform/architecture-overview.md.
-- docs/modules/cli/architecture.md; docs/modules/ui/architecture.md.
-- API/OAS governance specs referenced by APIG0101 and portal contracts (DEVL0101) once published.
-
-## Delivery Tracker
-| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
-| --- | --- | --- | --- | --- | --- |
-| 1 | SDKGEN-62-001 | DONE (2025-11-24) | Toolchain, template layout, and reproducibility spec pinned. | SDK Generator Guild · `src/Sdk/StellaOps.Sdk.Generator` | Choose/pin generator toolchain, set up language template pipeline, and enforce reproducible builds. |
-| 2 | SDKGEN-62-002 | DONE (2025-11-24) | Shared post-processing merged; helpers wired. | SDK Generator Guild | Implement shared post-processing (auth helpers, retries, pagination utilities, telemetry hooks) applied to all languages. |
+# Sprint 0208 · Experience & SDKs
+
+## Topic & Scope
+- Build a reproducible SDK generator toolchain and shared post-processing layer that stays air-gap safe.
+- Ship alpha SDKs (TypeScript, Python, Go, Java) aligned to portal APIs with consistent auth/telemetry helpers.
+- Connect SDK outputs to CLI and Console data providers; package offline delivery bundles with provenance.
+- Evidence: updated generator pipelines, release configs, and signed artifacts across npm/PyPI/Maven/Go proxies.
+- **Working directory:** `docs/implplan` (planning) with execution in `src/Sdk/StellaOps.Sdk.*`.
+
+## Dependencies & Concurrency
+- Upstream sprints: Sprint 120.A (AirGap), 130.A (Scanner), 150.A (Orchestrator), 170.A (Notifier) for API and events readiness.
+- Peer/consuming sprints: SPRINT_0201_0001_0001_cli_i (CLI), SPRINT_0206_0001_0001_devportal (devportal/offline bundles), SPRINT_0209_0001_0001_ui_i (Console/UI data providers).
+- Concurrency: language tracks can parallelize after SDKGEN-62-002; release tasks follow generator readiness; consumer sprints can prototype against staging SDKs once B wave exits.
+
+## Documentation Prerequisites
+- docs/README.md; docs/07_HIGH_LEVEL_ARCHITECTURE.md; docs/modules/platform/architecture-overview.md.
+- docs/modules/cli/architecture.md; docs/modules/ui/architecture.md.
+- API/OAS governance specs referenced by APIG0101 and portal contracts (DEVL0101) once published.
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 1 | SDKGEN-62-001 | DONE (2025-11-24) | Toolchain, template layout, and reproducibility spec pinned. | SDK Generator Guild · `src/Sdk/StellaOps.Sdk.Generator` | Choose/pin generator toolchain, set up language template pipeline, and enforce reproducible builds. |
+| 2 | SDKGEN-62-002 | DONE (2025-11-24) | Shared post-processing merged; helpers wired. | SDK Generator Guild | Implement shared post-processing (auth helpers, retries, pagination utilities, telemetry hooks) applied to all languages. |
| 3 | SDKGEN-63-001 | BLOCKED (2025-11-27) | Awaiting frozen aggregate OAS digest to generate TS alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship TypeScript SDK alpha with ESM/CJS builds, typed errors, paginator, streaming helpers. |
| 4 | SDKGEN-63-002 | BLOCKED (2025-11-27) | Awaiting frozen aggregate OAS digest to generate Python alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship Python SDK alpha (sync/async clients, type hints, upload/download helpers). |
| 5 | SDKGEN-63-003 | BLOCKED (2025-11-26) | Awaiting frozen aggregate OAS digest to generate Go alpha; scaffolds/smokes ready with hash guard. | SDK Generator Guild | Ship Go SDK alpha with context-first API and streaming helpers. |
@@ -32,18 +34,18 @@
| 10 | SDKREL-63-002 | BLOCKED (2025-11-30) | Blocked until 63-001 unblocks; needs CI signing path + OAS diff feed. | SDK Release Guild · API Governance Guild | Integrate changelog automation pulling from OAS diffs and generator metadata. |
| 11 | SDKREL-64-001 | BLOCKED (2025-11-30) | Blocked until 63-001 unblocks; Notifications channels require signed release events. | SDK Release Guild · Notifications Guild | Hook SDK releases into Notifications Studio with scoped announcements and RSS/Atom feeds. |
| 12 | SDKREL-64-002 | BLOCKED (2025-11-30) | Depends on SDKGEN-64-001 artifacts and signed releases; manifest format ready. | SDK Release Guild · Export Center Guild | Add `devportal --offline` bundle job packaging docs, specs, SDK artifacts for air-gapped users. |
-
-## Wave Coordination
-- Single wave covering generator and release work; language tracks branch after SDKGEN-62-002.
-
-## Wave Detail Snapshots
-| Wave | Window (UTC) | Scope | Exit criteria | Owners | Status |
-| --- | --- | --- | --- | --- | --- |
-| A: Generator foundation | 2025-11-25 → 2025-12-02 | SDKGEN-62-001..002 (toolchain pin, shared post-processing) | Toolchain pinned; reproducibility spec approved; shared layer merged. | SDK Generator Guild | Planned |
-| B: Language alphas | 2025-12-03 → 2025-12-22 | SDKGEN-63-001..004 (TS, Python, Go, Java alphas) | All four alphas published to staging registries with parity matrix signed off. | SDK Generator Guild | Planned |
-| C: Release & offline | 2025-12-08 → 2025-12-29 | SDKREL-63-001..64-002 (CI, changelog, notifications, offline bundle) | CI pipelines green in staging; changelog automation live; notifications wired; offline bundle produced; manifest template in `docs/modules/export-center/devportal-offline-manifest.md` adopted. | SDK Release Guild · Export Center Guild | Planned |
-
-## Interlocks
+
+## Wave Coordination
+- Single wave covering generator and release work; language tracks branch after SDKGEN-62-002.
+
+## Wave Detail Snapshots
+| Wave | Window (UTC) | Scope | Exit criteria | Owners | Status |
+| --- | --- | --- | --- | --- | --- |
+| A: Generator foundation | 2025-11-25 → 2025-12-02 | SDKGEN-62-001..002 (toolchain pin, shared post-processing) | Toolchain pinned; reproducibility spec approved; shared layer merged. | SDK Generator Guild | Planned |
+| B: Language alphas | 2025-12-03 → 2025-12-22 | SDKGEN-63-001..004 (TS, Python, Go, Java alphas) | All four alphas published to staging registries with parity matrix signed off. | SDK Generator Guild | Planned |
+| C: Release & offline | 2025-12-08 → 2025-12-29 | SDKREL-63-001..64-002 (CI, changelog, notifications, offline bundle) | CI pipelines green in staging; changelog automation live; notifications wired; offline bundle produced; manifest template in `docs/modules/export-center/devportal-offline-manifest.md` adopted. | SDK Release Guild · Export Center Guild | Planned |
+
+## Interlocks
- API governance: APIG0101 outputs for stable schemas; required before Wave A exit.
- Portal contracts: DEVL0101 (auth/session) inform shared post-processing; consume before Wave A design review.
- Devportal/offline: SPRINT_0206_0001_0001_devportal must expose bundle manifest format for SDKREL-64-002.
@@ -52,14 +54,14 @@
- Notifications/Export: Notifications Studio and Export Center pipelines must be live before Wave C release window (tasks 11–12).
- Aggregate OAS freeze: APIG0101 must publish tagged snapshot + SHA (Action #6) to unblock SDKGEN-63-001..004 generation.
- Signing keys: Sovereign crypto key provisioning for npm/PyPI/Maven/Go (Action #7) gates SDKREL-63-001 staging runs.
-
-## Upcoming Checkpoints
+
+## Upcoming Checkpoints
- 2025-12-05: TS alpha staging drop (SDKGEN-63-001) — verify packaging and typed errors (BLOCKED until aggregate OAS freeze).
- 2025-12-15: Multi-language alpha readiness check (SDKGEN-63-002..004) — parity matrix sign-off (BLOCKED until aggregate OAS freeze and Java alpha generation).
- 2025-12-16: Deliver parity matrix and SDK drop to UI/Console data providers (depends on Wave B artifacts).
- 2025-12-22: Release automation demo (SDKREL-63/64) — staging publishes with signatures and offline bundle (BLOCKED until SDKREL-63-001/002 advance).
-
-## Action Tracker
+
+## Action Tracker
| # | Action | Owner | Due (UTC) | Status |
| --- | --- | --- | --- | --- |
| 1 | Confirm registry signing keys and provenance workflow per language | SDK Release Guild | 2025-11-29 | BLOCKED (awaiting sovereign crypto key provisioning; overdue) |
@@ -69,8 +71,8 @@
| 5 | Deliver parity matrix and SDK drop to UI data providers per SPRINT_0209_0001_0001_ui_i | SDK Generator Guild · UI Guild | 2025-12-16 | Open |
| 6 | Request tagged aggregate OpenAPI snapshot + SHA from APIG0101 to unblock Wave B generation | API Governance Guild · SDK Generator Guild | 2025-12-02 | Open |
| 7 | Escalate sovereign crypto key provisioning for npm/PyPI/Maven/Go signing to unblock SDKREL-63-001 | SDK Release Guild · Platform Security | 2025-12-02 | Open |
-
-## Decisions & Risks
+
+## Decisions & Risks
- Toolchain pinned (OpenAPI Generator 7.4.0, JDK 21) and recorded in repo (`TOOLCHAIN.md`, `toolchain.lock.yaml`); downstream tracks must honor lock file for determinism.
- Dependencies on upstream API/portal contracts may delay generator pinning; mitigation: align with APIG0101 / DEVL0101 milestones.
- Release automation requires registry credentials and signing infra; keys still pending (Action Tracker #1 overdue). Mitigation: reuse sovereign crypto enablement (SPRINT_0514_0001_0001_sovereign_crypto_enablement.md) practices, escalate key provisioning by 2025-12-02, and block releases until keys are validated.
@@ -78,33 +80,33 @@
- Shared postprocess helpers copy only when CI sets `STELLA_POSTPROCESS_ROOT` and `STELLA_POSTPROCESS_LANG`; ensure generation jobs export these to keep helpers present in artifacts.
- Aggregate OAS freeze now on critical path for Wave B; request tagged snapshot with SHA (Action #6) by 2025-12-02 to unblock SDKGEN-63-001..004.
- Sprint currently fully blocked: all Delivery Tracker items depend on Actions #6–#7 (OAS snapshot and signing keys). If unresolved by 2025-12-02, push Wave B and downstream checkpoints by ≥1 week.
-
-### Risk Register
-| Risk | Impact | Mitigation | Owner | Status |
-| --- | --- | --- | --- | --- |
+
+### Risk Register
+| Risk | Impact | Mitigation | Owner | Status |
+| --- | --- | --- | --- | --- |
| Upstream APIs change after generator pin | Rework across four SDKs | Freeze spec version before SDKGEN-63-x; gate via API governance sign-off | SDK Generator Guild | Open |
| Aggregate OpenAPI freeze delayed | Wave B and downstream adoption blocked | Track APIG0101 schedule; request interim tagged snapshot with SHA; re-run hash guard once frozen | SDK Generator Guild | Open |
| Registry signing not provisioned | Cannot ship to npm/PyPI/Maven/Go | Coordinate with sovereign crypto enablement; dry-run staging before prod; Action #7 escalation due 2025-12-02 | SDK Release Guild | Open |
| Offline bundle inputs unavailable | Air-gapped delivery slips | Pull docs/specs from devportal cache; coordinate with Export Center; tied to SDKREL-64-002 blocker | SDK Release Guild | Open |
-
-## Execution Log
-| Date (UTC) | Update | Owner |
-| --- | --- | --- |
-| 2025-11-22 | Normalised sprint to standard template; renamed file to `SPRINT_0208_0001_0001_sdk.md`; no status changes. | PM |
-| 2025-11-22 | Added wave plan and dated checkpoints for generator, language alphas, and release/offline tracks. | PM |
-| 2025-11-22 | Added explicit interlocks to CLI/UI/Devportal sprints and new alignment actions. | PM |
-| 2025-11-22 | Added UI parity-matrix delivery action to keep data provider integration on track. | PM |
-| 2025-11-24 | Pinned generator toolchain (OpenAPI Generator CLI 7.4.0, JDK 21), template layout, and reproducibility rules; captured in `src/Sdk/StellaOps.Sdk.Generator/TOOLCHAIN.md` + `toolchain.lock.yaml`. | SDK Generator Guild |
-| 2025-11-24 | Started SDKGEN-62-002: added shared post-process scaffold (`postprocess/`), LF/whitespace normalizer script, and README for language hooks. | SDK Generator Guild |
-| 2025-11-24 | Completed SDKGEN-62-002: postprocess now copies auth/retry/pagination/telemetry helpers for TS/Python/Go/Java, wires TS/Python exports, and adds smoke tests. | SDK Generator Guild |
-| 2025-11-24 | Began SDKGEN-63-001: added TypeScript generator config (`ts/config.yaml`), deterministic driver script (`ts/generate-ts.sh`), and README; waiting on frozen OAS spec to produce alpha artifact. | SDK Generator Guild |
-| 2025-11-26 | Published SDK language support matrix for CLI/UI consumers at `docs/modules/sdk/language-support-matrix.md`; Action #2 closed. | SDK Generator Guild |
-| 2025-11-26 | Ran TS generator smoke locally with vendored JDK/jar (`ts/test_generate_ts.sh`); pass. Blocked until aggregate OpenAPI spec is frozen/published to generate Wave B alpha artifact. | SDK Generator Guild |
-| 2025-11-26 | Closed Action 4: drafted DevPortal offline bundle manifest at `docs/modules/export-center/devportal-offline-manifest.md` to align SDKREL-64-002 with SPRINT_0206. | SDK Release Guild |
-| 2025-11-26 | Added spec hash guard to TS/Python generators (`STELLA_OAS_EXPECTED_SHA256`) and emit `.oas.sha256` for provenance; updated smoke tests and READMEs. | SDK Generator Guild |
-| 2025-11-26 | Scaffolded Go generator (config/script/smoke), enabled hash guard + helper copy via postprocess, and added `.oas.sha256` emission; waiting on frozen OAS for Wave B alpha. | SDK Generator Guild |
-| 2025-11-26 | Scaffolded Java generator (config/script/smoke), added postprocess hook copy into `org.stellaops.sdk`, hash guard + `.oas.sha256`, and vendored-JDK fallback; waiting on frozen OAS for Wave B alpha. | SDK Generator Guild |
-| 2025-11-26 | Marked SDKGEN-63-003/004 BLOCKED pending frozen aggregate OAS digest; scaffolds and smoke tests are ready. | SDK Generator Guild |
+
+## Execution Log
+| Date (UTC) | Update | Owner |
+| --- | --- | --- |
+| 2025-11-22 | Normalised sprint to standard template; renamed file to `SPRINT_0208_0001_0001_sdk.md`; no status changes. | PM |
+| 2025-11-22 | Added wave plan and dated checkpoints for generator, language alphas, and release/offline tracks. | PM |
+| 2025-11-22 | Added explicit interlocks to CLI/UI/Devportal sprints and new alignment actions. | PM |
+| 2025-11-22 | Added UI parity-matrix delivery action to keep data provider integration on track. | PM |
+| 2025-11-24 | Pinned generator toolchain (OpenAPI Generator CLI 7.4.0, JDK 21), template layout, and reproducibility rules; captured in `src/Sdk/StellaOps.Sdk.Generator/TOOLCHAIN.md` + `toolchain.lock.yaml`. | SDK Generator Guild |
+| 2025-11-24 | Started SDKGEN-62-002: added shared post-process scaffold (`postprocess/`), LF/whitespace normalizer script, and README for language hooks. | SDK Generator Guild |
+| 2025-11-24 | Completed SDKGEN-62-002: postprocess now copies auth/retry/pagination/telemetry helpers for TS/Python/Go/Java, wires TS/Python exports, and adds smoke tests. | SDK Generator Guild |
+| 2025-11-24 | Began SDKGEN-63-001: added TypeScript generator config (`ts/config.yaml`), deterministic driver script (`ts/generate-ts.sh`), and README; waiting on frozen OAS spec to produce alpha artifact. | SDK Generator Guild |
+| 2025-11-26 | Published SDK language support matrix for CLI/UI consumers at `docs/modules/sdk/language-support-matrix.md`; Action #2 closed. | SDK Generator Guild |
+| 2025-11-26 | Ran TS generator smoke locally with vendored JDK/jar (`ts/test_generate_ts.sh`); pass. Blocked until aggregate OpenAPI spec is frozen/published to generate Wave B alpha artifact. | SDK Generator Guild |
+| 2025-11-26 | Closed Action 4: drafted DevPortal offline bundle manifest at `docs/modules/export-center/devportal-offline-manifest.md` to align SDKREL-64-002 with SPRINT_0206. | SDK Release Guild |
+| 2025-11-26 | Added spec hash guard to TS/Python generators (`STELLA_OAS_EXPECTED_SHA256`) and emit `.oas.sha256` for provenance; updated smoke tests and READMEs. | SDK Generator Guild |
+| 2025-11-26 | Scaffolded Go generator (config/script/smoke), enabled hash guard + helper copy via postprocess, and added `.oas.sha256` emission; waiting on frozen OAS for Wave B alpha. | SDK Generator Guild |
+| 2025-11-26 | Scaffolded Java generator (config/script/smoke), added postprocess hook copy into `org.stellaops.sdk`, hash guard + `.oas.sha256`, and vendored-JDK fallback; waiting on frozen OAS for Wave B alpha. | SDK Generator Guild |
+| 2025-11-26 | Marked SDKGEN-63-003/004 BLOCKED pending frozen aggregate OAS digest; scaffolds and smoke tests are ready. | SDK Generator Guild |
| 2025-11-26 | Added unified SDK smoke npm scripts (`sdk:smoke:*`, `sdk:smoke`) covering TS/Python/Go/Java to keep pre-alpha checks consistent. | SDK Generator Guild |
| 2025-11-26 | Added CI workflow `.gitea/workflows/sdk-generator.yml` to run `npm run sdk:smoke` on SDK generator changes (TS/Python/Go/Java). | SDK Generator Guild |
| 2025-11-27 | Marked SDKGEN-63-001/002 BLOCKED pending frozen aggregate OAS digest; scaffolds and smokes remain ready. | SDK Generator Guild |
@@ -116,7 +118,7 @@
| 2025-11-24 | Added fixture OpenAPI (`ts/fixtures/ping.yaml`) and smoke test (`ts/test_generate_ts.sh`) to validate TypeScript pipeline locally; skips if generator jar absent. | SDK Generator Guild |
| 2025-11-24 | Vendored `tools/openapi-generator-cli-7.4.0.jar` and `tools/jdk-21.0.1.tar.gz` with SHA recorded in `toolchain.lock.yaml`; adjusted TS script to ensure helper copy post-run and verified generation against fixture. | SDK Generator Guild |
| 2025-11-24 | Ran `ts/test_generate_ts.sh` with vendored JDK/JAR and fixture spec; smoke test passes (helpers present). | SDK Generator Guild |
-| 2025-11-24 | Added deterministic TS packaging templates (package.json, tsconfig base/cjs/esm, README, sdk-error) copied via postprocess; updated helper exports and lock hash. | SDK Generator Guild |
-| 2025-11-24 | Began SDKGEN-63-002: added Python generator config/script/README + smoke test (reuses ping fixture); awaiting frozen OAS to emit alpha. | SDK Generator Guild |
-| 2025-11-27 | Began SDKGEN-63-003: added Go SDK generator scaffold with config (`go/config.yaml`), driver script (`go/generate-go.sh`), smoke test (`go/test_generate_go.sh`), and README; context-first API design documented; awaiting frozen OAS to generate alpha. | SDK Generator Guild |
-| 2025-11-27 | Began SDKGEN-63-004: added Java SDK generator scaffold with config (`java/config.yaml`), driver script (`java/generate-java.sh`), smoke test (`java/test_generate_java.sh`), and README; OkHttp + Gson selected as HTTP client/serialization; builder pattern documented; awaiting frozen OAS to generate alpha. | SDK Generator Guild |
+| 2025-11-24 | Added deterministic TS packaging templates (package.json, tsconfig base/cjs/esm, README, sdk-error) copied via postprocess; updated helper exports and lock hash. | SDK Generator Guild |
+| 2025-11-24 | Began SDKGEN-63-002: added Python generator config/script/README + smoke test (reuses ping fixture); awaiting frozen OAS to emit alpha. | SDK Generator Guild |
+| 2025-11-27 | Began SDKGEN-63-003: added Go SDK generator scaffold with config (`go/config.yaml`), driver script (`go/generate-go.sh`), smoke test (`go/test_generate_go.sh`), and README; context-first API design documented; awaiting frozen OAS to generate alpha. | SDK Generator Guild |
+| 2025-11-27 | Began SDKGEN-63-004: added Java SDK generator scaffold with config (`java/config.yaml`), driver script (`java/generate-java.sh`), smoke test (`java/test_generate_java.sh`), and README; OkHttp + Gson selected as HTTP client/serialization; builder pattern documented; awaiting frozen OAS to generate alpha. | SDK Generator Guild |
diff --git a/docs/implplan/SPRINT_0209_0001_0001_ui_i.md b/docs/implplan/SPRINT_0209_0001_0001_ui_i.md
index 0240bb4ba..739138f08 100644
--- a/docs/implplan/SPRINT_0209_0001_0001_ui_i.md
+++ b/docs/implplan/SPRINT_0209_0001_0001_ui_i.md
@@ -25,6 +25,8 @@
- `docs/15_UI_GUIDE.md`
- `docs/18_CODING_STANDARDS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0210_0001_0002_ui_ii.md b/docs/implplan/SPRINT_0210_0001_0002_ui_ii.md
index 4f390ddb8..d2f896ef4 100644
--- a/docs/implplan/SPRINT_0210_0001_0002_ui_ii.md
+++ b/docs/implplan/SPRINT_0210_0001_0002_ui_ii.md
@@ -25,6 +25,8 @@
- `docs/schemas/audit-bundle-index.schema.json`
- Advisory: "28-Nov-2025 - Vulnerability Triage UX & VEX-First Decisioning.md"
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0211_0001_0003_ui_iii.md b/docs/implplan/SPRINT_0211_0001_0003_ui_iii.md
index 4f9b18e21..db4ac2351 100644
--- a/docs/implplan/SPRINT_0211_0001_0003_ui_iii.md
+++ b/docs/implplan/SPRINT_0211_0001_0003_ui_iii.md
@@ -25,6 +25,8 @@
- `docs/15_UI_GUIDE.md`
- `docs/18_CODING_STANDARDS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0212_0001_0001_web_i.md b/docs/implplan/SPRINT_0212_0001_0001_web_i.md
index 5c022a116..63426dd24 100644
--- a/docs/implplan/SPRINT_0212_0001_0001_web_i.md
+++ b/docs/implplan/SPRINT_0212_0001_0001_web_i.md
@@ -18,6 +18,8 @@
- `docs/api/console/workspaces.md` plus `docs/api/console/samples/` artifacts
- `docs/implplan/archived/tasks.md` for prior completions
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition / Evidence |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0213_0001_0002_web_ii.md b/docs/implplan/SPRINT_0213_0001_0002_web_ii.md
index 6ae76c796..ba68f101d 100644
--- a/docs/implplan/SPRINT_0213_0001_0002_web_ii.md
+++ b/docs/implplan/SPRINT_0213_0001_0002_web_ii.md
@@ -20,6 +20,8 @@
- `docs/modules/export-center/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0214_0001_0001_web_iii.md b/docs/implplan/SPRINT_0214_0001_0001_web_iii.md
index c6f72454e..1bc596870 100644
--- a/docs/implplan/SPRINT_0214_0001_0001_web_iii.md
+++ b/docs/implplan/SPRINT_0214_0001_0001_web_iii.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `src/Web/StellaOps.Web/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0215_0001_0001_vuln_triage_ux.md b/docs/implplan/SPRINT_0215_0001_0001_vuln_triage_ux.md
index dfb76d38e..0f888017f 100644
--- a/docs/implplan/SPRINT_0215_0001_0001_vuln_triage_ux.md
+++ b/docs/implplan/SPRINT_0215_0001_0001_vuln_triage_ux.md
@@ -23,6 +23,8 @@
- `docs/schemas/vex-decision.schema.json`
- `docs/schemas/audit-bundle-index.schema.json`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0215_0001_0001_web_iv.md b/docs/implplan/SPRINT_0215_0001_0001_web_iv.md
index fed24acb2..cc49019c9 100644
--- a/docs/implplan/SPRINT_0215_0001_0001_web_iv.md
+++ b/docs/implplan/SPRINT_0215_0001_0001_web_iv.md
@@ -18,6 +18,8 @@
- `docs/modules/policy/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0216_0001_0001_web_v.md b/docs/implplan/SPRINT_0216_0001_0001_web_v.md
index b95936e64..3926cb825 100644
--- a/docs/implplan/SPRINT_0216_0001_0001_web_v.md
+++ b/docs/implplan/SPRINT_0216_0001_0001_web_v.md
@@ -18,6 +18,8 @@
- `docs/modules/ui/architecture.md`
- `src/Web/StellaOps.Web/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0301_0001_0001_docs_md_i.md b/docs/implplan/SPRINT_0301_0001_0001_docs_md_i.md
index 7ee9223a9..180441abf 100644
--- a/docs/implplan/SPRINT_0301_0001_0001_docs_md_i.md
+++ b/docs/implplan/SPRINT_0301_0001_0001_docs_md_i.md
@@ -18,6 +18,8 @@
- `docs/modules/scanner/architecture.md`
- `docs/modules/airgap/architecture.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Task Board
| Task ID | Status | Owner(s) | Dependencies | Notes |
| --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0313_0001_0001_docs_modules_attestor.md b/docs/implplan/SPRINT_0313_0001_0001_docs_modules_attestor.md
index e35f42ba3..aa59f05a7 100644
--- a/docs/implplan/SPRINT_0313_0001_0001_docs_modules_attestor.md
+++ b/docs/implplan/SPRINT_0313_0001_0001_docs_modules_attestor.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0314_0001_0001_docs_modules_authority.md b/docs/implplan/SPRINT_0314_0001_0001_docs_modules_authority.md
index 7c0ddeb0c..661f8d601 100644
--- a/docs/implplan/SPRINT_0314_0001_0001_docs_modules_authority.md
+++ b/docs/implplan/SPRINT_0314_0001_0001_docs_modules_authority.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0315_0001_0001_docs_modules_ci.md b/docs/implplan/SPRINT_0315_0001_0001_docs_modules_ci.md
index 2ab49c863..5f3d84500 100644
--- a/docs/implplan/SPRINT_0315_0001_0001_docs_modules_ci.md
+++ b/docs/implplan/SPRINT_0315_0001_0001_docs_modules_ci.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
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 b358cfc51..5b3c2acad 100644
--- a/docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md
+++ b/docs/implplan/SPRINT_0316_0001_0001_docs_modules_cli.md
@@ -18,6 +18,8 @@
- docs/modules/platform/architecture-overview.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0317_0001_0001_docs_modules_concelier.md b/docs/implplan/SPRINT_0317_0001_0001_docs_modules_concelier.md
index 20b5462f8..57d1516b1 100644
--- a/docs/implplan/SPRINT_0317_0001_0001_docs_modules_concelier.md
+++ b/docs/implplan/SPRINT_0317_0001_0001_docs_modules_concelier.md
@@ -18,6 +18,8 @@
- docs/modules/platform/architecture-overview.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0320_0001_0001_docs_modules_export_center.md b/docs/implplan/SPRINT_0320_0001_0001_docs_modules_export_center.md
index 29f50c224..b6ae36a47 100644
--- a/docs/implplan/SPRINT_0320_0001_0001_docs_modules_export_center.md
+++ b/docs/implplan/SPRINT_0320_0001_0001_docs_modules_export_center.md
@@ -19,6 +19,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
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 e8ee90a50..c0f2b1f8d 100644
--- a/docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md
+++ b/docs/implplan/SPRINT_0321_0001_0001_docs_modules_graph.md
@@ -17,6 +17,8 @@
- docs/modules/platform/architecture-overview.md
- docs/07_HIGH_LEVEL_ARCHITECTURE.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0323_0001_0001_docs_modules_orchestrator.md b/docs/implplan/SPRINT_0323_0001_0001_docs_modules_orchestrator.md
index 0af9132f8..3d2a7f4f5 100644
--- a/docs/implplan/SPRINT_0323_0001_0001_docs_modules_orchestrator.md
+++ b/docs/implplan/SPRINT_0323_0001_0001_docs_modules_orchestrator.md
@@ -16,6 +16,8 @@
- docs/modules/orchestrator/implementation_plan.md
- docs/modules/platform/architecture-overview.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0324_0001_0001_docs_modules_platform.md b/docs/implplan/SPRINT_0324_0001_0001_docs_modules_platform.md
index 0ff760af1..774b551c4 100644
--- a/docs/implplan/SPRINT_0324_0001_0001_docs_modules_platform.md
+++ b/docs/implplan/SPRINT_0324_0001_0001_docs_modules_platform.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/implementation_plan.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0327_0001_0001_docs_modules_scanner.md b/docs/implplan/SPRINT_0327_0001_0001_docs_modules_scanner.md
index 38bd7497d..214e9e533 100644
--- a/docs/implplan/SPRINT_0327_0001_0001_docs_modules_scanner.md
+++ b/docs/implplan/SPRINT_0327_0001_0001_docs_modules_scanner.md
@@ -16,6 +16,8 @@
- docs/modules/platform/architecture-overview.md
- docs/modules/scanner/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0328_0001_0001_docs_modules_scheduler.md b/docs/implplan/SPRINT_0328_0001_0001_docs_modules_scheduler.md
index 687368aa1..dc0eb5f27 100644
--- a/docs/implplan/SPRINT_0328_0001_0001_docs_modules_scheduler.md
+++ b/docs/implplan/SPRINT_0328_0001_0001_docs_modules_scheduler.md
@@ -16,6 +16,8 @@
- docs/modules/scheduler/implementation_plan.md
- docs/modules/scheduler/AGENTS.md (this sprint refreshes it)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0330_0001_0001_docs_modules_telemetry.md b/docs/implplan/SPRINT_0330_0001_0001_docs_modules_telemetry.md
index c2c07c86c..1d14a85d7 100644
--- a/docs/implplan/SPRINT_0330_0001_0001_docs_modules_telemetry.md
+++ b/docs/implplan/SPRINT_0330_0001_0001_docs_modules_telemetry.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0331_0001_0001_docs_modules_ui.md b/docs/implplan/SPRINT_0331_0001_0001_docs_modules_ui.md
index 8c5b18f69..3cd8fc51d 100644
--- a/docs/implplan/SPRINT_0331_0001_0001_docs_modules_ui.md
+++ b/docs/implplan/SPRINT_0331_0001_0001_docs_modules_ui.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0332_0001_0001_docs_modules_vex_lens.md b/docs/implplan/SPRINT_0332_0001_0001_docs_modules_vex_lens.md
index 230df4e04..4251d62e4 100644
--- a/docs/implplan/SPRINT_0332_0001_0001_docs_modules_vex_lens.md
+++ b/docs/implplan/SPRINT_0332_0001_0001_docs_modules_vex_lens.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0333_0001_0001_docs_modules_excititor.md b/docs/implplan/SPRINT_0333_0001_0001_docs_modules_excititor.md
index f4963ae0a..02ff206b6 100644
--- a/docs/implplan/SPRINT_0333_0001_0001_docs_modules_excititor.md
+++ b/docs/implplan/SPRINT_0333_0001_0001_docs_modules_excititor.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0334_0001_0001_docs_modules_vuln_explorer.md b/docs/implplan/SPRINT_0334_0001_0001_docs_modules_vuln_explorer.md
index e33b42060..def7df761 100644
--- a/docs/implplan/SPRINT_0334_0001_0001_docs_modules_vuln_explorer.md
+++ b/docs/implplan/SPRINT_0334_0001_0001_docs_modules_vuln_explorer.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0335_0001_0001_docs_modules_zastava.md b/docs/implplan/SPRINT_0335_0001_0001_docs_modules_zastava.md
index afe52d53c..3af15150e 100644
--- a/docs/implplan/SPRINT_0335_0001_0001_docs_modules_zastava.md
+++ b/docs/implplan/SPRINT_0335_0001_0001_docs_modules_zastava.md
@@ -18,6 +18,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
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 439e3e199..1801fdc0a 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
@@ -17,6 +17,8 @@
- docs/reachability/function-level-evidence.md
- docs/reachability/DELIVERY_GUIDE.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0401_0001_0001_reachability_evidence_chain.md b/docs/implplan/SPRINT_0401_0001_0001_reachability_evidence_chain.md
index bcfcce4aa..b3d90b2cf 100644
--- a/docs/implplan/SPRINT_0401_0001_0001_reachability_evidence_chain.md
+++ b/docs/implplan/SPRINT_0401_0001_0001_reachability_evidence_chain.md
@@ -30,6 +30,8 @@
- docs/provenance/inline-dsse.md
- docs/ci/dsse-build-flow.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0504_0001_0001_ops_devops_ii.md b/docs/implplan/SPRINT_0504_0001_0001_ops_devops_ii.md
index 95f2bb33e..0a162acec 100644
--- a/docs/implplan/SPRINT_0504_0001_0001_ops_devops_ii.md
+++ b/docs/implplan/SPRINT_0504_0001_0001_ops_devops_ii.md
@@ -15,6 +15,8 @@
- `docs/modules/platform/architecture-overview.md`
- `ops/devops/AGENTS.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0509_0001_0001_samples.md b/docs/implplan/SPRINT_0509_0001_0001_samples.md
index 09cba7dfb..60bc66869 100644
--- a/docs/implplan/SPRINT_0509_0001_0001_samples.md
+++ b/docs/implplan/SPRINT_0509_0001_0001_samples.md
@@ -16,6 +16,8 @@
- docs/modules/concelier/architecture.md (for linkset schema/statuses)
- docs/modules/vuln-explorer/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0510_0001_0001_airgap.md b/docs/implplan/SPRINT_0510_0001_0001_airgap.md
index f422ae38a..2a3ddd13f 100644
--- a/docs/implplan/SPRINT_0510_0001_0001_airgap.md
+++ b/docs/implplan/SPRINT_0510_0001_0001_airgap.md
@@ -15,6 +15,8 @@
- docs/modules/devops/architecture.md
- docs/modules/airgap/airgap-mode.md (if present)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0512_0001_0001_bench.md b/docs/implplan/SPRINT_0512_0001_0001_bench.md
index ab1400edf..f50370bcc 100644
--- a/docs/implplan/SPRINT_0512_0001_0001_bench.md
+++ b/docs/implplan/SPRINT_0512_0001_0001_bench.md
@@ -16,6 +16,8 @@
- docs/modules/signals/architecture.md (for reachability benches)
- docs/modules/policy/architecture.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
@@ -27,9 +29,9 @@
| P6 | PREP-BENCH-SIG-26-002-BLOCKED-ON-26-001-OUTPU | DONE (2025-11-20) | Prep doc at `docs/benchmarks/signals/bench-sig-26-002-prep.md`; depends on 26-001 datasets. | Bench Guild · Policy Guild | Blocked on 26-001 outputs.
Document artefact/deliverable for BENCH-SIG-26-002 and publish location so downstream tasks can proceed. |
| 1 | BENCH-GRAPH-21-001 | DONE (2025-12-02) | PREP-BENCH-GRAPH-21-001-NEED-GRAPH-BENCH-HARN | Bench Guild · Graph Platform Guild | Build graph viewport/path benchmark harness (50k/100k nodes) measuring Graph API/Indexer latency, memory, and tile cache hit rates. |
| 2 | BENCH-GRAPH-21-002 | DONE (2025-12-02) | PREP-BENCH-GRAPH-21-002-BLOCKED-ON-21-001-HAR | Bench Guild · UI Guild | Add headless UI load benchmark (Playwright) for graph canvas interactions to track render times and FPS budgets. |
-| 3 | BENCH-GRAPH-24-002 | BLOCKED | Waiting for 50k/100k graph fixture (SAMPLES-GRAPH-24-003) | Bench Guild · UI Guild | Implement UI interaction benchmarks (filter/zoom/table operations) citing p95 latency; integrate with perf dashboards. |
-| 4 | BENCH-IMPACT-16-001 | BLOCKED | PREP-BENCH-IMPACT-16-001-IMPACT-INDEX-DATASET | Bench Guild · Scheduler Team | ImpactIndex throughput bench (resolve 10k productKeys) + RAM profile. |
-| 5 | BENCH-POLICY-20-002 | BLOCKED | PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE | Bench Guild · Policy Guild · Scheduler Guild | Add incremental run benchmark measuring delta evaluation vs full; capture SLA compliance. |
+| 3 | BENCH-GRAPH-24-002 | BLOCKED | Waiting for 50k/100k graph fixture (SAMPLES-GRAPH-24-003) | Bench Guild · UI Guild | Implement UI interaction benchmarks (filter/zoom/table operations) citing p95 latency; integrate with perf dashboards. |
+| 4 | BENCH-IMPACT-16-001 | BLOCKED | PREP-BENCH-IMPACT-16-001-IMPACT-INDEX-DATASET | Bench Guild · Scheduler Team | ImpactIndex throughput bench (resolve 10k productKeys) + RAM profile. |
+| 5 | BENCH-POLICY-20-002 | BLOCKED | PREP-BENCH-POLICY-20-002-POLICY-DELTA-SAMPLE | Bench Guild · Policy Guild · Scheduler Guild | Add incremental run benchmark measuring delta evaluation vs full; capture SLA compliance. |
| 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. |
| 8 | BENCH-DETERMINISM-401-057 | DONE (2025-11-27) | Feed-freeze hash + SBOM/VEX bundle list from Sprint 0401. | Bench Guild · Signals Guild · Policy Guild (`bench/determinism`, `docs/benchmarks/signals/bench-determinism.md`) | Run cross-scanner determinism bench from 23-Nov advisory; publish determinism% and CVSS delta σ; CI workflow `bench-determinism` runs harness and uploads manifests/results; offline runner added. |
diff --git a/docs/implplan/SPRINT_0513_0001_0001_provenance.md b/docs/implplan/SPRINT_0513_0001_0001_provenance.md
index 695025a2e..8db8b495f 100644
--- a/docs/implplan/SPRINT_0513_0001_0001_provenance.md
+++ b/docs/implplan/SPRINT_0513_0001_0001_provenance.md
@@ -18,6 +18,8 @@
- `docs/modules/orchestrator/architecture.md`
- `docs/modules/export-center/architecture.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_0513_0001_0001_public_reachability_benchmark.md b/docs/implplan/SPRINT_0513_0001_0001_public_reachability_benchmark.md
index 376793cbe..bad80094f 100644
--- a/docs/implplan/SPRINT_0513_0001_0001_public_reachability_benchmark.md
+++ b/docs/implplan/SPRINT_0513_0001_0001_public_reachability_benchmark.md
@@ -23,6 +23,8 @@
- Related advisory: `docs/product-advisories/archived/23-Nov-2025 - Publishing a Reachability Benchmark Dataset.md`
- Existing bench prep docs: `docs/benchmarks/signals/bench-determinism.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
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 eb5d776ae..1e70d410f 100644
--- a/docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md
+++ b/docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md
@@ -1,14 +1,14 @@
-# Sprint 0514 · Ops & Offline · Sovereign Crypto Enablement (190.K)
-
-## Topic & Scope
-- Deliver RootPack_RU-ready sovereign crypto providers (CryptoPro + PKCS#11), configuration knobs, deterministic tests, and repo-wide crypto routing audit.
-- Maintain quarantined fork for GostCryptography/CryptoPro plugin and ensure Authority/Scanner/Attestor route through registry-based providers.
-- **Working directory:** `src/__Libraries/StellaOps.Cryptography*`, `src/Authority`, `src/Scanner`, `src/Attestor`, `third_party/forks/AlexMAS.GostCryptography`.
-
-## Dependencies & Concurrency
-- Authority signing provider contract and JWKS export requirements (blocking AUTH-CRYPTO-90-001).
-- CI runners must support platform-specific CryptoPro/PKCS#11 tests (env/pin gated); may need opt-in pipelines.
-
+# Sprint 0514 · Ops & Offline · Sovereign Crypto Enablement (190.K)
+
+## Topic & Scope
+- Deliver RootPack_RU-ready sovereign crypto providers (CryptoPro + PKCS#11), configuration knobs, deterministic tests, and repo-wide crypto routing audit.
+- Maintain quarantined fork for GostCryptography/CryptoPro plugin and ensure Authority/Scanner/Attestor route through registry-based providers.
+- **Working directory:** `src/__Libraries/StellaOps.Cryptography*`, `src/Authority`, `src/Scanner`, `src/Attestor`, `third_party/forks/AlexMAS.GostCryptography`.
+
+## Dependencies & Concurrency
+- Authority signing provider contract and JWKS export requirements (blocking AUTH-CRYPTO-90-001).
+- CI runners must support platform-specific CryptoPro/PKCS#11 tests (env/pin gated); may need opt-in pipelines.
+
## Documentation Prerequisites
- docs/security/rootpack_ru_*.md
- docs/dev/crypto.md
@@ -16,7 +16,9 @@
- docs/modules/authority/architecture.md (for Authority provider/JWKS contract context)
- docs/modules/scanner/architecture.md (for registry wiring in Scanner WebService/Worker)
- docs/modules/attestor/architecture.md (for attestation hashing/witness flows)
-
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
@@ -30,7 +32,7 @@
| 7 | SEC-CRYPTO-90-013 | BLOCKED (2025-11-27) | After 90-021 (blocked). | Security Guild | Add Magma/Kuznyechik symmetric support via provider registry. |
| 8 | SEC-CRYPTO-90-014 | BLOCKED | Authority provider/JWKS contract pending (R1) | 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 | DONE (2025-11-26) | After 90-012/021 | Security & Docs Guild | Refresh RootPack/validation documentation. |
-| 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. |
+| 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 | BLOCKED (2025-11-27) | Await Authority provider/JWKS contract + registry option design (R1/R3) | Scanner WebService Guild · Security Guild | Route hashing/signing flows through `ICryptoProviderRegistry`. |
| 12 | SCANNER-WORKER-CRYPTO-90-001 | BLOCKED (2025-11-27) | After 11 (registry contract pending) | Scanner Worker Guild · Security Guild | Wire Scanner Worker/BuildX analyzers to registry/hash abstractions. |
| 13 | SCANNER-CRYPTO-90-002 | BLOCKED (2025-11-30) | Blocked by R1/R3: registry/provider contract (Authority) and PQ option mapping not finalized in runtime hosts. Design doc exists (`docs/security/pq-provider-options.md`). | Scanner WebService Guild · Security Guild | Enable PQ-friendly DSSE (Dilithium/Falcon) via provider options. |
diff --git a/docs/implplan/SPRINT_120_excititor_ii.md b/docs/implplan/SPRINT_120_excititor_ii.md
index e7ded94e5..bf1994746 100644
--- a/docs/implplan/SPRINT_120_excititor_ii.md
+++ b/docs/implplan/SPRINT_120_excititor_ii.md
@@ -1,5 +1,7 @@
# Legacy Sprint Filename (redirect)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
The Excititor Ingestion & Evidence phase II sprint was normalized on 2025-11-16 and now lives at `docs/implplan/SPRINT_0119_0001_0002_excititor_ii.md`.
This legacy file remains only as a pointer for bookmarks. All updates, task status changes, execution logs, and decisions must be recorded in the normalized sprint file.
diff --git a/docs/implplan/SPRINT_121_excititor_iii.md b/docs/implplan/SPRINT_121_excititor_iii.md
index c4d6b0a62..da15bac5f 100644
--- a/docs/implplan/SPRINT_121_excititor_iii.md
+++ b/docs/implplan/SPRINT_121_excititor_iii.md
@@ -15,6 +15,8 @@
- docs/modules/excititor/implementation_plan.md
- Component AGENTS.md under `src/Excititor/**`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_122_excititor_iv.md b/docs/implplan/SPRINT_122_excititor_iv.md
index 99cc312f9..ad1a4b112 100644
--- a/docs/implplan/SPRINT_122_excititor_iv.md
+++ b/docs/implplan/SPRINT_122_excititor_iv.md
@@ -16,6 +16,8 @@
- Excititor component `AGENTS.md` (Core, WebService, Worker)
- `docs/ingestion/aggregation-only-contract.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_123_excititor_v.md b/docs/implplan/SPRINT_123_excititor_v.md
index 2144fe039..28f80d816 100644
--- a/docs/implplan/SPRINT_123_excititor_v.md
+++ b/docs/implplan/SPRINT_123_excititor_v.md
@@ -15,6 +15,8 @@
- docs/airgap/portable-evidence-bundle-verification.md
- Excititor AGENTS.md files (WebService, Core, Storage)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_123_policy_reasoning.md b/docs/implplan/SPRINT_123_policy_reasoning.md
index 1403a3416..df2059af9 100644
--- a/docs/implplan/SPRINT_123_policy_reasoning.md
+++ b/docs/implplan/SPRINT_123_policy_reasoning.md
@@ -1,5 +1,7 @@
# Sprint 123 - Policy & Reasoning
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
_Last updated: November 8, 2025. Implementation order is DOING → TODO → BLOCKED._
Focus areas below were split out of the previous combined sprint; execute sections in order unless noted.
diff --git a/docs/implplan/SPRINT_124_excititor_vi.md b/docs/implplan/SPRINT_124_excititor_vi.md
index 4653b00ee..572032ae7 100644
--- a/docs/implplan/SPRINT_124_excititor_vi.md
+++ b/docs/implplan/SPRINT_124_excititor_vi.md
@@ -15,6 +15,8 @@
- docs/modules/excititor/observability/locker-manifest.md
- Excititor WebService AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_125_policy_reasoning.md b/docs/implplan/SPRINT_125_policy_reasoning.md
index 13eb286fe..60aefd5cf 100644
--- a/docs/implplan/SPRINT_125_policy_reasoning.md
+++ b/docs/implplan/SPRINT_125_policy_reasoning.md
@@ -1,5 +1,7 @@
# Sprint 125 - Policy & Reasoning
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
_Last updated: November 8, 2025. Implementation order is DOING → TODO → BLOCKED._
Focus areas below were split out of the previous combined sprint; execute sections in order unless noted.
diff --git a/docs/implplan/SPRINT_126_policy_reasoning.md b/docs/implplan/SPRINT_126_policy_reasoning.md
index 1d01cd26d..49463297c 100644
--- a/docs/implplan/SPRINT_126_policy_reasoning.md
+++ b/docs/implplan/SPRINT_126_policy_reasoning.md
@@ -1,5 +1,7 @@
# Sprint 126 - Policy & Reasoning
> Superseded by `docs/implplan/SPRINT_0126_0001_0001_policy_reasoning.md`; maintained for historical context only.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
_Last updated: November 8, 2025. Implementation order is DOING → TODO → BLOCKED._
diff --git a/docs/implplan/SPRINT_127_policy_reasoning.md b/docs/implplan/SPRINT_127_policy_reasoning.md
index a57ccbfbd..e566d343c 100644
--- a/docs/implplan/SPRINT_127_policy_reasoning.md
+++ b/docs/implplan/SPRINT_127_policy_reasoning.md
@@ -1,5 +1,7 @@
# Sprint 127 - Policy & Reasoning
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
_Last updated: November 27, 2025. Implementation order is DOING → TODO → BLOCKED._
Focus areas below were split out of the previous combined sprint; execute sections in order unless noted.
diff --git a/docs/implplan/SPRINT_128_policy_reasoning.md b/docs/implplan/SPRINT_128_policy_reasoning.md
index 2f76b92a9..62e74adc0 100644
--- a/docs/implplan/SPRINT_128_policy_reasoning.md
+++ b/docs/implplan/SPRINT_128_policy_reasoning.md
@@ -1,5 +1,7 @@
# Sprint 128 - Policy & Reasoning
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
_Last updated: November 8, 2025. Implementation order is DOING → TODO → BLOCKED._
Focus areas below were split out of the previous combined sprint; execute sections in order unless noted.
diff --git a/docs/implplan/SPRINT_132_scanner_surface.md b/docs/implplan/SPRINT_132_scanner_surface.md
index 549d2cc65..de3675bcf 100644
--- a/docs/implplan/SPRINT_132_scanner_surface.md
+++ b/docs/implplan/SPRINT_132_scanner_surface.md
@@ -14,6 +14,8 @@
- docs/modules/platform/architecture-overview.md
- src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_133_scanner_surface.md b/docs/implplan/SPRINT_133_scanner_surface.md
index 10e52de02..5c9f5375c 100644
--- a/docs/implplan/SPRINT_133_scanner_surface.md
+++ b/docs/implplan/SPRINT_133_scanner_surface.md
@@ -1,5 +1,7 @@
# Sprint 133 - Scanner & Surface
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Implementation order remains sequential across Sprint 130–139. Complete each sprint in order before pulling tasks from the next file.
## 4. Scanner.IV — Scanner & Surface focus on Scanner (phase IV).
diff --git a/docs/implplan/SPRINT_134_scanner_surface.md b/docs/implplan/SPRINT_134_scanner_surface.md
index c4ba1da8d..97c23bf63 100644
--- a/docs/implplan/SPRINT_134_scanner_surface.md
+++ b/docs/implplan/SPRINT_134_scanner_surface.md
@@ -1,5 +1,7 @@
# Sprint 134 - Scanner & Surface
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Implementation order remains sequential across Sprint 130–139. Complete each sprint in order before pulling tasks from the next file.
## 5. Scanner.V — Scanner & Surface focus on Scanner (phase V).
diff --git a/docs/implplan/SPRINT_135_scanner_surface.md b/docs/implplan/SPRINT_135_scanner_surface.md
index 118c139da..fe9ff18c8 100644
--- a/docs/implplan/SPRINT_135_scanner_surface.md
+++ b/docs/implplan/SPRINT_135_scanner_surface.md
@@ -1,5 +1,7 @@
# Redirect · Sprint 0135 · Scanner & Surface (Phase VI)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This legacy filename is retained only as a pointer. The authoritative sprint doc is `SPRINT_0135_0001_0001_scanner_surface.md`.
- Please update task state and execution logs in `docs/implplan/SPRINT_0135_0001_0001_scanner_surface.md`.
diff --git a/docs/implplan/SPRINT_136_scanner_surface.md b/docs/implplan/SPRINT_136_scanner_surface.md
index 17ef0896b..1b8cfdb28 100644
--- a/docs/implplan/SPRINT_136_scanner_surface.md
+++ b/docs/implplan/SPRINT_136_scanner_surface.md
@@ -1,3 +1,5 @@
# Legacy sprint file (redirect)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was renamed to `SPRINT_0136_0001_0001_scanner_surface.md` on 2025-11-19 to comply with the standard filename template. Please update and read the canonical file instead.
diff --git a/docs/implplan/SPRINT_144_zastava.md b/docs/implplan/SPRINT_144_zastava.md
index bbb225afc..1d406c0cf 100644
--- a/docs/implplan/SPRINT_144_zastava.md
+++ b/docs/implplan/SPRINT_144_zastava.md
@@ -1,5 +1,7 @@
# Sprint 144 - Runtime & Signals · 140.D) Zastava
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Runtime & Signals] 140.D) Zastava
diff --git a/docs/implplan/SPRINT_150_scheduling_automation.md b/docs/implplan/SPRINT_150_scheduling_automation.md
index 4662b3679..40d5d3fd0 100644
--- a/docs/implplan/SPRINT_150_scheduling_automation.md
+++ b/docs/implplan/SPRINT_150_scheduling_automation.md
@@ -1,5 +1,7 @@
# Sprint 150 - Scheduling & Automation
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
This file now only tracks the scheduling & automation status snapshot. Active backlog lives in Sprint 151+ files.
diff --git a/docs/implplan/SPRINT_152_orchestrator_ii.md b/docs/implplan/SPRINT_152_orchestrator_ii.md
index 82f728658..6fe7fd28e 100644
--- a/docs/implplan/SPRINT_152_orchestrator_ii.md
+++ b/docs/implplan/SPRINT_152_orchestrator_ii.md
@@ -1,5 +1,7 @@
# Moved: Sprint 0152-0001-0002 · Orchestrator II (Scheduling & Automation)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This legacy filename is retained to avoid broken references. The canonical sprint now lives at `docs/implplan/SPRINT_0152_0001_0002_orchestrator_ii.md` following the standard naming/template. Do not edit tasks here; update the canonical file only.
Status recap (read-only): All ORCH-SVC-32/33/34/35/36/37 tasks are DONE in the canonical sprint document.
diff --git a/docs/implplan/SPRINT_154_packsregistry.md b/docs/implplan/SPRINT_154_packsregistry.md
index 81be6cf1b..951e51756 100644
--- a/docs/implplan/SPRINT_154_packsregistry.md
+++ b/docs/implplan/SPRINT_154_packsregistry.md
@@ -1,5 +1,7 @@
# Legacy redirect — Sprint 0154 Packs Registry
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was renamed to `SPRINT_0154_0001_0001_packsregistry.md` on 2025-11-19 to match the standard format.
Please update the canonical file instead:
diff --git a/docs/implplan/SPRINT_157_taskrunner_i.md b/docs/implplan/SPRINT_157_taskrunner_i.md
index d49db8d68..40b8565a3 100644
--- a/docs/implplan/SPRINT_157_taskrunner_i.md
+++ b/docs/implplan/SPRINT_157_taskrunner_i.md
@@ -1,4 +1,6 @@
# Deprecated Sprint File
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was normalized and renamed to `docs/implplan/SPRINT_0157_0001_0001_taskrunner_i.md`.
Please update only the canonical file; this stub remains to prevent divergent edits. (Updated 2025-11-30.)
diff --git a/docs/implplan/SPRINT_158_taskrunner_ii.md b/docs/implplan/SPRINT_158_taskrunner_ii.md
index 9ca0ba422..2669c7840 100644
--- a/docs/implplan/SPRINT_158_taskrunner_ii.md
+++ b/docs/implplan/SPRINT_158_taskrunner_ii.md
@@ -1,5 +1,7 @@
# Redirect Notice · Sprint 158
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was normalized and renamed to `docs/implplan/SPRINT_0158_0001_0002_taskrunner_ii.md` (2025-11-19).
Please edit the canonical file only. This legacy filename is retained to prevent divergent updates.
diff --git a/docs/implplan/SPRINT_164_exportcenter_iii.md b/docs/implplan/SPRINT_164_exportcenter_iii.md
index d8008b7bc..be6da98e7 100644
--- a/docs/implplan/SPRINT_164_exportcenter_iii.md
+++ b/docs/implplan/SPRINT_164_exportcenter_iii.md
@@ -1,3 +1,5 @@
# Deprecated alias
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Sprint file was renamed to `SPRINT_0164_0001_0001_exportcenter_iii.md` for template compliance on 2025-11-19. Do not edit this file; update the canonical sprint instead.
diff --git a/docs/implplan/SPRINT_165_timelineindexer.md b/docs/implplan/SPRINT_165_timelineindexer.md
index 6a2f1a993..8765ae56e 100644
--- a/docs/implplan/SPRINT_165_timelineindexer.md
+++ b/docs/implplan/SPRINT_165_timelineindexer.md
@@ -1,3 +1,5 @@
# Legacy sprint file (redirect)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was renamed to `SPRINT_0165_0001_0001_timelineindexer.md` on 2025-11-19 to meet the standard filename template. Please consult the canonical file for all updates.
diff --git a/docs/implplan/SPRINT_170_notifications_telemetry.md b/docs/implplan/SPRINT_170_notifications_telemetry.md
index d6a69c160..1c5fbbeb0 100644
--- a/docs/implplan/SPRINT_170_notifications_telemetry.md
+++ b/docs/implplan/SPRINT_170_notifications_telemetry.md
@@ -1,5 +1,7 @@
# Sprint 170 - Notifications & Telemetry
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
This file now only tracks the notifications & telemetry status snapshot. Active backlog lives in Sprint 171+ files.
diff --git a/docs/implplan/SPRINT_171_notifier_i.md b/docs/implplan/SPRINT_171_notifier_i.md
index c7c3d8e65..e88c0be5c 100644
--- a/docs/implplan/SPRINT_171_notifier_i.md
+++ b/docs/implplan/SPRINT_171_notifier_i.md
@@ -1,5 +1,7 @@
# Sprint 171 - Notifications & Telemetry · 170.A) Notifier.I
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Notifications & Telemetry] 170.A) Notifier.I
diff --git a/docs/implplan/SPRINT_172_notifier_ii.md b/docs/implplan/SPRINT_172_notifier_ii.md
index fd96fd873..53ede7f36 100644
--- a/docs/implplan/SPRINT_172_notifier_ii.md
+++ b/docs/implplan/SPRINT_172_notifier_ii.md
@@ -1,5 +1,7 @@
# Sprint 172 - Notifications & Telemetry · 170.A) Notifier.II
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Notifications & Telemetry] 170.A) Notifier.II
diff --git a/docs/implplan/SPRINT_173_notifier_iii.md b/docs/implplan/SPRINT_173_notifier_iii.md
index 1bce32b3b..12656f359 100644
--- a/docs/implplan/SPRINT_173_notifier_iii.md
+++ b/docs/implplan/SPRINT_173_notifier_iii.md
@@ -1,5 +1,7 @@
# Sprint 173 - Notifications & Telemetry · 170.A) Notifier.III
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Notifications & Telemetry] 170.A) Notifier.III
diff --git a/docs/implplan/SPRINT_174_telemetry.md b/docs/implplan/SPRINT_174_telemetry.md
index 0e72a63dc..9bb8ce6f7 100644
--- a/docs/implplan/SPRINT_174_telemetry.md
+++ b/docs/implplan/SPRINT_174_telemetry.md
@@ -1,5 +1,7 @@
# Sprint 174 - Notifications & Telemetry · 170.B) Telemetry
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Notifications & Telemetry] 170.B) Telemetry
diff --git a/docs/implplan/SPRINT_185_shared_replay_primitives.md b/docs/implplan/SPRINT_185_shared_replay_primitives.md
index f2afeaf79..63824023e 100644
--- a/docs/implplan/SPRINT_185_shared_replay_primitives.md
+++ b/docs/implplan/SPRINT_185_shared_replay_primitives.md
@@ -1,5 +1,7 @@
# Sprint 185 - Replay Core · 185.A) Shared Replay Primitives
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
[Replay Core] 185.A) Shared Replay Primitives
Depends on: Sprint 160 Export & Evidence
Summary: Stand up a shared replay library, hashing/cononicalisation helpers, and baseline documentation for deterministic bundles.
diff --git a/docs/implplan/SPRINT_186_record_deterministic_execution.md b/docs/implplan/SPRINT_186_record_deterministic_execution.md
index 4ad2faf71..4434595d8 100644
--- a/docs/implplan/SPRINT_186_record_deterministic_execution.md
+++ b/docs/implplan/SPRINT_186_record_deterministic_execution.md
@@ -1,3 +1,5 @@
# Legacy Redirect
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint file was renamed to `SPRINT_0186_0001_0001_record_deterministic_execution.md` on 2025-11-19 to comply with the standard template and naming rules. Do not edit this legacy copy; update the canonical file instead.
diff --git a/docs/implplan/SPRINT_187_evidence_locker_cli_integration.md b/docs/implplan/SPRINT_187_evidence_locker_cli_integration.md
index b87b28985..c4a1aa180 100644
--- a/docs/implplan/SPRINT_187_evidence_locker_cli_integration.md
+++ b/docs/implplan/SPRINT_187_evidence_locker_cli_integration.md
@@ -19,6 +19,8 @@
- docs/modules/attestor/architecture.md
- docs/replay/DETERMINISTIC_REPLAY.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_200_experience_sdks.md b/docs/implplan/SPRINT_200_experience_sdks.md
index 6d93e61b2..7ded5f416 100644
--- a/docs/implplan/SPRINT_200_experience_sdks.md
+++ b/docs/implplan/SPRINT_200_experience_sdks.md
@@ -1,5 +1,7 @@
# Redirect Notice · Sprint 200
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was normalized and renamed to `docs/implplan/SPRINT_0200_0001_0001_experience_sdks.md` (2025-11-30).
Please edit the canonical file only. This legacy filename is retained to prevent divergent updates.
diff --git a/docs/implplan/SPRINT_202_cli_ii.md b/docs/implplan/SPRINT_202_cli_ii.md
index 40b2cba63..7c73cc781 100644
--- a/docs/implplan/SPRINT_202_cli_ii.md
+++ b/docs/implplan/SPRINT_202_cli_ii.md
@@ -1,5 +1,7 @@
# Redirect Notice · Sprint 202
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was normalized and renamed to `docs/implplan/SPRINT_0202_0001_0001_cli_ii.md` (2025-11-30).
Please edit the canonical file only. This legacy filename is retained to prevent divergent updates.
diff --git a/docs/implplan/SPRINT_203_cli_iii.md b/docs/implplan/SPRINT_203_cli_iii.md
index 5e1fc11f4..cdb941803 100644
--- a/docs/implplan/SPRINT_203_cli_iii.md
+++ b/docs/implplan/SPRINT_203_cli_iii.md
@@ -1,5 +1,7 @@
# Sprint 203 - Experience & SDKs · 180.A) Cli.III
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.A) Cli.III
diff --git a/docs/implplan/SPRINT_204_cli_iv.md b/docs/implplan/SPRINT_204_cli_iv.md
index c2be47791..7bf01e1e1 100644
--- a/docs/implplan/SPRINT_204_cli_iv.md
+++ b/docs/implplan/SPRINT_204_cli_iv.md
@@ -1,5 +1,7 @@
# Sprint 204 - Experience & SDKs · 180.A) Cli.IV
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.A) Cli.IV
diff --git a/docs/implplan/SPRINT_205_cli_v.md b/docs/implplan/SPRINT_205_cli_v.md
index 25dd9748e..a91fe245a 100644
--- a/docs/implplan/SPRINT_205_cli_v.md
+++ b/docs/implplan/SPRINT_205_cli_v.md
@@ -1,5 +1,7 @@
# Sprint 205 - Experience & SDKs · 180.A) Cli.V
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Experience & SDKs] 180.A) Cli.V
diff --git a/docs/implplan/SPRINT_215_web_iv.md b/docs/implplan/SPRINT_215_web_iv.md
index e19f25aa4..cb8b643c9 100644
--- a/docs/implplan/SPRINT_215_web_iv.md
+++ b/docs/implplan/SPRINT_215_web_iv.md
@@ -1,3 +1,5 @@
# Sprint 215 Web IV (legacy file)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
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 057e6c38f..87be5d9d0 100644
--- a/docs/implplan/SPRINT_300_documentation_process.md
+++ b/docs/implplan/SPRINT_300_documentation_process.md
@@ -13,6 +13,8 @@
- `docs/modules/platform/architecture-overview.md`
- `docs/README.md`
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Task Board
| Stream | Status | Owner(s) | Dependencies | Notes |
| --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_303_docs_tasks_md_iii.md b/docs/implplan/SPRINT_303_docs_tasks_md_iii.md
index be01c7d48..ff79a4bf1 100644
--- a/docs/implplan/SPRINT_303_docs_tasks_md_iii.md
+++ b/docs/implplan/SPRINT_303_docs_tasks_md_iii.md
@@ -1,5 +1,7 @@
# Sprint 303 - Documentation & Process · 200.A) Docs Tasks.Md.III
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.III
diff --git a/docs/implplan/SPRINT_304_docs_tasks_md_iv.md b/docs/implplan/SPRINT_304_docs_tasks_md_iv.md
index 2545fe83b..dd1107af2 100644
--- a/docs/implplan/SPRINT_304_docs_tasks_md_iv.md
+++ b/docs/implplan/SPRINT_304_docs_tasks_md_iv.md
@@ -17,6 +17,8 @@ Active items only. Completed/historic work now resides in `docs/implplan/archive
- Module dossiers: `docs/modules/export-center/architecture.md`, `docs/modules/attestor/architecture.md`, `docs/modules/signer/architecture.md`, `docs/modules/telemetry/architecture.md`, `docs/modules/ui/architecture.md` (graph UI tasks).
- Sprint template rules in `docs/implplan/AGENTS.md`.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
diff --git a/docs/implplan/SPRINT_305_docs_tasks_md_v.md b/docs/implplan/SPRINT_305_docs_tasks_md_v.md
index 5f71dbea4..61e613490 100644
--- a/docs/implplan/SPRINT_305_docs_tasks_md_v.md
+++ b/docs/implplan/SPRINT_305_docs_tasks_md_v.md
@@ -1,5 +1,7 @@
# Sprint 305 - Documentation & Process · 200.A) Docs Tasks.Md.V
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.V
diff --git a/docs/implplan/SPRINT_306_docs_tasks_md_vi.md b/docs/implplan/SPRINT_306_docs_tasks_md_vi.md
index d6e2f9ff6..b45c22720 100644
--- a/docs/implplan/SPRINT_306_docs_tasks_md_vi.md
+++ b/docs/implplan/SPRINT_306_docs_tasks_md_vi.md
@@ -1,5 +1,7 @@
# Sprint 306 - Documentation & Process · 200.A) Docs Tasks.Md.VI
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.VI
diff --git a/docs/implplan/SPRINT_307_docs_tasks_md_vii.md b/docs/implplan/SPRINT_307_docs_tasks_md_vii.md
index 580b624d2..126ac5cf1 100644
--- a/docs/implplan/SPRINT_307_docs_tasks_md_vii.md
+++ b/docs/implplan/SPRINT_307_docs_tasks_md_vii.md
@@ -1,5 +1,7 @@
# Sprint 307 - Documentation & Process · 200.A) Docs Tasks.Md.VII
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.VII
diff --git a/docs/implplan/SPRINT_308_docs_tasks_md_viii.md b/docs/implplan/SPRINT_308_docs_tasks_md_viii.md
index c1db6f88f..4f12c0880 100644
--- a/docs/implplan/SPRINT_308_docs_tasks_md_viii.md
+++ b/docs/implplan/SPRINT_308_docs_tasks_md_viii.md
@@ -1,5 +1,7 @@
# Sprint 308 - Documentation & Process · 200.A) Docs Tasks.Md.VIII
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.VIII
diff --git a/docs/implplan/SPRINT_309_docs_tasks_md_ix.md b/docs/implplan/SPRINT_309_docs_tasks_md_ix.md
index 0b1f0a8b7..81bf0996f 100644
--- a/docs/implplan/SPRINT_309_docs_tasks_md_ix.md
+++ b/docs/implplan/SPRINT_309_docs_tasks_md_ix.md
@@ -1,5 +1,7 @@
# Sprint 309 - Documentation & Process · 200.A) Docs Tasks.Md.IX
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.IX
diff --git a/docs/implplan/SPRINT_310_docs_tasks_md_x.md b/docs/implplan/SPRINT_310_docs_tasks_md_x.md
index 1a507f31d..746f540b0 100644
--- a/docs/implplan/SPRINT_310_docs_tasks_md_x.md
+++ b/docs/implplan/SPRINT_310_docs_tasks_md_x.md
@@ -1,5 +1,7 @@
# Sprint 310 - Documentation & Process · 200.A) Docs Tasks.Md.X
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.X
diff --git a/docs/implplan/SPRINT_311_docs_tasks_md_xi.md b/docs/implplan/SPRINT_311_docs_tasks_md_xi.md
index 76459daee..cdf94674a 100644
--- a/docs/implplan/SPRINT_311_docs_tasks_md_xi.md
+++ b/docs/implplan/SPRINT_311_docs_tasks_md_xi.md
@@ -1,5 +1,7 @@
# Sprint 311 - Documentation & Process · 200.A) Docs Tasks.Md.XI
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.A) Docs Tasks.Md.XI
diff --git a/docs/implplan/SPRINT_312_docs_modules_advisory_ai.md b/docs/implplan/SPRINT_312_docs_modules_advisory_ai.md
index ea34c9db4..88a709130 100644
--- a/docs/implplan/SPRINT_312_docs_modules_advisory_ai.md
+++ b/docs/implplan/SPRINT_312_docs_modules_advisory_ai.md
@@ -1,5 +1,7 @@
# Sprint 312 - Documentation & Process · 200.B) Docs Modules Advisory Ai
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.B) Docs Modules Advisory Ai
diff --git a/docs/implplan/SPRINT_313_docs_modules_attestor.md b/docs/implplan/SPRINT_313_docs_modules_attestor.md
index 47c96bf2b..be6098258 100644
--- a/docs/implplan/SPRINT_313_docs_modules_attestor.md
+++ b/docs/implplan/SPRINT_313_docs_modules_attestor.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0313_0001_0001_docs_modules_attestor.md` to comply with the standard template. Update any bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_314_docs_modules_authority.md b/docs/implplan/SPRINT_314_docs_modules_authority.md
index 1baebc7c7..2d83e8d9a 100644
--- a/docs/implplan/SPRINT_314_docs_modules_authority.md
+++ b/docs/implplan/SPRINT_314_docs_modules_authority.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0314_0001_0001_docs_modules_authority.md` to comply with the standard template. Update any bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_315_docs_modules_ci.md b/docs/implplan/SPRINT_315_docs_modules_ci.md
index cb7d828c7..f09bcaefc 100644
--- a/docs/implplan/SPRINT_315_docs_modules_ci.md
+++ b/docs/implplan/SPRINT_315_docs_modules_ci.md
@@ -1,3 +1,5 @@
# Moved
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint was renamed for template compliance. Please use `docs/implplan/SPRINT_0315_0001_0001_docs_modules_ci.md`.
diff --git a/docs/implplan/SPRINT_318_docs_modules_devops.md b/docs/implplan/SPRINT_318_docs_modules_devops.md
index 93caabe77..9bea8afa0 100644
--- a/docs/implplan/SPRINT_318_docs_modules_devops.md
+++ b/docs/implplan/SPRINT_318_docs_modules_devops.md
@@ -1,5 +1,7 @@
# Sprint 318 - Documentation & Process · 200.H) Docs Modules Devops
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.H) Docs Modules Devops
diff --git a/docs/implplan/SPRINT_319_docs_modules_excititor.md b/docs/implplan/SPRINT_319_docs_modules_excititor.md
index 3a2f9b4a3..36954dd36 100644
--- a/docs/implplan/SPRINT_319_docs_modules_excititor.md
+++ b/docs/implplan/SPRINT_319_docs_modules_excititor.md
@@ -1,5 +1,7 @@
# Sprint 319 - Documentation & Process · 200.I) Docs Modules Excititor
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.I) Docs Modules Excititor
diff --git a/docs/implplan/SPRINT_320_docs_modules_export_center.md b/docs/implplan/SPRINT_320_docs_modules_export_center.md
index 361365dd6..a09f13a14 100644
--- a/docs/implplan/SPRINT_320_docs_modules_export_center.md
+++ b/docs/implplan/SPRINT_320_docs_modules_export_center.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0320_0001_0001_docs_modules_export_center.md` to comply with the standard template. Update any bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_322_docs_modules_notify.md b/docs/implplan/SPRINT_322_docs_modules_notify.md
index 7f528614a..05b07273d 100644
--- a/docs/implplan/SPRINT_322_docs_modules_notify.md
+++ b/docs/implplan/SPRINT_322_docs_modules_notify.md
@@ -1,5 +1,7 @@
# Sprint 322 - Documentation & Process · 200.L) Docs Modules Notify
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.L) Docs Modules Notify
diff --git a/docs/implplan/SPRINT_324_docs_modules_platform.md b/docs/implplan/SPRINT_324_docs_modules_platform.md
index b9e1f5b67..7a7d1bf2c 100644
--- a/docs/implplan/SPRINT_324_docs_modules_platform.md
+++ b/docs/implplan/SPRINT_324_docs_modules_platform.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0324_0001_0001_docs_modules_platform.md` to comply with the standard template. Update any bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_325_docs_modules_policy.md b/docs/implplan/SPRINT_325_docs_modules_policy.md
index b5db96b9c..c58418cae 100644
--- a/docs/implplan/SPRINT_325_docs_modules_policy.md
+++ b/docs/implplan/SPRINT_325_docs_modules_policy.md
@@ -1,5 +1,7 @@
# Sprint 325 - Documentation & Process · 200.O) Docs Modules Policy
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.O) Docs Modules Policy
diff --git a/docs/implplan/SPRINT_326_docs_modules_registry.md b/docs/implplan/SPRINT_326_docs_modules_registry.md
index 073da2e6e..981ce7718 100644
--- a/docs/implplan/SPRINT_326_docs_modules_registry.md
+++ b/docs/implplan/SPRINT_326_docs_modules_registry.md
@@ -1,5 +1,7 @@
# Sprint 326 - Documentation & Process · 200.P) Docs Modules Registry
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
[Documentation & Process] 200.P) Docs Modules Registry
diff --git a/docs/implplan/SPRINT_327_docs_modules_scanner.md b/docs/implplan/SPRINT_327_docs_modules_scanner.md
index 9d5d28d8b..685be58d7 100644
--- a/docs/implplan/SPRINT_327_docs_modules_scanner.md
+++ b/docs/implplan/SPRINT_327_docs_modules_scanner.md
@@ -1,3 +1,5 @@
# Redirect
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint file was renamed to `SPRINT_0327_0001_0001_docs_modules_scanner.md` to comply with naming rules. Please edit the canonical file.
diff --git a/docs/implplan/SPRINT_329_docs_modules_signer.md b/docs/implplan/SPRINT_329_docs_modules_signer.md
index cd2ba20f4..a93c6c035 100644
--- a/docs/implplan/SPRINT_329_docs_modules_signer.md
+++ b/docs/implplan/SPRINT_329_docs_modules_signer.md
@@ -1,13 +1,15 @@
-# Sprint 329 - Documentation & Process · 200.S) Docs Modules Signer
-
-Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
-
-[Documentation & Process] 200.S) Docs Modules Signer
-Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - AirGap, Sprint 130.A - Scanner, Sprint 140.A - Graph, Sprint 150.A - Orchestrator, Sprint 160.A - EvidenceLocker, Sprint 170.A - Notifier, Sprint 180.A - Cli, Sprint 190.A - Ops Deployment
-Summary: Documentation & Process focus on Docs Modules Signer).
-Task ID | State | Task description | Owners (Source)
---- | --- | --- | ---
-SIGNER-DOCS-0001 | DONE (2025-11-05) | Validate that `docs/modules/signer/README.md` captures the latest DSSE/fulcio updates. | Docs Guild (docs/modules/signer)
-SIGNER-OPS-0001 | TODO | Review signer runbooks/observability assets after next sprint demo. | Ops Guild (docs/modules/signer)
-SIGNER-ENG-0001 | DONE (2025-11-27) | Keep module milestones aligned with signer sprints under `/docs/implplan`. Added Sprint Readiness Tracker to `docs/modules/signer/implementation_plan.md` mapping 4 phases to 17+ sprint tasks across Sprints 100, 186, 401, 513, 514. Updated README with Sprint 0186/0401 completed tasks (SIGN-CORE-186-004/005, SIGN-TEST-186-006, SIGN-VEX-401-018). | Module Team (docs/modules/signer)
-SIGNER-OPS-0001 | TODO | Sync outcomes back to ../.. | Ops Guild (docs/modules/signer)
+# Sprint 329 - Documentation & Process · 200.S) Docs Modules Signer
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
+
+[Documentation & Process] 200.S) Docs Modules Signer
+Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - AirGap, Sprint 130.A - Scanner, Sprint 140.A - Graph, Sprint 150.A - Orchestrator, Sprint 160.A - EvidenceLocker, Sprint 170.A - Notifier, Sprint 180.A - Cli, Sprint 190.A - Ops Deployment
+Summary: Documentation & Process focus on Docs Modules Signer).
+Task ID | State | Task description | Owners (Source)
+--- | --- | --- | ---
+SIGNER-DOCS-0001 | DONE (2025-11-05) | Validate that `docs/modules/signer/README.md` captures the latest DSSE/fulcio updates. | Docs Guild (docs/modules/signer)
+SIGNER-OPS-0001 | TODO | Review signer runbooks/observability assets after next sprint demo. | Ops Guild (docs/modules/signer)
+SIGNER-ENG-0001 | DONE (2025-11-27) | Keep module milestones aligned with signer sprints under `/docs/implplan`. Added Sprint Readiness Tracker to `docs/modules/signer/implementation_plan.md` mapping 4 phases to 17+ sprint tasks across Sprints 100, 186, 401, 513, 514. Updated README with Sprint 0186/0401 completed tasks (SIGN-CORE-186-004/005, SIGN-TEST-186-006, SIGN-VEX-401-018). | Module Team (docs/modules/signer)
+SIGNER-OPS-0001 | TODO | Sync outcomes back to ../.. | Ops Guild (docs/modules/signer)
diff --git a/docs/implplan/SPRINT_330_docs_modules_telemetry.md b/docs/implplan/SPRINT_330_docs_modules_telemetry.md
index 726080931..a618c9790 100644
--- a/docs/implplan/SPRINT_330_docs_modules_telemetry.md
+++ b/docs/implplan/SPRINT_330_docs_modules_telemetry.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0330_0001_0001_docs_modules_telemetry.md` to comply with the standard template. Update any links accordingly.
diff --git a/docs/implplan/SPRINT_331_docs_modules_ui.md b/docs/implplan/SPRINT_331_docs_modules_ui.md
index f7bf56ee1..45670f38d 100644
--- a/docs/implplan/SPRINT_331_docs_modules_ui.md
+++ b/docs/implplan/SPRINT_331_docs_modules_ui.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0331_0001_0001_docs_modules_ui.md` to meet the standard template. Update any links accordingly.
diff --git a/docs/implplan/SPRINT_332_docs_modules_vex_lens.md b/docs/implplan/SPRINT_332_docs_modules_vex_lens.md
index e3bad8647..85c7af1c4 100644
--- a/docs/implplan/SPRINT_332_docs_modules_vex_lens.md
+++ b/docs/implplan/SPRINT_332_docs_modules_vex_lens.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0332_0001_0001_docs_modules_vex_lens.md` for template compliance. Please update bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_333_docs_modules_excititor.md b/docs/implplan/SPRINT_333_docs_modules_excititor.md
index a9bb3b3c9..0756a01a7 100644
--- a/docs/implplan/SPRINT_333_docs_modules_excititor.md
+++ b/docs/implplan/SPRINT_333_docs_modules_excititor.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0333_0001_0001_docs_modules_excititor.md` to comply with the standard template. Update any links accordingly.
diff --git a/docs/implplan/SPRINT_334_docs_modules_vuln_explorer.md b/docs/implplan/SPRINT_334_docs_modules_vuln_explorer.md
index 5dc8a6065..1d7f1ec3c 100644
--- a/docs/implplan/SPRINT_334_docs_modules_vuln_explorer.md
+++ b/docs/implplan/SPRINT_334_docs_modules_vuln_explorer.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0334_0001_0001_docs_modules_vuln_explorer.md` to align with the standard naming template. Please update any bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_335_docs_modules_zastava.md b/docs/implplan/SPRINT_335_docs_modules_zastava.md
index cc5f9f912..8b5f7ff7c 100644
--- a/docs/implplan/SPRINT_335_docs_modules_zastava.md
+++ b/docs/implplan/SPRINT_335_docs_modules_zastava.md
@@ -1,3 +1,5 @@
# Moved sprint file
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
This sprint has been renamed to `SPRINT_0335_0001_0001_docs_modules_zastava.md` to align with the standard template. Please update any bookmarks accordingly.
diff --git a/docs/implplan/SPRINT_3400_0000_0000_postgres_conversion_overview.md b/docs/implplan/SPRINT_3400_0000_0000_postgres_conversion_overview.md
index 5db0acd8e..f7b6c7dd0 100644
--- a/docs/implplan/SPRINT_3400_0000_0000_postgres_conversion_overview.md
+++ b/docs/implplan/SPRINT_3400_0000_0000_postgres_conversion_overview.md
@@ -1,5 +1,7 @@
# PostgreSQL Conversion Project Overview
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Project Summary
**Objective:** Convert StellaOps control-plane domains from MongoDB to PostgreSQL using a strangler fig pattern for gradual rollout.
diff --git a/docs/implplan/SPRINT_3400_0001_0001_postgres_foundations.md b/docs/implplan/SPRINT_3400_0001_0001_postgres_foundations.md
index 05efe5930..aeb1f47c5 100644
--- a/docs/implplan/SPRINT_3400_0001_0001_postgres_foundations.md
+++ b/docs/implplan/SPRINT_3400_0001_0001_postgres_foundations.md
@@ -19,6 +19,8 @@
- docs/db/VERIFICATION.md
- docs/db/CONVERSION_PLAN.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_3401_0001_0001_postgres_authority.md b/docs/implplan/SPRINT_3401_0001_0001_postgres_authority.md
index c130d22e5..444cc5cfd 100644
--- a/docs/implplan/SPRINT_3401_0001_0001_postgres_authority.md
+++ b/docs/implplan/SPRINT_3401_0001_0001_postgres_authority.md
@@ -18,6 +18,8 @@
- docs/db/RULES.md
- src/Authority/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_3402_0001_0001_postgres_scheduler.md b/docs/implplan/SPRINT_3402_0001_0001_postgres_scheduler.md
index 688f2be3d..28097dc3a 100644
--- a/docs/implplan/SPRINT_3402_0001_0001_postgres_scheduler.md
+++ b/docs/implplan/SPRINT_3402_0001_0001_postgres_scheduler.md
@@ -18,6 +18,8 @@
- docs/db/RULES.md
- src/Scheduler/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_3403_0001_0001_postgres_notify.md b/docs/implplan/SPRINT_3403_0001_0001_postgres_notify.md
index e859d618e..234bf982f 100644
--- a/docs/implplan/SPRINT_3403_0001_0001_postgres_notify.md
+++ b/docs/implplan/SPRINT_3403_0001_0001_postgres_notify.md
@@ -20,6 +20,8 @@
- src/Notify/AGENTS.md
- src/Notify/__Libraries/StellaOps.Notify.Storage.Postgres/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_3404_0001_0001_postgres_policy.md b/docs/implplan/SPRINT_3404_0001_0001_postgres_policy.md
index 342917db7..e06d5d965 100644
--- a/docs/implplan/SPRINT_3404_0001_0001_postgres_policy.md
+++ b/docs/implplan/SPRINT_3404_0001_0001_postgres_policy.md
@@ -18,6 +18,8 @@
- docs/db/RULES.md
- src/Policy/AGENTS.md (if exists)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_3405_0001_0001_postgres_vulnerabilities.md b/docs/implplan/SPRINT_3405_0001_0001_postgres_vulnerabilities.md
index 3023d4fe8..6002ee339 100644
--- a/docs/implplan/SPRINT_3405_0001_0001_postgres_vulnerabilities.md
+++ b/docs/implplan/SPRINT_3405_0001_0001_postgres_vulnerabilities.md
@@ -18,6 +18,8 @@
- docs/db/RULES.md
- src/Concelier/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
### Sprint 5a: Schema & Repositories
diff --git a/docs/implplan/SPRINT_3406_0001_0001_postgres_vex_graph.md b/docs/implplan/SPRINT_3406_0001_0001_postgres_vex_graph.md
index adff8bc1e..e45311eb5 100644
--- a/docs/implplan/SPRINT_3406_0001_0001_postgres_vex_graph.md
+++ b/docs/implplan/SPRINT_3406_0001_0001_postgres_vex_graph.md
@@ -20,6 +20,8 @@
- docs/modules/platform/architecture-overview.md
- src/Excititor/AGENTS.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Wave Coordination
| Wave | Scope | Exit gate | Notes |
| --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_3407_0001_0001_postgres_cleanup.md b/docs/implplan/SPRINT_3407_0001_0001_postgres_cleanup.md
index 4ea2e6ca7..17841d5b5 100644
--- a/docs/implplan/SPRINT_3407_0001_0001_postgres_cleanup.md
+++ b/docs/implplan/SPRINT_3407_0001_0001_postgres_cleanup.md
@@ -24,6 +24,8 @@
- docs/db/VERIFICATION.md
- All module AGENTS.md files
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
### T7.1: Remove MongoDB Dependencies
diff --git a/docs/implplan/SPRINT_3408_0001_0001_postgres_migration_lifecycle.md b/docs/implplan/SPRINT_3408_0001_0001_postgres_migration_lifecycle.md
new file mode 100644
index 000000000..d22356c46
--- /dev/null
+++ b/docs/implplan/SPRINT_3408_0001_0001_postgres_migration_lifecycle.md
@@ -0,0 +1,272 @@
+# Sprint 3408 · PostgreSQL Migration Lifecycle Implementation
+
+## Topic & Scope
+- Implement the PostgreSQL migration strategy defined in `docs/db/MIGRATION_STRATEGY.md`.
+- Add startup migration hosts to all modules with advisory lock coordination.
+- Create CLI tooling for manual/release migrations.
+- Integrate migration status into health checks.
+- **Working directory:** src/__Libraries/StellaOps.Infrastructure.Postgres/Migrations (core), src/*/WebService (module integration)
+
+## Dependencies & Concurrency
+- Upstream: Sprint 3400 (Phase 0 - Foundations) must be DONE.
+- Upstream: All module PostgreSQL storage libraries must exist (Phases 1-5).
+- Concurrency: Can run in parallel with data migration tasks (PG-T5b.3.2, PG-T5b.4.4).
+- Reference: `docs/db/MIGRATION_STRATEGY.md`
+
+## Documentation Prerequisites
+- docs/db/MIGRATION_STRATEGY.md
+- docs/db/SPECIFICATION.md
+- docs/db/RULES.md
+- Existing module migration files in `src/*/Storage.Postgres/Migrations/`
+
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
+## Delivery Tracker
+
+### Wave 1: Core Infrastructure Enhancement
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 1 | MIG-T1.1 | DONE | Completed 2025-12-03 | Infrastructure | Create `MigrationCategory.cs` enum with filename parsing |
+| 2 | MIG-T1.2 | DONE | Completed 2025-12-03 | Infrastructure | Create `StartupMigrationHost.cs` with advisory locks |
+| 3 | MIG-T1.3 | DONE | Completed 2025-12-03 | Infrastructure | Create `MigrationServiceExtensions.cs` for DI |
+| 4 | MIG-T1.4 | DONE | Completed 2025-12-03 | Infrastructure | Update `MigrationRunner.cs` to support category filtering |
+| 5 | MIG-T1.5 | DONE | Completed 2025-12-03 | Infrastructure | Add checksum validation to existing `MigrationRunner` |
+| 6 | MIG-T1.6 | DONE | Completed 2025-12-03 | Infrastructure | Create `IMigrationRunner` interface for testability |
+| 7 | MIG-T1.7 | DONE | Completed 2025-12-03 | Infrastructure | Write unit tests for `MigrationCategory` (54 tests) |
+| 8 | MIG-T1.8 | DONE | Completed 2025-12-03 | Infrastructure | Write integration tests for `StartupMigrationHost` (13 tests) |
+
+### Wave 2: CLI Tooling
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 9 | MIG-T2.1 | DONE | Completed 2025-12-03 | CLI | Create `system migrations-run` command structure |
+| 10 | MIG-T2.2 | DONE | Completed 2025-12-03 | CLI | Implement `--module` filter for targeted migrations |
+| 11 | MIG-T2.3 | DONE | Completed 2025-12-03 | CLI | Implement `--category` filter (startup/release/seed/data) |
+| 12 | MIG-T2.4 | DONE | Completed 2025-12-03 | CLI | Implement `--dry-run` mode |
+| 13 | MIG-T2.5 | DONE | Completed 2025-12-03 | CLI | Create `system migrations-status` command |
+| 14 | MIG-T2.6 | DONE | Completed 2025-12-03 | CLI | Implement `--all` flag for cross-module status |
+| 15 | MIG-T2.7 | DONE | Completed 2025-12-03 | CLI | Create `system migrations-verify` command |
+| 16 | MIG-T2.8 | TODO | Depends on Scanner build fixes | CLI | Write CLI integration tests |
+
+### Wave 3: Module Integration - Authority
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 17 | MIG-T3.1 | TODO | Depends on MIG-T1.3 | Authority | Update Authority.Storage.Postgres.csproj with EmbeddedResource |
+| 18 | MIG-T3.2 | TODO | Depends on MIG-T3.1 | Authority | Rename migrations to follow naming convention (001-099) |
+| 19 | MIG-T3.3 | TODO | Depends on MIG-T3.2 | Authority | Register `AddStartupMigrations` in Authority.WebService |
+| 20 | MIG-T3.4 | TODO | Depends on MIG-T3.3 | Authority | Add migration status health check |
+| 21 | MIG-T3.5 | TODO | Depends on MIG-T3.4 | Authority | Test startup migration in Authority.WebService.Tests |
+
+### Wave 4: Module Integration - Scheduler
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 22 | MIG-T4.1 | TODO | Depends on MIG-T1.3 | Scheduler | Update Scheduler.Storage.Postgres.csproj with EmbeddedResource |
+| 23 | MIG-T4.2 | TODO | Depends on MIG-T4.1 | Scheduler | Rename migrations to follow naming convention |
+| 24 | MIG-T4.3 | TODO | Depends on MIG-T4.2 | Scheduler | Register `AddStartupMigrations` in Scheduler.WebService |
+| 25 | MIG-T4.4 | TODO | Depends on MIG-T4.3 | Scheduler | Add migration status health check |
+| 26 | MIG-T4.5 | TODO | Depends on MIG-T4.4 | Scheduler | Test startup migration in Scheduler.WebService.Tests |
+
+### Wave 5: Module Integration - Concelier
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 27 | MIG-T5.1 | TODO | Depends on MIG-T1.3 | Concelier | Update Concelier.Storage.Postgres.csproj with EmbeddedResource |
+| 28 | MIG-T5.2 | TODO | Depends on MIG-T5.1 | Concelier | Rename migrations to follow naming convention |
+| 29 | MIG-T5.3 | TODO | Depends on MIG-T5.2 | Concelier | Register `AddStartupMigrations` in Concelier.WebService |
+| 30 | MIG-T5.4 | TODO | Depends on MIG-T5.3 | Concelier | Add migration status health check |
+| 31 | MIG-T5.5 | TODO | Depends on MIG-T5.4 | Concelier | Test startup migration in Concelier.WebService.Tests |
+
+### Wave 6: Module Integration - Policy
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 32 | MIG-T6.1 | TODO | Depends on MIG-T1.3 | Policy | Update Policy.Storage.Postgres.csproj with EmbeddedResource |
+| 33 | MIG-T6.2 | TODO | Depends on MIG-T6.1 | Policy | Rename migrations to follow naming convention |
+| 34 | MIG-T6.3 | TODO | Depends on MIG-T6.2 | Policy | Register `AddStartupMigrations` in Policy.Engine |
+| 35 | MIG-T6.4 | TODO | Depends on MIG-T6.3 | Policy | Add migration status health check |
+| 36 | MIG-T6.5 | TODO | Depends on MIG-T6.4 | Policy | Test startup migration in Policy.Engine.Tests |
+
+### Wave 7: Module Integration - Notify
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 37 | MIG-T7.1 | TODO | Depends on MIG-T1.3 | Notify | Update Notify.Storage.Postgres.csproj with EmbeddedResource |
+| 38 | MIG-T7.2 | TODO | Depends on MIG-T7.1 | Notify | Rename migrations to follow naming convention |
+| 39 | MIG-T7.3 | TODO | Depends on MIG-T7.2 | Notify | Register `AddStartupMigrations` in Notify.WebService |
+| 40 | MIG-T7.4 | TODO | Depends on MIG-T7.3 | Notify | Add migration status health check |
+| 41 | MIG-T7.5 | TODO | Depends on MIG-T7.4 | Notify | Test startup migration in Notify.WebService.Tests |
+
+### Wave 8: Module Integration - Excititor
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 42 | MIG-T8.1 | TODO | Depends on MIG-T1.3 | Excititor | Update Excititor.Storage.Postgres.csproj with EmbeddedResource |
+| 43 | MIG-T8.2 | TODO | Depends on MIG-T8.1 | Excititor | Rename migrations to follow naming convention |
+| 44 | MIG-T8.3 | TODO | Depends on MIG-T8.2 | Excititor | Register `AddStartupMigrations` in Excititor.WebService |
+| 45 | MIG-T8.4 | TODO | Depends on MIG-T8.3 | Excititor | Add migration status health check |
+| 46 | MIG-T8.5 | TODO | Depends on MIG-T8.4 | Excititor | Test startup migration in Excititor.WebService.Tests |
+
+### Wave 9: Verification & Documentation
+| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
+| --- | --- | --- | --- | --- | --- |
+| 47 | MIG-T9.1 | TODO | Depends on Waves 3-8 | QA | End-to-end test: multi-instance startup race condition |
+| 48 | MIG-T9.2 | TODO | Depends on MIG-T9.1 | QA | End-to-end test: release migration blocking startup |
+| 49 | MIG-T9.3 | TODO | Depends on MIG-T9.1 | QA | End-to-end test: checksum mismatch detection |
+| 50 | MIG-T9.4 | TODO | Depends on MIG-T2.8 | Docs | Update CLI reference documentation |
+| 51 | MIG-T9.5 | TODO | Depends on MIG-T9.4 | Docs | Create runbook for migration operations |
+| 52 | MIG-T9.6 | TODO | Depends on MIG-T9.5 | DevOps | Add migration status to Grafana dashboards |
+
+## Wave Coordination
+
+```
+Wave 1 (Core Infrastructure) ─┬─► Wave 2 (CLI Tooling) ──────────────────────┐
+ │ │
+ ├─► Wave 3 (Authority) ─┐ │
+ ├─► Wave 4 (Scheduler) ─┤ │
+ ├─► Wave 5 (Concelier) ─┼─► Wave 9 (Verification)
+ ├─► Wave 6 (Policy) ────┤
+ ├─► Wave 7 (Notify) ────┤
+ └─► Wave 8 (Excititor) ─┘
+```
+
+- Wave 1 must complete before any other wave.
+- Waves 3-8 can run in parallel after Wave 1.
+- Wave 2 can run in parallel with Waves 3-8.
+- Wave 9 requires all other waves to complete.
+
+## Interlocks
+
+- **Sprint 3400**: Migration infrastructure depends on `StellaOps.Infrastructure.Postgres` from Phase 0.
+- **Sprints 3401-3406**: Module integration (Waves 3-8) requires respective module storage libraries.
+- **DevOps**: Health check integration requires coordination with monitoring infrastructure.
+- **CI/CD**: CLI commands must be available in deployment pipelines before Wave 9.
+
+## Exit Criteria
+
+- [ ] All modules have startup migrations with advisory locks
+- [ ] CLI provides `db migrate`, `db status`, `db verify` commands
+- [ ] Multi-instance race conditions are prevented
+- [ ] Checksum validation catches modified migrations
+- [ ] Release migrations block startup until manually applied
+- [ ] Health checks expose migration status
+- [ ] Documentation complete for operators
+
+## Task Details
+
+### MIG-T1.4: Update MigrationRunner with Category Support
+
+```csharp
+// Add to MigrationRunner.cs
+public async Task RunAsync(
+ string migrationsPath,
+ MigrationCategory? categoryFilter = null,
+ CancellationToken cancellationToken = default)
+{
+ // Filter migrations by category before execution
+}
+```
+
+### MIG-T2.1: CLI db migrate Command
+
+```bash
+# Command structure
+stellaops db migrate [options]
+
+Options:
+ --module Target specific module (Authority, Scheduler, etc.)
+ --category Filter by category (startup, release, seed, data)
+ --dry-run Show what would be executed without applying
+ --connection Override connection string
+ --timeout Migration timeout (default: 300)
+ --force Skip confirmation for release migrations
+```
+
+### MIG-T3.3: Authority Integration Example
+
+```csharp
+// In Authority.WebService/Program.cs or ServiceCollectionExtensions.cs
+public static IServiceCollection AddAuthorityPostgres(
+ this IServiceCollection services,
+ IConfiguration configuration)
+{
+ services.Configure(
+ configuration.GetSection("Authority:Storage:Postgres"));
+
+ // Register repositories...
+
+ // Add startup migrations
+ services.AddStartupMigrations(
+ schemaName: "auth",
+ moduleName: "Authority",
+ migrationsAssembly: typeof(AuthorityDataSource).Assembly,
+ connectionStringSelector: opts => opts.ConnectionString,
+ configureOptions: opts =>
+ {
+ opts.FailOnPendingReleaseMigrations = true;
+ opts.LockTimeoutSeconds = 120;
+ });
+
+ // Add health check
+ services.AddHealthChecks()
+ .AddCheck("authority-migrations");
+
+ return services;
+}
+```
+
+### MIG-T9.1: Multi-Instance Race Condition Test
+
+```csharp
+[Fact]
+public async Task MultipleInstances_ShouldNotApplyMigrationsTwice()
+{
+ // Start 5 instances simultaneously
+ var tasks = Enumerable.Range(0, 5)
+ .Select(_ => StartApplicationAsync())
+ .ToArray();
+
+ await Task.WhenAll(tasks);
+
+ // Verify migration was applied exactly once
+ var appliedCount = await GetMigrationAppliedCountAsync("001_initial_schema.sql");
+ Assert.Equal(1, appliedCount);
+}
+```
+
+## Decisions & Risks
+
+| Risk | Impact | Mitigation | Owner | Status |
+| --- | --- | --- | --- | --- |
+| Advisory lock contention in large deployments | Startup delays | Implement exponential backoff, configurable timeout | Infrastructure | Open |
+| Checksum drift from line-ending differences | False positives on validation | Normalize line endings before checksum | Infrastructure | Mitigated (implemented) |
+| CLI not available in air-gapped deployments | Cannot run release migrations | Embed CLI in container images | DevOps | Open |
+| Module startup order dependencies | Schema creation race | Each module creates its own schema independently | Infrastructure | Mitigated |
+
+## Action Tracker
+
+| # | Action | Owner | Due | Status | Notes |
+| --- | --- | --- | --- | --- | --- |
+| 1 | Complete Wave 1 infrastructure tasks | Infrastructure | TBD | DONE | MIG-T1.1-T1.8 complete |
+| 2 | Design CLI command structure | CLI Team | TBD | TODO | Coordinate with existing CLI patterns |
+| 3 | Identify migration file renames per module | All Guilds | TBD | TODO | Audit existing migrations |
+| 4 | Coordinate health check endpoints | DevOps | TBD | TODO | Align with existing /health patterns |
+
+## Execution Log
+
+| Date (UTC) | Update | Owner |
+| --- | --- | --- |
+| 2025-12-03 | Sprint file created | Claude |
+| 2025-12-03 | Completed MIG-T1.1: MigrationCategory.cs created | Claude |
+| 2025-12-03 | Completed MIG-T1.2: StartupMigrationHost.cs created with advisory locks | Claude |
+| 2025-12-03 | Completed MIG-T1.3: MigrationServiceExtensions.cs created for DI | Claude |
+| 2025-12-03 | Added Microsoft.Extensions.Hosting.Abstractions to Infrastructure.Postgres | Claude |
+| 2025-12-03 | Completed MIG-T1.4: Updated MigrationRunner.cs with category filtering and MigrationRunOptions | Claude |
+| 2025-12-03 | Completed MIG-T1.5: Added checksum validation to MigrationRunner (ValidateChecksumsAsync) | Claude |
+| 2025-12-03 | Completed MIG-T1.6: Created IMigrationRunner interface with full API | Claude |
+| 2025-12-03 | Completed MIG-T1.7: Created MigrationCategoryTests.cs (54 unit tests) | Claude |
+| 2025-12-03 | Completed MIG-T1.8: Created StartupMigrationHostTests.cs (13 integration tests) | Claude |
+| 2025-12-03 | Wave 1 COMPLETE - all core infrastructure tasks done | Claude |
+| 2025-12-03 | Completed MIG-T2.1-T2.7: Created `system migrations-*` CLI commands | Claude |
+| 2025-12-03 | Created MigrationModuleRegistry.cs with all 6 module definitions | Claude |
+| 2025-12-03 | Created SystemCommandHandlers.cs for migrations-run/status/verify | Claude |
+| 2025-12-03 | Added BuildSystemCommand to CommandFactory.cs | Claude |
+| 2025-12-03 | Added Storage.Postgres references to CLI project | Claude |
+| 2025-12-03 | Note: CLI build blocked by pre-existing Scanner module errors | Claude |
+
+---
+*Reference: docs/db/MIGRATION_STRATEGY.md*
diff --git a/docs/implplan/SPRINT_500_ops_offline.md b/docs/implplan/SPRINT_500_ops_offline.md
index 774c5f2a2..a7a6df73f 100644
--- a/docs/implplan/SPRINT_500_ops_offline.md
+++ b/docs/implplan/SPRINT_500_ops_offline.md
@@ -1,5 +1,7 @@
# Sprint 500 - Ops & Offline
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08).
This file now only tracks the Ops & Offline status snapshot. Active backlog lives in Sprint 501 and later files.
diff --git a/docs/implplan/SPRINT_501_ops_deployment_i.md b/docs/implplan/SPRINT_501_ops_deployment_i.md
index 5c60248a6..b5337ef8d 100644
--- a/docs/implplan/SPRINT_501_ops_deployment_i.md
+++ b/docs/implplan/SPRINT_501_ops_deployment_i.md
@@ -18,6 +18,8 @@ Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - A
- docs/modules/ci/architecture.md
- docs/airgap/** (for mirror/import tasks)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| Task ID | State | Task description | Owners (Source) |
| --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_502_ops_deployment_ii.md b/docs/implplan/SPRINT_502_ops_deployment_ii.md
index 5213f3162..6daab9a57 100644
--- a/docs/implplan/SPRINT_502_ops_deployment_ii.md
+++ b/docs/implplan/SPRINT_502_ops_deployment_ii.md
@@ -15,6 +15,8 @@
- docs/modules/platform/architecture-overview.md
- Any module-specific runbooks referenced by tasks (policy, VEX Lens, Findings Ledger).
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_503_ops_devops_i.md b/docs/implplan/SPRINT_503_ops_devops_i.md
index 00c19cb9f..2332009ae 100644
--- a/docs/implplan/SPRINT_503_ops_devops_i.md
+++ b/docs/implplan/SPRINT_503_ops_devops_i.md
@@ -19,6 +19,8 @@ Depends on: Sprint 100.A - Attestor, Sprint 110.A - AdvisoryAI, Sprint 120.A - A
- docs/modules/ci/architecture.md
- docs/airgap/** (for sealed-mode tasks)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| Task ID | State | Task description | Owners (Source) |
| --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_504_ops_devops_ii.log.md b/docs/implplan/SPRINT_504_ops_devops_ii.log.md
index 499fe9761..11e514725 100644
--- a/docs/implplan/SPRINT_504_ops_devops_ii.log.md
+++ b/docs/implplan/SPRINT_504_ops_devops_ii.log.md
@@ -1,4 +1,6 @@
## Execution Log (addendum)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-24 | Completed DEVOPS-CONTAINERS-44-001: added buildx multi-arch script (`scripts/buildx/build-multiarch.sh`) with SBOM + optional cosign signing, and workflow `.gitea/workflows/containers-multiarch.yml` for manual dispatch. | Implementer |
diff --git a/docs/implplan/SPRINT_505_ops_devops_iii.md b/docs/implplan/SPRINT_505_ops_devops_iii.md
index f9dc19c1b..1ac2fe070 100644
--- a/docs/implplan/SPRINT_505_ops_devops_iii.md
+++ b/docs/implplan/SPRINT_505_ops_devops_iii.md
@@ -15,6 +15,8 @@
- docs/modules/platform/architecture-overview.md
- Existing CI/OAS runbooks referenced by tasks.
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_506_ops_devops_iv.md b/docs/implplan/SPRINT_506_ops_devops_iv.md
index e9f9a5d2c..d69bf09a6 100644
--- a/docs/implplan/SPRINT_506_ops_devops_iv.md
+++ b/docs/implplan/SPRINT_506_ops_devops_iv.md
@@ -16,6 +16,8 @@
- docs/modules/devops/architecture.md
- ops/devops/README.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_507_ops_devops_v.md b/docs/implplan/SPRINT_507_ops_devops_v.md
index 34aacb96b..60109dae3 100644
--- a/docs/implplan/SPRINT_507_ops_devops_v.md
+++ b/docs/implplan/SPRINT_507_ops_devops_v.md
@@ -13,6 +13,8 @@
- ops/devops/README.md
- ops/devops/docker/base-image-guidelines.md
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_508_ops_offline_kit.md b/docs/implplan/SPRINT_508_ops_offline_kit.md
index e9f1173af..ae1997658 100644
--- a/docs/implplan/SPRINT_508_ops_offline_kit.md
+++ b/docs/implplan/SPRINT_508_ops_offline_kit.md
@@ -14,6 +14,8 @@
- docs/modules/devops/architecture.md
- ops/offline-kit README/tests
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/implplan/SPRINT_511_api.md b/docs/implplan/SPRINT_511_api.md
index d970d0834..0d315fc45 100644
--- a/docs/implplan/SPRINT_511_api.md
+++ b/docs/implplan/SPRINT_511_api.md
@@ -14,6 +14,8 @@
- docs/api/openapi-discovery.md
- src/Api/StellaOps.Api.Governance/README.md (if present)
+> **BLOCKED Tasks:** Before working on BLOCKED tasks, review [BLOCKED_DEPENDENCY_TREE.md](./BLOCKED_DEPENDENCY_TREE.md) for root blockers and dependencies.
+
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
diff --git a/docs/router/13-Step.md b/docs/router/13-Step.md
new file mode 100644
index 000000000..89d19b8f3
--- /dev/null
+++ b/docs/router/13-Step.md
@@ -0,0 +1,946 @@
+# Step 13: InMemory Transport Implementation
+
+**Phase 3: Transport Layer**
+**Estimated Complexity:** Medium
+**Dependencies:** Step 12 (Request/Response Serialization)
+
+---
+
+## Overview
+
+The InMemory transport provides a high-performance, zero-network transport for testing, local development, and same-process microservices. It serves as the reference implementation for the transport layer and must pass all protocol tests before any real transport implementation.
+
+---
+
+## Goals
+
+1. Implement a fully-functional in-process transport without network overhead
+2. Serve as the reference implementation for transport protocol compliance
+3. Enable fast integration tests without network dependencies
+4. Support all frame types and streaming semantics
+5. Provide debugging hooks for protocol validation
+
+---
+
+## Core Architecture
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ InMemory Transport Hub │
+├─────────────────────────────────────────────────────────────┤
+│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
+│ │ Gateway Side │◄──►│ Channels │◄──►│Microservice │ │
+│ │ Client │ │ (Duplex) │ │ Server │ │
+│ └──────────────┘ └──────────────┘ └──────────────┘ │
+│ │
+│ Connection Registry Frame Queue Handler Dispatch │
+└─────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Core Types
+
+### InMemory Channel
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory;
+
+///
+/// Bidirectional in-memory channel for frame exchange.
+///
+public sealed class InMemoryChannel : IAsyncDisposable
+{
+ private readonly Channel _gatewayToService;
+ private readonly Channel _serviceToGateway;
+ private readonly CancellationTokenSource _cts;
+
+ public string ChannelId { get; }
+ public string ServiceName { get; }
+ public string InstanceId { get; }
+ public ConnectionState State { get; private set; }
+ public DateTimeOffset CreatedAt { get; }
+ public DateTimeOffset LastActivityAt { get; private set; }
+
+ public InMemoryChannel(string serviceName, string instanceId)
+ {
+ ChannelId = Guid.NewGuid().ToString("N");
+ ServiceName = serviceName;
+ InstanceId = instanceId;
+ CreatedAt = DateTimeOffset.UtcNow;
+ LastActivityAt = CreatedAt;
+ State = ConnectionState.Connecting;
+ _cts = new CancellationTokenSource();
+
+ // Bounded channels to provide backpressure
+ var options = new BoundedChannelOptions(1000)
+ {
+ FullMode = BoundedChannelFullMode.Wait,
+ SingleReader = false,
+ SingleWriter = false
+ };
+
+ _gatewayToService = Channel.CreateBounded(options);
+ _serviceToGateway = Channel.CreateBounded(options);
+ }
+
+ ///
+ /// Gets the writer for sending frames from gateway to service.
+ ///
+ public ChannelWriter GatewayWriter => _gatewayToService.Writer;
+
+ ///
+ /// Gets the reader for receiving frames from gateway (service side).
+ ///
+ public ChannelReader ServiceReader => _gatewayToService.Reader;
+
+ ///
+ /// Gets the writer for sending frames from service to gateway.
+ ///
+ public ChannelWriter ServiceWriter => _serviceToGateway.Writer;
+
+ ///
+ /// Gets the reader for receiving frames from service (gateway side).
+ ///
+ public ChannelReader GatewayReader => _serviceToGateway.Reader;
+
+ public void MarkConnected()
+ {
+ State = ConnectionState.Connected;
+ LastActivityAt = DateTimeOffset.UtcNow;
+ }
+
+ public void UpdateActivity()
+ {
+ LastActivityAt = DateTimeOffset.UtcNow;
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ State = ConnectionState.Disconnected;
+ _cts.Cancel();
+ _gatewayToService.Writer.TryComplete();
+ _serviceToGateway.Writer.TryComplete();
+ _cts.Dispose();
+ }
+}
+```
+
+### InMemory Hub
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory;
+
+///
+/// Central hub managing all InMemory transport connections.
+///
+public sealed class InMemoryTransportHub : IDisposable
+{
+ private readonly ConcurrentDictionary _channels = new();
+ private readonly ConcurrentDictionary> _serviceChannels = new();
+ private readonly ILogger _logger;
+
+ public InMemoryTransportHub(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ ///
+ /// Creates a new channel for a microservice connection.
+ ///
+ public InMemoryChannel CreateChannel(string serviceName, string instanceId)
+ {
+ var channel = new InMemoryChannel(serviceName, instanceId);
+
+ if (!_channels.TryAdd(channel.ChannelId, channel))
+ {
+ throw new InvalidOperationException($"Channel {channel.ChannelId} already exists");
+ }
+
+ _serviceChannels.AddOrUpdate(
+ serviceName,
+ _ => new List { channel.ChannelId },
+ (_, list) => { lock (list) { list.Add(channel.ChannelId); } return list; }
+ );
+
+ _logger.LogDebug(
+ "Created InMemory channel {ChannelId} for {ServiceName}/{InstanceId}",
+ channel.ChannelId, serviceName, instanceId);
+
+ return channel;
+ }
+
+ ///
+ /// Gets a channel by ID.
+ ///
+ public InMemoryChannel? GetChannel(string channelId)
+ {
+ return _channels.TryGetValue(channelId, out var channel) ? channel : null;
+ }
+
+ ///
+ /// Gets all channels for a service.
+ ///
+ public IReadOnlyList GetServiceChannels(string serviceName)
+ {
+ if (!_serviceChannels.TryGetValue(serviceName, out var channelIds))
+ return Array.Empty();
+
+ var result = new List();
+ lock (channelIds)
+ {
+ foreach (var id in channelIds)
+ {
+ if (_channels.TryGetValue(id, out var channel) &&
+ channel.State == ConnectionState.Connected)
+ {
+ result.Add(channel);
+ }
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Removes a channel from the hub.
+ ///
+ public async Task RemoveChannelAsync(string channelId)
+ {
+ if (_channels.TryRemove(channelId, out var channel))
+ {
+ if (_serviceChannels.TryGetValue(channel.ServiceName, out var list))
+ {
+ lock (list) { list.Remove(channelId); }
+ }
+
+ await channel.DisposeAsync();
+
+ _logger.LogDebug("Removed InMemory channel {ChannelId}", channelId);
+ }
+ }
+
+ ///
+ /// Gets all active channels.
+ ///
+ public IEnumerable GetAllChannels()
+ {
+ return _channels.Values.Where(c => c.State == ConnectionState.Connected);
+ }
+
+ public void Dispose()
+ {
+ foreach (var channel in _channels.Values)
+ {
+ _ = channel.DisposeAsync();
+ }
+ _channels.Clear();
+ _serviceChannels.Clear();
+ }
+}
+```
+
+---
+
+## Gateway-Side Client
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory;
+
+///
+/// Gateway-side client for InMemory transport.
+///
+public sealed class InMemoryTransportClient : ITransportClient
+{
+ private readonly InMemoryTransportHub _hub;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private readonly ConcurrentDictionary> _pendingRequests = new();
+
+ public string TransportType => "InMemory";
+
+ public InMemoryTransportClient(
+ InMemoryTransportHub hub,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _hub = hub;
+ _serializer = serializer;
+ _logger = logger;
+ }
+
+ public async Task SendRequestAsync(
+ string serviceName,
+ RequestPayload request,
+ TimeSpan timeout,
+ CancellationToken cancellationToken)
+ {
+ var channels = _hub.GetServiceChannels(serviceName);
+ if (channels.Count == 0)
+ {
+ throw new NoAvailableInstanceException(serviceName);
+ }
+
+ // Simple round-robin selection (in production, use routing plugin)
+ var channel = channels[Random.Shared.Next(channels.Count)];
+
+ var correlationId = Guid.NewGuid().ToString("N");
+ var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ _pendingRequests[correlationId] = tcs;
+
+ try
+ {
+ // Create and send request frame
+ var frame = new Frame
+ {
+ Type = FrameType.Request,
+ CorrelationId = correlationId,
+ Payload = _serializer.SerializeRequest(request)
+ };
+
+ await channel.GatewayWriter.WriteAsync(frame, cancellationToken);
+ channel.UpdateActivity();
+
+ // Start listening for response
+ _ = ListenForResponseAsync(channel, correlationId, cancellationToken);
+
+ // Wait for response with timeout
+ using var timeoutCts = new CancellationTokenSource(timeout);
+ using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(
+ cancellationToken, timeoutCts.Token);
+
+ try
+ {
+ return await tcs.Task.WaitAsync(linkedCts.Token);
+ }
+ catch (OperationCanceledException) when (timeoutCts.IsCancellationRequested)
+ {
+ // Send cancel frame
+ await SendCancelAsync(channel, correlationId);
+ throw new TimeoutException($"Request to {serviceName} timed out after {timeout}");
+ }
+ }
+ finally
+ {
+ _pendingRequests.TryRemove(correlationId, out _);
+ }
+ }
+
+ public async IAsyncEnumerable SendStreamingRequestAsync(
+ string serviceName,
+ IAsyncEnumerable requestChunks,
+ TimeSpan timeout,
+ [EnumeratorCancellation] CancellationToken cancellationToken)
+ {
+ var channels = _hub.GetServiceChannels(serviceName);
+ if (channels.Count == 0)
+ {
+ throw new NoAvailableInstanceException(serviceName);
+ }
+
+ var channel = channels[Random.Shared.Next(channels.Count)];
+ var correlationId = Guid.NewGuid().ToString("N");
+
+ // Send all request chunks
+ await foreach (var chunk in requestChunks.WithCancellation(cancellationToken))
+ {
+ var frame = new Frame
+ {
+ Type = FrameType.Request,
+ CorrelationId = correlationId,
+ Payload = _serializer.SerializeRequest(chunk),
+ Flags = chunk.IsStreaming ? FrameFlags.None : FrameFlags.Final
+ };
+
+ await channel.GatewayWriter.WriteAsync(frame, cancellationToken);
+ channel.UpdateActivity();
+ }
+
+ // Read response chunks
+ await foreach (var frame in channel.GatewayReader.ReadAllAsync(cancellationToken))
+ {
+ if (frame.CorrelationId != correlationId)
+ continue;
+
+ if (frame.Type == FrameType.Response)
+ {
+ var response = _serializer.DeserializeResponse(frame.Payload);
+ yield return response;
+
+ if (response.IsFinalChunk || frame.Flags.HasFlag(FrameFlags.Final))
+ yield break;
+ }
+ }
+ }
+
+ private async Task ListenForResponseAsync(
+ InMemoryChannel channel,
+ string correlationId,
+ CancellationToken cancellationToken)
+ {
+ try
+ {
+ await foreach (var frame in channel.GatewayReader.ReadAllAsync(cancellationToken))
+ {
+ if (frame.CorrelationId != correlationId)
+ continue;
+
+ if (frame.Type == FrameType.Response)
+ {
+ var response = _serializer.DeserializeResponse(frame.Payload);
+
+ if (_pendingRequests.TryGetValue(correlationId, out var tcs))
+ {
+ tcs.TrySetResult(response);
+ }
+ return;
+ }
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ // Expected on cancellation
+ }
+ }
+
+ private async Task SendCancelAsync(InMemoryChannel channel, string correlationId)
+ {
+ try
+ {
+ var cancelFrame = new Frame
+ {
+ Type = FrameType.Cancel,
+ CorrelationId = correlationId,
+ Payload = Array.Empty()
+ };
+ await channel.GatewayWriter.WriteAsync(cancelFrame);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "Failed to send cancel frame for {CorrelationId}", correlationId);
+ }
+ }
+}
+```
+
+---
+
+## Microservice-Side Server
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory;
+
+///
+/// Microservice-side server for InMemory transport.
+///
+public sealed class InMemoryTransportServer : ITransportServer
+{
+ private readonly InMemoryTransportHub _hub;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private InMemoryChannel? _channel;
+ private CancellationTokenSource? _cts;
+ private Task? _processingTask;
+
+ public string TransportType => "InMemory";
+ public bool IsConnected => _channel?.State == ConnectionState.Connected;
+
+ public event Func>? OnRequest;
+ public event Func? OnCancel;
+
+ public InMemoryTransportServer(
+ InMemoryTransportHub hub,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _hub = hub;
+ _serializer = serializer;
+ _logger = logger;
+ }
+
+ public async Task ConnectAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ _channel = _hub.CreateChannel(serviceName, instanceId);
+ _cts = new CancellationTokenSource();
+
+ // Send HELLO frame
+ var helloPayload = new HelloPayload
+ {
+ ServiceName = serviceName,
+ InstanceId = instanceId,
+ Endpoints = endpoints,
+ Metadata = new Dictionary
+ {
+ ["transport"] = "InMemory",
+ ["pid"] = Environment.ProcessId.ToString()
+ }
+ };
+
+ var helloFrame = new Frame
+ {
+ Type = FrameType.Hello,
+ CorrelationId = Guid.NewGuid().ToString("N"),
+ Payload = _serializer.SerializeHello(helloPayload)
+ };
+
+ await _channel.ServiceWriter.WriteAsync(helloFrame, cancellationToken);
+
+ // Wait for HELLO response
+ var response = await _channel.ServiceReader.ReadAsync(cancellationToken);
+ if (response.Type != FrameType.Hello)
+ {
+ throw new ProtocolException($"Expected HELLO response, got {response.Type}");
+ }
+
+ _channel.MarkConnected();
+ _logger.LogInformation(
+ "InMemory transport connected for {ServiceName}/{InstanceId}",
+ serviceName, instanceId);
+
+ // Start processing loop
+ _processingTask = ProcessFramesAsync(_cts.Token);
+ }
+
+ private async Task ProcessFramesAsync(CancellationToken cancellationToken)
+ {
+ if (_channel == null) return;
+
+ try
+ {
+ await foreach (var frame in _channel.ServiceReader.ReadAllAsync(cancellationToken))
+ {
+ _channel.UpdateActivity();
+
+ switch (frame.Type)
+ {
+ case FrameType.Request:
+ _ = HandleRequestAsync(frame, cancellationToken);
+ break;
+
+ case FrameType.Cancel:
+ if (OnCancel != null)
+ {
+ await OnCancel(frame.CorrelationId, cancellationToken);
+ }
+ break;
+
+ case FrameType.Heartbeat:
+ await HandleHeartbeatAsync(frame);
+ break;
+ }
+ }
+ }
+ catch (OperationCanceledException)
+ {
+ // Expected on shutdown
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error processing InMemory frames");
+ }
+ }
+
+ private async Task HandleRequestAsync(Frame frame, CancellationToken cancellationToken)
+ {
+ if (_channel == null || OnRequest == null) return;
+
+ try
+ {
+ var request = _serializer.DeserializeRequest(frame.Payload);
+ var response = await OnRequest(request, cancellationToken);
+
+ var responseFrame = new Frame
+ {
+ Type = FrameType.Response,
+ CorrelationId = frame.CorrelationId,
+ Payload = _serializer.SerializeResponse(response),
+ Flags = FrameFlags.Final
+ };
+
+ await _channel.ServiceWriter.WriteAsync(responseFrame, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error handling request {CorrelationId}", frame.CorrelationId);
+
+ // Send error response
+ var errorResponse = new ResponsePayload
+ {
+ StatusCode = 500,
+ Headers = new Dictionary(),
+ ErrorMessage = ex.Message,
+ IsFinalChunk = true
+ };
+
+ var errorFrame = new Frame
+ {
+ Type = FrameType.Response,
+ CorrelationId = frame.CorrelationId,
+ Payload = _serializer.SerializeResponse(errorResponse),
+ Flags = FrameFlags.Final | FrameFlags.Error
+ };
+
+ await _channel.ServiceWriter.WriteAsync(errorFrame, cancellationToken);
+ }
+ }
+
+ private async Task HandleHeartbeatAsync(Frame frame)
+ {
+ if (_channel == null) return;
+
+ var pongFrame = new Frame
+ {
+ Type = FrameType.Heartbeat,
+ CorrelationId = frame.CorrelationId,
+ Payload = frame.Payload // Echo back
+ };
+
+ await _channel.ServiceWriter.WriteAsync(pongFrame);
+ }
+
+ public async Task DisconnectAsync()
+ {
+ _cts?.Cancel();
+
+ if (_processingTask != null)
+ {
+ try
+ {
+ await _processingTask.WaitAsync(TimeSpan.FromSeconds(5));
+ }
+ catch (TimeoutException)
+ {
+ _logger.LogWarning("InMemory processing task did not complete in time");
+ }
+ }
+
+ if (_channel != null)
+ {
+ await _hub.RemoveChannelAsync(_channel.ChannelId);
+ }
+
+ _cts?.Dispose();
+ }
+
+ public async Task SendHeartbeatAsync(CancellationToken cancellationToken)
+ {
+ if (_channel == null || _channel.State != ConnectionState.Connected)
+ return;
+
+ var heartbeatFrame = new Frame
+ {
+ Type = FrameType.Heartbeat,
+ CorrelationId = Guid.NewGuid().ToString("N"),
+ Payload = BitConverter.GetBytes(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds())
+ };
+
+ await _channel.ServiceWriter.WriteAsync(heartbeatFrame, cancellationToken);
+ }
+}
+```
+
+---
+
+## Integration with Global Routing State
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory;
+
+///
+/// InMemory transport integration with gateway routing state.
+///
+public sealed class InMemoryRoutingIntegration : IHostedService
+{
+ private readonly InMemoryTransportHub _hub;
+ private readonly IGlobalRoutingState _routingState;
+ private readonly ILogger _logger;
+ private Timer? _syncTimer;
+
+ public InMemoryRoutingIntegration(
+ InMemoryTransportHub hub,
+ IGlobalRoutingState routingState,
+ ILogger logger)
+ {
+ _hub = hub;
+ _routingState = routingState;
+ _logger = logger;
+ }
+
+ public Task StartAsync(CancellationToken cancellationToken)
+ {
+ // Sync InMemory channels with routing state periodically
+ _syncTimer = new Timer(SyncChannels, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
+ return Task.CompletedTask;
+ }
+
+ private void SyncChannels(object? state)
+ {
+ try
+ {
+ foreach (var channel in _hub.GetAllChannels())
+ {
+ var connection = new EndpointConnection
+ {
+ ServiceName = channel.ServiceName,
+ InstanceId = channel.InstanceId,
+ ConnectionId = channel.ChannelId,
+ Transport = "InMemory",
+ State = channel.State,
+ LastHeartbeat = channel.LastActivityAt
+ };
+
+ _routingState.UpdateConnection(connection);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error syncing InMemory channels");
+ }
+ }
+
+ public Task StopAsync(CancellationToken cancellationToken)
+ {
+ _syncTimer?.Dispose();
+ return Task.CompletedTask;
+ }
+}
+```
+
+---
+
+## Service Registration
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory;
+
+public static class InMemoryTransportExtensions
+{
+ ///
+ /// Adds InMemory transport to the gateway.
+ ///
+ public static IServiceCollection AddInMemoryTransport(this IServiceCollection services)
+ {
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddHostedService();
+
+ return services;
+ }
+
+ ///
+ /// Adds InMemory transport to a microservice.
+ ///
+ public static IServiceCollection AddInMemoryMicroserviceTransport(
+ this IServiceCollection services,
+ Action? configure = null)
+ {
+ var options = new InMemoryTransportOptions();
+ configure?.Invoke(options);
+
+ services.AddSingleton(options);
+ services.AddSingleton();
+
+ return services;
+ }
+}
+
+public class InMemoryTransportOptions
+{
+ public int MaxPendingRequests { get; set; } = 1000;
+ public TimeSpan ConnectionTimeout { get; set; } = TimeSpan.FromSeconds(30);
+}
+```
+
+---
+
+## Testing Utilities
+
+```csharp
+namespace StellaOps.Router.Transport.InMemory.Testing;
+
+///
+/// Test fixture for InMemory transport testing.
+///
+public sealed class InMemoryTransportFixture : IAsyncDisposable
+{
+ private readonly InMemoryTransportHub _hub;
+ private readonly ILoggerFactory _loggerFactory;
+
+ public InMemoryTransportHub Hub => _hub;
+
+ public InMemoryTransportFixture()
+ {
+ _loggerFactory = LoggerFactory.Create(b => b.AddConsole());
+ _hub = new InMemoryTransportHub(_loggerFactory.CreateLogger());
+ }
+
+ public InMemoryTransportClient CreateClient()
+ {
+ var serializer = new MessagePackPayloadSerializer();
+ return new InMemoryTransportClient(
+ _hub,
+ serializer,
+ _loggerFactory.CreateLogger());
+ }
+
+ public InMemoryTransportServer CreateServer()
+ {
+ var serializer = new MessagePackPayloadSerializer();
+ return new InMemoryTransportServer(
+ _hub,
+ serializer,
+ _loggerFactory.CreateLogger());
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ _hub.Dispose();
+ _loggerFactory.Dispose();
+ }
+}
+```
+
+---
+
+## Unit Tests
+
+```csharp
+public class InMemoryTransportTests
+{
+ [Fact]
+ public async Task SimpleRequestResponse_Works()
+ {
+ await using var fixture = new InMemoryTransportFixture();
+ var client = fixture.CreateClient();
+ var server = fixture.CreateServer();
+
+ // Setup server
+ server.OnRequest += (request, ct) => Task.FromResult(new ResponsePayload
+ {
+ StatusCode = 200,
+ Headers = new Dictionary(),
+ Body = Encoding.UTF8.GetBytes($"Hello {request.Path}")
+ });
+
+ await server.ConnectAsync("test-service", "instance-1", Array.Empty(), default);
+
+ // Send request
+ var response = await client.SendRequestAsync(
+ "test-service",
+ new RequestPayload
+ {
+ Method = "GET",
+ Path = "/test",
+ Headers = new Dictionary(),
+ Claims = new Dictionary()
+ },
+ TimeSpan.FromSeconds(5),
+ default);
+
+ Assert.Equal(200, response.StatusCode);
+ Assert.Equal("Hello /test", Encoding.UTF8.GetString(response.Body!));
+ }
+
+ [Fact]
+ public async Task Cancellation_SendsCancelFrame()
+ {
+ await using var fixture = new InMemoryTransportFixture();
+ var client = fixture.CreateClient();
+ var server = fixture.CreateServer();
+
+ var cancelReceived = new TaskCompletionSource();
+
+ server.OnRequest += async (request, ct) =>
+ {
+ await Task.Delay(TimeSpan.FromSeconds(30), ct);
+ return new ResponsePayload { StatusCode = 200, Headers = new Dictionary() };
+ };
+
+ server.OnCancel += (correlationId, ct) =>
+ {
+ cancelReceived.TrySetResult(true);
+ return Task.CompletedTask;
+ };
+
+ await server.ConnectAsync("test-service", "instance-1", Array.Empty(), default);
+
+ // Send request with short timeout
+ await Assert.ThrowsAsync(() =>
+ client.SendRequestAsync(
+ "test-service",
+ new RequestPayload { Method = "GET", Path = "/slow", Headers = new Dictionary(), Claims = new Dictionary() },
+ TimeSpan.FromMilliseconds(100),
+ default));
+
+ // Verify cancel was received
+ var result = await cancelReceived.Task.WaitAsync(TimeSpan.FromSeconds(1));
+ Assert.True(result);
+ }
+
+ [Fact]
+ public async Task MultipleInstances_DistributesRequests()
+ {
+ await using var fixture = new InMemoryTransportFixture();
+ var client = fixture.CreateClient();
+ var server1 = fixture.CreateServer();
+ var server2 = fixture.CreateServer();
+
+ var server1Count = 0;
+ var server2Count = 0;
+
+ server1.OnRequest += (r, ct) =>
+ {
+ Interlocked.Increment(ref server1Count);
+ return Task.FromResult(new ResponsePayload { StatusCode = 200, Headers = new Dictionary() });
+ };
+
+ server2.OnRequest += (r, ct) =>
+ {
+ Interlocked.Increment(ref server2Count);
+ return Task.FromResult(new ResponsePayload { StatusCode = 200, Headers = new Dictionary() });
+ };
+
+ await server1.ConnectAsync("test-service", "instance-1", Array.Empty(), default);
+ await server2.ConnectAsync("test-service", "instance-2", Array.Empty(), default);
+
+ // Send multiple requests
+ for (int i = 0; i < 100; i++)
+ {
+ await client.SendRequestAsync(
+ "test-service",
+ new RequestPayload { Method = "GET", Path = "/test", Headers = new Dictionary(), Claims = new Dictionary() },
+ TimeSpan.FromSeconds(5),
+ default);
+ }
+
+ // Both instances should have received requests
+ Assert.True(server1Count > 0);
+ Assert.True(server2Count > 0);
+ Assert.Equal(100, server1Count + server2Count);
+ }
+}
+```
+
+---
+
+## Deliverables
+
+1. `StellaOps.Router.Transport.InMemory/InMemoryChannel.cs`
+2. `StellaOps.Router.Transport.InMemory/InMemoryTransportHub.cs`
+3. `StellaOps.Router.Transport.InMemory/InMemoryTransportClient.cs`
+4. `StellaOps.Router.Transport.InMemory/InMemoryTransportServer.cs`
+5. `StellaOps.Router.Transport.InMemory/InMemoryRoutingIntegration.cs`
+6. `StellaOps.Router.Transport.InMemory/InMemoryTransportExtensions.cs`
+7. `StellaOps.Router.Transport.InMemory.Testing/InMemoryTransportFixture.cs`
+8. Unit tests for all frame types
+9. Integration tests for request/response patterns
+10. Streaming tests
+
+---
+
+## Next Step
+
+Proceed to [Step 14: TCP Transport Implementation](14-Step.md) to implement the primary production transport.
diff --git a/docs/router/14-Step.md b/docs/router/14-Step.md
new file mode 100644
index 000000000..4d202d568
--- /dev/null
+++ b/docs/router/14-Step.md
@@ -0,0 +1,1054 @@
+# Step 14: TCP Transport Implementation
+
+**Phase 3: Transport Layer**
+**Estimated Complexity:** High
+**Dependencies:** Step 13 (InMemory Transport)
+
+---
+
+## Overview
+
+The TCP transport is the primary production transport for connecting microservices to the gateway. It provides reliable, ordered frame delivery over persistent connections with efficient binary framing, connection multiplexing, and automatic reconnection.
+
+---
+
+## Goals
+
+1. Implement efficient binary frame encoding over TCP
+2. Support connection multiplexing for high throughput
+3. Implement automatic reconnection with exponential backoff
+4. Handle partial reads/writes correctly
+5. Integrate with .NET's socket pooling and buffer management
+
+---
+
+## Wire Protocol
+
+### Frame Layout
+
+```
+┌────────────────────────────────────────────────────────────────┐
+│ TCP Frame Format │
+├──────────┬──────────┬──────────┬──────────┬───────────────────┤
+│ Magic │ Flags │ Type │ Length │ Correlation │
+│ (2B) │ (1B) │ (1B) │ (4B) │ ID (16B) │
+├──────────┴──────────┴──────────┴──────────┴───────────────────┤
+│ Payload │
+│ (Length bytes) │
+└────────────────────────────────────────────────────────────────┘
+
+Total Header: 24 bytes
+Magic: 0x53 0x52 ("SR" - Stella Router)
+Flags: Compression, Final, Error
+Type: Hello=1, Heartbeat=2, Request=3, Response=4, Cancel=5
+Length: uint32, big-endian (max 16MB)
+Correlation ID: 16 bytes (GUID)
+Payload: Variable length
+```
+
+---
+
+## Core Types
+
+### TCP Frame Codec
+
+```csharp
+namespace StellaOps.Router.Transport.Tcp;
+
+///
+/// Encodes and decodes frames for TCP wire format.
+///
+public sealed class TcpFrameCodec
+{
+ private const ushort Magic = 0x5352; // "SR"
+ private const int HeaderSize = 24;
+ private const int MaxPayloadSize = 16 * 1024 * 1024; // 16MB
+
+ private readonly ArrayPool _bufferPool;
+
+ public TcpFrameCodec(ArrayPool? bufferPool = null)
+ {
+ _bufferPool = bufferPool ?? ArrayPool.Shared;
+ }
+
+ ///
+ /// Encodes a frame to wire format.
+ ///
+ public int Encode(Frame frame, Span destination)
+ {
+ if (destination.Length < HeaderSize + frame.Payload.Length)
+ throw new ArgumentException("Destination buffer too small");
+
+ var offset = 0;
+
+ // Magic (2 bytes)
+ BinaryPrimitives.WriteUInt16BigEndian(destination[offset..], Magic);
+ offset += 2;
+
+ // Flags (1 byte)
+ destination[offset++] = (byte)frame.Flags;
+
+ // Type (1 byte)
+ destination[offset++] = (byte)frame.Type;
+
+ // Length (4 bytes)
+ BinaryPrimitives.WriteUInt32BigEndian(destination[offset..], (uint)frame.Payload.Length);
+ offset += 4;
+
+ // Correlation ID (16 bytes)
+ if (Guid.TryParse(frame.CorrelationId, out var guid))
+ {
+ guid.TryWriteBytes(destination[offset..]);
+ }
+ offset += 16;
+
+ // Payload
+ frame.Payload.AsSpan().CopyTo(destination[offset..]);
+ offset += frame.Payload.Length;
+
+ return offset;
+ }
+
+ ///
+ /// Decodes a frame from wire format.
+ ///
+ public Frame Decode(ReadOnlySpan source)
+ {
+ if (source.Length < HeaderSize)
+ throw new ProtocolException("Incomplete frame header");
+
+ var offset = 0;
+
+ // Magic
+ var magic = BinaryPrimitives.ReadUInt16BigEndian(source[offset..]);
+ if (magic != Magic)
+ throw new ProtocolException($"Invalid magic: 0x{magic:X4}");
+ offset += 2;
+
+ // Flags
+ var flags = (FrameFlags)source[offset++];
+
+ // Type
+ var type = (FrameType)source[offset++];
+
+ // Length
+ var length = BinaryPrimitives.ReadUInt32BigEndian(source[offset..]);
+ if (length > MaxPayloadSize)
+ throw new ProtocolException($"Payload too large: {length}");
+ offset += 4;
+
+ // Correlation ID
+ var correlationId = new Guid(source.Slice(offset, 16)).ToString("N");
+ offset += 16;
+
+ // Verify we have full payload
+ if (source.Length < HeaderSize + length)
+ throw new ProtocolException("Incomplete payload");
+
+ // Payload
+ var payload = source.Slice(offset, (int)length).ToArray();
+
+ return new Frame
+ {
+ Type = type,
+ Flags = flags,
+ CorrelationId = correlationId,
+ Payload = payload
+ };
+ }
+
+ ///
+ /// Attempts to decode a frame from a buffer, returning bytes consumed.
+ ///
+ public bool TryDecode(ReadOnlySequence buffer, out Frame frame, out int bytesConsumed)
+ {
+ frame = default!;
+ bytesConsumed = 0;
+
+ if (buffer.Length < HeaderSize)
+ return false;
+
+ // Read header to get length
+ Span header = stackalloc byte[HeaderSize];
+ buffer.Slice(0, HeaderSize).CopyTo(header);
+
+ var length = BinaryPrimitives.ReadUInt32BigEndian(header[4..]);
+ var totalLength = HeaderSize + (int)length;
+
+ if (buffer.Length < totalLength)
+ return false;
+
+ // Decode full frame
+ var frameBytes = new byte[totalLength];
+ buffer.Slice(0, totalLength).CopyTo(frameBytes);
+ frame = Decode(frameBytes);
+ bytesConsumed = totalLength;
+
+ return true;
+ }
+}
+```
+
+### TCP Connection
+
+```csharp
+namespace StellaOps.Router.Transport.Tcp;
+
+///
+/// Represents a TCP connection with frame-based I/O.
+///
+public sealed class TcpFrameConnection : IAsyncDisposable
+{
+ private readonly Socket _socket;
+ private readonly NetworkStream _stream;
+ private readonly TcpFrameCodec _codec;
+ private readonly ILogger _logger;
+ private readonly SemaphoreSlim _writeLock = new(1, 1);
+ private readonly byte[] _readBuffer;
+ private readonly byte[] _writeBuffer;
+ private int _readBufferOffset;
+ private int _readBufferCount;
+
+ public string ConnectionId { get; }
+ public EndPoint? RemoteEndPoint => _socket.RemoteEndPoint;
+ public bool IsConnected => _socket.Connected;
+
+ public TcpFrameConnection(
+ Socket socket,
+ TcpFrameCodec codec,
+ ILogger logger)
+ {
+ _socket = socket;
+ _stream = new NetworkStream(socket, ownsSocket: false);
+ _codec = codec;
+ _logger = logger;
+ _readBuffer = new byte[64 * 1024]; // 64KB read buffer
+ _writeBuffer = new byte[64 * 1024]; // 64KB write buffer
+ ConnectionId = Guid.NewGuid().ToString("N");
+
+ // Configure socket options
+ _socket.NoDelay = true; // Disable Nagle's algorithm
+ _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
+ }
+
+ ///
+ /// Sends a frame over the connection.
+ ///
+ public async ValueTask SendAsync(Frame frame, CancellationToken cancellationToken)
+ {
+ await _writeLock.WaitAsync(cancellationToken);
+ try
+ {
+ var size = _codec.Encode(frame, _writeBuffer);
+ await _stream.WriteAsync(_writeBuffer.AsMemory(0, size), cancellationToken);
+ await _stream.FlushAsync(cancellationToken);
+ }
+ finally
+ {
+ _writeLock.Release();
+ }
+ }
+
+ ///
+ /// Receives a frame from the connection.
+ ///
+ public async ValueTask ReceiveAsync(CancellationToken cancellationToken)
+ {
+ while (true)
+ {
+ // Try to decode from existing buffer
+ if (_readBufferCount >= 24) // Minimum header size
+ {
+ var span = new ReadOnlySpan(_readBuffer, _readBufferOffset, _readBufferCount);
+
+ // Check if we have a complete frame
+ if (span.Length >= 8)
+ {
+ var payloadLength = BinaryPrimitives.ReadUInt32BigEndian(span[4..]);
+ var totalLength = 24 + (int)payloadLength;
+
+ if (span.Length >= totalLength)
+ {
+ var frame = _codec.Decode(span[..totalLength]);
+ _readBufferOffset += totalLength;
+ _readBufferCount -= totalLength;
+
+ // Compact buffer if needed
+ if (_readBufferOffset > _readBuffer.Length / 2)
+ {
+ Buffer.BlockCopy(_readBuffer, _readBufferOffset, _readBuffer, 0, _readBufferCount);
+ _readBufferOffset = 0;
+ }
+
+ return frame;
+ }
+ }
+ }
+
+ // Need more data
+ if (_readBufferOffset + _readBufferCount >= _readBuffer.Length)
+ {
+ // Compact buffer
+ Buffer.BlockCopy(_readBuffer, _readBufferOffset, _readBuffer, 0, _readBufferCount);
+ _readBufferOffset = 0;
+ }
+
+ var bytesRead = await _stream.ReadAsync(
+ _readBuffer.AsMemory(_readBufferOffset + _readBufferCount),
+ cancellationToken);
+
+ if (bytesRead == 0)
+ {
+ throw new EndOfStreamException("Connection closed by remote");
+ }
+
+ _readBufferCount += bytesRead;
+ }
+ }
+
+ ///
+ /// Receives frames as an async enumerable.
+ ///
+ public async IAsyncEnumerable ReceiveAllAsync(
+ [EnumeratorCancellation] CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ Frame frame;
+ try
+ {
+ frame = await ReceiveAsync(cancellationToken);
+ }
+ catch (EndOfStreamException)
+ {
+ yield break;
+ }
+ catch (OperationCanceledException)
+ {
+ yield break;
+ }
+
+ yield return frame;
+ }
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ _writeLock.Dispose();
+ await _stream.DisposeAsync();
+ _socket.Dispose();
+ }
+}
+```
+
+---
+
+## Gateway-Side TCP Server
+
+```csharp
+namespace StellaOps.Router.Transport.Tcp;
+
+///
+/// TCP server running on the gateway to accept microservice connections.
+///
+public sealed class TcpTransportServer : IHostedService
+{
+ private readonly TcpTransportConfig _config;
+ private readonly TcpFrameCodec _codec;
+ private readonly IGlobalRoutingState _routingState;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private Socket? _listener;
+ private CancellationTokenSource? _cts;
+ private readonly ConcurrentDictionary _connections = new();
+
+ public TcpTransportServer(
+ IOptions config,
+ TcpFrameCodec codec,
+ IGlobalRoutingState routingState,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _config = config.Value;
+ _codec = codec;
+ _routingState = routingState;
+ _serializer = serializer;
+ _logger = logger;
+ }
+
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ _cts = new CancellationTokenSource();
+
+ _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ _listener.Bind(new IPEndPoint(IPAddress.Parse(_config.ListenAddress), _config.Port));
+ _listener.Listen(_config.Backlog);
+
+ _logger.LogInformation(
+ "TCP transport server listening on {Address}:{Port}",
+ _config.ListenAddress, _config.Port);
+
+ _ = AcceptConnectionsAsync(_cts.Token);
+ }
+
+ private async Task AcceptConnectionsAsync(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ var socket = await _listener!.AcceptAsync(cancellationToken);
+ _logger.LogDebug("Accepted connection from {RemoteEndPoint}", socket.RemoteEndPoint);
+
+ _ = HandleConnectionAsync(socket, cancellationToken);
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error accepting connection");
+ }
+ }
+ }
+
+ private async Task HandleConnectionAsync(Socket socket, CancellationToken cancellationToken)
+ {
+ var connection = new TcpFrameConnection(socket, _codec, _logger);
+
+ try
+ {
+ // Wait for HELLO frame
+ var helloFrame = await connection.ReceiveAsync(cancellationToken)
+ .AsTask()
+ .WaitAsync(TimeSpan.FromSeconds(_config.HandshakeTimeoutSeconds), cancellationToken);
+
+ if (helloFrame.Type != FrameType.Hello)
+ {
+ _logger.LogWarning("Expected HELLO frame, got {Type}", helloFrame.Type);
+ return;
+ }
+
+ var hello = _serializer.DeserializeHello(helloFrame.Payload);
+ _logger.LogInformation(
+ "Microservice connected: {ServiceName}/{InstanceId}",
+ hello.ServiceName, hello.InstanceId);
+
+ // Send HELLO response
+ var helloResponse = new HelloResponse
+ {
+ Accepted = true,
+ HeartbeatIntervalMs = _config.HeartbeatIntervalMs,
+ MaxPayloadSize = _config.MaxPayloadSize
+ };
+
+ var responseFrame = new Frame
+ {
+ Type = FrameType.Hello,
+ CorrelationId = helloFrame.CorrelationId,
+ Payload = _serializer.SerializeHelloResponse(helloResponse)
+ };
+ await connection.SendAsync(responseFrame, cancellationToken);
+
+ // Create connection wrapper
+ var msConnection = new TcpMicroserviceConnection(
+ connection,
+ hello.ServiceName,
+ hello.InstanceId,
+ hello.Endpoints,
+ _serializer,
+ _logger);
+
+ _connections[connection.ConnectionId] = msConnection;
+
+ // Register with routing state
+ _routingState.RegisterConnection(new EndpointConnection
+ {
+ ConnectionId = connection.ConnectionId,
+ ServiceName = hello.ServiceName,
+ InstanceId = hello.InstanceId,
+ Transport = "TCP",
+ State = ConnectionState.Connected,
+ Endpoints = hello.Endpoints,
+ Region = hello.Metadata?.GetValueOrDefault("region"),
+ LastHeartbeat = DateTimeOffset.UtcNow
+ });
+
+ // Process frames
+ await msConnection.ProcessAsync(cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error handling connection {ConnectionId}", connection.ConnectionId);
+ }
+ finally
+ {
+ _connections.TryRemove(connection.ConnectionId, out _);
+ _routingState.RemoveConnection(connection.ConnectionId);
+ await connection.DisposeAsync();
+ }
+ }
+
+ ///
+ /// Gets a connection for sending requests to a service instance.
+ ///
+ public TcpMicroserviceConnection? GetConnection(string connectionId)
+ {
+ return _connections.TryGetValue(connectionId, out var conn) ? conn : null;
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken)
+ {
+ _cts?.Cancel();
+ _listener?.Close();
+
+ foreach (var connection in _connections.Values)
+ {
+ await connection.DisconnectAsync();
+ }
+
+ _cts?.Dispose();
+ }
+}
+
+///
+/// Represents an active microservice connection.
+///
+public sealed class TcpMicroserviceConnection
+{
+ private readonly TcpFrameConnection _connection;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private readonly ConcurrentDictionary> _pendingRequests = new();
+ private DateTimeOffset _lastActivity;
+
+ public string ServiceName { get; }
+ public string InstanceId { get; }
+ public EndpointDescriptor[] Endpoints { get; }
+ public DateTimeOffset LastActivity => _lastActivity;
+
+ public TcpMicroserviceConnection(
+ TcpFrameConnection connection,
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _connection = connection;
+ ServiceName = serviceName;
+ InstanceId = instanceId;
+ Endpoints = endpoints;
+ _serializer = serializer;
+ _logger = logger;
+ _lastActivity = DateTimeOffset.UtcNow;
+ }
+
+ public async Task ProcessAsync(CancellationToken cancellationToken)
+ {
+ await foreach (var frame in _connection.ReceiveAllAsync(cancellationToken))
+ {
+ _lastActivity = DateTimeOffset.UtcNow;
+
+ switch (frame.Type)
+ {
+ case FrameType.Response:
+ if (_pendingRequests.TryRemove(frame.CorrelationId, out var tcs))
+ {
+ tcs.TrySetResult(frame);
+ }
+ break;
+
+ case FrameType.Heartbeat:
+ // Microservice sent heartbeat response
+ break;
+ }
+ }
+ }
+
+ public async Task SendRequestAsync(
+ RequestPayload request,
+ TimeSpan timeout,
+ CancellationToken cancellationToken)
+ {
+ var correlationId = Guid.NewGuid().ToString("N");
+ var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ _pendingRequests[correlationId] = tcs;
+
+ try
+ {
+ var frame = new Frame
+ {
+ Type = FrameType.Request,
+ CorrelationId = correlationId,
+ Payload = _serializer.SerializeRequest(request)
+ };
+
+ await _connection.SendAsync(frame, cancellationToken);
+
+ using var timeoutCts = new CancellationTokenSource(timeout);
+ using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
+
+ try
+ {
+ var responseFrame = await tcs.Task.WaitAsync(linkedCts.Token);
+ return _serializer.DeserializeResponse(responseFrame.Payload);
+ }
+ catch (OperationCanceledException) when (timeoutCts.IsCancellationRequested)
+ {
+ // Send cancel
+ await SendCancelAsync(correlationId, CancellationToken.None);
+ throw new TimeoutException($"Request timed out after {timeout}");
+ }
+ }
+ finally
+ {
+ _pendingRequests.TryRemove(correlationId, out _);
+ }
+ }
+
+ private async Task SendCancelAsync(string correlationId, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var cancelFrame = new Frame
+ {
+ Type = FrameType.Cancel,
+ CorrelationId = correlationId,
+ Payload = Array.Empty()
+ };
+ await _connection.SendAsync(cancelFrame, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning(ex, "Failed to send cancel frame");
+ }
+ }
+
+ public async Task DisconnectAsync()
+ {
+ foreach (var pending in _pendingRequests.Values)
+ {
+ pending.TrySetCanceled();
+ }
+ _pendingRequests.Clear();
+ await _connection.DisposeAsync();
+ }
+}
+```
+
+---
+
+## Microservice-Side TCP Client
+
+```csharp
+namespace StellaOps.Router.Transport.Tcp;
+
+///
+/// TCP client for microservices to connect to the gateway.
+///
+public sealed class TcpTransportClient : ITransportServer, IAsyncDisposable
+{
+ private readonly TcpClientConfig _config;
+ private readonly TcpFrameCodec _codec;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private TcpFrameConnection? _connection;
+ private CancellationTokenSource? _cts;
+ private Task? _processingTask;
+ private int _reconnectAttempts;
+
+ public string TransportType => "TCP";
+ public bool IsConnected => _connection?.IsConnected ?? false;
+
+ public event Func>? OnRequest;
+ public event Func? OnCancel;
+
+ public TcpTransportClient(
+ IOptions config,
+ TcpFrameCodec codec,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _config = config.Value;
+ _codec = codec;
+ _serializer = serializer;
+ _logger = logger;
+ }
+
+ public async Task ConnectAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ _cts = new CancellationTokenSource();
+
+ await ConnectWithRetryAsync(serviceName, instanceId, endpoints, cancellationToken);
+
+ // Start processing loop
+ _processingTask = ProcessFramesAsync(serviceName, instanceId, endpoints, _cts.Token);
+ }
+
+ private async Task ConnectWithRetryAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+ await socket.ConnectAsync(_config.GatewayHost, _config.GatewayPort, cancellationToken);
+
+ _connection = new TcpFrameConnection(socket, _codec, _logger);
+
+ // Send HELLO
+ var hello = new HelloPayload
+ {
+ ServiceName = serviceName,
+ InstanceId = instanceId,
+ Endpoints = endpoints,
+ Metadata = new Dictionary
+ {
+ ["region"] = _config.Region ?? "default",
+ ["version"] = _config.ServiceVersion ?? "1.0.0"
+ }
+ };
+
+ var helloFrame = new Frame
+ {
+ Type = FrameType.Hello,
+ CorrelationId = Guid.NewGuid().ToString("N"),
+ Payload = _serializer.SerializeHello(hello)
+ };
+
+ await _connection.SendAsync(helloFrame, cancellationToken);
+
+ // Wait for response
+ var response = await _connection.ReceiveAsync(cancellationToken);
+ if (response.Type != FrameType.Hello)
+ {
+ throw new ProtocolException($"Expected HELLO response, got {response.Type}");
+ }
+
+ _reconnectAttempts = 0;
+ _logger.LogInformation(
+ "Connected to gateway at {Host}:{Port}",
+ _config.GatewayHost, _config.GatewayPort);
+
+ return;
+ }
+ catch (Exception ex) when (!cancellationToken.IsCancellationRequested)
+ {
+ _reconnectAttempts++;
+ var delay = Math.Min(
+ _config.InitialReconnectDelayMs * Math.Pow(2, _reconnectAttempts - 1),
+ _config.MaxReconnectDelayMs);
+
+ _logger.LogWarning(
+ ex,
+ "Connection attempt {Attempt} failed, retrying in {Delay}ms",
+ _reconnectAttempts, delay);
+
+ await Task.Delay((int)delay, cancellationToken);
+ }
+ }
+ }
+
+ private async Task ProcessFramesAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ if (_connection == null || !_connection.IsConnected)
+ {
+ await ConnectWithRetryAsync(serviceName, instanceId, endpoints, cancellationToken);
+ }
+
+ await foreach (var frame in _connection!.ReceiveAllAsync(cancellationToken))
+ {
+ switch (frame.Type)
+ {
+ case FrameType.Request:
+ _ = HandleRequestAsync(frame, cancellationToken);
+ break;
+
+ case FrameType.Cancel:
+ if (OnCancel != null)
+ {
+ await OnCancel(frame.CorrelationId, cancellationToken);
+ }
+ break;
+
+ case FrameType.Heartbeat:
+ await HandleHeartbeatAsync(frame);
+ break;
+ }
+ }
+ }
+ catch (EndOfStreamException)
+ {
+ _logger.LogWarning("Connection closed, attempting reconnect");
+ _connection = null;
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error processing frames");
+ _connection = null;
+ }
+ }
+ }
+
+ private async Task HandleRequestAsync(Frame frame, CancellationToken cancellationToken)
+ {
+ if (_connection == null || OnRequest == null) return;
+
+ try
+ {
+ var request = _serializer.DeserializeRequest(frame.Payload);
+ var response = await OnRequest(request, cancellationToken);
+
+ var responseFrame = new Frame
+ {
+ Type = FrameType.Response,
+ CorrelationId = frame.CorrelationId,
+ Payload = _serializer.SerializeResponse(response),
+ Flags = FrameFlags.Final
+ };
+
+ await _connection.SendAsync(responseFrame, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error handling request");
+
+ var errorResponse = new ResponsePayload
+ {
+ StatusCode = 500,
+ Headers = new Dictionary(),
+ ErrorMessage = ex.Message,
+ IsFinalChunk = true
+ };
+
+ var errorFrame = new Frame
+ {
+ Type = FrameType.Response,
+ CorrelationId = frame.CorrelationId,
+ Payload = _serializer.SerializeResponse(errorResponse),
+ Flags = FrameFlags.Final | FrameFlags.Error
+ };
+
+ await _connection.SendAsync(errorFrame, cancellationToken);
+ }
+ }
+
+ private async Task HandleHeartbeatAsync(Frame frame)
+ {
+ if (_connection == null) return;
+
+ var pongFrame = new Frame
+ {
+ Type = FrameType.Heartbeat,
+ CorrelationId = frame.CorrelationId,
+ Payload = frame.Payload
+ };
+
+ await _connection.SendAsync(pongFrame, CancellationToken.None);
+ }
+
+ public async Task DisconnectAsync()
+ {
+ _cts?.Cancel();
+
+ if (_processingTask != null)
+ {
+ try
+ {
+ await _processingTask.WaitAsync(TimeSpan.FromSeconds(5));
+ }
+ catch { }
+ }
+
+ if (_connection != null)
+ {
+ await _connection.DisposeAsync();
+ }
+
+ _cts?.Dispose();
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ await DisconnectAsync();
+ }
+}
+```
+
+---
+
+## Configuration
+
+```csharp
+namespace StellaOps.Router.Transport.Tcp;
+
+public class TcpTransportConfig
+{
+ public string ListenAddress { get; set; } = "0.0.0.0";
+ public int Port { get; set; } = 9500;
+ public int Backlog { get; set; } = 100;
+ public int HandshakeTimeoutSeconds { get; set; } = 30;
+ public int HeartbeatIntervalMs { get; set; } = 10000;
+ public int MaxPayloadSize { get; set; } = 16 * 1024 * 1024;
+}
+
+public class TcpClientConfig
+{
+ public string GatewayHost { get; set; } = "localhost";
+ public int GatewayPort { get; set; } = 9500;
+ public string? Region { get; set; }
+ public string? ServiceVersion { get; set; }
+ public int InitialReconnectDelayMs { get; set; } = 1000;
+ public int MaxReconnectDelayMs { get; set; } = 30000;
+ public int ConnectionTimeoutMs { get; set; } = 10000;
+}
+```
+
+---
+
+## YAML Configuration
+
+```yaml
+# Gateway config
+TcpTransport:
+ ListenAddress: "0.0.0.0"
+ Port: 9500
+ Backlog: 100
+ HandshakeTimeoutSeconds: 30
+ HeartbeatIntervalMs: 10000
+ MaxPayloadSize: 16777216 # 16MB
+
+# Microservice config
+TcpClient:
+ GatewayHost: "gateway.internal"
+ GatewayPort: 9500
+ Region: "us-east-1"
+ ServiceVersion: "1.0.0"
+ InitialReconnectDelayMs: 1000
+ MaxReconnectDelayMs: 30000
+```
+
+---
+
+## Service Registration
+
+```csharp
+namespace StellaOps.Router.Transport.Tcp;
+
+public static class TcpTransportExtensions
+{
+ public static IServiceCollection AddTcpTransport(
+ this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ services.Configure(
+ configuration.GetSection("TcpTransport"));
+
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddHostedService(sp => sp.GetRequiredService());
+
+ return services;
+ }
+
+ public static IServiceCollection AddTcpMicroserviceTransport(
+ this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ services.Configure(
+ configuration.GetSection("TcpClient"));
+
+ services.AddSingleton();
+ services.AddSingleton();
+
+ return services;
+ }
+}
+```
+
+---
+
+## Unit Tests
+
+```csharp
+public class TcpFrameCodecTests
+{
+ [Fact]
+ public void Encode_Decode_RoundTrips()
+ {
+ var codec = new TcpFrameCodec();
+ var original = new Frame
+ {
+ Type = FrameType.Request,
+ CorrelationId = Guid.NewGuid().ToString("N"),
+ Payload = Encoding.UTF8.GetBytes("test payload"),
+ Flags = FrameFlags.Compressed
+ };
+
+ var buffer = new byte[1024];
+ var length = codec.Encode(original, buffer);
+ var decoded = codec.Decode(buffer.AsSpan(0, length));
+
+ Assert.Equal(original.Type, decoded.Type);
+ Assert.Equal(original.CorrelationId, decoded.CorrelationId);
+ Assert.Equal(original.Payload, decoded.Payload);
+ Assert.Equal(original.Flags, decoded.Flags);
+ }
+
+ [Fact]
+ public void Decode_ThrowsOnInvalidMagic()
+ {
+ var codec = new TcpFrameCodec();
+ var buffer = new byte[24];
+ buffer[0] = 0xFF;
+ buffer[1] = 0xFF;
+
+ Assert.Throws(() => codec.Decode(buffer));
+ }
+}
+```
+
+---
+
+## Deliverables
+
+1. `StellaOps.Router.Transport.Tcp/TcpFrameCodec.cs`
+2. `StellaOps.Router.Transport.Tcp/TcpFrameConnection.cs`
+3. `StellaOps.Router.Transport.Tcp/TcpTransportServer.cs`
+4. `StellaOps.Router.Transport.Tcp/TcpMicroserviceConnection.cs`
+5. `StellaOps.Router.Transport.Tcp/TcpTransportClient.cs`
+6. `StellaOps.Router.Transport.Tcp/TcpTransportConfig.cs`
+7. `StellaOps.Router.Transport.Tcp/TcpTransportExtensions.cs`
+8. Wire format encoding/decoding tests
+9. Connection lifecycle tests
+10. Reconnection tests
+
+---
+
+## Next Step
+
+Proceed to [Step 15: TLS Transport Implementation](15-Step.md) to add TLS encryption on top of TCP.
diff --git a/docs/router/15-Step.md b/docs/router/15-Step.md
new file mode 100644
index 000000000..a4098accb
--- /dev/null
+++ b/docs/router/15-Step.md
@@ -0,0 +1,1156 @@
+# Step 15: TLS Transport Implementation
+
+**Phase 3: Transport Layer**
+**Estimated Complexity:** Medium
+**Dependencies:** Step 14 (TCP Transport)
+
+---
+
+## Overview
+
+The TLS transport wraps TCP with mutual TLS (mTLS) authentication for secure microservice-to-gateway communication. It provides encryption, server/client authentication, and certificate-based identity for production deployments.
+
+---
+
+## Goals
+
+1. Add TLS encryption layer on top of TCP transport
+2. Support mutual TLS (mTLS) for bidirectional authentication
+3. Support certificate rotation without service restart
+4. Integrate with platform certificate stores and custom CAs
+5. Provide clear certificate validation error messages
+
+---
+
+## Core Architecture
+
+```
+┌──────────────────────────────────────────────────────────────┐
+│ TLS Transport Stack │
+├──────────────────────────────────────────────────────────────┤
+│ │
+│ ┌─────────────┐ ┌─────────────┐ │
+│ │ Microservice│ │ Gateway │ │
+│ │ Client │◄──── mTLS ────────►│ Server │ │
+│ └──────┬──────┘ └──────┬──────┘ │
+│ │ │ │
+│ ┌──────▼──────┐ ┌──────▼──────┐ │
+│ │ SslStream │ │ SslStream │ │
+│ └──────┬──────┘ └──────┬──────┘ │
+│ │ │ │
+│ ┌──────▼──────┐ ┌──────▼──────┐ │
+│ │ Socket │ │ Socket │ │
+│ └─────────────┘ └─────────────┘ │
+│ │
+└──────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Configuration
+
+```csharp
+namespace StellaOps.Router.Transport.Tls;
+
+public class TlsTransportConfig : TcpTransportConfig
+{
+ /// Path to server certificate PFX/P12 file.
+ public string? CertificatePath { get; set; }
+
+ /// Password for the certificate file.
+ public string? CertificatePassword { get; set; }
+
+ /// Thumbprint to load certificate from Windows certificate store.
+ public string? CertificateThumbprint { get; set; }
+
+ /// Store name for certificate lookup.
+ public string CertificateStoreName { get; set; } = "My";
+
+ /// Store location for certificate lookup.
+ public string CertificateStoreLocation { get; set; } = "CurrentUser";
+
+ /// Whether to require client certificates (mTLS).
+ public bool RequireClientCertificate { get; set; } = true;
+
+ /// Path to CA certificate for client validation.
+ public string? ClientCaCertificatePath { get; set; }
+
+ /// Allowed TLS protocols.
+ public SslProtocols AllowedProtocols { get; set; } = SslProtocols.Tls12 | SslProtocols.Tls13;
+
+ /// Certificate revocation check mode.
+ public X509RevocationMode RevocationMode { get; set; } = X509RevocationMode.Online;
+
+ /// Whether to allow untrusted root certificates (dev only).
+ public bool AllowUntrustedRootCertificates { get; set; } = false;
+}
+
+public class TlsClientConfig : TcpClientConfig
+{
+ /// Path to client certificate PFX/P12 file.
+ public string? ClientCertificatePath { get; set; }
+
+ /// Password for the client certificate file.
+ public string? ClientCertificatePassword { get; set; }
+
+ /// Thumbprint to load client certificate from store.
+ public string? ClientCertificateThumbprint { get; set; }
+
+ /// Expected server certificate CN/SAN for validation.
+ public string? ExpectedServerName { get; set; }
+
+ /// Path to CA certificate for server validation.
+ public string? ServerCaCertificatePath { get; set; }
+
+ /// Whether to skip server certificate validation (dev only).
+ public bool SkipServerCertificateValidation { get; set; } = false;
+}
+```
+
+---
+
+## Certificate Provider
+
+```csharp
+namespace StellaOps.Router.Transport.Tls;
+
+///
+/// Provides certificates for TLS connections with hot-reload support.
+///
+public interface ICertificateProvider
+{
+ /// Gets the current server certificate.
+ X509Certificate2? GetServerCertificate();
+
+ /// Gets the current client certificate.
+ X509Certificate2? GetClientCertificate();
+
+ /// Gets CA certificates for validation.
+ X509Certificate2Collection GetCaCertificates();
+
+ /// Event raised when certificates are reloaded.
+ event Action? CertificatesReloaded;
+}
+
+public sealed class CertificateProvider : ICertificateProvider, IDisposable
+{
+ private readonly TlsTransportConfig _serverConfig;
+ private readonly TlsClientConfig? _clientConfig;
+ private readonly ILogger _logger;
+ private readonly FileSystemWatcher? _fileWatcher;
+ private X509Certificate2? _serverCertificate;
+ private X509Certificate2? _clientCertificate;
+ private X509Certificate2Collection _caCertificates = new();
+
+ public event Action? CertificatesReloaded;
+
+ public CertificateProvider(
+ IOptions serverConfig,
+ IOptions? clientConfig,
+ ILogger logger)
+ {
+ _serverConfig = serverConfig.Value;
+ _clientConfig = clientConfig?.Value;
+ _logger = logger;
+
+ LoadCertificates();
+
+ // Watch for certificate file changes
+ if (!string.IsNullOrEmpty(_serverConfig.CertificatePath))
+ {
+ var dir = Path.GetDirectoryName(_serverConfig.CertificatePath);
+ if (dir != null && Directory.Exists(dir))
+ {
+ _fileWatcher = new FileSystemWatcher(dir)
+ {
+ Filter = "*.pfx",
+ NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime
+ };
+ _fileWatcher.Changed += OnCertificateFileChanged;
+ _fileWatcher.EnableRaisingEvents = true;
+ }
+ }
+ }
+
+ private void LoadCertificates()
+ {
+ try
+ {
+ // Load server certificate
+ _serverCertificate = LoadCertificate(
+ _serverConfig.CertificatePath,
+ _serverConfig.CertificatePassword,
+ _serverConfig.CertificateThumbprint,
+ _serverConfig.CertificateStoreName,
+ _serverConfig.CertificateStoreLocation);
+
+ if (_serverCertificate != null)
+ {
+ _logger.LogInformation(
+ "Loaded server certificate: Subject={Subject}, Expires={Expires}",
+ _serverCertificate.Subject,
+ _serverCertificate.NotAfter);
+ }
+
+ // Load client certificate
+ if (_clientConfig != null)
+ {
+ _clientCertificate = LoadCertificate(
+ _clientConfig.ClientCertificatePath,
+ _clientConfig.ClientCertificatePassword,
+ _clientConfig.ClientCertificateThumbprint,
+ "My",
+ "CurrentUser");
+ }
+
+ // Load CA certificates
+ _caCertificates = new X509Certificate2Collection();
+
+ if (!string.IsNullOrEmpty(_serverConfig.ClientCaCertificatePath) &&
+ File.Exists(_serverConfig.ClientCaCertificatePath))
+ {
+ _caCertificates.Add(new X509Certificate2(_serverConfig.ClientCaCertificatePath));
+ }
+
+ if (_clientConfig != null &&
+ !string.IsNullOrEmpty(_clientConfig.ServerCaCertificatePath) &&
+ File.Exists(_clientConfig.ServerCaCertificatePath))
+ {
+ _caCertificates.Add(new X509Certificate2(_clientConfig.ServerCaCertificatePath));
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Failed to load certificates");
+ throw;
+ }
+ }
+
+ private X509Certificate2? LoadCertificate(
+ string? path,
+ string? password,
+ string? thumbprint,
+ string storeName,
+ string storeLocation)
+ {
+ // Try file-based certificate first
+ if (!string.IsNullOrEmpty(path) && File.Exists(path))
+ {
+ return new X509Certificate2(
+ path,
+ password,
+ X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet);
+ }
+
+ // Try certificate store
+ if (!string.IsNullOrEmpty(thumbprint))
+ {
+ using var store = new X509Store(
+ Enum.Parse(storeName),
+ Enum.Parse(storeLocation));
+
+ store.Open(OpenFlags.ReadOnly);
+
+ var certs = store.Certificates.Find(
+ X509FindType.FindByThumbprint,
+ thumbprint,
+ validOnly: false);
+
+ return certs.Count > 0 ? certs[0] : null;
+ }
+
+ return null;
+ }
+
+ private void OnCertificateFileChanged(object sender, FileSystemEventArgs e)
+ {
+ _logger.LogInformation("Certificate file changed, reloading: {Path}", e.FullPath);
+
+ try
+ {
+ // Small delay to ensure file is fully written
+ Thread.Sleep(500);
+ LoadCertificates();
+ CertificatesReloaded?.Invoke();
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Failed to reload certificates");
+ }
+ }
+
+ public X509Certificate2? GetServerCertificate() => _serverCertificate;
+ public X509Certificate2? GetClientCertificate() => _clientCertificate;
+ public X509Certificate2Collection GetCaCertificates() => _caCertificates;
+
+ public void Dispose()
+ {
+ _fileWatcher?.Dispose();
+ _serverCertificate?.Dispose();
+ _clientCertificate?.Dispose();
+ }
+}
+```
+
+---
+
+## TLS Connection Wrapper
+
+```csharp
+namespace StellaOps.Router.Transport.Tls;
+
+///
+/// TLS-wrapped frame connection.
+///
+public sealed class TlsFrameConnection : IAsyncDisposable
+{
+ private readonly Socket _socket;
+ private readonly SslStream _sslStream;
+ private readonly TcpFrameCodec _codec;
+ private readonly ILogger _logger;
+ private readonly SemaphoreSlim _writeLock = new(1, 1);
+ private readonly byte[] _readBuffer;
+ private readonly byte[] _writeBuffer;
+ private int _readBufferOffset;
+ private int _readBufferCount;
+
+ public string ConnectionId { get; }
+ public EndPoint? RemoteEndPoint => _socket.RemoteEndPoint;
+ public bool IsConnected => _socket.Connected;
+ public string? RemoteCertificateSubject { get; private set; }
+ public string? RemoteCertificateThumbprint { get; private set; }
+
+ public TlsFrameConnection(
+ Socket socket,
+ SslStream sslStream,
+ TcpFrameCodec codec,
+ ILogger logger)
+ {
+ _socket = socket;
+ _sslStream = sslStream;
+ _codec = codec;
+ _logger = logger;
+ _readBuffer = new byte[64 * 1024];
+ _writeBuffer = new byte[64 * 1024];
+ ConnectionId = Guid.NewGuid().ToString("N");
+
+ // Extract remote certificate info
+ if (_sslStream.RemoteCertificate != null)
+ {
+ var cert = new X509Certificate2(_sslStream.RemoteCertificate);
+ RemoteCertificateSubject = cert.Subject;
+ RemoteCertificateThumbprint = cert.Thumbprint;
+ }
+ }
+
+ public async ValueTask SendAsync(Frame frame, CancellationToken cancellationToken)
+ {
+ await _writeLock.WaitAsync(cancellationToken);
+ try
+ {
+ var size = _codec.Encode(frame, _writeBuffer);
+ await _sslStream.WriteAsync(_writeBuffer.AsMemory(0, size), cancellationToken);
+ await _sslStream.FlushAsync(cancellationToken);
+ }
+ finally
+ {
+ _writeLock.Release();
+ }
+ }
+
+ public async ValueTask ReceiveAsync(CancellationToken cancellationToken)
+ {
+ while (true)
+ {
+ // Try to decode from existing buffer
+ if (_readBufferCount >= 24)
+ {
+ var span = new ReadOnlySpan(_readBuffer, _readBufferOffset, _readBufferCount);
+
+ if (span.Length >= 8)
+ {
+ var payloadLength = BinaryPrimitives.ReadUInt32BigEndian(span[4..]);
+ var totalLength = 24 + (int)payloadLength;
+
+ if (span.Length >= totalLength)
+ {
+ var frame = _codec.Decode(span[..totalLength]);
+ _readBufferOffset += totalLength;
+ _readBufferCount -= totalLength;
+
+ if (_readBufferOffset > _readBuffer.Length / 2)
+ {
+ Buffer.BlockCopy(_readBuffer, _readBufferOffset, _readBuffer, 0, _readBufferCount);
+ _readBufferOffset = 0;
+ }
+
+ return frame;
+ }
+ }
+ }
+
+ if (_readBufferOffset + _readBufferCount >= _readBuffer.Length)
+ {
+ Buffer.BlockCopy(_readBuffer, _readBufferOffset, _readBuffer, 0, _readBufferCount);
+ _readBufferOffset = 0;
+ }
+
+ var bytesRead = await _sslStream.ReadAsync(
+ _readBuffer.AsMemory(_readBufferOffset + _readBufferCount),
+ cancellationToken);
+
+ if (bytesRead == 0)
+ {
+ throw new EndOfStreamException("TLS connection closed by remote");
+ }
+
+ _readBufferCount += bytesRead;
+ }
+ }
+
+ public async IAsyncEnumerable ReceiveAllAsync(
+ [EnumeratorCancellation] CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ Frame frame;
+ try
+ {
+ frame = await ReceiveAsync(cancellationToken);
+ }
+ catch (EndOfStreamException)
+ {
+ yield break;
+ }
+ catch (OperationCanceledException)
+ {
+ yield break;
+ }
+ catch (IOException ex) when (ex.InnerException is SocketException)
+ {
+ yield break;
+ }
+
+ yield return frame;
+ }
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ _writeLock.Dispose();
+ await _sslStream.DisposeAsync();
+ _socket.Dispose();
+ }
+}
+```
+
+---
+
+## Gateway TLS Server
+
+```csharp
+namespace StellaOps.Router.Transport.Tls;
+
+///
+/// TLS-enabled transport server for the gateway.
+///
+public sealed class TlsTransportServer : IHostedService
+{
+ private readonly TlsTransportConfig _config;
+ private readonly ICertificateProvider _certificateProvider;
+ private readonly TcpFrameCodec _codec;
+ private readonly IGlobalRoutingState _routingState;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private Socket? _listener;
+ private CancellationTokenSource? _cts;
+ private readonly ConcurrentDictionary _connections = new();
+
+ public TlsTransportServer(
+ IOptions config,
+ ICertificateProvider certificateProvider,
+ TcpFrameCodec codec,
+ IGlobalRoutingState routingState,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _config = config.Value;
+ _certificateProvider = certificateProvider;
+ _codec = codec;
+ _routingState = routingState;
+ _serializer = serializer;
+ _logger = logger;
+ }
+
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ var serverCert = _certificateProvider.GetServerCertificate();
+ if (serverCert == null)
+ {
+ throw new InvalidOperationException("Server certificate not configured");
+ }
+
+ _cts = new CancellationTokenSource();
+
+ _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ _listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
+ _listener.Bind(new IPEndPoint(IPAddress.Parse(_config.ListenAddress), _config.Port));
+ _listener.Listen(_config.Backlog);
+
+ _logger.LogInformation(
+ "TLS transport server listening on {Address}:{Port}",
+ _config.ListenAddress, _config.Port);
+
+ _ = AcceptConnectionsAsync(_cts.Token);
+ }
+
+ private async Task AcceptConnectionsAsync(CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ var socket = await _listener!.AcceptAsync(cancellationToken);
+ _logger.LogDebug("Accepted TLS connection from {RemoteEndPoint}", socket.RemoteEndPoint);
+
+ _ = HandleConnectionAsync(socket, cancellationToken);
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error accepting TLS connection");
+ }
+ }
+ }
+
+ private async Task HandleConnectionAsync(Socket socket, CancellationToken cancellationToken)
+ {
+ SslStream? sslStream = null;
+
+ try
+ {
+ var networkStream = new NetworkStream(socket, ownsSocket: false);
+ sslStream = new SslStream(
+ networkStream,
+ leaveInnerStreamOpen: false,
+ ValidateClientCertificate);
+
+ var serverCert = _certificateProvider.GetServerCertificate()!;
+
+ var authOptions = new SslServerAuthenticationOptions
+ {
+ ServerCertificate = serverCert,
+ ClientCertificateRequired = _config.RequireClientCertificate,
+ EnabledSslProtocols = _config.AllowedProtocols,
+ CertificateRevocationCheckMode = _config.RevocationMode
+ };
+
+ await sslStream.AuthenticateAsServerAsync(authOptions, cancellationToken);
+
+ _logger.LogDebug(
+ "TLS handshake complete: Protocol={Protocol}, Cipher={Cipher}",
+ sslStream.SslProtocol,
+ sslStream.CipherAlgorithm);
+
+ var connection = new TlsFrameConnection(socket, sslStream, _codec, _logger);
+
+ // Wait for HELLO frame
+ var helloFrame = await connection.ReceiveAsync(cancellationToken)
+ .AsTask()
+ .WaitAsync(TimeSpan.FromSeconds(_config.HandshakeTimeoutSeconds), cancellationToken);
+
+ if (helloFrame.Type != FrameType.Hello)
+ {
+ _logger.LogWarning("Expected HELLO frame, got {Type}", helloFrame.Type);
+ return;
+ }
+
+ var hello = _serializer.DeserializeHello(helloFrame.Payload);
+
+ // Log client certificate identity
+ if (connection.RemoteCertificateSubject != null)
+ {
+ _logger.LogInformation(
+ "Microservice connected via TLS: {ServiceName}/{InstanceId}, Cert={Subject}",
+ hello.ServiceName, hello.InstanceId, connection.RemoteCertificateSubject);
+ }
+
+ // Send HELLO response
+ var helloResponse = new HelloResponse
+ {
+ Accepted = true,
+ HeartbeatIntervalMs = _config.HeartbeatIntervalMs,
+ MaxPayloadSize = _config.MaxPayloadSize
+ };
+
+ var responseFrame = new Frame
+ {
+ Type = FrameType.Hello,
+ CorrelationId = helloFrame.CorrelationId,
+ Payload = _serializer.SerializeHelloResponse(helloResponse)
+ };
+ await connection.SendAsync(responseFrame, cancellationToken);
+
+ var msConnection = new TlsMicroserviceConnection(
+ connection,
+ hello.ServiceName,
+ hello.InstanceId,
+ hello.Endpoints,
+ _serializer,
+ _logger);
+
+ _connections[connection.ConnectionId] = msConnection;
+
+ _routingState.RegisterConnection(new EndpointConnection
+ {
+ ConnectionId = connection.ConnectionId,
+ ServiceName = hello.ServiceName,
+ InstanceId = hello.InstanceId,
+ Transport = "TLS",
+ State = ConnectionState.Connected,
+ Endpoints = hello.Endpoints,
+ Region = hello.Metadata?.GetValueOrDefault("region"),
+ LastHeartbeat = DateTimeOffset.UtcNow,
+ CertificateThumbprint = connection.RemoteCertificateThumbprint
+ });
+
+ await msConnection.ProcessAsync(cancellationToken);
+ }
+ catch (AuthenticationException ex)
+ {
+ _logger.LogWarning(ex, "TLS authentication failed from {RemoteEndPoint}", socket.RemoteEndPoint);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error handling TLS connection");
+ }
+ finally
+ {
+ if (sslStream != null)
+ {
+ var conn = new TlsFrameConnection(socket, sslStream, _codec, _logger);
+ _connections.TryRemove(conn.ConnectionId, out _);
+ _routingState.RemoveConnection(conn.ConnectionId);
+ await sslStream.DisposeAsync();
+ }
+ socket.Dispose();
+ }
+ }
+
+ private bool ValidateClientCertificate(
+ object sender,
+ X509Certificate? certificate,
+ X509Chain? chain,
+ SslPolicyErrors sslPolicyErrors)
+ {
+ if (!_config.RequireClientCertificate)
+ return true;
+
+ if (certificate == null)
+ {
+ _logger.LogWarning("Client did not provide certificate");
+ return false;
+ }
+
+ if (sslPolicyErrors == SslPolicyErrors.None)
+ return true;
+
+ if (_config.AllowUntrustedRootCertificates &&
+ sslPolicyErrors == SslPolicyErrors.RemoteCertificateChainErrors)
+ {
+ _logger.LogWarning("Accepting client certificate with chain errors (dev mode)");
+ return true;
+ }
+
+ _logger.LogWarning(
+ "Client certificate validation failed: Errors={Errors}, Subject={Subject}",
+ sslPolicyErrors,
+ certificate.Subject);
+
+ return false;
+ }
+
+ public TlsMicroserviceConnection? GetConnection(string connectionId)
+ {
+ return _connections.TryGetValue(connectionId, out var conn) ? conn : null;
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken)
+ {
+ _cts?.Cancel();
+ _listener?.Close();
+
+ foreach (var connection in _connections.Values)
+ {
+ await connection.DisconnectAsync();
+ }
+
+ _cts?.Dispose();
+ }
+}
+
+public sealed class TlsMicroserviceConnection
+{
+ private readonly TlsFrameConnection _connection;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private readonly ConcurrentDictionary> _pendingRequests = new();
+
+ public string ServiceName { get; }
+ public string InstanceId { get; }
+ public EndpointDescriptor[] Endpoints { get; }
+ public DateTimeOffset LastActivity { get; private set; }
+ public string? CertificateThumbprint => _connection.RemoteCertificateThumbprint;
+
+ public TlsMicroserviceConnection(
+ TlsFrameConnection connection,
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _connection = connection;
+ ServiceName = serviceName;
+ InstanceId = instanceId;
+ Endpoints = endpoints;
+ _serializer = serializer;
+ _logger = logger;
+ LastActivity = DateTimeOffset.UtcNow;
+ }
+
+ public async Task ProcessAsync(CancellationToken cancellationToken)
+ {
+ await foreach (var frame in _connection.ReceiveAllAsync(cancellationToken))
+ {
+ LastActivity = DateTimeOffset.UtcNow;
+
+ if (frame.Type == FrameType.Response &&
+ _pendingRequests.TryRemove(frame.CorrelationId, out var tcs))
+ {
+ tcs.TrySetResult(frame);
+ }
+ }
+ }
+
+ public async Task SendRequestAsync(
+ RequestPayload request,
+ TimeSpan timeout,
+ CancellationToken cancellationToken)
+ {
+ var correlationId = Guid.NewGuid().ToString("N");
+ var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ _pendingRequests[correlationId] = tcs;
+
+ try
+ {
+ var frame = new Frame
+ {
+ Type = FrameType.Request,
+ CorrelationId = correlationId,
+ Payload = _serializer.SerializeRequest(request)
+ };
+
+ await _connection.SendAsync(frame, cancellationToken);
+
+ var responseFrame = await tcs.Task.WaitAsync(timeout, cancellationToken);
+ return _serializer.DeserializeResponse(responseFrame.Payload);
+ }
+ finally
+ {
+ _pendingRequests.TryRemove(correlationId, out _);
+ }
+ }
+
+ public async Task DisconnectAsync()
+ {
+ foreach (var pending in _pendingRequests.Values)
+ {
+ pending.TrySetCanceled();
+ }
+ _pendingRequests.Clear();
+ await _connection.DisposeAsync();
+ }
+}
+```
+
+---
+
+## Microservice TLS Client
+
+```csharp
+namespace StellaOps.Router.Transport.Tls;
+
+///
+/// TLS client for microservices to connect securely to the gateway.
+///
+public sealed class TlsTransportClient : ITransportServer, IAsyncDisposable
+{
+ private readonly TlsClientConfig _config;
+ private readonly ICertificateProvider _certificateProvider;
+ private readonly TcpFrameCodec _codec;
+ private readonly IPayloadSerializer _serializer;
+ private readonly ILogger _logger;
+ private TlsFrameConnection? _connection;
+ private CancellationTokenSource? _cts;
+ private Task? _processingTask;
+ private int _reconnectAttempts;
+
+ public string TransportType => "TLS";
+ public bool IsConnected => _connection?.IsConnected ?? false;
+
+ public event Func>? OnRequest;
+ public event Func? OnCancel;
+
+ public TlsTransportClient(
+ IOptions config,
+ ICertificateProvider certificateProvider,
+ TcpFrameCodec codec,
+ IPayloadSerializer serializer,
+ ILogger logger)
+ {
+ _config = config.Value;
+ _certificateProvider = certificateProvider;
+ _codec = codec;
+ _serializer = serializer;
+ _logger = logger;
+ }
+
+ public async Task ConnectAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ _cts = new CancellationTokenSource();
+ await ConnectWithRetryAsync(serviceName, instanceId, endpoints, cancellationToken);
+ _processingTask = ProcessFramesAsync(serviceName, instanceId, endpoints, _cts.Token);
+ }
+
+ private async Task ConnectWithRetryAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ await socket.ConnectAsync(_config.GatewayHost, _config.GatewayPort, cancellationToken);
+
+ var networkStream = new NetworkStream(socket, ownsSocket: false);
+ var sslStream = new SslStream(
+ networkStream,
+ leaveInnerStreamOpen: false,
+ ValidateServerCertificate);
+
+ var clientCert = _certificateProvider.GetClientCertificate();
+ var clientCerts = clientCert != null
+ ? new X509CertificateCollection { clientCert }
+ : new X509CertificateCollection();
+
+ var authOptions = new SslClientAuthenticationOptions
+ {
+ TargetHost = _config.ExpectedServerName ?? _config.GatewayHost,
+ ClientCertificates = clientCerts,
+ EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13
+ };
+
+ await sslStream.AuthenticateAsClientAsync(authOptions, cancellationToken);
+
+ _logger.LogDebug(
+ "TLS handshake complete: Protocol={Protocol}, Server={Server}",
+ sslStream.SslProtocol,
+ _config.GatewayHost);
+
+ _connection = new TlsFrameConnection(socket, sslStream, _codec, _logger);
+
+ // Send HELLO
+ var hello = new HelloPayload
+ {
+ ServiceName = serviceName,
+ InstanceId = instanceId,
+ Endpoints = endpoints,
+ Metadata = new Dictionary
+ {
+ ["region"] = _config.Region ?? "default",
+ ["version"] = _config.ServiceVersion ?? "1.0.0"
+ }
+ };
+
+ var helloFrame = new Frame
+ {
+ Type = FrameType.Hello,
+ CorrelationId = Guid.NewGuid().ToString("N"),
+ Payload = _serializer.SerializeHello(hello)
+ };
+
+ await _connection.SendAsync(helloFrame, cancellationToken);
+
+ var response = await _connection.ReceiveAsync(cancellationToken);
+ if (response.Type != FrameType.Hello)
+ {
+ throw new ProtocolException($"Expected HELLO response, got {response.Type}");
+ }
+
+ _reconnectAttempts = 0;
+ _logger.LogInformation(
+ "Connected to gateway via TLS at {Host}:{Port}",
+ _config.GatewayHost, _config.GatewayPort);
+
+ return;
+ }
+ catch (AuthenticationException ex)
+ {
+ _logger.LogError(ex, "TLS authentication failed");
+ throw; // Don't retry auth failures
+ }
+ catch (Exception ex) when (!cancellationToken.IsCancellationRequested)
+ {
+ _reconnectAttempts++;
+ var delay = Math.Min(
+ _config.InitialReconnectDelayMs * Math.Pow(2, _reconnectAttempts - 1),
+ _config.MaxReconnectDelayMs);
+
+ _logger.LogWarning(ex, "TLS connection attempt {Attempt} failed, retrying in {Delay}ms",
+ _reconnectAttempts, delay);
+
+ await Task.Delay((int)delay, cancellationToken);
+ }
+ }
+ }
+
+ private bool ValidateServerCertificate(
+ object sender,
+ X509Certificate? certificate,
+ X509Chain? chain,
+ SslPolicyErrors sslPolicyErrors)
+ {
+ if (_config.SkipServerCertificateValidation)
+ {
+ _logger.LogWarning("Skipping server certificate validation (dev mode)");
+ return true;
+ }
+
+ if (sslPolicyErrors == SslPolicyErrors.None)
+ return true;
+
+ _logger.LogWarning(
+ "Server certificate validation failed: Errors={Errors}",
+ sslPolicyErrors);
+
+ return false;
+ }
+
+ private async Task ProcessFramesAsync(
+ string serviceName,
+ string instanceId,
+ EndpointDescriptor[] endpoints,
+ CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
+ {
+ if (_connection == null || !_connection.IsConnected)
+ {
+ await ConnectWithRetryAsync(serviceName, instanceId, endpoints, cancellationToken);
+ }
+
+ await foreach (var frame in _connection!.ReceiveAllAsync(cancellationToken))
+ {
+ switch (frame.Type)
+ {
+ case FrameType.Request:
+ _ = HandleRequestAsync(frame, cancellationToken);
+ break;
+
+ case FrameType.Cancel:
+ if (OnCancel != null)
+ await OnCancel(frame.CorrelationId, cancellationToken);
+ break;
+
+ case FrameType.Heartbeat:
+ await HandleHeartbeatAsync(frame);
+ break;
+ }
+ }
+ }
+ catch (EndOfStreamException)
+ {
+ _logger.LogWarning("TLS connection closed, attempting reconnect");
+ _connection = null;
+ }
+ catch (OperationCanceledException)
+ {
+ break;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error processing TLS frames");
+ _connection = null;
+ }
+ }
+ }
+
+ private async Task HandleRequestAsync(Frame frame, CancellationToken cancellationToken)
+ {
+ if (_connection == null || OnRequest == null) return;
+
+ try
+ {
+ var request = _serializer.DeserializeRequest(frame.Payload);
+ var response = await OnRequest(request, cancellationToken);
+
+ var responseFrame = new Frame
+ {
+ Type = FrameType.Response,
+ CorrelationId = frame.CorrelationId,
+ Payload = _serializer.SerializeResponse(response),
+ Flags = FrameFlags.Final
+ };
+
+ await _connection.SendAsync(responseFrame, cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error handling TLS request");
+
+ var errorResponse = new ResponsePayload
+ {
+ StatusCode = 500,
+ Headers = new Dictionary(),
+ ErrorMessage = ex.Message,
+ IsFinalChunk = true
+ };
+
+ var errorFrame = new Frame
+ {
+ Type = FrameType.Response,
+ CorrelationId = frame.CorrelationId,
+ Payload = _serializer.SerializeResponse(errorResponse),
+ Flags = FrameFlags.Final | FrameFlags.Error
+ };
+
+ await _connection.SendAsync(errorFrame, cancellationToken);
+ }
+ }
+
+ private async Task HandleHeartbeatAsync(Frame frame)
+ {
+ if (_connection == null) return;
+
+ var pongFrame = new Frame
+ {
+ Type = FrameType.Heartbeat,
+ CorrelationId = frame.CorrelationId,
+ Payload = frame.Payload
+ };
+
+ await _connection.SendAsync(pongFrame, CancellationToken.None);
+ }
+
+ public async Task DisconnectAsync()
+ {
+ _cts?.Cancel();
+ if (_processingTask != null)
+ {
+ try { await _processingTask.WaitAsync(TimeSpan.FromSeconds(5)); } catch { }
+ }
+ if (_connection != null)
+ {
+ await _connection.DisposeAsync();
+ }
+ _cts?.Dispose();
+ }
+
+ public async ValueTask DisposeAsync() => await DisconnectAsync();
+}
+```
+
+---
+
+## Service Registration
+
+```csharp
+namespace StellaOps.Router.Transport.Tls;
+
+public static class TlsTransportExtensions
+{
+ public static IServiceCollection AddTlsTransport(
+ this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ services.Configure(configuration.GetSection("TlsTransport"));
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddHostedService(sp => sp.GetRequiredService());
+
+ return services;
+ }
+
+ public static IServiceCollection AddTlsMicroserviceTransport(
+ this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ services.Configure(configuration.GetSection("TlsClient"));
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+
+ return services;
+ }
+}
+```
+
+---
+
+## YAML Configuration
+
+```yaml
+# Gateway TLS configuration
+TlsTransport:
+ ListenAddress: "0.0.0.0"
+ Port: 9501
+ CertificatePath: "/etc/stellaops/certs/gateway.pfx"
+ CertificatePassword: "${GATEWAY_CERT_PASSWORD}"
+ RequireClientCertificate: true
+ ClientCaCertificatePath: "/etc/stellaops/certs/client-ca.crt"
+ AllowedProtocols: "Tls12, Tls13"
+ RevocationMode: "Online"
+
+# Microservice TLS configuration
+TlsClient:
+ GatewayHost: "gateway.internal"
+ GatewayPort: 9501
+ ClientCertificatePath: "/etc/stellaops/certs/service.pfx"
+ ClientCertificatePassword: "${SERVICE_CERT_PASSWORD}"
+ ExpectedServerName: "gateway.stellaops.internal"
+```
+
+---
+
+## Deliverables
+
+1. `StellaOps.Router.Transport.Tls/TlsTransportConfig.cs`
+2. `StellaOps.Router.Transport.Tls/ICertificateProvider.cs`
+3. `StellaOps.Router.Transport.Tls/CertificateProvider.cs`
+4. `StellaOps.Router.Transport.Tls/TlsFrameConnection.cs`
+5. `StellaOps.Router.Transport.Tls/TlsTransportServer.cs`
+6. `StellaOps.Router.Transport.Tls/TlsTransportClient.cs`
+7. `StellaOps.Router.Transport.Tls/TlsTransportExtensions.cs`
+8. Certificate validation tests
+9. mTLS handshake tests
+10. Certificate rotation tests
+
+---
+
+## Next Step
+
+Proceed to [Step 16: GraphQL Handler Implementation](16-Step.md) to implement the GraphQL route handler plugin.
diff --git a/docs/router/16-Step.md b/docs/router/16-Step.md
new file mode 100644
index 000000000..831f7eaef
--- /dev/null
+++ b/docs/router/16-Step.md
@@ -0,0 +1,994 @@
+# Step 16: GraphQL Handler Implementation
+
+**Phase 4: Handler Plugins**
+**Estimated Complexity:** High
+**Dependencies:** Step 10 (Microservice Handler)
+
+---
+
+## Overview
+
+The GraphQL handler routes GraphQL queries, mutations, and subscriptions to appropriate microservices based on schema analysis. It supports schema stitching, query splitting, and federated execution across multiple services.
+
+---
+
+## Goals
+
+1. Route GraphQL operations to appropriate backend services
+2. Support schema federation/stitching across microservices
+3. Handle batched queries with DataLoader patterns
+4. Support subscriptions via WebSocket upgrade
+5. Provide introspection proxying and schema caching
+
+---
+
+## Core Architecture
+
+```
+┌──────────────────────────────────────────────────────────────────┐
+│ GraphQL Handler │
+├──────────────────────────────────────────────────────────────────┤
+│ │
+│ HTTP Request │
+│ │ │
+│ ▼ │
+│ ┌───────────────┐ │
+│ │ Query Parser │──► Extract operation type & fields │
+│ └───────┬───────┘ │
+│ │ │
+│ ▼ │
+│ ┌───────────────┐ ┌─────────────────┐ │
+│ │ Query Planner │───►│ Schema Registry │ │
+│ └───────┬───────┘ └─────────────────┘ │
+│ │ │
+│ ▼ │
+│ ┌───────────────┐ │
+│ │Query Executor │──► Split & dispatch to services │
+│ └───────┬───────┘ │
+│ │ │
+│ ▼ │
+│ ┌───────────────┐ │
+│ │Result Merger │──► Combine partial results │
+│ └───────────────┘ │
+│ │
+└──────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Configuration
+
+```csharp
+namespace StellaOps.Router.Handlers.GraphQL;
+
+public class GraphQLHandlerConfig
+{
+ /// Path prefix for GraphQL endpoint.
+ public string Path { get; set; } = "/graphql";
+
+ /// Whether to enable introspection queries.
+ public bool EnableIntrospection { get; set; } = true;
+
+ /// Whether to enable subscriptions.
+ public bool EnableSubscriptions { get; set; } = true;
+
+ /// Maximum query depth to prevent DOS.
+ public int MaxQueryDepth { get; set; } = 15;
+
+ /// Maximum query complexity score.
+ public int MaxQueryComplexity { get; set; } = 1000;
+
+ /// Timeout for query execution.
+ public TimeSpan ExecutionTimeout { get; set; } = TimeSpan.FromSeconds(30);
+
+ /// Cache duration for schema introspection.
+ public TimeSpan SchemaCacheDuration { get; set; } = TimeSpan.FromMinutes(5);
+
+ /// Whether to enable query batching.
+ public bool EnableBatching { get; set; } = true;
+
+ /// Maximum batch size.
+ public int MaxBatchSize { get; set; } = 10;
+
+ /// Registered GraphQL services and their type ownership.
+ public Dictionary Services { get; set; } = new();
+}
+
+public class GraphQLServiceConfig
+{
+ /// Service name for routing.
+ public required string ServiceName { get; set; }
+
+ /// Root types this service handles (Query, Mutation, Subscription).
+ public HashSet RootTypes { get; set; } = new();
+
+ /// Specific fields this service owns.
+ public Dictionary> OwnedFields { get; set; } = new();
+
+ /// Whether this service provides the full schema.
+ public bool IsSchemaProvider { get; set; }
+}
+```
+
+---
+
+## Core Types
+
+```csharp
+namespace StellaOps.Router.Handlers.GraphQL;
+
+///
+/// Parsed GraphQL request.
+///
+public sealed class GraphQLRequest
+{
+ public required string Query { get; init; }
+ public string? OperationName { get; init; }
+ public Dictionary? Variables { get; init; }
+ public Dictionary? Extensions { get; init; }
+}
+
+///
+/// GraphQL response format.
+///
+public sealed class GraphQLResponse
+{
+ public object? Data { get; set; }
+ public List? Errors { get; set; }
+ public Dictionary? Extensions { get; set; }
+}
+
+public sealed class GraphQLError
+{
+ public required string Message { get; init; }
+ public List? Locations { get; init; }
+ public List