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,616 @@
1
+ /**
2
+ * Trusted executor: admits a frozen request, prepares each selected cell on its host, applies
3
+ * fixtures through registered actions, runs compiled steps through the surface driver, collects
4
+ * boundary/host/identity observations and artifacts, cleans owned resources and seals a receipt.
5
+ * The reducer derives every verdict; drivers and hosts only supply observations.
6
+ */
7
+ import { lstatSync, mkdirSync } from 'node:fs';
8
+ import { join, resolve } from 'node:path';
9
+ import { ActionRegistry, AuthRecipe, BoundaryObservation, BudgetReservation, CampaignFixturePlan, CaseFixturePlan, CaseSpec, CostObservation, CredentialLease, EnvironmentBinding, EnvironmentPlan, ExecutionReceipt, FidelityPlan, FixtureManifest, HostPlan, IntelligencePolicy, LogicalPayload, MockResponses, NativeJobAction, McpToolCall, Persona, RoutingDecision, SeedRecipe, SelectionManifest, SurfaceBinding, digestOfValue, freeze, parseAs, refKey, sameDigest, selfDigest, verifySelfDigest, } from "../protocol/index.js";
10
+ import { HttpDriver, HttpStepError, bearerFor, captureValues, redactObservation } from "../adapters/http/driver.js";
11
+ import { NativeJobError } from "../adapters/job/driver.js";
12
+ import { BrowserStepError } from "../adapters/browser/driver.js";
13
+ import { CaseBrowserSession } from "../adapters/browser/session.js";
14
+ import { LocalProcessHost } from "../hosts/local.js";
15
+ import { MockLoopbackHost } from "../hosts/mock.js";
16
+ import { LocalArtifactStore } from "./artifacts.js";
17
+ import { collectCleanup } from "./cleanup.js";
18
+ import { readVerifiedBundle, writeExecutionBundle } from "./bundle.js";
19
+ import { checkCommittedExecutionBinding } from "./executionReadback.js";
20
+ import { requireRealDirectory, syncDirectory } from "./atomicFiles.js";
21
+ import { isoPlusMs, monotonicMs, newId, nowIso } from "./clock.js";
22
+ import { applyTemplateDeep } from "./compiler.js";
23
+ import { Deadline } from "./deadline.js";
24
+ import { Blocked, Conflict, InfrastructureFailure, isInfrastructureStepFailure } from "./errors.js";
25
+ import { EventLog } from "./events.js";
26
+ import { ExecutionOwnership, assertInterruptedOwnershipResolved } from "./executionOwnership.js";
27
+ import { checkedFrozenRequest, prepareFrozenCells } from "./executionPreparation.js";
28
+ import { REDUCER_REF, compareTargets, evaluateAssertions, evaluatePredicate, reduceCampaign, reduceCell } from "./reducer.js";
29
+ import { targetFromComponentAttestations } from "./targetObservation.js";
30
+ import { authorizeQualificationExecution } from "./qualificationExecution.js";
31
+ export const EXIT_CODES = { passed: 0, assertion_failed: 1, blocked: 2, inconclusive: 2, infrastructure_failed: 3, cancelled: 4 };
32
+ function ownerFor(scope) {
33
+ return scope.ownerId;
34
+ }
35
+ /** Readback reconciles a local commit; it never acquires resources or trusts cached PASS/summary. */
36
+ function committedRunSummary(input) {
37
+ const { executionId, attemptId, generation, attemptNumber, request, selection, scope, ledger } = input;
38
+ if (!/^[A-Za-z0-9_-]+$/.test(executionId) || !Number.isInteger(generation) || generation < 1 || !Number.isInteger(attemptNumber) || attemptNumber < 1)
39
+ throw new Conflict('committed_execution_binding_invalid');
40
+ const executionDir = join(input.stateDir, 'executions', executionId);
41
+ let checked;
42
+ try {
43
+ requireRealDirectory(executionDir);
44
+ checked = readVerifiedBundle(executionDir);
45
+ }
46
+ catch {
47
+ throw new Conflict('committed_execution_evidence_invalid; preserve the existing execution and reconcile its missing or corrupt evidence');
48
+ }
49
+ checkCommittedExecutionBinding(ledger, checked, { executionId, attemptId, generation, attemptNumber, scope, campaignId: request.campaignId,
50
+ requestDigest: request.ref.digest.hex, requestRef: request.ref, selectionRef: selection.ref });
51
+ return { executionId, attemptId, generation, campaignId: request.campaignId, outcome: checked.campaign.outcome,
52
+ exitCode: EXIT_CODES[checked.campaign.outcome], reasonCodes: [...new Set(checked.receipts.flatMap(receipt => receipt.reasonCodes))],
53
+ receipts: checked.receipts, campaign: checked.campaign, executionDir, redelivered: true };
54
+ }
55
+ function hasCommittedManifest(executionDir) {
56
+ try {
57
+ lstatSync(join(executionDir, 'manifest.json'));
58
+ return true;
59
+ }
60
+ catch (error) {
61
+ if (error.code === 'ENOENT')
62
+ return false;
63
+ throw new Conflict('committed_execution_evidence_unreadable');
64
+ }
65
+ }
66
+ export async function executeBundle(options) {
67
+ const { bundle, stateDir, ledger, scope } = options;
68
+ const signal = options.signal ?? new AbortController().signal;
69
+ const request = checkedFrozenRequest(bundle, scope);
70
+ if ((request.purpose === 'qualification' || request.purpose === 'regression' || request.sourcePlanRef || request.reviewRef || request.scenarioRefs.length || request.qualificationRoundRef) &&
71
+ !(request.purpose === 'qualification' && options.qualification)) {
72
+ throw new Blocked([{ code: 'scenario_lifecycle_unavailable', detail: 'qualification requires an authenticated runtime owner; source trials and activated regression admission are unavailable' }]);
73
+ }
74
+ const { docs, selection, fidelityPlan, campaignFixturePlan, intelligencePolicy, prepared } = prepareFrozenCells(bundle, scope, request);
75
+ // Idempotent admission: the same frozen key reconciles the existing execution.
76
+ const qualification = options.qualification && request.purpose === 'qualification'
77
+ ? await authorizeQualificationExecution(options.qualification, request, selection, ledger, null) : null;
78
+ if (qualification && resolve(join(stateDir, 'ledger')) !== resolve(ledger.dir))
79
+ throw new Conflict('qualification state directory must belong to the registration owner ledger');
80
+ const idemAggregate = qualification ? `qualification-execution:${qualification.admission.ref.digest.hex}` : `idempotency:${request.idempotencyKey}`;
81
+ const existing = ledger.current(idemAggregate);
82
+ let predecessor = null;
83
+ let attemptNumber = 1;
84
+ if (existing) {
85
+ const admissionHistory = qualification ? ledger.history(idemAggregate) : ledger.history(`execution:${String(existing.data.executionId)}`);
86
+ const admitted = admissionHistory.find((entry) => entry.type === 'admitted');
87
+ const executionId = qualification ? String(admitted?.data.executionId) : String(existing.data.executionId);
88
+ if (admitted?.data.requestDigest !== request.ref.digest.hex)
89
+ throw new Conflict('idempotency key is already bound to a different frozen request');
90
+ if (qualification && admitted?.data.stateDir !== resolve(stateDir))
91
+ throw new Conflict('qualification execution is already bound to another state directory');
92
+ const state = qualification ? existing : ledger.current(`execution:${executionId}`);
93
+ const binding = { executionId, attemptId: String(admitted?.data.attemptId), generation: Number(admitted?.data.generation),
94
+ campaignId: request.campaignId, requestDigest: request.ref.digest.hex, scope };
95
+ const checkedSummary = () => committedRunSummary({ stateDir, ledger, request, selection, scope, executionId,
96
+ attemptId: binding.attemptId, generation: binding.generation, attemptNumber: Number(admitted?.data.attemptNumber) });
97
+ if (qualification) {
98
+ // Qualification rounds bind per-cell allocations on the registration owner's ledger; they never replay or self-recover.
99
+ if (state && state.type === 'finalized')
100
+ return { ...state.data.summary, redelivered: true };
101
+ throw new Conflict('qualification attempt is incomplete; reconcile it instead of replaying allocated effects');
102
+ }
103
+ if (state && state.type === 'finalized') {
104
+ return checkedSummary();
105
+ }
106
+ if (!state || state.type !== 'interrupted')
107
+ throw new Conflict(`request ${request.idempotencyKey} is already in flight as ${executionId} (${state?.type ?? 'missing execution state'}); redelivery reconciles, it does not start another attempt`);
108
+ assertInterruptedOwnershipResolved(ledger, binding);
109
+ if (hasCommittedManifest(join(stateDir, 'executions', executionId))) {
110
+ const recovered = checkedSummary();
111
+ // A crashed publisher may have linked the valid manifest before syncing its directory.
112
+ try {
113
+ syncDirectory(recovered.executionDir);
114
+ }
115
+ catch {
116
+ throw new Conflict('committed_execution_durability_unconfirmed; preserve the committed bytes; no acquisition was replayed');
117
+ }
118
+ ledger.append(`execution:${executionId}`, state.version, 'finalized', { outcome: recovered.outcome, campaignResultRef: recovered.campaign.ref,
119
+ receiptRef: recovered.receipts[0]?.ref ?? null, recoveredFromCommittedBundle: true, summary: { ...recovered, receipts: [], redelivered: false } });
120
+ return recovered;
121
+ }
122
+ predecessor = state?.data.receiptRef ?? null;
123
+ attemptNumber = Number(existing.data.attemptNumber ?? 1) + 1;
124
+ }
125
+ if (request.limits.costCeilingCents < bundle.estimatedCostCents)
126
+ throw new Blocked([{ code: 'insufficient_budget_headroom', detail: `estimate ${bundle.estimatedCostCents} > ceiling ${request.limits.costCeilingCents}` }]);
127
+ const executionId = qualification?.admission.attempts[0].executionId ?? newId('exec');
128
+ const attemptId = qualification?.admission.attempts[0].attemptId ?? newId('attempt');
129
+ if (qualification && ledger.current(`execution:${executionId}`))
130
+ throw new Conflict('qualification allocation was already claimed; reconcile its execution');
131
+ const generation = 1;
132
+ const executionDir = join(stateDir, 'executions', executionId);
133
+ mkdirSync(join(stateDir, 'executions'), { recursive: true });
134
+ mkdirSync(executionDir, { recursive: !qualification });
135
+ const executionAggregate = qualification ? idemAggregate : `execution:${executionId}`;
136
+ const reservation = parseAs(BudgetReservation, freeze({
137
+ schemaVersion: 'workflow.budget-reservation/v1', ref: { id: `${executionId}.reservation`, revision: '1' }, scope,
138
+ campaignId: request.campaignId, executionId, attemptId, actionCents: request.limits.costCeilingCents, cleanupCents: 0, uncertainCents: 0, state: 'reserved', reservedAt: nowIso(),
139
+ }), 'budget reservation');
140
+ ledger.append(executionAggregate, 0, 'admitted', { requestDigest: request.ref.digest.hex, idempotencyKey: request.idempotencyKey, executionId, attemptId, generation, attemptNumber, reservation: reservation.ref,
141
+ ...(qualification ? { stateDir: resolve(stateDir), qualificationRoundRef: qualification.admission.ref } : {}) });
142
+ if (!qualification)
143
+ ledger.append(idemAggregate, existing ? existing.version : 0, 'bound', { executionId, attemptNumber });
144
+ const ownership = new ExecutionOwnership(ledger, { executionId, attemptId, generation, campaignId: request.campaignId, requestDigest: request.ref.digest.hex, scope });
145
+ ownership.initialize();
146
+ const artifacts = new LocalArtifactStore(join(stateDir, 'artifacts'));
147
+ const campaignDeadline = Deadline.in(request.limits.deadlineMs);
148
+ const receipts = [];
149
+ const hosts = { local: options.hosts?.local ?? new LocalProcessHost(), mock: options.hosts?.mock ?? new MockLoopbackHost() };
150
+ let phaseVersion = ledger.version(executionAggregate);
151
+ for (const item of prepared) {
152
+ const allocation = qualification?.admission.attempts.find(a => a.selectionCellId === item.cell.selectionCellId);
153
+ const beforeEffect = qualification && options.qualification ? async () => {
154
+ try {
155
+ await authorizeQualificationExecution(options.qualification, request, selection, ledger, item.cell.selectionCellId);
156
+ }
157
+ catch {
158
+ throw new HttpStepError('qualification_authority_unavailable', 'Qualification registration, source, state or effect authority is no longer current');
159
+ }
160
+ } : undefined;
161
+ const receipt = await runCell({ item, request, selection, fidelityPlan, campaignFixturePlan, intelligencePolicy, docs, scope,
162
+ executionId: allocation?.executionId ?? executionId, attemptId: allocation?.attemptId ?? attemptId,
163
+ generation, attemptNumber, predecessor, reservation, campaignDeadline, signal, artifacts, ownership, executionDir, hosts, bundle, onEvent: options.onEvent, beforeEffect });
164
+ receipts.push(receipt);
165
+ phaseVersion = ledger.append(executionAggregate, phaseVersion, 'cell.finalized', { selectionCellId: item.cell.selectionCellId, outcome: receipt.outcome, receiptRef: receipt.ref }).version;
166
+ }
167
+ const campaign = reduceCampaign({ scope, campaignId: request.campaignId, requestRef: request.ref, selection, receipts });
168
+ writeExecutionBundle({ dir: executionDir, bundle, request, selection, receipts, campaign });
169
+ const summary = {
170
+ executionId, attemptId, generation, campaignId: request.campaignId, outcome: campaign.outcome, exitCode: EXIT_CODES[campaign.outcome],
171
+ reasonCodes: [...new Set(receipts.flatMap((r) => r.reasonCodes))], receipts, campaign, executionDir, redelivered: false,
172
+ };
173
+ ledger.append(executionAggregate, phaseVersion, 'finalized', { outcome: campaign.outcome, campaignResultRef: campaign.ref, receiptRef: receipts[0]?.ref ?? null, summary: { ...summary, receipts: [], campaign } });
174
+ return summary;
175
+ }
176
+ async function runCell(ctx) {
177
+ const { item, request, scope, executionId, attemptId, generation, signal } = ctx;
178
+ const { spec, compiled, cell, hostPlan, environmentPlan, authRecipe, fidelityCell } = item;
179
+ const log = new EventLog(executionId, attemptId, generation, (event) => ctx.onEvent?.({ kind: event.kind, stepId: event.stepId, redactedPayload: event.redactedPayload, at: event.at }));
180
+ const startedAt = nowIso();
181
+ const cellDeadline = ctx.campaignDeadline.child(spec.limits.deadlineMs);
182
+ const blockedReasons = [];
183
+ const stepObservations = [];
184
+ let session = null;
185
+ let fixtureManifest = null;
186
+ let fixtureState = item.fixture ? 'unknown' : 'not_required';
187
+ let infrastructureFailure = false;
188
+ let cancelled = false;
189
+ const allocated = [];
190
+ const uncertainAllocations = new Set();
191
+ const fixtureOutputs = {};
192
+ const costs = [];
193
+ const hostStartedMs = monotonicMs();
194
+ log.emit('cell.started', null, { selectionCellId: cell.selectionCellId, caseId: spec.ref.id, caseDigest: spec.ref.digest.hex, lane: fidelityCell.lane });
195
+ const credentialNames = [...new Set([...(authRecipe.credentialName ? [authRecipe.credentialName] : []), ...compiled.credentialNames])];
196
+ const workspaceDir = join(ctx.executionDir, 'host', cell.selectionCellId.replace(/[^A-Za-z0-9._-]/g, '_'));
197
+ const hostOwnershipKey = `host:${cell.selectionCellId}`;
198
+ ctx.ownership.reserve(hostOwnershipKey, 'host', cell.selectionCellId, hostPlan.ref);
199
+ mkdirSync(workspaceDir, { recursive: true });
200
+ const host = hostPlan.adapter === 'mock_loopback' ? ctx.hosts.mock : ctx.hosts.local;
201
+ const mockResponses = hostPlan.mockResponsesRef ? ctx.docs.get(MockResponses, hostPlan.mockResponsesRef, 'mock responses') : null;
202
+ try {
203
+ if (ctx.beforeEffect)
204
+ await ctx.beforeEffect();
205
+ session = await host.start({ hostPlan, projectRoot: ctx.bundle.projectRoot, workspaceDir, scope, campaignId: request.campaignId, executionId, attemptId, generation, actorId: ownerFor(scope), credentialNames, signal, mockResponses });
206
+ ctx.ownership.observed(hostOwnershipKey, session.ownedResources.map(r => r.physicalId));
207
+ log.emit('host.started', null, { adapter: hostPlan.adapter, origin: session.origin, leaseRef: session.lease.ref, observationRef: session.observation.ref, attestations: session.attestations.map((a) => a.ref) });
208
+ }
209
+ catch (error) {
210
+ if (error instanceof Blocked)
211
+ blockedReasons.push(...error.reasons.map((r) => r.code));
212
+ else {
213
+ infrastructureFailure = true;
214
+ log.emit('host.failed', null, { error: String(error.message) });
215
+ }
216
+ }
217
+ // Host capability check: required capabilities need a probed, supported, current observation.
218
+ let requiredCapabilitiesObserved = false;
219
+ if (session) {
220
+ const supported = new Set(session.observation.capabilities.filter((c) => c.state === 'supported' && c.probe === 'probed').map((c) => c.capability));
221
+ const missing = hostPlan.requiredCapabilities.filter((c) => !supported.has(c));
222
+ requiredCapabilitiesObserved = missing.length === 0;
223
+ if (!requiredCapabilitiesObserved)
224
+ blockedReasons.push(`host_capability_unobserved:${missing.join('/')}`);
225
+ }
226
+ // Identity: compare expected component identities with launcher attestations.
227
+ let observedTarget = null;
228
+ let identityMatched = null;
229
+ if (session) {
230
+ observedTarget = targetFromComponentAttestations(cell.expectedTarget, session.attestations, hostPlan.launch, scope);
231
+ const comparison = compareTargets(cell.expectedTarget, observedTarget);
232
+ identityMatched = comparison.matched;
233
+ log.emit('identity.compared', null, { matched: comparison.matched, mismatches: comparison.mismatches });
234
+ if (comparison.matched === false)
235
+ blockedReasons.push('identity_mismatch');
236
+ if (comparison.matched === null)
237
+ blockedReasons.push('required_identity_unknown');
238
+ }
239
+ const credentialLease = parseAs(CredentialLease, freeze({
240
+ schemaVersion: 'workflow.credential-lease/v1', ref: { id: `${executionId}.${cell.selectionCellId}.credential-lease`, revision: '1' }, scope,
241
+ authRecipeRef: authRecipe.ref, personaRef: item.persona.ref, executionId, attemptId, credentialName: authRecipe.credentialName,
242
+ issuedBy: session ? (hostPlan.adapter === 'mock_loopback' ? 'environment' : 'local_launcher') : 'none', expiresAt: isoPlusMs(hostPlan.sessionLifetimeMs),
243
+ }), 'credential lease');
244
+ const origins = session ? environmentPlan.origins.map((o) => (o.startsWith('launch://') ? session.origin : o)) : environmentPlan.origins;
245
+ const provenance = fidelityCell.lane === 'mock_contract'
246
+ ? { runtime: 'mocked', data: 'mocked', provider: 'none', faults: 'none', interceptors: session?.interceptorRefs ?? [], injectedFaults: [] }
247
+ : { runtime: 'live', data: 'seeded_real', provider: 'none', faults: 'none', interceptors: [], injectedFaults: [] };
248
+ const environment = parseAs(EnvironmentBinding, freeze({
249
+ schemaVersion: 'workflow.environment/v1', ref: { id: `${executionId}.${cell.selectionCellId}.environment`, revision: '1' },
250
+ planRef: environmentPlan.ref, campaignId: request.campaignId, executionId, attemptId, generation, scope, class: environmentPlan.class, origins,
251
+ credentialLeaseRef: credentialLease.ref, actionEnvelopeRef: null, leaseExpiresAt: isoPlusMs(hostPlan.sessionLifetimeMs), budgetReservationRef: ctx.reservation.ref,
252
+ admissionEvidenceRefs: session ? [session.lease.ref, session.observation.ref, ...session.attestations.map((a) => a.ref)] : [],
253
+ expected: cell.expectedTarget, observed: observedTarget, provenance, networkProfileRef: null, clockProfileRef: null,
254
+ }), 'environment binding');
255
+ const driver = session ? new HttpDriver({ persona: authRecipe.credentialName ? session.credentials.get(authRecipe.credentialName) ?? null : null, named: Object.fromEntries(session.credentials) }, new Set([session.origin])) : null;
256
+ const origin = session?.origin ?? '';
257
+ const browser = new CaseBrowserSession({ origin, spec, persona: item.persona, bearer: authRecipe.credentialName ? session?.credentials.get(authRecipe.credentialName) ?? null : null,
258
+ onNetwork: observation => { log.emit('browser.network', null, observation); },
259
+ });
260
+ const runtimeVariables = { execution_nonce: attemptId, lease_namespace: cell.selectionCellId, target_origin: origin };
261
+ // ---- preparing: fixtures through registered actions with independent readback ----
262
+ if (item.fixture && session && driver && !infrastructureFailure && blockedReasons.length === 0) {
263
+ const { recipe, payload, registry } = item.fixture;
264
+ const order = topoOrder(recipe);
265
+ const manifestEntities = [];
266
+ const missing = [];
267
+ let failed = false;
268
+ for (const entityKey of order) {
269
+ if (failed) {
270
+ missing.push(entityKey);
271
+ continue;
272
+ }
273
+ if (signal.aborted) {
274
+ cancelled = true;
275
+ missing.push(entityKey);
276
+ continue;
277
+ }
278
+ const entity = recipe.entities.find((e) => e.entityKey === entityKey);
279
+ const logical = payload.entities.find((e) => e.entityKey === entityKey)?.values ?? {};
280
+ const variables = {};
281
+ for (const [name, value] of Object.entries(logical)) {
282
+ if (value && typeof value === 'object' && '$entity' in value) {
283
+ const v = value;
284
+ variables[name] = fixtureOutputs[v.$entity]?.[v.output];
285
+ }
286
+ else if (value && typeof value === 'object' && '$runtime' in value)
287
+ variables[name] = runtimeVariables[value.$runtime];
288
+ else
289
+ variables[name] = value;
290
+ }
291
+ const action = registry.actions.find((a) => a.actionId === entity.actionId);
292
+ const allocatingEvent = log.emit('fixture.allocating', null, { entityKey, actionId: action.actionId, effectKey: `${attemptId}:${entityKey}` });
293
+ try {
294
+ if (action.effect !== 'create')
295
+ throw new HttpStepError('fixture_ownership_unavailable', 'only a registered create action can allocate an owned fixture');
296
+ if (ctx.beforeEffect)
297
+ await ctx.beforeEffect();
298
+ ctx.ownership.reserve(`fixture:${cell.selectionCellId}:${entityKey}`, 'fixture', cell.selectionCellId, recipe.ref);
299
+ uncertainAllocations.add(entityKey);
300
+ const observation = await driver.request({ origin, method: action.method, path: action.path, body: action.body, auth: action.auth, variables, deadline: cellDeadline.child(10_000), signal });
301
+ if (action.expectStatus !== null && observation.status !== action.expectStatus)
302
+ throw new HttpStepError('unexpected_status', `${action.actionId} returned ${observation.status}, expected ${action.expectStatus}`);
303
+ const outputs = captureValues(observation, action.captures);
304
+ fixtureOutputs[entityKey] = { ...variables, ...outputs };
305
+ const observedId = outputs[entity.outputNames[0] ?? ''];
306
+ if (typeof observedId !== 'string' && !(typeof observedId === 'number' && Number.isFinite(observedId))) {
307
+ throw new HttpStepError('fixture_identity_unobserved', 'fixture allocation did not return a physical resource ID');
308
+ }
309
+ const parsedId = FixtureManifest.shape.entities.element.shape.physicalId.safeParse(String(observedId));
310
+ if (!parsedId.success)
311
+ throw new HttpStepError('fixture_identity_unobserved', 'captured fixture ID is invalid');
312
+ const physicalId = parsedId.data;
313
+ const cleanupHandle = entity.cleanup ? { actionId: entity.cleanup.actionId, args: { ...variables, ...outputs } } : null;
314
+ // Keep the observed cleanup handle in memory before any fallible acknowledgement/export callback.
315
+ allocated.push({ entityKey, physicalId, cleanup: cleanupHandle, absence: entity.cleanup ? entity.cleanup.absenceReadback : null });
316
+ ctx.ownership.observed(`fixture:${cell.selectionCellId}:${entityKey}`, [physicalId]);
317
+ const allocatedEvent = log.emit('fixture.allocated', null, { entityKey, physicalId, status: observation.status, requestId: observation.requestId, cleanupHandle }, { requestId: observation.requestId });
318
+ uncertainAllocations.delete(entityKey);
319
+ let readbackRefs = [];
320
+ if (entity.readback) {
321
+ const readAction = registry.actions.find((a) => a.actionId === entity.readback.actionId);
322
+ const readback = await driver.request({ origin, method: readAction.method, path: readAction.path, body: readAction.body, auth: readAction.auth, variables: { ...variables, ...outputs }, deadline: cellDeadline.child(10_000), signal });
323
+ const evaluation = evaluatePredicate(entity.readback.predicate, { status: readback.status, body: readback.body });
324
+ const readEvent = log.emit('fixture.readback', null, { entityKey, pass: evaluation.pass, reason: evaluation.reason, observation: redactObservation(readback) }, { requestId: readback.requestId });
325
+ readbackRefs = [EventLog.refOf(readEvent)];
326
+ if (!evaluation.pass)
327
+ throw new HttpStepError('readback_mismatch', `${entityKey}: ${evaluation.reason}`);
328
+ }
329
+ manifestEntities.push({ entityKey, boundaryId: 'application', physicalId, dataOrigin: 'generated_synthetic', cleanupOwnership: 'allocated_by_attempt', startingVersion: null, baselineRef: null, compensationStrategyRef: null, ownershipEvidenceRefs: [EventLog.refOf(allocatingEvent), EventLog.refOf(allocatedEvent)], readbackEvidenceRefs: readbackRefs, cleanupHandle });
330
+ }
331
+ catch (error) {
332
+ failed = true;
333
+ const code = error instanceof HttpStepError ? error.code : 'transport_failure';
334
+ log.emit('fixture.failed', null, { entityKey, code, message: String(error.message) });
335
+ missing.push(entityKey);
336
+ if (code === 'cancelled')
337
+ cancelled = true;
338
+ }
339
+ }
340
+ fixtureState = cancelled ? 'cancelled' : failed ? 'failed' : 'verified';
341
+ fixtureManifest = parseAs(FixtureManifest, freeze({
342
+ schemaVersion: 'workflow.fixture-manifest/v1', ref: { id: `${executionId}.${cell.selectionCellId}.fixtures`, revision: '1' }, scope,
343
+ campaignId: request.campaignId, executionId, attemptId, selectionCellId: cell.selectionCellId,
344
+ campaignFixturePlanRef: ctx.campaignFixturePlan.ref, caseFixturePlanRef: item.fixture.plan.ref, seedRecipeRef: recipe.ref, logicalPayloadRef: payload.ref,
345
+ materializedPayloadDigest: digestOfValue(fixtureOutputs), observedSchemaIdentityRef: null, migrationDigest: null,
346
+ namespace: cell.selectionCellId, executionNonce: attemptId, resourceLeaseRefs: [], entities: manifestEntities,
347
+ outputBindings: fixtureOutputs, lifecycleObservationRefs: [], state: fixtureState,
348
+ missingEntityKeys: missing, unexpectedResourceRefs: [], deadlineAt: new Date(cellDeadline.at).toISOString(), finalizedAt: nowIso(),
349
+ }), 'fixture manifest');
350
+ log.emit('fixture.finalized', null, { state: fixtureState, manifestRef: fixtureManifest.ref, missing });
351
+ }
352
+ // ---- running: compiled steps in frozen order; every step gets one terminal observation ----
353
+ const captured = {};
354
+ let integrationOperations = 0;
355
+ let uncertainOperations = 0;
356
+ let halted = blockedReasons.length > 0 || infrastructureFailure || !session || !driver || (fixtureState !== 'verified' && fixtureState !== 'not_required');
357
+ for (const stepId of compiled.orderedStepIds) {
358
+ const step = compiled.stepsById.get(stepId);
359
+ const inputDigest = digestOfValue(step);
360
+ if (halted || cancelled || signal.aborted) {
361
+ if (signal.aborted && !cancelled)
362
+ cancelled = true;
363
+ stepObservations.push({ stepId, result: cancelled ? 'cancelled' : 'not_run', reasonCode: cancelled ? 'cancelled' : 'halted_by_prior_failure', eventIds: [log.emit('step.skipped', stepId, { reason: cancelled ? 'cancelled' : 'halted' }).eventId], evidenceRefs: [], inputDigest, outputDigest: null, output: null, timing: null });
364
+ continue;
365
+ }
366
+ const variables = {};
367
+ try {
368
+ for (const [name, source] of Object.entries(step.inputs)) {
369
+ switch (source.kind) {
370
+ case 'literal':
371
+ variables[name] = source.value;
372
+ break;
373
+ case 'capture':
374
+ variables[name] = captured[source.stepId]?.[source.name];
375
+ break;
376
+ case 'fixture':
377
+ variables[name] = fixtureOutputs[source.entityKey]?.[source.outputName];
378
+ break;
379
+ case 'credential':
380
+ variables[name] = '<credential>';
381
+ break; // never expanded into variables or logs
382
+ case 'runtime':
383
+ variables[name] = runtimeVariables[source.name];
384
+ break;
385
+ }
386
+ if (variables[name] === undefined)
387
+ throw new HttpStepError('unresolved_variable', `${stepId}.${name}`);
388
+ }
389
+ }
390
+ catch (error) {
391
+ stepObservations.push({ stepId, result: 'failed', reasonCode: error.code ?? 'unresolved_variable', eventIds: [log.emit('step.failed', stepId, { message: String(error.message) }).eventId], evidenceRefs: [], inputDigest, outputDigest: null, output: null, timing: null });
392
+ halted = true;
393
+ continue;
394
+ }
395
+ const stepStart = nowIso();
396
+ const stepStartedMs = monotonicMs();
397
+ const startEvent = log.emit('step.started', stepId, { kind: step.kind, variables: Object.fromEntries(Object.entries(variables).filter(([k]) => step.inputs[k]?.kind !== 'credential')) });
398
+ const deadline = cellDeadline.child(step.timeoutMs);
399
+ try {
400
+ let observation;
401
+ if (ctx.beforeEffect)
402
+ await ctx.beforeEffect();
403
+ if (step.kind === 'http.request') {
404
+ observation = await driver.request({ origin, method: step.method, path: step.path, headers: step.headers, body: step.body, auth: step.auth, variables, deadline, signal });
405
+ if (step.expectStatus !== null && observation.status !== step.expectStatus) {
406
+ const finished = log.emit('step.finished', stepId, { result: 'failed', reason: 'unexpected_status', observation: redactObservation(observation) }, { requestId: observation.requestId });
407
+ stepObservations.push({ stepId, result: 'failed', reasonCode: `unexpected_status:${observation.status}`, eventIds: [startEvent.eventId, finished.eventId], evidenceRefs: [EventLog.refOf(finished)], inputDigest, outputDigest: digestOfValue(redactObservation(observation)), output: redactObservation(observation), timing: { startedAt: stepStart, finishedAt: nowIso(), durationMs: observation.durationMs } });
408
+ halted = true;
409
+ continue;
410
+ }
411
+ captured[stepId] = captureValues(observation, step.captures);
412
+ }
413
+ else if (step.kind === 'observe') {
414
+ observation = await driver.observe({ origin, method: step.readback.method, path: step.readback.path, auth: step.readback.auth, variables, deadline, signal }, step.predicate, step.pollIntervalMs);
415
+ captured[stepId] = captureValues(observation, step.captures);
416
+ }
417
+ else if (step.kind === 'mcp.call') {
418
+ if (!spec.effects.allowedHosts.includes(`launch://${hostPlan.launch?.componentId}`))
419
+ throw new HttpStepError('mcp_origin_not_admitted', 'MCP application origin is outside the frozen effect envelope');
420
+ const command = McpToolCall.parse({ ...step.command, arguments: applyTemplateDeep(step.command.arguments, variables) });
421
+ const credential = bearerFor(step, { persona: authRecipe.credentialName ? session?.credentials.get(authRecipe.credentialName) ?? null : null, named: Object.fromEntries(session?.credentials ?? []) });
422
+ let module;
423
+ try {
424
+ module = await import("../adapters/mcp/driver.js");
425
+ }
426
+ catch {
427
+ throw new HttpStepError('mcp_driver_unavailable', 'Install the pinned optional MCP SDK before planning this flow');
428
+ }
429
+ integrationOperations++;
430
+ uncertainOperations++;
431
+ observation = await new module.McpDriver(origin).call(command, credential, deadline, signal);
432
+ if (!observation.isError) {
433
+ uncertainOperations--;
434
+ captured[stepId] = captureValues({ body: observation }, step.captures);
435
+ }
436
+ }
437
+ else if (step.kind === 'job.submit' || step.kind === 'job.observe' || step.kind === 'job.cancel') {
438
+ if (!session?.nativeJobs)
439
+ throw new NativeJobError('native_job_unavailable', 'The host did not establish a native job channel');
440
+ const command = NativeJobAction.parse(applyTemplateDeep(step.command, variables));
441
+ const credential = bearerFor(step, { persona: authRecipe.credentialName ? session.credentials.get(authRecipe.credentialName) ?? null : null, named: Object.fromEntries(session.credentials) });
442
+ observation = step.kind === 'job.observe' && command.action === 'read'
443
+ ? await session.nativeJobs.observe(command, credential, step.predicate, step.pollIntervalMs, deadline, signal)
444
+ : await session.nativeJobs.request(command, credential, deadline, signal);
445
+ captured[stepId] = captureValues({ body: observation }, step.captures);
446
+ }
447
+ else if (step.kind === 'ui.navigate' || step.kind === 'ui.action' || step.kind === 'ui.observe') {
448
+ if (authRecipe.credentialName && !session?.credentials.get(authRecipe.credentialName))
449
+ throw new HttpStepError('missing_persona_credential', 'browser persona credential was not issued');
450
+ observation = await browser.execute(step, variables, deadline, signal);
451
+ }
452
+ else {
453
+ throw new HttpStepError('unsupported_operation', `${step.kind} is not implemented by the HTTP runner`);
454
+ }
455
+ const output = 'requestId' in observation ? redactObservation(observation) : observation;
456
+ const toolError = 'kind' in observation && observation.kind === 'mcp_tool' && observation.isError;
457
+ const result = toolError ? 'failed' : 'completed';
458
+ const finished = log.emit('step.finished', stepId, { result, observation: output }, { requestId: 'requestId' in observation ? observation.requestId : null });
459
+ stepObservations.push({ stepId, result, reasonCode: toolError ? 'mcp_tool_error' : null, eventIds: [startEvent.eventId, finished.eventId], evidenceRefs: [EventLog.refOf(finished)], inputDigest, outputDigest: digestOfValue(output), output, timing: { startedAt: stepStart, finishedAt: nowIso(), durationMs: monotonicMs() - stepStartedMs } });
460
+ if (toolError)
461
+ halted = true;
462
+ }
463
+ catch (error) {
464
+ const rawCode = error instanceof HttpStepError || error instanceof BrowserStepError || error instanceof NativeJobError ? error.code : 'transport_failure';
465
+ const code = rawCode === 'browser_cancelled' ? 'cancelled' : rawCode;
466
+ const finished = log.emit('step.finished', stepId, { result: code === 'cancelled' ? 'cancelled' : 'failed', reason: code, message: String(error.message) });
467
+ if (code === 'cancelled' || code === 'browser_cancelled')
468
+ cancelled = true;
469
+ else if (isInfrastructureStepFailure(code))
470
+ infrastructureFailure = true;
471
+ stepObservations.push({ stepId, result: code === 'cancelled' ? 'cancelled' : 'failed', reasonCode: code, eventIds: [startEvent.eventId, finished.eventId], evidenceRefs: [EventLog.refOf(finished)], inputDigest, outputDigest: null, output: null, timing: { startedAt: stepStart, finishedAt: nowIso(), durationMs: 0 } });
472
+ halted = true;
473
+ }
474
+ }
475
+ // ---- collecting: boundary observations ----
476
+ const boundaryObservations = fidelityCell.boundaries.map((rule) => {
477
+ let observedMode = 'unknown';
478
+ let accountClass = 'unknown';
479
+ if (session) {
480
+ if (rule.boundaryId === 'application') {
481
+ observedMode = session.boundaryMode;
482
+ accountClass = session.boundaryMode === 'real' ? 'local' : 'none';
483
+ }
484
+ else if (rule.boundaryId === 'storage') {
485
+ observedMode = session.dataDir ? 'real' : 'unknown';
486
+ accountClass = session.dataDir ? 'local' : 'unknown';
487
+ }
488
+ }
489
+ const mismatch = observedMode !== rule.mode ? [`expected ${rule.mode}, observed ${observedMode}`] : [];
490
+ return parseAs(BoundaryObservation, freeze({
491
+ schemaVersion: 'workflow.boundary-observation/v1', ref: { id: `${executionId}.${cell.selectionCellId}.boundary.${rule.boundaryId}`, revision: '1' }, scope,
492
+ campaignId: request.campaignId, executionId, attemptId, selectionCellId: cell.selectionCellId, fidelityPlanRef: ctx.fidelityPlan.ref,
493
+ boundaryId: rule.boundaryId, expectedMode: rule.mode, observedMode, observedAccountClass: accountClass, adapterRef: null,
494
+ identityEvidenceRefs: session?.attestations.map((a) => a.ref) ?? [], interactionEvidenceRefs: stepObservations.flatMap((s) => s.evidenceRefs).slice(0, 64),
495
+ resourceIdsRef: null, interceptorRefs: session?.interceptorRefs ?? [], faultRefs: [], observedAt: nowIso(), mismatchReasons: mismatch,
496
+ }), 'boundary observation');
497
+ });
498
+ const fidelityMatched = boundaryObservations.filter((b) => fidelityCell.claimBoundaryIds.includes(b.boundaryId)).every((b) => b.mismatchReasons.length === 0);
499
+ log.emit('boundaries.observed', null, { observations: boundaryObservations.map((b) => ({ boundaryId: b.boundaryId, expected: b.expectedMode, observed: b.observedMode, mismatches: b.mismatchReasons })) });
500
+ // Flush browser evidence before host cleanup; an unavailable recording cannot satisfy required capture.
501
+ const cleanupDeadline = Deadline.in(hostPlan.cleanupReserveMs);
502
+ const media = [];
503
+ const mediaArtifacts = [];
504
+ try {
505
+ const bytes = await browser.collectVideo(cleanupDeadline);
506
+ if (bytes) {
507
+ const artifact = ctx.artifacts.put({ id: `${executionId}.${cell.selectionCellId}.video`, bytes, mediaType: 'video/webm', producerRef: cell.expectedTarget.runner,
508
+ stepIds: compiled.orderedStepIds.filter(id => compiled.stepsById.get(id).kind.startsWith('ui.')), from: startedAt, to: nowIso() });
509
+ media.push({ digest: artifact.ref.digest.hex, bytes });
510
+ mediaArtifacts.push({ ...artifact, retentionPolicyRef: spec.capture.retentionPolicyRef });
511
+ log.emit('browser.video.collected', null, { ref: artifact.ref, byteCount: artifact.byteCount });
512
+ }
513
+ }
514
+ catch (error) {
515
+ // Preserve bounded driver facts without serializing arbitrary exception messages.
516
+ const cause = error instanceof BrowserStepError && ['video_final_frame_unavailable', 'video_empty', 'browser_network_metadata_limit'].includes(error.code) ? error.code : null;
517
+ const phase = error instanceof BrowserStepError && ['capture', 'frame', 'flush'].includes(error.phase ?? '') ? error.phase : null;
518
+ infrastructureFailure = true;
519
+ log.emit('browser.failed', null, { code: 'browser_evidence_collection_failed', cause, phase });
520
+ }
521
+ // ---- cleaning: owned fixtures in reverse order, then the host; a cleanup deadline is reserved ----
522
+ // Journal failure must never prevent best-effort cleanup of already acquired resources.
523
+ let ownershipWriteError;
524
+ try {
525
+ if (session)
526
+ ctx.ownership.cleaning(hostOwnershipKey);
527
+ for (const entry of allocated)
528
+ ctx.ownership.cleaning(`fixture:${cell.selectionCellId}:${entry.entityKey}`);
529
+ }
530
+ catch (error) {
531
+ ownershipWriteError = error;
532
+ }
533
+ const { cleanup, criticalCleanupConfirmed, confirmedFixtureKeys, hostCleanupConfirmed } = await collectCleanup({ allocated,
534
+ uncertainAllocations: uncertainAllocations.size, uncertainOperations, registry: item.fixture?.registry ?? null,
535
+ driver, origin, deadline: cleanupDeadline, session, reason: cancelled ? 'cancelled' : 'cell complete', log });
536
+ if (!ownershipWriteError) {
537
+ if (session && hostCleanupConfirmed)
538
+ ctx.ownership.removed(hostOwnershipKey);
539
+ for (const entry of allocated)
540
+ if (confirmedFixtureKeys.includes(entry.entityKey))
541
+ ctx.ownership.removed(`fixture:${cell.selectionCellId}:${entry.entityKey}`);
542
+ }
543
+ if (ownershipWriteError)
544
+ throw ownershipWriteError;
545
+ const hostSeconds = (monotonicMs() - hostStartedMs) / 1000;
546
+ // ---- sealing ----
547
+ const finishedAt = nowIso();
548
+ const sealedEvents = log.toJsonl();
549
+ const eventsArtifact = ctx.artifacts.put({ id: `${executionId}.${cell.selectionCellId}.events`, bytes: Buffer.from(sealedEvents, 'utf8'), mediaType: 'application/x-ndjson', producerRef: REDUCER_REF, stepIds: compiled.orderedStepIds, from: startedAt, to: finishedAt });
550
+ const allArtifacts = [eventsArtifact, ...mediaArtifacts];
551
+ const artifactsVerified = allArtifacts.every(artifact => ctx.artifacts.verify(artifact.ref.digest))
552
+ && (spec.capture.video !== 'required' || mediaArtifacts.length > 0)
553
+ && allArtifacts.reduce((sum, artifact) => sum + artifact.byteCount, 0) <= spec.limits.maxArtifactBytes;
554
+ const assertions = evaluateAssertions(spec, environmentPlan.class, stepObservations, REDUCER_REF, startedAt, finishedAt);
555
+ const reduction = reduceCell({ spec, expectedStepIds: compiled.orderedStepIds, steps: stepObservations, assertions, cancelled, fixtureState, identityMatched, fidelityMatched, requiredCapabilitiesObserved, artifactsVerified, unknownMutations: cleanup.remainingUnknownMutations, criticalCleanupConfirmed, infrastructureFailure, blockedReasons });
556
+ const routing = parseAs(RoutingDecision, freeze({
557
+ schemaVersion: 'workflow.routing-decision/v1', ref: { id: `${executionId}.${cell.selectionCellId}.routing`, revision: '1' }, scope,
558
+ owner: { kind: 'attempt', campaignId: request.campaignId, executionId, attemptId }, stage: 'replay', inputDigest: spec.ref.digest,
559
+ intelligencePolicyRef: ctx.intelligencePolicy.ref, catalogRef: null, candidates: [], selected: null,
560
+ estimate: { amountCents: 0, unknownReason: null }, budgetReservationRef: ctx.reservation.ref, escalationReason: 'known case replay performs no authoring inference', decidedAt: nowIso(),
561
+ }), 'routing decision');
562
+ costs.push(parseAs(CostObservation, freeze({
563
+ schemaVersion: 'workflow.cost-observation/v1', ref: { id: `${executionId}.${cell.selectionCellId}.cost.host`, revision: '1' }, scope,
564
+ owner: { kind: 'attempt', campaignId: request.campaignId, executionId, attemptId }, operationId: `${cell.selectionCellId}.host`, stage: 'execution',
565
+ billingRoute: 'host_minutes', providerRequestId: null, usageRef: null, rateSnapshotRef: null,
566
+ quantity: { value: Number(hostSeconds.toFixed(3)), unit: 'seconds' }, amount: { value: 0, currency: 'USD', kind: 'measured' }, reconciliation: 'reconciled', observedAt: nowIso(),
567
+ }), 'cost observation'));
568
+ const accounting = {
569
+ reservations: [{ reservationId: ctx.reservation.ref.id, kind: 'action', cents: ctx.reservation.actionCents }],
570
+ runnerSeconds: Number(hostSeconds.toFixed(3)), browserSeconds: Number(browser.seconds.toFixed(3)), inferenceCalls: 0, inferenceTokens: 0, requestedModel: null, observedModel: null,
571
+ providerRequestIds: stepObservations.flatMap((s) => (s.output && typeof s.output === 'object' && s.output.requestId ? [String(s.output.requestId)] : [])),
572
+ integrationOperations, artifactBytes: allArtifacts.reduce((sum, artifact) => sum + artifact.byteCount, 0), estimatedCents: 0, reconciledCents: 0, rateCardDigest: null, unknownCharges: [],
573
+ routingDecisionRefs: [routing.ref], costObservationRefs: costs.map((c) => c.ref),
574
+ };
575
+ const receipt = parseAs(ExecutionReceipt, freeze({
576
+ schemaVersion: 'workflow.execution/v1', ref: { id: `${executionId}.${cell.selectionCellId}.receipt`, revision: '1' },
577
+ executionId, campaignId: request.campaignId, attemptId, attemptNumber: ctx.attemptNumber, predecessorAttemptRef: ctx.predecessor, retryReason: ctx.predecessor ? 'redelivery after interrupted attempt' : null,
578
+ scope, requesterId: ownerFor(scope), caseRef: spec.ref, personaRef: item.persona.ref, surfaceBindingRef: item.binding.ref, variantRef: null,
579
+ executionHostRef: hostPlan.ref, hostLeaseRef: session?.lease.ref ?? { id: `${executionId}.host-lease.unissued`, revision: '0', digest: digestOfValue('unissued') }, hostObservationRefs: session ? [session.observation.ref] : [],
580
+ environment, idempotencyKey: request.idempotencyKey, requestRef: request.ref, selectionCellId: cell.selectionCellId, qualificationRoundRef: request.qualificationRoundRef,
581
+ fixtureManifestRef: fixtureManifest?.ref ?? null, boundaryObservationRefs: boundaryObservations.map((b) => b.ref), proofClaim: spec.proofClaim,
582
+ coverage: reduction.coverage, eventsDigest: eventsArtifact.ref.digest, assertions, steps: stepObservations, artifacts: allArtifacts, accounting,
583
+ performance: stepObservations.filter((s) => s.timing).map((s) => ({ metric: `step.${s.stepId}.duration`, boundary: compiled.stepsById.get(s.stepId).kind.startsWith('ui.') ? 'browser' : 'http', clock: 'monotonic', cellId: cell.selectionCellId, valueMs: s.timing.durationMs, censored: false, warm: false, strata: { host: hostPlan.adapter } })),
584
+ cleanup, outcome: reduction.outcome, reasonCodes: reduction.reasonCodes, proofEligible: reduction.proofEligible, startedAt, finalizedAt: finishedAt,
585
+ }), 'execution receipt');
586
+ const finalization = log.emit('cell.finalized', null, { outcome: receipt.outcome, reasonCodes: receipt.reasonCodes, receiptRef: receipt.ref });
587
+ // Persist cell-level records beside the receipt for the bundle writer. The events file carries the
588
+ // sealed bytes the receipt hashes; the finalization event is recorded separately.
589
+ writeExecutionBundle({ dir: ctx.executionDir, cell: { id: cell.selectionCellId, receipt, environment, fixtureManifest, boundaryObservations, hostLease: session?.lease ?? null, hostObservation: session?.observation ?? null, attestations: session?.attestations ?? [], credentialLease, routing, costs, eventsJsonl: sealedEvents, finalization, media } });
590
+ return receipt;
591
+ }
592
+ function topoOrder(recipe) {
593
+ const order = [];
594
+ const visiting = new Set();
595
+ const visited = new Set();
596
+ const visit = (key) => {
597
+ if (visited.has(key))
598
+ return;
599
+ if (visiting.has(key))
600
+ throw new Blocked([{ code: 'cyclic_fixture_dependency', detail: key }]);
601
+ visiting.add(key);
602
+ const entity = recipe.entities.find((e) => e.entityKey === key);
603
+ if (!entity)
604
+ throw new Blocked([{ code: 'unknown_fixture_dependency', detail: key }]);
605
+ for (const dep of entity.dependsOn)
606
+ visit(dep);
607
+ visiting.delete(key);
608
+ visited.add(key);
609
+ order.push(key);
610
+ };
611
+ for (const entity of recipe.entities)
612
+ visit(entity.entityKey);
613
+ return order;
614
+ }
615
+ export { selfDigest };
616
+ //# sourceMappingURL=executor.js.map