This is the full developer documentation for Docket # Docs > How to connect a coding agent to Docket, how the board works, and what Docket stores. Docket is a task board your coding agent works from. These pages say how to set it up, how it decides what your agent does next, and exactly what it keeps. * **Starting out?** The [quickstart](/docs/quickstart/) takes you from signing in to an agent finishing its first card. * **Want to know how it works?** [Concepts](/docs/concepts/) covers cards, the order they are done in, claims, and what happens when two cards touch the same file. * **Looking for a tool’s exact arguments?** The [tool reference](/docs/reference/) lists every tool with the description your agent is given. * **Something was refused?** [Troubleshooting](/docs/troubleshooting/) starts from the message you saw. * **Need to know what leaves your machine?** [Security and data](/docs/security/) lists every field. If you are an agent reading this for someone: the whole of these docs is at [/llms-full.txt](/llms-full.txt) as plain Markdown. # How Docket works > The board, the adapter and the loop your agent runs. Docket has two parts. The **board** is at app.usedocket.dev: it holds your cards and shows what has happened to them. The **adapter** is a small program your coding agent’s client runs on your machine. It gives the agent a set of tools for reading and changing the board, and it is the only part that looks at your repository. Docket does not run your agent, and it never changes your code. Your agent does the work with its own tools; Docket tells it what to work on and keeps the record. ## The loop [Section titled “The loop”](#the-loop) 1. **Cards go on the board.** You write them, or you tell your agent what needs doing and it writes them. A card says what done looks like. See [Cards](/docs/concepts/cards/). 2. **The agent claims the next card.** It calls [`claim_next`](/docs/reference/#claim_next) and is handed the next card that is ready, with a brief: the goal, the constraints, the files it may change, notes from the work it builds on, and the command that says when it is finished. See [What is next](/docs/concepts/ordering/). 3. **It does the work**, in your repository, as it would any other task. 4. **It finishes the card.** It runs the card’s command and reports the result with [`finish_card`](/docs/reference/#finish_card), leaving notes for whoever picks up the cards that depend on this one. 5. **You review and merge.** A finished card is a proposal. The board notices when its work reaches your main branch. See [The life of a card](/docs/concepts/lifecycle/). Then it claims the next one. ## Projects [Section titled “Projects”](#projects) A project is one repository’s board. Docket finds it from the repository’s remote: the first time an agent connects from a checkout, a project is made for it, and every other checkout of the same repository lands on the same project. Each project has a short key taken from the first letters of the repository’s name, and its cards are numbered under it: a repository called `billing-api` has cards `BIL-1`, `BIL-2` and so on. In a directory that is not a git repository, or one with no remote, the adapter still works. Its cards go to a single default project, and anything that depends on git (noticing a merge, the list of files a card changed) is left out. ## In this section [Section titled “In this section”](#in-this-section) * [Cards](/docs/concepts/cards/): what a card holds, and what makes a good one. * [The life of a card](/docs/concepts/lifecycle/): claims, the claim token, and why done is not merged. * [What is next](/docs/concepts/ordering/): how the next card is chosen. * [Scope and collisions](/docs/concepts/scope/): keeping two agents out of the same file. * [Versions and features](/docs/concepts/features/): grouping cards. * [Git rules](/docs/concepts/git-rules/): what a project can require of an agent’s branch and pull request. # Cards > What a card holds, and what makes one an agent can finish. A card is one piece of work: small enough for one agent to finish in one sitting and for you to review in one pull request. Everything an agent is told about the work comes from the card, so a card that leaves something out leaves the agent to decide it. ## What a card holds [Section titled “What a card holds”](#what-a-card-holds) | Field | What it is for | | ------------------ | ------------------------------------------------------------------- | | Title | A short name for the work. The only field a card must have. | | Goal | What done looks like, in a sentence or two. | | Constraints | The decisions already made: what to follow, what to avoid. | | Scope | The files the work may change, and the functions or types involved. | | Acceptance command | A command that exits zero when the card is done. | | Depends on | The cards that have to be finished first. | | Version | A label, such as `1.0`, for the release the card belongs to. | | Feature | The group of cards it ships with. | The arguments themselves are in the tool reference: [`create_card`](/docs/reference/#create_card) and [`update_card`](/docs/reference/#update_card). ## What a good card looks like [Section titled “What a good card looks like”](#what-a-good-card-looks-like) | Field | An example | | ------------------ | ----------------------------------------------------------------------------------------------------------------------- | | Title | Prorate a seat added in the middle of a cycle | | Goal | Adding a member mid-cycle charges only for the days left. | | Constraints | Use the existing `Money` type; never floats. Round half up, once, at the end. Do not touch how a full cycle is charged. | | Scope | `app/billing/proration.ts`, `app/billing/proration.test.ts` | | Acceptance command | `npm test -- billing/proration` | | Depends on | `APP-214` | * **The goal is an outcome, not a list of steps.** The agent works out the steps; it cannot work out what you meant. * **The constraints are the things it would otherwise decide again.** A library to use, an approach that was already tried and failed, a part of the code to leave alone. This is where most of a card’s value is. * **The scope names exact files where you can.** An exact path is what Docket uses to keep two cards out of the same file. A pattern like `app/billing/**` still tells the agent where its edges are, but is not compared with other cards. See [Scope and collisions](/docs/concepts/scope/). * **The command really can fail.** `npm test -- billing/proration` says something when it passes. `true` does not. * **Dependencies are written down.** A card that needs another one first stays off the list of ready cards until that one is finished, so the order does not depend on anybody remembering it. ## Changing and deleting [Section titled “Changing and deleting”](#changing-and-deleting) A card’s fields can be changed at any time with [`update_card`](/docs/reference/#update_card) or from the board. Its status is not one of them: a card moves between states by being claimed, finished or released. Dependencies are added and removed with [`link_cards`](/docs/reference/#link_cards) and [`unlink_cards`](/docs/reference/#unlink_cards). [`delete_card`](/docs/reference/#delete_card) refuses to delete a card that others depend on. It can be told to delete it anyway, which leaves those cards [orphaned](/docs/concepts/lifecycle/#orphaned). The board can also delete a card together with everything that depends on it; an agent cannot. A deleted card disappears from the board, but it is hidden, not erased. It stays in the database, with its history, until the account is deleted. See [Security and data](/docs/security/). # Versions and features > Two ways of grouping cards, and what each one changes. ## Versions [Section titled “Versions”](#versions) A version is a label on a card, such as `1.0`. It is only a label: there is no list of versions to keep, and no dates. It does three things: * [`list_cards`](/docs/reference/#list_cards) and [`claim_next`](/docs/reference/#claim_next) can be narrowed to one version. * Ready cards are handed out by version first. See [What is next](/docs/concepts/ordering/). * The board groups the cards that are to do under their version. A leading `v` is dropped, so `v1.0` and `1.0` are the same label. ## Features [Section titled “Features”](#features) A feature is a named group of cards that ship together, finer than a version. You make one with [`create_feature`](/docs/reference/#create_feature) or from the board, and put a card on it when the card is made or later. A card is on one feature or none. [`list_features`](/docs/reference/#list_features) shows each feature with how many of its cards are done. ## Feature branches [Section titled “Feature branches”](#feature-branches) By default a feature is a label and nothing more: every card is cut from your main branch and proposed back to it. A project can instead give each feature a branch of its own, such as `feature/billing`. Then: * A card on the feature is cut from the feature’s branch, and its pull request goes into that branch. * A card is tracked as merged into the feature’s branch separately from merged into main. A card that waits on another for the same file is let through when that work reaches its own base or main, whichever comes first. * When the feature’s cards are done and merged into its branch, the feature is proposed to main as one pull request. This keeps a run of related cards out of main until they are ready together. Like the other git rules, it is a setting of the project with no control on the board yet. See [Git rules](/docs/concepts/git-rules/). # Git rules > What a project can require of an agent's branch, push and pull request. Docket never touches your repository. What it can do is state a rule, let your agent do the work with its own tools, and check the result. A rule that is not met is refused, with what is missing. ## A new project has none [Section titled “A new project has none”](#a-new-project-has-none) Out of the box there are no git rules. An agent can work on whatever branch it is on, and can finish a card without pushing anything. One thing is asked of it in every project, by the description of `finish_card` itself: a `Card-Id` trailer on its commits, which is how the board comes to know the work was merged. It is asked for, not checked. See [The life of a card](/docs/concepts/lifecycle/#why-done-is-not-merged). ## What a project can turn on [Section titled “What a project can turn on”](#what-a-project-can-turn-on) | Rule | What it requires | When it is checked | | ----------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------- | | A branch for each card | Work happens on a branch named for the card, `card/APP-215` by default, not on main. | When the card is finished. | | A worktree | The agent works in a git worktree of its own, not in the main checkout. For several agents on one repository. | When the card is claimed. | | Pushed before finishing | The card’s branch is on the remote. | When the card is finished. | | A pull request | A pull request exists for the branch. | When the card is finished. | | Feature branches | A card on a feature is cut from, and proposed to, the feature’s branch. | When the card is finished. | A project can also name its own commands for starting a card and for shipping one. The brief then gives the agent that one command in place of the separate git steps. The adapter does the looking: it reads the branch, asks the remote whether the branch is there, and asks GitHub’s command-line tool for the pull request. What it reads is recorded as verified, apart from what the agent reports. ## With everything on [Section titled “With everything on”](#with-everything-on) This is how Docket’s own project runs. An agent is started in a worktree made for the card. It claims the card, works on the card’s branch, pushes, opens a pull request, and only then can finish. Finishing is refused, with the missing step named, until all of that is true. A person merges. ## Turning them on [Section titled “Turning them on”](#turning-them-on) The rules are settings of the project. There is no control for them on the board or among the tools yet. ## In a worktree [Section titled “In a worktree”](#in-a-worktree) The adapter is started by your client in one directory and reads git from there. An agent working in a worktree is somewhere else, so it has to say where: `claim_next`, `finish_card`, `claim_files` and `add_note` take a `workdir` argument, the path of the directory the agent is working in. See [Troubleshooting](/docs/troubleshooting/#working-in-a-worktree). # The life of a card > To do, doing, done and merged; claims and the claim token; and why done is not merged. A card is in one of these states. | State | What it means | | -------- | ----------------------------------------------------------- | | To do | Waiting. It may or may not be ready to start. | | Doing | An agent has claimed it and is working on it. | | Done | The agent has finished and reported. | | Orphaned | It depends on a card that was deleted, and needs repairing. | **Merged** is not a state. It is a fact the board learns about a card that is done, and it is the one that matters most. More on that below. ## Claiming [Section titled “Claiming”](#claiming) An agent starts a card by claiming it, with [`claim_next`](/docs/reference/#claim_next). A card has one holder: once it is claimed, nobody else can claim it. The claim comes with a **claim token**, a number. The agent has to give it back with every later call about that card: [`add_note`](/docs/reference/#add_note), [`claim_files`](/docs/reference/#claim_files), [`finish_card`](/docs/reference/#finish_card) and [`release_card`](/docs/reference/#release_card). The token is what lets Docket refuse a report from an agent that no longer holds the card. ## The lease [Section titled “The lease”](#the-lease) A claim lasts 30 minutes from the last thing the agent did with it. Leaving a note, taking a file, or any other call that carries the token starts the 30 minutes again, so an agent that is working keeps its card for as long as it works. An agent that has stopped, because it crashed or its session ended, loses the card when the 30 minutes run out. The card goes back to to do and can be claimed again. If the first agent comes back later, its token is refused and it is told to claim again. Three ways a card leaves doing without being finished: * The agent gives it back with [`release_card`](/docs/reference/#release_card) and says why. * The lease runs out. * You take it back from the board, with **Take it back** on the card. In all three the card returns to to do. ## Finishing [Section titled “Finishing”](#finishing) [`finish_card`](/docs/reference/#finish_card) moves the card to done. The agent is expected to have run the card’s acceptance command first and to report what happened, along with notes for whoever works on the cards that depend on this one. Those notes are the handoff: the next agent’s brief includes them. Docket records two kinds of fact with a finish, and keeps them apart: * **Reported** is what the agent said: how the command went, its notes, the files it says it changed. * **Verified** is what the adapter read from git: the branch and the commit, the files git shows as changed, whether the branch has been pushed, and the pull request’s address. The board shows which is which. ## Why done is not merged [Section titled “Why done is not merged”](#why-done-is-not-merged) Done means the agent says it has finished. That is a proposal. Whether the work is any good, and whether it goes into your main branch, is still up to you. So Docket tracks the merge separately. When commits on your main branch carry the card’s reference in a trailer, the card is merged: ```text Prorate a seat added in the middle of a cycle Card-Id: APP-215 ``` The adapter looks for this each time an agent calls `claim_next`, `get_card` or `list_cards`. It reads your checkout’s copy of the main branch, so a merge is seen once that checkout has fetched it. A commit without the trailer cannot be matched to a card, and the card stays “done” with no merge seen. It matters for more than neatness. When two cards change the same file, the second waits for the first to be **merged**, not just done: started any earlier, it would branch from a main branch without the first one’s work. See [Scope and collisions](/docs/concepts/scope/). ## Orphaned [Section titled “Orphaned”](#orphaned) A card becomes orphaned when a card it depends on is deleted. It cannot be claimed until the dependency is dealt with: remove it with [`unlink_cards`](/docs/reference/#unlink_cards), or point the card at different work with [`link_cards`](/docs/reference/#link_cards). It then goes back to to do by itself. `list_cards` with `status: "orphaned"` shows them. Note `list_cards` also accepts a fifth status, `abandoned`. Nothing in Docket sets it yet. # What is next > How Docket chooses the card an agent is given, and why a card may not be ready. When an agent calls [`claim_next`](/docs/reference/#claim_next) with no arguments, it is given the next card that is ready. This page says what ready means and what next means. ## Ready [Section titled “Ready”](#ready) A card is ready when all three of these are true: 1. It is to do: not claimed, not done, not orphaned, not deleted. 2. Every card it depends on has cleared. See below for what clears a dependency. 3. None of the exact files it names is held by a card that is being worked on. See [Scope and collisions](/docs/concepts/scope/). ## Next [Section titled “Next”](#next) Among the cards that are ready, the next one is chosen by: 1. **Version.** Cards with a version label come before cards without one, in the order of the labels. Labels are compared as text, so `1.10` sorts before `1.2`. 2. **Position on the board.** Within a version, the card nearer the top goes first. You set this by dragging cards on the board. Passing `version` to `claim_next` narrows the choice to that label. It does not change the rules. Passing `card` claims that card, if it is ready. Naming a card does not let an agent jump its dependencies: a card that is not ready is refused, with the reason. ## Dependencies [Section titled “Dependencies”](#dependencies) There are two kinds, and they clear at different moments. * **Declared.** You or an agent said one card needs another, with `depends_on` when the card was made or with [`link_cards`](/docs/reference/#link_cards) later. It clears when the other card is **done**. * **Added by Docket.** Docket ordered one card after another because both change the same file. It clears when the other card is done **and merged**. See [Scope and collisions](/docs/concepts/scope/). Either kind is removed with [`unlink_cards`](/docs/reference/#unlink_cards). An order Docket added and you removed is not added again. ## Two agents at once [Section titled “Two agents at once”](#two-agents-at-once) Two agents asking at the same moment get two different cards. Claims within a project are made one at a time, so the second is decided after the first has taken its card and its files. ## When nothing is ready [Section titled “When nothing is ready”](#when-nothing-is-ready) `claim_next` says so, and says why: ```text no cards ready: 2 blocked on dependencies, 1 waiting on files held elsewhere, 0 orphaned and needing repair, 1 in progress ``` The four numbers are the cards waiting on an unfinished dependency, the cards waiting on a file another card holds, the orphaned cards, and the cards being worked on. A card waiting on both a dependency and a file is counted once, as waiting on the dependency. What to do about each is in [Troubleshooting](/docs/troubleshooting/#no-cards-ready). # Scope and collisions > How a card's files keep two agents out of each other's way. A card’s scope is the list of files its work may change. It does two jobs: it tells the agent where its edges are, and it lets Docket keep two cards from changing the same file at the same time. ## Scope is a boundary [Section titled “Scope is a boundary”](#scope-is-a-boundary) The brief an agent is given lists the card’s scope and says what to do when the work needs a file that is not on it: ask for the file first, then edit it. Asking is [`claim_files`](/docs/reference/#claim_files). `claim_files` takes exact file paths. If no other card being worked on holds them, they are added to the card’s scope and the agent carries on. If one does, the agent is told which card and can wait, or make its card depend on that one. The point of asking before editing is that backing out is still free. When a card is finished, Docket compares the files git shows as changed with the files the card held. Files that were changed and never held are recorded on the card. ## Exact paths and patterns [Section titled “Exact paths and patterns”](#exact-paths-and-patterns) A scope entry is either an exact path, such as `app/billing/proration.ts`, or a pattern with a `*` in it, such as `app/billing/**`. Caution Only exact paths are compared between cards. A pattern tells the agent its boundary, but Docket cannot list the files it matches, so a card whose scope is only patterns is never held back by another card’s files and never holds another card back. Name the files you know the work will change. Use a pattern for the rest. ## Two cards, one file [Section titled “Two cards, one file”](#two-cards-one-file) Two rules apply, and both are on for a new project. **A file being worked on is held.** While a card is being done, the exact files in its scope are held. Another card that names one of them is not ready, and a claim on it is refused with the name of the card that holds the file. **Cards that share a file are put in order.** Whenever a card’s files change (when it is made, when its scope is edited, when it takes a file with `claim_files`, and when it finishes) Docket looks for other cards that name one of the same exact files. If one of the two has been started, the other is made to depend on it, and waits until it is done and merged. The card that starts first goes first. Two cards that have not started are not ordered against each other, since nothing can collide yet. The agent is told each time this happens, with the cards and the files, and how to undo it. Why merged, and not just done: the second card branches from your main branch. If the first one’s pull request is still open, the second would start from code that does not have the first one’s changes, and the conflict would only show up at the merge. Once a card is done, the files it holds are the ones git shows it changed, not the ones it predicted. If an order is wrong, [`unlink_cards`](/docs/reference/#unlink_cards) removes it and Docket does not add it back. ## Turning the rules off [Section titled “Turning the rules off”](#turning-the-rules-off) Both rules are settings of the project. There is no control for them on the board or among the tools yet. # Quickstart > From signing in to your coding agent finishing its first card. This takes you from nothing to your coding agent finishing its first card. You need a GitHub account, Node.js 18 or later, git, and one of Claude Code, Cursor or Codex. ## Sign in [Section titled “Sign in”](#sign-in) Go to [app.usedocket.dev](https://app.usedocket.dev) and press **Continue with GitHub**. Docket asks GitHub for `read:user` only: your public profile. It never asks for access to a repository. See [What GitHub is asked for](/docs/security/#what-github-is-asked-for). ## Copy your key [Section titled “Copy your key”](#copy-your-key) The first time you sign in, you land on **Connect an agent**, and your first API key is made there. It starts with `dk_`. The key is shown once. Docket keeps only a hash of it, so it cannot show you the key again: copy it before you leave the page. The page has already put it in the command for your client, below the key. If you lose it, make a new one on the [keys page](https://app.usedocket.dev/keys). ## Add Docket to your agent [Section titled “Add Docket to your agent”](#add-docket-to-your-agent) Your client runs Docket’s adapter, `@usedocket/mcp`, on your machine with `npx`; the first start downloads it. The key goes in your client’s settings. Below, put your key where it says `dk_your_key`. These are the commands the app gives you, so you can copy them from either place. ### Claude Code [Section titled “Claude Code”](#claude-code) Run this in a terminal. Then run `/mcp` in Claude Code, or restart it. ```sh claude mcp add docket --scope user -e DOCKET_API_KEY=dk_your_key -- npx -y @usedocket/mcp@latest ``` `--scope user` adds Docket to Claude Code everywhere, not only in the directory you run the command in. ### Cursor [Section titled “Cursor”](#cursor) Put this in `~/.cursor/mcp.json` (make the file if it is not there), then restart Cursor. If the file already has an `mcpServers` block, add the `docket` entry to it. ```json { "mcpServers": { "docket": { "command": "npx", "args": [ "-y", "@usedocket/mcp@latest" ], "env": { "DOCKET_API_KEY": "dk_your_key" } } } } ``` ### Codex [Section titled “Codex”](#codex) Run this in a terminal, then start Codex again. ```sh codex mcp add docket --env DOCKET_API_KEY=dk_your_key -- npx -y @usedocket/mcp@latest ``` ## Start it in your repository [Section titled “Start it in your repository”](#start-it-in-your-repository) The adapter reads git from the directory your client starts it in, and that decides which board you get. Start your agent in a repository that has a remote, such as one on GitHub. Docket makes a project for it on the first call, named after the repository: one called `hello-docket` gets the key `HEL`, and its cards are `HEL-1`, `HEL-2` and so on. In a directory with no remote, Docket still works, but the cards go to a project called **Default**, and the board can never see their work merged. See [Outside a git repository](/docs/troubleshooting/#outside-a-git-repository). A new project has no git rules: your agent can work on the branch it is on and finish a card without pushing. See [Git rules](/docs/concepts/git-rules/). ## Give it its first card [Section titled “Give it its first card”](#give-it-its-first-card) Ask your agent: > “Create a Docket card called Hello, then list my cards.” It calls `create_card`, then `list_cards`, and is told: ```text Created HEL-1 — Hello. ``` ```text HEL-1 todo Hello ``` The **Connect an agent** page notices by itself and says **Connected**, naming the project. There is nothing to reload. Then ask it to do the card: > “Claim the next Docket card and finish it.” It calls `claim_next` and is handed the card’s brief. A card that is only a title has a short one: the title, the branch and commit the work starts from, and a claim number, which the agent passes back when it finishes. ```text # HEL-1 — Hello --- claim 3 · branch main · base ab59486 · lease until 09:11Z Pass claim_id 3 to finish_card or release_card. The lease extends automatically while you leave notes. ``` It does the work, then calls `finish_card` and is told `HEL-1 is done.` ## What success looks like [Section titled “What success looks like”](#what-success-looks-like) On the [board](https://app.usedocket.dev/board), your repository is under **Projects**, and the card is under **Recently finished**. Ask the agent to list your cards again and it will say: ```text HEL-1 done Hello — merge not seen ``` Done is not merged. A finished card is a proposal, and the board counts it merged once a commit carrying `Card-Id: HEL-1` is on your remote’s main branch, as your checkout last saw it: after you push main, or pull once its pull request is merged. The agent is asked to put that line in its commits. A card whose work changed nothing has no such commit, and keeps “merge not seen”. See [Why done is not merged](/docs/concepts/lifecycle/#why-done-is-not-merged). ## Next [Section titled “Next”](#next) * [Cards](/docs/concepts/cards/): what to put on a card so your agent does the right thing. * [What is next](/docs/concepts/ordering/): how the next card is chosen. * [Troubleshooting](/docs/troubleshooting/): what each refusal means. # Tool reference > Every tool the Docket adapter gives your agent, with the description your agent is given. Your agent works with Docket through 14 tools. Each is listed here with the description and the arguments your agent is given for it, word for word: this page is generated from the adapter’s own definitions every time the site is built, and nothing on it below this point is written by hand. It describes `@usedocket/mcp` 0.1.0. ## `claim_next` [Section titled “claim_next”](#claim_next) **Claim the next card** Claim a card to work on and receive everything needed to start: goal, constraints, files in scope, the acceptance command, handoff notes from the work it depends on, and what it unblocks. Call this before starting any work. With no arguments it takes the next ready card in priority order. Pass `card` to claim a specific one — that still respects dependencies, so a card whose prerequisites are unfinished is refused with an explanation. Keep the claim token from the response: finish_card, release_card and add_note all require it. **Arguments** * `card` (string, optional): Claim this specific card, e.g. "DKT-14". Omit to take the next ready one. * `version` (string, optional): Only consider this version label, e.g. "1.0". * `workdir` (string, optional): Absolute path you are working in. Required if you are in a git worktree — Docket reads git from where it was started, which is not where you are. ## `get_card` [Section titled “get_card”](#get_card) **Read a card** Read a card's full brief without claiming it. Same content claim_next returns — use this to check what a card involves before deciding, or to re-read the brief for work already in progress. **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". ## `list_cards` [Section titled “list_cards”](#list_cards) **List cards** One line per card: reference, status, title, and either who holds it or what it is waiting on. Use it to see the shape of the board. To find what to work on next, call claim_next instead — it applies priority and dependency order for you. **Arguments** * `status` (one of `todo`, `doing`, `done`, `abandoned`, `orphaned`, optional): Filter by status. `orphaned` lists cards whose dependency was deleted or abandoned and which need repair. * `version` (string, optional): Filter by version label. * `feature` (string, optional): Only cards on this feature, by slug. ## `create_card` [Section titled “create_card”](#create_card) **Create a card** Record work that needs doing. Use it when you discover something out of scope for the card you are on — write it down rather than widening the current task. A good card states the goal in a sentence and names its constraints. `depends_on` is what makes ordering work: list the cards that must finish first and this one stays off the board until they do. `acceptance_command` is how anyone knows it is done — a command that exits zero. **Arguments** * `title` (string, required): Short imperative summary. * `goal` (string, optional): What done looks like, in a sentence or two. * `constraints` (string, optional): Decisions the implementer must respect: approaches to avoid, patterns to follow. * `depends_on` (list of strings, optional): Card references that must be done first, e.g. \["DKT-3"]. * `scope_globs` (list of strings, optional): File globs this work should touch. * `scope_symbols` (list of strings, optional): Function or type names involved. * `acceptance_command` (string, optional): Command that exits zero when the card is done. * `version` (string, optional): Version label, e.g. "1.0". * `feature` (string, optional): Feature slug, e.g. "billing". ## `update_card` [Section titled “update_card”](#update_card) **Update a card** Change a card's fields. Status is not a field here — claim_next, finish_card and release_card move cards between states, because each transition needs different information. Pass null to clear an optional field. **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". * `title` (string, optional) * `goal` (string or null, optional) * `constraints` (string or null, optional) * `acceptance_command` (string or null, optional) * `scope_globs` (list of strings, optional) * `scope_symbols` (list of strings, optional) * `version` (string or null, optional) * `feature` (string or null, optional): Feature slug; null takes the card off its feature. ## `create_feature` [Section titled “create_feature”](#create_feature) **Create a feature** Group cards that ship together, more finely than a version label. Create it once, then put cards on it with `feature` on create_card or update_card. The slug is derived from the name when omitted. It may later name a branch, so keep it short. **Arguments** * `name` (string, required): What the feature is called, e.g. "Billing". * `slug` (string, optional): Lowercase letters, digits and hyphens, e.g. "billing". * `description` (string, optional) ## `list_features` [Section titled “list_features”](#list_features) **List features** One line per feature: slug, name and how many of its cards are done. Use it to find a slug or to see how close a feature is to shipping; list_cards with `feature` shows the cards themselves. **Arguments** None. ## `link_cards` [Section titled “link_cards”](#link_cards) **Add a dependency** Make a card depend on other cards that already exist. Use it when an ordering constraint turns up after the plan was written: the card you are holding needs work that has not happened yet, or two cards would edit the same files and one has to go first. Write the edge down rather than leaving the order as prose in the constraints, where nothing enforces it. Adding an edge takes the card off the board until its new dependencies are done. A cycle is refused. Safe to re-run — an edge that is already there is left alone. **Arguments** * `card` (string, required): The card that should wait, e.g. "DKT-14". * `depends_on` (list of strings, required): Cards it should wait for, e.g. \["DKT-3"]. ## `unlink_cards` [Section titled “unlink_cards”](#unlink_cards) **Remove a dependency** Remove dependencies from a card. This is how an orphaned card is repaired. A card whose dependency was deleted or abandoned cannot be claimed until that dead edge is gone; `list_cards(status: "orphaned")` lists them and claim_next names the edge. Removing the last dead one puts the card back on the board. Also how to undo an ordering decision that turned out to be wrong. Safe to re-run. **Arguments** * `card` (string, required): The card to free up, e.g. "DKT-14". * `depends_on` (list of strings, required): Dependencies to drop, e.g. \["DKT-3"]. Deleted cards can be named here. ## `finish_card` [Section titled “finish_card”](#finish_card) **Finish a card** Report a card complete. Run its acceptance command first and report the real result — a failure recorded honestly is more useful than a pass that was never run. `notes` is the handoff: the next agent picking up a dependent card sees it and nothing else of your session. Write what they would otherwise have to rediscover — decisions you made, approaches that failed, anything surprising. Skipping it leaves them a file list. Add a `Card-Id: ` trailer to your commits and the work links itself; commit before finishing so the link points at something. If the project requires a branch, push, or pull request, this call checks for them and tells you what is missing rather than recording the card done. The brief lists those requirements under "Before you finish". **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". * `claim_id` (integer, required): The claim token returned by claim_next. Required — a stale or missing token is rejected. * `workdir` (string, optional): Absolute path you are working in. Required if you are in a git worktree — Docket reads git from where it was started, which is not where you are. * `notes` (string, optional): Handoff for whoever picks up the dependent cards. * `files_changed` (list of strings, optional): Paths you changed. * `acceptance` (string, optional): Result of the acceptance command — what actually happened when you ran it. ## `claim_files` [Section titled “claim_files”](#claim_files) **Take more files** Take files for the card you are holding, so no other agent can edit them while you work. CALL THIS BEFORE YOU EDIT a file the brief did not list — not afterwards. If another card in flight is holding it you are told which one and how long its lease has left, and at that point backing out is free: you can wait, or make this card depend on that one with link_cards. Once you have edited it there is nothing left to decide. Literal file paths, not globs. Taking a file also adds it to the card's declared scope, so the board ends up recording what the work really touched. Safe to re-run, and it extends your lease. **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". * `claim_id` (integer, required): The claim token returned by claim_next. Required — a stale or missing token is rejected. * `paths` (list of strings, required): Files you are about to edit, e.g. \["apps/web/lib/db.ts"]. * `workdir` (string, optional): Absolute path you are working in. Required if you are in a git worktree — Docket reads git from where it was started, which is not where you are. ## `add_note` [Section titled “add_note”](#add_note) **Leave a note** Record progress mid-task: a decision, a blocker, something you learned. Also extends your lease, so a long task does not get reclaimed while you are still on it. **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". * `claim_id` (integer, required): The claim token returned by claim_next. Required — a stale or missing token is rejected. * `note` (string, required) * `workdir` (string, optional): Absolute path you are working in. Required if you are in a git worktree — Docket reads git from where it was started, which is not where you are. ## `release_card` [Section titled “release_card”](#release_card) **Release a card** Give a card back without finishing it. Use this when you are blocked or the task turned out to be wrong — it returns to the board for someone else. Say why in `reason`; it is recorded on the card. **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". * `claim_id` (integer, required): The claim token returned by claim_next. Required — a stale or missing token is rejected. * `reason` (string, optional): Why you are handing it back. ## `delete_card` [Section titled “delete_card”](#delete_card) **Delete a card** Remove a card that should not exist — a duplicate, or work that is no longer wanted. Prefer release_card if you merely cannot do it, and abandon rather than delete if the work was considered and rejected; the record is worth keeping. Default mode `block` refuses when other cards depend on this one. `orphan` deletes anyway and marks those dependents as needing repair. Cascade deletion is not available here — it is a human decision made in the web app. **Arguments** * `card` (string, required): Card reference, e.g. "DKT-14". * `mode` (one of `block`, `orphan`, optional): block (default) refuses if anything depends on this card; orphan deletes and flags them. # Security and data > Everything that leaves your machine, everything Docket stores, and what deleting removes. The short version: the adapter runs on your machine and reads git there. The server is told what happened and never touches your repository. Docket is never sent the contents of a file. This page is the long version. It lists every field. ## What leaves your machine [Section titled “What leaves your machine”](#what-leaves-your-machine) The adapter, `@usedocket/mcp`, is the only part of Docket that runs on your machine. It sends something only when your agent calls one of its tools. Every call carries three things. **1. What your agent wrote.** The tool’s arguments, exactly as the agent gave them: a card’s title, goal, constraints, scope and acceptance command, a note, a report. The [tool reference](/docs/reference/) lists every argument of every tool. If the agent passes `workdir`, the path of the folder it is working in, that path is sent too. **2. Seven facts about the repository**, read from git in the directory the adapter was started in, or in `workdir`: | Field | What it is | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `remote` | The address of the `origin` remote, reduced to host, owner and name: `github.com/acme/billing-api`. A user name or password in the address is removed before it is sent. | | `owner` | The owner part of that address. | | `repo` | The name part of that address. | | `head` | The id of the commit that is checked out. | | `branch` | The name of the branch that is checked out. | | `dirty` | Whether there are uncommitted changes: yes or no. | | `in_worktree` | Whether the directory is a git worktree: yes or no. | Nothing else about the directory can be sent. The adapter keeps a fixed list of these seven and drops everything that is not on it. **3. A label for the agent**: the name of your client and four random characters, such as `claude-code-3fa9`. It is how the board says who holds a card. Two tools add more. **When a card is claimed**, the commit id and branch are recorded as where the work started. **When a card is finished**, the adapter reads these from git and sends them, so that the report does not rest on the agent’s word alone: | Field | What it is | | ------------------- | ----------------------------------------------------------------------------------------------------------------------- | | `tip_sha` | The id of the last commit of the work. | | `base_sha` | The id of the commit the work started from. | | `branch` | The branch the work is on. | | `dirty` | Whether there are uncommitted changes. | | `pushed` | Whether the branch is on the remote. | | `files_changed` | The names of the files that changed between those two commits. Names only. | | `card_trailers` | The card references found in `Card-Id` trailers on those commits. | | `pr_url`, `pr_base` | The address of the pull request and the branch it targets, if GitHub’s command-line tool is installed and there is one. | | `default_branch` | The name of the repository’s main branch. | | `workdir` | The folder’s path, when the agent gave one. | **Before `claim_next`, `get_card` and `list_cards`**, the adapter checks whether finished cards have been merged. For each one it finds on a branch, it sends the card’s reference, the id of the commit whose trailer names it, the branch’s name and the id of the branch’s last commit. ### What is not sent [Section titled “What is not sent”](#what-is-not-sent) * **The contents of any file, or any diff.** The adapter runs `git diff --name-only`: it asks git for names. * **Commit messages.** The adapter reads them on your machine, looking for `Card-Id` trailers. Only the card references it finds and the commit ids leave. * **The output of the acceptance command.** The adapter never runs it. Your agent runs it and says how it went, in its own words. * **Your prompts, your agent’s replies, and your model provider’s key.** The adapter is given tool calls and nothing else. * **Environment variables**, other than its own key, which it sends to prove who is calling. What your agent writes is kept as written Card text, notes and finish reports are your agent’s own words, and Docket stores them unchanged. If the agent pastes code, a secret or a command’s output into one, that is in the log. Docket does not look for such things or remove them. ## What GitHub is asked for [Section titled “What GitHub is asked for”](#what-github-is-asked-for) Signing in asks GitHub for one scope, `read:user`: your public profile. Docket reads your GitHub user id, your login and your public email address if you have set one. Docket never asks for access to a repository, public or private. It does not keep the token GitHub issues: the token is used once, to read the profile, and discarded. ## What Docket stores [Section titled “What Docket stores”](#what-docket-stores) Everything is in one database. In plain words, table by table: | Kept | What is in it | | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Your account | Your GitHub user id, login and public email, which plan the account is on, and when you joined. | | API keys | For each key: a hash of it, its first eight characters so you can tell keys apart, its label, when it was made, when it was last used (to within five minutes) and when it was deleted. Never the key. | | Projects | For each repository: a name and short key, the repository’s address, owner and name as above, a counter for numbering cards, and the project’s settings. | | Cards | Title, goal, constraints, scope (file patterns and symbol names), acceptance command, status, position, version and feature, with the times it was made, changed and deleted. Two further fields are reserved and empty. | | Dependencies | Which card waits on which, who added it (an agent, a person or Docket) and when. | | Files | The exact file paths each card has named or taken. | | Features | Name, short name and description. | | Claims | Which card, the agent’s label, the commit id and branch it started from, when its lease runs out, and how it ended: finished, released or expired. | | The log | One entry for everything that happens to a card: made, changed, linked, unlinked, started, files taken, note left, finished, released, merged, orphaned, deleted, lease expired. Each entry says who did it and when. A note’s entry holds the note. A finish’s entry holds the report and the git facts listed above. | | Housekeeping | A queue of the server’s own recurring jobs, such as expiring leases. | **The log cannot be edited.** The database refuses any change to an entry, and refuses to delete one, with a single exception: deleting your account deletes its log. **Not stored:** your code, the key itself, a GitHub token, and any record of your sessions. A session is a signed cookie in your browser; there is nothing on the server to look up. ## Cookies and browser storage [Section titled “Cookies and browser storage”](#cookies-and-browser-storage) On `app.usedocket.dev`: * A session cookie, signed, lasting 14 days. It is sent only to that address. * A cookie holding your choice of light or dark. * A cookie that lasts ten minutes while you are signing in with GitHub. This site, `usedocket.dev`, sets no cookies. It keeps your choice of light or dark in your browser’s local storage. ## How keys are kept [Section titled “How keys are kept”](#how-keys-are-kept) A key is `dk_` followed by 32 random bytes. It is shown once, when it is made. What is stored is a hash of the key combined with a secret that is held in the application’s configuration and not in the database. Someone who obtained a copy of the database alone could not use, or recover, a single key. Deleting a key stops it working at once. ## How accounts are kept apart [Section titled “How accounts are kept apart”](#how-accounts-are-kept-apart) Every table that holds your data has row-level security switched on and forced, in the database itself. Each request runs in a transaction that names the account it is for, and the database returns and changes only that account’s rows. This does not depend on the application remembering to filter. Requests are limited to 300 a minute for an account. A key that fails to authenticate is limited to ten attempts a minute. ## Deleting [Section titled “Deleting”](#deleting) **A card.** Deleting a card hides it. It stays in the database, with its log, until the account is deleted. **A key.** It stops working at once. Its hash and label stay, marked deleted, until the account is deleted. **Your account.** [Account](https://app.usedocket.dev/account) → Delete account shows a count of what will go and asks you to type your login. It then removes your account and everything under it from the database at once: projects, cards, dependencies, files, features, claims, the whole log and every key. Your keys stop working at that moment. **Backups.** Copies of the database are taken, and a deleted account remains in the copies made before it was deleted. No limit has been set yet on how long those copies are kept. ## Where it runs [Section titled “Where it runs”](#where-it-runs) * The app and its database run on Railway, in the United States. * Sign-in is GitHub’s. * The adapter is downloaded from npm. * This site is served by Cloudflare, which also counts visits to it without cookies. The server’s logs hold errors and, when an account is deleted, the counts of what was removed. Docket does not write card contents or tool calls to its logs as it runs; an error is logged with the message that caused it. ## If something is missing [Section titled “If something is missing”](#if-something-is-missing) If Docket does something with your data that is not written here, that is a fault in this page. # Troubleshooting > What Docket says when it refuses something, why, and what to do. Docket’s refusals are written to be acted on: each says what is wrong and names a way out. This page lists them by the message you or your agent will see. ## The adapter will not start [Section titled “The adapter will not start”](#the-adapter-will-not-start) ### No API key [Section titled “No API key”](#no-api-key) ```text [docket] DOCKET_API_KEY is not set. Get a key at https://app.usedocket.dev and add it to this server's "env" block in your MCP client config. ``` **Why.** The adapter has no key, so it stops before your client can use it. **What to do.** Make a key on the [keys page](https://app.usedocket.dev/keys) and put it in the adapter’s `env` in your client’s configuration. The [quickstart](/docs/quickstart/) has the command for each client. ## Every call is refused [Section titled “Every call is refused”](#every-call-is-refused) ### The key is rejected [Section titled “The key is rejected”](#the-key-is-rejected) ```text Docket rejected the API key. Check DOCKET_API_KEY, or issue a new key at https://app.usedocket.dev/keys ``` **Why.** The key is not one Docket knows: it was mistyped or cut short when pasted, it has been deleted, or the account it belonged to has been deleted. **What to do.** Make a new key and replace the old one in your client’s configuration, then restart the client. A key is shown once, when it is made; Docket keeps no copy it could show you again. ### The adapter is out of date [Section titled “The adapter is out of date”](#the-adapter-is-out-of-date) ```text Your @usedocket/mcp speaks protocol 1; this server needs 2 or later. Update with: npx -y @usedocket/mcp@latest ``` **Why.** The adapter on your machine is older than the server can work with. This happens when a tool the server now relies on did not exist in your version. **What to do.** Restart your client so that `npx -y @usedocket/mcp@latest` fetches the current adapter. If your configuration names a fixed version, change it. ### Too many requests [Section titled “Too many requests”](#too-many-requests) ```text Too many requests: more than 300 a minute for this account. Wait 12 seconds and try again. ``` **Why.** An account may make 300 calls a minute across all its keys, with up to 60 at once. The reply carries a `Retry-After` header with the same number of seconds. **What to do.** Wait that long. An agent in a loop that is calling Docket this often is usually retrying something that will not succeed; read the refusal it is retrying. A second limit applies to a key that does not authenticate: ten attempts a minute, after which that key is told `Too many requests with an API key that has not authenticated.` Fix the key; waiting will not. A refusal that counts calls made today, not in the last minute, is a ceiling: see [A ceiling](#a-ceiling). ### Docket cannot be reached [Section titled “Docket cannot be reached”](#docket-cannot-be-reached) ```text Could not reach Docket at https://app.usedocket.dev. Check your connection. Docket did not respond within 10s. Retry shortly. ``` **Why.** The first is your network, or the server being down. The second is the server being slow. **What to do.** Try again. Nothing was changed by a call that got no answer. ## Over a limit [Section titled “Over a limit”](#over-a-limit) ### Too large [Section titled “Too large”](#too-large) ```text goal is 41 KB; the limit is 32 KB. scope_globs has 240 entries; the limit is 200. That is 70 KB in all; the limit is 64 KB. APP-215 already depends on 200 cards; the limit is 200. This request is over 256 KB, which is the most Docket reads. ``` **Why.** What one call can write is bounded: a field at 32 KB, a list at 200 entries, the dependencies written on one card at 200, and one card, note or report at 64 KB in all. The server reads no request over 256 KB. The message names what was too big, by the argument’s own name. Nothing is written by a call that is refused. The files a finish reports as changed are never refused: a long list is stored shortened. **What to do.** Shorten it. Long material belongs in the repository, with a pointer to it on the card. One glob covers many files, so a long list of paths can usually be a few patterns. For dependencies, depend on the last card of a chain, not on every card in it. ### A ceiling [Section titled “A ceiling”](#a-ceiling) ```text This account holds 10,000 cards, and Pro allows 10,000; deleted ones count until they are removed. Remove old cards at https://app.usedocket.dev/account. Moving to Scale lifts it, on request: https://app.usedocket.dev/billing. This account has made 5,000 calls today, and Pro allows 5,000 a day. Calls are refused until midnight UTC, in 3 h 12 min. Moving to Scale lifts it, on request: https://app.usedocket.dev/billing. ``` **Why.** An account has four ceilings, set by its plan, and the message names the plan and its number: * **Calls a day**, across all its keys. * **Log entries a day**: what its agents and its people write. What Docket writes for itself, such as a lease running out or a merge being seen, is never counted. * **Cards**, every one it holds. Deleted cards count until they are removed. * **Projects in use.** Archived ones do not count. A day is a UTC day. An account that has never subscribed has the Pro plan’s ceilings. A ceiling refuses the write; it never charges for it. On the board, the same sentence appears where you made the change. **What to do.** Your agent is told to pass the message on to you and not to retry. For a day’s ceiling, the count starts again at midnight UTC. For cards, remove old ones on the [account page](https://app.usedocket.dev/account). For projects, archive one on the board. The message also says which plan lifts it. ## Claiming [Section titled “Claiming”](#claiming) ### No cards ready [Section titled “No cards ready”](#no-cards-ready) ```text no cards ready: 2 blocked on dependencies, 1 waiting on files held elsewhere, 0 orphaned and needing repair, 1 in progress ``` **Why.** Nothing on the board can be started right now. The numbers say what each card that is to do is waiting for. **What to do.** It depends on which number is not zero. * **Blocked on dependencies:** finish the cards they depend on. `list_cards` shows what each one waits for. * **Waiting on files held elsewhere:** another card being worked on holds a file. Claim the waiting card by name to be told which file and which card. * **Orphaned:** see [Orphaned](#orphaned) below. * **In progress, and nothing else:** the work is all claimed. Wait, or add a card. If every number is zero, the board is empty or finished: create a card. ### Already claimed [Section titled “Already claimed”](#already-claimed) ```text APP-215 is not claimable: already claimed by another agent ``` **Why.** A card has one holder, and this one has one. **What to do.** Claim a different card. If the agent that holds it has stopped, the card comes back by itself when its lease runs out, 30 minutes after that agent’s last call. You can also take it back at once from the card on the board. See [The life of a card](/docs/concepts/lifecycle/#the-lease). ### Blocked on dependencies [Section titled “Blocked on dependencies”](#blocked-on-dependencies) ```text APP-216 is not claimable: blocked on incomplete dependencies: APP-214, APP-215 ``` **Why.** The card depends on cards that are not done. The message lists them. **What to do.** Do those first; `claim_next` with no arguments will hand them over in order. If the dependency is wrong, remove it with [`unlink_cards`](/docs/reference/#unlink_cards). ### Waiting for a merge [Section titled “Waiting for a merge”](#waiting-for-a-merge) ```text APP-216 is not claimable: waiting for APP-214 to merge. Docket ordered this card after it because both write the same files, and starting before the merge would branch from a base without that work. Once the pull request is merged and this checkout has fetched it, the next claim sees it. If the order is wrong, unlink_cards removes it for good ``` **Why.** Docket put this card after another because both change the same file, and the other one is done but its work is not on your main branch yet. **What to do.** Merge the other card’s pull request, then `git fetch` (or `git pull`) in the checkout your agent is using, and claim again. Docket sees a merge only once that checkout has it, and only if the merged commits carry the card’s `Card-Id` trailer. If the two cards do not really collide, remove the order with `unlink_cards`. ### Files held by another card [Section titled “Files held by another card”](#files-held-by-another-card) ```text APP-216 is not claimable: its files are held by work in flight: ``` **Why.** The card names a file that a card being worked on already holds. The message names the file and the card. **What to do.** Wait for that card to finish. Or, if this card should always follow it, say so with [`link_cards`](/docs/reference/#link_cards), which puts the order on the board. ### Orphaned [Section titled “Orphaned”](#orphaned) ```text APP-217 is not claimable: orphaned — it depends on APP-210 (deleted). Drop that edge with unlink_cards, or re-point the card with link_cards, then claim it again ``` **Why.** A card this one depends on was deleted, so the dependency can never clear. **What to do.** What the message says: remove the dependency with `unlink_cards`, or replace it with `link_cards`. The card returns to to do by itself. ### Working in a worktree [Section titled “Working in a worktree”](#working-in-a-worktree) ```text This project runs one card per worktree, and this session is in the main checkout. Start an agent in its own workspace and claim APP-215 from there: ``` **Why.** The project requires each card to be done in a git worktree of its own, and the adapter was started in the main checkout. Nothing was claimed. **What to do.** Run the command the message gives, and start your agent in the directory it makes. If the agent *is* in a worktree and still sees this, the adapter is reading git from where your client started it, not from where the agent is. Have the agent pass the worktree’s path as `workdir` to `claim_next`, and to `finish_card`, `claim_files` and `add_note` after it. ## While working [Section titled “While working”](#while-working) ### The claim is not valid [Section titled “The claim is not valid”](#the-claim-is-not-valid) ```text claim 66 is not valid for APP-215. It may have expired, been released, or belong to another card — re-claim before reporting. ``` **Why.** The claim token no longer holds the card. Most often the lease ran out: the agent made no call about the card for 30 minutes, and the card went back to to do. **What to do.** Claim the card again with `claim_next` and its name, and use the new token. The work in the repository is untouched. On a long task, leave a note with [`add_note`](/docs/reference/#add_note) now and then: any call with the token starts the 30 minutes again. ### Files cannot be taken yet [Section titled “Files cannot be taken yet”](#files-cannot-be-taken-yet) ```text APP-216 cannot take those files yet: ``` **Why.** `claim_files` was asked for a file that another card being worked on holds. **What to do.** Do not edit the file. Wait for the other card, or make this card depend on it with `link_cards`. This is the moment asking first pays for itself: nothing has been changed that has to be undone. ### A pattern given to claim_files [Section titled “A pattern given to claim_files”](#a-pattern-given-to-claim_files) ```text claim_files takes literal file paths, not globs: ``` **Why.** A path given to `claim_files` had a `*` in it. Docket cannot list the files a pattern matches. **What to do.** Name each file. To widen what the card may touch in general, change its scope with `update_card`. ## Finishing [Section titled “Finishing”](#finishing) ### Finishing is refused [Section titled “Finishing is refused”](#finishing-is-refused) **Why.** The project has [git rules](/docs/concepts/git-rules/) and the work does not meet them yet: it is on the wrong branch, the branch is not pushed, or there is no pull request. The message names each missing step, or the one command the project uses for all of them. **What to do.** Do what it lists, then call `finish_card` again with the same token. ## Deleting [Section titled “Deleting”](#deleting) ### The card has dependents [Section titled “The card has dependents”](#the-card-has-dependents) ```text APP-214 has 2 live dependent(s); use orphan mode to delete anyway ``` **Why.** Other cards depend on the one being deleted. **What to do.** Either re-point or unlink those cards first, or delete with `mode: "orphan"`, which deletes the card and leaves the others [orphaned](/docs/concepts/lifecycle/#orphaned) for you to repair. ### Cascade delete [Section titled “Cascade delete”](#cascade-delete) ```text cascade delete is not permitted on this surface ``` **Why.** Deleting a card together with everything that depends on it is only offered on the board, where a person confirms it. **What to do.** Do it from the board. ## Outside a git repository [Section titled “Outside a git repository”](#outside-a-git-repository) There is no refusal for this. In a directory that is not a git repository, or one with no `origin` remote, the adapter still works, but: * Cards go to a default project and not to one named for a repository. * A finish carries no verified git facts, so the card cannot be seen as merged. * Rules about files still apply, since they come from the card’s scope. If you expected a repository’s own board and got an empty one, check that the client starts the adapter inside that repository. ## The code behind each message [Section titled “The code behind each message”](#the-code-behind-each-message) Refusals from the board carry a code. Your agent sees the message; the code is for telling them apart. | Code | Meaning | | ------- | --------------------------------------------------------------------- | | `DK001` | No card is ready. | | `DK002` | That card cannot be claimed. | | `DK003` | The claim token is stale or wrong. | | `DK004` | The card has dependents and cannot be deleted as asked. | | `DK005` | Cascade delete is not offered here. | | `DK006` | No such card. | | `DK007` | A file is held by another card, or `claim_files` was given a pattern. | | `DK008` | Too large to store: see [Too large](#too-large). | | `DK009` | Over one of the account’s ceilings: see [A ceiling](#a-ceiling). |