b43808b016
Only sign-bound varga_style questions may omit a concrete period. Remaining-layer existence and quality probes now drop as yearless_ungrounded_contrast instead of scoring by group order. Co-authored-by: Cursor <cursoragent@cursor.com>
319 lines
13 KiB
TypeScript
319 lines
13 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { inspectDiscriminatorProbes } from "../src/lib/rectification-agentic/core/candidate-contrast-packet.ts";
|
|
import { buildChoiceFrame, serverOwnedChoiceCopy } from "../src/lib/rectification-agentic/v9/choice-card.ts";
|
|
import {
|
|
decideFromDossier,
|
|
followupAsksRenderableDiscriminator,
|
|
type DecisionDossier,
|
|
} from "../src/lib/rectification-agentic/v9/decision-from-dossier.ts";
|
|
import { buildMethodFollowupPlan, shouldAttachChoiceFrame } from "../src/lib/rectification-agentic/v9/method-followup.ts";
|
|
import {
|
|
isRenderableProbe,
|
|
isRenderableStyleOptions,
|
|
} from "../src/lib/rectification-agentic/v9/probe-question-contract.ts";
|
|
import type { DiscriminatingEventProbe } from "../src/lib/rectification-agentic/v9/refinement-packet.ts";
|
|
import { d9StyleLabel, d10StyleLabel } from "../src/lib/rectification-agentic/v9/varga-type-tables.ts";
|
|
|
|
const YEARLESS_LAYERS = [
|
|
{ layer: "d4", kind: "existence" as const, domain: "relocation", family: "搬家或长期住到外地" },
|
|
{ layer: "d7", kind: "existence" as const, domain: "family", family: "家人结婚、添丁或住院" },
|
|
{ layer: "d12", kind: "existence" as const, domain: "family", family: "家人结婚、添丁或住院" },
|
|
{ layer: "d2", kind: "existence" as const, domain: "finance", family: "收入明显变化、大笔支出或欠债" },
|
|
{ layer: "d11", kind: "existence" as const, domain: "finance", family: "收入明显变化、大笔支出或欠债" },
|
|
{ layer: "d30", kind: "existence" as const, domain: "health_pressure", family: "生病、受伤或压力特别大" },
|
|
{ layer: "d24", kind: "event_quality" as const, domain: "education", family: "学业或考试发挥失常、压力特别大" },
|
|
{ layer: "d5", kind: "event_quality" as const, domain: "education", family: "学业或考试发挥失常、压力特别大" },
|
|
] as const;
|
|
|
|
const DATED_EXISTENCE: DiscriminatingEventProbe = {
|
|
year: 2016,
|
|
year_label: "2016 年前后",
|
|
domain: "relocation",
|
|
event_family: "搬家、离乡或长期异地",
|
|
source: "dasha_activation",
|
|
tracks: ["vimshottari", "narayana"],
|
|
tracks_agree: true,
|
|
unique_minute_claim: false,
|
|
user_meaning: "年份锁定 2016 年前后。",
|
|
role: "distinguish",
|
|
information_gain: 0.8,
|
|
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",
|
|
semantic_key: "relocation.2016.dasha_boundary",
|
|
};
|
|
|
|
function yearlessProbe(layer: string, kind: "existence" | "event_quality" | "varga_style", domain: string, family: string): DiscriminatingEventProbe {
|
|
return {
|
|
year: 0,
|
|
year_label: "当前这几个候选",
|
|
domain: domain as DiscriminatingEventProbe["domain"],
|
|
event_family: family,
|
|
source: "dasha_activation",
|
|
tracks: ["vimshottari", "narayana"],
|
|
tracks_agree: true,
|
|
unique_minute_claim: false,
|
|
user_meaning: "对照分盘差异只作校时方法,不是命运承诺。",
|
|
role: "distinguish",
|
|
information_gain: 1.2,
|
|
candidate_ids: ["05:00", "05:07"],
|
|
expected_outcomes: [
|
|
{ answer_class: "yes", supports: ["05:00"], conflicts: ["05:07"] },
|
|
{ answer_class: "no", supports: ["05:07"], conflicts: ["05:00"] },
|
|
],
|
|
choice_kind: kind,
|
|
semantic_key: `varga.${layer}.05:00/05:07`,
|
|
};
|
|
}
|
|
|
|
function contrastFromYearless(layer: string, kind: "existence" | "event_quality" | "varga_style", domain: string, extra: Record<string, unknown> = {}) {
|
|
return {
|
|
probeId: `contrast:varga.${layer}.05:00/05:07`,
|
|
candidateSetVersion: "05:00-05:07",
|
|
question: "当前几个候选还分得开。",
|
|
expectedOutcomes: [
|
|
{ outcomeId: "yes", supportsCandidateIds: ["05:00"], conflictsCandidateIds: ["05:07"] },
|
|
{ outcomeId: "no", supportsCandidateIds: ["05:07"], conflictsCandidateIds: ["05:00"] },
|
|
],
|
|
candidateSplitHash: `varga.${layer}.05:00/05:07`,
|
|
informationGain: 1.4,
|
|
sourceFeatures: [{ technique: layer.toUpperCase(), calculationResultId: null }],
|
|
domain,
|
|
year: null as number | null,
|
|
semanticKey: `varga.${layer}.05:00/05:07`,
|
|
choiceKind: kind,
|
|
...extra,
|
|
};
|
|
}
|
|
|
|
function frameFor(probe: DiscriminatingEventProbe) {
|
|
return buildChoiceFrame({
|
|
method_id: "dasha_events",
|
|
ask_theme: "dated_event",
|
|
domain: probe.domain,
|
|
user_prompt_hint: "unused",
|
|
choice_kind: probe.choice_kind,
|
|
semantic_key: probe.semantic_key,
|
|
style_options: probe.style_options,
|
|
}, { probes: [probe] });
|
|
}
|
|
|
|
test("yearless existence and quality varga layers do not mint a choice frame", () => {
|
|
for (const row of YEARLESS_LAYERS) {
|
|
const frame = frameFor(yearlessProbe(row.layer, row.kind, row.domain, row.family));
|
|
assert.equal(frame, null, `yearless ${row.layer} should not card`);
|
|
}
|
|
});
|
|
|
|
test("yearless signed D9/D10 varga_style still cards; unsigned varga_style does not", () => {
|
|
const signed = frameFor({
|
|
...yearlessProbe("d9", "varga_style", "relationship", "相处方式更接近其中一种"),
|
|
style_options: [
|
|
{ sign: "天秤座", label: d9StyleLabel("天秤座"), answer_class: "yes" },
|
|
{ sign: "天蝎座", label: d9StyleLabel("天蝎座"), answer_class: "weak_yes" },
|
|
],
|
|
});
|
|
assert.ok(signed);
|
|
const copy = serverOwnedChoiceCopy(signed!);
|
|
assert.ok(copy);
|
|
assert.equal(isRenderableStyleOptions(copy!.options.map((item) => ({
|
|
label: item.label,
|
|
answer_class: item.answer_class,
|
|
}))), true);
|
|
assert.equal(copy!.options.some((item) => item.label.includes("时间吻合") || item.label.includes("这段")), false);
|
|
assert.equal(signed!.option_a_answer_class, "yes");
|
|
assert.equal(signed!.option_b_answer_class, "weak_yes");
|
|
|
|
const unsigned = frameFor({
|
|
...yearlessProbe("d9", "varga_style", "relationship", "相处方式更接近其中一种"),
|
|
semantic_key: "varga.d9.05:00/05:07",
|
|
style_options: [
|
|
{ label: d9StyleLabel("天秤座"), answer_class: "yes" },
|
|
{ label: d9StyleLabel("天蝎座"), answer_class: "weak_yes" },
|
|
],
|
|
});
|
|
assert.equal(unsigned, null);
|
|
|
|
const d10 = frameFor({
|
|
...yearlessProbe("d10", "varga_style", "career", "做事风格更接近其中一种"),
|
|
style_options: [
|
|
{ sign: "巨蟹座", label: d10StyleLabel("巨蟹座"), answer_class: "yes" },
|
|
{ sign: "狮子座", label: d10StyleLabel("狮子座"), answer_class: "weak_yes" },
|
|
],
|
|
});
|
|
assert.ok(d10);
|
|
});
|
|
|
|
test("dated dasha, age-band, quality, and reserved-event cards still mint", () => {
|
|
assert.ok(frameFor(DATED_EXISTENCE));
|
|
assert.match(frameFor(DATED_EXISTENCE)!.prompt, /2016 年前后/);
|
|
const month = frameFor({
|
|
...DATED_EXISTENCE,
|
|
year: 2018,
|
|
year_label: "2018 年 3 月前后",
|
|
month: 3,
|
|
semantic_key: "relocation.2018.03.dasha_boundary",
|
|
});
|
|
assert.ok(month);
|
|
assert.match(month!.prompt, /2018 年 3 月/);
|
|
const quality = frameFor({
|
|
...DATED_EXISTENCE,
|
|
year: 2020,
|
|
year_label: "2020 年前后",
|
|
domain: "education",
|
|
event_family: "学业或考试发挥失常、压力特别大",
|
|
source: "known_event_quality",
|
|
choice_kind: "event_quality",
|
|
semantic_key: "education.2020.known_event_quality",
|
|
});
|
|
assert.ok(quality);
|
|
assert.match(quality!.prompt, /2020 年前后/);
|
|
const holdout = buildChoiceFrame({
|
|
method_id: "oos_blind",
|
|
ask_theme: "oos_blind",
|
|
domain: "family",
|
|
user_prompt_hint: "unused",
|
|
choice_kind: "existence",
|
|
}, {
|
|
scoring: false,
|
|
probes: [{
|
|
...DATED_EXISTENCE,
|
|
year: 2023,
|
|
year_label: "2023 年前后",
|
|
domain: "family",
|
|
event_family: "家人结婚、添丁或住院",
|
|
user_meaning: "盘外核对:只核对家人事件,不计入候选评分。",
|
|
semantic_key: "family.2023.holdout",
|
|
}],
|
|
});
|
|
assert.ok(holdout);
|
|
});
|
|
|
|
test("yearless ungrounded probes are dropped with a recognizable reason", () => {
|
|
const probes = YEARLESS_LAYERS.map((row) => contrastFromYearless(row.layer, row.kind, row.domain));
|
|
const inspected = inspectDiscriminatorProbes({
|
|
candidateSetVersion: "05:00-05:07",
|
|
vargaDifferences: [],
|
|
probes,
|
|
});
|
|
assert.equal(inspected.selected, null);
|
|
for (const row of YEARLESS_LAYERS) {
|
|
const dropped = inspected.dropped.find((item) => item.semantic_key === `varga.${row.layer}.05:00/05:07`);
|
|
assert.ok(dropped, row.layer);
|
|
assert.equal(dropped!.reason, "yearless_ungrounded_contrast");
|
|
}
|
|
const plan = buildMethodFollowupPlan({
|
|
evidence: [
|
|
{ status: "confirmed", domain: "education", datePrecision: "year", occurredFrom: "2016-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "career", datePrecision: "year", occurredFrom: "2020-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "relationship", datePrecision: "year", occurredFrom: "2024-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "family", datePrecision: "year", occurredFrom: "2021-01-01", occurredTo: null },
|
|
],
|
|
sessionOutcome: "discriminate_candidates",
|
|
candidatesSeparated: false,
|
|
contrastPacket: { candidateSetVersion: "05:00-05:07", vargaDifferences: [], probes },
|
|
});
|
|
assert.equal(plan.dropped_probes.some((item) => item.reason === "yearless_ungrounded_contrast"), true);
|
|
});
|
|
|
|
test("decision and ask layer agree when only yearless ungrounded contrast remains", () => {
|
|
const probes = YEARLESS_LAYERS.map((row) => contrastFromYearless(row.layer, row.kind, row.domain));
|
|
const evidence = [
|
|
{ id: "e-edu", status: "confirmed", domain: "education", datePrecision: "year" as const, occurredFrom: "2016-01-01", occurredTo: null, eventKind: "education_start" },
|
|
{ id: "e-career", status: "confirmed", domain: "career", datePrecision: "year" as const, occurredFrom: "2020-01-01", occurredTo: null, eventKind: "career_entry" },
|
|
{ id: "e-rel", status: "confirmed", domain: "relationship", datePrecision: "year" as const, occurredFrom: "2024-01-01", occurredTo: null, eventKind: "relationship_end" },
|
|
];
|
|
const dossier: DecisionDossier = {
|
|
evidence,
|
|
conversationSummary: { activeFocus: null, declinedSkippedTopics: [] },
|
|
latestResult: {
|
|
resultId: "55555555-5555-4555-8555-555555555555",
|
|
candidates: [
|
|
{ candidateId: "05:00", time: "05:00", rank: 1, relativeSupport: 18 },
|
|
{ candidateId: "05:07", time: "05:07", rank: 2, relativeSupport: 16 },
|
|
],
|
|
representativeTime: "05:00",
|
|
decisionReceipt: {
|
|
contrast_packet: { candidateSetVersion: "05:00-05:07", vargaDifferences: [], probes },
|
|
},
|
|
},
|
|
case: { acceptedTime: null },
|
|
};
|
|
const plan = buildMethodFollowupPlan({
|
|
evidence,
|
|
sessionOutcome: "discriminate_candidates",
|
|
candidatesSeparated: false,
|
|
contrastPacket: { candidateSetVersion: "05:00-05:07", vargaDifferences: [], probes },
|
|
});
|
|
const decision = decideFromDossier(dossier);
|
|
assert.equal(followupAsksRenderableDiscriminator(plan.next_followup), false);
|
|
assert.notEqual(decision.nextAction, "ask_candidate_discriminator");
|
|
assert.equal(decision.probe, null);
|
|
});
|
|
|
|
test("yearless cards cannot keep period-presupposing option copy; oos_blind without a year has no frame", () => {
|
|
const signed = completeAndCheck();
|
|
assert.equal(signed, true);
|
|
assert.equal(shouldAttachChoiceFrame({
|
|
intent: "out_of_sample_check",
|
|
ask_theme: "holdout",
|
|
source: "oos_blind",
|
|
}), false);
|
|
assert.equal(shouldAttachChoiceFrame({
|
|
intent: "out_of_sample_check",
|
|
ask_theme: "holdout",
|
|
source: "oos_blind",
|
|
probe_year: 2023,
|
|
year_label: "2023 年前后",
|
|
}), true);
|
|
const plan = buildMethodFollowupPlan({
|
|
evidence: [
|
|
{ status: "confirmed", domain: "education", datePrecision: "year", occurredFrom: "2016-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "career", datePrecision: "year", occurredFrom: "2020-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "relationship", datePrecision: "year", occurredFrom: "2024-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "family", datePrecision: "year", occurredFrom: "2021-01-01", occurredTo: null },
|
|
{ status: "confirmed", domain: "occupation", datePrecision: "unknown", occurredFrom: null, occurredTo: null, eventKind: "occupation_note" },
|
|
],
|
|
sessionOutcome: "validate_holdout",
|
|
oosBlindPrompts: [{
|
|
domain: "family",
|
|
user_meaning: "校时还没用过家人这条线。有没有一件没提过、但记得大概时间的家人变化?",
|
|
used_for_scoring: false,
|
|
}],
|
|
candidatesSeparated: true,
|
|
});
|
|
assert.ok(plan.next_followup);
|
|
assert.equal(plan.next_followup!.choice_frame, null);
|
|
assert.equal(plan.next_followup!.source, "oos_blind");
|
|
});
|
|
|
|
function completeAndCheck(): boolean {
|
|
const renderable = isRenderableProbe({
|
|
informationGain: 1.2,
|
|
candidateIds: ["05:00", "05:07"],
|
|
expectedOutcomeCount: 2,
|
|
choiceKind: "varga_style",
|
|
year: 0,
|
|
styleOptions: [
|
|
{ sign: "天秤座", label: d9StyleLabel("天秤座"), answer_class: "yes" },
|
|
{ sign: "天蝎座", label: d9StyleLabel("天蝎座"), answer_class: "weak_yes" },
|
|
],
|
|
});
|
|
assert.equal(renderable.ok, true);
|
|
const leaked = isRenderableProbe({
|
|
informationGain: 1.2,
|
|
candidateIds: ["05:00", "05:07"],
|
|
expectedOutcomeCount: 2,
|
|
choiceKind: "existence",
|
|
year: 0,
|
|
});
|
|
assert.equal(leaked.ok, false);
|
|
assert.equal(leaked.ok ? null : leaked.reason, "yearless_ungrounded_contrast");
|
|
return renderable.ok;
|
|
}
|