@nurix/nustack 0.24.0 → 0.25.1
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/commands/desktopAgent.js +1 -1
- package/dist/commands/doctor.js +8 -11
- package/dist/commands/obligationList.js +23 -49
- package/dist/commands/records.js +6 -88
- package/dist/commands/store.js +199 -0
- package/dist/commands/sync.js +2 -2
- package/dist/commands/toolkit.js +2 -2
- package/dist/lib/context/register.js +1 -1
- package/dist/lib/desktop-agents/checkout.js +1 -1
- package/dist/lib/desktop-agents/claudeRun.js +4 -4
- package/dist/lib/etna/reconcile.js +4 -4
- package/dist/lib/graph/library.js +1 -1
- package/dist/lib/harness/hookCheck.js +2 -8
- package/dist/lib/harness/storeWaivers.js +1 -4
- package/dist/lib/local_store/database.js +12 -92
- package/dist/lib/local_store/device_state.js +2 -2
- package/dist/lib/local_store/index.js +2 -2
- package/dist/lib/local_store/paths.js +0 -6
- package/dist/lib/local_store/routing.js +8 -44
- package/dist/lib/onboarding/folder_state.js +2 -2
- package/dist/lib/onboarding/init_fresh_folder.js +1 -1
- package/dist/lib/onboarding/manifest_writer.js +6 -6
- package/dist/lib/origin_guard.js +1 -1
- package/dist/lib/project_context.js +5 -5
- package/dist/lib/project_contract.js +2 -2
- package/dist/lib/records/drain.js +3 -153
- package/dist/lib/records/kinds.js +16 -0
- package/dist/lib/records/recordInput.js +1 -1
- package/dist/lib/records/recordsTable.js +119 -161
- package/dist/lib/records/refusalLog.js +7 -7
- package/dist/lib/sessions/brief.js +1 -1
- package/dist/lib/sessions/sessionEvents.js +5 -49
- package/dist/lib/store/open.js +136 -0
- package/dist/lib/store/wipe.js +34 -0
- package/dist/lib/sync/apply.js +113 -0
- package/dist/lib/sync/client.js +327 -0
- package/dist/lib/sync/endpoint.js +26 -0
- package/dist/lib/sync/manifest.js +80 -0
- package/dist/lib/sync/outbox.js +104 -0
- package/dist/machine.sql +934 -0
- package/dist/program.js +8 -6
- package/dist/records.schema.json +4 -0
- package/dist/spec_schema.json +5 -5
- package/dist/vendor/harness/rules/docsRoot.js +2 -2
- package/dist/vendor/harness/rules/index.js +1 -1
- package/package.json +5 -5
- package/dist/lib/local_store/migrations.js +0 -399
- package/dist/lib/records/door.js +0 -79
package/dist/machine.sql
ADDED
|
@@ -0,0 +1,934 @@
|
|
|
1
|
+
-- packages/contracts/src/store/machine.generated.sql - GENERATED by scripts/store-schema/compile.mjs; never edit.
|
|
2
|
+
-- The machine database: shared tables cut from packages/studio/seed/init.sql, machine-only tables, outbox triggers.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE `users` (
|
|
5
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
6
|
+
`label` text NOT NULL,
|
|
7
|
+
`primary_email` text NOT NULL,
|
|
8
|
+
`normalized_email` text NOT NULL,
|
|
9
|
+
`normalized_domain` text NOT NULL,
|
|
10
|
+
`email_verified_at` text,
|
|
11
|
+
`password_hash` text NOT NULL,
|
|
12
|
+
`auth_user_id` text,
|
|
13
|
+
`google_id` text,
|
|
14
|
+
`microsoft_id` text,
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
`oidc_issuer` text,
|
|
23
|
+
`oidc_subject` text,
|
|
24
|
+
`status` text NOT NULL DEFAULT 'active' CHECK (`status` IN ('active', 'disabled')),
|
|
25
|
+
`last_sign_in_at` text,
|
|
26
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
27
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
28
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
29
|
+
`sync_seq` integer
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE TABLE `organizations` (
|
|
33
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
34
|
+
`label` text NOT NULL,
|
|
35
|
+
`slug` text NOT NULL,
|
|
36
|
+
`created_by_user_id` text,
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
`status` text NOT NULL DEFAULT 'active' CHECK (`status` IN ('active', 'archived', 'locked')),
|
|
41
|
+
|
|
42
|
+
`normalized_domain` text,
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
`claim_source` text CHECK (`claim_source` IS NULL OR `claim_source` IN ('domain_bootstrap', 'seed')),
|
|
47
|
+
`domain_verified_at` text,
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
`pinned_slots` integer NOT NULL DEFAULT 5,
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
`license_tier` text NOT NULL DEFAULT 'trial'
|
|
60
|
+
CHECK (`license_tier` IN ('trial', 'pilot', 'paid', 'internal')),
|
|
61
|
+
`is_enrollment_open` integer NOT NULL DEFAULT 1,
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
`slack_webhook_url` text,
|
|
66
|
+
|
|
67
|
+
`monthly_spend_cap_cents` integer CHECK (`monthly_spend_cap_cents` IS NULL OR `monthly_spend_cap_cents` > 0),
|
|
68
|
+
`session_budget_default_cents` integer CHECK (`session_budget_default_cents` IS NULL OR `session_budget_default_cents` > 0),
|
|
69
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
70
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
71
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
72
|
+
`sync_seq` integer
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
CREATE TABLE `organization_user_map` (
|
|
76
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
77
|
+
`organization_id` text NOT NULL,
|
|
78
|
+
`user_id` text NOT NULL,
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
`role` text NOT NULL CHECK (`role` IN ('owner', 'admin', 'member', 'viewer')),
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
`joined_via` text CHECK (`joined_via` IN ('domain_bootstrap', 'domain_autojoin', 'organization_creator', 'invited', 'scim')),
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
`status` text NOT NULL DEFAULT 'active' CHECK (`status` IN ('active', 'removed')),
|
|
96
|
+
`removed_at` text,
|
|
97
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
98
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
99
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
100
|
+
`sync_seq` integer
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
CREATE TABLE `projects` (
|
|
104
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
105
|
+
`organization_id` text,
|
|
106
|
+
`created_by_user_id` text,
|
|
107
|
+
`label` text NOT NULL,
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
`description` text,
|
|
115
|
+
`status` text NOT NULL DEFAULT 'initializing' CHECK (`status` IN ('initializing', 'active', 'initialization_failed', 'archived')),
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
`mode` text NOT NULL DEFAULT 'specification' CHECK (`mode` IN ('specification', 'coding')),
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
`model_tier` text NOT NULL DEFAULT 'regular',
|
|
125
|
+
`initialized_at` text,
|
|
126
|
+
`archived_at` text,
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
`agent_slug` text,
|
|
132
|
+
`agent_version` text,
|
|
133
|
+
|
|
134
|
+
`init_status` text NOT NULL DEFAULT 'pending' CHECK (`init_status` IN ('pending', 'copying', 'completed', 'failed')),
|
|
135
|
+
`init_manifest_json` text NOT NULL DEFAULT '{}' CHECK (json_valid(`init_manifest_json`)),
|
|
136
|
+
`init_error_code` text,
|
|
137
|
+
`init_idempotency_key` text,
|
|
138
|
+
`init_completed_at` text,
|
|
139
|
+
|
|
140
|
+
`publication_state` text NOT NULL DEFAULT 'private' CHECK (`publication_state` IN ('private', 'public')),
|
|
141
|
+
`public_slug` text,
|
|
142
|
+
`public_label` text,
|
|
143
|
+
`public_tagline` text,
|
|
144
|
+
`public_description` text,
|
|
145
|
+
`public_categories_json` text CHECK (`public_categories_json` IS NULL OR json_valid(`public_categories_json`)),
|
|
146
|
+
`public_media_json` text CHECK (`public_media_json` IS NULL OR json_valid(`public_media_json`)),
|
|
147
|
+
`public_links_json` text CHECK (`public_links_json` IS NULL OR json_valid(`public_links_json`)),
|
|
148
|
+
`published_at` text,
|
|
149
|
+
`public_updated_at` text,
|
|
150
|
+
|
|
151
|
+
`github_installation_id` integer,
|
|
152
|
+
`github_repo_full_name` text,
|
|
153
|
+
`github_branch` text,
|
|
154
|
+
`github_known_head` text,
|
|
155
|
+
`github_is_active` integer,
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
`github_last_error` text,
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
`github_write_access` integer,
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
`live_version` integer,
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
`settled_commit` text,
|
|
172
|
+
`settled_at` text,
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
`marker_commit` text,
|
|
176
|
+
|
|
177
|
+
`is_pinned` integer NOT NULL DEFAULT 0,
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
`deploy_token_hash` text,
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
`hosting_hostname` text,
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
`previous_version` integer,
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
`deploy_claimed_at` text,
|
|
200
|
+
`deploy_state` text CHECK (`deploy_state` IS NULL OR `deploy_state` IN ('building', 'publishing')),
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
`deploy_version` integer,
|
|
204
|
+
|
|
205
|
+
`last_outcome_json` text CHECK (`last_outcome_json` IS NULL OR json_valid(`last_outcome_json`)),
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
`branch_policy` text CHECK (`branch_policy` IS NULL OR `branch_policy` IN ('trunk', 'branch')),
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
`installed_harness_version` text,
|
|
215
|
+
`harness_version_id` text,
|
|
216
|
+
`harness_id` text,
|
|
217
|
+
`harness_linked_at` text,
|
|
218
|
+
`harness_pin_held` integer NOT NULL DEFAULT 0 CHECK (`harness_pin_held` IN (0, 1)),
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
`harness_track` text,
|
|
225
|
+
`harness_pinned_semver` text,
|
|
226
|
+
`harness_is_canary` integer,
|
|
227
|
+
`harness_current_version_id` text,
|
|
228
|
+
`harness_compiled_through` text,
|
|
229
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
230
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
231
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
232
|
+
`sync_seq` integer
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
CREATE TABLE `harness_project_versions` (
|
|
236
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
237
|
+
`project_id` text NOT NULL,
|
|
238
|
+
`semver` text NOT NULL,
|
|
239
|
+
`digest` text NOT NULL,
|
|
240
|
+
`catalog_version` text NOT NULL,
|
|
241
|
+
`definition_snapshot_json` text NOT NULL CHECK (json_valid(`definition_snapshot_json`)),
|
|
242
|
+
`diff_json` text NOT NULL CHECK (json_valid(`diff_json`)),
|
|
243
|
+
`author_user_id` text,
|
|
244
|
+
`compile_mode` text NOT NULL CHECK (`compile_mode` IN ('model', 'mechanical')),
|
|
245
|
+
`runtimes_json` text NOT NULL CHECK (json_valid(`runtimes_json`)),
|
|
246
|
+
`r2_prefix` text NOT NULL,
|
|
247
|
+
`is_canary` integer NOT NULL DEFAULT 0 CHECK (`is_canary` IN (0, 1)),
|
|
248
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
249
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
250
|
+
`uploaded_at` text,
|
|
251
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
252
|
+
`sync_seq` integer
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
CREATE TABLE `project_files` (
|
|
256
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
257
|
+
`project_id` text NOT NULL,
|
|
258
|
+
`path` text NOT NULL,
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
`ref` text NOT NULL DEFAULT 'main',
|
|
262
|
+
`type` text NOT NULL,
|
|
263
|
+
`status` text NOT NULL,
|
|
264
|
+
`body_sha256` text NOT NULL,
|
|
265
|
+
`git_blob_sha` text NOT NULL,
|
|
266
|
+
|
|
267
|
+
`body_bytes` integer NOT NULL DEFAULT 0,
|
|
268
|
+
|
|
269
|
+
`git_mode` text NOT NULL DEFAULT '100644' CHECK (`git_mode` IN ('100644', '100755', '120000', '160000')),
|
|
270
|
+
|
|
271
|
+
`is_opaque` integer NOT NULL DEFAULT 0 CHECK (`is_opaque` IN (0, 1)),
|
|
272
|
+
`settlement_id` text NOT NULL,
|
|
273
|
+
`record_genre` text,
|
|
274
|
+
`fields_json` text CHECK (`fields_json` IS NULL OR json_valid(`fields_json`)),
|
|
275
|
+
`record_date` text,
|
|
276
|
+
`parse_version` integer,
|
|
277
|
+
`commit_sha` text,
|
|
278
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
279
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
280
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
281
|
+
`sync_seq` integer,
|
|
282
|
+
CHECK (CASE WHEN `record_genre` IS NULL THEN `fields_json` IS NULL AND `parse_version` IS NULL ELSE `fields_json` IS NOT NULL AND `parse_version` IS NOT NULL END)
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
CREATE TABLE `project_local_bindings` (
|
|
286
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
287
|
+
`project_id` text NOT NULL,
|
|
288
|
+
`device_id` text,
|
|
289
|
+
`user_id` text,
|
|
290
|
+
`repository_fingerprint` text NOT NULL,
|
|
291
|
+
`bound_branch` text NOT NULL,
|
|
292
|
+
`display_label` text,
|
|
293
|
+
`protocol_version` text NOT NULL,
|
|
294
|
+
`last_reported_commit_id` text,
|
|
295
|
+
`state` text NOT NULL DEFAULT 'healthy'
|
|
296
|
+
CHECK (`state` IN ('healthy', 'degraded', 'removed')),
|
|
297
|
+
`health_json` text DEFAULT '{}' CHECK (`health_json` IS NULL OR json_valid(`health_json`)),
|
|
298
|
+
`idempotency_key` text,
|
|
299
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
300
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
301
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
302
|
+
`sync_seq` integer
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
CREATE TABLE `project_commits` (
|
|
306
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
307
|
+
`project_id` text NOT NULL,
|
|
308
|
+
`ref` text NOT NULL,
|
|
309
|
+
`sha` text NOT NULL,
|
|
310
|
+
`parent_shas_json` text NOT NULL DEFAULT '[]' CHECK (json_valid(`parent_shas_json`)),
|
|
311
|
+
`author_name` text,
|
|
312
|
+
`author_email` text,
|
|
313
|
+
`subject` text NOT NULL,
|
|
314
|
+
`committed_at` text NOT NULL,
|
|
315
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
316
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
317
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
318
|
+
`sync_seq` integer
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
CREATE TABLE `harness_records` (
|
|
322
|
+
`id` text PRIMARY KEY,
|
|
323
|
+
`project_id` text NOT NULL,
|
|
324
|
+
`kind` text NOT NULL CHECK (`kind` IN ('obligation', 'gate_event', 'changelog', 'memory', 'backlog', 'proposal', 'triage')),
|
|
325
|
+
`schema_version` integer NOT NULL,
|
|
326
|
+
`natural_key` text NOT NULL,
|
|
327
|
+
`idempotency_key` text NOT NULL,
|
|
328
|
+
`session_id` text,
|
|
329
|
+
`plan_anchor` text,
|
|
330
|
+
`payload_json` text NOT NULL CHECK (json_valid(`payload_json`)),
|
|
331
|
+
`written_by_kind` text NOT NULL CHECK (`written_by_kind` IN ('person', 'session', 'agent')),
|
|
332
|
+
`agent_definition_id` text,
|
|
333
|
+
`occurred_at` text NOT NULL,
|
|
334
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
335
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
336
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
337
|
+
`sync_seq` integer
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
CREATE TABLE `github_repositories` (
|
|
341
|
+
`repository_id` integer PRIMARY KEY,
|
|
342
|
+
`installation_id` integer NOT NULL,
|
|
343
|
+
`full_name` text NOT NULL,
|
|
344
|
+
`default_branch` text NOT NULL,
|
|
345
|
+
`is_private` integer NOT NULL DEFAULT 0,
|
|
346
|
+
`refreshed_at` text NOT NULL DEFAULT (datetime('now')),
|
|
347
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
348
|
+
`sync_seq` integer
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
CREATE TABLE `sessions` (
|
|
352
|
+
|
|
353
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
354
|
+
`kind` text NOT NULL DEFAULT 'work' CHECK (`kind` IN ('work', 'harness_generation')),
|
|
355
|
+
`project_id` text,
|
|
356
|
+
`organization_id` text NOT NULL,
|
|
357
|
+
|
|
358
|
+
`started_by` text NOT NULL CHECK (`started_by` IN ('person', 'parent_session', 'schedule', 'automation', 'finding')),
|
|
359
|
+
|
|
360
|
+
`parent_session_id` text,
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
`agent_slug` text,
|
|
365
|
+
`agent_version` integer,
|
|
366
|
+
|
|
367
|
+
`substrate` text NOT NULL CHECK (`substrate` IN ('device', 'cloud', 'vendor')),
|
|
368
|
+
|
|
369
|
+
`mode` text NOT NULL CHECK (`mode` IN ('synchronous', 'asynchronous')),
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
`nustack` integer NOT NULL CHECK (`nustack` IN (0, 1)),
|
|
375
|
+
`vendor` text NOT NULL CHECK (`vendor` IN ('claude_code', 'codex', 'opencode', 'nustack')),
|
|
376
|
+
|
|
377
|
+
`vendor_session_id` text,
|
|
378
|
+
`renderer` text NOT NULL CHECK (`renderer` IN ('claude_transcript', 'codex_transcript', 'opencode_log', 'chat')),
|
|
379
|
+
`status` text NOT NULL CHECK (`status` IN ('created', 'running', 'waiting_on_person', 'done', 'failed', 'cancelled', 'dropped')),
|
|
380
|
+
|
|
381
|
+
`conversation_id` text,
|
|
382
|
+
`inputs_json` text CHECK (`inputs_json` IS NULL OR json_valid(`inputs_json`)),
|
|
383
|
+
`automation_id` text,
|
|
384
|
+
`dispatched_at` text,
|
|
385
|
+
`drop_reason` text,
|
|
386
|
+
|
|
387
|
+
`target_id` text,
|
|
388
|
+
`state_json` text CHECK (`state_json` IS NULL OR json_valid(`state_json`)),
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
`task` text,
|
|
392
|
+
`harness_version_id` text,
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
`started_by_principal_type` text,
|
|
399
|
+
`started_by_principal_id` text,
|
|
400
|
+
`start_commit` text,
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
`model_provider` text,
|
|
410
|
+
`model` text,
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
`runtime` text,
|
|
417
|
+
`config_digest` text,
|
|
418
|
+
`handover` text,
|
|
419
|
+
`harness_semver` text,
|
|
420
|
+
`harness_digest` text,
|
|
421
|
+
|
|
422
|
+
`result_json` text CHECK (`result_json` IS NULL OR json_valid(`result_json`)),
|
|
423
|
+
`budget_cents` integer,
|
|
424
|
+
`tags_json` text NOT NULL DEFAULT '[]' CHECK (json_valid(`tags_json`)),
|
|
425
|
+
`cost_cents` integer,
|
|
426
|
+
`cost_with_children_cents` integer,
|
|
427
|
+
`device_id` text,
|
|
428
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
429
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
430
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
431
|
+
`sync_seq` integer,
|
|
432
|
+
|
|
433
|
+
CHECK (CASE WHEN `kind` = 'harness_generation' THEN `target_id` IS NOT NULL ELSE `project_id` IS NOT NULL END),
|
|
434
|
+
CHECK (CASE WHEN `status` = 'dropped' THEN `dispatched_at` IS NULL ELSE `drop_reason` IS NULL END)
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
CREATE TABLE `session_label_rows` (
|
|
438
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
439
|
+
`session_id` text NOT NULL,
|
|
440
|
+
`project_id` text NOT NULL,
|
|
441
|
+
`agent_type` text NOT NULL,
|
|
442
|
+
|
|
443
|
+
`path` text,
|
|
444
|
+
`estimated_tokens` integer NOT NULL,
|
|
445
|
+
`returned_tokens` integer NOT NULL,
|
|
446
|
+
`handler` text NOT NULL,
|
|
447
|
+
|
|
448
|
+
`check_result` text,
|
|
449
|
+
`is_bypass_used` integer NOT NULL CHECK (`is_bypass_used` IN (0, 1)),
|
|
450
|
+
`latency_ms` integer,
|
|
451
|
+
|
|
452
|
+
`tokens_kept_out` integer,
|
|
453
|
+
`created_at` text NOT NULL,
|
|
454
|
+
`landed_at` text NOT NULL DEFAULT (datetime('now')),
|
|
455
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
456
|
+
`sync_seq` integer
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
CREATE TABLE `github_items` (
|
|
460
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
461
|
+
|
|
462
|
+
`repository_id` integer NOT NULL,
|
|
463
|
+
`kind` text NOT NULL CHECK (`kind` IN ('issue', 'pull_request')),
|
|
464
|
+
`number` integer NOT NULL,
|
|
465
|
+
`title` text NOT NULL,
|
|
466
|
+
|
|
467
|
+
`state` text NOT NULL CHECK (`state` IN ('open', 'closed', 'merged')),
|
|
468
|
+
|
|
469
|
+
`author` text,
|
|
470
|
+
`labels_json` text NOT NULL DEFAULT '[]' CHECK (json_valid(`labels_json`)),
|
|
471
|
+
|
|
472
|
+
`head_ref` text,
|
|
473
|
+
`base_ref` text,
|
|
474
|
+
`html_url` text NOT NULL,
|
|
475
|
+
|
|
476
|
+
`updated_at_github` text NOT NULL,
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
`created_at_github` text,
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
`merged_at` text,
|
|
486
|
+
|
|
487
|
+
`is_draft` integer NOT NULL DEFAULT 0 CHECK (`is_draft` IN (0, 1)),
|
|
488
|
+
`created_at` text NOT NULL DEFAULT (datetime('now')),
|
|
489
|
+
`updated_at` text NOT NULL DEFAULT (datetime('now')),
|
|
490
|
+
`row_version` integer NOT NULL DEFAULT 1,
|
|
491
|
+
`sync_seq` integer
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
CREATE INDEX `users_sync_seq_idx` ON `users` (`sync_seq`);
|
|
495
|
+
|
|
496
|
+
CREATE UNIQUE INDEX `users_normalized_email_unique` ON `users` (`normalized_email`);
|
|
497
|
+
|
|
498
|
+
CREATE UNIQUE INDEX `users_auth_user_id_unique` ON `users` (`auth_user_id`) WHERE `auth_user_id` IS NOT NULL;
|
|
499
|
+
|
|
500
|
+
CREATE UNIQUE INDEX `users_google_id_unique` ON `users` (`google_id`) WHERE `google_id` IS NOT NULL;
|
|
501
|
+
|
|
502
|
+
CREATE UNIQUE INDEX `users_microsoft_id_unique` ON `users` (`microsoft_id`) WHERE `microsoft_id` IS NOT NULL;
|
|
503
|
+
|
|
504
|
+
CREATE UNIQUE INDEX `users_oidc_subject_unique` ON `users` (`oidc_issuer`, `oidc_subject`)
|
|
505
|
+
WHERE `oidc_subject` IS NOT NULL;
|
|
506
|
+
|
|
507
|
+
CREATE INDEX `users_normalized_domain_idx` ON `users` (`normalized_domain`);
|
|
508
|
+
|
|
509
|
+
CREATE INDEX `organizations_sync_seq_idx` ON `organizations` (`sync_seq`);
|
|
510
|
+
|
|
511
|
+
CREATE UNIQUE INDEX `organizations_slug_unique` ON `organizations` (`slug`);
|
|
512
|
+
|
|
513
|
+
CREATE UNIQUE INDEX `organizations_normalized_domain_unique` ON `organizations` (`normalized_domain`)
|
|
514
|
+
WHERE `normalized_domain` IS NOT NULL;
|
|
515
|
+
|
|
516
|
+
CREATE INDEX `organization_user_map_sync_seq_idx` ON `organization_user_map` (`sync_seq`);
|
|
517
|
+
|
|
518
|
+
CREATE UNIQUE INDEX `organization_user_map_organization_user_unique` ON `organization_user_map` (`organization_id`, `user_id`);
|
|
519
|
+
|
|
520
|
+
CREATE INDEX `organization_user_map_user_status_idx` ON `organization_user_map` (`user_id`, `status`);
|
|
521
|
+
|
|
522
|
+
CREATE INDEX `projects_sync_seq_idx` ON `projects` (`sync_seq`);
|
|
523
|
+
|
|
524
|
+
CREATE INDEX `projects_organization_status_updated_idx` ON `projects` (`organization_id`, `status`, `updated_at` DESC);
|
|
525
|
+
|
|
526
|
+
CREATE INDEX `projects_publication_updated_idx` ON `projects` (`publication_state`, `updated_at` DESC);
|
|
527
|
+
|
|
528
|
+
CREATE UNIQUE INDEX `projects_init_idempotency_key_unique` ON `projects` (`init_idempotency_key`) WHERE `init_idempotency_key` IS NOT NULL;
|
|
529
|
+
|
|
530
|
+
CREATE UNIQUE INDEX `projects_public_slug_unique` ON `projects` (`public_slug`) WHERE `public_slug` IS NOT NULL;
|
|
531
|
+
|
|
532
|
+
CREATE INDEX `projects_github_installation_repo_idx` ON `projects` (`github_installation_id`, `github_repo_full_name`);
|
|
533
|
+
|
|
534
|
+
CREATE INDEX `projects_harness_idx` ON `projects` (`harness_id`);
|
|
535
|
+
|
|
536
|
+
CREATE UNIQUE INDEX `projects_deploy_token_hash_unique` ON `projects` (`deploy_token_hash`) WHERE `deploy_token_hash` IS NOT NULL;
|
|
537
|
+
|
|
538
|
+
CREATE UNIQUE INDEX `projects_hosting_hostname_unique` ON `projects` (`hosting_hostname`) WHERE `hosting_hostname` IS NOT NULL;
|
|
539
|
+
|
|
540
|
+
CREATE INDEX `harness_project_versions_sync_seq_idx` ON `harness_project_versions` (`sync_seq`);
|
|
541
|
+
|
|
542
|
+
CREATE UNIQUE INDEX `harness_project_versions_project_semver_unique` ON `harness_project_versions` (`project_id`, `semver`);
|
|
543
|
+
|
|
544
|
+
CREATE UNIQUE INDEX `harness_project_versions_project_digest_unique` ON `harness_project_versions` (`project_id`, `digest`);
|
|
545
|
+
|
|
546
|
+
CREATE INDEX `harness_project_versions_project_created_idx` ON `harness_project_versions` (`project_id`, `created_at`);
|
|
547
|
+
|
|
548
|
+
CREATE INDEX `project_files_sync_seq_idx` ON `project_files` (`sync_seq`);
|
|
549
|
+
|
|
550
|
+
CREATE UNIQUE INDEX `project_files_project_ref_path_unique` ON `project_files` (`project_id`, `ref`, `path`);
|
|
551
|
+
|
|
552
|
+
CREATE INDEX `project_files_project_type_idx` ON `project_files` (`project_id`, `type`);
|
|
553
|
+
|
|
554
|
+
CREATE INDEX `project_files_project_genre_idx` ON `project_files` (`project_id`, `record_genre`) WHERE `record_genre` IS NOT NULL;
|
|
555
|
+
|
|
556
|
+
CREATE INDEX `project_local_bindings_sync_seq_idx` ON `project_local_bindings` (`sync_seq`);
|
|
557
|
+
|
|
558
|
+
CREATE UNIQUE INDEX `project_local_bindings_project_fingerprint_unique`
|
|
559
|
+
ON `project_local_bindings` (`project_id`, `repository_fingerprint`)
|
|
560
|
+
WHERE `state` != 'removed';
|
|
561
|
+
|
|
562
|
+
CREATE UNIQUE INDEX `project_local_bindings_idempotency_key_unique`
|
|
563
|
+
ON `project_local_bindings` (`idempotency_key`)
|
|
564
|
+
WHERE `idempotency_key` IS NOT NULL;
|
|
565
|
+
|
|
566
|
+
CREATE INDEX `project_local_bindings_project_state_idx` ON `project_local_bindings` (`project_id`, `state`);
|
|
567
|
+
|
|
568
|
+
CREATE INDEX `project_local_bindings_device_id_idx` ON `project_local_bindings` (`device_id`);
|
|
569
|
+
|
|
570
|
+
CREATE INDEX `project_commits_sync_seq_idx` ON `project_commits` (`sync_seq`);
|
|
571
|
+
|
|
572
|
+
CREATE UNIQUE INDEX `project_commits_project_ref_sha_unique` ON `project_commits` (`project_id`, `ref`, `sha`);
|
|
573
|
+
|
|
574
|
+
CREATE INDEX `project_commits_project_ref_committed_idx` ON `project_commits` (`project_id`, `ref`, `committed_at` DESC);
|
|
575
|
+
|
|
576
|
+
CREATE INDEX `harness_records_sync_seq_idx` ON `harness_records` (`sync_seq`);
|
|
577
|
+
|
|
578
|
+
CREATE UNIQUE INDEX `harness_records_project_idempotency_unique` ON `harness_records` (`project_id`, `idempotency_key`);
|
|
579
|
+
|
|
580
|
+
CREATE INDEX `harness_records_project_kind_plan_idx` ON `harness_records` (`project_id`, `kind`, `plan_anchor`);
|
|
581
|
+
|
|
582
|
+
CREATE INDEX `harness_records_project_created_idx` ON `harness_records` (`project_id`, `created_at`, `id`);
|
|
583
|
+
|
|
584
|
+
CREATE INDEX `github_repositories_sync_seq_idx` ON `github_repositories` (`sync_seq`);
|
|
585
|
+
|
|
586
|
+
CREATE INDEX `github_repositories_installation_idx` ON `github_repositories` (`installation_id`, `full_name`);
|
|
587
|
+
|
|
588
|
+
CREATE INDEX `sessions_sync_seq_idx` ON `sessions` (`sync_seq`);
|
|
589
|
+
|
|
590
|
+
CREATE INDEX `sessions_automation_status_created_idx` ON `sessions` (`automation_id`, `status`, `created_at`)
|
|
591
|
+
WHERE `automation_id` IS NOT NULL;
|
|
592
|
+
|
|
593
|
+
CREATE UNIQUE INDEX `sessions_target_live_unique` ON `sessions` (`target_id`)
|
|
594
|
+
WHERE `kind` = 'harness_generation' AND `status` IN ('created', 'running');
|
|
595
|
+
|
|
596
|
+
CREATE INDEX `sessions_project_created_idx` ON `sessions` (`project_id`, `created_at` DESC);
|
|
597
|
+
|
|
598
|
+
CREATE INDEX `sessions_parent_idx` ON `sessions` (`parent_session_id`);
|
|
599
|
+
|
|
600
|
+
CREATE INDEX `sessions_vendor_idx` ON `sessions` (`vendor`, `vendor_session_id`);
|
|
601
|
+
|
|
602
|
+
CREATE INDEX `sessions_organization_created_idx` ON `sessions` (`organization_id`, `created_at` DESC);
|
|
603
|
+
|
|
604
|
+
CREATE INDEX `sessions_project_harness_digest_idx` ON `sessions` (`project_id`, `harness_digest`)
|
|
605
|
+
WHERE `harness_digest` IS NOT NULL;
|
|
606
|
+
|
|
607
|
+
CREATE INDEX `session_label_rows_sync_seq_idx` ON `session_label_rows` (`sync_seq`);
|
|
608
|
+
|
|
609
|
+
CREATE INDEX `session_label_rows_session_idx` ON `session_label_rows` (`session_id`);
|
|
610
|
+
|
|
611
|
+
CREATE INDEX `session_label_rows_project_created_idx` ON `session_label_rows` (`project_id`, `created_at`, `id`);
|
|
612
|
+
|
|
613
|
+
CREATE INDEX `github_items_sync_seq_idx` ON `github_items` (`sync_seq`);
|
|
614
|
+
|
|
615
|
+
CREATE UNIQUE INDEX `github_items_repository_kind_number_unique` ON `github_items` (`repository_id`, `kind`, `number`);
|
|
616
|
+
|
|
617
|
+
CREATE INDEX `github_items_repository_state_updated_idx` ON `github_items` (`repository_id`, `state`, `updated_at_github` DESC);
|
|
618
|
+
|
|
619
|
+
CREATE INDEX `github_items_repository_head_ref_idx` ON `github_items` (`repository_id`, `head_ref`)
|
|
620
|
+
WHERE `head_ref` IS NOT NULL;
|
|
621
|
+
|
|
622
|
+
CREATE TABLE `sync_outbox` (
|
|
623
|
+
`table_name` text NOT NULL,
|
|
624
|
+
`row_key` text NOT NULL,
|
|
625
|
+
`op` text NOT NULL CHECK (`op` IN ('upsert', 'delete')),
|
|
626
|
+
`base_version` integer NOT NULL,
|
|
627
|
+
`changed_json` text NOT NULL DEFAULT '[]' CHECK (json_valid(`changed_json`)),
|
|
628
|
+
`enqueued_at` integer NOT NULL,
|
|
629
|
+
`attempts` integer NOT NULL DEFAULT 0,
|
|
630
|
+
`next_attempt_at` integer,
|
|
631
|
+
`last_error` text,
|
|
632
|
+
PRIMARY KEY (`table_name`, `row_key`)
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
CREATE INDEX `sync_outbox_next_attempt_idx` ON `sync_outbox` (`next_attempt_at`);
|
|
636
|
+
|
|
637
|
+
CREATE TABLE `sync_state` (
|
|
638
|
+
`name` text PRIMARY KEY NOT NULL,
|
|
639
|
+
`value` text NOT NULL
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
CREATE TABLE `folder_roster` (
|
|
643
|
+
`path` text PRIMARY KEY NOT NULL,
|
|
644
|
+
`label` text NOT NULL,
|
|
645
|
+
`project_id` text NOT NULL,
|
|
646
|
+
`added_at` integer NOT NULL
|
|
647
|
+
);
|
|
648
|
+
|
|
649
|
+
CREATE INDEX `folder_roster_project_idx` ON `folder_roster` (`project_id`);
|
|
650
|
+
|
|
651
|
+
CREATE TABLE `parse_cache` (
|
|
652
|
+
`project_id` text NOT NULL,
|
|
653
|
+
`path` text NOT NULL,
|
|
654
|
+
`sha256` text NOT NULL,
|
|
655
|
+
`genre` text,
|
|
656
|
+
`fields_json` text CHECK (`fields_json` IS NULL OR json_valid(`fields_json`)),
|
|
657
|
+
`parse_version` integer NOT NULL,
|
|
658
|
+
`parsed_at` integer NOT NULL,
|
|
659
|
+
PRIMARY KEY (`project_id`, `path`)
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
CREATE TABLE `routing_latch` (
|
|
663
|
+
`session_id` text,
|
|
664
|
+
`job_kind` text,
|
|
665
|
+
`failures` integer NOT NULL DEFAULT 0,
|
|
666
|
+
`budget_misses` integer NOT NULL DEFAULT 0,
|
|
667
|
+
`latched_at` integer,
|
|
668
|
+
PRIMARY KEY (`session_id`, `job_kind`)
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
CREATE TABLE `gated_paths` (
|
|
672
|
+
`session_id` text,
|
|
673
|
+
`path` text,
|
|
674
|
+
`gated_at` integer,
|
|
675
|
+
PRIMARY KEY (`session_id`, `path`)
|
|
676
|
+
);
|
|
677
|
+
|
|
678
|
+
CREATE TABLE local_device_state (
|
|
679
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
680
|
+
device_ref TEXT,
|
|
681
|
+
api_base_url TEXT,
|
|
682
|
+
active_user_id TEXT,
|
|
683
|
+
active_user_email TEXT,
|
|
684
|
+
keychain_service TEXT,
|
|
685
|
+
keychain_account TEXT,
|
|
686
|
+
schema_version INTEGER NOT NULL DEFAULT 1,
|
|
687
|
+
last_auth_refresh_at_ms INTEGER,
|
|
688
|
+
created_at_ms INTEGER NOT NULL,
|
|
689
|
+
updated_at_ms INTEGER NOT NULL
|
|
690
|
+
, active_organization_id TEXT);
|
|
691
|
+
|
|
692
|
+
CREATE TABLE local_bindings (
|
|
693
|
+
id TEXT PRIMARY KEY,
|
|
694
|
+
project_id TEXT NOT NULL,
|
|
695
|
+
organization_id TEXT NOT NULL,
|
|
696
|
+
repository_root TEXT NOT NULL,
|
|
697
|
+
git_dir TEXT NOT NULL,
|
|
698
|
+
git_common_dir TEXT NOT NULL,
|
|
699
|
+
repository_fingerprint TEXT NOT NULL,
|
|
700
|
+
bound_branch TEXT NOT NULL,
|
|
701
|
+
last_processed_commit_id TEXT,
|
|
702
|
+
last_applied_project_sequence INTEGER NOT NULL DEFAULT 0,
|
|
703
|
+
whitelist_manifest_id TEXT,
|
|
704
|
+
whitelist_manifest_sha256 TEXT,
|
|
705
|
+
whitelist_cache_path TEXT,
|
|
706
|
+
etna_profile_json TEXT CHECK (etna_profile_json IS NULL OR json_valid(etna_profile_json)),
|
|
707
|
+
status TEXT NOT NULL CHECK (status IN ('creating','active','paused','failed','removed')),
|
|
708
|
+
last_error_code TEXT,
|
|
709
|
+
last_error_detail TEXT,
|
|
710
|
+
created_at_ms INTEGER NOT NULL,
|
|
711
|
+
updated_at_ms INTEGER NOT NULL
|
|
712
|
+
, telemetry_enabled INTEGER NOT NULL DEFAULT 1);
|
|
713
|
+
|
|
714
|
+
CREATE UNIQUE INDEX local_bindings_repository_root_live_unique
|
|
715
|
+
ON local_bindings (repository_root)
|
|
716
|
+
WHERE status IN ('creating','active','paused');
|
|
717
|
+
|
|
718
|
+
CREATE TABLE local_commit_origins (
|
|
719
|
+
binding_id TEXT NOT NULL REFERENCES local_bindings(id),
|
|
720
|
+
commit_id TEXT NOT NULL,
|
|
721
|
+
handoff_id TEXT NOT NULL,
|
|
722
|
+
origin TEXT NOT NULL CHECK (origin = 'cloud_handoff'),
|
|
723
|
+
created_at_ms INTEGER NOT NULL,
|
|
724
|
+
PRIMARY KEY (binding_id, commit_id)
|
|
725
|
+
);
|
|
726
|
+
|
|
727
|
+
CREATE TABLE inbound_handoff_applications (
|
|
728
|
+
handoff_id TEXT NOT NULL,
|
|
729
|
+
binding_id TEXT NOT NULL REFERENCES local_bindings(id),
|
|
730
|
+
state TEXT NOT NULL CHECK (state IN (
|
|
731
|
+
'received','evaluating','no_op','technical_wait','decision_required',
|
|
732
|
+
'approved','applying','committed','undo_requested','reverted',
|
|
733
|
+
'revert_conflict','superseded'
|
|
734
|
+
)),
|
|
735
|
+
manifest_sha256 TEXT,
|
|
736
|
+
base_manifest_json TEXT CHECK (base_manifest_json IS NULL OR json_valid(base_manifest_json)),
|
|
737
|
+
target_manifest_json TEXT CHECK (target_manifest_json IS NULL OR json_valid(target_manifest_json)),
|
|
738
|
+
local_state_fingerprint TEXT,
|
|
739
|
+
technical_wait_reason TEXT,
|
|
740
|
+
decision_state TEXT,
|
|
741
|
+
approved_by_user_id TEXT,
|
|
742
|
+
generated_commit_id TEXT,
|
|
743
|
+
notification_state TEXT,
|
|
744
|
+
recovery_bundle_id TEXT,
|
|
745
|
+
revert_commit_id TEXT,
|
|
746
|
+
superseded_by_handoff_id TEXT,
|
|
747
|
+
error_code TEXT,
|
|
748
|
+
error_detail TEXT,
|
|
749
|
+
created_at_ms INTEGER NOT NULL,
|
|
750
|
+
updated_at_ms INTEGER NOT NULL,
|
|
751
|
+
PRIMARY KEY (handoff_id, binding_id)
|
|
752
|
+
);
|
|
753
|
+
|
|
754
|
+
CREATE TABLE local_recovery_bundles (
|
|
755
|
+
id TEXT PRIMARY KEY,
|
|
756
|
+
binding_id TEXT NOT NULL,
|
|
757
|
+
handoff_id TEXT NOT NULL,
|
|
758
|
+
bundle_path TEXT NOT NULL,
|
|
759
|
+
manifest_sha256 TEXT NOT NULL,
|
|
760
|
+
state TEXT NOT NULL CHECK (state IN ('active','restored','expired','deleted')),
|
|
761
|
+
created_at_ms INTEGER NOT NULL,
|
|
762
|
+
expires_at_ms INTEGER NOT NULL
|
|
763
|
+
);
|
|
764
|
+
|
|
765
|
+
CREATE INDEX local_recovery_bundles_binding_idx ON local_recovery_bundles (binding_id);
|
|
766
|
+
|
|
767
|
+
CREATE TABLE pending_uploads (
|
|
768
|
+
binding_id TEXT NOT NULL,
|
|
769
|
+
commit_id TEXT NOT NULL,
|
|
770
|
+
manifest_sha256 TEXT,
|
|
771
|
+
whitelist_manifest_sha256 TEXT,
|
|
772
|
+
idempotency_key TEXT NOT NULL,
|
|
773
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
774
|
+
next_retry_at_ms INTEGER,
|
|
775
|
+
last_error_code TEXT,
|
|
776
|
+
last_error_detail TEXT,
|
|
777
|
+
created_at_ms INTEGER NOT NULL,
|
|
778
|
+
updated_at_ms INTEGER NOT NULL,
|
|
779
|
+
PRIMARY KEY (binding_id, commit_id)
|
|
780
|
+
);
|
|
781
|
+
|
|
782
|
+
CREATE UNIQUE INDEX pending_uploads_idempotency_key_unique
|
|
783
|
+
ON pending_uploads (idempotency_key);
|
|
784
|
+
|
|
785
|
+
CREATE TABLE "cached_project_events" (
|
|
786
|
+
binding_id TEXT NOT NULL,
|
|
787
|
+
project_sequence INTEGER NOT NULL,
|
|
788
|
+
event_type TEXT NOT NULL,
|
|
789
|
+
payload_json TEXT CHECK (payload_json IS NULL OR json_valid(payload_json)),
|
|
790
|
+
applied_at_ms INTEGER,
|
|
791
|
+
created_at_ms INTEGER NOT NULL,
|
|
792
|
+
PRIMARY KEY (binding_id, project_sequence)
|
|
793
|
+
);
|
|
794
|
+
|
|
795
|
+
CREATE TABLE local_filebeat_state (
|
|
796
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
797
|
+
binary_path TEXT,
|
|
798
|
+
config_dir TEXT,
|
|
799
|
+
desired_version TEXT,
|
|
800
|
+
observed_version TEXT,
|
|
801
|
+
desired_config_hash TEXT,
|
|
802
|
+
observed_config_hash TEXT,
|
|
803
|
+
process_state TEXT,
|
|
804
|
+
last_health_at_ms INTEGER,
|
|
805
|
+
created_at_ms INTEGER NOT NULL,
|
|
806
|
+
updated_at_ms INTEGER NOT NULL
|
|
807
|
+
, telemetry_enabled INTEGER NOT NULL DEFAULT 1, last_error_code TEXT);
|
|
808
|
+
|
|
809
|
+
CREATE TABLE local_activity_bindings (
|
|
810
|
+
id TEXT PRIMARY KEY,
|
|
811
|
+
binding_id TEXT NOT NULL,
|
|
812
|
+
provider TEXT NOT NULL CHECK (provider IN ('claude_code','codex')),
|
|
813
|
+
provider_project_path TEXT NOT NULL,
|
|
814
|
+
path_fingerprint TEXT NOT NULL,
|
|
815
|
+
state TEXT NOT NULL CHECK (state IN ('active','missing','disabled')),
|
|
816
|
+
last_observed_at_ms INTEGER,
|
|
817
|
+
created_at_ms INTEGER NOT NULL,
|
|
818
|
+
updated_at_ms INTEGER NOT NULL
|
|
819
|
+
);
|
|
820
|
+
|
|
821
|
+
CREATE UNIQUE INDEX local_activity_bindings_binding_provider_path_unique
|
|
822
|
+
ON local_activity_bindings (binding_id, provider, path_fingerprint);
|
|
823
|
+
|
|
824
|
+
CREATE TABLE local_history_decisions (
|
|
825
|
+
id TEXT PRIMARY KEY,
|
|
826
|
+
binding_id TEXT NOT NULL REFERENCES local_bindings(id),
|
|
827
|
+
decision TEXT NOT NULL CHECK (decision IN ('publish_current_state','adopt_without_publishing')),
|
|
828
|
+
old_baseline_commit_id TEXT,
|
|
829
|
+
new_baseline_commit_id TEXT NOT NULL,
|
|
830
|
+
handoff_id TEXT,
|
|
831
|
+
created_at_ms INTEGER NOT NULL
|
|
832
|
+
);
|
|
833
|
+
|
|
834
|
+
CREATE INDEX local_history_decisions_binding_idx
|
|
835
|
+
ON local_history_decisions (binding_id, created_at_ms);
|
|
836
|
+
|
|
837
|
+
CREATE TABLE local_accepted_uploads (
|
|
838
|
+
binding_id TEXT NOT NULL REFERENCES local_bindings(id),
|
|
839
|
+
commit_id TEXT NOT NULL,
|
|
840
|
+
handoff_id TEXT NOT NULL,
|
|
841
|
+
project_sequence INTEGER NOT NULL,
|
|
842
|
+
manifest_sha256 TEXT NOT NULL,
|
|
843
|
+
created_at_ms INTEGER NOT NULL,
|
|
844
|
+
PRIMARY KEY (binding_id, commit_id)
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
CREATE INDEX local_accepted_uploads_handoff_idx
|
|
848
|
+
ON local_accepted_uploads (handoff_id);
|
|
849
|
+
|
|
850
|
+
CREATE INDEX local_bindings_project_idx ON local_bindings (project_id);
|
|
851
|
+
|
|
852
|
+
CREATE TRIGGER `harness_records_outbox_insert` AFTER INSERT ON `harness_records` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
853
|
+
BEGIN
|
|
854
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
855
|
+
VALUES ('harness_records', NEW.`id`, 'upsert', 0, json_array('id', 'project_id', 'kind', 'schema_version', 'natural_key', 'idempotency_key', 'session_id', 'plan_anchor', 'payload_json', 'occurred_at'), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
856
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
857
|
+
END;
|
|
858
|
+
|
|
859
|
+
CREATE TRIGGER `harness_records_outbox_update` AFTER UPDATE ON `harness_records` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying') AND (OLD.`id` IS NOT NEW.`id` OR OLD.`project_id` IS NOT NEW.`project_id` OR OLD.`kind` IS NOT NEW.`kind` OR OLD.`schema_version` IS NOT NEW.`schema_version` OR OLD.`natural_key` IS NOT NEW.`natural_key` OR OLD.`idempotency_key` IS NOT NEW.`idempotency_key` OR OLD.`session_id` IS NOT NEW.`session_id` OR OLD.`plan_anchor` IS NOT NEW.`plan_anchor` OR OLD.`payload_json` IS NOT NEW.`payload_json` OR OLD.`occurred_at` IS NOT NEW.`occurred_at`)
|
|
860
|
+
BEGIN
|
|
861
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
862
|
+
VALUES ('harness_records', NEW.`id`, 'upsert', OLD.`row_version`, (SELECT json_group_array(`c`) FROM (SELECT 'id' AS `c` WHERE OLD.`id` IS NOT NEW.`id` UNION ALL SELECT 'project_id' AS `c` WHERE OLD.`project_id` IS NOT NEW.`project_id` UNION ALL SELECT 'kind' AS `c` WHERE OLD.`kind` IS NOT NEW.`kind` UNION ALL SELECT 'schema_version' AS `c` WHERE OLD.`schema_version` IS NOT NEW.`schema_version` UNION ALL SELECT 'natural_key' AS `c` WHERE OLD.`natural_key` IS NOT NEW.`natural_key` UNION ALL SELECT 'idempotency_key' AS `c` WHERE OLD.`idempotency_key` IS NOT NEW.`idempotency_key` UNION ALL SELECT 'session_id' AS `c` WHERE OLD.`session_id` IS NOT NEW.`session_id` UNION ALL SELECT 'plan_anchor' AS `c` WHERE OLD.`plan_anchor` IS NOT NEW.`plan_anchor` UNION ALL SELECT 'payload_json' AS `c` WHERE OLD.`payload_json` IS NOT NEW.`payload_json` UNION ALL SELECT 'occurred_at' AS `c` WHERE OLD.`occurred_at` IS NOT NEW.`occurred_at`)), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
863
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
864
|
+
END;
|
|
865
|
+
|
|
866
|
+
CREATE TRIGGER `harness_records_outbox_delete` AFTER DELETE ON `harness_records` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
867
|
+
BEGIN
|
|
868
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
869
|
+
VALUES ('harness_records', OLD.`id`, 'delete', OLD.`row_version`, '[]', CAST(unixepoch('subsec') * 1000 AS integer))
|
|
870
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'delete', `changed_json` = '[]', `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
871
|
+
END;
|
|
872
|
+
|
|
873
|
+
CREATE TRIGGER `project_files_outbox_insert` AFTER INSERT ON `project_files` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
874
|
+
BEGIN
|
|
875
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
876
|
+
VALUES ('project_files', NEW.`id`, 'upsert', 0, json_array('id', 'project_id', 'ref', 'path', 'type', 'status', 'body_sha256', 'git_blob_sha', 'body_bytes', 'git_mode', 'is_opaque', 'settlement_id', 'record_genre', 'fields_json', 'record_date', 'parse_version', 'commit_sha'), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
877
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
878
|
+
END;
|
|
879
|
+
|
|
880
|
+
CREATE TRIGGER `project_files_outbox_update` AFTER UPDATE ON `project_files` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying') AND (OLD.`id` IS NOT NEW.`id` OR OLD.`project_id` IS NOT NEW.`project_id` OR OLD.`ref` IS NOT NEW.`ref` OR OLD.`path` IS NOT NEW.`path` OR OLD.`type` IS NOT NEW.`type` OR OLD.`status` IS NOT NEW.`status` OR OLD.`body_sha256` IS NOT NEW.`body_sha256` OR OLD.`git_blob_sha` IS NOT NEW.`git_blob_sha` OR OLD.`body_bytes` IS NOT NEW.`body_bytes` OR OLD.`git_mode` IS NOT NEW.`git_mode` OR OLD.`is_opaque` IS NOT NEW.`is_opaque` OR OLD.`settlement_id` IS NOT NEW.`settlement_id` OR OLD.`record_genre` IS NOT NEW.`record_genre` OR OLD.`fields_json` IS NOT NEW.`fields_json` OR OLD.`record_date` IS NOT NEW.`record_date` OR OLD.`parse_version` IS NOT NEW.`parse_version` OR OLD.`commit_sha` IS NOT NEW.`commit_sha`)
|
|
881
|
+
BEGIN
|
|
882
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
883
|
+
VALUES ('project_files', NEW.`id`, 'upsert', OLD.`row_version`, (SELECT json_group_array(`c`) FROM (SELECT 'id' AS `c` WHERE OLD.`id` IS NOT NEW.`id` UNION ALL SELECT 'project_id' AS `c` WHERE OLD.`project_id` IS NOT NEW.`project_id` UNION ALL SELECT 'ref' AS `c` WHERE OLD.`ref` IS NOT NEW.`ref` UNION ALL SELECT 'path' AS `c` WHERE OLD.`path` IS NOT NEW.`path` UNION ALL SELECT 'type' AS `c` WHERE OLD.`type` IS NOT NEW.`type` UNION ALL SELECT 'status' AS `c` WHERE OLD.`status` IS NOT NEW.`status` UNION ALL SELECT 'body_sha256' AS `c` WHERE OLD.`body_sha256` IS NOT NEW.`body_sha256` UNION ALL SELECT 'git_blob_sha' AS `c` WHERE OLD.`git_blob_sha` IS NOT NEW.`git_blob_sha` UNION ALL SELECT 'body_bytes' AS `c` WHERE OLD.`body_bytes` IS NOT NEW.`body_bytes` UNION ALL SELECT 'git_mode' AS `c` WHERE OLD.`git_mode` IS NOT NEW.`git_mode` UNION ALL SELECT 'is_opaque' AS `c` WHERE OLD.`is_opaque` IS NOT NEW.`is_opaque` UNION ALL SELECT 'settlement_id' AS `c` WHERE OLD.`settlement_id` IS NOT NEW.`settlement_id` UNION ALL SELECT 'record_genre' AS `c` WHERE OLD.`record_genre` IS NOT NEW.`record_genre` UNION ALL SELECT 'fields_json' AS `c` WHERE OLD.`fields_json` IS NOT NEW.`fields_json` UNION ALL SELECT 'record_date' AS `c` WHERE OLD.`record_date` IS NOT NEW.`record_date` UNION ALL SELECT 'parse_version' AS `c` WHERE OLD.`parse_version` IS NOT NEW.`parse_version` UNION ALL SELECT 'commit_sha' AS `c` WHERE OLD.`commit_sha` IS NOT NEW.`commit_sha`)), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
884
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
885
|
+
END;
|
|
886
|
+
|
|
887
|
+
CREATE TRIGGER `project_files_outbox_delete` AFTER DELETE ON `project_files` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
888
|
+
BEGIN
|
|
889
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
890
|
+
VALUES ('project_files', OLD.`id`, 'delete', OLD.`row_version`, '[]', CAST(unixepoch('subsec') * 1000 AS integer))
|
|
891
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'delete', `changed_json` = '[]', `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
892
|
+
END;
|
|
893
|
+
|
|
894
|
+
CREATE TRIGGER `project_commits_outbox_insert` AFTER INSERT ON `project_commits` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
895
|
+
BEGIN
|
|
896
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
897
|
+
VALUES ('project_commits', NEW.`id`, 'upsert', 0, json_array('id', 'project_id', 'ref', 'sha', 'parent_shas_json', 'author_name', 'author_email', 'subject', 'committed_at'), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
898
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
899
|
+
END;
|
|
900
|
+
|
|
901
|
+
CREATE TRIGGER `project_commits_outbox_update` AFTER UPDATE ON `project_commits` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying') AND (OLD.`id` IS NOT NEW.`id` OR OLD.`project_id` IS NOT NEW.`project_id` OR OLD.`ref` IS NOT NEW.`ref` OR OLD.`sha` IS NOT NEW.`sha` OR OLD.`parent_shas_json` IS NOT NEW.`parent_shas_json` OR OLD.`author_name` IS NOT NEW.`author_name` OR OLD.`author_email` IS NOT NEW.`author_email` OR OLD.`subject` IS NOT NEW.`subject` OR OLD.`committed_at` IS NOT NEW.`committed_at`)
|
|
902
|
+
BEGIN
|
|
903
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
904
|
+
VALUES ('project_commits', NEW.`id`, 'upsert', OLD.`row_version`, (SELECT json_group_array(`c`) FROM (SELECT 'id' AS `c` WHERE OLD.`id` IS NOT NEW.`id` UNION ALL SELECT 'project_id' AS `c` WHERE OLD.`project_id` IS NOT NEW.`project_id` UNION ALL SELECT 'ref' AS `c` WHERE OLD.`ref` IS NOT NEW.`ref` UNION ALL SELECT 'sha' AS `c` WHERE OLD.`sha` IS NOT NEW.`sha` UNION ALL SELECT 'parent_shas_json' AS `c` WHERE OLD.`parent_shas_json` IS NOT NEW.`parent_shas_json` UNION ALL SELECT 'author_name' AS `c` WHERE OLD.`author_name` IS NOT NEW.`author_name` UNION ALL SELECT 'author_email' AS `c` WHERE OLD.`author_email` IS NOT NEW.`author_email` UNION ALL SELECT 'subject' AS `c` WHERE OLD.`subject` IS NOT NEW.`subject` UNION ALL SELECT 'committed_at' AS `c` WHERE OLD.`committed_at` IS NOT NEW.`committed_at`)), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
905
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
906
|
+
END;
|
|
907
|
+
|
|
908
|
+
CREATE TRIGGER `project_commits_outbox_delete` AFTER DELETE ON `project_commits` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
909
|
+
BEGIN
|
|
910
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
911
|
+
VALUES ('project_commits', OLD.`id`, 'delete', OLD.`row_version`, '[]', CAST(unixepoch('subsec') * 1000 AS integer))
|
|
912
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'delete', `changed_json` = '[]', `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
913
|
+
END;
|
|
914
|
+
|
|
915
|
+
CREATE TRIGGER `session_label_rows_outbox_insert` AFTER INSERT ON `session_label_rows` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
916
|
+
BEGIN
|
|
917
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
918
|
+
VALUES ('session_label_rows', NEW.`id`, 'upsert', 0, json_array('id', 'session_id', 'project_id', 'agent_type', 'path', 'estimated_tokens', 'returned_tokens', 'handler', 'check_result', 'is_bypass_used', 'latency_ms', 'tokens_kept_out', 'created_at'), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
919
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
920
|
+
END;
|
|
921
|
+
|
|
922
|
+
CREATE TRIGGER `session_label_rows_outbox_update` AFTER UPDATE ON `session_label_rows` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying') AND (OLD.`id` IS NOT NEW.`id` OR OLD.`session_id` IS NOT NEW.`session_id` OR OLD.`project_id` IS NOT NEW.`project_id` OR OLD.`agent_type` IS NOT NEW.`agent_type` OR OLD.`path` IS NOT NEW.`path` OR OLD.`estimated_tokens` IS NOT NEW.`estimated_tokens` OR OLD.`returned_tokens` IS NOT NEW.`returned_tokens` OR OLD.`handler` IS NOT NEW.`handler` OR OLD.`check_result` IS NOT NEW.`check_result` OR OLD.`is_bypass_used` IS NOT NEW.`is_bypass_used` OR OLD.`latency_ms` IS NOT NEW.`latency_ms` OR OLD.`tokens_kept_out` IS NOT NEW.`tokens_kept_out` OR OLD.`created_at` IS NOT NEW.`created_at`)
|
|
923
|
+
BEGIN
|
|
924
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
925
|
+
VALUES ('session_label_rows', NEW.`id`, 'upsert', OLD.`row_version`, (SELECT json_group_array(`c`) FROM (SELECT 'id' AS `c` WHERE OLD.`id` IS NOT NEW.`id` UNION ALL SELECT 'session_id' AS `c` WHERE OLD.`session_id` IS NOT NEW.`session_id` UNION ALL SELECT 'project_id' AS `c` WHERE OLD.`project_id` IS NOT NEW.`project_id` UNION ALL SELECT 'agent_type' AS `c` WHERE OLD.`agent_type` IS NOT NEW.`agent_type` UNION ALL SELECT 'path' AS `c` WHERE OLD.`path` IS NOT NEW.`path` UNION ALL SELECT 'estimated_tokens' AS `c` WHERE OLD.`estimated_tokens` IS NOT NEW.`estimated_tokens` UNION ALL SELECT 'returned_tokens' AS `c` WHERE OLD.`returned_tokens` IS NOT NEW.`returned_tokens` UNION ALL SELECT 'handler' AS `c` WHERE OLD.`handler` IS NOT NEW.`handler` UNION ALL SELECT 'check_result' AS `c` WHERE OLD.`check_result` IS NOT NEW.`check_result` UNION ALL SELECT 'is_bypass_used' AS `c` WHERE OLD.`is_bypass_used` IS NOT NEW.`is_bypass_used` UNION ALL SELECT 'latency_ms' AS `c` WHERE OLD.`latency_ms` IS NOT NEW.`latency_ms` UNION ALL SELECT 'tokens_kept_out' AS `c` WHERE OLD.`tokens_kept_out` IS NOT NEW.`tokens_kept_out` UNION ALL SELECT 'created_at' AS `c` WHERE OLD.`created_at` IS NOT NEW.`created_at`)), CAST(unixepoch('subsec') * 1000 AS integer))
|
|
926
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'upsert', `changed_json` = (SELECT json_group_array(`value`) FROM (SELECT `value` FROM json_each(`sync_outbox`.`changed_json`) UNION SELECT `value` FROM json_each(excluded.`changed_json`))), `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
927
|
+
END;
|
|
928
|
+
|
|
929
|
+
CREATE TRIGGER `session_label_rows_outbox_delete` AFTER DELETE ON `session_label_rows` WHEN NOT EXISTS (SELECT 1 FROM `sync_state` WHERE `name` = 'applying')
|
|
930
|
+
BEGIN
|
|
931
|
+
INSERT INTO `sync_outbox` (`table_name`, `row_key`, `op`, `base_version`, `changed_json`, `enqueued_at`)
|
|
932
|
+
VALUES ('session_label_rows', OLD.`id`, 'delete', OLD.`row_version`, '[]', CAST(unixepoch('subsec') * 1000 AS integer))
|
|
933
|
+
ON CONFLICT (`table_name`, `row_key`) DO UPDATE SET `op` = 'delete', `changed_json` = '[]', `enqueued_at` = excluded.`enqueued_at`, `attempts` = 0, `next_attempt_at` = NULL, `last_error` = NULL;
|
|
934
|
+
END;
|