Skip to content

Fix pre-existing CI: bound wire decoder recursion; unblock Smoke + parse gates#64

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/beautiful-edison-x0o5ke
Jun 20, 2026
Merged

Fix pre-existing CI: bound wire decoder recursion; unblock Smoke + parse gates#64
hyperpolymath merged 1 commit into
mainfrom
claude/beautiful-edison-x0o5ke

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What

Fixes two pre-existing, unrelated CI failures on main (surfaced while CI ran on the now-merged hook PR #63). Both were investigated and reproduced locally.

This branch contains only these fixes (4 files); the SessionStart hook from #63 is already merged.

1. parse-gatevcltotal-parse stack overflows

Two distinct causes, both fixed:

a) The wire decoder was not actually total. from_wire / from_wire_op / from_wire_schema are documented "total, never panics", but dec_expr (and dec_vqltype in the schema codec) recursed without any depth bound. A deeply-nested adversarial stream — thousands of nested Compare/Aggregate tags, or nested TList — overflows the native stack and aborts the process (SIGABRT). A crash is not a total Ok/Err, so this violated the trusted-boundary contract (and is a DoS vector). The existing *_total_on_garbage fuzz tests didn't catch it because ≤2048 random bytes rarely form a deep valid prefix.

Fix: bound decode recursion with a DepthGuard + MAX_DEPTH = 128 (the same cap serde_json uses), returning a new WireError::TooDeep. This mirrors the module's existing anti-DoS stance on untrusted counts (never pre-allocated), now extended to untrusted nesting. New regression test feeds a 200k-deep stream to both from_wire and from_wire_schema and asserts Err(TooDeep) with no overflow on the default 2 MiB stack.

b) The roundtrip property tests intermittently overflowed the 2 MiB test stack. proptest's recursive expr() / statement() strategies recurse far enough during value generation for some RNG seeds to exhaust the default test-thread stack — flaky, seed-dependent, and the cause of the intermittent red. The generated values themselves are shallow (measured max depth 6), so this is proptest harness overhead, not a deep AST, and is independent of (a).

Fix: run the parse-gate test step with RUST_MIN_STACK=32 MiB. (Verified: 8 MiB already clears it across repeated runs; 32 MiB is comfortable headroom.)

2. backend-matrix — every Smoke (<prover>) job fails at setup

All ~105 jobs failed identically before running any prover logic:

error: cannot create the lock file …/src/interface/echidna-client/Cargo.lock
because --locked was passed to prevent this

echidna-client is a standalone workspace with no committed Cargo.lock — its transitive echidna-core path-dep only exists once the sibling repo is cloned (the step just above), so a lockfile can't be committed and --locked can never be satisfied.

Fix: drop --locked from that one cargo test invocation so deps resolve fresh against the just-cloned sibling.

Validation

  • ✅ Full vcltotal-parse suite (lib + gate + parse + wire + conformance, 36 tests) green at RUST_MIN_STACK=32 MiB
  • cargo clippy --manifest-path src/interface/parse/Cargo.toml --all-targets --locked -- -D warnings clean (the gate's SPARK-grade lint set)
  • ✅ Totality regression test passes on the default 2 MiB stack (no overflow)
  • ✅ Roundtrip property tests pass repeatedly at ≥8 MiB

Note

The backend-matrix (Smoke) change can't be exercised locally — those jobs clone the echidna sibling, which isn't available here — but the edit directly removes the exact --locked condition that produced the error.

🤖 Generated with Claude Code

https://claude.ai/code/session_017nyxs8RgqZa72PzrTu3L75


Generated by Claude Code

…rse gates

Two unrelated, pre-existing CI failures on main:

parse-gate (vcltotal-parse):
- The "total, never-panics" wire decoder recursed without bound, so a
  deeply-nested adversarial stream (thousands of nested Compare/Aggregate
  tags, or TList in the schema codec) overflowed the native stack and
  aborted the process — a crash that violates the decoder's totality
  contract. Bound decode depth via a DepthGuard with MAX_DEPTH=128 (the
  cap serde_json uses for the same reason), returning the new
  WireError::TooDeep. Regression test covers both dec_expr and
  dec_vqltype: a 200k-deep input now returns Err, never overflows.
- The roundtrip property tests intermittently overflowed the default
  2 MiB test-thread stack: proptest's recursive expr()/statement()
  strategies recurse far enough during value generation for some RNG
  seeds (the generated values are shallow, depth ~6 — harness overhead,
  not a deep AST). Run the parse-gate test step with RUST_MIN_STACK set
  to 32 MiB so the property tests are robust.

backend-matrix (Smoke matrix — all per-prover jobs):
- echidna-client is a standalone workspace with no committed Cargo.lock
  (its echidna-core path-dep only exists once the sibling is cloned), so
  `cargo test --locked` failed before building ("cannot create the lock
  file ... because --locked was passed"). Drop --locked so dependencies
  resolve fresh against the just-cloned sibling.

Validated: full vcltotal-parse suite (lib + gate + parse + wire +
conformance) green at RUST_MIN_STACK=32 MiB; clippy --all-targets
-D warnings clean; the totality regression test passes on the default
2 MiB stack with no overflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017nyxs8RgqZa72PzrTu3L75
@hyperpolymath hyperpolymath marked this pull request as ready for review June 20, 2026 12:59
@hyperpolymath hyperpolymath enabled auto-merge (rebase) June 20, 2026 12:59
@hyperpolymath hyperpolymath disabled auto-merge June 20, 2026 12:59
@hyperpolymath hyperpolymath merged commit 46e80b6 into main Jun 20, 2026
128 checks passed
@hyperpolymath hyperpolymath deleted the claude/beautiful-edison-x0o5ke branch June 20, 2026 12:59
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