fuzz campaigns + gate: wave 7 close — three 15-min detached campaigns clean (payload_codegen finding harness-model: serde_json default f64 parse drifts 1-2 ULPs; invariant pinned to 2-ULP float-leaf drift + decode determinism, crash input promoted as payload_codec/seed-900), fuzz/.gitignore retightened to seed-* tracking, corpus-replay gate joins AGENTS.md verification list, research doc §9 implementation log, README finalized
This commit is contained in:
1 parent
5043f7bcd8
commit
f7de30e57e
7 files changed
+237
-25
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: fuzz-campaigns-and-gate
|
||||
name: Fuzz campaigns (detached) + corpus-replay gate wiring + AGENTS.md verification-list flip
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [fuzz-target-payload-codec, fuzz-target-every-parse, fuzz-target-name-validation]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
@@ -82,8 +82,63 @@ wiring deliverables the plan names:
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
- **One campaign finding, harness-model — no crate bugs (§9 log in the
|
||||
research doc carries the full disposition).** The `payload_codec`
|
||||
campaign crashed ~38 s in on `"46741844073709.51615"`:
|
||||
`decode(encode(v)) ≠ v` for f64 leaves. serde_json's default
|
||||
fast-path f64 parse of its own ryu output drifts 1–2 ULPs
|
||||
(probe-measured: ~30% of random-bits finite f64s fail one
|
||||
parse∘serialize∘parse pass; max drift exactly 2.00 ULP; not a
|
||||
fixpoint at extreme significand shapes). ADR-020 §4 pins default
|
||||
serde_json ("not pinned to a feature flavor"), so the crate-side
|
||||
`float_roundtrip` route is an ADR deviation, not a fix — harness
|
||||
defect. Fixed in `fuzz/shared/src/payload_codec.rs`: exact closure
|
||||
outside `Number` float leaves, float leaves drift-bounded at
|
||||
2 ULPs (`FLOAT_DRIFT_ULPS`, pinned-not-regressed), plus a
|
||||
decode-determinism pin. Crash input promoted to
|
||||
`corpus/payload_codec/seed-900`; re-run clean.
|
||||
- **`fuzz/.gitignore` retightened (its final state was this task's to
|
||||
set).** The scaffold's directory-level negations (`!corpus/<target>`)
|
||||
leaked SHA-named grown-corpus units into `git status` while
|
||||
campaigns ran (libFuzzer fork mode merges new units into the first
|
||||
corpus dir). Now: dirs re-included, contents ignored,
|
||||
`!corpus/<target>/seed-*` back — committed seeds + promoted crash
|
||||
inputs in git, grown corpora invisible.
|
||||
- **Campaigns ran in parallel** (15-min budget each, `FUZZ_RUNTIME_SECS=
|
||||
900`): logs `fuzz/artifacts/{payload_codec-20261010-221350,221951,
|
||||
every_parse-20261010-221351,name_validation-20261010-221352}.log`
|
||||
(the 221350 log is the pre-fix crash evidence; the 215619 log is the
|
||||
every_parse task's earlier 180 s smoke run, superseded). Polling
|
||||
note: the runner's children match `pgrep -af cargo-fuzz` (hyphen),
|
||||
not `cargo fuzz`.
|
||||
- **`gen_fuzz_seeds.py` no-op verified twice**: with the wave's edits
|
||||
stashed and with them applied, a re-run produced a zero diff on the
|
||||
committed corpus set (seed-900 is promotion, not generator output).
|
||||
- **serde_json version pin observed**: the drift characterization was
|
||||
against 1.0.152 (`fuzz/Cargo.lock`); the 2-ULP bound is
|
||||
pinned-not-regressed — a serde_json upgrade may only tighten it.
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Wave 7's operational close landed. Three 15-minute detached campaigns
|
||||
(`run-detached.sh`, `-fork=1 -rss_limit_mb=2048 -malloc_limit_mb=2048
|
||||
-timeout=25`; `payload_codec -max_len=65536 -dict=json.dict`,
|
||||
`every_parse`/`name_validation -max_len=4096 -use_value_profile=1`)
|
||||
all exited 0, `oom/timeout/crash: 0/0/0`, empty artifact dirs at
|
||||
completion: `payload_codec` ~586k execs (~650 exec/s, 2395 edges, corp
|
||||
1544); `every_parse` ~3.7M execs (~4.1k exec/s, 285 edges saturated,
|
||||
corp 805); `name_validation` ~59k execs (327 edges, corp 378). The one
|
||||
finding (payload_codec, ~38 s in) was harness-model — the `Value`
|
||||
round-trip invariant over-tightened against serde_json's default f64
|
||||
parse-precision posture — fixed harness-side crash-input-promoted, and
|
||||
the re-run is clean; no crate bugs (the research doc's
|
||||
successful-negative-result §9). Corpus policy final state verified:
|
||||
only `seed-*` tracked, grown corpora ignored, generator re-run a
|
||||
no-op. The gate joined AGENTS.md's Verification Commands and the
|
||||
fuzzing paragraph reflects the landed state; `fuzz/README.md` finalized
|
||||
(targets table incl. the float-drift pin, commands, corpus policy);
|
||||
research doc §9 appended and its §2/§6 "when wave 7 lands" clauses
|
||||
updated. Verified: workspace build/test, root + `shared`
|
||||
clippy/fmt, the `shared` corpus-replay gate (6 tests incl. the 208
|
||||
committed seeds), and `cargo check -p alkstore-mem --target
|
||||
wasm32-unknown-unknown` all green.
|
||||
Reference in new issue
Block a user