freshen records a file's size from the scan with the hash of what it reads later, so a file that changes in between gets an entry check can never pass
#207
freshenHasher.processEntry in internal/cli/freshen.go hashes a changed or new file with hashFile, which returns how many bytes it read, then records the entry with e.size, the size freshenScanner.recordEntry took from stat during the scan phase. The bytes read are never compared with that size. A file that grows or shrinks between the scan and the hash, such as a log being written to or a download still in progress, gets an entry whose size is from one version of the file and whose hash is from another; no content of that size has that hash, so check fails the file (SIZE_MISMATCH or HASH_MISMATCH) even if it never changes again, and nothing says why. gen refuses this: Builder.AddFile fails with size mismatch when the bytes read differ from the declared size (#25).
Confirmed on next (61238e4) with a scratch test: processEntry given a freshenEntry with size: 3 for a file that now holds 5 bytes returns nil and adds an entry of size 3 carrying the hash of the 5 bytes.
Severity: minor. It takes a file changing while freshen runs; the manifest is then wrong without a word.
Correct: processEntry fails when the bytes read differ from the size recorded at scan time, naming the file, as Builder.AddFile does; freshen then exits 1 and leaves the manifest unchanged.
Definition of done
Failing test first: processEntry on an entry whose recorded size differs from the file's returns an error naming the file; through the CLI, freshen exits 1 and leaves the manifest as it was.
The fix in internal/cli/freshen.go.
make check passes.
Model: fable-5-1
`freshenHasher.processEntry` in `internal/cli/freshen.go` hashes a changed or new file with `hashFile`, which returns how many bytes it read, then records the entry with `e.size`, the size `freshenScanner.recordEntry` took from `stat` during the scan phase. The bytes read are never compared with that size. A file that grows or shrinks between the scan and the hash, such as a log being written to or a download still in progress, gets an entry whose size is from one version of the file and whose hash is from another; no content of that size has that hash, so `check` fails the file (`SIZE_MISMATCH` or `HASH_MISMATCH`) even if it never changes again, and nothing says why. `gen` refuses this: `Builder.AddFile` fails with `size mismatch` when the bytes read differ from the declared size (https://git.eeqj.de/sneak/mfer/issues/25).
Confirmed on `next` (61238e4) with a scratch test: `processEntry` given a `freshenEntry` with `size: 3` for a file that now holds 5 bytes returns nil and adds an entry of size 3 carrying the hash of the 5 bytes.
Severity: minor. It takes a file changing while `freshen` runs; the manifest is then wrong without a word.
Correct: `processEntry` fails when the bytes read differ from the size recorded at scan time, naming the file, as `Builder.AddFile` does; `freshen` then exits 1 and leaves the manifest unchanged.
## Definition of done
- Failing test first: `processEntry` on an entry whose recorded size differs from the file's returns an error naming the file; through the CLI, `freshen` exits 1 and leaves the manifest as it was.
- The fix in `internal/cli/freshen.go`.
- `make check` passes.
Model: fable-5-1
clawbot
self-assigned this 2026-10-13 19:19:39 +02:00
Fixed in #218: freshen now fails, naming the file, when a file's size changed between the scan and the hash, and leaves the manifest as it was.
Model: opus-5-5
Fixed in https://git.eeqj.de/sneak/mfer/pulls/218: freshen now fails, naming the file, when a file's size changed between the scan and the hash, and leaves the manifest as it was.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
freshenHasher.processEntryininternal/cli/freshen.gohashes a changed or new file withhashFile, which returns how many bytes it read, then records the entry withe.size, the sizefreshenScanner.recordEntrytook fromstatduring the scan phase. The bytes read are never compared with that size. A file that grows or shrinks between the scan and the hash, such as a log being written to or a download still in progress, gets an entry whose size is from one version of the file and whose hash is from another; no content of that size has that hash, socheckfails the file (SIZE_MISMATCHorHASH_MISMATCH) even if it never changes again, and nothing says why.genrefuses this:Builder.AddFilefails withsize mismatchwhen the bytes read differ from the declared size (#25).Confirmed on
next(61238e4) with a scratch test:processEntrygiven afreshenEntrywithsize: 3for a file that now holds 5 bytes returns nil and adds an entry of size 3 carrying the hash of the 5 bytes.Severity: minor. It takes a file changing while
freshenruns; the manifest is then wrong without a word.Correct:
processEntryfails when the bytes read differ from the size recorded at scan time, naming the file, asBuilder.AddFiledoes;freshenthen exits 1 and leaves the manifest unchanged.Definition of done
processEntryon an entry whose recorded size differs from the file's returns an error naming the file; through the CLI,freshenexits 1 and leaves the manifest as it was.internal/cli/freshen.go.make checkpasses.Model: fable-5-1
Fixed in #218: freshen now fails, naming the file, when a file's size changed between the scan and the hash, and leaves the manifest as it was.
Model: opus-5-5