@sixb/pg 0.1.1 → 0.1.3

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 (112) hide show
  1. package/README.md +7 -6
  2. package/dist/agents/agent-storage.d.ts +7 -4
  3. package/dist/agents/agent-storage.d.ts.map +1 -1
  4. package/dist/agents/checkpoints.d.ts +12 -0
  5. package/dist/agents/checkpoints.d.ts.map +1 -0
  6. package/dist/agents/index.d.ts +1 -0
  7. package/dist/agents/index.d.ts.map +1 -1
  8. package/dist/agents/messages.d.ts +2 -1
  9. package/dist/agents/messages.d.ts.map +1 -1
  10. package/dist/agents/rows.d.ts +22 -12
  11. package/dist/agents/rows.d.ts.map +1 -1
  12. package/dist/agents/runs.d.ts +3 -2
  13. package/dist/agents/runs.d.ts.map +1 -1
  14. package/dist/auth-storage/service-accounts.d.ts.map +1 -1
  15. package/dist/auth-storage/shared.d.ts +0 -4
  16. package/dist/auth-storage/shared.d.ts.map +1 -1
  17. package/dist/connector-connection-storage.d.ts +9 -0
  18. package/dist/connector-connection-storage.d.ts.map +1 -0
  19. package/dist/index.d.ts +9 -5
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +5010 -1837
  22. package/dist/index.js.map +31 -26
  23. package/dist/latest-run-query.d.ts.map +1 -1
  24. package/dist/migrations.d.ts.map +1 -1
  25. package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
  26. package/dist/ontology-storage/materialization-state.d.ts +0 -2
  27. package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
  28. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
  29. package/dist/ontology-storage/materializations.d.ts.map +1 -1
  30. package/dist/ontology-storage/outbox.d.ts.map +1 -1
  31. package/dist/ontology-storage/shared.d.ts +3 -6
  32. package/dist/ontology-storage/shared.d.ts.map +1 -1
  33. package/dist/pg-action-run-storage.d.ts +3 -2
  34. package/dist/pg-action-run-storage.d.ts.map +1 -1
  35. package/dist/pg-ai-cost-storage.d.ts +12 -0
  36. package/dist/pg-ai-cost-storage.d.ts.map +1 -0
  37. package/dist/pg-ai-usage-storage.d.ts +16 -0
  38. package/dist/pg-ai-usage-storage.d.ts.map +1 -0
  39. package/dist/pg-execution-storage.d.ts +14 -0
  40. package/dist/pg-execution-storage.d.ts.map +1 -0
  41. package/dist/pg-pipeline-run-storage.d.ts +5 -2
  42. package/dist/pg-pipeline-run-storage.d.ts.map +1 -1
  43. package/dist/pg-projection-run-storage.d.ts +5 -2
  44. package/dist/pg-projection-run-storage.d.ts.map +1 -1
  45. package/dist/pg-sync-run-storage.d.ts +5 -2
  46. package/dist/pg-sync-run-storage.d.ts.map +1 -1
  47. package/dist/pg-webhook-run-storage.d.ts +5 -2
  48. package/dist/pg-webhook-run-storage.d.ts.map +1 -1
  49. package/dist/pg-workflow-run-storage.d.ts +5 -3
  50. package/dist/pg-workflow-run-storage.d.ts.map +1 -1
  51. package/dist/run-list-query.d.ts +1 -1
  52. package/dist/run-list-query.d.ts.map +1 -1
  53. package/dist/testing.d.ts +6 -0
  54. package/dist/testing.d.ts.map +1 -0
  55. package/package.json +3 -3
  56. package/src/agents/agent-storage.ts +9 -5
  57. package/src/agents/checkpoints.ts +175 -0
  58. package/src/agents/index.ts +1 -0
  59. package/src/agents/messages.ts +71 -13
  60. package/src/agents/rows.ts +57 -43
  61. package/src/agents/runs.ts +29 -15
  62. package/src/auth-storage/service-accounts.ts +14 -15
  63. package/src/auth-storage/shared.ts +0 -8
  64. package/src/connector-connection-storage.ts +760 -0
  65. package/src/index.ts +38 -15
  66. package/src/latest-run-query.ts +7 -1
  67. package/src/migrations/004-executions.sql +140 -0
  68. package/src/migrations/005-workflow-executions.sql +10 -0
  69. package/src/migrations/006-narrow-ontology-source-root-index.sql +4 -0
  70. package/src/migrations/007-split-overrides.sql +153 -0
  71. package/src/migrations/008-action-executions.sql +7 -0
  72. package/src/migrations/009-agent-executions.sql +21 -0
  73. package/src/migrations/010-ai-usage-accounting-foundation.sql +76 -0
  74. package/src/migrations/011-sync-failure-record.sql +23 -0
  75. package/src/migrations/012-pipeline-failure-record.sql +47 -0
  76. package/src/migrations/013-workflow-failure-record.sql +45 -0
  77. package/src/migrations/014-agent-failure-record.sql +56 -0
  78. package/src/migrations/015-projection-failure-record.sql +20 -0
  79. package/src/migrations/016-webhook-run-failure-record.sql +19 -0
  80. package/src/migrations/017-action-failure-record.sql +65 -0
  81. package/src/migrations/018-ontology-outbox-failure-record.sql +29 -0
  82. package/src/migrations/019-webhook-delivery-failure-record.sql +27 -0
  83. package/src/migrations/020-drop-run-usage-projections.sql +8 -0
  84. package/src/migrations/021-sync-pipeline-executions.sql +50 -0
  85. package/src/migrations/022-projection-executions.sql +115 -0
  86. package/src/migrations/023-webhook-executions.sql +30 -0
  87. package/src/migrations/024-ontology-commit-executions.sql +12 -0
  88. package/src/migrations/025-connector-connections.sql +231 -0
  89. package/src/migrations/026-ai-cost-accounting.sql +53 -0
  90. package/src/migrations/027-agent-context-checkpoints.sql +34 -0
  91. package/src/migrations/028-object-override-edit-times.sql +3 -0
  92. package/src/migrations.ts +82 -0
  93. package/src/ontology-storage/materialization-session.ts +25 -28
  94. package/src/ontology-storage/materialization-state.ts +161 -43
  95. package/src/ontology-storage/materialization-writer.ts +149 -76
  96. package/src/ontology-storage/materializations.ts +3 -1
  97. package/src/ontology-storage/outbox.ts +9 -2
  98. package/src/ontology-storage/shared.ts +10 -20
  99. package/src/pg-action-run-storage.ts +43 -67
  100. package/src/pg-ai-cost-storage.ts +707 -0
  101. package/src/pg-ai-usage-storage.ts +290 -0
  102. package/src/pg-execution-storage.ts +147 -0
  103. package/src/pg-pipeline-run-storage.ts +107 -41
  104. package/src/pg-projection-run-storage.ts +159 -91
  105. package/src/pg-sync-run-storage.ts +100 -28
  106. package/src/pg-webhook-run-storage.ts +89 -57
  107. package/src/pg-workflow-run-storage.ts +97 -130
  108. package/src/run-list-query.ts +9 -4
  109. package/src/testing.ts +18 -0
  110. package/dist/pg-webhook-delivery-storage.d.ts +0 -17
  111. package/dist/pg-webhook-delivery-storage.d.ts.map +0 -1
  112. package/src/pg-webhook-delivery-storage.ts +0 -180
@@ -594,6 +594,7 @@ export class PgOntologyMaterializationStorage implements OntologyMaterialization
594
594
  payload->'ref'->>'linkId' AS link_id
595
595
  FROM ${this.sql(PG_MATERIALIZATION_WORK_TABLE)}
596
596
  WHERE session_id = ${session.id} AND kind = 'cardinality'
597
+ AND payload->>'view' = 'effective'
597
598
  ), duplicate AS (
598
599
  SELECT scope_sort_key FROM work WHERE occupied
599
600
  GROUP BY scope_sort_key HAVING COUNT(*) > 1
@@ -836,12 +837,13 @@ export class PgOntologyMaterializationStorage implements OntologyMaterialization
836
837
  const actor = commit.actor === undefined ? null : jsonParameter(this.sql, commit.actor)
837
838
  const rows = await this.sql<PgOntologyCommitRow[]>`
838
839
  INSERT INTO ontology_commits (
839
- project_id, id, idempotency_key, request_hash,
840
+ project_id, id, idempotency_key, request_hash, execution_id,
840
841
  origin_kind, origin_run_id, origin_batch_ordinal, origin, actor,
841
842
  ontology_revision, projection_revision, ownership_hash,
842
843
  intent, result, committed_at
843
844
  ) VALUES (
844
845
  ${commit.projectId}, ${commit.id}, ${commit.idempotencyKey}, ${commit.requestHash},
846
+ ${commit.executionId},
845
847
  ${origin.kind}, ${origin.runId}, ${origin.batchOrdinal},
846
848
  ${jsonParameter(this.sql, commit.origin)}, ${actor}, ${commit.ontologyRevision},
847
849
  ${commit.projectionRevision ?? null}, ${commit.ownershipHash ?? null},
@@ -1,3 +1,4 @@
1
+ import { serializeSixbFailure } from "@sixb/core/internal/errors"
1
2
  import {
2
3
  MaterializationConflictError,
3
4
  MaterializationValidationError,
@@ -12,6 +13,7 @@ import type {
12
13
  RescheduleOntologyOutboxLeaseInput,
13
14
  SummarizeOntologyOutboxInput,
14
15
  } from "@sixb/core/storage"
16
+ import { ONTOLOGY_OUTBOX_FAILURE_CODES } from "@sixb/core/storage"
15
17
  import {
16
18
  assertNonblank,
17
19
  assertPositiveInteger,
@@ -57,7 +59,7 @@ export class PgOntologyOutboxStorage implements OntologyOutboxStorage {
57
59
  WHERE outbox.project_id = candidates.project_id AND outbox.id = candidates.id
58
60
  RETURNING outbox.id AS row_id, outbox.envelope, outbox.available_at,
59
61
  outbox.attempts, outbox.lease_id, outbox.lease_expires_at,
60
- outbox.published_at, outbox.last_error, outbox.created_at,
62
+ outbox.published_at, outbox.last_failure, outbox.created_at,
61
63
  outbox.commit_id, outbox.commit_ordinal
62
64
  )
63
65
  SELECT * FROM claimed ORDER BY created_at, commit_id, commit_ordinal
@@ -109,6 +111,10 @@ export class PgOntologyOutboxStorage implements OntologyOutboxStorage {
109
111
  assertTimestamp(input.availableAt, "Ontology outbox availableAt")
110
112
  const ids = validateLeaseIds(input.ids)
111
113
  if (ids.length === 0) return
114
+ const failure =
115
+ input.failure === undefined
116
+ ? null
117
+ : serializeSixbFailure(input.failure, ONTOLOGY_OUTBOX_FAILURE_CODES)
112
118
  const rows = await sql<{ readonly id: string }[]>`
113
119
  WITH leased AS MATERIALIZED (
114
120
  SELECT id FROM ontology_outbox
@@ -122,7 +128,8 @@ export class PgOntologyOutboxStorage implements OntologyOutboxStorage {
122
128
  WHERE (SELECT COUNT(*) FROM leased) = ${ids.length}
123
129
  )
124
130
  UPDATE ontology_outbox AS outbox
125
- SET available_at = ${input.availableAt}, last_error = ${input.error},
131
+ SET available_at = ${input.availableAt},
132
+ last_failure = COALESCE(${failure}::text::jsonb, outbox.last_failure),
126
133
  lease_id = NULL, lease_expires_at = NULL
127
134
  FROM eligible
128
135
  WHERE outbox.project_id = ${input.projectId} AND outbox.id = eligible.id
@@ -1,3 +1,4 @@
1
+ import { parseSixbFailure } from "@sixb/core/internal/errors"
1
2
  import type { ProjectionEntityRef } from "@sixb/core/internal/materialization"
2
3
  import { MaterializationConflictError } from "@sixb/core/internal/materialization"
3
4
  import type {
@@ -8,6 +9,7 @@ import type {
8
9
  OntologySourceRecord,
9
10
  StageSourceAssertion,
10
11
  } from "@sixb/core/storage"
12
+ import { ONTOLOGY_OUTBOX_FAILURE_CODES } from "@sixb/core/storage"
11
13
  import type { SQLClient } from "../pg-client"
12
14
 
13
15
  export {
@@ -32,6 +34,7 @@ export interface PgOntologyCommitRow {
32
34
  readonly id: string
33
35
  readonly idempotency_key: string
34
36
  readonly request_hash: string
37
+ readonly execution_id: string
35
38
  readonly origin_kind: string
36
39
  readonly origin_run_id: string | null
37
40
  readonly origin_batch_ordinal: number | string | null
@@ -85,8 +88,7 @@ export interface PgOntologySourceAssertionRow {
85
88
  readonly assertion: unknown
86
89
  }
87
90
 
88
- export interface PgOntologyOverrideRow {
89
- readonly entity_kind: "object" | "link"
91
+ export interface PgStoredOverrideRow {
90
92
  readonly value: unknown
91
93
  readonly last_commit_id: string
92
94
  readonly updated_at: Date | string
@@ -99,7 +101,7 @@ export interface PgOntologyOutboxRow {
99
101
  readonly lease_id: string | null
100
102
  readonly lease_expires_at: Date | string | null
101
103
  readonly published_at: Date | string | null
102
- readonly last_error: string | null
104
+ readonly last_failure: unknown | null
103
105
  readonly created_at: Date | string
104
106
  }
105
107
 
@@ -107,13 +109,6 @@ export function jsonParameter(sql: SQLClient, value: unknown): ReturnType<SQLCli
107
109
  return sql.json(value as PgJsonValue)
108
110
  }
109
111
 
110
- export function jsonKeyParameter(
111
- sql: SQLClient,
112
- canonicalKey: string
113
- ): ReturnType<SQLClient["json"]> {
114
- return jsonParameter(sql, JSON.parse(canonicalKey))
115
- }
116
-
117
112
  export function toIsoString(value: Date | string): string {
118
113
  return value instanceof Date ? value.toISOString() : new Date(value).toISOString()
119
114
  }
@@ -180,6 +175,7 @@ export function commitRecord(row: PgOntologyCommitRow): OntologyCommitRecord {
180
175
  id: row.id,
181
176
  idempotencyKey: row.idempotency_key,
182
177
  requestHash: row.request_hash,
178
+ executionId: row.execution_id,
183
179
  origin: structuredClone(row.origin) as OntologyCommitWrite["origin"],
184
180
  ...(row.actor === null
185
181
  ? {}
@@ -204,7 +200,10 @@ export function outboxRecord(row: PgOntologyOutboxRow): OntologyOutboxRecord {
204
200
  leaseId: row.lease_id,
205
201
  leaseExpiresAt: optionalIsoString(row.lease_expires_at),
206
202
  publishedAt: optionalIsoString(row.published_at),
207
- lastError: row.last_error,
203
+ lastFailure:
204
+ row.last_failure === null
205
+ ? null
206
+ : parseSixbFailure(row.last_failure, ONTOLOGY_OUTBOX_FAILURE_CODES),
208
207
  createdAt: toIsoString(row.created_at),
209
208
  }
210
209
  }
@@ -279,15 +278,6 @@ export async function assertProjectionExecution(
279
278
  }
280
279
  }
281
280
 
282
- export function requireRow<T>(
283
- row: T | undefined,
284
- kind: ConstructorParameters<typeof MaterializationConflictError>[0],
285
- message: string
286
- ): T {
287
- if (!row) throw new MaterializationConflictError(kind, message)
288
- return row
289
- }
290
-
291
281
  export function ontologyLockKey(kind: string, ...parts: readonly string[]): string {
292
282
  return `ontology:${kind}:${JSON.stringify(parts)}`
293
283
  }
@@ -1,4 +1,9 @@
1
1
  import type { ActionSubject, JsonValue } from "@sixb/core"
2
+ import {
3
+ parseActionRunFailure,
4
+ serializeActionRunFailure,
5
+ } from "@sixb/core/internal/action-run-storage"
6
+ import { assertActionRunExecution } from "@sixb/core/internal/action-run-storage-provider"
2
7
  import type {
3
8
  ActionRunEffectsRecord,
4
9
  ActionRunFailure,
@@ -8,6 +13,7 @@ import type {
8
13
  ActionRunStorage,
9
14
  ActionRunWritebackRecord,
10
15
  EnterActionRunPhaseInput,
16
+ ExecutionStorage,
11
17
  FinishActionRunInput,
12
18
  ListActionRunsInput,
13
19
  ListActionRunsResult,
@@ -29,7 +35,10 @@ import { isUniqueViolation } from "./storage-errors"
29
35
  import { type PgStoreClient, runPgTransaction } from "./transactions"
30
36
 
31
37
  export class PgActionRunStorage implements ActionRunStorage {
32
- constructor(private readonly sql: PgStoreClient) {}
38
+ constructor(
39
+ private readonly sql: PgStoreClient,
40
+ private readonly executions: ExecutionStorage
41
+ ) {}
33
42
 
34
43
  async lockForMaterialization(input: LockActionMaterializationRunInput): Promise<ActionRunRecord> {
35
44
  const [row] = await this.sql<DatabaseRow[]>`
@@ -57,11 +66,20 @@ export class PgActionRunStorage implements ActionRunStorage {
57
66
  }
58
67
 
59
68
  async queue(input: QueueActionRunInput): Promise<ActionRunRecord> {
69
+ await assertActionRunExecution({
70
+ executions: this.executions,
71
+ projectId: input.projectId,
72
+ executionId: input.executionId,
73
+ runId: input.id,
74
+ actionId: input.actionId,
75
+ })
76
+
60
77
  try {
61
78
  const [row] = await this.sql<DatabaseRow[]>`
62
79
  INSERT INTO action_runs (
63
80
  project_id,
64
81
  id,
82
+ execution_id,
65
83
  action_id,
66
84
  subject_kind,
67
85
  object_type_id,
@@ -76,20 +94,15 @@ export class PgActionRunStorage implements ActionRunStorage {
76
94
  writeback_status,
77
95
  writeback_completed_at,
78
96
  writeback_result,
79
- writeback_error_name,
80
- writeback_error_message,
81
- writeback_error_phase,
97
+ writeback_error,
82
98
  effects_status,
83
99
  effects_completed_at,
84
- effects_error_name,
85
- effects_error_message,
86
- effects_error_phase,
87
- error_name,
88
- error_message,
89
- error_phase
100
+ effects_error,
101
+ error
90
102
  ) VALUES (
91
103
  ${input.projectId},
92
104
  ${input.id},
105
+ ${input.executionId},
93
106
  ${input.actionId},
94
107
  ${input.subject.kind},
95
108
  ${input.subject.kind === "object" ? input.subject.objectTypeId : null},
@@ -108,12 +121,6 @@ export class PgActionRunStorage implements ActionRunStorage {
108
121
  ${null},
109
122
  ${null},
110
123
  ${null},
111
- ${null},
112
- ${null},
113
- ${null},
114
- ${null},
115
- ${null},
116
- ${null},
117
124
  ${null}
118
125
  )
119
126
  RETURNING *
@@ -157,17 +164,11 @@ export class PgActionRunStorage implements ActionRunStorage {
157
164
  writeback_status = ${null},
158
165
  writeback_completed_at = ${null},
159
166
  writeback_result = ${null},
160
- writeback_error_name = ${null},
161
- writeback_error_message = ${null},
162
- writeback_error_phase = ${null},
167
+ writeback_error = ${null},
163
168
  effects_status = ${null},
164
169
  effects_completed_at = ${null},
165
- effects_error_name = ${null},
166
- effects_error_message = ${null},
167
- effects_error_phase = ${null},
168
- error_name = ${null},
169
- error_message = ${null},
170
- error_phase = ${null}
170
+ effects_error = ${null},
171
+ error = ${null}
171
172
  WHERE project_id = ${input.projectId} AND id = ${input.id}
172
173
  RETURNING *
173
174
  `
@@ -183,9 +184,7 @@ export class PgActionRunStorage implements ActionRunStorage {
183
184
  status = ${"running"},
184
185
  phase = ${input.phase ?? "validation"},
185
186
  started_at = ${input.startedAt ?? new Date()},
186
- error_name = ${null},
187
- error_message = ${null},
188
- error_phase = ${null}
187
+ error = ${null}
189
188
  WHERE project_id = ${input.projectId}
190
189
  AND id = ${input.id}
191
190
  AND status = ${"queued"}
@@ -251,9 +250,7 @@ export class PgActionRunStorage implements ActionRunStorage {
251
250
  writeback_status = ${input.status},
252
251
  writeback_completed_at = ${nextWriteback.completedAt},
253
252
  writeback_result = ${input.status === "succeeded" ? JSON.stringify(input.result) : null}::text::jsonb,
254
- writeback_error_name = ${input.status === "failed" ? (input.error.name ?? null) : null},
255
- writeback_error_message = ${input.status === "failed" ? input.error.message : null},
256
- writeback_error_phase = ${input.status === "failed" ? (input.error.phase ?? "writeback") : null}
253
+ writeback_error = ${input.status === "failed" ? serializeActionRunFailure(input.error, "writeback") : null}::text::jsonb
257
254
  WHERE project_id = ${input.projectId} AND id = ${input.id}
258
255
  RETURNING *
259
256
  `
@@ -284,9 +281,7 @@ export class PgActionRunStorage implements ActionRunStorage {
284
281
  phase = ${"effects"},
285
282
  effects_status = ${input.status},
286
283
  effects_completed_at = ${nextEffects.completedAt},
287
- effects_error_name = ${input.status === "failed" ? (input.error.name ?? null) : null},
288
- effects_error_message = ${input.status === "failed" ? input.error.message : null},
289
- effects_error_phase = ${input.status === "failed" ? (input.error.phase ?? "effects") : null}
284
+ effects_error = ${input.status === "failed" ? serializeActionRunFailure(input.error, "effects") : null}::text::jsonb
290
285
  WHERE project_id = ${input.projectId} AND id = ${input.id}
291
286
  RETURNING *
292
287
  `
@@ -323,9 +318,7 @@ export class PgActionRunStorage implements ActionRunStorage {
323
318
  status = ${input.status},
324
319
  phase = ${phase},
325
320
  finished_at = ${input.finishedAt ?? new Date()},
326
- error_name = ${input.status === "succeeded" ? null : (input.error?.name ?? null)},
327
- error_message = ${input.status === "succeeded" ? null : (input.error?.message ?? null)},
328
- error_phase = ${input.status === "succeeded" ? null : (input.error?.phase ?? phase)}
321
+ error = ${input.status === "succeeded" ? null : serializeActionRunFailure(input.error)}::text::jsonb
329
322
  WHERE project_id = ${input.projectId} AND id = ${input.id}
330
323
  RETURNING *
331
324
  `
@@ -484,23 +477,14 @@ export class PgActionRunStorage implements ActionRunStorage {
484
477
  }
485
478
 
486
479
  function toActionRunFailure(row: DatabaseRow): ActionRunFailure | undefined {
487
- return toFailure(row.error_name, row.error_message, row.error_phase)
480
+ return row.error === null ? undefined : parseActionRunFailure(row.error)
488
481
  }
489
482
 
490
- function toFailure(
491
- name: string | null,
492
- message: string | null,
493
- phase: ActionRunPhase | null
494
- ): ActionRunFailure | undefined {
495
- if (!message) {
496
- return undefined
497
- }
498
-
499
- return {
500
- name: name ?? undefined,
501
- message,
502
- phase: phase ?? undefined,
503
- }
483
+ function parsePhaseFailure<TPhase extends Extract<ActionRunPhase, "writeback" | "effects">>(
484
+ value: unknown,
485
+ expectedPhase: TPhase
486
+ ): ActionRunFailure<TPhase> {
487
+ return parseActionRunFailure(value, expectedPhase)
504
488
  }
505
489
 
506
490
  function toActionRunWritebackRecord(row: DatabaseRow): ActionRunWritebackRecord | undefined {
@@ -523,11 +507,7 @@ function toActionRunWritebackRecord(row: DatabaseRow): ActionRunWritebackRecord
523
507
  return {
524
508
  status: "failed",
525
509
  completedAt,
526
- error: toFailure(
527
- row.writeback_error_name,
528
- row.writeback_error_message,
529
- row.writeback_error_phase
530
- ),
510
+ error: parsePhaseFailure(row.writeback_error, "writeback"),
531
511
  }
532
512
  }
533
513
 
@@ -550,7 +530,7 @@ function toActionRunEffectsRecord(row: DatabaseRow): ActionRunEffectsRecord | un
550
530
  return {
551
531
  status: "failed",
552
532
  completedAt,
553
- error: toFailure(row.effects_error_name, row.effects_error_message, row.effects_error_phase),
533
+ error: parsePhaseFailure(row.effects_error, "effects"),
554
534
  }
555
535
  }
556
536
 
@@ -595,6 +575,7 @@ function rowToActionRunRecord(row: DatabaseRow): ActionRunRecord {
595
575
  return {
596
576
  id: row.id,
597
577
  projectId: row.project_id,
578
+ executionId: row.execution_id,
598
579
  actionId: row.action_id,
599
580
  subject: rowToActionSubject(row),
600
581
  status: row.status,
@@ -629,6 +610,7 @@ function rowToActionSubject(row: DatabaseRow): ActionSubject {
629
610
  interface DatabaseRow {
630
611
  project_id: string
631
612
  id: string
613
+ execution_id: string
632
614
  action_id: string
633
615
  subject_kind: ActionSubject["kind"]
634
616
  object_type_id: string | null
@@ -643,15 +625,9 @@ interface DatabaseRow {
643
625
  writeback_status: ActionRunWritebackRecord["status"] | null
644
626
  writeback_completed_at: Date | string | null
645
627
  writeback_result: JsonValue | null
646
- writeback_error_name: string | null
647
- writeback_error_message: string | null
648
- writeback_error_phase: ActionRunPhase | null
628
+ writeback_error: unknown | null
649
629
  effects_status: ActionRunEffectsRecord["status"] | null
650
630
  effects_completed_at: Date | string | null
651
- effects_error_name: string | null
652
- effects_error_message: string | null
653
- effects_error_phase: ActionRunPhase | null
654
- error_name: string | null
655
- error_message: string | null
656
- error_phase: ActionRunPhase | null
631
+ effects_error: unknown | null
632
+ error: unknown | null
657
633
  }