fix(rectification): separate adjacent minutes with transition proximity
Independent Staging Quality Gate / validate (push) Successful in 11m56s
Independent Staging Quality Gate / publish (push) Has been cancelled

Day-level events now score Vimshottari/Narayana transition closeness so
nearby candidate minutes can diverge, with gated quality probes and
answer-prior ranking so high-base-rate existence questions stay out.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-01 17:41:06 +08:00
parent 20df8c6022
commit 8743dcb105
18 changed files with 1402 additions and 55 deletions
@@ -103,6 +103,7 @@ export type EngineContrastProbe = Readonly<{
answer_class?: string;
sign?: string;
}>[];
target_evidence_id?: string;
}>;
const REMAINING_LAYERS = ["d24", "d5", "d10", "d9", "d4", "d7", "d12", "d2", "d11", "d30"] as const;
@@ -16,6 +16,7 @@ export type SnapshotStaleReason =
| "scoreable_evidence_changed"
| "candidate_set_superseded"
| "inference_revision_changed"
| "scoring_policy_changed"
| "fingerprint_missing";
export const SNAPSHOT_STALE_COPY: Readonly<Record<SnapshotStaleReason, string>> = {
@@ -23,6 +24,7 @@ export const SNAPSHOT_STALE_COPY: Readonly<Record<SnapshotStaleReason, string>>
scoreable_evidence_changed: "可评分证据已变化,请重新比较候选",
candidate_set_superseded: "已有更新的候选结果",
inference_revision_changed: "候选后验已更新,请使用当前结果",
scoring_policy_changed: "评分政策已更新,请重新比较候选",
fingerprint_missing: "候选快照缺少证据指纹,请重新比较候选",
};
@@ -50,6 +52,13 @@ export function classifySnapshotStaleReason(
if (snapshot.inferenceRevision !== current.inferenceRevision) {
return "inference_revision_changed";
}
if (
snapshot.scoringPolicyVersion
&& current.scoringPolicyVersion
&& snapshot.scoringPolicyVersion !== current.scoringPolicyVersion
) {
return "scoring_policy_changed";
}
return null;
}
@@ -62,7 +71,8 @@ export function scoreableSnapshotIsCurrent(
if (!snapshot.scoreableEvidenceFingerprint || !current.scoreableEvidenceFingerprint) return false;
return snapshot.scoreableEvidenceFingerprint === current.scoreableEvidenceFingerprint
&& snapshot.candidateSetVersion === current.candidateSetVersion
&& snapshot.inferenceRevision === current.inferenceRevision;
&& snapshot.inferenceRevision === current.inferenceRevision
&& snapshot.scoringPolicyVersion === current.scoringPolicyVersion;
}
/** No stored snapshot is not stale; a stored snapshot with a missing fingerprint is. */
@@ -85,6 +85,7 @@ export type ConflictProbe = Readonly<{
information_gain: number;
source: string;
choice_kind?: ProbeChoiceKind;
target_evidence_id?: string;
style_options?: readonly Readonly<{
label: string;
answer_class: AnswerClass;
@@ -50,9 +50,19 @@ import {
spokenFollowupForUser,
} from "./method-followup";
import type { SessionOutcomeKind } from "./confirmation-gate";
import { refinementFromDecisionReceipt } from "./refinement-packet";
import { prospectiveWindowsNarration, refinementFromDecisionReceipt } from "./refinement-packet";
import { projectCurrentQuestion } from "./turn-decision";
function withProspectiveWindows(
base: string,
receipt: Readonly<Record<string, unknown>> | null | undefined,
): string {
const extra = prospectiveWindowsNarration(
refinementFromDecisionReceipt(receipt).prospective_probes,
);
return extra ? `${base} ${extra}` : base;
}
export type ApplyChoiceCommand = Readonly<{
userId: string;
caseId: string;
@@ -386,10 +396,10 @@ export async function persistNextInterviewAfterChoice(input: {
});
}
return {
hostNarration: nonConvergingRangeNarration({
hostNarration: withProspectiveWindows(nonConvergingRangeNarration({
credibleRange: input.nextAction.credible_range,
representativeTime: input.nextAction.representative_time,
}),
}), latest.decisionReceipt),
choiceReady: false,
};
}
@@ -535,10 +545,10 @@ export async function persistNextInterviewIfIdle(input: {
return {
persisted: false,
choiceReady: false,
hostNarration: `${nonConvergingRangeNarration({
hostNarration: withProspectiveWindows(`${nonConvergingRangeNarration({
credibleRange: decision.credibleRange,
representativeTime: decision.representativeTime,
})} 可以从下面的时间里选一个采用。`,
})} 可以从下面的时间里选一个采用。`, dossier.latestResult?.decisionReceipt),
};
}
if (isNonConvergingRangeOffer(decision)) {
@@ -615,7 +625,7 @@ async function persistExhaustionCollect(input: {
return {
persisted,
choiceReady: false,
hostNarration: range,
hostNarration: withProspectiveWindows(range, input.decisionReceipt ?? input.dossier.latestResult?.decisionReceipt),
};
}
@@ -702,19 +712,19 @@ ${nextInterview.hostNarration}`
}
}
const adoptionNarration = nextAction.can_adopt
? `${nonConvergingRangeNarration({
? withProspectiveWindows(`${nonConvergingRangeNarration({
credibleRange: nextAction.credible_range,
representativeTime: nextAction.representative_time,
})} 可以从下面的时间里选一个采用。`
})} 可以从下面的时间里选一个采用。`, input.dossier.latestResult?.decisionReceipt)
: null;
const completedRangePrefix = input.narration.replace(RECTIFICATION_TERMINATION_COPY, "").trim();
const completedRangeNarration = nextAction.type === "complete_with_range"
? `${completedRangePrefix}
? withProspectiveWindows(`${completedRangePrefix}
${nonConvergingRangeNarration({
credibleRange: nextAction.credible_range,
representativeTime: nextAction.representative_time,
}, RECTIFICATION_TERMINATION_COPY)}`
}, RECTIFICATION_TERMINATION_COPY)}`, input.dossier.latestResult?.decisionReceipt)
: null;
if (adoptionNarration || completedRangeNarration) {
hostNarration = adoptionNarration ?? completedRangeNarration ?? hostNarration;
@@ -275,6 +275,7 @@ function eventQuestionPrompt(
family: string,
kind: EventProbeChoiceKind,
domain?: string | null,
probe?: DiscriminatingEventProbe | null,
): string {
const time = period.trim();
const topic = family.replace(/[?。]+$/g, "").trim();
@@ -283,6 +284,9 @@ function eventQuestionPrompt(
? "亲密关系里,你更接近哪一种相处方式?"
: "平时做事,你更接近下面哪一种?";
}
if (kind === "event_quality" && probe?.role === "distinguish" && probe.target_evidence_id && probe.user_meaning?.trim()) {
return probe.user_meaning.trim();
}
if (!topic) return time;
const dated = isConcreteChoicePeriod(period);
if (kind === "event_quality") {
@@ -342,7 +346,7 @@ function hypothesisFor(
} else if (!isConcreteChoicePeriod(period)) {
return null;
}
const prompt = eventQuestionPrompt(period, probe.event_family, kind, domain);
const prompt = eventQuestionPrompt(period, probe.event_family, kind, domain, probe);
const why = probe.user_meaning?.trim() || followup.user_prompt_hint.trim();
if (!why) return null;
return withStyleOptionLabels(prompt, why, null, styleOptions.options);
@@ -184,7 +184,7 @@ export function contrastPacketFromLatestResult(
const answered = new Set((inference?.answered_probes ?? []).map((item) => item.probe_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 [];
if (probe.source === "known_event_quality" && !probe.target_evidence_id) return [];
if (probe.source === "nakshatra_boundary") return [];
return [{
semantic_key: probe.semantic_key,
@@ -200,6 +200,7 @@ export function contrastPacketFromLatestResult(
? { choice_kind: probe.choice_kind }
: {}),
...(probe.style_options?.length ? { style_options: probe.style_options } : {}),
...(probe.target_evidence_id ? { target_evidence_id: probe.target_evidence_id } : {}),
}];
});
const merged = mergeEngineProbes(
@@ -214,6 +215,7 @@ export function contrastPacketFromLatestResult(
expected_outcomes: probe.expected_outcomes,
choice_kind: probe.choice_kind,
style_options: probe.style_options,
target_evidence_id: probe.target_evidence_id,
})),
);
return buildCandidateContrastPacket({
@@ -398,6 +400,7 @@ function completedProbeForSemanticKey(
expected_outcomes: event.expected_outcomes,
...(event.choice_kind ? { choice_kind: event.choice_kind } : {}),
...(event.style_options?.length ? { style_options: event.style_options } : {}),
...(event.target_evidence_id ? { target_evidence_id: event.target_evidence_id } : {}),
}],
candidateTimes: [...(event.candidate_ids ?? [])],
});
@@ -508,10 +508,13 @@ function remainingReverseVerifyProbes(
const dasha: DiscriminatingEventProbe[] = [];
const fallback: DiscriminatingEventProbe[] = [];
for (const probe of probes ?? []) {
if (probe.source === "known_event_quality" || probe.role === "clarify" || probe.phase === "event_clarification") continue;
const anchoredQuality = probe.source === "known_event_quality"
&& Boolean(probe.target_evidence_id)
&& probe.role === "distinguish";
if ((probe.source === "known_event_quality" && !anchoredQuality) || probe.role === "clarify" || probe.phase === "event_clarification") continue;
if (probe.role === "collect" || probe.phase === "evidence_collection") continue;
if (declined.has(probe.domain)) continue;
if (probeYearAlreadyCovered(evidence, probe.domain, probe.year)) continue;
if (!anchoredQuality && probeYearAlreadyCovered(evidence, probe.domain, probe.year)) continue;
if (probeBelowAdultFloor(probe, birthDate)) continue;
if (CONFLICT_PROBE_SOURCES.has(probe.source)) {
dasha.push(probe);
@@ -1109,7 +1112,8 @@ export function isOfferBlockingFollowup(
function discriminatorFromFollowup(followup: MethodFollowup | null): CandidateDiscriminatorProbe | null {
if (!followup) return null;
if (followup.choice_kind === "event_quality" || followup.intent === "clarify_event") return null;
if (followup.intent === "clarify_event") return null;
if (followup.choice_kind === "event_quality" && followup.intent !== "distinguish_candidates") return null;
const realProbe = followup.source === "event_probe"
|| followup.source === "reverse_verify"
|| (followup.source === "active_focus" && followup.intent === "distinguish_candidates");
@@ -226,6 +226,24 @@ export type DiscriminatingEventProbe = Readonly<{
right_time?: string;
choice_kind?: EventProbeChoiceKind;
style_options?: readonly EventProbeStyleOption[];
target_evidence_id?: string;
display_date_label?: string;
}>;
export type ProspectiveProbe = Readonly<{
candidate_label: string;
domain: string;
window_label: string;
user_meaning: string;
used_for_scoring: false;
}>;
export type DroppedPacketProbe = Readonly<{
semantic_key?: string;
reason: string;
domain?: string;
year?: number;
source?: string;
}>;
export type CandidateContrastOpportunity = Readonly<{
@@ -492,6 +510,8 @@ function parseExpectedOutcomes(value: unknown): ProbeExpectedOutcome[] {
}
function parseProbeRole(row: Readonly<Record<string, unknown>>, source: string): EventProbeRole {
const anchored = typeof row.target_evidence_id === "string" && row.target_evidence_id.length > 0;
if (source === "known_event_quality" && row.role === "distinguish" && anchored) return "distinguish";
if (row.role === "clarify" || source === "known_event_quality") return "clarify";
if (row.role === "collect" || source === "age_band") return "collect";
if (row.role === "holdout" || source === "oos_blind") return "holdout";
@@ -531,7 +551,13 @@ export function parseEventProbes(
|| CLOCK_IN_COPY.test(family)
|| row.unique_minute_claim === true
) continue;
if (!options.allowQuality && source === "known_event_quality") continue;
const evidenceId = typeof row.target_evidence_id === "string" && UUID.test(row.target_evidence_id)
? row.target_evidence_id
: null;
const anchoredQuality = source === "known_event_quality"
&& Boolean(evidenceId)
&& (row.role === "distinguish" || row.phase === "candidate_discriminator");
if (!options.allowQuality && source === "known_event_quality" && !anchoredQuality) continue;
const tracks = Array.isArray(row.tracks)
? row.tracks.filter((track): track is "vimshottari" | "narayana" => track === "vimshottari" || track === "narayana")
: [];
@@ -578,6 +604,8 @@ export function parseEventProbes(
}),
} : {}),
...(expectedOutcomes.length > 0 ? { expected_outcomes: expectedOutcomes } : {}),
...(evidenceId ? { target_evidence_id: evidenceId } : {}),
...(asText(row.display_date_label, 40) ? { display_date_label: asText(row.display_date_label, 40)! } : {}),
};
if (options.requireDistinguishContract && distinguishContractErrors({ ...probe, role: "distinguish" }).length > 0) continue;
rows.push(probe);
@@ -602,6 +630,65 @@ export function parseCollectionProbes(value: unknown): readonly DiscriminatingEv
));
}
export function parseDroppedPacketProbes(value: unknown): readonly DroppedPacketProbe[] {
if (!Array.isArray(value)) return [];
const rows: DroppedPacketProbe[] = [];
for (const item of value) {
const row = asRecord(item);
const reason = asText(row?.reason, 80);
if (!row || !reason) continue;
rows.push({
reason,
...(asText(row.semantic_key, 80) ? { semantic_key: asText(row.semantic_key, 80)! } : {}),
...(typeof row.domain === "string" ? { domain: row.domain } : {}),
...(typeof row.year === "number" && Number.isInteger(row.year) ? { year: row.year } : {}),
...(typeof row.source === "string" ? { source: row.source } : {}),
});
if (rows.length === 16) break;
}
return rows;
}
export function parseProspectiveProbes(value: unknown): readonly ProspectiveProbe[] {
if (!Array.isArray(value)) return [];
const rows: ProspectiveProbe[] = [];
for (const item of value) {
const row = asRecord(item);
const label = asText(row?.candidate_label, 8);
const domain = typeof row?.domain === "string" ? row.domain : "";
const window = asText(row?.window_label, 40);
const meaning = asText(row?.user_meaning, 200);
if (
!row
|| !label
|| !EVENT_PROBE_DOMAIN_SET.has(domain)
|| !window
|| !meaning
|| row.used_for_scoring === true
|| CLOCK_IN_COPY.test(meaning)
|| CLOCK_IN_COPY.test(window)
) continue;
rows.push({
candidate_label: label,
domain,
window_label: window,
user_meaning: meaning,
used_for_scoring: false,
});
if (rows.length === 3) break;
}
return rows;
}
export function prospectiveWindowsNarration(probes: readonly ProspectiveProbe[]): string | null {
const meanings = probes
.filter((item) => item.used_for_scoring === false)
.map((item) => item.user_meaning.trim())
.filter((item) => item.length > 0 && !CLOCK_IN_COPY.test(item));
if (meanings.length === 0) return null;
return meanings.join(" ");
}
export function parseCandidateContrastOpportunities(value: unknown): readonly CandidateContrastOpportunity[] {
if (!Array.isArray(value)) return [];
const rows: CandidateContrastOpportunity[] = [];
@@ -711,6 +798,8 @@ export function refinementFromDecisionReceipt(
event_clarification_probes: readonly DiscriminatingEventProbe[];
evidence_collection_probes: readonly DiscriminatingEventProbe[];
candidate_contrast_opportunities: readonly CandidateContrastOpportunity[];
dropped_probes: readonly DroppedPacketProbe[];
prospective_probes: readonly ProspectiveProbe[];
} {
return {
event_dasha_ledger: parseEventDashaLedger(receipt?.event_dasha_ledger),
@@ -728,5 +817,7 @@ export function refinementFromDecisionReceipt(
receipt?.evidence_collection_probes ?? receipt?.discriminating_event_probes,
),
candidate_contrast_opportunities: parseCandidateContrastOpportunities(receipt?.candidate_contrast_opportunities),
dropped_probes: parseDroppedPacketProbes(receipt?.dropped_probes),
prospective_probes: parseProspectiveProbes(receipt?.prospective_probes),
};
}