Skip to content

tracking(import): harden remaining external-session boundary edge cases #5402

Description

@wutongyuonce

Context

PR #5308 establishes the shared Runtime Host external-session catalog/import path and closes its merge-blocking correctness findings. The review also identified several local edge cases that are safe to address as follow-up slices rather than expanding that PR further.

Review: #5308 (review)

This is a tracking issue. Each checkbox has its own authority and should remain an independently reviewable change; do not solve them by adding shared client state or by duplicating source rules outside their owner.

Follow-up slices

  • Bound filesystem cursor identity at the Codex adapter authority. A deeply nested rollout path can produce an encoded filesystem cursor larger than the 512-byte Host wire limit. Bound the catalog key before emitting it or replace the path payload with a fixed-size identity while preserving deterministic keyset continuation.
  • Coalesce TUI catalog search requests. pi-tui-runner.ts currently sends a Host query on every keystroke. Add a small debounce/coalescing boundary while retaining the existing revision guard that rejects stale responses.
  • Restore source Session ID search in the shared matcher. externalSessionMatchesQuery() currently matches title and cwd only. Include the source summary ID so pasting a Codex/Claude/OpenCode Session ID works in both Desktop and TUI without client-side filtering.
  • Finish deterministic projection before marking import commit started. projectSessionCatalogMessages(canonicalMessages) is currently evaluated after onCommitStarted(). Compute all deterministic projections first so a projection error remains a definite pre-commit failure instead of commit_outcome_unknown.
  • Align the memory execution-store lookup with SQLite publication semantics. The memory test double must exclude transcriptLedgerVersion === 0 staged Sessions from imported-copy counts.
  • Align Codex text timestamp ordering with displayed normalization. The SQL cursor key is now self-consistent, but CAST('2026-08-08T00:00:00Z' AS REAL) becomes 2026 while normalizeEpochMs() displays the same value as a 2026 epoch timestamp. Decide the accepted source timestamp shapes once and use that rule for both catalog order and summary timestamps. The regression must assert returned order, not sort the collected IDs before comparison.

Acceptance criteria

  • Every slice has an owner-level regression that fails when its stated invariant is removed.
  • Cursor and query work remains bounded at the source adapter or client seam that owns it.
  • Desktop and TUI consume the same shared matching semantics.
  • Pre-commit deterministic failures cannot be reported as an unknown durable outcome.
  • SQLite and memory test stores agree on staged Session invisibility.
  • Codex catalog ordering, emitted cursor position, and displayed timestamp share one documented normalization contract.
  • No new protocol field, cross-package cache, TTL/LRU, or client recovery ledger is introduced unless a slice demonstrates that the existing seam cannot satisfy its invariant.

Relevant code

  • packages/storage/src/codex-session-adapter.ts
  • packages/core/src/external-session.ts
  • packages/cli/src/pi-tui-runner.ts
  • packages/storage/src/session-store.ts
  • packages/storage/src/test-only/memory-execution-session.ts

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

trackingTracking or umbrella issue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions