fuzz: land the name_validation target (§3.3, wave 7)

This commit is contained in:
glm-5.3-flash committed 2026-10-10 22:08:23 +00:00
1 parent f7c1bd79b0
commit 5043f7bcd8
52 files changed
+465 -6

No files matched your search

+62 -5
View File
@@ -1,7 +1,7 @@
---
id: fuzz-target-name-validation
name: Fuzz target — `name_validation` (core name validation)
status: pending
status: completed
depends_on: [fuzz-scaffold]
scope: narrow
risk: trivial
@@ -58,14 +58,71 @@ guard-order discipline made continuous.
- docs/research/fuzzing.md §3.3 (target spec), §4, §7
- docs/architecture/core-contract.md §Naming / reserved namespace
- docs/architecture/decisions/014-naming-and-reserved-namespace.md §1
(the reserved-prefix rule the target demonstrates)
- docs/architecture/decisions/008-contract-v1-pinning.md §4/§5 — the
reserved-prefix rule and the typed-rejection taxonomy the target
demonstrates (the description's `014-naming-and-reserved-namespace.md`
reference was stale: ADR-014 is the outbox ADR; the reserved
namespace is ADR-008 §4, with the kinds list extended by ADR-014
outbox and ADR-009 schedule — corrected here)
- alkstore/src/validation.rs (the surface)
## Notes
> To be filled by implementation agent
- **No length cap is pinned — the "length-boundary exactness at the
cap" invariant was rendered as verdict-class length-independence.**
The description (and fuzzing.md §3.3) pinned a cap with a ±1
neighborhood ("a name at the cap is accepted, one past it rejected"),
but no cap exists anywhere in the normative stack: ADR-008 §4 pins
only non-empty (whitespace-only-rejected) + the reserved-prefix rule,
core-contract §Naming adds nothing about length, and
`alkstore/src/validation.rs` checks nothing about length. Per
AGENTS.md the ADR wins, so the shipped invariant pins what is true:
the verdict class is length-independent (no length is ever a
rejection cause) across probed neighborhoods (0↔1 empty boundary,
11↔12 prefix length, 63↔64 pg-identifier bytes, 4095↔4096 target
max_len, 65536 payload-cap scale). The only exact boundaries in the
pinned rule — empty↔one-char, whitespace-only↔content, and the
byte-exact prefix — are pinned exactly.
- **The "rejects in every casing/boundary form" invariant is pinned
with its exact-case direction.** The rule is byte-exact and
leading-only (`starts_with(RESERVED_PREFIX)`), so the battery pins
the byte-exact prefix rejecting (alone, suffixed,
whitespace-suffixed — anything not all-whitespace) **and** the
near-miss forms accepting on the shared kind (casing deviations,
missing trailing underscore, embedded and whitespace-led
occurrences) plus the local kind taking the non-empty rule only
(leading reserved prefix legal there, per ADR-008 §4's annotation
and the `NameKind::Local` doc).
- **Corpus-replay floor set at 32** (44 seeds committed), following
the sibling targets' pattern (64 / 48).
## Summary
> To be filled on completion
Landed the §3.3 target: `fuzz_targets/name_validation.rs` (thin
`fuzz_target!` wrapper, like the sibling targets) +
`shared/src/name_validation.rs` (invariants + `#[cfg(test)]` corpus
replay), its `[[bin]]` entry, `pub mod` in shared's lib.rs, the
`name_validation_seeds()` generator (44 deterministic seeds committed:
cap-neighborhood lengths, empty/whitespace-only, the reserved prefix
plain/suffixed/at-length plus the listener-reconnected string, seven
near-miss forms, unicode/control/invalid-UTF-8 shapes), the
`!corpus/name_validation` gitignore negation, and the README
targets-table row. Invariants: total (no-panic over lossy and
`arbitrary`-structured strings plus derived boundary forms);
determinism (double invocation on both kinds); typed-only rejections
(narrowed to a `Verdict` enum that panics on anything but
`Accept`/`InvalidName`/`ReservedName`); wrapper equivalence
(`validate_shared_name`/`validate_local_name` vs `validate_name` on
each `NameKind`); classification asserted against a locally recomputed
rule of record (verbatim-name-carrying errors — names not trimmed);
the casing/boundary battery; and the length-independence battery
(see Notes).
Verified: `cargo test --manifest-path fuzz/shared/Cargo.toml` green
(6/6, 44-seed replay included); shared clippy `-D warnings` + fmt
`--check` green; `cargo fuzz build` green from `fuzz/` (nightly pin);
root `cargo build` / `cargo test` (all suites pass) / clippy
`-D warnings` / fmt `--check` green; seed regeneration deterministic;
corpus files trackable (negation verified via `git check-ignore`).
Campaign runs are `fuzz-campaigns-and-gate`'s concern (this task is
one of its three dependencies).