Files
ww/protocol/README.md

6.7 KiB

WWAR v1 Phase 0 conformance

This directory freezes the byte-level interoperability surface of WWAR v1. It does not describe or execute the WW package manager, compiler, action graph, scheduler, provider system, cache, or bootstrap process.

Phase 0 follows one rule: schemas describe representation, executable WW/C code owns behavior, and tests observe that behavior. The Python programs here are development-time conformance tools. They are not part of a production WW build and are not a second build-system implementation.

Contents

  • schema/wire.json fixes the WWAR envelope, primitive frames, container frames, canonical Unicode rules, limits, and malformed-input precedence.
  • schema/records.json fixes scalar representations, record fields and tags, enum values, union discriminants, encoded defaults, record kinds, wrapper assignments, and artifact-to-digest identities.
  • schema/digests.json fixes the twelve domain separators and their finite, non-nestable byte formulas.
  • schema/wwar-v1.sha256 fixes the exact bytes of those three schemas.
  • tool.py strictly validates the schemas, encodes and decodes WWAR values and typed records, computes the frozen digests, and generates data-only lookup tables.
  • generated/wwar_v1_tables.json is a compact, pre-indexed codec table compiled from the three schemas. It contains no executable policy or schema prose.
  • vectors/ contains compact wire, typed-record, wrapper, and digest goldens.
  • check.py is the aggregate conformance gate and contains a small independent raw-wire/hash oracle. That oracle does not load or interpret record schemas.

Run the complete gate from the repository root:

make test-protocol

Regenerate the checked-in data after an intentional schema change:

python3 -B protocol/tool.py write-manifest
python3 -B protocol/tool.py emit-tables --output protocol/generated/wwar_v1_tables.json
python3 -B protocol/check.py

Generation is deterministic. The gate regenerates in two fresh directories, compares their bytes, and compares both with the checked-in output. All JSON is UTF-8, duplicate keys are rejected, and schema strings must already be NFC.

The generated table removes repetitive lookup construction from future codecs instead of copying the authoring schemas. Its positional columns are fixed:

  • a type is [kind, scalar-or-name-or-element-type];
  • a scalar is [base, length, maximum, values, path-class, nonempty];
  • a path is [shape, absolute, allow-dot, allow-dotdot, ASCII, roots];
  • a record is [top-level-kind, fields];
  • a field is [tag, name, type, cardinality, default, order, order-by];
  • a union is [discriminator, case-table];
  • a digest is [algorithm, separator, input, formula, entry-encoding].

The generator also turns enum, kind, artifact, and wrapper arrays into direct keyed lookup tables. The checked-in output carries the exact input-file hashes and bundle digest, and the gate proves it equals a fresh compilation. Path lexical checks are derived from the closed path columns; there is no second free-form rules list that can disagree with the codec.

Frozen surface

The v1 catalog contains:

  • seven primitive/container wire type codes;
  • 165 representation records and 809 field tags;
  • 41 enums with 202 numeric values;
  • three structural unions with 35 arms;
  • 22 top-level record-kind assignments, all at schema version 1;
  • 12 domain-separated SHA-256 formulas;
  • four compact wrapper assignments.

Every declared record field is present on the wire in increasing tag order. An optional field's encoded_default is its encoded empty value, not permission to omit the field. A decoder therefore reports MISSING_FIELD when a declared tag is absent. Union-inactive fields likewise remain present with their encoded empty defaults.

The generic WWAR envelope carries exactly one complete value. Typed record identity and wrapper operations additionally require the record named by their schema. This resolves an inconsistency in the experiment: its envelope prose said “record”, while both readers and nearly all primitive/container goldens accepted a generic root value.

The only experimental record deliberately not retained is NativeTypeGraphContextV1. It was unreachable from every top-level record, digest preimage, and signature preimage, and existed only as context for the discarded projection proof runtime. The other digest-preimage records remain as wire layouts; how later phases construct them is not Phase 0 behavior.

The migration compared a canonical assignment catalog against the archived experimental IDL. Its SHA-256 was 7b8660b451cc5260e9c7ad8d45da8e62313ff1f9b54259e211ff04b49c38671f. The comparison covers retained record names, field names/types/tags/defaults, scalar wire refinements, path classes, enum numbers, union arms, record kinds, digest formulas, artifact mappings, and wrapper assignments. In particular, it preserves intentional numeric holes; for example, FinalLinkTokenKind has no value 4.

What is deferred

Phase 0 retains only bytes and identities. The implementation phases own the following behavior and test it when it exists:

  • Phase 1: source import extraction, package loading and cycles, compiler export production/consumption, public type closure, and ABI projection construction.
  • Phase 2: action construction, action graphs, scheduling, failure propagation, CAS/cache storage and validation, sandboxing, and environment policy.
  • Phase 3: manifest/lock/work/vendor text parsers, module and source resolution, fetching, source-store policy, and source-tree filesystem construction.
  • Phase 4: native providers, recursive provider expansion, lowering, link-plan construction, tool adapters, and platform/native policy.
  • Phase 6: bootstrap-plan execution, staged rebuilds, and byte-for-byte fixed-point comparison.

There is intentionally no predicate language, context lookup mechanism, projection proof system, lowering program, graph interpreter, text-parser AST, semantic answer table, or bootstrap proof record in this directory. Digest preimage layouts and byte formulas do not prescribe how those values are derived.

Change discipline

WWAR v1 assignments are compatibility data. Do not renumber or silently reuse tags, enum values, union discriminants, record kinds, wrapper versions, or digest separators. An incompatible representation change requires a new wire or schema version and new vectors.

Declarative additions must remain closed data shapes and must remove more handwritten complexity than they introduce. Build behavior belongs in ordinary typed WW/C functions with focused tests. A generator may remove repetitive codec tables, but it must remain generic, deterministic, reviewable, and byte-for-byte reproducible.