principles-disciple 1.72.0 → 1.73.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 (309) hide show
  1. package/openclaw.plugin.json +10 -5
  2. package/package.json +17 -19
  3. package/scripts/acceptance-test.mjs +16 -73
  4. package/scripts/sync-plugin.mjs +382 -77
  5. package/src/commands/archive-impl.ts +2 -1
  6. package/src/commands/capabilities.ts +2 -2
  7. package/src/commands/context.ts +2 -2
  8. package/src/commands/disable-impl.ts +2 -1
  9. package/src/commands/evolution-status.ts +16 -16
  10. package/src/commands/export.ts +12 -67
  11. package/src/commands/pain.ts +91 -1
  12. package/src/commands/principle-rollback.ts +2 -1
  13. package/src/commands/promote-impl.ts +7 -43
  14. package/src/commands/rollback-impl.ts +2 -1
  15. package/src/commands/rollback.ts +2 -1
  16. package/src/commands/samples.ts +2 -1
  17. package/src/commands/thinking-os.ts +2 -1
  18. package/src/config/errors.ts +18 -2
  19. package/src/constants/diagnostician.ts +2 -2
  20. package/src/constants/tools.ts +2 -1
  21. package/src/core/__tests__/focus-history.test.ts +210 -0
  22. package/src/core/config.ts +1 -1
  23. package/src/core/confirm-first-gate.ts +255 -0
  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 +38 -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/pain-diagnostic-gate.ts +154 -0
  37. package/src/core/pain-signal.ts +21 -138
  38. package/src/core/pain.ts +15 -88
  39. package/src/core/pd-task-reconciler.ts +26 -115
  40. package/src/core/pd-task-service.ts +9 -9
  41. package/src/core/pd-task-types.ts +23 -127
  42. package/src/core/principle-compiler/__tests__/compiler-replay-gate.test.ts +174 -0
  43. package/src/core/principle-compiler/code-validator.ts +15 -42
  44. package/src/core/principle-compiler/compiler.ts +100 -15
  45. package/src/core/principle-compiler/index.ts +5 -2
  46. package/src/core/principle-compiler/template-generator.ts +4 -104
  47. package/src/core/principle-injection.ts +10 -202
  48. package/src/core/principle-internalization/filesystem-lifecycle-datasource.ts +42 -0
  49. package/src/core/principle-internalization/lifecycle-read-model.ts +39 -242
  50. package/src/core/principle-internalization/principle-lifecycle-service.ts +12 -10
  51. package/src/core/principle-tree-ledger-adapter.ts +145 -0
  52. package/src/core/principle-tree-ledger.ts +8 -6
  53. package/src/core/reflection/reflection-context.ts +14 -109
  54. package/src/core/replay-engine.ts +8 -500
  55. package/src/core/rule-host-helpers.ts +5 -35
  56. package/src/core/rule-host-types.ts +10 -82
  57. package/src/core/rule-host.ts +6 -63
  58. package/src/core/runtime-v2-prompt-activation-reader.ts +231 -0
  59. package/src/core/session-tracker.ts +87 -101
  60. package/src/core/shadow-observation-registry.ts +19 -48
  61. package/src/core/trajectory.ts +3 -1
  62. package/src/core/workflow-funnel-loader.ts +62 -68
  63. package/src/core/workspace-context.ts +46 -0
  64. package/src/core/workspace-dir-service.ts +1 -1
  65. package/src/core/workspace-dir-validation.ts +18 -9
  66. package/src/hooks/AGENTS.md +1 -1
  67. package/src/hooks/gate-block-helper.ts +46 -44
  68. package/src/hooks/gate.ts +207 -7
  69. package/src/hooks/lifecycle.ts +30 -32
  70. package/src/hooks/llm.ts +60 -32
  71. package/src/hooks/pain.ts +297 -103
  72. package/src/hooks/prompt.ts +459 -439
  73. package/src/hooks/subagent.ts +2 -29
  74. package/src/i18n/commands.ts +2 -10
  75. package/src/index.ts +95 -85
  76. package/src/openclaw-sdk.ts +311 -0
  77. package/src/service/central-database.ts +8 -4
  78. package/src/service/evolution-queue-migration.ts +2 -1
  79. package/src/service/evolution-worker.ts +163 -1786
  80. package/src/service/internalization-trigger-adapter.ts +302 -0
  81. package/src/service/keyword-optimization-service.ts +4 -4
  82. package/src/service/monitoring-query-service.ts +1 -215
  83. package/src/service/queue-io.ts +60 -331
  84. package/src/service/runtime-summary-service.ts +59 -16
  85. package/src/service/subagent-workflow/index.ts +0 -41
  86. package/src/service/subagent-workflow/types.ts +9 -120
  87. package/src/service/subagent-workflow/workflow-store.ts +2 -119
  88. package/src/service/workflow-watchdog.ts +0 -43
  89. package/src/types/event-payload.ts +16 -74
  90. package/src/types/event-types.ts +39 -547
  91. package/src/types/hygiene-types.ts +7 -30
  92. package/src/types/principle-tree-schema.ts +20 -222
  93. package/src/types/queue.ts +15 -70
  94. package/src/types/runtime-summary.ts +5 -49
  95. package/src/utils/io.ts +10 -0
  96. package/src/utils/retry.ts +1 -1
  97. package/src/utils/shadow-fingerprint.ts +2 -2
  98. package/src/utils/workspace-resolver.ts +50 -0
  99. package/templates/langs/en/core/AGENTS.md +2 -2
  100. package/templates/langs/en/core/BOOT.md +1 -1
  101. package/templates/langs/en/core/HEARTBEAT.md +2 -2
  102. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  103. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  104. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  105. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  106. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  107. package/templates/langs/en/skills/ai-sprint-orchestration/runtime/.gitignore +2 -2
  108. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  109. package/templates/langs/en/skills/evolve-task/SKILL.md +1 -1
  110. package/templates/langs/en/skills/pd-cli-operator/SKILL.md +67 -0
  111. package/templates/langs/en/skills/pd-diagnostician/SKILL.md +1 -1
  112. package/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
  113. package/templates/langs/en/skills/pd-pain-signal/SKILL.md +17 -39
  114. package/templates/langs/en/skills/pd-runtime-v2/SKILL.md +61 -0
  115. package/templates/langs/zh/core/AGENTS.md +2 -2
  116. package/templates/langs/zh/core/BOOT.md +1 -1
  117. package/templates/langs/zh/core/HEARTBEAT.md +2 -2
  118. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +1 -72
  119. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +6 -6
  120. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +6 -6
  121. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +8 -8
  122. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +2 -12
  123. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +2 -12
  124. package/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +2 -2
  125. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +51 -15
  126. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +21 -5
  127. package/templates/langs/zh/skills/evolve-task/SKILL.md +2 -2
  128. package/templates/langs/zh/skills/pd-cli-operator/SKILL.md +67 -0
  129. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +1 -1
  130. package/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
  131. package/templates/langs/zh/skills/pd-pain-signal/SKILL.md +17 -38
  132. package/templates/langs/zh/skills/pd-runtime-v2/SKILL.md +61 -0
  133. package/tests/build-artifacts.test.ts +1 -3
  134. package/tests/commands/evolution-status.test.ts +0 -118
  135. package/tests/core/bootstrap-rules.test.ts +1 -1
  136. package/tests/core/config.test.ts +1 -1
  137. package/tests/core/event-log.test.ts +35 -0
  138. package/tests/core/evolution-engine.test.ts +610 -0
  139. package/tests/core/file-store.test.ts +102 -0
  140. package/tests/core/focus-history.test.ts +203 -11
  141. package/tests/core/merge-gate-audit.test.ts +2 -169
  142. package/tests/core/model-deployment-registry.test.ts +7 -1
  143. package/tests/core/model-training-registry.test.ts +19 -0
  144. package/tests/core/observability.test.ts +0 -1
  145. package/tests/core/pain-diagnostic-gate.test.ts +498 -0
  146. package/tests/core/pain.test.ts +0 -1
  147. package/tests/core/principle-internalization/deprecated-readiness.test.ts +2 -2
  148. package/tests/core/principle-internalization/lifecycle-metrics.test.ts +2 -2
  149. package/tests/core/principle-internalization/{internalization-routing-policy.test.ts → lifecycle-routing-policy.test.ts} +6 -6
  150. package/tests/core/principle-internalization/lineage-source-retired.test.ts +56 -0
  151. package/tests/core/principle-internalization/principle-lifecycle-service.test.ts +1 -23
  152. package/tests/core/principle-tree-ledger-adapter.test.ts +253 -0
  153. package/tests/core/reflection-context.test.ts +0 -14
  154. package/tests/core/replay-engine.test.ts +127 -215
  155. package/tests/core/rule-host-helpers.test.ts +2 -2
  156. package/tests/core/rule-implementation-runtime.test.ts +0 -27
  157. package/tests/core/workflow-funnel-loader.test.ts +162 -0
  158. package/tests/core/workspace-dir-validation.test.ts +8 -1
  159. package/tests/core-anti-growth.test.ts +192 -0
  160. package/tests/hook-workspace-nextaction-contract.test.ts +42 -0
  161. package/tests/hooks/confirm-first-gate.test.ts +333 -0
  162. package/tests/hooks/gate-auto-correct-shadow.test.ts +310 -0
  163. package/tests/hooks/gate-auto-correct.test.ts +665 -0
  164. package/tests/hooks/gate-rule-host-pipeline.test.ts +2 -1
  165. package/tests/hooks/pain.test.ts +269 -12
  166. package/tests/hooks/prompt-characterization.test.ts +500 -0
  167. package/tests/hooks/prompt-size-guard.test.ts +32 -17
  168. package/tests/hooks/runtime-v2-prompt-activation.test.ts +869 -0
  169. package/tests/index.test.ts +94 -1
  170. package/tests/integration/auto-entry-gate.test.ts +248 -0
  171. package/tests/integration/internalization-trigger-guard.test.ts +69 -0
  172. package/tests/integration/m8-legacy-paths.test.ts +63 -0
  173. package/tests/integration/runtime-v2-pain-guard.test.ts +125 -0
  174. package/tests/plugin-config-resolution-cutover.test.ts +359 -0
  175. package/tests/runtime-v2-discovery-guard.test.ts +154 -0
  176. package/tests/service/central-database.test.ts +457 -0
  177. package/tests/service/evolution-worker.correction-observer.test.ts +173 -0
  178. package/tests/service/evolution-worker.timeout.test.ts +11 -129
  179. package/tests/service/internalization-trigger-adapter.test.ts +251 -0
  180. package/tests/service/monitoring-query-service.test.ts +1 -47
  181. package/tests/service/queue-io.test.ts +1 -62
  182. package/tests/service/runtime-summary-service.test.ts +3 -1
  183. package/tests/service/workflow-watchdog.test.ts +0 -91
  184. package/tests/utils/file-lock.test.ts +5 -3
  185. package/tests/utils/session-key.test.ts +52 -0
  186. package/tests/utils/subagent-probe.test.ts +48 -1
  187. package/vitest.config.ts +4 -11
  188. package/.planning/codebase/ARCHITECTURE.md +0 -157
  189. package/.planning/codebase/CONCERNS.md +0 -145
  190. package/.planning/codebase/CONVENTIONS.md +0 -148
  191. package/.planning/codebase/INTEGRATIONS.md +0 -81
  192. package/.planning/codebase/STACK.md +0 -87
  193. package/.planning/codebase/STRUCTURE.md +0 -193
  194. package/.planning/codebase/TESTING.md +0 -243
  195. package/.planning/phases/01-basic-visualization/01-GAP-CLOSURE-VERIFICATION.md +0 -113
  196. package/docs/COMMAND_REFERENCE.md +0 -76
  197. package/docs/COMMAND_REFERENCE_EN.md +0 -79
  198. package/scripts/build-web.mjs +0 -46
  199. package/scripts/diagnose-nocturnal.mjs +0 -537
  200. package/scripts/seed-nocturnal-scenarios.mjs +0 -384
  201. package/src/commands/nocturnal-review.ts +0 -322
  202. package/src/commands/nocturnal-rollout.ts +0 -790
  203. package/src/commands/nocturnal-train.ts +0 -986
  204. package/src/commands/pd-reflect.ts +0 -88
  205. package/src/core/adaptive-thresholds.ts +0 -478
  206. package/src/core/diagnostician-task-store.ts +0 -192
  207. package/src/core/nocturnal-arbiter.ts +0 -715
  208. package/src/core/nocturnal-artifact-lineage.ts +0 -116
  209. package/src/core/nocturnal-artificer.ts +0 -257
  210. package/src/core/nocturnal-candidate-scoring.ts +0 -530
  211. package/src/core/nocturnal-compliance.ts +0 -1146
  212. package/src/core/nocturnal-dataset.ts +0 -763
  213. package/src/core/nocturnal-executability.ts +0 -428
  214. package/src/core/nocturnal-export.ts +0 -499
  215. package/src/core/nocturnal-paths.ts +0 -240
  216. package/src/core/nocturnal-reasoning-deriver.ts +0 -343
  217. package/src/core/nocturnal-rule-implementation-validator.ts +0 -246
  218. package/src/core/nocturnal-snapshot-contract.ts +0 -99
  219. package/src/core/nocturnal-trajectory-extractor.ts +0 -512
  220. package/src/core/nocturnal-trinity-types.ts +0 -218
  221. package/src/core/nocturnal-trinity.ts +0 -2680
  222. package/src/core/principle-internalization/deprecated-readiness.ts +0 -93
  223. package/src/core/principle-internalization/internalization-routing-policy.ts +0 -208
  224. package/src/core/principle-internalization/lifecycle-metrics.ts +0 -152
  225. package/src/http/principles-console-route.ts +0 -709
  226. package/src/service/central-health-service.ts +0 -49
  227. package/src/service/central-overview-service.ts +0 -138
  228. package/src/service/control-ui-query-service.ts +0 -900
  229. package/src/service/cooldown-strategy.ts +0 -97
  230. package/src/service/evolution-pain-context.ts +0 -79
  231. package/src/service/evolution-query-service.ts +0 -407
  232. package/src/service/health-query-service.ts +0 -1038
  233. package/src/service/nocturnal-config.ts +0 -214
  234. package/src/service/nocturnal-runtime.ts +0 -734
  235. package/src/service/nocturnal-service.ts +0 -1605
  236. package/src/service/nocturnal-target-selector.ts +0 -545
  237. package/src/service/sleep-cycle.ts +0 -157
  238. package/src/service/startup-reconciler.ts +0 -112
  239. package/src/service/subagent-workflow/correction-observer-types.ts +0 -82
  240. package/src/service/subagent-workflow/correction-observer-workflow-manager.ts +0 -250
  241. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +0 -1
  242. package/src/service/subagent-workflow/dynamic-timeout.ts +0 -30
  243. package/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +0 -268
  244. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +0 -795
  245. package/src/service/subagent-workflow/runtime-direct-driver.ts +0 -268
  246. package/src/service/subagent-workflow/workflow-manager-base.ts +0 -580
  247. package/src/tools/write-pain-flag.ts +0 -215
  248. package/tests/commands/nocturnal-review.test.ts +0 -448
  249. package/tests/commands/nocturnal-train.test.ts +0 -97
  250. package/tests/commands/pd-reflect.test.ts +0 -49
  251. package/tests/core/adaptive-thresholds.test.ts +0 -261
  252. package/tests/core/nocturnal-arbiter.test.ts +0 -559
  253. package/tests/core/nocturnal-artifact-lineage.test.ts +0 -53
  254. package/tests/core/nocturnal-artificer.test.ts +0 -241
  255. package/tests/core/nocturnal-candidate-scoring.test.ts +0 -532
  256. package/tests/core/nocturnal-compliance-p-principles.test.ts +0 -133
  257. package/tests/core/nocturnal-compliance.test.ts +0 -646
  258. package/tests/core/nocturnal-dataset.test.ts +0 -892
  259. package/tests/core/nocturnal-e2e.test.ts +0 -234
  260. package/tests/core/nocturnal-executability.test.ts +0 -357
  261. package/tests/core/nocturnal-export.test.ts +0 -517
  262. package/tests/core/nocturnal-reasoning-deriver.test.ts +0 -372
  263. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +0 -428
  264. package/tests/core/nocturnal-rule-implementation-validator.test.ts +0 -127
  265. package/tests/core/nocturnal-snapshot-contract.test.ts +0 -121
  266. package/tests/core/nocturnal-trajectory-extractor.test.ts +0 -634
  267. package/tests/core/nocturnal-trinity.test.ts +0 -2053
  268. package/tests/core/pain-auto-repair.test.ts +0 -96
  269. package/tests/core/pain-integration.test.ts +0 -510
  270. package/tests/fixtures/nocturnal-reviewed-subset.json +0 -183
  271. package/tests/http/principles-console-route.test.ts +0 -162
  272. package/tests/integration/chaos-resilience.test.ts +0 -348
  273. package/tests/integration/empathy-workflow-integration.test.ts +0 -626
  274. package/tests/integration/pain-diagnostician-loop.e2e.test.ts +0 -380
  275. package/tests/service/control-ui-query-service.test.ts +0 -121
  276. package/tests/service/cooldown-strategy.test.ts +0 -164
  277. package/tests/service/data-endpoints-regression.test.ts +0 -834
  278. package/tests/service/empathy-observer-workflow-manager.test.ts +0 -175
  279. package/tests/service/evolution-worker.nocturnal.test.ts +0 -601
  280. package/tests/service/nocturnal-runtime-hardening.test.ts +0 -118
  281. package/tests/service/nocturnal-runtime.test.ts +0 -473
  282. package/tests/service/nocturnal-service-code-candidate.test.ts +0 -330
  283. package/tests/service/nocturnal-target-selector.test.ts +0 -615
  284. package/tests/service/startup-reconciler.test.ts +0 -148
  285. package/tests/tools/write-pain-flag.test.ts +0 -358
  286. package/ui/src/App.tsx +0 -45
  287. package/ui/src/api.ts +0 -220
  288. package/ui/src/charts.tsx +0 -955
  289. package/ui/src/components/ErrorState.tsx +0 -6
  290. package/ui/src/components/Loading.tsx +0 -13
  291. package/ui/src/components/ProtectedRoute.tsx +0 -12
  292. package/ui/src/components/Shell.tsx +0 -91
  293. package/ui/src/components/WorkspaceConfig.tsx +0 -178
  294. package/ui/src/components/index.ts +0 -5
  295. package/ui/src/context/auth.tsx +0 -80
  296. package/ui/src/context/theme.tsx +0 -66
  297. package/ui/src/hooks/useAutoRefresh.ts +0 -39
  298. package/ui/src/i18n/ui.ts +0 -473
  299. package/ui/src/main.tsx +0 -16
  300. package/ui/src/pages/EvolutionPage.tsx +0 -333
  301. package/ui/src/pages/FeedbackPage.tsx +0 -138
  302. package/ui/src/pages/GateMonitorPage.tsx +0 -136
  303. package/ui/src/pages/LoginPage.tsx +0 -89
  304. package/ui/src/pages/OverviewPage.tsx +0 -599
  305. package/ui/src/pages/SamplesPage.tsx +0 -174
  306. package/ui/src/pages/ThinkingModelsPage.tsx +0 -702
  307. package/ui/src/styles.css +0 -2020
  308. package/ui/src/types.ts +0 -384
  309. 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
- }