@oscharko-dev/keiko 0.1.0-beta.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 (450) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +7 -0
  3. package/README.md +621 -0
  4. package/TRADEMARKS.md +41 -0
  5. package/dist/audit/aggregate.d.ts +5 -0
  6. package/dist/audit/aggregate.js +25 -0
  7. package/dist/audit/build.d.ts +2 -0
  8. package/dist/audit/build.js +224 -0
  9. package/dist/audit/errors.d.ts +25 -0
  10. package/dist/audit/errors.js +39 -0
  11. package/dist/audit/index-api.d.ts +14 -0
  12. package/dist/audit/index-api.js +131 -0
  13. package/dist/audit/index.d.ts +12 -0
  14. package/dist/audit/index.js +17 -0
  15. package/dist/audit/persist.d.ts +8 -0
  16. package/dist/audit/persist.js +40 -0
  17. package/dist/audit/redaction.d.ts +3 -0
  18. package/dist/audit/redaction.js +61 -0
  19. package/dist/audit/report.d.ts +18 -0
  20. package/dist/audit/report.js +50 -0
  21. package/dist/audit/retention.d.ts +3 -0
  22. package/dist/audit/retention.js +95 -0
  23. package/dist/audit/runid.d.ts +1 -0
  24. package/dist/audit/runid.js +29 -0
  25. package/dist/audit/side-file.d.ts +12 -0
  26. package/dist/audit/side-file.js +82 -0
  27. package/dist/audit/store.d.ts +12 -0
  28. package/dist/audit/store.js +198 -0
  29. package/dist/audit/types.d.ts +188 -0
  30. package/dist/audit/types.js +8 -0
  31. package/dist/audit/workflow-evidence.d.ts +27 -0
  32. package/dist/audit/workflow-evidence.js +145 -0
  33. package/dist/cli/context.d.ts +2 -0
  34. package/dist/cli/context.js +102 -0
  35. package/dist/cli/evaluate.d.ts +7 -0
  36. package/dist/cli/evaluate.js +207 -0
  37. package/dist/cli/evidence.d.ts +8 -0
  38. package/dist/cli/evidence.js +88 -0
  39. package/dist/cli/gateway-config.d.ts +10 -0
  40. package/dist/cli/gateway-config.js +12 -0
  41. package/dist/cli/gen-tests.d.ts +7 -0
  42. package/dist/cli/gen-tests.js +208 -0
  43. package/dist/cli/index.d.ts +2 -0
  44. package/dist/cli/index.js +14 -0
  45. package/dist/cli/investigate.d.ts +8 -0
  46. package/dist/cli/investigate.js +242 -0
  47. package/dist/cli/models.d.ts +3 -0
  48. package/dist/cli/models.js +64 -0
  49. package/dist/cli/run.d.ts +7 -0
  50. package/dist/cli/run.js +187 -0
  51. package/dist/cli/runner.d.ts +6 -0
  52. package/dist/cli/runner.js +83 -0
  53. package/dist/cli/ui.d.ts +31 -0
  54. package/dist/cli/ui.js +240 -0
  55. package/dist/cli/verify.d.ts +2 -0
  56. package/dist/cli/verify.js +103 -0
  57. package/dist/evaluations/fixtures/bug-investigation/happy-path.d.ts +2 -0
  58. package/dist/evaluations/fixtures/bug-investigation/happy-path.js +66 -0
  59. package/dist/evaluations/fixtures/bug-investigation/investigation-only.d.ts +2 -0
  60. package/dist/evaluations/fixtures/bug-investigation/investigation-only.js +39 -0
  61. package/dist/evaluations/fixtures/bug-investigation/unsafe-action.d.ts +2 -0
  62. package/dist/evaluations/fixtures/bug-investigation/unsafe-action.js +37 -0
  63. package/dist/evaluations/fixtures/index.d.ts +7 -0
  64. package/dist/evaluations/fixtures/index.js +35 -0
  65. package/dist/evaluations/fixtures/support.d.ts +5 -0
  66. package/dist/evaluations/fixtures/support.js +42 -0
  67. package/dist/evaluations/fixtures/unit-tests/happy-path.d.ts +2 -0
  68. package/dist/evaluations/fixtures/unit-tests/happy-path.js +40 -0
  69. package/dist/evaluations/fixtures/unit-tests/retry-then-accept.d.ts +2 -0
  70. package/dist/evaluations/fixtures/unit-tests/retry-then-accept.js +39 -0
  71. package/dist/evaluations/fixtures/unit-tests/unsafe-action.d.ts +2 -0
  72. package/dist/evaluations/fixtures/unit-tests/unsafe-action.js +32 -0
  73. package/dist/evaluations/index.d.ts +12 -0
  74. package/dist/evaluations/index.js +12 -0
  75. package/dist/evaluations/manifest-check.d.ts +1 -0
  76. package/dist/evaluations/manifest-check.js +48 -0
  77. package/dist/evaluations/model-provider.d.ts +12 -0
  78. package/dist/evaluations/model-provider.js +26 -0
  79. package/dist/evaluations/render.d.ts +2 -0
  80. package/dist/evaluations/render.js +59 -0
  81. package/dist/evaluations/runner-support.d.ts +27 -0
  82. package/dist/evaluations/runner-support.js +163 -0
  83. package/dist/evaluations/runner.d.ts +20 -0
  84. package/dist/evaluations/runner.js +174 -0
  85. package/dist/evaluations/scorer.d.ts +14 -0
  86. package/dist/evaluations/scorer.js +131 -0
  87. package/dist/evaluations/scripted-model.d.ts +6 -0
  88. package/dist/evaluations/scripted-model.js +26 -0
  89. package/dist/evaluations/surface-parity.d.ts +2 -0
  90. package/dist/evaluations/surface-parity.js +184 -0
  91. package/dist/evaluations/types.d.ts +74 -0
  92. package/dist/evaluations/types.js +16 -0
  93. package/dist/gateway/capabilities.d.ts +11 -0
  94. package/dist/gateway/capabilities.data.d.ts +2 -0
  95. package/dist/gateway/capabilities.data.js +203 -0
  96. package/dist/gateway/capabilities.js +41 -0
  97. package/dist/gateway/config.d.ts +15 -0
  98. package/dist/gateway/config.js +154 -0
  99. package/dist/gateway/errors.d.ts +72 -0
  100. package/dist/gateway/errors.js +82 -0
  101. package/dist/gateway/gateway.d.ts +19 -0
  102. package/dist/gateway/gateway.js +94 -0
  103. package/dist/gateway/index.d.ts +10 -0
  104. package/dist/gateway/index.js +11 -0
  105. package/dist/gateway/model-selection.d.ts +9 -0
  106. package/dist/gateway/model-selection.js +36 -0
  107. package/dist/gateway/normalize.d.ts +7 -0
  108. package/dist/gateway/normalize.js +93 -0
  109. package/dist/gateway/openai-adapter.d.ts +20 -0
  110. package/dist/gateway/openai-adapter.js +263 -0
  111. package/dist/gateway/redaction.d.ts +1 -0
  112. package/dist/gateway/redaction.js +51 -0
  113. package/dist/gateway/resilience.d.ts +24 -0
  114. package/dist/gateway/resilience.js +166 -0
  115. package/dist/gateway/types.d.ts +108 -0
  116. package/dist/gateway/types.js +2 -0
  117. package/dist/harness/adapters.d.ts +23 -0
  118. package/dist/harness/adapters.js +38 -0
  119. package/dist/harness/context.d.ts +33 -0
  120. package/dist/harness/context.js +21 -0
  121. package/dist/harness/emitter.d.ts +15 -0
  122. package/dist/harness/emitter.js +72 -0
  123. package/dist/harness/errors.d.ts +21 -0
  124. package/dist/harness/errors.js +39 -0
  125. package/dist/harness/executor.d.ts +3 -0
  126. package/dist/harness/executor.js +211 -0
  127. package/dist/harness/fingerprint.d.ts +6 -0
  128. package/dist/harness/fingerprint.js +43 -0
  129. package/dist/harness/index.d.ts +9 -0
  130. package/dist/harness/index.js +13 -0
  131. package/dist/harness/loop.d.ts +3 -0
  132. package/dist/harness/loop.js +159 -0
  133. package/dist/harness/patcher.d.ts +4 -0
  134. package/dist/harness/patcher.js +49 -0
  135. package/dist/harness/planner.d.ts +3 -0
  136. package/dist/harness/planner.js +21 -0
  137. package/dist/harness/ports.d.ts +61 -0
  138. package/dist/harness/ports.js +4 -0
  139. package/dist/harness/session.d.ts +25 -0
  140. package/dist/harness/session.js +116 -0
  141. package/dist/harness/sinks.d.ts +30 -0
  142. package/dist/harness/sinks.js +72 -0
  143. package/dist/harness/tasks/explain-plan.d.ts +3 -0
  144. package/dist/harness/tasks/explain-plan.js +29 -0
  145. package/dist/harness/tasks/generate-unit-tests.d.ts +3 -0
  146. package/dist/harness/tasks/generate-unit-tests.js +28 -0
  147. package/dist/harness/tasks/investigate-bug.d.ts +3 -0
  148. package/dist/harness/tasks/investigate-bug.js +31 -0
  149. package/dist/harness/tasks/policy.d.ts +11 -0
  150. package/dist/harness/tasks/policy.js +22 -0
  151. package/dist/harness/tasks/verify.d.ts +3 -0
  152. package/dist/harness/tasks/verify.js +16 -0
  153. package/dist/harness/types.d.ts +270 -0
  154. package/dist/harness/types.js +33 -0
  155. package/dist/index.d.ts +11 -0
  156. package/dist/index.js +36 -0
  157. package/dist/sdk/index.d.ts +9 -0
  158. package/dist/sdk/index.js +37 -0
  159. package/dist/sdk/run-agent.d.ts +16 -0
  160. package/dist/sdk/run-agent.js +56 -0
  161. package/dist/tools/browser/cdp-client.d.ts +35 -0
  162. package/dist/tools/browser/cdp-client.js +218 -0
  163. package/dist/tools/browser/errors.d.ts +25 -0
  164. package/dist/tools/browser/errors.js +55 -0
  165. package/dist/tools/browser/index.d.ts +5 -0
  166. package/dist/tools/browser/index.js +6 -0
  167. package/dist/tools/browser/session.d.ts +44 -0
  168. package/dist/tools/browser/session.js +748 -0
  169. package/dist/tools/browser/types.d.ts +48 -0
  170. package/dist/tools/browser/types.js +2 -0
  171. package/dist/tools/browser/validators.d.ts +5 -0
  172. package/dist/tools/browser/validators.js +97 -0
  173. package/dist/tools/errors.d.ts +59 -0
  174. package/dist/tools/errors.js +94 -0
  175. package/dist/tools/exec.d.ts +42 -0
  176. package/dist/tools/exec.js +327 -0
  177. package/dist/tools/index.d.ts +11 -0
  178. package/dist/tools/index.js +14 -0
  179. package/dist/tools/patch-content.d.ts +10 -0
  180. package/dist/tools/patch-content.js +126 -0
  181. package/dist/tools/patch-normalize.d.ts +1 -0
  182. package/dist/tools/patch-normalize.js +80 -0
  183. package/dist/tools/patch-parse.d.ts +8 -0
  184. package/dist/tools/patch-parse.js +201 -0
  185. package/dist/tools/patch.d.ts +18 -0
  186. package/dist/tools/patch.js +403 -0
  187. package/dist/tools/registry.d.ts +36 -0
  188. package/dist/tools/registry.js +231 -0
  189. package/dist/tools/sandbox.d.ts +8 -0
  190. package/dist/tools/sandbox.js +121 -0
  191. package/dist/tools/schemas.d.ts +2 -0
  192. package/dist/tools/schemas.js +51 -0
  193. package/dist/tools/terminal-policy.d.ts +9 -0
  194. package/dist/tools/terminal-policy.js +313 -0
  195. package/dist/tools/types.d.ts +99 -0
  196. package/dist/tools/types.js +103 -0
  197. package/dist/tools/writer.d.ts +7 -0
  198. package/dist/tools/writer.js +20 -0
  199. package/dist/ui/browser.d.ts +10 -0
  200. package/dist/ui/browser.js +231 -0
  201. package/dist/ui/chat-handlers.d.ts +4 -0
  202. package/dist/ui/chat-handlers.js +281 -0
  203. package/dist/ui/csp-hashes.json +17 -0
  204. package/dist/ui/csp.d.ts +2 -0
  205. package/dist/ui/csp.js +66 -0
  206. package/dist/ui/deps.d.ts +34 -0
  207. package/dist/ui/deps.js +137 -0
  208. package/dist/ui/evidence.d.ts +27 -0
  209. package/dist/ui/evidence.js +142 -0
  210. package/dist/ui/files-deny.d.ts +2 -0
  211. package/dist/ui/files-deny.js +12 -0
  212. package/dist/ui/files.d.ts +65 -0
  213. package/dist/ui/files.js +492 -0
  214. package/dist/ui/headers.d.ts +2 -0
  215. package/dist/ui/headers.js +21 -0
  216. package/dist/ui/host-check.d.ts +2 -0
  217. package/dist/ui/host-check.js +58 -0
  218. package/dist/ui/index.d.ts +20 -0
  219. package/dist/ui/index.js +23 -0
  220. package/dist/ui/load-csp.d.ts +1 -0
  221. package/dist/ui/load-csp.js +28 -0
  222. package/dist/ui/read-handlers.d.ts +8 -0
  223. package/dist/ui/read-handlers.js +247 -0
  224. package/dist/ui/routes.d.ts +36 -0
  225. package/dist/ui/routes.js +129 -0
  226. package/dist/ui/run-engine.d.ts +20 -0
  227. package/dist/ui/run-engine.js +345 -0
  228. package/dist/ui/run-handlers.d.ts +8 -0
  229. package/dist/ui/run-handlers.js +431 -0
  230. package/dist/ui/run-request.d.ts +13 -0
  231. package/dist/ui/run-request.js +219 -0
  232. package/dist/ui/runs.d.ts +43 -0
  233. package/dist/ui/runs.js +92 -0
  234. package/dist/ui/server.d.ts +11 -0
  235. package/dist/ui/server.js +143 -0
  236. package/dist/ui/sink.d.ts +27 -0
  237. package/dist/ui/sink.js +80 -0
  238. package/dist/ui/sse.d.ts +7 -0
  239. package/dist/ui/sse.js +27 -0
  240. package/dist/ui/static/404.html +1 -0
  241. package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_buildManifest.js +1 -0
  242. package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_ssgManifest.js +1 -0
  243. package/dist/ui/static/_next/static/chunks/255-d47fd57964443afe.js +1 -0
  244. package/dist/ui/static/_next/static/chunks/4-be1fef693af8e088.js +1 -0
  245. package/dist/ui/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
  246. package/dist/ui/static/_next/static/chunks/app/_not-found/page-75825b09bcecad97.js +1 -0
  247. package/dist/ui/static/_next/static/chunks/app/launch/page-9c86a13c29884245.js +1 -0
  248. package/dist/ui/static/_next/static/chunks/app/layout-bdea63fe87947d50.js +1 -0
  249. package/dist/ui/static/_next/static/chunks/app/page-4168c12c68b7a853.js +1 -0
  250. package/dist/ui/static/_next/static/chunks/framework-a6e0b7e30f98059a.js +1 -0
  251. package/dist/ui/static/_next/static/chunks/main-778a50aebff02192.js +1 -0
  252. package/dist/ui/static/_next/static/chunks/main-app-30679af7240d63e9.js +1 -0
  253. package/dist/ui/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
  254. package/dist/ui/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
  255. package/dist/ui/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  256. package/dist/ui/static/_next/static/chunks/webpack-4a462cecab786e93.js +1 -0
  257. package/dist/ui/static/_next/static/css/be7cb54d5c5673b6.css +1 -0
  258. package/dist/ui/static/assets/editors/goland.svg +35 -0
  259. package/dist/ui/static/assets/editors/intellij.svg +39 -0
  260. package/dist/ui/static/assets/editors/pycharm.svg +58 -0
  261. package/dist/ui/static/assets/editors/rustrover.svg +19 -0
  262. package/dist/ui/static/assets/editors/vscode.svg +1 -0
  263. package/dist/ui/static/assets/editors/webstorm.svg +21 -0
  264. package/dist/ui/static/assets/icons/anthropic.svg +1 -0
  265. package/dist/ui/static/assets/icons/brave.svg +1 -0
  266. package/dist/ui/static/assets/icons/css3.svg +1 -0
  267. package/dist/ui/static/assets/icons/docker.svg +1 -0
  268. package/dist/ui/static/assets/icons/git.svg +1 -0
  269. package/dist/ui/static/assets/icons/github.svg +1 -0
  270. package/dist/ui/static/assets/icons/go.svg +1 -0
  271. package/dist/ui/static/assets/icons/gradle.svg +1 -0
  272. package/dist/ui/static/assets/icons/grafana.svg +1 -0
  273. package/dist/ui/static/assets/icons/graphql.svg +1 -0
  274. package/dist/ui/static/assets/icons/html5.svg +1 -0
  275. package/dist/ui/static/assets/icons/image.svg +1 -0
  276. package/dist/ui/static/assets/icons/java.svg +1 -0
  277. package/dist/ui/static/assets/icons/javascript.svg +1 -0
  278. package/dist/ui/static/assets/icons/json.svg +1 -0
  279. package/dist/ui/static/assets/icons/kafka.svg +1 -0
  280. package/dist/ui/static/assets/icons/kubernetes.svg +1 -0
  281. package/dist/ui/static/assets/icons/linear.svg +1 -0
  282. package/dist/ui/static/assets/icons/markdown.svg +1 -0
  283. package/dist/ui/static/assets/icons/nginx.svg +1 -0
  284. package/dist/ui/static/assets/icons/nodejs.svg +1 -0
  285. package/dist/ui/static/assets/icons/notion.svg +1 -0
  286. package/dist/ui/static/assets/icons/openai.svg +1 -0
  287. package/dist/ui/static/assets/icons/playwright.svg +1 -0
  288. package/dist/ui/static/assets/icons/postgresql.svg +1 -0
  289. package/dist/ui/static/assets/icons/prometheus.svg +1 -0
  290. package/dist/ui/static/assets/icons/properties.svg +1 -0
  291. package/dist/ui/static/assets/icons/puppeteer.svg +1 -0
  292. package/dist/ui/static/assets/icons/python.svg +1 -0
  293. package/dist/ui/static/assets/icons/react.svg +1 -0
  294. package/dist/ui/static/assets/icons/redis.svg +1 -0
  295. package/dist/ui/static/assets/icons/rust.svg +1 -0
  296. package/dist/ui/static/assets/icons/sentry.svg +1 -0
  297. package/dist/ui/static/assets/icons/slack.svg +1 -0
  298. package/dist/ui/static/assets/icons/spring.svg +1 -0
  299. package/dist/ui/static/assets/icons/typescript.svg +1 -0
  300. package/dist/ui/static/assets/icons/upstash.svg +1 -0
  301. package/dist/ui/static/assets/icons/yaml.svg +1 -0
  302. package/dist/ui/static/assets/keiko-logo.svg +10 -0
  303. package/dist/ui/static/index.html +1 -0
  304. package/dist/ui/static/index.txt +19 -0
  305. package/dist/ui/static/keiko-logo.svg +10 -0
  306. package/dist/ui/static/launch.html +1 -0
  307. package/dist/ui/static/launch.txt +19 -0
  308. package/dist/ui/static.d.ts +3 -0
  309. package/dist/ui/static.js +72 -0
  310. package/dist/ui/store/chats.d.ts +14 -0
  311. package/dist/ui/store/chats.js +110 -0
  312. package/dist/ui/store/db.d.ts +6 -0
  313. package/dist/ui/store/db.js +182 -0
  314. package/dist/ui/store/errors.d.ts +12 -0
  315. package/dist/ui/store/errors.js +30 -0
  316. package/dist/ui/store/index.d.ts +6 -0
  317. package/dist/ui/store/index.js +6 -0
  318. package/dist/ui/store/messages.d.ts +5 -0
  319. package/dist/ui/store/messages.js +137 -0
  320. package/dist/ui/store/paths.d.ts +4 -0
  321. package/dist/ui/store/paths.js +69 -0
  322. package/dist/ui/store/projects.d.ts +7 -0
  323. package/dist/ui/store/projects.js +61 -0
  324. package/dist/ui/store/schema.d.ts +3 -0
  325. package/dist/ui/store/schema.js +77 -0
  326. package/dist/ui/store/types.d.ts +80 -0
  327. package/dist/ui/store/types.js +3 -0
  328. package/dist/ui/store/validation.d.ts +4 -0
  329. package/dist/ui/store/validation.js +72 -0
  330. package/dist/ui/store-handlers.d.ts +16 -0
  331. package/dist/ui/store-handlers.js +465 -0
  332. package/dist/ui/terminal-errors.d.ts +21 -0
  333. package/dist/ui/terminal-errors.js +45 -0
  334. package/dist/ui/terminal-evidence.d.ts +20 -0
  335. package/dist/ui/terminal-evidence.js +65 -0
  336. package/dist/ui/terminal-routes.d.ts +9 -0
  337. package/dist/ui/terminal-routes.js +219 -0
  338. package/dist/ui/terminal.d.ts +67 -0
  339. package/dist/ui/terminal.js +835 -0
  340. package/dist/verification/classify.d.ts +10 -0
  341. package/dist/verification/classify.js +53 -0
  342. package/dist/verification/detect.d.ts +4 -0
  343. package/dist/verification/detect.js +81 -0
  344. package/dist/verification/errors.d.ts +11 -0
  345. package/dist/verification/errors.js +21 -0
  346. package/dist/verification/index.d.ts +17 -0
  347. package/dist/verification/index.js +13 -0
  348. package/dist/verification/limits.d.ts +3 -0
  349. package/dist/verification/limits.js +40 -0
  350. package/dist/verification/monitor.d.ts +4 -0
  351. package/dist/verification/monitor.js +58 -0
  352. package/dist/verification/orchestrator.d.ts +16 -0
  353. package/dist/verification/orchestrator.js +363 -0
  354. package/dist/verification/plan.d.ts +9 -0
  355. package/dist/verification/plan.js +125 -0
  356. package/dist/verification/summary.d.ts +40 -0
  357. package/dist/verification/summary.js +67 -0
  358. package/dist/verification/types.d.ts +63 -0
  359. package/dist/verification/types.js +13 -0
  360. package/dist/workflows/bug-investigation/context.d.ts +7 -0
  361. package/dist/workflows/bug-investigation/context.js +119 -0
  362. package/dist/workflows/bug-investigation/descriptor.d.ts +3 -0
  363. package/dist/workflows/bug-investigation/descriptor.js +46 -0
  364. package/dist/workflows/bug-investigation/emit.d.ts +12 -0
  365. package/dist/workflows/bug-investigation/emit.js +35 -0
  366. package/dist/workflows/bug-investigation/events.d.ts +81 -0
  367. package/dist/workflows/bug-investigation/events.js +9 -0
  368. package/dist/workflows/bug-investigation/failure-parse.d.ts +3 -0
  369. package/dist/workflows/bug-investigation/failure-parse.js +154 -0
  370. package/dist/workflows/bug-investigation/guard.d.ts +2 -0
  371. package/dist/workflows/bug-investigation/guard.js +69 -0
  372. package/dist/workflows/bug-investigation/index.d.ts +7 -0
  373. package/dist/workflows/bug-investigation/index.js +13 -0
  374. package/dist/workflows/bug-investigation/internal.d.ts +37 -0
  375. package/dist/workflows/bug-investigation/internal.js +64 -0
  376. package/dist/workflows/bug-investigation/model-loop.d.ts +4 -0
  377. package/dist/workflows/bug-investigation/model-loop.js +223 -0
  378. package/dist/workflows/bug-investigation/parse.d.ts +3 -0
  379. package/dist/workflows/bug-investigation/parse.js +123 -0
  380. package/dist/workflows/bug-investigation/prompt.d.ts +4 -0
  381. package/dist/workflows/bug-investigation/prompt.js +107 -0
  382. package/dist/workflows/bug-investigation/report.d.ts +23 -0
  383. package/dist/workflows/bug-investigation/report.js +151 -0
  384. package/dist/workflows/bug-investigation/stages.d.ts +13 -0
  385. package/dist/workflows/bug-investigation/stages.js +242 -0
  386. package/dist/workflows/bug-investigation/types.d.ts +91 -0
  387. package/dist/workflows/bug-investigation/types.js +14 -0
  388. package/dist/workflows/bug-investigation/verify-stage.d.ts +10 -0
  389. package/dist/workflows/bug-investigation/verify-stage.js +91 -0
  390. package/dist/workflows/bug-investigation/workflow.d.ts +2 -0
  391. package/dist/workflows/bug-investigation/workflow.js +74 -0
  392. package/dist/workflows/descriptor.d.ts +20 -0
  393. package/dist/workflows/descriptor.js +8 -0
  394. package/dist/workflows/index.d.ts +3 -0
  395. package/dist/workflows/index.js +2 -0
  396. package/dist/workflows/unit-tests/context.d.ts +7 -0
  397. package/dist/workflows/unit-tests/context.js +129 -0
  398. package/dist/workflows/unit-tests/conventions.d.ts +4 -0
  399. package/dist/workflows/unit-tests/conventions.js +87 -0
  400. package/dist/workflows/unit-tests/descriptor.d.ts +4 -0
  401. package/dist/workflows/unit-tests/descriptor.js +43 -0
  402. package/dist/workflows/unit-tests/emit.d.ts +12 -0
  403. package/dist/workflows/unit-tests/emit.js +35 -0
  404. package/dist/workflows/unit-tests/events.d.ts +78 -0
  405. package/dist/workflows/unit-tests/events.js +7 -0
  406. package/dist/workflows/unit-tests/index.d.ts +6 -0
  407. package/dist/workflows/unit-tests/index.js +10 -0
  408. package/dist/workflows/unit-tests/internal.d.ts +35 -0
  409. package/dist/workflows/unit-tests/internal.js +43 -0
  410. package/dist/workflows/unit-tests/model-loop.d.ts +4 -0
  411. package/dist/workflows/unit-tests/model-loop.js +95 -0
  412. package/dist/workflows/unit-tests/parse.d.ts +6 -0
  413. package/dist/workflows/unit-tests/parse.js +68 -0
  414. package/dist/workflows/unit-tests/prompt.d.ts +4 -0
  415. package/dist/workflows/unit-tests/prompt.js +71 -0
  416. package/dist/workflows/unit-tests/report.d.ts +21 -0
  417. package/dist/workflows/unit-tests/report.js +90 -0
  418. package/dist/workflows/unit-tests/stages.d.ts +9 -0
  419. package/dist/workflows/unit-tests/stages.js +155 -0
  420. package/dist/workflows/unit-tests/types.d.ts +70 -0
  421. package/dist/workflows/unit-tests/types.js +11 -0
  422. package/dist/workflows/unit-tests/verify-stage.d.ts +9 -0
  423. package/dist/workflows/unit-tests/verify-stage.js +56 -0
  424. package/dist/workflows/unit-tests/workflow.d.ts +2 -0
  425. package/dist/workflows/unit-tests/workflow.js +58 -0
  426. package/dist/workspace/contextPack.d.ts +9 -0
  427. package/dist/workspace/contextPack.js +94 -0
  428. package/dist/workspace/detect.d.ts +3 -0
  429. package/dist/workspace/detect.js +135 -0
  430. package/dist/workspace/discovery.d.ts +9 -0
  431. package/dist/workspace/discovery.js +167 -0
  432. package/dist/workspace/errors.d.ts +39 -0
  433. package/dist/workspace/errors.js +66 -0
  434. package/dist/workspace/fs.d.ts +21 -0
  435. package/dist/workspace/fs.js +36 -0
  436. package/dist/workspace/ignore.d.ts +14 -0
  437. package/dist/workspace/ignore.js +176 -0
  438. package/dist/workspace/index.d.ts +11 -0
  439. package/dist/workspace/index.js +13 -0
  440. package/dist/workspace/paths.d.ts +2 -0
  441. package/dist/workspace/paths.js +38 -0
  442. package/dist/workspace/realpath.d.ts +7 -0
  443. package/dist/workspace/realpath.js +72 -0
  444. package/dist/workspace/retrieval.d.ts +9 -0
  445. package/dist/workspace/retrieval.js +74 -0
  446. package/dist/workspace/summary.d.ts +3 -0
  447. package/dist/workspace/summary.js +54 -0
  448. package/dist/workspace/types.d.ts +103 -0
  449. package/dist/workspace/types.js +27 -0
  450. package/package.json +58 -0
@@ -0,0 +1,151 @@
1
+ // Report assembly and Markdown rendering (ADR-0009 D3). assembleBugReport composes the
2
+ // JSON-serializable BugInvestigationReport from pipeline stage outputs, enforcing the STRUCTURAL
3
+ // verified/hypothesis split: `verified` carries only facts the workflow established (patch validated,
4
+ // patch applied, verification summary, parsed failure frames) and `hypothesis` carries the redacted,
5
+ // explicitly-UNVERIFIED model output. ALL prose, the diff, the dry-run preview, frame paths, changed
6
+ // paths, and nextActions are redacted via redact() here — defence in depth on top of upstream
7
+ // redaction. renderBugMarkdownReport produces the CLI text path. Pure: no IO, no clock; the caller
8
+ // injects durationMs and counters.
9
+ import { redact } from "../../gateway/redaction.js";
10
+ import { isElevatedReviewPath } from "./guard.js";
11
+ const TEST_CASE_PREFIXES = ["test(", "it(", "describe("];
12
+ // Best-effort count of added regression-test cases: added (`+`) lines whose trimmed text begins
13
+ // with a known test-case opener. Not authoritative — informational only.
14
+ function estimateRegressionCount(files) {
15
+ let count = 0;
16
+ for (const file of files) {
17
+ for (const hunk of file.hunks) {
18
+ for (const line of hunk.lines) {
19
+ if (!line.startsWith("+")) {
20
+ continue;
21
+ }
22
+ const trimmed = line.slice(1).trimStart();
23
+ if (TEST_CASE_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
24
+ count += 1;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ return count;
30
+ }
31
+ function toChangedFiles(files) {
32
+ return files.map((file) => ({
33
+ path: redact(file.path),
34
+ kind: file.kind,
35
+ addedLines: file.addedLines,
36
+ removedLines: file.removedLines,
37
+ elevatedReview: isElevatedReviewPath(file.path),
38
+ }));
39
+ }
40
+ function redactFrames(frames) {
41
+ return frames.map((frame) => frame.line === undefined
42
+ ? { file: redact(frame.file), line: undefined }
43
+ : { file: redact(frame.file), line: frame.line });
44
+ }
45
+ function redactHypothesis(hypothesis) {
46
+ return {
47
+ rootCause: redactOptional(hypothesis.rootCause),
48
+ regressionTestStrategy: redactOptional(hypothesis.regressionTestStrategy),
49
+ uncertainty: redactOptional(hypothesis.uncertainty),
50
+ confidence: hypothesis.confidence,
51
+ };
52
+ }
53
+ function redactOptional(value) {
54
+ return value === undefined ? undefined : redact(value);
55
+ }
56
+ export function assembleBugReport(parts) {
57
+ return {
58
+ workflowId: "bug-investigation",
59
+ status: parts.status,
60
+ modelId: parts.modelId,
61
+ durationMs: parts.durationMs,
62
+ verified: {
63
+ patchValidates: parts.patchValidates,
64
+ patchApplied: parts.patchApplied,
65
+ verification: parts.verification,
66
+ failureFrames: redactFrames(parts.failureFrames),
67
+ },
68
+ hypothesis: redactHypothesis(parts.hypothesis),
69
+ proposedDiff: redactOptional(parts.proposedDiff),
70
+ dryRunPreview: redactOptional(parts.dryRunPreview),
71
+ changedFiles: toChangedFiles(parts.patchFiles),
72
+ regressionCoverage: estimateRegressionCount(parts.patchFiles),
73
+ verificationSkipReason: redactOptional(parts.verificationSkipReason),
74
+ nextActions: parts.nextActions.map((action) => redact(action)),
75
+ failureReason: redactOptional(parts.failureReason),
76
+ modelCallCount: parts.modelCallCount,
77
+ patchRetryCount: parts.patchRetryCount,
78
+ };
79
+ }
80
+ // ─── Markdown rendering ──────────────────────────────────────────────────────────
81
+ function sectionIf(heading, body) {
82
+ return body === undefined ? [] : [`## ${heading}`, body, ""];
83
+ }
84
+ function frameLines(report) {
85
+ if (report.verified.failureFrames.length === 0) {
86
+ return [];
87
+ }
88
+ const rows = report.verified.failureFrames.map((f) => f.line === undefined ? `- ${f.file}` : `- ${f.file}:${String(f.line)}`);
89
+ return ["## Failure locations (verified)", ...rows, ""];
90
+ }
91
+ function changedFileLines(report) {
92
+ if (report.changedFiles.length === 0) {
93
+ return [];
94
+ }
95
+ const rows = report.changedFiles.map((f) => {
96
+ const flag = f.elevatedReview ? " [elevated review]" : "";
97
+ return `- ${f.kind} ${f.path} (+${String(f.addedLines)} -${String(f.removedLines)})${flag}`;
98
+ });
99
+ return ["## Changed files (verified)", ...rows, ""];
100
+ }
101
+ function verificationLines(report) {
102
+ if (report.verified.verification !== undefined) {
103
+ return [
104
+ "## Verification (verified)",
105
+ `Status: ${report.verified.verification.overallStatus}`,
106
+ "",
107
+ ];
108
+ }
109
+ if (report.verificationSkipReason !== undefined) {
110
+ return ["## Verification (verified)", report.verificationSkipReason, ""];
111
+ }
112
+ return [];
113
+ }
114
+ function hypothesisLines(report) {
115
+ const h = report.hypothesis;
116
+ // Suppress the section entirely when the model produced no hypothesis (rejected/failed paths), so
117
+ // the rendered report does not show a bare "UNVERIFIED" header with no content.
118
+ const hasContent = h.rootCause !== undefined ||
119
+ h.regressionTestStrategy !== undefined ||
120
+ h.uncertainty !== undefined ||
121
+ h.confidence !== undefined;
122
+ if (!hasContent) {
123
+ return [];
124
+ }
125
+ return [
126
+ "## Hypothesis (UNVERIFIED — model output)",
127
+ ...sectionIf("Root cause", h.rootCause),
128
+ ...sectionIf("Regression test", h.regressionTestStrategy),
129
+ ...sectionIf("Uncertainty", h.uncertainty),
130
+ ...(h.confidence === undefined ? [] : [`Confidence: ${h.confidence}`, ""]),
131
+ ];
132
+ }
133
+ // A human-readable Markdown report for the CLI text path. Every field is already redacted by
134
+ // assembleBugReport, so rendering is plain string composition. Verified facts and the UNVERIFIED
135
+ // model hypothesis are clearly separated (AC #7).
136
+ export function renderBugMarkdownReport(report) {
137
+ return [
138
+ `# Bug investigation: ${report.status}`,
139
+ `Model: ${report.modelId} · ${String(report.durationMs)}ms · ` +
140
+ `${String(report.modelCallCount)} model call(s) · ${String(report.patchRetryCount)} retry(ies)`,
141
+ "",
142
+ ...frameLines(report),
143
+ ...changedFileLines(report),
144
+ ...verificationLines(report),
145
+ ...hypothesisLines(report),
146
+ ...sectionIf("Failure", report.failureReason),
147
+ ...(report.nextActions.length > 0
148
+ ? ["## Next actions", ...report.nextActions.map((a) => `- ${a}`), ""]
149
+ : []),
150
+ ].join("\n");
151
+ }
@@ -0,0 +1,13 @@
1
+ import type { WorkspaceInfo } from "../../workspace/index.js";
2
+ import { type AcceptedBugPatch, type BugModelLoopResult, type BugRunState } from "./internal.js";
3
+ import type { BugInvestigationReport, FailureEvidence, Hypothesis } from "./types.js";
4
+ export declare function rejectedReport(state: BugRunState, loop: BugModelLoopResult, evidence: FailureEvidence): BugInvestigationReport;
5
+ export declare function insufficientInputReport(state: BugRunState): BugInvestigationReport;
6
+ export declare function investigationOnlyReport(state: BugRunState, loop: BugModelLoopResult, hypothesis: Hypothesis, evidence: FailureEvidence): BugInvestigationReport;
7
+ export declare function dryRunReport(state: BugRunState, loop: BugModelLoopResult, accepted: AcceptedBugPatch, evidence: FailureEvidence): BugInvestigationReport;
8
+ export declare function cancelledReport(state: BugRunState, loop: BugModelLoopResult, accepted: AcceptedBugPatch | undefined, evidence: FailureEvidence, applied?: {
9
+ readonly changedFiles: readonly string[];
10
+ }): BugInvestigationReport;
11
+ export declare function failedReport(state: BugRunState, error: unknown): BugInvestigationReport;
12
+ export declare function emitCompleted(state: BugRunState, report: BugInvestigationReport): BugInvestigationReport;
13
+ export declare function finishPipeline(state: BugRunState, workspace: WorkspaceInfo, loop: BugModelLoopResult, evidence: FailureEvidence): Promise<BugInvestigationReport>;
@@ -0,0 +1,242 @@
1
+ // Terminal-report stages (ADR-0009 D3/D4/D11). Each function maps a pipeline outcome —
2
+ // fix-proposed (dry-run), fix-applied, investigation-only, rejected, cancelled, or failed — to the
3
+ // redacted BugInvestigationReport via assembleBugReport. applyPatch (apply mode) is the one IO
4
+ // boundary here and is fail-closed in #6 (applyEnabled gates the write); it receives the SAME
5
+ // tighter PatchLimits as validatePatch (D6 bound 1, defence-in-depth re-validation). finishPipeline
6
+ // selects the branch; emitCompleted stamps the terminal event. All redaction is inside assembleBugReport.
7
+ import { redact } from "../../gateway/redaction.js";
8
+ import { applyPatch, CommandCancelledError, renderDryRun, } from "../../tools/index.js";
9
+ import { nodeWorkspaceFs } from "../../workspace/fs.js";
10
+ import { assembleBugReport } from "./report.js";
11
+ import { runBugVerification } from "./verify-stage.js";
12
+ import { investigationNextActions, nextActionsFor, patchLimitsFrom, } from "./internal.js";
13
+ import { isElevatedReviewPath } from "./guard.js";
14
+ const EMPTY_HYPOTHESIS = {
15
+ rootCause: undefined,
16
+ regressionTestStrategy: undefined,
17
+ uncertainty: undefined,
18
+ confidence: undefined,
19
+ };
20
+ function elevatedPaths(accepted) {
21
+ return accepted.validation.files.map((f) => f.path).filter((p) => isElevatedReviewPath(p));
22
+ }
23
+ export function rejectedReport(state, loop, evidence) {
24
+ return assembleBugReport({
25
+ status: "rejected",
26
+ modelId: state.input.modelId,
27
+ durationMs: state.now() - state.startedAt,
28
+ patchFiles: [],
29
+ patchValidates: false,
30
+ patchApplied: false,
31
+ verification: undefined,
32
+ failureFrames: evidence.frames,
33
+ hypothesis: EMPTY_HYPOTHESIS,
34
+ proposedDiff: undefined,
35
+ dryRunPreview: undefined,
36
+ verificationSkipReason: undefined,
37
+ nextActions: [
38
+ `The model did not produce an in-scope fix (${loop.lastRejectionCode ?? "insufficient evidence"})`,
39
+ ],
40
+ failureReason: undefined,
41
+ modelCallCount: loop.modelCallCount,
42
+ patchRetryCount: loop.patchRetryCount,
43
+ });
44
+ }
45
+ // Insufficient-input rejection: returned by the intake precondition before any model call.
46
+ export function insufficientInputReport(state) {
47
+ return assembleBugReport({
48
+ status: "rejected",
49
+ modelId: state.input.modelId,
50
+ durationMs: state.now() - state.startedAt,
51
+ patchFiles: [],
52
+ patchValidates: false,
53
+ patchApplied: false,
54
+ verification: undefined,
55
+ failureFrames: [],
56
+ hypothesis: EMPTY_HYPOTHESIS,
57
+ proposedDiff: undefined,
58
+ dryRunPreview: undefined,
59
+ verificationSkipReason: undefined,
60
+ nextActions: [
61
+ "Provide at least one of: a description, failing output, a stack trace, or suspected target files",
62
+ ],
63
+ failureReason: undefined,
64
+ modelCallCount: 0,
65
+ patchRetryCount: 0,
66
+ });
67
+ }
68
+ export function investigationOnlyReport(state, loop, hypothesis, evidence) {
69
+ return assembleBugReport({
70
+ status: "investigation-only",
71
+ modelId: state.input.modelId,
72
+ durationMs: state.now() - state.startedAt,
73
+ patchFiles: [],
74
+ patchValidates: false,
75
+ patchApplied: false,
76
+ verification: undefined,
77
+ failureFrames: evidence.frames,
78
+ hypothesis,
79
+ proposedDiff: undefined,
80
+ dryRunPreview: undefined,
81
+ verificationSkipReason: "verification skipped: no patch produced (investigation-only)",
82
+ nextActions: investigationNextActions(),
83
+ failureReason: undefined,
84
+ modelCallCount: loop.modelCallCount,
85
+ patchRetryCount: loop.patchRetryCount,
86
+ });
87
+ }
88
+ export function dryRunReport(state, loop, accepted, evidence) {
89
+ const files = accepted.validation.files.map((f) => f.path);
90
+ return assembleBugReport({
91
+ status: "fix-proposed",
92
+ modelId: state.input.modelId,
93
+ durationMs: state.now() - state.startedAt,
94
+ patchFiles: accepted.validation.files,
95
+ patchValidates: true,
96
+ patchApplied: false,
97
+ verification: undefined,
98
+ failureFrames: evidence.frames,
99
+ hypothesis: accepted.hypothesis,
100
+ proposedDiff: accepted.diff,
101
+ dryRunPreview: renderDryRun(accepted.validation),
102
+ verificationSkipReason: "verification skipped: dry-run, no files written",
103
+ nextActions: nextActionsFor(false, files, elevatedPaths(accepted)),
104
+ failureReason: undefined,
105
+ modelCallCount: loop.modelCallCount,
106
+ patchRetryCount: loop.patchRetryCount,
107
+ });
108
+ }
109
+ // `applied` is set ONLY on a post-apply abort: the patch is already on disk, so the report (and the
110
+ // #10 ledger record) must reflect that (patchApplied: true) rather than hard-coding false. A
111
+ // pre-apply abort passes applied === undefined and stays patchApplied: false.
112
+ export function cancelledReport(state, loop, accepted, evidence, applied) {
113
+ const nextActions = applied === undefined
114
+ ? ["The workflow was cancelled before completion"]
115
+ : [
116
+ `The fix was applied to ${applied.changedFiles[0] ?? "disk"} but the workflow was cancelled before verification completed`,
117
+ "Run `keiko verify` to confirm the suite",
118
+ ];
119
+ return assembleBugReport({
120
+ status: "cancelled",
121
+ modelId: state.input.modelId,
122
+ durationMs: state.now() - state.startedAt,
123
+ patchFiles: accepted?.validation.files ?? [],
124
+ patchValidates: accepted !== undefined,
125
+ patchApplied: applied !== undefined,
126
+ verification: undefined,
127
+ failureFrames: evidence.frames,
128
+ hypothesis: accepted?.hypothesis ?? EMPTY_HYPOTHESIS,
129
+ proposedDiff: accepted?.diff,
130
+ dryRunPreview: accepted === undefined ? undefined : renderDryRun(accepted.validation),
131
+ verificationSkipReason: "verification skipped: cancelled",
132
+ nextActions,
133
+ failureReason: undefined,
134
+ modelCallCount: loop.modelCallCount,
135
+ patchRetryCount: loop.patchRetryCount,
136
+ });
137
+ }
138
+ export function failedReport(state, error) {
139
+ const message = redact(error instanceof Error ? error.message : "unexpected workflow failure");
140
+ const errorCode = error instanceof Error ? error.name : "UNKNOWN";
141
+ state.emitter.emit({ type: "bug:failed", errorCode, message });
142
+ return assembleBugReport({
143
+ status: "failed",
144
+ modelId: state.input.modelId,
145
+ durationMs: state.now() - state.startedAt,
146
+ patchFiles: [],
147
+ patchValidates: false,
148
+ patchApplied: false,
149
+ verification: undefined,
150
+ failureFrames: [],
151
+ hypothesis: EMPTY_HYPOTHESIS,
152
+ proposedDiff: undefined,
153
+ dryRunPreview: undefined,
154
+ verificationSkipReason: undefined,
155
+ nextActions: [`Inspect the error and retry: ${message}`],
156
+ failureReason: message,
157
+ modelCallCount: state.progress.modelCallCount,
158
+ patchRetryCount: state.progress.patchRetryCount,
159
+ });
160
+ }
161
+ function applyBugPatch(state, workspace, accepted) {
162
+ const fs = state.deps.fs ?? nodeWorkspaceFs;
163
+ const applyResult = applyPatch(workspace, accepted.diff, {
164
+ applyEnabled: true,
165
+ signal: state.signal,
166
+ fs,
167
+ limits: patchLimitsFrom(state.limits),
168
+ ...(state.deps.writer === undefined ? {} : { writer: state.deps.writer }),
169
+ });
170
+ return { fs, applyResult };
171
+ }
172
+ async function applyAndVerify(state, workspace, loop, accepted, evidence) {
173
+ let applyResult;
174
+ let fs;
175
+ try {
176
+ ({ fs, applyResult } = applyBugPatch(state, workspace, accepted));
177
+ }
178
+ catch (error) {
179
+ if (error instanceof CommandCancelledError) {
180
+ return cancelledReport(state, loop, accepted, evidence);
181
+ }
182
+ throw error;
183
+ }
184
+ state.emitter.emit({
185
+ type: "bug:patch:applied",
186
+ changedFiles: applyResult.changedFiles.length,
187
+ created: applyResult.created.length,
188
+ deleted: applyResult.deleted.length,
189
+ });
190
+ if (state.signal.aborted) {
191
+ // Post-apply abort: the patch is already on disk, so the report must reflect patchApplied: true
192
+ // (M1) — the #10 ledger record must match the real filesystem state.
193
+ return cancelledReport(state, loop, accepted, evidence, {
194
+ changedFiles: applyResult.changedFiles,
195
+ });
196
+ }
197
+ const verification = await runBugVerification(state, workspace, accepted.validation.files, fs);
198
+ return assembleBugReport({
199
+ status: "fix-applied",
200
+ modelId: state.input.modelId,
201
+ durationMs: state.now() - state.startedAt,
202
+ patchFiles: accepted.validation.files,
203
+ patchValidates: true,
204
+ patchApplied: true,
205
+ verification: verification.summary,
206
+ failureFrames: evidence.frames,
207
+ hypothesis: accepted.hypothesis,
208
+ proposedDiff: accepted.diff,
209
+ dryRunPreview: renderDryRun(accepted.validation),
210
+ verificationSkipReason: verification.skipReason,
211
+ nextActions: nextActionsFor(true, applyResult.changedFiles, elevatedPaths(accepted)),
212
+ failureReason: undefined,
213
+ modelCallCount: loop.modelCallCount,
214
+ patchRetryCount: loop.patchRetryCount,
215
+ });
216
+ }
217
+ export function emitCompleted(state, report) {
218
+ state.emitter.emit({
219
+ type: "bug:completed",
220
+ status: report.status,
221
+ durationMs: report.durationMs,
222
+ });
223
+ return report;
224
+ }
225
+ // Selects the terminal branch from the model-loop result: investigation-only (hypothesis, no
226
+ // patch), rejected (nothing usable), cancelled (abort before apply), apply+verify (apply mode), or
227
+ // dry-run (default).
228
+ export async function finishPipeline(state, workspace, loop, evidence) {
229
+ if (loop.accepted === undefined) {
230
+ if (loop.investigationOnly !== undefined) {
231
+ return investigationOnlyReport(state, loop, loop.investigationOnly, evidence);
232
+ }
233
+ return rejectedReport(state, loop, evidence);
234
+ }
235
+ if (state.signal.aborted) {
236
+ return cancelledReport(state, loop, loop.accepted, evidence);
237
+ }
238
+ if (state.input.apply === true) {
239
+ return applyAndVerify(state, workspace, loop, loop.accepted, evidence);
240
+ }
241
+ return dryRunReport(state, loop, loop.accepted, evidence);
242
+ }
@@ -0,0 +1,91 @@
1
+ import type { ModelPort } from "../../harness/ports.js";
2
+ import type { PatchChangeKind, SpawnFn, WorkspaceWriter } from "../../tools/index.js";
3
+ import type { WorkspaceFs } from "../../workspace/index.js";
4
+ import type { VerificationAuditSummary } from "../../verification/index.js";
5
+ import type { BugWorkflowEventSink } from "./events.js";
6
+ export type BugWorkflowStatus = "fix-applied" | "fix-proposed" | "investigation-only" | "rejected" | "cancelled" | "failed";
7
+ export interface FailureFrame {
8
+ readonly file: string;
9
+ readonly line?: number | undefined;
10
+ }
11
+ export interface FailureEvidence {
12
+ readonly frames: readonly FailureFrame[];
13
+ readonly messages: readonly string[];
14
+ }
15
+ export interface BugWorkflowLimits {
16
+ readonly maxModelCalls: number;
17
+ readonly maxRetries: number;
18
+ readonly contextBudgetBytes: number;
19
+ readonly maxBytesPerFile: number;
20
+ readonly maxFilesChanged: number;
21
+ readonly maxChangedLines: number;
22
+ readonly maxPatchBytes: number;
23
+ }
24
+ export declare const DEFAULT_BUG_WORKFLOW_LIMITS: BugWorkflowLimits;
25
+ export interface BugReportInput {
26
+ readonly description?: string | undefined;
27
+ readonly failingOutput?: string | undefined;
28
+ readonly stackTrace?: string | undefined;
29
+ readonly targetFiles?: readonly string[] | undefined;
30
+ }
31
+ export interface BugInvestigationInput {
32
+ readonly workspaceRoot: string;
33
+ readonly report: BugReportInput;
34
+ readonly apply?: boolean | undefined;
35
+ readonly modelId: string;
36
+ readonly limits?: Partial<BugWorkflowLimits> | undefined;
37
+ }
38
+ export interface BugInvestigationDeps {
39
+ readonly model: ModelPort;
40
+ readonly fs?: WorkspaceFs | undefined;
41
+ readonly writer?: WorkspaceWriter | undefined;
42
+ readonly spawn?: SpawnFn | undefined;
43
+ readonly now?: (() => number) | undefined;
44
+ readonly idSource?: (() => string) | undefined;
45
+ readonly sink?: BugWorkflowEventSink | undefined;
46
+ readonly processEnv?: NodeJS.ProcessEnv | undefined;
47
+ readonly signal?: AbortSignal | undefined;
48
+ }
49
+ export interface VerifiedFindings {
50
+ readonly patchValidates: boolean;
51
+ readonly patchApplied: boolean;
52
+ readonly verification?: VerificationAuditSummary | undefined;
53
+ readonly failureFrames: readonly FailureFrame[];
54
+ }
55
+ export interface Hypothesis {
56
+ readonly rootCause?: string | undefined;
57
+ readonly regressionTestStrategy?: string | undefined;
58
+ readonly uncertainty?: string | undefined;
59
+ readonly confidence?: "low" | "medium" | "high" | undefined;
60
+ }
61
+ export interface ChangedFile {
62
+ readonly path: string;
63
+ readonly kind: PatchChangeKind;
64
+ readonly addedLines: number;
65
+ readonly removedLines: number;
66
+ readonly elevatedReview: boolean;
67
+ }
68
+ export interface BugInvestigationReport {
69
+ readonly workflowId: "bug-investigation";
70
+ readonly status: BugWorkflowStatus;
71
+ readonly modelId: string;
72
+ readonly durationMs: number;
73
+ readonly verified: VerifiedFindings;
74
+ readonly hypothesis: Hypothesis;
75
+ readonly proposedDiff?: string | undefined;
76
+ readonly dryRunPreview?: string | undefined;
77
+ readonly changedFiles: readonly ChangedFile[];
78
+ readonly regressionCoverage: number;
79
+ readonly verificationSkipReason?: string | undefined;
80
+ readonly nextActions: readonly string[];
81
+ readonly failureReason?: string | undefined;
82
+ readonly modelCallCount: number;
83
+ readonly patchRetryCount: number;
84
+ }
85
+ export interface ParsedBugOutput {
86
+ readonly diff: string;
87
+ readonly rootCause: string | undefined;
88
+ readonly regressionTestStrategy: string | undefined;
89
+ readonly uncertainty: string | undefined;
90
+ readonly confidence: "low" | "medium" | "high" | undefined;
91
+ }
@@ -0,0 +1,14 @@
1
+ // All interfaces, type aliases, and frozen constant tables for the bug-investigation workflow
2
+ // (ADR-0009 D2/D3/D4/D7/D13). No runtime logic beyond the frozen tables. `readonly` everywhere;
3
+ // optional props are `| undefined` because exactOptionalPropertyTypes is on. Every report shape is
4
+ // plain JSON-serializable so the #10 audit ledger can persist it. Names are DISTINCT from the
5
+ // unit-test workflow's (ADR-0009 D5) because both barrels are re-exported from the package root.
6
+ export const DEFAULT_BUG_WORKFLOW_LIMITS = {
7
+ maxModelCalls: 3,
8
+ maxRetries: 2,
9
+ contextBudgetBytes: 65_536,
10
+ maxBytesPerFile: 8_192,
11
+ maxFilesChanged: 10,
12
+ maxChangedLines: 300,
13
+ maxPatchBytes: 65_536,
14
+ };
@@ -0,0 +1,10 @@
1
+ import { type PatchFileChange } from "../../tools/index.js";
2
+ import { type WorkspaceFs, type WorkspaceInfo } from "../../workspace/index.js";
3
+ import { type VerificationAuditSummary } from "../../verification/index.js";
4
+ import type { BugRunState } from "./internal.js";
5
+ export declare const SKIP_UNRESOLVED = "verification skipped: framework unknown or no test files resolved";
6
+ export interface BugVerificationOutcome {
7
+ readonly summary: VerificationAuditSummary | undefined;
8
+ readonly skipReason: string | undefined;
9
+ }
10
+ export declare function runBugVerification(state: BugRunState, workspace: WorkspaceInfo, changedFiles: readonly PatchFileChange[], fs: WorkspaceFs): Promise<BugVerificationOutcome>;
@@ -0,0 +1,91 @@
1
+ // The verification stage (ADR-0009 D11). Runs ONLY after a successful apply: it resolves a
2
+ // verification plan by deriving the just-fixed/added tests from the changed SOURCE files via #7
3
+ // resolveTargetedTests (so it finds the sibling/mirrored test incl. the just-added regression
4
+ // test), falling back to the full `test` script, and records an explicit skip reason when neither
5
+ // resolves or the framework is unknown. Verification reuses the #7 orchestrator unchanged; this
6
+ // stage only wires the plan and projects an output-text-free audit summary. DEFERRED (D11): a
7
+ // pre-patch reproduction baseline — Wave-1 verifies only the post-apply state.
8
+ import { nodeSpawnFn } from "../../tools/index.js";
9
+ import {} from "../../workspace/index.js";
10
+ import { buildVerificationPlan, detectScripts, resolveTargetedTests, runVerification, summarizeForAudit, DEFAULT_VERIFICATION_LIMITS, } from "../../verification/index.js";
11
+ import { isSensitivePath } from "./guard.js";
12
+ export const SKIP_UNRESOLVED = "verification skipped: framework unknown or no test files resolved";
13
+ // The non-test source files the patch changed — passed to resolveTargetedTests so it can find the
14
+ // associated tests (incl. the just-added regression test). We approximate "source" as any changed
15
+ // path that is not itself a test file (basename marks .test/.spec) and not a sensitive path.
16
+ function changedSourceFiles(files) {
17
+ return files.map((f) => f.path).filter((path) => !isSensitivePath(path) && !isTestFile(path));
18
+ }
19
+ function changedTestFiles(files) {
20
+ return files.map((f) => f.path).filter((path) => !isSensitivePath(path) && isTestFile(path));
21
+ }
22
+ function isTestFile(path) {
23
+ const slash = path.lastIndexOf("/");
24
+ const base = slash === -1 ? path : path.slice(slash + 1);
25
+ const segments = base.split(".");
26
+ return segments.includes("test") || segments.includes("spec");
27
+ }
28
+ function buildPlanFallback(workspace, fs) {
29
+ const catalog = detectScripts(workspace, fs);
30
+ return buildVerificationPlan(workspace, catalog, { only: ["test"] }, fs);
31
+ }
32
+ function targetedChangedTests(workspace, testFiles) {
33
+ if (testFiles.length === 0) {
34
+ return undefined;
35
+ }
36
+ if (workspace.testFramework === "vitest") {
37
+ return {
38
+ kind: "targeted-test",
39
+ scriptName: undefined,
40
+ command: "npx",
41
+ args: ["vitest", "run", ...testFiles],
42
+ limits: DEFAULT_VERIFICATION_LIMITS,
43
+ };
44
+ }
45
+ if (workspace.testFramework === "jest") {
46
+ return {
47
+ kind: "targeted-test",
48
+ scriptName: undefined,
49
+ command: "npx",
50
+ args: ["jest", ...testFiles],
51
+ limits: DEFAULT_VERIFICATION_LIMITS,
52
+ };
53
+ }
54
+ return undefined;
55
+ }
56
+ function resolveVerificationPlan(workspace, changedFiles, fs) {
57
+ const directTests = targetedChangedTests(workspace, changedTestFiles(changedFiles));
58
+ if (directTests !== undefined) {
59
+ return { workspaceRoot: workspace.root, steps: [directTests] };
60
+ }
61
+ const targeted = resolveTargetedTests(workspace, changedSourceFiles(changedFiles), fs, DEFAULT_VERIFICATION_LIMITS);
62
+ if (targeted.length > 0) {
63
+ return { workspaceRoot: workspace.root, steps: targeted };
64
+ }
65
+ const fallback = buildPlanFallback(workspace, fs);
66
+ const runnable = fallback.steps.filter((step) => step.skipReason === undefined);
67
+ return runnable.length > 0 ? { workspaceRoot: workspace.root, steps: runnable } : undefined;
68
+ }
69
+ export async function runBugVerification(state, workspace, changedFiles, fs) {
70
+ const plan = resolveVerificationPlan(workspace, changedFiles, fs);
71
+ if (plan === undefined) {
72
+ return { summary: undefined, skipReason: SKIP_UNRESOLVED };
73
+ }
74
+ const report = await runVerification(plan, {
75
+ workspace,
76
+ signal: state.signal,
77
+ spawn: state.deps.spawn ?? nodeSpawnFn,
78
+ processEnv: state.deps.processEnv ?? process.env,
79
+ now: state.now,
80
+ fs,
81
+ });
82
+ const summary = summarizeForAudit(report);
83
+ state.emitter.emit({
84
+ type: "bug:verification:result",
85
+ overallStatus: summary.overallStatus,
86
+ stepCount: summary.results.length,
87
+ passedCount: summary.results.filter((r) => r.status === "passed").length,
88
+ durationMs: summary.durationMs,
89
+ });
90
+ return { summary, skipReason: undefined };
91
+ }
@@ -0,0 +1,2 @@
1
+ import type { BugInvestigationDeps, BugInvestigationInput, BugInvestigationReport } from "./types.js";
2
+ export declare function investigateBug(input: BugInvestigationInput, deps: BugInvestigationDeps): Promise<BugInvestigationReport>;