docs(publish): address review nits on the contract block

Four corrections from the review of #8, all in the files this PR already
touches:

- A local signal on the line that creates .publish-new-. The other four shapes
  each got a note at their producing line, which is the whole premise of #7 —
  someone renaming TMP_DST reads its own comment block and would never see the
  contract note 45 lines up at OLD.

- '.publish-old- is milder' understated it. Milder is true; bounded is not. A
  key whose branch is merged, deleted or renamed is never published again, so
  its rotated generation stays until something outside this repo takes it —
  which is the case gitdan#30 itself makes, two lines away.

- The drift check now says the prefix constants ci-cache-reclaim.sh DECLARES,
  not the ones it enumerates. Those are different numbers: collect_entries()
  globs .stage- and .evicting- only, because .reading- is read and never
  swept. Only the declared reading makes the five-against-five count work, and
  a countability check that needs a coin flip to count is not one.

- publish-snapshot.sh's own header had two stale names ten lines above the
  stale pointer this PR fixes: step 1 staged at .stage-<tag> (that is
  hardlink_clone_into's inner path; the staged snapshot is .publish-new-<tag>)
  and step 2 named .publish-old-<tag> without the key. Pre-existing and
  outside both ACs, but #6's thesis is that a plausible-looking wrong name is
  the worst kind, and these are in the file the PR is about.

Comments and docs only. With comments and blank lines stripped, all three
scripts hash identically to origin/main.
This commit is contained in:
2026-08-24 13:06:49 -05:00
parent 0118c28f01
commit e3869c5920
3 changed files with 25 additions and 13 deletions
+6 -4
View File
@@ -246,7 +246,7 @@ block is the canonical description; this side owns the names.
|---|---|---|
| `.stage-<tag>` | `cache-lib.sh`, `hardlink_clone_into()` | stranded; only the arbiter reclaims it |
| `.publish-new-<tag>` | `publish-snapshot.sh` | stranded; see `daniel/gitdan#30` |
| `.publish-old-<key>-<tag>` | `publish-snapshot.sh` | swept by the next publish of that key |
| `.publish-old-<key>-<tag>` | `publish-snapshot.sh` | swept by the next publish of that key, if there is one |
| `.evicting-<name>-<pid>` | `prune-cache.sh`, `evict_dir()` | swept at the start of the next prune pass |
| `.reading-<source>-<tag>` | `cache-lib.sh`, `reader_lock_acquire()` | not garbage — see below |
@@ -269,9 +269,11 @@ as `.stage-` does, so it is the one that needed catching. Bringing both under
the arbiter's enumeration is tracked as `daniel/gitdan#30`.
The two lists are meant to be the same length — the five names above, and the
prefixes `ci-cache-reclaim.sh` enumerates. A mismatch means one side gained a
shape without telling the other, which is the drift the rule exists to catch
and the cheapest thing to check.
prefix constants `ci-cache-reclaim.sh` *declares*. Not the subset it enumerates
as reclaim candidates: that one is smaller, because `.reading-` is read and
never swept. A mismatch means one side gained a shape without telling the
other, which is the drift the rule exists to catch and the cheapest thing to
check.
**The staleness constants are part of the same contract, and that half has a
direction.** `CACHE_READ_STALE_SECONDS` (`cache-lib.sh`) and