Fast-follow to #3738 (log observability suite). Two non-blocking accuracy edges in the agent log-correlation tooling — both about the precision of the mark → tail pattern, neither affects the radio, TX safety, or the log data itself. Scope: src/core/AutomationServer.cpp.
1. doMark can return a seq/mono_us belonging to a later event (race)
doMark injects the marker via qCInfo(), which fires the log tap synchronously and assigns the mark its sequence number — but doMark then reads m_logSeq / m_logRing.back() on the next line, after re-acquiring m_logMutex. A concurrent logging thread can push an event in that gap, so the seq handed back to the caller may belong to a later event. Then log tail since=<seq> would skip whatever was logged immediately after the mark — defeating the purpose of mark (bracketing "what happened between START and now").
Fix: have the tap return the seq it assigned to this message (e.g. capture it inside the tap closure) instead of re-reading m_logSeq after the call.
2. log tail since=<seq> silently under-reports after ring eviction
The ring holds kLogRingMax = 8000 events. A tail since=<old_seq> whose seq has already been evicted returns only what's still resident, with no signal that earlier matching events were dropped — a driver can mistake a truncated window for a complete one.
Fix: include the oldest retained seq in the tail response so a driver can detect a gap ("events before this were evicted") rather than trusting the window as complete.
Severity
Low — both only manifest under concurrency/volume in the diagnostic log stream, and only degrade the accuracy of the agent-correlation helpers (mark/tail), not the radio or the captured data. Worth fixing so the correlation tooling is trustworthy.
Refs #3738, #3646.
🤖 Generated with Claude Code
Fast-follow to #3738 (log observability suite). Two non-blocking accuracy edges in the agent log-correlation tooling — both about the precision of the
mark → tailpattern, neither affects the radio, TX safety, or the log data itself. Scope:src/core/AutomationServer.cpp.1.
doMarkcan return aseq/mono_usbelonging to a later event (race)doMarkinjects the marker viaqCInfo(), which fires the log tap synchronously and assigns the mark its sequence number — butdoMarkthen readsm_logSeq/m_logRing.back()on the next line, after re-acquiringm_logMutex. A concurrent logging thread can push an event in that gap, so theseqhanded back to the caller may belong to a later event. Thenlog tail since=<seq>would skip whatever was logged immediately after the mark — defeating the purpose ofmark(bracketing "what happened between START and now").Fix: have the tap return the seq it assigned to this message (e.g. capture it inside the tap closure) instead of re-reading
m_logSeqafter the call.2.
log tail since=<seq>silently under-reports after ring evictionThe ring holds
kLogRingMax = 8000events. Atail since=<old_seq>whoseseqhas already been evicted returns only what's still resident, with no signal that earlier matching events were dropped — a driver can mistake a truncated window for a complete one.Fix: include the oldest retained seq in the
tailresponse so a driver can detect a gap ("events before this were evicted") rather than trusting the window as complete.Severity
Low — both only manifest under concurrency/volume in the diagnostic log stream, and only degrade the accuracy of the agent-correlation helpers (
mark/tail), not the radio or the captured data. Worth fixing so the correlation tooling is trustworthy.Refs #3738, #3646.
🤖 Generated with Claude Code