Semgrep matches code against patterns it already knows.
Acutis formally verifies code it has never seen.
Semgrep is a pattern matcher — it finds code that looks like known vulnerable patterns. Acutis is a formal verifier — it proves whether data flow properties hold at security boundaries. The distinction matters when AI writes code that doesn't match any known pattern.
def search(term): # term: params → {USER_CONTROLLED, SQL_META}
q = build_query(term) # unknown call → properties preserved
db.run(q) # SQL sink + SQL_META present → BLOCK
cursor.execute("SELECT * FROM users WHERE id=" + user_id)
python.lang.security.audit.formatted-sql-query
def search(term):
q = build_query("products", term)
return db.run(q)
build_query not in the database
Semgrep and Acutis both integrate with AI coding assistants via MCP. But what happens after the code is generated is fundamentally different.
Semgrep's MCP plugin bundles Hooks and Skills to scan every file an agent generates using Semgrep Code, Supply Chain, and Secrets. The scanning itself is still pattern-based — it runs the same Semgrep rules, just triggered automatically. Acutis doesn't run rules at all. It formally verifies whether dangerous properties (like MAY_CONTAIN_SQL_META) reach security boundaries unchecked.
| Acutis | Semgrep | |
|---|---|---|
| Analysis method | Property lattice — formal taint verification | Pattern matching against rule databases |
| Rule maintenance | Zero — AI provides all semantic info | Thousands of rules (4,000+ with Pro rules) |
| Novel functions | Handled — unknown = dangerous (top of lattice) | Missed unless a rule covers that function |
| MCP integration | Yes — formal verification in the loop | Yes — pattern scanning in the loop |
| What MCP scans | AI-generated code snippets with security contracts | Entire files post-write (Code, Supply Chain, Secrets) |
| Remediation | Property flow traces — AI fixes and re-verifies | Rule-based findings — AI regenerates until clean |
| Speed | 0.034ms per scan | Milliseconds to seconds depending on ruleset |
| False negatives | 0 on CVEFixes benchmark (F1 = 1.0) | Depends on rule coverage for that pattern |
| Trust model | Zero trust — unknown = dangerous, BLOCK by default | Permissive — no rule = no finding |
| CWE coverage | CWE-79, CWE-89 (extensible) | Hundreds of CWEs + secrets + supply chain |
| Language support | Python, JavaScript | 30+ languages |
Semgrep's power comes from its rule database — thousands of rules matching known vulnerable patterns. But AI invents new function names, wrappers, and abstractions that don't exist in any database. You can't enumerate what doesn't exist yet.
When Semgrep encounters a function it has no rule for, it says nothing. No finding, no warning. The code passes. Acutis treats unknowns as dangerous by default — if it can't prove something is safe, it blocks.
Semgrep's MCP scans entire files after they're written. Acutis verifies the specific code snippet the AI just generated, with full context about what's a source, sink, and transform. More precise, fewer false positives.
To be fair.
Semgrep covers 30+ languages, hundreds of CWEs, supply chain vulnerabilities, and secrets detection. Acutis focuses on formal verification of injection vulnerabilities (CWE-79, CWE-89) with an extensible architecture.
Years of CI/CD integrations, team dashboards, and enterprise workflows. Semgrep is battle-tested at scale across thousands of organizations.
Semgrep scans your entire codebase, not just AI-generated snippets. It catches known-bad patterns in code regardless of who wrote it. Acutis is purpose-built for the AI generation loop.
Acutis verifies at the point of generation with formal guarantees. Semgrep provides broad coverage in CI/CD. They're complementary — Acutis catches what Semgrep can't (novel patterns), Semgrep catches what Acutis doesn't cover yet (secrets, supply chain, broader CWE set).