53eb815c95
Write and read used different range definitions at the same lead of 8, so a real separation always fail-closed the candidate projection. Co-authored-by: Cursor <cursoragent@cursor.com>
220 lines
7.5 KiB
TypeScript
220 lines
7.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
|
|
import { buildInferenceState, type EngineEventInput } from "../src/lib/rectification-agentic/core/build-state.ts";
|
|
import { unionStillValidRange } from "../src/lib/rectification-agentic/core/credible-range.ts";
|
|
import { decideFromDossier } from "../src/lib/rectification-agentic/v9/decision-from-dossier.ts";
|
|
import {
|
|
authoritativeCandidateProjection,
|
|
buildCaseInferenceState,
|
|
} from "../src/lib/rectification-agentic/v9/inference-adapter.ts";
|
|
import { evidenceLedgerFingerprint } from "../src/lib/rectification-agentic/v9/tool-service.ts";
|
|
|
|
const HOLDOUT_EVENTS: readonly EngineEventInput[] = [
|
|
{ id: "e-edu", domain: "education", year: 2016, precision: "year" },
|
|
{ id: "e-career", domain: "career", year: 2018, precision: "year" },
|
|
{ id: "e-rel", domain: "relationship", year: 2021, precision: "year" },
|
|
{ id: "e-fam", domain: "family", year: 2023, precision: "year" },
|
|
];
|
|
|
|
const COVERAGE_EVIDENCE = [
|
|
{
|
|
id: "e-edu",
|
|
status: "confirmed",
|
|
domain: "education",
|
|
datePrecision: "year",
|
|
occurredFrom: "2016-01-01",
|
|
occurredTo: null,
|
|
eventKind: "education_milestone",
|
|
},
|
|
{
|
|
id: "e-career",
|
|
status: "confirmed",
|
|
domain: "career",
|
|
datePrecision: "year",
|
|
occurredFrom: "2018-01-01",
|
|
occurredTo: null,
|
|
eventKind: "career_entry",
|
|
},
|
|
{
|
|
id: "e-rel",
|
|
status: "confirmed",
|
|
domain: "relationship",
|
|
datePrecision: "year",
|
|
occurredFrom: "2021-01-01",
|
|
occurredTo: null,
|
|
eventKind: "relationship_start",
|
|
},
|
|
{
|
|
id: "e-fam",
|
|
status: "confirmed",
|
|
domain: "family",
|
|
datePrecision: "year",
|
|
occurredFrom: "2023-01-01",
|
|
occurredTo: null,
|
|
eventKind: "family_event",
|
|
},
|
|
{
|
|
id: "e-occ",
|
|
status: "confirmed",
|
|
domain: "occupation",
|
|
datePrecision: "unknown",
|
|
occurredFrom: null,
|
|
occurredTo: null,
|
|
eventKind: "occupation_note",
|
|
},
|
|
] as const;
|
|
|
|
function producedSnapshot(
|
|
rows: readonly Readonly<{ time: string; relativeSupport: number }>[],
|
|
events: readonly EngineEventInput[] = [],
|
|
) {
|
|
const times = rows.map((item) => item.time).sort();
|
|
const state = buildInferenceState({
|
|
range_start: times[0]!,
|
|
range_end: times[times.length - 1]!,
|
|
candidates: rows.map((item) => ({
|
|
id: item.time,
|
|
time: item.time,
|
|
relative_support: item.relativeSupport,
|
|
})),
|
|
events,
|
|
probes: [],
|
|
});
|
|
const persisted = state.candidates.map((item) => ({
|
|
candidateId: item.id,
|
|
time: item.time,
|
|
rank: item.rank,
|
|
relativeSupport: Math.round(item.posterior_score),
|
|
}));
|
|
return {
|
|
state,
|
|
latest: {
|
|
resultId: "55555555-5555-4555-8555-555555555555",
|
|
candidates: persisted,
|
|
representativeTime: state.representative_time,
|
|
evidenceLedgerFingerprint: evidenceLedgerFingerprint(COVERAGE_EVIDENCE as never),
|
|
decisionReceipt: { inference_state: state },
|
|
},
|
|
};
|
|
}
|
|
|
|
function dossierFor(latest: ReturnType<typeof producedSnapshot>["latest"]) {
|
|
return {
|
|
evidence: COVERAGE_EVIDENCE,
|
|
conversationSummary: { activeFocus: null, declinedSkippedTopics: [] },
|
|
latestResult: latest,
|
|
case: { acceptedTime: null },
|
|
};
|
|
}
|
|
|
|
test("producer 58/42 lead keeps both candidates and can close without opening the minute gate", () => {
|
|
const { state, latest } = producedSnapshot([
|
|
{ time: "05:02", relativeSupport: 58 },
|
|
{ time: "04:55", relativeSupport: 42 },
|
|
], HOLDOUT_EVENTS);
|
|
assert.deepEqual(state.credible_range, unionStillValidRange(state.candidates));
|
|
assert.notDeepEqual(state.credible_range, ["04:55", "05:02"]);
|
|
|
|
const projection = authoritativeCandidateProjection(latest);
|
|
assert.equal(projection.consistent, true);
|
|
assert.equal(projection.candidates.length, 2);
|
|
assert.deepEqual(projection.credibleRange, state.credible_range);
|
|
|
|
const decision = decideFromDossier(dossierFor(latest));
|
|
assert.equal(decision.separation.sufficient, true);
|
|
assert.equal(decision.nextAction, "ask_holdout_validation");
|
|
assert.equal(decision.canConfirmExactMinute, false);
|
|
assert.notEqual(decision.sessionOutcome, "exact_minute_confirmed");
|
|
});
|
|
|
|
test("producer 58/42 with no holdout is ready_to_adopt, not a unique minute", () => {
|
|
const { latest } = producedSnapshot([
|
|
{ time: "05:02", relativeSupport: 58 },
|
|
{ time: "04:55", relativeSupport: 42 },
|
|
]);
|
|
const decision = decideFromDossier(dossierFor(latest));
|
|
assert.equal(authoritativeCandidateProjection(latest).consistent, true);
|
|
assert.equal(decision.separation.sufficient, true);
|
|
assert.equal(decision.nextAction, "ready_to_adopt");
|
|
assert.equal(decision.canConfirmExactMinute, false);
|
|
assert.notEqual(decision.sessionOutcome, "exact_minute_confirmed");
|
|
});
|
|
|
|
test("producer 50/30/20 lead keeps all three candidates and still-valid range", () => {
|
|
const { state, latest } = producedSnapshot([
|
|
{ time: "05:00", relativeSupport: 50 },
|
|
{ time: "05:20", relativeSupport: 30 },
|
|
{ time: "05:40", relativeSupport: 20 },
|
|
]);
|
|
const projection = authoritativeCandidateProjection(latest);
|
|
assert.equal(projection.consistent, true);
|
|
assert.equal(projection.candidates.length, 3);
|
|
assert.deepEqual(projection.credibleRange, unionStillValidRange(state.candidates));
|
|
assert.deepEqual(projection.credibleRange, state.credible_range);
|
|
});
|
|
|
|
test("producer sole candidate stays consistent", () => {
|
|
const { state, latest } = producedSnapshot([
|
|
{ time: "05:02", relativeSupport: 100 },
|
|
]);
|
|
const projection = authoritativeCandidateProjection(latest);
|
|
assert.equal(projection.consistent, true);
|
|
assert.equal(projection.candidates.length, 1);
|
|
assert.deepEqual(projection.credibleRange, unionStillValidRange(state.candidates));
|
|
});
|
|
|
|
test("missing inference_state still fail-closes to an empty projection", () => {
|
|
const projection = authoritativeCandidateProjection({
|
|
candidates: [
|
|
{ candidateId: "05:02", time: "05:02", relativeSupport: 58 },
|
|
{ candidateId: "04:55", time: "04:55", relativeSupport: 42 },
|
|
],
|
|
decisionReceipt: {},
|
|
});
|
|
assert.equal(projection.consistent, false);
|
|
assert.deepEqual(projection.candidates, []);
|
|
assert.deepEqual(projection.scores, []);
|
|
assert.equal(projection.representativeTime, null);
|
|
assert.equal(projection.credibleRange, null);
|
|
});
|
|
|
|
test("a corrupted receipt range outside the window still fail-closes", () => {
|
|
const { state, latest } = producedSnapshot([
|
|
{ time: "05:02", relativeSupport: 58 },
|
|
{ time: "04:55", relativeSupport: 42 },
|
|
]);
|
|
const broken = {
|
|
...latest,
|
|
decisionReceipt: {
|
|
inference_state: { ...state, credible_range: ["04:00", "04:10"] },
|
|
},
|
|
};
|
|
const projection = authoritativeCandidateProjection(broken);
|
|
assert.equal(projection.consistent, false);
|
|
assert.deepEqual(projection.candidates, []);
|
|
assert.equal(projection.credibleRange, null);
|
|
});
|
|
|
|
test("buildCaseInferenceState receipt is the producer of the projected range", () => {
|
|
const state = buildCaseInferenceState({
|
|
range: { start_time: "04:55", end_time: "05:02" },
|
|
candidates: [
|
|
{ candidateId: "05:02", time: "05:02", relativeSupport: 58 },
|
|
{ candidateId: "04:55", time: "04:55", relativeSupport: 42 },
|
|
],
|
|
evidence: [],
|
|
probes: [],
|
|
});
|
|
const projection = authoritativeCandidateProjection({
|
|
candidates: state.candidates.map((item) => ({
|
|
candidateId: item.id,
|
|
time: item.time,
|
|
relativeSupport: Math.round(item.posterior_score),
|
|
})),
|
|
decisionReceipt: { inference_state: state },
|
|
});
|
|
assert.equal(projection.consistent, true);
|
|
assert.deepEqual(projection.credibleRange, unionStillValidRange(state.candidates));
|
|
});
|