feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,227 @@
const assert = require('node:assert/strict');
const test = require('node:test');
const { DatabaseSync } = require('node:sqlite');
const {
LOCAL_MODEL_INVOCATION_MIGRATION_PLAN_DIGEST,
migrateLocalModelInvocationFeature,
} = require('@qinglong/ai/model-invocation-migration');
const {
LocalModelInvocationFeatureActivationRepository,
LocalModelInvocationFeatureTransitionConflictError,
LocalModelInvocationFeatureTransitionUnavailableError,
assertLocalModelInvocationFeatureActive,
createLocalModelInvocationFeatureTransitionCommand,
} = require('@qinglong/ai/local-feature-activation');
function createMainSqliteContract(client) {
client.exec(`
CREATE TABLE "QingLong3SchemaMigrations" (
migration_id TEXT PRIMARY KEY,
stream_id TEXT NOT NULL,
dialect TEXT NOT NULL,
checksum TEXT NOT NULL,
applied_at_ms INTEGER NOT NULL
);
CREATE TABLE "Runs" (id TEXT PRIMARY KEY);
CREATE TABLE "RunEvents" (id TEXT PRIMARY KEY);
CREATE TABLE "StepRuns" (
id TEXT PRIMARY KEY,
run_id TEXT NOT NULL,
UNIQUE (run_id, id)
);
CREATE TABLE "StepRunMutations" (mutation_id TEXT PRIMARY KEY);
`);
}
function principal(authenticationId = 'local_ai_feature:proof-1') {
return {
subject: { type: 'user', id: 'owner-user' },
authenticationId,
authenticatedAtMs: 1_000,
expiresAtMs: 301_000,
assurance: 'local_console',
};
}
function transition(overrides = {}) {
return createLocalModelInvocationFeatureTransitionCommand({
featureId: 'model-invocation',
expectedGeneration: 0,
expectedState: null,
state: 'active',
mutationId: 'feature-activation-1',
requestId: 'feature-request-1',
expectedMigrationDigest: LOCAL_MODEL_INVOCATION_MIGRATION_PLAN_DIGEST,
safety: {
mode: 'fresh_database',
backupEvidenceDigest: null,
},
principal: principal(),
...overrides,
});
}
async function fixture() {
const client = new DatabaseSync(':memory:');
client.exec('PRAGMA foreign_keys = ON');
createMainSqliteContract(client);
await migrateLocalModelInvocationFeature(client);
return client;
}
test('local AI feature activation is append-only, replay-safe and non-destructive', async () => {
const client = await fixture();
const repository = new LocalModelInvocationFeatureActivationRepository(
client,
);
assert.equal(repository.findCurrent(), null);
assert.throws(
() => assertLocalModelInvocationFeatureActive(client),
LocalModelInvocationFeatureTransitionUnavailableError,
);
const activated = repository.transition(transition());
assert.equal(activated.status, 'created');
assert.equal(activated.transition.generation, 1);
assert.equal(activated.transition.state, 'active');
assert.equal(
assertLocalModelInvocationFeatureActive(client).transitionDigest,
activated.transition.transitionDigest,
);
const replayed = repository.transition(transition());
assert.equal(replayed.status, 'existing');
assert.deepEqual(replayed.transition, activated.transition);
const deactivated = repository.transition(
transition({
expectedGeneration: 1,
expectedState: 'active',
state: 'inactive',
mutationId: 'feature-deactivation-1',
requestId: 'feature-request-2',
safety: {
mode: 'preserve_existing',
backupEvidenceDigest: null,
},
}),
);
assert.equal(deactivated.status, 'created');
assert.equal(deactivated.transition.generation, 2);
assert.equal(deactivated.transition.state, 'inactive');
assert.throws(
() => assertLocalModelInvocationFeatureActive(client),
LocalModelInvocationFeatureTransitionUnavailableError,
);
assert.deepEqual(
{
...client
.prepare(
`SELECT
(SELECT count(*) FROM "ModelInvocationFeatureTransitions") AS transitions,
(SELECT count(*) FROM "ModelInvocationFeatureHead") AS heads,
(SELECT count(*) FROM "ModelInvocationStarts") AS starts,
(SELECT count(*) FROM "ModelPriceCatalogPublications") AS publications`,
)
.get(),
},
{ transitions: 2, heads: 1, starts: 0, publications: 0 },
);
client.close();
});
test('local AI feature activation rejects CAS, plan and identity drift', async () => {
const client = await fixture();
const repository = new LocalModelInvocationFeatureActivationRepository(
client,
);
repository.transition(transition());
assert.throws(
() =>
repository.transition(
transition({
mutationId: 'feature-activation-conflict',
requestId: 'feature-request-conflict',
}),
),
LocalModelInvocationFeatureTransitionConflictError,
);
assert.throws(
() =>
repository.transition(
transition({
expectedGeneration: 1,
expectedState: 'active',
state: 'inactive',
mutationId: 'feature-deactivation-plan-drift',
requestId: 'feature-request-plan-drift',
expectedMigrationDigest: 'f'.repeat(64),
safety: {
mode: 'preserve_existing',
backupEvidenceDigest: null,
},
}),
),
LocalModelInvocationFeatureTransitionConflictError,
);
assert.throws(
() =>
repository.transition(
transition({
principal: principal('local_ai_feature:different-proof'),
}),
),
LocalModelInvocationFeatureTransitionConflictError,
);
client.close();
});
test('local AI feature transaction fence runs before replay and rolls back', async () => {
const client = await fixture();
let fences = 0;
const first = new LocalModelInvocationFeatureActivationRepository(client, {
beforeMutation() {
fences += 1;
},
});
first.transition(transition());
first.transition(transition());
assert.equal(fences, 2);
const rejected = new LocalModelInvocationFeatureActivationRepository(client, {
beforeMutation() {
throw new Error('fence rejected');
},
});
assert.throws(
() =>
rejected.transition(
transition({
expectedGeneration: 1,
expectedState: 'active',
state: 'inactive',
mutationId: 'feature-deactivation-rejected',
requestId: 'feature-request-rejected',
safety: {
mode: 'preserve_existing',
backupEvidenceDigest: null,
},
}),
),
LocalModelInvocationFeatureTransitionUnavailableError,
);
assert.equal(
client
.prepare(
`SELECT count(*) AS count
FROM "ModelInvocationFeatureTransitions"`,
)
.get().count,
1,
);
client.close();
});