Files
alkhttp/fuzz
glm-5.3-flash c89aa65fb2 chore(deps): consume alkcall 0.9.0
- bump alkcall 0.8.1 -> 0.9 (gateway feature unchanged). No code change
  forced: none of the 0.9.0 breaking surfaces are constructed or
  pattern-matched in this crate — no ManagerError match arms (the new
  InvalidAdopt variant changes nothing here), no RelayError matching
  (the removed PubTypedOpen variant is unreachable from this crate),
  no Establishment construction or Debug dependence (the WS ferry
  passes Option<OpenEstablisher> through unchanged, per the 0.8.0
  audit), and the op/register forward-through refactor does not touch
  the from_wss import filter or the adapter-registered leaf bundles
- ride-through fixes: tests/ws_overlay_ops.rs now expects
  register_imported's new Result<(), String> return (8 sites assert
  registration success instead of discarding the value — the bool
  return they consumed was ignored anyway); fuzz/shared follows the
  main crate to alkcall 0.9 so the harness replay resolves one
  alkcall version (the stale 0.8.1 spec pinned two copies against
  alkhttp's requirement and broke the shared-crate build)
- minor bump 0.6.0 -> 0.7.0 per the dep-wave convention (0.3.0 rode
  alkcall 0.6.0, 0.4.0 rode 0.7.0, 0.5.0 rode 0.8.0): this crate's
  public API carries alkcall types through re-exports and the
  ProtocolHandler impl, so a semver-breaking upstream is
  semver-relevant here

Verification: cargo test 441+70 pass (default), 520+70 pass
(all-features), clippy --all-features --all-targets -D warnings clean,
fmt --check clean, doc --no-deps clean, fuzz corpus replay 21/21
2026-10-14 05:19:29 +00:00
..
2026-10-14 05:19:29 +00:00
2026-10-14 05:19:29 +00:00

alkhttp fuzzing

cargo-fuzz targets for the HTTP surface's hand-rolled parse paths. The design and operating rules live in docs/plans/fuzzing.md (adopted from alkcall's docs/research/fuzzing.md); this README is the operational cheat-sheet.

Layout

  • fuzz_targets/ — nightly-only fuzz_target! binaries (thin wrappers).
  • shared/ — stable-toolchain library holding the invariant logic; the corpus replay tests run here on plain cargo test.
  • corpus/<target>/ — committed seeds (regenerate with python3 fuzz/gen_fuzz_seeds.py).
  • artifacts/ — gitignored crash/oom/timeout artifacts + campaign logs.

Targets

Target Drives
sse_parser SseParser::feed + the FWD-17 envelope mapping (src/adapters/forward.rs) — the SSE frame parser every subscription forwards through
ws_chunk_framing WriteChunkWalk (the write pump's chunk walk) (src/websocket/byte_adapter.rs)
spec_import OpenAPISpec::from_str/from_yaml/from_json, the YAML normalization boundary, CompiledInputSchema compile/harden/validate, FromMCP::build_spec (src/adapters/openapi_spec.rs, input_validation.rs, from_mcp/mod.rs)
ws_session_opseq stateful op sequences over the WS byte adapter's generic pumps (run_read_pump/run_write_pump over the mock socket flavor) — interleavings, close timing, loud-gate mapping, backpressure
retry_throttle the inlined RetryAfterMiddleware's throttle map: capacity bound, eviction policy, ceiling clamp, refresh contraction, Retry-After parse partition

Running a campaign — always detached

Agent sessions must never run fuzzing in the foreground (an OOM in a target can take down the session host; see docs/plans/fuzzing.md §2). Use the detached runner:

fuzz/run-detached.sh sse_parser
# poll:
tail -n 50 fuzz/artifacts/sse_parser-*.log
ls fuzz/artifacts/sse_parser/
pgrep -f "cargo fuzz run sse_parser"

FUZZ_RUNTIME_SECS=1800 fuzz/run-detached.sh sse_parser for a longer campaign. The runner pins -fork=1 -rss_limit_mb=2048 -malloc_limit_mb=2048 -timeout=25 and detaches via setsid + nohup.

Corpus replay (the standing fuzz gate)

cargo test --manifest-path fuzz/shared/Cargo.toml

Replays every committed seed through the same invariant functions the fuzzer runs, on stable, no nightly needed. Part of the release verification checklist (AGENTS.md).

Toolchain notes

rust-toolchain.toml pins nightly for this subtree only (llvm-tools required by cargo-fuzz); the crate itself stays on stable at MSRV 1.88. cargo fuzz build must be run with the fuzz dir as CWD or trust the toolchain file (rustup resolves per directory).

Run campaigns before releases and after touching src/adapters/forward.rs (the SSE parser), src/websocket/byte_adapter.rs (the WS chunk walk), or the import adapters (src/adapters/openapi_spec.rs, input_validation.rs, from_mcp/).