feat(ql3): rehearse cross-domain reconciliation completion

This commit is contained in:
whyour
2026-09-02 02:37:39 +08:00
parent 37801d2f30
commit a95ed67fe8
20 changed files with 1030 additions and 60 deletions
@@ -162,6 +162,40 @@ function targetRunHistoryIsTerminal(client: DatabaseSync): boolean {
return true;
}
function legacyIdentityPolicyAuditIsEmpty(client: DatabaseSync): boolean {
const rows = client
.prepare(
`SELECT name
FROM sqlite_schema
WHERE type = 'table' AND name NOT LIKE 'sqlite_%'
ORDER BY name
LIMIT 513`,
)
.iterate() as IterableIterator<{ readonly name?: unknown }>;
let catalog = 0;
for (const row of rows) {
catalog += 1;
if (
catalog > 512 ||
typeof row.name !== 'string' ||
Buffer.byteLength(row.name, 'utf8') > MAX_NAME_BYTES
) {
return false;
}
if (
classifyLocalReconciliationFact('legacy', row.name) !==
'identity_policy_audit'
) {
continue;
}
const present = client
.prepare(`SELECT 1 AS present FROM ${quotedIdentifier(row.name)} LIMIT 1`)
.get() as { readonly present?: unknown } | undefined;
if (present?.present === 1) return false;
}
return true;
}
function requirement(
client: DatabaseSync,
database: LocalReconciliationSealedDatabaseKind,
@@ -201,6 +235,12 @@ function requirement(
reason: 'reviewable_fact' as const,
});
}
if (legacyIdentityPolicyAuditIsEmpty(client)) {
return Object.freeze({
decisionRequirement: 'informational' as const,
reason: 'catalog_evidence' as const,
});
}
return Object.freeze({
decisionRequirement: 'blocked' as const,
reason: 'identity_custody_required' as const,
@@ -3053,7 +3053,7 @@ test('review diagnostics keep secret and unknown facts blocked and row-free', (t
);
});
test('review diagnostics preserve target-native identity but keep legacy identity fail-closed', (t) => {
test('review diagnostics treat empty Legacy identity catalogs as no-effect evidence', (t) => {
const initializeDatabases = (paths) => {
planningDatabaseInitializer()(paths);
const legacy = new DatabaseSync(paths.legacySourcePath);
@@ -3085,8 +3085,8 @@ test('review diagnostics preserve target-native identity but keep legacy identit
fs.readFileSync(legacyCommand.request.outputPath, 'utf8'),
);
assert.equal(legacy.records[0].name, 'Auths');
assert.equal(legacy.records[0].decisionRequirement, 'blocked');
assert.equal(legacy.records[0].reason, 'identity_custody_required');
assert.equal(legacy.records[0].decisionRequirement, 'informational');
assert.equal(legacy.records[0].reason, 'catalog_evidence');
const targetCommand = diagnosticCommand(state, prepared, {
database: 'target',
@@ -3102,6 +3102,36 @@ test('review diagnostics preserve target-native identity but keep legacy identit
assert.equal(target.records[0].reason, 'reviewable_fact');
});
test('review diagnostics keep nonempty Legacy identity custody fail-closed', (t) => {
const initializeDatabases = (paths) => {
planningDatabaseInitializer()(paths);
const legacy = new DatabaseSync(paths.legacySourcePath);
legacy.exec(`
CREATE TABLE "Auths" (id INTEGER PRIMARY KEY);
INSERT INTO "Auths" (id) VALUES (1);
`);
legacy.close();
fs.copyFileSync(paths.legacySourcePath, paths.recoveryPath);
fs.chmodSync(paths.recoveryPath, 0o600);
};
const state = preparedReview(t, {
initializeDatabases,
planId: '00000000-0000-4000-8000-000000000335',
reviewId: '00000000-0000-4000-8000-000000000336',
reviewSuffix: 'nonempty-identity-custody',
});
const prepared = prepareLocalReconciliationReview(state.reviewCommand);
const command = diagnosticCommand(state, prepared, {
database: 'legacy',
domain: 'identity_policy_audit',
outputName: 'legacy-nonempty-identity.json',
});
writeLocalReconciliationReviewDiagnostics(command);
const page = JSON.parse(fs.readFileSync(command.request.outputPath, 'utf8'));
assert.equal(page.records[0].decisionRequirement, 'blocked');
assert.equal(page.records[0].reason, 'identity_custody_required');
});
test('review diagnostics page at sixty-four and CLI output stays content-free', (t) => {
const initializeDatabases = (paths) => {
planningDatabaseInitializer()(paths);