# Public reading experience and research workspace

**Live:** [Universal Law](https://d6g8k5htny-coder.github.io/main/site/).

The public home introduces the mathematics before its implementation. All pages share Home, Explore, Research, Library and Mathematics navigation. Contribution options remain available from every page's footer site map, from Home's About section, and from the workspace's Join the work section.

- **Home (`index.html`):** a short introduction to random landscapes, thresholds and persistence; the separate current-source panel loads a hash-verified local public source observation.
- **Explore (`explore.html`):** three deterministic teaching models—negative-definite curvature, cubic gap scaling and a finite capacity example. Controls work locally with no remote data service. These illustrate their defined examples and do not certify a continuum result.
- **Research (`research.html`):** dated public reading cuts, newest first (Home and the Research hero link the newest), followed by the established question-to-proof paths. Pinned source citations, scoped formal packets and issue-only proofs retain distinct scope; separately labeled mutable upstream links reach newer work.
- **Library and workspace (`workspace.html`):** the existing exact coefficient viewer, dated status snapshot, hash-verified source inventory and contributor instructions. Old `index.html#board`, `#coefficient`, `#inventory` and `#contribute` bookmarks route here; without JavaScript the home still offers the workspace link.
- **Reproduce (`reproduce.html`):** a single pinned coefficient replay, prerequisites, actual expected output and the boundary of the check.
- **Cite (`cite.html`):** object-specific citation guidance and a local immutable-reference builder. It checks input syntax, not source existence or scientific status.
- **Source records (`museum.html`):** the preserved historical source-bound exhibits, review cards and conditional routes. It names its separate snapshot; later proof-index results are not silently imported into old cards.
- **Formal (`formal.html`):** what the original 27 September 2026 Lean lane's 13 scalar companions establish and what stays outside them; an explanation at that source snapshot, not a current formalization inventory or live acceptance register. Its dated "Since this snapshot" section points to later formal packages.
- **Mathematics (`dependencies.html`):** current equation excerpts, a progressively expanded graph, Graph/List views, a loaded-neighborhood minimap, five separate evidence metadata axes, exact sources and static node pages with a "Resume this node" block, followed by the preserved dated dependency snapshot. It does not update scientific classifications or replace the proof index.
- **Measure (`measure.html`):** a synthetic counts-to-density teaching example with invented inputs; it generates no random field and validates no theorem.

The front and technical layers use the same existing evidence. No second scientific register or server backend is added. Source identities are available in expandable disclosures, while object/class labels and unavailable states remain visible. The original coefficient artifact’s `scientific_acceptance: false` is retained; later scoped review remains separate.

## Current source publication

The sticky Research tools strip's **Go to** disclosure keeps Research, current-source search, the reading
list, Mathematics, Compare and citation/reproduction tools reachable during long
reading sessions. Its ordinary links work without JavaScript; Formal remains
script-free. Other current pages add Escape/outside dismissal without trapping
focus. It is navigation, not a proof search or an activity indicator. Print hides
the control. Focused checks: `node --test tests/test_reader_jump.mjs` and
`python3 -B tools/reader_jump_browser_check.py --output browser-evidence/reader-jump`.

`tools/current_site_data.py` resolves public main and Math- commits once, verifies their complete Git trees and the seven acquired source files, and extracts exact indented proof displays. Other inventory rows bind paths and Git blobs; their document bytes are not downloaded. The page calls equation blocks excerpts and keeps their surrounding proof scope available by pinned line links. `tools/current_site_build.py` renders one payload offline into marked current sections and static node pages. Formal remains script-free. Research preserves its dated reading cuts and their source pins, with a separately identified current observation. Generated Research pages use the existing `current.mjs` module to verify the advertised local `current.json` observation and progressively update its clock-derived freshness label (`current`, `stale` or `clock disagreement`); the same observation becomes stale after two hours. The module checks freshness each minute and on page/visibility events; it does not poll for a new observation or refresh editorial reading cuts. Generated current navigation, the observation timestamp and source pins remain readable without JavaScript. Current observations and original dated reading cuts have separate identities.

"Resume this node" appears in the atlas inspector and on each current static node page. Both come from `resumeProjection` in `current-model.mjs`; `tools/current_site_history.py` keeps a Python copy, and `tests/test_current_site_resume.mjs` checks that the two agree on every node. The block names the snapshot's graph commit, path, SHA-256 and observation time, and warns readers to refresh from the live record before any ownership- or head-dependent action. Recorded `review_*` fields are labelled as review records, not as the current task, an owner or completion. Next action, missing input, owner evidence and retained stop read "not recorded in this snapshot" on the snapshot-only projection, because the graph records none of them. The atlas inspector also passes `node-status.json`, the published copy of `records/node_status`, into that same projection. Static node pages stay on the snapshot-only call. An owner object is shown only when `evidence_url` matches the shared comment pattern; `released_url`, when present, stays on that object and the atlas says released. The panel shows the recorded status and `observed_at`, and says stale when `observed_at` is more than 24 hours before the render clock. Status is freshness of that view, not scientific validity, and `scientific_effect` stays NONE. A bare `review_issue` number names no repository, so it is not linked. Continuation links come only from the small site-maintained `RESUME_TASK_RECORDS` table of explicitly identified operational pointers; they are not graph metadata, scientific acceptance or source-binding admission. Archived snapshot pages are unchanged.

The configured `.github/workflows/current-site.yml` builds on main pushes and a 30-minute schedule and deploys the complete tested docs artifact through Pages Actions. Each candidate needs its own hosted success and deployed-source acceptance. A failed source refresh cannot reach deployment. Source observations are not mathematical revalidation. Existing diagrams on Explore keep their defined teaching scope; the new source panel links the advancing work.


Observed production on 17 October 2026: [run 39076035717, attempt 1](https://github.com/d6g8k5htny-coder/main/actions/runs/39076035717) successfully built and deployed Main `df590a438f1252309270ca625c6fe8531ddadc3b`. The [dated #410 verification record](https://github.com/d6g8k5htny-coder/main/pull/410#issuecomment-6242575372) binds the observed receipt to exact public manifest, metadata and payload bytes, with public browser readback at 22:45:59–22:46:08 UTC. This establishes that observed publication only; later #415, #425 and atlas candidates need their own hosted and deployed-source acceptance. Source observations and deployment are not scientific revalidation.

Local current-view controls: `python3 -B -S -m unittest tests.test_current_site_data tests.test_current_site_build`; `node --test tests/test_current_site.mjs`; and, with the pinned browser packages and packaged Chrome, `python3 -B tools/current_site_browser_check.py --output browser-evidence/current-atlas`.

## Selected-claim reading

The Atlas inspector leads with the selected record's literal scope (or a separately labelled note), immutable source reference and explicit formal-evidence gap. Source identity, formal declaration/execution/alignment fields, review/continuation records and complete metadata remain available in native disclosures. Disclosure state survives layout changes for the same admitted claim and resets for a changed or refused claim. There are no claim titles in the current graph; identifiers are retained rather than replaced with invented titles. This presentation creates no formal binding or scientific acceptance.

An additional focused browser check is `python3 -B tools/atlas_claim_summary_browser_check.py --output browser-evidence/atlas-claim-summary` (packaged Chromium at `/usr/bin/chromium`, or `--browser PATH`). `--observe` records baseline failures without claiming acceptance. Real Orca speech evidence is version- and source-specific; DOM/AX checks alone do not certify spoken output.

The selected claim's **Depends on** and **Used by** cards retain every recorded edge. Required/context labels stay visible; **Recorded relationship** discloses the literal type, dependent → dependency direction and existing downstream counts. Keyboard selection brings an offscreen desktop heading into view while retaining the existing mobile reading route. `node --test tests/test_atlas_relationships.mjs` checks directed/parallel edges and unknown IDs; `python3 -B tools/atlas_relationships_browser_check.py --site docs/site --output browser-evidence/atlas-relationships` checks real keyboard/disclosure/history/visibility and narrow layouts against one admitted observation. `--observe` retains baseline failures; `--base-url URL` replays the same checks on the public origin after source identity verification. No new source mapping, status authority, dependency or spoken-AT qualification is introduced.

## Verify the reader experience

Compare has synchronized page controls before and after its results. It verifies
its comparison metadata, registry and selected bytes immediately. Its separate
source inventory stays pinned and unverified until Sources and scope is opened
or a source deep link requests it, then uses the existing unchanged verifier.
This avoids a redundant initial current-payload transfer; it does not share or
weaken admission. Source-tool loading failures keep an explicit reload retry and
all static source links. Focused checks: `node --test tests/test_compare_source_panel.mjs`
and `python3 -B tools/compare_experience_browser_check.py --output
browser-evidence/compare-experience`; the existing snapshot comparison checks retain
their byte/registry/refusal coverage after explicitly opening that separate panel.

Persistent source-status reading: `python3 -B -S -m unittest tests.test_current_site_persistent_status` checks current paragraph semantics, exact previous live-page restoration, frozen historical renderer identities and refusal of altered source text or pins. `python3 -B tools/persistent_status_browser_check.py --site docs/site --output browser-evidence/persistent-status` exercises desktop/phone themes, source disclosures, static/no-JavaScript reading and verification failure. Use an admitted matching HTML/payload/meta observation; `--observe` records baseline failures. Actual speech and its platform limits are reported separately in `docs/reports/atlas-persistent-status-20261026`; these browser checks do not certify speech or full accessibility. No production dependency was added.

Live Atlas control repair: `python3 -B tools/atlas_live_controls_browser_check.py --site docs/site --output browser-evidence/atlas-live-controls` exercises stable excerpt options, final-count announcements, keyboard View choice, exact source selection, reload/history and refused bookmarks at desktop/phone widths in both themes. Use an admitted matching HTML/payload/meta observation; `--observe` retains baseline failures. The report in `docs/reports/atlas-live-controls-20261026` distinguishes actual version-specific Orca speech from DOM checks and from the remaining Orca46.1 qualification. No production dependency was added.

```sh
# Stage any new or deleted file under docs/site or docs/public-math first (git add <path> / git rm <path>).
python3 -B tools/site_asset_release.py          # run after ANY change under docs/site or docs/public-math; re-keys ?site-release= URLs of changed assets and their importers
python3 -B tools/site_asset_release.py --check  # must print the token and exit 0; commit every rewritten file
python3 -B -m unittest discover -s tests -p test_public_shop_data.py
python3 -B -m unittest tests.test_site_asset_release
node --test tests/test_public_shop_frontend.mjs tests/test_explore_models.mjs tests/test_curvature_export.mjs tests/test_teaching_export.mjs tests/test_pin_export.mjs tests/test_palette_export.mjs tests/test_figure_png.mjs tests/test_reading_list_citation.mjs tests/test_reader_navigation.mjs tests/test_source_reference.mjs tests/test_measurement_model.mjs tests/test_dependency_viewer.mjs tests/test_museum_frontend.mjs tests/test_workspace_navigation.mjs
python3 -B -S -m unittest discover -s tests -p test_reader_links.py -v
python3 -B -m unittest discover -s tests -p test_museum_data.py && python3 -B tools/museum_check.py && node --test tests/test_museum_geometry.mjs
python3 -B -E -S tests/test_public_shop_check_identity_control.py -v
python3 -B -E -O -S tests/test_public_shop_check_identity_control.py -v
python3 -B tools/public_shop_check.py
```

These are the local steps of the required `public-shop` job, including both W8b public source identity controls. In the node list, two museum tests report SKIP without `MUSEUM_FIXTURE`; `tools/museum_check.py` reruns them with that fixture. The Run locally and museum blocks below are subsets of this list.

On macOS, a symlink alias in the process temporary directory can make the site-asset fixtures compare a lexical temporary path with the canonical path returned by the release inventory. That portability defect is owned in [#294](https://github.com/d6g8k5htny-coder/main/issues/294) and is not repaired here. The example below is a trusted local invocation setup only: it uses the caller's existing writable temporary directory, resolves that directory to its physical path, rejects the checkout and its descendants, and exports `TMPDIR` before starting a new Python process. It creates nothing, hard-codes no workstation path, and is not a production-path or fixture change.

```sh
(
  checkout_dir="$(pwd -P)" || exit 1
  trusted_tmpdir="$(CDPATH= cd -P "${TMPDIR:?Set TMPDIR to an existing trusted temporary directory}" && pwd -P)" || exit 1
  case "$trusted_tmpdir/" in "$checkout_dir/"*)
      printf '%s\n' 'Choose an existing temporary directory outside this checkout.' >&2
      exit 1
      ;;
  esac
  test -w "$trusted_tmpdir" || exit 1
  export TMPDIR="$trusted_tmpdir"
  python3 -B -m unittest tests.test_site_asset_release
)
```

Check real desktop/mobile layouts, keyboard operation, light/dark appearance and source-unavailable behavior separately. The pure-model tests are not browser or scientific verification.


## Captioned PNG teaching figures

Explore offers PNG alongside each existing SVG download. PNG rasterizes that
same validated, captioned SVG at fixed2× dimensions and embeds its original
structured metadata and readable citation in international-text chunks. Local
fonts can differ; source acquisition and mathematical verification are not
performed. Changed controls, geometry or theme cancel/refuse pending output;
errors explain retry and preserve SVG/manual citation. Unsupported browsers and
no-JavaScript views retain their existing alternatives.

Focused checks: `node --test tests/test_figure_png.mjs` and
`python3 -B tools/figure_png_browser_check.py --browser PATH --output
browser-evidence/figure-png` (optional pinned browser packages plus Pillow).
The exported PNG metadata can be inspected with a standard PNG text-chunk reader;
its visible caption travels with the image even when an app strips metadata.

## From a saved source to a reference

The Library's verified current-source search offers **Clear search**, a native
**Link to this search**, and **Save current search** together. A zero-match query
shows recovery guidance. Clearing resets the existing result window and returns
keyboard focus to the input. The link preserves literal query text and unrelated
page parameters; it runs against the admitted observation available when opened,
so its results are not frozen. The dated catalog remains a separate collection.
These tools appear only after the current snapshot verifies and add no source
acquisition, mathematical review or storage schema.

**Show more files** retains the current source rows, open acquisition identities
and source-save controls while appending the next 50 matches. Keyboard activation
focuses the first newly revealed source, including the final partial batch;
programmatic loading does not steal focus from another control. Changing or
restoring a query resets the result window. Focused regression:
`python3 -B tools/source_list_continuity_browser_check.py --output
browser-evidence/source-list-continuity`. This uses the real included admitted
observation, or `--origin URL` for a separately recorded served observation;
browser DOM checks do not establish source authentication or spoken accessibility.

Focused checks: `node --test tests/test_library_source_search.mjs` and
`python3 -B tools/library_source_search_browser_check.py --output
browser-evidence/library-source-search` (optional installed Playwright/Chromium;
use `--browser PATH` if needed). The browser driver blocks external HTTPS requests
and tests the included current snapshot; no online source custody is inferred.

Each saved source in the Library reading list has **Make a source reference**.
It opens the existing Cite builder with its repository, full commit, literal path
and actual SHA-256 when present. A Git blob is not substituted for a file hash.
The builder checks syntax only; no authorship, source acquisition, review or
mathematical acceptance is inferred. An unsupported literal path keeps its
original source and list actions with an explicit unavailable note. Saved
searches are not source citations. Back returns to the same browser-local list.

Focused checks: `node --test tests/test_reading_list_citation.mjs` and
`python3 -B tools/reading_list_citation_browser_check.py --browser PATH --output
browser-evidence/reading-list-citation` (optional pinned browser packages).

## Current-first Library discovery

Home's Library card opens the current collection. After that observation verifies,
the existing search moves ahead of its provenance disclosure. **File paths** keeps
the original repository/path matching, append50 results, source identities, saving
and citation behavior. **Acquired text** searches only the included excerpts and
source paths, appends ten previews at a time and links exact source lines. It does
not fetch complete documents or infer mathematical or graph connections. The
dated catalog and all source/status disclosures remain available.

The collection is presentation state in `library-collection=text`; existing
`source-q` bookmarks and saved file searches keep their meaning. Excerpt searches
have share links; they are not silently stored as file searches. A failed source
admission installs no new search. No-script users retain the static inventory.

Focused checks: `node --test tests/test_library_discovery.mjs` and
`python3 -B tools/library_discovery_browser_check.py --output
browser-evidence/library-discovery`. `--site PATH` selects one already admitted
local site, while `--origin URL` replays an independently identified publication.
The driver records actual geometry, literal text, file/text paging, keyboard and
source-link behavior; these are engineering checks, not mathematical acceptance
or a spoken-AT/full-WCAG certificate.

## Reading without losing your place

Research adds small question/map/source links to each of its seven dated readings
when JavaScript is available. These are native fragment links: keyboard focus,
Back/Forward and reload retain the existing reader-shell behavior. Each reading
also ends with a return to the question chooser. The source HTML, exact pins and
historical wording stay unchanged; a missing expected source disclosure omits
that reading’s enhancement. Without JavaScript the original open reading map and
archive remain available. Print hides the added navigation.

Focused browser check (Chrome with sandbox and the optional pinned Playwright
packages): `python3 -B tools/research_reading_browser_check.py --browser PATH
--output browser-evidence/research-reading`. This exercises navigation and
refusals; it does not certify scientific content or spoken screen-reader output.

## Latest public work is a reading cut

`research.html#latest-work` is static editorial navigation checked at its displayed
UTC time, except its closing **Check newer work** route list (`#newer-work`), which
carries its own "as read" date. It links the landed soft-model chain at Math `07320089`, the separately
landed cap formalization at `0fda855b`, exact public C81–C84 issue-comment proofs and
reviews (model and source-bound actual/contact scopes kept distinct), the finite numerical work at main `1e1c9a1c`, and the existing catalog and
query sources. The named boundaries are part of each reading path. This is a
curated selection plus full upstream navigation, not a complete artifact catalog,
scientific-status register or automatic synchronization service.

The 18:00 UTC refresh ([PR248](https://github.com/d6g8k5htny-coder/main/pull/248))
added the conditional actual-bar cards `#actual-bars` and `#strict-bar-coefficient`
to this cut. Later dated cuts were added above it: `#reading-addendum` (3 October 2026,
20:01 UTC), `#pair-endpoint-rate` (4 October, 00:18 UTC), `#shrinking-bin-sampling`
(4 October, 06:20 UTC, [PR266](https://github.com/d6g8k5htny-coder/main/pull/266)),
`#reading-cut-20261007` (7 October, 18:37 UTC), `#reading-cut-20261009` (9 October, 00:05 UTC; the landed finite Gaussian H0 lifetime source and its program, read at main `0be54aa2`) and `#reading-cut-20261010` (10 October, 20:24 UTC; main #329's regular-fold structural theorem, exact periodized Gaussian H0 adapter and marked short-bar process theorem, read at main `6e11abfb`). Home, the Research hero and the Library
link the newest cut. `#latest-work` keeps its 18:00 UTC heading, wording and pins; its
later additions are a forward pointer to the 20:01 addendum and two labeled
reviewer-lineage notes beside its 3 October review links, which the 7 October cut
discloses, and the maintained contents of its closing `#newer-work` route list
(below), which is navigation, not cut text. Two further labeled source-identity notes close the 20:01 and 00:18 cuts
with the SHA-256 identities their pinned links lacked, and one dated
`<p class="cut-pointer">` inside the 7 October cap card records that Math #193 was
reopened eight minutes after that cut. The 9 October 2026 cut (`#reading-cut-20261009`) restates all five in its source disclosure, so none
is the only record.

Exact-commit citations preserve the reading cut. The **Check newer work** section
(`#newer-work`) intentionally follows mutable upstream branches and discussions. It is
maintained navigation, not cut text: it carries an "as read" date, and when the
coordination board or task queue moves, its routes and the matching Join-the-work card
in `workspace.html` are updated in place without re-pinning any cut
(`NewerWorkRoutes` in `tests/test_reader_links.py` checks them). Comment links
identify the public record but comments remain editable; their reviews record the
reviewed identity. A missing source is unavailable evidence. No browser fetch or
execution of those sources is claimed. The Library, status and museum snapshots
retain all their original pins and are not refreshed by this section.

The existing four light/dark desktop/mobile source-card browser cases now also
exercise the Home → Latest public work route, native keyboard fragment focus,
repeated source-identity disclosure, Back/Forward navigation, no document overflow
and the static route with remote source requests refused. Each case retains a
latest-entry screenshot. Actual source identity readback is a separate engineering
check, not something established by a screenshot or link.

### Adding a dated reading cut

Insert the new `<section id="…" class="latest-work" tabindex="-1" aria-labelledby="…">` with its own `<time datetime="…Z">` immediately before the current newest cut. Never edit an earlier cut's text; the closing **Check newer work** route list (`#newer-work`) is maintained navigation with its own as-read date. In the same change:

1. Point Home's "Read the latest public work →", Research's hero "Latest public work" and the Library's latest-work links at the new id. Give the new cut one uniquely named link to the cut below it; exact link names must stay unique. Update the `<time datetime>` and visible date beside the Home and Library entry links to the new cut’s timestamp (`tests/test_reader_links.py` pins them). The Home About link line links Source records, Dependencies and Formal, and its disclosure links Measure; keep ‘dated’/‘synthetic’ in those labels. In the Research hero, add one row for the new cut at the top of the “Dated reading cuts” list (its question heading and the `<summary>` text of its source disclosure) and update the “Newest reading cut” `<time>`; if the cut introduces a status token not listed under `#status-words`, add a quoted-provenance row for it (where it is quoted from, never a definition).
2. In `tests/test_reader_links.py`, update the entry fragments, add the cut's pins to `EXPECTED_READING_URLS` and `EXPECTED_HASH_BINDINGS` (the parser joins the text of all `<code>` elements in an `<li>` into one string and binds that string to each pinned link in that `<li>`, so keep an item's `<code>` text equal to its intended digest), update the pinned-link total and the `p.latest-boundary` count, and add a byte-identity pin for the cut that is no longer newest. Five digests pin the page below the newest cut: the 9 October cut whole; the 7 October cut whole (cut-pointer included); `#shrinking-bin-sampling` whole; the cuts digest from `#pair-endpoint-rate` up to `#lifetimes`, with lineage notes and the contents of the `#newer-work` aside stripped (its opening tag and its place as the last child of `#latest-work` stay pinned); and the paths digest from `#lifetimes` up to `#further-reading`. A cut that stops being newest gets its own byte-identity pin, as the 06:20 cut has. Outside the pins stay the contents of `#newer-work` (maintained routes, checked by `NewerWorkRoutes` in `tests/test_reader_links.py`), the Further-reading section and the footer.
3. In `tools/public_shop_browser_check.py`, update `check_latest_work_flow` and `check_reading_addendum_flow`: entry focus, datetime, card and pinned-link counts.
4. Keep dated reading-cut bodies static, their IDs unique and every local fragment resolvable. Preserve the generator’s existing `current.mjs` progressive enhancement for current-observation freshness; it does not update the reading cuts or their source pins.
5. Append the new cut, with its date and UTC time, to the list of later dated cuts earlier in this section, so this guide does not stop at an older cut.
6. Rerun the release tool and the public-shop steps above.

Rules for future cards, not a retrofit of pinned cuts: each card carries one visible primary pinned proof link on its face, with digests, reviews and manifests in the disclosure, and the test’s EXPECTED lists enumerate card-face and disclosure links separately. Each card ends with a `<dl class="card-status">` of up to three rows — “Landed?” (landed at Math or main `<commit>` / open proposal, quoting the PR state at the cut), “Read by” (provider · verdict token quoted from the linked review · scope) and “Scientific effect” (quoting the source’s own declaration) — reusing the 7 October labels “Who read it:” / “Still candidates:” / “Still informal:” verbatim where they apply. A display equation inside a future card is authored as `<p class="display-formula"><code>…</code></p>`, which `home.css` renders as a block; kickers and eyebrows are uppercased by CSS, so a future cut may author them in sentence case. Pinned cuts are not retrofitted.

## Keep or share a Library search

The Library offers **Undo removal** after Remove or Clear reading list. It
restores only the latest entries removed in this page, adding them to the
current saved list so other tabs' additions survive. Source-metadata conflicts,
the 50-item ceiling and the 128 KiB limit refuse restoration without consuming
Undo. Resolve the conflict or free space in another tab before retrying: a new
Remove or Clear on this page replaces its previous recovery. Recovery is kept in
this page only and is lost on reload. Export remains the way to keep a separate
copy. No source is acquired or mathematically reviewed by restoring a note.

```bash
python3 -B tools/research_desk_undo_browser_check.py --output reading-undo-evidence
```

Saved reading-list rows keep their focused source/reference control and open
**Saved identity** disclosure when another tab updates the list. Validated
metadata changes refresh the displayed identity and reference. If the focused
item is removed, focus returns to the reading-list summary; a local Remove
button uses the neighboring Remove button when one remains. No new data is saved
automatically. These browser checks exercise that continuity and its tab-only,
queued-write and outside-focus controls:

```bash
python3 -B tools/research_desk_continuity_browser_check.py --output reading-continuity-evidence
```

The Library's search, repository and path filters are saved in the current URL
without adding a browser-history entry for every keystroke. Refreshing or
returning with Back/Forward restores the filters. **Link to this search** gives a
bookmarkable link directly to the catalog; **Clear filters** restores its initial
50-row view. Filtering never changes source identities or recorded review scope.

Search links use `q`, `repository` (`main` or `Math-`) and `path`. Empty values are
omitted; the first repeated value is used, and an unknown repository is treated
as all repositories. Unrelated parameters and section bookmarks are preserved in
the current address but omitted from the explicit search link. Filters are visible
in URLs and browser history. Links use the catalog’s pinned source records, not a
live proof index; the search URL does not freeze future catalog updates. If history updates are unavailable, filtering and the explicit
link still work; if source verification fails, controls stay unavailable.

The Library's static text names its bytes. `#status-rendered-from` states the SHA-256 and byte count of `status.json` and of the `STATUS.md` snapshot that `config.json` pins, and `#proof-link` carries the pinned proof URL that `app.js` also assigns; `tests/test_reader_links.py` pins both to `config.json` and to the payload bytes, so refreshing `status.json`, `config.json` or the SIDE24 pins means updating those sentences and the three `<noscript>` routes in the same change. A refused source prints `Unavailable: … No result inferred.` followed by a link to the pinned source on GitHub, built only from a pin whose repository, commit and path pass the displayed-identity guard that `core.verifiedBytes` applies to every pinned source (owner-fixed repository, 40-hex commit, no empty, `.` or `..` path segment, each segment URL-encoded).

## Browser evidence in CI

The existing `public-shop` workflow also runs a separate read-only `browser-smoke`
job. Its optional [pinned Playwright dependencies](../../tests/browser-requirements.txt)
use the [official Python package](https://pypi.org/project/playwright/1.62.0/)
with the Ubuntu 24.04 runner’s packaged stable Chrome and its enabled sandbox.
The browser version/executable hash and runner-image identity are recorded; the
browser is runner-bound rather than a fixed Playwright download. The runner serves
only `docs` on an ephemeral
loopback port. It does not publish a preview or use account credentials.

`browser-smoke` is not a required status check: as read on 7 October 2026, ruleset 23798639 requires only `verify`, `public-intake` and `public-shop`. Inspect its current-run report before integrating a site change.

The `public-shop-browser-<run-id>` artifact contains a JSON report and screenshots
for 1200×900 and 390×844 in light and dark mode, plus an explicitly refused
inventory request. It tests URL round-trips, actual Back/Forward navigation,
keyboard reset/focus and document overflow against the real app and pinned public
sources. Four additional source-card cases follow the Research reading path,
check exact review-comment links and retained qualifiers, and repeatedly open
and close the original-quote disclosure with the keyboard. They also capture
the Home, Explore, Cite, Reproduce and Formal entry viewports and check for
document overflow. The report binds the actual tested checkout separately from
the PR head. Two reader-tool cases follow the shared Research links at desktop
and narrow viewports, exercise the synthetic normalization/error boundary, and
verify the dependency viewer's pinned counts, review-source search, saved link,
invalid-link refusal and source-snapshot label.
Two rendered-layout cases read what Chromium drew rather than the stylesheets.
Focus rings are checked by painted pixels; everything else by computed styles
and laid-out boxes. On the museum page, `#museum-state` and
`#conditional-route-status` each keep one height at 1280 px from their first
text (verification held at the manifest request) to their last. At 1280, 390 and
320 px, in the light and the dark scheme, each conditional-route summary and
link, and the exhibit figure of each of the four views, is focused and
screenshotted, then blurred and screenshotted again: in the ring band, 4 to 7 px
outside the element (outside each line of a link that wraps), changed pixels
must run along at least 97% of every side and fill every outer corner (for a
target taller than the viewport, the viewport grows in height for these
screenshots). Its computed ring must also be solid 3px at a 4px offset, in a
colour with non-zero alpha and at least 3:1 against the background composited
behind it, with no ancestor whose overflow is not visible cutting the ring box.
No summary's ring box may cross any other text line in the card, above or below
it, and at 390 px an opened quote has no inline margin. The optional Three.js
request is refused, so every runner checks EC-014's 2D figure; the 3D canvas's
own ring is not checked. On Dependencies, five nodes with long ids, paths or
file names, at 320 and 390 px with and without a WCAG 1.4.12 text-spacing
override, keep the page within the viewport. No text line may be cut. Walking
outward from it, an ancestor that clips (overflow hidden or clip, paint
containment, content-visibility auto) must hold it inside its padding box, and
an ancestor's clip-path inset() inside that inset rectangle; any other clip-path
is reported as unmeasured. An overflow auto or scroll region makes its text
reachable on that axis, and from there the region's own scrollport must be held
by every ancestor further out and by the viewport. Every Lane and Record state
word stays on one line inside its cell, and the evidence table fits its scroll
region. Under the override the table may be wider only if that region scrolls to
its full width and a keyboard reader can use it: Tab reaches it from the
previous stop, its ring passes the same painted, contrast and clipping checks as
the others, arrow keys scroll it to the table's far edge and back, and Tab moves
on. WCAG 1.4.10 lets a data table's two-dimensional layout scroll; it does not
exempt the text of its cells or the content around it, and 1.4.12 still requires
no loss of content or function, so every other check here still applies to the
table. At 390 px with default spacing, on those nodes whose Source detail has no
unlinked JSON metadata, no ordinary Source detail word (not a JSON fragment,
path, id or hash, outside links and code) is split, except right after the
word's own hyphen or slash: where that break falls depends on the font. The
index stays within 320 px under the override. A failure names the element, the
side or the word.
A setup artifact without a successful report is not a completed browser run.

Inspect the screenshots before accepting visual quality. This is headless Chromium
with mobile-sized viewports, not physical touch-device, all-browser, full
accessibility or deployed-Pages certification. The original source validation and
required hosted checks remain separate and unchanged.

Without the runner's `/opt/google/chrome/chrome`, a local pre-check can install `tests/browser-requirements.txt` in a scratch environment. That installs only the Python packages: if the environment has no Chromium, download one with `python -m playwright install chromium`, which places it under Playwright's browser cache (`~/.cache/ms-playwright` on Linux, or `PLAYWRIGHT_BROWSERS_PATH` when that is set). In a disposable worktree, edit `tools/public_shop_browser_check.py` so that both its `executable` path and its launch use a local Playwright Chromium binary (`executable_path=…`, with `chromium_sandbox=False` only if the host requires it). Never commit that edit. Run it in that worktree with `python -B tools/public_shop_browser_check.py --output <dir>`; `--output` is required, and the directory receives `report.json` and the screenshots. Such a run is local evidence only: it is not the CI browser record and does not meet the contract's packaged-Chrome and sandbox conditions. Its `report.json` records `checked_commit` and `tree` from the checkout, which identify the base checkout, not the program that ran. To cite such a run, keep the unmodified report, the exact invocation, the modified harness bytes with their SHA-256 (or the original blob id with a replayable patch and the resulting SHA-256), and the executable and sandbox setting used; say that the harness was modified, and do not present the report as the tool's own output. A run without that retained material is an informal observation, not reproducible execution evidence.

## Run locally

From the repository root:

```sh
python3 -m http.server 8000 --directory docs
```

Open `http://localhost:8000/site/`. Internet access is required to read the immutable public GitHub inputs. If a hash or fetch fails, the affected view reports unavailable and infers no result.

```sh
python3 -B -m unittest discover -s tests -p test_public_shop_data.py
node --test tests/test_public_shop_frontend.mjs
python3 -B tools/public_shop_check.py
```

The interaction harness tests loading, searching, exact decimal selection and pinned query identity; it is not a visual browser test. Local-server preview was unavailable in the editing environment. The baseline live Pages site was checked in a real browser on 2026-09-26: all 2,138 original catalog records loaded and the exact SIDE24 source bytes verified. This baseline check does not validate a later museum deployment.

Reproduce the exports with `python3 -B tools/public_shop_data.py --check`. The exporter uses fixed source identities, refuses changed bytes or unfamiliar tables, and preserves verbatim cells. Updating the snapshot requires an explicit source-bound engineering PR; this viewer never decides a review disposition.

## Notebook

The [SIDE24 notebook](../notebooks/SIDE24_PUBLIC_COEFFICIENTS.ipynb) exposes the same immutable input and exact values, with an optional approximate chart. See [notebook instructions](../notebooks/README.md).

## Publication on main only

The configured [`.github/workflows/current-site.yml`](../../.github/workflows/current-site.yml) uploads the tested docs artifact with `actions/upload-pages-artifact` and deploys it with `actions/deploy-pages` (GitHub Pages source: GitHub Actions). The entry `docs/index.html` points to `site/`; `docs/.nojekyll` serves static files. GitHub Pages serves `docs/404.html` for any missing path under `/main/`: a static, script-free page with the brand header and the footer site map, linking `site/style.css` and `site/brand.css` by absolute path without a `?site-release=` key. The release tool keys each local asset URL separately: an asset's key hashes its key-stripped bytes and the keys of the assets it references (assets in a reference cycle share one key), so an edit re-keys only that asset and its importers, and a page-only or catalog-data edit changes no URL. It reads the `git ls-files` inventory of `docs/site` and `docs/public-math`, prints the whole-site identity over that inventory without writing it into URLs, and rewrites keys only inside the `.html`, `.css`, `.js` and `.mjs` files under `docs/site`; `docs/404.html`, like `docs/index.html`, lies outside that inventory, so neither page carries a key. The verified destination is [https://d6g8k5htny-coder.github.io/main/site/](https://d6g8k5htny-coder.github.io/main/site/). GitHub's branch publishing supports `/` or `/docs`, so `docs/site` is the app directory, not a selectable publishing root.

See the [deployment and review settings record](../PUBLIC_SHOP_SETUP.md). Pages, the public Project, the four profile pins, and the main/Math- branch rules have installation receipts. A public site does not establish branch protection or mathematical acceptance.

## Claim cards and exhibits

Open [the verification museum](museum.html). Its small `museum.json` display projection is reproduced by `tools/museum_data.py`; it is not a replacement for the 2,138-row public inventory. The generator preserves all eleven bullets in Math-'s “Reviewed scoped results”, the reconciled D1 row of STATUS's ACCEPT table, and the two remaining STATUS AMEND rows verbatim. An EXACT_COUNTEREXAMPLE retains that label; publication of a source does not make its claim accepted. Where a review is a GitHub comment, the displayed digest identifies the pinned index pointer, not mutable comment bytes.

The museum binds Math sources to `d6628da09384728992dcbe6e921cc28ba85aebb0` and main source/packet membership to `71400b94f6cb354a8cf7aba73ffede2138a64efa`. The existing board/inventory pin `a26f744be7597e3f0c0543c34ead23049bbac657` and SIDE24 import pin `9d7b6802424fb4715b31999066aafca8ee2f3cca` remain explicit historical identities. Neither changes the README's Math checkout or query checkout. No source fetch selects an AMEND branch.

Claims use claim/scope, source/review, and replay columns. Verified scope quotes have a small readable presentation for inline links, code and bold text. The complete original Markdown remains in **Exact source quote**. Relative links use the quoting index or STATUS file’s pinned repository and commit; quoted mutable links remain mutable. Only recognized research GitHub destinations become links, and unsupported syntax stays literal. These display links do not byte-verify their targets. Missing recorded replay commands are disclosed. The separate engineering strip and CI links do not attest to mathematical acceptance. D5's reviewed fixed-annulus region and its open pin-neighborhood/microdisk work remain separate objects.

- EC-014 illustrates the two-pin frame and six data coordinates. Camera motion is presentation, not a replay of its Jacobian argument. Imported self-labels are not adopted.
- D4/D5 diagrams show only their stated fixed regions, with OPEN complements. Diagram dimensions are schematic, not certified constants.
- P15 illustrates the source's stated finite realized-family example, with no unrestricted prize claim.
- D2 has a **fixture absent** card: no committed lifetime/barcode samples were found in the audited defaults. No synthetic proof data or live Gaussian sampler is supplied.
- The packet list contains two landed packages: the identity replay at main `71400b94f6cb354a8cf7aba73ffede2138a64efa` and the SIDE24 chart submitted for task #141 at main `a12c178c0f857a130cf434e9efd44233a038195b`. Each retains **REVIEW_REQUIRED**, scientific effect **NONE**, and **packet — not STATUS**. Unmerged PRs remain excluded.

```sh
python3 -B -m unittest discover -s tests -p test_museum_data.py
python3 -B tools/museum_check.py
node --test tests/test_museum_geometry.mjs
```

Existing intake enforcement remains `.github/workflows/public-intake.yml` and `tools/public_intake_check.py`: trusted `pull_request_target` code, no packet execution, incoming-only files, bounded identities, and a documented credential-pattern scan. The scan is not comprehensive. Task claims remain the human protocol in CONTRIBUTING; display inclusion never replaces review.

`museum_check.py` reads the pinned public bytes, checks regeneration, and exercises the actual committed manifest through the display code with the declared HTML containers. It also tests refusal of cross-claim proof, scope and replay substitutions. It is an integration harness, not a browser layout or GPU test. `museum_data.py --check` remains available for export-only reproduction.

The museum requests its mutable local `config.json` and `museum.json` with
`cache: 'no-store'`. Immutable remote source requests keep their existing caching
behavior. The manifest must still match the config's byte count and SHA-256 before
any cards render; a mixed deployment reports unavailable. This reduces browser
cache staleness, but is not an atomic deployment or a guarantee that an intermediary
cannot return an older coherent pair. A fresh browser read on 2026-09-26 verified
both landed packet cards after the earlier one-packet cached observation; that
observation and its correction are recorded on [main #154](https://github.com/d6g8k5htny-coder/main/issues/154).

The [implementation record](IMPLEMENTATION.md) maps W1–W12, coordination exclusions, and validation boundaries.

## Reproduce this source snapshot

The museum and exact lookup use these immutable checkouts. These commands
belong to the technical guide; the public home has no setup requirement.

```sh
git -C Math- checkout --detach d6628da09384728992dcbe6e921cc28ba85aebb0
git -C query- checkout --detach c88768bb11efd1f7d6bda188f13064bedec54a06
```

The source-identity gate checks these commands against `museum.json` and
`config.json`. Updating the reading interface does not update either source pin.

## One source-linked formal companion

The SIDE24 inspector can expose the existing closed arithmetic declaration
UniversalLaw.Side24.pairing_sum_six only when the complete claim record, proof
source blob/size/fingerprint and formal manifest identity match the pinned
evidence. This is a source-document connection, not coefficient or parent proof
coverage. Its actual package review is REJECTED (AMEND); the chosen row ALIGNED
does not override the existing all-31-target acceptance contract. Other claims,
changed sources and unrecognized manifest identities remain unmapped. The two
explicit current-source bridges described below connect only to the historical
artifact; they do not transfer its execution or alignment to a new manifest.
Original receipt/type/artifact bytes are retained under evidence/side24-main-3b39.
No Lean source, source admission, scientific status or renderer dependency changes.

Reproduce the historical offline data with python -B tools/atlas_formal_evidence_build.py
--root HISTORICAL_SOURCE_PROJECTION --snapshot EXACT_HISTORICAL_JSON (add --check
to compare). Its current-root manifest refusal is intentional. It reuses the existing
formal source and receipt/log validators; it makes no network call or new Lean
execution. The pinned original artifact is an input, not an authority for arbitrary
caller receipts. Execute the focused browser observer with --site GENERATED_SITE
--payload EXACT_CURRENT_JSON --output NEW_OUTPUT_DIRECTORY; the older committed
observation deliberately has a stale manifest and is not the positive fixture.
Run python -B -m unittest tests.test_atlas_formal_evidence_build, its -O equivalent,
and node --test tests/test_atlas_formal_evidence.mjs tests/test_current_site.mjs.
The browser observer records served-file identities separately from its own driver.

Current-source continuity is reproduced with
`python -B tools/atlas_formal_source_bridge.py --snapshot QUALIFIED_CURRENT_JSON --check`.
Manifest8228 has15identical formal files and two changed verification-control
hashes. Corrected manifesta22f has13identical formal files, two changed control
hashes, two documentation hashes and two other target annotations. Both full
manifest hashes are explicitly pinned; all Lean modules, dependencies, selected
declaration, scope and proof document must match the historical artifact.
The original3b39receipt, PENDING manifest alignment and REJECTED31-target review
retain their historical scope. The old two adverse endpoint findings are not a
verdict on the corrected current package. Unknown manifests still fail closed.
Existing derivation records cannot be overwritten by another observation.

The exact qualified public observation and reproduction instructions are in
`docs/reports/atlas-evidence-accessibility-20261026`; its compressed JSON is data,
not executable proof evidence. The small generated whitelist is a native module;
no production library or new status authority is added. The inspector's native
guide explains declarations, assumptions, kernel checking and alignment.

Focused checks: `python -B -m unittest tests.test_atlas_formal_source_bridge` and
its `-O` equivalent; `node --test tests/test_atlas_formal_source_bridge.mjs`;
`python -B tools/atlas_source_bridge_browser_check.py --site MATCHED_SITE --output NEW_DIRECTORY`;
and `python -B tools/atlas_accessibility_regression.py --site MATCHED_SITE --output NEW_DIRECTORY`.
The latter records actual footer hit targets/clicks, narrow themes, named regions,
headings, real3D relationship-list keyboard scrolling and source-fetch failure.
The separate pinned development-only axe audit documents scoped WCAG2.2AA
coverage and human/AT limitations. It is not a full conformance certificate.

### Reader Go to and visible focus

The native Go to disclosure on the eleven current reader pages shares the existing
Research tools strip. The strip stays at the top while scrolling, so its closed
launcher no longer covers source text in the lower corner. It remains available
while another field has focus. Scripted opening aligns the strip before showing
the bounded, scrollable menu; native links and script-free Formal retain ordinary
keyboard/page scrolling without JavaScript. Anchor clearance keeps destinations
below the strip. Repeating a same-page link opens collapsed disclosure ancestors
before native navigation, without writing history or redirecting focus. Modified,
download, new-tab and nonlocal actions keep their native behavior.

Compare's labelled Difference category selector reaches the existing record
categories directly. All categories remains the default; selecting a category
resets the twenty-row page view and announces its displayed count. Exact records,
edge multiplicity, source-pair links, acquisition and refusal rules are unchanged.
Empty categories remain explicit. New or refused comparisons clear the selector.

`python3 -B tools/website_navigation_browser_check.py --output NEW_DIRECTORY`
checks passive text visibility, repeated fragment activation and short-viewport
keyboard access. `--observe` retains failing baselines. Checkout hashes in that
driver describe local files only; public-code identity needs a separate byte proof.
Current automated qualification covers Chromium/Linux emulation, not every browser,
physical device, spoken assistive technology or full WCAG conformance.
