78f98ebachanges the same-input rectification scores: Shadbala Sthana and Drik feed the Shadbala auxiliary (BPHS Saptavargaja values, Moolatrikona 3 / 15 deg, whole-sign Kendradi, BPHS 26 special aspects, Mercury with any malefic) and jaimini.calc_arudha_padas feeds the event engine and feature facts. Per BUG-1181 the algorithm identity moves rectification-v5-matrix-scoring-13 -> -14. Policy v4, input contract v5 and the dated window contract (generation >= 9) are unchanged; the SQL guard accepts scoring-(9|[1-9][0-9]+), so no migration. - Memoization golden v7 written by write_golden (source_commit78f98eba); v6 stays byte-identical and is pinned by sha256. For this public request the candidate scores are unchanged (12:00 8.5336, 12:01 8.5242, 12:02 8.088); the Shadbala fingerprints, feature hash and candidate UUID moved. - New scoring-14 cross-midnight golden from midnight_date_anchor_regression.py --golden (baseline = this tree; independent-process A/B 3 x 7 fields equal); scoring-13 golden kept as history and opens read-only with recompare. - Dated-transitions scan unchanged (test passes without regeneration). - v9EngineVersion() default and the identity tests follow. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DbBXoyn7Hj3LCW3BUs5bZ8
71 lines
3.8 KiB
Python
71 lines
3.8 KiB
Python
from __future__ import annotations
|
|
|
|
import unittest
|
|
from decimal import Decimal
|
|
|
|
from scripts.rectification.decision_policy import (
|
|
POLICY_VERSION,
|
|
RELATIVE_SUPPORT_MODE,
|
|
_relative_support,
|
|
build_candidate_decisions,
|
|
)
|
|
from scripts.rectification.scoring_service import ALGORITHM_VERSION
|
|
|
|
|
|
def _row(time: str, score: float) -> dict:
|
|
return {"time": time, "score": score, "evidence": [], "missing_layers": []}
|
|
|
|
|
|
class RelativeSupportScaleTest(unittest.TestCase):
|
|
def test_holdout_gate_keeps_proportional_default(self) -> None:
|
|
# 原值: policy-v3;新值: policy-v4;原因: R1 区间门槛 4 件 3 域(BUG-1193),相对支持口径不变。
|
|
self.assertEqual(POLICY_VERSION, "rectification-candidate-policy-v4")
|
|
# Explicit date windows: scoring identity -8 -> -9, not a prior/policy change.
|
|
# 原值: -11;新值: -12;原因: 章动修正改变同输入分数(BUG-1275),策略 v4 与相对支持口径不变。
|
|
# 原值: -12;新值: -13;原因: D30 偶数星座与白羊 / 天蝎金星功能凶改变同输入分数(BUG-1560 / BUG-1570),策略 v4 与相对支持口径不变。
|
|
# 原值: -13;新值: -14;原因: 同输入分数变了(#166 占星师裁定:Shadbala Sthana / Drik 按具名 BPHS 口径、jaimini.py Arudha 例外从初算落点数,BUG-1583~1588),策略 v4 与相对支持口径不变。
|
|
self.assertEqual(ALGORITHM_VERSION, "rectification-v5-matrix-scoring-14")
|
|
self.assertEqual(RELATIVE_SUPPORT_MODE, "proportional")
|
|
|
|
def test_offset_top_two_lead_is_at_least_proportional(self) -> None:
|
|
scores = [
|
|
Decimal("15.52"), Decimal("15.40"), Decimal("14.10"), Decimal("13.00"),
|
|
Decimal("12.50"), Decimal("12.00"), Decimal("11.80"), Decimal("11.50"),
|
|
Decimal("11.40"), Decimal("11.20"), Decimal("11.10"), Decimal("10.96"),
|
|
]
|
|
floor = min(scores)
|
|
proportional = _relative_support(scores, floor=floor, mode="proportional")
|
|
offset = _relative_support(scores, floor=floor, mode="offset")
|
|
prop_lead = sorted(proportional, reverse=True)
|
|
offset_lead = sorted(offset, reverse=True)
|
|
self.assertGreaterEqual(offset_lead[0] - offset_lead[1], prop_lead[0] - prop_lead[1])
|
|
self.assertEqual(sum(offset), 100)
|
|
self.assertEqual(sum(proportional), 100)
|
|
|
|
def test_equal_scores_split_evenly_for_offset_and_proportional(self) -> None:
|
|
scores = [Decimal("12")] * 12
|
|
expected = _relative_support(scores, floor=Decimal("12"), mode="proportional")
|
|
offset = _relative_support(scores, floor=Decimal("12"), mode="offset")
|
|
self.assertEqual(offset, expected)
|
|
self.assertEqual(sum(offset), 100)
|
|
self.assertTrue(all(value in {8, 9} for value in offset))
|
|
|
|
def test_build_candidate_decisions_offset_lead_beats_proportional_on_spaced_grid(self) -> None:
|
|
scores = [
|
|
15.52, 15.40, 14.10, 13.00, 12.50, 12.00,
|
|
11.80, 11.50, 11.40, 11.20, 11.10, 10.96,
|
|
]
|
|
rows = [_row(f"05:{index * 5:02d}", score) for index, score in enumerate(scores)]
|
|
proportional = build_candidate_decisions(rows, result_id="00000000-0000-4000-8000-000000000001", support_mode="proportional")
|
|
offset = build_candidate_decisions(rows, result_id="00000000-0000-4000-8000-000000000001", support_mode="offset")
|
|
self.assertEqual(len(proportional), 12)
|
|
self.assertEqual(len(offset), 12)
|
|
prop_lead = proportional[0]["relative_support"] - proportional[1]["relative_support"]
|
|
offset_lead = offset[0]["relative_support"] - offset[1]["relative_support"]
|
|
self.assertGreaterEqual(offset_lead, prop_lead)
|
|
self.assertEqual(sum(item["relative_support"] for item in offset), 100)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|