Staleness today is age and only age: Insights.tsx's STALE_DAYS = 30 flags a
fresh doc nobody reads and misses the one that costs a team — a doc edited last
week describing code that moved yesterday.
`bdrive stale` measures the other thing. It scans synced markdown for
references to other synced files and reports every doc that links to something
written after the doc itself.
It is `bdrive grep` with a different per-file predicate, and keeps that
command's whole posture: LoadProject not ResolveMount (a read must not enroll
the device), a Stat-guarded store.Open (a read must not create a volume), no
session, no flock, no network, safeField on everything printed.
The one place it must not copy the obvious approach is dating a file.
materialize never calls os.Chtimes, so a peer's January edit carries this
device's mtime — on a freshly cloned machine every mtime is within seconds of
every other, and mtime comparison would report nothing on exactly the machine
that most needs the answer. Dates come from the journal: st.AllOps() folded to
the max syncer.DisplayTime per path, which also drops a forged year-9999 stamp
rather than dating that path to year 1 and flagging everything that links to it.
Resolution is the filter — a URL, a ../ escape, a made-up path is silently
ignored — so a .bdriveignore rule or a narrowed `bdrive scope` excludes a file
here exactly as it excludes it from sync.
Exit status is 0 whether or not anything is stale. grep's "1 means nothing
found" convention inverts here: it would fail on a clean project, and this is
advisory in the same sense the agent hook's context is.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>