@sjawhar/pi-envoy 10.0.0 → 10.1.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.
package/dist/dispatch.js CHANGED
@@ -14290,12 +14290,12 @@ var dispatchToolSpecs = [
14290
14290
  {
14291
14291
  name: "dispatch_request_approval",
14292
14292
  example: { issue: "DSP-1", summary: "A live sync replaces the nightly export." },
14293
- description: "Ask a human to approve a document at its current version. Before calling, have a fresh read-only reader check the spec against the code and the human's words, then resolve every finding; a Legion architect uses `plan-gap-analyst`. Opens an approval ask (Approve / " + "Request changes) in the human's Inbox whose question names the document and version, " + "followed by the summary; the answer pins a review to that version and arrives as " + "artifact.approved or artifact.changes_requested. An open request follows the document: a " + "later version moves it to that version and leaves it waiting on you, as a human's reply in " + "its thread does. Only the first move since the request was opened or handed back sends an " + "event, and never to the session whose version made it; dispatch doc-read shows whom it " + "waits on. Once the revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ", call this again to hand that same Inbox row back. The request carries nothing new. A " + "call while it already waits on the human hands nothing back: the same summary changes " + "nothing, and a different one is refused, since it would rewrite the card the human is " + "reading. Approve and Request changes each close the request, so the next call opens a new " + "one. Call it once per revision, when the revision is complete, never after each edit. An " + "approval goes stale when the document changes after it: request approval again once that " + "revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ". A new version of a Legion root spec closes its armed design gate until a human approves " + "it. " + "Refused, with nothing sent, while the document holds an open decision block, even when a " + "human asked for approval: the refusal names each block; ask the human to answer or waive " + "it first. " + OWNER_REFERENCE,
14293
+ description: "Ask a human to approve a document at its current version. Before calling, have a fresh read-only reader check the spec against the code and the human's words, then resolve every finding; a Legion architect uses `plan-gap-analyst`. Opens an approval ask (Approve / " + "Request changes) in the human's Inbox whose question names the document and version, " + "followed by the summary; the answer pins a review to that version and arrives as " + "artifact.approved or artifact.changes_requested. An open request follows the document: a " + "later version moves it to that version and leaves it waiting on you, as a human's reply in " + "its thread does. Only the first move since the request was opened or handed back sends an " + "event, and never to the session whose version made it; dispatch doc-read shows whom it " + "waits on. Once the revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ", call this again to hand that same Inbox row back. The request carries nothing new. A " + "call while it already waits on the human hands nothing back: the same summary changes " + "nothing, and a different one is refused, since it would rewrite the card the human is " + "reading. Approve and Request changes each close the request, so the next call opens a new " + "one. Call it once per revision, when the revision is complete, never after each edit. An " + "approval goes stale when the document changes outside its decision blocks after it: " + "request approval again once that revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ", with a one-sentence summary naming what changed since the earlier approval: the card " + "names that approval (version, date, reviewer) and its Show diff control carries the detail. " + "A human's own answer to a decision block carries the approval to the version it writes when " + "that answer is the whole change since the approved version, so nothing is requested for " + "it. A new version of a Legion root spec closes its armed design gate until a human " + "approves it; the carried approval reopens it too. " + "Refused, with nothing sent, while the document holds an open decision block, even when a " + "human asked for approval: the refusal names each block; ask the human to answer or waive " + "it first. " + OWNER_REFERENCE,
14294
14294
  arguments: (z2) => ({
14295
14295
  issue: z2.string().describe(ISSUE_REFERENCE).optional(),
14296
14296
  project: z2.string().describe("Project key owning the document.").optional(),
14297
14297
  artifact: z2.string().describe("Project document artifact id, slug, or filename; primary document by default for an issue.").optional(),
14298
- summary: z2.string({ min: 1 }).describe(`What the human is approving, in one to three sentences, and nothing else: no commentary on itself or the conversation, and no question. Request approval only once ${HUMAN_AGREED_TO_DOCUMENT}.`)
14298
+ summary: z2.string({ min: 1 }).describe(`What the human is approving, in one to three sentences, and nothing else: no commentary on itself or the conversation, and no question; after an earlier approval, one sentence naming what changed since it, since the card shows that approval and a diff. Request approval only once ${HUMAN_AGREED_TO_DOCUMENT}.`)
14299
14299
  }),
14300
14300
  validation: documentOwnerValidation(true)
14301
14301
  },
@@ -16785,7 +16785,7 @@ function approvalLine(artifact) {
16785
16785
  case "approved":
16786
16786
  return `Approval: approved v${approval.version} by ${approval.by?.id ?? "unknown"}`;
16787
16787
  case "stale":
16788
- return `Approval: approved v${approval.version} by ${approval.by?.id ?? "unknown"}, edited since (now v${approval.latest_version}) - request approval again once the human has agreed to every point in this version`;
16788
+ return `Approval: approved v${approval.version} by ${approval.by?.id ?? "unknown"}, changed since (now v${approval.latest_version}) - the human's own answer to a decision block carries the approval when that answer is the whole change since v${approval.version}; for any other change, request approval again once the human has agreed to every point in this version, with a --summary naming what changed since v${approval.version}`;
16789
16789
  case "changes_requested":
16790
16790
  return `Approval: changes requested on v${approval.version} by ${approval.by?.id ?? "unknown"}: ${approval.reason ?? ""}`;
16791
16791
  }
@@ -17234,7 +17234,7 @@ async function refuseOpenDecisionBlocks(client, tool, resolved) {
17234
17234
  const asks = new Map(documentAsks.map((ask) => [ask.block_id, ask]));
17235
17235
  const lines = version2.markdown.split(`
17236
17236
  `);
17237
- const stillOpen = (named, state) => state === "answered" ? `${named}, answered but still open in version ${latest}: it settles into a version on its own in about two seconds; wait, then request again` : `${named}, ${state} but still open in version ${latest}: write the decision into the text with dispatch doc-edit, which writes a version that carries it`;
17237
+ const stillOpen = (named, state) => state === "answered" ? `${named}, answered but still open in version ${latest}: it settles into a version on its own in about two seconds; wait for that version` : `${named}, ${state} but still open in version ${latest}: write the decision into the text with dispatch doc-edit, which writes a version that carries it`;
17238
17238
  const open = blocks.flatMap((block) => {
17239
17239
  const ask = asks.get(block.id);
17240
17240
  const openers = lines.filter((line) => line.includes(`ask{#${block.id} `) || line.includes(`ask{#${block.id}}`));
@@ -17263,7 +17263,7 @@ async function refuseOpenDecisionBlocks(client, tool, resolved) {
17263
17263
  throw new Error([
17264
17264
  `dispatch ${commandName(tool)} was not called: ${artifact.name} (version ${latest}) has ${count}. Answering one writes a new version, which would move this request to that version and leave it waiting on you.`,
17265
17265
  ...open.map((line) => `- ${line}`),
17266
- "Do not request approval over an open block, even when a human asked for it. Tell the human which block is open and ask them to answer it or to waive it. Once it is answered, it settles into a version on its own in about two seconds; wait, then request again. Edit the document only where the answer changes design text outside the block, never to restate it. If they waive it, close the block with dispatch resolve-ask (--kind resolved, their words as the --reason) and write their decision into the text with dispatch doc-edit. Then request approval again once the human has agreed to every point in the new version: the call opens the request, or hands an open one back to the human."
17266
+ "Do not request approval over an open block, even when a human asked for it. Tell the human which block is open and ask them to answer it or to waive it. Once it is answered, it settles into a version on its own in about two seconds. When the human approved an earlier version and their answer is the whole change since it, Dispatch carries the approval to the new version in their name: request nothing. When the answer changes design text outside the block, rewrite that text (never to restate the answer), then request approval again once the human has agreed to every point in the new version, with a one-sentence --summary naming what changed since the earlier approval. On a document nobody has approved, wait for that version, then request. If they waive it, close the block with dispatch resolve-ask (--kind resolved, their words as the --reason), write their decision into the text with dispatch doc-edit, then request approval again once the human has agreed to every point in the new version. The call opens the request, or hands an open one back to the human."
17267
17267
  ].join(`
17268
17268
  `));
17269
17269
  }
@@ -18054,7 +18054,7 @@ ${trailer.join(`
18054
18054
  });
18055
18055
  if (result.ask === null) {
18056
18056
  return {
18057
- text: `${resolved.artifact.name} (document id ${resolved.artifact.id}) is already approved at version ${result.version} by ${result.approval.by?.id ?? "unknown"}; no new request was opened. An edit after approval makes it stale, so request again only for a new version, once the human has agreed to every point in it.`,
18057
+ text: `${resolved.artifact.name} (document id ${resolved.artifact.id}) is already approved at version ${result.version} by ${result.approval.by?.id ?? "unknown"}; no new request was opened. A change outside the decision blocks after approval makes it stale, so request again only for such a version, once the human has agreed to every point in it, with a --summary naming what changed since version ${result.version}; the human's own answer to a decision block carries the approval when that answer is the whole change.`,
18058
18058
  details: {
18059
18059
  ...resolved.owner.kind === "project" ? documentResultDetails(resolved.artifact) : { issue: resolved.issue?.key },
18060
18060
  artifact: resolved.artifact.id,
@@ -18065,7 +18065,7 @@ ${trailer.join(`
18065
18065
  const details = await followedAskDetails(client, result.ask, resolved.artifact);
18066
18066
  const outcome = result.recorded ? `Approval requested for ${resolved.artifact.name} (document id ${resolved.artifact.id}) at version ${result.version} (ask ${result.ask.id}).` : `The approval request for ${resolved.artifact.name} (document id ${resolved.artifact.id}) at version ${result.version} (ask ${result.ask.id}) already waits on the human, so this call changed nothing: nothing since it last reached the human (a newer version, a human's reply in its thread, or your progress note) left it waiting on you.`;
18067
18067
  return {
18068
- text: `${outcome} The human's Inbox asks: ${JSON.stringify(result.ask.question)}. The answer arrives as artifact.approved or artifact.changes_requested. An edit before the answer moves this request to the new version and leaves it waiting on you, and an edit after approval makes the approval stale: either way, request again for the new version once the human has agreed to every point in it, which hands this request back or opens a new one.`,
18068
+ text: `${outcome} The human's Inbox asks: ${JSON.stringify(result.ask.question)}. The answer arrives as artifact.approved or artifact.changes_requested. An edit before the answer moves this request to the new version and leaves it waiting on you, and a change outside the decision blocks after approval makes the approval stale: either way, request again for the new version once the human has agreed to every point in it, which hands this request back or opens a new one, with a --summary naming what changed since the earlier approval. The human's own answer to a decision block carries the approval when that answer is the whole change since the approved version, and answers an open request Approve in their name: request nothing then.`,
18069
18069
  details: { ...details, artifact: resolved.artifact.id, version: result.version }
18070
18070
  };
18071
18071
  }
package/dist/envoy.js CHANGED
@@ -30277,12 +30277,12 @@ var dispatchToolSpecs = [
30277
30277
  {
30278
30278
  name: "dispatch_request_approval",
30279
30279
  example: { issue: "DSP-1", summary: "A live sync replaces the nightly export." },
30280
- description: "Ask a human to approve a document at its current version. Before calling, have a fresh read-only reader check the spec against the code and the human's words, then resolve every finding; a Legion architect uses `plan-gap-analyst`. Opens an approval ask (Approve / " + "Request changes) in the human's Inbox whose question names the document and version, " + "followed by the summary; the answer pins a review to that version and arrives as " + "artifact.approved or artifact.changes_requested. An open request follows the document: a " + "later version moves it to that version and leaves it waiting on you, as a human's reply in " + "its thread does. Only the first move since the request was opened or handed back sends an " + "event, and never to the session whose version made it; dispatch doc-read shows whom it " + "waits on. Once the revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ", call this again to hand that same Inbox row back. The request carries nothing new. A " + "call while it already waits on the human hands nothing back: the same summary changes " + "nothing, and a different one is refused, since it would rewrite the card the human is " + "reading. Approve and Request changes each close the request, so the next call opens a new " + "one. Call it once per revision, when the revision is complete, never after each edit. An " + "approval goes stale when the document changes after it: request approval again once that " + "revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ". A new version of a Legion root spec closes its armed design gate until a human approves " + "it. " + "Refused, with nothing sent, while the document holds an open decision block, even when a " + "human asked for approval: the refusal names each block; ask the human to answer or waive " + "it first. " + OWNER_REFERENCE,
30280
+ description: "Ask a human to approve a document at its current version. Before calling, have a fresh read-only reader check the spec against the code and the human's words, then resolve every finding; a Legion architect uses `plan-gap-analyst`. Opens an approval ask (Approve / " + "Request changes) in the human's Inbox whose question names the document and version, " + "followed by the summary; the answer pins a review to that version and arrives as " + "artifact.approved or artifact.changes_requested. An open request follows the document: a " + "later version moves it to that version and leaves it waiting on you, as a human's reply in " + "its thread does. Only the first move since the request was opened or handed back sends an " + "event, and never to the session whose version made it; dispatch doc-read shows whom it " + "waits on. Once the revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ", call this again to hand that same Inbox row back. The request carries nothing new. A " + "call while it already waits on the human hands nothing back: the same summary changes " + "nothing, and a different one is refused, since it would rewrite the card the human is " + "reading. Approve and Request changes each close the request, so the next call opens a new " + "one. Call it once per revision, when the revision is complete, never after each edit. An " + "approval goes stale when the document changes outside its decision blocks after it: " + "request approval again once that revision is complete and " + HUMAN_AGREED_TO_DOCUMENT + ", with a one-sentence summary naming what changed since the earlier approval: the card " + "names that approval (version, date, reviewer) and its Show diff control carries the detail. " + "A human's own answer to a decision block carries the approval to the version it writes when " + "that answer is the whole change since the approved version, so nothing is requested for " + "it. A new version of a Legion root spec closes its armed design gate until a human " + "approves it; the carried approval reopens it too. " + "Refused, with nothing sent, while the document holds an open decision block, even when a " + "human asked for approval: the refusal names each block; ask the human to answer or waive " + "it first. " + OWNER_REFERENCE,
30281
30281
  arguments: (z2) => ({
30282
30282
  issue: z2.string().describe(ISSUE_REFERENCE).optional(),
30283
30283
  project: z2.string().describe("Project key owning the document.").optional(),
30284
30284
  artifact: z2.string().describe("Project document artifact id, slug, or filename; primary document by default for an issue.").optional(),
30285
- summary: z2.string({ min: 1 }).describe(`What the human is approving, in one to three sentences, and nothing else: no commentary on itself or the conversation, and no question. Request approval only once ${HUMAN_AGREED_TO_DOCUMENT}.`)
30285
+ summary: z2.string({ min: 1 }).describe(`What the human is approving, in one to three sentences, and nothing else: no commentary on itself or the conversation, and no question; after an earlier approval, one sentence naming what changed since it, since the card shows that approval and a diff. Request approval only once ${HUMAN_AGREED_TO_DOCUMENT}.`)
30286
30286
  }),
30287
30287
  validation: documentOwnerValidation(true)
30288
30288
  },
@@ -213,11 +213,11 @@ field, and choosing your next issue are in [Working an issue](skill://dispatch/r
213
213
  ## Asking
214
214
 
215
215
  Two kinds of question reach a human. A decision about the design a document records is a decision
216
- block in that document ([Decision blocks](#decision-blocks)), whatever phase the work is in and
217
- whether or not the document was approved: a block in an approved document makes the approval
218
- stale, which is right. A Legion phase worker sends such a decision to its architect, which writes
219
- the block (`skill://legion-worker`). A to-do or permission only a human can give, or a decision
220
- with no document to live in, is a `dispatch ask`. The gates below apply to both.
216
+ block in that document ([Decision blocks](#decision-blocks)), at every phase, approved or not: a
217
+ block in an approved document leaves the approval stale until the answer, which carries it
218
+ forward when it is the whole change (below). A Legion phase worker sends it to its architect,
219
+ which writes the block (`skill://legion-worker`). A to-do or permission only a human can give, or
220
+ a decision with no document to live in, is a `dispatch ask`. The gates below apply to both.
221
221
 
222
222
  ### Before you ask
223
223
 
@@ -368,33 +368,33 @@ See [Following](#following) for why you receive what happens to asks you open an
368
368
  ## Approval of a spec
369
369
 
370
370
  Approval is a property of a document, not a question you phrase: a human approves a specific
371
- version, the way a pull-request review approves a commit, and any later version makes that
372
- approval stale. A later version also moves an open request to that version and leaves it waiting
373
- on you until you request again, which hands the same request back to the human. Answering a
374
- decision block writes a new version, so request approval only when all three hold: every decision
375
- block is settled, which means answered or waived as the next paragraph
376
- says; the human has agreed to every point in the spec; and the current version has not been
377
- approved. A Legion root spec under an armed design gate always goes to approval once all three
378
- hold (`skill://legion-architect`).
371
+ version, the way a pull-request review approves a commit, and a later version leaves that approval
372
+ stale, unless the human's own answer to a decision block is the whole change since the version
373
+ they approved; then Dispatch records an `approved` review in their name at that version and emits
374
+ `artifact.approved`, so request nothing. When the answer changes text outside its block, rewrite
375
+ that text, run the fresh reader below on it and request again. A later version also moves an open
376
+ request with it, waiting on you until you request again. Request only when all three hold: every
377
+ decision block is settled (answered or waived, below); the human has agreed to every point in the
378
+ spec; and the current version has not been approved. A Legion root spec under an armed design gate
379
+ always goes to approval once all three hold (`skill://legion-architect`).
379
380
 
380
381
  Before calling `dispatch request-approval`, have a fresh read-only reader check the current spec
381
- against the code and the human's words, then resolve every finding. A Legion architect uses its
382
- `plan-gap-analyst`; another session uses the read-only reader its host supplies.
383
-
384
- When all three hold, request it in the pass that finishes the spec: a design waiting with nothing in
385
- the human's Inbox waits on nobody. When a human asks for approval while a block is open, do not
386
- request it and do not hold it silently: name each open block and ask them to answer it or waive
387
- it. For a waiver, close the block with `dispatch resolve-ask --kind resolved` (their words as
388
- `--reason`), then write their decision into the text in their words and request.
389
- `dispatch request-approval` refuses while any block is open.
382
+ against the code and the human's words, then resolve every finding. A Legion architect uses
383
+ `plan-gap-analyst`, another session the read-only reader its host supplies. When all three hold,
384
+ request in the pass that finishes the spec: a design waiting with nothing in the human's Inbox
385
+ waits on nobody. When a human asks for approval while a block is open, neither request it nor hold
386
+ it silently: name each open block and ask them to answer or waive it. For a waiver, close it with
387
+ `dispatch resolve-ask --kind resolved` (their words as `--reason`), write their decision into the
388
+ text in their words and request. `dispatch request-approval` refuses while any block is open.
390
389
 
391
390
  An approval request carries nothing new: a point the human has not agreed to gets its own decision
392
391
  block first, with your recommendation, or, when it is a choice you can make yourself
393
392
  ([Before you ask](#before-you-ask), gate 1) and the human will not want a say in it, comes out of
394
393
  the spec and is made where the work happens; an inference you cannot defend in a decision block
395
394
  comes out of the spec. `--summary` says in one to three sentences what the human is approving and
396
- nothing else: no commentary on itself or on the conversation, and no open question. The Inbox
397
- shows it after "Approve spec.md (version N)?". Never write "Approve" options into an ordinary
395
+ nothing else: no commentary on itself or on the conversation, and no open question; after an
396
+ earlier approval, one sentence naming what changed since it, since the card shows that approval
397
+ and its `Show diff` control carries the detail. Never write "Approve" options into an ordinary
398
398
  `dispatch ask`; only humans approve. The call, its result and its answer:
399
399
  [Approval requests](skill://dispatch/references/documents.md#approval-requests).
400
400
 
@@ -226,7 +226,27 @@ nothing, and a different `--summary` is refused, since it would rewrite the card
226
226
  reading. The answer reaches you as `artifact.approved` or `artifact.changes_requested` with the
227
227
  pinned `version` and closes the request, so the next call opens a new one; `changes_requested`
228
228
  carries the reason, which is your next piece of work. Those reads show the document's approval
229
- state; `stale` means it was approved and then edited.
229
+ state; `stale` means it was approved and changed since, other than as the next paragraph says.
230
+
231
+ A human's own answer to a decision block in a document they approved can carry the approval to
232
+ the version it writes. Dispatch compares that version with the version they approved, every
233
+ decision block cut out of both; when the text outside the blocks is the same and every block added or
234
+ answered since has their answer, it records an `approved` review in their name pinned to the new version and
235
+ emits `artifact.approved`, in the transaction that writes the version, and answers an approval
236
+ request open on the document `Approve` in their name. The answer was the whole change since the
237
+ version they approved, so request nothing: `dispatch doc-read` shows `Approval: approved vN` at
238
+ the new version. An edit inside the block before the answer does not stop this. A change
239
+ outside the blocks, whoever wrote it (an upload or a typed edit included), a block added since the
240
+ approval that the human has not answered (open or waived), a block the approved version held that
241
+ someone else answered or that was waived since, a decided block whose question or options were
242
+ changed (its answer decided the question it was given on), a removed block, a request for changes
243
+ newer than the approval, or a document they never approved leaves the approval stale, and the next
244
+ request shows them the diff: a request on a document a human approved earlier carries
245
+ `approved` (`{version, at, by}`) in `ask.approval`, and its Inbox card puts
246
+ `Approved at version N on <date> by <who>.` and a `Show diff` control under the question, which
247
+ shows what changed between the two versions with every decision block cut out. So that request's
248
+ `--summary` is one sentence naming what changed since that approval, and repeats nothing the diff
249
+ shows.
230
250
 
231
251
  ## A document that is reloading
232
252
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-envoy",
3
- "version": "10.0.0",
3
+ "version": "10.1.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "omp": {