diff --git a/SKILL.md b/SKILL.md index ec9b30e9..6bb6b5a7 100644 --- a/SKILL.md +++ b/SKILL.md @@ -13,6 +13,7 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力 > **执行总控**:`references/quick-reference-guide.md` > **严格路由**:`references/strict-workflow-router.md`(涉及事业/婚恋/财务/应期/技法验证时必须优先读取) > **机器注册表**:`references/technique_registry.json` + `scripts/audit_capabilities.py` +> **文章级细节模板**:`references/interpretation_template_registry.json` + `scripts/validate_interpretation_templates.py` ## v6.9.14 核心能力 @@ -221,6 +222,37 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力 | **实战智慧** | ⭐反教条主义经验精华(全球占星师真实案例反馈总结) | `practitioner-wisdom-anti-dogma.md` | | **验证与错题** | 深度数据审计、技法缺陷与修复、推运反思、15+名人验证案例 | `audit-*` `lessons-learned-*` `verified-celebrity-cases-*` | +## 文章级细节模板入口(v6.9.17-template-registry) + +用户问到“吉祥天女/财富点、Yogi Point、娄宿 Ashwini 天赋、上升点度数定位、紧密合相、RTN/D9、Bhrigu Pada、Tithi Lord、Pancha Pakshi/Swara”等细颗粒技法时,不得临场凭记忆发挥,也不得把网上文章断语直接当权威。 + +必须先查: + +```bash +python3 scripts/validate_interpretation_templates.py --format markdown +``` + +注册表真源: + +`references/interpretation_template_registry.json` + +当前已冻结 6 个可复用模板: + +1. `yogi_asc_tight_orb_wealth`:Yogi Point / 上升度数 / `<1°` 紧密合相 / 财富激活 +2. `ashwini_talent_profile`:Ashwini / Ketu 系星宿 / Abhijit 择时边界 +3. `rtn_high_order_d9`:Rashi Tulya Navamsa / 高阶 D9 异象 +4. `bhrigu_pada_all_event`:Bhrigu Pada / Arudha Pada 全事件推进 +5. `tithi_lord_relationship`:Tithi Lord 关系与情绪节奏 +6. `pancha_pakshi_swara_boundary`:Pancha Pakshi / Swara 择时边界 + +使用规则: + +- 这些模板是“细节解释层”,不能替代 D1/D9/Dasha/Transit/相关分盘。 +- `<1°` 紧密合相只能提高敏感度或置信度,不能单独断财富、婚姻、事故或成就。 +- Ashwini/Abhijit/Ketu 星宿只能作为天赋、行动风格或择时偏好,不可单独断职业、财富或灵性高低。 +- Bhrigu Pada / RTN / Tithi Lord / Pancha Pakshi 必须作为辅助确认层;若没有主承诺和推运激活,输出置信度不得超过 C。 +- 所有文章/课程/网上说法默认归入 B/C 级线索,必须经过注册表中的 `required_cross_checks` 与 `forbidden_claims` 过滤。 + ## 当前最硬的未闭环点 > 这部分比“再加几个技法名”更重要,决定 skill 距离传统软件级深度还有多远。 diff --git a/references/interpretation_template_registry.json b/references/interpretation_template_registry.json new file mode 100644 index 00000000..a12f8aa0 --- /dev/null +++ b/references/interpretation_template_registry.json @@ -0,0 +1,227 @@ +{ + "schema_version": 1, + "scope": "jyotish_interpretation_template_registry", + "purpose": "Skill-level high-granularity interpretation templates distilled from local references and user-supplied article clues. These templates are guarded by source levels, cross-checks, confidence ceilings and forbidden claims.", + "global_rules": [ + "Do not turn online article claims into hard predictions without D1/Varga/Dasha/Transit cross-checks.", + "Use these templates after the strict workflow router has established the relevant promise and timing layer.", + "Keep personal user data out of persistent skill files and public repositories.", + "Treat JHora/PyJHora as external oracle sources only; do not copy incompatible licensed implementations." + ], + "templates": { + "yogi_asc_tight_orb_wealth": { + "title": "Yogi Point / Ascendant Degree / Tight Orb Wealth Activation", + "status": "frozen_template", + "authority_level": "A/B/C layered", + "domain": ["wealth", "lagna", "panchanga", "tight_orb"], + "source_refs": [ + "references/yogi-asc-tight-orb-wealth-freeze-guide.md", + "references/yogi-avayogi-system.md", + "scripts/aspects.py", + "scripts/special_lagnas.py" + ], + "trigger_patterns": [ + "财富点", + "吉祥天女财富点", + "Yogi Point", + "上升点度数定位", + "紧密合相", + "1度内合相" + ], + "required_cross_checks": [ + "D1 wealth promise: 2H/11H/5H/9H and their lords", + "Dhana/Lakshmi Yoga and Jupiter/Venus support", + "D2, D9 and D10 confirmation when wealth is career-linked", + "Dasha and transit activation of Yogi planet, Duplicate Yogi or wealth lords", + "Avayogi damage check before upgrading confidence" + ], + "confidence_ceiling": "B unless wealth promise, varga support and timing activation all agree; C when only Yogi/tight-orb signal exists.", + "forbidden_claims": [ + "Yogi Point conjunct Lagna guarantees wealth", + "A tight orb alone proves millionaire status", + "Gemstone/remedy guarantees money" + ], + "safe_output_patterns": [ + "Yogi Point can refine the prosperity activation channel after the main wealth promise is established.", + "A <1° contact is a sensitivity amplifier, not an independent wealth promise.", + "Avayogi contacts should be framed as leakage or friction to manage, not fatalism." + ] + }, + "ashwini_talent_profile": { + "title": "Ashwini / Ketu Nakshatra Talent And Action Style", + "status": "frozen_template", + "authority_level": "A/B/C layered", + "domain": ["nakshatra", "talent", "career", "muhurta"], + "source_refs": [ + "references/ashwini-abhijit-ketu-nakshatra-freeze-guide.md", + "references/nakshatra_deities.md", + "references/nakshatra-chinese-quick-ref.md", + "scripts/kalachakra_dasha.py" + ], + "trigger_patterns": [ + "娄宿", + "Ashwini", + "Ketu星宿", + "天赋特征", + "Abhijit", + "快速启动" + ], + "required_cross_checks": [ + "Placement of Moon, Lagna, Sun, AK, AmK, 10L or 1L in Ashwini/Magha/Mula", + "Ketu condition, dispositor and Dasha activation", + "Mars condition because Ashwini is in Aries", + "D9, D10 and D24 support for talent-to-career conversion", + "Panchanga context for electional use" + ], + "confidence_ceiling": "B for career style when D10/Dasha support exists; C for personality color only.", + "forbidden_claims": [ + "Ashwini alone makes someone a doctor", + "Ashwini guarantees wealth or spiritual status", + "Ketu nakshatra days are always bad" + ], + "safe_output_patterns": [ + "Ashwini favors quick response, repair, healing, mobility and pioneer behavior when the chart supports it.", + "Ketu nakshatra days are task-sensitive: useful for cutting, repair and root-work; cautious for pure stability commitments.", + "Abhijit is mainly an electional support window, not a standalone natal destiny marker." + ] + }, + "rtn_high_order_d9": { + "title": "Rashi Tulya Navamsa And High-Order D9 Anomaly Reading", + "status": "frozen_template", + "authority_level": "A/B/C layered", + "domain": ["d9", "navamsa", "relationship", "deep_motive"], + "source_refs": [ + "references/rtn-high-order-d9-freeze-execution-guide.md", + "references/rashi-tulya-navamsa-root-impulse.md", + "references/high-order-d9-execution-guide.md", + "scripts/rashi_tulya_navamsa.py" + ], + "trigger_patterns": [ + "RTN", + "Rashi Tulya Navamsa", + "高阶D9", + "D9异象", + "Navamsa返照" + ], + "required_cross_checks": [ + "Standard D1 and D9 promise first", + "Vargottama and Pushkara check before RTN weighting", + "D9 7L, Venus/Jupiter, DK and D9 Lagna condition", + "Mapped D1 house condition and event-relevant Varga", + "Dasha/transit activation before event claims" + ], + "confidence_ceiling": "B for motive/inner-pattern interpretation; C for timing unless Dasha and event Varga agree.", + "forbidden_claims": [ + "RTN alone proves divorce, death or disaster", + "Yama/Preta/Pisacha labels can be used as deterministic outcomes", + "D9 anomaly overrides D1 promise" + ], + "safe_output_patterns": [ + "RTN explains how Navamsa motives project into D1 life fields.", + "High-order D9 anomalies are warnings that require timing confirmation.", + "Use RTN as a depth layer after ordinary D1/D9 analysis, not as the first judgment." + ] + }, + "bhrigu_pada_all_event": { + "title": "Bhrigu Pada / Arudha Pada All-Event Progression Template", + "status": "frozen_template", + "authority_level": "A/B/C layered", + "domain": ["arudha", "bhrigu", "event", "timing"], + "source_refs": [ + "references/bhrigu-pada-all-event-freeze-execution-guide.md", + "references/bhrigu-pada-dasha-marriage-counting.md", + "scripts/bhrigu_pada_dasha.py", + "scripts/jaimini.py", + "scripts/special_lagnas.py" + ], + "trigger_patterns": [ + "Bhrigu Pada", + "Arudha Pada", + "A10", + "A2", + "UL", + "全事件推进" + ], + "required_cross_checks": [ + "D1 promise for the event domain", + "Select correct Pada: A2/A5/A7/A8/A10/A11/UL", + "Pada lord condition and relevant Varga", + "Vimshottari/Chara/transit convergence", + "Past-event verification before personal rule upgrade" + ], + "confidence_ceiling": "B as auxiliary event confirmation; C if used without Dasha/transit convergence.", + "forbidden_claims": [ + "Bhrigu Pada Dasha alone proves an event", + "A single progression proves exact date", + "Marriage-counting rules can be generalized to all charts without verification" + ], + "safe_output_patterns": [ + "Use the relevant Arudha Pada to identify how an event becomes visible in the world.", + "Treat Bhrigu Pada as a confirmation/progression layer, not a standalone prediction engine.", + "Upgrade only after Dasha, transit and event Varga agree." + ] + }, + "tithi_lord_relationship": { + "title": "Tithi Lord Relationship And Emotional Rhythm Template", + "status": "frozen_template", + "authority_level": "B/C guarded", + "domain": ["tithi", "relationship", "moon_sun", "panchanga"], + "source_refs": [ + "references/tithi-lord-freeze-execution-guide.md", + "references/tithi-lord-relationship-system.md" + ], + "trigger_patterns": [ + "Tithi Lord", + "月相主", + "关系节奏", + "情绪周期" + ], + "required_cross_checks": [ + "D1/D9 relationship promise", + "Moon, Venus/Jupiter and 7L condition", + "Dasha activation of Tithi lord or relationship significators", + "Transit Moon/Jupiter/Saturn trigger only inside supported windows" + ], + "confidence_ceiling": "C for standalone relationship judgment; B only when D1/D9/Dasha agree.", + "forbidden_claims": [ + "Tithi Lord alone decides marriage fate", + "One lunar-day trait proves compatibility" + ], + "safe_output_patterns": [ + "Tithi Lord can describe emotional rhythm and response style after relationship promise is checked.", + "Use it to refine timing texture, not to replace 7H/D9/Dasha." + ] + }, + "pancha_pakshi_swara_boundary": { + "title": "Pancha Pakshi / Swara Boundary Template", + "status": "covered_template", + "authority_level": "B/C guarded", + "domain": ["tamil", "muhurta", "panchanga", "action_timing"], + "source_refs": [ + "references/pancha-pakshi-nakshatra-systems.md" + ], + "trigger_patterns": [ + "Pancha Pakshi", + "五鸟", + "Swara", + "行动窗口", + "择时细节" + ], + "required_cross_checks": [ + "Primary Muhurta factors: Tithi, Vara, Nakshatra, Yoga, Karana", + "Moon strength and Tarabala/Chandrabala when available", + "Natal Dasha/transit relevance for personal actions", + "Avoid replacing core Muhurta with Pakshi/Swara alone" + ], + "confidence_ceiling": "C as auxiliary electional texture; B only with full Muhurta support.", + "forbidden_claims": [ + "Pakshi/Swara alone makes a time auspicious", + "One folk-timing layer overrides bad Moon or Dasha" + ], + "safe_output_patterns": [ + "Use Pakshi/Swara as a final action-timing refinement after ordinary Muhurta checks.", + "Frame weak Pakshi/Swara periods as caution or lower efficiency, not unavoidable failure." + ] + } + } +} diff --git a/scripts/validate_interpretation_templates.py b/scripts/validate_interpretation_templates.py new file mode 100644 index 00000000..f79b72ce --- /dev/null +++ b/scripts/validate_interpretation_templates.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +"""Validate high-granularity Jyotish interpretation templates.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +DEFAULT_REGISTRY = ROOT / "references" / "interpretation_template_registry.json" + +REQUIRED_TEMPLATE_FIELDS = [ + "title", + "status", + "authority_level", + "domain", + "source_refs", + "trigger_patterns", + "required_cross_checks", + "confidence_ceiling", + "forbidden_claims", + "safe_output_patterns", +] + + +def _resolve(path: str | None) -> Path: + if not path: + return DEFAULT_REGISTRY + candidate = Path(path) + return candidate if candidate.is_absolute() else ROOT / candidate + + +def _load_json(path: Path) -> dict[str, Any]: + with path.open("r", encoding="utf-8") as fh: + return json.load(fh) + + +def validate_registry(path: Path) -> dict[str, Any]: + problems: list[str] = [] + registry = _load_json(path) + if registry.get("scope") != "jyotish_interpretation_template_registry": + problems.append("invalid_scope") + templates = registry.get("templates") + if not isinstance(templates, dict) or not templates: + problems.append("missing_templates") + templates = {} + + for template_id, template in templates.items(): + if not isinstance(template, dict): + problems.append(f"{template_id}:not_object") + continue + for field in REQUIRED_TEMPLATE_FIELDS: + value = template.get(field) + if value in (None, "", [], {}): + problems.append(f"{template_id}:missing_{field}") + for ref in template.get("source_refs", []): + ref_path = ROOT / ref + if not ref_path.exists(): + problems.append(f"{template_id}:missing_source_ref:{ref}") + if not template.get("forbidden_claims"): + problems.append(f"{template_id}:missing_forbidden_claims") + if "alone" not in " ".join(template.get("forbidden_claims", [])).lower(): + problems.append(f"{template_id}:forbidden_claims_should_block_single-factor_use") + + return { + "scope": "jyotish_interpretation_template_validation", + "schema_version": 1, + "registry": str(path.relative_to(ROOT) if path.is_relative_to(ROOT) else path), + "valid": not problems, + "summary": { + "template_count": len(templates), + "template_ids": sorted(templates.keys()), + "problem_count": len(problems), + }, + "problems": problems, + "boundary": ( + "These templates are interpretation guardrails. They do not replace chart calculation, " + "Dasha/transit convergence, external oracle validation or the strict workflow router." + ), + } + + +def render_markdown(report: dict[str, Any]) -> str: + lines = [ + "# Jyotish Interpretation Template Validation", + "", + f"- valid: `{str(report['valid']).lower()}`", + f"- template_count: `{report['summary']['template_count']}`", + f"- problem_count: `{report['summary']['problem_count']}`", + "", + "## Templates", + "", + ] + lines.extend(f"- `{template_id}`" for template_id in report["summary"]["template_ids"]) + lines.extend(["", "## Boundary", "", report["boundary"], ""]) + if report["problems"]: + lines.extend(["## Problems", ""]) + lines.extend(f"- {problem}" for problem in report["problems"]) + lines.append("") + return "\n".join(lines) + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Validate Jyotish interpretation template registry") + parser.add_argument("--registry", help="Path to interpretation_template_registry.json") + parser.add_argument("--format", choices=["json", "markdown"], default="json") + return parser.parse_args(argv) + + +def main(argv: list[str] | None = None) -> int: + args = parse_args(argv) + report = validate_registry(_resolve(args.registry)) + if args.format == "markdown": + print(render_markdown(report)) + else: + print(json.dumps(report, ensure_ascii=False, indent=2)) + return 0 if report["valid"] else 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_interpretation_template_registry.py b/tests/test_interpretation_template_registry.py new file mode 100644 index 00000000..b4303268 --- /dev/null +++ b/tests/test_interpretation_template_registry.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +"""Tests for skill-level high-granularity interpretation templates.""" + +from __future__ import annotations + +import json +import subprocess +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +REGISTRY = ROOT / "references" / "interpretation_template_registry.json" + + +def test_interpretation_template_registry_covers_article_level_hard_topics() -> None: + data = json.loads(REGISTRY.read_text(encoding="utf-8")) + + assert data["scope"] == "jyotish_interpretation_template_registry" + templates = data["templates"] + required = { + "yogi_asc_tight_orb_wealth", + "ashwini_talent_profile", + "rtn_high_order_d9", + "bhrigu_pada_all_event", + "tithi_lord_relationship", + "pancha_pakshi_swara_boundary", + } + assert required <= set(templates) + + for template_id in required: + template = templates[template_id] + assert template["status"] in {"frozen_template", "covered_template"} + assert template["authority_level"] in {"A/B/C layered", "B/C guarded"} + assert template["source_refs"] + assert template["required_cross_checks"] + assert template["confidence_ceiling"] + assert template["forbidden_claims"] + assert template["safe_output_patterns"] + + +def test_interpretation_template_validator_reports_skill_readiness() -> None: + completed = subprocess.run( + [sys.executable, "scripts/validate_interpretation_templates.py", "--format", "json"], + cwd=ROOT, + text=True, + capture_output=True, + timeout=60, + check=False, + ) + + assert completed.returncode == 0, completed.stderr or completed.stdout + report = json.loads(completed.stdout) + assert report["scope"] == "jyotish_interpretation_template_validation" + assert report["valid"] is True + assert report["summary"]["template_count"] >= 6 + assert report["summary"]["problem_count"] == 0 + assert "yogi_asc_tight_orb_wealth" in report["summary"]["template_ids"]