A printed research paper on a desk

Docs

Documentation

Install draft, run your first paper in a minute, and read the full command-line reference — with real terminal output at every step.

draft is a command-line tool that turns a research PDF into a publication-ready Markdown article where every sentence is grounded in a quote-verified claim from the source. This page takes you from a clean machine to a checked, published article, then documents every flag, output and failure mode.

New to the idea? Read how grounding works first — it explains the gate that makes the output trustworthy. Ready to run it? Start below.

Overview

A run moves a paper through four phases. Only two of them call a model; the rest are deterministic Go.

  1. Read and section. The PDF is read to text and split into sections.
  2. Extract and verify. Each section is mined for claims, and a claim survives only if its quote appears verbatim in the source and every number in it appears in that quote.
  3. Write. The verified ledger — and nothing else — is arranged into an article in your house style.
  4. Attribute and sign. Every sentence is mapped back to the claim behind it, and a C2PA manifest is written beside the article.
Before you start draft never asks for an API key. Online, it drives an AI coding-agent CLI you are already logged into; offline, it uses a local model. Your PDF is read on your machine. See provenance & compliance for exactly what leaves it.

Install

Pick one. Homebrew is the shortest path on macOS; go install works anywhere with a Go toolchain.

Homebrew (macOS)

brew install --cask sebastienrousseau/tap/draft

Go toolchain (any platform)

go install github.com/sebastienrousseau/draft/cmd/draft@latest

From source

git clone https://github.com/sebastienrousseau/draft
cd draft && make build

Dependencies by platform

draft reads PDFs with pdftotext (Poppler) and, offline, writes with a local Ollama model. .docx is read by textutil on macOS (built in) or by --reader docling anywhere.

Platform Poppler (pdftotext) Ollama (offline writing)
macOS brew install poppler brew install ollama
Debian / Ubuntu sudo apt-get install poppler-utils curl -fsSL https://ollama.com/install.sh | sh
Fedora sudo dnf install poppler-utils curl -fsSL https://ollama.com/install.sh | sh
Windows scoop install poppler (or choco install poppler) download from ollama.com/download

You need Poppler only for PDF input, and Ollama only for offline runs.

Quickstart

From a clean machine to a checked article in four steps.

1. Check the machine

draft --doctor reports what draft can find: readers, backends, and the paths it will read from and write to. You need one online backend or a running Ollama server.

SOURCE TOOLING

pdftotext /opt/homebrew/bin/pdftotext

docling --reader docling: tables and structure, slower

BACKENDS

claude session provider

copilot session provider

ollama responding at http://127.0.0.1:11434

PATHS

drafts (--out) ~/Drop/Drafts

Ready. Run draft --dry-run <source> to check a specific paper.

Real draft --doctor output. A green tick is a backend draft can use; run --dry-run to check one specific paper without calling a model.

2. Run a paper

Point draft at a PDF. In auto mode it picks the first backend you are logged into and shows a live view of the four phases as they run.

draft "2603.23420.pdf"

draft ⧇ Drafting Grounded Articles — claude · sonnet · 900–1200 words


Queue

[1/1] 2603.23420.pdf

Pipeline

Resolve source

Read and section

Extract claims

Write article

·Validate and save

Log

· read 5 section(s)

· 6 claim(s) verified, 9 dropped

· writing…

Live Draft

writing, 342 words visible

57%

## Router-S: conditional compute at a fixed budget

Router-S reaches a validation loss of 3.41 against a dense baseline on an identical token budget — but the same evaluation reports that seed variance exceeds the gap being measured, which is the more important number to sit with.

Sparse routing is designed to cut the compute spent on tokens that are trivially predictable

[q] quit · [j/k] up/down · [pgup/pgdn] page

The draft terminal UI mid-run. On the left, the queue and the five-phase pipeline with a live log; on the right, the Live Draft panel — a status line, a progress bar, and the grounded article previewing as it is written, sentence by sentence. Prefer no UI? Add --print (paths to stdout) or --json (one JSON object per job).

When it finishes, the summary line reports the result:

Resolve source

Read and section

Extract claims · 6 verified, 9 dropped

Write article

Validate and save

✓ 1,066 words via claude in 3m 54s · 16,230 tokens · $0.52

A finished run. Nine of fifteen candidate claims were dropped by the gate — that is grounded-by-construction working, not a bug. A thin source yields a short draft rather than a padded one.

3. Inspect the article set

Each run writes one article as a dated set: three files that stay in sync, plus two a reader can check.

~/Drop/Drafts/2026-07-29/
├── source/2026-07-29-<slug>-body.md          # the article — edit this
├── yaml/2026-07-29-<slug>-frontmatter.yaml   # adjacent frontmatter
├── final/2026-07-29-<slug>-final.md          # combined, ready to publish
└── provenance/
    ├── 2026-07-29-<slug>-attribution.json    # which claim backs each sentence
    └── 2026-07-29-<slug>-c2pa.json           # C2PA manifest

Edit the body, then regenerate the other two in place with draft --frontmatter <body.md>. Your curated fields are preserved; only missing ones are rebuilt. See the article set for the rules.

4. Verify it

draft --verify recomputes the digests and confirms the article still matches the ledger it was written from.

PROVENANCE

made by draft 0.0.35

·written with claude sonnet

article unchanged since it was written (64261b97…)

claim ledger matches the verified claims

GROUNDING

·claims 6 verified

·attribution 13 of 36 sentences rest on a claim

SOURCES

two-column.pdf unchanged since it was read

Verified. The article matches the provenance written beside it.

Edit a sentence the ledger did not support and re-run this: verification fails. Download a real, verifiable set on the provenance & compliance page and run --verify on it yourself.

The run, phase by phase

The live view above maps one-to-one onto the pipeline. Each phase reports as it completes:

Phase What happens Model call?
Resolve source Locate the file; bare names resolve against ~/Drop/Drafts/Sources. No
Read and section pdftotext (or --reader docling) extracts text; it is split into sections. No
Extract claims One call per section mines claims; each is checked against the source and dropped unless its quote is verbatim. Yes
Write article One call arranges the verified ledger into an article in your house style. Yes
Validate and save House-style checks run; the set is written with attribution and a C2PA manifest. No
Tip The deterministic path — read, section, gate, validate — runs in about a tenth of a second on a 62-page paper. Everything else is model latency, which depends on your engine, not on draft. See the benchmarks.

Choosing an engine

In auto mode draft walks a preference list and uses the first backend you are logged into. Force one with --engine <name>, or split the two model phases with --extract-engine and --write-engine.

Verified, used by auto mode: claude, copilot, codex, grok, agy, cursor-agent.

Experimental (invocation correct, output unverified; auto uses them only with --experimental): amp, crush, goose, qwen, gemini-acp, codex-acp.

Offline: --engine ollama runs the whole pipeline against a local model. If an online call fails because you are offline, draft fails over to Ollama and stays there for the rest of the run.

No API key A session backend uses that tool's own logged-in session — the same credentials you already use with the CLI directly. draft stores no keys and adds no network calls of its own.

Escape hatch (opt-in): on a machine with no agent CLI, --engine api:anthropic or --engine api:openai calls a hosted API directly, reading your own key from ANTHROPIC_API_KEY or OPENAI_API_KEY. It is never chosen by auto mode — the keyless agent-session path stays the default — and it fails over to Ollama like any other backend.

Readers

Reader Use it for Speed
pdftotext (default) Most PDFs. A 62-page paper in about 110 ms. Fast
--reader docling Papers where tables and structure matter; reads PDF and DOCX on every platform. Mines table cells into claims. Slower

PDF, Markdown, plain text and DOCX are all accepted, and so is LaTeX (.tex) — read directly with no external tool, keeping a formula as exact text where pdftotext would scramble it.

Command reference

draft [flags] <source> [more-sources...]

Bare filenames resolve against ~/Drop/Drafts/Sources. Each source becomes its own draft, processed as a queue.

Engine and model

Flag Description
--engine <mode> auto (default), ollama, a provider name, or api:<provider>
--extract-engine <m> Backend for claim extraction (default: --engine)
--write-engine <m> Backend for writing (default: --engine)
--model <name> Session-provider model override (e.g. opus)
--experimental Let auto mode use experimental providers
--num-ctx <n> Ollama context window (default 8192)
--num-predict <n> Ollama max output tokens (default 6000)

Reading and grounding

Flag Description
--reader <name> pdftotext (default) or docling
--style <file> JSON house-style file: word band, banned vocabulary, language variant
--strict-numbers Fail on a number found in no verified claim
--second-gate Opt-in semantic pass: drop verified claims a local model finds unsupported by their quote
--no-cache Re-extract instead of reusing cached claims
--clear-cache Delete every cached claim extraction and exit

Output and workflow

Flag Description
--out <dir> Directory to write drafts into (default ~/Drop/Drafts)
--sources-dir <dir> Directory bare filenames resolve against
--merge Combine all sources into one draft
--force-new Draft even if today's folder already has one
--resume Reuse a verified claim ledger from an earlier attempt
--review <draft.md> Enhance an existing draft with surgical edits
--frontmatter <file> Regenerate frontmatter and the final article
--verify <file> Check an article against its provenance, and exit
--keep-artifacts Keep prompt/ledger files beside a successful draft

Modes and info

Flag Description
--print Run without the UI; print draft paths to stdout
--json Machine-readable output: one JSON object per job, or a verification record with --verify
--dry-run Report what a run would do, without calling a model
--doctor Check that this machine can run draft, and exit
--completion <sh> Print a completion script: bash, zsh, or fish
--version Print version and exit
-h, --help Show help

Examples

draft "2603.23420.pdf"                  # one paper
draft a.pdf b.pdf c.pdf                 # three drafts, queued
draft --merge notes.md paper.pdf        # combine into a single draft
draft --engine ollama paper.pdf         # force the local model
draft --review draft.md paper.pdf       # enhance an existing draft
draft --frontmatter source/x-body.md    # regenerate the yaml + final set

The article set

One article. Three files. Always in sync. Plus two a reader can check. Edit the body, then run draft --frontmatter <body.md> to regenerate the frontmatter and combined document. Three rules make that safe to run at any time:

  1. The filename is the article's identity. Its date and slug drive every URL in the frontmatter. Retitle the article and the permalink holds.
  2. Your edits always win. Curated fields are preserved verbatim; only missing ones are generated. Delete a field to have it rebuilt.
  3. Unchanged input is a no-op. Reprocessing a set that has not changed rewrites every file byte for byte identically.

The provenance pair is written once, by the run that produced the article, and is not regenerated — it describes the article the ledger was verified against.

Provenance and verification

Every set ships a per-sentence attribution file and a C2PA manifest. draft --verify <final.md> recomputes the digests and reports whether the article, the ledger and the sources are all unchanged. It is the reader's check, not just yours — anyone with the files can run it.

Signed credentials (opt-in). Configure a signing certificate chain and key (DRAFT_C2PA_CERT / DRAFT_C2PA_KEY, with c2patool installed) and draft also writes a signed, detached .c2pa credential bound to the article; draft --verify then validates its signature and trust chain as well as the digests. Without a certificate the manifest stays an unsigned definition, exactly as before.

A portable record. draft --verify --json prints a self-contained draft.verification-record/v1 — the article digest and whether it matches, the grounding summary, the signature state, and the overall verdict — that a script or another tool can consume and re-check without the CLI.

See provenance & compliance for what the manifest contains, how it maps to AI-disclosure rules, and a real set you can download and verify.

House style

--style <file> points draft at a JSON house-style file: a word band, a banned vocabulary, and a language variant. Style is enforced on the finished draft, not merely requested — a draft that breaks a rule is corrected, not shipped.

Configuration and environment

Most flags have an environment-variable equivalent, useful for CI or a shared default:

DRAFT_ENGINE, DRAFT_EXTRACT_ENGINE, DRAFT_WRITE_ENGINE, DRAFT_EDIT_ENGINE,
DRAFT_MODEL_SESSION, DRAFT_MODEL, DRAFT_WRITE_MODEL, DRAFT_EXTRACT_MODEL,
DRAFT_EDIT_MODEL, DRAFT_NUM_CTX, DRAFT_NUM_PREDICT, DRAFT_STRICT_NUMBERS,
DRAFT_SECOND_GATE, DRAFT_READER, DRAFT_DRAFTS_DIR, DRAFT_SOURCES_DIR,
DRAFT_CACHE_DIR, DRAFT_NO_CACHE, DRAFT_C2PA_CERT, DRAFT_C2PA_KEY,
DRAFT_C2PA_ALG, OLLAMA_HOST

Set DRAFT_SHOW_LOGO=0 to suppress the nib mark in --help. Publisher identity for the C2PA manifest is configured with the DRAFT_SITE_* variables.

Config files

For defaults you would otherwise repeat, draft reads a project draft.toml in the working directory and a user ~/.config/draft/config.toml (honouring XDG_CONFIG_HOME). They set the same settings as the flags — engine, extract-engine, write-engine, edit-engine, reader, model, the Ollama models, out, sources-dir, style, and the c2pa-cert / c2pa-key / c2pa-alg signing keys.

Precedence is flags > environment > project file > user file > built-in default, so adding a config file never changes what an existing command already does. DRAFT_CONFIG names an explicit file; DRAFT_NO_CONFIG disables the layer. The parser is a dependency-free flat key = value reader — no new module.

# draft.toml
engine = "claude"
reader = "docling"
out    = "~/Drafts"

Troubleshooting

No text in the PDF A scanned PDF has no text layer, so extraction returns nothing and the run fails. Use a source with selectable text, or convert it with OCR first. Native OCR is on the roadmap.

No backend found. Run draft --doctor. Log into one supported agent CLI, or install Ollama and start it for offline runs. You need exactly one.

A thin ledger. A source with few checkable claims yields a short draft by design. draft never pads; a short draft means the paper offered little the gate could verify.

Offline model not pulled. --engine ollama needs the model downloaded beforehand and the Ollama server running. draft --doctor reports whether it is reachable.

A run failed partway. The verified ledger is left on disk. Re-run with --resume to skip straight to writing rather than re-paying for extraction.

Next steps