feat(orchestrator): observe Page Data validation
This commit is contained in:
@@ -87,6 +87,61 @@ test('LangGraph runtime is idempotent by run id', async () => {
|
||||
assert.equal((await runtime.listEvents('run-shadow-1')).events.length, 3);
|
||||
});
|
||||
|
||||
test('LangGraph runtime records idempotent Page Data validation evidence after Shadow completion', async () => {
|
||||
const runtime = createLangGraphOrchestratorRuntime({
|
||||
checkpointer: new MemorySaver(),
|
||||
});
|
||||
await runtime.start(runSpec({
|
||||
input: {
|
||||
instruction: '[shadow-control-plane-only]',
|
||||
taskType: 'page_data_dev_complex',
|
||||
pageDataRequired: true,
|
||||
},
|
||||
}));
|
||||
const input = {
|
||||
idempotencyKey: 'run-shadow-1:page-data-delivery:v1',
|
||||
taskType: 'page_data_dev_complex',
|
||||
required: true,
|
||||
checks: [
|
||||
{ id: 'agent_run_completion', status: 'passed' },
|
||||
{ id: 'page_data_binding', status: 'passed' },
|
||||
{ id: 'page_data_storage_policy', status: 'passed' },
|
||||
],
|
||||
metrics: { pageCount: 2, publicationCount: 1 },
|
||||
observedAt: 123,
|
||||
};
|
||||
|
||||
const recorded = await runtime.recordValidationObservation('run-shadow-1', input);
|
||||
assert.equal(recorded.status, 'succeeded');
|
||||
assert.equal(recorded.validation.verdict, 'passed');
|
||||
assert.equal(recorded.validation.dataPolicy, 'control-plane-only-v1');
|
||||
assert.deepEqual(
|
||||
(await runtime.listEvents('run-shadow-1')).events.map((event) => event.type),
|
||||
[
|
||||
'workflow_validated',
|
||||
'workflow_planned',
|
||||
'workflow_completed',
|
||||
'workflow_validation_observed',
|
||||
],
|
||||
);
|
||||
|
||||
const duplicate = await runtime.recordValidationObservation('run-shadow-1', {
|
||||
...input,
|
||||
observedAt: 456,
|
||||
});
|
||||
assert.deepEqual(duplicate, recorded);
|
||||
assert.equal((await runtime.listEvents('run-shadow-1')).events.length, 4);
|
||||
await assert.rejects(
|
||||
() => runtime.recordValidationObservation('run-shadow-1', {
|
||||
...input,
|
||||
checks: [{ id: 'page_data_binding', status: 'failed' }],
|
||||
}),
|
||||
(error) => error.code === 'WORKFLOW_VALIDATION_IDEMPOTENCY_CONFLICT'
|
||||
&& error.status === 409,
|
||||
);
|
||||
assert.equal(await runtime.recordValidationObservation('missing-run', input), null);
|
||||
});
|
||||
|
||||
test('LangGraph runtime deletes terminal checkpoints and linked Executor Jobs', async () => {
|
||||
const runtime = createLangGraphOrchestratorRuntime({
|
||||
checkpointer: new MemorySaver(),
|
||||
|
||||
Reference in New Issue
Block a user