feat: audit DeepSeek Chat across sources

This commit is contained in:
wuyang
2026-07-30 03:56:55 +08:00
parent 29ceae4e1b
commit 9211333234
24 changed files with 123017 additions and 42 deletions
@@ -0,0 +1,347 @@
import { createHash } from "node:crypto";
import { readFileSync, statSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
const root = resolve(import.meta.dirname, "..");
const paths = {
sampling: resolve(
root,
"src/data/deepseek-v2-lite-chat-cross-source-sampling.json",
),
evaluation: resolve(
root,
"src/data/deepseek-v2-lite-chat-cross-source-sampling-eval.json",
),
rerun: resolve(
root,
"src/data/deepseek-v2-lite-chat-cross-source-sampling-repro-r0.json",
),
reproduction: resolve(
root,
"src/data/deepseek-v2-lite-chat-cross-source-sampling-reproduction.json",
),
analysis: resolve(
root,
"src/data/deepseek-v2-lite-chat-cross-source-sampling-analysis.json",
),
output: resolve(
root,
"src/data/deepseek-v2-lite-chat-cross-source-sampling-compact.json",
),
};
const readJson = (path) => JSON.parse(readFileSync(path, "utf8"));
const sha256 = (path) => createHash("sha256")
.update(readFileSync(path))
.digest("hex");
const artifact = (path) => ({
bytes: statSync(path).size,
sha256: sha256(path),
});
const sampling = readJson(paths.sampling);
const evaluation = readJson(paths.evaluation);
const reproduction = readJson(paths.reproduction);
const analysis = readJson(paths.analysis);
const samplingArtifact = artifact(paths.sampling);
const evaluationArtifact = artifact(paths.evaluation);
const rerunArtifact = artifact(paths.rerun);
const reproductionArtifact = artifact(paths.reproduction);
if (evaluation.input.sampling_sha256 !== samplingArtifact.sha256) {
throw new Error("evaluation → sampling hash contract failed");
}
if (reproduction.formal.sha256 !== samplingArtifact.sha256) {
throw new Error("reproduction → formal hash contract failed");
}
if (reproduction.rerun.sha256 !== rerunArtifact.sha256) {
throw new Error("reproduction → rerun hash contract failed");
}
if (
reproduction.summary.cells !== 64
|| reproduction.summary.all_preregistered_fields_exact !== 64
|| Object.values(reproduction.summary.by_field).some(
(value) => value !== 64,
)
) {
throw new Error("64-cell reproduction gate failed");
}
if (
analysis.inputs.sampling.sha256 !== samplingArtifact.sha256
|| analysis.inputs.evaluation.sha256 !== evaluationArtifact.sha256
|| analysis.inputs.reproduction.sha256 !== reproductionArtifact.sha256
) {
throw new Error("analysis input hash chain failed");
}
if (
analysis.contract.sources !== 16
|| analysis.contract.sources_per_domain !== 4
|| analysis.contract.seeds_per_source_condition !== 4
|| analysis.contract.outputs !== 256
) {
throw new Error("source-blocked analysis grid contract failed");
}
const conditions = analysis.contract.conditions;
const conditionLabels = {
s0_eos: "S0 · EOS",
s1_eos: "S1 · EOS",
s0_period: "S0 · 句点",
s1_period: "S1 · 句点",
};
const domainLabels = {
english: "English · WikiText-2",
chinese: "中文 · TNEWS",
code: "Code · HumanEval",
math: "Math · GSM8K",
};
const sourceLabel = (sourceId) => {
if (sourceId.startsWith("HumanEval/")) {
return sourceId;
}
if (sourceId.startsWith("gsm8k/")) {
return `GSM8K/${sourceId.split("/").at(-1)}`;
}
if (sourceId.startsWith("tnews/")) {
return `TNEWS/${sourceId.split("/").at(-1)}`;
}
if (sourceId.startsWith("wikitext2/")) {
return `WikiText/${sourceId.split("/").at(-1)}`;
}
return sourceId;
};
const sourceMeta = Object.fromEntries(
Object.entries(analysis.source_metadata).map(([sourceId, row]) => [
sourceId,
{
...row,
label: sourceLabel(sourceId),
},
]),
);
const evalRows = evaluation.rows.map((row) => {
let task = null;
if (row.domain === "math") {
task = {
predicted: row.task_evaluation.predicted_final,
gold: row.task_evaluation.gold_final,
covered: row.task_evaluation.evaluator_covered,
fixedPass: row.task_evaluation.fixed_budget_numeric_exact,
strictPass: row.task_evaluation.strict_complete_numeric_exact,
method: row.task_evaluation.extraction_method,
};
} else if (row.domain === "code") {
task = {
ast: row.task_evaluation.python_ast_parse,
executed: row.task_evaluation.execution.status !== "not_run",
status: row.task_evaluation.execution.status,
fixedPass: row.task_evaluation.fixed_budget_tests_pass,
strictPass: row.task_evaluation.strict_complete_tests_pass,
candidateHash: row.task_evaluation.candidate_sha256,
cacheHit: row.task_evaluation.execution_cache_hit,
};
}
return {
sourceId: row.source_id,
domain: row.domain,
condition: row.condition,
replicate: row.replicate_label,
baseSeed: row.base_seed,
generatedTokens: row.generated_tokens,
hitEos: row.hit_eos,
truncated: row.stopped_at_max_new_tokens,
trajectoryHash: row.generated_token_ids_sha256,
completionClass: row.completion_class,
task,
};
});
const taskFailures = evalRows
.filter((row) => row.task && !row.task.strictPass)
.map((row) => ({
sourceId: row.sourceId,
sourceLabel: sourceLabel(row.sourceId),
domain: row.domain,
condition: row.condition,
replicate: row.replicate,
generatedTokens: row.generatedTokens,
hitEos: row.hitEos,
completionClass: row.completionClass,
detail: row.domain === "math"
? {
predicted: row.task.predicted,
gold: row.task.gold,
failure: "wrong_numeric_answer",
}
: {
status: row.task.status,
candidateHash: row.task.candidateHash,
failure: row.task.status,
},
}));
const taskTotals = Object.fromEntries(
Object.entries(analysis.task_matrix).map(([domain, tasks]) => [
domain,
tasks.map((task) => ({
sourceId: task.source_id,
label: sourceLabel(task.source_id),
withinDomainIndex: task.within_domain_index,
conditions: Object.fromEntries(
Object.entries(task.conditions).map(([condition, cell]) => [
condition,
{
pass: cell.strict_complete_success,
outputs: 4,
anyPass: cell.observed_any_strict_complete_pass,
naturalEos: cell.natural_eos,
meanGeneratedTokens: cell.generated_tokens.mean,
minGeneratedTokens: cell.generated_tokens.min,
maxGeneratedTokens: cell.generated_tokens.max,
},
]),
),
totalPass: Object.values(task.conditions).reduce(
(total, cell) => total + cell.strict_complete_success,
0,
),
totalOutputs: 16,
})),
]),
);
const periodDirection = Object.fromEntries(
Object.entries(analysis.prior_direction_check).map(([domain, row]) => {
const values = Object.values(
row.period_shortens_mean_tokens.by_source,
);
return [domain, {
shorter: values.filter(Boolean).length,
sources: values.length,
bySource: row.period_shortens_mean_tokens.by_source,
}];
}),
);
const systemEosDirection = Object.fromEntries(
Object.entries(analysis.prior_direction_check).map(([domain, row]) => {
const values = Object.values(
row.system_on_raises_natural_eos_rate.by_source,
);
return [domain, {
raises: values.filter(Boolean).length,
sources: values.length,
bySource: row.system_on_raises_natural_eos_rate.by_source,
}];
}),
);
const result = {
schemaVersion: 1,
capturedAt: sampling.captured_at,
contract: {
protocolId: sampling.protocol_id,
model: sampling.model.repo,
revision: sampling.model.revision,
conditions,
conditionLabels,
domains: Object.keys(analysis.contract.sources_by_domain),
domainLabels,
sources: analysis.contract.sources,
sourcesPerDomain: analysis.contract.sources_per_domain,
seedsPerCell: analysis.contract.seeds_per_source_condition,
outputs: analysis.contract.outputs,
baseSeeds: sampling.seed_contract.executed_base_seeds,
decode: {
doSample: sampling.generation_contract.do_sample,
temperature: sampling.generation_contract.temperature,
topP: sampling.generation_contract.top_p,
topK: sampling.generation_contract.top_k,
maxNewTokens: sampling.generation_contract.max_new_tokens,
},
sourceIsPrimaryCoverageUnit: (
analysis.contract.source_is_primary_coverage_unit
),
seedIsWithinSourceRepeat: (
analysis.contract.seed_is_within_source_repeat
),
noPopulationConfidenceIntervals: (
analysis.contract.no_population_confidence_intervals
),
noPValues: analysis.contract.no_p_values,
batchSeedAlignedNotCommonRandomNumbers: (
sampling.seed_contract.batch_seed_aligned_not_common_random_numbers
),
},
headline: {
...analysis.overall,
promptHashExact: sampling.source_contract.prompt_hash_audit.exact,
promptHashCells: sampling.source_contract.prompt_hash_audit.cells,
firstTwoSeedComparableCells: (
sampling.summary.first_two_seeds.comparable_cells
),
firstTwoSeedDifferentTrajectories: (
sampling.summary.first_two_seeds.different_trajectories
),
reproducedCells: (
reproduction.summary.all_preregistered_fields_exact
),
reproductionCells: reproduction.summary.cells,
codeAstParse: evaluation.summary.code.ast_parse,
codeExecuted: evaluation.summary.code.executed,
codeStatuses: evaluation.summary.code.execution_statuses,
codeUniqueExecutionKeys: (
evaluation.sandbox.unique_code_cache_entries
),
},
sourceMeta,
sourcesByDomain: analysis.contract.sources_by_domain,
sourceCells: analysis.source_condition_cells,
domainConditions: analysis.domain_condition_summary,
sourceContrasts: analysis.source_contrasts,
domainContrasts: analysis.domain_contrasts,
periodDirection,
systemEosDirection,
taskTotals,
taskFailures,
evalRows,
reproduction: reproduction.summary,
artifacts: {
sampling: samplingArtifact,
evaluation: evaluationArtifact,
rerun: rerunArtifact,
reproduction: reproductionArtifact,
analysis: artifact(paths.analysis),
},
execution: {
generationSeconds: sampling.sources.reduce(
(total, source) => total + source.runs.reduce(
(subtotal, run) => subtotal + run.generation_seconds,
0,
),
0,
),
peakCudaMemoryAllocatedBytes: (
sampling.execution.peak_cuda_memory_allocated_bytes
),
torch: sampling.execution.torch,
transformers: sampling.execution.transformers,
deviceMap: sampling.execution.device_map,
sandbox: evaluation.sandbox,
},
claimBoundary: [
...sampling.claim_boundary,
...evaluation.claim_boundary,
...analysis.claim_boundary,
...reproduction.claim_boundary,
],
};
writeFileSync(paths.output, `${JSON.stringify(result, null, 2)}\n`);
console.log(JSON.stringify({
output: paths.output,
...artifact(paths.output),
headline: result.headline,
periodDirection: result.periodDirection,
}, null, 2));
+5 -2
View File
@@ -82,6 +82,8 @@ const overview = await evaluate(`(() => ({
behaviorEdges: document.querySelectorAll("[data-behavior-map-edge]").length,
completionDepthTabs: document.querySelectorAll("[data-cd-tab]").length,
completionDepthPanels: document.querySelectorAll("[data-cd-panel]").length,
crossSourceTabs: document.querySelectorAll("[data-cs-tab]").length,
crossSourcePanels: document.querySelectorAll("[data-cs-panel]").length,
hiddenStages: document.querySelectorAll("[data-hidden-stage]").length,
routerLayers: document.querySelectorAll("[data-router-layer]").length,
branches: document.querySelectorAll(".branch-grid > a").length,
@@ -1210,14 +1212,15 @@ console.log(JSON.stringify(report, null, 2));
const numeric = (text) => Number.parseFloat(text.replaceAll(",", ""));
const failures = [];
if (!overview.title.includes("为什么转向")) failures.push("专题标题异常");
if (overview.sections !== 29 || overview.tocLinks !== 29) failures.push("二十八个编号专题加阅读链的目录结构异常");
if (overview.sections !== 30 || overview.tocLinks !== 30) failures.push("二十九个编号专题加阅读链的目录结构异常");
if (overview.ledgers !== 24 || overview.waves !== 10) failures.push("二十四张问题账或十次转向结构异常");
if (overview.paperLinks !== 60 || overview.branches !== 5 || overview.followups !== 1) failures.push("论文链、旁支或公开后续标记异常");
if (overview.labTabs !== 4 || overview.labPanels !== 4) failures.push("四联实验结构异常");
if (overview.artifactTabs !== 13 || overview.artifactPanels !== 13 || overview.artifactLayers !== 27) failures.push("真实权重十三联实验结构异常");
if (overview.behaviorTabs !== 4 || overview.behaviorPanels !== 4 || overview.behaviorSources !== 16 || overview.behaviorEdges !== 10) failures.push("Chat 行为实验结构异常");
if (overview.completionDepthTabs !== 4 || overview.completionDepthPanels !== 4 || overview.hiddenStages !== 29 || overview.routerLayers !== 26) failures.push("Chat 完成度与全深度实验结构异常");
if (overview.heroLabs !== "20 个可操作实验") failures.push("DeepSeek 实验总数账异常");
if (overview.crossSourceTabs !== 4 || overview.crossSourcePanels !== 4) failures.push("跨来源采样实验结构异常");
if (overview.heroLabs !== "21 个可操作实验") failures.push("DeepSeek 实验总数账异常");
if (overview.navLinks !== 20 || home.navLinks !== 20 || mobile.mobileLinks !== 20 || overview.activeNav !== "DeepSeek") failures.push("全站导航未同步 DeepSeek");
if (overview.documentOverflow > 1 || mobile.documentOverflow > 1) failures.push("桌面或移动端存在文档级横向溢出");
if (capacity.initial.panel !== "capacity" || capacity.initial.total !== "32.1× FFN" || capacity.initial.active !== "1.13× FFN") failures.push("V3 稀疏容量初始账异常");
@@ -0,0 +1,314 @@
import { writeFileSync } from "node:fs";
const cdpPort = process.env.CDP_PORT ?? "9230";
const baseUrl = process.env.SITE_URL ?? "http://127.0.0.1:4327";
const pages = await fetch(`http://127.0.0.1:${cdpPort}/json/list`)
.then((response) => response.json());
const page = pages.find((entry) => entry.type === "page");
if (!page) throw new Error(`CDP ${cdpPort} 没有可用页面`);
const socket = new WebSocket(page.webSocketDebuggerUrl);
await new Promise((resolve, reject) => {
socket.addEventListener("open", resolve, { once: true });
socket.addEventListener("error", reject, { once: true });
});
let nextId = 0;
const pending = new Map();
const exceptions = [];
socket.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
if (message.id && pending.has(message.id)) {
const { resolve, reject } = pending.get(message.id);
pending.delete(message.id);
if (message.error) reject(new Error(message.error.message));
else resolve(message.result);
}
if (message.method === "Runtime.exceptionThrown") {
exceptions.push(
message.params.exceptionDetails.exception?.description
?? message.params.exceptionDetails.text,
);
}
});
const command = (method, params = {}) => new Promise((resolve, reject) => {
const id = ++nextId;
pending.set(id, { resolve, reject });
socket.send(JSON.stringify({ id, method, params }));
});
const pause = (milliseconds) => new Promise(
(resolve) => setTimeout(resolve, milliseconds),
);
const evaluate = async (expression) => {
const result = await command("Runtime.evaluate", {
expression,
returnByValue: true,
awaitPromise: true,
});
if (result.exceptionDetails) {
throw new Error(
result.exceptionDetails.exception?.description
?? result.exceptionDetails.text,
);
}
return result.result.value;
};
const screenshot = async (path) => {
const result = await command("Page.captureScreenshot", {
format: "png",
captureBeyondViewport: false,
});
writeFileSync(path, Buffer.from(result.data, "base64"));
};
const assert = (condition, message) => {
if (!condition) throw new Error(message);
};
await command("Page.enable");
await command("Runtime.enable");
await command("Emulation.setDeviceMetricsOverride", {
width: 1440,
height: 1100,
deviceScaleFactor: 1,
mobile: false,
});
await command("Page.navigate", { url: `${baseUrl}/deepseek/` });
for (let attempt = 0; attempt < 100; attempt += 1) {
await pause(100);
if (await evaluate("document.readyState === 'complete'")) break;
}
const overview = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
if (!root) return null;
document.documentElement.style.scrollBehavior = "auto";
window.scrollTo(0, root.getBoundingClientRect().top + window.scrollY);
const facts = Object.fromEntries(
[...root.querySelectorAll(".cs-ledger article")].map((node) => [
node.querySelector("span").textContent.trim(),
node.querySelector("b").textContent.trim(),
]),
);
return {
tabs: root.querySelectorAll("[data-cs-tab]").length,
panels: root.querySelectorAll("[data-cs-panel]").length,
active: root.querySelector("[data-cs-panel]:not([hidden])")?.dataset.csPanel,
sourceCards: root.querySelectorAll("[data-cs-source-cards] > article").length,
seedDots: root.querySelectorAll(".seed-dots > i").length,
outputCount: root.querySelector("[data-cs-output-count]").textContent.trim(),
naturalEos: root.querySelector("[data-cs-natural-eos]").textContent.trim(),
facts,
labs: [...document.querySelectorAll(".page-facts > div")]
.find((node) => node.querySelector("dt")?.textContent.trim() === "LABS")
?.querySelector("dd")?.textContent.trim(),
status: [...document.querySelectorAll(".page-facts > div")]
.find((node) => node.querySelector("dt")?.textContent.trim() === "STATUS")
?.querySelector("dd")?.textContent.trim(),
overflow: document.documentElement.scrollWidth
- document.documentElement.clientWidth,
};
})()`);
await pause(250);
await screenshot("/tmp/llm-atlas-cross-source-desktop.png");
const hierarchySwitch = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
const domain = root.querySelector("[data-cs-domain]");
const condition = root.querySelector("[data-cs-condition]");
domain.value = "code";
domain.dispatchEvent(new Event("change", { bubbles: true }));
condition.value = "s1_period";
condition.dispatchEvent(new Event("change", { bubbles: true }));
return {
cards: [...root.querySelectorAll("[data-cs-source-cards] > article")].map((node) => ({
id: node.dataset.sourceId,
eos: node.querySelector("header em").textContent.trim(),
footer: node.querySelector(":scope > p").textContent.trim(),
dots: node.querySelectorAll(".seed-dots > i").length,
})),
outputCount: root.querySelector("[data-cs-output-count]").textContent.trim(),
naturalEos: root.querySelector("[data-cs-natural-eos]").textContent.trim(),
};
})()`);
const taskMatrices = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
root.querySelector('[data-cs-tab="tasks"]').click();
const read = () => ({
active: root.querySelector("[data-cs-panel]:not([hidden])").dataset.csPanel,
total: root.querySelector("[data-cs-task-total]").textContent.trim(),
rows: [...root.querySelectorAll("[data-cs-task-matrix] > div")].map((row) => ({
id: row.dataset.taskId,
cells: [...row.querySelectorAll("b")].map((cell) => cell.textContent.trim()),
total: row.querySelector("strong").textContent.trim(),
})),
range: root.querySelector("[data-cs-task-range]").textContent.trim(),
interaction: root.querySelector("[data-cs-task-interaction]").textContent.trim(),
failure: root.querySelector("[data-cs-task-failure]").textContent.trim(),
});
const math = read();
root.querySelector('[data-cs-task-domain="code"]').click();
const code = read();
return { math, code };
})()`);
await pause(150);
await screenshot("/tmp/llm-atlas-cross-source-task-matrix.png");
const directions = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
root.querySelector('[data-cs-tab="directions"]').click();
const select = root.querySelector("[data-cs-direction-domain]");
const read = () => ({
active: root.querySelector("[data-cs-panel]:not([hidden])").dataset.csPanel,
shorter: root.querySelector("[data-cs-shorter]").textContent.trim(),
mean: root.querySelector("[data-cs-domain-mean]").textContent.trim(),
median: root.querySelector("[data-cs-domain-median]").textContent.trim(),
rows: [...root.querySelectorAll("[data-cs-direction-rows] > article")].map((row) => ({
id: row.dataset.directionSource,
value: row.querySelector("b").textContent.trim(),
dotClass: row.querySelector("u").className,
})),
});
select.value = "english";
select.dispatchEvent(new Event("change", { bubbles: true }));
const english = read();
select.value = "code";
select.dispatchEvent(new Event("change", { bubbles: true }));
const code = read();
return { english, code };
})()`);
const keyboard = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
const first = root.querySelector('[data-cs-tab="hierarchy"]');
first.click();
first.focus();
first.dispatchEvent(new KeyboardEvent("keydown", {
key: "ArrowRight", bubbles: true,
}));
return {
selected: root.querySelector('[data-cs-tab][aria-selected="true"]').dataset.csTab,
active: root.querySelector("[data-cs-panel]:not([hidden])").dataset.csPanel,
focused: document.activeElement.dataset.csTab,
};
})()`);
const reproduction = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
root.querySelector('[data-cs-tab="reproduction"]').click();
return {
fields: [...root.querySelectorAll(".repro-fields article")].map((node) => (
node.querySelector("b").textContent.trim()
)),
artifacts: [...root.querySelectorAll(".hash-chain article")].map((node) => ({
label: node.querySelector("span").textContent.trim(),
hash: node.querySelector("b").textContent.trim(),
})),
active: root.querySelector("[data-cs-panel]:not([hidden])").dataset.csPanel,
};
})()`);
await command("Emulation.setDeviceMetricsOverride", {
width: 390,
height: 844,
deviceScaleFactor: 1,
mobile: true,
});
await pause(300);
const mobile = await evaluate(`(() => {
const root = document.querySelector("[data-cross-source-lab]");
root.querySelector('[data-cs-tab="tasks"]').click();
root.scrollIntoView();
return {
documentOverflow: document.documentElement.scrollWidth
- document.documentElement.clientWidth,
rootOverflow: root.scrollWidth - root.clientWidth,
matrixWidth: root.querySelector("[data-cs-task-matrix]").getBoundingClientRect().width,
viewport: window.innerWidth,
};
})()`);
await screenshot("/tmp/llm-atlas-cross-source-mobile.png");
assert(overview, "找不到跨来源采样实验");
assert(overview.tabs === 4 && overview.panels === 4, "四页签/面板合同异常");
assert(overview.active === "hierarchy", "初始面板不是 hierarchy");
assert(overview.sourceCards === 4 && overview.seedDots === 16, "source/seed 层级渲染异常");
assert(overview.outputCount === "16 / 16", "初始输出总账异常");
assert(overview.facts.SOURCES === "16", "source headline 异常");
assert(overview.facts["SAMPLED OUTPUTS"] === "256", "output headline 异常");
assert(overview.facts["NATURAL EOS"] === "250 / 256", "EOS headline 异常");
assert(overview.facts["MATH · STRICT"] === "47 / 64", "Math headline 异常");
assert(overview.facts["CODE · TESTS"] === "52 / 64", "Code headline 异常");
assert(overview.labs === "21 个可操作实验", "DeepSeek LABS 总账异常");
assert(overview.status === "七轮 · 512 条采样", "DeepSeek STATUS 总账异常");
assert(overview.overflow <= 1, `桌面横向溢出 ${overview.overflow}px`);
assert(hierarchySwitch.cards.length === 4, "Code source cards 数量异常");
assert(hierarchySwitch.cards.every((row) => row.dots === 4), "每题 seed 数不为 4");
assert(
hierarchySwitch.cards.find((row) => row.id === "HumanEval/133")
?.footer.includes("0 / 4 strict task pass"),
"HumanEval/133 × s1_period 应为 0/4",
);
assert(hierarchySwitch.naturalEos === "16 / 16", "Code s1_period EOS 异常");
assert(taskMatrices.math.total === "47 / 64", "Math total 异常");
assert(
taskMatrices.math.rows.map((row) => row.cells.join(",")).join("|")
=== "3 / 4,4 / 4,3 / 4,4 / 4|4 / 4,4 / 4,4 / 4,4 / 4|2 / 4,2 / 4,3 / 4,1 / 4|1 / 4,4 / 4,1 / 4,3 / 4",
"Math 4×4 pass matrix 异常",
);
assert(taskMatrices.math.range === "8 → 16 / 16", "Math source range 异常");
assert(taskMatrices.math.failure === "17 / 64", "Math failure 账异常");
assert(taskMatrices.code.total === "52 / 64", "Code total 异常");
assert(
taskMatrices.code.rows.map((row) => row.cells.join(",")).join("|")
=== "4 / 4,4 / 4,4 / 4,4 / 4|2 / 4,1 / 4,1 / 4,4 / 4|4 / 4,4 / 4,4 / 4,0 / 4|4 / 4,4 / 4,4 / 4,4 / 4",
"Code 4×4 pass matrix 异常",
);
assert(taskMatrices.code.interaction === "1↑ · 2= · 1↓", "Code interaction 方向异常");
assert(taskMatrices.code.failure === "12 / 64", "Code failure 账异常");
assert(directions.english.shorter === "1 / 4", "English 方向数异常");
assert(directions.english.mean === "−8.5 tokens".replace("−", "-"), "English mean 异常");
assert(directions.english.median === "+21.2 tokens", "English median 异常");
assert(
directions.english.rows.map((row) => row.value).join("|")
=== "-121.0 tokens|+44.5 tokens|+41.0 tokens|+1.4 tokens",
"English source contrast 异常",
);
assert(directions.code.shorter === "4 / 4", "Code 方向数异常");
assert(directions.code.rows.every((row) => row.dotClass === "negative"), "Code 应四条全负");
assert(
keyboard.selected === "tasks"
&& keyboard.active === "tasks"
&& keyboard.focused === "tasks",
"页签键盘导航异常",
);
assert(reproduction.active === "reproduction", "复现面板切换异常");
assert(reproduction.fields.length === 8, "复现字段数不为 8");
assert(reproduction.fields.every((value) => value === "64 / 64"), "复现字段未全部 exact");
assert(reproduction.artifacts.length === 5, "hash chain 工件数不为 5");
assert(mobile.documentOverflow <= 1, `移动端 document 横向溢出 ${mobile.documentOverflow}px`);
assert(mobile.rootOverflow <= 1, `移动端实验横向溢出 ${mobile.rootOverflow}px`);
assert(mobile.matrixWidth <= mobile.viewport, "移动端任务矩阵超出 viewport");
assert(exceptions.length === 0, `浏览器异常:${exceptions.join(" | ")}`);
console.log(JSON.stringify({
overview,
hierarchySwitch,
taskMatrices,
directions,
keyboard,
reproduction,
mobile,
screenshots: [
"/tmp/llm-atlas-cross-source-desktop.png",
"/tmp/llm-atlas-cross-source-task-matrix.png",
"/tmp/llm-atlas-cross-source-mobile.png",
],
}, null, 2));
socket.close();