import assert from "node:assert/strict"; import test from "node:test"; import { applyChoiceWithoutEvidence } from "../src/lib/rectification-agentic/v9/inference-adapter.ts"; import { applyHoldoutAnswer, buildInferenceState } from "../src/lib/rectification-agentic/core/build-state.ts"; import { unionStillValidRange } from "../src/lib/rectification-agentic/core/credible-range.ts"; import { decideRectification } from "../src/lib/rectification-agentic/core/rectification-decision.ts"; import { posteriorMap } from "../src/lib/rectification-agentic/core/decision-fingerprint.ts"; import { holdoutEventIds } from "../src/lib/rectification-agentic/core/split-holdout.ts"; import { selectDiscriminatorProbe, buildCandidateContrastPacket } from "../src/lib/rectification-agentic/core/candidate-contrast-packet.ts"; import type { ConflictProbe } from "../src/lib/rectification-agentic/core/types.ts"; function probe(input: { id: string; domain: string; year: number; yesSupports: readonly string[]; noSupports: readonly string[]; }): ConflictProbe { return { id: input.id, semantic_key: `${input.domain}.${input.year}`, candidate_split_hash: `${input.yesSupports.join(",")}|${input.noSupports.join(",")}`, domain: input.domain, year: input.year, question: `${input.year} 年前后是否发生过相关前事?`, candidate_ids: [...input.yesSupports, ...input.noSupports], expected_outcomes: [ { answer_class: "yes", supports: input.yesSupports, conflicts: [] }, { answer_class: "no", supports: input.noSupports, conflicts: [] }, { answer_class: "unsure", supports: [], conflicts: [] }, ], information_gain: 0.4, source: "dasha_boundary", }; } test("credible range unions every still-valid cluster, not only rank=1", () => { const range = unionStillValidRange([ { id: "05:00", time: "05:00", cluster_range: ["05:00", "05:02"], prior_score: 12, posterior_score: 34, probability: 0.34, status: "active", rank: 1, strong_conflict_count: 0, }, { id: "05:20", time: "05:20", cluster_range: ["05:20", "05:22"], prior_score: 12, posterior_score: 33, probability: 0.33, status: "active", rank: 2, strong_conflict_count: 0, }, { id: "05:40", time: "05:40", cluster_range: ["05:40", "05:40"], prior_score: 4, posterior_score: 4, probability: 0.04, status: "active", rank: 3, strong_conflict_count: 0, }, ]); assert.deepEqual(range, ["05:00", "05:22"]); }); test("hidden case walks collection through holdout to a range or representative close", () => { const first = probe({ id: "p-career", domain: "career", year: 2015, yesSupports: ["05:00"], noSupports: ["05:20"], }); const collected = buildInferenceState({ range_start: "04:50", range_end: "05:30", candidates: [ { id: "05:00", time: "05:00", relative_support: 10 }, { id: "05:20", time: "05:20", relative_support: 4 }, ], events: [ { id: "e1", domain: "education", year: 2016, precision: "month" }, { id: "e2", domain: "career", year: 2018, precision: "year" }, { id: "e3", domain: "relationship", year: 2021, precision: "year" }, { id: "e4", domain: "family", year: 2023, precision: "year" }, ], probes: [first], }); const holdoutIds = holdoutEventIds(collected.events); assert.equal(holdoutIds.size, 1); assert.ok(collected.events.some((item) => item.usage === "training")); assert.ok(!collected.probes.some((item) => { const holdout = collected.events.find((row) => row.usage === "holdout"); return holdout !== undefined && item.domain === holdout.domain && item.year === holdout.year; })); const packet = buildCandidateContrastPacket({ candidateSetVersion: collected.candidate_set_id, calculationResultId: "11111111-1111-4111-8111-111111111111", engineProbes: collected.probes.map((item) => ({ semantic_key: item.semantic_key, candidate_split_hash: item.candidate_split_hash, domain: item.domain, year: item.year, user_meaning: item.question, information_gain: item.information_gain, expected_outcomes: item.expected_outcomes, candidate_ids: item.candidate_ids, })), }); const discriminator = selectDiscriminatorProbe(packet); assert.ok(discriminator); assert.ok(discriminator.informationGain > 0); assert.ok(discriminator.expectedOutcomes.length >= 2); const mapped = new Set(discriminator.expectedOutcomes.flatMap((row) => [ ...row.supportsCandidateIds, ...row.conflictsCandidateIds, ])); assert.ok(mapped.size >= 2); const before = posteriorMap(collected.candidates); const answered = applyChoiceWithoutEvidence(collected, { choiceKey: "A", schema: { probe_id: first.id, semantic_key: first.semantic_key }, }); assert.equal(answered.applied, true); assert.notDeepEqual(posteriorMap(answered.state.candidates), before); const scores = answered.state.candidates.map((item) => ({ time: item.time, score: item.posterior_score, })); const afterAnswers = decideRectification({ methodCoverageAll: true, candidateScores: scores, holdoutValidation: "not_started", }); assert.equal(afterAnswers.nextAction, "ask_holdout_validation"); assert.equal(afterAnswers.canConfirmExactMinute, false); const holdoutPassed = applyHoldoutAnswer(answered.state, "yes"); assert.equal(holdoutPassed.holdout_passed, true); assert.deepEqual(posteriorMap(holdoutPassed.candidates), posteriorMap(answered.state.candidates)); const closed = decideRectification({ methodCoverageAll: true, candidateScores: holdoutPassed.candidates.map((item) => ({ time: item.time, score: item.posterior_score, })), holdoutValidation: "passed", inferenceCredibleRange: holdoutPassed.credible_range, }); assert.ok(closed.nextAction === "ready_to_adopt" || closed.nextAction === "complete_with_range"); assert.equal(closed.canAdopt, true); assert.equal(closed.canConfirmExactMinute, false); assert.ok(closed.credibleRange); assert.notEqual(closed.sessionOutcome, "discriminate_candidates"); }); test("holdout failure returns to candidate discrimination", () => { const retry = probe({ id: "p-retry", domain: "career", year: 2018, yesSupports: ["05:00"], noSupports: ["05:20"], }); const state = buildInferenceState({ range_start: "04:50", range_end: "05:30", candidates: [ { id: "05:00", time: "05:00", relative_support: 40 }, { id: "05:20", time: "05:20", relative_support: 12 }, ], events: [ { id: "e1", domain: "education", year: 2016, precision: "month" }, { id: "e2", domain: "career", year: 2018, precision: "year" }, { id: "e3", domain: "relationship", year: 2021, precision: "year" }, { id: "e4", domain: "family", year: 2023, precision: "year" }, ], probes: [retry], }); const failed = applyHoldoutAnswer(state, "no"); assert.equal(failed.holdout_passed, false); const retryPacket = buildCandidateContrastPacket({ candidateSetVersion: failed.candidate_set_id, calculationResultId: "11111111-1111-4111-8111-111111111111", engineProbes: [{ semantic_key: retry.semantic_key, candidate_split_hash: retry.candidate_split_hash, domain: retry.domain, year: retry.year, user_meaning: retry.question, information_gain: retry.information_gain, expected_outcomes: retry.expected_outcomes, candidate_ids: retry.candidate_ids, }], }); const next = decideRectification({ methodCoverageAll: true, candidateScores: failed.candidates.map((item) => ({ time: item.time, score: item.posterior_score })), discriminatorProbe: selectDiscriminatorProbe(retryPacket), holdoutValidation: "failed", }); assert.equal(next.nextAction, "ask_candidate_discriminator"); });