principles-disciple 1.72.0 → 1.74.0

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 (319) hide show
  1. package/INSTALL.md +1 -3
  2. package/openclaw.plugin.json +10 -5
  3. package/package.json +17 -19
  4. package/scripts/acceptance-test.mjs +16 -73
  5. package/scripts/sync-plugin.mjs +382 -77
  6. package/src/commands/archive-impl.ts +2 -1
  7. package/src/commands/capabilities.ts +2 -2
  8. package/src/commands/context.ts +2 -2
  9. package/src/commands/disable-impl.ts +2 -1
  10. package/src/commands/evolution-status.ts +16 -16
  11. package/src/commands/export.ts +12 -67
  12. package/src/commands/pain.ts +91 -1
  13. package/src/commands/principle-rollback.ts +2 -1
  14. package/src/commands/promote-impl.ts +7 -43
  15. package/src/commands/rollback-impl.ts +2 -1
  16. package/src/commands/rollback.ts +2 -1
  17. package/src/commands/samples.ts +2 -1
  18. package/src/commands/thinking-os.ts +2 -1
  19. package/src/config/errors.ts +18 -2
  20. package/src/constants/diagnostician.ts +2 -2
  21. package/src/constants/tools.ts +2 -1
  22. package/src/core/__tests__/focus-history.test.ts +210 -0
  23. package/src/core/config.ts +1 -1
  24. package/src/core/correction-cue-learner.ts +2 -136
  25. package/src/core/correction-types.ts +16 -88
  26. package/src/core/dictionary.ts +19 -20
  27. package/src/core/empathy-keyword-matcher.ts +17 -289
  28. package/src/core/empathy-types.ts +18 -229
  29. package/src/core/event-log.ts +29 -132
  30. package/src/core/evolution-reducer.ts +21 -2
  31. package/src/core/evolution-types.ts +76 -464
  32. package/src/core/file-store.ts +80 -0
  33. package/src/core/focus-history.ts +228 -955
  34. package/src/core/local-worker-routing.ts +34 -314
  35. package/src/core/merge-gate-audit.ts +0 -195
  36. package/src/core/migration.ts +0 -1
  37. package/src/core/pain-diagnostic-gate.ts +154 -0
  38. package/src/core/pain-signal.ts +21 -138
  39. package/src/core/pain.ts +15 -88
  40. package/src/core/path-resolver.ts +0 -1
  41. package/src/core/paths.ts +0 -1
  42. package/src/core/pd-task-reconciler.ts +26 -115
  43. package/src/core/pd-task-service.ts +9 -9
  44. package/src/core/pd-task-types.ts +23 -127
  45. package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
  46. package/src/core/principle-compiler/code-validator.ts +15 -42
  47. package/src/core/principle-compiler/compiler.ts +100 -15
  48. package/src/core/principle-compiler/index.ts +5 -2
  49. package/src/core/principle-compiler/template-generator.ts +4 -104
  50. package/src/core/principle-injection.ts +10 -202
  51. package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
  52. package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
  53. package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
  54. package/src/core/principle-tree-ledger-adapter.ts +145 -0
  55. package/src/core/principle-tree-ledger.ts +8 -6
  56. package/src/core/reflection/reflection-context.ts +14 -109
  57. package/src/core/replay-engine.ts +8 -500
  58. package/src/core/rule-host-helpers.ts +5 -35
  59. package/src/core/rule-host-types.ts +10 -82
  60. package/src/core/rule-host.ts +6 -63
  61. package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
  62. package/src/core/session-tracker.ts +87 -101
  63. package/src/core/shadow-observation-registry.ts +19 -48
  64. package/src/core/trajectory.ts +3 -1
  65. package/src/core/workflow-funnel-loader.ts +62 -68
  66. package/src/core/workspace-context.ts +46 -0
  67. package/src/core/workspace-dir-service.ts +1 -1
  68. package/src/core/workspace-dir-validation.ts +18 -9
  69. package/src/hooks/AGENTS.md +1 -1
  70. package/src/hooks/gate-block-helper.ts +71 -64
  71. package/src/hooks/gate.ts +183 -31
  72. package/src/hooks/lifecycle.ts +30 -32
  73. package/src/hooks/llm.ts +60 -32
  74. package/src/hooks/pain.ts +297 -103
  75. package/src/hooks/prompt.ts +400 -440
  76. package/src/hooks/subagent.ts +2 -29
  77. package/src/i18n/commands.ts +2 -10
  78. package/src/index.ts +95 -85
  79. package/src/openclaw-sdk.ts +311 -0
  80. package/src/service/central-database.ts +8 -4
  81. package/src/service/evolution-queue-migration.ts +2 -1
  82. package/src/service/evolution-worker.ts +163 -1786
  83. package/src/service/internalization-trigger-adapter.ts +302 -0
  84. package/src/service/keyword-optimization-service.ts +4 -4
  85. package/src/service/monitoring-query-service.ts +1 -215
  86. package/src/service/queue-io.ts +60 -331
  87. package/src/service/runtime-summary-service.ts +59 -16
  88. package/src/service/subagent-workflow/index.ts +0 -41
  89. package/src/service/subagent-workflow/types.ts +9 -120
  90. package/src/service/subagent-workflow/workflow-store.ts +2 -119
  91. package/src/service/workflow-watchdog.ts +0 -43
  92. package/src/types/event-payload.ts +16 -74
  93. package/src/types/event-types.ts +38 -547
  94. package/src/types/hygiene-types.ts +7 -30
  95. package/src/types/principle-tree-schema.ts +20 -222
  96. package/src/types/queue.ts +15 -70
  97. package/src/types/runtime-summary.ts +5 -49
  98. package/src/utils/io.ts +8 -20
  99. package/src/utils/retry.ts +1 -1
  100. package/src/utils/shadow-fingerprint.ts +2 -2
  101. package/src/utils/workspace-resolver.ts +50 -0
  102. package/templates/langs/en/core/AGENTS.md +7 -7
  103. package/templates/langs/en/core/BOOT.md +1 -1
  104. package/templates/langs/en/core/HEARTBEAT.md +2 -2
  105. package/templates/langs/en/principles/THINKING_OS.md +3 -2
  106. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  107. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  108. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  109. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  110. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  111. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  112. package/templates/langs/en/skills/evolve-task/SKILL.md +3 -3
  113. package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
  114. package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
  115. package/templates/langs/en/skills/pd-mentor/SKILL.md +2 -3
  116. package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
  117. package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
  118. package/templates/langs/zh/core/AGENTS.md +7 -7
  119. package/templates/langs/zh/core/BOOT.md +1 -1
  120. package/templates/langs/zh/core/HEARTBEAT.md +2 -2
  121. package/templates/langs/zh/principles/THINKING_OS.md +3 -2
  122. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  123. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  124. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  125. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
  126. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  127. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  128. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  129. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
  130. package/templates/langs/zh/skills/evolve-task/SKILL.md +4 -4
  131. package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
  132. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
  133. package/templates/langs/zh/skills/pd-mentor/SKILL.md +2 -3
  134. package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
  135. package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
  136. package/tests/build-artifacts.test.ts +1 -3
  137. package/tests/commands/evolution-status.test.ts +0 -118
  138. package/tests/core/bootstrap-rules.test.ts +1 -1
  139. package/tests/core/config.test.ts +1 -1
  140. package/tests/core/event-log.test.ts +35 -0
  141. package/tests/core/evolution-engine.test.ts +610 -0
  142. package/tests/core/file-store.test.ts +102 -0
  143. package/tests/core/focus-history.test.ts +203 -11
  144. package/tests/core/merge-gate-audit.test.ts +2 -169
  145. package/tests/core/migration.test.ts +7 -7
  146. package/tests/core/model-deployment-registry.test.ts +7 -1
  147. package/tests/core/model-training-registry.test.ts +19 -0
  148. package/tests/core/observability.test.ts +0 -1
  149. package/tests/core/pain-diagnostic-gate.test.ts +498 -0
  150. package/tests/core/pain.test.ts +0 -1
  151. package/tests/core/path-resolver.test.ts +1 -1
  152. package/tests/core/paths-refactor.test.ts +0 -22
  153. package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
  154. package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
  155. package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
  156. package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
  157. package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
  158. package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
  159. package/tests/core/reflection-context.test.ts +0 -14
  160. package/tests/core/replay-engine.test.ts +127 -215
  161. package/tests/core/rule-host-helpers.test.ts +2 -2
  162. package/tests/core/rule-implementation-runtime.test.ts +0 -27
  163. package/tests/core/workflow-funnel-loader.test.ts +162 -0
  164. package/tests/core/workspace-context.test.ts +2 -2
  165. package/tests/core/workspace-dir-validation.test.ts +8 -1
  166. package/tests/core-anti-growth.test.ts +191 -0
  167. package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
  168. package/tests/hooks/confirm-first-removal.test.ts +188 -0
  169. package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
  170. package/tests/hooks/gate-auto-correct.test.ts +665 -0
  171. package/tests/hooks/gate-no-path-write-tool.test.ts +172 -0
  172. package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
  173. package/tests/hooks/pain.test.ts +269 -12
  174. package/tests/hooks/prompt-characterization.test.ts +500 -0
  175. package/tests/hooks/prompt-size-guard.test.ts +32 -17
  176. package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
  177. package/tests/index.test.ts +94 -1
  178. package/tests/integration/auto-entry-gate.test.ts +248 -0
  179. package/tests/integration/internalization-trigger-guard.test.ts +69 -0
  180. package/tests/integration/m8-legacy-paths.test.ts +63 -0
  181. package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
  182. package/tests/plugin-config-resolution-cutover.test.ts +359 -0
  183. package/tests/runtime-v2-discovery-guard.test.ts +154 -0
  184. package/tests/service/central-database.test.ts +457 -0
  185. package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
  186. package/tests/service/evolution-worker.timeout.test.ts +11 -129
  187. package/tests/service/internalization-trigger-adapter.test.ts +251 -0
  188. package/tests/service/monitoring-query-service.test.ts +1 -47
  189. package/tests/service/queue-io.test.ts +1 -62
  190. package/tests/service/runtime-summary-service.test.ts +3 -1
  191. package/tests/service/workflow-watchdog.test.ts +0 -91
  192. package/tests/utils/file-lock.test.ts +5 -3
  193. package/tests/utils/session-key.test.ts +52 -0
  194. package/tests/utils/subagent-probe.test.ts +48 -1
  195. package/vitest.config.ts +4 -11
  196. package/.planning/codebase/ARCHITECTURE.md +0 -157
  197. package/.planning/codebase/CONCERNS.md +0 -145
  198. package/.planning/codebase/CONVENTIONS.md +0 -148
  199. package/.planning/codebase/INTEGRATIONS.md +0 -81
  200. package/.planning/codebase/STACK.md +0 -87
  201. package/.planning/codebase/STRUCTURE.md +0 -193
  202. package/.planning/codebase/TESTING.md +0 -243
  203. package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
  204. package/docs/COMMAND_REFERENCE.md +0 -76
  205. package/docs/COMMAND_REFERENCE_EN.md +0 -79
  206. package/scripts/build-web.mjs +0 -46
  207. package/scripts/diagnose-nocturnal.mjs +0 -537
  208. package/scripts/seed-nocturnal-scenarios.mjs +0 -384
  209. package/src/commands/nocturnal-review.ts +0 -322
  210. package/src/commands/nocturnal-rollout.ts +0 -790
  211. package/src/commands/nocturnal-train.ts +0 -986
  212. package/src/commands/pd-reflect.ts +0 -88
  213. package/src/core/adaptive-thresholds.ts +0 -478
  214. package/src/core/diagnostician-task-store.ts +0 -192
  215. package/src/core/nocturnal-arbiter.ts +0 -715
  216. package/src/core/nocturnal-artifact-lineage.ts +0 -116
  217. package/src/core/nocturnal-artificer.ts +0 -257
  218. package/src/core/nocturnal-candidate-scoring.ts +0 -530
  219. package/src/core/nocturnal-compliance.ts +0 -1146
  220. package/src/core/nocturnal-dataset.ts +0 -763
  221. package/src/core/nocturnal-executability.ts +0 -428
  222. package/src/core/nocturnal-export.ts +0 -499
  223. package/src/core/nocturnal-paths.ts +0 -240
  224. package/src/core/nocturnal-reasoning-deriver.ts +0 -343
  225. package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
  226. package/src/core/nocturnal-snapshot-contract.ts +0 -99
  227. package/src/core/nocturnal-trajectory-extractor.ts +0 -512
  228. package/src/core/nocturnal-trinity-types.ts +0 -218
  229. package/src/core/nocturnal-trinity.ts +0 -2680
  230. package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
  231. package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
  232. package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
  233. package/src/http/principles-console-route.ts +0 -709
  234. package/src/service/central-health-service.ts +0 -49
  235. package/src/service/central-overview-service.ts +0 -138
  236. package/src/service/control-ui-query-service.ts +0 -900
  237. package/src/service/cooldown-strategy.ts +0 -97
  238. package/src/service/evolution-pain-context.ts +0 -79
  239. package/src/service/evolution-query-service.ts +0 -407
  240. package/src/service/health-query-service.ts +0 -1038
  241. package/src/service/nocturnal-config.ts +0 -214
  242. package/src/service/nocturnal-runtime.ts +0 -734
  243. package/src/service/nocturnal-service.ts +0 -1605
  244. package/src/service/nocturnal-target-selector.ts +0 -545
  245. package/src/service/sleep-cycle.ts +0 -157
  246. package/src/service/startup-reconciler.ts +0 -112
  247. package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
  248. package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
  249. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
  250. package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
  251. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
  252. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
  253. package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
  254. package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
  255. package/src/tools/write-pain-flag.ts +0 -215
  256. package/templates/langs/en/skills/plan-script/SKILL.md +0 -32
  257. package/templates/langs/zh/skills/plan-script/SKILL.md +0 -32
  258. package/tests/commands/nocturnal-review.test.ts +0 -448
  259. package/tests/commands/nocturnal-train.test.ts +0 -97
  260. package/tests/commands/pd-reflect.test.ts +0 -49
  261. package/tests/core/adaptive-thresholds.test.ts +0 -261
  262. package/tests/core/nocturnal-arbiter.test.ts +0 -559
  263. package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
  264. package/tests/core/nocturnal-artificer.test.ts +0 -241
  265. package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
  266. package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
  267. package/tests/core/nocturnal-compliance.test.ts +0 -646
  268. package/tests/core/nocturnal-dataset.test.ts +0 -892
  269. package/tests/core/nocturnal-e2e.test.ts +0 -234
  270. package/tests/core/nocturnal-executability.test.ts +0 -357
  271. package/tests/core/nocturnal-export.test.ts +0 -517
  272. package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
  273. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
  274. package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
  275. package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
  276. package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
  277. package/tests/core/nocturnal-trinity.test.ts +0 -2053
  278. package/tests/core/pain-auto-repair.test.ts +0 -96
  279. package/tests/core/pain-integration.test.ts +0 -510
  280. package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
  281. package/tests/http/principles-console-route.test.ts +0 -162
  282. package/tests/integration/chaos-resilience.test.ts +0 -348
  283. package/tests/integration/empathy-workflow-integration.test.ts +0 -626
  284. package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
  285. package/tests/service/control-ui-query-service.test.ts +0 -121
  286. package/tests/service/cooldown-strategy.test.ts +0 -164
  287. package/tests/service/data-endpoints-regression.test.ts +0 -834
  288. package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
  289. package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
  290. package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
  291. package/tests/service/nocturnal-runtime.test.ts +0 -473
  292. package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
  293. package/tests/service/nocturnal-target-selector.test.ts +0 -615
  294. package/tests/service/startup-reconciler.test.ts +0 -148
  295. package/tests/tools/write-pain-flag.test.ts +0 -358
  296. package/ui/src/App.tsx +0 -45
  297. package/ui/src/api.ts +0 -220
  298. package/ui/src/charts.tsx +0 -955
  299. package/ui/src/components/ErrorState.tsx +0 -6
  300. package/ui/src/components/Loading.tsx +0 -13
  301. package/ui/src/components/ProtectedRoute.tsx +0 -12
  302. package/ui/src/components/Shell.tsx +0 -91
  303. package/ui/src/components/WorkspaceConfig.tsx +0 -178
  304. package/ui/src/components/index.ts +0 -5
  305. package/ui/src/context/auth.tsx +0 -80
  306. package/ui/src/context/theme.tsx +0 -66
  307. package/ui/src/hooks/useAutoRefresh.ts +0 -39
  308. package/ui/src/i18n/ui.ts +0 -473
  309. package/ui/src/main.tsx +0 -16
  310. package/ui/src/pages/EvolutionPage.tsx +0 -333
  311. package/ui/src/pages/FeedbackPage.tsx +0 -138
  312. package/ui/src/pages/GateMonitorPage.tsx +0 -136
  313. package/ui/src/pages/LoginPage.tsx +0 -89
  314. package/ui/src/pages/OverviewPage.tsx +0 -599
  315. package/ui/src/pages/SamplesPage.tsx +0 -174
  316. package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
  317. package/ui/src/styles.css +0 -2020
  318. package/ui/src/types.ts +0 -384
  319. package/ui/src/utils/format.ts +0 -15
@@ -2,38 +2,32 @@
2
2
  * Local Worker Routing Policy — Task Classification and Routing Decisions
3
3
  * ======================================================================
4
4
  *
5
- * PURPOSE: Provide an explainable, testable policy that decides whether a given
6
- * task can be delegated to a local-worker profile (local-reader or local-editor)
7
- * or must stay on the main agent.
5
+ * Phase: PRI-74 Routing Guidance Migration (follow-up to PRI-75 Prompt Injection SDK Migration)
6
+ *
7
+ * This file is a THIN ADAPTER.
8
+ * Pure classification logic lives in @principles/core/prompt-builder/routing-guidance.ts.
9
+ * This file handles I/O (deployment registry, promotion state) and combines
10
+ * pure classification with deployment checks.
8
11
  *
9
12
  * ARCHITECTURE:
10
- * - This module is POLICY ONLY it makes routing decisions but does NOT execute them
11
- * - The main agent (or a delegation hook in a future phase) is responsible for
12
- * actually routing the task based on the RoutingDecision returned here
13
- * - All decisions are deterministic and based on structured input fields
14
- * - No model inference, no learning, no dynamic adaptation
13
+ * - Pure: classifyTaskKind, buildReason, buildBlockers, keyword constants core
14
+ * - I/O: getDeployment, isRoutingEnabledForProfile, isCheckpointDeployable, getPromotionState plugin
15
15
  *
16
16
  * TASK CLASSIFICATION TAXONOMY:
17
- * reader_eligible — clearly suitable for local-reader
18
- * editor_eligible — clearly suitable for local-editor
19
- * high_entropy_disallowed high-complexity tasks that must stay on main agent
20
- * ambiguous_scope — tasks that are unclear and need main-agent judgment
21
- * deployment_unavailable no enabled deployment exists for the target profile
22
- *
23
- * NOTE: risk_disallowed has been removed. Risk signals are now advisory only —
24
- * the main agent decides whether to delegate based on full context.
17
+ * Pure-classification output from classifyTaskKind() in @principles/core/prompt-builder/routing-guidance.ts:
18
+ * reader_eligible — clearly suitable for local-reader
19
+ * editor_eligible clearly suitable for local-editor
20
+ * high_entropy_disallowed high-complexity tasks that must stay on main agent
21
+ * ambiguous_scope tasks that are unclear and need main-agent judgment
22
+ * Plugin layer adds I/O-bound categories via deployment checks in classifyTask():
23
+ * profile_mismatch — target profile incompatible with task classification
24
+ * deployment_unavailable no enabled deployment exists for the target profile
25
25
  *
26
26
  * FAIL-CLOSED PRINCIPLE:
27
27
  * - When in doubt → stay_main
28
28
  * - Unclear intent → stay_main
29
29
  * - High complexity → stay_main
30
30
  * - No enabled deployment → stay_main
31
- *
32
- * DESIGN CONSTRAINTS:
33
- * - No actual task execution
34
- * - No automatic learning or route optimization
35
- * - No Trinity or adaptive threshold logic
36
- * - Routing decisions are fully explainable (return `reason` + `blockers[]`)
37
31
  */
38
32
 
39
33
  import type { WorkerProfile } from './model-deployment-registry.js';
@@ -44,58 +38,16 @@ import {
44
38
  import { isCheckpointDeployable } from './model-training-registry.js';
45
39
  import { getPromotionState } from './promotion-gate.js';
46
40
 
47
- // ---------------------------------------------------------------------------
48
- // Routing Input Contract
49
- // ---------------------------------------------------------------------------
50
-
51
- /**
52
- * The input contract for a routing decision.
53
- * All fields are optional — the classifier handles missing data gracefully
54
- * by treating it as ambiguous (stay_main).
55
- */
56
- export interface RoutingInput {
57
- /**
58
- * A short label or name for the task intent.
59
- * E.g., "read_file", "edit_config", "debug_memory_leak", "design_system"
60
- */
61
- taskIntent?: string;
62
-
63
- /**
64
- * Natural-language description of the task.
65
- * The classifier examines this for keywords indicating complexity/risk.
66
- */
67
- taskDescription?: string;
68
-
69
- /**
70
- * Specific tools requested or implied by the task.
71
- * These are examined for risk signals (e.g., bash, rm, git push).
72
- */
73
- requestedTools?: string[];
74
-
75
- /**
76
- * Specific files involved or targeted.
77
- * Examined for risk-path indicators (e.g., .git/, node_modules, production configs).
78
- */
79
- requestedFiles?: string[];
80
-
81
- /**
82
- * Shape of expected output.
83
- * E.g., "json", "markdown", "one_line", "full_report"
84
- */
85
- expectedOutputShape?: string;
86
-
87
- /**
88
- * Complexity hints for the task.
89
- * E.g., ["multi_step", "cross_file", "ambiguous", "requires_planning"]
90
- */
91
- complexityHints?: string[];
41
+ // Core pure functions — migrated to @principles/core/prompt-builder
42
+ import {
43
+ type RoutingInput as CoreRoutingInput,
44
+ classifyTaskKind as coreClassifyTaskKind,
45
+ buildReason as coreBuildReason,
46
+ buildBlockers as coreBuildBlockers,
47
+ } from '@principles/core/prompt-builder';
92
48
 
93
- /**
94
- * Target worker profile for routing consideration.
95
- * If omitted, both profiles are evaluated and the best match is returned.
96
- */
97
- targetProfile?: WorkerProfile;
98
- }
49
+ // Re-export RoutingInput from core for backward compatibility with existing imports
50
+ export type { RoutingInput } from '@principles/core/prompt-builder';
99
51
 
100
52
  // ---------------------------------------------------------------------------
101
53
  // Routing Decision Contract
@@ -180,238 +132,6 @@ export interface RoutingDecision {
180
132
 
181
133
  }
182
134
 
183
- // ---------------------------------------------------------------------------
184
- // Keyword Classifiers
185
- // ---------------------------------------------------------------------------
186
-
187
- /**
188
- * Keywords that indicate a task is suitable for `local-reader`.
189
- * Matched against taskIntent + taskDescription.
190
- */
191
- const READER_KEYWORDS = [
192
- 'read', 'view', 'show', 'get', 'find', 'search', 'grep', 'look',
193
- 'inspect', 'examine', 'list', 'cat', 'head', 'tail', 'diff',
194
- 'summary', 'summarize', 'extract', 'parse', 'review',
195
- 'check', 'verify', 'status', 'describe', 'explain_what',
196
- 'browse', 'fetch', 'show_content', 'file_content', 'code_read',
197
- ];
198
-
199
- /**
200
- * Keywords that indicate a task is suitable for `local-editor`.
201
- * Matched against taskIntent + taskDescription.
202
- */
203
- const EDITOR_KEYWORDS = [
204
- 'edit', 'update', 'modify', 'change', 'fix', 'patch', 'replace',
205
- 'add', 'remove', 'delete', 'insert', 'rewrite', 'refactor',
206
- 'apply', 'execute', 'run', 'transform', 'convert', 'migrate',
207
- 'write', 'create_file', 'append', 'touch', 'rename',
208
- ];
209
-
210
- /**
211
- * Keywords that indicate HIGH ENTROPY — tasks that must stay on main agent.
212
- * These indicate open-ended, multi-step, or ambiguous tasks.
213
- */
214
- const HIGH_ENTROPY_KEYWORDS = [
215
- 'design', 'architect', 'plan', 'strategy', 'roadmap', 'propose',
216
- 'research', 'investigate', 'explore', 'evaluate', 'compare',
217
- 'decide', 'choose', 'recommend', 'suggest', 'analyze_tradeoffs',
218
- 'unclear', 'vague', 'ambiguous', 'open_ended', 'multiple_options',
219
- 'architecture', 'system_design', 'high_level', 'blueprint',
220
- 'thinking', 'reasoning', '思考', '分析', '设计',
221
- ];
222
-
223
- // ---------------------------------------------------------------------------
224
- // Classification Helpers
225
- // ---------------------------------------------------------------------------
226
-
227
- /**
228
- * Simple case-insensitive keyword match.
229
- */
230
- function containsKeyword(text: string | undefined, keywords: string[]): boolean {
231
- if (!text) return false;
232
- const lower = text.toLowerCase();
233
- return keywords.some((kw) => lower.includes(kw));
234
- }
235
-
236
- /**
237
- * Compute a combined text from all input fields for keyword scanning.
238
- */
239
- function computeCombinedText(input: RoutingInput): string {
240
- const parts: string[] = [];
241
- if (input.taskIntent) parts.push(input.taskIntent);
242
- if (input.taskDescription) parts.push(input.taskDescription);
243
- if (input.expectedOutputShape) parts.push(input.expectedOutputShape);
244
- if (input.complexityHints) parts.push(input.complexityHints.join(' '));
245
- return parts.join(' ').toLowerCase();
246
- }
247
-
248
- // ---------------------------------------------------------------------------
249
- // Core Classification Logic
250
- // ---------------------------------------------------------------------------
251
-
252
- /**
253
- * Classify the task based on its input fields.
254
- * Returns a raw classification category (before deployment check).
255
- */
256
- function classifyTaskKind(input: RoutingInput): RoutingDecision['classification'] {
257
- const text = computeCombinedText(input);
258
- const { taskIntent, taskDescription, requestedFiles, complexityHints } = input;
259
-
260
- // --- Step 1: High-entropy keyword detection ---
261
- if (complexityHints?.some((h) =>
262
- ['multi_step', 'cross_file', 'ambiguous', 'requires_planning', 'open_ended', 'unclear'].includes(h)
263
- )) {
264
- return 'high_entropy_disallowed';
265
- }
266
-
267
- if (containsKeyword(text, HIGH_ENTROPY_KEYWORDS)) {
268
- return 'high_entropy_disallowed';
269
- }
270
-
271
- if (containsKeyword(taskIntent, ['design', 'architect', 'plan', 'propose']) ||
272
- containsKeyword(taskDescription, ['design', 'architect', 'plan', 'propose'])) {
273
- return 'high_entropy_disallowed';
274
- }
275
-
276
- // --- Step 2: Reader eligibility ---
277
- const intentIsReader = containsKeyword(taskIntent, READER_KEYWORDS);
278
- const descIsReader = containsKeyword(taskDescription, READER_KEYWORDS);
279
-
280
- if (intentIsReader && (descIsReader || !taskDescription)) {
281
- return 'reader_eligible';
282
- }
283
-
284
- // --- Step 3: Editor eligibility ---
285
- const uniqueFiles = requestedFiles
286
- ? [...new Set(requestedFiles.filter((f) => f.trim().length > 0))]
287
- : [];
288
- const intentIsEditor = containsKeyword(taskIntent, EDITOR_KEYWORDS);
289
- const descIsEditor = containsKeyword(taskDescription, EDITOR_KEYWORDS);
290
-
291
- if (intentIsEditor && (descIsEditor || !taskDescription)) {
292
- if (uniqueFiles.length >= 4) {
293
- return 'high_entropy_disallowed';
294
- }
295
- return 'editor_eligible';
296
- }
297
-
298
- // --- Step 4: Ambiguous scope ---
299
- if (taskDescription && taskDescription.trim().length > 0) {
300
- const trimmed = taskDescription.trim();
301
- if (trimmed.length < 20 || ['todo', 'fix', 'improve', 'change', 'update', 'something'].includes(trimmed.toLowerCase())) {
302
- return 'ambiguous_scope';
303
- }
304
- if (/\b(why|how|should|could|would|what if|should we|whether to)\b/i.test(trimmed)) {
305
- return 'ambiguous_scope';
306
- }
307
- }
308
-
309
- if (!taskIntent && !taskDescription) {
310
- return 'ambiguous_scope';
311
- }
312
-
313
- return 'ambiguous_scope';
314
- }
315
-
316
- /**
317
- * Build the reason string for a given classification.
318
- */
319
- function buildReason(
320
- classification: RoutingDecision['classification'],
321
- input: RoutingInput
322
- ): string {
323
- const { taskIntent, taskDescription } = input;
324
-
325
- switch (classification) {
326
- case 'reader_eligible':
327
- return `Task "${taskIntent || taskDescription || '(unnamed)'}" is classified as reader_eligible. ` +
328
- `Keywords indicate focused reading, inspection, or information retrieval. ` +
329
- `No high-entropy or risk signals detected.`;
330
-
331
- case 'editor_eligible':
332
- return `Task "${taskIntent || taskDescription || '(unnamed)'}" is classified as editor_eligible. ` +
333
- `Keywords indicate bounded editing, modification, or repair. ` +
334
- `No high-entropy or risk signals detected.`;
335
-
336
- case 'high_entropy_disallowed': {
337
- const uniqueFiles = input.requestedFiles
338
- ? [...new Set(input.requestedFiles.filter((f) => f.trim().length > 0))]
339
- : [];
340
- const isLargeScaleEdit = uniqueFiles.length >= 4;
341
- if (isLargeScaleEdit) {
342
- return `Task "${taskIntent || taskDescription || '(unnamed)'}" is blocked as high_entropy_disallowed. ` +
343
- `Editing ${uniqueFiles.length} files simultaneously exceeds the bounded-scope limit for local-editor. ` +
344
- `Large-scale multi-file edits require the main agent's coordination and risk judgment.`;
345
- }
346
- return `Task "${taskIntent || taskDescription || '(unnamed)'}" is blocked as high_entropy_disallowed. ` +
347
- `Keywords indicate open-ended planning, architecture design, or ambiguous multi-step work. ` +
348
- `These tasks require the main agent's full reasoning capability.`;
349
- }
350
-
351
- case 'ambiguous_scope':
352
- return `Task "${taskIntent || taskDescription || '(unnamed)'}" is blocked as ambiguous_scope. ` +
353
- `The task description is too vague, too short, or contains open-ended question words. ` +
354
- `Main agent must clarify scope before delegation.`;
355
-
356
- case 'profile_mismatch':
357
- return `Task profile does not match the requested target profile. ` +
358
- `The task's natural classification is incompatible with the specified worker profile. ` +
359
- `Main agent must re-route or choose a compatible profile.`;
360
-
361
- case 'deployment_unavailable':
362
- return `No enabled deployment available for routing. ` +
363
- `Either no checkpoint is bound to the profile, or routing has been disabled. ` +
364
- `Main agent must handle this task.`;
365
- }
366
- }
367
-
368
- /**
369
- * Build the blockers list for a given classification.
370
- */
371
- function buildBlockers(
372
- classification: RoutingDecision['classification'],
373
- input: RoutingInput
374
- ): string[] {
375
- switch (classification) {
376
- case 'reader_eligible':
377
- return [];
378
- case 'editor_eligible':
379
- return [];
380
- case 'high_entropy_disallowed': {
381
- const uniqueFiles = input.requestedFiles
382
- ? [...new Set(input.requestedFiles.filter((f) => f.trim().length > 0))]
383
- : [];
384
- const isLargeScaleEdit = uniqueFiles.length >= 4;
385
- return [
386
- isLargeScaleEdit
387
- ? `large-scale multi-file edit detected (${uniqueFiles.length} files): scope too broad for local-editor`
388
- : 'task contains high-entropy keywords (design/plan/architect/investigate)',
389
- 'complexity hint indicates multi-step or open-ended work',
390
- 'main agent required for full reasoning and judgment',
391
- ];
392
- }
393
- case 'ambiguous_scope':
394
- return [
395
- 'task description too vague or generic',
396
- 'task intent not provided or unclear',
397
- 'open-ended question words detected',
398
- 'main agent must clarify scope before delegation',
399
- ];
400
- case 'profile_mismatch':
401
- return [
402
- 'task natural profile incompatible with requested target profile',
403
- 'main agent must re-route or select a compatible profile',
404
- ];
405
-
406
- case 'deployment_unavailable':
407
- return [
408
- 'no enabled deployment found for target profile',
409
- 'routing may be disabled in deployment registry',
410
- 'main agent must handle task directly',
411
- ];
412
- }
413
- }
414
-
415
135
  // ---------------------------------------------------------------------------
416
136
  // Public API
417
137
  // ---------------------------------------------------------------------------
@@ -421,8 +141,8 @@ function buildBlockers(
421
141
  *
422
142
  * This is the main entry point for routing policy evaluation.
423
143
  * It:
424
- * 1. Classifies the task kind based on keywords and heuristics
425
- * 2. Checks deployment availability for the target profile
144
+ * 1. Classifies the task kind based on keywords and heuristics (core pure function)
145
+ * 2. Checks deployment availability for the target profile (plugin I/O)
426
146
  * 3. Returns a fully explainable RoutingDecision
427
147
  *
428
148
  * @param input - The routing input describing the task
@@ -430,11 +150,11 @@ function buildBlockers(
430
150
  * @returns RoutingDecision with classification, reason, blockers, and routing verdict
431
151
  */
432
152
  export function classifyTask(
433
- input: RoutingInput,
153
+ input: CoreRoutingInput,
434
154
  stateDir: string
435
155
  ): RoutingDecision {
436
- // --- Determine the raw task classification ---
437
- const classification = classifyTaskKind(input);
156
+ // --- Determine the raw task classification (delegated to core pure function) ---
157
+ const classification = coreClassifyTaskKind(input);
438
158
 
439
159
  // --- Determine the target profile ---
440
160
  // If input specifies a target, use it. Otherwise, pick based on classification.
@@ -485,9 +205,9 @@ export function classifyTask(
485
205
  };
486
206
  }
487
207
 
488
- // --- Build the decision ---
489
- const blockers = buildBlockers(classification, input);
490
- const reason = buildReason(classification, input);
208
+ // --- Build the decision (delegated to core pure functions) ---
209
+ const blockers = coreBuildBlockers(classification, input);
210
+ const reason = coreBuildReason(classification, input);
491
211
 
492
212
  // FAIL-CLOSED: route_local only if:
493
213
  // 1. Classification is eligible (reader_eligible or editor_eligible)
@@ -586,7 +306,7 @@ export function classifyTask(
586
306
  * Equivalent to calling classifyTask with targetProfile set.
587
307
  */
588
308
  export function canRouteToProfile(
589
- input: RoutingInput,
309
+ input: CoreRoutingInput,
590
310
  stateDir: string,
591
311
  profile: WorkerProfile
592
312
  ): boolean {
@@ -1,10 +1,6 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { getImplementationAssetRoot } from './code-implementation-storage.js';
4
- import { listDatasetRecords } from './nocturnal-dataset.js';
5
- import { listArtifactLineageRecords } from './nocturnal-artifact-lineage.js';
6
- import { listExports, verifyExportIntegrity } from './nocturnal-export.js';
7
- import { OpenClawTrinityRuntimeAdapter } from './nocturnal-trinity.js';
8
4
  import { resolvePdPath } from './paths.js';
9
5
  import type { ReplayReport } from './replay-engine.js';
10
6
 
@@ -30,11 +26,6 @@ export interface MergeGateAuditReport {
30
26
  };
31
27
  }
32
28
 
33
- function isWithinDir(parentDir: string, candidatePath: string): boolean {
34
- const relative = path.relative(path.resolve(parentDir), path.resolve(candidatePath));
35
- return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
36
- }
37
-
38
29
  function computeOverallStatus(checks: MergeGateAuditCheck[]): MergeGateAuditStatus {
39
30
  if (checks.some((check) => check.status === 'block')) {
40
31
  return 'block';
@@ -109,169 +100,6 @@ function auditQueuePathContract(workspaceDir: string): MergeGateAuditCheck {
109
100
  };
110
101
  }
111
102
 
112
- function auditRuntimeAdapterContract(): MergeGateAuditCheck {
113
- // Check the prototype surface only — do NOT instantiate the adapter.
114
- // Instantiation triggers cleanupStaleTempDirs() which scans os.tmpdir()
115
- // and could have side effects (removing stale temp dirs of other processes).
116
- const hasSurface =
117
- typeof OpenClawTrinityRuntimeAdapter.prototype.isRuntimeAvailable === 'function' &&
118
- typeof OpenClawTrinityRuntimeAdapter.prototype.getLastFailureReason === 'function';
119
-
120
- if (!hasSurface) {
121
- return {
122
- id: 'runtime_adapter_contract',
123
- status: 'block',
124
- summary: 'OpenClaw runtime adapter does not expose the expected contract-check surface.',
125
- };
126
- }
127
-
128
- return {
129
- id: 'runtime_adapter_contract',
130
- status: 'pass',
131
- summary: 'OpenClaw runtime adapter exposes the expected contract-check surface (isRuntimeAvailable, getLastFailureReason).',
132
- };
133
- }
134
-
135
- function auditDatasetArtifactIntegrity(workspaceDir: string): MergeGateAuditCheck {
136
- const records = listDatasetRecords(workspaceDir);
137
- if (records.length === 0) {
138
- return {
139
- id: 'dataset_artifact_integrity',
140
- status: 'defer',
141
- summary: 'No dataset records found. Dataset artifact integrity cannot be verified yet.',
142
- };
143
- }
144
-
145
- const missingArtifacts: string[] = [];
146
- const outOfWorkspaceArtifacts: string[] = [];
147
-
148
- for (const record of records) {
149
- if (!fs.existsSync(record.artifactPath)) {
150
- missingArtifacts.push(record.sampleFingerprint);
151
- continue;
152
- }
153
- if (!isWithinDir(workspaceDir, record.artifactPath)) {
154
- outOfWorkspaceArtifacts.push(record.sampleFingerprint);
155
- }
156
- }
157
-
158
- if (missingArtifacts.length > 0 || outOfWorkspaceArtifacts.length > 0) {
159
- return {
160
- id: 'dataset_artifact_integrity',
161
- status: 'block',
162
- summary: 'Dataset registry points to missing artifacts or paths outside the workspace boundary.',
163
- details: {
164
- recordCount: records.length,
165
- missingArtifacts,
166
- outOfWorkspaceArtifacts,
167
- },
168
- };
169
- }
170
-
171
- return {
172
- id: 'dataset_artifact_integrity',
173
- status: 'pass',
174
- summary: 'All dataset artifacts exist and remain inside the workspace boundary.',
175
- details: {
176
- recordCount: records.length,
177
- },
178
- };
179
- }
180
-
181
- function auditArtifactLineageIntegrity(workspaceDir: string): MergeGateAuditCheck {
182
- const records = listArtifactLineageRecords(workspaceDir);
183
- if (records.length === 0) {
184
- return {
185
- id: 'artifact_lineage_integrity',
186
- status: 'defer',
187
- summary: 'No artifact lineage records found. Lineage integrity cannot be verified yet.',
188
- };
189
- }
190
-
191
- const missingStoragePaths: string[] = [];
192
- const outOfWorkspaceStoragePaths: string[] = [];
193
-
194
- for (const record of records) {
195
- if (!fs.existsSync(record.storagePath)) {
196
- missingStoragePaths.push(record.artifactId);
197
- continue;
198
- }
199
- if (!isWithinDir(workspaceDir, record.storagePath)) {
200
- outOfWorkspaceStoragePaths.push(record.artifactId);
201
- }
202
- }
203
-
204
- if (missingStoragePaths.length > 0 || outOfWorkspaceStoragePaths.length > 0) {
205
- return {
206
- id: 'artifact_lineage_integrity',
207
- status: 'block',
208
- summary: 'Artifact lineage points to missing files or paths outside the workspace boundary.',
209
- details: {
210
- recordCount: records.length,
211
- missingStoragePaths,
212
- outOfWorkspaceStoragePaths,
213
- },
214
- };
215
- }
216
-
217
- return {
218
- id: 'artifact_lineage_integrity',
219
- status: 'pass',
220
- summary: 'All lineage storage paths exist and remain inside the workspace boundary.',
221
- details: {
222
- recordCount: records.length,
223
- },
224
- };
225
- }
226
-
227
- function auditOrpoExportIntegrity(workspaceDir: string): MergeGateAuditCheck {
228
- const exports = listExports(workspaceDir);
229
- if (exports.length === 0) {
230
- return {
231
- id: 'orpo_export_integrity',
232
- status: 'defer',
233
- summary: 'No ORPO exports found. Export integrity cannot be verified yet.',
234
- };
235
- }
236
-
237
- const invalidExportIds: string[] = [];
238
- const missingExportFiles: string[] = [];
239
-
240
- for (const manifest of exports) {
241
- if (!fs.existsSync(manifest.exportPath)) {
242
- missingExportFiles.push(manifest.exportId);
243
- continue;
244
- }
245
-
246
- const integrity = verifyExportIntegrity(workspaceDir, manifest.exportId);
247
- if (!integrity || !integrity.valid) {
248
- invalidExportIds.push(manifest.exportId);
249
- }
250
- }
251
-
252
- if (invalidExportIds.length > 0 || missingExportFiles.length > 0) {
253
- return {
254
- id: 'orpo_export_integrity',
255
- status: 'block',
256
- summary: 'ORPO export manifests or payloads failed integrity verification.',
257
- details: {
258
- exportCount: exports.length,
259
- invalidExportIds,
260
- missingExportFiles,
261
- },
262
- };
263
- }
264
-
265
- return {
266
- id: 'orpo_export_integrity',
267
- status: 'pass',
268
- summary: 'All ORPO exports pass manifest fingerprint verification.',
269
- details: {
270
- exportCount: exports.length,
271
- },
272
- };
273
- }
274
-
275
103
  function isReplayReportShape(value: unknown): value is ReplayReport {
276
104
  if (!value || typeof value !== 'object') {
277
105
  return false;
@@ -287,9 +115,6 @@ function isReplayReportShape(value: unknown): value is ReplayReport {
287
115
  );
288
116
  }
289
117
 
290
- /**
291
- * Collect all replay report file paths under the implementations directory.
292
- */
293
118
  function collectReplayReportPaths(stateDir: string): string[] {
294
119
  const implementationsRoot = path.join(stateDir, 'principles', 'implementations');
295
120
  if (!fs.existsSync(implementationsRoot)) return [];
@@ -313,9 +138,6 @@ function collectReplayReportPaths(stateDir: string): string[] {
313
138
  return paths;
314
139
  }
315
140
 
316
- /**
317
- * Result of validating a single replay report file.
318
- */
319
141
  type ReplayValidationCategory =
320
142
  | 'io_error'
321
143
  | 'malformed'
@@ -324,9 +146,6 @@ type ReplayValidationCategory =
324
146
  | 'empty_needs_review'
325
147
  | 'valid';
326
148
 
327
- /**
328
- * Check if the parsed replay report has a valid evidenceSummary shape.
329
- */
330
149
  function hasValidEvidenceSummary(parsed: unknown): boolean {
331
150
  if (!parsed || typeof parsed !== 'object') return false;
332
151
  const report = parsed as Partial<ReplayReport>;
@@ -338,11 +157,7 @@ function hasValidEvidenceSummary(parsed: unknown): boolean {
338
157
  return typeof (summary as Partial<ReplayReport['evidenceSummary']>).totalSamples === 'number';
339
158
  }
340
159
 
341
- /**
342
- * Validate a single replay report file and return its category.
343
- */
344
160
  function validateSingleReplayReport(reportPath: string): ReplayValidationCategory {
345
-
346
161
  let rawContent: string;
347
162
  try {
348
163
  rawContent = fs.readFileSync(reportPath, 'utf-8');
@@ -350,7 +165,6 @@ function validateSingleReplayReport(reportPath: string): ReplayValidationCategor
350
165
  return 'io_error';
351
166
  }
352
167
 
353
-
354
168
  let parsed: unknown;
355
169
  try {
356
170
  parsed = JSON.parse(rawContent);
@@ -366,7 +180,6 @@ function validateSingleReplayReport(reportPath: string): ReplayValidationCategor
366
180
  return 'missing_evidence_summary';
367
181
  }
368
182
 
369
-
370
183
  const evidenceSummary = parsed.evidenceSummary;
371
184
  if (parsed.overallDecision === 'pass' && evidenceSummary.totalSamples === 0) {
372
185
  return 'unsupported_pass';
@@ -379,9 +192,6 @@ function validateSingleReplayReport(reportPath: string): ReplayValidationCategor
379
192
  return 'valid';
380
193
  }
381
194
 
382
- /**
383
- * Categorize all replay report files by validation outcome.
384
- */
385
195
  interface ReplayValidationResults {
386
196
  ioErrorReports: string[];
387
197
  malformedReports: string[];
@@ -417,7 +227,6 @@ function categorizeReplayReports(reportPaths: string[]): ReplayValidationResults
417
227
  case 'empty_needs_review':
418
228
  results.emptyEvidenceNeedsReview.push(reportPath);
419
229
  break;
420
- // 'valid' — no action needed
421
230
  }
422
231
  }
423
232
 
@@ -473,10 +282,6 @@ export function runMergeGateAudit(workspaceDir: string, stateDir: string): Merge
473
282
  const checks: MergeGateAuditCheck[] = [
474
283
  auditPainFlagPathContract(workspaceDir),
475
284
  auditQueuePathContract(workspaceDir),
476
- auditRuntimeAdapterContract(),
477
- auditDatasetArtifactIntegrity(workspaceDir),
478
- auditArtifactLineageIntegrity(workspaceDir),
479
- auditOrpoExportIntegrity(workspaceDir),
480
285
  auditReplayEvidenceIntegrity(stateDir),
481
286
  ];
482
287
 
@@ -19,7 +19,6 @@ export function migrateDirectoryStructure(api: OpenClawPluginApi, workspaceDir:
19
19
  { legacy: path.join(legacyDocsDir, 'PRINCIPLES.md'), newKey: 'PRINCIPLES' },
20
20
  { legacy: path.join(legacyDocsDir, 'THINKING_OS.md'), newKey: 'THINKING_OS' },
21
21
  { legacy: path.join(legacyDocsDir, 'DECISION_POLICY.json'), newKey: 'DECISION_POLICY' },
22
- { legacy: path.join(legacyDocsDir, 'PLAN.md'), newKey: 'PLAN' },
23
22
  { legacy: path.join(legacyDocsDir, 'evolution_queue.json'), newKey: 'EVOLUTION_QUEUE' },
24
23
  { legacy: path.join(legacyDocsDir, '.pain_flag'), newKey: 'PAIN_FLAG' },
25
24
  { legacy: path.join(legacyDocsDir, 'SYSTEM_CAPABILITIES.json'), newKey: 'SYSTEM_CAPABILITIES' },