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>
This commit is contained in:
@@ -181,18 +181,27 @@ def _scan_layer_value(feature: dict[str, Any], layer: str) -> int | None:
|
||||
return raw if isinstance(raw, int) else None
|
||||
|
||||
|
||||
def window_scan(built: dict[str, Any]) -> dict[str, Any]:
|
||||
def window_scan(
|
||||
built: dict[str, Any],
|
||||
*,
|
||||
start_minute: int | None = None,
|
||||
end_minute: int | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""D1/D9/D10/D4/D5/D7/D12/D24/D2/D11/D30 plus display-only pada/Hora/Ghati/Bhava/Pranapada/KP."""
|
||||
counts: dict[str, set[int]] = {layer: set() for layer in _LAYER_LABEL}
|
||||
transitions: list[dict[str, Any]] = []
|
||||
previous: dict[str, int | None] | None = None
|
||||
for feature in _features(built):
|
||||
time = _feature_time(feature)
|
||||
if time and start_minute is not None and end_minute is not None:
|
||||
clock = _clock(time)
|
||||
if clock < start_minute or clock > end_minute:
|
||||
continue
|
||||
current = {layer: _scan_layer_value(feature, layer) for layer in _LAYER_LABEL}
|
||||
for layer, bucket in counts.items():
|
||||
value = current[layer]
|
||||
if isinstance(value, int):
|
||||
bucket.add(value)
|
||||
time = _feature_time(feature)
|
||||
if previous and time:
|
||||
for layer, label in _LAYER_LABEL.items():
|
||||
before = previous[layer]
|
||||
@@ -492,14 +501,43 @@ def oos_blind_prompts(request: dict[str, Any]) -> list[dict[str, Any]]:
|
||||
return prompts[:3]
|
||||
|
||||
|
||||
def cluster_scan(
|
||||
built: dict[str, Any],
|
||||
candidate_times: Sequence[str],
|
||||
representative_time: str | None,
|
||||
width_minutes: int | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""Scan only the indistinguishable candidate cluster, not the full declared range."""
|
||||
clocks: list[int] = []
|
||||
for raw in [*candidate_times, representative_time]:
|
||||
if isinstance(raw, str) and len(raw) >= 5:
|
||||
clocks.append(_clock(raw[:5]))
|
||||
if not clocks:
|
||||
return window_scan(built)
|
||||
lo, hi = min(clocks), max(clocks)
|
||||
span = hi - lo + 1
|
||||
width = max(int(width_minutes or 0), span, 1)
|
||||
if width > span:
|
||||
extra = width - span
|
||||
lo -= extra // 2
|
||||
hi += extra - extra // 2
|
||||
return window_scan(
|
||||
built,
|
||||
start_minute=max(0, lo),
|
||||
end_minute=min(24 * 60 - 1, hi),
|
||||
)
|
||||
|
||||
|
||||
def build_refinement_packet(
|
||||
request: dict[str, Any],
|
||||
built: dict[str, Any],
|
||||
*,
|
||||
representative_time: str | None,
|
||||
candidate_times: Sequence[str],
|
||||
cluster_width_minutes: int | None = None,
|
||||
) -> dict[str, Any]:
|
||||
scan = window_scan(built)
|
||||
cluster = cluster_scan(built, candidate_times, representative_time, cluster_width_minutes)
|
||||
ledger = event_dasha_ledger(request, built, representative_time)
|
||||
agreement = dasha_agreement(built, candidate_times)
|
||||
return {
|
||||
@@ -509,7 +547,7 @@ def build_refinement_packet(
|
||||
"dasha_agreement": agreement,
|
||||
"lagna_contrast": lagna_contrast(built),
|
||||
"nakshatra_boundary": nakshatra_boundary(built, representative_time),
|
||||
"precision_stage": precision_stage(scan, len(request.get("events") or [])),
|
||||
"precision_stage": precision_stage(cluster, len(request.get("events") or [])),
|
||||
"oos_blind_prompts": oos_blind_prompts(request),
|
||||
"unique_minute_claim": False,
|
||||
"confirmation_allowed": False,
|
||||
|
||||
Reference in New Issue
Block a user