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
@@ -46,6 +46,7 @@ import { persistServerOwnedFocus, openQuestionFromPersistedFocus, isCollectFocus
import { buildMethodFollowupPlan } from "@/lib/rectification-agentic/v9/method-followup";
import { isNonConvergingRangeOffer, nonConvergingRangeNarration } from "@/lib/rectification-agentic/core/rectification-decision";
import { RECTIFICATION_USER_COPY } from "@/lib/rectification-agentic/user-copy";
import { parseDeclaredBirthWindow } from "@/lib/rectification-agentic/v9/declared-window-utterance";
import {
awaitTurnExitBeforeResponse,
finalizeSuccessfulTurnExit,
@@ -268,6 +269,30 @@ export async function POST(request: Request) {
);
}
if (action === "message" && parseDeclaredBirthWindow(parsed.data.message ?? "")) {
try {
const narration = RECTIFICATION_USER_COPY.declaredWindowLockedReply;
const turn = await persistV9DeterministicTurn(accounting, userId, caseId, {
requestId,
userMessage: parsed.data.message ?? null,
assistantMessage: narration,
});
return completedMessageResponse(narration, requestId, caseId, turn.turnId);
} catch (error) {
if (error instanceof RectificationToolServiceError) {
const mapped = mapRectificationRpcError(error);
return NextResponse.json(
{ error: mapped.message, message: mapped.message, code: mapped.code },
{ status: mapped.status },
);
}
return NextResponse.json(
{ error: "校正回复保存失败", message: "请稍后重试。" },
{ status: 500 },
);
}
}
const selectedModel = isStructuredChoice
? null
: await resolveSessionLanguageModel(