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
@@ -0,0 +1,90 @@
"""Native golden verification plus explicitly synthetic order/gap arithmetic fixtures."""
import json
from pathlib import Path
from scripts.active_rectification_event_engine import compute_candidate_static_contexts
from scripts.rectification.refinement_packet import cluster_scan, lagna_contrast, window_scan
def test_native_lagna_golden_has_explicit_date_labels_and_segments():
fixture = json.loads((Path(__file__).resolve().parents[1]
/ "frontend/tests/fixtures/rectification-dated-lagna.native.json").read_text(encoding="utf-8"))
request = fixture["request"]
actual = lagna_contrast({"static_contexts": compute_candidate_static_contexts(request),
"candidate_intervals": request["candidate_intervals"]})
assert actual == fixture["lagna_contrast"]
assert "2000-02-29 23:58" in actual["user_meaning"]
assert [row["segment_index"] for row in actual["intervals"]] == [0, 1]
def test_native_scan_golden_matches_real_static_contexts():
fixture = json.loads((Path(__file__).resolve().parents[1]
/ "frontend/tests/fixtures/rectification-dated-transitions.native.json").read_text(encoding="utf-8"))
request = fixture["request"]
contexts = compute_candidate_static_contexts(request)
assert window_scan({"static_contexts": contexts,
"candidate_intervals": request["candidate_intervals"]}) == fixture["scan"]
def context(time, date, index, offset, segment, sign):
return {"time": time, "candidate_date": date, "window_index": index,
"window_offset_minutes": offset, "segment_index": segment,
"feature": {"time": time, "varga_ascendants": {"D9": sign}}}
def test_midnight_transitions_follow_candidate_order_not_clock_order():
rows = [context("23:58", "2000-06-14", 0, 0, 0, 0),
context("23:59", "2000-06-14", 1, 1, 0, 1),
context("00:00", "2000-06-15", 2, 2, 0, 2)]
transitions = [row for row in window_scan({"static_contexts": rows, "candidate_intervals": [{"start_at": "2000-06-14T23:58", "end_at": "2000-06-15T00:00"}]})["transitions"] if row["layer"] == "d9"]
changes = [row for row in transitions if not row.get("segment_start")]
assert [row["at"] for row in changes] == ["23:59", "00:00"]
assert [row["window_index"] for row in transitions] == [0, 1, 2]
assert transitions[0]["segment_start"] is True
assert transitions[-1]["candidate_date"] == "2000-06-15"
def test_disjoint_segments_have_independent_initial_states_not_gap_transitions():
rows = [context("00:00", "2000-06-15", 0, 0, 0, 0),
context("00:01", "2000-06-15", 1, 1, 0, 1),
context("23:00", "2000-06-15", 2, 1380, 1, 5),
context("23:01", "2000-06-15", 3, 1381, 1, 6)]
transitions = [row for row in window_scan({"static_contexts": rows, "candidate_intervals": [
{"start_at": "2000-06-15T00:00", "end_at": "2000-06-15T00:01"},
{"start_at": "2000-06-15T23:00", "end_at": "2000-06-15T23:01"},
]})["transitions"] if row["layer"] == "d9"]
assert [row["at"] for row in transitions if not row.get("segment_start")] == ["00:01", "23:01"]
starts = [row for row in transitions if row.get("segment_start")]
assert [row["segment_index"] for row in starts] == [0, 1]
assert starts[1]["from_sign"] == starts[1]["to_sign"]
assert starts[0]["segment_end_at"] == "2000-06-15T00:01"
assert starts[1]["segment_start_at"] == "2000-06-15T23:00"
def test_same_day_dated_changes_preserve_legacy_scan_output():
rows = [context(f"10:0{i}", "2000-06-15", i, i, 0, i) for i in range(4)]
legacy = window_scan({"static_contexts": rows})
dated = window_scan({"static_contexts": rows, "candidate_intervals": [{"start_at": "2000-06-15T10:00", "end_at": "2000-06-15T10:03"}]})
dated["transitions"] = [{key: value for key, value in row.items()
if key not in {"candidate_date", "window_index", "window_offset_minutes", "segment_index", "segment_start_at", "segment_end_at"}}
for row in dated["transitions"] if not row.get("segment_start")]
assert dated == legacy
def test_cluster_scan_uses_midnight_order_and_never_fills_segment_gaps():
rows = [context("23:58", "2000-06-14", 0, 0, 0, 0),
context("23:59", "2000-06-14", 1, 1, 0, 1),
context("00:00", "2000-06-15", 2, 2, 0, 2),
context("00:01", "2000-06-15", 3, 3, 0, 3)]
built = {"static_contexts": rows, "candidate_intervals": [{"start_at": "2000-06-14T23:58", "end_at": "2000-06-15T00:01"}]}
result = cluster_scan(built, ["23:59", "00:00"], "23:59", 2)
assert result["d9_lagna_count"] == 2
assert {row["at"] for row in result["transitions"]} == {"23:59", "00:00"}
def test_legacy_transition_shape_has_no_reconstructed_dates():
rows = [{"feature": {"time": time, "varga_ascendants": {"D9": sign}}}
for time, sign in [("10:00", 0), ("10:01", 1), ("10:02", 2)]]
transitions = window_scan({"static_contexts": rows})["transitions"]
assert [row["at"] for row in transitions] == ["10:01", "10:02"]
assert all("candidate_date" not in row and "segment_start" not in row for row in transitions)