docs/SPEC-TABLES.md §3: the id-table wire (#435, #439, #434) - #501
Conversation
|
Rulings on the six open points:
The page goes to a cold read now. |
|
Rulings on the cold read (its numbering): U1. The root body ends at its zero reference. The id table is located from the end of the wire, and any byte between the root's terminator and the table's first entry is malformed. Check order: the form byte first (an unknown form is refused as a newer form, nothing counted, before any trailer is read); on a known form, an unreadable trailer is malformed. |
§3 is rewritten to the id-table form: a one-byte form version, a body whose ids are 1-based canonical LEB128 references into a trailing id table of fnv1a64 ids in first-use order, LEB128 for every length, count and index, and the entry count as a fixed u64 at the very end. The enum takes its own kind 30 (#439), the escape kind is 31 (#434), and a payload-free union arm takes kind 32, because an arm header is now a field header and carries the arm's kind. That closes the silent arm-retype class, so §4.1's silent class has four members and not five, and §18.2's arm refusal reduces to the field rule. §3.1, §3.2, §2.2, §2.4, §2.6, §2.8, §4, §4.1, §4.2, §5, §6.3, §6.5, §8.1, §11, §14, §18.1, §18.2, §18.3, §19.2, §20.1, §20.2 and §20.4 are rewritten where they named the old widths, and docs/VERSIONING.md speaks of the layout in the present tense. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Every rule the read found underdetermined is stated once as present fact: the root body ends at its own zero reference and stray bytes before the trailer are malformed; the form byte is read first, so a newer form is a refusal and never damage; kinds 31 and 32 at a position the reader names are a kind mismatch and at one it cannot name are unknown; an element kind of 31 or 32 is the ordinary element-kind mismatch; the reserved id inside a nested body is malformed; a repeated id-table entry is malformed; and an enum reference no reader can name is §4's unknown. The contradictions go with them: the two "nothing reserved" openers, the 16-bit descriptor id, the five-byte empty array body, the blob's u32 region and cook lengths, the kind=none reason, the flags block's membership, the 32-bit fuzzer extremes, triple against pair, and the four-byte pointer field. The worked example prints all 120 bytes in hex with the record field references. The held-by-test list gains the refusal verdict, forms 0 and 0xFF, the last-slot reference, four arm pins and the two reserved-id controls. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
ef17f6a to
b56f6b9
Compare
Docs only. The page states the table wire's id-table form as present fact, before any implementation PR. No compiler, runtime or generated file moves here.
The wire, as §3 now states it
A saved table is three parts: the form byte, the root body, the id table.
1and it is the whole header. It is read first, before the trailer and before any body, so a file that is both a newer form and damaged is a refusal by name and never damage. On a form the reader knows, a trailer it cannot read ismalformed. Nothing else rides in front: no magic, no identity, no build version.id reference, kind (u8), payload. A reference is 1-based canonical unsigned LEB128 into the id table; reference0names no id and is the terminator, the enum'sNoneand the union's empty arm. Every length, count, node index and node count is the same varint, canonical, 64 bits in capability. The one fixed-width number on the wire is the id table's entry count.fnv1a64ids the body used, in first-use order across the whole wire, each a little-endian u64, then the count as a fixed u64 last. A reader resolves it once at open and dispatches every field through an array index.30enum, carrying the variant id reference (Whole-standard read at max effort: 15 contradictions, 6 narrowings, 6 pattern breaks, 13 prose-without-code, 11 versioning seams — and the one-design verdict #439);31escape,LthenLbytes, which no declaration maps to (Reserve one escape kind on the table wire: length-prefixed opaque, skip me #434);32payload-free, which only a union arm carries. Where the reader meets31or32decides the event:unknownat a position it cannot name,kind_mismatchat one it can. An element kind of31or32is the ordinary element-kind mismatch.0where an id is required, and a table that carries one id twice.What follows elsewhere on the page
30. §18's opening, §18.2's arm refusal (now the field rule) and §18.3's referent example follow.unknowncount and the 4 GiB save-time refusals go. The reserved node-table field id is0xFFFFFFFFFFFFFFFF, and the reserved id inside a nested body is malformed.fnv1a64, no fold and no rebound. A hash of0is an ordinary id. One id is held back, the node table's, and a declared name that produces it is refused by the checker. K1 and K2 stay.uint64_t, and "no table-wire identity" is spelled with the reserved id, one value everywhere, since0is now a hash a real name can produce.u64. The wire puts no ceiling on a blob; the storage does, and a blob past §11's derived-size cap is refused at load asmalformed.#435row stays under Owed before 3.0.0, because the repository is not behind the page yet.Numbers, recomputed and verified by first reproducing both of main's current digests byte for byte before changing a token: §20.2's worked projection is
schema-build-version 3with sixteen-hex-digit ids andgradeunder kind30, giving0xa9df771f6051391f, and the table-free unit0xc4adaacfe6cb2809. §18.1's example isschema-tables-baseline 7. The corpus ratios, the dispatch timings and the ladder's framing figure were measured on the previous form and are re-pinned by the implementation, which the page states.Held by test
Every rule names its pin and the one reason it goes red. The list carries the refusal verdict the report format gains for a refused form (forms
0,2and0xFF), the canonical-LEB pass, the reference bound in both directions with the last slot resolving, the table-trailer pass including the repeated entry, kinds31and32at named, unnamed, arm and element positions, the enum kind against the raw integer, an enum reference no reader can name, the four extra arm pins (enum against integer, pointer against integer,bytesagainststring, and anLdisagreeing with the LEB length under kinds17and30), the body terminator, byte identity over every pinned instance, and the two reserved-id controls, which plant the collision below the hash through a compiler test hook.Checks
go test ./compiler/...passes andmake checkexits 0, onorigin/mainat 0b8501c. No C++ or other language build was run. The docs example gate reads only fenced declaration blocks by anchor line and no declaration moved, so no exclusion was needed.🤖 Generated with Claude Code