Skip to content

feat(query): accept issue #33 literal examples — diff head + inline kwargs + PA-id auto-route#88

Open
hyperpolymath wants to merge 3 commits into
mainfrom
feat/issue-33-query-literal-examples
Open

feat(query): accept issue #33 literal examples — diff head + inline kwargs + PA-id auto-route#88
hyperpolymath wants to merge 3 commits into
mainfrom
feat/issue-33-query-literal-examples

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Closes the residual gap on #33: the issue body advertises three example query expressions, but two of the three failed to parse and one parsed-then-matched-nothing under the existing grammar. After this patch, all three expressions in the issue work verbatim.

The S1/S2/S3 architectural work is already in main (see #57, #58, #60, #61, #62, #63). This is the user-facing-syntax polish that lets the issue itself close cleanly against its own documented examples.

What changed

Issue example Before After
(crosslang :from FFI :to ProofDrift) works works
(category PA001 :severity Critical :pr-state nil) parse error parses → (and (rule-id PA001) (severity Critical) (pr-state nil))
(diff :since 2026-04-12 :category PA022) parse error ("unknown head: diff") parses → (and (since 2026-04-12) (rule-id PA022))
(category PA001) parsed, zero matches auto-routes to (rule-id PA001), matches findings

Three additions to src/query/mod.rs:

  1. diff head — keyword-only sugar for (and (kw VALUE) ...) over its :keyword VALUE pairs. Unwraps to the single clause when only one kwarg is supplied so the AST stays minimal.
  2. Inline :keyword VALUE kwargs on every unary headcategory, rule-id, severity, repo, file, pr-state, since. Implemented via a shared parse_trailing_kwargs helper so adding a new unary head adds a single dispatch row.
  3. (category PAxxx) auto-routes to Query::RuleId so the issue's literal example actually selects findings instead of silently matching zero. (category UnsafeCode) continues to match by WeakPointCategory Debug name.

Shared query_for_keyword dispatch keeps the inline-kwargs path and the diff path in lock-step.

Module-header docs updated

src/query/mod.rs now documents the new forms and shows the desugaring:

```text
(category PA001 :severity Critical :pr-state nil)
≡ (and (rule-id PA001) (severity Critical) (pr-state nil))

(diff :since 2026-04-12 :category PA022)
≡ (and (since 2026-04-12) (rule-id PA022))
```

Test plan

  • cargo test --lib --no-default-features300 passed (288 before; 12 new).
  • cargo clippy --all-targets --no-default-features -- -D warnings — clean.
  • End-to-end smoke against the binary with the three verbatim issue expressions — all parse, all run, all return "No matches" against an empty hexad store (the expected outcome with no findings registered):
    • (crosslang :from UnsafeFFI :to ProofDrift)
    • (category PA001 :severity Critical :pr-state nil)
    • (diff :since 2026-04-12 :category PA022)

Backwards compatibility

  • Pure addition. Every existing query expression continues to parse to the exact same Query AST. Verified by running the full existing test suite (288 tests) unchanged.
  • The single-clause diff form unwraps to the underlying clause, so AST consumers never see a needless Query::And wrapper.

Out of scope

  • The pre-existing cargo fmt drift in src/assail/analyzer.rs, src/bridge/{classify,lockfile,reachability}.rs, and src/main.rs discovered while running checks. Filing separately to keep the diff scoped.

Refs #33.

🤖 Generated with Claude Code

hyperpolymath and others added 3 commits May 30, 2026 20:31
just isn't packaged for ubuntu-22.04 stock apt. Inline the commands the
recipes wrapped so CI no longer needs apt-get install just. Local
contributors keep the Justfile shortcuts unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Chapel 2.8.0 .deb apt-installs but fails with "Depends: libunwind-dev"
on stock ubuntu-22.04 runners — dpkg bails before unpacking. Install
libunwind-dev first across all 4 Chapel install sites.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… kwargs + PA-id auto-route

Issue #33's body advertises three example query expressions. Two of them
parsed-then-errored or parsed-then-matched-nothing under the existing
grammar:

  (category PA001 :severity Critical :pr-state nil)
    → parse error: "expected ')', got Atom(":severity")"

  (diff :since 2026-04-12 :category PA022)
    → parse error: "unknown query head: diff"

  (category PA001)
    → parsed, but matched zero findings — `category` expects the
      `WeakPointCategory` Debug name (e.g. "UnsafeCode"), not a rule ID

This patch makes all three literal expressions in the issue work as
documented:

* New `diff` head — keyword-only sugar for `(and (kw VALUE) ...)`,
  unwrapped to the single clause when only one kwarg is supplied.
* Inline `:keyword VALUE` kwargs accepted on every unary head
  (`category`, `rule-id`, `severity`, `repo`, `file`, `pr-state`,
  `since`) via a shared `parse_trailing_kwargs` helper. Desugars to
  `(and head-positional kw-clauses…)`. Existing single-arg forms keep
  parsing to the same atomic `Query` variants.
* `(category PAxxx)` auto-routes to `Query::RuleId` so the issue's
  literal expression actually selects findings.

Shared `query_for_keyword` dispatch keeps inline-kwargs and `diff`
in lock-step — adding a new unary head requires a single row.

Docs updated in the `src/query/mod.rs` module header with the new
supported forms and a worked desugaring example.

12 new unit tests (300 total, was 288):
  parse_category_pa_id_auto_routes_to_rule_id
  parse_category_word_does_not_auto_route
  parse_issue_example_category_with_inline_kwargs
  parse_issue_example_diff_form
  parse_diff_with_single_kwarg_unwraps
  parse_diff_empty_errors
  parse_diff_rejects_unknown_keyword
  parse_diff_rejects_positional_arg
  parse_inline_kwargs_on_severity_head
  parse_inline_kwargs_on_since_head
  run_issue_example_category_with_kwargs_matches
  run_diff_form_matches_recent_findings

End-to-end smoke against the three issue examples: all parse, all run,
all return "No matches" against an empty store (correct).

`cargo test --lib`: 300 passed.
`cargo clippy --all-targets --no-default-features -- -D warnings`: clean.

Refs #33.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath
Copy link
Copy Markdown
Owner Author

FYI: panic-attack Base ruleset now requires chapel-ci-gate (single context, replaces the 6 individual chapel-ci jobs). This PR's workflow predates the gate, so it can't satisfy the new required check. Once #90 lands, run gh pr update-branch 88 (or push a refresh) to pick up the gate workflow. Auto-merge will then proceed normally.

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