@intx/db 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +2 -2
  2. package/dist/approval-store.d.ts +52 -0
  3. package/dist/approval-store.js +79 -0
  4. package/dist/asset-resolution.d.ts +2 -2
  5. package/dist/client.d.ts +10 -0
  6. package/dist/connection.js +11 -8
  7. package/dist/credential-resolution.d.ts +130 -18
  8. package/dist/credential-resolution.js +142 -3
  9. package/dist/grant-store.js +35 -13
  10. package/dist/index.d.ts +13 -4
  11. package/dist/index.js +11 -3
  12. package/dist/model-source-resolution.d.ts +52 -6
  13. package/dist/model-source-resolution.js +145 -19
  14. package/dist/parse-row.d.ts +212 -32
  15. package/dist/parse-row.js +109 -18
  16. package/dist/rekey-credential-secrets.d.ts +13 -0
  17. package/dist/rekey-credential-secrets.js +61 -0
  18. package/dist/schema/approvals.d.ts +245 -0
  19. package/dist/schema/approvals.js +52 -0
  20. package/dist/schema/catalog.d.ts +17 -0
  21. package/dist/schema/catalog.js +7 -1
  22. package/dist/schema/credentials.d.ts +1 -1
  23. package/dist/schema/git-tokens.js +1 -1
  24. package/dist/schema/grants.js +8 -2
  25. package/dist/schema/index.d.ts +8 -4
  26. package/dist/schema/index.js +8 -4
  27. package/dist/schema/messages.d.ts +5 -5
  28. package/dist/schema/messages.js +20 -9
  29. package/dist/schema/offerings.js +8 -2
  30. package/dist/schema/principals.d.ts +2 -2
  31. package/dist/schema/principals.js +7 -5
  32. package/dist/schema/providers.d.ts +17 -0
  33. package/dist/schema/providers.js +5 -0
  34. package/dist/schema/roles.js +6 -2
  35. package/dist/schema/session-assets.d.ts +1 -38
  36. package/dist/schema/session-assets.js +36 -19
  37. package/dist/schema/sessions.js +7 -2
  38. package/dist/schema/sidecar-allocation.d.ts +406 -0
  39. package/dist/schema/sidecar-allocation.js +57 -0
  40. package/dist/schema/sidecar.d.ts +19 -2
  41. package/dist/schema/sidecar.js +13 -3
  42. package/dist/schema/signal-correlations.d.ts +177 -0
  43. package/dist/schema/signal-correlations.js +31 -0
  44. package/dist/schema/wallets.d.ts +3 -3
  45. package/dist/schema/wallets.js +4 -2
  46. package/dist/schema/{agents.d.ts → workflow-definitions.d.ts} +79 -113
  47. package/dist/schema/workflow-definitions.js +97 -0
  48. package/dist/schema/workflow-run-dispatch.d.ts +328 -0
  49. package/dist/schema/workflow-run-dispatch.js +56 -0
  50. package/dist/schema/{workflow-deployments.d.ts → workflow-run-execution.d.ts} +43 -46
  51. package/dist/schema/workflow-run-execution.js +48 -0
  52. package/dist/schema/workflow-run-launch-spec.d.ts +200 -0
  53. package/dist/schema/workflow-run-launch-spec.js +26 -0
  54. package/dist/schema/{instances.d.ts → workflow-run.d.ts} +39 -71
  55. package/dist/schema/workflow-run.js +102 -0
  56. package/dist/sidecar-allocation-store.d.ts +171 -0
  57. package/dist/sidecar-allocation-store.js +512 -0
  58. package/dist/signal-correlation-store.d.ts +36 -0
  59. package/dist/signal-correlation-store.js +63 -0
  60. package/dist/tenant-hierarchy.d.ts +2 -1
  61. package/dist/tenant-hierarchy.js +10 -5
  62. package/dist/workflow-definition-store.d.ts +55 -0
  63. package/dist/workflow-definition-store.js +93 -0
  64. package/dist/workflow-run-dispatch-store.d.ts +80 -0
  65. package/dist/workflow-run-dispatch-store.js +298 -0
  66. package/dist/workflow-run-launch-spec-store.d.ts +13 -0
  67. package/dist/workflow-run-launch-spec-store.js +30 -0
  68. package/dist/workflow-run-store.d.ts +54 -0
  69. package/dist/workflow-run-store.js +85 -0
  70. package/migrations/0037_credential_use_backfill.sql +39 -0
  71. package/migrations/0038_chilly_blacklash.sql +37 -0
  72. package/migrations/0039_quick_carnage.sql +2 -0
  73. package/migrations/0040_reshape_approval_origin.sql +24 -0
  74. package/migrations/0041_make_approval_timeout_at_nullable.sql +1 -0
  75. package/migrations/0042_youthful_mantis.sql +2 -0
  76. package/migrations/0043_signal_correlation_deployment_fk.sql +1 -0
  77. package/migrations/0044_model_offering_quirks.sql +1 -0
  78. package/migrations/0045_create_workflow_run.sql +13 -0
  79. package/migrations/0046_approval_signal_correlation_run_fk.sql +2 -0
  80. package/migrations/0047_create_workflow_definition.sql +30 -0
  81. package/migrations/0048_workflow_definition_origin_agent_id.sql +2 -0
  82. package/migrations/0049_curly_omega_flight.sql +2 -0
  83. package/migrations/0050_late_crystal.sql +10 -0
  84. package/migrations/0051_funny_madelyne_pryor.sql +1 -0
  85. package/migrations/0052_drop_inference_turn_instance_fk.sql +1 -0
  86. package/migrations/0053_session_mail_session_id_index.sql +1 -0
  87. package/migrations/0054_rekey_instance_grants_to_workflow_run.sql +10 -0
  88. package/migrations/0055_backfill_anchor_workflow_runs.sql +69 -0
  89. package/migrations/0056_repoint_deployment_fks_to_anchor_run.sql +32 -0
  90. package/migrations/0057_drop_workflow_deployment_projection.sql +22 -0
  91. package/migrations/0058_repoint_offering_fk_to_definition.sql +41 -0
  92. package/migrations/0059_repoint_transaction_fk_to_run.sql +10 -0
  93. package/migrations/0060_drop_session_mail_instance_fk.sql +6 -0
  94. package/migrations/0061_drop_session_asset_instance_fk.sql +7 -0
  95. package/migrations/0062_drop_agent_asset_table.sql +11 -0
  96. package/migrations/0063_repoint_agent_role_fk_to_definition.sql +39 -0
  97. package/migrations/0064_repoint_agent_session_fk_to_definition.sql +47 -0
  98. package/migrations/0065_add_workflow_definition_model_requirements.sql +37 -0
  99. package/migrations/0066_rekey_agent_definition_principals_to_workflow.sql +27 -0
  100. package/migrations/0067_add_workflow_definition_kind.sql +10 -0
  101. package/migrations/0068_drop_agent_tables_and_origin_agent_id.sql +31 -0
  102. package/migrations/0069_drop_workflow_definition_kind.sql +10 -0
  103. package/migrations/0070_flashy_proteus.sql +13 -0
  104. package/migrations/0072_add_workflow_definition_credential_bindings.sql +1 -0
  105. package/migrations/0073_grant_target_exactly_one_check.sql +13 -0
  106. package/migrations/0074_add_provider_api_base_url.sql +1 -0
  107. package/migrations/0075_workflow_run_launch_spec.sql +17 -0
  108. package/migrations/0076_sidecar_allocation.sql +40 -0
  109. package/migrations/0077_workflow_run_dispatch.sql +29 -0
  110. package/migrations/0078_workflow_run_dispatch_kind.sql +2 -0
  111. package/migrations/0079_rename_workflow_run_deployment_id_to_anchor_run_id.sql +4 -0
  112. package/migrations/0080_rename_correlation_approval_deployment_id_to_anchor_run_id.sql +9 -0
  113. package/migrations/0081_workflow_definition_content_hash_and_approved_wire_hash.sql +4 -0
  114. package/migrations/0082_blue_black_queen.sql +1 -0
  115. package/migrations/0083_replace_launch_spec_snapshot_with_frozen_bundle.sql +3 -0
  116. package/migrations/0084_delete_orphaned_credential_grants.sql +22 -0
  117. package/migrations/meta/0037_snapshot.json +3237 -0
  118. package/migrations/meta/0038_snapshot.json +3470 -0
  119. package/migrations/meta/0039_snapshot.json +3470 -0
  120. package/migrations/meta/0040_snapshot.json +3489 -0
  121. package/migrations/meta/0041_snapshot.json +3489 -0
  122. package/migrations/meta/0042_snapshot.json +3489 -0
  123. package/migrations/meta/0043_snapshot.json +3498 -0
  124. package/migrations/meta/0044_snapshot.json +3504 -0
  125. package/migrations/meta/0045_snapshot.json +3589 -0
  126. package/migrations/meta/0046_snapshot.json +3607 -0
  127. package/migrations/meta/0047_snapshot.json +3832 -0
  128. package/migrations/meta/0048_snapshot.json +3853 -0
  129. package/migrations/meta/0049_snapshot.json +3854 -0
  130. package/migrations/meta/0050_snapshot.json +3924 -0
  131. package/migrations/meta/0051_snapshot.json +3940 -0
  132. package/migrations/meta/0052_snapshot.json +3931 -0
  133. package/migrations/meta/0053_snapshot.json +3952 -0
  134. package/migrations/meta/0054_snapshot.json +3952 -0
  135. package/migrations/meta/0055_snapshot.json +3952 -0
  136. package/migrations/meta/0056_snapshot.json +3952 -0
  137. package/migrations/meta/0057_snapshot.json +3839 -0
  138. package/migrations/meta/0058_snapshot.json +3839 -0
  139. package/migrations/meta/0059_snapshot.json +3839 -0
  140. package/migrations/meta/0060_snapshot.json +3830 -0
  141. package/migrations/meta/0061_snapshot.json +3821 -0
  142. package/migrations/meta/0062_snapshot.json +3723 -0
  143. package/migrations/meta/0063_snapshot.json +3723 -0
  144. package/migrations/meta/0064_snapshot.json +3723 -0
  145. package/migrations/meta/0065_snapshot.json +3729 -0
  146. package/migrations/meta/0066_snapshot.json +3729 -0
  147. package/migrations/meta/0067_snapshot.json +3736 -0
  148. package/migrations/meta/0068_snapshot.json +3347 -0
  149. package/migrations/meta/0069_snapshot.json +3340 -0
  150. package/migrations/meta/0070_snapshot.json +3444 -0
  151. package/migrations/meta/0072_snapshot.json +3450 -0
  152. package/migrations/meta/0073_snapshot.json +3455 -0
  153. package/migrations/meta/0074_snapshot.json +3461 -0
  154. package/migrations/meta/0075_snapshot.json +3567 -0
  155. package/migrations/meta/0076_snapshot.json +3851 -0
  156. package/migrations/meta/0077_snapshot.json +4067 -0
  157. package/migrations/meta/0078_snapshot.json +4078 -0
  158. package/migrations/meta/0079_snapshot.json +4078 -0
  159. package/migrations/meta/0080_snapshot.json +4078 -0
  160. package/migrations/meta/0081_snapshot.json +4096 -0
  161. package/migrations/meta/0082_snapshot.json +4102 -0
  162. package/migrations/meta/0083_snapshot.json +4096 -0
  163. package/migrations/meta/0084_snapshot.json +4096 -0
  164. package/migrations/meta/_journal.json +329 -0
  165. package/package.json +6 -3
  166. package/dist/schema/agent-assets.d.ts +0 -109
  167. package/dist/schema/agent-assets.js +0 -15
  168. package/dist/schema/agents.js +0 -57
  169. package/dist/schema/instances.js +0 -39
  170. package/dist/schema/workflow-deployments.js +0 -37
@@ -0,0 +1,39 @@
1
+ -- Re-point the agent_role foreign key off the agent onto the folded workflow
2
+ -- definition. The column keeps its agent_id name, but its values become
3
+ -- workflow_definition ids: every agent was folded to exactly one definition,
4
+ -- linked by workflow_definition.origin_agent_id (a partial unique index, so
5
+ -- the join matches at most one definition). Role assignments follow the
6
+ -- definition so they survive the agent table's retirement.
7
+ --
8
+ -- The guard runs before any write. The production path applies migrations under
9
+ -- `drizzle-kit migrate`, which wraps the pending set in a transaction, and
10
+ -- PostgreSQL DDL is transactional, so an aborting guard rolls the whole set
11
+ -- back -- there is no partial commit to defend against. It aborts loudly if any
12
+ -- agent_role row references an agent with no folded definition, meaning the
13
+ -- agent fold has not run; the total fold makes that impossible in a folded
14
+ -- database, so the guard is a fail-loud assertion.
15
+ DO $$
16
+ BEGIN
17
+ IF EXISTS (
18
+ SELECT 1
19
+ FROM "agent_role" ar
20
+ WHERE NOT EXISTS (
21
+ SELECT 1 FROM "workflow_definition" wd
22
+ WHERE wd.origin_agent_id = ar.agent_id
23
+ )
24
+ ) THEN
25
+ RAISE EXCEPTION 'agent_role row(s) reference an agent with no folded definition; run the agent fold (bin/db-backfill) before applying this migration';
26
+ END IF;
27
+ END $$;
28
+ --> statement-breakpoint
29
+ -- Drop the old agent foreign key BEFORE rewriting the values: the rewrite sets
30
+ -- agent_id to a workflow_definition id, which is not an agent id, so it would
31
+ -- violate the still-active agent FK.
32
+ ALTER TABLE "agent_role" DROP CONSTRAINT "agent_role_agent_id_agent_id_fk";
33
+ --> statement-breakpoint
34
+ UPDATE "agent_role" ar
35
+ SET agent_id = wd.id
36
+ FROM "workflow_definition" wd
37
+ WHERE wd.origin_agent_id = ar.agent_id;
38
+ --> statement-breakpoint
39
+ ALTER TABLE "agent_role" ADD CONSTRAINT "agent_role_agent_id_workflow_definition_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."workflow_definition"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1,47 @@
1
+ -- Re-point the agent_session foreign key off the agent onto the folded
2
+ -- workflow definition. The column keeps its agent_id name, but its values
3
+ -- become workflow_definition ids: a launched session is keyed to the folded
4
+ -- definition it runs, so it survives the agent table's retirement. The delete
5
+ -- rule also changes -- cascade (on agent, from 0008) becomes restrict: session
6
+ -- history is an audit record, so a definition with live sessions must not be
7
+ -- droppable out from under them.
8
+ --
9
+ -- The guard runs before any write. The production path applies migrations under
10
+ -- `drizzle-kit migrate`, which wraps the pending set in a transaction, and
11
+ -- PostgreSQL DDL is transactional, so an aborting guard rolls the whole set
12
+ -- back -- there is no partial commit to defend against.
13
+ -- Unlike the offering (0058) and agent_role (0063) re-points, it guards the
14
+ -- AGENT table, not agent_session: the launch handler writes a fresh
15
+ -- agent_session row at runtime for an agent that may have no existing sessions,
16
+ -- so a child-table guard would pass vacuously for a never-launched unfolded
17
+ -- agent and the writer would then explode on its undefined definition id.
18
+ -- Every agent folded implies every session's agent folded, covering both this
19
+ -- historical rewrite and the runtime writer.
20
+ DO $$
21
+ BEGIN
22
+ IF EXISTS (
23
+ SELECT 1
24
+ FROM "agent" a
25
+ WHERE NOT EXISTS (
26
+ SELECT 1 FROM "workflow_definition" wd
27
+ WHERE wd.origin_agent_id = a.id
28
+ )
29
+ ) THEN
30
+ RAISE EXCEPTION 'agent(s) have no folded definition; run the agent fold (bin/db-backfill) before applying this migration';
31
+ END IF;
32
+ END $$;
33
+ --> statement-breakpoint
34
+ -- Drop the old agent foreign key BEFORE rewriting the values: the rewrite sets
35
+ -- agent_id to a workflow_definition id, which is not an agent id, so it would
36
+ -- violate the still-active agent FK. agent_session's agent FK was written as a
37
+ -- raw inline REFERENCES in 0008, so Postgres auto-named it
38
+ -- agent_session_agent_id_fkey -- not the drizzle-style
39
+ -- agent_session_agent_id_agent_id_fk the snapshot infers.
40
+ ALTER TABLE "agent_session" DROP CONSTRAINT "agent_session_agent_id_fkey";
41
+ --> statement-breakpoint
42
+ UPDATE "agent_session" s
43
+ SET agent_id = wd.id
44
+ FROM "workflow_definition" wd
45
+ WHERE wd.origin_agent_id = s.agent_id;
46
+ --> statement-breakpoint
47
+ ALTER TABLE "agent_session" ADD CONSTRAINT "agent_session_agent_id_workflow_definition_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."workflow_definition"("id") ON DELETE restrict ON UPDATE no action;
@@ -0,0 +1,37 @@
1
+ -- Mirror each folded agent's model requirements onto its definition, so a
2
+ -- folded launch resolves its inference sources from the definition rather than
3
+ -- the agent row. The column is folded-only: null for a workflow-origin
4
+ -- definition, which carries no requirements manifest. A null/empty manifest is
5
+ -- legitimate -- it resolves to an unlaunchable empty source chain, exactly as
6
+ -- the agent field did -- so the copy preserves null verbatim and the column
7
+ -- takes no NOT NULL constraint.
8
+ --
9
+ -- Guard first: the backfill joins each folded definition to its agent over
10
+ -- origin_agent_id, a plain text column rather than an FK. If any folded
11
+ -- definition names an agent that does not exist, the join silently skips it and
12
+ -- its column stays null -- indistinguishable from a legitimately-null manifest.
13
+ -- Fail loud before writing so a broken back-reference surfaces here, not as a
14
+ -- mysteriously unlaunchable agent later. The production path applies migrations
15
+ -- under `drizzle-kit migrate`, which wraps the pending set in a transaction, and
16
+ -- PostgreSQL DDL is transactional, so an aborting guard rolls the whole set back
17
+ -- rather than leaving a half-applied backfill.
18
+ DO $$
19
+ BEGIN
20
+ IF EXISTS (
21
+ SELECT 1
22
+ FROM "workflow_definition" wd
23
+ WHERE wd.origin_agent_id IS NOT NULL
24
+ AND NOT EXISTS (
25
+ SELECT 1 FROM "agent" a WHERE a.id = wd.origin_agent_id
26
+ )
27
+ ) THEN
28
+ RAISE EXCEPTION 'folded definition(s) reference a missing agent; cannot backfill workflow_definition.model_requirements';
29
+ END IF;
30
+ END $$;
31
+ --> statement-breakpoint
32
+ ALTER TABLE "workflow_definition" ADD COLUMN "model_requirements" jsonb;
33
+ --> statement-breakpoint
34
+ UPDATE "workflow_definition" wd
35
+ SET model_requirements = a.model_requirements
36
+ FROM "agent" a
37
+ WHERE wd.origin_agent_id = a.id;
@@ -0,0 +1,27 @@
1
+ -- Re-key each folded agent's actor identity onto the workflow model. A
2
+ -- definition-level agent principal's ref_id is the legacy agent id; the fold
3
+ -- moved that agent onto a workflow_definition, so its principal moves too --
4
+ -- kind agent -> workflow, ref_id agent.id -> definition.id. Afterwards the
5
+ -- folded agent's stable identity is a workflow-kind principal keyed by the
6
+ -- definition, and any grants it owns ride along under the new key untouched.
7
+ --
8
+ -- The mapping is 1:1 per tenant, which is what keeps the rewrite from
9
+ -- colliding on principal's UNIQUE(tenant_id, kind, ref_id): the partial-unique
10
+ -- index on workflow_definition.origin_agent_id admits at most one definition
11
+ -- per agent id, so no two agent principals collapse onto the same workflow key.
12
+ -- Existing workflow principals key on a run id, never a definition id, so the
13
+ -- re-keyed rows cannot collide with them either. The tenant predicate holds the
14
+ -- rewrite inside a single tenant even though agent ids are globally unique.
15
+ --
16
+ -- Only the definition-level class re-keys. An instance-level agent principal's
17
+ -- ref_id is an agent_instance id, which matches no origin_agent_id (disjoint id
18
+ -- spaces), so the join leaves it kind agent -- it retires later with the
19
+ -- agent_instance table it depends on. Idempotent: kind = 'agent' guards the
20
+ -- rewrite, and once it runs no definition principal remains agent-kind, so a
21
+ -- re-run is a no-op.
22
+ UPDATE "principal" p
23
+ SET kind = 'workflow', ref_id = wd.id
24
+ FROM "workflow_definition" wd
25
+ WHERE p.kind = 'agent'
26
+ AND wd.origin_agent_id = p.ref_id
27
+ AND wd.tenant_id = p.tenant_id;
@@ -0,0 +1,10 @@
1
+ -- Classify each definition as a single-instance launch target (`instance`) or a
2
+ -- multi-step workflow deploy target (`workflow`), so the launch route can gate
3
+ -- on `kind` instead of `origin_agent_id` -- letting that column be dropped
4
+ -- later. Every folded (agent-origin) definition is an instance; a native
5
+ -- workflow-origin definition is a workflow. ADD COLUMN with a `workflow`
6
+ -- default sets every existing row to `workflow`; the backfill then flips the
7
+ -- folded rows, identified by a non-null origin_agent_id, to `instance`.
8
+ ALTER TABLE "workflow_definition" ADD COLUMN "kind" text DEFAULT 'workflow' NOT NULL;
9
+ --> statement-breakpoint
10
+ UPDATE "workflow_definition" SET "kind" = 'instance' WHERE "origin_agent_id" IS NOT NULL;
@@ -0,0 +1,31 @@
1
+ -- The fold onto workflow_definition/workflow_run is complete: nothing reads
2
+ -- the legacy agent tables or workflow_definition.origin_agent_id anymore. Drop
3
+ -- them. Child-first order (no CASCADE) so a bare DROP fails loudly if an
4
+ -- unmodelled dependent survives. The production path applies migrations under
5
+ -- `drizzle-kit migrate`, which wraps the pending set in a transaction, and
6
+ -- PostgreSQL DDL is transactional, so a guard's abort rolls the whole set back;
7
+ -- there is no partial-commit re-run-from-top mode. The IF EXISTS clauses keep
8
+ -- each drop tolerant of an already-absent relation regardless.
9
+ --
10
+ -- Guard first: agent_instance holds legacy routing, mail, and turn state that
11
+ -- the workflow-asset fold never converted into workflow_run (the fold projected
12
+ -- definitions from assets; it never migrated instances), and the fold tooling
13
+ -- has since been retired, so a bare DROP would destroy that state silently.
14
+ -- Abort while the table still holds rows so the loss is loud, not silent. The
15
+ -- to_regclass check keeps the file idempotent: on a re-run after the drop the
16
+ -- table is gone and the guard is skipped rather than erroring on a missing
17
+ -- relation.
18
+ DO $$
19
+ BEGIN
20
+ IF to_regclass('agent_instance') IS NOT NULL THEN
21
+ IF EXISTS (SELECT 1 FROM "agent_instance") THEN
22
+ RAISE EXCEPTION 'agent_instance still holds rows: dropping the agent tables would destroy legacy agent routing, mail, and turn state that was never folded into workflow_run and has no automated conversion (the fold tooling has been retired). Retire the remaining agent instances by hand before applying this migration (see the agent-fold migration note in DEV.md).';
23
+ END IF;
24
+ END IF;
25
+ END $$;
26
+ --> statement-breakpoint
27
+ DROP TABLE IF EXISTS "agent_instance";--> statement-breakpoint
28
+ DROP TABLE IF EXISTS "agent_version";--> statement-breakpoint
29
+ DROP TABLE IF EXISTS "agent";--> statement-breakpoint
30
+ DROP INDEX IF EXISTS "workflow_definition_origin_agent_idx";--> statement-breakpoint
31
+ ALTER TABLE "workflow_definition" DROP COLUMN IF EXISTS "origin_agent_id";
@@ -0,0 +1,10 @@
1
+ -- The instance/workflow `kind` discriminator is redundant: a run already
2
+ -- classifies structurally (a plain routing address with a null deployment id is
3
+ -- an instance-shaped run; a deployment-anchored run carries its deployment id),
4
+ -- and the interactive-launch path gates on the presence of a model_requirements
5
+ -- manifest instead of kind. Drop the column. The production path applies
6
+ -- migrations under `drizzle-kit migrate`, which wraps the pending set in a
7
+ -- transaction, and PostgreSQL DDL is transactional, so an aborting migration
8
+ -- rolls back with no partial-commit re-run to defend against; the IF EXISTS
9
+ -- keeps the drop tolerant of an already-absent column regardless.
10
+ ALTER TABLE "workflow_definition" DROP COLUMN IF EXISTS "kind";
@@ -0,0 +1,13 @@
1
+ CREATE TABLE "workflow_run_execution" (
2
+ "id" text PRIMARY KEY NOT NULL,
3
+ "run_id" text NOT NULL,
4
+ "message_id" text NOT NULL,
5
+ "status" text DEFAULT 'running' NOT NULL,
6
+ "started_at" timestamp DEFAULT now() NOT NULL,
7
+ "ended_at" timestamp,
8
+ "failure_reason" text
9
+ );
10
+ --> statement-breakpoint
11
+ ALTER TABLE "workflow_run_execution" ADD CONSTRAINT "workflow_run_execution_run_id_workflow_run_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
12
+ CREATE UNIQUE INDEX "workflow_run_execution_run_id_id_idx" ON "workflow_run_execution" USING btree ("run_id","id");--> statement-breakpoint
13
+ CREATE INDEX "workflow_run_execution_status_idx" ON "workflow_run_execution" USING btree ("status");
@@ -0,0 +1 @@
1
+ ALTER TABLE "workflow_definition" ADD COLUMN "credential_bindings" jsonb;
@@ -0,0 +1,13 @@
1
+ -- Every grant targets exactly one of a role or a principal. This CHECK is the
2
+ -- universal backstop: it holds for every insert path, including the internal
3
+ -- seeding and materialization sites that never touch the CreateGrant HTTP
4
+ -- validator. On the HTTP path, CreateGrant additionally enforces the same
5
+ -- exactly-one rule so a malformed POST is rejected with a 400 rather than
6
+ -- tripping this constraint as a 500.
7
+ --
8
+ -- On an existing database, ADD CONSTRAINT validates every row and FAILS LOUDLY
9
+ -- if a pre-existing grant carries both targets (or neither) -- rows a prior,
10
+ -- looser write path could have created. That is intentional: a both-target row
11
+ -- is ambiguous to auto-repair, so the migration surfaces it for manual
12
+ -- resolution rather than silently guessing which target to keep.
13
+ ALTER TABLE "grant" ADD CONSTRAINT "grant_target_exactly_one" CHECK (num_nonnulls("grant"."principal_id", "grant"."role_id") = 1);
@@ -0,0 +1 @@
1
+ ALTER TABLE "provider" ADD COLUMN "api_base_url" text;
@@ -0,0 +1,17 @@
1
+ CREATE TABLE "workflow_run_launch_spec" (
2
+ "anchor_run_id" text PRIMARY KEY NOT NULL,
3
+ "schema_version" integer DEFAULT 1 NOT NULL,
4
+ "session_id" text NOT NULL,
5
+ "deployment_domain" text NOT NULL,
6
+ "source_authority_principal_id" text NOT NULL,
7
+ "definition_snapshot" jsonb NOT NULL,
8
+ "definition_hash" text NOT NULL,
9
+ "source_offering_ids" jsonb NOT NULL,
10
+ "default_source_offering_id" text NOT NULL,
11
+ "deploy_content" jsonb NOT NULL,
12
+ "tool_package_pins" jsonb,
13
+ "created_at" timestamp DEFAULT now() NOT NULL
14
+ );
15
+ --> statement-breakpoint
16
+ ALTER TABLE "workflow_run_launch_spec" ADD CONSTRAINT "workflow_run_launch_spec_anchor_run_id_workflow_run_id_fk" FOREIGN KEY ("anchor_run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
17
+ ALTER TABLE "workflow_run_launch_spec" ADD CONSTRAINT "workflow_run_launch_spec_source_authority_principal_id_principal_id_fk" FOREIGN KEY ("source_authority_principal_id") REFERENCES "public"."principal"("id") ON DELETE restrict ON UPDATE no action;
@@ -0,0 +1,40 @@
1
+ CREATE TABLE "sidecar_allocation" (
2
+ "id" text PRIMARY KEY NOT NULL,
3
+ "anchor_run_id" text NOT NULL,
4
+ "tenant_id" text NOT NULL,
5
+ "provisioner_id" text NOT NULL,
6
+ "provisioner_api_version" integer NOT NULL,
7
+ "provisioner_binding_fingerprint" text NOT NULL,
8
+ "sidecar_id" text,
9
+ "placement_sharing" text NOT NULL,
10
+ "sidecar_reuse" text DEFAULT 'never' NOT NULL,
11
+ "status" text DEFAULT 'pending' NOT NULL,
12
+ "generation" integer DEFAULT 0 NOT NULL,
13
+ "ensure_accepted_generation" integer,
14
+ "external_ref" text,
15
+ "next_attempt_at" timestamp,
16
+ "reconciliation_lease_id" text,
17
+ "reconciliation_lease_expires_at" timestamp,
18
+ "ensure_attempts" integer DEFAULT 0 NOT NULL,
19
+ "destroy_attempts" integer DEFAULT 0 NOT NULL,
20
+ "connect_deadline" timestamp,
21
+ "failure_code" text,
22
+ "failure_message" text,
23
+ "created_at" timestamp DEFAULT now() NOT NULL,
24
+ "updated_at" timestamp DEFAULT now() NOT NULL,
25
+ CONSTRAINT "sidecar_allocation_status_check" CHECK ("sidecar_allocation"."status" in ('pending', 'provisioning', 'allocated', 'replacing', 'releasing', 'released', 'failed')),
26
+ CONSTRAINT "sidecar_allocation_placement_check" CHECK ("sidecar_allocation"."placement_sharing" = 'exclusive'),
27
+ CONSTRAINT "sidecar_allocation_generation_check" CHECK ("sidecar_allocation"."generation" >= 0),
28
+ CONSTRAINT "sidecar_allocation_accepted_generation_check" CHECK ("sidecar_allocation"."ensure_accepted_generation" is null or "sidecar_allocation"."ensure_accepted_generation" <= "sidecar_allocation"."generation")
29
+ );
30
+ --> statement-breakpoint
31
+ ALTER TABLE "sidecar" ALTER COLUMN "url" DROP NOT NULL;--> statement-breakpoint
32
+ ALTER TABLE "sidecar" ADD COLUMN "credential_scope" text DEFAULT 'shared' NOT NULL;--> statement-breakpoint
33
+ ALTER TABLE "sidecar_allocation" ADD CONSTRAINT "sidecar_allocation_anchor_run_id_workflow_run_id_fk" FOREIGN KEY ("anchor_run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
34
+ ALTER TABLE "sidecar_allocation" ADD CONSTRAINT "sidecar_allocation_tenant_id_tenant_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenant"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
35
+ ALTER TABLE "sidecar_allocation" ADD CONSTRAINT "sidecar_allocation_sidecar_id_sidecar_id_fk" FOREIGN KEY ("sidecar_id") REFERENCES "public"."sidecar"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
36
+ CREATE UNIQUE INDEX "sidecar_allocation_anchor_run_idx" ON "sidecar_allocation" USING btree ("anchor_run_id");--> statement-breakpoint
37
+ CREATE UNIQUE INDEX "sidecar_allocation_active_sidecar_idx" ON "sidecar_allocation" USING btree ("sidecar_id") WHERE "sidecar_allocation"."status" in ('provisioning', 'allocated', 'replacing', 'releasing');--> statement-breakpoint
38
+ CREATE INDEX "sidecar_allocation_sidecar_idx" ON "sidecar_allocation" USING btree ("sidecar_id");--> statement-breakpoint
39
+ CREATE INDEX "sidecar_allocation_reconciliation_idx" ON "sidecar_allocation" USING btree ("next_attempt_at","created_at") WHERE "sidecar_allocation"."status" in ('pending', 'provisioning', 'allocated', 'replacing', 'releasing') and "sidecar_allocation"."next_attempt_at" is not null;--> statement-breakpoint
40
+ ALTER TABLE "sidecar" ADD CONSTRAINT "sidecar_credential_scope_check" CHECK ("sidecar"."credential_scope" in ('shared', 'allocated'));
@@ -0,0 +1,29 @@
1
+ CREATE TABLE "workflow_run_dispatch" (
2
+ "id" text PRIMARY KEY NOT NULL,
3
+ "anchor_run_id" text NOT NULL,
4
+ "message_id" text NOT NULL,
5
+ "raw_message" "bytea" NOT NULL,
6
+ "step_grants" jsonb NOT NULL,
7
+ "status" text DEFAULT 'pending' NOT NULL,
8
+ "acknowledged_generation" integer,
9
+ "attempt_count" integer DEFAULT 0 NOT NULL,
10
+ "next_attempt_at" timestamp DEFAULT now(),
11
+ "delivery_lease_id" text,
12
+ "delivery_lease_expires_at" timestamp,
13
+ "failure_code" text,
14
+ "failure_message" text,
15
+ "created_at" timestamp DEFAULT now() NOT NULL,
16
+ "updated_at" timestamp DEFAULT now() NOT NULL,
17
+ "acknowledged_at" timestamp,
18
+ "settled_at" timestamp,
19
+ CONSTRAINT "workflow_run_dispatch_status_check" CHECK ("workflow_run_dispatch"."status" in ('pending', 'acknowledged', 'settled', 'failed')),
20
+ CONSTRAINT "workflow_run_dispatch_attempt_count_check" CHECK ("workflow_run_dispatch"."attempt_count" >= 0),
21
+ CONSTRAINT "workflow_run_dispatch_acknowledged_generation_check" CHECK ("workflow_run_dispatch"."acknowledged_generation" is null or "workflow_run_dispatch"."acknowledged_generation" >= 0),
22
+ CONSTRAINT "workflow_run_dispatch_acknowledged_state_check" CHECK ("workflow_run_dispatch"."status" <> 'acknowledged' or "workflow_run_dispatch"."acknowledged_generation" is not null),
23
+ CONSTRAINT "workflow_run_dispatch_pending_schedule_check" CHECK ("workflow_run_dispatch"."status" <> 'pending' or "workflow_run_dispatch"."next_attempt_at" is not null)
24
+ );
25
+ --> statement-breakpoint
26
+ ALTER TABLE "workflow_run_dispatch" ADD CONSTRAINT "workflow_run_dispatch_anchor_run_id_workflow_run_id_fk" FOREIGN KEY ("anchor_run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
27
+ CREATE UNIQUE INDEX "workflow_run_dispatch_anchor_message_idx" ON "workflow_run_dispatch" USING btree ("anchor_run_id","message_id");--> statement-breakpoint
28
+ CREATE INDEX "workflow_run_dispatch_delivery_idx" ON "workflow_run_dispatch" USING btree ("next_attempt_at","created_at") WHERE "workflow_run_dispatch"."status" = 'pending';--> statement-breakpoint
29
+ CREATE INDEX "workflow_run_dispatch_anchor_status_idx" ON "workflow_run_dispatch" USING btree ("anchor_run_id","status");
@@ -0,0 +1,2 @@
1
+ ALTER TABLE "workflow_run_dispatch" ADD COLUMN "kind" text DEFAULT 'mail' NOT NULL;--> statement-breakpoint
2
+ ALTER TABLE "workflow_run_dispatch" ADD CONSTRAINT "workflow_run_dispatch_kind_check" CHECK ("workflow_run_dispatch"."kind" in ('mail', 'signal'));
@@ -0,0 +1,4 @@
1
+ ALTER TABLE "workflow_run" RENAME COLUMN "deployment_id" TO "anchor_run_id";--> statement-breakpoint
2
+ ALTER TABLE "workflow_run" DROP CONSTRAINT "workflow_run_deployment_id_workflow_run_id_fk";
3
+ --> statement-breakpoint
4
+ ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_anchor_run_id_workflow_run_id_fk" FOREIGN KEY ("anchor_run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1,9 @@
1
+ ALTER TABLE "signal_correlation" RENAME COLUMN "deployment_id" TO "anchor_run_id";--> statement-breakpoint
2
+ ALTER TABLE "approval" RENAME COLUMN "deployment_id" TO "anchor_run_id";--> statement-breakpoint
3
+ ALTER TABLE "approval" DROP CONSTRAINT "approval_deployment_id_workflow_run_id_fk";
4
+ --> statement-breakpoint
5
+ ALTER TABLE "signal_correlation" DROP CONSTRAINT "signal_correlation_deployment_id_workflow_run_id_fk";
6
+ --> statement-breakpoint
7
+ ALTER INDEX "approval_deployment_idx" RENAME TO "approval_anchor_run_idx";--> statement-breakpoint
8
+ ALTER TABLE "approval" ADD CONSTRAINT "approval_anchor_run_id_workflow_run_id_fk" FOREIGN KEY ("anchor_run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
9
+ ALTER TABLE "signal_correlation" ADD CONSTRAINT "signal_correlation_anchor_run_id_workflow_run_id_fk" FOREIGN KEY ("anchor_run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1,4 @@
1
+ DROP INDEX "workflow_definition_asset_idx";--> statement-breakpoint
2
+ ALTER TABLE "workflow_definition" ADD COLUMN "wire_hash" text;--> statement-breakpoint
3
+ ALTER TABLE "workflow_definition_version" ADD COLUMN "approved_wire_hash" text;--> statement-breakpoint
4
+ CREATE UNIQUE INDEX "workflow_definition_asset_wire_hash_idx" ON "workflow_definition" USING btree ("asset_id","wire_hash");
@@ -0,0 +1 @@
1
+ ALTER TABLE "workflow_definition_version" ADD COLUMN "grant_snapshot" jsonb;
@@ -0,0 +1,3 @@
1
+ ALTER TABLE "workflow_run_launch_spec" ADD COLUMN "frozen_approval_bundle" jsonb NOT NULL;--> statement-breakpoint
2
+ ALTER TABLE "workflow_run_launch_spec" DROP COLUMN "definition_snapshot";--> statement-breakpoint
3
+ ALTER TABLE "workflow_run_launch_spec" DROP COLUMN "definition_hash";
@@ -0,0 +1,22 @@
1
+ -- Remove `credential:{id}` grant rows that reference a credential that no longer
2
+ -- exists. Before credential DELETE cleaned up its per-credential grants, deleting
3
+ -- a personal credential left its `credential:{id}` grant behind, and migration
4
+ -- 0037 backfilled the same shape for pre-existing personal credentials, so a
5
+ -- credential hard-deleted before that cleanup shipped left an orphaned grant.
6
+ --
7
+ -- The coarse wildcard `credential:*` role resource is excluded explicitly: no
8
+ -- credential has the id `*`, so the NOT EXISTS guard alone would wrongly match
9
+ -- it. There is no tenant scope: credential ids are globally unique, so an
10
+ -- orphaned grant is one whose id matches no credential in any tenant. This
11
+ -- removes every action on an orphaned resource, matching the credential DELETE
12
+ -- handler.
13
+ --
14
+ -- Idempotent: after this runs no orphaned row remains, so a re-run is a no-op.
15
+ DELETE FROM "grant"
16
+ WHERE "resource" LIKE 'credential:%'
17
+ AND "resource" <> 'credential:*'
18
+ AND NOT EXISTS (
19
+ SELECT 1
20
+ FROM "credential" c
21
+ WHERE c."id" = substr("grant"."resource", length('credential:') + 1)
22
+ );