| Round-1 finding | Disposition | Reason |
|---|---|---|
| 1. Scanner role can read parameters | **Closed** | §3.1 now requires an explicit deny covering all four parameter-read actions on every resource. |
| 2. Masked socket prevents clamd startup | **Closed** | §3.2 now requires a complete replacement service without `Requires=` or `Also=` referencing the socket. |
| 3. Foreground FreshClam conflicts with package-started daemon | **Closed** | Package starts are suppressed; the foreground initialization completes before the updater service starts. |
| 4. Incomplete scans can be recorded as clean | **Partly closed** | `AlertExceedsMax` and the new mapping address limit-only replies. A limit can still be hidden by a malware signature, violating D8; see finding 6. |
| 5. SSM administration lacks an installed agent | **Closed** | Installing and enabling the arm64 SSM agent is now the first bootstrap step. |

Reviewed draft 2 at `05752422`. These are design dispositions; no files changed or live tests performed.

6. **P2 — §§3.2, 4.3, 7: A malware signature can hide an earlier limit hit.**

   ClamAV’s default `HeuristicScanPrecedence no` allows scanning to continue after a heuristic detection and gives a subsequent malware detection precedence. Limit indicators use that heuristic path: [libclamav/others.c:1045,1354](https://raw.githubusercontent.com/Cisco-Talos/clamav/clamav-1.4.3/libclamav/others.c). The precedence behavior is documented in the [trixie configuration manual](https://manpages.debian.org/trixie/clamav-daemon/clamd.conf.5.en.html#HeuristicScanPrecedence).

   An archive with an oversized member followed by a detectable EICAR member can therefore produce a malware `FOUND` reply without the limit prefix. The proposed case never matches; [internal/clamd/clamd.go:280](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/clamd/clamd.go:280) still classifies it as infected, and [internal/objstore/clamav.go:364](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/objstore/clamav.go:364) signs that verdict. This contradicts D8’s required result for an object known to have been partly scanned. The zeros-only proof does not exercise this combination.

   **Fix:** Ensure an encountered limit survives to the client—configure and test heuristic precedence, or carry completion evidence separately from the selected signature. Add a mixed oversized-member/EICAR archive to §7 and require `unscanned`.

7. **P2 — §4.3: Mapping scan-time exhaustion to `skipped` makes a temporary timeout permanent.**

   `StatusSizeExceeded` becomes `VerdictSkipped`, but [internal/objstore/clamav.go:249](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/objstore/clamav.go:249) retries only `denied` and `failed`. An unchanged, signed `skipped` verdict is returned indefinitely. [internal/objstore/sweep.go:241](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/objstore/sweep.go:241) calls the engine only for `unknown`.

   Consequently, one `MaxScanTime` result during scanner contention permanently excludes that object from scanning, even after recovery or a timeout increase. Raising extraction limits likewise does not retry archives skipped under the previous settings.

   **Fix:** Preserve D8’s `unscanned` classification while defining retry behavior for engine-limit results. For example, retry skipped objects on subsequent sweeps, retaining the existing size check before fetching. Add a two-sweep test: limit refusal first, successful scan second, with unchanged object bytes.

8. **P2 — §6.2: Ship/promote does not establish the new console’s running-version precondition.**

   Direct promotion only writes the channel pointer: [internal/release/release.go:718](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/release/release.go:718). Adoption happens separately and can defer or fail staging: [internal/release/adopt.go:956](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/release/adopt.go:956). Restarting `console.service` before adoption therefore restarts the old executable, now with the scanner wired.

   The header check occurs after wiring and has no explicit expected-build or success-status gate. Moreover, the edge supplies `X-Carlos-Version` from its route state: [internal/edge/edge.go:2192](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/edge/edge.go:2192). For an unstamped console unit, adoption can advance that state without restarting the actual console process; see [internal/host/agent.go:2898](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/scanner-host/internal/host/agent.go:2898).

   **Fix:** Before changing scanner environment variables, require adoption of the exact console artifact containing §4.3, completion of the console process restart, and a successful response identifying that build. Make failure stop the sequence before wiring or enabling scanning.

**Verdict: accept with fixes.**