fix(rectification): keep hour-window tail clusters and lock the search window (BUG-623, BUG-624, BUG-625)
Independent Staging Quality Gate / validate (push) Successful in 17m15s
Independent Staging Quality Gate / publish (push) Successful in 2m15s

Hour windows no longer drop later signature clusters. Credible range uses cluster coverage, and a mid-session spoken birth window gets a fixed reply without calling the model.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-09 20:45:11 +08:00
co-authored by Cursor
parent a31a5e2426
commit 6008c07c81
41 changed files with 1164 additions and 44 deletions
+56 -4
View File
@@ -21,7 +21,7 @@ PROBE_PHASE_HOLDOUT_VALIDATION = "holdout_validation"
MIN_DISCRIMINATOR_EVENTS = 3
MIN_DISCRIMINATOR_DOMAINS = 2
MAX_PUBLIC_CLUSTERS = 12
MAX_PUBLIC_CLUSTERS = 64
SIGNATURE_LAYERS = ("d1", "d9", "d10", "d24", "d4", "d12", "md")
NAKSHATRA_SPAN = 360.0 / 27.0
LAYER_VARGA = {
@@ -235,6 +235,55 @@ def expand_times_through_clusters(
return expanded
def _cluster_peak_score(cluster: dict[str, Any], by_time: dict[str, dict[str, Any]]) -> float:
scores = [
float(by_time[time].get("score") or 0)
for time in cluster.get("times") or []
if time in by_time
]
return max(scores) if scores else 0.0
def cap_clusters_by_adjacent_merge(
clusters: Sequence[dict[str, Any]],
by_time: dict[str, dict[str, Any]],
max_clusters: int = MAX_PUBLIC_CLUSTERS,
) -> list[dict[str, Any]]:
"""Keep the whole window. If there are too many clusters, merge adjacent weak ones."""
work = [
{
**cluster,
"times": list(cluster.get("times") or []),
"contexts": list(cluster.get("contexts") or []),
}
for cluster in clusters
if cluster.get("times")
]
while len(work) > max_clusters:
best_index = 0
best_key: tuple[float, float, int] | None = None
for index in range(len(work) - 1):
left = _cluster_peak_score(work[index], by_time)
right = _cluster_peak_score(work[index + 1], by_time)
key = (min(left, right), left + right, index)
if best_key is None or key < best_key:
best_key = key
best_index = index
left = work[best_index]
right = work[best_index + 1]
merged_times = sorted(set(left["times"] + right["times"]), key=_clock)
work[best_index] = {
"signature": left.get("signature"),
"signature_key": f"{left.get('signature_key')}+{right.get('signature_key')}",
"contexts": list(left.get("contexts") or []) + list(right.get("contexts") or []),
"times": merged_times,
"representative_time": merged_times[len(merged_times) // 2],
"representative": left.get("representative") or right.get("representative"),
}
del work[best_index + 1]
return work
def select_signature_representatives(
rows: Sequence[dict[str, Any]],
static_contexts: Sequence[dict[str, Any]] | None = None,
@@ -251,14 +300,17 @@ def select_signature_representatives(
clusters = cluster_contexts_by_signature(contexts)
else:
clusters = _adjacent_score_clusters(list(by_time.values()))
clusters = cap_clusters_by_adjacent_merge(clusters, by_time)
representatives: list[dict[str, Any]] = []
for cluster in clusters:
members = [by_time[time] for time in cluster["times"] if time in by_time]
if not members:
continue
representatives.append(max(members, key=lambda row: (float(row.get("score") or 0), str(row.get("time")))))
if len(representatives) >= MAX_PUBLIC_CLUSTERS:
break
best = max(members, key=lambda row: (float(row.get("score") or 0), str(row.get("time"))))
representatives.append({
**best,
"cluster_times": [time for time in cluster["times"] if time in by_time],
})
representatives.sort(key=lambda row: (-float(row.get("score") or 0), str(row.get("time"))))
return representatives or list(rows)[:1]
+24
View File
@@ -402,16 +402,40 @@ def build_candidate_decisions(
abs(score - other) <= TIE_ABSOLUTE_TOLERANCE
for other in all_scores
)
cluster_times, cluster_start, cluster_end = _cluster_span(row)
decisions.append({
"candidate_id": str(uuid5(NAMESPACE_URL, f"{POLICY_VERSION}:{result_id}:{row['time']}")),
"rank": index + 1,
"time": row["time"],
"relative_support": supports[index],
"tied_minute_count": tied_minute_count,
"cluster_times": cluster_times,
"cluster_start": cluster_start,
"cluster_end": cluster_end,
})
return decisions
def _cluster_span(row: dict[str, Any]) -> tuple[list[str], str, str]:
raw = row.get("cluster_times")
times: list[str] = []
seen: set[str] = set()
values = raw if isinstance(raw, list) and raw else [row.get("time")]
for item in values:
text = str(item or "")[:5]
if len(text) != 5 or text[2] != ":" or text in seen:
continue
seen.add(text)
times.append(text)
if not times:
clock = str(row.get("time") or "")[:5]
times = [clock] if len(clock) == 5 and clock[2] == ":" else []
times.sort(key=lambda value: int(value[:2]) * 60 + int(value[3:5]))
start = times[0] if times else str(row.get("time") or "")[:5]
end = times[-1] if times else start
return times, start, end
def _gate(passed: bool, **details: Any) -> dict[str, Any]:
return {"passed": passed, **details}