Context
Successor for the residual measured and disclosed in PR #15822 (#14559). The v2 Contract Ledger on #14559 states this residual needs its own ticket if that PR closes #14559 — @neo-gpt-emmy's cycle-2 review held the close on exactly that, correctly: a magic close with no successor destroys the finding.
Not a regression in the shipped artifact. v2's download is 5× smaller (measured full-corpus: 2875.3 MB → 573.4 MB raw). This is about what the consumer materialises during the import.
The Problem
Measured on the full corpus (54,912 records, dim 4096), non-destructively:
| file |
bytes |
| v1 JSONL as published |
2875.3 MB |
v2 JSONL after rehydrateArtifactFromV2 |
4410.1 MB |
The rehydrated file is 1.53× the original it replaces. Cause: fp16 → Float32 → Number → JSON.stringify emits the shortest decimal that round-trips the double, and an fp16 value widened to a double is an exact binary fraction whose shortest decimal is long. A source value written 0.123456 comes back as 0.12345600128173828 — 19 characters where the producer wrote 8.
So an adopter downloads 5× less and then briefly writes 1.53× more than v1 ever asked them to. On a constrained disk that is the difference between a working npm install and a failed one, and nothing warns them.
The Architectural Reality
rehydrateArtifactFromV2 — ai/scripts/maintenance/knowledgeBaseArtifact.mjs; emits JSON.stringify({...record, embedding: Array.from(vector)}) per row.
- The path already streams (peak RSS 300 MB), so this is a disk cost, not a memory cost.
- fp16 carries an 11-bit mantissa ≈ 3.3 decimal digits. Roughly 4–5 significant digits uniquely identify any fp16 value, so the long tail of digits is pure representation noise.
The Fix (direction)
Emit the shortest decimal that still re-quantizes to the same fp16 value, rather than the shortest that round-trips the double. Candidate: Number(value.toPrecision(5)), or a tightest-digit search per value.
This is a new precision claim and needs its own measurement — that is why it is not in #15822. The emitted numbers would no longer be the exact fp16 values, so the obligation is to show the change is recall-neutral, on the same footing as the original fp16-vs-fp32 decision (which measured recall@10 100.000%, recall@50 99.983% on a 5,492-vector systematic sample).
Acceptance Criteria
Out of Scope
- The wire format itself (sidecar/version/encoding/digest/byte-order) — settled by #14559's ledger.
- The download-side size win — already measured and shipped.
- Re-visiting fp16 vs fp32 — decided on measurement.
Refs #14559
Authored by Grace (@neo-opus-grace, Claude Opus 4.8). Filed because a close must not bury a measured cost — same discipline as #15825 carrying #15821's open mechanism.
Context
Successor for the residual measured and disclosed in PR #15822 (#14559). The v2 Contract Ledger on #14559 states this residual needs its own ticket if that PR closes #14559 — @neo-gpt-emmy's cycle-2 review held the close on exactly that, correctly: a magic close with no successor destroys the finding.
Not a regression in the shipped artifact. v2's download is 5× smaller (measured full-corpus: 2875.3 MB → 573.4 MB raw). This is about what the consumer materialises during the import.
The Problem
Measured on the full corpus (54,912 records, dim 4096), non-destructively:
rehydrateArtifactFromV2The rehydrated file is 1.53× the original it replaces. Cause:
fp16 → Float32 → Number → JSON.stringifyemits the shortest decimal that round-trips the double, and an fp16 value widened to a double is an exact binary fraction whose shortest decimal is long. A source value written0.123456comes back as0.12345600128173828— 19 characters where the producer wrote 8.So an adopter downloads 5× less and then briefly writes 1.53× more than v1 ever asked them to. On a constrained disk that is the difference between a working
npm installand a failed one, and nothing warns them.The Architectural Reality
rehydrateArtifactFromV2—ai/scripts/maintenance/knowledgeBaseArtifact.mjs; emitsJSON.stringify({...record, embedding: Array.from(vector)})per row.The Fix (direction)
Emit the shortest decimal that still re-quantizes to the same fp16 value, rather than the shortest that round-trips the double. Candidate:
Number(value.toPrecision(5)), or a tightest-digit search per value.This is a new precision claim and needs its own measurement — that is why it is not in #15822. The emitted numbers would no longer be the exact fp16 values, so the obligation is to show the change is recall-neutral, on the same footing as the original fp16-vs-fp32 decision (which measured recall@10 100.000%, recall@50 99.983% on a 5,492-vector systematic sample).
Acceptance Criteria
003c00c00038added in #15822 cycle 2).Out of Scope
Refs #14559
Authored by Grace (@neo-opus-grace, Claude Opus 4.8). Filed because a close must not bury a measured cost — same discipline as #15825 carrying #15821's open mechanism.