Verdicts and authorization

View as Markdown

A verdict says what the evidence shows about who is driving a browser session. It is input to your decision, never the decision itself. Your application authenticates the user, checks their account permissions and decides every protected action.

The live classifier is heuristic-v4.33. This page describes its rules; how they changed over time is in the Changelog at the end.

What each verdict means

What each verdict means
VerdictScore (a fixed category code, not a probability)What it meansWhat it does not mean
human1Recent input in one page fits human patterns: varied trusted input or sufficiently measured mouse navigation, with timing a person can produce (keys tens of milliseconds apart, the pointer moving before a mouse click), and no automation flag or active agent marker anywhere in the session.Not proof of identity, and not a sign that the person may perform this action. A person can still be the wrong user, or be acting for an agent outside the browser. It is reported by the page, so it can be forged (see below).
agent (shown as "AI agent")99Recent evidence shows automation driving the page, or a valid Web Bot Auth signature from a reviewed operator.Not a sign the agent is malicious or unwanted. Many agents act for a signed-in user who asked them to. It also does not say which AI model is driving: generic automation never establishes that.
unknown50The evidence is not enough to decide either way. Fresh sessions usually start here.Not "probably human". Unknown is not counted as human: never counted, charged or treated as one.

Scores are fixed labels for the three verdicts (1, 50 and 99). They are not probabilities: do not compare them with thresholds. Branch on verdict. An AI agent verdict also carries a confidence band (High or Medium, below), which is a strength level, not a probability either.

What backs an AI agent verdict: confidence bands

Every AI agent verdict carries agentEvidence, which says what backs it, and confidence, a strength band read from it. The bands are strength levels, never measured probabilities. The dashboard shows them as a chip, "AI agent · High confidence" or "AI agent · Medium confidence", with how we know.

What backs an AI agent verdict: confidence bands
ConfidenceWhat earns it (agentEvidence)What it does at a protected actionChargeable
High: VerifiedSigned requests: a valid Web Bot Auth signature from a reviewed operator (verified)Follows the action's AI agent rule, Deny includedYes
HighAn automation trace: the webdriver flag, a driver-defined trace, or a headless browser (automation-trace); input injected by software (injected-input); sustained behaviour (sustained-behaviour); a behaviour change after a person (behaviour-change); two or more independent behaviour families agreeing on one page, with no physical-device input on the session (behaviour-corroborated, "Strong evidence: several behaviour signals agree"); Claude in Chrome's cursor driving the clicks (cursor-driven, "Claude's cursor is driving the clicks")Follows the AI agent rule, Deny includedYes
MediumBehaviour patterns alone: one behaviour family, or several when the session shows physical-device input (behaviour)Held for review (step-up) by default, even when the AI agent rule says Deny. The site owner can switch it to follow the AI agent rule (block)Never
LowReserved: nothing produces it today. A single weak signal stays Unknown, not AI agent——
UnknownNot enough to sayYour Unknown ruleNever
HumanHuman-like input from a physical deviceYour Human ruleNever

Edge evidence your backend forwards (Cloudflare, Fingerprint) is not a level: it is recorded beside the verdict and may only raise a decision (see Evidence sources below).

Medium-confidence AI agent verdicts are held for review by default

By default, an AI agent verdict on behaviour patterns alone (medium confidence) is held for review (review, heldInsteadOfDeny: true) when the action's AI agent rule says Deny, so your backend can settle it with its own check, such as a passkey or MFA prompt, Turnstile or its own approval: see step-up. Allow and Hold for review rules apply as set. It is never charged.

The site owner may turn on Block medium-confidence AI agent verdicts (Control › Rules). They then follow the AI agent rule like any other AI agent verdict, Deny included. The warning, in plain words: real people who behave unusually (assistive technology, touch-screen kiosks, remote desktops) could be blocked from that action, though never from the rest of your site.

Only the workspace owner can change it; admins and viewers see it. Every change is audited. Verify responses, decision records and the protection.decision webhook say which applied to a medium-confidence verdict: behaviourOnlyDenyEnabled (false: held for review, the default; true: the AI agent rule applied in full) and behaviourOnlyReason, a plain sentence.

High confidence follows the AI agent rule whatever this setting says. The No recent activity rule still applies to old evidence, as it does to every verdict, and a WebMCP tool call keeps the AI agent rule in full because it is agent-initiated by definition.

Protected actions remember an earlier AI agent

If a session was confidently detected as an agent earlier (not an analytics-only observation: a reading the dashboard and reports count as AI agent but that does not, by itself, select the AI agent rule at a protected action), a later Human reading is treated as Unknown when a protected action is decided. Your policy's Unknown branch then applies, so a person who takes over from an agent is handled the way you chose for uncertain sessions, never silently allowed on the human branch. The session's own verdict and history are unchanged; this only affects protected-action decisions.

Weighted evidence, without a probability claim

weightedEvidence is attached to internal verdicts and session details. The legacy score remains the fixed category label above. The evidence strengths are not percentages, confidence, chargeable-use inputs or authorization thresholds. The main result remains Human, AI agent or Unknown.

Evidence is grouped into automation environment, automation behaviour and human interaction. Within each family, only the strongest eligible observation contributes: repeated events, multiple detectors describing the same pointer/click pattern and overlapping behavioural combinations cannot add points. Automation family strengths can sum up to 100, while human support remains a separate value. No amount of weak centred-click or regular-timing evidence can establish AI agent without a qualifying rule. Vendor markers have no positive weight.

Existing freshness, sample counts, paired-interaction checks, input exclusions and telemetry-completeness requirements run before a rule contributes. Validated behavioural combinations contribute 80 or 85; direct automation environment indicators contribute 90; a verified operator signature contributes 100. A supported human pattern contributes 85. The internal decision boundary is 80 with a qualifying evidence rule; these values are engineering choices, not fitted or calibrated probabilities. Human and behavioural automation support in conflict yields Unknown; direct environment evidence retains its existing precedence. Human-blocking evidence (such as a vendor marker or provider-origin cap) cannot become automation support merely by blocking Human.

The detail explanation records fixed signal codes, family winners and separate human and automation strengths. Current evidence and the last recorded observation are separate; expiry must not attach current weights to a historical verdict. Controlled detector histories preserve the bounded explanation and compare it during replay. Version 4.6 remains separately executable, so comparisons do not silently run the new model under an old name.

These weights improve traceability and prevent correlated votes from accumulating. They do not establish real-world accuracy. Synthetic fixtures check regressions, while genuine human, accessibility and unseen-controller trials remain required. Assistive software can produce the same browser-visible signals as automation; zero false positives cannot be guaranteed.

How we know the agent's name

When a session is agent, the evidence may name the agent (the API field is attribution.controller), always together with how we know the name (attribution.strength). The dashboard shows the two side by side, for example "Claude in Chrome · Unconfirmed" (Words we use lists every term). Naming an agent never changes the verdict.

How we know the agent's name
How we know (strength)Based onHow far to trust the name
Verified (signed)A valid Web Bot Auth signature from a reviewed operator directoryThe operator is verified. The signature names the operator, not the user or the AI model, and authorizes nothing. A Verified name for a cloud browser platform (Intermediary) names the platform its customers' agents run on, not the customer agent.
Unconfirmed (weak-marker)Something the agent's tool leaves on the page, such as its overlay (a page marker), seen beside an agent verdictA hint. Anyone can add or rename it, and overlays can outlive the agent's control.
Self-reported (declared)The client named itself in its user agent (for example Agent-NovaAct/), seen beside an agent verdictA claim. Anyone can send or remove the token; it never changes the verdict or the usage category.
Not named (unattributed-automation)An agent verdict with no evidence naming the agentNothing is named. The dashboard shows these sessions as "Unnamed agent".

A page marker beside a human or unknown verdict names nobody. It is listed in pageMarkers as a technical note (a diagnostic). A missing marker or signature never means a person is present.

What a verdict can and can't prove

What a verdict can and can't prove
FamilyClues that count toward AI agent
TimingLong still pauses before clicks: three or more pauses of over 2 seconds, each ending in a mouse click, with no pointer movement, scrolling, selection or key press in between (at least 80% of such pauses). Reactions faster than a person reacts: three or more mouse presses under 50 ms after the page is shown or changes in-app, or key presses under 50 ms after a field was focused by script. Typing where at least half of the key gaps are under 1 ms (eight or more), with holds of 5 ms or more.
Pointer and scrollingStraight, constant-speed pointer paths (three or more, two thirds of all) delivered in bursts rather than at a mouse's polling rate. Two or more controls scrolled to the middle of the view with no input and pressed within 100 ms. Two or more wheel scrolls at the top-left corner or the exact centre of the view, where the pointer never was.
Page side effectsTwo or more screenshot-style text cursor flickers (cursors hidden on the fields and restored, as Playwright does while taking a screenshot). A debugging-bar-shaped slide of the page area (50–59 px in many small steps, window size unchanged, no focus or tab change) 10 seconds or more after the page opened, then a click within 5 seconds. Two or more fields focused by script (no click or Tab key) and filled with typed text within 50 ms, with no key press.
NetworkTwo or more requests your server verified in the last minute that the page itself never sent (needs request correlation, see Server API). An evidence upload a browser cannot make: a page clock running ahead of real time, or a complete set of browser request labels naming a navigation.

Request absence needs complete, gap-free capture through the request window in every recently known page context. Missing coverage stays unknown. Late matching telemetry retracts an earlier absence, and repeated verification of one correlated request counts once. Older SDK batches without a capture-end timestamp can prove presence, but cannot prove absence.

The reason names the families and the clues in plain words, for example "Behaviour clues of 2 different kinds agree — timing: long still pauses before each click, with nothing moving; page side effects: a screenshot-style text cursor flicker — patterns of software driving the browser". The agent is shown as Not named, and no AI model is ever named from these clues. The verdict stays categorical; the detail explanation can show internal evidence strengths, explicitly not probabilities.

The same ideas in other vendors' words

The same ideas in other vendors' words
Other vendors sayHere
Likelihood or probabilityNot calibrated or claimed. Internal weighted evidence strengths explain the categorical verdict; they are not percentages.
Verified bot, signed agentVerified (signed): a valid Web Bot Auth signature from a reviewed directory
Behavioural detection, biometricsThe live rules above (including the two-family combination), plus the shadow model under Technical
Headless or automation detectionAI agent from WebDriver, a headless browser or framework globals
Challenge, CAPTCHANot used. Hold for review (review) is the step-up
Likely automated, suspiciousUnknown: not enough evidence, never counted as human

A verdict is never authorization

Each action's policy maps human, agent, unknown and stale to allow, review or deny. verify returns the decision from that policy, and your backend applies it after its own checks. Riskier actions deserve stricter branches.

Unknown

Unknown gets its own policy branch. It never falls through to the human branch. A policy that allows unknown is saved only with an explicit acknowledgement (acknowledgeUnknownAllow), is audited and shows a warning in Control › Rules. For a sensitive action, send unknown to review, or deny it.

An action with no saved rule uses the default rule: Human: allow, AI agent: hold for review, Unknown: allow (until you save a rule that holds or denies it), No recent activity: deny. The default allows unknown because nobody has marked that action as sensitive; it is still the unknown branch, never the human one, and verify says the default decided (warnings: ["policy_missing"]). Save a rule for every sensitive action, with unknown set to review or deny. Write tools cannot run at all without a saved rule.

What your customer sees

Telltale answers your backend; it never shows anything to the person. Your app decides what a held or denied person sees, and a real person can be misread (someone using assistive technology, a kiosk, or someone who paused), so always give them a way through. Never tell the person they look like a bot or an AI agent.

Held for review (decision: review). Recommended message:

Note

We need to confirm it's you before we finish this. Please confirm with your passkey or a code from your authenticator app.

Run a step-up check (a passkey, a two-step code, Turnstile or your own approval) and report the result with POST /api/v1/decisions/{decisionId}/step-up, or let the adapters do it with an onHold handler (Step-up for held actions, with Express and Next.js examples). A person who passes goes ahead at once. Without a step-up, the request waits in Control › Approvals › Waiting until one of your team approves it, for up to 15 minutes, and your app asks again.

Denied (decision: deny). Recommended message:

Note

We couldn't complete this right now. If you think this is a mistake, contact our support team and we'll sort it out.

Point the person to a contact route or the same step-up check, and keep the rest of your site working for them: a denial covers one protected action, not the session. The rule editor in Control › Rules shows these messages, with a copy button, whenever a rule holds or denies.

Outdated activity (stale evidence)

Every policy has a maximum evidence age (maxAgeMs, 1 second to 5 minutes). When the latest evidence is older, verify returns stale: true, and the decision is the stricter of the stale branch and the current verdict's branch. Expired evidence can tighten a decision but never loosen it, so an agent that blocks the Telltale server cannot turn deny into allow. A policy with stale set to allow is saved only with acknowledgeStaleAllow and is audited.

Typing evidence uses the occurrence times of the supporting keys, not the time a heartbeat repeats a lifetime count. All three capital anomalies or all eight keys in a qualifying rhythm must still be within the evidence window. The recorder retains at most three timestamps for each capital anomaly and eight for the latest qualifying rhythm; keys, key codes and typed content are not sent. A new qualifying rhythm renews evidence even if it is shorter than a prior lifetime maximum. Older count-only summaries cannot prove recent typing; a fresh summary above a typing threshold with missing or invalid occurrence times caps the verdict at Unknown, with an explicit explanation, rather than claiming AI agent or Human. Valid expired occurrences allow subsequent human evidence to establish Human.

The current verdict also fades once its evidence leaves the 60-second evidence window, so a session nobody has touched for a while drifts back to unknown instead of keeping an old human verdict. A verified operator signature keeps a session agent until the signature expires or 10 minutes after it was last presented, whichever comes first.

The adviser model (analytics only)

Beside the verdict, the session detail shows a second opinion from an adviser model, for example "Adviser model: agent-like (first 30 seconds) · not used for decisions". It is a small machine-learning model trained on public research data, the FP-Agent dataset of people and AI browser agents doing web tasks, used with its authors' permission. It reads only timing shapes Telltale already collects in the first 30 seconds of a page: press holds, key holds and gaps, and scroll bursts. It never sees typed text.

The adviser only advises. It never changes the verdict, the action verdict, a protected action's decision, a policy, what is chargeable, the agent's name or a webhook that acts. You see it in the session detail and in label reports, so you can compare it with the verdict over time.

It says "no opinion" (Unknown) whenever it has too little to go on: fewer than two completed presses, key pairs or scrolls of one kind, a page shorter than its first time window, missing behaviour data, or values outside what it saw in training. On test-set research sessions it called no person an agent and no agent a person, but it gave no opinion on most of them, and research sessions are not your traffic. Its score is not a probability.

We also tested it on agents and tasks it had never seen: the model was retrained seven times, each time without one agent family, and three times without one task (the FP-Agent paper's holdout test). On unseen agents it still called no person an agent, but how many agents it noticed in the first 30 seconds varied widely: almost none for Atlas Agent (its fast scrolls and short presses lie outside anything the model had seen, so it says no opinion), about 1 in 5 for ChatGPT Agent and Manus, and about 8 in 10 for Browser Use and Claude. It also called a few unseen agents a person (4 of 794 ChatGPT Agent and 5 of 795 Claude sessions at 30 seconds). On an unseen task (Shopping) it called up to 5 of 48 people an agent in the first 2 seconds, and none at 10 and 30 seconds. So on agents or sites unlike its training data it can be wrong in both directions, which is why it stays an adviser. Exact counts are in models/fp-agent-early-xgb.meta.json under "holdouts".

Evidence sources and what each one can do

Each kind of evidence is kept separate, and each has a limit on what it can do to a protected action. Until test-set evaluations with real agents and assistive technology are published, only high confidence (a verified identity, an automation trace, injected input, sustained behaviour, a behaviour change, or several behaviour families agreeing without physical-device input) counts toward billing.

Evidence sources and what each one can do
SourceWhere it comes fromEffect on the verdictMost it can do to a protected action
Web Bot Auth signature checked by TelltaleRequest headers your backend forwards in request, checked against the reviewed operator listAI agent, named with strength signed (Verified)Deny, per your AI agent rule
Strong automation tracesThe browser SDK (for example automation-tool traces)AI agentDeny, per your AI agent rule
Injected input, sustained behaviour, behaviour changeThe browser SDK: keys with no hardware delay (Chromium), and enough consistent behaviour evidence on those pagesAI agent, high confidenceDeny, per your AI agent rule; chargeable
Several behaviour families agreeingThe browser SDK: keyboard timing, pointer and clicks, text insertion on one page, no physical-device input on the sessionAI agent, high confidenceDeny, per your AI agent rule; chargeable
Behaviour patterns aloneThe browser SDK (timing and movement patterns)AI agent, medium confidence, shown as "AI agent" in the dashboard and analyticsReview (step-up) by default; Deny only if the site blocks medium confidence; never charged
Page markers and self-declared user agentsThe browser SDK, or a forwarded requestNone on their own; they name an agent only beside an AI agent verdictNothing on their own
Cloudflare (customer's edge)evidence.cloudflare on verify, server key onlyNone: recorded beside the verdictDeny only for a Cloudflare-verified signed agent; review for a bot score below 30 or a verified bot; nothing for the rest
Fingerprint (customer's account)evidence.fingerprint on verify, server key onlyNone: recorded beside the verdictReview for bot bad or good; nothing for tampering, virtual machine and the other signals

For the two edge sources the last column is a ceiling (mayLeadTo in edgeEvidence), and edge evidence only ever tightens a decision: it raises Allow to Hold for review (review), and raises to Deny only when mayLeadTo is deny. It never goes past the action's AI agent rule (it stands in for an AI agent reading, so a site whose AI agent rule allows agents is not overruled by its own edge), never lowers a decision and never changes the verdict, so it never makes Unknown human. When it changed the decision, appliedToDecision is true and raisedFrom names the decision before; a hold it caused offers step-up with reason edge_evidence. Edge evidence alone is never chargeable: what is chargeable follows the verdict, and edge evidence never makes one AI agent. It is stored with the decision for your own rules and for audit. A Cloudflare signed-agent result is Cloudflare's check, not Telltale's, so it never becomes a Verified attribution; forward the Web Bot Auth headers to have Telltale check the signature itself. No source, edge or browser, can make a session human on its own: a high Cloudflare score or Fingerprint's "not detected" is context only. See Edge evidence for the fields and the Cloudflare Worker.

Evidence coverage and historical explanations

Session details expose evidenceCoverage: accepted SDK events, rejected events, duplicate/out-of-order events and events removed from the retained buffer. Counts carry a scope: session-lifetime for newly tracked sessions, since-tracking-start for existing sessions that began tracking later, or retained-only when no counters exist. Missing historical totals are unknown, not zero. Oldest retained observation and known revoked/expired status help explain coverage; a sequence gap or silence alone does not establish packet loss or a broken SDK.

Meaningful detection history retains a bounded explanation and classifier basis independently of raw evidence. These historical explanations never extend current protection decisions or chargeable activity. Legacy numeric score fields remain for compatibility but are deprecated and uncalibrated; scoreSemantics states this explicitly. Use verdict, reasons and freshness rather than interpreting a score as a probability.

Confidence in the dashboard

Every AI agent verdict in the dashboard (Sessions, the session drawer, Approvals, Your agent report and the Ledger) reads AI agent · High confidence or AI agent · Medium confidence; press or hover the confidence for how we know it (signed requests, automation traces, injected input, sustained behaviour, a handover to software input, several behaviour signals agreeing or Claude's cursor driving the clicks for High; behaviour patterns, how it moved, clicked and typed, for Medium). A reading with neither confidence nor agentEvidence, such as one from before confidence was recorded, shows "Confidence unknown". These are levels, not measured probabilities: there are no percentages. Chargeable: High confidence. Never charged: Medium confidence. Sessions can be filtered by confidence (the Confidence menu, or confidence=high|medium|low|unknown on GET /api/admin/sessions, which also returns page.confidenceCounts; the earlier evidence= values still work), and sorting by Verdict orders agent sessions High first. The API values (agentEvidence, confidence) are unchanged.

Detection history and current control

Sessions preserve the last meaningful detection separately from the current verdict. An Unknown observation or a quiet period does not erase an earlier AI agent or Human detection. Older sessions use retained timeline evidence where available; missing history is not invented.

The session details distinguish recent evidence, no recent evidence, and an inconclusive current driver with a previous detection. “No recent evidence” may mean inactivity or missing telemetry; it does not prove that the browser is idle. Human patterns describe observed behavior, not proof of a person. AI agent includes generic automation and does not establish a specific AI model.

A supported Human result can supersede the last AI agent detection; a single ordinary-looking click is insufficient under the existing human-pattern rules. Historical detection is presentation context only: it never extends current protection evidence, grants authorization, or creates chargeable agent minutes.

Changelog

Earlier revisions of the rules, newest first. Each entry says what changed at the time; where an entry and the sections above disagree, the sections above are current.

Current revision: edge people read Unknown, never AI agent (heuristic-v4.33)

Heuristic-v4.33 (2026-11-04) moves two readings that could come from a real person from AI agent at medium confidence to Unknown. Nothing else changed: every other rule, threshold and band is exactly as in heuristic-v4.32 below.

The cost: an AI agent built to look human that runs in a cloud browser and passes every shape check, or one that clicks without pointer travel and waits before each press, is now missed (Unknown) instead of medium. Missing an agent is acceptable; calling a person an AI agent is not. Numbers: accuracy report (opens the public report page).

Earlier revision: remote browser isolation (heuristic-v4.32)

Heuristic-v4.32 (2026-11-03) changed only the band of some injected-input verdicts. Remote browser isolation services (Cloudflare Browser Isolation, Menlo, Zscaler) and the "take over" live view of a cloud browser forward a real person's keys and pointer into a browser running in a data centre. That input reaches the page through the browser's software input path, so it arrives without the hardware delay a real mouse or keyboard has, exactly like an AI agent's injected input.

So injected input was held at medium confidence, never high (since heuristic-v4.33 it reads Unknown), when all of these hold: it is the only sign of software (no automation trace, no verified signature, no AI agent cursor, no agent page marker and no other behaviour signal, apart from the mouse hardware and a paste), the input is otherwise shaped like a person's (pointer travel before every mouse click, humanly possible and varied key timing, at least 10 keys or 3 such clicks), and the connection comes from a published data-centre address range. Under heuristic-v4.32, medium still showed as AI agent and was held for review; since heuristic-v4.33 the session reads Unknown. The reasons say why: "Input arrived without hardware delay, but everything else looks like a person and the connection comes from a cloud provider's address".

Injected input from any other address (a home or office network, a privacy relay, an unknown address, or an AI agent provider's own published range) stays high. The cost under heuristic-v4.32: an AI agent built to look human that runs in a cloud browser read medium instead of high (since heuristic-v4.33, Unknown). The frozen test-set results are unchanged, because no test set records the connection address (see the accuracy report (opens the public report page)).

Earlier revision: a person reaches Human sooner (heuristic-v4.31)

Heuristic-v4.31 (2026-11-03) changes only how quickly a person on a physical mouse and keyboard reads Human. No AI agent rule, threshold or confidence band changed, and the physical-device requirement for Human stays.

Strong device evidence. On a Chromium page (Chrome, Edge, Brave, Opera, Chrome on Android), the evidence is strong when the page's input shows both:

Software input does not show both. Input dispatched through Chrome's debugging protocol arrives with no delay, and a script that forges the delay still sends one pointer sample per move: on our tuning runs it merged 29-31% of moves, while real people merged 81-89%.

With strong device evidence, either of these is enough for Human (the other checks of the human rule still apply: trusted input, mouse clicks reached by real pointer movement, no impossible or metronomic typing, no machine-regular timing):

Without strong device evidence (Safari, Firefox, an older SDK, or a mouse that rarely merges samples, such as on some high-refresh displays) the rule is unchanged: 20 interactions of three kinds, 10 key or click intervals and the device delay.

On the live demo session a person drove by hand (mouse and scroll, no typing), Human now arrives 5.3 s after the first input instead of 22.3 s. In the FP-Agent research recordings, replayed as if every page came from real hardware, people who reach Human go from 436 to 470 of 546 (125 to 135 of the 159 in the test split), those who end the visit as Human from 423 to 457 (120 to 130), and no agent reaches Human even when it is given the same device evidence.

Not added: Human from mouse movement alone. The device delay is measured on presses, keys and wheel steps, not on pointer moves, so movement alone cannot show it, and smoothed or replayed mouse paths are exactly what humanising scripts copy. A movement-only path is built but switched off until we have fresh recordings of real people and a delay measured on pointer moves.

"Looks like a person so far": a display state, not a verdict.

While the verdict is still Unknown, the live demo and the dashboard may show Looks like a person so far as soon as the page's first input shows real hardware: at least 3 delay samples with a typical delay of at least 4 ms, and mouse moves that carry merged samples. On the live demo session that happens about 2 s after the first input.

It is not a verdict. The verdict stays unknown (provisional: 'looks-human' and provisionalSince appear beside it on the session view and the demo's own answer only). Protected actions, your Unknown rule, chargeable use, the usage ledger, webhooks, counts and reports never read it. AI agent evidence replaces it at once, including a handover. The order a visitor sees is: Monitoring, Looks like a person so far, Human activity once the evidence above is met, or AI agent activity at any point.

Earlier revision: VoiceOver when the pointer follows its cursor (heuristic-v4.30.1)

Heuristic-v4.30.1 (2026-11-03) closes one gap for screen-reader users. VoiceOver can move the mouse pointer to each control it reads ("mouse pointer follows VoiceOver cursor"). Its clicks then come after one pointer move and a pause, with pressure 0, which looked like software to two families at once. Now, on a page where nothing was typed (at most two keys, such as a Cmd+V paste) and every mouse press came after at most one pointer move and at least 200 ms with the pointer still, pointer and clicks and the mouse hardware do not count toward "several behaviour signals agree", exactly like VoiceOver's activate clicks. Such a page could still read AI agent at medium confidence; since heuristic-v4.33 it reads Unknown. Quick software clicks (about 100 ms after the move) are not affected, and neither is Claude's cursor driving the clicks. On FP-Agent and the Claude in Chrome bench, no high reading was lost.

Earlier revision: the mouse hardware, and Claude's cursor (heuristic-v4.30)

Heuristic-v4.30 (2026-11-03) keeps everything in heuristic-v4.29 below and reads two new things the script tag reports about the mouse (counts and fixed labels only: no position, pressure value or key leaves the page). Both work only in Chromium-based browsers (Chrome, Edge, Brave, Arc, Opera); Safari and Firefox get neither yet.

The mouse hardware is a fourth family for "several behaviour signals agree" (behaviour-corroborated, how we know: "Strong evidence: several behaviour signals agree", with "mouse hardware" among the families in the reason). It holds on a page when both of these point to software:

Neither alone is enough (a person's mouse on a fast display often sends one sample per move too). The family also needs the page's input timing to be present, so the physical-device exception can always be checked: without timing (an older SDK, the behaviour stream turned off) it never counts. It is a clue, never a rule on its own: it only raises an AI agent verdict that behaviour already made, the physical-device exception applies to it, and VoiceOver's clicks (which also report pressure 0) leave it exactly as they leave pointer and clicks. So pointer and clicks plus the mouse hardware, on a page with no hardware delay anywhere in the session, is high confidence. That is what an agent that only clicks (no typing, no paste) can now reach.

Claude's cursor driving the clicks is proof (agentEvidence: 'cursor-driven', high, how we know: "Claude's cursor is driving the clicks"). While Claude in Chrome's on-screen cursor is displayed, at least two mouse presses landed on it (within 8 px of its tip or centre), at two or more different spots, the cursor moved between presses, and every press on the page came with no pointer travel of its own. A leftover cursor that sits still can't produce this: someone clicking beside it never makes it move. It makes an AI agent verdict on its own, outranks the physical-device exception (Claude drives your visitor's own Chrome, where that person may have typed earlier), and switches a session that read Human, like other proof. The page marker names Claude in Chrome beside it, as before.

Not added: clicks after a long wait. Agents that teleport the pointer and wait 200-1500 ms before pressing look exactly like voice control and switch access, so that shape is not a rule. Such an agent stays Unknown unless its cursor or another signal gives it away. Missing an agent is acceptable; calling a person an AI agent is not.

Measured: FP-Agent and our own recordings of a person carry no mouse-hardware fields, so their numbers don't move; three Claude in Chrome bench kinds driven over Chrome's debugging protocol move from medium to high (quick clicks) and from Unknown to high (slow clicks with the cursor displayed), and stay Unknown with the cursor hidden. No real person has been recorded with the new fields yet.

Earlier revision: a person stays Human while they use the page (heuristic-v4.29)

Heuristic-v4.29 (2026-11-03) changes only how a person keeps a Human reading. Every AI agent rule, threshold and confidence band is exactly as in heuristic-v4.28.1.

Earlier revision: several behaviour signals agreeing (heuristic-v4.28.1)

Heuristic-v4.28.1 (2026-11-03) adds one way to reach high confidence. Detection itself is unchanged: the same sessions read AI agent, Unknown and Human as under heuristic-v4.28; only the band of some behaviour-backed AI agent verdicts moves from medium to high.

Two or more independent behaviour families agreeing on one page are high confidence (agentEvidence: 'behaviour-corroborated', shown as "Strong evidence: several behaviour signals agree"). A family is one kind of measurement; however many of its clues fire, it counts once:

Earlier revision: several behaviour signals agreeing (heuristic-v4.28.1)
FamilyIts clues
Keyboard timingkeys held for machine-short or machine-even times; machine typing (identical holds, no gap between keys); capitals without Shift; the behaviour stream's zero-gap typing
Pointer and clicksjump clicks (every press on the page with no pointer travel), quick jump clicks (page or visit), clicks at the exact centre of controls, paired press-and-release dispatch
Text insertiona paste on the page; fields focused and filled by script

The physical-device exception. If the session shows physical-device input, the reading stays medium: the heuristic-v4.27 device trait (a real hardware delay) on any page of the session or on the page where the families agreed, or the same delay on as few as three samples (all input, or keys alone: a median of at least 2 ms and none under 0.2 ms). Remote desktop, VoiceOver users who type, touch-screen kiosks and barcode scanners go through the operating system's input path and keep that delay. Where device timing is unavailable (an older SDK, the behaviour stream turned off, a replay), two families are enough.

Human still holds against guesses. After a Human reading, several behaviour signals agreeing reads Unknown, not AI agent. Only proof (injected input, an automation trace, a verified signature) or a sustained behaviour change makes it AI agent.

Accepted risk. When the browser can't report hardware timing, several behaviour signals agreeing is treated as high confidence. That can include people using remote desktop, kiosks or scanners. Hardware timing is missing with an older SDK, when the behaviour stream is turned off (it is on by default), or when the session's evidence is out of date; with it, those people stay medium. No FP-Agent participant (546 people) showed two families. Numbers: accuracy report (opens the public report page).

Earlier revision: injected input, sustained behaviour and behaviour change

Heuristic-v4.28 (2026-11-03) adds three ways to reach high confidence, and makes a person's session harder to read as an agent.

Input injected by software is high confidence. Heuristic-v4.27 measured the delay between each press, key and wheel event's own timestamp and the page (below), and asked for a device-like delay before calling anyone Human. Read the other way, for keys: when at least 10 of the 20 most recent key events on a page have a typical (median) delay under 1 ms and at least a tenth of them arrive with no delay at all (under 0.2 ms), they were stamped as the browser received them, not by an operating system's input pipeline, so software injected them. The session reads AI agent with agentEvidence: 'injected-input' and the reason "Input arrived without hardware delay: injected by software", instead of v4.27's Unknown.

Sustained behaviour is high confidence. A behaviour-based AI agent reading becomes sustained-behaviour as soon as enough evidence has accumulated, with no fixed time (elapsed time is reported, never a gate):

A brief odd moment is not a handover; a sustained change is. Once a session has read Human (a person on a physical device), a later reading backed only by behaviour patterns does not make it AI agent: it reads Unknown at most ("Human holds against guesses, not against proof"). Two things do switch it:

When physical-device input returns, new actions read Human again; the timeline keeps that an AI agent was driving earlier, and protected actions keep treating a later Human reading as Unknown, as before.

High confidence is chargeable from the moment it qualifies (earlier minutes are not charged afterwards) and follows the AI agent rule, Deny included. A verified signature still outranks every other level.

Previous revision: Human needs input from a physical device

Heuristic-v4.27 (2026-11-03) makes Human harder to earn. Input that merely passes the human pointer and key checks (curved mouse paths with real travel before each click, varied timing, human-length key holds) is no longer enough on its own: those checks describe what input looks like, and a script can copy that. Human now also needs positive evidence, from the same page, that the input came through a physical device:

Without either, the session stays Unknown, with the reason "Human-like input, but nothing showed it came from a physical device …". It is never called AI agent for this: a missing device trait is missing Human evidence, nothing more. In the live demo that reads "Can't confirm a person".

Why: the test-set adversarial bench in the accuracy report (opens the public report page) drove a stealth headless Chrome (normal user agent, webdriver hidden) with smoothed or replayed human mouse paths, a pause before each off-centre click and log-normal typing. Under heuristic-v4.26, 15 of its 20 test-set runs read Human, so a protected action would have treated them as a person. Under heuristic-v4.27, re-run on the same test-set seeds, all 20 read Unknown and none Human. They are still not caught as AI agent: this closes the door to Human, it does not detect them.

What it did to people, honestly: the user's own confirmed recordings still reach Human at the same moments as before (one person, one machine). In the FP-Agent research replay, which has no device timing at all, no session can reach Human any more: people who read Human there (317 of 546 sessions, 91 of 159 in the test split) now read Unknown, while agents are unchanged (7,025 of 7,182 AI agent, none Human) and no person reads AI agent. That replay figure is tuned on that data and says nothing about real visitors; the real shift for keyboard-only users, other browsers, touch and assistive technology is not measured yet. The rule was not chosen on any FP-Agent row. Full tables: accuracy report (opens the public report page).

What it costs, all toward Unknown, never toward Agent:

Agent detection, agentEvidence, and what an AI agent verdict may do were unchanged by v4.27. Heuristic-v4.28 (above) reads the same delay the other way on Chromium: no delay at all is injected input.

Earlier rule: only verified identity or an automation trace blocks or is chargeable (refined 2026-11-03 by the confidence bands above)

The confidence bands above refine this rule: high confidence (now also injected input, sustained behaviour and behaviour change) follows the AI agent rule and is chargeable; medium confidence is held for review by default and never charged.

Heuristic-v4.26 (2026-11-03) changes what an AI agent verdict may do, not how it is detected. Until test-set evaluations with real agents and with assistive-technology users are published, only two kinds of evidence may deny a protected action or count as chargeable:

An AI agent verdict that rests on behaviour alone (how the pointer, clicks, keys and timing look, with neither of the above) still reads AI agent in the dashboard and agent in the API. But:

Every AI agent verdict carries agentEvidence, which says what backs it: verified, automation-trace, injected-input, sustained-behaviour, behaviour-change (since v4.28), behaviour-corroborated (since v4.28.1), cursor-driven (since v4.30) or behaviour. A medium-confidence verdict also lists the reason "Behaviour patterns (medium confidence): ...". Detection itself is the same as heuristic-v4.25.

This replaces the 2026-11-02 rule of heuristic-v4.24 below, which let behaviour-only verdicts deny and be charged. It also goes further than the "analytics only" revisions before that: every behaviour rule is covered now, not only the four newest. The setting Behaviour signals can call AI agent stays the off switch: turned off, behaviour alone never calls a session an agent at all.

Why: these behaviour rules were tuned on research recordings that contain no assistive-technology users. Someone whose voice control, switch or dwell clicker clicks like software must not be locked out of an action or charged as an agent on that basis.

Previous revision: quick teleporting clicks counted across the visit

Heuristic-v4.25 applies the quick-teleporting-clicks rule (below) to the whole visit as well as to each page. Some agents click only once or twice per page, so no single page ever had three clicks. Now the last 16 clicks of the visit are judged together. It only applies while the visitor is still active: the newest of those clicks must be on a page that is still sending activity. In the FP-Agent research recordings (tuned on this data, so not an accuracy estimate) this raises the total to 7,025 of 7,182 agent sessions, with none of 546 people flagged. Test-set results are in the accuracy report (opens the public report page).

Previous revision: everything we catch counts (replaced by heuristic-v4.26)

Heuristic-v4.24 removed the "analytics only" limit. The behaviour rules below (quick teleporting clicks, teleporting clicks with robotic key holds or a paste, and rapid paired mouse transitions) used to label a session AI agent activity in dashboards only. Now the same verdict is used everywhere: protected actions apply the site's AI agent rule, and the usage counts as chargeable agent usage.

A site that does not want behaviour alone to call a session an agent can turn off Behaviour signals can call AI agent in its settings. Behaviour then only stops a session from being called Human.

The risk this accepts: these rules were tuned on research recordings that contain no assistive-technology users. Someone whose voice control, switch or dwell clicker clicks like software would now be treated as an agent at protected actions, not just labelled in a report.

Previous revision: quick teleporting clicks label an agent on their own (analytics only)

Heuristic-v4.23 adds one more analytics label. A page is labelled AI agent activity when it has at least three mouse presses, the pointer never travelled to any of them, and the typical press came within 200 ms of the pointer appearing at that spot. Software clicks the moment the pointer lands; in the FP-Agent recordings agents pressed a median of 0 to about 106 ms after the pointer arrived. A press that lands somewhere the pointer never was (some tools press at a new spot without moving the pointer at all) counts as instant.

The 200 ms limit is what protects people using assistive pointers. Voice control moves the pointer and clicks only once the command has been recognised, and switch scanning and dwell clicking wait for a timer, so they press hundreds of milliseconds after the pointer stops. Those patterns are modelled in our tests and never get this label. We have not yet checked the limit against real recordings of voice control, grid clicking, switch access or dwell clicking.

In the FP-Agent research recordings (tuned on this data, so not an accuracy estimate), together with the rules below, this labels 6,928 of 7,182 agent sessions and none of 546 people. Like the two-clue rule, it appears in dashboards and reports only and is never used for blocking, protected actions or billing.

Previous revision: two robot clues on one page, counted across the whole page (analytics only)

Heuristic-v4.22 keeps the two-clue rule below and widens it in two ways:

Each clue alone is still not enough. Voice control, switch access and dwell clicking jump the pointer, and many people paste. A paste never stops a session from being called Human. Like the rule below, this label appears in dashboards and reports only; it is never used for blocking, protected actions or billing.

In the FP-Agent research recordings (tuned on this data, so not an accuracy estimate), with both clues required on the same page, this labels 5,901 of 7,182 agent sessions and none of 546 people (14 people pasted, none on a page with jump clicks). The rule was chosen after looking at that data, and the recordings contain no assistive-technology users. An assistive-technology user who jump-clicks and also pastes on the same page would be labelled an agent in analytics, but never blocked or charged.

Previous revision: two robot clues together label an agent (analytics only)

Heuristic-v4.21 labels a session Agent for analytics when one page shows both of these: at least three mouse clicks in the last minute with no real pointer travel before any of them (the pointer jumped straight onto the spot), and machine-short or machine-even key holds (described below). Either clue alone is not enough, because voice control, switch access and eye-gaze dwell clicking also jump the pointer, and on-screen keyboards also hold keys for about 0 ms. This label appears in dashboards and reports; it is never used for blocking, protected actions or chargeable use, which still need certain evidence such as the browser's automation flag or a driver trace.

In the FP-Agent research recordings (tuned on this data, so not an accuracy estimate) this labels 2,670 of 7,182 agent sessions (Browser Use, Skyvern, Manus, Claude and Comet; not ChatGPT Agent or Atlas, whose key holds look human) and none of 546 people. The rule was chosen after looking at that data, and the recordings contain no assistive-technology users. Everything in heuristic-v4.20 is unchanged.

Previous revision: Human needs human key holds

Heuristic-v4.20 adds a second safety check before Human. When a page has at least eight key presses, we look at how long each key was held down (timings only, never which key). If the typical hold is under 25 ms, or every hold is almost exactly the same length (spread under 5% of the average), the session is not called Human and stays Unknown. It never calls anyone Agent: on-screen keyboards and auto-type tools also hold keys for about 0 ms.

Why: in the FP-Agent research recordings (tuned on this data, so not an accuracy estimate), none of the 445 people who typed at least eight keys on a page met either condition, while every Browser Use, Skyvern, Claude and Comet session that typed did, and most Manus sessions. ChatGPT Agent holds keys for a human-like length, so this check does not affect it; the mouse-travel check below still does. Thresholds were chosen after looking at that data. Everything in heuristic-v4.19 is unchanged.

Previous revision: automation tool traces count as proof

Heuristic-v4.19 treats traces that only an automation driver leaves in the page as strong evidence, like the browser's own automation flag: ChromeDriver's cdc_ names, Playwright's bindings and init scripts, Selenium's and older WebDriver hooks, PhantomJS and Nightmare. One of them is enough for AI agent, even when the automation flag has been switched off. Puppeteer's binding names and nodriver's click flash stay diagnostic, because a page or an extension can plausibly produce them. A trace names the framework only when the automation flag is also present, and it never names an AI model or vendor. Everything in heuristic-v4.18 below is unchanged.

Previous revision: Human needs real mouse travel

Heuristic-v4.18 makes Human harder to reach. When a stretch of activity includes mouse clicks, at least half of them (and at least one) must follow real pointer travel: three or more distinct mouse positions in the 1.5 seconds before the press, not a single jump onto the spot. If they don't, the session stays Unknown; this rule never calls anyone Agent. Keyboard, touch and click-free activity are unaffected.

Why: we replayed the public FP-Agent research dataset (seven commercial browser agents and 56 student participants on three tasks) through the detector. About 70,000 agent clicks; none followed real pointer travel, while 491 of 494 people who clicked did. Under heuristic-v4.17, 637 of 7,182 agent sessions were called Human at some point; under v4.18, none were, and people recognised as Human fell from 439 to 435 of 531. That replay lacks automation flags, element positions and some page measurements, it covers one website and desktop participants, and the rule was chosen after looking at that data, so treat these numbers as a check, not an accuracy figure. People who move the pointer with voice control, switch access or other assistive software may stay Unknown; Unknown is never treated as Human or Agent.

Previous revision: more sensitive analytics

Heuristic-v4.17 (kept unchanged in v4.18) retains the held-click pattern for analytics detection. Two trusted mouse presses can establish Agent when both jump directly onto different known controls, the controls are over 100 pixels apart, the next press starts within 200 ms of the previous release, and all four measured press/release delivery delays are positive. At least three must be below 1 ms; a single small scheduling outlier may be below 2 ms. Two delays at or above 1 ms, a delay at or above 2 ms, and missing or ambiguous zero timing do not qualify. The presses need not be unusually short. Complete telemetry, matching releases, stationary holds, a current visible segment and the existing keyboard, touch, pen and cancellation exclusions still apply.

The analytics rule can also use one matching dense pointer sample when the second move falls inside the normal stream’s 15 ms sampling interval. It requires the preceding sparse singleton and all the same pairing, completeness and transition checks. This reuses existing telemetry; it does not infer missing motion or add another evidence vote. Historical v4.14 and v4.15 remain replayable with their original limits.

The single-outlier allowance addresses recorded timing-sensitive misses. It is a bounded development heuristic, not a measured human/agent separation threshold. All four delays are retained in the evidence summary so the allowance can be audited; the strict protection and billing rule still requires every delay below 1 ms.

The same single-outlier allowance also applies to the existing short-press pattern for analytics: both matched holds must be positive and below 20 ms, with the original complete placement evidence and presses no more than ten seconds apart. Distinct known controls may occupy the same screen position after scrolling; otherwise an observed displacement over 20 pixels is required. This separate short pattern does not relax the held pattern’s rapid-transition requirements. Historical v4.16 remains replayable.

This is one combined behavioral signal. Its timing, placement and displacement do not earn separate votes; overlapping behavioral rules use the strongest family weight. A conflicting supported human pattern still produces Unknown unless independent strong automation evidence resolves it. No timeout forces a label.

The new pattern can resemble human-operated assistive software. When it is the only qualifying automation evidence, Agent is an analytics-only observation: it must not by itself trigger agent-based blocking or chargeable agent usage. Protected actions use the stricter action verdict and the customer's policy, including that policy's Unknown branch. This is not automatic permission to proceed. Existing stronger automation evidence remains eligible under the existing rules. The rich /api/v1/verify response exposes verdict, actionVerdict and analyticsOnly; its decision uses actionVerdict. The narrow compatibility /v1/verify response returns the strict action verdict. Updated server adapters validate the distinction; older adapters may reject differing branches and should be updated.

The result remains categorical, not a probability or proof of an AI vendor. Genuine human recordings and synthetic boundary tests are checked separately; neither a few passing recordings nor a constructed collision establishes a population false-positive rate.

Earlier rules retained from heuristic-v4.7. Rounded-centre pointer evidence requires repeated jumps between locations more than 20 CSS pixels apart, each landing within 1 CSS pixel of a control centre, with one non-coalesced move within 100 ms of the press. The timing clue is a matched mouse release under 20 ms. Agent requires either three jumps plus three short releases making up at least 75% of matched holds, or three jumps whose own matched releases are short. The latter binds both clues to the same interactions, so unrelated slower clicks do not erase positive evidence. A first press alone cannot establish a jump. These clues cannot borrow an unrelated signal to establish Agent. Keys, keyboard activations, untrusted buttons, touch, pen or composition exclude this pointer rule. Behavioural page combinations require a complete stream window: dropped samples or missing batch sequence numbers cannot establish an absence of human input. Gaps are counted only between retained batches of the same stream epoch, not before the start of the retained window. Independent direct automation evidence remains usable.

Corroborated element-labelling control. A separate pair recognises at least four single pointer jumps across at least three distinct landing positions, more than 20 CSS pixels apart, within 1 CSS pixel of interactive control centres. Each press must follow its one non-coalesced move within 250 ms and be within two seconds of a bulk element-labelling observation (the same nonstandard attribute changed on at least 25 elements in one observer batch). Common class, style, ARIA, form-state, Telltale and known password-manager/Grammarly attributes are excluded by collection. Ordinary travelled mouse paths, bulk DOM changes alone, pointer jumps alone, and stale inspection changes do not qualify. The same key, touch, pen, composition, untrusted-input and stream-loss exclusions apply. This independently combines pointer movement with page side effects; it does not rely on a named-agent marker or require very short holds.

The 250 ms arrival-to-press and two-second corroboration bounds are development-calibrated limits, not validated human/agent separation thresholds. They accommodate scheduling delays while keeping the observed page-labelling work close to the input. A person using assistive software that both bulk-labels elements and warps/clicks controls with this pattern can still be classified as automation. Real accessibility trials remain required; use review rather than automatic denial where that ambiguity matters. This does not identify an AI vendor or establish a calibrated probability. Versions 4.5 and 4.6 remain available for historical comparison.

Mouse-only navigation can now establish Human from repeated measured approaches, off-centre targeting, varied holds and varied click cadence, with no automation cap. It still needs at least 20 input events and ten click intervals; at least eight clicks and 75% of eligible clicks must have three or more approach moves, no jump, an offset over 2 pixels and a hold of at least 20 ms. Hold variation must reach 0.15 and within-kind cadence variation exceed 0.35 (coefficient of variation). Mixed input also needs variation within an input kind; two constant rates cannot manufacture human variation by pooling. Keyboard-only recognition remains limited; absence of a mouse is never Agent evidence.

These are heuristic thresholds, not an accuracy guarantee. Assistive software that synthesizes the same centred jumps and short mouse clicks without keyboard events can still look identical. Synthetic negative cases are regression checks, not real-human validation. Detection requires enough activity within the 60-second window; it is not forced by a timeout, and historical labels do not add agent minutes.

Fixes from the detector audit (heuristic-v4.28)