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,311 @@
const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
createInitialPluginPackageAutomationPublication,
createPluginPackageAutomationLifecyclePublication,
} = require('../dist/plugin-package/pluginPackageAutomationPublication');
const {
createPluginPackageWorkflowAdmissionBundle,
createPluginPackageWorkflowExecutionPlan,
InvalidPluginPackageWorkflowAdmissionReceiptError,
InvalidPluginPackageWorkflowExecutionPlanError,
normalizePluginPackageWorkflowAdmissionReceipt,
normalizePluginPackageWorkflowExecutionPlan,
PluginPackageWorkflowExecutionPlanConflictError,
pluginPackageWorkflowAdmissionReceiptDigest,
pluginPackageWorkflowExecutionPlanDigest,
} = require('@qinglong/runtime-core/plugin-package-workflow-execution-plan');
const {
pluginPackageTaskReconciliationFixture,
} = require('../../../test/contracts/pluginPackageTaskReconciliationRepositoryContract.cjs');
function fixture(namespace = 'workflow-execution-plan') {
const value = pluginPackageTaskReconciliationFixture(namespace, {
workflows: [
{
schema: 'qinglong/plugin-package-workflow-resource@v1',
id: 'daily',
name: 'Daily workflow',
enabled: true,
steps: [
{
id: 'collect',
task: 'alpha',
needs: [],
},
{
id: 'summarize',
task: 'beta',
needs: ['collect'],
},
],
},
],
});
return {
...value,
publication: createInitialPluginPackageAutomationPublication(
value.revision,
value.registry,
2_000,
),
};
}
function planInput(value, overrides = {}) {
return {
planId: 'workflow-plan-001',
runId: 'workflow-run-001',
workflowId: 'daily',
stepRunIds: {
collect: 'step-run-collect-001',
summarize: 'step-run-summarize-001',
},
publication: value.publication,
revision: value.revision,
taskSpecSemanticRegistry: value.registry,
plannedAtMs: 3_000,
...overrides,
};
}
test('binds one active publication and exact materialized Tasks into a canonical DAG plan', () => {
const value = fixture();
const plan = createPluginPackageWorkflowExecutionPlan(planInput(value));
assert.equal(
plan.target.publicationDigest,
value.publication.publicationDigest,
);
assert.equal(
plan.target.materializedRevisionDigest,
value.revision.revisionDigest,
);
assert.equal(plan.target.workflowId, 'daily');
assert.match(plan.target.workflowDefinitionDigest, /^[0-9a-f]{64}$/);
assert.deepEqual(
plan.steps.map(
({ stepKey, taskId, needs, initialStatus, taskDefinitionRef }) => ({
stepKey,
taskId,
needs,
initialStatus,
taskDefinitionRef,
}),
),
[
{
stepKey: 'collect',
taskId: 'alpha',
needs: [],
initialStatus: 'ready',
taskDefinitionRef: `plugin-package:${value.revision.revisionDigest}:task:alpha`,
},
{
stepKey: 'summarize',
taskId: 'beta',
needs: ['collect'],
initialStatus: 'pending',
taskDefinitionRef: `plugin-package:${value.revision.revisionDigest}:task:beta`,
},
],
);
assert.equal(
plan.steps.every(({ required }) => required),
true,
);
assert.equal(plan.planDigest, pluginPackageWorkflowExecutionPlanDigest(plan));
assert.deepEqual(normalizePluginPackageWorkflowExecutionPlan(plan), plan);
assert.deepEqual(
normalizePluginPackageWorkflowExecutionPlan(
JSON.parse(JSON.stringify(plan)),
),
plan,
);
assert.equal(
createPluginPackageWorkflowExecutionPlan(planInput(value)).planDigest,
plan.planDigest,
);
});
test('rejects withdrawn, drifted and incomplete Workflow execution inputs', () => {
const value = fixture('workflow-execution-plan-conflict');
const withdrawn = createPluginPackageAutomationLifecyclePublication({
previous: value.publication,
state: 'withdrawn',
lifecycleEventDigest: 'a'.repeat(64),
publishedAtMs: 2_001,
});
assert.throws(
() =>
createPluginPackageWorkflowExecutionPlan(
planInput(value, { publication: withdrawn }),
),
PluginPackageWorkflowExecutionPlanConflictError,
);
const replacement = fixture('workflow-execution-plan-replacement');
assert.throws(
() =>
createPluginPackageWorkflowExecutionPlan(
planInput(value, { revision: replacement.revision }),
),
PluginPackageWorkflowExecutionPlanConflictError,
);
assert.throws(
() =>
createPluginPackageWorkflowExecutionPlan(
planInput(value, {
stepRunIds: { collect: 'step-run-collect-001' },
}),
),
InvalidPluginPackageWorkflowExecutionPlanError,
);
assert.throws(
() =>
createPluginPackageWorkflowExecutionPlan(
planInput(value, {
stepRunIds: {
collect: 'step-run-shared',
summarize: 'step-run-shared',
},
}),
),
InvalidPluginPackageWorkflowExecutionPlanError,
);
});
test('fails closed when a durable plan digest or generation-bound Task reference drifts', () => {
const value = fixture('workflow-execution-plan-normalization');
const plan = createPluginPackageWorkflowExecutionPlan(planInput(value));
assert.throws(
() =>
normalizePluginPackageWorkflowExecutionPlan({
...plan,
planDigest: 'f'.repeat(64),
}),
InvalidPluginPackageWorkflowExecutionPlanError,
);
assert.throws(
() =>
normalizePluginPackageWorkflowExecutionPlan({
...plan,
steps: plan.steps.map((step) =>
step.stepKey === 'collect'
? {
...step,
taskDefinitionRef:
'plugin-package:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:task:alpha',
}
: step,
),
}),
InvalidPluginPackageWorkflowExecutionPlanError,
);
});
test('derives a deterministic atomic admission bundle and durable receipt', () => {
const value = fixture('workflow-admission-bundle');
const plan = createPluginPackageWorkflowExecutionPlan(planInput(value));
const bundle = createPluginPackageWorkflowAdmissionBundle(plan);
assert.deepEqual(bundle.plan, plan);
assert.equal(bundle.run.id, plan.runId);
assert.equal(bundle.run.status, 'running');
assert.equal(bundle.run.version, 3);
assert.equal(bundle.run.eventSequence, 3);
assert.equal(bundle.admissionEvent.sequence, 1);
assert.equal(bundle.admissionEvent.type, 'workflow.admitted');
assert.equal(bundle.admissionEvent.id.length <= 36, true);
assert.deepEqual(
bundle.stepMutations.map((mutation) => ({
stepKey: mutation.stepRun.stepKey,
status: mutation.stepRun.status,
expectedRunVersion: mutation.expectedRunVersion,
expectedRunEventSequence: mutation.expectedRunEventSequence,
eventSequence: mutation.event.sequence,
})),
[
{
stepKey: 'collect',
status: 'ready',
expectedRunVersion: 1,
expectedRunEventSequence: 1,
eventSequence: 2,
},
{
stepKey: 'summarize',
status: 'pending',
expectedRunVersion: 2,
expectedRunEventSequence: 2,
eventSequence: 3,
},
],
);
assert.equal(bundle.receipt.planDigest, plan.planDigest);
assert.equal(bundle.receipt.finalRunVersion, 3);
assert.equal(bundle.receipt.finalRunEventSequence, 3);
assert.equal(
bundle.receipt.receiptDigest,
pluginPackageWorkflowAdmissionReceiptDigest(bundle.receipt),
);
assert.equal(
bundle.stepMutations.every(
({ event }) => event.id.length <= 36 && event.dedupeKey.length <= 36,
),
true,
);
assert.deepEqual(
normalizePluginPackageWorkflowAdmissionReceipt(
JSON.parse(JSON.stringify(bundle.receipt)),
),
bundle.receipt,
);
assert.deepEqual(createPluginPackageWorkflowAdmissionBundle(plan), bundle);
});
test('rejects tampered Workflow admission receipts and counters', () => {
const value = fixture('workflow-admission-receipt-invalid');
const bundle = createPluginPackageWorkflowAdmissionBundle(
createPluginPackageWorkflowExecutionPlan(planInput(value)),
);
assert.throws(
() =>
normalizePluginPackageWorkflowAdmissionReceipt({
...bundle.receipt,
receiptDigest: 'f'.repeat(64),
}),
InvalidPluginPackageWorkflowAdmissionReceiptError,
);
assert.throws(
() =>
normalizePluginPackageWorkflowAdmissionReceipt({
...bundle.receipt,
finalRunVersion: 2,
}),
InvalidPluginPackageWorkflowAdmissionReceiptError,
);
});
test('keeps Run and RunEvent identities portable across SQLite and PostgreSQL', () => {
const value = fixture('workflow-portable-identity');
assert.throws(
() =>
createPluginPackageWorkflowExecutionPlan(
planInput(value, { runId: `r${'a'.repeat(36)}` }),
),
InvalidPluginPackageWorkflowExecutionPlanError,
);
});
test('publishes the pure planner only through its explicit runtime-core subpath', () => {
const subpath = require('@qinglong/runtime-core/plugin-package-workflow-execution-plan');
const root = require('../dist');
assert.equal(
subpath.createPluginPackageWorkflowExecutionPlan,
createPluginPackageWorkflowExecutionPlan,
);
assert.equal(root.createPluginPackageWorkflowExecutionPlan, undefined);
});