Epic: boot warm-up and listing-cache invalidation — one poller of record, not several clocks
- Dominant language
- TypeScript
- Stars
- 0
- Forks
- 0
- Avg merge
- 1h 35m
- Merged PRs (30d)
- 333
Description
The directory-listing cache expires on a clock that has no relationship to when anything changed, while the one component that actually knows what changed — the `/proc` roster — sits in the same process and tells it nothing. The clock is also miscalibrated in the wrong direction: `/bin`, which changes on a scale of months, gets the most aggressive re-warm, while the paths that move while the daemon sleeps fall through to a three-minute default. Meanwhile boot blocks on prefetches whose results the stale-serve path would deliver for free seconds later.
Grilled and settled 2026-09-04. Plan: `~/.claude/plans/boot-cache.md`.
## Defects established from source
- `ttl_get` matches an exact path or a `*` wildcard anchored at both ends, so `/home` does not cover `/home//feeds` and `/feeds/*` matches a top-level path that does not exist in this VFS. Only `/bin` and `/PUBLIC` ever take effect; everything else silently gets the 3-minute default.
- `maxEntries` is 100 with LRU eviction that bumps a counter and tells nobody. The checkpoint then persists the truncated set.
- Stale-while-revalidate already exists in `vfs.listing_get`, but only engages when an ambient listener is present, which means the daemon. Boot blocks on prefetches it would have covered.
- `{ scope: 'feed' }` fires on every instance add, status change and join update, so indexing a 20k-node feed emits ~20k events that mean no file appeared. The listing cache hears none of them anyway.
- `/SHARED` has no boot row at all, so a CUBE that stopped serving shared paths stays silent until someone goes looking.
## Settled decisions
1. Boot blocks only on `/bin`; Groups, Feeds, Public and `/SHARED` go behind the prompt.
2. A plain console serves stale immediately and refreshes silently behind. No repaint.
3. Your own act deletes a cache entry; someone else's act dirties it.
4. A narrow coalesced notifier, not a subscription to the proc change stream. Two call sites: roster delta arrivals and departures, and job terminal transitions.
5. TTL survives only where no signal exists. `/bin` goes to a day.
6. A deferred step that fails is annunciated rather than gated, and persists until a later attempt succeeds.
7. Boot readout gains a `PENDING` status, pads its status tags, renames `Listings` to `Folders` and reports age as well as count.
8. `/SHARED` becomes a warmed deferred step, after the slice measures its top-level listing size.
9. Proof is units, a job-completion live exemplar, an argus smoke scenario, and a two-identity share exemplar that skips without the second identity.
10. All five slices land before the DICOM epic #359 begins.
## Slices
- S1 cache truth — TTL matching, signal-split lifetimes, entry cap, `Folders` label with age
- S2 the notifier — cumin entry point, salsa push from two call sites, coalescing, feed-id walk
- S3 boot deferral — `PENDING` status, padded tags, three steps deferred, `/SHARED` measured and added
- S4 warm-failure annunciation — wire, prompt, argus status strip, persists until resolved, AEGIS law and smoke in the same PR
- S5 the share exemplar — two-identity arrival proof with `mise-e2e`
## Out of scope
The CUBE-side fix. Recorded as the change-discovery entry in `docs/CUBE-gaps.adoc`, proposing a `modified_since` filter near-term and a change collection with a resume cursor longer-term. No client-side arrangement can beat the roster walk's period; that ceiling is the gap.
Contributor guide
No contributing guide indexed for this repository
Research direction
Read ~/.claude/plans/boot-cache.md and inspect vfs.listing_get, the cumin entry point, and the boot readout steps. Trace the two notifier call sites described for roster deltas and job terminal transitions, then review the mise-e2e, argus, and AEGIS proof requirements. Done means all five slices and their listed proofs are complete.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend, cli, testing-qa
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100