fix(rectification): stop spoken collect once the training gate opens (BUG-1084..1087)

Once the discriminator training gate is open, only choice cards are asked
and the range card goes out when they are exhausted; targeted lines, their
re-ask and guided windows no longer hold the card or invite more events.
Delivery body says how many choice questions were used instead of the event
fit percent; narration names an excluded cluster instead of "range
unchanged"; a delivered turn no longer carries a collect question.

Offline replay (v4, 3 radii x 2 directions): truth in range 20/20 in every
cell; guided-window injections give the same width in truth and opposite
directions, so red line 1 was revised by product to truth-in-range only.
Skill 10.0.31 -> 10.0.32 (10.0.31 kept as deprecated for pinned cases).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
Jesse_Chen
2026-09-29 10:06:57 +08:00
co-authored by Claude Opus 5.5
parent bcf0c86feb
commit ea21743b09
72 changed files with 4249 additions and 259 deletions
@@ -12,6 +12,8 @@ import {
RECTIFICATION_EMPTY_COPY,
RECTIFICATION_QUESTION_RETRY_INTERVAL_MS,
RECTIFICATION_COLLECT_WAITING_PLACEHOLDER,
RECTIFICATION_COMPOSER_DEFAULT_PLACEHOLDER,
RECTIFICATION_DELIVERED_PLACEHOLDER,
recompareHistoricalResult,
contrastProbesFromReceipt,
type RectificationCaseSnapshotPayload,
@@ -658,7 +660,9 @@ export function RectificationAgenticChat(props: RectificationAgenticChatProps) {
? "请回答上面的问题…"
: !snapshotFailure && questionGap === "collect_waiting"
? RECTIFICATION_COLLECT_WAITING_PLACEHOLDER
: "继续说你记得的人生经历,或回答刚才的问题…"}
: questionGap === "delivered"
? RECTIFICATION_DELIVERED_PLACEHOLDER
: RECTIFICATION_COMPOSER_DEFAULT_PLACEHOLDER}
maxLength={RECTIFICATION_COMPOSER_MAX_LENGTH}
inputDisabled={readonly}
submitLabel="发送"
@@ -5,6 +5,7 @@ import { useEffect, useRef } from "react";
import {
groupWindowTransitions,
houseTableToNorthIndianChart,
precisionStageBoardCopy,
rectificationBoardPeekCopy,
workingRectificationTime,
type RectificationBoardDiff,
@@ -64,7 +65,7 @@ function RectificationBoardBody({
const displayMinutes = grouped.filter((row) => row.displayLayers.length > 0);
const changedHouses = new Set(diff.houseNumbers);
const changedMinutes = new Set(diff.transitionMinutes);
const stage = result?.precisionStage?.user_meaning
const stage = precisionStageBoardCopy(result?.precisionStage)
?? result?.natalRecast?.user_meaning
?? null;
const ledger = result?.eventDashaLedger ?? [];