!!id:"https://tson.io/2026/35/m/meta.tn?sha256=bf967ed0e3e2cd1d56864bc06c2c9fbc69270a60c978dd81c1db83c172d3b00e" !!meta:"https://tson.io/2026/35/m/meta-kernel.tn?sha256=28e4497bb5bd9c3e628547c0a9de9e6802a5b848959df96e4812a43fc53c307d" !!import:"https://tson.io/2026/35/m/meta-kernel.tn?sha256=28e4497bb5bd9c3e628547c0a9de9e6802a5b848959df96e4812a43fc53c307d" @doc:""" TSON meta-schema — 2026 Revision 35 draft. The canonical meta-schema for user schemas: a schema governed by the meta-kernel that adds the type constructors the core type library (core.tn) instantiates. Type constructors are a meta-schema concern: user schemas use them but should not define new ones. User schemas normally chain to this file via `!!meta`. The meta-kernel is reachable but not typically referenced directly — schemas that chain to meta-kernel are either alternative type libraries replacing meta, or extensions of the meta layer itself (the format's sanctioned extension point: new type vocabularies arrive as new meta layers, never as grammar changes). Hash pins here are real digests over the bytes of this copy; see meta-kernel.tn's note. Three families of constructors live here: 1. Structural constructors: `bytes_type` (with the `bytes_encoding` enum selecting its text spelling), whose instance in core is `bytes`; and `scoped` (with the `scope_kind` enum), whose instances in core are `declared`, `extern` and `dynamic` and whose applications are `extern_of` and `extern_type`. Fixed-size arrays need no constructor of their own — `[T; N]` is the spelling, and an intent that deserves a name earns a user template. 2. The `set` template — the `set` spelling of the kernel's `set_type` constructor, declared here for meta's own fields and for meta-layer extensions; core declares a sibling for user schemas. 3. Constraint vocabulary constructors for atom families that the kernel itself doesn't need: numeric (`float_type` for the approximate tier, with the `ieee_format` enum; `decimal_type` for the exact tier; `rational_type`; `complex_type`, with the `complex_component` enum), temporal (`date_type`, `time_type`, `datetime_type`, `duration_type`, `period_type`), identifier (`uuid_type`), network (`ipv4_type`, `ipv6_type`, `cidr4_type`, `cidr6_type`, `mac_type`), and text (`email_type`). Plus annotation types — the classifying markers `ordered`, `bounded`, `exact`, `numeric`; the checked assertion `disjoint`; the representation directives `rest` and `discriminator`; and the documentary `deprecated`, `since`, `todo`, `lang`, `title`, `examples`, `read_only`, `write_only`. Annotation types must reside in the governing target's namespace (per Part 2 §6); placing them in meta makes them reachable from core and from every schema that meta governs. An annotation never changes a value, its type, or whether it is valid: validation is over values, and a schema with every annotation erased admits exactly the same values. An annotation may add a load-time check, and it may direct how a class of encodings represents a value. No encoding is privileged — TSON text is one member of the text class, beside JSON — so a directive binds every encoding in its class, and a document in a directed encoding may not be readable without it. That is a directive's force, and it is the only force an annotation has over data. The same stance governs the type docs: a value space is described without reference to any encoding, and where a doc mentions how TSON text spells a value it says so by name. Constructors that bind to a governing specification compose with the kernel's atom_specification mixin and pin the spec field with `=`. Their instances in core are empty, `float_type` aside, whose instances select a `format`. Constraint fields whose values are of an atom meta declares the constructor of but not the instance — a bound of the constrained atom's own family, or a network list of the `cidr4`/`cidr6` family on the address types — use the kernel's `value` escape hatch; the resolver reads each such token under the atom it stands for once that atom is in scope. A field that counts something — a length, a digit count, a prefix length, a precision — is typed by the kernel's `non_negative_integer`, and one that may be negative by `integer`; both arrive through this schema's kernel import. The ordered numeric families state their bounds as field groups ([TSON-SCHEMA] §5.11): one inclusive-or-exclusive group per side, so an inclusive and an exclusive bound on the same side is unrepresentable rather than a prose rule. Value-level coherence (the lower bound not exceeding the upper) remains a schema-load check. `multiple_of`, wherever it appears (`decimal_type`, `rational_type`, `duration_type`, `period_type`, and the kernel's `integer_type`), follows one rule: the step is strictly positive — zero or a negative step is a schema-load error — the test ignores the sign of the value, a refinement may only tighten the step to an integer multiple of the inherited one, and the step composes with every other facet present. `members`, where it appears, is likewise uniform: every member satisfies the other facets on the same body or the schema fails to load, and a refinement may only shrink the set. """ { @doc:""" The set spelling an author writes: `set` where the bare construction is `!set_type { element_type: text }`. A §5.10 template, not a constructor: it composes with nothing and so is not IS-A `top`, and `set_type` stays parameterless as §4.2 requires of every container constructor. The element type arrives by application rather than by a parameter on the constructor itself. This copy serves meta's own fields (`scoped.scope`) and meta-layer extensions. Core declares a sibling under the same name, as it does for `void`, so that user schemas reach it through their core import rather than through the governing namespace. """ set => !set_type { element_type: T } @doc:""" The base encodings of RFC 4648 — its own term for the family — that a text encoding may spell a `bytes` value in (HEX is §8's base16). A spelling is not a kind of value: the same octets are `"3q2+7w=="`, `"deadbeef"` and `"3WV37Q======"`, and "abcd" is well-formed hex and well-formed base64 decoding to different octets, which is why a text reader must be told which alphabet is in force. """ bytes_encoding => !enum [BASE64 BASE64URL BASE32 HEX] @doc:""" Octet-sequence constraint vocabulary. Instance is `bytes` in core. The value is the octets: equality, identity, content addressing and the length facets are all over octets, never over a spelling — `length: 32` is a 32-byte digest whether it arrives as 64 hex characters, 44 base64 characters, or 32 raw bytes — so a round trip through any encoding preserves the value. `encoding` is a selector ([TSON-SCHEMA] §5.7): it picks which RFC 4648 alphabet the text class of encodings — TSON text, JSON, and any encoding whose values are character sequences — spells the octets in, and an encoding whose values are octets ignores it. A selector picks a spelling, so it never changes what two values compare as. It defaults to BASE64 (§4, padded — the choice of JSON Schema's contentEncoding, Protobuf's JSON mapping and CBOR's), so a `bytes` position is base64 in every text encoding, and core declares no spelled subtypes. `encoding` is **not refinable**: an alphabet narrows nothing — every octet string is writable in every one of them — so a refinement that only respells would claim an IS-A carrying no narrowing, and a hex-spelled document is not readable at a base64 position. That is the defect four sibling types were removed for. Another alphabet is another type, declared as its own instance — `hexdigest => !bytes_type { encoding: HEX length: 4 }`. Refining for *length* is unaffected and inherits the alphabet: `sha256 => !bytes ^ { length: 32 }` is a base64 sha256. It is a facet rather than an annotation because a container element has no annotation position: `[hexdigest]` can only work if the element's own type carries the alphabet. And once the type carries it, two types differing only in alphabet are two types, which is what a reader of either needs them to be. No spec pin: RFC 4648 governs spellings, not octets. """ bytes_type => atom & { encoding: bytes_encoding ~ BASE64 length: non_negative_integer? min_length: non_negative_integer? max_length: non_negative_integer? } @doc:""" Which namespace a value's type may be drawn from. LOCAL is the governing namespace — the schema's own declarations and its imports ([TSON-SCHEMA] §2.2.3); EXTERN is a foreign schema, whose identity the value carries with it (in TSON text, a nested !!schema on the value; [TSON-DATA] §2.3). """ scope_kind => !enum [LOCAL EXTERN] @doc:""" Constructor for open sum types: the value names its own type, and the instance names the namespaces that name may be resolved in. The distinction against `choice` is closed against open — a choice enumerates its variants, a scoped instance names where variants are drawn from — which is why `disjoint` is absent here as on every non-choice sum ([TSON-SCHEMA] §8.1). `scope` says which namespaces are admitted. `schemas` narrows the foreign ones: absent is any foreign schema, a keyed map is those schemas, and a key's absent value is every type that schema declares where a list is those types. The map is keyed by schema identity, so one schema cannot be listed twice, and keys are compared by canonical identity ([TSON-DATA] §2.2.1) so a pinned key and an unpinned !!schema in the data match; each pin is verified by the loader on its own. The state admitting nothing is unspellable rather than refused — min_items: 1 on both collections. One coherence rule, of the family a resolver already runs over min_items/max_items: `schemas` requires EXTERN in `scope`. `scope` is written `set` inline. §5.2 prohibits a `!` constructor application at a field position, which is why the kernel's own set-typed fields are named entries; a §5.10 template application is not one, so a schema the resolver materialises can write it where it stands. """ scoped => sum & { scope: set schemas: {uri => [type_name; 1..]?; 1..}? } @doc:""" IEEE 754-2019 interchange formats, both radices. Selects the representable grid of an approximate (`float_type`) value. The binary formats are the familiar base-2 floats; the decimal formats (decimal32/64/128) are base-10 *floating-point* — still approximate, with their own special values — and are NOT the exact fixed-point decimals of `decimal_type`. """ ieee_format => !enum [ BINARY16 BINARY32 BINARY64 BINARY128 BINARY256 DECIMAL32 DECIMAL64 DECIMAL128 ] @doc:""" Approximate-numeric constraint vocabulary (SQL's approximate tier; ISO/IEC 11404 approximate real). Instances in core are `float32` and `float64`. An approximate value is not stored as written: the receiver rounds it onto the discrete IEEE 754-2019 grid named by `format`, so precision may be lost and equality comparison is unsafe (ordering is PARTIAL — NaN is unordered). The `format` radix (binary or decimal) is the ISO 11404 radix characteristic of the type. The value set is that grid together with signed zeros, subnormals, the two infinities, and the canonical quiet NaN (Part 1 §5.6); `allow_nan`, `allow_infinity`, `allow_subnormal`, and `allow_negative_zero` default to true (`~ true` — the format's full set) and may be narrowed to false to exclude those representation artifacts. The bounds are OPTIONAL domain restrictions validated against the value as written, before rounding; they do not bound the special values. Not a narrowing of the exact tier: infinities and NaN are not exact numbers. Bounds: each side is a field group ([TSON-SCHEMA] §5.11) — the inclusive `min` or the exclusive `exclusive_min`; likewise `max` or `exclusive_max` — so at most one bound per side holds by shape. There is deliberately no `multiple_of` here — a step constraint cannot hold on a binary grid (e.g. 0.05 is not a binary32 value, so nothing is exactly a multiple of it); use the exact tier (`decimal_type`) when a step is required. A text-class token that does not land on the grid is rounded to nearest, ties to even (IEEE 754-2019 roundTiesToEven), the default across the format; loss of precision is expected, not an error. An encoding that carries the format's bits delivers a grid value directly and rounds nothing. """ float_type => atom & atom_specification & { spec: = "https://ieeexplore.ieee.org/document/8766229" format: ieee_format ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? allow_nan: boolean ~ true allow_infinity: boolean ~ true allow_subnormal: boolean ~ true allow_negative_zero: boolean ~ true } @doc:""" Exact-numeric constraint vocabulary (SQL's exact tier; ISO/IEC 11404 `scaled`, radix 10). Instance in core is `number` — the unrestricted exact number, which is also the JSON Schema `number` mapping (arbitrary magnitude and precision, finite, no special values). An exact value is exact: nothing is rounded on the way in, so equality is safe and ordering is TOTAL. Scale is not part of the value — `1`, `1.0` and `1.00` are one value (unlike Java's `BigDecimal.equals`), and whether a spelling's trailing zeros survive a round trip is an encoding's promise, not the type's. `total_digits`/`fraction_digits` are the ISO `scaled` precision and scale (SQL `DECIMAL(precision, scale)`): total significant digits and digits after the point. Bounds: each side is a field group ([TSON-SCHEMA] §5.11) — the inclusive `min` or the exclusive `exclusive_min`; likewise `max` or `exclusive_max` — so at most one bound per side holds by shape. `multiple_of` is exact here (e.g. `multiple_of` 0.05 admits only nickel steps) and composes with the other constraints — a value must satisfy all present facets. `fraction_digits` and `multiple_of` overlap but are not equivalent: `fraction_digits` 2 admits any hundredth, `multiple_of` 0.05 only multiples of a nickel. `members` enumerates the admitted values, as `integer_type.members` does for integers. Its elements are `value`-typed, so the set's own identity test cannot see them as numbers: the resolver reads each member under the constrained atom before the set is formed, so `1` and `1.0` are one member and a duplicate rather than two, and a member that does not parse as a decimal fails at schema load. The header's uniform `members` rule applies — every member inside the bounds and on the step, refinements only shrink the set. """ decimal_type => atom & { ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? multiple_of: value? total_digits: non_negative_integer? fraction_digits: non_negative_integer? members: set? } @doc:""" Rational constraint vocabulary. Instance is `rational` in core. Exact (ℚ; ISO/IEC 11404 `rational`), so bounds and `multiple_of` are exact. Bounds: each side is a field group ([TSON-SCHEMA] §5.11) — inclusive `min` or exclusive `exclusive_min`; `max` or `exclusive_max` — at most one bound per side by shape. Constraints operate on the value, not the written token: tokens are not normalized, so `"2/4"` and `"1/2"` satisfy the same constraints. """ rational_type => atom & { ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? multiple_of: value? } @doc:""" Allowed component types for a complex value. A closed vocabulary of numeric types (naming their core counterparts): exact `INTEGER` (Gaussian integers ℤ+ℤi), `NUMBER` (exact arbitrary precision), `RATIONAL` (ℚ+ℚi); approximate `FLOAT32`, `FLOAT64`. Being an enum, it restricts `complex_type.component` at schema-load time and is self-contained in meta (no dependency on the core type namespace). The members are a partial order, not a chain, and a refinement may move `component` only to a member whose value set is a subset of the source's: `INTEGER ⊂ NUMBER ⊂ RATIONAL` are the exact tiers and `FLOAT32 ⊂ FLOAT64` the approximate ones, and the two families are incomparable — binary64 carries ±inf and NaN that no exact decimal represents, and exact values carry precision no binary64 holds. So `!complex ^ { component: INTEGER }` narrows and its IS-A holds, while `!complex ^ { component: FLOAT64 }` is refused: a float64 complex is not a `complex`, and is declared as its own type, `!complex_type { component: FLOAT64 }`. """ complex_component => !enum [INTEGER NUMBER RATIONAL FLOAT32 FLOAT64] @doc:""" Complex constraint vocabulary. Instance is `complex` in core. A complex value is a pair of components (real and imaginary parts). `component` selects the type of both parts from the closed `complex_component` vocabulary; it defaults to `NUMBER` (REQUIRED_DEFAULT, §5.2), so a bare complex has exact components — a defaulted selector. The enum both enforces that a component is numeric (unlike a free `type_name`, which any token would satisfy) and keeps meta free of any reference to core's type names. Complex has no useful total order (`@ordered:NONE`), so the order-based facets of the other numeric tiers do not apply here. Exactness is inherited from `component` rather than fixed: `INTEGER`/`NUMBER`/`RATIONAL` components give an exact complex, `FLOAT32`/`FLOAT64` an approximate one — which is why `complex` carries no `@exact` marker of its own. """ complex_type => atom & { component: complex_component ~ NUMBER } @doc:"Date constraint vocabulary. Instance is `date` in core." date_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc3339" ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? } @doc:""" Time constraint vocabulary. Instance is `time` in core. `precision` is a constraint on the value, not on a spelling: `precision: N` admits a value that is a whole number of 10^-N seconds, so `precision: 3` is millisecond resolution and `precision: 0` whole seconds, and an encoding that counts nanoseconds checks it as readily as one that counts digits. The atom is exact — nothing is truncated; a value off the grid is rejected ([TSON-SCHEMA] §5.5). A text encoding may spell an admitted value with trailing zeros (`12:00:00.500` under `precision: 1`) and writes at most N digits. No timezone facet: RFC 3339 `full-time` already makes the offset mandatory. """ time_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc3339" ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? precision: non_negative_integer? } @doc:""" Datetime constraint vocabulary. Instance is `datetime` in core. `precision` as for `time_type`: the value is a whole number of 10^-N seconds, a constraint on the value ([TSON-SCHEMA] §5.5). No timezone facet: RFC 3339 `date-time` already makes the offset mandatory. """ datetime_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc3339" ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? precision: non_negative_integer? } @doc:""" Elapsed-time constraint vocabulary. Instance is `duration` in core. Lexical form is the RFC 3339 Appendix A `duration` production with three extensions and one restriction: an optional leading `-`; a fraction on the seconds component only, written with `.` (`PT0.5S`, never `PT1.5H` or `PT0,5S`); any subset of D, H, M, S may be omitted provided at least one component is present and order is kept (`PT1H30S` is admitted, as `java.time.Duration` writes it); and the Y and month-M components are not admitted — `P1M` is one month and belongs to `period`; a minute is `PT1M`. `PnW` stands alone, as in the ABNF (`P1W2D` is an error). A day is exactly 86400 s and a week 7 days. The value is a signed exact decimal number of seconds — `number`'s value space, in seconds: nothing is rounded, and the lexical form permits a fraction on the seconds component and nowhere else, so no non-terminating fraction is writable and every duration is a terminating decimal count. So `PT90M`, `PT1H30M` and `P0DT5400S` are one value, `PT0S`, `P0D` and `-PT0S` are one value, and ordering is TOTAL. Bounds compare the value, not the token. Both ends of that space are fixed at a signed 64-bit count of nanoseconds. The seconds component admits at most nine fractional digits, and a magnitude may not exceed 2^63 - 1 nanoseconds (about 292 years) — stated as a magnitude, so negating an admitted duration always yields an admitted one. A processor MUST represent every value in that range and MUST reject one outside it whether or not its own representation could hold it: a range that depends on which implementation read the document is not a range. Nothing is lost at either end, only spelled better — a span of centuries is a calendar span and is a `period`, and a quantity finer or wider than the range is a `number` in the unit the schema names. `precision` as for `time_type`, and it is `fraction_digits` on the seconds count: the value is a whole number of 10^-N seconds, so `precision: 0` admits whole seconds only and `precision: 9` is the nanosecond grid. A constraint on the value and not on a spelling — `PT0.50S` is a whole number of tenths — and it may not exceed 9, there being no tenth digit to constrain. `multiple_of` is `number`'s `multiple_of` on that same count, under the header's uniform rule: `PT15M` admits only quarter-hour values, and `-PT30M` is a multiple of `PT15M`. """ duration_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc3339#appendix-A" ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? precision: non_negative_integer? multiple_of: value? } @doc:""" Calendar-span constraint vocabulary. Instance is `period` in core. Lexical form is the RFC 3339 Appendix A `duration` production restricted to an optional leading `-`, then `P` followed by a Y component, an M component, or both in that order; no fraction, no W or D component and no `T` part (`P1M15D`, `P1Y0D` and `P1YT1H` are errors — use `duration`, or a record with a `period` field and a `duration` field, for mixed spans). The value is a signed integer number of months, so `P1Y` and `P12M` are equal, `P0Y`, `P0M` and `-P0M` are equal, and ordering is TOTAL. Bounds compare the value, not the token. `multiple_of` is a period under the header's uniform rule: `P3M` admits only whole quarters. """ period_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc3339#appendix-A" ( min: value | exclusive_min: value )? ( max: value | exclusive_max: value )? multiple_of: value? } @doc:"UUID constraint vocabulary. Instance is `uuid` in core." uuid_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc9562" version: non_negative_integer? } @doc:"Email constraint vocabulary. Instance is `email` in core." email_type => text_type & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc5322" } @doc:""" IPv4 address constraint vocabulary. Instance is `ipv4` in core. The spec pin cites RFC 3986 for its `IPv4address` production — the normative dotted-quad grammar (Part 1 §5.5). `within` and `excluding` list IPv4 networks in CIDR text (quoted — the form contains `/`): the address must lie inside at least one `within` network when the field is present, and inside no `excluding` network. `excluding` carves holes out of `within`. """ ipv4_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc3986" within: [value]? excluding: [value]? } @doc:""" IPv6 address constraint vocabulary. Instance is `ipv6` in core. `within` and `excluding` list IPv6 networks in CIDR text (quoted): the address must lie inside at least one `within` network when the field is present, and inside no `excluding` network. """ ipv6_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc4291" within: [value]? excluding: [value]? } @doc:""" IPv4 network constraint vocabulary. Instance is `cidr4` in core. `min_prefix`/`max_prefix` narrow the prefix length within the family range 0-32; bounds outside that range are invalid at the schema level. `within` lists IPv4 networks in CIDR text (quoted): the value must be a subnet of at least one. `excluding`: the value must not overlap any listed network — overlap, not containment, so a wider value cannot smuggle an excluded block. """ cidr4_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc4632" min_prefix: non_negative_integer? max_prefix: non_negative_integer? within: [value]? excluding: [value]? } @doc:""" IPv6 network constraint vocabulary. Instance is `cidr6` in core. `min_prefix`/`max_prefix` narrow the prefix length within the family range 0-128. `within` and `excluding` list IPv6 networks in CIDR text (quoted), with the semantics of `cidr4_type`: subnet-of for `within`, non-overlap for `excluding`. """ cidr6_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc4291" min_prefix: non_negative_integer? max_prefix: non_negative_integer? within: [value]? excluding: [value]? } @doc:""" MAC address (EUI-48) constraint vocabulary. Instance is `mac` in core. Deliberately bare beyond the pinned spec: I/G- and U/L-bit predicates and OUI (vendor) prefixes were considered and rejected as niche, and OUI is a living registry. """ mac_type => atom & atom_specification & { spec: = "https://www.rfc-editor.org/rfc/rfc9542" } @doc:"Ordering classification (ISO/IEC 11404 / XSD fundamental facet)." ordered => @annotation !enum [NONE PARTIAL TOTAL] @doc:"Boundedness annotation." bounded => @annotation boolean @doc:""" Exactness classification (ISO/IEC 11404 characterizing property): true for exact types (values preserved as written), false for approximate types (values rounded to a representation grid). """ exact => @annotation boolean @doc:"Numeric type marker annotation." numeric => @annotation void @doc:""" Author's assertion that a choice's variants are pairwise disjoint as value sets — advisory intent, checked against the resolver's derived `type_definition.disjoint` fact ([TSON-SCHEMA] §5.4). A void-targeted presence marker like `@numeric`: written bare, and presence is the assertion. Carries no decode force — the resolver computes disjointness whether or not the annotation is present. The derivation is total, so there is no unprovable state: present and refuted is a schema-load error; present and verified, or absent, is silent. """ disjoint => @annotation void @doc:"Marks a definition or field as deprecated." deprecated => @annotation text @doc:"Records when a definition or field was introduced." since => @annotation text @doc:"Marks incomplete work requiring attention." todo => @annotation text @doc:"BCP 47 language tag (RFC 5646)." lang => @annotation text @doc:"Short human-readable name for a definition or field." title => @annotation text @doc:"Example values for a definition or field, carried for documentation only." examples => @annotation [value] @doc:""" Marks a field an encoding's consumers may read but not write. A bare presence marker like `@numeric`: absence is the default, so there is no false to write (JSON Schema's `readOnly: false` maps to no annotation). `@read_only` and `@write_only` on one field is a schema-load error. """ read_only => @annotation void @doc:""" Marks a field an encoding's consumers may write but not read. A bare presence marker, on `@read_only`'s terms. """ write_only => @annotation void @doc:""" Names the field a member-dispatching encoding selects a choice's variant on. A representation directive: force in the class of encodings that dispatch a choice on a member, none in the model — a discriminated choice admits exactly the variants it admitted, and an encoding that tags variants (TSON text, with `!variant` at every non-disjoint choice) keeps its tags. It also carries load-time force, on `@disjoint`'s verified-or-error precedent ([TSON-SCHEMA] §5.4). Checked at schema load, two outcomes and no third: every variant is a record declaring the named field; that field is REQUIRED_FIXED in every variant (never REQUIRED_DEFAULT — a default is omissible and so cannot dispatch); and the fixed values are pairwise distinct. `field_name` is an identifier, so a non-name spelling fails at the annotation's own type. """ discriminator => @annotation field_name @doc:""" Designates the field an encoding that flattens is meant to flatten — the map-typed field a record's undeclared entries live in, a record being closed under its type ([TSON-SCHEMA] §7.2). A representation directive on `@discriminator`'s terms: force in the class of encodings that flatten, none in the model. Checked at schema load: the field's type resolves to a text-keyed map, and at most one field per composed chain carries the mark. """ rest => @annotation void }