fix(rectification): ask from the scored probe catalog, not snapshot leftovers
Independent Staging Quality Gate / validate (push) Successful in 9m30s
Independent Staging Quality Gate / publish (push) Has been cancelled

Empty snapshot candidates were starving remaining D24 splits, so the
TypeScript follow-up chain asked the low-gain Python career probe.
Read paths now share one inference+engine catalog and yield a stale
low-gain distinguish card to the current winner.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-28 09:48:57 +08:00
co-authored by Cursor
parent 4bf074b2bf
commit ca6252ecb6
9 changed files with 417 additions and 139 deletions
@@ -80,8 +80,11 @@ export type EngineContrastProbe = Readonly<{
information_gain?: number;
expected_outcomes?: readonly Readonly<{
answer_class?: string;
outcomeId?: string;
supports?: readonly string[];
supportsCandidateIds?: readonly string[];
conflicts?: readonly string[];
conflictsCandidateIds?: readonly string[];
}>[];
left_time?: string;
right_time?: string;
@@ -312,11 +315,12 @@ export function buildCandidateContrastPacket(input: {
candidateTimes: input.candidateTimes ?? [],
transitions: input.transitions ?? [],
});
const presentKeys = new Set(fromEngine.map((item) => item.semanticKey));
const fromVarga = vargaProbe(
remainingSplits,
input.candidateSetVersion,
input.calculationResultId ?? null,
asked,
new Set([...asked, ...presentKeys]),
);
const probes = [...fromEngine, ...(fromVarga ? [fromVarga] : [])]
.sort((left, right) => right.informationGain - left.informationGain);
@@ -515,15 +519,30 @@ export function conflictProbesFromContrast(
});
}
function inferredContrastChoiceKind(
semanticKey: string,
explicit?: ContrastChoiceKind,
): ContrastChoiceKind {
if (explicit === "varga_style" || explicit === "event_quality" || explicit === "existence") {
return explicit;
}
const layer = semanticKey.match(/^varga\.(d\d+)/)?.[1];
if (layer === "d9" || layer === "d10") return "varga_style";
if (layer === "d24" || layer === "d5") return "event_quality";
return "existence";
}
function probeFromEngine(
probe: EngineContrastProbe,
candidateSetVersion: string,
calculationResultId: string | null,
): CandidateDiscriminatorProbe | null {
const outcomes = (probe.expected_outcomes ?? []).flatMap((row) => {
const outcomeId = typeof row.answer_class === "string" ? row.answer_class : "";
const supports = row.supports ?? [];
const conflicts = row.conflicts ?? [];
const outcomeId = typeof row.answer_class === "string" && row.answer_class.trim()
? row.answer_class
: typeof row.outcomeId === "string" ? row.outcomeId : "";
const supports = row.supports ?? row.supportsCandidateIds ?? [];
const conflicts = row.conflicts ?? row.conflictsCandidateIds ?? [];
if (!outcomeId) return [];
return [{ outcomeId, supportsCandidateIds: supports, conflictsCandidateIds: conflicts }];
});
@@ -553,7 +572,7 @@ function probeFromEngine(
domain: probe.domain ?? null,
year: probe.year ?? null,
semanticKey,
choiceKind: probe.choice_kind,
choiceKind: inferredContrastChoiceKind(semanticKey, probe.choice_kind),
styleOptions: styleOptionsFromEngine(probe.style_options),
};
}
@@ -10,6 +10,7 @@ import {
selectDiscriminatorProbe,
volunteeredDomainsFromEvidence,
type CandidateContrastPacket,
type EngineContrastProbe,
} from "../core/candidate-contrast-packet.ts";
import {
decideRectification,
@@ -84,6 +85,22 @@ export function candidateScoresFromDossier(latest: DecisionDossier["latestResult
return authoritativeCandidateProjection(latest).scores;
}
const CLOCK_TIME = /^(?:[01]\d|2[0-3]):[0-5]\d$/;
export function discriminatorCandidateTimes(
latest: DecisionDossier["latestResult"],
): string[] {
const inference = previousInferenceFromReceipt(latest?.decisionReceipt ?? null);
const fromInference = [...new Set(
(inference?.candidates ?? [])
.filter((item) => item.status !== "eliminated")
.map((item) => item.time)
.filter((time) => CLOCK_TIME.test(time)),
)];
if (fromInference.length >= 2) return fromInference;
return candidateScoresFromDossier(latest).map((item) => item.time);
}
function holdoutStatusFromInference(inference: ReturnType<typeof previousInferenceFromReceipt>) {
if (!inference) return "unavailable" as const;
const hasHoldout = inference.events.some((item) => item.usage === "holdout");
@@ -105,15 +122,47 @@ function holdoutStatusFromState(state: InferenceState) {
return "unavailable" as const;
}
export function contrastPacketFromDossier(dossier: DecisionDossier): CandidateContrastPacket {
const windowScan = windowScanFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null);
const refinement = refinementFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null);
const inference = previousInferenceFromReceipt(dossier.latestResult?.decisionReceipt ?? null);
const candidateScores = candidateScoresFromDossier(dossier.latestResult);
export function contrastPacketFromLatestResult(
latest: DecisionDossier["latestResult"],
evidence: DecisionDossier["evidence"] = [],
): CandidateContrastPacket {
const windowScan = windowScanFromDecisionReceipt(latest?.decisionReceipt ?? null);
const refinement = refinementFromDecisionReceipt(latest?.decisionReceipt ?? null);
const inference = previousInferenceFromReceipt(latest?.decisionReceipt ?? null);
const answered = new Set((inference?.answered_probes ?? []).map((item) => item.id));
const fromInference: EngineContrastProbe[] = (inference?.probes ?? []).flatMap((probe) => {
if (answered.has(probe.id) || probe.information_gain <= 0) return [];
if (probe.source === "known_event_quality") return [];
return [{
semantic_key: probe.semantic_key,
candidate_split_hash: probe.candidate_split_hash,
domain: probe.domain,
year: probe.year > 0 ? probe.year : undefined,
user_meaning: probe.question,
information_gain: probe.information_gain,
expected_outcomes: probe.expected_outcomes,
candidate_ids: probe.candidate_ids,
}];
});
const merged = mergeEngineProbes(
fromInference,
refinement.discriminating_event_probes.map((probe) => ({
semantic_key: probe.semantic_key,
candidate_split_hash: probe.candidate_split_hash,
domain: probe.domain,
year: probe.year,
user_meaning: probe.user_meaning,
information_gain: probe.information_gain,
expected_outcomes: probe.expected_outcomes,
candidate_ids: probe.candidate_ids,
choice_kind: probe.choice_kind,
style_options: probe.style_options,
})),
);
return buildCandidateContrastPacket({
candidateSetVersion: inference?.candidate_set_id ?? dossier.latestResult?.resultId ?? "none",
calculationResultId: dossier.latestResult?.resultId ?? null,
engineProbes: refinement.discriminating_event_probes,
candidateSetVersion: inference?.candidate_set_id ?? latest?.resultId ?? "none",
calculationResultId: latest?.resultId ?? null,
engineProbes: merged,
vargaDifferences: [
...(windowScan?.d9_candidates_differ && windowScan.d9_sign_names.length >= 2
? [{ layer: "d9", signs: windowScan.d9_sign_names }]
@@ -122,16 +171,57 @@ export function contrastPacketFromDossier(dossier: DecisionDossier): CandidateCo
? [{ layer: "d10", signs: windowScan.d10_sign_names }]
: []),
],
candidateTimes: candidateScores.map((item) => item.time),
candidateTimes: discriminatorCandidateTimes(latest),
transitions: windowScan?.transitions ?? [],
askedKeys: askedDiscriminatorKeys(
dossier.latestResult?.decisionReceipt,
dossier.evidence,
),
volunteeredDomains: volunteeredDomainsFromEvidence(dossier.evidence),
askedKeys: askedDiscriminatorKeys(latest?.decisionReceipt, evidence),
volunteeredDomains: volunteeredDomainsFromEvidence(evidence),
});
}
function mergeEngineProbes(
...groups: ReadonlyArray<readonly EngineContrastProbe[] | undefined>
): EngineContrastProbe[] {
const byKey = new Map<string, EngineContrastProbe>();
for (const group of groups) {
for (const probe of group ?? []) {
const key = probe.semantic_key?.trim() ?? "";
if (!key) continue;
const current = byKey.get(key);
if (!current || (probe.information_gain ?? 0) > (current.information_gain ?? 0)) {
byKey.set(key, probe);
}
}
}
return [...byKey.values()];
}
export function contrastPacketFromDossier(dossier: DecisionDossier): CandidateContrastPacket {
return contrastPacketFromLatestResult(dossier.latestResult, dossier.evidence);
}
export function rectificationFollowupCatalog(
latest: DecisionDossier["latestResult"],
evidence: DecisionDossier["evidence"] = [],
) {
const receipt = latest?.decisionReceipt ?? null;
const refinement = refinementFromDecisionReceipt(receipt);
const inference = previousInferenceFromReceipt(receipt);
return {
contrastPacket: contrastPacketFromLatestResult(latest, evidence),
topCandidateTimes: discriminatorCandidateTimes(latest),
askedProbeKeys: askedDiscriminatorKeys(receipt, evidence),
eventProbes: refinement.discriminating_event_probes,
eventClarificationProbes: refinement.event_clarification_probes,
evidenceCollectionProbes: refinement.evidence_collection_probes,
precisionStage: refinement.precision_stage?.current ?? null,
nakshatraBoundary: refinement.nakshatra_boundary,
oosBlindPrompts: refinement.oos_blind_prompts,
holdoutEvents: (inference?.events ?? [])
.filter((item) => item.usage === "holdout")
.map((item) => ({ domain: item.domain, year: item.year })),
};
}
function contrastPacketFromState(state: InferenceState): CandidateContrastPacket {
const answered = new Set(state.answered_probes.map((item) => item.probe_id));
return buildCandidateContrastPacket({
@@ -6,15 +6,13 @@
* Card identity is the persisted focus UUID plus the inference revision.
*/
import { askedKeysFromLedgerEvidence } from "../core/candidate-contrast-packet.ts";
import { askedProbeKeysFromReceipt, previousInferenceFromReceipt } from "./inference-adapter";
import { previousInferenceFromReceipt } from "./inference-adapter";
import {
contrastPacketFromDossier,
decideFromDossier,
rectificationFollowupCatalog,
} from "./decision-from-dossier";
import { evidenceLedgerFingerprint } from "./tool-service";
import { projectRectificationChoiceCard } from "./method-followup";
import { refinementFromDecisionReceipt } from "./refinement-packet";
import {
internalObservationsFromWindowScan,
windowScanFromDecisionReceipt,
@@ -62,11 +60,11 @@ export function choiceCardFromCaseDossier(dossier: {
};
turns?: readonly Readonly<{ role: string; text: string | null }>[];
}): RectificationChoiceCard | null {
const windowScan = windowScanFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null);
const observations = internalObservationsFromWindowScan(windowScan);
const refinement = refinementFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null);
const catalog = rectificationFollowupCatalog(dossier.latestResult, dossier.evidence);
const observations = internalObservationsFromWindowScan(
windowScanFromDecisionReceipt(dossier.latestResult?.decisionReceipt ?? null),
);
const inference = previousInferenceFromReceipt(dossier.latestResult?.decisionReceipt ?? null);
const contrastPacket = contrastPacketFromDossier(dossier);
const decision = decideFromDossier(dossier, {
currentEvidenceFingerprint: evidenceLedgerFingerprint(dossier.evidence as never),
});
@@ -74,35 +72,23 @@ export function choiceCardFromCaseDossier(dossier: {
.reverse()
.find((turn) => turn.role === "assistant")
?.text ?? null;
const holdoutEvents = (inference?.events ?? [])
.filter((item) => item.usage === "holdout")
.map((item) => ({ domain: item.domain, year: item.year }));
return projectRectificationChoiceCard({
evidence: dossier.evidence,
activeFocus: dossier.conversationSummary.activeFocus,
declinedTopics: dossier.conversationSummary.declinedSkippedTopics,
observations,
sessionOutcome: decision.sessionOutcome,
...catalog,
precisionStage: decision.precisionStage === "collect_events"
? "collect_events"
: decision.precisionStage === "ready_to_adopt"
? "ready_to_adopt"
: refinement.precision_stage?.current,
nakshatraBoundary: refinement.nakshatra_boundary,
oosBlindPrompts: refinement.oos_blind_prompts,
eventProbes: refinement.discriminating_event_probes,
eventClarificationProbes: refinement.event_clarification_probes,
evidenceCollectionProbes: refinement.evidence_collection_probes,
askedProbeKeys: [
...askedProbeKeysFromReceipt(dossier.latestResult?.decisionReceipt),
...askedKeysFromLedgerEvidence(dossier.evidence),
],
: catalog.precisionStage,
accepted: Boolean(dossier.case.acceptedTime),
selectionAllowed: decision.selectionAllowed,
proposeAllowed: decision.proposeAllowed,
confirmationAllowed: decision.canConfirmExactMinute,
caseRevision: inference?.revision ?? 0,
contrastPacket,
candidateScores: decision.separation.ranked.map((item) => ({
time: item.time,
score: item.score,
@@ -111,7 +97,6 @@ export function choiceCardFromCaseDossier(dossier: {
latestAssistantText,
candidatesSeparated: decision.separation.sufficient,
holdoutValidation: decision.holdoutValidation,
holdoutEvents,
});
}
@@ -36,6 +36,8 @@
* Coverage complete never means adopt. Horary does not block cards.
* A/B/C/D choice frames attach only when candidates already diverge
* (event probes, precision stage, varga observation, nakshatra, or holdout).
* An already-open distinguish card yields if the live catalog winner is a
* different probe. Do not keep a low-gain Python event card over D24.
*/
import {
@@ -499,9 +501,19 @@ function followupOwnedProbe(
};
}
function persistedFocusProbeKey(focus: MethodFollowupFocus | null | undefined): string {
const key = focus?.expectedAnswerSchema?.semantic_key;
return typeof key === "string" && key.trim() ? key.trim() : "";
}
function rankedDiscriminatorKey(row: RankedDiscriminator | null): string {
if (!row) return "";
return row.eventProbe?.semantic_key ?? row.contrastProbe?.semanticKey ?? "";
}
function rankRenderableDiscriminators(input: {
eventProbes: readonly DiscriminatingEventProbe[];
contrastProbe: CandidateDiscriminatorProbe | null;
contrastProbes: readonly CandidateDiscriminatorProbe[];
askedKeys: ReadonlySet<string>;
topCandidateTimes?: readonly string[];
}): RankedDiscriminator[] {
@@ -520,7 +532,9 @@ function rankRenderableDiscriminators(input: {
for (const probe of input.eventProbes) {
push(renderableEventProbe(probe, input.askedKeys, top));
}
push(input.contrastProbe ? renderableContrastProbe(input.contrastProbe, input.askedKeys, top) : null);
for (const probe of input.contrastProbes) {
push(renderableContrastProbe(probe, input.askedKeys, top));
}
return rows.sort((left, right) => right.score - left.score || (right.eventProbe?.information_gain ?? right.contrastProbe?.informationGain ?? 0) - (left.eventProbe?.information_gain ?? left.contrastProbe?.informationGain ?? 0));
}
@@ -811,6 +825,7 @@ export function buildMethodFollowupPlan(input: {
accepted?: boolean;
candidatesSeparated?: boolean;
contrastPacket?: CandidateContrastPacket | null;
topCandidateTimes?: readonly string[];
holdoutValidation?: HoldoutValidationStatus;
holdoutEvents?: readonly Readonly<{ domain: string; year: number | null }>[];
}): MethodFollowupPlan {
@@ -879,7 +894,7 @@ export function buildMethodFollowupPlan(input: {
const sessionOutcome = input.sessionOutcome ?? "collect_evidence";
const candidatesSeparated = input.candidatesSeparated === true;
const contrastProbe = selectDiscriminatorProbe(input.contrastPacket ?? null);
const contrastProbes = candidatesSeparated ? [] : [...(input.contrastPacket?.probes ?? [])];
// Legacy known-event quality cards were never backed by an inference probe.
// Ignore them so existing cases resume evidence collection instead of exposing a stale card.
const focus = input.activeFocus?.intent === "clarify_event" ? null : input.activeFocus ?? null;
@@ -887,6 +902,20 @@ export function buildMethodFollowupPlan(input: {
focus && (focus.intent === "reverse_verify" || focus.intent === "out_of_sample_check"),
);
const coverageComplete = blockingMethodsCovered(methods);
const askedKeys = new Set([
...(input.askedProbeKeys ?? []),
...askedKeysFromLedgerEvidence(input.evidence),
]);
const rankedDiscriminators = dashaCovered && meetsAcceptanceEventQuality(input.evidence)
? rankRenderableDiscriminators({
eventProbes: remainingConflictProbes(input.eventProbes, input.evidence, declined, askedKeys),
contrastProbes,
askedKeys,
topCandidateTimes: input.topCandidateTimes,
})
: [];
const bestDiscriminator = rankedDiscriminators[0] ?? null;
const catalogWinnerKey = rankedDiscriminatorKey(bestDiscriminator);
const staleCollectFocus = Boolean(
focus
&& focus.intent === "collect_method_evidence"
@@ -898,9 +927,17 @@ export function buildMethodFollowupPlan(input: {
|| (focus.targetDomain === "horary" && horaryStatus !== "uncovered")
),
);
const staleDiscriminatorFocus = Boolean(
focus
&& focus.intent === "distinguish_candidates"
&& catalogWinnerKey
&& persistedFocusProbeKey(focus)
&& persistedFocusProbeKey(focus) !== catalogWinnerKey
);
if (
focus
&& !staleCollectFocus
&& !staleDiscriminatorFocus
&& (sessionOutcome !== "adopt_representative"
&& sessionOutcome !== "validated_range"
&& sessionOutcome !== "exact_minute_confirmed"
@@ -1018,18 +1055,6 @@ export function buildMethodFollowupPlan(input: {
let next: MethodFollowup | null = null;
const stage = input.precisionStage ?? null;
const askedKeys = new Set([
...(input.askedProbeKeys ?? []),
...askedKeysFromLedgerEvidence(input.evidence),
]);
const rankedDiscriminators = dashaCovered && meetsAcceptanceEventQuality(input.evidence)
? rankRenderableDiscriminators({
eventProbes: remainingConflictProbes(input.eventProbes, input.evidence, declined, askedKeys),
contrastProbe: !candidatesSeparated ? contrastProbe : null,
askedKeys,
})
: [];
const bestDiscriminator = rankedDiscriminators[0] ?? null;
const followupFromRanked = (ranked: RankedDiscriminator): MethodFollowup => {
if (ranked.kind === "event" && ranked.eventProbe) {
const conflictProbe = ranked.eventProbe;