import assert from "node:assert/strict"; import { readFileSync, readdirSync, statSync } from "node:fs"; import { join } from "node:path"; import test from "node:test"; import { answersFromEvidence } from "../src/lib/rectification-agentic/core/build-state.ts"; import { classifySnapshotStaleReason, storedSnapshotIsCurrent, type CandidateSnapshotSource, } from "../src/lib/rectification-agentic/core/snapshot-source.ts"; import type { ConflictProbe } from "../src/lib/rectification-agentic/core/types.ts"; import { contrastPacketFromLatestResult } from "../src/lib/rectification-agentic/v9/decision-from-dossier.ts"; import { parseDiscriminatingEventProbes, parseProspectiveProbes, prospectiveWindowsNarration, } from "../src/lib/rectification-agentic/v9/refinement-packet.ts"; const OUTCOMES = [ { answer_class: "yes" as const, supports: ["05:00"], conflicts: ["05:07"] }, { answer_class: "no" as const, supports: ["05:07"], conflicts: ["05:00"] }, ]; function source(overrides: Partial = {}): CandidateSnapshotSource { return { birthProfileFingerprint: "birth-a", scoreableEvidenceFingerprint: "score-a", inferenceRevision: 3, candidateSetVersion: "set-a", scoringPolicyVersion: "rectification-candidate-policy-v3", ...overrides, }; } function qualityProbe(overrides: Record = {}) { return { year: 2016, year_label: "2016 年 9 月", domain: "education", event_family: "学业或考试发挥失常、压力特别大", source: "known_event_quality", tracks: ["vimshottari", "narayana"], tracks_agree: true, unique_minute_claim: false, user_meaning: "2016 年 9 月那次上大学,更接近哪一种实际体验。", role: "distinguish", phase: "candidate_discriminator", semantic_key: "education.2016.known_event_quality", information_gain: 0.42, candidate_split_hash: "quality-split", candidate_set_version: "set-a", candidate_ids: ["05:00", "05:07"], expected_outcomes: OUTCOMES, choice_kind: "event_quality", question_contract_version: "probe-question-v1", target_evidence_id: "00000000-0000-4000-8000-000000000001", display_date_label: "2016 年 9 月", ...overrides, }; } function walkFiles(root: string, suffixes: readonly string[]): string[] { const skip = new Set(["node_modules", ".next", "dist"]); const out: string[] = []; const visit = (dir: string) => { for (const name of readdirSync(dir)) { if (skip.has(name)) continue; const path = join(dir, name); const stat = statSync(path); if (stat.isDirectory()) visit(path); else if (suffixes.some((suffix) => name.endsWith(suffix))) out.push(path); } }; visit(root); return out; } test("scoring policy version changes stale stored snapshots", () => { const current = source(); const previous = source({ scoringPolicyVersion: "rectification-candidate-policy-v2" }); assert.equal(classifySnapshotStaleReason(previous, current), "scoring_policy_changed"); assert.equal(storedSnapshotIsCurrent(previous, current), false); assert.equal(storedSnapshotIsCurrent(current, current), true); }); test("anchored known_event_quality distinguish probes stay in the public packet", () => { const parsed = parseDiscriminatingEventProbes([qualityProbe()]); assert.equal(parsed.length, 1); assert.equal(parsed[0]?.source, "known_event_quality"); assert.equal(parsed[0]?.role, "distinguish"); assert.equal(parsed[0]?.target_evidence_id, "00000000-0000-4000-8000-000000000001"); const unanchored = parseDiscriminatingEventProbes([qualityProbe({ target_evidence_id: undefined })]); assert.equal(unanchored.length, 0); const packet = contrastPacketFromLatestResult({ resultId: "result-a", decisionReceipt: { discriminating_event_probes: [qualityProbe()], inference_state: { probes: [{ id: "probe:education.2016.known_event_quality:quality-split", semantic_key: "education.2016.known_event_quality", candidate_split_hash: "quality-split", domain: "education", year: 2016, question: "2016 年 9 月那次上大学,更接近哪一种实际体验。", candidate_ids: ["05:00", "05:07"], expected_outcomes: OUTCOMES, information_gain: 0.42, source: "known_event_quality", choice_kind: "event_quality", target_evidence_id: "00000000-0000-4000-8000-000000000001", }], answered_probes: [], }, }, }); assert.equal( packet.probes.some((item) => ( item.semanticKey === "education.2016.known_event_quality" || item.choiceKind === "event_quality" )), true, ); }); test("quality answers are not inferred from event existence alone", () => { const probe: ConflictProbe = { id: "probe-quality", semantic_key: "education.2016.known_event_quality", candidate_split_hash: "quality-split", domain: "education", year: 2016, question: "那次上大学更接近哪一种体验", candidate_ids: ["05:00", "05:07"], expected_outcomes: OUTCOMES, information_gain: 0.42, source: "known_event_quality", choice_kind: "event_quality", }; const answers = answersFromEvidence([probe], [{ id: "00000000-0000-4000-8000-000000000001", domain: "education", year: 2016, precision: "month", }]); assert.equal(answers.length, 0); }); test("prospective probes stay out of scoring copy", () => { const parsed = parseProspectiveProbes([{ candidate_label: "A", domain: "career", window_label: "2027 年 3 月附近", user_meaning: "候选 A 预测下一次事业变动更可能在 2027 年 3 月附近。这是预测窗口,不是承诺;下次发生时回来补一条,可进一步分辨。", used_for_scoring: false, }]); assert.equal(parsed.length, 1); const copy = prospectiveWindowsNarration(parsed); assert.match(String(copy), /预测窗口/); assert.equal(parsed[0]?.used_for_scoring, false); }); test("scripts and frontend contain no answer-key literals", () => { const forbidden = ["target" + "_minute", "pl9_" + "1993", "regression" + "_only"]; const files = [ ...walkFiles(join(process.cwd(), "src"), [".ts", ".tsx", ".js"]), ...walkFiles(join(process.cwd(), "tests"), [".ts", ".tsx"]), ]; const hits: string[] = []; for (const file of files) { const text = readFileSync(file, "utf8"); for (const token of forbidden) { if (text.includes(token)) hits.push(`${file}:${token}`); } } assert.deepEqual(hits, []); });