Content Inspector

See what’s hidden in your text or files — invisible characters, metadata, and content provenance. No account, no upload; everything runs in your browser.

What is in this content?

No key, nothing to configure. Paste text or drop a file and this reports what can actually be determined about it — sorted by how much each finding is really worth.

The lab behind the tool: a working implementation of Scott Aaronson’s exponential-race text watermark — the argmax rt,i1/pt,i scheme — and a detector for it with an exact p-value. Generate watermarked and unwatermarked text, score either one, and measure how much editing it takes to destroy the signal.

This detects watermarks made with a key you hold. The signal is a correlation between the emitted tokens and a keyed pseudorandom function. Without the key there is nothing to correlate against and no statistic to compute — so this cannot tell you whether some arbitrary text came from a commercial model. It verifies your own generations, or a faithful replica like the one on the Generate tab.

Input

Examples

Every example below is scored with your current key, live. Read them before you look at the numbers — the first two are drawn from the identical distribution and nothing in the prose separates them. The third is the scheme's real failure mode: text that genuinely carries the watermark and still cannot be found.

Toy model — generated now, with your key

Human writing — never watermarked, shown to check for false positives

Blind test

Two passages from the same model, the same temperature and the same random seed — so they open with the same words and draw from the same distribution at every step. One was sampled with the watermark, one without. Nothing else differs. Pick the watermarked one before revealing.

Toy model

A word-level bigram model with unigram backoff, trained in-page on a small sample corpus. The text it writes is not meant to be coherent — it exists to produce honest probability distributions so the watermark and the detector have something real to work on.

Temperature is the entropy knob, and entropy is what carries the watermark. Turn it down and the model gets more confident, the race has less freedom to encode anything, and the detector goes blind — which is the scheme's central limitation, not a flaw in this implementation.

Robustness

Takes the current Detect input, applies increasing amounts of editing, and rescores. Each point is the mean of 6 runs.

The scheme

At position t the model produces a distribution pt,i over the vocabulary. A keyed pseudorandom function turns the previous k tokens into a value rt,i ∈ [0,1] for every candidate token. The sampler then emits

argmaxi rt,i1/pt,i ≡ argmaxi ln(rt,i) / pt,i

The two forms are the same ordering, but only the second survives floating point: with p = 0.01 the first is r100, which underflows to zero. Writing Ei = −ln ri ~ Exp(1) makes it the classic exponential race, argmin Ei/pi, which samples exactly from p. The watermark is free: the output distribution is untouched. What changes is that the choice is now a deterministic function of the key.

Detection

The detector recomputes r for the token that was actually emitted and sums

score = Σt ln( 1 / (1 − rt,xt) )

It never needs p. That is the property that makes the scheme deployable — verification requires the key and the tokenizer, not the model.

If the text has nothing to do with the key, each r is uniform, so each term is exactly Exp(1) and the total is Gamma(T, 1). The p-value is the upper tail of that distribution — computed here in log space, so it stays meaningful far below 1e-308. When the text was produced under the key, the race systematically favoured tokens with r near 1, and the sum runs high.

Why repeated contexts are skipped

Identical context plus identical token gives an identical r. Those terms are not independent, so counting them again would break the Gamma(T,1) null and manufacture significance out of ordinary repetition. Each distinct (context, token) pair is therefore scored once. Turning the checkbox off and scoring a repetitive passage shows what that guard is worth.

The same determinism has a second consequence, visible on the Generate tab: because a repeated context forces a repeated choice, a watermarked model with a small state space eventually falls into a loop. At k = 3 the toy model here locks into a cycle after roughly fifty tokens and stops producing new evidence no matter how much more text you ask for. Real models have effectively unbounded state, so this shows up rarely — but it is the reason detection strength is measured in distinct positions rather than length.

What the attack numbers show

An edit's damage is local. Changing a token destroys the evidence at that position and at the next k positions whose context window contains it; then the window slides past and scoring resumes exactly as before. Deletion and insertion do not knock the rest of the document out of alignment, because the context is the previous k tokens rather than a running hash of the whole prefix. Measured here, substitution, deletion and insertion all cost roughly k+1 positions per edit and land within noise of each other.

That gives the real robustness rule: the watermark survives while edits × (k+1) stays well under the number of distinct scored positions. Raising k buys a stronger signal per unit of text and pays for it with proportionally more fragility per edit. And it explains why paraphrase is the effective attack — not because it is clever, but because it edits everywhere at once.

Limits worth stating plainly

  • No key, no detection. This is not a general "was this AI written" tool, and no such tool follows from this math. A third party's watermark needs a third party's key.
  • Low entropy defeats it. Factual, templated, or short text carries little signal regardless of key.
  • The tokenizer must match. Scoring with a different tokenizer than generation used yields noise. The Token IDs input mode exists so you can feed real model tokens instead of this page's word splitter.
  • One key, one test. Scanning a document against many candidate keys is multiple testing; a p < 0.01 found among 200 keys means nothing on its own. The Calibrate button makes that concrete.

Open this page with ?selftest to run the statistical test suite in the browser.