Files
Jyotisha/frontend/tests/consultation-context.test.ts
T
Jesse_Chen 8010245981
Independent Staging Quality Gate / validate (push) Failing after 6m42s
Independent Staging Quality Gate / publish (push) Has been skipped
feat(product): present consult and rectification in local skill form
Default ayanamsa to Raman with true_pushya support, attach governed Raman packets, restore Path C questionnaires and eight-method verification copy, and keep unique-minute confirmation blocked.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 21:42:47 +08:00

263 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import { createConsultationPlan } from "../src/lib/consultation-plan.ts";
import { toAgentConsultationContext, toModelOutput } from "../src/mastra/consultation-workflow.ts";
test("passes transparent public-case references into the agent context", () => {
const workflowSource = readFileSync(new URL("../src/mastra/consultation-workflow.ts", import.meta.url), "utf8");
const agentSource = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8");
assert.match(workflowSource, /reference_transparency:\s*record\(data\.reference_transparency\)/);
assert.match(workflowSource, /vedastro_gateway:\s*record\(data\.vedastro_gateway\)/);
assert.match(workflowSource, /ashtakavarga:\s*chart\.ashtakavarga/);
assert.match(agentSource, /high_similarity_public_references_available/);
assert.match(agentSource, /requested_uncovered_domains/);
assert.match(agentSource, /public_context_only/);
assert.match(agentSource, /timing_state/);
assert.match(agentSource, /partial_match/);
assert.match(agentSource, /narayana_status/);
assert.match(agentSource, /transit_status/);
assert.match(agentSource, /Jupiter and Saturn relative houses/);
assert.match(agentSource, /exact_triggers as technical trigger points/);
assert.match(agentSource, /production_tuning_allowed=false/);
assert.match(agentSource, /no_majority_vote/);
assert.match(agentSource, /method_variant_not_majority_vote/);
assert.match(agentSource, /Shadbala\/Ashtakavarga component differences/);
assert.match(agentSource, /D2, D11/);
assert.match(agentSource, /gender-specific spouse significators are supplements/);
assert.match(agentSource, /male.*Venus/);
assert.match(agentSource, /female.*Jupiter\/Mars/);
});
test("keeps strength, Ashtakavarga, and timing evidence available to the answer model", () => {
const workflowSource = readFileSync(new URL("../src/mastra/consultation-workflow.ts", import.meta.url), "utf8");
const agentSource = readFileSync(new URL("../src/mastra/index.ts", import.meta.url), "utf8");
assert.match(workflowSource, /shadbala: chart\.shadbala/);
assert.match(workflowSource, /shadbala_boundary:/);
assert.match(workflowSource, /ashtakavarga: modules\.ashtakavarga/);
// This line used to pin the misspelling: it asserted the packet read
// `modules.dasha_boundaries` without anything checking that the engine writes
// that key. tests/test_consultation_consumer_context.py now compares the names
// across the boundary; this only pins that timing evidence is still passed.
assert.match(workflowSource, /dasha_sub_periods: modules\.dasha_sub_periods/);
assert.match(workflowSource, /varga_spectrum: modules\.varga_spectrum/);
assert.match(workflowSource, /technique_audit_table: consumerContext\.technique_audit_table/);
assert.match(agentSource, /evidence_contract\.technique_audit_table/);
assert.match(workflowSource, /evidence_contract:/);
assert.match(workflowSource, /missing_route_layers: consumerContext\.missing_route_layers/);
assert.match(workflowSource, /answer_policy: consumerContext\.answer_policy/);
assert.match(agentSource, /evidence_contract\.answer_policy/);
assert.match(agentSource, /can_answer_precise_timing/);
assert.match(workflowSource, /boundary: "not_auto_rectified"/);
assert.match(agentSource, /rectification\.boundary=not_auto_rectified/);
assert.match(workflowSource, /external_engine_evidence:/);
assert.match(workflowSource, /runtime_truth: record\(data\.runtime_truth\)/);
assert.match(workflowSource, /numerical_parity: record\(data\.external_parity_gate\)/);
assert.match(workflowSource, /real_case_calibration: record\(data\.real_case_calibration\)/);
});
test("projects only bounded server-selected evidence to the model", () => {
const context = toAgentConsultationContext({
success: true,
question: "事业如何",
chart: {
birth: { date: "1990-01-02", time: "03:04", latitude: 25.03, longitude: 121.56 },
ascendant: { sign: "Leo", degree: 12.5, reported_time: "private-reported-time" },
planets: [{ name: "Sun", sign: "Capricorn", degree: 4.2, lng: "private-lng" }],
houses: { first: { sign: "Leo" } },
dasha: { current: "Mars", next: "Rahu", utc_offset: "private-utc-offset" },
shadbala: { planets: { Sun: { total_rupa: 7.1 } } },
ashtakavarga: { house_scores: { "10": 31 } },
modules: {
shadbala: { total: 412 },
ashtakavarga: { total: 28 },
varga_spectrum: {
status: "used",
mode: "full_spectrum",
counts: { formal: 20, research_dn: 40, extended: 3, blocked: 0 },
formal: { D9: { lagna: "Leo", planets: { Sun: "Capricorn" }, name: "Navamsa" } },
research_dn: { D13: { lagna: "Aries", planets: { Moon: "Taurus" }, boundary: "generic D-N; not a formal named varga" } },
},
dasha_sub_periods: {
current: { antardasha: { lord: "Saturn", start: "2025-10-17", end: "2027-05-18" } },
boundary_count: 9,
utc_offset: "private-module-utc-offset",
},
narayana_dasha: { current: "Aries" },
functional_benefic_malefic: {
status: "used",
functional_benefics: ["Jupiter"],
functional_malefics: ["Mercury"],
},
kakshya: { status: "observation_only", boundary: "not verified day/month timing" },
yogas: { status: "executed", count: 1, yogas: [{ name: "Gaja Kesari", planets: ["Jupiter", "Moon"] }] },
arudha_padas: {
padas: {
A10: { name: "Karma Pada (A10)", sign: "Capricorn" },
UL: { name: "Upapada (UL)", sign: "Libra" },
},
},
gulika: { sign: "Scorpio", claim_boundary: "observation_only" },
kp_cusps: { houses: { "10": { sign: "Taurus", sublord: "Saturn" } } },
chara_dasha: {
status: "executed",
current: { sign: "Libra", lord: "Venus", duration_years: 8 },
sequence: [{ sign: "Libra", lord: "Venus", duration_years: 8 }],
},
transits: {
status: "executed",
sade_sati: { phase: "none", moon_sign: "Taurus", saturn_sign: "Pisces" },
search_period: { start: "2026-07-14", end: "2026-10-12" },
triggers: [{ date: "2026-08-21", planet: "Saturn", target: "Moon", kind: "exact_hit", orb: 0.08 }],
boundary: "observation windows, not guaranteed events",
},
},
},
routing: { primary_theme: "career" },
thematic_report: {
themes: {
career: {
theme: "career",
summary: "保留这条服务端证据摘要",
narrative: "事业证据叙事",
strength: "strong",
account_balance: "private-account-balance",
recommendations: ["保持稳健推进"],
evidence: [{
technique: "D10-Dashamsha-local",
chart: "D10",
conclusion: "D10 事业分盘已进入证据链",
sentiment: "positive",
strength: "strong",
details: {
source: "chart",
derived: true,
entitlements: "private-entitlements",
access_scopes: "private-access-scopes",
},
}],
},
},
},
consumer_context: {
route: "career", core_status: "ready", available_layers: ["natal", "timing"],
missing_route_layers: [], hard_blockers: [],
technique_truth: { status: "verified", access_scopes: "private-validation-scopes" },
answer_policy: {
can_answer_direction: true,
can_answer_precise_timing: false,
entitlements: "private-policy-entitlements",
},
user_facing_limitation: "精确月份暂不可用",
technique_audit_table: [
{ technique: "Formal Vargas D1D60", status: "executed", system: "jyotish", boundary: "20/20 named traditional charts" },
{ technique: "Yogas", status: "executed", system: "jyotish" },
{ technique: "Arudha / UL / A10", status: "executed", system: "jyotish" },
{ technique: "Narayana Dasha", status: "executed", system: "jyotish" },
{ technique: "Functional Benefic/Malefic", status: "executed", key_functional_benefics: ["Jupiter"] },
{ technique: "Western natal (tropical)", status: "executed", system: "western" },
{ technique: "VedAstro Cloud State", status: "executed", boundary: "official_cloud_evidence_available" },
{ technique: "MEVG / Global Web Evidence", status: "blocked", boundary: "caps_claims_until_global_web_evidence_runs" },
],
varga_spectrum: {
status: "used",
counts: { formal: 20, research_dn: 40 },
formal: { D9: { lagna: "Leo", planets: { Sun: "Capricorn" } } },
},
western_spectrum: {
status: "executed",
natal: { sun: "Aries", moon: "Taurus", ascendant: "Leo" },
techniques: {
transits: {
status: "executed",
target_date: "2026-07-14",
aspects: [{ transit_planet: "saturn", natal_point: "moon", aspect: "square", orb: 0.4 }],
},
},
},
vedastro_cross_check: {
status: "executed",
official_closure_state: "official_verified",
natal: { sun: "Leo", moon: "Cancer", ascendant: "Scorpio" },
},
},
reference_transparency: { similar_public_cases: { status: "public_context_only" } },
rectification: { summary: "none" },
vedastro_gateway: {
official_closure_state: "official_verified",
official_raw_response: { lat: 25.03, lon: 121.56, hour: 3, minute: 4 },
},
});
const output = toModelOutput(context);
const careerPlan = createConsultationPlan({ userIntent: "事业如何", theme: "career" });
const careerOutput = toModelOutput(context, careerPlan);
const serialized = JSON.stringify(output);
assert.equal(output.packet_version, "consultation-evidence-packet-v2");
assert.equal("birth" in output, false);
assert.equal(serialized.includes("1990-01-02"), false);
assert.equal(serialized.includes("03:04"), false);
assert.equal(serialized.includes("25.03"), false);
assert.equal(serialized.includes("121.56"), false);
for (const privateValue of [
"private-reported-time", "private-lng", "private-utc-offset", "private-module-utc-offset",
"private-account-balance", "private-entitlements", "private-access-scopes",
"private-validation-scopes", "private-policy-entitlements",
]) {
assert.equal(serialized.includes(privateValue), false);
}
for (const privateKey of [
"reported_time", "lng", "utc_offset", "account_balance", "entitlements", "access_scopes",
]) {
assert.equal(serialized.includes(`"${privateKey}"`), false);
}
assert.equal(serialized.includes("保留这条服务端证据摘要"), true);
assert.equal(serialized.includes("D10-Dashamsha-local"), true);
assert.equal(serialized.includes("total_rupa"), true);
assert.equal(serialized.includes("house_scores"), true);
assert.equal(serialized.includes('"dasha"'), true);
assert.equal(serialized.includes("narayana_dasha"), true);
// Antardasha boundaries are what an answer needs to name a month at all, and
// they were absent from every packet while this field named a module key the
// engine never wrote.
assert.equal(serialized.includes("dasha_sub_periods"), true);
assert.equal(serialized.includes("2027-05-18"), true);
assert.equal(serialized.includes('"status":"verified"'), true);
const answerPolicy = output.evidence_contract.answer_policy as Record<string, unknown>;
assert.equal(answerPolicy.can_answer_precise_timing, false);
assert.deepEqual(output.claim_cards.map((card) => card.category), ["natal_foundation", "domain", "timing", "validation"]);
assert.deepEqual(careerOutput.claim_cards.map((card) => card.category), ["natal_foundation", "domain", "timing", "validation"]);
assert.equal(JSON.stringify(careerOutput).includes('"dasha"'), true);
assert.equal(serialized.includes("consultation-evidence-packet-v2"), true);
assert.equal(output.presentation.template, "skill_level_2");
assert.equal(output.presentation.required_blocks.includes("technique_audit_table"), true);
assert.equal(serialized.includes("Formal Vargas"), true);
assert.equal(serialized.includes("varga_spectrum"), true);
assert.equal(serialized.includes('"D13"'), true);
assert.equal(serialized.includes("western_spectrum"), true);
assert.equal(serialized.includes("technique_audit_table"), true);
assert.equal(serialized.includes("functional_benefics"), true);
assert.equal(serialized.includes("Jupiter"), true);
assert.equal(serialized.includes("Gaja Kesari"), true);
assert.equal(serialized.includes("Karma Pada (A10)"), true);
assert.equal(serialized.includes("chara_dasha"), true);
assert.equal(serialized.includes("Venus"), true);
assert.equal(serialized.includes("sade_sati"), true);
assert.equal(serialized.includes("Taurus"), true);
assert.equal(serialized.includes("2026-08-21"), true);
assert.equal(serialized.includes("search_period"), true);
assert.equal(serialized.includes('"square"'), true);
const mustUse = output.evidence_contract.must_use_layers;
assert.equal(Array.isArray(mustUse), true);
assert.equal((mustUse as string[]).includes("Yogas"), true);
assert.equal((mustUse as string[]).includes("Arudha / UL / A10"), true);
assert.equal((mustUse as string[]).includes("VedAstro Cloud State"), true);
assert.equal((mustUse as string[]).includes("MEVG / Global Web Evidence"), false);
assert.equal(serialized.includes("Scorpio"), true);
assert.equal(serialized.includes("official_verified"), true);
assert.equal(serialized.includes("https://"), false);
});