principles-disciple 1.8.0 → 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 (460) 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 +6 -1
  10. package/package.json +13 -15
  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} +185 -63
  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} +166 -139
  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} +263 -36
  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/src/service/subagent-workflow/empathy-observer-workflow-manager.ts +603 -0
  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/src/service/subagent-workflow/types.ts +378 -0
  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 -127
  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 -99
  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 -12
  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 -51
  403. package/dist/hooks/progressive-trust-gate.js +0 -89
  404. package/dist/hooks/prompt.d.ts +0 -47
  405. package/dist/hooks/prompt.js +0 -884
  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 -567
  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 -52
  423. package/dist/service/empathy-observer-manager.js +0 -229
  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 -974
  428. package/dist/service/nocturnal-runtime.d.ts +0 -183
  429. package/dist/service/nocturnal-service.d.ts +0 -163
  430. package/dist/service/nocturnal-service.js +0 -787
  431. package/dist/service/nocturnal-target-selector.d.ts +0 -145
  432. package/dist/service/nocturnal-target-selector.js +0 -315
  433. package/dist/service/phase3-input-filter.d.ts +0 -73
  434. package/dist/service/phase3-input-filter.js +0 -172
  435. package/dist/service/runtime-summary-service.d.ts +0 -122
  436. package/dist/service/runtime-summary-service.js +0 -485
  437. package/dist/service/trajectory-service.d.ts +0 -2
  438. package/dist/service/trajectory-service.js +0 -15
  439. package/dist/tools/critique-prompt.d.ts +0 -14
  440. package/dist/tools/deep-reflect.d.ts +0 -39
  441. package/dist/tools/deep-reflect.js +0 -350
  442. package/dist/tools/model-index.d.ts +0 -9
  443. package/dist/types/event-types.d.ts +0 -306
  444. package/dist/types/event-types.js +0 -106
  445. package/dist/types/hygiene-types.d.ts +0 -20
  446. package/dist/types/hygiene-types.js +0 -12
  447. package/dist/types/runtime-summary.d.ts +0 -47
  448. package/dist/types/runtime-summary.js +0 -1
  449. package/dist/types.d.ts +0 -50
  450. package/dist/types.js +0 -22
  451. package/dist/utils/file-lock.d.ts +0 -71
  452. package/dist/utils/file-lock.js +0 -309
  453. package/dist/utils/glob-match.d.ts +0 -28
  454. package/dist/utils/hashing.d.ts +0 -9
  455. package/dist/utils/io.d.ts +0 -6
  456. package/dist/utils/io.js +0 -106
  457. package/dist/utils/nlp.d.ts +0 -9
  458. package/dist/utils/plugin-logger.d.ts +0 -39
  459. package/dist/utils/subagent-probe.d.ts +0 -34
  460. package/dist/utils/subagent-probe.js +0 -81
@@ -0,0 +1,543 @@
1
+ /**
2
+ * Evolution Engine Gate Integration Tests
3
+ *
4
+ * 集成测试:验证 Gate 系统在实际场景下的表现
5
+ */
6
+
7
+ import { describe, it, test, expect, beforeEach, afterEach } from 'vitest';
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import * as os from 'os';
11
+ import {
12
+ EvolutionEngine,
13
+ getEvolutionEngine,
14
+ } from '../../src/core/evolution-engine.js';
15
+ import {
16
+ EvolutionTier,
17
+ TIER_DEFINITIONS,
18
+ TASK_DIFFICULTY_CONFIG,
19
+ getTierByPoints,
20
+ ToolCallContext,
21
+ } from '../../src/core/evolution-types.js';
22
+
23
+ // ===== 测试工具 =====
24
+
25
+ function createTempWorkspace(): string {
26
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ep-gate-test-'));
27
+ const stateDir = path.join(tmpDir, '.state');
28
+ fs.mkdirSync(stateDir, { recursive: true });
29
+ return tmpDir;
30
+ }
31
+
32
+ function cleanupWorkspace(dir: string): void {
33
+ try {
34
+ fs.rmSync(dir, { recursive: true, force: true });
35
+ } catch {}
36
+ }
37
+
38
+ // ===== 集成测试套件 =====
39
+
40
+ describe('Gate Integration - Tier Progression Flow', () => {
41
+ let workspace: string;
42
+ let engine: EvolutionEngine;
43
+
44
+ beforeEach(() => {
45
+ workspace = createTempWorkspace();
46
+ engine = new EvolutionEngine(workspace);
47
+ });
48
+
49
+ afterEach(() => {
50
+ cleanupWorkspace(workspace);
51
+ });
52
+
53
+ test('Seed tier: maxLinesPerWrite = 150 (updated for modern AI capabilities)', () => {
54
+ const tierDef = engine.getTierDefinition();
55
+ expect(tierDef.permissions.maxLinesPerWrite).toBe(150);
56
+ expect(tierDef.permissions.maxFilesPerTask).toBe(3);
57
+ expect(tierDef.permissions.allowRiskPath).toBe(false);
58
+ expect(tierDef.permissions.allowSubagentSpawn).toBe(true); // Now allowed at Seed tier
59
+ });
60
+
61
+ test('Seed → Sprout: line limit increases to 300', () => {
62
+ // 50 points = Sprout
63
+ for (let i = 0; i < 17; i++) {
64
+ engine.recordSuccess('write', { difficulty: 'normal' });
65
+ }
66
+
67
+ const tier = engine.getTier();
68
+ expect(tier).toBeGreaterThanOrEqual(EvolutionTier.Sprout);
69
+
70
+ const tierDef = engine.getTierDefinition();
71
+ expect(tierDef.permissions.maxLinesPerWrite).toBe(300);
72
+ });
73
+
74
+ test('Seed → Sapling: line limit increases to 500, risk path unlocks', () => {
75
+ // 200 points = Sapling
76
+ for (let i = 0; i < 26; i++) {
77
+ engine.recordSuccess('write', { difficulty: 'hard' });
78
+ }
79
+
80
+ const tier = engine.getTier();
81
+ expect(tier).toBeGreaterThanOrEqual(EvolutionTier.Sapling);
82
+
83
+ const tierDef = engine.getTierDefinition();
84
+ expect(tierDef.permissions.maxLinesPerWrite).toBe(500);
85
+ expect(tierDef.permissions.allowRiskPath).toBe(true); // Risk path unlocks at Sapling
86
+ expect(tierDef.permissions.allowSubagentSpawn).toBe(true);
87
+ });
88
+
89
+ test('Full progression: Seed → Sprout → Sapling → Tree → Forest', () => {
90
+ // Seed (0) → Sprout (50)
91
+ for (let i = 0; i < 17; i++) engine.recordSuccess('write', { difficulty: 'normal' });
92
+ expect(engine.getTier()).toBeGreaterThanOrEqual(EvolutionTier.Sprout);
93
+
94
+ // Sprout (50) → Sapling (200)
95
+ for (let i = 0; i < 20; i++) engine.recordSuccess('write', { difficulty: 'hard' });
96
+ expect(engine.getTier()).toBeGreaterThanOrEqual(EvolutionTier.Sapling);
97
+
98
+ // Sapling (200) → Tree (500)
99
+ for (let i = 0; i < 38; i++) engine.recordSuccess('write', { difficulty: 'hard' });
100
+ expect(engine.getTier()).toBeGreaterThanOrEqual(EvolutionTier.Tree);
101
+
102
+ // Tree (500) → Forest (1000)
103
+ for (let i = 0; i < 63; i++) engine.recordSuccess('write', { difficulty: 'hard' });
104
+ expect(engine.getTier()).toBe(EvolutionTier.Forest);
105
+
106
+ // Forest: no limits
107
+ const tierDef = engine.getTierDefinition();
108
+ const perms = tierDef.permissions;
109
+ expect(perms.maxLinesPerWrite).toBe(Infinity);
110
+ expect(perms.allowRiskPath).toBe(true);
111
+ expect(perms.allowSubagentSpawn).toBe(true);
112
+ });
113
+ });
114
+
115
+ describe('Gate Integration - Blocking Recovery', () => {
116
+ let workspace: string;
117
+ let engine: EvolutionEngine;
118
+
119
+ beforeEach(() => {
120
+ workspace = createTempWorkspace();
121
+ engine = new EvolutionEngine(workspace);
122
+ });
123
+
124
+ afterEach(() => {
125
+ cleanupWorkspace(workspace);
126
+ });
127
+
128
+ test('blocked operation: agent can continue with allowed operations', () => {
129
+ // Seed tier: 150 line limit - so 200 lines should be blocked
130
+ const blocked = engine.beforeToolCall({
131
+ toolName: 'write',
132
+ content: Array(200).fill('line').join('\n'),
133
+ });
134
+ expect(blocked.allowed).toBe(false);
135
+ expect(blocked.reason).toContain('150');
136
+
137
+ // But 100-line write should work (within 150 limit)
138
+ const allowed = engine.beforeToolCall({
139
+ toolName: 'write',
140
+ content: Array(100).fill('line').join('\n'),
141
+ });
142
+ expect(allowed.allowed).toBe(true);
143
+ });
144
+
145
+ test('after promotion: previously blocked operations now allowed', () => {
146
+ // Initially Seed: 150 line limit
147
+ const blocked = engine.beforeToolCall({
148
+ toolName: 'write',
149
+ content: Array(200).fill('line').join('\n'),
150
+ });
151
+ expect(blocked.allowed).toBe(false);
152
+
153
+ // Earn points and promote to Sprout
154
+ for (let i = 0; i < 17; i++) {
155
+ engine.recordSuccess('write', { difficulty: 'normal' });
156
+ }
157
+
158
+ // Now Sprout: 300 line limit
159
+ const nowAllowed = engine.beforeToolCall({
160
+ toolName: 'write',
161
+ content: Array(200).fill('line').join('\n'),
162
+ });
163
+ expect(nowAllowed.allowed).toBe(true);
164
+ });
165
+
166
+ test('risk path access unlocks after promotion to Sapling', () => {
167
+ // Seed: risk path blocked
168
+ const blocked = engine.beforeToolCall({
169
+ toolName: 'write',
170
+ isRiskPath: true,
171
+ lineCount: 10,
172
+ });
173
+ expect(blocked.allowed).toBe(false);
174
+
175
+ // Promote to Sapling (where risk path unlocks)
176
+ for (let i = 0; i < 26; i++) {
177
+ engine.recordSuccess('write', { difficulty: 'hard' });
178
+ }
179
+
180
+ const allowed = engine.beforeToolCall({
181
+ toolName: 'write',
182
+ isRiskPath: true,
183
+ lineCount: 10,
184
+ });
185
+ expect(allowed.allowed).toBe(true);
186
+ });
187
+ });
188
+
189
+ describe('Gate Integration - Multi-tool Consistency', () => {
190
+ let workspace: string;
191
+ let engine: EvolutionEngine;
192
+
193
+ beforeEach(() => {
194
+ workspace = createTempWorkspace();
195
+ engine = new EvolutionEngine(workspace);
196
+ });
197
+
198
+ afterEach(() => {
199
+ cleanupWorkspace(workspace);
200
+ });
201
+
202
+ test('write tool respects line limit', () => {
203
+ // Exactly at limit (150) - should allow
204
+ const exact = engine.beforeToolCall({
205
+ toolName: 'write',
206
+ content: Array(150).fill('line').join('\n'),
207
+ });
208
+ expect(exact.allowed).toBe(true);
209
+
210
+ // 1 over limit (151) - should block
211
+ const over = engine.beforeToolCall({
212
+ toolName: 'write',
213
+ content: Array(151).fill('line').join('\n'),
214
+ });
215
+ expect(over.allowed).toBe(false);
216
+ });
217
+
218
+ test('edit tool respects line limit', () => {
219
+ const allowed = engine.beforeToolCall({
220
+ toolName: 'edit',
221
+ content: Array(100).fill('line').join('\n'),
222
+ });
223
+ expect(allowed.allowed).toBe(true);
224
+
225
+ const blocked = engine.beforeToolCall({
226
+ toolName: 'edit',
227
+ content: Array(200).fill('line').join('\n'),
228
+ });
229
+ expect(blocked.allowed).toBe(false);
230
+ });
231
+
232
+ test('high-risk tools blocked at Seed tier for risk paths', () => {
233
+ // run_shell_command and delete_file are high-risk, blocked for risk paths
234
+ const highRiskTools = ['run_shell_command', 'delete_file'];
235
+
236
+ for (const tool of highRiskTools) {
237
+ const result = engine.beforeToolCall({ toolName: tool, isRiskPath: true });
238
+ expect(result.allowed).toBe(false);
239
+ }
240
+
241
+ // sessions_spawn is now allowed at Seed tier
242
+ const spawnResult = engine.beforeToolCall({ toolName: 'sessions_spawn' });
243
+ expect(spawnResult.allowed).toBe(true);
244
+ });
245
+
246
+ test('read tool always allowed (no content restriction)', () => {
247
+ const result = engine.beforeToolCall({
248
+ toolName: 'read',
249
+ content: Array(1000).fill('line').join('\n'),
250
+ });
251
+ expect(result.allowed).toBe(true);
252
+ });
253
+ });
254
+
255
+ describe('Gate Integration - Edge Cases', () => {
256
+ let workspace: string;
257
+ let engine: EvolutionEngine;
258
+
259
+ beforeEach(() => {
260
+ workspace = createTempWorkspace();
261
+ engine = new EvolutionEngine(workspace);
262
+ });
263
+
264
+ afterEach(() => {
265
+ cleanupWorkspace(workspace);
266
+ });
267
+
268
+ test('empty content allowed', () => {
269
+ const result = engine.beforeToolCall({
270
+ toolName: 'write',
271
+ content: '',
272
+ });
273
+ expect(result.allowed).toBe(true);
274
+ });
275
+
276
+ test('single long line not counted as multiple lines', () => {
277
+ // One very long line (not multiple lines)
278
+ const result = engine.beforeToolCall({
279
+ toolName: 'write',
280
+ content: 'a'.repeat(10000), // 10000 chars, 1 line
281
+ });
282
+ expect(result.allowed).toBe(true);
283
+ });
284
+
285
+ test('lineCount option works the same as content', () => {
286
+ const viaContent = engine.beforeToolCall({
287
+ toolName: 'write',
288
+ content: Array(21).fill('line').join('\n'),
289
+ });
290
+
291
+ const viaLineCount = engine.beforeToolCall({
292
+ toolName: 'write',
293
+ lineCount: 21,
294
+ });
295
+
296
+ expect(viaContent.allowed).toBe(viaLineCount.allowed);
297
+ });
298
+
299
+ test('risk path detection at Seed tier', () => {
300
+ // Without isRiskPath flag
301
+ const normalWrite = engine.beforeToolCall({
302
+ toolName: 'write',
303
+ filePath: 'src/core/trust-engine.ts',
304
+ });
305
+ expect(normalWrite.allowed).toBe(true);
306
+
307
+ // With isRiskPath flag
308
+ const riskWrite = engine.beforeToolCall({
309
+ toolName: 'write',
310
+ filePath: 'src/core/trust-engine.ts',
311
+ isRiskPath: true,
312
+ });
313
+ expect(riskWrite.allowed).toBe(false);
314
+ });
315
+
316
+ test('tool name case sensitivity', () => {
317
+ // Exact match required
318
+ const lowercase = engine.beforeToolCall({ toolName: 'write' });
319
+ expect(lowercase.allowed).toBe(true);
320
+
321
+ const uppercase = engine.beforeToolCall({ toolName: 'WRITE' });
322
+ // Not in HIGH_RISK_TOOLS set, so it's not blocked
323
+ expect(uppercase.allowed).toBe(true);
324
+ });
325
+
326
+ test('no content, no line count - allowed', () => {
327
+ const result = engine.beforeToolCall({
328
+ toolName: 'write',
329
+ });
330
+ expect(result.allowed).toBe(true);
331
+ });
332
+ });
333
+
334
+ describe('Gate Integration - Persistence', () => {
335
+ let workspace: string;
336
+ let engine: EvolutionEngine;
337
+
338
+ beforeEach(() => {
339
+ workspace = createTempWorkspace();
340
+ });
341
+
342
+ afterEach(() => {
343
+ cleanupWorkspace(workspace);
344
+ });
345
+
346
+ test('gate permissions restored after restart', () => {
347
+ // Initial engine: Seed tier
348
+ engine = new EvolutionEngine(workspace);
349
+ expect(engine.getTier()).toBe(EvolutionTier.Seed);
350
+
351
+ // Risk path should be blocked at Seed
352
+ let blocked = engine.beforeToolCall({ toolName: 'write', isRiskPath: true, lineCount: 10 });
353
+ expect(blocked.allowed).toBe(false);
354
+
355
+ // Earn points
356
+ for (let i = 0; i < 26; i++) {
357
+ engine.recordSuccess('write', { difficulty: 'hard' });
358
+ }
359
+
360
+ // Now Sapling - risk path allowed
361
+ expect(engine.getTier()).toBeGreaterThanOrEqual(EvolutionTier.Sapling);
362
+ let allowed = engine.beforeToolCall({ toolName: 'write', isRiskPath: true, lineCount: 10 });
363
+ expect(allowed.allowed).toBe(true);
364
+
365
+ // Restart engine (simulating process restart)
366
+ engine = new EvolutionEngine(workspace);
367
+
368
+ // Should still be Sapling with same permissions
369
+ expect(engine.getTier()).toBeGreaterThanOrEqual(EvolutionTier.Sapling);
370
+ allowed = engine.beforeToolCall({ toolName: 'write', isRiskPath: true, lineCount: 10 });
371
+ expect(allowed.allowed).toBe(true);
372
+ });
373
+
374
+ test('points persisted correctly after restart', () => {
375
+ engine = new EvolutionEngine(workspace);
376
+
377
+ // Record some successes
378
+ engine.recordSuccess('write', { difficulty: 'hard' });
379
+ engine.recordSuccess('write', { difficulty: 'hard' });
380
+ const pointsBefore = engine.getPoints();
381
+
382
+ // Restart
383
+ engine = new EvolutionEngine(workspace);
384
+ const pointsAfter = engine.getPoints();
385
+
386
+ expect(pointsAfter).toBe(pointsBefore);
387
+ expect(pointsAfter).toBe(TASK_DIFFICULTY_CONFIG.hard.basePoints * 2);
388
+ });
389
+
390
+ test('double reward persisted correctly', () => {
391
+ engine = new EvolutionEngine(workspace);
392
+
393
+ // Failure then success = double reward
394
+ engine.recordFailure('write', { filePath: 'test.ts' });
395
+ const result = engine.recordSuccess('write', { filePath: 'test.ts', difficulty: 'normal' });
396
+ expect(result.isDoubleReward).toBe(true);
397
+
398
+ // Restart and verify double reward no longer applies (1hr cooldown)
399
+ engine = new EvolutionEngine(workspace);
400
+ const result2 = engine.recordSuccess('write', { filePath: 'test.ts', difficulty: 'normal' });
401
+ expect(result2.isDoubleReward).toBe(false);
402
+ });
403
+
404
+ test('stats persisted correctly', () => {
405
+ engine = new EvolutionEngine(workspace);
406
+
407
+ engine.recordSuccess('write', { difficulty: 'normal' });
408
+ engine.recordSuccess('write', { difficulty: 'normal' });
409
+ engine.recordFailure('write');
410
+
411
+ const statsBefore = engine.getStats();
412
+
413
+ // Restart
414
+ engine = new EvolutionEngine(workspace);
415
+ const statsAfter = engine.getStats();
416
+
417
+ expect(statsAfter.totalSuccesses).toBe(statsBefore.totalSuccesses);
418
+ expect(statsAfter.totalFailures).toBe(statsBefore.totalFailures);
419
+ expect(statsAfter.consecutiveSuccesses).toBe(0); // Reset on restart
420
+ });
421
+ });
422
+
423
+ describe('Gate Integration - Real World Scenarios', () => {
424
+ let workspace: string;
425
+ let engine: EvolutionEngine;
426
+
427
+ beforeEach(() => {
428
+ workspace = createTempWorkspace();
429
+ engine = new EvolutionEngine(workspace);
430
+ });
431
+
432
+ afterEach(() => {
433
+ cleanupWorkspace(workspace);
434
+ });
435
+
436
+ test('agent starts small, grows capability', () => {
437
+ // New agent at Seed
438
+ expect(engine.getTier()).toBe(EvolutionTier.Seed);
439
+
440
+ // Attempt 200-line write - blocked (Seed limit is 150)
441
+ let decision = engine.beforeToolCall({
442
+ toolName: 'write',
443
+ content: Array(200).fill('line').join('\n'),
444
+ });
445
+ expect(decision.allowed).toBe(false);
446
+
447
+ // Subagent spawn is now allowed at Seed
448
+ decision = engine.beforeToolCall({
449
+ toolName: 'sessions_spawn',
450
+ });
451
+ expect(decision.allowed).toBe(true);
452
+
453
+ // Risk path is blocked at Seed
454
+ decision = engine.beforeToolCall({
455
+ toolName: 'write',
456
+ isRiskPath: true,
457
+ lineCount: 10,
458
+ });
459
+ expect(decision.allowed).toBe(false);
460
+
461
+ // Work hard, grow to Forest
462
+ for (let i = 0; i < 125; i++) {
463
+ engine.recordSuccess('write', { difficulty: 'hard' });
464
+ }
465
+
466
+ // Now Forest - can do anything
467
+ decision = engine.beforeToolCall({
468
+ toolName: 'write',
469
+ content: Array(1000).fill('line').join('\n'),
470
+ });
471
+ expect(decision.allowed).toBe(true);
472
+
473
+ decision = engine.beforeToolCall({
474
+ toolName: 'sessions_spawn',
475
+ });
476
+ expect(decision.allowed).toBe(true);
477
+
478
+ decision = engine.beforeToolCall({
479
+ toolName: 'write',
480
+ filePath: 'src/core/trust-engine.ts',
481
+ isRiskPath: true,
482
+ });
483
+ expect(decision.allowed).toBe(true);
484
+ });
485
+
486
+ test('agent recovers from failure without losing progress', () => {
487
+ // Record some successes
488
+ for (let i = 0; i < 10; i++) {
489
+ engine.recordSuccess('write', { difficulty: 'normal' });
490
+ }
491
+ const pointsBeforeFailure = engine.getPoints();
492
+
493
+ // Record failures
494
+ engine.recordFailure('write', { filePath: 'test.ts' });
495
+ engine.recordFailure('write', { filePath: 'test2.ts' });
496
+
497
+ // Points should not decrease
498
+ expect(engine.getPoints()).toBe(pointsBeforeFailure);
499
+
500
+ // Recover with double reward
501
+ const result = engine.recordSuccess('write', { filePath: 'test.ts', difficulty: 'normal' });
502
+ expect(result.isDoubleReward).toBe(true);
503
+ expect(engine.getPoints()).toBeGreaterThan(pointsBeforeFailure);
504
+ });
505
+
506
+ test('status summary reflects gate permissions', () => {
507
+ const summary = engine.getStatusSummary();
508
+
509
+ expect(summary.tier).toBe(EvolutionTier.Seed);
510
+ expect(summary.permissions.maxLinesPerWrite).toBe(150);
511
+ expect(summary.permissions.allowRiskPath).toBe(false);
512
+ expect(summary.permissions.allowSubagentSpawn).toBe(true); // Allowed at Seed tier
513
+
514
+ // Earn promotion to Sapling (risk path unlocks)
515
+ for (let i = 0; i < 26; i++) {
516
+ engine.recordSuccess('write', { difficulty: 'hard' });
517
+ }
518
+
519
+ const summaryAfter = engine.getStatusSummary();
520
+ expect(summaryAfter.permissions.allowRiskPath).toBe(true);
521
+ });
522
+
523
+ test('different workspaces have independent gate state', () => {
524
+ const engine1 = new EvolutionEngine(workspace);
525
+ const workspace2 = createTempWorkspace();
526
+ const engine2 = new EvolutionEngine(workspace2);
527
+
528
+ // Engine 1 promotes to Sapling
529
+ for (let i = 0; i < 26; i++) {
530
+ engine1.recordSuccess('write', { difficulty: 'hard' });
531
+ }
532
+
533
+ // Engine 1 has risk path permission (Sapling tier)
534
+ let decision1 = engine1.beforeToolCall({ toolName: 'write', isRiskPath: true, lineCount: 10 });
535
+ expect(decision1.allowed).toBe(true);
536
+
537
+ // Engine 2 is still Seed - risk path blocked
538
+ let decision2 = engine2.beforeToolCall({ toolName: 'write', isRiskPath: true, lineCount: 10 });
539
+ expect(decision2.allowed).toBe(false);
540
+
541
+ cleanupWorkspace(workspace2);
542
+ });
543
+ });