diff --git a/PROGRESS-report-blocked-repairs-20260902.md b/PROGRESS-report-blocked-repairs-20260902.md new file mode 100644 index 00000000..c87a34bb --- /dev/null +++ b/PROGRESS-report-blocked-repairs-20260902.md @@ -0,0 +1,97 @@ +# PROGRESS · 个人报告全主题 blocked 修复(2026-09-02) + +任务书:`TASK-report-blocked-repairs-20260902.md` +分支:`codex/report-blocked-repairs-20260902` +基线:`origin/staging` @ `e37f8272`(任务书提交;内容基线 `24a1cf37`) + +开工前置:已读 `docs/research/pre_work_error_ledger.md`、`frontend/AGENTS.md`;`docs/BUG_HISTORY.md` 检索 BUG-486 及相邻条目;`python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45` 为 `status=pass`(`remote_visibility_status=verified`)。按任务书从 `origin/staging` 建 worktree。 + +--- + +## 任务 0 · Golden fixture 与形状契约 + +捕获命令(虚构 smoke 出生,非真人): + +```bash +.venv/bin/python scripts/capture_report_blocked_repairs_golden.py +``` + +脚本调用 `JyotishAPIHandler._compute_consultation_workflow`,body 对齐 worker:`entry_mode=direct_chart`,question `请为个人报告计算 主题证据`,`plan_version=consultation-plan-v2`,并设 `defer_optional_external_evidence=true` 以跳过 VedAstro(本轮修的是本地 varga / transits / jaimini 层)。主题:career / marriage / timing / wealth。出生:1993-06-15 10:30,lat 36.42 / lon 114.21 / tz 8,city Handan。 + +裁剪规则: + +- 保留 `chart.ascendant/planets/houses/dasha` +- `modules.varga_full` 只留 `D2_Hora` / `D9_Navamsa` / `D10_Dasamsa` / `D11_Rudramsa` / `D24_Chaturvimsamsa` 的完整值(引擎 D24 名是 Chaturvimsamsa,不是任务书举例的 Siddhamsa) +- 保留 `modules.transits`、`modules.jaimini`(含新增 `chara_karakas`)、`narayana_dasha`、`arudha_padas`、`yogas`、`ashtakavarga`、`dasha_sub_periods` +- 保留 `consumer_context` 的 route/core_status/available_layers/missing_route_layers/hard_blockers/answer_policy +- 保留 machine packet 中与主题闭合相关的 sections +- 删除 `ai_prompt_pack`、VedAstro、varga_spectrum、guided_topics、western、technique_audit_table,并压缩行星/宫位/dasha 字段 + +入库:`frontend/tests/fixtures/consultation-workflow-report-blocked-repairs-golden.json`(约 154KB)。入库前检索无邮箱、用户 id、真实姓名。 + +形状契约:`frontend/tests/report-blocked-repairs.test.ts` 直接读 golden,断言小写 `ascendant`、`sign_index`、`planets` 字典、`house_chart`,以及 `modules.transits.status`、`chara_karakas.AmK/DK`。该测试不依赖前端提取行为。 + +红线 9:`report-interpretive-facts.test.ts` 的 `engineVarga()` 原值是 `{ _meta, Ascendant: {sign, sign_idx, degree_in_sign}, Sun/Moon/Mars: {sign, sign_idx} }`(643f6f7a 手造旧形状,锁住了本轮要修的缺陷)。已换成 golden 派生的 D2/D11/D24 真值;断言语义未放宽。 + +--- + +## 任务 1 · 分盘值形状 + +`deriveVargaHousesFromEngine` 现读 `ascendant ?? Ascendant`,索引 `sign_index ?? sign_idx ?? sign`,度数 `degree ?? degree_in_sign`。优先 `varga.planets`(有 `house` 用 house,否则整星座宫推导);无 `planets` 时退回顶层行星键。不复制 `house_chart` 与未知键。`VARGA_KEY_ALIASES.D24` 补上真实键 `D24_Chaturvimsamsa`。 + +复现管线(golden 四主题):`charts` 含 D1/D2/D9/D10/D11/D24;wealth 出 claim card;`demoteThemesMissingRequiredCharts` 不触发;D2/D11 回执 executed。 + +--- + +## 任务 2 · Transit 回执 + +提取层读 `chart.modules.transits`:仅 `status === "executed"` 时 upsert `Transit`(`partial` + `executed: true`)。缺失或其他 status 不产回执。 + +单元覆盖:executed / 缺失 / `blocked` 三态。timing 在 executed 时出 claim card。 + +--- + +## 任务 3 · Chara Karaka + +引擎 `_attach_local_consultation_layers` 调用既有 `jaimini.calc_chara_karaka_7`,把结果挂到 `chart.modules.jaimini.chara_karakas`。键同时保留全名(`Amatyakaraka`/`Darakaraka`)与任务书建议的短名(`AmK`/`DK`)。不改 `arudha_padas`。 + +前端按 AmK/DK 行星存在性 upsert 回执。Python:`test_local_consultation_layers_attach_chara_karakas_from_jaimini`。 + +四主题复现:**claimCards 4,blockedSections 0**;ledger 中 AmK/DK/Transit/D2/D11 均 executed。 + +--- + +## 九主题逐项(golden career 图层复用到未单独捕获的主题) + +| 主题 | 结果 | +|---|---| +| career | claim | +| marriage | claim | +| wealth | claim | +| education | claim | +| migration_home | claim | +| family | claim | +| health_pressure | claim | +| timing | claim | +| general | claim | + +--- + +## 任务 4 · 质量门(本地) + +| 门 | 结果 | +|---|---| +| `frontend/node_modules/.bin/tsc --noEmit` | 通过(exit 0) | +| eslint(改动的 generation / 两个测试文件) | 0 error | +| `tsx --test` personal-report-generation + generation-v2 + contract + interpretive-facts + report-blocked-repairs | 64 passed / 0 failed(另 generation 单文件 55/55) | +| `pytest tests/test_consultation_consumer_context.py` | 28 passed | +| `next build` | 未跑(本机质量门已覆盖类型与合同;完整构建留给 staging 推送) | +| staging 真实报告重生 + 上一轮 writer/token 欠账 | 未做,需部署后由委托方核对 `/api/health` 的 `.deployment.gitCommit` | + +未改 `.gitea/workflows/**`,未提升 main。 + +--- + +## 开工回执后的实现顺序 + +先落引擎 `chara_karakas` 再捕获 golden(使 fixture 含新层),再修提取层与测试。形状契约只读 JSON,不依赖提取实现。 diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 4426a279..2433fe03 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -7485,7 +7485,7 @@ - 修复:把文档允许的分盘键归一成 D2/D9/D10/D11/D24(含 `D2_Hora` 等别名),占据星体走 celestial allowlist。write 主题若缺少对应结构化分盘,降成 blocked disclosure,不再组装成会解析失败的文档。终态 parse 失败时把缺分盘与 hash 失配从笼统的 `final_parse_rejected` 分出来;日志仍只写 allowlist token,不含用户或模型原文。不放宽 `.strict()` 文档 schema,也不改 assertionLevel 规则。 - 验证:`frontend/tests/personal-report-generation.test.ts` 用 `D2_Hora` / `D11_Rudramsa` 抽出 D2/D11 且财富章成为 claim;`frontend/tests/personal-report-generation-v2.test.ts` 财富 write 只有 D1 时 ready 且财富进 blocked;`frontend/tests/personal-report-contract.test.ts` 财富主题缺 D2/D11 仍拒绝。Gitea run 2298 在 `report-interpretive-facts.test.ts` 6 fail:夹具只有 D2/D11/D24 回执、没有 `varga_full`,降级后 wealth/education 卡被拿掉。补上结构化 D2/D11/D24 后该文件本地绿,并锁「仅回执则 demote」。未用登录会话在 staging 重生。 - 防复发:文档分盘 id 必须从引擎 `varga_full` 别名归一,不得只认 `D2` 这种短键。财富/事业/婚恋/教育 write 主题缺对应结构化分盘时必须降级 blocked,不得把 `final_parse_rejected` 当正常完成。新增分盘别名必须同时覆盖提取与文档 `CHART_IDS`。改 `REQUIRED_THEME_CHARTS` 或 demote 后必须跑 `frontend/tests/report-interpretive-facts.test.ts`;期望 write 主题 claim card 的夹具必须带对应结构化分盘,不能只标 machine section used。 -- 相关记录:BUG-352、BUG-451、BUG-467 +- 相关记录:BUG-352、BUG-451、BUG-467、BUG-489 - 复发自:无 - 修复版本:待发布 @@ -7520,3 +7520,19 @@ - 相关记录:BUG-471、BUG-485、BUG-487 - 复发自:BUG-487(服务端拼接后槽位兜底仍可见) - 修复版本:待发布 + +## BUG-489 | 个人报告四主题全部 blocked:分盘值形状、Transit 回执与 Chara Karaka 层缺失 + +- 状态:resolved +- 首次发现:2026-09-02 +- 最近更新:2026-09-02 +- 影响面:`deriveVargaHousesFromEngine`、`buildReportEvidenceBundleV2`、`_attach_local_consultation_layers`、personal_full `career/marriage/timing/wealth` +- 用户现象:staging 真实 personal_full 报告四个请求主题全部 blocked,摘要退化为「报告主题尚未生成」。blocked 理由分别为缺 AmK+Transit、缺 DK、缺 Transit、缺结构化 D2/D11。 +- 触发条件:个人报告按主题调用 `/api/consultation_workflow`,提取层组 `ReportEvidenceBundleV2`。与出生数据或线上环境无关,本地 smoke 出生可逐字复现。 +- 根因:三层叠加。`modules.varga_full` 真值是小写 `ascendant` / `sign_index` / `planets` 字典,提取层只读旧形状 `Ascendant` / `sign_idx` / 顶层行星键,所有分盘图提取失败;`modules.transits.status=executed` 存在但从不 upsert Transit 回执;consultation 响应的 `modules.jaimini` 只有 `arudha_padas`,没有 Chara Karaka,AmK/DK 回执无法闭合。BUG-486 的 `45f190a1` / `643f6f7a` 只修了键名别名、demote 兜底和手造旧形状 fixture,测试绿、线上仍挂。 +- 修复:提取层双形状兼容真实 varga;`transits.status==="executed"` 时 upsert Transit(`partial`+executed,缺或非 executed 不产回执);引擎把 `jaimini.calc_chara_karaka_7` 挂到 `chart.modules.jaimini.chara_karakas`(不改 `arudha_padas`),前端按 AmK/DK 存在性 upsert 回执。不放宽主题最低证据组,不改既有字段形状。 +- 验证:golden fixture 形状契约;`frontend/tests/report-blocked-repairs.test.ts` 锁双形状、Transit 三态、AmK/DK、四主题 claimCards 4 / blocked 0、九主题全 claim;`tests/test_consultation_consumer_context.py::test_local_consultation_layers_attach_chara_karakas_from_jaimini`;既有 personal-report generation / interpretive / contract / v2 回归绿。未做登录后的 staging 重生(部署后验收)。 +- 防复发:分盘 fixture 必须来自真实引擎响应,不得再手造 `Ascendant/sign_idx` 形状当 live 契约。Transit / AmK / DK 回执必须来自模块数据存在性,不得用 `available_layers` 名目冒充已执行。新增 `chara_karakas` 不得改写既有 `arudha_padas`。改提取形状后必须跑 `report-blocked-repairs` 与 `report-interpretive-facts`。 +- 相关记录:BUG-486、BUG-467、BUG-352 +- 复发自:BUG-486(键名别名与 demote 治标,值形状与缺失层未修) +- 修复版本:待发布 diff --git a/frontend/src/lib/personal-report-generation.ts b/frontend/src/lib/personal-report-generation.ts index b50ccc31..7b2b852a 100644 --- a/frontend/src/lib/personal-report-generation.ts +++ b/frontend/src/lib/personal-report-generation.ts @@ -316,7 +316,7 @@ const VARGA_KEY_ALIASES: Readonly= 1 && declared <= 12) { + return declared; + } + const planetIndex = signIndex(row.sign_index ?? row.sign_idx ?? row.sign); + if (planetIndex === null) return null; + return (((planetIndex - ascIndex) % 12) + 12) % 12 + 1; +} + +function collectVargaOccupants( + entries: Iterable, + ascIndex: number, +): string[][] { + const occupants: string[][] = Array.from({ length: 12 }, () => []); + for (const [name, item] of entries) { + const row = record(item); + if (!row) continue; + const house = vargaPlanetHouse(row, ascIndex); + if (house === null) continue; + const safeName = safeCelestialName(name); + if (safeName) occupants[house - 1].push(safeName); + } + return occupants; +} + /** - * Divisional charts in the real engine live under modules.varga_full with keys - * such as D2_Hora / D9_Navamsa / D10_Dasamsa / D11_Rudramsa (or D2 / D9 / D10 / - * D11). Each varga is {Ascendant: {sign_idx|sign}, : {sign_idx|sign}, - * _meta, _dignity, ...} — there are no house arrays. House signs are derived - * whole-sign from the divisional ascendant and occupants from each planet's - * sign index. Missing or non-document vargas are omitted; occupant names go - * through the celestial allowlist. + * Divisional charts live under modules.varga_full with keys such as D2_Hora / + * D9_Navamsa / D10_Dasamsa / D11_Rudramsa (or D2 / D9 / D10 / D11). + * + * The live engine shape is {ascendant: {sign, sign_index, degree}, planets: + * {Sun: {sign, sign_index, house, degree}, ...}, house_chart, division, name, + * meaning}. An older fixture shape used {Ascendant: {sign_idx|sign}, : + * {sign_idx|sign}, _meta, ...}. Both are accepted. House signs are whole-sign + * from the divisional ascendant. Occupants come from planets.house when + * present, otherwise from sign index. house_chart and unknown keys are not + * copied. Occupant names go through the celestial allowlist. */ function deriveVargaHousesFromEngine( varga: JsonRecord, @@ -340,22 +379,23 @@ function deriveVargaHousesFromEngine( degree: number; houses: ReportEvidencePacket["chart"]["houses"]; }> | null { - const ascendant = record(varga.Ascendant); - const ascIndex = ascendant ? signIndex(ascendant.sign_idx ?? ascendant.sign) : null; + const ascendant = record(varga.ascendant) ?? record(varga.Ascendant); + const ascIndex = ascendant + ? signIndex(ascendant.sign_index ?? ascendant.sign_idx ?? ascendant.sign) + : null; if (ascIndex === null) return null; - const occupants: string[][] = Array.from({ length: 12 }, () => []); - for (const [name, item] of Object.entries(varga)) { - if (name.startsWith("_") || name === "Ascendant" || name === "planets") continue; - const row = record(item); - const planetIndex = row ? signIndex(row.sign_idx ?? row.sign) : null; - if (planetIndex === null) continue; - const house = (((planetIndex - ascIndex) % 12) + 12) % 12 + 1; - const safeName = safeCelestialName(name); - if (safeName) occupants[house - 1].push(safeName); - } + const planets = record(varga.planets); + const occupants = planets + ? collectVargaOccupants(Object.entries(planets), ascIndex) + : collectVargaOccupants( + Object.entries(varga).filter(([name]) => ( + !name.startsWith("_") && !VARGA_ENGINE_META_KEYS.has(name) + )), + ascIndex, + ); return { ascIndex, - degree: finiteNumber(ascendant?.degree_in_sign ?? ascendant?.degree) ?? 0, + degree: finiteNumber(ascendant?.degree ?? ascendant?.degree_in_sign) ?? 0, houses: Array.from({ length: 12 }, (_, index) => ({ number: index + 1, sign: SIGNS[((ascIndex + index) % 12 + 12) % 12], @@ -1130,6 +1170,17 @@ function readChartModules(workflow: JsonRecord): JsonRecord { return record(record(workflow.chart)?.modules) ?? {}; } +function charaKarakaPlanetPresent( + karakas: JsonRecord | null, + keys: readonly string[], +): boolean { + if (!karakas) return false; + return keys.some((key) => { + const planet = text(record(karakas[key])?.planet); + return Boolean(planet && safeCelestialName(planet)); + }); +} + /** * Functional benefic/malefic table. `yogakarakas` wins over the benefic and * malefic lists so a planet is never reported twice. @@ -1621,6 +1672,20 @@ export function buildReportEvidenceBundleV2( } } + for (const { workflow } of packets) { + const modules = readChartModules(workflow); + if (text(record(modules.transits)?.status)?.toLowerCase() === "executed") { + upsertReceipt("Transit", "partial", true); + } + const karakas = record(record(modules.jaimini)?.chara_karakas); + if (charaKarakaPlanetPresent(karakas, ["AmK", "Amatyakaraka"])) { + upsertReceipt("AmK", "partial", true); + } + if (charaKarakaPlanetPresent(karakas, ["DK", "Darakaraka"])) { + upsertReceipt("DK", "partial", true); + } + } + // --- interpretive facts ------------------------------------------------- // Bound to receipts that already exist in the ledger; a layer without a // receipt is skipped rather than given a synthetic ref. diff --git a/frontend/tests/fixtures/consultation-workflow-report-blocked-repairs-golden.json b/frontend/tests/fixtures/consultation-workflow-report-blocked-repairs-golden.json new file mode 100644 index 00000000..f9bbc84b --- /dev/null +++ b/frontend/tests/fixtures/consultation-workflow-report-blocked-repairs-golden.json @@ -0,0 +1,5330 @@ +{ + "source": "scripts/jyotish_api_server.py _compute_consultation_workflow", + "smoke_birth": { + "year": 1993, + "month": 6, + "day": 15, + "hour": 10, + "minute": 30, + "lat": 36.42, + "lon": 114.21, + "tz": 8, + "city": "Handan", + "note": "fictional capture identity; not a real person" + }, + "trim": { + "keep_varga_keys": [ + "D2_Hora", + "D2", + "D9_Navamsa", + "D9", + "D10_Dasamsa", + "D10", + "D11_Rudramsa", + "D11", + "D24_Chaturvimsamsa", + "D24_Siddhamsa", + "D24" + ], + "keep_modules": [ + "varga_full", + "transits", + "jaimini", + "narayana_dasha", + "arudha_padas", + "yogas", + "ashtakavarga", + "dasha_sub_periods" + ], + "drop": [ + "ai_prompt_pack", + "vedastro", + "varga_spectrum", + "guided_topics", + "western_spectrum", + "technique_audit_table" + ] + }, + "themes": { + "career": { + "success": true, + "chart": { + "success": true, + "ascendant": { + "degree": 9.0, + "degree_in_sign": 9.0, + "lon": 129.003, + "sign": "Leo", + "sign_idx": 4 + }, + "planets": { + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "lon": 162.7310389205016, + "degree": 12.731, + "degree_in_sign": 12.731, + "house": 2, + "retrograde": false + }, + "Ketu": { + "sign": "Taurus", + "sign_idx": 1, + "lon": 49.363055820241016, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 10, + "retrograde": true + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "lon": 122.9900397721899, + "degree": 2.99, + "degree_in_sign": 2.99, + "house": 1, + "retrograde": false + }, + "Mercury": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 86.18527092954923, + "degree": 26.1853, + "degree_in_sign": 26.1853, + "house": 11, + "retrograde": false + }, + "Moon": { + "sign": "Aries", + "sign_idx": 0, + "lon": 3.2259370143924713, + "degree": 3.2259, + "degree_in_sign": 3.2259, + "house": 9, + "retrograde": false + }, + "Rahu": { + "sign": "Scorpio", + "sign_idx": 7, + "lon": 229.36305582024104, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 4, + "retrograde": true + }, + "Saturn": { + "sign": "Aquarius", + "sign_idx": 10, + "lon": 307.9889038425868, + "degree": 7.9889, + "degree_in_sign": 7.9889, + "house": 7, + "retrograde": true + }, + "Sun": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 61.69229619774846, + "degree": 1.6923, + "degree_in_sign": 1.6923, + "house": 11, + "retrograde": false + }, + "Venus": { + "sign": "Aries", + "sign_idx": 0, + "lon": 16.003783878640178, + "degree": 16.0038, + "degree_in_sign": 16.0038, + "house": 9, + "retrograde": false + } + }, + "houses": { + "1": { + "sign": "Leo", + "sign_idx": 4 + }, + "10": { + "sign": "Taurus", + "sign_idx": 1 + }, + "11": { + "sign": "Gemini", + "sign_idx": 2 + }, + "12": { + "sign": "Cancer", + "sign_idx": 3 + }, + "2": { + "sign": "Virgo", + "sign_idx": 5 + }, + "3": { + "sign": "Libra", + "sign_idx": 6 + }, + "4": { + "sign": "Scorpio", + "sign_idx": 7 + }, + "5": { + "sign": "Sagittarius", + "sign_idx": 8 + }, + "6": { + "sign": "Capricorn", + "sign_idx": 9 + }, + "7": { + "sign": "Aquarius", + "sign_idx": 10 + }, + "8": { + "sign": "Pisces", + "sign_idx": 11 + }, + "9": { + "sign": "Aries", + "sign_idx": 0 + } + }, + "dasha": { + "periods": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "mahadashas": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "current_md": "Ketu", + "start_date": "1991-10-05" + }, + "modules": { + "varga_full": { + "D2_Hora": { + "division": 2, + "name": "Hora", + "meaning": "财富", + "ascendant": { + "sign": "Leo", + "sign_index": 4, + "degree": 18.006, + "absolute_degree": 138.006 + }, + "planets": { + "Sun": { + "sign": "Leo", + "sign_index": 4, + "degree": 3.3846, + "house": 1, + "absolute_degree": 123.3846 + }, + "Moon": { + "sign": "Leo", + "sign_index": 4, + "degree": 6.4519, + "house": 1, + "absolute_degree": 126.4519 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 5.9801, + "house": 1, + "absolute_degree": 125.9801 + }, + "Mercury": { + "sign": "Cancer", + "sign_index": 3, + "degree": 22.3705, + "house": 12, + "absolute_degree": 112.3705 + }, + "Jupiter": { + "sign": "Cancer", + "sign_index": 3, + "degree": 25.4621, + "house": 12, + "absolute_degree": 115.4621 + }, + "Venus": { + "sign": "Cancer", + "sign_index": 3, + "degree": 2.0076, + "house": 12, + "absolute_degree": 92.0076 + }, + "Saturn": { + "sign": "Leo", + "sign_index": 4, + "degree": 15.9778, + "house": 1, + "absolute_degree": 135.9778 + }, + "Rahu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + } + }, + "house_chart": [ + [ + "Sun", + "Moon", + "Mars", + "Saturn", + "Rahu", + "Ketu" + ], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [ + "Mercury", + "Jupiter", + "Venus" + ] + ] + }, + "D9_Navamsa": { + "division": 9, + "name": "Navamsa", + "meaning": "配偶/灵性", + "ascendant": { + "sign": "Gemini", + "sign_index": 2, + "degree": 21.027, + "absolute_degree": 81.027 + }, + "planets": { + "Sun": { + "sign": "Libra", + "sign_index": 6, + "degree": 15.2307, + "house": 5, + "absolute_degree": 195.2307 + }, + "Moon": { + "sign": "Aries", + "sign_index": 0, + "degree": 29.0334, + "house": 11, + "absolute_degree": 29.0334 + }, + "Mars": { + "sign": "Aries", + "sign_index": 0, + "degree": 26.9104, + "house": 11, + "absolute_degree": 26.9104 + }, + "Mercury": { + "sign": "Taurus", + "sign_index": 1, + "degree": 25.6674, + "house": 12, + "absolute_degree": 55.6674 + }, + "Jupiter": { + "sign": "Aries", + "sign_index": 0, + "degree": 24.5794, + "house": 11, + "absolute_degree": 24.5794 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0341, + "house": 3, + "absolute_degree": 144.0341 + }, + "Saturn": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 11.9001, + "house": 7, + "absolute_degree": 251.9001 + }, + "Rahu": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 24.2675, + "house": 7, + "absolute_degree": 264.2675 + }, + "Ketu": { + "sign": "Gemini", + "sign_index": 2, + "degree": 24.2675, + "house": 1, + "absolute_degree": 84.2675 + } + }, + "house_chart": [ + [ + "Ketu" + ], + [], + [ + "Venus" + ], + [], + [ + "Sun" + ], + [], + [ + "Saturn", + "Rahu" + ], + [], + [], + [], + [ + "Moon", + "Mars", + "Jupiter" + ], + [ + "Mercury" + ] + ] + }, + "D10_Dasamsa": { + "division": 10, + "name": "Dasamsa", + "meaning": "事业", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 0.03, + "absolute_degree": 210.03 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 16.923, + "house": 8, + "absolute_degree": 76.923 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 2.2594, + "house": 7, + "absolute_degree": 32.2594 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 29.9004, + "house": 10, + "absolute_degree": 149.9004 + }, + "Mercury": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 21.8527, + "house": 4, + "absolute_degree": 321.8527 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 7.3104, + "house": 11, + "absolute_degree": 157.3104 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.0378, + "house": 11, + "absolute_degree": 160.0378 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 19.889, + "house": 6, + "absolute_degree": 19.889 + }, + "Rahu": { + "sign": "Capricorn", + "sign_index": 9, + "degree": 13.6306, + "house": 3, + "absolute_degree": 283.6306 + }, + "Ketu": { + "sign": "Cancer", + "sign_index": 3, + "degree": 13.6306, + "house": 9, + "absolute_degree": 103.6306 + } + }, + "house_chart": [ + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [ + "Ketu" + ], + [ + "Mars" + ], + [ + "Jupiter", + "Venus" + ], + [] + ] + }, + "D11_Rudramsa": { + "division": 11, + "name": "Rudramsa", + "meaning": "破坏/转化", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 9.033, + "absolute_degree": 219.033 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 18.6153, + "house": 8, + "absolute_degree": 78.6153 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.4853, + "house": 7, + "absolute_degree": 35.4853 + }, + "Mars": { + "sign": "Virgo", + "sign_index": 5, + "degree": 2.8904, + "house": 11, + "absolute_degree": 152.8904 + }, + "Mercury": { + "sign": "Pisces", + "sign_index": 11, + "degree": 18.038, + "house": 5, + "absolute_degree": 348.038 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 20.0414, + "house": 11, + "absolute_degree": 170.0414 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 26.0416, + "house": 11, + "absolute_degree": 176.0416 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 27.8779, + "house": 6, + "absolute_degree": 27.8779 + }, + "Rahu": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 2.9936, + "house": 4, + "absolute_degree": 302.9936 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 2.9936, + "house": 10, + "absolute_degree": 122.9936 + } + }, + "house_chart": [ + [], + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [], + [ + "Ketu" + ], + [ + "Mars", + "Jupiter", + "Venus" + ], + [] + ] + }, + "D24_Chaturvimsamsa": { + "division": 24, + "name": "Chaturvimsamsa", + "meaning": "教育/学习", + "ascendant": { + "sign": "Pisces", + "sign_index": 11, + "degree": 6.072, + "absolute_degree": 336.072 + }, + "planets": { + "Sun": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.6151, + "house": 7, + "absolute_degree": 160.6151 + }, + "Moon": { + "sign": "Libra", + "sign_index": 6, + "degree": 17.4225, + "house": 8, + "absolute_degree": 197.4225 + }, + "Mars": { + "sign": "Libra", + "sign_index": 6, + "degree": 11.761, + "house": 8, + "absolute_degree": 191.761 + }, + "Mercury": { + "sign": "Aries", + "sign_index": 0, + "degree": 28.4465, + "house": 2, + "absolute_degree": 28.4465 + }, + "Jupiter": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.5449, + "house": 3, + "absolute_degree": 35.5449 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0908, + "house": 6, + "absolute_degree": 144.0908 + }, + "Saturn": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 11.7337, + "house": 12, + "absolute_degree": 311.7337 + }, + "Rahu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + }, + "Ketu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + } + }, + "house_chart": [ + [], + [ + "Mercury" + ], + [ + "Jupiter" + ], + [], + [], + [ + "Venus" + ], + [ + "Sun" + ], + [ + "Moon", + "Mars", + "Rahu", + "Ketu" + ], + [], + [], + [], + [ + "Saturn" + ] + ] + } + }, + "transits": { + "status": "executed", + "sade_sati": { + "active": true, + "phase": "rising", + "phase_name": "上升期(Rising Phase)", + "moon_sign": "Aries", + "saturn_sign": "Pisces", + "intensity": "中等" + }, + "search_period": { + "start": "2026-09-02", + "end": "2026-12-01" + }, + "trigger_count": 0, + "boundary": "observation windows, not guaranteed events; empty triggers means none in the searched window, not that transits were skipped" + }, + "jaimini": { + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "chara_karakas": { + "Atmakaraka": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "AK": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "Amatyakaraka": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "AmK": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "Bhratrikaraka": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "BK": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "Matrikaraka": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "MK": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "Putrakaraka": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "PK": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "Gnatikaraka": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "GK": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "Darakaraka": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + }, + "DK": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + } + } + }, + "narayana_dasha": { + "current_dasha": { + "md": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "years": 9, + "start_age": 25.0, + "end_age": 34.0 + }, + "ad": { + "sign": "Virgo", + "sign_idx": 5, + "lord": "Mercury", + "years": 0.8265, + "start_age": 32.6224, + "end_age": 33.449 + }, + "pd": { + "sign": "Gemini", + "sign_idx": 2, + "lord": "Mercury", + "years": 0.1012, + "start_age": 33.1875, + "end_age": 33.2887 + }, + "remaining_years": 0.78 + }, + "lagna_sign": "Leo", + "mahadasha_sequence": [ + { + "lord": "Sun", + "sign": "Leo", + "start_age": 0.0, + "end_age": 10.0, + "years": 10 + }, + { + "lord": "Mercury", + "sign": "Virgo", + "start_age": 10.0, + "end_age": 19.0, + "years": 9 + }, + { + "lord": "Venus", + "sign": "Libra", + "start_age": 19.0, + "end_age": 25.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Scorpio", + "start_age": 25.0, + "end_age": 34.0, + "years": 9 + }, + { + "lord": "Jupiter", + "sign": "Sagittarius", + "start_age": 34.0, + "end_age": 43.0, + "years": 9 + }, + { + "lord": "Saturn", + "sign": "Capricorn", + "start_age": 43.0, + "end_age": 44.0, + "years": 1 + }, + { + "lord": "Saturn", + "sign": "Aquarius", + "start_age": 44.0, + "end_age": 56.0, + "years": 12 + }, + { + "lord": "Jupiter", + "sign": "Pisces", + "start_age": 56.0, + "end_age": 62.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Aries", + "start_age": 62.0, + "end_age": 66.0, + "years": 4 + }, + { + "lord": "Venus", + "sign": "Taurus", + "start_age": 66.0, + "end_age": 77.0, + "years": 11 + }, + { + "lord": "Mercury", + "sign": "Gemini", + "start_age": 77.0, + "end_age": 89.0, + "years": 12 + }, + { + "lord": "Moon", + "sign": "Cancer", + "start_age": 89.0, + "end_age": 98.0, + "years": 9 + } + ] + }, + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "yogas": { + "status": "executed", + "count": 6, + "yogas": [ + { + "name": "Sunaphaa Yoga", + "hit": false + }, + { + "name": "Anaphaa Yoga", + "hit": false + }, + { + "name": "Duradhara Yoga", + "hit": false + }, + { + "name": "Vosi Yoga", + "hit": false + }, + { + "name": "Ubhayachara Yoga", + "hit": false + }, + { + "name": "Naukaa Yoga", + "hit": false + } + ] + }, + "ashtakavarga": { + "sav": { + "scores": { + "Aries": 31, + "Taurus": 29, + "Gemini": 36, + "Cancer": 22, + "Leo": 29, + "Virgo": 28, + "Libra": 26, + "Scorpio": 29, + "Sagittarius": 24, + "Capricorn": 26, + "Aquarius": 33, + "Pisces": 24 + }, + "total": 337 + } + }, + "dasha_sub_periods": { + "current": { + "mahadasha": { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + "antardasha": { + "lord": "Rahu", + "start": "2026-03-05", + "end": "2027-09-04" + } + } + } + } + }, + "consumer_context": { + "route": "career", + "core_status": "ready", + "available_layers": [ + "A10", + "A7", + "D1", + "D10", + "D11", + "D12", + "D16", + "D2", + "D20", + "D24", + "D27", + "D3", + "D30", + "D4", + "D40", + "D45", + "D5", + "D6", + "D60", + "D7", + "D8", + "D9", + "KP_cusp", + "UL", + "ashtakavarga", + "dasha_boundaries", + "dasha_sub_periods", + "functional_benefic_malefic", + "house_degrees", + "narayana_dasha", + "planet_degrees", + "shadbala", + "varga_spectrum", + "yogas" + ], + "missing_route_layers": [], + "hard_blockers": [], + "answer_policy": { + "can_answer_direction": true, + "can_answer_chart_interpretation": true, + "can_answer_precise_timing": true, + "precise_timing_requested": false, + "should_lead_with_limitations": false, + "provider_unavailable_is_fatal": false + } + }, + "machine_evidence_packet": { + "sections": { + "D1": { + "status": "used", + "source_path": "chart.planets+chart.ascendant" + }, + "D9": { + "status": "used", + "source_path": "modules.varga_full.D9" + }, + "D10": { + "status": "used", + "source_path": "modules.varga_full.D10" + }, + "D2": { + "status": "used", + "source_path": "modules.varga_full.D2" + }, + "D4": { + "status": "used", + "source_path": "modules.varga_full.D4" + }, + "planet_degrees": { + "status": "used", + "source_path": "chart.planets" + }, + "house_degrees": { + "status": "used", + "source_path": "chart.houses" + }, + "dasha_boundaries": { + "status": "used", + "source_path": "modules.dasha" + }, + "dasha_sub_periods": { + "status": "used", + "source_path": "modules.dasha_sub_periods" + }, + "narayana_dasha": { + "status": "used", + "source_path": "modules.narayana_dasha" + }, + "ashtakavarga": { + "status": "used", + "source_path": "modules.ashtakavarga" + }, + "yogas": { + "status": "used", + "source_path": "modules.yogas" + }, + "UL": { + "status": "used", + "source_path": "modules.arudha_padas.UL" + }, + "A7": { + "status": "used", + "source_path": "modules.arudha_padas.A7" + }, + "A10": { + "status": "used", + "source_path": "modules.arudha_padas.A10" + }, + "D6": { + "status": "used", + "source_path": "modules.varga_full.D6" + }, + "D7": { + "status": "used", + "source_path": "modules.varga_full.D7" + }, + "D11": { + "status": "used", + "source_path": "modules.varga_full.D11" + }, + "D12": { + "status": "used", + "source_path": "modules.varga_full.D12" + }, + "D24": { + "status": "used", + "source_path": "modules.varga_full.D24" + }, + "D30": { + "status": "used", + "source_path": "modules.varga_full.D30" + } + } + } + }, + "marriage": { + "success": true, + "chart": { + "success": true, + "ascendant": { + "degree": 9.0, + "degree_in_sign": 9.0, + "lon": 129.003, + "sign": "Leo", + "sign_idx": 4 + }, + "planets": { + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "lon": 162.7310389205016, + "degree": 12.731, + "degree_in_sign": 12.731, + "house": 2, + "retrograde": false + }, + "Ketu": { + "sign": "Taurus", + "sign_idx": 1, + "lon": 49.363055820241016, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 10, + "retrograde": true + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "lon": 122.9900397721899, + "degree": 2.99, + "degree_in_sign": 2.99, + "house": 1, + "retrograde": false + }, + "Mercury": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 86.18527092954923, + "degree": 26.1853, + "degree_in_sign": 26.1853, + "house": 11, + "retrograde": false + }, + "Moon": { + "sign": "Aries", + "sign_idx": 0, + "lon": 3.2259370143924713, + "degree": 3.2259, + "degree_in_sign": 3.2259, + "house": 9, + "retrograde": false + }, + "Rahu": { + "sign": "Scorpio", + "sign_idx": 7, + "lon": 229.36305582024104, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 4, + "retrograde": true + }, + "Saturn": { + "sign": "Aquarius", + "sign_idx": 10, + "lon": 307.9889038425868, + "degree": 7.9889, + "degree_in_sign": 7.9889, + "house": 7, + "retrograde": true + }, + "Sun": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 61.69229619774846, + "degree": 1.6923, + "degree_in_sign": 1.6923, + "house": 11, + "retrograde": false + }, + "Venus": { + "sign": "Aries", + "sign_idx": 0, + "lon": 16.003783878640178, + "degree": 16.0038, + "degree_in_sign": 16.0038, + "house": 9, + "retrograde": false + } + }, + "houses": { + "1": { + "sign": "Leo", + "sign_idx": 4 + }, + "10": { + "sign": "Taurus", + "sign_idx": 1 + }, + "11": { + "sign": "Gemini", + "sign_idx": 2 + }, + "12": { + "sign": "Cancer", + "sign_idx": 3 + }, + "2": { + "sign": "Virgo", + "sign_idx": 5 + }, + "3": { + "sign": "Libra", + "sign_idx": 6 + }, + "4": { + "sign": "Scorpio", + "sign_idx": 7 + }, + "5": { + "sign": "Sagittarius", + "sign_idx": 8 + }, + "6": { + "sign": "Capricorn", + "sign_idx": 9 + }, + "7": { + "sign": "Aquarius", + "sign_idx": 10 + }, + "8": { + "sign": "Pisces", + "sign_idx": 11 + }, + "9": { + "sign": "Aries", + "sign_idx": 0 + } + }, + "dasha": { + "periods": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "mahadashas": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "current_md": "Ketu", + "start_date": "1991-10-05" + }, + "modules": { + "varga_full": { + "D2_Hora": { + "division": 2, + "name": "Hora", + "meaning": "财富", + "ascendant": { + "sign": "Leo", + "sign_index": 4, + "degree": 18.006, + "absolute_degree": 138.006 + }, + "planets": { + "Sun": { + "sign": "Leo", + "sign_index": 4, + "degree": 3.3846, + "house": 1, + "absolute_degree": 123.3846 + }, + "Moon": { + "sign": "Leo", + "sign_index": 4, + "degree": 6.4519, + "house": 1, + "absolute_degree": 126.4519 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 5.9801, + "house": 1, + "absolute_degree": 125.9801 + }, + "Mercury": { + "sign": "Cancer", + "sign_index": 3, + "degree": 22.3705, + "house": 12, + "absolute_degree": 112.3705 + }, + "Jupiter": { + "sign": "Cancer", + "sign_index": 3, + "degree": 25.4621, + "house": 12, + "absolute_degree": 115.4621 + }, + "Venus": { + "sign": "Cancer", + "sign_index": 3, + "degree": 2.0076, + "house": 12, + "absolute_degree": 92.0076 + }, + "Saturn": { + "sign": "Leo", + "sign_index": 4, + "degree": 15.9778, + "house": 1, + "absolute_degree": 135.9778 + }, + "Rahu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + } + }, + "house_chart": [ + [ + "Sun", + "Moon", + "Mars", + "Saturn", + "Rahu", + "Ketu" + ], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [ + "Mercury", + "Jupiter", + "Venus" + ] + ] + }, + "D9_Navamsa": { + "division": 9, + "name": "Navamsa", + "meaning": "配偶/灵性", + "ascendant": { + "sign": "Gemini", + "sign_index": 2, + "degree": 21.027, + "absolute_degree": 81.027 + }, + "planets": { + "Sun": { + "sign": "Libra", + "sign_index": 6, + "degree": 15.2307, + "house": 5, + "absolute_degree": 195.2307 + }, + "Moon": { + "sign": "Aries", + "sign_index": 0, + "degree": 29.0334, + "house": 11, + "absolute_degree": 29.0334 + }, + "Mars": { + "sign": "Aries", + "sign_index": 0, + "degree": 26.9104, + "house": 11, + "absolute_degree": 26.9104 + }, + "Mercury": { + "sign": "Taurus", + "sign_index": 1, + "degree": 25.6674, + "house": 12, + "absolute_degree": 55.6674 + }, + "Jupiter": { + "sign": "Aries", + "sign_index": 0, + "degree": 24.5794, + "house": 11, + "absolute_degree": 24.5794 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0341, + "house": 3, + "absolute_degree": 144.0341 + }, + "Saturn": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 11.9001, + "house": 7, + "absolute_degree": 251.9001 + }, + "Rahu": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 24.2675, + "house": 7, + "absolute_degree": 264.2675 + }, + "Ketu": { + "sign": "Gemini", + "sign_index": 2, + "degree": 24.2675, + "house": 1, + "absolute_degree": 84.2675 + } + }, + "house_chart": [ + [ + "Ketu" + ], + [], + [ + "Venus" + ], + [], + [ + "Sun" + ], + [], + [ + "Saturn", + "Rahu" + ], + [], + [], + [], + [ + "Moon", + "Mars", + "Jupiter" + ], + [ + "Mercury" + ] + ] + }, + "D10_Dasamsa": { + "division": 10, + "name": "Dasamsa", + "meaning": "事业", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 0.03, + "absolute_degree": 210.03 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 16.923, + "house": 8, + "absolute_degree": 76.923 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 2.2594, + "house": 7, + "absolute_degree": 32.2594 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 29.9004, + "house": 10, + "absolute_degree": 149.9004 + }, + "Mercury": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 21.8527, + "house": 4, + "absolute_degree": 321.8527 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 7.3104, + "house": 11, + "absolute_degree": 157.3104 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.0378, + "house": 11, + "absolute_degree": 160.0378 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 19.889, + "house": 6, + "absolute_degree": 19.889 + }, + "Rahu": { + "sign": "Capricorn", + "sign_index": 9, + "degree": 13.6306, + "house": 3, + "absolute_degree": 283.6306 + }, + "Ketu": { + "sign": "Cancer", + "sign_index": 3, + "degree": 13.6306, + "house": 9, + "absolute_degree": 103.6306 + } + }, + "house_chart": [ + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [ + "Ketu" + ], + [ + "Mars" + ], + [ + "Jupiter", + "Venus" + ], + [] + ] + }, + "D11_Rudramsa": { + "division": 11, + "name": "Rudramsa", + "meaning": "破坏/转化", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 9.033, + "absolute_degree": 219.033 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 18.6153, + "house": 8, + "absolute_degree": 78.6153 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.4853, + "house": 7, + "absolute_degree": 35.4853 + }, + "Mars": { + "sign": "Virgo", + "sign_index": 5, + "degree": 2.8904, + "house": 11, + "absolute_degree": 152.8904 + }, + "Mercury": { + "sign": "Pisces", + "sign_index": 11, + "degree": 18.038, + "house": 5, + "absolute_degree": 348.038 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 20.0414, + "house": 11, + "absolute_degree": 170.0414 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 26.0416, + "house": 11, + "absolute_degree": 176.0416 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 27.8779, + "house": 6, + "absolute_degree": 27.8779 + }, + "Rahu": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 2.9936, + "house": 4, + "absolute_degree": 302.9936 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 2.9936, + "house": 10, + "absolute_degree": 122.9936 + } + }, + "house_chart": [ + [], + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [], + [ + "Ketu" + ], + [ + "Mars", + "Jupiter", + "Venus" + ], + [] + ] + }, + "D24_Chaturvimsamsa": { + "division": 24, + "name": "Chaturvimsamsa", + "meaning": "教育/学习", + "ascendant": { + "sign": "Pisces", + "sign_index": 11, + "degree": 6.072, + "absolute_degree": 336.072 + }, + "planets": { + "Sun": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.6151, + "house": 7, + "absolute_degree": 160.6151 + }, + "Moon": { + "sign": "Libra", + "sign_index": 6, + "degree": 17.4225, + "house": 8, + "absolute_degree": 197.4225 + }, + "Mars": { + "sign": "Libra", + "sign_index": 6, + "degree": 11.761, + "house": 8, + "absolute_degree": 191.761 + }, + "Mercury": { + "sign": "Aries", + "sign_index": 0, + "degree": 28.4465, + "house": 2, + "absolute_degree": 28.4465 + }, + "Jupiter": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.5449, + "house": 3, + "absolute_degree": 35.5449 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0908, + "house": 6, + "absolute_degree": 144.0908 + }, + "Saturn": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 11.7337, + "house": 12, + "absolute_degree": 311.7337 + }, + "Rahu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + }, + "Ketu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + } + }, + "house_chart": [ + [], + [ + "Mercury" + ], + [ + "Jupiter" + ], + [], + [], + [ + "Venus" + ], + [ + "Sun" + ], + [ + "Moon", + "Mars", + "Rahu", + "Ketu" + ], + [], + [], + [], + [ + "Saturn" + ] + ] + } + }, + "transits": { + "status": "executed", + "sade_sati": { + "active": true, + "phase": "rising", + "phase_name": "上升期(Rising Phase)", + "moon_sign": "Aries", + "saturn_sign": "Pisces", + "intensity": "中等" + }, + "search_period": { + "start": "2026-09-02", + "end": "2026-12-01" + }, + "trigger_count": 0, + "boundary": "observation windows, not guaranteed events; empty triggers means none in the searched window, not that transits were skipped" + }, + "jaimini": { + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "chara_karakas": { + "Atmakaraka": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "AK": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "Amatyakaraka": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "AmK": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "Bhratrikaraka": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "BK": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "Matrikaraka": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "MK": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "Putrakaraka": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "PK": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "Gnatikaraka": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "GK": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "Darakaraka": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + }, + "DK": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + } + } + }, + "narayana_dasha": { + "current_dasha": { + "md": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "years": 9, + "start_age": 25.0, + "end_age": 34.0 + }, + "ad": { + "sign": "Virgo", + "sign_idx": 5, + "lord": "Mercury", + "years": 0.8265, + "start_age": 32.6224, + "end_age": 33.449 + }, + "pd": { + "sign": "Gemini", + "sign_idx": 2, + "lord": "Mercury", + "years": 0.1012, + "start_age": 33.1875, + "end_age": 33.2887 + }, + "remaining_years": 0.78 + }, + "lagna_sign": "Leo", + "mahadasha_sequence": [ + { + "lord": "Sun", + "sign": "Leo", + "start_age": 0.0, + "end_age": 10.0, + "years": 10 + }, + { + "lord": "Mercury", + "sign": "Virgo", + "start_age": 10.0, + "end_age": 19.0, + "years": 9 + }, + { + "lord": "Venus", + "sign": "Libra", + "start_age": 19.0, + "end_age": 25.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Scorpio", + "start_age": 25.0, + "end_age": 34.0, + "years": 9 + }, + { + "lord": "Jupiter", + "sign": "Sagittarius", + "start_age": 34.0, + "end_age": 43.0, + "years": 9 + }, + { + "lord": "Saturn", + "sign": "Capricorn", + "start_age": 43.0, + "end_age": 44.0, + "years": 1 + }, + { + "lord": "Saturn", + "sign": "Aquarius", + "start_age": 44.0, + "end_age": 56.0, + "years": 12 + }, + { + "lord": "Jupiter", + "sign": "Pisces", + "start_age": 56.0, + "end_age": 62.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Aries", + "start_age": 62.0, + "end_age": 66.0, + "years": 4 + }, + { + "lord": "Venus", + "sign": "Taurus", + "start_age": 66.0, + "end_age": 77.0, + "years": 11 + }, + { + "lord": "Mercury", + "sign": "Gemini", + "start_age": 77.0, + "end_age": 89.0, + "years": 12 + }, + { + "lord": "Moon", + "sign": "Cancer", + "start_age": 89.0, + "end_age": 98.0, + "years": 9 + } + ] + }, + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "yogas": { + "status": "executed", + "count": 1, + "yogas": [ + { + "name": "Bahu Sthree Yoga", + "hit": false + } + ] + }, + "ashtakavarga": { + "sav": { + "scores": { + "Aries": 31, + "Taurus": 29, + "Gemini": 36, + "Cancer": 22, + "Leo": 29, + "Virgo": 28, + "Libra": 26, + "Scorpio": 29, + "Sagittarius": 24, + "Capricorn": 26, + "Aquarius": 33, + "Pisces": 24 + }, + "total": 337 + } + }, + "dasha_sub_periods": { + "current": { + "mahadasha": { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + "antardasha": { + "lord": "Rahu", + "start": "2026-03-05", + "end": "2027-09-04" + } + } + } + } + }, + "consumer_context": { + "route": "marriage", + "core_status": "ready", + "available_layers": [ + "A10", + "A7", + "D1", + "D10", + "D11", + "D12", + "D16", + "D2", + "D20", + "D24", + "D27", + "D3", + "D30", + "D4", + "D40", + "D45", + "D5", + "D6", + "D60", + "D7", + "D8", + "D9", + "KP_cusp", + "UL", + "ashtakavarga", + "dasha_boundaries", + "dasha_sub_periods", + "functional_benefic_malefic", + "house_degrees", + "narayana_dasha", + "planet_degrees", + "shadbala", + "varga_spectrum", + "yogas" + ], + "missing_route_layers": [], + "hard_blockers": [], + "answer_policy": { + "can_answer_direction": true, + "can_answer_chart_interpretation": true, + "can_answer_precise_timing": true, + "precise_timing_requested": false, + "should_lead_with_limitations": false, + "provider_unavailable_is_fatal": false + } + }, + "machine_evidence_packet": { + "sections": { + "D1": { + "status": "used", + "source_path": "chart.planets+chart.ascendant" + }, + "D9": { + "status": "used", + "source_path": "modules.varga_full.D9" + }, + "D10": { + "status": "used", + "source_path": "modules.varga_full.D10" + }, + "D2": { + "status": "used", + "source_path": "modules.varga_full.D2" + }, + "D4": { + "status": "used", + "source_path": "modules.varga_full.D4" + }, + "planet_degrees": { + "status": "used", + "source_path": "chart.planets" + }, + "house_degrees": { + "status": "used", + "source_path": "chart.houses" + }, + "dasha_boundaries": { + "status": "used", + "source_path": "modules.dasha" + }, + "dasha_sub_periods": { + "status": "used", + "source_path": "modules.dasha_sub_periods" + }, + "narayana_dasha": { + "status": "used", + "source_path": "modules.narayana_dasha" + }, + "ashtakavarga": { + "status": "used", + "source_path": "modules.ashtakavarga" + }, + "yogas": { + "status": "used", + "source_path": "modules.yogas" + }, + "UL": { + "status": "used", + "source_path": "modules.arudha_padas.UL" + }, + "A7": { + "status": "used", + "source_path": "modules.arudha_padas.A7" + }, + "A10": { + "status": "used", + "source_path": "modules.arudha_padas.A10" + }, + "D6": { + "status": "used", + "source_path": "modules.varga_full.D6" + }, + "D7": { + "status": "used", + "source_path": "modules.varga_full.D7" + }, + "D11": { + "status": "used", + "source_path": "modules.varga_full.D11" + }, + "D12": { + "status": "used", + "source_path": "modules.varga_full.D12" + }, + "D24": { + "status": "used", + "source_path": "modules.varga_full.D24" + }, + "D30": { + "status": "used", + "source_path": "modules.varga_full.D30" + } + } + } + }, + "timing": { + "success": true, + "chart": { + "success": true, + "ascendant": { + "degree": 9.0, + "degree_in_sign": 9.0, + "lon": 129.003, + "sign": "Leo", + "sign_idx": 4 + }, + "planets": { + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "lon": 162.7310389205016, + "degree": 12.731, + "degree_in_sign": 12.731, + "house": 2, + "retrograde": false + }, + "Ketu": { + "sign": "Taurus", + "sign_idx": 1, + "lon": 49.363055820241016, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 10, + "retrograde": true + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "lon": 122.9900397721899, + "degree": 2.99, + "degree_in_sign": 2.99, + "house": 1, + "retrograde": false + }, + "Mercury": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 86.18527092954923, + "degree": 26.1853, + "degree_in_sign": 26.1853, + "house": 11, + "retrograde": false + }, + "Moon": { + "sign": "Aries", + "sign_idx": 0, + "lon": 3.2259370143924713, + "degree": 3.2259, + "degree_in_sign": 3.2259, + "house": 9, + "retrograde": false + }, + "Rahu": { + "sign": "Scorpio", + "sign_idx": 7, + "lon": 229.36305582024104, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 4, + "retrograde": true + }, + "Saturn": { + "sign": "Aquarius", + "sign_idx": 10, + "lon": 307.9889038425868, + "degree": 7.9889, + "degree_in_sign": 7.9889, + "house": 7, + "retrograde": true + }, + "Sun": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 61.69229619774846, + "degree": 1.6923, + "degree_in_sign": 1.6923, + "house": 11, + "retrograde": false + }, + "Venus": { + "sign": "Aries", + "sign_idx": 0, + "lon": 16.003783878640178, + "degree": 16.0038, + "degree_in_sign": 16.0038, + "house": 9, + "retrograde": false + } + }, + "houses": { + "1": { + "sign": "Leo", + "sign_idx": 4 + }, + "10": { + "sign": "Taurus", + "sign_idx": 1 + }, + "11": { + "sign": "Gemini", + "sign_idx": 2 + }, + "12": { + "sign": "Cancer", + "sign_idx": 3 + }, + "2": { + "sign": "Virgo", + "sign_idx": 5 + }, + "3": { + "sign": "Libra", + "sign_idx": 6 + }, + "4": { + "sign": "Scorpio", + "sign_idx": 7 + }, + "5": { + "sign": "Sagittarius", + "sign_idx": 8 + }, + "6": { + "sign": "Capricorn", + "sign_idx": 9 + }, + "7": { + "sign": "Aquarius", + "sign_idx": 10 + }, + "8": { + "sign": "Pisces", + "sign_idx": 11 + }, + "9": { + "sign": "Aries", + "sign_idx": 0 + } + }, + "dasha": { + "periods": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "mahadashas": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "current_md": "Ketu", + "start_date": "1991-10-05" + }, + "modules": { + "varga_full": { + "D2_Hora": { + "division": 2, + "name": "Hora", + "meaning": "财富", + "ascendant": { + "sign": "Leo", + "sign_index": 4, + "degree": 18.006, + "absolute_degree": 138.006 + }, + "planets": { + "Sun": { + "sign": "Leo", + "sign_index": 4, + "degree": 3.3846, + "house": 1, + "absolute_degree": 123.3846 + }, + "Moon": { + "sign": "Leo", + "sign_index": 4, + "degree": 6.4519, + "house": 1, + "absolute_degree": 126.4519 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 5.9801, + "house": 1, + "absolute_degree": 125.9801 + }, + "Mercury": { + "sign": "Cancer", + "sign_index": 3, + "degree": 22.3705, + "house": 12, + "absolute_degree": 112.3705 + }, + "Jupiter": { + "sign": "Cancer", + "sign_index": 3, + "degree": 25.4621, + "house": 12, + "absolute_degree": 115.4621 + }, + "Venus": { + "sign": "Cancer", + "sign_index": 3, + "degree": 2.0076, + "house": 12, + "absolute_degree": 92.0076 + }, + "Saturn": { + "sign": "Leo", + "sign_index": 4, + "degree": 15.9778, + "house": 1, + "absolute_degree": 135.9778 + }, + "Rahu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + } + }, + "house_chart": [ + [ + "Sun", + "Moon", + "Mars", + "Saturn", + "Rahu", + "Ketu" + ], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [ + "Mercury", + "Jupiter", + "Venus" + ] + ] + }, + "D9_Navamsa": { + "division": 9, + "name": "Navamsa", + "meaning": "配偶/灵性", + "ascendant": { + "sign": "Gemini", + "sign_index": 2, + "degree": 21.027, + "absolute_degree": 81.027 + }, + "planets": { + "Sun": { + "sign": "Libra", + "sign_index": 6, + "degree": 15.2307, + "house": 5, + "absolute_degree": 195.2307 + }, + "Moon": { + "sign": "Aries", + "sign_index": 0, + "degree": 29.0334, + "house": 11, + "absolute_degree": 29.0334 + }, + "Mars": { + "sign": "Aries", + "sign_index": 0, + "degree": 26.9104, + "house": 11, + "absolute_degree": 26.9104 + }, + "Mercury": { + "sign": "Taurus", + "sign_index": 1, + "degree": 25.6674, + "house": 12, + "absolute_degree": 55.6674 + }, + "Jupiter": { + "sign": "Aries", + "sign_index": 0, + "degree": 24.5794, + "house": 11, + "absolute_degree": 24.5794 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0341, + "house": 3, + "absolute_degree": 144.0341 + }, + "Saturn": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 11.9001, + "house": 7, + "absolute_degree": 251.9001 + }, + "Rahu": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 24.2675, + "house": 7, + "absolute_degree": 264.2675 + }, + "Ketu": { + "sign": "Gemini", + "sign_index": 2, + "degree": 24.2675, + "house": 1, + "absolute_degree": 84.2675 + } + }, + "house_chart": [ + [ + "Ketu" + ], + [], + [ + "Venus" + ], + [], + [ + "Sun" + ], + [], + [ + "Saturn", + "Rahu" + ], + [], + [], + [], + [ + "Moon", + "Mars", + "Jupiter" + ], + [ + "Mercury" + ] + ] + }, + "D10_Dasamsa": { + "division": 10, + "name": "Dasamsa", + "meaning": "事业", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 0.03, + "absolute_degree": 210.03 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 16.923, + "house": 8, + "absolute_degree": 76.923 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 2.2594, + "house": 7, + "absolute_degree": 32.2594 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 29.9004, + "house": 10, + "absolute_degree": 149.9004 + }, + "Mercury": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 21.8527, + "house": 4, + "absolute_degree": 321.8527 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 7.3104, + "house": 11, + "absolute_degree": 157.3104 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.0378, + "house": 11, + "absolute_degree": 160.0378 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 19.889, + "house": 6, + "absolute_degree": 19.889 + }, + "Rahu": { + "sign": "Capricorn", + "sign_index": 9, + "degree": 13.6306, + "house": 3, + "absolute_degree": 283.6306 + }, + "Ketu": { + "sign": "Cancer", + "sign_index": 3, + "degree": 13.6306, + "house": 9, + "absolute_degree": 103.6306 + } + }, + "house_chart": [ + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [ + "Ketu" + ], + [ + "Mars" + ], + [ + "Jupiter", + "Venus" + ], + [] + ] + }, + "D11_Rudramsa": { + "division": 11, + "name": "Rudramsa", + "meaning": "破坏/转化", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 9.033, + "absolute_degree": 219.033 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 18.6153, + "house": 8, + "absolute_degree": 78.6153 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.4853, + "house": 7, + "absolute_degree": 35.4853 + }, + "Mars": { + "sign": "Virgo", + "sign_index": 5, + "degree": 2.8904, + "house": 11, + "absolute_degree": 152.8904 + }, + "Mercury": { + "sign": "Pisces", + "sign_index": 11, + "degree": 18.038, + "house": 5, + "absolute_degree": 348.038 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 20.0414, + "house": 11, + "absolute_degree": 170.0414 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 26.0416, + "house": 11, + "absolute_degree": 176.0416 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 27.8779, + "house": 6, + "absolute_degree": 27.8779 + }, + "Rahu": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 2.9936, + "house": 4, + "absolute_degree": 302.9936 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 2.9936, + "house": 10, + "absolute_degree": 122.9936 + } + }, + "house_chart": [ + [], + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [], + [ + "Ketu" + ], + [ + "Mars", + "Jupiter", + "Venus" + ], + [] + ] + }, + "D24_Chaturvimsamsa": { + "division": 24, + "name": "Chaturvimsamsa", + "meaning": "教育/学习", + "ascendant": { + "sign": "Pisces", + "sign_index": 11, + "degree": 6.072, + "absolute_degree": 336.072 + }, + "planets": { + "Sun": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.6151, + "house": 7, + "absolute_degree": 160.6151 + }, + "Moon": { + "sign": "Libra", + "sign_index": 6, + "degree": 17.4225, + "house": 8, + "absolute_degree": 197.4225 + }, + "Mars": { + "sign": "Libra", + "sign_index": 6, + "degree": 11.761, + "house": 8, + "absolute_degree": 191.761 + }, + "Mercury": { + "sign": "Aries", + "sign_index": 0, + "degree": 28.4465, + "house": 2, + "absolute_degree": 28.4465 + }, + "Jupiter": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.5449, + "house": 3, + "absolute_degree": 35.5449 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0908, + "house": 6, + "absolute_degree": 144.0908 + }, + "Saturn": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 11.7337, + "house": 12, + "absolute_degree": 311.7337 + }, + "Rahu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + }, + "Ketu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + } + }, + "house_chart": [ + [], + [ + "Mercury" + ], + [ + "Jupiter" + ], + [], + [], + [ + "Venus" + ], + [ + "Sun" + ], + [ + "Moon", + "Mars", + "Rahu", + "Ketu" + ], + [], + [], + [], + [ + "Saturn" + ] + ] + } + }, + "transits": { + "status": "executed", + "sade_sati": { + "active": true, + "phase": "rising", + "phase_name": "上升期(Rising Phase)", + "moon_sign": "Aries", + "saturn_sign": "Pisces", + "intensity": "中等" + }, + "search_period": { + "start": "2026-09-02", + "end": "2026-12-01" + }, + "trigger_count": 0, + "boundary": "observation windows, not guaranteed events; empty triggers means none in the searched window, not that transits were skipped" + }, + "jaimini": { + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "chara_karakas": { + "Atmakaraka": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "AK": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "Amatyakaraka": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "AmK": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "Bhratrikaraka": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "BK": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "Matrikaraka": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "MK": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "Putrakaraka": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "PK": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "Gnatikaraka": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "GK": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "Darakaraka": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + }, + "DK": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + } + } + }, + "narayana_dasha": { + "current_dasha": { + "md": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "years": 9, + "start_age": 25.0, + "end_age": 34.0 + }, + "ad": { + "sign": "Virgo", + "sign_idx": 5, + "lord": "Mercury", + "years": 0.8265, + "start_age": 32.6224, + "end_age": 33.449 + }, + "pd": { + "sign": "Gemini", + "sign_idx": 2, + "lord": "Mercury", + "years": 0.1012, + "start_age": 33.1875, + "end_age": 33.2887 + }, + "remaining_years": 0.78 + }, + "lagna_sign": "Leo", + "mahadasha_sequence": [ + { + "lord": "Sun", + "sign": "Leo", + "start_age": 0.0, + "end_age": 10.0, + "years": 10 + }, + { + "lord": "Mercury", + "sign": "Virgo", + "start_age": 10.0, + "end_age": 19.0, + "years": 9 + }, + { + "lord": "Venus", + "sign": "Libra", + "start_age": 19.0, + "end_age": 25.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Scorpio", + "start_age": 25.0, + "end_age": 34.0, + "years": 9 + }, + { + "lord": "Jupiter", + "sign": "Sagittarius", + "start_age": 34.0, + "end_age": 43.0, + "years": 9 + }, + { + "lord": "Saturn", + "sign": "Capricorn", + "start_age": 43.0, + "end_age": 44.0, + "years": 1 + }, + { + "lord": "Saturn", + "sign": "Aquarius", + "start_age": 44.0, + "end_age": 56.0, + "years": 12 + }, + { + "lord": "Jupiter", + "sign": "Pisces", + "start_age": 56.0, + "end_age": 62.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Aries", + "start_age": 62.0, + "end_age": 66.0, + "years": 4 + }, + { + "lord": "Venus", + "sign": "Taurus", + "start_age": 66.0, + "end_age": 77.0, + "years": 11 + }, + { + "lord": "Mercury", + "sign": "Gemini", + "start_age": 77.0, + "end_age": 89.0, + "years": 12 + }, + { + "lord": "Moon", + "sign": "Cancer", + "start_age": 89.0, + "end_age": 98.0, + "years": 9 + } + ] + }, + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "yogas": { + "status": "executed", + "count": 20, + "yogas": [ + { + "name": "Sunaphaa Yoga", + "hit": false + }, + { + "name": "Anaphaa Yoga", + "hit": false + }, + { + "name": "Duradhara Yoga", + "hit": false + }, + { + "name": "Vosi Yoga", + "hit": false + }, + { + "name": "Ubhayachara Yoga", + "hit": false + }, + { + "name": "Naukaa Yoga", + "hit": false + }, + { + "name": "Bahu Puthra Yoga", + "hit": false + }, + { + "name": "Eka Puthra Yoga", + "hit": false + }, + { + "name": "Dattha Puthra Yoga", + "hit": false + }, + { + "name": "Matru Sneha Yoga", + "hit": false + }, + { + "name": "Matru Satrutwa Yoga", + "hit": false + }, + { + "name": "Matrudeerghayur Yoga", + "hit": false + }, + { + "name": "Matrunasa Yoga", + "hit": false + }, + { + "name": "Bhratruvriddhi Yoga", + "hit": false + }, + { + "name": "Bahu Sthree Yoga", + "hit": false + }, + { + "name": "Dharidhra Yoga", + "hit": false + }, + { + "name": "Swaveeryaddhana Yoga", + "hit": false + }, + { + "name": "Anthya Vayasi Dhana Yoga", + "hit": false + }, + { + "name": "Matrumooladdhana Yoga", + "hit": false + }, + { + "name": "Madhya Vayasi Dhana Yoga", + "hit": false + } + ] + }, + "ashtakavarga": { + "sav": { + "scores": { + "Aries": 31, + "Taurus": 29, + "Gemini": 36, + "Cancer": 22, + "Leo": 29, + "Virgo": 28, + "Libra": 26, + "Scorpio": 29, + "Sagittarius": 24, + "Capricorn": 26, + "Aquarius": 33, + "Pisces": 24 + }, + "total": 337 + } + }, + "dasha_sub_periods": { + "current": { + "mahadasha": { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + "antardasha": { + "lord": "Rahu", + "start": "2026-03-05", + "end": "2027-09-04" + } + } + } + } + }, + "consumer_context": { + "route": "timing", + "core_status": "ready", + "available_layers": [ + "A10", + "A7", + "D1", + "D10", + "D11", + "D12", + "D16", + "D2", + "D20", + "D24", + "D27", + "D3", + "D30", + "D4", + "D40", + "D45", + "D5", + "D6", + "D60", + "D7", + "D8", + "D9", + "KP_cusp", + "UL", + "ashtakavarga", + "dasha_boundaries", + "dasha_sub_periods", + "functional_benefic_malefic", + "house_degrees", + "narayana_dasha", + "planet_degrees", + "shadbala", + "varga_spectrum", + "yogas" + ], + "missing_route_layers": [], + "hard_blockers": [], + "answer_policy": { + "can_answer_direction": true, + "can_answer_chart_interpretation": true, + "can_answer_precise_timing": true, + "precise_timing_requested": true, + "should_lead_with_limitations": false, + "provider_unavailable_is_fatal": false + } + }, + "machine_evidence_packet": { + "sections": { + "D1": { + "status": "used", + "source_path": "chart.planets+chart.ascendant" + }, + "D9": { + "status": "used", + "source_path": "modules.varga_full.D9" + }, + "D10": { + "status": "used", + "source_path": "modules.varga_full.D10" + }, + "D2": { + "status": "used", + "source_path": "modules.varga_full.D2" + }, + "D4": { + "status": "used", + "source_path": "modules.varga_full.D4" + }, + "planet_degrees": { + "status": "used", + "source_path": "chart.planets" + }, + "house_degrees": { + "status": "used", + "source_path": "chart.houses" + }, + "dasha_boundaries": { + "status": "used", + "source_path": "modules.dasha" + }, + "dasha_sub_periods": { + "status": "used", + "source_path": "modules.dasha_sub_periods" + }, + "narayana_dasha": { + "status": "used", + "source_path": "modules.narayana_dasha" + }, + "ashtakavarga": { + "status": "used", + "source_path": "modules.ashtakavarga" + }, + "yogas": { + "status": "used", + "source_path": "modules.yogas" + }, + "UL": { + "status": "used", + "source_path": "modules.arudha_padas.UL" + }, + "A7": { + "status": "used", + "source_path": "modules.arudha_padas.A7" + }, + "A10": { + "status": "used", + "source_path": "modules.arudha_padas.A10" + }, + "D6": { + "status": "used", + "source_path": "modules.varga_full.D6" + }, + "D7": { + "status": "used", + "source_path": "modules.varga_full.D7" + }, + "D11": { + "status": "used", + "source_path": "modules.varga_full.D11" + }, + "D12": { + "status": "used", + "source_path": "modules.varga_full.D12" + }, + "D24": { + "status": "used", + "source_path": "modules.varga_full.D24" + }, + "D30": { + "status": "used", + "source_path": "modules.varga_full.D30" + } + } + } + }, + "wealth": { + "success": true, + "chart": { + "success": true, + "ascendant": { + "degree": 9.0, + "degree_in_sign": 9.0, + "lon": 129.003, + "sign": "Leo", + "sign_idx": 4 + }, + "planets": { + "Jupiter": { + "sign": "Virgo", + "sign_idx": 5, + "lon": 162.7310389205016, + "degree": 12.731, + "degree_in_sign": 12.731, + "house": 2, + "retrograde": false + }, + "Ketu": { + "sign": "Taurus", + "sign_idx": 1, + "lon": 49.363055820241016, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 10, + "retrograde": true + }, + "Mars": { + "sign": "Leo", + "sign_idx": 4, + "lon": 122.9900397721899, + "degree": 2.99, + "degree_in_sign": 2.99, + "house": 1, + "retrograde": false + }, + "Mercury": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 86.18527092954923, + "degree": 26.1853, + "degree_in_sign": 26.1853, + "house": 11, + "retrograde": false + }, + "Moon": { + "sign": "Aries", + "sign_idx": 0, + "lon": 3.2259370143924713, + "degree": 3.2259, + "degree_in_sign": 3.2259, + "house": 9, + "retrograde": false + }, + "Rahu": { + "sign": "Scorpio", + "sign_idx": 7, + "lon": 229.36305582024104, + "degree": 19.3631, + "degree_in_sign": 19.3631, + "house": 4, + "retrograde": true + }, + "Saturn": { + "sign": "Aquarius", + "sign_idx": 10, + "lon": 307.9889038425868, + "degree": 7.9889, + "degree_in_sign": 7.9889, + "house": 7, + "retrograde": true + }, + "Sun": { + "sign": "Gemini", + "sign_idx": 2, + "lon": 61.69229619774846, + "degree": 1.6923, + "degree_in_sign": 1.6923, + "house": 11, + "retrograde": false + }, + "Venus": { + "sign": "Aries", + "sign_idx": 0, + "lon": 16.003783878640178, + "degree": 16.0038, + "degree_in_sign": 16.0038, + "house": 9, + "retrograde": false + } + }, + "houses": { + "1": { + "sign": "Leo", + "sign_idx": 4 + }, + "10": { + "sign": "Taurus", + "sign_idx": 1 + }, + "11": { + "sign": "Gemini", + "sign_idx": 2 + }, + "12": { + "sign": "Cancer", + "sign_idx": 3 + }, + "2": { + "sign": "Virgo", + "sign_idx": 5 + }, + "3": { + "sign": "Libra", + "sign_idx": 6 + }, + "4": { + "sign": "Scorpio", + "sign_idx": 7 + }, + "5": { + "sign": "Sagittarius", + "sign_idx": 8 + }, + "6": { + "sign": "Capricorn", + "sign_idx": 9 + }, + "7": { + "sign": "Aquarius", + "sign_idx": 10 + }, + "8": { + "sign": "Pisces", + "sign_idx": 11 + }, + "9": { + "sign": "Aries", + "sign_idx": 0 + } + }, + "dasha": { + "periods": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "mahadashas": [ + { + "lord": "Ketu", + "start": "1991-10-05", + "end": "1998-10-05" + }, + { + "lord": "Venus", + "start": "1998-10-05", + "end": "2018-10-05" + }, + { + "lord": "Sun", + "start": "2018-10-05", + "end": "2024-10-04" + }, + { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + { + "lord": "Mars", + "start": "2034-10-05", + "end": "2041-10-04" + }, + { + "lord": "Rahu", + "start": "2041-10-04", + "end": "2059-10-05" + }, + { + "lord": "Jupiter", + "start": "2059-10-05", + "end": "2075-10-05" + }, + { + "lord": "Saturn", + "start": "2075-10-05", + "end": "2094-10-05" + }, + { + "lord": "Mercury", + "start": "2094-10-05", + "end": "2111-10-06" + } + ], + "current_md": "Ketu", + "start_date": "1991-10-05" + }, + "modules": { + "varga_full": { + "D2_Hora": { + "division": 2, + "name": "Hora", + "meaning": "财富", + "ascendant": { + "sign": "Leo", + "sign_index": 4, + "degree": 18.006, + "absolute_degree": 138.006 + }, + "planets": { + "Sun": { + "sign": "Leo", + "sign_index": 4, + "degree": 3.3846, + "house": 1, + "absolute_degree": 123.3846 + }, + "Moon": { + "sign": "Leo", + "sign_index": 4, + "degree": 6.4519, + "house": 1, + "absolute_degree": 126.4519 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 5.9801, + "house": 1, + "absolute_degree": 125.9801 + }, + "Mercury": { + "sign": "Cancer", + "sign_index": 3, + "degree": 22.3705, + "house": 12, + "absolute_degree": 112.3705 + }, + "Jupiter": { + "sign": "Cancer", + "sign_index": 3, + "degree": 25.4621, + "house": 12, + "absolute_degree": 115.4621 + }, + "Venus": { + "sign": "Cancer", + "sign_index": 3, + "degree": 2.0076, + "house": 12, + "absolute_degree": 92.0076 + }, + "Saturn": { + "sign": "Leo", + "sign_index": 4, + "degree": 15.9778, + "house": 1, + "absolute_degree": 135.9778 + }, + "Rahu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 8.7261, + "house": 1, + "absolute_degree": 128.7261 + } + }, + "house_chart": [ + [ + "Sun", + "Moon", + "Mars", + "Saturn", + "Rahu", + "Ketu" + ], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [], + [ + "Mercury", + "Jupiter", + "Venus" + ] + ] + }, + "D9_Navamsa": { + "division": 9, + "name": "Navamsa", + "meaning": "配偶/灵性", + "ascendant": { + "sign": "Gemini", + "sign_index": 2, + "degree": 21.027, + "absolute_degree": 81.027 + }, + "planets": { + "Sun": { + "sign": "Libra", + "sign_index": 6, + "degree": 15.2307, + "house": 5, + "absolute_degree": 195.2307 + }, + "Moon": { + "sign": "Aries", + "sign_index": 0, + "degree": 29.0334, + "house": 11, + "absolute_degree": 29.0334 + }, + "Mars": { + "sign": "Aries", + "sign_index": 0, + "degree": 26.9104, + "house": 11, + "absolute_degree": 26.9104 + }, + "Mercury": { + "sign": "Taurus", + "sign_index": 1, + "degree": 25.6674, + "house": 12, + "absolute_degree": 55.6674 + }, + "Jupiter": { + "sign": "Aries", + "sign_index": 0, + "degree": 24.5794, + "house": 11, + "absolute_degree": 24.5794 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0341, + "house": 3, + "absolute_degree": 144.0341 + }, + "Saturn": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 11.9001, + "house": 7, + "absolute_degree": 251.9001 + }, + "Rahu": { + "sign": "Sagittarius", + "sign_index": 8, + "degree": 24.2675, + "house": 7, + "absolute_degree": 264.2675 + }, + "Ketu": { + "sign": "Gemini", + "sign_index": 2, + "degree": 24.2675, + "house": 1, + "absolute_degree": 84.2675 + } + }, + "house_chart": [ + [ + "Ketu" + ], + [], + [ + "Venus" + ], + [], + [ + "Sun" + ], + [], + [ + "Saturn", + "Rahu" + ], + [], + [], + [], + [ + "Moon", + "Mars", + "Jupiter" + ], + [ + "Mercury" + ] + ] + }, + "D10_Dasamsa": { + "division": 10, + "name": "Dasamsa", + "meaning": "事业", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 0.03, + "absolute_degree": 210.03 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 16.923, + "house": 8, + "absolute_degree": 76.923 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 2.2594, + "house": 7, + "absolute_degree": 32.2594 + }, + "Mars": { + "sign": "Leo", + "sign_index": 4, + "degree": 29.9004, + "house": 10, + "absolute_degree": 149.9004 + }, + "Mercury": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 21.8527, + "house": 4, + "absolute_degree": 321.8527 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 7.3104, + "house": 11, + "absolute_degree": 157.3104 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.0378, + "house": 11, + "absolute_degree": 160.0378 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 19.889, + "house": 6, + "absolute_degree": 19.889 + }, + "Rahu": { + "sign": "Capricorn", + "sign_index": 9, + "degree": 13.6306, + "house": 3, + "absolute_degree": 283.6306 + }, + "Ketu": { + "sign": "Cancer", + "sign_index": 3, + "degree": 13.6306, + "house": 9, + "absolute_degree": 103.6306 + } + }, + "house_chart": [ + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [ + "Ketu" + ], + [ + "Mars" + ], + [ + "Jupiter", + "Venus" + ], + [] + ] + }, + "D11_Rudramsa": { + "division": 11, + "name": "Rudramsa", + "meaning": "破坏/转化", + "ascendant": { + "sign": "Scorpio", + "sign_index": 7, + "degree": 9.033, + "absolute_degree": 219.033 + }, + "planets": { + "Sun": { + "sign": "Gemini", + "sign_index": 2, + "degree": 18.6153, + "house": 8, + "absolute_degree": 78.6153 + }, + "Moon": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.4853, + "house": 7, + "absolute_degree": 35.4853 + }, + "Mars": { + "sign": "Virgo", + "sign_index": 5, + "degree": 2.8904, + "house": 11, + "absolute_degree": 152.8904 + }, + "Mercury": { + "sign": "Pisces", + "sign_index": 11, + "degree": 18.038, + "house": 5, + "absolute_degree": 348.038 + }, + "Jupiter": { + "sign": "Virgo", + "sign_index": 5, + "degree": 20.0414, + "house": 11, + "absolute_degree": 170.0414 + }, + "Venus": { + "sign": "Virgo", + "sign_index": 5, + "degree": 26.0416, + "house": 11, + "absolute_degree": 176.0416 + }, + "Saturn": { + "sign": "Aries", + "sign_index": 0, + "degree": 27.8779, + "house": 6, + "absolute_degree": 27.8779 + }, + "Rahu": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 2.9936, + "house": 4, + "absolute_degree": 302.9936 + }, + "Ketu": { + "sign": "Leo", + "sign_index": 4, + "degree": 2.9936, + "house": 10, + "absolute_degree": 122.9936 + } + }, + "house_chart": [ + [], + [], + [], + [ + "Rahu" + ], + [ + "Mercury" + ], + [ + "Saturn" + ], + [ + "Moon" + ], + [ + "Sun" + ], + [], + [ + "Ketu" + ], + [ + "Mars", + "Jupiter", + "Venus" + ], + [] + ] + }, + "D24_Chaturvimsamsa": { + "division": 24, + "name": "Chaturvimsamsa", + "meaning": "教育/学习", + "ascendant": { + "sign": "Pisces", + "sign_index": 11, + "degree": 6.072, + "absolute_degree": 336.072 + }, + "planets": { + "Sun": { + "sign": "Virgo", + "sign_index": 5, + "degree": 10.6151, + "house": 7, + "absolute_degree": 160.6151 + }, + "Moon": { + "sign": "Libra", + "sign_index": 6, + "degree": 17.4225, + "house": 8, + "absolute_degree": 197.4225 + }, + "Mars": { + "sign": "Libra", + "sign_index": 6, + "degree": 11.761, + "house": 8, + "absolute_degree": 191.761 + }, + "Mercury": { + "sign": "Aries", + "sign_index": 0, + "degree": 28.4465, + "house": 2, + "absolute_degree": 28.4465 + }, + "Jupiter": { + "sign": "Taurus", + "sign_index": 1, + "degree": 5.5449, + "house": 3, + "absolute_degree": 35.5449 + }, + "Venus": { + "sign": "Leo", + "sign_index": 4, + "degree": 24.0908, + "house": 6, + "absolute_degree": 144.0908 + }, + "Saturn": { + "sign": "Aquarius", + "sign_index": 10, + "degree": 11.7337, + "house": 12, + "absolute_degree": 311.7337 + }, + "Rahu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + }, + "Ketu": { + "sign": "Libra", + "sign_index": 6, + "degree": 14.7133, + "house": 8, + "absolute_degree": 194.7133 + } + }, + "house_chart": [ + [], + [ + "Mercury" + ], + [ + "Jupiter" + ], + [], + [], + [ + "Venus" + ], + [ + "Sun" + ], + [ + "Moon", + "Mars", + "Rahu", + "Ketu" + ], + [], + [], + [], + [ + "Saturn" + ] + ] + } + }, + "transits": { + "status": "executed", + "sade_sati": { + "active": true, + "phase": "rising", + "phase_name": "上升期(Rising Phase)", + "moon_sign": "Aries", + "saturn_sign": "Pisces", + "intensity": "中等" + }, + "search_period": { + "start": "2026-09-02", + "end": "2026-12-01" + }, + "trigger_count": 0, + "boundary": "observation windows, not guaranteed events; empty triggers means none in the searched window, not that transits were skipped" + }, + "jaimini": { + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "chara_karakas": { + "Atmakaraka": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "AK": { + "planet": "Mercury", + "degree_in_sign": 26.1853, + "rank": 1, + "domain": "灵魂使命、核心自我、人生最高目标", + "cn_name": "灵魂星AK" + }, + "Amatyakaraka": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "AmK": { + "planet": "Venus", + "degree_in_sign": 16.0038, + "rank": 2, + "domain": "事业方向、主要谋士、权力代理", + "cn_name": "事业星AmK" + }, + "Bhratrikaraka": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "BK": { + "planet": "Jupiter", + "degree_in_sign": 12.731, + "rank": 3, + "domain": "兄弟姐妹、勇气、冒险精神", + "cn_name": "兄弟星BK" + }, + "Matrikaraka": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "MK": { + "planet": "Saturn", + "degree_in_sign": 7.9889, + "rank": 4, + "domain": "母亲、家庭根基、情感安全感", + "cn_name": "母亲星MK" + }, + "Putrakaraka": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "PK": { + "planet": "Moon", + "degree_in_sign": 3.2259, + "rank": 5, + "domain": "子女、创造力、学生、智能成果", + "cn_name": "子女星PK" + }, + "Gnatikaraka": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "GK": { + "planet": "Mars", + "degree_in_sign": 2.99, + "rank": 6, + "domain": "竞争对手、疾病、障碍、转化力量", + "cn_name": "障碍星GK" + }, + "Darakaraka": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + }, + "DK": { + "planet": "Sun", + "degree_in_sign": 1.6923, + "rank": 7, + "domain": "配偶特质、伴侣关系、婚姻质量", + "cn_name": "配偶星DK" + } + } + }, + "narayana_dasha": { + "current_dasha": { + "md": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "years": 9, + "start_age": 25.0, + "end_age": 34.0 + }, + "ad": { + "sign": "Virgo", + "sign_idx": 5, + "lord": "Mercury", + "years": 0.8265, + "start_age": 32.6224, + "end_age": 33.449 + }, + "pd": { + "sign": "Gemini", + "sign_idx": 2, + "lord": "Mercury", + "years": 0.1012, + "start_age": 33.1875, + "end_age": 33.2887 + }, + "remaining_years": 0.78 + }, + "lagna_sign": "Leo", + "mahadasha_sequence": [ + { + "lord": "Sun", + "sign": "Leo", + "start_age": 0.0, + "end_age": 10.0, + "years": 10 + }, + { + "lord": "Mercury", + "sign": "Virgo", + "start_age": 10.0, + "end_age": 19.0, + "years": 9 + }, + { + "lord": "Venus", + "sign": "Libra", + "start_age": 19.0, + "end_age": 25.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Scorpio", + "start_age": 25.0, + "end_age": 34.0, + "years": 9 + }, + { + "lord": "Jupiter", + "sign": "Sagittarius", + "start_age": 34.0, + "end_age": 43.0, + "years": 9 + }, + { + "lord": "Saturn", + "sign": "Capricorn", + "start_age": 43.0, + "end_age": 44.0, + "years": 1 + }, + { + "lord": "Saturn", + "sign": "Aquarius", + "start_age": 44.0, + "end_age": 56.0, + "years": 12 + }, + { + "lord": "Jupiter", + "sign": "Pisces", + "start_age": 56.0, + "end_age": 62.0, + "years": 6 + }, + { + "lord": "Mars", + "sign": "Aries", + "start_age": 62.0, + "end_age": 66.0, + "years": 4 + }, + { + "lord": "Venus", + "sign": "Taurus", + "start_age": 66.0, + "end_age": 77.0, + "years": 11 + }, + { + "lord": "Mercury", + "sign": "Gemini", + "start_age": 77.0, + "end_age": 89.0, + "years": 12 + }, + { + "lord": "Moon", + "sign": "Cancer", + "start_age": 89.0, + "end_age": 98.0, + "years": 9 + } + ] + }, + "arudha_padas": { + "padas": { + "A7": { + "sign": "Scorpio", + "sign_idx": 7, + "lord": "Mars", + "source_house_sign": "Aquarius", + "source_house_lord": "Saturn", + "lord_sign": "Aquarius", + "distance": 1, + "exception_triggered": true, + "house_num": 7, + "name": "Dara Pada (A7)" + }, + "A10": { + "sign": "Pisces", + "sign_idx": 11, + "lord": "Jupiter", + "source_house_sign": "Taurus", + "source_house_lord": "Venus", + "lord_sign": "Aries", + "distance": 12, + "exception_triggered": false, + "house_num": 10, + "name": "Karma Pada (A10)" + }, + "UL": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "upapada": { + "sign": "Aries", + "sign_idx": 0, + "lord": "Mars", + "source_house_sign": "Cancer", + "source_house_lord": "Moon", + "lord_sign": "Aries", + "distance": 10, + "exception_triggered": true, + "house_num": 12, + "name": "Upapada (UL)" + } + }, + "yogas": { + "status": "executed", + "count": 5, + "yogas": [ + { + "name": "Dharidhra Yoga", + "hit": false + }, + { + "name": "Swaveeryaddhana Yoga", + "hit": false + }, + { + "name": "Anthya Vayasi Dhana Yoga", + "hit": false + }, + { + "name": "Matrumooladdhana Yoga", + "hit": false + }, + { + "name": "Madhya Vayasi Dhana Yoga", + "hit": false + } + ] + }, + "ashtakavarga": { + "sav": { + "scores": { + "Aries": 31, + "Taurus": 29, + "Gemini": 36, + "Cancer": 22, + "Leo": 29, + "Virgo": 28, + "Libra": 26, + "Scorpio": 29, + "Sagittarius": 24, + "Capricorn": 26, + "Aquarius": 33, + "Pisces": 24 + }, + "total": 337 + } + }, + "dasha_sub_periods": { + "current": { + "mahadasha": { + "lord": "Moon", + "start": "2024-10-04", + "end": "2034-10-05" + }, + "antardasha": { + "lord": "Rahu", + "start": "2026-03-05", + "end": "2027-09-04" + } + } + } + } + }, + "consumer_context": { + "route": "wealth", + "core_status": "ready", + "available_layers": [ + "A10", + "A7", + "D1", + "D10", + "D11", + "D12", + "D16", + "D2", + "D20", + "D24", + "D27", + "D3", + "D30", + "D4", + "D40", + "D45", + "D5", + "D6", + "D60", + "D7", + "D8", + "D9", + "KP_cusp", + "UL", + "ashtakavarga", + "dasha_boundaries", + "dasha_sub_periods", + "functional_benefic_malefic", + "house_degrees", + "narayana_dasha", + "planet_degrees", + "shadbala", + "varga_spectrum", + "yogas" + ], + "missing_route_layers": [], + "hard_blockers": [], + "answer_policy": { + "can_answer_direction": true, + "can_answer_chart_interpretation": true, + "can_answer_precise_timing": true, + "precise_timing_requested": false, + "should_lead_with_limitations": false, + "provider_unavailable_is_fatal": false + } + }, + "machine_evidence_packet": { + "sections": { + "D1": { + "status": "used", + "source_path": "chart.planets+chart.ascendant" + }, + "D9": { + "status": "used", + "source_path": "modules.varga_full.D9" + }, + "D10": { + "status": "used", + "source_path": "modules.varga_full.D10" + }, + "D2": { + "status": "used", + "source_path": "modules.varga_full.D2" + }, + "D4": { + "status": "used", + "source_path": "modules.varga_full.D4" + }, + "planet_degrees": { + "status": "used", + "source_path": "chart.planets" + }, + "house_degrees": { + "status": "used", + "source_path": "chart.houses" + }, + "dasha_boundaries": { + "status": "used", + "source_path": "modules.dasha" + }, + "dasha_sub_periods": { + "status": "used", + "source_path": "modules.dasha_sub_periods" + }, + "narayana_dasha": { + "status": "used", + "source_path": "modules.narayana_dasha" + }, + "ashtakavarga": { + "status": "used", + "source_path": "modules.ashtakavarga" + }, + "yogas": { + "status": "used", + "source_path": "modules.yogas" + }, + "UL": { + "status": "used", + "source_path": "modules.arudha_padas.UL" + }, + "A7": { + "status": "used", + "source_path": "modules.arudha_padas.A7" + }, + "A10": { + "status": "used", + "source_path": "modules.arudha_padas.A10" + }, + "D6": { + "status": "used", + "source_path": "modules.varga_full.D6" + }, + "D7": { + "status": "used", + "source_path": "modules.varga_full.D7" + }, + "D11": { + "status": "used", + "source_path": "modules.varga_full.D11" + }, + "D12": { + "status": "used", + "source_path": "modules.varga_full.D12" + }, + "D24": { + "status": "used", + "source_path": "modules.varga_full.D24" + }, + "D30": { + "status": "used", + "source_path": "modules.varga_full.D30" + } + } + } + } + } +} diff --git a/frontend/tests/report-blocked-repairs.test.ts b/frontend/tests/report-blocked-repairs.test.ts new file mode 100644 index 00000000..10705e04 --- /dev/null +++ b/frontend/tests/report-blocked-repairs.test.ts @@ -0,0 +1,208 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; +import { buildReportEvidenceBundleV2 } from "../src/lib/personal-report-generation.ts"; +import { REPORT_THEME_IDS } from "../src/lib/report-theme-evidence-plan.ts"; + +type JsonRecord = Record; + +const GOLDEN = JSON.parse(readFileSync( + new URL("./fixtures/consultation-workflow-report-blocked-repairs-golden.json", import.meta.url), + "utf8", +)) as { + themes: Record; +}; + +const SKILL = { + name: "jyotish-vedic-astrology", + version: "6.9.14", + sha256: "a".repeat(64), + sourceCommit: "b".repeat(40), +} as const; + +const SUBJECT = { + displayName: "冒烟用户", + birthTimeStatus: "accepted" as const, + birthPlaceLabel: "冒烟市", +}; + +const FOUR_THEMES = ["career", "marriage", "timing", "wealth"] as const; + +function clone(value: T): T { + return JSON.parse(JSON.stringify(value)) as T; +} + +function goldenWorkflow(theme: string): JsonRecord { + return clone(GOLDEN.themes[theme] ?? GOLDEN.themes.career); +} + +function buildBundle(themes: readonly string[], workflows?: readonly JsonRecord[]) { + return buildReportEvidenceBundleV2({ + workflows: themes.map((theme, index) => ({ + theme, + workflow: workflows?.[index] ?? goldenWorkflow(theme), + })), + subject: SUBJECT, + requestedThemes: [...themes], + reportType: "personal_full", + presentationMode: "default", + skillSnapshot: SKILL, + }); +} + +function chartModules(workflow: JsonRecord): JsonRecord { + const chart = workflow.chart as JsonRecord; + return chart.modules as JsonRecord; +} + +function executedTechniques(bundle: ReturnType): string[] { + return bundle.executionLedger + .filter((receipt) => receipt.executed && receipt.status !== "blocked") + .map((receipt) => receipt.technique) + .sort(); +} + +test("golden fixture locks the live engine varga and transits shape", () => { + const vargaFull = chartModules(GOLDEN.themes.career).varga_full as JsonRecord; + assert.ok(vargaFull.D2_Hora); + assert.ok(vargaFull.D9_Navamsa); + assert.ok(vargaFull.D10_Dasamsa); + assert.ok(vargaFull.D11_Rudramsa); + assert.ok(vargaFull.D24_Chaturvimsamsa); + for (const key of ["D2_Hora", "D9_Navamsa", "D10_Dasamsa", "D11_Rudramsa", "D24_Chaturvimsamsa"] as const) { + const varga = vargaFull[key] as JsonRecord; + const ascendant = varga.ascendant as JsonRecord; + const planets = varga.planets as JsonRecord; + assert.equal(typeof ascendant.sign, "string", `${key} ascendant.sign`); + assert.equal(typeof ascendant.sign_index, "number", `${key} ascendant.sign_index`); + assert.equal(typeof ascendant.degree, "number", `${key} ascendant.degree`); + assert.equal(varga.Ascendant, undefined, `${key} must not use the old Ascendant key as the live shape`); + assert.ok(planets.Sun && typeof (planets.Sun as JsonRecord).sign_index === "number", `${key} planets.Sun`); + assert.ok(Array.isArray(varga.house_chart)); + assert.equal((varga.house_chart as unknown[]).length, 12); + } + const transits = chartModules(GOLDEN.themes.career).transits as JsonRecord; + assert.equal(typeof transits.status, "string"); + const karakas = (chartModules(GOLDEN.themes.career).jaimini as JsonRecord).chara_karakas as JsonRecord; + assert.equal(typeof (karakas.AmK as JsonRecord).planet, "string"); + assert.equal(typeof (karakas.DK as JsonRecord).planet, "string"); +}); + +test("deriveVargaHousesFromEngine reads the live planets-dict shape and the old top-level shape", () => { + const goldenBundle = buildBundle(["wealth"], [goldenWorkflow("wealth")]); + const required = ["D1", "D2", "D9", "D10", "D11", "D24"]; + for (const id of required) { + assert.ok(goldenBundle.charts.some((chart) => chart.id === id), `golden missing ${id}`); + } + const d2 = goldenBundle.charts.find((chart) => chart.id === "D2")!; + assert.equal(d2.houses.length, 12); + assert.equal(d2.houses[0].sign, "Leo"); + assert.ok(d2.houses[0].occupants.includes("Sun")); + + const oldShape = goldenWorkflow("wealth"); + const modules = chartModules(oldShape); + // Keep the old 643f6f7a-era shape as a compatibility path: Ascendant/sign_idx + // plus top-level planet keys. Live engine responses no longer look like this. + modules.varga_full = { + D2_Hora: { + _meta: { fixture: "legacy-shape" }, + Ascendant: { sign: "Cancer", sign_idx: 3, degree_in_sign: 8.25 }, + Sun: { sign: "Leo", sign_idx: 4 }, + Moon: { sign: "Virgo", sign_idx: 5 }, + }, + D11_Rudramsa: { + Ascendant: { sign: "Scorpio", sign_idx: 7 }, + Sun: { sign: "Sagittarius", sign_idx: 8 }, + }, + }; + const oldBundle = buildBundle(["wealth"], [oldShape]); + const oldD2 = oldBundle.charts.find((chart) => chart.id === "D2"); + const oldD11 = oldBundle.charts.find((chart) => chart.id === "D11"); + assert.ok(oldD2); + assert.ok(oldD11); + assert.equal(oldD2.houses[0].sign, "Cancer"); + assert.ok(oldD2.houses[1].occupants.includes("Sun")); + assert.equal(oldD11.houses[0].sign, "Scorpio"); +}); + +test("Transit receipt upserts only when modules.transits.status is executed", () => { + const executed = buildBundle(["timing"], [goldenWorkflow("timing")]); + assert.ok(executed.claimCards.some((card) => card.theme === "timing")); + assert.equal(executed.blockedSections.some((section) => section.theme === "timing"), false); + const transit = executed.executionLedger.find((receipt) => receipt.technique === "Transit"); + assert.ok(transit); + assert.equal(transit.executed, true); + assert.equal(transit.status, "partial"); + + const missing = goldenWorkflow("timing"); + delete chartModules(missing).transits; + const missingBundle = buildBundle(["timing"], [missing]); + assert.equal(missingBundle.claimCards.some((card) => card.theme === "timing"), false); + assert.ok(missingBundle.blockedSections.some((section) => ( + section.theme === "timing" && section.reason.includes("Transit") + ))); + assert.equal( + missingBundle.executionLedger.some((receipt) => receipt.technique === "Transit" && receipt.executed), + false, + ); + + const blocked = goldenWorkflow("timing"); + (chartModules(blocked).transits as JsonRecord).status = "blocked"; + const blockedBundle = buildBundle(["timing"], [blocked]); + assert.equal(blockedBundle.claimCards.some((card) => card.theme === "timing"), false); + assert.equal( + blockedBundle.executionLedger.some((receipt) => receipt.technique === "Transit" && receipt.executed), + false, + ); +}); + +test("AmK and DK receipts require chara_karakas planet rows", () => { + const full = buildBundle(["career", "marriage"]); + assert.ok(full.claimCards.some((card) => card.theme === "career")); + assert.ok(full.claimCards.some((card) => card.theme === "marriage")); + assert.ok(executedTechniques(full).includes("AmK")); + assert.ok(executedTechniques(full).includes("DK")); + + const noKarakas = goldenWorkflow("career"); + delete (chartModules(noKarakas).jaimini as JsonRecord).chara_karakas; + const careerOnly = buildBundle(["career"], [noKarakas]); + const blocked = careerOnly.blockedSections.find((section) => section.theme === "career"); + assert.ok(blocked); + assert.ok(blocked.reason.includes("AmK")); + assert.equal(blocked.reason.includes("Transit"), false); +}); + +test("golden four-theme pipeline emits claim cards and no blocked sections", () => { + const bundle = buildBundle(FOUR_THEMES); + assert.deepEqual(bundle.claimCards.map((card) => card.theme).sort(), [...FOUR_THEMES].sort()); + assert.deepEqual(bundle.blockedSections.map((section) => section.theme), []); + const chartIds = bundle.charts.map((chart) => chart.id).sort(); + for (const id of ["D1", "D2", "D9", "D10", "D11", "D24"]) { + assert.ok(chartIds.includes(id), `charts missing ${id}: ${chartIds.join(",")}`); + } + const executed = executedTechniques(bundle); + for (const technique of ["AmK", "DK", "Transit", "D2", "D11"]) { + assert.ok(executed.includes(technique), `ledger missing executed ${technique}`); + } + assert.equal( + bundle.claimCards.some((card) => card.theme === "wealth") + && !bundle.blockedSections.some((section) => section.reason.includes("结构化分盘")), + true, + ); +}); + +test("nine requested themes close from the same golden chart layers", () => { + const bundle = buildBundle(REPORT_THEME_IDS); + const claimed = new Set(bundle.claimCards.map((card) => card.theme)); + const blocked = Object.fromEntries( + bundle.blockedSections.map((section) => [section.theme, section.reason]), + ); + const rows = REPORT_THEME_IDS.map((theme) => ({ + theme, + status: claimed.has(theme) ? "claim" : "blocked", + reason: blocked[theme] ?? null, + })); + for (const row of rows) { + assert.equal(row.status, "claim", `${row.theme} still blocked: ${row.reason}`); + } +}); diff --git a/frontend/tests/report-interpretive-facts.test.ts b/frontend/tests/report-interpretive-facts.test.ts index 228f4a99..c9031be8 100644 --- a/frontend/tests/report-interpretive-facts.test.ts +++ b/frontend/tests/report-interpretive-facts.test.ts @@ -1,4 +1,5 @@ import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; import test from "node:test"; import { buildReportEvidenceBundleV2, @@ -91,14 +92,28 @@ function machineSections(): JsonRecord { }; } -function engineVarga(ascIndex: number): JsonRecord { - return { - _meta: { fixture: true }, - Ascendant: { sign: SIGNS[ascIndex], sign_idx: ascIndex, degree_in_sign: 10.5 }, - Sun: { sign: SIGNS[ascIndex], sign_idx: ascIndex }, - Moon: { sign: SIGNS[(ascIndex + 1) % 12], sign_idx: (ascIndex + 1) % 12 }, - Mars: { sign: SIGNS[(ascIndex + 2) % 12], sign_idx: (ascIndex + 2) % 12 }, +// Previous 643f6f7a fixture used the old engine-incompatible shape: +// `{ _meta, Ascendant: { sign, sign_idx, degree_in_sign }, Sun/Moon/Mars: { sign, sign_idx } }`. +// That locked the defect this round repairs (frontend only read Ascendant/sign_idx). +// Replaced with golden-derived live `modules.varga_full` values (lowercase +// ascendant, sign_index, planets dict, house_chart). +const GOLDEN_VARGA = ( + JSON.parse(readFileSync(new URL("./fixtures/consultation-workflow-report-blocked-repairs-golden.json", import.meta.url), "utf8")) as { + themes: { career: { chart: { modules: { varga_full: Record } } } }; + } +).themes.career.chart.modules.varga_full; + +function engineVargaFromGolden(id: "D2" | "D11" | "D24"): JsonRecord { + const aliases: Record = { + D2: ["D2_Hora", "D2"], + D11: ["D11_Rudramsa", "D11"], + D24: ["D24_Chaturvimsamsa", "D24_Siddhamsa", "D24"], }; + for (const key of aliases[id]) { + const value = GOLDEN_VARGA[key]; + if (value) return value; + } + throw new Error(`golden varga ${id} missing`); } type FixtureOptions = Readonly<{ @@ -128,9 +143,9 @@ function workflowFixture(options: FixtureOptions = {}): JsonRecord { // education claim cards (Gitea run 2298). if (options.structuredVargas !== false) { modules.varga_full = { - D2: engineVarga(ASC_INDEX), - D11: engineVarga((ASC_INDEX + 2) % 12), - D24: engineVarga((ASC_INDEX + 4) % 12), + D2: engineVargaFromGolden("D2"), + D11: engineVargaFromGolden("D11"), + D24: engineVargaFromGolden("D24"), }; } if (interpretive) { diff --git a/scripts/capture_report_blocked_repairs_golden.py b/scripts/capture_report_blocked_repairs_golden.py new file mode 100644 index 00000000..8f82cc4d --- /dev/null +++ b/scripts/capture_report_blocked_repairs_golden.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 +"""Capture trimmed consultation_workflow responses for report blocked-repairs fixtures. + +Smoke birth only: 1993-06-15 10:30, lat 36.42 / lon 114.21 / tz 8. +""" +from __future__ import annotations + +import json +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "scripts")) + +from consultation_plan_contract import PLAN_VERSION, _ROUTE_CONTRACTS # noqa: E402 +from jyotish_api_server import JyotishAPIHandler # noqa: E402 + +BIRTH = { + "year": 1993, + "month": 6, + "day": 15, + "hour": 10, + "minute": 30, + "lat": 36.42, + "lon": 114.21, + "tz": 8, + "city": "Handan", +} +THEMES = ("career", "marriage", "timing", "wealth") +VARGA_KEEP = ( + "D2_Hora", "D2", + "D9_Navamsa", "D9", + "D10_Dasamsa", "D10", + "D11_Rudramsa", "D11", + "D24_Chaturvimsamsa", "D24_Siddhamsa", "D24", +) +MODULE_KEEP = ( + "varga_full", + "transits", + "jaimini", + "narayana_dasha", + "arudha_padas", + "yogas", + "ashtakavarga", + "dasha_sub_periods", +) +CONSUMER_KEEP = ( + "route", + "core_status", + "available_layers", + "missing_route_layers", + "hard_blockers", + "answer_policy", +) +CHART_KEEP = ("success", "ascendant", "planets", "houses", "dasha") + + +def _handler() -> JyotishAPIHandler: + return JyotishAPIHandler.__new__(JyotishAPIHandler) + + +def _body(theme: str) -> dict: + contract = _ROUTE_CONTRACTS[theme] + return { + **BIRTH, + "question": f"请为个人报告计算 {theme} 主题证据", + "question_text": f"请为个人报告计算 {theme} 主题证据", + "theme": list(contract.themes), + "entry_mode": "direct_chart", + "plan_version": PLAN_VERSION, + "strict_workflow_route": contract.resolved_routes[0], + "required_layers": list(contract.required_layers), + "claim_boundary": contract.claim_boundary, + "plan_depth": "standard", + "requested_domains": list(contract.requested_domains), + "timing_horizon": "next_12_months" if theme == "timing" else None, + "precision_boundary": "server_evidence_required", + "required_evidence_categories": list(contract.required_evidence_categories), + "defer_optional_external_evidence": True, + } + + +def _trim_varga(varga_full: dict) -> dict: + trimmed = {} + for key in VARGA_KEEP: + value = varga_full.get(key) + if isinstance(value, dict): + trimmed[key] = value + if trimmed: + return trimmed + # Fall back to prefix match if the live keys drifted. + for key, value in varga_full.items(): + if not isinstance(key, str) or not isinstance(value, dict): + continue + if any(key == keep or key.startswith(f"{keep.split('_')[0]}_") for keep in ("D2", "D9", "D10", "D11", "D24")): + if key.startswith(("D2", "D9", "D10", "D11", "D24")): + trimmed[key] = value + return trimmed + + +def _trim_workflow(raw: dict) -> dict: + chart = raw.get("chart") if isinstance(raw.get("chart"), dict) else {} + modules = chart.get("modules") if isinstance(chart.get("modules"), dict) else {} + kept_modules = {} + for name in MODULE_KEEP: + value = modules.get(name) + if name == "varga_full" and isinstance(value, dict): + kept_modules[name] = _trim_varga(value) + elif value is not None: + kept_modules[name] = value + kept_chart = {key: chart[key] for key in CHART_KEEP if key in chart} + if chart.get("success") is not None: + kept_chart["success"] = chart.get("success") + kept_chart["modules"] = kept_modules + consumer = raw.get("consumer_context") if isinstance(raw.get("consumer_context"), dict) else {} + machine = raw.get("machine_evidence_packet") if isinstance(raw.get("machine_evidence_packet"), dict) else {} + workflow = { + "success": bool(raw.get("success")), + "chart": kept_chart, + "consumer_context": {key: consumer[key] for key in CONSUMER_KEEP if key in consumer}, + "machine_evidence_packet": { + "sections": machine.get("sections") if isinstance(machine.get("sections"), dict) else {}, + }, + } + return _compact_workflow(workflow) + + +def _pick(row: dict, keys: tuple[str, ...]) -> dict: + return {key: row[key] for key in keys if key in row} + + +def _compact_workflow(workflow: dict) -> dict: + """Drop bulky unused fields after the extraction-layer keep list.""" + chart = workflow["chart"] + planets = chart.get("planets") + if isinstance(planets, dict): + chart["planets"] = { + name: _pick(row, ("sign", "sign_idx", "sign_index", "lon", "degree", "degree_in_sign", "house", "retrograde")) + if isinstance(row, dict) else row + for name, row in planets.items() + } + houses = chart.get("houses") + if isinstance(houses, dict): + chart["houses"] = { + key: _pick(row, ("cusp_sign", "sign", "sign_idx", "lord")) if isinstance(row, dict) else row + for key, row in houses.items() + } + dasha = chart.get("dasha") + if isinstance(dasha, dict): + periods = [ + _pick(item, ("lord", "start", "end")) + for item in (dasha.get("periods") or []) + if isinstance(item, dict) + ] + compact_dasha = {} + if periods: + compact_dasha["periods"] = periods + compact_dasha["mahadashas"] = periods + for key in ("current_md", "start_date"): + if key in dasha: + compact_dasha[key] = dasha[key] + chart["dasha"] = compact_dasha + modules = chart["modules"] + transits = modules.get("transits") + if isinstance(transits, dict): + modules["transits"] = _pick(transits, ("status", "sade_sati", "search_period", "trigger_count", "boundary")) + sav = (modules.get("ashtakavarga") or {}).get("sav") if isinstance(modules.get("ashtakavarga"), dict) else None + if isinstance(sav, dict): + modules["ashtakavarga"] = {"sav": _pick(sav, ("scores", "total"))} + yogas = modules.get("yogas") + if isinstance(yogas, dict): + rows = [ + _pick(item, ("name", "category", "hit", "planets")) + for item in (yogas.get("yogas") or []) + if isinstance(item, dict) + ] + modules["yogas"] = {"status": yogas.get("status"), "count": yogas.get("count"), "yogas": rows} + nara = modules.get("narayana_dasha") + if isinstance(nara, dict): + modules["narayana_dasha"] = _pick(nara, ("current_dasha", "lagna_sign")) + arudha = modules.get("arudha_padas") + if isinstance(arudha, dict): + padas = arudha.get("padas") if isinstance(arudha.get("padas"), dict) else {} + modules["arudha_padas"] = {"padas": {key: padas[key] for key in ("A7", "A10", "UL") if key in padas}} + jaimini = modules.get("jaimini") + if isinstance(jaimini, dict): + compact_jaimini = {} + if isinstance(jaimini.get("arudha_padas"), dict): + padas = jaimini["arudha_padas"].get("padas") if isinstance(jaimini["arudha_padas"].get("padas"), dict) else {} + compact_jaimini["arudha_padas"] = {"padas": {key: padas[key] for key in ("A7", "A10", "UL") if key in padas}} + karakas = jaimini.get("chara_karakas") + if isinstance(karakas, dict): + compact_jaimini["chara_karakas"] = { + key: _pick(row, ("planet", "degree_in_sign", "rank", "domain", "cn_name")) if isinstance(row, dict) else row + for key, row in karakas.items() + } + modules["jaimini"] = compact_jaimini + sub = modules.get("dasha_sub_periods") + if isinstance(sub, dict) and isinstance(sub.get("current"), dict): + modules["dasha_sub_periods"] = {"current": sub["current"]} + sections = workflow["machine_evidence_packet"].get("sections") + if isinstance(sections, dict): + keep = { + "D1", "D2", "D4", "D6", "D7", "D9", "D10", "D11", "D12", "D24", "D30", + "A7", "A10", "UL", "dasha_boundaries", "narayana_dasha", "yogas", "ashtakavarga", + "planet_degrees", "house_degrees", "dasha_sub_periods", + } + workflow["machine_evidence_packet"]["sections"] = {key: value for key, value in sections.items() if key in keep} + return workflow + + +def main() -> int: + handler = _handler() + out_dir = ROOT / "frontend/tests/fixtures" + out_dir.mkdir(parents=True, exist_ok=True) + payload = { + "source": "scripts/jyotish_api_server.py _compute_consultation_workflow", + "smoke_birth": {**BIRTH, "note": "fictional capture identity; not a real person"}, + "trim": { + "keep_varga_keys": list(VARGA_KEEP), + "keep_modules": list(MODULE_KEEP), + "drop": [ + "ai_prompt_pack", + "vedastro", + "varga_spectrum", + "guided_topics", + "western_spectrum", + "technique_audit_table", + ], + }, + "themes": {}, + } + for theme in THEMES: + raw = handler._compute_consultation_workflow(_body(theme)) + payload["themes"][theme] = _trim_workflow(raw) + varga = payload["themes"][theme]["chart"]["modules"].get("varga_full") or {} + transits = payload["themes"][theme]["chart"]["modules"].get("transits") or {} + jaimini = payload["themes"][theme]["chart"]["modules"].get("jaimini") or {} + print( + theme, + "success=", + payload["themes"][theme]["success"], + "varga_keys=", + sorted(varga), + "transits=", + transits.get("status"), + "karakas=", + sorted((jaimini.get("chara_karakas") or {})), + ) + dest = out_dir / "consultation-workflow-report-blocked-repairs-golden.json" + dest.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") + print("wrote", dest, "bytes", dest.stat().st_size) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/jyotish_api_server.py b/scripts/jyotish_api_server.py index 87b2e923..9e7dd3cc 100644 --- a/scripts/jyotish_api_server.py +++ b/scripts/jyotish_api_server.py @@ -1502,6 +1502,38 @@ def _attach_local_consultation_layers(handler, chart: dict, birth_payload: dict, except Exception as exc: diagnostics.append({'layer': 'arudha_padas', 'status': 'unavailable', 'reason': exc.__class__.__name__}) + existing_jaimini = modules.get('jaimini') if isinstance(modules.get('jaimini'), dict) else {} + if planets and not isinstance(existing_jaimini.get('chara_karakas'), dict): + try: + jaimini = _load_local_module('jaimini') + planet_degs = { + name: lon % 30 + for name, lon in _planet_longitudes(planets).items() + } + ck7 = jaimini.calc_chara_karaka_7(planet_degs) if planet_degs else {} + table = ck7.get('karaka_table') if isinstance(ck7, dict) else None + if isinstance(table, dict) and table: + short_names = { + 'Atmakaraka': 'AK', + 'Amatyakaraka': 'AmK', + 'Bhratrikaraka': 'BK', + 'Matrikaraka': 'MK', + 'Putrakaraka': 'PK', + 'Gnatikaraka': 'GK', + 'Darakaraka': 'DK', + } + chara_karakas = {} + for full_name, row in table.items(): + if not isinstance(row, dict): + continue + chara_karakas[full_name] = row + alias = short_names.get(full_name) + if alias: + chara_karakas[alias] = row + modules.setdefault('jaimini', {})['chara_karakas'] = chara_karakas + except Exception as exc: + diagnostics.append({'layer': 'chara_karakas', 'status': 'unavailable', 'reason': exc.__class__.__name__}) + if planets and ascendant and not isinstance(modules.get('narayana_dasha'), dict): try: narayana = _load_local_module('narayana_dasha') diff --git a/tests/test_consultation_consumer_context.py b/tests/test_consultation_consumer_context.py index 61c09db0..b7c37e93 100644 --- a/tests/test_consultation_consumer_context.py +++ b/tests/test_consultation_consumer_context.py @@ -160,6 +160,31 @@ def test_local_consultation_layers_include_yogas_transits_and_route_chara() -> N assert 'chara_dasha' not in wealth['local_consultation_layers']['available'] +def test_local_consultation_layers_attach_chara_karakas_from_jaimini() -> None: + from jaimini import calc_chara_karaka_7 + + chart = _attach_local_consultation_layers( + _handler(), + _base_chart(), + dict(_BIRTH), + {'current_date': _REFERENCE_DATE, 'strict_workflow_route': 'career'}, + ) + jaimini_mod = chart['modules']['jaimini'] + assert jaimini_mod['arudha_padas']['padas']['A10']['name'] == 'Karma Pada (A10)' + karakas = jaimini_mod['chara_karakas'] + planet_degs = { + name: float(data['lon']) % 30 + for name, data in chart['planets'].items() + } + expected = calc_chara_karaka_7(planet_degs)['karaka_table'] + assert karakas['Amatyakaraka']['planet'] == expected['Amatyakaraka']['planet'] + assert karakas['AmK']['planet'] == expected['Amatyakaraka']['planet'] + assert karakas['Darakaraka']['planet'] == expected['Darakaraka']['planet'] + assert karakas['DK']['planet'] == expected['Darakaraka']['planet'] + assert karakas['AmK']['degree_in_sign'] == expected['Amatyakaraka']['degree_in_sign'] + assert karakas['DK']['rank'] == expected['Darakaraka']['rank'] + + def test_consultation_computes_transit_trigger_windows(monkeypatch) -> None: class FakeTransit: @staticmethod