Skip to content

feat: canonical / Observatory Ledger reader (TIN-2903)#231

Draft
Jesssullivan wants to merge 16 commits into
mainfrom
jess/tin-2903-observatory-ledger-reader
Draft

feat: canonical / Observatory Ledger reader (TIN-2903)#231
Jesssullivan wants to merge 16 commits into
mainfrom
jess/tin-2903-observatory-ledger-reader

Conversation

@Jesssullivan

@Jesssullivan Jesssullivan commented Jul 15, 2026

Copy link
Copy Markdown
Owner

TIN-2903 — canonical / Observatory Ledger reader (draft, iterate in place)

Do not merge. Merging deploys to the production apex. Promotion remains separately gated by operator + Claude design QA, TIN-2891 data readiness, TIN-2801, reconciliation with current main, and an explicit promotion ruling.

Scope on the current head

The draft carries the reader design-of-record implementation plus the M1.3 interaction slice and M1.5a contract tests. The product and visual decisions remain operator/Claude-owned.

Mechanical follow-up on the current head:

  • b0ee3cd regenerates the Bazel-consumed pnpm-lock.yaml so direct @floating-ui/dom@1.8.0 is present in the rules_js graph
  • abe8a0e adds component/metadata contract coverage for SSR state, counterpart axes, and constellation node metadata

Private-shadow QA truth

The authoritative QA surface is the tailnet-only tss route, not a local server and not a Pages preview.

Deployment proof and current reachability are separate facts. The tss peer must be reachable during operator QA; a successful historical apply does not by itself prove present tailnet availability.

Validation state

Hosted build/lint/Lighthouse are green on exact head abe8a0e. The authoritative GF remote:check, remote:test, and remote:e2e run is https://github.com/Jesssullivan/jesssullivan.github.io/actions/runs/29602370480 and must finish genuinely green before another exact-head dispatch or any promotion discussion.

… 2026-07-15 design of record (TIN-2903)

Study recovered via transcript replay (sha256 84b299401d9c1daf…).
Design-of-record mock is subordinate to TIN-2903's fidelity contract.
…d, pulse cards) — TIN-2903

Harvested byte-for-byte from origin/feat/blog-tiered-reader-ui:
- src/lib/components/TierBadge.svelte
- src/lib/components/TierBadge.test.ts
- src/lib/stream/blend.ts
- src/lib/stream/blend.test.ts
- src/lib/components/pulse/PulseNoteCard.svelte (adds TierBadge integration)
- src/lib/components/pulse/PulseBirdCard.svelte (adds TierBadge integration)
- src/lib/components/pulse/PulseCards.test.ts (co-located tier-badge tests)
State A is the existing heron hero (verbatim identity, assets, alt, scroll-fade);
state B is a decorative aria-hidden constellation whose motion language (golden-angle
plumage stars, time-rings, tag lines, twinkle, goldfinch pulse comets, slow drift) is
carried from the recovered 2026-07-03 study's planetarium canvas. 14s dwell / 1.4s
crossfade; pause on hover/focus; explicit toggle + pause buttons (aria-pressed);
prefers-reduced-motion holds state A static and never starts the oscillation.
…nts (TIN-2903)

NoteworthySpread (register 01) + LedgerRegister (register 02, capped 8 + archive
link) compose the harvested TierBadge; PulseRail composes the #217 PulseNoteCard/
PulseBirdCard donors and renders every snapshot item in producer order (no silent
cap); ConstellationSection exposes buildConstellationGroups as native details/summary
disclosures with an honest category/tag label.
…-2903)

SSR-first, fail-soft loader (missing/invalid pulse snapshot -> empty rail; posts
from the build-time static index). The page partitions on explicit editorial_tier
only, so today's zero-tier data lands entirely in register 02 and the front page
stays calm rather than empty. /blog is untouched as the paginated archive.
…ha (TIN-2903)

Retire the Blog nav link (wordmark -> /), demote Signal Boosts and surface /aag +
/consultancy in a footer More group. Suppress the layout hero on / (the masthead
carries identity there) and keep glass-nav tracking scroll. Add a build-from-{sha}
footer line rendered only when a real PUBLIC_BUILD_SHA/GITHUB_SHA is present (wired
via a Vite define), plus a TODO(TIN-2903) for the unrecorded heron asset provenance.
Existing footer lines kept verbatim; mobile drawer theme/mode pickers untouched.
…thead control labels (TIN-2903)

BlogCard wiring lifted verbatim from feat/blog-tiered-reader-ui (the harvested TierBadge test exercises it); aria-labels added to the masthead toggle/pause buttons flagged by the build a11y pass.
…d animation (TIN-2903 M1.1+M1.2)

- crossfade the constellation in at hydration instead of after a 14s dwell;
  the heron hero remains the SSR/no-JS and reduced-motion state
- raise the masthead band from 280px to clamp(360px, 48vh, 640px) and make
  the heron layer cover it; star field now fills an ellipse matched to the
  band's own aspect instead of the y*0.5 squish against one radius
- spend animation frames only while the constellation can be seen: the rAF
  loop pauses when the heron state is showing, the masthead leaves the
  viewport (IntersectionObserver), or the tab is hidden

Interaction (hover/zoom/labels) is NOT in this slice — that is M1.3+ per
the ratified program charter. svelte-check 0 errors, vitest 29/29, build green.
…ntract (TIN-2903)

homepage.spec.ts still asserted the retired meta-refresh redirect ('/ ->
/blog' + canonical -> /blog); visual-qa.spec.ts still expected the retired
Blog nav link. Rewritten to the ratified contract: '/' serves the reader
directly (observatory masthead visible, canonical = apex root), /blog
remains the archive, and the desktop nav asserts a surviving primary link
plus the Blog link's absence. Full local run: 158 passed, 0 failed
(chromium/firefox/webkit).
…641 option a)

The checked-in pulse snapshot ages between deploys (frozen at 3 items
since PR #111 while the live broker carries 6). Apply /pulse's existing
onMount broker-hydration pattern at the reader home: live snapshot items
when the broker answers within 10s, the static build-time items
otherwise, failure silent (stale-not-broken fail-soft). Masthead comets,
constellation groups, and the rail all consume the hydrated items.
svelte-check 0 errors, vitest 44/44, build green.
…ine-readable dates (TIN-2903)

Adversarial semantic review findings, all branch-introduced:
- the reader home had no h1 (site identity was a p[role=banner]); the
  masthead title is now the document h1, and the illegal role=banner
  (nested inside main, duplicating the AppBar's header landmark) is gone
- dates render in <time datetime> elements throughout the reader; the
  ledger column shows full ISO dates — a month-day alone was ambiguous
  across a decade-spanning archive
@Jesssullivan
Jesssullivan force-pushed the jess/tin-2903-observatory-ledger-reader branch from 3b1d7ad to a2f35aa Compare July 17, 2026 03:26
@Jesssullivan
Jesssullivan temporarily deployed to blog-shadow-dispatch July 17, 2026 05:42 — with GitHub Actions Inactive
…gate, tier/time axes in the accessible counterpart (TIN-2903 M1.3)

Pointer interaction on the deterministic golden-angle canvas, per the
ratified M1.3 spec (07-03 study affordances, embeddings still deferred):
- hover: point-in-radius pick over the live Star[] (26px), DOM tooltip
  (tier/tag kicker, title, date or reading-time meta), hovered star
  brightens and drift freezes so the target holds still; idle surfaces
  redraw only on hover CHANGE
- click: navigates to the entry with a 200ms local-magnify flourish when
  motion runs; reduced-motion/paused navigate immediately with no motion;
  the pending navigation timer is tracked and cleared on unmount
- labels: noteworthy stars always labeled, hovered stars labeled brighter
  (with zero-tier live data every label is hover-only today — honest)
- ledger.ts: ConstellationNode gains optional tag/date/readingMinutes;
  postToConstellationNode exported so masthead + groups share one shape
- ConstellationSection: gains the tier + time axes the canvas encodes
  (closes the semantic-review counterpart gap); canvas stays aria-hidden
  with pointer affordances only, keyboard access via the section

Adversarially verified (ship-with-nits; both minors fixed at helm:
change-gated idle redraw, tracked flourish timer). svelte-check 0 errors,
vitest 133/133, build green.
….3 conformance)

The design-system audit (in-house reference sweep) ruled the house
pattern for canvas-point tooltips: Skeleton's Tooltip anatomy needs a
DOM trigger, which a canvas star is not, so the conformant path is
@floating-ui/dom computePosition against a virtual element at the
cursor — the same positioning engine Skeleton's own Tooltip uses via
@zag-js/popper. Replaces the raw left/top set (which clipped at the
band's edges) with offset/flip/shift middleware, and declares
@floating-ui/dom as a direct dependency instead of leaning on the
transitive copy. svelte-check 0 errors, vitest 133/133, build green.
@Jesssullivan
Jesssullivan deployed to blog-shadow-dispatch July 17, 2026 14:54 — with GitHub Actions Active
…TIN-2903 M1.5a)

House-harness (svelte/server render, node env) tests for the previously
untested reader surfaces:
- ObservatoryMasthead SSR truths: heron is the no-JS state (constellation
  layer not .on server-side), single h1 with no banner role, aria-hidden
  decorative canvas + honesty caption, tooltip present but not shown,
  initial control labels
- ConstellationSection: all three canvas axes present in the accessible
  counterpart (topic grouping, tier badge, time datetime) + fail-soft
  empty render
- ledger.ts: postToConstellationNode interaction metadata (first
  non-empty tag, date, reading minutes) and absent-field honesty

Client-lifecycle coverage (dwell oscillation, listener/timer cleanup,
pointer interaction) needs a jsdom environment the repo does not
configure — recorded as the open M1.5b infra decision rather than
introduced unilaterally. vitest 141/141, svelte-check 0 errors.
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.

1 participant