ultra-builder-pro-cli 0.24.2 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/adapters/claude.js +104 -0
- package/adapters/codex.js +363 -40
- package/adapters/grok.js +1254 -58
- package/adapters/kimi.js +682 -13
- package/adapters/opencode.js +132 -11
- package/docs/AGENT-CONTEXT.md +14 -0
- package/docs/ARTIFACT-AUTHORITY.md +13 -0
- package/docs/COMMIT-HASH-BACKFILL.md +25 -18
- package/docs/RUNTIME-COMPAT-MATRIX.md +18 -2
- package/mcp-server/lib/artifact-registry.cjs +181 -51
- package/mcp-server/lib/baseline-workflow.cjs +160 -23
- package/mcp-server/lib/change-workflow.cjs +21 -16
- package/mcp-server/lib/context-envelope.cjs +124 -51
- package/mcp-server/lib/decision-records.cjs +164 -78
- package/mcp-server/lib/kernel-change-workflow.cjs +2029 -0
- package/mcp-server/lib/legacy-change-workflow.cjs +294 -71
- package/mcp-server/lib/managed-file-write.cjs +56 -0
- package/mcp-server/lib/prd-parser.cjs +2 -2
- package/mcp-server/lib/stage-checkpoints.cjs +163 -9
- package/mcp-server/lib/state-db.cjs +186 -8
- package/mcp-server/lib/state-ops.cjs +214 -31
- package/mcp-server/lib/task-contract.cjs +404 -0
- package/mcp-server/lib/task-expander.cjs +2 -2
- package/mcp-server/lib/task-ledger.cjs +175 -62
- package/mcp-server/lib/ultra-facade.cjs +1786 -169
- package/mcp-server/lib/worker-packet.cjs +2 -2
- package/mcp-server/server.cjs +23 -4
- package/orchestrator/parallel-orchestrator.cjs +114 -27
- package/orchestrator/session-runner.cjs +25 -136
- package/package.json +1 -1
- package/skills/ultra-change/SKILL.md +6 -1
- package/skills/ultra-dev/SKILL.md +9 -4
- package/skills/ultra-plan/SKILL.md +13 -4
- package/skills/ultra-plan/references/semantic-preflight.md +6 -4
- package/spec/mcp-tools.yaml +114 -9
- package/spec/schemas/context-file.v4.5.schema.json +2 -2
- package/spec/schemas/state-db.sql +10 -6
- package/spec/schemas/task-ledger.v2.schema.json +23 -8
- package/spec/schemas/tasks.v4.5.schema.json +34 -12
|
@@ -109,8 +109,64 @@ function writeManagedJson(rootDir, relativePath, value) {
|
|
|
109
109
|
return writeManagedFile(rootDir, relativePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
function snapshotManagedFile(rootDir, relativePath) {
|
|
113
|
+
const relative = normalizeProjectRelative(relativePath);
|
|
114
|
+
const directoryRelative = path.posix.dirname(relative);
|
|
115
|
+
const basename = path.posix.basename(relative);
|
|
116
|
+
const prepared = ensureDirectory(rootDir, directoryRelative);
|
|
117
|
+
const target = path.join(prepared.directory, basename);
|
|
118
|
+
const stat = fs.lstatSync(target, { throwIfNoEntry: false });
|
|
119
|
+
if (!stat) return { path: relative, existed: false, bytes: null };
|
|
120
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
121
|
+
throw new ManagedFileWriteError(
|
|
122
|
+
'PATH_AUTHORITY_VIOLATION',
|
|
123
|
+
`managed artifact target is unsafe: ${relative}`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
path: relative,
|
|
128
|
+
existed: true,
|
|
129
|
+
bytes: fs.readFileSync(target),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function removeManagedFile(rootDir, relativePath) {
|
|
134
|
+
const relative = normalizeProjectRelative(relativePath);
|
|
135
|
+
const directoryRelative = path.posix.dirname(relative);
|
|
136
|
+
const basename = path.posix.basename(relative);
|
|
137
|
+
const prepared = ensureDirectory(rootDir, directoryRelative);
|
|
138
|
+
const target = path.join(prepared.directory, basename);
|
|
139
|
+
const stat = fs.lstatSync(target, { throwIfNoEntry: false });
|
|
140
|
+
if (!stat) return false;
|
|
141
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
142
|
+
throw new ManagedFileWriteError(
|
|
143
|
+
'PATH_AUTHORITY_VIOLATION',
|
|
144
|
+
`managed artifact rollback target is unsafe: ${relative}`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
fs.unlinkSync(target);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function restoreManagedFile(rootDir, snapshot) {
|
|
152
|
+
if (!snapshot || typeof snapshot.path !== 'string') {
|
|
153
|
+
throw new ManagedFileWriteError(
|
|
154
|
+
'PATH_AUTHORITY_VIOLATION',
|
|
155
|
+
'managed artifact rollback snapshot is invalid',
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (snapshot.existed) {
|
|
159
|
+
return writeManagedFile(rootDir, snapshot.path, snapshot.bytes);
|
|
160
|
+
}
|
|
161
|
+
removeManagedFile(rootDir, snapshot.path);
|
|
162
|
+
return { path: snapshot.path, removed: true };
|
|
163
|
+
}
|
|
164
|
+
|
|
112
165
|
module.exports = {
|
|
113
166
|
ManagedFileWriteError,
|
|
167
|
+
removeManagedFile,
|
|
168
|
+
restoreManagedFile,
|
|
169
|
+
snapshotManagedFile,
|
|
114
170
|
writeManagedFile,
|
|
115
171
|
writeManagedJson,
|
|
116
172
|
};
|
|
@@ -19,8 +19,8 @@ const TASK_LIST_SCHEMA = Object.freeze({
|
|
|
19
19
|
properties: {
|
|
20
20
|
id: { type: 'string', pattern: '^[a-zA-Z0-9_\\-]+$' },
|
|
21
21
|
title: { type: 'string', minLength: 3, maxLength: 200 },
|
|
22
|
-
type: { type: 'string',
|
|
23
|
-
priority: { type: 'string',
|
|
22
|
+
type: { type: 'string', minLength: 1, maxLength: 80 },
|
|
23
|
+
priority: { type: 'string', minLength: 1, maxLength: 80 },
|
|
24
24
|
complexity: { type: 'integer', minimum: 1, maximum: 10 },
|
|
25
25
|
deps: { type: 'array', items: { type: 'string' } },
|
|
26
26
|
files_modified: { type: 'array', items: { type: 'string' } },
|
|
@@ -55,10 +55,10 @@ function normalizeDiagnostics(value) {
|
|
|
55
55
|
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
56
56
|
throw new StageCheckpointError('VALIDATION_ERROR', `diagnostics[${index}] must be an object`);
|
|
57
57
|
}
|
|
58
|
-
|
|
59
|
-
if (!code) {
|
|
58
|
+
if (typeof item.code !== 'string' || !item.code.trim()) {
|
|
60
59
|
throw new StageCheckpointError('VALIDATION_ERROR', `diagnostics[${index}].code is required`);
|
|
61
60
|
}
|
|
61
|
+
const code = item.code.trim();
|
|
62
62
|
const severity = item.severity || 'needs_attention';
|
|
63
63
|
if (!['warning', 'needs_attention', 'hard_conflict'].includes(severity)) {
|
|
64
64
|
throw new StageCheckpointError(
|
|
@@ -66,15 +66,79 @@ function normalizeDiagnostics(value) {
|
|
|
66
66
|
`diagnostics[${index}].severity is invalid`,
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
|
+
if (item.message !== undefined && typeof item.message !== 'string') {
|
|
70
|
+
throw new StageCheckpointError(
|
|
71
|
+
'VALIDATION_ERROR',
|
|
72
|
+
`diagnostics[${index}].message must be a string`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
69
75
|
return {
|
|
70
76
|
code,
|
|
71
77
|
severity,
|
|
72
|
-
...(item.message ? { message:
|
|
78
|
+
...(item.message ? { message: item.message } : {}),
|
|
73
79
|
...(item.details === undefined ? {} : { details: item.details }),
|
|
74
80
|
};
|
|
75
81
|
});
|
|
76
82
|
}
|
|
77
83
|
|
|
84
|
+
function normalizePayload(value) {
|
|
85
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
86
|
+
throw new StageCheckpointError('VALIDATION_ERROR', 'checkpoint payload must be an object');
|
|
87
|
+
}
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function normalizeEvidence(value) {
|
|
92
|
+
if (!Array.isArray(value)) {
|
|
93
|
+
throw new StageCheckpointError('VALIDATION_ERROR', 'evidence must be an array');
|
|
94
|
+
}
|
|
95
|
+
return value.map((item, index) => {
|
|
96
|
+
if (!item || typeof item !== 'object' || Array.isArray(item)) {
|
|
97
|
+
throw new StageCheckpointError('VALIDATION_ERROR', `evidence[${index}] must be an object`);
|
|
98
|
+
}
|
|
99
|
+
return item;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function idempotencyConflict(idempotencyKey, priorDigest, requestedDigest) {
|
|
104
|
+
return new StageCheckpointError(
|
|
105
|
+
'IDEMPOTENCY_KEY_CONFLICT',
|
|
106
|
+
`idempotency key ${idempotencyKey} was already used for another checkpoint request`,
|
|
107
|
+
{
|
|
108
|
+
idempotency_key: idempotencyKey,
|
|
109
|
+
prior_request_digest: priorDigest,
|
|
110
|
+
requested_request_digest: requestedDigest,
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function draftRequestDigest({
|
|
116
|
+
stage,
|
|
117
|
+
scopeType,
|
|
118
|
+
scopeId,
|
|
119
|
+
payload,
|
|
120
|
+
}) {
|
|
121
|
+
const requestPayload = stage === 'plan' && payload && typeof payload === 'object'
|
|
122
|
+
? Object.fromEntries(Object.entries(payload).filter(([key]) => key !== 'plan'))
|
|
123
|
+
: payload;
|
|
124
|
+
return canonical.digest({
|
|
125
|
+
operation: 'checkpoint:draft',
|
|
126
|
+
stage,
|
|
127
|
+
scope_type: scopeType,
|
|
128
|
+
scope_id: scopeId,
|
|
129
|
+
payload: requestPayload,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function checkpointDraftRequestDigest(checkpoint) {
|
|
134
|
+
return draftRequestDigest({
|
|
135
|
+
stage: checkpoint.stage,
|
|
136
|
+
scopeType: checkpoint.scope_type,
|
|
137
|
+
scopeId: checkpoint.scope_id,
|
|
138
|
+
payload: checkpoint.payload,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
78
142
|
function checkpointDigest(value) {
|
|
79
143
|
return canonical.digest({
|
|
80
144
|
stage: value.stage,
|
|
@@ -151,6 +215,28 @@ function existingByIdempotency(db, idempotencyKey) {
|
|
|
151
215
|
);
|
|
152
216
|
}
|
|
153
217
|
|
|
218
|
+
function findIdempotentDraft(db, input = {}) {
|
|
219
|
+
validateStage(input.stage);
|
|
220
|
+
const scope = normalizeScope(input.scope);
|
|
221
|
+
const idempotencyKey = String(input.idempotency_key || '').trim();
|
|
222
|
+
if (!idempotencyKey) {
|
|
223
|
+
throw new StageCheckpointError('VALIDATION_ERROR', 'idempotency_key is required');
|
|
224
|
+
}
|
|
225
|
+
const existing = existingByIdempotency(db, idempotencyKey);
|
|
226
|
+
if (!existing) return null;
|
|
227
|
+
const requestedDigest = draftRequestDigest({
|
|
228
|
+
stage: input.stage,
|
|
229
|
+
scopeType: scope.type,
|
|
230
|
+
scopeId: scope.id,
|
|
231
|
+
payload: normalizePayload(input.payload),
|
|
232
|
+
});
|
|
233
|
+
const priorDigest = checkpointDraftRequestDigest(existing);
|
|
234
|
+
if (priorDigest !== requestedDigest) {
|
|
235
|
+
throw idempotencyConflict(idempotencyKey, priorDigest, requestedDigest);
|
|
236
|
+
}
|
|
237
|
+
return existing;
|
|
238
|
+
}
|
|
239
|
+
|
|
154
240
|
function saveDraft(db, input = {}) {
|
|
155
241
|
validateStage(input.stage);
|
|
156
242
|
const scope = normalizeScope(input.scope);
|
|
@@ -158,12 +244,23 @@ function saveDraft(db, input = {}) {
|
|
|
158
244
|
if (!idempotencyKey) {
|
|
159
245
|
throw new StageCheckpointError('VALIDATION_ERROR', 'idempotency_key is required');
|
|
160
246
|
}
|
|
247
|
+
const payload = normalizePayload(input.payload);
|
|
248
|
+
const evidence = normalizeEvidence(input.evidence);
|
|
249
|
+
const diagnostics = normalizeDiagnostics(input.diagnostics);
|
|
250
|
+
const requestedDigest = draftRequestDigest({
|
|
251
|
+
stage: input.stage,
|
|
252
|
+
scopeType: scope.type,
|
|
253
|
+
scopeId: scope.id,
|
|
254
|
+
payload,
|
|
255
|
+
});
|
|
161
256
|
const existingRetry = existingByIdempotency(db, idempotencyKey);
|
|
162
|
-
if (existingRetry)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
257
|
+
if (existingRetry) {
|
|
258
|
+
const priorDigest = checkpointDraftRequestDigest(existingRetry);
|
|
259
|
+
if (priorDigest !== requestedDigest) {
|
|
260
|
+
throw idempotencyConflict(idempotencyKey, priorDigest, requestedDigest);
|
|
261
|
+
}
|
|
262
|
+
return existingRetry;
|
|
263
|
+
}
|
|
167
264
|
return ops.tx(db, () => {
|
|
168
265
|
const draft = db.prepare(
|
|
169
266
|
`SELECT * FROM stage_checkpoints
|
|
@@ -241,6 +338,33 @@ function saveDraft(db, input = {}) {
|
|
|
241
338
|
});
|
|
242
339
|
}
|
|
243
340
|
|
|
341
|
+
function acceptanceReceipt(db, idempotencyKey) {
|
|
342
|
+
if (!idempotencyKey) return null;
|
|
343
|
+
const rows = db.prepare(
|
|
344
|
+
`SELECT payload_json FROM events
|
|
345
|
+
WHERE type = 'ultra_checkpoint_accepted'
|
|
346
|
+
ORDER BY id DESC`,
|
|
347
|
+
).all();
|
|
348
|
+
for (const row of rows) {
|
|
349
|
+
const payload = parseJson(row.payload_json, {});
|
|
350
|
+
if (payload.idempotency_key === idempotencyKey) return payload;
|
|
351
|
+
}
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function acceptanceReceiptForCheckpoint(db, checkpointId) {
|
|
356
|
+
const rows = db.prepare(
|
|
357
|
+
`SELECT payload_json FROM events
|
|
358
|
+
WHERE type = 'ultra_checkpoint_accepted'
|
|
359
|
+
ORDER BY id DESC`,
|
|
360
|
+
).all();
|
|
361
|
+
for (const row of rows) {
|
|
362
|
+
const payload = parseJson(row.payload_json, {});
|
|
363
|
+
if (payload.checkpoint_id === checkpointId && payload.idempotency_key) return payload;
|
|
364
|
+
}
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
|
|
244
368
|
function acceptDraft(db, input = {}) {
|
|
245
369
|
const idempotencyKey = String(input.idempotency_key || '').trim();
|
|
246
370
|
if (!idempotencyKey) {
|
|
@@ -249,7 +373,34 @@ function acceptDraft(db, input = {}) {
|
|
|
249
373
|
return ops.tx(db, () => {
|
|
250
374
|
const row = db.prepare('SELECT * FROM stage_checkpoints WHERE id = ?').get(input.id);
|
|
251
375
|
if (!row) throw new StageCheckpointError('CHECKPOINT_NOT_FOUND', `checkpoint not found: ${input.id}`);
|
|
252
|
-
|
|
376
|
+
const checkpoint = rowToCheckpoint(row);
|
|
377
|
+
const requestedDigest = canonical.digest({
|
|
378
|
+
operation: 'checkpoint:accept',
|
|
379
|
+
checkpoint_id: checkpoint.id,
|
|
380
|
+
checkpoint_digest: checkpoint.digest,
|
|
381
|
+
});
|
|
382
|
+
const prior = acceptanceReceipt(db, idempotencyKey);
|
|
383
|
+
if (prior) {
|
|
384
|
+
if (prior.request_digest !== requestedDigest) {
|
|
385
|
+
throw idempotencyConflict(
|
|
386
|
+
idempotencyKey,
|
|
387
|
+
prior.request_digest || null,
|
|
388
|
+
requestedDigest,
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
return checkpoint;
|
|
392
|
+
}
|
|
393
|
+
if (row.status === 'accepted') {
|
|
394
|
+
const checkpointReceipt = acceptanceReceiptForCheckpoint(db, checkpoint.id);
|
|
395
|
+
if (checkpointReceipt) {
|
|
396
|
+
throw idempotencyConflict(
|
|
397
|
+
idempotencyKey,
|
|
398
|
+
checkpointReceipt.request_digest || null,
|
|
399
|
+
requestedDigest,
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
return checkpoint;
|
|
403
|
+
}
|
|
253
404
|
if (row.status !== 'draft') {
|
|
254
405
|
throw new StageCheckpointError(
|
|
255
406
|
'CHECKPOINT_NOT_MUTABLE',
|
|
@@ -279,6 +430,8 @@ function acceptDraft(db, input = {}) {
|
|
|
279
430
|
stage: accepted.stage,
|
|
280
431
|
revision: accepted.revision,
|
|
281
432
|
digest: accepted.digest,
|
|
433
|
+
idempotency_key: idempotencyKey,
|
|
434
|
+
request_digest: requestedDigest,
|
|
282
435
|
},
|
|
283
436
|
});
|
|
284
437
|
return accepted;
|
|
@@ -303,6 +456,7 @@ module.exports = {
|
|
|
303
456
|
readCheckpoint,
|
|
304
457
|
listCheckpoints,
|
|
305
458
|
saveDraft,
|
|
459
|
+
findIdempotentDraft,
|
|
306
460
|
acceptDraft,
|
|
307
461
|
currentCheckpoint,
|
|
308
462
|
checkpointDigest,
|
|
@@ -9,7 +9,7 @@ const REPO_ROOT = process.env.UBP_RUNTIME_ROOT
|
|
|
9
9
|
? path.resolve(process.env.UBP_RUNTIME_ROOT)
|
|
10
10
|
: path.resolve(__dirname, '..', '..');
|
|
11
11
|
const SCHEMA_FILE = path.join(REPO_ROOT, 'spec', 'schemas', 'state-db.sql');
|
|
12
|
-
const EXPECTED_VERSION = '
|
|
12
|
+
const EXPECTED_VERSION = '23.0';
|
|
13
13
|
const KIMI_SCHEMA_VERSION = '9.1';
|
|
14
14
|
const CONTEXT_SCHEMA_VERSION = '10.0';
|
|
15
15
|
const BASELINE_SCHEMA_VERSION = '11.0';
|
|
@@ -24,6 +24,7 @@ const DECISION_COMPLETION_SCHEMA_VERSION = '19.0';
|
|
|
24
24
|
const ARTIFACT_REGISTRY_SCHEMA_VERSION = '20.0';
|
|
25
25
|
const KERNEL_SCHEMA_VERSION = '21.0';
|
|
26
26
|
const CHECKPOINT_NATIVE_SCHEMA_VERSION = '22.0';
|
|
27
|
+
const SEMANTIC_KERNEL_SCHEMA_VERSION = '23.0';
|
|
27
28
|
|
|
28
29
|
const MIGRATED_GAPS = Object.freeze([{
|
|
29
30
|
id: 'legacy-rebaseline-required',
|
|
@@ -306,9 +307,154 @@ function applyChangeColumns(db) {
|
|
|
306
307
|
db, 'changes', columns, 'alignment_thread_id',
|
|
307
308
|
'TEXT REFERENCES decision_threads(id) ON DELETE SET NULL',
|
|
308
309
|
) || changed;
|
|
310
|
+
changed = addColumnIfMissing(
|
|
311
|
+
db, 'changes', columns, 'supersedes_id',
|
|
312
|
+
'TEXT REFERENCES changes(id) ON DELETE SET NULL',
|
|
313
|
+
) || changed;
|
|
309
314
|
return changed;
|
|
310
315
|
}
|
|
311
316
|
|
|
317
|
+
function upgradeSemanticKernelConstraints(db) {
|
|
318
|
+
const tables = new Set(tableNames(db));
|
|
319
|
+
if (!tables.has('changes') || !tables.has('tasks')) return false;
|
|
320
|
+
const taskColumns = columnNames(db, 'tasks');
|
|
321
|
+
const preservesLegacyComplexityHint = taskColumns.has('complexity_hint');
|
|
322
|
+
const changesSql = db.prepare(
|
|
323
|
+
"SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'changes'",
|
|
324
|
+
).get()?.sql || '';
|
|
325
|
+
const tasksSql = db.prepare(
|
|
326
|
+
"SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'tasks'",
|
|
327
|
+
).get()?.sql || '';
|
|
328
|
+
const current = /length\s*\(\s*trim\s*\(\s*kind\s*\)\s*\)\s+BETWEEN\s+1\s+AND\s+80/i
|
|
329
|
+
.test(changesSql)
|
|
330
|
+
&& /length\s*\(\s*trim\s*\(\s*type\s*\)\s*\)\s+BETWEEN\s+1\s+AND\s+80/i
|
|
331
|
+
.test(tasksSql)
|
|
332
|
+
&& /length\s*\(\s*trim\s*\(\s*priority\s*\)\s*\)\s+BETWEEN\s+1\s+AND\s+80/i
|
|
333
|
+
.test(tasksSql)
|
|
334
|
+
&& /length\s*\(\s*trim\s*\(\s*slice_kind\s*\)\s*\)\s+BETWEEN\s+1\s+AND\s+80/i
|
|
335
|
+
.test(tasksSql)
|
|
336
|
+
&& columnNames(db, 'changes').has('supersedes_id');
|
|
337
|
+
if (current) return false;
|
|
338
|
+
|
|
339
|
+
const foreignKeys = db.pragma('foreign_keys', { simple: true });
|
|
340
|
+
db.pragma('foreign_keys = OFF');
|
|
341
|
+
try {
|
|
342
|
+
db.transaction(() => {
|
|
343
|
+
db.exec(`
|
|
344
|
+
DROP TABLE IF EXISTS changes_semantic_kernel_upgrade;
|
|
345
|
+
CREATE TABLE changes_semantic_kernel_upgrade (
|
|
346
|
+
id TEXT PRIMARY KEY,
|
|
347
|
+
title TEXT NOT NULL,
|
|
348
|
+
kind TEXT NOT NULL CHECK (length(trim(kind)) BETWEEN 1 AND 80),
|
|
349
|
+
status TEXT NOT NULL DEFAULT 'active'
|
|
350
|
+
CHECK (status IN ('active', 'blocked', 'ready', 'archived', 'cancelled')),
|
|
351
|
+
intent TEXT NOT NULL,
|
|
352
|
+
docs_impact_json TEXT NOT NULL DEFAULT '{"status":"unknown","files":[],"rationale":null}',
|
|
353
|
+
provider_refs_json TEXT NOT NULL DEFAULT '{}',
|
|
354
|
+
baseline_bypass_json TEXT,
|
|
355
|
+
contract_json TEXT NOT NULL DEFAULT '{}',
|
|
356
|
+
classification_json TEXT NOT NULL DEFAULT '{}',
|
|
357
|
+
research_disposition_json TEXT NOT NULL DEFAULT '{}',
|
|
358
|
+
alignment_thread_id TEXT REFERENCES decision_threads(id) ON DELETE SET NULL,
|
|
359
|
+
base_commit TEXT,
|
|
360
|
+
supersedes_id TEXT REFERENCES changes_semantic_kernel_upgrade(id) ON DELETE SET NULL,
|
|
361
|
+
artifact_root TEXT NOT NULL,
|
|
362
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
363
|
+
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
364
|
+
closed_at TEXT
|
|
365
|
+
);
|
|
366
|
+
INSERT INTO changes_semantic_kernel_upgrade (
|
|
367
|
+
id, title, kind, status, intent, docs_impact_json, provider_refs_json,
|
|
368
|
+
baseline_bypass_json, contract_json, classification_json,
|
|
369
|
+
research_disposition_json, alignment_thread_id, base_commit,
|
|
370
|
+
supersedes_id, artifact_root, created_at, updated_at, closed_at
|
|
371
|
+
)
|
|
372
|
+
SELECT
|
|
373
|
+
id, title, kind, status, intent, docs_impact_json, provider_refs_json,
|
|
374
|
+
baseline_bypass_json, contract_json, classification_json,
|
|
375
|
+
research_disposition_json, alignment_thread_id, base_commit,
|
|
376
|
+
supersedes_id, artifact_root, created_at, updated_at, closed_at
|
|
377
|
+
FROM changes;
|
|
378
|
+
|
|
379
|
+
DROP TABLE IF EXISTS tasks_semantic_kernel_upgrade;
|
|
380
|
+
CREATE TABLE tasks_semantic_kernel_upgrade (
|
|
381
|
+
id TEXT PRIMARY KEY,
|
|
382
|
+
title TEXT NOT NULL,
|
|
383
|
+
type TEXT NOT NULL CHECK (length(trim(type)) BETWEEN 1 AND 80),
|
|
384
|
+
priority TEXT NOT NULL CHECK (length(trim(priority)) BETWEEN 1 AND 80),
|
|
385
|
+
complexity INTEGER CHECK (complexity BETWEEN 1 AND 10),
|
|
386
|
+
estimated_days REAL CHECK (estimated_days IS NULL OR estimated_days > 0),
|
|
387
|
+
status TEXT NOT NULL DEFAULT 'pending'
|
|
388
|
+
CHECK (status IN ('pending', 'in_progress', 'completed', 'blocked', 'expanded')),
|
|
389
|
+
deps TEXT,
|
|
390
|
+
files_modified TEXT,
|
|
391
|
+
session_id TEXT,
|
|
392
|
+
stale INTEGER NOT NULL DEFAULT 0 CHECK (stale IN (0, 1)),
|
|
393
|
+
${preservesLegacyComplexityHint ? 'complexity_hint TEXT,' : ''}
|
|
394
|
+
tag TEXT,
|
|
395
|
+
trace_to TEXT,
|
|
396
|
+
outcome TEXT,
|
|
397
|
+
slice_kind TEXT CHECK (
|
|
398
|
+
slice_kind IS NULL OR length(trim(slice_kind)) BETWEEN 1 AND 80
|
|
399
|
+
),
|
|
400
|
+
public_seam TEXT,
|
|
401
|
+
verification_command TEXT,
|
|
402
|
+
acceptance_json TEXT NOT NULL DEFAULT '[]',
|
|
403
|
+
context_refs_json TEXT NOT NULL DEFAULT '[]',
|
|
404
|
+
docs_impact_json TEXT NOT NULL DEFAULT '{"status":"unknown","files":[],"rationale":null}',
|
|
405
|
+
ownership_json TEXT NOT NULL DEFAULT '{}',
|
|
406
|
+
context_file TEXT,
|
|
407
|
+
completion_commit TEXT,
|
|
408
|
+
change_id TEXT REFERENCES changes_semantic_kernel_upgrade(id) ON DELETE SET NULL,
|
|
409
|
+
parent_id TEXT REFERENCES tasks_semantic_kernel_upgrade(id) ON DELETE SET NULL,
|
|
410
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
411
|
+
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
412
|
+
);
|
|
413
|
+
INSERT INTO tasks_semantic_kernel_upgrade (
|
|
414
|
+
id, title, type, priority, complexity, estimated_days, status, deps,
|
|
415
|
+
files_modified, session_id, stale,
|
|
416
|
+
${preservesLegacyComplexityHint ? 'complexity_hint,' : ''}
|
|
417
|
+
tag, trace_to, outcome, slice_kind,
|
|
418
|
+
public_seam, verification_command, acceptance_json, context_refs_json,
|
|
419
|
+
docs_impact_json, ownership_json, context_file, completion_commit,
|
|
420
|
+
change_id, parent_id, created_at, updated_at
|
|
421
|
+
)
|
|
422
|
+
SELECT
|
|
423
|
+
id, title, type, priority, complexity, estimated_days, status, deps,
|
|
424
|
+
files_modified, session_id, stale,
|
|
425
|
+
${preservesLegacyComplexityHint ? 'complexity_hint,' : ''}
|
|
426
|
+
tag, trace_to, outcome, slice_kind,
|
|
427
|
+
public_seam, verification_command, acceptance_json, context_refs_json,
|
|
428
|
+
docs_impact_json, ownership_json, context_file, completion_commit,
|
|
429
|
+
change_id, parent_id, created_at, updated_at
|
|
430
|
+
FROM tasks;
|
|
431
|
+
|
|
432
|
+
DROP TABLE tasks;
|
|
433
|
+
DROP TABLE changes;
|
|
434
|
+
ALTER TABLE changes_semantic_kernel_upgrade RENAME TO changes;
|
|
435
|
+
ALTER TABLE tasks_semantic_kernel_upgrade RENAME TO tasks;
|
|
436
|
+
CREATE INDEX changes_status ON changes(status, created_at);
|
|
437
|
+
CREATE INDEX changes_kind ON changes(kind, created_at);
|
|
438
|
+
CREATE INDEX tasks_status ON tasks(status);
|
|
439
|
+
CREATE INDEX tasks_tag ON tasks(tag);
|
|
440
|
+
CREATE INDEX tasks_session ON tasks(session_id) WHERE session_id IS NOT NULL;
|
|
441
|
+
CREATE INDEX tasks_stale ON tasks(stale) WHERE stale = 1;
|
|
442
|
+
CREATE INDEX tasks_parent ON tasks(parent_id) WHERE parent_id IS NOT NULL;
|
|
443
|
+
CREATE INDEX tasks_change ON tasks(change_id) WHERE change_id IS NOT NULL;
|
|
444
|
+
`);
|
|
445
|
+
const violations = db.pragma('foreign_key_check');
|
|
446
|
+
if (violations.length > 0) {
|
|
447
|
+
throw new Error(
|
|
448
|
+
`semantic kernel migration produced ${violations.length} foreign key violation(s)`,
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
})();
|
|
452
|
+
} finally {
|
|
453
|
+
db.pragma(`foreign_keys = ${foreignKeys ? 'ON' : 'OFF'}`);
|
|
454
|
+
}
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
|
|
312
458
|
function applySemanticAuthorityColumns(db) {
|
|
313
459
|
let changed = false;
|
|
314
460
|
if (tableNames(db).includes('workflow_steps')) {
|
|
@@ -416,7 +562,7 @@ function applyCompatibleColumns(db) {
|
|
|
416
562
|
}
|
|
417
563
|
const taskAdditions = [
|
|
418
564
|
['outcome', 'TEXT'],
|
|
419
|
-
['slice_kind',
|
|
565
|
+
['slice_kind', 'TEXT CHECK (slice_kind IS NULL OR length(trim(slice_kind)) BETWEEN 1 AND 80)'],
|
|
420
566
|
['public_seam', 'TEXT'],
|
|
421
567
|
['verification_command', 'TEXT'],
|
|
422
568
|
['acceptance_json', "TEXT NOT NULL DEFAULT '[]'"],
|
|
@@ -486,7 +632,7 @@ function migrateAdaptiveWorkflowRuns(db, fromVersion = latestSchemaVersion(db))
|
|
|
486
632
|
if ([
|
|
487
633
|
ADAPTIVE_SCHEMA_VERSION, DECISION_COMPLETION_SCHEMA_VERSION,
|
|
488
634
|
ARTIFACT_REGISTRY_SCHEMA_VERSION, KERNEL_SCHEMA_VERSION,
|
|
489
|
-
CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
635
|
+
CHECKPOINT_NATIVE_SCHEMA_VERSION, SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
490
636
|
].includes(fromVersion) || existing) {
|
|
491
637
|
return false;
|
|
492
638
|
}
|
|
@@ -1007,6 +1153,11 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1007
1153
|
}
|
|
1008
1154
|
const gitStateChangedFrom = upgradeBaselineWorktreeConstraint(db, fromVersion);
|
|
1009
1155
|
const decisionCompletionChanged = upgradeDecisionThreadLifecycle(db);
|
|
1156
|
+
db.transaction(() => {
|
|
1157
|
+
applyCompatibleColumns(db);
|
|
1158
|
+
applyChangeColumns(db);
|
|
1159
|
+
})();
|
|
1160
|
+
const semanticKernelChanged = upgradeSemanticKernelConstraints(db);
|
|
1010
1161
|
db.transaction(() => {
|
|
1011
1162
|
applyCompatibleColumns(db);
|
|
1012
1163
|
const contextChanged = applyContextSpineUpgrade(db);
|
|
@@ -1020,6 +1171,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1020
1171
|
DIALOGUE_SCHEMA_VERSION, GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION,
|
|
1021
1172
|
DECISION_COMPLETION_SCHEMA_VERSION, ARTIFACT_REGISTRY_SCHEMA_VERSION,
|
|
1022
1173
|
KERNEL_SCHEMA_VERSION, CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1174
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1023
1175
|
].includes(fromVersion)
|
|
1024
1176
|
&& !contextMigration,
|
|
1025
1177
|
);
|
|
@@ -1049,6 +1201,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1049
1201
|
GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION,
|
|
1050
1202
|
DECISION_COMPLETION_SCHEMA_VERSION, ARTIFACT_REGISTRY_SCHEMA_VERSION,
|
|
1051
1203
|
KERNEL_SCHEMA_VERSION, CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1204
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1052
1205
|
].includes(fromVersion)
|
|
1053
1206
|
&& !baselineMigration) {
|
|
1054
1207
|
db.prepare(
|
|
@@ -1123,6 +1276,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1123
1276
|
DIALOGUE_SCHEMA_VERSION, GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION,
|
|
1124
1277
|
DECISION_COMPLETION_SCHEMA_VERSION, ARTIFACT_REGISTRY_SCHEMA_VERSION,
|
|
1125
1278
|
KERNEL_SCHEMA_VERSION, CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1279
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1126
1280
|
].includes(fromVersion) && !workflowMigration) {
|
|
1127
1281
|
db.prepare(
|
|
1128
1282
|
`INSERT INTO migration_history
|
|
@@ -1141,7 +1295,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1141
1295
|
AUTHORITY_SCHEMA_VERSION, SEMANTIC_SCHEMA_VERSION, DIALOGUE_SCHEMA_VERSION,
|
|
1142
1296
|
GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION, DECISION_COMPLETION_SCHEMA_VERSION,
|
|
1143
1297
|
ARTIFACT_REGISTRY_SCHEMA_VERSION, KERNEL_SCHEMA_VERSION,
|
|
1144
|
-
CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1298
|
+
CHECKPOINT_NATIVE_SCHEMA_VERSION, SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1145
1299
|
].includes(fromVersion) && !authorityMigration) {
|
|
1146
1300
|
db.prepare(
|
|
1147
1301
|
`INSERT INTO migration_history
|
|
@@ -1160,7 +1314,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1160
1314
|
SEMANTIC_SCHEMA_VERSION, DIALOGUE_SCHEMA_VERSION, GIT_AUTHORITY_SCHEMA_VERSION,
|
|
1161
1315
|
ADAPTIVE_SCHEMA_VERSION, DECISION_COMPLETION_SCHEMA_VERSION,
|
|
1162
1316
|
ARTIFACT_REGISTRY_SCHEMA_VERSION, KERNEL_SCHEMA_VERSION,
|
|
1163
|
-
CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1317
|
+
CHECKPOINT_NATIVE_SCHEMA_VERSION, SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1164
1318
|
].includes(fromVersion) && !semanticMigration) {
|
|
1165
1319
|
db.prepare(
|
|
1166
1320
|
`INSERT INTO migration_history
|
|
@@ -1179,6 +1333,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1179
1333
|
DIALOGUE_SCHEMA_VERSION, GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION,
|
|
1180
1334
|
DECISION_COMPLETION_SCHEMA_VERSION, ARTIFACT_REGISTRY_SCHEMA_VERSION,
|
|
1181
1335
|
KERNEL_SCHEMA_VERSION, CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1336
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1182
1337
|
].includes(fromVersion)
|
|
1183
1338
|
&& !dialogueMigration) {
|
|
1184
1339
|
db.prepare(
|
|
@@ -1197,7 +1352,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1197
1352
|
if (fromVersion && ![
|
|
1198
1353
|
GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION, DECISION_COMPLETION_SCHEMA_VERSION,
|
|
1199
1354
|
ARTIFACT_REGISTRY_SCHEMA_VERSION, KERNEL_SCHEMA_VERSION,
|
|
1200
|
-
CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1355
|
+
CHECKPOINT_NATIVE_SCHEMA_VERSION, SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1201
1356
|
].includes(fromVersion)
|
|
1202
1357
|
&& !gitStateMigration) {
|
|
1203
1358
|
db.prepare(
|
|
@@ -1217,7 +1372,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1217
1372
|
if (fromVersion && ![
|
|
1218
1373
|
ADAPTIVE_SCHEMA_VERSION, DECISION_COMPLETION_SCHEMA_VERSION,
|
|
1219
1374
|
ARTIFACT_REGISTRY_SCHEMA_VERSION, KERNEL_SCHEMA_VERSION,
|
|
1220
|
-
CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1375
|
+
CHECKPOINT_NATIVE_SCHEMA_VERSION, SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1221
1376
|
].includes(fromVersion) && !adaptiveMigration) {
|
|
1222
1377
|
db.prepare(
|
|
1223
1378
|
`INSERT INTO migration_history
|
|
@@ -1237,6 +1392,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1237
1392
|
if (fromVersion && ![
|
|
1238
1393
|
DECISION_COMPLETION_SCHEMA_VERSION, ARTIFACT_REGISTRY_SCHEMA_VERSION,
|
|
1239
1394
|
KERNEL_SCHEMA_VERSION, CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1395
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1240
1396
|
].includes(fromVersion) && !completionMigration) {
|
|
1241
1397
|
db.prepare(
|
|
1242
1398
|
`INSERT INTO migration_history
|
|
@@ -1256,6 +1412,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1256
1412
|
if (fromVersion && fromVersion !== ARTIFACT_REGISTRY_SCHEMA_VERSION
|
|
1257
1413
|
&& fromVersion !== KERNEL_SCHEMA_VERSION
|
|
1258
1414
|
&& fromVersion !== CHECKPOINT_NATIVE_SCHEMA_VERSION
|
|
1415
|
+
&& fromVersion !== SEMANTIC_KERNEL_SCHEMA_VERSION
|
|
1259
1416
|
&& !artifactRegistryMigration) {
|
|
1260
1417
|
db.prepare(
|
|
1261
1418
|
`INSERT INTO migration_history
|
|
@@ -1275,6 +1432,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1275
1432
|
if (fromVersion
|
|
1276
1433
|
&& fromVersion !== KERNEL_SCHEMA_VERSION
|
|
1277
1434
|
&& fromVersion !== CHECKPOINT_NATIVE_SCHEMA_VERSION
|
|
1435
|
+
&& fromVersion !== SEMANTIC_KERNEL_SCHEMA_VERSION
|
|
1278
1436
|
&& !kernelMigration) {
|
|
1279
1437
|
db.prepare(
|
|
1280
1438
|
`INSERT INTO migration_history
|
|
@@ -1291,6 +1449,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1291
1449
|
).get();
|
|
1292
1450
|
if (fromVersion
|
|
1293
1451
|
&& fromVersion !== CHECKPOINT_NATIVE_SCHEMA_VERSION
|
|
1452
|
+
&& fromVersion !== SEMANTIC_KERNEL_SCHEMA_VERSION
|
|
1294
1453
|
&& !checkpointNativeMigration) {
|
|
1295
1454
|
db.prepare(
|
|
1296
1455
|
`INSERT INTO migration_history
|
|
@@ -1302,6 +1461,24 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1302
1461
|
'Bind Baseline research to Stage Checkpoints and add byte digests for Context Envelopes and Worker Packets',
|
|
1303
1462
|
);
|
|
1304
1463
|
}
|
|
1464
|
+
const semanticKernelMigration = db.prepare(
|
|
1465
|
+
"SELECT 1 FROM migration_history WHERE to_version = '23.0' AND status = 'success' LIMIT 1",
|
|
1466
|
+
).get();
|
|
1467
|
+
if (fromVersion
|
|
1468
|
+
&& fromVersion !== SEMANTIC_KERNEL_SCHEMA_VERSION
|
|
1469
|
+
&& !semanticKernelMigration) {
|
|
1470
|
+
db.prepare(
|
|
1471
|
+
`INSERT INTO migration_history
|
|
1472
|
+
(from_version, to_version, direction, status, notes)
|
|
1473
|
+
VALUES (?, ?, 'forward', 'success', ?)`,
|
|
1474
|
+
).run(
|
|
1475
|
+
CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1476
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1477
|
+
semanticKernelChanged
|
|
1478
|
+
? 'Move Task and Change business vocabulary out of SQLite enums and add immutable Change successor linkage'
|
|
1479
|
+
: 'Record semantic-kernel vocabulary and Change successor authority',
|
|
1480
|
+
);
|
|
1481
|
+
}
|
|
1305
1482
|
db.exec('CREATE INDEX IF NOT EXISTS tasks_change ON tasks(change_id) WHERE change_id IS NOT NULL');
|
|
1306
1483
|
db.exec('CREATE INDEX IF NOT EXISTS events_change ON events(change_id, id)');
|
|
1307
1484
|
ensureActiveSessionLeaseIndex(db);
|
|
@@ -1309,7 +1486,7 @@ function applyCompatibleUpgrades(db, fromVersion = latestSchemaVersion(db), { le
|
|
|
1309
1486
|
'INSERT OR IGNORE INTO schema_version (version, description) VALUES (?, ?)',
|
|
1310
1487
|
).run(
|
|
1311
1488
|
EXPECTED_VERSION,
|
|
1312
|
-
'
|
|
1489
|
+
'Persistence and safety kernel with open semantic vocabulary and immutable Change successors',
|
|
1313
1490
|
);
|
|
1314
1491
|
})();
|
|
1315
1492
|
}
|
|
@@ -1343,6 +1520,7 @@ function initStateDb(dbPath) {
|
|
|
1343
1520
|
DIALOGUE_SCHEMA_VERSION, GIT_AUTHORITY_SCHEMA_VERSION, ADAPTIVE_SCHEMA_VERSION,
|
|
1344
1521
|
DECISION_COMPLETION_SCHEMA_VERSION, ARTIFACT_REGISTRY_SCHEMA_VERSION,
|
|
1345
1522
|
KERNEL_SCHEMA_VERSION, CHECKPOINT_NATIVE_SCHEMA_VERSION,
|
|
1523
|
+
SEMANTIC_KERNEL_SCHEMA_VERSION,
|
|
1346
1524
|
].includes(fromVersion);
|
|
1347
1525
|
backupPath = migrationBackup(db, dbPath, fromVersion, existing);
|
|
1348
1526
|
// This must precede every ALTER, table rebuild, or index creation. Runtime
|