ccdd-gate
Deterministic gates for AI-written code

A small model implements.
An arbiter that can't be bribed decides.

ccdd-gate seals a task's property-tests and complexity budget before any agent touches the target. Same input, same verdict — every run.

Gate 00

The verdict a demo never shows you

A small model implements fast. Nothing about that tells you whether the result respects the budget your team signed off on, or whether the tests it "passes" are the ones that actually matter.

The usual fix is a bigger model reviewing its own work — slower, non-deterministic, and it costs tokens every single time. ccdd-gate replaces that review with a script: complexity measured by AST, tests frozen by hash, a verdict that never changes between runs.

Gate 01

Two pillars, one arbiter

CODE

The complexity/tests gate: cyclomatic complexity, nesting depth, parameter count and length, measured by real AST across 14 languages — never estimated. A function only passes below the signed budget, with its frozen property-tests green.

EVALS

For an agent's non-deterministic output (text/JSON): a frozen, signed dataset plus deterministic checks — schema, groundedness, PII, trajectory — decide PASS/FAIL with zero LLM calls (Tier 1). A bounded LLM judge is Tier 2, opt-in, and its own agreement with a human golden set is measured before anyone trusts it.

Gate 02

How a task moves through the gate

The contract's exit code is the only opinion that counts — from lint to verdict.

1
Lint
2
Freeze tests
🔒
Sign budget
3
Implement
4
Gate
VERDICT: PASS
Gate 03

The oracle is only as strong as it's proven to be

The tests pass clean.
Green tests look like a strong oracle — but green only means no one has tried to break it yet.
So mutation_audit tries.
A fixed set of mutations — flipped comparators, swapped operators — run against the frozen tests. A mutant that survives means the oracle missed it.
A weak spot, found.
One boundary case slipped through untested. Add the test that kills it, and the score — not a feeling — says the oracle is strong now.
Gate 04

By the numbers, as of this file

Every figure below is checked into the repository — verifiable, not asserted.

14languages measured by real AST
23MCP tools, one LLM call among them
541tests, zero mocks on the crypto path
0tokens spent to compute a verdict
9signed governance rules, Ed25519-verified
Gate 05

What gets gated, what stays out

The honest boundary is part of the method, not a gap in it.

Can be gated

  • Complexity and length, measured by AST — never estimated by a model
  • A frozen property-test's pass/fail, hash-sealed before the implementer sees the task
  • A signature drift between the contract and the implementation, before it breaks a caller
  • A complexity exception, but only with a real Ed25519 signature from a registered reviewer

Stays out, declared

  • Whether a test oracle is well-designed — mutation testing measures its strength, it doesn't write it for you
  • Coherence and usefulness of an agent's prose — that's what the opt-in Tier 2 judge is for, and even it gets audited
  • The implementer's reasoning. ccdd-gate contracts the artifact a model produces, never how it thinks.
Gate 06

Fourteen languages, one oracle

A frozen conformance suite is the reference: every new tree-sitter backend must reproduce the same cyclomatic, nesting and parameter counts as the Python baseline before it's accepted.

Python
TypeScript
JavaScript
Rust
Go
Java
C#
PHP
Ruby
Kotlin
C
Swift
C++
TSX

Python is native (stdlib AST, zero deps); the other thirteen are one optional dependency away (tree-sitter grammars) — a missing grammar degrades to an announced no-op, never a silent skip.

Read the gate yourself

MIT-licensed. Every claim on this page is checked into the repository that backs it.

— Mauricio Perera