The D5 dirty-merge gate at be/verbs/get/get.js:1053 reads kind === "f", reusing checkout's leaf-kind (f/x/l/s) as a mergeability test. Two wrongs follow: a dirty EXECUTABLE text file (x) is clean-reset (its uncommitted edit silently dropped), and a dirty BINARY 644 file (f) is fed to weave3 as if it were text.
kindOf() exists to tell checkout.materialise how to WRITE a leaf; mergeability is a property of the BYTES, not the mode bit.isBinary at be/views/diff/diff.js:75 — git's heuristic, NUL in the first 8000 bytes — but it is file-private.f or x) AND no side of the 3-way (base, on-disk, target) is binary → weave3; everything else clean-resets exactly as l/s do today.isBinary from be/views/diff/diff.js and reuse it — no second copy of the heuristic.weave3 and checkout.materialise(..., {kind}) already pass kind through unchanged — nothing downstream needs touching.(kind === "f" || kind === "x") && !anySideBinary