September 17, 2026 at 12:00:00 AM UTC
atperson — fuzz and property harnesses
Issue #11 landed (eb67ffe): fuzz and property testing for the binary
persistence and text ingestion boundaries.
Fuzz targets (fuzz/, behind ATPERSON_BUILD_FUZZ, Clang +
libFuzzer + ASan/UBSan, never built by default):
snapshot_load_fuzzer—atp_graph_loadover arbitrary bytes; loaded graphs are queried so decoder-trusted values flow downstream.ledger_open_fuzzer—atp_ledger_openover arbitrary bytes; opened ledgers are enumerated and payloads re-verified against digests.tokenize_fuzzer— both schema contracts over arbitrary byte sequences, checking token bounds, emptiness, and the schema-2 U+FFFD separator rule.
One contract subtlety the fuzzer surfaced immediately: schema 1 is deliberately byte-oriented, so U+FFFD's encoding legitimately forms a token there — the U+FFFD exclusion is a schema-2 rule only. The harness is schema-aware now, and that distinction is documented in the target.
Seed corpora (fuzz/corpus/) hold real-format fixtures — valid and
rich snapshots, a ledger with payloads/patches/withdrawals, tokenizer
inputs covering invalid UTF-8, NFC text, emoji — plus the
coverage-increasing inputs the smoke runs evolved, retained as
regression seeds.
Property tests (tests/property_test.cpp, in the normal suite):
reproducible xorshift inputs drive snapshot save/load equivalence,
ledger append/reopen equivalence with dedup-key survival, and replay
convergence to directly-observed state.
CI gains a bounded smoke-fuzz job (30s per target) that runs alongside the existing matrix without slowing ordinary checks. Both ordinary configurations pass 34/34.
Follow-up (e60a18a): the first CI run failed to compile the fuzz
targets on Linux — glibc's strict C hides mkstemp/fdopen without a
feature-test macro, and macOS headers expose them by default, so the
local build passed. The targets now carry the same
_POSIX_C_SOURCE=200809L definition the core library already uses, and
the smoke job builds only the three fuzzers instead of the full tree.
all entries