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,240 +0,0 @@
1
- /**
2
- * Nocturnal Paths — Canonical Path Registry for Sleep-Mode Reflection Artifacts
3
- * =============================================================================
4
- *
5
- * PURPOSE: Establishes a single source of truth for all nocturnal artifact paths.
6
- * Prevents path fragmentation and ensures consistent resolution across modules.
7
- *
8
- * ARCHITECTURE:
9
- * Operator-facing (read by agent, injected into prompts):
10
- * memory/reflection-log.md ← human-readable lessons, NOT training data
11
- *
12
- * Nocturnal artifacts (structured, NOT injected into prompts):
13
- * .state/nocturnal/samples/ ← decision-point JSON artifacts (Phase 2+)
14
- * .state/nocturnal/memory/ ← short-term reflection memory (Phase 2+)
15
- * .state/exports/orpo/ ← approved training pairs, immutable (Phase 3+)
16
- *
17
- * DESIGN CONSTRAINTS:
18
- * - Nocturnal samples are NEVER written to memory/reflection-log.md
19
- * - Prompt injection reads ONLY from memory/reflection-log.md
20
- * - Each nocturnal artifact category has its own subdirectory
21
- * - All paths go through this registry — no ad-hoc path construction
22
- *
23
- * USAGE:
24
- * import { NocturnalPathResolver, NOCTURNAL_DIRS, NOCTURNAL_FILES } from './nocturnal-paths.js';
25
- * const sampleDir = NocturnalPathResolver.samplesDir(workspaceDir);
26
- */
27
-
28
- import * as path from 'path';
29
- import * as fs from 'fs';
30
-
31
- // ---------------------------------------------------------------------------
32
- // Directory Constants
33
- // ---------------------------------------------------------------------------
34
-
35
- export const NOCTURNAL_DIRS = {
36
- /** Root directory for all nocturnal reflection artifacts */
37
- ROOT: '.state/nocturnal',
38
-
39
- /**
40
- * Structured decision-point samples from nocturnal reflection.
41
- * Each file is a JSON artifact containing:
42
- * - session snapshot reference
43
- * - target principle
44
- * - decision-point contrastive pair
45
- * - arbiter approval status
46
- */
47
- SAMPLES: '.state/nocturnal/samples',
48
-
49
- /**
50
- * Short-term operator-facing reflection memory.
51
- * Written by nocturnal service, NOT injected into prompts directly.
52
- * Consumed by operator on next session start.
53
- */
54
- MEMORY: '.state/nocturnal/memory',
55
-
56
- /**
57
- * Nocturnal runtime bookkeeping (cooldowns, quotas).
58
- * NOTE: nocturnal-runtime.json is written to stateDir directly
59
- * (not under NOCTURNAL_DIRS.ROOT) for simpler migration.
60
- */
61
- // RUNTIME is in {stateDir}/nocturnal-runtime.json (not here)
62
-
63
- /**
64
- * Approved training pairs ready for export.
65
- * Immutable once written — never modified in place.
66
- * Consumed by external trainer (not the plugin).
67
- */
68
- EXPORTS: '.state/exports/orpo',
69
- } as const;
70
-
71
- // ---------------------------------------------------------------------------
72
- // File Path Constants (within their respective directories)
73
- // ---------------------------------------------------------------------------
74
-
75
- export const NOCTURNAL_FILES = {
76
- /**
77
- * Arbiter review queue for pending samples.
78
- * Not written by nocturnal service directly — created during arbiter review.
79
- * Format: JSON array of sample refs pending approval.
80
- */
81
- REVIEW_QUEUE: '.state/nocturnal/review-queue.json',
82
-
83
- /**
84
- * Lineage metadata for all samples.
85
- * Written alongside each sample file for traceability.
86
- */
87
- LINEAGE_INDEX: '.state/nocturnal/samples/lineage-index.json',
88
- } as const;
89
-
90
- // ---------------------------------------------------------------------------
91
- // Path Resolution
92
- // ---------------------------------------------------------------------------
93
-
94
- /**
95
- * Cross-platform path join for workspace-relative paths.
96
- * Handles Windows vs POSIX differences.
97
- */
98
- function joinWorkspacePath(workspaceDir: string, relativePath: string): string {
99
- const normalized = relativePath.replace(/\\/g, '/');
100
- if (/^[A-Za-z]:/.test(workspaceDir)) {
101
- // Windows
102
- return path.win32.join(workspaceDir, ...normalized.split('/'));
103
- }
104
- return path.posix.join(workspaceDir, ...normalized.split('/'));
105
- }
106
-
107
- /**
108
- * Resolves a nocturnal directory path within a workspace.
109
- */
110
- export function resolveNocturnalDir(workspaceDir: string, dirKey: keyof typeof NOCTURNAL_DIRS): string {
111
- return joinWorkspacePath(workspaceDir, NOCTURNAL_DIRS[dirKey]);
112
- }
113
-
114
- /**
115
- * Resolves a nocturnal file path within a workspace.
116
- */
117
- export function resolveNocturnalFile(workspaceDir: string, fileKey: keyof typeof NOCTURNAL_FILES): string {
118
- return joinWorkspacePath(workspaceDir, NOCTURNAL_FILES[fileKey]);
119
- }
120
-
121
- // ---------------------------------------------------------------------------
122
- // NocturnalPathResolver — Fluent API for common resolutions
123
- // ---------------------------------------------------------------------------
124
-
125
- export const NocturnalPathResolver = {
126
- /**
127
- * Returns the samples directory path.
128
- * Creates the directory if it does not exist.
129
- */
130
- samplesDir(workspaceDir: string): string {
131
- const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
132
- if (!fs.existsSync(dir)) {
133
- fs.mkdirSync(dir, { recursive: true });
134
- }
135
- return dir;
136
- },
137
-
138
- /**
139
- * Returns the memory directory path.
140
- * Creates the directory if it does not exist.
141
- */
142
- memoryDir(workspaceDir: string): string {
143
- const dir = resolveNocturnalDir(workspaceDir, 'MEMORY');
144
- if (!fs.existsSync(dir)) {
145
- fs.mkdirSync(dir, { recursive: true });
146
- }
147
- return dir;
148
- },
149
-
150
- /**
151
- * Returns the exports directory path.
152
- * Creates the directory if it does not exist.
153
- */
154
- exportsDir(workspaceDir: string): string {
155
- const dir = resolveNocturnalDir(workspaceDir, 'EXPORTS');
156
- if (!fs.existsSync(dir)) {
157
- fs.mkdirSync(dir, { recursive: true });
158
- }
159
- return dir;
160
- },
161
-
162
- /**
163
- * Returns the path for a named sample file.
164
- * File is NOT created — caller decides when to write.
165
- */
166
- samplePath(workspaceDir: string, sampleId: string): string {
167
- const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
168
- // Sanitize sampleId for filesystem
169
- const safeId = sampleId.replace(/[/\\:]/g, '_');
170
- return path.join(dir, `${safeId}.json`);
171
- },
172
-
173
- /**
174
- * Returns the path for nocturnal reflection memory.
175
- * This is the operator-facing summary written after each nocturnal run.
176
- */
177
- reflectionMemoryPath(workspaceDir: string): string {
178
- return path.join(
179
- resolveNocturnalDir(workspaceDir, 'MEMORY'),
180
- 'reflection-memory.md'
181
- );
182
- },
183
-
184
- /**
185
- * Lists all sample files in the samples directory.
186
- * Returns absolute paths sorted by modification time (newest first).
187
- */
188
- listSamples(workspaceDir: string): string[] {
189
- const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
190
- if (!fs.existsSync(dir)) {
191
- return [];
192
- }
193
- try {
194
- return fs.readdirSync(dir)
195
- .filter(f => f.endsWith('.json'))
196
- .map(f => path.join(dir, f))
197
- .sort((a, b) => fs.statSync(b).mtime.getTime() - fs.statSync(a).mtime.getTime());
198
- } catch {
199
- return [];
200
- }
201
- },
202
-
203
- /**
204
- * Lists all approved sample files ready for export.
205
- * Filters to samples with status === 'approved'.
206
- */
207
- listApprovedSamples(workspaceDir: string): string[] {
208
- return this.listSamples(workspaceDir).filter(samplePath => {
209
- try {
210
- const content = fs.readFileSync(samplePath, 'utf-8');
211
- const sample = JSON.parse(content);
212
- return sample.status === 'approved';
213
- } catch {
214
- return false;
215
- }
216
- });
217
- },
218
- } as const;
219
-
220
- // ---------------------------------------------------------------------------
221
- // Constants for documentation / external reference
222
- // ---------------------------------------------------------------------------
223
-
224
- /**
225
- * Complete path map for reference.
226
- * These mirror the keys in NOCTURNAL_DIRS and NOCTURNAL_FILES.
227
- */
228
- export const NOCTURNAL_PATH_DESCRIPTIONS: Record<string, string> = {
229
- '.state/nocturnal/samples/': 'Structured decision-point JSON artifacts (not injected into prompts)',
230
- '.state/nocturnal/memory/': 'Short-term operator-facing reflection memory (not prompt-injected)',
231
- '.state/exports/orpo/': 'Approved training pairs, immutable after export',
232
- '.state/nocturnal/review-queue.json': 'Pending sample review queue',
233
- 'memory/reflection-log.md': 'Operator-facing human-readable lessons (INJECTED into prompts)',
234
- };
235
-
236
- /**
237
- * IMPORTANT: memory/reflection-log.md is NOT a nocturnal artifact.
238
- * It is the pre-existing operator-facing reflection log, defined in paths.ts.
239
- * It is kept separate from nocturnal outputs by design.
240
- */
@@ -1,343 +0,0 @@
1
- /**
2
- * Nocturnal Reasoning Deriver — Runtime Reasoning Signal Extraction
3
- * ==============================================================
4
- *
5
- * PURPOSE: Derive structured reasoning signals from existing snapshot data
6
- * without any snapshot schema changes. Pure functions, zero dependencies.
7
- *
8
- * THREE FUNCTIONS:
9
- * - deriveReasoningChain: Extract thinking content, uncertainty, confidence from assistant turns
10
- * - deriveDecisionPoints: Extract before/after context per tool call (Plan 02)
11
- * - deriveContextualFactors: Compute contextual factors from snapshot (Plan 02)
12
- */
13
-
14
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
- import type { NocturnalAssistantTurn, NocturnalToolCall, NocturnalUserTurn, NocturnalSessionSnapshot } from './nocturnal-trajectory-extractor.js';
16
- import { detectThinkingModelMatches, listThinkingModels } from './thinking-models.js';
17
-
18
- // ---------------------------------------------------------------------------
19
- // Shared helpers
20
- // ---------------------------------------------------------------------------
21
-
22
- /** Parse an ISO 8601 timestamp, returning NaN for invalid formats. */
23
- function parseTs(ts: string): number {
24
- // ISO 8601 strings without Z suffix or offset are treated as local time.
25
- // Log a warning for ambiguous formats (missing timezone indicator).
26
- if (
27
- typeof ts === 'string' &&
28
- !ts.endsWith('Z') &&
29
- !ts.includes('+') &&
30
- ts.includes('-', 4)
31
- ) {
32
- // Looks like an ISO date but no timezone — could be ambiguous
33
- const bare = ts.slice(0, 10);
34
- if (/^\d{4}-\d{2}-\d{2}$/.test(bare)) {
35
- // Plain YYYY-MM-DD without time or Z — definitely ambiguous
36
- console.warn(`[Deriver] Timestamp missing timezone: "${ts}"`);
37
- }
38
- }
39
- return Date.parse(ts);
40
- }
41
-
42
- // ---------------------------------------------------------------------------
43
- // Shared types (used across all three derive functions)
44
- // ---------------------------------------------------------------------------
45
-
46
- export interface DerivedReasoningSignal {
47
- turnIndex: number;
48
- thinkingContent: string;
49
- uncertaintyMarkers: string[];
50
- confidenceSignal: "high" | "medium" | "low";
51
- }
52
-
53
- export interface DerivedDecisionPoint {
54
- toolName: string;
55
- outcome: "success" | "failure" | "blocked";
56
- beforeContext: string;
57
- afterReflection?: string;
58
- confidenceDelta?: number;
59
- }
60
-
61
- export interface DerivedContextualFactors {
62
- fileStructureKnown: boolean;
63
- errorHistoryPresent: boolean;
64
- userGuidanceAvailable: boolean;
65
- timePressure: boolean;
66
- }
67
-
68
- // ---------------------------------------------------------------------------
69
- // Constants
70
- // ---------------------------------------------------------------------------
71
-
72
- const UNCERTAINTY_PATTERNS: RegExp[] = [
73
- /let me (check|verify|confirm|understand)/gi,
74
- /I should (first|probably|maybe)/gi,
75
- /not sure (if|whether|about)/gi,
76
- ];
77
-
78
- const THINKING_TAG_REGEX = /<thinking>([\s\S]*?)<\/thinking>/g;
79
-
80
- // ---------------------------------------------------------------------------
81
- // Helpers
82
- // ---------------------------------------------------------------------------
83
-
84
- /**
85
- * Compute thinking model activation ratio for text.
86
- * Uses detectThinkingModelMatches() from thinking-models.ts.
87
- * Returns 0-1, rounded to 2 decimal places.
88
- */
89
- function computeThinkingModelActivation(text: string): number {
90
- if (!text || text.trim().length === 0) return 0;
91
- const matches = detectThinkingModelMatches(text);
92
- const totalModels = listThinkingModels().length;
93
- if (totalModels === 0) return 0;
94
- return Math.round((matches.length / totalModels) * 100) / 100;
95
- }
96
-
97
- /**
98
- * Map activation ratio (0-1) to confidence signal.
99
- * Thresholds: high > 0.6, medium 0.3-0.6, low < 0.3
100
- */
101
- function mapConfidenceSignal(activation: number): "high" | "medium" | "low" {
102
- if (activation > 0.6) return "high";
103
- if (activation >= 0.3) return "medium";
104
- return "low";
105
- }
106
-
107
- // ---------------------------------------------------------------------------
108
- // deriveReasoningChain (DERIV-01)
109
- // ---------------------------------------------------------------------------
110
-
111
- /**
112
- * Extract thinking content, uncertainty markers, and confidence signal
113
- * from each assistant turn in the snapshot.
114
- *
115
- * DERIV-01: Returns one DerivedReasoningSignal per assistant turn.
116
- * Empty input returns empty array. Never throws.
117
- */
118
- export function deriveReasoningChain(assistantTurns: NocturnalAssistantTurn[]): DerivedReasoningSignal[] {
119
- if (!assistantTurns || assistantTurns.length === 0) return [];
120
-
121
- return assistantTurns.map(turn => {
122
- const text = turn.sanitizedText ?? '';
123
-
124
- // Extract all <thinking> content blocks (multiple blocks per turn possible)
125
- const thinkingMatches = [...text.matchAll(THINKING_TAG_REGEX)];
126
- const thinkingContent = thinkingMatches.map(m => m[1].trim()).join('\n');
127
-
128
- // Detect uncertainty markers (collect all unique matches across 3 patterns)
129
- const uncertaintyMarkers: string[] = [];
130
- for (const pattern of UNCERTAINTY_PATTERNS) {
131
- // Reset lastIndex to avoid g-flag state issues
132
- pattern.lastIndex = 0;
133
- const matches = text.match(pattern);
134
- if (matches) {
135
- for (const m of matches) {
136
- if (!uncertaintyMarkers.includes(m)) {
137
- uncertaintyMarkers.push(m);
138
- }
139
- }
140
- }
141
- }
142
-
143
- // Confidence signal: only meaningful when <thinking> content exists.
144
- // Without thinking tags we cannot extract a genuine reasoning trace, so
145
- // we fall back to 'low' rather than misleading the downstream pipeline
146
- // with activation derived from non-thinking patterns in the response text.
147
-
148
- let confidenceSignal: "high" | "medium" | "low";
149
- if (thinkingContent.length === 0) {
150
- confidenceSignal = 'low';
151
- } else {
152
- const activation = computeThinkingModelActivation(text);
153
- confidenceSignal = mapConfidenceSignal(activation);
154
- }
155
-
156
- return {
157
- turnIndex: turn.turnIndex,
158
- thinkingContent,
159
- uncertaintyMarkers,
160
- confidenceSignal,
161
- };
162
- });
163
- }
164
-
165
- // ---------------------------------------------------------------------------
166
- // Helpers (Plan 02)
167
- // ---------------------------------------------------------------------------
168
-
169
- /**
170
- * Convert confidence signal to numeric value for delta computation.
171
- * high=1, medium=0.5, low=0
172
- */
173
- function confidenceToNumber(signal: "high" | "medium" | "low"): number {
174
- switch (signal) {
175
- case "high": return 1;
176
- case "medium": return 0.5;
177
- case "low": return 0;
178
- }
179
- }
180
-
181
- // ---------------------------------------------------------------------------
182
- // deriveDecisionPoints (DERIV-02)
183
- // ---------------------------------------------------------------------------
184
-
185
- /**
186
- * Extract before-context and after-reflection for each tool call.
187
- *
188
- * DERIV-02: For each tool call, find the assistant turn immediately before it
189
- * (by createdAt timestamp) and extract last 500 chars as beforeContext.
190
- * On failure outcome, find the next assistant turn and extract first 300 chars
191
- * as afterReflection. Compute confidence delta between before/after.
192
- *
193
- * Empty inputs return empty array. Never throws.
194
- */
195
- export function deriveDecisionPoints(
196
- assistantTurns: NocturnalAssistantTurn[],
197
- toolCalls: NocturnalToolCall[],
198
- ): DerivedDecisionPoint[] {
199
- if (!toolCalls || toolCalls.length === 0) return [];
200
- if (!assistantTurns || assistantTurns.length === 0) {
201
- // Return decision points with empty beforeContext when no assistant turns
202
- return toolCalls.map(tc => ({
203
- toolName: tc.toolName,
204
- outcome: tc.outcome,
205
- beforeContext: '',
206
- }));
207
- }
208
-
209
- // Sort assistant turns by createdAt for binary search
210
- const sortedTurns = [...assistantTurns].sort(
211
- (a, b) => parseTs(a.createdAt) - parseTs(b.createdAt)
212
- );
213
-
214
- // Binary search: find rightmost assistant turn with createdAt < tcTime
215
- const findBeforeTurn = (tcTime: number): NocturnalAssistantTurn | undefined => {
216
-
217
- let lo = 0, hi = sortedTurns.length - 1, result: NocturnalAssistantTurn | undefined;
218
- while (lo <= hi) {
219
- const mid = (lo + hi) >>> 1;
220
- if (parseTs(sortedTurns[mid].createdAt) < tcTime) {
221
- result = sortedTurns[mid];
222
- lo = mid + 1;
223
- } else {
224
- hi = mid - 1;
225
- }
226
- }
227
- return result;
228
- };
229
-
230
- return toolCalls.map(tc => {
231
- const tcTime = parseTs(tc.createdAt);
232
- const beforeTurn = findBeforeTurn(tcTime);
233
-
234
- const beforeContext = beforeTurn
235
- ? beforeTurn.sanitizedText.slice(-500)
236
- : '';
237
-
238
- // On failure, find next assistant turn after tool call
239
-
240
- let afterReflection: string | undefined;
241
-
242
- let confidenceDelta: number | undefined;
243
-
244
- if (tc.outcome === 'failure') {
245
- const afterTurn = sortedTurns.find(
246
- turn => parseTs(turn.createdAt) > tcTime
247
- );
248
- if (afterTurn) {
249
- afterReflection = afterTurn.sanitizedText.slice(0, 300);
250
- }
251
-
252
- // Compute confidence delta if both before and after turns exist
253
- if (beforeTurn && afterTurn) {
254
- const beforeConfidence = confidenceToNumber(
255
- mapConfidenceSignal(computeThinkingModelActivation(beforeTurn.sanitizedText))
256
- );
257
- const afterConfidence = confidenceToNumber(
258
- mapConfidenceSignal(computeThinkingModelActivation(afterTurn.sanitizedText))
259
- );
260
- confidenceDelta = Math.round((afterConfidence - beforeConfidence) * 100) / 100;
261
- }
262
- }
263
-
264
- const result: DerivedDecisionPoint = {
265
- toolName: tc.toolName,
266
- outcome: tc.outcome,
267
- beforeContext,
268
- };
269
- if (afterReflection !== undefined) result.afterReflection = afterReflection;
270
- if (confidenceDelta !== undefined) result.confidenceDelta = confidenceDelta;
271
- return result;
272
- });
273
- }
274
-
275
- // ---------------------------------------------------------------------------
276
- // deriveContextualFactors (DERIV-03)
277
- // ---------------------------------------------------------------------------
278
-
279
- /**
280
- * Compute contextual factors from session snapshot data.
281
- *
282
- * DERIV-03: Four boolean factors indicating the environment
283
- * the agent was operating in. All derived from existing snapshot
284
- * fields -- no schema changes.
285
- *
286
- * Empty/missing data returns all-false defaults. Never throws.
287
- */
288
-
289
- export function deriveContextualFactors(
290
- snapshot: NocturnalSessionSnapshot,
291
- ): DerivedContextualFactors {
292
- const defaults: DerivedContextualFactors = {
293
- fileStructureKnown: false,
294
- errorHistoryPresent: false,
295
- userGuidanceAvailable: false,
296
- timePressure: false,
297
- };
298
-
299
- if (!snapshot) return defaults;
300
-
301
- const { toolCalls = [], userTurns = [] } = snapshot;
302
-
303
- // fileStructureKnown: any Read tool precedes any Write tool in chronological order
304
- let fileStructureKnown = false;
305
- const isReadTool = (name: string) => /^(read|grep|search|find|inspect|look)/i.test(name);
306
- const isWriteTool = (name: string) => /^(edit|write|create|delete|remove|move|rename)/i.test(name);
307
- let hasSeenRead = false;
308
- for (const tc of toolCalls) {
309
- if (isReadTool(tc.toolName)) hasSeenRead = true;
310
- if (isWriteTool(tc.toolName) && hasSeenRead) {
311
- fileStructureKnown = true;
312
- break;
313
- }
314
- }
315
-
316
- // errorHistoryPresent: any tool call with outcome === 'failure'
317
- const errorHistoryPresent = toolCalls.some(tc => tc.outcome === 'failure');
318
-
319
- // userGuidanceAvailable: any user turn with correctionDetected === true
320
- const userGuidanceAvailable = (userTurns || []).some(ut => ut.correctionDetected === true);
321
-
322
- // timePressure: >50% of consecutive tool call pairs have < 2s gap
323
- let timePressure = false;
324
- if (toolCalls.length >= 2) {
325
- const sorted = [...toolCalls].sort(
326
- (a, b) => parseTs(a.createdAt) - parseTs(b.createdAt)
327
- );
328
- let rapidGaps = 0;
329
- for (let i = 0; i < sorted.length - 1; i++) {
330
- const gap = parseTs(sorted[i + 1].createdAt) - parseTs(sorted[i].createdAt);
331
- if (gap < 2000) rapidGaps++;
332
- }
333
- const totalPairs = sorted.length - 1;
334
- timePressure = rapidGaps / totalPairs > 0.5;
335
- }
336
-
337
- return {
338
- fileStructureKnown,
339
- errorHistoryPresent,
340
- userGuidanceAvailable,
341
- timePressure,
342
- };
343
- }