Skip to content

test(sexpr): audit predicate matrix + fuzz + doc examples + linked-from source-arg fix#194

Merged
avrabe merged 2 commits intomainfrom
test/sexpr-audit
Apr 22, 2026
Merged

test(sexpr): audit predicate matrix + fuzz + doc examples + linked-from source-arg fix#194
avrabe merged 2 commits intomainfrom
test/sexpr-audit

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Apr 22, 2026

Summary

Comprehensive audit of the s-expression filter/query language used by rivet list --filter, rivet matrix --filter, rivet export --filter, rivet coverage --filter, {{query:(...)}} embeds, and schema conditional/traceability rules.

Scope

  • Inventoried all 22 predicates from rivet-core/src/sexpr_eval.rs::lower_list
  • Wrote three-shape coverage (positive / negative / malformed) for every predicate
  • Added proptest campaigns guarding parse, lower, evaluate, and pretty-print roundtrip from panics
  • Verified every example in the docs via end-to-end tests
  • Added CLI smoke tests for list --filter, stats --filter, coverage --filter

Bug found + fixed

  • (linked-from <type> <source>) silently ignored its second argument. Same silent-accept shape as v0.4.2's links-count operator drop. Regression test linked_from_source_filter_is_honoured pins the fix.

Stats

  • +108 Rust unit/integration tests
  • +4 proptest campaigns × 256 cases = 1024 fuzz invocations per run
  • +9 doc-example tests (1-to-1 with every example in getting-started.md)
  • +6 CLI integration tests

Recommendations the audit surfaced but did not act on

  1. (count <scope>) is equivalent to (exists <scope> true) — lowering for (> (count …) N) doesn't exist; either add it or clarify docs
  2. matches silently returns false on invalid regex — consistent with filter semantics but a parse-time warning would save debugging time
  3. Accessor::Field is the only variant; dotted accessors links.satisfies.* parse as symbols and resolve to empty strings — worth documenting

These three go into a follow-up PR as part of v0.4.3.

Test plan

  • cargo test --workspace — all 40 test binaries green
  • rivet docs check — PASS (41 files, 0 violations)
  • No new clippy warnings

Refs: REQ-004, REQ-010

🤖 Generated with Claude Code

avrabe added 2 commits April 22, 2026 23:32
Comprehensive s-expression audit: close the coverage gaps in the
predicate inventory and add four campaigns on top of the existing
proptest_sexpr properties.

New coverage:

* rivet-core/tests/sexpr_predicate_matrix.rs (92 tests)
  Three-shape coverage — positive, negative, malformed — for every
  predicate the lowerer recognises. Fills gaps for !=, >, <, >=, <=,
  linked-from (arity), count, reachable-from, reachable-to, plus
  arity/operator-shape errors for every head form.

* rivet-core/tests/sexpr_fuzz.rs (4 proptest campaigns, 256 cases each)
  - parse_never_panics: random ASCII + paren/quote soup must not panic
    sexpr::parse
  - lower_never_panics: full parse_filter on arbitrary input
  - evaluate_never_panics: lowered Expr evaluated on a synthetic store
  - roundtrip_equivalence: generated Expr → pretty-print → re-parse
    must preserve truth value on every fixture artifact

* rivet-core/tests/sexpr_doc_examples.rs (9 tests)
  Every s-expression example in docs/getting-started.md runs
  end-to-end with an asserted match count, catching any future drift
  between the docs and the evaluator.

* rivet-cli/tests/sexpr_filter_integration.rs (6 tests)
  CLI-level smoke for list/stats/coverage --filter, including a
  baseline vs. filtered comparison to catch silently-ignored filters
  and a bad-s-expr exit-code assertion.

Verifies: REQ-048
Refs: REQ-028
`(linked-from "satisfies" "REQ-A")` silently ignored its second
argument — the evaluator's `Expr::LinkedFrom` arm bound the source
parameter as `_source` and only checked the link type. A filter
naming a specific source ID got the same result set as the wildcard
form, which hid real differences at the source level.

This is the same class of bug as the `links-count` operator drop
fixed in v0.4.2 — lowerer accepts the argument, evaluator throws it
away — so the fix follows the same pattern as `Expr::LinkedBy`: treat
`Value::Wildcard` as "any source" and otherwise require an exact
match against the backlink source.

Adds a regression test (`linked_from_source_filter_is_honoured`) in
the predicate-matrix audit suite that exercises both the specific-id
and wildcard forms on a store with two distinct source artifacts.

Fixes: REQ-004
Verifies: REQ-004
@avrabe avrabe merged commit 5ac3046 into main Apr 22, 2026
2 checks passed
@avrabe avrabe deleted the test/sexpr-audit branch April 22, 2026 21:39
@github-actions
Copy link
Copy Markdown

📐 Rivet artifact delta

No artifact changes in this PR. Code-only changes (renderer, CLI wiring, tests) don't touch the artifact graph.

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