mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 01:27:35 +00:00
* fix: preserve terminal retirement proof across renderer publications * refactor: share the live-surface filter between retirement proof preservation and projection The publication projection already dropped proofs whose surface is live; reuse that as one helper instead of a second inline scan. * fix: emit stored retirement proofs from host-authored snapshot writes Three callers built a snapshot, stored it, then emitted the pre-store object. Storing grafts on the preserved proofs, so those frames carried the stored snapshotVersion without the proofs; subscribers dedupe on version and never saw them. * fix: send terminal retirement proofs once per stream and fence them by occupant Proofs are pinned per worktree for the host's lifetime, so every snapshot publication — including a 50ms title tick — re-shipped up to 64 proofs (~17 KB on realistic ids) to every paired client. Negotiate session-tabs.retirement-proof-delta.v1: the host projects each session-tabs stream to send a proof only the first time that stream carries it, and a capable renderer keeps the union in a ledger keyed by (environment, worktree) with the same 64-entry bound and the same live-surface drop rule as the host, reset on removed frames and on a new connection generation. Legacy clients keep receiving the full list; CLI and mobile do not advertise the capability. Also inherit worktreeInstanceId onto identity-less host writes so a host write between two renderer occupants can no longer launder one occupant's proofs into the next. * fix: keep an empty proof delta distinguishable from a proof-less host A negotiated stream now sends retiredTerminalSurfaces: [] when nothing is new instead of omitting the field. Absence is the host's "I hold no proofs" signal — which is also what a recreated worktree's fresh host entry publishes — so the client ledger forgets on absence and a successor occupant never inherits its predecessor's proofs, even when the removed frame was missed. * test: pin ledger visibility against a legacy full-list host An old host sends the full proof list whenever it holds any and omits the field when it holds none. Prove the new client ledger shows exactly what a legacy client would see across that sequence, so forgetting on absence is verified not to regress the mixed-version case.
54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import type { RuntimeMobileSessionTabsResult } from '../../shared/runtime-types'
|
|
import { dropRetirementProofsForLiveSurfaces } from './mobile-session-terminal-retirement-proof'
|
|
import type {
|
|
RuntimeMobileSessionProjectionHost,
|
|
RuntimeMobileSessionProjectionInput
|
|
} from './runtime-mobile-session-projection-contract'
|
|
|
|
export function finalizeRuntimeMobileSessionTabsResult(
|
|
{ snapshot, tabs }: RuntimeMobileSessionProjectionInput,
|
|
host: RuntimeMobileSessionProjectionHost
|
|
): RuntimeMobileSessionTabsResult {
|
|
const active =
|
|
tabs.find((tab) => tab.isActive && tab.id === snapshot.activeTabId) ??
|
|
tabs.find((tab) => tab.isActive) ??
|
|
(snapshot.activeTabId ? (tabs[0] ?? null) : null)
|
|
const normalizedTabs =
|
|
active && !tabs.some((tab) => tab.isActive)
|
|
? tabs.map((tab) => (tab.id === active.id ? { ...tab, isActive: true } : tab))
|
|
: tabs
|
|
const tabGroups = host.sanitizeGroups(snapshot.tabGroups, normalizedTabs)
|
|
const validGroupIds = new Set(tabGroups?.map((group) => group.id) ?? [])
|
|
const tabGroupLayout =
|
|
snapshot.tabGroupLayout === undefined
|
|
? undefined
|
|
: host.pruneGroupLayout(snapshot.tabGroupLayout, validGroupIds)
|
|
const activeGroupId =
|
|
snapshot.activeGroupId && validGroupIds.has(snapshot.activeGroupId)
|
|
? snapshot.activeGroupId
|
|
: (tabGroups?.find((group) =>
|
|
active ? group.tabOrder.some((tabId) => host.collectTabIds([active]).has(tabId)) : false
|
|
)?.id ??
|
|
tabGroups?.[0]?.id ??
|
|
null)
|
|
return {
|
|
worktree: snapshot.worktree,
|
|
publicationEpoch: snapshot.publicationEpoch,
|
|
snapshotVersion: snapshot.snapshotVersion,
|
|
activeGroupId,
|
|
activeTabId: active?.id ?? null,
|
|
activeTabType: active?.type ?? null,
|
|
...(tabGroups ? { tabGroups } : {}),
|
|
...(snapshot.tabGroupLayout !== undefined ? { tabGroupLayout } : {}),
|
|
...(snapshot.retiredTerminalSurfaces
|
|
? {
|
|
retiredTerminalSurfaces: dropRetirementProofsForLiveSurfaces(
|
|
snapshot.retiredTerminalSurfaces,
|
|
snapshot.tabs
|
|
)
|
|
}
|
|
: {}),
|
|
tabs: normalizedTabs
|
|
}
|
|
}
|