principles-disciple 1.8.1 → 1.8.2

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 (470) hide show
  1. package/ADVANCED_CONFIG_ZH.md +97 -0
  2. package/AGENT_INSTALL.md +173 -0
  3. package/AGENT_INSTALL_EN.md +173 -0
  4. package/INSTALL.md +256 -0
  5. package/SKILL.md +63 -0
  6. package/docs/COMMAND_REFERENCE.md +76 -0
  7. package/docs/COMMAND_REFERENCE_EN.md +79 -0
  8. package/esbuild.config.js +75 -0
  9. package/openclaw.plugin.json +4 -4
  10. package/package.json +11 -13
  11. package/scripts/build-web.mjs +46 -0
  12. package/scripts/install-dependencies.cjs +47 -0
  13. package/scripts/sync-plugin.mjs +802 -0
  14. package/scripts/verify-build.mjs +109 -0
  15. package/src/agents/nocturnal-dreamer.md +152 -0
  16. package/src/agents/nocturnal-philosopher.md +138 -0
  17. package/src/agents/nocturnal-reflector.md +126 -0
  18. package/src/agents/nocturnal-scribe.md +164 -0
  19. package/src/commands/capabilities.ts +85 -0
  20. package/{dist/commands/context.js → src/commands/context.ts} +78 -38
  21. package/src/commands/evolution-status.ts +146 -0
  22. package/src/commands/export.ts +111 -0
  23. package/src/commands/focus.ts +533 -0
  24. package/src/commands/nocturnal-review.ts +311 -0
  25. package/src/commands/nocturnal-rollout.ts +763 -0
  26. package/src/commands/nocturnal-train.ts +1002 -0
  27. package/{dist/commands/pain.js → src/commands/pain.ts} +68 -49
  28. package/src/commands/principle-rollback.ts +27 -0
  29. package/{dist/commands/rollback.js → src/commands/rollback.ts} +44 -12
  30. package/src/commands/samples.ts +60 -0
  31. package/src/commands/strategy.ts +38 -0
  32. package/{dist/commands/thinking-os.js → src/commands/thinking-os.ts} +59 -36
  33. package/src/commands/workflow-debug.ts +128 -0
  34. package/{dist/config/defaults/runtime.js → src/config/defaults/runtime.ts} +12 -5
  35. package/src/config/errors.ts +163 -0
  36. package/{dist/config/index.d.ts → src/config/index.ts} +2 -1
  37. package/src/constants/diagnostician.ts +66 -0
  38. package/src/constants/tools.ts +62 -0
  39. package/src/core/adaptive-thresholds.ts +476 -0
  40. package/{dist/core/config-service.js → src/core/config-service.ts} +7 -4
  41. package/{dist/core/config.js → src/core/config.ts} +158 -46
  42. package/src/core/control-ui-db.ts +435 -0
  43. package/{dist/core/detection-funnel.js → src/core/detection-funnel.ts} +36 -21
  44. package/{dist/core/detection-service.js → src/core/detection-service.ts} +7 -4
  45. package/{dist/core/dictionary-service.js → src/core/dictionary-service.ts} +7 -4
  46. package/{dist/core/dictionary.js → src/core/dictionary.ts} +57 -34
  47. package/src/core/empathy-keyword-matcher.ts +327 -0
  48. package/src/core/empathy-types.ts +218 -0
  49. package/src/core/event-log.ts +544 -0
  50. package/src/core/evolution-engine.ts +612 -0
  51. package/src/core/evolution-logger.ts +353 -0
  52. package/src/core/evolution-migration.ts +77 -0
  53. package/src/core/evolution-reducer.ts +731 -0
  54. package/src/core/evolution-types.ts +456 -0
  55. package/src/core/external-training-contract.ts +527 -0
  56. package/src/core/focus-history.ts +1458 -0
  57. package/src/core/hygiene/tracker.ts +117 -0
  58. package/{dist/core/init.js → src/core/init.ts} +39 -26
  59. package/src/core/local-worker-routing.ts +617 -0
  60. package/{dist/core/migration.js → src/core/migration.ts} +18 -11
  61. package/src/core/model-deployment-registry.ts +722 -0
  62. package/src/core/model-training-registry.ts +813 -0
  63. package/src/core/nocturnal-arbiter.ts +706 -0
  64. package/src/core/nocturnal-candidate-scoring.ts +392 -0
  65. package/src/core/nocturnal-compliance.ts +1075 -0
  66. package/src/core/nocturnal-dataset.ts +668 -0
  67. package/src/core/nocturnal-executability.ts +428 -0
  68. package/src/core/nocturnal-export.ts +390 -0
  69. package/{dist/core/nocturnal-paths.js → src/core/nocturnal-paths.ts} +49 -23
  70. package/src/core/nocturnal-trajectory-extractor.ts +484 -0
  71. package/src/core/nocturnal-trinity.ts +1384 -0
  72. package/src/core/pain.ts +122 -0
  73. package/{dist/core/path-resolver.js → src/core/path-resolver.ts} +157 -36
  74. package/{dist/core/paths.js → src/core/paths.ts} +13 -4
  75. package/src/core/principle-training-state.ts +450 -0
  76. package/src/core/profile.ts +226 -0
  77. package/src/core/promotion-gate.ts +822 -0
  78. package/{dist/core/risk-calculator.js → src/core/risk-calculator.ts} +42 -16
  79. package/{dist/core/session-tracker.js → src/core/session-tracker.ts} +175 -62
  80. package/src/core/shadow-observation-registry.ts +534 -0
  81. package/{dist/core/system-logger.js → src/core/system-logger.ts} +9 -5
  82. package/src/core/thinking-models.ts +217 -0
  83. package/src/core/training-program.ts +630 -0
  84. package/src/core/trajectory-types.ts +243 -0
  85. package/src/core/trajectory.ts +1673 -0
  86. package/{dist/core/workspace-context.js → src/core/workspace-context.ts} +57 -32
  87. package/src/hooks/bash-risk.ts +171 -0
  88. package/src/hooks/edit-verification.ts +295 -0
  89. package/src/hooks/gate-block-helper.ts +160 -0
  90. package/src/hooks/gate.ts +210 -0
  91. package/src/hooks/gfi-gate.ts +177 -0
  92. package/src/hooks/lifecycle.ts +326 -0
  93. package/{dist/hooks/llm.js → src/hooks/llm.ts} +160 -80
  94. package/src/hooks/message-sanitize.ts +45 -0
  95. package/src/hooks/pain.ts +384 -0
  96. package/src/hooks/progressive-trust-gate.ts +174 -0
  97. package/src/hooks/prompt.ts +920 -0
  98. package/src/hooks/subagent.ts +207 -0
  99. package/src/hooks/thinking-checkpoint.ts +73 -0
  100. package/src/hooks/trajectory-collector.ts +290 -0
  101. package/src/http/principles-console-route.ts +716 -0
  102. package/src/i18n/commands.ts +117 -0
  103. package/src/index.ts +694 -0
  104. package/src/service/central-database.ts +831 -0
  105. package/src/service/control-ui-query-service.ts +888 -0
  106. package/src/service/evolution-query-service.ts +405 -0
  107. package/src/service/evolution-worker.ts +1646 -0
  108. package/src/service/health-query-service.ts +836 -0
  109. package/{dist/service/nocturnal-runtime.js → src/service/nocturnal-runtime.ts} +235 -79
  110. package/src/service/nocturnal-service.ts +1015 -0
  111. package/src/service/nocturnal-target-selector.ts +532 -0
  112. package/src/service/phase3-input-filter.ts +237 -0
  113. package/src/service/runtime-summary-service.ts +757 -0
  114. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +513 -0
  115. package/{dist/service/subagent-workflow/empathy-observer-workflow-manager.js → src/service/subagent-workflow/empathy-observer-workflow-manager.ts} +240 -117
  116. package/src/service/subagent-workflow/index.ts +51 -0
  117. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +856 -0
  118. package/src/service/subagent-workflow/runtime-direct-driver.ts +166 -0
  119. package/{dist/service/subagent-workflow/types.d.ts → src/service/subagent-workflow/types.ts} +137 -18
  120. package/src/service/subagent-workflow/workflow-store.ts +328 -0
  121. package/src/service/trajectory-service.ts +15 -0
  122. package/{dist/tools/critique-prompt.js → src/tools/critique-prompt.ts} +25 -8
  123. package/src/tools/deep-reflect.ts +349 -0
  124. package/{dist/tools/model-index.js → src/tools/model-index.ts} +33 -17
  125. package/src/types/event-types.ts +453 -0
  126. package/src/types/hygiene-types.ts +31 -0
  127. package/src/types/principle-tree-schema.ts +244 -0
  128. package/src/types/runtime-summary.ts +49 -0
  129. package/src/types.ts +74 -0
  130. package/src/utils/file-lock.ts +391 -0
  131. package/{dist/utils/glob-match.js → src/utils/glob-match.ts} +21 -20
  132. package/{dist/utils/hashing.js → src/utils/hashing.ts} +6 -4
  133. package/src/utils/io.ts +110 -0
  134. package/{dist/utils/nlp.js → src/utils/nlp.ts} +19 -12
  135. package/{dist/utils/plugin-logger.js → src/utils/plugin-logger.ts} +33 -8
  136. package/src/utils/subagent-probe.ts +94 -0
  137. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
  138. package/templates/pain_settings.json +2 -1
  139. package/tests/README.md +120 -0
  140. package/tests/build-artifacts.test.ts +111 -0
  141. package/tests/commands/evolution-status.test.ts +222 -0
  142. package/tests/commands/evolver.test.ts +22 -0
  143. package/tests/commands/export.test.ts +78 -0
  144. package/tests/commands/nocturnal-review.test.ts +448 -0
  145. package/tests/commands/nocturnal-train.test.ts +97 -0
  146. package/tests/commands/pain.test.ts +108 -0
  147. package/tests/commands/samples.test.ts +65 -0
  148. package/tests/commands/strategy.test.ts +34 -0
  149. package/tests/commands/thinking-os.test.ts +88 -0
  150. package/tests/core/adaptive-thresholds.test.ts +261 -0
  151. package/tests/core/config-service.test.ts +89 -0
  152. package/tests/core/config.test.ts +90 -0
  153. package/tests/core/control-ui-db.test.ts +75 -0
  154. package/tests/core/core-template-guidance.test.ts +21 -0
  155. package/tests/core/detection-funnel.test.ts +63 -0
  156. package/tests/core/detection-service.test.ts +50 -0
  157. package/tests/core/dictionary-service.test.ts +116 -0
  158. package/tests/core/dictionary.test.ts +168 -0
  159. package/tests/core/empathy-keyword-matcher.test.ts +209 -0
  160. package/tests/core/event-log.test.ts +181 -0
  161. package/tests/core/evolution-e2e.test.ts +58 -0
  162. package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
  163. package/tests/core/evolution-engine.test.ts +562 -0
  164. package/tests/core/evolution-logger.test.ts +148 -0
  165. package/tests/core/evolution-migration.test.ts +50 -0
  166. package/tests/core/evolution-paths.test.ts +21 -0
  167. package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
  168. package/tests/core/evolution-reducer.test.ts +180 -0
  169. package/tests/core/evolution-types-loop.test.ts +48 -0
  170. package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
  171. package/tests/core/external-training-contract.test.ts +463 -0
  172. package/tests/core/focus-history.test.ts +682 -0
  173. package/tests/core/init-flatten.test.ts +69 -0
  174. package/tests/core/init-refactor.test.ts +87 -0
  175. package/tests/core/init-v1.3.test.ts +46 -0
  176. package/tests/core/init.test.ts +190 -0
  177. package/tests/core/local-worker-routing.test.ts +757 -0
  178. package/tests/core/migration.test.ts +84 -0
  179. package/tests/core/model-deployment-registry.test.ts +845 -0
  180. package/tests/core/model-training-registry.test.ts +889 -0
  181. package/tests/core/nocturnal-arbiter.test.ts +494 -0
  182. package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
  183. package/tests/core/nocturnal-compliance.test.ts +646 -0
  184. package/tests/core/nocturnal-dataset.test.ts +892 -0
  185. package/tests/core/nocturnal-executability.test.ts +357 -0
  186. package/tests/core/nocturnal-export.test.ts +462 -0
  187. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
  188. package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
  189. package/tests/core/nocturnal-trinity.test.ts +953 -0
  190. package/tests/core/pain.test.ts +33 -0
  191. package/tests/core/path-resolver.test.ts +57 -0
  192. package/tests/core/paths-refactor.test.ts +42 -0
  193. package/tests/core/phase7-rollout-integration.test.ts +477 -0
  194. package/tests/core/principle-training-state.test.ts +712 -0
  195. package/tests/core/profile.test.ts +56 -0
  196. package/tests/core/promotion-gate.test.ts +556 -0
  197. package/tests/core/risk-calculator.test.ts +168 -0
  198. package/tests/core/session-tracker.test.ts +191 -0
  199. package/tests/core/training-program.test.ts +472 -0
  200. package/tests/core/trajectory.test.ts +265 -0
  201. package/tests/core/workspace-context-factory.test.ts +18 -0
  202. package/tests/core/workspace-context.test.ts +134 -0
  203. package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
  204. package/tests/fixtures/production-compatibility.test.ts +147 -0
  205. package/tests/fixtures/production-mock-generator.ts +282 -0
  206. package/tests/hooks/bash-risk-integration.test.ts +137 -0
  207. package/tests/hooks/bash-risk.test.ts +81 -0
  208. package/tests/hooks/edit-verification.test.ts +678 -0
  209. package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
  210. package/tests/hooks/gate-edit-verification.test.ts +435 -0
  211. package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
  212. package/tests/hooks/gate.test.ts +271 -0
  213. package/tests/hooks/gfi-gate-unit.test.ts +422 -0
  214. package/tests/hooks/gfi-gate.test.ts +669 -0
  215. package/tests/hooks/lifecycle.test.ts +248 -0
  216. package/tests/hooks/llm.test.ts +308 -0
  217. package/tests/hooks/message-sanitize.test.ts +36 -0
  218. package/tests/hooks/pain.test.ts +141 -0
  219. package/tests/hooks/progressive-trust-gate.test.ts +277 -0
  220. package/tests/hooks/prompt.test.ts +1411 -0
  221. package/tests/hooks/subagent.test.ts +467 -0
  222. package/tests/hooks/thinking-gate.test.ts +313 -0
  223. package/tests/http/principles-console-route.test.ts +140 -0
  224. package/tests/hygiene-tracker.test.ts +77 -0
  225. package/tests/index.integration.test.ts +179 -0
  226. package/tests/index.shadow-routing.integration.test.ts +140 -0
  227. package/tests/index.test.ts +9 -0
  228. package/tests/integration/empathy-workflow-integration.test.ts +627 -0
  229. package/tests/service/control-ui-query-service.test.ts +121 -0
  230. package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
  231. package/tests/service/evolution-worker.test.ts +585 -0
  232. package/tests/service/nocturnal-runtime.test.ts +470 -0
  233. package/tests/service/nocturnal-service.test.ts +577 -0
  234. package/tests/service/nocturnal-target-selector.test.ts +615 -0
  235. package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
  236. package/tests/service/phase3-input-filter.test.ts +289 -0
  237. package/tests/service/runtime-summary-service.test.ts +919 -0
  238. package/tests/task-compliance.test.ts +166 -0
  239. package/tests/test-utils.ts +48 -0
  240. package/tests/tools/critique-prompt.test.ts +260 -0
  241. package/tests/tools/deep-reflect.test.ts +232 -0
  242. package/tests/tools/model-index.test.ts +246 -0
  243. package/tests/ui/app.test.tsx +114 -0
  244. package/tests/utils/file-lock.test.ts +407 -0
  245. package/tests/utils/hashing.test.ts +32 -0
  246. package/tests/utils/io.test.ts +39 -0
  247. package/tests/utils/nlp.test.ts +53 -0
  248. package/tests/utils/plugin-logger.test.ts +156 -0
  249. package/tsconfig.json +16 -0
  250. package/tsconfig.tsbuildinfo +1 -0
  251. package/ui/src/App.tsx +45 -0
  252. package/ui/src/api.ts +216 -0
  253. package/ui/src/charts.tsx +586 -0
  254. package/ui/src/components/ErrorState.tsx +6 -0
  255. package/ui/src/components/Loading.tsx +13 -0
  256. package/ui/src/components/ProtectedRoute.tsx +12 -0
  257. package/ui/src/components/Shell.tsx +91 -0
  258. package/ui/src/components/WorkspaceConfig.tsx +146 -0
  259. package/ui/src/components/index.ts +5 -0
  260. package/ui/src/context/auth.tsx +80 -0
  261. package/ui/src/context/theme.tsx +66 -0
  262. package/ui/src/hooks/useAutoRefresh.ts +39 -0
  263. package/ui/src/i18n/ui.ts +363 -0
  264. package/ui/src/main.tsx +16 -0
  265. package/ui/src/pages/EvolutionPage.tsx +352 -0
  266. package/ui/src/pages/FeedbackPage.tsx +140 -0
  267. package/ui/src/pages/GateMonitorPage.tsx +136 -0
  268. package/ui/src/pages/LoginPage.tsx +88 -0
  269. package/ui/src/pages/OverviewPage.tsx +238 -0
  270. package/ui/src/pages/SamplesPage.tsx +174 -0
  271. package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
  272. package/ui/src/styles.css +1661 -0
  273. package/ui/src/types.ts +368 -0
  274. package/ui/src/utils/format.ts +15 -0
  275. package/vitest.config.ts +23 -0
  276. package/dist/commands/capabilities.d.ts +0 -3
  277. package/dist/commands/capabilities.js +0 -73
  278. package/dist/commands/context.d.ts +0 -5
  279. package/dist/commands/evolution-status.d.ts +0 -4
  280. package/dist/commands/evolution-status.js +0 -117
  281. package/dist/commands/evolver.d.ts +0 -9
  282. package/dist/commands/evolver.js +0 -26
  283. package/dist/commands/export.d.ts +0 -2
  284. package/dist/commands/export.js +0 -98
  285. package/dist/commands/focus.d.ts +0 -14
  286. package/dist/commands/focus.js +0 -457
  287. package/dist/commands/nocturnal-review.d.ts +0 -24
  288. package/dist/commands/nocturnal-review.js +0 -265
  289. package/dist/commands/nocturnal-rollout.d.ts +0 -27
  290. package/dist/commands/nocturnal-rollout.js +0 -671
  291. package/dist/commands/nocturnal-train.d.ts +0 -25
  292. package/dist/commands/nocturnal-train.js +0 -919
  293. package/dist/commands/pain.d.ts +0 -5
  294. package/dist/commands/principle-rollback.d.ts +0 -4
  295. package/dist/commands/principle-rollback.js +0 -22
  296. package/dist/commands/rollback.d.ts +0 -19
  297. package/dist/commands/samples.d.ts +0 -2
  298. package/dist/commands/samples.js +0 -55
  299. package/dist/commands/strategy.d.ts +0 -3
  300. package/dist/commands/strategy.js +0 -29
  301. package/dist/commands/thinking-os.d.ts +0 -2
  302. package/dist/config/defaults/runtime.d.ts +0 -40
  303. package/dist/config/errors.d.ts +0 -84
  304. package/dist/config/errors.js +0 -94
  305. package/dist/config/index.js +0 -7
  306. package/dist/constants/diagnostician.d.ts +0 -12
  307. package/dist/constants/diagnostician.js +0 -56
  308. package/dist/constants/tools.d.ts +0 -17
  309. package/dist/constants/tools.js +0 -54
  310. package/dist/core/adaptive-thresholds.d.ts +0 -186
  311. package/dist/core/adaptive-thresholds.js +0 -300
  312. package/dist/core/config-service.d.ts +0 -15
  313. package/dist/core/config.d.ts +0 -129
  314. package/dist/core/control-ui-db.d.ts +0 -95
  315. package/dist/core/control-ui-db.js +0 -292
  316. package/dist/core/detection-funnel.d.ts +0 -33
  317. package/dist/core/detection-service.d.ts +0 -15
  318. package/dist/core/dictionary-service.d.ts +0 -15
  319. package/dist/core/dictionary.d.ts +0 -38
  320. package/dist/core/event-log.d.ts +0 -82
  321. package/dist/core/event-log.js +0 -463
  322. package/dist/core/evolution-engine.d.ts +0 -118
  323. package/dist/core/evolution-engine.js +0 -464
  324. package/dist/core/evolution-logger.d.ts +0 -137
  325. package/dist/core/evolution-logger.js +0 -256
  326. package/dist/core/evolution-migration.d.ts +0 -5
  327. package/dist/core/evolution-migration.js +0 -65
  328. package/dist/core/evolution-reducer.d.ts +0 -98
  329. package/dist/core/evolution-reducer.js +0 -465
  330. package/dist/core/evolution-types.d.ts +0 -287
  331. package/dist/core/evolution-types.js +0 -78
  332. package/dist/core/external-training-contract.d.ts +0 -276
  333. package/dist/core/external-training-contract.js +0 -269
  334. package/dist/core/focus-history.d.ts +0 -210
  335. package/dist/core/focus-history.js +0 -1185
  336. package/dist/core/hygiene/tracker.d.ts +0 -22
  337. package/dist/core/hygiene/tracker.js +0 -106
  338. package/dist/core/init.d.ts +0 -12
  339. package/dist/core/local-worker-routing.d.ts +0 -175
  340. package/dist/core/local-worker-routing.js +0 -525
  341. package/dist/core/migration.d.ts +0 -6
  342. package/dist/core/model-deployment-registry.d.ts +0 -218
  343. package/dist/core/model-deployment-registry.js +0 -503
  344. package/dist/core/model-training-registry.d.ts +0 -295
  345. package/dist/core/model-training-registry.js +0 -475
  346. package/dist/core/nocturnal-arbiter.d.ts +0 -159
  347. package/dist/core/nocturnal-arbiter.js +0 -534
  348. package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
  349. package/dist/core/nocturnal-candidate-scoring.js +0 -266
  350. package/dist/core/nocturnal-compliance.d.ts +0 -175
  351. package/dist/core/nocturnal-compliance.js +0 -824
  352. package/dist/core/nocturnal-dataset.d.ts +0 -224
  353. package/dist/core/nocturnal-dataset.js +0 -443
  354. package/dist/core/nocturnal-executability.d.ts +0 -85
  355. package/dist/core/nocturnal-executability.js +0 -331
  356. package/dist/core/nocturnal-export.d.ts +0 -124
  357. package/dist/core/nocturnal-export.js +0 -275
  358. package/dist/core/nocturnal-paths.d.ts +0 -124
  359. package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
  360. package/dist/core/nocturnal-trajectory-extractor.js +0 -307
  361. package/dist/core/nocturnal-trinity.d.ts +0 -311
  362. package/dist/core/nocturnal-trinity.js +0 -880
  363. package/dist/core/pain.d.ts +0 -4
  364. package/dist/core/pain.js +0 -70
  365. package/dist/core/path-resolver.d.ts +0 -46
  366. package/dist/core/paths.d.ts +0 -65
  367. package/dist/core/principle-training-state.d.ts +0 -121
  368. package/dist/core/principle-training-state.js +0 -321
  369. package/dist/core/profile.d.ts +0 -62
  370. package/dist/core/profile.js +0 -210
  371. package/dist/core/promotion-gate.d.ts +0 -238
  372. package/dist/core/promotion-gate.js +0 -529
  373. package/dist/core/risk-calculator.d.ts +0 -22
  374. package/dist/core/session-tracker.d.ts +0 -101
  375. package/dist/core/shadow-observation-registry.d.ts +0 -217
  376. package/dist/core/shadow-observation-registry.js +0 -308
  377. package/dist/core/system-logger.d.ts +0 -8
  378. package/dist/core/thinking-models.d.ts +0 -38
  379. package/dist/core/thinking-models.js +0 -170
  380. package/dist/core/training-program.d.ts +0 -233
  381. package/dist/core/training-program.js +0 -433
  382. package/dist/core/trajectory.d.ts +0 -411
  383. package/dist/core/trajectory.js +0 -1307
  384. package/dist/core/workspace-context.d.ts +0 -71
  385. package/dist/hooks/bash-risk.d.ts +0 -57
  386. package/dist/hooks/bash-risk.js +0 -137
  387. package/dist/hooks/edit-verification.d.ts +0 -62
  388. package/dist/hooks/edit-verification.js +0 -256
  389. package/dist/hooks/gate-block-helper.d.ts +0 -44
  390. package/dist/hooks/gate-block-helper.js +0 -119
  391. package/dist/hooks/gate.d.ts +0 -24
  392. package/dist/hooks/gate.js +0 -173
  393. package/dist/hooks/gfi-gate.d.ts +0 -40
  394. package/dist/hooks/gfi-gate.js +0 -113
  395. package/dist/hooks/lifecycle.d.ts +0 -5
  396. package/dist/hooks/lifecycle.js +0 -284
  397. package/dist/hooks/llm.d.ts +0 -13
  398. package/dist/hooks/message-sanitize.d.ts +0 -3
  399. package/dist/hooks/message-sanitize.js +0 -37
  400. package/dist/hooks/pain.d.ts +0 -5
  401. package/dist/hooks/pain.js +0 -301
  402. package/dist/hooks/progressive-trust-gate.d.ts +0 -52
  403. package/dist/hooks/progressive-trust-gate.js +0 -134
  404. package/dist/hooks/prompt.d.ts +0 -49
  405. package/dist/hooks/prompt.js +0 -905
  406. package/dist/hooks/subagent.d.ts +0 -10
  407. package/dist/hooks/subagent.js +0 -387
  408. package/dist/hooks/thinking-checkpoint.d.ts +0 -37
  409. package/dist/hooks/thinking-checkpoint.js +0 -51
  410. package/dist/hooks/trajectory-collector.d.ts +0 -32
  411. package/dist/hooks/trajectory-collector.js +0 -256
  412. package/dist/http/principles-console-route.d.ts +0 -9
  413. package/dist/http/principles-console-route.js +0 -681
  414. package/dist/i18n/commands.d.ts +0 -26
  415. package/dist/i18n/commands.js +0 -116
  416. package/dist/index.d.ts +0 -7
  417. package/dist/index.js +0 -581
  418. package/dist/service/central-database.d.ts +0 -104
  419. package/dist/service/central-database.js +0 -649
  420. package/dist/service/control-ui-query-service.d.ts +0 -221
  421. package/dist/service/control-ui-query-service.js +0 -543
  422. package/dist/service/empathy-observer-manager.d.ts +0 -88
  423. package/dist/service/empathy-observer-manager.js +0 -414
  424. package/dist/service/evolution-query-service.d.ts +0 -155
  425. package/dist/service/evolution-query-service.js +0 -258
  426. package/dist/service/evolution-worker.d.ts +0 -101
  427. package/dist/service/evolution-worker.js +0 -975
  428. package/dist/service/health-query-service.d.ts +0 -170
  429. package/dist/service/health-query-service.js +0 -662
  430. package/dist/service/nocturnal-runtime.d.ts +0 -183
  431. package/dist/service/nocturnal-service.d.ts +0 -163
  432. package/dist/service/nocturnal-service.js +0 -787
  433. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  434. package/dist/service/nocturnal-target-selector.js +0 -315
  435. package/dist/service/phase3-input-filter.d.ts +0 -73
  436. package/dist/service/phase3-input-filter.js +0 -172
  437. package/dist/service/runtime-summary-service.d.ts +0 -122
  438. package/dist/service/runtime-summary-service.js +0 -485
  439. package/dist/service/subagent-workflow/empathy-observer-workflow-manager.d.ts +0 -48
  440. package/dist/service/subagent-workflow/index.d.ts +0 -4
  441. package/dist/service/subagent-workflow/index.js +0 -3
  442. package/dist/service/subagent-workflow/runtime-direct-driver.d.ts +0 -77
  443. package/dist/service/subagent-workflow/runtime-direct-driver.js +0 -75
  444. package/dist/service/subagent-workflow/types.js +0 -11
  445. package/dist/service/subagent-workflow/workflow-store.d.ts +0 -26
  446. package/dist/service/subagent-workflow/workflow-store.js +0 -165
  447. package/dist/service/trajectory-service.d.ts +0 -2
  448. package/dist/service/trajectory-service.js +0 -15
  449. package/dist/tools/critique-prompt.d.ts +0 -14
  450. package/dist/tools/deep-reflect.d.ts +0 -39
  451. package/dist/tools/deep-reflect.js +0 -350
  452. package/dist/tools/model-index.d.ts +0 -9
  453. package/dist/types/event-types.d.ts +0 -306
  454. package/dist/types/event-types.js +0 -106
  455. package/dist/types/hygiene-types.d.ts +0 -20
  456. package/dist/types/hygiene-types.js +0 -12
  457. package/dist/types/runtime-summary.d.ts +0 -47
  458. package/dist/types/runtime-summary.js +0 -1
  459. package/dist/types.d.ts +0 -50
  460. package/dist/types.js +0 -22
  461. package/dist/utils/file-lock.d.ts +0 -71
  462. package/dist/utils/file-lock.js +0 -309
  463. package/dist/utils/glob-match.d.ts +0 -28
  464. package/dist/utils/hashing.d.ts +0 -9
  465. package/dist/utils/io.d.ts +0 -6
  466. package/dist/utils/io.js +0 -106
  467. package/dist/utils/nlp.d.ts +0 -9
  468. package/dist/utils/plugin-logger.d.ts +0 -39
  469. package/dist/utils/subagent-probe.d.ts +0 -34
  470. package/dist/utils/subagent-probe.js +0 -81
@@ -0,0 +1,390 @@
1
+ /**
2
+ * Nocturnal ORPO Export — Approved Dataset to Decision-Point JSONL
3
+ * =================================================================
4
+ *
5
+ * PURPOSE: Export approved nocturnal samples as ORPO-formatted decision-point
6
+ * training JSONL, strictly separated from legacy correction export.
7
+ *
8
+ * ARCHITECTURE:
9
+ * - Export output: .state/exports/orpo/{exportId}.jsonl
10
+ * - Export manifest: .state/exports/orpo/{exportId}-manifest.json
11
+ * - Legacy corrections: untouched, separate path
12
+ *
13
+ * ORPO FORMAT (each line):
14
+ * {
15
+ * sampleFingerprint: string,
16
+ * artifactId: string,
17
+ * sessionId: string,
18
+ * principleId: string,
19
+ * targetModelFamily: string,
20
+ * prompt: string, // badDecision (the wrong choice)
21
+ * chosen: string, // betterDecision (the right choice)
22
+ * rejected: string, // badDecision (for ORPO)
23
+ * rationale: string,
24
+ * datasetMetadata: {
25
+ * sampleFingerprint: string,
26
+ * artifactPath: string,
27
+ * createdAt: string,
28
+ * exportedAt: string,
29
+ * exportId: string,
30
+ * datasetFingerprint: string
31
+ * }
32
+ * }
33
+ *
34
+ * EXPORT GATING (fail-closed):
35
+ * - reviewStatus === 'approved_for_training'
36
+ * - targetModelFamily matches requested target (or any if not specified)
37
+ * - Lineage fields complete (sampleFingerprint, artifactId, sessionId, principleId)
38
+ * - Source artifact file exists and is approved
39
+ *
40
+ * DESIGN CONSTRAINTS:
41
+ * - No trainer invocation
42
+ * - No automatic training
43
+ * - No checkpoint deploy
44
+ * - Export is read-only from dataset perspective
45
+ */
46
+
47
+ import * as fs from 'fs';
48
+ import * as path from 'path';
49
+ import * as crypto from 'crypto';
50
+ import {
51
+ listDatasetRecords,
52
+ readDatasetArtifact,
53
+ type NocturnalDatasetRecord,
54
+ } from './nocturnal-dataset.js';
55
+ import { NocturnalPathResolver } from './nocturnal-paths.js';
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Types
59
+ // ---------------------------------------------------------------------------
60
+
61
+ /**
62
+ * A single ORPO training sample in JSONL format.
63
+ */
64
+ export interface ORPOSample {
65
+ sampleFingerprint: string;
66
+ artifactId: string;
67
+ sessionId: string;
68
+ principleId: string;
69
+ targetModelFamily: string;
70
+ /** The suboptimal decision (what the agent did wrong) */
71
+ prompt: string;
72
+ /** The correct decision (what should have been done) */
73
+ chosen: string;
74
+ /** The suboptimal decision (same as prompt, for ORPO structure) */
75
+ rejected: string;
76
+ rationale: string;
77
+ datasetMetadata: {
78
+ sampleFingerprint: string;
79
+ artifactPath: string;
80
+ createdAt: string;
81
+ exportedAt: string;
82
+ exportId: string;
83
+ datasetFingerprint: string;
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Export manifest containing metadata about the entire export.
89
+ */
90
+ export interface ORPOExportManifest {
91
+ exportId: string;
92
+ createdAt: string;
93
+ sampleCount: number;
94
+ targetModelFamily: string;
95
+ /** SHA-256 of all sample fingerprints, sorted — for reproducibility */
96
+ datasetFingerprint: string;
97
+ exportPath: string;
98
+ manifestPath: string;
99
+ samples: Array<{
100
+ sampleFingerprint: string;
101
+ artifactId: string;
102
+ sessionId: string;
103
+ principleId: string;
104
+ }>;
105
+ }
106
+
107
+ /**
108
+ * Result of an export operation.
109
+ */
110
+ export interface ExportResult {
111
+ success: boolean;
112
+ manifest?: ORPOExportManifest;
113
+ error?: string;
114
+ emptyReason?: 'no_approved_samples' | 'family_mismatch' | 'all_samples_missing_artifacts';
115
+ }
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // Dataset Fingerprint (for reproducibility)
119
+ // ---------------------------------------------------------------------------
120
+
121
+ /**
122
+ * Compute a deterministic dataset fingerprint from a sorted list of sample fingerprints.
123
+ * This allows reproducible exports — same dataset always produces same fingerprint.
124
+ */
125
+ function computeDatasetFingerprint(sampleFingerprints: string[]): string {
126
+ const sorted = [...sampleFingerprints].sort();
127
+ const combined = sorted.join('|');
128
+ return crypto.createHash('sha256').update(combined, 'utf8').digest('hex');
129
+ }
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // Individual Sample Serialization
133
+ // ---------------------------------------------------------------------------
134
+
135
+ /**
136
+ * Serialize a single dataset record + artifact to ORPO JSONL line.
137
+ * Caller guarantees record.targetModelFamily is non-null.
138
+ */
139
+ function serializeORPOSample(
140
+ record: NocturnalDatasetRecord,
141
+ artifact: ReturnType<typeof readDatasetArtifact>,
142
+ exportId: string,
143
+ datasetFingerprint: string
144
+ ): ORPOSample {
145
+ const now = new Date().toISOString();
146
+
147
+ return {
148
+ sampleFingerprint: record.sampleFingerprint,
149
+ artifactId: record.artifactId,
150
+ sessionId: record.sessionId,
151
+ principleId: record.principleId,
152
+ targetModelFamily: record.targetModelFamily as string, // validated non-null by caller
153
+ // For ORPO: prompt = badDecision, chosen = betterDecision, rejected = badDecision
154
+ // This teaches the model to prefer betterDecision over badDecision
155
+ prompt: artifact.badDecision,
156
+ chosen: artifact.betterDecision,
157
+ rejected: artifact.badDecision,
158
+ rationale: artifact.rationale,
159
+ datasetMetadata: {
160
+ sampleFingerprint: record.sampleFingerprint,
161
+ artifactPath: record.artifactPath,
162
+ createdAt: record.createdAt,
163
+ exportedAt: now,
164
+ exportId,
165
+ datasetFingerprint,
166
+ },
167
+ };
168
+ }
169
+
170
+ // ---------------------------------------------------------------------------
171
+ // Core Export Function
172
+ // ---------------------------------------------------------------------------
173
+
174
+ /**
175
+ * Export approved nocturnal samples as ORPO decision-point JSONL.
176
+ *
177
+ * @param workspaceDir - Workspace directory
178
+ * @param targetModelFamily - Specific model family to export, or undefined for all
179
+ * @param options - Additional export options
180
+ * @returns ExportResult
181
+ */
182
+ export function exportORPOSamples(
183
+ workspaceDir: string,
184
+ targetModelFamily?: string | null,
185
+ _options: Record<string, never> = {}
186
+ ): ExportResult {
187
+ const exportId = crypto.randomUUID();
188
+ const now = new Date().toISOString();
189
+
190
+ // Step 1: Collect eligible records
191
+ // Use listDatasetRecords directly to have full control over the family filter
192
+ // (listExportReadyRecords uses ?? which maps null→undefined, losing the null distinction)
193
+ const allApprovedRecords = listDatasetRecords(workspaceDir, {
194
+ reviewStatus: 'approved_for_training',
195
+ });
196
+
197
+ let eligibleRecords: typeof allApprovedRecords;
198
+
199
+ if (targetModelFamily !== undefined && targetModelFamily !== null) {
200
+ // Specific family: check if ANY records (regardless of status) have this family
201
+ const allRecords = listDatasetRecords(workspaceDir);
202
+ const hasAnyWithFamily = allRecords.some((r) => r.targetModelFamily === targetModelFamily);
203
+ if (!hasAnyWithFamily) {
204
+ // Family doesn't exist in any record
205
+ return {
206
+ success: false,
207
+ error: 'No samples found for the requested target model family',
208
+ emptyReason: 'family_mismatch',
209
+ };
210
+ }
211
+ // Family exists but none are approved
212
+ eligibleRecords = allApprovedRecords.filter((r) => r.targetModelFamily === targetModelFamily);
213
+ } else {
214
+ // All families
215
+ eligibleRecords = allApprovedRecords;
216
+ }
217
+
218
+ // Step 2: Validate we have records
219
+ if (eligibleRecords.length === 0) {
220
+ return {
221
+ success: false,
222
+ error: 'No approved samples found for export',
223
+ emptyReason: 'no_approved_samples',
224
+ };
225
+ }
226
+
227
+ // Step 3: Verify lineage completeness and read artifacts
228
+ const orpoSamples: ORPOSample[] = [];
229
+ const failedFingerprints: string[] = [];
230
+
231
+ for (const record of eligibleRecords) {
232
+ // Enforce targetModelFamily binding — samples without a family cannot enter training
233
+ if (record.targetModelFamily === null) {
234
+ failedFingerprints.push(record.sampleFingerprint);
235
+ continue;
236
+ }
237
+
238
+ // Verify lineage completeness
239
+ if (!record.sampleFingerprint || !record.artifactId || !record.sessionId || !record.principleId) {
240
+ failedFingerprints.push(record.sampleFingerprint);
241
+ continue;
242
+ }
243
+
244
+ // Read artifact (throws on error — distinguishes read failure from missing artifact)
245
+ let artifact;
246
+ try {
247
+ artifact = readDatasetArtifact(workspaceDir, record.sampleFingerprint);
248
+ } catch {
249
+ failedFingerprints.push(record.sampleFingerprint);
250
+ continue;
251
+ }
252
+
253
+ // Serialize
254
+ orpoSamples.push(serializeORPOSample(record, artifact, exportId, ''));
255
+ }
256
+
257
+ // Step 4: Fail if all samples failed validation
258
+ if (orpoSamples.length === 0) {
259
+ return {
260
+ success: false,
261
+ error: `All ${eligibleRecords.length} eligible samples failed validation (missing artifacts or lineage)`,
262
+ emptyReason: 'all_samples_missing_artifacts',
263
+ };
264
+ }
265
+
266
+ // Step 5: Compute dataset fingerprint for manifest
267
+ const datasetFingerprint = computeDatasetFingerprint(
268
+ orpoSamples.map((s) => s.sampleFingerprint)
269
+ );
270
+
271
+ // Step 6: Fill in dataset fingerprint in all samples
272
+ for (const sample of orpoSamples) {
273
+ sample.datasetMetadata.datasetFingerprint = datasetFingerprint;
274
+ }
275
+
276
+ // Step 7: Write JSONL file
277
+ const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
278
+ const jsonlPath = path.join(exportsDir, `${exportId}.jsonl`);
279
+ const lines = orpoSamples.map((s) => JSON.stringify(s)).join('\n') + '\n';
280
+ fs.writeFileSync(jsonlPath, lines, 'utf-8');
281
+
282
+ // Step 8: Write manifest
283
+ const manifest: ORPOExportManifest = {
284
+ exportId,
285
+ createdAt: now,
286
+ sampleCount: orpoSamples.length,
287
+ targetModelFamily: targetModelFamily ?? 'all',
288
+ datasetFingerprint,
289
+ exportPath: jsonlPath,
290
+ manifestPath: path.join(exportsDir, `${exportId}-manifest.json`),
291
+ samples: orpoSamples.map((s) => ({
292
+ sampleFingerprint: s.sampleFingerprint,
293
+ artifactId: s.artifactId,
294
+ sessionId: s.sessionId,
295
+ principleId: s.principleId,
296
+ })),
297
+ };
298
+
299
+ fs.writeFileSync(manifest.manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
300
+
301
+ return {
302
+ success: true,
303
+ manifest,
304
+ };
305
+ }
306
+
307
+ /**
308
+ * Verify an existing export by re-computing its dataset fingerprint.
309
+ * Returns true if the export is intact and reproducible.
310
+ */
311
+ export function verifyExportIntegrity(
312
+ workspaceDir: string,
313
+ exportId: string
314
+ ): { valid: boolean; computedFingerprint: string; manifestFingerprint: string } | null {
315
+ const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
316
+ const manifestPath = path.join(exportsDir, `${exportId}-manifest.json`);
317
+
318
+ if (!fs.existsSync(manifestPath)) {
319
+ return null;
320
+ }
321
+
322
+ try {
323
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as ORPOExportManifest;
324
+ const computedFingerprint = computeDatasetFingerprint(
325
+ manifest.samples.map((s) => s.sampleFingerprint)
326
+ );
327
+
328
+ return {
329
+ valid: computedFingerprint === manifest.datasetFingerprint,
330
+ computedFingerprint,
331
+ manifestFingerprint: manifest.datasetFingerprint,
332
+ };
333
+ } catch {
334
+ return null;
335
+ }
336
+ }
337
+
338
+ /**
339
+ * List all exports in the exports directory.
340
+ */
341
+ export function listExports(workspaceDir: string): ORPOExportManifest[] {
342
+ const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
343
+ if (!fs.existsSync(exportsDir)) {
344
+ return [];
345
+ }
346
+
347
+ try {
348
+ const files = fs.readdirSync(exportsDir);
349
+ const manifests: ORPOExportManifest[] = [];
350
+
351
+ for (const file of files) {
352
+ if (!file.endsWith('-manifest.json')) continue;
353
+ try {
354
+ const manifest = JSON.parse(
355
+ fs.readFileSync(path.join(exportsDir, file), 'utf-8')
356
+ ) as ORPOExportManifest;
357
+ manifests.push(manifest);
358
+ } catch {
359
+ // Skip malformed manifest
360
+ }
361
+ }
362
+
363
+ return manifests.sort(
364
+ (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
365
+ );
366
+ } catch {
367
+ return [];
368
+ }
369
+ }
370
+
371
+ /**
372
+ * Read an export manifest by ID.
373
+ */
374
+ export function getExportManifest(
375
+ workspaceDir: string,
376
+ exportId: string
377
+ ): ORPOExportManifest | null {
378
+ const exportsDir = NocturnalPathResolver.exportsDir(workspaceDir);
379
+ const manifestPath = path.join(exportsDir, `${exportId}-manifest.json`);
380
+
381
+ if (!fs.existsSync(manifestPath)) {
382
+ return null;
383
+ }
384
+
385
+ try {
386
+ return JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as ORPOExportManifest;
387
+ } catch {
388
+ return null;
389
+ }
390
+ }
@@ -24,14 +24,18 @@
24
24
  * import { NocturnalPathResolver, NOCTURNAL_DIRS, NOCTURNAL_FILES } from './nocturnal-paths.js';
25
25
  * const sampleDir = NocturnalPathResolver.samplesDir(workspaceDir);
26
26
  */
27
+
27
28
  import * as path from 'path';
28
29
  import * as fs from 'fs';
30
+
29
31
  // ---------------------------------------------------------------------------
30
32
  // Directory Constants
31
33
  // ---------------------------------------------------------------------------
34
+
32
35
  export const NOCTURNAL_DIRS = {
33
36
  /** Root directory for all nocturnal reflection artifacts */
34
37
  ROOT: '.state/nocturnal',
38
+
35
39
  /**
36
40
  * Structured decision-point samples from nocturnal reflection.
37
41
  * Each file is a JSON artifact containing:
@@ -41,28 +45,33 @@ export const NOCTURNAL_DIRS = {
41
45
  * - arbiter approval status
42
46
  */
43
47
  SAMPLES: '.state/nocturnal/samples',
48
+
44
49
  /**
45
50
  * Short-term operator-facing reflection memory.
46
51
  * Written by nocturnal service, NOT injected into prompts directly.
47
52
  * Consumed by operator on next session start.
48
53
  */
49
54
  MEMORY: '.state/nocturnal/memory',
55
+
50
56
  /**
51
57
  * Nocturnal runtime bookkeeping (cooldowns, quotas).
52
58
  * NOTE: nocturnal-runtime.json is written to stateDir directly
53
59
  * (not under NOCTURNAL_DIRS.ROOT) for simpler migration.
54
60
  */
55
61
  // RUNTIME is in {stateDir}/nocturnal-runtime.json (not here)
62
+
56
63
  /**
57
64
  * Approved training pairs ready for export.
58
65
  * Immutable once written — never modified in place.
59
66
  * Consumed by external trainer (not the plugin).
60
67
  */
61
68
  EXPORTS: '.state/exports/orpo',
62
- };
69
+ } as const;
70
+
63
71
  // ---------------------------------------------------------------------------
64
72
  // File Path Constants (within their respective directories)
65
73
  // ---------------------------------------------------------------------------
74
+
66
75
  export const NOCTURNAL_FILES = {
67
76
  /**
68
77
  * Arbiter review queue for pending samples.
@@ -70,20 +79,23 @@ export const NOCTURNAL_FILES = {
70
79
  * Format: JSON array of sample refs pending approval.
71
80
  */
72
81
  REVIEW_QUEUE: '.state/nocturnal/review-queue.json',
82
+
73
83
  /**
74
84
  * Lineage metadata for all samples.
75
85
  * Written alongside each sample file for traceability.
76
86
  */
77
87
  LINEAGE_INDEX: '.state/nocturnal/samples/lineage-index.json',
78
- };
88
+ } as const;
89
+
79
90
  // ---------------------------------------------------------------------------
80
91
  // Path Resolution
81
92
  // ---------------------------------------------------------------------------
93
+
82
94
  /**
83
95
  * Cross-platform path join for workspace-relative paths.
84
96
  * Handles Windows vs POSIX differences.
85
97
  */
86
- function joinWorkspacePath(workspaceDir, relativePath) {
98
+ function joinWorkspacePath(workspaceDir: string, relativePath: string): string {
87
99
  const normalized = relativePath.replace(/\\/g, '/');
88
100
  if (/^[A-Za-z]:/.test(workspaceDir)) {
89
101
  // Windows
@@ -91,77 +103,89 @@ function joinWorkspacePath(workspaceDir, relativePath) {
91
103
  }
92
104
  return path.posix.join(workspaceDir, ...normalized.split('/'));
93
105
  }
106
+
94
107
  /**
95
108
  * Resolves a nocturnal directory path within a workspace.
96
109
  */
97
- export function resolveNocturnalDir(workspaceDir, dirKey) {
110
+ export function resolveNocturnalDir(workspaceDir: string, dirKey: keyof typeof NOCTURNAL_DIRS): string {
98
111
  return joinWorkspacePath(workspaceDir, NOCTURNAL_DIRS[dirKey]);
99
112
  }
113
+
100
114
  /**
101
115
  * Resolves a nocturnal file path within a workspace.
102
116
  */
103
- export function resolveNocturnalFile(workspaceDir, fileKey) {
117
+ export function resolveNocturnalFile(workspaceDir: string, fileKey: keyof typeof NOCTURNAL_FILES): string {
104
118
  return joinWorkspacePath(workspaceDir, NOCTURNAL_FILES[fileKey]);
105
119
  }
120
+
106
121
  // ---------------------------------------------------------------------------
107
122
  // NocturnalPathResolver — Fluent API for common resolutions
108
123
  // ---------------------------------------------------------------------------
124
+
109
125
  export const NocturnalPathResolver = {
110
126
  /**
111
127
  * Returns the samples directory path.
112
128
  * Creates the directory if it does not exist.
113
129
  */
114
- samplesDir(workspaceDir) {
130
+ samplesDir(workspaceDir: string): string {
115
131
  const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
116
132
  if (!fs.existsSync(dir)) {
117
133
  fs.mkdirSync(dir, { recursive: true });
118
134
  }
119
135
  return dir;
120
136
  },
137
+
121
138
  /**
122
139
  * Returns the memory directory path.
123
140
  * Creates the directory if it does not exist.
124
141
  */
125
- memoryDir(workspaceDir) {
142
+ memoryDir(workspaceDir: string): string {
126
143
  const dir = resolveNocturnalDir(workspaceDir, 'MEMORY');
127
144
  if (!fs.existsSync(dir)) {
128
145
  fs.mkdirSync(dir, { recursive: true });
129
146
  }
130
147
  return dir;
131
148
  },
149
+
132
150
  /**
133
151
  * Returns the exports directory path.
134
152
  * Creates the directory if it does not exist.
135
153
  */
136
- exportsDir(workspaceDir) {
154
+ exportsDir(workspaceDir: string): string {
137
155
  const dir = resolveNocturnalDir(workspaceDir, 'EXPORTS');
138
156
  if (!fs.existsSync(dir)) {
139
157
  fs.mkdirSync(dir, { recursive: true });
140
158
  }
141
159
  return dir;
142
160
  },
161
+
143
162
  /**
144
163
  * Returns the path for a named sample file.
145
164
  * File is NOT created — caller decides when to write.
146
165
  */
147
- samplePath(workspaceDir, sampleId) {
166
+ samplePath(workspaceDir: string, sampleId: string): string {
148
167
  const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
149
168
  // Sanitize sampleId for filesystem
150
169
  const safeId = sampleId.replace(/[/\\:]/g, '_');
151
170
  return path.join(dir, `${safeId}.json`);
152
171
  },
172
+
153
173
  /**
154
174
  * Returns the path for nocturnal reflection memory.
155
175
  * This is the operator-facing summary written after each nocturnal run.
156
176
  */
157
- reflectionMemoryPath(workspaceDir) {
158
- return path.join(resolveNocturnalDir(workspaceDir, 'MEMORY'), 'reflection-memory.md');
177
+ reflectionMemoryPath(workspaceDir: string): string {
178
+ return path.join(
179
+ resolveNocturnalDir(workspaceDir, 'MEMORY'),
180
+ 'reflection-memory.md'
181
+ );
159
182
  },
183
+
160
184
  /**
161
185
  * Lists all sample files in the samples directory.
162
186
  * Returns absolute paths sorted by modification time (newest first).
163
187
  */
164
- listSamples(workspaceDir) {
188
+ listSamples(workspaceDir: string): string[] {
165
189
  const dir = resolveNocturnalDir(workspaceDir, 'SAMPLES');
166
190
  if (!fs.existsSync(dir)) {
167
191
  return [];
@@ -171,42 +195,44 @@ export const NocturnalPathResolver = {
171
195
  .filter(f => f.endsWith('.json'))
172
196
  .map(f => path.join(dir, f))
173
197
  .sort((a, b) => fs.statSync(b).mtime.getTime() - fs.statSync(a).mtime.getTime());
174
- }
175
- catch {
198
+ } catch {
176
199
  return [];
177
200
  }
178
201
  },
202
+
179
203
  /**
180
204
  * Lists all approved sample files ready for export.
181
205
  * Filters to samples with status === 'approved'.
182
206
  */
183
- listApprovedSamples(workspaceDir) {
207
+ listApprovedSamples(workspaceDir: string): string[] {
184
208
  return this.listSamples(workspaceDir).filter(samplePath => {
185
209
  try {
186
210
  const content = fs.readFileSync(samplePath, 'utf-8');
187
211
  const sample = JSON.parse(content);
188
212
  return sample.status === 'approved';
189
- }
190
- catch {
213
+ } catch {
191
214
  return false;
192
215
  }
193
216
  });
194
217
  },
195
- };
218
+ } as const;
219
+
196
220
  // ---------------------------------------------------------------------------
197
221
  // Constants for documentation / external reference
198
222
  // ---------------------------------------------------------------------------
223
+
199
224
  /**
200
225
  * Complete path map for reference.
201
226
  * These mirror the keys in NOCTURNAL_DIRS and NOCTURNAL_FILES.
202
227
  */
203
- export const NOCTURNAL_PATH_DESCRIPTIONS = {
204
- '.state/nocturnal/samples/': 'Structured decision-point JSON artifacts (not injected into prompts)',
205
- '.state/nocturnal/memory/': 'Short-term operator-facing reflection memory (not prompt-injected)',
206
- '.state/exports/orpo/': 'Approved training pairs, immutable after export',
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',
207
232
  '.state/nocturnal/review-queue.json': 'Pending sample review queue',
208
- 'memory/reflection-log.md': 'Operator-facing human-readable lessons (INJECTED into prompts)',
233
+ 'memory/reflection-log.md': 'Operator-facing human-readable lessons (INJECTED into prompts)',
209
234
  };
235
+
210
236
  /**
211
237
  * IMPORTANT: memory/reflection-log.md is NOT a nocturnal artifact.
212
238
  * It is the pre-existing operator-facing reflection log, defined in paths.ts.