Files
alktty/fuzz
glm-5.3-flash 0170897bbb feat: alkcall 0.9.0 adoption — bump to 0.7.0
The stub-sweep release changes no type alktty touches: the four
implemented stubs, the register_openable Pub-typed refusal (alktty's
op is Sub-typed), the register_imported Result return, and the removed
RelayError::PubTypedOpen are all surfaces alktty never exercises.

- alkcall requirement 0.8.1 -> 0.9.0; lockfile follows
- alktty 0.6.0 -> 0.7.0 (minor: raising the minimum alkcall requirement
  is ecosystem-coordination breaking on a 0.x crate)
- one test fix: `establisher_ok_on_valid_params` formatted a
  Result<Establishment, _> with {:?} — Establishment no longer derives
  Debug in alkcall 0.9.0; the assert now branches on Err and formats
  only the error

Verification: 113 default / 156 all-features tests, clippy
--all-targets -D warnings, fmt --check, cargo doc, fuzz corpus replay
(9 tests / 340 seeds), wasm32-unknown-unknown check + clippy,
publish --dry-run — all pass.
2026-10-14 05:15:06 +00:00
..

alktty fuzzing

cargo-fuzz targets for the wire-facing parse surfaces. 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
chunk_frame ChunkReader/ChunkWriter (5-byte chunk codec, ADR-001)
negotiation_frame NegotiationReader/NegotiationWriter + NegotiateRequest + error_response_bytes + the cross-codec peek-disambiguation seam
control_json ControlMessage::from_slice/to_json + signal_from_name
session_opseq the producer session pump (drive_session_pre_negotiated) + a fuzz-local mock backend — the stateful op-sequence target (ADR-004/ADR-005 invariants; the alkcall-bug-class hunt)

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 §3). Use the detached runner:

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

FUZZ_RUNTIME_SECS=1800 fuzz/run-detached.sh negotiation_frame 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/wire.rs, src/negotiation.rs, src/control.rs, the adapter, or the session pump.

session_opseq notes

The op-sequence target is inherently slower than the byte-format targets (each input drives a full tokio session with bounded reads and yields — tens of exec/s per worker, not millions). That is expected: the value is state-space exploration, not throughput. It uses tokio::time::timeout internally, so the nightly target needs the --features time tokio surface already present via the shared crate's deps — no extra flags. Its invariants (kill-on-Drop, exit-chunk-is-last, sentinel/FIFO semantics) are the ones unit tests assert individually; the fuzzer explores interleavings no example test can enumerate.