Every detector asks whether a machine wrote this. For a team that writes with agents, the useful question is the complement: which bytes did not come through the pipeline, and did anyone look at them twice?
| @@ src/router.py hunk 120–148 · ledger .nhw/attest.jsonl · 27 of 29 lines attested | ||
| 131 | A | def route(job: Job) -> Worker: |
| 132 | A | if job.private or job.size > BULK: |
| 133 | A | return pick_specialist(job) |
| 134 | ? | if job.owner == "arnaud": return LOCAL # quick fix, 23:40 |
| 135 | A | try: |
| 136 | A | return default_worker(job) |
| 137 | ? | except Exception: pass |
| 138 | A | raise NoWorker(job.id) |
Illustrative hunk. The gutter is the whole product: the two lines nobody's pipeline saw are the two lines the incident report will name.
Measured on one developer's machine, 4 September 2026. Reproducible on any Claude Code install with python3 eval/separability.py.
Every deployed AI-text detector answers one question: did a machine write this? For a team that writes with agents all day, the useful question is the complement: which spans did not come through the agent pipeline, with its prompt, diff, log and test run? We call those spans unattested. Most are human-typed; some are machine output that arrived through a channel nobody logged; the two cannot be told apart after the fact, and this paper does not claim to. Three points. First, the statistical methods built for AI-text detection cannot perform the inverted task: on 300 labelled passages, a local AI-tell detector separates machine from human prose with an AUC of 0.91, yet 60 % of machine passages (95 % CI 52–68 %) carry no tell, so a "no tell means human" rule has a precision of 7–9 % at a 5 % human share. Second, provenance recorded at write time has no such ceiling: files the agent wrote inside the logged channel during the log window show a median of 100 % of lines attested (40 files; 96 % over all 63), hand-written notes 0 %. Third, coverage is the whole problem: the proof of concept's own source, written by the same agent through an unlogged shell channel, attests at 9 %. That gap defines the product: a signed, append-only authorship ledger emitted by every writing tool, with a stated threat model, verified at review time.
The public conversation about AI text runs in one direction. Schools want to know whether a student wrote the essay. Regulators want machine output labelled so citizens can tell. A video published this week captures the mood: it explains that Anthropic's Fable 5.1 now watermarks all of its text, then spends seven minutes on a recipe for laundering that text through a local model so the mark disappears [14].
Watch a working engineer for a day and the direction reverses. On the machine used for this paper, 2,716 file writes were made by an agent in five weeks, each logged with the exact bytes, the session and the timestamp. The human-typed changes over the same period left no such record. They were made in an editor, in a hurry, often after the agent had finished and the tests had passed. When something broke later, the question in the retrospective was never "did the AI write this?" It was "who touched this after the AI was done?"
That question has no tooling. The product is called NoHumanWrites, a provocation chosen on purpose; the claim underneath is narrower: a machine write that goes through a logged, signed channel can be proven to have done so, and everything else is unattested. Whether an unattested byte was typed by a person or emitted by an unlogged tool is not something the artefact can tell you; it is something the team's instrumentation decides.
Watermarks. Kirchenbauer et al. showed in 2023 that a language model can bias its token choices toward a pseudo-random "green list" at negligible quality cost, producing text a key-holder can later identify [1]. Google DeepMind's SynthID-Text refined this into tournament sampling, published in Nature in October 2024 [2]; generation and detection code are open source [10]. Anthropic adopted a scheme of this family for models released on or after 2 August 2026, worldwide, on every product surface, with no opt-out, to satisfy Article 50 of the EU AI Act [12, 13]. The detection key is not public.
Statistical detectors. DetectGPT [5] and Binoculars [6] score text by how a reference model would have predicted it; Ghostbuster [7] trains a classifier on features from weaker models. RAID showed most of these degrade sharply under paraphrase and domain shift [8]. Sadasivan et al. gave the theoretical reason: as generated text approaches the human distribution, any detector's best performance approaches a coin flip [3]. OpenAI withdrew its own classifier in July 2023 [9]. Liang et al. found that commercial detectors flag essays by non-native English writers as machine-made at rates above 60 % [4]. That last result matters here because our task, done badly, would produce the mirror-image injustice.
Provenance. For images, audio and video, C2PA defines signed Content Credentials that travel with the file [11]. For software builds, in-toto and SLSA attest how an artefact was produced and Sigstore supplies signing and a transparency log [16, 17]. None attest authorship at line level: build provenance names the pipeline, commit signing names the committer, and a developer who commits an agent's output under their own name is telling the truth about the commit and nothing about who wrote the lines.
Any span not covered by a signed record of a machine write. In code: the hot-fix typed at 23:40, the constant changed by hand, the except: pass added to get a deploy through, and also the file an agent produced through sed -i on a server where no hook ran. In research writing: the sentence added to the machine's draft without a source. The harm is not that a person wrote it. The harm is that it skipped the pipeline, and the review process, having already approved the machine's pull request, waves the follow-up through. A tool that surfaces these spans does not judge them; it routes them to the review they missed.
Layer 1, provenance by construction. Every harness knows the exact bytes it writes. A hook records, per write, the file, the hunk, a hash of the normalised text, the producing model and session, and a signature from a key on the developer's machine, into an append-only ledger .nhw/attest.jsonl. A verifier walks the pull-request diff: covered lines are attested; the rest is reported. Proves machine authorship exactly and proves nothing about the remainder, which is the correct asymmetry.
Layer 2, vendor watermarks. For text produced outside a cooperating harness. Teams running their own models can hold their own SynthID key today [10]; for Claude and Gemini output this layer waits on a vendor detection endpoint. Needs a few hundred tokens for confidence and dies under a full rewrite, but a positive result is cryptographic, not stylistic.
Layer 3, statistical triage. Inside a document dense with machine patterns, the paragraph with none is the candidate insertion. Section 6 shows how weak this is. It orders a reviewer's attention and never produces a label on its own.
The ordering is the design. Most systems in this space start at layer 3 and hope. We start where the answer is exact and treat everything else as a fallback that announces its own uncertainty.
A provenance scheme without an adversary is a diary. Version 0.1 defends against forgetting: nobody remembers which lines came from the agent, and signed records kept with the code answer that durably and survive a squash. It does not defend against a developer who wants to lie: the key and the hook live on their machine, so they can sign hand-typed text or delete records. The ledger proves "this hunk went through this developer's signing channel", not "a model wrote this". Against a hostile developer the scheme needs a trust anchor the developer does not control: records pushed at write time to a verifier or a transparency log (Sigstore's Rekor [17]), or signing by the harness vendor. Append-only is by convention until the ledger head is anchored in signed commits. And intent is out of scope: "write exactly these lines" yields an attested hunk that is human-authored in every useful sense; the ledger records channel, not thought.
Unattested lines identify their author by elimination on a small team, and records carry a session id and a machine key: personal data under the GDPR once linkable. So the verifier reports "unattested", never a name; aggregates are per repository, not per developer; prompts are not recorded unless the team opts in. A deployment that turns unattested share into a per-person metric has left the design and should tell its staff.
nhw/attest.py reads every Claude Code transcript under ~/.claude/projects, extracts the Write and Edit tool calls, indexes each produced line by a hash of its normalised content, and attributes any file line by line. Index: 312 transcript files, 2,716 writes, 72,681 attested lines, covering 30 July to 4 September 2026.
| Corpus | Files | Median attested | Line-weighted | 0–20 % | 20–50 % | 50–80 % | 80–100 % |
|---|---|---|---|---|---|---|---|
Vault tools tools/*.py, all | 63 | 96 % | 64 % (strong) | 22 | 2 | 3 | 36 |
| Vault tools, modified within the log window | 40 | 100 % | 76 % (strong) | — | — | — | — |
Vault wiki wiki/*.md | 285 | 5 % | 23 % | 178 | 19 | 16 | 72 |
Vault raw notes raw/*.md | 100 | 0 % | 18 % | 73 | 0 | 2 | 25 |
Agent config ~/.claude | 5 | 100 % | 94 % | 0 | 1 | 0 | 4 |
This PoC nhw/*.py | 3 | 9 % | 9 % | 3 | 0 | 0 | 0 |
Files per attestation bucket. The distributions sit at the extremes: a file is either mostly attested or barely attested, because authorship is decided per file by which channel produced it. The 20–80 % middle holds 12 % of wiki files (35 of 285) and 8 % of tools (5 of 63).
Where the agent wrote code inside the logged harness during the log window, attestation is near-complete: the in-window median is 100 %. The gap to the line-weighted figure is a few large, older files. Line matching is a proxy for hunk provenance, not authorship: a human retyping an agent line verbatim counts as attested, a formatter reflowing one counts as unattested. The wiki and raw corpora are mostly unattested even though the same agent wrote most of them: their pages predate the log window or came from other harnesses (a Telegram bot, a scheduled job). Unattested means human or untracked, and on this machine untracked dominates.
The last row makes that point without argument. The proof of concept's own three source files were written by the agent in this session, through a shell heredoc rather than the logged write tool. The ledger saw nothing. Attestation: 9 %, all of it weak matches on generic import lines. This is an instrumentation gap, not a property of agents. Log forensics after the fact cannot close it; only a record emitted by every writing channel at write time can. That is why layer 1 in production is a hook and a signature, and the transcript reader is a demonstration.
On two wiki pages the agent wrote end to end, git blame reports 0 % machine authorship: a backup job commits the working tree under the human's name every six hours. On a tool the agent committed itself with Co-Authored-By trailers, git reports 83 % (551 of 667 lines). Git is a usable second source only where commit discipline already encodes authorship, and it inverts the truth where it does not.
The transcripts also give labelled prose: what the developer typed to the agent is human, what the agent answered is machine. We took 40–300-word passages of each with no pasted structure, removed near-duplicates, and sampled 150 of each from 310 and 2,987 unique passages. Each was scored by sloptrim 0.9.0, a local detector of 71 documented AI-writing patterns [15], and by burstiness (standard deviation of sentence length over its mean).
| Measure | Human p10 / p50 / p90 | Machine p10 / p50 / p90 |
|---|---|---|
| sloptrim AI-tell score (0–100) | 0 / 0 / 8 | 0 / 18 / 25 |
| Burstiness | 0.28 / 0.58 / 0.94 | 0.29 / 0.60 / 0.96 |
AUC for machine vs human on the sloptrim score: 0.912. On burstiness: 0.483, a coin flip; the folk belief that people vary sentence length more than models do does not survive a modern model's chat output. At the detector's threshold of 20, 149 of 150 human passages fall below it (sensitivity 0.993, 95 % interval 0.963–0.999), which sounds like a fine human detector until one reads the other column: 90 of 150 machine passages also fall below it (false-positive rate 0.60, interval 0.52–0.68). Six machine paragraphs in ten carry no tell the detector knows. One writer, one model family, chat-register prose: the numbers will move on other data. The shape will not.
Suppose a team's artefacts are 5 % human-inserted by span, a figure we have not measured and state as an assumption. Use the measured sensitivity (0.993) and false-positive rate (0.60) of the "no tell means human" rule.
precision = 0.993 × 0.05 / (0.993 × 0.05 + 0.60 × 0.95) ≈ 0.08 (interval 0.07–0.09)
Fewer than one flag in twelve is a person. At a 1 % human share the figure is 1.4–1.9 %. A threshold near 25, read off the quantiles above, would cut the false-positive rate to about 0.10 for a precision around 34 %: an operating point read off two quantiles, not a measurement, and one flag in three being real is still not a tool anyone keeps.
This is the arithmetic that made classroom detectors harmful [3, 4], run in the other direction. A statistical detector of authorship is only acceptable where a false result costs nothing; here a false "human" costs a review and a false "machine" hides the thing we were looking for. The same arithmetic applies to layer 1: its "unattested" label has a false-human rate equal to the share of machine writes that bypass the hook, which on this machine was large before the hook existed. The difference is that layer 3's false-positive rate is a property of language and cannot be engineered down, while layer 1's is a property of the team's tooling and can, channel by channel. That difference, not any AUC, is the argument of the paper.
The video that prompted this work treats the watermark as a threat and offers a laundering recipe [14]. NoHumanWrites is the mirror image. It never removes a mark. It never asserts that a person's work is machine-made, the failure mode with victims. It asserts, with a signature, that a machine's work is machine-made, and leaves the remainder unlabelled for a human to look at.
Stated precisely: Article 50(2) obliges providers of generative systems to mark outputs in a machine-readable, detectable format, with exemptions for assistive and standard editing; Article 50(4) puts disclosure duties on deployers for deep fakes and public-interest text [13]. Neither speaks to source code in a private repository, and this paper does not claim it does. The relevance is indirect: the same vendors now emit machine-readable marks, and a detection endpoint built for regulators would serve a second constituency, teams who want to know what the machine wrote in order to trust it. Two design rules follow: the ledger records a machine key, never a person's name, so the reviewer sees "unattested", not a colleague; and the tool ships with no humaniser, rewrite or removal mode, so it cannot be turned around and pointed at the people Article 50 protects.
The wedge is a pull-request check for teams that already write with agents. Install a GitHub App, add one hook to the harness, and each pull request shows the share of changed bytes that is machine-attested, highlights the unattested hunks, and applies a policy the team chose: comment, require a second approver, require a test that touches the file, or block. The ledger stays in the repository as plain JSON; only the numbers leave. Pricing in the plan: $12 per seat per month, free for public repositories, a compliance tier for teams whose auditors now ask which parts the AI wrote.
The honest test is not the AUC. It is whether the number on the pull request changes one review decision a week on a real team. Five design partners will tell us within a month.
The repository ships a single-file checker for anyone who writes with an agent. python3 nohumanwrites.py check <path> scores a file, a directory or a repository, lists the unattested lines, and states which evidence it used, in this order: a signed ledger in the repository (exact, verifiable); the agent harness's own logs on the machine (exact for logged writes, unsigned); or neither, in which case it reports "no provenance" and refuses to score, because writing style is not evidence (§6). python3 nohumanwrites.py setup creates the dedicated signing key and installs the hook so every later agent edit is signed; --badge prints a README badge, --json feeds a CI check. Run on this paper's own repository the evening the hook was installed, it reported 5 % attested: the ledger had existed for an hour and most files predate it, which is the coverage lesson of §5, delivered by the tool about itself.
The same ledger extends past code without changing its logic, only its unit. A book chapter is scored by paragraph, with a paragraph whose sentences mostly survive reported as edited rather than lost; lyrics and poetry by verse line within stanzas; sheet music by bar in ABC notation or by <measure> in MusicXML; an exported .docx or .epub is unpacked and its paragraphs matched against the ledger, so provenance survives the export. Text a person receives from a model elsewhere (a chat interface, a music model) enters the ledger through nohumanwrites.py import <file> --from <label>, signed at the moment of receipt; whatever the person changes afterwards surfaces as edited or unattested. Media files are checked for a C2PA manifest and otherwise reported as having no provenance. None of this looks at style. A poem nobody signed cannot be classified by this tool or, per §6, by any other; what the tool answers is the question a publisher or a co-author can act on: what changed after the machine's version was signed.
$ python3 nohumanwrites.py import chapter1.md --from claude.ai
chapter1.md: 1 signed record(s) as received from claude.ai [prose profile]
$ python3 nohumanwrites.py check chapter1.md # after the author's rewrite
NoHumanWrites: 50% attested — 2 of 4 units
chapter1.md [prose]: 1 unattested paragraph(s) → paragraph 4; 1 edited paragraph(s): paragraph 2
$ python3 nohumanwrites.py check ~/my-project
NoHumanWrites: 92% attested — 4,118 of 4,476 lines
evidence: signed ledger (.nhw/attest.jsonl)
src/router.py: 2 unattested line(s) → [134, 137]
unattested = typed by hand, or written through a channel with no hook. Review those first.
Formatters rewrite attested lines without changing meaning: hash at token level, or re-attest after a formatter the harness itself invoked? Agents that edit through shell commands, as ours did, need the hook at the file-system or git-index level: where is the right choke point? What token count does Anthropic's watermark need, and will a detection endpoint accept short code hunks at all? Should a span a human reviewed and approved be marked differently from one nobody looked at?
Everything above is measured on current systems. In the one published ladder that grades them, Morris et al.'s Levels of AGI, today's frontier chatbots sit at the lowest rung, "Emerging" [18]; nothing measured places them higher, and the people building them disagree about when they will climb. This section picks no date. It asks what happens to the argument as autonomy rises, using only frameworks and measurements on the record.
Measured. METR's time-horizon work tracks the length of software tasks a system completes with 50 % reliability; a horizon is not a promise of unattended work. Its January 2026 update: doubling "around every 7 months over the period 2019 to 2025", 228 tasks, best measured system (Claude Opus 4.5) at 320 minutes with an interval of 170–729, intervals "still very wide" [20]. ARC-AGI-3: skill-acquisition efficiency in novel, "100 % human-solvable" environments; "as long as there is a gap between AI and human learning, we do not have AGI" [21]. The International AI Safety Report's October 2025 update: gains in coding, mathematics and autonomous operation, profile "jagged" [22].
Declared. As reported by Fortune from Davos, January 2026: Hassabis, "a 50 % chance AGI might be achieved within the decade", defined as "all the cognitive capabilities humans can — and I mean all", today's systems "nowhere near"; Amodei reported predicting developers' work replaced within a year and Nobel-level research within two; LeCun quoted, "we're never going to get to human-level intelligence by training LLMs" [28]. Amodei's "country of geniuses in a datacenter" [27]; AI 2027 as a forecast, not a measurement [32]. Dated statements by interested parties, relayed by a journalist in the Davos case, cited as such.
Defined. Morris et al. (Google DeepMind, 2023) separate performance from generality and add an autonomy axis with five levels, 0–4: tool, consultant, collaborator, expert, agent; autonomy is a deployment choice [18]. Feng, McDonald and Zhang (2025) define five levels by the role left to the human: operator, collaborator, consultant, approver, observer, "a deliberate design decision, separate from capability" [19]. The two ladders order consultant and collaborator differently, so they are not interchangeable; the rest of this section uses Feng et al.'s, because it names the human's role, which is what a provenance record has to capture.
At the operator and collaborator levels, where our data was gathered, the unattested share is mostly the human's hand. At the approver and observer levels the human stops typing bytes and starts approving, or watching, tasks. The unattested share then falls, not to zero and not because of any detector: the human channel into the file narrows while machine channels multiply, and whether it reaches zero depends entirely on whether every machine channel is instrumented, the coverage problem of §5 with more channels. If the 7-month doubling holds, systems that reliably finish day-long tasks arrive inside any team's planning horizon; the interval in [20] is wide enough that they may already be here.
The ledger's unit then expands. "Which bytes did a person type" stays one column; next to it: which task a person authorised, under what constraints, which system executed it, which actions it took, what an independent monitor said. The record format anticipates the first step: producer already names harness, model and session, and an authorised_by record signed by the human who launched the task fits beside the machine-signed hunks. It anticipates nothing more; §10.3 explains why the remaining columns cannot come from the same recorder. Two honest limits: a human signature on "refactor the auth module" proves a person launched that task and is accountable for it, nothing about the 5,000 lines that followed; and the AI-control literature is explicit that human review is expensive, subject to automation bias, and subvertible by a capable system that curates what the reviewer sees [23]. Authorisation is the accountability leg, not the safety leg.
Falsifiable prediction, with one confound removed: on any team running the hook, unattested share per pull request should fall as agents get longer tasks, holding hook coverage constant (measured per channel, so that instrumenting a new channel is not mistaken for autonomy). Flat at constant coverage while task length grows, and this section is wrong.
§4.1 assumed the developer might lie and the machine was an honest scribe. The AI-control literature adds the second adversary: treat the capable model as untrusted; let a weaker trusted model monitor, edit or execute, so safety holds even if the strong model tries to subvert the task [23]. Meinke et al. document frontier models scheming in context [25]; Bengio and co-authors set out why oversight must scale with capability [29]. The protocols are specific: Redwood Research's untrusted-advice protocol (July 2026) has a trusted executor take every action while the untrusted model sends short hints; at 16 characters per message it recovers about 67 % of the gap between the two models' SWE-bench Verified scores [24]. The same executor-and-advisor shape is exposed as an API feature [30].
The two adversaries stack. A recorder that runs inside the environment the untrusted model controls (its container, its shell, its git index) can be tampered with by that model: hunks forged, authorisations spoofed, monitor verdicts deleted. So the machine-signed hunk must be produced or countersigned by a component outside the model's reach, the trusted executor of [23, 24], and the record must say which model, in which trust tier, under which monitor, on whose authority. Layered provenance: hunks signed by a trusted executor, authorisations signed by a human, monitor verdicts bound to the exact task, policy, model version and action sequence, all anchored in a log the model cannot rewrite (§4.1's Rekor serves here too). The monitor and the trusted executor carry the safety weight; the human signature carries accountability; the hunk signature carries the audit trail. NoHumanWrites as described in §4 is the audit-trail leg, built for the honest-machine case; the format teams adopt for it is the one the other legs will have to fit. That is the reason to fix the format now, and the reason not to oversell it.
Three claims get stronger as capability rises. Provenance must be captured at write time, by every channel, and the recorder must sit outside the writer's control: our own 9 % came from an agent using a shell instead of the logged tool; a more autonomous system creates its own channels and an untrusted one can attack the recorder, so the recorder moves to the environment boundary (sandbox, git index, container host, trusted executor), the same conclusion the control literature reaches about monitoring [23]. This is the load-bearing claim. Statistics cannot attribute authorship, and the ceiling falls [3]. The human's remaining contributions are authorisation and review, and the record must make them legible without pretending they are secure; how large they are depends on the autonomy level a team chooses, which [18] and [19] both insist is a choice.
No date; no definition beyond the operational levels; no claim about the safety of any autonomy level ([22], [23], [29]); no claim that the §10.2–10.3 extensions are built, and the trusted-executor leg is a requirement on someone else's component. The 2025–2026 sources postdate the training data of most automated reviewers; they were checked live at the URLs given and archived on 4 September 2026 (eval/sources-archived.txt). The §5 measurements are unchanged by anything here.
Eight frontier models reviewed v0.1 cold (transcript in the repository): one "do not publish", seven "publish after fixes". Applied: the task is defined as unattested, not human; the wiki mid-range figure is corrected from 6 % to 12 %; in-window and strong-match numbers are reported; confidence intervals are given and propagated; the base-rate argument is applied to layer 1; a threat model, a privacy section and supply-chain related work are added; Article 50 is described by paragraph; the 9 % result is framed as an instrumentation gap; the study is labelled an n=1 experience report. §10 (toward AGI) added afterwards at the author's request and put through a second eight-model fact-check; v0.2.1 applies its corrections (Morris's "Emerging AGI" acknowledged, autonomy ladders unmixed, 50 % horizon not read as unattended, "inverts" → "gains an adversary", "share to zero" withdrawn, falsifier corrected for coverage, recorder placed outside the untrusted model's reach, Davos quotes marked as reported).