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
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Internalization Dumb Trigger Adapter (PRI-63)
3
+ *
4
+ * Thin adapter that wakes periodically to probe SQLite for ready
5
+ * internalization tasks. Plugin layer only — does NOT execute LLM calls,
6
+ * does NOT directly chain PeerRunners, does NOT modify task status.
7
+ *
8
+ * Core decision functions (validateInternalizationTaskReady) determine
9
+ * if a task is ready to be processed. This adapter is only responsible
10
+ * for waking and logging — actual dispatch is handled by future
11
+ * Orchestrator PRI.
12
+ *
13
+ * @see docs/adr/0003-peer-agent-state-machine-orchestration.md
14
+ * @see packages/principles-core/src/runtime-v2/internalization/internalization-state-machine.ts (PRI-62)
15
+ */
16
+
17
+ import type { TaskRecord } from '@principles/core/runtime-v2';
18
+
19
+ import {
20
+ validateInternalizationTaskReady,
21
+ isPeerRunnerKind,
22
+ hydratePITaskRecord,
23
+ type PITaskRecord,
24
+ type PeerRunnerKind,
25
+ } from '@principles/core/runtime-v2';
26
+
27
+ // ── Structured log event types ───────────────────────────────────────────────
28
+
29
+ type TriggerWakeEvent = {
30
+ event: 'INTERNALIZATION_TRIGGER_WAKE';
31
+ workspaceDir: string;
32
+ taskId: string;
33
+ taskKind: PeerRunnerKind;
34
+ correlationId?: string;
35
+ gateDecision: 'proceed';
36
+ timestamp: string;
37
+ };
38
+
39
+ type TriggerNoopEvent = {
40
+ event: 'INTERNALIZATION_TRIGGER_NOOP';
41
+ workspaceDir: string;
42
+ timestamp: string;
43
+ };
44
+
45
+ type TriggerBlockedEvent = {
46
+ event: 'INTERNALIZATION_TRIGGER_BLOCKED';
47
+ workspaceDir: string;
48
+ taskId: string;
49
+ taskKind: string;
50
+ gateDecision: 'blocked' | 'dependency_failed' | 'retry_wait_pending';
51
+ blockedBy?: string[];
52
+ failedDependencies?: string[];
53
+ retryAfter?: string;
54
+ timestamp: string;
55
+ };
56
+
57
+ type TriggerFailedEvent = {
58
+ event: 'INTERNALIZATION_TRIGGER_FAILED';
59
+ workspaceDir: string;
60
+ failureCategory: 'invalid_context' | 'provider_error' | 'unexpected_error';
61
+ error?: string;
62
+ timestamp: string;
63
+ };
64
+
65
+ type LogEvent = TriggerWakeEvent | TriggerNoopEvent | TriggerFailedEvent | TriggerBlockedEvent;
66
+
67
+ // ── Logger interface ─────────────────────────────────────────────────────────
68
+
69
+ export interface TriggerLogger {
70
+ debug?(msg: string, meta?: Record<string, unknown>): void;
71
+ info?(msg: string, meta?: Record<string, unknown>): void;
72
+ warn?(msg: string, meta?: Record<string, unknown>): void;
73
+ error?(msg: string, meta?: Record<string, unknown>): void;
74
+ }
75
+
76
+ // ── Task provider interface (dependency injection for testability) ───────────
77
+
78
+ export interface InternalizationTaskProvider {
79
+ listTasks(filter?: { status?: string; taskKind?: string }): Promise<TaskRecord[]>;
80
+ getTask(taskId: string): Promise<TaskRecord | null>;
81
+ }
82
+
83
+ // ── Wake context ──────────────────────────────────────────────────────────────
84
+
85
+ export interface TriggerContext {
86
+ workspaceDir: string;
87
+ stateDir: string;
88
+ }
89
+
90
+ // ── Adapter interface ─────────────────────────────────────────────────────────
91
+
92
+ export interface InternalizationTriggerAdapter {
93
+ wake(ctx: TriggerContext): Promise<void>;
94
+ start(ctx: TriggerContext, intervalMs?: number): () => void;
95
+ stop(): void;
96
+ }
97
+
98
+ // ── Internal state ─────────────────────────────────────────────────────────────
99
+
100
+ interface AdapterState {
101
+ intervalId: ReturnType<typeof setInterval> | null;
102
+ }
103
+
104
+ // ── Log helper ────────────────────────────────────────────────────────────────
105
+
106
+ function emitLog(
107
+ logger: TriggerLogger | undefined,
108
+ event: LogEvent,
109
+ ): void {
110
+ const { event: eventType, ...meta } = event;
111
+
112
+ switch (eventType) {
113
+ case 'INTERNALIZATION_TRIGGER_WAKE':
114
+ logger?.info?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_WAKE', meta);
115
+ break;
116
+ case 'INTERNALIZATION_TRIGGER_NOOP':
117
+ logger?.debug?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_NOOP', meta);
118
+ break;
119
+ case 'INTERNALIZATION_TRIGGER_BLOCKED':
120
+ logger?.debug?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_BLOCKED', meta);
121
+ break;
122
+ case 'INTERNALIZATION_TRIGGER_FAILED':
123
+ logger?.error?.('[PD:InternalizationTrigger] INTERNALIZATION_TRIGGER_FAILED', meta);
124
+ break;
125
+ }
126
+ }
127
+
128
+ // ── Core adapter factory ───────────────────────────────────────────────────────
129
+
130
+ /**
131
+ * Creates a dumb trigger adapter that probes for ready internalization tasks.
132
+ *
133
+ * Design constraints (enforced by architecture regression guards):
134
+ * - PLUGIN_NO_INLINE_EXECUTION: wake() is read-only, does not await long tasks
135
+ * - PEER_NO_DIRECT_CHAINING: adapter does not call Dreamer/Philosopher/Scribe
136
+ * - TASK_MODEL_REUSE: reuses PITaskRecord / TaskRecord, no second task model
137
+ *
138
+ * @param provider - Task data access abstraction (SqliteTaskStore in production)
139
+ * @param logger - Optional structured logger
140
+ */
141
+ export function createInternalizationTrigger(
142
+ provider: InternalizationTaskProvider,
143
+ logger?: TriggerLogger,
144
+ ): InternalizationTriggerAdapter {
145
+ const state: AdapterState = {
146
+ intervalId: null,
147
+ };
148
+
149
+ // ── wake: single trigger cycle ─────────────────────────────────────────────
150
+
151
+ async function wake(ctx: TriggerContext): Promise<void> {
152
+ // Fail closed: missing workspaceDir or stateDir
153
+ if (!ctx.workspaceDir || !ctx.stateDir) {
154
+ emitLog(logger, {
155
+ event: 'INTERNALIZATION_TRIGGER_FAILED',
156
+ workspaceDir: ctx.workspaceDir ?? '(missing)',
157
+ failureCategory: 'invalid_context',
158
+ error: 'workspaceDir or stateDir is missing',
159
+ timestamp: new Date().toISOString(),
160
+ });
161
+ return;
162
+ }
163
+
164
+ try {
165
+ // Query pending and retry_wait tasks (non-terminal states that can be leased)
166
+ const pendingTasks = await provider.listTasks({ status: 'pending' });
167
+ const retryWaitTasks = await provider.listTasks({ status: 'retry_wait' });
168
+
169
+ // Filter to only PeerRunner tasks, then hydrate PI metadata from diagnosticJson.
170
+ // Tasks without valid PI metadata in diagnosticJson return null and are filtered out.
171
+ const pendingPITasks = pendingTasks
172
+ .filter(t => isPeerRunnerKind(t.taskKind))
173
+ .map(t => hydratePITaskRecord(t))
174
+ .filter((t): t is PITaskRecord => t !== null);
175
+
176
+ const retryWaitPITasks = retryWaitTasks
177
+ .filter(t => isPeerRunnerKind(t.taskKind))
178
+ .map(t => hydratePITaskRecord(t))
179
+ .filter((t): t is PITaskRecord => t !== null);
180
+
181
+ const candidateTasks = [...pendingPITasks, ...retryWaitPITasks];
182
+
183
+ // No candidates → NOOP
184
+ if (candidateTasks.length === 0) {
185
+ emitLog(logger, {
186
+ event: 'INTERNALIZATION_TRIGGER_NOOP',
187
+ workspaceDir: ctx.workspaceDir,
188
+ timestamp: new Date().toISOString(),
189
+ });
190
+ return;
191
+ }
192
+
193
+ // Evaluate each candidate
194
+ let hasReadyTask = false;
195
+
196
+ for (const task of candidateTasks) {
197
+ // Fetch dependency tasks for gate validation
198
+ const dependencies: TaskRecord[] = [];
199
+ if (task.dependencyTaskIds && task.dependencyTaskIds.length > 0) {
200
+ for (const depId of task.dependencyTaskIds) {
201
+ const dep = await provider.getTask(depId);
202
+ if (dep) dependencies.push(dep);
203
+ // Fail closed: if dep not found, dependencies array is incomplete
204
+ // validateInternalizationTaskReady will return 'blocked'
205
+ }
206
+ }
207
+
208
+ const gateResult = validateInternalizationTaskReady(task, dependencies);
209
+
210
+ if (gateResult.decision === 'proceed') {
211
+ // Task is ready — log WAKE event (read-only, no mutation)
212
+ emitLog(logger, {
213
+ event: 'INTERNALIZATION_TRIGGER_WAKE',
214
+ workspaceDir: ctx.workspaceDir,
215
+ taskId: task.taskId,
216
+ taskKind: task.taskKind,
217
+ correlationId: task.correlationId,
218
+ gateDecision: gateResult.decision,
219
+ timestamp: new Date().toISOString(),
220
+ });
221
+ hasReadyTask = true;
222
+ } else {
223
+ // blocked, dependency_failed, or retry_wait_pending — debug visibility for operators
224
+ emitLog(logger, {
225
+ event: 'INTERNALIZATION_TRIGGER_BLOCKED',
226
+ workspaceDir: ctx.workspaceDir,
227
+ taskId: task.taskId,
228
+ taskKind: task.taskKind,
229
+ gateDecision: gateResult.decision,
230
+ blockedBy: gateResult.decision === 'blocked' ? gateResult.blockedBy : undefined,
231
+ failedDependencies: gateResult.decision === 'dependency_failed' ? gateResult.failedDependencies : undefined,
232
+ retryAfter: gateResult.decision === 'retry_wait_pending' ? gateResult.retryAfter : undefined,
233
+ timestamp: new Date().toISOString(),
234
+ });
235
+ }
236
+ }
237
+
238
+ // All candidates were blocked
239
+ if (!hasReadyTask) {
240
+ emitLog(logger, {
241
+ event: 'INTERNALIZATION_TRIGGER_NOOP',
242
+ workspaceDir: ctx.workspaceDir,
243
+ timestamp: new Date().toISOString(),
244
+ });
245
+ }
246
+ } catch (err) {
247
+ emitLog(logger, {
248
+ event: 'INTERNALIZATION_TRIGGER_FAILED',
249
+ workspaceDir: ctx.workspaceDir,
250
+ failureCategory: 'provider_error',
251
+ error: err instanceof Error ? err.message : String(err),
252
+ timestamp: new Date().toISOString(),
253
+ });
254
+ }
255
+ }
256
+
257
+ // ── start: begin periodic wake cycles ─────────────────────────────────────
258
+
259
+ function start(ctx: TriggerContext, intervalMs = 5 * 60 * 1000): () => void {
260
+ // Prevent re-entrancy: if already running, warn and return existing stop
261
+ if (state.intervalId !== null) {
262
+ logger?.warn?.('[PD:InternalizationTrigger] start() called while already running — returning existing stop', {
263
+ workspaceDir: ctx.workspaceDir,
264
+ stateDir: ctx.stateDir,
265
+ });
266
+ return stop;
267
+ }
268
+
269
+ // Immediate first wake
270
+ wake(ctx).catch(err => {
271
+ logger?.error?.('[PD:InternalizationTrigger] start() initial wake failed', {
272
+ error: err instanceof Error ? err.message : String(err),
273
+ });
274
+ });
275
+
276
+ // Schedule periodic wake
277
+ state.intervalId = setInterval(() => {
278
+ wake(ctx).catch(err => {
279
+ logger?.error?.('[PD:InternalizationTrigger] periodic wake failed', {
280
+ error: err instanceof Error ? err.message : String(err),
281
+ });
282
+ });
283
+ }, intervalMs);
284
+
285
+ return stop;
286
+ }
287
+
288
+ // ── stop: halt periodic wake ──────────────────────────────────────────────
289
+
290
+ function stop(): void {
291
+ if (state.intervalId !== null) {
292
+ clearInterval(state.intervalId);
293
+ state.intervalId = null;
294
+ }
295
+ }
296
+
297
+ return { wake, start, stop };
298
+ }
299
+
300
+ // ── Re-export types for consumers ────────────────────────────────────────────
301
+
302
+ export type { PITaskRecord, PeerRunnerKind } from '@principles/core/runtime-v2';
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { CorrectionCueLearner } from '../core/correction-cue-learner.js';
10
- import type { CorrectionObserverResult } from './subagent-workflow/correction-observer-types.js';
10
+ import type { CorrectionObserverOutputV1 as CorrectionObserverResult } from '@principles/core/runtime-v2';
11
11
  import type { PluginLogger } from '../openclaw-sdk.js';
12
12
  import { TrajectoryRegistry } from '../core/trajectory.js';
13
13
 
@@ -83,8 +83,8 @@ export class KeywordOptimizationService {
83
83
  const MAX_FP_TERMS = 20;
84
84
  const normalizedFpTerms = [...new Set(
85
85
  result.fpTerms
86
- .map(t => t.trim().toLowerCase())
87
- .filter(t => t.length > 0)
86
+ .map((t: string) => t.trim().toLowerCase())
87
+ .filter((t: string) => t.length > 0)
88
88
  )].slice(0, MAX_FP_TERMS);
89
89
 
90
90
  for (const term of normalizedFpTerms) {
@@ -166,4 +166,4 @@ export type TrajectoryHistoryEntry = {
166
166
  };
167
167
 
168
168
  /** Re-export CorrectionObserverPayload for convenience */
169
- export type { CorrectionObserverPayload } from './subagent-workflow/correction-observer-types.js';
169
+ export type { CorrectionObserverPayload } from '@principles/core/runtime-v2';
@@ -1,9 +1,5 @@
1
1
  import { WorkflowStore } from './subagent-workflow/workflow-store.js';
2
2
 
3
- /**
4
- * Monitoring query service for Nocturnal workflows and Trinity stages.
5
- * Encapsulates all monitoring data queries, keeping logic separate from API routes.
6
- */
7
3
  export class MonitoringQueryService {
8
4
  private readonly workspaceDir: string;
9
5
  private readonly store: WorkflowStore;
@@ -17,30 +13,20 @@ export class MonitoringQueryService {
17
13
  this.store.dispose();
18
14
  }
19
15
 
20
- /**
21
- * Get workflows with optional filtering and stuck detection.
22
- * @param filters - Optional state and type filters
23
- * @returns Workflow list with stuck detection
24
- */
25
16
  getWorkflows(filters: { state?: string; type?: string } = {}): WorkflowListResponse {
26
- // Query workflows from WorkflowStore
27
17
  let workflows = filters.state
28
18
  ? this.store.listWorkflows(filters.state)
29
19
  : this.store.listWorkflows();
30
20
 
31
- // Filter by workflow type if specified
32
21
  if (filters.type) {
33
22
  workflows = workflows.filter(wf => wf.workflow_type === filters.type);
34
23
  }
35
24
 
36
25
  const now = Date.now();
37
26
  const workflowsWithStuckDetection = workflows.map(wf => {
38
- // Parse metadata for timeout configuration
39
-
40
27
  const metadata = parseWorkflowMetadata(wf.metadata_json);
41
- const timeoutMs = metadata.timeoutMs ?? 15 * 60 * 1000; // Default 15 minutes
28
+ const timeoutMs = metadata.timeoutMs ?? 15 * 60 * 1000;
42
29
 
43
- // Check if workflow is stuck (active and exceeded timeout)
44
30
  const isStuck = wf.state === 'active' && (now - wf.created_at) > timeoutMs;
45
31
  const stuckDuration = isStuck ? now - wf.created_at : null;
46
32
 
@@ -56,158 +42,6 @@ export class MonitoringQueryService {
56
42
 
57
43
  return { workflows: workflowsWithStuckDetection };
58
44
  }
59
-
60
- /**
61
- * Get Trinity stage status for a specific workflow.
62
- * @param workflowId - Workflow ID to query
63
- * @returns Trinity stage status or null if workflow not found
64
- */
65
- getTrinityStatus(workflowId: string): TrinityStatusResponse | null {
66
- // Get workflow and validate
67
- const workflow = this.store.getWorkflow(workflowId);
68
- if (!workflow) {
69
- return null;
70
- }
71
-
72
- // Fetch stage data
73
- const events = this.store.getEvents(workflowId);
74
- const stageOutputs = this.store.getStageOutputs(workflowId);
75
-
76
- // Define stage types
77
- const stages = ['dreamer', 'philosopher', 'scribe'] as const;
78
-
79
- // Compute stage states from events
80
- const stagesInfo: TrinityStageInfo[] = stages.map(stage => {
81
- // Find events for this stage
82
- const startEvent = events.find(e => e.event_type === `trinity_${stage}_start`);
83
- const completeEvent = events.find(e => e.event_type === `trinity_${stage}_complete`);
84
- const failedEvent = events.find(e => e.event_type === `trinity_${stage}_failed`);
85
-
86
- // Determine status
87
-
88
-
89
- let status: 'pending' | 'running' | 'completed' | 'failed';
90
-
91
-
92
- let reason: string | undefined;
93
-
94
- if (!startEvent) {
95
- status = 'pending';
96
- reason = undefined;
97
- } else if (failedEvent) {
98
- status = 'failed';
99
- ({ reason } = failedEvent);
100
- } else if (completeEvent) {
101
- status = 'completed';
102
- reason = undefined;
103
- } else {
104
- status = 'running';
105
- reason = undefined;
106
- }
107
-
108
- // Count outputs for this stage
109
- const outputCount = stageOutputs.filter(so => so.stage === stage).length;
110
-
111
- // Calculate duration if stage started and completed/failed
112
-
113
-
114
- let duration: number | undefined;
115
- if (startEvent && (completeEvent || failedEvent)) {
116
- const endEvent = completeEvent || failedEvent;
117
- if (endEvent) {
118
- duration = endEvent.created_at - startEvent.created_at;
119
- }
120
- }
121
-
122
- return {
123
- stage,
124
- status,
125
- reason,
126
- outputCount,
127
- duration,
128
- };
129
- });
130
-
131
- return {
132
- workflowId,
133
- stages: stagesInfo,
134
- };
135
- }
136
-
137
- /**
138
- * Get aggregate health metrics for all Trinity workflows.
139
- * @returns Aggregate health statistics
140
- */
141
- getTrinityHealth(): TrinityHealthResponse {
142
- // Get all workflows
143
- const workflows = this.store.listWorkflows();
144
-
145
- // Initialize counters
146
- let totalCalls = 0;
147
- let totalDuration = 0;
148
- let failedCalls = 0;
149
-
150
- // Initialize stage statistics
151
- const stageStats = {
152
- dreamer: { total: 0, completed: 0, failed: 0 },
153
- philosopher: { total: 0, completed: 0, failed: 0 },
154
- scribe: { total: 0, completed: 0, failed: 0 },
155
- };
156
-
157
- // Iterate through workflows and aggregate
158
- for (const workflow of workflows) {
159
- const events = this.store.getEvents(workflow.workflow_id);
160
- const isTerminal =
161
- workflow.state === 'completed'
162
- || workflow.state === 'terminal_error'
163
- || workflow.state === 'expired'
164
- || workflow.state === 'cleanup_pending';
165
- let workflowFailed = false;
166
-
167
- // Aggregate stage statistics
168
- for (const stage of ['dreamer', 'philosopher', 'scribe'] as const) {
169
- // Check if stage started
170
- const started = events.some(e => e.event_type === `trinity_${stage}_start`);
171
- if (started) {
172
- stageStats[stage].total++;
173
- }
174
-
175
- // Check if completed
176
- const completed = events.some(e => e.event_type === `trinity_${stage}_complete`);
177
- if (completed) {
178
- stageStats[stage].completed++;
179
- }
180
-
181
- // Check if failed
182
- const failed = events.some(e => e.event_type === `trinity_${stage}_failed`);
183
- if (failed) {
184
- stageStats[stage].failed++;
185
- workflowFailed = true;
186
- }
187
- }
188
-
189
- // Calculate duration for terminal workflows so the aggregate reflects all finished runs.
190
- if (isTerminal) {
191
- totalCalls++;
192
- const duration = workflow.duration_ms ?? (Date.now() - workflow.created_at);
193
- totalDuration += duration;
194
- if (workflowFailed || workflow.state === 'terminal_error' || workflow.state === 'expired') {
195
- failedCalls++;
196
- }
197
- }
198
- }
199
-
200
- // Calculate derived metrics
201
- const avgDuration = totalCalls > 0 ? totalDuration / totalCalls : 0;
202
- const failureRate = totalCalls > 0 ? failedCalls / totalCalls : 0;
203
-
204
- return {
205
- totalCalls,
206
- avgDuration: Math.round(avgDuration),
207
- failureRate: Number(failureRate.toFixed(4)),
208
- stageStats,
209
- };
210
- }
211
45
  }
212
46
 
213
47
  function parseWorkflowMetadata(metadataJson: string): { timeoutMs?: number } {
@@ -219,16 +53,10 @@ function parseWorkflowMetadata(metadataJson: string): { timeoutMs?: number } {
219
53
  }
220
54
  }
221
55
 
222
- /**
223
- * Response type for workflow listing endpoint.
224
- */
225
56
  export interface WorkflowListResponse {
226
57
  workflows: WorkflowInfo[];
227
58
  }
228
59
 
229
- /**
230
- * Enriched workflow information with stuck detection.
231
- */
232
60
  export interface WorkflowInfo {
233
61
  workflowId: string;
234
62
  type: string;
@@ -237,45 +65,3 @@ export interface WorkflowInfo {
237
65
  createdAt: string;
238
66
  stuckDuration: number | null;
239
67
  }
240
-
241
- /**
242
- * Response type for Trinity status endpoint.
243
- */
244
- export interface TrinityStatusResponse {
245
- workflowId: string;
246
- stages: TrinityStageInfo[];
247
- }
248
-
249
- /**
250
- * Information about a single Trinity stage.
251
- */
252
- export interface TrinityStageInfo {
253
- stage: 'dreamer' | 'philosopher' | 'scribe';
254
- status: 'pending' | 'running' | 'completed' | 'failed';
255
- reason?: string;
256
- outputCount: number;
257
- duration?: number;
258
- }
259
-
260
- /**
261
- * Response type for Trinity health metrics endpoint.
262
- */
263
- export interface TrinityHealthResponse {
264
- totalCalls: number;
265
- avgDuration: number;
266
- failureRate: number;
267
- stageStats: {
268
- dreamer: StageStats;
269
- philosopher: StageStats;
270
- scribe: StageStats;
271
- };
272
- }
273
-
274
- /**
275
- * Per-stage statistics.
276
- */
277
- export interface StageStats {
278
- total: number;
279
- completed: number;
280
- failed: number;
281
- }