RULING (gritzko, chat 2026-07-19): GET uses the SAME stamping rules PATCH uses for merged files (the DIS-057 band) — the follow-up GET-049's constraint explicitly anticipated ("route merge outputs to the DIS-057-style band"). Today a bare get that carries an uncommitted edit leaves the file wearing its OLD put row's restamp; that ts stays in the wtlog stamp-set, so the STATUS-011 has(mtime) fast path validates the file clean against a base that moved — dirt that status and bare diff HIDE, and a post would silently not commit.
Incident 2026-07-19, work/STATUS-016: wtlog put shared/wtlog.js (row 26719BQw09, BE-011 restamp → mtime 11:26:59.009), then a user bare get ///be/#27d03a26 (row 26719BkGEg) carried the edit per GET-048 §4.
jab status | cat and bare jab diff | cat read the tree CLEAN; targeted jab diff shared/wtlog.js prints the full delta vs base — the discrepancy.pat clean apply), ceil-1ms (mrg weave), ceil (cnf); the outcome rides the stamp offset, zero content reads.After ANY get, no file can read clean while differing from the new base: carried/woven outputs are stamped into a DIS-057-style band under the get row's ceiling and classify buckets them by offset.
v per Status; conflict carries !).put-staged file identical
in old+new base is skipped by the reconcile, keeping its put restamp — still
in the whole-log stamp-set (has() is not floor-scoped), so STATUS-011 reads
it clean vs the advanced base. Woven/conflict legs DID rewrite (visible), so
the incident is specifically the un-rewritten leg.ok via has()): ceil-1ms mrg
(wt v), ceil-2ms con (wt !). The ceiling is NOT registered — clean
overwrites keep it. In practice stampTs >> the prior tail (separate procs),
so the below-ceiling band never collides with a real row ts; the same 1-2ms
collision edge GET-049 already noted (cosmetic).bandStamp(g,full,outcome) twin of trySetMtime;
the leaf weave leg stamps mrg (or the ceiling when the weave reproduced the
target), the three conflict legs stamp con. The pruned leg is caught by a
terminal carrySweep: collect every pre-get put path (all de-scoped by the
just-appended get row), and for each NOT visited by a leaf, restamp to the
band iff still dirty vs the new base. No log read-back — the band derives
from g.stampTs (the ts ulog.append returned); row appended before stamps....v / ...!put row itself is left below the get floor (out of scope per
the ruling — put/post semantics untouched); only the DIRT is made visible.LANDED 64525364 (2026-07-19 12:42, "GET-050: get must follow same rules for merged files as patch"); work/GET-050 clean at tip. The DECISION-side hole (stamp false-clean at get's pending check on a base-moved file → clean-overwrite discard) is split out as GET-052.
Original staging note (historical):
Changed (staged):
shared/classify.js — patchStamps also opens the recentmost get row's band
{ceil-1:mod, ceil-2:con} (pd-scoped); the ceiling stays the GET-049 ok stamp.verbs/get/get.js — bandStamp helper; leaf weave/conflict legs restamp to
the band; collectStaged+carrySweep (finalizeGet) restamp de-scoped,
still-dirty PRUNED carried files; g.seen skips leaf-handled paths.test/get/carry-stamp/run.sh — NEW case (test submodule): put f.txt, advance
a diverged mover g.txt, bare-get → f.txt (pruned) reads ...v + bare diff
lists it; clean g.txt stays unlit. Glob-registered (no CMakeLists edit).Evidence: manual repro RED (post-get status/bare diff EMPTY for f.txt, only
targeted diff f.txt showed it) → GREEN (...v f.txt, bare diff lists it).
Suites green: test/get/* (35 pass / 6 env-skip, GET-049 stamp + weave/conflict incl.),
test/status/* (12), test/patch/* (26, stampband incl.), test/work/view,
statusfast.js, patchband.js. Pre-existing unrelated red: test/work/getctx (pty
frame goldens — identical FAIL on pristine baseline).
Suggested commit message:
GET-050: get band-restamps carried files so stale put stamps can't false-clean