Skip to content

Add a soundness fuzzer for satask handlers - #8

Merged
TiloRC merged 4 commits into
TiloRC:mainfrom
tilorc-bot:agent/handler-fuzzer
Sep 22, 2026
Merged

TiloRC merged 4 commits into
TiloRC:mainfrom
tilorc-bot:agent/handler-fuzzer

Conversation

@tilorc-bot

Copy link
Copy Markdown
Contributor

Why

The validation suites measure how many queries get answered; they do not check
whether a definite answer is true. The --oracle comparison in #7 catches
definite contradictions with ask, but a definite answer where ask is unsure
is accepted there and can still be unsound.

What

  • Add tools/check_soundness.py, which checks definite satask answers
    against concrete models and ask. Hypothesis shrinks findings to minimal
    examples, and generated assumptions are satisfied by a model drawn first, so
    no query is rejected for lack of a model.
  • Ship curated regressions from the handler audits (the T1/T2 bugs on
    cde5c70) plus an --engine random mode for runs that report every finding.
  • Suppress model counterexamples that ask also gives, since some handlers
    intentionally mirror upstream rules that ground models can contradict;
    --strict reports them.
  • Add hypothesis to the dev extra, cover the helpers and strategy with unit
    tests, and document the command in the README. No handler code is touched.

Findings

  • Catches the T1/T2 unsoundness on cde5c70.
  • Found a new one on agent/tail-audits (not on main): the Pow complex
    closure has no nonzero-base guard, so complex(x) gives complex(1/x) and
    ~complex(1/x) gives ~zero(x). Reported separately; both queries are
    curated regressions.
  • CI wiring is deferred until that Pow finding is fixed, otherwise main goes
    red when the tail-audit handlers merge.

Verification

  • pytest reasoning/tests: 154 passed, 1 xfailed.
  • mypy strict clean; tools/regen_known_facts.py --check up to date;
    old-assumptions scan at its 2 pre-existing findings.

This description was written by an AI agent (opencode, deepseek-v4.1-flash) on
behalf of TiloRC.

tools/check_soundness.py generates queries and checks definite satask
answers against concrete models and sympy.ask. Model counterexamples are
suppressed when ask shares the answer, because some handlers mirror
upstream rules that ground models can contradict; --strict reports them.

The curated regression list catches the T1/T2 unsoundness on cde5c70,
and the audit is clean on agent/tail-audits across 470 random queries.
No handler code is touched.
The hypothesis engine draws a model first and builds assumptions that
hold under it, so no query is rejected for lack of a model, and findings
shrink to a minimal example. The stdlib generator remains available with
--engine random.

The fuzzer found a new unsoundness on agent/tail-audits: the Pow complex
closure lacks a nonzero-base guard, so complex(x) gives complex(1/x) and
~complex(1/x) gives ~zero(x). Both queries are curated regressions now.
Case.assumptions shadowed the SymPy attribute name the advisory
old-assumptions scan looks for, so the scan reported seven false
positives. Renaming the field keeps the scan at its two pre-existing
findings. The README now points at the audit, and the report notes that
CI wiring waits for the Pow complex fix.
Generating an example calls ask on ground atoms, which can exceed
Hypothesis's slow-generation threshold on CI runners.
@TiloRC
TiloRC merged commit b07b332 into TiloRC:main Sep 22, 2026
3 checks passed
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.

2 participants