@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,45 +1,14 @@
1
1
  # Documents: typed blocks, comments, suggestions, and artifacts
2
2
 
3
- `skill://dispatch` sends you here when you write a typed block (an `:::ask` or a callout), comment on
4
- or suggest a change to a document, upload an artifact, request a document's approval, or get
5
- `DOC_SCHEMA`, `INVALID_ASK_BLOCK` or `DOC_SERVICE_UNAVAILABLE` back. Changing a document's text,
6
- tables included, is [Editing a document](skill://dispatch/references/document-edits.md).
3
+ Read this to write a typed block, comment, suggest, upload an artifact, request approval, or handle `DOC_SCHEMA`, `INVALID_ASK_BLOCK` or `DOC_SERVICE_UNAVAILABLE`. Text and table edits are [Editing a document](skill://dispatch/references/document-edits.md).
7
4
 
8
5
  ## Typed blocks
9
6
 
10
- The server declares typed document blocks at `GET /api/v1/schema/blocks`. Write one only with the
11
- container-directive form `:::name{#block-id key="value"}` on its own line, ordinary block children,
12
- and a closing line of as many colons at the same nesting. A typed block directly inside another needs the outer
13
- one's fence a colon longer (`::::callout{…}` around a `:::callout{…}`), and so does one whose code holds a `:::` line;
14
- Dispatch writes its fences that way. An unclosed typed block at document level is rejected. An
15
- opening line that continues a paragraph instead of standing on its own (indented four or more
16
- columns under the paragraph's text) is refused, naming the line's number and text - `INVALID_OP` on an edit's `markdown` or `with`, `INVALID_MARKDOWN` on any other write - since it
17
- would be stored as the paragraph's text; start the block on its own line. An opening written inside
18
- a line is stored as text, and `dispatch issue` and `dispatch artifact` quote it back as a
19
- typed-block opening that is text, not a block. For
20
- a new typed block, omit `#block-id`; Dispatch mints it. When editing an existing typed block, retain
21
- its id and every rendered attribute. Never copy an existing block's id into new markdown: an id
22
- names one block, so an insert, upload or suggestion whose markdown names an id the document holds
23
- outside the text it replaces is refused naming the id: `INVALID_OP` for an insert,
24
- `INVALID_MARKDOWN` for any other write. To rewrite such a block whole, `delete` it and then
25
- `insert` the new one carrying its id, anchored on the block before or after it, in that order and
26
- in one batch: an insert carrying an id the document still holds is refused. An `ask` block whose ask
27
- is still open cannot be rewritten that way: `dispatch doc-edit` refuses the `delete`, so reword it with
28
- `replace`, relocate it with `move`, or change its question, options, urgency or `multiple` with
29
- `dispatch edit-ask` if you asked it ([Editing a document](skill://dispatch/references/document-edits.md)).
30
-
31
- Use only the type names, content rule, attributes, and enum values returned by the schema. Values are
32
- quoted: `:::callout{kind="warning" title="Risk"}`. Do not write Pandoc-style `::: {.callout}`, leaf
33
- `::name` directives, or text `:name` directives; those strings are literal when quoted inside a code
34
- block. Do not set attributes the schema marks `server: true`; the server ignores them and reasserts
35
- its authoritative value at settlement.
36
-
37
- Questions about a document must be `ask` blocks, never an `Open questions` prose section. An ask
38
- body is one or more question paragraphs followed by an optional bullet list of options, where each
39
- item is `Label: description`. A spec, an uploaded document or an uploaded version holding an ask that
40
- breaks that shape - a code block, heading or quote in it, a paragraph after its options, a second
41
- list - is refused with `INVALID_ASK_BLOCK`; so is an edit that writes one. An ask someone left
42
- unreadable in the browser refuses nothing it is carried through unchanged by. For example:
7
+ - Use only the types, content rules, attributes and enum values from `GET /api/v1/schema/blocks`. Quote values: `:::callout{kind="warning" title="Risk"}`. Never set an attribute marked `server: true`.
8
+ - Write the container form only: `:::name{#block-id key="value"}` on its own line, block children, and a closing line with the same number of colons. A block inside another, or one whose code holds a `:::` line, needs the outer fence one colon longer. Never write Pandoc `::: {.callout}`, leaf `::name` or text `:name`.
9
+ - Dispatch refuses an unclosed block, and an opening indented four or more columns under a paragraph. An opening inside a line is stored as text.
10
+ - For a new block, omit `#block-id`: Dispatch mints it. When you edit one, keep its id and every attribute. Never copy an id into new markdown. To rewrite a block whole, `delete` it, then `insert` it with its id, in one batch. You cannot do this to an open ask's block: use `replace`, `move` or `dispatch edit-ask`.
11
+ - Questions about a document are `ask` blocks, never an "Open questions" section. The body is question paragraphs, then an optional bullet list of `Label: description` options. A code block, heading or quote, a paragraph after the options, or a second list is `INVALID_ASK_BLOCK`.
43
12
 
44
13
  ```md
45
14
  :::ask{urgency="high" multiple="false"}
@@ -54,153 +23,42 @@ unknown cost before production while keeping today's release possible.
54
23
  :::
55
24
  ```
56
25
 
57
- When a human answers a decision written as an ask block, the answer lives on that ask. Use
58
- `dispatch resolve-ask` when the decision is resolved without a human response, or preserve the
59
- human's answer; never rewrite the question into its answer or blank its options. An edit that leaves
60
- an ask block without a question or with a blank option is rejected with `INVALID_ASK_BLOCK`.
61
-
62
- When `dispatch issue` or `dispatch artifact` answers `This spec holds no ask blocks …`, read it as a
63
- question: either no decision is needed and you say nothing, or you forgot to make it a block. When
64
- it answers `… typed-block openings in this document are text, not blocks`, the quoted openings are
65
- blocks stored as prose (inside a line, or a paste with something before every line): fix the markdown
66
- and upload again; a mention on purpose belongs in code. Neither answer sees a spec wrapped whole in a
67
- code fence (take the fence off), a malformed opening inside a line (`::ask{`, `:::ask {`: an ask opens
68
- only as `:::ask{…}` on a line of its own), or any `dispatch doc-edit`: after an edit that writes an
69
- ask, `dispatch doc-read` the section and check it renders as `:::ask{#<id> …}` on its own line.
26
+ - A human's answer lives on the ask. Never rewrite the question into its answer or blank its options. Resolve without a human with `dispatch resolve-ask`.
27
+ - An answered or resolved ask's question is fixed. Dispatch writes its block back. To ask something new, write a new block. An open ask's block is its text.
28
+ - `This spec holds no ask blocks …`: either no decision is needed, or you forgot the block. `… typed-block openings in this document are text, not blocks`: fix the markdown and upload again. Put an intended mention in code.
29
+ - Neither check sees a spec wrapped in a code fence, an opening like `::ask{` or `:::ask {`, or any `doc-edit`. After an edit that writes an ask, `dispatch doc-read` the section and check that it renders `:::ask{#<id> …}` on its own line.
70
30
 
71
31
  ## Comments and suggestions
72
32
 
73
- Add feedback with `dispatch comment` (`dispatch comment --help` lists its flags):
74
-
75
33
  ```bash
76
34
  dispatch comment --issue <KEY> --artifact spec --quote '<the passage>' --body '<the question or note>'
77
- ```
78
-
79
- It prints the comment's id; a `--reply-to-ask` reply also makes you one of the ask's followers
80
- (see [Following](skill://dispatch/references/asks.md)).
81
- `--ref` names the owner (an issue or project-document reference) in place of `--issue`/`--project`.
82
- An ask, comment or message link there is refused, since the comment would land outside it: reply
83
- under an ask with `--reply-to-ask`, in a comment's thread with `--reply-to`, and read a message
84
- with `dispatch read`.
85
- `--quote` requires `--artifact`; its anchor is pinned to the containing block while retaining the quote
86
- for display. Omit both for a floating issue comment. A reply (`--reply-to`/`--reply-to-ask`) takes no
87
- `--quote`; it belongs to its parent's anchor. Reply to any comment in a thread; the server keeps
88
- threads flat. A reply to a resolved thread reopens it, except a decided suggestion's: a reply joins
89
- that thread and the suggestion stays accepted or rejected. Use `--reply-to-ask` to reply directly under a
90
- question asked with `dispatch ask`; `--turn` (only with `--reply-to-ask`) says who holds the turn after
91
- the reply — `agent` for a progress note that keeps the ask waiting on you, `human` (the default) when
92
- the human needs to act; see "Asking" in `skill://dispatch`. Comments are edited only by their author from the
93
- dashboard. A delivered `comment.created` event carries the comment `id`; reply to it with
94
- `dispatch comment --reply-to <id>`.
95
-
96
- Resolve your own review comment once you have addressed it:
97
-
98
- ```bash
99
- dispatch resolve-comment --comment <id>
100
- ```
101
-
102
- `--comment` is the comment id, or a `dispatch://KEY/comment/<id>` or `dispatch://PROJECT/artifact/<slug>/comment/<id>` reference (an
103
- 8+ character id prefix is resolved against the owner's comments). It takes no reason —
104
- say what you did in a `--reply-to` first if the thread needs it. The server lets any session or human resolve any open comment, so
105
- resolve only threads you opened or were asked to close; reopening a resolved thread is human-only (from the dashboard), though your
106
- reply to it reopens it - except a decided suggestion's, which your reply joins and leaves accepted or rejected. A reply to a pending
107
- suggestion whose text an edit removed lands as well. Asks are closed with `dispatch resolve-ask` instead.
108
-
109
- An exact replacement for document text is a suggestion (`dispatch suggest`), never a comment; a
110
- comment is for a question or a note the human answers in words. A human accepts a suggestion with
111
- one click and cannot accept a comment, so propose the replacement instead of describing it:
112
-
113
- ```bash
114
35
  dispatch suggest --issue <KEY> --artifact spec --quote '<exact text>' --replace-with '<replacement>'
115
36
  ```
116
37
 
117
- It prints the suggestion's id; `--body` adds a note and `--occurrence` picks a repeated quote. A human accepts or rejects a suggestion.
118
- Errors: `TARGET_AMBIGUOUS` (add `--occurrence`), `TARGET_NOT_FOUND` (re-read first), `INVALID_ANCHOR`/`ANCHOR_MISSING`/`ANCHOR_ORPHANED`
119
- (bad, unwritten, or stale quote), `INVALID_MARKDOWN`/`DOC_SCHEMA` (malformed content), `CAP_EXCEEDED`, `ISSUE_CLOSED`.
120
- Suggest only what the quoted block can hold. The accept, not the suggestion, checks that: an
121
- accept whose replacement would break an ask block that was readable before it is refused with
122
- `INVALID_ASK_BLOCK` - a question given a code block, text after an ask's options, a second option
123
- list, or an emptied question; one that names an id the document holds outside the text it
124
- replaces, an ask under a held id included, with `INVALID_MARKDOWN`; and one no part of the
125
- document can hold where it sits (a code block over a table cell's whole text), or whose quote runs
126
- into an ask or callout from the text before it, with `INVALID_OP`. Either changes nothing: the human sees the reason with no Retry, and the suggestion
127
- stays open until someone rejects or replaces it.
38
+ - An exact replacement is a suggestion, never a comment: a human accepts it with one click. A comment is for a question or note answered in words.
39
+ - Omit `--quote` and `--artifact` for a floating comment. A reply (`--reply-to`, `--reply-to-ask`) takes no quote. Threads are flat. A reply reopens a resolved thread, except a decided suggestion's. `--turn` works only with `--reply-to-ask`.
40
+ - `--ref` names the owner only. Dispatch refuses an ask, comment or message link there.
41
+ - Resolve your own comment once addressed: `dispatch resolve-comment --comment <id>`. It takes no reason, so reply first if needed. Resolve only threads you opened or were asked to close. Reopening a resolved thread from the dashboard is human-only, but your reply to it reopens it, except a decided suggestion's.
42
+ - Suggest only what the quoted block can hold. The accept checks it, and a refused accept stays open.
43
+ - Error codes: `TARGET_AMBIGUOUS` (add `--occurrence`), `TARGET_NOT_FOUND` (re-read), `INVALID_ANCHOR` / `ANCHOR_MISSING` / `ANCHOR_ORPHANED` (bad or stale quote), `INVALID_MARKDOWN` / `DOC_SCHEMA`, `CAP_EXCEEDED`, `ISSUE_CLOSED`.
128
44
 
129
45
  ## Artifacts
130
46
 
131
- Attach an image, diagram, or local file with:
132
-
133
47
  ```bash
134
48
  dispatch artifact --issue <KEY> --name diagram.png --path ./diagram.png
135
- ```
136
-
137
- Or, when the text is already at hand, post a Markdown document directly:
138
-
139
- ```bash
140
49
  dispatch artifact --issue <KEY> --name load-test-results.md --content-file - <<'EOF'
141
50
  # Load test
142
- ...
143
51
  EOF
144
52
  ```
145
53
 
146
- Exactly one of `--issue` and `--project` is required. A project upload creates an unlinked project document; it takes no `--artifact`.
147
- Exactly one of `--path` and `--content` is required. It prints the document's slug and version.
148
- Uploading the same `--name` creates its next version — so uploading `spec.md` **replaces the issue's own specification**
149
- with your text. Never do that: the spec is edited in place with `dispatch doc-edit` (see [Editing a document](skill://dispatch/references/document-edits.md)). Address an existing
150
- artifact by the slug the upload printed or by its filename, and a project document by its artifact id, slug, or filename; the
151
- slug also arrives on `artifact.created` events. Dispatch suffixes a slug two documents would share, so one document's
152
- filename can be another's slug (`plan v2` takes `plan-v2`, then a document named `plan-v2` takes `plan-v2-2`): a bare
153
- `--artifact` that names both is refused with each one's id, while a `dispatch://` reference's document part is always the slug.
154
- A document you upload holding a copy of another document's `:::ask` block, under the same `#id` and with the same
155
- question, options, `multiple` and urgency, on the same issue (or the same project for a project document), opens no
156
- ask: the copy shows the state and answer of the ask it was copied from, names it and its document in `copied_from` and
157
- `copied_from_document`, and cannot be answered there. Answer the original: its answer or resolution shows on the copy a
158
- few seconds later. A copy may hold the original's earlier wording, from before someone reworded it. It stays a copy
159
- while the original is open, and shows an answer or resolution given while the original still asked that wording; an
160
- answer or resolution given after the rewording decides a question the copy does not ask, so the copy opens its own ask
161
- instead. A copy whose text you change opens a new ask. Once the original's block leaves its document, its copies share
162
- one new ask: the first copy to settle opens it and the others name it.
163
-
164
- An answered or resolved ask's question is fixed. Editing its block's question, options, `multiple` or urgency in the
165
- document, or uploading a version that changes them, does not change the ask: a few seconds later the block is written
166
- back to the question the answer was given on, beside its answer. To ask something new, write a new ask block with its
167
- own `#id`. An open ask's block is its text: edit it and the ask changes with it.
168
-
169
- A picture meant to be seen inline in a message, comment or ask is not uploaded with `dispatch artifact`: pass its local
170
- path with that command's `--image`, once per picture (PNG, JPEG, GIF or WebP by its bytes, at most 25 MiB each). Each is uploaded to the issue (a
171
- project document's project; for a reply to a direct message, your own conversation) and appended after a blank line as
172
- one `![<file name>](dispatch://<owner>/artifact/<slug>@vN)` line, about 60 characters that count toward the body or
173
- question cap; a command the lines would carry over the cap is refused with the count before anything uploads, and again,
174
- with nothing posted, in the rare case where Dispatch gives an upload a longer address than that (a later version of a
175
- name the owner already holds, or a slug another file took first). The `@vN` pins the version the upload made (the same
176
- file name again makes the next version). A plain `dispatch://KEY/artifact/<slug>` reference to an image stays a link
177
- with a thumbnail.
178
-
179
- `dispatch read` writes the pictures the messages, asks and comments it shows embed to files, newest first, at most 8 and
180
- 10 MiB per read, prints a `- picture: <path>` line for each, and its `Pictures:` section names each one shown, in order, and the rest by reference for
181
- `dispatch doc-read`, which shows one picture (at most 3,750,000 bytes, the 5 MB of base64 a model provider takes; a
182
- larger one or an SVG is described). Open each written file with your file-read tool. A picture in a
183
- conversation on the Agents page belongs to that conversation, `dispatch://agent/<session id>/artifact/<slug>@vN`, and
184
- `dispatch doc-read` reads it by that reference alone. On Oh My Pi an Inbox delivery carries its pictures as images; in
185
- Claude Code it stays text with the reference.
186
-
187
- A session is shown each picture once. A later read or delivery that embeds a picture you were already shown names it in
188
- `Pictures:` as `shown earlier this session` and sends no bytes, since every request carries the session's whole history
189
- and a model provider refuses one over 32 MB; `dispatch doc-read` always shows the picture, so ask it for one you need
190
- again, after compaction too.
191
-
192
- Documents are CommonMark. A bare `<https://example.com|text>` is a CommonMark autolink and is normalised: the angle brackets are
193
- dropped and the URL keeps `|text`. A backslash-escaped `\<https://example.com|text>` displays as `<https://example.com|text>` in the
194
- document but comes back re-escaped (`\<`) from `dispatch doc-read`. A Slack mrkdwn draft, or any other payload that is not Markdown,
195
- still belongs inside a fenced code block, where it survives verbatim both ways.
196
-
197
- A table cell ends at every `|` not written `\|`, inside inline code and links too, so write
198
- `` `x: Promise<void> \| undefined` ``, never `` `x: Promise<void> | undefined` ``, in a cell. A row
199
- holding text in a cell past its table's width is refused rather than stored without it, naming the
200
- row: write a `|` inside a cell as `\|`, or, where the row really has more cells, give the header and
201
- delimiter rows as many. Blank cells past the width are dropped, on every path. A spec, an upload or
202
- a version answers `INVALID_MARKDOWN`, an insert of blocks `INVALID_OP` on `markdown`, and an insert
203
- of bare table rows `TABLE_WIDTH`, which names the cell counts only.
54
+ - Uploading the same `--name` makes its next version. Never upload `spec.md`: it replaces the human's spec. Edit with `dispatch doc-edit`.
55
+ - Address an artifact by the slug the upload printed. A bare `--artifact` that names two documents (a slug and a filename) is refused with both ids. A `dispatch://` reference always uses the slug.
56
+ - A copy of another document's `:::ask` block (same `#id` and text, same owner) opens no ask. It mirrors the original. Answer the original. Change the copy's text and it opens its own ask.
57
+ - A picture from an Agents-page conversation is `dispatch://agent/<session id>/artifact/<slug>@vN`. `dispatch doc-read` reads it by that reference alone.
58
+ - Show a picture inline with `--image` on `message`, `comment` or `ask`, not `dispatch artifact`. Each adds about 60 characters that count toward the cap. A plain `dispatch://KEY/artifact/<slug>` link to an image shows a thumbnail.
59
+ - `dispatch read` and `dispatch doc-read` write pictures to files and print `- picture: <path>`. Open each with your file-read tool. A session sees each picture once. `dispatch doc-read` shows it again, after compaction too.
60
+ - Documents are CommonMark. Put Slack mrkdwn or other non-Markdown in a fenced code block.
61
+ - In a table cell, write every `|` as `\|`, inside code and links too. A row wider than its table is refused.
204
62
 
205
63
  ## Approval requests
206
64
 
@@ -208,64 +66,14 @@ of bare table rows `TABLE_WIDTH`, which names the cell counts only.
208
66
  dispatch request-approval --issue <KEY> --summary '<what the human is approving>'
209
67
  ```
210
68
 
211
- The command opens an approval ask with the options `Approve` and `Request changes`, its question
212
- "Approve spec.md (version N)?" followed by the summary, where N is the document's latest version. It
213
- is refused, with nothing sent, while that version holds a decision block open, and the refusal
214
- names each block and its ask. An answer or a `dispatch resolve-ask` closes the ask at once but
215
- reaches a version only when the document settles, about two seconds later. An answered block
216
- already carries its own record, so wait for that version rather than editing just to force one; a
217
- waiver carries none, so write the human's decision into the text with your next `dispatch doc-edit`
218
- before you request. A block written in the last few seconds counts as open before Dispatch has
219
- opened its ask. A document holds one open request. A new version moves it to that version, keeping
220
- its thread and summary, and leaves it waiting on you, as a human's reply in its thread does; a move
221
- your own edit made sends you no event, and `dispatch read` and `dispatch doc-read` show it as
222
- `Approval: awaiting, waiting on agent`. Run it again when "Approval of a spec" in `skill://dispatch`
223
- allows: that hands the same request back to the human, reworded first when `--summary` is new. Your
224
- own reply in its thread hands it back too, with no command and the summary it already holds, unless
225
- you post it with `--reply-to-ask` and `--turn agent` (`--reply-to` carries no turn, so its reply takes
226
- the default, `human`) or a new version has moved the request since your last
227
- `dispatch request-approval`. While it waits on the human, the same `--summary` changes
228
- nothing, and a different `--summary` is refused, since it would rewrite the card they are
229
- reading. The answer reaches you as `artifact.approved` or `artifact.changes_requested` with the
230
- pinned `version` and closes the request, so the next call opens a new one; `changes_requested`
231
- carries the reason, which is your next piece of work. Those reads show the document's approval
232
- state; `stale` means it was approved and changed since, other than as the next paragraph says.
233
-
234
- A human's own answer to a decision block in a document they approved can carry the approval to
235
- the version it writes. Dispatch compares that version with the version they approved, every
236
- decision block cut out of both; when the text outside the blocks is the same and every block added or
237
- answered since has their answer, it records an `approved` review in their name pinned to the new version and
238
- emits `artifact.approved`, in the transaction that writes the version, and answers an approval
239
- request open on the document `Approve` in their name. The answer was the whole change since the
240
- version they approved, so request nothing: `dispatch doc-read` shows `Approval: approved vN` at
241
- the new version. An edit inside the block before the answer does not stop this. A change
242
- outside the blocks, whoever wrote it (an upload or a typed edit included), a block added since the
243
- approval that the human has not answered (open or waived), a block the approved version held that
244
- someone else answered or that was waived since, a decided block whose question or options were
245
- changed (its answer decided the question it was given on), a removed block, a request for changes
246
- newer than the approval, or a document they never approved leaves the approval stale, and the next
247
- request shows them the diff: a request on a document a human approved earlier carries
248
- `approved` (`{version, at, by}`) in `ask.approval`, and its Inbox card puts
249
- `Approved at version N on <date> by <who>.` and a `Show diff` control under the question, which
250
- shows what changed between the two versions with every decision block cut out. So that request's
251
- `--summary` is one sentence naming what changed since that approval, and repeats nothing the diff
252
- shows.
69
+ - It opens an `Approve` / `Request changes` ask on the latest version. It is refused while a decision block is open. A block written in the last few seconds counts as open.
70
+ - An answer or resolve reaches a version about two seconds later. Wait for that version, do not edit to force one. A waiver carries no record: write the decision into the text before you request.
71
+ - A document holds one open request. A new version moves it and leaves it `waiting on agent`. Run the command again when "Approval of a spec" allows, to hand it back. Your own thread reply hands it back too, unless you reply with `--reply-to-ask` and `--turn agent`. A `--reply-to` reply takes no turn flag, so it takes the default, `human`. Exception: a new version moved the request since your last `dispatch request-approval`. Then no reply hands it back: run `dispatch request-approval` again. While it waits on the human, a different `--summary` is refused.
72
+ - The answer arrives as `artifact.approved` or `artifact.changes_requested` with its version. `changes_requested` carries the reason: that is your next work. `stale` means approved, then changed.
73
+ - A human's own answer to a block can carry their approval forward. That needs no change outside the blocks, and their answer on every new or answered block. Then `dispatch doc-read` shows `Approval: approved vN`. Anything else leaves it stale, and the card shows a diff: make the next `--summary` one sentence on what changed.
253
74
 
254
75
  ## A document that is reloading
255
76
 
256
- These calls can answer `DOC_SERVICE_UNAVAILABLE` (HTTP 503), because each writes a document inside its
257
- transaction: `dispatch doc-edit`; `dispatch ask` and `dispatch comment` on a quote; a `dispatch comment` reply
258
- in a thread whose first comment is anchored; `dispatch suggest`; `dispatch resolve-comment` on an anchored
259
- comment; `dispatch artifact` replacing a document that already exists; and, on an ask that lives in a `:::ask`
260
- block, `dispatch edit-ask` and `dispatch resolve-ask`, which write that block. Creating an issue with a spec,
261
- uploading a new document, `dispatch request-approval` and `dispatch message` never answer it, and neither do
262
- `dispatch edit-ask` and `dispatch resolve-ask` on an ask that has no block. It means that document's live room
263
- failed and is reloading from its durable copy, so the server refused rather than wait for it; your call wrote
264
- nothing and the document is intact. Nothing retries it for you: the Dispatch client hands a 503 straight back.
265
- Wait a few seconds and make the same call again. A second refusal in a row is worth telling your human about,
266
- with the document's reference.
267
-
268
- `dispatch doc-read` can answer it too, though it writes nothing: a read never opens a live room, and waits out
269
- a room that is reloading, so it is refused only when the document's durable copy cannot be read or decoded.
270
- Retry it the same way.
271
-
77
+ - `DOC_SERVICE_UNAVAILABLE` (503) means the document's live room is reloading. Your call wrote nothing. Nothing retries for you. Wait a few seconds and repeat the same call.
78
+ - A second refusal in a row: tell the human, with the document's reference.
79
+ - It comes from calls that write a document. Those are `doc-edit`, a quoted `ask` or `comment`, a reply in an anchored thread, and `suggest`. Also `resolve-comment` on an anchored comment, an `artifact` that replaces a document, and `edit-ask` / `resolve-ask` on a block ask. `doc-read` returns it only when the durable copy is unreadable.
@@ -1,12 +1,8 @@
1
1
  # Before and after: a decision block, a reply, a message, and a draft
2
2
 
3
- `skill://dispatch` sends you here for worked examples: a design decision in its document, a reply
4
- that names its mechanism, a message that should not be sent, and a draft placed where the human
5
- reads it.
6
-
7
3
  ## Before / after
8
4
 
9
- Before — a wall of text hides the decision and the human never receives it:
5
+ Before: a wall of text hides the decision, and the human never gets it.
10
6
 
11
7
  ```text
12
8
  The deploy branch has the migration and dashboard changes. Staging is fine, but release notes are
@@ -14,8 +10,7 @@ not reviewed before tomorrow's customer demo. Review the notes, ship without the
14
10
  dashboard from the release. Waiting is safest, but the list above may be stale.
15
11
  ```
16
12
 
17
- After — write the decision into the document section it concerns: state the problem, and make each
18
- genuinely different option a button, so the answer stays with the release design:
13
+ After: a decision block in the section it concerns, each real option a button.
19
14
 
20
15
  ```bash
21
16
  dispatch doc-edit --issue LEGION-815 --artifact spec --ops-json-file - <<'EOF'
@@ -27,35 +22,27 @@ dispatch doc-edit --issue LEGION-815 --artifact spec --ops-json-file - <<'EOF'
27
22
  EOF
28
23
  ```
29
24
 
30
- Before — a progress note that nobody needs, posted where humans look for decisions:
25
+ Before: a progress note nobody needs.
31
26
 
32
27
  ```bash
33
28
  dispatch message --issue LEGION-815 --body 'Merged the release PR, moving to docs next.'
34
29
  ```
35
30
 
36
- After — nothing. The merge is visible on the pull request; the docs work shows up as its own deliverable. Post a message only when
37
- a human must act or a deliverable is theirs to use:
31
+ After: nothing. The PR shows the merge. Post only when a human must act or can use a deliverable:
38
32
 
39
33
  ```bash
40
34
  dispatch message --issue LEGION-815 --body 'Release 1.4 is live on the devbox (dispatch://LEGION-815/artifact/release-notes). Nothing needed from you.'
41
35
  ```
42
36
 
43
- Before — a draft the human must read is uploaded as a separate file, the spec only names it, and
44
- the ask does not point at it, so the reader has to go looking:
37
+ Before: the draft is a separate file, the spec only names it, and the ask does not link it.
45
38
 
46
39
  ```bash
47
40
  dispatch artifact --issue OPS-52 --name cu-update-2026-09-15.md --content 'Hi team, ...'
48
41
  dispatch doc-edit --issue OPS-52 --artifact spec \
49
42
  --ops-json '[{"op":"insert","after":"## Context","markdown":"## Draft (artifact cu-update-2026-09-15.md)"}]'
50
- dispatch ask --issue OPS-52 \
51
- --question 'Customers need an update today, but the draft is only in a separate file, so the reader cannot review it in context. How should we proceed? Recommendation: put the draft in the spec before sending it.' \
52
- --option 'Put the draft in the spec: Adds a spec edit before sending but lets the reader review it in context.' \
53
- --option 'Keep the separate file: Saves the spec edit but leaves the reader to find the draft.'
54
43
  ```
55
44
 
56
- After — the draft is a section of the spec, and the ask anchors there. Sending it is a to-do only a
57
- human can complete, so it stays a standalone ask. If it really must be a file, the spec and the ask
58
- both link the slug the upload printed:
45
+ After: the draft is a spec section, and the ask (a human-only send) anchors there. A real file is linked by its slug from both.
59
46
 
60
47
  ```bash
61
48
  dispatch doc-edit --issue OPS-52 --artifact spec \
@@ -64,7 +51,7 @@ dispatch ask --issue OPS-52 --anchor-json '{"artifact":"spec","quote":"Hi team,"
64
51
  --question 'Customers need an update today, and the reviewed text is ready in the spec. Sending it cannot be recalled. How should we proceed? Recommendation: send the reviewed update.' \
65
52
  --option 'Send the reviewed update: Delivers the update today but makes its text external.' \
66
53
  --option 'Hold the update: Avoids sending now but leaves customers without the update.'
67
- # or, for a real file — the spec links it where the reader needs it, and so does the ask:
54
+ # or, for a real file:
68
55
  dispatch doc-edit --issue OPS-52 --artifact spec \
69
56
  --ops-json '[{"op":"insert","after":"## Context","markdown":"## Draft\n\nThe update to send: dispatch://OPS-52/artifact/cu-update-2026-09-15-md"}]'
70
57
  dispatch ask --issue OPS-52 --ref dispatch://OPS-52/artifact/cu-update-2026-09-15-md \
@@ -75,8 +62,7 @@ dispatch ask --issue OPS-52 --ref dispatch://OPS-52/artifact/cu-update-2026-09-1
75
62
 
76
63
  ## Naming the mechanism
77
64
 
78
- Before — a reply explaining a design paraphrases its tool, its route and its event away, so the
79
- reader has to ask which tool, and how Legion "notices" anything:
65
+ Before: the reply paraphrases its tool, route and event away.
80
66
 
81
67
  ```text
82
68
  Today, when a spec is ready, the architect tells Legion so with a dedicated call on its Legion
@@ -84,8 +70,7 @@ tool, and Legion then waits for your approval. This change removes that call, be
84
70
  notice your approval of the spec by itself.
85
71
  ```
86
72
 
87
- After — the reader's sentence first, then each mechanism by its real name, with how it works in a
88
- clause:
73
+ After: the reader's sentence first, then each mechanism by name, with how it works in a clause.
89
74
 
90
75
  ```text
91
76
  For you nothing changes: you still click Approve on the spec. What goes is a step the architect
@@ -97,6 +82,4 @@ version, which Dispatch does when you click Approve on the request the architect
97
82
  document from Dispatch itself and waits for the same event.
98
83
  ```
99
84
 
100
- "A dedicated call", "tells" and "notice" each stood for something the reader can search for, find
101
- in a log, or set. None is a noun anyone coined, so each is named; the clause after each name is
102
- what keeps the reply readable on a phone.
85
+ "A dedicated call", "tells" and "notice" each stood for something the reader can search, find in a log, or set.