源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
Dependency audit / audit (push) Canceled after 0s
CI / plan (push) Canceled after 0s
Gitoxide helper admission / macos-latest (push) Canceled after 0s
Gitoxide helper admission / ubuntu-latest (push) Canceled after 0s
Gitoxide helper admission / windows-latest (push) Canceled after 0s
Runtime Host peer admission / quality (push) Canceled after 0s
Windows recovery / windows_recovery (push) Canceled after 0s
CI / heavy (push) Canceled after 0s
CI / test (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,401 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
const SAFE_TRACE_KEYS = new Set([
|
||||
'type',
|
||||
'actionType',
|
||||
'path',
|
||||
'effect',
|
||||
'verified',
|
||||
'supported',
|
||||
'ok',
|
||||
'durationMs',
|
||||
'at',
|
||||
'toolCallId',
|
||||
'pid',
|
||||
'windowId',
|
||||
'expectedPid',
|
||||
'expectedWindowId',
|
||||
'winnerPid',
|
||||
'winnerWindowId',
|
||||
'winnerZIndex',
|
||||
'address',
|
||||
'tool',
|
||||
]);
|
||||
const SAFE_TRACE_TYPES = new Set([
|
||||
'dispatch',
|
||||
'fallback',
|
||||
'occlusion',
|
||||
'outcome',
|
||||
'semantic_result',
|
||||
'snapshot',
|
||||
'target',
|
||||
'tool_start',
|
||||
'tool_result',
|
||||
'complete',
|
||||
'abort',
|
||||
'error',
|
||||
]);
|
||||
const SAFE_ACTION_TYPES = new Set([
|
||||
'list_apps',
|
||||
'observe',
|
||||
'click_element',
|
||||
'set_value',
|
||||
'select_text',
|
||||
'secondary_action',
|
||||
'press_key',
|
||||
'screenshot',
|
||||
'cursor_position',
|
||||
'mouse_move',
|
||||
'left_click',
|
||||
'right_click',
|
||||
'middle_click',
|
||||
'double_click',
|
||||
'triple_click',
|
||||
'left_mouse_down',
|
||||
'left_mouse_up',
|
||||
'left_click_drag',
|
||||
'type',
|
||||
'key',
|
||||
'hold_key',
|
||||
'scroll',
|
||||
'wait',
|
||||
'zoom',
|
||||
'unknown',
|
||||
]);
|
||||
const SAFE_TRACE_PATHS = new Set(['ax', 'cdp', 'cgevent', 'screenshot-detail']);
|
||||
const SAFE_TRACE_EFFECTS = new Set(['confirmed', 'unverifiable']);
|
||||
const SAFE_DISPATCH_ADDRESSES = new Set(['ax', 'px', 'semantic', 'none']);
|
||||
const SAFE_DISPATCH_TOOLS = new Set([
|
||||
'click',
|
||||
'set_value',
|
||||
'page',
|
||||
'press_key',
|
||||
'scroll',
|
||||
'drag',
|
||||
'zoom',
|
||||
]);
|
||||
|
||||
function safeUrlOrigin(value) {
|
||||
try {
|
||||
return new URL(value).origin;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function actionType(action) {
|
||||
return typeof action?.type === 'string'
|
||||
? action.type
|
||||
: typeof action?.action === 'string'
|
||||
? action.action
|
||||
: 'unknown';
|
||||
}
|
||||
|
||||
function safeToken(value, allowed) {
|
||||
return typeof value === 'string' && allowed.has(value) ? value : undefined;
|
||||
}
|
||||
|
||||
function resultCode(text) {
|
||||
if (typeof text !== 'string') return undefined;
|
||||
const failed = text.match(/\bfailed:\s*([a-z][a-z0-9_]{1,63})\b/i);
|
||||
if (failed) return failed[1];
|
||||
const status = text.match(/\b(?:ok|error)=([a-z][a-z0-9_]{1,63})\b/i);
|
||||
return status?.[1];
|
||||
}
|
||||
|
||||
export function sanitizeCuActionRecord(record) {
|
||||
const type = actionType(record?.action ?? record);
|
||||
return {
|
||||
type: SAFE_ACTION_TYPES.has(type) ? type : 'unknown',
|
||||
...(safeId(record?.toolCallId) ? { toolCallId: safeId(record.toolCallId) } : {}),
|
||||
...(safeId(record?.sourceObservationId)
|
||||
? { sourceObservationId: safeId(record.sourceObservationId) }
|
||||
: {}),
|
||||
...(type !== 'screenshot' && safeId(record?.resultObservationId)
|
||||
? { resultObservationId: safeId(record.resultObservationId) }
|
||||
: {}),
|
||||
...(Number.isInteger(record?.targetPid) && record.targetPid > 0
|
||||
? { targetPid: record.targetPid }
|
||||
: {}),
|
||||
...(Number.isInteger(record?.targetWindowId) && record.targetWindowId > 0
|
||||
? { targetWindowId: record.targetWindowId }
|
||||
: {}),
|
||||
...(typeof record?.success === 'boolean' ? { success: record.success } : {}),
|
||||
...(typeof record?.targetOwned === 'boolean' ? { targetOwned: record.targetOwned } : {}),
|
||||
...(record?.expectedFailure === true ? { expectedFailure: true } : {}),
|
||||
...(Number.isFinite(record?.durationMs) ? { durationMs: record.durationMs } : {}),
|
||||
...(Number.isFinite(record?.modelLatencyMs) ? { modelLatencyMs: record.modelLatencyMs } : {}),
|
||||
...(Number.isFinite(record?.toolLatencyMs) ? { toolLatencyMs: record.toolLatencyMs } : {}),
|
||||
...(Number.isFinite(record?.displayLagMs) ? { displayLagMs: record.displayLagMs } : {}),
|
||||
...(resultCode(record?.text) ? { resultCode: resultCode(record.text) } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
export function sanitizeCuTrace(trace) {
|
||||
if (!trace || typeof trace !== 'object') return null;
|
||||
if (!SAFE_TRACE_TYPES.has(trace.type)) return null;
|
||||
const sanitized = {};
|
||||
for (const [key, value] of Object.entries(trace)) {
|
||||
if (!SAFE_TRACE_KEYS.has(key)) continue;
|
||||
if (key === 'type') {
|
||||
sanitized.type = trace.type;
|
||||
continue;
|
||||
}
|
||||
if (key === 'actionType') {
|
||||
const action = safeToken(value, SAFE_ACTION_TYPES);
|
||||
if (action) sanitized.actionType = action;
|
||||
continue;
|
||||
}
|
||||
if (key === 'path') {
|
||||
const path = safeToken(value, SAFE_TRACE_PATHS);
|
||||
if (path) sanitized.path = path;
|
||||
continue;
|
||||
}
|
||||
if (key === 'effect') {
|
||||
const effect = safeToken(value, SAFE_TRACE_EFFECTS);
|
||||
if (effect) sanitized.effect = effect;
|
||||
continue;
|
||||
}
|
||||
if (key === 'address') {
|
||||
const address = safeToken(value, SAFE_DISPATCH_ADDRESSES);
|
||||
if (address) sanitized.address = address;
|
||||
continue;
|
||||
}
|
||||
if (key === 'tool') {
|
||||
const tool = safeToken(value, SAFE_DISPATCH_TOOLS);
|
||||
if (tool) sanitized.tool = tool;
|
||||
continue;
|
||||
}
|
||||
if (typeof value === 'string' || typeof value === 'boolean' || Number.isFinite(value)) {
|
||||
sanitized[key] = value;
|
||||
}
|
||||
}
|
||||
return Object.keys(sanitized).length > 0 ? sanitized : null;
|
||||
}
|
||||
|
||||
export function sanitizeCuDirectReport(report) {
|
||||
return sanitizeCuReport({
|
||||
...report,
|
||||
endpointOrigin: safeUrlOrigin(report?.endpointOrigin ?? report?.baseUrl),
|
||||
});
|
||||
}
|
||||
|
||||
export function sanitizeCuReport(report) {
|
||||
const terminal = report?.terminal;
|
||||
const fixtureState = report?.fixtureState;
|
||||
const expectedState = Array.isArray(report?.expectedState)
|
||||
? report.expectedState.map(sanitizeAssertionResult).filter(Boolean)
|
||||
: [];
|
||||
const violations = Array.isArray(report?.forbiddenEffects?.violations)
|
||||
? report.forbiddenEffects.violations.map(sanitizeAssertionResult).filter(Boolean)
|
||||
: [];
|
||||
return {
|
||||
schemaVersion: report?.schemaVersion === 1 ? 1 : undefined,
|
||||
runId: safeId(report?.runId),
|
||||
gitRevision: safeGitRevision(report?.gitRevision),
|
||||
generatedAt: safeTimestamp(report?.generatedAt),
|
||||
contentLineage: sanitizeContentLineage(report?.contentLineage),
|
||||
evidenceClass: safeToken(
|
||||
report?.evidenceClass,
|
||||
new Set(['real-runtime', 'fault-injection', 'hermetic-protocol', 'static-contract']),
|
||||
),
|
||||
scenarioId: safeId(report?.scenarioId),
|
||||
producer: safeId(report?.producer),
|
||||
transportClass: safeToken(
|
||||
report?.transportClass,
|
||||
new Set(['live-network', 'hermetic', 'static']),
|
||||
),
|
||||
policyMode: safeToken(report?.policyMode, new Set(['enforced', 'bypassed'])),
|
||||
qualificationEligible: report?.qualificationEligible === true,
|
||||
deprecated: report?.deprecated === true,
|
||||
toolExposure: safeToken(report?.toolExposure, new Set(['direct-e2e', 'deferred'])),
|
||||
provider: safeId(report?.provider),
|
||||
model: safeId(report?.model),
|
||||
endpointOrigin: safeUrlOrigin(report.baseUrl),
|
||||
status: safeToken(report?.status, new Set(['pass', 'fail', 'inconclusive'])),
|
||||
terminal:
|
||||
terminal && typeof terminal === 'object'
|
||||
? {
|
||||
type: safeToken(terminal.type, new Set(['complete', 'abort', 'error'])),
|
||||
stopReason: safeToken(
|
||||
terminal.stopReason,
|
||||
new Set([
|
||||
'end_turn',
|
||||
'max_tokens',
|
||||
'step_limit',
|
||||
'error',
|
||||
'user_stop',
|
||||
'permission_handoff',
|
||||
]),
|
||||
),
|
||||
}
|
||||
: undefined,
|
||||
fixtureIdentity: sanitizeFixtureIdentity(report?.fixtureIdentity),
|
||||
faultInjection: sanitizeFaultInjection(report?.faultInjection),
|
||||
run:
|
||||
report?.run && typeof report.run === 'object'
|
||||
? {
|
||||
status: safeToken(
|
||||
report.run.status,
|
||||
new Set([
|
||||
'created',
|
||||
'running',
|
||||
'waiting_for_user',
|
||||
'completed',
|
||||
'failed',
|
||||
'cancelled',
|
||||
]),
|
||||
),
|
||||
failureClass: safeId(report.run.failureClass),
|
||||
...(Number.isFinite(report.run.durationMs)
|
||||
? { durationMs: report.run.durationMs }
|
||||
: {}),
|
||||
}
|
||||
: undefined,
|
||||
...(Number.isFinite(report?.totalLatencyMs) ? { totalLatencyMs: report.totalLatencyMs } : {}),
|
||||
actionAttempts: Number.isInteger(report?.actionAttempts) ? report.actionAttempts : undefined,
|
||||
actionCount: Number.isInteger(report?.actionCount) ? report.actionCount : undefined,
|
||||
actionCounts: sanitizeCountMap(report?.actionCounts),
|
||||
minimumActionsPassed: report?.minimumActionsPassed === true,
|
||||
actionsWithinBudget: report?.actionsWithinBudget === true,
|
||||
dispatchPathPassed: report?.dispatchPathPassed === true,
|
||||
actions: Array.isArray(report?.actions) ? report.actions.map(sanitizeCuActionRecord) : [],
|
||||
fixtureState: sanitizeFixtureState(fixtureState),
|
||||
expectedState,
|
||||
forbiddenEffects: {
|
||||
status: safeToken(report?.forbiddenEffects?.status, new Set(['pass', 'fail'])),
|
||||
violations,
|
||||
},
|
||||
traces: Array.isArray(report?.traces) ? report.traces.map(sanitizeCuTrace).filter(Boolean) : [],
|
||||
driverTraces: Array.isArray(report?.driverTraces)
|
||||
? report.driverTraces.map(sanitizeCuTrace).filter(Boolean)
|
||||
: [],
|
||||
};
|
||||
}
|
||||
|
||||
function sanitizeContentLineage(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
|
||||
const generator = safeScriptPath(value.generator);
|
||||
const gitRevision = safeGitRevision(value.gitRevision);
|
||||
const generatedAt = safeTimestamp(value.generatedAt);
|
||||
if (!generator || !gitRevision || !generatedAt) return undefined;
|
||||
return { generator, gitRevision, generatedAt };
|
||||
}
|
||||
|
||||
function safeScriptPath(value) {
|
||||
return typeof value === 'string' && /^scripts\/[A-Za-z0-9._/-]{1,192}$/.test(value)
|
||||
? value
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function safeGitRevision(value) {
|
||||
return typeof value === 'string' && /^[a-f0-9]{40}$/.test(value) ? value : undefined;
|
||||
}
|
||||
|
||||
function safeTimestamp(value) {
|
||||
if (typeof value !== 'string') return undefined;
|
||||
const timestamp = Date.parse(value);
|
||||
return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value
|
||||
? value
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function sanitizeFixtureIdentity(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
|
||||
const candidates = Array.isArray(value.instances) ? value.instances : [value];
|
||||
const instances = candidates.flatMap((candidate) => {
|
||||
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) return [];
|
||||
const pid = Number.isInteger(candidate.pid) && candidate.pid > 0 ? candidate.pid : undefined;
|
||||
const windowIds = Array.isArray(candidate.windowIds)
|
||||
? [...new Set(candidate.windowIds.filter((entry) => Number.isInteger(entry) && entry > 0))]
|
||||
: [];
|
||||
return pid && windowIds.length > 0 ? [{ pid, windowIds }] : [];
|
||||
});
|
||||
if (instances.length === 0) return undefined;
|
||||
return {
|
||||
instances: instances.filter(
|
||||
(candidate, index) =>
|
||||
instances.findIndex(
|
||||
(entry) =>
|
||||
entry.pid === candidate.pid &&
|
||||
JSON.stringify(entry.windowIds) === JSON.stringify(candidate.windowIds),
|
||||
) === index,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function sanitizeFaultInjection(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;
|
||||
const layer = safeToken(value.layer, new Set(['runtime']));
|
||||
const kind = safeId(value.kind);
|
||||
return layer && kind ? { layer, kind } : undefined;
|
||||
}
|
||||
|
||||
function safeId(value) {
|
||||
return typeof value === 'string' && /^[A-Za-z0-9._-]{1,128}$/.test(value) ? value : undefined;
|
||||
}
|
||||
|
||||
function sanitizeCountMap(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).flatMap(([key, count]) =>
|
||||
SAFE_ACTION_TYPES.has(key) && Number.isInteger(count) && count >= 0 ? [[key, count]] : [],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function sanitizeFixtureState(value) {
|
||||
if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).flatMap(([windowId, state]) => {
|
||||
if (!safeId(windowId) || !state || typeof state !== 'object' || Array.isArray(state)) {
|
||||
return [];
|
||||
}
|
||||
const safeState = Object.fromEntries(
|
||||
Object.entries(state).flatMap(([key, field]) =>
|
||||
safeId(key) &&
|
||||
(typeof field === 'boolean' ||
|
||||
typeof field === 'number' ||
|
||||
(typeof field === 'string' && /^[A-Za-z0-9 .:_-]{0,128}$/.test(field)))
|
||||
? [[key, field]]
|
||||
: [],
|
||||
),
|
||||
);
|
||||
return [[windowId, safeState]];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function sanitizeAssertionResult(value) {
|
||||
if (!value || typeof value !== 'object') return null;
|
||||
const windowId = safeId(value.windowId);
|
||||
const path = safeId(value.path);
|
||||
if (!windowId || !path || typeof value.pass !== 'boolean') return null;
|
||||
return {
|
||||
windowId,
|
||||
path,
|
||||
pass: value.pass,
|
||||
...(typeof value.actual === 'boolean' ||
|
||||
typeof value.actual === 'number' ||
|
||||
typeof value.actual === 'string'
|
||||
? { actual: value.actual }
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user