rubenglez

doctier

Tiered privacy and lifecycle for generated docs, over git

GoGitage

Get the binary ↗

Coding agents generate a lot of documents alongside the code: plans, specs, strategy notes, throwaway scratch files. Git models exactly one axis for them, tracked or ignored, so there is no “private but shared” and no “delete itself when the PR merges”. doctier builds those two missing axes on top of git instead of inventing a new store.

Each document is classified by visibility (public plaintext, or private, encrypted with age using the SSH keys you already have) and lifetime (durable forever, or ephemeral with an expiry trigger: a TTL, a PR merge, or the worktree it was born in). Because everything maps to git primitives, encrypted docs travel to every clone and worktree through git’s own checkout; a coding agent spawned in a fresh worktree sees exactly the docs it should, already decrypted, with nothing extra to set up. Concurrent edits to a private doc merge like any other file: a merge driver decrypts both sides, 3-way merges the plaintext, and re-encrypts the result.

The checks are fail-closed and also run in CI, which matters: the filter and hooks live in .git and don’t travel with a clone, so the CI check is what makes the guarantee hold for every contributor. On GitHub that’s one line, the bundled action installs doctier and runs the check. The manifest and recipients file are plain tracked files, so gate changes to them with code review; the README is upfront about what age can and cannot hide.

For agent workflows, doctier agents maintains a tier-aware context block in AGENTS.md, listing ephemerals only while they’re in flight for the current unit of work, and a companion doctier-setup skill (npx skills add RubenGlez/doctier) scans the repo and writes the manifest for you, asking only about the exceptions.

It’s a single static Go binary, no Go toolchain needed: prebuilt binaries on GitHub Releases, a Homebrew tap (the repo doubles as its own tap), or an install script, with macOS builds signed and notarized. Status is early (v0.x) and actively developed; the core, from manifest to filters, checks, merge driver, and GC, works end to end.

01

Init

Run doctier init in your repo. It scaffolds the .doctier.yml manifest, syncs .gitattributes and .gitignore with your rules, and installs the git hooks and the encryption filter.

02

Classify

Write rules only for the exceptions. A document that matches no rule stays public and durable, plain git's default; first match wins.

03

Grant

doctier grant adds an SSH public key to the recipients and re-encrypts private docs. Revoking is deleting that line and running grant again.

04

Forget about it

git add encrypts private docs, checkout decrypts them, a merge driver 3-way merges them across branches, the pre-commit check blocks cleartext leaks, and doctier gc collects expired ephemerals.

What each tier maps to

VisibilityLifetimeStorage
publicdurabletracked, plaintext
privatedurabletracked, encrypted with age
anyephemeraltracked; deleted at the expiry trigger
anyephemeral + sensitivegitignored, local; dies with the worktree
The doctier banner — the wordmark and pitch next to a 2×2 matrix of visibility (public, private) by lifetime (durable, ephemeral), each cell showing how that tier is stored in git