feat(star-bin): plan 03 — runtime (registry, loader, star renderer)#442
Merged
Conversation
Names the dedup story before the Gaia starCatalog survey row lands: famous stars are the curated overlay, the Gaia bin is the survey — mirroring the FamousGalaxy↔survey split. Key/const/type/discriminant rename only; the numeric code stays 21 and the body renderer path is untouched. Files moved via npm run move-files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
skymap | 8223528 | Commit Preview URL Branch Preview URL |
Jul 17 2026, 12:23 AM |
…plan 03 Task 2) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ow (plan 03 Task 3) Appends the code, adds the tier-aware singleton row (draw budget + crossfade band carried in-row as Task-12 tuning starting values), and extends galaxyType's exhaustive non-galaxy throw group — the star survey carries stellar, not galaxy, photometry. Also sweeps two FamousStar rename prose stragglers from the Task 1 review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… (plan 03 Task 4) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… GaiaStars rename
User decisions 2026-07-15: famous stars become a second starCatalog row
(bin + labels sidecar, future plan); more catalogs coming, so settings +
entries mirror the galaxy cluster shape (starCatalogs{enabled,items} keyed
by registry-derived StarCatalogId); Source.StarCatalog renames to GaiaStars
(Gaia-the-mission also ships galaxy content). 13 tasks after renumbering.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…plan 03 task 5) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sk 6) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… (amendment 2026-07-16) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…6 review fix) The 'tiered' field is a union-wide discriminant of SOURCE_REGISTRY (volume rows carry literal values too), so the guard-narrowed entry collapses to never in the untiered branch without the widening. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… 10) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r build V8 caps Set and Map at 16,777,216 entries; the real Gaia catalog streams 16,844,156 rows. Invert the GCNS dedup membership (track GCNS ids seen in main, bounded by the 331k supplement) and carry truncation tags on the candidate rows instead of an identity-keyed per-star side Map. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…er reload, progress wake (plan 03 task 7) Also fixes the three initGpu.destroyReachability failures introduced by the starCatalogRenderer construction (stub renderer mock, test-file only). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sk 11) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… surface (plan 03 task 12) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e tier search One memoized size(k) map across all three tier binary searches dedupes the expensive high-k prefix probes; selection is provably k-identical (exact L6 probes only decide). An injected onProgress sink narrates every probe and tier completion on stderr. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ard (final-review fix wave) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stars now fade in while the Milky-Way cloud still dominates the view instead of only inside 5 kpc; first-pass eye-tuning from real-data bring-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ndary The GCNS table's dist_50 column is in kpc (verified against parallax); consuming it as parsecs placed ~217k supplement stars 1000x too near the Sun with absolute magnitudes clamped to the faint end of the LUT. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sSection Settings/UI half of the star-size control, mirroring galaxyCatalogs.sizePx (default 2.5 px, range 1-8). The GPU plumb reads selectStarCatalogSize in a follow-up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… round-trip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… vertex ramp Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Peak intensity = EXPOSURE*flux/(K_GAUSS*rPx^2) makes integrated screen luminance proportional to flux and radius-invariant, so refine/coarsen swaps deposit identical light. Leaves stay point sources; aggregates fill their box footprint so the far field blends into a continuous glow. One knob: STAR_FLUX_EXPOSURE. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…plete and gated Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 0.3 edge/dist refine proxy only split octree boxes subtending ~17°, so the far field drew one glow per box at box pitch — a visible lattice. 0.05 (~3°) refines anything big enough to read as structure; budgets raised so small/medium tiers can afford the deeper cut. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…TAR_FLUX_EXPOSURE scale Second advanced slider (0.2–3.0, default 1.0, mirroring the galaxy brightness twin's range). Plumbed settings → container → draw args → StarUniforms byte 84 → vertex peak multiplier; identity at 1.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…Overlap (shader) Two advanced sliders to dial out the aggregate-box lattice by eye: refineThreshold (0.01-0.30) parameterizes the walk's split criterion — lower splits boxes into real stars earlier; glowOverlap (1.0-2.5) scales aggregate glow radius past the box footprint (StarUniforms byte 88), peak auto-conserves flux since it divides by final rPx^2. Leaves untouched; both identity at their defaults. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…hold 0.16 Tuned jointly: a coarser cut (0.16 ~ 9 degrees, up from 0.05) with 4x glow overlap gives the same smooth far field at a much lower node count than deep refinement with tight glows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… range 0.01–4 The exposure ramp now carries the cross-scale swing, so the 0.01–100 brightness range is no longer needed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…200 pc The Milky Way cloud rendered on the COSMO slab, whose near plane is FIXED at 10 kpc — but its approach fade only starts at 8 kpc, so a descent hard-clipped fully-opaque clumps before the fade could touch them (fifth layer to hit this trap; same cure as the other four). Moving to NEAR0 required two companions: the adaptive far plane now pulls in on deep descents, so stars.wesl + dust.wesl clamp clip.z inside it (the starCatalog trick — both passes verified depthless); and the pick renderer becomes the sole NEAR0 pickable, so it now self-binds its @group(0) pick camera instead of inheriting whatever a prior COSMO pickable left bound (a hidden order-dependence that was fragile before this change). The approach band deepens to { fullAt: 0.002, goneAt: 0.0002 } — the clumps stay through the descent and hand off to the real Gaia star catalog (fully faded in inside 8 kpc) instead of vanishing above it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gh exposure Every tint anchor has r = 1.0, so once a glow's additive contribution exceeded displayable range the shared per-channel tonemap saturated red first, then green: the whole far field collapsed to yellow-white and the data's real colour structure (blue-white halo aggregates, reddened disc plane at BP-RP ~2) vanished. The fragment now compresses the SCALAR intensity through an exponential knee (KNEE * (1 - exp(-I/KNEE)), KNEE = 8.0, eye-tunable) BEFORE the tint multiply, so channel ratios -- the hue -- survive arbitrary exposure. Linear below the knee, so the photometric LOD invariance holds exactly in the faint regime; bright cores still whiten, but by accumulation of many compressed glows, not per-channel clipping of one. Opacity folds into I pre-compression (a faded bright glow is a dimmed bright glow, not a re-dimmed compressed one). Scoped to the star pass: galaxies/volumes keep their calibrated look through the shared tonemap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The walker rebuilt a (level,morton)->index Map over ALL catalog nodes on every call (~268k inserts/frame on the large tier, final-review finding N1) and computed each node's angular priority twice (m7). The new starOctreeIndex builds once per catalog at load and memoises: flat Int32Array child links (O(1) resolution, no hashing), SoA box geometry (Float64Array origins/edges), scalar node fields, and the subtree star counts folded into the same pass. The hot loop touches only typed arrays and a reused scratch heap; priority is computed once at push and carried through the heap. Cut output verified identical old vs new. Bench (stars-large, 268k nodes): 23-26 ms/call -> 0.008-0.019 ms near, 0.79 ms worst-case far camera. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
User reports the loop keeps running after auto-rotate stops. Dev-only, rate-limited: the frame tail logs which shouldKeepTicking arm is true, and the scheduler tallies requestRender reasons per frame, logged when the camera is inactive (catches wake paths that bypass the predicate). Greppable marker: TODO(wake-probe) — remove after T13. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t kept RAF loop awake forever The thumbnail PriorityQueue frees its in-flight slot in a .finally on the fetcher promise, and fetchGalaxyBitmap ran bare fetch() calls with no signal from the engine path — so one stalled cutout request (SDSS ImgCutout / CDS hips2fits) never settled, the in-flight count never returned to zero, and hasInFlightWork kept render-on-demand ticking indefinitely (found via the T13 wake probe: thumbs=true, all else false). Every tryFetch now runs under AbortSignal.timeout(30s) composed with the caller's signal via AbortSignal.any; a timeout collapses to the existing null/failure-memoisation path, and LRU eviction already un-memoises for a later retry. The deadline lives in the fetcher, not the generic queue: settlement is the fetcher's contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…abels toggle The Labels section's tri-state master summed only LABEL_CATEGORIES, so it never touched the Star names row; the Earth/planet captions had no toggle at all (hardcoded always-on in foregroundLabelsLayer). The master now counts every row the section renders, and a new labels.planetLabelsEnabled (default on) gates the 'earth'/'planet' caption kinds exactly as starLabelsEnabled gates 'star'/'sun' — through the temporal envelope, so flipping either fades rather than pops. The foreground captions stay out of SOURCE_ENTRIES: they are seeded scene bodies, not catalog sources. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The RAF-loop-won't-sleep bug is fixed (thumbnail fetch deadline in fetchGalaxyBitmap) and confirmed; the dev-only reason tally in the scheduler, the [wake] console probes in runFrame, and the string-reason requestRender arguments they fed all come back out, restoring the scheduler's no-argument contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The quantization grid divided the population bounding box — 98 kpc, set entirely by LMC/SMC members and bad-parallax outliers while p99.9 of the star-weighted mass sits within 11 kpc — into 512 cells, giving 192 pc leaves and a 228k-star cell at the Sun whose LOD flip was a visible pop. Dropping stars past 12 kpc and deepening the grid to 1024^3 (still within the uint32 Morton field, no format bump) brings leaves to 23 pc and the fattest cell to ~1.3k stars. Rust builder mirrored in its worktree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fixed-finest-grid octree made every occupied 23-pc cell a node, so sparse regions minted millions of 1-2-star leaves: 4.37M nodes whose 16-byte table entries evicted ~5M stars from the gzip-budgeted large tier. Subtrees holding <=64 stars now collapse into a childless fat leaf at their level, records re-expressed in the coarser cell; dense cells keep full 23-pc resolution. Large tier: 623k nodes, 12.85M stars at G<=13.66. Leaf-vs-aggregate therefore stops being 'level 0' and becomes 'childMask == 0' everywhere it was encoded: the subtree-count seed, the layer's flux-multiplier push, and NodeParams.level -> isAggregate (the glow-overlap and box-extent selects in the vertex stage). No format bump: childMask, level, recordCount were already on disk. Rust builder mirrored in its worktree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The leaf-capacity cut commits ~40k draws to fill the 1.5M-instance budget, and both CPU costs scaled with that count: the walker round- tripped every committed node through the best-first heap (7.2 ms), and the renderer paid setBindGroup+draw per node (~9 ms encode). Walker: children that cannot refine (childless or below threshold) commit at the push site and never enter the heap — only refine candidates get ordered, which preserves the cut exactly (once a parent refines, every child draws regardless of budget). Priorities compare as squared ratios (no per-node sqrt), and the output is a reused SoA snapshot instead of 40k allocated objects. 7.2 ms -> 1.9 ms. Renderer: NodeParams moves from a per-draw dynamic-offset uniform to a per-source read-only storage array plus an exclusive prefix sum of record counts; the vertex stage binary-searches the prefix by instance_index to route itself to its node, and the whole cut draws as one draw(3, totalInstances). Per-source buffers keep the writeBuffer/submit ordering landmine at bay; the bind group is rebuilt with the frame's exact size so arrayLength carries the draw count. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
toFixed(2) in Mpc units rounds every position inside ~5 kpc to 0, which made the 'l'-key printout useless for communicating deep-zoom camera poses. Target + distance now format with toPrecision(8) — significant figures survive the full 1e-17..1e2 Mpc scale range and still paste as plain numeric literals. Yaw/pitch/fov stay at 4 decimals (radians). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The supplement (faint nearby stars exempt from the tier apparent-mag cut) all sits inside 100 pc, so the built bins carried a measured 2.2x flux-density step at exactly that radius — a bright ball around the Sun with a hard shell edge. Supplement rows now drop probabilistically from full inclusion at 70 pc to none at 100 pc; the keep decision hashes the star's Gaia DR3 source_id through splitmix64 (bit-identical in the TS and Rust builders, top-53-bit float convention) so builds stay deterministic and record-for-record comparable. Main-catalog rows are untouched at any distance. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 15x/70x near/far exposure anchors were eye-tuned against older, dimmer bins; the current bins carry far more local flux and need a live retune. starExposureRamp is parameterized by (nearX, farX) — bit- identical at the 15/70 defaults — and the two anchors become settings.starCatalogs.exposureNearX/FarX with 'Exposure (near)' (1-60) and 'Exposure (far)' (5-300) sliders in the Stars Advanced group. The shader-baked near exposure (STAR_FLUX_EXPOSURE = 6000 = 400 x 15) is named and handed back out by the CPU ramp, so the shader is untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Star catalogs now report their decoded starCount through the same engineSourceCountReported -> sourceCounts path the galaxy surveys use (fired on the slot's ready transition, so tier switches re-report), and StarsSection renders the same formatted count span per catalog row — absent entries render no chip rather than a misleading 0. Keyed per catalog id, so future star bins inherit the chip automatically. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two deep-zoom costs, one root cause each: - STAR_GLOW_MAX_PX=384 caps the final glow radius (after sizeScale and overlap), bounding per-star additive fill at pi*MAX^2. Flux-conserving: the peak divides by the same clamped rPx^2, so total luminance is invariant — a compact bright core instead of a huge dim halo. - produceMilkyWayLabel now rides the surveyDeepZoom fade band on the near side. The origin-anchored "You are here" stem is COSMO-slab content that cannot project once the camera descends inside the 10 kpc near plane; left emitting, it expanded into a near-degenerate screen-filling quad and kept the whole marker-lines pass alive at solar-system zoom. Culling it (gone by 2 kpc) empties the director's line set so the pass skips. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mposite The star-catalog pass was fill-bound: thousands of aggregate glow quads (box footprint x glowOverlap 4.7, clamped at 384 px) additively summed to 78-139 full screens of overdraw at kpc-scale zoom — 12-20 ms GPU. Split the cut into two streams sharing one memoised CPU walk (prepareStarCut: walk + fade advance + childMask partition, once per frame): - Leaf stars (childMask == 0): unchanged — full-res into HDR, per-glow hue-preserving knee. - Aggregates: LINEAR (fsLinear, no knee) into a new half-res rgba16float 'star-aggregates' offscreen, alpha carrying the summed raw scalar; a fullscreen 'star-upsample' composite in the HDR step applies starKnee to the SUMMED field and adds the result. Half-res per axis quarters the aggregate fill. Kneeing the summed field also fixes the LOD compression asymmetry behind the overblown clump at intermediate zoom: stacked sub-knee aggregate quads previously escaped the compression that tames concentrated bright leaves (flux itself was verified conserved — cut/truth 0.99 refined, 0.58 coarse). The knee curve now lives in one WESL module (knee.wesl) imported by both the leaf fragment and the composite. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
starExposureRamp becomes a piecewise log-linear curve through three anchors: near (1 pc, nearX), NEW mid (3 kpc, midX), far (10 kpc, farX). The default midX = 57 sits on the old two-point curve at the 3 kpc knot (15*(70/15)^(log10(3000)/4) = 57.23), so defaults reproduce the previous look; pulling the new 'Exposure (mid)' slider (5-150) bends only the middle segment. Rationale: farX must stay high (~70) for whole-galaxy legibility at >= 10 kpc, but a single near->far ramp forced by that value over-exposes the dense central clump in the intermediate 1-6 kpc zone, which had no lever of its own. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Foreground-body picking: blocked -> ready, both blockers shipped; stars first per user priority. - New: improve planet rendering (needs-design), lower-res star-aggregate offscreen experiment (ready), bright clump at 5.9 kpc (deferred, with full diagnostic detail file). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The wheel-zoom floor is now unconditionally 1e-17 Mpc (Earth-surface
scale) and the command palette's foreground-body rows (Earth, planets,
stars) always surface. The 0.05 Mpc releasable envelope and its
hasUrlGate('deepZoom') read are deleted; hasUrlGate itself stays for the
tour and gpuTimings flags. Stale gate mentions pruned from comments in
seven source files; surveyDeepZoom (the unrelated scale-fade band) is
untouched.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The fetcher-written gaia.sha256 (gcns_main.csv + hip2.dat checksums, written only after all count assertions pass) and the 2026-07-15 fetch completion date — the committed post-fetch registry record, per the DESI Task 11 precedent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DoD audit 2026-07-17: tests 4,124 PASS, typecheck PASS, all checkboxes resolved (plan-01 Task 11 human attestations recorded inline; plan-02 real-data build satisfied via the byte-verified Rust pipeline, PR #443; plan-03 small-tier mobile cap deferred to a backlog entry). R2 sync of stars-{small,medium,large}.bin ran as part of the same gate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rulkens
marked this pull request as ready for review
July 17, 2026 00:28
rulkens
added a commit
that referenced
this pull request
Jul 18, 2026
Eight rungs flipped to "Built in skymap" now that their subsystems landed on main since #401 opened: - 10^21 Milky Way → GPU star + dust point cloud (#408, impostor gone) - 10^20 Orion Arm → true-position Gaia star bin (#442) - 10^17 nearest stars → Sun + Proxima at true parallax (#444) - 10^12/10^11/10^10/10^8 planets, solar system, Earth+Moon → planet rendering (#445) - 10^9 the Sun → emissive scene-star sphere (#444) 10^19 Local Bubble downgraded research → buildable (star field renders; the local dust volume is the remaining wiring). 10^7 Earth stays built but its viz no longer claims the geolocation pin / atmosphere, neither of which is rendered yet. Each newly-built rung carries a `ref` link to the PR that shipped it, rendered next to the badge — making the footer's "'Built in skymap' links point at the subsystem" promise real. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Executes plan 03: the
starCatalogregistry row + settings, tier-aware fetcher/slot, pure octree draw-cut walker + f64 origin seam, vertex-pulling WESL star renderer, and the NEAR0 HDR layer with the Milky-Way-cloud crossfade.Tasks 1–11 form a complete mergeable unit exercised on synthetic catalogs; Task 12 (visual bring-up + budget/crossfade tuning) is gated on the real Gaia fetch +
build-starsrun and may land as a follow-up.Source.Star→Source.FamousStarrename (value stays 21)🤖 Generated with Claude Code