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
@@ -1,512 +0,0 @@
1
- /**
2
- * Nocturnal Trajectory Extractor — Structured Session Snapshot API
3
- * ==============================================================
4
- *
5
- * PURPOSE: Provide minimal necessary structured trajectory extraction
6
- * for the nocturnal reflection pipeline. NOT a general-purpose data mirror.
7
- *
8
- * DESIGN PRINCIPLES:
9
- * - Uses sanitized text ONLY — never raw_text or blob payloads
10
- * - Two distinct query paths:
11
- * 1. Analytics query (listRecentNocturnalCandidateSessions) — for target selection
12
- * 2. Runtime query (getNocturnalSessionSnapshot) — for sample generation
13
- * - All snapshots are self-contained and principle-relevant metadata-rich
14
- *
15
- * WHAT THIS MODULE DOES:
16
- * - List recent sessions with metadata relevant to nocturnal target selection
17
- * - Extract structured session snapshots for a selected violating session
18
- *
19
- * WHAT THIS MODULE DOES NOT DO:
20
- * - NO snapshot database cloning
21
- * - NO full trajectory export
22
- * - NO raw text exposure
23
- * - NO target selection logic
24
- * - NO sample generation
25
- *
26
- * ARTIFACT OUTPUTS go to:
27
- * .state/nocturnal/samples/ ← structured JSON artifacts
28
- *
29
- * FILE: {stateDir}/nocturnal/snapshots/ (cached snapshots if needed, optional)
30
- */
31
-
32
- import type { TrajectoryDatabase} from './trajectory.js';
33
- import { TrajectoryRegistry } from './trajectory.js';
34
- import { detectThinkingModelMatches, listThinkingModels } from './thinking-models.js';
35
-
36
- // ---------------------------------------------------------------------------
37
- // Types
38
- // ---------------------------------------------------------------------------
39
-
40
- /**
41
- * Minimal sanitized assistant turn for nocturnal snapshot.
42
- * Contains ONLY sanitizedText — raw_text is never exposed.
43
- */
44
- export interface NocturnalAssistantTurn {
45
- turnIndex: number;
46
- sanitizedText: string;
47
- model: string;
48
- createdAt: string;
49
- }
50
-
51
- /**
52
- * Minimal sanitized user turn for nocturnal snapshot.
53
- * Contains only derived cues — NO raw user text.
54
- */
55
- export interface NocturnalUserTurn {
56
- turnIndex: number;
57
- correctionDetected: boolean;
58
- correctionCue: string | null;
59
- createdAt: string;
60
- }
61
-
62
- /**
63
- * Tool call event for nocturnal snapshot.
64
- */
65
- export interface NocturnalToolCall {
66
- toolName: string;
67
- outcome: 'success' | 'failure' | 'blocked';
68
- filePath: string | null;
69
- durationMs: number | null;
70
- exitCode: number | null;
71
- errorType: string | null;
72
- errorMessage: string | null;
73
- createdAt: string;
74
- }
75
-
76
- /**
77
- * Pain signal for nocturnal snapshot.
78
- */
79
- export interface NocturnalPainEvent {
80
- source: string;
81
- score: number;
82
- severity: string | null;
83
- reason: string | null;
84
- createdAt: string;
85
- }
86
-
87
- /**
88
- * Gate block event for nocturnal snapshot.
89
- */
90
- export interface NocturnalGateBlock {
91
- toolName: string;
92
- filePath: string | null;
93
- reason: string;
94
- planStatus: string | null;
95
- createdAt: string;
96
- }
97
-
98
- /**
99
- * User correction sample for nocturnal snapshot.
100
- * #268: Wire correction_samples into nocturnal pipeline.
101
- */
102
- export interface NocturnalUserCorrection {
103
- correctionCue: string | null;
104
- }
105
-
106
- /**
107
- * A structured nocturnal session snapshot.
108
- * Contains all information needed for a reflector to generate decision-point samples.
109
- *
110
- * GUARANTEES:
111
- * - NO raw_text exposed
112
- * - NO blob references resolved
113
- * - All text is sanitized or derived-cue only
114
- * - Self-contained (principle-relevant metadata included)
115
- */
116
- export interface NocturnalSessionSnapshot {
117
- sessionId: string;
118
- startedAt: string;
119
- updatedAt: string;
120
- assistantTurns: NocturnalAssistantTurn[];
121
- userTurns: NocturnalUserTurn[];
122
- toolCalls: NocturnalToolCall[];
123
- painEvents: NocturnalPainEvent[];
124
- gateBlocks: NocturnalGateBlock[];
125
- /** #268: User corrections from correction_samples table */
126
- userCorrections: NocturnalUserCorrection[];
127
- /**
128
- * Summary statistics for quick triage.
129
- * #246: All fields are now number (never null).
130
- * Previously null was used to mean "no trajectory data", but this caused
131
- * downstream consumers to crash on arithmetic. The fallback path now
132
- * queries the trajectory extractor for real data and falls back to 0.
133
- * Use _dataSource === 'pain_context_fallback' to detect partial data.
134
- */
135
- stats: {
136
- totalAssistantTurns: number;
137
- totalToolCalls: number;
138
- totalPainEvents: number;
139
- totalGateBlocks: number;
140
- failureCount: number;
141
- };
142
- /**
143
- * #219: Marker for data source to identify fallback/partial stats.
144
- * - 'pain_context_fallback': Stats derived from pain context only (trajectory extractor failed)
145
- */
146
- _dataSource?: 'pain_context_fallback';
147
- }
148
-
149
- /**
150
- * Summary entry for session listing (used by nocturnal target selector).
151
- * Lightweight — only identification and basic metadata, no turns.
152
- */
153
- export interface NocturnalSessionSummary {
154
- sessionId: string;
155
- startedAt: string;
156
- updatedAt: string;
157
- /** Number of assistant turns (for relevance scoring) */
158
- assistantTurnCount: number;
159
- /** Number of tool calls (for violation signal density) */
160
- toolCallCount: number;
161
- /** Number of pain events (for pain signal density) */
162
- painEventCount: number;
163
- /** Number of gate blocks (for constraint violation evidence) */
164
- gateBlockCount: number;
165
- /** Number of failed tool calls (for violation signal) */
166
- failureCount: number;
167
- }
168
-
169
- /**
170
- * Options for listing recent nocturnal candidate sessions.
171
- */
172
- export interface ListNocturnalSessionsOptions {
173
- /** Maximum number of sessions to return (default: 20) */
174
- limit?: number;
175
- /** Only return sessions updated after this date */
176
- dateFrom?: string;
177
- /** Only return sessions updated before this date */
178
- dateTo?: string;
179
- /** Minimum tool call count threshold (default: 1) */
180
- minToolCalls?: number;
181
- }
182
-
183
- // ---------------------------------------------------------------------------
184
- // Core Extractor
185
- // ---------------------------------------------------------------------------
186
-
187
- /**
188
- * Nocturnal Trajectory Extractor.
189
- *
190
- * Provides sanitized, structured access to session data for the nocturnal
191
- * reflection pipeline. All queries return sanitized text only.
192
- *
193
- * This class is a thin, focused wrapper around TrajectoryDatabase.
194
- * It does NOT cache snapshots or maintain its own state.
195
- */
196
- export class NocturnalTrajectoryExtractor {
197
- private readonly trajectory: TrajectoryDatabase;
198
-
199
- constructor(trajectory: TrajectoryDatabase) {
200
- this.trajectory = trajectory;
201
- }
202
-
203
- /**
204
- * List recent sessions suitable for nocturnal target selection.
205
- *
206
- * ANALYTICS QUERY — used by nocturnal target selector to find candidate sessions.
207
- *
208
- * @param options - Query options
209
- * @returns Lightweight session summaries ordered by most recently updated
210
- */
211
- listRecentNocturnalCandidateSessions(
212
- options: ListNocturnalSessionsOptions = {}
213
- ): NocturnalSessionSummary[] {
214
- const limit = options.limit ?? 20;
215
- const minToolCalls = options.minToolCalls ?? 1;
216
-
217
- // Get recent sessions from trajectory DB
218
- const sessions = this.trajectory.listRecentSessions({
219
- limit: limit * 3, // Over-fetch to allow filtering
220
- dateFrom: options.dateFrom,
221
- dateTo: options.dateTo,
222
- });
223
-
224
- if (sessions.length === 0) {
225
- return [];
226
- }
227
-
228
- // For each session, get counts
229
- // We batch these by fetching tool_calls count per session
230
- const summaries: NocturnalSessionSummary[] = [];
231
-
232
- for (const session of sessions) {
233
- if (summaries.length >= limit) break;
234
-
235
- const toolCalls = this.trajectory.listToolCallsForSession(session.sessionId);
236
- const painEvents = this.trajectory.listPainEventsForSession(session.sessionId);
237
- const gateBlocks = this.trajectory.listGateBlocksForSession(session.sessionId);
238
-
239
- // Filter by minimum tool calls threshold
240
- if (toolCalls.length < minToolCalls) {
241
- continue;
242
- }
243
-
244
- const failureCount = toolCalls.filter((tc) => tc.outcome === 'failure').length;
245
-
246
- summaries.push({
247
- sessionId: session.sessionId,
248
- startedAt: session.startedAt,
249
- updatedAt: session.updatedAt,
250
- assistantTurnCount: 0, // Not readily available without extra query
251
- toolCallCount: toolCalls.length,
252
- painEventCount: painEvents.length,
253
- gateBlockCount: gateBlocks.length,
254
- failureCount,
255
- });
256
- }
257
-
258
- return summaries;
259
- }
260
-
261
- /**
262
- * Get a full structured snapshot for a specific session.
263
- *
264
- * RUNTIME QUERY — used by nocturnal service after target selection.
265
- *
266
- * SECURITY GUARANTEES:
267
- * - Only sanitizedText from assistant turns (never raw_text)
268
- * - Only correction cues from user turns (never raw user text)
269
- * - Tool calls with outcome and error info (no raw parameters)
270
- * - Pain events with score and reason (no raw event data)
271
- * - Gate blocks with tool/reason info (no file content)
272
- *
273
- * @param sessionId - Session ID to snapshot
274
- * @returns Full structured snapshot, or null if session not found
275
- */
276
- getNocturnalSessionSnapshot(sessionId: string): NocturnalSessionSnapshot | null {
277
- // Verify session exists — must use a large enough limit to cover all candidates,
278
- // not just the single most-recent session (which would cause false negatives when
279
- // the selector targets an older session).
280
- const sessions = this.trajectory.listRecentSessions({ limit: 1000 });
281
- const sessionExists = sessions.some((s) => s.sessionId === sessionId);
282
- if (!sessionExists) {
283
- // Session might not be in trajectory DB — try to get basic info
284
- // If no data at all, return null for fail-safe
285
- return null;
286
- }
287
-
288
- // Fetch all turn data
289
- const assistantTurns = this.trajectory.listAssistantTurns(sessionId);
290
- const userTurns = this.trajectory.listUserTurnsForSession(sessionId);
291
- const toolCalls = this.trajectory.listToolCallsForSession(sessionId);
292
- const painEvents = this.trajectory.listPainEventsForSession(sessionId);
293
- const gateBlocks = this.trajectory.listGateBlocksForSession(sessionId);
294
- // #268: Fetch correction samples for this session
295
- const correctionSamples = this.trajectory.listCorrectionSamplesForSession(sessionId);
296
-
297
- // Map to sanitized structures
298
- // SECURITY: Only sanitizedText from assistant turns
299
- const sanitizedAssistantTurns: NocturnalAssistantTurn[] = assistantTurns.map(
300
- (turn, index) => ({
301
- turnIndex: index,
302
- sanitizedText: turn.sanitizedText,
303
- model: turn.model,
304
- createdAt: turn.createdAt,
305
- })
306
- );
307
-
308
- // SECURITY: Only derived cues from user turns
309
- const sanitizedUserTurns: NocturnalUserTurn[] = userTurns.map((turn) => ({
310
- turnIndex: turn.turnIndex,
311
- correctionDetected: turn.correctionDetected,
312
- correctionCue: turn.correctionCue,
313
- createdAt: turn.createdAt,
314
- }));
315
-
316
- // Tool calls — include outcome and error info but not raw params
317
- const nocturnalToolCalls: NocturnalToolCall[] = toolCalls.map((tc) => ({
318
- toolName: tc.toolName,
319
- outcome: tc.outcome as 'success' | 'failure' | 'blocked',
320
- filePath: tc.filePath,
321
- durationMs: tc.durationMs,
322
- exitCode: tc.exitCode,
323
- errorType: tc.errorType,
324
- errorMessage: tc.errorMessage,
325
- createdAt: tc.createdAt,
326
- }));
327
-
328
- // Pain events — score and reason only
329
- const nocturnalPainEvents: NocturnalPainEvent[] = painEvents.map((pe) => ({
330
- source: pe.source,
331
- score: pe.score,
332
- severity: pe.severity,
333
- reason: pe.reason,
334
- createdAt: pe.createdAt,
335
- }));
336
-
337
- // Gate blocks — tool and reason only
338
- const nocturnalGateBlocks: NocturnalGateBlock[] = gateBlocks.map((gb) => ({
339
- toolName: gb.toolName,
340
- filePath: gb.filePath,
341
- reason: gb.reason,
342
- planStatus: gb.planStatus,
343
- createdAt: gb.createdAt,
344
- }));
345
-
346
- // Compute summary stats
347
- const failureCount = toolCalls.filter((tc) => tc.outcome === 'failure').length;
348
-
349
- // Get session metadata (use trajectory data)
350
- const sessionMeta = sessions.find((s) => s.sessionId === sessionId);
351
-
352
- return {
353
- sessionId,
354
- startedAt: sessionMeta?.startedAt ?? new Date(0).toISOString(),
355
- updatedAt: sessionMeta?.updatedAt ?? new Date(0).toISOString(),
356
- assistantTurns: sanitizedAssistantTurns,
357
- userTurns: sanitizedUserTurns,
358
- toolCalls: nocturnalToolCalls,
359
- painEvents: nocturnalPainEvents,
360
- gateBlocks: nocturnalGateBlocks,
361
- // #268: Map correction samples to nocturnal format
362
- userCorrections: correctionSamples.map((cs: { correctionCue: string | null }) => ({
363
- correctionCue: cs.correctionCue,
364
- })),
365
- stats: {
366
- totalAssistantTurns: sanitizedAssistantTurns.length,
367
- totalToolCalls: nocturnalToolCalls.length,
368
- totalPainEvents: nocturnalPainEvents.length,
369
- totalGateBlocks: nocturnalGateBlocks.length,
370
- failureCount,
371
- },
372
- };
373
- }
374
- }
375
-
376
- // ---------------------------------------------------------------------------
377
- // Factory
378
- // ---------------------------------------------------------------------------
379
-
380
- /**
381
- * Creates a NocturnalTrajectoryExtractor from a workspace directory.
382
- *
383
- * USAGE:
384
- * const extractor = createNocturnalTrajectoryExtractor(workspaceDir);
385
- * const sessions = extractor.listRecentNocturnalCandidateSessions({ limit: 10 });
386
- * const snapshot = extractor.getNocturnalSessionSnapshot(sessionId);
387
- */
388
-
389
- export function createNocturnalTrajectoryExtractor(
390
- workspaceDir: string,
391
- _stateDir?: string
392
- ): NocturnalTrajectoryExtractor {
393
- // Use the registry to get or create the TrajectoryDatabase instance
394
- const trajectory = TrajectoryRegistry.get(workspaceDir);
395
- return new NocturnalTrajectoryExtractor(trajectory);
396
- }
397
-
398
- // ---------------------------------------------------------------------------
399
- // Direct module helpers (for cases where you already have TrajectoryDatabase)
400
- // ---------------------------------------------------------------------------
401
-
402
- /**
403
- * List recent sessions for nocturnal target selection.
404
- * Convenience wrapper around NocturnalTrajectoryExtractor.
405
- */
406
- export function listNocturnalCandidateSessions(
407
- trajectory: TrajectoryDatabase,
408
- options: ListNocturnalSessionsOptions = {}
409
- ): NocturnalSessionSummary[] {
410
- return new NocturnalTrajectoryExtractor(trajectory).listRecentNocturnalCandidateSessions(options);
411
- }
412
-
413
- /**
414
- * Get a session snapshot for nocturnal reflection.
415
- * Convenience wrapper around NocturnalTrajectoryExtractor.
416
- */
417
- export function getNocturnalSessionSnapshot(
418
- trajectory: TrajectoryDatabase,
419
- sessionId: string
420
- ): NocturnalSessionSnapshot | null {
421
- return new NocturnalTrajectoryExtractor(trajectory).getNocturnalSessionSnapshot(sessionId);
422
- }
423
-
424
- // ---------------------------------------------------------------------------
425
- // Reflection Quality Metrics
426
- // ---------------------------------------------------------------------------
427
-
428
- /**
429
- * Compute thinking model activation for a text.
430
- * Returns 0-1 ratio of matched thinking models to total available models.
431
- *
432
- * @param text - Text to analyze
433
- * @returns Activation ratio (0-1)
434
- */
435
- export function computeThinkingModelActivation(text: string): number {
436
- if (!text || text.trim().length === 0) return 0;
437
- const matches = detectThinkingModelMatches(text);
438
- const totalModels = listThinkingModels().length;
439
- return Math.round((matches.length / totalModels) * 100) / 100;
440
- }
441
-
442
- /**
443
- * Compute planning ratio from a session snapshot.
444
- * Planning ratio = write operations preceded immediately by a read tool / total write operations.
445
- * A higher ratio indicates more careful planning behavior (reading before writing).
446
- *
447
- * Only the immediately preceding tool is checked — each write needs its own
448
- * preceding read to count as planned. This prevents a single read from satisfying
449
- * multiple writes in sequence.
450
- *
451
- * @param snapshot - Session snapshot to analyze
452
- * @returns Planning ratio (0-1), or 0 if no write operations
453
- */
454
- export function computePlanningRatio(snapshot: NocturnalSessionSnapshot): number {
455
- const {toolCalls} = snapshot;
456
-
457
- let totalWrites = 0;
458
- let writesWithPrecedingRead = 0;
459
-
460
- for (let i = 0; i < toolCalls.length; i++) {
461
- const tc = toolCalls[i];
462
- const isWriteTool = /^(edit|write|create|delete|remove|move|rename)/i.test(tc.toolName);
463
-
464
- if (isWriteTool) {
465
- totalWrites++;
466
- // Check only the immediately preceding tool
467
- if (i > 0) {
468
- const prevTc = toolCalls[i - 1];
469
- const isReadTool = /^(read|grep|search|find|inspect|look)/i.test(prevTc.toolName);
470
- if (isReadTool) {
471
- writesWithPrecedingRead++;
472
- }
473
- }
474
- }
475
- }
476
-
477
- if (totalWrites === 0) return 0;
478
- return Math.round((writesWithPrecedingRead / totalWrites) * 100) / 100;
479
- }
480
-
481
- /**
482
- * Compute thinking model delta between original and improved decisions.
483
- * Positive delta means the improved decision uses more thinking models.
484
- *
485
- * @param originalText - Original (bad) decision text
486
- * @param improvedText - Improved (better) decision text
487
- * @returns Delta in thinking model activation (-1 to 1)
488
- */
489
- export function computeThinkingModelDelta(originalText: string, improvedText: string): number {
490
- const originalActivation = computeThinkingModelActivation(originalText);
491
- const improvedActivation = computeThinkingModelActivation(improvedText);
492
- const delta = improvedActivation - originalActivation;
493
- return Math.round(delta * 100) / 100;
494
- }
495
-
496
- /**
497
- * Compute planning ratio gain between original and improved snapshots.
498
- * Positive gain means the improved behavior has better planning (more reads before writes).
499
- *
500
- * @param originalSnapshot - Original session snapshot
501
- * @param improvedSnapshot - Improved session snapshot
502
- * @returns Planning ratio gain (-1 to 1)
503
- */
504
- export function computePlanningRatioGain(
505
- originalSnapshot: NocturnalSessionSnapshot,
506
- improvedSnapshot: NocturnalSessionSnapshot
507
- ): number {
508
- const originalRatio = computePlanningRatio(originalSnapshot);
509
- const improvedRatio = computePlanningRatio(improvedSnapshot);
510
- const gain = improvedRatio - originalRatio;
511
- return Math.round(gain * 100) / 100;
512
- }