aiden-runtime 4.9.1 → 4.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -1
- package/dist/cli/v4/aidenPrompt.js +12 -0
- package/dist/cli/v4/chatSession.js +41 -13
- package/dist/cli/v4/commands/channel.js +4 -6
- package/dist/cli/v4/commands/cron.js +6 -1
- package/dist/cli/v4/commands/daemonDoctor.js +5 -5
- package/dist/cli/v4/commands/daemonStatus.js +1 -1
- package/dist/cli/v4/commands/greeter.js +86 -0
- package/dist/cli/v4/commands/help.js +2 -0
- package/dist/cli/v4/commands/index.js +4 -0
- package/dist/cli/v4/commands/mcp.js +2 -2
- package/dist/cli/v4/commands/plugins.js +4 -6
- package/dist/cli/v4/commands/trigger.js +18 -18
- package/dist/cli/v4/confirmPrompt.js +67 -0
- package/dist/cli/v4/greeter/history.js +134 -0
- package/dist/cli/v4/greeter/index.js +147 -0
- package/dist/cli/v4/greeter/scan.js +140 -0
- package/dist/cli/v4/greeter/selectOffer.js +118 -0
- package/dist/cli/v4/greeter/templates.js +51 -0
- package/dist/cli/v4/greeter/types.js +23 -0
- package/dist/core/v4/daemon/db/migrations.js +398 -398
- package/dist/core/v4/daemon/idempotency/runIdempotencyStore.js +10 -10
- package/dist/core/v4/daemon/incarnationStore.js +9 -9
- package/dist/core/v4/daemon/runs/attemptStore.js +8 -8
- package/dist/core/v4/daemon/runs/reclaim.js +12 -12
- package/dist/core/v4/daemon/runs/stuckAttemptWatchdog.js +19 -19
- package/dist/core/v4/daemon/spans/spanStore.js +14 -14
- package/dist/core/v4/daemon/triggerBus.js +61 -61
- package/dist/core/v4/hooks/auditQuery.js +11 -11
- package/dist/core/v4/hooks/dispatcher.js +13 -13
- package/dist/core/v4/hooks/registry.js +8 -8
- package/dist/core/v4/mcp/transport.js +9 -9
- package/dist/core/v4/update/executeInstall.js +29 -18
- package/dist/core/v4/update/recoveryScript.js +70 -0
- package/dist/core/v4/util/spawnCommand.js +151 -0
- package/package.json +1 -1
- package/themes/default.yaml +52 -52
- package/themes/dracula.yaml +32 -32
- package/themes/light.yaml +32 -32
- package/themes/monochrome.yaml +31 -31
- package/themes/tokyo-night.yaml +32 -32
|
@@ -28,241 +28,241 @@ exports.runMigrations = runMigrations;
|
|
|
28
28
|
// Embedded v1 schema. Source of truth lives at
|
|
29
29
|
// `core/v4/daemon/db/schema/v1.sql` — kept in sync via the
|
|
30
30
|
// `tests/v4/daemon/db/migrations.test.ts` snapshot check.
|
|
31
|
-
const V1_SQL = `
|
|
32
|
-
CREATE TABLE IF NOT EXISTS schema_version (
|
|
33
|
-
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
34
|
-
version INTEGER NOT NULL,
|
|
35
|
-
applied_at INTEGER NOT NULL
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
CREATE TABLE IF NOT EXISTS daemon_instances (
|
|
39
|
-
instance_id TEXT PRIMARY KEY,
|
|
40
|
-
pid INTEGER NOT NULL,
|
|
41
|
-
hostname TEXT NOT NULL,
|
|
42
|
-
started_at INTEGER NOT NULL,
|
|
43
|
-
last_heartbeat INTEGER NOT NULL,
|
|
44
|
-
shutdown_at INTEGER,
|
|
45
|
-
shutdown_reason TEXT,
|
|
46
|
-
exit_code INTEGER,
|
|
47
|
-
version TEXT NOT NULL
|
|
48
|
-
);
|
|
49
|
-
CREATE INDEX IF NOT EXISTS idx_daemon_instances_alive
|
|
50
|
-
ON daemon_instances(shutdown_at) WHERE shutdown_at IS NULL;
|
|
51
|
-
|
|
52
|
-
CREATE TABLE IF NOT EXISTS runs (
|
|
53
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
54
|
-
trigger_event_id INTEGER,
|
|
55
|
-
session_id TEXT NOT NULL,
|
|
56
|
-
instance_id TEXT NOT NULL,
|
|
57
|
-
status TEXT NOT NULL,
|
|
58
|
-
finish_reason TEXT,
|
|
59
|
-
started_at INTEGER NOT NULL,
|
|
60
|
-
completed_at INTEGER,
|
|
61
|
-
resume_pending INTEGER NOT NULL DEFAULT 0,
|
|
62
|
-
resume_reason TEXT,
|
|
63
|
-
FOREIGN KEY (instance_id) REFERENCES daemon_instances(instance_id) ON DELETE CASCADE
|
|
64
|
-
);
|
|
65
|
-
CREATE INDEX IF NOT EXISTS idx_runs_session ON runs(session_id, started_at);
|
|
66
|
-
CREATE INDEX IF NOT EXISTS idx_runs_active
|
|
67
|
-
ON runs(status) WHERE status IN ('queued','running');
|
|
68
|
-
|
|
69
|
-
CREATE TABLE IF NOT EXISTS trigger_events (
|
|
70
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
-
source TEXT NOT NULL,
|
|
72
|
-
source_key TEXT NOT NULL,
|
|
73
|
-
idempotency_key TEXT,
|
|
74
|
-
payload_json TEXT NOT NULL,
|
|
75
|
-
status TEXT NOT NULL,
|
|
76
|
-
attempts INTEGER NOT NULL DEFAULT 0,
|
|
77
|
-
claim_owner TEXT,
|
|
78
|
-
claim_expires_at INTEGER,
|
|
79
|
-
last_error TEXT,
|
|
80
|
-
created_at INTEGER NOT NULL,
|
|
81
|
-
updated_at INTEGER NOT NULL,
|
|
82
|
-
completed_at INTEGER,
|
|
83
|
-
run_id INTEGER,
|
|
84
|
-
FOREIGN KEY (run_id) REFERENCES runs(id) ON DELETE SET NULL
|
|
85
|
-
);
|
|
86
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_trigger_events_idem
|
|
87
|
-
ON trigger_events(source, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
88
|
-
CREATE INDEX IF NOT EXISTS idx_trigger_events_pending
|
|
89
|
-
ON trigger_events(status, created_at) WHERE status IN ('pending','claimed');
|
|
90
|
-
CREATE INDEX IF NOT EXISTS idx_trigger_events_claim_expiry
|
|
91
|
-
ON trigger_events(claim_expires_at) WHERE status = 'claimed';
|
|
92
|
-
|
|
93
|
-
CREATE TABLE IF NOT EXISTS run_events (
|
|
94
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
95
|
-
run_id INTEGER NOT NULL,
|
|
96
|
-
ts INTEGER NOT NULL,
|
|
97
|
-
kind TEXT NOT NULL,
|
|
98
|
-
payload TEXT NOT NULL,
|
|
99
|
-
FOREIGN KEY (run_id) REFERENCES runs(id) ON DELETE CASCADE
|
|
100
|
-
);
|
|
101
|
-
CREATE INDEX IF NOT EXISTS idx_run_events_run ON run_events(run_id, ts);
|
|
102
|
-
|
|
103
|
-
CREATE TABLE IF NOT EXISTS idempotency_keys (
|
|
104
|
-
scope TEXT NOT NULL,
|
|
105
|
-
key TEXT NOT NULL,
|
|
106
|
-
fingerprint TEXT,
|
|
107
|
-
response_json TEXT NOT NULL,
|
|
108
|
-
status_code INTEGER NOT NULL DEFAULT 200,
|
|
109
|
-
created_at INTEGER NOT NULL,
|
|
110
|
-
expires_at INTEGER NOT NULL,
|
|
111
|
-
PRIMARY KEY (scope, key)
|
|
112
|
-
);
|
|
113
|
-
CREATE INDEX IF NOT EXISTS idx_idem_expiry ON idempotency_keys(expires_at);
|
|
114
|
-
|
|
115
|
-
CREATE TABLE IF NOT EXISTS crash_reports (
|
|
116
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
117
|
-
instance_id TEXT NOT NULL,
|
|
118
|
-
detected_at INTEGER NOT NULL,
|
|
119
|
-
prev_started_at INTEGER,
|
|
120
|
-
prev_last_heartbeat INTEGER,
|
|
121
|
-
prev_pid INTEGER,
|
|
122
|
-
affected_sessions TEXT NOT NULL,
|
|
123
|
-
ps_snapshot TEXT,
|
|
124
|
-
details TEXT NOT NULL,
|
|
125
|
-
FOREIGN KEY (instance_id) REFERENCES daemon_instances(instance_id) ON DELETE CASCADE
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
CREATE TABLE IF NOT EXISTS restart_failure_counts (
|
|
129
|
-
session_id TEXT PRIMARY KEY,
|
|
130
|
-
count INTEGER NOT NULL,
|
|
131
|
-
last_failure INTEGER NOT NULL,
|
|
132
|
-
auto_suspended INTEGER NOT NULL DEFAULT 0
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
CREATE TABLE IF NOT EXISTS triggers (
|
|
136
|
-
id TEXT PRIMARY KEY,
|
|
137
|
-
source TEXT NOT NULL,
|
|
138
|
-
name TEXT NOT NULL,
|
|
139
|
-
spec_json TEXT NOT NULL,
|
|
140
|
-
enabled INTEGER NOT NULL DEFAULT 1,
|
|
141
|
-
fire_rate_limit INTEGER,
|
|
142
|
-
prompt_template TEXT,
|
|
143
|
-
deliver_only INTEGER NOT NULL DEFAULT 0,
|
|
144
|
-
created_at INTEGER NOT NULL,
|
|
145
|
-
updated_at INTEGER NOT NULL
|
|
146
|
-
);
|
|
147
|
-
CREATE INDEX IF NOT EXISTS idx_triggers_source_enabled ON triggers(source, enabled);
|
|
31
|
+
const V1_SQL = `
|
|
32
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
33
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
34
|
+
version INTEGER NOT NULL,
|
|
35
|
+
applied_at INTEGER NOT NULL
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
CREATE TABLE IF NOT EXISTS daemon_instances (
|
|
39
|
+
instance_id TEXT PRIMARY KEY,
|
|
40
|
+
pid INTEGER NOT NULL,
|
|
41
|
+
hostname TEXT NOT NULL,
|
|
42
|
+
started_at INTEGER NOT NULL,
|
|
43
|
+
last_heartbeat INTEGER NOT NULL,
|
|
44
|
+
shutdown_at INTEGER,
|
|
45
|
+
shutdown_reason TEXT,
|
|
46
|
+
exit_code INTEGER,
|
|
47
|
+
version TEXT NOT NULL
|
|
48
|
+
);
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_daemon_instances_alive
|
|
50
|
+
ON daemon_instances(shutdown_at) WHERE shutdown_at IS NULL;
|
|
51
|
+
|
|
52
|
+
CREATE TABLE IF NOT EXISTS runs (
|
|
53
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
54
|
+
trigger_event_id INTEGER,
|
|
55
|
+
session_id TEXT NOT NULL,
|
|
56
|
+
instance_id TEXT NOT NULL,
|
|
57
|
+
status TEXT NOT NULL,
|
|
58
|
+
finish_reason TEXT,
|
|
59
|
+
started_at INTEGER NOT NULL,
|
|
60
|
+
completed_at INTEGER,
|
|
61
|
+
resume_pending INTEGER NOT NULL DEFAULT 0,
|
|
62
|
+
resume_reason TEXT,
|
|
63
|
+
FOREIGN KEY (instance_id) REFERENCES daemon_instances(instance_id) ON DELETE CASCADE
|
|
64
|
+
);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_runs_session ON runs(session_id, started_at);
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_runs_active
|
|
67
|
+
ON runs(status) WHERE status IN ('queued','running');
|
|
68
|
+
|
|
69
|
+
CREATE TABLE IF NOT EXISTS trigger_events (
|
|
70
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
71
|
+
source TEXT NOT NULL,
|
|
72
|
+
source_key TEXT NOT NULL,
|
|
73
|
+
idempotency_key TEXT,
|
|
74
|
+
payload_json TEXT NOT NULL,
|
|
75
|
+
status TEXT NOT NULL,
|
|
76
|
+
attempts INTEGER NOT NULL DEFAULT 0,
|
|
77
|
+
claim_owner TEXT,
|
|
78
|
+
claim_expires_at INTEGER,
|
|
79
|
+
last_error TEXT,
|
|
80
|
+
created_at INTEGER NOT NULL,
|
|
81
|
+
updated_at INTEGER NOT NULL,
|
|
82
|
+
completed_at INTEGER,
|
|
83
|
+
run_id INTEGER,
|
|
84
|
+
FOREIGN KEY (run_id) REFERENCES runs(id) ON DELETE SET NULL
|
|
85
|
+
);
|
|
86
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_trigger_events_idem
|
|
87
|
+
ON trigger_events(source, idempotency_key) WHERE idempotency_key IS NOT NULL;
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_trigger_events_pending
|
|
89
|
+
ON trigger_events(status, created_at) WHERE status IN ('pending','claimed');
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_trigger_events_claim_expiry
|
|
91
|
+
ON trigger_events(claim_expires_at) WHERE status = 'claimed';
|
|
92
|
+
|
|
93
|
+
CREATE TABLE IF NOT EXISTS run_events (
|
|
94
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
95
|
+
run_id INTEGER NOT NULL,
|
|
96
|
+
ts INTEGER NOT NULL,
|
|
97
|
+
kind TEXT NOT NULL,
|
|
98
|
+
payload TEXT NOT NULL,
|
|
99
|
+
FOREIGN KEY (run_id) REFERENCES runs(id) ON DELETE CASCADE
|
|
100
|
+
);
|
|
101
|
+
CREATE INDEX IF NOT EXISTS idx_run_events_run ON run_events(run_id, ts);
|
|
102
|
+
|
|
103
|
+
CREATE TABLE IF NOT EXISTS idempotency_keys (
|
|
104
|
+
scope TEXT NOT NULL,
|
|
105
|
+
key TEXT NOT NULL,
|
|
106
|
+
fingerprint TEXT,
|
|
107
|
+
response_json TEXT NOT NULL,
|
|
108
|
+
status_code INTEGER NOT NULL DEFAULT 200,
|
|
109
|
+
created_at INTEGER NOT NULL,
|
|
110
|
+
expires_at INTEGER NOT NULL,
|
|
111
|
+
PRIMARY KEY (scope, key)
|
|
112
|
+
);
|
|
113
|
+
CREATE INDEX IF NOT EXISTS idx_idem_expiry ON idempotency_keys(expires_at);
|
|
114
|
+
|
|
115
|
+
CREATE TABLE IF NOT EXISTS crash_reports (
|
|
116
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
117
|
+
instance_id TEXT NOT NULL,
|
|
118
|
+
detected_at INTEGER NOT NULL,
|
|
119
|
+
prev_started_at INTEGER,
|
|
120
|
+
prev_last_heartbeat INTEGER,
|
|
121
|
+
prev_pid INTEGER,
|
|
122
|
+
affected_sessions TEXT NOT NULL,
|
|
123
|
+
ps_snapshot TEXT,
|
|
124
|
+
details TEXT NOT NULL,
|
|
125
|
+
FOREIGN KEY (instance_id) REFERENCES daemon_instances(instance_id) ON DELETE CASCADE
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
CREATE TABLE IF NOT EXISTS restart_failure_counts (
|
|
129
|
+
session_id TEXT PRIMARY KEY,
|
|
130
|
+
count INTEGER NOT NULL,
|
|
131
|
+
last_failure INTEGER NOT NULL,
|
|
132
|
+
auto_suspended INTEGER NOT NULL DEFAULT 0
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
CREATE TABLE IF NOT EXISTS triggers (
|
|
136
|
+
id TEXT PRIMARY KEY,
|
|
137
|
+
source TEXT NOT NULL,
|
|
138
|
+
name TEXT NOT NULL,
|
|
139
|
+
spec_json TEXT NOT NULL,
|
|
140
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
141
|
+
fire_rate_limit INTEGER,
|
|
142
|
+
prompt_template TEXT,
|
|
143
|
+
deliver_only INTEGER NOT NULL DEFAULT 0,
|
|
144
|
+
created_at INTEGER NOT NULL,
|
|
145
|
+
updated_at INTEGER NOT NULL
|
|
146
|
+
);
|
|
147
|
+
CREATE INDEX IF NOT EXISTS idx_triggers_source_enabled ON triggers(source, enabled);
|
|
148
148
|
`;
|
|
149
149
|
// v4.5 Phase 2 — file_observations table. Source of truth lives at
|
|
150
150
|
// `core/v4/daemon/db/schema/v2.sql`; kept in sync via the migrations
|
|
151
151
|
// test snapshot check.
|
|
152
|
-
const V2_SQL = `
|
|
153
|
-
CREATE TABLE IF NOT EXISTS file_observations (
|
|
154
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
155
|
-
watcher_id TEXT NOT NULL,
|
|
156
|
-
abs_path TEXT NOT NULL,
|
|
157
|
-
file_key TEXT NOT NULL DEFAULT '',
|
|
158
|
-
size INTEGER,
|
|
159
|
-
mtime_ms INTEGER NOT NULL,
|
|
160
|
-
content_hash TEXT,
|
|
161
|
-
last_event_type TEXT,
|
|
162
|
-
last_seen_at INTEGER NOT NULL,
|
|
163
|
-
last_processed_at INTEGER,
|
|
164
|
-
last_event_id INTEGER,
|
|
165
|
-
last_status TEXT NOT NULL DEFAULT 'pending',
|
|
166
|
-
coalesced_count INTEGER NOT NULL DEFAULT 0,
|
|
167
|
-
FOREIGN KEY (watcher_id) REFERENCES triggers(id) ON DELETE CASCADE,
|
|
168
|
-
FOREIGN KEY (last_event_id) REFERENCES trigger_events(id) ON DELETE SET NULL
|
|
169
|
-
);
|
|
170
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_file_obs_watcher_path
|
|
171
|
-
ON file_observations(watcher_id, abs_path);
|
|
172
|
-
CREATE INDEX IF NOT EXISTS idx_file_obs_last_seen
|
|
173
|
-
ON file_observations(last_seen_at);
|
|
174
|
-
CREATE INDEX IF NOT EXISTS idx_file_obs_pending
|
|
175
|
-
ON file_observations(watcher_id, last_status) WHERE last_status = 'pending';
|
|
152
|
+
const V2_SQL = `
|
|
153
|
+
CREATE TABLE IF NOT EXISTS file_observations (
|
|
154
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
155
|
+
watcher_id TEXT NOT NULL,
|
|
156
|
+
abs_path TEXT NOT NULL,
|
|
157
|
+
file_key TEXT NOT NULL DEFAULT '',
|
|
158
|
+
size INTEGER,
|
|
159
|
+
mtime_ms INTEGER NOT NULL,
|
|
160
|
+
content_hash TEXT,
|
|
161
|
+
last_event_type TEXT,
|
|
162
|
+
last_seen_at INTEGER NOT NULL,
|
|
163
|
+
last_processed_at INTEGER,
|
|
164
|
+
last_event_id INTEGER,
|
|
165
|
+
last_status TEXT NOT NULL DEFAULT 'pending',
|
|
166
|
+
coalesced_count INTEGER NOT NULL DEFAULT 0,
|
|
167
|
+
FOREIGN KEY (watcher_id) REFERENCES triggers(id) ON DELETE CASCADE,
|
|
168
|
+
FOREIGN KEY (last_event_id) REFERENCES trigger_events(id) ON DELETE SET NULL
|
|
169
|
+
);
|
|
170
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_file_obs_watcher_path
|
|
171
|
+
ON file_observations(watcher_id, abs_path);
|
|
172
|
+
CREATE INDEX IF NOT EXISTS idx_file_obs_last_seen
|
|
173
|
+
ON file_observations(last_seen_at);
|
|
174
|
+
CREATE INDEX IF NOT EXISTS idx_file_obs_pending
|
|
175
|
+
ON file_observations(watcher_id, last_status) WHERE last_status = 'pending';
|
|
176
176
|
`;
|
|
177
177
|
// v4.5 Phase 3 — webhook_deliveries log.
|
|
178
|
-
const V3_SQL = `
|
|
179
|
-
CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
|
180
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
181
|
-
route_id TEXT NOT NULL,
|
|
182
|
-
delivery_id TEXT,
|
|
183
|
-
signature_verified INTEGER NOT NULL,
|
|
184
|
-
status_code INTEGER NOT NULL,
|
|
185
|
-
response_body TEXT,
|
|
186
|
-
client_ip TEXT,
|
|
187
|
-
headers_json TEXT,
|
|
188
|
-
body_hash TEXT NOT NULL,
|
|
189
|
-
received_at INTEGER NOT NULL,
|
|
190
|
-
processed_at INTEGER,
|
|
191
|
-
trigger_event_id INTEGER,
|
|
192
|
-
FOREIGN KEY (route_id) REFERENCES triggers(id) ON DELETE CASCADE,
|
|
193
|
-
FOREIGN KEY (trigger_event_id) REFERENCES trigger_events(id) ON DELETE SET NULL
|
|
194
|
-
);
|
|
195
|
-
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_route_time
|
|
196
|
-
ON webhook_deliveries(route_id, received_at);
|
|
197
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_webhook_deliveries_delivery
|
|
198
|
-
ON webhook_deliveries(route_id, delivery_id) WHERE delivery_id IS NOT NULL;
|
|
199
|
-
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_received
|
|
200
|
-
ON webhook_deliveries(received_at);
|
|
178
|
+
const V3_SQL = `
|
|
179
|
+
CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
|
180
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
181
|
+
route_id TEXT NOT NULL,
|
|
182
|
+
delivery_id TEXT,
|
|
183
|
+
signature_verified INTEGER NOT NULL,
|
|
184
|
+
status_code INTEGER NOT NULL,
|
|
185
|
+
response_body TEXT,
|
|
186
|
+
client_ip TEXT,
|
|
187
|
+
headers_json TEXT,
|
|
188
|
+
body_hash TEXT NOT NULL,
|
|
189
|
+
received_at INTEGER NOT NULL,
|
|
190
|
+
processed_at INTEGER,
|
|
191
|
+
trigger_event_id INTEGER,
|
|
192
|
+
FOREIGN KEY (route_id) REFERENCES triggers(id) ON DELETE CASCADE,
|
|
193
|
+
FOREIGN KEY (trigger_event_id) REFERENCES trigger_events(id) ON DELETE SET NULL
|
|
194
|
+
);
|
|
195
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_route_time
|
|
196
|
+
ON webhook_deliveries(route_id, received_at);
|
|
197
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_webhook_deliveries_delivery
|
|
198
|
+
ON webhook_deliveries(route_id, delivery_id) WHERE delivery_id IS NOT NULL;
|
|
199
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_received
|
|
200
|
+
ON webhook_deliveries(received_at);
|
|
201
201
|
`;
|
|
202
202
|
// v4.5 Phase 4a — email_seen forensic table.
|
|
203
|
-
const V4_SQL = `
|
|
204
|
-
CREATE TABLE IF NOT EXISTS email_seen (
|
|
205
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
206
|
-
route_id TEXT NOT NULL,
|
|
207
|
-
mailbox TEXT NOT NULL,
|
|
208
|
-
uid_validity INTEGER NOT NULL,
|
|
209
|
-
uid INTEGER NOT NULL,
|
|
210
|
-
message_id TEXT,
|
|
211
|
-
from_address TEXT,
|
|
212
|
-
subject TEXT,
|
|
213
|
-
received_at INTEGER NOT NULL,
|
|
214
|
-
processed_at INTEGER,
|
|
215
|
-
trigger_event_id INTEGER,
|
|
216
|
-
status TEXT NOT NULL,
|
|
217
|
-
FOREIGN KEY (route_id) REFERENCES triggers(id) ON DELETE CASCADE,
|
|
218
|
-
FOREIGN KEY (trigger_event_id) REFERENCES trigger_events(id) ON DELETE SET NULL
|
|
219
|
-
);
|
|
220
|
-
CREATE UNIQUE INDEX IF NOT EXISTS idx_email_seen_route_uid
|
|
221
|
-
ON email_seen(route_id, uid_validity, uid);
|
|
222
|
-
CREATE INDEX IF NOT EXISTS idx_email_seen_received
|
|
223
|
-
ON email_seen(received_at);
|
|
224
|
-
CREATE INDEX IF NOT EXISTS idx_email_seen_message_id
|
|
225
|
-
ON email_seen(message_id) WHERE message_id IS NOT NULL;
|
|
203
|
+
const V4_SQL = `
|
|
204
|
+
CREATE TABLE IF NOT EXISTS email_seen (
|
|
205
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
206
|
+
route_id TEXT NOT NULL,
|
|
207
|
+
mailbox TEXT NOT NULL,
|
|
208
|
+
uid_validity INTEGER NOT NULL,
|
|
209
|
+
uid INTEGER NOT NULL,
|
|
210
|
+
message_id TEXT,
|
|
211
|
+
from_address TEXT,
|
|
212
|
+
subject TEXT,
|
|
213
|
+
received_at INTEGER NOT NULL,
|
|
214
|
+
processed_at INTEGER,
|
|
215
|
+
trigger_event_id INTEGER,
|
|
216
|
+
status TEXT NOT NULL,
|
|
217
|
+
FOREIGN KEY (route_id) REFERENCES triggers(id) ON DELETE CASCADE,
|
|
218
|
+
FOREIGN KEY (trigger_event_id) REFERENCES trigger_events(id) ON DELETE SET NULL
|
|
219
|
+
);
|
|
220
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_email_seen_route_uid
|
|
221
|
+
ON email_seen(route_id, uid_validity, uid);
|
|
222
|
+
CREATE INDEX IF NOT EXISTS idx_email_seen_received
|
|
223
|
+
ON email_seen(received_at);
|
|
224
|
+
CREATE INDEX IF NOT EXISTS idx_email_seen_message_id
|
|
225
|
+
ON email_seen(message_id) WHERE message_id IS NOT NULL;
|
|
226
226
|
`;
|
|
227
227
|
// v4.5 Phase 5b — scheduled_workflows table (cron migration from JSON
|
|
228
228
|
// to SQLite). One-shot data migration from `cron_jobs.json` runs from
|
|
229
229
|
// the daemon bootstrap after this schema applies, not from inside the
|
|
230
230
|
// DDL transaction itself — keeps schema-only migrations idempotent.
|
|
231
|
-
const V5_SQL = `
|
|
232
|
-
CREATE TABLE IF NOT EXISTS scheduled_workflows (
|
|
233
|
-
id TEXT PRIMARY KEY,
|
|
234
|
-
name TEXT NOT NULL,
|
|
235
|
-
schedule_expression TEXT NOT NULL,
|
|
236
|
-
timezone TEXT NOT NULL DEFAULT 'UTC',
|
|
237
|
-
enabled INTEGER NOT NULL DEFAULT 1,
|
|
238
|
-
payload_json TEXT NOT NULL,
|
|
239
|
-
prompt_template TEXT,
|
|
240
|
-
deliver_only INTEGER NOT NULL DEFAULT 0,
|
|
241
|
-
misfire_policy TEXT NOT NULL DEFAULT 'skip_stale',
|
|
242
|
-
fire_rate_limit INTEGER,
|
|
243
|
-
catch_up_limit INTEGER,
|
|
244
|
-
grace_ms INTEGER,
|
|
245
|
-
last_fired_at INTEGER,
|
|
246
|
-
next_fire_at INTEGER,
|
|
247
|
-
created_at INTEGER NOT NULL,
|
|
248
|
-
updated_at INTEGER NOT NULL
|
|
249
|
-
);
|
|
250
|
-
CREATE INDEX IF NOT EXISTS idx_scheduled_workflows_next_fire
|
|
251
|
-
ON scheduled_workflows(next_fire_at) WHERE enabled = 1;
|
|
252
|
-
CREATE INDEX IF NOT EXISTS idx_scheduled_workflows_enabled
|
|
253
|
-
ON scheduled_workflows(enabled);
|
|
231
|
+
const V5_SQL = `
|
|
232
|
+
CREATE TABLE IF NOT EXISTS scheduled_workflows (
|
|
233
|
+
id TEXT PRIMARY KEY,
|
|
234
|
+
name TEXT NOT NULL,
|
|
235
|
+
schedule_expression TEXT NOT NULL,
|
|
236
|
+
timezone TEXT NOT NULL DEFAULT 'UTC',
|
|
237
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
238
|
+
payload_json TEXT NOT NULL,
|
|
239
|
+
prompt_template TEXT,
|
|
240
|
+
deliver_only INTEGER NOT NULL DEFAULT 0,
|
|
241
|
+
misfire_policy TEXT NOT NULL DEFAULT 'skip_stale',
|
|
242
|
+
fire_rate_limit INTEGER,
|
|
243
|
+
catch_up_limit INTEGER,
|
|
244
|
+
grace_ms INTEGER,
|
|
245
|
+
last_fired_at INTEGER,
|
|
246
|
+
next_fire_at INTEGER,
|
|
247
|
+
created_at INTEGER NOT NULL,
|
|
248
|
+
updated_at INTEGER NOT NULL
|
|
249
|
+
);
|
|
250
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_workflows_next_fire
|
|
251
|
+
ON scheduled_workflows(next_fire_at) WHERE enabled = 1;
|
|
252
|
+
CREATE INDEX IF NOT EXISTS idx_scheduled_workflows_enabled
|
|
253
|
+
ON scheduled_workflows(enabled);
|
|
254
254
|
`;
|
|
255
255
|
// Embedded v6 schema. Source of truth lives at
|
|
256
256
|
// `core/v4/daemon/db/schema/v6.sql` (matching v1-v4 convention).
|
|
257
257
|
// Kept in sync via the `tests/v4/daemon/db/migrations-v6.test.ts`
|
|
258
258
|
// snapshot check.
|
|
259
|
-
const V6_SQL = `
|
|
260
|
-
ALTER TABLE runs ADD COLUMN spawned_from_run_id INTEGER;
|
|
261
|
-
ALTER TABLE runs ADD COLUMN spawned_from_session_id TEXT;
|
|
262
|
-
|
|
263
|
-
CREATE INDEX IF NOT EXISTS idx_runs_spawned_from
|
|
264
|
-
ON runs(spawned_from_run_id)
|
|
265
|
-
WHERE spawned_from_run_id IS NOT NULL;
|
|
259
|
+
const V6_SQL = `
|
|
260
|
+
ALTER TABLE runs ADD COLUMN spawned_from_run_id INTEGER;
|
|
261
|
+
ALTER TABLE runs ADD COLUMN spawned_from_session_id TEXT;
|
|
262
|
+
|
|
263
|
+
CREATE INDEX IF NOT EXISTS idx_runs_spawned_from
|
|
264
|
+
ON runs(spawned_from_run_id)
|
|
265
|
+
WHERE spawned_from_run_id IS NOT NULL;
|
|
266
266
|
`;
|
|
267
267
|
// Embedded v7 schema. Source of truth at
|
|
268
268
|
// `core/v4/daemon/db/schema/v7.sql` (same convention). Kept in
|
|
@@ -277,44 +277,44 @@ CREATE INDEX IF NOT EXISTS idx_runs_spawned_from
|
|
|
277
277
|
// * `recovery_reports` — one row per observed failure → success
|
|
278
278
|
// transition; carries the strategy that worked + verification +
|
|
279
279
|
// free-text notes for operator review.
|
|
280
|
-
const V7_SQL = `
|
|
281
|
-
CREATE TABLE IF NOT EXISTS failure_signatures (
|
|
282
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
283
|
-
signature TEXT UNIQUE NOT NULL,
|
|
284
|
-
tool_name TEXT NOT NULL,
|
|
285
|
-
failure_category TEXT NOT NULL,
|
|
286
|
-
args_hash TEXT,
|
|
287
|
-
first_seen_at INTEGER NOT NULL,
|
|
288
|
-
last_seen_at INTEGER NOT NULL,
|
|
289
|
-
occurrences INTEGER NOT NULL DEFAULT 1,
|
|
290
|
-
recovered_count INTEGER NOT NULL DEFAULT 0,
|
|
291
|
-
last_recovery_report_id INTEGER
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
CREATE INDEX IF NOT EXISTS idx_failure_signatures_signature
|
|
295
|
-
ON failure_signatures(signature);
|
|
296
|
-
|
|
297
|
-
CREATE INDEX IF NOT EXISTS idx_failure_signatures_tool
|
|
298
|
-
ON failure_signatures(tool_name);
|
|
299
|
-
|
|
300
|
-
CREATE TABLE IF NOT EXISTS recovery_reports (
|
|
301
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
302
|
-
signature_id INTEGER NOT NULL REFERENCES failure_signatures(id),
|
|
303
|
-
run_id INTEGER REFERENCES runs(id),
|
|
304
|
-
session_id TEXT,
|
|
305
|
-
failed_attempts INTEGER NOT NULL,
|
|
306
|
-
successful_strategy TEXT NOT NULL,
|
|
307
|
-
changed_parameters TEXT,
|
|
308
|
-
verification TEXT,
|
|
309
|
-
created_at INTEGER NOT NULL,
|
|
310
|
-
notes TEXT
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
CREATE INDEX IF NOT EXISTS idx_recovery_reports_signature
|
|
314
|
-
ON recovery_reports(signature_id);
|
|
315
|
-
|
|
316
|
-
CREATE INDEX IF NOT EXISTS idx_recovery_reports_run
|
|
317
|
-
ON recovery_reports(run_id);
|
|
280
|
+
const V7_SQL = `
|
|
281
|
+
CREATE TABLE IF NOT EXISTS failure_signatures (
|
|
282
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
283
|
+
signature TEXT UNIQUE NOT NULL,
|
|
284
|
+
tool_name TEXT NOT NULL,
|
|
285
|
+
failure_category TEXT NOT NULL,
|
|
286
|
+
args_hash TEXT,
|
|
287
|
+
first_seen_at INTEGER NOT NULL,
|
|
288
|
+
last_seen_at INTEGER NOT NULL,
|
|
289
|
+
occurrences INTEGER NOT NULL DEFAULT 1,
|
|
290
|
+
recovered_count INTEGER NOT NULL DEFAULT 0,
|
|
291
|
+
last_recovery_report_id INTEGER
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
CREATE INDEX IF NOT EXISTS idx_failure_signatures_signature
|
|
295
|
+
ON failure_signatures(signature);
|
|
296
|
+
|
|
297
|
+
CREATE INDEX IF NOT EXISTS idx_failure_signatures_tool
|
|
298
|
+
ON failure_signatures(tool_name);
|
|
299
|
+
|
|
300
|
+
CREATE TABLE IF NOT EXISTS recovery_reports (
|
|
301
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
302
|
+
signature_id INTEGER NOT NULL REFERENCES failure_signatures(id),
|
|
303
|
+
run_id INTEGER REFERENCES runs(id),
|
|
304
|
+
session_id TEXT,
|
|
305
|
+
failed_attempts INTEGER NOT NULL,
|
|
306
|
+
successful_strategy TEXT NOT NULL,
|
|
307
|
+
changed_parameters TEXT,
|
|
308
|
+
verification TEXT,
|
|
309
|
+
created_at INTEGER NOT NULL,
|
|
310
|
+
notes TEXT
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
CREATE INDEX IF NOT EXISTS idx_recovery_reports_signature
|
|
314
|
+
ON recovery_reports(signature_id);
|
|
315
|
+
|
|
316
|
+
CREATE INDEX IF NOT EXISTS idx_recovery_reports_run
|
|
317
|
+
ON recovery_reports(run_id);
|
|
318
318
|
`;
|
|
319
319
|
// v4.9.0 Slice 4 — daemon_incarnations table. Source of truth lives at
|
|
320
320
|
// `core/v4/daemon/db/schema/v8.sql`; kept in sync via the migrations
|
|
@@ -322,163 +322,163 @@ CREATE INDEX IF NOT EXISTS idx_recovery_reports_run
|
|
|
322
322
|
// (which keeps its random-UUID instance_id intact for existing
|
|
323
323
|
// `evaluateBootState` / `reclaimStuckRuns` consumers); v8 introduces
|
|
324
324
|
// the persistent daemon identity + per-boot incarnation correlation.
|
|
325
|
-
const V8_SQL = `
|
|
326
|
-
CREATE TABLE IF NOT EXISTS daemon_incarnations (
|
|
327
|
-
incarnation_id TEXT PRIMARY KEY,
|
|
328
|
-
daemon_id TEXT NOT NULL,
|
|
329
|
-
pid INTEGER NOT NULL,
|
|
330
|
-
started_at TEXT NOT NULL,
|
|
331
|
-
ended_at TEXT,
|
|
332
|
-
exit_reason TEXT,
|
|
333
|
-
exit_code INTEGER,
|
|
334
|
-
aiden_version TEXT,
|
|
335
|
-
node_version TEXT
|
|
336
|
-
);
|
|
337
|
-
CREATE INDEX IF NOT EXISTS idx_incarnations_daemon
|
|
338
|
-
ON daemon_incarnations(daemon_id, started_at DESC);
|
|
325
|
+
const V8_SQL = `
|
|
326
|
+
CREATE TABLE IF NOT EXISTS daemon_incarnations (
|
|
327
|
+
incarnation_id TEXT PRIMARY KEY,
|
|
328
|
+
daemon_id TEXT NOT NULL,
|
|
329
|
+
pid INTEGER NOT NULL,
|
|
330
|
+
started_at TEXT NOT NULL,
|
|
331
|
+
ended_at TEXT,
|
|
332
|
+
exit_reason TEXT,
|
|
333
|
+
exit_code INTEGER,
|
|
334
|
+
aiden_version TEXT,
|
|
335
|
+
node_version TEXT
|
|
336
|
+
);
|
|
337
|
+
CREATE INDEX IF NOT EXISTS idx_incarnations_daemon
|
|
338
|
+
ON daemon_incarnations(daemon_id, started_at DESC);
|
|
339
339
|
`;
|
|
340
340
|
// v4.9.0 Slice 5 — durable run queue. Source of truth lives at
|
|
341
341
|
// `core/v4/daemon/db/schema/v9.sql`; kept in sync via the migrations
|
|
342
342
|
// test snapshot check.
|
|
343
|
-
const V9_SQL = `
|
|
344
|
-
CREATE TABLE IF NOT EXISTS run_attempts (
|
|
345
|
-
attempt_id TEXT PRIMARY KEY,
|
|
346
|
-
run_id INTEGER NOT NULL,
|
|
347
|
-
attempt_number INTEGER NOT NULL,
|
|
348
|
-
incarnation_id TEXT NOT NULL,
|
|
349
|
-
started_at TEXT NOT NULL,
|
|
350
|
-
ended_at TEXT,
|
|
351
|
-
status TEXT NOT NULL,
|
|
352
|
-
finish_reason TEXT,
|
|
353
|
-
error_class TEXT,
|
|
354
|
-
error_message TEXT,
|
|
355
|
-
FOREIGN KEY (run_id) REFERENCES runs(id) ON DELETE CASCADE
|
|
356
|
-
);
|
|
357
|
-
CREATE INDEX IF NOT EXISTS idx_run_attempts_run
|
|
358
|
-
ON run_attempts(run_id, attempt_number);
|
|
359
|
-
CREATE INDEX IF NOT EXISTS idx_run_attempts_incarnation
|
|
360
|
-
ON run_attempts(incarnation_id);
|
|
361
|
-
|
|
362
|
-
CREATE TABLE IF NOT EXISTS spans (
|
|
363
|
-
span_id TEXT PRIMARY KEY,
|
|
364
|
-
trace_id TEXT NOT NULL,
|
|
365
|
-
parent_span_id TEXT,
|
|
366
|
-
run_id INTEGER,
|
|
367
|
-
attempt_id TEXT,
|
|
368
|
-
incarnation_id TEXT NOT NULL,
|
|
369
|
-
kind TEXT NOT NULL,
|
|
370
|
-
name TEXT NOT NULL,
|
|
371
|
-
started_at TEXT NOT NULL,
|
|
372
|
-
ended_at TEXT,
|
|
373
|
-
status TEXT,
|
|
374
|
-
attrs_json TEXT,
|
|
375
|
-
error_class TEXT,
|
|
376
|
-
error_message TEXT
|
|
377
|
-
);
|
|
378
|
-
CREATE INDEX IF NOT EXISTS idx_spans_trace ON spans(trace_id, started_at);
|
|
379
|
-
CREATE INDEX IF NOT EXISTS idx_spans_run ON spans(run_id, started_at);
|
|
380
|
-
CREATE INDEX IF NOT EXISTS idx_spans_parent ON spans(parent_span_id);
|
|
381
|
-
|
|
382
|
-
CREATE TABLE IF NOT EXISTS run_idempotency_keys (
|
|
383
|
-
namespace TEXT NOT NULL,
|
|
384
|
-
key TEXT NOT NULL,
|
|
385
|
-
fingerprint TEXT NOT NULL,
|
|
386
|
-
run_id INTEGER,
|
|
387
|
-
trigger_event_id INTEGER,
|
|
388
|
-
span_id TEXT,
|
|
389
|
-
status TEXT NOT NULL,
|
|
390
|
-
created_at TEXT NOT NULL,
|
|
391
|
-
expires_at TEXT,
|
|
392
|
-
result_ref TEXT,
|
|
393
|
-
PRIMARY KEY (namespace, key)
|
|
394
|
-
);
|
|
395
|
-
CREATE INDEX IF NOT EXISTS idx_idempotency_expires
|
|
396
|
-
ON run_idempotency_keys(expires_at) WHERE expires_at IS NOT NULL;
|
|
397
|
-
CREATE INDEX IF NOT EXISTS idx_idempotency_run
|
|
398
|
-
ON run_idempotency_keys(run_id) WHERE run_id IS NOT NULL;
|
|
343
|
+
const V9_SQL = `
|
|
344
|
+
CREATE TABLE IF NOT EXISTS run_attempts (
|
|
345
|
+
attempt_id TEXT PRIMARY KEY,
|
|
346
|
+
run_id INTEGER NOT NULL,
|
|
347
|
+
attempt_number INTEGER NOT NULL,
|
|
348
|
+
incarnation_id TEXT NOT NULL,
|
|
349
|
+
started_at TEXT NOT NULL,
|
|
350
|
+
ended_at TEXT,
|
|
351
|
+
status TEXT NOT NULL,
|
|
352
|
+
finish_reason TEXT,
|
|
353
|
+
error_class TEXT,
|
|
354
|
+
error_message TEXT,
|
|
355
|
+
FOREIGN KEY (run_id) REFERENCES runs(id) ON DELETE CASCADE
|
|
356
|
+
);
|
|
357
|
+
CREATE INDEX IF NOT EXISTS idx_run_attempts_run
|
|
358
|
+
ON run_attempts(run_id, attempt_number);
|
|
359
|
+
CREATE INDEX IF NOT EXISTS idx_run_attempts_incarnation
|
|
360
|
+
ON run_attempts(incarnation_id);
|
|
361
|
+
|
|
362
|
+
CREATE TABLE IF NOT EXISTS spans (
|
|
363
|
+
span_id TEXT PRIMARY KEY,
|
|
364
|
+
trace_id TEXT NOT NULL,
|
|
365
|
+
parent_span_id TEXT,
|
|
366
|
+
run_id INTEGER,
|
|
367
|
+
attempt_id TEXT,
|
|
368
|
+
incarnation_id TEXT NOT NULL,
|
|
369
|
+
kind TEXT NOT NULL,
|
|
370
|
+
name TEXT NOT NULL,
|
|
371
|
+
started_at TEXT NOT NULL,
|
|
372
|
+
ended_at TEXT,
|
|
373
|
+
status TEXT,
|
|
374
|
+
attrs_json TEXT,
|
|
375
|
+
error_class TEXT,
|
|
376
|
+
error_message TEXT
|
|
377
|
+
);
|
|
378
|
+
CREATE INDEX IF NOT EXISTS idx_spans_trace ON spans(trace_id, started_at);
|
|
379
|
+
CREATE INDEX IF NOT EXISTS idx_spans_run ON spans(run_id, started_at);
|
|
380
|
+
CREATE INDEX IF NOT EXISTS idx_spans_parent ON spans(parent_span_id);
|
|
381
|
+
|
|
382
|
+
CREATE TABLE IF NOT EXISTS run_idempotency_keys (
|
|
383
|
+
namespace TEXT NOT NULL,
|
|
384
|
+
key TEXT NOT NULL,
|
|
385
|
+
fingerprint TEXT NOT NULL,
|
|
386
|
+
run_id INTEGER,
|
|
387
|
+
trigger_event_id INTEGER,
|
|
388
|
+
span_id TEXT,
|
|
389
|
+
status TEXT NOT NULL,
|
|
390
|
+
created_at TEXT NOT NULL,
|
|
391
|
+
expires_at TEXT,
|
|
392
|
+
result_ref TEXT,
|
|
393
|
+
PRIMARY KEY (namespace, key)
|
|
394
|
+
);
|
|
395
|
+
CREATE INDEX IF NOT EXISTS idx_idempotency_expires
|
|
396
|
+
ON run_idempotency_keys(expires_at) WHERE expires_at IS NOT NULL;
|
|
397
|
+
CREATE INDEX IF NOT EXISTS idx_idempotency_run
|
|
398
|
+
ON run_idempotency_keys(run_id) WHERE run_id IS NOT NULL;
|
|
399
399
|
`;
|
|
400
400
|
// v4.9.0 Slice 7 — external trace adoption. Adds `external_trace_id`
|
|
401
401
|
// to `spans` + `runs` for W3C traceparent adoption alongside Aiden's
|
|
402
402
|
// typed `trc_<uuidv7>`. Source of truth: `db/schema/v10.sql`.
|
|
403
|
-
const V10_SQL = `
|
|
404
|
-
ALTER TABLE spans ADD COLUMN external_trace_id TEXT;
|
|
405
|
-
ALTER TABLE runs ADD COLUMN external_trace_id TEXT;
|
|
406
|
-
CREATE INDEX IF NOT EXISTS idx_spans_external_trace
|
|
407
|
-
ON spans(external_trace_id) WHERE external_trace_id IS NOT NULL;
|
|
403
|
+
const V10_SQL = `
|
|
404
|
+
ALTER TABLE spans ADD COLUMN external_trace_id TEXT;
|
|
405
|
+
ALTER TABLE runs ADD COLUMN external_trace_id TEXT;
|
|
406
|
+
CREATE INDEX IF NOT EXISTS idx_spans_external_trace
|
|
407
|
+
ON spans(external_trace_id) WHERE external_trace_id IS NOT NULL;
|
|
408
408
|
`;
|
|
409
409
|
// v4.9.0 Slice 12a — Hook system tables. Source of truth lives at
|
|
410
410
|
// `core/v4/daemon/db/schema/v11.sql`.
|
|
411
|
-
const V11_SQL = `
|
|
412
|
-
CREATE TABLE IF NOT EXISTS hooks (
|
|
413
|
-
hook_id TEXT PRIMARY KEY,
|
|
414
|
-
name TEXT NOT NULL,
|
|
415
|
-
version TEXT,
|
|
416
|
-
source TEXT NOT NULL,
|
|
417
|
-
runtime TEXT NOT NULL,
|
|
418
|
-
manifest_path TEXT NOT NULL,
|
|
419
|
-
code_hash TEXT NOT NULL,
|
|
420
|
-
enabled INTEGER NOT NULL DEFAULT 0,
|
|
421
|
-
trust_state TEXT NOT NULL,
|
|
422
|
-
created_at TEXT NOT NULL,
|
|
423
|
-
updated_at TEXT NOT NULL,
|
|
424
|
-
UNIQUE(manifest_path)
|
|
425
|
-
);
|
|
426
|
-
CREATE TABLE IF NOT EXISTS hook_subscriptions (
|
|
427
|
-
subscription_id TEXT PRIMARY KEY,
|
|
428
|
-
hook_id TEXT NOT NULL REFERENCES hooks(hook_id) ON DELETE CASCADE,
|
|
429
|
-
event TEXT NOT NULL,
|
|
430
|
-
matcher_json TEXT,
|
|
431
|
-
authority TEXT NOT NULL,
|
|
432
|
-
mode TEXT NOT NULL,
|
|
433
|
-
priority INTEGER NOT NULL DEFAULT 0,
|
|
434
|
-
timeout_ms INTEGER NOT NULL,
|
|
435
|
-
on_error TEXT NOT NULL,
|
|
436
|
-
on_timeout TEXT NOT NULL,
|
|
437
|
-
enabled INTEGER NOT NULL DEFAULT 1
|
|
438
|
-
);
|
|
439
|
-
CREATE INDEX IF NOT EXISTS idx_hook_subscriptions_event ON hook_subscriptions(event, enabled);
|
|
440
|
-
CREATE TABLE IF NOT EXISTS hook_capability_grants (
|
|
441
|
-
grant_id TEXT PRIMARY KEY,
|
|
442
|
-
hook_id TEXT NOT NULL REFERENCES hooks(hook_id) ON DELETE CASCADE,
|
|
443
|
-
capability TEXT NOT NULL,
|
|
444
|
-
scope_json TEXT NOT NULL,
|
|
445
|
-
granted_by TEXT,
|
|
446
|
-
granted_at TEXT NOT NULL,
|
|
447
|
-
revoked_at TEXT
|
|
448
|
-
);
|
|
449
|
-
CREATE TABLE IF NOT EXISTS hook_executions (
|
|
450
|
-
hook_execution_id TEXT PRIMARY KEY,
|
|
451
|
-
hook_id TEXT NOT NULL REFERENCES hooks(hook_id),
|
|
452
|
-
subscription_id TEXT REFERENCES hook_subscriptions(subscription_id),
|
|
453
|
-
event TEXT NOT NULL,
|
|
454
|
-
run_id TEXT,
|
|
455
|
-
trace_id TEXT,
|
|
456
|
-
span_id TEXT,
|
|
457
|
-
parent_span_id TEXT,
|
|
458
|
-
tool_call_id TEXT,
|
|
459
|
-
status TEXT NOT NULL,
|
|
460
|
-
decision TEXT,
|
|
461
|
-
elapsed_ms INTEGER NOT NULL,
|
|
462
|
-
cpu_ms INTEGER,
|
|
463
|
-
max_rss_kb INTEGER,
|
|
464
|
-
exit_code INTEGER,
|
|
465
|
-
payload_hash TEXT,
|
|
466
|
-
response_hash TEXT,
|
|
467
|
-
stdout_preview TEXT,
|
|
468
|
-
stderr_preview TEXT,
|
|
469
|
-
error_kind TEXT,
|
|
470
|
-
error_message TEXT,
|
|
471
|
-
started_at TEXT NOT NULL,
|
|
472
|
-
finished_at TEXT NOT NULL
|
|
473
|
-
);
|
|
474
|
-
CREATE INDEX IF NOT EXISTS idx_hook_executions_run ON hook_executions(run_id, started_at);
|
|
475
|
-
CREATE INDEX IF NOT EXISTS idx_hook_executions_hook ON hook_executions(hook_id, started_at);
|
|
476
|
-
CREATE INDEX IF NOT EXISTS idx_hook_executions_event ON hook_executions(event, started_at);
|
|
411
|
+
const V11_SQL = `
|
|
412
|
+
CREATE TABLE IF NOT EXISTS hooks (
|
|
413
|
+
hook_id TEXT PRIMARY KEY,
|
|
414
|
+
name TEXT NOT NULL,
|
|
415
|
+
version TEXT,
|
|
416
|
+
source TEXT NOT NULL,
|
|
417
|
+
runtime TEXT NOT NULL,
|
|
418
|
+
manifest_path TEXT NOT NULL,
|
|
419
|
+
code_hash TEXT NOT NULL,
|
|
420
|
+
enabled INTEGER NOT NULL DEFAULT 0,
|
|
421
|
+
trust_state TEXT NOT NULL,
|
|
422
|
+
created_at TEXT NOT NULL,
|
|
423
|
+
updated_at TEXT NOT NULL,
|
|
424
|
+
UNIQUE(manifest_path)
|
|
425
|
+
);
|
|
426
|
+
CREATE TABLE IF NOT EXISTS hook_subscriptions (
|
|
427
|
+
subscription_id TEXT PRIMARY KEY,
|
|
428
|
+
hook_id TEXT NOT NULL REFERENCES hooks(hook_id) ON DELETE CASCADE,
|
|
429
|
+
event TEXT NOT NULL,
|
|
430
|
+
matcher_json TEXT,
|
|
431
|
+
authority TEXT NOT NULL,
|
|
432
|
+
mode TEXT NOT NULL,
|
|
433
|
+
priority INTEGER NOT NULL DEFAULT 0,
|
|
434
|
+
timeout_ms INTEGER NOT NULL,
|
|
435
|
+
on_error TEXT NOT NULL,
|
|
436
|
+
on_timeout TEXT NOT NULL,
|
|
437
|
+
enabled INTEGER NOT NULL DEFAULT 1
|
|
438
|
+
);
|
|
439
|
+
CREATE INDEX IF NOT EXISTS idx_hook_subscriptions_event ON hook_subscriptions(event, enabled);
|
|
440
|
+
CREATE TABLE IF NOT EXISTS hook_capability_grants (
|
|
441
|
+
grant_id TEXT PRIMARY KEY,
|
|
442
|
+
hook_id TEXT NOT NULL REFERENCES hooks(hook_id) ON DELETE CASCADE,
|
|
443
|
+
capability TEXT NOT NULL,
|
|
444
|
+
scope_json TEXT NOT NULL,
|
|
445
|
+
granted_by TEXT,
|
|
446
|
+
granted_at TEXT NOT NULL,
|
|
447
|
+
revoked_at TEXT
|
|
448
|
+
);
|
|
449
|
+
CREATE TABLE IF NOT EXISTS hook_executions (
|
|
450
|
+
hook_execution_id TEXT PRIMARY KEY,
|
|
451
|
+
hook_id TEXT NOT NULL REFERENCES hooks(hook_id),
|
|
452
|
+
subscription_id TEXT REFERENCES hook_subscriptions(subscription_id),
|
|
453
|
+
event TEXT NOT NULL,
|
|
454
|
+
run_id TEXT,
|
|
455
|
+
trace_id TEXT,
|
|
456
|
+
span_id TEXT,
|
|
457
|
+
parent_span_id TEXT,
|
|
458
|
+
tool_call_id TEXT,
|
|
459
|
+
status TEXT NOT NULL,
|
|
460
|
+
decision TEXT,
|
|
461
|
+
elapsed_ms INTEGER NOT NULL,
|
|
462
|
+
cpu_ms INTEGER,
|
|
463
|
+
max_rss_kb INTEGER,
|
|
464
|
+
exit_code INTEGER,
|
|
465
|
+
payload_hash TEXT,
|
|
466
|
+
response_hash TEXT,
|
|
467
|
+
stdout_preview TEXT,
|
|
468
|
+
stderr_preview TEXT,
|
|
469
|
+
error_kind TEXT,
|
|
470
|
+
error_message TEXT,
|
|
471
|
+
started_at TEXT NOT NULL,
|
|
472
|
+
finished_at TEXT NOT NULL
|
|
473
|
+
);
|
|
474
|
+
CREATE INDEX IF NOT EXISTS idx_hook_executions_run ON hook_executions(run_id, started_at);
|
|
475
|
+
CREATE INDEX IF NOT EXISTS idx_hook_executions_hook ON hook_executions(hook_id, started_at);
|
|
476
|
+
CREATE INDEX IF NOT EXISTS idx_hook_executions_event ON hook_executions(event, started_at);
|
|
477
477
|
`;
|
|
478
478
|
// v4.9.0 Slice 12b — auto-disable rail. Just an ADD COLUMN; full
|
|
479
479
|
// rationale lives in `core/v4/daemon/db/schema/v12.sql`.
|
|
480
|
-
const V12_SQL = `
|
|
481
|
-
ALTER TABLE hooks ADD COLUMN consecutive_failures INTEGER NOT NULL DEFAULT 0;
|
|
480
|
+
const V12_SQL = `
|
|
481
|
+
ALTER TABLE hooks ADD COLUMN consecutive_failures INTEGER NOT NULL DEFAULT 0;
|
|
482
482
|
`;
|
|
483
483
|
const MIGRATIONS = [
|
|
484
484
|
{ version: 1, name: 'phase 1 — daemon foundation', sql: V1_SQL },
|