import assert from "node:assert/strict"; import test from "node:test"; import { applyHoldoutAnswer } from "../src/lib/rectification-agentic/core/build-state.ts"; import { decideFromDossier, rectificationFollowupCatalog } from "../src/lib/rectification-agentic/v9/decision-from-dossier.ts"; import { buildCaseInferenceState } from "../src/lib/rectification-agentic/v9/inference-adapter.ts"; import { buildMethodFollowupPlan } from "../src/lib/rectification-agentic/v9/method-followup.ts"; import { evidenceLedgerFingerprint } from "../src/lib/rectification-agentic/v9/tool-service.ts"; import type { InferenceState } from "../src/lib/rectification-agentic/core/types.ts"; const COVERED_EVIDENCE = [ { id: "e-edu", status: "confirmed", domain: "education", datePrecision: "year", occurredFrom: "2016-01-01", occurredTo: null, eventKind: "education_milestone", }, { id: "e-career-a", status: "confirmed", domain: "career", datePrecision: "year", occurredFrom: "2018-01-01", occurredTo: null, eventKind: "career_entry", }, { id: "e-career-b", status: "confirmed", domain: "career", datePrecision: "year", occurredFrom: "2020-01-01", occurredTo: null, eventKind: "career_change", }, { id: "e-rel", status: "confirmed", domain: "relationship", datePrecision: "year", occurredFrom: "2024-01-01", occurredTo: null, eventKind: "relationship_start", }, { id: "e-fam", status: "confirmed", domain: "family", datePrecision: "year", occurredFrom: "2023-01-01", occurredTo: null, eventKind: "family_event", }, { id: "e-occ", status: "confirmed", domain: "occupation", datePrecision: "unknown", occurredFrom: null, occurredTo: null, eventKind: "occupation_note", }, ] as const; function producedDossier( evidence: readonly Readonly<{ id: string; status: string; domain: string; datePrecision: string; occurredFrom: string | null; occurredTo: string | null; eventKind?: string | null; }>[], options: { previous?: InferenceState | null } = {}, ) { const state = buildCaseInferenceState({ range: { start_time: "04:55", end_time: "05:02" }, candidates: [ { candidateId: "05:02", time: "05:02", relativeSupport: 58 }, { candidateId: "04:55", time: "04:55", relativeSupport: 42 }, ], evidence, probes: [], previous: options.previous, }); const latest = { resultId: "55555555-5555-4555-8555-555555555555", candidates: state.candidates.map((item) => ({ candidateId: item.id, time: item.time, rank: item.rank, relativeSupport: Math.round(item.posterior_score), })), representativeTime: state.representative_time, evidenceLedgerFingerprint: evidenceLedgerFingerprint(evidence as never), decisionReceipt: { inference_state: state }, }; return { state, dossier: { evidence, conversationSummary: { activeFocus: null, declinedSkippedTopics: [] }, latestResult: latest, case: { acceptedTime: null }, }, }; } function holdoutFollowup(dossier: ReturnType["dossier"]) { const catalog = rectificationFollowupCatalog(dossier.latestResult, dossier.evidence); return buildMethodFollowupPlan({ evidence: dossier.evidence, declinedTopics: dossier.conversationSummary.declinedSkippedTopics, sessionOutcome: "validate_holdout", ...catalog, candidatesSeparated: true, }); } test("sticky holdout with unknown precision does not ask validation and can adopt", () => { const { state, dossier: dated } = producedDossier(COVERED_EVIDENCE); const holdout = state.events.find((item) => item.usage === "holdout"); assert.ok(holdout); assert.notEqual(holdout.year, null); assert.equal(decideFromDossier(dated).nextAction, "ask_holdout_validation"); const undated = COVERED_EVIDENCE.map((item) => ( item.id === holdout.id ? { ...item, datePrecision: "unknown", occurredFrom: null, occurredTo: null } : item )); const { state: sticky, dossier } = producedDossier(undated, { previous: state }); const stickyHoldout = sticky.events.find((item) => item.id === holdout.id); assert.equal(stickyHoldout?.usage, "holdout"); assert.equal(stickyHoldout?.year, null); assert.equal(stickyHoldout?.precision, "unknown"); const decision = decideFromDossier(dossier); assert.notEqual(decision.nextAction, "ask_holdout_validation"); assert.equal(decision.nextAction, "ready_to_adopt"); assert.equal(decision.sessionOutcome, "adopt_representative"); assert.notEqual(decision.sessionOutcome, "validated_range"); assert.equal(decision.validated, false); assert.equal(decision.canAdopt, true); assert.equal(decision.canConfirmExactMinute, false); }); test("dated holdout asks validation with a renderable followup card", () => { const { dossier } = producedDossier(COVERED_EVIDENCE); const decision = decideFromDossier(dossier); assert.equal(decision.nextAction, "ask_holdout_validation"); assert.equal(decision.canConfirmExactMinute, false); const plan = holdoutFollowup(dossier); assert.ok(plan.next_followup); assert.ok(plan.next_followup.choice_frame, "holdout card must be renderable"); assert.equal(plan.next_followup.choice_frame.scoring, false); assert.ok(plan.next_followup.choice_frame.prompt); }); test("passed holdout is a validated range, not a unique minute", () => { const { state, dossier } = producedDossier(COVERED_EVIDENCE); const passed = applyHoldoutAnswer(state, "yes"); const decided = decideFromDossier({ ...dossier, latestResult: { ...dossier.latestResult, decisionReceipt: { inference_state: passed }, }, }); assert.equal(decided.sessionOutcome, "validated_range"); assert.equal(decided.canAdopt, true); assert.equal(decided.validated, true); assert.equal(decided.canConfirmExactMinute, false); assert.notEqual(decided.nextAction, "ask_holdout_validation"); }); test("failed holdout keeps existing non-validated close or discriminate path", () => { const { state, dossier } = producedDossier(COVERED_EVIDENCE); const failed = applyHoldoutAnswer(state, "no"); assert.equal(failed.holdout_passed, false); const decided = decideFromDossier({ ...dossier, latestResult: { ...dossier.latestResult, decisionReceipt: { inference_state: failed }, }, }); assert.equal(decided.holdoutValidation, "failed"); assert.notEqual(decided.nextAction, "ask_holdout_validation"); assert.notEqual(decided.sessionOutcome, "validated_range"); assert.equal(decided.validated, false); assert.equal(decided.canConfirmExactMinute, false); }); test("ask_holdout_validation is only returned when the same dossier can build a holdout followup", () => { const fixtures = [ producedDossier(COVERED_EVIDENCE).dossier, producedDossier(COVERED_EVIDENCE.filter((item) => item.domain !== "occupation")).dossier, ]; for (const dossier of fixtures) { const decision = decideFromDossier(dossier); if (decision.nextAction !== "ask_holdout_validation") continue; const plan = holdoutFollowup(dossier); assert.ok(plan.next_followup, "ask_holdout_validation requires a holdout followup"); assert.equal(decision.canConfirmExactMinute, false); } });