Description
The log shutdown path flushes and stops the flow correlator while the NetFlow socket and workers are still active. A datagram accepted in that interval is counted into metrics and inserted into an already-stopped correlator; held repair records are also flushed into it later. No second correlator flush or dropped-record accounting occurs, so per-flow logs can disappear during ordinary graceful shutdown.
Acceptance Criteria
- #1 A regression injects or releases a NetFlow record during shutdown and fails against the pre-fix ordering
- #2 Shutdown first quiesces NetFlow intake and workers, then performs exactly one final processor and correlator drain while the log pipeline is still accepting records
- #3 Every accepted record during shutdown is delivered or reflected in an existing dropped counter; none can remain stranded in the stopped correlator
Definition of Done
- #1 just check
- #2 just gen (if any generated artifact changed) and the diff committed
Implementation Plan
Add a lifecycle regression around the shutdown seam, watch it fail for the post-flush intake window, then reorder shutdown ownership so the listener and processor quiesce before the final correlator flush and before the log pipeline drain.
Wave 6 correction: add an end-to-end shutdown regression using the real flowlog Bridge and pipeline; keep the bridge callback live through AfterSourcesStopped and clear it only after the correlator final flush has enqueued; verify the sink receives the pending flow and the dropped counter does not move.
Implementation Notes
Wave 6 audit disproved AC2 in the real bridge lifecycle: pipeline cancellation makes Bridge.Run clear its emit callback before AfterSourcesStopped invokes corr.Flush, so pending flow logs increment the bridge dropped count instead of entering the still-open queue. The prior shutdown regression used a direct sink and could not observe this seam.
Wave 6 final integration: the real flowlog bridge stays bound through the correlator flush and is explicitly unbound afterward. Regression and full repository gate passed at 2389ac3b.
Final Summary
Fixed by 8962f470. Shutdown now waits for log push sources, NetFlow listener/workers and the release ticker, then performs one processor flush and one correlator flush before the log queue closes. The pre-fix regression failed with a stranded held record; targeted checks passed: just test TestShutdownFlowQuiescesBeforeFinalFlush and just test TestPushSourceDoesNotBlockStop. Integrated just check passed. CodeRabbit took two completed passes: pass 1 found the valid Zenarmor quiescence gap; pass 2 completed with zero findings.
Wave 6 supersession: fixed at 2389ac3b. NetFlow producers quiesce before one final processor/correlator drain; the real bridge remains bound until that drain enqueues, then unbinds. The pre-fix regression lost the held flow and moved the dropped counter; the fixed regression and final just check passed.