All work AI SYSTEMS / WRITING TOOLS live

13  /  AI SYSTEMS / WRITING TOOLS

AI Humanizer

Most rewriters promise detector evasion nobody can deliver. Mine guarantees only that keywords survive.

June 2026Next.js 15 (App Router)React 19TypeScript 5 (strict)Vercel AI SDK v5OpenAI (gpt-4o-mini + embeddings)Server-Sent EventsTailwind v4 + shadcn/uinginx + PM2 + Let's Encrypt

The challenge

AI drafts have a tell. Uniform sentence lengths, transition-word openers, em-dashes, the same twenty words. Most tools that claim to fix this spin synonyms, which makes the writing worse, or promise guaranteed detector evasion, which nobody can honestly deliver. Underneath sits a second problem: a rewrite that quietly drops or alters a target keyword has failed, however natural it reads.

What I built

I built a Next.js app with a landing page and a two-pane streaming editor. One server pipeline does the work — preclean, keyword index, streamed rewrite, deterministic postprocess, keyword verify-and-repair, statistics — emitting Server-Sent Events so the draft appears as it is written, then a single terminal event swaps in the final text, a keyword report and a before/after writing-statistics meter. Locked keywords carry a hard guarantee I enforce in code rather than in the prompt. Three strength modes, optional citation protection, per-IP rate limiting held in process memory, no accounts, no database, no stored text. It runs on two of my own servers behind nginx and Let's Encrypt rather than a managed platform.

How it works

EVERY REWRITE Keyword indexbuilt before the rewrite Streamed rewritelocked phrases stay visible Verify, in codeverbatim, count, sentence Keyword reportgoes out with the text IF A PHRASE DOES NOT SURVIVE Rewrite that sentenceonly that one, masked Trim surplus copiesno keyword stuffing Splice the originalsentence back, byte for byte A hard guarantee in code, not in the prompt
The mechanism, drawn from the build.

What it looks like

AI Humanizer — screenshot
Running locallyAI SYSTEMS / WRITING TOOLS

The detail

01

Keyword lock

Locked phrases stay visible to the model so it can write around them, then a deterministic pass checks that every phrase survived verbatim, at the same count, in its source sentence. I repair failures by re-rewriting only the offending sentence with the phrase masked as ⟦KW0007⟧, trim surplus copies to stop keyword stuffing, and splice the original sentence back byte for byte when anything still fails. 27 of my suite's 60 unit tests cover that one module.

02

Refusing the trick

I label the stats panel writing statistics, not a detector verdict, and nothing in the app claims guaranteed evasion. My improvements doc names what I deliberately left out: homoglyph and zero-width injection, blind synonym spinning, recursive rewrite-until-evaded loops, and optimising against any single detector score. Chasing a detector reading costs writing quality, so what I aim at is naturalness with the meaning intact.

03

Two fail-open gates

When a deterministic lint on burstiness, lexical diversity, transition density and em-dash rate still reads as AI-ish, the pipeline runs one critique-and-revise pass. Never recursive. An optional N-best reranker draws extra candidates in parallel and keeps the most natural one, and I put both gates behind an embedding cosine-similarity check against the original — a failed candidate or a missing embedding never blocks the rewrite, only cancellation does.

04

Eval harness

One command scores input-to-output deltas on burstiness, MTLD, em-dash and transition density, contractions and Flesch across a fixture set, then diffs the report against a saved baseline. I load the library modules directly through Node ESM module-customisation hooks that resolve the path alias and stub Next's server-only shim, so it needs no bundler. Default runs are fully offline; I put the live pipeline, detector and perplexity passes behind opt-in flags.

05

Streaming past nginx

The rewrite is Node-runtime SSE on my own machines rather than a managed platform, so the tokens had to survive my own proxy. PM2 on the app server, a separate nginx reverse proxy terminating SSL with proxy_buffering off for the SSE route, and X-Accel-Buffering set to no in the response headers as a second defence. I verified it end to end over HTTPS on deployment day — token events arriving, then settled.

The outcome

The site is up: landing page and editor both return 200 over HTTPS on a current certificate, which I checked on 16 September 2026. The rewrite endpoint is not working today — it returns an upstream provider error, because the OpenAI key on the server needs rotating, which my deployment notes already flagged. I built and deployed it inside three days in June 2026, including a second pass on rewrite quality after I scrapped the first engine and went back to research. The 60-test suite passes, and the app boots and renders both routes from a clean checkout.