chore: bump to 0.6.0, changelog for the fuzzing adoption (alkcall 0.8.1)

This commit is contained in:
glm-5.3-flash committed 2026-09-28 10:18:50 +00:00
1 parent fb7cfe3851
commit 3855bb1c99
3 files changed
+87 -2

No files matched your search

+85
View File
@@ -4,6 +4,90 @@ All notable changes to this crate are documented here. The format is
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
this crate adheres to [Semantic Versioning](https://semver.org/).
## [0.6.0] - 2026-09-28
The fuzzing adoption: a cargo-fuzz workspace over the four wire-facing
parse surfaces, with zero findings in the crate — every crash the
campaigns produced was a harness-model gap, and every fix landed in the
harness, not the crate. The `alkcall` requirement also updates to
0.8.1. No API, wire-format, or behavior change; this release ships no
source change in `src/` at all — the deltas are the fuzz workspace,
the dependency bump, and this changelog. Minor bump per the 0.x
ecosystem-coordination rule (alktty's public signatures reference
alkcall types, so downstream crates must unify on alkcall 0.8.1).
### Added
- **cargo-fuzz workspace under `fuzz/`** (per
`docs/plans/fuzzing.md`, adopted from the alkcall fuzzing playbook):
four targets over the wire-facing surfaces, with the invariant logic
in a stable-toolchain shared crate (`fuzz/shared/`) so the corpus
replays on stable — the nightly pin is scoped to the subtree via
`fuzz/rust-toolchain.toml`:
- `chunk_frame` — the 5-byte chunk codec
(`ChunkReader`/`ChunkWriter`), including the
peek/disambiguation seam (`peek_stream_type` vs
`read_chunk_after_peek` in both call orders must yield exactly one
chunk).
- `negotiation_frame` — the 4-byte BE length-prefixed negotiation
framing + `NegotiateRequest` JSON parse + `error_response_bytes`,
and the cross-codec invariant that an error-response frame's
length-prefix high byte is `0x00` so a `ChunkReader` peek
distinguishes it from a chunk (ADR-001 §5).
- `control_json` — `ControlMessage` JSON parse + `signal_from_name`.
- `session_opseq` — the stateful target: a `#[derive(Arbitrary)]`
12-op sequence drives the real producer session pump
(`drive_session_pre_negotiated`) over a duplex pair against a
fuzz-local mock backend, asserting the wire-contract invariants
(kill-on-`Drop` per ADR-005, exit-chunk-is-last per ADR-004,
lossless per-stream FIFO + single stdout sentinel, stdin
prefix-losslessness, control dispatch bounds, take-once
allocation, teardown termination).
- **Committed corpus: 340 hand-made seeds** across the four targets
(deterministic generator `fuzz/gen_fuzz_seeds.py`; the
`session_opseq` seeds are hand-encoded against the `arbitrary` 1.4.x
derive layout with the encoding pinned by a decode test). Grown
corpus entries are gitignored and excised after campaigns.
- **The standing fuzz gate**: `cargo test --manifest-path
fuzz/shared/Cargo.toml` replays every committed seed through the
same invariant functions the targets run, on stable. Added to the
verification checklist.
- **Detached-runner rule**: campaigns run via `fuzz/run-detached.sh`
(setsid/nohup, fork mode, bounded RSS) — never in the foreground of
an agent session.
### Changed
- **BREAKING (ecosystem-coordination) — `alkcall` bumped to 0.8.1.**
alkcall 0.8.1 is a patch release fixing the duplicate
adopt/open channel-state destruction found by alkcall's own fuzz
campaign; it changed no type alktty touches. Downstream crates must
unify on alkcall 0.8.x per the caret requirement. Minor bump per
the 0.x ecosystem-coordination rule.
- **Root `Cargo.toml` gains a `[workspace]` table**
(`members = ["."]`, `exclude = ["fuzz"]`) so the fuzz subtree's
nightly dev-deps never join the root workspace (an MSRV footgun),
and `fuzz/` joins the publish exclude. Verified: the packaged file
list is unchanged except for the exclusion (43 files; the fuzz
workspace, seeds, plans, reviews, and `.opencode/` all stay out of
the crate).
### Verification
- 0 findings across all four targets: detached campaigns (10 min each
on the three wire targets; 10 min on `session_opseq` at 42.3k execs,
cov 3934 → 4075 and still growing at budget end) plus a 60s smoke
run on target 4 — no crash/OOM/timeout/leak.
- Corpus replay 9 tests green on stable (340 seeds); crate tests 113
default / 156 all-features; clippy stable + wasm; fmt; doc; wasm
check — all pass.
- The three crashes the harness-model smoke runs surfaced were
harness gaps, each fixed in the fuzz harness (the alkcall §7.7
pattern): a failed client write can mean the session completed and
dropped the server duplex half mid-write — the harness drains and
requires the exit chunk on any write/shutdown error (a premature
close is a finding). No adapter code changed.
## [0.5.0] - 2026-09-18
The alkcall 0.8.0 adoption: a dependency bump only — no source change
@@ -321,6 +405,7 @@ alknet mono-repo.
the client→backend pump is aborted at session end instead of
lingering until the client disconnects.
[0.6.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.6.0
[0.5.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.5.0
[0.4.1]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.4.1
[0.4.0]: https://git.alk.dev/alkdev/alktty/releases/tag/v0.4.0
Generated
+1 -1
View File
@@ -48,7 +48,7 @@ dependencies = [
[[package]]
name = "alktty"
version = "0.5.0"
version = "0.6.0"
dependencies = [
"alkcall",
"async-trait",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "alktty"
version = "0.5.0"
version = "0.6.0"
edition = "2021"
rust-version = "1.88"
license = "MIT OR Apache-2.0"