Repository navigation
verify-gguf without the gguf package and without a sidecar accepts any file that starts with 'GGUF' (CR-A09-002) #83
Description
Wave 0 · theme D0-2: GGUF integrity chain: the .sha256 sidecar · highest severity High · 2 finding(s) · effort small
Summary
CI image without gguf accepts a truncated model as verified.
Primary finding
CR-A09-002 — verify-gguf without the gguf package and without a sidecar accepts any file that starts with 'GGUF'
severity High · reachability default · intent intended-but-harmful · confidence confirmed · independently confirmed · reproduced end to end · already tracked: KNOWN-OPEN TRUST-04 — docs/roadmap/phase-16-trust-surface-hardening.md:416-424,438-440 (S5 open); docs/roadmap/risks-and-decisions.md:259
What happens. In the documented degraded mode (gguf absent) only the 4-byte magic is checked when no sidecar exists; a 4-byte file or a truncated/modified GGUF prints 'OK' and exits 0. Together with F2 (no sidecar produced by the exporter) this is the default state for minimal CI images. The doc's 'minimum signal the file is what the exporter wrote' overstates it.
Where.
forgelm/verify/_gguf.py:197-203forgelm/verify/_gguf.py:175-181forgelm/verify/_gguf.py:153-181forgelm/verify/_gguf.py:84-96forgelm/export.py:205-228docs/reference/verify_gguf_subcommand.md:46docs/usermanuals/en/deployment/verify-gguf.md:12docs/usermanuals/en/deployment/gguf-export.md:19-22forgelm/cli/subcommands/_verify_gguf.py:124-125forgelm/export.py:461-478
Evidence.
- --venv lower (no gguf): magic_only.gguf (4 bytes 'GGUF'), trunc_nosc, tamper_nosc and trunc_newsc all exit 0 'OK'.
Recommended fix. Add minimal structural checks that need no dependency (version field, size sanity) and print 'metadata layer skipped' in the verdict line, or exit non-zero when neither metadata nor sidecar could be checked.
Other findings with the same root cause
These close with the same fix; update them in the same pull request.
DOC-D3B01-025 — docs/usermanuals/en/deployment/verify-gguf.md: misleading — A clean verify-gguf exit is the minimum signal the file is what the exporter wrote
severity Medium · already tracked: KNOWN-OPEN TRUST-04 docs/roadmap/phase-16-trust-surface-hardening.md:415-424
Where. docs/usermanuals/en/deployment/verify-gguf.md:12 · type: misleading
The document says. A clean verify-gguf exit is the minimum signal the file is what the exporter wrote
What the code does. Without gguf and a sidecar a 4-byte 'GGUF' file exits 0; with gguf but no sidecar a tensor-byte modification exits 0.
Code references. forgelm/verify/_gguf.py:175-210
User impact. Over-trust of a weak check.
Proposed correction. State what a clean exit proves per mode.
Turkish mirror. the Turkish page has no such statement
Acceptance criteria
- A regression test reproduces the failure scenario and asserts the corrected behaviour.
- Documentation listed above is corrected in English and in its Turkish mirror in the same PR.
- Every finding in this issue is resolved or explicitly closed with a reason.
- The release note names the contract this fix restores.
Found by the October 2026 ForgeLM code and documentation review against commit cab2947. Code links point at that commit; line numbers may have moved since. Finding IDs (CR-…, DOC-…, TECH-…) are stable references for this backlog.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
feat(export): write the SHA-256 sidecar verify-gguf relies on, and do…