Skip to content

Add normative vox-wire spec and reconcile surrounding chapters#366

Closed
fasterthanlime wants to merge 13 commits into
mainfrom
codex/review-voxwire-spec
Closed

Add normative vox-wire spec and reconcile surrounding chapters#366
fasterthanlime wants to merge 13 commits into
mainfrom
codex/review-voxwire-spec

Conversation

@fasterthanlime
Copy link
Copy Markdown
Contributor

Summary

  • Added a new normative wire.md chapter defining vox-wire as the single value format with self-describing and compact modes
  • Reconciled schema exchange, connectivity, and zero-copy chapters to use vox-wire terminology instead of the old CBOR/postcard split
  • Updated the spec index to surface wire value encoding in the main spec flow

Testing

  • Tracey validation passed for Rust, Swift, and TypeScript spec coverage
  • git diff --check passed
  • Not run (not requested): runtime or integration tests

Reconcile the rationale note with docs/content/telex/_index.md:
close open questions the spec settled, name the migration order,
enumerate the facet-cbor call sites that die, pin the
vox-postcard → telex rename story, and capture the streaming-
compression head-of-line caveat the spec already encodes.
…s, lift Vox-isms

- Fold dynamic value into compact mode rather than carving it out:
  compact framing is opaque to the bytes inside any length prefix, so
  a dynamic-value field is just a self-described value behind the
  standard field prefix. Spec out both modes explicitly.
- Self-describing aggregate bodies are now pinned by an umbrella rule
  (telex.tags.aggregate-payload): every nested element/key/value is
  itself a self-described Telex value. Closes the gap for list, set,
  map, array, tuple, and nd-array (which also gains a self-describing
  body clause).
- Lift Vox-specific language out of Telex rules: telex.format,
  telex.bootstrap.self-describing, telex.compression, and
  telex.compression.modes no longer reference "Vox messages", "session
  handshake", "link attachment", or "transport-prologue". They speak
  in Telex-pure terms.
- Drop the native-vs-wasm bias on telex.translation.compiled and
  telex.translation.no-evolution-fallback — the build-time-not-message
  invariant applies to every backend, interpreted or JIT.
- Set and map values now have a canonical wire form: elements/keys
  ordered by ascending lexicographic comparison of their compact-mode
  encoded bytes, duplicates rejected by both encoders and decoders.
  NaN keys/elements are rejected explicitly because they would break
  duplicate detection; +0.0 and -0.0 stay distinct because their byte
  patterns differ. This makes value bytes content-addressable and
  composes with the existing schema-hash mechanism.

- Move the content-hash mechanism (type-id umbrella, hash algorithm,
  TypeRef encoding, per-kind hashes for primitives/struct/enum/
  container/tuple, and the recursive-type 3-step algorithm) from
  docs/content/spec/schemas.md into docs/content/telex/_index.md
  under new telex.type-id* and telex.hash.recursive* rule IDs.
  Hashing is a Telex-level concern (no Vox dependencies); only the
  Vox-specific channel-hash extension and the per-connection scoping
  rule stay in schemas.md.

- Rewrite the wire-level translation duplicates in schemas.md
  (schema.translation.{field-matching,skip-unknown,fill-defaults,
  reorder,enum}) as thin pointers to their Telex normative versions
  (telex.translation.name-matching, telex.skip.*, telex.translation.
  default-fill). The Tracey rule IDs are preserved so existing
  r[impl ...] and r[verify ...] annotations in vox-postcard, vox,
  and vox-types continue to anchor correctly while the wire facts
  live in one place.

- Rename r[impl ...] / r[verify ...] annotations in vox-types/src/
  schema.rs and vox-schema/src/lib.rs that referenced the moved rule
  IDs. tracey_validate passes cleanly across all 6 spec/impl
  combinations.
…tighten newtype prose

Three spec edits flowing from interview-round design decisions:

- Canonical form is compact-mode-only. r[telex.aggregate.set] and
  r[telex.aggregate.map] now split their bodies by mode: compact-mode
  bytes MUST be byte-canonical (sorted lex by encoded form, duplicates
  rejected); self-describing mode is implementation-defined for order
  (duplicates still rejected in both modes). Self-describing transport
  carries bootstrap and schema values whose identity comes from
  structural hashing (r[telex.type-id.hash]), not from encoded bytes,
  so byte canonicity in self-describing mode is not load-bearing.
  Updated r[telex.aggregate.set-map.canonical] and
  r[telex.aggregate.set-map.float-keys] to match.

- Telex stops referencing Vox by spec-rule. r[telex.type-id] no longer
  cross-links r[schema.type-id.hash.channel]. New rule
  r[telex.type-id.reserved-kinds] reserves "channel" for the Vox RPC
  protocol; the body lives in Vox's spec. This admits the layering
  honestly — Vox is the primary protocol Telex serves and the
  extension set is small — without coupling Telex's spec text to
  Vox's rule IDs.

- Newtype hashing tightened. The preamble to
  r[telex.type-id.hash.primitives] used to claim that any single-field
  wrapper (including a plain `struct UserId(u64)`) flattens to the
  inner primitive hash, which doesn't match what the extractor does
  (only #[facet(transparent)] is flattened). Updated to make
  flattening explicitly opt-in, so source languages preserve their
  newtype distinctions across the wire by default.

Follow-up: SchemaKind has no Set variant in vox-schema; the extractor
in vox-types lowers Def::Set into SchemaKind::List, so Vox can't yet
express the set/list distinction the Telex spec requires. That's a
Rust change across vox-schema, vox-types, plan/IR/JIT, and the Swift/TS
bindings — separate from this spec work.
Split Telex schema identity into a separate spec page, keep core Telex focused on the value byte format, and update Vox schema docs to own Vox-specific rules.

Remove premature Telex Tracey annotations from existing Vox schema code so Telex coverage remains honest until real Telex implementation work lands.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant