tracegrove 0.0.0-stage → 0.3.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 (721) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +588 -2
  3. package/conformance/coordination-vectors.json +377 -0
  4. package/dist/adapters/browser/capabilities.d.ts +45 -0
  5. package/dist/adapters/browser/capabilities.js +14 -0
  6. package/dist/adapters/browser/capabilities.js.map +1 -0
  7. package/dist/adapters/browser/driver.d.ts +45 -0
  8. package/dist/adapters/browser/driver.js +295 -0
  9. package/dist/adapters/browser/driver.js.map +1 -0
  10. package/dist/adapters/browser/session.d.ts +21 -0
  11. package/dist/adapters/browser/session.js +87 -0
  12. package/dist/adapters/browser/session.js.map +1 -0
  13. package/dist/adapters/http/capabilities.d.ts +2 -0
  14. package/dist/adapters/http/capabilities.js +21 -0
  15. package/dist/adapters/http/capabilities.js.map +1 -0
  16. package/dist/adapters/http/driver.d.ts +55 -0
  17. package/dist/adapters/http/driver.js +125 -0
  18. package/dist/adapters/http/driver.js.map +1 -0
  19. package/dist/adapters/job/capabilities.d.ts +45 -0
  20. package/dist/adapters/job/capabilities.js +8 -0
  21. package/dist/adapters/job/capabilities.js.map +1 -0
  22. package/dist/adapters/job/driver.d.ts +26 -0
  23. package/dist/adapters/job/driver.js +110 -0
  24. package/dist/adapters/job/driver.js.map +1 -0
  25. package/dist/adapters/job/types.d.ts +9 -0
  26. package/dist/adapters/job/types.js +2 -0
  27. package/dist/adapters/job/types.js.map +1 -0
  28. package/dist/adapters/mcp/capabilities.d.ts +46 -0
  29. package/dist/adapters/mcp/capabilities.js +17 -0
  30. package/dist/adapters/mcp/capabilities.js.map +1 -0
  31. package/dist/adapters/mcp/driver.d.ts +10 -0
  32. package/dist/adapters/mcp/driver.js +83 -0
  33. package/dist/adapters/mcp/driver.js.map +1 -0
  34. package/dist/adapters/poll.d.ts +12 -0
  35. package/dist/adapters/poll.js +31 -0
  36. package/dist/adapters/poll.js.map +1 -0
  37. package/dist/authoring/activity.d.ts +17 -0
  38. package/dist/authoring/activity.js +18 -0
  39. package/dist/authoring/activity.js.map +1 -0
  40. package/dist/authoring/agent.d.ts +70 -0
  41. package/dist/authoring/agent.js +268 -0
  42. package/dist/authoring/agent.js.map +1 -0
  43. package/dist/authoring/appLaunch.d.ts +7 -0
  44. package/dist/authoring/appLaunch.js +32 -0
  45. package/dist/authoring/appLaunch.js.map +1 -0
  46. package/dist/authoring/appLocation.d.ts +2 -0
  47. package/dist/authoring/appLocation.js +5 -0
  48. package/dist/authoring/appLocation.js.map +1 -0
  49. package/dist/authoring/browser.d.ts +15 -0
  50. package/dist/authoring/browser.js +20 -0
  51. package/dist/authoring/browser.js.map +1 -0
  52. package/dist/authoring/compile.d.ts +47 -0
  53. package/dist/authoring/compile.js +508 -0
  54. package/dist/authoring/compile.js.map +1 -0
  55. package/dist/authoring/discover.d.ts +43 -0
  56. package/dist/authoring/discover.js +149 -0
  57. package/dist/authoring/discover.js.map +1 -0
  58. package/dist/authoring/environmentTemplates.d.ts +3 -0
  59. package/dist/authoring/environmentTemplates.js +24 -0
  60. package/dist/authoring/environmentTemplates.js.map +1 -0
  61. package/dist/authoring/heal.d.ts +108 -0
  62. package/dist/authoring/heal.js +723 -0
  63. package/dist/authoring/heal.js.map +1 -0
  64. package/dist/authoring/index.d.ts +14 -0
  65. package/dist/authoring/index.js +15 -0
  66. package/dist/authoring/index.js.map +1 -0
  67. package/dist/authoring/init.d.ts +21 -0
  68. package/dist/authoring/init.js +141 -0
  69. package/dist/authoring/init.js.map +1 -0
  70. package/dist/authoring/localSettings.d.ts +33 -0
  71. package/dist/authoring/localSettings.js +31 -0
  72. package/dist/authoring/localSettings.js.map +1 -0
  73. package/dist/authoring/media.d.ts +10 -0
  74. package/dist/authoring/media.js +37 -0
  75. package/dist/authoring/media.js.map +1 -0
  76. package/dist/authoring/module.d.ts +2 -0
  77. package/dist/authoring/module.js +38 -0
  78. package/dist/authoring/module.js.map +1 -0
  79. package/dist/authoring/run.d.ts +74 -0
  80. package/dist/authoring/run.js +242 -0
  81. package/dist/authoring/run.js.map +1 -0
  82. package/dist/authoring/runSource.d.ts +6 -0
  83. package/dist/authoring/runSource.js +24 -0
  84. package/dist/authoring/runSource.js.map +1 -0
  85. package/dist/authoring/savedRun.d.ts +13 -0
  86. package/dist/authoring/savedRun.js +94 -0
  87. package/dist/authoring/savedRun.js.map +1 -0
  88. package/dist/authoring/schema.d.ts +574 -0
  89. package/dist/authoring/schema.js +147 -0
  90. package/dist/authoring/schema.js.map +1 -0
  91. package/dist/authoring/snapshotSource.d.ts +13 -0
  92. package/dist/authoring/snapshotSource.js +41 -0
  93. package/dist/authoring/snapshotSource.js.map +1 -0
  94. package/dist/authoring/sourceSelection.d.ts +34 -0
  95. package/dist/authoring/sourceSelection.js +13 -0
  96. package/dist/authoring/sourceSelection.js.map +1 -0
  97. package/dist/authoring/sources.d.ts +5 -0
  98. package/dist/authoring/sources.js +65 -0
  99. package/dist/authoring/sources.js.map +1 -0
  100. package/dist/authoring/status.d.ts +48 -0
  101. package/dist/authoring/status.js +100 -0
  102. package/dist/authoring/status.js.map +1 -0
  103. package/dist/authoring/typed.d.ts +6 -0
  104. package/dist/authoring/typed.js +5 -0
  105. package/dist/authoring/typed.js.map +1 -0
  106. package/dist/authoring/ui.d.ts +10 -0
  107. package/dist/authoring/ui.js +486 -0
  108. package/dist/authoring/ui.js.map +1 -0
  109. package/dist/authoring/uiPage.d.ts +1 -0
  110. package/dist/authoring/uiPage.js +358 -0
  111. package/dist/authoring/uiPage.js.map +1 -0
  112. package/dist/authoring/uiSourceControls.d.ts +2 -0
  113. package/dist/authoring/uiSourceControls.js +41 -0
  114. package/dist/authoring/uiSourceControls.js.map +1 -0
  115. package/dist/authoring/verificationSource.d.ts +41 -0
  116. package/dist/authoring/verificationSource.js +46 -0
  117. package/dist/authoring/verificationSource.js.map +1 -0
  118. package/dist/authoring/workspace.d.ts +33 -0
  119. package/dist/authoring/workspace.js +58 -0
  120. package/dist/authoring/workspace.js.map +1 -0
  121. package/dist/cli/arguments.d.ts +288 -0
  122. package/dist/cli/arguments.js +121 -0
  123. package/dist/cli/arguments.js.map +1 -0
  124. package/dist/cli/cleanup.d.ts +18 -0
  125. package/dist/cli/cleanup.js +40 -0
  126. package/dist/cli/cleanup.js.map +1 -0
  127. package/dist/cli/doctor.d.ts +51 -0
  128. package/dist/cli/doctor.js +118 -0
  129. package/dist/cli/doctor.js.map +1 -0
  130. package/dist/cli/errors.d.ts +2 -0
  131. package/dist/cli/errors.js +84 -0
  132. package/dist/cli/errors.js.map +1 -0
  133. package/dist/cli/jsonFile.d.ts +2 -0
  134. package/dist/cli/jsonFile.js +15 -0
  135. package/dist/cli/jsonFile.js.map +1 -0
  136. package/dist/cli/main.d.ts +2 -0
  137. package/dist/cli/main.js +603 -0
  138. package/dist/cli/main.js.map +1 -0
  139. package/dist/cli/render.d.ts +22 -0
  140. package/dist/cli/render.js +150 -0
  141. package/dist/cli/render.js.map +1 -0
  142. package/dist/cli/samples/catalog.d.ts +10 -0
  143. package/dist/cli/samples/catalog.js +3 -0
  144. package/dist/cli/samples/catalog.js.map +1 -0
  145. package/dist/cli/samples/write.d.ts +5 -0
  146. package/dist/cli/samples/write.js +64 -0
  147. package/dist/cli/samples/write.js.map +1 -0
  148. package/dist/cli/source.d.ts +41 -0
  149. package/dist/cli/source.js +59 -0
  150. package/dist/cli/source.js.map +1 -0
  151. package/dist/core/activationDecision.d.ts +153 -0
  152. package/dist/core/activationDecision.js +34 -0
  153. package/dist/core/activationDecision.js.map +1 -0
  154. package/dist/core/artifacts.d.ts +18 -0
  155. package/dist/core/artifacts.js +79 -0
  156. package/dist/core/artifacts.js.map +1 -0
  157. package/dist/core/atomicFiles.d.ts +9 -0
  158. package/dist/core/atomicFiles.js +76 -0
  159. package/dist/core/atomicFiles.js.map +1 -0
  160. package/dist/core/boundedFile.d.ts +2 -0
  161. package/dist/core/boundedFile.js +28 -0
  162. package/dist/core/boundedFile.js.map +1 -0
  163. package/dist/core/bundle.d.ts +77 -0
  164. package/dist/core/bundle.js +375 -0
  165. package/dist/core/bundle.js.map +1 -0
  166. package/dist/core/bundleArchive.d.ts +10 -0
  167. package/dist/core/bundleArchive.js +47 -0
  168. package/dist/core/bundleArchive.js.map +1 -0
  169. package/dist/core/bundleEvidence.d.ts +12 -0
  170. package/dist/core/bundleEvidence.js +169 -0
  171. package/dist/core/bundleEvidence.js.map +1 -0
  172. package/dist/core/bundleExport.d.ts +12 -0
  173. package/dist/core/bundleExport.js +36 -0
  174. package/dist/core/bundleExport.js.map +1 -0
  175. package/dist/core/bundleFiles.d.ts +5 -0
  176. package/dist/core/bundleFiles.js +47 -0
  177. package/dist/core/bundleFiles.js.map +1 -0
  178. package/dist/core/bundlePaths.d.ts +2 -0
  179. package/dist/core/bundlePaths.js +7 -0
  180. package/dist/core/bundlePaths.js.map +1 -0
  181. package/dist/core/bundleSnapshot.d.ts +26 -0
  182. package/dist/core/bundleSnapshot.js +71 -0
  183. package/dist/core/bundleSnapshot.js.map +1 -0
  184. package/dist/core/capabilityBoundary.d.ts +1452 -0
  185. package/dist/core/capabilityBoundary.js +361 -0
  186. package/dist/core/capabilityBoundary.js.map +1 -0
  187. package/dist/core/capabilityLifecycle.d.ts +366 -0
  188. package/dist/core/capabilityLifecycle.js +79 -0
  189. package/dist/core/capabilityLifecycle.js.map +1 -0
  190. package/dist/core/cleanup.d.ts +35 -0
  191. package/dist/core/cleanup.js +71 -0
  192. package/dist/core/cleanup.js.map +1 -0
  193. package/dist/core/cleanupActions.d.ts +5 -0
  194. package/dist/core/cleanupActions.js +15 -0
  195. package/dist/core/cleanupActions.js.map +1 -0
  196. package/dist/core/cleanupAttestation.d.ts +23 -0
  197. package/dist/core/cleanupAttestation.js +57 -0
  198. package/dist/core/cleanupAttestation.js.map +1 -0
  199. package/dist/core/clock.d.ts +4 -0
  200. package/dist/core/clock.js +14 -0
  201. package/dist/core/clock.js.map +1 -0
  202. package/dist/core/compiler.d.ts +19 -0
  203. package/dist/core/compiler.js +200 -0
  204. package/dist/core/compiler.js.map +1 -0
  205. package/dist/core/controller.d.ts +7 -0
  206. package/dist/core/controller.js +132 -0
  207. package/dist/core/controller.js.map +1 -0
  208. package/dist/core/coordination.d.ts +72 -0
  209. package/dist/core/coordination.js +118 -0
  210. package/dist/core/coordination.js.map +1 -0
  211. package/dist/core/corpus.d.ts +60 -0
  212. package/dist/core/corpus.js +216 -0
  213. package/dist/core/corpus.js.map +1 -0
  214. package/dist/core/deadline.d.ts +12 -0
  215. package/dist/core/deadline.js +38 -0
  216. package/dist/core/deadline.js.map +1 -0
  217. package/dist/core/deliveryJournal.d.ts +37 -0
  218. package/dist/core/deliveryJournal.js +85 -0
  219. package/dist/core/deliveryJournal.js.map +1 -0
  220. package/dist/core/environmentPreflight.d.ts +14 -0
  221. package/dist/core/environmentPreflight.js +179 -0
  222. package/dist/core/environmentPreflight.js.map +1 -0
  223. package/dist/core/errors.d.ts +22 -0
  224. package/dist/core/errors.js +29 -0
  225. package/dist/core/errors.js.map +1 -0
  226. package/dist/core/events.d.ts +14 -0
  227. package/dist/core/events.js +37 -0
  228. package/dist/core/events.js.map +1 -0
  229. package/dist/core/executionInspection.d.ts +90 -0
  230. package/dist/core/executionInspection.js +31 -0
  231. package/dist/core/executionInspection.js.map +1 -0
  232. package/dist/core/executionOwnership.d.ts +72 -0
  233. package/dist/core/executionOwnership.js +82 -0
  234. package/dist/core/executionOwnership.js.map +1 -0
  235. package/dist/core/executionPreparation.d.ts +362 -0
  236. package/dist/core/executionPreparation.js +93 -0
  237. package/dist/core/executionPreparation.js.map +1 -0
  238. package/dist/core/executionReadback.d.ts +15 -0
  239. package/dist/core/executionReadback.js +21 -0
  240. package/dist/core/executionReadback.js.map +1 -0
  241. package/dist/core/executor.d.ts +46 -0
  242. package/dist/core/executor.js +616 -0
  243. package/dist/core/executor.js.map +1 -0
  244. package/dist/core/frozenBundle.d.ts +314 -0
  245. package/dist/core/frozenBundle.js +24 -0
  246. package/dist/core/frozenBundle.js.map +1 -0
  247. package/dist/core/fsDurability.d.ts +2 -0
  248. package/dist/core/fsDurability.js +12 -0
  249. package/dist/core/fsDurability.js.map +1 -0
  250. package/dist/core/generators.d.ts +4 -0
  251. package/dist/core/generators.js +71 -0
  252. package/dist/core/generators.js.map +1 -0
  253. package/dist/core/gitSnapshot.d.ts +63 -0
  254. package/dist/core/gitSnapshot.js +55 -0
  255. package/dist/core/gitSnapshot.js.map +1 -0
  256. package/dist/core/gitSources.d.ts +29 -0
  257. package/dist/core/gitSources.js +97 -0
  258. package/dist/core/gitSources.js.map +1 -0
  259. package/dist/core/ledger.d.ts +38 -0
  260. package/dist/core/ledger.js +169 -0
  261. package/dist/core/ledger.js.map +1 -0
  262. package/dist/core/ledgerInspection.d.ts +18 -0
  263. package/dist/core/ledgerInspection.js +66 -0
  264. package/dist/core/ledgerInspection.js.map +1 -0
  265. package/dist/core/ledgerRecords.d.ts +23 -0
  266. package/dist/core/ledgerRecords.js +29 -0
  267. package/dist/core/ledgerRecords.js.map +1 -0
  268. package/dist/core/localActivationState.d.ts +260 -0
  269. package/dist/core/localActivationState.js +49 -0
  270. package/dist/core/localActivationState.js.map +1 -0
  271. package/dist/core/localPromotionState.d.ts +387 -0
  272. package/dist/core/localPromotionState.js +22 -0
  273. package/dist/core/localPromotionState.js.map +1 -0
  274. package/dist/core/localQualificationResults.d.ts +39 -0
  275. package/dist/core/localQualificationResults.js +160 -0
  276. package/dist/core/localQualificationResults.js.map +1 -0
  277. package/dist/core/localReviewStore.d.ts +28 -0
  278. package/dist/core/localReviewStore.js +167 -0
  279. package/dist/core/localReviewStore.js.map +1 -0
  280. package/dist/core/localScenarioActivation.d.ts +6 -0
  281. package/dist/core/localScenarioActivation.js +70 -0
  282. package/dist/core/localScenarioActivation.js.map +1 -0
  283. package/dist/core/localScenarioOwner.d.ts +20 -0
  284. package/dist/core/localScenarioOwner.js +2 -0
  285. package/dist/core/localScenarioOwner.js.map +1 -0
  286. package/dist/core/localScenarioPromotion.d.ts +9 -0
  287. package/dist/core/localScenarioPromotion.js +49 -0
  288. package/dist/core/localScenarioPromotion.js.map +1 -0
  289. package/dist/core/localScenarioState.d.ts +2297 -0
  290. package/dist/core/localScenarioState.js +117 -0
  291. package/dist/core/localScenarioState.js.map +1 -0
  292. package/dist/core/localScenarioStore.d.ts +838 -0
  293. package/dist/core/localScenarioStore.js +218 -0
  294. package/dist/core/localScenarioStore.js.map +1 -0
  295. package/dist/core/localScenarioStructure.d.ts +4 -0
  296. package/dist/core/localScenarioStructure.js +52 -0
  297. package/dist/core/localScenarioStructure.js.map +1 -0
  298. package/dist/core/localStructureState.d.ts +2 -0
  299. package/dist/core/localStructureState.js +22 -0
  300. package/dist/core/localStructureState.js.map +1 -0
  301. package/dist/core/lookup.d.ts +662 -0
  302. package/dist/core/lookup.js +55 -0
  303. package/dist/core/lookup.js.map +1 -0
  304. package/dist/core/ownership.d.ts +3 -0
  305. package/dist/core/ownership.js +24 -0
  306. package/dist/core/ownership.js.map +1 -0
  307. package/dist/core/planInspection.d.ts +108 -0
  308. package/dist/core/planInspection.js +44 -0
  309. package/dist/core/planInspection.js.map +1 -0
  310. package/dist/core/planner.d.ts +14 -0
  311. package/dist/core/planner.js +261 -0
  312. package/dist/core/planner.js.map +1 -0
  313. package/dist/core/qualification.d.ts +26 -0
  314. package/dist/core/qualification.js +58 -0
  315. package/dist/core/qualification.js.map +1 -0
  316. package/dist/core/qualificationBundle.d.ts +6 -0
  317. package/dist/core/qualificationBundle.js +51 -0
  318. package/dist/core/qualificationBundle.js.map +1 -0
  319. package/dist/core/qualificationExecution.d.ts +879 -0
  320. package/dist/core/qualificationExecution.js +54 -0
  321. package/dist/core/qualificationExecution.js.map +1 -0
  322. package/dist/core/recoveryStatus.d.ts +6 -0
  323. package/dist/core/recoveryStatus.js +123 -0
  324. package/dist/core/recoveryStatus.js.map +1 -0
  325. package/dist/core/reducer.d.ts +56 -0
  326. package/dist/core/reducer.js +355 -0
  327. package/dist/core/reducer.js.map +1 -0
  328. package/dist/core/replayAssessment.d.ts +15 -0
  329. package/dist/core/replayAssessment.js +78 -0
  330. package/dist/core/replayAssessment.js.map +1 -0
  331. package/dist/core/replayEvidence.d.ts +7 -0
  332. package/dist/core/replayEvidence.js +58 -0
  333. package/dist/core/replayEvidence.js.map +1 -0
  334. package/dist/core/repositorySelectionEvidence.d.ts +3 -0
  335. package/dist/core/repositorySelectionEvidence.js +58 -0
  336. package/dist/core/repositorySelectionEvidence.js.map +1 -0
  337. package/dist/core/rerun.d.ts +3 -0
  338. package/dist/core/rerun.js +24 -0
  339. package/dist/core/rerun.js.map +1 -0
  340. package/dist/core/resultSink.d.ts +52 -0
  341. package/dist/core/resultSink.js +120 -0
  342. package/dist/core/resultSink.js.map +1 -0
  343. package/dist/core/review.d.ts +22 -0
  344. package/dist/core/review.js +65 -0
  345. package/dist/core/review.js.map +1 -0
  346. package/dist/core/runnerCapabilities.d.ts +22 -0
  347. package/dist/core/runnerCapabilities.js +44 -0
  348. package/dist/core/runnerCapabilities.js.map +1 -0
  349. package/dist/core/scenario.d.ts +32 -0
  350. package/dist/core/scenario.js +119 -0
  351. package/dist/core/scenario.js.map +1 -0
  352. package/dist/core/scenarioActivation.d.ts +16 -0
  353. package/dist/core/scenarioActivation.js +47 -0
  354. package/dist/core/scenarioActivation.js.map +1 -0
  355. package/dist/core/scenarioStructure.d.ts +400 -0
  356. package/dist/core/scenarioStructure.js +72 -0
  357. package/dist/core/scenarioStructure.js.map +1 -0
  358. package/dist/core/snapshotEvidence.d.ts +3 -0
  359. package/dist/core/snapshotEvidence.js +37 -0
  360. package/dist/core/snapshotEvidence.js.map +1 -0
  361. package/dist/core/snapshotRepository.d.ts +48 -0
  362. package/dist/core/snapshotRepository.js +47 -0
  363. package/dist/core/snapshotRepository.js.map +1 -0
  364. package/dist/core/source-analysis.d.ts +18 -0
  365. package/dist/core/source-analysis.js +99 -0
  366. package/dist/core/source-analysis.js.map +1 -0
  367. package/dist/core/source-citation.d.ts +53 -0
  368. package/dist/core/source-citation.js +59 -0
  369. package/dist/core/source-citation.js.map +1 -0
  370. package/dist/core/sourcePromotion.d.ts +929 -0
  371. package/dist/core/sourcePromotion.js +92 -0
  372. package/dist/core/sourcePromotion.js.map +1 -0
  373. package/dist/core/sourceReviewEvidence.d.ts +271 -0
  374. package/dist/core/sourceReviewEvidence.js +24 -0
  375. package/dist/core/sourceReviewEvidence.js.map +1 -0
  376. package/dist/core/targetObservation.d.ts +3 -0
  377. package/dist/core/targetObservation.js +26 -0
  378. package/dist/core/targetObservation.js.map +1 -0
  379. package/dist/hosts/launchTemplates.d.ts +2 -0
  380. package/dist/hosts/launchTemplates.js +5 -0
  381. package/dist/hosts/launchTemplates.js.map +1 -0
  382. package/dist/hosts/local.d.ts +17 -0
  383. package/dist/hosts/local.js +311 -0
  384. package/dist/hosts/local.js.map +1 -0
  385. package/dist/hosts/localSupervisor.d.ts +1 -0
  386. package/dist/hosts/localSupervisor.js +115 -0
  387. package/dist/hosts/localSupervisor.js.map +1 -0
  388. package/dist/hosts/mock.d.ts +4 -0
  389. package/dist/hosts/mock.js +82 -0
  390. package/dist/hosts/mock.js.map +1 -0
  391. package/dist/hosts/pinnedArguments.d.ts +3 -0
  392. package/dist/hosts/pinnedArguments.js +39 -0
  393. package/dist/hosts/pinnedArguments.js.map +1 -0
  394. package/dist/hosts/runtime.d.ts +5 -0
  395. package/dist/hosts/runtime.js +60 -0
  396. package/dist/hosts/runtime.js.map +1 -0
  397. package/dist/hosts/sourceIdentity.d.ts +54 -0
  398. package/dist/hosts/sourceIdentity.js +27 -0
  399. package/dist/hosts/sourceIdentity.js.map +1 -0
  400. package/dist/hosts/types.d.ts +39 -0
  401. package/dist/hosts/types.js +2 -0
  402. package/dist/hosts/types.js.map +1 -0
  403. package/dist/index.d.ts +56 -0
  404. package/dist/index.js +52 -0
  405. package/dist/index.js.map +1 -0
  406. package/dist/integrations/awr/attachment.d.ts +34 -0
  407. package/dist/integrations/awr/attachment.js +120 -0
  408. package/dist/integrations/awr/attachment.js.map +1 -0
  409. package/dist/integrations/awr/attachmentContracts.d.ts +273 -0
  410. package/dist/integrations/awr/attachmentContracts.js +39 -0
  411. package/dist/integrations/awr/attachmentContracts.js.map +1 -0
  412. package/dist/integrations/awr/attachmentHttp.d.ts +9 -0
  413. package/dist/integrations/awr/attachmentHttp.js +19 -0
  414. package/dist/integrations/awr/attachmentHttp.js.map +1 -0
  415. package/dist/integrations/awr/cli.d.ts +7 -0
  416. package/dist/integrations/awr/cli.js +43 -0
  417. package/dist/integrations/awr/cli.js.map +1 -0
  418. package/dist/integrations/awr/contracts.d.ts +54 -0
  419. package/dist/integrations/awr/contracts.js +33 -0
  420. package/dist/integrations/awr/contracts.js.map +1 -0
  421. package/dist/integrations/awr/http.d.ts +8 -0
  422. package/dist/integrations/awr/http.js +23 -0
  423. package/dist/integrations/awr/http.js.map +1 -0
  424. package/dist/integrations/awr/index.d.ts +7 -0
  425. package/dist/integrations/awr/index.js +8 -0
  426. package/dist/integrations/awr/index.js.map +1 -0
  427. package/dist/integrations/awr/jsonHttp.d.ts +15 -0
  428. package/dist/integrations/awr/jsonHttp.js +69 -0
  429. package/dist/integrations/awr/jsonHttp.js.map +1 -0
  430. package/dist/integrations/awr/outbox.d.ts +28 -0
  431. package/dist/integrations/awr/outbox.js +88 -0
  432. package/dist/integrations/awr/outbox.js.map +1 -0
  433. package/dist/integrations/awr/projection.d.ts +4 -0
  434. package/dist/integrations/awr/projection.js +54 -0
  435. package/dist/integrations/awr/projection.js.map +1 -0
  436. package/dist/protocol/canonical.d.ts +41 -0
  437. package/dist/protocol/canonical.js +114 -0
  438. package/dist/protocol/canonical.js.map +1 -0
  439. package/dist/protocol/index.d.ts +9620 -0
  440. package/dist/protocol/index.js +185 -0
  441. package/dist/protocol/index.js.map +1 -0
  442. package/dist/protocol/primitives.d.ts +63 -0
  443. package/dist/protocol/primitives.js +46 -0
  444. package/dist/protocol/primitives.js.map +1 -0
  445. package/dist/protocol/schemas/browser.d.ts +153 -0
  446. package/dist/protocol/schemas/browser.js +29 -0
  447. package/dist/protocol/schemas/browser.js.map +1 -0
  448. package/dist/protocol/schemas/capability.d.ts +2126 -0
  449. package/dist/protocol/schemas/capability.js +165 -0
  450. package/dist/protocol/schemas/capability.js.map +1 -0
  451. package/dist/protocol/schemas/capabilityLifecycle.d.ts +509 -0
  452. package/dist/protocol/schemas/capabilityLifecycle.js +47 -0
  453. package/dist/protocol/schemas/capabilityLifecycle.js.map +1 -0
  454. package/dist/protocol/schemas/cleanup.d.ts +109 -0
  455. package/dist/protocol/schemas/cleanup.js +59 -0
  456. package/dist/protocol/schemas/cleanup.js.map +1 -0
  457. package/dist/protocol/schemas/cli.d.ts +121 -0
  458. package/dist/protocol/schemas/cli.js +24 -0
  459. package/dist/protocol/schemas/cli.js.map +1 -0
  460. package/dist/protocol/schemas/config.d.ts +59 -0
  461. package/dist/protocol/schemas/config.js +32 -0
  462. package/dist/protocol/schemas/config.js.map +1 -0
  463. package/dist/protocol/schemas/corpus.d.ts +36 -0
  464. package/dist/protocol/schemas/corpus.js +10 -0
  465. package/dist/protocol/schemas/corpus.js.map +1 -0
  466. package/dist/protocol/schemas/definitions.d.ts +3409 -0
  467. package/dist/protocol/schemas/definitions.js +431 -0
  468. package/dist/protocol/schemas/definitions.js.map +1 -0
  469. package/dist/protocol/schemas/evidenceProjection.d.ts +146 -0
  470. package/dist/protocol/schemas/evidenceProjection.js +18 -0
  471. package/dist/protocol/schemas/evidenceProjection.js.map +1 -0
  472. package/dist/protocol/schemas/execution.d.ts +3179 -0
  473. package/dist/protocol/schemas/execution.js +500 -0
  474. package/dist/protocol/schemas/execution.js.map +1 -0
  475. package/dist/protocol/schemas/gitSources.d.ts +330 -0
  476. package/dist/protocol/schemas/gitSources.js +32 -0
  477. package/dist/protocol/schemas/gitSources.js.map +1 -0
  478. package/dist/protocol/schemas/mcp.d.ts +24 -0
  479. package/dist/protocol/schemas/mcp.js +16 -0
  480. package/dist/protocol/schemas/mcp.js.map +1 -0
  481. package/dist/protocol/schemas/nativeJob.d.ts +106 -0
  482. package/dist/protocol/schemas/nativeJob.js +16 -0
  483. package/dist/protocol/schemas/nativeJob.js.map +1 -0
  484. package/dist/protocol/schemas/portableEnvironment.d.ts +1256 -0
  485. package/dist/protocol/schemas/portableEnvironment.js +108 -0
  486. package/dist/protocol/schemas/portableEnvironment.js.map +1 -0
  487. package/dist/protocol/schemas/promotion.d.ts +132 -0
  488. package/dist/protocol/schemas/promotion.js +9 -0
  489. package/dist/protocol/schemas/promotion.js.map +1 -0
  490. package/dist/protocol/schemas/protocol.d.ts +146 -0
  491. package/dist/protocol/schemas/protocol.js +25 -0
  492. package/dist/protocol/schemas/protocol.js.map +1 -0
  493. package/dist/protocol/schemas/recoveryStatus.d.ts +88 -0
  494. package/dist/protocol/schemas/recoveryStatus.js +20 -0
  495. package/dist/protocol/schemas/recoveryStatus.js.map +1 -0
  496. package/dist/protocol/schemas/resultSink.d.ts +80 -0
  497. package/dist/protocol/schemas/resultSink.js +14 -0
  498. package/dist/protocol/schemas/resultSink.js.map +1 -0
  499. package/dist/protocol/schemas/review.d.ts +248 -0
  500. package/dist/protocol/schemas/review.js +45 -0
  501. package/dist/protocol/schemas/review.js.map +1 -0
  502. package/dist/protocol/schemas/scenario.d.ts +810 -0
  503. package/dist/protocol/schemas/scenario.js +53 -0
  504. package/dist/protocol/schemas/scenario.js.map +1 -0
  505. package/dist/protocol/schemas/source.d.ts +300 -0
  506. package/dist/protocol/schemas/source.js +25 -0
  507. package/dist/protocol/schemas/source.js.map +1 -0
  508. package/dist/source/git.d.ts +36 -0
  509. package/dist/source/git.js +159 -0
  510. package/dist/source/git.js.map +1 -0
  511. package/dist/source/gitObjectProof.d.ts +12 -0
  512. package/dist/source/gitObjectProof.js +115 -0
  513. package/dist/source/gitObjectProof.js.map +1 -0
  514. package/dist/source/snapshotPaths.d.ts +2 -0
  515. package/dist/source/snapshotPaths.js +24 -0
  516. package/dist/source/snapshotPaths.js.map +1 -0
  517. package/dist/source/snapshotTree.d.ts +15 -0
  518. package/dist/source/snapshotTree.js +79 -0
  519. package/dist/source/snapshotTree.js.map +1 -0
  520. package/docs/architecture.md +126 -0
  521. package/docs/awr-delivery.md +102 -0
  522. package/docs/browser-driver.md +148 -0
  523. package/docs/cleanup-followups.md +74 -0
  524. package/docs/developer-ux.md +315 -0
  525. package/docs/examples/portable-environments/alongside_runner.json +199 -0
  526. package/docs/examples/portable-environments/external_staging.json +183 -0
  527. package/docs/git-object-proof.md +100 -0
  528. package/docs/git-source-resolution.md +133 -0
  529. package/docs/images/ui-run.png +0 -0
  530. package/docs/local-execution-recovery.md +55 -0
  531. package/docs/local-review-store.md +13 -0
  532. package/docs/local-scenario-store.md +91 -0
  533. package/docs/mcp-driver.md +87 -0
  534. package/docs/native-jobs.md +96 -0
  535. package/docs/portable-environments.md +155 -0
  536. package/docs/qualification-registration.md +58 -0
  537. package/docs/qualification-results.md +59 -0
  538. package/docs/replay-assessment.md +17 -0
  539. package/docs/result-sink.md +87 -0
  540. package/docs/scenario-activation.md +54 -0
  541. package/docs/scenario-structure.md +58 -0
  542. package/docs/source-promotion.md +104 -0
  543. package/docs/source-review.md +21 -0
  544. package/docs/verified-bundles.md +175 -0
  545. package/docs/work-report-attachment.md +127 -0
  546. package/package.json +45 -4
  547. package/samples/django-notes/manage.py +8 -0
  548. package/samples/django-notes/notes/__init__.py +0 -0
  549. package/samples/django-notes/notes/auth.py +14 -0
  550. package/samples/django-notes/notes/migrations/0001_initial.py +19 -0
  551. package/samples/django-notes/notes/migrations/__init__.py +0 -0
  552. package/samples/django-notes/notes/models.py +13 -0
  553. package/samples/django-notes/notes/views.py +33 -0
  554. package/samples/django-notes/notesite/__init__.py +0 -0
  555. package/samples/django-notes/notesite/settings.py +17 -0
  556. package/samples/django-notes/notesite/urls.py +9 -0
  557. package/samples/django-notes/requirements.txt +1 -0
  558. package/samples/django-notes/tracegrove/notes/crud.flow.yaml +27 -0
  559. package/samples/django-notes/tracegrove.config.yaml +7 -0
  560. package/samples/fastapi-notes/app/__init__.py +0 -0
  561. package/samples/fastapi-notes/app/main.py +69 -0
  562. package/samples/fastapi-notes/requirements.txt +2 -0
  563. package/samples/fastapi-notes/tracegrove/notes/crud.flow.yaml +27 -0
  564. package/samples/fastapi-notes/tracegrove.config.yaml +8 -0
  565. package/samples/notes-api/app/app.mjs +67 -0
  566. package/samples/notes-api/app/http.mjs +16 -0
  567. package/samples/notes-api/tracegrove/fixtures/existing-note.fixture.yaml +12 -0
  568. package/samples/notes-api/tracegrove/notes/create-read-delete.flow.yaml +35 -0
  569. package/samples/notes-api/tracegrove/notes/list.flow.yaml +25 -0
  570. package/samples/notes-api/tracegrove.config.yaml +15 -0
  571. package/samples/notes-api/verification/actions/notes.registry.yaml +6 -0
  572. package/samples/notes-api/verification/auth/host-issued-owner.yaml +6 -0
  573. package/samples/notes-api/verification/cases/notes.contract.yaml +51 -0
  574. package/samples/notes-api/verification/cases/notes.create.yaml +123 -0
  575. package/samples/notes-api/verification/cases/notes.suite.yaml +5 -0
  576. package/samples/notes-api/verification/components/notes-api-stub.profile.yaml +8 -0
  577. package/samples/notes-api/verification/components/notes-api.profile.yaml +15 -0
  578. package/samples/notes-api/verification/environments/local-notes.yaml +11 -0
  579. package/samples/notes-api/verification/environments/mock-notes.yaml +11 -0
  580. package/samples/notes-api/verification/fidelity/full-live-sandbox.yaml +7 -0
  581. package/samples/notes-api/verification/fidelity/mock-contract.yaml +6 -0
  582. package/samples/notes-api/verification/fixtures/existing-note.payload.yaml +15 -0
  583. package/samples/notes-api/verification/fixtures/existing-note.plan.yaml +9 -0
  584. package/samples/notes-api/verification/fixtures/existing-note.recipe.yaml +29 -0
  585. package/samples/notes-api/verification/hosts/local-process.yaml +27 -0
  586. package/samples/notes-api/verification/hosts/mock-loopback.yaml +14 -0
  587. package/samples/notes-api/verification/mocks/notes.responses.yaml +5 -0
  588. package/samples/notes-api/verification/personas/owner.yaml +16 -0
  589. package/samples/notes-api/verification/policies/no-authoring-inference.yaml +10 -0
  590. package/samples/notes-api/verification/runners/http.yaml +5 -0
  591. package/samples/notes-api/verification/surfaces/http-api.binding.yaml +11 -0
  592. package/samples/notes-api/verification/surfaces/http-api.pack.yaml +7 -0
  593. package/samples/notes-api/verification/workflow.yaml +27 -0
  594. package/samples/notes-browser/tracegrove/notes/browser.flow.yaml +19 -0
  595. package/samples/notes-browser/verification/cases/notes.browser.yaml +63 -0
  596. package/samples/notes-browser/verification/cases/notes.suite.yaml +4 -0
  597. package/samples/notes-browser/verification/runners/http.yaml +5 -0
  598. package/samples/notes-browser/verification/surfaces/http-api.binding.yaml +11 -0
  599. package/samples/notes-browser/verification/surfaces/http-api.pack.yaml +7 -0
  600. package/samples/notes-django/README.md +21 -0
  601. package/samples/notes-django/app/django_app.py +119 -0
  602. package/samples/notes-django/app/requirements.lock +4 -0
  603. package/samples/notes-mcp/app/mcp.mjs +47 -0
  604. package/samples/notes-mcp/tracegrove/notes.flow.yaml +20 -0
  605. package/samples/notes-mcp/tracegrove.config.yaml +13 -0
  606. package/samples/report-jobs/README.md +30 -0
  607. package/samples/report-jobs/app/jobs-api.mjs +65 -0
  608. package/samples/report-jobs/app/native-bridge.mjs +30 -0
  609. package/samples/report-jobs/app/store.mjs +74 -0
  610. package/samples/report-jobs/app/worker.mjs +22 -0
  611. package/samples/report-jobs/tracegrove/fixtures/failed-job.fixture.yaml +12 -0
  612. package/samples/report-jobs/tracegrove/fixtures/held-job.fixture.yaml +12 -0
  613. package/samples/report-jobs/tracegrove/fixtures/success-job.fixture.yaml +12 -0
  614. package/samples/report-jobs/tracegrove/reports/cancellation.flow.yaml +15 -0
  615. package/samples/report-jobs/tracegrove/reports/completion.flow.yaml +31 -0
  616. package/samples/report-jobs/tracegrove/reports/failure.flow.yaml +12 -0
  617. package/samples/report-jobs/tracegrove.config.yaml +10 -0
  618. package/samples/report-native/README.md +11 -0
  619. package/samples/report-native/tracegrove/cancellation.flow.yaml +11 -0
  620. package/samples/report-native/tracegrove/completion.flow.yaml +22 -0
  621. package/samples/report-native/tracegrove/failure.flow.yaml +7 -0
  622. package/samples/report-native/tracegrove.config.yaml +11 -0
  623. package/schema/tracegrove_cli-error_v1.json +156 -0
  624. package/schema/tracegrove_config_v1.json +233 -0
  625. package/schema/tracegrove_fixture_v1.json +297 -0
  626. package/schema/tracegrove_flow_v1.json +960 -0
  627. package/schema/tracegrove_recovery-status_v1.json +234 -0
  628. package/schema/tracegrove_run-video_v1.json +25 -0
  629. package/schema/workflow_action-registry_v1.json +303 -0
  630. package/schema/workflow_auth-recipe_v1.json +146 -0
  631. package/schema/workflow_boundary-observation_v1.json +515 -0
  632. package/schema/workflow_browser-command_v1.json +292 -0
  633. package/schema/workflow_browser-locator_v1.json +74 -0
  634. package/schema/workflow_browser-network-observation_v1.json +48 -0
  635. package/schema/workflow_browser-observation_v1.json +53 -0
  636. package/schema/workflow_budget-reservation_v1.json +150 -0
  637. package/schema/workflow_campaign-result_v1.json +382 -0
  638. package/schema/workflow_capability-artifact-manifest_v1.json +529 -0
  639. package/schema/workflow_capability-descriptor_v1.json +351 -0
  640. package/schema/workflow_capability-lifecycle-checkpoint_v1.json +510 -0
  641. package/schema/workflow_capability-observation_v1.json +1707 -0
  642. package/schema/workflow_capability-operation_v1.json +3212 -0
  643. package/schema/workflow_capability-replay-plan_v1.json +1247 -0
  644. package/schema/workflow_capability-retry-policy_v1.json +39 -0
  645. package/schema/workflow_capability-retry-state_v1.json +242 -0
  646. package/schema/workflow_case_v1.json +4222 -0
  647. package/schema/workflow_change-model_v1.json +614 -0
  648. package/schema/workflow_cleanup-expectation_v1.json +108 -0
  649. package/schema/workflow_cleanup-followup_v1.json +145 -0
  650. package/schema/workflow_component-profile_v1.json +219 -0
  651. package/schema/workflow_config_v1.json +180 -0
  652. package/schema/workflow_corpus_v1.json +172 -0
  653. package/schema/workflow_cost-observation_v1.json +366 -0
  654. package/schema/workflow_credential-lease_v1.json +222 -0
  655. package/schema/workflow_effective-config_v1.json +214 -0
  656. package/schema/workflow_environment-plan_v1.json +445 -0
  657. package/schema/workflow_environment_v1.json +1827 -0
  658. package/schema/workflow_evidence-projection_v1.json +636 -0
  659. package/schema/workflow_execution_v1.json +4086 -0
  660. package/schema/workflow_fidelity-plan_v1.json +512 -0
  661. package/schema/workflow_fidelity-profile_v1.json +396 -0
  662. package/schema/workflow_fixture-manifest_v1.json +918 -0
  663. package/schema/workflow_fixture-plan_v1.json +594 -0
  664. package/schema/workflow_git-source-request_v1.json +124 -0
  665. package/schema/workflow_git-source-resolution_v1.json +660 -0
  666. package/schema/workflow_git-source-snapshot_v1.json +287 -0
  667. package/schema/workflow_host-lease_v1.json +321 -0
  668. package/schema/workflow_host-observation_v1.json +282 -0
  669. package/schema/workflow_host-plan_v1.json +719 -0
  670. package/schema/workflow_identity-attestation_v1.json +412 -0
  671. package/schema/workflow_intelligence-policy_v1.json +153 -0
  672. package/schema/workflow_logical-payload_v1.json +206 -0
  673. package/schema/workflow_mcp-tool-call_v1.json +70 -0
  674. package/schema/workflow_mcp-tool-observation_v1.json +125 -0
  675. package/schema/workflow_mock-responses_v1.json +185 -0
  676. package/schema/workflow_native-job-action_v1.json +123 -0
  677. package/schema/workflow_native-job-observation_v1.json +138 -0
  678. package/schema/workflow_native-job-ready_v1.json +31 -0
  679. package/schema/workflow_native-job-request_v1.json +155 -0
  680. package/schema/workflow_native-job-response_v1.json +125 -0
  681. package/schema/workflow_ownership_v1.json +116 -0
  682. package/schema/workflow_persona_v1.json +499 -0
  683. package/schema/workflow_plan-edit-projection_v1.json +152 -0
  684. package/schema/workflow_plan-review_v1.json +246 -0
  685. package/schema/workflow_portable-environment-intent_v1.json +499 -0
  686. package/schema/workflow_portable-environment-profile_v1.json +1429 -0
  687. package/schema/workflow_portable-preflight_v1.json +2281 -0
  688. package/schema/workflow_qualification-admission_v1.json +467 -0
  689. package/schema/workflow_qualification-intent_v1.json +98 -0
  690. package/schema/workflow_qualification-policy_v1.json +109 -0
  691. package/schema/workflow_qualification-round_v1.json +226 -0
  692. package/schema/workflow_replay-assessment_v1.json +197 -0
  693. package/schema/workflow_replay-finding_v1.json +147 -0
  694. package/schema/workflow_request_v1.json +1567 -0
  695. package/schema/workflow_result-ingest_v1.json +343 -0
  696. package/schema/workflow_revisions_v1.json +334 -0
  697. package/schema/workflow_routing-decision_v1.json +482 -0
  698. package/schema/workflow_runner-capabilities_v1.json +316 -0
  699. package/schema/workflow_runner-profile_v1.json +119 -0
  700. package/schema/workflow_runner-protocol_v1_host.json +382 -0
  701. package/schema/workflow_runner-protocol_v1_plugin.json +491 -0
  702. package/schema/workflow_scenario-activation-intent_v1.json +346 -0
  703. package/schema/workflow_scenario-activation_v1.json +562 -0
  704. package/schema/workflow_scenario-projection_v1.json +221 -0
  705. package/schema/workflow_scenario-promotion_v1.json +455 -0
  706. package/schema/workflow_scenario-replay-assessment_v1.json +696 -0
  707. package/schema/workflow_scenario-revision-token_v1.json +115 -0
  708. package/schema/workflow_scenario-structure_v1.json +368 -0
  709. package/schema/workflow_scenario_v1.json +401 -0
  710. package/schema/workflow_scoped-resource_v1.json +550 -0
  711. package/schema/workflow_seed-recipe_v1.json +724 -0
  712. package/schema/workflow_selection_v1.json +1108 -0
  713. package/schema/workflow_signed-cleanup-followup_v1.json +175 -0
  714. package/schema/workflow_source-plan_v1.json +756 -0
  715. package/schema/workflow_source-selection_v1.json +456 -0
  716. package/schema/workflow_source-validation_v1.json +366 -0
  717. package/schema/workflow_step-event_v1.json +228 -0
  718. package/schema/workflow_stream-transcript_v1.json +1030 -0
  719. package/schema/workflow_suite_v1.json +64 -0
  720. package/schema/workflow_surface-binding_v1.json +411 -0
  721. package/schema/workflow_surface-pack_v1.json +159 -0
@@ -0,0 +1,148 @@
1
+ # Local browser driver
2
+
3
+ `BrowserDriver` runs real Chromium in a fresh, nonpersistent context. It does
4
+ not connect to an existing browser profile. Install its pinned browser before
5
+ running browser tests or using the driver:
6
+
7
+ ```sh
8
+ npm ci
9
+ PLAYWRIGHT_SKIP_BROWSER_GC=1 npx --no-install playwright install chromium
10
+ npm test -- tests/browser-driver.test.ts
11
+ ```
12
+
13
+ Linux CI uses `playwright install --with-deps chromium` to install the browser
14
+ and its system libraries.
15
+
16
+ Run the packaged browser sample through the same low-level CLI as an API case:
17
+
18
+ ```sh
19
+ npm run build
20
+ node dist/cli/main.js sample-config --sample notes-browser --output /tmp/notes-browser
21
+ node dist/cli/main.js plan --config /tmp/notes-browser/verification/workflow.yaml --output /tmp/notes-browser-request.json
22
+ node dist/cli/main.js run --request /tmp/notes-browser-request.json
23
+ ```
24
+
25
+ Use fresh output paths: sample generation refuses to overwrite a project. The
26
+ run prints its execution ID and bundle path. Pass that path to
27
+ `node dist/cli/main.js verify-bundle --bundle <path>` for independent verification.
28
+ The sample shares its real app, personas, fixture recipes, and cleanup with
29
+ `notes-api`; only its browser runner, binding, and case differ.
30
+
31
+ The exported `BrowserCommand`, `BrowserLocator`, and `BrowserObservation` Zod
32
+ schemas also have generated JSON Schemas. Commands navigate, click, fill, or
33
+ read visible text. Locators use exact roles, labels, or test IDs. Arbitrary
34
+ scripts and selectors are not accepted. Observations contain browser facts;
35
+ the driver does not decide whether a scenario passes.
36
+
37
+ Each operation has a deadline. Cancellation or a failed mutating operation closes the
38
+ context and browser before returning. Calls on one driver are serialized by
39
+ rejecting concurrent operations. Closing is idempotent. A closure acknowledgement
40
+ does not prove cleanup of an operating-system process tree after controller death.
41
+
42
+ Page requests must stay on the admitted origin. Chromium's CDP Fetch interception
43
+ checks every redirect hop while retaining native response streaming. Service
44
+ workers and WebSockets are disabled, and extra pages are closed. This is page
45
+ request filtering, not an operating system network sandbox; arbitrary application
46
+ code, workers, and popups require a host network boundary for full confinement.
47
+
48
+ `collectVideo()` closes the browser, flushes the WebM recording, and reads at
49
+ most 32 MiB from a regular file without following a final symlink. `dispose()`
50
+ removes the private temporary recording directory. Recordings and DOM text are
51
+ raw and may contain application data; callers must apply their evidence access
52
+ and retention policy before storing or sharing them. This driver does not issue
53
+ credentials or copy an owner's authenticated session.
54
+
55
+ The real-browser tests submit a local form, check an independent server receipt,
56
+ read the resulting DOM, and inspect the flushed recording. Separate tests cover
57
+ cross-origin paths, page requests and redirects, cancellation, timeout, invalid
58
+ commands, and expired startup.
59
+
60
+ The core runner profile accepts `adapter: browser`. A typed `ui.navigate` step
61
+ has a path; `ui.action` carries a click or fill command; `ui.observe` carries a
62
+ semantic target, predicate, and poll interval. DOM predicates address
63
+ `browser.text` or `browser.url` through the `browser.observation/1` oracle.
64
+ HTTP steps and fixtures can run in the same case for independent readback.
65
+
66
+ Each poll counts against `maxBrowserActions`. Case method and resource-prefix
67
+ rules filter page requests; read-only cases allow only GET and HEAD. Persona
68
+ viewport, locale, timezone, and reduced motion are passed to the browser. Pointer
69
+ activation uses clicks, keyboard activation uses focus with Enter or Space for toggles, and touch
70
+ activation uses taps. Host-issued bearer credentials are added only to admitted
71
+ page requests, never expanded into filled values or recorded commands.
72
+ Network events record methods, paths, and response statuses without request
73
+ headers or query strings. Recording more than 512 network events invalidates
74
+ collection. Required traces and declared redaction policies remain blocked.
75
+
76
+ Before closing a successful session, collection completes a layout-aware
77
+ screenshot, then requests another capture and waits for a frame presented after
78
+ the first capture through Playwright’s public screencast callback. Only then
79
+ does it stop and flush the encoder. A fresh frame delivered during the first
80
+ capture can still contain older pixels. This uses the cleanup deadline, not an
81
+ arbitrary recording delay. Collection failures name their capture, frame, or
82
+ flush phase without exposing page text or Playwright diagnostics.
83
+ The controller seals the recording bytes into the portable bundle and records
84
+ browser duration and artifact bytes. Verification reproduces the frozen runner
85
+ capabilities, independently reduces browser assertions, and checks video hashes
86
+ and byte counts. A required recording cannot be satisfied by an event log alone.
87
+
88
+ The integrated native tests cover pointer, keyboard, and 375px simulated touch,
89
+ combining an authenticated UI, DOM observation,
90
+ independent API assertions, fixture cleanup, video capture, and portable bundle
91
+ verification. A decoded-frame test checks the recorded terminal visual state.
92
+ This proves local behavior. Hosted admission, staging personas, and
93
+ controller-death browser cleanup remain open; no production qualification is claimed.
94
+
95
+ ## Short flows and Grove
96
+
97
+ The packaged sample also includes a short browser flow. From the repository root:
98
+
99
+ ```sh
100
+ node dist/cli/main.js test --config /tmp/notes-browser/tracegrove.config.yaml --grep notes.browser
101
+ node dist/cli/main.js ui --dir /tmp/notes-browser
102
+ ```
103
+
104
+ Open the printed loopback address and select the browser scenario. Its step
105
+ panel shows expected and observed text plus native recording controls. The
106
+ player supports keyboard playback and byte-range seeking, and preserves its
107
+ position when changing steps. Each media request verifies one immutable bundle
108
+ snapshot and binds the digest to that run and scenario. Corrupt, unbound, or
109
+ symlinked recordings are refused.
110
+
111
+ Browser commands reuse the core command and locator schemas:
112
+
113
+ ```yaml
114
+ title: Show the seeded note
115
+ given: { existing: existing-note }
116
+ browser:
117
+ allowPaths: [/ui, /notes]
118
+ allowMethods: [GET, HEAD]
119
+ steps:
120
+ - browser: { kind: navigate, path: /ui }
121
+ expect: { status: 200 }
122
+ - browser: { kind: click, target: { by: role, role: button, name: Refresh } }
123
+ - browser: { kind: read, target: { by: testId, name: notes } }
124
+ expect: { text: Existing note }
125
+ ```
126
+
127
+ `fill` accepts a semantic `target` and string `value`. Browser reads require
128
+ `expect.text` and poll until it holds. Click/fill steps assert completion; add a
129
+ DOM read or independent API readback to establish the effect. Browser steps use
130
+ the default persona, and browser flows require a recording. Set `maxActions`
131
+ and `maxArtifactBytes` inside the flow's `browser` block to tune their budgets.
132
+ Its allowed paths and methods combine with those derived from HTTP steps and
133
+ fixtures into the flow's effect envelope.
134
+
135
+ Persona configuration accepts optional `viewport`, `inputMode`, `locale`,
136
+ `timezone`, and `reducedMotion` fields alongside `subject`. Simulated touch
137
+ does not qualify a physical mobile device. Required traces, executable
138
+ redaction policies, and non-browser native surfaces remain unsupported.
139
+
140
+ Read-only observation timeouts preserve the browser for final evidence collection.
141
+ Browser polling retains its last completed observation at the deadline so an
142
+ unmet expectation keeps its observed value and remains an assertion failure.
143
+ Cancellation and actual browser errors still propagate; failed mutating actions
144
+ close the browser to revoke late effects.
145
+
146
+ Capture failures remain infrastructure failures with no accepted video. The sealed `browser.failed` event includes a bounded driver `cause` and `phase` (`capture`, `frame`, or `flush`) when available; unknown exceptions expose neither their message nor arbitrary fields.
147
+
148
+ Recordings use the persona viewport at native size, rounded up to even dimensions for VP9 (at most one padding pixel per edge), instead of scaling mobile content into a desktop canvas. Fresh-frame and encoder-flush checks remain required.
@@ -0,0 +1,74 @@
1
+ # Signed cleanup follow-ups
2
+
3
+ An executing worker's cleanup report cannot release a hosted persona. A separate
4
+ collector may sign a follow-up after observing the execution-owned resources.
5
+ The follow-up is a new immutable record; it does not rewrite the attempt receipt.
6
+
7
+ The ownership ledger supplies a `CleanupExpectation` containing the exact scope,
8
+ attempt, worker, fencing generation, coordination version, admitted effects,
9
+ unresolved effects and owned resource identities. HTTP absence and host stop are
10
+ distinct obligations. The collector signs the canonical follow-up with an
11
+ Ed25519 key kept outside the executing worker. Its scope-bound observer grant
12
+ comes from protected control-plane configuration, not from the submitted proof.
13
+
14
+ `verifyCleanupFollowup` validates the signature against that configuration and
15
+ the complete expected manifest. It rejects unknown/revoked keys, executing-worker
16
+ signers, altered bindings, changed resource/effect closure, unresolved effects,
17
+ missing or wrong-kind observations, duplicate identities and stale/future evidence.
18
+ The evidence window is at most five minutes. Status-only HTTP absence requires a
19
+ GET/HEAD observation returning 404 or 410; a 200 response cannot qualify.
20
+
21
+ The signature includes the algorithm, key ID and follow-up under the
22
+ `tracegrove.signed-cleanup-followup/v1` domain separator. The signature field is
23
+ excluded from signed bytes; the returned proof digest covers the complete envelope.
24
+ The expectation digest includes every expectation field. Base64url signatures
25
+ must use canonical unpadded encoding. Key IDs select configured public keys;
26
+ the verifier never trusts a public key carried by the proof itself.
27
+
28
+ `deriveCleanupExpectation` combines the current coordination snapshot with the
29
+ protected ownership record. Missing host inventory prevents derivation. Admitted
30
+ effects without independent resolution remain unresolved; extra effects and
31
+ duplicate resources are refused. Takeover derives the current worker and fence
32
+ while retaining prior resource identities. `ownershipLedgerHeadDigest` anchors
33
+ the expectation to the exact canonical ledger event, including issuer receipts.
34
+ The helper cannot establish that caller-supplied files came from that ledger.
35
+
36
+ ## Offline inspection
37
+
38
+ ```sh
39
+ workflow-verify verify-cleanup --proof followup.json \
40
+ --expectation expected.json --trust observers.json --json
41
+ ```
42
+
43
+ The trust file uses this shape, containing public keys only:
44
+
45
+ ```json
46
+ {
47
+ "schemaVersion": "workflow.cleanup-observers/v1",
48
+ "observers": [{
49
+ "keyId": "configured-collector-key",
50
+ "scopeId": "workspace-scope",
51
+ "observerId": "independent-collector",
52
+ "publicKeyPem": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n"
53
+ }]
54
+ }
55
+ ```
56
+
57
+ Exit 0 means the supplied files pass signature and expectation checks. Exit 2
58
+ means validation failed. JSON output always reports `hostedReleaseAdmitted: false`.
59
+ Inputs are limited to 4 MiB per file. A local trust file is useful for inspection
60
+ and cannot configure a hosted authority or provision a signing key.
61
+
62
+ ## Remaining hosted requirements
63
+
64
+ The control plane must independently establish ownership and provider receipts,
65
+ qualify the collector and provision/revoke its protected signing authority.
66
+ The storage owner must load the current expectation and lease, recheck time and
67
+ fencing under its admission lock, then append cleanup admission and persona
68
+ release atomically. This verifier does not implement that storage transaction,
69
+ prove provider absence from a digest alone, or authorize compensation actions.
70
+ Worker release through the ordinary coordination port remains refused.
71
+
72
+ Local tests use ephemeral keys. One native HTTP case rejects observed presence,
73
+ deletes an owned test resource and verifies a separately observed absence; it is
74
+ local conformance evidence, not a qualified staging or provider receipt.
@@ -0,0 +1,315 @@
1
+ # Tracegrove developer UX redesign
2
+
3
+ Status: phase 1 is implemented in the draft PR (see Phasing). Node, FastAPI and Django samples pass end to end through it.
4
+
5
+ ## The problem today
6
+
7
+ Writing one HTTP test for the notes sample takes **19 YAML files across 13 folders** (`workflow.yaml`, suite, case, persona, auth recipe, component profile with a hand-pinned sha256, environment plan, host plan, runner, surface pack, surface binding, fidelity profile, intelligence policy, action registry, seed recipe, fixture plan, a materialized payload with a pinned digest, …). Every file carries `schemaVersion`, `ref.id` and `ref.revision`. Running it is four commands (`doctor`, `plan --output request.json`, `run --request`, `verify-bundle`) and the results land in `.workflow-verify/executions/<uuid>/`, a folder name nobody can find again.
8
+
9
+ The kernel underneath (frozen corpus, digests, independent readback, owned cleanup, sealed bundles) is the valuable part, and it stays exactly as it is. What is missing is a front door.
10
+
11
+ ## Design principles
12
+
13
+ 1. **One config, one file per test.** Everything else is derived, with an escape hatch to the strict v1 corpus when you need it.
14
+ 2. **Convention over configuration.** Paths, ids, names and defaults come from where files live. Nothing has an id you have to invent.
15
+ 3. **Compile, don't replace.** The new files compile into the existing `workflow.*/v1` documents, so every guarantee (digests, attestation, cleanup proof, `verify-bundle`) still holds and the evidence is identical in kind.
16
+ 4. **One command to run.** `tracegrove test` plans, runs, reports and verifies. The frozen request is still written, just not by you.
17
+ 5. **Framework presets, not framework plugins.** FastAPI, Django and Node are a few lines of launch defaults, not a dependency on the user's stack.
18
+ 6. **Results you can find.** Human-named run folders, a `latest` pointer, Markdown + JSON + JUnit next to the sealed bundle.
19
+
20
+ ## What a user's repo looks like
21
+
22
+ ```text
23
+ my-app/
24
+ tracegrove.config.yaml # the only config file
25
+ tracegrove/ # tests live here (configurable: testDir)
26
+ notes/
27
+ create-read-delete.flow.yaml
28
+ authz.flow.yaml
29
+ fixtures/
30
+ existing-note.fixture.yaml
31
+ .tracegrove/ # generated, gitignored
32
+ runs/
33
+ 2026-10-16T14-22-03Z_pass_3f9a1c/
34
+ summary.md summary.json junit.xml bundle/
35
+ latest -> 2026-10-16T14-22-03Z_pass_3f9a1c
36
+ compiled/ # the derived v1 corpus, for inspection or ejection
37
+ state/ # ledger
38
+ ```
39
+
40
+ ## Naming conventions
41
+
42
+ | Thing | Convention | Derived id |
43
+ | --- | --- | --- |
44
+ | Test file | `tracegrove/<area>/<behavior>.flow.yaml`, kebab-case | case id `<area>.<behavior>` |
45
+ | Fixture file | `tracegrove/fixtures/<name>.fixture.yaml` | entity key `<name>` |
46
+ | Step | `name:` in plain words, optional | `snake_case(name)`, else `<method>_<n>` |
47
+ | Assertion | from a step's `expect:` | `<step>.expect` |
48
+ | Persona | key under `personas:` | credential `<persona>_token` |
49
+ | Saved value | `save: { noteId: note.id }` | referenced as `{noteId}` anywhere later |
50
+ | Fixture output | `{existing.noteId}` | input from fixture `existing`, output `noteId` |
51
+ | Tags | `tags: [smoke, authz]` | coverage tags; filter with `--tag` |
52
+ | Run folder | `<UTC timestamp>_<outcome>_<short execution id>` | sortable, greppable |
53
+
54
+ ## The config file
55
+
56
+ ```yaml
57
+ # tracegrove.config.yaml
58
+ project: notes
59
+ app:
60
+ adapter: node # node | fastapi | django | command
61
+ entry: app/app.mjs # node: script; fastapi: module:app; django: manage.py dir
62
+ health: /health
63
+ sources: [app/**] # files whose digest is attested as "what was tested"
64
+ env:
65
+ NOTES_BUILD: sample
66
+ inject: # where tracegrove hands the app its port, data dir and tokens
67
+ port: PORT
68
+ dataDir: NOTES_DIR
69
+ tokens: NOTES_TOKENS
70
+ personas:
71
+ owner: { subject: alice } # first persona is the default caller
72
+ intruder: { subject: bob }
73
+ ```
74
+
75
+ Defaults when omitted: `testDir: tracegrove`, `inject` = `PORT`, `TRACEGROVE_DATA_DIR`, `TRACEGROVE_TOKENS`, `health: /health`, deadline 60 s, sources = all tracked-looking files under the app dir excluding `node_modules`, `.venv`, `__pycache__`, `.git`, `.tracegrove`.
76
+
77
+ ## Adapter presets
78
+
79
+ | `adapter` | Launch it compiles to | Notes |
80
+ | --- | --- | --- |
81
+ | `node` | `node <entry>` with `PORT` set | Any Express/Fastify/Hono/Nest app that reads `PORT`. |
82
+ | `fastapi` | `<python> -m uvicorn <entry> --host 127.0.0.1 --port {port}` | `python:` defaults to `.venv/bin/python` if present, else `python3`. |
83
+ | `django` | `<python> manage.py migrate --noinput && <python> manage.py runserver 127.0.0.1:{port} --noreload` | Point `DATABASES` at `TRACEGROVE_DATA_DIR` for a fresh database per run (the sample does). |
84
+ | `command` | Reserved for a qualified application-runtime adapter | Currently BLOCKED: a shell wrapper cannot attest the application interpreter. |
85
+
86
+ `{port}` and `{dataDir}` are substituted in `args` and `env` values. Tracegrove picks a free loopback port itself (the "assigned" port mode), so apps no longer need to print `listening <port>`.
87
+
88
+ **Auth hook.** Tracegrove issues a random bearer token per persona per run and passes `{token: subject}` as JSON in the `tokens` env var. The app adds about five lines in test mode to accept them:
89
+
90
+ ```python
91
+ # FastAPI
92
+ tokens = json.loads(os.environ.get("TRACEGROVE_TOKENS", "{}"))
93
+ def current_user(authorization: str = Header("")):
94
+ sub = tokens.get(authorization.removeprefix("Bearer "))
95
+ if not sub: raise HTTPException(401)
96
+ return sub
97
+ ```
98
+
99
+ ```python
100
+ # Django middleware
101
+ TOKENS = json.loads(os.environ.get("TRACEGROVE_TOKENS", "{}"))
102
+ def tracegrove_auth(get_response):
103
+ def mw(request):
104
+ sub = TOKENS.get(request.headers.get("Authorization", "").removeprefix("Bearer "))
105
+ if sub: request.user = User.objects.get_or_create(username=sub)[0]
106
+ return get_response(request)
107
+ return mw
108
+ ```
109
+
110
+ ```js
111
+ // Express
112
+ const tokens = JSON.parse(process.env.TRACEGROVE_TOKENS ?? '{}');
113
+ app.use((req, _res, next) => { req.user = tokens[(req.headers.authorization ?? '').slice(7)]; next(); });
114
+ ```
115
+
116
+ `tracegrove init` prints the right snippet for the detected framework.
117
+
118
+ ## A test
119
+
120
+ ```yaml
121
+ # tracegrove/notes/create-read-delete.flow.yaml
122
+ title: Create a note, read it back, keep other notes intact, delete it
123
+ risk: critical # critical | standard (default) | exploratory
124
+ tags: [notes]
125
+ given:
126
+ existing: existing-note # tracegrove/fixtures/existing-note.fixture.yaml
127
+ steps:
128
+ - name: create
129
+ POST: /notes
130
+ json: { title: Fresh note, body: Written through the real API. }
131
+ expect: { status: 201 }
132
+ save: { noteId: note.id }
133
+
134
+ - name: read back
135
+ GET: /notes/{noteId}
136
+ observe: true # independent readback, polled until it holds
137
+ expect: { status: 200, json: { note.title: Fresh note } }
138
+
139
+ - name: intruder is denied
140
+ GET: /notes/{noteId}
141
+ as: intruder
142
+ expect: { status: 403, absent: [note] }
143
+
144
+ - name: delete
145
+ DELETE: /notes/{noteId}
146
+ expect: { status: 204 }
147
+
148
+ - name: gone
149
+ GET: /notes/{noteId}
150
+ observe: true
151
+ expect: { status: 404 }
152
+
153
+ - name: existing note untouched
154
+ GET: /notes/{existing.noteId}
155
+ observe: true
156
+ expect: { status: 200, json: { note.title: Existing note } }
157
+ ```
158
+
159
+ Rules: one HTTP verb key per step; use block style (or quotes) for values containing `{` or `[`, because YAML reads them as inline maps and lists; `json:` is the request body; `expect.json` keys are dot paths into the response body; `absent` lists paths that must not exist; the effect envelope (allowed methods, path prefixes, max creates) is derived from the steps and fixtures, so the safety rails stay on without being written by hand.
160
+
161
+ ## A fixture
162
+
163
+ ```yaml
164
+ # tracegrove/fixtures/existing-note.fixture.yaml
165
+ create:
166
+ POST: /notes
167
+ json: { title: Existing note, body: { words: 6 } }
168
+ expect: 201
169
+ save: { noteId: note.id }
170
+ readback:
171
+ GET: /notes/{noteId}
172
+ expect: { status: 200, json: { note.title: Existing note } }
173
+ cleanup:
174
+ DELETE: /notes/{noteId}
175
+ expect: 204
176
+ gone: { GET: "/notes/{noteId}", status: 404 }
177
+ ```
178
+
179
+ `{ words: 6 }` uses the deterministic generator; the logical payload is materialized at compile time, so there is no digest to paste.
180
+
181
+ ## TypeScript authoring
182
+
183
+ Use `tracegrove.config.ts` instead of the YAML config for editor completion and
184
+ shared constants. Flows and fixtures can independently use `.flow.ts` and
185
+ `.fixture.ts`; YAML and TypeScript files can coexist when their logical names
186
+ differ. They all compile through the same Zod schemas into the same corpus.
187
+
188
+ ```ts
189
+ // tracegrove.config.ts
190
+ import { defineConfig } from 'workflow-verify/authoring';
191
+
192
+ export default defineConfig({
193
+ project: 'notes',
194
+ app: { adapter: 'node', entry: 'app/app.mjs' },
195
+ personas: { owner: { subject: 'alice' } },
196
+ });
197
+ ```
198
+
199
+ ```ts
200
+ // tracegrove/notes/health.flow.ts
201
+ import { flow } from 'workflow-verify/authoring';
202
+
203
+ export default flow({
204
+ title: 'The application is ready',
205
+ steps: [{ GET: '/health', expect: 200 }],
206
+ });
207
+ ```
208
+
209
+ `fixture({...})` supplies the same editor types for fixture recipes. The helpers
210
+ preserve input values; the ordinary compiler validates and fills defaults. Run
211
+ your TypeScript checker for editor contracts and `tracegrove check` for canonical
212
+ runtime validation. `test`, `list`, `compile`, discovery and Grove use either
213
+ config format. `init` preserves an existing TypeScript config.
214
+
215
+ TypeScript authoring executes trusted project code, including during `check` and
216
+ discovery; it is outside the application sandbox. Each module loads in a fresh
217
+ Node process so edits to imported helpers are seen on the next compilation.
218
+ Evaluation is limited to five seconds and a 1 MiB JSON-compatible default export.
219
+ Console output does not contaminate CLI JSON. Errors report the failing module
220
+ without forwarding arbitrary module diagnostics.
221
+
222
+ Use Node 22's erasable TypeScript: include extensions on relative imports and use
223
+ `import type` for types. Enums, parameter properties, JSX, and tsconfig path aliases
224
+ are not transformed. The package's Node version requirement still applies. Keep
225
+ one project config; discovery rejects competing YAML and TypeScript configs.
226
+ An explicit `--config` on `test`, `list`, or `compile` selects a format when both
227
+ are intentionally present.
228
+
229
+ ## Command reference
230
+
231
+ ```text
232
+ tracegrove init detect FastAPI / Django / Node, write config + an example flow + .gitignore entry
233
+ tracegrove test [--grep notes] [--tag smoke] [--json]
234
+ compile, plan, run, write the run folder, verify the bundle
235
+ tracegrove list list flows with their derived ids, tags and steps
236
+ tracegrove show [--run latest] print a run's summary
237
+ tracegrove compile write the derived v1 corpus to .tracegrove/compiled (to inspect or eject)
238
+ ```
239
+
240
+ Exit codes are unchanged (0 pass, 1 assertion failure, 2 blocked, 3 infrastructure, 4 cancelled). `workflow-verify` and all of its low-level commands keep working; the compiled folder is a normal `workflow.yaml` project, so `workflow-verify plan --config .tracegrove/compiled/workflow.yaml` still works.
241
+
242
+ ## Output a human reads first
243
+
244
+ ```text
245
+ tracegrove · notes · app sha 3e8d13bc9bd1
246
+
247
+ PASS notes.create-read-delete 6 steps 28 ms
248
+ FAIL notes.authz 3 steps 14 ms
249
+ step "intruder is denied": expected status 403, got 200
250
+ GET /notes/9c1e… -> 200 {"note":{"id":"9c1e…","title":"Fresh note"}}
251
+ ERROR notes.crud 5 steps 0 ms
252
+ (app startup): application exited before becoming ready; last app output:
253
+ | ERROR: Error loading ASGI app. Could not import module "app.mian".
254
+
255
+ 1 passed, 1 failed · run .tracegrove/runs/2026-10-16T14-22-03Z_fail_3f9a1c
256
+ ```
257
+
258
+ `summary.md` carries the same table plus per-step request/response excerpts; `junit.xml` lets GitHub Actions, GitLab and Buildkite annotate failures with no plugin.
259
+
260
+ ## Forking it into your own repo
261
+
262
+ 1. `npm i -D tracegrove` once it is published (today: install the packed archive, as the `tracegrove-notes-api` repo does).
263
+ 2. `npx tracegrove init` writes `tracegrove.config.yaml`, `tracegrove/example.flow.yaml` and adds `.tracegrove/` to `.gitignore`.
264
+ 3. Paste the printed auth snippet into the app's test-mode auth.
265
+ 4. `npx tracegrove test`.
266
+ 5. CI: one step, `npx tracegrove test`, then upload `.tracegrove/runs/latest` as an artifact.
267
+
268
+ ## Phasing
269
+
270
+ | Phase | Scope | In the draft PR |
271
+ | --- | --- | --- |
272
+ | 1 | Config + flow + fixture compiler, node/fastapi/django presets, assigned port mode, app-output-on-startup-failure, `test`/`list`/`compile`/`show`/`init`, run folders with summary.md/json/junit, Node/FastAPI/Django samples | Yes; generic command host remains unqualified |
273
+ | 2 | `lanes:` with an offline mock lane compiled from recorded responses; `--update-snapshots` to record them | No |
274
+ | 3 | `tracegrove.config.ts` with `defineConfig`, `flow()` and `fixture()` for editor completion; canonical JSON Schema for YAML | Implemented through the shared compiler; no alternative executor |
275
+ | 4 | Login-recipe personas (POST /login, cookie or token capture) for apps whose auth can't be patched; external `url:` targets with declared, unverified identity | No |
276
+ | 5 | Browser surface using shared typed `browser:` commands, independent DOM/API checks, and verified Grove recording playback | Implemented locally; staging qualification remains open |
277
+
278
+ ## Structured command failures
279
+
280
+ An uncaught command failure with `--json`, `--json true` or `--json=true` writes one
281
+ `tracegrove.cli-error/v1` result to stdout and no exception diagnostic to stderr. The strict
282
+ schema is exported as `schema/tracegrove_cli-error_v1.json` and `CliErrorReport` from the
283
+ protocol package. For example, `tracegrove run --json` returns exit 2 and:
284
+
285
+ ```json
286
+ {"schemaVersion":"tracegrove.cli-error/v1","command":"run","errorClass":"blocked","exitCode":2,"reasons":[{"code":"missing_argument","message":"A required option or option value is missing.","recovery":"Run tracegrove help and correct the command options."}],"omittedReasonCount":0}
287
+ ```
288
+
289
+ Messages and recovery actions come from a controlled public vocabulary. Raw exception text,
290
+ stacks, supplied argument values, configuration contents and arbitrary internal reason codes
291
+ are omitted. At most 32 reasons are returned; `omittedReasonCount` reports any remainder.
292
+ Unknown prerequisites use `prerequisite_unavailable`. Unknown command names become `command: null`.
293
+ This trades detailed candidate diagnostics for a bounded machine result; keep private evidence
294
+ under its existing access policy when investigating a failure.
295
+
296
+ Existing process exit statuses are preserved: blocked/conflict/schema failures use 2;
297
+ infrastructure and unexpected failures use 3. A top-level JSON parse failure retains its legacy
298
+ exit 3 with `errorClass: invalid_input` and `invalid_json`. The report's exit code equals the
299
+ process status. It does not assert that execution never started or authorize a retry: a failure
300
+ can follow partial effects, and uncertain ownership must be reconciled before replay.
301
+
302
+ Doctor retains `tracegrove.doctor/v1`. Completed test/run results and assertion failures retain
303
+ their existing JSON and exit codes 0/1/2/3/4. Returned check/verification results keep their existing
304
+ schemas. `--json false` and `--json=false` keep prose errors, and `--jsonl` keeps its existing event
305
+ stream and top-level error behavior. Successful reports, doctor reports and artifacts are outside
306
+ this error envelope's omission policy; this change establishes no artifact redaction guarantee.
307
+
308
+ ## Found along the way
309
+
310
+ - The bundle verifier re-derived "infrastructure failed" only from step reason codes, so any run whose app never started produced a bundle that failed its own verification. The PR fixes this by also reading the sealed `host.failed` event; that evidence can only move a cell away from passed.
311
+
312
+ ## Open questions for Hope
313
+
314
+ - Package and binary name: `tracegrove` for both (recommended), keeping `workflow-verify` as an alias.
315
+ - Default test folder: `tracegrove/` (recommended) versus `tests/tracegrove/` to sit beside pytest/jest.