@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.
- package/README.md +2 -2
- package/dist/approval-store.d.ts +52 -0
- package/dist/approval-store.js +79 -0
- package/dist/asset-resolution.d.ts +2 -2
- package/dist/client.d.ts +10 -0
- package/dist/connection.js +11 -8
- package/dist/credential-resolution.d.ts +130 -18
- package/dist/credential-resolution.js +142 -3
- package/dist/grant-store.js +35 -13
- package/dist/index.d.ts +13 -4
- package/dist/index.js +11 -3
- package/dist/model-source-resolution.d.ts +52 -6
- package/dist/model-source-resolution.js +145 -19
- package/dist/parse-row.d.ts +212 -32
- package/dist/parse-row.js +109 -18
- package/dist/rekey-credential-secrets.d.ts +13 -0
- package/dist/rekey-credential-secrets.js +61 -0
- package/dist/schema/approvals.d.ts +245 -0
- package/dist/schema/approvals.js +52 -0
- package/dist/schema/catalog.d.ts +17 -0
- package/dist/schema/catalog.js +7 -1
- package/dist/schema/credentials.d.ts +1 -1
- package/dist/schema/git-tokens.js +1 -1
- package/dist/schema/grants.js +8 -2
- package/dist/schema/index.d.ts +8 -4
- package/dist/schema/index.js +8 -4
- package/dist/schema/messages.d.ts +5 -5
- package/dist/schema/messages.js +20 -9
- package/dist/schema/offerings.js +8 -2
- package/dist/schema/principals.d.ts +2 -2
- package/dist/schema/principals.js +7 -5
- package/dist/schema/providers.d.ts +17 -0
- package/dist/schema/providers.js +5 -0
- package/dist/schema/roles.js +6 -2
- package/dist/schema/session-assets.d.ts +1 -38
- package/dist/schema/session-assets.js +36 -19
- package/dist/schema/sessions.js +7 -2
- package/dist/schema/sidecar-allocation.d.ts +406 -0
- package/dist/schema/sidecar-allocation.js +57 -0
- package/dist/schema/sidecar.d.ts +19 -2
- package/dist/schema/sidecar.js +13 -3
- package/dist/schema/signal-correlations.d.ts +177 -0
- package/dist/schema/signal-correlations.js +31 -0
- package/dist/schema/wallets.d.ts +3 -3
- package/dist/schema/wallets.js +4 -2
- package/dist/schema/{agents.d.ts → workflow-definitions.d.ts} +79 -113
- package/dist/schema/workflow-definitions.js +97 -0
- package/dist/schema/workflow-run-dispatch.d.ts +328 -0
- package/dist/schema/workflow-run-dispatch.js +56 -0
- package/dist/schema/{workflow-deployments.d.ts → workflow-run-execution.d.ts} +43 -46
- package/dist/schema/workflow-run-execution.js +48 -0
- package/dist/schema/workflow-run-launch-spec.d.ts +200 -0
- package/dist/schema/workflow-run-launch-spec.js +26 -0
- package/dist/schema/{instances.d.ts → workflow-run.d.ts} +39 -71
- package/dist/schema/workflow-run.js +102 -0
- package/dist/sidecar-allocation-store.d.ts +171 -0
- package/dist/sidecar-allocation-store.js +512 -0
- package/dist/signal-correlation-store.d.ts +36 -0
- package/dist/signal-correlation-store.js +63 -0
- package/dist/tenant-hierarchy.d.ts +2 -1
- package/dist/tenant-hierarchy.js +10 -5
- package/dist/workflow-definition-store.d.ts +55 -0
- package/dist/workflow-definition-store.js +93 -0
- package/dist/workflow-run-dispatch-store.d.ts +80 -0
- package/dist/workflow-run-dispatch-store.js +298 -0
- package/dist/workflow-run-launch-spec-store.d.ts +13 -0
- package/dist/workflow-run-launch-spec-store.js +30 -0
- package/dist/workflow-run-store.d.ts +54 -0
- package/dist/workflow-run-store.js +85 -0
- package/migrations/0037_credential_use_backfill.sql +39 -0
- package/migrations/0038_chilly_blacklash.sql +37 -0
- package/migrations/0039_quick_carnage.sql +2 -0
- package/migrations/0040_reshape_approval_origin.sql +24 -0
- package/migrations/0041_make_approval_timeout_at_nullable.sql +1 -0
- package/migrations/0042_youthful_mantis.sql +2 -0
- package/migrations/0043_signal_correlation_deployment_fk.sql +1 -0
- package/migrations/0044_model_offering_quirks.sql +1 -0
- package/migrations/0045_create_workflow_run.sql +13 -0
- package/migrations/0046_approval_signal_correlation_run_fk.sql +2 -0
- package/migrations/0047_create_workflow_definition.sql +30 -0
- package/migrations/0048_workflow_definition_origin_agent_id.sql +2 -0
- package/migrations/0049_curly_omega_flight.sql +2 -0
- package/migrations/0050_late_crystal.sql +10 -0
- package/migrations/0051_funny_madelyne_pryor.sql +1 -0
- package/migrations/0052_drop_inference_turn_instance_fk.sql +1 -0
- package/migrations/0053_session_mail_session_id_index.sql +1 -0
- package/migrations/0054_rekey_instance_grants_to_workflow_run.sql +10 -0
- package/migrations/0055_backfill_anchor_workflow_runs.sql +69 -0
- package/migrations/0056_repoint_deployment_fks_to_anchor_run.sql +32 -0
- package/migrations/0057_drop_workflow_deployment_projection.sql +22 -0
- package/migrations/0058_repoint_offering_fk_to_definition.sql +41 -0
- package/migrations/0059_repoint_transaction_fk_to_run.sql +10 -0
- package/migrations/0060_drop_session_mail_instance_fk.sql +6 -0
- package/migrations/0061_drop_session_asset_instance_fk.sql +7 -0
- package/migrations/0062_drop_agent_asset_table.sql +11 -0
- package/migrations/0063_repoint_agent_role_fk_to_definition.sql +39 -0
- package/migrations/0064_repoint_agent_session_fk_to_definition.sql +47 -0
- package/migrations/0065_add_workflow_definition_model_requirements.sql +37 -0
- package/migrations/0066_rekey_agent_definition_principals_to_workflow.sql +27 -0
- package/migrations/0067_add_workflow_definition_kind.sql +10 -0
- package/migrations/0068_drop_agent_tables_and_origin_agent_id.sql +31 -0
- package/migrations/0069_drop_workflow_definition_kind.sql +10 -0
- package/migrations/0070_flashy_proteus.sql +13 -0
- package/migrations/0072_add_workflow_definition_credential_bindings.sql +1 -0
- package/migrations/0073_grant_target_exactly_one_check.sql +13 -0
- package/migrations/0074_add_provider_api_base_url.sql +1 -0
- package/migrations/0075_workflow_run_launch_spec.sql +17 -0
- package/migrations/0076_sidecar_allocation.sql +40 -0
- package/migrations/0077_workflow_run_dispatch.sql +29 -0
- package/migrations/0078_workflow_run_dispatch_kind.sql +2 -0
- package/migrations/0079_rename_workflow_run_deployment_id_to_anchor_run_id.sql +4 -0
- package/migrations/0080_rename_correlation_approval_deployment_id_to_anchor_run_id.sql +9 -0
- package/migrations/0081_workflow_definition_content_hash_and_approved_wire_hash.sql +4 -0
- package/migrations/0082_blue_black_queen.sql +1 -0
- package/migrations/0083_replace_launch_spec_snapshot_with_frozen_bundle.sql +3 -0
- package/migrations/0084_delete_orphaned_credential_grants.sql +22 -0
- package/migrations/meta/0037_snapshot.json +3237 -0
- package/migrations/meta/0038_snapshot.json +3470 -0
- package/migrations/meta/0039_snapshot.json +3470 -0
- package/migrations/meta/0040_snapshot.json +3489 -0
- package/migrations/meta/0041_snapshot.json +3489 -0
- package/migrations/meta/0042_snapshot.json +3489 -0
- package/migrations/meta/0043_snapshot.json +3498 -0
- package/migrations/meta/0044_snapshot.json +3504 -0
- package/migrations/meta/0045_snapshot.json +3589 -0
- package/migrations/meta/0046_snapshot.json +3607 -0
- package/migrations/meta/0047_snapshot.json +3832 -0
- package/migrations/meta/0048_snapshot.json +3853 -0
- package/migrations/meta/0049_snapshot.json +3854 -0
- package/migrations/meta/0050_snapshot.json +3924 -0
- package/migrations/meta/0051_snapshot.json +3940 -0
- package/migrations/meta/0052_snapshot.json +3931 -0
- package/migrations/meta/0053_snapshot.json +3952 -0
- package/migrations/meta/0054_snapshot.json +3952 -0
- package/migrations/meta/0055_snapshot.json +3952 -0
- package/migrations/meta/0056_snapshot.json +3952 -0
- package/migrations/meta/0057_snapshot.json +3839 -0
- package/migrations/meta/0058_snapshot.json +3839 -0
- package/migrations/meta/0059_snapshot.json +3839 -0
- package/migrations/meta/0060_snapshot.json +3830 -0
- package/migrations/meta/0061_snapshot.json +3821 -0
- package/migrations/meta/0062_snapshot.json +3723 -0
- package/migrations/meta/0063_snapshot.json +3723 -0
- package/migrations/meta/0064_snapshot.json +3723 -0
- package/migrations/meta/0065_snapshot.json +3729 -0
- package/migrations/meta/0066_snapshot.json +3729 -0
- package/migrations/meta/0067_snapshot.json +3736 -0
- package/migrations/meta/0068_snapshot.json +3347 -0
- package/migrations/meta/0069_snapshot.json +3340 -0
- package/migrations/meta/0070_snapshot.json +3444 -0
- package/migrations/meta/0072_snapshot.json +3450 -0
- package/migrations/meta/0073_snapshot.json +3455 -0
- package/migrations/meta/0074_snapshot.json +3461 -0
- package/migrations/meta/0075_snapshot.json +3567 -0
- package/migrations/meta/0076_snapshot.json +3851 -0
- package/migrations/meta/0077_snapshot.json +4067 -0
- package/migrations/meta/0078_snapshot.json +4078 -0
- package/migrations/meta/0079_snapshot.json +4078 -0
- package/migrations/meta/0080_snapshot.json +4078 -0
- package/migrations/meta/0081_snapshot.json +4096 -0
- package/migrations/meta/0082_snapshot.json +4102 -0
- package/migrations/meta/0083_snapshot.json +4096 -0
- package/migrations/meta/0084_snapshot.json +4096 -0
- package/migrations/meta/_journal.json +329 -0
- package/package.json +6 -3
- package/dist/schema/agent-assets.d.ts +0 -109
- package/dist/schema/agent-assets.js +0 -15
- package/dist/schema/agents.js +0 -57
- package/dist/schema/instances.js +0 -39
- package/dist/schema/workflow-deployments.js +0 -37
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DB, DBExecutor } from "./client.js";
|
|
2
|
+
import { parseWorkflowRunLaunchSpecRow } from "./parse-row.js";
|
|
3
|
+
import { workflowRunLaunchSpec } from "./schema/workflow-run-launch-spec.js";
|
|
4
|
+
type DBHandle = DB["db"];
|
|
5
|
+
type LaunchSpecInsert = typeof workflowRunLaunchSpec.$inferInsert;
|
|
6
|
+
type ParsedLaunchSpec = ReturnType<typeof parseWorkflowRunLaunchSpecRow>;
|
|
7
|
+
/** Store for immutable workflow recovery inputs keyed by anchor run. */
|
|
8
|
+
export declare function createWorkflowRunLaunchSpecStore(db: DBHandle): {
|
|
9
|
+
create(row: LaunchSpecInsert, tx?: DBExecutor): Promise<ParsedLaunchSpec>;
|
|
10
|
+
get(anchorRunId: string, tx?: DBExecutor): Promise<ParsedLaunchSpec | null>;
|
|
11
|
+
};
|
|
12
|
+
export type WorkflowRunLaunchSpecStore = ReturnType<typeof createWorkflowRunLaunchSpecStore>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { eq } from "drizzle-orm";
|
|
2
|
+
import { parseWorkflowRunLaunchSpecRow } from "./parse-row.js";
|
|
3
|
+
import { workflowRunLaunchSpec } from "./schema/workflow-run-launch-spec.js";
|
|
4
|
+
/** Store for immutable workflow recovery inputs keyed by anchor run. */
|
|
5
|
+
export function createWorkflowRunLaunchSpecStore(db) {
|
|
6
|
+
return {
|
|
7
|
+
async create(row, tx) {
|
|
8
|
+
parseWorkflowRunLaunchSpecRow({
|
|
9
|
+
...row,
|
|
10
|
+
schemaVersion: row.schemaVersion ?? 1,
|
|
11
|
+
toolPackagePins: row.toolPackagePins ?? null,
|
|
12
|
+
createdAt: row.createdAt ?? new Date(),
|
|
13
|
+
});
|
|
14
|
+
const [inserted] = await (tx ?? db)
|
|
15
|
+
.insert(workflowRunLaunchSpec)
|
|
16
|
+
.values(row)
|
|
17
|
+
.returning();
|
|
18
|
+
if (inserted === undefined) {
|
|
19
|
+
throw new Error(`workflowRunLaunchSpecStore.create: insert returned no row for ${row.anchorRunId}`);
|
|
20
|
+
}
|
|
21
|
+
return parseWorkflowRunLaunchSpecRow(inserted);
|
|
22
|
+
},
|
|
23
|
+
async get(anchorRunId, tx) {
|
|
24
|
+
const row = await (tx ?? db).query.workflowRunLaunchSpec.findFirst({
|
|
25
|
+
where: eq(workflowRunLaunchSpec.anchorRunId, anchorRunId),
|
|
26
|
+
});
|
|
27
|
+
return row === undefined ? null : parseWorkflowRunLaunchSpecRow(row);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { DB, DBExecutor } from "./client.js";
|
|
2
|
+
import { workflowRun } from "./schema/workflow-run.js";
|
|
3
|
+
import { parseWorkflowRunRow } from "./parse-row.js";
|
|
4
|
+
type DBHandle = DB["db"];
|
|
5
|
+
type WorkflowRunInsert = typeof workflowRun.$inferInsert;
|
|
6
|
+
type ParsedWorkflowRun = ReturnType<typeof parseWorkflowRunRow>;
|
|
7
|
+
/**
|
|
8
|
+
* Store for the `workflow_run` table, the per-run authorization subject that
|
|
9
|
+
* approvals and signal correlations anchor to. Each method accepts an optional
|
|
10
|
+
* transaction handle so the run row can be written in the same transaction that
|
|
11
|
+
* co-writes the run's principal or its approval.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createWorkflowRunStore(db: DBHandle): {
|
|
14
|
+
create(row: WorkflowRunInsert, tx?: DBExecutor): Promise<ParsedWorkflowRun>;
|
|
15
|
+
/**
|
|
16
|
+
* Idempotent variant of `create`. On an `id` primary-key conflict the
|
|
17
|
+
* insert is a no-op and this returns `null` rather than throwing, so a
|
|
18
|
+
* redelivered createIfAbsent (workflow-log replay, supervisor restart
|
|
19
|
+
* re-emitting) does not fail the run's co-write. Returns the parsed row
|
|
20
|
+
* only when this call performed the insert.
|
|
21
|
+
*/
|
|
22
|
+
createIfAbsent(row: WorkflowRunInsert, tx?: DBExecutor): Promise<ParsedWorkflowRun | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Anchor an externally-triggered run onto its deploy-time anchor row. The
|
|
25
|
+
* anchor is created at deploy (born "deployed" with a null principal); the
|
|
26
|
+
* first trigger reconciles it here, attaching `principalId` and flipping
|
|
27
|
+
* "deployed" -> "running" in one UPDATE. The insert is a conflict-tolerant
|
|
28
|
+
* safety net: the anchor provably exists by the time a trigger runs, so it
|
|
29
|
+
* normally no-ops. The three-part guard makes the reconcile single-shot and
|
|
30
|
+
* safe: `principalId IS NULL` never overwrites a principal a concurrent
|
|
31
|
+
* winner already set, and `status = 'deployed'` never resurrects a run a
|
|
32
|
+
* concurrent teardown already settled terminal (the null-principal guard
|
|
33
|
+
* alone would). `principalId` must be non-null: only the externally-
|
|
34
|
+
* triggered path anchors through here, and it always mints one.
|
|
35
|
+
*/
|
|
36
|
+
anchorWithPrincipal(row: WorkflowRunInsert & {
|
|
37
|
+
principalId: string;
|
|
38
|
+
}, tx?: DBExecutor): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Atomically settle a live run into a terminal state. The live-status guard
|
|
41
|
+
* (`status IN ('deployed','running')`) makes the flip single-shot: the first
|
|
42
|
+
* caller stamps the terminal status and `endedAt` and gets the row back; any
|
|
43
|
+
* later caller matches no row and receives null, so the run is not
|
|
44
|
+
* re-terminated and its `endedAt` is not overwritten. Accepting "deployed"
|
|
45
|
+
* settles a deployment torn down before its first trigger. This is a safety
|
|
46
|
+
* property, not a recovery path -- it makes a second call (a manual replay
|
|
47
|
+
* against an already-settled run) a harmless no-op; it does not by itself
|
|
48
|
+
* re-drive a flip that failed. Returns the parsed row only on the winning
|
|
49
|
+
* flip.
|
|
50
|
+
*/
|
|
51
|
+
markTerminal(runId: string, status: "completed" | "failed" | "cancelled", endedAt: Date, tx?: DBExecutor): Promise<ParsedWorkflowRun | null>;
|
|
52
|
+
};
|
|
53
|
+
export type WorkflowRunStore = ReturnType<typeof createWorkflowRunStore>;
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { and, eq, inArray, isNull } from "drizzle-orm";
|
|
2
|
+
import { liveWorkflowRunStatuses, workflowRun } from "./schema/workflow-run.js";
|
|
3
|
+
import { parseWorkflowRunRow } from "./parse-row.js";
|
|
4
|
+
/**
|
|
5
|
+
* Store for the `workflow_run` table, the per-run authorization subject that
|
|
6
|
+
* approvals and signal correlations anchor to. Each method accepts an optional
|
|
7
|
+
* transaction handle so the run row can be written in the same transaction that
|
|
8
|
+
* co-writes the run's principal or its approval.
|
|
9
|
+
*/
|
|
10
|
+
export function createWorkflowRunStore(db) {
|
|
11
|
+
return {
|
|
12
|
+
async create(row, tx) {
|
|
13
|
+
const [inserted] = await (tx ?? db)
|
|
14
|
+
.insert(workflowRun)
|
|
15
|
+
.values(row)
|
|
16
|
+
.returning();
|
|
17
|
+
if (inserted === undefined) {
|
|
18
|
+
throw new Error(`workflowRunStore.create: insert returned no row for ${row.id}`);
|
|
19
|
+
}
|
|
20
|
+
return parseWorkflowRunRow(inserted);
|
|
21
|
+
},
|
|
22
|
+
/**
|
|
23
|
+
* Idempotent variant of `create`. On an `id` primary-key conflict the
|
|
24
|
+
* insert is a no-op and this returns `null` rather than throwing, so a
|
|
25
|
+
* redelivered createIfAbsent (workflow-log replay, supervisor restart
|
|
26
|
+
* re-emitting) does not fail the run's co-write. Returns the parsed row
|
|
27
|
+
* only when this call performed the insert.
|
|
28
|
+
*/
|
|
29
|
+
async createIfAbsent(row, tx) {
|
|
30
|
+
const [inserted] = await (tx ?? db)
|
|
31
|
+
.insert(workflowRun)
|
|
32
|
+
.values(row)
|
|
33
|
+
.onConflictDoNothing({ target: workflowRun.id })
|
|
34
|
+
.returning();
|
|
35
|
+
return inserted === undefined ? null : parseWorkflowRunRow(inserted);
|
|
36
|
+
},
|
|
37
|
+
/**
|
|
38
|
+
* Anchor an externally-triggered run onto its deploy-time anchor row. The
|
|
39
|
+
* anchor is created at deploy (born "deployed" with a null principal); the
|
|
40
|
+
* first trigger reconciles it here, attaching `principalId` and flipping
|
|
41
|
+
* "deployed" -> "running" in one UPDATE. The insert is a conflict-tolerant
|
|
42
|
+
* safety net: the anchor provably exists by the time a trigger runs, so it
|
|
43
|
+
* normally no-ops. The three-part guard makes the reconcile single-shot and
|
|
44
|
+
* safe: `principalId IS NULL` never overwrites a principal a concurrent
|
|
45
|
+
* winner already set, and `status = 'deployed'` never resurrects a run a
|
|
46
|
+
* concurrent teardown already settled terminal (the null-principal guard
|
|
47
|
+
* alone would). `principalId` must be non-null: only the externally-
|
|
48
|
+
* triggered path anchors through here, and it always mints one.
|
|
49
|
+
*/
|
|
50
|
+
async anchorWithPrincipal(row, tx) {
|
|
51
|
+
const executor = tx ?? db;
|
|
52
|
+
const [inserted] = await executor
|
|
53
|
+
.insert(workflowRun)
|
|
54
|
+
.values(row)
|
|
55
|
+
.onConflictDoNothing({ target: workflowRun.id })
|
|
56
|
+
.returning();
|
|
57
|
+
if (inserted !== undefined)
|
|
58
|
+
return;
|
|
59
|
+
await executor
|
|
60
|
+
.update(workflowRun)
|
|
61
|
+
.set({ principalId: row.principalId, status: "running" })
|
|
62
|
+
.where(and(eq(workflowRun.id, row.id), isNull(workflowRun.principalId), eq(workflowRun.status, "deployed")));
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* Atomically settle a live run into a terminal state. The live-status guard
|
|
66
|
+
* (`status IN ('deployed','running')`) makes the flip single-shot: the first
|
|
67
|
+
* caller stamps the terminal status and `endedAt` and gets the row back; any
|
|
68
|
+
* later caller matches no row and receives null, so the run is not
|
|
69
|
+
* re-terminated and its `endedAt` is not overwritten. Accepting "deployed"
|
|
70
|
+
* settles a deployment torn down before its first trigger. This is a safety
|
|
71
|
+
* property, not a recovery path -- it makes a second call (a manual replay
|
|
72
|
+
* against an already-settled run) a harmless no-op; it does not by itself
|
|
73
|
+
* re-drive a flip that failed. Returns the parsed row only on the winning
|
|
74
|
+
* flip.
|
|
75
|
+
*/
|
|
76
|
+
async markTerminal(runId, status, endedAt, tx) {
|
|
77
|
+
const [updated] = await (tx ?? db)
|
|
78
|
+
.update(workflowRun)
|
|
79
|
+
.set({ status, endedAt })
|
|
80
|
+
.where(and(eq(workflowRun.id, runId), inArray(workflowRun.status, [...liveWorkflowRunStatuses])))
|
|
81
|
+
.returning();
|
|
82
|
+
return updated === undefined ? null : parseWorkflowRunRow(updated);
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
-- Backfill `credential:{id}` / `use` grants for the owner of every existing
|
|
2
|
+
-- personal credential (rows where `principal_id` is set) that does not already
|
|
3
|
+
-- have one. This keeps existing personal-credential owners working once
|
|
4
|
+
-- launch enforcement fails closed. Organizational credentials
|
|
5
|
+
-- (`principal_id` IS NULL) are intentionally excluded: they remain gated
|
|
6
|
+
-- behind tenant-owner role inheritance and explicit administrative grants.
|
|
7
|
+
--
|
|
8
|
+
-- Idempotent: the `WHERE NOT EXISTS` guard skips any credential whose owner
|
|
9
|
+
-- already holds a matching grant, so re-application inserts nothing and does
|
|
10
|
+
-- not fail. Grant ids reproduce the app convention (`grt_` prefix followed by
|
|
11
|
+
-- 32 hex characters) via `gen_random_uuid()`.
|
|
12
|
+
INSERT INTO "grant" (
|
|
13
|
+
"id",
|
|
14
|
+
"tenant_id",
|
|
15
|
+
"principal_id",
|
|
16
|
+
"resource",
|
|
17
|
+
"action",
|
|
18
|
+
"effect",
|
|
19
|
+
"origin",
|
|
20
|
+
"expires_at"
|
|
21
|
+
)
|
|
22
|
+
SELECT
|
|
23
|
+
'grt_' || replace(gen_random_uuid()::text, '-', ''),
|
|
24
|
+
c."tenant_id",
|
|
25
|
+
c."principal_id",
|
|
26
|
+
'credential:' || c."id",
|
|
27
|
+
'use',
|
|
28
|
+
'allow',
|
|
29
|
+
'creator',
|
|
30
|
+
NULL
|
|
31
|
+
FROM "credential" c
|
|
32
|
+
WHERE c."principal_id" IS NOT NULL
|
|
33
|
+
AND NOT EXISTS (
|
|
34
|
+
SELECT 1
|
|
35
|
+
FROM "grant" g
|
|
36
|
+
WHERE g."principal_id" = c."principal_id"
|
|
37
|
+
AND g."resource" = 'credential:' || c."id"
|
|
38
|
+
AND g."action" = 'use'
|
|
39
|
+
);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
CREATE TABLE "approval" (
|
|
2
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
3
|
+
"tenant_id" text NOT NULL,
|
|
4
|
+
"instance_id" text NOT NULL,
|
|
5
|
+
"agent_id" text NOT NULL,
|
|
6
|
+
"origin_principal_id" text NOT NULL,
|
|
7
|
+
"correlation_id" text NOT NULL,
|
|
8
|
+
"tool_definition" jsonb NOT NULL,
|
|
9
|
+
"tool_arguments" jsonb NOT NULL,
|
|
10
|
+
"scope" text,
|
|
11
|
+
"status" text DEFAULT 'pending' NOT NULL,
|
|
12
|
+
"origin_kind" text NOT NULL,
|
|
13
|
+
"timeout_at" timestamp NOT NULL,
|
|
14
|
+
"resolved_at" timestamp,
|
|
15
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
16
|
+
"updated_at" timestamp DEFAULT now() NOT NULL,
|
|
17
|
+
CONSTRAINT "approval_correlation_id_unique" UNIQUE("correlation_id")
|
|
18
|
+
);
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
CREATE TABLE "signal_correlation" (
|
|
21
|
+
"correlation_id" text PRIMARY KEY NOT NULL,
|
|
22
|
+
"tenant_id" text NOT NULL,
|
|
23
|
+
"deployment_id" text NOT NULL,
|
|
24
|
+
"agent_address" text NOT NULL,
|
|
25
|
+
"run_id" text NOT NULL,
|
|
26
|
+
"signal_name" text NOT NULL,
|
|
27
|
+
"kind" text NOT NULL,
|
|
28
|
+
"signal_id" text,
|
|
29
|
+
"resolved_at" timestamp,
|
|
30
|
+
"created_at" timestamp DEFAULT now() NOT NULL
|
|
31
|
+
);
|
|
32
|
+
--> statement-breakpoint
|
|
33
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_tenant_id_tenant_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenant"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
34
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_instance_id_agent_instance_id_fk" FOREIGN KEY ("instance_id") REFERENCES "public"."agent_instance"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
35
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_agent_id_agent_id_fk" FOREIGN KEY ("agent_id") REFERENCES "public"."agent"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
36
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_origin_principal_id_principal_id_fk" FOREIGN KEY ("origin_principal_id") REFERENCES "public"."principal"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
37
|
+
ALTER TABLE "signal_correlation" ADD CONSTRAINT "signal_correlation_tenant_id_tenant_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenant"("id") ON DELETE cascade ON UPDATE no action;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- Reshape `approval` so its origin is the workflow deployment it came from.
|
|
2
|
+
-- The dropped instance/agent/origin-principal FKs had no valid referent: a
|
|
3
|
+
-- workflow deployment has no agent_instance/agent row and its run principal is
|
|
4
|
+
-- a substrate principal, not a `principal`-table row. The three added columns
|
|
5
|
+
-- are NOT NULL with no default and no backfill; like the repo's other such
|
|
6
|
+
-- adds (e.g. 0014, `workflow_deployment.address`), this relies on the table
|
|
7
|
+
-- being empty when the migration runs. The table is unreleased -- the approval
|
|
8
|
+
-- routes are 501 stubs -- so no populated row predates these columns.
|
|
9
|
+
ALTER TABLE "approval" DROP CONSTRAINT "approval_instance_id_agent_instance_id_fk";
|
|
10
|
+
--> statement-breakpoint
|
|
11
|
+
ALTER TABLE "approval" DROP CONSTRAINT "approval_agent_id_agent_id_fk";
|
|
12
|
+
--> statement-breakpoint
|
|
13
|
+
ALTER TABLE "approval" DROP CONSTRAINT "approval_origin_principal_id_principal_id_fk";
|
|
14
|
+
--> statement-breakpoint
|
|
15
|
+
ALTER TABLE "approval" ADD COLUMN "deployment_id" text NOT NULL;--> statement-breakpoint
|
|
16
|
+
ALTER TABLE "approval" ADD COLUMN "run_id" text NOT NULL;--> statement-breakpoint
|
|
17
|
+
ALTER TABLE "approval" ADD COLUMN "agent_address" text NOT NULL;--> statement-breakpoint
|
|
18
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_deployment_id_workflow_deployment_id_fk" FOREIGN KEY ("deployment_id") REFERENCES "public"."workflow_deployment"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
19
|
+
CREATE INDEX "approval_tenant_status_idx" ON "approval" USING btree ("tenant_id","status","created_at");--> statement-breakpoint
|
|
20
|
+
CREATE INDEX "approval_deployment_idx" ON "approval" USING btree ("deployment_id");--> statement-breakpoint
|
|
21
|
+
ALTER TABLE "approval" DROP COLUMN "instance_id";--> statement-breakpoint
|
|
22
|
+
ALTER TABLE "approval" DROP COLUMN "agent_id";--> statement-breakpoint
|
|
23
|
+
ALTER TABLE "approval" DROP COLUMN "origin_principal_id";--> statement-breakpoint
|
|
24
|
+
ALTER TABLE "approval" DROP COLUMN "origin_kind";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "approval" ALTER COLUMN "timeout_at" DROP NOT NULL;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "signal_correlation" ADD CONSTRAINT "signal_correlation_deployment_id_workflow_deployment_id_fk" FOREIGN KEY ("deployment_id") REFERENCES "public"."workflow_deployment"("id") ON DELETE cascade ON UPDATE no action;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "model_offering" ADD COLUMN "quirks" jsonb;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
CREATE TABLE "workflow_run" (
|
|
2
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
3
|
+
"deployment_id" text NOT NULL,
|
|
4
|
+
"tenant_id" text NOT NULL,
|
|
5
|
+
"principal_id" text,
|
|
6
|
+
"status" text DEFAULT 'running' NOT NULL,
|
|
7
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
8
|
+
"ended_at" timestamp
|
|
9
|
+
);
|
|
10
|
+
--> statement-breakpoint
|
|
11
|
+
ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_deployment_id_workflow_deployment_id_fk" FOREIGN KEY ("deployment_id") REFERENCES "public"."workflow_deployment"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
12
|
+
ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_tenant_id_tenant_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenant"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
13
|
+
ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_principal_id_principal_id_fk" FOREIGN KEY ("principal_id") REFERENCES "public"."principal"("id") ON DELETE set null ON UPDATE no action;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_run_id_workflow_run_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "signal_correlation" ADD CONSTRAINT "signal_correlation_run_id_workflow_run_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
CREATE TABLE "workflow_definition" (
|
|
2
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
3
|
+
"tenant_id" text NOT NULL,
|
|
4
|
+
"creator_principal_id" text,
|
|
5
|
+
"asset_id" text,
|
|
6
|
+
"name" text NOT NULL,
|
|
7
|
+
"description" text,
|
|
8
|
+
"grant_requirements" jsonb,
|
|
9
|
+
"current_version" text DEFAULT '1' NOT NULL,
|
|
10
|
+
"status" text DEFAULT 'deployed' NOT NULL,
|
|
11
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
12
|
+
"updated_at" timestamp DEFAULT now() NOT NULL
|
|
13
|
+
);
|
|
14
|
+
--> statement-breakpoint
|
|
15
|
+
CREATE TABLE "workflow_definition_version" (
|
|
16
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
17
|
+
"definition_id" text NOT NULL,
|
|
18
|
+
"version" text NOT NULL,
|
|
19
|
+
"status" text DEFAULT 'active' NOT NULL,
|
|
20
|
+
"created_at" timestamp DEFAULT now() NOT NULL,
|
|
21
|
+
CONSTRAINT "workflow_definition_version_definition_version" UNIQUE("definition_id","version")
|
|
22
|
+
);
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
ALTER TABLE "workflow_definition" ADD CONSTRAINT "workflow_definition_tenant_id_tenant_id_fk" FOREIGN KEY ("tenant_id") REFERENCES "public"."tenant"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
25
|
+
ALTER TABLE "workflow_definition" ADD CONSTRAINT "workflow_definition_creator_principal_id_principal_id_fk" FOREIGN KEY ("creator_principal_id") REFERENCES "public"."principal"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
|
|
26
|
+
ALTER TABLE "workflow_definition" ADD CONSTRAINT "workflow_definition_asset_id_asset_id_fk" FOREIGN KEY ("asset_id") REFERENCES "public"."asset"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
|
27
|
+
ALTER TABLE "workflow_definition_version" ADD CONSTRAINT "workflow_definition_version_definition_id_workflow_definition_id_fk" FOREIGN KEY ("definition_id") REFERENCES "public"."workflow_definition"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
28
|
+
CREATE INDEX "workflow_definition_tenant_idx" ON "workflow_definition" USING btree ("tenant_id","created_at");--> statement-breakpoint
|
|
29
|
+
CREATE UNIQUE INDEX "workflow_definition_asset_idx" ON "workflow_definition" USING btree ("asset_id");--> statement-breakpoint
|
|
30
|
+
CREATE INDEX "workflow_definition_version_definition_idx" ON "workflow_definition_version" USING btree ("definition_id");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
ALTER TABLE "workflow_run" ALTER COLUMN "deployment_id" DROP NOT NULL;--> statement-breakpoint
|
|
2
|
+
ALTER TABLE "workflow_run" ADD COLUMN "definition_id" text;--> statement-breakpoint
|
|
3
|
+
ALTER TABLE "workflow_run" ADD COLUMN "address" text;--> statement-breakpoint
|
|
4
|
+
ALTER TABLE "workflow_run" ADD COLUMN "public_key" text;--> statement-breakpoint
|
|
5
|
+
ALTER TABLE "workflow_run" ADD COLUMN "sidecar_id" text;--> statement-breakpoint
|
|
6
|
+
ALTER TABLE "workflow_run" ADD COLUMN "kernel_id" text;--> statement-breakpoint
|
|
7
|
+
ALTER TABLE "workflow_run" ADD COLUMN "model_preferences" jsonb;--> statement-breakpoint
|
|
8
|
+
ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_definition_id_workflow_definition_id_fk" FOREIGN KEY ("definition_id") REFERENCES "public"."workflow_definition"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
9
|
+
ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_sidecar_id_sidecar_id_fk" FOREIGN KEY ("sidecar_id") REFERENCES "public"."sidecar"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
|
10
|
+
CREATE INDEX "workflow_run_definition_idx" ON "workflow_run" USING btree ("definition_id");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CREATE UNIQUE INDEX "workflow_run_address_idx" ON "workflow_run" USING btree ("address") WHERE "workflow_run"."address" is not null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "inference_turn" DROP CONSTRAINT "inference_turn_instance_id_agent_instance_id_fk";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CREATE INDEX "session_mail_session_id_created_at_idx" ON "session_mail" USING btree ("session_id","created_at");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Re-key run-scoped grants onto the folded workflow-run resource. A folded run
|
|
2
|
+
-- shares the instance id space, so the rewrite is prefix-identity: the id after
|
|
3
|
+
-- the colon is unchanged, only the type name moves instance: -> workflow-run:
|
|
4
|
+
-- (carrying instance:* -> workflow-run:* too). The match is colon-delimited so
|
|
5
|
+
-- it never touches the unrelated agent-state: grants; there is no instance-state
|
|
6
|
+
-- sibling. Idempotent: after this runs no row matches instance:%, so a re-run is
|
|
7
|
+
-- a no-op.
|
|
8
|
+
UPDATE "grant"
|
|
9
|
+
SET resource = 'workflow-run:' || substr(resource, length('instance:') + 1)
|
|
10
|
+
WHERE resource LIKE 'instance:%';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
-- Reconstruct an anchor workflow_run for every deployment that predates the
|
|
2
|
+
-- runtime anchor insert. A deployment's routing address and reconnect key now
|
|
3
|
+
-- live on its anchor run (the workflow_run whose id equals the deployment id),
|
|
4
|
+
-- which new deploys create at runtime -- but deployments created earlier have a
|
|
5
|
+
-- workflow_deployment row and no anchor run, so the reconnect key lookup finds
|
|
6
|
+
-- no run for their address and their reconnect challenge fails closed. This
|
|
7
|
+
-- copies the deployment's identity onto a fresh anchor run so those deployments
|
|
8
|
+
-- reconnect exactly as ones deployed after the runtime anchor insert do.
|
|
9
|
+
--
|
|
10
|
+
-- A runtime-created anchor run also carries its definition -- deploy resolves
|
|
11
|
+
-- and writes definition_id -- so a reconstructed one must too; an anchor run
|
|
12
|
+
-- without a definition is only half the deployment's first-class stand-in. A
|
|
13
|
+
-- definition_id resolves from the deployment's asset, which the workflow-asset
|
|
14
|
+
-- fold populates. The guard below aborts the migration before it writes
|
|
15
|
+
-- anything if any deployment still needing an anchor run has no folded
|
|
16
|
+
-- definition, so the backfill reconstructs every anchor run completely or
|
|
17
|
+
-- writes nothing and tells the operator to run the fold first. The production
|
|
18
|
+
-- path applies migrations under `drizzle-kit migrate`, which wraps the pending
|
|
19
|
+
-- set in a transaction, and PostgreSQL DDL is transactional, so an aborting
|
|
20
|
+
-- guard rolls the whole set back -- there is no partial commit to re-run from
|
|
21
|
+
-- the top, so the guard is simply a clear up-front precondition.
|
|
22
|
+
DO $$
|
|
23
|
+
BEGIN
|
|
24
|
+
IF EXISTS (
|
|
25
|
+
SELECT 1
|
|
26
|
+
FROM "workflow_deployment" wd
|
|
27
|
+
WHERE NOT EXISTS (
|
|
28
|
+
SELECT 1 FROM "workflow_run" r WHERE r.id = wd.id
|
|
29
|
+
)
|
|
30
|
+
AND NOT EXISTS (
|
|
31
|
+
SELECT 1 FROM "workflow_definition" wdef
|
|
32
|
+
WHERE wdef.asset_id = wd.definition_asset_id
|
|
33
|
+
)
|
|
34
|
+
) THEN
|
|
35
|
+
RAISE EXCEPTION 'workflow-asset fold has not run: a deployment lacks a folded definition and its anchor run would be definition-less. The fold tooling has been retired; create the missing workflow_definition for the deployment asset by hand before applying this migration (see the agent-fold migration note in DEV.md).';
|
|
36
|
+
END IF;
|
|
37
|
+
END $$;
|
|
38
|
+
--> statement-breakpoint
|
|
39
|
+
-- public_key is copied from the deployment (its old deploy-ack key) so the
|
|
40
|
+
-- reconnect challenge resolves the same key it did before; created_at is copied
|
|
41
|
+
-- so listing order is stable; status is the anchor's live value; definition_id
|
|
42
|
+
-- resolves through the folded definition the guard above proved present. The
|
|
43
|
+
-- remaining columns match a runtime anchor insert: no principal, no runtime
|
|
44
|
+
-- bindings, not ended. NOT EXISTS on the id keeps it idempotent and skips
|
|
45
|
+
-- deployments that already have a runtime-created anchor run.
|
|
46
|
+
INSERT INTO "workflow_run" (
|
|
47
|
+
id,
|
|
48
|
+
tenant_id,
|
|
49
|
+
deployment_id,
|
|
50
|
+
definition_id,
|
|
51
|
+
address,
|
|
52
|
+
public_key,
|
|
53
|
+
status,
|
|
54
|
+
created_at
|
|
55
|
+
)
|
|
56
|
+
SELECT
|
|
57
|
+
wd.id,
|
|
58
|
+
wd.tenant_id,
|
|
59
|
+
wd.id,
|
|
60
|
+
wdef.id,
|
|
61
|
+
wd.address,
|
|
62
|
+
wd.public_key,
|
|
63
|
+
'running',
|
|
64
|
+
wd.created_at
|
|
65
|
+
FROM "workflow_deployment" wd
|
|
66
|
+
LEFT JOIN "workflow_definition" wdef ON wdef.asset_id = wd.definition_asset_id
|
|
67
|
+
WHERE NOT EXISTS (
|
|
68
|
+
SELECT 1 FROM "workflow_run" r WHERE r.id = wd.id
|
|
69
|
+
);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
-- Re-point the three deployment_id foreign keys from the workflow_deployment
|
|
2
|
+
-- projection onto the anchor run -- the workflow_run whose id equals the
|
|
3
|
+
-- deployment id -- leaving the projection unreferenced. Every deployment_id
|
|
4
|
+
-- value already equals an anchor run's id (migration 0055 backfilled one per
|
|
5
|
+
-- deployment), so each re-pointed constraint validates on add; a deployment
|
|
6
|
+
-- that somehow lacks its anchor run makes the ADD CONSTRAINT abort, a free
|
|
7
|
+
-- integrity check.
|
|
8
|
+
--
|
|
9
|
+
-- First, fill definition_id on the runs the projection still anchors, so every
|
|
10
|
+
-- run carries its definition -- the run anchors on the definition, not the
|
|
11
|
+
-- deployment. A pre-existing non-anchor run -- a folded or child run created
|
|
12
|
+
-- before this branch added the column -- has a null definition_id that only the
|
|
13
|
+
-- deployment -> asset -> definition join can resolve; migration 0055 fills the
|
|
14
|
+
-- anchor runs it inserts but never touches these existing rows, and
|
|
15
|
+
-- workflow_deployment is the only place their mapping survives. asset_id is
|
|
16
|
+
-- unique per definition, so the join matches at most one definition per run.
|
|
17
|
+
UPDATE "workflow_run" r
|
|
18
|
+
SET definition_id = wdef.id
|
|
19
|
+
FROM "workflow_deployment" wd
|
|
20
|
+
JOIN "workflow_definition" wdef ON wdef.asset_id = wd.definition_asset_id
|
|
21
|
+
WHERE r.deployment_id = wd.id
|
|
22
|
+
AND r.definition_id IS NULL;
|
|
23
|
+
--> statement-breakpoint
|
|
24
|
+
ALTER TABLE "approval" DROP CONSTRAINT "approval_deployment_id_workflow_deployment_id_fk";
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
ALTER TABLE "signal_correlation" DROP CONSTRAINT "signal_correlation_deployment_id_workflow_deployment_id_fk";
|
|
27
|
+
--> statement-breakpoint
|
|
28
|
+
ALTER TABLE "workflow_run" DROP CONSTRAINT "workflow_run_deployment_id_workflow_deployment_id_fk";
|
|
29
|
+
--> statement-breakpoint
|
|
30
|
+
ALTER TABLE "approval" ADD CONSTRAINT "approval_deployment_id_workflow_run_id_fk" FOREIGN KEY ("deployment_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
31
|
+
ALTER TABLE "signal_correlation" ADD CONSTRAINT "signal_correlation_deployment_id_workflow_run_id_fk" FOREIGN KEY ("deployment_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
|
32
|
+
ALTER TABLE "workflow_run" ADD CONSTRAINT "workflow_run_deployment_id_workflow_run_id_fk" FOREIGN KEY ("deployment_id") REFERENCES "public"."workflow_run"("id") ON DELETE cascade ON UPDATE no action;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-- Drop the workflow_deployment projection. Its routing identity, reconnect key,
|
|
2
|
+
-- and status now live on the anchor run, its foreign keys were re-pointed onto
|
|
3
|
+
-- the anchor run, and nothing reads or writes it. This is irreversible.
|
|
4
|
+
--
|
|
5
|
+
-- Promote workflow_run.definition_id to NOT NULL: every run now carries a
|
|
6
|
+
-- definition (set at birth for new runs, filled by 0056 for the rows the
|
|
7
|
+
-- projection anchored). The guard below aborts before writing anything if any
|
|
8
|
+
-- run is still null -- that means the workflow-asset fold has not run, and
|
|
9
|
+
-- dropping the projection would strand those rows with no way to resolve their
|
|
10
|
+
-- definition. A blunt IS NULL check catches every class, including a run with a
|
|
11
|
+
-- null deployment_id the deployment join could never reach. Abort loudly so the
|
|
12
|
+
-- operator runs the fold and retries.
|
|
13
|
+
DO $$
|
|
14
|
+
BEGIN
|
|
15
|
+
IF EXISTS (SELECT 1 FROM "workflow_run" WHERE definition_id IS NULL) THEN
|
|
16
|
+
RAISE EXCEPTION 'workflow_run rows without a definition remain; run the workflow-asset fold (bin/db-backfill) before applying this migration';
|
|
17
|
+
END IF;
|
|
18
|
+
END $$;
|
|
19
|
+
--> statement-breakpoint
|
|
20
|
+
ALTER TABLE "workflow_run" ALTER COLUMN "definition_id" SET NOT NULL;
|
|
21
|
+
--> statement-breakpoint
|
|
22
|
+
DROP TABLE "workflow_deployment";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
-- Re-point the offering foreign key off the agent onto the folded workflow
|
|
2
|
+
-- definition. The column keeps its agent_id name -- the offering API exposes
|
|
3
|
+
-- agentId -- but its values become workflow_definition ids: every agent was
|
|
4
|
+
-- folded to exactly one definition, linked by workflow_definition.origin_agent_id
|
|
5
|
+
-- (a partial unique index, so the join matches at most one definition).
|
|
6
|
+
--
|
|
7
|
+
-- The guard runs before any write. The production path applies migrations under
|
|
8
|
+
-- `drizzle-kit migrate`, which wraps the pending set in a transaction, and
|
|
9
|
+
-- PostgreSQL DDL is transactional, so an aborting guard rolls the whole set
|
|
10
|
+
-- back -- there is no partial commit to defend against. It aborts loudly if any
|
|
11
|
+
-- offering's agent has no folded definition, meaning the agent fold has not
|
|
12
|
+
-- run; the total fold makes that impossible in a folded database, so the guard
|
|
13
|
+
-- is a fail-loud assertion.
|
|
14
|
+
DO $$
|
|
15
|
+
BEGIN
|
|
16
|
+
IF EXISTS (
|
|
17
|
+
SELECT 1
|
|
18
|
+
FROM "offering" o
|
|
19
|
+
WHERE NOT EXISTS (
|
|
20
|
+
SELECT 1 FROM "workflow_definition" wd
|
|
21
|
+
WHERE wd.origin_agent_id = o.agent_id
|
|
22
|
+
)
|
|
23
|
+
) THEN
|
|
24
|
+
RAISE EXCEPTION 'offering(s) reference an agent with no folded definition; run the agent fold (bin/db-backfill) before applying this migration';
|
|
25
|
+
END IF;
|
|
26
|
+
END $$;
|
|
27
|
+
--> statement-breakpoint
|
|
28
|
+
-- Drop the old agent foreign key BEFORE rewriting the values: the rewrite sets
|
|
29
|
+
-- agent_id to a workflow_definition id, which is not an agent id, so it would
|
|
30
|
+
-- violate the still-active agent FK. The offering table was renamed from
|
|
31
|
+
-- `capability` (migration 0004); Postgres does not rename constraints on a
|
|
32
|
+
-- table rename, so its agent FK still carries the original `capability_`-
|
|
33
|
+
-- prefixed name, not the `offering_`-prefixed name drizzle's snapshot infers.
|
|
34
|
+
ALTER TABLE "offering" DROP CONSTRAINT "capability_agent_id_agent_id_fk";
|
|
35
|
+
--> statement-breakpoint
|
|
36
|
+
UPDATE "offering" o
|
|
37
|
+
SET agent_id = wd.id
|
|
38
|
+
FROM "workflow_definition" wd
|
|
39
|
+
WHERE wd.origin_agent_id = o.agent_id;
|
|
40
|
+
--> statement-breakpoint
|
|
41
|
+
ALTER TABLE "offering" ADD CONSTRAINT "offering_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,10 @@
|
|
|
1
|
+
-- Re-point the transaction ledger off the agent onto the run that incurs a
|
|
2
|
+
-- charge. The table is unwritten (no producer), so there is no data to migrate
|
|
3
|
+
-- and no contract to preserve: rename agent_id to run_id and reference
|
|
4
|
+
-- workflow_run, keeping the nullable set-null delete so ledger history survives
|
|
5
|
+
-- the deletion of the run it references.
|
|
6
|
+
ALTER TABLE "transaction" RENAME COLUMN "agent_id" TO "run_id";
|
|
7
|
+
--> statement-breakpoint
|
|
8
|
+
ALTER TABLE "transaction" DROP CONSTRAINT "transaction_agent_id_agent_id_fk";
|
|
9
|
+
--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "transaction" ADD CONSTRAINT "transaction_run_id_workflow_run_id_fk" FOREIGN KEY ("run_id") REFERENCES "public"."workflow_run"("id") ON DELETE set null ON UPDATE no action;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
-- Drop session_mail's foreign key to agent_instance. instance_id becomes a
|
|
2
|
+
-- bare polymorphic column -- a legacy agent_instance id, or null for a folded
|
|
3
|
+
-- run -- mirroring inference_turn.instance_id (migration 0052). A folded run's
|
|
4
|
+
-- id comes from a shared id space that agent_instance does not contain, so no
|
|
5
|
+
-- single-table foreign key spans both.
|
|
6
|
+
ALTER TABLE "session_mail" DROP CONSTRAINT "session_mail_instance_id_agent_instance_id_fk";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
-- Drop session_asset's foreign key to agent_instance. instance_id becomes a
|
|
2
|
+
-- bare polymorphic column -- a legacy agent_instance id or a folded run id --
|
|
3
|
+
-- mirroring inference_turn.instance_id (migration 0052). A folded launch
|
|
4
|
+
-- already writes its workflow_run id here, which the agent_instance FK rejected,
|
|
5
|
+
-- so this also unblocks attaching assets to a folded run. instance_id stays NOT
|
|
6
|
+
-- NULL and part of the (instance_id, mount_path) primary key.
|
|
7
|
+
ALTER TABLE "session_asset" DROP CONSTRAINT "session_asset_instance_id_agent_instance_id_fk";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Drop the agent_asset table. Manual attach-to-an-agent was never wired,
|
|
2
|
+
-- so the table has no writer and is empty, and the launch-time direct
|
|
3
|
+
-- attachment path that read it is gone. session_asset's agent_asset_id
|
|
4
|
+
-- foreign key and its source column only distinguished direct attachments
|
|
5
|
+
-- from resolver-derived materializations; with the direct path gone every
|
|
6
|
+
-- row is resolver-derived, so both are dead. Drop the two columns first --
|
|
7
|
+
-- dropping agent_asset_id takes its foreign key with it -- so the table
|
|
8
|
+
-- has no remaining dependents when it goes (no CASCADE needed).
|
|
9
|
+
ALTER TABLE "session_asset" DROP COLUMN "agent_asset_id";--> statement-breakpoint
|
|
10
|
+
ALTER TABLE "session_asset" DROP COLUMN "source";--> statement-breakpoint
|
|
11
|
+
DROP TABLE "agent_asset";
|