@astrosheep/keiyaku 4.5.6 → 4.5.8

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 (245) 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 +10 -8
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +22 -1
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +53 -0
  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 +372 -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/body.d.ts +7 -5
  23. package/build/src/akuma/body.js +25 -36
  24. package/build/src/akuma/call-request.d.ts +80 -0
  25. package/build/src/akuma/call-request.js +211 -0
  26. package/build/src/akuma/heart/facts.d.ts +6 -78
  27. package/build/src/akuma/heart/index.d.ts +3 -3
  28. package/build/src/akuma/heart/index.js +2 -2
  29. package/build/src/akuma/heart/request-authority.d.ts +6 -4
  30. package/build/src/akuma/heart/request-authority.js +31 -35
  31. package/build/src/akuma/heart/request-rows.js +12 -23
  32. package/build/src/akuma/heart/schema.d.ts +1 -1
  33. package/build/src/akuma/heart/schema.js +5 -13
  34. package/build/src/akuma/heart/storage.d.ts +0 -1
  35. package/build/src/akuma/heart/storage.js +0 -54
  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 +856 -137
  41. package/build/src/akuma/projection.js +190 -0
  42. package/build/src/akuma/provider.d.ts +30 -3
  43. package/build/src/akuma/provider.js +104 -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/index.d.ts +3 -3
  48. package/build/src/akuma/providers/claude/index.js +16 -5
  49. package/build/src/akuma/providers/codex-app-server/events.js +1 -1
  50. package/build/src/akuma/providers/codex-app-server/index.js +18 -6
  51. package/build/src/akuma/providers/grok-build/index.js +5 -4
  52. package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
  53. package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
  54. package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
  55. package/build/src/akuma/providers/pi/index.js +42 -14
  56. package/build/src/akuma/publication.js +75 -13
  57. package/build/src/akuma/request-lifecycle.d.ts +3 -9
  58. package/build/src/akuma/request-lifecycle.js +12 -25
  59. package/build/src/akuma/request-rendezvous.d.ts +26 -0
  60. package/build/src/akuma/request-rendezvous.js +100 -0
  61. package/build/src/akuma/request-serve.d.ts +5 -65
  62. package/build/src/akuma/request-serve.js +92 -204
  63. package/build/src/akuma/request-wire.d.ts +109 -115
  64. package/build/src/akuma/request-wire.js +63 -318
  65. package/build/src/akuma/requests.d.ts +19 -47
  66. package/build/src/akuma/requests.js +51 -107
  67. package/build/src/akuma/turn-drive.d.ts +5 -3
  68. package/build/src/akuma/turn-drive.js +32 -10
  69. package/build/src/akuma-body.d.ts +7 -2
  70. package/build/src/akuma-body.js +68 -46
  71. package/build/src/cli/accepted.d.ts +1 -1
  72. package/build/src/cli/accepted.js +2 -2
  73. package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
  74. package/build/src/cli/commands/akuma-invoke.js +17 -9
  75. package/build/src/cli/commands/akuma.js +7 -7
  76. package/build/src/cli/commands/contract-invoke.d.ts +3 -2
  77. package/build/src/cli/commands/contract-invoke.js +26 -19
  78. package/build/src/cli/commands/contract.d.ts +13 -13
  79. package/build/src/cli/commands/contract.js +32 -17
  80. package/build/src/cli/commands/install.d.ts +1 -1
  81. package/build/src/cli/commands/install.js +1 -1
  82. package/build/src/cli/commands/task-invoke.d.ts +7 -2
  83. package/build/src/cli/commands/task-invoke.js +67 -158
  84. package/build/src/cli/commands/task.d.ts +1 -1
  85. package/build/src/cli/commands/task.js +60 -22
  86. package/build/src/cli/coordinates.d.ts +2 -0
  87. package/build/src/cli/coordinates.js +18 -2
  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 +37 -22
  92. package/build/src/cli/render/akuma-activity.d.ts +4 -1
  93. package/build/src/cli/render/akuma-activity.js +45 -30
  94. package/build/src/cli/render/akuma-tool.d.ts +5 -1
  95. package/build/src/cli/render/akuma.js +5 -9
  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 +25 -65
  101. package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
  102. package/build/src/cli/render/kanshi-akuma.js +111 -0
  103. package/build/src/cli/render/kanshi.js +108 -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 +28 -10
  111. package/build/src/cli/render/terminal.d.ts +28 -0
  112. package/build/src/cli/render/terminal.js +65 -0
  113. package/build/src/cli/result.d.ts +3 -3
  114. package/build/src/cli/runtime.js +3 -1
  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 +36 -18
  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 +19 -7
  140. package/build/src/git/read-observation.js +29 -20
  141. package/build/src/git/reconcile.d.ts +11 -0
  142. package/build/src/git/reconcile.js +64 -11
  143. package/build/src/git/repository.d.ts +8 -2
  144. package/build/src/git/repository.js +42 -21
  145. package/build/src/git/target-placement.d.ts +1 -0
  146. package/build/src/git/target-placement.js +5 -6
  147. package/build/src/git/tender.d.ts +1 -0
  148. package/build/src/git/terminal-reconcile.d.ts +1 -1
  149. package/build/src/git/terminal-reconcile.js +22 -20
  150. package/build/src/git/workspace.d.ts +14 -0
  151. package/build/src/git/workspace.js +44 -0
  152. package/build/src/kanshi/index.d.ts +1 -1
  153. package/build/src/kanshi/read.js +16 -16
  154. package/build/src/kanshi/report.d.ts +2 -2
  155. package/build/src/library/address.d.ts +9 -3
  156. package/build/src/library/address.js +3 -2
  157. package/build/src/library/akuma-creation.d.ts +4 -3
  158. package/build/src/library/akuma-creation.js +19 -13
  159. package/build/src/library/audit.d.ts +1 -1
  160. package/build/src/library/audit.js +5 -3
  161. package/build/src/library/catalog.d.ts +3 -1
  162. package/build/src/library/catalog.js +20 -6
  163. package/build/src/library/composition.d.ts +371 -0
  164. package/build/src/library/composition.js +28 -0
  165. package/build/src/library/configuration.js +8 -2
  166. package/build/src/library/continuation.js +66 -30
  167. package/build/src/library/contract-bind.js +10 -2
  168. package/build/src/library/contract-forwarding-reconciliation-result.d.ts +96 -0
  169. package/build/src/library/contract-forwarding-reconciliation-result.js +83 -0
  170. package/build/src/library/contract-forwarding-result.d.ts +6723 -0
  171. package/build/src/library/contract-forwarding-result.js +521 -0
  172. package/build/src/library/contract-forwarding.d.ts +72 -0
  173. package/build/src/library/contract-forwarding.js +125 -0
  174. package/build/src/library/contract-handle.d.ts +36 -0
  175. package/build/src/library/contract-handle.js +313 -0
  176. package/build/src/library/contract-operations.d.ts +1044 -67
  177. package/build/src/library/contract-operations.js +190 -118
  178. package/build/src/library/contract.d.ts +11 -32
  179. package/build/src/library/contract.js +16 -289
  180. package/build/src/library/fleet-result.d.ts +1454 -0
  181. package/build/src/library/fleet-result.js +96 -0
  182. package/build/src/library/fleet.d.ts +112 -54
  183. package/build/src/library/fleet.js +211 -71
  184. package/build/src/library/input.d.ts +2 -0
  185. package/build/src/library/input.js +4 -0
  186. package/build/src/library/keiyaku.d.ts +371 -20
  187. package/build/src/library/keiyaku.js +8 -21
  188. package/build/src/library/mutation.d.ts +3 -3
  189. package/build/src/library/mutation.js +5 -9
  190. package/build/src/library/nuke.d.ts +1 -1
  191. package/build/src/library/nuke.js +4 -3
  192. package/build/src/library/reconcile.d.ts +4 -0
  193. package/build/src/library/reconcile.js +2 -0
  194. package/build/src/library/refusal.d.ts +0 -9
  195. package/build/src/library/refusal.js +0 -7
  196. package/build/src/protocol/amend.js +56 -50
  197. package/build/src/protocol/attempt.d.ts +2 -0
  198. package/build/src/protocol/attempt.js +17 -5
  199. package/build/src/protocol/completion.js +7 -0
  200. package/build/src/protocol/deliver.js +6 -2
  201. package/build/src/protocol/operations.d.ts +4 -1
  202. package/build/src/protocol/operations.js +5 -2
  203. package/build/src/protocol/placement.d.ts +1 -0
  204. package/build/src/protocol/placement.js +52 -38
  205. package/build/src/protocol/read/observation.d.ts +1 -4
  206. package/build/src/protocol/read/observation.js +2 -15
  207. package/build/src/protocol/reintegrate.js +62 -58
  208. package/build/src/protocol/review.js +5 -0
  209. package/build/src/protocol/run.js +17 -13
  210. package/build/src/runtime/proc/run.d.ts +8 -0
  211. package/build/src/runtime/proc/run.js +27 -0
  212. package/build/src/runtime/proc/termination.js +26 -22
  213. package/build/src/runtime/proc/windows-launch.exe +0 -0
  214. package/build/src/settlement/holder.d.ts +2 -1
  215. package/build/src/settlement/holder.js +15 -4
  216. package/build/src/settlement/settle.js +99 -33
  217. package/build/src/task/board.d.ts +68 -27
  218. package/build/src/task/board.js +31 -1
  219. package/build/src/task/catalog.d.ts +4 -0
  220. package/build/src/task/catalog.js +23 -0
  221. package/build/src/task/compose-language.d.ts +4 -0
  222. package/build/src/task/compose-language.js +40 -7
  223. package/build/src/task/compose-parser.d.ts +2 -1
  224. package/build/src/task/compose-parser.js +5 -3
  225. package/build/src/task/compose.d.ts +1 -0
  226. package/build/src/task/compose.js +4 -1
  227. package/build/src/task/context.d.ts +7 -1
  228. package/build/src/task/context.js +25 -6
  229. package/build/src/task/index.d.ts +18 -5
  230. package/build/src/task/index.js +97 -16
  231. package/build/src/task/mutation-result.d.ts +923 -0
  232. package/build/src/task/mutation-result.js +140 -0
  233. package/build/src/task/mutation.d.ts +552 -28
  234. package/build/src/task/mutation.js +304 -97
  235. package/build/src/task/operations.d.ts +1 -4
  236. package/build/src/task/operations.js +0 -6
  237. package/build/src/task/public.d.ts +2 -0
  238. package/build/src/task/public.js +1 -0
  239. package/build/src/workspace-place.d.ts +7 -2
  240. package/build/src/workspace-place.js +34 -24
  241. package/build/src/world.d.ts +1 -0
  242. package/build/src/world.js +11 -0
  243. package/package.json +8 -6
  244. package/build/src/akuma/request-execution.d.ts +0 -8
  245. package/build/src/akuma/request-execution.js +0 -98
@@ -0,0 +1,80 @@
1
+ import { type Soul } from "./heart/index.js";
2
+ import { type AkuId, type AkumaPaths } from "./identity.js";
3
+ import { type ErasedRequestCommand, type RequestCommand } from "./request-wire.js";
4
+ import type { OwnedProcess } from "../runtime/proc/run.js";
5
+ import { z } from "zod";
6
+ import { type WorldRoot } from "../world.js";
7
+ declare const akumaCallRecipeSchema: z.ZodObject<{
8
+ description: z.ZodOptional<z.ZodString>;
9
+ allowed: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("./allowed.js").AllowedActions, unknown>>;
10
+ provider: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
11
+ name: string;
12
+ kind: "acp" | "claude-agent-sdk" | "codex-app-server" | "grok-build" | "opencode-sdk" | "pi";
13
+ executable?: string;
14
+ config?: Readonly<Record<string, unknown>>;
15
+ env?: Readonly<Record<string, string>>;
16
+ }>, unknown>>;
17
+ options: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
18
+ model?: string;
19
+ effort?: string;
20
+ readonly?: true;
21
+ network?: "disabled" | "enabled";
22
+ systemPrompt?: string;
23
+ systemPromptMode?: import("./provider-recipe.js").SystemPromptMode;
24
+ }>, unknown>>;
25
+ readonly: z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("./provider-recipe.js").ReadonlyRestraint, unknown>>>;
26
+ }, z.core.$strict>;
27
+ declare const akumaCallPayloadSchema: z.ZodObject<{
28
+ world: z.ZodString;
29
+ archetype: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
30
+ body: z.ZodString;
31
+ cwd: z.ZodOptional<z.ZodString>;
32
+ recipe: z.ZodObject<{
33
+ description: z.ZodOptional<z.ZodString>;
34
+ allowed: z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("./allowed.js").AllowedActions, unknown>>;
35
+ provider: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
36
+ name: string;
37
+ kind: "acp" | "claude-agent-sdk" | "codex-app-server" | "grok-build" | "opencode-sdk" | "pi";
38
+ executable?: string;
39
+ config?: Readonly<Record<string, unknown>>;
40
+ env?: Readonly<Record<string, string>>;
41
+ }>, unknown>>;
42
+ options: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
43
+ model?: string;
44
+ effort?: string;
45
+ readonly?: true;
46
+ network?: "disabled" | "enabled";
47
+ systemPrompt?: string;
48
+ systemPromptMode?: import("./provider-recipe.js").SystemPromptMode;
49
+ }>, unknown>>;
50
+ readonly: z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodTransform<import("./provider-recipe.js").ReadonlyRestraint, unknown>>>;
51
+ }, z.core.$strict>;
52
+ }, z.core.$strict>;
53
+ export type AkumaCallRecipe = z.infer<typeof akumaCallRecipeSchema>;
54
+ export type AkumaCallRequest = z.infer<typeof akumaCallPayloadSchema> & Readonly<{
55
+ action: "akuma.call";
56
+ }>;
57
+ export type AkumaCallRequestChildLaunch = Readonly<{
58
+ paths: AkumaPaths;
59
+ seed: Omit<Soul, "createdAt">;
60
+ initialBody: string;
61
+ }>;
62
+ type CallExecutionContext = Readonly<{
63
+ id: string;
64
+ requester: string;
65
+ signal: AbortSignal;
66
+ world: WorldRoot;
67
+ paths: AkumaPaths;
68
+ parent: Soul;
69
+ spawn(launch: AkumaCallRequestChildLaunch): Promise<OwnedProcess | void>;
70
+ admissionOpen(): boolean;
71
+ }>;
72
+ export declare function decodeAkumaCallRequest(value: unknown): AkumaCallRequest | null;
73
+ export declare function akumaCallRequestCommand(): RequestCommand<AkumaCallRequest, AkuId, never, AkuId, CallExecutionContext>;
74
+ export declare function akumaCallRequestCommands(): Readonly<Record<"akuma.call", ErasedRequestCommand>>;
75
+ export declare function requestForwardedAkumaCall(input: Omit<AkumaCallRequest, "action"> & Readonly<{
76
+ directory: string;
77
+ id: string;
78
+ signal?: AbortSignal;
79
+ }>): Promise<AkuId>;
80
+ export {};
@@ -0,0 +1,211 @@
1
+ import { isAbsolute, resolve } from "node:path";
2
+ import { clipAllowedActions, decodeAllowedActions } from "./allowed.js";
3
+ import { refuseRequest, reserveRequest } from "./heart/index.js";
4
+ import { archetypeName, parseAkuId } from "./identity.js";
5
+ import { publishAkuma } from "./publication.js";
6
+ import { decodeProviderOptions, decodeReadonlyRestraint } from "./provider-recipe.js";
7
+ import { decodeProviderExecution } from "./providers/index.js";
8
+ import { requestBodyCommand } from "./request-rendezvous.js";
9
+ import { eraseRequestCommand } from "./request-wire.js";
10
+ import { z } from "zod";
11
+ import { World } from "../world.js";
12
+ function schemaDecode(decode, message) {
13
+ return z.unknown().transform((value, context) => {
14
+ try {
15
+ return decode(value);
16
+ }
17
+ catch {
18
+ context.addIssue({ code: "custom", message });
19
+ return z.NEVER;
20
+ }
21
+ });
22
+ }
23
+ const absolutePathSchema = z.string().refine((value) => isAbsolute(value) && resolve(value) === value);
24
+ const akuIdSchema = z.string().transform((value, context) => {
25
+ try {
26
+ const id = parseAkuId(value).id;
27
+ if (id !== value) {
28
+ context.addIssue({ code: "custom", message: "expected canonical AkuId" });
29
+ return z.NEVER;
30
+ }
31
+ return id;
32
+ }
33
+ catch {
34
+ context.addIssue({ code: "custom", message: "expected canonical AkuId" });
35
+ return z.NEVER;
36
+ }
37
+ });
38
+ const archetypeSchema = z.string().transform((value, context) => {
39
+ try {
40
+ return archetypeName(value);
41
+ }
42
+ catch {
43
+ context.addIssue({ code: "custom", message: "expected archetype" });
44
+ return z.NEVER;
45
+ }
46
+ });
47
+ const allowedActionsSchema = schemaDecode(decodeAllowedActions, "expected allowed actions");
48
+ const providerExecutionSchema = schemaDecode(decodeProviderExecution, "expected provider execution");
49
+ const providerOptionsSchema = schemaDecode(decodeProviderOptions, "expected provider options");
50
+ const readonlyRestraintSchema = schemaDecode(decodeReadonlyRestraint, "expected readonly restraint");
51
+ const akumaCallRecipeSchema = z
52
+ .object({
53
+ description: z.string().trim().min(1).optional(),
54
+ allowed: allowedActionsSchema,
55
+ provider: providerExecutionSchema,
56
+ options: providerOptionsSchema,
57
+ readonly: readonlyRestraintSchema.optional(),
58
+ })
59
+ .strict()
60
+ .superRefine((recipe, context) => {
61
+ if ((recipe.options.readonly === true) !== (recipe.readonly !== undefined)) {
62
+ context.addIssue({ code: "custom", message: "readonly recipe fields disagree" });
63
+ }
64
+ });
65
+ const akumaCallPayloadSchema = z
66
+ .object({
67
+ world: absolutePathSchema,
68
+ archetype: archetypeSchema,
69
+ body: z.string(),
70
+ cwd: absolutePathSchema.optional(),
71
+ recipe: akumaCallRecipeSchema,
72
+ })
73
+ .strict();
74
+ function carriesLaunchWorld(value) {
75
+ const upstream = object(value);
76
+ return upstream !== null && typeof upstream.launchWorld === "function";
77
+ }
78
+ function decodeCallExecutionContext(value) {
79
+ const context = object(value);
80
+ const paths = object(context?.paths);
81
+ const parent = object(context?.parent);
82
+ const parentId = akuIdSchema.safeParse(parent?.id);
83
+ if (context === null ||
84
+ typeof context.id !== "string" ||
85
+ context.id.trim() === "" ||
86
+ typeof context.requester !== "string" ||
87
+ typeof context.signal !== "object" ||
88
+ context.signal === null ||
89
+ typeof context.signal.throwIfAborted !== "function" ||
90
+ paths === null ||
91
+ !["directory", "heart", "leash", "log", "requests"].every((key) => typeof paths[key] === "string") ||
92
+ parent === null ||
93
+ !parentId.success ||
94
+ typeof parent.cwd !== "string" ||
95
+ !Array.isArray(parent.allowed) ||
96
+ typeof context.spawn !== "function" ||
97
+ typeof context.admissionOpen !== "function")
98
+ throw new Error("invalid Akuma call execution context");
99
+ if (!carriesLaunchWorld(context.upstream))
100
+ throw new Error("Akuma call requires a minted launch World");
101
+ return {
102
+ id: context.id,
103
+ requester: context.requester,
104
+ signal: context.signal,
105
+ world: context.upstream.launchWorld(),
106
+ paths: context.paths,
107
+ parent: context.parent,
108
+ spawn: context.spawn,
109
+ admissionOpen: context.admissionOpen,
110
+ };
111
+ }
112
+ function object(value) {
113
+ return value !== null && typeof value === "object" && !Array.isArray(value)
114
+ ? value
115
+ : null;
116
+ }
117
+ export function decodeAkumaCallRequest(value) {
118
+ const parsed = akumaCallPayloadSchema.safeParse(value);
119
+ return parsed.success ? { ...parsed.data, action: "akuma.call" } : null;
120
+ }
121
+ function callPayload(request) {
122
+ const { action: _action, ...payload } = request;
123
+ return payload;
124
+ }
125
+ async function executeAkumaCall(request, context) {
126
+ const world = context.world;
127
+ const requestWorld = await World.prove(request.world);
128
+ if (requestWorld !== world) {
129
+ await refuseRequest(context.paths, context.id, `request world ${requestWorld} does not match ${world}`);
130
+ throw new Error(`request world ${requestWorld} does not match ${world}`);
131
+ }
132
+ const recipe = {
133
+ ...(request.recipe.description === undefined ? {} : { description: request.recipe.description }),
134
+ allowed: clipAllowedActions(request.recipe.allowed, context.parent.allowed),
135
+ provider: request.recipe.provider,
136
+ options: request.recipe.options,
137
+ ...(request.recipe.readonly === undefined ? {} : { readonly: request.recipe.readonly }),
138
+ };
139
+ const published = await publishAkuma({
140
+ worldPath: world,
141
+ archetype: request.archetype,
142
+ signal: context.signal,
143
+ launch: async (allocated) => {
144
+ if (!context.admissionOpen())
145
+ throw new Error("body closed request admission");
146
+ await reserveRequest(context.paths, context.id, allocated.id);
147
+ return await context.spawn({
148
+ paths: allocated.paths,
149
+ seed: {
150
+ id: allocated.id,
151
+ archetype: allocated.archetype,
152
+ ...recipe,
153
+ cwd: request.cwd ?? context.parent.cwd,
154
+ origin: { kind: "request", parent: context.parent.id, requestId: context.id },
155
+ },
156
+ initialBody: request.body,
157
+ });
158
+ },
159
+ });
160
+ return { result: published.id, child: published.id };
161
+ }
162
+ export function akumaCallRequestCommand() {
163
+ return {
164
+ action: "akuma.call",
165
+ encodeRequest: callPayload,
166
+ decodeRequest: decodeAkumaCallRequest,
167
+ encodeResult: (result) => result,
168
+ decodeResult: (result) => {
169
+ const child = akuIdSchema.safeParse(result);
170
+ if (!child.success)
171
+ throw new Error("Akuma call returned an invalid child");
172
+ return child.data;
173
+ },
174
+ encodeService: (service) => service,
175
+ decodeService: (_service) => {
176
+ throw new Error("Akuma call has no service evidence");
177
+ },
178
+ projectService: (_service) => {
179
+ throw new Error("Akuma call has no service evidence");
180
+ },
181
+ projectChild: (child) => {
182
+ const id = akuIdSchema.safeParse(child);
183
+ if (!id.success)
184
+ throw new Error("Akuma call stored an invalid child reference");
185
+ return id.data;
186
+ },
187
+ decodeReference: (reference) => {
188
+ const child = akuIdSchema.safeParse(reference);
189
+ if (!child.success)
190
+ throw new Error("Akuma call stored an invalid child reference");
191
+ return child.data;
192
+ },
193
+ isPermitted: (allowed) => allowed.includes("akuma.call"),
194
+ decodeExecutionContext: decodeCallExecutionContext,
195
+ execute: executeAkumaCall,
196
+ };
197
+ }
198
+ export function akumaCallRequestCommands() {
199
+ return { "akuma.call": eraseRequestCommand(akumaCallRequestCommand()) };
200
+ }
201
+ export async function requestForwardedAkumaCall(input) {
202
+ const { directory, id, signal, ...request } = input;
203
+ const response = await requestBodyCommand({
204
+ directory,
205
+ id,
206
+ command: akumaCallRequestCommand(),
207
+ value: { ...request, action: "akuma.call" },
208
+ ...(signal === undefined ? {} : { signal }),
209
+ });
210
+ return response.kind === "returned" ? response.result : response.reference;
211
+ }
@@ -2,7 +2,6 @@ import type { AkuId } from "../identity.js";
2
2
  import type { ResumeCoordinate } from "../coordinate.js";
3
3
  import type { ProviderExecution, ProviderOptions, ReadonlyRestraint } from "../provider-recipe.js";
4
4
  import type { AllowedActions } from "../allowed.js";
5
- import type { TaskMutationAction, TaskMutationRequest } from "../../task/mutation.js";
6
5
  export type { ResumeCoordinate } from "../coordinate.js";
7
6
  export type AkumaOrigin = Readonly<{
8
7
  kind: "direct";
@@ -123,75 +122,10 @@ export type TellReceiptInput = Readonly<{
123
122
  turnSequence: number;
124
123
  fence: string;
125
124
  }>);
126
- export type TaskRequestInput = Readonly<{
127
- id: string;
128
- action: TaskMutationAction;
129
- world: string;
130
- request: TaskMutationRequest;
131
- }>;
132
125
  export type RequestInput = Readonly<{
133
126
  id: string;
134
- action: "akuma.call";
135
- archetype: string;
136
- body: string;
137
- cwd?: string;
138
- world: string;
139
- recipe: RequestRecipe;
140
- }> | Readonly<{
141
- id: string;
142
- action: "akuma.wait";
143
- targets: readonly AkuId[];
144
- completion: "any" | "all";
145
- timeoutMs?: number;
146
- }> | Readonly<{
147
- id: string;
148
- action: "akuma.tell";
149
- target: AkuId;
150
- body: string;
151
- }> | Readonly<{
152
- id: string;
153
- action: "akuma.kill";
154
- targets: readonly AkuId[];
155
- }> | Readonly<{
156
- id: string;
157
- action: "contract.deliver";
158
- repoRoot: string;
159
- contractId: string;
160
- message?: string;
161
- includeDirty: boolean;
162
- materializeConflict: boolean;
163
- }> | Readonly<{
164
- id: string;
165
- action: "contract.review";
166
- repoRoot: string;
167
- contractId: string;
168
- verdict: "satisfied" | "unsatisfied";
169
- summary?: string;
170
- }> | TaskRequestInput;
171
- export type UpstreamRequestService = Readonly<{
172
- action: "akuma.wait";
173
- }> | Readonly<{
174
- action: "akuma.tell";
175
- target: AkuId;
176
- tellId: string;
177
- }> | Readonly<{
178
- action: "akuma.kill";
179
- results: readonly Readonly<{
180
- id: AkuId;
181
- evidence: KillEvidence;
182
- }>[];
183
- }> | Readonly<{
184
- action: "contract.deliver";
185
- repoRoot: string;
186
- contractId: string;
187
- deliveryFactId: string;
188
- }> | Readonly<{
189
- action: "contract.review";
190
- repoRoot: string;
191
- contractId: string;
192
- reviewFactId: string;
193
- }> | Readonly<{
194
- action: TaskMutationRequest["action"];
127
+ action: string;
128
+ payloadJson: string;
195
129
  }>;
196
130
  type AdmittedRequest = RequestInput & Readonly<{
197
131
  requester: AkuId;
@@ -199,21 +133,15 @@ type AdmittedRequest = RequestInput & Readonly<{
199
133
  }>;
200
134
  export type RequestFact = (AdmittedRequest & Readonly<{
201
135
  state: "admitted";
202
- }>) | (Extract<AdmittedRequest, {
203
- action: "akuma.call";
204
- }> & Readonly<{
136
+ }>) | (AdmittedRequest & Readonly<{
205
137
  state: "reserved";
206
138
  child: AkuId;
207
- }>) | (Extract<AdmittedRequest, {
208
- action: "akuma.call";
209
- }> & Readonly<{
139
+ }>) | (AdmittedRequest & Readonly<{
210
140
  state: "served";
211
141
  child: AkuId;
212
- }>) | (Exclude<AdmittedRequest, {
213
- action: "akuma.call";
214
- }> & Readonly<{
142
+ }>) | (AdmittedRequest & Readonly<{
215
143
  state: "served";
216
- service: UpstreamRequestService;
144
+ serviceJson: string;
217
145
  }>) | (AdmittedRequest & Readonly<{
218
146
  state: "refused";
219
147
  diagnostic: string;
@@ -3,10 +3,10 @@ import type { BodyEnd, BodyFact, ForkPoint, HeartSnapshot, KillFact, SealFact, S
3
3
  export type { CallFact } from "./facts.js";
4
4
  import type { ActivityFact } from "./rows.js";
5
5
  import { type ActivityFactSlice } from "./timeline.js";
6
- export { HeartAbsentError, HeldAkumaLeash, classifyHeartSchema, initializeHeart, isHeartAbsent, probeLeash, watchHeart, } from "./storage.js";
7
- export { admitRequest, readNonterminalRequests, readRequest, refuseRequest, reserveRequest, serveRequest, serveUpstreamRequest, voidRequest, } from "./request-authority.js";
6
+ export { HeartAbsentError, HeldAkumaLeash, classifyHeartSchema, initializeHeart, isHeartAbsent, probeLeash, } from "./storage.js";
7
+ export { admitRequest, isRequestInputConflict, readNonterminalRequests, readRequest, refuseRequest, reserveRequest, serveRequest, serveUpstreamRequest, voidRequest, } from "./request-authority.js";
8
8
  export { life, lifeAt } from "./facts.js";
9
- export type { AkumaLife, AkumaOrigin, BodyEnd, BodyFact, HeartSnapshot, ForkPoint, KillEvidence, KillFact, LeashProbe, PauseFact, RequestFact, RequestInput, RequestRecipe, UpstreamRequestService, SealFact, SessionFact, Soul, StopFact, TellFact, TellDelivery, TellDeliveryInput, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact, } from "./facts.js";
9
+ export type { AkumaLife, AkumaOrigin, BodyEnd, BodyFact, HeartSnapshot, ForkPoint, KillEvidence, KillFact, LeashProbe, PauseFact, RequestFact, RequestInput, RequestRecipe, SealFact, SessionFact, Soul, StopFact, TellFact, TellDelivery, TellDeliveryInput, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact, } from "./facts.js";
10
10
  export type { ResumeCoordinate } from "../coordinate.js";
11
11
  export declare function readSoul(paths: AkumaPaths): Promise<Soul | null>;
12
12
  export declare function heartExists(paths: AkumaPaths): Promise<boolean>;
@@ -4,8 +4,8 @@ import { insertTellDeliveryFact, insertTellFact, insertTellReceiptFact, pendingT
4
4
  import { activityFactSlice, lastActivityAt as readLastActivityAt, pruneActivityFacts, } from "./timeline.js";
5
5
  import { isHeartAbsent, readSealFromLeash, readTransaction, transaction, withHeart, withReadOnlyHeart, } from "./storage.js";
6
6
  import { soulFact } from "./soul.js";
7
- export { HeartAbsentError, HeldAkumaLeash, classifyHeartSchema, initializeHeart, isHeartAbsent, probeLeash, watchHeart, } from "./storage.js";
8
- export { admitRequest, readNonterminalRequests, readRequest, refuseRequest, reserveRequest, serveRequest, serveUpstreamRequest, voidRequest, } from "./request-authority.js";
7
+ export { HeartAbsentError, HeldAkumaLeash, classifyHeartSchema, initializeHeart, isHeartAbsent, probeLeash, } from "./storage.js";
8
+ export { admitRequest, isRequestInputConflict, readNonterminalRequests, readRequest, refuseRequest, reserveRequest, serveRequest, serveUpstreamRequest, voidRequest, } from "./request-authority.js";
9
9
  export { life, lifeAt } from "./facts.js";
10
10
  const ACTIVITY_LIMIT = 5_000;
11
11
  export async function readSoul(paths) {
@@ -1,11 +1,13 @@
1
- import type { AkuId, AkumaPaths } from "../identity.js";
2
- import type { RequestFact, RequestInput, UpstreamRequestService } from "./facts.js";
1
+ import { type AkuId, type AkumaPaths } from "../identity.js";
2
+ import type { RequestFact, RequestInput } from "./facts.js";
3
+ export declare function isRequestInputConflict(error: unknown): error is Error;
3
4
  export declare function admitRequest(paths: AkumaPaths, input: RequestInput & Readonly<{
4
5
  admittedAt: string;
6
+ permitted: boolean;
5
7
  }>): Promise<RequestFact>;
6
8
  export declare function reserveRequest(paths: AkumaPaths, id: string, child: AkuId): Promise<RequestFact>;
7
- export declare function serveRequest(paths: AkumaPaths, id: string, child: AkuId): Promise<RequestFact>;
8
- export declare function serveUpstreamRequest(paths: AkumaPaths, id: string, service: UpstreamRequestService): Promise<RequestFact>;
9
+ export declare function serveRequest(paths: AkumaPaths, id: string, child: string): Promise<RequestFact>;
10
+ export declare function serveUpstreamRequest(paths: AkumaPaths, id: string, serviceJson: string): Promise<RequestFact>;
9
11
  export declare function refuseRequest(paths: AkumaPaths, id: string, diagnostic: string): Promise<RequestFact>;
10
12
  export declare function voidRequest(paths: AkumaPaths, id: string, evidence: string): Promise<RequestFact>;
11
13
  export declare function readRequest(paths: AkumaPaths, id: string): Promise<RequestFact | null>;
@@ -1,39 +1,37 @@
1
+ import { parseAkuId } from "../identity.js";
1
2
  import { insertRequestFact, nonterminalRequestFacts, requestFact, updateRequestRefused, updateRequestReserved, updateRequestServed, updateRequestVoided, updateUpstreamRequestServed, } from "./request-rows.js";
2
3
  import { transaction, withHeart } from "./storage.js";
3
4
  import { soulFact } from "./soul.js";
4
- import { clipAllowedActions } from "../allowed.js";
5
5
  import { requestPayloadJson } from "./request-rows.js";
6
+ // This stays out of the public Heart index: only transport service projects it as a refusal.
7
+ class RequestInputConflictError extends Error {
8
+ constructor(id) {
9
+ super(`Akuma request ${id} reused different input`);
10
+ this.name = "RequestInputConflictError";
11
+ }
12
+ }
13
+ export function isRequestInputConflict(error) {
14
+ return error instanceof RequestInputConflictError;
15
+ }
6
16
  export async function admitRequest(paths, input) {
7
17
  return await withHeart(paths, (heart) => transaction(heart, () => {
8
18
  const soul = soulFact(heart);
9
19
  if (soul === null)
10
20
  throw new Error("Akuma request admission requires a born Soul");
11
- const action = input.action;
12
- const parentAllowed = soul.allowed;
13
- const permitted = action === "akuma.wait" || parentAllowed.includes(action);
14
- const normalized = input.action === "akuma.call"
15
- ? {
16
- ...input,
17
- recipe: {
18
- ...input.recipe,
19
- allowed: permitted ? clipAllowedActions(input.recipe.allowed, parentAllowed) : input.recipe.allowed,
20
- },
21
- }
22
- : input;
21
+ const { permitted, ...request } = input;
23
22
  insertRequestFact(heart, {
24
- ...normalized,
23
+ ...request,
25
24
  requester: soul.id,
26
- admittedAt: input.admittedAt,
27
- ...(permitted ? {} : { refusal: `not-allowed: ${action}` }),
25
+ ...(permitted ? {} : { refusal: `not-allowed: ${input.action}` }),
28
26
  });
29
27
  const fact = requestFact(heart, input.id);
30
28
  if (fact === null)
31
29
  throw new Error(`Akuma request ${input.id} was not admitted`);
32
30
  if (fact.requester !== soul.id ||
33
- fact.id !== normalized.id ||
34
- fact.action !== normalized.action ||
35
- requestPayloadJson(fact) !== requestPayloadJson(normalized)) {
36
- throw new Error(`Akuma request ${input.id} reused different input`);
31
+ fact.id !== input.id ||
32
+ fact.action !== input.action ||
33
+ requestPayloadJson(fact) !== requestPayloadJson(input)) {
34
+ throw new RequestInputConflictError(input.id);
37
35
  }
38
36
  return fact;
39
37
  }));
@@ -43,43 +41,41 @@ export async function reserveRequest(paths, id, child) {
43
41
  const before = requestFact(heart, id);
44
42
  if (before === null)
45
43
  throw new Error(`unknown Akuma request ${id}`);
46
- if (before.action !== "akuma.call")
47
- throw new Error(`Akuma request ${id} cannot reserve a child`);
48
44
  if (before.state === "admitted")
49
45
  updateRequestReserved(heart, id, child);
50
- else if ((before.state !== "reserved" && before.state !== "served") || before.child !== child) {
46
+ else if ((before.state !== "reserved" && before.state !== "served") ||
47
+ !("child" in before) ||
48
+ before.child !== child) {
51
49
  throw new Error(`Akuma request ${id} cannot reserve ${child}`);
52
50
  }
53
51
  return requestFact(heart, id);
54
52
  }));
55
53
  }
56
54
  export async function serveRequest(paths, id, child) {
55
+ const parsed = parseAkuId(child);
56
+ if (parsed.id !== child)
57
+ throw new Error(`Akuma request ${id} has a noncanonical child`);
57
58
  return await withHeart(paths, (heart) => transaction(heart, () => {
58
59
  const before = requestFact(heart, id);
59
60
  if (before === null)
60
61
  throw new Error(`unknown Akuma request ${id}`);
61
- if (before.action !== "akuma.call")
62
- throw new Error(`Akuma request ${id} cannot serve a child`);
63
- if (before.state === "reserved" && before.child === child)
64
- updateRequestServed(heart, id, child);
65
- else if (before.state !== "served" || before.child !== child) {
62
+ if (before.state === "reserved" && before.child === parsed.id)
63
+ updateRequestServed(heart, id, parsed.id);
64
+ else if (before.state !== "served" || !("child" in before) || before.child !== parsed.id) {
66
65
  throw new Error(`Akuma request ${id} cannot serve ${child}`);
67
66
  }
68
67
  return requestFact(heart, id);
69
68
  }));
70
69
  }
71
- export async function serveUpstreamRequest(paths, id, service) {
70
+ export async function serveUpstreamRequest(paths, id, serviceJson) {
72
71
  return await withHeart(paths, (heart) => transaction(heart, () => {
73
72
  const before = requestFact(heart, id);
74
73
  if (before === null)
75
74
  throw new Error(`unknown Akuma request ${id}`);
76
- if (before.action === "akuma.call" || service.action !== before.action) {
77
- throw new Error(`Akuma request ${id} has a mismatched service reference`);
78
- }
79
75
  if (before.state === "admitted")
80
- updateUpstreamRequestServed(heart, id, service);
81
- else if (before.state !== "served") {
82
- throw new Error(`Akuma request ${id} cannot be served as ${service.action}`);
76
+ updateUpstreamRequestServed(heart, id, serviceJson);
77
+ else if (before.state !== "served" || !("serviceJson" in before) || before.serviceJson !== serviceJson) {
78
+ throw new Error(`Akuma request ${id} cannot be served with this service reference`);
83
79
  }
84
80
  return requestFact(heart, id);
85
81
  }));
@@ -1,45 +1,34 @@
1
- import { isTaskMutationAction } from "../../task/mutation.js";
2
- function json(value) {
3
- return JSON.stringify(value);
4
- }
5
- function parsed(value) {
1
+ function assertJsonText(value) {
6
2
  if (typeof value !== "string")
7
3
  throw new Error("Akuma authority contains non-text JSON");
8
- return JSON.parse(value);
4
+ JSON.parse(value);
5
+ return value;
9
6
  }
10
7
  export function requestPayloadJson(input) {
11
- const { id: _id, action: _action, requester: _requester, admittedAt: _admittedAt, state: _state, child: _child, service: _service, diagnostic: _diagnostic, evidence: _evidence, refusal: _refusal, ...payload } = input;
12
- return json(payload);
8
+ return assertJsonText(input.payloadJson);
13
9
  }
14
10
  function decodeRequestRow(row) {
15
- const knownAction = ["akuma.call", "akuma.wait", "akuma.tell", "akuma.kill", "contract.deliver", "contract.review"].includes(row.action) || isTaskMutationAction(row.action);
16
- if (!knownAction)
17
- throw new Error(`Akuma authority contains an unknown request action: ${row.action}`);
18
- const payload = parsed(row.payload_json);
19
11
  const input = {
20
12
  id: row.id,
21
13
  requester: row.requester,
22
14
  action: row.action,
23
- ...payload,
15
+ payloadJson: assertJsonText(row.payload_json),
24
16
  admittedAt: row.admitted_at,
25
17
  };
26
18
  if (row.state === "reserved") {
27
- if (input.action !== "akuma.call" || row.child === null) {
19
+ if (row.child === null || row.service_json !== null) {
28
20
  throw new Error("Akuma authority contains an invalid reserved request");
29
21
  }
30
22
  return { ...input, state: row.state, child: row.child };
31
23
  }
32
24
  if (row.state === "served") {
33
- if (input.action === "akuma.call") {
34
- if (row.child === null)
35
- throw new Error("Akuma authority contains a served call without a child");
25
+ if (row.child !== null && row.service_json === null) {
36
26
  return { ...input, state: row.state, child: row.child };
37
27
  }
38
- if (row.service_json === null) {
39
- throw new Error("Akuma authority contains a served request without a service reference");
28
+ if (row.child === null && row.service_json !== null) {
29
+ return { ...input, state: row.state, serviceJson: assertJsonText(row.service_json) };
40
30
  }
41
- const service = parsed(row.service_json);
42
- return { ...input, state: row.state, service };
31
+ throw new Error("Akuma authority contains an invalid served request");
43
32
  }
44
33
  if (row.state === "refused")
45
34
  return { ...input, state: row.state, diagnostic: row.diagnostic };
@@ -82,8 +71,8 @@ export function updateRequestServed(database, id, child) {
82
71
  export function updateUpstreamRequestServed(database, id, service) {
83
72
  database
84
73
  .prepare(`UPDATE requests SET state = 'served', service_json = ?
85
- WHERE id = ? AND state = 'admitted' AND action != 'akuma.call'`)
86
- .run(json(service), id);
74
+ WHERE id = ? AND state = 'admitted'`)
75
+ .run(assertJsonText(service), id);
87
76
  }
88
77
  export function updateRequestRefused(database, id, diagnostic) {
89
78
  database