Surface raw-document caching, sitemap conditional fetching and explain cadence in the console (v0.14.0) - #184
Merged
Merged
Conversation
…hing and explain cadence; v0.14.0 Catch-up with plugin v0.77.0 (PRs #165, #177, #181, #182). Four signals the plugin now emits or returns had no console surface, and each one is invisible by construction rather than merely missing. RAW-DOCUMENT CACHE (plugin #181). New Traffic panel reading `prerender_ops` `raw_cache`, and it leads with the REFUSALS: a route that is enabled and storing nothing produces the same miss rate, the same origin proxies and the same absence of errors as a route nobody enabled, so `stored` alone would be blind to the whole failure mode. `has-cookie` (the origin is personalizing a route assumed to be shared) and `oversize` (`maxBytes` below the route's real document size) are called out above the breakdown rather than left as bars. `raw` AS A SERVE VERDICT. The colours were already added; this makes them coherent everywhere else: - the non-hit taxonomy gains a `raw` family — without it the verdict fell through to "an outcome this console does not know about"; - the Cache-served tile now counts the VERDICT (`isCacheServed`) rather than the source `cache`. The two agreed until v0.76.0; `raw` is a cache serve with its own source, so the tile would have fallen as the feature started working while gross offload rose. The raw share is named in the subtitle, never folded in; - the staleness panel's past-due denominator moves the other way, to source `cache` only: `page_age` is emitted only on that branch, so counting raw serves there would have shrunk the past-due share and fired the "verdicts disagree" note against a fleet that is genuinely behind. SITEMAPS (plugin #165, #177). `lastRefreshed` is relabelled "ingested": a 304 deliberately writes nothing, so it is when this document's ENTRIES last changed, not when it was checked — and "refreshed" made conditional fetching working read as a sitemap hours stale. When it was checked comes from the run row and is shown beside it. The per-root walk now reports its 304s and its fast-path creates (a SUBSET of created, stated with its denominator), and a new panel sums the `sitemap_*` counters across roots and nodes over 24h — `sitemap_not_modified` is the only evidence anywhere that conditional fetching works at all, and a flat zero across a day of walks is flagged. EXPLAIN CADENCE (plugin #182). The explainer renders the new `cadence` block: effective interval, all four inputs, the demand floor, and `clampedBy` first. `floor` across a route means the ladder has no dynamic range there. The Target card's `renderInterval` is relabelled as the ceiling it is. THE GUARD'S sitemap_* BLIND SPOT IS CLOSED. `metrics.sitemapRun` is on DYNAMIC_SERIES_SLOT, and that exemption cost exactly what the probe one did: two series shipped unread with a green suite on both sides. The new test reads the EMIT SITES rather than the catalog, deliberately — the catalog enumerates six `sitemap_*` names and the plugin emits fifteen, so a catalog-based guard would have passed while blind to the two series it exists for. Not closed, and named in the guard rather than left silent: the `sitemap_departure_*` family (ten series) has no panel. Departures are a separate decision surface with dry-run-vs-armed semantics of their own and want their own panel, not seven more tiles on the walk card. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Console catch-up with plugin v0.77.0 (#165, #177, #181, #182). Four signals the plugin now emits or returns had no console surface, and each is invisible by construction rather than merely missing.
@harperfast/prerender-console0.13.1 → 0.14.0 — new panels and a relabelled field, no breaking change. No console version is reserved in an open PR (#178 is plugin v0.75.0) andprerender-console-v0.14.0is unreleased.1. The raw-document cache reports what it REFUSED (#181)
New Traffic panel over
prerender_opsseriesraw_cache. It leads with the refusals, because that is the whole point: a route that is enabled and storing nothing produces the same miss rate, the same origin proxies and the same absence of errors as a route nobody enabled. Chartingstoredalone would have been blind to the one failure mode the series exists for.Two outcomes are findings rather than traffic and are called out above the breakdown:
has-cookie— the origin set a cookie, i.e. it is personalizing a route enabled on the assumption it is shared. The refusal is correct; the assumption is not, and nothing else in this console would ever say so.oversize—render.raw.maxBytessits below the route's real document size, so the feature is on and structurally cannot fill. A settings fix.The rest (
not-200,content-type,no-store,no-body,staging,capture-busy,capture-failed,write-failed,empty) get a row each with what they mean. Off and never configured, the panel describes the capability instead of drawing a chart of zeroes — the same exit the discovery gate takes, and it sits next to it: the gate keeps those URLs out of the rotation, the raw cache answers them anyway.Store rate is deliberately not divided by serves. A document stored now is read by the next crawler, possibly in the next window. Different populations, shown side by side.
2.
rawas a serve verdict, made coherent everywhere elseThe colour entries in
charts.jswere already in place. This is what consuming them correctly turned out to require:rawfamily. Without it the verdict fell through to "an outcome this console does not know about" — a cache serve that costs the origin nothing, filed under unknown.path === 'cache', which agreed withisCacheServeduntil v0.76.0 because every cache-served verdict carried sourcecache.rawbreaks that — it is a cache serve with its own source — so the tile would have fallen as the feature started working, while gross offload rose. It now usesisCacheServed(the enumerationcharts.jssays every such sum must share) and names the raw share in the subtitle rather than folding it in: a snapshot means a render covers that URL, a raw document means one never will.cacheonly.page_age/route_page_ageare emitted only when the source iscache, so a raw serve contributes no age sample; counting it in that denominator would shrink the past-due share on exactly the deployments serving a lot of raw, and fire the "the verdicts disagree with this ratio" note against a fleet that is genuinely behind.That last pair is the answer to "is the
rawaddition coherent with how these sets are consumed?" — it was not, in two opposite directions, and one closed set (NOT_HIT) had no entry at all.3. Sitemaps: ingested vs checked, and the walk counters (#165, #177)
lastRefreshedwas mislabelled and is now "ingested". A 304 deliberately writes nothing — the stored row and its validator are still current — so that field is when this document's entries last changed, not when it was looked at. Labelled "refreshed", conditional fetching working read as a sitemap hours stale. When it was checked comes from the run row (SitemapRefresh, one per root) and is shown beside it, on the root cards and in the detail stats. A child sitemap has no run row, and the card says which timestamp it is carrying.The per-root last walk now reports
Not modified (304) — N of M documentsand, on the creates line, how many took the new-target fast path — a subset of created, stated with its denominator so it can never read as a fourth count.New walk-activity panel summing the
sitemap_*counters across roots and nodes over 24h (the range key the Change probe view already uses, so the two share one cached scan per node).sitemap_not_modifiednon-zero is the only evidence anywhere that conditional fetching is working at all — a walk that re-parses everything succeeds exactly like one that skipped — so zero 304s across a day of walks is flagged explicitly.4. Explain returns a cadence block, and the console renders it (#182)
The explainer's Target card showed
renderInterval, which is the ceiling the demand ladder schedules inside; with the ladder armed that is not the cadence for most of a corpus, and nothing said so. A new Render cadence card renders the plugin's own resolution — effective interval, all four inputs, the demand floor — and leads withclampedBy:floor— the ladder wanted faster and the floor refused. Across a route it means the ladder has no dynamic range there and promotion is running for nothing.ceiling— the rung is slower than the route grants, so it is inert.The Target row is relabelled
Render interval (ceiling). A URL with no target gets no card: cadence is a property of being in the rotation, and absence is the answer rather than a row of dashes.The metric guard's
sitemap_*blind spot is closedmetrics.sitemapRunis onDYNAMIC_SERIES_SLOT, and that exemption cost exactly what the probe one did:sitemap_not_modified(v0.69.0) andsitemap_created_soon(v0.74.0) shipped unread with a green suite on both sides.The new test reads the emit sites in
resources/Sitemap.js, deliberately not the catalog as the probe test does. The two have drifted and the drift is the point: the catalog'svalueslist enumerates sixsitemap_*names while the plugin emits fifteen, so a catalog-based guard would have passed while blind to the two series it exists for. Verified to bite (renaming a read makes it fail with the series name).What I did NOT fix, explicitly
sitemap_departure_*(ten series) still has no panel. It is now named in the guard with the reason rather than passing silently: departures are a separate decision surface with dry-run-vs-armed semantics of their own and want their own panel, not seven more tiles on the walk card.departure_reattachedis the one METRICS.md says to watch.METRICS.prerender_ops.dimensions.path.valueslist is stale — it is missingraw_cache,sitemap_not_modified,sitemap_created_soonand the wholedeparture_*family. That is a plugin-side catalog fix and would need a plugin version bump, so it is out of scope for a console PR. The new guard routes around it by reading emit sites; the probe guard still reads the catalog and is therefore exposed to the same drift.serve_errorgainedraw-blob-timeout/raw-blob-unreadabledetails.serve_erroris waived in the coverage guard (the serve-side view of it isbot_serveblob-*on Traffic) and those two details have no serve-side equivalent, since a raw blob fault degrades to an origin proxy counted asmiss. Left as-is; worth a follow-up if raw caching goes wide.Verification
packages/console: 276 tests pass (was 261; the guard was already failing onraw_cacheatorigin/main). New: 4 raw-cache Traffic tests, 5 sitemap ingest/walk tests, a newinspectView.test.jswith 5 cadence tests, and the sitemap-family guard.packages/plugin: 1155 tests pass (untouched, run as a sanity check).npm run lintandnpm run format:checkclean at the root.🤖 Generated with Claude Code