firedrill-run 2.2.5 → 3.0.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 (392) hide show
  1. package/README.md +178 -22
  2. package/bin/firedrill.mjs +29 -5
  3. package/dist/assembly.json +13 -0
  4. package/dist/cli/runtime/candidate_copy.py +395 -0
  5. package/dist/cli/runtime/source_snapshot.py +391 -0
  6. package/dist/cli/src/administration.js +295 -0
  7. package/dist/cli/src/agent-changes.js +496 -0
  8. package/dist/cli/src/assessment-requests.js +67 -0
  9. package/dist/cli/src/auth.js +465 -0
  10. package/dist/cli/src/billing-commerce-contracts.js +1 -0
  11. package/dist/cli/src/billing-usage.js +227 -0
  12. package/dist/cli/src/billing-wallet-contracts.js +1 -0
  13. package/dist/cli/src/billing.js +170 -0
  14. package/dist/cli/src/bootstrap-process-lock.js +136 -0
  15. package/dist/cli/src/browser-links.js +14 -0
  16. package/dist/cli/src/campaign-controls.js +122 -0
  17. package/dist/cli/src/campaign-diagnoses.js +118 -0
  18. package/dist/cli/src/campaign-reports.js +1215 -0
  19. package/dist/cli/src/campaign-world.js +156 -0
  20. package/dist/cli/src/candidate-copy.js +376 -0
  21. package/dist/cli/src/catalog-contracts.js +1 -0
  22. package/dist/cli/src/ci-access-contracts.js +1 -0
  23. package/dist/cli/src/ci-configuration-contracts.js +1 -0
  24. package/dist/cli/src/ci-coverage.js +64 -0
  25. package/dist/cli/src/ci-delivery-contracts.js +1 -0
  26. package/dist/cli/src/ci-result-contracts.js +1 -0
  27. package/dist/cli/src/ci-run-contracts.js +1 -0
  28. package/dist/cli/src/ci-setup-proposals.js +52 -0
  29. package/dist/cli/src/company-policies.js +229 -0
  30. package/dist/cli/src/completion.js +79 -0
  31. package/dist/cli/src/configuration-intents.js +277 -0
  32. package/dist/cli/src/configuration.js +369 -0
  33. package/dist/cli/src/continuous-simulation.js +277 -0
  34. package/dist/cli/src/coordinated-checkpoints.js +133 -0
  35. package/dist/cli/src/credential-mode.js +139 -0
  36. package/dist/cli/src/credentials.js +331 -0
  37. package/dist/cli/src/credit-format.js +8 -0
  38. package/dist/cli/src/dataset-contracts.js +1 -0
  39. package/dist/cli/src/dataset-export.js +154 -0
  40. package/dist/cli/src/dataset-reads.js +37 -0
  41. package/dist/cli/src/dependency-preparation.js +239 -0
  42. package/dist/cli/src/director-tool-setup.js +104 -0
  43. package/dist/cli/src/driver-review.js +225 -0
  44. package/dist/cli/src/evaluation-authoring.js +315 -0
  45. package/dist/cli/src/evidence-bundles.js +367 -0
  46. package/dist/cli/src/execution-proposals.js +36 -0
  47. package/dist/cli/src/http.js +302 -0
  48. package/dist/cli/src/local-container-boundary.js +38 -0
  49. package/dist/cli/src/local-container-policy.js +201 -0
  50. package/dist/cli/src/local-execution-setup.js +81 -0
  51. package/dist/cli/src/local-source-basis.js +73 -0
  52. package/dist/cli/src/local-source.js +66 -0
  53. package/dist/cli/src/local-value-store.js +91 -0
  54. package/dist/cli/src/local-values.js +163 -0
  55. package/dist/cli/src/login-organizations.js +70 -0
  56. package/dist/cli/src/main.js +1622 -0
  57. package/dist/cli/src/mcp-connection.js +109 -0
  58. package/dist/cli/src/native/bindings.js +137 -0
  59. package/dist/cli/src/native/canonical.js +370 -0
  60. package/dist/cli/src/native/cloud-resources.js +942 -0
  61. package/dist/cli/src/native/companion-channel.js +421 -0
  62. package/dist/cli/src/native/companion-ipc.js +473 -0
  63. package/dist/cli/src/native/contracts.js +218 -0
  64. package/dist/cli/src/native/control-plane.js +1354 -0
  65. package/dist/cli/src/native/credit-approval.js +15 -0
  66. package/dist/cli/src/native/dependency-proxy.js +1006 -0
  67. package/dist/cli/src/native/drill-cleanup.js +115 -0
  68. package/dist/cli/src/native/drill-runner.js +1562 -0
  69. package/dist/cli/src/native/drivers/action-trace.js +210 -0
  70. package/dist/cli/src/native/drivers/function-wrapper.js +152 -0
  71. package/dist/cli/src/native/drivers/http.js +442 -0
  72. package/dist/cli/src/native/drivers/index.js +47 -0
  73. package/dist/cli/src/native/drivers/jsonl-process.js +538 -0
  74. package/dist/cli/src/native/drivers/playwright.js +600 -0
  75. package/dist/cli/src/native/drivers/signed-event.js +244 -0
  76. package/dist/cli/src/native/drivers/types.js +578 -0
  77. package/dist/cli/src/native/evidence-filter.js +255 -0
  78. package/dist/cli/src/native/isolated-access.js +241 -0
  79. package/dist/cli/src/native/library-sharing.js +220 -0
  80. package/dist/cli/src/native/local-run.js +667 -0
  81. package/dist/cli/src/native/local-secrets.js +19 -0
  82. package/dist/cli/src/native/mcp-config.js +123 -0
  83. package/dist/cli/src/native/metadata-requests.js +120 -0
  84. package/dist/cli/src/native/observations.js +1159 -0
  85. package/dist/cli/src/native/owned-groups.js +46 -0
  86. package/dist/cli/src/native/plan.js +594 -0
  87. package/dist/cli/src/native/png.js +159 -0
  88. package/dist/cli/src/native/ports.js +43 -0
  89. package/dist/cli/src/native/readiness.js +139 -0
  90. package/dist/cli/src/native/reassessments.js +206 -0
  91. package/dist/cli/src/native/redaction.js +235 -0
  92. package/dist/cli/src/native/registration.js +155 -0
  93. package/dist/cli/src/native/roots.js +110 -0
  94. package/dist/cli/src/native/run-cleanup.js +199 -0
  95. package/dist/cli/src/native/scratch.js +117 -0
  96. package/dist/cli/src/native/screenshots.js +60 -0
  97. package/dist/cli/src/native/session.js +556 -0
  98. package/dist/cli/src/native/standalone-proxy.js +580 -0
  99. package/dist/cli/src/native/standalone-renewals.js +183 -0
  100. package/dist/cli/src/native/standalone-state.js +193 -0
  101. package/dist/cli/src/native/standalone-tools.js +187 -0
  102. package/dist/cli/src/native/supervisor.js +831 -0
  103. package/dist/cli/src/native/target-auth.js +161 -0
  104. package/dist/cli/src/native/target-state.js +330 -0
  105. package/dist/cli/src/native/tool-reuse.js +364 -0
  106. package/dist/cli/src/native/tool-setups.js +336 -0
  107. package/dist/cli/src/native/world-reuse.js +288 -0
  108. package/dist/cli/src/onboarding.js +23 -0
  109. package/dist/cli/src/priority-requests.js +70 -0
  110. package/dist/cli/src/priority.js +223 -0
  111. package/dist/cli/src/prompts.js +184 -0
  112. package/dist/cli/src/real-operations.js +221 -0
  113. package/dist/cli/src/recipe-intents.js +58 -0
  114. package/dist/cli/src/recorded-context-intents.js +59 -0
  115. package/dist/cli/src/recorded-context.js +248 -0
  116. package/dist/cli/src/recordings.js +69 -0
  117. package/dist/cli/src/registration-guide.js +39 -0
  118. package/dist/cli/src/report-exports.js +213 -0
  119. package/dist/cli/src/request-input.js +47 -0
  120. package/dist/cli/src/resource-lifecycle.js +141 -0
  121. package/dist/cli/src/revision-requests.js +55 -0
  122. package/dist/cli/src/runner-abandon.js +53 -0
  123. package/dist/cli/src/runner-campaign-controls.js +262 -0
  124. package/dist/cli/src/runner-claim-reads.js +36 -0
  125. package/dist/cli/src/runner-completion.js +65 -0
  126. package/dist/cli/src/runner-configuration.js +546 -0
  127. package/dist/cli/src/runner-container.js +794 -0
  128. package/dist/cli/src/runner-evidence-erasure.js +351 -0
  129. package/dist/cli/src/runner-evidence-privacy.js +37 -0
  130. package/dist/cli/src/runner-evidence-retention.js +161 -0
  131. package/dist/cli/src/runner-evidence.js +326 -0
  132. package/dist/cli/src/runner-execute.js +92 -0
  133. package/dist/cli/src/runner-execution-deadline.js +25 -0
  134. package/dist/cli/src/runner-grants.js +307 -0
  135. package/dist/cli/src/runner-identity.js +615 -0
  136. package/dist/cli/src/runner-inputs.js +308 -0
  137. package/dist/cli/src/runner-jobs.js +49 -0
  138. package/dist/cli/src/runner-model-transport.js +392 -0
  139. package/dist/cli/src/runner-ownership.js +332 -0
  140. package/dist/cli/src/runner-process-lock.js +175 -0
  141. package/dist/cli/src/runner-runtime.js +396 -0
  142. package/dist/cli/src/runner-session-channel.js +377 -0
  143. package/dist/cli/src/runner-trial-completion.js +34 -0
  144. package/dist/cli/src/runner-trial-journal.js +358 -0
  145. package/dist/cli/src/runner-trial-live.js +393 -0
  146. package/dist/cli/src/runner-trial-protocol.js +289 -0
  147. package/dist/cli/src/runner-trial-sync.js +110 -0
  148. package/dist/cli/src/runner-trial-transfer.js +107 -0
  149. package/dist/cli/src/runner-voice.js +40 -0
  150. package/dist/cli/src/runner-world-claim.js +21 -0
  151. package/dist/cli/src/runner-world-collector.js +159 -0
  152. package/dist/cli/src/runner-world-command-evidence.js +487 -0
  153. package/dist/cli/src/runner-world-commands.js +268 -0
  154. package/dist/cli/src/runner-world-completion.js +76 -0
  155. package/dist/cli/src/runner-world-erasure.js +95 -0
  156. package/dist/cli/src/runner-world-evidence-sync.js +91 -0
  157. package/dist/cli/src/runner-world-journal.js +510 -0
  158. package/dist/cli/src/runner-world-native-filters.js +134 -0
  159. package/dist/cli/src/runner-world-observations.js +50 -0
  160. package/dist/cli/src/runner-world-session-protocol.js +134 -0
  161. package/dist/cli/src/saved-records.js +40 -0
  162. package/dist/cli/src/scenario-authoring.js +212 -0
  163. package/dist/cli/src/scenario-discovery.js +216 -0
  164. package/dist/cli/src/scenario-paths.js +68 -0
  165. package/dist/cli/src/scenario-requests.js +4 -0
  166. package/dist/cli/src/service-receipts.js +105 -0
  167. package/dist/cli/src/simple/authoring.js +270 -0
  168. package/dist/cli/src/simple/credit-approval.js +16 -0
  169. package/dist/cli/src/simple/help.js +98 -0
  170. package/dist/cli/src/simple/init.js +61 -0
  171. package/dist/cli/src/simple/library-sharing.js +414 -0
  172. package/dist/cli/src/simple/metadata-requests.js +46 -0
  173. package/dist/cli/src/simple/native-report.js +841 -0
  174. package/dist/cli/src/simple/native-tools.js +780 -0
  175. package/dist/cli/src/simple/plan-apply.js +506 -0
  176. package/dist/cli/src/simple/reassessment.js +323 -0
  177. package/dist/cli/src/simple/register.js +123 -0
  178. package/dist/cli/src/simple/run.js +122 -0
  179. package/dist/cli/src/simple/status.js +49 -0
  180. package/dist/cli/src/simple/tool-renewal.js +308 -0
  181. package/dist/cli/src/simple/tool-reuse.js +526 -0
  182. package/dist/cli/src/simple/tool-start-catalog.js +100 -0
  183. package/dist/cli/src/simple/tool-state.js +426 -0
  184. package/dist/cli/src/simple/tools-author.js +222 -0
  185. package/dist/cli/src/simple/watch.js +28 -0
  186. package/dist/cli/src/simple/world-reuse.js +586 -0
  187. package/dist/cli/src/simulation-intents.js +406 -0
  188. package/dist/cli/src/simulation-run.js +1058 -0
  189. package/dist/cli/src/source-batch.js +322 -0
  190. package/dist/cli/src/source-connection.js +451 -0
  191. package/dist/cli/src/source-runtime.js +346 -0
  192. package/dist/cli/src/source-selection-intents.js +75 -0
  193. package/dist/cli/src/source-sets.js +214 -0
  194. package/dist/cli/src/target-models.js +109 -0
  195. package/dist/cli/src/tool-catalog.js +224 -0
  196. package/dist/cli/src/tool-command-contracts.js +1 -0
  197. package/dist/cli/src/tool-command-export.js +245 -0
  198. package/dist/cli/src/tool-connection-contracts.js +1 -0
  199. package/dist/cli/src/tool-connection-reads.js +23 -0
  200. package/dist/cli/src/tool-contributions.js +58 -0
  201. package/dist/cli/src/tool-data.js +116 -0
  202. package/dist/cli/src/tool-datasets.js +176 -0
  203. package/dist/cli/src/tool-group-contracts.js +1 -0
  204. package/dist/cli/src/tool-group-reads.js +26 -0
  205. package/dist/cli/src/tool-group-state.js +147 -0
  206. package/dist/cli/src/tool-groups.js +311 -0
  207. package/dist/cli/src/tool-instances.js +186 -0
  208. package/dist/cli/src/tool-lifecycle-contracts.js +1 -0
  209. package/dist/cli/src/tool-lifecycle-reads.js +30 -0
  210. package/dist/cli/src/tool-lifecycle.js +323 -0
  211. package/dist/cli/src/tool-package-contracts.js +1 -0
  212. package/dist/cli/src/tool-package-reads.js +41 -0
  213. package/dist/cli/src/tool-records.js +53 -0
  214. package/dist/cli/src/tool-runtime.js +96 -0
  215. package/dist/cli/src/tool-state-contracts.js +1 -0
  216. package/dist/cli/src/tool-state-reads.js +31 -0
  217. package/dist/cli/src/tools.js +306 -0
  218. package/dist/cli/src/trial-actions.js +93 -0
  219. package/dist/cli/src/trial-checkpoints.js +133 -0
  220. package/dist/cli/src/trial-checks.js +70 -0
  221. package/dist/cli/src/trial-state.js +197 -0
  222. package/dist/cli/src/vault.js +266 -0
  223. package/dist/cli/src/workspace-registration.js +383 -0
  224. package/dist/cli/src/workspace-team-contracts.js +1 -0
  225. package/dist/cli/src/world-access.js +231 -0
  226. package/dist/cli/src/world-agent.js +4 -0
  227. package/dist/cli/src/world-checkpoint-scopes.js +15 -0
  228. package/dist/cli/src/world-contracts.js +6 -0
  229. package/dist/cli/src/world-creation.js +201 -0
  230. package/dist/cli/src/world-datasets.js +207 -0
  231. package/dist/cli/src/world-inspection.js +257 -0
  232. package/dist/cli/src/world-recipes.js +103 -0
  233. package/dist/cli/src/world-requests.js +241 -0
  234. package/dist/cli/src/world-session-checkpoints.js +196 -0
  235. package/dist/cli/src/world-session-lifecycle.js +207 -0
  236. package/dist/cli/src/world-session-requests.js +215 -0
  237. package/dist/cli/src/world-session-state.js +145 -0
  238. package/dist/cli/src/world-session-voice.js +66 -0
  239. package/dist/cli/src/world-sessions.js +288 -0
  240. package/dist/cli/src/world-stream.js +99 -0
  241. package/dist/cli/src/world-time-report.js +58 -0
  242. package/dist/contracts/agent-change-contracts.js +75 -0
  243. package/dist/contracts/agent-execution-contracts.js +38 -0
  244. package/dist/contracts/application-state-contracts.js +26 -0
  245. package/dist/contracts/assessment-aggregate-contracts.js +15 -0
  246. package/dist/contracts/assessment-contracts.js +74 -0
  247. package/dist/contracts/billing-commerce-contracts.js +107 -0
  248. package/dist/contracts/billing-wallet-contracts.js +43 -0
  249. package/dist/contracts/campaign-lifecycle.js +1 -0
  250. package/dist/contracts/campaign-world-contracts.js +80 -0
  251. package/dist/contracts/catalog-contracts.js +73 -0
  252. package/dist/contracts/ci-access-contracts.js +68 -0
  253. package/dist/contracts/ci-configuration-contracts.js +88 -0
  254. package/dist/contracts/ci-coverage-contracts.js +65 -0
  255. package/dist/contracts/ci-coverage-labels.js +25 -0
  256. package/dist/contracts/ci-delivery-contracts.js +61 -0
  257. package/dist/contracts/ci-result-contracts.js +103 -0
  258. package/dist/contracts/ci-run-contracts.js +51 -0
  259. package/dist/contracts/ci-setup-contracts.js +88 -0
  260. package/dist/contracts/clip-contracts.js +32 -0
  261. package/dist/contracts/comparison-contracts.js +53 -0
  262. package/dist/contracts/composite-contracts.js +34 -0
  263. package/dist/contracts/context-contracts.js +76 -0
  264. package/dist/contracts/continuation-report-contracts.js +1 -0
  265. package/dist/contracts/continuity-requirements.js +8 -0
  266. package/dist/contracts/coordinated-checkpoint-contracts.js +34 -0
  267. package/dist/contracts/dataset-contracts.js +88 -0
  268. package/dist/contracts/dependency-decision-contracts.js +36 -0
  269. package/dist/contracts/dependency-protocol-contracts.js +43 -0
  270. package/dist/contracts/director-execution.js +51 -0
  271. package/dist/contracts/driver-review-contracts.js +99 -0
  272. package/dist/contracts/evidence-contracts.js +65 -0
  273. package/dist/contracts/evidence-coverage-contracts.js +10 -0
  274. package/dist/contracts/export-contracts.js +44 -0
  275. package/dist/contracts/github-directory-contracts.js +96 -0
  276. package/dist/contracts/insight-contracts.js +11 -0
  277. package/dist/contracts/inspection-contracts.js +1 -0
  278. package/dist/contracts/local-claim-contracts.js +39 -0
  279. package/dist/contracts/local-configuration-contracts.js +7 -0
  280. package/dist/contracts/local-evidence-contracts.js +32 -0
  281. package/dist/contracts/local-grant-contracts.js +83 -0
  282. package/dist/contracts/local-input-contracts.js +19 -0
  283. package/dist/contracts/local-runner-contracts.js +42 -0
  284. package/dist/contracts/local-trial-live-contracts.js +16 -0
  285. package/dist/contracts/local-value-source-contracts.js +92 -0
  286. package/dist/contracts/local-world-native-contracts.js +8 -0
  287. package/dist/contracts/mcp-contracts.js +42 -0
  288. package/dist/contracts/media-contracts.js +28 -0
  289. package/dist/contracts/native-check-contracts.js +31 -0
  290. package/dist/contracts/native-identity-contracts.js +52 -0
  291. package/dist/contracts/onboarding-contracts.js +32 -0
  292. package/dist/contracts/performance-contracts.js +85 -0
  293. package/dist/contracts/planning-contracts.js +81 -0
  294. package/dist/contracts/real-operation-contracts.js +30 -0
  295. package/dist/contracts/recommendation-contracts.js +54 -0
  296. package/dist/contracts/report-contracts.js +1 -0
  297. package/dist/contracts/resource-lifecycle-contracts.js +57 -0
  298. package/dist/contracts/revision-contracts.js +12 -0
  299. package/dist/contracts/revision-request-contracts.js +39 -0
  300. package/dist/contracts/saved-record-contracts.js +76 -0
  301. package/dist/contracts/scenario-draft-comparison.js +91 -0
  302. package/dist/contracts/scenario-world-contracts.js +14 -0
  303. package/dist/contracts/service-contracts.js +1 -0
  304. package/dist/contracts/session-command-contracts.js +56 -0
  305. package/dist/contracts/session-contracts.js +65 -0
  306. package/dist/contracts/session-state-contracts.js +67 -0
  307. package/dist/contracts/session-voice-contracts.js +45 -0
  308. package/dist/contracts/source-set-contracts.js +26 -0
  309. package/dist/contracts/source-upload-contracts.js +22 -0
  310. package/dist/contracts/tool-command-contracts.js +57 -0
  311. package/dist/contracts/tool-connection-contracts.js +87 -0
  312. package/dist/contracts/tool-contribution-contracts.js +35 -0
  313. package/dist/contracts/tool-group-contracts.js +53 -0
  314. package/dist/contracts/tool-group-state-contracts.js +63 -0
  315. package/dist/contracts/tool-lifecycle-contracts.js +94 -0
  316. package/dist/contracts/tool-package-contracts.js +91 -0
  317. package/dist/contracts/tool-protocol-contracts.js +71 -0
  318. package/dist/contracts/tool-runtime-billing-contracts.js +28 -0
  319. package/dist/contracts/tool-setup-proposal.js +59 -0
  320. package/dist/contracts/tool-state-contracts.js +79 -0
  321. package/dist/contracts/trial-state-contracts.js +30 -0
  322. package/dist/contracts/typescript/agent-change.js +1 -0
  323. package/dist/contracts/typescript/assessment-aggregate.js +1 -0
  324. package/dist/contracts/typescript/assessment.js +1 -0
  325. package/dist/contracts/typescript/billing-commerce.js +1 -0
  326. package/dist/contracts/typescript/campaigns.js +1 -0
  327. package/dist/contracts/typescript/catalog.js +1 -0
  328. package/dist/contracts/typescript/ci-access.js +1 -0
  329. package/dist/contracts/typescript/ci-configuration.js +1 -0
  330. package/dist/contracts/typescript/ci-delivery.js +1 -0
  331. package/dist/contracts/typescript/ci-result.js +1 -0
  332. package/dist/contracts/typescript/ci-runs.js +1 -0
  333. package/dist/contracts/typescript/clips.js +1 -0
  334. package/dist/contracts/typescript/comparison.js +1 -0
  335. package/dist/contracts/typescript/composite.js +1 -0
  336. package/dist/contracts/typescript/connections.js +1 -0
  337. package/dist/contracts/typescript/context.js +1 -0
  338. package/dist/contracts/typescript/datasets.js +1 -0
  339. package/dist/contracts/typescript/evidence-coverage.js +1 -0
  340. package/dist/contracts/typescript/export.js +1 -0
  341. package/dist/contracts/typescript/github-directory.js +1 -0
  342. package/dist/contracts/typescript/insight.js +1 -0
  343. package/dist/contracts/typescript/inspection.js +1 -0
  344. package/dist/contracts/typescript/intake.js +1 -0
  345. package/dist/contracts/typescript/local-claim.js +1 -0
  346. package/dist/contracts/typescript/local-configuration.js +1 -0
  347. package/dist/contracts/typescript/local-evidence.js +1 -0
  348. package/dist/contracts/typescript/local-grant.js +1 -0
  349. package/dist/contracts/typescript/local-input.js +1 -0
  350. package/dist/contracts/typescript/local-runner.js +1 -0
  351. package/dist/contracts/typescript/local-trial-live.js +1 -0
  352. package/dist/contracts/typescript/local-value-source.js +1 -0
  353. package/dist/contracts/typescript/local-world-native.js +1 -0
  354. package/dist/contracts/typescript/mcp.js +1 -0
  355. package/dist/contracts/typescript/media.js +1 -0
  356. package/dist/contracts/typescript/native-check.js +1 -0
  357. package/dist/contracts/typescript/native-identity.js +1 -0
  358. package/dist/contracts/typescript/onboarding.js +1 -0
  359. package/dist/contracts/typescript/performance.js +1 -0
  360. package/dist/contracts/typescript/planning.js +1 -0
  361. package/dist/contracts/typescript/preparation.js +1 -0
  362. package/dist/contracts/typescript/real-operation.js +1 -0
  363. package/dist/contracts/typescript/recommendation.js +1 -0
  364. package/dist/contracts/typescript/reports.js +1 -0
  365. package/dist/contracts/typescript/resource-lifecycle.js +1 -0
  366. package/dist/contracts/typescript/saved-record.js +1 -0
  367. package/dist/contracts/typescript/scenarios.js +1 -0
  368. package/dist/contracts/typescript/services.js +1 -0
  369. package/dist/contracts/typescript/session-command.js +1 -0
  370. package/dist/contracts/typescript/session-state.js +1 -0
  371. package/dist/contracts/typescript/session-voice.js +1 -0
  372. package/dist/contracts/typescript/session.js +1 -0
  373. package/dist/contracts/typescript/tool-command.js +1 -0
  374. package/dist/contracts/typescript/tool-connection.js +1 -0
  375. package/dist/contracts/typescript/tool-contribution.js +1 -0
  376. package/dist/contracts/typescript/tool-groups.js +1 -0
  377. package/dist/contracts/typescript/tool-lifecycle.js +1 -0
  378. package/dist/contracts/typescript/tool-package.js +1 -0
  379. package/dist/contracts/typescript/tool-state.js +1 -0
  380. package/dist/contracts/typescript/trial-state.js +1 -0
  381. package/dist/contracts/typescript/vault.js +1 -0
  382. package/dist/contracts/typescript/workspace-team.js +1 -0
  383. package/dist/contracts/typescript/world-stream.js +1 -0
  384. package/dist/contracts/workspace-team-contracts.js +55 -0
  385. package/dist/contracts/world-command.js +65 -0
  386. package/dist/contracts/world-lifetime-contracts.js +74 -0
  387. package/dist/contracts/world-recipe-contracts.js +27 -0
  388. package/dist/contracts/world-stream-contracts.js +27 -0
  389. package/dist/package.json +1 -0
  390. package/package.json +16 -16
  391. package/LICENSE.md +0 -23
  392. package/PACKAGING.json +0 -50
@@ -0,0 +1,73 @@
1
+ import { toolProtocolMetadataMatches } from './tool-protocol-contracts.js';
2
+ const uuid = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
3
+ const digest = /^[a-f0-9]{64}$/;
4
+ const serviceKey = /^[a-z][a-z0-9_-]{0,79}$/;
5
+ const operationName = /^[A-Za-z][A-Za-z0-9_.-]{0,127}$/;
6
+ const optionalId = (value) => value === null || uuid.test(value);
7
+ const setupStates = ['preparing', 'inspecting', 'starting', 'instance_requested', 'saved', 'failed', 'withdrawn'];
8
+ export function catalogRead(value, matches) {
9
+ if (!matches)
10
+ throw new Error('The catalog response did not match this selection. Refresh the original item or request.');
11
+ return value;
12
+ }
13
+ function page(value, selected) {
14
+ return Number.isSafeInteger(value.page) && value.page >= 1 && (!selected || value.page === selected)
15
+ && Number.isSafeInteger(value.page_size) && value.page_size >= 1 && value.page_size <= 100
16
+ && Number.isSafeInteger(value.count) && value.count >= 0 && value.results.length <= value.page_size;
17
+ }
18
+ export function catalogReleaseMatches(value, workspace, id) {
19
+ return !!value && uuid.test(workspace) && value.workspace_id === workspace && uuid.test(value.id) && (!id || id === value.id)
20
+ && typeof value.category === 'string' && value.category.length <= 64
21
+ && typeof value.available === 'boolean' && Number.isSafeInteger(value.operation_count) && value.operation_count >= 0
22
+ && Number.isSafeInteger(value.service_count) && value.service_count >= 1 && value.interfaces.every(one => one === 'http' || one === 'mcp')
23
+ && (value.logo_url === null || value.logo_url === `/api/workspaces/${workspace}/tools/library/${value.id}/logo`)
24
+ && (!value.saved_version || uuid.test(value.saved_version.id));
25
+ }
26
+ export function catalogReleaseDetailMatches(value, workspace, id) {
27
+ return catalogReleaseMatches(value, workspace, id) && digest.test(value.contract_digest) && digest.test(value.manifest_digest)
28
+ && value.setup.default_duration_seconds >= 60 && value.setup.default_duration_seconds <= value.setup.maximum_duration_seconds;
29
+ }
30
+ export function catalogPageMatches(value, workspace, query = '', selectedPage, category = '') {
31
+ return !!value && value.workspace_id === workspace && value.query === query.trim() && value.category === category && page(value, selectedPage)
32
+ && value.results.every(row => catalogReleaseMatches(row, workspace));
33
+ }
34
+ function selection(value, release) {
35
+ return value.workspace_id === release.workspace_id && value.release_id === release.id
36
+ && value.contract_digest === release.contract_digest && value.manifest_digest === release.manifest_digest;
37
+ }
38
+ export function catalogServiceMatches(value, release, key) {
39
+ return !!value && selection(value, release) && serviceKey.test(key) && value.key === key && value.id === key;
40
+ }
41
+ export function catalogServicesMatch(value, release, query = '', selectedPage) {
42
+ return !!value && selection(value, release) && value.query === query.trim() && page(value, selectedPage)
43
+ && value.results.every(row => row.id === row.key && serviceKey.test(row.key) && Number.isSafeInteger(row.operation_count) && row.operation_count >= 1);
44
+ }
45
+ export function catalogOperationsMatch(value, release, service, query = '', selectedPage) {
46
+ return !!value && selection(value, release) && serviceKey.test(service) && value.service_key === service
47
+ && value.query === query.trim() && page(value, selectedPage) && value.results.every(row => operationName.test(row.name)
48
+ && toolProtocolMetadataMatches(row)
49
+ && ['none', 'read', 'write', 'mixed'].includes(row.effect) && ['http', 'mcp'].includes(row.transport.kind));
50
+ }
51
+ export function catalogOperationMatches(value, release, service, name) {
52
+ return !!value && selection(value, release) && value.service_key === service && serviceKey.test(service)
53
+ && value.name === name && operationName.test(name) && ['http', 'mcp'].includes(value.transport.kind)
54
+ && !!value.input_schema && (value.output_schema !== null || value.transport.kind === 'http' && value.transport.response_encoding !== undefined
55
+ && value.transport.response_encoding !== 'json') && toolProtocolMetadataMatches(value);
56
+ }
57
+ export function catalogSetupMatches(value, scope, selected) {
58
+ const input = selected?.input;
59
+ return !!value && uuid.test(scope.workspace) && uuid.test(scope.actor) && value.workspace_id === scope.workspace && value.actor_id === scope.actor
60
+ && [value.id, value.request_key, value.release_id, value.upload_request_key].every(one => uuid.test(one))
61
+ && [value.implementation_id, value.instance_id, value.group_id].every(optionalId) && setupStates.includes(value.state)
62
+ && optionalId(value.usage_quote_id) && (value.duration_seconds === null ? value.usage_quote_id === null : value.usage_quote_id !== null)
63
+ && (!selected?.key || value.request_key === selected.key) && (!selected?.id || value.id === selected.id)
64
+ && (!input || value.release_id === input.release_id && value.duration_seconds === input.duration_seconds && value.usage_quote_id === input.usage_quote_id)
65
+ && (value.duration_seconds === null || Number.isSafeInteger(value.duration_seconds) && value.duration_seconds >= 60)
66
+ && (value.state !== 'instance_requested' || value.instance_id !== null && value.implementation_id !== null)
67
+ && (value.state !== 'saved' || value.implementation_id !== null && value.instance_id === null)
68
+ && (!value.can_withdraw || !['instance_requested', 'saved', 'withdrawn'].includes(value.state));
69
+ }
70
+ export function catalogSetupsMatch(value, scope, release = null, selectedPage) {
71
+ return !!value && value.workspace_id === scope.workspace && value.actor_id === scope.actor && value.release_filter === release
72
+ && page(value, selectedPage) && value.results.every(row => catalogSetupMatches(row, scope) && (!release || row.release_id === release));
73
+ }
@@ -0,0 +1,68 @@
1
+ export const ciAcknowledgementNames = ['prepare_source', 'simulate_source', 'driver_input', 'execute_source', 'future_commits', 'untrusted_fork', 'saved_values', 'target_models',
2
+ 'real_startup', 'real_trials', 'shared_real_state', 'evaluation_evidence', 'starting_data', 'browser_recording', 'voice_recording', 'desktop_recording'];
3
+ const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
4
+ const sha = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
5
+ const count = (v, min = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= min;
6
+ const date = (v) => v === null || Number.isFinite(Date.parse(v));
7
+ export function ciAccessRead(value, matches) {
8
+ if (!matches)
9
+ throw new Error('The CI access response did not match the selected workspace, configuration or original request. Review its retained history before continuing.');
10
+ return value;
11
+ }
12
+ function identity(v, workspace, original) {
13
+ return !!v && v.workspace_id === workspace && [v.id, v.workspace_id, v.request_key, v.configuration_id, v.configuration_revision_id].every(uuid)
14
+ && sha(v.request_digest) && count(v.revision, 1) && (!original.id || original.id === v.id)
15
+ && (!original.configuration || original.configuration === v.configuration_id) && (!original.key || original.key === v.request_key)
16
+ && (!original.digest || original.digest === v.request_digest) && (original.revision === undefined || original.revision === v.revision);
17
+ }
18
+ export function ciApprovalMatches(v, workspace, original = {}) {
19
+ if (!identity(v, workspace, original) || !uuid(v.approved_by_id) || original.actor && original.actor !== v.approved_by_id
20
+ || !sha(v.sha256) || !count(v.vault_entry_count) || !Number.isFinite(Date.parse(v.created_at)) || !date(v.revoked_at)
21
+ || !['recorded', 'revoked'].includes(v.state) || (v.state === 'revoked') !== (v.revoked_at !== null) || typeof v.fork !== 'boolean'
22
+ || !v.acknowledgements || Object.keys(v.acknowledgements).length !== ciAcknowledgementNames.length
23
+ || ciAcknowledgementNames.some(key => typeof v.acknowledgements[key] !== 'boolean')
24
+ || !v.acknowledgements.execute_source || !v.acknowledgements.starting_data || v.acknowledgements.untrusted_fork !== v.fork)
25
+ return false;
26
+ return v.scope === 'same_repository' ? v.run_id === null && v.head_sha === null && !v.fork && v.acknowledgements.future_commits
27
+ : v.scope === 'exact_run' && uuid(v.run_id) && typeof v.head_sha === 'string' && /^[a-f0-9]{40}$/.test(v.head_sha) && !v.acknowledgements.future_commits;
28
+ }
29
+ function page(v, number) {
30
+ return v.page === number && count(v.page, 1) && count(v.page_size, 1) && v.page_size <= 100 && count(v.count) && Array.isArray(v.results) && v.results.length <= v.page_size;
31
+ }
32
+ export function ciApprovalsMatch(v, workspace, configuration, filters = {}, number = 1) {
33
+ return !!v && v.workspace_id === workspace && v.configuration_id === configuration && !!v.filters && page(v, number)
34
+ && ['revision', 'state', 'scope', 'run_id'].every(key => v.filters[key] === (filters[key] ?? ''))
35
+ && v.results.every(row => ciApprovalMatches(row, workspace, { configuration }) && (!filters.revision || String(row.revision) === filters.revision)
36
+ && (!filters.state || row.state === filters.state) && (!filters.scope || row.scope === filters.scope) && (!filters.run_id || row.run_id === filters.run_id));
37
+ }
38
+ export function ciApprovalBasisMatches(v, workspace, configuration, revision, world) {
39
+ return !!v && v.workspace_id === workspace && v.configuration_id === configuration && v.revision === revision && count(v.revision, 1)
40
+ && sha(v.basis_sha256) && uuid(v.world_id) && (!world || world === v.world_id) && count(v.configuration_revision, 1)
41
+ && [v.vault_entry_count, v.model_connection_count, v.real_connection_count, v.scenario_count, v.planned_trials].every(one => count(one))
42
+ && count(v.parallelism, 1) && count(v.trial_seconds, 1) && count(v.source_component_count, 1)
43
+ && (v.driver_kind === null || ['browser_workflow', 'adaptive_browser', 'desktop', 'process', 'event'].includes(v.driver_kind))
44
+ && typeof v.driver_input_required === 'boolean' && v.driver_input_required === (v.driver_kind !== null)
45
+ && (v.preparation_budget === null || count(v.preparation_budget.maximum_units, 1) && count(v.preparation_budget.credit_scale, 1)
46
+ && typeof v.preparation_budget.denomination === 'string' && typeof v.preparation_budget.policy_version === 'string')
47
+ && (v.simulation_budget === null || count(v.simulation_budget.maximum_units) && count(v.simulation_budget.credit_scale, 1)
48
+ && typeof v.simulation_budget.denomination === 'string' && typeof v.simulation_budget.policy_version === 'string')
49
+ && [v.evaluation_evidence, v.browser_recording, v.voice_recording, v.desktop_recording].every(one => typeof one === 'boolean');
50
+ }
51
+ export function ciApprovalRequestMatches(v, workspace, original) {
52
+ return !!v && v.workspace_id === workspace && v.actor_id === original.actor && v.request_key === original.key
53
+ && (v.state === 'not_received' ? v.approval === null && !original.id : v.state === 'received' && v.approval !== null && ciApprovalMatches(v.approval, workspace, original));
54
+ }
55
+ export function ciActivationMatches(v, workspace, original = {}) {
56
+ return identity(v, workspace, original) && uuid(v.created_by_id) && (!original.actor || original.actor === v.created_by_id)
57
+ && uuid(v.input_approval_id) && Number.isFinite(Date.parse(v.created_at)) && date(v.revoked_at)
58
+ && ['enabled', 'paused'].includes(v.state) && (v.revoked_at === null || v.state === 'paused')
59
+ && (v.revoke_reason === null || ['user_paused', 'configuration_changed', 'input_approval_revoked', 'authorization_changed'].includes(v.revoke_reason));
60
+ }
61
+ export function ciActivationsMatch(v, workspace, configuration, revision = '', state = '', number = 1) {
62
+ return !!v && v.workspace_id === workspace && v.configuration_id === configuration && v.revision === revision && v.state === state && page(v, number)
63
+ && v.results.every(row => ciActivationMatches(row, workspace, { configuration }) && (!revision || String(row.revision) === revision) && (!state || row.state === state));
64
+ }
65
+ export function ciActivationRequestMatches(v, workspace, original) {
66
+ return !!v && v.workspace_id === workspace && v.actor_id === original.actor && v.request_key === original.key
67
+ && (v.state === 'not_received' ? v.activation === null && !original.id : v.state === 'received' && v.activation !== null && ciActivationMatches(v.activation, workspace, original));
68
+ }
@@ -0,0 +1,88 @@
1
+ import { gitHubId } from './github-directory-contracts.js';
2
+ const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
3
+ const sha = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
4
+ const integer = (v, minimum = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= minimum;
5
+ const text = (v, maximum) => typeof v === 'string' && v.length > 0 && v.length <= maximum && !/[\x00-\x1f\x7f]/.test(v);
6
+ export function ciConfigurationRead(value, matches) {
7
+ if (!matches)
8
+ throw new Error('The CI response did not match the selected workspace, configuration, revision or original request. Reload its saved history.');
9
+ return value;
10
+ }
11
+ export function ciRevisionMatches(v, workspace, configuration) {
12
+ if (!v || v.workspace_id !== workspace || configuration && v.configuration_id !== configuration
13
+ || ![v.id, v.workspace_id, v.configuration_id, v.actor_id, v.request_key].every(uuid)
14
+ || !sha(v.request_digest) || !sha(v.sha256) || !integer(v.revision, 1) || !Number.isFinite(Date.parse(v.created_at)))
15
+ return false;
16
+ const doc = v.document;
17
+ return !!doc && text(doc.name, 120) && ['draft', 'disconnected'].includes(doc.state) && uuid(doc.world_id) && uuid(doc.plan_id)
18
+ && typeof doc.source_alias === 'string' && /^[a-z][a-z0-9_-]{0,63}$/.test(doc.source_alias)
19
+ && (doc.preparation_budget === null || integer(doc.preparation_budget.maximum_units, 1) && integer(doc.preparation_budget.credit_scale, 1)
20
+ && text(doc.preparation_budget.denomination, 64) && text(doc.preparation_budget.policy_version, 64))
21
+ && (doc.simulation_budget === null || integer(doc.simulation_budget.maximum_units) && integer(doc.simulation_budget.credit_scale, 1)
22
+ && text(doc.simulation_budget.denomination, 64) && text(doc.simulation_budget.policy_version, 64))
23
+ && !!doc.scenario_policy && ['all', 'change_relevant'].includes(doc.scenario_policy.mode)
24
+ && Array.isArray(doc.scenario_policy.mandatory_scenario_ids) && doc.scenario_policy.mandatory_scenario_ids.length <= 100
25
+ && doc.scenario_policy.mandatory_scenario_ids.every(uuid)
26
+ && new Set(doc.scenario_policy.mandatory_scenario_ids).size === doc.scenario_policy.mandatory_scenario_ids.length
27
+ && sha(doc.scenario_policy.sha256)
28
+ && (doc.nightly_hour_utc === null || integer(doc.nightly_hour_utc) && doc.nightly_hour_utc <= 23)
29
+ && ['report_only', 'hard_constraints'].includes(doc.mode) && /^[a-f0-9]{40}$/.test(doc.baseline_sha) && text(doc.default_branch, 512)
30
+ && Array.isArray(doc.triggers) && doc.triggers.length >= 1 && doc.triggers.length <= 3
31
+ && new Set(doc.triggers).size === doc.triggers.length && doc.triggers.every(one => ['pull_request', 'default_branch', 'nightly'].includes(one))
32
+ && doc.triggers.includes('nightly') === (doc.nightly_hour_utc !== null);
33
+ }
34
+ export function ciConfigurationMatches(v, workspace, id) {
35
+ if (!v || v.workspace_id !== workspace || !uuid(v.id) || id !== undefined && v.id !== id
36
+ || !integer(v.revision, 1) || !text(v.name, 120) || !['draft', 'active', 'disconnected'].includes(v.state)
37
+ || !gitHubId(v.installation_id) || !gitHubId(v.repository_id) || !text(v.repository, 512)
38
+ || !text(v.account, 255) || typeof v.connection_state !== 'string' || !Number.isFinite(Date.parse(v.updated_at))
39
+ || v.activation_id !== null && !uuid(v.activation_id) || !v.head
40
+ || !ciRevisionMatches(v.head, workspace, v.id) || v.head.revision !== v.revision
41
+ || (v.state === 'disconnected') !== (v.head.document.state === 'disconnected'))
42
+ return false;
43
+ const b = v.baseline;
44
+ return b === null || b.world_id === v.head.document.world_id && b.plan_id === v.head.document.plan_id
45
+ && integer(b.plan_revision, 1) && integer(b.scenario_count) && integer(b.planned_trials)
46
+ && typeof b.world_name === 'string' && b.source_revision === v.head.document.baseline_sha;
47
+ }
48
+ function pageMatches(v, page) {
49
+ return v.page === page && integer(v.page, 1) && integer(v.page_size, 1) && v.page_size <= 100
50
+ && integer(v.count) && Array.isArray(v.results) && v.results.length <= v.page_size;
51
+ }
52
+ export function ciConfigurationsMatch(v, workspace, query = '', state = '', page = 1, repository = '') {
53
+ return !!v && v.workspace_id === workspace && v.query === query.trim() && v.state === state && v.repository_id === repository
54
+ && pageMatches(v, page) && v.results.every(row => ciConfigurationMatches(row, workspace));
55
+ }
56
+ export function ciRevisionPageMatches(v, workspace, configuration, revision = '', mode = '', page = 1) {
57
+ return !!v && v.workspace_id === workspace && v.configuration_id === configuration && v.revision === revision && v.mode === mode
58
+ && pageMatches(v, page) && v.results.every(row => ciRevisionMatches(row, workspace, configuration)
59
+ && (!revision || String(row.revision) === revision) && (!mode || row.document.mode === mode)
60
+ && (row.world_url === null || row.world_url === `/worlds/${row.document.world_id}`));
61
+ }
62
+ export function ciConfigurationRequestMatches(v, workspace, original) {
63
+ return !!v && v.workspace_id === workspace && v.actor_id === original.actor && v.request_key === original.key
64
+ && (v.state === 'not_received' ? v.configuration_id === null && v.saved_revision === null
65
+ : v.state === 'received' && uuid(v.configuration_id) && (!original.configuration || v.configuration_id === original.configuration)
66
+ && v.saved_revision !== null && ciRevisionMatches(v.saved_revision, workspace, v.configuration_id)
67
+ && v.saved_revision.actor_id === original.actor && v.saved_revision.request_key === original.key && v.saved_revision.request_digest === original.digest);
68
+ }
69
+ export function ciPlansMatch(v, workspace, installation, repository, query = '', page = 1) {
70
+ return !!v && v.workspace_id === workspace && v.installation_id === installation && v.repository_id === repository
71
+ && gitHubId(installation) && gitHubId(repository) && v.query === query.trim() && pageMatches(v, page)
72
+ && v.results.every(row => uuid(row.id) && uuid(row.world_id) && integer(row.revision, 1) && integer(row.scenario_count)
73
+ && integer(row.planned_trials) && typeof row.world_name === 'string' && /^[a-f0-9]{40}$/.test(row.source_sha)
74
+ && Array.isArray(row.source_aliases) && row.source_aliases.length > 0 && row.source_aliases.length <= 128
75
+ && new Set(row.source_aliases.map(one => one.alias)).size === row.source_aliases.length
76
+ && row.source_aliases.every(one => /^[a-z][a-z0-9_-]{0,63}$/.test(one.alias) && /^[a-f0-9]{40}$/.test(one.revision))
77
+ && Number.isFinite(Date.parse(row.created_at)));
78
+ }
79
+ export function ciScenariosMatch(v, workspace, configuration, revision, query = '', page = 1) {
80
+ return !!v && v.workspace_id === workspace && v.configuration_id === configuration && String(v.configuration_revision) === revision
81
+ && v.query === query.trim() && pageMatches(v, page) && uuid(v.plan_id) && uuid(v.world_id) && integer(v.plan_revision, 1)
82
+ && integer(v.selected_scenarios) && v.count <= v.selected_scenarios && typeof v.world_name === 'string'
83
+ && v.results.every((row, index) => integer(row.position) && row.position < v.selected_scenarios
84
+ && (index === 0 || row.position > v.results[index - 1].position)
85
+ && (row.available ? uuid(row.scenario_id) && uuid(row.item_id) && typeof row.name === 'string' && integer(row.revision, 1)
86
+ && sha(row.definition_sha256) && row.detail_path === `/scenarios/${row.item_id}`
87
+ : row.available === false && [row.scenario_id, row.item_id, row.name, row.revision, row.definition_sha256, row.detail_path].every(one => one === null)));
88
+ }
@@ -0,0 +1,65 @@
1
+ import { gitHubId } from './github-directory-contracts.js';
2
+ const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(v);
3
+ const sha = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
4
+ const integer = (v, min = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= min;
5
+ const code = (v) => typeof v === 'string' && /^[a-z][a-z0-9_]{0,63}$/.test(v);
6
+ const path = (v) => typeof v === 'string' && v.length > 0 && v.length <= 1024
7
+ && !v.startsWith('/') && !v.includes('\\') && !v.split('/').some(one => one === '..' || one === '.' || one === '') && !/[\x00-\x1f\x7f]/.test(v);
8
+ const page = (v, number) => integer(v.page, 1) && v.page === number && integer(v.count)
9
+ && integer(v.page_size, 1) && v.page_size <= 100 && Array.isArray(v.results) && v.results.length <= v.page_size
10
+ && v.results.length <= v.count;
11
+ export function ciPlanScenariosMatch(v, workspace, plan, selected) {
12
+ return !!v && v.workspace_id === workspace && uuid(v.workspace_id) && v.plan_id === plan && uuid(v.plan_id)
13
+ && v.installation_id === selected.installation && gitHubId(v.installation_id) && v.repository_id === selected.repository && gitHubId(v.repository_id)
14
+ && v.source_alias === selected.sourceAlias && /^[a-z][a-z0-9_-]{0,63}$/.test(v.source_alias)
15
+ && [v.world_id, v.source_id].every(uuid) && [v.plan_revision, v.world_revision].every(one => integer(one, 1))
16
+ && integer(v.configuration_revision) && sha(v.plan_sha256) && v.max_mandatory === 100
17
+ && v.query === (selected.query ?? '').trim() && page(v, selected.page ?? 1)
18
+ && v.results.every((row, index) => integer(row.position) && (index === 0 || row.position > v.results[index - 1].position)
19
+ && typeof row.protected_required_checks === 'boolean' && (row.available
20
+ ? uuid(row.scenario_id) && uuid(row.item_id) && integer(row.revision, 1) && sha(row.definition_sha256)
21
+ && typeof row.name === 'string' && row.detail_path === `/scenarios/${row.item_id}`
22
+ : row.available === false && row.protected_required_checks === true
23
+ && [row.scenario_id, row.item_id, row.revision, row.definition_sha256, row.name, row.detail_path].every(one => one === null)));
24
+ }
25
+ export function ciCoverageMatches(v, workspace, run) {
26
+ if (!v || v.workspace_id !== workspace || v.run_id !== run || ![v.workspace_id, v.run_id].every(uuid))
27
+ return false;
28
+ if (v.state === 'not_available')
29
+ return v.selection === null;
30
+ const s = v.selection;
31
+ return v.state === 'ready' && !!s && uuid(s.id) && ['all', 'change_relevant'].includes(s.policy_mode)
32
+ && ['all', 'reduced'].includes(s.state) && code(s.reason)
33
+ && [s.baseline_count, s.selected_count, s.skipped_count, s.baseline_drills, s.selected_drills].every(one => integer(one))
34
+ && (s.changed_files === null || integer(s.changed_files))
35
+ && s.selected_count + s.skipped_count === s.baseline_count && s.selected_drills <= s.baseline_drills
36
+ && s.reduced === (s.state === 'reduced') && (s.reduced ? s.policy_mode === 'change_relevant' && s.skipped_count > 0 && s.selected_count > 0 : s.skipped_count === 0)
37
+ && s.source_scope === 'retained_sanitized_files' && sha(s.basis_sha256) && sha(s.document_sha256)
38
+ && typeof s.created_at === 'string' && Number.isFinite(Date.parse(s.created_at));
39
+ }
40
+ function originalPage(v, workspace, run, selection, query, number) {
41
+ return !!v && v.workspace_id === workspace && v.run_id === run && [v.workspace_id, v.run_id].every(uuid)
42
+ && v.selection_id === selection.id && v.document_sha256 === selection.document_sha256 && v.query === query.trim() && page(v, number);
43
+ }
44
+ export function ciCoverageScenariosMatch(v, workspace, run, selection, filters = {}) {
45
+ return originalPage(v, workspace, run, selection, filters.query ?? '', filters.page ?? 1)
46
+ && v.selected === (filters.selected ?? 'all') && v.reason === (filters.reason ?? '') && v.count <= selection.baseline_count
47
+ && v.results.every((row, index) => integer(row.position) && row.position < selection.baseline_count
48
+ && (index === 0 || row.position > v.results[index - 1].position) && [row.scenario_id, row.item_id].every(uuid)
49
+ && integer(row.revision, 1) && sha(row.definition_sha256) && code(row.reason) && typeof row.selected === 'boolean'
50
+ && (v.selected === 'all' || row.selected === (v.selected === 'selected')) && (!v.reason || row.reason === v.reason)
51
+ && (row.available ? typeof row.name === 'string' && row.detail_path === `/scenarios/${row.item_id}`
52
+ : row.available === false && row.name === null && row.detail_path === null)
53
+ && Array.isArray(row.links) && row.links.length <= 24 && row.links.every(link => path(link.path)
54
+ && [link.before_sha256, link.after_sha256].every(one => one === null || sha(one))
55
+ && ['changed', 'unchanged', 'missing', 'stale', 'unscoped'].includes(link.status)));
56
+ }
57
+ export function ciCoverageFilesMatch(v, workspace, run, selection, query = '', number = 1) {
58
+ return originalPage(v, workspace, run, selection, query, number) && selection.changed_files !== null && v.count <= selection.changed_files
59
+ && (query.trim() !== '' || v.count === selection.changed_files) && new Set(v.results.map(row => row.path)).size === v.results.length
60
+ && v.results.every(row => path(row.path)
61
+ && [row.before_sha256, row.after_sha256].every(one => one === null || sha(one))
62
+ && (row.change === 'added' ? row.before_sha256 === null && sha(row.after_sha256)
63
+ : row.change === 'removed' ? sha(row.before_sha256) && row.after_sha256 === null
64
+ : ['modified', 'metadata_changed'].includes(row.change) && sha(row.before_sha256) && sha(row.after_sha256)));
65
+ }
@@ -0,0 +1,25 @@
1
+ /** Human descriptions of the original selection reasons, not inferred impact. */
2
+ const reasons = {
3
+ policy_all: 'All scenarios selected by the reviewed policy',
4
+ broad_trigger: 'The full plan is kept for this run type',
5
+ comparison_unavailable: 'The source comparison was unavailable, so the full plan was kept',
6
+ no_changed_files: 'No changes were found in the source comparison, so the full plan was kept',
7
+ change_relevant: 'Selection based on reviewed source links',
8
+ additional_mandatory: 'Included as an additional mandatory case',
9
+ required_checks: 'Included to preserve required checks',
10
+ unknown_checks: 'Included because check coverage is uncertain',
11
+ coverage_unlinked: 'Included because no source links were provided',
12
+ coverage_invalid: 'Included because its source links could not be validated',
13
+ coverage_capacity: 'Included because its source links could not be fully reviewed',
14
+ coverage_missing: 'Included because linked source is missing',
15
+ coverage_stale: 'Included because its source links are out of date',
16
+ coverage_unscoped: 'Included because its source links are outside the compared component',
17
+ linked_change: 'Included because linked source changed',
18
+ linked_unchanged: 'Skipped because its linked source was unchanged',
19
+ empty_selection_kept_all: 'No safe subset was found, so the full plan was kept',
20
+ };
21
+ export const ciCoverageReason = (value) => reasons[value] ?? 'Inspect the saved selection details';
22
+ export const ciCoverageLinkLabel = (value) => ({ changed: 'Changed', unchanged: 'Unchanged', missing: 'Source missing',
23
+ stale: 'Link out of date', unscoped: 'Outside compared source' }[value] ?? 'Source link details unavailable');
24
+ export const ciCoverageFileLabel = (value) => ({ added: 'Added', removed: 'Removed', modified: 'Modified',
25
+ metadata_changed: 'File metadata changed' }[value] ?? 'Change details unavailable');
@@ -0,0 +1,61 @@
1
+ export const ciDeliveryStates = ['queued', 'prepared', 'dispatching', 'uncertain', 'attention_required', 'confirmed', 'rejected', 'superseded'];
2
+ const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
3
+ const count = (v, min = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= min;
4
+ const date = (v) => typeof v === 'string' && Number.isFinite(Date.parse(v));
5
+ export function ciDeliveryRead(value, matches) {
6
+ if (!matches)
7
+ throw new Error('The GitHub delivery did not match this workspace, run or original request. Reload its retained history before continuing.');
8
+ return value;
9
+ }
10
+ export function ciDeliveryIntentMatches(v, run) {
11
+ return !!v && uuid(v.intent_id) && uuid(v.run_id) && (!run || v.run_id === run) && ciDeliveryStates.includes(v.state)
12
+ && count(v.sequence) && count(v.source_revision) && count(v.retry_number) && ['report', 'progress', 'withdrawal', 'rerun_review'].includes(v.purpose)
13
+ && (v.purpose === 'rerun_review' ? uuid(v.rerun_event_id) : v.rerun_event_id === null)
14
+ && date(v.created_at) && [v.dispatched_at, v.confirmed_at].every(one => one === null || date(one))
15
+ && (v.progress_revision === null || count(v.progress_revision, 1)) && (v.phase === null || typeof v.phase === 'string')
16
+ && (v.write_http_status === null || count(v.write_http_status, 100) && v.write_http_status <= 599)
17
+ && (v.conclusion === null || ['success', 'failure', 'neutral', 'cancelled', 'action_required'].includes(v.conclusion))
18
+ && (v.state !== 'confirmed' || v.dispatched_at !== null && v.confirmed_at !== null);
19
+ }
20
+ export function ciDeliveryMatches(v, workspace, run, kind) {
21
+ if (!v || v.workspace_id !== workspace || v.run_id !== run || v.kind !== kind || !uuid(workspace) || !uuid(run)
22
+ || ![...ciDeliveryStates, 'not_available', 'not_applicable'].includes(v.state)
23
+ || ![v.check_confirmed, v.comment_confirmed, v.confirmed_for_run, v.result_current].every(one => typeof one === 'boolean')
24
+ || v.head !== null && (!ciDeliveryIntentMatches(v.head, kind === 'check' ? run : undefined) || v.head.state !== v.state)
25
+ || v.waiting_for !== null && !ciDeliveryIntentMatches(v.waiting_for, kind === 'check' ? run : undefined))
26
+ return false;
27
+ if (v.url !== null) {
28
+ try {
29
+ const url = new URL(v.url);
30
+ if (url.protocol !== 'https:' || url.hostname !== 'github.com' || url.username || url.password)
31
+ return false;
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ if (v.state === 'not_available' || v.state === 'not_applicable')
38
+ return v.head === null && v.waiting_for === null && !v.check_confirmed && !v.comment_confirmed
39
+ && !v.result_current && !v.confirmed_for_run && (v.state !== 'not_applicable' || kind === 'comment');
40
+ const confirmed = kind === 'check' ? v.check_confirmed : v.comment_confirmed;
41
+ return v.head !== null && (kind === 'check' ? !v.comment_confirmed : !v.check_confirmed)
42
+ && (!confirmed || v.head.state === 'confirmed' && v.head.dispatched_at !== null && v.head.confirmed_at !== null)
43
+ && (!v.result_current || v.head.purpose === 'report' && v.head.run_id === run);
44
+ }
45
+ export function ciDeliveriesMatch(v, workspace, run, kind, status, page) {
46
+ return !!v && v.workspace_id === workspace && v.run_id === run && v.kind === kind && v.status === status && count(v.count)
47
+ && v.page === page && count(v.page_size, 1) && v.page_size <= 100 && Array.isArray(v.results) && v.results.length <= v.page_size
48
+ && v.results.every(one => ciDeliveryIntentMatches(one, kind === 'check' ? run : undefined) && (!status || one.state === status))
49
+ && new Set(v.results.map(one => one.intent_id)).size === v.results.length;
50
+ }
51
+ export function ciDeliveryRecoveryMatches(v, workspace, intent, kind, original = {}) {
52
+ return !!v && v.workspace_id === workspace && v.intent_id === intent && v.kind === kind
53
+ && [v.id, v.workspace_id, v.actor_id, v.request_key, v.intent_id].every(uuid) && /^[a-f0-9]{64}$/.test(v.request_digest)
54
+ && count(v.sequence, 1) && typeof v.retry_rejected === 'boolean' && /^[a-z_]{1,24}$/.test(v.state) && date(v.created_at)
55
+ && (!original.id || original.id === v.id) && (!original.actor || original.actor === v.actor_id)
56
+ && (!original.key || original.key === v.request_key) && (!original.digest || original.digest === v.request_digest);
57
+ }
58
+ export function ciDeliveryRecoveryRequestMatches(v, workspace, intent, kind, original) {
59
+ return !!v && v.workspace_id === workspace && v.intent_id === intent && v.kind === kind && v.actor_id === original.actor && v.request_key === original.key
60
+ && (v.state === 'not_received' ? v.request === null && !original.id : v.state === 'received' && v.request !== null && ciDeliveryRecoveryMatches(v.request, workspace, intent, kind, original));
61
+ }
@@ -0,0 +1,103 @@
1
+ import { ciCoverageMatches } from './ci-coverage-contracts.js';
2
+ const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
3
+ const sha = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
4
+ const count = (v, min = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= min;
5
+ const date = (v) => typeof v === 'string' && Number.isFinite(Date.parse(v));
6
+ const reportStates = ['waiting', 'collecting', 'ready', 'attention_required', 'changed', 'canceled', 'not_available'];
7
+ const trialCounts = ['retained', 'completed', 'failed', 'platform_failed', 'timed_out', 'canceled', 'unfinished', 'invoked', 'results',
8
+ 'declared', 'expected_exact', 'observed', 'exact_met', 'exact_unmet', 'unknown', 'native_unmet'];
9
+ export function ciResultRead(value, matches) {
10
+ if (!matches)
11
+ throw new Error('The report did not match the selected workspace, run or original request. Reload its retained result before continuing.');
12
+ return value;
13
+ }
14
+ export function ciResultMatches(v, workspace, run, selected = {}) {
15
+ if (!v || v.workspace_id !== workspace || v.run_id !== run || !uuid(workspace) || !uuid(run) || !reportStates.includes(v.state)
16
+ || typeof v.published !== 'boolean' || typeof v.check_confirmed !== 'boolean' || typeof v.publication_current !== 'boolean'
17
+ || ![true, false, null].includes(v.comment_required) || ![true, false, null].includes(v.comment_confirmed)
18
+ || ![null, 'pending', 'settled'].includes(v.withdrawal) || v.published !== (v.ci_verdict !== null)
19
+ || v.ci_verdict !== null && !['neutral', 'success', 'failure'].includes(v.ci_verdict))
20
+ return false;
21
+ if (v.state === 'not_available')
22
+ return v.result === null && v.id === null && v.campaign_id === null && v.sequence === null
23
+ && v.source_revision === null && v.observed_at === null && v.report_path === null && !v.published && !v.check_confirmed && !v.publication_current
24
+ && v.comment_required === null && v.comment_confirmed === null && v.withdrawal === null;
25
+ if (!uuid(v.id) || !uuid(v.campaign_id) || !count(v.sequence, 1) || !count(v.source_revision)
26
+ || v.report_path !== `/campaigns/${v.campaign_id}` || selected.campaign && selected.campaign !== v.campaign_id
27
+ || v.observed_at !== null && !date(v.observed_at))
28
+ return false;
29
+ if (v.state !== 'ready')
30
+ return v.result === null && !v.published && v.ci_verdict === null;
31
+ const result = v.result;
32
+ if (!result || result.schema !== 'firedrill.github-ci-result.v1' || result.run_id !== run || result.campaign_id !== v.campaign_id
33
+ || !/^[a-f0-9]{40}$/.test(result.head_sha) || selected.sha && selected.sha !== result.head_sha
34
+ || !uuid(result.configuration_revision_id) || !sha(result.plan_sha256) || !date(result.observed_at)
35
+ || !date(v.observed_at) || Date.parse(result.observed_at) !== Date.parse(v.observed_at)
36
+ || result.report_path !== v.report_path || result.scores_path !== `/api/workspaces/${workspace}/ci/runs/${run}/result/scores`
37
+ || !count(result.scenarios) || !count(result.planned_trials) || !['completed', 'failed', 'canceled'].includes(result.execution_state))
38
+ return false;
39
+ if (result.coverage !== undefined && result.coverage !== null && (!ciCoverageMatches({ workspace_id: workspace, run_id: run,
40
+ state: 'ready', selection: result.coverage }, workspace, run) || result.scenarios !== result.coverage.selected_count
41
+ || result.planned_trials !== result.coverage.selected_drills))
42
+ return false;
43
+ const trials = result.trials, assessment = result.assessment, decision = result.decision;
44
+ return !!trials && trialCounts.every(key => count(trials[key])) && !!assessment
45
+ && [assessment.expected, assessment.assessed, assessment.not_applicable, assessment.not_assessable, assessment.unavailable, assessment.score_groups].every(one => count(one))
46
+ && assessment.assessed + assessment.not_applicable + assessment.not_assessable + assessment.unavailable === assessment.expected
47
+ && typeof assessment.requested === 'boolean' && !!decision && decision.published === false && decision.constraint_scope === 'source_exact_checks'
48
+ && ['report_only', 'hard_constraints'].includes(decision.mode) && ['report_only', 'met', 'unmet', 'incomplete'].includes(decision.status)
49
+ && ['neutral', 'success', 'failure'].includes(decision.suggested_conclusion)
50
+ && [decision.complete, decision.execution_complete, decision.check_coverage_complete, decision.assessment_coverage_complete, decision.has_exact_constraints].every(one => typeof one === 'boolean')
51
+ && decision.complete === (decision.execution_complete && decision.check_coverage_complete && decision.assessment_coverage_complete)
52
+ && (!v.published || v.publication_current && v.check_confirmed && (!v.comment_required || v.comment_confirmed === true)
53
+ && v.ci_verdict === decision.suggested_conclusion);
54
+ }
55
+ function reportPageMatches(v, workspace, run, query, page) {
56
+ if (!v || v.workspace_id !== workspace || v.run_id !== run || v.query !== query.trim() || !uuid(v.campaign_id)
57
+ || !count(v.source_revision) || v.observed_at !== null && !date(v.observed_at) || !Array.isArray(v.results))
58
+ return false;
59
+ if (v.state !== 'ready')
60
+ return reportStates.includes(v.state) && v.count === null && v.page === null && v.page_size === null
61
+ && v.next === null && v.previous === null && v.results.length === 0;
62
+ return count(v.count) && v.page === page && count(v.page_size, 1) && v.page_size <= 100 && v.results.length <= v.page_size
63
+ && date(v.observed_at) && v.results.every((one, index) => count(one.position)
64
+ && (index === 0 || one.position > v.results[index - 1].position) && uuid(one.criterion_id));
65
+ }
66
+ export function ciCriteriaMatches(v, workspace, run, query, status, page) {
67
+ if (!reportPageMatches(v, workspace, run, query, page) || v.status !== status)
68
+ return false;
69
+ return v.state !== 'ready' || v.results.every(one => {
70
+ const values = one.counts;
71
+ return sha(one.definition_sha256) && (one.name === null || typeof one.name === 'string') && !!values && Object.values(values).every(number => count(number))
72
+ && values.assessed + values.not_applicable + values.not_assessable + values.unavailable === values.expected
73
+ && ['complete', 'incomplete', 'not_assessable'].includes(one.coverage_state)
74
+ && (!status || status === one.coverage_state) && (one.definition_url === null || /^\/evaluations\/[a-f0-9-]{36}$/.test(one.definition_url));
75
+ });
76
+ }
77
+ export function ciScoresMatch(v, workspace, run, query, page) {
78
+ if (!reportPageMatches(v, workspace, run, query, page))
79
+ return false;
80
+ return v.state !== 'ready' || v.results.every(one => {
81
+ const { cohort, summary } = one;
82
+ if (!uuid(one.example_execution_id) || !cohort || !uuid(cohort.assessment_id) || !uuid(cohort.scenario_id) || !sha(cohort.identity)
83
+ || !Array.isArray(cohort.levels) || cohort.levels.length < 2 || cohort.levels.length > 10 || !cohort.levels.every(level => typeof level === 'string')
84
+ || !['higher', 'lower'].includes(cohort.direction) || !summary
85
+ || ![summary.observed, summary.assessed, summary.not_assessable, summary.not_applicable].every(number => count(number))
86
+ || summary.assessed + summary.not_assessable + summary.not_applicable !== summary.observed)
87
+ return false;
88
+ const values = [summary.mean, summary.minimum, summary.maximum];
89
+ return summary.assessed === 0 ? values.every(value => value === null) : values.every(value => typeof value === 'number'
90
+ && Number.isFinite(value) && value >= 0 && value <= cohort.levels.length - 1)
91
+ && summary.minimum <= summary.mean && summary.mean <= summary.maximum;
92
+ });
93
+ }
94
+ export function ciResultRefreshMatches(v, workspace, run, original = {}) {
95
+ return !!v && v.workspace_id === workspace && v.run_id === run && [v.id, v.workspace_id, v.actor_id, v.request_key, v.run_id].every(uuid)
96
+ && sha(v.request_digest) && count(v.sequence, 1) && /^[a-z_]{1,24}$/.test(v.state) && date(v.created_at)
97
+ && (!original.id || original.id === v.id) && (!original.actor || original.actor === v.actor_id)
98
+ && (!original.key || original.key === v.request_key) && (!original.digest || original.digest === v.request_digest);
99
+ }
100
+ export function ciResultRefreshRequestMatches(v, workspace, run, original) {
101
+ return !!v && v.workspace_id === workspace && v.run_id === run && v.actor_id === original.actor && v.request_key === original.key
102
+ && (v.state === 'not_received' ? v.request === null && !original.id : v.state === 'received' && v.request !== null && ciResultRefreshMatches(v.request, workspace, run, original));
103
+ }
@@ -0,0 +1,51 @@
1
+ export const ciRunStates = ['queued', 'acquiring_source', 'preparing_world', 'configuration_required', 'validating', 'planning', 'running',
2
+ 'report_pending', 'attention_required', 'canceling', 'completed', 'failed', 'canceled', 'superseded'];
3
+ const uuid = (v) => typeof v === 'string' && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
4
+ const integer = (v, min = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= min;
5
+ const date = (v) => v === null || Number.isFinite(Date.parse(v));
6
+ export function ciRunRead(value, matches) {
7
+ if (!matches)
8
+ throw new Error('The CI run response did not match the selected workspace, original preparation or history filters. Check the retained run before continuing.');
9
+ return value;
10
+ }
11
+ export function ciRunMatches(v, workspace, selected = {}) {
12
+ if (!v || v.workspace_id !== workspace || ![v.id, v.workspace_id, v.configuration_id, v.created_by_id, v.event_id, v.request_key].every(uuid)
13
+ || !/^[a-f0-9]{64}$/.test(v.request_digest) || !integer(v.configuration_revision, 1)
14
+ || selected.id !== undefined && v.id !== selected.id || selected.configuration !== undefined && v.configuration_id !== selected.configuration
15
+ || selected.actor !== undefined && v.created_by_id !== selected.actor || selected.key !== undefined && v.request_key !== selected.key
16
+ || selected.digest !== undefined && v.request_digest !== selected.digest || !/^[a-f0-9]{40}$/.test(v.head_sha)
17
+ || typeof v.reference !== 'string' || !v.reference.length || v.reference.length > 1024 || /[\x00-\x1f\x7f]/.test(v.reference)
18
+ || typeof v.fork !== 'boolean' || !ciRunStates.includes(v.state) || typeof v.cleanup_pending !== 'boolean'
19
+ || v.cleanup_pending !== (v.state === 'canceling') || !Number.isFinite(Date.parse(v.created_at)) || !Number.isFinite(Date.parse(v.updated_at))
20
+ || !date(v.observed_head_at) || ![v.source_id, v.world_id, v.campaign_id, v.validation_id, v.activation_id].every(one => one === null || uuid(one))
21
+ || !v.head_status || !['pending', 'current', 'changed'].includes(v.head_status.state) || !date(v.head_status.checked_at)
22
+ || v.world_url !== null && v.world_url !== `/worlds/${v.world_id}` || v.report_url !== null && v.report_url !== `/campaigns/${v.campaign_id}`
23
+ || v.world_configuration_revision !== null && (!v.world_id || !integer(v.world_configuration_revision, 1)))
24
+ return false;
25
+ if (v.trigger === 'pull_request' ? !integer(v.pull_number, 1) : v.trigger === 'check_run'
26
+ ? !(v.pull_number === null ? !v.fork : integer(v.pull_number, 1))
27
+ : !['push', 'scheduled'].includes(v.trigger) || v.pull_number !== null || v.fork)
28
+ return false;
29
+ if (v.source && (!uuid(v.source.id) || v.source.id !== v.source_id
30
+ || !(v.source.revision === v.head_sha || /^set:[a-f0-9]{64}$/.test(v.source.revision))
31
+ || !integer(v.source.excluded_files)))
32
+ return false;
33
+ const report = v.recorded_report;
34
+ return report === undefined || report === null || report.basis === 'recorded_report' && ['met', 'unmet', 'incomplete', 'report_only'].includes(report.status)
35
+ && typeof report.complete === 'boolean' && (report.status !== 'met' || report.complete) && Number.isFinite(Date.parse(report.observed_at));
36
+ }
37
+ export function ciRunsMatch(v, workspace, configuration, filters = {}, page = 1) {
38
+ return !!v && v.workspace_id === workspace && v.configuration_id === configuration && v.page === page && integer(v.page, 1)
39
+ && integer(v.count) && integer(v.page_size, 1) && v.page_size <= 100 && Array.isArray(v.results) && v.results.length <= v.page_size
40
+ && !!v.filters && ['sha', 'state', 'trigger', 'reference', 'outcome'].every(key => v.filters[key] === (filters[key] ?? ''))
41
+ && (filters.world ? v.filters.world?.id === filters.world : v.filters.world === null)
42
+ && v.results.every(row => ciRunMatches(row, workspace, { configuration }) && (!filters.sha || row.head_sha === filters.sha.toLowerCase())
43
+ && (!filters.state || row.state === filters.state) && (!filters.trigger || row.trigger === filters.trigger)
44
+ && (!filters.reference || row.reference.startsWith(filters.reference))
45
+ && (!filters.outcome || (filters.outcome === 'no_report' ? !row.recorded_report : row.recorded_report?.status === filters.outcome)));
46
+ }
47
+ export function ciRunRequestMatches(v, workspace, original) {
48
+ return !!v && v.workspace_id === workspace && v.actor_id === original.actor && v.request_key === original.key
49
+ && (v.state === 'not_received' ? v.run === null && !original.id : v.state === 'received' && v.run !== null
50
+ && ciRunMatches(v.run, workspace, original) && v.run.activation_id === null);
51
+ }