One engine, many surfaces
The architectural rule that makes the rest of the system trustworthy: the core engine is independent of every front-end. CLI, MCP, and API are thin adapters that all call the same runAudit and policy/gate functions, so security logic exists in exactly one place and behaves identically everywhere. No surface can drift into its own private notion of "secure".
One honest nuance: the secret scanner and the gate now have two byte-compatible implementations — the Rust security engine (crates/veylqorix-engine) and the TypeScript core. They are cross-verified against the same golden vectors, so a finding id and its redaction look identical on either side; runAudit calls the engine when the binary is available and degrades to the TypeScript path with a labeled note when it is not. The guarantee the surfaces rely on is the contract — one finding schema, one gate decision, stable exit codes — not which language produced it.

AI clients (Claude Code, Codex, Cursor) reach one security core through a portable skill and MCP adapters.
The MCP server exposes six tools — scan_repository, scan_dependencies, scan_secrets, run_security_checks, get_findings, validate_fix — with Zod-validated inputs and structured, evidence-based output. Its filesystem access is confined to configured workspace roots: path traversal and symlink escapes are rejected. Secret values are redacted in every response. And the server has no write path at all — it cannot commit, push, or modify the repository it is scanning.
Verify, don’t trust
One of the six tools, validate_fix, encodes the whole protocol: after you fix a finding, the scan re-runs to confirm the finding no longer reproduces. Remediation is part of the loop, not a suggestion — a fix is not confirmed without a rescan.