agentic-orchestrator 0.1.25 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/agentic/orchestrator/defaults/policy.defaults.yaml +1 -0
  2. package/agentic/orchestrator/policy.yaml +1 -0
  3. package/agentic/orchestrator/schemas/policy.schema.json +4 -0
  4. package/agentic/orchestrator/schemas/policy.user.schema.json +4 -0
  5. package/apps/control-plane/src/application/services/activity-monitor-service.ts +42 -0
  6. package/apps/control-plane/src/application/services/collision-queue-service.ts +48 -0
  7. package/apps/control-plane/src/application/services/cost-tracking-service.ts +80 -0
  8. package/apps/control-plane/src/application/services/feature-deletion-service.ts +57 -0
  9. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +65 -0
  10. package/apps/control-plane/src/application/services/feature-state-service.ts +87 -0
  11. package/apps/control-plane/src/application/services/gate-selection-service.ts +28 -0
  12. package/apps/control-plane/src/application/services/gate-service.ts +148 -0
  13. package/apps/control-plane/src/application/services/issue-tracker-service.ts +28 -0
  14. package/apps/control-plane/src/application/services/lock-service.ts +88 -0
  15. package/apps/control-plane/src/application/services/merge-service.ts +63 -0
  16. package/apps/control-plane/src/application/services/notifier-service.ts +70 -0
  17. package/apps/control-plane/src/application/services/patch-service.ts +95 -0
  18. package/apps/control-plane/src/application/services/performance-analytics-service.ts +90 -0
  19. package/apps/control-plane/src/application/services/plan-service.ts +184 -0
  20. package/apps/control-plane/src/application/services/pr-monitor-service.ts +58 -0
  21. package/apps/control-plane/src/application/services/qa-index-service.ts +68 -0
  22. package/apps/control-plane/src/application/services/reactions-service.ts +77 -0
  23. package/apps/control-plane/src/application/services/reporting-service.ts +79 -0
  24. package/apps/control-plane/src/application/services/run-lease-service.ts +79 -0
  25. package/apps/control-plane/src/application/tools/tool-router.ts +76 -0
  26. package/apps/control-plane/src/mcp/tool-runtime.ts +4 -0
  27. package/apps/control-plane/src/providers/providers.ts +96 -0
  28. package/apps/control-plane/src/providers/worker-provider-factory.ts +4 -0
  29. package/apps/control-plane/src/supervisor/build-wave-executor.ts +4 -0
  30. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +4 -0
  31. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +4 -0
  32. package/apps/control-plane/src/supervisor/run-coordinator.ts +4 -0
  33. package/apps/control-plane/src/supervisor/runtime.ts +4 -0
  34. package/apps/control-plane/src/supervisor/session-orchestrator.ts +4 -0
  35. package/apps/control-plane/test/dashboard-api.integration.spec.ts +310 -1
  36. package/apps/control-plane/test/dashboard-client.spec.ts +136 -1
  37. package/apps/control-plane/test/dashboard-live-feed.spec.ts +153 -0
  38. package/apps/control-plane/test/dashboard-ui-utils.spec.ts +132 -0
  39. package/apps/control-plane/test/mcp.spec.ts +96 -0
  40. package/apps/control-plane/test/tool-runtime.spec.ts +68 -0
  41. package/config/agentic/orchestrator/policy.yaml +1 -0
  42. package/dist/apps/control-plane/application/services/activity-monitor-service.d.ts +42 -0
  43. package/dist/apps/control-plane/application/services/activity-monitor-service.js +42 -0
  44. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
  45. package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +48 -0
  46. package/dist/apps/control-plane/application/services/collision-queue-service.js +48 -0
  47. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
  48. package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +79 -0
  49. package/dist/apps/control-plane/application/services/cost-tracking-service.js +76 -0
  50. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
  51. package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +57 -0
  52. package/dist/apps/control-plane/application/services/feature-deletion-service.js +57 -0
  53. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  54. package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +64 -0
  55. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +61 -0
  56. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
  57. package/dist/apps/control-plane/application/services/feature-state-service.d.ts +86 -0
  58. package/dist/apps/control-plane/application/services/feature-state-service.js +83 -0
  59. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
  60. package/dist/apps/control-plane/application/services/gate-selection-service.d.ts +28 -0
  61. package/dist/apps/control-plane/application/services/gate-selection-service.js +28 -0
  62. package/dist/apps/control-plane/application/services/gate-selection-service.js.map +1 -1
  63. package/dist/apps/control-plane/application/services/gate-service.d.ts +148 -0
  64. package/dist/apps/control-plane/application/services/gate-service.js +120 -0
  65. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  66. package/dist/apps/control-plane/application/services/issue-tracker-service.d.ts +28 -0
  67. package/dist/apps/control-plane/application/services/issue-tracker-service.js +28 -0
  68. package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
  69. package/dist/apps/control-plane/application/services/lock-service.d.ts +88 -0
  70. package/dist/apps/control-plane/application/services/lock-service.js +64 -0
  71. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
  72. package/dist/apps/control-plane/application/services/merge-service.d.ts +62 -0
  73. package/dist/apps/control-plane/application/services/merge-service.js +59 -0
  74. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  75. package/dist/apps/control-plane/application/services/notifier-service.d.ts +70 -0
  76. package/dist/apps/control-plane/application/services/notifier-service.js +70 -0
  77. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
  78. package/dist/apps/control-plane/application/services/patch-service.d.ts +94 -0
  79. package/dist/apps/control-plane/application/services/patch-service.js +91 -0
  80. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
  81. package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +89 -0
  82. package/dist/apps/control-plane/application/services/performance-analytics-service.js +86 -0
  83. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
  84. package/dist/apps/control-plane/application/services/plan-service.d.ts +287 -0
  85. package/dist/apps/control-plane/application/services/plan-service.js +207 -0
  86. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  87. package/dist/apps/control-plane/application/services/pr-monitor-service.d.ts +58 -0
  88. package/dist/apps/control-plane/application/services/pr-monitor-service.js +58 -0
  89. package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
  90. package/dist/apps/control-plane/application/services/qa-index-service.d.ts +67 -0
  91. package/dist/apps/control-plane/application/services/qa-index-service.js +64 -0
  92. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
  93. package/dist/apps/control-plane/application/services/reactions-service.d.ts +76 -0
  94. package/dist/apps/control-plane/application/services/reactions-service.js +73 -0
  95. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
  96. package/dist/apps/control-plane/application/services/reporting-service.d.ts +78 -0
  97. package/dist/apps/control-plane/application/services/reporting-service.js +75 -0
  98. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  99. package/dist/apps/control-plane/application/services/run-lease-service.d.ts +79 -0
  100. package/dist/apps/control-plane/application/services/run-lease-service.js +79 -0
  101. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  102. package/dist/apps/control-plane/application/tools/tool-router.d.ts +76 -0
  103. package/dist/apps/control-plane/application/tools/tool-router.js +62 -0
  104. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
  105. package/dist/apps/control-plane/mcp/tool-runtime.d.ts +3 -0
  106. package/dist/apps/control-plane/mcp/tool-runtime.js +3 -0
  107. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
  108. package/dist/apps/control-plane/providers/providers.d.ts +88 -0
  109. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  110. package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +3 -0
  111. package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
  112. package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +3 -0
  113. package/dist/apps/control-plane/supervisor/build-wave-executor.js +3 -0
  114. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  115. package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +3 -0
  116. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +3 -0
  117. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
  118. package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +3 -0
  119. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +3 -0
  120. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  121. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +3 -0
  122. package/dist/apps/control-plane/supervisor/run-coordinator.js +3 -0
  123. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  124. package/dist/apps/control-plane/supervisor/runtime.d.ts +3 -0
  125. package/dist/apps/control-plane/supervisor/runtime.js +3 -0
  126. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  127. package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +3 -0
  128. package/dist/apps/control-plane/supervisor/session-orchestrator.js +3 -0
  129. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
  130. package/package.json +1 -1
  131. package/packages/web-dashboard/src/app/analytics/page.tsx +451 -0
  132. package/packages/web-dashboard/src/app/api/analytics/route.ts +62 -0
  133. package/packages/web-dashboard/src/app/api/collisions/route.ts +63 -0
  134. package/packages/web-dashboard/src/app/api/features/[id]/cost/route.ts +29 -0
  135. package/packages/web-dashboard/src/app/api/features/[id]/review-brief/route.ts +31 -0
  136. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -8
  137. package/packages/web-dashboard/src/app/api/features/[id]/test-index/route.ts +31 -0
  138. package/packages/web-dashboard/src/app/api/flaky/route.ts +20 -0
  139. package/packages/web-dashboard/src/app/api/policy/budget/route.ts +31 -0
  140. package/packages/web-dashboard/src/app/api/run/route.ts +162 -0
  141. package/packages/web-dashboard/src/app/api/status/route.ts +2 -5
  142. package/packages/web-dashboard/src/app/feature/[id]/page.tsx +112 -0
  143. package/packages/web-dashboard/src/app/page.tsx +379 -77
  144. package/packages/web-dashboard/src/components/agent-pipeline-stepper.tsx +100 -0
  145. package/packages/web-dashboard/src/components/dependency-chains.tsx +58 -0
  146. package/packages/web-dashboard/src/components/detail-panel.tsx +215 -5
  147. package/packages/web-dashboard/src/components/feature-card.tsx +5 -0
  148. package/packages/web-dashboard/src/components/feature-cost-panel.tsx +66 -0
  149. package/packages/web-dashboard/src/components/feature-list-view.tsx +336 -0
  150. package/packages/web-dashboard/src/components/gate-step-drilldown.tsx +92 -0
  151. package/packages/web-dashboard/src/components/kanban-board.tsx +3 -0
  152. package/packages/web-dashboard/src/components/live-event-feed.tsx +60 -0
  153. package/packages/web-dashboard/src/components/lock-resource-map.tsx +73 -0
  154. package/packages/web-dashboard/src/components/plan-revision-timeline.tsx +55 -0
  155. package/packages/web-dashboard/src/components/plan-risk-annotations.tsx +63 -0
  156. package/packages/web-dashboard/src/components/plan-scope-tree.tsx +285 -0
  157. package/packages/web-dashboard/src/components/qa-coverage-map.tsx +174 -0
  158. package/packages/web-dashboard/src/components/quick-launch-panel.tsx +70 -0
  159. package/packages/web-dashboard/src/components/review-brief-panel.tsx +75 -0
  160. package/packages/web-dashboard/src/components/run-health-panel.tsx +85 -0
  161. package/packages/web-dashboard/src/components/summary-bar.tsx +59 -2
  162. package/packages/web-dashboard/src/components/verification-signals.tsx +167 -0
  163. package/packages/web-dashboard/src/lib/analytics-utils.ts +3 -0
  164. package/packages/web-dashboard/src/lib/aop-client.ts +510 -11
  165. package/packages/web-dashboard/src/lib/api-envelope.ts +48 -0
  166. package/packages/web-dashboard/src/lib/authz-adapter.ts +33 -0
  167. package/packages/web-dashboard/src/lib/dashboard-utils.ts +304 -0
  168. package/packages/web-dashboard/src/lib/live-feed.ts +218 -0
  169. package/packages/web-dashboard/src/lib/policy-reader.ts +22 -0
  170. package/packages/web-dashboard/src/lib/types.ts +114 -0
  171. package/packages/web-dashboard/src/styles/dashboard.module.css +341 -1
  172. package/spec-files/{outstanding → completed}/agentic_orchestrator_dashboard_advanced_ux_spec.md +1 -1
  173. package/spec-files/outstanding/agentic_orchestrator_evidence_integrity_doctor_spec.md +561 -0
  174. package/spec-files/outstanding/agentic_orchestrator_kernel_simplification_spec.md +834 -0
  175. package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +12 -5
  176. package/spec-files/outstanding/agentic_orchestrator_observability_replay_spec.md +442 -0
  177. package/spec-files/progress.md +174 -1
@@ -0,0 +1,561 @@
1
+ # Feature Spec: Evidence Integrity Chain + Doctor Diagnostics (AOP)
2
+
3
+ > **Split from**: `agentic_orchestrator_observability_integrity_diagnostics_spec.md` (v2.0)
4
+ > **Covers**: OID2 (Q4 Evidence Integrity) + OID3 (Q11 Doctor) + OID4 (CLI surface) + OID5 (Hardening)
5
+ > **Roadmap Mapping:** M33 / Q4 + Q11
6
+
7
+ **Version:** 1.0
8
+ **Date:** 2026-03-05
9
+ **Status:** Implementation-Ready
10
+
11
+ ---
12
+
13
+ ## 0. Standards and Dependencies
14
+
15
+ ### 0.1 Prerequisite
16
+
17
+ **This spec MUST NOT begin implementation until `agentic_orchestrator_observability_replay_spec` has been merged.**
18
+
19
+ Specifically, that spec's OID0 must be complete, which provides:
20
+
21
+ - Policy schema extensions for `innovation`, `observability`, and `diagnostics` sections
22
+ - Error codes: `evidence_chain_missing`, `evidence_chain_artifact_missing`, `evidence_chain_hash_mismatch`, `evidence_chain_discontinuity`, `evidence_integrity_write_failed`, `doctor_check_failed`, `doctor_report_write_failed`
23
+ - Tool catalog stubs for `evidence.verify_chain` and `doctor.run`
24
+ - Tool schema stub files for both tools
25
+ - TOOLS constants: `TOOLS.EVIDENCE_VERIFY_CHAIN`, `TOOLS.DOCTOR_RUN`
26
+
27
+ Verify this before planning:
28
+
29
+ ```bash
30
+ grep -q "evidence_chain_missing" apps/control-plane/src/core/error-codes.ts
31
+ grep -q "evidence.verify_chain" agentic/orchestrator/tools/catalog.json
32
+ ```
33
+
34
+ If either check fails, do not proceed — block on the prerequisite spec.
35
+
36
+ ### 0.2 Required Standards
37
+
38
+ All implementation MUST preserve:
39
+
40
+ - deterministic tool behavior and normalized error envelopes
41
+ - MCP/in-process transport parity for all new tools
42
+ - strict contract validation (`validate:mcp-contracts`) and architecture boundaries (`validate:architecture`)
43
+ - runtime artifact ownership under `.aop/**`
44
+ - existing idempotency semantics for mutating tools
45
+
46
+ ### 0.3 Required Upstream Inputs
47
+
48
+ Implementing agents MUST read before writing any code:
49
+
50
+ - `apps/control-plane/src/application/services/gate-service.ts`
51
+ - `apps/control-plane/src/core/gates.ts`
52
+ - `apps/control-plane/src/core/path-layout.ts`
53
+ - `apps/control-plane/src/core/kernel.ts`
54
+ - `apps/control-plane/src/core/constants.ts`
55
+ - `apps/control-plane/src/core/error-codes.ts`
56
+ - `apps/control-plane/src/application/services/reporting-service.ts`
57
+ - `apps/control-plane/src/cli/types.ts`
58
+ - `apps/control-plane/src/cli/cli-argument-parser.ts`
59
+ - `apps/control-plane/src/cli/help-command-handler.ts`
60
+ - `apps/control-plane/src/interfaces/cli/bootstrap.ts`
61
+ - `apps/control-plane/src/application/tools/tool-metadata.ts`
62
+ - `agentic/orchestrator/defaults/policy.defaults.yaml`
63
+ - `agentic/orchestrator/schemas/policy.schema.json`
64
+ - `agentic/orchestrator/tools/catalog.json`
65
+
66
+ ### 0.4 Feature Scope
67
+
68
+ This spec implements:
69
+
70
+ - **OID2**: Q4 Tamper-Evident Evidence Integrity Chain
71
+ - **OID3**: Q11 `aop doctor` Readiness + Drift Diagnostics
72
+ - **OID4** (evidence + doctor portion): `aop evidence verify` and `aop doctor` CLI commands
73
+ - **OID5**: Hardening, performance, and retention rules
74
+
75
+ Out of scope:
76
+
77
+ - Policy schema extensions (already done by prerequisite spec)
78
+ - Error code additions (already done by prerequisite spec)
79
+ - Replay timeline (covered by prerequisite spec)
80
+ - `aop replay` CLI command (covered by prerequisite spec)
81
+ - Autonomous RCA narrative generation
82
+ - External KMS/HSM signing
83
+ - Remote telemetry backends
84
+
85
+ ---
86
+
87
+ ## 1. Architectural Context
88
+
89
+ ### 1.1 Critical Integration Corrections
90
+
91
+ Before implementing OID2, apply this fix to `GateService.evidenceLatest()`:
92
+
93
+ **Current behavior**: scans all `*.json` files in the evidence directory by mtime.
94
+ **Problem**: adding `chain.jsonl` and `manifest.integrity.json` to the evidence directory will cause `evidence.latest` to return chain metadata instead of the actual latest gate evidence.
95
+ **Fix**: restrict `evidenceLatest()` to files matching `gate-*.json` and `latest-*.json` patterns only.
96
+
97
+ This fix must land before any chain files are written to the evidence directory.
98
+
99
+ ### 1.2 Existing Runtime Touchpoints
100
+
101
+ - **Evidence write path**: `GateService.gatesRun()` + `core/gates.ts` is the authoritative source for gate evidence artifacts. `EvidenceIntegrityService` hooks into the GateService write path.
102
+ - **Read/report path**: `ReportingService` is the read aggregation surface. Integrity checks must not bypass service boundaries.
103
+ - **Config validation**: `SchemaRegistry` + `loadComposedPolicy` used by doctor for DRIFT_001/DRIFT_002 checks.
104
+
105
+ ### 1.3 Boundary Rules (Normative)
106
+
107
+ - `core/*` remains pure infrastructure/domain helpers.
108
+ - Evidence chain append/verify belongs in `application/services/` and is invoked from `GateService` write path.
109
+ - Doctor scans are deterministic local checks only (file/config/runtime state). No network dependency.
110
+ - Chain verification is read-only — it never mutates evidence artifacts.
111
+
112
+ ---
113
+
114
+ ## 2. Contracts
115
+
116
+ ### 2.1 Evidence Integrity Chain Contracts
117
+
118
+ Paths:
119
+
120
+ ```text
121
+ .aop/features/<feature_id>/evidence/chain.jsonl
122
+ .aop/features/<feature_id>/evidence/manifest.integrity.json
123
+ ```
124
+
125
+ Chain entry contract (one JSON line per tracked artifact):
126
+
127
+ ```json
128
+ {
129
+ "algorithm_version": 1,
130
+ "sequence": 7,
131
+ "feature_id": "feature_x",
132
+ "artifact_rel_path": "evidence/gate-full-1741050000.json",
133
+ "artifact_hash": "sha256:...",
134
+ "prev_chain_hash": "sha256:...",
135
+ "chain_hash": "sha256:...",
136
+ "created_at": "2026-03-04T10:15:01.000Z"
137
+ }
138
+ ```
139
+
140
+ Hash payload (canonical JSON with stable key order, used to compute `chain_hash`):
141
+
142
+ ```json
143
+ {
144
+ "algorithm_version": 1,
145
+ "sequence": 7,
146
+ "feature_id": "feature_x",
147
+ "artifact_rel_path": "evidence/gate-full-1741050000.json",
148
+ "artifact_hash": "sha256:...",
149
+ "prev_chain_hash": "sha256:..."
150
+ }
151
+ ```
152
+
153
+ Manifest contract (`.manifest.integrity.json`):
154
+
155
+ ```json
156
+ {
157
+ "entry_count": 7,
158
+ "head_hash": "sha256:...",
159
+ "last_verified_at": "2026-03-04T10:30:00.000Z",
160
+ "last_verified_result": "ok"
161
+ }
162
+ ```
163
+
164
+ Rules:
165
+
166
+ - `chain_hash = sha256(canonical_json(hash_payload))`.
167
+ - `prev_chain_hash` for the first entry is `"sha256:genesis"` (fixed sentinel).
168
+ - Key order for canonical JSON: `algorithm_version`, `sequence`, `feature_id`, `artifact_rel_path`, `artifact_hash`, `prev_chain_hash`.
169
+ - `artifact_hash = sha256(file_contents)` in hex format, prefixed `sha256:`.
170
+ - Chain append is per-feature file-locked on `chain.jsonl`.
171
+ - Tracked artifacts in v1 scope: files matching `gate-*.json` and `latest-*.json` only.
172
+ - Verification fails closed: missing artifact, hash mismatch, or chain discontinuity all return failure with first failing sequence and reason.
173
+
174
+ ### 2.2 Doctor Report Contract
175
+
176
+ Paths:
177
+
178
+ ```text
179
+ .aop/runtime/doctor/last_report.json
180
+ .aop/runtime/doctor/history/<timestamp>.json
181
+ ```
182
+
183
+ Report contract:
184
+
185
+ ```json
186
+ {
187
+ "ok": true,
188
+ "generated_at": "2026-03-04T10:30:00.000Z",
189
+ "summary": {
190
+ "critical": 0,
191
+ "warning": 1,
192
+ "info": 3
193
+ },
194
+ "findings": [
195
+ {
196
+ "id": "DRIFT_004_STALE_RUN_LEASE",
197
+ "severity": "warning",
198
+ "message": "Run lease appears stale and still populated",
199
+ "remediation": "Run `aop run --takeover-stale-run` or clear stale lease after verification",
200
+ "refs": [".aop/runtime/default/run-lease.json"]
201
+ }
202
+ ]
203
+ }
204
+ ```
205
+
206
+ Rules:
207
+
208
+ - Findings sorted lexically by `id`.
209
+ - `summary` counts derived strictly from the `findings` array — never set independently.
210
+ - `ok = (summary.critical === 0)` in normal mode.
211
+ - `ok = (summary.critical === 0 && summary.warning === 0)` in strict mode (affects CLI exit code only, not stored `ok`).
212
+
213
+ ### 2.3 `evidence.verify_chain` Tool (Replaces Stub from Prerequisite Spec)
214
+
215
+ Read-only tool. Verifies the integrity chain for a feature.
216
+
217
+ Input schema:
218
+
219
+ ```json
220
+ {
221
+ "type": "object",
222
+ "required": ["feature_id"],
223
+ "properties": {
224
+ "feature_id": { "type": "string", "minLength": 1 }
225
+ }
226
+ }
227
+ ```
228
+
229
+ Output schema:
230
+
231
+ ```json
232
+ {
233
+ "type": "object",
234
+ "required": ["feature_id", "valid", "entry_count"],
235
+ "properties": {
236
+ "feature_id": { "type": "string" },
237
+ "valid": { "type": "boolean" },
238
+ "entry_count": { "type": "integer" },
239
+ "first_failure_sequence": { "type": "integer" },
240
+ "failure_reason": { "type": "string" }
241
+ }
242
+ }
243
+ ```
244
+
245
+ Returns `evidence_chain_missing` error if `chain.jsonl` does not exist.
246
+
247
+ ### 2.4 `doctor.run` Tool (Replaces Stub from Prerequisite Spec)
248
+
249
+ Mutating tool (persists report artifacts). Requires `operation_id`.
250
+
251
+ Input schema:
252
+
253
+ ```json
254
+ {
255
+ "type": "object",
256
+ "properties": {
257
+ "strict": { "type": "boolean" }
258
+ }
259
+ }
260
+ ```
261
+
262
+ Output schema: the full doctor report object (§2.2 contract).
263
+
264
+ ---
265
+
266
+ ## 3. Detailed Implementation Plan
267
+
268
+ ### OID2: Q4 Evidence Integrity Chain
269
+
270
+ #### 3.1 Pre-work: Fix `GateService.evidenceLatest()`
271
+
272
+ **Immediate fix before any chain files exist:**
273
+
274
+ In `apps/control-plane/src/application/services/gate-service.ts`, update `evidenceLatest()` to filter the evidence directory contents to only files matching `gate-*.json` or `latest-*.json`. Reject `chain.jsonl`, `manifest.integrity.json`, and any other file.
275
+
276
+ Add a regression test in `apps/control-plane/test/gates.spec.ts`:
277
+
278
+ - `evidenceLatest` ignores `chain.jsonl` when present alongside gate files.
279
+ - `evidenceLatest` ignores `manifest.integrity.json` when present.
280
+
281
+ #### 3.2 Path-layout Helpers
282
+
283
+ Add to `AopPathLayout` in `apps/control-plane/src/core/path-layout.ts`:
284
+
285
+ ```
286
+ evidenceChainPath(featureId): string // .aop/features/<id>/evidence/chain.jsonl
287
+ evidenceManifestPath(featureId): string // .aop/features/<id>/evidence/manifest.integrity.json
288
+ evidenceChainLockPath(featureId): string // .aop/features/<id>/evidence/chain.lock
289
+ doctorReportPath(): string // .aop/runtime/doctor/last_report.json
290
+ doctorHistoryDir(): string // .aop/runtime/doctor/history/
291
+ doctorHistoryPath(ts: string): string // .aop/runtime/doctor/history/<ts>.json
292
+ ```
293
+
294
+ #### 3.3 EvidenceIntegrityService
295
+
296
+ **Write path algorithm** (`append(featureId, artifactRelPath)`):
297
+
298
+ 1. Check policy: `innovation.tamper_evident_evidence && observability.evidence_integrity.enabled`. If false, return early (no-op).
299
+ 2. Acquire per-feature chain lock.
300
+ 3. Compute `artifact_hash = sha256(file_contents)` of the artifact.
301
+ 4. Read current chain tail: last line of `chain.jsonl` to get `prev_chain_hash` and `sequence`. If file is empty or missing, use `prev_chain_hash = "sha256:genesis"` and `sequence = 0`.
302
+ 5. Compute `chain_hash` from canonical hash payload.
303
+ 6. Append new entry to `chain.jsonl`.
304
+ 7. Update `manifest.integrity.json` with new `entry_count` and `head_hash`.
305
+ 8. Release lock.
306
+ 9. On error: if enabled via policy, propagate as `evidence_integrity_write_failed`. Otherwise log and continue.
307
+
308
+ **Verify algorithm** (`verify(featureId)`):
309
+
310
+ 1. Check `chain.jsonl` exists; return `evidence_chain_missing` error if not.
311
+ 2. Read all entries in order.
312
+ 3. For each entry:
313
+ a. Check artifact file exists; fail with `evidence_chain_artifact_missing` if not.
314
+ b. Recompute `artifact_hash`; fail with `evidence_chain_hash_mismatch` if mismatch.
315
+ c. Recompute `chain_hash` from canonical payload; fail with `evidence_chain_hash_mismatch` if mismatch.
316
+ d. Check `prev_chain_hash` matches previous entry's `chain_hash` (or genesis for sequence 0); fail with `evidence_chain_discontinuity` if not.
317
+ 4. Return `{ valid: true, entry_count }` on full pass.
318
+ 5. Return `{ valid: false, entry_count, first_failure_sequence, failure_reason }` on first failure.
319
+
320
+ **GateService integration** — after `gatesRun()` successfully writes gate evidence files, call `EvidenceIntegrityService.append()` for each tracked artifact (`gate-*.json`, `latest-*.json`). This is a best-effort call by default.
321
+
322
+ **Implementation targets**:
323
+
324
+ - `apps/control-plane/src/application/services/evidence-integrity-service.ts` (new)
325
+ - `apps/control-plane/src/application/services/gate-service.ts` — fix `evidenceLatest`, add `EvidenceIntegrityService` integration
326
+ - `apps/control-plane/src/core/path-layout.ts` — evidence chain + doctor path helpers
327
+ - `apps/control-plane/src/core/kernel.ts` — register `evidence.verify_chain` handler
328
+
329
+ **Test plan**:
330
+
331
+ - `apps/control-plane/test/evidence-integrity-service.spec.ts` (new):
332
+ - genesis entry written correctly (prev_chain_hash sentinel)
333
+ - chain append: sequence increments, chain_hash computed correctly
334
+ - verify: untampered chain returns `valid: true`
335
+ - verify: tampered artifact content → `evidence_chain_hash_mismatch`
336
+ - verify: tampered chain_hash in entry → `evidence_chain_hash_mismatch`
337
+ - verify: deleted artifact → `evidence_chain_artifact_missing`
338
+ - verify: discontinuous `prev_chain_hash` → `evidence_chain_discontinuity`
339
+ - append when policy disabled: no-op, no files created
340
+ - Extend `apps/control-plane/test/gates.spec.ts`:
341
+ - `evidenceLatest` ignores `chain.jsonl` and `manifest.integrity.json`
342
+ - Extend `apps/control-plane/test/kernel.spec.ts`:
343
+ - `evidence.latest` still returns gate evidence artifact, not chain metadata
344
+ - Extend `apps/control-plane/test/mcp.spec.ts`:
345
+ - `evidence.verify_chain` parity (in-process vs MCP)
346
+
347
+ **Exit criteria**:
348
+
349
+ - Tampered artifact triggers deterministic failure with reason and first failing sequence
350
+ - Untampered chain verifies successfully end-to-end
351
+ - `evidenceLatest` unaffected by chain files
352
+
353
+ ---
354
+
355
+ ### OID3: Q11 Doctor Diagnostics
356
+
357
+ #### 3.4 DoctorService
358
+
359
+ Implement deterministic scanner with fixed check IDs, strict severity, and stable output ordering.
360
+
361
+ **Required checks (v1)** — executed in lexical order by check ID:
362
+
363
+ | ID | Severity | Description |
364
+ | ------------------------------------- | -------- | --------------------------------------------------------------------------------------------------- |
365
+ | `DRIFT_001_POLICY_SCHEMA_INVALID` | critical | Policy file fails `loadComposedPolicy` validation |
366
+ | `DRIFT_002_GATES_SCHEMA_INVALID` | critical | Gates file fails schema validation |
367
+ | `DRIFT_003_TOOL_CONTRACT_DRIFT` | warning | Any tool schema in catalog fails `validate:mcp-contracts` logic |
368
+ | `DRIFT_004_STALE_RUN_LEASE` | warning | Run lease exists and `lease_expires_at` is in the past |
369
+ | `DRIFT_005_RUNTIME_SESSION_ORPHANS` | warning | Feature session IDs in run lease reference feature IDs not in `index.active` |
370
+ | `DRIFT_006_TIMELINE_CORRUPTION` | warning | Any timeline file contains unparseable lines (only checked if replay enabled) |
371
+ | `DRIFT_007_EVIDENCE_CHAIN_INVALID` | warning | Any feature's integrity chain fails verification (only checked if evidence integrity enabled) |
372
+ | `DRIFT_008_INDEX_STATE_INCONSISTENCY` | critical | Feature IDs appear in multiple index lists simultaneously (active + blocked, active + merged, etc.) |
373
+
374
+ **Deterministic output rules**:
375
+
376
+ - Check execution order: fixed lexically by check ID (DRIFT_001 → DRIFT_008).
377
+ - Findings sorted by check ID in output.
378
+ - Same repo state yields identical findings array except `generated_at` and `last_verified_at` fields.
379
+ - Each check is fully independent — one check failing must not prevent subsequent checks from running.
380
+
381
+ **Doctor report persistence**:
382
+
383
+ 1. Write report to `doctorHistoryPath(generatedAt)`.
384
+ 2. Write (overwrite) `last_report.json` with same content.
385
+ 3. Prune history directory to keep newest 20 reports.
386
+
387
+ **Implementation targets**:
388
+
389
+ - `apps/control-plane/src/application/services/doctor-service.ts` (new)
390
+ - `agentic/orchestrator/schemas/doctor_report.schema.json` (new — validates report output)
391
+ - `apps/control-plane/src/core/path-layout.ts` — doctor path helpers (if not already added in OID2)
392
+ - `apps/control-plane/src/core/kernel.ts` — register `doctor.run` handler
393
+
394
+ **Test plan**:
395
+
396
+ - `apps/control-plane/test/doctor-service.spec.ts` (new):
397
+ - all 8 check IDs present in output when all failures triggered
398
+ - findings sorted lexically by ID
399
+ - `ok=false` when any critical finding present
400
+ - `ok=true` when no critical findings (warnings allowed)
401
+ - DRIFT_006 skipped (no finding emitted) when replay disabled via policy
402
+ - DRIFT_007 skipped when evidence integrity disabled via policy
403
+ - DRIFT_008 detects feature ID in both `active` and `blocked` simultaneously
404
+ - report artifact is schema-valid
405
+ - history is pruned to 20 entries
406
+ - Extend `apps/control-plane/test/cli.unit.spec.ts`:
407
+ - `doctor` command parser coverage
408
+ - `--strict` flag parsed correctly
409
+ - `--json` flag parsed correctly
410
+ - Extend `apps/control-plane/test/mcp.spec.ts`:
411
+ - `doctor.run` parity (in-process vs MCP)
412
+
413
+ **Exit criteria**:
414
+
415
+ - Report artifact passes `doctor_report.schema.json` validation
416
+ - Strict-mode exit behavior deterministic and tested
417
+ - All 8 checks execute independently
418
+
419
+ ---
420
+
421
+ ### OID4 (Evidence + Doctor Portion): CLI Surface
422
+
423
+ Add `aop evidence verify` and `aop doctor` commands.
424
+
425
+ **CLI specifications**:
426
+
427
+ ```
428
+ aop evidence verify --feature-id <id> [--json]
429
+ aop doctor [--strict] [--json]
430
+ ```
431
+
432
+ - `aop evidence verify`: calls `evidence.verify_chain` and displays result.
433
+ - `aop doctor`: calls `doctor.run`, displays findings, exits non-zero on critical (or warnings in `--strict`).
434
+ - Both support `--json` for raw tool response output.
435
+
436
+ **Required file changes** (per CLAUDE.md — all in the same change):
437
+
438
+ 1. `apps/control-plane/src/cli/types.ts` — add `CliCommand.Evidence`, `CliCommand.Doctor`; add `strict` option field
439
+ 2. `apps/control-plane/src/cli/cli-argument-parser.ts` — parse `evidence verify` subcommand and `doctor`
440
+ 3. `apps/control-plane/src/interfaces/cli/bootstrap.ts` — dispatch both commands to handlers
441
+ 4. `apps/control-plane/src/cli/help-command-handler.ts` — add `evidence` and `doctor` entries to `COMMAND_HELP`
442
+ 5. `apps/control-plane/src/cli/evidence-command-handler.ts` (new)
443
+ 6. `apps/control-plane/src/cli/doctor-command-handler.ts` (new)
444
+
445
+ **Doctor CLI semantics**:
446
+
447
+ - Normal mode: exits non-zero if any critical finding present.
448
+ - `--strict` mode: exits non-zero if any critical **or** warning finding present.
449
+ - Both modes: exits 0 if only info findings.
450
+ - `--json`: emit full report JSON regardless of findings.
451
+
452
+ **Test additions**:
453
+
454
+ - Extend `apps/control-plane/test/cli.unit.spec.ts`: parser coverage for `evidence verify` and `doctor` + flags
455
+ - `apps/control-plane/test/evidence-command-handler.spec.ts` (new): dispatch, JSON mode, error passthrough
456
+ - `apps/control-plane/test/doctor-command-handler.spec.ts` (new): strict vs normal exit codes, JSON mode
457
+
458
+ ---
459
+
460
+ ### OID5: Hardening and Retention
461
+
462
+ #### Replay Retention (Companion to Prerequisite Spec)
463
+
464
+ The prerequisite spec's `ReplayTimelineService` implements retention. This spec adds a doctor check (DRIFT_006) that detects timeline corruption. No additional replay retention work is needed here.
465
+
466
+ #### Evidence Integrity vs Retention Rule
467
+
468
+ If any evidence pruning occurs (manual or policy-driven), chain integrity may fail because chain entries reference deleted artifacts. The following invariant must be documented and enforced:
469
+
470
+ - `DRIFT_007_EVIDENCE_CHAIN_INVALID` in doctor will fire if chain references a missing file.
471
+ - Documentation must explicitly state: integrity verification requires preserving all tracked artifacts.
472
+ - Doctor finding for DRIFT_007 must include remediation text: `"Do not prune evidence artifacts when evidence_integrity is enabled. Disable integrity before pruning."`.
473
+
474
+ **Implementation targets**:
475
+
476
+ - `apps/control-plane/src/application/services/doctor-service.ts` — DRIFT_007 remediation text
477
+ - `README.md` — operational caveat section on integrity and retention
478
+
479
+ **Test plan**:
480
+
481
+ - `apps/control-plane/test/evidence-integrity-service.spec.ts`: verify correctly returns `evidence_chain_artifact_missing` when artifact deleted after chain written
482
+ - `apps/control-plane/test/doctor-service.spec.ts`: DRIFT_007 fires with correct remediation when chain references missing artifact
483
+
484
+ **Exit criteria**:
485
+
486
+ - Doctor correctly identifies integrity failures after evidence file deletion
487
+ - Remediation text is actionable and present in finding
488
+
489
+ ---
490
+
491
+ ## 4. Test Strategy Summary
492
+
493
+ ### 4.1 Unit Tests
494
+
495
+ - Chain hash recomputation and discontinuity detection
496
+ - Doctor check ID ordering and severity aggregation
497
+ - Evidence integrity write path under per-feature lock
498
+ - DRIFT_006/007 conditional execution based on policy toggles
499
+
500
+ ### 4.2 Integration Tests
501
+
502
+ - Evidence tamper triggers `evidence.verify_chain` failure with correct sequence and reason
503
+ - Doctor identifies intentionally broken policy/schema/runtime artifacts
504
+ - `evidenceLatest` unaffected by chain metadata files in evidence directory
505
+
506
+ ### 4.3 Transport Parity
507
+
508
+ - `evidence.verify_chain` parity: in-process vs MCP
509
+ - `doctor.run` parity: in-process vs MCP
510
+
511
+ ### 4.4 CLI Tests
512
+
513
+ - Parser/help/bootstrap coverage for `evidence verify` and `doctor`
514
+ - `--strict` exit code behavior
515
+ - `--json` output correctness
516
+
517
+ ### 4.5 Regression Tests
518
+
519
+ - `evidence.latest` unaffected by integrity metadata files (must be verified independently of prerequisite spec)
520
+ - Existing gate behavior preserved when integrity is disabled
521
+
522
+ ---
523
+
524
+ ## 5. Acceptance Criteria
525
+
526
+ 1. Evidence integrity chain detects tampering and discontinuities deterministically, returning first failing sequence and reason.
527
+ 2. `evidence.latest` returns gate evidence, not chain metadata, even when chain files are present.
528
+ 3. `aop doctor` produces deterministic, schema-valid findings with actionable remediations, sorted by check ID.
529
+ 4. Doctor strict mode exits non-zero on warnings; normal mode exits non-zero only on criticals.
530
+ 5. `evidence.verify_chain` and `doctor.run` tools are fully wired: constants / kernel / tool-metadata / catalog / schemas / RBAC / tools.md.
531
+ 6. `aop evidence verify` and `aop doctor` commands are fully wired: types / parser / help / bootstrap / handlers.
532
+ 7. DRIFT_007 correctly fires when an integrity-tracked artifact is missing.
533
+ 8. Quality gates pass: `lint`, `typecheck`, `test`, `validate:mcp-contracts`, `validate:architecture`.
534
+
535
+ ---
536
+
537
+ ## 6. Risks and Mitigations
538
+
539
+ - **Risk**: Chain file corruption under concurrent gate runs.
540
+ - **Mitigation**: Per-feature file lock around all chain append operations.
541
+
542
+ - **Risk**: False confidence from disabled checks in doctor.
543
+ - **Mitigation**: DRIFT_006/007 explicitly skip with an info finding when the relevant feature is disabled (no silent suppression).
544
+
545
+ - **Risk**: Schema drift between `doctor_report.schema.json` and actual service output.
546
+ - **Mitigation**: Doctor output validated against schema in service tests.
547
+
548
+ - **Risk**: `evidenceLatest` regression introduced by fix.
549
+ - **Mitigation**: Explicit regression tests for `evidenceLatest` with chain files present.
550
+
551
+ ---
552
+
553
+ ## 7. Definition of Done
554
+
555
+ A completed implementation session MUST provide:
556
+
557
+ - Changed files and rationale by phase (OID2 → OID3 → OID4 → OID5)
558
+ - Schema/catalog/RBAC deltas (tool stub schemas replaced with real schemas)
559
+ - Regenerated `tools.md`
560
+ - Test additions and executed command results (`npm test`, `npm run lint`, `npm run validate:mcp-contracts`)
561
+ - `spec-files/progress.md` update entry covering OID2, OID3, OID4, and OID5 milestones