Files
Jyotisha/frontend/tests/consult-projection-timing-20260927.test.ts
T
Jesse_ChenandClaude Opus 5.5 75a1844cdf fix(consult): project the running Narayana period and pratyantar dates to the model (BUG-1054)
timingKeys now admits current_dasha.md/ad/pd (sign, lord, years,
start_age, end_age), remaining_years and pratyantar_dasha_timeline. Depth
and item caps unchanged. Golden regression over three public AA engine
captures asserts values, not key presence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-27 02:54:11 +08:00

88 lines
4.0 KiB
TypeScript

// BUG-1054: the model-visible timing projection dropped the running Narayana
// period (`current_dasha.md/ad/pd`) and the Vimshottari pratyantar window
// (`pratyantar_dasha_timeline`), although the engine computed both.
//
// The fixture is a real engine capture (AGENTS §7.4) of three public AA charts:
// scripts/research/capture_consult_evidence_card_golden.py. Expected values are
// read straight from the engine payload, and the assertion is on values, not on
// the key being present.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import {
consultationWorkflowResponseSchema,
toAgentConsultationContext,
toModelOutput,
} from "../src/mastra/consultation-workflow.ts";
type Json = Record<string, unknown>;
const golden = JSON.parse(readFileSync(
new URL("./fixtures/consult-evidence-card-golden.json", import.meta.url),
"utf8",
)) as { charts: Array<{ id: string; workflow: Json }> };
function dig(value: unknown, ...keys: string[]): unknown {
let current = value;
for (const key of keys) {
if (!current || typeof current !== "object" || Array.isArray(current)) return undefined;
current = (current as Json)[key];
}
return current;
}
function timingCard(workflow: Json) {
const parsed = consultationWorkflowResponseSchema.parse(structuredClone(workflow));
const packet = toModelOutput(toAgentConsultationContext(parsed));
const card = packet.claim_cards.find((item) => item.category === "timing");
assert.ok(card, "the timing claim card is present");
return card.evidence as Json;
}
test("the fixture carries the engine values the projection used to drop", () => {
assert.equal(golden.charts.length, 3);
for (const chart of golden.charts) {
const modules = dig(chart.workflow, "chart", "modules");
assert.equal(typeof dig(modules, "narayana_dasha", "current_dasha", "md", "sign"), "string", chart.id);
assert.match(String(dig(modules, "dasha_sub_periods", "pratyantar_dasha_timeline", "current", "start")), /^\d{4}-\d{2}-\d{2}$/, chart.id);
}
});
test("the running Narayana period reaches the model timing card with the engine's own values", () => {
for (const chart of golden.charts) {
const engine = dig(chart.workflow, "chart", "modules", "narayana_dasha", "current_dasha") as Json;
const projected = dig(timingCard(chart.workflow), "narayana_dasha", "current_dasha") as Json;
assert.ok(projected && Object.keys(projected).length > 0, `${chart.id}: current_dasha is no longer empty`);
for (const level of ["md", "ad", "pd"] as const) {
for (const key of ["sign", "lord", "years", "start_age", "end_age"] as const) {
assert.equal(dig(projected, level, key), dig(engine, level, key), `${chart.id} ${level}.${key}`);
}
}
assert.equal(projected.remaining_years, engine.remaining_years, `${chart.id} remaining_years`);
}
});
test("the Vimshottari pratyantar window reaches the model timing card with the engine's own dates", () => {
for (const chart of golden.charts) {
const engine = dig(chart.workflow, "chart", "modules", "dasha_sub_periods", "pratyantar_dasha_timeline") as Json;
const projected = dig(timingCard(chart.workflow), "dasha_sub_periods", "pratyantar_dasha_timeline") as Json;
for (const phase of ["current", "next"] as const) {
for (const key of ["lord", "start", "end"] as const) {
assert.equal(dig(projected, phase, key), dig(engine, phase, key), `${chart.id} pratyantar ${phase}.${key}`);
}
}
}
});
test("the mahadasha and antardasha dates the projection already carried are unchanged", () => {
for (const chart of golden.charts) {
const engine = dig(chart.workflow, "chart", "modules", "dasha_sub_periods", "current") as Json;
const projected = dig(timingCard(chart.workflow), "dasha_sub_periods", "current") as Json;
for (const level of ["mahadasha", "antardasha"] as const) {
for (const key of ["lord", "start", "end"] as const) {
assert.equal(dig(projected, level, key), dig(engine, level, key), `${chart.id} ${level}.${key}`);
}
}
}
});