anthropies README

The project's README from github.com/CharlesHoskinson/anthropies. As one markdown file: README.md.

Don't Catch Anthropies

anthropies

Restore clean title in Outputs the user already owns.

Apache 2.0 1.0.0 DarioCyclovir purge-anthropies

Apache-2.0. Usable from any LLM coding agent. Not affiliated with Anthropic PBC.

Current release: 1.0.0 DarioCyclovir.


Honesty

This tool certifies Layer A (Unicode, trailers, banners) and hard-bound C2PA/metadata on files you own. It does not remove Anthropic's keyed text mark.

Channel What you get
official unavailable unless ANTHROPIC_DETECT_URL is set. No default URL. No score.
c2pa present / absent / removed / not-applicable. Soft-binding and pixel marks are out of scope.
deterministic Per-kind counts only. Certificate for the bytes we strip.
statistical Best-effort 5-gram overlap. Not an official-detector certificate.

clean does not remove the keyed text mark. humanize is best-effort. capture fetches a Claude Output you own; it does not watermark. demo prints four channels and never claims official text-kill.


Release 1.0.0 DarioCyclovir

This is the first production release. Package, CLI, and plugin version is 1.0.0.

HTTP GET /health and GET /capabilities keep JSON version "0.3.0". That field is the locked HTTP API version, not the package version. Kernel API is 1.0.0. Sidecar protocol is 1.0.0. The default Compose image tag remains anthropies:0.3.0 to match that HTTP contract.

Pack implementationVersion values stay 0.4.0 unless a later pack ships its own bump.

Surface Value
Package / CLI / plugin 1.0.0
GET /health version 0.3.0
GET /capabilities version 0.3.0
kernelApiVersion 1.0.0
Sidecar protocol 1.0.0
Default Compose image anthropies:0.3.0

What this release includes:

What this release does not do:


How to run

git clone https://github.com/CharlesHoskinson/anthropies.git
cd anthropies
pnpm install
pnpm build
pnpm install -g .

Or one-shot: npx anthropies --help. From this repo after pnpm build: node dist/cli.js --help. Version is 1.0.0.

npx anthropies inspect COMMIT_EDITMSG
npx anthropies clean notes.md --in-place
npx anthropies humanize essay.md
npx anthropies init-rewrite
npx anthropies capture --model <allowlisted-id> --prompt "..."
npx anthropies demo
npx anthropies serve

serve binds loopback 127.0.0.1:8765 by default. Remote bind requires an explicit --host. The skill prefers ANTHROPIES_SERVICE_URL (same default) and health-checks first. Official stays unavailable unless ANTHROPIC_DETECT_URL is set.

Method Path Role
GET /health { "ok": true, "version": "0.3.0" }
GET /capabilities Pack inventory, tools, scorers. JSON version is 0.3.0.
POST /inspect Inspect an owned file
POST /clean Strip Layer A and hard-bound metadata
GET, POST /detect Run detector packs. Not a clean certificate
GET /openapi.json OpenAPI 3.0.3

There is no HTTP /humanize. Detection is not a clean certificate. Official stays unavailable unless ANTHROPIC_DETECT_URL is set.

Docker (Dockerfile + compose.yaml) is the same service. docker compose up --build publishes 127.0.0.1:8765:8765. The process inside binds 0.0.0.0:8765. The host mapping stays loopback. The image does not install qpdf, exiftool, or c2patool. GitHub Actions runs pnpm test and pnpm build on Ubuntu and Windows.

Shipped packs

GET /capabilities lists these ids. Optional packs fail soft when their sidecar or weights are absent.

Pack id Channel Role
anthropies.layer-a deterministic Invisible Unicode, agent trailers, generated banners
anthropies.c2pa c2pa Hard-bound C2PA / metadata on raster and SVG
anthropies.pdf c2pa PDF metadata
anthropies.pdf-tools c2pa PDF structure inspect
anthropies.html c2pa HTML metadata
anthropies.md c2pa Markdown metadata
anthropies.svg-strip c2pa SVG metadata strip
anthropies.docx c2pa Word OOXML metadata
anthropies.odt c2pa OpenDocument metadata
anthropies.xlsx c2pa Excel OOXML metadata
anthropies.pptx c2pa PowerPoint OOXML metadata
anthropies.epub c2pa EPUB OPF metadata
anthropies.raster-strip c2pa Raster provenance metadata. Does not drop AVIF/HEIC pixels
anthropies.audit-directory deterministic Bounded directory audit
anthropies.audit-website deterministic Website audit with SSRF defenses
anthropies.rewrite-stylometry statistical Rewrite observation. Not an official-kill
anthropies.gemini-synthid statistical Gemini detector adapter. Fail-soft
anthropies.official official Official detector when ANTHROPIC_DETECT_URL is set
anthropies.markllm statistical Optional Apache-2.0 wrap. Operator checkout
anthropies.markdiffusion statistical Optional Apache-2.0 wrap. Operator checkout
anthropies.ctrlregen statistical Original method code. Operator-supplied weights
anthropies.image-scoring statistical Optional noncommercial sidecar. Not in the core image

Operator profiles and compatibility

The default Compose profile is local-only TypeScript core. Licensed and heavy optional packs stay off until you enable one optional pack profile independently, for example docker compose --profile markllm up (or markdiffusion, ctrlregen, image-scoring).

License disposition and redistribution limits apply per profile. image-scoring is optional-noncommercial and is not redistributed inside the core image. markllm / markdiffusion wrap Apache-2.0 upstreams. ctrlregen keeps operator-supplied weights out of the default image.

Kernel ranges, sidecar protocol 1.0.0, pins, and troubleshooting for unavailable or incompatible optional packs are in docs/COMPATIBILITY.md.

Humanize (title restoration)

humanize is title restoration: a best-effort wording rewrite on a non-origin model so the keyed text mark is no longer the shipped prose. Residual statistical risk remains. It is not an official-kill and does not prove the official Claude text detector will fail.

Default humanize is print-prompt: it prints a rewrite prompt and does not destamp. Run that prompt on a local unmarked model (Llama, Qwen, Mistral, DeepSeek with watermarking off). Do not run it with Claude or Gemini.

# Grok
mkdir -p ~/.grok/skills
ln -sfn "$(pwd)/skills/purge-anthropies" ~/.grok/skills/purge-anthropies

# Claude Code: clean + print-prompt only. Do not rewrite with Claude.
mkdir -p ~/.claude/skills
ln -sfn "$(pwd)/skills/purge-anthropies" ~/.claude/skills/purge-anthropies
# or: claude --plugin-dir "$(pwd)"

In an agent session: /purge-anthropies. Skill: skills/purge-anthropies/SKILL.md. Slash: commands/purge-anthropies.md. Plugin: .claude-plugin/plugin.json.

capture and demo need ANTHROPIC_API_KEY only when the committed allowlist has a model ID. An empty allowlist is valid; then those commands skip live fetch. Live captures land in fixtures/live/ and are gitignored. They are pipeline smoke, not a "this is watermarked" proof.

Configuring the rewrite backend

humanize defaults to print-prompt (no HTTP call). To point it at a local or remote rewrite model, run the interactive setup:

anthropies init-rewrite

This walks you through backend, model, base URL, API key, and remote-allow, then writes ~/.anthropies/config.json. POSIX mode is 0600. Windows uses the profile directory ACLs.

Setting Config file key Env var override Default
Backend rewrite.backend ANTHROPIES_REWRITE_BACKEND print-prompt
Model rewrite.model ANTHROPIES_REWRITE_MODEL (unset)
Base URL rewrite.baseUrl ANTHROPIES_REWRITE_BASE_URL http://127.0.0.1:11434
API key rewrite.apiKey ANTHROPIES_REWRITE_API_KEY (unset)
Allow remote rewrite.allowRemote ANTHROPIES_REWRITE_ALLOW_REMOTE false

Precedence: env var > config file > built-in default. Env vars win for CI/CD and Docker; the config file is for day-to-day interactive use. Non-loopback base URLs require allowRemote: true (or ANTHROPIES_REWRITE_ALLOW_REMOTE=1) — this is a fail-closed guard because the rewrite request sends your full text to the remote server.


Command × channel

Command deterministic c2pa official statistical
inspect report present/absent report present/absent unavailable unless URL set unavailable / not-run
clean strip Layer A strip hard-bound metadata unavailable unless URL set not-run
humanize Layer A first n/a on text unavailable unless URL set best-effort rewrite_metric
init-rewrite n/a n/a n/a writes rewrite config only
capture does not detect n/a does not detect n/a
demo run inspect/clean skipped or certified unavailable unless URL set skipped if print-prompt

inspect exit 1 is driven only by deterministic or c2pa present. Official and statistical never flip inspect to 1 by themselves.



How the Mark Works

Claude output can carry marks at three different layers: generated wording, file metadata, and commit text. They fail in different ways, and a tool that removes one can leave the other two intact. The diagram follows the text through those layers.

                    ┌─────────────────────────────────────────────┐
   YOUR PROMPT ───▶ │  C L A U D E                                │
                    │                                             │
                    │   next-token distribution                   │
                    │        │                                    │
                    │        ▼                                    │
                    │   tournament sampling ◀── secret key k      │
                    │        │                                    │
                    └────────┼────────────────────────────────────┘
                             ▼
                        ┌─────────┐
                        │  TEXT   │  ① keyed watermark (IN the wording)
                        └────┬────┘
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
        ┌──────────┐   ┌──────────┐   ┌──────────┐
        │ .png/.jpg│   │ commit   │   │  prose   │
        │ .svg     │   │ message  │   │  as-is   │
        └────┬─────┘   └────┬─────┘   └────┬─────┘
             ▼              ▼              ▼
        ② C2PA          ③ trailer       ① only
        signed          Co-Authored-By
        manifest        : Claude
        (metadata)      (plain text)

① is the hard one. ② and ③ are metadata and text, so a deterministic edit can remove them. ① is the wording itself.


① The keyed watermark

Anthropic's own analogy is the clearest one available. Imagine a board game where each turn you roll a die. Now replace the die with the digits of π, starting from some agreed position. The moves are still random as far as any player can tell. But someone who knows you used π and knows where you started can look at the finished game and work out that the rolls were not dice.

The watermark changes word choice without adding characters or altering meaning. It changes the source of the randomness the model uses to pick among words that were equally good.

The seed

Every position gets its own seed, computed from the preceding text and a secret key:

   … the  court  will  probably  ▓▓▓▓▓
        └─────────┬─────────┘      ▲
           last H tokens            │
          (H = 4 by default)        │
                  │                 │
                  ▼                 │
          ┌────────────────┐        │
          │ hash(context,  │        │
          │      key k)    │        │
          └────────┬───────┘        │
                   ▼                │
                seed r_t ───────────┘
                   │
                   ▼
       m pseudorandom "g-functions", each of which
       scores EVERY candidate token 0 or 1

The preceding H tokens and secret key produce the per-position seed r_t. That seed selects the g-functions that score each candidate token. Change the key and every score changes. Without the key the scores are unrecoverable, which is why only the holder of the key can detect the mark.

Tournament sampling

Candidates come from Claude's own probability distribution, then pass through a knockout bracket. At each layer, the survivor is whichever candidate scores higher under that layer's g-function.

  layer 1   [hold]  [find]   [rule]  [conclude]      ← drawn from the model's
              g=1     g=0      g=0      g=1             own distribution
                \     /          \      /
                 \   /            \    /
  layer 2       [hold]           [conclude]
                 g=0                g=1
                    \               /
                     \             /
  layer 3              [conclude]  ◀── emitted
                                       (30 layers by default)

Every survivor is a word the model already rated as good. The tournament breaks ties the same way every time for a given key and context. That consistency creates the signal.

Two consequences follow:

Why code is barely marked

This follows from the sampling rule. The tournament can only bias a choice if there is a choice.

  HIGH ENTROPY: prose                    LOW ENTROPY: code / facts
  many equally-good next words           one correct next token

  "the argument is …"                    "for (int i = 0; i <"
     ├── compelling  █                    ├── i           ████████████
     ├── persuasive  █                    ├── j           ▏
     ├── forceful    █                    └── k           ▏
     ├── strong      █
     └── weak        █                    tournament has nothing to pick
  tournament picks among them             between: NO MARK
  MARK LANDS

Anthropic states the limit in its own words. Where there is no choice to make, the watermark is not applied: where "something would be factually wrong or a piece of code would break if a different term was chosen." And code "has generally less watermarking than some other forms of text," because it "in very many cases has to be exact."

Syntax and exact facts leave little room for the tournament, but comments and identifier names can still offer several acceptable choices. They remain more exposed.

Detection

Detection needs the key, not the model. The mean detector reports a raw score, the frequentist detector reports a p-value against an unkeyed-text null, and the Bayesian detector reports a conditional probability. They answer different questions:

  scored g-values ──┬─▶ MEAN            raw score, ~0.5 under the null
                    │                   (needs a length-specific threshold)
                    │
                    ├─▶ FREQUENTIST     an exact p-value against
                    │                   "this text is not keyed"
                    │
                    └─▶ BAYESIAN        P(watermarked | g-values)
                                        ⚠ conditioned on an assumed base rate,
                                          default 0.5; must be trained per key

The reported operating point is a true-positive rate of about 70% at 200 tokens against a 1% false-positive rate, rising to roughly 87% at 400 tokens. Short passages sit near the detector's floor: maximum true-positive rate around 0.3 at 50 tokens.

A detection is a statement about contact with the system, not about authorship. It cannot distinguish "Claude wrote this" from "Claude edited this."


② C2PA content credentials

A C2PA credential is a cryptographically signed manifest attached to .png, .jpg, and .svg. Its hash binds the manifest to a particular file under a certificate chain, so the credential can show that the file it accompanies is the file that was signed.

   ┌──────────────────────────────┐
   │  image bytes                 │  ← unchanged
   ├──────────────────────────────┤
   │  C2PA manifest               │  ← signed, tamper-evident
   │  "processed with Claude"     │
   └──────────────────────────────┘
              │
      re-encode, screenshot,
      or strip metadata
              ▼
   ┌──────────────────────────────┐
   │  image bytes                 │  ← still valid, credential gone
   └──────────────────────────────┘

Verification is deterministic: no threshold, no error rate, no length dependence. Re-encoding, s

anthropies (CharlesHoskinson/anthropies)

Searching Database…

Что это?Anthropies — CLI-инструмент и локальный HTTP-сервис, снимающий вендорные метки (невидимый Unicode, трейлеры, баннеры, C2PA и метаданные файлов) с уже принадлежащих вам результатов, сгенерированных ИИ. Он явно не удаляет ключевой текстовый водяной знак Anthropic — только слои метаданных и форматирования вокруг него.
Это CLI-инструмент или веб-приложение?Это прежде всего инструмент командной строки (inspect, clean, humanize, capture, demo), который может также работать как локальный HTTP-сервер через команду serve, по умолчанию привязанный к loopback.
Как его запустить?Запустите мгновенно через 'npx anthropies --help' или склонируйте репозиторий, выполните 'pnpm build', затем 'node dist/cli.js --help'. Docker-образ также доступен через 'docker compose up --build'.
Нужен ли API-ключ Anthropic для использования?Нет, не по умолчанию. 'capture' и 'demo' требуют ANTHROPIC_API_KEY только когда закоммиченный allowlist уже содержит ID модели; с пустым allowlist они просто пропускают живую загрузку. Для сборки и запуска CLI нужен Node.js 22+.
Это действительно обходит детектор водяных знаков Claude?Нет — он не может удалить ключевой текстовый водяной знак Anthropic, только метаданные файлов, невидимый Unicode и трейлеры. Команда 'humanize' делает переписывание «по мере возможностей», снижающее статистическую обнаружимость, но это прямо не является снятием официальной метки и нигде не утверждается, что официальный детектор Claude не сработает.
Отправляет ли функция humanize мой текст на удалённый сервер?Только если вы явно согласитесь. Бэкенды переписывания не на loopback требуют установки allowRemote в true, иначе запрос отправил бы полный текст вашего документа на внешний сервер; эта защита по умолчанию выключена (fail-closed).
Что именно представляет собой ключевой водяной знак Anthropic?Это скрытое смещение в выборе слов, а не добавленная полезная нагрузка: в каждой позиции токена секретный ключ плюс предшествующий текст дают seed, который решает, какое из нескольких одинаково хороших слов-кандидатов выиграет «турнир» скоринга. Обнаружить итоговый паттерн может только владелец ключа.
Почему код почти не помечается водяным знаком?«Турнир» может смещать выбор, только когда несколько токенов одинаково валидны, а в коде взаимозаменяемых вариантов куда меньше, чем в прозе, поскольку синтаксис и точные факты оставляют мало простора для замены слов. Поэтому собственное маркирование Anthropic на коде гораздо слабее, чем на текстах на естественном языке.
Какие типы файлов он может чистить?В нём есть специализированные пакеты для PDF, HTML, Markdown, DOCX, ODT, XLSX, PPTX, EPUB, SVG и растровых изображений, вычищающие жёстко привязанные метаданные и данные происхождения из каждого формата.
Что на самом деле доказывает команда demo?Команда demo прогоняет inspect и clean по четырём каналам обнаружения (детерминистический, C2PA, официальный, статистический) и печатает результаты, но это явно лишь «дымовая проверка конвейера», и нигде не утверждается, что официальный текстовый детектор Claude не сработает.
Size
1.1 MB
Stars
191
Age
2mo
Commits · 90 Days