@sjawhar/opencode-legion-envoy 8.17.0 → 8.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,227 +1,65 @@
1
1
  # Working an issue: choosing, claiming, status, priority, and the backlog
2
2
 
3
- `skill://dispatch` sends you here when you pick your next issue, claim or release one, get
4
- `409 ISSUE_CLAIMED`, move an issue's status or priority, reorder a board, reassign an issue, sync a
5
- project's architecture model, or list or audit a project's backlog.
3
+ Read this to choose, claim or release an issue, or to handle `409 ISSUE_CLAIMED`. Read it to move status or priority, reorder a board, reassign, sync an architecture model, or audit a backlog.
6
4
 
7
5
  ## Choosing what to work on
8
6
 
9
- When you finish an issue, or are told to work on the next thing, take the top ready issue of the
10
- whole backlog, across every project: status `todo`, highest priority first, then board rank. There
11
- are no areas: a standing role, a product owner and a lane each take the top issue like everyone
12
- else. `todo` means ready: specced, unblocked, and waiting on neither a deploy nor a
13
- decision. An issue that waits on one belongs in `backlog`, with what it waits on said on the issue.
14
-
15
- Hold at most three issues in flight (`in_progress`, `testing`, `needs_review` or `retro`), of any
16
- kind. The limit is per agent and has nothing to do with the week's priorities: the priorities
17
- decide only what you pull next. Past three:
18
- push any unfinished work, say where in one comment on the issue, move it to `backlog` and clear
19
- its route. Each issue counts on its own; a child does not ride under its parent's slot.
20
- In-flight issues with no owner at all go
21
- back to `backlog` as well: no claim or route held by a live session, no Dispatch activity in the
22
- last day, and no pull request moving on GitHub (an owner working there leaves no Dispatch trace).
23
- The order keeper sweeps those. Never write the status of an issue that carries the `legion`
24
- label, or of any issue under one: the Legion daemon writes those statuses. A status your session
25
- writes on the root of a tree Legion is running is set back and the tree's architect told who wrote
26
- it; only a person in the dashboard, the controller's `set_status`, or the operator stops that tree. On an issue under one, a
27
- status that takes it out of the flow parks that issue and stops its workers.
28
-
29
- One agent keeps the backlog's order against those priorities. Setting an
30
- issue's priority stays yours ([Priority is yours to set](#priority-is-yours-to-set)); reordering
31
- the board does not.
32
- When the top of the backlog looks wrong, or a priority's next step is not yet a ready issue,
33
- publish it to `notifications.role.backlog-order`, which the order keeper holds, instead of
34
- reordering the board yourself.
7
+ - When you finish an issue, or are told to take the next thing, take the top ready issue of the backlog, across every project. Ready means status `todo`, sorted by priority, then board rank. No areas: a standing role, a product owner and a lane take the top issue too.
8
+ - `todo` means ready: specced, unblocked, waiting on no deploy and no decision. An issue that waits on one goes in `backlog`, with what it waits on said on the issue.
9
+ - Hold at most three issues in flight (`in_progress`, `testing`, `needs_review`, `retro`), of any kind, per agent. A child counts on its own. Priorities decide only what you pull next. Past three: push unfinished work, say where in one comment, move it to `backlog` and clear its route.
10
+ - An in-flight issue with no owner goes back to `backlog`. No owner means no claim or route held by a live session, no Dispatch activity in a day, and no PR moving on GitHub. The order keeper sweeps those.
11
+ - Never write the status of an issue with the `legion` label or under one. A status you write on a running Legion root is set back and its architect is told. Only a person in the dashboard, the controller's `set_status`, or the operator stops that tree. On a child, a status out of the flow parks it and stops its workers.
12
+ - Set priority yourself. Never reorder the board: one agent keeps the order. When the top looks wrong, or a priority's next step is not a ready issue, publish to `notifications.role.backlog-order`.
35
13
 
36
14
  ## Claim the issue before you work it
37
15
 
38
- Before you start implementing an issue, claim it:
39
-
40
16
  ```bash
41
17
  dispatch claim --issue LEGION-234 # I am implementing this
42
18
  dispatch claim --issue LEGION-234 --release # I have stopped; it is free
43
19
  ```
44
20
 
45
- A claim records **your** session — the one making the call, never another — and shows on every
46
- read of the issue: the dashboard header, the issue list and board, `dispatch read` (a
47
- `Claimed by:` line) and `dispatch issues` (a claim on the row). A session's claim there ends
48
- `· not running` when the live agent registry does not list that session, as the dashboard's chip
49
- does — that claim is free to take — and `· liveness unknown` when the registry could not be read,
50
- which says nothing either way. `dispatch issues` plus the dashboard's **Unclaimed** filter is how
51
- you find work nobody is on.
52
-
53
- - **`409 ISSUE_CLAIMED` means someone else holds this issue.** When it is another session, the
54
- refusal names it and says it is still running: do not work the issue in parallel — message
55
- that session (its id is in the message; `envoy_send` reaches it) or pick up something else,
56
- and tell the human if you believe the work should be yours. When a **human** holds it, the
57
- refusal names the person and says nothing about a session running, because there is none to
58
- message: ask them with `dispatch ask` instead, so the open ask appears in their Inbox, and
59
- never assume their claim has lapsed — only a human releases or forces a human's claim.
60
- - **`409 CLAIM_CONTENDED` means the issue changed hands twice while your call ran**, so nothing
61
- was applied and nobody's liveness was checked. Read the issue and decide again; it is not a
62
- refusal by a live holder.
63
- - **A claim whose session has ended is yours to take.** If the Envoy listener no longer lists
64
- the holder, your claim simply succeeds; the takeover is recorded on the issue and the session
65
- that lost it is told.
66
- - **Release it when you stop** — finished, handing over, or moving to something else. A claim is
67
- released by its holder or any human — and by any agent once the holder's session is no longer
68
- running, the same rule that lets you take it. Closing the issue releases it for you.
69
- - A claim is intent to implement, not contact: reading the issue, commenting, asking, or gating
70
- its pull request claims nothing, so a coordinator never collides with an implementer.
71
-
72
- **Claiming and moving the status are two separate actions, and you do both.** A claim says which
73
- session is on the work; the status says where the work has got to, and humans use it to track
74
- that too. So when you start: `dispatch claim --issue <KEY>` **and**
75
- `dispatch issue-update --issue <KEY> --status in_progress`.
21
+ - A claim records your own session. Reads show it (`Claimed by:`). `· not running` means the holder is gone and you can take it. `· liveness unknown` says nothing. Find free work with `dispatch issues` and the dashboard's **Unclaimed** filter.
22
+ - `409 ISSUE_CLAIMED` from a live session: never work it in parallel. Message that session (`envoy_send`) or take other work, and tell the human if you think it should be yours. From a human: ask them with `dispatch ask`. Never assume a human's claim lapsed. Only a human releases or forces it.
23
+ - `409 CLAIM_CONTENDED`: nothing applied. Read the issue and decide again.
24
+ - Release when you stop. The holder, any human, or any agent once the holder's session ended can release it.
25
+ - Claiming moves no status. Do both when you start.
76
26
 
77
27
  ## Issue status is yours to move
78
28
 
79
- The issue's status is how a human sees delivery without asking a session. Outside Legion (where
80
- the daemon writes it), the session doing the work moves it, the way a person moves a card:
81
- `in_progress` when implementation starts, `testing` when the change is being proven on a
82
- production-like surface, `needs_review` when its pull request is open and waiting on the merge
83
- queue, `done` when the change has been driven in production (a merge is not `done`). Move child
84
- issues you own as well as the root. An issue left at `triage` while work is underway is a defect.
85
- Waiting for the deploy lane is not a status and is never announced.
86
-
87
- ```bash
88
- # PATCH /api/v1/issues/{key} — status, title, labels, priority, external links (merged by URL, or cleared by an empty list), route, parent, blocked_by, repo
89
- dispatch issue-update --issue PROJ-175 --status testing
90
- dispatch issue-update --issue PROJ-175 --status done --reason 'Shipped in owner/repo#7; verified on the production dashboard.'
91
- dispatch issue-update --issue PROJ-175 --priority 1 # 0–3; see Priority is yours to set
92
- dispatch issue-update --issue PROJ-175 --external-link https://github.com/owner/repo/pull/7
93
- dispatch issue-update --issue PROJ-175 --parent PROJ-170 # same-project key; --parent '' clears it
94
- dispatch issue-update --issue PROJ-175 --repo acme/widgets # mapped to the project; --repo '' clears it
95
- ```
96
-
97
- Closing takes a `--reason`, and the command refuses `--status done` without one: it posts the reason on
98
- the issue as a message, then closes it, because a closed issue refuses messages, comments, and
99
- artifacts, so a reason left for later has nowhere to go. When the close fails after the post, the
100
- error names the posted message; after a timeout or a server error it also says the close may have
101
- landed, so read the issue's status first. A retry points its reason at the posted message rather
102
- than repeating it.
103
-
104
- The three clears differ: `--clear-priority` sends null, `--parent ''`, `--route ''` and
105
- `--repo ''` clear with an empty string, and `--clear-external-links` / `--clear-blocked-by` send an
106
- empty list. Guessing the wrong shape is a refusal either way.
107
-
108
- An issue targets one repository: its own `--repo`, else its nearest ancestor's, else the project's
109
- default (set on the Settings page), else none. A repository not mapped to the issue's project is
110
- refused `REPO_NOT_MAPPED`, naming it. `dispatch read` prints the result as
111
- `Repository: owner/name (own)`, `Repository: owner/name (inherited or project default)`, or
112
- `Repository: none`. `Repository: unknown (…)` means the Dispatch server is older than repository
113
- fields: the read still works, and a `--repo` write there fails rather than drop the repository.
114
-
115
- Link the pull request that delivers the issue with `--external-link` when you open it; the issue page
116
- renders its state and checks from that link, and `dispatch read` lists it under `External links:`.
117
- The command is authenticated with the same bearer as every
118
- other `dispatch` command: a Legion pane reads it from the `DISPATCH_TOKEN_FILE` path the daemon sets on
119
- the pane; any other session's `dispatch` command reads `dispatch.token` from the `envoy.json` its
120
- host's plugin read, which the plugin hands it in `ENVOY_CONFIG_FILE`. By that plugin's rule, that
121
- is an OMP session's profile directory under an omp profile other than `default`, a Claude Code
122
- session's `CLAUDE_CONFIG_DIR` (its subagents' too) or an OpenCode session's `OPENCODE_CONFIG_DIR`,
123
- else the file `ENVOY_CONFIG_FILE` names, else `~/.config/legion/envoy.json`.
124
-
125
- A write to an issue still in `triage` answers once with `… is still in triage …`; move the status
126
- when work has started.
29
+ - Move it as a person moves a card, root and owned children: `in_progress`, `testing`, `needs_review`, then `done` once driven in production. A merge is not `done`. An issue left in `triage` while work runs is a defect. Waiting for the deploy lane is not a status and is never announced.
30
+ - `--status done` needs `--reason`. Dispatch posts it as a message, then closes. If the close fails after the post, read the status first. A retry points its reason at the posted message.
31
+ - Clears differ: `--clear-priority`, `--parent ''` / `--route ''` / `--repo ''`, `--clear-external-links` / `--clear-blocked-by`. See `dispatch issue-update --help`.
32
+ - Repository: own `--repo`, else nearest ancestor's, else the project default, else none. Unmapped is `REPO_NOT_MAPPED`. `dispatch read` shows `Repository:`. `Repository: unknown (…)` is an older server: a `--repo` write there fails.
33
+ - Link the delivering PR with `--external-link` when you open it.
34
+ - `… is still in triage …` on a write: move the status once work starts.
127
35
 
128
36
  ## Priority is yours to set
129
37
 
130
- Priority is the coarse bucket a backlog is read by: `0` is P0, the highest, through `3`, P3, the
131
- lowest, and `null` clears it. Agents set it (`dispatch://LEGION/artifact/issue-status-conventions-md`)
132
- — on creation, and on a grooming pass over issues that have none — and say what you set and why;
133
- the human overrides anything they disagree with from the dashboard. A closed
134
- issue takes only `rank`, `components`, a reopening `status` (any status but `done`), and an
135
- external-links write that adds no new link (so a link can move to the issue that replaced it);
136
- everything else, `priority` included, waits for the reopen (`409 ISSUE_CLOSED`). So reopen it
137
- first, then set the priority — the two cannot go in one command. `rank` itself is not a flag:
138
- reorder it the way [Issue reads](#board-rank-priority-and-assignee-on-a-read) describes, through `PATCH /api/v1/issues/{key}`.
38
+ - `0` (P0, highest) to `3` (P3), `null` clears. Set it on creation and on grooming passes over issues with none. Say what you set and why. The human overrides from the dashboard.
39
+ - A closed issue takes only `rank`, `components`, a reopening status, and an external-links write that adds no link. Reopen first, then set priority, in two commands (`409 ISSUE_CLOSED`).
40
+ - Labels are optional. Dispatch trims them, keeps their case, and drops case-insensitive duplicates.
139
41
 
140
42
  ## Board rank, priority, and assignee on a read
141
43
 
142
- Issue reads include `rank`, the server-owned ordering key used by project boards; reorder through `PATCH /api/v1/issues/{key}` with `{"rank": {"before": "<key>", "after": "<key>"}}`, either neighbor optional and both in the issue's project. A bearer caller also names its own session in that body, `"actor": {"kind": "session", "id": "<your session id>"}`, or the server refuses with `ACTOR_KIND`. They also include nullable coarse priority (`P0` highest through `P3` lowest) and `assignee`: the lowercase email of the person who answers the issue's asks, or `null` when nobody holds it. `dispatch read` of an issue prints it as `Assignee: <email>` or `Assignee: unassigned`.
44
+ - Reads carry `rank`, nullable priority, and `assignee`: a lowercase email, or `null`. `dispatch read` prints `Assignee: unassigned` for `null`.
45
+ - Reorder with `PATCH /api/v1/issues/{key}` and `{"rank": {"before": "<key>", "after": "<key>"}}` (either optional, same project). A bearer also sends `"actor": {"kind": "session", "id": "<your session id>"}`, or gets `ACTOR_KIND`.
143
46
 
144
47
  ## Reading a project's backlog
145
48
 
146
- To see the shape of a project rather than find a phrase, list its issues:
147
- ```bash
148
- dispatch issues --project <KEY>
149
- ```
150
- Each row carries the issue key, title, status, priority, parent, labels, its open-ask count, and
151
- when it last changed — a roadmap or backlog pass without opening every issue. Filter with `--status`
152
- (a lifecycle status), `--parent` (one issue's children), `--label`, `--priority` (repeated, `0`–`3`, with
153
- `none` for an issue with no priority: `--priority 0 --priority 1` is every P0 and P1), `--route-status` (below), or
154
- `--updated-since` (an RFC3339 timestamp, for "what moved this week"). `--limit` is the page size, 50 by
155
- default and 250 at most, and `--offset` is where the page starts; the output says how many issues
156
- match. Repeating with the next offset walks every matching issue only while the list does not
157
- change: an issue that enters or leaves what your filters match, or whose status or rank changes,
158
- between two pages shifts rows across a page boundary, and the walk then shows one issue twice and
159
- misses another.
160
-
161
- This is not search: it matches no text. Use `dispatch search` for a keyword or phrase, and
162
- `dispatch issues` when you want every issue in a project and its current state.
49
+ `dispatch issues --project <KEY>` lists every issue with status, priority, parent, labels, open asks and last change. It is not search. Filters and paging are in `--help`. A page walk is exact only while the list holds still.
163
50
 
164
51
  ### The owner audit
165
52
 
166
- As the owner of a surface, list the project's P0 and P1 issues and staff or close each one nobody
167
- has started:
168
- ```bash
169
- dispatch issues --project <KEY> --priority 0 --priority 1 --limit 250
170
- ```
171
- Every unclaimed row in `triage`, `icebox`, `backlog` or `todo` is a decision: someone takes it and
172
- builds it, or it closes. A row in `in_progress`, `testing`, `needs_review` or `retro`, or one that
173
- carries a claim, is work under way ([Issue status is yours to move](#issue-status-is-yours-to-move))
174
- and is not re-staffed. A todo with a finished spec reads as queued work that nobody is doing.
175
-
176
- A close that says the defect cannot happen cites the code that makes it impossible. An issue
177
- closed because a rewrite forecloses it names the file and line in the rewrite that does so; a
178
- close that cannot name one is not foreclosed, it is unread. The cheapest way for a rewrite to reach
179
- parity is to port the code, defect included.
180
-
181
- The audit finds four shapes:
182
-
183
- - **Unstaffed work.** A plan or measurement exists, and no one is building it.
184
- - **Unrecorded delivery.** An issue not yet in `testing` or `done`, claimed or not, has a merged PR
185
- naming it. Check the change live, then move the issue.
186
- - **Unrecorded practice.** Someone does the issue's work by hand, more than once, while the issue
187
- sits in backlog. It leaves no plan and no PR to find; the tell is your own messages. Doing
188
- something by hand more than once means an issue is wearing the wrong status.
189
- - **Unreachable route.** An open issue whose route names a role nobody holds, or a session that is
190
- not running, reaches nobody, whatever its priority, and the priority filter above never finds
191
- it. List it on its own:
192
- ```bash
193
- dispatch issues --project <KEY> --route-status no_holder --limit 250
194
- ```
195
- Each row reads `route role:sre (nobody holds it right now)` or `route session:<id> (that session
196
- is not running right now)`. That is one read of the listener, and one read cannot tell a
197
- restart gap from a vacancy: an agent box that restarts or resumes keeps the session id, but the
198
- session is absent from the listener for minutes, and its role with it.
199
- So a route is unowned only when it is `no_holder` on two reads at least ten minutes apart: list
200
- again after ten minutes and act on the issues both lists name. Confirm with the second
201
- `dispatch issues` read, not `envoy_role_get`: a role lookup releases the claim of a holder whose
202
- session is absent from the registry as it answers. Then staff the role, re-route the
203
- issue to a live holder, or clear the route and assign it. `--route-status unknown` means the
204
- listener did not answer, so a route could not be judged; a `no_holder` filter refuses rather
205
- than answer an empty list then.
206
-
207
- Run the audit as a step of a coordinator's loop, at each checkpoint, not as a habit: these shapes
208
- are found by running the check, not by noticing them.
209
-
210
- ## Search paging
211
-
212
- `skill://dispatch` sends you here when a `dispatch search` page is not enough: more hits remain,
213
- or a kind runs out before the page does.
214
-
215
- A page holds `--limit` hits (20 by default, 50 at most); the first line names how many match
216
- (`showing 1-20 of 312`), and, while more can be reached, the last line names the next `--offset`.
217
- Each kind lists at most its best 100, so when the output says the rest cannot be paged to, narrow
218
- the query or name a `--project`.
53
+ As a surface's owner, run `dispatch issues --project <KEY> --priority 0 --priority 1 --limit 250` at each checkpoint of a coordinator's loop. These shapes show up only when you run the check.
219
54
 
220
- ## Syncing a project's architecture model
55
+ - Each unclaimed row in `triage`, `icebox`, `backlog` or `todo` is a decision: someone builds it, or it closes. Rows in flight or claimed are not re-staffed.
56
+ - A close that says the defect cannot happen cites the code that prevents it. A close by rewrite names the file and line that forecloses it. Without one, the issue is unread, not foreclosed: a rewrite reaches parity most cheaply by porting the defect.
57
+ - Find four shapes:
58
+ - **Unstaffed work**: a plan or measurement exists, nobody builds it.
59
+ - **Unrecorded delivery**: a merged PR names an issue not yet in `testing` or `done`. Check it live, then move it.
60
+ - **Unrecorded practice**: someone does the issue's work by hand more than once. The tell is your own messages. Fix the status.
61
+ - **Unreachable route**: the priority filter above never finds it, whatever its priority. List it on its own with `dispatch issues --project <KEY> --route-status no_holder --limit 250`. A route is unowned only when two reads ten minutes apart both list it, since a restarting session is absent for minutes. Check with the second `dispatch issues`, not `envoy_role_get`, which releases an absent holder's claim. Then staff the role, re-route to a live holder, or clear the route and assign. `unknown` means the listener did not answer.
221
62
 
222
- Import a project's architecture model from its configured source repository now (a human configures the source in Settings):
223
- ```bash
224
- dispatch architecture-sync --project CORE
225
- ```
226
- It prints the imported commit, or the recorded error when the model was rejected — the previous model stays up. Without a configured source it answers 404 `SOURCE_NOT_FOUND`.
63
+ ## Syncing a project's architecture model
227
64
 
65
+ `dispatch architecture-sync --project CORE` imports the model now. It prints the commit, or the error, and keeps the old model. No source configured answers `SOURCE_NOT_FOUND`.
@@ -1,76 +1,31 @@
1
1
  # Answering targeted and direct messages
2
2
 
3
- `skill://dispatch` sends you here when a Dispatch frame targets you as BTW, Aside or Steer, or a
4
- human messages you directly from the Agents page.
3
+ Read this when a Dispatch frame targets you as BTW, Aside or Steer, or a human messages you from the Agents page.
5
4
 
6
5
  ## Targeted agent messages
7
6
 
8
- A human — or any bearer caller over HTTP, such as a test rig — can target the issue message at a
9
- live Envoy session or role as **BTW**, **Aside**, or **Steer** (the dashboard calls a steer
10
- **Send**). The incoming Dispatch frame names
11
- the issue and includes a `reply_with` hint (`{ command }`, the `dispatch` command line that answers it, with `...` for
12
- the body); reply on the same open issue with that command, never a new targeted send:
7
+ - A human (or a bearer over HTTP) can target an issue message at your session or role. The modes are **BTW**, **Aside** or **Steer** (the dashboard says **Send**). The frame names the issue and a `reply_with` hint.
8
+ - Reply on that issue with that command, never a new targeted send:
13
9
 
14
10
  ```bash
15
11
  dispatch message --issue CORE-1 --in-reply-to <targeted-message-id> --body 'The requested answer.'
16
12
  ```
17
13
 
18
- `--in-reply-to` correlates the answer under the asker's message in its Conversation card. A BTW
19
- delivery can post its answer automatically; use this call when the frame asks the primary agent to
20
- reply. A human may reply to your message in turn — the follow-up arrives as a targeted frame whose
21
- `in_reply_to` names your message and whose `reply_body` quotes it; answer it the same way,
22
- `dispatch message --issue <KEY> --in-reply-to <their reply id> --body-file -`, so the exchange reads as one
23
- thread. `dispatch message` itself never carries `target` or `delivery`: agent-to-agent traffic goes
24
- through Envoy or Oh My Pi's `agent://` messages. A bearer that targets over HTTP names its own
25
- session in `actor` (`{kind: "session", id}`), and the card shows that session as the author.
26
- `GET /api/v1/agents` (any authenticated caller) lists live sessions with their capabilities
27
- (`aside`, `btw`, `steer`); target only a session that advertises the mode you want. Sending to a
28
- session with no issue (`POST /api/v1/agents/{session_id}/messages`) stays human-only.
14
+ - A BTW can post its answer automatically. Reply yourself when the frame asks the primary agent to.
15
+ - A human's reply to you arrives as a frame with `in_reply_to` and `reply_body`. Answer it the same way, with their reply's id.
16
+ - `dispatch message` never carries `target` or `delivery`. Agent-to-agent traffic goes over Envoy or `agent://`.
17
+ - A bearer that targets over HTTP names its session in `actor` (`{kind: "session", id}`). Target only a session that `GET /api/v1/agents` lists with that mode. Sending to a session with no issue is human-only.
29
18
 
30
19
  ## Answering a direct message
31
20
 
32
- A human can also message you directly from the **Agents** page, with no issue at all. On Oh My
33
- Pi, a person's **Send** or **Aside** arrives as their own user message, exactly as if they had
34
- typed it at your terminal: your Envoy plugin takes it only once Dispatch accepts it as a person's
35
- own fresh message to you, and runs the text Dispatch stored. Answer it in the conversation as
36
- you would anything typed, with no `dispatch message`; the Agents page shows your conversation
37
- live, so they read your answer there.
38
-
39
- A Send or Aside that starts with `/` runs as the command it names, as it would at your terminal:
40
- a prompt template or command file arrives as the user message it expands to, a `/skill:<name>`
41
- as that skill's prompt, and slash text that names no command as the words themselves; answer each
42
- as you would typed. A command that runs without reaching you (`/session`, `/compact`), or that
43
- did not run (one only your own terminal runs, such as `/new`), is answered on Dispatch by your
44
- plugin, as your reply to that message: what the command printed, or why it did not run. You
45
- receive nothing for it and write nothing for it. A command that prints and then submits a prompt
46
- (`/force:<tool> <prompt>`) gets the same reply, and you answer only the prompt it submitted.
47
-
48
- Everything else still arrives as a Dispatch frame: a **BTW**, a broadcast, a direct message on a
49
- host that takes no user turn from its plugin (Claude Code), and one Dispatch did not accept.
50
- That frame names no issue and its `reply_with` hint carries none either; answer it with the
51
- message's bare id in `--in-reply-to`, alone:
21
+ - On Oh My Pi, an Agents-page **Send** or **Aside** arrives as a user message. Answer in the conversation, with no `dispatch message`.
22
+ - A text that starts with `/` runs as that command. Answer what it expands to as typed. A command that never reaches you (`/session`, `/compact`, `/new`) is answered by your plugin: write nothing. For `/force:<tool> <prompt>`, answer only the prompt.
23
+ - Everything else arrives as a Dispatch frame with no issue. That is a BTW, a broadcast, a direct message on Claude Code, or one Dispatch did not accept. Answer with the bare id and no `--issue`:
52
24
 
53
25
  ```bash
54
26
  dispatch message --in-reply-to <the direct message's id> --body 'The requested answer.'
55
27
  ```
56
28
 
57
- Leave `--issue` out — there is no issue to post into, and naming one would file your answer on
58
- unrelated work. Dispatch threads the reply under their message in the same conversation, and the
59
- human sees it in your conversation on the Agents page, where it shows as an unread reply until
60
- they read it. Every other message still names its issue, so keep the `--issue`
61
- the frame gave you whenever it gave you one; a `dispatch://KEY/message/<id>` reference names the
62
- issue its message lives on, so that form is a reply on that issue, not a direct message.
63
-
64
- Have more to say after you answered? Run it again with the same `--in-reply-to` and the new text:
65
- Dispatch threads that follow-up under your first reply, and the output names the reply it
66
- follows. The same text again posts nothing, so a retry is safe. Your host may already have
67
- answered a **BTW** automatically before you got here; a second call is then your follow-up to
68
- that answer, so read the output before writing again.
69
-
70
- Read the whole conversation back — their message and every reply, yours included — with the
71
- message id alone; it has no issue:
72
-
73
- ```bash
74
- dispatch read --message <the direct message's id, or any reply's>
75
- ```
76
-
29
+ - Naming an issue would file your answer on unrelated work. Keep `--issue` whenever the frame gave one. A `dispatch://KEY/message/<id>` names its issue.
30
+ - More to say: run it again with the same `--in-reply-to`. The same text posts nothing, so a retry is safe. Your host may have answered a BTW already: read the output before you write again.
31
+ - Read the whole conversation back with `dispatch read --message <id>`.
@@ -1,49 +1,18 @@
1
1
  # Reading Dispatch back, and the reference forms
2
2
 
3
- `skill://dispatch` sends you here when you catch up after a restart, read an issue, ask, comment,
4
- message or document, trace what cites a node, or need the exact `dispatch://` form for a reference.
3
+ Read this to catch up after a restart, read a node, trace what cites it, or write a `dispatch://` reference.
5
4
 
6
5
  ## What comes back
7
6
 
8
- After a restart, catch up with `dispatch read` (`--issue`, or `--project` and `--artifact`, or `--ref`):
9
-
10
- ```bash
11
- dispatch read --issue <KEY>
12
- ```
13
-
14
- With an issue ref, it prints the issue summary, open asks, references, and recent events. With a project
15
- document owner or ref, it prints a document summary. With an ask ref, it prints that ask's
16
- question, options, state, answer, and its reply thread. With a comment ref, it prints that comment and its quoted reply chain. With a
17
- message ref, it prints that message and its reply chain. Reads do not subscribe; use `dispatch doc-read` for document contents.
18
-
19
- An anchored comment or ask also prints `Position:`, where its quote's block stands — `table[3] › row 5 (Red-teamer loop), column Due`
20
- is the fourth top-level block, a table, its row 5 (row 0 is the header; the index `delete_row` takes), labelled by the row's cells
21
- before the anchored one, in the column headed Due; outside a table it is the path of types and child indexes down to the block. The
22
- same facts are `anchor_block` on `GET /api/v1/comments/{id}` and `GET /api/v1/asks/{id}`, and
23
- `GET /api/v1/artifacts/{id}/blocks/{block_id}` answers them for any block id a document holds. When Dispatch could not read the
24
- document, the read still answers and prints `Position: unavailable (DOC_SERVICE_UNAVAILABLE)` (try again shortly),
25
- `Position: unavailable (DOC_SCHEMA)` (the document needs repair) or `Position: unavailable (INTERNAL)`; the API carries that
26
- code as `anchor_block_error`.
27
-
28
- Every read ends with two sections from the reference graph. `Referenced by:` lists what points at the node — every document, ask,
29
- comment, or message that cites it, plus its structure: child issues, attached documents, anchored and owned asks and comments, replies,
30
- followers — and `Links:` lists what it cites. Each row is `- <edge kind> <node kind> dispatch://… (<excerpt> · <when>)`; for a
31
- document source the excerpt is the start of the block holding the mention, and a whole list is one block, so every issue named in
32
- one list previews the list's first item. When a document references many issues and each backlink should read right, give each
33
- issue its own paragraph (or block), not an item of one list. Cross-project, always: a message on another project's issue that
34
- cites an ask shows up under that ask. So "what led to this decision" is one `dispatch read` on the ask, and "who relies on this
35
- document" one read on the document. Cite with `dispatch://` references (below) whenever you name a node in a body — a bare id or
36
- title is invisible to the graph.
7
+ - After a restart, catch up with `dispatch read --issue <KEY>` (or `--project` with `--artifact`, or `--ref`). It prints the issue's summary, open asks, references and recent events, or an ask's, comment's or message's thread. Reads do not subscribe. Use `dispatch doc-read` for document text.
8
+ - An anchored comment or ask prints `Position:`, where its quote's block stands. `unavailable (DOC_SERVICE_UNAVAILABLE)` means try again shortly. `unavailable (DOC_SCHEMA)` means the document needs repair.
9
+ - The API gives the same facts as `anchor_block` (or `anchor_block_error`) on `GET /api/v1/comments/{id}` and `GET /api/v1/asks/{id}`. `GET /api/v1/artifacts/{id}/blocks/{block_id}` gives them for any block.
10
+ - Each read ends with `Referenced by:` (what cites the node) and `Links:` (what it cites), across projects. "What led to this decision" is one read on the ask.
11
+ - A whole list is one block, so every issue named in one list previews the list's first item. Give each issue its own paragraph when each backlink should read right.
12
+ - Cite with `dispatch://` whenever you name a node. A bare id or title is invisible to the graph.
37
13
 
38
14
  ## Reference forms
39
15
 
40
- Use these in document, ask, comment, and message bodies. In the dashboard, a reference renders
41
- as an inline link whose text is the target's title (an issue's title, an ask's question, a
42
- comment's first line, a document's name) once it resolves; a body that is only a bare reference
43
- still gets an unfurl card instead. Every `--ref` flag below (and `--issue`/`--project`) accepts
44
- either form — an issue key or a project key is never ambiguous, since a project key never
45
- contains a dash:
46
-
47
16
  ```text
48
17
  dispatch://KEY
49
18
  dispatch://KEY/spec
@@ -56,10 +25,6 @@ dispatch://PROJECT/artifact/<document-ref>/ask/<id>
56
25
  dispatch://PROJECT/artifact/<document-ref>/comment/<id>
57
26
  ```
58
27
 
59
- A bare UUID or `KEY#seq` is not a reference; the `dispatch://` form is what Dispatch links and records. `dispatch read` also
60
- accepts the dashboard URL of an issue, spec, artifact, ask, comment, or project document on the configured server, or on its public
61
- dashboard when `DISPATCH_PUBLIC_URL` names one (it maps to the `dispatch://` form above), and an issue's read names its page
62
- (`Link:`, on that public dashboard when there is one), the link to hand a person. An ask or comment id may be a unique prefix of at least 8 hex characters; a message id is always the
63
- full uuid. A non-uuid id on `GET /asks/{id}`, `/comments/{id}`, or `/issues/{key}/messages/{id}` is a 400 `ASK_ID_INPUT` /
64
- `COMMENT_ID_INPUT` / `MESSAGE_ID_INPUT`, never a 500.
65
-
28
+ - A reference renders as a link titled by its target. A body that is only a reference gets an unfurl card.
29
+ - A bare UUID or `KEY#seq` is not a reference. `dispatch read` also takes a dashboard URL, also on the public dashboard when `DISPATCH_PUBLIC_URL` names one. An issue read prints its `Link:`: hand that to a person.
30
+ - An ask or comment id can be a unique 8+ hex prefix. A message id is always the full UUID.