mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
feat(local): bind legacy adoption provenance
This commit is contained in:
@@ -157,6 +157,45 @@ test('publishes tasks, execution facts, triggers, audit and ledger atomically',
|
||||
.get().count,
|
||||
2,
|
||||
);
|
||||
assert.deepEqual(
|
||||
client
|
||||
.prepare(
|
||||
`SELECT task."row_ordinal" AS rowOrdinal,
|
||||
task."task_id" AS taskId,
|
||||
task."task_revision" AS taskRevision,
|
||||
task."trigger_count" AS triggerCount,
|
||||
trigger."trigger_ordinal" AS triggerOrdinal,
|
||||
trigger."trigger_id" AS triggerId,
|
||||
trigger."trigger_revision" AS triggerRevision
|
||||
FROM "QingLong3LegacyAdoptionTasks" AS task
|
||||
JOIN "QingLong3LegacyAdoptionTriggers" AS trigger
|
||||
ON trigger."adoption_mutation_id" = task."adoption_mutation_id"
|
||||
AND trigger."row_ordinal" = task."row_ordinal"
|
||||
ORDER BY task."row_ordinal", trigger."trigger_ordinal"`,
|
||||
)
|
||||
.all()
|
||||
.map((row) => ({ ...row })),
|
||||
[
|
||||
{
|
||||
rowOrdinal: 1,
|
||||
taskId: 'legacy-cron:1',
|
||||
taskRevision: 1,
|
||||
triggerCount: 1,
|
||||
triggerOrdinal: 1,
|
||||
triggerId: 'legacy-cron:1:cron:1',
|
||||
triggerRevision: 1,
|
||||
},
|
||||
{
|
||||
rowOrdinal: 2,
|
||||
taskId: 'legacy-cron:2',
|
||||
taskRevision: 1,
|
||||
triggerCount: 1,
|
||||
triggerOrdinal: 1,
|
||||
triggerId: 'legacy-cron:2:cron:1',
|
||||
triggerRevision: 1,
|
||||
},
|
||||
],
|
||||
);
|
||||
assert.deepEqual(
|
||||
{
|
||||
...client
|
||||
@@ -191,6 +230,8 @@ test('rolls the complete publication back on a later candidate conflict', async
|
||||
'QingLong3Triggers',
|
||||
'QingLong3LocalTriggerSchedules',
|
||||
'QingLong3LegacyAdoptions',
|
||||
'QingLong3LegacyAdoptionTasks',
|
||||
'QingLong3LegacyAdoptionTriggers',
|
||||
'QingLong3SecurityAuditEvents',
|
||||
]) {
|
||||
assert.equal(
|
||||
@@ -235,6 +276,8 @@ test('awaits the final external authority check and rolls back on rejection', as
|
||||
'QingLong3Triggers',
|
||||
'QingLong3LocalTriggerSchedules',
|
||||
'QingLong3LegacyAdoptions',
|
||||
'QingLong3LegacyAdoptionTasks',
|
||||
'QingLong3LegacyAdoptionTriggers',
|
||||
'QingLong3SecurityAuditEvents',
|
||||
]) {
|
||||
assert.equal(
|
||||
@@ -264,3 +307,33 @@ test('rejects stale authorization fences before any adoption mutation', async (t
|
||||
);
|
||||
await adoption.close();
|
||||
});
|
||||
|
||||
test('rejects exact replay when durable provenance has drifted', async (t) => {
|
||||
const databasePath = await preparedDatabase(t);
|
||||
const input = command([candidate(1)]);
|
||||
const adoption = await openLocalSqliteAdoptionDatabase({
|
||||
databasePath,
|
||||
profile: 'edge',
|
||||
});
|
||||
await adoption.publisher.publish(input);
|
||||
await adoption.close();
|
||||
|
||||
const client = new DatabaseSync(databasePath);
|
||||
client
|
||||
.prepare(
|
||||
`UPDATE "QingLong3LegacyAdoptionTasks"
|
||||
SET "item_digest" = ? WHERE "adoption_mutation_id" = ?`,
|
||||
)
|
||||
.run('f'.repeat(64), MUTATION_ID);
|
||||
client.close();
|
||||
|
||||
const reopened = await openLocalSqliteAdoptionDatabase({
|
||||
databasePath,
|
||||
profile: 'edge',
|
||||
});
|
||||
await assert.rejects(
|
||||
reopened.publisher.publish(input),
|
||||
LocalLegacyAdoptionConflictError,
|
||||
);
|
||||
await reopened.close();
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ test('authentication projection opens the target read-only without journal or fi
|
||||
try {
|
||||
assert.equal(database.profile, 'edge');
|
||||
assert.equal(database.readiness.contractName, 'local-control-core');
|
||||
assert.equal(database.readiness.contractVersion, 50);
|
||||
assert.equal(database.readiness.contractVersion, 51);
|
||||
assert.equal(await database.apiCredentials.resolve('absent'), null);
|
||||
assert.equal(await database.ownerPepper.resolveKey('absent'), null);
|
||||
} finally {
|
||||
|
||||
@@ -150,9 +150,11 @@ test('creates a reviewed edge database and opens runtime only after readiness',
|
||||
'0098-capability-v49',
|
||||
'0099-legacy-data-directory-adoptions',
|
||||
'0100-capability-v50',
|
||||
'0101-legacy-adoption-provenance',
|
||||
'0102-capability-v51',
|
||||
]);
|
||||
assert.equal(migrated.readiness.contractName, 'local-control-core');
|
||||
assert.equal(migrated.readiness.contractVersion, 50);
|
||||
assert.equal(migrated.readiness.contractVersion, 51);
|
||||
assert.equal(migrated.readiness.journalMode, 'delete');
|
||||
assert.equal(fs.statSync(databasePath).mode & 0o777, 0o600);
|
||||
|
||||
@@ -598,8 +600,8 @@ test('backfills v14 execution revisions with a verified independent digest', asy
|
||||
.get(),
|
||||
},
|
||||
{
|
||||
contract_version: 50,
|
||||
migration_id: '0099-legacy-data-directory-adoptions',
|
||||
contract_version: 51,
|
||||
migration_id: '0101-legacy-adoption-provenance',
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
@@ -786,19 +788,19 @@ test('excludes reviewed optional feature tables while preserving unknown table d
|
||||
const options = { databasePath, profile: 'edge' };
|
||||
await migrateLocalSqlitePath(options);
|
||||
const client = new DatabaseSync(databasePath);
|
||||
assert.equal((await auditLocalSqlitePath(options)).tableCount, 83);
|
||||
assert.equal((await auditLocalSqlitePath(options)).tableCount, 85);
|
||||
client.exec(
|
||||
'CREATE TABLE "ModelInvocationFeatureHead" (feature_id TEXT PRIMARY KEY)',
|
||||
);
|
||||
client.close();
|
||||
|
||||
assert.equal((await auditLocalSqlitePath(options)).tableCount, 83);
|
||||
assert.equal((await auditLocalSqlitePath(options)).tableCount, 85);
|
||||
|
||||
const unknownClient = new DatabaseSync(databasePath);
|
||||
unknownClient.exec('CREATE TABLE "UserExtensionData" (id TEXT PRIMARY KEY)');
|
||||
unknownClient.close();
|
||||
|
||||
assert.equal((await auditLocalSqlitePath(options)).tableCount, 84);
|
||||
assert.equal((await auditLocalSqlitePath(options)).tableCount, 86);
|
||||
|
||||
const triggerClient = new DatabaseSync(databasePath);
|
||||
triggerClient.exec(`
|
||||
|
||||
@@ -156,7 +156,7 @@ test('atomically admits one generation-bound Workflow Run and exactly replays it
|
||||
},
|
||||
{ runs: 1, steps: 2, events: 3, mutations: 2, admissions: 1 },
|
||||
);
|
||||
assert.equal((await auditLocalSqliteReadiness(client)).contractVersion, 50);
|
||||
assert.equal((await auditLocalSqliteReadiness(client)).contractVersion, 51);
|
||||
});
|
||||
|
||||
test('runs an optional authorization guard inside new and replay transactions', async (t) => {
|
||||
@@ -288,7 +288,7 @@ test('exactly replays immutable admission after the Workflow StepRun advances',
|
||||
},
|
||||
{ status: 'running', version: 5, eventSequence: 5 },
|
||||
);
|
||||
assert.equal((await auditLocalSqliteReadiness(client)).contractVersion, 50);
|
||||
assert.equal((await auditLocalSqliteReadiness(client)).contractVersion, 51);
|
||||
});
|
||||
|
||||
test('fails closed before writing when the exact installation is not active', async (t) => {
|
||||
|
||||
+1
-1
@@ -231,7 +231,7 @@ test('atomically admits the exact reconciled local Task revision and replays it'
|
||||
stepAttemptCount: 0,
|
||||
},
|
||||
);
|
||||
assert.equal((await auditLocalSqliteReadiness(client)).contractVersion, 50);
|
||||
assert.equal((await auditLocalSqliteReadiness(client)).contractVersion, 51);
|
||||
});
|
||||
|
||||
test('bounds candidate paging before SQL and fences cancellation', async (t) => {
|
||||
|
||||
@@ -40,9 +40,9 @@ test('creates and exactly replays a reviewed rollout backup', async (t) => {
|
||||
await migrateLocalSqlitePath(state);
|
||||
const prepared = await createLocalSqliteRolloutBackup(state);
|
||||
assert.equal(prepared.status, 'prepared');
|
||||
assert.equal(prepared.contractVersion, 50);
|
||||
assert.equal(prepared.writeContractVersion, 50);
|
||||
assert.equal(LOCAL_SQLITE_WRITE_CONTRACT_VERSION, 50);
|
||||
assert.equal(prepared.contractVersion, 51);
|
||||
assert.equal(prepared.writeContractVersion, 51);
|
||||
assert.equal(LOCAL_SQLITE_WRITE_CONTRACT_VERSION, 51);
|
||||
assert.match(prepared.sha256, /^[0-9a-f]{64}$/);
|
||||
assert.equal(prepared.bytes > 0, true);
|
||||
assert.equal(prepared.pageCount > 0, true);
|
||||
|
||||
Reference in New Issue
Block a user