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,160 @@
1
+ /**
2
+ * Gate Block Helper - Single Authoritative Block Persistence
3
+ *
4
+ * PURPOSE: Provide ONE authoritative implementation for gate block persistence.
5
+ *
6
+ * All gate modules (progressive-trust-gate, gfi-gate, etc.) must use this
7
+ * helper to ensure consistent block tracking, event logging, and retry behavior.
8
+ *
9
+ * This eliminates the "multi-truth source" problem where different modules
10
+ * had their own block persistence implementations.
11
+ */
12
+
13
+ import { trackBlock } from '../core/session-tracker.js';
14
+ import type { WorkspaceContext } from '../core/workspace-context.js';
15
+ import type { PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
16
+ import {
17
+ TRAJECTORY_GATE_BLOCK_RETRY_DELAY_MS,
18
+ TRAJECTORY_GATE_BLOCK_MAX_RETRIES
19
+ } from '../config/index.js';
20
+
21
+ /**
22
+ * Block context containing all information needed for block persistence
23
+ */
24
+ export interface BlockContext {
25
+ filePath: string;
26
+ reason: string;
27
+ toolName: string;
28
+ sessionId?: string;
29
+ /** Source module that triggered the block (for audit trail) */
30
+ blockSource?: string;
31
+ }
32
+
33
+ /**
34
+ * Single authoritative block helper.
35
+ *
36
+ * Responsibilities:
37
+ * 1. Call trackBlock() for session-level GFI tracking
38
+ * 2. Record to EventLog for operator visibility
39
+ * 3. Record to trajectory for analytics
40
+ * 4. Handle retry logic for trajectory persistence failures
41
+ * 5. Generate consistent operator-facing block message
42
+ *
43
+ * @param wctx - Workspace context
44
+ * @param blockCtx - Block context with file, reason, tool info
45
+ * @param logger - Logger instance
46
+ * @returns PluginHookBeforeToolCallResult with block=true
47
+ */
48
+ export function recordGateBlockAndReturn(
49
+ wctx: WorkspaceContext,
50
+ blockCtx: BlockContext,
51
+ logger: { warn?: (message: string) => void; error?: (message: string) => void; info?: (message: string) => void }
52
+ ): PluginHookBeforeToolCallResult {
53
+ const { filePath, reason, toolName, sessionId, blockSource } = blockCtx;
54
+
55
+ // Default logger if not provided
56
+ const logWarn = (msg: string) => logger.warn?.(msg);
57
+ const logError = (msg: string) => logger.error?.(msg);
58
+
59
+ // Log the block event
60
+ const sourceTag = blockSource ? `[${blockSource}]` : '';
61
+ logError(`[PD_GATE]${sourceTag} BLOCKED: ${filePath}. Reason: ${reason}`);
62
+
63
+ // 1. Track block for session-level GFI calculation
64
+ if (sessionId) {
65
+ trackBlock(sessionId);
66
+ }
67
+
68
+ // 2. Prepare trajectory payload
69
+ const trajectoryPayload = {
70
+ sessionId: sessionId ?? null,
71
+ toolName,
72
+ filePath,
73
+ reason,
74
+ blockSource: blockSource ?? 'gate',
75
+ };
76
+
77
+ // 3. Record to EventLog (primary persistence)
78
+ try {
79
+ wctx.eventLog.recordGateBlock(sessionId, {
80
+ toolName,
81
+ filePath,
82
+ reason,
83
+ blockSource: blockSource ?? 'gate',
84
+ });
85
+ } catch (error: unknown) {
86
+ logWarn(`[PD_GATE] Failed to record gate block event: ${String(error)}`);
87
+ }
88
+
89
+ // 4. Record to trajectory (secondary persistence with retry)
90
+ try {
91
+ wctx.trajectory?.recordGateBlock?.(trajectoryPayload);
92
+ } catch (error: unknown) {
93
+ logWarn(`[PD_GATE] Failed to record trajectory gate block: ${String(error)}`);
94
+ scheduleTrajectoryGateBlockRetry(wctx, trajectoryPayload, 1, logWarn, logError);
95
+ }
96
+
97
+ // 5. Return consistent block result with operator guidance
98
+ return {
99
+ block: true,
100
+ blockReason: `[Principles Disciple] Security Gate Blocked this action.
101
+ File: ${filePath}
102
+ Reason: ${reason}
103
+
104
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
105
+ 📋 How to unblock this operation:
106
+
107
+ 1. Use the plan-script skill to create a PLAN.md:
108
+ → Invoke: skill:plan-script
109
+
110
+ 2. Fill in the plan with:
111
+ - Target Files: ${filePath}
112
+ - Steps: What you want to do (be specific)
113
+ - Metrics: How to verify success
114
+ - Active Mental Models: Select 2 relevant models from .principles/THINKING_OS.md
115
+ - Rollback: How to restore if it fails
116
+
117
+ 3. After completing the plan, set STATUS: READY in PLAN.md
118
+
119
+ 4. Retry the operation
120
+
121
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
122
+ This is a mandatory security gate. The operation was blocked because the modification exceeds the allowed threshold for your current evolution tier.
123
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Schedule retry for trajectory gate block persistence.
129
+ *
130
+ * Uses exponential backoff with max retries.
131
+ * Failures are logged but do not affect the runtime block decision.
132
+ */
133
+ function scheduleTrajectoryGateBlockRetry(
134
+ wctx: WorkspaceContext,
135
+ payload: {
136
+ sessionId: string | null;
137
+ toolName: string;
138
+ filePath: string;
139
+ reason: string;
140
+ blockSource?: string;
141
+ },
142
+ attempt: number,
143
+ logWarn: (message: string) => void,
144
+ logError: (message: string) => void
145
+ ): void {
146
+ if (attempt > TRAJECTORY_GATE_BLOCK_MAX_RETRIES) {
147
+ logError(`[PD_GATE] Failed to persist trajectory gate block after ${TRAJECTORY_GATE_BLOCK_MAX_RETRIES} retries: ${payload.toolName} ${payload.filePath}`);
148
+ return;
149
+ }
150
+
151
+ setTimeout(() => {
152
+ try {
153
+ wctx.trajectory?.recordGateBlock?.(payload);
154
+ logWarn(`[PD_GATE] Trajectory gate block persisted on retry ${attempt}`);
155
+ } catch (error: unknown) {
156
+ logWarn(`[PD_GATE] Retrying trajectory gate block persistence (attempt ${attempt + 1}): ${String(error)}`);
157
+ scheduleTrajectoryGateBlockRetry(wctx, payload, attempt + 1, logWarn, logError);
158
+ }
159
+ }, TRAJECTORY_GATE_BLOCK_RETRY_DELAY_MS * attempt);
160
+ }
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Security Gate Hook - Orchestration Layer
3
+ *
4
+ * HOOK CHAIN PRIORITY (short-circuits on first block):
5
+ *
6
+ * 1. Early Return: Skip if not write/bash/agent tool or no workspace
7
+ * 2. Thinking OS Checkpoint (P-10): Deep reflection enforcement
8
+ * 3. GFI Gate: Fatigue index-based blocking
9
+ * 4. Bash Mutation Detection: Heuristic for bash file modifications
10
+ * 5. Progressive Gate: EP tier-based access control
11
+ * 6. Edit Verification (P-03): Exact/fuzzy match for edit operations
12
+ *
13
+ * IMPORTANT: This is the SINGLE AUTHORITATIVE orchestration path.
14
+ * All policy modules (gfi-gate, progressive-trust-gate) use the shared
15
+ * `recordGateBlockAndReturn` helper to ensure consistent block persistence.
16
+ *
17
+ * Zero-width character detection is handled in bash-risk.ts.
18
+ */
19
+
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import { isRisky, normalizePath, planStatus as getPlanStatus } from '../utils/io.js';
23
+ import { normalizeProfile } from '../core/profile.js';
24
+ import { estimateLineChanges } from '../core/risk-calculator.js';
25
+ import { WorkspaceContext } from '../core/workspace-context.js';
26
+ import { checkThinkingCheckpoint } from './thinking-checkpoint.js';
27
+ import { handleEditVerification } from './edit-verification.js';
28
+ import { checkGfiGate } from './gfi-gate.js';
29
+ import { checkProgressiveTrustGate } from './progressive-trust-gate.js';
30
+ import { recordGateBlockAndReturn } from './gate-block-helper.js';
31
+ import type { PluginHookBeforeToolCallEvent, PluginHookToolContext, PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
32
+ import {
33
+ AGENT_TOOLS,
34
+ BASH_TOOLS_SET,
35
+ WRITE_TOOLS,
36
+ } from '../constants/tools.js';
37
+
38
+ export function handleBeforeToolCall(
39
+ event: PluginHookBeforeToolCallEvent,
40
+ ctx: PluginHookToolContext & { workspaceDir?: string; pluginConfig?: Record<string, unknown>; logger?: any }
41
+ ): PluginHookBeforeToolCallResult | void {
42
+ const logger = ctx.logger || console;
43
+
44
+ // 1. Identify tool type
45
+ const isBash = BASH_TOOLS_SET.has(event.toolName);
46
+ const isWriteTool = WRITE_TOOLS.has(event.toolName);
47
+ const isAgentTool = AGENT_TOOLS.has(event.toolName);
48
+
49
+ if (!ctx.workspaceDir || (!isWriteTool && !isBash && !isAgentTool)) {
50
+ return;
51
+ }
52
+
53
+ const wctx = WorkspaceContext.fromHookContext(ctx);
54
+
55
+ // 2. Load Profile
56
+ const profilePath = wctx.resolve('PROFILE');
57
+ let profile = {
58
+ risk_paths: [] as string[],
59
+ gate: { require_plan_for_risk_paths: true },
60
+ progressive_gate: {
61
+ enabled: true,
62
+ plan_approvals: {
63
+ enabled: false,
64
+ max_lines_override: -1,
65
+ allowed_patterns: [] as string[],
66
+ allowed_operations: [] as string[],
67
+ }
68
+ },
69
+ edit_verification: {
70
+ enabled: true,
71
+ max_file_size_bytes: 10 * 1024 * 1024,
72
+ fuzzy_match_enabled: true,
73
+ fuzzy_match_threshold: 0.8,
74
+ skip_large_file_action: 'warn' as 'warn' | 'block',
75
+ },
76
+ thinking_checkpoint: {
77
+ enabled: false, // Default OFF
78
+ window_ms: 5 * 60 * 1000,
79
+ high_risk_tools: ['run_shell_command', 'delete_file', 'move_file'],
80
+ }
81
+ };
82
+
83
+ if (fs.existsSync(profilePath)) {
84
+ try {
85
+ const rawProfile = JSON.parse(fs.readFileSync(profilePath, 'utf8'));
86
+ profile = normalizeProfile(rawProfile);
87
+ } catch (e) {
88
+ logger?.error?.(`[PD_GATE] Failed to parse PROFILE.json: ${String(e)}`);
89
+ }
90
+ }
91
+
92
+ // ─────────────────────────────────────────────────────────────────────────────
93
+ // POLICY STEP 1: Thinking OS Checkpoint (P-10)
94
+ // ─────────────────────────────────────────────────────────────────────────────
95
+ // Only enforced when thinking_checkpoint.enabled = true in PROFILE.json
96
+ const thinkingResult = checkThinkingCheckpoint(
97
+ event,
98
+ profile.thinking_checkpoint || {},
99
+ ctx.sessionId,
100
+ logger
101
+ );
102
+ if (thinkingResult) {
103
+ return thinkingResult;
104
+ }
105
+
106
+ // ─────────────────────────────────────────────────────────────────────────────
107
+ // POLICY STEP 2: GFI Gate - Hard Intercept
108
+ // ─────────────────────────────────────────────────────────────────────────────
109
+ // 根据 GFI (疲劳指数) 精细化拦截工具调用
110
+ // 注意:TIER 0 (只读工具) 已在早期过滤中放行,此处不检查
111
+ const gfiGateConfig = wctx.config.get('gfi_gate');
112
+ const gfiResult = checkGfiGate(event, wctx, ctx.sessionId, gfiGateConfig, logger);
113
+ if (gfiResult) {
114
+ return gfiResult;
115
+ }
116
+
117
+ // Merge pluginConfig (OpenClaw UI settings)
118
+ const configRiskPaths = (ctx.pluginConfig?.riskPaths as string[] | undefined) ?? [];
119
+ if (configRiskPaths.length > 0) {
120
+ profile.risk_paths = [...new Set([...profile.risk_paths, ...configRiskPaths])];
121
+ }
122
+
123
+ // 3. Resolve the target file path
124
+ let filePath = event.params.file_path || event.params.path || event.params.file || event.params.target;
125
+
126
+ // Heuristic for bash mutation detection
127
+ if (isBash && !filePath) {
128
+ const command = String(event.params.command || event.params.args || "");
129
+ const mutationMatch = command.match(/(?:>|>>|sed\s+-i|rm|mv|mkdir|touch|cp)\s+(?:-[a-zA-Z]+\s+)*([^\s;&|<>]+)/);
130
+
131
+ if (mutationMatch) {
132
+ filePath = mutationMatch[1];
133
+ } else {
134
+ const hasRiskPath = profile.risk_paths.some(rp => command.includes(rp));
135
+ const isMutation = /(?:>|>>|sed|rm|mv|mkdir|touch|cp|npm|yarn|pnpm|pip|cargo)/.test(command);
136
+
137
+ if (hasRiskPath && isMutation) {
138
+ filePath = command;
139
+ } else {
140
+ return;
141
+ }
142
+ }
143
+ }
144
+
145
+ if (typeof filePath !== 'string') return;
146
+
147
+ const relPath = normalizePath(filePath, ctx.workspaceDir);
148
+ const risky = (isBash && filePath.includes(' '))
149
+ ? profile.risk_paths.some(rp => filePath.includes(rp))
150
+ : isRisky(relPath, profile.risk_paths);
151
+
152
+ // ─────────────────────────────────────────────────────────────────────────────
153
+ // POLICY STEP 3: Progressive Trust Gate (Stage 1-4 access control)
154
+ // ─────────────────────────────────────────────────────────────────────────────
155
+ // IMPORTANT: This step does NOT return early on allow.
156
+ // We must continue to edit verification for ALL allowed operations.
157
+ if (profile.progressive_gate?.enabled) {
158
+ const lineChanges = estimateLineChanges({ toolName: event.toolName, params: event.params });
159
+ const progressiveGateResult = checkProgressiveTrustGate(
160
+ event,
161
+ wctx,
162
+ relPath,
163
+ risky,
164
+ lineChanges,
165
+ logger,
166
+ ctx,
167
+ profile
168
+ );
169
+ if (progressiveGateResult) {
170
+ return progressiveGateResult;
171
+ }
172
+ // NOTE: Do NOT return here! Continue to edit verification.
173
+ // All allowed operations (regardless of EP tier) should still run edit verification.
174
+ } else {
175
+ // FALLBACK: Legacy Gate Logic (when progressive gate is disabled)
176
+ if (risky && profile.gate?.require_plan_for_risk_paths) {
177
+ const planStatus = getPlanStatus(ctx.workspaceDir);
178
+ if (planStatus !== 'READY') {
179
+ return recordGateBlockAndReturn(wctx, {
180
+ filePath: relPath,
181
+ reason: `No READY plan found in PLAN.md.`,
182
+ toolName: event.toolName,
183
+ sessionId: ctx.sessionId,
184
+ blockSource: 'gate-legacy',
185
+ }, logger);
186
+ }
187
+ }
188
+ }
189
+
190
+ // ─────────────────────────────────────────────────────────────────────────────
191
+ // POLICY STEP 4: Edit Tool Verification (P-03)
192
+ // ─────────────────────────────────────────────────────────────────────────────
193
+ // This MUST run after all other gate checks for ALL tools.
194
+ // Edit verification ensures oldText matches the actual file content.
195
+ if (event.toolName === 'edit' && profile.edit_verification?.enabled !== false) {
196
+ const verifyResult = handleEditVerification(event, wctx, ctx, {
197
+ enabled: profile.edit_verification.enabled,
198
+ max_file_size_bytes: profile.edit_verification.max_file_size_bytes,
199
+ fuzzy_match_enabled: profile.edit_verification.fuzzy_match_enabled,
200
+ fuzzy_match_threshold: profile.edit_verification.fuzzy_match_threshold,
201
+ skip_large_file_action: profile.edit_verification.skip_large_file_action as 'warn' | 'block' | undefined,
202
+ });
203
+ if (verifyResult) {
204
+ return verifyResult; // Block or modify params
205
+ }
206
+ }
207
+
208
+ // All checks passed - allow the operation
209
+ return;
210
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * GFI Gate Module
3
+ *
4
+ * Handles Fatigue Index (GFI) based tool blocking with TIER 0-3 classification.
5
+ *
6
+ * **Responsibilities:**
7
+ * - Calculate dynamic GFI thresholds based on EP tier and line changes
8
+ * - Apply tier-based tool blocking:
9
+ * - TIER 0: Read-only tools (never blocked)
10
+ * - TIER 1: Low-risk writes (blocked when GFI >= low_risk_block threshold)
11
+ * - TIER 2: High-risk operations (blocked when GFI >= high_risk_block threshold)
12
+ * - TIER 3: Bash commands (content-dependent blocking)
13
+ * - Prevent subagent spawn at critically high GFI (>=90)
14
+ *
15
+ * **Configuration:**
16
+ * - GFI thresholds from config.gfi_gate
17
+ * - EP tier multipliers for dynamic threshold calculation
18
+ * - Large change adjustments
19
+ *
20
+ * **Block Persistence:**
21
+ * - Uses shared `recordGateBlockAndReturn` from gate-block-helper.ts
22
+ * - Ensures single authoritative block persistence path
23
+ */
24
+
25
+ import { getSession } from '../core/session-tracker.js';
26
+ import { estimateLineChanges } from '../core/risk-calculator.js';
27
+ import { analyzeBashCommand, calculateDynamicThreshold, type DynamicThresholdConfig } from './bash-risk.js';
28
+ import { BASH_TOOLS_SET, HIGH_RISK_TOOLS, LOW_RISK_WRITE_TOOLS, AGENT_TOOLS } from '../constants/tools.js';
29
+ import { AGENT_SPAWN_GFI_THRESHOLD } from '../config/index.js';
30
+ import { recordGateBlockAndReturn } from './gate-block-helper.js';
31
+ import { getEvolutionEngine } from '../core/evolution-engine.js';
32
+ import type { WorkspaceContext } from '../core/workspace-context.js';
33
+ import type { PluginHookBeforeToolCallEvent, PluginHookBeforeToolCallResult } from '../openclaw-sdk.js';
34
+
35
+ export interface GfiGateConfig {
36
+ enabled?: boolean;
37
+ thresholds?: {
38
+ low_risk_block?: number;
39
+ high_risk_block?: number;
40
+ };
41
+ large_change_lines?: number;
42
+ ep_tier_multipliers?: Record<string, number>;
43
+ bash_safe_patterns?: string[];
44
+ bash_dangerous_patterns?: string[];
45
+ }
46
+
47
+ /**
48
+ * Internal helper to call the shared block helper with gfi-gate source tag.
49
+ */
50
+ function block(
51
+ wctx: WorkspaceContext,
52
+ filePath: string,
53
+ reason: string,
54
+ toolName: string,
55
+ sessionId: string | undefined,
56
+ logger?: { info?: (message: string) => void; warn?: (message: string) => void; error?: (message: string) => void }
57
+ ): PluginHookBeforeToolCallResult {
58
+ return recordGateBlockAndReturn(wctx, {
59
+ filePath,
60
+ reason,
61
+ toolName,
62
+ sessionId,
63
+ blockSource: 'gfi-gate',
64
+ }, logger || { warn: () => {}, error: () => {} });
65
+ }
66
+
67
+ export function checkGfiGate(
68
+ event: PluginHookBeforeToolCallEvent,
69
+ wctx: WorkspaceContext,
70
+ sessionId: string | undefined,
71
+ config: GfiGateConfig,
72
+ logger?: { info?: (message: string) => void; warn?: (message: string) => void }
73
+ ): PluginHookBeforeToolCallResult | undefined {
74
+ if (!config || config.enabled === false || !sessionId) {
75
+ return undefined;
76
+ }
77
+
78
+ const session = getSession(sessionId);
79
+ const currentGfi = session?.currentGfi || 0;
80
+
81
+ const getEpTier = (): number => {
82
+ return getEvolutionEngine(wctx.workspaceDir).getTier();
83
+ };
84
+
85
+ // TIER 3: Bash commands
86
+ if (BASH_TOOLS_SET.has(event.toolName)) {
87
+ const command = String(event.params.command || event.params.args || '');
88
+ const bashRisk = analyzeBashCommand(
89
+ command,
90
+ config.bash_safe_patterns || [],
91
+ config.bash_dangerous_patterns || [],
92
+ logger
93
+ );
94
+
95
+ if (bashRisk === 'dangerous') {
96
+ logger?.warn?.(`[PD:GFI_GATE] Dangerous bash command blocked: ${command.substring(0, 50)}...`);
97
+ return block(wctx, command.substring(0, 100), `危险命令被拦截。检测到危险命令模式,需要确认执行意图。`, event.toolName, sessionId, logger);
98
+ }
99
+
100
+ if (bashRisk === 'safe') {
101
+ return undefined;
102
+ }
103
+
104
+ // normal bash - check GFI threshold
105
+ const tier = getEpTier();
106
+ const baseThreshold = config.thresholds?.low_risk_block || 70;
107
+ const dynamicThreshold = calculateDynamicThreshold(
108
+ baseThreshold,
109
+ tier,
110
+ 0,
111
+ {
112
+ large_change_lines: config.large_change_lines || 50,
113
+ ep_tier_multipliers: config.ep_tier_multipliers || { '1': 0.5, '2': 0.75, '3': 1.0, '4': 1.5, '5': 2.0 },
114
+ }
115
+ );
116
+
117
+ if (currentGfi >= dynamicThreshold) {
118
+ logger?.warn?.(`[PD:GFI_GATE] Bash blocked by GFI: ${currentGfi} >= ${dynamicThreshold}`);
119
+ return block(wctx, command.substring(0, 100), `疲劳指数过高 (GFI: ${currentGfi}/${dynamicThreshold})。系统进入保护模式。`, event.toolName, sessionId, logger);
120
+ }
121
+
122
+ return undefined;
123
+ }
124
+
125
+ // TIER 2: High-risk tools
126
+ if (HIGH_RISK_TOOLS.has(event.toolName)) {
127
+ const tier = getEpTier();
128
+ const baseThreshold = config.thresholds?.high_risk_block || 40;
129
+ const dynamicThreshold = calculateDynamicThreshold(
130
+ baseThreshold,
131
+ tier,
132
+ 0,
133
+ {
134
+ large_change_lines: config.large_change_lines || 50,
135
+ ep_tier_multipliers: config.ep_tier_multipliers || { '1': 0.5, '2': 0.75, '3': 1.0, '4': 1.5, '5': 2.0 },
136
+ }
137
+ );
138
+
139
+ if (currentGfi >= dynamicThreshold) {
140
+ const filePath = event.params.file_path || event.params.path || event.params.file || event.params.target || 'unknown';
141
+ logger?.warn?.(`[PD:GFI_GATE] High-risk tool "${event.toolName}" blocked by GFI: ${currentGfi} >= ${dynamicThreshold}`);
142
+ return block(wctx, filePath, `高风险操作被拦截。GFI: ${currentGfi}/${dynamicThreshold}。高风险工具需要更低的阈值。`, event.toolName, sessionId, logger);
143
+ }
144
+ }
145
+
146
+ // TIER 1: Low-risk write tools
147
+ if (LOW_RISK_WRITE_TOOLS.has(event.toolName)) {
148
+ const tier = getEpTier();
149
+ const lineChanges = estimateLineChanges({ toolName: event.toolName, params: event.params });
150
+ const baseThreshold = config.thresholds?.low_risk_block || 70;
151
+ const dynamicThreshold = calculateDynamicThreshold(
152
+ baseThreshold,
153
+ tier,
154
+ lineChanges,
155
+ {
156
+ large_change_lines: config.large_change_lines || 50,
157
+ ep_tier_multipliers: config.ep_tier_multipliers || { '1': 0.5, '2': 0.75, '3': 1.0, '4': 1.5, '5': 2.0 },
158
+ }
159
+ );
160
+
161
+ if (currentGfi >= dynamicThreshold) {
162
+ const filePath = event.params.file_path || event.params.path || event.params.file || event.params.target || 'unknown';
163
+ logger?.warn?.(`[PD:GFI_GATE] Low-risk tool "${event.toolName}" blocked by GFI: ${currentGfi} >= ${dynamicThreshold}`);
164
+ return block(wctx, filePath, `疲劳指数过高 (GFI: ${currentGfi}/${dynamicThreshold})。系统进入保护模式。`, event.toolName, sessionId, logger);
165
+ }
166
+ }
167
+
168
+ // AGENT_TOOLS: Block subagent spawn when GFI is critically high
169
+ if (AGENT_TOOLS.has(event.toolName)) {
170
+ if (currentGfi >= AGENT_SPAWN_GFI_THRESHOLD) {
171
+ logger?.warn?.(`[PD:GFI_GATE] Agent tool "${event.toolName}" blocked by GFI: ${currentGfi} >= ${AGENT_SPAWN_GFI_THRESHOLD}`);
172
+ return block(wctx, 'subagent-spawn', `疲劳指数过高,禁止派生子智能体。GFI: ${currentGfi}/${AGENT_SPAWN_GFI_THRESHOLD}`, event.toolName, sessionId, logger);
173
+ }
174
+ }
175
+
176
+ return undefined;
177
+ }