From 070f4c5678373b7619dca7eca376c100e4a475d2 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Wed, 22 Jul 2026 10:56:38 -0700 Subject: [PATCH] fix(extract): floor --stale stamp at LINK_EXTRACTOR_VERSION_TS so version bumps don't create permanently-stale pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The version-ts bump in this PR exposed a latent conflict: extractStaleFromDB stamps links_extracted_at = the page's read updated_at (#1768 µs fix), but a page last edited BEFORE the new LINK_EXTRACTOR_VERSION_TS then lands below the version watermark and the 'links_extracted_at < versionTs' arm re-flags it stale on every run — an infinite re-extraction loop. Stamp max(updated_at, versionTs); versionTs is always a past release date, so the D4 concurrent-edit race guard still holds. Fixes the test/extract-stale.test.ts CI failure on this branch. Co-Authored-By: Claude Fable 5 --- src/commands/extract.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/commands/extract.ts b/src/commands/extract.ts index 21eeaaef5..755bbd98d 100644 --- a/src/commands/extract.ts +++ b/src/commands/extract.ts @@ -1743,7 +1743,15 @@ async function extractStaleFromDB( // `page.updated_at.toISOString()` — the JS Date is ms-truncated, so the // µs-precision DB updated_at stayed strictly greater and the page never // cleared on Postgres. Stamping the exact value makes them equal. - processedRefs.push({ slug: page.slug, source_id: page.source_id, extractedAt: page.updated_at_iso }); + // + // Version-arm floor: a page last edited BEFORE LINK_EXTRACTOR_VERSION_TS + // would otherwise be stamped below the version watermark and stay + // permanently stale (`links_extracted_at < versionTs` re-fires every run). + // Stamp max(updated_at, versionTs) — versionTs is always a past release + // date, so a concurrent edit's now() still exceeds the stamp and D4 holds. + // Tie at ms precision picks updated_at_iso (its µs ≥ versionTs's .000000). + const stampTs = new Date(page.updated_at_iso) >= new Date(versionTs) ? page.updated_at_iso : versionTs; + processedRefs.push({ slug: page.slug, source_id: page.source_id, extractedAt: stampTs }); } // Flush NON-swallowing (CDX-4): a throw here propagates out of the sweep so