13. **P2 — The self-test accepts timeouts as proof that archive limits work.** [scanner-selftest:104](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/infra/modules/scanner-host/files/scanner-selftest:104)
2
3
The classifier accepts `Heuristics.Limits.Exceeded.MaxScanTime FOUND` as a successful `limit` result. That proves only that scanning timed out, not that the deterministic archive limits prevented silent truncation. A regressed engine can therefore pass during transient load and later answer `OK` when that load subsides. ClamAV generates this reply specifically on timeout. [ClamAV 1.4.3 source](https://github.com/Cisco-Talos/clamav/blob/clamav-1.4.3/libclamav/others.c#L1152-L1156)
4
5
The substring match also accepts `Win.Heuristics.Limits.Exceeded.Fake FOUND`. Both misclassifications were reproduced using the actual classifier.
6
7
**Fix:** Parse the signature and accept only the expected deterministic limit names. Treat `MaxScanTime` as failure or retry it within a bounded policy; reject lookalikes. Add regression cases for both.
8
9
14. **P3 — A logging failure bypasses the required FAILED marker.** [scanner-init.sh.tftpl:15](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/infra/modules/scanner-host/scanner-init.sh.tftpl:15)
10
11
If `tee /dev/console` fails inside `say()`, `set -e` terminates the script without invoking the non-inherited `ERR` trap. Simulating that failure with the actual function definitions produced exit status 1 but no `SCANNER-HOST FAILED:` marker. The prescribed serial-output polling can consequently receive neither terminal marker.
12
13
**Fix:** Handle logging failures explicitly, or inherit the trap with `set -E` and make `fail()` emit its marker through a fallback that does not depend on successful serial-console logging.
14
15
Reviewed `092c5a85`; no files changed. Shell syntax, OpenTofu formatting and diff checks passed. Go, provider-backed and live-box tests were not run.