Skip to content

#334 v0-detect: canonical data inventory + release manifest + boot cross-check#338

Merged
rdhyee merged 6 commits into
isamplesorg:mainfrom
rdhyee:docs/canonical-manifest
Jul 24, 2026
Merged

#334 v0-detect: canonical data inventory + release manifest + boot cross-check#338
rdhyee merged 6 commits into
isamplesorg:mainfrom
rdhyee:docs/canonical-manifest

Conversation

@rdhyee

@rdhyee rdhyee commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🤖 rbotyee (Claude, operated by @rdhyee) — Raymond's intent: answer "can we simplify our stable of supplementary parquet files?" (7/22) and land #334's v0-detect in small chunks (7/23). What I did: 3 docs/code chunks + 4 Codex review rounds to LGTM.

BLUF (plain English)

The Explorer's live data set is already minimal — 16 named parquets + the search index. The "accidental history" is what surrounds it: superseded suffix versions (each bump a real fix that left its predecessor served — the #326 failure class) and old snapshot generations. This PR neutralizes the accident three ways: a human inventory (CANONICAL.md), a machine manifest (generated from the live origin, deployed with the site), and a boot cross-check — if the page ever pins a data file the manifest doesn't bless, users see an amber "data release could not be validated" banner instead of silently inconsistent results.

What's in it

  • CANONICAL.md — canonical vs superseded vs generations, with the suffix-bump history mapped to actual commits, and the policy: a suffix bump must update the deprecation table + regenerate the manifest in the same change
  • tools/build_release_manifest.py — fail-closed generator: strict 1-byte ranged-GET probes (206 + exact Content-Range + ETag required), search-index inventory cross-validated three ways (shard_sizes.json base=256 + hot_tokens.json hot=591 = build_stats.json shard_files=847; any disagreement refuses emission)
  • isamples_202608_release_manifest.json — 21 objects, committed + listed in project.resources so it deploys same-origin with the code whose expectations it records
  • explorer.qmd manifestCheck cell — non-blocking, never throws; pins all 16 URLs + 4 runtime sidecars + whatever <link rel=preload> tags are actually in the DOM; compares the shared search_index_base cell against manifest.search_index.path; mismatch → console.error + dismissible banner; missing manifest → warn only

Review trail (4 Codex rounds)

Round 1 caught the two big ones: the manifest wouldn't have deployed at all (absent from project.resources — detection dead on arrival) and CANONICAL mislabeled 202604 as orphan when it backs the live /current/ alias tutorials use. Rounds 2–3 tightened the shard inventory (my "852 was wrong" correction was itself wrong — 256 logical vs 847 physical files) and probe strictness. Round 4: LGTM, no findings.

Issue #334 stays open until this merges + the v1 (URL-derivation) disposition is recorded there. v1 is explicitly post-grant.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y

rdhyee and others added 6 commits July 23, 2026 10:02
…story

Answers RY's 2026-07-22 question ('can we simplify our stable of
supplementary parquet files?'): the live set is minimal (17 files +
search index); the accumulation is superseded suffix versions (each
bump a real fix that left its predecessor served — the isamplesorg#326 class)
and two orphan snapshot generations (202604/202606). Suffix-bump
policy + post-grant attic plan included. Chunk 1 of the isamplesorg#334 v0 work.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
…v0, chunk 2)

Machine-readable twin of CANONICAL.md: 20 canonical objects (16 parquet
+ 4 search-index sidecars), size/etag via 1-byte ranged GET against the
live origin (the Worker 403s HEAD and the default Python UA — script
identifies honestly). Fail-closed: any missing file aborts emission.
Manifest is committed into the site repo so it deploys atomically with
the code whose pinned URLs it describes; the boot cross-check (chunk 3)
fetches it same-origin.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
…the release manifest

New OJS cell (depends only on the URL cells; non-blocking, never throws):
fetches the same-origin release manifest and verifies every pinned data
URL appears in it. Mismatch -> console.error + dismissible amber banner
('data release could not be validated'); missing manifest -> console
warning only. Converts the isamplesorg#326 silent-divergence class into
caught-at-next-boot. window.__manifestCheck exposes the result for specs.

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
…rch-index gap

- _quarto.yml: manifest added to project.resources (it would never have
  deployed — detection dead on arrival)
- search_index_base: single top-level cell shared by the runtime substrate
  path AND the manifest check; check also compares manifest.search_index.path
  so a _v1->_v2 bump with a stale manifest trips the banner
- check pins hot_topk.parquet (runtime-loaded), drops df.parquet
  (offline-only per contract); audits <link rel=preload> hrefs from the DOM
- builder: strict probe (206 + exact Content-Range + 1 byte + ETag;
  --permissive for dev), shard inventory derived from shard_sizes.json
  (256 shards, not the hard-coded 852)
- banner idempotent across cell re-evaluations
- CANONICAL.md: 202604 correctly marked as backing the live /current/
  alias (NOT movable); 202606 as documented pipeline intermediate; suffix
  history corrected to actual commits; nonexistent oc_sidecar row removed

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
… + doc accuracy

- Shard inventory: base=256 (shard_sizes.json) + hot sub-files=591
  (build_stats.json shard_files=847 physical vs shard_count=256 logical
  - the distinction round 2 surfaced) = 852 objects with sidecars; the
  builder cross-validates logical count between both artifacts
- Probe validates status + Content-Range (strict fullmatch) BEFORE reading
  the body (bounded read(2)) so a Range-ignoring origin can't force a
  300 MB download
- Header text now matches reality (ranged GET, not HEAD); CANONICAL's
  attic sentence names its targets instead of a stale section ref

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
…counts hard-required

- hot_shard_files now summed from hot_tokens.json tokens[*].sub_files
  (their authoritative declaration), not derived by subtraction
- three-way cross-check: shard_sizes base + hot_tokens hot == build_stats
  shard_files, any disagreement or missing count refuses emission
- last stale HEAD wording + shard_count/shard_files confusion in note and
  error text corrected

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
@rdhyee rdhyee added the CC+Codex+LGTM Claude and Codex both reached LGTM; ready for human review label Jul 24, 2026
@rdhyee

rdhyee commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

🤖 rbotyee (Claude, operated by @rdhyee) — staging verification, 2026-07-24 7:00am.

Staging (fork Pages, branch build): PASS. The manifest deploys (/isamples_202608_release_manifest.json → 200 — the round-1 finding that it wouldn't have deployed is confirmed fixed), and the live boot check reports {status: "ok", missing: [], extra: ["…/df.parquet"]} — the single extra being correct behavior (df.parquet is archived-but-offline-only by contract). No banner, zero console errors, Explorer boots normally. The mismatch path (banner + console.error) was exercised by simulation during Codex review round 1 (lite_v3→v4 produced MISMATCH with correct names).

Ready for merge on Raymond's call.

@rdhyee
rdhyee merged commit 00284c1 into isamplesorg:main Jul 24, 2026
2 checks passed
rdhyee added a commit to rdhyee/isamplesorg.github.io that referenced this pull request Jul 24, 2026
- Every stale reference to the deleted tutorial updated (navbar+sidebar,
  explorer footer, how-to-use, README, SERIALIZATIONS consumer note,
  narrow_vs_wide + archive links, 3 test files now assert 'Guided Tour')
- Deep-link honesty: intro promise softened to what URLs actually carry;
  Anatolia links 300km -> 150km so mode=point is real (point-mode
  threshold is 180km); densest-cell claim scoped to the res4 aggregate
- CSV claim corrected to the 50,000-row cap; place-name search mechanism
  corrected to place metadata (not coordinates)
- Source bars use the real SOURCE_COLORS palette; vocab join constrained
  to lang='en'
- Note: CANONICAL.md link resolves on merge (PR isamplesorg#338 landed on main
  after this branch was cut — merge brings them together)

Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Nohddj7oXLnkJ4P9Cibg8Y
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CC+Codex+LGTM Claude and Codex both reached LGTM; ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant