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,534 @@
1
+ /**
2
+ * Shadow Observation Registry — Runtime Shadow Evidence for Promotion Gate
3
+ * =======================================================================
4
+ *
5
+ * PURPOSE: Track real-world runtime evidence from shadow deployments to inform
6
+ * promotion gate decisions. Real evidence replaces eval verdict proxies.
7
+ *
8
+ * ARCHITECTURE:
9
+ * - Shadow observations are recorded by the routing system when a checkpoint
10
+ * is routed in shadow mode
11
+ * - Each observation captures whether the routing decision was accepted,
12
+ * rejected, or escalated by the runtime
13
+ * - The promotion gate queries this registry to get real arbiter/executability
14
+ * reject rates instead of using eval verdict as a proxy
15
+ *
16
+ * SHADOW OBSERVATION LIFECYCLE:
17
+ * 1. Routing system routes task to shadow checkpoint (shadow_ready state)
18
+ * 2. Observation recorded: { checkpointId, taskFingerprint, routedAt }
19
+ * 3. Task completes or times out
20
+ * 4. Observation updated: { completedAt, accepted/rejected/escalated, failureSignals }
21
+ * 5. After sufficient observations, promotion gate can query real reject rates
22
+ *
23
+ * DATA RETENTION:
24
+ * - Observations are kept for 7 days by default
25
+ * - Can be queried by checkpointId, time window, or outcome
26
+ *
27
+ * DESIGN CONSTRAINTS:
28
+ * - Fail-closed: if no shadow evidence exists, fall back to eval proxies
29
+ * - Shadow evidence must be statistically significant (min sample size)
30
+ * - Observations are retained until cleanup removes expired entries
31
+ */
32
+
33
+ import * as fs from 'fs';
34
+ import * as path from 'path';
35
+ import * as crypto from 'crypto';
36
+ import { withLock } from '../utils/file-lock.js';
37
+
38
+ // ---------------------------------------------------------------------------
39
+ // Constants
40
+ // ---------------------------------------------------------------------------
41
+
42
+ /**
43
+ * Registry file for shadow observations.
44
+ */
45
+ const SHADOW_REGISTRY_FILE = 'shadow-registry.json';
46
+
47
+ /**
48
+ * Default observation retention period in milliseconds.
49
+ * 7 days
50
+ */
51
+ export const DEFAULT_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
52
+
53
+ /**
54
+ * Minimum number of shadow observations required before trusting the evidence.
55
+ * Below this, we fall back to eval proxies.
56
+ */
57
+ export const MIN_OBSERVATIONS_FOR_TRUST = 5;
58
+
59
+ /**
60
+ * Time window for computing recent reject rates.
61
+ * Only observations within this window are considered.
62
+ * 24 hours
63
+ */
64
+ export const RECENT_WINDOW_MS = 24 * 60 * 60 * 1000;
65
+
66
+ // ---------------------------------------------------------------------------
67
+ // Types
68
+ // ---------------------------------------------------------------------------
69
+
70
+ /**
71
+ * Outcome of a shadow routing observation.
72
+ */
73
+ export type ShadowOutcome = 'accepted' | 'rejected' | 'escalated';
74
+
75
+ /**
76
+ * Runtime failure signals captured during shadow routing.
77
+ */
78
+ export interface RuntimeFailureSignals {
79
+ /** Whether the task timed out */
80
+ timedOut: boolean;
81
+
82
+ /** Whether an exception was thrown */
83
+ threwException: boolean;
84
+
85
+ /** Whether the output was empty or invalid */
86
+ invalidOutput: boolean;
87
+
88
+ /** Whether the worker profile rejected the routing */
89
+ profileRejected: boolean;
90
+
91
+ /** Additional failure signals (free-form for extensibility) */
92
+ extra: Record<string, boolean>;
93
+ }
94
+
95
+ /**
96
+ * A shadow observation — records a single shadow routing event.
97
+ */
98
+ export interface ShadowObservation {
99
+ /** Unique identifier for this observation */
100
+ observationId: string;
101
+
102
+ /** Checkpoint being routed to in shadow mode */
103
+ checkpointId: string;
104
+
105
+ /** Worker profile this observation is for */
106
+ workerProfile: string;
107
+
108
+ /** Task fingerprint (hash of task input for deduplication) */
109
+ taskFingerprint: string;
110
+
111
+ /** ISO-8601 timestamp when routing decision was made */
112
+ routedAt: string;
113
+
114
+ /** ISO-8601 timestamp when task completed (null if still pending) */
115
+ completedAt?: string;
116
+
117
+ /** Outcome of the shadow routing */
118
+ outcome?: ShadowOutcome;
119
+
120
+ /** Runtime failure signals (null if still pending) */
121
+ failureSignals?: RuntimeFailureSignals;
122
+
123
+ /** Whether this observation was used in a promotion gate evaluation */
124
+ usedInGate?: boolean;
125
+ }
126
+
127
+ /**
128
+ * Computed statistics from shadow observations.
129
+ */
130
+ export interface ShadowStats {
131
+ /** Checkpoint ID these stats are for */
132
+ checkpointId: string;
133
+
134
+ /** Total observations in the time window */
135
+ totalCount: number;
136
+
137
+ /** Count by outcome */
138
+ acceptedCount: number;
139
+ rejectedCount: number;
140
+ escalatedCount: number;
141
+
142
+ /** Computed rates */
143
+ rejectRate: number; // rejected / totalCount
144
+ escalationRate: number; // escalated / totalCount
145
+ acceptanceRate: number; // accepted / totalCount
146
+
147
+ /** Failure signal frequencies */
148
+ timedOutRate: number;
149
+ threwExceptionRate: number;
150
+ invalidOutputRate: number;
151
+ profileRejectedRate: number;
152
+
153
+ /** Whether this has enough data to trust */
154
+ isStatisticallySignificant: boolean;
155
+
156
+ /** Time window used for computation */
157
+ windowStart: string;
158
+ windowEnd: string;
159
+ }
160
+
161
+ /**
162
+ * The complete shadow registry.
163
+ */
164
+ export interface ShadowRegistry {
165
+ observations: ShadowObservation[];
166
+
167
+ /** Schema version for migration support */
168
+ version: number;
169
+ }
170
+
171
+ // ---------------------------------------------------------------------------
172
+ // Registry Path
173
+ // ---------------------------------------------------------------------------
174
+
175
+ function getRegistryPath(stateDir: string): string {
176
+ return path.join(stateDir, SHADOW_REGISTRY_FILE);
177
+ }
178
+
179
+ /**
180
+ * Ensure the registry directory exists.
181
+ */
182
+ function ensureRegistryDir(stateDir: string): void {
183
+ const registryPath = getRegistryPath(stateDir);
184
+ const dir = path.dirname(registryPath);
185
+ if (!fs.existsSync(dir)) {
186
+ fs.mkdirSync(dir, { recursive: true });
187
+ }
188
+ }
189
+
190
+ // ---------------------------------------------------------------------------
191
+ // File Operations
192
+ // ---------------------------------------------------------------------------
193
+
194
+ /**
195
+ * Read the registry from disk. Returns empty registry if missing.
196
+ */
197
+ function readRegistry(stateDir: string): ShadowRegistry {
198
+ const registryPath = getRegistryPath(stateDir);
199
+ if (!fs.existsSync(registryPath)) {
200
+ return { observations: [], version: 1 };
201
+ }
202
+ try {
203
+ const content = fs.readFileSync(registryPath, 'utf-8');
204
+ return JSON.parse(content) as ShadowRegistry;
205
+ } catch (err) {
206
+ console.warn(`[shadow-observation-registry] Registry corrupted at ${registryPath}, recovering with empty state: ${String(err)}`);
207
+ return { observations: [], version: 1 };
208
+ }
209
+ }
210
+
211
+ /**
212
+ * Write the registry to disk atomically.
213
+ */
214
+ function writeRegistry(stateDir: string, registry: ShadowRegistry): void {
215
+ ensureRegistryDir(stateDir);
216
+ const registryPath = getRegistryPath(stateDir);
217
+ const tmpPath = `${registryPath}.tmp`;
218
+ fs.writeFileSync(tmpPath, JSON.stringify(registry, null, 2), 'utf-8');
219
+ fs.renameSync(tmpPath, registryPath);
220
+ }
221
+
222
+ /**
223
+ * Execute a read-modify-write under an exclusive file lock.
224
+ */
225
+ function withShadowRegistryLock<T>(
226
+ stateDir: string,
227
+ fn: (registry: ShadowRegistry) => T
228
+ ): T {
229
+ const registryPath = getRegistryPath(stateDir);
230
+ return withLock(registryPath, () => {
231
+ const registry = readRegistry(stateDir);
232
+ return fn(registry);
233
+ });
234
+ }
235
+
236
+ // ---------------------------------------------------------------------------
237
+ // Observation Recording
238
+ // ---------------------------------------------------------------------------
239
+
240
+ /**
241
+ * Parameters for recording a shadow routing observation.
242
+ */
243
+ export interface RecordObservationParams {
244
+ /** Checkpoint being routed to in shadow mode */
245
+ checkpointId: string;
246
+
247
+ /** Worker profile */
248
+ workerProfile: string;
249
+
250
+ /** Task fingerprint for deduplication */
251
+ taskFingerprint: string;
252
+
253
+ /** ISO-8601 timestamp when routing decision was made */
254
+ routedAt?: string;
255
+ }
256
+
257
+ /**
258
+ * Record a new shadow observation (when task is routed to shadow checkpoint).
259
+ *
260
+ * @param stateDir - Workspace state directory
261
+ * @param params - Observation parameters
262
+ * @returns The created ShadowObservation
263
+ */
264
+ export function recordShadowRouting(
265
+ stateDir: string,
266
+ params: RecordObservationParams
267
+ ): ShadowObservation {
268
+ const observation: ShadowObservation = {
269
+ observationId: crypto.randomUUID(),
270
+ checkpointId: params.checkpointId,
271
+ workerProfile: params.workerProfile,
272
+ taskFingerprint: params.taskFingerprint,
273
+ routedAt: params.routedAt ?? new Date().toISOString(),
274
+ };
275
+
276
+ return withShadowRegistryLock(stateDir, (registry) => {
277
+ registry.observations.push(observation);
278
+ writeRegistry(stateDir, registry);
279
+ return observation;
280
+ });
281
+ }
282
+
283
+ /**
284
+ * Parameters for completing a shadow observation.
285
+ */
286
+ export interface CompleteObservationParams {
287
+ /** Observation ID to complete */
288
+ observationId: string;
289
+
290
+ /** Outcome of the shadow routing */
291
+ outcome: ShadowOutcome;
292
+
293
+ /** Runtime failure signals */
294
+ failureSignals?: RuntimeFailureSignals;
295
+ }
296
+
297
+ /**
298
+ * Complete a pending shadow observation (when task finishes).
299
+ *
300
+ * @param stateDir - Workspace state directory
301
+ * @param params - Completion parameters
302
+ * @returns The updated ShadowObservation, or null if not found
303
+ */
304
+ export function completeShadowObservation(
305
+ stateDir: string,
306
+ params: CompleteObservationParams
307
+ ): ShadowObservation | null {
308
+ return withShadowRegistryLock(stateDir, (registry) => {
309
+ const idx = registry.observations.findIndex(
310
+ (o) => o.observationId === params.observationId
311
+ );
312
+
313
+ if (idx === -1) {
314
+ return null;
315
+ }
316
+
317
+ const observation = registry.observations[idx];
318
+ observation.completedAt = new Date().toISOString();
319
+ observation.outcome = params.outcome;
320
+ observation.failureSignals = params.failureSignals ?? {
321
+ timedOut: false,
322
+ threwException: false,
323
+ invalidOutput: false,
324
+ profileRejected: false,
325
+ extra: {},
326
+ };
327
+
328
+ writeRegistry(stateDir, registry);
329
+ return observation;
330
+ });
331
+ }
332
+
333
+ /**
334
+ * Complete a shadow observation by task fingerprint (alternative lookup).
335
+ *
336
+ * @param stateDir - Workspace state directory
337
+ * @param taskFingerprint - Task fingerprint to look up
338
+ * @param outcome - Outcome of the shadow routing
339
+ * @param failureSignals - Runtime failure signals
340
+ * @returns The updated ShadowObservation, or null if not found
341
+ */
342
+ export function completeShadowObservationByTask(
343
+ stateDir: string,
344
+ taskFingerprint: string,
345
+ outcome: ShadowOutcome,
346
+ failureSignals?: RuntimeFailureSignals
347
+ ): ShadowObservation | null {
348
+ return withShadowRegistryLock(stateDir, (registry) => {
349
+ // Find the oldest pending observation for this task
350
+ const pendingObs = registry.observations
351
+ .filter((o) => o.taskFingerprint === taskFingerprint && !o.completedAt)
352
+ .sort((a, b) => a.routedAt.localeCompare(b.routedAt));
353
+
354
+ if (pendingObs.length === 0) {
355
+ return null;
356
+ }
357
+
358
+ const observation = pendingObs[0];
359
+ observation.completedAt = new Date().toISOString();
360
+ observation.outcome = outcome;
361
+ observation.failureSignals = failureSignals ?? {
362
+ timedOut: false,
363
+ threwException: false,
364
+ invalidOutput: false,
365
+ profileRejected: false,
366
+ extra: {},
367
+ };
368
+
369
+ writeRegistry(stateDir, registry);
370
+ return observation;
371
+ });
372
+ }
373
+
374
+ // ---------------------------------------------------------------------------
375
+ // Statistics Computation
376
+ // ---------------------------------------------------------------------------
377
+
378
+ /**
379
+ * Parameters for computing shadow statistics.
380
+ */
381
+ export interface ComputeShadowStatsParams {
382
+ /** Checkpoint ID to compute stats for */
383
+ checkpointId: string;
384
+
385
+ /** Time window in milliseconds (default: RECENT_WINDOW_MS) */
386
+ windowMs?: number;
387
+
388
+ /** Retention period in milliseconds (default: DEFAULT_RETENTION_MS) */
389
+ retentionMs?: number;
390
+ }
391
+
392
+ /**
393
+ * Compute shadow routing statistics for a checkpoint.
394
+ *
395
+ * @param stateDir - Workspace state directory
396
+ * @param params - Computation parameters
397
+ * @returns ShadowStats with computed rates, or null if not enough data
398
+ */
399
+ export function computeShadowStats(
400
+ stateDir: string,
401
+ params: ComputeShadowStatsParams
402
+ ): ShadowStats | null {
403
+ const {
404
+ checkpointId,
405
+ windowMs = RECENT_WINDOW_MS,
406
+ retentionMs = DEFAULT_RETENTION_MS,
407
+ } = params;
408
+
409
+ const now = Date.now();
410
+ const windowStart = new Date(now - windowMs).toISOString();
411
+ const windowEnd = new Date(now).toISOString();
412
+
413
+ return withShadowRegistryLock(stateDir, (registry) => {
414
+ // Filter observations:
415
+ // 1. For this checkpoint
416
+ // 2. Within the time window
417
+ // 3. Not expired (within retention period)
418
+ const cutoff = new Date(now - retentionMs).toISOString();
419
+
420
+ const relevantObs = registry.observations.filter((o) => {
421
+ if (o.checkpointId !== checkpointId) return false;
422
+ if (o.routedAt < cutoff) return false; // expired
423
+ if (o.routedAt < windowStart) return false; // outside window
424
+ if (!o.completedAt) return false; // still pending
425
+ return true;
426
+ });
427
+
428
+ const totalCount = relevantObs.length;
429
+
430
+ // Not enough data - fail closed (return null to use eval proxies)
431
+ if (totalCount < MIN_OBSERVATIONS_FOR_TRUST) {
432
+ return null;
433
+ }
434
+
435
+ const acceptedCount = relevantObs.filter((o) => o.outcome === 'accepted').length;
436
+ const rejectedCount = relevantObs.filter((o) => o.outcome === 'rejected').length;
437
+ const escalatedCount = relevantObs.filter((o) => o.outcome === 'escalated').length;
438
+
439
+ // Failure signal counts
440
+ const withTimedOut = relevantObs.filter((o) => o.failureSignals?.timedOut).length;
441
+ const withThrewException = relevantObs.filter((o) => o.failureSignals?.threwException).length;
442
+ const withInvalidOutput = relevantObs.filter((o) => o.failureSignals?.invalidOutput).length;
443
+ const withProfileRejected = relevantObs.filter((o) => o.failureSignals?.profileRejected).length;
444
+
445
+ const rejectRate = totalCount > 0 ? rejectedCount / totalCount : 0;
446
+ const escalationRate = totalCount > 0 ? escalatedCount / totalCount : 0;
447
+ const acceptanceRate = totalCount > 0 ? acceptedCount / totalCount : 0;
448
+
449
+ return {
450
+ checkpointId,
451
+ totalCount,
452
+ acceptedCount,
453
+ rejectedCount,
454
+ escalatedCount,
455
+ rejectRate: Math.round(rejectRate * 1000) / 1000,
456
+ escalationRate: Math.round(escalationRate * 1000) / 1000,
457
+ acceptanceRate: Math.round(acceptanceRate * 1000) / 1000,
458
+ timedOutRate: Math.round((withTimedOut / totalCount) * 1000) / 1000,
459
+ threwExceptionRate: Math.round((withThrewException / totalCount) * 1000) / 1000,
460
+ invalidOutputRate: Math.round((withInvalidOutput / totalCount) * 1000) / 1000,
461
+ profileRejectedRate: Math.round((withProfileRejected / totalCount) * 1000) / 1000,
462
+ isStatisticallySignificant: totalCount >= MIN_OBSERVATIONS_FOR_TRUST,
463
+ windowStart,
464
+ windowEnd,
465
+ };
466
+ });
467
+ }
468
+
469
+ /**
470
+ * Query shadow observations for a checkpoint.
471
+ *
472
+ * @param stateDir - Workspace state directory
473
+ * @param checkpointId - Checkpoint ID to query
474
+ * @param limit - Maximum observations to return (default: 100)
475
+ * @returns Array of shadow observations
476
+ */
477
+ export function queryShadowObservations(
478
+ stateDir: string,
479
+ checkpointId: string,
480
+ limit: number = 100
481
+ ): ShadowObservation[] {
482
+ return withShadowRegistryLock(stateDir, (registry) => {
483
+ return registry.observations
484
+ .filter((o) => o.checkpointId === checkpointId)
485
+ .sort((a, b) => b.routedAt.localeCompare(a.routedAt)) // newest first
486
+ .slice(0, limit);
487
+ });
488
+ }
489
+
490
+ /**
491
+ * Mark observations as used in a promotion gate evaluation.
492
+ *
493
+ * @param stateDir - Workspace state directory
494
+ * @param observationIds - IDs of observations to mark
495
+ */
496
+ export function markObservationsUsedInGate(
497
+ stateDir: string,
498
+ observationIds: string[]
499
+ ): void {
500
+ withShadowRegistryLock(stateDir, (registry) => {
501
+ for (const obs of registry.observations) {
502
+ if (observationIds.includes(obs.observationId)) {
503
+ obs.usedInGate = true;
504
+ }
505
+ }
506
+ writeRegistry(stateDir, registry);
507
+ });
508
+ }
509
+
510
+ /**
511
+ * Clean up expired observations (older than retention period).
512
+ *
513
+ * @param stateDir - Workspace state directory
514
+ * @param retentionMs - Retention period in milliseconds (default: DEFAULT_RETENTION_MS)
515
+ * @returns Number of observations removed
516
+ */
517
+ export function cleanupExpiredObservations(
518
+ stateDir: string,
519
+ retentionMs: number = DEFAULT_RETENTION_MS
520
+ ): number {
521
+ const cutoff = new Date(Date.now() - retentionMs).toISOString();
522
+ let removed = 0;
523
+
524
+ withShadowRegistryLock(stateDir, (registry) => {
525
+ const before = registry.observations.length;
526
+ registry.observations = registry.observations.filter(
527
+ (o) => o.routedAt >= cutoff
528
+ );
529
+ removed = before - registry.observations.length;
530
+ writeRegistry(stateDir, registry);
531
+ });
532
+
533
+ return removed;
534
+ }
@@ -1,30 +1,34 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { resolvePdPath } from './paths.js';
4
+
4
5
  /**
5
6
  * System Logger for Principles Disciple
6
7
  * Writes critical evolutionary events to the project's memory/logs/SYSTEM.log
7
8
  * Uses asynchronous writing to avoid blocking the Node.js event loop.
8
9
  */
9
10
  export const SystemLogger = {
10
- log(workspaceDir, eventType, message) {
11
- if (!workspaceDir)
12
- return;
11
+ log(workspaceDir: string | undefined, eventType: string, message: string): void {
12
+ if (!workspaceDir) return;
13
+
13
14
  try {
14
15
  const logFile = resolvePdPath(workspaceDir, 'SYSTEM_LOG');
15
16
  const logDir = path.dirname(logFile);
17
+
16
18
  if (!fs.existsSync(logDir)) {
17
19
  fs.mkdirSync(logDir, { recursive: true });
18
20
  }
21
+
19
22
  const timestamp = new Date().toISOString();
23
+
20
24
  // Format: [YYYY-MM-DDTHH:mm:ss.sssZ] [EVENT_TYPE] Message
21
25
  const logEntry = `[${timestamp}] [${eventType.padEnd(15)}] ${message}\n`;
26
+
22
27
  // Use fire-and-forget async append to prevent blocking
23
28
  fs.appendFile(logFile, logEntry, 'utf8', (err) => {
24
29
  // Silently drop errors (e.g. disk full) to not crash the gateway
25
30
  });
26
- }
27
- catch (e) {
31
+ } catch (e) {
28
32
  // Silently fail if we can't setup the log
29
33
  }
30
34
  }