Skip to content

docs: explorer state contract (closes #164)#166

Merged
rdhyee merged 4 commits intoisamplesorg:mainfrom
rdhyee:explorer-state-contract
May 8, 2026
Merged

docs: explorer state contract (closes #164)#166
rdhyee merged 4 commits intoisamplesorg:mainfrom
rdhyee:explorer-state-contract

Conversation

@rdhyee
Copy link
Copy Markdown
Contributor

@rdhyee rdhyee commented May 8, 2026

Summary

Adds EXPLORER_STATE.md — the state-contract doc for explorer.qmd, requested in #164.

  • Inventory tables for every piece of explorer state: URL query params, URL hash params, DOM-as-state, viewer.* / window.* fields, OJS cells with deps + side effects.
  • Search-semantics decision: option C (side-panel lookup with result-pin overlay). Updated from the original option-B framing after Codex review on Improve Interactive Explorer full-text search substrate #165 surfaced a sharper third option. The §6 implementation rules (50-pin cap, z-order above cluster + sample-mode, hollow-ring styling on source palette, fit-to-bounds only when result extent < 30° × 30°, lifecycle tied to ?search= non-empty) and a result-set-shape acceptance table (zero / one / local-many / global-many) are non-negotiable defaults for the implementer.
  • Facet-count contract restated to match [codex] Phase 2: add globe cross-filter facet counts #158 and the option-C decision (?search= does NO modify facet counts; backend contract unchanged from option B).
  • All references cite explorer.qmd line numbers against current main (94e7674).
  • Confirmed _urlParamsHydrated is gone.

PR is doc-only, no code changes. Three commits: original doc (78ec90a), option C addition (d139313), option C UX-rule + §9 reconciliation + pin-count wording (cdab34a + 062863d).

What this unblocks

Once merged, the items in #163 can be re-scoped against the contract:

Coordinating with the parallel FTS workstream

The search-backend question is intentionally orthogonal to option C. The state contract specifies which UI surfaces display matches (side panel + result-pin overlay); the FTS substrate work in #165 / #169-#172 specifies how matches are computed. The two land independently; the contract is compatible with every backend the FTS work might choose (in-browser ILIKE, static-Parquet inverted index, hosted-search service).

Test plan

  • Review inventory tables against current explorer.qmd
  • Confirm option-C decision and rationale (vs A and original B framing)
  • Confirm option-C implementation rules table is non-negotiable defaults the implementer should respect
  • Confirm facet-count contract matches landed behavior from [codex] Phase 2: add globe cross-filter facet counts #158

Closes #164. Refs #163, #158, PR #162, #165 (Codex review surfaced option C).

🤖 Generated with Claude Code

rdhyee added a commit to rdhyee/isamplesorg.github.io that referenced this pull request May 8, 2026
…amplesorg#165 review

Codex review of isamplesorg#165 surfaced a third option that supersedes the prior
A/B framing: side-panel lookup with a temporary point-overlay of matching
samples on the globe. Backend contract is unchanged from option B —
cluster layer and facet counts remain unaffected — but the UI surface
gains a visual answer to "where did my search land geographically."

Resolves isamplesorg#163 item 4 (zero results + populated map UX wart) cleanly:
zero results render zero pins; non-zero results render distinguishable
result pins layered above the cluster layer.

Adds a small state-inventory addendum: viewer.searchResultPoints (new
Cesium primitive collection), and an optional viewer._searchResults
cache. URL/hash params and DOM-as-state are unchanged.

Refs isamplesorg#163, isamplesorg#165, PR isamplesorg#166.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdhyee
Copy link
Copy Markdown
Contributor Author

rdhyee commented May 8, 2026

Updated: option C added per Codex review on #165

Codex's review on #165 surfaced a third option that supersedes the prior A/B framing in §6:

(C) Side-panel lookup with result-pin overlay — search backend is unchanged from option B (cluster layer and facet counts remain unaffected), but the UI surface gains a temporary point-overlay of the matching samples on the globe. Cleared when the search is cleared. Resolves #163 item 4 cleanly without making H3 clusters text-aware.

The new commit (`26429ec`):

  • Reframes §6 around three options (A/B/C) with rationale for adopting (C).
  • Adds an "Addendum to state inventory" naming the new `viewer.searchResultPoints` collection and an optional `viewer._searchResults` cache.
  • Updates the §7 facet-count-contract row to reference (C) instead of (B); facet counts are still NO for search since (C) preserves (B)'s data contract.

URL/hash params and DOM-as-state are unchanged. The "backend orthogonal to UI surface" framing is preserved — (C) is compatible with every search backend the substrate work in #169-#172 might land.

Diff is +96/-40 against the original PR; same author, same scope.

@rdhyee
Copy link
Copy Markdown
Contributor Author

rdhyee commented May 8, 2026

Review follow-up from the FTS/state-contract pass:

The option C revision is the right direction, but I would tighten two things before treating #163 item 4 as closed.

  1. There is a doc mismatch in EXPLORER_STATE.md: section 6 says option C solves Interactive Explorer rethink: architecture review + UX/feature backlog #163 item 4 through a result-pin overlay, but section 9 still says item 4 is now a side-panel-copy fix. That weakens the implementation target. If option C is the contract, acceptance should include overlay behavior, not only copy.

  2. Option C should specify the failure modes explicitly before implementation: zero results render zero pins and clear no-match state; one result can fly/select normally; local-many results can fit-to-bounds; global-many results should probably not auto-zoom to the whole world. Fit-to-bounds is only good when the result extent is bounded. For broad result sets, keep camera stable or use a gentler "show pins, don't yank camera" behavior.

I'd also make the overlay styling part of the contract: distinct ring/halo pins, capped to the displayed result set, layered above clusters/sample points, and click behavior matching sample-mode point selection. Without that, the new pathology is visual competition with the cluster layer, even though the backend/facet-count semantics are clean.

rdhyee added a commit to rdhyee/isamplesorg.github.io that referenced this pull request May 8, 2026
…iew)

Codex round-2 review on isamplesorg#165 flagged that option C's UX was
under-specified and §9 still pointed at the superseded "side-panel-copy
fix" framing for isamplesorg#163 item 4.

§6 additions:
- Implementation rules table: 50-pin cap, z-order above cluster +
  sample-mode, hollow ring styling on source palette, hover/click
  behaviors mirror existing patterns, fit-to-bounds only when result
  extent < 30° × 30° (otherwise fly-to-top-1 to avoid disorienting
  zoom-out on globally distributed result sets).
- Result-set shape acceptance table: zero, one, local-many, global-many
  must each be visually verified.

§9 reconciliation:
- isamplesorg#163 item 4 framing updated from "side-panel-copy fix" to "resolved
  by option C with the four shape cases verified."

Refs isamplesorg#163, isamplesorg#165, PR isamplesorg#166.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdhyee
Copy link
Copy Markdown
Contributor Author

rdhyee commented May 8, 2026

Round-2 fixes (commit `9d35a30`)

Codex round-2 review on #165 flagged two things in this PR:

  1. Option C UX was under-specified. Pin count cap, z-order, styling, fit-to-bounds policy, lifecycle were all left to implementation interpretation. Now locked: 50-pin cap, hollow ring above cluster + sample-mode, fit-to-bounds only when result extent < 30° × 30° (otherwise fly-to-top-1 — avoids the disorienting zoom-out on globally distributed result sets like `basalt`). Lifecycle tied to `?search=` non-empty.
  2. §9 still pointed at the superseded framing. `Interactive Explorer rethink: architecture review + UX/feature backlog #163 item 4` was described as a "side-panel-copy fix" — that was the option-B framing, not option-C. Reconciled to "resolved by option C with the four result-set shape cases verified."

Also added a result-set shape acceptance table in §6 — implementation must visually verify zero, one, local-many (regional cluster), and global-many (multi-continent spread) before this counts as done.

Diff: +30/-7 on top of the existing PR.

rdhyee and others added 4 commits May 8, 2026 07:36
State-contract doc for explorer.qmd: enumerates every URL query param,
hash param, DOM-as-state element, viewer.* / window.* widget field, and
OJS cell with deps + side effects. Records the search-semantics decision
(option B, side-panel lookup) and restates the facet-count contract from
isamplesorg#158. Doc-only; no code changes.

Refs isamplesorg#163, isamplesorg#158, PR isamplesorg#162.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…amplesorg#165 review

Codex review of isamplesorg#165 surfaced a third option that supersedes the prior
A/B framing: side-panel lookup with a temporary point-overlay of matching
samples on the globe. Backend contract is unchanged from option B —
cluster layer and facet counts remain unaffected — but the UI surface
gains a visual answer to "where did my search land geographically."

Resolves isamplesorg#163 item 4 (zero results + populated map UX wart) cleanly:
zero results render zero pins; non-zero results render distinguishable
result pins layered above the cluster layer.

Adds a small state-inventory addendum: viewer.searchResultPoints (new
Cesium primitive collection), and an optional viewer._searchResults
cache. URL/hash params and DOM-as-state are unchanged.

Refs isamplesorg#163, isamplesorg#165, PR isamplesorg#166.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iew)

Codex round-2 review on isamplesorg#165 flagged that option C's UX was
under-specified and §9 still pointed at the superseded "side-panel-copy
fix" framing for isamplesorg#163 item 4.

§6 additions:
- Implementation rules table: 50-pin cap, z-order above cluster +
  sample-mode, hollow ring styling on source palette, hover/click
  behaviors mirror existing patterns, fit-to-bounds only when result
  extent < 30° × 30° (otherwise fly-to-top-1 to avoid disorienting
  zoom-out on globally distributed result sets).
- Result-set shape acceptance table: zero, one, local-many, global-many
  must each be visually verified.

§9 reconciliation:
- isamplesorg#163 item 4 framing updated from "side-panel-copy fix" to "resolved
  by option C with the four shape cases verified."

Refs isamplesorg#163, isamplesorg#165, PR isamplesorg#166.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex round-3 wording nit: "Never render more, never render fewer than
the result set size" was ambiguous since the full match set may exceed
50. Reword as "Pin count equals min(50, total_matches)" — the displayed
result set is what gets pinned, not the full match set.

Refs isamplesorg#165, PR isamplesorg#166.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rdhyee rdhyee force-pushed the explorer-state-contract branch from 9d35a30 to 062863d Compare May 8, 2026 14:36
@rdhyee
Copy link
Copy Markdown
Contributor Author

rdhyee commented May 8, 2026

Round-3 cleanup applied

Three small fixes per Codex round-3 review on #165:

  1. Rebased to drop the unrelated provenance commit. PR was carrying `94e7674` (scancode-2026-05-04.json, ~20k lines) — same scope-creep that hit PR explorer: search perf-smoke baseline (#167) #173 earlier. PR is now 3 commits, single file (`EXPLORER_STATE.md`), +351/-0.
  2. PR body refreshed to describe option C (was stale on option B).
  3. Pin-count wording nit in §6 implementation table (commit `062863d`): "never render more, never render fewer than the result set size" → "Pin count equals `min(50, total_matches)`" — disambiguates "result set size" from "full match set."

@rdhyee
Copy link
Copy Markdown
Contributor Author

rdhyee commented May 8, 2026

Review result: no blocking issues found. The state-contract doc is internally consistent with the option-C decision, and it keeps the UI-surface contract orthogonal to the search substrate work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explorer state contract: URL/DOM/widget-state inventory + search-as-global-filter decision

1 participant