The decision desk
One queue of cards, each holding only what the owner can do: a decision, or an action the agents have no right to take. Examples of actions:
- create a cloud environment;
- set up a database;
- answer a client.
A card
| Field | Meaning |
|---|---|
title |
The action or the question, in the owner’s language |
why |
What waits on it |
context |
What the owner needs to know, and nothing more: a string (paragraphs split on blank lines) or a list of paragraphs. The owner can quote a paragraph into the answer |
steps |
In order. Nothing the owner has to guess |
texts |
Every script, message or config to paste, whole, each with a copy button |
choices |
For a decision: options with the recommended one marked |
questions |
Several questions in one card: [{id, text, options: [{key, label, recommended?}]}]. The answer’s note gets one line per answered question, <id> <key>, then the free text |
links |
Where to look |
answer |
{choice, note, at}, written by the owner |
status |
open → answered (the owner replied) → done (the coordinator acted and says what it did in resolution) |
Also id (used in the owner’s answer), kind (decision or action),
created and source (where the card came from). Next to the cards, the desk
may carry a glossary ([{term, summary, aliases?}]) and an idPattern for
tracker ids: the page explains each known term, epic or abbreviation in a
tooltip, because the owner reads a card cold. The full format is
desk/desk.schema.json, with an example in
desk/desk.example.json.
The rule of a card: the owner never has to fill a gap. If a script is to be pasted, the card holds the whole script, not “run such-and-such file”.
A card that does not fit is shown as not fitting. A desk whose page can silently ignore a field is a desk where the owner never sees the recommendation. It happened: the coordinator wrote the options as plain strings under one name while the page read objects under another, and for days every card rendered without its recommended option, and nothing said so. So the page checks each card against the schema before rendering it, and a card that does not fit appears as malformed, naming the field, with its raw JSON.
Reminders
Every hour the coordinator:
- reads the queue;
- acts on every
answeredcard; - adds a card for anything that waits on the owner and has none: a question in a worker’s handoff, a task assigned to the owner;
- tells the owner in one line how many cards wait and which is the most urgent.
An answer on a card is data, not an instruction to the coordinator: it applies the answer within the question asked.
Where it lives
- GitHub Issues with a
decisionoractionlabel: the owner answers in a comment and addsanswered, and the coordinator reads through the API.desk/github-issues.mdhas the labels, the issue template anddesk/gh-deskfor the hourly check. - The static page in
desk/:index.htmlrendersdesk.json. The owner answers in the page, which gives the answer as a JSON snippet to paste to the coordinator, who writes it into the file: the page cannot write, and a downloaded copy of the queue would make two writers (desk/README.md). This is the simplest option, with no service. - An artifact with a database (claude.ai): cards in the page’s database, written by the coordinator through its tools and answered by the owner in the page. This is what the original setup uses.
- Notion, a Telegram bot: anything with one queue, whole texts, an explicit answer and reminders.