Skip to content

docs(adr): freeze-gate value-flow uint encoding - #60

Open
mfw78 wants to merge 4 commits into
docs/restore-docs-treefrom
docs/freeze-gate-adrs
Open

docs(adr): freeze-gate value-flow uint encoding#60
mfw78 wants to merge 4 commits into
docs/restore-docs-treefrom
docs/freeze-gate-adrs

Conversation

@mfw78

@mfw78 mfw78 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What

Adds ADR 0001 and ADR 0002 recording the value-flow freeze-gate decisions and enforces them in code. ADR 0001 defines the minimal-length canonical uint encoding: big-endian magnitude, no leading zero bytes, zero represented as the empty byte list, and non-minimal input is rejected rather than normalised. ADR 0002 records the bare native asset case as resolved by restructuring rather than by ratifying it as invalid, making native-token(offchain(...)) unrepresentable. videre-sdk's value_flow module gains the shipped codec: encode_uint (via to_be_bytes_trimmed_vec) and decode_uint, which rejects a leading zero byte and inputs over 32 bytes, surfacing a UintError via thiserror; AssetAmount::erc20 now routes through encode_uint. videre-test gains a UintVectors fixture module following the existing codec/header fixture conventions, publishing crates/videre-test/vectors/uint.json with five accept vectors and three reject vectors covering non-minimal and oversize encodings.

Why

The value-flow encoding needed a documented, canonical rule so implementations agree on wire format instead of each hand-rolling their own uint representation, and the bare native asset shape needed a decision recorded before other work builds on it. Closes #20

Testing

Run on a fresh clone at origin/docs/freeze-gate-adrs (eef8b5d), detached, with RUSTFLAGS="-D warnings" and --locked to mirror .github/workflows/ci.yml. Touched crates over origin/docs/restore-docs-tree..HEAD: videre-sdk, videre-test, echo-venue (plus docs/adr/*).

  • cargo clippy -p videre-sdk -p videre-test -p echo-venue --all-targets --all-features --locked -- -D warnings - clean, zero warnings.
  • cargo test --doc -p videre-sdk -p videre-test -p echo-venue --all-features --locked - 1 passed, 0 failed (videre_test lib.rs:16; videre_sdk has no doctests).
  • RUSTDOCFLAGS='-D warnings' cargo doc --no-deps -p videre-sdk -p videre-test -p echo-venue --all-features --locked - clean.
  • Guest wasms (echo-venue changed): cargo build --release --target wasm32-wasip2 --locked -p echo-venue -p echo-client -p echo-keeper -p flaky-venue -p logging-venue.

AI Assistance

Implementation by claude-fable-5, red-team review by claude-opus-5, PR description by claude-sonnet-5.

mfw78 added 4 commits August 7, 2026 02:31
ADR 0001 records the minimal-length canonical uint: the big-endian magnitude with no leading zero bytes, zero as the empty list, and rejection of non-minimal input rather than normalisation.

ADR 0002 records the bare native case in the asset variant: the restructuring makes native-token(offchain(...)) unrepresentable, which goes further than the ratify-as-invalid option the tracker issue floated.

Both decisions were taken in the shipped WIT at the freeze gate and existed nowhere as a record (#20).

AI Assistance: Claude Fable wrote the ADRs from the shipped WIT and the tracker record.
value_flow already owned the encode through AssetAmount::erc20. decode_uint is the shipped counterpart: it rejects a leading zero byte and an encoding past 32 bytes instead of normalising, per ADR 0001. encode_uint names the trim so the constructor and the conformance vectors share one spelling.

AI Assistance: Claude Fable wrote the codec functions and their unit tests.
…ings

The types.wit minimal-length MUST had prose only. vectors/uint.json publishes the canonical encodings plus the reject vectors, and the check is generic over the decoder, so the red-green pair is itself a test: a deliberately tolerant decode that normalises padding fails exactly the non-minimal vectors, and the shipped decode_uint conforms.

The file is pinned by a regeneration test like the reference fixtures, so a drift in the published bytes is a red.

AI Assistance: Claude Fable wrote the vector module, the published file, and the red-green tests.
The branch gave videre-sdk encode_uint but left three hand-rolled encoders behind it. videre-test's reference adapter and echo-venue each carried their own minimal_be(u64), and the SDK acceptance adapter emitted amount_wei.to_be_bytes(), a fixed-width 8-byte word that decode_uint rejects as non-minimal. All three now call encode_uint, so ADR 0001's claim that value_flow owns both directions holds.

UintError gains #[non_exhaustive] to match every other public error in the SDK, since a wider amount width reopens the 32-byte bound.

The reject vectors gain the ABI word forms of zero and one: the 32-byte padded encoding is the non-minimal shape a real EVM decoder produces, and the tolerant-decoder test now proves the vectors catch it.

ADR 0001 states the 32-byte bound in the Decision, because vectors/uint.json publishes it as a conformance MUST that types.wit does not spell out, and it records that videre-host does not yet decode a guest-returned amount. The ADR README points the #47 batch at 0003.

AI Assistance: Claude Fable red-teamed the branch and wrote these fixes.
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