Skip to content

hardening: serialise the deploy payload once; guard/parser differential test; 0.6.3 - #11

Merged
SaulBuilds merged 6 commits into
mainfrom
fix/pba-r2-sdk-serialise-once
Sep 26, 2026
Merged

SaulBuilds merged 6 commits into
mainfrom
fix/pba-r2-sdk-serialise-once

Conversation

@SaulBuilds

@SaulBuilds SaulBuilds commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up hardening. Details are in the private audit record.

Item Change Tests Revert / mutants
Payload guarded as sent deploy_model calls json.dumps(tx_data) once, runs assert_payload_has_no_key_share_material on that payload (duplicate keys refused), and sends that same payload. _send_transaction accepts a pre-serialised string. This is the only send path that runs the guard. tests/test_payload_guard.py revert: red
Differential property test 40k seeded near-hex inputs. parse_share_y must agree with a reference strict grammar, and the guard must refuse everything the strict reference, bytes.fromhex or the legacy truncating decoder turns into 16 or more bytes. tests/test_guard_parser_differential.py canonical-only guard regex: 3 failed; lenient parser: 1 failed
Release 0.6.3, with a CHANGELOG entry (0.6.2 is published). Not published.

Local CI, frozen lockfile, Python 3.11.16:

  • 766 passed, 43 skipped including the economics suite (714 excludes it); the skips are integration tests that need a local node.
  • The economics suite runs in CI.
  • ruff, mypy, uv lock --check and the locked pip-audit are clean.
  • The wheel tripwire passes on 0.6.3.

🤖 Generated with [Claude Code](https://claude.com/cla### Update (verifier round 5)

  • The payload parse refuses duplicate object keys, and so does the guard's JSON-string scan.
  • Byte values and their JSON renderings (integer lists, the Buffer shape, index-keyed objects) count as share values.
  • The shared vectors file is v2, byte-identical in citrate-sdk-js with the sha256 pinned.
  • The differential tests cover every byte form and duplicate keys.
  • Test names are neutral.

Verification

  • Revert: red (17 failed).
  • Hand mutants: all 6 killed.
  • Local, frozen lockfile (Python 3.11.16): 788 passed, 1 failed, 43 skipped. The one failure is the economics wall-clock performance test (test_10year_medium_under_60s), on a machine at load average ~240; outside economics the count is 737 passed, 43 skipped.
  • ruff, mypy, uv lock --check, the locked pip-audit and the wheel tripwire are clean.

ude-code)

BerryManifold and others added 3 commits September 25, 2026 18:26
…bytes

deploy_model serialises tx_data once, runs the share guard on json.loads of that payload, and sends the same payload (_send_transaction accepts a pre-serialised JSON string). The guard now judges exactly what is sent. Before, it walked the live objects, and json.dumps could serialise something different (for example a dict subclass with overridden item access). deploy_model is the only send path that runs the guard.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Generates 40k near-hex strings from a fixed seed: canonical hex, perturbed hex and free-form near-hex, with ASCII and Unicode whitespace, junk characters and 0x/0X prefixes. It asserts that (1) parse_share_y agrees with a reference strict grammar, and (2) the guard refuses every input that the strict reference, bytes.fromhex or the legacy truncating JS decoder turns into >= 16 bytes. Reverting the guard to the earlier canonical-only regex fails it (3 failures), and so does a lenient parser (1 failure).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
0.6.2 is published, so this change set ships as 0.6.3. CHANGELOG entry added. Not published: releasing is the owner's call.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SaulBuilds
SaulBuilds force-pushed the fix/pba-r2-sdk-serialise-once branch from 9df644d to f4d834a Compare September 26, 2026 01:26
BerryManifold and others added 3 commits September 25, 2026 19:16
…ped share values

- assert_payload_has_no_key_share_material parses the serialised payload with a hook that refuses duplicate object keys, then runs the guard. deploy_model uses it on the exact payload it sends.
- The guard's nested JSON-string scan uses the same strict parse.
- The share-shape match recognises bytes and their JSON renderings: integer lists, the Buffer JSON shape, and objects keyed 0..n-1 with byte values (>= 16 bytes).
- The shared vectors file is v2 (byte shapes and raw payloads), byte-identical in citrate-sdk-js (sha256 pinned).
- The differential tests cover y as bytes, bytearray, integer lists and the JSON byte shapes, plus duplicate keys.
- The deploy payload test is renamed to test_payload_guard.py, with neutral case names.
Hand mutants (6) are all killed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@SaulBuilds
SaulBuilds merged commit 6f023b2 into main Sep 26, 2026
10 checks passed
@SaulBuilds
SaulBuilds deleted the fix/pba-r2-sdk-serialise-once branch September 26, 2026 03:35
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.

2 participants