From beea0f1996b5c060a99cebed1462a28d38601cbc Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Wed, 15 Jul 2026 13:52:05 +0800 Subject: [PATCH] enforce repository local yoga and prashna tests --- docs/research/pre_work_error_ledger.md | 1 + scripts/jyotish_api_server.py | 4 ++++ tests/run_yoga_test_suite.py | 17 +++++++++------ tests/test_api_server_security.py | 30 +++++++------------------- tests/test_yoga_hardcoded.py | 12 ++++++----- 5 files changed, 30 insertions(+), 34 deletions(-) diff --git a/docs/research/pre_work_error_ledger.md b/docs/research/pre_work_error_ledger.md index 57bd703b..b9c62eca 100644 --- a/docs/research/pre_work_error_ledger.md +++ b/docs/research/pre_work_error_ledger.md @@ -99,6 +99,7 @@ For large architecture or release work, also read: | ERR-066 | The pre-work fragment sweep invoked a retired `audit-capabilities --mode strict` contract, so governance tests and the mandatory preflight failed before real checks ran. | mitigated 2026-07-14 | Invoke the supported `--mode validate`; `tests/test_preflight_fragment_scan.py` and `pre_work_check.py` must remain green before substantive work. | | ERR-067 | A generic “Western timing” label can imply techniques that have not been computed. | mitigated 2026-07-15 | Native timing requires explicit transit, solar-return, secondary-progression, or solar-arc fields; boundaries still name unavailable progressed angles, converse, parans, midpoints, duration, and interpretation. | | ERR-068 | PyJHora comparison reports hard-coded `2026-06-03` as generation time, making fresh external benchmark artifacts appear stale and weakening audit traceability. | mitigated 2026-07-15 | `write_report()` records an injected-or-current UTC ISO timestamp; keep the deterministic timestamp regression. | +| ERR-069 | Yoga validation tests and helper runner still imported rules from a `.workbuddy` mirror, so full pytest could fail or silently validate a divergent checkout. | mitigated 2026-07-15 | Resolve repo root from each file location; retain runtime-boundary and focused Yoga regressions. | ## Fragment Sweep Command Set diff --git a/scripts/jyotish_api_server.py b/scripts/jyotish_api_server.py index bf4536b3..236bbe5b 100644 --- a/scripts/jyotish_api_server.py +++ b/scripts/jyotish_api_server.py @@ -5030,6 +5030,10 @@ class JyotishAPIHandler(BaseHTTPRequestHandler): from prashna_context import PrashnaContextError, build_prashna_context except ModuleNotFoundError: # pragma: no cover - package import path from scripts.prashna_context import PrashnaContextError, build_prashna_context + if "question" in body and not isinstance(body["question"], str): + raise BadRequest('question must be a string') + if "question_text" in body and not isinstance(body["question_text"], str): + raise BadRequest('question_text must be a string') if "planets" in body or "asc_degree" in body: raise BadRequest("Prashna planets and ascendant are backend-computed; client values are forbidden") try: diff --git a/tests/run_yoga_test_suite.py b/tests/run_yoga_test_suite.py index af7b3785..47b9f744 100644 --- a/tests/run_yoga_test_suite.py +++ b/tests/run_yoga_test_suite.py @@ -1,18 +1,21 @@ """ 自动化 Yoga 测试运行器 — 从 yoga_test_suite.json 加载用例并批量验证 """ -import json, sys, os -SKILL_DIR = '/.workbuddy/skills/jyotish-vedic-astrology' -sys.path.insert(0, os.path.join(SKILL_DIR, 'scripts')) -RULES_PATH = os.path.join(SKILL_DIR, 'references', 'yoga_rules.json') +import json +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / 'scripts')) +RULES_PATH = ROOT / 'references' / 'yoga_rules.json' from yoga_engine import YogaEngine -engine = YogaEngine(RULES_PATH) +engine = YogaEngine(str(RULES_PATH)) def detect(rule_id, planets, asc, ctx=None): return any(r.get('rule_id') == rule_id for r in engine.detect(planets, asc, context=ctx)) -suite_path = os.path.join(SKILL_DIR, 'tests', 'yoga_test_suite.json') -with open(suite_path) as f: +suite_path = ROOT / 'tests' / 'yoga_test_suite.json' +with suite_path.open() as f: suite = json.load(f) passed = 0 diff --git a/tests/test_api_server_security.py b/tests/test_api_server_security.py index c4fb0362..6d051c36 100644 --- a/tests/test_api_server_security.py +++ b/tests/test_api_server_security.py @@ -908,33 +908,19 @@ def test_prashna_rejects_non_string_question() -> None: handler._compute_prashna({'question': {'bad': 'shape'}, 'planets': {}}) -def test_prashna_returns_chart_and_answer_for_valid_request() -> None: +def test_prashna_returns_backend_question_context_with_verdict_blocked() -> None: handler = _handler() result = handler._compute_prashna({ 'question': 'career', 'question_text': '这个工作机会是否值得争取?', - 'horary_number': 140, - 'planets': {'Saturn': {'sign': 'Pisces'}, 'Moon': {'sign': 'Scorpio'}}, + 'question_timestamp': '2026-07-15T10:00:00+08:00', + 'lat': 39.9042, + 'lon': 116.4074, + 'timezone': 8, }) - assert 'prashna_chart' in result - assert 'kp_answer' in result - assert result['kp_answer']['question_type'] == 'career' - assert result['kp_answer_v2']['primary_house'] == 10 - assert 'arudha' in result - assert 'sphutas' in result - assert 'sahams' in result - assert 'lost_item' in result - assert 'kunda' in result - kp_horary = result['kp_horary'] - assert kp_horary['method'] == 'KP Horary' - assert kp_horary['horary_number'] == 140 - assert kp_horary['question_houses']['primary'] == 10 - assert kp_horary['ruling_planets']['ascendant_lord'] - assert kp_horary['ruling_planets']['moon_star_lord'] - assert kp_horary['cuspal_sub_lord']['house'] == 10 - assert kp_horary['cuspal_sub_lord']['kp_lords']['sub_lord'] - assert kp_horary['house_significators']['10'] - assert kp_horary['judgement_matrix'] + assert result['status'] == 'computed' + assert result['prashna_context']['chart_source'] == 'swiss_ephemeris_backend' + assert result['verdict']['status'] == 'blocked' def test_prashna_advanced_legacy_functions_exist() -> None: diff --git a/tests/test_yoga_hardcoded.py b/tests/test_yoga_hardcoded.py index 344c4952..1d965c2a 100644 --- a/tests/test_yoga_hardcoded.py +++ b/tests/test_yoga_hardcoded.py @@ -1,12 +1,14 @@ """ PyJHora 风格硬编码 Yoga True/False 测试 """ -import sys, os -SKILL_DIR = '/.workbuddy/skills/jyotish-vedic-astrology' -sys.path.insert(0, os.path.join(SKILL_DIR, 'scripts')) -RULES_PATH = os.path.join(SKILL_DIR, 'references', 'yoga_rules.json') +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / 'scripts')) +RULES_PATH = ROOT / 'references' / 'yoga_rules.json' from yoga_engine import YogaEngine -engine = YogaEngine(RULES_PATH) +engine = YogaEngine(str(RULES_PATH)) def detect(rule_id, planets, ascendant, context=None): results = engine.detect(planets, ascendant, context=context)