principles-disciple 1.8.1 → 1.8.3

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 (508) 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/en/skills/ai-sprint-orchestration/EXAMPLES.md +63 -0
  138. package/templates/langs/en/skills/ai-sprint-orchestration/REFERENCE.md +136 -0
  139. package/templates/langs/en/skills/ai-sprint-orchestration/SKILL.md +67 -0
  140. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +214 -0
  141. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +107 -0
  142. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +107 -0
  143. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +105 -0
  144. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +108 -0
  145. package/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +58 -0
  146. package/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +190 -0
  147. package/templates/langs/en/skills/ai-sprint-orchestration/runtime/.gitignore +2 -0
  148. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +310 -0
  149. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +683 -0
  150. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +604 -0
  151. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +32 -0
  152. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +707 -0
  153. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +3419 -0
  154. package/templates/langs/zh/skills/ai-sprint-orchestration/EXAMPLES.md +63 -0
  155. package/templates/langs/zh/skills/ai-sprint-orchestration/REFERENCE.md +136 -0
  156. package/templates/langs/zh/skills/ai-sprint-orchestration/SKILL.md +67 -0
  157. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +214 -0
  158. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +107 -0
  159. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +107 -0
  160. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +105 -0
  161. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +108 -0
  162. package/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +58 -0
  163. package/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +190 -0
  164. package/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +2 -0
  165. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +310 -0
  166. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +683 -0
  167. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +604 -0
  168. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +32 -0
  169. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +707 -0
  170. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +3419 -0
  171. package/templates/langs/zh/skills/ai-sprint-orchestration/test/archive.test.mjs +230 -0
  172. package/templates/langs/zh/skills/ai-sprint-orchestration/test/contract-enforcement.test.mjs +672 -0
  173. package/templates/langs/zh/skills/ai-sprint-orchestration/test/decision.test.mjs +1321 -0
  174. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +1419 -0
  175. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
  176. package/templates/pain_settings.json +2 -1
  177. package/tests/README.md +120 -0
  178. package/tests/build-artifacts.test.ts +111 -0
  179. package/tests/commands/evolution-status.test.ts +222 -0
  180. package/tests/commands/evolver.test.ts +22 -0
  181. package/tests/commands/export.test.ts +78 -0
  182. package/tests/commands/nocturnal-review.test.ts +448 -0
  183. package/tests/commands/nocturnal-train.test.ts +97 -0
  184. package/tests/commands/pain.test.ts +108 -0
  185. package/tests/commands/samples.test.ts +65 -0
  186. package/tests/commands/strategy.test.ts +34 -0
  187. package/tests/commands/thinking-os.test.ts +88 -0
  188. package/tests/core/adaptive-thresholds.test.ts +261 -0
  189. package/tests/core/config-service.test.ts +89 -0
  190. package/tests/core/config.test.ts +90 -0
  191. package/tests/core/control-ui-db.test.ts +75 -0
  192. package/tests/core/core-template-guidance.test.ts +21 -0
  193. package/tests/core/detection-funnel.test.ts +63 -0
  194. package/tests/core/detection-service.test.ts +50 -0
  195. package/tests/core/dictionary-service.test.ts +116 -0
  196. package/tests/core/dictionary.test.ts +168 -0
  197. package/tests/core/empathy-keyword-matcher.test.ts +209 -0
  198. package/tests/core/event-log.test.ts +181 -0
  199. package/tests/core/evolution-e2e.test.ts +58 -0
  200. package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
  201. package/tests/core/evolution-engine.test.ts +562 -0
  202. package/tests/core/evolution-logger.test.ts +148 -0
  203. package/tests/core/evolution-migration.test.ts +50 -0
  204. package/tests/core/evolution-paths.test.ts +21 -0
  205. package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
  206. package/tests/core/evolution-reducer.test.ts +180 -0
  207. package/tests/core/evolution-types-loop.test.ts +48 -0
  208. package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
  209. package/tests/core/external-training-contract.test.ts +463 -0
  210. package/tests/core/focus-history.test.ts +682 -0
  211. package/tests/core/init-flatten.test.ts +69 -0
  212. package/tests/core/init-refactor.test.ts +87 -0
  213. package/tests/core/init-v1.3.test.ts +46 -0
  214. package/tests/core/init.test.ts +190 -0
  215. package/tests/core/local-worker-routing.test.ts +757 -0
  216. package/tests/core/migration.test.ts +84 -0
  217. package/tests/core/model-deployment-registry.test.ts +845 -0
  218. package/tests/core/model-training-registry.test.ts +889 -0
  219. package/tests/core/nocturnal-arbiter.test.ts +494 -0
  220. package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
  221. package/tests/core/nocturnal-compliance.test.ts +646 -0
  222. package/tests/core/nocturnal-dataset.test.ts +892 -0
  223. package/tests/core/nocturnal-executability.test.ts +357 -0
  224. package/tests/core/nocturnal-export.test.ts +462 -0
  225. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
  226. package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
  227. package/tests/core/nocturnal-trinity.test.ts +953 -0
  228. package/tests/core/pain.test.ts +33 -0
  229. package/tests/core/path-resolver.test.ts +57 -0
  230. package/tests/core/paths-refactor.test.ts +42 -0
  231. package/tests/core/phase7-rollout-integration.test.ts +477 -0
  232. package/tests/core/principle-training-state.test.ts +712 -0
  233. package/tests/core/profile.test.ts +56 -0
  234. package/tests/core/promotion-gate.test.ts +556 -0
  235. package/tests/core/risk-calculator.test.ts +168 -0
  236. package/tests/core/session-tracker.test.ts +191 -0
  237. package/tests/core/training-program.test.ts +472 -0
  238. package/tests/core/trajectory.test.ts +265 -0
  239. package/tests/core/workspace-context-factory.test.ts +18 -0
  240. package/tests/core/workspace-context.test.ts +134 -0
  241. package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
  242. package/tests/fixtures/production-compatibility.test.ts +147 -0
  243. package/tests/fixtures/production-mock-generator.ts +282 -0
  244. package/tests/hooks/bash-risk-integration.test.ts +137 -0
  245. package/tests/hooks/bash-risk.test.ts +81 -0
  246. package/tests/hooks/edit-verification.test.ts +678 -0
  247. package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
  248. package/tests/hooks/gate-edit-verification.test.ts +435 -0
  249. package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
  250. package/tests/hooks/gate.test.ts +271 -0
  251. package/tests/hooks/gfi-gate-unit.test.ts +422 -0
  252. package/tests/hooks/gfi-gate.test.ts +669 -0
  253. package/tests/hooks/lifecycle.test.ts +248 -0
  254. package/tests/hooks/llm.test.ts +308 -0
  255. package/tests/hooks/message-sanitize.test.ts +36 -0
  256. package/tests/hooks/pain.test.ts +141 -0
  257. package/tests/hooks/progressive-trust-gate.test.ts +277 -0
  258. package/tests/hooks/prompt.test.ts +1411 -0
  259. package/tests/hooks/subagent.test.ts +467 -0
  260. package/tests/hooks/thinking-gate.test.ts +313 -0
  261. package/tests/http/principles-console-route.test.ts +140 -0
  262. package/tests/hygiene-tracker.test.ts +77 -0
  263. package/tests/index.integration.test.ts +179 -0
  264. package/tests/index.shadow-routing.integration.test.ts +140 -0
  265. package/tests/index.test.ts +9 -0
  266. package/tests/integration/empathy-workflow-integration.test.ts +627 -0
  267. package/tests/service/control-ui-query-service.test.ts +121 -0
  268. package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
  269. package/tests/service/evolution-worker.test.ts +585 -0
  270. package/tests/service/nocturnal-runtime.test.ts +470 -0
  271. package/tests/service/nocturnal-service.test.ts +577 -0
  272. package/tests/service/nocturnal-target-selector.test.ts +615 -0
  273. package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
  274. package/tests/service/phase3-input-filter.test.ts +289 -0
  275. package/tests/service/runtime-summary-service.test.ts +919 -0
  276. package/tests/task-compliance.test.ts +166 -0
  277. package/tests/test-utils.ts +48 -0
  278. package/tests/tools/critique-prompt.test.ts +260 -0
  279. package/tests/tools/deep-reflect.test.ts +232 -0
  280. package/tests/tools/model-index.test.ts +246 -0
  281. package/tests/ui/app.test.tsx +114 -0
  282. package/tests/utils/file-lock.test.ts +407 -0
  283. package/tests/utils/hashing.test.ts +32 -0
  284. package/tests/utils/io.test.ts +39 -0
  285. package/tests/utils/nlp.test.ts +53 -0
  286. package/tests/utils/plugin-logger.test.ts +156 -0
  287. package/tsconfig.json +16 -0
  288. package/tsconfig.tsbuildinfo +1 -0
  289. package/ui/src/App.tsx +45 -0
  290. package/ui/src/api.ts +216 -0
  291. package/ui/src/charts.tsx +586 -0
  292. package/ui/src/components/ErrorState.tsx +6 -0
  293. package/ui/src/components/Loading.tsx +13 -0
  294. package/ui/src/components/ProtectedRoute.tsx +12 -0
  295. package/ui/src/components/Shell.tsx +91 -0
  296. package/ui/src/components/WorkspaceConfig.tsx +146 -0
  297. package/ui/src/components/index.ts +5 -0
  298. package/ui/src/context/auth.tsx +80 -0
  299. package/ui/src/context/theme.tsx +66 -0
  300. package/ui/src/hooks/useAutoRefresh.ts +39 -0
  301. package/ui/src/i18n/ui.ts +363 -0
  302. package/ui/src/main.tsx +16 -0
  303. package/ui/src/pages/EvolutionPage.tsx +352 -0
  304. package/ui/src/pages/FeedbackPage.tsx +140 -0
  305. package/ui/src/pages/GateMonitorPage.tsx +136 -0
  306. package/ui/src/pages/LoginPage.tsx +88 -0
  307. package/ui/src/pages/OverviewPage.tsx +238 -0
  308. package/ui/src/pages/SamplesPage.tsx +174 -0
  309. package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
  310. package/ui/src/styles.css +1661 -0
  311. package/ui/src/types.ts +368 -0
  312. package/ui/src/utils/format.ts +15 -0
  313. package/vitest.config.ts +23 -0
  314. package/dist/commands/capabilities.d.ts +0 -3
  315. package/dist/commands/capabilities.js +0 -73
  316. package/dist/commands/context.d.ts +0 -5
  317. package/dist/commands/evolution-status.d.ts +0 -4
  318. package/dist/commands/evolution-status.js +0 -117
  319. package/dist/commands/evolver.d.ts +0 -9
  320. package/dist/commands/evolver.js +0 -26
  321. package/dist/commands/export.d.ts +0 -2
  322. package/dist/commands/export.js +0 -98
  323. package/dist/commands/focus.d.ts +0 -14
  324. package/dist/commands/focus.js +0 -457
  325. package/dist/commands/nocturnal-review.d.ts +0 -24
  326. package/dist/commands/nocturnal-review.js +0 -265
  327. package/dist/commands/nocturnal-rollout.d.ts +0 -27
  328. package/dist/commands/nocturnal-rollout.js +0 -671
  329. package/dist/commands/nocturnal-train.d.ts +0 -25
  330. package/dist/commands/nocturnal-train.js +0 -919
  331. package/dist/commands/pain.d.ts +0 -5
  332. package/dist/commands/principle-rollback.d.ts +0 -4
  333. package/dist/commands/principle-rollback.js +0 -22
  334. package/dist/commands/rollback.d.ts +0 -19
  335. package/dist/commands/samples.d.ts +0 -2
  336. package/dist/commands/samples.js +0 -55
  337. package/dist/commands/strategy.d.ts +0 -3
  338. package/dist/commands/strategy.js +0 -29
  339. package/dist/commands/thinking-os.d.ts +0 -2
  340. package/dist/config/defaults/runtime.d.ts +0 -40
  341. package/dist/config/errors.d.ts +0 -84
  342. package/dist/config/errors.js +0 -94
  343. package/dist/config/index.js +0 -7
  344. package/dist/constants/diagnostician.d.ts +0 -12
  345. package/dist/constants/diagnostician.js +0 -56
  346. package/dist/constants/tools.d.ts +0 -17
  347. package/dist/constants/tools.js +0 -54
  348. package/dist/core/adaptive-thresholds.d.ts +0 -186
  349. package/dist/core/adaptive-thresholds.js +0 -300
  350. package/dist/core/config-service.d.ts +0 -15
  351. package/dist/core/config.d.ts +0 -129
  352. package/dist/core/control-ui-db.d.ts +0 -95
  353. package/dist/core/control-ui-db.js +0 -292
  354. package/dist/core/detection-funnel.d.ts +0 -33
  355. package/dist/core/detection-service.d.ts +0 -15
  356. package/dist/core/dictionary-service.d.ts +0 -15
  357. package/dist/core/dictionary.d.ts +0 -38
  358. package/dist/core/event-log.d.ts +0 -82
  359. package/dist/core/event-log.js +0 -463
  360. package/dist/core/evolution-engine.d.ts +0 -118
  361. package/dist/core/evolution-engine.js +0 -464
  362. package/dist/core/evolution-logger.d.ts +0 -137
  363. package/dist/core/evolution-logger.js +0 -256
  364. package/dist/core/evolution-migration.d.ts +0 -5
  365. package/dist/core/evolution-migration.js +0 -65
  366. package/dist/core/evolution-reducer.d.ts +0 -98
  367. package/dist/core/evolution-reducer.js +0 -465
  368. package/dist/core/evolution-types.d.ts +0 -287
  369. package/dist/core/evolution-types.js +0 -78
  370. package/dist/core/external-training-contract.d.ts +0 -276
  371. package/dist/core/external-training-contract.js +0 -269
  372. package/dist/core/focus-history.d.ts +0 -210
  373. package/dist/core/focus-history.js +0 -1185
  374. package/dist/core/hygiene/tracker.d.ts +0 -22
  375. package/dist/core/hygiene/tracker.js +0 -106
  376. package/dist/core/init.d.ts +0 -12
  377. package/dist/core/local-worker-routing.d.ts +0 -175
  378. package/dist/core/local-worker-routing.js +0 -525
  379. package/dist/core/migration.d.ts +0 -6
  380. package/dist/core/model-deployment-registry.d.ts +0 -218
  381. package/dist/core/model-deployment-registry.js +0 -503
  382. package/dist/core/model-training-registry.d.ts +0 -295
  383. package/dist/core/model-training-registry.js +0 -475
  384. package/dist/core/nocturnal-arbiter.d.ts +0 -159
  385. package/dist/core/nocturnal-arbiter.js +0 -534
  386. package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
  387. package/dist/core/nocturnal-candidate-scoring.js +0 -266
  388. package/dist/core/nocturnal-compliance.d.ts +0 -175
  389. package/dist/core/nocturnal-compliance.js +0 -824
  390. package/dist/core/nocturnal-dataset.d.ts +0 -224
  391. package/dist/core/nocturnal-dataset.js +0 -443
  392. package/dist/core/nocturnal-executability.d.ts +0 -85
  393. package/dist/core/nocturnal-executability.js +0 -331
  394. package/dist/core/nocturnal-export.d.ts +0 -124
  395. package/dist/core/nocturnal-export.js +0 -275
  396. package/dist/core/nocturnal-paths.d.ts +0 -124
  397. package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
  398. package/dist/core/nocturnal-trajectory-extractor.js +0 -307
  399. package/dist/core/nocturnal-trinity.d.ts +0 -311
  400. package/dist/core/nocturnal-trinity.js +0 -880
  401. package/dist/core/pain.d.ts +0 -4
  402. package/dist/core/pain.js +0 -70
  403. package/dist/core/path-resolver.d.ts +0 -46
  404. package/dist/core/paths.d.ts +0 -65
  405. package/dist/core/principle-training-state.d.ts +0 -121
  406. package/dist/core/principle-training-state.js +0 -321
  407. package/dist/core/profile.d.ts +0 -62
  408. package/dist/core/profile.js +0 -210
  409. package/dist/core/promotion-gate.d.ts +0 -238
  410. package/dist/core/promotion-gate.js +0 -529
  411. package/dist/core/risk-calculator.d.ts +0 -22
  412. package/dist/core/session-tracker.d.ts +0 -101
  413. package/dist/core/shadow-observation-registry.d.ts +0 -217
  414. package/dist/core/shadow-observation-registry.js +0 -308
  415. package/dist/core/system-logger.d.ts +0 -8
  416. package/dist/core/thinking-models.d.ts +0 -38
  417. package/dist/core/thinking-models.js +0 -170
  418. package/dist/core/training-program.d.ts +0 -233
  419. package/dist/core/training-program.js +0 -433
  420. package/dist/core/trajectory.d.ts +0 -411
  421. package/dist/core/trajectory.js +0 -1307
  422. package/dist/core/workspace-context.d.ts +0 -71
  423. package/dist/hooks/bash-risk.d.ts +0 -57
  424. package/dist/hooks/bash-risk.js +0 -137
  425. package/dist/hooks/edit-verification.d.ts +0 -62
  426. package/dist/hooks/edit-verification.js +0 -256
  427. package/dist/hooks/gate-block-helper.d.ts +0 -44
  428. package/dist/hooks/gate-block-helper.js +0 -119
  429. package/dist/hooks/gate.d.ts +0 -24
  430. package/dist/hooks/gate.js +0 -173
  431. package/dist/hooks/gfi-gate.d.ts +0 -40
  432. package/dist/hooks/gfi-gate.js +0 -113
  433. package/dist/hooks/lifecycle.d.ts +0 -5
  434. package/dist/hooks/lifecycle.js +0 -284
  435. package/dist/hooks/llm.d.ts +0 -13
  436. package/dist/hooks/message-sanitize.d.ts +0 -3
  437. package/dist/hooks/message-sanitize.js +0 -37
  438. package/dist/hooks/pain.d.ts +0 -5
  439. package/dist/hooks/pain.js +0 -301
  440. package/dist/hooks/progressive-trust-gate.d.ts +0 -52
  441. package/dist/hooks/progressive-trust-gate.js +0 -134
  442. package/dist/hooks/prompt.d.ts +0 -49
  443. package/dist/hooks/prompt.js +0 -905
  444. package/dist/hooks/subagent.d.ts +0 -10
  445. package/dist/hooks/subagent.js +0 -387
  446. package/dist/hooks/thinking-checkpoint.d.ts +0 -37
  447. package/dist/hooks/thinking-checkpoint.js +0 -51
  448. package/dist/hooks/trajectory-collector.d.ts +0 -32
  449. package/dist/hooks/trajectory-collector.js +0 -256
  450. package/dist/http/principles-console-route.d.ts +0 -9
  451. package/dist/http/principles-console-route.js +0 -681
  452. package/dist/i18n/commands.d.ts +0 -26
  453. package/dist/i18n/commands.js +0 -116
  454. package/dist/index.d.ts +0 -7
  455. package/dist/index.js +0 -581
  456. package/dist/service/central-database.d.ts +0 -104
  457. package/dist/service/central-database.js +0 -649
  458. package/dist/service/control-ui-query-service.d.ts +0 -221
  459. package/dist/service/control-ui-query-service.js +0 -543
  460. package/dist/service/empathy-observer-manager.d.ts +0 -88
  461. package/dist/service/empathy-observer-manager.js +0 -414
  462. package/dist/service/evolution-query-service.d.ts +0 -155
  463. package/dist/service/evolution-query-service.js +0 -258
  464. package/dist/service/evolution-worker.d.ts +0 -101
  465. package/dist/service/evolution-worker.js +0 -975
  466. package/dist/service/health-query-service.d.ts +0 -170
  467. package/dist/service/health-query-service.js +0 -662
  468. package/dist/service/nocturnal-runtime.d.ts +0 -183
  469. package/dist/service/nocturnal-service.d.ts +0 -163
  470. package/dist/service/nocturnal-service.js +0 -787
  471. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  472. package/dist/service/nocturnal-target-selector.js +0 -315
  473. package/dist/service/phase3-input-filter.d.ts +0 -73
  474. package/dist/service/phase3-input-filter.js +0 -172
  475. package/dist/service/runtime-summary-service.d.ts +0 -122
  476. package/dist/service/runtime-summary-service.js +0 -485
  477. package/dist/service/subagent-workflow/empathy-observer-workflow-manager.d.ts +0 -48
  478. package/dist/service/subagent-workflow/index.d.ts +0 -4
  479. package/dist/service/subagent-workflow/index.js +0 -3
  480. package/dist/service/subagent-workflow/runtime-direct-driver.d.ts +0 -77
  481. package/dist/service/subagent-workflow/runtime-direct-driver.js +0 -75
  482. package/dist/service/subagent-workflow/types.js +0 -11
  483. package/dist/service/subagent-workflow/workflow-store.d.ts +0 -26
  484. package/dist/service/subagent-workflow/workflow-store.js +0 -165
  485. package/dist/service/trajectory-service.d.ts +0 -2
  486. package/dist/service/trajectory-service.js +0 -15
  487. package/dist/tools/critique-prompt.d.ts +0 -14
  488. package/dist/tools/deep-reflect.d.ts +0 -39
  489. package/dist/tools/deep-reflect.js +0 -350
  490. package/dist/tools/model-index.d.ts +0 -9
  491. package/dist/types/event-types.d.ts +0 -306
  492. package/dist/types/event-types.js +0 -106
  493. package/dist/types/hygiene-types.d.ts +0 -20
  494. package/dist/types/hygiene-types.js +0 -12
  495. package/dist/types/runtime-summary.d.ts +0 -47
  496. package/dist/types/runtime-summary.js +0 -1
  497. package/dist/types.d.ts +0 -50
  498. package/dist/types.js +0 -22
  499. package/dist/utils/file-lock.d.ts +0 -71
  500. package/dist/utils/file-lock.js +0 -309
  501. package/dist/utils/glob-match.d.ts +0 -28
  502. package/dist/utils/hashing.d.ts +0 -9
  503. package/dist/utils/io.d.ts +0 -6
  504. package/dist/utils/io.js +0 -106
  505. package/dist/utils/nlp.d.ts +0 -9
  506. package/dist/utils/plugin-logger.d.ts +0 -39
  507. package/dist/utils/subagent-probe.d.ts +0 -34
  508. package/dist/utils/subagent-probe.js +0 -81
@@ -0,0 +1,265 @@
1
+ import { afterEach, describe, expect, it } from 'vitest';
2
+ import fs from 'fs';
3
+ import os from 'os';
4
+ import path from 'path';
5
+ import { TrajectoryDatabase } from '../../src/core/trajectory.js';
6
+
7
+ describe('TrajectoryDatabase', () => {
8
+ let workspaceDir: string | null = null;
9
+
10
+ afterEach(() => {
11
+ if (workspaceDir) {
12
+ fs.rmSync(workspaceDir, { recursive: true, force: true });
13
+ workspaceDir = null;
14
+ }
15
+ });
16
+
17
+ it('bootstraps trajectory.db and blob/export directories', () => {
18
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
19
+ const db = new TrajectoryDatabase({ workspaceDir });
20
+
21
+ expect(fs.existsSync(path.join(workspaceDir, '.state', 'trajectory.db'))).toBe(true);
22
+ expect(fs.existsSync(path.join(workspaceDir, '.state', 'blobs'))).toBe(true);
23
+ expect(fs.existsSync(path.join(workspaceDir, '.state', 'exports'))).toBe(true);
24
+
25
+ const stats = db.getDataStats();
26
+ expect(stats.assistantTurns).toBe(0);
27
+ expect(stats.userTurns).toBe(0);
28
+ expect(stats.pendingSamples).toBe(0);
29
+ db.dispose();
30
+ });
31
+
32
+ it('stores oversized assistant raw text in blob storage and preserves sanitized text inline', () => {
33
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
34
+ const db = new TrajectoryDatabase({ workspaceDir, blobInlineThresholdBytes: 128 });
35
+
36
+ const raw = `${'A'.repeat(256)}\n<empathy signal="damage" severity="mild"/>`;
37
+ db.recordAssistantTurn({
38
+ sessionId: 's1',
39
+ runId: 'run-1',
40
+ provider: 'test',
41
+ model: 'model',
42
+ rawText: raw,
43
+ sanitizedText: 'clean text',
44
+ usageJson: { input: 10, output: 20 },
45
+ empathySignalJson: { detected: true, severity: 'mild' },
46
+ });
47
+
48
+ const turns = db.listAssistantTurns('s1');
49
+ expect(turns).toHaveLength(1);
50
+ expect(turns[0].sanitizedText).toBe('clean text');
51
+ expect(turns[0].rawText).toBe(raw);
52
+ expect(turns[0].blobRef).toBeTruthy();
53
+ db.dispose();
54
+ });
55
+
56
+ it('creates a pending correction sample after a user correction followed by successful recovery', () => {
57
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
58
+ const db = new TrajectoryDatabase({ workspaceDir });
59
+
60
+ const assistantTurnId = db.recordAssistantTurn({
61
+ sessionId: 's1',
62
+ runId: 'run-1',
63
+ provider: 'test',
64
+ model: 'model',
65
+ rawText: 'I changed the wrong file.',
66
+ sanitizedText: 'I changed the wrong file.',
67
+ usageJson: {},
68
+ empathySignalJson: { detected: false },
69
+ });
70
+
71
+ db.recordToolCall({
72
+ sessionId: 's1',
73
+ toolName: 'edit',
74
+ outcome: 'failure',
75
+ errorType: 'EACCES',
76
+ errorMessage: 'permission denied',
77
+ });
78
+
79
+ db.recordUserTurn({
80
+ sessionId: 's1',
81
+ turnIndex: 1,
82
+ rawText: '你错了,不是这个文件,重新来。',
83
+ correctionDetected: true,
84
+ correctionCue: '你错了',
85
+ referencesAssistantTurnId: assistantTurnId,
86
+ });
87
+
88
+ db.recordToolCall({
89
+ sessionId: 's1',
90
+ toolName: 'edit',
91
+ outcome: 'success',
92
+ });
93
+
94
+ const samples = db.listCorrectionSamples('pending');
95
+ expect(samples).toHaveLength(1);
96
+ expect(samples[0].sessionId).toBe('s1');
97
+ expect(samples[0].badAssistantTurnId).toBe(assistantTurnId);
98
+ expect(samples[0].reviewStatus).toBe('pending');
99
+ expect(samples[0].qualityScore).toBeGreaterThan(0);
100
+ db.dispose();
101
+ });
102
+
103
+ it('does not create a correction sample when prerequisites are missing', () => {
104
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
105
+ const db = new TrajectoryDatabase({ workspaceDir });
106
+
107
+ db.recordToolCall({
108
+ sessionId: 's1',
109
+ toolName: 'edit',
110
+ outcome: 'failure',
111
+ errorType: 'EACCES',
112
+ });
113
+ db.recordUserTurn({
114
+ sessionId: 's1',
115
+ turnIndex: 1,
116
+ rawText: 'redo',
117
+ correctionDetected: false,
118
+ referencesAssistantTurnId: null,
119
+ });
120
+ db.recordToolCall({
121
+ sessionId: 's1',
122
+ toolName: 'edit',
123
+ outcome: 'success',
124
+ });
125
+
126
+ expect(db.listCorrectionSamples('pending')).toHaveLength(0);
127
+ db.dispose();
128
+ });
129
+
130
+ it('raises when reviewing a missing correction sample', () => {
131
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
132
+ const db = new TrajectoryDatabase({ workspaceDir });
133
+
134
+ expect(() => db.reviewCorrectionSample('missing', 'approved')).toThrow('Correction sample not found');
135
+ db.dispose();
136
+ });
137
+
138
+ it('aggregates daily metrics without multiplying user corrections', () => {
139
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
140
+ const db = new TrajectoryDatabase({ workspaceDir });
141
+
142
+ db.recordToolCall({
143
+ sessionId: 's1',
144
+ toolName: 'edit',
145
+ outcome: 'failure',
146
+ createdAt: '2026-03-19T10:00:00.000Z',
147
+ });
148
+ db.recordToolCall({
149
+ sessionId: 's1',
150
+ toolName: 'write',
151
+ outcome: 'success',
152
+ createdAt: '2026-03-19T11:00:00.000Z',
153
+ });
154
+ db.recordUserTurn({
155
+ sessionId: 's1',
156
+ turnIndex: 1,
157
+ rawText: 'redo',
158
+ correctionDetected: true,
159
+ correctionCue: 'redo',
160
+ createdAt: '2026-03-19T12:00:00.000Z',
161
+ });
162
+ db.recordUserTurn({
163
+ sessionId: 's1',
164
+ turnIndex: 2,
165
+ rawText: 'again',
166
+ correctionDetected: true,
167
+ correctionCue: 'again',
168
+ createdAt: '2026-03-19T13:00:00.000Z',
169
+ });
170
+
171
+ const result = db.exportAnalytics();
172
+ const payload = JSON.parse(fs.readFileSync(result.filePath, 'utf8')) as {
173
+ dailyMetrics: Array<{ day: string; tool_calls: number; failures: number; user_corrections: number }>;
174
+ };
175
+ expect(payload.dailyMetrics).toEqual([
176
+ { day: '2026-03-19', tool_calls: 2, failures: 1, user_corrections: 2 },
177
+ ]);
178
+ db.dispose();
179
+ });
180
+
181
+ it('applies busy_timeout and prunes orphaned blobs on startup', () => {
182
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
183
+ const blobDir = path.join(workspaceDir, '.state', 'blobs');
184
+ fs.mkdirSync(blobDir, { recursive: true });
185
+ const orphanBlob = path.join(blobDir, 'assistant-orphan.txt');
186
+ fs.writeFileSync(orphanBlob, 'stale blob', 'utf8');
187
+ const oldTime = new Date('2026-01-01T00:00:00.000Z');
188
+ fs.utimesSync(orphanBlob, oldTime, oldTime);
189
+
190
+ const db = new TrajectoryDatabase({
191
+ workspaceDir,
192
+ busyTimeoutMs: 2500,
193
+ orphanBlobGraceDays: 0,
194
+ });
195
+
196
+ expect((db as any).db.pragma('busy_timeout', { simple: true })).toBe(2500);
197
+ expect(fs.existsSync(orphanBlob)).toBe(false);
198
+ db.dispose();
199
+ });
200
+
201
+ it('imports legacy sessions, events, and evolution artifacts idempotently', () => {
202
+ workspaceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pd-trajectory-'));
203
+ const sessionDir = path.join(workspaceDir, '.state', 'sessions');
204
+ const logsDir = path.join(workspaceDir, '.state', 'logs');
205
+ const memoryDir = path.join(workspaceDir, 'memory');
206
+ fs.mkdirSync(sessionDir, { recursive: true });
207
+ fs.mkdirSync(logsDir, { recursive: true });
208
+ fs.mkdirSync(memoryDir, { recursive: true });
209
+
210
+ fs.writeFileSync(
211
+ path.join(sessionDir, 'session-a.json'),
212
+ JSON.stringify({ sessionId: 'legacy-session', lastActivityAt: Date.parse('2026-03-18T10:00:00.000Z') }),
213
+ 'utf8',
214
+ );
215
+ fs.writeFileSync(
216
+ path.join(logsDir, 'events.jsonl'),
217
+ [
218
+ JSON.stringify({
219
+ type: 'pain_signal',
220
+ sessionId: 'legacy-session',
221
+ ts: '2026-03-18T10:01:00.000Z',
222
+ data: { source: 'legacy_pain', score: 12, reason: 'legacy reason' },
223
+ }),
224
+ JSON.stringify({
225
+ type: 'trust_change',
226
+ sessionId: 'legacy-session',
227
+ ts: '2026-03-18T10:02:00.000Z',
228
+ data: { previousScore: 80, newScore: 82, delta: 2, reason: 'legacy trust' },
229
+ }),
230
+ ].join('\n'),
231
+ 'utf8',
232
+ );
233
+ fs.writeFileSync(
234
+ path.join(memoryDir, 'evolution.jsonl'),
235
+ `${JSON.stringify({
236
+ type: 'principle_promoted',
237
+ ts: '2026-03-18T10:03:00.000Z',
238
+ data: { principleId: 'p-1', summary: 'legacy principle' },
239
+ })}\n`,
240
+ 'utf8',
241
+ );
242
+
243
+ const db = new TrajectoryDatabase({ workspaceDir });
244
+ const firstStats = db.getDataStats();
245
+ expect(firstStats.painEvents).toBe(1);
246
+ expect(firstStats.assistantTurns).toBe(0);
247
+
248
+ const analytics = JSON.parse(fs.readFileSync(db.exportAnalytics().filePath, 'utf8')) as {
249
+ stats: { painEvents: number };
250
+ principleEffectiveness: Array<{ event_type: string; total: number }>;
251
+ };
252
+ expect(analytics.stats.painEvents).toBe(1);
253
+ expect(analytics.principleEffectiveness).toEqual(
254
+ expect.arrayContaining([
255
+ expect.objectContaining({ event_type: 'principle_promoted', total: 1 }),
256
+ ]),
257
+ );
258
+ db.dispose();
259
+
260
+ const reopened = new TrajectoryDatabase({ workspaceDir });
261
+ const secondStats = reopened.getDataStats();
262
+ expect(secondStats.painEvents).toBe(1);
263
+ reopened.dispose();
264
+ });
265
+ });
@@ -0,0 +1,18 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { createTestContext } from '../test-utils.js';
3
+ import * as path from 'path';
4
+
5
+ describe('WorkspaceContext Factory (Test Utils)', () => {
6
+ it('should create a test context with a temporary directory', () => {
7
+ const wctx = createTestContext();
8
+
9
+ expect(wctx.workspaceDir).toContain('pd-test-');
10
+ expect(wctx.stateDir).toContain('.state');
11
+ });
12
+
13
+ it('should allow overriding workspaceDir', () => {
14
+ const customDir = path.resolve('/custom/test');
15
+ const wctx = createTestContext({ workspaceDir: customDir });
16
+ expect(wctx.workspaceDir).toBe(customDir);
17
+ });
18
+ });
@@ -0,0 +1,134 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { WorkspaceContext } from '../../src/core/workspace-context.js';
3
+ import * as fs from 'fs';
4
+ import * as path from 'path';
5
+
6
+ vi.mock('fs');
7
+ vi.mock('../../src/core/trajectory.js', () => ({
8
+ TrajectoryRegistry: {
9
+ get: vi.fn(() => ({
10
+ dispose: vi.fn(),
11
+ })),
12
+ use: vi.fn(),
13
+ dispose: vi.fn(),
14
+ clear: vi.fn(),
15
+ }
16
+ }));
17
+
18
+ describe('WorkspaceContext', () => {
19
+ // Use path.resolve for cross-platform compatibility on Windows
20
+ const workspaceDir = path.resolve('/mock/workspace');
21
+ const stateDir = path.resolve('/mock/state');
22
+
23
+ beforeEach(() => {
24
+ vi.clearAllMocks();
25
+ WorkspaceContext.clearCache();
26
+ });
27
+
28
+ afterEach(() => {
29
+ vi.resetAllMocks();
30
+ });
31
+
32
+ it('should create an instance from hook context', () => {
33
+ const mockCtx = { workspaceDir, stateDir };
34
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
35
+
36
+ expect(wctx.workspaceDir).toBe(workspaceDir);
37
+ expect(wctx.stateDir).toBe(stateDir);
38
+ });
39
+
40
+ it('should cache instances based on workspaceDir', () => {
41
+ const mockCtx1 = { workspaceDir, stateDir: path.resolve('/state1') };
42
+ const mockCtx2 = { workspaceDir, stateDir: path.resolve('/state2') };
43
+
44
+ const wctx1 = WorkspaceContext.fromHookContext(mockCtx1);
45
+ const wctx2 = WorkspaceContext.fromHookContext(mockCtx2);
46
+
47
+ expect(wctx1).toBe(wctx2);
48
+ expect(wctx1.stateDir).toBe(path.resolve('/state1'));
49
+ });
50
+
51
+ it('should use fallback workspace when workspaceDir is missing', () => {
52
+ const mockCtx = { stateDir };
53
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
54
+ expect(wctx).toBeDefined();
55
+ expect(wctx.workspaceDir).toBeDefined();
56
+ });
57
+
58
+ it('should resolve paths using PD_FILES keys', () => {
59
+ const mockCtx = { workspaceDir };
60
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
61
+
62
+ // PROFILE is at .principles/PROFILE.json
63
+ expect(wctx.resolve('PROFILE')).toBe(path.join(workspaceDir, '.principles', 'PROFILE.json'));
64
+ // PLAN is at root
65
+ expect(wctx.resolve('PLAN')).toBe(path.join(workspaceDir, 'PLAN.md'));
66
+ });
67
+
68
+ it('should support explicit disposal from cache', () => {
69
+ const mockCtx = { workspaceDir };
70
+ const wctx1 = WorkspaceContext.fromHookContext(mockCtx);
71
+
72
+ WorkspaceContext.dispose(workspaceDir);
73
+
74
+ const wctx2 = WorkspaceContext.fromHookContext(mockCtx);
75
+ expect(wctx1).not.toBe(wctx2);
76
+ });
77
+
78
+ it('should allow invalidation of internal state', () => {
79
+ const mockCtx = { workspaceDir };
80
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
81
+
82
+ expect(() => wctx.invalidate()).not.toThrow();
83
+ });
84
+
85
+ it('should lazy load ConfigService', () => {
86
+ const mockCtx = { workspaceDir };
87
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
88
+
89
+ const config = wctx.config;
90
+ expect(config).toBeDefined();
91
+ expect(wctx.config).toBe(config); // Should be cached
92
+ });
93
+
94
+ it('should lazy load EventLog', () => {
95
+ const mockCtx = { workspaceDir };
96
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
97
+
98
+ const eventLog = wctx.eventLog;
99
+ expect(eventLog).toBeDefined();
100
+ expect(wctx.eventLog).toBe(eventLog); // Should be cached
101
+ });
102
+
103
+ it('should pass trajectory settings from config into the registry', async () => {
104
+ const { TrajectoryRegistry } = await import('../../src/core/trajectory.js');
105
+ const mockCtx = { workspaceDir };
106
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
107
+
108
+ (wctx as any)._config = {
109
+ get: vi.fn((key: string) => {
110
+ if (key === 'trajectory.blob_inline_threshold_bytes') return 2048;
111
+ if (key === 'trajectory.busy_timeout_ms') return 1500;
112
+ if (key === 'trajectory.orphan_blob_grace_days') return 2;
113
+ return undefined;
114
+ }),
115
+ };
116
+
117
+ const trajectory = wctx.trajectory;
118
+ expect(trajectory).toBeDefined();
119
+ expect(TrajectoryRegistry.get).toHaveBeenCalledWith(workspaceDir, {
120
+ blobInlineThresholdBytes: 2048,
121
+ busyTimeoutMs: 1500,
122
+ orphanBlobGraceDays: 2,
123
+ });
124
+ });
125
+
126
+ it('should lazy load Dictionary service', () => {
127
+ const mockCtx = { workspaceDir };
128
+ const wctx = WorkspaceContext.fromHookContext(mockCtx);
129
+
130
+ const dictionary = wctx.dictionary;
131
+ expect(dictionary).toBeDefined();
132
+ expect(wctx.dictionary).toBe(dictionary);
133
+ });
134
+ });
@@ -0,0 +1,183 @@
1
+ {
2
+ "$schema": "nocturnal-reviewed-subset-v1",
3
+ "description": "Reviewed subset fixture for comparing single-reflector vs Trinity quality",
4
+ "version": "1.0.0",
5
+ "createdAt": "2026-03-28T00:00:00.000Z",
6
+ "testCases": [
7
+ {
8
+ "caseId": "case-001",
9
+ "principleId": "T-01",
10
+ "principleDescription": "Map Before Territory: Always survey the existing structure before making changes",
11
+ "sessionId": "session-case-001",
12
+ "signalType": "failure",
13
+ "signalContext": "Agent edited src/main.ts without reading it first, causing a merge conflict",
14
+ "singleReflectorOutput": {
15
+ "artifactId": "single-001-artifact",
16
+ "sessionId": "session-case-001",
17
+ "principleId": "T-01",
18
+ "sourceSnapshotRef": "snapshot-case-001",
19
+ "badDecision": "Edited src/main.ts without first reading its contents, leading to a merge conflict",
20
+ "betterDecision": "Read src/main.ts to understand its current structure before making edits",
21
+ "rationale": "Surveying the existing territory prevents conflicts and ensures edits integrate properly",
22
+ "createdAt": "2026-03-28T00:01:00.000Z"
23
+ },
24
+ "trinityOutput": {
25
+ "selectedCandidateIndex": 0,
26
+ "badDecision": "Edited src/main.ts without first reading its contents, leading to a merge conflict with parallel changes",
27
+ "betterDecision": "Before editing, read src/main.ts to understand its current structure and identify any conflicting sections",
28
+ "rationale": "Surveying the existing territory before making changes prevents conflicts and ensures the edit integrates properly with the current implementation",
29
+ "sessionId": "session-case-001",
30
+ "principleId": "T-01",
31
+ "sourceSnapshotRef": "snapshot-case-001",
32
+ "telemetry": {
33
+ "chainMode": "trinity",
34
+ "dreamerPassed": true,
35
+ "philosopherPassed": true,
36
+ "scribePassed": true,
37
+ "candidateCount": 3,
38
+ "selectedCandidateIndex": 0,
39
+ "stageFailures": []
40
+ }
41
+ },
42
+ "qualityScores": {
43
+ "singleReflector": {
44
+ "specificity": 0.85,
45
+ "principleAlignment": 0.90,
46
+ "actionability": 0.88,
47
+ "rationaleQuality": 0.85,
48
+ "overall": 0.87
49
+ },
50
+ "trinity": {
51
+ "specificity": 0.95,
52
+ "principleAlignment": 0.95,
53
+ "actionability": 0.92,
54
+ "rationaleQuality": 0.95,
55
+ "overall": 0.94
56
+ }
57
+ },
58
+ "trinityWins": true,
59
+ "notes": "Trinity produces more specific badDecision and betterDecision with better rationale"
60
+ },
61
+ {
62
+ "caseId": "case-002",
63
+ "principleId": "T-08",
64
+ "principleDescription": "Pain as Signal: Treat failures and errors as signals to pause and reflect",
65
+ "sessionId": "session-case-002",
66
+ "signalType": "pain",
67
+ "signalContext": "Agent retries failing bash command 3 times without any diagnosis",
68
+ "singleReflectorOutput": {
69
+ "artifactId": "single-002-artifact",
70
+ "sessionId": "session-case-002",
71
+ "principleId": "T-08",
72
+ "sourceSnapshotRef": "snapshot-case-002",
73
+ "badDecision": "Retried failing operation without diagnosing",
74
+ "betterDecision": "Diagnose before retrying",
75
+ "rationale": "Treating failures as signals prevents repeated failures",
76
+ "createdAt": "2026-03-28T00:02:00.000Z"
77
+ },
78
+ "trinityOutput": {
79
+ "selectedCandidateIndex": 0,
80
+ "badDecision": "After bash command failed with 'command not found', immediately retried the exact same command without pausing to diagnose the root cause",
81
+ "betterDecision": "When the bash command fails, pause to check if the tool is installed, verify the path, or consult documentation before retrying",
82
+ "rationale": "Treating each failure as a signal to diagnose rather than blindly retry prevents repeated failures and respects the cost of each action attempt",
83
+ "sessionId": "session-case-002",
84
+ "principleId": "T-08",
85
+ "sourceSnapshotRef": "snapshot-case-002",
86
+ "telemetry": {
87
+ "chainMode": "trinity",
88
+ "dreamerPassed": true,
89
+ "philosopherPassed": true,
90
+ "scribePassed": true,
91
+ "candidateCount": 2,
92
+ "selectedCandidateIndex": 0,
93
+ "stageFailures": []
94
+ }
95
+ },
96
+ "qualityScores": {
97
+ "singleReflector": {
98
+ "specificity": 0.70,
99
+ "principleAlignment": 0.85,
100
+ "actionability": 0.75,
101
+ "rationaleQuality": 0.80,
102
+ "overall": 0.77
103
+ },
104
+ "trinity": {
105
+ "specificity": 0.95,
106
+ "principleAlignment": 0.95,
107
+ "actionability": 0.90,
108
+ "rationaleQuality": 0.95,
109
+ "overall": 0.94
110
+ }
111
+ },
112
+ "trinityWins": true,
113
+ "notes": "Single-reflector is generic; Trinity provides specific diagnosis steps"
114
+ },
115
+ {
116
+ "caseId": "case-003",
117
+ "principleId": "T-03",
118
+ "principleDescription": "Evidence Over Intuition: Ground decisions in observable evidence",
119
+ "sessionId": "session-case-003",
120
+ "signalType": "gate_block",
121
+ "signalContext": "Agent proceeded with a tool call despite receiving a gate block",
122
+ "singleReflectorOutput": {
123
+ "artifactId": "single-003-artifact",
124
+ "sessionId": "session-case-003",
125
+ "principleId": "T-03",
126
+ "sourceSnapshotRef": "snapshot-case-003",
127
+ "badDecision": "Proceeded despite gate block",
128
+ "betterDecision": "Respect gate blocks",
129
+ "rationale": "Gate blocks are safety mechanisms",
130
+ "createdAt": "2026-03-28T00:03:00.000Z"
131
+ },
132
+ "trinityOutput": {
133
+ "selectedCandidateIndex": 0,
134
+ "badDecision": "Proceeded with a tool call despite receiving a gate block, bypassing the safety check",
135
+ "betterDecision": "Read the blocked operation documentation and obtain proper authorization before retrying the operation",
136
+ "rationale": "Respecting gate blocks prevents unintended system modifications and ensures alignment with operational constraints",
137
+ "sessionId": "session-case-003",
138
+ "principleId": "T-03",
139
+ "sourceSnapshotRef": "snapshot-case-003",
140
+ "telemetry": {
141
+ "chainMode": "trinity",
142
+ "dreamerPassed": true,
143
+ "philosopherPassed": true,
144
+ "scribePassed": true,
145
+ "candidateCount": 3,
146
+ "selectedCandidateIndex": 0,
147
+ "stageFailures": []
148
+ }
149
+ },
150
+ "qualityScores": {
151
+ "singleReflector": {
152
+ "specificity": 0.60,
153
+ "principleAlignment": 0.75,
154
+ "actionability": 0.65,
155
+ "rationaleQuality": 0.70,
156
+ "overall": 0.68
157
+ },
158
+ "trinity": {
159
+ "specificity": 0.90,
160
+ "principleAlignment": 0.95,
161
+ "actionability": 0.88,
162
+ "rationaleQuality": 0.92,
163
+ "overall": 0.91
164
+ }
165
+ },
166
+ "trinityWins": true,
167
+ "notes": "Single-reflector is too generic; Trinity is much more specific"
168
+ }
169
+ ],
170
+ "summary": {
171
+ "totalCases": 3,
172
+ "trinityWins": 3,
173
+ "singleReflectorWins": 0,
174
+ "averageDelta": {
175
+ "specificity": 0.23,
176
+ "principleAlignment": 0.10,
177
+ "actionability": 0.17,
178
+ "rationaleQuality": 0.17,
179
+ "overall": 0.19
180
+ },
181
+ "conclusion": "Trinity consistently outperforms single-reflector on reviewed subset"
182
+ }
183
+ }