Documents / Decisions / adr-fad49eaa4648
Staleness ages from creation, never from the last edit
Why an absent `verified` falls back to `created` rather than `updated`, and why absent is not treated as infinitely stale.
Context¶
adr-bd7c4f3c5764 made staleness data: a per-type review_days cadence, an optional verified
date, and today - (verified or updated) > review_days. The updated half of that fallback is
the defect in issue-6726eabcf871: updated moves on every edit, so a document nobody had
vouched for left the review queue as soon as anybody wrote in it.
The fallback has to answer "what is the earliest date docir can honestly claim somebody looked
at this?" for a document with no verified. updated answers a different question — "when was
this file last touched?" — and the two come apart hardest in the document that matters most: the
evidence that an ask is still unanswered is a re-check written into its body. Recording the
silence is what ended the report of it.
Decision¶
Staleness ages from a date an edit cannot move. Document.stale_reference_date() returns
verified when present and created otherwise; it never reads updated.
created is the one date the write path sets once and never rewrites — not a retype, not a tag
rename, not check --fix, not a body edit. A document with no verified therefore enters the
queue exactly one cadence after it was written and stays there until somebody stamps
docir update <id> --verified.
The stale finding now names the clock it read: never verified, created
Alternatives considered¶
Age from verified alone, treating absent as infinitely stale. Semantically the cleanest
reading of the queue — a document nobody has vouched for is stale by definition — and it was
measured before being rejected. On this store on 2026-09-05 (196 live documents, 84 carrying a
cadence, 1 carrying verified) it reports 83 of 84 documents stale, including ones written
the day before, because the corpus is younger than its shortest cadence. It also makes
review_days inert for every unverified document: the cadence never applies, so the queue is
"everything", cannot be worked down, and is indistinguishable from a corpus that has genuinely
rotted. That is issue-40d1792bc9f9 again — a warning that fires on the product's own defaults —
and the same argument the docir schema validate dead-end warning was dropped on.
A second stamp for "I re-checked and it is still unanswered", distinct from verified. This
records the real event, which created only approximates, and it is what the reporter's own
workaround does with a date declared in the body. Rejected here as the wrong size of change for
a defect fix: a frontmatter field, a migration, a CLI verb, an MCP argument and a contract
clause, for one workflow. It stays additive — nothing in this decision forecloses it, and a
document that carries it would simply age from the later of it and created.
Consequences¶
- The queue is monotonic in the absence of
--verified: writing into a document can no longer remove it, which is what makes a re-check safe to record. - A never-verified document reports stale one cadence after creation rather than after its last edit. On a corpus whose documents are edited more often than their cadence, this reports more documents than before — correctly; those are the documents nobody has confirmed.
- The clock start is
created, which is not necessarily when the thing the document tracks began. For a document standing in for an external ask,createdprecedes the ask, so silence is under-reported by that gap, once, at the document's birth. Bounded by the gap and paid only once, against a defect that cleared the entry on every edit. issue-9ed4905e0db8's rule — a mechanical rewrite must not advanceupdated— no longer has staleness behind it, sinceupdatedno longer feeds the clock. It stands on its own ground:updatedis the edit clock every read view shows, and a bulk rewrite claiming every document was edited today is a lie about that.- Two builds reading one store disagree about
stale, silently. Measured by the cross-version procedureadr-ab4598c6f707requires: one document,created: 2024-01-01,updatedtoday, never verified, 365-day cadence — 0.23.0 reportsstale: falseand this build reportsstale: true, from the same file. Neither refuses, so it is not a break by that decision's own test; it is the third thing that decision does not name, a field both builds show with different values.staleis computed and carries no provenance, so nothing reports the disagreement, anddoctor'sstale-index-builddoes not cover it — a teammate who runsreindexthemselves clears that finding while still reading the old rule. It resolves when everyone upgrades, and until then the review queue is per-build. This did not appear on docir's own corpus, whose oldest document is younger than the shortest cadence in its schema.