-
Notifications
You must be signed in to change notification settings - Fork 1
small fixes 2026-08-17 (4): shipped S2 pyramid opt-out, deliberate shardmap re-pin driver #467
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
2893d6a
89f20f4
d8518c2
32f2b99
844348c
0aa3358
ba246df
84678a4
4a96fd5
1c49621
967f9ae
db14b48
0b4f9e2
819ddeb
57364d5
98ab544
8aed187
2d7d914
7307a38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -179,6 +179,20 @@ places the panel. | |
| print(bench_metrics.select_densest_shard(sm)) # -> (shard_key, n_granules) | ||
| ``` | ||
|
|
||
| > **Re-pinning a map that already exists** is one command: | ||
| > `tools/repin_benchmark_shardmaps.py` (issue #444) rebuilds through the | ||
| > drift check's own recipe, selects the pin (nested rule included), prunes | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) Stale after It matters here because the sentence is the one that tells a re-pinner where the shared logic lives, and the whole point of the fold was that a Fix: "rebuilds through the shared recipe in
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude Fixed in 7307a38. The re-pin block now reads that the driver "rebuilds through the shared recipe in The pre-existing python fence just above (~line 176) is untouched — |
||
| > the ring maps, and writes the map plus its `targets.json` | ||
| > `shard_key`/`n_granules`. It re-pins **deliberately** — the drift check | ||
| > stays the accident detector — so run it only when a convention or grammar | ||
| > change makes the committed words wrong. `--check` rebuilds and reports the | ||
| > differences without writing. The entry's `note` is prose: restate it by | ||
| > hand in the same commit. | ||
| > | ||
| > ```bash | ||
| > uv run python tools/repin_benchmark_shardmaps.py --check healpix_o9_88s | ||
| > ``` | ||
|
|
||
| > **The committed maps span two granule-record schemas.** The five | ||
| > `sm_healpix_*.json` maps were last rebuilt after issue #246, so their | ||
| > granule records carry `time_start`/`time_end` (and their `metadata` a | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,13 +61,13 @@ def resolve_aoi_temporal_cmr(sm_meta: dict) -> tuple[dict, dict, dict]: | |
| ) | ||
|
|
||
|
|
||
| pytestmark = [ | ||
| pytest.mark.slow, | ||
| pytest.mark.skipif( | ||
| os.environ.get("ZAGG_BENCHMARK_DRIFT") != "1", | ||
| reason="set ZAGG_BENCHMARK_DRIFT=1 to run the CMR shard-map drift check", | ||
| ), | ||
| ] | ||
| #: The network gate is the drift check's own, not the module's (it was | ||
| #: module-level while the drift check was the only test here): the issue #444 | ||
| #: re-pin-driver tests below rebuild from the committed catalogs and need no CMR. | ||
| needs_cmr = pytest.mark.skipif( | ||
| os.environ.get("ZAGG_BENCHMARK_DRIFT") != "1", | ||
| reason="set ZAGG_BENCHMARK_DRIFT=1 to run the CMR shard-map drift check", | ||
| ) | ||
|
|
||
|
|
||
| def _containing_shard(parent_grid, shard_key: int) -> int: | ||
|
|
@@ -101,6 +101,8 @@ def _config_for_shardmap(sm_key: str) -> Path: | |
| raise AssertionError(f"no target references shardmap '{sm_key}'") | ||
|
|
||
|
|
||
| @pytest.mark.slow | ||
| @needs_cmr | ||
| @pytest.mark.parametrize("sm_key", list(MANIFEST["shardmaps"])) | ||
| def test_pinned_shardmap_no_drift(sm_key): | ||
| from zagg.catalog import load_polygon, polygon_to_bbox | ||
|
|
@@ -170,3 +172,92 @@ def test_pinned_shardmap_no_drift(sm_key): | |
| f"{sm_key}: densest granule count drifted {pinned_n} -> {n} " | ||
| f"(rebuilt densest shard {key}). Re-pin the shard map + targets.json." | ||
| ) | ||
|
|
||
|
|
||
| # -- the deliberate re-pin driver (issue #444) -------------------------------- | ||
| # | ||
| # ``tools/repin_benchmark_shardmaps.py`` is the counterpart of the drift check | ||
| # above: the guard detects an accidental move, the driver makes a deliberate | ||
| # one. It imports the guard's recipe helpers, so these tests pin the parts the | ||
| # guard does not exercise -- the pruning, the pin write-back, and the claim the | ||
| # driver exists to support: that it reproduces the PR #441 artifacts from the | ||
| # committed catalogs. | ||
|
|
||
| OFFLINE_PINS = [k for k, v in MANIFEST["shardmaps"].items() if v.get("catalog_parquet")] | ||
|
|
||
|
|
||
| def _driver(): | ||
| """The re-pin driver, imported from ``tools/`` (not an installed module).""" | ||
| sys.path.insert(0, str(REPO / "tools")) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) Nit (decline freely). Not a correctness issue — the imports resolve to the same module object either way — purely house-style consistency (§4). Generated by Claude Code
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude Folded in The insert is hoisted to module scope beside the sys.path.insert(0, str(REPO / "tools"))
def _driver():
"""The re-pin driver, imported from ``tools/`` (not an installed module).
The import itself stays lazy: the driver imports THIS module for the
rebuild recipe, so importing it at module scope would be circular.
"""
import repin_benchmark_shardmaps
return repin_benchmark_shardmapsThat circularity is the one reason the whole thing is not simply a module-scope import like Generated by Claude Code |
||
| import repin_benchmark_shardmaps | ||
|
|
||
| return repin_benchmark_shardmaps | ||
|
|
||
|
|
||
| def _without_volatile(text: str, volatile) -> str: | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review)
The filter drops any line containing But the coupling is invisible and the failure is silent. If Fix (either is fine):
Low severity today, but it is the kind of test that reports green forever once it breaks. Generated by Claude Code
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude Folded in I kept the comparison line-oriented on purpose: issue #444's word is "byte-identically", and switching to parsed structures would quietly soften that to structural equality — the same class of relaxation your lines = text.splitlines(keepends=True)
kept = [line for line in lines if not any(f'"{k}"' in line for k in volatile)]
assert len(lines) - len(kept) == len(volatile), (
f"expected one line per excused metadata key, dropped {len(lines) - len(kept)} of "
f"{len(lines)} -- has ShardMap.to_json stopped pretty-printing?"
)The vacuous-pass path you describe is now impossible: compact JSON would drop 1 line of 1 against an expected 2 and fail with a message naming the cause. It also closes the direction you did not raise — a key string surfacing inside a granule record would drop more lines than expected and fail too, rather than silently widening the exclusion. The docstring records the coupling to Generated by Claude Code |
||
| """A written map's text minus the metadata lines a rebuild legitimately moves.""" | ||
| return "".join( | ||
| line | ||
| for line in text.splitlines(keepends=True) | ||
| if not any(f'"{k}"' in line for k in volatile) | ||
| ) | ||
|
|
||
|
|
||
| @pytest.mark.slow | ||
| @pytest.mark.parametrize("sm_key", OFFLINE_PINS) | ||
| def test_offline_pin_reproduces_committed_map(sm_key, tmp_path): | ||
| """The driver reproduces the PR #441 artifacts from the committed catalogs. | ||
|
|
||
| The acceptance test issue #444 asks for, and the reason it can only cover | ||
| the ``catalog_parquet`` (88S ring) entries: the NEON trio rebuilds from CMR | ||
| by design -- an ATL03 footprint quad blankets the whole NEON box, so a local | ||
| full-catalog snapshot over-includes (``tests/data/benchmark/README.md``). | ||
|
|
||
| Byte-for-byte over the whole written manifest -- every granule record, | ||
| ``shard_keys``, ``grid_signature``, and the metadata the build derives -- | ||
| except the two keys a faithful rebuild still moves, which are asserted | ||
| separately below. | ||
| """ | ||
| driver = _driver() | ||
| mapped, key, n = driver.repin(sm_key) | ||
| sm_meta = MANIFEST["shardmaps"][sm_key] | ||
| assert (key, n) == (sm_meta["shard_key"], sm_meta["n_granules"]) | ||
|
|
||
| written = tmp_path / "rebuilt.json" | ||
| mapped.to_json(str(written)) | ||
| assert _without_volatile(written.read_text(), driver.VOLATILE_META) == _without_volatile( | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude (review) The acceptance test's exemption list is owned by the code under test — issue #444's "byte-identically" is relaxed by whatever the driver decides to relax it by. assert _without_volatile(written.read_text(), driver.VOLATILE_META) == _without_volatile(
(BENCH / sm_meta["path"]).read_text(), driver.VOLATILE_META
)
To be fair to the diff: I checked and the comparison is genuinely strong right now — 38,791 of Fix: pin the exemption in the test rather than importing it — assert driver.VOLATILE_META == ("build_wall_s", "mortie_order") # widening it must fail here— or just hard-code the tuple locally in Generated by Claude Code
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤖 from Claude Agreed on the ratchet — folded in #: The metadata keys the byte comparison below excuses, pinned HERE rather than
#: imported from the driver. [...] widening it has to be a deliberate edit here too.
EXCUSED_META = ("build_wall_s", "mortie_order")and the acceptance test both uses the local tuple and cross-checks the driver's: assert tuple(driver.EXCUSED_META) == EXCUSED_META, (
"the driver's excused-metadata set moved -- restate it here deliberately"
)So appending a key to the driver's set to quiet a noisy Thanks for measuring today's strength (38,791 of 38,793 lines) — that number is why this is a ratchet fix and not a coverage fix. Your Generated by Claude Code |
||
| (BENCH / sm_meta["path"]).read_text(), driver.VOLATILE_META | ||
| ) | ||
|
|
||
| from zagg.config import load_config | ||
| from zagg.grids import from_config | ||
|
|
||
| # The one live divergence, and why it is not a pin move: PR #447 made the | ||
| # unpinned HEALPix ``swath`` cover order the SHARD order, where the | ||
| # committed maps recorded the chunk order they were built at. The | ||
| # assignment is unchanged -- which is what the byte comparison above just | ||
| # showed, over the same catalog. | ||
| grid = from_config(load_config(str(_config_for_shardmap(sm_key)))) | ||
| assert mapped.metadata["mortie_order"] == grid.parent_order | ||
|
|
||
|
|
||
| def test_repin_updates_only_the_pin_literals_in_targets(): | ||
| # The write-back is surgical because targets.json is hand-formatted (compact | ||
| # inline ``worker`` objects survive a re-pin); the entry's prose ``note`` is | ||
| # the re-pinner's to restate, not the driver's to rewrite. | ||
| driver = _driver() | ||
| text = (BENCH / "targets.json").read_text() | ||
| out = driver.update_targets(text, "healpix_o9", 4242, 7) | ||
|
|
||
| entry = json.loads(out)["shardmaps"]["healpix_o9"] | ||
| assert (entry["shard_key"], entry["n_granules"]) == (4242, 7) | ||
| assert entry["note"] == MANIFEST["shardmaps"]["healpix_o9"]["note"] | ||
| changed = [(a, b) for a, b in zip(text.splitlines(), out.splitlines(), strict=True) if a != b] | ||
| assert len(changed) == 2, changed | ||
|
|
||
|
|
||
| def test_repin_refuses_an_unknown_shardmap(capsys): | ||
| driver = _driver() | ||
| with pytest.raises(SystemExit): | ||
| driver.main(["--check", "healpix_o42"]) | ||
| assert "unknown shard map(s) ['healpix_o42']" in capsys.readouterr().err | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 from Claude (review)
The comment attributes a dispatch effect that this key does not have — and it is 8 lines where all seven sibling opt-outs in the repo are one.
The fix itself is right, and I verified the root cause end to end on this branch:
The problem is the prose. It says an absent key means the default is ON "so every raster run dispatches a rollup sweep whose overview family generates nothing". The
sois false. Dispatch is gated onstore_layout == "hive" and get_sweep(config)— nothing in that expression readsoutput.pyramid. This config resolves tostore_layout: hive(grid-aware default,get_store_layout) andget_sweep → True(default-on for hive), before and after this change, which I confirmed by running it. Settingpyramid: falsesuppresses zero dispatches; it changes only the manifest declaration, and that is the actual — and sufficient — win. A future reader who takes the comment at face value will conclude the sweep stopped and be wrong.Two related notes:
atl03_tdigest_healpix_hive.yaml:83,atl03_tdigest_strata_healpix.yaml:157,gedi01b_waveform_healpix_hive.yaml:206,s2_neon_o9.yaml:32, and the three benchmark configs. An 8-line block here is out of house style for a one-word knob. I would cut it to the sibling form and let the PR body carry the essay:runner.py, both dispatch sites". There are fourget_sweep(config)gates: line 1173 (local raster, in-process), 1611 (Lambda raster), 3328 (local point), 4201 (Lambda point). The decline of issue Shipped S2 config's absent pyramid key silently defaults the (no-op) raster sweep on #459 item (3) still looks right to me, but espg is being asked to rule on a follow-up that is 4 call sites, not 2 — worth correcting before that ruling.Generated by Claude Code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤖 from Claude
You are right on the causation and I have not tried to defend it — folded in
db14b48. The 8-line block is now the sibling one-liner, using your wording:The false
sois gone with it: the comment no longer claims anything about dispatch, because the change does not affect dispatch. What it does — drop the manifest's five-level declaration to{"overview": {"orders": []}}— is the win, and the PR body carries that measurement.PR-body Q1 corrected too. It now says four
get_sweep(config)gates with your line numbers (1173 local raster, 1611 Lambda raster, 3328 local point, 4201 Lambda point) instead of "both dispatch sites", so the issue #459 item (3) ruling is made against the real call-site count. I left the decline itself standing — your read of it matches mine, and the reasoning was about the four sweep families, not the number of gates.Re-verified after the edit that the resolution and the identity are untouched:
cfg.output["pyramid"] is False,get_pyramid(cfg) is None,build_pyramid_block(...) == {"spec": "zagg-pyramid/1", "overview": {"orders": []}}, andtests/test_raster_runner.pyis green at 61 passed.Generated by Claude Code