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:
Jesse_Chen
2026-08-21 02:01:57 +08:00
parent 5fdabfae89
commit a88467ffa8
12 changed files with 180 additions and 41 deletions
+17 -10
View File
@@ -481,11 +481,13 @@ def build_decision_receipt(
reasons = [*acceptance_reasons, *confirmation_reasons]
representative = candidate_decisions[0] if candidate_decisions else None
width = indistinguishable_width_minutes(candidate_decisions)
packet = build_refinement_packet(
request,
built,
representative_time=representative["time"] if representative else None,
candidate_times=[item["time"] for item in candidate_decisions],
cluster_width_minutes=width,
)
if packet["dasha_agreement"]["status"] == "conflict":
if overall_confidence == "high":
@@ -494,7 +496,6 @@ def build_decision_receipt(
overall_confidence = "low"
reasons.append("vimshottari_narayana_conflict")
confirmation_reasons.append("vimshottari_narayana_conflict")
width = indistinguishable_width_minutes(candidate_decisions)
adjacent_passed = unique_top["passed"] and width <= MAX_CONFIRMATION_WIDTH_MINUTES
confirmation_event_quality = len(scoreable_events) >= MIN_CONFIRMATION_EVENTS
confirmation_domain_quality = len(domains) >= MIN_CONFIRMATION_DOMAINS
@@ -508,17 +509,23 @@ def build_decision_receipt(
confirmation_reasons.append("insufficient_confirmation_margin")
if not adjacent_passed:
confirmation_reasons.append("adjacent_minutes_indistinguishable")
propose_allowed = all((
acceptance_allowed,
unique_top["passed"],
diagnostic_quality["passed"],
required_layers["passed"],
confirmation_event_quality,
confirmation_domain_quality,
adjacent_passed,
))
fit_high = packet["event_fit_rate"].get("band") == "high"
propose_allowed = bool(
acceptance_allowed
and required_layers["passed"]
and (
fit_high
or all((
diagnostic_quality["passed"],
confirmation_event_quality,
confirmation_domain_quality,
))
)
)
engine_granted = all((
propose_allowed,
unique_top["passed"],
adjacent_passed,
confirmation_margin,
not dasha_conflict,
))
+41 -3
View File
@@ -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,