Skip to content

feat(archiver): explain empty archiver reads with coverage verdicts - #568

Merged
thellert merged 1 commit into
mainfrom
feature/archiver-coverage-verdicts
Aug 11, 2026
Merged

feat(archiver): explain empty archiver reads with coverage verdicts#568
thellert merged 1 commit into
mainfrom
feature/archiver-coverage-verdicts

Conversation

@thellert

Copy link
Copy Markdown
Collaborator

An archiver_read that finds nothing now says why.

Previously an empty window produced a success response with points: 0 and no
explanation, leaving four different situations indistinguishable to the agent:
a window that predates the archive, a window after the newest sample (e.g. a
stopped recorder), a channel that was never recorded, and a genuine gap inside
coverage. The agent could only guess, or report a bare "no data found" that
leaves the operator stuck.

The response now carries a summary.coverage block whenever a requested
channel has zero points, naming one of five verdicts per channel —
window_precedes_archive, window_follows_archive, never_recorded,
gap_within_coverage, coverage_unknown — with the archive's real bounds and
a plain-language message.

Design properties:

  • Facts only. Bounds come from the store's actual oldest/newest samples via
    get_metadata; a backend that reports no bounds (EPICS, DOOCS) yields
    coverage_unknown rather than a guess. The explanation may be missing; it is
    never invented.
  • A gap stays data. A window inside coverage with no samples is reported as
    recorded silence, not an error — nothing raises, and the data that did come
    back is never lost to its own explanation (probe failures degrade to a note).
  • The common path is untouched. Probes run only for empty channels; a fully
    answered query changes shape not at all.

The archiver-world e2e's pre-coverage claim now extends to the tool surface:
the bound the agent is shown is the deployed store's true oldest sample, ±1 s.

An archiver_read that finds nothing now says why. The response carries a
coverage block naming what the emptiness means -- the window precedes or
follows the archive's real bounds, the channel was never recorded, or the
window holds a genuine gap -- so the agent can tell an unarchived past
from recorded silence instead of guessing at a bare zero.

Verdicts are derived only from what the connector reports: bounds come
from the store's actual oldest and newest samples, a backend that reports
no bounds yields "unknown" rather than a guess, and a failed probe becomes
a note on the verdict rather than the loss of whatever data did come
back. Probes run only for channels that returned empty, so a fully
answered query costs nothing and changes shape not at all.

The archiver-world e2e now asserts the same claim at the tool surface:
the bound shown for a pre-coverage window is the deployed store's true
oldest sample, not a declared window.
@thellert
thellert merged commit 3e5cbc4 into main Aug 11, 2026
44 checks passed
@thellert
thellert deleted the feature/archiver-coverage-verdicts branch August 11, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant