fix(rectification): fold D24 into education refine and score family D3

Window scan now drives d5_refine when D24 changes, family events use D3, and pada/Hora/Ghati are display-only. New cases bind Skill 10.0.7 without unique-minute confirmation.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-20 11:04:55 +08:00
co-authored by Cursor
parent 9a5cf67209
commit 70efb56926
35 changed files with 894 additions and 72 deletions
+51 -1
View File
@@ -12,7 +12,22 @@ from scripts.rectification.refinement_packet import (
)
def feature(time: str, *, d1: int | None = None, d9: int | None = None, d10: int | None = None, d4: int | None = None, d5: int | None = None, d7: int | None = None, d12: int | None = None, degree: float | None = None) -> dict:
def feature(
time: str,
*,
d1: int | None = None,
d9: int | None = None,
d10: int | None = None,
d4: int | None = None,
d5: int | None = None,
d7: int | None = None,
d12: int | None = None,
d24: int | None = None,
degree: float | None = None,
pada: int | None = None,
hora: int | None = None,
ghati: int | None = None,
) -> dict:
vargas = {}
if d9 is not None:
vargas["D9"] = d9
@@ -26,11 +41,19 @@ def feature(time: str, *, d1: int | None = None, d9: int | None = None, d10: int
vargas["D7"] = d7
if d12 is not None:
vargas["D12"] = d12
if d24 is not None:
vargas["D24"] = d24
row: dict = {"time": time, "varga_ascendants": vargas}
if d1 is not None:
row["ascendant_sign_index"] = d1
if degree is not None:
row["ascendant_degree"] = degree
if pada is not None:
row["pada_index"] = pada
if hora is not None:
row["hora_sign_index"] = hora
if ghati is not None:
row["ghati_sign_index"] = ghati
return {"feature": row}
@@ -95,6 +118,10 @@ class RefinementPacketTest(unittest.TestCase):
self.assertEqual(precision_stage({"d10_candidates_differ": True}, 2)["current"], "d10_refine")
self.assertEqual(precision_stage({"d4_candidates_differ": True}, 2)["current"], "d4_refine")
self.assertEqual(precision_stage({"d5_candidates_differ": True}, 2)["current"], "d5_refine")
self.assertEqual(
precision_stage({"d24_candidates_differ": True, "d5_candidates_differ": False}, 2)["current"],
"d5_refine",
)
self.assertNotEqual(precision_stage({"d4_candidates_differ": True}, 2)["current"], "theme_refine")
self.assertIn("搬家", precision_stage({"d4_candidates_differ": True}, 2)["user_meaning"])
self.assertNotIn("家人", precision_stage({"d4_candidates_differ": True}, 2)["user_meaning"])
@@ -102,6 +129,29 @@ class RefinementPacketTest(unittest.TestCase):
self.assertEqual(ready["current"], "ready_to_adopt")
self.assertFalse(ready["unique_minute_claim"])
def test_window_scan_reports_d24_and_fine_minute_changes_without_unique_claim(self):
scan = window_scan({
"static_contexts": [
feature("05:13", d1=1, d5=3, d24=4, pada=10, hora=2, ghati=6),
feature("05:14", d1=1, d5=3, d24=8, pada=11, hora=3, ghati=6),
]
})
self.assertEqual(scan["d24_lagna_count"], 2)
self.assertTrue(scan["d24_candidates_differ"])
self.assertFalse(scan["d5_candidates_differ"])
self.assertEqual(scan["pada_count"], 2)
self.assertTrue(scan["pada_candidates_differ"])
self.assertTrue(scan["hora_candidates_differ"])
self.assertFalse(scan["ghati_candidates_differ"])
meanings = [item["user_meaning"] for item in scan["transitions"]]
self.assertIn("D24 在 05:14 发生变化", meanings)
self.assertIn("Nakshatra pada 在 05:14 发生变化", meanings)
self.assertIn("Hora Lagna 在 05:14 发生变化", meanings)
self.assertNotIn("Ghati Lagna 在 05:14 发生变化", meanings)
self.assertFalse(scan["unique_minute_claim"])
self.assertFalse(scan["confirmation_allowed"])
self.assertEqual(precision_stage(scan, 2)["current"], "d5_refine")
def test_packet_ledger_oos_and_nakshatra_without_scores(self):
request = request_events()
built = {