What
There has been one retrieval (2026-08-07); the second will replace it, and the pages will describe the new file as if the old one never existed. This keeps every pinned retrieval's artifact under site/data/history/<source>/<retrieved>.json, adds site/history.html, and for each consecutive pair publishes the paired per-value differences a reader needs: records per year added or removed (FRAP), IRWIN coverage per year, per-field three-state counts, DINS incidents added, and per-incident completeness for incidents present in both. Each row carries both retrieval dates, both values, and the difference; no line is fitted, no direction is stated, and a field absent from one pin is shown as absent.
Why it matters
FRAP publishes versioned releases and the DINS layer is appended to after each season, so "what did the publisher fill in since last year" is the question a downstream user asks and cannot answer from either file alone. The sibling wildfire-service-territory-overlap decided this shape in advance for its own second retrieval (ADR 0012: paired, never modelled) and the same rule fits here: two pins invite a story about improvement, and the page must refuse to tell it. The build stays deterministic; history artifacts are inputs committed under site/, and the page is rendered from them like the other two.
Scope
- History directory and a loader that refuses an artifact whose
source.retrieved or sha256 disagrees with its filename or, for the current pin, with sources.py.
render.py: history.html with the same palette, markers, WCAG gates, and prose-number tracing test as the other pages.
- An ADR recording the paired-difference rule and the refusal of trend language, with a page test that greps for it.
tests/test_published_site.py extended to the new page; site-offline builds it from two fixture pins.
Out of scope
- Any per-year or per-incident rate of change.
- Retrieval scheduling.
Done when
- With two fixture pins, the page lists each changed per-year count with both values and the difference, and an incident present only in the later pin as "not in earlier retrieval".
- With one pin, the page says there is one retrieval and no comparison, rather than an empty table.
- A history artifact whose hash disagrees with its filename fails the build.
- The page passes every existing page gate.
Pointers
src/perimeter/render.py, artifacts.py, sources.py (RETRIEVED), site/data/, docs/adr/0009-the-clock-lives-in-the-gate.md
wildfire-service-territory-overlap/docs/adr/0012-two-boundary-retrievals-are-compared-paired-never-modelled.md
Proposed with AI assistance.
What
There has been one retrieval (2026-08-07); the second will replace it, and the pages will describe the new file as if the old one never existed. This keeps every pinned retrieval's artifact under
site/data/history/<source>/<retrieved>.json, addssite/history.html, and for each consecutive pair publishes the paired per-value differences a reader needs: records per year added or removed (FRAP), IRWIN coverage per year, per-field three-state counts, DINS incidents added, and per-incident completeness for incidents present in both. Each row carries both retrieval dates, both values, and the difference; no line is fitted, no direction is stated, and a field absent from one pin is shown as absent.Why it matters
FRAP publishes versioned releases and the DINS layer is appended to after each season, so "what did the publisher fill in since last year" is the question a downstream user asks and cannot answer from either file alone. The sibling
wildfire-service-territory-overlapdecided this shape in advance for its own second retrieval (ADR 0012: paired, never modelled) and the same rule fits here: two pins invite a story about improvement, and the page must refuse to tell it. The build stays deterministic; history artifacts are inputs committed undersite/, and the page is rendered from them like the other two.Scope
source.retrievedorsha256disagrees with its filename or, for the current pin, withsources.py.render.py:history.htmlwith the same palette, markers, WCAG gates, and prose-number tracing test as the other pages.tests/test_published_site.pyextended to the new page;site-offlinebuilds it from two fixture pins.Out of scope
Done when
Pointers
src/perimeter/render.py,artifacts.py,sources.py(RETRIEVED),site/data/,docs/adr/0009-the-clock-lives-in-the-gate.mdwildfire-service-territory-overlap/docs/adr/0012-two-boundary-retrievals-are-compared-paired-never-modelled.mdProposed with AI assistance.