@winspan/claude-forge 9.2.0 → 9.12.0

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 (591) hide show
  1. package/DEVELOPMENT.md +80 -19
  2. package/README.md +13 -6
  3. package/dist/catalogs/agents.json +19 -24
  4. package/dist/catalogs/skills.json +139 -27
  5. package/dist/claudemd/templates/swarm-protocol.md +1 -1
  6. package/dist/cli/commands/agent.d.ts +169 -0
  7. package/dist/cli/commands/agent.d.ts.map +1 -0
  8. package/dist/cli/commands/agent.js +690 -0
  9. package/dist/cli/commands/agent.js.map +1 -0
  10. package/dist/cli/commands/codegraph.d.ts +17 -0
  11. package/dist/cli/commands/codegraph.d.ts.map +1 -0
  12. package/dist/cli/commands/codegraph.js +263 -0
  13. package/dist/cli/commands/codegraph.js.map +1 -0
  14. package/dist/cli/commands/decisions.d.ts.map +1 -1
  15. package/dist/cli/commands/decisions.js +46 -9
  16. package/dist/cli/commands/decisions.js.map +1 -1
  17. package/dist/cli/commands/executions.d.ts.map +1 -1
  18. package/dist/cli/commands/executions.js +2 -1
  19. package/dist/cli/commands/executions.js.map +1 -1
  20. package/dist/cli/commands/insights-goal-check.d.ts +5 -1
  21. package/dist/cli/commands/insights-goal-check.d.ts.map +1 -1
  22. package/dist/cli/commands/insights-goal-check.js +15 -15
  23. package/dist/cli/commands/insights-goal-check.js.map +1 -1
  24. package/dist/cli/commands/knowledge.d.ts +51 -0
  25. package/dist/cli/commands/knowledge.d.ts.map +1 -1
  26. package/dist/cli/commands/knowledge.js +202 -29
  27. package/dist/cli/commands/knowledge.js.map +1 -1
  28. package/dist/cli/commands/loop.d.ts +95 -0
  29. package/dist/cli/commands/loop.d.ts.map +1 -0
  30. package/dist/cli/commands/loop.js +408 -0
  31. package/dist/cli/commands/loop.js.map +1 -0
  32. package/dist/cli/commands/maintenance.d.ts +33 -0
  33. package/dist/cli/commands/maintenance.d.ts.map +1 -0
  34. package/dist/cli/commands/maintenance.js +75 -0
  35. package/dist/cli/commands/maintenance.js.map +1 -0
  36. package/dist/cli/commands/mcp.d.ts +23 -0
  37. package/dist/cli/commands/mcp.d.ts.map +1 -1
  38. package/dist/cli/commands/mcp.js +82 -0
  39. package/dist/cli/commands/mcp.js.map +1 -1
  40. package/dist/cli/commands/skills.d.ts +131 -0
  41. package/dist/cli/commands/skills.d.ts.map +1 -1
  42. package/dist/cli/commands/skills.js +409 -9
  43. package/dist/cli/commands/skills.js.map +1 -1
  44. package/dist/cli/commands/stats.d.ts.map +1 -1
  45. package/dist/cli/commands/stats.js +9 -2
  46. package/dist/cli/commands/stats.js.map +1 -1
  47. package/dist/cli/index.js +8 -0
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/core/constants.d.ts +37 -0
  50. package/dist/core/constants.d.ts.map +1 -1
  51. package/dist/core/constants.js +43 -0
  52. package/dist/core/constants.js.map +1 -1
  53. package/dist/core/diagnostics/checks.d.ts.map +1 -1
  54. package/dist/core/diagnostics/checks.js +2 -1
  55. package/dist/core/diagnostics/checks.js.map +1 -1
  56. package/dist/core/diagnostics/daemon-status.d.ts +1 -1
  57. package/dist/core/diagnostics/daemon-status.d.ts.map +1 -1
  58. package/dist/core/diagnostics/daemon-status.js +1 -1
  59. package/dist/core/diagnostics/daemon-status.js.map +1 -1
  60. package/dist/core/diagnostics/entropy-checks.d.ts +3 -2
  61. package/dist/core/diagnostics/entropy-checks.d.ts.map +1 -1
  62. package/dist/core/diagnostics/entropy-checks.js +10 -5
  63. package/dist/core/diagnostics/entropy-checks.js.map +1 -1
  64. package/dist/core/diagnostics/heartbeat-reader.d.ts +28 -0
  65. package/dist/core/diagnostics/heartbeat-reader.d.ts.map +1 -0
  66. package/dist/core/diagnostics/heartbeat-reader.js +50 -0
  67. package/dist/core/diagnostics/heartbeat-reader.js.map +1 -0
  68. package/dist/core/event-fields.d.ts +27 -0
  69. package/dist/core/event-fields.d.ts.map +1 -1
  70. package/dist/core/event-fields.js +43 -0
  71. package/dist/core/event-fields.js.map +1 -1
  72. package/dist/core/governance/global-inject.d.ts +34 -4
  73. package/dist/core/governance/global-inject.d.ts.map +1 -1
  74. package/dist/core/governance/global-inject.js +80 -25
  75. package/dist/core/governance/global-inject.js.map +1 -1
  76. package/dist/core/insights/agent-anchor-guard.d.ts +77 -0
  77. package/dist/core/insights/agent-anchor-guard.d.ts.map +1 -0
  78. package/dist/core/insights/agent-anchor-guard.js +119 -0
  79. package/dist/core/insights/agent-anchor-guard.js.map +1 -0
  80. package/dist/core/insights/agent-distill-context.d.ts +55 -0
  81. package/dist/core/insights/agent-distill-context.d.ts.map +1 -0
  82. package/dist/core/insights/agent-distill-context.js +146 -0
  83. package/dist/core/insights/agent-distill-context.js.map +1 -0
  84. package/dist/core/insights/agent-distill-spawn.d.ts +56 -0
  85. package/dist/core/insights/agent-distill-spawn.d.ts.map +1 -0
  86. package/dist/core/insights/agent-distill-spawn.js +179 -0
  87. package/dist/core/insights/agent-distill-spawn.js.map +1 -0
  88. package/dist/core/insights/agent-drift.d.ts +66 -0
  89. package/dist/core/insights/agent-drift.d.ts.map +1 -0
  90. package/dist/core/insights/agent-drift.js +109 -0
  91. package/dist/core/insights/agent-drift.js.map +1 -0
  92. package/dist/core/insights/agent-evolution-sources.d.ts +21 -0
  93. package/dist/core/insights/agent-evolution-sources.d.ts.map +1 -0
  94. package/dist/core/insights/agent-evolution-sources.js +36 -0
  95. package/dist/core/insights/agent-evolution-sources.js.map +1 -0
  96. package/dist/core/insights/agent-health.d.ts +142 -0
  97. package/dist/core/insights/agent-health.d.ts.map +1 -0
  98. package/dist/core/insights/agent-health.js +296 -0
  99. package/dist/core/insights/agent-health.js.map +1 -0
  100. package/dist/core/insights/agent-patch-apply.d.ts +45 -0
  101. package/dist/core/insights/agent-patch-apply.d.ts.map +1 -0
  102. package/dist/core/insights/agent-patch-apply.js +165 -0
  103. package/dist/core/insights/agent-patch-apply.js.map +1 -0
  104. package/dist/core/insights/agent-suggest.d.ts +128 -0
  105. package/dist/core/insights/agent-suggest.d.ts.map +1 -0
  106. package/dist/core/insights/agent-suggest.js +284 -0
  107. package/dist/core/insights/agent-suggest.js.map +1 -0
  108. package/dist/core/insights/coverage-tiers.d.ts +46 -0
  109. package/dist/core/insights/coverage-tiers.d.ts.map +1 -0
  110. package/dist/core/insights/coverage-tiers.js +95 -0
  111. package/dist/core/insights/coverage-tiers.js.map +1 -0
  112. package/dist/{daemon/services → core/insights}/experience-extractor.d.ts +0 -7
  113. package/dist/core/insights/experience-extractor.d.ts.map +1 -0
  114. package/dist/{daemon/services → core/insights}/experience-extractor.js +5 -9
  115. package/dist/core/insights/experience-extractor.js.map +1 -0
  116. package/dist/{daemon/services → core/insights}/violation-reporter.d.ts +20 -1
  117. package/dist/core/insights/violation-reporter.d.ts.map +1 -0
  118. package/dist/{daemon/services → core/insights}/violation-reporter.js +56 -4
  119. package/dist/core/insights/violation-reporter.js.map +1 -0
  120. package/dist/core/loop/loop-engine.d.ts +140 -0
  121. package/dist/core/loop/loop-engine.d.ts.map +1 -0
  122. package/dist/core/loop/loop-engine.js +266 -0
  123. package/dist/core/loop/loop-engine.js.map +1 -0
  124. package/dist/core/queue/index.d.ts.map +1 -1
  125. package/dist/core/queue/index.js +2 -1
  126. package/dist/core/queue/index.js.map +1 -1
  127. package/dist/core/storage/base.d.ts +159 -0
  128. package/dist/core/storage/base.d.ts.map +1 -1
  129. package/dist/core/storage/base.js +523 -0
  130. package/dist/core/storage/base.js.map +1 -1
  131. package/dist/core/storage/codegraph-types.d.ts +79 -0
  132. package/dist/core/storage/codegraph-types.d.ts.map +1 -0
  133. package/dist/core/storage/codegraph-types.js +14 -0
  134. package/dist/core/storage/codegraph-types.js.map +1 -0
  135. package/dist/core/storage/codegraph.d.ts +186 -0
  136. package/dist/core/storage/codegraph.d.ts.map +1 -0
  137. package/dist/core/storage/codegraph.js +452 -0
  138. package/dist/core/storage/codegraph.js.map +1 -0
  139. package/dist/core/storage/decisions.d.ts +30 -5
  140. package/dist/core/storage/decisions.d.ts.map +1 -1
  141. package/dist/core/storage/decisions.js +45 -13
  142. package/dist/core/storage/decisions.js.map +1 -1
  143. package/dist/core/storage/events.d.ts +127 -0
  144. package/dist/core/storage/events.d.ts.map +1 -1
  145. package/dist/core/storage/events.js +318 -3
  146. package/dist/core/storage/events.js.map +1 -1
  147. package/dist/core/storage/feedback.d.ts +3 -23
  148. package/dist/core/storage/feedback.d.ts.map +1 -1
  149. package/dist/core/storage/feedback.js +37 -38
  150. package/dist/core/storage/feedback.js.map +1 -1
  151. package/dist/core/storage/injections.d.ts +40 -0
  152. package/dist/core/storage/injections.d.ts.map +1 -1
  153. package/dist/core/storage/injections.js +69 -0
  154. package/dist/core/storage/injections.js.map +1 -1
  155. package/dist/core/storage/knowledge.d.ts +226 -0
  156. package/dist/core/storage/knowledge.d.ts.map +1 -1
  157. package/dist/core/storage/knowledge.js +391 -4
  158. package/dist/core/storage/knowledge.js.map +1 -1
  159. package/dist/core/storage/pipeline-rollup.d.ts +1 -7
  160. package/dist/core/storage/pipeline-rollup.d.ts.map +1 -1
  161. package/dist/core/storage/pipeline-rollup.js +18 -57
  162. package/dist/core/storage/pipeline-rollup.js.map +1 -1
  163. package/dist/core/storage/routing.d.ts +34 -0
  164. package/dist/core/storage/routing.d.ts.map +1 -1
  165. package/dist/core/storage/routing.js +92 -2
  166. package/dist/core/storage/routing.js.map +1 -1
  167. package/dist/core/storage/rows.d.ts +5 -25
  168. package/dist/core/storage/rows.d.ts.map +1 -1
  169. package/dist/core/storage/schema.sql +92 -27
  170. package/dist/core/storage/sessions.d.ts.map +1 -1
  171. package/dist/core/storage/sessions.js +2 -1
  172. package/dist/core/storage/sessions.js.map +1 -1
  173. package/dist/core/storage/skills.d.ts +159 -0
  174. package/dist/core/storage/skills.d.ts.map +1 -1
  175. package/dist/core/storage/skills.js +350 -4
  176. package/dist/core/storage/skills.js.map +1 -1
  177. package/dist/core/storage/sqlite.d.ts +81 -25
  178. package/dist/core/storage/sqlite.d.ts.map +1 -1
  179. package/dist/core/storage/sqlite.js +143 -45
  180. package/dist/core/storage/sqlite.js.map +1 -1
  181. package/dist/core/storage/tasks.d.ts +270 -0
  182. package/dist/core/storage/tasks.d.ts.map +1 -1
  183. package/dist/core/storage/tasks.js +495 -16
  184. package/dist/core/storage/tasks.js.map +1 -1
  185. package/dist/core/storage/tool-intercepts.d.ts +1 -1
  186. package/dist/core/storage/tool-intercepts.js +1 -1
  187. package/dist/core/types.d.ts +26 -3
  188. package/dist/core/types.d.ts.map +1 -1
  189. package/dist/core/types.js +1 -3
  190. package/dist/core/types.js.map +1 -1
  191. package/dist/core/utils/binary-paths.d.ts +32 -0
  192. package/dist/core/utils/binary-paths.d.ts.map +1 -1
  193. package/dist/core/utils/binary-paths.js +52 -0
  194. package/dist/core/utils/binary-paths.js.map +1 -1
  195. package/dist/core/utils/claude-cli-resolver.d.ts.map +1 -0
  196. package/dist/{skills/distill → core/utils}/claude-cli-resolver.js +1 -1
  197. package/dist/core/utils/claude-cli-resolver.js.map +1 -0
  198. package/dist/core/utils/claude-cli-spawn.d.ts +1 -1
  199. package/dist/core/utils/claude-cli-spawn.js +2 -2
  200. package/dist/core/utils/claude-cli-spawn.js.map +1 -1
  201. package/dist/core/utils/noise-prompt.d.ts +1 -1
  202. package/dist/core/utils/noise-prompt.js +1 -1
  203. package/dist/core/utils/time.d.ts +26 -0
  204. package/dist/core/utils/time.d.ts.map +1 -1
  205. package/dist/core/utils/time.js +33 -0
  206. package/dist/core/utils/time.js.map +1 -1
  207. package/dist/daemon/config-store.d.ts.map +1 -1
  208. package/dist/daemon/config-store.js +14 -5
  209. package/dist/daemon/config-store.js.map +1 -1
  210. package/dist/daemon/event-parser.d.ts.map +1 -1
  211. package/dist/daemon/event-parser.js +5 -0
  212. package/dist/daemon/event-parser.js.map +1 -1
  213. package/dist/daemon/handlers/post-tool-use.d.ts +24 -16
  214. package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
  215. package/dist/daemon/handlers/post-tool-use.js +76 -116
  216. package/dist/daemon/handlers/post-tool-use.js.map +1 -1
  217. package/dist/daemon/handlers/pre-tool-use.d.ts +35 -10
  218. package/dist/daemon/handlers/pre-tool-use.d.ts.map +1 -1
  219. package/dist/daemon/handlers/pre-tool-use.js +71 -38
  220. package/dist/daemon/handlers/pre-tool-use.js.map +1 -1
  221. package/dist/daemon/handlers/stop.d.ts +20 -0
  222. package/dist/daemon/handlers/stop.d.ts.map +1 -1
  223. package/dist/daemon/handlers/stop.js +96 -8
  224. package/dist/daemon/handlers/stop.js.map +1 -1
  225. package/dist/daemon/handlers/user-prompt.d.ts +16 -1
  226. package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
  227. package/dist/daemon/handlers/user-prompt.js +97 -56
  228. package/dist/daemon/handlers/user-prompt.js.map +1 -1
  229. package/dist/daemon/handlers/violation-content-backfill.d.ts +76 -0
  230. package/dist/daemon/handlers/violation-content-backfill.d.ts.map +1 -0
  231. package/dist/daemon/handlers/violation-content-backfill.js +167 -0
  232. package/dist/daemon/handlers/violation-content-backfill.js.map +1 -0
  233. package/dist/daemon/index.d.ts +19 -0
  234. package/dist/daemon/index.d.ts.map +1 -1
  235. package/dist/daemon/index.js +125 -200
  236. package/dist/daemon/index.js.map +1 -1
  237. package/dist/daemon/rules/defaults.d.ts.map +1 -1
  238. package/dist/daemon/rules/defaults.js +151 -64
  239. package/dist/daemon/rules/defaults.js.map +1 -1
  240. package/dist/daemon/rules/types.d.ts +28 -22
  241. package/dist/daemon/rules/types.d.ts.map +1 -1
  242. package/dist/daemon/rules/workflow-defaults.js +9 -9
  243. package/dist/daemon/rules/workflow-defaults.js.map +1 -1
  244. package/dist/daemon/services/codegraph-sync.d.ts +94 -0
  245. package/dist/daemon/services/codegraph-sync.d.ts.map +1 -0
  246. package/dist/daemon/services/codegraph-sync.js +159 -0
  247. package/dist/daemon/services/codegraph-sync.js.map +1 -0
  248. package/dist/daemon/services/decision-hint.d.ts +47 -10
  249. package/dist/daemon/services/decision-hint.d.ts.map +1 -1
  250. package/dist/daemon/services/decision-hint.js +99 -24
  251. package/dist/daemon/services/decision-hint.js.map +1 -1
  252. package/dist/daemon/services/event-ttl-sweep.d.ts.map +1 -1
  253. package/dist/daemon/services/event-ttl-sweep.js +3 -2
  254. package/dist/daemon/services/event-ttl-sweep.js.map +1 -1
  255. package/dist/daemon/services/feedback-aggregator.d.ts +14 -26
  256. package/dist/daemon/services/feedback-aggregator.d.ts.map +1 -1
  257. package/dist/daemon/services/feedback-aggregator.js +23 -63
  258. package/dist/daemon/services/feedback-aggregator.js.map +1 -1
  259. package/dist/daemon/services/heartbeat-writer.d.ts +6 -15
  260. package/dist/daemon/services/heartbeat-writer.d.ts.map +1 -1
  261. package/dist/daemon/services/heartbeat-writer.js +7 -36
  262. package/dist/daemon/services/heartbeat-writer.js.map +1 -1
  263. package/dist/daemon/services/kb-injector.d.ts +1 -1
  264. package/dist/daemon/services/kb-injector.d.ts.map +1 -1
  265. package/dist/daemon/services/kb-injector.js +10 -2
  266. package/dist/daemon/services/kb-injector.js.map +1 -1
  267. package/dist/daemon/services/kb-rebuild-scheduler.d.ts +95 -0
  268. package/dist/daemon/services/kb-rebuild-scheduler.d.ts.map +1 -0
  269. package/dist/daemon/services/kb-rebuild-scheduler.js +149 -0
  270. package/dist/daemon/services/kb-rebuild-scheduler.js.map +1 -0
  271. package/dist/daemon/services/loop-hint.d.ts +139 -0
  272. package/dist/daemon/services/loop-hint.d.ts.map +1 -0
  273. package/dist/daemon/services/loop-hint.js +272 -0
  274. package/dist/daemon/services/loop-hint.js.map +1 -0
  275. package/dist/daemon/services/outcome-classification-service.js +1 -1
  276. package/dist/daemon/services/outcome-classification-service.js.map +1 -1
  277. package/dist/daemon/services/task-segmenter.d.ts +11 -0
  278. package/dist/daemon/services/task-segmenter.d.ts.map +1 -1
  279. package/dist/daemon/services/task-segmenter.js +48 -2
  280. package/dist/daemon/services/task-segmenter.js.map +1 -1
  281. package/dist/daemon/startup/maintenance-schedulers.d.ts +68 -0
  282. package/dist/daemon/startup/maintenance-schedulers.d.ts.map +1 -0
  283. package/dist/daemon/startup/maintenance-schedulers.js +294 -0
  284. package/dist/daemon/startup/maintenance-schedulers.js.map +1 -0
  285. package/dist/daemon/templates/agents/agent-retro-distiller.md +106 -0
  286. package/dist/daemon/templates/agents/claudemd-writer.md +1 -0
  287. package/dist/daemon/templates/agents/coder.md +165 -8
  288. package/dist/daemon/templates/agents/decision-maker.md +107 -21
  289. package/dist/daemon/templates/agents/doc-reviewer.md +4 -1
  290. package/dist/daemon/templates/agents/harness-debug-full.md +85 -3
  291. package/dist/daemon/templates/agents/knowledge-builder.md +1 -0
  292. package/dist/daemon/templates/agents/patch-applier.md +1 -0
  293. package/dist/daemon/templates/agents/planner.md +55 -3
  294. package/dist/daemon/templates/agents/safety-net-implementer.md +278 -0
  295. package/dist/daemon/templates/agents/skill-distiller.md +1 -0
  296. package/dist/daemon/templates/agents/task-boundary-classifier.md +1 -0
  297. package/dist/daemon/templates/agents/verify-agent.md +128 -5
  298. package/dist/hooks/stop.sh +7 -1
  299. package/dist/knowledge/builder.js +36 -7
  300. package/dist/knowledge/builder.js.map +1 -1
  301. package/dist/knowledge/constants.d.ts +10 -5
  302. package/dist/knowledge/constants.d.ts.map +1 -1
  303. package/dist/knowledge/constants.js +10 -5
  304. package/dist/knowledge/constants.js.map +1 -1
  305. package/dist/knowledge/graph/edge-extractor.d.ts +45 -0
  306. package/dist/knowledge/graph/edge-extractor.d.ts.map +1 -0
  307. package/dist/knowledge/graph/edge-extractor.js +242 -0
  308. package/dist/knowledge/graph/edge-extractor.js.map +1 -0
  309. package/dist/knowledge/graph/impact.d.ts +73 -0
  310. package/dist/knowledge/graph/impact.d.ts.map +1 -0
  311. package/dist/knowledge/graph/impact.js +94 -0
  312. package/dist/knowledge/graph/impact.js.map +1 -0
  313. package/dist/knowledge/graph/types.d.ts +22 -0
  314. package/dist/knowledge/graph/types.d.ts.map +1 -0
  315. package/dist/knowledge/graph/types.js +13 -0
  316. package/dist/knowledge/graph/types.js.map +1 -0
  317. package/dist/knowledge/prompt.d.ts +9 -0
  318. package/dist/knowledge/prompt.d.ts.map +1 -1
  319. package/dist/knowledge/prompt.js +17 -5
  320. package/dist/knowledge/prompt.js.map +1 -1
  321. package/dist/knowledge/query.d.ts +13 -0
  322. package/dist/knowledge/query.d.ts.map +1 -1
  323. package/dist/knowledge/query.js +107 -10
  324. package/dist/knowledge/query.js.map +1 -1
  325. package/dist/knowledge/repo-map.d.ts +11 -5
  326. package/dist/knowledge/repo-map.d.ts.map +1 -1
  327. package/dist/knowledge/repo-map.js +42 -3
  328. package/dist/knowledge/repo-map.js.map +1 -1
  329. package/dist/knowledge/validator.d.ts.map +1 -1
  330. package/dist/knowledge/validator.js +69 -2
  331. package/dist/knowledge/validator.js.map +1 -1
  332. package/dist/mcp/server.d.ts +64 -8
  333. package/dist/mcp/server.d.ts.map +1 -1
  334. package/dist/mcp/server.js +233 -18
  335. package/dist/mcp/server.js.map +1 -1
  336. package/dist/skills/distill/distiller.js +1 -1
  337. package/dist/skills/distill/distiller.js.map +1 -1
  338. package/dist/skills/distilled/distilled-api-design.md +4 -0
  339. package/dist/skills/distilled/distilled-brainstorming.md +79 -0
  340. package/dist/skills/distilled/distilled-brand-guidelines.md +86 -0
  341. package/dist/skills/distilled/distilled-canvas-design.md +128 -0
  342. package/dist/skills/distilled/distilled-claude-api.md +185 -0
  343. package/dist/skills/distilled/distilled-creator.md +5 -2
  344. package/dist/skills/distilled/distilled-dispatching-parallel-agents.md +136 -0
  345. package/dist/skills/distilled/distilled-doc-coauthoring.md +144 -0
  346. package/dist/skills/distilled/distilled-docx.md +231 -0
  347. package/dist/skills/distilled/distilled-executing-plans.md +85 -50
  348. package/dist/skills/distilled/distilled-finishing-a-development-branch.md +213 -0
  349. package/dist/skills/distilled/distilled-frontend-design.md +118 -0
  350. package/dist/skills/distilled/distilled-harness-engineering.md +1 -1
  351. package/dist/skills/distilled/distilled-receiving-code-review.md +185 -0
  352. package/dist/skills/distilled/distilled-subagent-driven-development.md +124 -0
  353. package/dist/skills/distilled/distilled-systematic-debugging.md +108 -260
  354. package/dist/skills/distilled/distilled-test-driven-development.md +432 -0
  355. package/dist/skills/distilled/distilled-using-superpowers.md +134 -0
  356. package/dist/skills/distilled/distilled-verification-before-completion.md +88 -78
  357. package/dist/skills/distilled/distilled-writing-skills.md +175 -0
  358. package/dist/skills/registry.d.ts +10 -50
  359. package/dist/skills/registry.d.ts.map +1 -1
  360. package/dist/skills/registry.js +7 -118
  361. package/dist/skills/registry.js.map +1 -1
  362. package/dist/skills/tools/pipeline-suggest.js +2 -2
  363. package/dist/skills/tools/pipeline-suggest.js.map +1 -1
  364. package/dist/skills/tools/skill-invoke.d.ts +2 -1
  365. package/dist/skills/tools/skill-invoke.d.ts.map +1 -1
  366. package/dist/skills/tools/skill-invoke.js +3 -1
  367. package/dist/skills/tools/skill-invoke.js.map +1 -1
  368. package/dist/web/analytics/anti-pattern-detector.d.ts.map +1 -1
  369. package/dist/web/analytics/anti-pattern-detector.js +6 -1
  370. package/dist/web/analytics/anti-pattern-detector.js.map +1 -1
  371. package/dist/web/analytics/drift-detector.d.ts +6 -0
  372. package/dist/web/analytics/drift-detector.d.ts.map +1 -1
  373. package/dist/web/analytics/drift-detector.js +15 -8
  374. package/dist/web/analytics/drift-detector.js.map +1 -1
  375. package/dist/web/analytics/weekly-report.d.ts +13 -0
  376. package/dist/web/analytics/weekly-report.d.ts.map +1 -1
  377. package/dist/web/analytics/weekly-report.js +17 -3
  378. package/dist/web/analytics/weekly-report.js.map +1 -1
  379. package/dist/web/routes/_helpers.d.ts +31 -0
  380. package/dist/web/routes/_helpers.d.ts.map +1 -1
  381. package/dist/web/routes/_helpers.js +33 -0
  382. package/dist/web/routes/_helpers.js.map +1 -1
  383. package/dist/web/routes/agent-distill.d.ts +49 -0
  384. package/dist/web/routes/agent-distill.d.ts.map +1 -0
  385. package/dist/web/routes/agent-distill.js +526 -0
  386. package/dist/web/routes/agent-distill.js.map +1 -0
  387. package/dist/web/routes/config.d.ts +56 -0
  388. package/dist/web/routes/config.d.ts.map +1 -0
  389. package/dist/web/routes/config.js +243 -0
  390. package/dist/web/routes/config.js.map +1 -0
  391. package/dist/web/routes/decisions.js +1 -1
  392. package/dist/web/routes/decisions.js.map +1 -1
  393. package/dist/web/routes/error-handler.d.ts +0 -4
  394. package/dist/web/routes/error-handler.d.ts.map +1 -1
  395. package/dist/web/routes/error-handler.js +0 -8
  396. package/dist/web/routes/error-handler.js.map +1 -1
  397. package/dist/web/routes/events.d.ts.map +1 -1
  398. package/dist/web/routes/events.js +2 -1
  399. package/dist/web/routes/events.js.map +1 -1
  400. package/dist/web/routes/insights.d.ts.map +1 -1
  401. package/dist/web/routes/insights.js +0 -0
  402. package/dist/web/routes/insights.js.map +1 -1
  403. package/dist/web/routes/knowledge.d.ts +43 -2
  404. package/dist/web/routes/knowledge.d.ts.map +1 -1
  405. package/dist/web/routes/knowledge.js +117 -6
  406. package/dist/web/routes/knowledge.js.map +1 -1
  407. package/dist/web/routes/pipeline.d.ts +0 -9
  408. package/dist/web/routes/pipeline.d.ts.map +1 -1
  409. package/dist/web/routes/pipeline.js +0 -4
  410. package/dist/web/routes/pipeline.js.map +1 -1
  411. package/dist/web/routes/rules.d.ts.map +1 -1
  412. package/dist/web/routes/rules.js +20 -6
  413. package/dist/web/routes/rules.js.map +1 -1
  414. package/dist/web/routes/sessions.d.ts.map +1 -1
  415. package/dist/web/routes/sessions.js +8 -7
  416. package/dist/web/routes/sessions.js.map +1 -1
  417. package/dist/web/routes/skill-stats.d.ts.map +1 -1
  418. package/dist/web/routes/skill-stats.js +153 -16
  419. package/dist/web/routes/skill-stats.js.map +1 -1
  420. package/dist/web/routes/skills-distill.js +1 -1
  421. package/dist/web/routes/skills-distill.js.map +1 -1
  422. package/dist/web/routes/stats.d.ts.map +1 -1
  423. package/dist/web/routes/stats.js +2 -1
  424. package/dist/web/routes/stats.js.map +1 -1
  425. package/dist/web/routes/task-timeline.d.ts +95 -19
  426. package/dist/web/routes/task-timeline.d.ts.map +1 -1
  427. package/dist/web/routes/task-timeline.js +344 -88
  428. package/dist/web/routes/task-timeline.js.map +1 -1
  429. package/dist/web/routes/tasks.d.ts.map +1 -1
  430. package/dist/web/routes/tasks.js +52 -30
  431. package/dist/web/routes/tasks.js.map +1 -1
  432. package/dist/web/routes/violations.d.ts +1 -1
  433. package/dist/web/routes/violations.d.ts.map +1 -1
  434. package/dist/web/routes/violations.js +3 -2
  435. package/dist/web/routes/violations.js.map +1 -1
  436. package/dist/web/server.d.ts.map +1 -1
  437. package/dist/web/server.js +20 -0
  438. package/dist/web/server.js.map +1 -1
  439. package/dist/web/services/agent-distill-manager.d.ts +122 -0
  440. package/dist/web/services/agent-distill-manager.d.ts.map +1 -0
  441. package/dist/web/services/agent-distill-manager.js +397 -0
  442. package/dist/web/services/agent-distill-manager.js.map +1 -0
  443. package/dist/web/services/distill-manager.d.ts +47 -0
  444. package/dist/web/services/distill-manager.d.ts.map +1 -1
  445. package/dist/web/services/distill-manager.js +103 -0
  446. package/dist/web/services/distill-manager.js.map +1 -1
  447. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js +2 -0
  448. package/dist/web/static/assets/AgentDetailPage-DlUeA1sX.js.map +1 -0
  449. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js +3 -0
  450. package/dist/web/static/assets/AgentDistillRunPage-Cybo4bii.js.map +1 -0
  451. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js +2 -0
  452. package/dist/web/static/assets/AgentsPage-Qd9FExLG.js.map +1 -0
  453. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js +2 -0
  454. package/dist/web/static/assets/DaemonHealthPage-DTSVqtrI.js.map +1 -0
  455. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js +2 -0
  456. package/dist/web/static/assets/DecisionDetailPage-b4BA8dhc.js.map +1 -0
  457. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js +2 -0
  458. package/dist/web/static/assets/DecisionsPage-a3NRo_T7.js.map +1 -0
  459. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js +2 -0
  460. package/dist/web/static/assets/DiagnosticsPage-DIVdiIQG.js.map +1 -0
  461. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js +4 -0
  462. package/dist/web/static/assets/DistillDetailPage-U6a3l2iP.js.map +1 -0
  463. package/dist/web/static/assets/DistillPage-O7BHtRN8.js +2 -0
  464. package/dist/web/static/assets/DistillPage-O7BHtRN8.js.map +1 -0
  465. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js +2 -0
  466. package/dist/web/static/assets/DistillRunPage-D1JuRWWr.js.map +1 -0
  467. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js +2 -0
  468. package/dist/web/static/assets/GlobalScopeHint-Q3wTJx3F.js.map +1 -0
  469. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js +2 -0
  470. package/dist/web/static/assets/IssueDetailPage-BDfrtk2C.js.map +1 -0
  471. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js +2 -0
  472. package/dist/web/static/assets/IssuesPage-SKmhlCrw.js.map +1 -0
  473. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js +2 -0
  474. package/dist/web/static/assets/KbDetailPage-Yna86Na8.js.map +1 -0
  475. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js +2 -0
  476. package/dist/web/static/assets/KbHitsPage-Cljl7H9p.js.map +1 -0
  477. package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js → MarkdownRenderer-DlDQNihj.js} +2 -2
  478. package/dist/web/static/assets/{MarkdownRenderer-DZmTl-8J.js.map → MarkdownRenderer-DlDQNihj.js.map} +1 -1
  479. package/dist/web/static/assets/NotFound-LMzbP51V.js +2 -0
  480. package/dist/web/static/assets/{NotFound-BQPh0vaF.js.map → NotFound-LMzbP51V.js.map} +1 -1
  481. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js +2 -0
  482. package/dist/web/static/assets/SettingsPage-DzoK4PKg.js.map +1 -0
  483. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js +2 -0
  484. package/dist/web/static/assets/SkillDetailPage-BuBJJ_NX.js.map +1 -0
  485. package/dist/web/static/assets/SkillsPage-aojkJpBc.js +2 -0
  486. package/dist/web/static/assets/SkillsPage-aojkJpBc.js.map +1 -0
  487. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js +4 -0
  488. package/dist/web/static/assets/TaskDetailPage-1ckxnGhw.js.map +1 -0
  489. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js +6 -0
  490. package/dist/web/static/assets/TasksHubPage-C2PLh3eg.js.map +1 -0
  491. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js +2 -0
  492. package/dist/web/static/assets/WorkplacePage-DHrp5VxS.js.map +1 -0
  493. package/dist/web/static/assets/arco-DV6xCLhr.js +14 -0
  494. package/dist/web/static/assets/arco-DV6xCLhr.js.map +1 -0
  495. package/dist/web/static/assets/charts-BSV4cyC4.js +37 -0
  496. package/dist/web/static/assets/charts-BSV4cyC4.js.map +1 -0
  497. package/dist/web/static/assets/{index-7bl3kbcx.css → index-B_v_MKlb.css} +1 -1
  498. package/dist/web/static/assets/index-DileOOE4.js +4 -0
  499. package/dist/web/static/assets/index-DileOOE4.js.map +1 -0
  500. package/dist/web/static/assets/markdown-CA7ePUts.js +30 -0
  501. package/dist/web/static/assets/markdown-CA7ePUts.js.map +1 -0
  502. package/dist/web/static/assets/{outcome-DUn1NjlC.js → outcome-BKGy9azt.js} +2 -2
  503. package/dist/web/static/assets/{outcome-DUn1NjlC.js.map → outcome-BKGy9azt.js.map} +1 -1
  504. package/dist/web/static/assets/{query-S6X1S7K9.js → query-CgCOpYWf.js} +2 -2
  505. package/dist/web/static/assets/{query-S6X1S7K9.js.map → query-CgCOpYWf.js.map} +1 -1
  506. package/dist/web/static/assets/{react-router-JVUrkhdd.js → react-router-Cxmg8RuL.js} +3 -3
  507. package/dist/web/static/assets/{react-router-JVUrkhdd.js.map → react-router-Cxmg8RuL.js.map} +1 -1
  508. package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js → syntax-highlighter-BDYycNja.js} +3 -3
  509. package/dist/web/static/assets/{syntax-highlighter-BkZfCDsz.js.map → syntax-highlighter-BDYycNja.js.map} +1 -1
  510. package/dist/web/static/assets/task-title-BhOcemuR.js +2 -0
  511. package/dist/web/static/assets/task-title-BhOcemuR.js.map +1 -0
  512. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js +2 -0
  513. package/dist/web/static/assets/useAgentStats-B-uTgqBd.js.map +1 -0
  514. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js +2 -0
  515. package/dist/web/static/assets/useDecisions-D-G2Ft5T.js.map +1 -0
  516. package/dist/web/static/assets/useDistill-21dZkXlT.js +3 -0
  517. package/dist/web/static/assets/useDistill-21dZkXlT.js.map +1 -0
  518. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js +2 -0
  519. package/dist/web/static/assets/useEffectiveProject-DQiyX54y.js.map +1 -0
  520. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js +2 -0
  521. package/dist/web/static/assets/useIssuesFeed-CFiyQkAL.js.map +1 -0
  522. package/dist/web/static/assets/useKbHits-xKXWgqh9.js +2 -0
  523. package/dist/web/static/assets/useKbHits-xKXWgqh9.js.map +1 -0
  524. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js +2 -0
  525. package/dist/web/static/assets/useSkillStats-B5hbIwdf.js.map +1 -0
  526. package/dist/web/static/assets/vendor-DS-q4Eyc.js +36 -0
  527. package/dist/web/static/assets/vendor-DS-q4Eyc.js.map +1 -0
  528. package/dist/web/static/index.html +6 -6
  529. package/package.json +5 -3
  530. package/dist/core/storage/workflow-recommendations.d.ts +0 -124
  531. package/dist/core/storage/workflow-recommendations.d.ts.map +0 -1
  532. package/dist/core/storage/workflow-recommendations.js +0 -274
  533. package/dist/core/storage/workflow-recommendations.js.map +0 -1
  534. package/dist/daemon/services/experience-extractor.d.ts.map +0 -1
  535. package/dist/daemon/services/experience-extractor.js.map +0 -1
  536. package/dist/daemon/services/violation-reporter.d.ts.map +0 -1
  537. package/dist/daemon/services/violation-reporter.js.map +0 -1
  538. package/dist/daemon/templates/agents/harness-hotfix.md +0 -99
  539. package/dist/daemon/templates/agents/hybrid-feature-with-safety.md +0 -104
  540. package/dist/daemon/templates/agents/refactor-specialist.md +0 -98
  541. package/dist/skills/distill/claude-cli-resolver.d.ts.map +0 -1
  542. package/dist/skills/distill/claude-cli-resolver.js.map +0 -1
  543. package/dist/skills/distilled/distilled-defi-amm-security.md +0 -293
  544. package/dist/skills/keyword-score.d.ts +0 -29
  545. package/dist/skills/keyword-score.d.ts.map +0 -1
  546. package/dist/skills/keyword-score.js +0 -54
  547. package/dist/skills/keyword-score.js.map +0 -1
  548. package/dist/web/static/assets/AgentContentPage-DkeRNxok.js +0 -2
  549. package/dist/web/static/assets/AgentContentPage-DkeRNxok.js.map +0 -1
  550. package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js +0 -2
  551. package/dist/web/static/assets/AgentDelegationTable-ByBa0x1l.js.map +0 -1
  552. package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js +0 -3
  553. package/dist/web/static/assets/ContextInsightsPage-oUk7_I8u.js.map +0 -1
  554. package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js +0 -2
  555. package/dist/web/static/assets/DaemonHealthPage-DG2fyOP7.js.map +0 -1
  556. package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js +0 -2
  557. package/dist/web/static/assets/DecisionsPage-CMAPEnKb.js.map +0 -1
  558. package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js +0 -2
  559. package/dist/web/static/assets/DiagnosticsPage-DQd-Zm4r.js.map +0 -1
  560. package/dist/web/static/assets/DriftTab-DqpepOhI.js +0 -2
  561. package/dist/web/static/assets/DriftTab-DqpepOhI.js.map +0 -1
  562. package/dist/web/static/assets/HealthHomePage-CN6zNIie.js +0 -3
  563. package/dist/web/static/assets/HealthHomePage-CN6zNIie.js.map +0 -1
  564. package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js +0 -2
  565. package/dist/web/static/assets/KbHitRateTable-ByEIWujF.js.map +0 -1
  566. package/dist/web/static/assets/NotFound-BQPh0vaF.js +0 -2
  567. package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js +0 -2
  568. package/dist/web/static/assets/ProjectSwitcher-D3lZMFd3.js.map +0 -1
  569. package/dist/web/static/assets/SettingsPage-oLJBNzQj.js +0 -2
  570. package/dist/web/static/assets/SettingsPage-oLJBNzQj.js.map +0 -1
  571. package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js +0 -2
  572. package/dist/web/static/assets/SkillContentPage-DK5rgfgw.js.map +0 -1
  573. package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js +0 -2
  574. package/dist/web/static/assets/SkillStatsTable-DYMzjEUV.js.map +0 -1
  575. package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js +0 -2
  576. package/dist/web/static/assets/SkillsDistillTab-C7qaG8q3.js.map +0 -1
  577. package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js +0 -6
  578. package/dist/web/static/assets/TasksHubPage-03wsRRsJ.js.map +0 -1
  579. package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js +0 -3
  580. package/dist/web/static/assets/ViolationsPage-DSiLr-9O.js.map +0 -1
  581. package/dist/web/static/assets/arco-Bhi3a6Qp.js +0 -14
  582. package/dist/web/static/assets/arco-Bhi3a6Qp.js.map +0 -1
  583. package/dist/web/static/assets/charts-BuHQWDbQ.js +0 -37
  584. package/dist/web/static/assets/charts-BuHQWDbQ.js.map +0 -1
  585. package/dist/web/static/assets/index-BIYnq1Dx.js +0 -4
  586. package/dist/web/static/assets/index-BIYnq1Dx.js.map +0 -1
  587. package/dist/web/static/assets/useTabsParam-k8qte_0C.js +0 -2
  588. package/dist/web/static/assets/useTabsParam-k8qte_0C.js.map +0 -1
  589. package/dist/web/static/assets/vendor-DWgdB1eY.js +0 -65
  590. package/dist/web/static/assets/vendor-DWgdB1eY.js.map +0 -1
  591. /package/dist/{skills/distill → core/utils}/claude-cli-resolver.d.ts +0 -0
@@ -0,0 +1,278 @@
1
+ ---
2
+ name: safety-net-implementer
3
+ description: Safety-net implementation agent for low-coverage (<50%) modules — replaces harness-hotfix / refactor-specialist / hybrid-feature-with-safety. Three modes, one discipline. mode=hotfix for known-cause bug fixes ("修复 X bug", "hotfix", "urgent fix", "fix the broken Y"); mode=refactor for behavior-preserving restructure ("重构", "refactor", "整理", "拆分", "cleanup"); mode=hybrid-feature for new features touching legacy code ("新功能 + 改老代码", "add X to legacy module Y", "feature touching hooks/claudemd"). Caller declares the mode in the prompt or the agent self-selects. For unknown/intermittent bugs use harness-debug-full; for well-tested modules (>=50% coverage) use coder.
4
+ tools: Read, Edit, Write, Bash, Glob, Grep
5
+ model: inherit
6
+ color: orange
7
+ version: 1
8
+ ---
9
+
10
+ # IMPORTANT: subagent rules
11
+
12
+ - You are a subagent — you **cannot** spawn other agents (built-in CC restriction)
13
+ - You MUST NOT modify test fixtures to satisfy buggy impl
14
+ - You MUST NOT exceed your declared scope; stop and report if scope creep is needed
15
+ - You MUST run **scoped** tests (only the touched module/path, e.g.
16
+ `npx vitest run tests/unit/core/loop`) before declaring done — do NOT run
17
+ `npm test` / a bare full `npx vitest run`. The full-suite regression sweep is
18
+ owned by `verify-agent` at the commit gate, not by you.
19
+ - You MUST write a changelog to `docs/implementation/YYYY-MM-DD/HHMM-[task]-changelog.md`
20
+
21
+ # Role
22
+
23
+ Safety-net-first implementation agent for low-coverage code. One discipline,
24
+ three modes: you NEVER touch a low-coverage module before pinning its behavior
25
+ with tests. The mode only changes WHAT the Step 1 safety-net looks like; every
26
+ other step is shared.
27
+
28
+ # Mode declaration (read this first)
29
+
30
+ The caller SHOULD declare the mode in the prompt (`mode=hotfix` /
31
+ `mode=refactor` / `mode=hybrid-feature`). If no mode is declared, self-select
32
+ using this table, state your chosen mode in your first message, and proceed:
33
+
34
+ | Mode | Task shape | Step 1 safety-net form |
35
+ |------|-----------|------------------------|
36
+ | `hotfix` | Root cause of a bug is KNOWN; fix scope bounded (1-3 files) | A test that reproduces the bug — MUST FAIL before the fix |
37
+ | `refactor` | Restructure only — no new behavior, no bug fixes | Characterization tests of current behavior — MUST PASS before the refactor |
38
+ | `hybrid-feature` | NEW behavior that must modify legacy low-coverage files | Characterization tests for the legacy touchpoints you will EDIT (not the ones you only read) — MUST PASS before any change |
39
+
40
+ Wrong-agent checks (stop and report if any applies):
41
+ - Root cause unknown / intermittent / "时好时坏" → `harness-debug-full`
42
+ - Target module already has >=50% coverage → `coder`
43
+ - Spec-driven multi-file work in well-tested modules → `coder`
44
+
45
+ # Workflow
46
+
47
+ ## Step 1: safety-net (form depends on mode)
48
+
49
+ **mode=hotfix** — write the failing test FIRST:
50
+ - Identify where the bug surfaces (function, handler, route).
51
+ - Write a unit or integration test that reproduces it.
52
+ - Run the **scoped** test (`npx vitest run <your-new-test-file>`, NOT `npm test`)
53
+ — the test MUST FAIL, and fail at the right place (the failure message
54
+ describes the actual bug, not a setup error).
55
+ - If you cannot make it fail reliably, do NOT proceed — escalate to `harness-debug-full`.
56
+
57
+ **mode=refactor** — characterize current behavior:
58
+ - Read the target module top-to-bottom; understand inputs/outputs.
59
+ - Pure functions → golden-master tests; I/O code → integration tests;
60
+ side-effecty code → spy/mock the boundary, assert call shape.
61
+ - Cover the "load-bearing" branches: at least one test per significant code path.
62
+ - Run the **scoped** tests (`npx vitest run <touched-path>`, NOT `npm test`) —
63
+ all new tests must PASS against the unrefactored code.
64
+
65
+ **mode=hybrid-feature** — protect only the legacy touchpoints:
66
+ - Identify exactly which legacy files/functions your feature will MODIFY.
67
+ - For each one, write characterization tests (as in refactor mode). You do NOT
68
+ need to test legacy code you only READ.
69
+ - Run the **scoped** tests (`npx vitest run <touched-path>`, NOT `npm test`) —
70
+ safety-net tests must pass against unmodified legacy code.
71
+
72
+ In all modes: safety-net tests are immutable once written. If they need editing
73
+ later, you changed behavior — revert and rethink.
74
+
75
+ ## Step 2: design (brief, mode-appropriate)
76
+
77
+ - `hotfix`: no design doc — plan the minimal change that makes the test pass.
78
+ - `refactor`: short design note (inline in changelog): target file layout, what
79
+ extracts/merges/renames; identify the trickiest move and start there.
80
+ - `hybrid-feature`: list integration points between new and legacy code; prefer
81
+ ADDING new functions over MODIFYING existing ones; justify every legacy
82
+ modification in the note.
83
+
84
+ ## Step 2.7: discover the methodology skill dynamically (targeted)
85
+
86
+ Before you implement (Step 3), find the ONE most-relevant distilled methodology
87
+ skill for what you are ABOUT to do — by DYNAMIC DISCOVERY, not a hardcoded
88
+ mode→skill table (decision c20c2d1f). Steps:
89
+
90
+ 1. **Describe the sub-task you are actually doing** in one phrase (e.g.
91
+ `"reproduce a known null-deref in the event handler"` for hotfix,
92
+ `"characterize then extract the maintenance scheduler"` for refactor,
93
+ `"add a new CLI subcommand to the skills module"` for hybrid-feature), then
94
+ run via **Bash**:
95
+ `cf skill search "<task-desc>" --json`
96
+ 2. **Read the ranked candidates + scores**, then YOU (the LLM) judge which single
97
+ one — at most 1, the most relevant — actually fits. If the output says
98
+ `no_strong_match: true` (or none truly fits), **skip the pull** and note
99
+ `skill-pull-skipped: no-match` in the changelog. Do NOT force a weak candidate.
100
+ 3. **Pull the one you chose:**
101
+ `cf skill invoke <id> --reason "safetynet/<phase>" --agent safety-net-implementer`
102
+ (pass `--agent safety-net-implementer` so `agent_id` is written — decision
103
+ 234f1ad4 Q6). Read the methodology it prints and use it as your reference.
104
+
105
+ Rules:
106
+ - **Pick at most one** via `cf skill search`; use it as a reference, not a script.
107
+ Do NOT pull the whole catalog — pulling everything every time is the noise trap
108
+ (d08da374) we are avoiding. There is NO default "always pull X for this mode".
109
+ - **When to SKIP:** if `cf skill search` reports `no_strong_match`, or the change
110
+ is trivial / a one-line fix or pure config tweak, skip the pull and note
111
+ `skill-pull-skipped: no-match` (or `trivial`) in the changelog. Do not pull just
112
+ to pull.
113
+ - This is the safety-net analogue of `coder` Step 2.7 / `verify-agent` Step 0.
114
+
115
+ > Why Bash, not MCP: subagents in this harness have **zero MCP access** — the MCP
116
+ > `skill_invoke` / `skill_search` tools are uncallable from you. `cf skill search`
117
+ > / `cf skill invoke` (Bash) are the working channel; invoke records to
118
+ > `skill_invocations` (`invocation_type='cli'`).
119
+
120
+ **Telemetry convention (required).** The `--reason` MUST begin with the prefix
121
+ **`safetynet/`** (e.g. `--reason "safetynet/executing-plans"`). The
122
+ `<workflow>/<phase>` form is parsed by `parseWorkflowMeta` into `workflow`/`phase`
123
+ columns — keep both segments lowercase, letters/digits/hyphens only.
124
+
125
+ ## Step 2.5: Assess impact before touching a symbol — pick the right tool
126
+
127
+ Fixes, renames, and legacy modifications all ripple to callers you haven't
128
+ read. Assess who is affected before you Edit/Write, but **pick the tool that
129
+ fits the shape of the question**:
130
+
131
+ - **Cross-layer / transitive impact / rename blast-radius** (changing a storage
132
+ facade method → which web routes / handlers break, or "this change ripples
133
+ several hops out to who") → **MUST use** `code_impact <Class.method>`
134
+ (transitive caller closure; pass the qualified name). This is codegraph's moat:
135
+ grep cannot follow call edges across layers.
136
+ - **Find a direct call-site / a definition / who implements an interface** →
137
+ use **grep** (`grep "X("` / `grep "implements Y"`). Faster and more precise for
138
+ "find this name in this layer"; do NOT use codegraph here (slower or silently
139
+ empty for these).
140
+ - **Not sure which?** "cross-file / cross-layer / transitive" → codegraph;
141
+ "find a name right here in this layer" → grep.
142
+
143
+ `code_impact` / `code_graph_explore` / `code_search` are MCP tools in **deferred**
144
+ form: before calling, load the schema with
145
+ `ToolSearch select:mcp__claude-forge__code_impact` (and likewise for the others).
146
+ **Fallback when no MCP is available**: shell out via Bash —
147
+ `cf codegraph impact <symbol> --json` / `cf knowledge query <keyword> --json --reason "safetynet/kb-impact"`.
148
+ Prefer passing a qualified symbol name (`Class.method`); pass `--reason` on the
149
+ KB query so the pull is attributable in `kb_query_log` (source=agent-pull).
150
+
151
+ Touching a public API or storage facade with cross-layer reach without first
152
+ pulling its transitive caller set is a defect, not a shortcut.
153
+
154
+ ## Step 2.6: pull the relevant KB precedent for the module you touch (near-mandatory) (decision 2eac9d87)
155
+
156
+ Before you modify existing low-coverage code, pull the ONE most-relevant KB
157
+ precedent for the module/symbol you are about to touch — **at most 1 page, by the
158
+ trigger table**. Low-coverage legacy code is exactly where accumulated precedent
159
+ and known gotchas live, so the default is to PULL, not to skip. Read it before
160
+ editing:
161
+
162
+ | Touched area | Bash command |
163
+ |---|---|
164
+ | An existing module / symbol (the code lives in `src/<x>/`) | `cf knowledge fetch "modules/<x>" --reason "safetynet/kb-precedent"` (e.g. `modules/daemon`, `modules/cli`, `modules/skills`) |
165
+ | Architecture / layering / cross-cutting touchpoint | `cf knowledge fetch "architecture" --reason "safetynet/kb-precedent"` |
166
+ | Decision / trade-off being honored or fixed | `cf knowledge fetch "decisions" --reason "safetynet/kb-precedent"` |
167
+ | Gotcha-prone / debugging-flavored (a "时好时坏" bug, gzip event content, DB column type landmine, vitest IO storm, daemon socket) | `cf knowledge fetch "agents-experience/<area>" --reason "safetynet/kb-precedent"` (or `cf knowledge query <keyword> --reason "safetynet/kb-precedent"`) |
168
+
169
+ **Near-mandatory wording:** unless the task is trivial / a pure new-file build
170
+ with no existing module context, pull **exactly one** most-relevant KB precedent
171
+ per the table. `cf knowledge query <keyword> --reason "safetynet/kb-precedent"` is
172
+ the lighter probe when unsure which page; `cf knowledge fetch <topic>` returns the
173
+ full precedent ready to paste into your reasoning.
174
+
175
+ > Why Bash, not MCP: subagents have **zero MCP access** — `knowledge_query` is
176
+ > uncallable. The `--reason "safetynet/kb-precedent"` makes the pull attributable
177
+ > in `kb_query_log` (source=agent-pull).
178
+
179
+ Rules:
180
+ - **Pull exactly one** — the single most-relevant page. Do NOT pull a stack of
181
+ pages; "pull everything every time" is the noise trap (d08da374) we avoid.
182
+ - **When to SKIP:** only if the change is trivial / a pure new-file build with no
183
+ existing module, symbol, decision, or gotcha context. Then note
184
+ `kb-pull-skipped: trivial` in the changelog. The default is to pull.
185
+
186
+ After you USE the KB content, rate it (mirrors `cf skill feedback`):
187
+ - `cf knowledge feedback --rating helped|partial|not-actionable --note "<one line: what precedent applied / didn't>"`
188
+ - Rate HONESTLY — `partial`/`not-actionable` are valuable refinement signals, not
189
+ failures. Only run it if you actually pulled. Record the `KB pull:` line in the
190
+ changelog (see Output).
191
+
192
+ ## Step 3: implement (small steps, always green)
193
+
194
+ - `hotfix`: smallest possible change to make the failing test pass. No
195
+ refactoring "while you're in there"; no defensive checks beyond the test.
196
+ Target <20 LOC.
197
+ - `refactor`: one conceptual move per commit-worthy unit; after each move run
198
+ `npm test` — green or revert. If a safety-net test fails, you changed
199
+ behavior: revert and rethink.
200
+ - `hybrid-feature`: new files first, then legacy modifications. After each
201
+ legacy modification, run the safety-net tests — must stay green.
202
+
203
+ ## Step 4: test (cover the new shape)
204
+
205
+ > Run only the **scoped** tests for the module/path you touched (e.g.
206
+ > `npx vitest run tests/unit/core/loop`). Do NOT run `npm test` / a bare full
207
+ > `npx vitest run` — the single full-suite regression sweep is owned by
208
+ > `verify-agent` at the commit gate (decision 8a51b15d). "Full suite green"
209
+ > below means: verify-agent's later full run stays green; your job is the scoped
210
+ > slice.
211
+
212
+ - `hotfix`: the reproducing test now passes; scoped tests for the touched path green.
213
+ - `refactor`: add tests for new boundaries you created; total coverage goes UP.
214
+ - `hybrid-feature`: the new feature MUST have its own dedicated tests (happy
215
+ path, edge cases, error paths, integration with legacy); aim for >=50%
216
+ coverage on new code from day one. The safety-net only proves you didn't
217
+ break old stuff — it does not prove the feature works.
218
+
219
+ ## Step 5: verify & review
220
+
221
+ - `hotfix`: verify in REAL runtime — run the actual app / CLI / browser flow
222
+ that triggered the bug; capture evidence (command output, log lines,
223
+ screenshot if web). If real-runtime verification is impossible (external
224
+ service), document why and add an integration-level test instead.
225
+ - `refactor` / `hybrid-feature`: read your own diff end-to-end; for each chunk
226
+ ask "did I change behavior here?" — if yes, revert that chunk. Verify the
227
+ safety-net tests still pass UNCHANGED (no test edits to accommodate the work).
228
+
229
+ # Constraints (all modes)
230
+
231
+ - NEVER skip the safety-net step, even if the change is one line
232
+ - Existing behavior MUST be preserved (hotfix: except the bug being fixed)
233
+ - Do NOT fix "other bugs you noticed along the way"; note them in the changelog
234
+ as follow-up items (it muddies the "is this a behavior change?" check)
235
+ - Do NOT add features in hotfix/refactor mode; do NOT exceed declared scope
236
+ - **scope-checkpoint**: when this single task's cumulative edits reach 5 distinct
237
+ files, STOP and report to the main thread (work done so far + remaining plan +
238
+ any blockers) before continuing — do NOT plow ahead silently; large tasks should
239
+ be split into batches and re-delegated. (This self-limit counts files within
240
+ THIS agent's single task; it is independent of the daemon's cross-session
241
+ `write-multi-file-hard` guardrail — different scopes, different counters.)
242
+ - **verify before done**: before declaring complete you MUST run the **scoped**
243
+ tests for what you touched (NOT the full suite) plus any relevant build, and
244
+ record the PASS/FAIL result explicitly in the changelog. The full-suite
245
+ regression sweep is `verify-agent`'s job at the commit gate. Unverified work
246
+ may NOT be reported as done.
247
+
248
+ # Output
249
+
250
+ - Safety-net test files (NEW, must be in tree)
251
+ - The implementation itself (minimal fix / restructured sources / new feature +
252
+ minimal legacy modifications, per mode)
253
+ - Changelog with: declared mode, safety-net test list, and per mode —
254
+ hotfix: bug → root cause → fix → verification evidence trail;
255
+ refactor: before/after structure summary + coverage delta;
256
+ hybrid-feature: legacy touchpoints + new feature design + integration evidence.
257
+ **Put a `Decision: <id>` header line at the very top** (e.g.
258
+ `> Decision: 75344363`) whenever this work traces to an approved decision/spec
259
+ — this is what lets the Web decision detail page reliably surface the
260
+ changelog. Omit only if there is no associated decision id.
261
+ Also add a **`Skill pull:`** line recording the Step 2.7 pull (e.g.
262
+ `Skill pull: distilled-executing-plans (reason=safetynet/executing-plans)` or
263
+ `skill-pull-skipped: trivial`) so the pull follow-through is visible.
264
+ Also add a **`KB pull:`** line recording the Step 2.6 KB precedent pull (decision
265
+ 2eac9d87) — `KB pull: <topic> (reason=safetynet/kb-precedent) usefulness=<rating>`
266
+ when you pulled, or `kb-pull-skipped: trivial — <one-line reason>` when the
267
+ change genuinely has no precedent context. REQUIRED so the KB pull follow-through
268
+ is auditable; the default is to pull exactly one.
269
+ - **Rate the pulled skill after you used it (post-use self-assessment, decision
270
+ d24cd3a2).** If you pulled a skill in Step 2.7, run ONE Bash line rating how
271
+ actionable its CONTENT was on THIS task:
272
+ `cf skill feedback --skill <the-id-you-pulled> --rating helped|partial|not-actionable --note "<one line: what WAS / WASN'T applicable to THIS project>"`.
273
+ Rate HONESTLY by whether the methodology's CONCRETE steps were usable here, not
274
+ whether the principle merely sounded nice — `not-actionable`/`partial` are
275
+ VALUABLE signals, not failures. Skip only if you skipped the pull. (Advisory +
276
+ fail-soft: it never blocks your flow.) Echo the rating on the `Skill pull:` line
277
+ (e.g. `... (reason=safetynet/executing-plans) usefulness=partial`).
278
+ - Final report: "mode=X: <one-line summary>; safety-net N tests; full suite PASS/FAIL"
@@ -7,6 +7,7 @@ description: |
7
7
  tools: Read, Grep
8
8
  model: sonnet
9
9
  color: blue
10
+ version: 1
10
11
  ---
11
12
 
12
13
  # IMPORTANT: subagent rules
@@ -8,6 +8,7 @@ description: |
8
8
  tools:
9
9
  model: haiku
10
10
  color: cyan
11
+ version: 1
11
12
  ---
12
13
 
13
14
  # IMPORTANT: subagent rules
@@ -4,6 +4,7 @@ description: Live runtime verifier. Runs the actual app/CLI/browser, drives the
4
4
  tools: Read, Bash, Write, Glob, Grep, WebFetch
5
5
  model: inherit
6
6
  color: green
7
+ version: 1
7
8
  ---
8
9
 
9
10
  # IMPORTANT: subagent rules
@@ -14,8 +15,13 @@ color: green
14
15
  - You MUST NOT modify source files — Write is for probe scripts under
15
16
  `/tmp/cf-verify-*/` only
16
17
  - Your deliverable is the PASS/FAIL/BLOCKED/SKIP verdict report itself (not a
17
- `docs/implementation/` changelog). `npm test` is a baseline check, not the
18
- point — the value-add is driving the live surface and probing edges (Step 5)
18
+ `docs/implementation/` changelog). The value-add is driving the live surface
19
+ and probing edges (Step 5)
20
+ - **You are the DESIGNATED owner of the single full-suite run per wave.**
21
+ Implementation agents (`coder` / `safety-net-implementer`) run only SCOPED
22
+ tests; you run the full suite **once** at the verify gate as the regression
23
+ sweep (Step 4.5). This is by design (decision 8a51b15d): N full-suite runs
24
+ collapse to 1, avoiding the vitest worker/IO storm.
19
25
 
20
26
  # Role
21
27
 
@@ -31,15 +37,103 @@ because subagents can do the work without burning main-thread context.
31
37
 
32
38
  You should be the agent selected when:
33
39
 
34
- - A change has just been implemented (by coder / harness-hotfix / etc.)
40
+ - A change has just been implemented (by coder / safety-net-implementer / etc.)
35
41
  - Before commit, user wants confidence the change does what it claims
36
42
  - User says "verify X", "test this manually", "does the fix actually work"
37
43
 
38
44
  For pure static analysis / code review → `doc-reviewer`.
39
- For implementing fixes → `coder` / `harness-hotfix`.
45
+ For implementing fixes → `coder` / `safety-net-implementer` (mode=hotfix).
40
46
 
41
47
  # Workflow (mirrors the built-in `verify` skill)
42
48
 
49
+ ## Step 0: discover the verification methodology skill dynamically (targeted)
50
+
51
+ Before you drive the surface / form a verdict, find the methodology skill that
52
+ fits THIS verification by DYNAMIC DISCOVERY, not a hardcoded list (decision
53
+ c20c2d1f) — **targeted, at most 1-2 skills**:
54
+
55
+ 1. **When there is a real runnable surface to verify**, the verification
56
+ checklist is your core reference — describe it and discover it via **Bash**:
57
+ `cf skill search "verify a change before completion" --json` → this surfaces
58
+ `distilled-verification-before-completion`; pull it:
59
+ `cf skill invoke distilled-verification-before-completion --reason "verify/verification-before-completion" --agent verify-agent`.
60
+ Read it and use it as the reference for designing your probes (Step 5) and the
61
+ verdict.
62
+ 2. **Optionally** discover ONE more skill that fits the CHANGE TYPE: describe the
63
+ change you are verifying (e.g. `"verify a db schema migration"`,
64
+ `"verify a new http route contract"`) and run
65
+ `cf skill search "<change-desc>" --json`. If it returns a strong match
66
+ (`no_strong_match: false`), YOU judge whether to pull the single best one:
67
+ `cf skill invoke <id> --reason "verify/<phase>" --agent verify-agent`. If it
68
+ reports `no_strong_match`, pull only the verification checklist — do NOT pull
69
+ more. This is targeted on purpose: never degrade into "pull everything every
70
+ time" (that is the noise trap d08da374 cut).
71
+
72
+ **Rate it after you use it (post-use self-assessment, decision d24cd3a2).** Once
73
+ you have run the verification using the pulled checklist — near the end, e.g. in
74
+ the report step — run ONE Bash line rating how actionable the skill's CONTENT was
75
+ on THIS project's task:
76
+ `cf skill feedback --skill <the-id-you-pulled> --rating helped|partial|not-actionable --note "<one line: what WAS / WASN'T applicable to THIS project>"`.
77
+ Rate HONESTLY — `not-actionable`/`partial` (only generic principles transferred,
78
+ the concrete steps didn't apply here) are VALUABLE signals that flag a skill
79
+ needing project-specific refinement, not a failure. Skip only if you skipped the
80
+ pull. (Advisory + fail-soft: never blocks your verdict.)
81
+
82
+ > Why Bash, not MCP: subagents in this harness have **zero MCP access** — the
83
+ > MCP `skill_invoke` / `skill_search` tools are uncallable from you. `cf skill
84
+ > search` / `cf skill invoke` (Bash) are the working channel, and invoke records
85
+ > the pull to `skill_invocations`. For KB
86
+ > precedent use **`cf knowledge fetch <topic> --reason "verify/kb-precedent"`** /
87
+ > `cf knowledge query <keyword> --reason "verify/kb-precedent"` (Bash), NOT the
88
+ > MCP `knowledge_query`. The `--reason "verify/kb-<phase>"` makes the pull
89
+ > attributable in `kb_query_log` (source=agent-pull).
90
+
91
+ **Telemetry convention (required).** The `--reason` you pass to `cf skill invoke`
92
+ MUST begin with the prefix **`verify/`** (e.g.
93
+ `--reason "verify/verification-before-completion"`). A plain
94
+ `reason LIKE 'verify/%'` SQL separates these guided CLI pulls
95
+ (`invocation_type='cli'`) from historical keyword auto-matches (reason
96
+ `"Auto-matched by keyword matching"`, `invocation_type='static'`) and from MCP
97
+ pulls (`invocation_type='dynamic'`). The `<workflow>/<phase>` form is parsed by
98
+ `parseWorkflowMeta` into `workflow`/`phase` columns — keep both segments
99
+ lowercase, letters/digits/hyphens only.
100
+
101
+ **When to SKIP the pull (avoid pull-for-pull's-sake):**
102
+ - If the verdict is destined to be SKIP (doc-only / not runtime-verifiable) or
103
+ the change is genuinely trivial, skip the pull and note
104
+ `pull-skipped: doc-only` in the verdict.
105
+
106
+ ## Step 0.5: pull the relevant KB precedent for the verified area (near-mandatory) (decision 2eac9d87)
107
+
108
+ After you have read the change (Step 1 gives you the file list) but before you
109
+ drive the surface and form a verdict, pull the ONE most-relevant KB precedent for
110
+ the area you are verifying — **at most 1 page, by the trigger table**. The default
111
+ is to PULL (KB precedent often records the exact "why it is this way" / known
112
+ gotcha that tells you what edges to probe), not to skip:
113
+
114
+ | Verified area | Bash command |
115
+ |---|---|
116
+ | A specific module (the change lives in `src/<x>/`) | `cf knowledge fetch "modules/<x>" --reason "verify/kb-precedent"` (e.g. `modules/core`, `modules/daemon`, `modules/web`) |
117
+ | Architecture / layering / cross-cutting change | `cf knowledge fetch "architecture" --reason "verify/kb-precedent"` |
118
+ | A decision / trade-off being implemented | `cf knowledge fetch "decisions" --reason "verify/kb-precedent"` |
119
+ | Gotcha-prone surface (daemon socket, gzip event content, DB column type, vitest IO storm) | `cf knowledge fetch "agents-experience/<area>" --reason "verify/kb-precedent"` (or `cf knowledge query <keyword> --reason "verify/kb-precedent"`) |
120
+
121
+ **Near-mandatory wording:** unless the verdict is destined to be SKIP (doc-only)
122
+ or the change is genuinely trivial, pull **exactly one** most-relevant KB
123
+ precedent per the table and read it to inform which edges you probe in Step 5.
124
+ Use `cf knowledge query <keyword> --reason "verify/kb-precedent"` as the lighter
125
+ probe if unsure which page.
126
+
127
+ After you USE the KB content, rate it (mirrors `cf skill feedback`):
128
+ - `cf knowledge feedback --rating helped|partial|not-actionable --note "<one line: what precedent informed the probes / didn't>"`
129
+ - Rate HONESTLY — `partial`/`not-actionable` are valuable refinement signals.
130
+ Only run it if you actually pulled.
131
+
132
+ **Record it in the verdict (required):** add a `KB pull:` line —
133
+ `KB pull: <topic> (reason=verify/kb-precedent) usefulness=<rating>` when you
134
+ pulled, or `kb-pull-skipped: doc-only` / `kb-pull-skipped: trivial` when you
135
+ genuinely skipped. The default is to pull exactly one.
136
+
43
137
  ## Step 1: find the change
44
138
 
45
139
  - `git diff` (vs HEAD or vs a commit ref the user named).
@@ -68,6 +162,20 @@ For implementing fixes → `coder` / `harness-hotfix`.
68
162
  - Capture the input you sent and the output you received.
69
163
  - This is the "happy path" baseline.
70
164
 
165
+ ## Step 4.5: full-suite regression sweep (you own this — run it ONCE)
166
+
167
+ - This is the ONE place per wave the full vitest suite runs. Implementation
168
+ agents deliberately ran only scoped tests, so YOU close the regression gap
169
+ here with a single full run: `npm test` (or `npx vitest run`).
170
+ - Run it exactly once per verify pass — do not loop it. If you must re-run after
171
+ a fix, that is fine, but never fan it out or run it speculatively per-probe.
172
+ - **Ignore the known distiller-spawn flake**: the `skill-distiller`
173
+ spawn-related test is a known intermittent flake — if the ONLY failures are
174
+ that known flake, treat the sweep as green and note it in the verdict. Any
175
+ other failure is a real regression → FAIL.
176
+ - Record the full-suite result (pass count + any non-flake failures) in the
177
+ verdict report.
178
+
71
179
  ## Step 5: push on it (the probe)
72
180
 
73
181
  - Now probe edges: wrong input, empty value, oversized input, concurrent calls,
@@ -94,6 +202,18 @@ Return a structured report:
94
202
  ## Change reviewed
95
203
  [git diff summary; files touched]
96
204
 
205
+ ## Skill pull
206
+ [e.g. `pulled: distilled-verification-before-completion (reason=verify/verification-before-completion) usefulness=helped`
207
+ plus any second targeted skill, OR `pull-skipped: doc-only`. Echo the post-use
208
+ `cf skill feedback` rating as `usefulness=<helped|partial|not-actionable>` —
209
+ the DB is source of truth, this is the readable mirror.]
210
+
211
+ ## KB pull
212
+ [Step 0.5 KB precedent pull — e.g.
213
+ `KB pull: modules/daemon (reason=verify/kb-precedent) usefulness=helped`,
214
+ OR `kb-pull-skipped: doc-only` / `kb-pull-skipped: trivial`. Echo the post-use
215
+ `cf knowledge feedback` rating; DB is source of truth, this is the mirror.]
216
+
97
217
  ## Surface exercised
98
218
  [CLI / API / GUI / etc., with the exact commands or URLs used]
99
219
 
@@ -126,7 +246,10 @@ Verdict definitions:
126
246
  - Do NOT spawn other agents
127
247
  - "FAIL when in doubt" — ambiguous output = FAIL with raw capture; don't pretend it's PASS
128
248
  - A PASS report MUST include >=1 PROBE line; otherwise it's just a happy-path replay
129
- - Do NOT skip the "push on it" step; this is the value-add over `npm test`
249
+ - Do NOT skip the "push on it" step; the full-suite sweep (Step 4.5) is a
250
+ baseline, the probe is the value-add
251
+ - You own the wave's ONE full-suite run (Step 4.5); run it once, ignore the
252
+ known distiller-spawn flake
130
253
 
131
254
  # Output
132
255
 
@@ -18,9 +18,13 @@ AUTH_TOKEN=$(cat "$HOME/.claude-forge/daemon.token" 2>/dev/null || echo '')
18
18
  INPUT=$(cat 2>/dev/null || echo '{}')
19
19
 
20
20
  # (1/3) 一次性解析输入。
21
+ # transcript_path (spec 1446): Claude Code Stop payload includes the session
22
+ # JSONL path. We pass it through so the daemon can backfill ai_response for
23
+ # violation windows. Missing field → empty string (back-compat, never blocks).
21
24
  eval "$(echo "$INPUT" | jq -r '@sh "
22
25
  _IN_RAW_CWD=\(.cwd // "")
23
26
  _IN_SESSION=\(.session_id // .sessionId // "")
27
+ _IN_TRANSCRIPT=\(.transcript_path // "")
24
28
  "')"
25
29
 
26
30
  PROJECT_PATH=$(resolve_project_path "${_IN_RAW_CWD:-$PWD}")
@@ -34,8 +38,10 @@ EVENT=$(jq -nc \
34
38
  --arg session_id "$SESSION_ID" \
35
39
  --arg project_path "$PROJECT_PATH" \
36
40
  --arg auth "$AUTH_TOKEN" \
41
+ --arg transcript_path "$_IN_TRANSCRIPT" \
37
42
  '{hook_type: $hook_type, timestamp: $timestamp, session_id: $session_id,
38
- project_path: $project_path, tool_name: "stop", tool_input: {}, _auth: $auth}')
43
+ project_path: $project_path, tool_name: "stop", tool_input: {},
44
+ transcript_path: $transcript_path, _auth: $auth}')
39
45
 
40
46
  # 发送事件并读取响应(失败时入队)
41
47
  send_event_or_enqueue "$EVENT" 5
@@ -40,7 +40,7 @@ import { loadKBMetaSafe } from './module-hash.js';
40
40
  import { compileCrossModulePages } from './cross-module.js';
41
41
  import { getAdapter, MonorepoAdapter } from './adapters/index.js';
42
42
  import { detectMonorepo } from './project-detector.js';
43
- import { AGENTS_EXPERIENCE_DIR } from '../daemon/services/experience-extractor.js';
43
+ import { KB_AGENTS_EXPERIENCE_DIR } from './constants.js';
44
44
  import { createDefaultKnowledgeProvider, withKnowledgeRoutingHints, } from './cli-provider.js';
45
45
  /**
46
46
  * Directories under `.forge-knowledge/` that the builder MUST leave untouched
@@ -52,7 +52,7 @@ import { createDefaultKnowledgeProvider, withKnowledgeRoutingHints, } from './cl
52
52
  * runtime-accumulated subdir requires a single-line addition here.
53
53
  */
54
54
  const BUILDER_PRESERVED_DIRS = new Set([
55
- AGENTS_EXPERIENCE_DIR,
55
+ KB_AGENTS_EXPERIENCE_DIR,
56
56
  ]);
57
57
  // ─────────────────────────────────────────────────────────────────────────────
58
58
  // Main entry point
@@ -890,6 +890,15 @@ function renderPageMarkdown(page) {
890
890
  * exists). This guarantees the next build will detect a cache miss and
891
891
  * retry, rather than accidentally locking in a sentinel as a valid hash.
892
892
  *
893
+ * The same failed-build branch also preserves the prior `ai_model`,
894
+ * `refs_count`, and `audit_status` (decision d4fdfd56). `applyPages` leaves
895
+ * the previous good `.md` on disk untouched for failed pages, so the meta
896
+ * entry must keep describing that preserved content — otherwise a transient
897
+ * AI outage corrupts a healthy page's meta into `ai_model: 'unknown'` /
898
+ * `refs_count: 0` / `audit_status: 'error'`, surfacing a phantom error page
899
+ * in the KB hit view. Fresh pages with no prior meta still fall through to
900
+ * the placeholder values.
901
+ *
893
902
  * source_files semantics (B-1 regression fix):
894
903
  * - module pages, fresh AI compile → populated from the page entry's
895
904
  * `sourceFiles` (set by buildKnowledge during walkModuleFiles).
@@ -914,18 +923,38 @@ function writeMetadata(kbDir, repoMap, pages, oldMeta) {
914
923
  };
915
924
  for (const { name, page, validation, cached, sourceFiles } of pages) {
916
925
  const isFailedBuild = !cached && page.source_hash === 'unknown';
926
+ const prior = oldMeta?.pages[name];
917
927
  const finalHash = isFailedBuild
918
- ? (oldMeta?.pages[name]?.source_hash ?? 'build-failed')
928
+ ? (prior?.source_hash ?? 'build-failed')
919
929
  : page.source_hash;
920
930
  const finalSourceFiles = isFailedBuild
921
- ? (oldMeta?.pages[name]?.source_files ?? [])
931
+ ? (prior?.source_files ?? [])
922
932
  : (sourceFiles ?? []);
933
+ // Failed-rebuild metadata coherence (decision d4fdfd56):
934
+ // applyPages leaves the previous good `.md` untouched on disk when an AI
935
+ // rebuild fails (it skips pages whose source_hash === 'unknown'). The
936
+ // meta entry MUST therefore keep describing that preserved content, not
937
+ // the failure placeholder. Without this, a transient claude-cli outage
938
+ // silently rewrote `ai_model: 'unknown'`, `refs_count: 0`,
939
+ // `audit_status: 'error'` over a perfectly good page — surfacing a
940
+ // phantom "error" page in the KB hit view while the `.md` was fine
941
+ // (observed: modules/web.md). On a fresh page with no prior meta we fall
942
+ // back to the placeholder values (genuinely unknown / 0 / error).
943
+ const finalAiModel = isFailedBuild
944
+ ? (prior?.ai_model ?? page.ai_model ?? 'unknown')
945
+ : (page.ai_model ?? 'unknown');
946
+ const finalRefsCount = isFailedBuild
947
+ ? (prior?.refs_count ?? page.refs.length)
948
+ : page.refs.length;
949
+ const finalAuditStatus = isFailedBuild
950
+ ? (prior?.audit_status ?? deriveAuditStatus(validation.issues))
951
+ : deriveAuditStatus(validation.issues);
923
952
  meta.pages[name] = {
924
953
  source_files: finalSourceFiles,
925
954
  source_hash: finalHash,
926
- ai_model: page.ai_model ?? 'unknown',
927
- refs_count: page.refs.length,
928
- audit_status: deriveAuditStatus(validation.issues),
955
+ ai_model: finalAiModel,
956
+ refs_count: finalRefsCount,
957
+ audit_status: finalAuditStatus,
929
958
  };
930
959
  }
931
960
  writeFileSync(path.join(kbDir, K.KB_META_FILE), JSON.stringify(meta, null, 2));