INVARIANT (gritzko, 2026-07-17): every file undirtied by a post carries a wtlog-stamp mtime, so the next status confirms it clean with zero content reads. post HAS a stamp site (be/verbs/post/post.js:942, BE-011) — this ticket VERIFIES coverage of every undirtied class and fixes gaps. Siblings: GET-049 (get stamps nothing), PATCH-013.
put-staged files already carry their put row stamps, which stay in the wtlog after post — those confirm clean without a post restamp. The suspect classes are files post undirties WITHOUT a prior put stamp:
jab post (stages mod files directly, PUT-009 ruling): do those get a stamp at post time (post.js:942 — what does its loop cover)?has(ts) after the boundary moves, or do they fall out of the in-scope stamp-set?A repro test per class: post, then assert every undirtied file's mtime ∈ the wtlog stamp-set AND status does zero content reads on them (STATUS-011 observable). Fix whichever class misses, repro-first.
post.js:942's BE-011 stamp is the pattern to extend, not replace.stamp BEFORE the pack write, and ulog.append's old guard (use < nowAfter → bump) silently re-stamped the ms-stale explicit ts to NOW — so BE-011 stamped an mtime no wtlog row carries, and status content-re-read every committed file after every post.shared/ulog.js append (RULING 2026-07-17): an explicit row ts is HONOURED whenever it stays strictly past the running floor (all native ULOGAppendAt refuses is ts<=last); only a genuine collision bumps. append RETURNS the assigned ts per row — a restamping caller uses the return value (a log READ-BACK, the first-cut ulog.prevRow approach, was REJECTED by gritzko). Hunk kept minimal/byte-stable — GET-049 duplicates it for a clean weave.be.now, minted afresh PER VERB INVOCATION at the loop edge (core/loop.js mintBe ambient — a pager-spelled post in the resident process gets a fresh one; snapshot/restored across re-entry). post() reads be.now (ron.now() fallback) into ctx.now; ONE ctx.now is reused across the parent and every folded sub (threaded via ctx, never re-sampled per repo). Same-ms collision edge (ts<=tail, e.g. the parent row after a just-appended gitlink-bump row): the row bumps, the mtime restamp uses append's returned assigned ts, so row-ts==mtime holds unconditionally.ts = use + 1n stepping in append stays (ms>999 packed stamps are valid numbers); the ron->ts conversion clamp belongs to PUT-010.has(ts) is boundary-BLIND (the whole drained row set, wtlog.js:249) — a pre-pd stamp never ages out; the test's -aged mode pins that with mtimes strictly below the just-moved pd (incl. the DIS-072 sub re-attach get row landing past the sub's post stamp).has(ts) scope vs the moved pd boundary — a stamp that ages out of scope is a fast-path hole even with correct mtimes.mod files (PUT-009 ruling); (c) staged-move post (destination); (d) sub post folding a gitlink bump (sub interior file + parent rows) — each: mtime ∈ wtlogReader.has() via the SAME reader status.js:278 opens, zero io.open on those files during classify, no dirty rows.has() is scope-blind, pre-pd stamps stay members — asserted with aged-past-pd mtimes in every class.ctest -j16 -LE big), stable over reruns; worktree updated (jab get, base e4501b50) and re-verified. New test test/post/restamp/run.sh (+ its .stampchk.js checker inline); diff: shared/ulog.js append (+return, honour-explicit guard), verbs/post/post.js (ctx.now/stamp/assigned, ~+14/-4), core/loop.js (+3: be.now ambient + snapshot).