feat: ship deterministic parser and lifecycle release
This commit is contained in:
1 parent
208c434b31
commit
7b5d855b09
176 files changed
+20248
-1362
No files matched your search
@@ -0,0 +1,151 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import {
|
||||
OPERATION_TIMING_SCHEMA_VERSION,
|
||||
sanitizeOperationTiming
|
||||
} from '../src/operation-timing.js';
|
||||
|
||||
test('control plane keeps only the operation timing allowlisted shape', () => {
|
||||
const sanitized = sanitizeOperationTiming({
|
||||
schema_version: OPERATION_TIMING_SCHEMA_VERSION,
|
||||
status: 'completed',
|
||||
total_ms: 12_345.6,
|
||||
stage_count: 2,
|
||||
started_at: '2026-08-25T00:00:00.000Z',
|
||||
customer: '测试客户',
|
||||
stages: [{
|
||||
stage: 'preflight',
|
||||
status: 'completed',
|
||||
duration_ms: 2_345.4,
|
||||
url: 'https://example.invalid/private',
|
||||
details: [{
|
||||
step: 'network_wait.preflight_raw_instruction',
|
||||
status: 'completed',
|
||||
duration_ms: 1_800,
|
||||
response_text: 'private',
|
||||
counters: {
|
||||
request_count: 4,
|
||||
customer_name: 1,
|
||||
invalid_negative: -1,
|
||||
invalid_text: 'secret'
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
stage: 'john_smith',
|
||||
status: 'completed',
|
||||
duration_ms: 100
|
||||
}]
|
||||
});
|
||||
|
||||
assert.deepEqual(sanitized, {
|
||||
schema_version: OPERATION_TIMING_SCHEMA_VERSION,
|
||||
status: 'completed',
|
||||
total_ms: 12_346,
|
||||
stage_count: 2,
|
||||
stages: [{
|
||||
stage: 'preflight',
|
||||
status: 'completed',
|
||||
duration_ms: 2_345,
|
||||
details: [{
|
||||
step: 'network_wait.preflight_raw_instruction',
|
||||
status: 'completed',
|
||||
duration_ms: 1_800,
|
||||
counters: { request_count: 4 }
|
||||
}]
|
||||
}]
|
||||
});
|
||||
assert.equal(JSON.stringify(sanitized).includes('测试客户'), false);
|
||||
assert.equal(JSON.stringify(sanitized).includes('example.invalid'), false);
|
||||
assert.equal(JSON.stringify(sanitized).includes('response_text'), false);
|
||||
});
|
||||
|
||||
test('control plane rejects unknown timing contracts', () => {
|
||||
assert.equal(sanitizeOperationTiming(null), null);
|
||||
assert.equal(sanitizeOperationTiming({ schema_version: 'other', stages: [] }), null);
|
||||
assert.equal(sanitizeOperationTiming({ stages: [] }), null);
|
||||
});
|
||||
|
||||
test('control plane accepts every plugin page-action timing code', () => {
|
||||
const actions = [
|
||||
'cleanup_completed_lifecycle_dialog',
|
||||
'create_split_child_live',
|
||||
'create_split_parent_live',
|
||||
'export_confirmation_sources',
|
||||
'inspect_operation_context',
|
||||
'live_submit_approved',
|
||||
'live_submit_lifecycle_operation',
|
||||
'live_submit_team_batch_approved',
|
||||
'open_order_form',
|
||||
'open_team_batch_form',
|
||||
'ping_order_frame',
|
||||
'ping_team_batch_frame',
|
||||
'preflight_lifecycle_operation',
|
||||
'preflight_raw_instruction',
|
||||
'preflight_team_batch_native',
|
||||
'prepare_lifecycle_operation',
|
||||
'resolve_lifecycle_operation',
|
||||
'return_to_order_list',
|
||||
'unknown_action',
|
||||
'verify_lifecycle_operation',
|
||||
'verify_order_marker',
|
||||
'verify_team_batch_receipts'
|
||||
];
|
||||
const sanitized = sanitizeOperationTiming({
|
||||
schema_version: OPERATION_TIMING_SCHEMA_VERSION,
|
||||
status: 'completed',
|
||||
total_ms: 1,
|
||||
stages: [{
|
||||
stage: 'browser_execution',
|
||||
status: 'completed',
|
||||
duration_ms: 1,
|
||||
details: actions.map((action) => ({
|
||||
step: `action_roundtrip.${action}`,
|
||||
status: 'completed',
|
||||
duration_ms: 1,
|
||||
counters: { call_count: 1 }
|
||||
}))
|
||||
}]
|
||||
});
|
||||
|
||||
const details = sanitized?.stages as Array<{ details?: Array<{ step: string }> }>;
|
||||
assert.deepEqual(details[0]?.details?.map((detail) => detail.step), actions.map((action) => `action_roundtrip.${action}`));
|
||||
});
|
||||
|
||||
test('control plane keeps the privacy-safe orchestration breakdown used to locate unattributed time', () => {
|
||||
const safeDetails = [
|
||||
{ step: 'storage_prune.local_history', counters: { removed_result_count: 8, protected_root_count: 2 } },
|
||||
{ step: 'storage_read.result_state', counters: { result_count: 12, execution_count: 12, timing_count: 1 } },
|
||||
{ step: 'storage_write.result_state', counters: { call_count: 1 } },
|
||||
{ step: 'tab_lookup.cache_hit', counters: { cache_hit_count: 1 } },
|
||||
{ step: 'preflight_lookup.parallel_wall', counters: { request_count: 4 } },
|
||||
{ step: 'preflight_product_linkage', counters: { sample_count: 5, stable_sample_count: 4 } },
|
||||
{ step: 'preflight_submit_intercept', counters: { submit_count: 1, quiet_wait_ms: 150 } }
|
||||
];
|
||||
const sanitized = sanitizeOperationTiming({
|
||||
schema_version: OPERATION_TIMING_SCHEMA_VERSION,
|
||||
status: 'completed',
|
||||
total_ms: 10,
|
||||
stages: [{
|
||||
stage: 'preflight',
|
||||
status: 'completed',
|
||||
duration_ms: 10,
|
||||
details: safeDetails.map((detail) => ({ ...detail, status: 'completed', duration_ms: 1 }))
|
||||
}]
|
||||
});
|
||||
const stages = sanitized?.stages as Array<{ details?: Array<{ step: string }> }>;
|
||||
assert.deepEqual(stages[0]?.details?.map((detail) => detail.step), safeDetails.map((detail) => detail.step));
|
||||
|
||||
const rejected = sanitizeOperationTiming({
|
||||
schema_version: OPERATION_TIMING_SCHEMA_VERSION,
|
||||
status: 'completed',
|
||||
total_ms: 1,
|
||||
stages: [{
|
||||
stage: 'preflight',
|
||||
status: 'completed',
|
||||
duration_ms: 1,
|
||||
details: [{ step: 'storage_read.customer_value', duration_ms: 1, counters: { customer_name: 1 } }]
|
||||
}]
|
||||
});
|
||||
const rejectedStages = rejected?.stages as Array<{ details?: Array<unknown> }>;
|
||||
assert.equal(rejectedStages[0]?.details, undefined);
|
||||
});
|
||||
Reference in new issue
Block a user