v0.22.0: Practical JSON Foundation
Status: Phase 0 through Phase 5 complete; published and externally audited (2026-08-31). The publication record freezes the release evidence. v0.22.0 adds a strict, owning JSON DOM, exact JSON numbers, parsing, and generation as ordinary standard-library source. It does not add floating-point types, reflection, serialization derivation, or compiler-known JSON behavior.
The adopted public contract is JSON Values and Text. The installed v0.22.0 candidate passed release qualification, so that chapter is current for v0.22.0. This milestone owns work order and completion evidence only; it does not restate public behavior.
Phase 0: Public Contract and Feasibility
Status: complete and reviewed. The Phase 0 review records the RFC, authority, representation, ownership, allocation, source-capability, and implementation-boundary audit plus feasibility evidence.
Phase 0 fixes the complete initial API and strict RFC 8259 policy before standard-library source is added. The selected model uses one owning Value enum, an opaque exact-token Number, decoded String keys, Vec arrays, Map objects, whole-text parsing, compact String generation, and Writer generation.
Accepted Direction
std/jsonis ordinary source and has no compiler-recognized declaration or ABI.- Number stores one exact validated decimal token and never converts through floating point.
- Object names are compared after decoding; duplicates are rejected.
- Objects use representation-neutral Map semantics and expose no ordering promise.
- Parsing owns an explicit frame stack and sets no shortcut-driven fixed nesting limit.
- String and Writer output share one traversal and escaping authority.
- Ordinary and recoverable APIs share recoverable cores with typed private failure classification.
- JSON escape rules reuse one standard-internal Unicode-scalar encoder.
Existing Capabilities
The current language and standard library already provide:
- recursive nominal values through finite owning-container indirection;
- move-only partial aggregates, optional/fallible state, deterministic drop, and enum matching;
- UTF-8 input views, validated owning String mutation, and byte-range projection;
- Vec stacks and arrays, Map object storage, String hashing/equality, and readonly Map iteration;
- current-context and explicit recoverable allocation with owning-buffer affinity;
- recoverable Writer output and built-in error values.
The shape Value -> Vec<Value> | Map<String, Value> passed a standalone check with the published v0.21.0 compiler, including construction and destruction of a nested array. No recursive layout, destruction, parser, numeric, or JSON compiler feature is required.
Required Shared Prerequisites
Only two new standard-internal prerequisites are admitted:
- 1. scalar-to-UTF-8 encoding under the existing
std/internal/utf8responsibility; - an active-context recoverable allocator adapter under the existing
std/memresponsibility.
Phase 1 qualification also found that the already-specified public u8.checked(u64) and u8.truncate(u64) numeric contract had no implementation. Completing that pre-existing contract requires one source-private runtime role; its identity and behavior remain general numeric infrastructure and contain no JSON knowledge. Everything else belongs inside std/json. No new public numeric type, char, floating-point backend, tuple, reflection system, source attribute, or parser primitive is a JSON prerequisite.
Phase 2 qualification found one unrelated contextual-inference defect: a generic call used as the operand of catch or otherwise did not receive the recovery expression's expected payload type, although propagation already did. The checking fix now gives every recovery call that same general payload context. It contains no JSON type, module, error, or allocation policy.
Completion Gate
Phase 0 is complete only when:
- the future-direction specification is the sole authority for public JSON values, numbers, parsing, generation, allocation, failure, Unicode, duplicate, and ordering behavior;
- RFC 8259 deviations and interoperability choices are explicit;
- the exact-token number model avoids premature range and precision limits;
- ordinary and recoverable allocation share one planned implementation authority;
- parser and generator ownership have one cleanup source of truth;
- implementation gaps are assigned to existing responsibilities rather than a JSON-driven compiler extension;
- generated documentation, link validation, and repository whitespace checks pass;
- review finds no representation leak, duplicate source of truth, source-order dependency, compatibility spelling, or unresolved user-visible choice.
Phase 1: Lexical and Unicode Foundation
Status: complete and reviewed. The Phase 1 review records the implementation, native execution, editor, allocation, primitive-boundary, and authority audit.
Phase 1 implements and qualifies Number, the single byte cursor, strict number scanning, exact i64/u64 conversion, JSON string escape decoding, Unicode-scalar encoding, typed internal failure classification, and the current-context recoverable allocator adapter. Number retains exact source spelling while integer projection consumes the scanner's normalized decimal metadata rather than re-running lexical grammar. Offset-bearing input errors allocate through the same allocator as the requested parse operation. This phase does not construct container Values.
Phase 2: Owning DOM Parser
Status: complete and reviewed. The Phase 2 review records the ownership, non-recursion, failure, allocation-affinity, compiler-boundary, native, and editor audit.
Phase 2 implements the public owning Value enum and one whole-text parser over the Phase 1 cursor. One ParserState owns the active grammar state; an explicit Vec<Continuation> owns only parent containers waiting for one completed child. Closing a container moves it toward its parent or the root exactly once. Decoded duplicate names are rejected before Map insertion, and ordinary language ownership cleans every partial state on syntax, duplicate, or allocation failure. No token array, source-location tree, recursive parse call, fixed nesting limit, or parallel cleanup table exists.
Native qualification covers every root kind, nested arrays and objects, malformed boundaries, decoded duplicate names, deep input, partial cleanup, current allocation, recoverable allocation, and explicit allocator results crossing a different current region. LSP qualification exposes the root Value and parser contracts without exposing ParserState or Continuation.
Phase 3: Shared Generator
Status: complete and reviewed. The Phase 3 review records the traversal, escaping, ownership, destination-failure, allocation, native, and editor audit.
Phase 3 implements one non-recursive Value traversal and one compact string-escaping authority. A package-internal byte-sink contract adapts that authority to either an owning String or an arbitrary public Writer. Traversal frames retain container loans plus semantic ordinals, never a loan from a cursor that the same frame must move. Map exposes only a package-restricted semantic entry projection for this suspended traversal; JSON cannot inspect table storage.
Native qualification covers every scalar spelling, exact Number text, all control-escape classes, an unescaped solidus, a multibyte scalar crossing the local buffer boundary, deep arrays, all Map entries, current and explicit traversal allocation, complete Writer output, destination failure, and observable partial output. LSP qualification exposes the generator contract without exposing its frame, failure, or sink declarations.
Phase 4: Practical Integration
Status: complete and reviewed. The Phase 4 review records the application, process, diagnostic, formatting, editor, and authority-boundary audit.
Phase 4 adds a complete json-normalize package that composes process arguments, UTF-8 filesystem input, strict parsing, compact Writer generation, and public error reporting. Its usage, success, and malformed-input paths run as native processes. The package crosses no JSON-specific filesystem or operating-system API.
Canonical formatter qualification now covers the new package automatically. LSP qualification uses the real application source plus recoverable API source to prove public hover, definition, completion, signature, and diagnostic results. Editor output contains no parser, traversal, sink, or private Writer-adapter declaration.
Phase 5: Standard-Library Stabilization
Status: complete and reviewed. The Phase 5 review records the adversarial JSON matrix, collection failure-policy correction, low-level dependency reduction, public contract documentation, complete workspace qualification, and final standard-library authority audit.
All variable-capacity collections now obtain the stable std.mem.capacity_overflow failure from one package-internal memory authority. Ordinary Vec insertion distinguishes bounds termination from allocation termination before entering its recoverable core. Generic value copying and replacement workarounds are isolated under the existing internal pointer contract, removing direct public pointer dependencies from formatting and source iterators.
JSON qualification covers integer range and exponent boundaries, non-JSON whitespace and trailing input, decoded duplicate names, Unicode scalar and surrogate boundaries, every compact control escape class, deep ownership, selected allocator affinity, destination failure, and String/Writer agreement. Public declarations for the most frequently used collection, text, memory, I/O, path, formatting, and process operations now carry hover documentation in their contract roots.
Phase 5 does not package or publish v0.22.0. Release preparation owns version identity, future-direction promotion, deterministic artifact generation, fresh-install qualification, and release notes.
Release Preparation
Status: qualified, published, and externally audited. The release-preparation record owns the candidate identity, duplicate source and artifact gates, installed-home matrix, and final local evidence. The separately authorized publication is recorded in ../releases/v0.22.0.md.