@llblab/pi-actors 0.25.0 → 0.26.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.
Files changed (91) hide show
  1. package/BACKLOG.md +4 -8
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +1 -1
  4. package/dist/lib/actor-worker.d.ts +3 -0
  5. package/dist/lib/actor-worker.js +54 -6
  6. package/dist/lib/coordinator.js +31 -4
  7. package/dist/recipes/actor-worker.json +10 -6
  8. package/dist/recipes/lens-swarm.json +0 -2
  9. package/dist/recipes/pipeline-architect-coordinator.json +0 -2
  10. package/dist/recipes/pipeline-artifact-bundle.json +0 -2
  11. package/dist/recipes/pipeline-artifact-report.json +0 -2
  12. package/dist/recipes/pipeline-artifact-write.json +0 -2
  13. package/dist/recipes/pipeline-async-run-ops.json +0 -2
  14. package/dist/recipes/pipeline-checkpoint-continuation.json +0 -2
  15. package/dist/recipes/pipeline-development-tasking.json +0 -2
  16. package/dist/recipes/pipeline-docs-maintenance.json +0 -2
  17. package/dist/recipes/pipeline-media-library.json +0 -2
  18. package/dist/recipes/pipeline-quorum-review.json +0 -2
  19. package/dist/recipes/pipeline-release-readiness.json +0 -2
  20. package/dist/recipes/pipeline-release-summary.json +0 -2
  21. package/dist/recipes/pipeline-repo-health.json +0 -2
  22. package/dist/recipes/pipeline-research-synthesis.json +0 -2
  23. package/dist/recipes/pipeline-review-readiness.json +0 -2
  24. package/dist/recipes/pipeline-room-swarm.json +0 -2
  25. package/dist/recipes/subagent-artifact.json +0 -2
  26. package/dist/recipes/subagent-checkpoint.json +0 -2
  27. package/dist/recipes/subagent-conflict-report.json +0 -2
  28. package/dist/recipes/subagent-contradiction-map.json +0 -2
  29. package/dist/recipes/subagent-critic.json +0 -2
  30. package/dist/recipes/subagent-evidence-map.json +0 -2
  31. package/dist/recipes/subagent-followup.json +0 -2
  32. package/dist/recipes/subagent-judge.json +0 -2
  33. package/dist/recipes/subagent-merge.json +0 -2
  34. package/dist/recipes/subagent-message.json +0 -2
  35. package/dist/recipes/subagent-normalize.json +0 -2
  36. package/dist/recipes/subagent-plan.json +0 -2
  37. package/dist/recipes/subagent-prompt.json +0 -2
  38. package/dist/recipes/subagent-quorum.json +0 -2
  39. package/dist/recipes/subagent-review-coordinator.json +0 -2
  40. package/dist/recipes/subagent-review.json +0 -2
  41. package/dist/recipes/subagent-task-card.json +0 -2
  42. package/dist/recipes/subagent-tools.json +0 -2
  43. package/dist/recipes/subagent-verify.json +0 -2
  44. package/dist/recipes/subagents-prompts.json +0 -2
  45. package/dist/skills/actors/SKILL.md +2 -2
  46. package/dist/skills/swarm/SKILL.md +1 -1
  47. package/docs/actor-messages.md +1 -1
  48. package/docs/template-recipes.md +2 -2
  49. package/lib/actor-worker.ts +62 -6
  50. package/lib/coordinator.ts +33 -4
  51. package/package.json +1 -1
  52. package/recipes/actor-worker.json +10 -6
  53. package/recipes/lens-swarm.json +0 -2
  54. package/recipes/pipeline-architect-coordinator.json +0 -2
  55. package/recipes/pipeline-artifact-bundle.json +0 -2
  56. package/recipes/pipeline-artifact-report.json +0 -2
  57. package/recipes/pipeline-artifact-write.json +0 -2
  58. package/recipes/pipeline-async-run-ops.json +0 -2
  59. package/recipes/pipeline-checkpoint-continuation.json +0 -2
  60. package/recipes/pipeline-development-tasking.json +0 -2
  61. package/recipes/pipeline-docs-maintenance.json +0 -2
  62. package/recipes/pipeline-media-library.json +0 -2
  63. package/recipes/pipeline-quorum-review.json +0 -2
  64. package/recipes/pipeline-release-readiness.json +0 -2
  65. package/recipes/pipeline-release-summary.json +0 -2
  66. package/recipes/pipeline-repo-health.json +0 -2
  67. package/recipes/pipeline-research-synthesis.json +0 -2
  68. package/recipes/pipeline-review-readiness.json +0 -2
  69. package/recipes/pipeline-room-swarm.json +0 -2
  70. package/recipes/subagent-artifact.json +0 -2
  71. package/recipes/subagent-checkpoint.json +0 -2
  72. package/recipes/subagent-conflict-report.json +0 -2
  73. package/recipes/subagent-contradiction-map.json +0 -2
  74. package/recipes/subagent-critic.json +0 -2
  75. package/recipes/subagent-evidence-map.json +0 -2
  76. package/recipes/subagent-followup.json +0 -2
  77. package/recipes/subagent-judge.json +0 -2
  78. package/recipes/subagent-merge.json +0 -2
  79. package/recipes/subagent-message.json +0 -2
  80. package/recipes/subagent-normalize.json +0 -2
  81. package/recipes/subagent-plan.json +0 -2
  82. package/recipes/subagent-prompt.json +0 -2
  83. package/recipes/subagent-quorum.json +0 -2
  84. package/recipes/subagent-review-coordinator.json +0 -2
  85. package/recipes/subagent-review.json +0 -2
  86. package/recipes/subagent-task-card.json +0 -2
  87. package/recipes/subagent-tools.json +0 -2
  88. package/recipes/subagent-verify.json +0 -2
  89. package/recipes/subagents-prompts.json +0 -2
  90. package/skills/actors/SKILL.md +2 -2
  91. package/skills/swarm/SKILL.md +1 -1
package/BACKLOG.md CHANGED
@@ -180,7 +180,7 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
180
180
  ### M-09 Actor Worker v2
181
181
 
182
182
  - Priority: High.
183
- - Status: Open.
183
+ - Status: Done.
184
184
  - Goal: Promote `actor-worker` from a minimal demo into the canonical standard-worker reference pattern.
185
185
  - Why now: Mailbox-loop semantics are now stable enough to show artifact production, compact status, and stale-claim recovery without adding a scheduler or broker.
186
186
  - Direction:
@@ -196,7 +196,7 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
196
196
  ### M-10 Dist Package Contract Hardening
197
197
 
198
198
  - Priority: Medium.
199
- - Status: Open.
199
+ - Status: Done.
200
200
  - Goal: Make the dist-first package contract difficult to regress after the 0.24 packaging shift.
201
201
  - Why now: `dist/` is now the default JS-only runtime surface and carries mirrored scripts, recipes, fixtures, and skills.
202
202
  - Direction:
@@ -211,7 +211,7 @@ The backlog is intentionally pruned to the 20% of work most likely to deliver 80
211
211
  ### M-11 Actor Termination Semantics
212
212
 
213
213
  - Priority: Medium.
214
- - Status: Open; core mailbox-loop hotfix landed in 0.24.8.
214
+ - Status: Done.
215
215
  - Goal: Make `control.kill` the canonical parent-to-actor termination action while keeping `control.stop` and `control.cancel` as actor-domain messages whose meaning depends on the actor protocol.
216
216
  - Why now: Mailbox workers need a clearer lifecycle boundary before v2 patterns harden. Treating `stop`, `cancel`, and `kill` as equivalent stop messages blurs actor termination with domain-specific task or playback control.
217
217
  - Remaining direction:
@@ -240,9 +240,5 @@ These are valid ideas but not current focus. Reintroduce only with concrete evid
240
240
  ## Suggested Milestone Order
241
241
 
242
242
  ```text
243
- 0.25 — Worker maturity:
244
- M-09
245
-
246
- 0.26 — Package contract hardening and lifecycle semantics:
247
- M-10, M-11
243
+ Next milestone: choose from deferred items only after concrete actor workflow evidence appears.
248
244
  ```
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.26.1: Coordinator Empty-Synthesis Hotfix
6
+
7
+ - `[Coordinator]` Treat all-failed participant rounds and empty synthesis as a failed coordinator run instead of a clean success, preserving operator trust when swarm branches all exit non-zero.
8
+ - `[Artifacts]` Write compact diagnostics into empty synthesis artifacts, including participant attempt/success/failure counts and transcript size, so failed swarms leave actionable evidence instead of only `No synthesis output`.
9
+
10
+ ## 0.26.0: Actor Worker v2 and Package Contract Hardening
11
+
12
+ - `[Actor Worker]` Promoted the packaged `actor-worker` into a v2 reference pattern with compact `worker-status.json`, optional per-task result artifacts under `worker-artifacts/`, stale-claim surfacing through status, and artifact metadata on `task.result` room messages.
13
+ - `[Recipes]` Audited packaged async recipe mailbox contracts so `control.stop` and `control.cancel` remain declared only for actor-domain handlers such as locker/coordinator/music control, while generic async recipes expose `control.kill` for runtime termination.
14
+ - `[Packaging]` Hardened dist package regressions with mirrored asset checks for `dist/scripts`, `dist/recipes`, `dist/fixtures`, and `dist/skills`, plus negative checks for stale dist files and source-only runtime imports in built script shims.
15
+ - `[Skills]` Updated the actors skill recipe navigator to document the v2 worker pattern and its `control.kill` termination contract.
16
+
5
17
  ## 0.25.0: Recipe Doctor Remediation UX
6
18
 
7
19
  - `[Recipe Doctor]` Added prioritized advisory remediations to recipe doctor output, including a compact top action, structured verbose remediation entries, blocked lower-priority candidates for invalid/disabled overrides, and ordered coverage for invalid, disabled, shadowed, and risky shell-boundary recipes.
package/README.md CHANGED
@@ -89,7 +89,7 @@ cat > ~/.pi/agent/recipes/docs_review.json <<'JSON'
89
89
  "async": true,
90
90
  "args": ["scope:path", "model:string"],
91
91
  "mailbox": {
92
- "accepts": ["control.stop", "control.continue"],
92
+ "accepts": ["control.kill", "control.continue"],
93
93
  "emits": ["review.completed", "run.failed"]
94
94
  },
95
95
  "template": "pi -p --model {model} --no-tools \"Review {scope} for unclear actor-runtime onboarding. Return concise findings.\""
@@ -3,10 +3,13 @@
3
3
  * Zones: worker demo, mailbox loop recipe runtime
4
4
  */
5
5
  interface ActorWorkerArgs {
6
+ artifact_dir?: string;
6
7
  branch?: string;
7
8
  poll_ms?: string | number;
8
9
  run?: string;
10
+ stale_claim_ms?: string | number;
9
11
  state_dir?: string;
12
+ write_artifacts?: string | boolean;
10
13
  }
11
14
  export declare function parseActorWorkerArgs(argv: string[]): ActorWorkerArgs;
12
15
  export declare function runActorWorker(argv?: string[]): Promise<void>;
@@ -2,9 +2,9 @@
2
2
  * Canonical mailbox-backed actor worker entrypoint logic.
3
3
  * Zones: worker demo, mailbox loop recipe runtime
4
4
  */
5
- import { appendFileSync } from "node:fs";
5
+ import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
6
6
  import { join } from "node:path";
7
- import { appendRoomMessage, ensureRoomMember } from "./actor-rooms.js";
7
+ import { appendRoomMessage, ensureRoomMember, readBranchInboxMessages } from "./actor-rooms.js";
8
8
  import { handleMailboxLoopOnce, isMailboxLoopStopMessage } from "./mailbox-loop.js";
9
9
  export function parseActorWorkerArgs(argv) {
10
10
  const args = {};
@@ -29,21 +29,54 @@ function sleep(ms) {
29
29
  function text(value) {
30
30
  return typeof value === "string" ? value : JSON.stringify(value);
31
31
  }
32
+ function enabled(value) {
33
+ return value !== false && value !== "false" && value !== "0";
34
+ }
35
+ function safeName(value) {
36
+ return String(value ?? "unknown").replaceAll(/[^A-Za-z0-9_.-]+/g, "_");
37
+ }
32
38
  export async function runActorWorker(argv = process.argv.slice(2)) {
33
39
  const args = parseActorWorkerArgs(argv);
34
40
  const stateDir = String(args.state_dir ?? "");
35
41
  const run = String(args.run ?? "");
36
42
  const branch = String(args.branch ?? "worker");
37
43
  const pollMs = Math.max(50, Number(args.poll_ms ?? 1000));
44
+ const staleClaimMs = Math.max(0, Number(args.stale_claim_ms ?? 0));
45
+ const artifactDir = String(args.artifact_dir ?? join(stateDir, "worker-artifacts"));
46
+ const writeArtifacts = enabled(args.write_artifacts ?? true);
38
47
  if (!stateDir || !run) {
39
48
  throw new Error("usage: actor-worker.mjs --state-dir <dir> --run <id> [--branch worker] [--poll-ms 1000]");
40
49
  }
41
50
  const branchAddress = `branch:${run}/${branch}`;
42
51
  const roomAddress = `room:${run}`;
43
52
  const journalPath = join(stateDir, "worker-events.jsonl");
53
+ const statusPath = join(stateDir, "worker-status.json");
54
+ if (writeArtifacts)
55
+ mkdirSync(artifactDir, { recursive: true });
44
56
  function journal(event, data = {}) {
45
57
  appendFileSync(journalPath, `${JSON.stringify({ event, ts: new Date().toISOString(), ...data })}\n`);
46
58
  }
59
+ function staleClaims() {
60
+ if (staleClaimMs <= 0)
61
+ return 0;
62
+ const cutoff = Date.now() - staleClaimMs;
63
+ return readBranchInboxMessages(stateDir, run, branchAddress).filter((record) => {
64
+ if (record.status !== "claimed" || !record.claimed_at)
65
+ return false;
66
+ const claimedAt = Date.parse(record.claimed_at);
67
+ return Number.isFinite(claimedAt) && claimedAt < cutoff;
68
+ }).length;
69
+ }
70
+ function status(state, data = {}) {
71
+ writeFileSync(statusPath, `${JSON.stringify({ artifact_dir: artifactDir, branch, run, stale_claims: staleClaims(), state, ts: new Date().toISOString(), ...data }, null, 2)}\n`);
72
+ }
73
+ function writeResultArtifact(id, result) {
74
+ if (!writeArtifacts)
75
+ return undefined;
76
+ const path = join(artifactDir, `${safeName(id)}.txt`);
77
+ writeFileSync(path, `${result}\n`);
78
+ return path;
79
+ }
47
80
  function room(type, summary, body = {}) {
48
81
  appendRoomMessage(stateDir, "main", {
49
82
  body,
@@ -55,7 +88,9 @@ export async function runActorWorker(argv = process.argv.slice(2)) {
55
88
  }
56
89
  ensureRoomMember(stateDir, run, "main", branchAddress, { display: branch, role: "worker", status: "present" }, `${branch} joined as mailbox worker`);
57
90
  room("awaiting_assignment", `${branch} awaiting assignment`, { branch });
58
- journal("worker.started", { branch, run });
91
+ journal("worker.started", { artifact_dir: artifactDir, branch, run, stale_claim_ms: staleClaimMs });
92
+ status("awaiting_assignment", { handled: 0, stale_claim_ms: staleClaimMs });
93
+ let handled = 0;
59
94
  let stopping = false;
60
95
  while (!stopping) {
61
96
  const result = await handleMailboxLoopOnce({ address: branchAddress, kind: "branch", run, stateDir }, (message) => {
@@ -63,6 +98,7 @@ export async function runActorWorker(argv = process.argv.slice(2)) {
63
98
  stopping = true;
64
99
  room("actor.leave", `${branch} stopping`, { branch, reason: message.type });
65
100
  journal("worker.stopping", { id: message.id, type: message.type });
101
+ status("stopping", { handled, reason: message.type });
66
102
  return;
67
103
  }
68
104
  room("task.claim", `${branch} claimed ${message.type}`, {
@@ -70,17 +106,29 @@ export async function runActorWorker(argv = process.argv.slice(2)) {
70
106
  id: message.id,
71
107
  type: message.type,
72
108
  });
109
+ const result = text(message.body);
110
+ const artifact = writeResultArtifact(message.id, result);
111
+ handled += 1;
73
112
  room("task.result", `${branch} handled ${message.type}`, {
113
+ artifact,
74
114
  branch,
75
115
  id: message.id,
76
- result: text(message.body),
116
+ result,
77
117
  type: message.type,
78
118
  });
79
119
  room("awaiting_assignment", `${branch} awaiting assignment`, { branch });
80
- journal("task.handled", { id: message.id, type: message.type });
120
+ journal("task.handled", { artifact, id: message.id, type: message.type });
121
+ status("awaiting_assignment", {
122
+ handled,
123
+ last_artifact: artifact,
124
+ last_id: message.id,
125
+ last_type: message.type,
126
+ stale_claim_ms: staleClaimMs,
127
+ });
81
128
  }, { owner: branchAddress });
82
129
  if (!result.handled)
83
130
  await sleep(pollMs);
84
131
  }
85
- journal("worker.done", { branch, run });
132
+ journal("worker.done", { branch, handled, run });
133
+ status("done", { handled });
86
134
  }
@@ -259,7 +259,7 @@ async function readRoomTranscript(config) {
259
259
  }
260
260
  async function synthesize(config, locker) {
261
261
  if (!config.artifactPath)
262
- return;
262
+ return { code: 0, empty: false };
263
263
  if (locker) {
264
264
  await writeLockerMessage(locker, {
265
265
  type: "lock.claim",
@@ -269,9 +269,13 @@ async function synthesize(config, locker) {
269
269
  const transcript = await readRoomTranscript(config);
270
270
  const prompt = `Synthesize this transcript into a concise Markdown artifact. Mission: ${config.mission}. Include: Title, Consensus, Roles, Protocol, Final Artifact Shape, Next Actions, Open Questions. Use only the transcript evidence below.\n\nTRANSCRIPT:\n${transcript.slice(-24000)}`;
271
271
  const result = await runPi(prompt, config.model, config.thinking);
272
- await writeFile(config.artifactPath, result.stdout.trim()
272
+ const output = result.stdout.trim();
273
+ const diagnostics = config.stats
274
+ ? `\n\n## Diagnostics\n\nparticipant_attempts=${config.stats.participantAttempts}\nparticipant_success=${config.stats.participantSuccess}\nparticipant_failures=${config.stats.participantFailures}\nsynthesis_code=${result.code}\ntranscript_messages=${transcript.trim() ? transcript.split("\n").length : 0}\n`
275
+ : "";
276
+ await writeFile(config.artifactPath, output
273
277
  ? result.stdout
274
- : "# Synthesis Artifact\n\nNo synthesis output.\n", "utf8");
278
+ : `# Synthesis Artifact\n\nNo synthesis output.${diagnostics}\n`, "utf8");
275
279
  if (locker) {
276
280
  await writeLockerMessage(locker, {
277
281
  type: "lock.complete",
@@ -284,6 +288,7 @@ async function synthesize(config, locker) {
284
288
  });
285
289
  }
286
290
  process.stdout.write(`artifact=${config.artifactPath}\n`);
291
+ return { code: result.code, empty: !output };
287
292
  }
288
293
  async function readInboxLines(inboxPath) {
289
294
  if (!existsSync(inboxPath))
@@ -378,9 +383,17 @@ async function participantRound(role, round, config) {
378
383
  const address = `branch:${config.runId}/${role.name}`;
379
384
  const prompt = `You are ${displayName} (${address}), ${role.persona}. Mission: ${config.mission}. Round ${round}/${config.rounds}. First call inspect target=${config.room} view=previews lines=30 and inspect target=${config.room} view=contacts. Then call message once to ${config.room} from ${address} type=chat.message. Body: 2-4 sentences that react to a named participant, propose the next coordination step, and refine the shared artifact. Use contacts for peer names and addresses. End stdout with summary <=160 chars.`;
380
385
  const result = await executeParticipantPrompt(role, prompt, config);
386
+ if (config.stats) {
387
+ config.stats.participantAttempts += 1;
388
+ if (result.code === 0)
389
+ config.stats.participantSuccess += 1;
390
+ else
391
+ config.stats.participantFailures += 1;
392
+ }
381
393
  process.stdout.write(`[${role.name} round ${round}] code=${result.code}\n${result.stdout}\n`);
382
394
  if (result.stderr.trim())
383
395
  process.stderr.write(`[${role.name} round ${round}] ${result.stderr}\n`);
396
+ return result;
384
397
  }
385
398
  async function participantJoin(role, config) {
386
399
  const displayName = role.name;
@@ -546,6 +559,11 @@ export async function runCoordinator(argv = process.argv.slice(2)) {
546
559
  artifactPath: arg("artifact-path", ""),
547
560
  locker: boolArg("locker", false),
548
561
  lockerLeaseMs: numberArg("locker-lease-ms", 600000),
562
+ stats: {
563
+ participantAttempts: 0,
564
+ participantSuccess: 0,
565
+ participantFailures: 0,
566
+ },
549
567
  };
550
568
  if (!config.model) {
551
569
  console.error("--model is required");
@@ -559,7 +577,16 @@ export async function runCoordinator(argv = process.argv.slice(2)) {
559
577
  if (!runMode)
560
578
  throw new Error(`Unknown coordinator mode: ${config.mode}`);
561
579
  await runMode(config, locker);
562
- await synthesize(config, locker);
580
+ const synthesis = await synthesize(config, locker);
581
+ if (config.stats.participantAttempts > 0 && config.stats.participantSuccess === 0) {
582
+ failures.push(`All participant rounds failed: attempts=${config.stats.participantAttempts}`);
583
+ }
584
+ if (synthesis?.empty && config.stats.participantFailures > 0) {
585
+ failures.push(`Synthesis output was empty after participant failures: failures=${config.stats.participantFailures}`);
586
+ }
587
+ if (synthesis && synthesis.code !== 0) {
588
+ failures.push(`Synthesis command failed: code=${synthesis.code}`);
589
+ }
563
590
  }
564
591
  catch (globalError) {
565
592
  failures.push(`Global coordinator error: ${globalError.message}`);
@@ -4,18 +4,20 @@
4
4
  "args": [
5
5
  "repo:path",
6
6
  "branch:string",
7
- "poll_ms:int"
7
+ "poll_ms:int",
8
+ "stale_claim_ms:int",
9
+ "write_artifacts:bool"
8
10
  ],
9
11
  "defaults": {
10
12
  "repo": "~/.pi/agent/extensions/pi-actors",
11
13
  "branch": "worker",
12
- "poll_ms": "1000"
14
+ "poll_ms": "1000",
15
+ "stale_claim_ms": "0",
16
+ "write_artifacts": "true"
13
17
  },
14
18
  "mailbox": {
15
19
  "accepts": [
16
20
  "task.assign",
17
- "control.stop",
18
- "control.cancel",
19
21
  "control.kill"
20
22
  ],
21
23
  "emits": [
@@ -29,7 +31,9 @@
29
31
  ]
30
32
  },
31
33
  "artifacts": {
32
- "journal": "{state_dir}/worker-events.jsonl"
34
+ "journal": "{state_dir}/worker-events.jsonl",
35
+ "status": "{state_dir}/worker-status.json",
36
+ "results": "{state_dir}/worker-artifacts"
33
37
  },
34
- "template": "{repo}/scripts/actor-worker.mjs --state-dir {state_dir} --run {run_id} --branch {branch} --poll-ms {poll_ms}"
38
+ "template": "{repo}/scripts/actor-worker.mjs --state-dir {state_dir} --run {run_id} --branch {branch} --poll-ms {poll_ms} --stale-claim-ms {stale_claim_ms} --write-artifacts {write_artifacts}"
35
39
  }
@@ -30,8 +30,6 @@
30
30
  },
31
31
  "mailbox": {
32
32
  "accepts": [
33
- "control.stop",
34
- "control.cancel",
35
33
  "control.kill"
36
34
  ],
37
35
  "emits": [
@@ -26,8 +26,6 @@
26
26
  },
27
27
  "mailbox": {
28
28
  "accepts": [
29
- "control.stop",
30
- "control.cancel",
31
29
  "control.kill"
32
30
  ],
33
31
  "emits": [
@@ -35,8 +35,6 @@
35
35
  },
36
36
  "mailbox": {
37
37
  "accepts": [
38
- "control.stop",
39
- "control.cancel",
40
38
  "control.kill"
41
39
  ],
42
40
  "emits": [
@@ -18,8 +18,6 @@
18
18
  },
19
19
  "mailbox": {
20
20
  "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
21
  "control.kill"
24
22
  ],
25
23
  "emits": [
@@ -21,8 +21,6 @@
21
21
  },
22
22
  "mailbox": {
23
23
  "accepts": [
24
- "control.stop",
25
- "control.cancel",
26
24
  "control.kill"
27
25
  ],
28
26
  "emits": [
@@ -24,8 +24,6 @@
24
24
  },
25
25
  "mailbox": {
26
26
  "accepts": [
27
- "control.stop",
28
- "control.cancel",
29
27
  "control.kill"
30
28
  ],
31
29
  "emits": [
@@ -22,8 +22,6 @@
22
22
  "accepts": [
23
23
  "control.reply",
24
24
  "control.revise",
25
- "control.stop",
26
- "control.cancel",
27
25
  "control.kill"
28
26
  ],
29
27
  "emits": [
@@ -24,8 +24,6 @@
24
24
  },
25
25
  "mailbox": {
26
26
  "accepts": [
27
- "control.stop",
28
- "control.cancel",
29
27
  "control.kill"
30
28
  ],
31
29
  "emits": [
@@ -23,8 +23,6 @@
23
23
  },
24
24
  "mailbox": {
25
25
  "accepts": [
26
- "control.stop",
27
- "control.cancel",
28
26
  "control.kill"
29
27
  ],
30
28
  "emits": [
@@ -23,8 +23,6 @@
23
23
  },
24
24
  "mailbox": {
25
25
  "accepts": [
26
- "control.stop",
27
- "control.cancel",
28
26
  "control.kill"
29
27
  ],
30
28
  "emits": [
@@ -20,8 +20,6 @@
20
20
  },
21
21
  "mailbox": {
22
22
  "accepts": [
23
- "control.stop",
24
- "control.cancel",
25
23
  "control.kill"
26
24
  ],
27
25
  "emits": [
@@ -40,8 +40,6 @@
40
40
  },
41
41
  "mailbox": {
42
42
  "accepts": [
43
- "control.stop",
44
- "control.cancel",
45
43
  "control.kill"
46
44
  ],
47
45
  "emits": [
@@ -29,8 +29,6 @@
29
29
  },
30
30
  "mailbox": {
31
31
  "accepts": [
32
- "control.stop",
33
- "control.cancel",
34
32
  "control.kill"
35
33
  ],
36
34
  "emits": [
@@ -25,8 +25,6 @@
25
25
  },
26
26
  "mailbox": {
27
27
  "accepts": [
28
- "control.stop",
29
- "control.cancel",
30
28
  "control.kill"
31
29
  ],
32
30
  "emits": [
@@ -22,8 +22,6 @@
22
22
  },
23
23
  "mailbox": {
24
24
  "accepts": [
25
- "control.stop",
26
- "control.cancel",
27
25
  "control.kill"
28
26
  ],
29
27
  "emits": [
@@ -25,8 +25,6 @@
25
25
  },
26
26
  "mailbox": {
27
27
  "accepts": [
28
- "control.stop",
29
- "control.cancel",
30
28
  "control.kill"
31
29
  ],
32
30
  "emits": [
@@ -34,8 +34,6 @@
34
34
  },
35
35
  "mailbox": {
36
36
  "accepts": [
37
- "control.stop",
38
- "control.cancel",
39
37
  "control.kill"
40
38
  ],
41
39
  "emits": [
@@ -19,8 +19,6 @@
19
19
  },
20
20
  "mailbox": {
21
21
  "accepts": [
22
- "control.stop",
23
- "control.cancel",
24
22
  "control.kill"
25
23
  ],
26
24
  "emits": [
@@ -21,8 +21,6 @@
21
21
  "accepts": [
22
22
  "control.continue",
23
23
  "control.revise",
24
- "control.stop",
25
- "control.cancel",
26
24
  "control.kill"
27
25
  ],
28
26
  "emits": [
@@ -17,8 +17,6 @@
17
17
  },
18
18
  "mailbox": {
19
19
  "accepts": [
20
- "control.stop",
21
- "control.cancel",
22
20
  "control.kill"
23
21
  ],
24
22
  "emits": [
@@ -18,8 +18,6 @@
18
18
  },
19
19
  "mailbox": {
20
20
  "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
21
  "control.kill"
24
22
  ],
25
23
  "emits": [
@@ -20,8 +20,6 @@
20
20
  },
21
21
  "mailbox": {
22
22
  "accepts": [
23
- "control.stop",
24
- "control.cancel",
25
23
  "control.kill"
26
24
  ],
27
25
  "emits": [
@@ -18,8 +18,6 @@
18
18
  },
19
19
  "mailbox": {
20
20
  "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
21
  "control.kill"
24
22
  ],
25
23
  "emits": [
@@ -21,8 +21,6 @@
21
21
  "accepts": [
22
22
  "control.reply",
23
23
  "control.revise",
24
- "control.stop",
25
- "control.cancel",
26
24
  "control.kill"
27
25
  ],
28
26
  "emits": [
@@ -18,8 +18,6 @@
18
18
  },
19
19
  "mailbox": {
20
20
  "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
21
  "control.kill"
24
22
  ],
25
23
  "emits": [
@@ -18,8 +18,6 @@
18
18
  },
19
19
  "mailbox": {
20
20
  "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
21
  "control.kill"
24
22
  ],
25
23
  "emits": [
@@ -22,8 +22,6 @@
22
22
  },
23
23
  "mailbox": {
24
24
  "accepts": [
25
- "control.stop",
26
- "control.cancel",
27
25
  "control.kill"
28
26
  ],
29
27
  "emits": [
@@ -16,8 +16,6 @@
16
16
  },
17
17
  "mailbox": {
18
18
  "accepts": [
19
- "control.stop",
20
- "control.cancel",
21
19
  "control.kill"
22
20
  ],
23
21
  "emits": [
@@ -18,8 +18,6 @@
18
18
  },
19
19
  "mailbox": {
20
20
  "accepts": [
21
- "control.stop",
22
- "control.cancel",
23
21
  "control.kill"
24
22
  ],
25
23
  "emits": [
@@ -14,8 +14,6 @@
14
14
  },
15
15
  "mailbox": {
16
16
  "accepts": [
17
- "control.stop",
18
- "control.cancel",
19
17
  "control.kill"
20
18
  ],
21
19
  "emits": [
@@ -17,8 +17,6 @@
17
17
  },
18
18
  "mailbox": {
19
19
  "accepts": [
20
- "control.stop",
21
- "control.cancel",
22
20
  "control.kill"
23
21
  ],
24
22
  "emits": [
@@ -36,8 +36,6 @@
36
36
  },
37
37
  "mailbox": {
38
38
  "accepts": [
39
- "control.stop",
40
- "control.cancel",
41
39
  "control.kill"
42
40
  ],
43
41
  "emits": [
@@ -22,8 +22,6 @@
22
22
  },
23
23
  "mailbox": {
24
24
  "accepts": [
25
- "control.stop",
26
- "control.cancel",
27
25
  "control.kill"
28
26
  ],
29
27
  "emits": [