Skip to content

QA: mutation to 6 modules (≥80), continuous deep-fuzz + load/SLO harnesses (closes #14)#16

Merged
code-with-rashid merged 1 commit into
mainfrom
qa/issue-14-mutation-fuzz-load
Jun 23, 2026
Merged

QA: mutation to 6 modules (≥80), continuous deep-fuzz + load/SLO harnesses (closes #14)#16
code-with-rashid merged 1 commit into
mainfrom
qa/issue-14-mutation-fuzz-load

Conversation

@code-with-rashid

Copy link
Copy Markdown
Owner

Closes the remaining #14 items — 1 (expand mutation), 2 (continuous fuzz), 3 (throughput-SLO load). With this, Issue #14 is fully addressed.

1. Mutation beyond the validator

Expanded the Stryker scope 1 → 6 modules, all now ≥ the 80 break threshold:

module before after
spec/validate-response 85.4% 85.4%
runner/resolve 84.4% 84.4%
spec/scaffold 81.5%
runner/capture 80.4%
mock/engine 77.4% 82.2%
spec/drift 75.6% 92.3%

engine and drift were under 80 and lifted by targeted killing tests (mock-engine-mutation.test.ts, drift-mutation.test.ts) asserting exact content-types, the validate-mode 400 body, route specificity, regex semantics, normalizeKey whitespace handling, and sorted diff output. vitest.mutation.config.ts excludes the ~11s fuzz smoke from mutation runs (it was in the covering set and re-ran per mutant, so engine never finished inline).

2. Continuous fuzz to the 1M-exec budget

qa/fuzz/deep-fuzz.mjs — feedback-driven (keeps inputs that hit a new output signature, AFL-style corpus growth), 7 targets, up to 1,000,000 execs OR --minutes per target, crash/hang findings → qa/fuzz/findings.jsonl, corpus persisted to qa/corpus/. Scheduled weekly in fuzz-deep.yml. Smoke: 140k execs, 0 findings. (Found+fixed two bugs in the fuzzer itself: a global-not-per-target findings counter, and treating jsonpath's correct throw on a malformed author expression as a crash.)

3. Throughput / latency / leak SLO

qa/load/load-test.mjs + load.yml. Hard SLOs: zero errors and bounded post-GC heapUsed growth — the real leak signal. (I first gated on RSS, saw it climb 58MB, then realised RSS only tracks V8's high-water mark; post-GC heap is flat, +0.6MB over 47k requests → no leak.) Latency gated on p95 (stable), not p99 (a single GC spike blew p99 to 1469ms). Results: mock ~2400 rps / p95 ~40ms, web ~740 rps static / p95 ~68ms, both leak-free.

Verification

326 vitest tests green, typecheck 7/7, all 6 mutation modules ≥80, deep-fuzz 0 findings, load SLOs met repeatably.

…zz + load/SLO harnesses

Closes the remaining Issue #14 items 1-3.

Item 1 — mutation beyond the validator:
- Stryker scope 1 -> 6 modules, all now >= the 80 break threshold.
- mock/engine.ts 77.4% -> 82.2% (mock-engine-mutation.test.ts) and spec/drift.ts
  75.6% -> 92.3% (drift-mutation.test.ts) via targeted killing tests; the other
  four (validate-response, resolve, scaffold, capture) were already >=80.
- vitest.mutation.config.ts excludes the ~11s fuzz smoke from the mutation run
  (it was in the covering set and re-ran per mutant, so engine never finished).

Item 2 — continuous fuzz to the 1M-exec budget:
- qa/fuzz/deep-fuzz.mjs: feedback-driven (corpus grows on new output signatures),
  7 targets, 1,000,000 execs OR --minutes each, crash/hang findings + persisted
  corpus. Scheduled in fuzz-deep.yml. Smoke: 140k execs, 0 findings. Fixed two
  harness bugs found along the way (global findings counter; jsonpath's correct
  throw on a malformed author path was wrongly flagged).

Item 3 — throughput/latency/leak SLO:
- qa/load/load-test.mjs + load.yml. Hard SLOs: zero errors and bounded post-GC
  heapUsed growth (the real leak signal — RSS only tracks the high-water mark).
  Latency gated on p95 (stable), not p99 (single GC spikes). mock ~2400 rps /
  p95 ~40ms, web ~740 rps static / p95 ~68ms, both leak-free.

326 tests green, typecheck 7/7.
@code-with-rashid code-with-rashid merged commit c3edfee into main Jun 23, 2026
3 checks passed
@code-with-rashid code-with-rashid deleted the qa/issue-14-mutation-fuzz-load branch June 23, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant