Skip to content

Commit beb3323

Browse files
Rewrite NORTHSTAR.md for an outside reader (v0.14.3)
The manifesto was written in the shorthand of the conversations that produced it. Dropped the internal "Target / 110%" pillar table (→ four plain commitment statements), the "purity is an instrument, not an identity" in-joke, the struck-through "no parsing, ever" amendment (changelog history, not manifesto), and the "SOTA" bravado. Principles and scope rule kept — they already read for an outsider. No code changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 53a923d commit beb3323

3 files changed

Lines changed: 58 additions & 43 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes. The project follows semver; until 1.0, minor versions
44
may adjust APIs (taken so far, both pre-npm: `dischargeSPD``emissionSPD`
55
in 0.12.0, `sodiumSPD``lowPressureSodiumSPD` in 0.13.0 — see below).
66

7+
## 0.14.3 — 2026-06-13
8+
9+
Docs only. Rewrote NORTHSTAR.md for an outside reader: dropped the internal
10+
"Target / 110%" pillar framing, the "purity is an instrument" in-joke, and the
11+
struck-through "no parsing, ever" amendment (that history lives here in the
12+
changelog, not the manifesto). The design principles and scope rule are
13+
unchanged in substance — only the insider shorthand is gone. No code changes.
14+
715
## 0.14.2 — 2026-06-13
816

917
Docs correctness. Audited the "Honest comparison" table against the *current*

NORTHSTAR.md

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,57 @@
33
> **A research-grade color laboratory for the web.**
44
> **Every color space, every illuminant — digit-identical in JS, GLSL, and WGSL.**
55
6-
Every conversion is generated from one table of cited constants. The matrix that
7-
runs in your JavaScript is the matrix that runs in your shader — and CI verifies
8-
it to the last digit. Stop hand-porting color matrices.
9-
10-
## Pillars
11-
12-
| Pillar | Target | 110% |
13-
|---|---|---|
14-
| **Coverage** | All 14 CSS Color 4 spaces + OKHSL/OKHSV; full CIE illuminant table + arbitrary white points; gamut checking *and* gamut mapping | Illuminants from correlated color temperature (`illuminantFromCCT`); CAT02/CAT16/von Kries alongside Bradford |
15-
| **Verified precision** | Every conversion tested against derivational invariants and spec fixtures; round-trip bounds CI-enforced; every constant carries a citation | Differential testing against culori, colorjs.io, and @texel/color as oracles; precision-bounds table in the README, generated by CI |
16-
| **Everywhere** | Core imports clean in Node / SSR / workers; GLSL + WGSL + JS emitted from a single descriptor pipeline over single-sourced constants | GPU parity tests in CI; shader-side gamut mapping |
17-
| **Speed** | Zero-allocation out-param paths; precomposed routes; honest published benchmarks | SOTA: nothing maintained is faster, on conversion or gamut mapping — measured with @texel/color's own suite |
6+
What this library is for, and the rules it holds itself to. Every conversion is
7+
generated from one table of cited constants — the matrix that runs in your
8+
JavaScript is the matrix that runs in your shader, verified in CI to the last
9+
digit. That one idea drives everything below.
10+
11+
## What it commits to
12+
13+
- **Coverage.** Every CSS Color 4 space plus OKHSL/OKHSV; the CIE illuminants and
14+
arbitrary white points; chromatic adaptation across multiple transforms
15+
(Bradford, CAT02, CAT16, von Kries); illuminants from correlated color
16+
temperature; gamut *checking* and gamut *mapping*; and a spectral layer (color
17+
matching functions, Planck's law, daylight, emission).
18+
- **Verified precision.** Conversions are tested against derivational invariants,
19+
spec fixtures, and the other major libraries as oracles (culori, colorjs.io,
20+
@texel/color). Round-trip error bounds are CI-enforced and published — measured,
21+
never implied.
22+
- **Portability.** The core imports cleanly in Node, SSR, and workers, and one
23+
pipeline emits JS, GLSL, and WGSL from the same constants — with CPU/GPU parity
24+
checked in CI, so a color is identical on both.
25+
- **Speed.** Zero-allocation paths and precomposed routes, with benchmarks that
26+
are public and reproducible (`npm run bench`).
1827

1928
## Principles
2029

2130
1. **Derive, don't transcribe.** RGB↔XYZ matrices are computed at module load
22-
from cited primaries and white points. A hardcoded matrix is a transcription
23-
error waiting to happen; a derived one is checked against published values in CI.
24-
2. **One source of truth.** Constants live in one table. JS functions, GLSL
25-
strings, and WGSL strings are all views of that table.
26-
3. **Precision is a contract.** No rounding inside conversions. Bytes exist only
31+
from cited primaries and white points, then checked against published values
32+
in CI. A hardcoded matrix is a transcription error waiting to happen.
33+
2. **One source of truth.** Constants live in one table; the JS functions, GLSL
34+
strings, and WGSL strings are all views of it.
35+
3. **Precision is a contract.** No rounding inside conversions — bytes exist only
2736
at the explicit `toBytes`/`fromBytes` boundary. Error bounds are measured,
28-
published, and enforced — never implied.
29-
4. **The math is honest about itself.** Hue is undefined at zero chroma; CSS
30-
white points differ from CIE 15 values in the fifth digit; gamut mapping is
31-
lossy. We document these instead of papering over them.
32-
33-
## Scope rule
34-
35-
**If a frozen spec defines it on coordinates, implement it exactly; strings
36-
on the way out only; constants still in motion wait.**
37-
38-
## Anti-goals
39-
40-
- No color wrapper class — plain arrays in, plain arrays out
41-
- ~~No CSS string parsing, ever~~**amended at v0.8**: purity is an
42-
instrument, not an identity. Strings are how colors arrive in the world,
43-
so the frozen Level 4 grammar is in scope — behind a fenced boundary
44-
(src/parse): the conversion core never sees a string, `none` becomes NaN
45-
under the numerical policy, and still-moving grammar (Level 5 relative
46-
color syntax) waits like every other unfrozen spec
47-
- Alpha is not a color coordinate — the conversion core stays 3-channel;
48-
spec-defined alpha interactions (premultiplied mixing, serialization) are
49-
separate, consistently 4-channel entry points
50-
- No palettes, harmonies, color naming, or gradient objects — those belong
51-
to applications (spec-defined interpolation itself is in scope)
52-
- No unfrozen perceptual models (APCA waits for WCAG 3 to freeze)
37+
published, and enforced.
38+
4. **The math is honest about itself.** Hue is undefined at zero chroma; the CSS
39+
white points differ from the CIE 15 values in the fifth digit; gamut mapping
40+
is lossy. The library documents these rather than papering over them.
41+
42+
## Scope
43+
44+
One rule decides what belongs here: **if a frozen spec defines it on
45+
coordinates, implement it exactly; parse strings only at a fenced boundary;
46+
anything still in motion waits.**
47+
48+
Out of scope, on purpose:
49+
50+
- **No color wrapper class** — plain arrays in, plain arrays out.
51+
- **Strings only at the edge.** Parsing covers the frozen CSS Color 4 grammar
52+
behind a fenced module the conversion core never sees; CSS Level 5
53+
relative-color syntax and calc() wait until the spec freezes.
54+
- **Alpha is not a color coordinate** — the conversion core stays 3-channel;
55+
alpha-aware operations (premultiplied mixing, serialization) are separate,
56+
4-channel entry points.
57+
- **No palettes, harmonies, color naming, or gradient objects** — those belong
58+
to applications. (Spec-defined interpolation itself is in scope.)
59+
- **No unfrozen perceptual models** — APCA returns when WCAG 3 freezes.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "whitepoint",
3-
"version": "0.14.2",
3+
"version": "0.14.3",
44
"description": "Research-grade color math: every CSS color space, arbitrary illuminants, CATs, and CCT — digit-identical in JS, GLSL, and WGSL.",
55
"type": "module",
66
"main": "./src/index.js",

0 commit comments

Comments
 (0)