@moondeck/station 0.0.1 → 1.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 (326) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +149 -2
  3. package/bin/uai-host.mjs +130 -0
  4. package/db/migrations/0000_host_tasks.sql +12 -0
  5. package/db/migrations/0001_host_ui.sql +11 -0
  6. package/db/migrations/0002_host_github_tokens.sql +8 -0
  7. package/db/migrations/0003_host_ssh_keys.sql +8 -0
  8. package/db/migrations/0004_host_owner_name.sql +1 -0
  9. package/db/migrations/0005_host_env_vars.sql +5 -0
  10. package/db/migrations/0006_host_project_env.sql +9 -0
  11. package/db/migrations/0007_host_github_token_kind.sql +7 -0
  12. package/db/migrations/0008_host_mcp_connections.sql +18 -0
  13. package/db/migrations/0009_host_agent_sessions.sql +15 -0
  14. package/db/migrations/0010_host_engine_accounts.sql +13 -0
  15. package/db/migrations/0011_codex_thread_id.sql +5 -0
  16. package/db/migrations/0012_agent_session_attach_key.sql +4 -0
  17. package/db/migrations/0013_github_credential_generations.sql +11 -0
  18. package/db/migrations/0014_host_inventory_event_index.sql +1 -0
  19. package/db/migrations/0015_host_settings.sql +9 -0
  20. package/db/migrations/0016_task_environment.sql +2 -0
  21. package/db/migrations/0017_engine_account_scope.sql +7 -0
  22. package/db/migrations/0018_engine_account_position.sql +3 -0
  23. package/db/migrations/0019_engine_account_store_ref.sql +3 -0
  24. package/db/migrations/0020_user_credential_store_ref.sql +6 -0
  25. package/db/migrations/0021_project_env_store_ref.sql +3 -0
  26. package/db/migrations/0022_task_project_ids.sql +5 -0
  27. package/db/migrations/0023_project_env_org.sql +4 -0
  28. package/db/migrations/0024_task_env_mode.sql +9 -0
  29. package/db/migrations/0025_project_env_authority.sql +147 -0
  30. package/db/migrations/0026_project_env_replica.sql +150 -0
  31. package/db/migrations/0027_cloud_credential_foundation.sql +51 -0
  32. package/db/migrations/0028_leased_engine_runtimes.sql +11 -0
  33. package/db/migrations/0029_task_shared_files_mode.sql +5 -0
  34. package/db/migrations/0030_credential_cleanup_restops.sql +12 -0
  35. package/db/migrations/meta/_journal.json +223 -0
  36. package/db/schema.ts +850 -0
  37. package/images/standard/Dockerfile +347 -0
  38. package/images/standard/README.md +167 -0
  39. package/images/standard/container/code-server-settings.json +63 -0
  40. package/images/standard/container/corepack-version +1 -0
  41. package/images/standard/container/uai-init +704 -0
  42. package/images/standard/container/uai-materialize-runtimes +1527 -0
  43. package/images/standard/container/uai-task-forwarder.mjs +303 -0
  44. package/images/standard/tool-versions +2 -0
  45. package/lib/__fixtures__/skill-index/SKILL.md +10 -0
  46. package/lib/__fixtures__/skill-index/skills/accessibility-checklist.md +7 -0
  47. package/lib/__fixtures__/skill-index/skills/brand-voice.md +9 -0
  48. package/lib/__fixtures__/skill-index/skills/design-tokens.md +9 -0
  49. package/lib/agent-cli.ts +1507 -0
  50. package/lib/agent-errors.ts +22 -0
  51. package/lib/agent.ts +672 -0
  52. package/lib/agents/attach-compatibility.ts +51 -0
  53. package/lib/agents/claude.ts +918 -0
  54. package/lib/agents/codex-token-usage.fixture.json +130 -0
  55. package/lib/agents/codex.ts +1392 -0
  56. package/lib/agents/cursor-period-usage.ts +253 -0
  57. package/lib/agents/cursor.ts +562 -0
  58. package/lib/agents/dispatch.ts +78 -0
  59. package/lib/agents/durable-proc.ts +334 -0
  60. package/lib/agents/factory.ts +57 -0
  61. package/lib/agents/grok.ts +381 -0
  62. package/lib/agents/kimi.ts +329 -0
  63. package/lib/agents/machine-durable.ts +604 -0
  64. package/lib/agents/mock.ts +133 -0
  65. package/lib/agents/mode.ts +64 -0
  66. package/lib/agents/opencode.ts +508 -0
  67. package/lib/agents/output-source.ts +3 -0
  68. package/lib/agents/proc.ts +221 -0
  69. package/lib/agents/rate-limit.ts +337 -0
  70. package/lib/agents/registry.ts +182 -0
  71. package/lib/agents/session-state.ts +197 -0
  72. package/lib/agents/skill-index-preamble.fixture.ts +26 -0
  73. package/lib/agents/transport.ts +741 -0
  74. package/lib/agents/types.ts +254 -0
  75. package/lib/agents/uai.ts +106 -0
  76. package/lib/agents/usage.ts +44 -0
  77. package/lib/apple-one-off.ts +277 -0
  78. package/lib/apple-runtime-recycle.ts +237 -0
  79. package/lib/apple-uninstall-teardown.ts +224 -0
  80. package/lib/assignment-evidence.ts +94 -0
  81. package/lib/attachments.ts +48 -0
  82. package/lib/browser-testing.ts +1537 -0
  83. package/lib/capture-flow.ts +332 -0
  84. package/lib/cloud-credential-cleanup-adapter.ts +123 -0
  85. package/lib/cloud-credential-host.ts +512 -0
  86. package/lib/cloud-credential-leases.ts +2587 -0
  87. package/lib/cloud-credential-runtime.ts +1357 -0
  88. package/lib/cloud-state.ts +56 -0
  89. package/lib/codex-auth.ts +456 -0
  90. package/lib/command-db.ts +310 -0
  91. package/lib/compose-network-recovery.ts +283 -0
  92. package/lib/connection-secret-redaction.ts +25 -0
  93. package/lib/container-runtime.ts +1453 -0
  94. package/lib/credential-cleanup-inventory.ts +490 -0
  95. package/lib/credential-consumers/engine-anchor.ts +1880 -0
  96. package/lib/credential-consumers/engines.ts +797 -0
  97. package/lib/credential-consumers/files.ts +934 -0
  98. package/lib/credential-consumers/github.ts +702 -0
  99. package/lib/credential-consumers/mcp.ts +389 -0
  100. package/lib/credential-consumers/task-files.ts +127 -0
  101. package/lib/credential-consumers/task-secrets.ts +10 -0
  102. package/lib/credential-store-pickup.ts +149 -0
  103. package/lib/credential-store-scope.ts +112 -0
  104. package/lib/credential-store.ts +932 -0
  105. package/lib/credentials-activation-authority.ts +709 -0
  106. package/lib/credentials-purge.ts +1006 -0
  107. package/lib/custom-connection-capture.ts +395 -0
  108. package/lib/custom-connection-launch.ts +384 -0
  109. package/lib/custom-connection-runtime.ts +141 -0
  110. package/lib/db.ts +80 -0
  111. package/lib/disk-pressure.ts +42 -0
  112. package/lib/docker-exec.ts +156 -0
  113. package/lib/engine-accounts.ts +1970 -0
  114. package/lib/engine-connect.ts +321 -0
  115. package/lib/engine-credential-env.ts +52 -0
  116. package/lib/engine-login.ts +2933 -0
  117. package/lib/engines.ts +1342 -0
  118. package/lib/enrollment-state.ts +251 -0
  119. package/lib/env-file.ts +246 -0
  120. package/lib/env-schema.ts +891 -0
  121. package/lib/env.ts +195 -0
  122. package/lib/fs-aliases.ts +49 -0
  123. package/lib/git-clone-credentials.ts +334 -0
  124. package/lib/git-diff.ts +530 -0
  125. package/lib/git-identity.ts +715 -0
  126. package/lib/github-git-auth.ts +207 -0
  127. package/lib/github-origin.ts +28 -0
  128. package/lib/github-tokens.ts +2439 -0
  129. package/lib/host-cloud-url.ts +62 -0
  130. package/lib/host-config.ts +279 -0
  131. package/lib/host-env.ts +424 -0
  132. package/lib/host-logs.ts +965 -0
  133. package/lib/internal-connections.ts +5 -0
  134. package/lib/keyed-promise-tail.ts +23 -0
  135. package/lib/launch-mode.ts +25 -0
  136. package/lib/lease.ts +239 -0
  137. package/lib/legacy-host.ts +769 -0
  138. package/lib/legacy-runtime-retirement.ts +424 -0
  139. package/lib/legacy-runtime-v1.fixture.ts +627 -0
  140. package/lib/machine-exec.ts +238 -0
  141. package/lib/machine-gateway-tunnel.ts +344 -0
  142. package/lib/machine-keys.ts +65 -0
  143. package/lib/machine-project-env-loader.ts +152 -0
  144. package/lib/machine-provider-aws.ts +923 -0
  145. package/lib/machine-provider-local.ts +338 -0
  146. package/lib/machine-provider.ts +90 -0
  147. package/lib/managed-activation-watcher.ts +72 -0
  148. package/lib/managed-install-owner-watcher.ts +55 -0
  149. package/lib/managed-operation-drain.ts +57 -0
  150. package/lib/managed-runtime.ts +4296 -0
  151. package/lib/managed-update-scheduler.ts +125 -0
  152. package/lib/mcp-capture.ts +865 -0
  153. package/lib/mcp-config-lock.ts +2 -0
  154. package/lib/mcp-connections.ts +959 -0
  155. package/lib/mcp-gateway.ts +2594 -0
  156. package/lib/obs.ts +512 -0
  157. package/lib/openrouter-budget.ts +247 -0
  158. package/lib/orchestrator.ts +11409 -0
  159. package/lib/person-capture.ts +327 -0
  160. package/lib/preview-ports.ts +85 -0
  161. package/lib/preview-sidecar.ts +331 -0
  162. package/lib/project-env-authority.ts +1319 -0
  163. package/lib/project-env-feature.ts +74 -0
  164. package/lib/project-env-legacy-tags.ts +130 -0
  165. package/lib/project-env-loader.ts +242 -0
  166. package/lib/project-env-replica.ts +2094 -0
  167. package/lib/project-env-schema-capture.ts +342 -0
  168. package/lib/project-env-staging.ts +148 -0
  169. package/lib/project-env-task-policy.ts +176 -0
  170. package/lib/project-env-task-replica.ts +1752 -0
  171. package/lib/release-feed.ts +61 -0
  172. package/lib/release-manifest.ts +710 -0
  173. package/lib/release-trust.ts +46 -0
  174. package/lib/repo-clone.ts +38 -0
  175. package/lib/routing/shadow.ts +261 -0
  176. package/lib/runner-boot.ts +10 -0
  177. package/lib/runtime-activation-tail.ts +279 -0
  178. package/lib/runtime-archive.ts +1216 -0
  179. package/lib/runtime-authority.ts +166 -0
  180. package/lib/runtime-guard.ts +36 -0
  181. package/lib/runtime-provider-state.ts +169 -0
  182. package/lib/runtime-reconnect.ts +86 -0
  183. package/lib/runtime-state.ts +1033 -0
  184. package/lib/safe-http.ts +364 -0
  185. package/lib/secrets-proxy/address.ts +95 -0
  186. package/lib/secrets-proxy/audit.ts +30 -0
  187. package/lib/secrets-proxy/ca-store.ts +200 -0
  188. package/lib/secrets-proxy/ca.ts +470 -0
  189. package/lib/secrets-proxy/container-steps.ts +138 -0
  190. package/lib/secrets-proxy/der.ts +273 -0
  191. package/lib/secrets-proxy/engine.ts +1633 -0
  192. package/lib/secrets-proxy/host.ts +93 -0
  193. package/lib/secrets-proxy/hostname.ts +57 -0
  194. package/lib/secrets-proxy/placeholders.ts +196 -0
  195. package/lib/secrets-proxy/policy.ts +150 -0
  196. package/lib/secrets-proxy/readiness.ts +148 -0
  197. package/lib/secrets-proxy/runtime.ts +582 -0
  198. package/lib/secrets-proxy/scrub.ts +559 -0
  199. package/lib/secrets-proxy/sidecar-view.ts +139 -0
  200. package/lib/secrets-proxy/task-scripts.ts +262 -0
  201. package/lib/secrets-proxy/task-trust.ts +605 -0
  202. package/lib/secrets-proxy/trust-watch.ts +80 -0
  203. package/lib/secrets.ts +71 -0
  204. package/lib/shared-files-s3.ts +976 -0
  205. package/lib/shared-files.ts +156 -0
  206. package/lib/sidecar-assign.ts +49 -0
  207. package/lib/sidecar-guard.ts +58 -0
  208. package/lib/sidecar-resume.ts +178 -0
  209. package/lib/sidecar.ts +69 -0
  210. package/lib/signin-box-credentials.ts +465 -0
  211. package/lib/signin-box.ts +114 -0
  212. package/lib/skill-index-example.fixture.ts +56 -0
  213. package/lib/skill-layout.ts +417 -0
  214. package/lib/skills.ts +489 -0
  215. package/lib/ssh.ts +401 -0
  216. package/lib/standard-image-cleanup.ts +117 -0
  217. package/lib/standard-image-pin.ts +207 -0
  218. package/lib/standard-image.ts +1697 -0
  219. package/lib/stopped-task-status-queue.ts +120 -0
  220. package/lib/task-container-cli.ts +269 -0
  221. package/lib/task-credential-cleanup.ts +752 -0
  222. package/lib/task-diff-sandbox.ts +464 -0
  223. package/lib/task-diff.ts +91 -0
  224. package/lib/task-env-forwarder.ts +228 -0
  225. package/lib/task-env-source.ts +249 -0
  226. package/lib/task-environment/anchor.ts +31 -0
  227. package/lib/task-environment/apple-container.ts +860 -0
  228. package/lib/task-environment/docker.ts +1344 -0
  229. package/lib/task-environment/index.ts +466 -0
  230. package/lib/task-environment/legacy-adoption.ts +467 -0
  231. package/lib/task-environment/machine-environment.ts +61 -0
  232. package/lib/task-environment/machine-task-up.ts +1227 -0
  233. package/lib/task-environment/machine.ts +974 -0
  234. package/lib/task-environment/registry.ts +59 -0
  235. package/lib/task-environment/self-identity.ts +20 -0
  236. package/lib/task-environment/self.ts +566 -0
  237. package/lib/task-environment/types.ts +642 -0
  238. package/lib/task-environment/workspace-files.ts +685 -0
  239. package/lib/task-environment/workspace-runtime.fixture.ts +50 -0
  240. package/lib/task-files-machine-retirement-outbox.ts +592 -0
  241. package/lib/task-files-machine-retirement.ts +116 -0
  242. package/lib/task-files-readiness.ts +127 -0
  243. package/lib/task-gateway-port.ts +22 -0
  244. package/lib/task-gateway-protocol.ts +190 -0
  245. package/lib/task-gateway-recovery.ts +47 -0
  246. package/lib/task-gateway-state.ts +512 -0
  247. package/lib/task-identity.ts +19 -0
  248. package/lib/task-inventory.ts +682 -0
  249. package/lib/task-machine-credentials-activation.ts +95 -0
  250. package/lib/task-machine-swap-safety.ts +729 -0
  251. package/lib/task-person-credentials.ts +76 -0
  252. package/lib/task-project-ops-host.ts +147 -0
  253. package/lib/task-project-ops.ts +1062 -0
  254. package/lib/task-secret-staging.ts +16 -0
  255. package/lib/task-status.ts +46 -0
  256. package/lib/task-token.ts +46 -0
  257. package/lib/token-broker-adopt.ts +344 -0
  258. package/lib/token-broker-lambda.ts +105 -0
  259. package/lib/token-broker-local.ts +392 -0
  260. package/lib/token-broker-revision.ts +310 -0
  261. package/lib/token-broker-ssm.ts +525 -0
  262. package/lib/token-broker.ts +218 -0
  263. package/lib/token-lanes/openai-oauth.ts +123 -0
  264. package/lib/token-lanes/registry.ts +45 -0
  265. package/lib/token-lanes/types.ts +163 -0
  266. package/lib/token-lanes/xai-oauth.ts +165 -0
  267. package/lib/transcript.ts +128 -0
  268. package/lib/tunnel-registry.ts +220 -0
  269. package/lib/tunnel-runtime.ts +235 -0
  270. package/lib/ulid.ts +16 -0
  271. package/lib/user-bus-env.ts +116 -0
  272. package/lib/user-credentials-store.ts +435 -0
  273. package/lib/vnode-pressure.ts +142 -0
  274. package/package.json +115 -8
  275. package/runner/runner.mjs +442 -0
  276. package/scripts/agent/_common.sh +633 -0
  277. package/scripts/agent/env-hook.sh +626 -0
  278. package/scripts/agent/moondeck-cli.sh +5 -0
  279. package/scripts/agent/task-down.sh +291 -0
  280. package/scripts/agent/task-status.sh +70 -0
  281. package/scripts/agent/task-up.sh +3761 -0
  282. package/scripts/agent/uai-env-exec.sh +26 -0
  283. package/scripts/install/darwin.ts +1048 -0
  284. package/scripts/install/linux.ts +958 -0
  285. package/scripts/install/types.ts +78 -0
  286. package/scripts/install/util.ts +254 -0
  287. package/scripts/install/win.ts +143 -0
  288. package/src/activation-respawn.ts +155 -0
  289. package/src/apple-tunnel-route.ts +104 -0
  290. package/src/capture-wire.ts +102 -0
  291. package/src/cli.ts +2583 -0
  292. package/src/cloud-credentials.ts +2144 -0
  293. package/src/cloud-origins.ts +23 -0
  294. package/src/credential-location.ts +248 -0
  295. package/src/credential-wire-validation.ts +25 -0
  296. package/src/custom-connections.ts +237 -0
  297. package/src/engine-account-paths.ts +11 -0
  298. package/src/engine-models.ts +39 -0
  299. package/src/engine-usage.ts +104 -0
  300. package/src/event-outbox.ts +185 -0
  301. package/src/index.ts +2899 -0
  302. package/src/load-env.ts +97 -0
  303. package/src/machine-tunnel-route.ts +156 -0
  304. package/src/main.ts +6349 -0
  305. package/src/never-proxied-domains.ts +31 -0
  306. package/src/outbound-frame.ts +31 -0
  307. package/src/paths.ts +81 -0
  308. package/src/project-env-latest.ts +130 -0
  309. package/src/project-env-policy.ts +396 -0
  310. package/src/project-env-wording.ts +53 -0
  311. package/src/protocol.ts +5545 -0
  312. package/src/runtime-bootstrap.ts +165 -0
  313. package/src/station-identity.ts +96 -0
  314. package/src/task-env-names.ts +28 -0
  315. package/src/task-secrets.ts +75 -0
  316. package/src/tunnel-dial.ts +102 -0
  317. package/src/ui/server.ts +852 -0
  318. package/src/ui/types.ts +173 -0
  319. package/src/workspace-path-policy.ts +41 -0
  320. package/ui/app.js +1102 -0
  321. package/ui/index.html +90 -0
  322. package/ui/style.css +685 -0
  323. package/ui/uai-favicon.svg +21 -0
  324. package/ui/uai-logo-black.svg +9 -0
  325. package/ui/uai-wheel.svg +9 -0
  326. package/bin/moondeck-station.mjs +0 -3
@@ -0,0 +1,147 @@
1
+ -- ADR-153: the owned runner's durable, value-free project-env authority.
2
+ --
3
+ -- This migration deliberately does not backfill host_project_env. An older
4
+ -- runtime may keep writing that table after the migration lands but before
5
+ -- the first bindings-v1 reconciliation. After its caller takes the capability
6
+ -- floor, the first begin transaction snapshots the then-current rows and
7
+ -- activates the permanent legacy-write journal below.
8
+ CREATE TABLE `host_project_env_records` (
9
+ `project_id` text NOT NULL,
10
+ `key` text NOT NULL,
11
+ `revision` integer NOT NULL,
12
+ `generation` integer NOT NULL,
13
+ `tombstone` integer NOT NULL,
14
+ `binding_json` text,
15
+ `policy_epoch` integer,
16
+ `listing_generation` integer NOT NULL,
17
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
18
+ PRIMARY KEY(`project_id`, `key`),
19
+ CONSTRAINT `host_project_env_records_head` CHECK (
20
+ (`tombstone` = 0 AND `revision` >= 1 AND `generation` >= 1) OR
21
+ (`tombstone` = 1 AND `revision` = 1 AND `generation` = 0) OR
22
+ (`tombstone` = 1 AND `revision` >= 2 AND `generation` >= 2)
23
+ ),
24
+ CONSTRAINT `host_project_env_records_binding` CHECK (
25
+ (`generation` = 0 AND `binding_json` IS NULL AND `policy_epoch` IS NULL
26
+ AND `listing_generation` >= 2 AND (`listing_generation` % 2) = 0) OR
27
+ (`generation` > 0 AND `policy_epoch` >= 1)
28
+ ),
29
+ CONSTRAINT `host_project_env_records_listing` CHECK (`listing_generation` >= 0),
30
+ CONSTRAINT `host_project_env_records_boolean` CHECK (`tombstone` IN (0, 1))
31
+ );
32
+ --> statement-breakpoint
33
+ CREATE TABLE `host_project_env_projects` (
34
+ `project_id` text PRIMARY KEY NOT NULL,
35
+ `record_version` integer NOT NULL DEFAULT 0,
36
+ CONSTRAINT `host_project_env_projects_version` CHECK (`record_version` >= 0)
37
+ );
38
+ --> statement-breakpoint
39
+ CREATE TABLE `host_project_env_authority` (
40
+ `id` text PRIMARY KEY NOT NULL DEFAULT 'host',
41
+ `activated` integer NOT NULL DEFAULT 0,
42
+ `gate_open` integer NOT NULL DEFAULT 1,
43
+ `stream_id` text,
44
+ `applied_sequence` integer NOT NULL DEFAULT 0,
45
+ `attempt_id` text,
46
+ `attempt_legacy_version` integer,
47
+ `legacy_version` integer NOT NULL DEFAULT 0,
48
+ `policy_epochs_json` text NOT NULL DEFAULT '[1]',
49
+ `modern_write` integer NOT NULL DEFAULT 0,
50
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
51
+ CONSTRAINT `host_project_env_authority_singleton` CHECK (`id` = 'host'),
52
+ CONSTRAINT `host_project_env_authority_booleans` CHECK (
53
+ `activated` IN (0, 1) AND `gate_open` IN (0, 1) AND `modern_write` IN (0, 1)
54
+ ),
55
+ CONSTRAINT `host_project_env_authority_cursor` CHECK (
56
+ `applied_sequence` >= 0 AND `legacy_version` >= 0 AND
57
+ (`attempt_legacy_version` IS NULL OR `attempt_legacy_version` >= 0)
58
+ ),
59
+ CONSTRAINT `host_project_env_authority_stream` CHECK (
60
+ (`activated` = 0 AND `stream_id` IS NULL AND `applied_sequence` = 0 AND `attempt_id` IS NULL) OR
61
+ (`activated` = 1 AND `stream_id` IS NOT NULL)
62
+ ),
63
+ CONSTRAINT `host_project_env_authority_attempt` CHECK (
64
+ (`attempt_id` IS NULL AND `attempt_legacy_version` IS NULL) OR
65
+ (`attempt_id` IS NOT NULL AND `attempt_legacy_version` IS NOT NULL AND `gate_open` = 0)
66
+ ),
67
+ CONSTRAINT `host_project_env_authority_open` CHECK (`gate_open` = 0 OR `attempt_id` IS NULL)
68
+ );
69
+ --> statement-breakpoint
70
+ INSERT INTO `host_project_env_authority` (`id`) VALUES ('host');
71
+ --> statement-breakpoint
72
+ CREATE TABLE `host_project_env_delivery_receipts` (
73
+ `stream_id` text NOT NULL,
74
+ `sequence` integer NOT NULL,
75
+ `request_kind` text NOT NULL,
76
+ `request_mac` text NOT NULL,
77
+ `ok` integer NOT NULL,
78
+ `state_json` text,
79
+ `record_version` integer,
80
+ `code` text,
81
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
82
+ PRIMARY KEY(`stream_id`, `sequence`),
83
+ CONSTRAINT `host_project_env_delivery_receipts_sequence` CHECK (`sequence` >= 1),
84
+ CONSTRAINT `host_project_env_delivery_receipts_boolean` CHECK (`ok` IN (0, 1)),
85
+ CONSTRAINT `host_project_env_delivery_receipts_outcome` CHECK (
86
+ (`ok` = 1 AND `code` IS NULL) OR (`ok` = 0 AND `code` IS NOT NULL)
87
+ ),
88
+ CONSTRAINT `host_project_env_delivery_receipts_version` CHECK (
89
+ `record_version` IS NULL OR `record_version` >= 0
90
+ )
91
+ );
92
+ --> statement-breakpoint
93
+ CREATE TABLE `host_project_env_legacy_journal` (
94
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
95
+ `project_id` text NOT NULL,
96
+ `key` text NOT NULL,
97
+ `mutation` text NOT NULL,
98
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
99
+ CONSTRAINT `host_project_env_legacy_journal_mutation` CHECK (`mutation` IN ('set', 'delete'))
100
+ );
101
+ --> statement-breakpoint
102
+ CREATE INDEX `host_project_env_legacy_journal_key_idx`
103
+ ON `host_project_env_legacy_journal` (`project_id`, `key`);
104
+ --> statement-breakpoint
105
+ -- These triggers are inert until the first modern reconciliation activates
106
+ -- the authority. Afterwards, any old process that changes plaintext storage
107
+ -- leaves durable evidence and closes the serving gate. Metadata-only updates
108
+ -- do neither. Modern writes raise modern_write in their enclosing transaction.
109
+ CREATE TRIGGER `host_project_env_legacy_insert`
110
+ AFTER INSERT ON `host_project_env`
111
+ WHEN (SELECT `activated` = 1 AND `modern_write` = 0
112
+ FROM `host_project_env_authority` WHERE `id` = 'host')
113
+ BEGIN
114
+ INSERT INTO `host_project_env_legacy_journal` (`project_id`, `key`, `mutation`)
115
+ VALUES (NEW.`project_id`, NEW.`key`, 'set');
116
+ UPDATE `host_project_env_authority`
117
+ SET `gate_open` = 0, `legacy_version` = `legacy_version` + 1,
118
+ `updated_at` = unixepoch() * 1000
119
+ WHERE `id` = 'host';
120
+ END;
121
+ --> statement-breakpoint
122
+ CREATE TRIGGER `host_project_env_legacy_update`
123
+ AFTER UPDATE OF `value_enc` ON `host_project_env`
124
+ WHEN OLD.`value_enc` IS NOT NEW.`value_enc`
125
+ AND (SELECT `activated` = 1 AND `modern_write` = 0
126
+ FROM `host_project_env_authority` WHERE `id` = 'host')
127
+ BEGIN
128
+ INSERT INTO `host_project_env_legacy_journal` (`project_id`, `key`, `mutation`)
129
+ VALUES (NEW.`project_id`, NEW.`key`, 'set');
130
+ UPDATE `host_project_env_authority`
131
+ SET `gate_open` = 0, `legacy_version` = `legacy_version` + 1,
132
+ `updated_at` = unixepoch() * 1000
133
+ WHERE `id` = 'host';
134
+ END;
135
+ --> statement-breakpoint
136
+ CREATE TRIGGER `host_project_env_legacy_delete`
137
+ AFTER DELETE ON `host_project_env`
138
+ WHEN (SELECT `activated` = 1 AND `modern_write` = 0
139
+ FROM `host_project_env_authority` WHERE `id` = 'host')
140
+ BEGIN
141
+ INSERT INTO `host_project_env_legacy_journal` (`project_id`, `key`, `mutation`)
142
+ VALUES (OLD.`project_id`, OLD.`key`, 'delete');
143
+ UPDATE `host_project_env_authority`
144
+ SET `gate_open` = 0, `legacy_version` = `legacy_version` + 1,
145
+ `updated_at` = unixepoch() * 1000
146
+ WHERE `id` = 'host';
147
+ END;
@@ -0,0 +1,150 @@
1
+ -- ADR-153: durable Uai Cloud task-machine project-env replica.
2
+ --
3
+ -- The live and staged views are separate from both one another and the owned
4
+ -- runner authority. A page can therefore materialise values without making
5
+ -- them visible, and commit can replace the complete task view atomically.
6
+ CREATE TABLE `host_project_env_replica_authority` (
7
+ `id` text PRIMARY KEY NOT NULL DEFAULT 'replica',
8
+ `activated` integer NOT NULL DEFAULT 0,
9
+ `gate_open` integer NOT NULL DEFAULT 0,
10
+ `stream_id` text,
11
+ `applied_sequence` integer NOT NULL DEFAULT 0,
12
+ `attempt_id` text,
13
+ `org_id` text,
14
+ `policy_epochs_json` text NOT NULL DEFAULT '[1]',
15
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
16
+ CONSTRAINT `host_project_env_replica_authority_singleton` CHECK (`id` = 'replica'),
17
+ CONSTRAINT `host_project_env_replica_authority_booleans` CHECK (`activated` IN (0, 1) AND `gate_open` IN (0, 1)),
18
+ CONSTRAINT `host_project_env_replica_authority_cursor` CHECK (`applied_sequence` >= 0),
19
+ CONSTRAINT `host_project_env_replica_authority_stream` CHECK (
20
+ (`activated` = 0 AND `stream_id` IS NULL AND `applied_sequence` = 0 AND `attempt_id` IS NULL AND `org_id` IS NULL AND `gate_open` = 0) OR
21
+ (`activated` = 1 AND `stream_id` IS NOT NULL AND `org_id` IS NOT NULL)
22
+ ),
23
+ CONSTRAINT `host_project_env_replica_authority_gate` CHECK (`gate_open` = 0 OR `attempt_id` IS NULL)
24
+ );
25
+ --> statement-breakpoint
26
+ INSERT INTO `host_project_env_replica_authority` (`id`) VALUES ('replica');
27
+ --> statement-breakpoint
28
+ CREATE TABLE `host_project_env_replica_projects` (
29
+ `project_id` text PRIMARY KEY NOT NULL,
30
+ `record_version` integer NOT NULL,
31
+ CONSTRAINT `host_project_env_replica_projects_version` CHECK (`record_version` >= 0)
32
+ );
33
+ --> statement-breakpoint
34
+ CREATE TABLE `host_project_env_replica_records` (
35
+ `project_id` text NOT NULL,
36
+ `key` text NOT NULL,
37
+ `revision` integer NOT NULL,
38
+ `generation` integer NOT NULL,
39
+ `tombstone` integer NOT NULL,
40
+ `value_ref_json` text,
41
+ `binding_json` text,
42
+ `policy_epoch` integer,
43
+ `listing_generation` integer NOT NULL,
44
+ `materialization` text NOT NULL,
45
+ `materialization_reason` text,
46
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
47
+ PRIMARY KEY(`project_id`, `key`),
48
+ CONSTRAINT `host_project_env_replica_records_head` CHECK (
49
+ (`tombstone` = 0 AND `revision` >= 1 AND `generation` >= 1 AND `value_ref_json` IS NOT NULL) OR
50
+ (`tombstone` = 1 AND `revision` = 1 AND `generation` = 0 AND `value_ref_json` IS NULL) OR
51
+ (`tombstone` = 1 AND `revision` >= 2 AND `generation` >= 2 AND `value_ref_json` IS NULL)
52
+ ),
53
+ CONSTRAINT `host_project_env_replica_records_binding` CHECK (
54
+ (`generation` = 0 AND `binding_json` IS NULL AND `policy_epoch` IS NULL AND `listing_generation` >= 2 AND (`listing_generation` % 2) = 0) OR
55
+ (`generation` > 0 AND `policy_epoch` >= 1)
56
+ ),
57
+ CONSTRAINT `host_project_env_replica_records_listing` CHECK (`listing_generation` >= 0),
58
+ CONSTRAINT `host_project_env_replica_records_boolean` CHECK (`tombstone` IN (0, 1)),
59
+ CONSTRAINT `host_project_env_replica_records_materialization` CHECK (
60
+ (`materialization` = 'installed' AND `tombstone` = 0 AND `materialization_reason` IS NULL) OR
61
+ (`materialization` IN ('withheld', 'unavailable') AND `materialization_reason` IS NOT NULL)
62
+ )
63
+ );
64
+ --> statement-breakpoint
65
+ CREATE TABLE `host_project_env_replica_values` (
66
+ `project_id` text NOT NULL,
67
+ `key` text NOT NULL,
68
+ `revision` integer NOT NULL,
69
+ `generation` integer NOT NULL,
70
+ `value_ref_json` text NOT NULL,
71
+ `value_enc` text NOT NULL,
72
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
73
+ PRIMARY KEY(`project_id`, `key`),
74
+ CONSTRAINT `host_project_env_replica_values_head` CHECK (`revision` >= 1 AND `generation` >= 1)
75
+ );
76
+ --> statement-breakpoint
77
+ CREATE TABLE `host_project_env_replica_stage_projects` (
78
+ `attempt_id` text NOT NULL,
79
+ `project_id` text NOT NULL,
80
+ `record_version` integer,
81
+ `last_key` text,
82
+ `complete` integer NOT NULL DEFAULT 0,
83
+ PRIMARY KEY(`attempt_id`, `project_id`),
84
+ CONSTRAINT `host_project_env_replica_stage_projects_version` CHECK (`record_version` IS NULL OR `record_version` >= 0),
85
+ CONSTRAINT `host_project_env_replica_stage_projects_complete` CHECK (`complete` IN (0, 1))
86
+ );
87
+ --> statement-breakpoint
88
+ CREATE TABLE `host_project_env_replica_stage_records` (
89
+ `attempt_id` text NOT NULL,
90
+ `project_id` text NOT NULL,
91
+ `key` text NOT NULL,
92
+ `revision` integer NOT NULL,
93
+ `generation` integer NOT NULL,
94
+ `tombstone` integer NOT NULL,
95
+ `value_ref_json` text,
96
+ `binding_json` text,
97
+ `policy_epoch` integer,
98
+ `listing_generation` integer NOT NULL,
99
+ `materialization` text NOT NULL,
100
+ `materialization_reason` text,
101
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
102
+ `present` integer NOT NULL DEFAULT 0,
103
+ PRIMARY KEY(`attempt_id`, `project_id`, `key`),
104
+ CONSTRAINT `host_project_env_replica_stage_records_head` CHECK (
105
+ (`tombstone` = 0 AND `revision` >= 1 AND `generation` >= 1 AND `value_ref_json` IS NOT NULL) OR
106
+ (`tombstone` = 1 AND `revision` = 1 AND `generation` = 0 AND `value_ref_json` IS NULL) OR
107
+ (`tombstone` = 1 AND `revision` >= 2 AND `generation` >= 2 AND `value_ref_json` IS NULL)
108
+ ),
109
+ CONSTRAINT `host_project_env_replica_stage_records_binding` CHECK (
110
+ (`generation` = 0 AND `binding_json` IS NULL AND `policy_epoch` IS NULL AND `listing_generation` >= 2 AND (`listing_generation` % 2) = 0) OR
111
+ (`generation` > 0 AND `policy_epoch` >= 1)
112
+ ),
113
+ CONSTRAINT `host_project_env_replica_stage_records_listing` CHECK (`listing_generation` >= 0),
114
+ CONSTRAINT `host_project_env_replica_stage_records_boolean` CHECK (`tombstone` IN (0, 1) AND `present` IN (0, 1)),
115
+ CONSTRAINT `host_project_env_replica_stage_records_materialization` CHECK (
116
+ (`materialization` = 'installed' AND `tombstone` = 0 AND `materialization_reason` IS NULL) OR
117
+ (`materialization` IN ('withheld', 'unavailable') AND `materialization_reason` IS NOT NULL)
118
+ )
119
+ );
120
+ --> statement-breakpoint
121
+ CREATE TABLE `host_project_env_replica_stage_values` (
122
+ `attempt_id` text NOT NULL,
123
+ `project_id` text NOT NULL,
124
+ `key` text NOT NULL,
125
+ `revision` integer NOT NULL,
126
+ `generation` integer NOT NULL,
127
+ `value_ref_json` text NOT NULL,
128
+ `value_enc` text NOT NULL,
129
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
130
+ PRIMARY KEY(`attempt_id`, `project_id`, `key`),
131
+ CONSTRAINT `host_project_env_replica_stage_values_head` CHECK (`revision` >= 1 AND `generation` >= 1)
132
+ );
133
+ --> statement-breakpoint
134
+ CREATE TABLE `host_project_env_replica_receipts` (
135
+ `stream_id` text NOT NULL,
136
+ `sequence` integer NOT NULL,
137
+ `request_mac` text NOT NULL,
138
+ `result_json` text,
139
+ `record_version` integer,
140
+ `ok` integer NOT NULL,
141
+ `code` text,
142
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
143
+ PRIMARY KEY(`stream_id`, `sequence`),
144
+ CONSTRAINT `host_project_env_replica_receipts_sequence` CHECK (`sequence` >= 1),
145
+ CONSTRAINT `host_project_env_replica_receipts_boolean` CHECK (`ok` IN (0, 1)),
146
+ CONSTRAINT `host_project_env_replica_receipts_outcome` CHECK (
147
+ (`ok` = 1 AND `result_json` IS NOT NULL AND `record_version` IS NOT NULL AND `code` IS NULL) OR
148
+ (`ok` = 0 AND `result_json` IS NULL AND `record_version` IS NULL AND `code` IS NOT NULL)
149
+ )
150
+ );
@@ -0,0 +1,51 @@
1
+ -- ADR-154 runner persistence foundation. A run epoch is non-secret
2
+ -- assignment identity; cleanup rows contain paths and ids only, never values.
3
+ ALTER TABLE `uai_host_tasks` ADD `run_epoch` integer NOT NULL DEFAULT 0
4
+ CONSTRAINT `uai_host_tasks_run_epoch` CHECK (`run_epoch` >= 0);
5
+ --> statement-breakpoint
6
+ CREATE TABLE `host_task_run_assignments` (
7
+ `task_id` text PRIMARY KEY NOT NULL,
8
+ `highest_run_epoch` integer NOT NULL,
9
+ `assignment_open` integer NOT NULL DEFAULT 1,
10
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
11
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
12
+ CONSTRAINT `host_task_run_assignments_epoch` CHECK (`highest_run_epoch` >= 1),
13
+ CONSTRAINT `host_task_run_assignments_open` CHECK (`assignment_open` IN (0, 1)),
14
+ CONSTRAINT `host_task_run_assignments_task_id` CHECK (length(`task_id`) > 0)
15
+ );
16
+ --> statement-breakpoint
17
+ CREATE TABLE `host_credential_cleanup_paths` (
18
+ `task_id` text NOT NULL,
19
+ `run_epoch` integer NOT NULL,
20
+ `runtime_locator` text NOT NULL,
21
+ `lane` text NOT NULL,
22
+ `path` text NOT NULL,
23
+ `credential_id` text NOT NULL,
24
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
25
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
26
+ PRIMARY KEY(`task_id`, `run_epoch`, `runtime_locator`, `path`),
27
+ CONSTRAINT `host_credential_cleanup_paths_run_epoch` CHECK (`run_epoch` >= 1),
28
+ CONSTRAINT `host_credential_cleanup_paths_identity` CHECK (
29
+ length(`task_id`) > 0 AND length(`runtime_locator`) > 0 AND length(`credential_id`) > 0
30
+ ),
31
+ CONSTRAINT `host_credential_cleanup_paths_lane` CHECK (
32
+ `lane` IN ('engine-auth', 'github', 'ssh', 'files-session')
33
+ ),
34
+ CONSTRAINT `host_credential_cleanup_paths_absolute_path` CHECK (substr(`path`, 1, 1) = '/')
35
+ );
36
+ --> statement-breakpoint
37
+ CREATE INDEX `host_credential_cleanup_paths_task_credential_idx`
38
+ ON `host_credential_cleanup_paths` (`task_id`, `run_epoch`, `credential_id`);
39
+ --> statement-breakpoint
40
+ CREATE TABLE `host_credential_cleanup_pending` (
41
+ `task_id` text PRIMARY KEY NOT NULL,
42
+ `run_epoch` integer NOT NULL,
43
+ `reason` text NOT NULL,
44
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
45
+ `updated_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
46
+ CONSTRAINT `host_credential_cleanup_pending_run_epoch` CHECK (`run_epoch` >= 1),
47
+ CONSTRAINT `host_credential_cleanup_pending_reason` CHECK (
48
+ `reason` IN ('removed', 'denied', 'expired', 'assignment', 'restart', 'stop', 'park', 'teardown')
49
+ ),
50
+ CONSTRAINT `host_credential_cleanup_pending_task_id` CHECK (length(`task_id`) > 0)
51
+ );
@@ -0,0 +1,11 @@
1
+ CREATE TABLE `host_leased_engine_runtimes` (
2
+ `task_id` text NOT NULL,
3
+ `run_epoch` integer NOT NULL,
4
+ `runtime_locator` text NOT NULL,
5
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
6
+ PRIMARY KEY(`task_id`, `run_epoch`, `runtime_locator`),
7
+ CONSTRAINT `host_leased_engine_runtimes_run_epoch` CHECK (`run_epoch` >= 1),
8
+ CONSTRAINT `host_leased_engine_runtimes_identity` CHECK (
9
+ length(`task_id`) > 0 AND length(`runtime_locator`) > 0
10
+ )
11
+ );
@@ -0,0 +1,5 @@
1
+ -- ADR-154 Files v1: persist the cloud-issued mode for crash recovery. The
2
+ -- task-owned `.uai/files-mounted` marker is an observation, never authority.
3
+ ALTER TABLE `uai_host_tasks` ADD `shared_files_mode` text
4
+ CONSTRAINT `uai_host_tasks_shared_files_mode`
5
+ CHECK (`shared_files_mode` IS NULL OR `shared_files_mode` IN ('off', 'ro', 'rw'));
@@ -0,0 +1,12 @@
1
+ CREATE TABLE IF NOT EXISTS `host_credential_cleanup_restops` (
2
+ `task_id` text NOT NULL,
3
+ `container_id` text NOT NULL,
4
+ `run_epoch` integer NOT NULL,
5
+ `runtime_locator` text NOT NULL,
6
+ `created_at` integer NOT NULL DEFAULT (unixepoch() * 1000),
7
+ PRIMARY KEY(`task_id`, `container_id`),
8
+ CONSTRAINT `host_credential_cleanup_restops_run_epoch` CHECK (`run_epoch` >= 1),
9
+ CONSTRAINT `host_credential_cleanup_restops_identity` CHECK (
10
+ length(`task_id`) > 0 AND length(`container_id`) > 0 AND length(`runtime_locator`) > 0
11
+ )
12
+ );
@@ -0,0 +1,223 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "sqlite",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "6",
8
+ "when": 1779900001000,
9
+ "tag": "0000_host_tasks",
10
+ "breakpoints": true
11
+ },
12
+ {
13
+ "idx": 1,
14
+ "version": "6",
15
+ "when": 1779900002000,
16
+ "tag": "0001_host_ui",
17
+ "breakpoints": true
18
+ },
19
+ {
20
+ "idx": 2,
21
+ "version": "6",
22
+ "when": 1779900003000,
23
+ "tag": "0002_host_github_tokens",
24
+ "breakpoints": true
25
+ },
26
+ {
27
+ "idx": 3,
28
+ "version": "6",
29
+ "when": 1779900004000,
30
+ "tag": "0003_host_ssh_keys",
31
+ "breakpoints": true
32
+ },
33
+ {
34
+ "idx": 4,
35
+ "version": "6",
36
+ "when": 1779900005000,
37
+ "tag": "0004_host_owner_name",
38
+ "breakpoints": true
39
+ },
40
+ {
41
+ "idx": 5,
42
+ "version": "6",
43
+ "when": 1779900006000,
44
+ "tag": "0005_host_env_vars",
45
+ "breakpoints": true
46
+ },
47
+ {
48
+ "idx": 6,
49
+ "version": "6",
50
+ "when": 1779900007000,
51
+ "tag": "0006_host_project_env",
52
+ "breakpoints": true
53
+ },
54
+ {
55
+ "idx": 7,
56
+ "version": "6",
57
+ "when": 1779900008000,
58
+ "tag": "0007_host_github_token_kind",
59
+ "breakpoints": true
60
+ },
61
+ {
62
+ "idx": 8,
63
+ "version": "6",
64
+ "when": 1779900009000,
65
+ "tag": "0008_host_mcp_connections",
66
+ "breakpoints": true
67
+ },
68
+ {
69
+ "idx": 9,
70
+ "version": "6",
71
+ "when": 1779900010000,
72
+ "tag": "0009_host_agent_sessions",
73
+ "breakpoints": true
74
+ },
75
+ {
76
+ "idx": 10,
77
+ "version": "6",
78
+ "when": 1779900011000,
79
+ "tag": "0010_host_engine_accounts",
80
+ "breakpoints": true
81
+ },
82
+ {
83
+ "idx": 11,
84
+ "version": "6",
85
+ "when": 1779900012000,
86
+ "tag": "0011_codex_thread_id",
87
+ "breakpoints": true
88
+ },
89
+ {
90
+ "idx": 12,
91
+ "version": "6",
92
+ "when": 1779900013000,
93
+ "tag": "0012_agent_session_attach_key",
94
+ "breakpoints": true
95
+ },
96
+ {
97
+ "idx": 13,
98
+ "version": "6",
99
+ "when": 1786045000000,
100
+ "tag": "0013_github_credential_generations",
101
+ "breakpoints": true
102
+ },
103
+ {
104
+ "idx": 14,
105
+ "version": "6",
106
+ "when": 1786406400000,
107
+ "tag": "0014_host_inventory_event_index",
108
+ "breakpoints": true
109
+ },
110
+ {
111
+ "idx": 15,
112
+ "version": "6",
113
+ "when": 1786406401000,
114
+ "tag": "0015_host_settings",
115
+ "breakpoints": true
116
+ },
117
+ {
118
+ "idx": 16,
119
+ "version": "6",
120
+ "when": 1786406402000,
121
+ "tag": "0016_task_environment",
122
+ "breakpoints": true
123
+ },
124
+ {
125
+ "idx": 17,
126
+ "version": "6",
127
+ "when": 1788820000000,
128
+ "tag": "0017_engine_account_scope",
129
+ "breakpoints": true
130
+ },
131
+ {
132
+ "idx": 18,
133
+ "version": "6",
134
+ "when": 1788900000000,
135
+ "tag": "0018_engine_account_position",
136
+ "breakpoints": true
137
+ },
138
+ {
139
+ "idx": 19,
140
+ "version": "6",
141
+ "when": 1788900000001,
142
+ "tag": "0019_engine_account_store_ref",
143
+ "breakpoints": true
144
+ },
145
+ {
146
+ "idx": 20,
147
+ "version": "6",
148
+ "when": 1788900000002,
149
+ "tag": "0020_user_credential_store_ref",
150
+ "breakpoints": true
151
+ },
152
+ {
153
+ "idx": 21,
154
+ "version": "6",
155
+ "when": 1788900000003,
156
+ "tag": "0021_project_env_store_ref",
157
+ "breakpoints": true
158
+ },
159
+ {
160
+ "idx": 22,
161
+ "version": "6",
162
+ "when": 1788900000004,
163
+ "tag": "0022_task_project_ids",
164
+ "breakpoints": true
165
+ },
166
+ {
167
+ "idx": 23,
168
+ "version": "6",
169
+ "when": 1788900000005,
170
+ "tag": "0023_project_env_org",
171
+ "breakpoints": true
172
+ },
173
+ {
174
+ "idx": 24,
175
+ "version": "6",
176
+ "when": 1788900000006,
177
+ "tag": "0024_task_env_mode",
178
+ "breakpoints": true
179
+ },
180
+ {
181
+ "idx": 25,
182
+ "version": "6",
183
+ "when": 1788900000007,
184
+ "tag": "0025_project_env_authority",
185
+ "breakpoints": true
186
+ },
187
+ {
188
+ "idx": 26,
189
+ "version": "6",
190
+ "when": 1788900000008,
191
+ "tag": "0026_project_env_replica",
192
+ "breakpoints": true
193
+ },
194
+ {
195
+ "idx": 27,
196
+ "version": "6",
197
+ "when": 1791331200000,
198
+ "tag": "0027_cloud_credential_foundation",
199
+ "breakpoints": true
200
+ },
201
+ {
202
+ "idx": 28,
203
+ "version": "6",
204
+ "when": 1791331200001,
205
+ "tag": "0028_leased_engine_runtimes",
206
+ "breakpoints": true
207
+ },
208
+ {
209
+ "idx": 29,
210
+ "version": "6",
211
+ "when": 1791590400000,
212
+ "tag": "0029_task_shared_files_mode",
213
+ "breakpoints": true
214
+ },
215
+ {
216
+ "idx": 30,
217
+ "version": "6",
218
+ "when": 1793318400000,
219
+ "tag": "0030_credential_cleanup_restops",
220
+ "breakpoints": true
221
+ }
222
+ ]
223
+ }