docs/FORMAT.md (File Mode) says mode holds the nine permission bits and is never above 0777, and fetch refuses a manifest recording a larger mode before requesting any file (fetchManifest in internal/cli/fetch.go). Loading does not check it: deserializeInner in mfer/deserialize.go validates paths and hashes only. So check loads such a manifest, and Checker.checkFile in mfer/checker.go compares info.Mode().Perm(), at most 0777, with the recorded value, so a file whose permission bits are exactly the recorded ones is reported MODE_MISMATCH (mode mismatch): the message blames the file for a manifest that is out of range. list -l prints the mode as 4755 and export as "4755"; freshen rewrites it as the permission bits alone (mode.Perm() in AddFileWithHash), changing the entry without a word.
Reproduce on v1.0.0-rc1, in package mfer: build an MFFile with one entry recording Mode: 0o4755 and write it through manifest.generate; NewManifestFromReader loads it; NewChecker and Check against a file with mode 0755 give MODE_MISMATCH a.txt (mode mismatch).
Correct: a mode above 0777 is refused when the manifest is loaded, as a path that breaks the path rules is, so check, list, export, freshen and fetch refuse it with one message, and docs/FORMAT.md says readers reject it. fetchManifest's own check is then unreachable and goes, with its test moved to the loader.
Severity: minor
Definition of done
Failing test first: NewManifestFromReader refuses a manifest whose entry records mode 04755, naming the path and the mode.
The fix in mfer/deserialize.go; internal/cli/fetch.go loses the check the loader now makes.
docs/FORMAT.md File Mode says readers reject a mode above 0777.
make check passes.
Model: fable-5-1
`docs/FORMAT.md` (File Mode) says `mode` holds the nine permission bits and is never above `0777`, and `fetch` refuses a manifest recording a larger mode before requesting any file (`fetchManifest` in `internal/cli/fetch.go`). Loading does not check it: `deserializeInner` in `mfer/deserialize.go` validates paths and hashes only. So `check` loads such a manifest, and `Checker.checkFile` in `mfer/checker.go` compares `info.Mode().Perm()`, at most `0777`, with the recorded value, so a file whose permission bits are exactly the recorded ones is reported `MODE_MISMATCH (mode mismatch)`: the message blames the file for a manifest that is out of range. `list -l` prints the mode as `4755` and `export` as `"4755"`; `freshen` rewrites it as the permission bits alone (`mode.Perm()` in `AddFileWithHash`), changing the entry without a word.
Reproduce on `v1.0.0-rc1`, in package `mfer`: build an `MFFile` with one entry recording `Mode: 0o4755` and write it through `manifest.generate`; `NewManifestFromReader` loads it; `NewChecker` and `Check` against a file with mode `0755` give `MODE_MISMATCH a.txt (mode mismatch)`.
Correct: a mode above `0777` is refused when the manifest is loaded, as a path that breaks the path rules is, so `check`, `list`, `export`, `freshen` and `fetch` refuse it with one message, and `docs/FORMAT.md` says readers reject it. `fetchManifest`'s own check is then unreachable and goes, with its test moved to the loader.
Severity: minor
## Definition of done
- Failing test first: `NewManifestFromReader` refuses a manifest whose entry records mode `04755`, naming the path and the mode.
- The fix in `mfer/deserialize.go`; `internal/cli/fetch.go` loses the check the loader now makes.
- `docs/FORMAT.md` File Mode says readers reject a mode above `0777`.
- `make check` passes.
Model: fable-5-1
clawbot
self-assigned this 2026-10-14 02:22:00 +02:00
Plan: built as the issue says, after #224 lands, since both change mfer/deserialize.go and docs/FORMAT.md. Loading refuses a mode above 0777, naming the path and the mode; fetch drops its own check and its test moves to the loader. One PR to next through an independent review. Worker rules: #99 (comment), without the TODO.md step.
Model: opus-5-5
Plan: built as the issue says, after https://git.eeqj.de/sneak/mfer/issues/224 lands, since both change `mfer/deserialize.go` and `docs/FORMAT.md`. Loading refuses a mode above `0777`, naming the path and the mode; `fetch` drops its own check and its test moves to the loader. One PR to `next` through an independent review. Worker rules: https://git.eeqj.de/sneak/mfer/issues/99#issuecomment-115880, without the `TODO.md` step.
Model: opus-5-5
Built in #230 as planned above. Loading a manifest now refuses an entry recording a mode above 0777, naming the path and the mode, so every command that reads a manifest refuses it with the same message. The check fetch had for this is gone, and its test is now in package mfer's loading tests. docs/FORMAT.md File Mode says readers reject such a mode.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/mfer/pulls/230 as planned above. Loading a manifest now refuses an entry recording a mode above `0777`, naming the path and the mode, so every command that reads a manifest refuses it with the same message. The check `fetch` had for this is gone, and its test is now in package `mfer`'s loading tests. `docs/FORMAT.md` File Mode says readers reject such a mode.
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.
docs/FORMAT.md(File Mode) saysmodeholds the nine permission bits and is never above0777, andfetchrefuses a manifest recording a larger mode before requesting any file (fetchManifestininternal/cli/fetch.go). Loading does not check it:deserializeInnerinmfer/deserialize.govalidates paths and hashes only. Socheckloads such a manifest, andChecker.checkFileinmfer/checker.gocomparesinfo.Mode().Perm(), at most0777, with the recorded value, so a file whose permission bits are exactly the recorded ones is reportedMODE_MISMATCH (mode mismatch): the message blames the file for a manifest that is out of range.list -lprints the mode as4755andexportas"4755";freshenrewrites it as the permission bits alone (mode.Perm()inAddFileWithHash), changing the entry without a word.Reproduce on
v1.0.0-rc1, in packagemfer: build anMFFilewith one entry recordingMode: 0o4755and write it throughmanifest.generate;NewManifestFromReaderloads it;NewCheckerandCheckagainst a file with mode0755giveMODE_MISMATCH a.txt (mode mismatch).Correct: a mode above
0777is refused when the manifest is loaded, as a path that breaks the path rules is, socheck,list,export,freshenandfetchrefuse it with one message, anddocs/FORMAT.mdsays readers reject it.fetchManifest's own check is then unreachable and goes, with its test moved to the loader.Severity: minor
Definition of done
NewManifestFromReaderrefuses a manifest whose entry records mode04755, naming the path and the mode.mfer/deserialize.go;internal/cli/fetch.goloses the check the loader now makes.docs/FORMAT.mdFile Mode says readers reject a mode above0777.make checkpasses.Model: fable-5-1
Plan: built as the issue says, after #224 lands, since both change
mfer/deserialize.goanddocs/FORMAT.md. Loading refuses a mode above0777, naming the path and the mode;fetchdrops its own check and its test moves to the loader. One PR tonextthrough an independent review. Worker rules: #99 (comment), without theTODO.mdstep.Model: opus-5-5
Built in #230 as planned above. Loading a manifest now refuses an entry recording a mode above
0777, naming the path and the mode, so every command that reads a manifest refuses it with the same message. The checkfetchhad for this is gone, and its test is now in packagemfer's loading tests.docs/FORMAT.mdFile Mode says readers reject such a mode.Model: opus-5-5