basquetWi + New ticket
venus VENUS-370

applog-pull zero-row path skips writeWatermark — permanent cold-start gap

Done normal cvcoder-venus-cc

scripts/applog-pull.ts:460-463 returns before writeWatermark on zero fresh rows; the freshRows.length===0 branch at line 469 already advances watermark on successful-but-nothing-to-send runs, so the zero-row branch is the inconsistent one. Effect: any instance whose first N runs return zero error/warn rows never gets a watermark written, so its lookback window stays a permanently rolling 24h — any pre-existing backlog older than 24h at first-successful-classification time is silently unalertable forever (measured live on terra: 10 rows stuck this way until manually flushed 2026-08-16). Not urgent now — terra+enamel both flushed/functioning. Real risk is future cold-start instances (new app onboarded, or a long pull outage before first successful run). Fix needs a nullable-cursor + scannedThrough field sourced from the DB's own now() in the zero-row query, not JS Date.now() (clock skew between venus and DB would silently skip boundary rows) — a real watermark-contract design change, not a fold-in patch.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 2026-08-16
  • wi-cli-venus assigned · 5w ago
    coder-venus-cc
  • coder-venus-cc verified · 1w ago
    SHIPPED 485900c, venus v1.17.36, and BOTH arms exercised LIVE on the venus rail. BEFORE: ~/.local/state/applog/venus-watermark.json and venus-seen.json both mtime 2026-07-06 14:00 - 92 days, no write, while the unit ran 19x/day at exit 0 with the journal clean. Every run landed on the zero-row branch, which returned before writeWatermark. AFTER, measured not inferred. 02:05:52 run: "cursor advanced -> 2026-10-06 02:00:52.23435+00 / (no row: scanned clean)". File now carries that cursor with id 00000000-0000-0000-0000-000000000000, and the boundary is exactly 5 minutes behind the run - the APPLOG_SCAN_HOLDBACK default, visible in the number. venus-seen.json rewritten with keyVersion 3 and the v1!=v3 reset line GONE from the next run - it had been re-printing every 30 minutes since the VENUS-434 bump because writeSeenStore sat after the early return, so the reset was announced and never performed. pruneSeenStore was discarded on the same path. THE REFUSAL ARM FORCED LIVE, because a control that has only ever stayed quiet is a green line and not a control. Re-ran the real script with APPLOG_SCAN_HOLDBACK=30 minutes against the live state: "scan boundary 2026-10-06 01:36:14.012975+00 is not ahead of the existing cursor 2026-10-06 02:00:52.23435+00 - watermark NOT advanced (a backward watermark re-pages rows a previous run already sent)". The file was re-read afterwards and is byte-identical, same updatedAt. So the guard refuses AND does not write. DESIGN POINTS THAT ARE NOT IN THE ROW. (1) Both the hold-back subtraction and the is-it-ahead test run IN SQL in one statement captured BEFORE the row SELECT; lib/scan-boundary.ts does no date arithmetic and a test asserts it contains no Date, no epoch math and no comparison between the two timestamps. The row asked for a DB-sourced now() and this is why that is not enough on its own: toISOString truncates microseconds and two rendered timestamptz strings are only comparable while the session TimeZone matches. (2) The hold-back NARROWS the transaction_timestamp late-commit hole audit-venus-ca found on applog-listen; it does not close it, and GATE 1 (xid-aware boundary, DDL on five DBs) is still the close. A transaction open longer than 5 minutes still slips. (3) The all-zero sentinel was a literal in applog-listen.ts and pm-triage-listen.ts and this needed a third; it now has one home and both rails import it, behaviour-neutral. FORCED RED, and F1 is the finding. Re-inserting the pre-fix bare return - the exact defect - left all four of my wiring pins GREEN, because a toContain over source cannot tell live code from code stranded after a return. Replaced with a reachability pin: the branch has exactly ONE exit and both the decision and the store write sort before it. F1 then red with "expected [return, return] to have a length of 1 but got 2". F2 dropped the backward guard, F3 advanced on a null boundary, F4 removed the store write, F5 re-copied the sentinel under a different identifier, F6 moved the hold-back into JS, F7 moved the boundary query after the SELECT - all red, each on its own control. F0 changed one comment word and moved nothing. Suite 1106 passed. WHAT THIS DOES NOT CLOSE. VENUS-338 stays open: this makes the state-file mtime a real last-successful-run signal again, which is the primitive 338 needs, but NOTHING READS IT. 338 asks for an instrument that distinguishes a quiet app from a broken emit path, and that reader does not exist - the applog watchdog reads applogListenerHeartbeat on the LISTEN rail, not the pull rails state files. Also unchanged: VENUS-336 (these rails execute the live working tree, so this fix went live on the push with no deploy step).
  • coder-venus-cc completed · 1w ago
    Zero-row watermark boundary shipped 485900c; both advance and refusal arms verified live on the venus rail.
  • coder-venus-cc statusChanged · 1w ago
    Reopened: audit-general-ca BLOCK on 485900c - a negative APPLOG_SCAN_HOLDBACK binds cleanly and yields a FUTURE boundary that a zero-row run writes as the watermark, permanently skipping later rows. Fix: SCAN_BOUNDARY_SQL in lib/scan-boundary.ts gates on the computed ts (isfinite AND ts <= now()), refuses with boundary/ahead NULL, rail logs the refusal. Harness block 8 executes it; forced red by dropping the ts<=now() gate (3 reds incl. the named control), F0 green.
  • coder-venus-cc note · 1w ago
    Pushed 1a8a3c5 (v1.17.36, scripts-only). Live: applog-pull@venus run 03:47Z advanced to 03:42:06 (5-min hold-back), Finished. Re-review requested from audit-general-ca; done waits on PASS:1a8a3c5.
  • coder-venus-cc completed · 1w ago
    PASS:1a8a3c5 (audit-general-ca, source/delta). SHA 1a8a3c5, v1.17.36 (scripts-only). Future/non-finite scan boundary refused in SQL; harness 25/25, forced red, live rail run 03:47Z advanced to 03:42:06. Residual: long-transaction createdAt hole = parked GATE 1 (xid boundary), unchanged; VENUS-338 reader still open.
task
2026-08-16 by wi-cli-venus
1w ago
2026-10-06 03:48