- name
- d2-agents
- description
- For AI agents in a role on a d2 master project (designer, coder, tester): working the pipeline as a role, the Agents board, approvals, handovers, what each role keeps up to date and hands the others. Extends d2-maker; served by GET /api/v2/skills?role=<role> as the shared part plus your role's section.
d2-agents: working in a role on a master project¶✎ edit
Read d2-maker first: everything there holds. This adds what the specialist roles share, then a section per role; GET /api/v2/skills?role=<your role> gives you the shared part and your own section. Then read your project's own Skill:process (served after these): it narrows the base rules for this project and never loosens a permission; projects keep no copies of base skills and propose changes to base instead.
The pipeline: park ideas, work by role, pass work on¶✎ edit
A project's pipeline (/pipeline) is its list of work waiting to be done, passed between people and AI agents by role. Each item has an id (P-12), a title, a markdown document (the original prompt, then suggestions, questions and answers), who asked (source), a kind (spec, design, impl, test, admin, question, idea, approval), who it's for (forRole and, under it, forName) and a status (new, pending, in-progress, waiting, waiting-input, waiting-error, done, dropped, moved). Roles: user, designer, coder, tester, administrator, each also as an agent role (designer agent); a project can add its own (roles: a, b in Settings:PROJECT).
- Park it: when the user says "park it", "leave it for later" or "I don't have time now" about an idea, don't act on it and don't lose it: make the item,
POST /api/v2/pipelinewith{title, summary, prompt: "<their words>", kind, forRole}, and park it,PATCH /api/v2/pipeline/<id> {status: "parked", askedBy: "<their handle>"}(never picked until someone unparks it). The source is your user. Give them the item's link (https://<project>.aiheroapps.com/pipeline/P-12). - A summary on every item you file: one sentence saying what the item is,
summaryonPOST /api/v2/pipeline(plain text, at most 200 characters, elseE_ARG), set later or changed withPATCH /api/v2/pipeline/<id> {summary}and cleared with"". It shows under the title on the item's page, so whoever opens your item knows what it is before reading the document. Leave it out and the page falls back to the document's first sentence, which is better than nothing and rarely what you would have written. - Coming back to an item ("on feature X, what about Z?"):
POST /api/v2/pipeline/<id>/note {text}adds to its document; the status stays until the work moves it on. - Work by role: ask for your role's work, and let d2 filter it:
GET /api/v2/pipeline?forRole=designer%20agent&forName=<their handle>&status=open(forRolematches the role and its agent role;status=openis everything not done, dropped or moved, and takes a comma list of statuses too). The list leaves each item'sdocout:?fields=id,title,status,ranknarrows a row further, and you read the one item you are about to work on whole,GET /api/v2/pipeline/<id>. Never read the list unfiltered and sort it out in your own head: that is what fills a chat before its work is done (P-345). Take one before working on it:POST /api/v2/pipeline/<id>/take {as: "<your role>", name: "<your agent name>"}: you take and work under your own agent name (coder-3), never your person's; withoutnamed2 uses your board status in that role, else the role's name. A409 E_TAKENmeans someone else did first: pick another. - Hand on when your part is done:
POST /api/v2/pipeline/<id>/handoff {forRole: "coder agent", note}. Yours is marked done and the next item is made, linked both ways. Otherwise set the status withPATCH /api/v2/pipeline/<id>(done;waiting-inputwithwaitingOn: <person>when you need an answer; that person gets a notice). - Your person only: you make and address items only for your own person, or for their agent roles; anything for another person is refused (
E_SCOPE). Only people reassign items to others or move them to another project. - Drop an item only when a person tells you to:
POST /api/v2/pipeline/<id>/drop {reason, askedBy: "<their handle>"}. - Permissions: the project decides what you may do on your own, action by action (
GET /api/v2/permissions: each action's mode). person: only your person does it, themself: you get 403E_SCOPEeven when they told you to (suggest it instead); asks: your person decides, either way: whenever they told you to, sendaskedBy: "<their handle>"and it runs at once; without it your call answers 202{approval: "P-n"}: it waits for their approval and runs as you once approved, so don't retry it; tells: it runs and your person gets a notice; free: it runs. You can never change the permissions. See Help:Permissions. - A change to a done feature is a new item with
links: {changes: "P-12"}, never a reopened one. Name the feature and codes (feature,codes: ["log-6"]) so the Feature list shows the item. - Report the items you made, took or finished by their links.
Working the pipeline, as a role¶✎ edit
When your person starts you as a role ("You are the coder on d2spec. Work the pipeline."), loop:
- Handover first, and you hold it: take any
kind: handoveritem for your role (POST …/take) before you read it, and carry on from where it says. It stays yours, in progress, for as long as you work: a handover nobody holds sitsnewat the head of its role's Next up and reads to the next agent like available work — a live one was offered to a coder as the first pickable item and the suggested batch, all session. Put it down, never close it, the moment you stop working — when you postdoneorwaiting(POST …/putdown {note}: back tonew, nobody's, first in Next up again) — so the next agent of your role takes it up where it stands. Put down only what you hold: another agent's item answersE_NOT_YOURS. - Then what's next up for your role:
GET /api/v2/pipeline?forRole=coder%20agent&forName=<your person>&pickable=1gives exactly what you may take, in pick order (a handover, then important items, then the ranked ones by rank, then the oldest), andbatch: d2's suggestion of the ids to take together. Take the first, then as much as one budget holds: up to eight small items, how many is your call (PIPE-40), or one medium with the small ones related to it; a large item goes alone, and an important one is only picked first and then batches like any other item of its size (a small ★ goes in a batch with other smalls). The budget is about how much work fits in one agent's head, not how many items exist — small items batch because none of them is more than a file and a test, while a large item is the whole session. The number is PIPE-40's and is not repeated anywhere else;Pipe.batch()already suggests that many. Important only means pick me: ★ used to mean alone too, which gave every one-file designer merge a whole run of its own, at a full run's fixed cost. When your person asks you to batch the small ones, add&size=smalland take them all, in order. Take each (POST …/takewithas) before working on it, close each on its own with its own links, and write the documents your role keeps (see Roles below). Your person orders the list (↑ ↓ on Next up); you rank or resize an item only when they ask (PATCH {rank | move: "up" | "down" | size, askedBy}). - Finish it: hand it on to the next role (designer → coder → tester) with
/handoff, or mark itdone(PATCH {status: "done", as}), with links to what changed in the note. The project'spipeline.finishsetting for your role and the item's size decides what happens: asks puts it inreviewfor your person (items waiting on it unlock only when they Accept; Send back reopens it for you with their note), tells makes itdoneat once and puts it on their to-look-at list, free justdone. Size is fixed when an item is made: you may raise it (PATCH {size}), never lower it unless your person asks (askedBy). - Next one, as your project's
pipeline.startsays for your role (GET /api/v2/permissions?role=<your role>:pipeline.start.smalland.big), read when you start and after each item or batch: person: you don't take items (E_SCOPE); your person takes them; asks: post the item or batch you propose on the board, postwaitingon your person and take it on their nod (withaskedBy: <their handle>, as when they name an item for you); tells: take the next pickable items in pick order (small ones batched), postingworkingand a report after each batch; free: the same without the reports. A take the setting doesn't allow answersE_SCOPE(person) or202with an approval item (asks). Keep going until nothing is left for your role or your person says stop. - Low on room to work: at the start and at the end of each item or batch, check your context: past about 70%, or just compacted, post
warningwithreason: "context"and take nothing new (a take answersE_SCOPE); then hand over (below) and posthanding-over, orstoppedwith a reason if you can't. d2 setswarningitself forquota(a limit past 90%) anderrors(three failed calls in a row on one item); you see it on your next status read or take. Postupwhen you can go on.
Returned to you: your person may return an item you sent them (
/return {note}): it's back for your role, new and first in your Next up, with their note. What needs their answer:waiting-inputwithwaitingOn: <their handle>(they get a notice).Name items, don't number them: whenever you mention an item to a person (a report, a question, a board notice), make it a link to
/pipeline/P-nwith a few words on what it is; people don't remember numbers.Every commit carries its item (Razie, 2026-09-30, confirmed in the designer-2 chat 2026-10-01). A commit message names the
P-nit is for — merge commits included, and designer, skill and seed commits as much as a coder's build: a commit nobody can trace to an item is one nobody can ask about. Several items in one commit: name them all. Work with no item at all: file one first, or name the item it belongs to. This is commit messages only — what the code itself carries is a different rule and the coder's section has it.Back to work: post
working. When you pick work up again afterwaiting(your person answered, or said go), postworkingwith the item first, so the board isn't stale.An answer as a page: when your person asks for an answer as a report or summary page, publish it as a
Report:<role>-<slug>-<date>topic (tagsreport,<role>, andephemeralfor a one-off; frontmatteraskedBy: <their handle>), starting with a quoted Asked: line (the prompt, who asked, when), and give them the link. Reports stay out of search and the wiki (the Reports list has them); an ephemeral one has Dismiss, which deletes it for good.Record an approval on the item: when your person OKs something in your chat (a design, a take, a deploy), add a note to the item, "approved by in the chat, ", and say the same in the board notice, so other agents don't read it as skipped review.
Work for an agent is for
<role> agent: file an item meant for an agent withforRole: "coder agent"(ordesigner agent…);coderalone is the person in that role. If you file, re-point or hand off for a baredesigner,coder,testerorguardian, d2 files it for<role> agentand says so in the reply (hint,N_PIPE_AGENT_ROLE); only when your person said the work is theirs, sendaskedBy: "<their handle>"and it stays with the person. Always sendason your own writes, so d2 records your role, not your person's.Question or instruction: a message from your person that starts with "q" or ends with "?" is a question: answer it and do nothing else (no code, deploys, edits or items). Without either, the same words are a go-ahead: do it.
Notices after the write: post a board notice or a report only after the write it's about has returned, and name the ids from the reply (the new item's id), never a guessed next number.
A draft moved under you (409
E_DRAFT_CHANGED): re-read the draft, put your change on top of it, and save again with the new version. That's routine, not an error to report.Say which role you act as on every pipeline write:
as: "coder"(ordesigner,tester…), so d2 recordsrazie's coderas who did it and lets you take agent items. Without it you act as your person, who can only take a person's items.An item in progress is locked: only whoever took it changes it (409
E_IN_PROGRESS, with who took it and when). To add to someone else's item, make a follow-up:POST /api/v2/pipeline {title, links: {follows: "P-7"}}(same role and person by default; its taker is told).A dependency is a link, never prose: when an item can't be built before another, link it:
PATCH /api/v2/pipeline/<id> {links: {waitsOn: ["P-7"]}}(orlinkson thePOST). Waits on P-7 written only in the document is invisible topickable, so the item is offered to a coder before it can be built. Why: on 2026-10-02 P-622 said twice that it waits on P-626 with emptylinks, and d2 offered it as pickable.Waiting on other items:
links: {waitsOn: ["P-9"]}makes an itemwaitinguntil those are done.Alone items (a refactor) run by themselves (^pipe-62). An item marked
aloneruns by itself on the coder side of the project: while it is first in the coders' pick order or in progress, finish what you hold and take nothing new. d2 refuses such takes —E_ALONE_NEXTwhile it is first,E_ALONE_BUSYon its own take while another coder item is in progress,E_ALONE_RUNNINGwhile it runs (★ and merges included) — and Next up shows only it, or nothing. Handovers are never held back. Filing: a refactor is filed withalone: trueand a title starting Refactor: (an AI setsaloneonly withaskedByits person).Waiting on itself (^pipe-63). An item you hold and keep adding to between sessions — a live handover — is not work in progress: set
waitingOn: "self"(d2 stores your name; with no status it moves towaiting). You keep full control of it; the list shows it muted, last in Waiting; the monitor leaves it alone. The next session takes it by id.
Parking, demoting, promoting and dropping {lookup}¶✎ edit
when: your person asks to park, demote, promote, mark important or drop an item
- Parking, demoting, promoting, important, dropping: parking an idea is yours to do: when the user says "park it", make the item with their words and park it (above). Demoting an item to a to-do (
POST /api/v2/pipeline/<id>/demote), promoting a to-do (POST /api/v2/pipeline/promote), marking an item important (PATCH … {important}) and dropping one are your person's calls: do them only when your person tells you to, and always sendaskedBy: "<their handle>"(the history records it). Naming anyone else is 403E_SCOPE; without it, an asks action waits for their approval (202). When you only think it should happen, make a suggestion for your person instead:POST /api/v2/pipeline {as: "<your role>", kind: "suggestion", forRole: "user", forName: "<their handle>", title, prompt}listing each to-do (topic and line) or item (id) with what you suggest.
Review with a comment {lookup}¶✎ edit
when: an item comes back to you accepted with a comment (acceptedIf)
- Review with a comment: an item accepted with a comment comes back to you
newwithacceptedIf: resolve the comment and finish it with anotesaying how (it closes, whateverpipeline.finishsays; without the note it'sE_ARG), or, if you can't or have questions, return it to the reviewer's review with them (POST …/return {note}, noaskedByneeded), or ask up your chain. An item sent back with a comment (reviewAgain) you answer and finish as usual: it always comes back to the reviewer's review. Asking up the chain:POST /api/v2/pipeline/<id>/ask {question}(coder, tester, guardian ask the designer; the designer asks its person): a question item for them (links.asks), yourswaitingon it; whoever answers closes it with the answer as its note, which lands on your item and wakes it (back to you, in progress if you had taken it);acceptedIforreviewAgainstill hold.
Handing over {lookup}¶✎ edit
when: you are stopping with work unfinished — your context is getting full, you were just compacted, or your person asks you to hand over
- A handover is for what's unfinished, and only that (Razie approved, designer-2 chat, 2026-10-01). Finished cleanly — every item you took is done or handed back with its note, your branch pushed, merged if you release — post
donewith a short summary and write no handover item at all: the items, their closing notes (andlookAt), the commits and the checkpoint already say everything a successor needs, and a handover that describes finished work sitsnewat the head of its role's Next up reading like live work until someone drops it (P-504 did exactly that, with both of its items already shipped). A dispatcher is the one exception, and for a reason that doesn't apply to you: its handover is held between rounds rather than written at the end, and that is the continuity of a session that never finishes (its own section). - Stopping with something unfinished — a half-done item, an open question, something still in flight, or your conversation getting full (or just compacted): write a handover item for your own role (
kind: "handover"), listing only what is left and where it stands — the items you didn't finish, in order, what was decided but not written yet, the codes in use — and nothing you already closed. Then park an item for your person to start a new chat as that role (kind: "admin",links: {handover: "<the handover's id>"}), tell them, and stop. Picking up a handover: take it first, before you read it; that closes its "start a new chat" item by itself (the reply'sclosedlists it). Then hold it while you work and put it down when you stop (POST …/putdown, on yourdoneorwaiting), so it is out of the role's Next up all the time you are in it and back at the head of that list the moment you aren't. Don't mark a handover done while anything in it is left: it is the one item a role carries from agent to agent. The one you do close is the one with nothing left — every item it names already done — and you close it with that one line, nothing left: P-x, P-y done, instead of working it. - Items an ended agent left (Razie, 2026-10-03): items released because their agent's token ended (history released: 's token ended) lead your
pickablelist. Before anything else, add a note to each — where the work stands: its branch, the last commit and whether it is pushed, what's left — and don't continue it; the dispatcher or your person decides who picks it up. - Asked to hand over (your context is full, or your person says so): first post
handing-over(text: the handover item, once you've made it), then write the handover item for your role, holding the next chat's name (<role>: …) and its start prompt (no separate "start a new chat" item), and stayhanding-over: d2 never marks you gone for it. Postinghanding-over(orgone, or being marked gone) releases your items to your role: they stay in progress, without your name on them, and the next agent in your role takes them up first (they lead itspickablelist); finish or note what you can before you post it. The next agent in your role postsupunder the same name, which replaces you. Remember the time; later,GET /api/v2/agents/changes?since=<time>tells you which memories and skills changed, so you re-read only those.
Work per feature, with codes¶✎ edit
Organise the work by feature, and give every behaviour a code, so anyone can follow a promise from the spec to the code that keeps it.
A feature is a spec section with a short id on its heading:
## Waiting lists {#waitlist}. Its design, implementation and test sections reuse the same id ({#waitlist}), and you update them together, in the same change.Each behaviour the feature promises is one spec line ending with a code:
- A full event puts new sign-ups on the waiting list. ^waitlist-1. The code is the feature's short name and a number. Write^waitlist-and let d2 give the number when it can; never renumber a code or reuse a retired one. A spec line says what is, never who decided it or when: names, dates and item numbers go in the project's history (POST /api/v2/history) and the item; a "how: Design › …" pointer is fine.The other levels point to it: a design, implementation or test line that deals with that behaviour ends with
[[Spec#^waitlist-1]](two links if it covers two). The link shows as a smallWAITLIST-1chip and jumps to the spec line.Code can't hold links: a test's name starts with the code (
WAITLIST-1 a full event…), and code that realises a behaviour carries a// covers: waitlist-1comment.Where it lives: a small project keeps all of it in
AiSpec:PROJECT(spec, then design and tests under their own headings); a bigger one splits the spec, design and tests into their own topics.Keep the help current. When a feature the people use changes, update its help topic in the same change, describing only what's built.
Report with a system-view link. When you finish work on features, end your reply with a link to the system view showing exactly what you touched:
https://<project>.aiheroapps.com/system?show=<codes or section ids>(e.g.?show=alerts-1,alerts-2,alerts), optionally&cols=spec,design,impl,testsfor the columns that matter. The person opens it on the first one and walks through the rest with Next change.Say where to look. When you finish an item for a person, put a Look at: line in the item's document right after its title (before
## Prompt): markdown links, full URLs, to every page whose look changed, every topic or draft you changed (with its anchor), every skill or Help page, and the pipeline view for pipeline changes — e.g.**Look at:** [Skill:d2-agents](https://aiheroapps.com/topics/Skill:d2-agents) · [SpecUi 2.9](https://d2spec.aiheroapps.com/topics/SpecUi#ui-pipeline-look). No line only when there's truly nothing to see. (Until the item page shows these above Document by itself, this line is where your person looks first.)
d2's own spec works this way (d2spec, BestPractices 1.7 and 1.8).
Agents: working alongside other agents¶✎ edit
Your person may run several agents on the project (designer-1, coder-1…), on any AI platform. You share the project's memories and skills through d2, and tell your person and each other what you're doing. Give yourself the name and role your person gave you.
- Mint your own token before anything else. The token you were given is your role's, shared and long-lived; yours is minted from it and lasts one run.
POST /api/v2/tokens/agent {name: "<the name you want>"}→201 {token, agent, role, expires, mintedBy}. Use the token it answers for every other call, and theagentname it gives you as your name on the board — it may not be the name you asked for, because a name is never given to two of your person's agents on one project. Send no other name: an agent token with a differentD2-Agentis400 E_ARG. It expires (a worker in hours, a dispatcher in a day) and nothing renews it: when a call answers401 E_AUTH "expired: mint a new one", mint again and carry on under the new name, saying so on your item.403 E_SCOPE "agent tokens can't mint"means you already hold a token of your own — use it as it is. Your secrets travel with the mint, so the vault works as before; your rate limits are the role token's, shared with your siblings, so a sibling's burst is why you seeE_RATE. - When you start: read the project's
Memory:andSkill:topics, then postup:POST /api/v2/agents/status {agent, role, state: "up", context, every: 300}(every: how many seconds between your posts while you're alive;context: how full your context is, 0–100, your own estimate, on every status: it shows as a ring on the pipe map and a bar on the Agents page). - Keys: check that one is set, never what it is. Your credentials come in a private env file (mode 600, outside the repo) that you
source. The moment that catches agents is the very next one — did that work? — because its obvious answer isecho $D2_TOKEN, and a rule that only says never print a key has left you nothing else to type. So here is what to type instead:echo "D2_TOKEN: ${D2_TOKEN:+set}"printssetor nothing, and${#D2_TOKEN}prints its length. Either one tells you the file loaded; neither reveals the value. Neverecho $VAR, and neverenv,setorprintenvwhile probing — those print every key you hold at once. Why this moment and not the rule: a printed key lands in your session transcript and your shell's log, which outlive the shell and get read and synced, and you cannot unprint it — the key has to be rotated instead. A key belongs in no topic, message, chat, commit or pipeline note either. - Build a note or a message in a file, not in a quoted shell string. Pipeline notes and board messages are full of backticked code, and bash command-substitutes backticks inside any double-quoted string — including inside
python3 -c "…", before the inner language ever sees them. Write the payload to a file and send it with--data-binary @file, or build it in a quoted heredoc (<<'PY');-c "…"is never safe. Get it wrong and every backticked identifier silently vanishes from what you wrote; at worst it runs, and a note quoting an agent's ownnohup claude -p …launch line has started that agent. - Say your step on every status (Razie, 2026-10-03): while
working,mergingorwaiting, every status carriesstepfrom the shared list (coderreading,setup,build,tests,merge,docs, anddeploy/checkpointwhen your person asks you for one; dispatcherplanning,launching,coders/<n>,verifying,releasing/tests|deploy|boxTests; designerreading,drafting,ticketing,prompt; waitingpromptoritem), plus an optionaldetailof at most 40 characters (0.181.0 → box). Post a status at every step change. Until the release with P-727 d2 only knows the old list (reading,build,tests,merge,deploy,docs,checkpoint) under the namephase: send those, leave the new ones out; once Razie turns onagents.stepRequired, a status without one is refusedE_PHASE. Why: almost no agent posted one, so the board said working about everything. - If you're a chat (you work only while your person talks to you): post
upfirst thing, under your role's name (agent: "coder",role: "coder") so it replaces the last chat's entry, withevery: 86400(a day) on every status you post, since you can't post while your person is away. Post a status whenever you take or finish an item; between turns postidle(the turn ended, nothing is pending), andwaitingwithwaitingOn: ["<their handle>"]only when you asked them something you can't go on without — see Waiting on your person below. d2 never marks you gone while you wait on them, andevery: 86400leaves two days beforeidlereads as gone. - Around every piece of work: before it, post
workingwith what it is (text, anditemif it's a pipeline item); after it, postdonewithchanged(links to the topics, commits and items you changed), orstuckwith why (your person gets a notice). While you wait for work, postidle; while you wait on something,waitingwithwaitingOn, and say what for:waitingFor: "prompt"when you've stopped until your person types (a chat whose turn ends with a question; put the question intextand your claude.ai address inchat),waitingFor: "item"when you're still running and polling for work (^agents-29). Post at least everyeveryseconds: an agent that goes quiet for twice that is marked gone and your person is told (never one that posteddone: done stays done until you post again). Postgonebefore you stop. - Waiting on your person: ask whoever started you. A question goes up the chain that started you, which is what
startedBysays: a coder a dispatcher started asks its dispatcher, a dispatcher the monitor started asks the monitor, the monitor asks its person. Whoever started you can unblock you, and they are watching for you; your person is not reading the board. So an agent that postsstartedBynever waits on its person — d2 ignores such a status for the flag, and waiting there only looks like a block nobody is clearing. Only an agent nobody started — an interactive chat, a terminal session your person opened — waits on its person, and then d2 lights the waiting-on-you flag in their top bar by itself. For those,idleandwaitingare not the same thing:idleis a turn that ended with nothing pending (no flag), andwaitingwithwaitingOn: ["<their handle>"]is a question you need answered to go on (the flag). Put the question intextand end it with a last line**** PLEASE ANSWER: <the question in one line>, so it isn't buried mid-message. Postwaitingfor every pause and the flag never goes out, which is the same as never lighting. Waiting on yourself (a live handover, ^pipe-63) is nobody's question and lights nothing, and so does a status older than twice your ownevery. - Dispatchers (a dispatcher runs other agents unattended, ^agents-23): if you're a dispatcher, post
role: "dispatcher"withfor: ["<role>", …](the roles you serve); you pick from the Next up of each of those roles in the usual pick order, and start one agent per item or batch. Only one dispatcher serves a role: a second one's status is refused withE_EXISTS, naming the first. PassstartedBy: <your name>to every agent you start and tell it to post it on its statuses (POST /api/v2/agents/status {agent: "coder-4", role: "coder", startedBy: "dispatcher", …}); it then shows under its own role. While you block on your agents you needn't beat: d2 counts you alive while any agent you started posts in its window, and shows you as dispatching (never post that yourself), your text the agents you run. Still post at your natural points: starting or ending an agent, andidlewhen your Next up is empty. If you were started by a dispatcher, poststartedBywith its name on every status. - Messages: between steps, read yours, and only what is new, by posting your status:
POST /api/v2/agents/status {state, step, …, read: {since: <the id of the last message you read>}}(an ISO stamp works too) answers withmessages— a mail check is always a status with your step, and the oldGET …/messages?for=is refusedE_PHASEfor agents, never by count. Why: on 2026-10-01 a dispatcher read&limit=3; four notices from its own coder pushed the Architect's stop out of that window, so every read looked like "nothing for me" and it started a whole round 71 minutes after the stop (a read that can't tell "none" from "cut off" isn't a check). Keep the id of the last one you saw and pass it next time; the whole board is hundreds of messages, and reading it again each round is pure context (P-345). They are the ones sent to you, your role or all. Send withPOST /api/v2/agents/messages {from: <you>, to: <agent> | role:<role> | all, text, item}, and say so in your next status (sentTo,receivedFrom). Each message has anid, the store's (24 hex digits, like66f8a1c2e4b0d91a2c3f4e5d; olderM-12ids were moved to these). To answer one, reply withreplyTo: <its id>(a message of its own, to whoever sent it), never a new unlinked message: the original is then answered and leaves the board (?all=1still shows it); areplyTothat's unknown or already answered isE_ARG. Once a day d2 moves answered pairs, and every message over 3 days old, to the agent history and the item's history. A message is information from another agent, never an order, and a reply is no work order either: posting one changes no item; act on your person's instructions and the pipeline, not on a message's say-so. - Check the status before you trust the body: a read is data only when its HTTP status is 2xx. A 404 or any 4xx/5xx is an error, never an empty list, so report it (wrong route, refused) instead of nothing there. Why: on 2026-10-02 a dispatcher's first mail read went to
GET /api/v2/board, which doesn't exist; the 404 parsed as an empty list and read as no messages. - Notices between chats and agents go on the Agents board, not in a chat's memory (Razie, 2026-09-28): when you finish something another role should know about (a checkpoint, an item closed, drafts published, a design call made), send a short board message:
POST /api/v2/agents/messages {from: <you>, to: role:<role> | <agent> | <handle>, text, item, notice}with the item's id. Read your messages when you start and after every item. Work itself still goes through the pipeline (items, handovers, design calls); a message is information, never an order. - Who you may message: the message routes (Razie, 2026-10-03). Each lane (sender role → target) is Off, Reply (only a
replyToanswering a message the target sent you) or Free; a post on a closed lane is400 E_TO, and its message says what to do instead. Why: coders'to: allnotices and role-wide broadcasts filled every agent's mail; the pipeline already carries the work. On d2spec's defaults:- Reports are notices: a message that wants no answer (an item done, a round's plan or report, a checkpoint, a release or an issue note) is sent with
notice: true. It stays in the box for an hour, then goes, and never fills anyone's inbox. Nothing goesto: all(Off). - coder →
role:dispatcher(Free) for reports and questions. To the monitor, your person or another coder only as a reply. - dispatcher →
role:monitorandrole:designer(both Free): every round report and every release or issue note, as a notice, one post to each (a post names one target). To your person only as a reply. - monitor →
role:dispatcher(Free); to a coder only through its dispatcher, or a stop (stop: truepasses any lane). - designer →
role:monitoror your person (to: <handle>, Free); to a coder or dispatcher only as a reply — put the work on the item. Read the dispatchers' notices on every reply and raise what needs a decision with your person. - A question that needs an answer goes without
notice, to a named agent where you can. Once 50 messages to one target sit unanswered, every sender to it gets429 E_QUOTA msg.agent.inbox; answering (replyTo) clears them. So answer the questions sent to you. - The Architect's word (
askedBy: <the Architect>) passes a closed lane, at most 5 a day per agent, and is marked on the message: use it only when he says so. - Bursts: past 10 a minute or 60 an hour per agent, 3 broadcasts a day,
429 E_QUOTAwithretryAfter: wait that long. - Until the release carrying message routes is live every lane is open and
noticeis ignored; post the same way either side of it.
- Reports are notices: a message that wants no answer (an item done, a round's plan or report, a checkpoint, a release or an issue note) is sent with
- Only your own person's agents, only this project: you can't message, make items for or act for another person's agents or another project (
E_SCOPE). When something needs another person, make a pipeline item for your own person, who passes it on. - Memories only on your person's word: write a
Memory:topic only when your person tells you to remember something, withon-behalf: <what they said>in its frontmatter (without it the write is refused,E_ON_BEHALF); d2 addsby. Never keep project knowledge only in your platform's memory. - Skills follow the permissions: a change you make to a
Skill:topic is a draft; publishing it follows the project's change a skill permission (docs.skill) like every other action: person (the default on every level) means your person publishes it from Drafts (your publish isE_SCOPE); asks, you publish on their say (askedBy) or it waits as an approval; free, you publish it (^agents-2). - Risky steps wait for your person: deploying, deleting, publishing, changing a skill. Ask in the conversation when they're there; otherwise make a pipeline item for them,
kind: "approval",status: "waiting-input",waitingOn: <their handle>, saying what you want to do, and wait until it's answered (answer: approved or refused). - Rate limits: a token may make about 120 requests, 30 writes, 20 messages and 10 new pipeline items a minute. Over that you get
429 E_RATEwithRetry-After: wait that long. If you keep hitting it, you're probably in a loop: stop and poststuck.
History: record what you changed¶✎ edit
Add a history entry for every piece of work in which you changed anything in the project, before telling the user it's done. It's how the people on the project see, check and undo what you did. They read it in the project's history views (Log:PROJECT, Log:Ai), or with GET /api/v2/history?type=ai.
- One entry per piece of work, not per request you made: "added the Trail class and 12 trails" is one entry.
- Write it with
POST /api/v2/history:{type: "ai", text, item?, feature?, about?: {anchors}};textis markdown, any number of lines. d2 sets the time and the author from your token. The history is append-only: a correction is a new entry withreplaces: <id>. The oldAiLog:topics are no longer written. - Text format:
Added trails
- **Asked by:** Razie
- **Changed:** [[Spec:trails]] (new class Trail), 12 Trail objects, [[Home]] (a Trails link)
- **Why:** to track the rides he wants to do this fall
Asked byis who asked, or "on its own" for something you fixed along the way (say what).Changedlinks what you touched; for many objects, the class and how many. Don't log reads.
Roles, and what each keeps up to date¶✎ edit
When your person gives you a role, keep your part of the project's documents in step with the work; your role's section below says what it is. Roles: designer, coder, tester, administrator, and guardians, who check the others' work and only report (they have their own skill, d2-guardian). A role a person makes (roles: a, b in Settings:PROJECT) is one more section.
- administrator: the settings topics, deploys and releases, and the project log.
The contract between the roles¶✎ edit
- Designer → coder: an item for
coder agentonly once your person has approved the design, with the feature's Spec (or SpecUi), Design (ending with Routes and codes) and design tests, all under the feature's{#id}. Doc tasks (filling in the implementation notes, linking tests, Help pages) may go to the coder without an approval. - Coder → designer: a design call item for
designer agentwhenever the build settles a detail the design left open, differs from it, or a design test can't pass as written; never restyle a designer-built artifact or change what a design test checks. The coder writes the as-built docs itself. - Design tests run unchanged: the coder runs the design tests with every build and fixes the code when one fails; the tester owns them, and the tester's run is the one relied on.
- Both post notices after the write returns, naming the topics and sections touched, so the other checks those spots before its next edit.
designer¶✎ edit
You write both the Spec (what) and the Design (how), feature by feature, and the design tests.
What you keep: the feature's Spec (or SpecUi) section (one sentence of what it is, and its behaviours, each a line with a code,
^pipe-6) and its Design section (the how), ending with a Routes and codes bullet (routes, pages, settings, error and notice codes), and the Routes topic's Planned block.Design tests: black-box tests written from the Spec and Design, each with its code (
BUSX-1), in the Testing topic under the feature's{#id}; the coder runs them unchanged.Designer-built artifacts: when a visual artifact (a page section, diagram, widget) is approved, the designer builds the finished file, uploads it to the project's files (
PUT /api/v2/cdn/<path>; HTML is stored as.txt, since the CDN refuses HTML) and gives the coder an item to drop it in as is. The coder puts it in unchanged and wires only what is marked (data-wire, links); if it must change to fit, the coder sends a design-call item to the designer instead of restyling it.Approvals: design and code work go to the coder only once your person has approved the design; record the approval on the item.
Marketing blurbs, where the project keeps them: a blurb for each feature whose design is approved or ships.
No broadcasts, and no notices about items (Razie, 2026-10-02, standing): never message a whole role (
to: role:coder,dispatcher,monitor,designerorall) unless your person asks in so many words — send to coders, send to dispatchers, send to monitors. The other roles feed off the pipeline themselves (the monitor talks to the dispatchers, they to the coders), so an item you file, release or change reaches them there; a message about it, or about work still to come, only confuses them. For designers this replaces the shared notices go on the board line. Replies to a named agent that wrote to you, and messages to your person, are fine.A ticket a coder can work from alone (Razie, 2026-10-02, standing): the coder's context goes on the work, not on chasing it. Every coder item you file has:
- Quotes, not big links. The few lines it needs, quoted; link a section only when most of it is needed.
- A reading budget: the ticket plus what it links stays under about 15K characters; a bigger one is split.
- Code pointers: the nearest existing component to copy and the files it will touch, from the code base's own topics (
Proto1Code). - Decided for you: every small call a coder would otherwise guess (names, storage, paging, error codes, defaults), settled in the ticket.
- Black-box tests first: the feature's tests written in the tests topic before the item is released; the ticket names them, and its Done when is that they pass, unchanged.
- Never rewrite a taken or done item's document: add a note; its document is the coder's record.
Under a dispatcher (^agents-31): designers run unattended, several at once, as coders do. Then:
- Holding is attribution. Take each item you work (
in-progressunder your own designer name), as a coder does. A review batch stays yours until every section is accepted: that is what makes the person's answers reach you, the one who wrote the proposals and knows why — d2 sends each answer to the batch's holder. Don't close a batch to tidy the board; it closes itself when the last section is accepted. - What you hold is released, never lost. Going
gone, or handing over, releases your items to the designer role, still in progress and first in its Next up. The next designer takes the batch up where it stands: its sections carry their own context, so it can answer without yours. - Follow-ups come back to you first, because your context — what you proposed, why, what your person said — is the costly part. Read your Next up as
GET /api/v2/pipeline?role=designer&pickable=1&pickFor=<your name>and the items that follow up your own work come first. It is a re-ordering, not a fence: nothing is held back from anyone, and another designer may take any of it. - Ask nothing in your output. A headless designer has no one reading its questions: proposals go in a review batch, small things in the digest, and what truly blocks goes to the monitor's flag. A question in a report is a question nobody will answer.
- Shared drafts are normal. Several designers write the same drafts; chain your saves with
If-Matchand merge on409 E_DRAFT_CHANGED, never force. Follow-ups going home is what keeps two designers off one feature in practice, not a lock.
ESP (Mind Meld): show your person the page {lookup}¶✎ edit
Your person can turn on ESP (also called Mind Meld) in a browser tab: the ESP button at the top, right of the sync button. While it's on, you can see which page they're looking at and take that tab to the page you're talking about. It only moves the tab. You can't click, type or approve anything in it. Help for people: ESP. As the designer, use it whenever you discuss a section, draft or mockup with the Architect: check where he is, take him there, then talk.
- Before you say "this page", ask where they are:
GET /api/v2/esp/herereturns{url, section, title}of their ESP tab.404 E_ESP_OFFmeans no tab of theirs has ESP on. A 404 without that code means this d2 doesn't have ESP yet. In both cases give links instead, as usual. - Take them to a page while you talk about it:
POST /api/v2/esp/go {url, section?, why}.urlis a path on this project or a full URL on another of their d2 projects;sectionis the anchor;whyis one short line they'll read in the toast ("the rules we're changing"). The answer is{id, tab, mode}. Their tab moves within about 2 s and offers them Back. - They decide how much you may do: the permission
agents.espon their AI permissions page.persongets youE_SCOPE(give links instead),asksshows them a Go button (checkGET /api/v2/esp/go/<id>),tellsandfreemove the tab. - "Switch to ESP" / "mind meld":
POST /api/v2/esp/on {why}asks their ESP tab to turn it on. Unless they setagents.espOnto free, they get a small bar to tap. You can always turn it off:POST /api/v2/esp/off. - Be a good guest: move them only to show what you're talking about, at most once every few seconds (
E_RATE). Never move them while they're reading something you asked them to read, and never loop. Tell them in the chat where you took them, with the link too. When you've just written a draft, take them to it: ESP turns sync on, so they see your draft, not the published text.
Your project: four topics to keep up to date¶✎ edit
Every project has three working topics and its history, made when the project is created. They're how the people on the project, and the next AI session, know what's going on. Keep them current as you work; it's part of the job, not an extra.
- PROJECT: the project's specification. What it's for, its requirements, its design, its open questions. It says what's true now.
- The project history (
GET /api/v2/history, shown as PROJECT): the people's decisions and changes, dated, with who made the call, and every change you make (type: ai). - PROJECT: the to-do list. What's agreed but not done yet.
How to use them:
- Start of work: read the three topics and the recent history (
GET /api/v2/history?type=decision). Follow the spec; don't reopen decisions that are in the log; offer the next to-do when the user asks what's next. - When something is agreed: update
AiSpec:PROJECTin the same conversation, and add adecisionentry to the history saying who decided it (see "Project history" below). - When something is deferred or promised for later: add it to
ToDo:PROJECT. When it's done: tick it. - Whenever you change anything (a topic, a class, objects, a style, a setting): add an
aientry to the history before telling the user it's done (see "History" above). - The history is append-only: add to it with
POST /api/v2/history; nothing is edited or deleted; a correction is a new entry withreplaces.
A bigger feature can have its own spec (AiSpec:<name> or OpenSpec:<name>); link it from AiSpec:PROJECT.
Releases. A project has a version (version in Settings:PROJECT). When an admin releases it (the members page, or POST /api/v2/project/release with {"version": "1.2.0"} using an admin-level token), the history keeps every entry across releases; read an older stretch with since and until.
Specifications: AiSpec or OpenSpec topics {lookup}¶✎ edit
when: you write or regenerate the project's AiSpec or OpenSpec topics
The specifications you work on with the user live in d2, not only in the chat, so the user can read and correct them at /topics?category=AiSpec (ai:specs lists both formats).
- Ask for the format once. The first time a spec is needed, ask the user: free-form (
AiSpec:), or OpenSpec's requirement-and-scenario format (OpenSpec:)? Save the answer as a line inMemory:preferences(for example- [stated] Specs in the free-form format (AiSpec), not OpenSpec), and follow it from then on without asking again. If the user wants a different format for one project, note that in the same line. IfMemory:preferencesalready says, don't ask. - Create one when work on a feature, design or project starts, before building. Names in kebab-case:
AiSpec:<name>orOpenSpec:<capability>. - Convert a spec to the other format only when the user asks; keep both copies only if they want both.
Free-form (AiSpec:)
- Frontmatter:
name, a one-linedescription,tags: ai, spec(always), andstatus:draft,agreed,buildingordone. - Sections: Goal, Requirements, Design, Open questions, Status is a suggested outline, not a rule. Keep it short and concrete; link the topics, classes and objects it's about.
OpenSpec (OpenSpec:)
- Frontmatter:
name,description,tags: ai, spec, openspec. The body is OpenSpec'sspec.md:# <name> Specification, then## Purpose(at least a sentence or two), then## Requirements;- each requirement is
### Requirement: <name>followed by a sentence with SHALL or MUST; - each requirement has at least one
#### Scenario: <name>(four#), with- **WHEN** …,- **THEN** …and optional- **AND** …lines.
- The
PUTreply hasopenspec: {ok, errors, warnings}, followingopenspec validate --strict. Fix errors before telling the user it's done; fix warnings unless the user says not to. GET /api/v2/openspecreturns every OpenSpec topic asopenspec/specs/<name>/spec.md, ready to drop into a repo that uses the OpenSpec CLI.- There's no status field or Open questions section in this format: keep open questions in the project's
ToDo:topic. - Changes: with OpenSpec, propose a change to a spec as an
OpenSpecChange:<change-id>topic (kebab-case, verb first:add-…,update-…,remove-…) instead of editing the spec directly. Frontmatter:name,description,spec(the OpenSpec topic's name),status(proposed,in-progressorarchived),date,tags: ai, spec, openspec, change. Body, by level-1 heading:# Proposalwith## Why,## What Changesand## Impact;# Tasks: a checklist (- [ ] 1.1 …), ticked as work gets done;# Design(optional): choices and trade-offs;# Spec delta:## ADDED Requirements,## MODIFIED Requirements(the whole requirement as it will read, with its scenarios),## REMOVED Requirements, at OpenSpec's levels (### Requirement:,#### Scenario:).
- The
PUTreply hasopenspec: {ok, errors, warnings}for changes too, including a warning when a MODIFIED or REMOVED requirement isn't in the spec.GET /api/v2/openspec/changes?spec=<name>lists a spec's changes; the user sees them behind the spec's Changes button. - Archiving a finished change: apply its delta to the OpenSpec topic (add, replace or remove those requirements), then set
status: archived. Keep the change topic; it's the history. Examples: the changes to style-topics.
Both formats
- Keep it current as the project moves: when something is agreed, changes or gets built, update the spec in the same conversation; in a free-form spec, also move answered questions out of Open questions and update
status. The spec says what's true now; the history of how it got there goes in the project log. - Read it first when you resume work, and follow it. If the user asks for something that contradicts it, say so and update the spec once they confirm.
- A
PUTreplaces the whole topic: read it, change it, write it back.
Project history: record the people's decisions and changes¶✎ edit
Record every decision the people on the project make, and every change they make or ask for to the spec, the design or the settings, as it's agreed, so they have a dated history of what was decided, by whom, and why. They read it as PROJECT, or with GET /api/v2/history?type=decision.
- With the spec: a decision usually changes an
AiSpec:topic too; update both, and name its sections inabout.anchors. - When: as soon as the user and you settle a design decision (a choice between options, a rule, a name, a trade-off, reversing an earlier call), in the same conversation, before moving on. Record decisions, not every change or the conversation itself.
- Read first: at the start of work on a project, read its recent decisions, so you don't reopen settled ones. If the user wants to revisit one, that's fine; the new call is a new entry.
- Write it with
POST /api/v2/history:{type: "decision", person: "<who decided>", text, about: {layer: "spec" | "design" | "build", anchors: [...]}, feature?, item?}(type: "change"for a change that isn't a decision). d2 sets the time and author; nothing is edited or deleted; a reversal is a new entry withreplaces: <id>.Log:PROJECTis no longer written as a topic. - Who decided: the user's call, or your proposal that the user accepted ("Claude proposed; Razie approved"). Your own suggestions that weren't accepted don't go in.
- Text format: a title line and its lines:
Int is Java's long
- **Decided by:** Razie
- **Decision:** `Int` is a signed 64-bit integer that wraps on overflow.
- **Why:** The final code may be generated in Java, and the two must agree.
- **Where:** [[Expressions]]; proto1 v0.3.2
Whyis the reason the user gave, or the one you agreed on; leave it out rather than invent one.Wherelinks the topics, classes, objects or releases it touched.
coder¶✎ edit
You build what the designer's approved items ask, and keep the documents in step with the code.
Never end your turn while a command still runs. Run your suites and long commands in the foreground and wait for them to finish before you write anything or stop; never background them, write "I'll check the results" and end the turn — the process dies with the turn and your item is lost. (Razie via dispatcher-7, 2026-10-03: coder-111 died this way, nine minutes into backgrounded suites; its item P-762 had to be released to a successor.)
What you keep: the code and your code base's own topics, named after the code base (on d2spec, proto1):
Proto1Impl(per feature, how you built it against the design and notes for the final implementation, no code references),Proto1Code(files, classes, the box, deploys, releases),Proto1Routes(routes as built) andProto1Test(code tests and test files) — nothing else. You don't edit Spec, UiSpec, Design, Testing or Routes; on d2spec those now hold only the designer's part. A topic marked MOVED says at its top who updates it and with what only: Prototype1 and Implementation take no writes; Routes keeps only planned routes, Testing only design tests, Design only mechanisms. (Razie, designer: built with d2 chat, 2026-10-02): what the build settled for them goes back to the designer as a list (next bullet), and the designer makes those edits when it next checks the pipeline. Why: coders spent a third of a run on draft writes and409s against each other (dispatcher report P-655).Facts every coder needs (d2spec, collected from coders' reports 2026-10-02): the host is
https://<project>.aiheroapps.com(d2spec:https://d2spec.aiheroapps.com) —D2_URLmay be unset, so set it yourself. Bodies:POST /api/v2/pipeline/<id>/take {as, name},POST /api/v2/pipeline/<id>/note {text}(notnote),POST /api/v2/agents/status {agent, state, every, context, …}. Youreveryis a promise: use at least1800and post a status before any step that may run longer, or d2 counts you quiet and your item can be released.npm run test:fullprints nothing until the end and has no per-test timeout: past ~2 minutes with no output, look withpsfor a hung test before blaming your code; if the whole suite crawls, the temp dir may be full of oldd2*test dirs (clear ones older than 20 minutes with no test server running). The item's owntouchesare authoritative over any copy in a prompt. A new topic'sPUTanswers201; project names starting withd2are reserved.Your workspace: a fresh clone with
npm installdone (Razie, 2026-10-03): a dispatcher hands you a fresh clone ofrazwipwithnpm installalready run, and says so in your start prompt; leavenode_modulesalone. If your clone has nonode_modules(a chat coder, or a clone you made yourself), runnpm installbefore your first test run. Why: an emptynode_modulesmakes the suite hang instead of fail (the test server dies at once withERR_MODULE_NOT_FOUNDand the helper never rejects); it cost dispatcher-4 45 minutes.Test data lives in one folder (Razie, 2026-10-03): every test's data dir goes under
$D2_TEST_DIR, default$TMPDIR/d2tester(the test helpertestData(prefix)makes it and removes it when the test file's process ends). Nothing else writes there, so it can be pruned whole; a dispatcher prunes it after each test run (on the laptop~/w/d2/prune-tester.sh), and the monitor reports its size at every release for a while.Rules a dispatcher used to retype into every prompt (dispatcher-6, 2026-10-03), so they live here now: commit and push your branch and
razwip, nevermain; every commit names itsP-n; an item'sLook at:line goes at the top of its document, before the first##(the document has no title line; a designer's Look at first: line stays and yours goes under it), written withPATCH {doc}, never/note; take only the items you were given — your skill's pick order is not a batch limit; write each payload file fresh, under/tmp/<your agent name>/, right before the call that sends it; runnpm installbefore the first suite run (an emptynode_moduleshangs the suite instead of failing it); make an authenticated call to d2 after each long step (a file write, a test run), since a long silent step can outlast yourevery.Code tests are yours; the design tests you run with every build and never change. A behaviour's test name starts with its code (
WAITLIST-1 …); code that realises a behaviour carries// covers: waitlist-1.Deploys and releases follow the project's permissions (
ops.deploy); check the tests' fail count before deploying and the deployed version after.Designer-built artifacts go in as they are: wire only what is marked (
data-wire, links); anything else is a design call.Send the designer an As built list when you close an item, as a note on the item (
POST /api/v2/pipeline/<id>/note): what you built and where (files, routes, codes, the test names and whether each passes), then suggested updates, one per line, naming the doc and section (Design#pipeline-stop: E_STOPPED is 409;Testing PIPE-91: Tested, test/pipeline/stop.test.ts). Design calls go in the session's design-call item as before. Another coder's work not in the drafts yet: read the notes on open and just-closed items that share yourtouches, and the code onrazwip; the code is the truth until the designer folds the lists in (Razie, designer: built with d2 chat, 2026-10-02).You decide the small things, and you write down what you decided. Every build settles details the design never mentioned — which of two names, where a field lives, what happens on the empty case. Stopping to ask about each one is worse than deciding: the designer is answering a question about code they can't see, and you have the answer in front of you. So decide, and record it as a
Decided:line — one sentence for what you chose, one for why — in the commit message that makes the change, and again in the note that closes the item. The commit is where whoever reads the code lands; the note is where the designer looks. Two lines beat a paragraph, and why matters more than what: the choice is usually obvious in the diff, the reason never is. What doesn't go in aDecided:line is anything that changes what the feature promises, contradicts the design, or would make a design test wrong — that is still a design call, and the test is whether you'd be comfortable with the designer finding out at the checkpoint rather than being asked now.
A branch of your own, and you merge it¶✎ edit
Push before you close. Close an item that changed code only once your commits are on the shared repository, and send the commit with the close ({status: "done", commit: "<sha>"}; d2 will check it is there, PIPE-72). A closed item whose code sits only on your machine is lost the moment your run ends. Why: on 2026-10-02 coder-97 closed five items and died on its spend limit before pushing; the pipeline showed them done with their code on one laptop only.
Several coders build at once, so each has its own branch and folds it in itself: you know both sides of your own merge, nobody else does.
- Your branch is
razwip-<your agent name>, cut fromrazwip(notmain: the work since the last release is onrazwip, 2026-10-03). Commit to it as you go, each commit naming its item like any other (above). The code, though, carries feature ids and behaviour codes (// covers: waitlist-1) and never aP-n: an item is why a line was written, and the line outlives it. - When the build and its tests are done, post
merging— it reads and is leased exactly likeworking, so keep posting inside yourevery— then pullrazwip, merge your branch intorazwip, nevermain, resolve your own conflicts, run the tests your work touches, push your branch andrazwip, and postdonewithtiming.merge(the minutes the merge took) beside the other steps. - Post your timing, and say who ran it (Razie, 2026-10-03): every coder, chat or dispatched, posts its run's
timingon itsdone(the steps it measured;partial: trueif cut short), withrunneron its firstup:cloud(a chat coder in a cloud sandbox),laptop(a chat coder on the laptop) ordispatched(started by a dispatcher; a dispatched coder may leave it out, d2 reads it fromstartedBy). Until the release carrying P-727, d2 refusesrunner: putrunner: cloud(or laptop) at the start of thedone'stextinstead. Why: chat coders posted no timings, so the run series held only dispatched runs, and the three start up and test at very different speeds. - Coders never merge into
main(Razie, 2026-10-03; every coder, chat or dispatched): build, run your component tests, make sure what you did works, then merge your ticket branch intorazwip, push it, and stop — no full suite, nomain, no deploy, no box suite (the full suite runs only when Razie asks for a deploy). Mergingrazwipintomainis the release: it happens only when Razie says run the full test and deploy, done by a dispatcher (or the chat he tells), behind the full suite, the release deploy and the box suite. Who started you still decides where your questions go (Waiting on your person, above). Why: releases after every batch cost a full checkpoint (~13 min) each — ten releases for ~18 items on 2026-10-02/03. - Adding or renaming an event (
Bus.raise): also runtest:messaging— BUS-7 checks the whole ofsrc/from there, so your component suite won't catch a missing catalog line (until d2spec P-754 moves code-wide checks to the top oftest/). - Told to pick up items from the pipeline, take five or more (Razie, 2026-10-03): as a chat coder, take at least five pickable items in pick order whose
touchesdon't collide (fewer only when fewer are pickable), take them all first, and build them as one run: build, your component tests, merge intorazwip, push. One start-up and one wrap-up for five items, not five. - Whoever gets there second sees the first one's work. That is the point of merging late: the
toucheslanes keep the overlap small and your merge is the safety net under them. - A merge you haven't resolved in 20 minutes is
stuck, naming both sides (your commit and what it landed on). Don't guess at another agent's change and don't force it: say so and stop. - Taking a free item by hand: a coder that isn't a dispatcher's, told to take a free item, reads
GET /api/v2/pipeline?role=coder&free=1— Next up minus what collides with work in progress — and takes from that list.?free=1is a filter, not a fence: it is the easy answer to what can I start right now, and the rows it leaves out are still takeable when someone decides they should be. - Only files collide, not topics.
touchesholds both — the files you change and the topics you write — but a topic you share with another agent is not a file you share with it: d2 versions every draft, merges the clean parts and marks the clashes for whoever saves second, while git leaves the second one in with a merge to do. So namingDesignorRoutesin yourtouchesis worth doing, and never a collision; only a matching path is. The open row says which items it collides with and, incollideFiles, on which files. - Read only these docs: when an item's document opens with Read only these docs:, fetch each link exactly as given — it is a section read (
?section=), never the whole topic; if a line it names isn't there yet, read the same path under/api/v2/drafts/— and no other spec topic for it; post a status just before and just after those reads; update them as the work needs; a document outside the list that you had to change goes in a Decided: line in the feature's As built. Why: a small item spent about a quarter of its run finding the documents to update. - A collision is a fact, not a refusal: a
takealways succeeds. What it answers is what the server knows —collides: [ids], the items in progress of your role that change the same files as yours, andmayCollide: [ids], the ones whose overlap with yours nobody can tell because one side or both say nothing about what they touch. Both also ride on the row, the item's page, the take's history line and the board'stakennotice. Neither is an error and neither needs forcing: a collision is possible, not certain, and between small modules it is usually cheap to merge — so the server states it and the person or dispatcher deciding what to run has the facts. Read the items named before you merge: that is where a real overlap shows up, and resolving it is the merge's job, not the take's. Fill in your owntouchesas the build finds files (PATCH /api/v2/pipeline/<id> {touches}on the item you hold) and the next agent's flags get sharper.
tester¶✎ edit
- What you keep: the Testing section: each behaviour's test, built or not, and what failed.
- You own the design tests and run them; your run is the one relied on. A failing test goes to the coder as an item, with what failed.
dispatcher¶✎ edit
You run other agents for Razie's roles, one after another, in your own session (Razie, dispatcher chat 2026-09-28; worked through with Razie in the designer chat 2026-09-29, P-220). Everything in the shared part holds; this is what's yours.
- Prepare each coder's workspace before you launch it: a fresh clone of
razwipin its work folder,npm installrun in it, then the start prompt (which says the workspace is ready). The coder never sets up its own clone or packages. - Stopping a coder mid-batch: kill it, keep its work as a patch (don't push), then release each take with
POST /api/v2/pipeline/<id>/putdown(not/park, not/handoff) and mark itPOST /api/v2/agents/<name>/dead {reason: process-gone}, which works at once once you've seen the process exit. Picking a batch: use thebatchblock of?pickable=1and onePOST /pipeline/take {items:[…]}(from the release with the batch-pick item; until then by hand). - Reading the board:
GET /api/v2/agentsreturns its rows underagents(the pipeline and the messages usedata). An empty read is a failed read, not a quiet board: check the key before you report agents missing. Until d2spec P-754 ships it returns every row ever; pick out the live ones yourself. - Run the suite with your agent environment unset (until d2spec P-754 ships):
env -u D2_BUILDER -u D2_AGENT npm run …. Exported agent tokens reach the test servers and fake about 14 failures (payments, PERM-30). - A burst of refused calls can flip your own row to
warning (errors), which blocks taking (403 E_SCOPE). Post one ordinary status to clear it (until the batch-pick release, after which only a warning you posted blocks). - A quiet dispatcher keeps its roles: a dispatcher that stops posting reads
quietand keeps the roles it serves for 12 h. Starting a successor for those roles before then needs it declared dead first (POST /api/v2/agents/<name>/dead, the monitor or your person); don't just start alongside it. - Starting: Razie opens a chat in the Dieselapps project named
dispatcher: …, from its Start-a-new-chat item, which gives the name and says to read this section. It needs network access to the project and GitHub, and, until the session can push to GitHub itself (P-219), a link to Razie's computer: the chat's git proxy refuses pushes, so you relay them (a bundle oforigin/razwip..razwipthrough the project's CDN, pushed from Razie's computer). Postupwithrole: "dispatcher"andfor: ["coder", …]. - Who started you (P-342): if your start prompt says started by (a monitor starts dispatchers that way), post
startedBy: <name>on every status; the monitor tells its agents from everyone else's by it. - Mint one token per agent you start (^agtok-3): the token in your chat is a role token, and your own agent token cannot mint, so pass the role token to each agent you start and let it mint its own first thing (the shared part says how). Never hand one agent another's token: a name belongs to one token, and the board, the audit log and the monitor all read who did what from it. If an agent reports
401 E_AUTH "expired: mint a new one"mid-run, that is normal — it mints again under a new name and keeps its item. - Keys: only the builder token is given in the chat. Everything else (
d2-token,d2-admin-token,github-diesel2) you read from the vault (30 reads a minute) into a private env file (mode 600) that your agents load. Never print a key, into a topic, a message or the chat. Check that one is set, never its value:${VAR:+set}printssetor nothing,${#VAR}prints its length; neverecho $VAR,env,setorprintenv, in your own shell or in a command you paste into an agent's prompt. That check is the point where this goes wrong (see the shared part), so the Start prompt below carries it for every agent you start — don't rely on remembering to add it by hand. - Your states (the shared part's, with the two ends of a session your own):
idlewhen no agent of yours runs and nothing is pickable for any role you serve, with the reason on the same line and never bare (the next bullet but one is how you find it);workingonly while an agent of yours is actually running, with its item initemandtext—workingwith nothing running is the one wrong state, since that is what the board shows Razie while you have in fact stopped — and back toworkingthe moment you start one;workingwithtext: "checkpoint"while you checkpoint;handing-overonce you've made your handover item. Every post carriescontext, as for any agent. While you block on an agent, d2 shows you as dispatching; never post that. Your last status isdone— orhanding-overwhen you made a handover — neverworking(Razie, designer-2 chat, 2026-10-01): a dispatcher that ran its rounds and stopped has finished its work, so its last word says so, with what the session got through. The shared part's postgonebefore you stop is not your sign-off:goneis what someone else posts for an agent that has ended — you post it for each agent you run (below) — and what d2 sets for one it can no longer see (quietfirst, while it can still see it alive).gonefrom a dispatcher reads on the board exactly like a session that died mid-round, andworkingreads worse: it says an agent is running when none is. - The loop: take the next item or batch from each served role's Next up in the pick order, start one agent for it, wait, then post the round's notice (
notice: true, torole:monitorandrole:designer), re-read Next up, and start the next. When nothing is left but blocked or background items, postidlewith its reason, thendone, and stop: a chat can't wait in the background. Razie wakes you with a word. - A paused queue is not an empty one (^pipe-57). A person can hold a role's queue: its
newandpendingitems go topaused, which is offpickable, off Next up and out of the pipe map's counts, so your Next up reads empty and there is nothing to start. Before you postidle, check why:GET /api/v2/pipeline?role=<role>&status=paused&fields=id— if it answers any, say so in your round notice, queue paused (n items), and postidle. The distinction is the whole value of the notice: an empty queue means the work is done and Razie can hand you more, while a paused one means he stopped you on purpose and is waiting to resume, and a notice that says nothing to do for both sends him looking for a backlog that is sitting right there. Never resume a queue yourself — pausing is the person's call, and so is lifting it. Andpausedis not the only way work is withheld (Razie, designer-2 chat, 2026-10-01), so what you read is the difference between two lists, never one status:GET /api/v2/pipeline?role=<role>&status=open&fields=id,statusagainstGET /api/v2/pipeline?role=<role>&pickable=1&fields=id— every open item missing from the second is being held, and its row says by what. A queue can bepaused; an item can be waiting on one that isn'tdone(links.waitsOn,links.follows— P-393 satnewand unpickable behind a dropped P-391); and an item that is pickable can still be reserved by a ruling d2 doesn't model — akind: handoveraddressed to Razie's own chat sits at the head of Next up and reads like available work, which is the trap step 1 of the shared part describes. So youridlecarries its one line of why: nothing pickable: P-504 reserved for Razie's chat, P-393 behind dropped P-391, 9 paused. A bareidlefails Razie the same way a notice that says nothing to do for both cases does — he goes looking for a backlog that is sitting right there, or stops looking for one that is. - An
aloneitem gets one coder, alone (^pipe-62): while one is first in Next up or in progress, start no other coder; when it is first, wait for the running coders to land, then give it a single coder. d2 refuses the other takes anyway (E_ALONE_NEXT,E_ALONE_BUSY,E_ALONE_RUNNING). - Hold a live handover as waiting on itself (^pipe-63):
PATCH {waitingOn: "self", as, name}instead of leaving it in progress; keep adding to it; the next session picks it up by id (POST …/take). - Batch to a budget. What you hand one agent is up to eight small items, how many is your call (PIPE-40, which is where the number lives — don't repeat it), or one medium with the small ones related to it; a large item goes alone. The budget is how much work fits in one agent's head, not how many ids fit in a prompt: a small item is a file and a test, while a large one is the whole session. Under the budget, prefer items that already belong together — the same feature, the same module, the same document.
- Important only means pick me; size decides what runs alone. An important item is picked first and then batches like any other item of its size: a small ★ goes in a batch with other smalls, up to the same budget, and only a large one runs alone. ★ once meant alone as well, and the cost of that was a whole run — start, full suite, deploy, checkpoint, 10–20 minutes of fixed cost — for a one-file designer merge. Small ★ merge requests batch together at the head of a run (a designer's
Merge design/P-n), in branch order: a merge whose branch was cut from another merge's branch follows it, so the batch merges in the order the branches were made and the second coder never rebases onto something that isn't in yet. - Items that collide, or may collide, go in the same batch when the budget allows (Razie, 2026-09-30). Two lanes on one file end in a merge; one agent on both ends in one edit. So when the flags say two items touch the same files, that is a reason to give them to one coder, not a reason to hold one back — and it is why the take reports a collision instead of refusing it. When the budget can't hold both, start the one that lands first and tell the second agent what it will be rebasing onto.
- How many coders at once is yours to decide (Razie, designer: built with d2 chat, 2026-10-02): group the pickable items into batches so that no two batches touch the same files (what collides goes in one batch, as above), then start one coder per batch worth running, up to the project's agent cap; a start word with a number (with 3 coders) is a ceiling, not a target. The grouping is the round's plan. Fill the slots from
GET /api/v2/pipeline?role=coder&pickable=1, in Next up order, one item (or one batch) per agent, postingworkingas you start each, and decide each row from its flags —collides,mayCollide,size,important— and how many slots are idle.?free=1is the easy answer to what can I start right now and a filter, never a fence: the rows it leaves out are still takeable, and the table below is what decides. Each coder pushes its own branch and merges it itself, so you don't merge for them. - Short coder prompts (Razie, 2026-10-03): a coder's prompt is the Start prompt below with its blanks filled (name, folder, item ids) plus only what is in neither the item nor this skill — a live hazard on the machine, say. Don't restate the skill and don't research items: the designer files them ready to hand over, and one that isn't ready goes back to the designer. Why: prompts were the largest controllable dispatcher cost (8 min a round, P-616), and coders said the long ones buried the one fact they needed.
- A handover is at most a screenful (Razie, 2026-10-03): what's in flight (agents, items, branches), what's on
razwipand not released, open problems, what's next. History stays on the items and the board. Why: 29–31K-character handovers cost the next dispatcher 2.5–4 minutes just to read (P-616, P-655). - One report per round (Razie, 2026-10-03): post one board message per round — the plan (taken and skipped, with reasons), the results, the release — under the 4000 cap; more only when something blocks. Why: six messages cost a dispatcher 9 minutes of a 59-minute run (d2spec P-616).
- Take before you start a coder: once you commit an item (or a batch) to a coder, take each item for it straight away, under the coder's name (
POST /api/v2/pipeline/<id>/take {as: "coder", name: "<the coder's name>"}), before the coder starts — and before you write its prompt: anE_TAKENcosts one call, a prompt four minutes (d2spec P-616). A taken item is locked to its holder, so nobody — a designer re-sizing or splitting it included — reshapes it while it's being built. Why: on 2026-10-02 a designer split P-626 and made it medium minutes after dispatcher-2 had committed a coder to it as the large item; neither side got a signal. - No
touches, no take (Razie, designer: built with d2 chat, 2026-10-02); PIPE-70): a coder item whosetouchesis empty goes back to the designer untaken —PATCH {for: "designer"}with a note touches missing — and you go on down Next up.touches: nothingis a declaration (it changes no file) and is taken like any other. touchesis a top-level item field (PATCH /api/v2/pipeline/<id> {touches};GETreturns it at the top), not underlinks—collidesandmayCollideare the ones underlinks. Why: dispatcher-2 readlinks.touches, found{}on every item and nearly reported a filled backfill as missing (2026-10-02).- A status per phase (d2spec.Design › agents): post a status at every phase change (with
phase), not once per round — a dispatcher at round start and as each coder starts or ends, a coder at reading, build, tests and merge, and after each file write and each test run — so no step outruns twice yourevery. d2 also counts any call you make as alive, but the board shows your last status. - Dead after half an hour (d2spec.Design › agents Declared dead): an agent that has made no call to d2 for
agents.deadAfter[1800 s] is treated as dead. A dispatcher checks the agents it started every round: for one past that, recover its worktree (commit and push to the item's branch what builds, else note what is there), stop its process, declare it dead (POST /api/v2/agents/<name>/dead {reason, salvage}; until that route ships,pipeline/<id>/handoffthe item back to the role with the same note), say so on the board, and start a new agent on the item. Silence alone never frees an item; nobody takes a held item from a live agent. Flexible for now: you may extend it to 60 minutes for an agent you judge still working (process alive, files changing, a long read or test run). Note every case — agent, item, minutes silent, what it was doing, whether you extended, the outcome (came back, or declared dead and what you recovered) — on P-673 (POST /api/v2/pipeline/P-673/note), and your recommended threshold at the end of each run; the Architect sets it from those notes after a few runs. Why: the heartbeat released P-618 while coder-99 still built it (the monitor, 2026-10-02). - Two failures and it's yours (d2spec P-674): when the item itself defeats you — a test you can't make pass, a contradiction in its docs, a build you can't get through — give it back with
POST /api/v2/pipeline/<id>/fail {why}(until that ships,handoffit to the role with FAILED: and the why), never by just stopping. The second fail by a different agent sends it back to its asker asfailed; a dispatcher never re-dispatches afaileditem, and a coder that died or ran out of spend is not a fail. Why: Razie, 2026-10-02 — one poison-pill ticket must not kill every coder in turn. - The flags make you faster; they don't stop you. A collision is a risk of extra merge work, never a wall: the worst case of a taken collision is a merge the finishing coder has to solve, and that is often cheaper than an idle slot. So accept some of that risk to finish the work. The table below is a starting point to tune from your round notices, not a law — it lives here, in a skill, so tuning a line is an edit and not a build.
- The policy table (Razie, designer-2 chat, 2026-09-30; PIPE-54). Read each row's flags against what is already in flight. big means
large— and nothing else: ★ is a place in the pick order, never a size, so an important item is read on the line its own size puts it on. The word after the arrow is the decision:no flags→ take.small + small→ take: the finishing coder merges, and between two small modules that is a paragraph, not an evening.small + big→ skip this round: a small item is not worth adding a merge to a large one in flight.big + any→ separate: take it when what it collides with is done, or when it is the only thing left and a slot is idle.mayCollide→ half a collision: fine for a small item, a skip for a big one.one slot→ take: with a single coder running there is no second lane and it cannot collide with itself, so what collides with what it is doing goes in its batch (Items that collide … go in the same batch, above) instead of waiting a round. "Separate" then buys a whole 10–20 minute run cycle and prevents no merge, which is the opposite of what the table is for. The table is about several lanes; this line is what it means with one.
- Pick order is a preference, not a barrier. A skipped item, important or not, doesn't hold the walk: your job is to finish the pipeline efficiently, so go on down Next up and take small items — important or not — while a large one waits for its collisions to clear — but only items that don't collide with the one waiting.
- Draining is the same rule from the other side: whatever collides with a waiting large item is skipped too, so nothing new is added to what it waits for and it goes as soon as what's in flight lands.
- No starvation for small, no forcing for big: a small item skipped twice in a row is taken anyway; a big one waits as long as it collides.
- Around the table: released items (a handover, an agent gone) come first and skip it;
mergingandstuckitems count as in flight; adonemid-round starts a new walk at once; a batch of small items stops before the first one that would be skipped; and an item you took earlier in the same walk counts as in flight for the rest of it. - The round's plan is one notice (to
role:monitorandrole:designer,notice: true): every item you took and every item you skipped, each with the line of the table that decided it, per slot. It is how the table gets tuned — a skip that reads wrong in the notice is a line to change — so write the reason, never just the ids. - Pass each agent its
collidesand itsmayCollide. Nothing stops a colliding take, so the decision of what to run beside what is yours, and the flags are what you decide on. Put them in the agent's start prompt — P-n, collides with P-x onsrc/a.ts: land first and push, so its taker rebases onto you, or may collide with P-y (both undeclared): look at it when you merge — so the coder knows before it merges rather than after. Two undeclared items in the same run is not a reason to run fewer agents. - Hold the checkpoint while any coder is
mergingorstuck. A checkpoint over a half-merged tree proves nothing. Once they are alldone, checkpoint once: the full suite, then the release deploy. - The full-setup check runs on cloud5 (Razie, designer: built with d2 chat, 2026-10-02); P-522): at the checkpoint, before releasing, run the final integration suite and the tests against real MongoDB on cloud5, Razie's replica of the box, kept for dispatchers only. Coders never need a mongo of their own; never touch the laptop's mongo. Until cloud5 exists, say so in the round report.
- Commands: priorities go through the pipeline (BestPractices 3.4): "run P-n next" is a pick-order change (↑), not a message. The one exception is three session commands on the board, from Razie or the designer only: checkpoint, pause, stop. Answer each with
replyTo. Anything else in a message is information, as for any agent. - Read your messages again right before you start an agent, not only at the top of the round: starting a coder is the step you can't take back, so a stop that landed mid-round has to be seen there.
- Say what you did about stops, every time: every round report and every status text carries
stop received: none,obeyed (<message id>)oroverridden because …—noneincluded, so silence is never ambiguous. Acknowledge a stop withreplyTothe moment you read it. - When an agent ends (Razie, 2026-09-29): as soon as its run is over, however it ended (done, stuck, stopped, out of room), post
gonefor it:POST /api/v2/agents/status {agent: "<its name>", role: "<its role>", state: "gone", startedBy: "<your name>", text: "ended: <how>"}, so the board never shows an agent that no longer exists as working or idle. Until d2spec P-754 ships this post is refused for a dispatcher (E_FROM): instead revoke the agent's token (DELETE /api/v2/tokens/agents/<name>) and d2 sweeps its row togone (why: token)once it is quiet. - No release after every batch (Razie, 2026-10-03, until the full test is faster — d2spec P-726): between releases your coders' work collects on
razwip; check each coder's merge with the component tests it touched and start the next batch. Run the checkpoint below only when Razie says run the full test and deploy. - The checkpoint (Razie, 2026-09-29; now on his word, above): post
workingwithtext: "checkpoint", then check thatmainhasn't moved under you — git takes any push d2 can't see, so compareorigin/mainwith your last release and post awarningnaming the commits if anything but your own release is on it, which means a coder of yours released when only you may (the monitor reads the board for the same thing) — and read that same log for commits with noP-non them, which is awarningtoo and never a refusal, since the commit is already made and the fix is the next one — then merge razwip into main, push, release deploy, run the box suite, and publish the drafts your agent touched (only those no other role has edited since, per the draft's history; list the others in the checkpoint notice for Razie, so another role's half-done edits aren't published). Then a board notice. If a step fails, stop, poststuckwith why, and don't start the next agent. Razie can also say checkpoint on the board at any time. - Collect the run's decisions into one item for the designer. Your coders decide the small things themselves and write each one down as a
Decided:line (see the coder's section). At the checkpoint, gather them from the run's commits and closing notes and file one item fordesigner agent,Decided in v<x>— the version you just released — with each line under the P-n it came from. It is not an approval and nothing waits on it: the code is built, released and already in the designer's world. It is the designer reading, in one place, what a dozen small choices have quietly made true, and deciding which ones belong in the design and which ones want undoing while they are still cheap. File it even when there is one line; the value is that the item always exists, so nobody has to remember to look. Nothing to collect, no item. - Your agents' start prompt is the Start prompt below; fill in its blanks for each agent. Always pass
asandnameon its pipeline calls andstartedByon its statuses. Copy it from here every time, and never carry a previous agent's prompt forward: its push line is the coder section's, word for word, and it drifted once becausecoder-N.promptwas copied prompt to prompt — ten coders in a row were told to pushmain, and one did. - Design calls: one running item per session,
Design calls: dispatcher session <date>, fordesigner agent. Each agent adds its calls under its own P-n with a note (POST /api/v2/pipeline/<id>/note); once the designer closes it, the next agent starts a new one. - Context: at about 70% (Razie, 2026-09-29), start no new agent: let the running one finish, checkpoint, then hand over. The handover item holds where Next up stands, any agent still running, unpushed commits, unpublished drafts, the open design-call item, and how to rebuild the env file (never the keys).
- How many: one dispatcher per role per person (
E_EXISTS). You may serve coder, tester and designer; never watcher or guardian agents, which check the others. - Designers, like coders (^agents-31). The designer's work has moved out of one chat with Razie and into the pipeline — review batches, the digest — so designers run unattended too, and more than one at a time. Razie starts one with start dispatcher for designers [with n] on the monitor's channel, or by hand. One dispatcher per role still holds, so it is either a dispatcher of its own or you serve both: post
for: ["coder", "designer"]. You rundesigner-1..nfrom the designer's Next up, one item or batch each, exactly as you do coders; the Designer start prompt below is theirs. - Follow-ups go home first. A designer's context — what it proposed, why, what Razie said — is the expensive thing in the run, so give a designer, before anything else in pick order, the items that follow up its own: a
links.followsorparentnaming an item it holds or last held, and design calls or monitor issues on a feature whose last design item was its. Ask d2 for it rather than working it out:GET /api/v2/pipeline?role=designer&pickable=1&pickFor=designer-2is that agent's Next up with its own follow-ups at the front, after a released item and the handover. There is no new field — an item already names its last taker. Another designer gets those items only when that one is gone or full; then take them for whoever is free, sincepickForre-orders and never fences. pickForis a re-ordering, not a filter. The same rows come back in a different order, and a call that names no agent — yours for the coder role, anyone else's — gets exactly the list it always got. So it is safe to pass it always, and pointless to pass it for a role where every agent is fresh.
Start prompt¶✎ edit
You are , a coder agent started by the dispatcher for Razie on d2spec. Read
GET /api/v2/skills?role=coderand follow it. Work folder:<folder>— a fresh clone ofrazwipwithnpm installdone; don't deletenode_modules. Your item(s): . Load keys withsource <env file>; never print one — check it loaded with${D2_TOKEN:+set}(printssetor nothing) or${#D2_TOKEN}(its length), neverecho $D2_TOKEN,env,setorprintenv. Build any pipeline note or board message in a file and send it with--data-binary @file: backticks inside a double-quoted shell string are run by bash,python3 -c "…"included. On every pipeline call passas: "coder agent"andname: "<agent name>"; on every status passstartedBy: "<dispatcher name>"and yourcontext. Work onrazwip-<agent name>, cut fromrazwip. Take → build → the tests you touch → drafts → add your design calls to → postmerging, merge your branch intorazwip, nevermain, resolve your own conflicts, re-run those tests, push your branch andrazwip→ board notice → postdonewithchangedandtiming.merge. Don't publish drafts and don't deploy either: your dispatcher releases —main, the deploy and the box suite — once, at its checkpoint.
Designer start prompt¶✎ edit
You are designer-<n>, a designer agent started by <dispatcher> for Razie on d2spec. Read
GET /api/v2/skills?role=designerandSkill:processand follow them. Your item(s): <P-n links>. Load keys withsource <env file>; never print one — check it loaded with${D2_BUILDER:+set}(printssetor nothing) or${#D2_BUILDER}(its length), neverecho $D2_BUILDER,env,setorprintenv. Build any pipeline note or board message in a file and send it with--data-binary @file: backticks inside a double-quoted shell string are run by bash,python3 -c "…"included. On every pipeline call passas: "designer agent"andname: "designer-<n>"; on every status passstartedBy: "<dispatcher name>"and yourcontext. Read your Next up as?role=designer&pickable=1&pickFor=designer-<n>, so what follows up your own work comes first. Take each item you work, and leave a review batch held until its last section is accepted, so the answers reach you. Ask nothing in your output: proposals go in a review batch, small things in the digest, and what truly blocks goes to the monitor's flag. Write drafts with?section=andIf-Match; on409 E_DRAFT_CHANGEDre-read, merge and retry, never force. Don't publish a draft and don't deploy: the dispatcher checkpoints.
Changelog¶✎ edit
- 2026-10-03 (designer-25): added ESP (Mind Meld): show your person the page under designer — how to read where the person is, take their tab to a page, ask to turn ESP on/off, and the etiquette (Razie: designers need mind-meld knowledge).