harnery 0.38.0 → 0.40.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 (378) hide show
  1. package/dist/commands/agents.d.ts.map +1 -1
  2. package/dist/commands/agents.js +32 -8
  3. package/dist/commands/artifacts.d.ts.map +1 -1
  4. package/dist/commands/artifacts.js +97 -6
  5. package/dist/commands/backup.d.ts +16 -0
  6. package/dist/commands/backup.d.ts.map +1 -1
  7. package/dist/commands/backup.js +239 -33
  8. package/dist/commands/browse.d.ts +8 -0
  9. package/dist/commands/browse.d.ts.map +1 -1
  10. package/dist/commands/browse.js +466 -231
  11. package/dist/commands/diagnostics.d.ts.map +1 -1
  12. package/dist/commands/diagnostics.js +6 -3
  13. package/dist/commands/ledger-v3.d.ts.map +1 -1
  14. package/dist/commands/ledger-v3.js +20 -4
  15. package/dist/commands/qa-run.d.ts.map +1 -1
  16. package/dist/commands/qa-run.js +26 -3
  17. package/dist/commands/qa-status.d.ts.map +1 -1
  18. package/dist/commands/qa-status.js +7 -2
  19. package/dist/commands/resources.d.ts.map +1 -1
  20. package/dist/commands/resources.js +23 -3
  21. package/dist/commands/review-pack.d.ts.map +1 -1
  22. package/dist/commands/review-pack.js +98 -23
  23. package/dist/commands/tunnel.d.ts.map +1 -1
  24. package/dist/commands/tunnel.js +2 -2
  25. package/dist/core/adapters/profiles.d.ts +1 -1
  26. package/dist/core/agents/canonical-emit.d.ts +3 -2
  27. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  28. package/dist/core/agents/canonical-emit.js +2 -0
  29. package/dist/core/agents/cli.js +13 -6
  30. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  31. package/dist/core/agents/live-authority-v3.js +5 -3
  32. package/dist/core/agents/live-lifecycle-v3.d.ts +2 -2
  33. package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
  34. package/dist/core/agents/render/prompt-context.d.ts +7 -5
  35. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  36. package/dist/core/agents/render/prompt-context.js +63 -8
  37. package/dist/core/agents/session-finalizer-v3.d.ts +2 -2
  38. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  39. package/dist/core/agents/state/live-coordination-view.d.ts +3 -3
  40. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  41. package/dist/core/agents/state/live-coordination-view.js +2 -1
  42. package/dist/core/agents/state/names.d.ts +35 -2
  43. package/dist/core/agents/state/names.d.ts.map +1 -1
  44. package/dist/core/agents/state/names.js +80 -5
  45. package/dist/core/agents/state/stale-sweep.d.ts +2 -1
  46. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  47. package/dist/core/agents/state/stale-sweep.js +23 -6
  48. package/dist/core/agents/turn-elapsed.d.ts +51 -0
  49. package/dist/core/agents/turn-elapsed.d.ts.map +1 -0
  50. package/dist/core/agents/turn-elapsed.js +91 -0
  51. package/dist/core/artifacts/activity.d.ts +14 -0
  52. package/dist/core/artifacts/activity.d.ts.map +1 -0
  53. package/dist/core/artifacts/activity.js +52 -0
  54. package/dist/core/artifacts/delivery-card.d.ts +39 -0
  55. package/dist/core/artifacts/delivery-card.d.ts.map +1 -0
  56. package/dist/core/artifacts/delivery-card.js +282 -0
  57. package/dist/core/artifacts/index.d.ts +42 -7
  58. package/dist/core/artifacts/index.d.ts.map +1 -1
  59. package/dist/core/artifacts/index.js +288 -76
  60. package/dist/core/artifacts/mutation-lock.d.ts +2 -0
  61. package/dist/core/artifacts/mutation-lock.d.ts.map +1 -0
  62. package/dist/core/artifacts/mutation-lock.js +91 -0
  63. package/dist/core/backup/host-snapshot.d.ts +18 -0
  64. package/dist/core/backup/host-snapshot.d.ts.map +1 -0
  65. package/dist/core/backup/host-snapshot.js +64 -0
  66. package/dist/core/config.d.ts +20 -5
  67. package/dist/core/config.d.ts.map +1 -1
  68. package/dist/core/config.js +44 -10
  69. package/dist/core/diagnostics/advice.d.ts +38 -3
  70. package/dist/core/diagnostics/advice.d.ts.map +1 -1
  71. package/dist/core/diagnostics/advice.js +103 -99
  72. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  73. package/dist/core/diagnostics/bundle.js +111 -47
  74. package/dist/core/diagnostics/comparison.d.ts.map +1 -1
  75. package/dist/core/diagnostics/comparison.js +3 -2
  76. package/dist/core/diagnostics/contract.d.ts +15 -31
  77. package/dist/core/diagnostics/contract.d.ts.map +1 -1
  78. package/dist/core/diagnostics/contract.js +2 -5
  79. package/dist/core/diagnostics/index.d.ts +2 -0
  80. package/dist/core/diagnostics/index.d.ts.map +1 -1
  81. package/dist/core/diagnostics/index.js +2 -0
  82. package/dist/core/diagnostics/pressure-contract.d.ts +260 -0
  83. package/dist/core/diagnostics/pressure-contract.d.ts.map +1 -0
  84. package/dist/core/diagnostics/pressure-contract.js +70 -0
  85. package/dist/core/diagnostics/pressure.d.ts +25 -0
  86. package/dist/core/diagnostics/pressure.d.ts.map +1 -0
  87. package/dist/core/diagnostics/pressure.js +1138 -0
  88. package/dist/core/diagnostics/replay.d.ts.map +1 -1
  89. package/dist/core/diagnostics/replay.js +90 -10
  90. package/dist/core/events/v3/adapter-id.d.ts +6 -0
  91. package/dist/core/events/v3/adapter-id.d.ts.map +1 -0
  92. package/dist/core/events/v3/adapter-id.js +7 -0
  93. package/dist/core/events/v3/archive-retention.d.ts.map +1 -1
  94. package/dist/core/events/v3/archive-retention.js +3 -2
  95. package/dist/core/events/v3/bootstrap.d.ts +41 -4
  96. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  97. package/dist/core/events/v3/bootstrap.js +120 -17
  98. package/dist/core/events/v3/capabilities.d.ts +16 -9
  99. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  100. package/dist/core/events/v3/capabilities.js +37 -2
  101. package/dist/core/events/v3/capability-drift.d.ts +2 -2
  102. package/dist/core/events/v3/capability-drift.d.ts.map +1 -1
  103. package/dist/core/events/v3/control-witness.d.ts +48 -5
  104. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  105. package/dist/core/events/v3/control-witness.js +91 -36
  106. package/dist/core/events/v3/control.d.ts.map +1 -1
  107. package/dist/core/events/v3/control.js +22 -2
  108. package/dist/core/events/v3/index.d.ts +2 -1
  109. package/dist/core/events/v3/index.d.ts.map +1 -1
  110. package/dist/core/events/v3/index.js +2 -1
  111. package/dist/core/events/v3/live-feed.d.ts +7 -1
  112. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  113. package/dist/core/events/v3/live-feed.js +21 -3
  114. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  115. package/dist/core/events/v3/live-routing.js +10 -2
  116. package/dist/core/events/v3/producers/command-recorder.d.ts +2 -2
  117. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  118. package/dist/core/events/v3/producers/command-recorder.js +2 -1
  119. package/dist/core/events/v3/producers/coordination-recorder.d.ts +2 -2
  120. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  121. package/dist/core/events/v3/producers/coordination-recorder.js +2 -1
  122. package/dist/core/events/v3/producers/hook-base.d.ts +2 -2
  123. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  124. package/dist/core/events/v3/producers/hook-base.js +15 -5
  125. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  126. package/dist/core/events/v3/producers/hook.js +17 -4
  127. package/dist/core/events/v3/producers/intake.d.ts +4 -4
  128. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  129. package/dist/core/events/v3/producers/intake.js +3 -2
  130. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -1
  131. package/dist/core/events/v3/producers/producer-state-observer.js +2 -1
  132. package/dist/core/events/v3/producers/recorder.d.ts +16 -5
  133. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  134. package/dist/core/events/v3/producers/recorder.js +31 -9
  135. package/dist/core/events/v3/reader.d.ts.map +1 -1
  136. package/dist/core/events/v3/reader.js +10 -13
  137. package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
  138. package/dist/core/events/v3/runtime-build.js +3 -2
  139. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +2 -2
  140. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -1
  141. package/dist/core/events/v3/turn-telemetry.d.ts +2 -2
  142. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  143. package/dist/core/hooks/adapter/output.d.ts +16 -14
  144. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  145. package/dist/core/hooks/adapter/output.js +36 -38
  146. package/dist/core/hooks/backup-schedule.d.ts +34 -0
  147. package/dist/core/hooks/backup-schedule.d.ts.map +1 -0
  148. package/dist/core/hooks/backup-schedule.js +114 -0
  149. package/dist/core/hooks/cli.js +61 -18
  150. package/dist/core/hooks/codex-wsl-bridge.d.ts +2 -0
  151. package/dist/core/hooks/codex-wsl-bridge.d.ts.map +1 -1
  152. package/dist/core/hooks/codex-wsl-bridge.js +18 -4
  153. package/dist/core/hooks/index.d.ts +1 -0
  154. package/dist/core/hooks/index.d.ts.map +1 -1
  155. package/dist/core/hooks/index.js +1 -0
  156. package/dist/core/hooks/prompt-context/contract.d.ts +61 -0
  157. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -0
  158. package/dist/core/hooks/prompt-context/contract.js +102 -0
  159. package/dist/core/hooks/prompt-context/index.d.ts +5 -0
  160. package/dist/core/hooks/prompt-context/index.d.ts.map +1 -0
  161. package/dist/core/hooks/prompt-context/index.js +2 -0
  162. package/dist/core/hooks/prompt-context/runner.d.ts +24 -0
  163. package/dist/core/hooks/prompt-context/runner.d.ts.map +1 -0
  164. package/dist/core/hooks/prompt-context/runner.js +249 -0
  165. package/dist/core/qa-artifacts.d.ts +3 -0
  166. package/dist/core/qa-artifacts.d.ts.map +1 -1
  167. package/dist/core/qa-artifacts.js +25 -3
  168. package/dist/core/resources/contract.d.ts +69 -3
  169. package/dist/core/resources/contract.d.ts.map +1 -1
  170. package/dist/core/resources/contract.js +1 -1
  171. package/dist/core/resources/index.d.ts +1 -0
  172. package/dist/core/resources/index.d.ts.map +1 -1
  173. package/dist/core/resources/index.js +1 -0
  174. package/dist/core/resources/native.d.ts +36 -0
  175. package/dist/core/resources/native.d.ts.map +1 -0
  176. package/dist/core/resources/native.js +418 -0
  177. package/dist/core/resources/sampler.d.ts +2 -0
  178. package/dist/core/resources/sampler.d.ts.map +1 -1
  179. package/dist/core/resources/sampler.js +31 -1
  180. package/dist/core/resources/status.d.ts +61 -0
  181. package/dist/core/resources/status.d.ts.map +1 -0
  182. package/dist/core/resources/status.js +536 -0
  183. package/dist/core/resources/system.d.ts +27 -0
  184. package/dist/core/resources/system.d.ts.map +1 -0
  185. package/dist/core/resources/system.js +439 -0
  186. package/dist/core/semantic/contract.d.ts +13 -13
  187. package/dist/core/semantic/service.d.ts +2 -0
  188. package/dist/core/semantic/service.d.ts.map +1 -1
  189. package/dist/core/semantic/service.js +27 -4
  190. package/dist/core/storage/builtins.js +41 -0
  191. package/dist/core/supervisor/contract.d.ts +41 -3
  192. package/dist/core/supervisor/contract.d.ts.map +1 -1
  193. package/dist/core/supervisor/contract.js +3 -2
  194. package/dist/core/supervisor/findings.d.ts +3 -0
  195. package/dist/core/supervisor/findings.d.ts.map +1 -1
  196. package/dist/core/supervisor/findings.js +88 -0
  197. package/dist/core/supervisor/history.d.ts.map +1 -1
  198. package/dist/core/supervisor/history.js +14 -0
  199. package/dist/core/supervisor/ledger-state.d.ts +55 -0
  200. package/dist/core/supervisor/ledger-state.d.ts.map +1 -0
  201. package/dist/core/supervisor/ledger-state.js +0 -0
  202. package/dist/core/supervisor/service.d.ts.map +1 -1
  203. package/dist/core/supervisor/service.js +120 -7
  204. package/dist/core/supervisor/storage.d.ts +3 -1
  205. package/dist/core/supervisor/storage.d.ts.map +1 -1
  206. package/dist/core/supervisor/storage.js +4 -0
  207. package/dist/core/workflow/admission.d.ts +3 -0
  208. package/dist/core/workflow/admission.d.ts.map +1 -1
  209. package/dist/core/workflow/admission.js +28 -16
  210. package/dist/core/workflow/engine.js +2 -2
  211. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  212. package/dist/core/workflow/live-session-v3.js +6 -1
  213. package/dist/core/workflow/proof.d.ts.map +1 -1
  214. package/dist/core/workflow/proof.js +4 -3
  215. package/dist/lib/browser/capture-fidelity.d.ts +7 -0
  216. package/dist/lib/browser/capture-fidelity.d.ts.map +1 -1
  217. package/dist/lib/browser/capture-fidelity.js +17 -0
  218. package/dist/lib/browser/client.d.ts +9 -0
  219. package/dist/lib/browser/client.d.ts.map +1 -1
  220. package/dist/lib/browser/client.js +85 -37
  221. package/dist/lib/browser/index.d.ts +3 -1
  222. package/dist/lib/browser/index.d.ts.map +1 -1
  223. package/dist/lib/browser/index.js +2 -1
  224. package/dist/lib/browser/page-review-budget.d.ts +13 -0
  225. package/dist/lib/browser/page-review-budget.d.ts.map +1 -0
  226. package/dist/lib/browser/page-review-budget.js +251 -0
  227. package/dist/lib/browser/page-review-contracts.d.ts +127 -0
  228. package/dist/lib/browser/page-review-contracts.d.ts.map +1 -0
  229. package/dist/lib/browser/page-review-contracts.js +5 -0
  230. package/dist/lib/browser/page-review-evidence.d.ts +48 -0
  231. package/dist/lib/browser/page-review-evidence.d.ts.map +1 -0
  232. package/dist/lib/browser/page-review-evidence.js +340 -0
  233. package/dist/lib/browser/page-review-judge.d.ts +1 -1
  234. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  235. package/dist/lib/browser/page-review-judge.js +46 -38
  236. package/dist/lib/browser/page-review-pack.d.ts +44 -22
  237. package/dist/lib/browser/page-review-pack.d.ts.map +1 -1
  238. package/dist/lib/browser/page-review-pack.js +116 -36
  239. package/dist/lib/browser/page-review-source.d.ts +12 -0
  240. package/dist/lib/browser/page-review-source.d.ts.map +1 -0
  241. package/dist/lib/browser/page-review-source.js +22 -0
  242. package/dist/lib/browser/qa-run-contracts.d.ts +35 -9
  243. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  244. package/dist/lib/browser/qa-run-contracts.js +48 -14
  245. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  246. package/dist/lib/browser/qa-run.js +215 -68
  247. package/dist/lib/browser/qa-snapshot.d.ts +6 -0
  248. package/dist/lib/browser/qa-snapshot.d.ts.map +1 -1
  249. package/dist/lib/browser/qa-snapshot.js +259 -48
  250. package/dist/lib/browser/review-capture-transaction.d.ts +13 -0
  251. package/dist/lib/browser/review-capture-transaction.d.ts.map +1 -0
  252. package/dist/lib/browser/review-capture-transaction.js +79 -0
  253. package/dist/lib/browser/standalone-html.d.ts.map +1 -1
  254. package/dist/lib/browser/standalone-html.js +4 -2
  255. package/dist/lib/browser/thumbnail-association.d.ts +34 -0
  256. package/dist/lib/browser/thumbnail-association.d.ts.map +1 -0
  257. package/dist/lib/browser/thumbnail-association.js +158 -0
  258. package/dist/lib/browser/tiling.d.ts +30 -0
  259. package/dist/lib/browser/tiling.d.ts.map +1 -1
  260. package/dist/lib/browser/tiling.js +38 -0
  261. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  262. package/dist/lib/docs-metadata-managed.js +4 -1
  263. package/dist/lib/identities/assume.d.ts.map +1 -1
  264. package/dist/lib/identities/assume.js +7 -1
  265. package/dist/lib/instructions/templates.d.ts.map +1 -1
  266. package/dist/lib/instructions/templates.js +1 -0
  267. package/dist/lib/local-file-url.d.ts +12 -0
  268. package/dist/lib/local-file-url.d.ts.map +1 -1
  269. package/dist/lib/local-file-url.js +16 -2
  270. package/dist/lib/tunnel/state.d.ts +19 -4
  271. package/dist/lib/tunnel/state.d.ts.map +1 -1
  272. package/dist/lib/tunnel/state.js +53 -13
  273. package/package.json +7 -4
  274. package/schemas/config.schema.json +69 -2
  275. package/src/commands/agents.ts +42 -9
  276. package/src/commands/artifacts.ts +130 -6
  277. package/src/commands/backup.ts +287 -34
  278. package/src/commands/browse.ts +564 -267
  279. package/src/commands/diagnostics.ts +6 -3
  280. package/src/commands/ledger-v3.ts +20 -3
  281. package/src/commands/qa-run.ts +37 -3
  282. package/src/commands/qa-status.ts +11 -2
  283. package/src/commands/resources.ts +23 -3
  284. package/src/commands/review-pack.ts +165 -62
  285. package/src/commands/tunnel.ts +2 -1
  286. package/src/core/agents/canonical-emit.ts +4 -2
  287. package/src/core/agents/cli.ts +14 -6
  288. package/src/core/agents/live-authority-v3.ts +7 -3
  289. package/src/core/agents/live-lifecycle-v3.ts +2 -2
  290. package/src/core/agents/render/prompt-context.ts +68 -14
  291. package/src/core/agents/session-finalizer-v3.ts +2 -2
  292. package/src/core/agents/state/live-coordination-view.ts +4 -4
  293. package/src/core/agents/state/names.ts +92 -7
  294. package/src/core/agents/state/stale-sweep.ts +22 -8
  295. package/src/core/agents/turn-elapsed.ts +135 -0
  296. package/src/core/artifacts/activity.ts +71 -0
  297. package/src/core/artifacts/delivery-card.ts +375 -0
  298. package/src/core/artifacts/index.ts +385 -91
  299. package/src/core/artifacts/mutation-lock.ts +106 -0
  300. package/src/core/backup/host-snapshot.ts +76 -0
  301. package/src/core/config.ts +66 -13
  302. package/src/core/diagnostics/advice.ts +148 -120
  303. package/src/core/diagnostics/bundle.ts +138 -52
  304. package/src/core/diagnostics/comparison.ts +6 -2
  305. package/src/core/diagnostics/contract.ts +39 -42
  306. package/src/core/diagnostics/index.ts +2 -0
  307. package/src/core/diagnostics/pressure-contract.ts +294 -0
  308. package/src/core/diagnostics/pressure.ts +1361 -0
  309. package/src/core/diagnostics/replay.ts +116 -11
  310. package/src/core/events/v3/adapter-id.ts +12 -0
  311. package/src/core/events/v3/archive-retention.ts +3 -6
  312. package/src/core/events/v3/bootstrap.ts +163 -16
  313. package/src/core/events/v3/capabilities.ts +75 -25
  314. package/src/core/events/v3/capability-drift.ts +2 -2
  315. package/src/core/events/v3/control-witness.ts +172 -41
  316. package/src/core/events/v3/control.ts +34 -2
  317. package/src/core/events/v3/index.ts +3 -0
  318. package/src/core/events/v3/live-feed.ts +23 -5
  319. package/src/core/events/v3/live-routing.ts +14 -2
  320. package/src/core/events/v3/producers/command-recorder.ts +4 -4
  321. package/src/core/events/v3/producers/coordination-recorder.ts +4 -4
  322. package/src/core/events/v3/producers/hook-base.ts +21 -16
  323. package/src/core/events/v3/producers/hook.ts +21 -4
  324. package/src/core/events/v3/producers/intake.ts +6 -6
  325. package/src/core/events/v3/producers/producer-state-observer.ts +2 -1
  326. package/src/core/events/v3/producers/recorder.ts +50 -21
  327. package/src/core/events/v3/reader.ts +14 -13
  328. package/src/core/events/v3/runtime-build.ts +3 -2
  329. package/src/core/events/v3/runtime-telemetry-capabilities.ts +3 -3
  330. package/src/core/events/v3/turn-telemetry.ts +4 -4
  331. package/src/core/hooks/adapter/output.ts +50 -36
  332. package/src/core/hooks/backup-schedule.ts +147 -0
  333. package/src/core/hooks/cli.ts +65 -14
  334. package/src/core/hooks/codex-wsl-bridge.ts +21 -5
  335. package/src/core/hooks/index.ts +1 -0
  336. package/src/core/hooks/prompt-context/contract.ts +177 -0
  337. package/src/core/hooks/prompt-context/index.ts +22 -0
  338. package/src/core/hooks/prompt-context/runner.ts +303 -0
  339. package/src/core/qa-artifacts.ts +29 -3
  340. package/src/core/resources/contract.ts +76 -3
  341. package/src/core/resources/index.ts +1 -0
  342. package/src/core/resources/native.ts +481 -0
  343. package/src/core/resources/sampler.ts +46 -1
  344. package/src/core/resources/status.ts +717 -0
  345. package/src/core/resources/system.ts +530 -0
  346. package/src/core/semantic/service.ts +37 -3
  347. package/src/core/storage/builtins.ts +41 -0
  348. package/src/core/supervisor/contract.ts +45 -3
  349. package/src/core/supervisor/findings.ts +159 -0
  350. package/src/core/supervisor/history.ts +15 -0
  351. package/src/core/supervisor/ledger-state.ts +0 -0
  352. package/src/core/supervisor/service.ts +133 -5
  353. package/src/core/supervisor/storage.ts +7 -0
  354. package/src/core/workflow/admission.ts +33 -17
  355. package/src/core/workflow/engine.ts +2 -2
  356. package/src/core/workflow/live-session-v3.ts +6 -8
  357. package/src/core/workflow/proof.ts +4 -3
  358. package/src/lib/browser/capture-fidelity.ts +23 -0
  359. package/src/lib/browser/client.ts +96 -44
  360. package/src/lib/browser/index.ts +15 -1
  361. package/src/lib/browser/page-review-budget.ts +309 -0
  362. package/src/lib/browser/page-review-contracts.ts +129 -0
  363. package/src/lib/browser/page-review-evidence.ts +465 -0
  364. package/src/lib/browser/page-review-judge.ts +56 -40
  365. package/src/lib/browser/page-review-pack.ts +181 -43
  366. package/src/lib/browser/page-review-source.ts +30 -0
  367. package/src/lib/browser/qa-run-contracts.ts +62 -18
  368. package/src/lib/browser/qa-run.ts +259 -71
  369. package/src/lib/browser/qa-snapshot.ts +289 -48
  370. package/src/lib/browser/review-capture-transaction.ts +106 -0
  371. package/src/lib/browser/standalone-html.ts +4 -2
  372. package/src/lib/browser/thumbnail-association.ts +190 -0
  373. package/src/lib/browser/tiling.ts +63 -0
  374. package/src/lib/docs-metadata-managed.ts +4 -1
  375. package/src/lib/identities/assume.ts +12 -4
  376. package/src/lib/instructions/templates.ts +1 -0
  377. package/src/lib/local-file-url.ts +17 -2
  378. package/src/lib/tunnel/state.ts +70 -13
@@ -1 +1 @@
1
- {"version":3,"file":"qa-run-contracts.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run-contracts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qa-run-contracts.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run-contracts.ts"],"names":[],"mappings":"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"}
@@ -162,6 +162,18 @@ export function validateQaRunJob(value) {
162
162
  }
163
163
  if (job.policy !== undefined) {
164
164
  const p = job.policy;
165
+ if (p === null || typeof p !== "object" || Array.isArray(p)) {
166
+ errors.push("policy must be an object");
167
+ }
168
+ if (p?.accept_dispositions !== undefined && typeof p.accept_dispositions !== "boolean") {
169
+ errors.push("policy.accept_dispositions must be a boolean");
170
+ }
171
+ if (p?.critique_tile_budget !== undefined) {
172
+ const n = p.critique_tile_budget;
173
+ if (typeof n !== "number" || !Number.isInteger(n) || n < 8 || n > 400) {
174
+ errors.push("policy.critique_tile_budget must be an integer between 8 and 400");
175
+ }
176
+ }
165
177
  if (p?.command_concurrency !== undefined) {
166
178
  const n = p.command_concurrency;
167
179
  if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n > 8) {
@@ -182,8 +194,8 @@ export function validateQaRunJob(value) {
182
194
  }
183
195
  if (p?.critique_max_tiles !== undefined) {
184
196
  const n = p.critique_max_tiles;
185
- if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n > 200) {
186
- errors.push("policy.critique_max_tiles must be an integer between 1 and 200");
197
+ if (typeof n !== "number" || !Number.isInteger(n) || n < 1 || n > 400) {
198
+ errors.push("policy.critique_max_tiles must be an integer between 1 and 400");
187
199
  }
188
200
  }
189
201
  if (p?.critique_pool !== undefined) {
@@ -213,7 +225,10 @@ export function contextIdFor(context) {
213
225
  /**
214
226
  * Merge planner-manifest coverage with the job's extra contexts. The manifest
215
227
  * is the floor: its contexts always run, in manifest order, and a job can only
216
- * append. The union construction makes narrowing impossible by design; the
228
+ * append coverage or supply setup arguments for an exactly matching context.
229
+ * IDs and rendering identities must agree; aliases are rejected rather than
230
+ * silently losing a setup or leaving a check pointed at an absent context.
231
+ * The union construction makes narrowing impossible by design; the
217
232
  * returned list is what the runner executes and what the result reports.
218
233
  */
219
234
  export function mergeCoverage(manifest, job) {
@@ -223,14 +238,31 @@ export function mergeCoverage(manifest, job) {
223
238
  theme: context.theme,
224
239
  state: context.state,
225
240
  }));
226
- const seen = new Set(merged.map((context) => context.id));
241
+ const identity = (context) => JSON.stringify([context.viewport, context.theme, context.state]);
242
+ const byId = new Map(merged.map((context) => [context.id, context]));
243
+ const byRender = new Map(merged.map((context) => [identity(context), context]));
244
+ const jobIds = new Set();
227
245
  for (const context of job.contexts ?? []) {
228
- const canonical = contextIdFor(context);
229
- if (seen.has(canonical) || seen.has(context.id))
246
+ if (jobIds.has(context.id))
247
+ throw new Error(`Duplicate QA context ID: ${context.id}`);
248
+ jobIds.add(context.id);
249
+ const existingId = byId.get(context.id);
250
+ const existingRender = byRender.get(identity(context));
251
+ if (existingId || existingRender) {
252
+ if (!existingId || existingId !== existingRender) {
253
+ throw new Error(`Conflicting QA context ID or rendering identity: ${context.id}`);
254
+ }
255
+ if (context.args !== undefined)
256
+ existingId.args = [...context.args];
230
257
  continue;
231
- seen.add(canonical);
232
- seen.add(context.id);
233
- merged.push(context);
258
+ }
259
+ const added = {
260
+ ...context,
261
+ ...(context.args !== undefined ? { args: [...context.args] } : {}),
262
+ };
263
+ byId.set(added.id, added);
264
+ byRender.set(identity(added), added);
265
+ merged.push(added);
234
266
  }
235
267
  return merged;
236
268
  }
@@ -266,12 +298,14 @@ function canonicalize(value) {
266
298
  return value;
267
299
  }
268
300
  /** SHA-256 hex digest over the effective validated job (after the CLI merges
269
- * its authoritative `target` and `mode`). `policy` is excluded: concurrency,
270
- * timeout, and metered-critique knobs change how the run executes, not what
271
- * it proves, and CLI flags mutate them after the job file is read — including
272
- * them would make the same job file verify differently across invocations. */
301
+ * its authoritative `target` and `mode`). Runtime policy knobs are excluded.
302
+ * Disposition acceptance changes what can establish a pass, so enabling it
303
+ * is identity-bearing; an ordinary run cannot verify as an accepting run. */
273
304
  export function computeJobDigest(job) {
274
- const { policy: _policy, ...identityBearing } = job;
305
+ const { policy, ...rest } = job;
306
+ const identityBearing = policy?.accept_dispositions === true
307
+ ? { ...rest, policy: { accept_dispositions: true } }
308
+ : rest;
275
309
  return createHash("sha256")
276
310
  .update(JSON.stringify(canonicalize(identityBearing)))
277
311
  .digest("hex");
@@ -1 +1 @@
1
- {"version":3,"file":"qa-run.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qa-run.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-run.ts"],"names":[],"mappings":"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"}
@@ -16,11 +16,13 @@ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "
16
16
  import { cpus, freemem, loadavg, totalmem } from "node:os";
17
17
  import { basename, join } from "node:path";
18
18
  import { DEFAULT_CRITIQUE_RUBRIC } from "./critique.js";
19
+ import { allocateTileBudget, capturePlanDigest, validatePageReviewCapturePlan, } from "./page-review-budget.js";
20
+ import { PAGE_REVIEW_DEFAULT_TILE_BUDGET, } from "./page-review-contracts.js";
21
+ import { applyPackReviewDecisions, buildPackNativeEvidence } from "./page-review-evidence.js";
19
22
  import { judgePageReviewPack, toCritiqueRecords } from "./page-review-judge.js";
20
- import { finalizePageReviewPack, gateHitsFromEnvelope, PAGE_REVIEW_DEFAULT_RETENTION_MINUTES, PAGE_REVIEW_FINDINGS_FILENAME, PAGE_REVIEW_PACK_DIRNAME, PAGE_REVIEW_PACK_SCHEMA, PAGE_REVIEW_REVIEW_FILENAME, readPackContext, readPackDom, readPackFullPage, readPackManifest, readPackSignature, } from "./page-review-pack.js";
21
- import { QA_CRITIQUE_CONTRACT_VERSION, rubricDigest } from "./qa-reuse.js";
23
+ import { finalizePageReviewPack, gateHitsFromEnvelope, PAGE_REVIEW_DEFAULT_RETENTION_MINUTES, PAGE_REVIEW_FINDINGS_FILENAME, PAGE_REVIEW_PACK_DIRNAME, PAGE_REVIEW_PACK_SCHEMA, PAGE_REVIEW_REVIEW_FILENAME, readPackContext, readPackDom, readPackManifest, readPackSignature, readPackTiles, } from "./page-review-pack.js";
22
24
  import { computeJobDigest, computeVerdict, mergeCoverage, QA_RUN_RESULT_SCHEMA_VERSION, QA_RUN_STATUS_SCHEMA_VERSION, } from "./qa-run-contracts.js";
23
- import { saveQaSnapshot } from "./qa-snapshot.js";
25
+ import { loadReviewDecisions, saveQaSnapshot } from "./qa-snapshot.js";
24
26
  /** Set on the runner's own environment before the host's critique provider is
25
27
  * loaded for the judge stage, unless the job permits metered critique: the
26
28
  * provider must stay on subscription-backed headless harnesses and surface
@@ -76,7 +78,6 @@ const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
76
78
  const DEFAULT_RUN_DEADLINE_MS = 900_000;
77
79
  const DEFAULT_COMMAND_CONCURRENCY = 2;
78
80
  /** Gate-hit rectangles forwarded to one context's capture child (`--review-pack-hit-rect`). */
79
- const REVIEW_PACK_HIT_RECTS_PER_CONTEXT = 50;
80
81
  const EXEC_MAX_BUFFER = 16 * 1024 * 1024;
81
82
  /** The planner's deterministic vocabulary is an executable contract, not a
82
83
  * report-only hint. A job may add checks, but these arguments always run for
@@ -617,12 +618,22 @@ export async function runQaMatrix(options) {
617
618
  ctx.viewport,
618
619
  ...(ctx.theme === "dark" ? ["--color-scheme", "dark"] : []),
619
620
  ...(ctx.args ?? []),
621
+ ...(job.interaction_states ?? [])
622
+ .filter((state) => state.name === ctx.state)
623
+ .flatMap((state) => [
624
+ ...state.setup,
625
+ ...state.assertions.flatMap((assertion) => ["--assert", assertion]),
626
+ "--assert-fail",
627
+ ]),
620
628
  ];
621
629
  // The planner's tile ceiling and every critique child must agree on the
622
630
  // per-context band cap, or the predicted cost and the real coverage drift.
623
- const critiqueMaxTilesArgs = job.policy?.critique_max_tiles !== undefined
624
- ? ["--check-critique-max-tiles", String(job.policy.critique_max_tiles)]
625
- : [];
631
+ const critiqueMaxTilesArgs = [
632
+ "--check-critique-max-tiles",
633
+ String(job.policy?.critique_max_tiles ??
634
+ job.policy?.critique_tile_budget ??
635
+ PAGE_REVIEW_DEFAULT_TILE_BUDGET),
636
+ ];
626
637
  // ------------------------------------------------------------------ plan
627
638
  const planArgv = [
628
639
  ...browseArgv,
@@ -707,6 +718,37 @@ export async function runQaMatrix(options) {
707
718
  }
708
719
  return finalize();
709
720
  }
721
+ // The planning render and capture must use the same native band geometry.
722
+ // Load the provider's pixel budget before gates, without making model calls.
723
+ const visual = manifest.checks.visual;
724
+ const runsVisual = visual !== "none";
725
+ const priorHeadlessOnly = process.env[QA_RUN_HEADLESS_ONLY_ENV];
726
+ const restoreHeadlessOnly = () => {
727
+ if (priorHeadlessOnly === undefined)
728
+ delete process.env[QA_RUN_HEADLESS_ONLY_ENV];
729
+ else
730
+ process.env[QA_RUN_HEADLESS_ONLY_ENV] = priorHeadlessOnly;
731
+ };
732
+ let provider;
733
+ if (runsVisual) {
734
+ if (!job.policy?.allow_metered_critique)
735
+ process.env[QA_RUN_HEADLESS_ONLY_ENV] = "1";
736
+ try {
737
+ provider =
738
+ options.critiqueProvider ??
739
+ (options.critiqueProviderLoader ? await options.critiqueProviderLoader() : undefined);
740
+ }
741
+ catch (err) {
742
+ log(`critique provider failed to load: ${err instanceof Error ? err.message : String(err)}`);
743
+ }
744
+ }
745
+ const bandArgs = provider?.tileBudgetPx !== undefined
746
+ ? ["--check-critique-band", String(Math.max(200, Math.min(1400, provider.tileBudgetPx)))]
747
+ : [];
748
+ const scopeArgs = visual === "full-page"
749
+ ? []
750
+ : manifest.scopes.flatMap((s) => ["--review-pack-scope", s.selector]);
751
+ const gateCapturePlans = new Map();
710
752
  const manifestGateArgs = manifest.checks.deterministic.flatMap((check) => MANIFEST_DETERMINISTIC_ARGS[check] ?? []);
711
753
  const enforceConsole = manifest.checks.deterministic.includes("console");
712
754
  const checks = job.checks ?? [];
@@ -734,6 +776,20 @@ export async function runQaMatrix(options) {
734
776
  ...(manifest.checks.visual !== "none" ? ["--no-screenshot"] : []),
735
777
  ...manifestGateArgs,
736
778
  ...applicable.flatMap((check) => check.args),
779
+ ...(runsVisual
780
+ ? [
781
+ "--review-pack-plan",
782
+ "--review-pack-context",
783
+ ctx.id,
784
+ "--qa-theme",
785
+ ctx.theme,
786
+ "--qa-state",
787
+ ctx.state,
788
+ ...scopeArgs,
789
+ ...bandArgs,
790
+ ...critiqueMaxTilesArgs,
791
+ ]
792
+ : []),
737
793
  ];
738
794
  log(`gate ${ctx.id}: ${checkId}`);
739
795
  const { res, wallTimeMs } = await timedExec(argv, baseEnv);
@@ -741,6 +797,25 @@ export async function runQaMatrix(options) {
741
797
  const failures = [];
742
798
  let outcome;
743
799
  const envelope = existsSync(jsonPath) ? readEnvelope(jsonPath) : undefined;
800
+ if (runsVisual) {
801
+ try {
802
+ const capturePlan = validatePageReviewCapturePlan(envelope?.review_pack_capture_plan);
803
+ if (capturePlan.context_id !== ctx.id ||
804
+ capturePlan.viewport !== ctx.viewport ||
805
+ capturePlan.theme !== ctx.theme ||
806
+ capturePlan.state !== ctx.state) {
807
+ throw new Error("capture plan belongs to a different render context");
808
+ }
809
+ gateCapturePlans.set(ctx.id, capturePlan);
810
+ }
811
+ catch (err) {
812
+ blockers.push({
813
+ stage: "capture",
814
+ context_id: ctx.id,
815
+ reason: `capture plan unavailable: ${err instanceof Error ? err.message : String(err)}`,
816
+ });
817
+ }
818
+ }
744
819
  const consoleFailures = enforceConsole ? parseConsoleFailures(envelope) : [];
745
820
  if (!res.error && res.exitCode === 0 && existsSync(jsonPath)) {
746
821
  if (consoleFailures.length > 0) {
@@ -864,8 +939,6 @@ export async function runQaMatrix(options) {
864
939
  // Each context is rendered ONCE into the run's page review pack (full-page
865
940
  // screenshot, tiles as PNG files, DOM, signature) through the same bounded
866
941
  // pool the gates used, and its browser closes before any vision call.
867
- const visual = manifest.checks.visual;
868
- const cleanSoFar = blockers.length === 0 && commands.every((command) => command.outcome === "passed");
869
942
  const packDir = join(outDir, PAGE_REVIEW_PACK_DIRNAME);
870
943
  const capturedRecords = [];
871
944
  const judgeCommand = options.reviewPackJudgeCommand?.(packDir);
@@ -928,61 +1001,49 @@ export async function runQaMatrix(options) {
928
1001
  });
929
1002
  }
930
1003
  };
931
- // The provider is loaded once, before capture, so the capture children can
932
- // clamp band height to the routed model's vision budget (what browse does
933
- // for --check-critique) and the judge reuses the same instance.
934
- const priorHeadlessOnly = process.env[QA_RUN_HEADLESS_ONLY_ENV];
935
- const restoreHeadlessOnly = () => {
936
- if (priorHeadlessOnly === undefined)
937
- delete process.env[QA_RUN_HEADLESS_ONLY_ENV];
938
- else
939
- process.env[QA_RUN_HEADLESS_ONLY_ENV] = priorHeadlessOnly;
940
- };
941
- let provider;
942
- const runsVisual = cleanSoFar && visual !== "none";
1004
+ enterStage("capture");
1005
+ const captureStart = Date.now();
943
1006
  if (runsVisual) {
944
- if (!job.policy?.allow_metered_critique)
945
- process.env[QA_RUN_HEADLESS_ONLY_ENV] = "1";
1007
+ writeFileSync(join(outDir, "preliminary-gates.json"), `${JSON.stringify(gateOutcomes, null, 2)}\n`);
1008
+ for (const gate of gateOutcomes)
1009
+ if (gate) {
1010
+ gate.outcome = "unknown";
1011
+ gate.failures = ["Authoritative same-visit gates and capture have not completed."];
1012
+ }
1013
+ const allocations = new Map();
946
1014
  try {
947
- provider =
948
- options.critiqueProvider ??
949
- (options.critiqueProviderLoader ? await options.critiqueProviderLoader() : undefined);
1015
+ const plans = contexts.map((ctx) => {
1016
+ const candidate = gateCapturePlans.get(ctx.id);
1017
+ if (!candidate)
1018
+ throw new Error(`no valid capture plan for ${ctx.id}; rerun after fixing its gate capture`);
1019
+ return candidate;
1020
+ });
1021
+ const ceilings = job.policy?.critique_max_tiles === undefined
1022
+ ? undefined
1023
+ : Object.fromEntries(contexts.map((ctx) => [ctx.id, job.policy?.critique_max_tiles]));
1024
+ const allocation = allocateTileBudget(plans, job.policy?.critique_tile_budget ?? PAGE_REVIEW_DEFAULT_TILE_BUDGET, ceilings);
1025
+ for (const row of allocation.contexts)
1026
+ allocations.set(row.context_id, row);
1027
+ writeFileSync(join(outDir, "tile-allocation.json"), `${JSON.stringify(allocation, null, 2)}\n`);
1028
+ log(`tile budget: ${allocation.used}/${allocation.budget} allocated across ${allocations.size} contexts`);
950
1029
  }
951
1030
  catch (err) {
952
- provider = undefined;
953
- log(`critique provider failed to load: ${err instanceof Error ? err.message : String(err)}`);
954
- }
955
- }
956
- const bandArgs = provider?.tileBudgetPx !== undefined
957
- ? ["--check-critique-band", String(Math.max(200, Math.min(1400, provider.tileBudgetPx)))]
958
- : [];
959
- const scopeArgs = visual === "full-page"
960
- ? []
961
- : manifest.scopes.flatMap((s) => ["--review-pack-scope", s.selector]);
962
- // Gate-hit rectangles ride into each context's capture child so the bands
963
- // they land in are cut even past the tile cap (`hit band N` tiles). The
964
- // gates ran first, so the rects are known before the page is captured.
965
- const hitRectsByContext = new Map();
966
- for (const gate of gateRecords()) {
967
- for (const hit of gate.hits ?? []) {
968
- const list = hitRectsByContext.get(gate.context_id) ?? [];
969
- if (list.length >= REVIEW_PACK_HIT_RECTS_PER_CONTEXT)
970
- break;
971
- const r = hit.rect;
972
- list.push([r.x, r.y, Math.max(0, r.width), Math.max(0, r.height)].map((n) => Math.round(n)).join(","));
973
- hitRectsByContext.set(gate.context_id, list);
1031
+ blockers.push({
1032
+ stage: "capture",
1033
+ reason: `tile allocation failed: ${err instanceof Error ? err.message : String(err)}`,
1034
+ });
974
1035
  }
975
- }
976
- const hitRectArgs = (contextId) => (hitRectsByContext.get(contextId) ?? []).flatMap((spec) => ["--review-pack-hit-rect", spec]);
977
- enterStage("capture");
978
- const captureStart = Date.now();
979
- if (runsVisual) {
980
1036
  const captureOutcomes = new Array(contexts.length);
981
1037
  const captureRecords = new Array(contexts.length);
982
1038
  await runPool(contexts, concurrency, async (ctx, index) => {
983
1039
  if (pastDeadline())
984
1040
  return;
1041
+ const allocation = allocations.get(ctx.id);
1042
+ if (!allocation)
1043
+ return;
985
1044
  const outPrefix = join(outDir, `${ctx.id}-capture`);
1045
+ const allocationFile = `${outPrefix}-allocation.json`;
1046
+ writeFileSync(allocationFile, `${JSON.stringify(allocation)}\n`);
986
1047
  const argv = [
987
1048
  ...browseArgv,
988
1049
  job.target,
@@ -998,11 +1059,16 @@ export async function runQaMatrix(options) {
998
1059
  ctx.theme,
999
1060
  "--qa-state",
1000
1061
  ctx.state,
1001
- ...(visual === "scoped" ? ["--no-review-pack-bands"] : []),
1062
+ "--review-pack-reservation",
1063
+ allocationFile,
1064
+ "--review-pack-plan",
1065
+ ...manifestGateArgs,
1066
+ ...checks
1067
+ .filter((check) => check.contexts === undefined || check.contexts.includes(ctx.id))
1068
+ .flatMap((check) => check.args),
1002
1069
  ...scopeArgs,
1003
1070
  ...critiqueMaxTilesArgs,
1004
1071
  ...bandArgs,
1005
- ...hitRectArgs(ctx.id),
1006
1072
  ];
1007
1073
  log(`capture ${ctx.id}${scopeArgs.length > 0 ? ` [${manifest.scopes.map((s) => s.selector).join(",")}]` : ""}`);
1008
1074
  const { res, wallTimeMs } = await timedExec(argv, baseEnv);
@@ -1012,16 +1078,48 @@ export async function runQaMatrix(options) {
1012
1078
  const failures = [];
1013
1079
  let outcome;
1014
1080
  let record;
1015
- if (!res.error && res.exitCode === 0 && envelope && report?.context_id) {
1081
+ if (!res.error &&
1082
+ (res.exitCode === 0 || res.exitCode === 2) &&
1083
+ envelope &&
1084
+ report?.context_id) {
1016
1085
  try {
1017
1086
  record = readPackContext(packDir, report.context_id);
1018
- outcome = "passed";
1087
+ const currentPlan = validatePageReviewCapturePlan(envelope.review_pack_capture_plan);
1088
+ const transaction = envelope.review_pack_transaction;
1089
+ if (!record.capture_plan ||
1090
+ record.id !== ctx.id ||
1091
+ capturePlanDigest(record.capture_plan) !== capturePlanDigest(currentPlan) ||
1092
+ transaction?.source_digest !== currentPlan.source_digest ||
1093
+ transaction.attempts?.at(-1)?.status !== "captured" ||
1094
+ record.tiles.length > allocation.selected_ids.length) {
1095
+ throw new Error("Fresh gates, source identity and native capture are not bound to the same transaction.");
1096
+ }
1097
+ const freshFailures = [
1098
+ ...parseGateFailures(envelope),
1099
+ ...(enforceConsole ? parseConsoleFailures(envelope) : []),
1100
+ ];
1101
+ if (res.exitCode === 2 && !freshFailures.length)
1102
+ freshFailures.push("Fresh gate command returned exit code 2.");
1103
+ const preliminaryGate = gateOutcomes[index];
1104
+ if (!preliminaryGate)
1105
+ throw new Error("Missing context gate identity.");
1106
+ Object.assign(preliminaryGate, {
1107
+ argv,
1108
+ exit_code: res.exitCode,
1109
+ outcome: freshFailures.length ? "failed" : "passed",
1110
+ failures: freshFailures,
1111
+ artifacts: gatherArtifacts(outPrefix),
1112
+ wall_time_ms: wallTimeMs,
1113
+ });
1114
+ outcome = freshFailures.length ? "failed" : "passed";
1115
+ failures.push(...freshFailures);
1019
1116
  }
1020
1117
  catch (err) {
1021
1118
  outcome = "unknown";
1022
1119
  const reason = `pack context unreadable: ${err instanceof Error ? err.message : String(err)}`;
1023
1120
  failures.push(reason);
1024
1121
  blockers.push({ stage: "capture", context_id: ctx.id, reason });
1122
+ record = undefined;
1025
1123
  }
1026
1124
  }
1027
1125
  else {
@@ -1099,7 +1197,50 @@ export async function runQaMatrix(options) {
1099
1197
  };
1100
1198
  for (const row of judged.contexts) {
1101
1199
  judgedById.set(row.context_id, row);
1200
+ const captured = capturedRecords.find((record) => record.id === row.context_id);
1201
+ if (captured)
1202
+ captured.evidence_context = row.record.evidence_context;
1102
1203
  let contextOutcome = row.outcome === "pass" ? "passed" : row.outcome === "fail" ? "failed" : "unknown";
1204
+ let dismissed = [];
1205
+ if (job.policy?.accept_dispositions === true &&
1206
+ (row.outcome === "pass" || row.outcome === "fail") &&
1207
+ row.tiles_unjudged === 0 &&
1208
+ !row.record.capture_incomplete &&
1209
+ !row.coverage.capped) {
1210
+ try {
1211
+ const evidence = buildPackNativeEvidence(row.record, readPackTiles(packDir, row.record), DEFAULT_CRITIQUE_RUBRIC);
1212
+ const slot = loadReviewDecisions(job.target, { viewport: row.record.viewport, theme: row.record.theme, state: row.record.state }, options.snapshotStore ?? {});
1213
+ const reviewed = applyPackReviewDecisions({
1214
+ target: job.target,
1215
+ evidence,
1216
+ findings: row.findings,
1217
+ slot,
1218
+ enabled: true,
1219
+ });
1220
+ dismissed = reviewed.applied;
1221
+ if (dismissed.length > 0 &&
1222
+ reviewed.findings.every((finding) => finding.severity !== "high")) {
1223
+ contextOutcome = "passed";
1224
+ }
1225
+ }
1226
+ catch (err) {
1227
+ contextOutcome = "unknown";
1228
+ blockers.push({
1229
+ stage: "critique",
1230
+ context_id: row.context_id,
1231
+ reason: `reviewed disposition evidence unavailable: ${err instanceof Error ? err.message : String(err)}`,
1232
+ });
1233
+ }
1234
+ }
1235
+ if (row.record.capture_incomplete) {
1236
+ if (contextOutcome !== "failed")
1237
+ contextOutcome = "unknown";
1238
+ blockers.push({
1239
+ stage: "capture",
1240
+ context_id: row.context_id,
1241
+ reason: "native capture evidence is incomplete; recapture this context before signoff",
1242
+ });
1243
+ }
1103
1244
  if (row.outcome === "skipped") {
1104
1245
  const detail = row.error ?? "critique reported no conclusive outcome";
1105
1246
  blockers.push({
@@ -1116,13 +1257,13 @@ export async function runQaMatrix(options) {
1116
1257
  blockers.push({
1117
1258
  stage: "critique",
1118
1259
  context_id: row.context_id,
1119
- reason: `judge did not review ${row.tiles_unjudged} of ${row.tiles_total} tile(s) before the ` +
1120
- "run deadline; nothing is proven for them",
1260
+ reason: row.error ??
1261
+ `judge did not review ${row.tiles_unjudged} of ${row.tiles_total} tile(s) before the ` +
1262
+ "run deadline; nothing is proven for them",
1121
1263
  });
1122
1264
  }
1123
- // A capped capture holds the top of the page and nothing below it.
1124
- // Signoff cannot rest on that; review mode keeps the row honest via
1125
- // `coverage` and leaves the verdict to the tiles that were seen.
1265
+ // Selected bands may leave gaps anywhere. Signoff needs complete
1266
+ // coverage, while review mode reports what was actually captured.
1126
1267
  if (job.mode === "signoff" && row.coverage.capped && contextOutcome !== "failed") {
1127
1268
  contextOutcome = "unknown";
1128
1269
  blockers.push({
@@ -1130,7 +1271,7 @@ export async function runQaMatrix(options) {
1130
1271
  context_id: row.context_id,
1131
1272
  reason: `critique coverage capped: ${row.coverage.bands_reviewed} of ${row.coverage.bands_total} bands ` +
1132
1273
  `reviewed (${row.coverage.reviewed_height_px} of ${row.coverage.page_height_px} px); raise ` +
1133
- "policy.critique_max_tiles to review the whole page in signoff mode",
1274
+ "policy.critique_tile_budget (and any explicit per-context ceiling) for full signoff coverage",
1134
1275
  });
1135
1276
  }
1136
1277
  const scopeById = new Map(row.record.tiles.map((tile) => [tile.id, tile.scope]));
@@ -1141,6 +1282,7 @@ export async function runQaMatrix(options) {
1141
1282
  tiles_reviewed: row.tiles_reviewed,
1142
1283
  tiles_reused: row.tiles_reused,
1143
1284
  outcome: contextOutcome,
1285
+ ...(dismissed.length > 0 ? { dismissed } : {}),
1144
1286
  findings: row.findings.map((finding) => {
1145
1287
  const selector = scopeById.get(finding.tile_id);
1146
1288
  return {
@@ -1163,7 +1305,7 @@ export async function runQaMatrix(options) {
1163
1305
  // -------------------------------------------------------------- snapshot
1164
1306
  // Signoff persists each context's baseline from the pack's own files (no
1165
1307
  // browser). The critique rides along only when the whole tile set was
1166
- // freshly judged, uncapped, and unscoped — a partial or scoped review must
1308
+ // judged or safely reused, uncapped, and unscoped — a partial or scoped review must
1167
1309
  // never become the next baseline's finding record. When the manifest
1168
1310
  // required no visual pass, a dedicated browse --qa-snapshot pass still runs.
1169
1311
  enterStage("snapshot");
@@ -1176,14 +1318,14 @@ export async function runQaMatrix(options) {
1176
1318
  const row = judgedById.get(record.id);
1177
1319
  const persistCritique = row !== undefined &&
1178
1320
  (row.outcome === "pass" || row.outcome === "fail") &&
1321
+ !record.capture_incomplete &&
1179
1322
  !record.coverage.capped &&
1180
- row.tiles_reused === 0 &&
1181
1323
  row.tiles_unjudged === 0 &&
1182
1324
  record.scopes.length === 0;
1183
1325
  const persisted = persistCritique && row
1184
1326
  ? {
1185
- contract_version: QA_CRITIQUE_CONTRACT_VERSION,
1186
- rubric_digest: rubricDigest(DEFAULT_CRITIQUE_RUBRIC),
1327
+ contract_version: 2,
1328
+ rubric_digest: "",
1187
1329
  outcome: row.outcome,
1188
1330
  findings: row.findings.map(({ tile_id: _tileId, ...finding }) => finding),
1189
1331
  tiles: record.tiles.map((tile) => ({
@@ -1197,10 +1339,15 @@ export async function runQaMatrix(options) {
1197
1339
  }
1198
1340
  : undefined;
1199
1341
  try {
1342
+ const tileEvidence = buildPackNativeEvidence(record, readPackTiles(packDir, record), DEFAULT_CRITIQUE_RUBRIC);
1343
+ if (persisted) {
1344
+ persisted.contract_version = tileEvidence.context.critique_contract_version;
1345
+ persisted.rubric_digest = tileEvidence.context.rubric_digest;
1346
+ }
1200
1347
  const saved = saveQaSnapshot(job.target, { viewport: record.viewport, theme: record.theme, state: record.state }, {
1201
1348
  signature: readPackSignature(packDir, record),
1202
1349
  domHtml: readPackDom(packDir, record),
1203
- screenshotPng: readPackFullPage(packDir, record),
1350
+ tileEvidence,
1204
1351
  ...(persisted ? { critique: persisted } : {}),
1205
1352
  }, options.snapshotStore ?? {});
1206
1353
  savedSnapshots.set(record.id, saved.path);
@@ -1,3 +1,4 @@
1
+ import { type PageReviewDecisionSlot, type PageReviewNativeEvidence } from "./page-review-contracts.js";
1
2
  import { type QaContext, type QaSignature } from "./qa-plan.js";
2
3
  import type { PersistedCritique } from "./qa-reuse.js";
3
4
  declare const SNAPSHOT_DIR: string;
@@ -14,10 +15,14 @@ export interface StoredQaSnapshot {
14
15
  /** Critique results persisted with the snapshot (full-coverage runs only) —
15
16
  * what the band-diff reuse layer replays for provably-unchanged regions. */
16
17
  critique?: PersistedCritique;
18
+ tileEvidence?: PageReviewNativeEvidence;
17
19
  }
18
20
  /** Filesystem-safe key for a target URL/file + render context. The digest
19
21
  * disambiguates targets whose sanitized slugs collide. */
20
22
  export declare function qaSnapshotKey(target: string): string;
23
+ export declare function loadReviewDecisions(target: string, context: QaContext, opts?: QaSnapshotStoreOptions): PageReviewDecisionSlot | null;
24
+ /** Decisions contain text and digests only; replacing a baseline cannot touch this slot. */
25
+ export declare function saveReviewDecisions(target: string, context: QaContext, slot: PageReviewDecisionSlot, opts?: QaSnapshotStoreOptions): void;
21
26
  /**
22
27
  * Persist a QA snapshot atomically. The whole context directory is staged as
23
28
  * `<dir>.tmp-<pid>` and renamed into place, replacing any prior snapshot for
@@ -28,6 +33,7 @@ export declare function saveQaSnapshot(target: string, context: QaContext, conte
28
33
  domHtml?: string;
29
34
  screenshotPng?: Buffer;
30
35
  critique?: PersistedCritique;
36
+ tileEvidence?: PageReviewNativeEvidence;
31
37
  }, opts?: QaSnapshotStoreOptions): StoredQaSnapshot;
32
38
  /** Load the persisted snapshot for a target + context, or null. A corrupt
33
39
  * signature file returns null (and the caller re-acquires a baseline) rather
@@ -1 +1 @@
1
- {"version":3,"file":"qa-snapshot.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-snapshot.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,QAAA,MAAM,YAAY,QAA0D,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,WAAW,CAAC;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;gFAC4E;IAC5E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED;0DAC0D;AAC1D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBpD;AAWD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE;IACP,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B,EACD,IAAI,GAAE,sBAA2B,GAChC,gBAAgB,CAyBlB;AAED;;4DAE4D;AAC5D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,sBAA2B,GAChC,gBAAgB,GAAG,IAAI,CAiCzB;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,sBAA2B,GAAG,MAAM,EAAE,CAUjF;AAED,MAAM,WAAW,kBAAkB;IACjC;;uCAEmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACrD,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;CAC/E,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwB9B;AAED,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"qa-snapshot.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/qa-snapshot.ts"],"names":[],"mappings":"AA2BA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,QAAA,MAAM,YAAY,QAA0D,CAAC;AAE7E,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,WAAW,CAAC;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;gFAC4E;IAC5E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,YAAY,CAAC,EAAE,wBAAwB,CAAC;CACzC;AAED;0DAC0D;AAC1D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBpD;AA2HD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,sBAA2B,GAChC,sBAAsB,GAAG,IAAI,CAc/B;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,EAAE,sBAAsB,EAC5B,IAAI,GAAE,sBAA2B,GAChC,IAAI,CAaN;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,OAAO,EAAE;IACP,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,YAAY,CAAC,EAAE,wBAAwB,CAAC;CACzC,EACD,IAAI,GAAE,sBAA2B,GAChC,gBAAgB,CAoElB;AAED;;4DAE4D;AAC5D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,EAClB,IAAI,GAAE,sBAA2B,GAChC,gBAAgB,GAAG,IAAI,CAqEzB;AAED,6EAA6E;AAC7E,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,sBAA2B,GAAG,MAAM,EAAE,CAUjF;AAED,MAAM,WAAW,kBAAkB;IACjC;;uCAEmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IACrD,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;KAAE,CAAC;CAC/E,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwB9B;AAED,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,CAAC"}