Skip to content

Abandoned cycles written before #2803 carry status=SUCCESS, so status-filtered analysis under-counts them silently #2926

Description

@erikdarlingdata

Abandoned cycles written before #2803 carry status = SUCCESS, so any analysis filtering on status reports those days clean

An analysis trap rather than a live defect — the write path is already correct. Filing it because it silently voided the first pass of an investigation today and will do the same to the next one.

The shape

EnumeratedCollectorDriver classifies a run as abandoned ? AbandonedStatus : "SUCCESS", with AbandonedStatus = "ABANDONED". That distinction arrived in #2803 (26403150, "Give a wall-clock-budget-abandoned cycle its own collection_log status"). Rows written before it carry the abandonment's own error_message — "wall-clock budget (120s) reached; cycle abandoned" — together with rows_collected: 0 and status: SUCCESS.

So a query shaped like WHERE status <> 'SUCCESS', or an MCP read filtered the same way, reports those windows as 100% clean. Observed concretely: six such rows on one server, and the omission hid roughly a third of that server's abandonment events from a first scan. They were only recovered by filtering on error_message instead.

Why it is worth a guard rather than a note

The rows are historical and cannot be rewritten — collection_log is an append-only hypertable and the abandonment already happened. So the durable fix is not to the data but to the readers, and the risk is that each new analysis rediscovers this the hard way. Two options worth weighing:

  • Derive "abandoned" from the conjunction that is true across the whole series — rows_collected = 0 together with the wall-clock message — rather than from status alone, wherever an abandonment count is computed. That works on both eras.
  • Or bound the claim explicitly: have any surface that counts abandonments state the cutoff, so a reader knows a pre-Give a wall-clock-budget-abandoned cycle its own collection_log status #2803 window is under-counted rather than clean.

The first is preferable if anything in the read path already counts abandonments, because a filter that is wrong for one era of a retention window is wrong silently and in the reassuring direction.

The general shape, which is the reusable part

This is the same defect class as an empty column read as evidence of a disabled feature: a filter that is correct against current writes and silently wrong against older ones, failing in the direction that looks healthy. A count of zero from a status filter is indistinguishable from a genuinely quiet period, and nothing in the response marks the boundary.

Provenance

Found while root-causing the 120 s abandonment tail. The status-classification code path and #2803's commit were both read on current dev; the six affected rows and the one-third undercount were observed in collected data.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions