Files
Jyotisha/frontend/tests/conversational-convergence.test.ts
T
2026-07-25 11:50:41 +08:00

110 lines
3.6 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
convergenceNotes,
nextPlateauCount,
shouldCompleteBoundedResult,
} from "../src/lib/conversational-rectification/convergence.ts";
import type { RectificationTechnicalPacket } from "../src/lib/conversational-rectification/technical-packet.ts";
const pendingPacket = {
candidate: { status: "pending_validation" },
suggestedDomains: [
{ domain: "relationship", layer: "D9", reason: "relationship evidence" },
{ domain: "finance", layer: "D11", reason: "finance evidence" },
],
} as unknown as RectificationTechnicalPacket;
test("an unchanged range only advances background plateau state", () => {
const candidate = {
rangeStart: "04:30",
rangeEnd: "06:30",
workingState: { notes: ["range_plateau_count:50", "keep-me"] },
};
const packet = {
...pendingPacket,
candidate: {
...pendingPacket.candidate,
range: { startTime: "04:30", endTime: "06:30" },
},
} as RectificationTechnicalPacket;
const plateauCount = nextPlateauCount(candidate, packet);
assert.equal(plateauCount, 51);
assert.deepEqual(convergenceNotes(candidate, plateauCount), ["keep-me", "range_plateau_count:51"]);
});
test("a changed range resets background plateau state without completing the session", () => {
const candidate = {
rangeStart: "04:30",
rangeEnd: "06:30",
workingState: { notes: ["range_plateau_count:8"] },
};
const packet = {
...pendingPacket,
candidate: {
...pendingPacket.candidate,
range: { startTime: "05:10", endTime: "05:40" },
},
} as RectificationTechnicalPacket;
assert.equal(nextPlateauCount(candidate, packet), 0);
});
test("a covered 4-event 3-domain plateau completes as a bounded result", () => {
assert.equal(shouldCompleteBoundedResult({
packet: pendingPacket,
scoreableEventCount: 4,
scoreableDomainCount: 3,
answeredDomains: new Set(["relationship", "finance", "career"]),
plateauCount: 2,
}), true);
});
test("an unanswered discriminating domain keeps the conversation active", () => {
assert.equal(shouldCompleteBoundedResult({
packet: pendingPacket,
scoreableEventCount: 4,
scoreableDomainCount: 3,
answeredDomains: new Set(["relationship", "career", "education"]),
plateauCount: 2,
}), false);
});
test("system-only blockers complete a covered range without waiting for another plateau", () => {
const packet = {
...pendingPacket,
suggestedDomains: [],
expertWorkflow: { hardBlockers: ["required_layers_incomplete", "minute_holdout_not_ready"] },
} as unknown as RectificationTechnicalPacket;
assert.equal(shouldCompleteBoundedResult({
packet,
scoreableEventCount: 4,
scoreableDomainCount: 3,
answeredDomains: new Set(["relationship", "career", "education"]),
plateauCount: 0,
}), true);
});
test("user-resolvable blockers do not complete a bounded result", () => {
const packet = {
...pendingPacket,
suggestedDomains: [],
expertWorkflow: { hardBlockers: ["insufficient_events"] },
} as unknown as RectificationTechnicalPacket;
assert.equal(shouldCompleteBoundedResult({
packet,
scoreableEventCount: 4,
scoreableDomainCount: 3,
answeredDomains: new Set(["relationship", "career", "education"]),
plateauCount: 2,
}), true, "the completed evidence plateau, not a stale blocker, is decisive");
assert.equal(shouldCompleteBoundedResult({
packet,
scoreableEventCount: 4,
scoreableDomainCount: 3,
answeredDomains: new Set(["relationship", "career", "education"]),
plateauCount: 1,
}), false);
});