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,888 @@
1
+ import { ControlUiDatabase } from '../core/control-ui-db.js';
2
+ import { getThinkingModel, listThinkingModels } from '../core/thinking-models.js';
3
+ import { WorkspaceContext } from '../core/workspace-context.js';
4
+
5
+ /** Time window (in minutes) for querying principle events related to a sample */
6
+ const PRINCIPLE_EVENT_WINDOW_MINUTES = 10;
7
+
8
+ export interface OverviewResponse {
9
+ workspaceDir: string;
10
+ generatedAt: string;
11
+ dataFreshness: string | null;
12
+ dataSource: 'trajectory_db_analytics';
13
+ runtimeControlPlaneSource: 'pd_evolution_status';
14
+ summary: {
15
+ repeatErrorRate: number;
16
+ userCorrectionRate: number;
17
+ pendingSamples: number;
18
+ approvedSamples: number;
19
+ thinkingCoverageRate: number;
20
+ painEvents: number;
21
+ principleEventCount: number;
22
+ gateBlocks: number;
23
+ taskOutcomes: number;
24
+ };
25
+ dailyTrend: Array<{
26
+ day: string;
27
+ toolCalls: number;
28
+ failures: number;
29
+ userCorrections: number;
30
+ thinkingTurns: number;
31
+ }>;
32
+ topRegressions: Array<{
33
+ toolName: string;
34
+ errorType: string;
35
+ occurrences: number;
36
+ }>;
37
+ sampleQueue: {
38
+ counters: Record<string, number>;
39
+ preview: Array<{
40
+ sampleId: string;
41
+ sessionId: string;
42
+ qualityScore: number;
43
+ reviewStatus: string;
44
+ createdAt: string;
45
+ }>;
46
+ };
47
+ thinkingSummary: {
48
+ activeModels: number;
49
+ dormantModels: number;
50
+ effectiveModels: number;
51
+ coverageRate: number;
52
+ };
53
+ }
54
+
55
+ export interface SampleListFilters {
56
+ status?: string;
57
+ qualityMin?: number;
58
+ dateFrom?: string;
59
+ dateTo?: string;
60
+ failureMode?: string;
61
+ page?: number;
62
+ pageSize?: number;
63
+ }
64
+
65
+ export interface SamplesResponse {
66
+ counters: Record<string, number>;
67
+ items: Array<{
68
+ sampleId: string;
69
+ sessionId: string;
70
+ reviewStatus: string;
71
+ qualityScore: number;
72
+ failureMode: string;
73
+ relatedThinkingCount: number;
74
+ createdAt: string;
75
+ updatedAt: string;
76
+ diffExcerpt: string;
77
+ }>;
78
+ pagination: {
79
+ page: number;
80
+ pageSize: number;
81
+ total: number;
82
+ totalPages: number;
83
+ };
84
+ }
85
+
86
+ export interface SampleDetailResponse {
87
+ sampleId: string;
88
+ sessionId: string;
89
+ reviewStatus: string;
90
+ qualityScore: number;
91
+ createdAt: string;
92
+ updatedAt: string;
93
+ badAttempt: {
94
+ assistantTurnId: number;
95
+ rawText: string;
96
+ sanitizedText: string;
97
+ createdAt: string;
98
+ };
99
+ userCorrection: {
100
+ userTurnId: number;
101
+ rawText: string;
102
+ correctionCue: string | null;
103
+ createdAt: string;
104
+ };
105
+ recoveryToolSpan: Array<{ id: number; toolName: string }>;
106
+ relatedPrinciples: Array<{
107
+ principleId: string | null;
108
+ eventType: string;
109
+ createdAt: string;
110
+ }>;
111
+ relatedThinkingHits: Array<{
112
+ id: number;
113
+ modelId: string;
114
+ modelName: string;
115
+ matchedPattern: string;
116
+ scenarios: string[];
117
+ createdAt: string;
118
+ triggerExcerpt: string;
119
+ }>;
120
+ reviewHistory: Array<{
121
+ reviewStatus: string;
122
+ note: string | null;
123
+ createdAt: string;
124
+ }>;
125
+ }
126
+
127
+ export interface ThinkingModelSummary {
128
+ modelId: string;
129
+ name: string;
130
+ description: string;
131
+ hits: number;
132
+ coverageRate: number;
133
+ successRate: number;
134
+ failureRate: number;
135
+ painRate: number;
136
+ correctionRate: number;
137
+ correctionSampleRate: number;
138
+ commonScenarios: string[];
139
+ recommendation: 'reinforce' | 'rework' | 'archive';
140
+ }
141
+
142
+ export interface ThinkingOverviewResponse {
143
+ summary: {
144
+ totalModels: number;
145
+ activeModels: number;
146
+ dormantModels: number;
147
+ effectiveModels: number;
148
+ coverageRate: number;
149
+ };
150
+ topModels: ThinkingModelSummary[];
151
+ dormantModels: Array<{
152
+ modelId: string;
153
+ name: string;
154
+ description: string;
155
+ }>;
156
+ effectiveModels: ThinkingModelSummary[];
157
+ scenarioMatrix: Array<{
158
+ modelId: string;
159
+ modelName: string;
160
+ scenario: string;
161
+ hits: number;
162
+ }>;
163
+ coverageTrend: Array<{
164
+ day: string;
165
+ assistantTurns: number;
166
+ thinkingTurns: number;
167
+ coverageRate: number;
168
+ }>;
169
+ }
170
+
171
+ export interface ThinkingModelDetailResponse {
172
+ modelMeta: {
173
+ modelId: string;
174
+ name: string;
175
+ description: string;
176
+ hits: number;
177
+ coverageRate: number;
178
+ recommendation: 'reinforce' | 'rework' | 'archive';
179
+ };
180
+ usageTrend: Array<{
181
+ day: string;
182
+ hits: number;
183
+ }>;
184
+ scenarioDistribution: Array<{
185
+ scenario: string;
186
+ hits: number;
187
+ }>;
188
+ outcomeStats: {
189
+ events: number;
190
+ successRate: number;
191
+ failureRate: number;
192
+ painRate: number;
193
+ correctionRate: number;
194
+ correctionSampleRate: number;
195
+ };
196
+ recentEvents: Array<{
197
+ id: number;
198
+ createdAt: string;
199
+ matchedPattern: string;
200
+ scenarios: string[];
201
+ triggerExcerpt: string;
202
+ toolContext: Array<{ toolName: string; outcome: string; errorType?: string | null }>;
203
+ painContext: Array<{ source: string; score: number }>;
204
+ principleContext: Array<{ principleId: string | null; eventType: string }>;
205
+ }>;
206
+ }
207
+
208
+ function parseJson<T>(raw: string | null | undefined, fallback: T): T {
209
+ if (!raw) return fallback;
210
+ try {
211
+ return JSON.parse(raw) as T;
212
+ } catch {
213
+ return fallback;
214
+ }
215
+ }
216
+
217
+ function roundRate(numerator: number, denominator: number): number {
218
+ if (!denominator) return 0;
219
+ return Number((numerator / denominator).toFixed(4));
220
+ }
221
+
222
+ function clampPageSize(input?: number): number {
223
+ if (!Number.isFinite(input)) return 20;
224
+ return Math.min(100, Math.max(1, Number(input)));
225
+ }
226
+
227
+ function summarizeRecommendation(model: {
228
+ hits: number;
229
+ successRate: number;
230
+ failureRate: number;
231
+ painRate: number;
232
+ correctionRate: number;
233
+ }): 'reinforce' | 'rework' | 'archive' {
234
+ if (model.hits === 0) return 'archive';
235
+ if (model.failureRate > model.successRate || model.correctionRate >= 0.35 || model.painRate >= 0.3) {
236
+ return 'rework';
237
+ }
238
+ return 'reinforce';
239
+ }
240
+
241
+ export class ControlUiQueryService {
242
+ private readonly workspaceDir: string;
243
+ private readonly trajectory;
244
+ private readonly uiDb: ControlUiDatabase;
245
+
246
+ constructor(workspaceDir: string) {
247
+ this.workspaceDir = workspaceDir;
248
+ this.trajectory = WorkspaceContext.fromHookContext({ workspaceDir }).trajectory;
249
+ this.uiDb = new ControlUiDatabase({ workspaceDir });
250
+ }
251
+
252
+ dispose(): void {
253
+ this.uiDb.dispose();
254
+ }
255
+
256
+ getOverview(days: number = 30): OverviewResponse {
257
+ const stats = this.trajectory.getDataStats();
258
+ const regressionRows = this.uiDb.all<{
259
+ tool_name: string;
260
+ error_type: string;
261
+ occurrences: number;
262
+ }>('SELECT tool_name, error_type, occurrences FROM v_error_clusters ORDER BY occurrences DESC LIMIT 5');
263
+ const failureStats = this.uiDb.get<{ total_failures: number; repeated_failures: number }>(`
264
+ SELECT
265
+ COALESCE(SUM(occurrences), 0) AS total_failures,
266
+ COALESCE(SUM(CASE WHEN occurrences > 1 THEN occurrences ELSE 0 END), 0) AS repeated_failures
267
+ FROM v_error_clusters
268
+ `) ?? { total_failures: 0, repeated_failures: 0 };
269
+ const correctionTotal = this.uiDb.get<{ count: number }>(
270
+ 'SELECT COUNT(*) AS count FROM user_turns WHERE correction_detected = 1',
271
+ )?.count ?? 0;
272
+ const principleEventCount = this.uiDb.get<{ count: number }>(
273
+ 'SELECT COUNT(*) AS count FROM principle_events',
274
+ )?.count ?? 0;
275
+ const gateBlockCount = this.uiDb.get<{ count: number }>(
276
+ 'SELECT COUNT(*) AS count FROM gate_blocks',
277
+ )?.count ?? 0;
278
+ const taskOutcomeCount = this.uiDb.get<{ count: number }>(
279
+ 'SELECT COUNT(*) AS count FROM task_outcomes',
280
+ )?.count ?? 0;
281
+ const sampleCounters = this.uiDb.all<{ review_status: string; total: number }>(
282
+ 'SELECT review_status, total FROM v_sample_queue',
283
+ );
284
+ const samplePreview = this.uiDb.all<{
285
+ sample_id: string;
286
+ session_id: string;
287
+ quality_score: number;
288
+ review_status: string;
289
+ created_at: string;
290
+ }>(`
291
+ SELECT sample_id, session_id, quality_score, review_status, created_at
292
+ FROM correction_samples
293
+ ORDER BY created_at DESC
294
+ LIMIT 5
295
+ `);
296
+ const coverageRow = this.uiDb.get<{ thinking_turns: number; assistant_turns: number }>(`
297
+ SELECT
298
+ COUNT(DISTINCT assistant_turn_id) AS thinking_turns,
299
+ (SELECT COUNT(*) FROM assistant_turns) AS assistant_turns
300
+ FROM thinking_model_events
301
+ `) ?? { thinking_turns: 0, assistant_turns: 0 };
302
+ const effectiveCount = this.uiDb.all<{
303
+ events: number;
304
+ success_windows: number;
305
+ failure_windows: number;
306
+ pain_windows: number;
307
+ correction_windows: number;
308
+ }>('SELECT events, success_windows, failure_windows, pain_windows, correction_windows FROM v_thinking_model_effectiveness')
309
+ .filter((row) => summarizeRecommendation({
310
+ hits: Number(row.events),
311
+ successRate: roundRate(Number(row.success_windows), Number(row.events)),
312
+ failureRate: roundRate(Number(row.failure_windows), Number(row.events)),
313
+ painRate: roundRate(Number(row.pain_windows), Number(row.events)),
314
+ correctionRate: roundRate(Number(row.correction_windows), Number(row.events)),
315
+ }) === 'reinforce').length;
316
+ const dailyTrend = this.uiDb.all<{
317
+ day: string;
318
+ tool_calls: number;
319
+ failures: number;
320
+ user_corrections: number;
321
+ thinking_turns: number;
322
+ }>(`
323
+ WITH thinking_daily AS (
324
+ SELECT substr(created_at, 1, 10) AS day, COUNT(DISTINCT assistant_turn_id) AS thinking_turns
325
+ FROM thinking_model_events
326
+ GROUP BY substr(created_at, 1, 10)
327
+ )
328
+ SELECT
329
+ dm.day AS day,
330
+ dm.tool_calls AS tool_calls,
331
+ dm.failures AS failures,
332
+ dm.user_corrections AS user_corrections,
333
+ COALESCE(td.thinking_turns, 0) AS thinking_turns
334
+ FROM v_daily_metrics dm
335
+ LEFT JOIN thinking_daily td ON td.day = dm.day
336
+ ORDER BY dm.day DESC
337
+ LIMIT ?
338
+ `, days).reverse();
339
+ const counters = Object.fromEntries(sampleCounters.map((row) => [row.review_status, Number(row.total)]));
340
+ const activeModels = this.uiDb.get<{ count: number }>(
341
+ 'SELECT COUNT(DISTINCT model_id) AS count FROM thinking_model_events',
342
+ )?.count ?? 0;
343
+
344
+ return {
345
+ workspaceDir: this.workspaceDir,
346
+ generatedAt: new Date().toISOString(),
347
+ dataFreshness: stats.lastIngestAt,
348
+ dataSource: 'trajectory_db_analytics',
349
+ runtimeControlPlaneSource: 'pd_evolution_status',
350
+ summary: {
351
+ repeatErrorRate: roundRate(Number(failureStats.repeated_failures), Number(failureStats.total_failures)),
352
+ userCorrectionRate: roundRate(correctionTotal, stats.userTurns),
353
+ pendingSamples: stats.pendingSamples,
354
+ approvedSamples: stats.approvedSamples,
355
+ thinkingCoverageRate: roundRate(coverageRow.thinking_turns, coverageRow.assistant_turns),
356
+ painEvents: stats.painEvents,
357
+ principleEventCount,
358
+ gateBlocks: Number(gateBlockCount),
359
+ taskOutcomes: Number(taskOutcomeCount),
360
+ },
361
+ dailyTrend: dailyTrend.map((row) => ({
362
+ day: row.day,
363
+ toolCalls: Number(row.tool_calls),
364
+ failures: Number(row.failures),
365
+ userCorrections: Number(row.user_corrections),
366
+ thinkingTurns: Number(row.thinking_turns),
367
+ })),
368
+ topRegressions: regressionRows.map((row) => ({
369
+ toolName: row.tool_name,
370
+ errorType: row.error_type,
371
+ occurrences: Number(row.occurrences),
372
+ })),
373
+ sampleQueue: {
374
+ counters,
375
+ preview: samplePreview.map((row) => ({
376
+ sampleId: row.sample_id,
377
+ sessionId: row.session_id,
378
+ qualityScore: Number(row.quality_score),
379
+ reviewStatus: row.review_status,
380
+ createdAt: row.created_at,
381
+ })),
382
+ },
383
+ thinkingSummary: {
384
+ activeModels,
385
+ dormantModels: Math.max(0, listThinkingModels().length - activeModels),
386
+ effectiveModels: effectiveCount,
387
+ coverageRate: roundRate(coverageRow.thinking_turns, coverageRow.assistant_turns),
388
+ },
389
+ };
390
+ }
391
+
392
+ listSamples(filters: SampleListFilters = {}): SamplesResponse {
393
+ const page = Math.max(1, Number(filters.page ?? 1));
394
+ const pageSize = clampPageSize(filters.pageSize);
395
+ const offset = (page - 1) * pageSize;
396
+ const where: string[] = [];
397
+ const params: unknown[] = [];
398
+
399
+ if (filters.status && filters.status !== 'all') {
400
+ where.push('cs.review_status = ?');
401
+ params.push(filters.status);
402
+ }
403
+ if (Number.isFinite(filters.qualityMin)) {
404
+ where.push('cs.quality_score >= ?');
405
+ params.push(Number(filters.qualityMin));
406
+ }
407
+ if (filters.dateFrom) {
408
+ where.push('cs.created_at >= ?');
409
+ params.push(filters.dateFrom);
410
+ }
411
+ if (filters.dateTo) {
412
+ where.push('cs.created_at <= ?');
413
+ params.push(filters.dateTo);
414
+ }
415
+ if (filters.failureMode) {
416
+ where.push(`
417
+ COALESCE(
418
+ (
419
+ SELECT COALESCE(tc.error_type, tc.tool_name)
420
+ FROM tool_calls tc
421
+ WHERE tc.session_id = cs.session_id
422
+ AND tc.outcome = 'failure'
423
+ AND tc.created_at <= ut.created_at
424
+ ORDER BY tc.created_at DESC
425
+ LIMIT 1
426
+ ),
427
+ 'unknown'
428
+ ) = ?
429
+ `);
430
+ params.push(filters.failureMode);
431
+ }
432
+
433
+ const whereClause = where.length > 0 ? `WHERE ${where.join(' AND ')}` : '';
434
+ const total = Number(this.uiDb.get<{ count: number }>(`
435
+ SELECT COUNT(*) AS count
436
+ FROM correction_samples cs
437
+ JOIN user_turns ut ON ut.id = cs.user_correction_turn_id
438
+ ${whereClause}
439
+ `, ...params)?.count ?? 0);
440
+
441
+ const items = this.uiDb.all<{
442
+ sample_id: string;
443
+ session_id: string;
444
+ review_status: string;
445
+ quality_score: number;
446
+ created_at: string;
447
+ updated_at: string;
448
+ diff_excerpt: string;
449
+ failure_mode: string;
450
+ related_thinking_count: number;
451
+ }>(`
452
+ SELECT
453
+ cs.sample_id,
454
+ cs.session_id,
455
+ cs.review_status,
456
+ cs.quality_score,
457
+ cs.created_at,
458
+ cs.updated_at,
459
+ cs.diff_excerpt,
460
+ COALESCE(
461
+ (
462
+ SELECT COALESCE(tc.error_type, tc.tool_name)
463
+ FROM tool_calls tc
464
+ WHERE tc.session_id = cs.session_id
465
+ AND tc.outcome = 'failure'
466
+ AND tc.created_at <= ut.created_at
467
+ ORDER BY tc.created_at DESC
468
+ LIMIT 1
469
+ ),
470
+ 'unknown'
471
+ ) AS failure_mode,
472
+ (
473
+ SELECT COUNT(*)
474
+ FROM thinking_model_events tme
475
+ JOIN assistant_turns at2 ON at2.id = cs.bad_assistant_turn_id
476
+ WHERE tme.session_id = cs.session_id
477
+ AND tme.created_at >= at2.created_at
478
+ AND tme.created_at <= ut.created_at
479
+ ) AS related_thinking_count
480
+ FROM correction_samples cs
481
+ JOIN user_turns ut ON ut.id = cs.user_correction_turn_id
482
+ ${whereClause}
483
+ ORDER BY cs.created_at DESC
484
+ LIMIT ? OFFSET ?
485
+ `, ...params, pageSize, offset);
486
+ const counters = this.uiDb.all<{ review_status: string; count: number }>(`
487
+ SELECT review_status, COUNT(*) AS count
488
+ FROM correction_samples
489
+ GROUP BY review_status
490
+ `);
491
+
492
+ return {
493
+ counters: Object.fromEntries(counters.map((row) => [row.review_status, Number(row.count)])),
494
+ items: items.map((row) => ({
495
+ sampleId: row.sample_id,
496
+ sessionId: row.session_id,
497
+ reviewStatus: row.review_status,
498
+ qualityScore: Number(row.quality_score),
499
+ failureMode: row.failure_mode,
500
+ relatedThinkingCount: Number(row.related_thinking_count),
501
+ createdAt: row.created_at,
502
+ updatedAt: row.updated_at,
503
+ diffExcerpt: row.diff_excerpt,
504
+ })),
505
+ pagination: {
506
+ page,
507
+ pageSize,
508
+ total,
509
+ totalPages: total === 0 ? 0 : Math.ceil(total / pageSize),
510
+ },
511
+ };
512
+ }
513
+
514
+ getSampleDetail(sampleId: string): SampleDetailResponse | null {
515
+ const row = this.uiDb.get<{
516
+ sample_id: string;
517
+ session_id: string;
518
+ review_status: string;
519
+ quality_score: number;
520
+ created_at: string;
521
+ updated_at: string;
522
+ recovery_tool_span_json: string;
523
+ principle_ids_json: string;
524
+ bad_turn_id: number;
525
+ bad_raw_text: string | null;
526
+ bad_blob_ref: string | null;
527
+ bad_sanitized_text: string;
528
+ bad_created_at: string;
529
+ user_turn_id: number;
530
+ user_raw_text: string | null;
531
+ user_blob_ref: string | null;
532
+ user_correction_cue: string | null;
533
+ user_created_at: string;
534
+ }>(`
535
+ SELECT
536
+ cs.sample_id,
537
+ cs.session_id,
538
+ cs.review_status,
539
+ cs.quality_score,
540
+ cs.created_at,
541
+ cs.updated_at,
542
+ cs.recovery_tool_span_json,
543
+ cs.principle_ids_json,
544
+ at.id AS bad_turn_id,
545
+ at.raw_text AS bad_raw_text,
546
+ at.blob_ref AS bad_blob_ref,
547
+ at.sanitized_text AS bad_sanitized_text,
548
+ at.created_at AS bad_created_at,
549
+ ut.id AS user_turn_id,
550
+ ut.raw_text AS user_raw_text,
551
+ ut.blob_ref AS user_blob_ref,
552
+ ut.correction_cue AS user_correction_cue,
553
+ ut.created_at AS user_created_at
554
+ FROM correction_samples cs
555
+ JOIN assistant_turns at ON at.id = cs.bad_assistant_turn_id
556
+ JOIN user_turns ut ON ut.id = cs.user_correction_turn_id
557
+ WHERE cs.sample_id = ?
558
+ `, sampleId);
559
+ if (!row) return null;
560
+
561
+ const reviewHistory = this.uiDb.all<{
562
+ review_status: string;
563
+ note: string | null;
564
+ created_at: string;
565
+ }>(`
566
+ SELECT review_status, note, created_at
567
+ FROM sample_reviews
568
+ WHERE sample_id = ?
569
+ ORDER BY created_at DESC
570
+ `, sampleId);
571
+ const relatedThinkingHits = this.uiDb.all<{
572
+ id: number;
573
+ model_id: string;
574
+ matched_pattern: string;
575
+ scenario_json: string;
576
+ created_at: string;
577
+ trigger_excerpt: string;
578
+ }>(`
579
+ SELECT id, model_id, matched_pattern, scenario_json, created_at, trigger_excerpt
580
+ FROM thinking_model_events
581
+ WHERE session_id = ?
582
+ AND created_at >= ?
583
+ AND created_at <= ?
584
+ ORDER BY created_at DESC
585
+ LIMIT 20
586
+ `, row.session_id, row.bad_created_at, row.user_created_at);
587
+ const relatedPrinciples = this.uiDb.all<{
588
+ principle_id: string | null;
589
+ event_type: string;
590
+ created_at: string;
591
+ }>(`
592
+ SELECT principle_id, event_type, created_at
593
+ FROM principle_events
594
+ WHERE created_at >= ?
595
+ AND created_at <= datetime(?, '+' || ? || ' minutes')
596
+ ORDER BY created_at DESC
597
+ LIMIT 20
598
+ `, row.bad_created_at, row.user_created_at, PRINCIPLE_EVENT_WINDOW_MINUTES);
599
+ const seededPrincipleIds = parseJson<string[]>(row.principle_ids_json, []).map((principleId) => ({
600
+ principleId,
601
+ eventType: 'seeded_from_sample',
602
+ createdAt: row.created_at,
603
+ }));
604
+
605
+ return {
606
+ sampleId: row.sample_id,
607
+ sessionId: row.session_id,
608
+ reviewStatus: row.review_status,
609
+ qualityScore: Number(row.quality_score),
610
+ createdAt: row.created_at,
611
+ updatedAt: row.updated_at,
612
+ badAttempt: {
613
+ assistantTurnId: Number(row.bad_turn_id),
614
+ rawText: this.uiDb.restoreRawText(row.bad_raw_text, row.bad_blob_ref),
615
+ sanitizedText: row.bad_sanitized_text,
616
+ createdAt: row.bad_created_at,
617
+ },
618
+ userCorrection: {
619
+ userTurnId: Number(row.user_turn_id),
620
+ rawText: this.uiDb.restoreRawText(row.user_raw_text, row.user_blob_ref),
621
+ correctionCue: row.user_correction_cue,
622
+ createdAt: row.user_created_at,
623
+ },
624
+ recoveryToolSpan: parseJson<Array<{ id: number; toolName: string }>>(row.recovery_tool_span_json, []),
625
+ relatedPrinciples: [
626
+ ...seededPrincipleIds,
627
+ ...relatedPrinciples.map((item) => ({
628
+ principleId: item.principle_id,
629
+ eventType: item.event_type,
630
+ createdAt: item.created_at,
631
+ })),
632
+ ],
633
+ relatedThinkingHits: relatedThinkingHits.map((item) => ({
634
+ id: Number(item.id),
635
+ modelId: item.model_id,
636
+ modelName: getThinkingModel(item.model_id)?.name ?? item.model_id,
637
+ matchedPattern: item.matched_pattern,
638
+ scenarios: parseJson<string[]>(item.scenario_json, []),
639
+ createdAt: item.created_at,
640
+ triggerExcerpt: item.trigger_excerpt,
641
+ })),
642
+ reviewHistory: reviewHistory.map((item) => ({
643
+ reviewStatus: item.review_status,
644
+ note: item.note,
645
+ createdAt: item.created_at,
646
+ })),
647
+ };
648
+ }
649
+
650
+ reviewSample(sampleId: string, decision: 'approved' | 'rejected', note?: string) {
651
+ return this.trajectory.reviewCorrectionSample(sampleId, decision, note);
652
+ }
653
+
654
+ exportCorrections(mode: 'raw' | 'redacted') {
655
+ return this.trajectory.exportCorrections({ mode, approvedOnly: true });
656
+ }
657
+
658
+ getThinkingOverview(): ThinkingOverviewResponse {
659
+ const topModels = this.loadThinkingModelSummaries();
660
+ const knownModels = listThinkingModels();
661
+ const activeIds = new Set(topModels.filter((model) => model.hits > 0).map((model) => model.modelId));
662
+ const dormantModels = knownModels
663
+ .filter((model) => !activeIds.has(model.id))
664
+ .map((model) => ({
665
+ modelId: model.id,
666
+ name: model.name,
667
+ description: model.description,
668
+ }));
669
+ const coverageRow = this.uiDb.get<{ thinking_turns: number; assistant_turns: number }>(`
670
+ SELECT
671
+ COUNT(DISTINCT assistant_turn_id) AS thinking_turns,
672
+ (SELECT COUNT(*) FROM assistant_turns) AS assistant_turns
673
+ FROM thinking_model_events
674
+ `) ?? { thinking_turns: 0, assistant_turns: 0 };
675
+ const coverageTrend = this.uiDb.all<{
676
+ day: string;
677
+ assistant_turns: number;
678
+ thinking_turns: number;
679
+ }>(`
680
+ WITH assistant_daily AS (
681
+ SELECT substr(created_at, 1, 10) AS day, COUNT(*) AS assistant_turns
682
+ FROM assistant_turns
683
+ GROUP BY substr(created_at, 1, 10)
684
+ ),
685
+ thinking_daily AS (
686
+ SELECT substr(created_at, 1, 10) AS day, COUNT(DISTINCT assistant_turn_id) AS thinking_turns
687
+ FROM thinking_model_events
688
+ GROUP BY substr(created_at, 1, 10)
689
+ )
690
+ SELECT
691
+ assistant_daily.day AS day,
692
+ assistant_daily.assistant_turns AS assistant_turns,
693
+ COALESCE(thinking_daily.thinking_turns, 0) AS thinking_turns
694
+ FROM assistant_daily
695
+ LEFT JOIN thinking_daily ON thinking_daily.day = assistant_daily.day
696
+ ORDER BY assistant_daily.day ASC
697
+ `);
698
+ const scenarioMatrix = this.uiDb.all<{
699
+ model_id: string;
700
+ scenario: string;
701
+ hits: number;
702
+ }>('SELECT model_id, scenario, hits FROM v_thinking_model_scenarios ORDER BY hits DESC, model_id ASC');
703
+
704
+ return {
705
+ summary: {
706
+ totalModels: knownModels.length,
707
+ activeModels: activeIds.size,
708
+ dormantModels: dormantModels.length,
709
+ effectiveModels: topModels.filter((model) => model.recommendation === 'reinforce').length,
710
+ coverageRate: roundRate(coverageRow.thinking_turns, coverageRow.assistant_turns),
711
+ },
712
+ topModels,
713
+ dormantModels,
714
+ effectiveModels: topModels.filter((model) => model.recommendation === 'reinforce'),
715
+ scenarioMatrix: scenarioMatrix.map((row) => ({
716
+ modelId: row.model_id,
717
+ modelName: getThinkingModel(row.model_id)?.name ?? row.model_id,
718
+ scenario: row.scenario,
719
+ hits: Number(row.hits),
720
+ })),
721
+ coverageTrend: coverageTrend.map((row) => ({
722
+ day: row.day,
723
+ assistantTurns: Number(row.assistant_turns),
724
+ thinkingTurns: Number(row.thinking_turns),
725
+ coverageRate: roundRate(Number(row.thinking_turns), Number(row.assistant_turns)),
726
+ })),
727
+ };
728
+ }
729
+
730
+ getThinkingModelDetail(modelId: string): ThinkingModelDetailResponse | null {
731
+ if (!getThinkingModel(modelId)) {
732
+ return null;
733
+ }
734
+
735
+ const summary = this.loadThinkingModelSummaries().find((item) => item.modelId === modelId) ?? {
736
+ modelId,
737
+ name: getThinkingModel(modelId)?.name ?? modelId,
738
+ description: getThinkingModel(modelId)?.description ?? 'Unknown thinking model.',
739
+ hits: 0,
740
+ coverageRate: 0,
741
+ successRate: 0,
742
+ failureRate: 0,
743
+ painRate: 0,
744
+ correctionRate: 0,
745
+ correctionSampleRate: 0,
746
+ commonScenarios: [],
747
+ recommendation: 'archive' as const,
748
+ };
749
+ const usageTrend = this.uiDb.all<{ day: string; hits: number }>(`
750
+ SELECT day, hits
751
+ FROM v_thinking_model_daily_trend
752
+ WHERE model_id = ?
753
+ ORDER BY day ASC
754
+ `, modelId);
755
+ const scenarioDistribution = this.uiDb.all<{ scenario: string; hits: number }>(`
756
+ SELECT scenario, hits
757
+ FROM v_thinking_model_scenarios
758
+ WHERE model_id = ?
759
+ ORDER BY hits DESC, scenario ASC
760
+ `, modelId);
761
+ const effect = this.uiDb.get<{
762
+ events: number;
763
+ success_windows: number;
764
+ failure_windows: number;
765
+ pain_windows: number;
766
+ correction_windows: number;
767
+ correction_sample_windows: number;
768
+ }>('SELECT * FROM v_thinking_model_effectiveness WHERE model_id = ?', modelId) ?? {
769
+ events: 0,
770
+ success_windows: 0,
771
+ failure_windows: 0,
772
+ pain_windows: 0,
773
+ correction_windows: 0,
774
+ correction_sample_windows: 0,
775
+ };
776
+ const recentEvents = this.uiDb.all<{
777
+ id: number;
778
+ created_at: string;
779
+ matched_pattern: string;
780
+ scenario_json: string;
781
+ trigger_excerpt: string;
782
+ tool_context_json: string;
783
+ pain_context_json: string;
784
+ principle_context_json: string;
785
+ }>(`
786
+ SELECT id, created_at, matched_pattern, scenario_json, trigger_excerpt,
787
+ tool_context_json, pain_context_json, principle_context_json
788
+ FROM thinking_model_events
789
+ WHERE model_id = ?
790
+ ORDER BY created_at DESC
791
+ LIMIT 20
792
+ `, modelId);
793
+
794
+ return {
795
+ modelMeta: {
796
+ modelId: summary.modelId,
797
+ name: summary.name,
798
+ description: summary.description,
799
+ hits: summary.hits,
800
+ coverageRate: summary.coverageRate,
801
+ recommendation: summary.recommendation,
802
+ },
803
+ usageTrend: usageTrend.map((row) => ({
804
+ day: row.day,
805
+ hits: Number(row.hits),
806
+ })),
807
+ scenarioDistribution: scenarioDistribution.map((row) => ({
808
+ scenario: row.scenario,
809
+ hits: Number(row.hits),
810
+ })),
811
+ outcomeStats: {
812
+ events: Number(effect.events),
813
+ successRate: roundRate(Number(effect.success_windows), Number(effect.events)),
814
+ failureRate: roundRate(Number(effect.failure_windows), Number(effect.events)),
815
+ painRate: roundRate(Number(effect.pain_windows), Number(effect.events)),
816
+ correctionRate: roundRate(Number(effect.correction_windows), Number(effect.events)),
817
+ correctionSampleRate: roundRate(Number(effect.correction_sample_windows), Number(effect.events)),
818
+ },
819
+ recentEvents: recentEvents.map((row) => ({
820
+ id: Number(row.id),
821
+ createdAt: row.created_at,
822
+ matchedPattern: row.matched_pattern,
823
+ scenarios: parseJson<string[]>(row.scenario_json, []),
824
+ triggerExcerpt: row.trigger_excerpt,
825
+ toolContext: parseJson<Array<{ toolName: string; outcome: string; errorType?: string | null }>>(row.tool_context_json, []),
826
+ painContext: parseJson<Array<{ source: string; score: number }>>(row.pain_context_json, []),
827
+ principleContext: parseJson<Array<{ principleId: string | null; eventType: string }>>(row.principle_context_json, []),
828
+ })),
829
+ };
830
+ }
831
+
832
+ private loadThinkingModelSummaries(): ThinkingModelSummary[] {
833
+ const knownModels = listThinkingModels();
834
+ const usageRows = new Map(this.uiDb.all<{
835
+ model_id: string;
836
+ hits: number;
837
+ coverage_rate: number;
838
+ }>('SELECT model_id, hits, coverage_rate FROM v_thinking_model_usage').map((row) => [row.model_id, row]));
839
+ const effectRows = new Map(this.uiDb.all<{
840
+ model_id: string;
841
+ events: number;
842
+ success_windows: number;
843
+ failure_windows: number;
844
+ pain_windows: number;
845
+ correction_windows: number;
846
+ correction_sample_windows: number;
847
+ }>('SELECT * FROM v_thinking_model_effectiveness').map((row) => [row.model_id, row]));
848
+ const scenarioRows = this.uiDb.all<{
849
+ model_id: string;
850
+ scenario: string;
851
+ hits: number;
852
+ }>('SELECT model_id, scenario, hits FROM v_thinking_model_scenarios ORDER BY hits DESC');
853
+
854
+ return knownModels.map((model) => {
855
+ const usage = usageRows.get(model.id);
856
+ const effect = effectRows.get(model.id);
857
+ const events = Number(effect?.events ?? usage?.hits ?? 0);
858
+ const successRate = roundRate(Number(effect?.success_windows ?? 0), events);
859
+ const failureRate = roundRate(Number(effect?.failure_windows ?? 0), events);
860
+ const painRate = roundRate(Number(effect?.pain_windows ?? 0), events);
861
+ const correctionRate = roundRate(Number(effect?.correction_windows ?? 0), events);
862
+ const correctionSampleRate = roundRate(Number(effect?.correction_sample_windows ?? 0), events);
863
+ return {
864
+ modelId: model.id,
865
+ name: model.name,
866
+ description: model.description,
867
+ hits: Number(usage?.hits ?? 0),
868
+ coverageRate: Number(usage?.coverage_rate ?? 0),
869
+ successRate,
870
+ failureRate,
871
+ painRate,
872
+ correctionRate,
873
+ correctionSampleRate,
874
+ commonScenarios: scenarioRows
875
+ .filter((row) => row.model_id === model.id)
876
+ .slice(0, 3)
877
+ .map((row) => row.scenario),
878
+ recommendation: summarizeRecommendation({
879
+ hits: Number(usage?.hits ?? 0),
880
+ successRate,
881
+ failureRate,
882
+ painRate,
883
+ correctionRate,
884
+ }),
885
+ };
886
+ }).sort((left, right) => right.hits - left.hits || left.modelId.localeCompare(right.modelId));
887
+ }
888
+ }