Skip to content

perf(share): stat-stamp listing cache — warm picker opens in milliseconds - #159

Open
od0 wants to merge 5 commits into
bryan/parallel-gatherfrom
bryan/listing-cache
Open

perf(share): stat-stamp listing cache — warm picker opens in milliseconds#159
od0 wants to merge 5 commits into
bryan/parallel-gatherfrom
bryan/listing-cache

Conversation

@od0

@od0 od0 commented Aug 4, 2026

Copy link
Copy Markdown

Layer 3 of the picker-performance stack (on #157, under #154). Closes #158.

A sidecar stat-stamp cache makes warm session listings effectively instant: ~/.toolpath/listing-cache.json, keyed by the sync machinery's existing stamps (claude: whole-chain stamp keyed by chain head; codex: rollout mtime+size; opencode: row updated-at). A gather rebuilds rows for stamp-matching artifacts from the cache and scans only new/changed ones; vanished artifacts drop out; a corrupt or missing cache degrades to a fresh scan. The expensive three providers (claude/codex/opencode) are cache-backed; adding another is one call site. Enumeration reuses sync/sources.rs's ArtifactSource impls via new per-manager constructors, so cache stamps and sync stamps can never disagree — one enumeration path.

Correctness gate: warm-gather rows asserted field-for-field identical to a cold scan; invalidation pinned by append/rotate/delete tests (13 new tests). Ranking, row formatting, and the gather_artifacts signature unchanged. matches_cwd is never cached (it depends on the caller's cwd).

Measured (synthetic 300-session tree, release): cold 75 ms → warm 6.8 ms. On a real 3.9 GB tree via #154's picker: first run ~2.3 s (one-time hydration), then 0.03 s end-to-end.

path-cli 0.16.2 → 0.16.3. Design doc: docs/superpowers/specs/2026-08-04-listing-cache-design.md.

od0 added 5 commits August 4, 2026 13:53
listing-cache.json under $TOOLPATH_CONFIG_DIR (0600, atomic
temp+rename), versioned, treated as empty on any load failure. No
advisory lock: last-writer-wins is fine for a cache. Stores picker-row
fields per artifact next to the same modified+size stamps the sync
manifest uses; matches_cwd is deliberately not cached.
gather_artifacts now enumerates the three expensive providers through
the same ArtifactSource machinery sync uses (per-manager constructors
exposed from sync/sources.rs), rebuilds rows from the listing cache on
a stamp hit, and scans only new/changed artifacts: claude per missed
chain via read_conversation_metadata, codex per missed rollout via
read_metadata over one lazy id->path walk, opencode via one full
list_session_metadata pass on the first miss. Ordering reproduces the
fresh scans (within-project / global activity sort); the project
filter applies after reconstruction so the cache stays filter-
agnostic; sections are written back only when they changed.

Correctness gates: cold==warm row equality, cache-tamper visibility,
append and chain-rotation invalidation, deletion self-heal, corrupt-
cache tolerance, post-reconstruction project filtering. Existing
gather tests now pin $TOOLPATH_CONFIG_DIR so they stop touching the
real ~/.toolpath.
@od0 od0 changed the title bryan/listing cache perf(share): stat-stamp listing cache — warm picker opens in milliseconds Aug 4, 2026
@od0
od0 marked this pull request as ready for review August 4, 2026 17:56
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

🔍 Preview deployed: https://c2c5bf8c.toolpath.pages.dev

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Instant picker startup: stat-stamp metadata cache for session listing

2 participants