import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; import { mentionedVargaKeysFromLedgerEvidence, remainingVargaSplits, volunteeredDomainsFromEvidence, } from "../src/lib/rectification-agentic/core/candidate-contrast-packet.ts"; import { canonicalCollectDomain, declinedHasDomain, } from "../src/lib/rectification-agentic/v9/domain-alias.ts"; import { buildMethodFollowupPlan, declinedCollectDomains, holdoutFollowupFor, remainingConflictProbes, remainingReverseVerifyProbes, type MethodFollowupEvidence, } from "../src/lib/rectification-agentic/v9/method-followup.ts"; import type { DiscriminatingEventProbe } from "../src/lib/rectification-agentic/v9/refinement-packet.ts"; function existenceProbe( domain: DiscriminatingEventProbe["domain"], year: number, ): DiscriminatingEventProbe { const key = `${domain}.${year}.dasha_boundary`; return { year, year_label: `${year} 年前后`, domain, event_family: "生病、受伤或压力特别大", source: "dasha_boundary", tracks: ["vimshottari", "narayana"], tracks_agree: true, unique_minute_claim: false, user_meaning: `时间范围锁定 ${year} 年。`, role: "distinguish", information_gain: 1.1, semantic_key: key, candidate_split_hash: key, candidate_ids: ["05:00", "05:20"], expected_outcomes: [ { answer_class: "yes", supports: ["05:00"], conflicts: ["05:20"] }, { answer_class: "no", supports: ["05:20"], conflicts: ["05:00"] }, ], choice_kind: "existence", }; } function datedHealth(): MethodFollowupEvidence { return { id: "e-health", status: "confirmed", domain: "health", datePrecision: "month", occurredFrom: "2024-10-01", occurredTo: null, eventKind: "self_health_event", summary: "那年秋天身体垮过一截", }; } test("canonicalCollectDomain maps health and occupation-as-other", () => { assert.equal(canonicalCollectDomain("health"), "health_pressure"); assert.equal(canonicalCollectDomain("health_pressure"), "health_pressure"); assert.equal( canonicalCollectDomain("other", "collect:occupation:collect_method_evidence"), "occupation", ); assert.equal(canonicalCollectDomain("other", "collect:other:opening"), "other"); assert.equal(canonicalCollectDomain("career"), "career"); }); test("H1 holdout skips health_pressure after a skipped health focus", () => { const declined = declinedCollectDomains([{ target_domain: "health", status: "skipped", intent: "collect_method_evidence", question_id: "collect:health_pressure:collect_method_evidence", }]); assert.equal(declinedHasDomain(declined, "health_pressure"), true); const next = holdoutFollowupFor({ evidence: [ { id: "e-edu", status: "confirmed", domain: "education", datePrecision: "month", occurredFrom: "2016-09-01", occurredTo: null, eventKind: "education_start", }, { id: "e-career", status: "confirmed", domain: "career", datePrecision: "month", occurredFrom: "2018-04-01", occurredTo: null, eventKind: "career_entry", }, { id: "e-rel", status: "confirmed", domain: "relationship", datePrecision: "month", occurredFrom: "2021-05-01", occurredTo: null, eventKind: "relationship_start", }, ], oosBlindPrompts: [{ domain: "health_pressure", user_meaning: "校时还没用过健康压力这条线。", used_for_scoring: false, }], }, declined); assert.equal(next, null); }); test("H3 reverse-verify drops a declined health_pressure probe", () => { const declined = declinedCollectDomains([{ target_domain: "health", status: "declined", intent: "collect_method_evidence", question_id: "collect:health_pressure:collect_method_evidence", }]); const remaining = remainingReverseVerifyProbes( [existenceProbe("health_pressure", 2024)], [], declined, new Set(), "1997-08-08", ); assert.equal(remaining.length, 0); }); test("H4 conflict probes drop a declined health_pressure probe", () => { const declined = declinedCollectDomains([{ target_domain: "health", status: "declined", intent: "collect_method_evidence", question_id: "collect:health_pressure:collect_method_evidence", }]); const remaining = remainingConflictProbes( [existenceProbe("health_pressure", 2024)], [], declined, new Set(), "1997-08-08", ); assert.equal(remaining.length, 0); }); test("H5 ledger health 2024-10 covers a health_pressure 2024 probe", () => { const remaining = remainingReverseVerifyProbes( [existenceProbe("health_pressure", 2024)], [datedHealth()], new Set(), new Set(), "1997-08-08", ); assert.equal(remaining.length, 0); const conflicts = remainingConflictProbes( [existenceProbe("health_pressure", 2024)], [datedHealth()], new Set(), new Set(), "1997-08-08", ); assert.equal(conflicts.length, 0); }); test("H9 ledger health maps to D30 without relying on summary keywords", () => { const mentioned = mentionedVargaKeysFromLedgerEvidence([{ status: "confirmed", domain: "health", summary: "普通摘要不含关键词", }]); assert.equal(mentioned.includes("varga.d30"), true); }); test("H8 volunteered health aliases health_pressure so D30 remaining splits enter", () => { const hidden = remainingVargaSplits( ["05:00", "05:04"], [{ layer: "d30", at: "05:04" }], ); assert.equal(hidden.length, 0); const shown = remainingVargaSplits( ["05:00", "05:04"], [{ layer: "d30", at: "05:04" }], volunteeredDomainsFromEvidence([{ status: "confirmed", domain: "health" }]), ); assert.equal(shown[0]?.layer, "d30"); }); test("O1 occupation declined as other plus collect:occupation id covers occupation without career", () => { const declined = declinedCollectDomains([{ target_domain: "other", status: "declined", intent: "collect_method_evidence", question_id: "collect:occupation:collect_method_evidence", }]); assert.equal(declined.has("occupation"), true); assert.equal(declined.has("other"), false); const plan = buildMethodFollowupPlan({ evidence: [{ id: "e-edu", status: "confirmed", domain: "education", datePrecision: "month", occurredFrom: "2016-09-01", occurredTo: null, eventKind: "education_start", }], declinedTopics: [{ target_domain: "other", status: "declined", intent: "collect_method_evidence", question_id: "collect:occupation:collect_method_evidence", }], sessionOutcome: "collect_evidence", birthDate: "1997-08-08", }); assert.equal(plan.methods.find((item) => item.method_id === "occupation")?.status, "covered"); assert.notEqual(plan.next_followup?.domain, "occupation"); }); test("method-followup health compares only through domain-alias", () => { const followup = readFileSync( new URL("../src/lib/rectification-agentic/v9/method-followup.ts", import.meta.url), "utf8", ); const alias = readFileSync( new URL("../src/lib/rectification-agentic/v9/domain-alias.ts", import.meta.url), "utf8", ); assert.match(alias, /export function canonicalCollectDomain/); assert.match(alias, /"health"/); assert.doesNotMatch(followup, /"health"/); });