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.
91 lines
5.1 KiB
Python
91 lines
5.1 KiB
Python
"""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)
|