feat(toolbox): reconcile by the age of the last one, not the hour - #12
Merged
Merged
Conversation
A reconcile was due only in the run that started in hour 03 UTC. The schedule lives in katoptra/dispatch and moved: tlnet left 03:30 on 2026-09-09 and had not reconciled since. The toolbox now owns the rule. `due` reads the start epoch of the run that last completed a reconcile from .state/reconciled, through the engine's pull, and leaves .run/reconcile once it is RECONCILE_HOURS (24, a mirror's root var) old, less half an hour so a daily run's start-time jitter cannot skip every other day. `reconciled` records it through push. RECONCILE=true and false still force either way; any other value, and an hour count that is not a whole number from 1, stops the run. The rsync engine runs `due` after `clock`, gates `reconcile` on the flag, holds it while batches wait (delete would hold the orphans back), and records the reconcile last. `clock` writes the epoch alone and clears a stale flag. The rsync example's offline check covers the rule, and CLAUDE.md records that task runs every command under set -e.
This was referenced Sep 23, 2026
jshvn
added a commit
to katoptra/ctan
that referenced
this pull request
Sep 23, 2026
## Why lib v2.2.0 (katoptra/lib#12) decides a reconcile by the age of the last one instead of the hour a run starts. tlnet's slot left 03:30 on 2026-09-09, and it had not swept its bucket since. ## What - `render.txt` changes: - `clock` writes the epoch alone and clears `.run/reconcile`; - `due` runs after it; - `reconcile` ends with `reconciled`, which pushes `.state/reconciled`. - The docs drop hour 03 (and tlnet's 03:30 dispatch) for the age rule: CLAUDE.md, the Taskfile comment that names `RECONCILE` as the toolbox's, and for tlnet the README. The first run on v2.2.0 reconciles, because no marker exists yet. ## Test plan - [x] `render.txt` rendered against the lib branch before release. The `check` job re-renders it against the released `v2`.
jshvn
added a commit
to katoptra/tlnet
that referenced
this pull request
Sep 23, 2026
## Why lib v2.2.0 (katoptra/lib#12) decides a reconcile by the age of the last one instead of the hour a run starts. tlnet's slot left 03:30 on 2026-09-09, and it had not swept its bucket since. ## What - `render.txt` changes: - `clock` writes the epoch alone and clears `.run/reconcile`; - `due` runs after it; - `reconcile` ends with `reconciled`, which pushes `.state/reconciled`. - The docs drop hour 03 (and tlnet's 03:30 dispatch) for the age rule: CLAUDE.md, the Taskfile comment that names `RECONCILE` as the toolbox's, and for tlnet the README. The first run on v2.2.0 reconciles, because no marker exists yet. ## Test plan - [x] `render.txt` rendered against the lib branch before release. The `check` job re-renders it against the released `v2`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
reconcilewas due only in the run that started in hour 03 UTC. The schedule lives in katoptra/dispatch and moves. tlnet's slot left 03:30 on 2026-09-09, and every run since has loggedTask "reconcile" is up to date. The last sweep was a manualRECONCILE=trueon 09-09.What
duepulls.state/reconciledthrough the engine'spull. The key holds the start epoch of the run that last completed a reconcile..run/reconcileonce that time isRECONCILE_HOURSold (default 24; a mirror overrides it in root vars), or when none is on record.RECONCILE=trueforces a reconcile andfalseskips one.RECONCILE, and any hour count that is not a whole number from 1, stops the run. A leading zero would be read as octal.reconciledrecords the run's start throughpush.clockwrites only the epoch and clears a stale.run/reconcile. Nothing can key on the hour any more.dueafterclock;reconcileon the flag;deletewould hold the orphans back and the chained run that lands the last batch should sweep;The next minor release, v2.2.0. The first run on each rsync mirror after the tag moves reconciles, because no marker exists yet. ctan's takes about 7 minutes.
Test plan
examples/rsync:task checkandtask run -- task offline, from a clean.run. New cases:RECONCILE_HOURS=2;trueandfalse;RECONCILE=yesandRECONCILE_HOURS=abcand08, each checked by its message.examples/proton:task checkandtask run -- task offlinerender.txtpreviewed against this branch; each has a follow-up PR.