• Decision: capture.Writer.WritePacket forces ci.InterfaceIndex = 0 and both live-capture call sites (internal/capture/tcpdump.go's startGopacket, cmd/app/app.go's capture setup) call SetCaptureLength(65536) on the pcapgo.EthernetHandle. pod-up.sh now also waits for dump.pcapng to exist (not just the keylog socket) and forwards a RETAIN=1 env var to the sidecar's own --retain startup flag. The in-process gopacket capture backend's occasional-to-systematic TCP segment loss during a real TLS handshake/response burst on a real container bridge interface is accepted as a known, disclosed capacity limitation (tests retry-then-skip, never hard-fail) rather than fixed in this pass.
  • Reason: Each was a real, previously-undiscovered defect found by actually bringing up a rootful pod and running real traffic through it (every prior verification pass had these tests skip on privilege/tool-availability grounds, so they never executed for real before this session): ci.InterfaceIndex defaults to the OS's real ifindex from pcapgo.EthernetHandle.ReadPacketData (almost never 0), which pcapgo.NgWriter rejects outright as "non existent interface", silently dropping every packet; the default MTU-sized AF_PACKET read buffer truncates GSO/TSO-inflated container-veth frames; pod-up.sh's original readiness wait raced ahead of capture-writer creation, so an immediate teardown (no traffic) could find no capture file at all; --retain was only ever a pod-down.sh-level (teardown-time) volume-removal decision, never forwarded to the already-running sidecar's own --retain flag, so the app's graceful-shutdown Retention.Cleanup always wiped its directory's contents regardless of operator intent. A kernel-level BPF traffic filter (SetBPF) was attempted to address the segment-loss limitation and reverted: it made things categorically worse (capture stopped entirely mid-connection) rather than better.
  • Trade-off: The segment-loss limitation remains unresolved — a proper fix needs a mmap'd AF_PACKET ring-buffer capture (e.g. gopacket/afpacket), a substantially larger change than a bugfix pass; accepting bounded-retry-then-skip in the affected test is honest but means this specific offline-decrypt-content guarantee is not currently proven end-to-end on every host.
  • Scope: Feature 03 (internal/capture, cmd/app, deploy/podman/).
  • Date: 2026-09-18
  • Status: active, amended by AD-014 — the InterfaceIndex, GSO-snaplen, dump.pcapng readiness-wait and RETAIN-forwarding fixes all still hold and are still load-bearing. The CAPTURE-04 segment-loss trade-off is resolved, and this decision's diagnosis of it is superseded: the failure was never segment loss and never a capacity limit of pcapgo.EthernetHandle. AD-014 found three sufficient causes elsewhere (an ALPN-blind -Y http filter, a Decryption Secrets Block written after the packet blocks, and tshark's default out-of-order TCP reassembly being off) and showed that a simultaneous tcpdump — an mmap'd AF_PACKET ring, the very thing proposed here as the fix — reproduced the same symptom, so the gopacket/afpacket migration this trade-off called for was never the remedy and is withdrawn.