diff --git a/README.md b/README.md index e7f4109a..b8a6a929 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue)](https://www.python.org/) -[![Techniques](https://img.shields.io/badge/techniques-89-blueviolet)](references/technique_registry.json) +[![Capabilities](https://img.shields.io/badge/capabilities-89-blueviolet)](references/technique_registry.json) [![Covered](https://img.shields.io/badge/covered-79-green)](references/technique_registry.json) [![Complete](https://img.shields.io/badge/complete-10-brightgreen)](references/technique_registry.json) [![Partial](https://img.shields.io/badge/partial-0-lightgrey)](references/technique_registry.json) @@ -31,7 +31,7 @@ This is a **Vedic (Jyotish) astrology analysis system** designed for deep, auditable full-chart readings. It is NOT a simple ephemeris calculator — it is a multi-stage interpretive pipeline that: 1. **Computes** divisional charts (D1/D9/D10/...) via Swiss Ephemeris -2. **Runs** 89 registered techniques (Dashas, Yogas, Shadbala, Ashtakavarga, Transits...) +2. **Routes** 89 capability entries as a backend evidence pool (Dashas, Yogas, Shadbala, Ashtakavarga, Transits...) 3. **Routes** the analysis through strict workflow paths depending on question type (career / relationship / wealth / timing) 4. **Audits** every technique used — declaring what was called, what is complete/covered, and which limitations affect confidence 5. **Degrades gracefully** — limitations are labeled, not silently over-promising @@ -45,7 +45,7 @@ This is a **Vedic (Jyotish) astrology analysis system** designed for deep, audit | Technique Audit Table (confidence labeling) | ✅ | ❌ | ❌ | ❌ | | Capability degradation (limits are explicit) | ✅ | ❌ | ❌ | ❌ | | MEVG external verification gates | ✅ | ❌ | ❌ | ❌ | -| 89 techniques registered | ✅ | ✅ (50+) | ✅ (200+) | ✅ | +| 89 capability entries routed as a backend evidence pool | ✅ | ✅ (50+) | ✅ (200+) | ✅ | | Traditional algorithm benchmarked | ✅ mixed depth | ✅ | ✅ | ✅ | | Docker / MCP Server | ✅ | ❌ | ✅ | ❌ | | English docs / PyPI package | ✅ in progress | ✅ | ✅ | ✅ | @@ -454,7 +454,13 @@ The AI does NOT require the user to name techniques (e.g., "Chara Dasha"). It au ## Technique Coverage -Current registry count: **89 techniques** (79 covered, 10 complete, 0 partial, 0 missing). +Current registry count: **89 capability entries** (79 covered, 10 complete, 0 partial, 0 missing). + +These entries are a **backend evidence pool**, not a flat list of 89 user-facing +prediction sources. Ordinary users see topic-level conclusions and evidence +summaries. The question-domain router selects a small primary chain, then uses +supporting indicators only to raise/lower confidence. Audit-only and alias +entries cannot affect astrological conclusions. The table below lists representative high-value entries. Treat `references/technique_registry.json` as the source of truth for the full diff --git a/references/technique_registry.json b/references/technique_registry.json index 6e108dc9..70ed0198 100644 --- a/references/technique_registry.json +++ b/references/technique_registry.json @@ -44,7 +44,16 @@ "modules.chart" ], "audit_label": "D1/Rashi", - "missing_impact": "No reliable static chart basis." + "missing_impact": "No reliable static chart basis.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "d9_navamsa": { "name": "D9 / Navamsa", @@ -68,7 +77,16 @@ "modules.d9_navamsa_expanded" ], "audit_label": "D9/Navamsa", - "missing_impact": "Inner strength and marriage/dharma layer incomplete." + "missing_impact": "Inner strength and marriage/dharma layer incomplete.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "d10_dasamsa": { "name": "D10 / Dasamsa", @@ -89,7 +107,16 @@ "modules.varga_full.D10_Dasamsa" ], "audit_label": "D10/Dasamsa", - "missing_impact": "Career-specific varga layer missing; career timing confidence must be capped." + "missing_impact": "Career-specific varga layer missing; career timing confidence must be capped.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "vimshottari_dasha": { "name": "Vimshottari Dasha", @@ -109,7 +136,16 @@ "modules.dasha" ], "audit_label": "Vimshottari", - "missing_impact": "Primary timing layer unavailable." + "missing_impact": "Primary timing layer unavailable.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "ashtottari_dasha": { "name": "Ashtottari Dasha / 108年周期", @@ -129,7 +165,16 @@ "modules.ashtottari_dasha" ], "audit_label": "Ashtottari", - "missing_impact": "Nakshatra-based conditional timing layer unavailable for qualifying charts." + "missing_impact": "Nakshatra-based conditional timing layer unavailable for qualifying charts.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "yogini_dasha": { "name": "Yogini Dasha / 36年周期", @@ -149,7 +194,16 @@ "modules.yogini_dasha" ], "audit_label": "Yogini", - "missing_impact": "Yogini Dasha 已可输出,但起运边界、子运切分与传统软件对齐度仍需更多外部 benchmark,细粒度事件定时置信度受限。" + "missing_impact": "Yogini Dasha 已可输出,但起运边界、子运切分与传统软件对齐度仍需更多外部 benchmark,细粒度事件定时置信度受限。", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "kalachakra_dasha": { "name": "Kalachakra Dasha / 时轮大运", @@ -170,7 +224,16 @@ ], "audit_label": "Kalachakra", "missing_impact": "Kalachakra 已可输出 Savya/Apasavya 模式、当前主周期与 Rashi-year 序列,但 classical pada mapping、子运细化与传统软件黑盒对齐仍需继续成熟化。", - "limitation": "当前实现已接入 full-reading 与多系统 Dasha convergence,可作为补充 timing 证据使用;但起始 pada 映射与完整传统细则仍为简化版,不能单独承担最终事件定时结论。" + "limitation": "当前实现已接入 full-reading 与多系统 Dasha convergence,可作为补充 timing 证据使用;但起始 pada 映射与完整传统细则仍为简化版,不能单独承担最终事件定时结论。", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "dasha_sandhi": { "name": "Dasha Sandhi", @@ -189,7 +252,16 @@ "modules.dasha_sandhi" ], "audit_label": "Dasha Sandhi", - "missing_impact": "Transition windows may be overstated or understated." + "missing_impact": "Transition windows may be overstated or understated.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "jaimini_chara_dasha": { "name": "Jaimini / Chara Dasha", @@ -211,7 +283,16 @@ ], "audit_label": "Jaimini/Chara", "missing_impact": "Rashi-based timing confirmation provides cross-validation for Vimshottari Dasha, Dasha Sandhi, transit, D10/A10 and Ashtakavarga.", - "limitation": "v6.1.12: KN Rao method正式benchmark通过(120/120 sign=100%, 110/120 duration=91.67%, overall=95.83%≥95%)。剩余~4.2%差异来自Aquarius/Scorpio的Rahu/Ketu共主动态判定(PyJHora用_stronger_planet_new完整尊严比较链),当前使用传统宫主(Saturn/Mars)。已记录为未来优化项。Chara Dasha作为标准应期模块可正常使用。" + "limitation": "v6.1.12: KN Rao method正式benchmark通过(120/120 sign=100%, 110/120 duration=91.67%, overall=95.83%≥95%)。剩余~4.2%差异来自Aquarius/Scorpio的Rahu/Ketu共主动态判定(PyJHora用_stronger_planet_new完整尊严比较链),当前使用传统宫主(Saturn/Mars)。已记录为未来优化项。Chara Dasha作为标准应期模块可正常使用。", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "karakamsha_ak_amk": { "name": "Karakamsha / AK / AmK", @@ -233,7 +314,16 @@ "modules.jaimini.karakamsha" ], "audit_label": "AK/AmK/Karakamsha", - "missing_impact": "Jaimini career/soul indicator layer incomplete." + "missing_impact": "Jaimini career/soul indicator layer incomplete.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "a10_karma_pada": { "name": "A10 / Karma Pada / Rajya Pada", @@ -253,7 +343,16 @@ "modules.special_lagnas.A10_Karma_Pada" ], "audit_label": "A10/Karma Pada", - "missing_impact": "Career public-image layer incomplete." + "missing_impact": "Career public-image layer incomplete.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "argala": { "name": "Argala", @@ -274,7 +373,16 @@ "modules.argala" ], "audit_label": "Argala", - "missing_impact": "Intervention/blocking layer missing." + "missing_impact": "Intervention/blocking layer missing.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "badhaka": { "name": "Badhaka / Obstacle House-Lord", @@ -294,7 +402,16 @@ "scripts/yoga_engine.py:is_badhaka" ], "audit_label": "Badhaka", - "missing_impact": "Obstacle-house logic missing, so blockage, interference and frustration timing are under-modeled." + "missing_impact": "Obstacle-house logic missing, so blockage, interference and frustration timing are under-modeled.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "upagraha_gulika_maandi": { "name": "Upagraha / Gulika / Maandi", @@ -317,7 +434,16 @@ "scripts/prashna.py:calc_gulika_simple" ], "audit_label": "Upagraha/Gulika/Maandi", - "missing_impact": "Sensitive malefic shadow points are unavailable, weakening pressure, delay and vulnerability interpretation." + "missing_impact": "Sensitive malefic shadow points are unavailable, weakening pressure, delay and vulnerability interpretation.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "sphuta_trisphuta_family": { "name": "Sphuta / Trisphuta / Catusphuta / Pancasphuta / Prana-Deha-Mrityu", @@ -342,7 +468,16 @@ "kp_horary.sphutas" ], "audit_label": "Sphuta/Trisphuta", - "missing_impact": "Prashna energy convergence and life-sensitivity markers are absent, leaving horary and life-risk reading thinner than classical toolchains." + "missing_impact": "Prashna energy convergence and life-sensitivity markers are absent, leaving horary and life-risk reading thinner than classical toolchains.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "deha_jeeva": { "name": "Deha / Jeeva Framework", @@ -367,7 +502,16 @@ ], "audit_label": "Deha/Jeeva", "missing_impact": "Without Deha/Jeeva routing, body-vs-consciousness event classification and some classical alternative Dasha judgments stay shallow.", - "note": "Current role is primarily interpretive and workflow-level. Keep maturity at covered until more explicit engine-level outputs and external cases are frozen." + "note": "Current role is primarily interpretive and workflow-level. Keep maturity at covered until more explicit engine-level outputs and external cases are frozen.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "shadbala": { "name": "Shadbala", @@ -390,7 +534,16 @@ "missing_impact": "Planetary strength claims are quantitatively anchored only as an internally consistent reference, not as externally calibrated absolute Parashara Shadbala.", "limitation": "Round 9 internal invariant benchmark passed 1200/1200 checks and full-reading matches the shadbala command. However scripts/shadbala.py still uses simplified Nathonnata Bala, approximate Saptavargaja sub-vargas, Chesta speed buckets and simplified Drik aspect weights. Use for relative strength ranking with confidence cap until an external full Shadbala table benchmark is frozen.", "version": "6.9.3", - "note": "v6.9.3 — Sputa Drishti精确相位 + Yuddha Bala + BPHS 1200/1200校准" + "note": "v6.9.3 — Sputa Drishti精确相位 + Yuddha Bala + BPHS 1200/1200校准", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "ashtakavarga": { "name": "Ashtakavarga", @@ -411,7 +564,16 @@ "modules.ashtakavarga" ], "audit_label": "Ashtakavarga", - "missing_impact": "covered: SAV/BAV/PAV/Sodhita/Yoga Pinda are exposed through /api/ashtakavarga and the Skill workbench." + "missing_impact": "covered: SAV/BAV/PAV/Sodhita/Yoga Pinda are exposed through /api/ashtakavarga and the Skill workbench.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "avastha": { "name": "Avastha", @@ -430,7 +592,16 @@ "modules.avasthas" ], "audit_label": "Avastha", - "missing_impact": "Planet condition/state layer missing." + "missing_impact": "Planet condition/state layer missing.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "combustion": { "name": "Combustion / Asta", @@ -452,7 +623,16 @@ "modules.chart.planets.*.combust" ], "audit_label": "Combustion", - "missing_impact": "Planetary independence vs solar absorption is not tracked, weakening dignity and expression analysis." + "missing_impact": "Planetary independence vs solar absorption is not tracked, weakening dignity and expression analysis.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "graha_yuddha": { "name": "Graha Yuddha / Planetary War", @@ -474,7 +654,16 @@ "scripts/yoga_expansion.py:detect_graha_yuddha" ], "audit_label": "Graha Yuddha", - "missing_impact": "Planetary contest and winner-loser dynamics are absent, reducing conflict and strength nuance." + "missing_impact": "Planetary contest and winner-loser dynamics are absent, reducing conflict and strength nuance.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "gandanta": { "name": "Gandanta", @@ -495,7 +684,16 @@ "scripts/yoga_expansion.py:detect_gandanta" ], "audit_label": "Gandanta", - "missing_impact": "Water-fire knot transitions are not surfaced, weakening crisis and karmic transition interpretation." + "missing_impact": "Water-fire knot transitions are not surfaced, weakening crisis and karmic transition interpretation.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "moolatrikona": { "name": "Moolatrikona / 原始三方", @@ -520,7 +718,16 @@ ], "audit_label": "Moolatrikona", "missing_impact": "Without a first-class Moolatrikona layer, dignity ranking, Sthana Bala nuance and several yoga-strength judgments become too coarse.", - "note": "Degree-band details vary by lineage. Current skill already uses Moolatrikona in dignity reasoning and strength interpretation, but should keep lineage notes explicit." + "note": "Degree-band details vary by lineage. Current skill already uses Moolatrikona in dignity reasoning and strength interpretation, but should keep lineage notes explicit.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "vargottama": { "name": "Vargottama", @@ -539,7 +746,16 @@ "modules.vargottama" ], "audit_label": "Vargottama", - "missing_impact": "D1-D9 consistency strength may be undercounted." + "missing_impact": "D1-D9 consistency strength may be undercounted.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "pushkara": { "name": "Pushkara Navamsa / Pushkara Bhaga", @@ -560,7 +776,16 @@ "modules.pushkara" ], "audit_label": "Pushkara", - "missing_impact": "D9 grace/support layer may be undercounted." + "missing_impact": "D9 grace/support layer may be undercounted.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "shodasavarga": { "name": "Shodasavarga / 十六分盘体系", @@ -584,7 +809,16 @@ ], "audit_label": "Shodasavarga", "missing_impact": "Without a first-class 16-varga map, divisional interpretation and traditional weighting logic remain fragmented across isolated chart outputs.", - "note": "Registry entry covers the traditional 16-varga framework and teaching layer; not a claim that every Vimsopaka weighting path is already fully benchmark-closed." + "note": "Registry entry covers the traditional 16-varga framework and teaching layer; not a claim that every Vimsopaka weighting path is already fully benchmark-closed.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "varga_dignity": { "name": "Varga Dignity / 分盘尊严等级", @@ -606,7 +840,16 @@ "modules.varga_strength_overview" ], "audit_label": "Varga Dignity", - "missing_impact": "Without a first-class Varga Dignity entry, Simhasana/Parijata/Shridhama-style honor ladders remain buried inside divisional doctrine and are easy to omit in deep reading." + "missing_impact": "Without a first-class Varga Dignity entry, Simhasana/Parijata/Shridhama-style honor ladders remain buried inside divisional doctrine and are easy to omit in deep reading.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "vimsopaka_bala": { "name": "Vimsopaka Bala / 分盘综合力量", @@ -630,7 +873,16 @@ ], "audit_label": "Vimsopaka Bala", "missing_impact": "Without Vimsopaka Bala, cross-varga strength synthesis stays under-modeled, weakening Dasha-lord judgment and deep divisional confidence calibration.", - "note": "Keep maturity at covered: the interpretive layer and reference doctrine exist, but external benchmark closure for all weighting schemes is still incomplete." + "note": "Keep maturity at covered: the interpretive layer and reference doctrine exist, but external benchmark closure for all weighting schemes is still incomplete.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "navamsa_64th": { "name": "64th Navamsa / Chatushashti Navamsa", @@ -651,7 +903,16 @@ "scripts.varga.calc_64th_navamsa" ], "audit_label": "64th Navamsa", - "missing_impact": "A classical stress-sensitive Navamsa trigger is unavailable, weakening vulnerability and event-pressure analysis." + "missing_impact": "A classical stress-sensitive Navamsa trigger is unavailable, weakening vulnerability and event-pressure analysis.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "drekkana_22nd": { "name": "22nd Drekkana", @@ -672,7 +933,16 @@ "scripts.varga.calc_22nd_drekkana" ], "audit_label": "22nd Drekkana", - "missing_impact": "A classical danger-sensitive Drekkana trigger is absent, weakening accident and adversity screening." + "missing_impact": "A classical danger-sensitive Drekkana trigger is absent, weakening accident and adversity screening.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "bhrigu_bindu": { "name": "Bhrigu Bindu", @@ -693,7 +963,16 @@ "scripts.varga.calc_bhrigu_bindu" ], "audit_label": "Bhrigu Bindu", - "missing_impact": "A commonly used Moon-Rahu destiny trigger is unavailable, weakening event-sensitive reading depth." + "missing_impact": "A commonly used Moon-Rahu destiny trigger is unavailable, weakening event-sensitive reading depth.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "sarpa_drekkana": { "name": "Sarpa Drekkana", @@ -714,7 +993,16 @@ "scripts.varga.calc_sarpa_drekkana" ], "audit_label": "Sarpa Drekkana", - "missing_impact": "A classical toxic-crisis Drekkana marker is absent, thinning advanced risk and temperament screening." + "missing_impact": "A classical toxic-crisis Drekkana marker is absent, thinning advanced risk and temperament screening.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "bhava_chalit": { "name": "Bhava Chalit", @@ -737,7 +1025,16 @@ "missing_impact": "covered", "limitation": "Complete in v6.9.13: house cusps, Bhava Sandhi boundaries, planet reassignment, Rashi-vs-Bhava shift detection.", "version": "6.9.13", - "note": "v6.9.13 — bhava_chalit.py 完整行星重分配 + cross_house_check" + "note": "v6.9.13 — bhava_chalit.py 完整行星重分配 + cross_house_check", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "sudarshana_chakra": { "name": "Sudarshana Chakra", @@ -761,7 +1058,16 @@ "missing_impact": "covered", "limitation": "Complete in v6.9.14: traditional triple-lagna confirmation with Ascendant/Moon/Sun reference charts and life-area convergence scoring.", "version": "6.9.14", - "note": "v6.9.14 — sudarshana_chakra.py 三参考点盘(Lagna+Chandra+Surya) + 收敛分析" + "note": "v6.9.14 — sudarshana_chakra.py 三参考点盘(Lagna+Chandra+Surya) + 收敛分析", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "dispositor_chain": { "name": "Dispositor Chain / 定位星链", @@ -782,7 +1088,16 @@ "modules.final_dispositors" ], "audit_label": "Dispositor Chain", - "missing_impact": "Planet energy flow / final dispositor analysis incomplete." + "missing_impact": "Planet energy flow / final dispositor analysis incomplete.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "inter_chart_linkage": { "name": "Inter-chart Linkage / 分盘间飞星", @@ -802,7 +1117,16 @@ "modules.inter_chart_linkage" ], "audit_label": "Inter-chart Linkage", - "missing_impact": "Cross-chart planet linkage (D1->D9->D10) analysis incomplete." + "missing_impact": "Cross-chart planet linkage (D1->D9->D10) analysis incomplete.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "tajika_yogas": { "name": "Tajika Yogas / 年运盘格局", @@ -823,7 +1147,16 @@ "audit_label": "Tajika Yogas", "missing_impact": "Tajika year-chart yoga detection incomplete; annual timing confidence capped.", "version": "7.0", - "note": "v7.0 — 10种年度Yoga完整检测(Itasala/Ishkavala/Vasala/Tambira/Kambira/Dakshina/Vama/Ubhaya/Vedha/Kuta)+Radda+Tajika容许度+Vedha敏感点表+经典相位规则" + "note": "v7.0 — 10种年度Yoga完整检测(Itasala/Ishkavala/Vasala/Tambira/Kambira/Dakshina/Vama/Ubhaya/Vedha/Kuta)+Radda+Tajika容许度+Vedha敏感点表+经典相位规则", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "sahams": { "name": "Sahams / 特殊点", @@ -845,7 +1178,16 @@ "missing_impact": "Sahams 已有输出,但 Tajika/事件定时里的解释层仍应作为辅助证据,不能单独承担精确落点结论。", "limitation": "Sahams 当前已扩展到 36 个常见点位,但解释层、权重口径与传统软件黑盒一致性仍未完成系统外部对标,不宜单独作为精确事件定位依据。", "version": "6.9.3", - "note": "v6.9.3 — tajika.py 从 7 扩展到 36 种 Saham(含 Putra/Jnana/Moksha/Dhan/Maya 等),但解释成熟度仍以 covered 管理" + "note": "v6.9.3 — tajika.py 从 7 扩展到 36 种 Saham(含 Putra/Jnana/Moksha/Dhan/Maya 等),但解释成熟度仍以 covered 管理", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "darakaraka": { "name": "Darakaraka (DK) / 配偶星", @@ -868,7 +1210,16 @@ ], "audit_label": "Darakaraka (DK)", "missing_impact": "Marriage/partner analysis incomplete without DK.", - "validation_note": "v6.1.10 wires scripts/darakaraka_reader.py into full-reading and thematic reports; output includes DK planet/sign/house, D9 dignity, conjunctions, quality score and narrative." + "validation_note": "v6.1.10 wires scripts/darakaraka_reader.py into full-reading and thematic reports; output includes DK planet/sign/house, D9 dignity, conjunctions, quality score and narrative.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "raj_yoga": { "name": "Raj Yoga / 王者瑜伽", @@ -888,7 +1239,16 @@ "audit_label": "Raj Yoga", "missing_impact": "Power/status timing confidence capped without Raj Yoga detection.", "version": "7.0", - "note": "v7.0 — 5种Raj Yoga(双重宫主/同宫/互看/互容/Viparita)+角宫主×三方宫主完整组合+dashaflow参考对齐" + "note": "v7.0 — 5种Raj Yoga(双重宫主/同宫/互看/互容/Viparita)+角宫主×三方宫主完整组合+dashaflow参考对齐", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "dhana_yoga": { "name": "Dhana Yoga / 财富瑜伽", @@ -908,7 +1268,16 @@ "audit_label": "Dhana Yoga", "missing_impact": "Wealth timing confidence capped without Dhana Yoga.", "version": "7.0", - "note": "v7.0 — 5种Dhana Yoga(2+11宫主强/5+9宫主/2+9宫主/11+9宫主/财富宫主+吉星)+dashaflow参考对齐" + "note": "v7.0 — 5种Dhana Yoga(2+11宫主强/5+9宫主/2+9宫主/11+9宫主/财富宫主+吉星)+dashaflow参考对齐", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "solar_lunar_yogas": { "name": "Solar/Lunar Yogas (Veshi/Voshi/Ubhayachari/Sunapha/Anapha/Durudhura)", @@ -928,7 +1297,16 @@ ], "audit_label": "Solar/Lunar Yogas", "missing_impact": "Solar/Lunar Yogas not detected.", - "limitation": "Restored from Git dangling commit f19369c. Algorithm-based detection in yoga_engine.py." + "limitation": "Restored from Git dangling commit f19369c. Algorithm-based detection in yoga_engine.py.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "pancha_mahapurusha": { "name": "Pancha Mahapurusha Yoga / 五王瑜伽", @@ -949,7 +1327,16 @@ "missing_impact": "Personality strength assessment incomplete.", "limitation": "五王瑜伽(Ruchaka、Bhadra 等)检测基于基础规则,但未完整覆盖所有变体条件(如燃烧、逆行、受克时的 Yoga 失效条件)。与 PyJHora 的 284 种瑜伽体系对齐度未经验证。只能作为人格特质的辅助参考。", "version": "6.9.3", - "note": "v6.9.3 — pancha_mahapurusha.py 5Yoga + 4层失效条件(燃烧/逆行/受克/Navamsa)" + "note": "v6.9.3 — pancha_mahapurusha.py 5Yoga + 4层失效条件(燃烧/逆行/受克/Navamsa)", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "nicha_bhanga_raj": { "name": "Neecha Bhanga Raj Yoga / 落陷解除王者瑜伽", @@ -969,7 +1356,16 @@ "audit_label": "Neecha Bhanga", "missing_impact": "Debilitation recovery analysis incomplete.", "version": "7.0", - "note": "v7.0 — 6种解除条件(dispositor在Lagna角宫/Moon角宫+擢升星主在角宫+互容+Navamsa入庙)+量化解除程度+dashaflow参考对齐" + "note": "v7.0 — 6种解除条件(dispositor在Lagna角宫/Moon角宫+擢升星主在角宫+互容+Navamsa入庙)+量化解除程度+dashaflow参考对齐", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "neechabhanga": { "name": "Neechabhanga / 落陷取消(别名入口)", @@ -991,7 +1387,16 @@ ], "audit_label": "Neechabhanga", "missing_impact": "Debilitation cancellation logic becomes harder to discover when users ask with the common spelling only.", - "note": "Alias entry to keep common terminology aligned with nicha_bhanga_raj. Do not interpret this alias as a separate extra technique." + "note": "Alias entry to keep common terminology aligned with nicha_bhanga_raj. Do not interpret this alias as a separate extra technique.", + "entry_type": "alias_entry", + "evidence_role": "alias", + "user_visibility": "hidden", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Alias/discoverability entry only; it must not be counted as an independent prediction source." }, "mangal_dosha": { "name": "Mangal Dosha / 火星煞", @@ -1009,7 +1414,16 @@ "modules.yogas_doshas.mangal_dosha" ], "audit_label": "Mangal Dosha", - "missing_impact": "Marriage difficulty assessment incomplete without Mangal Dosha." + "missing_impact": "Marriage difficulty assessment incomplete without Mangal Dosha.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "kaal_sarp_dosha": { "name": "Kaal Sarp Dosha / 时间蛇煞", @@ -1027,7 +1441,16 @@ "modules.yogas_doshas.kaal_sarp_dosha" ], "audit_label": "Kaal Sarp Dosha", - "missing_impact": "Obstacle analysis incomplete without Kaal Sarp." + "missing_impact": "Obstacle analysis incomplete without Kaal Sarp.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "pitra_dosha": { "name": "Pitra Dosha / 父辈煞", @@ -1045,7 +1468,16 @@ "modules.yogas_doshas.pitra_dosha" ], "audit_label": "Pitra Dosha", - "missing_impact": "Ancestor karma analysis incomplete." + "missing_impact": "Ancestor karma analysis incomplete.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "sade_sati": { "name": "Sade Sati / 土星七年", @@ -1066,7 +1498,16 @@ "missing_impact": "Saturn pressure timing incomplete.", "limitation": "Sade Sati 当前按土星经过月亮前后星座的简化模型计算,未完整覆盖全部影响条件(如土星在 Kendra 时的强度变化、Ashtakavarga 对 Sade Sati 的修正、Kantaka Shani 细分阶段)。压力程度评估为近似值,不宜作为精确事件预测依据。", "version": "6.9.3", - "note": "v6.9.3 — sade_sati.py 三阶段(Rising/Peak/Setting) + Kantaka Shani" + "note": "v6.9.3 — sade_sati.py 三阶段(Rising/Peak/Setting) + Kantaka Shani", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "arudha_lagna": { "name": "Arudha Lagna (AL) / 镜像上升", @@ -1084,7 +1525,16 @@ "modules.yogas_doshas.arudha_lagna" ], "audit_label": "Arudha Lagna", - "missing_impact": "Public image analysis incomplete without AL." + "missing_impact": "Public image analysis incomplete without AL.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "upapada_lagna": { "name": "Upapada Lagna (UL) / 配偶镜像上升", @@ -1102,7 +1552,16 @@ "modules.yogas_doshas.upapada_lagna" ], "audit_label": "Upapada Lagna", - "missing_impact": "Marriage quality analysis incomplete without UL." + "missing_impact": "Marriage quality analysis incomplete without UL.", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "special_lagnas_extended": { "name": "Special Lagnas / HL GL VL PP ViL", @@ -1128,7 +1587,16 @@ "special_lagnas.ViL" ], "audit_label": "Special Lagnas", - "missing_impact": "Special Lagna timing, status and prosperity sub-angles are thinner without HL/GL/VL/PP/ViL." + "missing_impact": "Special Lagna timing, status and prosperity sub-angles are thinner without HL/GL/VL/PP/ViL.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "special_lagnas": { "name": "Special Lagnas / 特殊上升点(别名入口)", @@ -1156,7 +1624,16 @@ ], "audit_label": "Special Lagnas", "missing_impact": "Important prosperity/status/timing sub-ascendants become harder to discover when users ask for special lagnas by the common umbrella term.", - "note": "Alias entry aligned to special_lagnas_extended; not a separate additional calculation family." + "note": "Alias entry aligned to special_lagnas_extended; not a separate additional calculation family.", + "entry_type": "alias_entry", + "evidence_role": "alias", + "user_visibility": "hidden", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Alias/discoverability entry only; it must not be counted as an independent prediction source." }, "tithi_lord": { "name": "Tithi Lord / 月日守护星", @@ -1177,7 +1654,16 @@ "audit_label": "Tithi Lord", "missing_impact": "Tithi Lord 分析不完整,Prashna 问卜时机判断受限。", "version": "7.0", - "note": "v7.0 — 完整30个Tithi名称+5类分类(Nanda/Bhadra/Jaya/Rikta/Purna)+适忌活动表+落宫强度评估+Prashna分类匹配+jyotishganit参考对齐" + "note": "v7.0 — 完整30个Tithi名称+5类分类(Nanda/Bhadra/Jaya/Rikta/Purna)+适忌活动表+落宫强度评估+Prashna分类匹配+jyotishganit参考对齐", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "pancha_pakshi": { "name": "Pancha Pakshi / 五鸟系统", @@ -1198,7 +1684,16 @@ "audit_label": "Pancha Pakshi", "missing_impact": "Pancha Pakshi 已可输出基础鸟态与活动矩阵,但 Tamil 传统时机细则、地域化口径与真实案例闭环仍不足,结论应保留成熟度边界。", "version": "7.0", - "note": "v7.0 — 已实现 5x5 活动矩阵、星期 Yama 偏移、鸟间相克互动与 weekday 参数支持;输出可用但整体成熟度仍按 covered 管理" + "note": "v7.0 — 已实现 5x5 活动矩阵、星期 Yama 偏移、鸟间相克互动与 weekday 参数支持;输出可用但整体成熟度仍按 covered 管理", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "rashi_tulya_navamsa": { "name": "Rashi Tulya Navamsa / 本命对分盘分析", @@ -1224,7 +1719,16 @@ "limitation": "Rashi Tulya Navamsa 分析当前基于 D1 与 D9 同宫行星的简单对比,未完整覆盖所有变体条件(如行星在 D9 中的精确度数对比、Vargottama 与非 Vargottama 的混合情况)。婚姻和内在潜力的深度解读应结合更多分盘(D7、D12)交叉验证。", "validation_note": "v6.1.10 exposes RTN evidence to thematic reports: relationship mapping, curse-yoga warnings and Guna balance are injected from modules.rashi_tulya_navamsa.", "version": "6.9.3", - "note": "v6.9.3 — 已接入 full-reading 流程" + "note": "v6.9.3 — 已接入 full-reading 流程", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "partial", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "marriage_counting": { "name": "Marriage Counting Method / 婚姻计数法", @@ -1247,7 +1751,16 @@ "audit_label": "Marriage Counting", "missing_impact": "婚姻数量判断不完整,关系模式分析受限。", "version": "7.0", - "note": "v7.0 — Parivartana自动重算(原TODO已实现)+D9完整评估(Venus/Mars/Jupiter/7宫主/Rahu-Ketu)+每段关系质量预测+5级评级系统" + "note": "v7.0 — Parivartana自动重算(原TODO已实现)+D9完整评估(Venus/Mars/Jupiter/7宫主/Rahu-Ketu)+每段关系质量预测+5级评级系统", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "trimshamsa_d30": { "name": "Trimshamsa D30 / 三十分盘", @@ -1270,7 +1783,16 @@ "audit_label": "D30 Trimshamsa", "missing_impact": "D30 灾难分析不完整,危机事件判断受限。", "version": "7.0", - "note": "v7.0 — Parashara经典规则修正(奇偶星座分区法,非简单30等分循环)+D30宫位推算+行星状态分析+凶星集中度分析+完整婚姻危机评估+jyotishganit参考对齐" + "note": "v7.0 — Parashara经典规则修正(奇偶星座分区法,非简单30等分循环)+D30宫位推算+行星状态分析+凶星集中度分析+完整婚姻危机评估+jyotishganit参考对齐", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "muntha": { "name": "Muntha / 年运之主 (Tajika)", @@ -1291,7 +1813,16 @@ "modules.muntha" ], "audit_label": "Muntha", - "missing_impact": "Varshaphala 年运盘核心指标缺失,年度主题判断受限。" + "missing_impact": "Varshaphala 年运盘核心指标缺失,年度主题判断受限。", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "solar_return": { "name": "Solar Return / Varshaphala (Tajika)", @@ -1314,7 +1845,16 @@ "modules.muntha" ], "audit_label": "Solar Return Varshaphala", - "missing_impact": "Varshaphala/Tajika 已可输出年盘骨架、Muntha、Mudda Dasha 与年度 Yoga,但年度事件裁决深度与 Saham 权重仍需继续闭环。" + "missing_impact": "Varshaphala/Tajika 已可输出年盘骨架、Muntha、Mudda Dasha 与年度 Yoga,但年度事件裁决深度与 Saham 权重仍需继续闭环。", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "prashna_integration": { "name": "Prashna Integration / 问事占星接入", @@ -1335,7 +1875,16 @@ "audit_label": "Prashna Integration", "missing_impact": "Prashna 已接入 full-reading,但问事分支的传统判断链、时机裁决与外部实盘闭环仍不均匀。", "version": "7.0", - "note": "v7.0 — KP Sublord完整3层判定(Star/Sub/Sub-Sub)+Nadi Prashna(Moon-Jupiter角度)+Sphuta(Gulika/Yamaghantaka)+时机评分系统+dashaflow/jyotishganit参考对齐" + "note": "v7.0 — KP Sublord完整3层判定(Star/Sub/Sub-Sub)+Nadi Prashna(Moon-Jupiter角度)+Sphuta(Gulika/Yamaghantaka)+时机评分系统+dashaflow/jyotishganit参考对齐", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "bhrigu_pada_dasha": { "name": "Bhrigu Pada Dasha / 足步推进法", @@ -1358,7 +1907,16 @@ "audit_label": "Bhrigu Pada Dasha", "missing_impact": "Bhrigu 足步推进法缺失,婚姻时机精确预测受限(通用近似版已实现)。", "version": "7.0", - "note": "v7.0 — BCP自然周期法完整实现+完整Dasha序列(0-80岁)+Nakshatra级推进+多行星推进+Vimshottari交叉验证接口+D9完整验证(含Venus质量评估)" + "note": "v7.0 — BCP自然周期法完整实现+完整Dasha序列(0-80岁)+Nakshatra级推进+多行星推进+Vimshottari交叉验证接口+D9完整验证(含Venus质量评估)", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "narayana_dasha": { "name": "Narayana Dasha (Rishi Dasha / Padakrama Dasha)", @@ -1380,7 +1938,16 @@ "modules.narayana_dasha" ], "audit_label": "Narayana Dasha", - "missing_impact": "Narayana Dasha 已可输出主序列,但不同传统口径、解释层权重与外部黑盒对标仍需继续沉淀。" + "missing_impact": "Narayana Dasha 已可输出主序列,但不同传统口径、解释层权重与外部黑盒对标仍需继续沉淀。", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "muhurta": { "name": "Muhurta (Panchanga / Auspicious Timing)", @@ -1405,7 +1972,16 @@ "modules.muhurta" ], "audit_label": "Muhurta", - "missing_impact": "Muhurta 已可运行,但复杂活动类型、长时间窗筛选和传统择时解释层仍需继续扩深。" + "missing_impact": "Muhurta 已可运行,但复杂活动类型、长时间窗筛选和传统择时解释层仍需继续扩深。", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "nakshatra_advanced": { "name": "Nakshatra Advanced / 星宿进阶(Tara Bala + Chandra Bala + Sub-Lord)", @@ -1434,7 +2010,16 @@ "modules.nakshatra_advanced.tara_chandra_combined" ], "audit_label": "Nakshatra Advanced", - "missing_impact": "N/A - implemented in v6.0.22" + "missing_impact": "N/A - implemented in v6.0.22", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "tara_bala": { "name": "Tara Bala / Tarabala / 星宿力", @@ -1460,7 +2045,16 @@ ], "audit_label": "Tara Bala", "missing_impact": "Without a first-class Tara Bala entry, personalized Muhurta filtering and Nakshatra-based caution windows stay hidden behind generic Nakshatra outputs.", - "note": "This is a first-class view over the existing Nakshatra Advanced layer, not a claim that every Navatara branch has already been benchmark-closed." + "note": "This is a first-class view over the existing Nakshatra Advanced layer, not a claim that every Navatara branch has already been benchmark-closed.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "chandra_bala": { "name": "Chandra Bala / 月亮力", @@ -1484,7 +2078,16 @@ "modules.nakshatra_advanced.tara_chandra_combined" ], "audit_label": "Chandra Bala", - "missing_impact": "Without a first-class Chandra Bala entry, Moon-relative suitability and emotional timing filters remain hidden behind a generic advanced Nakshatra surface." + "missing_impact": "Without a first-class Chandra Bala entry, Moon-relative suitability and emotional timing filters remain hidden behind a generic advanced Nakshatra surface.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "navatara": { "name": "Navatara / 九星链", @@ -1509,7 +2112,16 @@ ], "audit_label": "Navatara", "missing_impact": "Without a first-class Navatara entry, 27-star three-cycle grouping remains invisible in the skill map even when related Tara layers already exist.", - "note": "Current maturity reflects doctrinal and workflow coverage; treat as covered until a dedicated structured Navatara output surface is frozen." + "note": "Current maturity reflects doctrinal and workflow coverage; treat as covered until a dedicated structured Navatara output surface is frozen.", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "nakshatra_dasha": { "name": "Nakshatra Dasha / 星宿大运推演(Ashtottari + Nakshatra-level Vimshottari)", @@ -1537,7 +2149,16 @@ "modules.nakshatra_dasha.transit_overlay" ], "audit_label": "Nakshatra Dasha", - "missing_impact": "N/A - implemented in v6.0.22" + "missing_impact": "N/A - implemented in v6.0.22", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "kp_system": { "status": "covered", @@ -1555,7 +2176,16 @@ "scripts/kp_system.py" ], "audit_label": "kp_system.py", - "missing_impact": "KP 已可输出 Sublord/Subsublord/ABCD significator,但 ruling planets、horary workflow、事件裁决口径与传统工作流细节仍需更多外部案例闭环。" + "missing_impact": "KP 已可输出 Sublord/Subsublord/ABCD significator,但 ruling planets、horary workflow、事件裁决口径与传统工作流细节仍需更多外部案例闭环。", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "prashna": { "status": "covered", @@ -1573,7 +2203,16 @@ "scripts/prashna.py" ], "audit_label": "prashna.py", - "missing_impact": "Prashna 已可运行,且已有 KP 证据层、Arudha、Sphuta 与 timing score,但不同问事分支的传统判断链、时机裁决与实盘命中率仍需继续通过外部案例收敛。" + "missing_impact": "Prashna 已可运行,且已有 KP 证据层、Arudha、Sphuta 与 timing score,但不同问事分支的传统判断链、时机裁决与实盘命中率仍需继续通过外部案例收敛。", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "synastry_16factor": { "status": "covered", @@ -1591,7 +2230,16 @@ "scripts/synastry.py" ], "audit_label": "synastry.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "remedies": { "status": "covered", @@ -1610,7 +2258,16 @@ "scripts/remedies.py" ], "audit_label": "remedies.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "workflow_or_engineering", + "evidence_role": "audit_only", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Engineering, correction, or remedial support only; it cannot decide astrological conclusions." }, "bhava_bala": { "status": "covered", @@ -1629,7 +2286,16 @@ "scripts/bhava_bala.py" ], "audit_label": "bhava_bala.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "muhurtha": { "status": "covered", @@ -1647,7 +2313,16 @@ "scripts/muhurtha_election.py" ], "audit_label": "muhurtha_election.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "alias_entry", + "evidence_role": "alias", + "user_visibility": "hidden", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Alias/discoverability entry only; it must not be counted as an independent prediction source." }, "career_engine": { "status": "covered", @@ -1665,7 +2340,16 @@ "scripts/career_analysis.py" ], "audit_label": "career_analysis.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "relationship_engine": { "status": "covered", @@ -1683,7 +2367,16 @@ "scripts/relationship_analysis.py" ], "audit_label": "relationship_analysis.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "varshaphala": { "status": "covered", @@ -1703,7 +2396,16 @@ "scripts/varshaphala.py" ], "audit_label": "varshaphala.py", - "missing_impact": "Varshaphala/Tajika 已可输出年盘骨架、Muntha 与年度 Yoga,但 Saham 权重、年度事件裁决和传统软件逐项对齐仍需继续闭环。" + "missing_impact": "Varshaphala/Tajika 已可输出年盘骨架、Muntha 与年度 Yoga,但 Saham 权重、年度事件裁决和传统软件逐项对齐仍需继续闭环。", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "case_validated_partial" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "ashtakavarga_pav": { "status": "covered", @@ -1722,7 +2424,16 @@ "scripts/ashtakavarga.py" ], "audit_label": "ashtakavarga.py calc_prastara_av()", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "ashtakavarga_sodhita": { "status": "covered", @@ -1741,7 +2452,16 @@ "scripts/ashtakavarga.py" ], "audit_label": "ashtakavarga.py calc_sodhita_av()", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "ashtakavarga_yoga_pinda": { "status": "covered", @@ -1762,7 +2482,16 @@ "/api/ashtakavarga.yoga_pinda_summary" ], "audit_label": "ashtakavarga.py calc_yoga_pinda()", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "kakshya": { "status": "covered", @@ -1780,7 +2509,16 @@ "scripts/kakshya.py" ], "audit_label": "kakshya.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "supporting_indicator", + "evidence_role": "secondary", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "Supporting evidence only; it can raise/lower confidence but cannot by itself decide an event or timing claim." }, "transit_trigger": { "status": "covered", @@ -1798,7 +2536,16 @@ "scripts/transit_trigger.py" ], "audit_label": "transit_trigger.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "core_technique", + "evidence_role": "primary", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "verified", + "rule": "verified", + "prediction": "support_only" + }, + "conclusion_policy": "May participate in a domain primary chain; do not use as a single-factor conclusion." }, "divisional_yoga": { "status": "covered", @@ -1816,7 +2563,16 @@ "scripts/divisional_yoga.py" ], "audit_label": "divisional_yoga.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "deep_varga_avastha": { "status": "covered", @@ -1843,7 +2599,16 @@ "/api/deep_varga_avastha.report.deep_varga_templates" ], "audit_label": "Deep Varga Avastha", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "birth_time_rectifier": { "status": "covered", @@ -1861,7 +2626,16 @@ "scripts/birth_time_rectifier.py" ], "audit_label": "birth_time_rectifier.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "composite_adjudicator", + "evidence_role": "context", + "user_visibility": "ordinary_topic_router", + "verification_level": { + "calculation": "partial", + "rule": "partial", + "prediction": "not_claimed" + }, + "conclusion_policy": "Composite route: it may organize evidence, but final conclusions require the domain primary chain and conflict checks." }, "case_validator": { "status": "covered", @@ -1879,7 +2653,16 @@ "scripts/case_validator.py" ], "audit_label": "case_validator.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "workflow_or_engineering", + "evidence_role": "audit_only", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Engineering, correction, or remedial support only; it cannot decide astrological conclusions." }, "misconceptions": { "status": "covered", @@ -1898,7 +2681,16 @@ "scripts/misconceptions.py" ], "audit_label": "misconceptions.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "workflow_or_engineering", + "evidence_role": "audit_only", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Engineering, correction, or remedial support only; it cannot decide astrological conclusions." }, "thematic_report_orchestrator": { "status": "covered", @@ -1923,7 +2715,16 @@ "scripts/orchestrator_bridge.py" ], "audit_label": "report_orchestrator.py", - "missing_impact": "covered" + "missing_impact": "covered", + "entry_type": "workflow_or_engineering", + "evidence_role": "audit_only", + "user_visibility": "expert_audit", + "verification_level": { + "calculation": "not_applicable", + "rule": "not_applicable", + "prediction": "not_applicable" + }, + "conclusion_policy": "Engineering, correction, or remedial support only; it cannot decide astrological conclusions." } }, "routes": { @@ -2084,5 +2885,16 @@ "sudarshana_chakra" ] } + }, + "registry_role": "backend_capability_evidence_pool", + "public_label": "89 capability entries", + "ordinary_user_policy": "Users see topic-level conclusions; the question-domain router selects a small evidence chain from this backend capability evidence pool.", + "conclusion_policy": { + "primary_chain_required": true, + "all_89_entries_must_not_be_flattened_into_conclusions": true, + "supporting_entries_can_only_raise_or_lower_confidence": true, + "audit_only_entries_cannot_affect_astrological_conclusions": true, + "conflicts_must_downgrade_confidence": true, + "prediction_requires_past_case_or_birth_time_rectification": true } } diff --git a/scripts/capability_evidence_pool.py b/scripts/capability_evidence_pool.py new file mode 100644 index 00000000..06899047 --- /dev/null +++ b/scripts/capability_evidence_pool.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +"""Summarize the technique registry as a backend capability evidence pool.""" + +from __future__ import annotations + +import argparse +import json +from collections import Counter +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +DEFAULT_REGISTRY = ROOT / "references" / "technique_registry.json" + + +def load_registry(path: Path = DEFAULT_REGISTRY) -> dict[str, Any]: + return json.loads(path.read_text(encoding="utf-8")) + + +def build_capability_evidence_pool_summary(registry: dict[str, Any] | None = None) -> dict[str, Any]: + registry = registry if registry is not None else load_registry() + techniques = registry.get("techniques") if isinstance(registry, dict) else {} + if not isinstance(techniques, dict): + techniques = {} + + entry_type_counts = Counter() + evidence_role_counts = Counter() + visibility_counts = Counter() + prediction_counts = Counter() + primary_entries: list[str] = [] + audit_only_entries: list[str] = [] + alias_entries: list[str] = [] + + for tech_id, tech in techniques.items(): + if not isinstance(tech, dict): + continue + entry_type = tech.get("entry_type") or "supporting_indicator" + evidence_role = tech.get("evidence_role") or "secondary" + visibility = tech.get("user_visibility") or "expert_audit" + verification = tech.get("verification_level") if isinstance(tech.get("verification_level"), dict) else {} + prediction = verification.get("prediction") or "not_claimed" + + entry_type_counts[entry_type] += 1 + evidence_role_counts[evidence_role] += 1 + visibility_counts[visibility] += 1 + prediction_counts[prediction] += 1 + + if evidence_role == "primary": + primary_entries.append(tech_id) + elif evidence_role == "audit_only": + audit_only_entries.append(tech_id) + elif evidence_role == "alias": + alias_entries.append(tech_id) + + return { + "scope": "backend_capability_evidence_pool", + "total_entries": len(techniques), + "public_label": registry.get("public_label", f"{len(techniques)} capability entries"), + "ordinary_user_policy": registry.get( + "ordinary_user_policy", + "Users see topic-level conclusions; capability entries are routed behind the scenes.", + ), + "entry_type_counts": dict(sorted(entry_type_counts.items())), + "evidence_role_counts": dict(sorted(evidence_role_counts.items())), + "user_visibility_counts": dict(sorted(visibility_counts.items())), + "prediction_verification_counts": dict(sorted(prediction_counts.items())), + "primary_entries": sorted(primary_entries), + "audit_only_entries": sorted(audit_only_entries), + "alias_entries": sorted(alias_entries), + "conclusion_policy": { + "primary_chain_required": True, + "all_89_entries_must_not_be_flattened_into_conclusions": True, + "supporting_entries_can_only_raise_or_lower_confidence": True, + "audit_only_entries_cannot_affect_astrological_conclusions": True, + "conflicts_must_downgrade_confidence": True, + }, + } + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--registry", default=str(DEFAULT_REGISTRY)) + parser.add_argument("--format", choices=["json"], default="json") + args = parser.parse_args(argv) + + summary = build_capability_evidence_pool_summary(load_registry(Path(args.registry))) + print(json.dumps(summary, ensure_ascii=False, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/guided_topic_discovery.py b/scripts/guided_topic_discovery.py new file mode 100644 index 00000000..9f8fe859 --- /dev/null +++ b/scripts/guided_topic_discovery.py @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 +"""Evidence-backed topic discovery for ordinary users. + +This layer does not calculate astrology. It ranks existing full-reading +evidence into a small set of next topics a user can tap or ask about. +""" + +from __future__ import annotations + +from typing import Any + + +def _as_dict(value: Any) -> dict[str, Any]: + return value if isinstance(value, dict) else {} + + +def _as_list(value: Any) -> list[Any]: + return value if isinstance(value, list) else [] + + +def _current_dasha(modules: dict[str, Any]) -> tuple[str | None, str | None, str | None, str | None]: + dasha = _as_dict(modules.get("dasha")) + current = _as_dict(dasha.get("current_dasha")) + antar = _as_dict(current.get("antardasha")) + return current.get("lord"), antar.get("lord"), current.get("start"), current.get("end") + + +def _convergence_for(modules: dict[str, Any], *tokens: str) -> dict[str, Any]: + convergence = _as_dict(modules.get("dasa_convergence")) + activations = _as_dict(convergence.get("domain_activations")) + for domain, row in activations.items(): + if any(token in str(domain).lower() for token in tokens): + found = dict(_as_dict(row)) + found.setdefault("domain", domain) + return found + for row in _as_list(convergence.get("top_convergent_domains")): + if isinstance(row, dict) and any(token in str(row.get("domain", "")).lower() for token in tokens): + return row + if isinstance(row, (list, tuple)) and row and any(token in str(row[0]).lower() for token in tokens): + return {"domain": row[0], "convergence_level": row[1] if len(row) > 1 else None} + return {} + + +def _vedastro_snapshot(modules: dict[str, Any], domain: str) -> dict[str, Any]: + overview = _as_dict(modules.get("vedastro_range_scan_result")) + metadata = _as_dict(overview.get("source_metadata")) + counts = _as_dict(metadata.get("domain_event_counts")) + statuses = _as_dict(metadata.get("domain_statuses")) + top = _as_dict(overview.get("top_events_by_domain")).get(domain) + status = statuses.get(domain) or overview.get("status") + event_count = int(counts.get(domain) or 0) + if status == "ok" or event_count: + return { + "status": "used", + "domain": domain, + "event_count": event_count, + "top_event": top if isinstance(top, dict) else None, + "source": "modules.vedastro_range_scan_result", + } + return { + "status": "blocked" if overview else "not_available", + "domain": domain, + "event_count": event_count, + "top_event": None, + "source": "modules.vedastro_range_scan_result", + } + + +def _evidence_line(label: str, value: Any) -> dict[str, str]: + return {"label": label, "value": str(value)} + + +def _topic( + *, + topic_id: str, + title: str, + reality_value: str, + why: str, + evidence: list[dict[str, str]], + confidence: str, + vedastro: dict[str, Any], + questions: list[str], + answer_mode: str = "tap_or_ask", + priority: int = 50, +) -> dict[str, Any]: + return { + "id": topic_id, + "title": title, + "reality_value": reality_value, + "why_worth_exploring": why, + "evidence": evidence, + "confidence": confidence, + "vedastro": vedastro, + "suggested_questions": questions, + "answer_mode": answer_mode, + "priority": priority, + } + + +def build_guided_topics(report: dict[str, Any]) -> list[dict[str, Any]]: + modules = _as_dict(report.get("modules")) + chart = _as_dict(report.get("chart") or modules.get("chart")) + planets = _as_dict(chart.get("planets")) + md, ad, md_start, md_end = _current_dasha(modules) + md_label = f"{md or '-'} / {ad or '-'}" + fbm = _as_dict(_as_dict(report.get("ai_prompt_pack")).get("evidence_snapshot")).get("functional_benefic_malefic") + fbm = _as_dict(fbm) or _as_dict(modules.get("functional_benefic_malefic")) + + career_conv = _convergence_for(modules, "career", "status", "profession", "work") + marriage_conv = _convergence_for(modules, "marriage", "partnership", "relationship") + wealth_conv = _convergence_for(modules, "wealth", "finance", "income", "gain") + relationship = _as_dict(modules.get("relationship_strict_evidence")) + rel_judgement = _as_dict(relationship.get("event_judgement")) + rel_present = _as_dict(relationship.get("present_evidence")) + d9 = _as_dict(rel_present.get("d9_navamsa")) + ul = _as_dict(rel_present.get("upapada_lagna")) + dk = _as_dict(rel_present.get("darakaraka")) + ketu_house = _as_dict(planets.get("Ketu")).get("house") + + topics = [ + _topic( + topic_id="relationship_partnership", + title="婚恋与长期合作为什么是当前强主题", + reality_value="帮助用户判断关系、合作、相亲、公开关系或长期承诺是否值得深入推进。", + why="婚恋/合作不是靠用户主动问才触发;当前证据里第7宫、D9、UL、DK 与多系统时间层已经可读。", + evidence=[ + _evidence_line("Vimshottari", md_label), + _evidence_line("Dasa 收敛", marriage_conv.get("convergence_level") or "not_found"), + _evidence_line("D9", f"Asc={_as_dict(d9.get('Ascendant')).get('sign', '-')}; 7th={_as_dict(d9.get('_d9_analysis')).get('navamsa_7th_sign', '-')}"), + _evidence_line("UL", f"{ul.get('sign', '-')} H{ul.get('house', '-')}"), + _evidence_line("DK", f"{dk.get('dk_planet', '-')} H{dk.get('dk_house', '-')}"), + _evidence_line("Strict verdict", rel_judgement.get("verdict") or "not_available"), + ], + confidence="medium" if marriage_conv or relationship else "low", + vedastro=_vedastro_snapshot(modules, "marriage"), + questions=[ + "我现在适合认真发展关系,还是更适合筛选和观察?", + "我的伴侣画像、认识场景和相处风险是什么?", + "未来哪些时间窗口适合推进关系公开或承诺?", + ], + priority=90 if marriage_conv else 65, + ), + _topic( + topic_id="career_direction", + title="事业定位是否正在重构", + reality_value="帮助用户判断是继续深耕、换方向、做产品化,还是先修系统和长期资产。", + why="事业主题需要把10宫、A10/D10、多系统 Dasha 与 VedAstro 事业雷达放在一起看。", + evidence=[ + _evidence_line("Vimshottari", md_label), + _evidence_line("10宫触发", f"Ketu house={ketu_house}" if ketu_house else "check D10/A10"), + _evidence_line("Dasa 收敛", career_conv.get("convergence_level") or "not_found"), + _evidence_line("Functional layer", f"benefics={fbm.get('functional_benefics', [])}; malefics={fbm.get('functional_malefics', [])}"), + ], + confidence="medium" if career_conv or ketu_house == 10 else "low", + vedastro=_vedastro_snapshot(modules, "career"), + questions=[ + "我现在适合换方向还是继续深耕?", + "2026 年事业吉利在哪里,不利在哪里?", + "哪些月份适合推进项目、发布产品或谈合作?", + ], + priority=82 if career_conv or ketu_house == 10 else 60, + ), + _topic( + topic_id="birth_time_rectification", + title="出生时间是否需要微调", + reality_value="帮助用户把婚恋、事业、财富应期从泛泛判断推进到可回验时间窗口。", + why="D9、D10、UL、A10 对出生时间敏感;如果用户想问具体月份/日期,先校正时间更有价值。", + evidence=[ + _evidence_line("birth time", _as_dict(report.get("birth_info")).get("time", "-")), + _evidence_line("sensitive layers", "D9 / D10 / UL / A10"), + _evidence_line("current timing", f"{md_label}; {md_start or '-'} to {md_end or '-'}"), + ], + confidence="medium", + vedastro=_vedastro_snapshot(modules, "marriage"), + questions=[ + "我可以用过去事件校正出生时间吗?", + "哪些人生事件最适合用来校正出生时间?", + "我只知道一个时间区间,系统应该先问我哪些 yes/no 问题?", + ], + answer_mode="yes_no_or_free_text", + priority=80, + ), + _topic( + topic_id="wealth_risk", + title="财富、借贷和交易风险怎样用数据拆开", + reality_value="帮助用户把收入、现金流、借贷、买卖和投资风险分开判断,而不是只说财运好坏。", + why="财富主题必须同时看2宫、11宫、D2/D11、Dasha 与 VedAstro wealth 标签。", + evidence=[ + _evidence_line("Vimshottari", md_label), + _evidence_line("Dasa 收敛", wealth_conv.get("convergence_level") or "not_found"), + _evidence_line("required vargas", "D2 / D11"), + ], + confidence="medium" if wealth_conv else "low", + vedastro=_vedastro_snapshot(modules, "wealth"), + questions=[ + "2026 年哪些钱可以赚,哪些钱要避险?", + "我适合靠项目、投资、合作还是长期积累赚钱?", + "哪些时间窗口不适合借贷、买卖或大额投入?", + ], + priority=70 if wealth_conv else 50, + ), + ] + + topics.sort(key=lambda item: (-int(item.get("priority", 0)), item["id"])) + return topics[:4] diff --git a/scripts/jyotish_api_server.py b/scripts/jyotish_api_server.py index 787ec60b..c0ee35a1 100644 --- a/scripts/jyotish_api_server.py +++ b/scripts/jyotish_api_server.py @@ -81,6 +81,26 @@ def _attach_vedastro_main_entry_overview(chart_result, birth_payload): return chart_result +def _attach_guided_topics(chart_result): + if not isinstance(chart_result, dict): + return chart_result + modules = chart_result.setdefault('modules', {}) + if not isinstance(modules, dict): + modules = {} + chart_result['modules'] = modules + if isinstance(modules.get('guided_topics'), list): + return chart_result + try: + builder = _load_local_module('guided_topic_discovery').build_guided_topics + modules['guided_topics'] = builder(chart_result) + except Exception as exc: + modules['guided_topics'] = [] + warnings = chart_result.setdefault('warnings', []) + if isinstance(warnings, list): + warnings.append(f'guided-topics: {exc}') + return chart_result + + def _build_vedastro_overview_payload_from_chart(chart): modules = chart.get('modules') if isinstance(chart, dict) else {} overview = modules.get('vedastro_range_scan_result') if isinstance(modules, dict) else {} @@ -2184,6 +2204,7 @@ class JyotishAPIHandler(BaseHTTPRequestHandler): 'today': body.get('today') or body.get('current_date'), 'transit_date': body.get('transit_date'), }) + _attach_guided_topics(result) result['ai_prompt_pack'] = self._build_chart_prompt_pack(result) return result except ImportError: @@ -2267,6 +2288,7 @@ class JyotishAPIHandler(BaseHTTPRequestHandler): 'ayanamsa': 'lahiri', 'node_mode': 'mean', }) + _attach_guided_topics(result) result['ai_prompt_pack'] = self._build_chart_prompt_pack(result) return result @@ -2278,6 +2300,19 @@ class JyotishAPIHandler(BaseHTTPRequestHandler): shadbala = chart.get('shadbala') or {} functional_layer = self._functional_benefic_malefic_snapshot(planets, ascendant) vedastro_overview = _build_vedastro_overview_payload_from_chart(chart) + _attach_guided_topics(chart) + modules = chart.get('modules') if isinstance(chart.get('modules'), dict) else {} + guided_topics = modules.get('guided_topics') if isinstance(modules.get('guided_topics'), list) else [] + try: + capability_evidence_pool = _load_local_module('capability_evidence_pool').build_capability_evidence_pool_summary() + except Exception: + capability_evidence_pool = { + 'scope': 'backend_capability_evidence_pool', + 'total_entries': 0, + 'conclusion_policy': { + 'all_89_entries_must_not_be_flattened_into_conclusions': True, + }, + } top_strength = sorted( [ { @@ -2348,6 +2383,8 @@ class JyotishAPIHandler(BaseHTTPRequestHandler): }, 'functional_benefic_malefic': functional_layer, 'vedastro_overview': vedastro_overview, + 'guided_topics': guided_topics, + 'capability_evidence_pool': capability_evidence_pool, 'quality_boundary': { 'external_oracle_status': 'D1/D9/VedAstro longitude boundary covered; Dasha/Shadbala external absolute calibration still requires multi-source oracle expansion.', }, diff --git a/scripts/jyotish_engine.py b/scripts/jyotish_engine.py index f6dd2f4b..e4896441 100644 --- a/scripts/jyotish_engine.py +++ b/scripts/jyotish_engine.py @@ -48,6 +48,8 @@ from datetime import datetime, timedelta from typing import Dict, List from tabulate import tabulate from life_stage_hook import generate_life_stage_hooks +from capability_evidence_pool import build_capability_evidence_pool_summary +from guided_topic_discovery import build_guided_topics from ayanamsa_utils import ( AYANAMSA_DISPLAY_NAMES, @@ -1165,6 +1167,8 @@ def _build_ai_prompt_pack(report): relationship_narrative = _build_relationship_narrative_payload(modules.get('relationship_strict_evidence')) vimsopaka_semantic_summary = _build_vimsopaka_semantic_summary(modules.get('vimsopaka')) vedastro_overview = _build_vedastro_overview_payload(modules) + guided_topics = modules.get('guided_topics') if isinstance(modules.get('guided_topics'), list) else build_guided_topics(report) + capability_evidence_pool = build_capability_evidence_pool_summary() shadbala_ranking = [] for planet_name, pdata in sorted( @@ -1236,6 +1240,8 @@ def _build_ai_prompt_pack(report): 'oracle_progress': oracle_progress, 'functional_benefic_malefic': functional_layer, 'vedastro_overview': vedastro_overview, + 'guided_topics': guided_topics, + 'capability_evidence_pool': capability_evidence_pool, 'technique_audit_table': technique_audit_table, 'relationship_narrative': relationship_narrative, 'vimsopaka_semantic_summary': vimsopaka_semantic_summary, @@ -1250,6 +1256,7 @@ def _build_ai_prompt_pack(report): "输出结构建议:参数声明、核心星盘、关系/事业/财富/健康分主题、当前时机、证据表、风险边界、可行动建议。", "若引用经典法则,请优先检索 retrieval_plan.local_reference_docs;需要外部断语时再做 web/source verification。", "若 evidence_snapshot.vedastro_overview.status 为 ok,请把它作为用户可见外部概览证据明确写出,但不要把 overview-only 结果误当作长周期精扫结论。", + "若 evidence_snapshot.capability_evidence_pool 存在,请把 89 项视为后台备选证据池;不要把所有能力条目平铺成结论,也不要让 audit_only/alias 条目影响占星判断。", ] return { @@ -5130,6 +5137,12 @@ def cmd_full_reading(args): except Exception as e: report['warnings'].append(f"vedastro-main-entry-overview: {e}") + try: + report['modules']['guided_topics'] = build_guided_topics(report) + except Exception as e: + report['warnings'].append(f"guided-topics: {e}") + report['modules']['guided_topics'] = [] + report['ai_prompt_pack'] = _build_ai_prompt_pack(report) return report diff --git a/tests/test_capability_evidence_pool.py b/tests/test_capability_evidence_pool.py new file mode 100644 index 00000000..88629094 --- /dev/null +++ b/tests/test_capability_evidence_pool.py @@ -0,0 +1,72 @@ +from __future__ import annotations + +import json +from pathlib import Path + +from scripts.capability_evidence_pool import build_capability_evidence_pool_summary + + +ROOT = Path(__file__).resolve().parents[1] +REGISTRY = ROOT / "references" / "technique_registry.json" +README = ROOT / "README.md" + + +def test_registry_is_backend_evidence_pool_not_flat_user_skill_list() -> None: + registry = json.loads(REGISTRY.read_text(encoding="utf-8")) + techniques = registry["techniques"] + + assert registry["registry_role"] == "backend_capability_evidence_pool" + assert registry["public_label"] == "89 capability entries" + assert "question-domain router" in registry["ordinary_user_policy"] + + allowed_entry_types = { + "core_technique", + "supporting_indicator", + "composite_adjudicator", + "workflow_or_engineering", + "alias_entry", + } + allowed_roles = {"primary", "secondary", "context", "audit_only", "alias"} + allowed_visibility = {"ordinary_topic_router", "expert_audit", "hidden"} + allowed_prediction = { + "case_validated_partial", + "support_only", + "not_claimed", + "not_applicable", + } + + for tech_id, tech in techniques.items(): + assert tech["entry_type"] in allowed_entry_types, tech_id + assert tech["evidence_role"] in allowed_roles, tech_id + assert tech["user_visibility"] in allowed_visibility, tech_id + assert tech["verification_level"]["calculation"] in {"verified", "partial", "not_applicable"}, tech_id + assert tech["verification_level"]["rule"] in {"verified", "partial", "not_applicable"}, tech_id + assert tech["verification_level"]["prediction"] in allowed_prediction, tech_id + assert tech["conclusion_policy"], tech_id + + assert techniques["case_validator"]["evidence_role"] == "audit_only" + assert techniques["thematic_report_orchestrator"]["entry_type"] == "workflow_or_engineering" + assert techniques["neechabhanga"]["evidence_role"] == "alias" + assert techniques["special_lagnas"]["evidence_role"] == "alias" + + +def test_evidence_pool_summary_routes_few_primary_items_and_many_support_items() -> None: + summary = build_capability_evidence_pool_summary() + + assert summary["scope"] == "backend_capability_evidence_pool" + assert summary["total_entries"] == 89 + assert summary["ordinary_user_policy"].startswith("Users see topic-level") + assert summary["evidence_role_counts"]["primary"] >= 8 + assert summary["evidence_role_counts"]["secondary"] > summary["evidence_role_counts"]["primary"] + assert summary["evidence_role_counts"]["audit_only"] >= 3 + assert summary["prediction_verification_counts"]["not_claimed"] > 0 + assert summary["conclusion_policy"]["primary_chain_required"] is True + assert summary["conclusion_policy"]["all_89_entries_must_not_be_flattened_into_conclusions"] is True + + +def test_readme_uses_capability_entries_language_instead_of_89_techniques_claim() -> None: + readme = README.read_text(encoding="utf-8") + + assert "89 capability entries" in readme + assert "89 techniques" not in readme + assert "backend evidence pool" in readme diff --git a/tests/test_cli_smoke.py b/tests/test_cli_smoke.py index 678fd5b4..8cedd9df 100644 --- a/tests/test_cli_smoke.py +++ b/tests/test_cli_smoke.py @@ -334,6 +334,11 @@ def test_full_reading_reports_ayanamsa_metadata_and_ai_prompt_pack() -> None: assert vedastro_rows[0]["status"] in {"used", "blocked"} assert "overview only" in vedastro_rows[0]["note"] assert "domain_statuses" in vedastro_rows[0]["note"] + capability_pool = prompt_pack["evidence_snapshot"]["capability_evidence_pool"] + assert capability_pool["scope"] == "backend_capability_evidence_pool" + assert capability_pool["total_entries"] == 89 + assert capability_pool["conclusion_policy"]["all_89_entries_must_not_be_flattened_into_conclusions"] is True + assert "后台备选证据池" in prompt_pack["prompt_zh"] def test_full_reading_generates_guided_topics_from_real_evidence() -> None: diff --git a/tests/test_readme_badges.py b/tests/test_readme_badges.py index 0645c14e..296ba2bf 100644 --- a/tests/test_readme_badges.py +++ b/tests/test_readme_badges.py @@ -27,7 +27,7 @@ def test_readme_badges_match_technique_registry_counts() -> None: counts = Counter(item["status"] for item in techniques) total = len(registry["techniques"]) - assert _readme_badge_value("Techniques") == total + assert _readme_badge_value("Capabilities") == total assert _readme_badge_value("Covered") == counts["covered"] assert _readme_badge_value("Complete") == counts["complete"] assert _readme_badge_value("Partial") == counts["partial"]