Skip to content

feat(query): panic-attack query subcommand (issue #33 S3)#57

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/issue-33-s3-query
May 27, 2026
Merged

feat(query): panic-attack query subcommand (issue #33 S3)#57
hyperpolymath merged 1 commit into
mainfrom
feat/issue-33-s3-query

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Third slice of #33. Adds a `panic-attack query` subcommand that evaluates a small S-expression query language over the per-finding hexads from #55 (S1) joined with the campaign-state hexads from #56 (S2).

Stacked on #56 — diff against `main` includes the S1+S2 changes until those land; this PR rebases cleanly.

Supported forms (S3 initial)

```scheme
(category UnsafeCode)
(rule-id PA004)
(severity Critical)
(repo ) ; case-insensitive substring
(file ) ; case-insensitive substring
(pr-state pr-filed|pr-merged|pr-closed|dismissed|nil)
(and ...)
(or ...)
(not )
```

`(pr-state nil)` matches any finding without a campaign hexad — i.e. the operationally important "open work not yet PR'd" view that the estate-sweep campaign needs most.

CLI

```
panic-attack query "(and (category UnsafeCode) (pr-state nil))"
panic-attack query "(severity Critical)" --format json
panic-attack query "(repo alpha)" --verisimdb-dir verisimdb-data
```

Default output: fixed-width table. JSON via `--format json`.

Deferred to S3 follow-ups

Three follow-ups will land in the next PRs in this stack:

  • `(crosslang :from FFI :to ProofDrift)` — needs integration with `src/kanren/crosslang.rs`.
  • `(diff :since :category )` — needs an explicit baseline-run cursor.
  • `panic-attack campaign poll` (was S2 scope cut) — GitHub PR-state polling.

Implementation notes

  • Small hand-rolled S-expression tokenizer/parser (~170 LOC) — doesn't depend on the a2ml parser since the query surface is narrower.
  • Evaluator pre-joins findings with their latest campaign event (newest-by-`created_at` wins per `finding_id`) before filtering. `(pr-state ...)` is a free clause inside `and`/`or` rather than a special case.

Test plan

  • `cargo test --lib` — 239 green (19 new in `src/query/`).
  • `cargo clippy --all-targets -- -D warnings` — clean.
  • `cargo fmt --all` — clean.
  • End-to-end CLI smoke: hand-crafted finding hexad + `campaign register-pr` + `query (and (category UnsafeCode) (pr-state pr-filed)) --format json` returns the expected JSON with the joined campaign state.

Refs #33. Stacked on #56 (S2) → #55 (S1).

🤖 Generated with Claude Code

Adds the third slice of issue #33: a panic-attack query subcommand that
evaluates a small S-expression query language over the persisted
per-finding hexads (S1) and campaign-state hexads (S2), joined by
finding_id.

Supported forms in this initial S3:

  (category UnsafeCode)
  (rule-id PA004)
  (severity Critical)
  (repo <name-substring>)        ; case-insensitive substring
  (file <path-substring>)        ; case-insensitive substring
  (pr-state pr-filed|pr-merged|pr-closed|dismissed|nil)
  (and <expr> <expr> ...)
  (or  <expr> <expr> ...)
  (not <expr>)

`pr-state nil` matches any finding without a campaign hexad — i.e. the
operationally important "open work not yet PR'd" view that the
estate-sweep campaign needs most.

CLI:
  panic-attack query "(and (category UnsafeCode) (pr-state nil))"
  panic-attack query "(severity Critical)" --format json
  panic-attack query "(repo alpha)" --verisimdb-dir verisimdb-data

Output: fixed-width table by default, JSON via `--format json`.

Deferred to S3 follow-ups (recorded in the module header):
- (crosslang :from FFI :to ProofDrift) — needs integration with
  src/kanren/crosslang.rs.
- (diff :since <date> :category <X>) — needs an explicit baseline-run
  cursor beyond created_at.

Implementation notes:
- Small hand-rolled S-expression tokenizer/parser in src/query/mod.rs
  (~170 lines including escape handling for quoted strings and `;`
  line comments). Doesn't depend on the a2ml parser since the query
  surface is narrower.
- Evaluator pre-joins findings with their latest campaign event
  (newest-by-created_at wins per finding_id) before filtering. That
  keeps `(pr-state ...)` a free clause inside `and`/`or` rather than
  forcing a special-case in the loop.

Tests: 19 new in src/query/ — 8 parser (positive + 3 rejection cases),
9 evaluator (each filter, and/or/not, pr-state nil/filed/excluded), 2
renderer. Full lib suite: 239 green. Clippy clean.

CLI smoke validated: writing a hand-crafted finding hexad + invoking
campaign register-pr + query returns the expected JSON with the
pr-filed state joined in.

Refs #33. Stacked on #56 (S2). Diff against main includes S1+S2
changes until they land; this PR rebases cleanly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath hyperpolymath force-pushed the feat/issue-33-s3-query branch from c41905c to bc07d0f Compare May 27, 2026 13:24
@hyperpolymath hyperpolymath merged commit 732b409 into main May 27, 2026
15 of 25 checks passed
@hyperpolymath hyperpolymath deleted the feat/issue-33-s3-query branch May 27, 2026 13:25
hyperpolymath added a commit that referenced this pull request May 27, 2026
Adds two query forms to the panic-attack query subcommand:

1. (since 2026-04-12) — match findings whose first_seen_run (when ISO-
   formatted) or hexad created_at is >= the cutoff. RFC-3339 strings
   sort lexicographically, so a string >= compare is exact for any
   well-formed timestamp. Combined with `and`, expresses the
   "(diff :since DATE :category CAT)" use case the issue calls out:
       (and (since 2026-04-12) (category CryptoMisuse))

2. (crosslang :from FROM_CAT :to TO_CAT)  — co-occurrence proxy for
   FFI/cross-language reachability. Matches a TO-category finding in a
   repo that also has at least one FROM-category finding. Most
   FFI-driven proof drift surfaces in the same repo, so this is the
   operationally useful approximation until kanren-crosslang facts are
   persisted as hexads (a later slice). Both keyword and positional
   shapes accepted:
       (crosslang :from UnsafeFFI :to ProofDrift)
       (crosslang UnsafeFFI ProofDrift)

Implementation:

- New Query variants Since(String) and Crosslang { from, to }.
- Parser extended with `since` and `crosslang` heads; crosslang
  accepts both positional and `:from`/`:to` keyword forms.
- Evaluator's load_context now also builds a repo→categories index so
  (crosslang ...) is O(1) per row.

Tests: 9 new (5 parser positive + 2 rejection cases, 2 crosslang
evaluator, 1 since evaluator). Lib total: 248 green. Clippy clean
with -D warnings.

Refs #33. Stacked on #57 (S3) — diff against main includes the
S1+S2+S3 changes until they land.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 27, 2026
## Summary

Adds two query forms to \`panic-attack query\`, closing the S3
follow-ups called out in #57:

1. **\`(since 2026-04-12)\`** — matches findings whose
\`first_seen_run\` (when ISO-formatted) or hexad \`created_at\` is ≥ the
cutoff. RFC-3339 strings sort lexicographically, so the string \`>=\`
compare is exact for any well-formed timestamp. Combined with \`and\`,
this expresses the **\`(diff :since DATE :category CAT)\`** use case the
issue calls out:
   \`\`\`scheme
   (and (since 2026-04-12) (category CryptoMisuse))
   \`\`\`

2. **\`(crosslang :from FROM_CAT :to TO_CAT)\`** — co-occurrence proxy
for FFI/cross-language reachability. Matches a \`TO\`-category finding
in a repo that also has at least one \`FROM\`-category finding. Most
FFI-driven proof drift surfaces in the same repo, so this is the
operationally useful approximation until \`kanren::crosslang\` facts are
persisted as hexads.
   Both shapes parse:
   \`\`\`scheme
   (crosslang :from UnsafeFFI :to ProofDrift)
   (crosslang UnsafeFFI ProofDrift)
   \`\`\`

> Stacked on #57 — diff against \`main\` includes the S1+S2+S3 changes
until they land.

## Test plan

- [x] \`cargo test --lib\` — 248 green (9 new).
- [x] \`cargo clippy --all-targets -- -D warnings\` — clean.

Refs #33. Stacked on #57.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 27, 2026
… follow-up) (#61)

## Summary
- Adds a `HexadSemantic.crosslang: Option<CrosslangSemantic>` facet and
a
  `build_crosslang_hexads(...)` helper that drives the kanren
`CrossLangAnalyzer` per repo (ingest → extract → load_rules → analyze →
  query_interactions) and emits one hexad per derived
  `CrossLangInteraction`.
- New env var `PANIC_ATTACK_STORE_CROSSLANG_HEXADS` (separate from
  `PANIC_ATTACK_STORE_FINDING_HEXADS`) opts a run into emission;
  `persist_assemblyline_report` writes to `<dir>/hexads/crosslang/`
  file-side only.
- Adds `load_crosslang_hexads(base_dir)` so the paired query-evaluator
PR
  can match against persisted facts; falls back to empty `Vec` when the
dir is missing (the evaluator treats that as "use co-occurrence proxy").

## Why
Tightens the `(crosslang :from :to)` query from a same-repo
co-occurrence
proxy to a true FFI/cross-language reachability check against
persisted kanren-derived facts. PR 1 of a 2-PR stack; PR 2 switches the
evaluator over while preserving fall-back semantics.

## Test plan
- [x] `cargo test --lib` — 252 tests pass, including 4 new
      `storage::tests::*crosslang*` cases (build-empty, build-from-FFI,
      write/read roundtrip + missing-dir, env-var default-off + opt-in).
- [x] `cargo clippy --all-targets -- -D warnings` clean.
- [x] `cargo fmt --all` no diff.

Stacks under: issue #33 S1/S2/S3 PRs (#55, #56, #57, #58). Filed against
`main` per orphan-trap rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 74 issues detected

Severity Count
🔴 Critical 7
🟠 High 16
🟡 Medium 51

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in boj-build.yml",
    "type": "unknown",
    "file": "boj-build.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in cargo-audit.yml",
    "type": "unknown",
    "file": "cargo-audit.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "unknown",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in casket-pages.yml",
    "type": "unknown",
    "file": "casket-pages.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "unknown",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in coverage.yml",
    "type": "unknown",
    "file": "coverage.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dependency-review.yml",
    "type": "unknown",
    "file": "dependency-review.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in dogfood-gate.yml",
    "type": "unknown",
    "file": "dogfood-gate.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

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