wai: integer-operators (Draft), the operator set wai-ops/1, with its payload text in integer-payloads #202

Merged
dcharlot merged 5 commits from wai/d2a-operators-text into main 2026-10-10 07:40:43 -04:00
Owner

Adds wai/extensions/integer-operators.md (Draft): wai-ops/1, the integer operator set the integer-exact capabilities decode through. It also adds to integer-payloads.md the payload text the operator set depends on. Text only: no code, vector or registry change.

What lands

1. integer-operators.md, status Draft. It covers:

  • the operators and their exact integer arithmetic. Rounding, bias placement and shift scope are parameters of requantisation;
  • a range policy on every tensor: derived, clamp or check;
  • the acc64 and acc32 profiles;
  • the static bounds rules, which saturate at ±2^255, and the canonical bounds certificate;
  • the accelerator subset wai-ops/1-npu;
  • the WHG1 graph form;
  • the stage operators, among them the mANS decode E8 and the wai.image.jpegai scale path (§13.6.1);
  • canonical lowerings of int_synth.json, WHM1, WAM1 and WMB1 to WHG1;
  • conformance.

The status block says that the wai-ops crate, the wai-verify bounds tool and the ops-conformance corpus come after this Draft. Until they land, each capability's reference is the decoder its payload extension names.

2. integer-payloads.md.

  • §9 now lists the members and checks of entropy.json. Its sentence on the layers' arithmetic now cites integer-operators §13.2 and §13.3.
  • New §13 covers the wai.neural.int_synth payload and int_synth.json.
  • New §14 covers WIM1 and the WMB1 bundle. It states that every element of y not yet decoded is 0 when it enters the entropy network, and that the three networks and the tables share one afrac in 1..=30.

Every statement in these sections was checked against the decoders: CondEntropy::try_from_value, int_synth::decode_from_spec, int_mlicpp::{parse_header, from_bundle, decode_inner}. They match, with one exception. int_synth does not yet make these checks: a reserved byte of 0, C ≥ 1, the caps, k ≥ 1, stride ≥ 1, a shift of at most 127, and the certificate. These are planned changes that take effect with the capability's lowering. §13 lists them as checks that wait for the lowering, and integer-operators §15.3 says each change takes effect then. Every committed int_synth payload and set already passes the syntactic ones.

3. The README names the extension, and the CHANGELOG records it. No file enumerates the extensions directory apart from the section-refs check, which picks the new file up by itself. Wire identifiers in the registry cover delivery identifiers only, and they do not list the integer payload magics, so none is added.

Edits to the drafted text

The first commit is the text as drafted. The second commit reconciles it with what lands beside it:

  • §15.2 points to the integer-payloads sections instead of carrying a second copy. The §13.5 payload column cites them. The WIA1 and WIS1 rows now cite integer-payloads §5 and §6; before, they pointed at this text's own §5 and §6.
  • §15.1 separates the changes that land now from those that land with each capability's lowering. The SPEC, registry and determinism-tiers changes wait for those lowerings.
  • §13.6.1:
    • in the bundle, the shift members' shape is [1, C, 1, 1], not [C];
    • the text now defines a segment's payload: the bytes after its marker and length field;
    • each payload is one entropy substream, within the configuration determinism-tiers §5 scopes.
  • §8.1 pins the evaluation order of a product or sum of more than two operands that a rule writes without Σ, and shows that the 512-bit width is needed (check (b) below).

Check (a): E8 and §13.6.1 against jpegai_mans.rs, on the committed vector

Method.

  • I wrote E8 and §13.6.1 in Python from the text alone: the window, both table builds, sgm and fac, the scale graph and the stage operators.
  • I read jpegai_mans.rs against E8 line by line, and jpegai_decode::decode_plane, decode_hyper_scale and the jpegai_pipeline derivations against §13.6.1.
  • A scratch program built against this branch's wai-rs dumped what the code computes on tests/vectors/jpegai/test256.bin, the committed codestream. It used the pinned jpegai/v1 members norm.json, hs_y.json and hs_uv.json, and their SHA-256 values matched tools/jpegai-e2e-v1.sha256.

Results. All match:

  • Text against code, on test256.bin. Both planes, luma at 160 channels and chroma at 96, give identical integers at every stage: z, I_s, the mask, likely, rvs, σ_idx and y_q. That covers 703 and 537 coded latent positions, three of them decoded through the escape, and 4,096 hyper-latent symbols, seven of them through the read(6) escape. The 32 × 256 latent tables are identical too.
  • Text against the reference decoder's recorded calls on the same codestream. The fixture's segment bytes are test256.bin's, and the hyper-latent symbols of both planes, every span's σ_idx and mask, and every span's symbols are identical. This also confirms the chroma plane's 160 discarded luma rows.
  • Text against the reference encoder's golden streams.
    • The table build matches the reference decode tables.
    • A 200-position sgm span matches, 12 positions of it escaped.
    • Two fac rows of 96 match, four symbols of them escaped.
  • Text against the normative packed tables. All 32 × 256 entries match.
  • Differential fuzz, text against code. The code ran as a debug build, so overflow checks were on. 46,000 random cases (two seeds) covered random streams, row widths from 1 to 300, bounds including 0, 128 and 255, masks, span and row lengths with every remainder mod 4, zero tails and short streams:
    • 16,682 cases decoded identically;
    • in 29,318, the text refused (stream_exhausted) exactly where the code panicked;
    • there were 0 mismatches;
    • 348 values of magnitude 128 or more were decoded under a bound of 128.

Falsifying the checker. Each mutation went into a copy of the Python, not the repository:

  • reading B_y as signed failed the fuzz (94 mismatches);
  • dropping mod 2^8 from the state update failed both;
  • skipping chroma's luma rows failed on test256.bin.

Findings.

  • Fixed: the shift members' shape, and the segment-payload wording above.
  • Open, for the D2a stage vectors:
    • No committed or reference vector reaches a bound of 128. test256.bin codes σ_idx ≤ 20 for luma and ≤ 10 for chroma, and the golden streams use bounds 4–11. So a decoder that reads B_y as signed passes every existing jpegai test. Only the fuzz above tells the two readings apart, and the synthetic vector §14.1 item 7 calls for has to carry the check.
    • The same holds for the remainder rules: no real span or row length leaves a remainder mod 4.
    • The same holds for the T_z carry rule: every committed row ends at 255.
  • Informative: no vector can pin where E8 places a flush inside a group. The window is a lossless backward reader. A refill leaves at least 56 bits held, and an sgm group reads at most 49 between refills even with its flush moved after the outbound reads. Moving the sgm group flush after the outbound reads left every fuzz case unchanged, refusals included. Only the point at which a refusal fires could depend on it.

Check (b): Lemma L1, and the 512-bit sufficiency of §8.1

Lemma L1, re-derived.

  • d_c² ≤ T < C·(V + 1), and (r + 1)² > V + ε ≥ V + 1, so |d_c| < √C·(r + 1).
  • With k ≤ 2^32/r and r ≥ r0, this gives |d_c·k| < isqrt_ceil(C)·2^32·(r0 + 1)/r0.
  • Let Y = isqrt_ceil(C)·2^16·(r0 + 1)/r0. Then n_c < Y. On the negative side the floor adds at most 1, so |n_c| < Y + 1, and therefore |n_c| ≤ ⌈Y⌉ ≤ ⌊Y⌋ + 1 = N_max.
  • The other alternative of the ln.n and ln.dk rules needs the mean in [l, h]. It is: the mean is S/C rounded half away from zero, and S/C lies between the integers l and h.

Trying to break it. I implemented layernorm_c exactly as §5.7 and §2 define it, and asserted that every value it forms lies in its §8.3 interval. That covers every partial sum of ln.S and ln.T, and each of ln.m, ln.d, ln.v, ln.k, ln.dk, ln.n, ln.ng and the output. Inputs:

  • exhaustive: 40,684 inputs, with C from 1 to 4, small ranges, and 14 values of ε from 1 to 2^64 − 1;
  • adversarial: 720,000 inputs from hill-climbing on |n|/N_max, with C up to 64, ranges up to 2^62 and γ at the i32 extremes;
  • chains: 120,000 inputs through three chained layernorm_c stages, each stage's input range the previous stage's producer result.

There was no counterexample. The ln.dk bound is attained exactly: with C = 2 and x = (l, l + 1), |d·k| = ⌊2^32/r0⌋. The largest |n|/N_max seen was 0.984.

512 bits, re-derived. After saturation, every operand lies within ±2^255. So a product lies within ±2^510, a sum within ±2^256, and every other primitive within its operands' range. A signed 512-bit integer holds that, with nothing to spare: igdn.x2 on an input at ±2^255 forms 2^510. The text now says so.

Trying to break it. An engine computed every primitive exactly, asserted that each operand lay within ±2^255 and each result within signed 512 bits, then saturated. It ran 20,000 random chains of up to 11 operators with extreme parameters:

  • conv with ±2^63 weights and post biases;
  • rq at shift 127 in every rounding mode;
  • mul;
  • igdn with γ and β at the i64 extremes;
  • layernorm_c at ε = 2^64 − 1 and C = 2^26;
  • l2norm and gram at L = 2^26;
  • leaky at a = −2^63;
  • add and softmax.

Those chains formed 120,626 nodes, 13,291 of them saturated. No operand fell outside ±2^255, and no exact result needed more than 512 bits.

Finding, fixed in the text. §8.1 fixed the order of a Σ but not that of a product of three or more factors written without one. A zero factor makes the saturated flag depend on the order: 2^200·2^100·0. Every such product in §8.3 is safe: C·(h − l)², L·X² and isqrt_ceil(C)·2^32·(r0 + 1). Either no factor can be 0, or a 0 makes every partial product 0. All 42 extreme cases agree in every order. So no certificate changes, and the text now fixes a left fold as written. R_round is evaluated as §2 writes it. The half-up addend it forms is the one rq.p already forms on the same node, so this cannot change a flag either.

Review fixes (commits 3 to 5)

A review of the D2a crate and corpus against this text found rules that only the crate and the corpus README stated, and two width claims that do not hold. Each is now in the text. The crate PR carries the matching code and a vector for each rule.

  • Conditions and their codes (§5E). A condition an operator states is refused before any symbol: model_mismatch, field_range for E2, and geometry_mismatch for the shapes E11 and E12 read. E5, E6, E7 and E10 now state their conditions. E8's table and bound checks are model_mismatch; only its window refusals are stream_exhausted.
  • E9. The 32-bit form fits i32 only when, beyond hi − lo ≤ 65535, lo − 131070 and hi + 131070 also fit. At lo = 2^31 − 65536, hi = 2^31 − 1, q = 65535, pred = hi and r = 2, it forms hi + 131070.
  • E12 and §7.4. (b − a)·ρ reaches 65535·(2^32 − 2), just under 2^48, and rdiv's 2|n| + d passes 2^48. Every value fits i50, not 47 bits.
  • §4.
    • Run step 1 goes input by input.
    • Step 3 checks the sizes an operator forms against 2^26, then the shape rule, then max_elems.
    • Step 4 applies the inputs' policies first.
  • §5.3, §5.10.
    • The cap is on the uncropped output, cout·uh·uw.
    • A crop's start is at least 0.
    • At load, a scalar start is planned at 0.
  • §8.3. subpos_merge takes the hull of its inputs' intervals, and crop_to takes its first input's interval.
  • §10.3, §10.4.
    • A refused decode changes no state.
    • chscale's m_bytes and layernorm_c's g_bytes are 4 or 8.
  • §13.2. A tensor that a ReLU reads, other than the network's input, is derived. The crate gave such a tensor check [−2^63, I64], so three committed lowered graphs did not follow the text. The crate PR regenerates them.
  • §14.1.
    • A decode's inputs are data inputs only.
    • A refused load lists both profiles.
    • The stage modes, the predictors' fields and CHW layouts, and coding_order's indices are now normative.
    • at is now defined, including mans_decode's position rule for a flush that belongs to no single position.
    • The checker recomputes profiles.

Checks run

  • scripts/check-wai-section-refs.py: clean. It now checks the references to integer-payloads §13 and §14, integer-operators §13.0, §13.2, §13.3 and §15.3, and determinism-tiers §5.
  • check-public-names.sh and check-comparative-prose.sh, one file at a time, on both extension texts, the README and this body: clean, and again on integer-operators after the review fixes. The CHANGELOG's hits are historical lines only.
  • check-no-vanity-metrics.sh: clean.
  • I checked the open PRs first. None touches integer-payloads.md. #197, #199 and #200 also add CHANGELOG entries at the top, so whichever lands second has a one-hunk conflict there.

🤖 Generated with Claude Code

Adds `wai/extensions/integer-operators.md` (Draft): `wai-ops/1`, the integer operator set the integer-exact capabilities decode through. It also adds to `integer-payloads.md` the payload text the operator set depends on. Text only: no code, vector or registry change. ## What lands **1. `integer-operators.md`, status Draft.** It covers: - the operators and their exact integer arithmetic. Rounding, bias placement and shift scope are parameters of requantisation; - a range policy on every tensor: `derived`, `clamp` or `check`; - the `acc64` and `acc32` profiles; - the static bounds rules, which saturate at ±2^255, and the canonical bounds certificate; - the accelerator subset `wai-ops/1-npu`; - the `WHG1` graph form; - the stage operators, among them the mANS decode E8 and the `wai.image.jpegai` scale path (§13.6.1); - canonical lowerings of `int_synth.json`, `WHM1`, `WAM1` and `WMB1` to `WHG1`; - conformance. The status block says that the `wai-ops` crate, the `wai-verify bounds` tool and the `ops-conformance` corpus come after this Draft. Until they land, each capability's reference is the decoder its payload extension names. **2. `integer-payloads.md`.** - §9 now lists the members and checks of `entropy.json`. Its sentence on the layers' arithmetic now cites integer-operators §13.2 and §13.3. - New §13 covers the `wai.neural.int_synth` payload and `int_synth.json`. - New §14 covers `WIM1` and the `WMB1` bundle. It states that every element of `y` not yet decoded is 0 when it enters the entropy network, and that the three networks and the tables share one `afrac` in `1..=30`. Every statement in these sections was checked against the decoders: `CondEntropy::try_from_value`, `int_synth::decode_from_spec`, `int_mlicpp::{parse_header, from_bundle, decode_inner}`. They match, with one exception. `int_synth` does not yet make these checks: a reserved byte of 0, `C ≥ 1`, the caps, `k ≥ 1`, `stride ≥ 1`, a shift of at most 127, and the certificate. These are planned changes that take effect with the capability's lowering. §13 lists them as checks that wait for the lowering, and integer-operators §15.3 says each change takes effect then. Every committed `int_synth` payload and set already passes the syntactic ones. **3. The README names the extension, and the CHANGELOG records it.** No file enumerates the extensions directory apart from the section-refs check, which picks the new file up by itself. Wire identifiers in the registry cover delivery identifiers only, and they do not list the integer payload magics, so none is added. ## Edits to the drafted text The first commit is the text as drafted. The second commit reconciles it with what lands beside it: - §15.2 points to the integer-payloads sections instead of carrying a second copy. The §13.5 payload column cites them. The `WIA1` and `WIS1` rows now cite integer-payloads §5 and §6; before, they pointed at this text's own §5 and §6. - §15.1 separates the changes that land now from those that land with each capability's lowering. The SPEC, registry and determinism-tiers changes wait for those lowerings. - §13.6.1: - in the bundle, the shift members' shape is `[1, C, 1, 1]`, not `[C]`; - the text now defines a segment's payload: the bytes after its marker and length field; - each payload is one entropy substream, within the configuration determinism-tiers §5 scopes. - §8.1 pins the evaluation order of a product or sum of more than two operands that a rule writes without Σ, and shows that the 512-bit width is needed (check (b) below). ## Check (a): E8 and §13.6.1 against `jpegai_mans.rs`, on the committed vector **Method.** - I wrote E8 and §13.6.1 in Python from the text alone: the window, both table builds, `sgm` and `fac`, the scale graph and the stage operators. - I read `jpegai_mans.rs` against E8 line by line, and `jpegai_decode::decode_plane`, `decode_hyper_scale` and the `jpegai_pipeline` derivations against §13.6.1. - A scratch program built against this branch's `wai-rs` dumped what the code computes on `tests/vectors/jpegai/test256.bin`, the committed codestream. It used the pinned `jpegai/v1` members `norm.json`, `hs_y.json` and `hs_uv.json`, and their SHA-256 values matched `tools/jpegai-e2e-v1.sha256`. **Results.** All match: - **Text against code, on `test256.bin`.** Both planes, luma at 160 channels and chroma at 96, give identical integers at every stage: `z`, `I_s`, the mask, `likely`, `rvs`, `σ_idx` and `y_q`. That covers 703 and 537 coded latent positions, three of them decoded through the escape, and 4,096 hyper-latent symbols, seven of them through the `read(6)` escape. The 32 × 256 latent tables are identical too. - **Text against the reference decoder's recorded calls on the same codestream.** The fixture's segment bytes are `test256.bin`'s, and the hyper-latent symbols of both planes, every span's `σ_idx` and mask, and every span's symbols are identical. This also confirms the chroma plane's 160 discarded luma rows. - **Text against the reference encoder's golden streams.** - The table build matches the reference decode tables. - A 200-position `sgm` span matches, 12 positions of it escaped. - Two `fac` rows of 96 match, four symbols of them escaped. - **Text against the normative packed tables.** All 32 × 256 entries match. - **Differential fuzz, text against code.** The code ran as a debug build, so overflow checks were on. 46,000 random cases (two seeds) covered random streams, row widths from 1 to 300, bounds including 0, 128 and 255, masks, span and row lengths with every remainder mod 4, zero tails and short streams: - 16,682 cases decoded identically; - in 29,318, the text refused (`stream_exhausted`) exactly where the code panicked; - there were 0 mismatches; - 348 values of magnitude 128 or more were decoded under a bound of 128. **Falsifying the checker.** Each mutation went into a copy of the Python, not the repository: - reading `B_y` as signed failed the fuzz (94 mismatches); - dropping `mod 2^8` from the state update failed both; - skipping chroma's luma rows failed on `test256.bin`. **Findings.** - Fixed: the shift members' shape, and the segment-payload wording above. - Open, for the D2a stage vectors: - No committed or reference vector reaches a bound of 128. `test256.bin` codes `σ_idx` ≤ 20 for luma and ≤ 10 for chroma, and the golden streams use bounds 4–11. So a decoder that reads `B_y` as signed passes every existing jpegai test. Only the fuzz above tells the two readings apart, and the synthetic vector §14.1 item 7 calls for has to carry the check. - The same holds for the remainder rules: no real span or row length leaves a remainder mod 4. - The same holds for the `T_z` carry rule: every committed row ends at 255. - Informative: no vector can pin where E8 places a flush inside a group. The window is a lossless backward reader. A refill leaves at least 56 bits held, and an `sgm` group reads at most 49 between refills even with its flush moved after the outbound reads. Moving the `sgm` group flush after the outbound reads left every fuzz case unchanged, refusals included. Only the point at which a refusal fires could depend on it. ## Check (b): Lemma L1, and the 512-bit sufficiency of §8.1 **Lemma L1, re-derived.** - `d_c² ≤ T < C·(V + 1)`, and `(r + 1)² > V + ε ≥ V + 1`, so `|d_c| < √C·(r + 1)`. - With `k ≤ 2^32/r` and `r ≥ r0`, this gives `|d_c·k| < isqrt_ceil(C)·2^32·(r0 + 1)/r0`. - Let `Y = isqrt_ceil(C)·2^16·(r0 + 1)/r0`. Then `n_c < Y`. On the negative side the floor adds at most 1, so `|n_c| < Y + 1`, and therefore `|n_c| ≤ ⌈Y⌉ ≤ ⌊Y⌋ + 1 = N_max`. - The other alternative of the `ln.n` and `ln.dk` rules needs the mean in `[l, h]`. It is: the mean is `S/C` rounded half away from zero, and `S/C` lies between the integers `l` and `h`. **Trying to break it.** I implemented `layernorm_c` exactly as §5.7 and §2 define it, and asserted that every value it forms lies in its §8.3 interval. That covers every partial sum of `ln.S` and `ln.T`, and each of `ln.m`, `ln.d`, `ln.v`, `ln.k`, `ln.dk`, `ln.n`, `ln.ng` and the output. Inputs: - exhaustive: 40,684 inputs, with `C` from 1 to 4, small ranges, and 14 values of `ε` from 1 to 2^64 − 1; - adversarial: 720,000 inputs from hill-climbing on `|n|/N_max`, with `C` up to 64, ranges up to 2^62 and `γ` at the i32 extremes; - chains: 120,000 inputs through three chained `layernorm_c` stages, each stage's input range the previous stage's producer result. There was no counterexample. The `ln.dk` bound is attained exactly: with `C = 2` and `x = (l, l + 1)`, `|d·k| = ⌊2^32/r0⌋`. The largest `|n|/N_max` seen was 0.984. **512 bits, re-derived.** After saturation, every operand lies within ±2^255. So a product lies within ±2^510, a sum within ±2^256, and every other primitive within its operands' range. A signed 512-bit integer holds that, with nothing to spare: `igdn.x2` on an input at ±2^255 forms 2^510. The text now says so. **Trying to break it.** An engine computed every primitive exactly, asserted that each operand lay within ±2^255 and each result within signed 512 bits, then saturated. It ran 20,000 random chains of up to 11 operators with extreme parameters: - `conv` with ±2^63 weights and post biases; - `rq` at shift 127 in every rounding mode; - `mul`; - `igdn` with `γ` and `β` at the i64 extremes; - `layernorm_c` at `ε = 2^64 − 1` and `C = 2^26`; - `l2norm` and `gram` at `L = 2^26`; - `leaky` at `a = −2^63`; - `add` and `softmax`. Those chains formed 120,626 nodes, 13,291 of them saturated. No operand fell outside ±2^255, and no exact result needed more than 512 bits. **Finding, fixed in the text.** §8.1 fixed the order of a `Σ` but not that of a product of three or more factors written without one. A zero factor makes the saturated flag depend on the order: `2^200·2^100·0`. Every such product in §8.3 is safe: `C·(h − l)²`, `L·X²` and `isqrt_ceil(C)·2^32·(r0 + 1)`. Either no factor can be 0, or a 0 makes every partial product 0. All 42 extreme cases agree in every order. So no certificate changes, and the text now fixes a left fold as written. `R_round` is evaluated as §2 writes it. The half-up addend it forms is the one `rq.p` already forms on the same node, so this cannot change a flag either. ## Review fixes (commits 3 to 5) A review of the D2a crate and corpus against this text found rules that only the crate and the corpus README stated, and two width claims that do not hold. Each is now in the text. The crate PR carries the matching code and a vector for each rule. - **Conditions and their codes (§5E).** A condition an operator states is refused before any symbol: `model_mismatch`, `field_range` for E2, and `geometry_mismatch` for the shapes E11 and E12 read. E5, E6, E7 and E10 now state their conditions. E8's table and bound checks are `model_mismatch`; only its window refusals are `stream_exhausted`. - **E9.** The 32-bit form fits i32 only when, beyond `hi − lo ≤ 65535`, `lo − 131070` and `hi + 131070` also fit. At `lo = 2^31 − 65536`, `hi = 2^31 − 1`, `q = 65535`, `pred = hi` and `r = 2`, it forms `hi + 131070`. - **E12 and §7.4.** `(b − a)·ρ` reaches `65535·(2^32 − 2)`, just under 2^48, and rdiv's `2|n| + d` passes 2^48. Every value fits i50, not 47 bits. - **§4.** - Run step 1 goes input by input. - Step 3 checks the sizes an operator forms against 2^26, then the shape rule, then `max_elems`. - Step 4 applies the inputs' policies first. - **§5.3, §5.10.** - The cap is on the uncropped output, `cout·uh·uw`. - A crop's start is at least 0. - At load, a scalar start is planned at 0. - **§8.3.** `subpos_merge` takes the hull of its inputs' intervals, and `crop_to` takes its first input's interval. - **§10.3, §10.4.** - A refused decode changes no state. - `chscale`'s `m_bytes` and `layernorm_c`'s `g_bytes` are 4 or 8. - **§13.2.** A tensor that a ReLU reads, other than the network's input, is `derived`. The crate gave such a tensor `check [−2^63, I64]`, so three committed lowered graphs did not follow the text. The crate PR regenerates them. - **§14.1.** - A decode's inputs are data inputs only. - A refused load lists both profiles. - The stage `modes`, the predictors' fields and CHW layouts, and `coding_order`'s indices are now normative. - `at` is now defined, including `mans_decode`'s position rule for a flush that belongs to no single position. - The checker recomputes `profiles`. ## Checks run - `scripts/check-wai-section-refs.py`: clean. It now checks the references to integer-payloads §13 and §14, integer-operators §13.0, §13.2, §13.3 and §15.3, and determinism-tiers §5. - `check-public-names.sh` and `check-comparative-prose.sh`, one file at a time, on both extension texts, the README and this body: clean, and again on integer-operators after the review fixes. The CHANGELOG's hits are historical lines only. - `check-no-vanity-metrics.sh`: clean. - I checked the open PRs first. None touches `integer-payloads.md`. #197, #199 and #200 also add CHANGELOG entries at the top, so whichever lands second has a one-hunk conflict there. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The proposed extension text as drafted: the operators and their exact
integer arithmetic, the tensor range policies, the acc64 and acc32
profiles, the static bounds rules and the bounds certificate, the
accelerator subset, the WHG1 graph form, profile declaration, the
relation to the determinism tiers, the canonical lowerings of the
existing integer network forms, and conformance.

This commit is the text as drafted, unedited; the next commits
reconcile it with what lands beside it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: integer-operators lands beside its payload text
Some checks failed
standards workspaces build + test / arl-rs (pull_request) Has been cancelled
standards workspaces build + test / eoc-rs (pull_request) Has been cancelled
standards workspaces build + test / jcp-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-code-rs (pull_request) Has been cancelled
standards workspaces build + test / joule-ui-rs (pull_request) Has been cancelled
standards workspaces build + test / joulecontract-rs (pull_request) Has been cancelled
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / map-rs (pull_request) Has been cancelled
standards workspaces build + test / mesh-rs (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
standards workspaces build + test / proof-rs (pull_request) Has been cancelled
standards workspaces build + test / sandbox-rs (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / smart-byte-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI section references / cited sections exist (pull_request) Has been cancelled
116fcb520f
integer-payloads gains the text the operator set depends on:
- §9: the members and checks of entropy.json, and the layers'
  arithmetic is now integer-operators §13.2 (WHM1) and §13.3 (WAM1);
- §13: the wai.neural.int_synth payload and its set, int_synth.json,
  with the checks the reference decoder makes only once it decodes
  through its lowering listed as such;
- §14: WIM1 and the WMB1 bundle of wai.neural.int_mlicpp, including
  that the entropy network reads every element of y not yet decoded
  as 0, and the one afrac in 1..=30 its networks and tables share.

integer-operators is reconciled with that:
- §15.2 points at those sections instead of carrying a second copy,
  and the §13.5 payload column cites them (WIA1 and WIS1 now name
  integer-payloads, not this text's own §5 and §6);
- §15.1 separates what changes now from what lands with each
  capability's lowering, and §15.3 says each change takes effect then;
- §13.6.1: the hyper-scale shift members are [1, C, 1, 1] in the
  bundle, not [C]; a segment's payload is defined (after the marker
  and length field), and each is one entropy substream within the
  configuration determinism-tiers §5 scopes;
- §8.1: a product or sum of more than two operands written without
  Σ is a left fold as written, which keeps the saturated flag
  independent of evaluation order, and the 512-bit width is shown to
  be needed (igdn.x2 at ±2^255 forms 2^510);
- the status block says the reference crate, tool and corpus follow
  this Draft, and names the decoders that are the reference until then.

The README names the extension and the CHANGELOG records it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A review of the D2a corpus found rules that only the crate and the corpus README
stated, and two width claims that do not hold. This writes each into the text.

- §5E: a condition an operator states is refused before any symbol, with
  model_mismatch (field_range for E2, geometry_mismatch for the shapes E11 and
  E12 read). E8's table and bound checks are model_mismatch; only its window
  refusals are stream_exhausted. E5, E6, E7 and E10 state their conditions.
- E9: the 32-bit form fits i32 only when lo − 131070 and hi + 131070 also do;
  near the i32 limits it does not.
- E12 and §7.4: rate_predict's product (b − a)·ρ reaches 2^48 and rdiv's
  2|n| + d passes it; every value fits i50, not 47 bits.
- §4: step 1 runs input by input; step 3 checks the sizes an operator forms
  against 2^26, then the shape rule, then max_elems; step 4 applies the inputs'
  policies first.
- §5.3: the cap is on the uncropped output, cout·uh·uw. §5.10: crop starts are
  at least 0, and at load a scalar start is planned at 0.
- §10.3: a refused decode changes no state. §10.4: chscale's m_bytes and
  layernorm_c's g_bytes are 4 or 8.
- §13.2: a tensor read by a ReLU, other than the network's input, is derived.
- §14.1: decode inputs are data inputs only; a refused load lists both
  profiles; stage modes, the predictors' fields and layouts, and coding_order's
  indices are normative; and `at`, mans_decode's position rule included.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The movement row gave "the input's interval" and the hull only for concat.
subpos_merge reads four inputs and crop_to two; the row now says that
subpos_merge, like concat, takes the hull of its inputs' intervals, and that
crop_to takes its first input's, which a bounds pass written from the text
needs in order to agree with the certified tags.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: integer-operators §14.1, the checker recomputes profiles too
All checks were successful
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m30s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m9s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m12s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m14s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m20s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m6s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m49s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 7m8s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 13s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 13m57s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 8s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 25s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 49s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m55s
WAI section references / cited sections exist (pull_request) Successful in 11s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 48m54s
standards workspaces build + test / aac-rs (pull_request) Successful in 14m12s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 10m57s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 3m56s
standards workspaces build + test / map-rs (pull_request) Successful in 5m4s
standards workspaces build + test / mesh-rs (pull_request) Successful in 4m0s
standards workspaces build + test / openpay (pull_request) Successful in 15m28s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 10m29s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m8s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 3m23s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m46s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m8s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 10m7s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 29s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m23s
fee4516886
`profiles` decides which implementations must reproduce a vector, so an
independent checker that copies it checks nothing about it. The checker now
recomputes it from its own bounds pass (§8), as it does `load` and `expect`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!202
No description provided.