Repository navigation
Description
Debounce the artifact auto re-export so a re-export doesn't run on every incremental index.
Design accepted on 2026-08-20 on PR #870 by @moofone. Re-filed as an issue because the hook point that PR targeted no longer exists on main — export moved out of dump_and_persist into export_after_publish (src/pipeline/pipeline.c:2529-2544), whose signature (cbm_pipeline_t *p, const char *final_path) has no access to changed_total, file_count or stamps[] — all of which the debounce needs, and all local to cbm_pipeline_run_incremental. Reaching them needs new cross-module plumbing, so this is a design task rather than a rebase, and it deserves its own issue instead of blocking on a stale branch.
Accepted shape
Skip the per-run re-export unless one of:
changed_totalexceeds a threshold, or- cumulative drift since the last export exceeds a threshold (@moofone added this trigger mid-review), or
- the artifact is older than a max age.
Changes requested against the original, to carry forward
- MAX_AGE ~1h, not 24h.
- Deletions must count toward drift, with a test.
- A run-summary line naming the blocking threshold, so a skipped export is explainable rather than mysterious.
- README documentation — the original added two env knobs and changed a user-visible default cadence with no docs.
Defect to fix in any implementation
parse_iso8601_utc (src/pipeline/artifact.c:244) range-checks month/day/hour/min/sec but never the year. In pipeline_incremental.c:800 the result feeds (exported_epoch + 1) * CBM_NS_PER_SEC; since INT64_MAX / 1e9 ≈ year 2262, a hostile or corrupt "indexed_at":"9999-01-01T00:00:00Z" yields ≈2.53e20 and overflows signed int64 — reachable on the first index after a clone. Release builds wrap; the Makefile.cbm diag UBSan lane traps. sscanf("%d") on an out-of-range year is itself UB. Range-check the year.
Credit to @moofone for the design and for adding the cumulative-drift trigger during review.
Activity