@opengeni/db 0.28.1 → 0.28.9
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/dist/{chunk-HT5T62CC.js → chunk-P6CUHXQZ.js} +651 -206
- package/dist/chunk-P6CUHXQZ.js.map +1 -0
- package/dist/{chunk-DBS5HPEW.js → chunk-VHBFHMPC.js} +7 -1
- package/dist/chunk-VHBFHMPC.js.map +1 -0
- package/dist/environment-crypto.d.ts +8 -4
- package/dist/index.d.ts +265 -20
- package/dist/index.js +3966 -2185
- package/dist/index.js.map +1 -1
- package/dist/lossless-columns.d.ts +58 -0
- package/dist/lossless-json.d.ts +39 -0
- package/dist/memory-domain.d.ts +3 -6
- package/dist/persistence-errors.d.ts +7 -14
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +2 -2
- package/dist/schema.d.ts +1419 -271
- package/dist/schema.js +9 -1
- package/dist/session-realtime-terminal.d.ts +7 -0
- package/dist/transcription-recordings-schema.d.ts +44 -6
- package/dist/transcription-recordings.d.ts +1 -1
- package/drizzle/0065_enrollment_credential_generation.sql +10 -0
- package/drizzle/0140_retained_screenshot_artifacts.sql +192 -0
- package/drizzle/0176_lossless_canonical_json.sql +975 -0
- package/drizzle/0177_session_events_workspace_turn_type_index.sql +5 -0
- package/drizzle/0178_permissioned_secret_reads.sql +14 -0
- package/drizzle/0179_slack_private_shortcut_delivery_gate.sql +85 -0
- package/drizzle/0180_retained_screenshot_lifecycle_fences.sql +273 -0
- package/drizzle/0181_connected_machine_removal.sql +52 -0
- package/drizzle/0182_connected_machine_remove_session_default.sql +77 -0
- package/package.json +4 -4
- package/src/database.ts +7 -1
- package/src/environment-crypto.ts +22 -9
- package/src/index.ts +4253 -1601
- package/src/lossless-columns.ts +35 -0
- package/src/lossless-json.ts +322 -0
- package/src/memory-domain.ts +5 -44
- package/src/persistence-errors.ts +29 -34
- package/src/runtime-posture.ts +6 -0
- package/src/schema.ts +260 -38
- package/src/session-control.ts +125 -76
- package/src/session-queue-commands.ts +325 -234
- package/src/session-realtime-context.ts +18 -5
- package/src/session-realtime-ledger.ts +29 -7
- package/src/session-realtime-mirror.ts +4 -2
- package/src/session-realtime-terminal.ts +89 -21
- package/src/session-realtime.ts +3 -2
- package/src/session-tool-call-settlement.ts +29 -15
- package/src/transcription-recordings-schema.ts +5 -2
- package/src/transcription-recordings.ts +70 -40
- package/dist/chunk-DBS5HPEW.js.map +0 -1
- package/dist/chunk-HT5T62CC.js.map +0 -1
- package/dist/event-payload-sanitizer.d.ts +0 -32
- package/src/event-payload-sanitizer.ts +0 -377
package/src/schema.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
bigint,
|
|
12
12
|
boolean,
|
|
13
13
|
check,
|
|
14
|
+
customType,
|
|
14
15
|
foreignKey,
|
|
15
16
|
index,
|
|
16
17
|
integer,
|
|
@@ -21,8 +22,8 @@ import {
|
|
|
21
22
|
timestamp,
|
|
22
23
|
uniqueIndex,
|
|
23
24
|
uuid,
|
|
24
|
-
customType,
|
|
25
25
|
} from "drizzle-orm/pg-core";
|
|
26
|
+
import { losslessCodecVersion, losslessJsonb, losslessText } from "./lossless-columns";
|
|
26
27
|
|
|
27
28
|
const vector = customType<{ data: number[]; driverData: string }>({
|
|
28
29
|
dataType() {
|
|
@@ -1371,7 +1372,8 @@ export const sessions = pgTable(
|
|
|
1371
1372
|
.notNull()
|
|
1372
1373
|
.references(() => workspaces.id, { onDelete: "cascade" }),
|
|
1373
1374
|
status: text("status").notNull().default("queued"),
|
|
1374
|
-
initialMessage:
|
|
1375
|
+
initialMessage: losslessText("initial_message").notNull(),
|
|
1376
|
+
initialMessageCodecVersion: losslessCodecVersion("initial_message_codec_version"),
|
|
1375
1377
|
// Invisible host context frozen with the winning session create. The
|
|
1376
1378
|
// initial turn copies this value so an idempotent repair can never adopt a
|
|
1377
1379
|
// retrying caller's different instructions.
|
|
@@ -1825,8 +1827,10 @@ export const sessionRealtimeEntries = pgTable(
|
|
|
1825
1827
|
// result/error to the same ordinary turn. It never denotes a child/fork
|
|
1826
1828
|
// session.
|
|
1827
1829
|
turnId: uuid("turn_id"),
|
|
1828
|
-
text:
|
|
1829
|
-
|
|
1830
|
+
text: losslessText("text"),
|
|
1831
|
+
textCodecVersion: losslessCodecVersion("text_codec_version"),
|
|
1832
|
+
payload: losslessJsonb("payload").$type<Record<string, unknown>>().notNull().default({}),
|
|
1833
|
+
payloadCodecVersion: losslessCodecVersion("payload_codec_version"),
|
|
1830
1834
|
clientAckedAt: timestamp("client_acked_at", { withTimezone: true }),
|
|
1831
1835
|
providerAckedAt: timestamp("provider_acked_at", { withTimezone: true }),
|
|
1832
1836
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
@@ -1890,14 +1894,6 @@ export const sessionRealtimeEntries = pgTable(
|
|
|
1890
1894
|
"session_realtime_entries_delegation_item_check",
|
|
1891
1895
|
sql`${table.delegationItemId} is null or octet_length(${table.delegationItemId}) between 1 and 1024`,
|
|
1892
1896
|
),
|
|
1893
|
-
textValid: check(
|
|
1894
|
-
"session_realtime_entries_text_check",
|
|
1895
|
-
sql`${table.text} is null or octet_length(${table.text}) <= 131072`,
|
|
1896
|
-
),
|
|
1897
|
-
payloadValid: check(
|
|
1898
|
-
"session_realtime_entries_payload_check",
|
|
1899
|
-
sql`octet_length(${table.payload}::text) <= 131072`,
|
|
1900
|
-
),
|
|
1901
1897
|
turnValid: check(
|
|
1902
1898
|
"session_realtime_entries_turn_check",
|
|
1903
1899
|
sql`${table.turnId} is null
|
|
@@ -2171,6 +2167,145 @@ export const fileUploads = pgTable(
|
|
|
2171
2167
|
}),
|
|
2172
2168
|
);
|
|
2173
2169
|
|
|
2170
|
+
/** Exact pending/ready byte accounting for retained computer screenshots. */
|
|
2171
|
+
export const workspaceScreenshotQuotas = pgTable(
|
|
2172
|
+
"workspace_screenshot_quotas",
|
|
2173
|
+
{
|
|
2174
|
+
workspaceId: uuid("workspace_id")
|
|
2175
|
+
.primaryKey()
|
|
2176
|
+
.references(() => workspaces.id, { onDelete: "cascade" }),
|
|
2177
|
+
accountId: uuid("account_id")
|
|
2178
|
+
.notNull()
|
|
2179
|
+
.references(() => managedAccounts.id, { onDelete: "cascade" }),
|
|
2180
|
+
reservedBytes: bigint("reserved_bytes", { mode: "number" }).notNull().default(0),
|
|
2181
|
+
readyBytes: bigint("ready_bytes", { mode: "number" }).notNull().default(0),
|
|
2182
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
2183
|
+
},
|
|
2184
|
+
(table) => ({
|
|
2185
|
+
workspaceAccount: foreignKey({
|
|
2186
|
+
columns: [table.workspaceId, table.accountId],
|
|
2187
|
+
foreignColumns: [workspaces.id, workspaces.accountId],
|
|
2188
|
+
name: "workspace_screenshot_quotas_workspace_account_fk",
|
|
2189
|
+
}).onDelete("cascade"),
|
|
2190
|
+
nonnegative: check(
|
|
2191
|
+
"workspace_screenshot_quotas_nonnegative_chk",
|
|
2192
|
+
sql`${table.reservedBytes} >= 0 and ${table.readyBytes} >= 0`,
|
|
2193
|
+
),
|
|
2194
|
+
}),
|
|
2195
|
+
);
|
|
2196
|
+
|
|
2197
|
+
/** Provider-neutral screenshot lifecycle; canonical bytes stay in `files` storage. */
|
|
2198
|
+
export const retainedScreenshotArtifacts = pgTable(
|
|
2199
|
+
"retained_screenshot_artifacts",
|
|
2200
|
+
{
|
|
2201
|
+
// The composite file FK is RESTRICT in migration 0176: only the retained
|
|
2202
|
+
// screenshot lifecycle may remove its backing file after provider cleanup.
|
|
2203
|
+
artifactId: uuid("artifact_id").primaryKey(),
|
|
2204
|
+
accountId: uuid("account_id")
|
|
2205
|
+
.notNull()
|
|
2206
|
+
.references(() => managedAccounts.id, { onDelete: "cascade" }),
|
|
2207
|
+
workspaceId: uuid("workspace_id")
|
|
2208
|
+
.notNull()
|
|
2209
|
+
.references(() => workspaces.id, { onDelete: "cascade" }),
|
|
2210
|
+
sessionId: uuid("session_id").references(() => sessions.id, { onDelete: "set null" }),
|
|
2211
|
+
// Turn/attempt foreign keys are installed by migrations 0140/0176.
|
|
2212
|
+
// Those tables are declared later in this monolithic schema module, so
|
|
2213
|
+
// referencing them here would create an eager initialization cycle.
|
|
2214
|
+
turnId: uuid("turn_id"),
|
|
2215
|
+
attemptId: uuid("attempt_id"),
|
|
2216
|
+
settlementKey: text("settlement_key").notNull(),
|
|
2217
|
+
toolCallId: text("tool_call_id").notNull(),
|
|
2218
|
+
toolOutputId: text("tool_output_id").notNull(),
|
|
2219
|
+
status: text("status")
|
|
2220
|
+
.$type<
|
|
2221
|
+
| "pending"
|
|
2222
|
+
| "reconciling"
|
|
2223
|
+
| "ready"
|
|
2224
|
+
| "cleanup_queued"
|
|
2225
|
+
| "cleanup_pending"
|
|
2226
|
+
| "failed"
|
|
2227
|
+
| "expired"
|
|
2228
|
+
| "deleted"
|
|
2229
|
+
>()
|
|
2230
|
+
.notNull()
|
|
2231
|
+
.default("pending"),
|
|
2232
|
+
quotaState: text("quota_state")
|
|
2233
|
+
.$type<"reserved" | "ready" | "released">()
|
|
2234
|
+
.notNull()
|
|
2235
|
+
.default("reserved"),
|
|
2236
|
+
mediaType: text("media_type").notNull(),
|
|
2237
|
+
sizeBytes: bigint("size_bytes", { mode: "number" }).notNull(),
|
|
2238
|
+
sha256: text("sha256").notNull(),
|
|
2239
|
+
width: integer("width").notNull(),
|
|
2240
|
+
height: integer("height").notNull(),
|
|
2241
|
+
retentionExpiresAt: timestamp("retention_expires_at", { withTimezone: true }).notNull(),
|
|
2242
|
+
readyAt: timestamp("ready_at", { withTimezone: true }),
|
|
2243
|
+
cleanupReason: text("cleanup_reason"),
|
|
2244
|
+
lastError: text("last_error"),
|
|
2245
|
+
maintenanceClaimId: uuid("maintenance_claim_id"),
|
|
2246
|
+
maintenanceClaimedAt: timestamp("maintenance_claimed_at", { withTimezone: true }),
|
|
2247
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
2248
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
2249
|
+
},
|
|
2250
|
+
(table) => ({
|
|
2251
|
+
settlementKey: uniqueIndex("retained_screenshot_artifacts_settlement_key_uq").on(
|
|
2252
|
+
table.settlementKey,
|
|
2253
|
+
),
|
|
2254
|
+
sessionCreated: index("retained_screenshot_artifacts_session_created_idx").on(
|
|
2255
|
+
table.workspaceId,
|
|
2256
|
+
table.sessionId,
|
|
2257
|
+
table.createdAt,
|
|
2258
|
+
table.artifactId,
|
|
2259
|
+
),
|
|
2260
|
+
readyExpiry: index("retained_screenshot_artifacts_ready_expiry_idx")
|
|
2261
|
+
.on(table.retentionExpiresAt, table.artifactId)
|
|
2262
|
+
.where(sql`${table.status} = 'ready'`),
|
|
2263
|
+
pendingReconcile: index("retained_screenshot_artifacts_pending_reconcile_idx")
|
|
2264
|
+
.on(table.updatedAt, table.artifactId)
|
|
2265
|
+
.where(
|
|
2266
|
+
sql`${table.status} in ('pending', 'reconciling', 'cleanup_queued', 'cleanup_pending')`,
|
|
2267
|
+
),
|
|
2268
|
+
workspaceAccount: foreignKey({
|
|
2269
|
+
columns: [table.workspaceId, table.accountId],
|
|
2270
|
+
foreignColumns: [workspaces.id, workspaces.accountId],
|
|
2271
|
+
name: "retained_screenshot_artifacts_workspace_account_fk",
|
|
2272
|
+
}).onDelete("cascade"),
|
|
2273
|
+
workspaceFile: foreignKey({
|
|
2274
|
+
columns: [table.workspaceId, table.artifactId],
|
|
2275
|
+
foreignColumns: [files.workspaceId, files.id],
|
|
2276
|
+
name: "retained_screenshot_artifacts_workspace_file_fk",
|
|
2277
|
+
}).onDelete("restrict"),
|
|
2278
|
+
statusValid: check(
|
|
2279
|
+
"retained_screenshot_artifacts_status_chk",
|
|
2280
|
+
sql`${table.status} in ('pending', 'reconciling', 'ready', 'cleanup_queued', 'cleanup_pending', 'failed', 'expired', 'deleted')`,
|
|
2281
|
+
),
|
|
2282
|
+
quotaStateValid: check(
|
|
2283
|
+
"retained_screenshot_artifacts_quota_state_chk",
|
|
2284
|
+
sql`${table.quotaState} in ('reserved', 'ready', 'released')`,
|
|
2285
|
+
),
|
|
2286
|
+
statusQuotaValid: check(
|
|
2287
|
+
"retained_screenshot_artifacts_status_quota_chk",
|
|
2288
|
+
sql`(${table.status} in ('pending', 'reconciling') and ${table.quotaState} = 'reserved')
|
|
2289
|
+
or (${table.status} = 'ready' and ${table.quotaState} = 'ready')
|
|
2290
|
+
or (${table.status} in ('cleanup_queued', 'cleanup_pending') and ${table.quotaState} in ('reserved', 'ready'))
|
|
2291
|
+
or (${table.status} in ('failed', 'expired', 'deleted') and ${table.quotaState} = 'released')`,
|
|
2292
|
+
),
|
|
2293
|
+
claimShapeValid: check(
|
|
2294
|
+
"retained_screenshot_artifacts_claim_shape_chk",
|
|
2295
|
+
sql`(${table.status} in ('reconciling', 'cleanup_pending')
|
|
2296
|
+
and ${table.maintenanceClaimId} is not null
|
|
2297
|
+
and ${table.maintenanceClaimedAt} is not null)
|
|
2298
|
+
or (${table.status} not in ('reconciling', 'cleanup_pending')
|
|
2299
|
+
and ${table.maintenanceClaimId} is null
|
|
2300
|
+
and ${table.maintenanceClaimedAt} is null)`,
|
|
2301
|
+
),
|
|
2302
|
+
dimensionsValid: check(
|
|
2303
|
+
"retained_screenshot_artifacts_dimensions_chk",
|
|
2304
|
+
sql`${table.width} between 1 and 16384 and ${table.height} between 1 and 16384 and (${table.width}::bigint * ${table.height}::bigint) <= 67108864`,
|
|
2305
|
+
),
|
|
2306
|
+
}),
|
|
2307
|
+
);
|
|
2308
|
+
|
|
2174
2309
|
export const documentBases = pgTable(
|
|
2175
2310
|
"document_bases",
|
|
2176
2311
|
{
|
|
@@ -2380,7 +2515,8 @@ export const knowledgeMemories = pgTable(
|
|
|
2380
2515
|
status: text("status").notNull().default("proposed"),
|
|
2381
2516
|
kind: text("kind").notNull().default("semantic"),
|
|
2382
2517
|
scope: text("scope").notNull().default("workspace"),
|
|
2383
|
-
text:
|
|
2518
|
+
text: losslessText("text").notNull(),
|
|
2519
|
+
textCodecVersion: losslessCodecVersion("text_codec_version"),
|
|
2384
2520
|
sourceRefs: jsonb("source_refs").$type<unknown[]>().notNull().default([]),
|
|
2385
2521
|
confidence: integer("confidence").notNull().default(50),
|
|
2386
2522
|
metadata: jsonb("metadata").$type<Record<string, unknown>>().notNull().default({}),
|
|
@@ -2491,7 +2627,8 @@ export const sessionTurns = pgTable(
|
|
|
2491
2627
|
status: text("status").notNull(),
|
|
2492
2628
|
source: text("source").notNull().default("user"),
|
|
2493
2629
|
position: bigint("position", { mode: "number" }).notNull(),
|
|
2494
|
-
prompt:
|
|
2630
|
+
prompt: losslessText("prompt").notNull(),
|
|
2631
|
+
promptCodecVersion: losslessCodecVersion("prompt_codec_version"),
|
|
2495
2632
|
// Host context for this exact turn. System-level at runtime and deliberately
|
|
2496
2633
|
// separate from the visible prompt/event payload.
|
|
2497
2634
|
turnInstructions: text("turn_instructions"),
|
|
@@ -3150,8 +3287,10 @@ export const sessionSystemUpdates = pgTable(
|
|
|
3150
3287
|
classification: text("classification").notNull().default("info"),
|
|
3151
3288
|
sourceId: text("source_id").notNull(),
|
|
3152
3289
|
dedupeKey: text("dedupe_key").notNull(),
|
|
3153
|
-
summary:
|
|
3154
|
-
|
|
3290
|
+
summary: losslessText("summary").notNull(),
|
|
3291
|
+
summaryCodecVersion: losslessCodecVersion("summary_codec_version"),
|
|
3292
|
+
payload: losslessJsonb("payload").$type<Record<string, unknown>>().notNull().default({}),
|
|
3293
|
+
payloadCodecVersion: losslessCodecVersion("payload_codec_version"),
|
|
3155
3294
|
lineage: jsonb("lineage").$type<Record<string, unknown>>().notNull().default({}),
|
|
3156
3295
|
// Private immutable authority frozen when this machine input is accepted.
|
|
3157
3296
|
// Public projections intentionally omit connection ids and owner subjects.
|
|
@@ -3235,8 +3374,10 @@ export const sessionSystemUpdateOutbox = pgTable(
|
|
|
3235
3374
|
kind: text("kind").notNull(),
|
|
3236
3375
|
classification: text("classification").notNull(),
|
|
3237
3376
|
sourceId: text("source_id").notNull(),
|
|
3238
|
-
summary:
|
|
3239
|
-
|
|
3377
|
+
summary: losslessText("summary").notNull(),
|
|
3378
|
+
summaryCodecVersion: losslessCodecVersion("summary_codec_version"),
|
|
3379
|
+
payload: losslessJsonb("payload").$type<Record<string, unknown>>().notNull().default({}),
|
|
3380
|
+
payloadCodecVersion: losslessCodecVersion("payload_codec_version"),
|
|
3240
3381
|
lineage: jsonb("lineage").$type<Record<string, unknown>>().notNull().default({}),
|
|
3241
3382
|
// Exact private authority copied from the causal parent turn in the source
|
|
3242
3383
|
// terminal transaction. Delivery retries cannot replace this snapshot.
|
|
@@ -3472,7 +3613,8 @@ export const sessionEvents = pgTable(
|
|
|
3472
3613
|
duplicateReason: text("duplicate_reason"),
|
|
3473
3614
|
sequence: integer("sequence").notNull(),
|
|
3474
3615
|
type: text("type").notNull(),
|
|
3475
|
-
payload:
|
|
3616
|
+
payload: losslessJsonb("payload").$type<unknown>().notNull().default({}),
|
|
3617
|
+
payloadCodecVersion: losslessCodecVersion("payload_codec_version"),
|
|
3476
3618
|
clientEventId: text("client_event_id"),
|
|
3477
3619
|
producerId: text("producer_id"),
|
|
3478
3620
|
producerSeq: integer("producer_seq"),
|
|
@@ -3507,16 +3649,15 @@ export const sessionEvents = pgTable(
|
|
|
3507
3649
|
table.type,
|
|
3508
3650
|
table.sequence,
|
|
3509
3651
|
),
|
|
3652
|
+
workspaceTurnType: index("session_events_workspace_turn_type_idx")
|
|
3653
|
+
.on(table.workspaceId, table.turnId, table.type)
|
|
3654
|
+
.where(sql`${table.turnId} is not null`),
|
|
3510
3655
|
monitoringTail: index("session_events_workspace_session_monitoring_tail_idx")
|
|
3511
3656
|
.on(table.workspaceId, table.sessionId, table.sequence)
|
|
3512
3657
|
.where(
|
|
3513
3658
|
sql`${table.type} not in ('agent.message.delta', 'agent.reasoning.delta', 'sandbox.command.output.delta', 'terminal.pty.output.delta')`,
|
|
3514
3659
|
),
|
|
3515
3660
|
duplicateOfEvent: index("session_events_duplicate_of_event_idx").on(table.duplicateOfEventId),
|
|
3516
|
-
payloadBytes: check(
|
|
3517
|
-
"session_events_payload_bytes_check",
|
|
3518
|
-
sql`octet_length(${table.payload}::text) <= 65536`,
|
|
3519
|
-
),
|
|
3520
3661
|
typeBytes: check(
|
|
3521
3662
|
"session_events_type_bytes_check",
|
|
3522
3663
|
sql`octet_length(${table.type}) <= 256 and position(E'\n' in ${table.type}) = 0 and position(E'\r' in ${table.type}) = 0`,
|
|
@@ -3555,8 +3696,10 @@ export const agentRunStates = pgTable("agent_run_states", {
|
|
|
3555
3696
|
onDelete: "set null",
|
|
3556
3697
|
}),
|
|
3557
3698
|
stateVersion: integer("state_version").notNull(),
|
|
3558
|
-
serializedRunState:
|
|
3559
|
-
|
|
3699
|
+
serializedRunState: losslessText("serialized_run_state").notNull(),
|
|
3700
|
+
serializedRunStateCodecVersion: losslessCodecVersion("serialized_run_state_codec_version"),
|
|
3701
|
+
pendingApprovals: losslessJsonb("pending_approvals").$type<unknown[]>().notNull().default([]),
|
|
3702
|
+
pendingApprovalsCodecVersion: losslessCodecVersion("pending_approvals_codec_version"),
|
|
3560
3703
|
// Exact provider rejection marks the latest current-turn receipt only when it
|
|
3561
3704
|
// was part of the rejected request. The serialized receipt remains durable;
|
|
3562
3705
|
// recovery builds a temporary view without unusable opaque artifacts.
|
|
@@ -3651,8 +3794,8 @@ export const sessionHumanInputRequests = pgTable(
|
|
|
3651
3794
|
);
|
|
3652
3795
|
|
|
3653
3796
|
// Conversation truth: ordered, verbatim SDK input items (issue #35). The
|
|
3654
|
-
// model-facing memory store —
|
|
3655
|
-
//
|
|
3797
|
+
// model-facing memory store — exact and replay-ready. session_events is also
|
|
3798
|
+
// exact canonical OpenGeni data; transport projections must not rewrite it.
|
|
3656
3799
|
export const sessionHistoryItems = pgTable(
|
|
3657
3800
|
"session_history_items",
|
|
3658
3801
|
{
|
|
@@ -3676,7 +3819,8 @@ export const sessionHistoryItems = pgTable(
|
|
|
3676
3819
|
// positions; only the summary uses the half-step. `mode: "number"` maps the
|
|
3677
3820
|
// postgres.js string back to a JS number so every reader stays numeric.
|
|
3678
3821
|
position: numeric("position", { mode: "number" }).notNull(),
|
|
3679
|
-
item:
|
|
3822
|
+
item: losslessJsonb("item").$type<Record<string, unknown>>().notNull(),
|
|
3823
|
+
itemCodecVersion: losslessCodecVersion("item_codec_version"),
|
|
3680
3824
|
// Live-row flag for client-side context compaction. The read path selects
|
|
3681
3825
|
// only active rows; a compaction supersedes the summarized prefix (sets this
|
|
3682
3826
|
// false — never deletes, so the full transcript stays as an audit trail) and
|
|
@@ -3706,7 +3850,7 @@ export const sessionHistoryItems = pgTable(
|
|
|
3706
3850
|
|
|
3707
3851
|
// Turn-lineage ledger for a tool call that the SDK emitted but has not yet
|
|
3708
3852
|
// produced a durably reconciled result. The raw call item is model-facing truth
|
|
3709
|
-
// (not
|
|
3853
|
+
// (not a transport projection). The attempt/generation identify
|
|
3710
3854
|
// where the call originated, but the receipt survives an approval resume into a
|
|
3711
3855
|
// newer attempt of the same logical turn. Turn-ending transactions
|
|
3712
3856
|
// consume these rows atomically and append a valid interrupted result so a
|
|
@@ -3732,9 +3876,11 @@ export const sessionPendingToolCalls = pgTable(
|
|
|
3732
3876
|
attemptId: uuid("attempt_id").notNull(),
|
|
3733
3877
|
callId: text("call_id").notNull(),
|
|
3734
3878
|
callType: text("call_type").notNull(),
|
|
3735
|
-
callItem:
|
|
3879
|
+
callItem: losslessJsonb("call_item").$type<Record<string, unknown>>().notNull(),
|
|
3880
|
+
callItemCodecVersion: losslessCodecVersion("call_item_codec_version"),
|
|
3736
3881
|
modelToolOutputTruncationTokens: integer("model_tool_output_truncation_tokens"),
|
|
3737
|
-
resultItem:
|
|
3882
|
+
resultItem: losslessJsonb("result_item").$type<Record<string, unknown>>(),
|
|
3883
|
+
resultItemCodecVersion: losslessCodecVersion("result_item_codec_version"),
|
|
3738
3884
|
resultRecordedAt: timestamp("result_recorded_at", { withTimezone: true }),
|
|
3739
3885
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
3740
3886
|
},
|
|
@@ -3773,7 +3919,8 @@ export const sandboxSessionEnvelopes = pgTable(
|
|
|
3773
3919
|
sessionId: uuid("session_id")
|
|
3774
3920
|
.notNull()
|
|
3775
3921
|
.references(() => sessions.id, { onDelete: "cascade" }),
|
|
3776
|
-
envelope:
|
|
3922
|
+
envelope: losslessJsonb("envelope").$type<Record<string, unknown>>().notNull(),
|
|
3923
|
+
envelopeCodecVersion: losslessCodecVersion("envelope_codec_version"),
|
|
3777
3924
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
3778
3925
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
3779
3926
|
},
|
|
@@ -4549,7 +4696,8 @@ export const sessionRecordings = pgTable(
|
|
|
4549
4696
|
width: integer("width").notNull(),
|
|
4550
4697
|
height: integer("height").notNull(),
|
|
4551
4698
|
|
|
4552
|
-
reason:
|
|
4699
|
+
reason: losslessText("reason"),
|
|
4700
|
+
reasonCodecVersion: losslessCodecVersion("reason_codec_version"),
|
|
4553
4701
|
|
|
4554
4702
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
4555
4703
|
finalizedAt: timestamp("finalized_at", { withTimezone: true }),
|
|
@@ -4759,6 +4907,10 @@ export const enrollments = pgTable(
|
|
|
4759
4907
|
desktopUnavailableReason: text("desktop_unavailable_reason"),
|
|
4760
4908
|
allowScreenControl: boolean("allow_screen_control").notNull().default(false),
|
|
4761
4909
|
status: text("status", { enum: enrollmentStatusValues }).notNull().default("active"),
|
|
4910
|
+
// Credential-family fence. Existing rows/migration-era bearers are generation
|
|
4911
|
+
// 1; every successful re-enrollment increments this atomically before a new
|
|
4912
|
+
// bearer is signed. Auth and self-revoke require an exact row/claim match.
|
|
4913
|
+
credentialGeneration: integer("credential_generation").notNull().default(1),
|
|
4762
4914
|
os: text("os", { enum: enrollmentOsValues }).notNull().default("linux"),
|
|
4763
4915
|
arch: text("arch").notNull().default("x86_64"),
|
|
4764
4916
|
// Heartbeat liveness cursor. Null until the first connect.
|
|
@@ -4786,6 +4938,68 @@ export const enrollments = pgTable(
|
|
|
4786
4938
|
}),
|
|
4787
4939
|
);
|
|
4788
4940
|
|
|
4941
|
+
// One durable receipt per workspace-authorized connected-machine removal
|
|
4942
|
+
// request. The enrollment row remains the lifecycle truth; this table preserves
|
|
4943
|
+
// the exact idempotency key, request fingerprint, and terminal result so a lost
|
|
4944
|
+
// response can be replayed without re-running dependency checks or mutating a
|
|
4945
|
+
// different enrollment that happens to share the same display name.
|
|
4946
|
+
export const machineRemovalOperationOutcomeValues = [
|
|
4947
|
+
"removed",
|
|
4948
|
+
"already_removed",
|
|
4949
|
+
"blocked",
|
|
4950
|
+
] as const;
|
|
4951
|
+
|
|
4952
|
+
export const machineRemovalOperations = pgTable(
|
|
4953
|
+
"machine_removal_operations",
|
|
4954
|
+
{
|
|
4955
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
4956
|
+
accountId: uuid("account_id")
|
|
4957
|
+
.notNull()
|
|
4958
|
+
.references(() => managedAccounts.id, { onDelete: "cascade" }),
|
|
4959
|
+
workspaceId: uuid("workspace_id")
|
|
4960
|
+
.notNull()
|
|
4961
|
+
.references(() => workspaces.id, { onDelete: "cascade" }),
|
|
4962
|
+
enrollmentId: uuid("enrollment_id")
|
|
4963
|
+
.notNull()
|
|
4964
|
+
.references(() => enrollments.id, { onDelete: "restrict" }),
|
|
4965
|
+
operationKey: text("operation_key").notNull(),
|
|
4966
|
+
requestFingerprint: text("request_fingerprint").notNull(),
|
|
4967
|
+
outcome: text("outcome", { enum: machineRemovalOperationOutcomeValues }).notNull(),
|
|
4968
|
+
result: jsonb("result").$type<Record<string, unknown>>().notNull().default({}),
|
|
4969
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
4970
|
+
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
|
|
4971
|
+
},
|
|
4972
|
+
(table) => ({
|
|
4973
|
+
workspaceAccount: foreignKey({
|
|
4974
|
+
name: "machine_removal_operations_workspace_account_fk",
|
|
4975
|
+
columns: [table.workspaceId, table.accountId],
|
|
4976
|
+
foreignColumns: [workspaces.id, workspaces.accountId],
|
|
4977
|
+
}).onDelete("cascade"),
|
|
4978
|
+
workspaceOperation: uniqueIndex("machine_removal_operations_workspace_operation_uq").on(
|
|
4979
|
+
table.workspaceId,
|
|
4980
|
+
table.operationKey,
|
|
4981
|
+
),
|
|
4982
|
+
workspaceIdentity: uniqueIndex("machine_removal_operations_workspace_id_uq").on(
|
|
4983
|
+
table.workspaceId,
|
|
4984
|
+
table.id,
|
|
4985
|
+
),
|
|
4986
|
+
enrollmentTimeline: index("machine_removal_operations_enrollment_created_idx").on(
|
|
4987
|
+
table.workspaceId,
|
|
4988
|
+
table.enrollmentId,
|
|
4989
|
+
table.createdAt,
|
|
4990
|
+
),
|
|
4991
|
+
requestFingerprintValid: check(
|
|
4992
|
+
"machine_removal_operations_request_fingerprint_chk",
|
|
4993
|
+
sql`${table.requestFingerprint} ~ '^[0-9a-f]{64}$'`,
|
|
4994
|
+
),
|
|
4995
|
+
operationKeyValid: check(
|
|
4996
|
+
"machine_removal_operations_operation_key_chk",
|
|
4997
|
+
sql`length(btrim(${table.operationKey})) between 1 and 200
|
|
4998
|
+
and ${table.operationKey} = btrim(${table.operationKey})`,
|
|
4999
|
+
),
|
|
5000
|
+
}),
|
|
5001
|
+
);
|
|
5002
|
+
|
|
4789
5003
|
// The OAuth 2.0 device-authorization (RFC 8628) PENDING request (M5, migration
|
|
4790
5004
|
// 0025 / enrollment + §18 LOUD consent). An agent's `enroll` starts
|
|
4791
5005
|
// a flow (POST /enrollments/device/start) → one short-TTL, single-use row keyed by
|
|
@@ -5404,7 +5618,8 @@ export const hostExportConfig = pgTable(
|
|
|
5404
5618
|
/**
|
|
5405
5619
|
* Transactional delivery buffer. It intentionally has no tenant/source FKs:
|
|
5406
5620
|
* a workspace deletion must not erase an already-committed, unacknowledged
|
|
5407
|
-
* host fact.
|
|
5621
|
+
* host fact. Session-event payloads retain their exact storage bytes plus
|
|
5622
|
+
* explicit codec truth; usage payloads remain ordinary JSON.
|
|
5408
5623
|
*/
|
|
5409
5624
|
export const hostExportOutbox = pgTable(
|
|
5410
5625
|
"host_export_outbox",
|
|
@@ -5434,6 +5649,7 @@ export const hostExportOutbox = pgTable(
|
|
|
5434
5649
|
.default({}),
|
|
5435
5650
|
origin: text("origin"),
|
|
5436
5651
|
payload: jsonb("payload").$type<unknown>().notNull(),
|
|
5652
|
+
payloadCodecVersion: losslessCodecVersion("payload_codec_version"),
|
|
5437
5653
|
envelopeBytes: integer("envelope_bytes").notNull(),
|
|
5438
5654
|
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
|
|
5439
5655
|
sourceRecordedAt: timestamp("source_recorded_at", { withTimezone: true }).notNull(),
|
|
@@ -5509,6 +5725,7 @@ export const hostExportConsumers = pgTable(
|
|
|
5509
5725
|
consecutiveFailures: integer("consecutive_failures").notNull().default(0),
|
|
5510
5726
|
nextAttemptAt: timestamp("next_attempt_at", { withTimezone: true }).notNull().defaultNow(),
|
|
5511
5727
|
lastError: text("last_error"),
|
|
5728
|
+
lastErrorCodecVersion: losslessCodecVersion("last_error_codec_version"),
|
|
5512
5729
|
lastErrorAt: timestamp("last_error_at", { withTimezone: true }),
|
|
5513
5730
|
blockedAt: timestamp("blocked_at", { withTimezone: true }),
|
|
5514
5731
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
@@ -5542,7 +5759,9 @@ export const hostExportDeadLetters = pgTable(
|
|
|
5542
5759
|
exportCursor: bigint("export_cursor", { mode: "bigint" }).notNull(),
|
|
5543
5760
|
sourceId: uuid("source_id").notNull(),
|
|
5544
5761
|
reason: text("reason").notNull(),
|
|
5545
|
-
envelope:
|
|
5762
|
+
envelope: losslessJsonb("envelope").$type<Record<string, unknown>>().notNull(),
|
|
5763
|
+
envelopeCodecVersion: losslessCodecVersion("envelope_codec_version"),
|
|
5764
|
+
eventPayloadCodecVersion: losslessCodecVersion("event_payload_codec_version"),
|
|
5546
5765
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
5547
5766
|
},
|
|
5548
5767
|
(table) => ({
|
|
@@ -5643,7 +5862,8 @@ export const auditEvents = pgTable(
|
|
|
5643
5862
|
action: text("action").notNull(),
|
|
5644
5863
|
targetType: text("target_type"),
|
|
5645
5864
|
targetId: text("target_id"),
|
|
5646
|
-
metadata:
|
|
5865
|
+
metadata: losslessJsonb("metadata").$type<Record<string, unknown>>().notNull().default({}),
|
|
5866
|
+
metadataCodecVersion: losslessCodecVersion("metadata_codec_version"),
|
|
5647
5867
|
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow(),
|
|
5648
5868
|
},
|
|
5649
5869
|
(table) => ({
|
|
@@ -6011,11 +6231,13 @@ export const rigChanges = pgTable(
|
|
|
6011
6231
|
}),
|
|
6012
6232
|
// 'setup_append' | 'definition_edit' (CHECK in migration 0047).
|
|
6013
6233
|
kind: text("kind").notNull(),
|
|
6014
|
-
payload:
|
|
6234
|
+
payload: losslessJsonb("payload").$type<Record<string, unknown>>().notNull(),
|
|
6235
|
+
payloadCodecVersion: losslessCodecVersion("payload_codec_version"),
|
|
6015
6236
|
// 'proposed' | 'verifying' | 'merged' | 'rejected' | 'failed' (CHECK in 0047).
|
|
6016
6237
|
status: text("status").notNull().default("proposed"),
|
|
6017
6238
|
proposedBy: text("proposed_by"),
|
|
6018
|
-
verification:
|
|
6239
|
+
verification: losslessJsonb("verification").$type<Record<string, unknown>>(),
|
|
6240
|
+
verificationCodecVersion: losslessCodecVersion("verification_codec_version"),
|
|
6019
6241
|
resultVersionId: uuid("result_version_id").references(() => rigVersions.id, {
|
|
6020
6242
|
onDelete: "set null",
|
|
6021
6243
|
}),
|