@assemblyline-agents/postgres 1.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +1 -1
  2. package/dist/adapter-agent-state.d.ts +15 -0
  3. package/dist/adapter-agent-state.d.ts.map +1 -0
  4. package/dist/adapter-agent-state.js +163 -0
  5. package/dist/adapter-agent-state.js.map +1 -0
  6. package/dist/adapter-checkpoints.d.ts +1 -1
  7. package/dist/adapter-checkpoints.d.ts.map +1 -1
  8. package/dist/adapter-checkpoints.js +47 -27
  9. package/dist/adapter-checkpoints.js.map +1 -1
  10. package/dist/adapter-connection-events.d.ts +26 -0
  11. package/dist/adapter-connection-events.d.ts.map +1 -0
  12. package/dist/adapter-connection-events.js +126 -0
  13. package/dist/adapter-connection-events.js.map +1 -0
  14. package/dist/adapter-conversation-turns.d.ts +3 -1
  15. package/dist/adapter-conversation-turns.d.ts.map +1 -1
  16. package/dist/adapter-conversation-turns.js +99 -17
  17. package/dist/adapter-conversation-turns.js.map +1 -1
  18. package/dist/adapter-conversations.d.ts +11 -1
  19. package/dist/adapter-conversations.d.ts.map +1 -1
  20. package/dist/adapter-conversations.js +82 -15
  21. package/dist/adapter-conversations.js.map +1 -1
  22. package/dist/adapter-delivery.d.ts.map +1 -1
  23. package/dist/adapter-delivery.js +20 -12
  24. package/dist/adapter-delivery.js.map +1 -1
  25. package/dist/adapter-grants.d.ts +2 -0
  26. package/dist/adapter-grants.d.ts.map +1 -1
  27. package/dist/adapter-grants.js +18 -8
  28. package/dist/adapter-grants.js.map +1 -1
  29. package/dist/adapter-memory.d.ts +2 -0
  30. package/dist/adapter-memory.d.ts.map +1 -1
  31. package/dist/adapter-memory.js +23 -13
  32. package/dist/adapter-memory.js.map +1 -1
  33. package/dist/adapter-misc.d.ts +8 -0
  34. package/dist/adapter-misc.d.ts.map +1 -1
  35. package/dist/adapter-misc.js +80 -33
  36. package/dist/adapter-misc.js.map +1 -1
  37. package/dist/adapter-runs.d.ts.map +1 -1
  38. package/dist/adapter-runs.js +37 -23
  39. package/dist/adapter-runs.js.map +1 -1
  40. package/dist/adapter-sandbox.d.ts +2 -1
  41. package/dist/adapter-sandbox.d.ts.map +1 -1
  42. package/dist/adapter-sandbox.js +91 -19
  43. package/dist/adapter-sandbox.js.map +1 -1
  44. package/dist/adapter-settings.js +4 -4
  45. package/dist/adapter-settings.js.map +1 -1
  46. package/dist/adapter-timeline.d.ts +5 -0
  47. package/dist/adapter-timeline.d.ts.map +1 -0
  48. package/dist/adapter-timeline.js +86 -0
  49. package/dist/adapter-timeline.js.map +1 -0
  50. package/dist/adapter-usage.d.ts.map +1 -1
  51. package/dist/adapter-usage.js +7 -7
  52. package/dist/adapter-usage.js.map +1 -1
  53. package/dist/adapter-workspaces.d.ts +25 -0
  54. package/dist/adapter-workspaces.d.ts.map +1 -0
  55. package/dist/adapter-workspaces.js +486 -0
  56. package/dist/adapter-workspaces.js.map +1 -0
  57. package/dist/index.d.ts +90 -2
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +150 -6
  60. package/dist/index.js.map +1 -1
  61. package/dist/learning-store.d.ts +32 -0
  62. package/dist/learning-store.d.ts.map +1 -0
  63. package/dist/learning-store.js +182 -0
  64. package/dist/learning-store.js.map +1 -0
  65. package/dist/migrations.d.ts +7 -1
  66. package/dist/migrations.d.ts.map +1 -1
  67. package/dist/migrations.js +617 -150
  68. package/dist/migrations.js.map +1 -1
  69. package/dist/presets.d.ts +1 -1
  70. package/dist/presets.d.ts.map +1 -1
  71. package/dist/provider.d.ts +1 -1
  72. package/dist/provider.js +7 -7
  73. package/dist/provider.js.map +1 -1
  74. package/dist/row-mappers.d.ts.map +1 -1
  75. package/dist/row-mappers.js +24 -3
  76. package/dist/row-mappers.js.map +1 -1
  77. package/dist/sql-helpers.d.ts +0 -1
  78. package/dist/sql-helpers.d.ts.map +1 -1
  79. package/dist/sql-helpers.js +11 -6
  80. package/dist/sql-helpers.js.map +1 -1
  81. package/dist/stores.d.ts +3 -1
  82. package/dist/stores.d.ts.map +1 -1
  83. package/dist/stores.js +72 -24
  84. package/dist/stores.js.map +1 -1
  85. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  export const POSTGRES_SCHEMA_MIGRATIONS_SQL = `
2
- create table if not exists openeve_schema_migrations (
2
+ create table if not exists assembly_line_schema_migrations (
3
3
  id text primary key,
4
4
  checksum text not null,
5
5
  description text not null,
@@ -9,11 +9,11 @@ create table if not exists openeve_schema_migrations (
9
9
  `;
10
10
  export const postgresMigrations = [
11
11
  {
12
- id: "001_openeve_state",
13
- description: "Core OpenEve runtime state, memory documents, file catalog, sandbox sync worker fields, queues, and idempotency tables.",
12
+ id: "001_assembly_line_state",
13
+ description: "Core Assembly Line runtime state, memory documents, file catalog, sandbox sync worker fields, queues, and idempotency tables.",
14
14
  expandContractNotes: "All objects are created with if-not-exists semantics. Existing deployments can expand in place; later cleanup should be additive until all runtimes are upgraded.",
15
15
  sql: `
16
- create table if not exists openeve_runs (
16
+ create table if not exists assembly_line_runs (
17
17
  id text primary key,
18
18
  agent_revision text not null,
19
19
  status text not null,
@@ -26,9 +26,9 @@ create table if not exists openeve_runs (
26
26
  updated_at timestamptz not null
27
27
  );
28
28
 
29
- create table if not exists openeve_run_events (
29
+ create table if not exists assembly_line_run_events (
30
30
  id text primary key,
31
- run_id text not null references openeve_runs(id),
31
+ run_id text not null references assembly_line_runs(id),
32
32
  sequence integer not null,
33
33
  type text not null,
34
34
  data jsonb not null default '{}'::jsonb,
@@ -36,9 +36,9 @@ create table if not exists openeve_run_events (
36
36
  unique (run_id, sequence)
37
37
  );
38
38
 
39
- create table if not exists openeve_tool_calls (
39
+ create table if not exists assembly_line_tool_calls (
40
40
  id text primary key,
41
- run_id text not null references openeve_runs(id),
41
+ run_id text not null references assembly_line_runs(id),
42
42
  tool_name text not null,
43
43
  status text not null,
44
44
  input jsonb not null,
@@ -50,17 +50,17 @@ create table if not exists openeve_tool_calls (
50
50
  updated_at timestamptz not null
51
51
  );
52
52
 
53
- create table if not exists openeve_checkpoints (
53
+ create table if not exists assembly_line_checkpoints (
54
54
  id text primary key,
55
- run_id text not null references openeve_runs(id),
55
+ run_id text not null references assembly_line_runs(id),
56
56
  name text not null,
57
57
  data jsonb not null default '{}'::jsonb,
58
58
  created_at timestamptz not null
59
59
  );
60
60
 
61
- create table if not exists openeve_delivery_obligations (
61
+ create table if not exists assembly_line_delivery_obligations (
62
62
  id text primary key,
63
- run_id text not null references openeve_runs(id),
63
+ run_id text not null references assembly_line_runs(id),
64
64
  channel text not null,
65
65
  payload jsonb not null,
66
66
  idempotency_key text not null unique,
@@ -69,7 +69,7 @@ create table if not exists openeve_delivery_obligations (
69
69
  updated_at timestamptz not null
70
70
  );
71
71
 
72
- create table if not exists openeve_agents (
72
+ create table if not exists assembly_line_agents (
73
73
  id text primary key,
74
74
  name text not null,
75
75
  manifest jsonb not null,
@@ -77,17 +77,17 @@ create table if not exists openeve_agents (
77
77
  updated_at timestamptz not null
78
78
  );
79
79
 
80
- create table if not exists openeve_agent_revisions (
80
+ create table if not exists assembly_line_agent_revisions (
81
81
  agent_revision text primary key,
82
- agent_id text references openeve_agents(id),
82
+ agent_id text references assembly_line_agents(id),
83
83
  manifest jsonb not null,
84
84
  source_hashes jsonb not null default '{}'::jsonb,
85
85
  created_at timestamptz not null
86
86
  );
87
87
 
88
- create table if not exists openeve_conversations (
88
+ create table if not exists assembly_line_conversations (
89
89
  id text primary key,
90
- agent_id text references openeve_agents(id),
90
+ agent_id text references assembly_line_agents(id),
91
91
  channel text not null,
92
92
  subject text,
93
93
  metadata jsonb not null default '{}'::jsonb,
@@ -95,26 +95,26 @@ create table if not exists openeve_conversations (
95
95
  updated_at timestamptz not null
96
96
  );
97
97
 
98
- create table if not exists openeve_messages (
98
+ create table if not exists assembly_line_messages (
99
99
  id text primary key,
100
- conversation_id text references openeve_conversations(id),
101
- run_id text references openeve_runs(id),
100
+ conversation_id text references assembly_line_conversations(id),
101
+ run_id text references assembly_line_runs(id),
102
102
  role text not null,
103
103
  content jsonb not null,
104
104
  created_at timestamptz not null
105
105
  );
106
106
 
107
- create table if not exists openeve_approval_gates (
107
+ create table if not exists assembly_line_approval_gates (
108
108
  id text primary key,
109
- run_id text not null references openeve_runs(id),
110
- tool_call_id text references openeve_tool_calls(id),
109
+ run_id text not null references assembly_line_runs(id),
110
+ tool_call_id text references assembly_line_tool_calls(id),
111
111
  status text not null,
112
112
  reason text,
113
113
  created_at timestamptz not null,
114
114
  updated_at timestamptz not null
115
115
  );
116
116
 
117
- create table if not exists openeve_schedules (
117
+ create table if not exists assembly_line_schedules (
118
118
  id text primary key,
119
119
  name text not null,
120
120
  cron text not null,
@@ -124,10 +124,10 @@ create table if not exists openeve_schedules (
124
124
  updated_at timestamptz not null
125
125
  );
126
126
 
127
- create table if not exists openeve_schedule_runs (
127
+ create table if not exists assembly_line_schedule_runs (
128
128
  id text primary key,
129
- schedule_id text references openeve_schedules(id),
130
- run_id text references openeve_runs(id),
129
+ schedule_id text references assembly_line_schedules(id),
130
+ run_id text references assembly_line_runs(id),
131
131
  idempotency_key text not null unique,
132
132
  status text not null,
133
133
  run_at timestamptz not null,
@@ -135,9 +135,9 @@ create table if not exists openeve_schedule_runs (
135
135
  updated_at timestamptz not null
136
136
  );
137
137
 
138
- create table if not exists openeve_memory_file_indexes (
138
+ create table if not exists assembly_line_memory_file_indexes (
139
139
  id text primary key,
140
- run_id text references openeve_runs(id),
140
+ run_id text references assembly_line_runs(id),
141
141
  path text not null,
142
142
  blob_key text not null,
143
143
  sha256 text not null,
@@ -145,10 +145,10 @@ create table if not exists openeve_memory_file_indexes (
145
145
  created_at timestamptz not null
146
146
  );
147
147
 
148
- create unique index if not exists openeve_memory_file_indexes_revision_unique
149
- on openeve_memory_file_indexes (run_id, path, sha256);
148
+ create unique index if not exists assembly_line_memory_file_indexes_revision_unique
149
+ on assembly_line_memory_file_indexes (run_id, path, sha256);
150
150
 
151
- create table if not exists openeve_memory_documents (
151
+ create table if not exists assembly_line_memory_documents (
152
152
  id text primary key,
153
153
  scope_key text not null unique,
154
154
  scope jsonb not null,
@@ -175,24 +175,24 @@ create table if not exists openeve_memory_documents (
175
175
  updated_at timestamptz not null
176
176
  );
177
177
 
178
- create index if not exists openeve_memory_documents_scope_path
179
- on openeve_memory_documents ((scope->>'agentScope'), normalized_path);
178
+ create index if not exists assembly_line_memory_documents_scope_path
179
+ on assembly_line_memory_documents ((scope->>'agentScope'), normalized_path);
180
180
 
181
- create index if not exists openeve_memory_documents_scope_user
182
- on openeve_memory_documents ((scope->>'agentScope'), (scope->>'userId'), updated_at);
181
+ create index if not exists assembly_line_memory_documents_scope_user
182
+ on assembly_line_memory_documents ((scope->>'agentScope'), (scope->>'userId'), updated_at);
183
183
 
184
- create index if not exists openeve_memory_documents_scope_conversation
185
- on openeve_memory_documents ((scope->>'agentScope'), (scope->>'conversationId'), updated_at);
184
+ create index if not exists assembly_line_memory_documents_scope_conversation
185
+ on assembly_line_memory_documents ((scope->>'agentScope'), (scope->>'conversationId'), updated_at);
186
186
 
187
- create index if not exists openeve_memory_documents_scope_project
188
- on openeve_memory_documents ((scope->>'agentScope'), (scope->>'projectId'), updated_at);
187
+ create index if not exists assembly_line_memory_documents_scope_project
188
+ on assembly_line_memory_documents ((scope->>'agentScope'), (scope->>'projectId'), updated_at);
189
189
 
190
- create index if not exists openeve_memory_documents_search_vector
191
- on openeve_memory_documents using gin (search_vector);
190
+ create index if not exists assembly_line_memory_documents_search_vector
191
+ on assembly_line_memory_documents using gin (search_vector);
192
192
 
193
- create table if not exists openeve_file_catalog_records (
193
+ create table if not exists assembly_line_file_catalog_records (
194
194
  id text primary key,
195
- run_id text references openeve_runs(id),
195
+ run_id text references assembly_line_runs(id),
196
196
  path text not null,
197
197
  kind text not null,
198
198
  blob_key text not null,
@@ -202,30 +202,30 @@ create table if not exists openeve_file_catalog_records (
202
202
  created_at timestamptz not null
203
203
  );
204
204
 
205
- create unique index if not exists openeve_file_catalog_records_revision_unique
206
- on openeve_file_catalog_records (run_id, path, sha256);
205
+ create unique index if not exists assembly_line_file_catalog_records_revision_unique
206
+ on assembly_line_file_catalog_records (run_id, path, sha256);
207
207
 
208
- create table if not exists openeve_sandbox_leases (
208
+ create table if not exists assembly_line_sandbox_leases (
209
209
  id text primary key,
210
- run_id text references openeve_runs(id),
210
+ run_id text references assembly_line_runs(id),
211
211
  sandbox_id text not null,
212
212
  status text not null,
213
213
  acquired_at timestamptz not null,
214
214
  released_at timestamptz
215
215
  );
216
216
 
217
- create table if not exists openeve_sandbox_snapshots (
217
+ create table if not exists assembly_line_sandbox_snapshots (
218
218
  id text primary key,
219
- run_id text references openeve_runs(id),
219
+ run_id text references assembly_line_runs(id),
220
220
  sandbox_id text not null,
221
221
  snapshot_id text not null,
222
222
  metadata jsonb not null default '{}'::jsonb,
223
223
  created_at timestamptz not null
224
224
  );
225
225
 
226
- create table if not exists openeve_sandbox_sync_jobs (
226
+ create table if not exists assembly_line_sandbox_sync_jobs (
227
227
  id text primary key,
228
- run_id text not null references openeve_runs(id),
228
+ run_id text not null references assembly_line_runs(id),
229
229
  sandbox_id text not null,
230
230
  status text not null,
231
231
  idempotency_key text not null unique,
@@ -245,18 +245,18 @@ create table if not exists openeve_sandbox_sync_jobs (
245
245
  updated_at timestamptz not null
246
246
  );
247
247
 
248
- create index if not exists openeve_sandbox_sync_jobs_due
249
- on openeve_sandbox_sync_jobs (status, next_attempt_at, created_at);
248
+ create index if not exists assembly_line_sandbox_sync_jobs_due
249
+ on assembly_line_sandbox_sync_jobs (status, next_attempt_at, created_at);
250
250
 
251
- create index if not exists openeve_sandbox_sync_jobs_lease
252
- on openeve_sandbox_sync_jobs (lease_token, lease_expires_at);
251
+ create index if not exists assembly_line_sandbox_sync_jobs_lease
252
+ on assembly_line_sandbox_sync_jobs (lease_token, lease_expires_at);
253
253
 
254
- create index if not exists openeve_sandbox_sync_jobs_run
255
- on openeve_sandbox_sync_jobs (run_id, status);
254
+ create index if not exists assembly_line_sandbox_sync_jobs_run
255
+ on assembly_line_sandbox_sync_jobs (run_id, status);
256
256
 
257
- create table if not exists openeve_usage_records (
257
+ create table if not exists assembly_line_usage_records (
258
258
  id text primary key,
259
- run_id text references openeve_runs(id),
259
+ run_id text references assembly_line_runs(id),
260
260
  model text,
261
261
  input_tokens integer not null default 0,
262
262
  output_tokens integer not null default 0,
@@ -266,9 +266,9 @@ create table if not exists openeve_usage_records (
266
266
  created_at timestamptz not null
267
267
  );
268
268
 
269
- create table if not exists openeve_run_queue (
269
+ create table if not exists assembly_line_run_queue (
270
270
  id text primary key,
271
- run_id text references openeve_runs(id),
271
+ run_id text references assembly_line_runs(id),
272
272
  queue text not null,
273
273
  status text not null,
274
274
  available_at timestamptz not null,
@@ -277,7 +277,7 @@ create table if not exists openeve_run_queue (
277
277
  updated_at timestamptz not null
278
278
  );
279
279
 
280
- create table if not exists openeve_connection_grants (
280
+ create table if not exists assembly_line_connection_grants (
281
281
  connection_name text not null,
282
282
  principal_key text not null,
283
283
  principal jsonb not null,
@@ -291,7 +291,7 @@ create table if not exists openeve_connection_grants (
291
291
  primary key (connection_name, principal_key)
292
292
  );
293
293
 
294
- create table if not exists openeve_connection_authorization_sessions (
294
+ create table if not exists assembly_line_connection_authorization_sessions (
295
295
  id text primary key,
296
296
  state text not null unique,
297
297
  connection_name text not null,
@@ -301,8 +301,8 @@ create table if not exists openeve_connection_authorization_sessions (
301
301
  callback_url text not null,
302
302
  code_verifier text,
303
303
  resume jsonb,
304
- run_id text references openeve_runs(id),
305
- tool_call_id text references openeve_tool_calls(id),
304
+ run_id text references assembly_line_runs(id),
305
+ tool_call_id text references assembly_line_tool_calls(id),
306
306
  tool_name text,
307
307
  challenge jsonb not null default '{}'::jsonb,
308
308
  continuation jsonb,
@@ -312,7 +312,7 @@ create table if not exists openeve_connection_authorization_sessions (
312
312
  updated_at timestamptz not null
313
313
  );
314
314
 
315
- create table if not exists openeve_idempotency_keys (
315
+ create table if not exists assembly_line_idempotency_keys (
316
316
  scope text not null,
317
317
  key text not null,
318
318
  owner_id text,
@@ -322,11 +322,11 @@ create table if not exists openeve_idempotency_keys (
322
322
  `
323
323
  },
324
324
  {
325
- id: "002_openeve_self_improvement",
325
+ id: "002_assembly_line_self_improvement",
326
326
  description: "Durable skills, dynamic schedules, and runtime-provided connection definitions.",
327
327
  expandContractNotes: "Adds independent tables only; no contract phase is required.",
328
328
  sql: `
329
- create table if not exists openeve_skills (
329
+ create table if not exists assembly_line_skills (
330
330
  scope text not null,
331
331
  name text not null,
332
332
  body text not null,
@@ -338,7 +338,7 @@ create table if not exists openeve_skills (
338
338
  primary key (scope, name)
339
339
  );
340
340
 
341
- create table if not exists openeve_dynamic_schedules (
341
+ create table if not exists assembly_line_dynamic_schedules (
342
342
  id text primary key,
343
343
  scope text not null,
344
344
  prompt text not null,
@@ -359,10 +359,10 @@ create table if not exists openeve_dynamic_schedules (
359
359
  updated_at timestamptz not null
360
360
  );
361
361
 
362
- create index if not exists openeve_dynamic_schedules_due
363
- on openeve_dynamic_schedules (enabled, next_run_at);
362
+ create index if not exists assembly_line_dynamic_schedules_due
363
+ on assembly_line_dynamic_schedules (enabled, next_run_at);
364
364
 
365
- create table if not exists openeve_connection_definitions (
365
+ create table if not exists assembly_line_connection_definitions (
366
366
  scope text not null,
367
367
  name text not null,
368
368
  protocol text not null,
@@ -377,14 +377,14 @@ create table if not exists openeve_connection_definitions (
377
377
  `
378
378
  },
379
379
  {
380
- id: "003_openeve_memory_embeddings_pgvector",
380
+ id: "003_assembly_line_memory_embeddings_pgvector",
381
381
  description: "Optional pgvector-backed memory embeddings for semantic search.",
382
382
  expandContractNotes: "Requires the vector extension. Keep gated per deployment and backfill embeddings after enabling.",
383
383
  optional: true,
384
384
  sql: `
385
385
  create extension if not exists vector;
386
386
 
387
- create table if not exists openeve_memory_embeddings (
387
+ create table if not exists assembly_line_memory_embeddings (
388
388
  id text primary key,
389
389
  scope_key text not null,
390
390
  scope jsonb not null,
@@ -400,36 +400,36 @@ create table if not exists openeve_memory_embeddings (
400
400
  unique (scope_key, model)
401
401
  );
402
402
 
403
- create index if not exists openeve_memory_embeddings_scope_model
404
- on openeve_memory_embeddings ((scope->>'agentScope'), model, stale);
403
+ create index if not exists assembly_line_memory_embeddings_scope_model
404
+ on assembly_line_memory_embeddings ((scope->>'agentScope'), model, stale);
405
405
 
406
- create index if not exists openeve_memory_embeddings_path_model
407
- on openeve_memory_embeddings (path, model, content_sha256);
406
+ create index if not exists assembly_line_memory_embeddings_path_model
407
+ on assembly_line_memory_embeddings (path, model, content_sha256);
408
408
 
409
- create index if not exists openeve_memory_embeddings_vector
410
- on openeve_memory_embeddings using ivfflat (embedding vector_cosine_ops);
409
+ create index if not exists assembly_line_memory_embeddings_vector
410
+ on assembly_line_memory_embeddings using ivfflat (embedding vector_cosine_ops);
411
411
  `
412
412
  },
413
413
  {
414
- id: "004_openeve_connection_grant_credentials",
414
+ id: "004_assembly_line_connection_grant_credentials",
415
415
  description: "Adds nullable credential material to connection grants.",
416
416
  expandContractNotes: "Additive nullable column only; existing grants remain valid.",
417
417
  sql: `
418
- alter table openeve_connection_grants
418
+ alter table assembly_line_connection_grants
419
419
  add column if not exists credential jsonb;
420
420
  `
421
421
  },
422
422
  {
423
- id: "005_openeve_sandbox_sessions",
423
+ id: "005_assembly_line_sandbox_sessions",
424
424
  description: "Durable sandbox session records for warm reconnect, dirty retention, and async sync diagnostics.",
425
425
  expandContractNotes: "Additive table and indexes only; foreground runtime paths use tiny upserts while async workers perform filesystem writeback.",
426
426
  sql: `
427
- create table if not exists openeve_sandbox_sessions (
427
+ create table if not exists assembly_line_sandbox_sessions (
428
428
  id text primary key,
429
429
  session_key text not null unique,
430
430
  provider text not null,
431
431
  sandbox_id text not null,
432
- run_id text references openeve_runs(id),
432
+ run_id text references assembly_line_runs(id),
433
433
  root text,
434
434
  state text not null,
435
435
  dirty boolean not null default false,
@@ -443,30 +443,30 @@ create table if not exists openeve_sandbox_sessions (
443
443
  updated_at timestamptz not null
444
444
  );
445
445
 
446
- create index if not exists openeve_sandbox_sessions_dirty
447
- on openeve_sandbox_sessions (dirty, updated_at);
446
+ create index if not exists assembly_line_sandbox_sessions_dirty
447
+ on assembly_line_sandbox_sessions (dirty, updated_at);
448
448
 
449
- create index if not exists openeve_sandbox_sessions_provider_state
450
- on openeve_sandbox_sessions (provider, state, last_seen_at);
449
+ create index if not exists assembly_line_sandbox_sessions_provider_state
450
+ on assembly_line_sandbox_sessions (provider, state, last_seen_at);
451
451
  `
452
452
  },
453
453
  {
454
- id: "006_openeve_dynamic_schedule_triggers",
454
+ id: "006_assembly_line_dynamic_schedule_triggers",
455
455
  description: "Add trigger lifecycle metadata to dynamic schedules.",
456
456
  expandContractNotes: "Additive nullable columns only; older dynamic schedule rows keep using prompt-only dispatch.",
457
457
  sql: `
458
- alter table if exists openeve_dynamic_schedules
458
+ alter table if exists assembly_line_dynamic_schedules
459
459
  add column if not exists message text,
460
460
  add column if not exists project_id text,
461
461
  add column if not exists trigger jsonb;
462
462
  `
463
463
  },
464
464
  {
465
- id: "007_openeve_delivery_queue",
465
+ id: "007_assembly_line_delivery_queue",
466
466
  description: "Durable delivery queue lease/retry columns, due index, and run status sweep index for orphan recovery.",
467
467
  expandContractNotes: "Additive columns with defaults and new indexes only. Delivery rows created before this migration are normalized on read (next_attempt_at backfilled from created_at).",
468
468
  sql: `
469
- alter table if exists openeve_delivery_obligations
469
+ alter table if exists assembly_line_delivery_obligations
470
470
  add column if not exists attempt_count integer not null default 0,
471
471
  add column if not exists max_attempts integer not null default 5,
472
472
  add column if not exists next_attempt_at timestamptz,
@@ -476,40 +476,40 @@ alter table if exists openeve_delivery_obligations
476
476
  add column if not exists sent_at timestamptz,
477
477
  add column if not exists failed_at timestamptz;
478
478
 
479
- update openeve_delivery_obligations set next_attempt_at = created_at where next_attempt_at is null;
479
+ update assembly_line_delivery_obligations set next_attempt_at = created_at where next_attempt_at is null;
480
480
 
481
- create index if not exists openeve_delivery_obligations_due
482
- on openeve_delivery_obligations (status, next_attempt_at, created_at)
481
+ create index if not exists assembly_line_delivery_obligations_due
482
+ on assembly_line_delivery_obligations (status, next_attempt_at, created_at)
483
483
  where status in ('pending', 'sending');
484
484
 
485
- create index if not exists openeve_delivery_obligations_lease
486
- on openeve_delivery_obligations (lease_token, lease_expires_at);
485
+ create index if not exists assembly_line_delivery_obligations_lease
486
+ on assembly_line_delivery_obligations (lease_token, lease_expires_at);
487
487
 
488
- create index if not exists openeve_runs_status_updated
489
- on openeve_runs (status, updated_at);
488
+ create index if not exists assembly_line_runs_status_updated
489
+ on assembly_line_runs (status, updated_at);
490
490
  `
491
491
  },
492
492
  {
493
- id: "008_openeve_checkpoint_retention",
493
+ id: "008_assembly_line_checkpoint_retention",
494
494
  description: "Indexes for bounded checkpoint retention and operator cleanup.",
495
495
  expandContractNotes: "Additive indexes only. Checkpoint pruning remains explicit operator maintenance.",
496
496
  sql: `
497
- create index if not exists openeve_checkpoints_run_name_created
498
- on openeve_checkpoints (run_id, name, created_at desc);
497
+ create index if not exists assembly_line_checkpoints_run_name_created
498
+ on assembly_line_checkpoints (run_id, name, created_at desc);
499
499
 
500
- create index if not exists openeve_checkpoints_created
501
- on openeve_checkpoints (created_at);
500
+ create index if not exists assembly_line_checkpoints_created
501
+ on assembly_line_checkpoints (created_at);
502
502
  `
503
503
  },
504
504
  {
505
- id: "009_openeve_runtime_controls",
505
+ id: "009_assembly_line_runtime_controls",
506
506
  description: "Durable run control intents, scoped runtime settings, and operator audit events.",
507
507
  expandContractNotes: "Additive nullable column and new tables only; older runtimes ignore them safely during rolling upgrades.",
508
508
  sql: `
509
- alter table if exists openeve_runs
509
+ alter table if exists assembly_line_runs
510
510
  add column if not exists control_intent text;
511
511
 
512
- create table if not exists openeve_runtime_settings (
512
+ create table if not exists assembly_line_runtime_settings (
513
513
  scope text not null,
514
514
  key text not null,
515
515
  value jsonb not null,
@@ -517,7 +517,7 @@ create table if not exists openeve_runtime_settings (
517
517
  primary key (scope, key)
518
518
  );
519
519
 
520
- create table if not exists openeve_runtime_control_events (
520
+ create table if not exists assembly_line_runtime_control_events (
521
521
  id text primary key,
522
522
  scope text not null,
523
523
  type text not null,
@@ -525,49 +525,49 @@ create table if not exists openeve_runtime_control_events (
525
525
  created_at timestamptz not null
526
526
  );
527
527
 
528
- create index if not exists openeve_runtime_control_events_scope_created
529
- on openeve_runtime_control_events (scope, created_at);
528
+ create index if not exists assembly_line_runtime_control_events_scope_created
529
+ on assembly_line_runtime_control_events (scope, created_at);
530
530
  `
531
531
  },
532
532
  {
533
- id: "010_openeve_direct_conversations",
533
+ id: "010_assembly_line_direct_conversations",
534
534
  description: "Stable agent scoping, titles, archiving, and cursor indexes for direct conversation clients.",
535
535
  expandContractNotes: "Additive nullable columns and indexes only. Existing conversations are backfilled from their earliest associated run when possible.",
536
536
  sql: `
537
- alter table if exists openeve_conversations
537
+ alter table if exists assembly_line_conversations
538
538
  add column if not exists agent_scope text,
539
539
  add column if not exists agent_revision text,
540
540
  add column if not exists title text,
541
541
  add column if not exists archived_at timestamptz;
542
542
 
543
- update openeve_conversations conversation
543
+ update assembly_line_conversations conversation
544
544
  set agent_revision = (
545
545
  select run.agent_revision
546
- from openeve_messages message
547
- join openeve_runs run on run.id = message.run_id
546
+ from assembly_line_messages message
547
+ join assembly_line_runs run on run.id = message.run_id
548
548
  where message.conversation_id = conversation.id
549
549
  order by message.created_at asc
550
550
  limit 1
551
551
  )
552
552
  where conversation.agent_revision is null;
553
553
 
554
- update openeve_conversations
554
+ update assembly_line_conversations
555
555
  set agent_scope = coalesce(agent_scope, agent_revision, agent_id)
556
556
  where agent_scope is null;
557
557
 
558
- create index if not exists openeve_conversations_scope_channel_updated
559
- on openeve_conversations (agent_scope, channel, updated_at desc, id desc);
558
+ create index if not exists assembly_line_conversations_scope_channel_updated
559
+ on assembly_line_conversations (agent_scope, channel, updated_at desc, id desc);
560
560
 
561
- create index if not exists openeve_messages_conversation_created
562
- on openeve_messages (conversation_id, created_at desc, id desc);
561
+ create index if not exists assembly_line_messages_conversation_created
562
+ on assembly_line_messages (conversation_id, created_at desc, id desc);
563
563
  `
564
564
  },
565
565
  {
566
- id: "011_openeve_usage_accounting",
566
+ id: "011_assembly_line_usage_accounting",
567
567
  description: "Source-backed idempotent usage ledger, exact monetary fields, provenance, and query indexes.",
568
568
  expandContractNotes: "Adds observational accounting columns, marks legacy cash unavailable rather than estimating it, and widens token counters. The legacy cost_usd column remains for rolling compatibility but is not authoritative.",
569
569
  sql: `
570
- alter table if exists openeve_usage_records
570
+ alter table if exists assembly_line_usage_records
571
571
  alter column input_tokens type bigint,
572
572
  alter column output_tokens type bigint,
573
573
  alter column cached_tokens type bigint,
@@ -594,14 +594,14 @@ alter table if exists openeve_usage_records
594
594
  add column if not exists receipt_sha256 text,
595
595
  add column if not exists occurred_at timestamptz;
596
596
 
597
- update openeve_usage_records
597
+ update assembly_line_usage_records
598
598
  set idempotency_key = coalesce(idempotency_key, 'legacy:' || id),
599
599
  cost_micros = null,
600
600
  cost_source = 'unavailable',
601
601
  occurred_at = coalesce(occurred_at, created_at)
602
602
  where idempotency_key is null or occurred_at is null;
603
603
 
604
- update openeve_usage_records
604
+ update assembly_line_usage_records
605
605
  set input_tokens = 0,
606
606
  output_tokens = 0,
607
607
  cached_tokens = 0,
@@ -610,52 +610,52 @@ set input_tokens = 0,
610
610
  token_source = 'unavailable'
611
611
  where token_source not in ('provider_reported', 'provider_reconciled');
612
612
 
613
- update openeve_usage_records
613
+ update assembly_line_usage_records
614
614
  set cost_micros = null,
615
615
  upstream_cost_micros = null,
616
616
  cost_source = 'unavailable'
617
617
  where cost_source not in ('provider_reported', 'provider_reconciled');
618
618
 
619
- alter table if exists openeve_usage_records
619
+ alter table if exists assembly_line_usage_records
620
620
  alter column idempotency_key set not null,
621
621
  alter column occurred_at set not null;
622
622
 
623
- create unique index if not exists openeve_usage_records_idempotency
624
- on openeve_usage_records (idempotency_key);
623
+ create unique index if not exists assembly_line_usage_records_idempotency
624
+ on assembly_line_usage_records (idempotency_key);
625
625
 
626
- create index if not exists openeve_usage_records_occurred
627
- on openeve_usage_records (occurred_at desc, id desc);
626
+ create index if not exists assembly_line_usage_records_occurred
627
+ on assembly_line_usage_records (occurred_at desc, id desc);
628
628
 
629
- create index if not exists openeve_usage_records_agent_occurred
630
- on openeve_usage_records (agent_id, occurred_at desc);
629
+ create index if not exists assembly_line_usage_records_agent_occurred
630
+ on assembly_line_usage_records (agent_id, occurred_at desc);
631
631
 
632
- create index if not exists openeve_usage_records_run_occurred
633
- on openeve_usage_records (run_id, occurred_at);
632
+ create index if not exists assembly_line_usage_records_run_occurred
633
+ on assembly_line_usage_records (run_id, occurred_at);
634
634
 
635
- create index if not exists openeve_usage_records_provider_request
636
- on openeve_usage_records (provider, provider_request_id)
635
+ create index if not exists assembly_line_usage_records_provider_request
636
+ on assembly_line_usage_records (provider, provider_request_id)
637
637
  where provider_request_id is not null;
638
638
  `
639
639
  },
640
640
  {
641
- id: "012_openeve_run_terminal_outcome",
641
+ id: "012_assembly_line_run_terminal_outcome",
642
642
  description: "Queryable terminal reason/error on runs and poison-schedule failure tracking.",
643
643
  expandContractNotes: "Additive nullable columns only; older runtimes ignore them safely during rolling upgrades.",
644
644
  sql: `
645
- alter table if exists openeve_runs
645
+ alter table if exists assembly_line_runs
646
646
  add column if not exists terminal_reason text,
647
647
  add column if not exists terminal_error text;
648
648
 
649
- alter table if exists openeve_dynamic_schedules
649
+ alter table if exists assembly_line_dynamic_schedules
650
650
  add column if not exists consecutive_failures integer not null default 0;
651
651
  `
652
652
  },
653
653
  {
654
- id: "013_openeve_conversation_turn_mailbox",
654
+ id: "013_assembly_line_conversation_turn_mailbox",
655
655
  description: "Durable per-conversation FIFO ingress mailbox with cross-replica active-turn exclusion.",
656
656
  expandContractNotes: "Adds a new mailbox table and indexes only; older runtimes ignore it safely during rolling upgrades.",
657
657
  sql: `
658
- create table if not exists openeve_conversation_turns (
658
+ create table if not exists assembly_line_conversation_turns (
659
659
  id text primary key,
660
660
  enqueue_sequence bigserial not null,
661
661
  agent_scope text not null,
@@ -666,7 +666,7 @@ create table if not exists openeve_conversation_turns (
666
666
  idempotency_scope text not null,
667
667
  idempotency_key text not null,
668
668
  status text not null,
669
- run_id text references openeve_runs(id),
669
+ run_id text references assembly_line_runs(id),
670
670
  attempt_count integer not null default 0,
671
671
  max_attempts integer not null default 5,
672
672
  next_attempt_at timestamptz not null,
@@ -678,16 +678,483 @@ create table if not exists openeve_conversation_turns (
678
678
  unique (agent_scope, idempotency_scope, idempotency_key)
679
679
  );
680
680
 
681
- create unique index if not exists openeve_conversation_turns_one_active
682
- on openeve_conversation_turns (agent_scope, conversation_id)
681
+ create unique index if not exists assembly_line_conversation_turns_one_active
682
+ on assembly_line_conversation_turns (agent_scope, conversation_id)
683
683
  where status in ('running', 'blocked');
684
684
 
685
- create index if not exists openeve_conversation_turns_ready
686
- on openeve_conversation_turns (agent_scope, status, next_attempt_at, enqueue_sequence);
685
+ create index if not exists assembly_line_conversation_turns_ready
686
+ on assembly_line_conversation_turns (agent_scope, status, next_attempt_at, enqueue_sequence);
687
687
 
688
- create index if not exists openeve_conversation_turns_run
689
- on openeve_conversation_turns (run_id)
688
+ create index if not exists assembly_line_conversation_turns_run
689
+ on assembly_line_conversation_turns (run_id)
690
690
  where run_id is not null;
691
+ `
692
+ },
693
+ {
694
+ id: "014_assembly_line_agent_state",
695
+ description: "Conversation-scoped durable agent hook state with aggregate revisions and compare-and-set support.",
696
+ expandContractNotes: "Adds isolated control-plane state tables and indexes only; no existing semantic memory or runtime settings are reused.",
697
+ sql: `
698
+ create table if not exists assembly_line_agent_state_scopes (
699
+ agent_scope text not null,
700
+ conversation_id text not null,
701
+ revision bigint not null default 0,
702
+ created_at timestamptz not null,
703
+ updated_at timestamptz not null,
704
+ primary key (agent_scope, conversation_id)
705
+ );
706
+
707
+ create table if not exists assembly_line_agent_state (
708
+ agent_scope text not null,
709
+ conversation_id text not null,
710
+ key text not null,
711
+ value jsonb not null,
712
+ revision bigint not null,
713
+ created_at timestamptz not null,
714
+ updated_at timestamptz not null,
715
+ primary key (agent_scope, conversation_id, key),
716
+ foreign key (agent_scope, conversation_id)
717
+ references assembly_line_agent_state_scopes(agent_scope, conversation_id)
718
+ on delete cascade
719
+ );
720
+
721
+ create index if not exists assembly_line_agent_state_conversation_revision
722
+ on assembly_line_agent_state (agent_scope, conversation_id, revision);
723
+ `
724
+ },
725
+ {
726
+ id: "015_assembly_line_background_learning",
727
+ description: "Append-only skill revisions, separate pending skill changes, and durable background review jobs.",
728
+ expandContractNotes: "Adds isolated learning tables and additive skill metadata columns; legacy pending rows remain readable.",
729
+ sql: `
730
+ alter table assembly_line_skills add column if not exists revision bigint;
731
+ alter table assembly_line_skills add column if not exists archived boolean not null default false;
732
+
733
+ create table if not exists assembly_line_skill_revisions (
734
+ id text primary key,
735
+ scope text not null,
736
+ name text not null,
737
+ revision bigint not null,
738
+ action text not null,
739
+ body text not null,
740
+ body_sha256 text not null,
741
+ origin text not null,
742
+ previous_revision bigint,
743
+ source_run_id text,
744
+ review_job_id text,
745
+ created_at timestamptz not null,
746
+ unique (scope, name, revision)
747
+ );
748
+
749
+ create index if not exists assembly_line_skill_revisions_skill
750
+ on assembly_line_skill_revisions (scope, name, revision);
751
+
752
+ create table if not exists assembly_line_pending_skill_changes (
753
+ id text primary key,
754
+ scope text not null,
755
+ name text not null,
756
+ action text not null,
757
+ revision_action text,
758
+ body text,
759
+ origin text not null,
760
+ source_run_id text,
761
+ review_job_id text,
762
+ created_at timestamptz not null
763
+ );
764
+
765
+ create index if not exists assembly_line_pending_skill_changes_scope
766
+ on assembly_line_pending_skill_changes (scope, created_at);
767
+
768
+ create table if not exists assembly_line_background_review_jobs (
769
+ id text primary key,
770
+ scope text not null,
771
+ source_run_id text not null,
772
+ idempotency_key text not null,
773
+ reasons jsonb not null default '[]'::jsonb,
774
+ status text not null,
775
+ attempt_count integer not null default 0,
776
+ max_attempts integer not null default 3,
777
+ next_attempt_at timestamptz not null,
778
+ lease_token text,
779
+ lease_expires_at timestamptz,
780
+ review_run_id text,
781
+ last_error text,
782
+ created_at timestamptz not null,
783
+ updated_at timestamptz not null,
784
+ unique (scope, idempotency_key)
785
+ );
786
+
787
+ create index if not exists assembly_line_background_review_jobs_due
788
+ on assembly_line_background_review_jobs (status, next_attempt_at);
789
+ `
790
+ },
791
+ {
792
+ id: "016_assembly_line_file_index_dedupe",
793
+ description: "File index uniqueness matching runtime dedupe semantics: NULL run_id participates and catalog records include kind.",
794
+ expandContractNotes: "Requires Postgres 15+ (nulls not distinct). Collapses accumulated NULL-run_id duplicates, then replaces the unique indexes; recordFileIndex conflict targets switch in the same release.",
795
+ sql: `
796
+ delete from assembly_line_memory_file_indexes a
797
+ using assembly_line_memory_file_indexes b
798
+ where a.run_id is not distinct from b.run_id
799
+ and a.path = b.path
800
+ and a.sha256 = b.sha256
801
+ and a.ctid > b.ctid;
802
+
803
+ drop index if exists assembly_line_memory_file_indexes_revision_unique;
804
+
805
+ create unique index if not exists assembly_line_memory_file_indexes_dedupe
806
+ on assembly_line_memory_file_indexes (run_id, path, sha256) nulls not distinct;
807
+
808
+ delete from assembly_line_file_catalog_records a
809
+ using assembly_line_file_catalog_records b
810
+ where a.run_id is not distinct from b.run_id
811
+ and a.path = b.path
812
+ and a.kind = b.kind
813
+ and a.sha256 = b.sha256
814
+ and a.ctid > b.ctid;
815
+
816
+ drop index if exists assembly_line_file_catalog_records_revision_unique;
817
+
818
+ create unique index if not exists assembly_line_file_catalog_records_dedupe
819
+ on assembly_line_file_catalog_records (run_id, path, kind, sha256) nulls not distinct;
820
+ `
821
+ },
822
+ {
823
+ id: "017_assembly_line_agent_state_text_equality",
824
+ description: "Canonical JSON text alongside agent-state jsonb values so changed-detection matches JSON.stringify equality across state backends.",
825
+ expandContractNotes: "Additive nullable column backfilled from the jsonb value. Rows written before this migration may report one spurious changed=true while their text form converges to the runtime's serialization.",
826
+ sql: `
827
+ alter table assembly_line_agent_state
828
+ add column if not exists value_text text;
829
+
830
+ update assembly_line_agent_state
831
+ set value_text = value::text
832
+ where value_text is null;
833
+ `
834
+ },
835
+ {
836
+ id: "018_assembly_line_memory_scope_key_canonicalization",
837
+ description: "Recompute memory document and embedding scope_key values from stored scope JSON so exact-key lookups match rows written under earlier key-escaping schemes.",
838
+ expandContractNotes: "Rows written by older adapters can carry a scope_key that today's postgresMemoryKey never produces; key lookups (get/delete) then miss rows that JSON-scope listing finds, and a re-save inserts a duplicate row instead of upserting. Recomputes every key with the current escaping (% -> %25 before : -> %3A, missing scope fields as *), keeping the newest row when two rows collapse onto one canonical key.",
839
+ sql: `
840
+ delete from assembly_line_memory_documents a
841
+ using assembly_line_memory_documents b
842
+ where replace(replace(a.scope->>'agentScope', '%', '%25'), ':', '%3A')
843
+ || ':' || coalesce(replace(replace(a.scope->>'userId', '%', '%25'), ':', '%3A'), '*')
844
+ || ':' || coalesce(replace(replace(a.scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
845
+ || ':' || coalesce(replace(replace(a.scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
846
+ || ':' || a.path
847
+ = replace(replace(b.scope->>'agentScope', '%', '%25'), ':', '%3A')
848
+ || ':' || coalesce(replace(replace(b.scope->>'userId', '%', '%25'), ':', '%3A'), '*')
849
+ || ':' || coalesce(replace(replace(b.scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
850
+ || ':' || coalesce(replace(replace(b.scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
851
+ || ':' || b.path
852
+ and (a.updated_at, a.ctid) < (b.updated_at, b.ctid);
853
+
854
+ update assembly_line_memory_documents
855
+ set scope_key = replace(replace(scope->>'agentScope', '%', '%25'), ':', '%3A')
856
+ || ':' || coalesce(replace(replace(scope->>'userId', '%', '%25'), ':', '%3A'), '*')
857
+ || ':' || coalesce(replace(replace(scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
858
+ || ':' || coalesce(replace(replace(scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
859
+ || ':' || path
860
+ where scope_key is distinct from replace(replace(scope->>'agentScope', '%', '%25'), ':', '%3A')
861
+ || ':' || coalesce(replace(replace(scope->>'userId', '%', '%25'), ':', '%3A'), '*')
862
+ || ':' || coalesce(replace(replace(scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
863
+ || ':' || coalesce(replace(replace(scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
864
+ || ':' || path;
865
+
866
+ do $$
867
+ begin
868
+ -- The embeddings table only exists when the optional pgvector migration ran.
869
+ if to_regclass('assembly_line_memory_embeddings') is null then return; end if;
870
+
871
+ delete from assembly_line_memory_embeddings a
872
+ using assembly_line_memory_embeddings b
873
+ where a.model = b.model
874
+ and replace(replace(a.scope->>'agentScope', '%', '%25'), ':', '%3A')
875
+ || ':' || coalesce(replace(replace(a.scope->>'userId', '%', '%25'), ':', '%3A'), '*')
876
+ || ':' || coalesce(replace(replace(a.scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
877
+ || ':' || coalesce(replace(replace(a.scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
878
+ || ':' || a.path
879
+ = replace(replace(b.scope->>'agentScope', '%', '%25'), ':', '%3A')
880
+ || ':' || coalesce(replace(replace(b.scope->>'userId', '%', '%25'), ':', '%3A'), '*')
881
+ || ':' || coalesce(replace(replace(b.scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
882
+ || ':' || coalesce(replace(replace(b.scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
883
+ || ':' || b.path
884
+ and (a.updated_at, a.ctid) < (b.updated_at, b.ctid);
885
+
886
+ update assembly_line_memory_embeddings
887
+ set scope_key = replace(replace(scope->>'agentScope', '%', '%25'), ':', '%3A')
888
+ || ':' || coalesce(replace(replace(scope->>'userId', '%', '%25'), ':', '%3A'), '*')
889
+ || ':' || coalesce(replace(replace(scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
890
+ || ':' || coalesce(replace(replace(scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
891
+ || ':' || path
892
+ where scope_key is distinct from replace(replace(scope->>'agentScope', '%', '%25'), ':', '%3A')
893
+ || ':' || coalesce(replace(replace(scope->>'userId', '%', '%25'), ':', '%3A'), '*')
894
+ || ':' || coalesce(replace(replace(scope->>'conversationId', '%', '%25'), ':', '%3A'), '*')
895
+ || ':' || coalesce(replace(replace(scope->>'projectId', '%', '%25'), ':', '%3A'), '*')
896
+ || ':' || path;
897
+ end
898
+ $$;
899
+ `
900
+ },
901
+ {
902
+ id: "019_assembly_line_versioned_workspaces",
903
+ description: "Provider-neutral workspace identities, immutable versions, and named checkpoints.",
904
+ sql: `
905
+ create table if not exists assembly_line_workspaces (
906
+ id text primary key,
907
+ scope_key text not null unique,
908
+ scope jsonb not null,
909
+ head_version_id text,
910
+ source_workspace_id text references assembly_line_workspaces(id),
911
+ source_version_id text,
912
+ name text,
913
+ metadata jsonb not null default '{}'::jsonb,
914
+ created_at timestamptz not null,
915
+ updated_at timestamptz not null
916
+ );
917
+
918
+ create index if not exists assembly_line_workspaces_agent_scope
919
+ on assembly_line_workspaces ((scope->>'agentScope'), updated_at desc);
920
+
921
+ create table if not exists assembly_line_workspace_versions (
922
+ id text primary key,
923
+ workspace_id text not null references assembly_line_workspaces(id) on delete cascade,
924
+ parent_version_id text references assembly_line_workspace_versions(id),
925
+ source_version_id text,
926
+ source_checkpoint_id text,
927
+ manifest_blob_key text not null,
928
+ manifest_sha256 text not null,
929
+ file_count integer not null,
930
+ total_bytes bigint not null,
931
+ reason text not null,
932
+ run_id text references assembly_line_runs(id),
933
+ idempotency_key text not null unique,
934
+ metadata jsonb not null default '{}'::jsonb,
935
+ created_at timestamptz not null
936
+ );
937
+
938
+ create index if not exists assembly_line_workspace_versions_workspace_created
939
+ on assembly_line_workspace_versions (workspace_id, created_at desc);
940
+
941
+ create table if not exists assembly_line_workspace_checkpoints (
942
+ id text primary key,
943
+ workspace_id text not null references assembly_line_workspaces(id) on delete cascade,
944
+ name text not null,
945
+ version_id text not null references assembly_line_workspace_versions(id),
946
+ created_at timestamptz not null,
947
+ updated_at timestamptz not null,
948
+ unique (workspace_id, name)
949
+ );
950
+
951
+ create index if not exists assembly_line_workspace_checkpoints_version
952
+ on assembly_line_workspace_checkpoints (version_id);
953
+ `
954
+ },
955
+ {
956
+ id: "020_assembly_line_workspace_search",
957
+ description: "Versioned workspace text chunks and full-text search indexes.",
958
+ sql: `
959
+ create table if not exists assembly_line_workspace_search_chunks (
960
+ id text primary key,
961
+ workspace_id text not null references assembly_line_workspaces(id) on delete cascade,
962
+ version_id text not null references assembly_line_workspace_versions(id) on delete cascade,
963
+ path text not null,
964
+ start_line integer not null,
965
+ end_line integer not null,
966
+ content text not null,
967
+ content_sha256 text not null,
968
+ content_type text not null,
969
+ embedding jsonb,
970
+ embedding_model text,
971
+ metadata jsonb not null default '{}'::jsonb,
972
+ search_vector tsvector generated always as (
973
+ setweight(to_tsvector('simple', coalesce(path, '')), 'A') ||
974
+ setweight(to_tsvector('simple', coalesce(content, '')), 'B')
975
+ ) stored,
976
+ created_at timestamptz not null,
977
+ unique (workspace_id, version_id, path, start_line)
978
+ );
979
+
980
+ create index if not exists assembly_line_workspace_search_chunks_version
981
+ on assembly_line_workspace_search_chunks (workspace_id, version_id, path, start_line);
982
+
983
+ create index if not exists assembly_line_workspace_search_chunks_vector
984
+ on assembly_line_workspace_search_chunks using gin (search_vector);
985
+
986
+ create table if not exists assembly_line_workspace_search_indexes (
987
+ workspace_id text primary key references assembly_line_workspaces(id) on delete cascade,
988
+ version_id text not null references assembly_line_workspace_versions(id) on delete cascade,
989
+ chunk_count integer not null,
990
+ embedding_model text,
991
+ indexed_at timestamptz not null
992
+ );
993
+ `
994
+ },
995
+ {
996
+ id: "021_assembly_line_workspace_embeddings_pgvector",
997
+ description: "Optional pgvector-backed workspace chunk embeddings for semantic search.",
998
+ expandContractNotes: "Requires the vector extension. Keep gated per deployment and reindex workspace heads after enabling.",
999
+ optional: true,
1000
+ sql: `
1001
+ create extension if not exists vector;
1002
+
1003
+ create table if not exists assembly_line_workspace_search_embeddings (
1004
+ chunk_id text primary key references assembly_line_workspace_search_chunks(id) on delete cascade,
1005
+ workspace_id text not null references assembly_line_workspaces(id) on delete cascade,
1006
+ version_id text not null references assembly_line_workspace_versions(id) on delete cascade,
1007
+ model text not null,
1008
+ dimensions integer not null,
1009
+ embedding vector not null,
1010
+ created_at timestamptz not null
1011
+ );
1012
+
1013
+ create index if not exists assembly_line_workspace_search_embeddings_scope
1014
+ on assembly_line_workspace_search_embeddings (workspace_id, version_id, model);
1015
+
1016
+ create index if not exists assembly_line_workspace_search_embeddings_vector
1017
+ on assembly_line_workspace_search_embeddings using ivfflat (embedding vector_cosine_ops);
1018
+ `
1019
+ },
1020
+ {
1021
+ id: "022_assembly_line_workspace_version_pruning",
1022
+ description: "Allow retained workspace histories to prune an ancestor without deleting its descendants.",
1023
+ sql: `
1024
+ alter table assembly_line_workspace_versions
1025
+ drop constraint if exists assembly_line_workspace_versions_parent_version_id_fkey;
1026
+
1027
+ alter table assembly_line_workspace_versions
1028
+ add constraint assembly_line_workspace_versions_parent_version_id_fkey
1029
+ foreign key (parent_version_id)
1030
+ references assembly_line_workspace_versions(id)
1031
+ on delete set null;
1032
+ `
1033
+ },
1034
+ {
1035
+ id: "023_assembly_line_message_search",
1036
+ description: "Full-text search over attributed conversation and ambient channel messages.",
1037
+ sql: `
1038
+ alter table assembly_line_messages
1039
+ add column if not exists search_vector tsvector generated always as (
1040
+ to_tsvector('simple', coalesce(content->>'text', ''))
1041
+ ) stored;
1042
+
1043
+ create index if not exists assembly_line_messages_search_vector
1044
+ on assembly_line_messages using gin (search_vector);
1045
+ `
1046
+ },
1047
+ {
1048
+ id: "024_assembly_line_connection_events",
1049
+ description: "Provider event registrations and the durable inbound connection event inbox.",
1050
+ sql: `
1051
+ create table if not exists assembly_line_connection_event_registrations (
1052
+ connection_name text not null,
1053
+ provider text not null,
1054
+ principal_key text not null,
1055
+ principal jsonb not null,
1056
+ binding_id text not null,
1057
+ callback_url text not null,
1058
+ selected_events jsonb not null default '[]'::jsonb,
1059
+ resources jsonb not null default '[]'::jsonb,
1060
+ desired_hash text not null,
1061
+ status text not null,
1062
+ external_id text,
1063
+ state jsonb,
1064
+ expires_at timestamptz,
1065
+ instructions text,
1066
+ detail text,
1067
+ created_at timestamptz not null,
1068
+ updated_at timestamptz not null,
1069
+ primary key (connection_name, principal_key),
1070
+ unique (connection_name, binding_id)
1071
+ );
1072
+
1073
+ create index if not exists assembly_line_connection_event_registrations_expiry
1074
+ on assembly_line_connection_event_registrations (expires_at)
1075
+ where status='active' and expires_at is not null;
1076
+
1077
+ create table if not exists assembly_line_connection_event_inbox (
1078
+ id text primary key,
1079
+ connection_name text not null,
1080
+ provider text not null,
1081
+ principal_key text not null,
1082
+ event_id text not null,
1083
+ event jsonb not null,
1084
+ status text not null,
1085
+ attempt_count integer not null default 0,
1086
+ max_attempts integer not null default 8,
1087
+ next_attempt_at timestamptz not null,
1088
+ lease_token text,
1089
+ lease_expires_at timestamptz,
1090
+ last_error text,
1091
+ created_at timestamptz not null,
1092
+ updated_at timestamptz not null,
1093
+ unique (connection_name, principal_key, event_id)
1094
+ );
1095
+
1096
+ create index if not exists assembly_line_connection_event_inbox_due
1097
+ on assembly_line_connection_event_inbox (status, next_attempt_at, created_at);
1098
+ `
1099
+ },
1100
+ {
1101
+ id: "025_assembly_line_run_delivery_outcome",
1102
+ description: "Queryable user-visible delivery outcome on run summaries.",
1103
+ expandContractNotes: "Additive nullable columns only; older runtimes ignore them safely during rolling upgrades.",
1104
+ sql: `
1105
+ alter table if exists assembly_line_runs
1106
+ add column if not exists delivery_status text,
1107
+ add column if not exists delivery_error text,
1108
+ add column if not exists delivery_attempts integer;
1109
+ `
1110
+ },
1111
+ {
1112
+ id: "026_assembly_line_workspace_files",
1113
+ description: "Workspace-scoped durable file catalog records for cross-run discovery and mounting.",
1114
+ sql: `
1115
+ alter table if exists assembly_line_file_catalog_records
1116
+ add column if not exists workspace_id text references assembly_line_workspaces(id) on delete cascade;
1117
+
1118
+ update assembly_line_file_catalog_records file
1119
+ set workspace_id = workspace.id
1120
+ from assembly_line_runs run
1121
+ join assembly_line_workspaces workspace
1122
+ on workspace.id = nullif(run.input->>'workspaceId', '')
1123
+ where file.run_id = run.id
1124
+ and file.workspace_id is null;
1125
+
1126
+ update assembly_line_file_catalog_records file
1127
+ set workspace_id = workspace.id
1128
+ from assembly_line_runs run
1129
+ join assembly_line_conversations conversation
1130
+ on conversation.id = nullif(run.input->>'conversationId', '')
1131
+ join assembly_line_workspaces workspace
1132
+ on workspace.scope->>'kind' = 'conversation'
1133
+ and workspace.scope->>'scopeId' = conversation.id
1134
+ and workspace.scope->>'agentScope' = conversation.agent_scope
1135
+ and coalesce(workspace.scope->>'tenantId', '') = coalesce(run.input->>'tenantId', '')
1136
+ where file.run_id = run.id
1137
+ and file.workspace_id is null
1138
+ and nullif(run.input->>'workspaceId', '') is null
1139
+ and nullif(run.input->>'projectId', '') is null;
1140
+
1141
+ update assembly_line_file_catalog_records file
1142
+ set workspace_id = workspace.id
1143
+ from assembly_line_runs run
1144
+ left join assembly_line_conversations conversation
1145
+ on conversation.id = nullif(run.input->>'conversationId', '')
1146
+ join assembly_line_workspaces workspace
1147
+ on workspace.scope->>'kind' = 'project'
1148
+ and workspace.scope->>'scopeId' = nullif(run.input->>'projectId', '')
1149
+ and workspace.scope->>'agentScope' = coalesce(conversation.agent_scope, run.agent_revision)
1150
+ and coalesce(workspace.scope->>'tenantId', '') = coalesce(run.input->>'tenantId', '')
1151
+ where file.run_id = run.id
1152
+ and file.workspace_id is null
1153
+ and nullif(run.input->>'workspaceId', '') is null;
1154
+
1155
+ create index if not exists assembly_line_file_catalog_records_workspace_created
1156
+ on assembly_line_file_catalog_records (workspace_id, created_at desc)
1157
+ where workspace_id is not null;
691
1158
  `
692
1159
  }
693
1160
  ];