tandemdoc
v0.1.0
Published
Share a Markdown file to a live Google Doc your reviewers comment in — a thin MIT client for the hosted TandemDoc review layer. Comments in, commits out.
Maintainers
Readme
TandemDoc
The human review layer for agent-built docs — in the real Google Doc your reviewers already use.
You and your agents write Markdown in Git. Your reviewers live in Google Docs. TandemDoc bridges the two without making anyone move:
tandemdoc share spec.md
→ https://docs.google.com/document/d/… (live, review-ready, commentable)Comments in, commits out. Your Markdown stays the source of truth; the Doc is a live mirror your reviewers can comment on. Their comments come back to you — and when your agent addresses one, the thread gets resolved with a reply that says what changed.
This repo is the open client: the CLI, the MCP config, the tool schemas, and the fidelity corpus. The sync engine and the pair state are the hosted product — see What's open, what's cloud. No self-host theater.
30-second quickstart
npx tandemdoc@latest login # device code — approve in any browsercd your-repo
npx tandemdoc@latest share docs/spec.mdThat's it. You get a live Google Doc URL. Send it to your reviewer — they need nothing installed, no account with us, no new tool. Reviewers are always free.
npx tandemdoc@latest pull # see their comments in your terminal
npx tandemdoc@latest status # sync state for every linked doc
npx tandemdoc@latest whoami # which account this CLI acts as (offline — no network call)On a paid Approval Lane, a founder can approve a pending change and mint a signed-off, immutable version — then hand out a receipt anyone can check without trusting us:
npx tandemdoc@latest approve --pair <id> # approve the pending candidate → ApprovedVersion
npx tandemdoc@latest receipt --pair <id> --json > receipt.json # fetch the publishable manifest
npx tandemdoc@latest receipt --verify receipt.json # replay the chain OFFLINE — no network, no loginreceipt --verify is the honest part: it re-derives the whole governance chain from the saved manifest with the network unplugged, shares no code with the server that produced it, and names the exact position if anything was altered. The manifest is content-free — ids and hashes only, never your document text.
Why a receipt, when AI output is already watermarked?
Watermarks answer did an AI touch this? Receipts answer did a human stand behind it? As agents write more and humans review less, the few documents a human genuinely approved are the ones governing everything downstream — who stood behind them, in what role, on exactly which version. This is the artifact that proves which those were.
Manage the lane itself from the terminal — every subcommand a thin client over the same MCP tools (the readout and the lanes.yml validation are computed server-side, so the CLI never forks a copy that could drift):
tandemdoc lane create --pair <id> --preset fast-lane <rosterId…> # bind a Fast-Lane (who may Command / Approve) — DACI: author lanes.yml + `lane compile`, or the web Lane Builder
tandemdoc lane assign [email protected] --pair <id> --role approver # add a roster reviewer to a lane role
tandemdoc lane compile --lane <laneId> --file lanes.yml # compile a lanes.yml policy (paid plan)
tandemdoc lane show --pair <id> # the plain-English readout, verbatim
tandemdoc lane doctor --pair <id> # ENFORCED (exit 0) vs ATTESTED (non-zero) — scriptabletandemdoc lane doctor is the scriptable gate: it exits 0 only when the merge is actually enforced (branch protection can block an unapproved merge) and not C1 sharing-blocked — attested (recorded, not blocked) is non-zero, so tandemdoc lane doctor --pair <id> && deploy never trusts an overclaim. A bad policy — on create, assign, or compile — comes back as the same typed floor reasons the web builder shows, and nothing is bound or written.
The npm package and the installed command are both
tandemdoc. Every command takes--jsonfor agents; exit codes are0ok ·1refusal ·2usage ·3network. Several Google accounts on one machine?tandemdoc whoaminames the one you're acting as, andtandemdoc login --as [email protected]tells the approval page who you expect to be.
Use it from your agent (MCP)
TandemDoc is a thin client over the same remote MCP server your agent can use directly:
tandemdoc mcp install --target claude-code # also: claude-desktop, cursor, vscode, --printOr configure it yourself:
{
"mcpServers": {
"tandemdoc": {
"type": "http",
"url": "https://mcp.tandemdoc.com/mcp",
"headers": {
"Authorization": "Bearer <your token — run `tandemdoc login`>"
}
}
}
}Tools your agent gets:
| Tool | What it does |
|---|---|
| create_link | Link a repo Markdown file to a live Google Doc reviewers can comment on. Returns the Doc URL, the pair id, and a fidelity receipt. On a lossy conversion it refuses and creates nothing — it never absorbs a fidelity risk on your behalf. |
| list_links | List your linked docs: id, title, repo/path, sync status. Read-only. |
| get_link_status | Poll one link's provisioning + sync state and its fidelity receipt. Use it to await the first sync after create_link. |
| get_link_review | Read the open reviewer threads on a link: the anchored quote, the reviewer's display name, timestamps, and replies. Read-only. |
| check | Check whether a Markdown doc is inside the Google Docs writable set before you create_link it — the exact reason a real sync would refuse it. Read-only. |
| create_lane | Bind a governance Approval Lane (Fast-Lane preset) to a pair: who may Command an edit and who may Approve it. The policy floor refuses a bad lane with typed reasons — no lane is bound. |
| get_lane_status | Report a lane-bound pair's governance status: the bound lane, any Approve pending, any approved version pending on the mirror, the plain-English readout (lane show), and the enforced-vs-attested doctor verdict (lane doctor). Read-only. |
| approve | Approve the pending candidate on a lane-bound pair (backs tandemdoc approve). Records the approval and freezes an immutable approved version once the merge lands. |
| get_receipt | Fetch a pair's approved-version receipt (backs tandemdoc receipt): the publishable, content-free JSON manifest that verifies offline. Read-only. |
| assign_reviewer | Assign a reviewer (by email) to a role on a pair's Approval Lane (backs tandemdoc lane assign). The reviewer must already be on the account roster; a non-roster email is refused with the policy floor's typed reason and nothing is written. |
| verify_receipt | Verify an approved-version receipt manifest server-side — replays the governance chain from genesis and names the offending event on failure. The server twin of the CLI's offline tandemdoc receipt --verify. Read-only. |
| compile_lane | Compile a lanes.yml policy file into a new governed snapshot version for a lane (paid plan; backs tandemdoc lane compile). An invalid file is refused with the typed floor violations — nothing moves. |
So the whole loop is one instruction away: "share this spec for review" … "check if anyone commented" … "address her comment and push." You steer, the agent pedals.
What we can never do to your Doc
Most Markdown→Docs pipelines are one-shot publishers: the demo works, and the second push silently destroys your reviewer's comments — while the API keeps reporting them alive. We built TandemDoc because we measured exactly that.
Our sync engine ships behind a fidelity corpus — a public set of survive-or-refuse invariants it must pass before any release touches a real Doc:
- A comment on a paragraph the update doesn't touch survives — not moved, not duplicated.
- A comment that appears mid-write on a region about to change aborts the write — captured, never clobbered.
- Ambiguous anchors are reported as ambiguous, never silently guessed.
- A quote spanning an edit boundary is reported unmatched, never mis-anchored.
- Round-trips do not drift — every cycle must reproduce the canonical Markdown.
- And when a document is outside our fidelity envelope, the answer is a loud refusal with a receipt — never a quiet mangle.
The corpus is in corpus/ with a runnable checker. It's host-agnostic — you can point it at whatever stack you're currently syncing Docs with. Our engine's current pass results are committed to the repo, and CI verifies that committed export against a fresh render on every release — the drift-gate — so what you read is what actually shipped: corpus/results/latest.json.
What's open, what's cloud
We believe you should be able to read every line that runs on your machine — and we won't pretend the rest is open when it isn't.
| Open (MIT, this repo) | Closed (the hosted product) |
|---|---|
| The TandemDoc CLI — everything that runs on your machine | The fidelity/sync engine |
| MCP config helpers + the full tool schemas | Durable pair state & version bookkeeping |
| The fidelity corpus + checker harness | Comment harvest & loop orchestration |
| This README, the docs, llms.txt | The hosted sync service |
There is no self-hosted server, and we're not planning one for v1. Anything stateful — the pair, the sync, the trust machinery — runs in our cloud. Your token is yours: tandemdoc logout revokes it server-side, immediately — and tandemdoc logout --all revokes every account stored on the machine.
Honest limits
- Formatting envelope. We sync the constructs we can round-trip losslessly (headings, paragraphs, emphasis, code, lists, links, tables). Documents that need more than that — heavily formatted legal/contract layouts, for instance — get a refusal, not a best-effort mangle.
- Reviewer identity is display-name only. The Drive comment API doesn't expose emails to third parties. We tell you the name; we don't invent the identity.
- Google Docs today. Other hosts are built behind the same seam and will surface when they meet the fidelity bar.
- The CLI is thin by design. No daemon, no watchers, no telemetry — it makes network calls only to our API for the command you ran, and nothing else.
Pricing
Free — 1 live shared doc, forever · Author $99/mo — everything: unlimited docs, the full loop, approval lanes, the Review Record · 30 days free to start, no card required. Reviewers are always free. Unlimited. Your reviewers never need a seat to comment.
Details: tandemdoc.com/pricing · Security & data handling: tandemdoc.com/security
Contributing
Bug fixes, new tandemdoc mcp install targets, docs, and checker improvements are very welcome — see CONTRIBUTING.md. Corpus cases are proposed via issue (they enter through the engine's CI, so the public corpus always reflects what actually ships). Security reports: SECURITY.md.
License
MIT. "TandemDoc" and the chain-link mark (one solid plate, unequal pins) are trademarks — see TRADEMARK.md.
