Files
Jyotisha/tests/test_rectification_confirmation_and.py
T
Jesse_Chen a88467ffa8 fix(rectification): offer representative time once event-fit is enough
Keep unique-top and width on confirmation only, and stop lagna-frame follow-ups from blocking cards on an already-scored cluster.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 02:01:57 +08:00

304 lines
12 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from scripts.rectification.decision_policy import (
apply_vedastro_minute_sensitive_to_receipt,
build_candidate_decisions,
build_decision_receipt,
indistinguishable_width_minutes,
)
from scripts.rectification.sealed_holdout import (
PILOT_REPORT_PATH,
holdout_passed,
load_sealed_minute_holdout,
)
ROOT = Path(__file__).resolve().parents[1]
def _request(*, extra_events=()):
events = [
{
"id": "00000000-0000-4000-8000-000000000001",
"domain": "career",
"summary": "入职",
"event_kind": "career_entry",
"precision": "day",
"date_start": "2016-09-15",
"date_end": "2016-09-15",
},
{
"id": "00000000-0000-4000-8000-000000000002",
"domain": "relationship",
"summary": "开始一段关系",
"event_kind": "relationship_start",
"precision": "day",
"date_start": "2018-03-01",
"date_end": "2018-03-01",
},
{
"id": "00000000-0000-4000-8000-000000000003",
"domain": "education",
"summary": "毕业",
"event_kind": "education_completion",
"precision": "day",
"date_start": "2015-06-01",
"date_end": "2015-06-01",
},
*extra_events,
]
return {"events": events}
def _diagnostics():
return {
"leave_one_event_out_retention_rate": 1,
"leave_one_domain_out_retention_rate": 1,
"date_sensitivity_retention_rate": 1,
"primary_secondary_margin_percent": 50,
}
def _rows():
return [
{"time": "05:13", "score": 20, "evidence": [], "missing_layers": []},
{"time": "05:14", "score": 8, "evidence": [], "missing_layers": []},
]
def test_sealed_holdout_contract_matches_v2_pilot_and_stays_closed() -> None:
holdout = load_sealed_minute_holdout()
report = json.loads(PILOT_REPORT_PATH.read_text(encoding="utf-8"))
product = json.loads((ROOT / "references" / "rectification_sealed_holdout.v1.json").read_text(encoding="utf-8"))
assert holdout["sealed_benchmark_id"] == report["benchmark_id"] == product["sealed_benchmark_id"]
assert holdout["valid_public_aa_cases"] == report["case_gate"]["valid_public_aa_cases"]
assert holdout["required_cases"] == report["case_gate"]["minimum_public_aa_cases"]
assert holdout["top_1_rate"] == report["metrics"]["top_1_rate"]
assert holdout["confirmation_coverage_rate"] == report["metrics"]["confirmation_coverage_rate"]
assert holdout["status"] == "not_ready"
assert holdout_passed(holdout) is False
def test_vedastro_pass_rewrites_audit_but_holdout_still_blocks(monkeypatch) -> None:
extra = [{
"id": "00000000-0000-4000-8000-000000000004",
"domain": "family",
"summary": "家人变化",
"event_kind": "family_event",
"precision": "day",
"date_start": "2020-01-01",
"date_end": "2020-01-01",
}]
decisions = build_candidate_decisions(_rows(), result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(_request(extra_events=extra), decisions, {"missing_layers": [], "matrix": {}}, _diagnostics())
assert receipt["gates"]["exact_confirmation"]["engine_granted"] is True
apply_vedastro_minute_sensitive_to_receipt(receipt, "passed", summary={"discriminated": True})
audit = {row["technique"]: row for row in receipt["technique_audit_table"]}
assert audit["VedAstro 分钟级校验"]["status"] == "executed"
assert "未调用不等于失败" not in audit["VedAstro 分钟级校验"]["note"]
assert audit["唯一分钟确认"]["status"] == "blocked"
assert receipt["confirmation_allowed"] is False
assert receipt["gates"]["exact_confirmation"]["holdout"]["status"] == "not_ready"
def test_confirmation_allowed_only_when_holdout_ready(monkeypatch) -> None:
extra = [{
"id": "00000000-0000-4000-8000-000000000004",
"domain": "family",
"summary": "家人变化",
"event_kind": "family_event",
"precision": "day",
"date_start": "2020-01-01",
"date_end": "2020-01-01",
}]
monkeypatch.setattr(
"scripts.rectification.decision_policy.load_sealed_minute_holdout",
lambda: {
"sealed_benchmark_id": "minute_rectification_holdout_v2",
"status": "ready",
"valid_public_aa_cases": 20,
"required_cases": 20,
"top_1_rate": 0.7,
"confirmation_coverage_rate": 0.2,
},
)
monkeypatch.setattr("scripts.rectification.decision_policy.holdout_passed", lambda holdout=None: True)
decisions = build_candidate_decisions(_rows(), result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(_request(extra_events=extra), decisions, {"missing_layers": [], "matrix": {}}, _diagnostics())
apply_vedastro_minute_sensitive_to_receipt(receipt, "passed", summary={"discriminated": True})
assert receipt["confirmation_allowed"] is True
assert receipt["confirm_allowed"] is True
audit = {row["technique"]: row for row in receipt["technique_audit_table"]}
assert audit["唯一分钟确认"]["status"] == "executed"
def test_kp_only_missing_does_not_block_propose_or_engine_grant() -> None:
extra = [{
"id": "00000000-0000-4000-8000-000000000004",
"domain": "family",
"summary": "家人变化",
"event_kind": "family_event",
"precision": "day",
"date_start": "2020-01-01",
"date_end": "2020-01-01",
}]
decisions = build_candidate_decisions(_rows(), result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(
_request(extra_events=extra),
decisions,
{"missing_layers": ["KP_cusps"], "matrix": {}},
_diagnostics(),
)
assert receipt["gates"]["required_layers"]["passed"] is True
assert receipt["gates"]["required_layers"]["missing_layers"] == []
assert receipt["gates"]["required_layers"]["skipped_by_policy"] == ["KP_cusps"]
assert receipt["propose_allowed"] is True
assert receipt["gates"]["exact_confirmation"]["engine_granted"] is True
assert "missing_mandatory_layers" not in receipt["confirmation_reasons"]
def test_four_events_two_domains_selects_but_does_not_propose() -> None:
events = [
{
"id": "00000000-0000-4000-8000-000000000001",
"domain": "education",
"summary": "入学",
"event_kind": "education_start",
"precision": "month",
"date_start": "2016-09-01",
"date_end": "2016-09-30",
},
{
"id": "00000000-0000-4000-8000-000000000002",
"domain": "education",
"summary": "毕业",
"event_kind": "education_completion",
"precision": "month",
"date_start": "2020-06-01",
"date_end": "2020-06-30",
},
{
"id": "00000000-0000-4000-8000-000000000003",
"domain": "relationship",
"summary": "相识",
"event_kind": "relationship_start",
"precision": "day",
"date_start": "2024-05-01",
"date_end": "2024-05-01",
},
{
"id": "00000000-0000-4000-8000-000000000004",
"domain": "relationship",
"summary": "分手",
"event_kind": "relationship_end",
"precision": "day",
"date_start": "2024-08-08",
"date_end": "2024-08-08",
},
]
decisions = build_candidate_decisions(_rows(), result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(
{"events": events},
decisions,
{"missing_layers": ["KP_cusps"], "matrix": {}},
{
"leave_one_event_out_retention_rate": 1,
"leave_one_domain_out_retention_rate": 0.5,
"date_sensitivity_retention_rate": 1,
"primary_secondary_margin_percent": 10.27,
},
)
assert receipt["selection_allowed"] is True
assert receipt["propose_allowed"] is False
assert receipt["gates"]["exact_confirmation"]["engine_granted"] is False
assert "insufficient_confirmation_domains" in receipt["confirmation_reasons"]
assert "insufficient_diagnostic_stability" in receipt["confirmation_reasons"]
def test_d9_missing_still_blocks_required_layers() -> None:
extra = [{
"id": "00000000-0000-4000-8000-000000000004",
"domain": "family",
"summary": "家人变化",
"event_kind": "family_event",
"precision": "day",
"date_start": "2020-01-01",
"date_end": "2020-01-01",
}]
decisions = build_candidate_decisions(_rows(), result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(
_request(extra_events=extra),
decisions,
{"missing_layers": ["KP_cusps", "D9"], "matrix": {}},
_diagnostics(),
)
assert receipt["gates"]["required_layers"]["passed"] is False
assert receipt["gates"]["required_layers"]["missing_layers"] == ["D9"]
assert receipt["propose_allowed"] is False
assert "missing_mandatory_layers" in receipt["confirmation_reasons"]
def test_timeout_status_stays_not_evaluated_not_fail() -> None:
decisions = build_candidate_decisions(_rows(), result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(_request(), decisions, {"missing_layers": [], "matrix": {}}, _diagnostics())
apply_vedastro_minute_sensitive_to_receipt(
receipt,
"not_evaluated",
summary={"reason": "vedastro_minute_snapshot_timeout"},
)
exact = receipt["gates"]["exact_confirmation"]
assert exact["external_validation_status"] == "not_evaluated"
assert exact["external_validation_status"] != "failed"
assert receipt["confirmation_allowed"] is False
note = next(row["note"] for row in receipt["technique_audit_table"] if row["technique"] == "VedAstro 分钟级校验")
assert "不等于失败" in note
def test_indistinguishable_width_matches_public_span() -> None:
width = indistinguishable_width_minutes([
{"time": "04:45", "rank": 1, "tied_minute_count": 25},
{"time": "04:46", "rank": 2, "tied_minute_count": 25},
{"time": "04:47", "rank": 3, "tied_minute_count": 25},
])
assert width >= 25
def test_fourteen_minute_tied_cluster_proposes_but_does_not_confirm() -> None:
extra = [{
"id": "00000000-0000-4000-8000-000000000004",
"domain": "family",
"summary": "家人变化",
"event_kind": "family_event",
"precision": "day",
"date_start": "2020-01-01",
"date_end": "2020-01-01",
}]
rows = [
{
"time": f"{15 + ((50 + offset) // 60):02d}:{(50 + offset) % 60:02d}",
"score": 20,
"evidence": [],
"missing_layers": [],
}
for offset in range(14)
]
decisions = build_candidate_decisions(rows, result_id="00000000-0000-4000-8000-000000000099")
receipt = build_decision_receipt(
_request(extra_events=extra),
decisions,
{"missing_layers": ["KP_cusps"], "matrix": {}},
_diagnostics(),
)
exact = receipt["gates"]["exact_confirmation"]
assert receipt["selection_allowed"] is True
assert receipt["propose_allowed"] is True
assert receipt["gates"]["unique_top"]["passed"] is False
assert exact["indistinguishable_width_minutes"] >= 14
assert exact["adjacent_passed"] is False
assert exact["engine_granted"] is False
assert receipt["confirmation_allowed"] is False
assert "adjacent_minutes_indistinguishable" in receipt["confirmation_reasons"]