fix(rectification): stop unwritten-evidence claims and same-cluster dasha false conflicts (BUG-635–640)
Host only says 记下了 after a real write; Mastra schema rejections fail closed. Ledger year keys no longer drop quality probes, dual-dasha agreement is per cluster, width uses cluster span, and public house tables follow the inference minute. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -132,6 +132,64 @@ class RefinementPacketTest(unittest.TestCase):
|
||||
self.assertEqual(agreement["narayana_top"], "05:14")
|
||||
self.assertIn("冲突", agreement["user_meaning"])
|
||||
|
||||
def test_dasha_agreement_same_cluster_peaks_agree(self):
|
||||
built = {
|
||||
"matrix": {
|
||||
"00000000-0000-4000-8000-000000000001": {
|
||||
"04:54": {"points": 8, "rule_ids": ["vim_md_domain_house"]},
|
||||
"04:59": {"points": 1, "rule_ids": ["vim_ad_domain_house"]},
|
||||
},
|
||||
"00000000-0000-4000-8000-000000000002": {
|
||||
"04:54": {"points": 1, "rule_ids": ["narayana_ad_domain_house"]},
|
||||
"04:59": {"points": 9, "rule_ids": ["narayana_md_domain_house"]},
|
||||
},
|
||||
}
|
||||
}
|
||||
clusters = [{
|
||||
"time": "04:54",
|
||||
"cluster_start": "04:54",
|
||||
"cluster_end": "04:59",
|
||||
"cluster_times": ["04:54", "04:59"],
|
||||
}]
|
||||
without_clusters = dasha_agreement(built, ["04:54", "04:59"])
|
||||
self.assertEqual(without_clusters["status"], "conflict")
|
||||
agreement = dasha_agreement(built, ["04:54", "04:59"], clusters=clusters)
|
||||
self.assertEqual(agreement["status"], "agree")
|
||||
self.assertEqual(agreement["vimshottari_top"], "04:54")
|
||||
self.assertEqual(agreement["narayana_top"], "04:59")
|
||||
|
||||
def test_dasha_agreement_cross_cluster_peaks_conflict(self):
|
||||
built = {
|
||||
"matrix": {
|
||||
"00000000-0000-4000-8000-000000000001": {
|
||||
"05:13": {"points": 8, "rule_ids": ["vim_md_domain_house"]},
|
||||
"05:20": {"points": 1, "rule_ids": ["vim_ad_domain_house"]},
|
||||
},
|
||||
"00000000-0000-4000-8000-000000000002": {
|
||||
"05:13": {"points": 1, "rule_ids": ["narayana_ad_domain_house"]},
|
||||
"05:20": {"points": 9, "rule_ids": ["narayana_md_domain_house"]},
|
||||
},
|
||||
}
|
||||
}
|
||||
clusters = [
|
||||
{"time": "05:13", "cluster_start": "05:13", "cluster_end": "05:13", "cluster_times": ["05:13"]},
|
||||
{"time": "05:20", "cluster_start": "05:20", "cluster_end": "05:20", "cluster_times": ["05:20"]},
|
||||
]
|
||||
agreement = dasha_agreement(built, ["05:13", "05:20"], clusters=clusters)
|
||||
self.assertEqual(agreement["status"], "conflict")
|
||||
|
||||
def test_dasha_agreement_one_track_is_partial(self):
|
||||
built = {
|
||||
"matrix": {
|
||||
"00000000-0000-4000-8000-000000000001": {
|
||||
"05:13": {"points": 8, "rule_ids": ["vim_md_domain_house"]},
|
||||
"05:20": {"points": 1, "rule_ids": ["vim_ad_domain_house"]},
|
||||
},
|
||||
}
|
||||
}
|
||||
agreement = dasha_agreement(built, ["05:13", "05:20"])
|
||||
self.assertEqual(agreement["status"], "partial")
|
||||
|
||||
def test_precision_stage_walks_d1_then_d9_then_ready(self):
|
||||
self.assertEqual(precision_stage({"d1_candidates_differ": True}, 2)["current"], "lagna_frame")
|
||||
self.assertEqual(precision_stage({"d9_candidates_differ": True}, 2)["current"], "d9_refine")
|
||||
@@ -278,24 +336,24 @@ class RefinementPacketTest(unittest.TestCase):
|
||||
request = request_events()
|
||||
rows = [
|
||||
{"time": "05:13", "score": 20, "evidence": [], "missing_layers": []},
|
||||
{"time": "05:14", "score": 8, "evidence": [], "missing_layers": []},
|
||||
{"time": "05:20", "score": 8, "evidence": [], "missing_layers": []},
|
||||
]
|
||||
decisions = build_candidate_decisions(rows, result_id="00000000-0000-4000-8000-000000000099")
|
||||
built = {
|
||||
"missing_layers": [],
|
||||
"static_contexts": [feature("05:13", d1=1, d9=1, d10=4), feature("05:14", d1=1, d9=1, d10=4)],
|
||||
"static_contexts": [feature("05:13", d1=1, d9=1, d10=4), feature("05:20", d1=2, d9=1, d10=4)],
|
||||
"matrix": {
|
||||
request["events"][0]["id"]: {
|
||||
"05:13": {"points": 8, "rule_ids": ["vim_md_domain_house"]},
|
||||
"05:14": {"points": 1, "rule_ids": ["vim_ad_domain_house"]},
|
||||
"05:20": {"points": 1, "rule_ids": ["vim_ad_domain_house"]},
|
||||
},
|
||||
request["events"][1]["id"]: {
|
||||
"05:13": {"points": 1, "rule_ids": ["narayana_ad_domain_house"]},
|
||||
"05:14": {"points": 9, "rule_ids": ["narayana_md_domain_house"]},
|
||||
"05:20": {"points": 9, "rule_ids": ["narayana_md_domain_house"]},
|
||||
},
|
||||
request["events"][2]["id"]: {
|
||||
"05:13": {"points": 1, "rule_ids": ["vim_md_domain_varga"]},
|
||||
"05:14": {"points": 1, "rule_ids": ["vim_md_domain_varga"]},
|
||||
"05:20": {"points": 1, "rule_ids": ["vim_md_domain_varga"]},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -316,6 +374,53 @@ class RefinementPacketTest(unittest.TestCase):
|
||||
self.assertTrue(any(row["technique"] == "VedAstro 分钟级校验" and row["status"] == "blocked" for row in receipt["technique_audit_table"]))
|
||||
self.assertFalse(receipt["unique_minute_claim"])
|
||||
|
||||
def test_same_cluster_dasha_peaks_agree_without_opening_confirmation(self):
|
||||
request = request_events()
|
||||
rows = [
|
||||
{"time": "04:54", "score": 20, "evidence": [], "missing_layers": []},
|
||||
{"time": "04:59", "score": 18, "evidence": [], "missing_layers": []},
|
||||
]
|
||||
contexts = [
|
||||
feature("04:54", d1=1, d9=1, d10=4),
|
||||
feature("04:59", d1=1, d9=1, d10=4),
|
||||
]
|
||||
decisions = build_candidate_decisions(
|
||||
rows,
|
||||
result_id="00000000-0000-4000-8000-000000000099",
|
||||
static_contexts=contexts,
|
||||
)
|
||||
built = {
|
||||
"missing_layers": [],
|
||||
"static_contexts": contexts,
|
||||
"candidate_times": ["04:54", "04:59"],
|
||||
"matrix": {
|
||||
request["events"][0]["id"]: {
|
||||
"04:54": {"points": 8, "rule_ids": ["vim_md_domain_house"]},
|
||||
"04:59": {"points": 1, "rule_ids": ["vim_ad_domain_house"]},
|
||||
},
|
||||
request["events"][1]["id"]: {
|
||||
"04:54": {"points": 1, "rule_ids": ["narayana_ad_domain_house"]},
|
||||
"04:59": {"points": 9, "rule_ids": ["narayana_md_domain_house"]},
|
||||
},
|
||||
request["events"][2]["id"]: {
|
||||
"04:54": {"points": 1, "rule_ids": ["vim_md_domain_varga"]},
|
||||
"04:59": {"points": 1, "rule_ids": ["vim_md_domain_varga"]},
|
||||
},
|
||||
},
|
||||
}
|
||||
diagnostics = {
|
||||
"leave_one_event_out_retention_rate": 1,
|
||||
"leave_one_domain_out_retention_rate": 1,
|
||||
"date_sensitivity_retention_rate": 1,
|
||||
"primary_secondary_margin_percent": 50,
|
||||
}
|
||||
receipt = build_decision_receipt(request, decisions, built, diagnostics)
|
||||
self.assertEqual(receipt["dasha_agreement"]["status"], "agree")
|
||||
self.assertNotIn("vimshottari_narayana_conflict", receipt["reasons"])
|
||||
self.assertFalse(receipt["confirmation_allowed"])
|
||||
width = receipt["gates"]["exact_confirmation"]["indistinguishable_width_minutes"]
|
||||
self.assertGreaterEqual(width, 6)
|
||||
|
||||
def test_receipt_recasts_house_tables_per_candidate_and_blocks_unique_minute(self):
|
||||
request = request_events()
|
||||
rows = [
|
||||
|
||||
Reference in New Issue
Block a user