Carry explicit local date intervals instead of inferring the day from clock order. Cluster width, delivery, adoption, and reports keep the actual civil date; adopted date is stored separately from the reported birth_date. Algorithm identity is scoring-9 / spec-v5. Scoring weights, confirmation thresholds, and Skill version are unchanged. Isolated Linux final-3 gates passed; four pre-existing Python failures remain. This is not a production release.
75 lines
5.6 KiB
TypeScript
75 lines
5.6 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { readFileSync } from "node:fs";
|
|
import { clusterEquivalentCandidates } from "../src/lib/rectification-agentic/core/cluster-candidates.ts";
|
|
import { buildInferenceState } from "../src/lib/rectification-agentic/core/build-state.ts";
|
|
import { remainingSplitLayers } from "../src/lib/rectification-agentic/v9/collection-question-pool.ts";
|
|
import { lagnaContrastIntervalLabel, parseLagnaContrast } from "../src/lib/rectification-agentic/v9/refinement-packet.ts";
|
|
|
|
test("native lagna absolute endpoints survive parsing and board formatting", () => {
|
|
const fixture = JSON.parse(readFileSync(new URL("./fixtures/rectification-dated-lagna.native.json", import.meta.url), "utf8"));
|
|
const parsed = parseLagnaContrast(fixture.lagna_contrast)!;
|
|
assert.ok(parsed);
|
|
assert.deepEqual(parsed.intervals.map((row) => [row.start_at, row.end_at, row.segment_index]),
|
|
fixture.lagna_contrast.intervals.map((row: Record<string, unknown>) => [row.start_at, row.end_at, row.segment_index]));
|
|
assert.match(lagnaContrastIntervalLabel(parsed.intervals[0]!), /2000-02-29 23:58.*2000-03-01 00:02/);
|
|
assert.match(parsed.user_meaning, /2000-02-29 23:58/);
|
|
const source = readFileSync(new URL("../src/components/rectification-board.tsx", import.meta.url), "utf8");
|
|
assert.match(source, /\{lagnaContrastIntervalLabel\(interval\)\}/);
|
|
});
|
|
|
|
// Synthetic arithmetic cases, not engine-response goldens.
|
|
const candidate = (time: string, index: number, offset: number, segment: number) => ({
|
|
id: time, time, score: 1, relative_support: 1, candidate_date: time.startsWith("23") ? "2000-06-14" : "2000-06-15",
|
|
window_index: index, window_offset_minutes: offset, segment_index: segment,
|
|
});
|
|
|
|
test("dated equivalent clustering respects segment boundaries and midnight adjacency", () => {
|
|
const disjoint = [candidate("10:00", 0, 0, 0), candidate("10:02", 1, 2, 1)];
|
|
assert.equal(clusterEquivalentCandidates(disjoint).length, 2);
|
|
const midnight = [candidate("23:59", 0, 0, 0), candidate("00:00", 1, 1, 0)];
|
|
assert.deepEqual(clusterEquivalentCandidates(midnight).map((row) => row.member_ids), [["23:59", "00:00"]]);
|
|
assert.equal(clusterEquivalentCandidates(midnight, ["00:00"]).length, 2);
|
|
assert.equal(clusterEquivalentCandidates([candidate("10:00", 0, 0, 0), candidate("10:05", 1, 5, 0)]).length, 2);
|
|
const state = buildInferenceState({ range_start: "10:00", range_end: "10:02", candidates: disjoint, events: [], probes: [] });
|
|
assert.ok(state.candidates.every((row) => row.status === "active"));
|
|
assert.deepEqual(state.candidates.map((row) => row.posterior_score), [1, 1]);
|
|
});
|
|
|
|
test("dated and legacy ordinary same-day equivalent clusters match", () => {
|
|
const dated = [candidate("10:00", 0, 0, 0), candidate("10:01", 1, 1, 0)];
|
|
assert.deepEqual(clusterEquivalentCandidates(dated), clusterEquivalentCandidates(dated.map(({ id, time, score }) => ({ id, time, score }))));
|
|
});
|
|
|
|
const bound = { candidate_date: "2000-06-15", segment_index: 0, segment_start_at: "2000-06-15T10:00", segment_end_at: "2000-06-15T10:10" };
|
|
const transitions = [
|
|
{ ...bound, layer: "d9", at: "10:00", window_index: 0, window_offset_minutes: 0, segment_start: true, from_sign: "白羊", to_sign: "白羊" },
|
|
{ ...bound, layer: "d9", at: "10:10", window_index: 10, window_offset_minutes: 10, from_sign: "白羊", to_sign: "金牛" },
|
|
{ ...bound, layer: "d10", at: "10:00", window_index: 0, window_offset_minutes: 0, segment_start: true, from_sign: "白羊", to_sign: "白羊" },
|
|
{ ...bound, layer: "d10", at: "10:01", window_index: 1, window_offset_minutes: 1, from_sign: "白羊", to_sign: "金牛" },
|
|
];
|
|
|
|
test("active subset excludes eliminated D9 split without resurrecting full-window flags", () => {
|
|
assert.deepEqual(remainingSplitLayers({ transitions, activeTimes: ["10:00", "10:01"], scanFlags: { d9_candidates_differ: true } }), ["d10"]);
|
|
assert.deepEqual(remainingSplitLayers({ transitions, activeTimes: ["10:02", "10:03"], scanFlags: { d9_candidates_differ: true, d10_candidates_differ: true } }), []);
|
|
assert.deepEqual(remainingSplitLayers({ transitions: transitions.filter((row) => !("segment_start" in row && row.segment_start)).map(({ layer, at }) => ({ layer, at })), activeTimes: ["10:00", "10:01"] }), ["d10"]);
|
|
});
|
|
|
|
test("separate segment starts only justify collection when surviving signs differ", () => {
|
|
const starts = [transitions[0]!, { ...transitions[0]!, at: "12:00", segment_start_at: "2000-06-15T12:00",
|
|
segment_end_at: "2000-06-15T12:01", segment_index: 1, window_index: 11, window_offset_minutes: 120 }];
|
|
assert.deepEqual(remainingSplitLayers({ transitions: starts, activeTimes: ["10:00", "12:00"] }), []);
|
|
assert.deepEqual(remainingSplitLayers({ transitions: [starts[0]!, { ...starts[1]!, from_sign: "金牛", to_sign: "金牛" }], activeTimes: ["10:00", "12:00"] }), ["d9"]);
|
|
});
|
|
|
|
test("dated lagna parser keeps absolute endpoints and rejects partial or impossible dates", () => {
|
|
const interval = { start: "23:59", end: "00:00", lagna: "白羊", lords: {}, start_at: "2000-06-14T23:59", end_at: "2000-06-15T00:00", segment_index: 0 };
|
|
const second = { ...interval, start: "00:01", end: "00:02", start_at: "2000-06-15T00:01", end_at: "2000-06-15T00:02" };
|
|
const parsed = parseLagnaContrast({ intervals: [interval, second] });
|
|
assert.equal((parsed?.intervals[0] as unknown as Record<string, unknown>)?.start_at, interval.start_at);
|
|
assert.match(parsed!.user_meaning, /2000-06-14 23:59/);
|
|
for (const patch of [{ start_at: "2000-02-30T23:59" }, { end_at: undefined }, { segment_index: -1 }, { start_at: "2000-06-14T23:58" }]) {
|
|
assert.equal(parseLagnaContrast({ intervals: [{ ...interval, ...patch }, second] }), null);
|
|
}
|
|
});
|