Skip to content

Commit c5c2182

Browse files
committed
docs(spec): state the residual bound the changeset states, and point the ADR-0087 marker at the right bullet
F1 — `packages/spec/src/data/numeric-column-representation.ts`'s "residual bound" section said only that magnitudes below 1e-30 round to zero, while the shipped changeset states the column keeps 30 fractional digits, that precision loss BEGINS around |x| < 1e-13 and is TOTAL below 1e-30, and that magnitudes at or above 1e35 are refused. That docblock is the canonical home both `sql-driver.ts` and `os generate migration` point readers at ("the spec module carries the measurements, the ruling and the residual bound"), and it says of itself that the bound is "stated here so no reader has to rediscover it" — so it now states both ends of the bound in the changeset's own terms. F2 — `.changeset/numeric-column-representation.md` said "Three consequences" above four bullets, and its ADR-0087 marker claimed "bullet 3 IS a prescription" where bullet 3 is the read-seam bullet and the prescription is bullet 4 (the `NOT NULL` / `storage.notNull` one). The marker is the auditable artifact the gate prints verbatim, so a wrong internal pointer defeats its purpose. Exactly one `adr-0087:` marker, same category and same argument. Docblock and changeset prose only: no behaviour change, no schema move, no test edit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Js5kTpTtxieBjPyScgxJ3
1 parent 0348567 commit c5c2182

2 files changed

Lines changed: 15 additions & 8 deletions

File tree

.changeset/numeric-column-representation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ the write-time contract the record validator enforces, and binding the DDL to it
3636
post-deploy tightening a destructive migration.
3737

3838
**BREAKING** — new columns only; no existing column is retyped, no migration is planned, and no
39-
backfill runs. Three consequences to know before creating new tables:
39+
backfill runs. Four consequences to know before creating new tables:
4040

4141
- `rating` is an INTEGER column, and the two server dialects dispose of a fractional star count
4242
DIFFERENTLY — do not read one answer for both. PostgreSQL REFUSES `4.5` outright, where a
@@ -67,4 +67,4 @@ backfill runs. Three consequences to know before creating new tables:
6767
SQLite emits byte-identical DDL for the six exact-decimal members: knex compiles both
6868
`table.decimal(name, p, s)` and `table.float(name)` to the same `float` column there.
6969

70-
<!-- adr-0087: not-required (no-migration-prescription) Claimed on a POSITIVE argument, not on the detector finding nothing — the failure mode this gate's own docblock names (#8277). Stated plainly: bullet 3 IS a prescription, and it is a prescription for a SOURCE AUTHOR, not for a metadata upgrader, which is the distinction ADR-0087's D8 addendum says this category cannot mechanically tell apart. The ledger serves `objectstack migrate meta`; the only ledger entry this change could carry is the `field-required-notnull-explicit` conversion, and that conversion was WITHDRAWN by maintainer ruling on 2026-09-08 (decision batch #85, #16693/#16890) on the ground that stamping `storage.notNull` wherever `required: true` appears is the implication ADR-0113 abolished — `packages/spec/src/conversions/registry.ts` now carries a tombstone saying re-adding one is the mistake it exists to stop. So `registered` is FORBIDDEN here, not merely unnecessary. The other four are closed on facts: the bumped packages publish (not `unpublished`); no id pre-dates the base (not `already-registered`); no named symbol is a non-metadata runtime interface (not `runtime-interface-only`); and `type-surface-only` fails its predicate 2, since this diff adds a module under `packages/spec/**`. The numeric half prescribes nothing at all — no spec key, no export and no config field is removed or renamed, existing sources parse and publish unchanged, and existing columns are untouched by the ruling that authorized this (「不考虑现有数据」). ⚠️ The residual is declared rather than hidden: the vocabulary has no category for a source-author prescription the ledger must not carry, which is D8's blind spot reached from a second direction; raised for the maintainer in the PR report rather than resolved by dropping the BREAKING banner. -->
70+
<!-- adr-0087: not-required (no-migration-prescription) Claimed on a POSITIVE argument, not on the detector finding nothing — the failure mode this gate's own docblock names (#8277). Stated plainly: bullet 4 (the `NOT NULL` one) IS a prescription, and it is a prescription for a SOURCE AUTHOR, not for a metadata upgrader, which is the distinction ADR-0087's D8 addendum says this category cannot mechanically tell apart. The ledger serves `objectstack migrate meta`; the only ledger entry this change could carry is the `field-required-notnull-explicit` conversion, and that conversion was WITHDRAWN by maintainer ruling on 2026-09-08 (decision batch #85, #16693/#16890) on the ground that stamping `storage.notNull` wherever `required: true` appears is the implication ADR-0113 abolished — `packages/spec/src/conversions/registry.ts` now carries a tombstone saying re-adding one is the mistake it exists to stop. So `registered` is FORBIDDEN here, not merely unnecessary. The other four are closed on facts: the bumped packages publish (not `unpublished`); no id pre-dates the base (not `already-registered`); no named symbol is a non-metadata runtime interface (not `runtime-interface-only`); and `type-surface-only` fails its predicate 2, since this diff adds a module under `packages/spec/**`. The numeric half prescribes nothing at all — no spec key, no export and no config field is removed or renamed, existing sources parse and publish unchanged, and existing columns are untouched by the ruling that authorized this (「不考虑现有数据」). ⚠️ The residual is declared rather than hidden: the vocabulary has no category for a source-author prescription the ledger must not carry, which is D8's blind spot reached from a second direction; raised for the maintainer in the PR report rather than resolved by dropping the BREAKING banner. -->

packages/spec/src/data/numeric-column-representation.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,19 @@
9898
* ## The residual bound, stated rather than assumed
9999
*
100100
* An exact-decimal column is bounded where a float is not, so this table is
101-
* not lossless in every direction. Magnitudes below 1e-30 round to zero and
102-
* magnitudes at or above 1e35 are REFUSED, where today's `real` keeps about
103-
* seven significant digits out to ~1e38. Two things make that the right
104-
* trade: a refusal is loud and a silent rounding is not, and the sql format's
105-
* `numeric(18,2)` already refuses everything at or above 1e16 today. It is a
106-
* bound, and it is stated here so no reader has to rediscover it.
101+
* not lossless in every direction, and the bound has two ends. Downward, the
102+
* column keeps 30 fractional digits, so a magnitude whose significant digits
103+
* run past the 30th decimal place loses the tail silently:
104+
* `1.2345678901234567e-15` stores as `0.000000000000001234567890123457`.
105+
* Precision loss therefore BEGINS around |x| < 1e-13 — where a double's ~17
106+
* significant digits first reach past the 30th decimal place — and is TOTAL
107+
* below 1e-30, where nothing is left and the value rounds to zero. Upward,
108+
* magnitudes at or above 1e35 are REFUSED (the 35 integer digits that
109+
* 65 - 30 leaves), where today's `real` keeps about seven significant digits
110+
* out to ~1e38. Two things make that the right trade: a refusal is loud and a
111+
* silent rounding is not, and the sql format's `numeric(18,2)` already
112+
* refuses everything at or above 1e16 today. It is a bound, and it is stated
113+
* here so no reader has to rediscover it.
107114
*
108115
* ## SQLite, per type — the constraint the report raised, answered
109116
*

0 commit comments

Comments
 (0)