Task · OPN-0098

Reclaim expired Zenarmor inventory entries before rejecting fresh sightings

Description

Wave 8 fresh retained-state audit: boundedInventory.seen in internal/collector/boundedinventory.go checks key and byte capacity before TTL pruning, which runs only from live during snapshot construction. At capacity, an expired inventory can reject a new one-time device observation and count a false capacity refusal until the next snapshot. The lost observation cannot be recovered by subsequent pruning. This is the same stale-capacity class as the DNS cache repair, on a distinct state store not covered by the Wave 6/7 audit tables.

Acceptance Criteria

Definition of Done

Implementation Plan

Add a deterministic expiry-before-admission regression, observe failure, reclaim expired entries only when admission is otherwise capacity-blocked, then run focused race tests and integrate under root CodeRabbit and just check.

Implementation Notes

Failing-before: TestBoundedInventory_AdmissionReclaimsExpiredEntries failed with live = [current], want [current visitor]. After capacity-triggered expiry reclamation: go test -race ./internal/collector -run ^TestBoundedInventory -count=1 returned ok in 1.455s. The earliest-expiry bound avoids a full scan on every rejected sighting while every held entry is live. Integration gate and source review still pending.

Final Summary

Expired capacity is reclaimed before admission, with conservative next-expiry indexing and correct byte accounting. Deterministic failing-before regression: live = [current], want [current visitor]. Focused race tests passed in 1.455s. CodeRabbit two-file source slice complete/review_completed, zero findings, one completed pass. Integrated just check passed exit 0 in isolated exact-source worktree; just gen completed with no inventory-generated changes. Commit follows in the same root integration batch.

Landed in 4ab20cee, published with whole-wave correction 7a34b51b. Final integrated just check also passed on the corrected publication tree.

View the source file on GitHub