fix(rectification): keep clock-stamped events out of window intercept (BUG-631, BUG-632)
Independent Staging Quality Gate / validate (push) Successful in 12m36s
Independent Staging Quality Gate / publish (push) Successful in 2m11s

Dated life events with clock times were swallowed as birth-window replies, and compare columns still stopped at the first nine candidates after the hour-window cap.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-10 09:23:35 +08:00
co-authored by Cursor
parent 2de2aa0b71
commit 719ff55a09
19 changed files with 395 additions and 24 deletions
+23 -10
View File
@@ -9,8 +9,11 @@ from __future__ import annotations
from typing import Any, Sequence
from scripts.rectification.candidate_contrast import MAX_PUBLIC_CLUSTERS
from scripts.rectification.house_table import PLANET_ZH, SIGN_LORDS, SIGNS, SIGNS_CN
COLUMN_COMPARE_BUDGET_MS = 3000
NAKSHATRA_SPAN = 40.0 / 3.0
NAKSHATRA_BOUNDARY_DEGREES = 2.0
MATCH_LABELS = {
@@ -263,12 +266,14 @@ def column_times_for_compare(
candidate_times: Sequence[str],
representative_time: str | None,
*,
limit: int = 9,
limit: int = MAX_PUBLIC_CLUSTERS,
) -> list[str]:
"""Unique HH:MM keys for by_time ledgers/windows, capped at `limit`.
Compare cards still project at most three posterior columns; this set is
the engine candidate list so those clocks can look up a row.
the full public candidate list (≤64) so inference-layer clocks can look up
a row. Callers that already know a smaller active set may pass it as
`column_times` when a 64-minute compare would exceed COLUMN_COMPARE_BUDGET_MS.
"""
seen: list[str] = []
for raw in candidate_times:
@@ -621,14 +626,22 @@ def build_refinement_packet(
scan = window_scan(built)
cluster = cluster_scan(built, candidate_times, representative_time, cluster_width_minutes)
ledger = event_dasha_ledger(request, built, representative_time)
columns = column_times_for_compare(
column_times if column_times is not None else candidate_times,
representative_time,
)
compare_started = perf_counter()
ledgers_by_time = event_dasha_ledgers_by_time(request, built, columns)
windows_by_time = prospective_windows_by_time(request, built, columns)
column_compare_ms = round((perf_counter() - compare_started) * 1000, 1)
minute_step = request.get("minute_step")
skip_column_compare = isinstance(minute_step, int) and not isinstance(minute_step, bool) and minute_step > 1
if skip_column_compare:
columns: list[str] = []
ledgers_by_time: dict[str, Any] = {}
windows_by_time: dict[str, Any] = {}
column_compare_ms = 0.0
else:
columns = column_times_for_compare(
column_times if column_times is not None else candidate_times,
representative_time,
)
compare_started = perf_counter()
ledgers_by_time = event_dasha_ledgers_by_time(request, built, columns)
windows_by_time = prospective_windows_by_time(request, built, columns)
column_compare_ms = round((perf_counter() - compare_started) * 1000, 1)
agreement = dasha_agreement(built, candidate_times)
stage = precision_stage(cluster, len(request.get("events") or []))
if not include_discriminators: