fix(rectification): anchor candidate windows to civil dates across midnight
Independent Staging Quality Gate / validate (push) Successful in 13m27s
Independent Staging Quality Gate / publish (push) Failing after 1h0m1s

Carry explicit local date intervals instead of inferring the day from clock
order. Cluster width, delivery, adoption, and reports keep the actual civil
date; adopted date is stored separately from the reported birth_date.

Algorithm identity is scoring-9 / spec-v5. Scoring weights, confirmation
thresholds, and Skill version are unchanged. Isolated Linux final-3 gates
passed; four pre-existing Python failures remain. This is not a production
release.
This commit is contained in:
jesse-ux
2026-09-21 02:55:00 +08:00
parent 3be740f84d
commit b85c4a686a
115 changed files with 106484 additions and 315 deletions
+7 -4
View File
@@ -13,8 +13,8 @@ from scripts.rectification.dasha_transition_proximity import merge_transition_pr
from scripts.rectification.contracts import LifeEvent, RectificationRequest, is_scoreable_event
from scripts.rectification.case_holdout import holdout_event_ids
ALGORITHM_VERSION = "rectification-v5-matrix-scoring-8"
INPUT_CONTRACT_VERSION = "rectification-calculation-spec-v4"
ALGORITHM_VERSION = "rectification-v5-matrix-scoring-9"
INPUT_CONTRACT_VERSION = "rectification-calculation-spec-v5"
PRECISION_WEIGHTS = {
"day": 1.0,
"month": 0.8,
@@ -115,7 +115,7 @@ def _legacy_request(request: RectificationRequest, event: LifeEvent, sampled_dat
"date": sampled_date, "precision": "day", "summary": event.get("summary", ""),
}],
}
for key in ("ayanamsa", "node_mode", "minute_step"):
for key in ("ayanamsa", "node_mode", "minute_step", "candidate_intervals"):
if key in request:
legacy_request[key] = request[key]
return legacy_request
@@ -307,6 +307,7 @@ def build_event_contribution_matrix(
"date_sensitivity": date_sensitivity,
"missing_layers": sorted(missing_layers),
"static_contexts": static_contexts,
**({"candidate_intervals": request["candidate_intervals"]} if "candidate_intervals" in request else {}),
}
@@ -341,7 +342,7 @@ def calculation_spec(request: RectificationRequest) -> dict[str, Any]:
return int(value) if value.is_integer() else value
spec = {
"version": INPUT_CONTRACT_VERSION,
"version": INPUT_CONTRACT_VERSION if "candidate_intervals" in request else "rectification-calculation-spec-v4",
"birthDate": request["birth_date"],
"candidateRange": {"start": request["start_time"], "end": request["end_time"]},
"latitude": json_number(request["lat"]),
@@ -359,6 +360,8 @@ def calculation_spec(request: RectificationRequest) -> dict[str, Any]:
):
if source in request:
spec[target] = request[source] # type: ignore[literal-required]
if "candidate_intervals" in request:
spec["candidateIntervals"] = request["candidate_intervals"]
return spec