Commit 3f8400f
## Summary
Closes the residual gap on
[#33](#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 head** — `category`,
`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
- [x] `cargo test --lib --no-default-features` — **300 passed** (288
before; 12 new).
- [x] `cargo clippy --all-targets --no-default-features -- -D warnings`
— clean.
- [x] 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](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f988566 commit 3f8400f
2 files changed
Lines changed: 280 additions & 19 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
3 | 21 | | |
4 | 22 | | |
5 | 23 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| 14 | + | |
14 | 15 | | |
15 | 16 | | |
16 | 17 | | |
| |||
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
25 | 42 | | |
26 | 43 | | |
27 | 44 | | |
| |||
236 | 253 | | |
237 | 254 | | |
238 | 255 | | |
239 | | - | |
240 | | - | |
| 256 | + | |
241 | 257 | | |
242 | 258 | | |
243 | 259 | | |
244 | | - | |
245 | | - | |
| 260 | + | |
246 | 261 | | |
247 | 262 | | |
248 | 263 | | |
249 | | - | |
250 | | - | |
| 264 | + | |
251 | 265 | | |
252 | 266 | | |
253 | 267 | | |
254 | | - | |
255 | | - | |
| 268 | + | |
256 | 269 | | |
257 | 270 | | |
258 | 271 | | |
259 | | - | |
260 | | - | |
| 272 | + | |
261 | 273 | | |
262 | 274 | | |
263 | 275 | | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
| 276 | + | |
271 | 277 | | |
272 | 278 | | |
273 | 279 | | |
| |||
290 | 296 | | |
291 | 297 | | |
292 | 298 | | |
293 | | - | |
294 | | - | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
295 | 314 | | |
296 | 315 | | |
297 | 316 | | |
| |||
388 | 407 | | |
389 | 408 | | |
390 | 409 | | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
391 | 499 | | |
392 | 500 | | |
393 | 501 | | |
| |||
1111 | 1219 | | |
1112 | 1220 | | |
1113 | 1221 | | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
| 1225 | + | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
| 1233 | + | |
| 1234 | + | |
| 1235 | + | |
| 1236 | + | |
| 1237 | + | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
| 1253 | + | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | + | |
| 1283 | + | |
| 1284 | + | |
| 1285 | + | |
| 1286 | + | |
| 1287 | + | |
| 1288 | + | |
| 1289 | + | |
| 1290 | + | |
| 1291 | + | |
| 1292 | + | |
| 1293 | + | |
| 1294 | + | |
| 1295 | + | |
| 1296 | + | |
| 1297 | + | |
| 1298 | + | |
| 1299 | + | |
| 1300 | + | |
| 1301 | + | |
| 1302 | + | |
| 1303 | + | |
| 1304 | + | |
| 1305 | + | |
| 1306 | + | |
| 1307 | + | |
| 1308 | + | |
| 1309 | + | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + | |
| 1313 | + | |
| 1314 | + | |
| 1315 | + | |
| 1316 | + | |
| 1317 | + | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
| 1322 | + | |
| 1323 | + | |
| 1324 | + | |
| 1325 | + | |
| 1326 | + | |
| 1327 | + | |
| 1328 | + | |
| 1329 | + | |
| 1330 | + | |
| 1331 | + | |
| 1332 | + | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
| 1339 | + | |
| 1340 | + | |
| 1341 | + | |
| 1342 | + | |
| 1343 | + | |
| 1344 | + | |
| 1345 | + | |
| 1346 | + | |
| 1347 | + | |
| 1348 | + | |
| 1349 | + | |
| 1350 | + | |
| 1351 | + | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
| 1355 | + | |
| 1356 | + | |
1114 | 1357 | | |
0 commit comments