When it runs
On every Write, Edit, and MultiEdit. The check is folded into the same tool call Claude already makes, so you don't see it as a separate step.
↳ writing src/auth/reset.ts…
flowrail-verify · deny
✗ no-secrets-in-code token compared with == at line 22
suggested fix use timing-safe equal
↳ retrying with the fix…
flowrail-verify · allow
✓ committedNine guardrails today
no-secrets-in-code: catches what Layer 1 can't (JWT shapes, connection strings, env vars accidentally inlined). Suppresses placeholders, test fixtures, sk_test_* keys.
agentic-no-scope-escalation: blocks writes outside the feature's declared surface area, against the active review's spec.
agentic-no-system-data-in-shared-content: blocks env-var contents, file contents, and infra metadata from leaking into anything network-facing.
no-destructive-infra-operations: blocks writes that encode destructive infrastructure operations.
app-security-authz: flags application-level authorization weaknesses in the new content.
no-broken-access-control: flags request-time IDOR/BOLA patterns and fail-open authorization in the new content.
no-csv-formula-injection: blocks spreadsheet formula injection (CWE-1236) in generated CSV and export content.
no-unsafe-file-upload: flags unrestricted file-upload handling (CWE-434) in the new content.
no-unvalidated-outbound-request: flags SSRF-shaped outbound requests built from unvalidated input (CWE-918).
All nine run on every verification; per-threat-category selection arrives in v1.
flowrail_verify_code
{
"design_review_id": "dr_7f3a9e2c",
"file_path": "src/auth/reset.ts",
"file_content": "import express from \"express\"; ...",
"guardrails": [
"no-secrets-in-code",
"agentic-no-scope-escalation",
"agentic-no-system-data-in-shared-content",
"no-destructive-infra-operations",
"app-security-authz",
"no-broken-access-control",
"no-csv-formula-injection",
"no-unsafe-file-upload",
"no-unvalidated-outbound-request"
]
}{
"decision": "deny",
"verdicts": [
{
"guardrail": "no-secrets-in-code",
"verdict": "fail",
"summary": "Token compared with == at line 22"
}
],
"additional_context": "Use timing-safe equal..."
}When verify denies, Claude almost always patches its own write and retries on the next pass. You see the cycle as a single noisy tool call, not a manual approval gate. Server-side, every call emits verification_completed; file content is hashed before storage.