Conversation
…was purged on purpose Both published collections told consumers, on the mode hex asset, "for the area held by each class use the fractional-coverage asset instead". No such asset exists: fractions were dropped deliberately for this source (BUILD.md - at 30 m and res 10 a cell holds ~17 pixels and stands are far larger, so mode tracked the true CONUS VCC distribution to within 0.72 pp), and the two partial prefixes (vcc 1/6, evt 2/6, ~9 GB) were purged so they could not fake coverage. make-stac.py already had a `fractions_published` flag, but it only popped the asset and rewrote the collection-level description; `hex_desc` was built unconditionally, so the asset-level sentence survived. verify-stac.py does not catch it because the reference is prose, not an entry in `assets`. - hex_desc now branches on fractions_published. The no-fractions text states the limit and names the reducer that answers it, instead of pointing at nothing. - bucket_collection() had the same class of drift in the other direction: it claimed all four products "in both dominant-class and per-class fractional-coverage form" and emitted child links for all four. Only vcc and evt are published. That was corrected by hand at publish time, so re-running the generator would have regressed the live document back to the false claim and added two 404 child links. Added PUBLISHED and matched the live text. Republished landfire-2024-vcc and landfire-2024-evt via a geo-workflows job, patching only assets.<layer>-hex.description (asserted no other key changed). verify-stac.py --bucket public-landfire exits 0 for both, and build() now reproduces the published description byte-for-byte for both layers. The bucket collection needed no republish - it was already correct on S3; this only stops the generator from undoing it.
9 tasks
cboettig
added a commit
that referenced
this pull request
Sep 14, 2026
make-stac-structure.py authors all seven and the public-landfire bucket collection. Two shapes in one tranche needing opposite treatment: CONTINUOUS (cbd, cbh, cc, ch) -- linearly scaled physical quantities. `mean` reducer, decode from the shipped CSV (KGM3 = VALUE/100, METERS = VALUE/10, CC_PERCENT = VALUE), and NO classification:classes: a continuous surface has no class list, and #628's rule is that anything listed there gets painted. CATEGORICAL (fbfm13, fvc, fvh) -- class codes. `mode` reducer, classification:classes from the shipped legend with fill codes REMOVED per #628. Every range, mean and `values` array is MEASURED from the published hex rather than taken from upstream documentation (#518). Verified: all 48 fvc / 40 fvh / 17 fbfm13 values present in the data are legend members, and no fill code appears in any class list. The four facts a consumer cannot recover from the data are all in the published text: - the decode factor -- without it a reader takes 12 for 12 kg/m^3 rather than 0.12; - `0 = Non-Forested` is a category, not a measurement, and is ~69% of valid pixels, so it is excluded and a mean over these layers is a mean over FOREST, not over all land; - cbh's top class (stored 100) means ">= 10 m" and holds ~19% of cells, so its mean is pulled toward that ceiling; - cc has no class below 10% cover -- sparse tree cover falls into 0 and is absent, so the layer cannot separate open woodland from treeless ground. One prose bug the gate could not catch: cc's decode sentence read "the stored value is not the physical quantity: the stored value is already a percentage to obtain percent", because the template assumed a scale factor and cc's is identity. verify-stac.py passed it -- it checks structure, not whether the sentence parses. Now branches on scale == 1.0. Bucket collection gets a SINGLE OWNER. make-stac.py's bucket_collection() knows only the original four layers, so running it against public-landfire/stac-collection.json would silently drop these seven; it is marked superseded in a docstring and this file carries the full nine-product roster. Two generators for one file is how the fractions claim drifted the first time (PR #655). Gates, all green: pre-publish verify-stac.py --no-data PASS x7 + bucket upload readback byte-identical x7 + bucket post-cluster verify-stac.py --bucket --dataset exit 0 x7 (includes the data-backed values == ingested DISTINCT check via the MCP) bucket collection 2 -> 9 children; public-landfire already registered in the root.
5 tasks
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.
Fixes the dangling fractions reference found while triaging #203.
The defect
Both published LANDFIRE collections carried this on their
modehex asset:There is no such asset, and there was never meant to be one.
fractionswas dropped deliberately for this source, with measurements recorded inBUILD.md:make-stac.pyalready had afractions_publishedflag — but it only popped the asset and rewrote the collection-level description.hex_descwas built unconditionally, so the asset-level sentence survived and pointed at something purged on purpose.verify-stac.pydoes not catch it: the reference is in prose, not an entry inassets.Two fixes
1.
hex_descbranches onfractions_published. The no-fractions text states the limit and names the reducer that answers it, rather than pointing at nothing:No layer-specific figure in the string — the 0.72 pp measurement is VCC's and would be false in EVT's description.
2.
bucket_collection()had the same class of drift, in the other direction. It claimed all four products "in both dominant-class and per-class fractional-coverage form" and emittedchildlinks for all four, where onlyvccandevtare published. The live bucket collection is correct because it was corrected by hand at publish time — so re-running the committed generator would have regressed it to the false claim and added two 404 child links. Added aPUBLISHEDset and matched the live text.Published and verified
Republished
landfire-2024-vccandlandfire-2024-evtthrough ageo-workflowsjob (no local NRP credentials), patching onlyassets.<layer>-hex.description:verify-stac.py --no-dataverify-stac.py --bucket public-landfire --dataset landfire-2024-vcc… --dataset landfire-2024-evtCode and data agree: stubbing the legend/histogram readers with the published values and running
build()reproduces the livedescriptionbyte-for-byte for both layers, andbucket_collection()now reproduces the live bucket document exactly (description and child list). So the next generator run is a no-op rather than a regression.The bucket collection itself needed no republish — it was already correct on S3. This only stops the generator from undoing it.
Not addressed here
verify-stac.py --bucket … landfire-2024-evtreports one pre-existing ADVISORY,values-extra: declared codes7969and9075never appear in the data. Untouched by this PR (thevaluesarray was not modified) and noted on Import: LANDFIRE CONUS vegetation & departure suite — EVT, BpS, FRG, SClass, VCC, VDep (LF2024/2020/2016) #203.⛔ SCOPEsection on Import: LANDFIRE CONUS vegetation & departure suite — EVT, BpS, FRG, SClass, VCC, VDep (LF2024/2020/2016) #203 still mandatesmode+fractionsunconditionally, which now contradicts the measured decision. Flagged on the issue; a scope edit, not a code change.9,8,0against9,8,7,6,5,0as pinned. Separate question, also on Import: LANDFIRE CONUS vegetation & departure suite — EVT, BpS, FRG, SClass, VCC, VDep (LF2024/2020/2016) #203.