round 1: project the web transcript from append-origin events

Replace the surface-ordered fold with a log-ordered human transcript:
append-origin surface events at their own log positions plus one marker per
landed compaction checkpoint. Command folding, the tool-call index, and the
rev-keyed memo carry over unchanged.

Removes foldDegraded, the padding sentinels, baseSeq, and degradedSeqs() --
they existed only to satisfy the core fold's seq === index assertion. That
also closes the pagination hole A1 exposed: a page can carry a checkpoint
whose shadowed range fell outside the window, and nothing resolves
surfaceOp.start anymore.
This commit is contained in:
Hypatia May
2026-07-30 10:18:24 +08:00
parent c249ad8253
commit 8e5c792b50
45 changed files with 1385 additions and 602 deletions

View File

@@ -110,8 +110,8 @@ export function deriveTrajectoryLayout(input: TrajectoryLayoutInput): readonly T
lastAssistantTurn = node.turn
continue
}
if (node.kind === 'context') {
// No trajectory cell, but the surface still advances the duration cursor.
if (node.kind === 'context' || node.kind === 'compaction') {
// No trajectory cell, but transcript metadata still advances the duration cursor.
prevAbsTime = finiteTime(node.time) ?? prevAbsTime
continue
}

View File

@@ -45,7 +45,7 @@ export interface SpanStats {
* Fold snapshot nodes into per-turn spans. Only assistant nodes carry a turn
* number; user/steering/context/tool nodes attach to the turn last seen in
* sequence order (turn 0 collects the pre-assistant prologue).
* @param nodes - snapshot nodes in surface order.
* @param nodes - snapshot nodes in human transcript order.
* @returns spans ordered by first appearance.
*/
export function deriveSpans(nodes: ConversationSnapshot['nodes']): readonly TurnSpan[] {