Skip to content

feat: Observatory Ledger reader — canonical / (TIN-2903; supersedes #231) - #254

Closed
Jesssullivan wants to merge 19 commits into
mainfrom
jess/tin-2903-observatory-ledger-reader
Closed

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

Conversation

@Jesssullivan

Copy link
Copy Markdown
Owner

Fresh PR for the reader lane so the current tip gets pull_request CI coverage (#231 was closed in tonight's board sweep with the tip un-run; this respects the close and restores coverage).

Carries the rebased #231 history (16 commits, clean rebase onto 2f32ce6) plus tonight's mechanics slices per the 2026-08-12 operator rulings:

  • Full-bleed constellation hero — band clamp(360px,48vh,640px)clamp(430px,92svh,1100px), ellipse maxR 0.42→0.47, non-cardinal star floor 2.2px/0.62 while the tier field is sparse (0 noteworthy until TIN-2891 data). R6 deterministic/honesty constraints unchanged.
  • Hover/focus post previews on ledger rows — new PostHoverPreview (Skeleton Tooltip anatomy, anchor-as-trigger via the element snippet; portal card with clamped description + category/reading-time/tags). NoteworthySpread skipped (descriptions already inline); ConstellationSection nodes are groupings, not posts.
  • shadow-preview dispatch default → ubuntu-latest (this branch's copy of the runner-label fix; main gets it via fix(ci): repoint blog CI to reachable runner labels (gates + shadow dispatch) #253).

DRAFT — promotion stays a separate operator ruling (R8). Needs rebase onto main for the dompurify fix (#249) once #253 lands; iterating on the tailnet shadow route meanwhile.

… 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
…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.
…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.
Operator dwell verdict 2026-08-12 (M1.4): the constellation band read as too
small and too dim. Band clamp(360px,48vh,640px) -> clamp(430px,92svh,1100px)
(full-viewport hero, register sliver preserved as scroll affordance); ellipse
maxR 0.42 -> 0.47; non-cardinal star floor 1.6px/0.55 -> 2.2px/0.62 with glow
0.34 -> 0.38 while the tier field is sparse (0 noteworthy posts until
TIN-2891 lands). Deterministic layout, honesty caption, scroll-fade, and
reduced-motion behavior unchanged (R6/R4 hold).
…ooltip

M1.3 floating-UI presence beyond the single canvas star tooltip: new
PostHoverPreview wraps a post link as the zag trigger (element snippet keeps
the anchor itself as the trigger — keyboard focus opens it) and portals a
preview card (clamped description, category/reading-time/tags meta). Wired on
LedgerRegister rows — the dense register earns previews; NoteworthySpread
already shows descriptions inline (skipped as redundant);
ConstellationSection nodes are category groupings, not posts (out of scope).
DOM-anchored surface per the ruled tooltip pattern split
(docs/in-house-reference.md); canvas keeps direct @floating-ui/dom.
The workflow_dispatch input default tinyland-dind names the org-registered
runner pool this personal repo can never draw from, so every manual dispatch
queued until cancelled — while pull_request runs succeeded via the
BLOG_SHADOW_SOURCE_RUNNER=ubuntu-latest repo var. Same bug class as the
bazel-remote-gates repoint on #247.
@Jesssullivan

Copy link
Copy Markdown
Owner Author

Closing as superseded by the current TIN-2413 contract and the August 12 two-lane contraction. TIN-2903 is Canceled; Observatory/Ledger is no longer public IA, and this branch must not be a deployment source or implementation base. Signed commits remain recoverable as donor/history. No merge, branch deletion, or served-state change.

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