Some checks are pending
Fuzz Smoke / libFuzzer smoke (push) Waiting to run
Startup ordering defects were only observable by waiting minutes on a live daemon, and the one that aborted it took a live restart loop to find. Give the startup contracts a deterministic harness that runs in milliseconds. + startup_fuzz_support.h drives the real ServiceManagerFsm and the real DeferralGate with virtual time: legal phase advances, injected failure, shutdown and terminal reset, idle/busy, pressure/calm, starvation deadlines and cancellation + oracles fail closed on shutdown resurrection without reset, failure-to-ready, eligibility disagreeing with fsm.isReady(), admission outside the virtual deadline, and ineligible work touching the admission gate; fuzzed IEEE-754 components must never yield non-finite or out-of-range scores + catch2_startup_replay runs named regressions plus 1024 seeded traces per run and reports the root seed and action offset for replay + fuzz_startup builds the same harness for libFuzzer/AFL, with a seed generator that refuses to overwrite different existing files - the fuzzing lane no longer defaults to TSan: harnesses link -fsanitize=fuzzer,address,undefined and the two runtimes cannot share a process; combining them now fails with an explanation instead of producing a binary that cannot start - documented the lane invocation, target naming and the coverage limits, including that governor call ordering inside the poller is not covered Scope: contract-valid single-owner schedules. Executor interleavings, late callbacks, concurrent FSM instances and filesystem/model faults are not modeled. Signed-off-by: trvon <git@trevon.dev>
82 lines
4.1 KiB
Markdown
82 lines
4.1 KiB
Markdown
# Startup contract fuzzing
|
|
|
|
`catch2_startup_replay` and `fuzz_startup` use the same replay support in
|
|
`tools/fuzzing/startup_fuzz_support.h`. The harness drives the real
|
|
`ServiceManagerFsm`, the real `DeferralGate` with virtual time, and the production
|
|
semantic-score helpers. It never starts a daemon, opens a corpus, loads a model,
|
|
changes host pressure, or sleeps.
|
|
|
|
## Fast regression and seed replay
|
|
|
|
After configuring the usual Debug test build:
|
|
|
|
```sh
|
|
meson compile -C build/debug -j2 catch2_startup_replay catch2_embedding_service_timing
|
|
build/debug/tests/catch2_startup_replay --rng-seed 42
|
|
build/debug/tests/catch2_embedding_service_timing '[semantic-startup],[startup-eligibility]'
|
|
```
|
|
|
|
The seeded case tests 1,024 traces of 256 actions and float bit patterns per run.
|
|
Failures report the Catch2 root seed, round and action offset. Re-running with
|
|
that root seed reproduces the entire deterministic campaign. Named cases cover
|
|
pressure deadlines before readiness, optional vector initialization, failure,
|
|
shutdown, cancellation and explicit restart/reset. A separate real vector/KG
|
|
fixture covers both streamed backfill and corpus-rebuild edge weights.
|
|
|
|
## Coverage-guided campaign
|
|
|
|
Use the existing fuzz build configuration. `./setup.sh Fuzzing` sets
|
|
`-Dbuild-fuzzers=true -Db_lundef=false` and selects AFL++ or libFuzzer
|
|
(`tools/fuzzing/meson.build`). It defaults TSan **off**: the harnesses link
|
|
`-fsanitize=fuzzer,address,undefined`, so combining fuzzing with `--tsan` is
|
|
rejected rather than producing a binary that cannot start.
|
|
|
|
A plain Meson configure also works and avoids Conan re-resolution:
|
|
|
|
```sh
|
|
CC=clang CXX=clang++ meson setup build/fuzzing \
|
|
--native-file build/release/build-release/conan/conan_meson_native.ini \
|
|
--wrap-mode=nofallback --buildtype=debug -Db_lundef=false \
|
|
-Dbuild-fuzzers=true -Dbuild-tests=false -Dbuild-cli=false \
|
|
-Dbuild-plugins=false -Dbuild-benchmarks=false
|
|
```
|
|
|
|
Every project object is then rebuilt with `-fsanitize=fuzzer-no-link` plus
|
|
ASan/UBSan, so the first build of this lane is expensive. `meson compile`
|
|
accepts either the executable name or its output path; raw `ninja` needs the path:
|
|
|
|
```sh
|
|
meson compile -C build/fuzzing -j4 fuzz_startup # same as tools/fuzzing/fuzz_startup
|
|
python3 tools/fuzzing/startup_seeds.py /tmp/yams-startup-corpus
|
|
build/fuzzing/tools/fuzzing/fuzz_startup /tmp/yams-startup-corpus -seed=42 -max_total_time=60
|
|
build/fuzzing/tools/fuzzing/fuzz_startup /tmp/yams-startup-corpus/pressure-before-ready
|
|
```
|
|
|
|
Keep failing raw input files as regression corpus artifacts. The low seven bits
|
|
of each byte select `StartupAction` modulo its count; the high bit selects the
|
|
optional-vector branch for an advance action. Processing is bounded to 512
|
|
actions and 32 float-component pairs. A deadline action advances virtual time
|
|
past the pressure starvation deadline; elapsed time cannot supply missing
|
|
startup readiness. Seed generation refuses to overwrite different existing files.
|
|
|
|
## Scope
|
|
|
|
This is a **contract-valid, single-owner state-machine/data fuzzer**, not a full
|
|
startup or concurrency proof. `tinyfsm` state is process-global, so do not run
|
|
multiple replay instances concurrently in one process. Independent fuzz worker
|
|
processes are fine. The Catch2 smoke target also compiles and invokes the actual
|
|
coverage-fuzzer entry point without claiming coverage-guided instrumentation.
|
|
|
|
Known coverage limit: the replay asserts that ineligible work leaves the real
|
|
`DeferralGate` untouched, but that ordering lives in the harness. A regression
|
|
that moved `ResourceGovernor::admitDeferrable()` ahead of the readiness check
|
|
inside `EmbeddingService::channelPoller` would not fail the replay. The
|
|
service-level `[startup-eligibility]` test covers the production predicate
|
|
(`semanticBackfillEligible`) and its stop/idle behavior, not the governor call
|
|
order; covering that needs an injectable admission seam.
|
|
|
|
Arbitrary late callbacks, real executor interleavings, concurrent FSM instances,
|
|
filesystem/model/plugin faults, migrations and cold-start resource KPIs need
|
|
additional production seams and separate integration campaigns. Do not infer
|
|
live startup speed, sanitizer-engine coverage or end-to-end recovery from a
|
|
passing replay test.
|