Skip to content

null (never now()) as the absent-recency sentinel for lastModifiedAt

Date: 2026-06-08 Status: Accepted Decision: hl-26y Deciders: Sean Brandt

When a file’s last-commit date cannot be determined — scan disabled, scan failed, file predates the --shallow-since window, or an incremental re-index lacks a head-commit timestamp — the lastModifiedAt chunk payload field must carry some value. The sentinel choice determines how every downstream consumer (analyzer context formatter, reviewer demotion logic, prompt annotations) interprets missing data.

All code paths that cannot determine a file’s last-commit date write lastModifiedAt: null. Consumers treat null and field-absent identically as “age unknown”: no annotation, no demotion. One rule: null ≡ window-cutoff ≡ scan-disabled ≡ scan-failure ≡ incremental-index-without-head-commit. Freshness is never fabricated with now().

  • Fabricating freshness (now()) would make scan failures silently corrupt the recency signal — stale docs would appear fresh, defeating the feature.
  • Treating unknown as maximally stale (epoch) would incorrectly demote all pre-existing chunks on first deploy, before any re-index.
  • A single null rule covers four distinct “unknown” causes uniformly, so consumers need no per-cause branching — one null-check suffices.
  • null / absent ≡ “age unknown” (chosen): unambiguous; never false-fresh, never false-stale. Requires an explicit null-check in every consumer.
  • Date.now() / current timestamp: no null-check, but fabricates freshness for unknown-age files.
  • Epoch (1970-01-01): always present and clearly “old”, but treats unknown as maximally stale — wrong for all pre-existing data.
  • Positive: pre-existing chunks are neutral until re-indexed; scan failures are safe (index completes, age features inert); future consumers implement correct behavior with a single null-check.
  • Negative: repos never re-indexed after deploy never gain age annotations — operators must trigger a re-index to backfill; webhook re-indexes without a head-commit timestamp stay null-dated.
  • Neutral: Qdrant payloads are schemaless — null and absent are treated identically by the JS client; the rule unifies both.