a0ce55f066
Showing a choice card is no longer treated as completion. Distinguish probes require real candidate groups, holdout stays out of scoring, and ordinary sessions can finish with a credible range instead of an exact-minute gate. Co-authored-by: Cursor <cursoragent@cursor.com>
85 lines
3.2 KiB
TypeScript
85 lines
3.2 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
buildCandidateContrastPacket,
|
|
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.equal(probe.styleOptions?.length, 3);
|
|
assert.equal(probe.expectedOutcomes.length, 3);
|
|
assert.deepEqual(probe.expectedOutcomes.map((row) => row.supportsCandidateIds), [
|
|
["05:00"],
|
|
["05:03"],
|
|
["05:04"],
|
|
]);
|
|
});
|
|
|
|
test("two-way remaining D9 maps C to unsure, not the other minute group", () => {
|
|
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, 2);
|
|
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.equal(probe.expectedOutcomes.some((row) => row.outcomeId === "no"), false);
|
|
});
|
|
|
|
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");
|
|
});
|