@astrosheep/keiyaku 4.5.11 → 4.5.13

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 (272) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +135 -377
  2. package/build/integrations/pi/keiyaku.ts +11 -116
  3. package/build/src/akuma/akuma-errors.d.ts +1 -0
  4. package/build/src/akuma/akuma-errors.js +1 -0
  5. package/build/src/akuma/akuma-handle.d.ts +1 -0
  6. package/build/src/akuma/akuma-handle.js +6 -7
  7. package/build/src/akuma/akuma-product.d.ts +6 -8
  8. package/build/src/akuma/akuma-product.js +141 -57
  9. package/build/src/akuma/akuma.d.ts +5 -7
  10. package/build/src/akuma/akuma.js +1 -22
  11. package/build/src/akuma/archetype.d.ts +6 -5
  12. package/build/src/akuma/archetype.js +137 -38
  13. package/build/src/akuma/body.d.ts +5 -5
  14. package/build/src/akuma/body.js +223 -63
  15. package/build/src/akuma/call-input.d.ts +4 -0
  16. package/build/src/akuma/call-input.js +21 -0
  17. package/build/src/akuma/call-request.d.ts +5 -8
  18. package/build/src/akuma/call-request.js +28 -73
  19. package/build/src/akuma/fleet-execution.d.ts +26 -0
  20. package/build/src/akuma/fleet-execution.js +109 -0
  21. package/build/src/{library/fleet-result.d.ts → akuma/fleet-observation.d.ts} +13 -57
  22. package/build/src/{library/fleet-result.js → akuma/fleet-observation.js} +4 -25
  23. package/build/src/akuma/fleet-request.d.ts +122 -0
  24. package/build/src/akuma/fleet-request.js +168 -0
  25. package/build/src/akuma/heart/facts.d.ts +23 -0
  26. package/build/src/akuma/heart/facts.js +7 -0
  27. package/build/src/akuma/heart/index.d.ts +43 -4
  28. package/build/src/akuma/heart/index.js +107 -7
  29. package/build/src/akuma/heart/request-authority.d.ts +2 -0
  30. package/build/src/akuma/heart/request-authority.js +28 -3
  31. package/build/src/akuma/heart/request-rows.d.ts +2 -0
  32. package/build/src/akuma/heart/request-rows.js +24 -5
  33. package/build/src/akuma/heart/rows.d.ts +4 -1
  34. package/build/src/akuma/heart/rows.js +46 -19
  35. package/build/src/akuma/heart/schema.d.ts +1 -1
  36. package/build/src/akuma/heart/schema.js +28 -6
  37. package/build/src/akuma/heart/storage.d.ts +1 -1
  38. package/build/src/akuma/heart/tells.d.ts +29 -0
  39. package/build/src/akuma/heart/tells.js +136 -5
  40. package/build/src/akuma/heart/timeline.js +9 -3
  41. package/build/src/akuma/projection-read.js +36 -3
  42. package/build/src/akuma/projection.js +3 -4
  43. package/build/src/akuma/provider.d.ts +4 -0
  44. package/build/src/akuma/provider.js +56 -3
  45. package/build/src/akuma/providers/claude/index.js +3 -0
  46. package/build/src/akuma/providers/codex-app-server/index.js +14 -12
  47. package/build/src/akuma/providers/pi/index.js +7 -1
  48. package/build/src/akuma/publication.js +65 -49
  49. package/build/src/akuma/request-lifecycle.d.ts +5 -4
  50. package/build/src/akuma/request-lifecycle.js +29 -16
  51. package/build/src/akuma/request-rendezvous.d.ts +15 -12
  52. package/build/src/akuma/request-rendezvous.js +80 -51
  53. package/build/src/akuma/request-serve.d.ts +1 -2
  54. package/build/src/akuma/request-serve.js +94 -39
  55. package/build/src/akuma/request-wire.d.ts +57 -26
  56. package/build/src/akuma/request-wire.js +64 -25
  57. package/build/src/akuma/turn-drive.d.ts +5 -4
  58. package/build/src/akuma/turn-drive.js +27 -11
  59. package/build/src/akuma-body.d.ts +4 -6
  60. package/build/src/akuma-body.js +19 -17
  61. package/build/src/bounded-list.d.ts +8 -0
  62. package/build/src/bounded-list.js +14 -0
  63. package/build/src/cli/accepted.d.ts +1 -1
  64. package/build/src/cli/accepted.js +1 -0
  65. package/build/src/cli/commands/akuma-invoke.js +1 -25
  66. package/build/src/cli/commands/contract-help.d.ts +5 -2
  67. package/build/src/cli/commands/contract-help.js +62 -12
  68. package/build/src/cli/commands/contract-invoke.d.ts +5 -0
  69. package/build/src/cli/commands/contract-invoke.js +26 -1
  70. package/build/src/cli/commands/contract.js +50 -18
  71. package/build/src/cli/commands/task-invoke.js +10 -2
  72. package/build/src/cli/commands/task-query.js +3 -4
  73. package/build/src/cli/coordinates.d.ts +13 -0
  74. package/build/src/cli/coordinates.js +38 -24
  75. package/build/src/cli/draft.d.ts +1 -1
  76. package/build/src/cli/invoke.js +14 -1
  77. package/build/src/cli/render/akuma-activity.d.ts +0 -1
  78. package/build/src/cli/render/akuma-activity.js +5 -38
  79. package/build/src/cli/render/akuma.js +4 -1
  80. package/build/src/cli/render/audit.js +4 -1
  81. package/build/src/cli/render/catalog.js +13 -39
  82. package/build/src/cli/render/contract.js +4 -14
  83. package/build/src/cli/render/kanshi-akuma.js +3 -8
  84. package/build/src/cli/render/kanshi.js +8 -34
  85. package/build/src/cli/render/nuke.js +7 -3
  86. package/build/src/cli/render/receipt.d.ts +1 -0
  87. package/build/src/cli/render/receipt.js +8 -0
  88. package/build/src/cli/render/refusal.js +4 -3
  89. package/build/src/cli/render/task.js +4 -37
  90. package/build/src/cli/render/terminal.d.ts +2 -6
  91. package/build/src/cli/render/terminal.js +4 -9
  92. package/build/src/cli/result.d.ts +2 -1
  93. package/build/src/contract-guidance.js +13 -3
  94. package/build/src/contract-worktree.d.ts +1 -0
  95. package/build/src/contract-worktree.js +26 -2
  96. package/build/src/core/facts/codec.d.ts +2 -1
  97. package/build/src/core/facts/codec.js +3 -0
  98. package/build/src/core/facts/gate.d.ts +2 -1
  99. package/build/src/core/facts/gate.js +63 -0
  100. package/build/src/core/verbs/abandon.d.ts +2 -1
  101. package/build/src/core/verbs/abandon.js +16 -0
  102. package/build/src/core/verbs/amend.d.ts +2 -1
  103. package/build/src/core/verbs/amend.js +20 -0
  104. package/build/src/core/verbs/arc.d.ts +2 -1
  105. package/build/src/core/verbs/arc.js +16 -0
  106. package/build/src/core/verbs/attestation.d.ts +2 -1
  107. package/build/src/core/verbs/attestation.js +16 -0
  108. package/build/src/core/verbs/bind.d.ts +2 -1
  109. package/build/src/core/verbs/bind.js +16 -0
  110. package/build/src/core/verbs/deliver.d.ts +2 -1
  111. package/build/src/core/verbs/deliver.js +16 -0
  112. package/build/src/core/verbs/placement.d.ts +2 -1
  113. package/build/src/core/verbs/placement.js +58 -1
  114. package/build/src/dispatch/association.d.ts +13 -0
  115. package/build/src/dispatch/association.js +20 -0
  116. package/build/src/dispatch/index.d.ts +6 -0
  117. package/build/src/dispatch/index.js +27 -3
  118. package/build/src/git/hooks.d.ts +9 -1
  119. package/build/src/git/hooks.js +79 -1
  120. package/build/src/git/nuke.d.ts +2 -1
  121. package/build/src/git/nuke.js +6 -11
  122. package/build/src/git/private-state-seat.d.ts +26 -1
  123. package/build/src/git/private-state-seat.js +78 -13
  124. package/build/src/git/process.d.ts +2 -0
  125. package/build/src/git/reconcile.d.ts +1 -2
  126. package/build/src/git/reconcile.js +0 -6
  127. package/build/src/git/repository.d.ts +0 -2
  128. package/build/src/git/repository.js +27 -25
  129. package/build/src/git/result-codec.d.ts +29 -0
  130. package/build/src/git/result-codec.js +306 -0
  131. package/build/src/git/target-placement.js +2 -8
  132. package/build/src/git/workspace.d.ts +2 -0
  133. package/build/src/git/workspace.js +4 -0
  134. package/build/src/index.d.ts +1 -0
  135. package/build/src/kanshi/fleet.js +1 -1
  136. package/build/src/kanshi/read.js +55 -28
  137. package/build/src/kanshi/report.d.ts +4 -3
  138. package/build/src/kanshi/select.js +14 -1
  139. package/build/src/library/address.d.ts +1 -0
  140. package/build/src/library/address.js +4 -7
  141. package/build/src/library/akuma-creation.d.ts +5 -3
  142. package/build/src/library/akuma-creation.js +90 -33
  143. package/build/src/library/audit.js +2 -1
  144. package/build/src/library/catalog.d.ts +10 -2
  145. package/build/src/library/catalog.js +65 -25
  146. package/build/src/library/composition.d.ts +1 -0
  147. package/build/src/library/composition.js +1 -0
  148. package/build/src/library/configuration.d.ts +4 -21
  149. package/build/src/library/configuration.js +2 -158
  150. package/build/src/library/continuation.d.ts +20 -1
  151. package/build/src/library/continuation.js +36 -0
  152. package/build/src/library/contract-bind.d.ts +1 -0
  153. package/build/src/library/contract-bind.js +16 -5
  154. package/build/src/library/contract-forwarding.d.ts +2 -2
  155. package/build/src/library/contract-forwarding.js +18 -4
  156. package/build/src/library/contract-handle.js +4 -3
  157. package/build/src/library/contract-operations.d.ts +5 -9
  158. package/build/src/library/contract-operations.js +34 -47
  159. package/build/src/library/contract.d.ts +11 -2
  160. package/build/src/library/contract.js +21 -1
  161. package/build/src/library/delivery.d.ts +4 -1
  162. package/build/src/library/delivery.js +47 -0
  163. package/build/src/library/fleet.d.ts +4 -136
  164. package/build/src/library/fleet.js +31 -315
  165. package/build/src/library/keiyaku.d.ts +7 -3
  166. package/build/src/library/keiyaku.js +1 -0
  167. package/build/src/library/mutation.d.ts +431 -3
  168. package/build/src/library/mutation.js +192 -19
  169. package/build/src/library/nuke.d.ts +7 -1
  170. package/build/src/library/nuke.js +18 -4
  171. package/build/src/library/reconcile.d.ts +14 -0
  172. package/build/src/library/reconcile.js +22 -8
  173. package/build/src/library/refusal.d.ts +9 -1
  174. package/build/src/library/refusal.js +76 -0
  175. package/build/src/library/region.d.ts +0 -8
  176. package/build/src/library/region.js +1 -29
  177. package/build/src/library/result-codec.d.ts +2 -0
  178. package/build/src/library/result-codec.js +12 -0
  179. package/build/src/markdown/lex.js +9 -2
  180. package/build/src/markdown/types.d.ts +2 -1
  181. package/build/src/markdown/types.js +3 -1
  182. package/build/src/plugin/akuma-signals.d.ts +12 -0
  183. package/build/src/plugin/akuma-signals.js +14 -0
  184. package/build/src/plugin/public.d.ts +51 -0
  185. package/build/src/plugin/public.js +1 -0
  186. package/build/src/plugin/runtime.d.ts +14 -0
  187. package/build/src/plugin/runtime.js +357 -0
  188. package/build/src/protocol/amend.js +3 -3
  189. package/build/src/protocol/attempt.d.ts +2 -1
  190. package/build/src/protocol/attempt.js +1 -1
  191. package/build/src/protocol/audit.d.ts +1 -1
  192. package/build/src/protocol/audit.js +1 -1
  193. package/build/src/protocol/bind.d.ts +3 -1
  194. package/build/src/protocol/bind.js +26 -0
  195. package/build/src/protocol/completion.js +0 -1
  196. package/build/src/protocol/deliver.d.ts +1 -1
  197. package/build/src/protocol/deliver.js +136 -57
  198. package/build/src/protocol/intent.d.ts +0 -1
  199. package/build/src/protocol/intent.js +0 -1
  200. package/build/src/protocol/operations.d.ts +9 -2
  201. package/build/src/protocol/operations.js +16 -1
  202. package/build/src/protocol/outcome.d.ts +3 -0
  203. package/build/src/protocol/outcome.js +17 -1
  204. package/build/src/protocol/placement.js +10 -3
  205. package/build/src/protocol/read/status.d.ts +8 -0
  206. package/build/src/protocol/read/status.js +49 -0
  207. package/build/src/protocol/reintegrate.js +10 -3
  208. package/build/src/protocol/result-codec.d.ts +22 -0
  209. package/build/src/protocol/result-codec.js +442 -0
  210. package/build/src/protocol/review.d.ts +1 -1
  211. package/build/src/protocol/review.js +81 -46
  212. package/build/src/protocol/run.d.ts +22 -2
  213. package/build/src/protocol/run.js +119 -29
  214. package/build/src/runtime/proc/lifecycle.js +1 -1
  215. package/build/src/runtime/proc/line-rpc.d.ts +7 -1
  216. package/build/src/runtime/proc/line-rpc.js +49 -9
  217. package/build/src/runtime/proc/run.d.ts +0 -1
  218. package/build/src/runtime/proc/run.js +1 -11
  219. package/build/src/runtime/proc/termination.d.ts +1 -0
  220. package/build/src/runtime/proc/termination.js +63 -18
  221. package/build/src/runtime/proc/windows-launch.exe +0 -0
  222. package/build/src/settings.d.ts +10 -0
  223. package/build/src/settings.js +88 -2
  224. package/build/src/settlement/result-codec.d.ts +2 -0
  225. package/build/src/settlement/result-codec.js +56 -0
  226. package/build/src/settlement/settle.d.ts +5 -12
  227. package/build/src/settlement/settle.js +60 -55
  228. package/build/src/task/board.d.ts +3 -0
  229. package/build/src/task/board.js +22 -4
  230. package/build/src/task/catalog.d.ts +13 -2
  231. package/build/src/task/catalog.js +59 -5
  232. package/build/src/task/compose.d.ts +4 -2
  233. package/build/src/task/compose.js +56 -30
  234. package/build/src/task/created-observation.d.ts +39 -0
  235. package/build/src/task/created-observation.js +26 -0
  236. package/build/src/task/identity.d.ts +6 -0
  237. package/build/src/task/identity.js +48 -7
  238. package/build/src/task/index.d.ts +4 -3
  239. package/build/src/task/index.js +19 -16
  240. package/build/src/task/input.d.ts +3 -1
  241. package/build/src/task/input.js +7 -4
  242. package/build/src/task/lifecycle-operations.d.ts +6 -0
  243. package/build/src/task/lifecycle-operations.js +116 -0
  244. package/build/src/task/mutation-result.d.ts +762 -20
  245. package/build/src/task/mutation-result.js +34 -9
  246. package/build/src/task/mutation.d.ts +4 -9
  247. package/build/src/task/mutation.js +17 -52
  248. package/build/src/task/operation-types.d.ts +114 -0
  249. package/build/src/task/operation-types.js +1 -0
  250. package/build/src/task/operations.d.ts +6 -113
  251. package/build/src/task/operations.js +75 -117
  252. package/build/src/task/query.d.ts +8 -11
  253. package/build/src/task/query.js +7 -14
  254. package/build/src/task/store.d.ts +11 -1
  255. package/build/src/task/store.js +169 -55
  256. package/build/src/task/view.d.ts +4 -0
  257. package/build/src/task/view.js +7 -0
  258. package/build/src/verification/declaration.d.ts +1 -0
  259. package/build/src/verification/declaration.js +18 -1
  260. package/build/src/verification/execution.d.ts +0 -1
  261. package/build/src/verification/execution.js +5 -5
  262. package/build/src/world.d.ts +0 -2
  263. package/build/src/world.js +3 -7
  264. package/package.json +17 -5
  265. package/build/src/cli/square-edge.d.ts +0 -7
  266. package/build/src/cli/square-edge.js +0 -159
  267. package/build/src/git/ref-migration.d.ts +0 -22
  268. package/build/src/git/ref-migration.js +0 -55
  269. package/build/src/library/contract-forwarding-reconciliation-result.d.ts +0 -102
  270. package/build/src/library/contract-forwarding-reconciliation-result.js +0 -92
  271. package/build/src/library/contract-forwarding-result.d.ts +0 -4270
  272. package/build/src/library/contract-forwarding-result.js +0 -521
@@ -0,0 +1,14 @@
1
+ export const DEFAULT_BOUNDED_LIST_LIMIT = 50;
2
+ export const MAX_BOUNDED_LIST_LIMIT = 500;
3
+ export function boundedListLimit(value = undefined) {
4
+ if (value === undefined)
5
+ return DEFAULT_BOUNDED_LIST_LIMIT;
6
+ if (!Number.isSafeInteger(value) || value < 1 || value > MAX_BOUNDED_LIST_LIMIT) {
7
+ throw new TypeError(`limit must be an integer from 1 to ${MAX_BOUNDED_LIST_LIMIT}`);
8
+ }
9
+ return value;
10
+ }
11
+ export function projectBoundedList(rows, limit) {
12
+ const projected = rows.slice(0, limit + 1);
13
+ return { rows: projected.slice(0, limit), hasMore: projected.length > limit };
14
+ }
@@ -1,6 +1,6 @@
1
1
  import { type AmendResult, type AuditReport, type BindResult, type ContractId, type Delivery, type MutationResult, type Review } from "../index.js";
2
2
  import type { AcceptedAbandonResult, AcceptedAmendResult, AcceptedArcResult, AcceptedAuditResult, AcceptedBindResult, AcceptedDeliverResult, AcceptedResult, AcceptedReviewResult, InvocationResult } from "./result.js";
3
- type MutationObservation = Pick<MutationResult<unknown>, "facts" | "head" | "lags" | "settlementLags" | "recoverySnapshot">;
3
+ type MutationObservation = Pick<MutationResult<unknown>, "facts" | "head" | "lags" | "settlementLags" | "recoverySnapshot" | "seatClose">;
4
4
  type MutationCallOptions = Readonly<{
5
5
  coordinate?: ContractId;
6
6
  projectRefusal?: (refusal: unknown) => unknown;
@@ -20,6 +20,7 @@ function acceptedEnvelope(result, coordinate) {
20
20
  settlementLags: result.settlementLags,
21
21
  ...(result.recoverySnapshot === undefined ? {} : { recoverySnapshot: result.recoverySnapshot }),
22
22
  ...(result.lags.length === 0 || firstLag === undefined ? {} : { lag: [firstLag, ...result.lags.slice(1)] }),
23
+ ...(result.seatClose === undefined || result.seatClose.length === 0 ? {} : { seatClose: result.seatClose }),
23
24
  };
24
25
  }
25
26
  function acceptedRegion(result) {
@@ -2,13 +2,6 @@ import { Keiyaku, } from "../../index.js";
2
2
  import { beginCall, finishCall } from "../../library/akuma-creation.js";
3
3
  import { killAkuma, tellAkuma, waitAkuma } from "../../library/fleet.js";
4
4
  import { localExecutionContext } from "../../akuma/requests.js";
5
- import { recognizeAndListen } from "../square-edge.js";
6
- function withRollbackDiagnostic(primary, rollback) {
7
- const primaryText = primary instanceof Error ? primary.message : String(primary);
8
- const rollbackText = rollback instanceof Error ? rollback.message : String(rollback);
9
- const error = new Error(`${primaryText}; ${rollbackText}`, { cause: primary });
10
- return error;
11
- }
12
5
  function inputAlias(selector) {
13
6
  return selector.startsWith("@") ? selector : undefined;
14
7
  }
@@ -127,24 +120,7 @@ export async function invokeAkuma(command, input) {
127
120
  ...(command.alias === undefined ? {} : { alias: command.alias }),
128
121
  ...(command.allowed === undefined ? {} : { allowed: command.allowed }),
129
122
  }, input.execution ?? localExecutionContext());
130
- const listener = born.born.kind === "born"
131
- ? await recognizeAndListen(input.path, input.environment, born.born.allocated)
132
- : undefined;
133
- let result;
134
- try {
135
- result = await (input.finishCall ?? finishCall)(born, listener?.participantName);
136
- }
137
- catch (error) {
138
- if (listener?.committed === true) {
139
- try {
140
- await listener.rollback();
141
- }
142
- catch (rollbackError) {
143
- throw withRollbackDiagnostic(error, rollbackError);
144
- }
145
- }
146
- throw error;
147
- }
123
+ const result = await (input.finishCall ?? finishCall)(born);
148
124
  return { kind: "akuma", action: "call", result, world: input.path };
149
125
  }
150
126
  case "wait":
@@ -22,6 +22,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
22
22
  };
23
23
  readonly usage: "bind [--task <task/...>] [--target <ref>] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] [--json] - | bind --fork-of <kei/...> [--target <ref>] [--actor <actor>] [--json]";
24
24
  readonly purpose: "Create one Contract from stdin Markdown or a sibling fork.";
25
+ readonly details: string;
25
26
  };
26
27
  readonly amend: {
27
28
  readonly positional: "optional";
@@ -60,7 +61,8 @@ export declare const CONTRACT_COMMAND_SPECS: {
60
61
  readonly json: "boolean";
61
62
  };
62
63
  readonly usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--json]";
63
- readonly purpose: "Record one review verdict.";
64
+ readonly purpose: "Record one review verdict over this Contract's current subject.";
65
+ readonly details: string;
64
66
  };
65
67
  readonly arc: {
66
68
  readonly positional: "optional";
@@ -105,9 +107,10 @@ export declare const CONTRACT_COMMAND_SPECS: {
105
107
  readonly positional: "optional";
106
108
  readonly stdin: "none";
107
109
  readonly flags: {
110
+ readonly limit: "value";
108
111
  readonly json: "boolean";
109
112
  };
110
- readonly usage: "ls task[/] [--json]\nls kei[/] [--json]\nls aku[/] [--json]\nls aku/<akuma>[/] [--json]\nls \"aku/*/*\" [--json]";
113
+ readonly usage: "ls task[/] [--limit <count>] [--json]\nls kei[/] [--limit <count>] [--json]\nls aku[/] [--json]\nls aku/<akuma>[/] [--limit <count>] [--json]\nls \"aku/*/*\" [--limit <count>] [--json]";
111
114
  readonly purpose: "List one identity directory.";
112
115
  };
113
116
  readonly audit: {
@@ -14,6 +14,24 @@ export const CONTRACT_COMMAND_SPECS = {
14
14
  },
15
15
  usage: "bind [--task <task/...>] [--target <ref>] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] [--json] - | bind --fork-of <kei/...> [--target <ref>] [--actor <actor>] [--json]",
16
16
  purpose: "Create one Contract from stdin Markdown or a sibling fork.",
17
+ details: [
18
+ "stdin is Contract Markdown:",
19
+ " # <title>",
20
+ " ## Context motivation, authority, baseline, and boundaries",
21
+ " ## Objective one observable end state",
22
+ " ## Design closed decisions and ordering",
23
+ " ## Region one fenced path-pattern declaration",
24
+ " ## Criteria one or more ### <criterion> entries",
25
+ " ## Verification optional fenced executor declarations",
26
+ "",
27
+ "Region uses one closed fence with no info string or exactly 'txt'; put one",
28
+ "repository-relative path pattern on each nonblank line. A trailing '/'",
29
+ "is directory shorthand for 'path/**'.",
30
+ "",
31
+ "Verification uses one or more closed bash, zsh, or pwsh fences. Its fence",
32
+ "may add timeout=<integer><ms|s|m|h>; the section contains no other prose.",
33
+ "Unknown ## sections are retained as extensions; reserved section names are refused.",
34
+ ].join("\n"),
17
35
  },
18
36
  amend: {
19
37
  positional: "optional",
@@ -42,19 +60,28 @@ export const CONTRACT_COMMAND_SPECS = {
42
60
  usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--materialize-conflict] [--json]",
43
61
  purpose: "Deliver your work as this Contract's candidate.",
44
62
  details: [
45
- "A clean worktree delivers its HEAD; --include-dirty captures every non-ignored",
46
- "byte as an immutable commit object without changing the appointed worktree's HEAD",
47
- "or real index. Runs or reuses Verification and requests placement: when every",
48
- "prerequisite and declared gate is current, the same invocation places and claims.",
49
- "Otherwise the candidate is recorded and the Contract is tendered. A prior git",
50
- "commit is optional preparation — it never delivers, and delivering never",
51
- "satisfies a review gate.",
63
+ "The subject is the whole Contract. An Arc names the chapter you are in — it",
64
+ "frames the work, it never shrinks what the Contract accepts. Finishing a chapter",
65
+ "is progress; deliver is the different claim that the worktree, as it stands, is",
66
+ "the Contract's candidate.",
67
+ "",
68
+ "A clean worktree delivers its HEAD. --include-dirty captures every non-ignored",
69
+ "change as an immutable commit; your branch and index are untouched, so a prior",
70
+ "git commit is optional preparation, never a requirement.",
71
+ "",
72
+ "Delivering records the candidate and requests placement. If prerequisites and",
73
+ "every declared gate already hold, this same invocation places and the Contract is",
74
+ "claimed; otherwise the candidate stays recorded and the Contract is tendered.",
75
+ "Delivering again replaces the candidate and stales any earlier review of it.",
76
+ "Deliver never satisfies a review gate — review is someone's independent verdict,",
77
+ "not a side effect of delivering.",
52
78
  "",
53
79
  " --include-dirty Include all non-ignored worktree bytes, including an",
54
80
  " unmerged shared index, in the candidate commit.",
55
81
  " --materialize-conflict After a conflict result, project the judged targetHead",
56
- " into the worktree as an uncommitted merge. Not a",
57
- " delivery: resolve, then deliver with --include-dirty.",
82
+ " into the worktree as an uncommitted merge. With",
83
+ " --include-dirty, captured non-ignored bytes are kept",
84
+ " as the merge base. Not a delivery: resolve, then deliver with --include-dirty.",
58
85
  ].join("\n"),
59
86
  },
60
87
  review: {
@@ -62,7 +89,30 @@ export const CONTRACT_COMMAND_SPECS = {
62
89
  stdin: "optional",
63
90
  flags: { satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" },
64
91
  usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--json]",
65
- purpose: "Record one review verdict.",
92
+ purpose: "Record one review verdict over this Contract's current subject.",
93
+ details: [
94
+ "You are judging the whole Contract, not the current Arc. The subject is whatever",
95
+ "the Contract binds right now: the delivered candidate if one exists, or the current",
96
+ "document and worktree state before any delivery. Pre-delivery review is real",
97
+ "testimony over that subject — it creates no candidate, and without a delivered",
98
+ "candidate it can never place.",
99
+ "",
100
+ "The question --satisfied answers is: does the complete current subject meet",
101
+ "everything this Contract's acceptance asks — now, on evidence you already hold?",
102
+ "A finished chapter is never grounds for satisfied.",
103
+ "",
104
+ "--satisfied records that verdict and requests placement. If a delivered candidate,",
105
+ "prerequisites, and every declared gate hold, this same invocation places and the",
106
+ "Contract is claimed — a terminal state; a verdict that places cannot be taken back.",
107
+ "Verify the complete current subject first, then testify. If anything still blocks",
108
+ "placement, the verdict is recorded and the Contract stays active.",
109
+ "",
110
+ "--unsatisfied records what is not met and never requests placement.",
111
+ "",
112
+ "--summary is your testimony, not decoration. Satisfied: the conclusion that the",
113
+ "whole Contract is complete, and the evidence it rests on. Unsatisfied: the specific",
114
+ "blocker, missing evidence, or unmet term.",
115
+ ].join("\n"),
66
116
  },
67
117
  arc: {
68
118
  positional: "optional",
@@ -95,8 +145,8 @@ export const CONTRACT_COMMAND_SPECS = {
95
145
  ls: {
96
146
  positional: "optional",
97
147
  stdin: "none",
98
- flags: { json: "boolean" },
99
- usage: 'ls task[/] [--json]\nls kei[/] [--json]\nls aku[/] [--json]\nls aku/<akuma>[/] [--json]\nls "aku/*/*" [--json]',
148
+ flags: { limit: "value", json: "boolean" },
149
+ usage: 'ls task[/] [--limit <count>] [--json]\nls kei[/] [--limit <count>] [--json]\nls aku[/] [--json]\nls aku/<akuma>[/] [--limit <count>] [--json]\nls "aku/*/*" [--limit <count>] [--json]',
100
150
  purpose: "List one identity directory.",
101
151
  },
102
152
  audit: {
@@ -22,5 +22,10 @@ export type ContractMutationInput = Readonly<{
22
22
  establishWorld: () => Promise<WorldRoot>;
23
23
  execution: ExecutionContext;
24
24
  }>;
25
+ export declare function admitMarkdownBindSyntax(input: Readonly<{
26
+ markdown: string;
27
+ processCwd?: string;
28
+ cwd?: string;
29
+ }>): Promise<void>;
25
30
  export declare function invokeContractMutation(input: ContractMutationInput): Promise<InvocationResult>;
26
31
  export {};
@@ -33,13 +33,38 @@ async function selectContract(repo, selector, scope, library) {
33
33
  : resolveContextualContract(await library.list({ repo }), selector, scope);
34
34
  return { id, contract: library.of({ repo, id }) };
35
35
  }
36
+ function draftWarning(error) {
37
+ return { warning: `bind draft could not be preserved: ${error instanceof Error ? error.message : String(error)}` };
38
+ }
36
39
  async function bindDraftReceipt(establishWorld, markdown) {
37
40
  const { preserveBindDraft } = await import("../draft.js");
38
41
  try {
39
42
  return preserveBindDraft(await establishWorld(), markdown);
40
43
  }
41
44
  catch (error) {
42
- return { warning: `bind draft could not be preserved: ${error instanceof Error ? error.message : String(error)}` };
45
+ return draftWarning(error);
46
+ }
47
+ }
48
+ async function bindDraftReceiptAtCwd(input, markdown) {
49
+ const { preserveBindDraft } = await import("../draft.js");
50
+ try {
51
+ const { resolveInvocationCwd } = await import("../coordinates.js");
52
+ return await preserveBindDraft(await resolveInvocationCwd(input), markdown);
53
+ }
54
+ catch (error) {
55
+ return draftWarning(error);
56
+ }
57
+ }
58
+ export async function admitMarkdownBindSyntax(input) {
59
+ try {
60
+ const { parseMarkdownBindDocument } = await import("../../library/contract.js");
61
+ parseMarkdownBindDocument(input.markdown);
62
+ }
63
+ catch (error) {
64
+ if (!(error instanceof TypeError))
65
+ throw error;
66
+ const { BindDraftError } = await import("../draft.js");
67
+ throw new BindDraftError(error, await bindDraftReceiptAtCwd(input, input.markdown));
43
68
  }
44
69
  }
45
70
  async function invokeBind(input) {
@@ -137,31 +137,63 @@ function parseRegion(parts) {
137
137
  output: parts.output,
138
138
  };
139
139
  }
140
+ function akumaCatalogQuery(query, parts) {
141
+ const limit = optionalFlag(parts.flags, "limit");
142
+ if (query.kind !== "akuma") {
143
+ if (limit !== undefined)
144
+ refuse("ls", "--limit requires an Akuma instance directory");
145
+ return query;
146
+ }
147
+ if (limit !== undefined && (!/^[1-9][0-9]*$/u.test(limit) || !Number.isSafeInteger(Number(limit))))
148
+ refuse("ls", "--limit requires a positive safe integer");
149
+ return {
150
+ ...query,
151
+ ...(limit === undefined ? {} : { limit: Number(limit) }),
152
+ };
153
+ }
154
+ function listLimit(parts) {
155
+ const limit = optionalFlag(parts.flags, "limit");
156
+ if (limit !== undefined && (!/^[1-9][0-9]*$/u.test(limit) || !Number.isSafeInteger(Number(limit))))
157
+ refuse("ls", "--limit requires a positive safe integer");
158
+ return limit === undefined ? undefined : Number(limit);
159
+ }
160
+ function taskCatalogQuery(path, limit) {
161
+ if (path === "task" || path === "task/") {
162
+ return { kind: "tasks", namespace: [], ...(limit === undefined ? {} : { limit }) };
163
+ }
164
+ if (!path.startsWith("task/"))
165
+ return null;
166
+ if (!path.endsWith("/"))
167
+ refuse("ls", `invalid Task namespace selector: ${path}`);
168
+ const body = path.slice("task/".length, -1);
169
+ if (body.length === 0 || body.split("/").some((segment) => segment.length === 0))
170
+ refuse("ls", `invalid Task namespace selector: ${path}`);
171
+ try {
172
+ const namespace = parseTaskNamespaceSelector(path);
173
+ return { kind: "tasks", namespace, ...(limit === undefined ? {} : { limit }) };
174
+ }
175
+ catch (error) {
176
+ refuse("ls", error instanceof Error ? error.message : `invalid Task namespace selector: ${path}`);
177
+ }
178
+ }
140
179
  function parseLs(parts) {
141
180
  const path = parts.positionals[0];
142
- if (path === "task" || path === "task/")
143
- return { command: "ls", query: { kind: "tasks", namespace: [] }, output: parts.output };
144
- if (path.startsWith("task/")) {
145
- if (!path.endsWith("/"))
146
- refuse("ls", `invalid Task namespace selector: ${path}`);
147
- const body = path.slice("task/".length, -1);
148
- if (body.length === 0 || body.split("/").some((segment) => segment.length === 0))
149
- refuse("ls", `invalid Task namespace selector: ${path}`);
150
- try {
151
- const namespace = parseTaskNamespaceSelector(path);
152
- return { command: "ls", query: { kind: "tasks", namespace }, output: parts.output };
153
- }
154
- catch (error) {
155
- refuse("ls", error instanceof Error ? error.message : `invalid Task namespace selector: ${path}`);
156
- }
181
+ const limit = listLimit(parts);
182
+ const taskQuery = taskCatalogQuery(path, limit);
183
+ if (taskQuery !== null)
184
+ return { command: "ls", query: taskQuery, output: parts.output };
185
+ if (path === "kei" || path === "kei/") {
186
+ return {
187
+ command: "ls",
188
+ query: { kind: "contracts", ...(limit === undefined ? {} : { limit }) },
189
+ output: parts.output,
190
+ };
157
191
  }
158
- if (path === "kei" || path === "kei/")
159
- return { command: "ls", query: { kind: "contracts" }, output: parts.output };
160
192
  try {
161
193
  const query = parseAkumaCatalogPath(path);
162
194
  if (query === null)
163
195
  refuse("ls", "ls requires a supported identity directory selector");
164
- return { command: "ls", query, output: parts.output };
196
+ return { command: "ls", query: akumaCatalogQuery(query, parts), output: parts.output };
165
197
  }
166
198
  catch (error) {
167
199
  if (error instanceof CliUsageError)
@@ -1,5 +1,4 @@
1
- /* eslint-disable max-lines -- Task edge keeps native reads, forwarding, and local dispatch together. */
2
- import { Tasks, } from "../../task/index.js";
1
+ import { Tasks, taskRowViewLimit, } from "../../task/index.js";
3
2
  import { taskCompositionNamespaceHeader } from "../../task/compose-language.js";
4
3
  import { observeTaskDetails } from "../../task/operations.js";
5
4
  import { parseTaskNamespaceSelector } from "../../task/catalog.js";
@@ -51,6 +50,14 @@ function limit(command) {
51
50
  const raw = value(command, "limit");
52
51
  return raw === undefined ? undefined : Number(raw);
53
52
  }
53
+ function validateTaskRowView(command) {
54
+ if (command.action === "ls" ||
55
+ command.action === "ready" ||
56
+ command.action === "blocked" ||
57
+ command.action === "query") {
58
+ taskRowViewLimit(limit(command));
59
+ }
60
+ }
54
61
  function explicitListNamespace(command) {
55
62
  return command.action === "ls" && command.positionals.length === 1
56
63
  ? parseTaskNamespaceSelector(command.positionals[0])
@@ -257,6 +264,7 @@ function establishesWorld(command) {
257
264
  }
258
265
  // eslint-disable-next-line complexity -- this is the single CLI edge ordering world, context, forwarding, and local execution.
259
266
  export async function invokeTask(command, input) {
267
+ validateTaskRowView(command);
260
268
  const planOnly = command.action === "compose" && command.flags.plan === true;
261
269
  const composeMarkdown = command.action === "compose" ? await input.readStdin() : undefined;
262
270
  const composition = composeMarkdown === undefined ? undefined : taskCompositionNamespaceHeader(composeMarkdown);
@@ -1,4 +1,4 @@
1
- import { MAX_TASK_LIMIT, TASK_RELATION_PREDICATE_FIELDS, normalizeTaskQuery, } from "../../task/query.js";
1
+ import { TASK_RELATION_PREDICATE_FIELDS, normalizeTaskQuery, } from "../../task/query.js";
2
2
  function syntax(message, offset) {
3
3
  throw new Error(`${message} at column ${offset + 1}`);
4
4
  }
@@ -262,9 +262,8 @@ export function parseTaskQueryExpression(source) {
262
262
  return normalizeTaskQuery(new Parser(lex(source)).parse());
263
263
  }
264
264
  export function validateTaskLimit(source) {
265
- if (!/^[1-9][0-9]*$/u.test(source) || Number(source) > MAX_TASK_LIMIT) {
266
- throw new Error(`--limit must be an integer from 1 to ${MAX_TASK_LIMIT}`);
267
- }
265
+ if (!/^[1-9][0-9]*$/u.test(source) || !Number.isSafeInteger(Number(source)))
266
+ throw new Error("--limit requires a positive safe integer");
268
267
  }
269
268
  export function validateTaskParent(source) {
270
269
  try {
@@ -22,4 +22,17 @@ export type CliCoordinateInput = Readonly<{
22
22
  gitPath?: string;
23
23
  command: ParsedCommand;
24
24
  }>;
25
+ export declare function resolveInvocationCwd(input: Readonly<{
26
+ processCwd?: string;
27
+ cwd?: string;
28
+ }>): Promise<string>;
29
+ export declare const cliCoordinateDiscovery: {
30
+ repoAt(coordinate: string, gitPath?: string): Promise<Repo>;
31
+ worldResolve(cwd: string, repositoryRoot?: string): Promise<Readonly<{
32
+ root: WorldRoot | null;
33
+ candidate: WorldRoot | null;
34
+ establish: () => Promise<WorldRoot>;
35
+ }>>;
36
+ resolve(input: CliCoordinateInput): Promise<CliCoordinates>;
37
+ };
25
38
  export declare function resolveCliCoordinates(input: CliCoordinateInput): Promise<CliCoordinates>;
@@ -11,11 +11,15 @@ async function canonicalInvocationCwd(input) {
11
11
  throw new CliUsageError(`invocation cwd is not an existing directory: ${input}`);
12
12
  }
13
13
  }
14
+ export async function resolveInvocationCwd(input) {
15
+ const processCwd = resolve(input.processCwd ?? ".");
16
+ return canonicalInvocationCwd(resolve(processCwd, input.cwd ?? "."));
17
+ }
14
18
  async function discoverRepoAt(coordinate, gitPath) {
15
19
  try {
16
20
  return {
17
21
  kind: "present",
18
- repo: await Repo.at({ path: coordinate, ...(gitPath === undefined ? {} : { gitPath }) }),
22
+ repo: await cliCoordinateDiscovery.repoAt(coordinate, gitPath),
19
23
  };
20
24
  }
21
25
  catch (error) {
@@ -44,9 +48,40 @@ function repoFor(use, discovery) {
44
48
  throw discovery.error;
45
49
  return undefined;
46
50
  }
51
+ export const cliCoordinateDiscovery = {
52
+ async repoAt(coordinate, gitPath) {
53
+ return Repo.at({ path: coordinate, ...(gitPath === undefined ? {} : { gitPath }) });
54
+ },
55
+ async worldResolve(cwd, repositoryRoot) {
56
+ return World.resolve({ cwd, ...(repositoryRoot === undefined ? {} : { repositoryRoot }) });
57
+ },
58
+ async resolve(input) {
59
+ const cwd = await resolveInvocationCwd(input);
60
+ const invocationRepo = await discoverRepoAt(cwd, input.gitPath);
61
+ const selectedRepo = input.repo === undefined ? invocationRepo : await discoverRepoAt(resolve(cwd, input.repo), input.gitPath);
62
+ const worldRepo = invocationRepo.kind === "present" ? invocationRepo.repo : undefined;
63
+ const repo = repoFor(commandRepoPolicy(input.command).use, selectedRepo);
64
+ const world = await resolveWorld(cwd, worldRepo);
65
+ const boundary = worldRepo === undefined ? (world.root ?? world.candidate ?? cwd) : worldRepo.cwd;
66
+ return {
67
+ cwd,
68
+ cwdSource: input.cwd === undefined ? "process" : "input",
69
+ ...(repo === undefined ? {} : { repo }),
70
+ world: world.root,
71
+ candidateWorld: world.candidate,
72
+ taskContext: {
73
+ directory: cwd,
74
+ boundary,
75
+ writeRoot: worldRepo === undefined ? boundary : cwd,
76
+ managed: await managedContractWorktree(boundary),
77
+ },
78
+ establishWorld: world.establish,
79
+ };
80
+ },
81
+ };
47
82
  async function resolveWorld(cwd, repo) {
48
83
  try {
49
- const resolution = await World.resolve({ cwd, ...(repo === undefined ? {} : { repositoryRoot: repo.root }) });
84
+ const resolution = await cliCoordinateDiscovery.worldResolve(cwd, repo?.root);
50
85
  return {
51
86
  root: resolution.root,
52
87
  candidate: resolution.candidate,
@@ -69,26 +104,5 @@ async function resolveWorld(cwd, repo) {
69
104
  }
70
105
  }
71
106
  export async function resolveCliCoordinates(input) {
72
- const processCwd = resolve(input.processCwd ?? ".");
73
- const cwd = await canonicalInvocationCwd(resolve(processCwd, input.cwd ?? "."));
74
- const invocationRepo = await discoverRepoAt(cwd, input.gitPath);
75
- const selectedRepo = input.repo === undefined ? invocationRepo : await discoverRepoAt(resolve(cwd, input.repo), input.gitPath);
76
- const worldRepo = invocationRepo.kind === "present" ? invocationRepo.repo : undefined;
77
- const repo = repoFor(commandRepoPolicy(input.command).use, selectedRepo);
78
- const world = await resolveWorld(cwd, worldRepo);
79
- const boundary = worldRepo === undefined ? (world.root ?? world.candidate ?? cwd) : worldRepo.cwd;
80
- return {
81
- cwd,
82
- cwdSource: input.cwd === undefined ? "process" : "input",
83
- ...(repo === undefined ? {} : { repo }),
84
- world: world.root,
85
- candidateWorld: world.candidate,
86
- taskContext: {
87
- directory: cwd,
88
- boundary,
89
- writeRoot: worldRepo === undefined ? boundary : cwd,
90
- managed: await managedContractWorktree(boundary),
91
- },
92
- establishWorld: world.establish,
93
- };
107
+ return cliCoordinateDiscovery.resolve(input);
94
108
  }
@@ -5,4 +5,4 @@ export declare class BindDraftError extends Error {
5
5
  readonly draft: BindDraftReceipt;
6
6
  constructor(original: unknown, draft: BindDraftReceipt);
7
7
  }
8
- export declare function preserveBindDraft(world: WorldRoot, markdown: string, now?: number): Promise<BindDraftReceipt>;
8
+ export declare function preserveBindDraft(world: WorldRoot | string, markdown: string, now?: number): Promise<BindDraftReceipt>;
@@ -162,7 +162,11 @@ async function invokeCatalog(parsed, world, repo, home) {
162
162
  if (parsed.query.kind === "archetypes") {
163
163
  return {
164
164
  kind: "catalog",
165
- catalog: await Keiyaku.ls({ query: parsed.query, ...(home === undefined ? {} : { home }) }),
165
+ catalog: await Keiyaku.ls({
166
+ query: parsed.query,
167
+ ...(world === null ? {} : { path: world }),
168
+ ...(home === undefined ? {} : { home }),
169
+ }),
166
170
  };
167
171
  }
168
172
  if (world === null)
@@ -406,6 +410,15 @@ export async function invoke(invocation, runtime = {}) {
406
410
  }
407
411
  const acquiredRuntime = await withAcquiredStdin(command, withResolvedTaskActor(command, runtime));
408
412
  runtime.onOperationStart?.();
413
+ if (command.command === "bind" && command.forkOf === undefined) {
414
+ const markdown = await (acquiredRuntime.readStdin ?? readStdin)();
415
+ const { admitMarkdownBindSyntax } = await import("./commands/contract-invoke.js");
416
+ await admitMarkdownBindSyntax({
417
+ markdown,
418
+ ...(runtime.cwd === undefined ? {} : { processCwd: runtime.cwd }),
419
+ ...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
420
+ });
421
+ }
409
422
  return await invokeParsed({
410
423
  ...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
411
424
  ...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
@@ -16,7 +16,6 @@ type SnapshotCoreOptions = Readonly<{
16
16
  facts?: readonly string[];
17
17
  }>;
18
18
  export declare function snapshotText(view: SnapshotView, context: TextRenderContext, options?: SnapshotCoreOptions): string;
19
- export declare function killObservationText(id: string, evidence: KillEvidence, observation: AkumaObservationStage, context: TextRenderContext, alias?: string): string;
20
19
  export declare function killResultText(id: string, evidence: KillEvidence, alias?: string): string;
21
20
  export declare function mutationObservationStageText(id: string, observation: AkumaObservationStage, context: TextRenderContext, options?: SnapshotCoreOptions & Readonly<{
22
21
  showLife?: boolean;
@@ -182,38 +182,15 @@ function taskDispositionMark(disposition) {
182
182
  return "●";
183
183
  return disposition === "blocked" ? "‖" : "○";
184
184
  }
185
- function changeStat(group) {
186
- let added = 0;
187
- let removed = 0;
188
- for (const change of group) {
189
- if (change.diffstat === undefined)
190
- return "+? -?";
191
- added += change.diffstat.added;
192
- removed += change.diffstat.removed;
193
- }
194
- return `+${added} -${removed}`;
195
- }
196
- function groupedChangeRows(changes) {
197
- const groups = [];
198
- const seen = new Map();
199
- for (const change of changes) {
200
- const index = seen.get(change.path);
201
- if (index === undefined) {
202
- seen.set(change.path, groups.length);
203
- groups.push([change]);
204
- }
205
- else
206
- groups[index].push(change);
207
- }
208
- return groups.map((group) => ({ path: group[0].path, stat: changeStat(group) }));
185
+ function changeStat(change) {
186
+ return change.diffstat === undefined ? "+? -?" : `+${change.diffstat.added} -${change.diffstat.removed}`;
209
187
  }
210
188
  function renderReportedChangeLines(snapshot) {
211
- const rows = groupedChangeRows(snapshot.reportedChanges);
212
- const width = rows.reduce((max, row) => Math.max(max, row.stat.length), 0);
189
+ const width = snapshot.reportedChanges.reduce((max, change) => Math.max(max, changeStat(change).length), 0);
213
190
  return [
214
191
  `changes ${snapshot.reportedChanges.length + snapshot.reportedChangesOmitted}`,
215
- ...rows.map((row) => ` ${row.stat.padEnd(width)} ${safeText(row.path)}`),
216
- ...(snapshot.reportedChangesOmitted > 0 ? [` ⋮ ${snapshot.reportedChangesOmitted} earlier changes`] : []),
192
+ ...snapshot.reportedChanges.map((change) => ` ${changeStat(change).padEnd(width)} ${safeText(change.path)}`),
193
+ ...(snapshot.reportedChangesOmitted > 0 ? [` ⋮ ${snapshot.reportedChangesOmitted} more files`] : []),
217
194
  ];
218
195
  }
219
196
  function renderTaskRow(row, columns) {
@@ -292,16 +269,6 @@ function killResultLabel(evidence) {
292
269
  return "✓ already stopped";
293
270
  return `! not killed · ${evidence}`;
294
271
  }
295
- function latestKillActivity(snapshot, context) {
296
- const rows = snapshot.entries.flatMap((entry) => (entry.kind === "row" ? [entry.row] : []));
297
- const latest = rows.reduce((selected, row) => (selected === undefined || row.sequence > selected.sequence ? row : selected), undefined);
298
- return latest === undefined ? [] : groupedRows([latest], context);
299
- }
300
- export function killObservationText(id, evidence, observation, context, alias) {
301
- const heading = snapshotHeading(id, alias, observation.kind === "observed" ? observation.contract : undefined);
302
- const activity = observation.kind === "observed" ? latestKillActivity(observation.status.timeline, context) : [];
303
- return [...heading, ...activity, "", killResultLabel(evidence)].join("\n");
304
- }
305
272
  export function killResultText(id, evidence, alias) {
306
273
  return [...snapshotHeading(id, alias, undefined), "", killResultLabel(evidence)].join("\n");
307
274
  }
@@ -3,8 +3,11 @@ import { DEFAULT_CONTEXT, akumaRawAnswer, associatedIdentity, historyText, killR
3
3
  import { safeText } from "./terminal.js";
4
4
  export { akumaRawAnswer } from "./akuma-activity.js";
5
5
  function dispatchLines(stage) {
6
- if (stage.kind === "none" || stage.kind === "dispatched")
6
+ if (stage.kind === "none")
7
7
  return [];
8
+ if (stage.kind === "dispatched") {
9
+ return (stage.seatClose ?? []).map((lag) => `dispatch lag ${lag.kind} ${safeText(lag.diagnostic)}`);
10
+ }
8
11
  if (stage.failure.kind === "conflict")
9
12
  return [`dispatch failed conflict ${stage.failure.current.contractId}`];
10
13
  return [`dispatch failed ${stage.failure.kind} ${safeText(stage.failure.diagnostic)}`];
@@ -1,4 +1,4 @@
1
- import { cleanupLines, leakLines, receiptPayload, receiptRow, stopLines, titleLines } from "./receipt.js";
1
+ import { cleanupLines, leakLines, receiptPayload, receiptRow, seatCloseLines, stopLines, titleLines, } from "./receipt.js";
2
2
  import { renderRefusalFacts } from "./refusal.js";
3
3
  import { gitShortStat, renderOpaqueBlock } from "./terminal.js";
4
4
  const CHILD = " ";
@@ -78,6 +78,9 @@ function obligationLines(result, columns) {
78
78
  return [
79
79
  ...(result.cleanup === undefined ? [] : cleanupLines(result.cleanup, columns)),
80
80
  ...(result.leak === undefined ? [] : leakLines(result.leak, columns)),
81
+ ...(result.seatClose === undefined || result.seatClose.length === 0
82
+ ? []
83
+ : seatCloseLines(result.seatClose, columns)),
81
84
  ];
82
85
  }
83
86
  function recordLines(result, columns) {