feat(rectification): show the credible range as a persistent timeline
The range is the only quantity that expresses convergence, and it existed only as a sentence in the transcript. The bar makes it permanent. It is the chat grid's first row, outside the scroll container, so scrollHeight is untouched and use-conversation-scroll-anchor needs no change. Its height is fixed because nothing observes it: a growing bar would alter clientHeight and let an anchored reader lose the tail. The axis is the current search window, not the opening one, since widening overruns the opening window. Marks are binary — in range or excluded — because relative support between candidate minutes carries no demonstrated minute-level discrimination (BUG-560, blocked). Band and marks move by transform alone; globals.css bans width transitions, and transform keeps the motion off the layout path. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016P5RoqzmUQEbeC2qjAkeGr
This commit is contained in:
co-authored by
Claude Fable 5
parent
109b1d7f0c
commit
ce91a0d23c
@@ -65,10 +65,30 @@ export type RectificationCaseSnapshotPayload = Readonly<{
|
||||
status?: unknown;
|
||||
accepted_time?: unknown;
|
||||
confirmed_time?: unknown;
|
||||
/**
|
||||
* Both are already on the wire from the case route; declaring them here
|
||||
* lets the timeline read the current search window and stage. No server
|
||||
* change was needed.
|
||||
*/
|
||||
candidate_range?: unknown;
|
||||
stage?: unknown;
|
||||
}>;
|
||||
turns?: unknown;
|
||||
}>;
|
||||
|
||||
/** `candidate_range` as `[start, end]`; null when absent or malformed. */
|
||||
export function searchWindowFromSnapshot(value: unknown): readonly [string, string] | null {
|
||||
if (!value || typeof value !== "object") return null;
|
||||
const row = value as { start_time?: unknown; end_time?: unknown };
|
||||
const start = typeof row.start_time === "string" ? row.start_time.trim() : "";
|
||||
const end = typeof row.end_time === "string" ? row.end_time.trim() : "";
|
||||
return start && end ? [start, end] : null;
|
||||
}
|
||||
|
||||
export function caseStageFromSnapshot(value: unknown): "minute" | "block_scan" | null {
|
||||
return value === "minute" || value === "block_scan" ? value : null;
|
||||
}
|
||||
|
||||
export function isRectificationCaseSnapshotPayload(value: unknown): value is RectificationCaseSnapshotPayload {
|
||||
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user