feat(ql3): bind service lineage to legacy data receipt

This commit is contained in:
whyour
2026-08-21 13:27:40 +08:00
parent f1fc316be1
commit 07cb5ea0a8
9 changed files with 473 additions and 29 deletions
@@ -19,6 +19,9 @@ const {
advanceLocalCutoverInstanceHead,
claimLocalCutoverInstance,
} = require('../dist/deployment/cutover/instanceLineage.js');
const {
createLocalDataDirectoryApplicationCommit,
} = require('@qinglong/local-sqlite/data-directory-application-commit');
const roots = [];
@@ -247,6 +250,68 @@ test('binds an adopted first start to the current legacy-stopped instance head',
);
});
test('rejects v4 legacy data receipt drift before publishing a service intent', () => {
const { root } = fixture();
const { identity, previousRecordDigest } = adoptedHead(root);
adoptedApplication(root, identity, previousRecordDigest);
const applicationPath = path.join(root, 'local-application.json');
const application = JSON.parse(fs.readFileSync(applicationPath, 'utf8'));
const commit = createLocalDataDirectoryApplicationCommit({
mutationId: '00000000-0000-4000-8000-000000000001',
projectId: 'project-edge-router-1',
profile: 'edge',
sourceStageManifestDigest: '1'.repeat(64),
transformationDigest: '2'.repeat(64),
modelDigest: '3'.repeat(64),
publicationDigest: '4'.repeat(64),
receiptDigest: '5'.repeat(64),
committedAtMs: 1786416000001,
receipt: {
secretCount: 2,
environmentSecretCount: 1,
sshSecretCount: 1,
},
});
const commitPath = path.join(root, 'legacy-data-commit.json');
fs.writeFileSync(commitPath, `${JSON.stringify(commit)}\n`, { mode: 0o600 });
fs.writeFileSync(
applicationPath,
`${JSON.stringify({
...application,
schema: 'qinglong/local-application-process@v4',
legacyDataApplication: {
commitPath,
expectedCommitDigest: commit.commitDigest,
expectedReceiptDigest: '0'.repeat(64),
},
})}\n`,
{ mode: 0o600 },
);
const command = prepareCommand(root);
command.request.lineage = {
mode: 'adopted',
cutoverId: identity.request.cutoverId,
generation: 1,
expectedActivationDigest: identity.request.expectedActivationDigest,
previousRecordDigest,
};
assert.throws(
() => prepareLocalServiceManagerIntent(command),
/legacy data application commit does not match the application binding/,
);
assert.equal(
fs.existsSync(
path.join(
root,
'service',
'service-manager-intents',
`${command.request.actionId}.json`,
),
),
false,
);
});
test('does not allow fresh service intent to bypass an existing cutover head', () => {
const { root } = fixture();
adoptedHead(root);