@astrosheep/keiyaku 4.5.7 → 4.5.9

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 (244) hide show
  1. package/README.md +10 -0
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +3 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +12 -11
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +33 -12
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
  12. package/build/src/akuma/abort.d.ts +2 -1
  13. package/build/src/akuma/abort.js +6 -23
  14. package/build/src/akuma/akuma-handle.js +4 -2
  15. package/build/src/akuma/akuma-observe.d.ts +2 -0
  16. package/build/src/akuma/akuma-observe.js +1 -0
  17. package/build/src/akuma/akuma-product.js +9 -7
  18. package/build/src/akuma/akuma.d.ts +392 -9
  19. package/build/src/akuma/akuma.js +31 -1
  20. package/build/src/akuma/allowed.d.ts +1 -1
  21. package/build/src/akuma/allowed.js +1 -0
  22. package/build/src/akuma/archetype.js +1 -1
  23. package/build/src/akuma/body.d.ts +8 -5
  24. package/build/src/akuma/body.js +12 -5
  25. package/build/src/akuma/call-request.d.ts +80 -0
  26. package/build/src/akuma/call-request.js +211 -0
  27. package/build/src/akuma/heart/facts.d.ts +16 -78
  28. package/build/src/akuma/heart/facts.js +11 -0
  29. package/build/src/akuma/heart/index.d.ts +3 -2
  30. package/build/src/akuma/heart/index.js +4 -1
  31. package/build/src/akuma/heart/request-authority.d.ts +5 -4
  32. package/build/src/akuma/heart/request-authority.js +20 -34
  33. package/build/src/akuma/heart/request-rows.js +12 -23
  34. package/build/src/akuma/heart/schema.d.ts +1 -1
  35. package/build/src/akuma/heart/schema.js +5 -13
  36. package/build/src/akuma/index.d.ts +1 -1
  37. package/build/src/akuma/index.js +1 -1
  38. package/build/src/akuma/projection-read.d.ts +1 -0
  39. package/build/src/akuma/projection-read.js +8 -1
  40. package/build/src/akuma/projection.d.ts +907 -137
  41. package/build/src/akuma/projection.js +193 -9
  42. package/build/src/akuma/provider.d.ts +30 -3
  43. package/build/src/akuma/provider.js +111 -0
  44. package/build/src/akuma/providers/acp/core.d.ts +2 -2
  45. package/build/src/akuma/providers/acp/core.js +13 -6
  46. package/build/src/akuma/providers/acp/index.js +5 -4
  47. package/build/src/akuma/providers/claude/events.d.ts +2 -2
  48. package/build/src/akuma/providers/claude/events.js +16 -3
  49. package/build/src/akuma/providers/claude/index.d.ts +3 -3
  50. package/build/src/akuma/providers/claude/index.js +16 -5
  51. package/build/src/akuma/providers/codex-app-server/events.d.ts +2 -2
  52. package/build/src/akuma/providers/codex-app-server/events.js +25 -4
  53. package/build/src/akuma/providers/codex-app-server/index.js +18 -6
  54. package/build/src/akuma/providers/grok-build/index.js +5 -4
  55. package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
  56. package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
  57. package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
  58. package/build/src/akuma/providers/pi/index.js +72 -58
  59. package/build/src/akuma/request-lifecycle.d.ts +4 -10
  60. package/build/src/akuma/request-lifecycle.js +7 -5
  61. package/build/src/akuma/request-rendezvous.d.ts +26 -0
  62. package/build/src/akuma/request-rendezvous.js +100 -0
  63. package/build/src/akuma/request-serve.d.ts +6 -66
  64. package/build/src/akuma/request-serve.js +83 -210
  65. package/build/src/akuma/request-wire.d.ts +109 -115
  66. package/build/src/akuma/request-wire.js +63 -318
  67. package/build/src/akuma/requests.d.ts +19 -47
  68. package/build/src/akuma/requests.js +51 -107
  69. package/build/src/akuma/turn-drive.d.ts +5 -3
  70. package/build/src/akuma/turn-drive.js +39 -11
  71. package/build/src/akuma-body.d.ts +7 -2
  72. package/build/src/akuma-body.js +68 -46
  73. package/build/src/body/amend.js +18 -19
  74. package/build/src/cli/accepted.d.ts +1 -1
  75. package/build/src/cli/accepted.js +2 -2
  76. package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
  77. package/build/src/cli/commands/akuma-invoke.js +17 -9
  78. package/build/src/cli/commands/akuma.js +8 -8
  79. package/build/src/cli/commands/contract-invoke.d.ts +3 -2
  80. package/build/src/cli/commands/contract-invoke.js +42 -30
  81. package/build/src/cli/commands/contract.d.ts +16 -20
  82. package/build/src/cli/commands/contract.js +58 -25
  83. package/build/src/cli/commands/install.d.ts +2 -1
  84. package/build/src/cli/commands/install.js +3 -2
  85. package/build/src/cli/commands/task-invoke.d.ts +3 -0
  86. package/build/src/cli/commands/task-invoke.js +23 -140
  87. package/build/src/cli/commands/task.js +54 -20
  88. package/build/src/cli/invoke.js +39 -25
  89. package/build/src/cli/main.js +2 -1
  90. package/build/src/cli/parse.d.ts +2 -2
  91. package/build/src/cli/parse.js +56 -27
  92. package/build/src/cli/render/akuma-activity.d.ts +3 -0
  93. package/build/src/cli/render/akuma-activity.js +45 -29
  94. package/build/src/cli/render/akuma-tool.d.ts +5 -1
  95. package/build/src/cli/render/akuma.js +4 -8
  96. package/build/src/cli/render/audit.js +1 -1
  97. package/build/src/cli/render/catalog.js +80 -21
  98. package/build/src/cli/render/contract-observation.d.ts +2 -0
  99. package/build/src/cli/render/contract-observation.js +11 -0
  100. package/build/src/cli/render/contract.js +35 -62
  101. package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
  102. package/build/src/cli/render/kanshi-akuma.js +132 -0
  103. package/build/src/cli/render/kanshi.js +131 -213
  104. package/build/src/cli/render/receipt.d.ts +1 -2
  105. package/build/src/cli/render/receipt.js +76 -26
  106. package/build/src/cli/render/refusal.js +2 -10
  107. package/build/src/cli/render/region.js +5 -2
  108. package/build/src/cli/render/settings.d.ts +1 -1
  109. package/build/src/cli/render/settings.js +27 -8
  110. package/build/src/cli/render/task.js +22 -5
  111. package/build/src/cli/render/terminal.d.ts +32 -1
  112. package/build/src/cli/render/terminal.js +77 -1
  113. package/build/src/cli/result.d.ts +3 -3
  114. package/build/src/cli/runtime.js +4 -2
  115. package/build/src/cli/selectors.d.ts +2 -1
  116. package/build/src/cli/selectors.js +4 -3
  117. package/build/src/cli/square-edge.js +120 -36
  118. package/build/src/cli/usage.js +2 -1
  119. package/build/src/contract-guidance.d.ts +5 -0
  120. package/build/src/contract-guidance.js +121 -0
  121. package/build/src/contract-worktree.d.ts +0 -1
  122. package/build/src/contract-worktree.js +32 -83
  123. package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
  124. package/build/src/coordination/sqlite-transaction-lock.js +5 -0
  125. package/build/src/core/facts/codec.d.ts +2 -0
  126. package/build/src/core/facts/codec.js +4 -0
  127. package/build/src/core/verbs/placement.d.ts +6 -1
  128. package/build/src/core/verbs/placement.js +5 -3
  129. package/build/src/dispatch/index.d.ts +0 -2
  130. package/build/src/dispatch/index.js +54 -55
  131. package/build/src/git/admission.js +2 -2
  132. package/build/src/git/hooks.d.ts +9 -15
  133. package/build/src/git/hooks.js +23 -317
  134. package/build/src/git/nuke.d.ts +2 -1
  135. package/build/src/git/nuke.js +39 -21
  136. package/build/src/git/private-state-seat.d.ts +12 -0
  137. package/build/src/git/private-state-seat.js +39 -0
  138. package/build/src/git/process.d.ts +6 -0
  139. package/build/src/git/process.js +26 -11
  140. package/build/src/git/read-observation.js +29 -20
  141. package/build/src/git/reconcile.d.ts +13 -1
  142. package/build/src/git/reconcile.js +70 -11
  143. package/build/src/git/ref-migration.d.ts +22 -0
  144. package/build/src/git/ref-migration.js +55 -0
  145. package/build/src/git/repository.d.ts +10 -6
  146. package/build/src/git/repository.js +16 -8
  147. package/build/src/git/target-placement.d.ts +1 -0
  148. package/build/src/git/target-placement.js +5 -0
  149. package/build/src/git/tender.d.ts +1 -0
  150. package/build/src/git/terminal-reconcile.d.ts +1 -1
  151. package/build/src/git/terminal-reconcile.js +22 -20
  152. package/build/src/git/workspace.d.ts +14 -0
  153. package/build/src/git/workspace.js +44 -0
  154. package/build/src/kanshi/index.d.ts +1 -1
  155. package/build/src/kanshi/read.js +16 -16
  156. package/build/src/kanshi/report.d.ts +2 -2
  157. package/build/src/library/address.d.ts +9 -3
  158. package/build/src/library/address.js +3 -2
  159. package/build/src/library/akuma-creation.d.ts +4 -3
  160. package/build/src/library/akuma-creation.js +19 -13
  161. package/build/src/library/audit.d.ts +14 -6
  162. package/build/src/library/audit.js +13 -23
  163. package/build/src/library/catalog.d.ts +3 -1
  164. package/build/src/library/catalog.js +20 -6
  165. package/build/src/library/composition.d.ts +385 -0
  166. package/build/src/library/composition.js +28 -0
  167. package/build/src/library/configuration.js +8 -2
  168. package/build/src/library/continuation.js +66 -30
  169. package/build/src/library/contract-bind.js +10 -2
  170. package/build/src/library/contract-forwarding-reconciliation-result.d.ts +102 -0
  171. package/build/src/library/contract-forwarding-reconciliation-result.js +92 -0
  172. package/build/src/library/contract-forwarding-result.d.ts +4464 -0
  173. package/build/src/library/contract-forwarding-result.js +521 -0
  174. package/build/src/library/contract-forwarding.d.ts +71 -0
  175. package/build/src/library/contract-forwarding.js +114 -0
  176. package/build/src/library/contract-handle.d.ts +38 -0
  177. package/build/src/library/contract-handle.js +314 -0
  178. package/build/src/library/contract-operations.d.ts +214 -69
  179. package/build/src/library/contract-operations.js +189 -118
  180. package/build/src/library/contract-types.d.ts +7 -3
  181. package/build/src/library/contract.d.ts +21 -34
  182. package/build/src/library/contract.js +29 -287
  183. package/build/src/library/fleet-result.d.ts +1580 -0
  184. package/build/src/library/fleet-result.js +98 -0
  185. package/build/src/library/fleet.d.ts +112 -54
  186. package/build/src/library/fleet.js +211 -71
  187. package/build/src/library/input.d.ts +3 -1
  188. package/build/src/library/input.js +11 -1
  189. package/build/src/library/keiyaku.d.ts +388 -20
  190. package/build/src/library/keiyaku.js +13 -21
  191. package/build/src/library/mutation.d.ts +3 -3
  192. package/build/src/library/mutation.js +5 -9
  193. package/build/src/library/nuke.d.ts +1 -1
  194. package/build/src/library/nuke.js +4 -3
  195. package/build/src/library/reconcile.d.ts +4 -0
  196. package/build/src/library/reconcile.js +2 -0
  197. package/build/src/library/refusal.d.ts +0 -9
  198. package/build/src/library/refusal.js +0 -7
  199. package/build/src/protocol/amend.js +56 -50
  200. package/build/src/protocol/attempt.d.ts +2 -0
  201. package/build/src/protocol/attempt.js +8 -1
  202. package/build/src/protocol/completion.js +7 -0
  203. package/build/src/protocol/deliver.js +6 -2
  204. package/build/src/protocol/operations.d.ts +4 -1
  205. package/build/src/protocol/operations.js +5 -2
  206. package/build/src/protocol/placement.d.ts +1 -0
  207. package/build/src/protocol/placement.js +52 -38
  208. package/build/src/protocol/read/observation.d.ts +1 -4
  209. package/build/src/protocol/read/observation.js +2 -15
  210. package/build/src/protocol/reintegrate.js +62 -58
  211. package/build/src/protocol/review.js +5 -0
  212. package/build/src/protocol/run.js +17 -13
  213. package/build/src/runtime/proc/run.d.ts +9 -0
  214. package/build/src/runtime/proc/run.js +51 -4
  215. package/build/src/runtime/proc/termination.js +26 -22
  216. package/build/src/runtime/proc/windows-launch.exe +0 -0
  217. package/build/src/settlement/holder.d.ts +2 -1
  218. package/build/src/settlement/holder.js +15 -4
  219. package/build/src/settlement/settle.js +99 -33
  220. package/build/src/task/board.d.ts +68 -27
  221. package/build/src/task/board.js +31 -1
  222. package/build/src/task/catalog.d.ts +4 -0
  223. package/build/src/task/catalog.js +23 -0
  224. package/build/src/task/compose-language.js +33 -7
  225. package/build/src/task/compose-parser.d.ts +1 -1
  226. package/build/src/task/compose-parser.js +1 -1
  227. package/build/src/task/compose.js +2 -0
  228. package/build/src/task/index.d.ts +12 -4
  229. package/build/src/task/index.js +97 -16
  230. package/build/src/task/mutation-result.d.ts +923 -0
  231. package/build/src/task/mutation-result.js +140 -0
  232. package/build/src/task/mutation.d.ts +552 -28
  233. package/build/src/task/mutation.js +304 -97
  234. package/build/src/task/operations.d.ts +1 -4
  235. package/build/src/task/operations.js +0 -6
  236. package/build/src/task/public.d.ts +2 -0
  237. package/build/src/task/public.js +1 -0
  238. package/build/src/workspace-place.d.ts +7 -2
  239. package/build/src/workspace-place.js +34 -24
  240. package/build/src/world.d.ts +1 -0
  241. package/build/src/world.js +11 -0
  242. package/package.json +8 -6
  243. package/build/src/akuma/request-execution.d.ts +0 -8
  244. package/build/src/akuma/request-execution.js +0 -98
@@ -1,49 +1,21 @@
1
- import { type CallRequestClaim, type DeliverRequestClaim, type ForwardedDeliveryReference, type ForwardedReviewReference, type KillRequestClaim, type ReviewRequestClaim, type TellRequestClaim, type UpstreamRequestOutcome, type WaitRequestClaim } from "./request-wire.js";
2
- import { type TaskMutationRequest } from "../task/mutation.js";
3
- export type { UpstreamRequestOutcome } from "./request-wire.js";
4
- export declare class AkumaBodyRequestError extends Error {
5
- readonly outcome: "refused" | "voided";
6
- readonly diagnostic: string;
7
- readonly kind = "akuma-body-request";
8
- constructor(outcome: "refused" | "voided", diagnostic: string);
9
- }
10
- export declare function injectedBodyRequests(): string | null;
11
- export declare function requestBodyCall(input: Omit<CallRequestClaim, "action"> & Readonly<{
1
+ export { AkumaBodyRequestError, requestBodyCommand } from "./request-rendezvous.js";
2
+ export type ExecutionChannel = Readonly<{
3
+ kind: "local";
4
+ }> | Readonly<{
5
+ kind: "body-request";
12
6
  directory: string;
13
- }>): Promise<import("./identity.js").AkuId>;
14
- export declare function requestBodyTask(input: Readonly<{
15
- directory: string;
16
- world: string;
17
- request: TaskMutationRequest;
18
- id?: string;
19
- }>): Promise<unknown>;
20
- export declare function requestBodyWait(input: Omit<WaitRequestClaim, "action" | "id"> & Readonly<{
21
- directory: string;
22
- id?: string;
23
- }>): Promise<UpstreamRequestOutcome>;
24
- export declare function requestBodyTell(input: Omit<TellRequestClaim, "action" | "id"> & Readonly<{
25
- directory: string;
26
- id?: string;
27
- }>): Promise<UpstreamRequestOutcome>;
28
- export declare function requestBodyKill(input: Omit<KillRequestClaim, "action" | "id"> & Readonly<{
29
- directory: string;
30
- id?: string;
31
- }>): Promise<UpstreamRequestOutcome>;
32
- type ContractRequestInput<T extends DeliverRequestClaim | ReviewRequestClaim> = Omit<T, "action" | "id"> & Readonly<{
33
- directory: string;
34
- signal?: AbortSignal;
35
7
  }>;
36
- type BodyDeliverInput = ContractRequestInput<DeliverRequestClaim>;
37
- export declare function requestBodyDeliver(input: BodyDeliverInput & Readonly<{
38
- id?: never;
39
- }>): Promise<UpstreamRequestOutcome>;
40
- export declare function requestBodyDeliver(input: BodyDeliverInput & Readonly<{
41
- id: string;
42
- }>): Promise<UpstreamRequestOutcome | ForwardedDeliveryReference>;
43
- type BodyReviewInput = ContractRequestInput<ReviewRequestClaim>;
44
- export declare function requestBodyReview(input: BodyReviewInput & Readonly<{
45
- id?: never;
46
- }>): Promise<UpstreamRequestOutcome>;
47
- export declare function requestBodyReview(input: BodyReviewInput & Readonly<{
48
- id: string;
49
- }>): Promise<UpstreamRequestOutcome | ForwardedReviewReference>;
8
+ export type ExecutionContext = Readonly<{
9
+ channel: ExecutionChannel;
10
+ }>;
11
+ export type LibraryExecution = ExecutionContext;
12
+ export declare function localExecutionContext(): ExecutionContext;
13
+ export declare function bodyRequestExecutionContext(directory: unknown): ExecutionContext;
14
+ /** Constructs the one direct-parent route a caller may explicitly compose. */
15
+ export declare function bodyRequestExecution(input: Readonly<{
16
+ directory: string;
17
+ }>): LibraryExecution;
18
+ /** Normalizes the public carrier before a composition captures its immutable channel. */
19
+ export declare function libraryExecution(value: unknown): LibraryExecution;
20
+ export declare function libraryExecutionInput(input: unknown): LibraryExecution;
21
+ export declare function executionChannel(context?: ExecutionContext): ExecutionChannel;
@@ -1,120 +1,64 @@
1
- import { randomUUID } from "node:crypto";
2
- import { access, readFile } from "node:fs/promises";
3
- import { abortableDelay } from "./abort.js";
4
- import { AKUMA_REQUESTS_ENV } from "./provider.js";
5
- import { absolute, atomicJson, decodeReceipt, receiptPath, requestPath, requestPayload, } from "./request-wire.js";
6
- import { isTaskMutationAction } from "../task/mutation.js";
7
- const POLL_MS = 100;
8
- export class AkumaBodyRequestError extends Error {
9
- outcome;
10
- diagnostic;
11
- kind = "akuma-body-request";
12
- constructor(outcome, diagnostic) {
13
- super(`Akuma body request ${outcome}: ${diagnostic}`);
14
- this.outcome = outcome;
15
- this.diagnostic = diagnostic;
16
- this.name = "AkumaBodyRequestError";
17
- }
18
- }
19
- export function injectedBodyRequests() {
20
- const directory = process.env[AKUMA_REQUESTS_ENV];
21
- if (directory === undefined)
22
- return null;
23
- if (!absolute(directory))
24
- throw new Error(`${AKUMA_REQUESTS_ENV} must be an absolute normalized path`);
25
- return directory;
1
+ import { isAbsolute, resolve } from "node:path";
2
+ export { AkumaBodyRequestError, requestBodyCommand } from "./request-rendezvous.js";
3
+ const LOCAL_CHANNEL = Object.freeze({ kind: "local" });
4
+ export function localExecutionContext() {
5
+ return Object.freeze({ channel: LOCAL_CHANNEL });
26
6
  }
27
- async function requestBody(input) {
28
- input.signal?.throwIfAborted();
29
- const transportId = randomUUID();
30
- await atomicJson(requestPath(input.directory, transportId), {
31
- id: input.claim.id,
32
- action: input.claim.action,
33
- payload: requestPayload(input.claim),
34
- });
35
- const path = receiptPath(input.directory, transportId);
36
- for (;;) {
37
- try {
38
- const receipt = decodeReceipt(await readFile(path, "utf8"), input.claim.id, input.claim.action);
39
- if (receipt === null)
40
- throw new Error(`Akuma body request ${input.claim.id} has an invalid receipt`);
41
- if (receipt.state === "refused")
42
- throw new AkumaBodyRequestError("refused", receipt.diagnostic);
43
- if (receipt.state === "voided")
44
- throw new AkumaBodyRequestError("voided", receipt.evidence);
45
- return receipt;
46
- }
47
- catch (error) {
48
- if (error.code !== "ENOENT")
49
- throw error;
50
- }
51
- if (!(await access(input.directory).then(() => true, () => false))) {
52
- throw new AkumaBodyRequestError("voided", "parent request channel closed before a receipt");
53
- }
54
- await abortableDelay(POLL_MS, input.signal);
7
+ export function bodyRequestExecutionContext(directory) {
8
+ if (typeof directory !== "string" || !isAbsolute(directory) || resolve(directory) !== directory) {
9
+ throw new Error("AKUMA_REQUESTS must be an absolute normalized path");
55
10
  }
11
+ return Object.freeze({ channel: Object.freeze({ kind: "body-request", directory }) });
56
12
  }
57
- export async function requestBodyCall(input) {
58
- const { directory, ...claim } = input;
59
- const receipt = await requestBody({ directory, claim: { ...claim, action: "akuma.call" } });
60
- if (receipt.action !== "akuma.call" || receipt.state !== "served") {
61
- throw new Error(`Akuma body request ${input.id} returned the wrong action`);
13
+ function valueRecord(value, label) {
14
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
15
+ throw new TypeError(`${label} must be an object`);
62
16
  }
63
- return receipt.child;
17
+ return value;
64
18
  }
65
- async function requestUpstream(directory, claim, signal) {
66
- const receipt = await requestBody({ directory, claim, ...(signal === undefined ? {} : { signal }) });
67
- if (receipt.action === "akuma.call" || receipt.state !== "served" || !("outcome" in receipt)) {
68
- throw new Error(`Akuma body request ${claim.id} returned the wrong action`);
19
+ function closed(value, keys, label) {
20
+ for (const key of Object.keys(value)) {
21
+ if (!keys.includes(key))
22
+ throw new TypeError(`${label} has unknown field: ${key}`);
69
23
  }
70
- return receipt.outcome;
71
24
  }
72
- export async function requestBodyTask(input) {
73
- const id = input.id ?? randomUUID();
74
- const receipt = await requestBody({
75
- directory: input.directory,
76
- claim: { id, action: input.request.action, world: input.world, request: input.request },
77
- });
78
- if (!isTaskMutationAction(receipt.action) || receipt.action !== input.request.action || receipt.state !== "served") {
79
- throw new Error(`Akuma body request ${id} returned the wrong action`);
25
+ /** Constructs the one direct-parent route a caller may explicitly compose. */
26
+ export function bodyRequestExecution(input) {
27
+ const value = valueRecord(input, "body request execution input");
28
+ closed(value, ["directory"], "body request execution input");
29
+ if (typeof value.directory !== "string")
30
+ throw new TypeError("body request execution directory must be a string");
31
+ try {
32
+ return bodyRequestExecutionContext(value.directory);
33
+ }
34
+ catch (error) {
35
+ throw new TypeError(error instanceof Error ? error.message : String(error));
80
36
  }
81
- if ("reference" in receipt)
82
- return receipt.reference;
83
- if (receipt.outcome.kind === "returned")
84
- return receipt.outcome.result;
85
- throw new Error(receipt.outcome.failure.kind === "failed"
86
- ? receipt.outcome.failure.diagnostic
87
- : "Akuma body request parent is not born");
88
- }
89
- export async function requestBodyWait(input) {
90
- const { directory, id = randomUUID(), ...claim } = input;
91
- return await requestUpstream(directory, { ...claim, id, action: "akuma.wait" });
92
- }
93
- export async function requestBodyTell(input) {
94
- const { directory, id = randomUUID(), ...claim } = input;
95
- return await requestUpstream(directory, { ...claim, id, action: "akuma.tell" });
96
- }
97
- export async function requestBodyKill(input) {
98
- const { directory, id = randomUUID(), ...claim } = input;
99
- return await requestUpstream(directory, { ...claim, id, action: "akuma.kill" });
100
37
  }
101
- async function requestContract(input, action) {
102
- const { directory, id = randomUUID(), signal, ...claim } = input;
103
- const receipt = await requestBody({
104
- directory,
105
- claim: { ...claim, id, action },
106
- ...(signal === undefined ? {} : { signal }),
107
- });
108
- if (receipt.action !== action || receipt.state !== "served") {
109
- throw new Error(`Akuma body request ${id} returned the wrong action`);
38
+ /** Normalizes the public carrier before a composition captures its immutable channel. */
39
+ export function libraryExecution(value) {
40
+ const context = valueRecord(value, "execution");
41
+ closed(context, ["channel"], "execution");
42
+ const channel = valueRecord(context.channel, "execution channel");
43
+ if (channel.kind === "local") {
44
+ closed(channel, ["kind"], "execution channel");
45
+ return localExecutionContext();
46
+ }
47
+ if (channel.kind === "body-request") {
48
+ closed(channel, ["directory", "kind"], "execution channel");
49
+ if (typeof channel.directory !== "string")
50
+ throw new TypeError("execution channel directory must be a string");
51
+ return bodyRequestExecution({ directory: channel.directory });
110
52
  }
111
- return "reference" in receipt
112
- ? receipt.reference
113
- : receipt.outcome;
53
+ throw new TypeError("execution channel must be local or body-request");
114
54
  }
115
- export async function requestBodyDeliver(input) {
116
- return await requestContract(input, "contract.deliver");
55
+ export function libraryExecutionInput(input) {
56
+ const value = valueRecord(input, "Keiyaku.withExecution input");
57
+ closed(value, ["execution"], "Keiyaku.withExecution input");
58
+ if (value.execution === undefined)
59
+ throw new TypeError("Keiyaku.withExecution input requires execution");
60
+ return libraryExecution(value.execution);
117
61
  }
118
- export async function requestBodyReview(input) {
119
- return await requestContract(input, "contract.review");
62
+ export function executionChannel(context) {
63
+ return context?.channel ?? LOCAL_CHANNEL;
120
64
  }
@@ -1,7 +1,8 @@
1
1
  import { type ResumeCoordinate, type Soul, type TellFact } from "./heart/index.js";
2
2
  import type { AkumaPaths } from "./identity.js";
3
3
  import { type ProviderAdapter, type TurnResult } from "./provider.js";
4
- import { type RequestChildLaunch, type UpstreamExecutionPort } from "./request-serve.js";
4
+ import type { AkumaCallRequestChildLaunch } from "./call-request.js";
5
+ import type { ErasedRequestCommand } from "./request-wire.js";
5
6
  import { BodySupervisor } from "./body-supervisor.js";
6
7
  import type { OwnedProcess } from "../runtime/proc/run.js";
7
8
  export declare function turnRecipe(paths: AkumaPaths, soul: Soul): Promise<Readonly<{
@@ -25,8 +26,9 @@ export type DriveTurnInput = Readonly<{
25
26
  call?: string;
26
27
  launchTells: readonly TellFact[];
27
28
  supervisor: BodySupervisor;
28
- runtimeSpawn(launch: RequestChildLaunch): Promise<OwnedProcess | void>;
29
- upstream?: UpstreamExecutionPort;
29
+ runtimeSpawn(launch: AkumaCallRequestChildLaunch): Promise<OwnedProcess | void>;
30
+ upstream?: unknown;
31
+ commands: Readonly<Record<string, ErasedRequestCommand>>;
30
32
  now(): string;
31
33
  }>;
32
34
  export declare function driveTurn(input: DriveTurnInput): Promise<(DrivenTurn & Readonly<{
@@ -1,6 +1,7 @@
1
1
  import { abortableDelay } from "./abort.js";
2
+ /* eslint-disable max-lines-per-function -- Turn setup and consumption each preserve one ordered lifecycle transaction. */
2
3
  import { appendActivity, beginTurn, breakBody, heartExists, readHeart, recordSession, recordTellDeliveries, recordTellReceipt, } from "./heart/index.js";
3
- import { encodeAgentEvent } from "./provider.js";
4
+ import { encodeAgentEvent, } from "./provider.js";
4
5
  import { BodyRequestPump } from "./request-serve.js";
5
6
  import { CONTROL_RESPONSE_MS } from "./body-supervisor.js";
6
7
  function serializeEffects() {
@@ -79,6 +80,7 @@ async function startTurnDrive(input) {
79
80
  now: input.now,
80
81
  spawn: input.runtimeSpawn,
81
82
  ...(input.upstream === undefined ? {} : { upstream: input.upstream }),
83
+ commands: input.commands,
82
84
  signal: input.supervisor.signal,
83
85
  });
84
86
  const driveController = new AbortController();
@@ -101,14 +103,15 @@ async function startTurnDrive(input) {
101
103
  signal: driveController.signal,
102
104
  requests: { dir: requests.directory },
103
105
  };
104
- const setup = session === undefined
106
+ const attempt = session === undefined
105
107
  ? input.adapter.start({ ...driveInput, session: { kind: "fresh" } })
106
108
  : input.adapter.resume({ ...driveInput, session: { kind: "resume", coordinate: session } });
109
+ const custodyFailure = observeFailure(attempt.closed);
107
110
  try {
108
- const selected = await Promise.race([setup, requests.failure]);
111
+ const selected = await Promise.race([attempt.result, requests.failure, custodyFailure]);
109
112
  if (input.supervisor.signal.aborted) {
110
113
  try {
111
- const retirement = await retireProviderCustody(input, turn.sequence, selected);
114
+ const retirement = await retireProviderCustody(input, turn.sequence, attempt);
112
115
  await requests.close();
113
116
  if (retirement.kind === "hung")
114
117
  return retirement;
@@ -129,6 +132,8 @@ async function startTurnDrive(input) {
129
132
  void selected.completion.then(() => requests.stopAdmission(), () => undefined);
130
133
  return {
131
134
  turnSequence: turn.sequence,
135
+ attempt,
136
+ custodyFailure,
132
137
  drive: selected,
133
138
  requests,
134
139
  cwd,
@@ -138,21 +143,39 @@ async function startTurnDrive(input) {
138
143
  };
139
144
  }
140
145
  catch (error) {
146
+ const retirement = await retireProviderCustody(input, turn.sequence, attempt);
147
+ if (retirement.kind === "hung") {
148
+ try {
149
+ await requests.close();
150
+ }
151
+ finally {
152
+ input.supervisor.signal.removeEventListener("abort", cancelDrive);
153
+ }
154
+ return retirement;
155
+ }
141
156
  return await failedTurnSetup(input, turn.sequence, requests, cancelDrive, error);
142
157
  }
143
158
  }
144
- async function retireProviderCustody(input, turnSequence, drive) {
159
+ async function retireProviderCustody(input, turnSequence, attempt) {
145
160
  const dispose = async (operation) => await Promise.race([
146
- operation().then(() => ({ kind: "retired" }), (error) => ({ kind: "held", error })),
161
+ operation().then(async () => {
162
+ try {
163
+ await attempt.closed;
164
+ return { kind: "retired" };
165
+ }
166
+ catch (error) {
167
+ return { kind: "held", error };
168
+ }
169
+ }, (error) => ({ kind: "held", error })),
147
170
  abortableDelay(CONTROL_RESPONSE_MS).then(() => ({
148
171
  kind: "held",
149
172
  error: new Error(`provider custody remained live after ${CONTROL_RESPONSE_MS}ms`),
150
173
  })),
151
174
  ]);
152
- let outcome = await dispose(drive.abort);
175
+ let outcome = await dispose(attempt.abort);
153
176
  if (outcome.kind === "retired")
154
177
  return outcome;
155
- outcome = await dispose(drive.forceDispose);
178
+ outcome = await dispose(attempt.forceDispose);
156
179
  if (outcome.kind === "retired")
157
180
  return outcome;
158
181
  if (await heartExists(input.paths)) {
@@ -191,8 +214,11 @@ function pumpReceipts(writers) {
191
214
  }
192
215
  })();
193
216
  }
217
+ function observeFailure(settlement) {
218
+ return settlement.then(() => new Promise(() => { }), (error) => Promise.reject(error));
219
+ }
194
220
  function observeReceiptFailure(receiptPump) {
195
- return receiptPump.then(() => new Promise(() => { }), (error) => Promise.reject(error));
221
+ return observeFailure(receiptPump);
196
222
  }
197
223
  function observeCompletionFailure(drive) {
198
224
  return drive.completion.then(() => new Promise(() => { }), (error) => ({ kind: "completion-failed", error }));
@@ -226,7 +252,7 @@ async function submitPendingLiveTells(writers, pending, attempted, tellLive) {
226
252
  }
227
253
  async function stopActiveDrive(input, active) {
228
254
  try {
229
- const retirement = await retireProviderCustody(input, active.turnSequence, active.drive);
255
+ const retirement = await retireProviderCustody(input, active.turnSequence, active.attempt);
230
256
  await active.requests.close();
231
257
  return retirement;
232
258
  }
@@ -285,6 +311,7 @@ async function consumeTurnDrive(input, active) {
285
311
  receiptFailure,
286
312
  requests.failure,
287
313
  completionFailure,
314
+ active.custodyFailure,
288
315
  ]);
289
316
  if (next.kind === "completion-failed") {
290
317
  requests.stopAdmission();
@@ -308,6 +335,7 @@ async function consumeTurnDrive(input, active) {
308
335
  pending = iterator.next();
309
336
  }
310
337
  const result = await drive.completion;
338
+ await active.attempt.closed;
311
339
  if (tellPump !== null)
312
340
  await tellPump;
313
341
  await writeWitness.drain();
@@ -320,7 +348,7 @@ async function consumeTurnDrive(input, active) {
320
348
  const retirement = await stopActiveDrive(input, active);
321
349
  return retirement.kind === "hung" ? retirement : { kind: "stopped" };
322
350
  }
323
- const retirement = await retireProviderCustody(input, turnSequence, drive);
351
+ const retirement = await retireProviderCustody(input, turnSequence, active.attempt);
324
352
  try {
325
353
  await requests.close();
326
354
  }
@@ -1,8 +1,13 @@
1
1
  import { type BodyLaunch } from "./akuma/body.js";
2
- import type { UpstreamExecutionPort } from "./akuma/request-serve.js";
2
+ import { type WorldRoot } from "./world.js";
3
+ import { type FleetRequestPort } from "./library/fleet.js";
4
+ import { type ContractRequestPort } from "./library/contract-operations.js";
5
+ import { type TaskMutationRequestPort } from "./task/mutation.js";
3
6
  type BodyProcessConfiguration = Readonly<{
4
7
  home?: string;
5
8
  gitPath?: string;
6
9
  }>;
7
- export declare function upstreamFor(launch: BodyLaunch, processConfiguration: BodyProcessConfiguration): UpstreamExecutionPort;
10
+ export declare function upstreamFor(launch: BodyLaunch, processConfiguration: BodyProcessConfiguration): Promise<FleetRequestPort & ContractRequestPort & TaskMutationRequestPort & Readonly<{
11
+ launchWorld(): WorldRoot;
12
+ }>>;
8
13
  export {};
@@ -1,47 +1,45 @@
1
1
  import { LEASH_HELD_EXIT, runAkumaBody } from "./akuma/body.js";
2
+ import { akumaCallRequestCommands } from "./akuma/call-request.js";
2
3
  import { worldRootForAkumaPaths } from "./akuma/identity.js";
4
+ import { World } from "./world.js";
3
5
  import { executeKillAkuma, executeTellAkuma, executeWaitAkuma } from "./library/fleet.js";
6
+ import { fleetRequestCommands } from "./library/fleet.js";
4
7
  import { requireBranchesToBeUpToDateFrom, worktreeHooksFrom } from "./library/configuration.js";
5
- import { executeForwardedDeliver, executeForwardedReview } from "./library/contract.js";
8
+ import { contractRequestCommands, executeForwardedAudit, executeForwardedDeliver, executeForwardedReview, } from "./library/contract-operations.js";
6
9
  import { Repo } from "./library/repo.js";
7
10
  import { settings } from "./settings.js";
8
- import { executeTaskMutation } from "./task/mutation.js";
9
- export function upstreamFor(launch, processConfiguration) {
10
- const path = worldRootForAkumaPaths(launch.paths);
11
+ import { executeTaskMutation, taskMutationRequestCommands } from "./task/mutation.js";
12
+ async function contractDependencies(repoRoot, processConfiguration) {
13
+ const repo = await Repo.at({
14
+ path: repoRoot,
15
+ ...(processConfiguration.gitPath === undefined ? {} : { gitPath: processConfiguration.gitPath }),
16
+ });
17
+ if (repo.root !== repoRoot)
18
+ throw new TypeError("forwarded Contract repoRoot must equal the canonical primary worktree");
19
+ const world = await World.prove(repo.root);
20
+ const configuration = await settings({
21
+ root: world,
22
+ ...(processConfiguration.home === undefined ? {} : { home: processConfiguration.home }),
23
+ });
24
+ return [repo, configuration];
25
+ }
26
+ function contractUpstream(processConfiguration) {
11
27
  return {
12
- wait: async (input) => await executeWaitAkuma({
13
- path,
14
- ids: input.targets,
15
- completion: input.completion,
16
- ...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
17
- signal: input.signal,
18
- }),
19
- tell: async (input) => await executeTellAkuma({
20
- path,
21
- id: input.target,
22
- body: input.body,
23
- tellId: input.tellId,
24
- recordedAt: input.recordedAt,
25
- signal: input.signal,
26
- }),
27
- kill: async (input) => {
28
- const result = await executeKillAkuma({ path, ids: input.targets, signal: input.signal });
29
- return {
30
- result,
31
- service: result.results.map(({ id, evidence }) => ({ id, evidence })),
32
- };
28
+ audit: async (input) => {
29
+ const [repo, configuration] = await contractDependencies(input.repoRoot, processConfiguration);
30
+ return await executeForwardedAudit({
31
+ repo,
32
+ contractId: input.contractId,
33
+ requester: input.requester,
34
+ includeDirty: input.includeDirty,
35
+ showDiff: input.showDiff,
36
+ requireBranchesToBeUpToDate: requireBranchesToBeUpToDateFrom({ settings: configuration }),
37
+ hooks: worktreeHooksFrom({ settings: configuration }),
38
+ signal: input.signal,
39
+ });
33
40
  },
34
41
  deliver: async (input) => {
35
- const [repo, configuration] = await Promise.all([
36
- Repo.at({
37
- path: input.repoRoot,
38
- ...(processConfiguration.gitPath === undefined ? {} : { gitPath: processConfiguration.gitPath }),
39
- }),
40
- settings({
41
- root: input.repoRoot,
42
- ...(processConfiguration.home === undefined ? {} : { home: processConfiguration.home }),
43
- }),
44
- ]);
42
+ const [repo, configuration] = await contractDependencies(input.repoRoot, processConfiguration);
45
43
  return await executeForwardedDeliver({
46
44
  repo,
47
45
  contractId: input.contractId,
@@ -55,16 +53,7 @@ export function upstreamFor(launch, processConfiguration) {
55
53
  });
56
54
  },
57
55
  review: async (input) => {
58
- const [repo, configuration] = await Promise.all([
59
- Repo.at({
60
- path: input.repoRoot,
61
- ...(processConfiguration.gitPath === undefined ? {} : { gitPath: processConfiguration.gitPath }),
62
- }),
63
- settings({
64
- root: input.repoRoot,
65
- ...(processConfiguration.home === undefined ? {} : { home: processConfiguration.home }),
66
- }),
67
- ]);
56
+ const [repo, configuration] = await contractDependencies(input.repoRoot, processConfiguration);
68
57
  return await executeForwardedReview({
69
58
  repo,
70
59
  contractId: input.contractId,
@@ -74,6 +63,32 @@ export function upstreamFor(launch, processConfiguration) {
74
63
  hooks: worktreeHooksFrom({ settings: configuration }),
75
64
  });
76
65
  },
66
+ };
67
+ }
68
+ export async function upstreamFor(launch, processConfiguration) {
69
+ const world = await World.prove(worldRootForAkumaPaths(launch.paths));
70
+ return {
71
+ launchWorld: () => world,
72
+ ...contractUpstream(processConfiguration),
73
+ wait: async (input) => await executeWaitAkuma({
74
+ path: world,
75
+ ids: input.targets,
76
+ completion: input.completion,
77
+ ...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
78
+ signal: input.signal,
79
+ }),
80
+ tell: async (input) => await executeTellAkuma({
81
+ path: world,
82
+ id: input.target,
83
+ body: input.body,
84
+ tellId: input.tellId,
85
+ recordedAt: input.recordedAt,
86
+ signal: input.signal,
87
+ }),
88
+ kill: async (input) => {
89
+ const result = await executeKillAkuma({ path: world, ids: input.targets, signal: input.signal });
90
+ return result;
91
+ },
77
92
  task: async (input) => await executeTaskMutation({
78
93
  world: input.world,
79
94
  request: input.request,
@@ -95,5 +110,12 @@ const configuration = {
95
110
  ...(mappedHome === undefined || mappedHome.length === 0 ? {} : { home: mappedHome }),
96
111
  ...(mappedGitPath === undefined ? {} : { gitPath: mappedGitPath }),
97
112
  };
98
- if ((await runAkumaBody(launch, upstreamFor(launch, configuration))) === "held")
113
+ const upstream = await upstreamFor(launch, configuration);
114
+ const commands = {
115
+ ...akumaCallRequestCommands(),
116
+ ...fleetRequestCommands(),
117
+ ...contractRequestCommands(),
118
+ ...taskMutationRequestCommands(),
119
+ };
120
+ if ((await runAkumaBody(launch, upstream, commands)) === "held")
99
121
  process.exitCode = LEASH_HELD_EXIT;
@@ -22,10 +22,11 @@ function operationSections(document) {
22
22
  refusal("amend operations contain bytes outside H2 sections");
23
23
  }
24
24
  return sections(document).map((section) => {
25
- const match = /^(Add|Update|Replace|Append|Remove):[ ]+(.+)$/.exec(section.title.trim());
26
- if (!match)
27
- refusal(`invalid amend operation heading: ${section.title}`);
28
- return { kind: match[1], target: match[2].trim(), section };
25
+ const title = section.title.trim();
26
+ const match = /^(Add|Update|Replace|Append|Remove):[ ]+(.+)$/.exec(title);
27
+ return match
28
+ ? { kind: match[1], target: match[2].trim(), section }
29
+ : { kind: "Set", target: title, section };
29
30
  });
30
31
  }
31
32
  function prose(document, section, label) {
@@ -112,7 +113,7 @@ function completeBody(body) {
112
113
  objective: body.objective,
113
114
  design: body.design,
114
115
  region: body.region,
115
- criteria: body.criteria.filter((criterion) => criterion !== undefined),
116
+ criteria: body.criteria,
116
117
  verification: body.verification,
117
118
  extensions: body.extensions.filter((extension) => extension !== undefined),
118
119
  };
@@ -137,15 +138,6 @@ function alteredText(body, target, value) {
137
138
  }
138
139
  function applyRemove(body, operation, document) {
139
140
  requireEmpty(document, operation.section);
140
- if (operation.target.startsWith("Criterion ")) {
141
- const title = operation.target.slice("Criterion ".length);
142
- const index = criterionIndex(body, title);
143
- if (index < 0)
144
- refusal(`unknown criterion '${title}'`);
145
- body.criteria[index] = undefined;
146
- body.criterionIndexes.delete(normalizeTitle(title));
147
- return;
148
- }
149
141
  const index = extensionIndex(body, operation.target);
150
142
  if (index < 0)
151
143
  refusal(`unknown extension '${operation.target}'`);
@@ -236,6 +228,13 @@ function applyReplace(body, operation, document) {
236
228
  const extension = body.extensions[index];
237
229
  body.extensions[index] = { ...extension, content: prose(document, operation.section, "extension") };
238
230
  }
231
+ function applySet(body, operation, document) {
232
+ if (contractSectionName(operation.target) !== null || extensionIndex(body, operation.target) >= 0) {
233
+ applyReplace(body, operation, document);
234
+ return;
235
+ }
236
+ applyAdd(body, operation, document);
237
+ }
239
238
  function applyOperation(body, operation, document) {
240
239
  switch (operation.kind) {
241
240
  case "Add":
@@ -253,13 +252,13 @@ function applyOperation(body, operation, document) {
253
252
  case "Remove":
254
253
  applyRemove(body, operation, document);
255
254
  return;
255
+ case "Set":
256
+ applySet(body, operation, document);
257
+ return;
256
258
  }
257
259
  }
258
260
  function operationKey(operation) {
259
- const target = operation.target.startsWith("Criterion ")
260
- ? `Criterion ${normalizeTitle(operation.target.slice("Criterion ".length))}`
261
- : operation.target;
262
- return `${operation.kind}:${target}`;
261
+ return `${operation.kind}:${operation.target}`;
263
262
  }
264
263
  function apply(source, current) {
265
264
  const document = parseToAST(source);
@@ -274,7 +273,7 @@ function apply(source, current) {
274
273
  if (seen.has(key))
275
274
  refusal(`duplicate amend operation '${key}'`);
276
275
  seen.add(key);
277
- changed.add(normalizeTitle(operation.target.startsWith("Criterion ") ? "Criteria" : operation.target));
276
+ changed.add(normalizeTitle(operation.target));
278
277
  applyOperation(body, operation, document);
279
278
  }
280
279
  return { body: completeBody(body), changed };
@@ -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" | "effects" | "lags" | "settlement">;
3
+ type MutationObservation = Pick<MutationResult<unknown>, "facts" | "head" | "lags" | "settlementLags" | "recoverySnapshot">;
4
4
  type MutationCallOptions = Readonly<{
5
5
  coordinate?: ContractId;
6
6
  projectRefusal?: (refusal: unknown) => unknown;