firedrill-run 2.2.4 → 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,88 @@
1
+ import { gitHubId } from './github-directory-contracts.js';
2
+ import { nativeMetadataCanonical } from './local-value-source-contracts.js';
3
+ const uuid = (v) => typeof v === 'string'
4
+ && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
5
+ const sha = (v) => typeof v === 'string' && /^[a-f0-9]{64}$/.test(v);
6
+ const integer = (v, minimum = 0) => typeof v === 'number' && Number.isSafeInteger(v) && v >= minimum;
7
+ const text = (v, maximum) => typeof v === 'string'
8
+ && v.length > 0 && v.length <= maximum && !/[\x00-\x1f\x7f]/.test(v);
9
+ const date = (v) => typeof v === 'string' && Number.isFinite(Date.parse(v));
10
+ const requestKeys = ['title', 'world_id', 'source_id', 'source_revision', 'world_revision', 'configuration_id',
11
+ 'configuration_revision', 'configuration_sha256', 'plan_id', 'plan_revision', 'plan_sha256', 'source_alias',
12
+ 'component_source_id', 'component_revision', 'connection_id', 'installation_id', 'repository_id', 'repository',
13
+ 'connection_access_revision', 'connection_verified_at', 'source_set_sha256', 'graph_sha256', 'triggers', 'mode',
14
+ 'nightly_hour_utc', 'scenario_count', 'repetitions', 'planned_trials', 'scenario_policy'].sort();
15
+ const requirements = new Set(['managed_plan_required', 'github_source_required', 'github_connection_required',
16
+ 'repository_directory_required', 'repository_access_required', 'preparation_budget_review_required',
17
+ 'simulation_budget_review_required', 'input_access_review_required', 'separate_activation_required', 'pr_plan_too_long']);
18
+ export function ciSetupProposalId(value) {
19
+ if (!value || typeof value !== 'object' || Array.isArray(value))
20
+ return null;
21
+ const row = value;
22
+ return row.schema === 'firedrill.ci-setup-proposal.v1' && uuid(row.ci_setup_proposal_id)
23
+ ? row.ci_setup_proposal_id : null;
24
+ }
25
+ export function ciSetupProposalMatches(value, world, id, actor) {
26
+ if (!value || typeof value !== 'object' || Array.isArray(value))
27
+ return false;
28
+ const row = value;
29
+ const r = row.request;
30
+ if (row.schema !== 'firedrill.ci-setup-proposal.v1' || row.id !== id || row.world_id !== world
31
+ || ![row.id, row.actor_id, row.world_id].every(uuid) || actor !== undefined && row.actor_id !== actor
32
+ || !sha(row.request_sha256) || !r || typeof r !== 'object' || Array.isArray(r)
33
+ || Object.keys(r).sort().join(',') !== requestKeys.join(',') || r.world_id !== world
34
+ || ![r.world_id, r.source_id, r.configuration_id, r.plan_id, r.component_source_id, r.connection_id].every(uuid)
35
+ || ![r.world_revision, r.plan_revision, r.repetitions].every(v => integer(v, 1))
36
+ || ![r.configuration_revision, r.connection_access_revision].every(v => integer(v))
37
+ || ![r.configuration_sha256, r.plan_sha256].every(sha) || !text(r.source_revision, 128)
38
+ || !/^[a-f0-9]{40}$/.test(r.component_revision) || !/^[a-z][a-z0-9_-]{0,63}$/.test(r.source_alias)
39
+ || !gitHubId(r.installation_id) || !gitHubId(r.repository_id) || !text(r.repository, 512) || !text(r.title, 120)
40
+ || r.connection_verified_at !== null && !date(r.connection_verified_at)
41
+ || [r.source_set_sha256, r.graph_sha256].some(v => v !== null && !sha(v))
42
+ || !Array.isArray(r.triggers) || r.triggers.length < 1 || r.triggers.length > 3
43
+ || new Set(r.triggers).size !== r.triggers.length
44
+ || !r.triggers.every(v => ['pull_request', 'default_branch', 'nightly'].includes(v))
45
+ || !['report_only', 'hard_constraints'].includes(r.mode)
46
+ || (r.triggers.includes('nightly') ? !integer(r.nightly_hour_utc) || r.nightly_hour_utc > 23 : r.nightly_hour_utc !== null)
47
+ || !integer(r.scenario_count) || !integer(r.planned_trials) || r.planned_trials !== r.scenario_count * r.repetitions
48
+ || !r.scenario_policy || Object.keys(r.scenario_policy).sort().join(',') !== 'mandatory_scenario_ids,mode,sha256'
49
+ || !['all', 'change_relevant'].includes(r.scenario_policy.mode) || !sha(r.scenario_policy.sha256)
50
+ || !Array.isArray(r.scenario_policy.mandatory_scenario_ids) || r.scenario_policy.mandatory_scenario_ids.length > 100
51
+ || !r.scenario_policy.mandatory_scenario_ids.every(uuid)
52
+ || new Set(r.scenario_policy.mandatory_scenario_ids).size !== r.scenario_policy.mandatory_scenario_ids.length
53
+ || !['available', 'current', 'can_review'].every(key => typeof row[key] === 'boolean')
54
+ || row.can_review && (!row.available || !row.current)
55
+ || !Array.isArray(row.missing_requirements) || row.missing_requirements.length > 16
56
+ || new Set(row.missing_requirements).size !== row.missing_requirements.length
57
+ || !row.missing_requirements.every(v => typeof v === 'string' && requirements.has(v))
58
+ || row.handoff_path !== `/ci/new?world=${world}&proposal=${id}`
59
+ || row.requires_user_approval !== true || row.configuration_created !== false
60
+ || row.activation_started !== false || row.consent_granted !== false)
61
+ return false;
62
+ const summary = row.configuration_summary;
63
+ if (!summary || Object.keys(summary).sort().join(',') !== [
64
+ 'variables', 'build_variables', 'runtime_variables', 'unresolved_variables', 'dependencies',
65
+ 'simulated_dependencies', 'real_dependencies', 'model_connections'
66
+ ].sort().join(',')
67
+ || !Object.values(summary).every(v => integer(v)) || summary.build_variables > summary.variables
68
+ || summary.runtime_variables > summary.variables || summary.unresolved_variables > summary.variables
69
+ || summary.simulated_dependencies + summary.real_dependencies > summary.dependencies)
70
+ return false;
71
+ const plan = row.plan;
72
+ if (plan !== null && (!plan || plan.id !== r.plan_id || plan.world_id !== world || plan.revision !== r.plan_revision
73
+ || plan.scenario_count !== r.scenario_count || plan.planned_trials !== r.planned_trials
74
+ || typeof plan.world_name !== 'string' || !date(plan.created_at) || plan.source_sha !== r.component_revision
75
+ || !Array.isArray(plan.source_aliases) || plan.source_aliases.length !== 1
76
+ || plan.source_aliases[0]?.alias !== r.source_alias || plan.source_aliases[0]?.revision !== r.component_revision))
77
+ return false;
78
+ const repository = row.repository_option;
79
+ if (repository !== null && (!repository || repository.id !== r.repository_id || repository.full_name !== r.repository
80
+ || repository.default_branch !== null && !text(repository.default_branch, 512)))
81
+ return false;
82
+ return !row.can_review || plan !== null && repository !== null;
83
+ }
84
+ /** Check the original immutable request after the structural/context guard. */
85
+ export async function ciSetupRequestDigest(request) {
86
+ const bytes = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(nativeMetadataCanonical(request)));
87
+ return Array.from(new Uint8Array(bytes), one => one.toString(16).padStart(2, '0')).join('');
88
+ }
@@ -0,0 +1,32 @@
1
+ const uuid = (value) => /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(value);
2
+ export function captureClipMatches(row, prefix, expected) {
3
+ if (!uuid(row.id) || !uuid(row.request_key) || expected !== undefined && row.id !== expected
4
+ || row.origin !== 'browser_derived_capture_playback')
5
+ return false;
6
+ const path = `${prefix}/${row.id}/file`;
7
+ return row.file === null || row.state === 'retained' && row.file.path === path
8
+ && row.file.download_path === `${path}?download=1` && row.file.content_type === 'video/mp4';
9
+ }
10
+ export function sameCaptureSelection(actual, original) {
11
+ return actual.id === original.id && actual.request_key === original.request_key && actual.source_kind === original.source_kind
12
+ && actual.attempt_number === original.attempt_number && actual.frames === original.frames
13
+ && actual.started_at === original.started_at && actual.ended_at === original.ended_at
14
+ && actual.duration_us === original.duration_us && actual.source_sha256 === original.source_sha256
15
+ && actual.width === original.width && actual.height === original.height && actual.origin === original.origin;
16
+ }
17
+ /** Corroborate the original private destination before sending encoded bytes. */
18
+ export function captureClipUploadDestination(ticket, prefix, clip) {
19
+ const workspace = prefix.match(/^\/api\/workspaces\/([a-f0-9-]{36})\/campaigns\/[a-f0-9-]{36}\/trials\/[a-f0-9-]{36}\/capture-clips$/)?.[1];
20
+ const url = new URL(ticket.upload_url);
21
+ const parts = url.pathname.split('/');
22
+ if (!workspace || !uuid(workspace) || url.origin !== 'https://storage.googleapis.com' || url.username || url.password || url.hash
23
+ || parts.length !== 7 || !parts[1] || parts[2] !== 'private' || !uuid(parts[3]) || parts[4] !== workspace
24
+ || parts[5] !== 'capture-clips' || parts[6] !== `${clip.id}.mp4`
25
+ || ticket.method !== 'PUT' || Object.keys(ticket.headers).sort().join(',') !== 'Content-Type,x-goog-if-generation-match,x-goog-meta-firedrill-clip-artifact,x-goog-meta-firedrill-clip-id'
26
+ || ticket.headers['Content-Type'] !== 'video/mp4' || ticket.headers['x-goog-if-generation-match'] !== '0'
27
+ || !uuid(ticket.headers['x-goog-meta-firedrill-clip-artifact']) || ticket.headers['x-goog-meta-firedrill-clip-id'] !== clip.id
28
+ || !Number.isFinite(Date.parse(ticket.expires_at)) || !captureClipMatches(ticket.clip, prefix, clip.id)
29
+ || !sameCaptureSelection(ticket.clip, clip) || ticket.clip.state !== 'uploading')
30
+ throw new Error('The original private clip upload could not be confirmed. No bytes were transferred.');
31
+ return url;
32
+ }
@@ -0,0 +1,53 @@
1
+ import { memoryProbeMatches } from './revision-contracts.js';
2
+ const count = (value) => Number.isSafeInteger(value) && value >= 0;
3
+ function summaryMatches(value, cohort, kind) {
4
+ const c = value?.scenario;
5
+ if (!c || c.scope !== 'scenario_schedule' || !['planned', 'retained', 'invoked', 'completed', 'target_failed',
6
+ 'platform_failed', 'timed_out', 'canceled', 'unfinished', 'changed_world', 'unconfirmed_world'].every(key => count(c[key]))
7
+ || c.invoked > c.retained || c.changed_world + c.unconfirmed_world > c.retained
8
+ || c.completed + c.target_failed + c.platform_failed + c.timed_out + c.canceled + c.unfinished !== c.retained
9
+ || ![value.observed, value.assessed, value.not_assessable, value.not_applicable, value.missing, value.without_assessment].every(count)
10
+ || value.observed + c.changed_world + c.unconfirmed_world + value.without_assessment !== c.retained
11
+ || value.assessed + value.not_assessable + value.not_applicable + value.missing !== value.observed
12
+ || [value.mean, value.minimum, value.maximum].some(one => one !== null && (!Number.isFinite(one) || one < 0))
13
+ || (value.assessed > 0) !== (value.mean !== null && value.minimum !== null && value.maximum !== null))
14
+ return false;
15
+ if (kind === 'style')
16
+ return true;
17
+ if (!('distribution' in value) || !Array.isArray(value.distribution) || value.distribution.length !== cohort.levels.length - 1)
18
+ return false;
19
+ return value.distribution.every((bin, index) => bin.index === index && bin.minimum === index && bin.maximum === index + 1
20
+ && bin.upper_inclusive === (index === value.distribution.length - 1) && count(bin.count))
21
+ && value.distribution.reduce((total, bin) => total + bin.count, 0) === value.assessed;
22
+ }
23
+ function cohortKindMatches(cohort, kind) {
24
+ return kind === 'memory' ? 'memory' in cohort && Array.isArray(cohort.memory.probes)
25
+ : kind === 'style' ? 'parser' in cohort && typeof cohort.parser === 'string' && !!cohort.parser
26
+ : !('memory' in cohort) && !('parser' in cohort);
27
+ }
28
+ function selectedRunsMatch(page, selected) {
29
+ return !!page && !!page.current && !!page.baseline && Number.isSafeInteger(page.count) && page.count >= 0
30
+ && Number.isSafeInteger(page.page_size) && page.page_size > 0 && page.page_size <= 100
31
+ && Array.isArray(page.results) && page.results.length <= page.page_size
32
+ && page.current.id === selected.current && page.baseline.id === selected.baseline
33
+ && selected.current !== selected.baseline && page.kind === selected.kind;
34
+ }
35
+ export function comparisonPageMatches(page, selected) {
36
+ return selectedRunsMatch(page, selected) && page.results.every(row => cohortKindMatches(row.cohort, selected.kind)
37
+ && summaryMatches(row.current, row.cohort, selected.kind) && summaryMatches(row.baseline, row.cohort, selected.kind));
38
+ }
39
+ export function comparisonObservationsMatch(page, selected) {
40
+ if (!selectedRunsMatch(page, selected) || page.cohort.assessment_id !== selected.assessment
41
+ || !cohortKindMatches(page.cohort, selected.kind)
42
+ || !summaryMatches(page.summary.current, page.cohort, selected.kind)
43
+ || !summaryMatches(page.summary.baseline, page.cohort, selected.kind)
44
+ || selected.cohort && page.cohort.identity !== selected.cohort.identity
45
+ || !page.results.every(row => (row.side === 'current' ? row.campaign_id === selected.current
46
+ : row.side === 'baseline' && row.campaign_id === selected.baseline)
47
+ && (selected.side === 'both' || row.side === selected.side)))
48
+ return false;
49
+ if (page.kind !== 'memory')
50
+ return page.probe === null && selected.probe === undefined;
51
+ const probe = page.cohort.memory.probes[selected.probe ?? 0];
52
+ return !!probe && !!page.probe && memoryProbeMatches(page.probe, probe);
53
+ }
@@ -0,0 +1,34 @@
1
+ function availableValueMatches(row) {
2
+ return row.state === 'available' ? row.value !== null && Number.isFinite(row.value) && row.value >= 0 && row.value <= 100
3
+ : row.value === null;
4
+ }
5
+ export function compositeMatches(value, campaign, execution) {
6
+ return value.campaign_id === campaign && (!execution || value.execution_id === execution) && availableValueMatches(value)
7
+ && (value.state === 'not_configured' ? value.dimensions.length === 0 && value.required_checks.length === 0
8
+ : value.dimensions.every(row => row.levels.length === row.values.length));
9
+ }
10
+ export function compositePageMatches(value, campaign) {
11
+ return value.campaign_id === campaign && value.results.every(row => compositeMatches(row, campaign));
12
+ }
13
+ function selectedRunsMatch(value, current, baseline) {
14
+ return current !== baseline && value.current.id === current && value.baseline.id === baseline;
15
+ }
16
+ function countsMatch(cohort) {
17
+ return [cohort.current, cohort.baseline].every(side => [side.planned, side.retained, side.changed_world, side.unconfirmed_world].every(value => Number.isSafeInteger(value) && value >= 0) && side.changed_world + side.unconfirmed_world <= side.retained);
18
+ }
19
+ export function compositeGroupsMatch(value, current, baseline) {
20
+ return selectedRunsMatch(value, current, baseline) && value.results.every(row => /^[a-f0-9]{64}$/.test(row.id)
21
+ && countsMatch(row) && row.dimensions.every(dimension => dimension.levels.length === dimension.values.length));
22
+ }
23
+ export function compositeModelsMatch(value, current, baseline, cohort) {
24
+ return selectedRunsMatch(value, current, baseline) && value.cohort.id === cohort && countsMatch(value.cohort);
25
+ }
26
+ export function compositeObservationsMatch(value, selected) {
27
+ return selectedRunsMatch(value, selected.current, selected.baseline) && value.cohort.id === selected.cohort
28
+ && countsMatch(value.cohort)
29
+ && value.results.every(row => (selected.side === 'both' || row.side === selected.side)
30
+ && (selected.status === 'all' || (row.value === null ? 'unavailable' : 'available') === selected.status)
31
+ && (selected.model === undefined || row.model === selected.model) && availableValueMatches(row)
32
+ && (row.side === 'current' ? row.campaign_id === selected.current
33
+ : row.side === 'baseline' && row.campaign_id === selected.baseline));
34
+ }
@@ -0,0 +1,76 @@
1
+ const recordingId = (value) => typeof value === 'string' && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(value);
2
+ export function recordingMatches(value, selectedId) {
3
+ const row = value;
4
+ return !!row && recordingId(row.id) && (!selectedId || row.id === selectedId) && typeof row.filename === 'string' && row.filename.length <= 255
5
+ && ['otlp_json', 'langfuse_json', 'incident_json', 'har_json'].includes(row.format)
6
+ && ['uploading', 'processing', 'review', 'accepted', 'rejected', 'revoked'].includes(row.state)
7
+ && typeof row.can_complete === 'boolean' && typeof row.source_revision === 'string' && row.source_revision.length <= 256
8
+ && Number.isFinite(Date.parse(row.created_at)) && (row.reviewed_at === null || Number.isFinite(Date.parse(row.reviewed_at)))
9
+ && (row.failure === null || typeof row.failure === 'string') && !!row.summary && typeof row.summary === 'object' && !Array.isArray(row.summary)
10
+ && (row.summary.record_count === undefined || Number.isSafeInteger(row.summary.record_count) && row.summary.record_count > 0)
11
+ && (row.summary.gaps === undefined || Array.isArray(row.summary.gaps) && row.summary.gaps.every(one => typeof one === 'string'));
12
+ }
13
+ function recordingPage(value, page, maximum = 100) {
14
+ return !!value && value.page === page && Number.isSafeInteger(value.count) && value.count >= 0 && Number.isSafeInteger(value.page_size)
15
+ && value.page_size > 0 && value.page_size <= maximum && Array.isArray(value.results) && value.results.length <= value.page_size && value.results.length <= value.count;
16
+ }
17
+ export function recordingsMatch(value, scope, page, query = '') {
18
+ return !!value && value.workspace_id === scope.workspace && value.world_id === scope.world && value.query === query.trim()
19
+ && recordingPage(value, page) && Number.isSafeInteger(value.limits?.max_upload_bytes) && value.limits.max_upload_bytes > 0
20
+ && value.results.every(row => recordingMatches(row));
21
+ }
22
+ export function recordingRequestMatches(value, scope, key) {
23
+ return !!value && value.workspace_id === scope.workspace && value.world_id === scope.world && value.request_key === key
24
+ && (value.state === 'not_retained' ? value.recording === null : value.state === 'received' && recordingMatches(value.recording));
25
+ }
26
+ export function recordedObservationsMatch(value, scope, context, page, query = '') {
27
+ return !!value && value.workspace_id === scope.workspace && value.world_id === scope.world && value.context_id === context
28
+ && value.query === query.trim() && recordingPage(value, page, 25) && value.results.every(row => !!row && typeof row.pointer === 'string'
29
+ && typeof row.content_omitted === 'boolean' && typeof row.name === 'string' && row.name.length <= 512
30
+ && ['tool', 'conversation', 'observation', 'task', 'policy'].includes(row.kind)
31
+ && (row.operation === null || typeof row.operation === 'string' && row.operation.length <= 512)
32
+ && (!row.content_omitted || row.input === null && row.output === null));
33
+ }
34
+ export function samePolicyVersion(actual, expected) {
35
+ return actual.id === expected.id && actual.agent_id === expected.agent_id
36
+ && actual.policy_id === expected.policy_id && actual.version === expected.version;
37
+ }
38
+ export function policyActionConfirmed(actual, before, action) {
39
+ return samePolicyVersion(actual, before) && Number.isSafeInteger(actual.latest_version)
40
+ && actual.latest_version >= before.latest_version && (action === 'archive' ? actual.archived
41
+ : action === 'restore' ? !actual.archived && !actual.removed
42
+ : action === 'remove' ? actual.removed && !actual.available
43
+ : actual.state === 'revoked' && !actual.available);
44
+ }
45
+ export function policyUploadDestination(ticket, workspace, format) {
46
+ const types = { text: 'text/plain', markdown: 'text/markdown',
47
+ pdf: 'application/pdf', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' };
48
+ const url = new URL(ticket.upload_url ?? '');
49
+ if (!/^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(ticket.id)
50
+ || url.origin !== 'https://storage.googleapis.com' || url.username || url.password || url.hash
51
+ || !url.pathname.endsWith(`/${workspace}/policies/${ticket.id}/original`)
52
+ || ticket.method !== 'PUT' || !ticket.headers
53
+ || Object.keys(ticket.headers).sort().join(',') !== 'Content-Type,x-goog-if-generation-match'
54
+ || ticket.headers['Content-Type'] !== types[format] || ticket.headers['x-goog-if-generation-match'] !== '0') {
55
+ throw new Error('The private policy upload destination could not be confirmed. No document was transferred.');
56
+ }
57
+ return url.href;
58
+ }
59
+ export function recordingProcessingConfirmed(row, id) {
60
+ return row.id === id && ['processing', 'review', 'accepted'].includes(row.state);
61
+ }
62
+ export function recordingUploadDestination(ticket, workspace, expectedId) {
63
+ const uuid = (value) => /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(value);
64
+ const url = new URL(ticket.upload_url);
65
+ if (!uuid(ticket.id) || expectedId && ticket.id !== expectedId || ticket.method !== 'PUT'
66
+ || url.origin !== 'https://storage.googleapis.com' || url.username || url.password || url.hash
67
+ || !url.pathname.endsWith(`/${workspace}/context/${ticket.id}/original`)
68
+ || Object.keys(ticket.headers).sort().join(',') !== 'Content-Type,x-goog-if-generation-match,x-goog-meta-firedrill-recording-artifact,x-goog-meta-firedrill-recording-context,x-goog-meta-firedrill-recording-purpose'
69
+ || ticket.headers['Content-Type'] !== 'application/json' || ticket.headers['x-goog-if-generation-match'] !== '0'
70
+ || !uuid(ticket.headers['x-goog-meta-firedrill-recording-artifact'])
71
+ || ticket.headers['x-goog-meta-firedrill-recording-context'] !== ticket.id
72
+ || ticket.headers['x-goog-meta-firedrill-recording-purpose'] !== 'recorded_context') {
73
+ throw new Error('The recording upload destination could not be confirmed. No file was transferred.');
74
+ }
75
+ return url.href;
76
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export function continuityRequirementsMatch(value, world, revision, selectionRevision) {
2
+ const row = value;
3
+ return !!row && typeof row === 'object' && row.schema === 'firedrill.continuity-requirements.v1'
4
+ && row.world_id === world && row.world_revision === revision && row.selection_revision === selectionRevision && /^[a-f0-9]{64}$/.test(row.selection_sha256)
5
+ && Number.isSafeInteger(row.continuous_scenarios) && row.continuous_scenarios >= 0
6
+ && Number.isSafeInteger(row.minimum_trial_seconds) && row.minimum_trial_seconds >= 0 && row.minimum_trial_seconds <= 2592000
7
+ && (row.continuous_scenarios === 0 ? row.minimum_trial_seconds === 0 : row.minimum_trial_seconds > 5);
8
+ }
@@ -0,0 +1,34 @@
1
+ const uuid = (value) => typeof value === 'string' && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(value);
2
+ const count = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
3
+ export const nativeCheckpointScopes = ['owned_postgres_rows_sequences_and_sql_clock', 'declared_sqlite_files', 'owned_postgres_and_declared_sqlite_files'];
4
+ export function coordinatedCheckpointMatches(value, world, selected = {}) {
5
+ return !!value && uuid(value.id) && value.world_id === world && uuid(value.session_id) && uuid(value.request_key)
6
+ && (selected.session === undefined || value.session_id === selected.session) && (selected.id === undefined || value.id === selected.id)
7
+ && (selected.key === undefined || value.request_key === selected.key) && (selected.name === undefined || value.name === selected.name)
8
+ && typeof value.name === 'string' && value.name.length > 0 && value.name.length <= 120
9
+ && ['pending', 'retained', 'unavailable'].includes(value.state) && typeof value.available === 'boolean'
10
+ && Number.isFinite(Date.parse(value.created_at)) && (value.captured_at === null || Number.isFinite(Date.parse(value.captured_at)))
11
+ && count(value.application_component_count) && value.application_component_count <= 1000 && count(value.excluded_count) && value.excluded_count <= 1000
12
+ && (value.native_scope === null || nativeCheckpointScopes.includes(value.native_scope))
13
+ && (value.controlled_services_included === null || value.controlled_services_included === true)
14
+ && ['application_consistent', 'mixed_or_crash_consistent', 'not_observed'].includes(value.consistency)
15
+ && ['source_attested_quiescence_and_native_capture', 'not_observed'].includes(value.consistency_basis)
16
+ && (value.problem === null || typeof value.problem === 'string')
17
+ && (!value.available || value.state === 'retained' && value.captured_at !== null && value.application_component_count > 0
18
+ && value.controlled_services_included === true && value.native_scope !== null && value.consistency !== 'not_observed'
19
+ && value.consistency_basis === 'source_attested_quiescence_and_native_capture');
20
+ }
21
+ export function coordinatedCheckpointDetailMatches(value, world, selected = {}) {
22
+ return coordinatedCheckpointMatches(value, world, selected) && Array.isArray(value.components) && value.components.length <= 1000
23
+ && value.components.every(one => !!one && typeof one.name === 'string' && one.name.length > 0
24
+ && ['application_memory', 'database', 'files', 'queue_cursor', 'conversation', 'scheduled_jobs'].includes(one.kind)
25
+ && ['application_consistent', 'crash_consistent'].includes(one.consistency))
26
+ && Array.isArray(value.excluded) && value.excluded.length <= 1000 && value.excluded.every(one => typeof one === 'string' && one.length > 0 && one.length <= 256)
27
+ && (value.event_watermark === null || typeof value.event_watermark === 'string' && value.event_watermark.length > 0 && value.event_watermark.length <= 256)
28
+ && typeof value.barrier_released === 'boolean' && (value.record_count === null || count(value.record_count))
29
+ && (value.collection_count === null || count(value.collection_count))
30
+ && (value.available ? value.components.length === value.application_component_count && value.excluded.length === value.excluded_count
31
+ && value.barrier_released && value.event_watermark !== null && value.record_count !== null && value.collection_count !== null
32
+ : value.components.length === 0 && value.excluded.length === 0 && !value.barrier_released && value.event_watermark === null
33
+ && value.record_count === null && value.collection_count === null);
34
+ }
@@ -0,0 +1,88 @@
1
+ const uuid = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/;
2
+ const hash = /^[a-f0-9]{64}$/;
3
+ const optionalId = (value) => value === null || uuid.test(value);
4
+ export function datasetRead(value, matches) {
5
+ if (!matches)
6
+ throw new Error('The dataset response did not match this saved version or original request. Inspect its retained history.');
7
+ return value;
8
+ }
9
+ export function datasetScope(prefix, actor) {
10
+ const parts = prefix.split('/');
11
+ if (parts[0] !== '' || parts[1] !== 'api' || parts[2] !== 'workspaces' || !uuid.test(parts[3] ?? ''))
12
+ return null;
13
+ return parts.length === 5 && parts[4] === 'tools' ? { workspace: parts[3], actor, kind: 'tool' }
14
+ : parts.length === 6 && parts[4] === 'worlds' && uuid.test(parts[5] ?? '') ? { workspace: parts[3], actor, kind: 'world', world: parts[5] } : null;
15
+ }
16
+ export function datasetMatches(value, scope, selected = {}) {
17
+ if (!value || value.workspace_id !== scope.workspace || value.kind !== scope.kind
18
+ || ![value.id, value.workspace_id, value.actor_id, value.request_key, value.series_id].every(one => uuid.test(one))
19
+ || !optionalId(value.previous_version_id) || !hash.test(value.request_digest) || !Number.isSafeInteger(value.version) || value.version < 1
20
+ || !Number.isSafeInteger(value.edit_count) || value.edit_count < 0 || value.edit_count > 100000
21
+ || !['saving', 'retained', 'failed', 'withdrawn'].includes(value.state)
22
+ || selected.id !== undefined && selected.id !== value.id || selected.key !== undefined && (selected.key !== value.request_key || value.actor_id !== scope.actor)
23
+ || selected.digest !== undefined && selected.digest !== value.request_digest || selected.name !== undefined && selected.name !== value.name
24
+ || selected.previous !== undefined && selected.previous !== value.previous_version_id || selected.editCount !== undefined && selected.editCount !== value.edit_count
25
+ || selected.withdrawn && (value.state !== 'withdrawn' || !value.withdrawn_at || value.available)
26
+ || value.available !== (value.file !== null) || value.available && (value.state !== 'retained' || !!value.withdrawn_at)
27
+ || value.file && (!Number.isSafeInteger(value.file.size) || value.file.size < 1 || value.file.size > 8 * 1024 ** 2 || !hash.test(value.file.sha256)))
28
+ return false;
29
+ return value.kind === 'tool' ? uuid.test(value.implementation_id) && uuid.test(value.checkpoint_id)
30
+ && (!selected.source || selected.source === value.checkpoint_id) && (!selected.implementation || selected.implementation === value.implementation_id)
31
+ : scope.kind === 'world' && value.world_id === scope.world && uuid.test(value.observation_id)
32
+ && (!selected.source || selected.source === value.observation_id) && (!value.can_start_session || value.available);
33
+ }
34
+ export function datasetPageMatches(value, scope, filters = {}) {
35
+ if (!value || value.workspace_id !== scope.workspace || value.query !== (filters.query ?? '').trim()
36
+ || value.state_filter !== (filters.state ?? 'all') || value.series_id_filter !== (filters.series ?? null)
37
+ || !Number.isSafeInteger(value.page) || value.page < 1 || filters.page !== undefined && value.page !== filters.page
38
+ || !Number.isSafeInteger(value.page_size) || value.page_size < 1 || value.page_size > 100 || value.results.length > value.page_size
39
+ || !Number.isSafeInteger(value.count) || value.count < 0 || !Number.isSafeInteger(value.capacity.recipe_bytes)
40
+ || value.capacity.recipe_bytes < 1 || value.capacity.recipe_bytes > 8 * 1024 ** 2)
41
+ return false;
42
+ if ('world_id' in value ? scope.kind !== 'world' || value.world_id !== scope.world || value.observation_id_filter !== (filters.source ?? null)
43
+ || value.startable_filter !== (filters.startable ?? false)
44
+ : scope.kind !== 'tool' || value.checkpoint_id_filter !== (filters.source ?? null) || value.implementation_id_filter !== (filters.implementation ?? null))
45
+ return false;
46
+ return value.results.every(row => datasetMatches(row, scope, { source: filters.source, implementation: filters.implementation })
47
+ && (value.state_filter === 'all' || row.state === value.state_filter) && (!filters.series || row.series_id === filters.series));
48
+ }
49
+ export function datasetDocumentMatches(value, scope, row) {
50
+ if (!datasetMatches(row, scope) || !row.available || !value || value.id !== row.id || !Array.isArray(value.edits) || value.edits.length !== row.edit_count)
51
+ return false;
52
+ return value.schema === 'firedrill.tool-dataset.v1' ? row.kind === 'tool' && value.implementation_id === row.implementation_id
53
+ && value.checkpoint_id === row.checkpoint_id && [value.checkpoint_sha256, value.contract_digest, value.schema_digest].every(one => hash.test(one))
54
+ : row.kind === 'world' && value.world_id === row.world_id && value.observation_id === row.observation_id && uuid.test(value.source_id)
55
+ && Number.isSafeInteger(value.world_revision) && value.world_revision >= 1 && [value.configuration_digest, value.archive_digest, value.index_digest].every(one => hash.test(one));
56
+ }
57
+ function cell(value, depth = 0) {
58
+ if (!value || typeof value !== 'object' || Array.isArray(value) || depth > 24)
59
+ return false;
60
+ const item = value, keys = Object.keys(item).sort().join(',');
61
+ if (item.type === 'null')
62
+ return keys === 'type';
63
+ if (item.type === 'binary' && item.encoding === 'base64')
64
+ return keys === 'encoding,type,value' && typeof item.value === 'string';
65
+ if (keys !== 'type,value')
66
+ return false;
67
+ if (item.type === 'boolean')
68
+ return typeof item.value === 'boolean';
69
+ if (['string', 'integer', 'decimal', 'datetime', 'date', 'time', 'uuid', 'binary'].includes(String(item.type)))
70
+ return typeof item.value === 'string';
71
+ if (item.type === 'float')
72
+ return typeof item.value === 'number' && Number.isFinite(item.value) && (!Number.isInteger(item.value) || Number.isSafeInteger(item.value))
73
+ || typeof item.value === 'string' && ['nan', 'inf', '-inf'].includes(item.value);
74
+ if (item.type === 'array')
75
+ return Array.isArray(item.value) && item.value.every(one => cell(one, depth + 1));
76
+ return item.type === 'object' && !!item.value && typeof item.value === 'object' && !Array.isArray(item.value)
77
+ && Object.values(item.value).every(one => cell(one, depth + 1));
78
+ }
79
+ export function datasetEdits(value) {
80
+ return Array.isArray(value) && value.length <= 100000 && value.every(edit => {
81
+ if (!edit || typeof edit !== 'object' || Array.isArray(edit) || Object.keys(edit).sort().join(',') !== 'action,collection,position,values'
82
+ || typeof edit.collection !== 'string' || !hash.test(edit.collection) || !['insert', 'update', 'delete'].includes(edit.action)
83
+ || (edit.action === 'insert' ? edit.position !== null : !Number.isSafeInteger(edit.position) || edit.position < 0))
84
+ return false;
85
+ return edit.action === 'delete' ? edit.values === null : !!edit.values && typeof edit.values === 'object' && !Array.isArray(edit.values)
86
+ && (edit.action !== 'update' || Object.keys(edit.values).length > 0) && Object.values(edit.values).every(one => cell(one));
87
+ });
88
+ }
@@ -0,0 +1,36 @@
1
+ const object = (value) => Boolean(value && typeof value === 'object' && !Array.isArray(value));
2
+ const sha = (value) => typeof value === 'string' && /^[a-f0-9]{64}$/.test(value);
3
+ const id = (value) => typeof value === 'string' && /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/.test(value);
4
+ export function dependencyDecisionMatches(value) {
5
+ if (!object(value))
6
+ return false;
7
+ const keys = Object.keys(value).sort().join(',');
8
+ return value.action === 'catalog' ? keys === 'acknowledge_coverage_gaps,action,candidate_id' && sha(value.candidate_id) && value.acknowledge_coverage_gaps === true
9
+ : value.action === 'generated' ? keys === 'acknowledge_coverage_gaps,action' && value.acknowledge_coverage_gaps === true
10
+ : value.action === 'continue' ? keys === 'action,continuation_digest' && sha(value.continuation_digest)
11
+ : value.action === 'withdraw' && keys === 'action';
12
+ }
13
+ export function dependencyDecisionCanonical(value) {
14
+ if (!dependencyDecisionMatches(value))
15
+ throw new Error('Choose the exact original dependency decision.');
16
+ return '{' + Object.keys(value).sort().map(key => JSON.stringify(key) + ':' + JSON.stringify(value[key])).join(',') + '}';
17
+ }
18
+ export async function dependencyDecisionDigest(value) {
19
+ const bytes = await globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(dependencyDecisionCanonical(value)));
20
+ return Array.from(new Uint8Array(bytes), one => one.toString(16).padStart(2, '0')).join('');
21
+ }
22
+ export function dependencyDecisionReceiptMatches(value, scope, digest) {
23
+ if (!object(value) || Object.keys(value).sort().join(',') !== 'accepted_at,accepted_state,action,actor_id,decision_digest,preparation_id,schema,state,workspace_id,world_id'
24
+ || value.schema !== 'firedrill.dependency-decision-receipt.v1' || value.actor_id !== scope.actor || !id(scope.actor)
25
+ || value.workspace_id !== scope.workspace || !id(scope.workspace) || value.world_id !== scope.world || !id(scope.world)
26
+ || value.preparation_id !== scope.preparation || !id(scope.preparation) || value.decision_digest !== digest || !sha(digest)
27
+ || !['accepted', 'not_observed', 'unavailable'].includes(String(value.state)))
28
+ return false;
29
+ const accepted = ['catalog', 'generated', 'withdraw', 'continue'].includes(String(value.action))
30
+ && ['queued', 'adopting', 'applied', 'withdrawn'].includes(String(value.accepted_state))
31
+ && (value.action === 'catalog' ? ['adopting', 'applied'].includes(String(value.accepted_state))
32
+ : value.action === 'generated' ? value.accepted_state === 'applied' : value.action === 'continue' ? value.accepted_state === 'queued' : value.accepted_state === 'withdrawn')
33
+ && typeof value.accepted_at === 'string' && Number.isFinite(Date.parse(value.accepted_at));
34
+ const absent = value.action === null && value.accepted_state === null && value.accepted_at === null;
35
+ return value.state === 'accepted' ? accepted : value.state === 'not_observed' ? absent : absent || accepted;
36
+ }
@@ -0,0 +1,43 @@
1
+ const object = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
2
+ const names = (v, maximum = 100) => Array.isArray(v) && v.length <= maximum
3
+ && v.every(one => typeof one === 'string' && /^[A-Za-z0-9_.~-]{1,128}$/.test(one));
4
+ const optionalName = (v) => v === null || typeof v === 'string' && /^[A-Za-z_][A-Za-z0-9_.~-]{0,127}$/.test(v);
5
+ export function protocolProfileMatches(v) {
6
+ return object(v) && typeof v.available === 'boolean' && typeof v.http_declared === 'boolean'
7
+ && typeof v.aliases_declared === 'boolean' && (v.request_encoding === null || ['json', 'query', 'form', 'multipart', 'text', 'base64', 'none'].includes(String(v.request_encoding)))
8
+ && (v.response_encoding === null || ['json', 'text', 'binary'].includes(String(v.response_encoding)))
9
+ && names(v.mapped_header_names) && names(v.ignored_metadata_headers) && names(v.query_names) && names(v.multipart_part_names)
10
+ && v.multipart_part_names.every(name => /^[A-Za-z_][A-Za-z0-9_.-]{0,99}$/.test(name))
11
+ && optionalName(v.body_argument) && optionalName(v.content_type_argument) && (v.idempotency_header === null || v.idempotency_header === 'Idempotency-Key')
12
+ && optionalName(v.idempotency_argument) && names(v.mcp_aliases, 16);
13
+ }
14
+ export function protocolComparisonMatches(v) {
15
+ return object(v) && protocolProfileMatches(v.source) && protocolProfileMatches(v.package)
16
+ && (v.explicit_expectations_match === null || typeof v.explicit_expectations_match === 'boolean') && v.runtime_validated === false;
17
+ }
18
+ export function compatibilityPageMatches(v, request, candidate, page) {
19
+ return object(v) && v.request_id === request && v.candidate_id === candidate && v.page === page
20
+ && v.page_size === 25 && typeof v.count === 'number' && Number.isSafeInteger(v.count) && v.count >= 0
21
+ && v.behavior_validated === false && Array.isArray(v.results) && v.results.length <= 25 && v.results.every(one => object(one)
22
+ && (one.name === null || typeof one.name === 'string' && one.name.length <= 255)
23
+ && ['declaration_match', 'missing', 'mismatch', 'unsupported'].includes(String(one.state))
24
+ && (one.reason === null || typeof one.reason === 'string') && Array.isArray(one.gaps)
25
+ && one.gaps.length <= 30 && one.gaps.every(gap => typeof gap === 'string' && gap.length <= 2000)
26
+ && (one.protocol_metadata === undefined || protocolComparisonMatches(one.protocol_metadata)));
27
+ }
28
+ export function protocolProfileLines(value) {
29
+ if (!value.available)
30
+ return ['Protocol metadata is unavailable. Inspect the original declaration.'];
31
+ return [
32
+ ...(value.http_declared ? [`Request ${value.request_encoding}; response ${value.response_encoding}.`,
33
+ ...(value.mapped_header_names.length ? ['Mapped headers: ' + value.mapped_header_names.join(', ')] : []),
34
+ ...(value.ignored_metadata_headers.length ? ['Ignored request metadata: ' + value.ignored_metadata_headers.join(', ')] : []),
35
+ ...(value.query_names.length ? ['Query parameters: ' + value.query_names.join(', ')] : []),
36
+ ...(value.multipart_part_names.length ? ['Multipart parts: ' + value.multipart_part_names.join(', ')] : []),
37
+ ...(value.body_argument ? ['Body argument: ' + value.body_argument] : []),
38
+ ...(value.content_type_argument ? ['Body media type argument: ' + value.content_type_argument] : []),
39
+ ...(value.idempotency_header ? [`Idempotency: ${value.idempotency_header} from ${value.idempotency_argument}.`] : [])]
40
+ : ['HTTP data mapping not declared.']),
41
+ ...(value.mcp_aliases.length ? ['MCP aliases: ' + value.mcp_aliases.join(', ')] : []),
42
+ ];
43
+ }
@@ -0,0 +1,51 @@
1
+ const uuid = (value) => typeof value === 'string'
2
+ && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(value);
3
+ const positive = (value) => Number.isSafeInteger(value) && Number(value) > 0;
4
+ export function executionProposalId(value) {
5
+ if (!value || typeof value !== 'object' || Array.isArray(value))
6
+ return null;
7
+ const row = value;
8
+ return row.schema === 'firedrill.director-execution-proposal.v1' && uuid(row.execution_proposal_id)
9
+ ? row.execution_proposal_id : null;
10
+ }
11
+ export function isExecutionProposal(value) {
12
+ if (!value || typeof value !== 'object' || Array.isArray(value))
13
+ return false;
14
+ const row = value;
15
+ return row.schema === 'firedrill.director-execution-proposal.v1'
16
+ && ['id', 'actor_id', 'world_id', 'source_id', 'plan_request_key', 'admission_request_key', 'validation_request_key']
17
+ .every(key => uuid(row[key]))
18
+ && (row.previous_plan_id === null || uuid(row.previous_plan_id))
19
+ && typeof row.title === 'string' && row.title.length > 0 && row.title.length <= 160
20
+ && ['validate', 'simulate'].includes(row.action) && ['choose', 'managed', 'local'].includes(row.location)
21
+ && [row.world_revision, row.repetitions, row.parallelism, row.trial_seconds].every(positive)
22
+ && Number.isSafeInteger(row.configuration_revision) && row.configuration_revision >= 0
23
+ && Number.isSafeInteger(row.scenario_count) && row.scenario_count >= 0
24
+ && Number.isSafeInteger(row.planned_trials) && row.planned_trials === row.scenario_count * row.repetitions
25
+ && typeof row.selection_revision === 'string' && /^[a-z0-9-]{1,128}$/.test(row.selection_revision)
26
+ && typeof row.evaluation_revision === 'string' && /^[a-f0-9]{64}$/.test(row.evaluation_revision)
27
+ && ['available', 'current', 'can_execute'].every(key => typeof row[key] === 'boolean')
28
+ && !!row.selector && ['ids', 'all_matching'].includes(row.selector.mode) && row.selector.query === ''
29
+ && Array.isArray(row.selector.ids) && row.selector.ids.every(uuid)
30
+ && row.selector.ids.length <= 100 && new Set(row.selector.ids).size === row.selector.ids.length
31
+ && Array.isArray(row.selector.excluded) && row.selector.excluded.length === 0
32
+ && (row.selector.mode === 'ids' ? row.selector.ids.length > 0 : row.selector.ids.length === 0)
33
+ && (row.action === 'validate' ? row.scenario_count === 0 && row.planned_trials === 0
34
+ : row.scenario_count > 0 && (row.selector.mode !== 'ids' || row.scenario_count === row.selector.ids.length))
35
+ && (!row.can_execute || row.available && row.current)
36
+ && (row.plan === null || uuid(row.plan?.id) && typeof row.plan.current === 'boolean')
37
+ && (row.campaign === null || uuid(row.campaign?.id) && typeof row.campaign.state === 'string'
38
+ && ['managed', 'local'].includes(row.campaign.execution_location))
39
+ && (row.validation === null || uuid(row.validation?.id) && typeof row.validation.state === 'string'
40
+ && typeof row.validation.active === 'boolean' && typeof row.validation.current === 'boolean'
41
+ && ['managed', 'local'].includes(row.validation.execution_location));
42
+ }
43
+ export function executionPlanMatches(proposal, plan) {
44
+ const ids = (values) => [...new Set(values)].sort().join(',');
45
+ return !!plan && plan.current && plan.scenario_count === proposal.scenario_count
46
+ && plan.planned_trials === proposal.planned_trials && plan.repetitions === proposal.repetitions
47
+ && plan.parallelism === proposal.parallelism && plan.trial_seconds === proposal.trial_seconds
48
+ && (proposal.location === 'choose' || plan.execution.location === proposal.location)
49
+ && plan.selector.mode === proposal.selector.mode && plan.selector.query === ''
50
+ && ids(plan.selector.ids) === ids(proposal.selector.ids) && ids(plan.selector.excluded) === '';
51
+ }