@isaacriehm/cairn 0.1.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 (562) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/backprop/id.d.ts +14 -0
  5. package/dist/backprop/id.js +40 -0
  6. package/dist/backprop/id.js.map +1 -0
  7. package/dist/backprop/index.d.ts +23 -0
  8. package/dist/backprop/index.js +21 -0
  9. package/dist/backprop/index.js.map +1 -0
  10. package/dist/backprop/prompt.d.ts +16 -0
  11. package/dist/backprop/prompt.js +101 -0
  12. package/dist/backprop/prompt.js.map +1 -0
  13. package/dist/backprop/runner.d.ts +18 -0
  14. package/dist/backprop/runner.js +95 -0
  15. package/dist/backprop/runner.js.map +1 -0
  16. package/dist/backprop/schema.d.ts +61 -0
  17. package/dist/backprop/schema.js +55 -0
  18. package/dist/backprop/schema.js.map +1 -0
  19. package/dist/backprop/types.d.ts +101 -0
  20. package/dist/backprop/types.js +24 -0
  21. package/dist/backprop/types.js.map +1 -0
  22. package/dist/backprop/writer.d.ts +27 -0
  23. package/dist/backprop/writer.js +301 -0
  24. package/dist/backprop/writer.js.map +1 -0
  25. package/dist/claude/error.d.ts +33 -0
  26. package/dist/claude/error.js +58 -0
  27. package/dist/claude/error.js.map +1 -0
  28. package/dist/claude/index.d.ts +3 -0
  29. package/dist/claude/index.js +3 -0
  30. package/dist/claude/index.js.map +1 -0
  31. package/dist/claude/runner.d.ts +11 -0
  32. package/dist/claude/runner.js +132 -0
  33. package/dist/claude/runner.js.map +1 -0
  34. package/dist/claude/types.d.ts +52 -0
  35. package/dist/claude/types.js +14 -0
  36. package/dist/claude/types.js.map +1 -0
  37. package/dist/cli/attention.d.ts +11 -0
  38. package/dist/cli/attention.js +234 -0
  39. package/dist/cli/attention.js.map +1 -0
  40. package/dist/cli/daemon.d.ts +54 -0
  41. package/dist/cli/daemon.js +351 -0
  42. package/dist/cli/daemon.js.map +1 -0
  43. package/dist/cli/doctor.d.ts +8 -0
  44. package/dist/cli/doctor.js +116 -0
  45. package/dist/cli/doctor.js.map +1 -0
  46. package/dist/cli/gc.d.ts +15 -0
  47. package/dist/cli/gc.js +139 -0
  48. package/dist/cli/gc.js.map +1 -0
  49. package/dist/cli/hook.d.ts +18 -0
  50. package/dist/cli/hook.js +57 -0
  51. package/dist/cli/hook.js.map +1 -0
  52. package/dist/cli/index.d.ts +2 -0
  53. package/dist/cli/index.js +127 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/cli/init.d.ts +1 -0
  56. package/dist/cli/init.js +77 -0
  57. package/dist/cli/init.js.map +1 -0
  58. package/dist/cli/install.d.ts +52 -0
  59. package/dist/cli/install.js +308 -0
  60. package/dist/cli/install.js.map +1 -0
  61. package/dist/cli/join.d.ts +1 -0
  62. package/dist/cli/join.js +84 -0
  63. package/dist/cli/join.js.map +1 -0
  64. package/dist/cli/mcp.d.ts +1 -0
  65. package/dist/cli/mcp.js +62 -0
  66. package/dist/cli/mcp.js.map +1 -0
  67. package/dist/cli/mirror.d.ts +1 -0
  68. package/dist/cli/mirror.js +97 -0
  69. package/dist/cli/mirror.js.map +1 -0
  70. package/dist/cli/run.d.ts +1 -0
  71. package/dist/cli/run.js +174 -0
  72. package/dist/cli/run.js.map +1 -0
  73. package/dist/cli/scope.d.ts +8 -0
  74. package/dist/cli/scope.js +65 -0
  75. package/dist/cli/scope.js.map +1 -0
  76. package/dist/cli/task.d.ts +18 -0
  77. package/dist/cli/task.js +137 -0
  78. package/dist/cli/task.js.map +1 -0
  79. package/dist/cli/watch.d.ts +1 -0
  80. package/dist/cli/watch.js +73 -0
  81. package/dist/cli/watch.js.map +1 -0
  82. package/dist/decision-capture/capture.d.ts +57 -0
  83. package/dist/decision-capture/capture.js +186 -0
  84. package/dist/decision-capture/capture.js.map +1 -0
  85. package/dist/decision-capture/extractor.d.ts +20 -0
  86. package/dist/decision-capture/extractor.js +103 -0
  87. package/dist/decision-capture/extractor.js.map +1 -0
  88. package/dist/decision-capture/id.d.ts +14 -0
  89. package/dist/decision-capture/id.js +44 -0
  90. package/dist/decision-capture/id.js.map +1 -0
  91. package/dist/decision-capture/index.d.ts +25 -0
  92. package/dist/decision-capture/index.js +21 -0
  93. package/dist/decision-capture/index.js.map +1 -0
  94. package/dist/decision-capture/prompt.d.ts +15 -0
  95. package/dist/decision-capture/prompt.js +68 -0
  96. package/dist/decision-capture/prompt.js.map +1 -0
  97. package/dist/decision-capture/refinement-prompt.d.ts +25 -0
  98. package/dist/decision-capture/refinement-prompt.js +146 -0
  99. package/dist/decision-capture/refinement-prompt.js.map +1 -0
  100. package/dist/decision-capture/refinement-schema.d.ts +52 -0
  101. package/dist/decision-capture/refinement-schema.js +61 -0
  102. package/dist/decision-capture/refinement-schema.js.map +1 -0
  103. package/dist/decision-capture/refinement.d.ts +60 -0
  104. package/dist/decision-capture/refinement.js +439 -0
  105. package/dist/decision-capture/refinement.js.map +1 -0
  106. package/dist/decision-capture/schema.d.ts +70 -0
  107. package/dist/decision-capture/schema.js +71 -0
  108. package/dist/decision-capture/schema.js.map +1 -0
  109. package/dist/decision-capture/types.d.ts +201 -0
  110. package/dist/decision-capture/types.js +20 -0
  111. package/dist/decision-capture/types.js.map +1 -0
  112. package/dist/decision-capture/writer.d.ts +90 -0
  113. package/dist/decision-capture/writer.js +267 -0
  114. package/dist/decision-capture/writer.js.map +1 -0
  115. package/dist/frontend/discord/acl.d.ts +6 -0
  116. package/dist/frontend/discord/acl.js +19 -0
  117. package/dist/frontend/discord/acl.js.map +1 -0
  118. package/dist/frontend/discord/channels.d.ts +29 -0
  119. package/dist/frontend/discord/channels.js +58 -0
  120. package/dist/frontend/discord/channels.js.map +1 -0
  121. package/dist/frontend/discord/classifier.d.ts +16 -0
  122. package/dist/frontend/discord/classifier.js +29 -0
  123. package/dist/frontend/discord/classifier.js.map +1 -0
  124. package/dist/frontend/discord/index.d.ts +118 -0
  125. package/dist/frontend/discord/index.js +1104 -0
  126. package/dist/frontend/discord/index.js.map +1 -0
  127. package/dist/frontend/discord/slash.d.ts +18 -0
  128. package/dist/frontend/discord/slash.js +90 -0
  129. package/dist/frontend/discord/slash.js.map +1 -0
  130. package/dist/frontend/inbox.d.ts +17 -0
  131. package/dist/frontend/inbox.js +30 -0
  132. package/dist/frontend/inbox.js.map +1 -0
  133. package/dist/frontend/index.d.ts +8 -0
  134. package/dist/frontend/index.js +6 -0
  135. package/dist/frontend/index.js.map +1 -0
  136. package/dist/frontend/stub/index.d.ts +58 -0
  137. package/dist/frontend/stub/index.js +144 -0
  138. package/dist/frontend/stub/index.js.map +1 -0
  139. package/dist/frontend/types.d.ts +247 -0
  140. package/dist/frontend/types.js +15 -0
  141. package/dist/frontend/types.js.map +1 -0
  142. package/dist/gc/apply.d.ts +26 -0
  143. package/dist/gc/apply.js +48 -0
  144. package/dist/gc/apply.js.map +1 -0
  145. package/dist/gc/canary.d.ts +42 -0
  146. package/dist/gc/canary.js +134 -0
  147. package/dist/gc/canary.js.map +1 -0
  148. package/dist/gc/classify.d.ts +25 -0
  149. package/dist/gc/classify.js +89 -0
  150. package/dist/gc/classify.js.map +1 -0
  151. package/dist/gc/doc-gardening.d.ts +29 -0
  152. package/dist/gc/doc-gardening.js +146 -0
  153. package/dist/gc/doc-gardening.js.map +1 -0
  154. package/dist/gc/frontmatter.d.ts +35 -0
  155. package/dist/gc/frontmatter.js +111 -0
  156. package/dist/gc/frontmatter.js.map +1 -0
  157. package/dist/gc/generator-drift.d.ts +28 -0
  158. package/dist/gc/generator-drift.js +53 -0
  159. package/dist/gc/generator-drift.js.map +1 -0
  160. package/dist/gc/index.d.ts +35 -0
  161. package/dist/gc/index.js +26 -0
  162. package/dist/gc/index.js.map +1 -0
  163. package/dist/gc/quality-update.d.ts +23 -0
  164. package/dist/gc/quality-update.js +69 -0
  165. package/dist/gc/quality-update.js.map +1 -0
  166. package/dist/gc/stub-hits.d.ts +31 -0
  167. package/dist/gc/stub-hits.js +125 -0
  168. package/dist/gc/stub-hits.js.map +1 -0
  169. package/dist/gc/sweep.d.ts +56 -0
  170. package/dist/gc/sweep.js +178 -0
  171. package/dist/gc/sweep.js.map +1 -0
  172. package/dist/gc/types.d.ts +129 -0
  173. package/dist/gc/types.js +26 -0
  174. package/dist/gc/types.js.map +1 -0
  175. package/dist/ground/drift.d.ts +8 -0
  176. package/dist/ground/drift.js +23 -0
  177. package/dist/ground/drift.js.map +1 -0
  178. package/dist/ground/frontmatter.d.ts +20 -0
  179. package/dist/ground/frontmatter.js +49 -0
  180. package/dist/ground/frontmatter.js.map +1 -0
  181. package/dist/ground/glob.d.ts +10 -0
  182. package/dist/ground/glob.js +46 -0
  183. package/dist/ground/glob.js.map +1 -0
  184. package/dist/ground/index.d.ts +14 -0
  185. package/dist/ground/index.js +10 -0
  186. package/dist/ground/index.js.map +1 -0
  187. package/dist/ground/ledgers.d.ts +18 -0
  188. package/dist/ground/ledgers.js +103 -0
  189. package/dist/ground/ledgers.js.map +1 -0
  190. package/dist/ground/manifest.d.ts +10 -0
  191. package/dist/ground/manifest.js +88 -0
  192. package/dist/ground/manifest.js.map +1 -0
  193. package/dist/ground/paths.d.ts +20 -0
  194. package/dist/ground/paths.js +61 -0
  195. package/dist/ground/paths.js.map +1 -0
  196. package/dist/ground/quality-grades.d.ts +11 -0
  197. package/dist/ground/quality-grades.js +98 -0
  198. package/dist/ground/quality-grades.js.map +1 -0
  199. package/dist/ground/schemas.d.ts +306 -0
  200. package/dist/ground/schemas.js +188 -0
  201. package/dist/ground/schemas.js.map +1 -0
  202. package/dist/ground/walk.d.ts +7 -0
  203. package/dist/ground/walk.js +53 -0
  204. package/dist/ground/walk.js.map +1 -0
  205. package/dist/index.d.ts +8 -0
  206. package/dist/index.js +9 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/init/detect.d.ts +25 -0
  209. package/dist/init/detect.js +336 -0
  210. package/dist/init/detect.js.map +1 -0
  211. package/dist/init/index.d.ts +14 -0
  212. package/dist/init/index.js +9 -0
  213. package/dist/init/index.js.map +1 -0
  214. package/dist/init/init.d.ts +68 -0
  215. package/dist/init/init.js +673 -0
  216. package/dist/init/init.js.map +1 -0
  217. package/dist/init/mapper.d.ts +160 -0
  218. package/dist/init/mapper.js +248 -0
  219. package/dist/init/mapper.js.map +1 -0
  220. package/dist/init/prompts.d.ts +70 -0
  221. package/dist/init/prompts.js +80 -0
  222. package/dist/init/prompts.js.map +1 -0
  223. package/dist/init/secrets.d.ts +18 -0
  224. package/dist/init/secrets.js +76 -0
  225. package/dist/init/secrets.js.map +1 -0
  226. package/dist/init/seed.d.ts +21 -0
  227. package/dist/init/seed.js +75 -0
  228. package/dist/init/seed.js.map +1 -0
  229. package/dist/init/setup-runners.d.ts +17 -0
  230. package/dist/init/setup-runners.js +70 -0
  231. package/dist/init/setup-runners.js.map +1 -0
  232. package/dist/init/types.d.ts +59 -0
  233. package/dist/init/types.js +10 -0
  234. package/dist/init/types.js.map +1 -0
  235. package/dist/init/walker.d.ts +53 -0
  236. package/dist/init/walker.js +460 -0
  237. package/dist/init/walker.js.map +1 -0
  238. package/dist/init/workflow-block.d.ts +34 -0
  239. package/dist/init/workflow-block.js +110 -0
  240. package/dist/init/workflow-block.js.map +1 -0
  241. package/dist/logger.d.ts +3 -0
  242. package/dist/logger.js +23 -0
  243. package/dist/logger.js.map +1 -0
  244. package/dist/mcp/context.d.ts +16 -0
  245. package/dist/mcp/context.js +8 -0
  246. package/dist/mcp/context.js.map +1 -0
  247. package/dist/mcp/errors.d.ts +17 -0
  248. package/dist/mcp/errors.js +23 -0
  249. package/dist/mcp/errors.js.map +1 -0
  250. package/dist/mcp/index.d.ts +10 -0
  251. package/dist/mcp/index.js +7 -0
  252. package/dist/mcp/index.js.map +1 -0
  253. package/dist/mcp/path-allowlist.d.ts +25 -0
  254. package/dist/mcp/path-allowlist.js +66 -0
  255. package/dist/mcp/path-allowlist.js.map +1 -0
  256. package/dist/mcp/result.d.ts +8 -0
  257. package/dist/mcp/result.js +18 -0
  258. package/dist/mcp/result.js.map +1 -0
  259. package/dist/mcp/schemas.d.ts +153 -0
  260. package/dist/mcp/schemas.js +135 -0
  261. package/dist/mcp/schemas.js.map +1 -0
  262. package/dist/mcp/server.d.ts +11 -0
  263. package/dist/mcp/server.js +58 -0
  264. package/dist/mcp/server.js.map +1 -0
  265. package/dist/mcp/telemetry.d.ts +15 -0
  266. package/dist/mcp/telemetry.js +13 -0
  267. package/dist/mcp/telemetry.js.map +1 -0
  268. package/dist/mcp/tools/append.d.ts +8 -0
  269. package/dist/mcp/tools/append.js +33 -0
  270. package/dist/mcp/tools/append.js.map +1 -0
  271. package/dist/mcp/tools/archive.d.ts +8 -0
  272. package/dist/mcp/tools/archive.js +49 -0
  273. package/dist/mcp/tools/archive.js.map +1 -0
  274. package/dist/mcp/tools/ask-operator.d.ts +34 -0
  275. package/dist/mcp/tools/ask-operator.js +93 -0
  276. package/dist/mcp/tools/ask-operator.js.map +1 -0
  277. package/dist/mcp/tools/canonical-for-topic.d.ts +6 -0
  278. package/dist/mcp/tools/canonical-for-topic.js +40 -0
  279. package/dist/mcp/tools/canonical-for-topic.js.map +1 -0
  280. package/dist/mcp/tools/decision-get.d.ts +6 -0
  281. package/dist/mcp/tools/decision-get.js +49 -0
  282. package/dist/mcp/tools/decision-get.js.map +1 -0
  283. package/dist/mcp/tools/decisions-for-symbol.d.ts +7 -0
  284. package/dist/mcp/tools/decisions-for-symbol.js +42 -0
  285. package/dist/mcp/tools/decisions-for-symbol.js.map +1 -0
  286. package/dist/mcp/tools/decisions-in-scope.d.ts +7 -0
  287. package/dist/mcp/tools/decisions-in-scope.js +47 -0
  288. package/dist/mcp/tools/decisions-in-scope.js.map +1 -0
  289. package/dist/mcp/tools/drop-task.d.ts +12 -0
  290. package/dist/mcp/tools/drop-task.js +47 -0
  291. package/dist/mcp/tools/drop-task.js.map +1 -0
  292. package/dist/mcp/tools/get-full.d.ts +7 -0
  293. package/dist/mcp/tools/get-full.js +46 -0
  294. package/dist/mcp/tools/get-full.js.map +1 -0
  295. package/dist/mcp/tools/ground-get.d.ts +7 -0
  296. package/dist/mcp/tools/ground-get.js +80 -0
  297. package/dist/mcp/tools/ground-get.js.map +1 -0
  298. package/dist/mcp/tools/index.d.ts +3 -0
  299. package/dist/mcp/tools/index.js +44 -0
  300. package/dist/mcp/tools/index.js.map +1 -0
  301. package/dist/mcp/tools/invariant-get.d.ts +6 -0
  302. package/dist/mcp/tools/invariant-get.js +49 -0
  303. package/dist/mcp/tools/invariant-get.js.map +1 -0
  304. package/dist/mcp/tools/invariants-in-scope.d.ts +7 -0
  305. package/dist/mcp/tools/invariants-in-scope.js +65 -0
  306. package/dist/mcp/tools/invariants-in-scope.js.map +1 -0
  307. package/dist/mcp/tools/query-history.d.ts +9 -0
  308. package/dist/mcp/tools/query-history.js +33 -0
  309. package/dist/mcp/tools/query-history.js.map +1 -0
  310. package/dist/mcp/tools/record-decision.d.ts +14 -0
  311. package/dist/mcp/tools/record-decision.js +101 -0
  312. package/dist/mcp/tools/record-decision.js.map +1 -0
  313. package/dist/mcp/tools/record-run-event.d.ts +10 -0
  314. package/dist/mcp/tools/record-run-event.js +28 -0
  315. package/dist/mcp/tools/record-run-event.js.map +1 -0
  316. package/dist/mcp/tools/search.d.ts +9 -0
  317. package/dist/mcp/tools/search.js +165 -0
  318. package/dist/mcp/tools/search.js.map +1 -0
  319. package/dist/mcp/tools/supersedes-chain.d.ts +6 -0
  320. package/dist/mcp/tools/supersedes-chain.js +66 -0
  321. package/dist/mcp/tools/supersedes-chain.js.map +1 -0
  322. package/dist/mcp/tools/timeline.d.ts +9 -0
  323. package/dist/mcp/tools/timeline.js +65 -0
  324. package/dist/mcp/tools/timeline.js.map +1 -0
  325. package/dist/mcp/tools/types.d.ts +9 -0
  326. package/dist/mcp/tools/types.js +2 -0
  327. package/dist/mcp/tools/types.js.map +1 -0
  328. package/dist/mirror/clone.d.ts +6 -0
  329. package/dist/mirror/clone.js +48 -0
  330. package/dist/mirror/clone.js.map +1 -0
  331. package/dist/mirror/dirty-overlap.d.ts +13 -0
  332. package/dist/mirror/dirty-overlap.js +77 -0
  333. package/dist/mirror/dirty-overlap.js.map +1 -0
  334. package/dist/mirror/index.d.ts +7 -0
  335. package/dist/mirror/index.js +7 -0
  336. package/dist/mirror/index.js.map +1 -0
  337. package/dist/mirror/paths.d.ts +18 -0
  338. package/dist/mirror/paths.js +45 -0
  339. package/dist/mirror/paths.js.map +1 -0
  340. package/dist/mirror/push.d.ts +9 -0
  341. package/dist/mirror/push.js +27 -0
  342. package/dist/mirror/push.js.map +1 -0
  343. package/dist/mirror/state.d.ts +4 -0
  344. package/dist/mirror/state.js +36 -0
  345. package/dist/mirror/state.js.map +1 -0
  346. package/dist/mirror/sync.d.ts +9 -0
  347. package/dist/mirror/sync.js +33 -0
  348. package/dist/mirror/sync.js.map +1 -0
  349. package/dist/mirror/types.d.ts +77 -0
  350. package/dist/mirror/types.js +2 -0
  351. package/dist/mirror/types.js.map +1 -0
  352. package/dist/orchestrator/activity-summarizer.d.ts +33 -0
  353. package/dist/orchestrator/activity-summarizer.js +120 -0
  354. package/dist/orchestrator/activity-summarizer.js.map +1 -0
  355. package/dist/orchestrator/inbox.d.ts +78 -0
  356. package/dist/orchestrator/inbox.js +115 -0
  357. package/dist/orchestrator/inbox.js.map +1 -0
  358. package/dist/orchestrator/index.d.ts +9 -0
  359. package/dist/orchestrator/index.js +7 -0
  360. package/dist/orchestrator/index.js.map +1 -0
  361. package/dist/orchestrator/orchestrator.d.ts +154 -0
  362. package/dist/orchestrator/orchestrator.js +2437 -0
  363. package/dist/orchestrator/orchestrator.js.map +1 -0
  364. package/dist/orchestrator/prompt.d.ts +19 -0
  365. package/dist/orchestrator/prompt.js +50 -0
  366. package/dist/orchestrator/prompt.js.map +1 -0
  367. package/dist/orchestrator/queue.d.ts +21 -0
  368. package/dist/orchestrator/queue.js +80 -0
  369. package/dist/orchestrator/queue.js.map +1 -0
  370. package/dist/orchestrator/run-log.d.ts +53 -0
  371. package/dist/orchestrator/run-log.js +92 -0
  372. package/dist/orchestrator/run-log.js.map +1 -0
  373. package/dist/orchestrator/runner.d.ts +56 -0
  374. package/dist/orchestrator/runner.js +172 -0
  375. package/dist/orchestrator/runner.js.map +1 -0
  376. package/dist/orchestrator/tool-digest.d.ts +35 -0
  377. package/dist/orchestrator/tool-digest.js +116 -0
  378. package/dist/orchestrator/tool-digest.js.map +1 -0
  379. package/dist/orchestrator/types.d.ts +263 -0
  380. package/dist/orchestrator/types.js +2 -0
  381. package/dist/orchestrator/types.js.map +1 -0
  382. package/dist/orchestrator/workspace.d.ts +21 -0
  383. package/dist/orchestrator/workspace.js +31 -0
  384. package/dist/orchestrator/workspace.js.map +1 -0
  385. package/dist/profiles/index.d.ts +3 -0
  386. package/dist/profiles/index.js +3 -0
  387. package/dist/profiles/index.js.map +1 -0
  388. package/dist/profiles/registry.d.ts +5 -0
  389. package/dist/profiles/registry.js +31 -0
  390. package/dist/profiles/registry.js.map +1 -0
  391. package/dist/profiles/types.d.ts +48 -0
  392. package/dist/profiles/types.js +11 -0
  393. package/dist/profiles/types.js.map +1 -0
  394. package/dist/profiles/unknown.d.ts +9 -0
  395. package/dist/profiles/unknown.js +17 -0
  396. package/dist/profiles/unknown.js.map +1 -0
  397. package/dist/reviewer/index.d.ts +6 -0
  398. package/dist/reviewer/index.js +5 -0
  399. package/dist/reviewer/index.js.map +1 -0
  400. package/dist/reviewer/prompt.d.ts +11 -0
  401. package/dist/reviewer/prompt.js +132 -0
  402. package/dist/reviewer/prompt.js.map +1 -0
  403. package/dist/reviewer/remediation.d.ts +15 -0
  404. package/dist/reviewer/remediation.js +61 -0
  405. package/dist/reviewer/remediation.js.map +1 -0
  406. package/dist/reviewer/reviewer.d.ts +9 -0
  407. package/dist/reviewer/reviewer.js +89 -0
  408. package/dist/reviewer/reviewer.js.map +1 -0
  409. package/dist/reviewer/schema.d.ts +45 -0
  410. package/dist/reviewer/schema.js +43 -0
  411. package/dist/reviewer/schema.js.map +1 -0
  412. package/dist/reviewer/types.d.ts +74 -0
  413. package/dist/reviewer/types.js +14 -0
  414. package/dist/reviewer/types.js.map +1 -0
  415. package/dist/sensors/attestation.d.ts +44 -0
  416. package/dist/sensors/attestation.js +262 -0
  417. package/dist/sensors/attestation.js.map +1 -0
  418. package/dist/sensors/catalog.d.ts +41 -0
  419. package/dist/sensors/catalog.js +123 -0
  420. package/dist/sensors/catalog.js.map +1 -0
  421. package/dist/sensors/decisions.d.ts +30 -0
  422. package/dist/sensors/decisions.js +393 -0
  423. package/dist/sensors/decisions.js.map +1 -0
  424. package/dist/sensors/diff.d.ts +27 -0
  425. package/dist/sensors/diff.js +148 -0
  426. package/dist/sensors/diff.js.map +1 -0
  427. package/dist/sensors/index.d.ts +13 -0
  428. package/dist/sensors/index.js +9 -0
  429. package/dist/sensors/index.js.map +1 -0
  430. package/dist/sensors/remediation.d.ts +20 -0
  431. package/dist/sensors/remediation.js +65 -0
  432. package/dist/sensors/remediation.js.map +1 -0
  433. package/dist/sensors/runner.d.ts +44 -0
  434. package/dist/sensors/runner.js +95 -0
  435. package/dist/sensors/runner.js.map +1 -0
  436. package/dist/sensors/structural.d.ts +30 -0
  437. package/dist/sensors/structural.js +204 -0
  438. package/dist/sensors/structural.js.map +1 -0
  439. package/dist/sensors/stub-catalog.d.ts +39 -0
  440. package/dist/sensors/stub-catalog.js +115 -0
  441. package/dist/sensors/stub-catalog.js.map +1 -0
  442. package/dist/sensors/types.d.ts +135 -0
  443. package/dist/sensors/types.js +14 -0
  444. package/dist/sensors/types.js.map +1 -0
  445. package/dist/tier0/classify.d.ts +5 -0
  446. package/dist/tier0/classify.js +91 -0
  447. package/dist/tier0/classify.js.map +1 -0
  448. package/dist/tier0/index.d.ts +3 -0
  449. package/dist/tier0/index.js +3 -0
  450. package/dist/tier0/index.js.map +1 -0
  451. package/dist/tier0/ollama.d.ts +22 -0
  452. package/dist/tier0/ollama.js +63 -0
  453. package/dist/tier0/ollama.js.map +1 -0
  454. package/dist/tier0/types.d.ts +24 -0
  455. package/dist/tier0/types.js +7 -0
  456. package/dist/tier0/types.js.map +1 -0
  457. package/dist/tightener/index.d.ts +4 -0
  458. package/dist/tightener/index.js +4 -0
  459. package/dist/tightener/index.js.map +1 -0
  460. package/dist/tightener/prompt.d.ts +3 -0
  461. package/dist/tightener/prompt.js +67 -0
  462. package/dist/tightener/prompt.js.map +1 -0
  463. package/dist/tightener/schema.d.ts +68 -0
  464. package/dist/tightener/schema.js +44 -0
  465. package/dist/tightener/schema.js.map +1 -0
  466. package/dist/tightener/tighten.d.ts +2 -0
  467. package/dist/tightener/tighten.js +66 -0
  468. package/dist/tightener/tighten.js.map +1 -0
  469. package/dist/tightener/types.d.ts +74 -0
  470. package/dist/tightener/types.js +6 -0
  471. package/dist/tightener/types.js.map +1 -0
  472. package/dist/uat/bundle.d.ts +68 -0
  473. package/dist/uat/bundle.js +168 -0
  474. package/dist/uat/bundle.js.map +1 -0
  475. package/dist/uat/index.d.ts +15 -0
  476. package/dist/uat/index.js +10 -0
  477. package/dist/uat/index.js.map +1 -0
  478. package/dist/uat/persistent.d.ts +64 -0
  479. package/dist/uat/persistent.js +206 -0
  480. package/dist/uat/persistent.js.map +1 -0
  481. package/dist/uat/probes/cli.d.ts +11 -0
  482. package/dist/uat/probes/cli.js +107 -0
  483. package/dist/uat/probes/cli.js.map +1 -0
  484. package/dist/uat/probes/http.d.ts +12 -0
  485. package/dist/uat/probes/http.js +139 -0
  486. package/dist/uat/probes/http.js.map +1 -0
  487. package/dist/uat/probes/index.d.ts +21 -0
  488. package/dist/uat/probes/index.js +30 -0
  489. package/dist/uat/probes/index.js.map +1 -0
  490. package/dist/uat/probes/integration.d.ts +18 -0
  491. package/dist/uat/probes/integration.js +188 -0
  492. package/dist/uat/probes/integration.js.map +1 -0
  493. package/dist/uat/probes/sql/config.d.ts +14 -0
  494. package/dist/uat/probes/sql/config.js +57 -0
  495. package/dist/uat/probes/sql/config.js.map +1 -0
  496. package/dist/uat/probes/sql/index.d.ts +29 -0
  497. package/dist/uat/probes/sql/index.js +43 -0
  498. package/dist/uat/probes/sql/index.js.map +1 -0
  499. package/dist/uat/probes/sql/mysql.d.ts +12 -0
  500. package/dist/uat/probes/sql/mysql.js +96 -0
  501. package/dist/uat/probes/sql/mysql.js.map +1 -0
  502. package/dist/uat/probes/sql/pg.d.ts +20 -0
  503. package/dist/uat/probes/sql/pg.js +102 -0
  504. package/dist/uat/probes/sql/pg.js.map +1 -0
  505. package/dist/uat/probes/sql/sqlite.d.ts +9 -0
  506. package/dist/uat/probes/sql/sqlite.js +58 -0
  507. package/dist/uat/probes/sql/sqlite.js.map +1 -0
  508. package/dist/uat/probes/sql/types.d.ts +46 -0
  509. package/dist/uat/probes/sql/types.js +10 -0
  510. package/dist/uat/probes/sql/types.js.map +1 -0
  511. package/dist/uat/probes/sql.d.ts +9 -0
  512. package/dist/uat/probes/sql.js +119 -0
  513. package/dist/uat/probes/sql.js.map +1 -0
  514. package/dist/uat/probes/ui.d.ts +19 -0
  515. package/dist/uat/probes/ui.js +244 -0
  516. package/dist/uat/probes/ui.js.map +1 -0
  517. package/dist/uat/prompt.d.ts +10 -0
  518. package/dist/uat/prompt.js +85 -0
  519. package/dist/uat/prompt.js.map +1 -0
  520. package/dist/uat/question.d.ts +50 -0
  521. package/dist/uat/question.js +139 -0
  522. package/dist/uat/question.js.map +1 -0
  523. package/dist/uat/rejection.d.ts +58 -0
  524. package/dist/uat/rejection.js +163 -0
  525. package/dist/uat/rejection.js.map +1 -0
  526. package/dist/uat/runner.d.ts +6 -0
  527. package/dist/uat/runner.js +96 -0
  528. package/dist/uat/runner.js.map +1 -0
  529. package/dist/uat/schema.d.ts +322 -0
  530. package/dist/uat/schema.js +189 -0
  531. package/dist/uat/schema.js.map +1 -0
  532. package/dist/uat/types.d.ts +268 -0
  533. package/dist/uat/types.js +18 -0
  534. package/dist/uat/types.js.map +1 -0
  535. package/dist/uat/uat.d.ts +89 -0
  536. package/dist/uat/uat.js +256 -0
  537. package/dist/uat/uat.js.map +1 -0
  538. package/dist/voice/index.d.ts +4 -0
  539. package/dist/voice/index.js +4 -0
  540. package/dist/voice/index.js.map +1 -0
  541. package/dist/voice/model.d.ts +23 -0
  542. package/dist/voice/model.js +46 -0
  543. package/dist/voice/model.js.map +1 -0
  544. package/dist/voice/pipe.d.ts +9 -0
  545. package/dist/voice/pipe.js +47 -0
  546. package/dist/voice/pipe.js.map +1 -0
  547. package/dist/voice/transcribe.d.ts +3 -0
  548. package/dist/voice/transcribe.js +43 -0
  549. package/dist/voice/transcribe.js.map +1 -0
  550. package/dist/voice/types.d.ts +26 -0
  551. package/dist/voice/types.js +9 -0
  552. package/dist/voice/types.js.map +1 -0
  553. package/dist/watch/daemon.d.ts +21 -0
  554. package/dist/watch/daemon.js +143 -0
  555. package/dist/watch/daemon.js.map +1 -0
  556. package/dist/watch/index.d.ts +4 -0
  557. package/dist/watch/index.js +3 -0
  558. package/dist/watch/index.js.map +1 -0
  559. package/dist/watch/regenerate.d.ts +25 -0
  560. package/dist/watch/regenerate.js +51 -0
  561. package/dist/watch/regenerate.js.map +1 -0
  562. package/package.json +75 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Question agent (Phase 11.y).
3
+ *
4
+ * Read-only Q&A agent that the operator invokes via the ❓ Ask path
5
+ * during UAT approval. Reads the bundle's tightened spec, diff paths,
6
+ * UAT summary (acceptance results + evidence pointers), reviewer
7
+ * verdict + summary, and decisions in scope. Returns one structured
8
+ * answer per question.
9
+ *
10
+ * Per UAT_PIPELINE.md §7. Tier 1 (Haiku) default — cheap, no file
11
+ * write tools.
12
+ */
13
+ import type { ClaudeTier } from "../claude/index.js";
14
+ import type { UatSummary } from "./types.js";
15
+ export interface QuestionAgentInput {
16
+ question: string;
17
+ /** Tightened spec body the implementer received. */
18
+ tightened_spec: string;
19
+ /** Acceptance criteria the implementer was given. */
20
+ acceptance_criteria: string[];
21
+ /** Files changed in the run (paths + status only — content is omitted to
22
+ * keep the question agent cheap). */
23
+ changed_files: {
24
+ path: string;
25
+ status: string;
26
+ }[];
27
+ /** UAT summary (probe results + evidence pointers + sensors passed). */
28
+ summary: UatSummary;
29
+ /** Reviewer verdict + summary text. */
30
+ reviewer?: {
31
+ verdict: "pass" | "fail";
32
+ summary: string;
33
+ };
34
+ /** In-scope decision ids — the agent may cite by id. */
35
+ decision_ids?: string[];
36
+ /** Tier — Haiku default, Sonnet via override for thorny questions. */
37
+ tier?: ClaudeTier;
38
+ /** Per-call timeout. Default 120_000 ms. */
39
+ timeout_ms?: number;
40
+ }
41
+ export interface QuestionAgentOutput {
42
+ answer: string;
43
+ /** Self-reported confidence in the answer. */
44
+ confidence_signal: "high" | "medium" | "low";
45
+ /** Citations pointing back to the bundle (e.g. "summary.yaml#AC2",
46
+ * "diff:src/foo.ts", "decision:DEC-0042"). */
47
+ citations: string[];
48
+ }
49
+ export declare const QUESTION_AGENT_SYSTEM_PROMPT: string;
50
+ export declare function runQuestionAgent(input: QuestionAgentInput): Promise<QuestionAgentOutput>;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Question agent (Phase 11.y).
3
+ *
4
+ * Read-only Q&A agent that the operator invokes via the ❓ Ask path
5
+ * during UAT approval. Reads the bundle's tightened spec, diff paths,
6
+ * UAT summary (acceptance results + evidence pointers), reviewer
7
+ * verdict + summary, and decisions in scope. Returns one structured
8
+ * answer per question.
9
+ *
10
+ * Per UAT_PIPELINE.md §7. Tier 1 (Haiku) default — cheap, no file
11
+ * write tools.
12
+ */
13
+ import { runClaude } from "../claude/index.js";
14
+ import { logger } from "../logger.js";
15
+ const log = logger("uat.question");
16
+ const QUESTION_AGENT_SCHEMA = {
17
+ type: "object",
18
+ additionalProperties: false,
19
+ properties: {
20
+ answer: { type: "string" },
21
+ confidence_signal: { enum: ["high", "medium", "low"] },
22
+ citations: { type: "array", items: { type: "string" } },
23
+ },
24
+ required: ["answer", "confidence_signal", "citations"],
25
+ };
26
+ export const QUESTION_AGENT_SYSTEM_PROMPT = [
27
+ "You are the UAT QUESTION agent in a developer harness.",
28
+ "",
29
+ "The operator has just inspected a UAT bundle and asked you a question. Your job is to answer it from the bundle alone — you have no file-write tools, no shell, no ability to re-run sensors. You read the tightened spec, the changed-file paths, the UAT acceptance results, and the reviewer's verdict, and you produce ONE concise answer.",
30
+ "",
31
+ "Rules:",
32
+ " - Answer the question directly. No preamble. No 'Great question!'.",
33
+ " - If the bundle does not contain the information needed, say so explicitly. Don't invent context.",
34
+ " - When you reference something, cite it: `summary.yaml#AC2`, `diff:src/foo.ts`, `decision:DEC-0042`.",
35
+ " - `confidence_signal`:",
36
+ " - `high` — the answer is supported by an explicit acceptance result, sensor pass, or quoted file path.",
37
+ " - `medium` — the answer is reasonable inference from the bundle but not directly stated.",
38
+ " - `low` — the bundle is sparse or your answer is best-guess; tell the operator they need to inspect manually.",
39
+ " - Keep `answer` to 1-3 short paragraphs. The operator is on their phone.",
40
+ "",
41
+ "Return ONLY the JSON object. No markdown wrapper.",
42
+ ].join("\n");
43
+ function isOutput(value) {
44
+ if (typeof value !== "object" || value === null)
45
+ return false;
46
+ const v = value;
47
+ if (typeof v["answer"] !== "string")
48
+ return false;
49
+ if (v["confidence_signal"] !== "high" &&
50
+ v["confidence_signal"] !== "medium" &&
51
+ v["confidence_signal"] !== "low") {
52
+ return false;
53
+ }
54
+ if (!Array.isArray(v["citations"]))
55
+ return false;
56
+ return true;
57
+ }
58
+ function buildUserPrompt(input) {
59
+ const parts = [];
60
+ parts.push("# Operator's question");
61
+ parts.push("");
62
+ parts.push(input.question.trim());
63
+ parts.push("");
64
+ parts.push("# Tightened spec");
65
+ parts.push("");
66
+ parts.push(input.tightened_spec.trim());
67
+ if (input.acceptance_criteria.length > 0) {
68
+ parts.push("");
69
+ parts.push("# Acceptance criteria");
70
+ parts.push("");
71
+ for (const a of input.acceptance_criteria)
72
+ parts.push(`- ${a}`);
73
+ }
74
+ if (input.changed_files.length > 0) {
75
+ parts.push("");
76
+ parts.push("# Files changed (paths only)");
77
+ parts.push("");
78
+ for (const f of input.changed_files)
79
+ parts.push(`- ${f.path} (${f.status})`);
80
+ }
81
+ parts.push("");
82
+ parts.push("# UAT summary");
83
+ parts.push("");
84
+ parts.push(`Goal: ${input.summary.goal_one_liner}`);
85
+ parts.push(`Diff stats: ${input.summary.diff_stats.files_changed} files, +${input.summary.diff_stats.lines_added} / -${input.summary.diff_stats.lines_removed}`);
86
+ parts.push("");
87
+ parts.push("Acceptance results:");
88
+ for (const r of input.summary.acceptance_results) {
89
+ const reason = r.failure_reason ? ` — ${r.failure_reason}` : "";
90
+ parts.push(`- ${r.id} (${r.probe_kind}): ${r.status}${reason}`);
91
+ }
92
+ if (input.summary.cold_start_smoke) {
93
+ parts.push("");
94
+ parts.push(`Cold-start smoke: ${input.summary.cold_start_smoke.status}`);
95
+ }
96
+ parts.push("");
97
+ parts.push(`Sensors passed: ${input.summary.sensors_passed.join(", ") || "(none)"}`);
98
+ parts.push(`Reviewer subagent verdict: ${input.summary.reviewer_subagent_verdict}`);
99
+ if (input.reviewer && input.reviewer.summary) {
100
+ parts.push("");
101
+ parts.push(`Reviewer summary: ${input.reviewer.summary}`);
102
+ }
103
+ if (input.decision_ids && input.decision_ids.length > 0) {
104
+ parts.push("");
105
+ parts.push(`Decisions in scope: ${input.decision_ids.join(", ")}`);
106
+ }
107
+ parts.push("");
108
+ parts.push("---");
109
+ parts.push("");
110
+ parts.push("Now answer the operator's question. Return ONLY the JSON object.");
111
+ return parts.join("\n");
112
+ }
113
+ export async function runQuestionAgent(input) {
114
+ const tier = input.tier ?? "haiku";
115
+ log.info({
116
+ tier,
117
+ question_chars: input.question.length,
118
+ ac_count: input.acceptance_criteria.length,
119
+ diff_files: input.changed_files.length,
120
+ }, "question agent dispatch");
121
+ const result = await runClaude({
122
+ tier,
123
+ prompt: buildUserPrompt(input),
124
+ system: QUESTION_AGENT_SYSTEM_PROMPT,
125
+ jsonSchema: QUESTION_AGENT_SCHEMA,
126
+ timeoutMs: input.timeout_ms ?? 120_000,
127
+ });
128
+ if (!isOutput(result.parsed)) {
129
+ throw new Error(`question agent returned malformed output. preview: ${result.text.slice(0, 200)}`);
130
+ }
131
+ log.info({
132
+ answer_chars: result.parsed.answer.length,
133
+ confidence: result.parsed.confidence_signal,
134
+ citations: result.parsed.citations.length,
135
+ duration_ms: result.durationMs,
136
+ }, "question agent complete");
137
+ return result.parsed;
138
+ }
139
+ //# sourceMappingURL=question.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"question.js","sourceRoot":"","sources":["../../src/uat/question.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * UAT rejection capture + retry remediation.
3
+ *
4
+ * Per UAT_PIPELINE.md §6:
5
+ * 1. Adapter posts: "🔴 Rejected. What's wrong? A/B/C/D".
6
+ * 2. Operator picks category + supplies free text or voice URL.
7
+ * 3. If voice URL: Whisper transcribes via existing voice/transcribeUrl.
8
+ * 4. Result is a structured `UatRejection`.
9
+ * 5. Orchestrator writes `rejection.yaml` under the run's UAT dir.
10
+ * 6. Implementer is re-spawned on the next attempt with the rejection
11
+ * formatted as remediation context.
12
+ */
13
+ import type { FrontendAdapter } from "../frontend/types.js";
14
+ import type { UatRejection, UatSummary } from "./types.js";
15
+ /** Detect an http(s) audio URL anywhere in `text`. */
16
+ export declare function extractAudioUrl(text: string | undefined): string | undefined;
17
+ export interface CaptureUatRejectionArgs {
18
+ adapter: FrontendAdapter;
19
+ runId: string;
20
+ taskId: string;
21
+ /** Optional initial reason from `adapter.requestApproval`'s reject response. */
22
+ initialReason?: string;
23
+ /** Channel id to thread the dialog into when supported by the adapter. */
24
+ channelId?: string;
25
+ /**
26
+ * Override the dialog timeout. Default 24h per UAT_PIPELINE §9 timeouts.
27
+ * Tests / smokes pass a short value so the stub adapter resolves quickly.
28
+ */
29
+ timeoutMs?: number;
30
+ }
31
+ /**
32
+ * Run the post-reject A/B/C/D dialog, optionally transcribe a voice URL,
33
+ * and return the structured `UatRejection`. Voice transcription is
34
+ * best-effort: if Whisper isn't available, the URL is preserved in the
35
+ * operator_note but voice_transcript stays unset.
36
+ */
37
+ export declare function captureUatRejection(args: CaptureUatRejectionArgs): Promise<UatRejection>;
38
+ export interface WriteRejectionYamlArgs {
39
+ repoRoot: string;
40
+ runId: string;
41
+ rejection: UatRejection;
42
+ summary: UatSummary;
43
+ }
44
+ /** Write `rejection.yaml` under the run's UAT directory. */
45
+ export declare function writeRejectionYaml(args: WriteRejectionYamlArgs): Promise<string>;
46
+ export interface UatRejectionRemediationArgs {
47
+ rejection: UatRejection;
48
+ summary: UatSummary;
49
+ attempt: number;
50
+ maxAttempts: number;
51
+ }
52
+ /**
53
+ * Format the operator's rejection as agent-prompt-shaped retry context.
54
+ * Tone matches Phase 9 + 10 remediation: lead with what failed, then the
55
+ * concrete actions the implementer should take, framed by the rejection
56
+ * category.
57
+ */
58
+ export declare function formatUatRejectionRemediation(args: UatRejectionRemediationArgs): string;
@@ -0,0 +1,163 @@
1
+ /**
2
+ * UAT rejection capture + retry remediation.
3
+ *
4
+ * Per UAT_PIPELINE.md §6:
5
+ * 1. Adapter posts: "🔴 Rejected. What's wrong? A/B/C/D".
6
+ * 2. Operator picks category + supplies free text or voice URL.
7
+ * 3. If voice URL: Whisper transcribes via existing voice/transcribeUrl.
8
+ * 4. Result is a structured `UatRejection`.
9
+ * 5. Orchestrator writes `rejection.yaml` under the run's UAT dir.
10
+ * 6. Implementer is re-spawned on the next attempt with the rejection
11
+ * formatted as remediation context.
12
+ */
13
+ import { mkdir, writeFile } from "node:fs/promises";
14
+ import { join } from "node:path";
15
+ import { stringify as stringifyYaml } from "yaml";
16
+ import { logger } from "../logger.js";
17
+ import { transcribeUrl } from "../voice/transcribe.js";
18
+ import { uatDirFor } from "./bundle.js";
19
+ const log = logger("uat.rejection");
20
+ const REJECTION_DIALOG_TIMEOUT_MS = 86_400_000; // 24h per UAT_PIPELINE §9
21
+ const CATEGORY_LABEL = {
22
+ A: "Feature missing entirely",
23
+ B: "UI / copy issue (specify in screenshot)",
24
+ C: "Wrong behavior (describe in voice/text)",
25
+ D: "Other",
26
+ };
27
+ function isCategoryChoice(s) {
28
+ return s === "A" || s === "B" || s === "C" || s === "D";
29
+ }
30
+ /** Detect an http(s) audio URL anywhere in `text`. */
31
+ export function extractAudioUrl(text) {
32
+ if (!text)
33
+ return undefined;
34
+ const m = text.match(/(https?:\/\/\S+\.(?:mp3|ogg|wav|m4a|webm|aac|flac))/i);
35
+ return m?.[1];
36
+ }
37
+ /**
38
+ * Run the post-reject A/B/C/D dialog, optionally transcribe a voice URL,
39
+ * and return the structured `UatRejection`. Voice transcription is
40
+ * best-effort: if Whisper isn't available, the URL is preserved in the
41
+ * operator_note but voice_transcript stays unset.
42
+ */
43
+ export async function captureUatRejection(args) {
44
+ const dialog = await args.adapter.requestDialog({
45
+ bundleId: `uat-reject-${args.runId}`,
46
+ prompt: [
47
+ "🔴 Rejected. What's wrong?",
48
+ "(Reply with a voice-note URL ending in .mp3 / .m4a / .ogg / .wav / .webm to attach voice context — Whisper will transcribe it.)",
49
+ ].join("\n"),
50
+ choices: [
51
+ { id: "A", label: CATEGORY_LABEL.A },
52
+ { id: "B", label: CATEGORY_LABEL.B },
53
+ { id: "C", label: CATEGORY_LABEL.C },
54
+ { id: "D", label: CATEGORY_LABEL.D },
55
+ ],
56
+ ...(args.channelId !== undefined ? { channelId: args.channelId } : {}),
57
+ timeoutMs: args.timeoutMs ?? REJECTION_DIALOG_TIMEOUT_MS,
58
+ });
59
+ const choice = isCategoryChoice(dialog.choiceId) ? dialog.choiceId : "D";
60
+ const freeText = dialog.freeText ?? "";
61
+ const initial = args.initialReason ?? "";
62
+ const note = [initial, freeText].filter((s) => s.trim().length > 0).join("\n");
63
+ // Voice URL detection — search both the dialog free text and the initial
64
+ // reject reason. Operator might paste it in either place.
65
+ const voiceUrl = extractAudioUrl(freeText) ?? extractAudioUrl(initial);
66
+ let voiceTranscript;
67
+ if (voiceUrl) {
68
+ try {
69
+ const result = await transcribeUrl(voiceUrl);
70
+ voiceTranscript = result.text.trim();
71
+ log.info({ run_id: args.runId, voice_url: voiceUrl, chars: voiceTranscript.length }, "voice transcribed");
72
+ }
73
+ catch (err) {
74
+ log.warn({ err: String(err), url: voiceUrl, run_id: args.runId }, "voice transcription failed; preserving URL in operator_note");
75
+ }
76
+ }
77
+ return {
78
+ category: choice,
79
+ operator_note: note,
80
+ ...(voiceTranscript !== undefined ? { voice_transcript: voiceTranscript } : {}),
81
+ rejected_at: new Date().toISOString(),
82
+ };
83
+ }
84
+ /** Write `rejection.yaml` under the run's UAT directory. */
85
+ export async function writeRejectionYaml(args) {
86
+ const dir = uatDirFor(args.repoRoot, args.runId);
87
+ await mkdir(dir, { recursive: true });
88
+ const path = join(dir, "rejection.yaml");
89
+ const failedAcs = args.summary.acceptance_results
90
+ .filter((r) => r.status === "fail")
91
+ .map((r) => ({ id: r.id, text: r.text, reason: r.failure_reason ?? null }));
92
+ const body = {
93
+ run_id: args.runId,
94
+ task_id: args.summary.task_id,
95
+ rejected_at: args.rejection.rejected_at,
96
+ category: args.rejection.category,
97
+ category_label: CATEGORY_LABEL[args.rejection.category],
98
+ operator_note: args.rejection.operator_note,
99
+ voice_transcript: args.rejection.voice_transcript ?? null,
100
+ referenced_screenshots: args.rejection.referenced_screenshots ?? [],
101
+ failed_acceptance_criteria: failedAcs,
102
+ };
103
+ await writeFile(path, stringifyYaml(body), "utf8");
104
+ log.info({ run_id: args.runId, path, category: args.rejection.category }, "rejection.yaml written");
105
+ return path;
106
+ }
107
+ /**
108
+ * Format the operator's rejection as agent-prompt-shaped retry context.
109
+ * Tone matches Phase 9 + 10 remediation: lead with what failed, then the
110
+ * concrete actions the implementer should take, framed by the rejection
111
+ * category.
112
+ */
113
+ export function formatUatRejectionRemediation(args) {
114
+ const lines = [];
115
+ lines.push("## Operator rejected the UAT bundle");
116
+ lines.push("");
117
+ lines.push(`On attempt ${args.attempt - 1} the operator rejected the run via UAT. This is retry attempt ${args.attempt} of ${args.maxAttempts}.`);
118
+ lines.push("");
119
+ lines.push(`**Category:** ${args.rejection.category} — ${CATEGORY_LABEL[args.rejection.category]}`);
120
+ if (args.rejection.operator_note.trim().length > 0) {
121
+ lines.push("");
122
+ lines.push("**Operator note:**");
123
+ lines.push("");
124
+ lines.push(args.rejection.operator_note.trim());
125
+ }
126
+ if (args.rejection.voice_transcript) {
127
+ lines.push("");
128
+ lines.push("**Voice transcript:**");
129
+ lines.push("");
130
+ lines.push(args.rejection.voice_transcript);
131
+ }
132
+ const fails = args.summary.acceptance_results.filter((r) => r.status === "fail");
133
+ if (fails.length > 0) {
134
+ lines.push("");
135
+ lines.push("**Acceptance criteria that did not pass in the prior UAT:**");
136
+ lines.push("");
137
+ for (const f of fails) {
138
+ const reason = f.failure_reason ? ` — ${f.failure_reason}` : "";
139
+ lines.push(`- ${f.id} (${f.probe_kind}): ${f.text}${reason}`);
140
+ }
141
+ }
142
+ lines.push("");
143
+ lines.push("## What to do");
144
+ lines.push("");
145
+ switch (args.rejection.category) {
146
+ case "A":
147
+ lines.push("Feature missing entirely. The previous attempt did not deliver the requested capability. Re-read the tightened spec, identify what's missing, and ship a complete delta — do not regenerate from scratch unless your prior diff is contradictory.");
148
+ break;
149
+ case "B":
150
+ lines.push("UI / copy issue. Locate the visual or textual problem the operator described and fix it specifically. Do NOT regenerate the whole feature; ship a tight delta to address the operator's note + any referenced screenshots.");
151
+ break;
152
+ case "C":
153
+ lines.push("Wrong behavior. The implementation runs but produces the wrong result. Diagnose why each failed acceptance criterion did not pass, fix the underlying behavior, and verify locally before re-emitting attestation. Per-AC failure reasons above are concrete; do not paper over them.");
154
+ break;
155
+ case "D":
156
+ lines.push("Other / mixed concern. Read the operator note (and any voice transcript) carefully and address what's described. If the note is itself ambiguous, emit a `blocked_by:` block instead of a partial diff.");
157
+ break;
158
+ }
159
+ lines.push("");
160
+ lines.push("Re-emit your `attestation:` YAML at end of reply with corrected `delivered`/`files_touched`/`todos_introduced`/`stubs_introduced` counts. Do NOT re-introduce any pattern flagged in `.harness/config/stub-patterns.yaml`.");
161
+ return lines.join("\n");
162
+ }
163
+ //# sourceMappingURL=rejection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rejection.js","sourceRoot":"","sources":["../../src/uat/rejection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * UAT-runner — Tier-2 (Sonnet) call that picks one probe per acceptance
3
+ * criterion. Auto-escalates to Opus on second failure (caller's policy).
4
+ */
5
+ import type { UatRunnerInput, UatRunnerOutput } from "./types.js";
6
+ export declare function generateUatChecks(input: UatRunnerInput): Promise<UatRunnerOutput>;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * UAT-runner — Tier-2 (Sonnet) call that picks one probe per acceptance
3
+ * criterion. Auto-escalates to Opus on second failure (caller's policy).
4
+ */
5
+ import { runClaude } from "../claude/index.js";
6
+ import { logger } from "../logger.js";
7
+ import { buildUatRunnerUserPrompt, UAT_RUNNER_SYSTEM_PROMPT } from "./prompt.js";
8
+ import { UAT_RUNNER_OUTPUT_SCHEMA } from "./schema.js";
9
+ const log = logger("uat.runner");
10
+ function isProbe(value) {
11
+ if (typeof value !== "object" || value === null)
12
+ return false;
13
+ const v = value;
14
+ return (v["kind"] === "http" ||
15
+ v["kind"] === "cli" ||
16
+ v["kind"] === "ui" ||
17
+ v["kind"] === "sql" ||
18
+ v["kind"] === "integration");
19
+ }
20
+ function isAcceptanceCheck(value) {
21
+ if (typeof value !== "object" || value === null)
22
+ return false;
23
+ const v = value;
24
+ return (typeof v["id"] === "string" &&
25
+ typeof v["text"] === "string" &&
26
+ isProbe(v["probe"]));
27
+ }
28
+ function isOutput(value) {
29
+ if (typeof value !== "object" || value === null)
30
+ return false;
31
+ const v = value;
32
+ if (!Array.isArray(v["acceptance_checks"]))
33
+ return false;
34
+ for (const c of v["acceptance_checks"]) {
35
+ if (!isAcceptanceCheck(c))
36
+ return false;
37
+ }
38
+ if (typeof v["cold_start_smoke"] !== "boolean")
39
+ return false;
40
+ if (typeof v["backend_only"] !== "boolean")
41
+ return false;
42
+ return true;
43
+ }
44
+ export async function generateUatChecks(input) {
45
+ log.info({
46
+ tier: input.tier,
47
+ ac_count: input.acceptance_criteria.length,
48
+ diff_files: input.changed_files.length,
49
+ is_high_stakes: input.is_high_stakes,
50
+ hints: input.hints,
51
+ }, "uat-runner dispatch");
52
+ const result = await runClaude({
53
+ tier: input.tier,
54
+ prompt: buildUatRunnerUserPrompt(input),
55
+ system: UAT_RUNNER_SYSTEM_PROMPT,
56
+ jsonSchema: UAT_RUNNER_OUTPUT_SCHEMA,
57
+ timeoutMs: input.timeout_ms ?? 300_000,
58
+ });
59
+ if (!isOutput(result.parsed)) {
60
+ throw new Error(`uat-runner returned malformed output. preview: ${result.text.slice(0, 200)}`);
61
+ }
62
+ // Reject probes for unavailable surfaces — defense-in-depth in case the
63
+ // model emitted them despite the prompt.
64
+ const filtered = [];
65
+ for (const check of result.parsed.acceptance_checks) {
66
+ if (check.probe.kind === "ui" && input.hints.ui_available !== true) {
67
+ log.warn({ check_id: check.id }, "dropping ui probe — surface not available");
68
+ continue;
69
+ }
70
+ if (check.probe.kind === "sql" && input.hints.sql_available !== true) {
71
+ log.warn({ check_id: check.id }, "dropping sql probe — surface not available");
72
+ continue;
73
+ }
74
+ if (check.probe.kind === "integration" && input.hints.integration_available !== true) {
75
+ log.warn({ check_id: check.id }, "dropping integration probe — surface not available");
76
+ continue;
77
+ }
78
+ filtered.push(check);
79
+ }
80
+ log.info({
81
+ checks_emitted: result.parsed.acceptance_checks.length,
82
+ checks_after_filter: filtered.length,
83
+ cold_start_smoke: result.parsed.cold_start_smoke,
84
+ backend_only: result.parsed.backend_only,
85
+ ungenerable_reason: result.parsed.ungenerable_reason,
86
+ }, "uat-runner complete");
87
+ return {
88
+ acceptance_checks: filtered,
89
+ cold_start_smoke: result.parsed.cold_start_smoke,
90
+ backend_only: result.parsed.backend_only,
91
+ ...(result.parsed.ungenerable_reason !== undefined
92
+ ? { ungenerable_reason: result.parsed.ungenerable_reason }
93
+ : {}),
94
+ };
95
+ }
96
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/uat/runner.ts"],"names":[],"mappings":"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"}