Commit Graph
225 Commits
Author SHA1 Message Date
SenrokaiandClaude Opus 5.5 0f659af5b3 Pin the M giants' corrections from M4 on, a colour off the table, and a phone held sideways
Three rules the suite passed without, each a test only:

- ef20991 credits its M-giant corrections with M4 going from 0.82 to 1.00 of van Belle's measured
  radii and M5 from 0.71 to 1.00, but only its M6 entry was tested. Reverting M0-M5.5 to the
  dwarf's correction, the M4 or M5 entry to the dwarf's, or the M7.5 entry to M6's, all passed; so
  did reading the table's first entry past its end, which six M8 III stars in the catalogue take
  (28 times too faint, 5.3 times too small). stellar.spec now draws three of van Belle's own
  giants, HD 118669 (M4), HD 104207 (M5) and HIP 68357 (M7), from their median Johnson V, parallax
  and radius in his tables 6 and 4, none behind more than 0.02 mag of dust. They come out at 1.00,
  1.00 and 0.91 of their measured 103.1, 103.2 and 173.3 R; the window is 15 %, since the
  dwarf's correction at M4 only moves the radius by 18 %. And M8 III takes M7.5 III's correction.
- 6a45c91 says a derived radius came "from its type" for a dwarf whose colour the table does not
  read, but no case had one. star-readouts.spec adds HD 49748, G5 V at B-V -0.32; 26 cards in the
  catalogue read this way.
- The phone framing test used a portrait canvas, where the width is the shorter side. A landscape
  one, 844x390, now expects the camera at the framing the 390 px side gives.

Guarded mutants, each failing only the test named, 1 of 837: M0-M5.5 on the dwarf's correction
(`index < 72`); M4 entry -2.2 -> -1.78; M5 entry -2.68 -> -2.025; M7.5 entry -4.86 -> -3.94; past
the end, the first entry (all "draws van Belle's own M4, M5 and M7 giants..."); any colour counted
as read ("says a radius was derived, and from what..."); shorterSidePx the canvas width ("frames
it by the shorter side on a phone held sideways too").

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 21:45:46 +02:00
SenrokaiandClaude Opus 5.5 74913d844d Place a naked-eye star by SIMBAD's name only within a magnitude of its source, and hold HD 45951 to it
e7c420b placed two naked-eye HYG rows along the Gaia source SIMBAD names them as. One of them,
θ¹ Ori A (HD 37020, HYG 26155), came with HYG's V 4.98 and O7, which are Hipparcos's for it and a
companion together: SIMBAD has θ¹ Ori A at V 6.73 and B0V, and its source at G 6.63. At 378 pc the
map drew it at 2.7e4 L and 37 100 K, brighter than θ¹ Ori C beside it, and counted it naked-eye.
The lookup by position already refuses a source more than a magnitude off HYG's V (it refused
this one); the lookup by name now does too. At its own magnitude and 378 pc the map does not keep
the star, as it keeps none that faint past 250 pc: 455 519 -> 455 518 stars, naked-eye 8 899 ->
8 898, of them past 250 pc 1 664 -> 1 663. HD 45951 (V 6.20 against G 5.90) is placed as before.

Nothing checked where HD 45951 was placed, only that its name was there. Along HYG's direction,
31.7' out, every check passed with the star drawn twice: under its name, and as its bare Gaia
designation. validateStars now requires the star named HD 45951 to carry that source's
designation, and requires HYG 26155 to be absent. The MIN_NAKED_EYE_STARS comment gives the new
counts and says why θ¹ Ori A is left out.

ETL mutants, each in a throwaway worktree with a copy of the cache, reached validation and failed
with the expected message:
- HD 45951 placed along HYG's x/y/z: "HD 45951 is not on Gaia DR3 3369454521490604416, the source
  SIMBAD names it as"
- the magnitude check dropped from the lookup by name: "θ¹ Ori A is drawn in the V and type of
  Hipparcos's blend of it with a companion."

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 21:40:06 +02:00
SenrokaiandClaude Opus 5.5 98082a0460 Keep Gaia's colour on a star HYG describes without one
combine took the described entry's colour whole, null included. So a HYG row with no B-V, merged
into its Gaia source, lost the BP-RP Gaia measured for it: HD 45951, HD 45291 and HD 124953, three
naked-eye giants Gaia has at BP-RP 1.25, 1.19 and 0.37, showed no colour on their card. HD 45951's
point had its colour at 280159d, as a bare Gaia designation.

combine now takes the colour, in its own system, from the other entry where the description has
none. The fallback the review proposed, `described.colorIndex ?? other.colorIndex`, reads the same
empty row here, since the Gaia entry is inserted first and so is `kept`, and the HYG row is both
`other` and `described`; it is one of the mutants below. The fold into a source whose HYG star SIMBAD
puts elsewhere keeps the Gliese row's own colour or none, not that other star's.

Published catalogue: 931 stars gain a Gaia BP-RP, all HYG-described entries on a Gaia source with
a V magnitude. 298 of them had neither type nor colour and are now drawn with a temperature and a
radius. 621 dwarfs read their temperature off that colour rather than their type's row, 290 of them
by more than 500 K. The colour is the one every other dwarf on the map is read from, and it agrees
with the brightness where the type does not: HIP 1546, "K:" at V 12.46 and 33.5 pc (M_V 9.8), was
5 270 K and 0.126 R, and is 3 732 K and 0.42 R at BP-RP 2.01. The three giants keep the
temperature and radius their type gives. Star count and every ETL figure unchanged.

Guarded mutants: no fallback, and the review's fallback to `other`, each fail only "keeps Gaia's
colour where the description has none"; the misplaced fold falling back to the other star's colour
fails only "describes the entry by the Gliese row where SIMBAD names the HYG star already there as
another source" (1 of 837 each).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 21:28:29 +02:00
SenrokaiandClaude Opus 5.5 5620776601 Describe a folded Gliese star by its own row where SIMBAD puts the HYG star already there elsewhere
e7c420b folded a Gliese-only row into a Gaia entry a HYG star already described whenever the two V
agreed within 0.5, and kept that HYG star's description. HYG hangs "Gl 905.2A", M5, V 13.11,
B-V 1.55 on HIP 117059, which SIMBAD names as LAWD 93: Gl 905.2B, a DA white dwarf, Gaia DR3
2871730307948650368. Gl 905.2A is G 130-6, another source 3' away with no parallax. So the fold
dropped the white dwarf's own row (DA4, V 12.90, B-V 0.15) and drew its source as a 3 384 K M5
dwarf of 0.292 solar radii.

foldByIdentity now looks up the SIMBAD designation of the HYG star describing the target. Where it
names another source, the Gliese row is the star on this one, and its description, photometry
included, replaces that one (combine takes the described entry as an argument). Five of the 63
folds are of this kind; decoded from the published catalogue, before -> after:

- Gl 905.2A [116690] M5 V 13.11, 3 384 K, 0.292 R -> Gl 905.2B [119589] DA4 V 12.90, 8 175 K, 0.022 R
- GJ 9490A [71678] M0 -> GJ 9490C [118981] K5, the type SIMBAD gives BD+20 3009 (same V and B-V)
- HD 40887 [28371] V 7.85 -> Gl 225.2C [118408] V 8.30, on the source SIMBAD names GJ 225.2 C
- Tau Oph [88131] F5V+ V 4.77 (the pair's light) -> Tau Oph [119195] dF3 V 5.24, GJ 700.1 A's
- HD 65277 [38820] "Gl 293.1B" -> HD 65277 [118511] Gl 293.1A, V 8.06, on GJ 293.1 A's source

Nothing else changes: 455 519 stars, 63 folds, 0 Gliese rows beside their source, no planet
hosted on any of the five ids. The HD 40887 name leaves the map, SIMBAD putting HD 40887 AB on
the source HYG labels Gl 225.2B.

The tolerance's doc said the ten such pairs agree within 0.12. There are 14; 11 do, and the three
that differ by 0.21, 0.45 and 0.47 are three of these five.

Guarded mutants, each failing only "describes the entry by the Gliese row where SIMBAD names the
HYG star already there as another source" (1 of 834): the condition never true; the condition
inverted to describer === designation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 21:18:13 +02:00
SenrokaiandClaude Opus 5.5 e7c420b296 Fold a Gliese star into its Gaia source in Gaia's photometry, wherever HYG already put it, and place two naked-eye stars by SIMBAD's name for them
The Gliese fold (030447b) kept HYG's magnitude, band and colour over the Gaia entry's, putting
CNS3's V at Gaia's distance. Of the 49 folded, 15 lost a measured BP-RP and 6 their temperature and
radius (Gl 700.1C, Gl 632.2B, GJ 9800B, Gl 734B, Gl 323B, GJ 3605), and GJ 4285, V 11.45 where
SIMBAD has G 13.05, was drawn five times too luminous. A folded star now keeps the photometry of the
entry already there; HYG's name, id and type still come with the fold. Published catalogue, before
-> after: GJ 4285 V 11.45, 3 850 K, 0.491 R☉, 4.76e-2 L☉ -> G 13.05, BP-RP 2.74, 3 291 K, 0.297 R☉,
9.29e-3 L☉; GJ 3207 0.574 -> 0.278 R☉; Gl 700.1C no temperature, 4.54 L☉ -> 5 155 K, 1.214 R☉,
0.937 L☉; Gl 632.2B -> 9 044 K, 0.018 R☉; Gl 734B -> 3 360 K, 0.381 R☉.

The fold also looked its target up by name, so it saw only Gaia entries still bare. Where a
Hipparcos row of HYG's had already taken the source, the Gliese-only row of the same star stayed
beside it and the check counted none: Gl 251 at 5.76 pc beside HD 265866 (the host of GJ 251 b and
c) at 5.58, Gl 422 beside HD 304043. Gaia entries now carry their DR3 designation through the merge
(ETL only; the assets do not store it) and the fold looks it up; into an entry a HYG star already
describes it folds only where the two V agree within 0.5, so a companion SIMBAD gives its primary's
source stays. 14 more rows fold, 63 in all, each within 0.47 of the star it joins: Gl 251, Gl 422,
Gl 162, Gl 794, Gl 225.2C, Gl 905.2B, GJ 3232, GJ 4046, GJ 9490C, GJ 9608, 69 Tau Oph (Gl 700.1A)
and the second rows of HD 65277, HD 120237 and HD 336196. Stars within 10 pc 367 -> 366, within
25 pc 5 479 -> 5 468; distances without an error 346 -> 332; HYG survivors 11 478 -> 11 465.

validateMerge's count of Gliese rows beside their source took SIMBAD's map from the function the
fold takes it from, so a slip in the map turned both off: with it empty, GJ 2097 and GJ 4285 were
back inside 10 pc and the ETL passed. It now also asks for GJ 2097 and GJ 4285 beyond 20 pc and for
no Gl 251 or Gl 422 by name, and glieseGaiaDesignations refuses fewer than 3 200 HYG rows matched to
SIMBAD (3 352 of HYG's 3 801 measured).

4d47896 left 22 naked-eye HYG rows out as having no distance anywhere; two had one. HD 45951 (K0 III,
V 6.2) was on the map only as "Gaia DR3 3369454521490604416", HYG's declination being 31.7' out,
and θ¹ Ori A (HD 37020, HIP 26220) sits 0.1" from Gaia DR3 3017364132050194688, 2.643 ± 0.072 mas,
which the magnitude test refused because HYG gives V 4.98 against G 6.63. One cached SIMBAD query
now names the Gaia DR3 source of each naked-eye HYG row with no distance (199 of 206 HD numbers),
and a row nothing else places takes that source from the bright list, at its position: HD 45951 at
112.0 pc, under its name, and θ¹ Ori A at 378.4 pc. HD 45951 joins the required names. The twenty
still left out are named in build.ts; none has a bright source with a parallax five times its error
within a minute of arc nor under its SIMBAD name. Naked-eye stars 8 898 -> 8 899; 455 532 -> 455 519
stars.

The fold and the identity lookup are tested in star-merge.spec.ts. Guarded mutants (1 of 833
failed unless noted):
- the Gliese row's photometry kept: caught by "...in Gaia's photometry" (and the Hipparcos-row fold test, 2 failed)
- combine dropping the designation: caught by "folds one into a Gaia entry a HYG star of the same brightness..."
- folding whatever the brightness; tolerance 2 magnitudes: caught by "leaves a star with a Hipparcos error alone..."
- folding into bare entries only: caught by the Hipparcos-row fold test (and the leave-alone test, 2 failed)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:55:25 +02:00
SenrokaiandClaude Opus 5.5 c8d1bbb879 Hold st_lum's conversion to two hosts' luminosities, and mu2 Sco b to its host
8d59c72 checked only that every host luminosity was positive, which catches st_lum stored
unconverted and nothing else: converted as 10^-x, Proxima Cen b came out 662 L☉ and TRAPPIST-1 e
1 808, and as e^x Proxima 0.0595, 39 times too bright, and in both runs the ETL completed with
every check passing. The value is printed as measured on host cards and warms their planets.
validateExoplanets now asks two hosts for the luminosity their st_lum gives, within 10 %: Proxima
Cen b's, st_lum -2.821, 1.51e-3 L☉ (Ribas et al. 2017 measure 0.00151), and HD 97048 b's, st_lum
+1.602, 40.0, so a sign slip fails on both sides of the Sun. The published file has 1.5100e-3 and
40.000.

5fb0d45 placed mu2 Sco b's host by its parallax, the archive giving no sy_dist, and only the helper
was tested: with the parallax dropped at the call site the ETL still passed, 6 327 of 6 354 hosted
against a floor of 99.5 %. mu2 Sco b must now have a host.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:54:48 +02:00
SenrokaiandClaude Opus 5.5 ef2099177a Give M giants their own bolometric correction, which from M4 on is not a dwarf's at their temperature
aafc788 held the M6-M7 giants at van Belle's 3 134 K but kept the dwarf sequence's correction at that
temperature, -2.76, so they were still drawn too small: RZ Ari 81.5 R☉ where its CHARM2 diameter of
10.30 mas gives 119 at its distance, EU Del 72.6 where 9.90 mas gives 126, 30 Her 126 against 177.
The comment called the M6 sizes corrected; they were not.

From van Belle et al. (2021) themselves, m_bol from their table 4 bolometric fluxes (IAU 2015 zero
point) less their dereddened Johnson V (table 6, median of each star's values), the giants' BC_V
by type is within 0.1 of the dwarf sequence's at the same temperature down to M3, and then parts
from it as TiO takes the V light: -2.20 against -1.78 at M4 (31 stars), -2.68 against -2.03 at M5
(15), -3.34 at M5.5 (7), -3.94 against -2.76 at M6 (3), -4.86 at M7-M7.75 (4). From M0 an M giant
now takes those medians, linear between types and held past the ends; G and K giants keep the
dwarf's at their temperature.

Measured, drawn radius over van Belle's own measured one, median by type, before -> after:
M0 0.96 -> 0.96, M2 0.98 -> 1.00, M3 0.94 -> 0.98, M4 0.82 -> 1.00, M5 0.71 -> 1.00,
M6 0.66 -> 1.13, M7 0.38 -> 0.94. In the catalogue, against CHARM2 diameters at the app's own
distances: RZ Ari 81.5 -> 140.3 R☉ (measured 119.3, ratio 1.18), EU Del 72.6 -> 124.9 (126.3,
0.99), 30 Her 126.0 -> 216.9 (177.5, 1.22), Eps Oct 92.6 -> 159.3 (110.4 from a K-band disc of
±13 %, 1.44); Mirach 82.6 -> 83.1, Betelgeuse 538.8 -> 551.0, Antares 409.7 -> 414.0. The M6 value
rests on three stars and both 30 Her and Eps Oct are semiregular variables, so the late-M sizes are
good to a quarter, no better. 312 stars' corrections move by more than 0.05 mag.

Guarded mutants, each caught by "draws an M6 giant at the radius its measured diameter gives..."
alone (1 of 833 failed): M giants back on the dwarf's correction; M6 entry at -2.76; interpolation
taken from the wrong end.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:54:26 +02:00
SenrokaiandClaude Opus 5.5 6a45c914ac Say a derived radius came from the star's type where no colour went into its temperature
The card said every derived radius came "from colour and brightness". Since 206e88a a star with no
colour the table reads is placed at its type's row, and a giant's temperature is always its type's
(giantSurface): on the published catalogue that is 844 stars with no colour at all, GJ 3655 (M8)
among them, and 10 702 giants with one, all labelled "from colour". temperatureFromColour, beside
effectiveTemperatureK, says which path the temperature took, and the card now reads "from its type
and brightness" where it was the type, and "from its temperature and brightness" for the archive
hosts whose colour was itself read off st_teff.

Guarded mutants, each caught by "says a radius was derived, and from what" alone (1 of 831 failed):
- the basis always "colour"
- giants not excluded in temperatureFromColour
- colorFromTemperature ignored

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:42:37 +02:00
SenrokaiandClaude Opus 5.5 c0ed91dcf9 Pin three rules the suite passed without: the first planet's temperature, the one-step error floor, and G carried to V by type
publishedTemperaturesK keeps each host's first st_teff so the star field tints it as starSurfaceOf
draws its disc; the only test used Proxima, with one planet, and letting the last row win passed
all 828 tests while 189 hosts in the catalogue would be tinted apart from their disc (193 hosts give
their planets differing st_teff, 30 by more than 200 K). The new test gives one host three rows,
none, 4 094 and 3 640 K, and asks both functions for the same 4 094.

The error column's at-least-one-step floor was tested with an error of 1e-6, which at 255 steps
rounded to none but at f31ffe1's 65 535 rounds to 66, so dropping the floor passed. The fixture is
now 1e-12, 0.07 of a step.

206e88a carries a G magnitude to V at the type's G-V where a star has no colour, and no test held
it: the only type-only case was in V. The new case measures GJ 3655 in G, 3.11 brighter at M8, and
asks for the V case's luminosity; taken as V it came out 17 times as luminous. Oph 11 (M9, G 18.91)
is the one published star on that path.

Guarded mutants, each caught by its named test alone (1 of 831 failed):
- "hostStarTemperatureK && !temperatures.has(hostStarId)" -> "hostStarTemperatureK"
- the Math.max(1, ...) floor removed
- "(sequence?.gMinusV ?? 0)" -> "(sequenceAtColour(star)?.gMinusV ?? 0)"

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:42:37 +02:00
SenrokaiandClaude Opus 5.5 ee168996f7 Test the disc's limb law by working it out, and the phone framing through the scene
The disc test walked the material's node graph and asserted only that the constant 0.6 was in it,
so any law that kept the literal passed: a limb 1.6 times brighter than the centre, a reversed mu,
mu held at 1, all 828 tests green. It now evaluates the factor the photograph is multiplied by off
the graph itself, at a given cosine between normal and line of sight, knowing only +, -, *, clamp,
dot, oneMinus and negate and failing on anything else, and asks for the Sun's linear law: 1 at the
centre, 0.7 at mu 0.5, 0.4 at the limb and 0.4 past the silhouette. The dot must be of normalView
and positionViewDirection.

The phone framing (e62e2fb) depends on the scene passing the canvas's shorter side, and the test
canvas had no size, so removing that argument left every test passing. A new test gives the canvas
390x844, enters Antares and asks for the camera where systemFramingDistanceAu puts it with
shorterSidePx 390, 1.5 times or more further out than without it.

Guarded mutants, each caught by its named test alone (1 of 831 failed):
- limb 1 + 0.6 mu; mu reversed with oneMinus; mu clamped to 1; negated law (limb 1.6x);
  clamp removed: "...darkened towards the limb".
- shorterSidePx dropped; shorterSidePx times 0: "frames a supergiant on a phone...".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:42:37 +02:00
SenrokaiandClaude Opus 5.5 4c1e19d635 Give the disc sizes the framing quotes as radii, and the meta columns in the order they are stored
The framing rule works in radii: at 390x844 a giant's disc may take 0.74 - 90/195 = 0.278 of the
195 px half-side, 54 px from the centre, and before e62e2fb it took half of it, 98 px. The comment
and the spec called the 98 px a disc, which reads as a width, and a name 70 px from the centre
would then have been off it. e62e2fb's message says "54 px wide" and "98 px wide" for the same
radii: the discs are about 108 and 195 px across.

The stars-meta.bin doc comment still put the photometry byte before the distance error, which
f31ffe1 moved ahead of it for alignment; metaColumns, the DISTANCE_ERROR_STEPS comment and the
README already had the new order.

The scene's 2 883 hosts past the survey edge are all hosts past it: 2 878 are the archive's own
stars and 5 are HYG's (HD 81817, HD 102272, HD 158996, HD 208527, HD 220074).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 19:17:20 +02:00
SenrokaiandClaude Opus 5.5 280159dcd2 Bring the figures the comments quote back to what the catalogue now holds
Later commits on this branch (0e9ab6f, ff744a0, 8c3a860, and this round's fold, positional lookup
and parallax fallback) changed counts that comments in build.ts, star-readouts.ts, star-catalog.ts
and fetchExoplanets.ts still quoted as "measured" or "today". Each is now the value measured on the
published catalogue after an ETL run from cache (decoded with decodeStarCatalog, or from the
validator log where it prints them):

- distances without a published error 439 -> 346, the Gliese ones 357 -> 264 (82 archive);
- parallax distances ranged 1 109 -> 1 116; HYG stars at Gaia's distance 8 129 -> 8 105, and the
  Gaia-placed stars HYG describes 62 002 -> 61 713 at Gaia's distance, 62 097 in all;
- HYG rows without a Gaia counterpart 11 554 -> 11 478: past 250 pc 8 307 (1 660 naked-eye), inside
  it 3 170 (1 204 brighter than V 8, 1 804 from 8 to 12, 162 fainter, 112 of them Gliese stars
  within 50 pc); the sentence also said those were every star past 250 pc, which the archive's
  hosts no longer let it be;
- planets with a host 6 327 -> 6 328, the 26 left having neither a distance nor a parallax;
- renamed hosts 575 -> 574; the composite table fills 100 of the 127 blank distances, not "the 100".

No ceiling or floor changes; comments only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 17:46:00 +02:00
SenrokaiandClaude Opus 5.5 f31ffe1425 Store a star's distance error in two bytes, so the card prints the error its catalogue published
a81dd49 kept the square root of the relative error in 255ths. A step was a few per cent of the
error itself, which moved the last digit the card prints: over the cached Gaia answers, 2 822 of
the 53 209 stars whose card prints an error printed another one than their published parallax
error gives (Gaia DR3 1415230383034813824 "112 +- 2 pc" for 3), and Rigel, 3.78 +- 0.34 mas in van
Leeuwen 2007, read "265 +- 23 pc" for 23.8.

The column is now a Uint16 in 65 535ths, placed before the photometry byte so its view stays
two-byte aligned whatever the star count; BYTES_PER_STAR_META goes from 16 to 17, the build.ts
round trip tolerance to half a 65 535th, and the README names the column. The same count gives 12,
each on a rounding half. In the running app Rigel reads "265 +- 24 pc".

The cost: stars-meta.bin goes from 7 288 512 to 7 744 044 bytes, and gzip -9 from 3 117 639 to
3 623 379, half a megabyte more to download, since the extra byte is noise-like. One reviewer
judged the one-byte figure within the errors' own accuracy; this takes the other two's view that
the card should print the published number.

Control: 255 steps again fails "keeps an error close enough that the card prints the published
one" alone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 17:43:54 +02:00
SenrokaiandClaude Opus 5.5 4d47896b4a Find the naked-eye stars Gaia's HIP cross-match lacks by position, and give two unnamed ones back their names
c64eea0 and ff744a0 left 34 of HYG's stars of V 6.5 or brighter off the map for want of a distance,
saying no survey gave them one. Gaia DR3 does, for twelve, above the ETL's own cut of five times
the parallax error: fetchStars looks Gaia up only by HIP number through hipparcos2_best_neighbour,
which lacks some of theirs (66 Ori's among them), and never looks up a HYG row with no HIP number.
HD 197770 is 1.102 +- 0.029 mas; HD 45291 and HD 124953 were on the map only as bare Gaia entries
a second of arc from where HYG has them, so searching their names found nothing.

fetchStars now fetches, once and cached, Gaia DR3's 35 910 sources brighter than G 7.5 with a
usable parallax, and for a naked-eye row nothing else places takes the nearest within 5" and a
magnitude of its V. At 15" theta-1 Ori (HIP 26220) took the source of theta-1 Ori C, 12.9" away and
already on the map; the twelve found are within 4.1". An ETL run from cache: 455 522 stars become
455 532, the naked-eye stars 8 886 become 8 898 (1 663 past 250 pc), with 66 Ori, HD 49567, HD 54309,
HD 74455, HD 114461, 10 Sge, HD 197770, HD 33948, HD 152249 and HD 162678 added, and HD 45291 and
HD 124953 folded into their Gaia entries under their names. 22 stay out, with no distance anywhere.
In the running app HD 197770 reads "907 +- 25 pc", 66 Ori "469 +- 61 pc", HD 45291 "108 pc" and
HD 124953 "46 pc". Four of the twelve have a RUWE above 3.7 in Gaia; the ETL has never filtered on it.

validateStars now also requires HD 197770 and HD 45291. Control: without the positional lookup,
the ETL fails with "HD 197770 is missing" (the naked-eye floor alone would not see twelve stars go),
and the baseline passes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 17:36:44 +02:00
SenrokaiandClaude Opus 5.5 030447b83c Fold a Gliese star into the Gaia source SIMBAD names it as, so none is drawn twice or inside 10 pc by mistake
HYG's Gliese-only rows, with no Hipparcos astrometry and no published error on their distance,
reach the merge with positions off by up to minutes of arc, photometric distances and sometimes
wrong proper motions, and isSameStar's geometry missed 49 of them beside their own Gaia entry. 43
lie within 25 pc and 27 are fainter than V 12, the layer the brief asked to merge without
duplicates. GJ 3478 is 16.3" from its Gaia entry, past the 15" tolerance; GJ 2097 moves 39 %
differently by HYG's motion; GJ 4285 is co-moving but 1.6 magnitudes brighter in HYG's V than
Gaia's G. Two of them were false stars inside 10 pc: GJ 2097 at 6.41 pc and GJ 4285 at 6.80, which
Gaia measures at 24.47 and 28.25. HYG also put Gl 94 31.6 degrees from where it is, and HD 23585
and HD 23713, Pleiades members at 135 pc, at 20.6 and 22.2. 0e9ab6f's "no Gliese row within 25 pc
has a co-moving bare Gaia entry 3-300" away" held only under its own motion rule.

fetchStars now asks SIMBAD once, in one cached TAP query, for the Gaia DR3 designation of every
object it knows by a GJ number (4 868), maps HYG's `gl` column onto it, and foldByIdentity folds
each Gliese-only row into the bare Gaia entry of that source: HYG's name, type and photometry,
Gaia's position and distance, as combine does for any other pair. An ETL run from cache folds 49:
455 571 stars become 455 522, the stars within 10 pc 369 become 367, within 25 pc 5 522 become
5 479, HYG rows without a Gaia counterpart 11 517 become 11 468, distances with no published error
395 become 346. exoplanets.json is unchanged. In the running app GJ 2097 reads "24 pc, HYG, Gaia
DR3 distance", GJ 4285 28 pc, Gl 94 17 pc, and 367 stars lie within 10 pc.

validateMerge now refuses any Gliese-only row beside the bare Gaia entry SIMBAD names as the same
star. Controls: folding with an empty identity map fails the ETL with "49 Gliese stars are drawn
beside the Gaia source SIMBAD names them as, starting with GJ 1033" (the baseline passed); in the
unit suite, folding a row with a Hipparcos error fails "leaves a star with a Hipparcos error, and
a Gaia entry already folded into, alone", and keeping the Gliese position fails "folds a Gliese
entry into the Gaia entry SIMBAD names it as, at Gaia's position and distance". HYG's V is kept
for a folded star, which for GJ 3207 is the wrong one (11.51 where SIMBAD has 13.75).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 17:20:32 +02:00
SenrokaiandClaude Opus 5.5 8d59c720b3 Hold the published catalogue to its naked-eye stars, its host luminosities and five other things no check saw
Seven properties of the catalogue could be lost by a one-line slip in the ETL with every validator
passing and the weekly job publishing the result. validateStars and validateExoplanets now refuse:

- fewer than 8 800 stars of V 6.5 or brighter (8 886 measured), or Rigel, Deneb or Alnilam gone;
  with no magnitude handed to placementDistancePc, 7 378 are left;
- a host luminosity that is not positive, or fewer than 90 % of planets carrying one (6 036 of
  6 354): st_lum is published as log10(L/L_sun), and stored unconverted 3 307 read <= 0 and
  Proxima's -2.82;
- fewer than 40 colours marked as read off a temperature (54 measured);
- an archive-placed star more than 1 mas from its planets' published position carried from
  J2015.5 to J2000 (6.6e-8 mas at most measured; not carried, 6 277.9);
- fewer than 300 HYG stars folded into Gaia keeping their more precise Hipparcos distance (384),
  or Tarazed and Eta Leo off theirs;
- more than 5 archive stars numbered other than their name hashes to (1 measured).

These come from an interrupted earlier attempt left uncommitted in this worktree; its other half,
asymmetric archive distance errors that nothing in the ETL wrote, and a placementDistancePc test
that failed, was discarded (saved in the scratchpad as uncommitted-at-start.patch). The naked-eye
check is new, and runs before the Hipparcos one, which the same slip also trips.

Controls, each an ETL run from cache in a throwaway worktree that reached "Validating output..."
and failed with the named check's own message: no magnitude to placementDistancePc (naked-eye
floor); `10 ** logLuminosity` -> `logLuminosity`; colorFromTemperature never set; the archive
epoch offset times 0; combine never taking the other entry's distance; archive ids in arrival
order. The unmutated baseline passed. star.model.ts's count of flagged hosts, 57, is now 54.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 17:08:31 +02:00
SenrokaiandClaude Opus 5.5 5fb0d45623 Place an archive host by its parallax where the archive gives no distance, so mu2 Sco b has its star
The archive leaves sy_dist blank for mu2 Sco and publishes sy_plx 6.31 +- 0.86 mas. The matcher
only reads the parallax as a second chance beside a finite sy_dist, and the archive-star fallback
needs sy_dist too, so mu2 Sco b had no host while Pipirima (HIP 82545, V 3.56, B2 IV) sat on the
map 0.4" from the archive's direction at 145.3 pc. The build.ts comment and the step report said
the 27 hostless planets had "no distance in either archive table"; mu2 Sco was the one whose row
has a parallax.

archiveDistancePc takes sy_dist, or 1000 / sy_plx where it is blank (158.5 pc here, within the
ratio test of Pipirima's 145.3). An ETL run from cache changes exoplanets.json alone: mu2 Sco b
now has host 82294, Pipirima, and 6 328 of 6 354 planets have a host (26 without, none of whose
rows has a distance or a parallax). hostDistancePc stays the archive's own blank.

Control: ignoring the parallax fails "takes the archive's parallax where it gives no distance,
and nothing from a parallax that is none" alone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 16:37:30 +02:00
SenrokaiandClaude Opus 5.5 734b048c9e Write the star assets once, after the archive's hosts are added, not before them as well
Since 494fb56 and 4c8e4a0, fetchStars wrote stars.bin, stars-meta.bin and stars-index.json, and
fetchExoplanets wrote them again with the 3 277 hosts it adds from the archive and the 574 Gaia
designations it renames, after the live Horizons and archive fetches in between. A run stopped
between the two writes, or fetchStars.ts run on its own as the README documented, left 452 294
stars on disk with no archive star and 574 hosts back to their designations, and the existing
exoplanets.json pointing 4 237 planets at stars that were not there. It happened on this branch:
the dev server served those files.

fetchStars now returns the stars and writes nothing; fetchExoplanets, which build.ts runs after
it, is the only writer. fetchStars.ts run on its own runs fetchExoplanets, which fetches the
stars itself. Checked from cache: `tsx tools/etl/fetchStars.ts` exits 0 and writes 455 571 stars,
the published files byte for byte; build.ts with fetchSolarSystem made to throw fails with
"simulated Horizons outage" and leaves every data file unchanged, where before it left the
452 294-star catalogue. The README's table now names fetchExoplanets.ts as what writes them.

The ETL has no unit harness; these two runs are the check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 16:21:03 +02:00
SenrokaiandClaude Opus 5.5 073fb9f718 Ring only the planet hosts inside the survey edge, so the Kepler field is not a band over the view
4c8e4a0 added 3 277 hosts from the archive, 2 883 of them past 250 pc and 916 past a kiloparsec,
most in the Kepler field. Every host got a 12 px ring whatever its distance and a place in the
draw budget's first tier after the pinned stars, rules set when 1 of 1 379 hosts lay past 250 pc.
At boot the opening view held 3 332 rings against 1 290 before, 1 687 of them in its lower right
(x > 1000, y > 550 at 1600x1000) where there were 116, over the 250-350 pc grid labels; hosts 1-3
kpc away read as neighbours in a view whose range is 307 pc, and 629 stars past a kiloparsec were
drawn where there had been 3.

Rings and the host tier now take the hosts within SURVEY_EDGE_PC only. The far hosts still compete
for the budget by brightness, and search still enters them. Measured in the running app at
1600x1000: 1 853 rings in all, 1 698 in the opening view, 199 in its lower right; 31 stars past a
kiloparsec drawn; 1 767 hosts drawn. This reverses "a ring on every host" for the far ones: that
was the user's rule of 2026-09-17, when the only far host was one star, so it is flagged for them.

The scene test's fixture gains the lens's planet, 6.7 kpc out. The new test checks the ring count
and the host tier; the opening-view test now expects the lens out of that tier. Control: dropping
the distance condition fails the new test and that one (2 of 824).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 16:14:28 +02:00
SenrokaiandClaude Opus 5.5 e62e2fb03f Keep a giant's disc clear of its neighbours' names on a phone, not only on a desktop
d1aa22e framed a giant so its disc took half the view's tighter half-extent, inside the ring its
neighbours are named on at 0.74 of it. It measured that at 1600x1000 only. The names hang a fixed
distance in from the ring, 74-78 px, so on a 390x844 phone the 0.24 of the half-side between disc
and ring is 47 px and the names land on the disc: Betelgeuse was drawn 98 px wide with HD 39374's
name 70 px from its centre, Antares with HD 148199's at 68 px.

The framing now takes the canvas's shorter side and keeps the disc inside the ring less 90 px,
at most half the half-extent as before, at least a tenth. Measured in the running app at 390x844
on arrival: Betelgeuse, Antares and Rigel drawn 54 px wide, the nearest names at 70, 68 and 127
px. At 1600x1000 nothing changes: Betelgeuse 250 px, its nearest name at 296. The ring's fraction
moves to system-framing.ts, beside the rule that depends on it, and the scene reads it there.

The review's other half, that the Readout sheet covers 44 % of the disc once opened on a phone, is
not changed: the dock opens with no panel below 640 px and folds it on any tap on the scene, so
the star arrives with nothing over it.

Control: giving the names no reach fails "keeps a giant's disc clear of its neighbours' names on
a phone" alone. The scene's passing of the canvas size has no unit test (the test canvas has no
size); the app measurement above covers it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 16:09:56 +02:00
SenrokaiandClaude Opus 5.5 4e7d4cd1d6 Say a type estimated from a colour read off the archive's temperature came from the temperature
23547de gave archive hosts measured in no colour a B-V read off the dwarf sequence at their st_teff,
and the card's Colour row says so, but the subtitle then estimated a type from that colour and
said "from colour". 30 of the 54 flagged stars read that way: PSR J1719-1438, a millisecond pulsar
whose only input is st_teff 4 500 K, read "Spectral type ~K5, from colour" beside "B-V 1.13, from
its temperature"; DP Leo ~B7, ZTF J1828+2308 ~B5, ZTF J1230-2655 ~A0.

The subtitle now ends ", from its temperature" for those 30. In the running app the pulsar's card
reads "Spectral type ~K5, from its temperature" above "B-V 1.13, from its temperature". The type
itself is still the dwarf the temperature matches, which a pulsar is not; this only stops it
naming a measurement that does not exist.

Control: ignoring the flag fails "says an estimate came from the temperature where the colour
was read off it" alone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 16:05:08 +02:00
SenrokaiandClaude Opus 5.5 2dac3767e8 List a host's own planets ahead of the systems whose names only run on from its own
Once the archive's 3 277 hosts became stars and 574 Gaia hosts took their names, "K2-18" listed
the star K2-18 and then K2-180 to K2-186, and no planet: "k2-18 b" and "k2-180" were both prefix
matches, and on a tie the ranking put every star before every exoplanet. Replaying each host's
name through the ranking over the published catalogue, 325 hosts had some of their own planets
pushed out of the eight rows shown (655 planet rows), against 75 before the archive stars.

A prefix match that ends where a word does now scores 3.5, between an exact match and a prefix
running on into the same word. The same replay gives 50 hosts and 62 rows. In the running app
"K2-18" lists K2-18, K2-18 b, K2-18 c, then K2-180 onward; "Kepler-186" lists the star and
Kepler-186 b to f before Kepler-1860; Kepler-22 b and WASP-12 b are back. "Proxima", "Io" and
"TRAPPIST-1" list as before.

Control: scoring the word-ending prefix level with any prefix fails "lists a host's own planets
ahead of the systems whose names run on from its own" alone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 16:05:08 +02:00
SenrokaiandClaude Opus 5.5 f8582b78d0 Test the star's disc itself: its photograph, its colour and its darkening toward the limb
2242fe0 gave every star the Sun's photograph in grey, tinted at its temperature and limb-darkened
as 1 - 0.6(1 - mu), and nothing tested any of the three: with the coefficient at 0, the tint
dropped from the material, or the photograph replaced by the tint alone, all 817 tests passed. The
one colour test read scene.starTint, a uniform the scene sets whether or not the material uses it.

The new test enters Proxima and walks the disc material's colour node graph for the tint uniform,
the texture loaded from SUN_TEXTURE_PATH and the coefficient 0.6. Controls, each failing it alone
(1 of 820): the coefficient at 0; at -0.6, a limb brighter than the centre; the tint dropped; the
photograph replaced by the tint. A mutant that keeps the texture node in the graph but multiplies
it by nothing is not caught; the test checks the parts, not the arithmetic between them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:57:52 +02:00
SenrokaiandClaude Opus 5.5 368fcfb6f0 Keep each spectral type's giant surface once, rather than reparse it for every star at boot
The star field reads every star's temperature at boot, and each read asked giantSurface, which
splits the type and runs two regular expressions whether or not the star is a giant: 455 571
times for 2 888 distinct type strings. It depends on the type alone, so it is now kept per type.

The tint pass over the published catalogue gives the same colours (checksum 5 830 745.929 before
and after) and in Node takes 167-237 ms against 241-305. In the running app, the star field
rebuilt in the page three times after each of four cold boots: median 65 ms before (60-79), 51
and 53 ms after in two runs (46-67). The longest task after the data lands did not move beyond
the noise (median 851 ms before, 859 and 827 after): most of the boot growth since c38a42c is the
larger catalogue and the per-star colour lookup, which the tint needs. Memoising colorIndexToRgb
on its three inputs, the fix the review also named, would not help: 337 998 of the 455 571
triples are distinct, and reviewers measured it 260-370 ms slower.

No behaviour changes, so no new test; the suite (819) passes as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:51:41 +02:00
SenrokaiandClaude Opus 5.5 17cf11b6b1 Tint a planet host in the star field at the archive's temperature, which its disc is drawn at
95ffb00 said the field took "the same function and the same temperature the disc is drawn with".
It did for stars without planets, but a host's disc is drawn at the archive's st_teff
(starSurfaceOf), and the field read the host's temperature off its colour. Of the 4 485 hosts with
a temperature on the published catalogue, 1 755 were more than 0.1 in RGB from their own disc:
Kepler-186 at 3 096 K in the field and 3 788 K on its disc, HD 97048 at 6 825 and 10 000.

The scene now hands StarFieldRenderer each host's first published temperature among its planets,
the rule starSurfaceOf uses (publishedTemperaturesK, beside it), and the field tints that star at
it. Over the catalogue the hosts more than 0.1 off their disc go from 1 755 to 0. Measured in the
running app at 1600x1000, field tint against the disc's starTint after entering each: Kepler-186
(1, 0.620, 0.326) against (1, 0.619, 0.326), where the field was (1, 0.498, 0.174); Teegarden's
Star 0.001 apart; Proxima, HD 97048 and Sirius 0.

The field's test compared colorIndexToRgb with the same formula. The new scene test enters Proxima,
whose B-V 1.8 reads 3 070 K and whose disc is drawn at the archive's 2 900, and compares its field
colour with the disc's. Controls, each failing that test alone: the field ignoring the map it is
given, and the scene passing an empty one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:48:09 +02:00
SenrokaiandClaude Opus 5.5 aafc788352 Hold van Belle's giant temperatures at 3 134 K from M6, as its table does, and test every piece
giantSurface carried the 64-71.5 fit of van Belle et al. (2021, ApJ 922, 163, table 8) on to
index 73.9, where the table's fourth piece, 72-74, is flat at 3 134 K: M6 III (index 72) came out
3 300 K and M7 III 3 214 K. The paper's own M6 and M7 giants average 3 112 and 3 114 K. The
temperature and the correction at it both feed the drawn radius, so the 29 catalogue giants from
M6 to M7.9 were drawn too small: Rho-2 Ari 57.1 solar radii, now 81.5; 30 Her 88.3, now 126.0;
Eps Oct 64.9, now 92.6. The comment said the scale was held "past M7.75"; it now says from M6.

The giant test only reached the third piece (Aldebaran K5 III, Antares M1). It now checks each
piece against table 8: G8 III 4 797.08 K, K2 III 4 387.58, M5.5 III 3 343.43, and M6 and M7 III at
3 134. Controls, each failing "reads a giant's temperature and correction both off its type"
alone: the third piece carried past M6 again; a G giant indexed as K; the first piece's slope
52.74 -> 45; the second's 199.41 -> 180. Before this, the last three left all 817 tests passing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:42:15 +02:00
SenrokaiandClaude Opus 5.5 206e88ae85 Read a dwarf with a type and no colour at its type's row of the dwarf sequence
A non-giant with a spectral type but no colour took its temperature off the textbook colour
spectralTypeToColorIndex gives its type, read on Pecaut & Mamajek's table, and its bolometric
correction off the old textbook anchors. The table puts those colours elsewhere: M8's B-V 1.88
is M5-M5.5 there, 3 001 K where M8 V is 2 570, and the anchors give M8 -3.92 where the table has
-5.65. GJ 3655 (M8, 14.35 pc) was drawn at 0.035 solar radii, a third of Jupiter, where its
type's row gives 0.106 (Mamajek's M8 V: 0.114). Every O type came out B0's 31 400 K.

Both now read dwarfSequenceAtType, which already existed for the giants, and a G magnitude is
carried to V at the type's G-V too. On the published catalogue, of the 835 non-giant stars with
a band, a type and no colour, those more than 200 K off their type's row go from 21 to 0, those
with a radius more than 1.5 times off it from 7 to 1 and a luminosity from 10 to 1 (the one left,
Oph 11, is a G-band star). GJ 3849 (dM9) goes from 0.030 to 0.089 solar radii, GJ 3855 (M6.5)
from 0.040 to 0.087.

Two tests pinned the textbook path and now read the table: M5Ve with no colour is 3 060 K, not
3 106, and K5 tints as B-V 1.15, its row, not 1.105. An O8 star is 35 100 K, its row, not B0's.
Controls: reading the temperature through the textbook colour again fails "is drawn at its
type's row of the dwarf sequence" (with the three updated tests); reading the correction off the
anchors again fails that test alone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 15:41:01 +02:00
SenrokaiandClaude Opus 5.5 89c2568018 Describe the star at a system's centre as it is drawn now, not by the innermost-orbit rule and its halo
The README still said the star was sized against its innermost orbit and made visible by a halo,
two things 7213f98 and 2242fe0 removed. It now says what the view draws: the star at its own
radius on the orbits' scale, the archive's for a host and derived from luminosity and temperature
otherwise, marked "from colour and brightness" on the card; a limb-darkened disc in its
blackbody's colour, lighting its planets in that colour against the Sun's; a grey point where
nothing gives a size or temperature (5aac46d); the three-pixel floor and no halo; the camera held
at 0.05 AU or three radii, whichever is further, and a giant framed inside its neighbours' ring
(d1aa22e).

Measured on :4302 at 1600 by 1000 against published radii: Sun 1.0000 R☉ (card "1.00 solar
radii"); Proxima Centauri 0.1410, the archive's st_rad (0.154 in Boyajian et al. 2012); Sirius A
1.7943, derived, card "~1.8 solar radii, from colour and brightness" (1.711); TRAPPIST-1 0.1192
(0.119). The star's light: Sun (1, 1, 1), Proxima (1, 0.523, 0.165), TRAPPIST-1 (1, 0.443,
0.095), ups And (F8V) (0.899, 0.937, 1), Sirius (0.52, 0.666, 1), intensity pi in every one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 13:34:38 +02:00
SenrokaiandClaude Opus 5.5 a70a7290f3 Test that the host matcher carries an archive row back from J2015.5, where the constant only was
6d81c45 set ARCHIVE_EPOCH to Gaia DR2's 2015.5 and tested the constant's value, through
propagateProperMotion; nothing tested that resolveHostStarId uses it. The review's mutant that
carried the matcher's queries back from 2016 passed 807 of 807, since the GJ 15 A fixture's decoy
sits 16″ away and half a year moves the query 1.5″ there.

A new case gives resolveHostStarId Barnard's star's archive row (the J2015.5 position and motion
the epoch test already uses) and three stars: Barnard's at the row carried back 15.5 years, and
decoys where carrying it back 16 and 15 years lands, 5.2″ either side at its 10.4″/yr. It must pick
Barnard's. Controls: the matcher carrying back from 2016, or from 2015, each fail it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 00:19:38 +02:00
SenrokaiandClaude Opus 5.5 69a052730f Test that the system view warms a host's planets by the luminosity the archive gives it
d94451e passes the host's surface luminosity, the archive's st_lum where it has one, to the
SystemOrbitsRenderer that classifies each planet, and no test looked at what the renderer got: the
review's mutants that handed it the derived luminosity, none, or the Sun's all passed 807 of 807.
Its commit says 544 planet temperatures move by more than 10 % and 98 planets change class with it.

The scene spec now enters Proxima and checks that Proxima b's marker carries the texture of the
appearance 0.00151 L☉ gives it (228 K, temperate), after checking that null and 1 L☉ each give
another class, so that the texture can tell them apart. Controls: the renderer given
starSurfaceOf(star, []).luminositySolar (the fixture has no measured band, so none), null, or 1
each fail it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 00:15:31 +02:00
SenrokaiandClaude Opus 5.5 15b8f2dff3 Say which stars sit at the Gliese catalogue's distances, about half of them no parallax at all
f8af0ec rewrote the neighbourhood note to say where positions come from, and it still said
"measured parallaxes" for everything but the archive's hosts. 313 HYG stars besides the Sun have
neither a Hipparcos nor a Gaia distance and sit at HYG's own, which for these rows is the Gliese
catalogue's resulting parallax: fetchStars says as much ("as often photometric as measured"), and
the review's cross-match with CNS3 (Gliese & Jahreiss 1991, VizieR V/70A; not repeated here)
found about 154 of them with a photometric or spectroscopic parallax, 130 within 25 pc — GJ 3522
drawn at 4.46 pc, 1000/224 mas, with no trigonometric parallax behind it. positionsNote now counts
the HYG stars without a distance error, the Sun aside, and names them. In the app on :4302 the note
reads "Positions from measured parallaxes; for the 313 stars only the Gliese catalogue places, from
its distances, about half of them photometric; for the 3,277 planet hosts only the NASA Exoplanet
Archive places, from its distances." and still fits the readout panel in four lines.

Test: a new star-readouts case counts a Gliese row and leaves the Sun out; the archive-only case
now expects the semicolon. Controls: dropping the Gliese clause, and counting the Sun among the
Gliese stars, each fail it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 00:10:58 +02:00
SenrokaiandClaude Opus 5.5 5ab4c5df89 Say a planet has no temperature because its star's luminosity or its orbit is unknown, not its star
The card and the body page said "Its host star is not in the catalogue" for every planet without
an equilibrium temperature. Over the shipped data that is 2 714 planets, and the host really is
missing for 27. 2 420 have no semi-major axis, and since 869635b gave a star no survey measured no
luminosity, 267 more have a host that is on the map: OGLE-2005-BLG-390L b's card said so inside its
own host's system. The text now names both things that can be missing without claiming which:
"No temperature could be derived: its star's luminosity or its orbit's size is not known." In the
app on :4302, /body/OGLE-2005-BLG-390L b and /body/PSR J1719-1438 b read it.

Test: the object card's missing-temperature case now expects the new sentence and checks the old
claim is gone. Control: putting the old sentence back fails it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 00:07:18 +02:00
SenrokaiandClaude Opus 5.5 8f99335bae Give a luminosity below a hundredth of the Sun's two figures, so Proxima reads 0.0015 L☉ not 0.002
formatLuminosity printed three decimals from a thousandth to 1 L☉, which leaves one figure below
a hundredth. d94451e put the archive's own luminosity on the card, and Proxima's 1.51×10⁻³ L☉
(st_lum −2.821 ± 0.02 dex) read 0.002, 32 % over and six times the archive's error bar, while
8.9×10⁻⁴ just below the cut kept its two figures. Below 0.01 it is now two significant figures.

Over the 4 440 hosts exoplanets.json gives a luminosity for: 23 printed more than 10 % off it and
43 more than 5 % before (worst 32.5 %); none more than 5 % after (worst 4.4 %). In the app on
:4302, Proxima's card reads "Luminosity 0.0015 L☉".

Tests: quantity.spec now expects 0.0017 → "0.0017 L☉" and Proxima's figure → "0.0015 L☉", and
keeps 0.0523 and 0.523 at three decimals; star-readouts.spec and the scene spec now expect
"0.0015 L☉" where they pinned "0.002". Controls: three decimals below a hundredth, and two figures
reaching up to 1, each fail the named test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 00:04:47 +02:00
SenrokaiandClaude Opus 5.5 95ffb009a2 Tint each star in the field the colour its own disc is drawn in, a blackbody at its temperature
4191b70 carried BP−RP to the dwarf's B−V before the field's tint ramp read it, and said the Gaia
stars had been tinted redder than their own disc in the system view. They had been paler: the ramp
was white at B−V 0.8, a K0 dwarf, where a blackbody against the display's D65 is white near 6 500
K, B−V 0.44, and its red end, (1, 0.6, 0.35), was paler than an M dwarf's disc. After it 245 850 of
the 376 660 BP−RP stars were tinted bluish, 227 797 of them while their disc was warm. The field
now takes blackbodyColor at effectiveTemperatureK, the same function and the same temperature the
disc is drawn with, so a giant is tinted at its type's temperature too.

Over the shipped catalogue: stars bluish in the field with a warm disc 227 797 → 0, bluish at all
245 850 → 17 931, mean RGB distance from each star's field tint to its disc 0.250 → 0.001 (what is
left is the tint being cached at the nearest 10 K, which moves no channel by more than 0.0014). In
the app on :4302, field against disc after entering each star: Gaia DR3 6361559602963567744 (BP−RP
0.882, 5 543 K) (0.974, 0.982, 1) → (1, 0.854, 0.764) against (1, 0.854, 0.765); Gaia DR3
2026408043220034176 (1.84, 3 850 K) (1, 0.793, 0.664) → (1, 0.629, 0.34), the disc's own; HD 13531
(G0, B−V 0.70) (0.971, 0.979, 1) → (1, 0.86, 0.779), its disc's.

A blackbody per star cost 100 ms, and the scan of the table rows another 70, so the tint is cached
per 10 K and the table is bisected. Building the star field over the whole catalogue in the app
took 176-196 ms before and 151-159 after, four runs each.

Tests: a new case tints a G2 dwarf warm, exactly its 5 770 K blackbody, and Antares at the
temperature its type gives; the BP−RP render test now also checks an M0's blackbody. Controls: a
giant tinted at its colour's temperature, the tint taken against a bluer white than the disc's,
and a cache a hundred times too coarse each fail the named test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-30 00:00:43 +02:00
SenrokaiandClaude Opus 5.5 a8f394cf57 Read a giant's temperature off its type as well as its correction, so a radius has one source
d097f4b gave a giant its type's bolometric correction but left its temperature at the dwarf its
colour reads as, and the radius drawn from the two paired a correction for one star with the
temperature of another. The M giants stayed too cool (610 of them at a median 3 275 K, Antares
3 019 against Ohnaka et al.'s 3 660), and a hot giant behind dust got a 30 000 K star's correction
at the temperature of an A star: Menkib, O7.5 Iab at B−V 0.02, was drawn at 9 517 K and 95 R☉,
Alp Cam, O9.5 Ia, at 338, where 14 and 21 are published. Rigel went from 81 to 102 R☉, Alnilam
from 57 to 108.

giantSurface now reads both off the type: G to M giants off van Belle et al.'s (2021, table 8)
interferometric scale, fitted to 191 giants from G1 to M7.75 III, with the correction the dwarf
sequence has at that temperature; O to F giants off the dwarf of their type, for which the table
gains Mamajek's O3 to O9.5 rows (without colours, which do not tell O types apart); carbon and S
stars, which no row reads and which got the Sun's −0.06 at 2 420 K, off the medians of Bergeat et
al. (2001): 2 990 K over the 441 stars of their table 10 and −2.83 over the 383 with a V magnitude,
counted again from VizieR here.

On the shipped catalogue (drawn radius in R☉, before → after, published): Antares 690 → 410 at
3 730 K (680; its luminosity from V is 0.4 dex under Ohnaka's), Aldebaran 48.5 → 44.0 (44.2),
Arcturus 22.5 → 24.1 (25.4), Menkar 160 → 103, Gacrux 118 → 73, Rigel 102 → 67 (74.1), Alnilam
108 → 33, Menkib 95 → 6.9 (14, the dust still dims it), Alp Cam 338 → 31, La Superba 133 → 311
(315) and 544 → 6 977 L☉ (8 090 from Bergeat's bolometric magnitude), 19 Psc 130 → 305 (295).
The 610 M giants now sit at a median 3 644 K (p10 3 386, p90 3 816). Against their own radii
before, the O giants' fall to a median 0.08, the B giants' to 0.62, the M giants' to 0.68, and the
K giants' rise by 8 %. It is not better everywhere: Pollux goes from 8.6 to 10.1 against 8.8,
119 Tau from 700 to 326 against 587, and Mintaka and Alnitak, placed by Hipparcos at 212 and 226
pc where they are about 380, come out 8.8 and 11.8 against 13 to 20.

Tests: the giant case in stellar.spec now checks Antares's temperature against Ohnaka's, and
Aldebaran (to a tenth) and Rigel (to a fifth) against their interferometric radii; new cases give
Menkib its type's 36 100 K and a radius within 2.5 times the published one, and La Superba a
luminosity within a fifth of Bergeat's and 2 990 K; spectral.spec covers dwarfSequenceAtType. The
scene's supergiant case now expects Antares at 350-480 R☉ where it pinned 600-760. Controls:
the luminosity or the temperature ignoring giantSurface, G-M giants read as the dwarf of their
type, their correction taken off the type instead of their temperature, O giants through the
textbook colour clamped at B0, the type index off by one subclass and carbon stars unhandled each
fail the named test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 23:51:20 +02:00
SenrokaiandClaude Opus 5.5 06b4ff64b5 Read a white dwarf past the table's blue end at the temperature white dwarfs of its colour have
31e0c04 clamped an untyped star bluer than BP−RP −0.12 to the table's B9 row, so every one of the
110 white dwarfs within 50 pc was drawn at 10 700 K. Gentile Fusillo et al. (2021, MNRAS 508, 3877)
fit 104 of them at 14 266 to 39 304 K, and the radius their mass and gravity give was a median
0.65 of the one drawn. Past the table's end, dwarfSequenceAtColor now reads BP−RP off the median
pure-hydrogen temperature they fit in bins of ±0.025 around −0.15 to −0.40 (15 369 to 28 585 K,
counted again from the cross-match: 27, 24, 22, 15, 10 and 2 stars), and the correction and G−V
off the table's own rows at that temperature, through a new dwarfSequenceAtTemperature that
temperatureToColorIndex now shares.

Against GF21's R = sqrt(GM/g) over the same 104, the drawn radius goes from a median 1.53 (p10
1.33, p90 1.96) to 0.96 (0.94, 1.05), and the temperature from 0.59 of theirs to 1.00 (0.88,
1.02). Gaia DR3 6791196382856581376 is now 19 251 K and 0.0120 R☉, against their 19 205 K and
0.01245.

Tests: stellar.spec's −0.25 case now expects 19 012 K where it pinned 10 700, and a new case gives
that white dwarf its radius to within a fifth; spectral.spec reads −0.15, −0.13 and −0.6, keeps
the red end and B−V's blue end at their rows, and covers dwarfSequenceAtTemperature. Controls:
no white-dwarf branch, the bin's temperature without interpolating, B9's correction kept at the
new temperature, and the temperature read the wrong way round each fail the named test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 23:38:16 +02:00
SenrokaiandClaude Opus 5.5 18faa6d0b2 Classify a star for the rows that list it, not every star each time the index is built
The search index and the route index gave every one of the 455 571 stars a subtitle up front
through spectralClassification, which filtered the dwarf table afresh on each call; the star
field's tints read the same table once per BP−RP star. Both indices now carry the star itself
and classify it only for the rows shown (entrySubtitle): eight search results, a few route
options. The two filtered columns of the table are built once.

Node, over the shipped catalogue, five runs: classifying every star 121-167 ms before, 56-62
after hoisting the table alone; reading the sequence at every BP−RP colour 187-216 ms, now
111-127. In the app on :4302, two cold loads each, the long task when the Search tab opens was
264-380 ms (median 280) before and 164-276 ms (median 171) after; the longest boot task 863 and
875 ms before, 654 and 741 after.

Tests: the search spec checks its index holds no classification and the row still reads
"Star · ~M8"; the scene spec now reads the route options, and checks its index holds none either.
Controls: classifying every star in the search index, doing so in the route index, and route
options printing the index's subtitle each fail the named test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 23:30:53 +02:00
SenrokaiandClaude Opus 5.5 ff744a00de Place a naked-eye star HYG gives no distance for by its Hipparcos parallax, where that is 2.5 times its error
c64eea0 left out 41 naked-eye stars "because neither survey gives them a distance". Hipparcos does:
HYG's distances are 1 000 over van Leeuwen's 2007 parallaxes, which the ETL already downloads for
their errors, but HYG writes its 100 000 pc placeholder for every parallax under 1 mas whatever its
error, while keeping far less certain ones above it (Alnilam at 1.65 ± 0.45 mas is drawn). 30 of
the 41 have a positive parallax in the new reduction and 7 have one at least 2.5 times its error:
HD 74180 at 0.67 ± 0.16 mas (4.2 σ), Mu Cep at 0.55 ± 0.20.

hipparcosDistancePc (star-merge.ts, with HYG's placeholder constant moved beside it) keeps HYG's
distance and, where it gives the placeholder, takes 1 000 over the parallax when that is 2.5 times
its error; fetchHipparcosParallaxErrors now returns the parallax with its error. From cache the ETL
keeps 73 563 HYG rows against 73 556 and publishes 455 571 stars; the seven are Alp Cam (1.4 to 3.0
kpc), Psi-1 Aur, HD 74180 (1.2 to 2.0 kpc), HD 86352, HD 96918, Mu Cep (1.3 to 2.9 kpc) and HD
217476, each printed as the range its parallax's error gives. The other 34 stay out: no parallax,
or one within 2.5 times its error of zero. Parallax distances printed as ranges go from 1 109 to
1 116; the validators hold.

Controls, each failing its named test: placeholder rows given no distance, and any parallax 1.25
times its error placing a star (1 of 807 each).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:45:12 +02:00
SenrokaiandClaude Opus 5.5 8c3a86097c Place a star at whichever of its two distances is the more precise, not at Gaia's regardless
placementDistancePc took Gaia's distance wherever the cross-match gave a usable one, and its
docstring and c64eea0 called that "the better measurement", adding that Gaia saturates on the
brightest stars "so those sit at their Hipparcos distance". For 273 of the 88 781 HYG stars with
both, Gaia's relative error is the larger, 257 of them naked-eye and 38 by more than twice: Eta Leo
was drawn at Gaia's 556.6 pc ±17 % against Hipparcos's 389 pc ±6.2 %, Schedar and Tarazed at
Gaia's though both have Gaia G of about 2.

placementDistancePc now takes both relative errors and picks the smaller, Gaia's as before when
either is missing; fetchStars gives the placed star the error and the Gaia-distance flag of the
distance it took. The merge's combine keeps the Gaia entry's direction, and now takes the other
entry's distance with its error where that is the more precise, so a bright star Gaia's main query
also holds lands at its Hipparcos distance too. Gaia still wins for the rest, whose parallaxes are
some fifty times more precise.

From cache: 424 stars move, 386 of them naked-eye; HYG rows at Gaia's distance 58 379 -> 58 109 and
HYG stars flagged so 8 129 -> 8 095. Eta Leo 556.6 -> 389.1 pc, Tarazed 178.9 -> 121.1, Imai 139.5 ->
105.8, Schedar 71.0 -> 70.0, Alphecca 23.7 -> 23.0, each now "±" its Hipparcos error. Where the two
disagree by more than 5 σ (21 stars, Iot Gem 11 σ), one of the formal errors is wrong, and this
takes the smaller one at its word. The validators pass unchanged.

Controls, each failing its named test: the placement ignoring the errors, the merge keeping Gaia's
distance whatever the errors, and taking the distance but not its error (1 of 805 each).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:37:35 +02:00
SenrokaiandClaude Opus 5.5 23547defe0 Read an archive host's colour off the dwarf sequence at its temperature, and say it was not measured
For an archive-placed host with a temperature and no B magnitude, fetchExoplanets took B−V from
Ballesteros' blackbody fit, which runs 0.1 to 0.2 redder than Pecaut & Mamajek's dwarf sequence
below 3 800 K, and the luminosity then read its correction off that sequence at that colour: 3 500 K
came back as 3 102 K with a correction 1.15 magnitudes too large, anything under about 3 170 K was
clamped to B−V 2.00, and the card printed it as a measured "Colour B−V 2.00". CFBDSIR
J145829+101343, a 580 K brown dwarf, read "Spectral type ~M6, from colour".

temperatureToColorIndex now reads the table itself backwards, interpolating B−V between the two
types the temperature falls between, so the temperature and correction read back off the colour
are the table's at that temperature; it has no answer outside 2 420 to 31 400 K. The colour is
flagged colorFromTemperature, a fifth bit in the photometry byte (the format, README and the ETL's
round-trip check follow), and the card prints it "B−V 1.66, from its temperature", marked derived.

From cache: 57 archive stars change colour; 54 carry the flag and 3, CFBDSIR J145829+101343 among
them, now have none. For the 47 of them the archive gives a luminosity, the one derived from
magnitude and colour moves from a median 0.228 dex off it to 0.124; Kepler-445 (3 157 K) from
0.0282 L☉ to 0.0080 against the archive's 0.0079. Its colour goes from 2.00 to 1.67. The card shows
the archive's luminosity where it has one since earlier on this branch, so this is the figure used
for the rest and for their radii.

Controls, each failing its named test: the nearest hotter row taken without interpolating (2 of
803 failed), no refusal outside the table, the flag not encoded, and the card calling the colour
measured (1 of 803 each).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:29:09 +02:00
SenrokaiandClaude Opus 5.5 f82b5e1c74 Hold the published catalogue to what its host radii, distance errors and Gaia-distance flags come to
Three things the branch added could vanish from the data with every check passing, as the review
showed with guarded ETL mutants: dropping st_rad or st_teff from each planet left 0 of 6 354
carrying their host's radius or temperature, storing Gaia's parallax_error in milliarcseconds
rather than over the parallax changed 431 464 distance readouts, and dropping the flag fetchStars
sets relabelled 8 129 HYG stars placed at Gaia's distance "HYG". The round trip compares decoded
with encoded, and the counts of missing bands and errors do not look at what the values are.

validateExoplanets now requires 90 % of planets to carry their host's radius and temperature
(measured 6 030 and 6 054 of 6 354). validateStars requires the median relative error of the
distances at Gaia's to be under 1 % (measured 0.33 %), at most 1 % of stars to have a parallax
distance with an error of a fifth or more (measured 1 109, 0.24 %; the archive's, which are on the
distance and never ranged, are left out), and at least 6 000 HYG stars flagged at Gaia's distance
(measured 8 129). Figures from an ETL run from cache on this branch.

Each proved by a guarded mutant in a scratch copy of the ETL, run from the cache, failing with its
own message: host radius dropped ("Only 0 of 6354 exoplanets carry their host's radius and 6054 its
temperature"), host temperature dropped ("6030 ... and 0"), the Gaia error left in mas ("The median
error of Gaia's distances is 1.92 %"), the same with the median check waived ("17689 parallax
distances have an error of a fifth or more"), and the flag dropped ("Only 0 HYG stars are flagged
at Gaia's distance"); a no-op edit completed. No ceiling is loosened.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:20:38 +02:00
SenrokaiandClaude Opus 5.5 6d81c45f45 Carry the archive's positions back from Gaia DR2's J2015.5, where it publishes them, not J2016
fetchExoplanets placed each star it adds from the Exoplanet Archive by carrying the archive's
position back sixteen years, and 4c8e4a0 said the archive publishes at Gaia's J2016. It does not:
its positions are Gaia DR2's at J2015.5 although it names the DR3 source. Barnard's star in the
archive, 269.4486144, 4.7379808, equals DR2 4472832130942575872 at J2015.5 to 1e-7°, and sits 5.2″
from DR3's J2016 place; the review found 66 of the 67 archive-placed stars moving over 100 mas a
year within 0.21 mas of their DR2 position and none within 1 mas of DR3's. The matcher's comment
made the same claim of HD 133131 and TOI-2459, whose positions are DR2's too.

host-star-matching.ts now exports CATALOGUE_EPOCH and ARCHIVE_EPOCH = 2015.5, the matcher carries a
query back by their difference, and fetchExoplanets uses the same two, so the epoch is written
once. From cache: only the 3 277 archive-placed stars move, 2 287 of them by more than a
milliarcsecond, 74 by more than 50 and TOI-2406 most, by 203 mas, half a year of its 405 mas/yr;
no planet changes host. Invisible at map scale; the point is that the constant and its comments
now say what the archive does.

Control: ARCHIVE_EPOCH back to 2016.0 fails "carries Barnard's star from the archive's position to
where Gaia DR3's goes, to a few milliarcseconds" (1 of 802), which puts the two 5.2″ apart. The
GJ 15 A matching fixture is now built at J2015.5 too. fetchExoplanets' use of the constant has no
test of its own; the ETL has no test harness.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:20:26 +02:00
SenrokaiandClaude Opus 5.5 62f81f2c43 Number the stars the archive places after their host's name, so a refresh keeps each one's id
4c8e4a0 numbered each star it adds from the Exoplanet Archive by its place among the unmatched
hosts, in pl_name order, and the refresh workflow re-queries the archive every Monday. One host
added or dropped ahead of another renumbers it: in the review, removing a single planet row
renamed 3 276 of the 3 277 ids, and a bookmark kept on Kepler-186 (1070001620) opened Kepler-1860
under Kepler-186's stored name. HYG's and Gaia's ids do not move between refreshes; the merge's own
comment says ids are meant to hold.

archiveStarId (host-star-matching.ts, beside the matcher the ETL already imports from there) hashes
the host name with FNV-1a into the 3.7 million ids between 1 070 000 000 and 2^30, and moves a name
whose id is taken to the next free one. The added stars are sorted by id before they are appended,
so the published list stays in id order. Measured: all 4 237 archive-hosted planets change host id
once (Kepler-186 is now 1073671518), none of the others; one of the 3 277 names was probed past a
collision, and one new id falls in the old 1070000000-1070003276 range, so a bookmark saved on that
old id would open the wrong star once. Dropping the same row from a copy of the cached answer and
rerunning the exoplanet step in a scratch copy of the ETL now leaves 3 276 of 3 276 ids unchanged.
The validators pass: no duplicate id, all under 2^30.

Controls, each failing its named test: the id taken from the order of arrival, and no probing past
a taken id (1 of 801 each).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:12:00 +02:00
SenrokaiandClaude Opus 5.5 1a8e734651 Leave the dark nebulae out of the backdrop, whose sprites can only add light
c01d3ec read OpenNGC's addendum, which brought in its only two DrkN rows, C099 the Coalsack and
B033 the Horsehead; NGC.csv has none. classifyOpenNgcType mapped DrkN to 'nebula', so both were
drawn as the backdrop's nebula sprite: ff86b0, additive, at the faintest opacity and the 70 pc
minimum size, about 1.6° across. The review measured it adding up to +59 in red over the Coalsack
beside Crux, where the sky has a dark hole, and darkening no pixel, as an additive sprite cannot.

DrkN is now among the codes dropped, with the reason beside the map. fetchDeepSky from cache keeps
488 objects against 490, still 107 Messier objects and every required id; README's count follows.
On :4302 the served backdrop holds 488 objects and the scene 488 sprites, neither of them C099 or
B033.

Control: DrkN mapped back to 'nebula' fails "leaves out a dark nebula, which a sprite that adds
light cannot draw" (1 of 801).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 21:00:31 +02:00
SenrokaiandClaude Opus 5.5 0e9ab6ffb5 Fold the Gliese entries that move with a Gaia star up to 160″ away, where a minute left 39 twice
74b93a0 let a Gliese-only HYG row fold into a Gaia entry that moves with it up to a minute of arc
away, since Gliese's positions are off by that much. Its report counted only the 3-60″ residue.
Measured on the published catalogue with the merge's own motion and brightness rules, 39 Gliese
rows within 25 pc still had a bare Gaia entry moving with them 60 to 150″ away (32 within 100″,
none past 150); with every row shifted a quarter of a degree north or south, none did. The review
found 36 of them to be the same star under SIMBAD, three within 10 pc: GJ 3618 (LHS 288) at 4.49 pc
beside its Gaia entry at 4.83 pc 94″ away, GJ 1123 at 8.13 and 9.52, GJ 1001 at 9.60 and 12.31.

MERGE_COMOVING_ANGULAR_TOLERANCE_DEG is now 160″. The ETL from cache folds 62 046 entries against
62 002, leaves 11 510 HYG rows without a counterpart against 11 554, and publishes 455 564 stars;
within 10, 25 and 50 pc the map now holds 369, 5 523 and 40 877 against 372, 5 564 and 40 921
(GCNS: 312 Gaia sources within 10 pc). No Gliese row within 25 pc has a co-moving bare Gaia entry
3-300″ away any more. GJ 3618, GJ 1123, Gl 319C and GJ 3999A now sit on Gaia entries. One
exoplanet changes host id: LHS 475 b's Gaia entry took HYG's id with its description.

Not every name lands where SIMBAD would put it: Gl 319C takes the entry SIMBAD calls GJ 319 B, as
HYG's Gl 319B already sat on SIMBAD's C, and GJ 3999A takes the entry named GJ 4000B before, which
moves to the bare one beside it. Both systems go from one entry too many to one per star; the
names follow HYG's positions, which only identifiers could correct. The merge validators hold: 23
cross-catalogue pairs within an arcsecond, as before.

Controls, each failing its named test: the window back to a minute (2 of 801 failed), and 200″
(1 of 801).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 20:59:05 +02:00
SenrokaiandClaude Opus 5.5 150ec76bbd Say that a host's radius, temperature and luminosity come from the composite table alone
The comment on hostStarRadiusSolar and its two neighbours said they were read from "the planet's
default row first, then the composite table". The default-row query (TAP_COLUMNS in
fetchExoplanets.ts) asks for none of st_rad, st_teff or st_lum — the cached answer's columns end at
st_mass and disc_year — so host() always reads them from pscomppars, whose columns may each cite a
different reference: Proxima's 0.141 R☉ is the composite table's. It also said they were measured
where stellar.ts derives a luminosity, which held for the luminosity only once starSurfaceOf began
reading st_lum, earlier on this branch; it now points at starSurfaceOf. A comment, so there is no
test to fail.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 20:50:42 +02:00
SenrokaiandClaude Opus 5.5 4ebe663a84 Carry the Hipparcos parallax errors between weekly refreshes, as the Gaia answers already are
a81dd49 added a query of public.hipparcos_newreduction on the ESA archive, cached as
hipparcos-errors-<hash>.csv, and fetchStars requires it: a failed or short answer throws. The
refresh workflow carries only tools/etl/.cache/gaia-dr3-*.csv between runs, a glob that file does
not match, so every weekly run fetched its 117 955 rows live from the archive the cache exists to
spare, and an ESA outage would have failed the refresh even with every Gaia answer cached. Before
a81dd49 a warm cache meant no request to that archive at all.

The cache step now lists both globs. Its key gains "-hipparcos": actions/cache keys are immutable,
and an entry already saved under the old key would be restored without the new file and never
saved again. Checked with Node's path.matchesGlob against the local cache (gaia-dr3-54fdbc7a,
gaia-dr3-hip-785b92fc and hipparcos-errors-f846b045 match, the archive's own files do not) and by
parsing the workflow with PyYAML. A workflow file has no unit test to fail without the change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 20:46:29 +02:00
SenrokaiandClaude Opus 5.5 08bf8b18a6 Test that a Gaia star with no measured band is still labelled Gaia's
describingCatalogue calls a star Gaia's when its source is gaia and its band is not V. 44 Gaia
sources in the shipped catalogue have no G (Gaia DR3 40091256260676736 among them), and nothing
tested them: narrowing the rule to band G, which would relabel all 44 "HYG" and count them as HYG
in the neighbourhood census, passed the suite. The existing test already builds such a star and
now checks its Source row as well.

Control: the rule narrowed to band G fails "says a stand-in magnitude was not measured, and leaves
out a colour there is none of" (1 of 797).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 20:43:51 +02:00
SenrokaiandClaude Opus 5.5 f8af0ecf6e List stars in search and routes by the type their colour gives them, and say where archive positions come from
5333be6 gave the star card an estimated type for the 383 695 stars the ETL files as "Unknown",
but search rows, the route search index and the current-star route option still printed that
literal: TRAPPIST-1 read "STAR · UNKNOWN" in search beside "Spectral type ~M8, from colour" on its
card, audit #17's own symptom. spectralClassification (spectral.ts) now gives the catalogue's type,
else the colour's marked "~", else nothing, and all three and the card's subtitle use it; a search
row with nothing to add prints its kind alone rather than a trailing " · ".

The neighbourhood note still read "Positions from measured parallaxes" after 4c8e4a0 placed 3 277
stars at the Exoplanet Archive's sy_dist, 343 of them without a usable parallax and 281 of those
past 1 kpc — microlensing hosts such as OGLE-2005-BLG-390L at 6.6 kpc, from a lensing model.
positionsNote now says so, with the count. Neither the note nor the census subtitle (audit #16) had
a test: putting back "Hipparcos · Yale Bright Star · Gliese" passed all 775.

In the app on :4302: the note reads "Positions from measured parallaxes, and for the 3,277 planet
hosts only the NASA Exoplanet Archive places, from its distances. Grid marks the galactic plane
through the Sun."; search reads "TRAPPIST-1 STAR · ~M8", "OGLE-2005-BLG-390L STAR", "Sirius STAR ·
A0M"; TRAPPIST-1's route option has subtitle "~M8".

The scene spec gains an archive-placed fixture star. Controls, each failing its named test: the
search row printing the raw type, keeping the separator with nothing after it, the route index
and the current-star option printing the raw type, the note back to parallaxes only, the subtitle
back to the old catalogue list (1 of 797 each), the note never counting the archive (2 of 797),
and the classification without its estimate (3 of 797).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 20:42:03 +02:00
SenrokaiandClaude Opus 5.5 4191b70e63 Tint a star measured in Gaia's BP−RP as the B−V of the dwarf of that colour
colorIndexToRgb maps a B−V onto the star field's tint ramp, and its one caller passed it every
star's colour index, whatever colorSystem said. BP−RP is the larger of the two for the same star —
0.823 against 0.65 for a G2 dwarf, 1.84 against 1.42 for an M0 (Pecaut & Mamajek) — so the 376 703
stars measured in it, 83 % of the catalogue, were tinted as later types than they are, and redder
than HYG's stars of the same type, and than their own disc in the system view.

A BP−RP is now carried to the B−V of the dwarf sequence at that colour (the table's own B−V
column, which DwarfSequencePoint now returns, clamped at its ends), then tinted as before. The
median Gaia colour, BP−RP 0.883, a G7 dwarf, read as a K2: its tint goes from (1, 0.972, 0.955) to
(0.975, 0.982, 1), the same as HYG's G7 stars.

Controls, each failing its named test: BP−RP read as B−V (2 of 792 failed), the star field not
passing the colour system (1 of 792), and the B−V taken from the wrong column (3 of 792).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-29 20:31:27 +02:00