Living Websites

An AI content detector that runs in CI, not after you publish

Nearly every AI content detector is a web form. You finish a draft, paste it in, read a probability score, and move on. By then the text is already written, and often already live. de-AI gate works the other way around. It is built to run inside your build, as a pre-commit hook or a CI step, and it fails the job the moment a tell slips through.

The gap: detection happens after you publish

A web-based detector is post-hoc by design. It checks one page at a time, by hand, after the writing is done. Nothing about it stops AI-written text from reaching production, because it sits outside the process that ships your content. It is a spot check, not a control.

For a team shipping content on a cadence, a spot check does not hold. Pages go out faster than anyone can paste them into a form, and the one that skips the check is the one that carries the tell.

The gate: a hard exit code in your pipeline

de-AI gate is built to sit in the pipeline itself. It scans local files, served HTML and authored records, and returns a hard exit code: 0 when clean, 1 on any hard violation. A non-zero exit fails the step, so the build stops before the content ships.

It stays quiet enough to leave switched on. Only high-precision tells are hard failures. Structural heuristics, such as sentence-length variance and transition scaffolding, report as advisory warnings and never change the exit code, so the gate does not cry wolf on legitimate human copy.

Wire it up

A CI step is the command plus its exit code. Run the scan in a job or a pre-commit hook, and let a non-zero result fail the run. Run the served-HTML scan and the record scan as separate invocations.

  • node cli.mjs --html ./public (fails the step with exit 1 on any hard tell in served pages)
  • node cli.mjs --records ./data (fails on smuggled curly quotes in authored records)
  • python gate.py --html ./public --records ./data (same contract, standard-library Python)
  • node cli.mjs --html ./public --warn-only (non-blocking baseline while you clean up existing content)

Why deterministic matters for a gate

A gate has to be trustworthy to leave on. If it blocked builds on a probability, every false positive would be a blocked merge over text a human actually wrote, and the team would switch it off within a week. de-AI gate blocks only on a literal tell that is present in the file, so a failed build always points at a real character or phrase you can see and fix.

Keep reading, then get the source.

de-AI gate is open source under the MIT license. Drop it into a pre-commit hook or a CI job and let the exit code do the work.

Get de-AI gate on GitHub

FAQ

Will it block my merge?

Yes, on a hard violation. A hard tell returns exit code 1, which fails the step and blocks the merge. Start with --warn-only for a non-blocking baseline, clean up what it finds, then switch to blocking mode once the build is green.

Does it slow the build down?

It runs deterministic regex over local files with no network calls and no dependencies to install, so it adds a fast local scan to the job rather than a remote request.

What is the difference between the --html and --records scans?

The --html scan reads served HTML and prose for character and phrase tells after stripping CSS and comments. The --records scan reads authored JS, JSON, or TS records for smuggled curly quotes and similar substitutions that a served-HTML scan misses. Run them as separate invocations.