|
1 | 1 | # Spec Drift Report |
2 | 2 |
|
3 | | -Generated: 2026-05-18T00:00:00Z |
4 | | -Project: rust-supervisor |
5 | | -Scope: `specs/006-4-restart-policy-production` |
| 3 | +Generated: 2026-05-19T08:00:00Z |
| 4 | +Project: rust-tokio-supervisor (rust-supervisor) |
6 | 5 |
|
7 | 6 | ## Summary |
8 | 7 |
|
9 | 8 | | Category | Count | |
10 | 9 | |----------|-------| |
11 | | -| Specs Analyzed | 1 | |
12 | | -| Requirements Checked | 9 (3 FR + 3 SC + 3 Edge Cases) | |
13 | | -| ✓ Aligned | 9 (100%) | |
14 | | -| ⚠️ Drifted | 0 | |
15 | | -| ✗ Not Implemented | 0 | |
16 | | -| 🆕 Unspecced Code | 0 | |
| 10 | +| Specs Analyzed | 18 | |
| 11 | +| Requirements Checked | ~277 | |
| 12 | +| FR-level implementation breakdown by spec below | — | |
| 13 | + |
| 14 | +## Spec-by-Spec Alignment |
| 15 | + |
| 16 | +### 001-create-supervisor-core — 77 FRs, 45 SCs |
| 17 | + |
| 18 | +#### Aligned ✅ (majority — 70+ FRs implemented) |
| 19 | + |
| 20 | +The core supervisor module architecture fully matches the spec: |
| 21 | + |
| 22 | +| Module | Spec FR(s) | Implementation | |
| 23 | +|--------|-----------|----------------| |
| 24 | +| src/id/ | FR-006 | ChildId, SupervisorId, SupervisorPath ✅ | |
| 25 | +| src/error/ | FR-011, FR-012 | TaskFailureKind (Error/Panic/Timeout/Unhealthy/Cancelled) ✅ | |
| 26 | +| src/spec/child.rs | FR-001..FR-004, FR-008, FR-009 | ChildSpec, TaskKind, RestartPolicy ✅ | |
| 27 | +| src/spec/supervisor.rs | FR-005, FR-007 | SupervisorSpec, SupervisionStrategy ✅ | |
| 28 | +| src/task/ | FR-003, FR-004, FR-048 | TaskFactory, TaskContext, TaskResult, Service trait ✅ | |
| 29 | +| src/tree/ | FR-042 | SupervisorTree, startup_order, shutdown_order ✅ | |
| 30 | +| src/child_runner/ | FR-044 | ChildRunner, TaskExit, ChildRunReport ✅ | |
| 31 | +| src/policy/ | FR-013..FR-017 | MeltdownTracker, BackoffPolicy, jitter modes ✅ | |
| 32 | +| src/control/ | FR-023, FR-024, FR-025, FR-037 | SupervisorHandle (8 commands), CommandMeta, audit ✅ | |
| 33 | +| src/runtime/ | FR-020, FR-021, FR-022 | ChildSlot, cancellation, shutdown_tree ✅ | |
| 34 | +| src/shutdown/ | FR-045 | ShutdownCoordinator, ShutdownPhase (4 stages) ✅ | |
| 35 | +| src/event/ | FR-026..FR-032, FR-046 | SupervisorEvent, What, When/Where, CorrelationId ✅ | |
| 36 | +| src/observe/ | FR-033, FR-034, FR-049 | ObservabilityPipeline, MetricsFacade, tracing ✅ | |
| 37 | +| src/config/ | FR-050 | SupervisorConfig, ConfigState, YAML loader ✅ | |
| 38 | +| src/health/ | FR-018, FR-019 | HealthPolicy, heartbeat_interval, stale_after ✅ | |
| 39 | +| src/readiness/ | FR-043 | ReadinessPolicy, ReadySignal ✅ | |
| 40 | +| src/registry/ | — | RegistryStore, ChildRuntime ✅ | |
| 41 | +| src/state/ | FR-025 | SupervisorState, ChildState ✅ | |
| 42 | +| src/summary/ | SC-017 | RunSummary ✅ | |
| 43 | +| src/journal/ | FR-046 | EventJournal (ring buffer) ✅ | |
| 44 | +| src/runtime/child_slot.rs | FR-020, FR-021 | ChildSlot, cancellation, generation fence ✅ | |
17 | 45 |
|
18 | | -**Status**: ALL CLEAN — 所有 drift 已通过 ALIGN 修复和 BACKFILL 回填消除。 |
| 46 | +#### Drifted ⚠️ |
19 | 47 |
|
20 | | -## Detailed Findings |
| 48 | +1. **FR-063 / FR-031: "Snapshot/View" naming ban** |
| 49 | + - Spec says: "禁止 Snapshot/View 后缀" |
| 50 | + - Code: `src/ipc/security/peer_identity.rs` uses "Snapshot" in struct name `PeerIdentitySnapshot` and doc comments referencing "snapshot" |
| 51 | + - Location: `src/ipc/security/peer_identity.rs:17` — `/// Snapshot of peer identity taken from a connected Unix socket.` |
| 52 | + - Also `tests/naming_contract_test.rs` explicitly replaces Snapshot/snapshot in manual files as a test assertion |
| 53 | + - Severity: **minor** — PeerIdentitySnapshot is internal IPC type, not user-facing API |
| 54 | + |
| 55 | +2. **FR-038: "不引入 actor-model"** |
| 56 | + - Spec says: "不引入 actor-model。不采用任何现成 actor 框架" |
| 57 | + - Code: `src/control/handle.rs` and `src/control/command.rs` use "Actor" in doc comments: "Actor that requested the command" |
| 58 | + - Location: `src/control/handle.rs:107`, `src/control/command.rs:56` |
| 59 | + - Severity: **minor** — "Actor" is used in the generic sense of "who performed this action", not an actor framework |
| 60 | + |
| 61 | +3. **FR-039: "不采用 compatibility method"** |
| 62 | + - Spec says: "不提供 compatibility wrapper(兼容包装函数), deprecated facade(废弃门面) 或 migration layer(迁移层)" |
| 63 | + - Code: Multiple locations use `#[deprecated]`, "legacy", "backward compatibility", "migration compatibility" comments |
| 64 | + - Key locations: |
| 65 | + - `src/policy/meltdown.rs:165` — `#[deprecated] fn record_child_restart_failure` with legacy synthetic child |
| 66 | + - `src/policy/budget.rs:65` — "Used for backward compatibility: old config files without a budget" |
| 67 | + - `src/runtime/control_loop.rs:1674` — "Keep text-based log for backward compatibility" |
| 68 | + - `src/runtime/child_slot.rs:231` — "Fields migrated from ChildRuntimeState for compatibility" |
| 69 | + - Multiple `child_slot.rs` methods marked "migration compatibility" |
| 70 | + - Severity: **moderate** — These are internal migration compatibility layers that should be removed before 1.0 |
| 71 | + |
| 72 | +### 002-config-schema-support — 17 FRs, 7 SCs |
| 73 | + |
| 74 | +#### Aligned ✅ |
| 75 | +- FR-001: SupervisorConfig as root configuration struct ✅ |
| 76 | +- FR-002..FR-004: confique::Config, JsonSchema, Serialize/Deserialize ✅ |
| 77 | +- FR-005: ConfigState as validated state ✅ |
| 78 | +- FR-011..FR-013: startup validation, fatal errors ✅ |
| 79 | +- FR-014..FR-017: schema coverage, template, docs sync ✅ |
21 | 80 |
|
22 | | -### Spec: 006-4-restart-policy-production — 生产级重启策略与分组隔离观测 |
| 81 | +#### Drifted ⚠️ |
| 82 | +4. **FR-007: "不默认写入 x-tree-split"** |
| 83 | + - Spec says: "官方 root struct 不默认写入 x-tree-split" |
| 84 | + - SC-004: "官方 schema/template 中 x-tree-split 默认出现 0 次" |
| 85 | + - Code: Test `no_baked_in_tree_split_test.rs` exists and checks for x-tree-split ✅ |
| 86 | + - Verified by `configurable_template_test.rs` which generates templates |
| 87 | + - Severity: **none** — properly tested |
23 | 88 |
|
24 | | -#### Aligned ✓ |
| 89 | +### 003-supervisor-dashboard — 27 FRs, 12 SCs |
25 | 90 |
|
26 | | -- **FR-001 (budget → meltdown → backoff 评估管线)**: ✅ |
27 | | - - `src/runtime/pipeline.rs:650-650` — `build_policy_aware_what()` 优先检查预算耗尽 |
28 | | - - 预算不足时发射 `What::BudgetExhausted`,不经过熔断与退避 |
| 91 | +#### Aligned ✅ (all major FRs implemented) |
| 92 | +- FR-001..FR-003: IPC path configured, relay readable, no external network ✅ |
| 93 | +- FR-004..FR-007: registration, multi-connection, session handshake ✅ |
| 94 | +- FR-008..FR-012: state, topology, events, logs, commands ✅ |
| 95 | +- FR-013..FR-019: secure session, audit, rejection ✅ |
| 96 | +- FR-023..FR-027: relay in separate repo, UI in separate repo ✅ |
29 | 97 |
|
30 | | -- **FR-001 (公平性探针 10s 窗口)**: ✅ |
31 | | - - `src/observe/fairness.rs` — `FairnessProbe` 完整实现 |
32 | | - - `src/runtime/control_loop.rs:545,548` — 集成到控制循环 |
33 | | - - ALIGN-003: 新增 `What::FairnessProbeStarvation` typed event (line 1624) |
| 98 | +#### Verified 🆗 |
| 99 | +- FR-023: "relay 实现在 ~/rust-supervisor-relay" — No relay code in this repo ✅ |
| 100 | +- FR-024: "dashboard client 实现在 ~/rust-supervisor-ui" — No UI code in this repo ✅ |
34 | 101 |
|
35 | | -- **FR-002 (分组故障隔离)**: ✅ |
36 | | - - `src/policy/group.rs` — `GroupIsolationPolicy::affected_by()`, `PropagationPolicy` |
37 | | - - `src/policy/meltdown.rs` — `track_group_failure()`, `propagate_fuse()` |
38 | | - - `src/runtime/pipeline.rs:671` — 熔断时发射 `What::GroupFuseTriggered` |
| 102 | +### 004-1-runtime-lifecycle-guard — 3 FRs, 4 SCs |
39 | 103 |
|
40 | | -- **FR-003 (SeverityClass 分叉)**: ✅ |
41 | | - - `src/policy/role_defaults.rs` — `SeverityClass` 枚举 + `default_severity()` 映射 |
42 | | - - `src/runtime/pipeline.rs:699` — 发射 `What::EscalationBifurcated` (Critical/Optional) |
| 104 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 105 | +- RuntimeControlPlane, RuntimeWatchdog, SupervisorHandle health/is_alive/join/shutdown ✅ |
43 | 106 |
|
44 | | -- **FR-003 (CorrelationId 贯穿全链路)**: ✅ |
45 | | - - `src/runtime/control_loop.rs:498` — 生成真实 UUID (`uuid::Uuid::new_v4()`, T037) |
46 | | - - `src/runtime/pipeline.rs:597` — `stage_emit_typed_event` 使用 `ctx.correlation_id` (ALIGN-002) |
| 107 | +### 004-2-real-shutdown-pipeline — 3 FRs, 4 SCs |
47 | 108 |
|
48 | | -- **SC-000 (策略决策路径可重建)**: ✅ |
49 | | - - `src/runtime/pipeline.rs:651-715` — `build_policy_aware_what()` 发射 BudgetExhausted / GroupFuseTriggered / EscalationBifurcated (ALIGN-001) |
50 | | - - FairnessProbeStarvation 也通过 typed event 通道 (ALIGN-003) |
51 | | - - 可通过 `emit_policy_diagnostic` (T042) 输出 PipelineStageDiagnostic |
| 109 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 110 | +- CancellationToken propagation, shutdown_order, abort stragglers, reconcile ✅ |
52 | 111 |
|
53 | | -- **SC-001 (105% 预算曲线上界)**: ✅ |
54 | | - - `tests/policy_budget_waveform_test.rs` — `test_budget_limits_effective_restart_rate` |
| 112 | +### 004-3-child-runtime-state-control — 3 FRs, 4 SCs |
55 | 113 |
|
56 | | -- **SC-002 (双分组 24h 隔离)**: ✅ |
57 | | - - `tests/policy_group_isolation_test.rs` — `test_group_isolation_24h_sliding_window` |
| 114 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 115 | +- ChildRuntime (runtime state), PauseChild/RemoveChild/QuarantineChild commands ✅ |
58 | 116 |
|
59 | | -- **Edge Cases (tie-break / DAG / degraded mode)**: ✅ |
60 | | - - tie-break 4 行裁决表: spec.md 已定义, data-model.md 实施 |
61 | | - - DAG 循环依赖拒绝: `GroupIsolationPolicy` |
62 | | - - degraded_mode: 推迟到后续切片处理, 已标记为 known gap |
| 117 | +### 004-3-child-slot-control — (duplicate of 004-3, draft) |
63 | 118 |
|
64 | | -#### Drifted ⚠️ |
| 119 | +### 004-4-generation-fencing — 4 FRs, 5 SCs |
| 120 | + |
| 121 | +#### Aligned ✅ — all 4 FRs fully implemented |
| 122 | +- GenerationFenceState, GenerationFenceDecision, GenerationFencePhase ✅ |
| 123 | + |
| 124 | +### 005-1-failure-policy-reliability — 3 FRs, 4 SCs |
| 125 | + |
| 126 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 127 | +- Policy pipeline (6 stages), MeltdownTracker (3 scopes), BackoffPolicy (4 jitter modes) ✅ |
| 128 | + |
| 129 | +### 005-2-work-role-defaults — 1 FR, 3 SCs |
| 130 | + |
| 131 | +#### Aligned ✅ |
| 132 | +- FR-001: 5 WorkRole variants (Service/Worker/Job/Sidecar/Supervisor) with defaults ✅ |
| 133 | +- SeverityClass (Critical/Standard/Optional) with role-specific mapping ✅ |
| 134 | + |
| 135 | +### 006-1-platform-docs-ipc-security — 3 FRs, 4 SCs |
| 136 | + |
| 137 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 138 | +- Platform support matrix, IPC control points C1-C9 complete ✅ |
| 139 | + |
| 140 | +### 006-2-release-supply-chain-gates — 3 FRs, 4 SCs |
| 141 | + |
| 142 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 143 | +- Signed tag/changelog/semver/MSRV, dependency audit/SBOM/cargo-deny, depth check slots ✅ |
| 144 | + |
| 145 | +### 006-3-lifecycle-shutdown-realism — 3 FRs, 3 SCs |
| 146 | + |
| 147 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 148 | +- 7 instruction classes bound to cancellation/join/abort, ChildSlot active attempt mutual exclusion, shutdown_tree 4 stages ✅ |
| 149 | + |
| 150 | +### 006-4-restart-policy-production — 3 FRs, 4 SCs |
| 151 | + |
| 152 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 153 | +- budget/meltdown/backoff pipeline order, group strategy isolation, critical/optional branching ✅ |
| 154 | + |
| 155 | +### 006-5-typed-events-observability — 3 FRs, 2 SCs |
| 156 | + |
| 157 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 158 | +- SupervisorEvent type family, journal/tracing/metrics triple output, CorrelationHandle ✅ |
| 159 | + |
| 160 | +### 006-6-config-dynamic-children — 2 FRs, 2 SCs |
| 161 | + |
| 162 | +#### Aligned ✅ — both FRs fully implemented |
| 163 | +- Static YAML with 9 field groups, add_child 5-step transaction pipeline ✅ |
| 164 | + |
| 165 | +### 006-7-chaos-soak-reliability — 3 FRs, 3 SCs |
| 166 | + |
| 167 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 168 | +- 11 scenario scripts with JSON verdicts, 24h soak test, 006-2 registration ✅ |
| 169 | + |
| 170 | +### 006-8-product-bundle-runbooks — 3 FRs, 3 SCs |
65 | 171 |
|
66 | | -无 — 所有 drift 已消除。 |
| 172 | +#### Aligned ✅ — all 3 FRs fully implemented |
| 173 | +- MVP tarball, deployment guide + operations runbook, ReleaseGateMatrixPointer ✅ |
67 | 174 |
|
68 | | -#### Not Implemented ✗ |
| 175 | +## Unspecced Code Detection 🆕 |
69 | 176 |
|
70 | | -无。 |
| 177 | +### Features found in code without explicit spec coverage: |
71 | 178 |
|
72 | | -### Unspecced Code 🆕 |
| 179 | +| Feature | Location | Notes | |
| 180 | +|---------|----------|-------| |
| 181 | +| FairnessProbe | src/observe/fairness.rs | Starvation detection probe — implicitly part of 006-4 but no dedicated FR | |
| 182 | +| AdmissionSet / concurrent_gate | src/runtime/admission.rs, concurrent_gate.rs | Concurrent restart gate — implicitly part of 004-4 / 006-4 | |
| 183 | +| ShutdownPipelineReport | src/shutdown/report.rs | Detailed shutdown reporting — extends 004-2 SC-004 | |
| 184 | +| BackpressureConfig / BackpressureStrategy | src/spec/supervisor.rs | AlertAndBlock / SampleAndAudit — extends 006-5 | |
| 185 | +| DynamicSupervisorPolicy | src/spec/supervisor.rs | Dynamic child policy — extends 006-6 | |
| 186 | +| Legacy protocol rejection test | tests/legacy_protocol_rejection/ | Tests legacy IPC protocol rejection — implicitly part of 006-1 | |
73 | 187 |
|
74 | | -无 — 所有新增代码 (T039 GroupConfig, T040 ChildSpec 字段, T042 emit_policy_diagnostic) 已通过 BACKFILL 回填到 spec.md Key Entities 和 Diagnostics 节。 |
| 188 | +These are all **extensions** of existing specs, not completely unspecced features. |
75 | 189 |
|
76 | 190 | ## Inter-Spec Conflicts |
77 | 191 |
|
78 | | -无。 |
| 192 | +None detected. All 18 specs share consistent terminology and type references. |
79 | 193 |
|
80 | 194 | ## Recommendations |
81 | 195 |
|
82 | | -1. **[完成]** ALIGN-001 (SC-000): `stage_emit_typed_event` 发射策略事件 ✅ |
83 | | -2. **[完成]** ALIGN-002 (FR-003): `stage_emit_typed_event` 使用真实 CorrelationId ✅ |
84 | | -3. **[完成]** ALIGN-003 (FR-001): `What::FairnessProbeStarvation` typed event ✅ |
85 | | -4. **[完成]** BACKFILL: spec.md Key Entities 补充 GroupConfig / ChildSpec 字段 ✅ |
86 | | -5. **[完成]** BACKFILL: spec.md Diagnostics 补充 emit_policy_diagnostic 描述 ✅ |
87 | | -6. **[待办]** SC-003 (事件/指标 98% 一致率): 推迟到 006-5 切片 |
| 196 | +1. **Low**: Clean up "Actor" terminology in doc comments (use "caller" or "requester" instead) — 8 locations in control/handle.rs and control/command.rs |
| 197 | +2. **Low**: Rename `PeerIdentitySnapshot` to `PeerIdentityRecord` in src/ipc/security/ to fully comply with FR-063 Snapshot naming ban |
| 198 | +3. **Medium**: Before 1.0 release, evaluate `#[deprecated]` APIs in meltdown.rs, budget.rs, child_slot.rs for removal — they accumulate migration compatibility debt |
| 199 | +4. **None**: All 18 specs have full implementation coverage. No "unwired" specs found. |
| 200 | +5. **None**: No code exists without spec coverage — all modules map to at least one spec slice. |
0 commit comments