Files
Jyotisha/frontend/tests/rectification-candidate-contrast-packet.test.ts
T
Jesse_Chen 0eb740a6b8
Independent Staging Quality Gate / validate (push) Successful in 10m33s
Independent Staging Quality Gate / publish (push) Successful in 16m24s
fix(rectification): keep holdout, D9 probes, and asked keys on the decision boundary
Reserve a month-or-better holdout, degrade unsigned D9/D10 to existence, and treat ledger keywords as mention-only so remaining discriminators stay in the pool.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 18:04:34 +08:00

170 lines
7.0 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
buildCandidateContrastPacket,
mentionedVargaKeysFromLedgerEvidence,
remainingVargaSplits,
selectDiscriminatorProbe,
volunteeredDomainsFromEvidence,
} from "../src/lib/rectification-agentic/core/candidate-contrast-packet.ts";
test("remaining D10 three-way outranks a skewed D24 split", () => {
const packet = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:04",
candidateTimes: ["05:00", "05:03", "05:04"],
transitions: [
{ layer: "d10", at: "05:03", from_sign: "巨蟹座", to_sign: "狮子座" },
{ layer: "d10", at: "05:04", from_sign: "狮子座", to_sign: "处女座" },
{ layer: "d24", at: "05:04", from_sign: "白羊座", to_sign: "金牛座" },
],
});
const probe = selectDiscriminatorProbe(packet);
assert.ok(probe);
assert.equal(probe.domain, "career");
assert.equal(probe.choiceKind, "varga_style");
assert.match(probe.semanticKey, /varga\.d10/);
assert.doesNotMatch(probe.semanticKey, /varga\.d24/);
assert.ok(packet.probes.some((item) => item.semanticKey.startsWith("varga.d24.")));
assert.ok(packet.probes.some((item) => item.semanticKey.startsWith("varga.d10.")));
assert.equal(probe.styleOptions?.length, 4);
assert.equal(probe.expectedOutcomes.length, 4);
assert.deepEqual(probe.expectedOutcomes.filter((row) => row.outcomeId !== "unsure").map((row) => row.supportsCandidateIds), [
["05:00"],
["05:03"],
["05:04"],
]);
});
test("two-way remaining D9 keeps the other minute on weak_yes, not no", () => {
const packet = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:04",
candidateTimes: ["05:00", "05:04"],
transitions: [
{ layer: "d9", at: "05:04", from_sign: "巨蟹座", to_sign: "狮子座" },
],
});
const probe = selectDiscriminatorProbe(packet);
assert.ok(probe);
assert.equal(probe.choiceKind, "varga_style");
assert.equal(probe.styleOptions?.length, 4);
assert.deepEqual(probe.expectedOutcomes.find((row) => row.outcomeId === "yes")?.supportsCandidateIds, ["05:00"]);
assert.deepEqual(probe.expectedOutcomes.find((row) => row.outcomeId === "weak_yes")?.supportsCandidateIds, ["05:04"]);
assert.deepEqual(probe.expectedOutcomes.find((row) => row.outcomeId === "no")?.supportsCandidateIds, []);
assert.equal(probe.styleOptions?.some((item) => item.answerClass === "unsure"), true);
assert.doesNotMatch(probe.question, /不得发明年份|Opportunity/);
assert.match(probe.authoringHint ?? "", /不得发明年份/);
assert.match(probe.question, /相处|关系/);
});
test("remaining D7 enters the pool as family existence", () => {
const splits = remainingVargaSplits(
["05:00", "05:04"],
[{ layer: "d7", at: "05:04", from_sign: "金牛座", to_sign: "双子座" }],
);
assert.equal(splits[0]?.layer, "d7");
const packet = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:04",
candidateTimes: ["05:00", "05:04"],
remainingSplits: splits,
});
const probe = selectDiscriminatorProbe(packet);
assert.equal(probe?.domain, "family");
assert.equal(probe?.choiceKind, "existence");
assert.ok((probe?.informationGain ?? 0) > 0);
assert.equal((probe?.expectedOutcomes.length ?? 0) >= 2, true);
assert.match(probe?.candidateSplitHash ?? "", /05:00-05:04/);
});
test("finance remaining splits stay out unless volunteered", () => {
const hidden = remainingVargaSplits(
["05:00", "05:04"],
[{ layer: "d2", at: "05:04" }],
);
assert.equal(hidden.length, 0);
const shown = remainingVargaSplits(
["05:00", "05:04"],
[{ layer: "d2", at: "05:04" }],
volunteeredDomainsFromEvidence([{ status: "confirmed", domain: "finance" }]),
);
assert.equal(shown[0]?.layer, "d2");
});
test("existence probes leave the catalog once that domain already has dated evidence", () => {
const packet = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:14",
engineProbes: [{
semantic_key: "career.2023.dasha_activation",
domain: "career",
year: 2023,
user_meaning: "时间范围锁定 2023 年前后。",
information_gain: 0.56,
expected_outcomes: [
{ answer_class: "yes", supports: ["05:00"], conflicts: ["05:14"] },
{ answer_class: "no", supports: ["05:14"], conflicts: ["05:00"] },
],
}],
providedDomains: ["career"],
candidateTimes: ["05:00", "05:07", "05:14"],
transitions: [
{ layer: "d24", at: "05:07", from_sign: "白羊座", to_sign: "金牛座" },
{ layer: "d24", at: "05:14", from_sign: "金牛座", to_sign: "双子座" },
],
});
assert.equal(packet.probes.some((item) => item.semanticKey.includes("career.2023")), false);
assert.match(selectDiscriminatorProbe(packet)?.semanticKey ?? "", /^varga\.d24\./);
});
test("D9 remaining split without signs degrades to existence instead of dropping", () => {
const packet = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:04",
candidateTimes: ["05:00", "05:04"],
transitions: [{ layer: "d9", at: "05:04" }],
});
const probe = selectDiscriminatorProbe(packet);
assert.ok(probe);
assert.equal(probe.choiceKind, "existence");
assert.match(probe.semanticKey, /^varga\.d9\./);
assert.equal(probe.styleOptions?.length, 4);
assert.doesNotMatch(probe.question, /不得发明年份|Opportunity/);
assert.ok(probe.question.trim().length >= 8);
assert.deepEqual(probe.expectedOutcomes.find((row) => row.outcomeId === "yes")?.supportsCandidateIds, ["05:00"]);
assert.deepEqual(probe.expectedOutcomes.find((row) => row.outcomeId === "weak_yes")?.supportsCandidateIds, ["05:00"]);
assert.deepEqual(probe.expectedOutcomes.find((row) => row.outcomeId === "no")?.supportsCandidateIds, ["05:04"]);
});
test("occupation mention does not skip remaining D10; answered varga.d10 still does", () => {
const evidence = [{
status: "confirmed",
domain: "occupation",
eventKind: "occupation_note",
summary: "互联网程序员 / 前端",
}];
const mentioned = mentionedVargaKeysFromLedgerEvidence(evidence);
assert.ok(mentioned.includes("varga.d10"));
const transitions = [
{ layer: "d10", at: "05:03", from_sign: "巨蟹座", to_sign: "狮子座" },
{ layer: "d10", at: "05:04", from_sign: "狮子座", to_sign: "处女座" },
{ layer: "d4", at: "05:04", from_sign: "金牛座", to_sign: "双子座" },
];
const times = ["05:00", "05:03", "05:04"];
const mentionedPacket = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:04",
candidateTimes: times,
transitions,
mentionedKeys: mentioned,
});
assert.ok(mentionedPacket.probes.some((item) => item.semanticKey.startsWith("varga.d10.")));
assert.match(
selectDiscriminatorProbe(mentionedPacket, { mentionedKeys: mentioned })?.semanticKey ?? "",
/^varga\.d4\./,
);
const answeredPacket = buildCandidateContrastPacket({
candidateSetVersion: "05:00-05:04",
candidateTimes: times,
transitions,
askedKeys: ["varga.d10"],
});
assert.equal(answeredPacket.probes.some((item) => item.semanticKey.startsWith("varga.d10.")), false);
});