Coverage
The span bar and its shared scale, the stale tint, gap cut-outs from the file index, the cross-kind Partial column, and the two smart views that filter on them.
One cell answers three questions — how much of the store's timeline a series spans, whether it
has stopped, and whether it has holes — and a fourth, whether an instrument has days where one
kind is present and another is not, cannot be answered per series and gets its own column. The
authorities are crates/vike-data-manager/src/view.rs for the rendering and
crates/vike-data-manager/src/model.rs for the rollups the scale is built from.
The span bar
paint_coverage_bar paints a background track and a filled segment spanning the series'
[first_ts, last_ts], mapped over the tree-wide window [global_first, global_last]. That window
is global_span: the earliest first and latest last across every venue with at least one series,
folded from the RollUp each node carries. The header gives the reason for a shared scale: bars
are painted over the tree-wide window "so bars are comparable across every row". A zero-row series
paints an empty track, and when nothing has data the window is inert and every bar is empty.
Stale
A series reads as stale when its last_ts lags more than 35 % of the tree-wide span behind the
global maximum, and its bar takes the warning colour. is_stale's doc calls the fraction arbitrary
but conservative: recent data is typically within a few percent of the newest, and anything more
than a third of the whole window behind is very likely an abandoned or broken feed rather than
yesterday's close. It is a fraction of the span you hold, not a number of days.
Gap cut-outs
The rich grid takes a GapMap: per-series missing-day ranges keyed by the same SeriesKey the
selection uses. paint_coverage_bar overpaints each range as a dark cut-out inside the filled
segment, so a hole reads as missing against the span. Fetching the map is the caller's job — the
header is explicit that this crate never calls series_gaps itself — and has_gaps's doc states
the conservative default: a series absent from the map, never fetched or failed, is treated as
gap-free, so the bar never flags a series it has no data for.
What a gap is comes from crates/vike-data/src/datafusion_hist.rs's series_gaps: the ranges
missing within a series' recorded span, derived purely from the manifest's date= file index with
no Parquet scan, as cheap as a coverage read. Contiguous coverage, fewer than two distinct days, or
no data at all return an empty list; it never errors on "no data". The finder underneath is
crates/vike-data/src/coverage.rs's find_gaps, whose doc example is the whole rule: present days
[1, 2, 5, 6] give one gap, (3, 4).
A gap is a missing day, not a missing row
The index knows which days exist and nothing finer. coverage.rs's header draws the line: a day
that is present but was recorded through a feed outage is a row-level trust question, answered by
the quality module over scanned rows, not by this fold. A day the recorder half-covered shows as
present here.
The app fetches the map alongside the tree: crates/vike-app-core/src/stored_load.rs's
load_stored_tree probes series_gaps once per listed series — manifest-only locally, one small
RPC per series on a remote store — and a failed probe skips that one entry rather than failing the
refresh, which runs on the tab's first render and on Refresh, never per frame.
Partial days
PartialDayMap is keyed one level above the gap map, by vike_data::InstrumentKey — venue, label
and the grouped flag. Its doc explains why it is a second map rather than more gap entries: the two
answer different questions and neither derives from the other. A gap says this series is missing
days 3–4, a hole in one kind's own timeline. A partial day says on day 11 the instrument has
trades but no book — invisible per series, because each series is perfectly contiguous on its
own. The doc's example is the case that motivated the column: a Polymarket venue backfill restores
the trade tape and nothing else, since no venue-direct source serves book, so the trade series
closes its gap, the book series never had one, and only the join shows that a market-making
backtest over that window would run on no book at all.
The join is coverage.rs's InstrumentCoverage::partial_days, and two of its rules shape the
column:
- Only tick kinds are lined up.
TICK_KINDSistrade,quote,book,depth. Bars are excluded on purpose: they derive from trades, so a missing bar day beside a present trade day is a resample not yet run, not a hole in the tape.depthis included because that is where some feeds' L2 lands — omitting it once made the report claim an instrument had no L2 while 34 rows of it sat on disk. - Days are held against the instrument's own recorded kinds. An instrument with no book series
at all is not partial on every day it will ever have — the doc calls that "a permanent ⚠ carrying
no day-to-day information, which is precisely how an operator learns to ignore a warning
column"; the absence is already visible as a missing
bookrow. With fewer than two recorded kinds nothing is partial.
The report is a manifest fold in the same cost class as the inventory — one manifest read per
series, no Parquet scan — so the Data Manager runs it on open. The column shows a ⚠ glyph and puts
the detail in the tooltip, in partial_days_label's shape: 3 partial days (book, quote). It is
an instrument-level flag, so every row of one instrument carries the same value.
Over the wire, the column has three states
crates/vike-app-core/src/stored_mode.rs decides them. Local: rendered from the local fold.
Remote, verb served: rendered from the wire answer. Remote, verb not served: a note in its place —
"Partial column unavailable: the connected datahub did not answer the cross-kind coverage verb (an
older server, or a read failure — see the log)". The verb is capability-negotiated rather than
version-gated, so a refusal means the peer predates it, and an empty column is never substituted,
because empty would claim "nothing is partial" — a different and possibly false fact.
The smart views
filter_tree applies the sidebar's choice. Has gaps keeps only series with a non-empty gap
list; Stale keeps only series whose coverage lags the tree-wide span, reusing is_stale; a
venue entry keeps only that venue. Both smart views drop symbols left with nothing and venues that
empty out, and — the detail filter_stale_venue's doc insists on — rebuild the rollups over the
surviving rows, so the filtered tree's header summaries and span bars stay internally consistent
rather than describing rows you can no longer see.
The catalog
The stored-series grid — one rollup row per venue, one row per series, six sortable columns, a search box, and in the app a checkbox column with a bulk-action bar.
Backfill from the GUI
What the Backfill button plans from a selection, the one resolved address that decides whether it runs in this process or on a data service, and what a venue backfill cannot repair.