copydesk
CLAUDE.md1 starsChanged 2 months agoMITView on GitHub
Auto-loaded on every session. AGENTS.md symlinks here for harnesses that expect that filename. CopyDesk is a prose gate for AI agents. It occupies three pipeline positions no other tool stands in: rules enter the model's context before generation, a write is refused at write time so the model must revise, and a pre-commit hook refuses a commit whose added Markdown breaks the rules. The rule engine is harness-neutral; per-harness adapters translate payloads at the edge. Adopted unchanged from CrossRev's ADR…
- Commits and pushes
In this repositoryOne other file it gives its agents.
- copydeskSkill
The file
We split this CLAUDE.md into the rules it gives an agent
1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 31
Commit messages, pull request and issue titles and bodies, review comments and release notes are public and permanent.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CopyDesk — instructions for AI agents
Auto-loaded on every session. AGENTS.md symlinks here for harnesses that expect that filename.
CopyDesk is a prose gate for AI agents. It occupies three pipeline positions no other tool stands in: rules enter the model's context before generation, a write is refused at write time so the model must revise, and a pre-commit hook refuses a commit whose added Markdown breaks the rules. The rule engine is harness-neutral; per-harness adapters translate payloads at the edge.
How the name is written
Adopted unchanged from CrossRev's ADR 0010.
CopyDesk is the default in every human-readable reference. Printed command output, the prose inside help text, documentation, skill text and diagram labels all take CopyDesk.
Lowercase copydesk is an allowlist, not a split down the middle. The complete list: the command and its arguments, the npm package name, config filenames, installed paths, environment-variable prefixes in their lowercase forms, and any string a script matches literally.
The trap that catches people: in help text, copydesk check README.md stays lowercase and the sentence above it does not.
plain-english is a preset name, not the tool. Every string naming that preset keeps its own spelling, including the output style's name: Plain English frontmatter, the plain-english-rules block markers, and rules/plain-english.json.
Two repositories, one working tree
A private working-memory sidecar sits beside this repository: carlosboeing/copydesk-workbench, cloned as an independent git repository at .workbench/ and git-ignored here. Penmark and CrossRev both use the same arrangement.
Never cross-commit. Plain git … targets this public repository. git -C .workbench … targets the private workbench. No command legitimately stages both.
Working memory — brainstorms, designs, plans, reviews, notes, and the captured evaluation transcripts — lives in the workbench. Code, public documentation, ADRs, ROADMAP and CHANGELOG live here.
A pre-commit hook at git-hooks/private-workbench-guard/pre-commit refuses a commit that stages the workbench as a gitlink. git add -f .workbench records a submodule reference, publishing the private repository's name and commit SHA even though clones get none of its content.
What a public artifact may say
Commit messages, pull request and issue titles and bodies, review comments and release notes are public and permanent. A reader arrives with the repository and nothing else.
Never name a private or local source in one. Not .workbench, not copydesk-workbench, not the bare phrase "the workbench", not a path to a document held there, not /Users/..., not a client name or an internal cost figure.
The damage is a citation the reader cannot follow. "See the plan in the workbench" says something exists and withholds it, which is worse than saying nothing. Restate the fact instead: put the reasoning in the body in its own words, or in an ADR under docs/adrs/ that the artifact then links. A record that cannot be published is "held locally, available on request".
No hook catches this. git-hooks/private-workbench-guard/pre-commit reads the staged diff, so it never sees a message or a body, and gh pr create --body reaches the GitHub API without touching git.
A pull request body follows .github/PULL_REQUEST_TEMPLATE.md, which gh pr create --body bypasses. An issue title is one clause under 60 characters naming the change or the symptom.
The compatibility contract
Six items are frozen from the first public release. A language rewrite must not move them. Everything else is internal and free to change.
- A
versionfield in the config file. Without it no schema migration is possible. - Rule identifiers.
sentence-length,banned-word,orphan-pointerand the rest. An alias map absorbs future renames. - A three-value severity vocabulary:
errorblocks,warnreports,offdisables. A fourth value later is a migration. - Additive list semantics. Word lists take
addandremove, never replacement. Replacement makes extending a preset require restating it. extendsaccepting a string or an array, later entries winning, with an explicitrulesblock overriding everything.- The command-line surface: commands, flags, environment variables and exit codes.
The telemetry event schema is versioned separately and joins this list unchanged.
At 1.0.0, the compatibility contract gains channel names (chat, documents, commits, reviews), style names (plain, engineer, editorial, general), guidance identifiers, canonical camelCase configuration parameters, and the three-location discovery order (user, project, local). Until 1.0.0, these prevention items remain free to move as usage feedback warrants.
Deliberately free: which rules are compiled and which are data, the implementation language, the internal rule representation, how presets are stored on disk, and whether more rule extension points arrive later.
bin/copydesk is the permanent entrypoint. Every installer, hook and document goes through it, so a later implementation replaces what sits behind it with no consumer seeing a difference.
Distribution
Published to npm as copydesk. The name was free and npm accepted it, so the copydesk-ai fallback was never needed.
The fallback existed because npm refused crossrev for a sibling project, and that check runs only at publish time with no advance query and no appeal. The -ai suffix is a collision workaround for that one name rather than a house convention.
Versioning follows the house pattern: a root VERSION file, vX.Y.Z tags, a floating v0, and Keep a Changelog format.
Working principles
- The test suite is the safety net and it stays green.
python3 -m unittest discover tests/. The pre-commit hook runs it with no path guard, because an earlier guard exited 0 in silence once its path moved. - Every scan states a control. A scan returning nothing proves nothing until a pattern known to be present returns a hit through the same command form.
- The rule data travels with the linter.
lib/linter.pycompilesrules/plain.jsonat import. An installed hook copy needs the preset beside it, orCOPYDESK_RULESpointing at one. Without it the module raisesPresetNotFoundand the gate exits non-blocking. - Instructions are generated, never hand-edited.
scripts/generate-instructions.pyrendersoutput-styles/copydesk.mdand the reminder precis from the preset. Continuous integration runs--check. - The gate fails open. A hook that blocks on its own misconfiguration is worse than one that lets the write through. It prints the error and records a telemetry event.
- Conventional Commits.
<type>(<scope>): <description>, imperative mood, subject at most 72 characters. Never write a bare#Nunless it references a real GitHub issue. - No emojis in files unless asked.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

