principles-disciple 1.8.1 → 1.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (508) hide show
  1. package/ADVANCED_CONFIG_ZH.md +97 -0
  2. package/AGENT_INSTALL.md +173 -0
  3. package/AGENT_INSTALL_EN.md +173 -0
  4. package/INSTALL.md +256 -0
  5. package/SKILL.md +63 -0
  6. package/docs/COMMAND_REFERENCE.md +76 -0
  7. package/docs/COMMAND_REFERENCE_EN.md +79 -0
  8. package/esbuild.config.js +75 -0
  9. package/openclaw.plugin.json +4 -4
  10. package/package.json +11 -13
  11. package/scripts/build-web.mjs +46 -0
  12. package/scripts/install-dependencies.cjs +47 -0
  13. package/scripts/sync-plugin.mjs +802 -0
  14. package/scripts/verify-build.mjs +109 -0
  15. package/src/agents/nocturnal-dreamer.md +152 -0
  16. package/src/agents/nocturnal-philosopher.md +138 -0
  17. package/src/agents/nocturnal-reflector.md +126 -0
  18. package/src/agents/nocturnal-scribe.md +164 -0
  19. package/src/commands/capabilities.ts +85 -0
  20. package/{dist/commands/context.js → src/commands/context.ts} +78 -38
  21. package/src/commands/evolution-status.ts +146 -0
  22. package/src/commands/export.ts +111 -0
  23. package/src/commands/focus.ts +533 -0
  24. package/src/commands/nocturnal-review.ts +311 -0
  25. package/src/commands/nocturnal-rollout.ts +763 -0
  26. package/src/commands/nocturnal-train.ts +1002 -0
  27. package/{dist/commands/pain.js → src/commands/pain.ts} +68 -49
  28. package/src/commands/principle-rollback.ts +27 -0
  29. package/{dist/commands/rollback.js → src/commands/rollback.ts} +44 -12
  30. package/src/commands/samples.ts +60 -0
  31. package/src/commands/strategy.ts +38 -0
  32. package/{dist/commands/thinking-os.js → src/commands/thinking-os.ts} +59 -36
  33. package/src/commands/workflow-debug.ts +128 -0
  34. package/{dist/config/defaults/runtime.js → src/config/defaults/runtime.ts} +12 -5
  35. package/src/config/errors.ts +163 -0
  36. package/{dist/config/index.d.ts → src/config/index.ts} +2 -1
  37. package/src/constants/diagnostician.ts +66 -0
  38. package/src/constants/tools.ts +62 -0
  39. package/src/core/adaptive-thresholds.ts +476 -0
  40. package/{dist/core/config-service.js → src/core/config-service.ts} +7 -4
  41. package/{dist/core/config.js → src/core/config.ts} +158 -46
  42. package/src/core/control-ui-db.ts +435 -0
  43. package/{dist/core/detection-funnel.js → src/core/detection-funnel.ts} +36 -21
  44. package/{dist/core/detection-service.js → src/core/detection-service.ts} +7 -4
  45. package/{dist/core/dictionary-service.js → src/core/dictionary-service.ts} +7 -4
  46. package/{dist/core/dictionary.js → src/core/dictionary.ts} +57 -34
  47. package/src/core/empathy-keyword-matcher.ts +327 -0
  48. package/src/core/empathy-types.ts +218 -0
  49. package/src/core/event-log.ts +544 -0
  50. package/src/core/evolution-engine.ts +612 -0
  51. package/src/core/evolution-logger.ts +353 -0
  52. package/src/core/evolution-migration.ts +77 -0
  53. package/src/core/evolution-reducer.ts +731 -0
  54. package/src/core/evolution-types.ts +456 -0
  55. package/src/core/external-training-contract.ts +527 -0
  56. package/src/core/focus-history.ts +1458 -0
  57. package/src/core/hygiene/tracker.ts +117 -0
  58. package/{dist/core/init.js → src/core/init.ts} +39 -26
  59. package/src/core/local-worker-routing.ts +617 -0
  60. package/{dist/core/migration.js → src/core/migration.ts} +18 -11
  61. package/src/core/model-deployment-registry.ts +722 -0
  62. package/src/core/model-training-registry.ts +813 -0
  63. package/src/core/nocturnal-arbiter.ts +706 -0
  64. package/src/core/nocturnal-candidate-scoring.ts +392 -0
  65. package/src/core/nocturnal-compliance.ts +1075 -0
  66. package/src/core/nocturnal-dataset.ts +668 -0
  67. package/src/core/nocturnal-executability.ts +428 -0
  68. package/src/core/nocturnal-export.ts +390 -0
  69. package/{dist/core/nocturnal-paths.js → src/core/nocturnal-paths.ts} +49 -23
  70. package/src/core/nocturnal-trajectory-extractor.ts +484 -0
  71. package/src/core/nocturnal-trinity.ts +1384 -0
  72. package/src/core/pain.ts +122 -0
  73. package/{dist/core/path-resolver.js → src/core/path-resolver.ts} +157 -36
  74. package/{dist/core/paths.js → src/core/paths.ts} +13 -4
  75. package/src/core/principle-training-state.ts +450 -0
  76. package/src/core/profile.ts +226 -0
  77. package/src/core/promotion-gate.ts +822 -0
  78. package/{dist/core/risk-calculator.js → src/core/risk-calculator.ts} +42 -16
  79. package/{dist/core/session-tracker.js → src/core/session-tracker.ts} +175 -62
  80. package/src/core/shadow-observation-registry.ts +534 -0
  81. package/{dist/core/system-logger.js → src/core/system-logger.ts} +9 -5
  82. package/src/core/thinking-models.ts +217 -0
  83. package/src/core/training-program.ts +630 -0
  84. package/src/core/trajectory-types.ts +243 -0
  85. package/src/core/trajectory.ts +1673 -0
  86. package/{dist/core/workspace-context.js → src/core/workspace-context.ts} +57 -32
  87. package/src/hooks/bash-risk.ts +171 -0
  88. package/src/hooks/edit-verification.ts +295 -0
  89. package/src/hooks/gate-block-helper.ts +160 -0
  90. package/src/hooks/gate.ts +210 -0
  91. package/src/hooks/gfi-gate.ts +177 -0
  92. package/src/hooks/lifecycle.ts +326 -0
  93. package/{dist/hooks/llm.js → src/hooks/llm.ts} +160 -80
  94. package/src/hooks/message-sanitize.ts +45 -0
  95. package/src/hooks/pain.ts +384 -0
  96. package/src/hooks/progressive-trust-gate.ts +174 -0
  97. package/src/hooks/prompt.ts +920 -0
  98. package/src/hooks/subagent.ts +207 -0
  99. package/src/hooks/thinking-checkpoint.ts +73 -0
  100. package/src/hooks/trajectory-collector.ts +290 -0
  101. package/src/http/principles-console-route.ts +716 -0
  102. package/src/i18n/commands.ts +117 -0
  103. package/src/index.ts +694 -0
  104. package/src/service/central-database.ts +831 -0
  105. package/src/service/control-ui-query-service.ts +888 -0
  106. package/src/service/evolution-query-service.ts +405 -0
  107. package/src/service/evolution-worker.ts +1646 -0
  108. package/src/service/health-query-service.ts +836 -0
  109. package/{dist/service/nocturnal-runtime.js → src/service/nocturnal-runtime.ts} +235 -79
  110. package/src/service/nocturnal-service.ts +1015 -0
  111. package/src/service/nocturnal-target-selector.ts +532 -0
  112. package/src/service/phase3-input-filter.ts +237 -0
  113. package/src/service/runtime-summary-service.ts +757 -0
  114. package/src/service/subagent-workflow/deep-reflect-workflow-manager.ts +513 -0
  115. package/{dist/service/subagent-workflow/empathy-observer-workflow-manager.js → src/service/subagent-workflow/empathy-observer-workflow-manager.ts} +240 -117
  116. package/src/service/subagent-workflow/index.ts +51 -0
  117. package/src/service/subagent-workflow/nocturnal-workflow-manager.ts +856 -0
  118. package/src/service/subagent-workflow/runtime-direct-driver.ts +166 -0
  119. package/{dist/service/subagent-workflow/types.d.ts → src/service/subagent-workflow/types.ts} +137 -18
  120. package/src/service/subagent-workflow/workflow-store.ts +328 -0
  121. package/src/service/trajectory-service.ts +15 -0
  122. package/{dist/tools/critique-prompt.js → src/tools/critique-prompt.ts} +25 -8
  123. package/src/tools/deep-reflect.ts +349 -0
  124. package/{dist/tools/model-index.js → src/tools/model-index.ts} +33 -17
  125. package/src/types/event-types.ts +453 -0
  126. package/src/types/hygiene-types.ts +31 -0
  127. package/src/types/principle-tree-schema.ts +244 -0
  128. package/src/types/runtime-summary.ts +49 -0
  129. package/src/types.ts +74 -0
  130. package/src/utils/file-lock.ts +391 -0
  131. package/{dist/utils/glob-match.js → src/utils/glob-match.ts} +21 -20
  132. package/{dist/utils/hashing.js → src/utils/hashing.ts} +6 -4
  133. package/src/utils/io.ts +110 -0
  134. package/{dist/utils/nlp.js → src/utils/nlp.ts} +19 -12
  135. package/{dist/utils/plugin-logger.js → src/utils/plugin-logger.ts} +33 -8
  136. package/src/utils/subagent-probe.ts +94 -0
  137. package/templates/langs/en/skills/ai-sprint-orchestration/EXAMPLES.md +63 -0
  138. package/templates/langs/en/skills/ai-sprint-orchestration/REFERENCE.md +136 -0
  139. package/templates/langs/en/skills/ai-sprint-orchestration/SKILL.md +67 -0
  140. package/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +214 -0
  141. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +107 -0
  142. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +107 -0
  143. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +105 -0
  144. package/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +108 -0
  145. package/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +58 -0
  146. package/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +190 -0
  147. package/templates/langs/en/skills/ai-sprint-orchestration/runtime/.gitignore +2 -0
  148. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +310 -0
  149. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +683 -0
  150. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +604 -0
  151. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +32 -0
  152. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +707 -0
  153. package/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +3419 -0
  154. package/templates/langs/zh/skills/ai-sprint-orchestration/EXAMPLES.md +63 -0
  155. package/templates/langs/zh/skills/ai-sprint-orchestration/REFERENCE.md +136 -0
  156. package/templates/langs/zh/skills/ai-sprint-orchestration/SKILL.md +67 -0
  157. package/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +214 -0
  158. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +107 -0
  159. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +107 -0
  160. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +105 -0
  161. package/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +108 -0
  162. package/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +58 -0
  163. package/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +190 -0
  164. package/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +2 -0
  165. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +310 -0
  166. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +683 -0
  167. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +604 -0
  168. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +32 -0
  169. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +707 -0
  170. package/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +3419 -0
  171. package/templates/langs/zh/skills/ai-sprint-orchestration/test/archive.test.mjs +230 -0
  172. package/templates/langs/zh/skills/ai-sprint-orchestration/test/contract-enforcement.test.mjs +672 -0
  173. package/templates/langs/zh/skills/ai-sprint-orchestration/test/decision.test.mjs +1321 -0
  174. package/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +1419 -0
  175. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +70 -1
  176. package/templates/pain_settings.json +2 -1
  177. package/tests/README.md +120 -0
  178. package/tests/build-artifacts.test.ts +111 -0
  179. package/tests/commands/evolution-status.test.ts +222 -0
  180. package/tests/commands/evolver.test.ts +22 -0
  181. package/tests/commands/export.test.ts +78 -0
  182. package/tests/commands/nocturnal-review.test.ts +448 -0
  183. package/tests/commands/nocturnal-train.test.ts +97 -0
  184. package/tests/commands/pain.test.ts +108 -0
  185. package/tests/commands/samples.test.ts +65 -0
  186. package/tests/commands/strategy.test.ts +34 -0
  187. package/tests/commands/thinking-os.test.ts +88 -0
  188. package/tests/core/adaptive-thresholds.test.ts +261 -0
  189. package/tests/core/config-service.test.ts +89 -0
  190. package/tests/core/config.test.ts +90 -0
  191. package/tests/core/control-ui-db.test.ts +75 -0
  192. package/tests/core/core-template-guidance.test.ts +21 -0
  193. package/tests/core/detection-funnel.test.ts +63 -0
  194. package/tests/core/detection-service.test.ts +50 -0
  195. package/tests/core/dictionary-service.test.ts +116 -0
  196. package/tests/core/dictionary.test.ts +168 -0
  197. package/tests/core/empathy-keyword-matcher.test.ts +209 -0
  198. package/tests/core/event-log.test.ts +181 -0
  199. package/tests/core/evolution-e2e.test.ts +58 -0
  200. package/tests/core/evolution-engine-gate-integration.test.ts +543 -0
  201. package/tests/core/evolution-engine.test.ts +562 -0
  202. package/tests/core/evolution-logger.test.ts +148 -0
  203. package/tests/core/evolution-migration.test.ts +50 -0
  204. package/tests/core/evolution-paths.test.ts +21 -0
  205. package/tests/core/evolution-reducer.detector-metadata.test.ts +602 -0
  206. package/tests/core/evolution-reducer.test.ts +180 -0
  207. package/tests/core/evolution-types-loop.test.ts +48 -0
  208. package/tests/core/evolution-user-stories.e2e.test.ts +249 -0
  209. package/tests/core/external-training-contract.test.ts +463 -0
  210. package/tests/core/focus-history.test.ts +682 -0
  211. package/tests/core/init-flatten.test.ts +69 -0
  212. package/tests/core/init-refactor.test.ts +87 -0
  213. package/tests/core/init-v1.3.test.ts +46 -0
  214. package/tests/core/init.test.ts +190 -0
  215. package/tests/core/local-worker-routing.test.ts +757 -0
  216. package/tests/core/migration.test.ts +84 -0
  217. package/tests/core/model-deployment-registry.test.ts +845 -0
  218. package/tests/core/model-training-registry.test.ts +889 -0
  219. package/tests/core/nocturnal-arbiter.test.ts +494 -0
  220. package/tests/core/nocturnal-candidate-scoring.test.ts +400 -0
  221. package/tests/core/nocturnal-compliance.test.ts +646 -0
  222. package/tests/core/nocturnal-dataset.test.ts +892 -0
  223. package/tests/core/nocturnal-executability.test.ts +357 -0
  224. package/tests/core/nocturnal-export.test.ts +462 -0
  225. package/tests/core/nocturnal-reviewed-subset-comparison.test.ts +428 -0
  226. package/tests/core/nocturnal-trajectory-extractor.test.ts +634 -0
  227. package/tests/core/nocturnal-trinity.test.ts +953 -0
  228. package/tests/core/pain.test.ts +33 -0
  229. package/tests/core/path-resolver.test.ts +57 -0
  230. package/tests/core/paths-refactor.test.ts +42 -0
  231. package/tests/core/phase7-rollout-integration.test.ts +477 -0
  232. package/tests/core/principle-training-state.test.ts +712 -0
  233. package/tests/core/profile.test.ts +56 -0
  234. package/tests/core/promotion-gate.test.ts +556 -0
  235. package/tests/core/risk-calculator.test.ts +168 -0
  236. package/tests/core/session-tracker.test.ts +191 -0
  237. package/tests/core/training-program.test.ts +472 -0
  238. package/tests/core/trajectory.test.ts +265 -0
  239. package/tests/core/workspace-context-factory.test.ts +18 -0
  240. package/tests/core/workspace-context.test.ts +134 -0
  241. package/tests/fixtures/nocturnal-reviewed-subset.json +183 -0
  242. package/tests/fixtures/production-compatibility.test.ts +147 -0
  243. package/tests/fixtures/production-mock-generator.ts +282 -0
  244. package/tests/hooks/bash-risk-integration.test.ts +137 -0
  245. package/tests/hooks/bash-risk.test.ts +81 -0
  246. package/tests/hooks/edit-verification.test.ts +678 -0
  247. package/tests/hooks/gate-edit-verification-p1.test.ts +632 -0
  248. package/tests/hooks/gate-edit-verification.test.ts +435 -0
  249. package/tests/hooks/gate-pipeline-integration.test.ts +404 -0
  250. package/tests/hooks/gate.test.ts +271 -0
  251. package/tests/hooks/gfi-gate-unit.test.ts +422 -0
  252. package/tests/hooks/gfi-gate.test.ts +669 -0
  253. package/tests/hooks/lifecycle.test.ts +248 -0
  254. package/tests/hooks/llm.test.ts +308 -0
  255. package/tests/hooks/message-sanitize.test.ts +36 -0
  256. package/tests/hooks/pain.test.ts +141 -0
  257. package/tests/hooks/progressive-trust-gate.test.ts +277 -0
  258. package/tests/hooks/prompt.test.ts +1411 -0
  259. package/tests/hooks/subagent.test.ts +467 -0
  260. package/tests/hooks/thinking-gate.test.ts +313 -0
  261. package/tests/http/principles-console-route.test.ts +140 -0
  262. package/tests/hygiene-tracker.test.ts +77 -0
  263. package/tests/index.integration.test.ts +179 -0
  264. package/tests/index.shadow-routing.integration.test.ts +140 -0
  265. package/tests/index.test.ts +9 -0
  266. package/tests/integration/empathy-workflow-integration.test.ts +627 -0
  267. package/tests/service/control-ui-query-service.test.ts +121 -0
  268. package/tests/service/empathy-observer-workflow-manager.test.ts +176 -0
  269. package/tests/service/evolution-worker.test.ts +585 -0
  270. package/tests/service/nocturnal-runtime.test.ts +470 -0
  271. package/tests/service/nocturnal-service.test.ts +577 -0
  272. package/tests/service/nocturnal-target-selector.test.ts +615 -0
  273. package/tests/service/nocturnal-workflow-manager.test.ts +439 -0
  274. package/tests/service/phase3-input-filter.test.ts +289 -0
  275. package/tests/service/runtime-summary-service.test.ts +919 -0
  276. package/tests/task-compliance.test.ts +166 -0
  277. package/tests/test-utils.ts +48 -0
  278. package/tests/tools/critique-prompt.test.ts +260 -0
  279. package/tests/tools/deep-reflect.test.ts +232 -0
  280. package/tests/tools/model-index.test.ts +246 -0
  281. package/tests/ui/app.test.tsx +114 -0
  282. package/tests/utils/file-lock.test.ts +407 -0
  283. package/tests/utils/hashing.test.ts +32 -0
  284. package/tests/utils/io.test.ts +39 -0
  285. package/tests/utils/nlp.test.ts +53 -0
  286. package/tests/utils/plugin-logger.test.ts +156 -0
  287. package/tsconfig.json +16 -0
  288. package/tsconfig.tsbuildinfo +1 -0
  289. package/ui/src/App.tsx +45 -0
  290. package/ui/src/api.ts +216 -0
  291. package/ui/src/charts.tsx +586 -0
  292. package/ui/src/components/ErrorState.tsx +6 -0
  293. package/ui/src/components/Loading.tsx +13 -0
  294. package/ui/src/components/ProtectedRoute.tsx +12 -0
  295. package/ui/src/components/Shell.tsx +91 -0
  296. package/ui/src/components/WorkspaceConfig.tsx +146 -0
  297. package/ui/src/components/index.ts +5 -0
  298. package/ui/src/context/auth.tsx +80 -0
  299. package/ui/src/context/theme.tsx +66 -0
  300. package/ui/src/hooks/useAutoRefresh.ts +39 -0
  301. package/ui/src/i18n/ui.ts +363 -0
  302. package/ui/src/main.tsx +16 -0
  303. package/ui/src/pages/EvolutionPage.tsx +352 -0
  304. package/ui/src/pages/FeedbackPage.tsx +140 -0
  305. package/ui/src/pages/GateMonitorPage.tsx +136 -0
  306. package/ui/src/pages/LoginPage.tsx +88 -0
  307. package/ui/src/pages/OverviewPage.tsx +238 -0
  308. package/ui/src/pages/SamplesPage.tsx +174 -0
  309. package/ui/src/pages/ThinkingModelsPage.tsx +127 -0
  310. package/ui/src/styles.css +1661 -0
  311. package/ui/src/types.ts +368 -0
  312. package/ui/src/utils/format.ts +15 -0
  313. package/vitest.config.ts +23 -0
  314. package/dist/commands/capabilities.d.ts +0 -3
  315. package/dist/commands/capabilities.js +0 -73
  316. package/dist/commands/context.d.ts +0 -5
  317. package/dist/commands/evolution-status.d.ts +0 -4
  318. package/dist/commands/evolution-status.js +0 -117
  319. package/dist/commands/evolver.d.ts +0 -9
  320. package/dist/commands/evolver.js +0 -26
  321. package/dist/commands/export.d.ts +0 -2
  322. package/dist/commands/export.js +0 -98
  323. package/dist/commands/focus.d.ts +0 -14
  324. package/dist/commands/focus.js +0 -457
  325. package/dist/commands/nocturnal-review.d.ts +0 -24
  326. package/dist/commands/nocturnal-review.js +0 -265
  327. package/dist/commands/nocturnal-rollout.d.ts +0 -27
  328. package/dist/commands/nocturnal-rollout.js +0 -671
  329. package/dist/commands/nocturnal-train.d.ts +0 -25
  330. package/dist/commands/nocturnal-train.js +0 -919
  331. package/dist/commands/pain.d.ts +0 -5
  332. package/dist/commands/principle-rollback.d.ts +0 -4
  333. package/dist/commands/principle-rollback.js +0 -22
  334. package/dist/commands/rollback.d.ts +0 -19
  335. package/dist/commands/samples.d.ts +0 -2
  336. package/dist/commands/samples.js +0 -55
  337. package/dist/commands/strategy.d.ts +0 -3
  338. package/dist/commands/strategy.js +0 -29
  339. package/dist/commands/thinking-os.d.ts +0 -2
  340. package/dist/config/defaults/runtime.d.ts +0 -40
  341. package/dist/config/errors.d.ts +0 -84
  342. package/dist/config/errors.js +0 -94
  343. package/dist/config/index.js +0 -7
  344. package/dist/constants/diagnostician.d.ts +0 -12
  345. package/dist/constants/diagnostician.js +0 -56
  346. package/dist/constants/tools.d.ts +0 -17
  347. package/dist/constants/tools.js +0 -54
  348. package/dist/core/adaptive-thresholds.d.ts +0 -186
  349. package/dist/core/adaptive-thresholds.js +0 -300
  350. package/dist/core/config-service.d.ts +0 -15
  351. package/dist/core/config.d.ts +0 -129
  352. package/dist/core/control-ui-db.d.ts +0 -95
  353. package/dist/core/control-ui-db.js +0 -292
  354. package/dist/core/detection-funnel.d.ts +0 -33
  355. package/dist/core/detection-service.d.ts +0 -15
  356. package/dist/core/dictionary-service.d.ts +0 -15
  357. package/dist/core/dictionary.d.ts +0 -38
  358. package/dist/core/event-log.d.ts +0 -82
  359. package/dist/core/event-log.js +0 -463
  360. package/dist/core/evolution-engine.d.ts +0 -118
  361. package/dist/core/evolution-engine.js +0 -464
  362. package/dist/core/evolution-logger.d.ts +0 -137
  363. package/dist/core/evolution-logger.js +0 -256
  364. package/dist/core/evolution-migration.d.ts +0 -5
  365. package/dist/core/evolution-migration.js +0 -65
  366. package/dist/core/evolution-reducer.d.ts +0 -98
  367. package/dist/core/evolution-reducer.js +0 -465
  368. package/dist/core/evolution-types.d.ts +0 -287
  369. package/dist/core/evolution-types.js +0 -78
  370. package/dist/core/external-training-contract.d.ts +0 -276
  371. package/dist/core/external-training-contract.js +0 -269
  372. package/dist/core/focus-history.d.ts +0 -210
  373. package/dist/core/focus-history.js +0 -1185
  374. package/dist/core/hygiene/tracker.d.ts +0 -22
  375. package/dist/core/hygiene/tracker.js +0 -106
  376. package/dist/core/init.d.ts +0 -12
  377. package/dist/core/local-worker-routing.d.ts +0 -175
  378. package/dist/core/local-worker-routing.js +0 -525
  379. package/dist/core/migration.d.ts +0 -6
  380. package/dist/core/model-deployment-registry.d.ts +0 -218
  381. package/dist/core/model-deployment-registry.js +0 -503
  382. package/dist/core/model-training-registry.d.ts +0 -295
  383. package/dist/core/model-training-registry.js +0 -475
  384. package/dist/core/nocturnal-arbiter.d.ts +0 -159
  385. package/dist/core/nocturnal-arbiter.js +0 -534
  386. package/dist/core/nocturnal-candidate-scoring.d.ts +0 -137
  387. package/dist/core/nocturnal-candidate-scoring.js +0 -266
  388. package/dist/core/nocturnal-compliance.d.ts +0 -175
  389. package/dist/core/nocturnal-compliance.js +0 -824
  390. package/dist/core/nocturnal-dataset.d.ts +0 -224
  391. package/dist/core/nocturnal-dataset.js +0 -443
  392. package/dist/core/nocturnal-executability.d.ts +0 -85
  393. package/dist/core/nocturnal-executability.js +0 -331
  394. package/dist/core/nocturnal-export.d.ts +0 -124
  395. package/dist/core/nocturnal-export.js +0 -275
  396. package/dist/core/nocturnal-paths.d.ts +0 -124
  397. package/dist/core/nocturnal-trajectory-extractor.d.ts +0 -242
  398. package/dist/core/nocturnal-trajectory-extractor.js +0 -307
  399. package/dist/core/nocturnal-trinity.d.ts +0 -311
  400. package/dist/core/nocturnal-trinity.js +0 -880
  401. package/dist/core/pain.d.ts +0 -4
  402. package/dist/core/pain.js +0 -70
  403. package/dist/core/path-resolver.d.ts +0 -46
  404. package/dist/core/paths.d.ts +0 -65
  405. package/dist/core/principle-training-state.d.ts +0 -121
  406. package/dist/core/principle-training-state.js +0 -321
  407. package/dist/core/profile.d.ts +0 -62
  408. package/dist/core/profile.js +0 -210
  409. package/dist/core/promotion-gate.d.ts +0 -238
  410. package/dist/core/promotion-gate.js +0 -529
  411. package/dist/core/risk-calculator.d.ts +0 -22
  412. package/dist/core/session-tracker.d.ts +0 -101
  413. package/dist/core/shadow-observation-registry.d.ts +0 -217
  414. package/dist/core/shadow-observation-registry.js +0 -308
  415. package/dist/core/system-logger.d.ts +0 -8
  416. package/dist/core/thinking-models.d.ts +0 -38
  417. package/dist/core/thinking-models.js +0 -170
  418. package/dist/core/training-program.d.ts +0 -233
  419. package/dist/core/training-program.js +0 -433
  420. package/dist/core/trajectory.d.ts +0 -411
  421. package/dist/core/trajectory.js +0 -1307
  422. package/dist/core/workspace-context.d.ts +0 -71
  423. package/dist/hooks/bash-risk.d.ts +0 -57
  424. package/dist/hooks/bash-risk.js +0 -137
  425. package/dist/hooks/edit-verification.d.ts +0 -62
  426. package/dist/hooks/edit-verification.js +0 -256
  427. package/dist/hooks/gate-block-helper.d.ts +0 -44
  428. package/dist/hooks/gate-block-helper.js +0 -119
  429. package/dist/hooks/gate.d.ts +0 -24
  430. package/dist/hooks/gate.js +0 -173
  431. package/dist/hooks/gfi-gate.d.ts +0 -40
  432. package/dist/hooks/gfi-gate.js +0 -113
  433. package/dist/hooks/lifecycle.d.ts +0 -5
  434. package/dist/hooks/lifecycle.js +0 -284
  435. package/dist/hooks/llm.d.ts +0 -13
  436. package/dist/hooks/message-sanitize.d.ts +0 -3
  437. package/dist/hooks/message-sanitize.js +0 -37
  438. package/dist/hooks/pain.d.ts +0 -5
  439. package/dist/hooks/pain.js +0 -301
  440. package/dist/hooks/progressive-trust-gate.d.ts +0 -52
  441. package/dist/hooks/progressive-trust-gate.js +0 -134
  442. package/dist/hooks/prompt.d.ts +0 -49
  443. package/dist/hooks/prompt.js +0 -905
  444. package/dist/hooks/subagent.d.ts +0 -10
  445. package/dist/hooks/subagent.js +0 -387
  446. package/dist/hooks/thinking-checkpoint.d.ts +0 -37
  447. package/dist/hooks/thinking-checkpoint.js +0 -51
  448. package/dist/hooks/trajectory-collector.d.ts +0 -32
  449. package/dist/hooks/trajectory-collector.js +0 -256
  450. package/dist/http/principles-console-route.d.ts +0 -9
  451. package/dist/http/principles-console-route.js +0 -681
  452. package/dist/i18n/commands.d.ts +0 -26
  453. package/dist/i18n/commands.js +0 -116
  454. package/dist/index.d.ts +0 -7
  455. package/dist/index.js +0 -581
  456. package/dist/service/central-database.d.ts +0 -104
  457. package/dist/service/central-database.js +0 -649
  458. package/dist/service/control-ui-query-service.d.ts +0 -221
  459. package/dist/service/control-ui-query-service.js +0 -543
  460. package/dist/service/empathy-observer-manager.d.ts +0 -88
  461. package/dist/service/empathy-observer-manager.js +0 -414
  462. package/dist/service/evolution-query-service.d.ts +0 -155
  463. package/dist/service/evolution-query-service.js +0 -258
  464. package/dist/service/evolution-worker.d.ts +0 -101
  465. package/dist/service/evolution-worker.js +0 -975
  466. package/dist/service/health-query-service.d.ts +0 -170
  467. package/dist/service/health-query-service.js +0 -662
  468. package/dist/service/nocturnal-runtime.d.ts +0 -183
  469. package/dist/service/nocturnal-service.d.ts +0 -163
  470. package/dist/service/nocturnal-service.js +0 -787
  471. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  472. package/dist/service/nocturnal-target-selector.js +0 -315
  473. package/dist/service/phase3-input-filter.d.ts +0 -73
  474. package/dist/service/phase3-input-filter.js +0 -172
  475. package/dist/service/runtime-summary-service.d.ts +0 -122
  476. package/dist/service/runtime-summary-service.js +0 -485
  477. package/dist/service/subagent-workflow/empathy-observer-workflow-manager.d.ts +0 -48
  478. package/dist/service/subagent-workflow/index.d.ts +0 -4
  479. package/dist/service/subagent-workflow/index.js +0 -3
  480. package/dist/service/subagent-workflow/runtime-direct-driver.d.ts +0 -77
  481. package/dist/service/subagent-workflow/runtime-direct-driver.js +0 -75
  482. package/dist/service/subagent-workflow/types.js +0 -11
  483. package/dist/service/subagent-workflow/workflow-store.d.ts +0 -26
  484. package/dist/service/subagent-workflow/workflow-store.js +0 -165
  485. package/dist/service/trajectory-service.d.ts +0 -2
  486. package/dist/service/trajectory-service.js +0 -15
  487. package/dist/tools/critique-prompt.d.ts +0 -14
  488. package/dist/tools/deep-reflect.d.ts +0 -39
  489. package/dist/tools/deep-reflect.js +0 -350
  490. package/dist/tools/model-index.d.ts +0 -9
  491. package/dist/types/event-types.d.ts +0 -306
  492. package/dist/types/event-types.js +0 -106
  493. package/dist/types/hygiene-types.d.ts +0 -20
  494. package/dist/types/hygiene-types.js +0 -12
  495. package/dist/types/runtime-summary.d.ts +0 -47
  496. package/dist/types/runtime-summary.js +0 -1
  497. package/dist/types.d.ts +0 -50
  498. package/dist/types.js +0 -22
  499. package/dist/utils/file-lock.d.ts +0 -71
  500. package/dist/utils/file-lock.js +0 -309
  501. package/dist/utils/glob-match.d.ts +0 -28
  502. package/dist/utils/hashing.d.ts +0 -9
  503. package/dist/utils/io.d.ts +0 -6
  504. package/dist/utils/io.js +0 -106
  505. package/dist/utils/nlp.d.ts +0 -9
  506. package/dist/utils/plugin-logger.d.ts +0 -39
  507. package/dist/utils/subagent-probe.d.ts +0 -34
  508. package/dist/utils/subagent-probe.js +0 -81
@@ -0,0 +1,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
  }