@astrosheep/keiyaku 4.0.4 → 4.0.6

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 (233) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +15 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +24 -4
  8. package/build/src/akuma/akuma.d.ts +2 -1
  9. package/build/src/akuma/akuma.js +27 -9
  10. package/build/src/akuma/allowed.d.ts +1 -1
  11. package/build/src/akuma/allowed.js +3 -10
  12. package/build/src/akuma/archetype.d.ts +3 -1
  13. package/build/src/akuma/archetype.js +11 -6
  14. package/build/src/akuma/body-turn.d.ts +64 -0
  15. package/build/src/akuma/body-turn.js +449 -0
  16. package/build/src/akuma/body.d.ts +4 -5
  17. package/build/src/akuma/body.js +9 -414
  18. package/build/src/akuma/heart/facts.d.ts +37 -9
  19. package/build/src/akuma/heart/facts.js +3 -1
  20. package/build/src/akuma/heart/index.d.ts +4 -13
  21. package/build/src/akuma/heart/index.js +14 -135
  22. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  23. package/build/src/akuma/heart/request-authority.js +119 -0
  24. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  25. package/build/src/akuma/heart/request-rows.js +88 -0
  26. package/build/src/akuma/heart/rows.d.ts +1 -28
  27. package/build/src/akuma/heart/rows.js +4 -138
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +11 -3
  30. package/build/src/akuma/heart/soul.js +0 -36
  31. package/build/src/akuma/heart/timeline.d.ts +1 -0
  32. package/build/src/akuma/heart/timeline.js +19 -0
  33. package/build/src/akuma/index.d.ts +1 -1
  34. package/build/src/akuma/nuke.d.ts +2 -0
  35. package/build/src/akuma/nuke.js +152 -0
  36. package/build/src/akuma/provider-recipe.js +1 -11
  37. package/build/src/akuma/provider.d.ts +4 -7
  38. package/build/src/akuma/providers/acp/config.d.ts +8 -0
  39. package/build/src/akuma/providers/acp/config.js +37 -0
  40. package/build/src/akuma/providers/acp/core.js +12 -2
  41. package/build/src/akuma/providers/acp/index.d.ts +1 -8
  42. package/build/src/akuma/providers/acp/index.js +2 -38
  43. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  44. package/build/src/akuma/providers/claude/index.js +12 -3
  45. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  46. package/build/src/akuma/providers/codex-app-server/index.js +5 -2
  47. package/build/src/akuma/providers/grok-build/index.js +1 -2
  48. package/build/src/akuma/providers/index.d.ts +3 -2
  49. package/build/src/akuma/providers/index.js +36 -36
  50. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  51. package/build/src/akuma/providers/opencode-sdk/index.js +14 -4
  52. package/build/src/akuma/providers/opencode-sdk/session.d.ts +2 -2
  53. package/build/src/akuma/providers/opencode-sdk/session.js +2 -2
  54. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  55. package/build/src/akuma/providers/pi/index.js +29 -6
  56. package/build/src/akuma/request-serve.d.ts +88 -0
  57. package/build/src/akuma/request-serve.js +484 -0
  58. package/build/src/akuma/request-wire.d.ts +125 -0
  59. package/build/src/akuma/request-wire.js +383 -0
  60. package/build/src/akuma/requests.d.ts +28 -94
  61. package/build/src/akuma/requests.js +52 -562
  62. package/build/src/akuma-body.d.ts +7 -0
  63. package/build/src/akuma-body.js +69 -2
  64. package/build/src/alias/index.d.ts +1 -0
  65. package/build/src/alias/index.js +34 -1
  66. package/build/src/body/arc.js +4 -29
  67. package/build/src/body/decode.js +5 -39
  68. package/build/src/body/envelope.d.ts +7 -0
  69. package/build/src/body/envelope.js +37 -0
  70. package/build/src/cli/accepted.js +21 -9
  71. package/build/src/cli/commands/akuma-invoke.js +1 -0
  72. package/build/src/cli/commands/akuma.d.ts +1 -0
  73. package/build/src/cli/commands/akuma.js +13 -10
  74. package/build/src/cli/commands/contract.d.ts +28 -17
  75. package/build/src/cli/commands/contract.js +23 -17
  76. package/build/src/cli/commands/install.d.ts +2 -2
  77. package/build/src/cli/commands/install.js +6 -6
  78. package/build/src/cli/commands/nuke.d.ts +10 -0
  79. package/build/src/cli/commands/nuke.js +20 -0
  80. package/build/src/cli/commands/task-invoke.d.ts +15 -0
  81. package/build/src/cli/commands/task-invoke.js +144 -24
  82. package/build/src/cli/commands/task-query.d.ts +2 -2
  83. package/build/src/cli/commands/task-query.js +1 -2
  84. package/build/src/cli/commands/task.js +22 -22
  85. package/build/src/cli/coordinates.d.ts +6 -2
  86. package/build/src/cli/coordinates.js +12 -56
  87. package/build/src/cli/invoke.d.ts +5 -4
  88. package/build/src/cli/invoke.js +112 -58
  89. package/build/src/cli/main.d.ts +0 -2
  90. package/build/src/cli/main.js +4 -140
  91. package/build/src/cli/parse.d.ts +17 -4
  92. package/build/src/cli/parse.js +93 -15
  93. package/build/src/cli/render/akuma.js +111 -53
  94. package/build/src/cli/render/audit.js +2 -6
  95. package/build/src/cli/render/contract.js +61 -20
  96. package/build/src/cli/render/kanshi.js +15 -5
  97. package/build/src/cli/render/nuke.d.ts +3 -0
  98. package/build/src/cli/render/nuke.js +8 -0
  99. package/build/src/cli/render/receipt.js +28 -1
  100. package/build/src/cli/render/refusal.d.ts +2 -1
  101. package/build/src/cli/render/refusal.js +31 -0
  102. package/build/src/cli/render/terminal.d.ts +0 -2
  103. package/build/src/cli/render/terminal.js +0 -29
  104. package/build/src/cli/render/text.js +6 -1
  105. package/build/src/cli/result.d.ts +36 -9
  106. package/build/src/cli/runtime.d.ts +2 -0
  107. package/build/src/cli/runtime.js +140 -0
  108. package/build/src/cli/usage.d.ts +0 -2
  109. package/build/src/cli/usage.js +0 -4
  110. package/build/src/contract-worktree.d.ts +29 -14
  111. package/build/src/contract-worktree.js +131 -70
  112. package/build/src/core/facts/codec.js +9 -0
  113. package/build/src/core/facts/fold.js +13 -1
  114. package/build/src/core/facts/types.d.ts +8 -1
  115. package/build/src/core/subject.js +4 -3
  116. package/build/src/core/verbs/placement.d.ts +9 -1
  117. package/build/src/core/verbs/placement.js +24 -6
  118. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  119. package/build/src/core/verbs/reintegrate.js +24 -0
  120. package/build/src/dispatch/index.d.ts +1 -1
  121. package/build/src/git/admission.d.ts +2 -1
  122. package/build/src/git/hooks.d.ts +2 -0
  123. package/build/src/git/hooks.js +34 -1
  124. package/build/src/git/integration.d.ts +9 -2
  125. package/build/src/git/integration.js +92 -1
  126. package/build/src/git/nuke.d.ts +2 -0
  127. package/build/src/git/nuke.js +97 -0
  128. package/build/src/git/observe.d.ts +2 -1
  129. package/build/src/git/observe.js +6 -5
  130. package/build/src/git/process.d.ts +28 -0
  131. package/build/src/git/process.js +94 -0
  132. package/build/src/git/read-observation.d.ts +2 -1
  133. package/build/src/git/read-observation.js +3 -2
  134. package/build/src/git/reconcile.d.ts +4 -1
  135. package/build/src/git/reconcile.js +42 -8
  136. package/build/src/git/repository.d.ts +2 -29
  137. package/build/src/git/repository.js +7 -118
  138. package/build/src/git/scratch.d.ts +1 -1
  139. package/build/src/git/scratch.js +1 -1
  140. package/build/src/git/target-placement.d.ts +3 -2
  141. package/build/src/git/target-placement.js +15 -14
  142. package/build/src/git/tender.d.ts +2 -1
  143. package/build/src/git/tender.js +4 -3
  144. package/build/src/git/terminal-seal.d.ts +2 -2
  145. package/build/src/git/terminal-seal.js +3 -6
  146. package/build/src/git/workspace.d.ts +4 -1
  147. package/build/src/git/workspace.js +1 -1
  148. package/build/src/index.d.ts +1 -2
  149. package/build/src/index.js +1 -1
  150. package/build/src/kanshi/read.js +5 -1
  151. package/build/src/library/address.js +7 -1
  152. package/build/src/library/akuma-creation.d.ts +1 -0
  153. package/build/src/library/akuma-creation.js +8 -1
  154. package/build/src/library/audit.d.ts +3 -1
  155. package/build/src/library/audit.js +2 -1
  156. package/build/src/library/bind.d.ts +2 -1
  157. package/build/src/library/bind.js +1 -1
  158. package/build/src/library/configuration.d.ts +1 -1
  159. package/build/src/library/configuration.js +52 -18
  160. package/build/src/library/contract.d.ts +59 -4
  161. package/build/src/library/contract.js +195 -34
  162. package/build/src/library/delivery.d.ts +4 -2
  163. package/build/src/library/fleet.d.ts +27 -7
  164. package/build/src/library/fleet.js +79 -39
  165. package/build/src/library/input.d.ts +0 -1
  166. package/build/src/library/input.js +0 -5
  167. package/build/src/library/keiyaku.d.ts +6 -2
  168. package/build/src/library/keiyaku.js +2 -0
  169. package/build/src/library/mutation.d.ts +3 -1
  170. package/build/src/library/mutation.js +3 -0
  171. package/build/src/library/nuke.d.ts +14 -0
  172. package/build/src/library/nuke.js +54 -0
  173. package/build/src/library/reconcile.d.ts +2 -1
  174. package/build/src/library/reconcile.js +8 -3
  175. package/build/src/library/refusal.d.ts +10 -1
  176. package/build/src/library/region.d.ts +1 -1
  177. package/build/src/library/repo.d.ts +4 -1
  178. package/build/src/library/repo.js +10 -4
  179. package/build/src/protocol/abandon.d.ts +9 -0
  180. package/build/src/protocol/abandon.js +15 -0
  181. package/build/src/protocol/amend.d.ts +16 -0
  182. package/build/src/protocol/amend.js +77 -0
  183. package/build/src/protocol/arc.d.ts +6 -0
  184. package/build/src/protocol/arc.js +12 -0
  185. package/build/src/protocol/attempt.d.ts +2 -1
  186. package/build/src/protocol/audit.d.ts +53 -0
  187. package/build/src/protocol/audit.js +147 -0
  188. package/build/src/protocol/bind.d.ts +1 -1
  189. package/build/src/protocol/completion.d.ts +42 -0
  190. package/build/src/protocol/completion.js +183 -0
  191. package/build/src/protocol/deliver.d.ts +49 -0
  192. package/build/src/protocol/deliver.js +261 -0
  193. package/build/src/protocol/intent.d.ts +2 -1
  194. package/build/src/protocol/intent.js +8 -2
  195. package/build/src/protocol/operations.d.ts +93 -202
  196. package/build/src/protocol/operations.js +23 -642
  197. package/build/src/protocol/placement.d.ts +12 -13
  198. package/build/src/protocol/placement.js +8 -19
  199. package/build/src/protocol/read/status.d.ts +17 -5
  200. package/build/src/protocol/read/status.js +57 -13
  201. package/build/src/protocol/reconcile.d.ts +35 -0
  202. package/build/src/protocol/reconcile.js +41 -0
  203. package/build/src/protocol/reintegrate.d.ts +31 -0
  204. package/build/src/protocol/reintegrate.js +74 -0
  205. package/build/src/protocol/review.d.ts +34 -0
  206. package/build/src/protocol/review.js +156 -0
  207. package/build/src/protocol/run.d.ts +1 -1
  208. package/build/src/runtime/proc/run.js +9 -5
  209. package/build/src/settlement/fence.d.ts +3 -1
  210. package/build/src/settlement/fence.js +24 -0
  211. package/build/src/settlement/holder.d.ts +1 -1
  212. package/build/src/settlement/settle.d.ts +1 -1
  213. package/build/src/settlement/settle.js +1 -2
  214. package/build/src/task/board.d.ts +0 -1
  215. package/build/src/task/board.js +0 -3
  216. package/build/src/task/compose.d.ts +2 -2
  217. package/build/src/task/compose.js +13 -11
  218. package/build/src/task/context.d.ts +14 -2
  219. package/build/src/task/context.js +30 -7
  220. package/build/src/task/index.d.ts +7 -6
  221. package/build/src/task/index.js +17 -145
  222. package/build/src/task/input.d.ts +18 -0
  223. package/build/src/task/input.js +189 -0
  224. package/build/src/task/mutation.d.ts +44 -0
  225. package/build/src/task/mutation.js +93 -0
  226. package/build/src/task/operations.d.ts +14 -6
  227. package/build/src/task/operations.js +57 -57
  228. package/build/src/task/store.d.ts +1 -0
  229. package/build/src/task/store.js +91 -3
  230. package/build/src/verification/execution.d.ts +1 -1
  231. package/build/src/workspace-place.d.ts +3 -4
  232. package/build/src/workspace-place.js +26 -15
  233. package/package.json +3 -3
@@ -1,159 +1,20 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { abortableDelay } from "./abort.js";
3
- import { HeldAkumaLeash, appendActivity, beginTurn, breakBody, endTurn, finishBodyIfIdle, heartExists, isHeartAbsent, readHeart, recordSession, recordTellDeliveries, recordTellReceipt, } from "./heart/index.js";
4
- import { encodeAgentEvent, } from "./provider.js";
3
+ import { BodySupervisor, driveTurn, turnRecipe } from "./body-turn.js";
4
+ import { HeldAkumaLeash, breakBody, endTurn, finishBodyIfIdle, heartExists, isHeartAbsent, readHeart, } from "./heart/index.js";
5
5
  import { resolveProviderExecution } from "./providers/index.js";
6
- import { BodyRequestPump, clearBodyRequestTransport, settleBodyRequests, } from "./requests.js";
6
+ import { clearBodyRequestTransport, settleBodyRequests, } from "./request-serve.js";
7
7
  import { spawnDetachedProcess, } from "../runtime/proc/run.js";
8
8
  const LEASH_RETRY_MS = 25;
9
- const BODY_CONTROL_OBSERVATION_MS = 100;
10
- export const CONTROL_RESPONSE_MS = 1_000;
11
- class BodySupervisor {
12
- paths;
13
- bodySequence;
14
- leash;
15
- signal;
16
- controller = new AbortController();
17
- finished = new AbortController();
18
- observer;
19
- waiter;
20
- observation;
21
- stopping;
22
- constructor(paths, bodySequence, leash, observation) {
23
- this.paths = paths;
24
- this.bodySequence = bodySequence;
25
- this.leash = leash;
26
- this.signal = this.controller.signal;
27
- this.observation = observation;
28
- this.observer = this.observe();
29
- }
30
- static async open(paths, bodySequence, leash) {
31
- return new BodySupervisor(paths, bodySequence, leash, await readHeart(paths));
32
- }
33
- get reason() { return this.stopping; }
34
- current() { return this.observation; }
35
- async recordHung(diagnostic, at) {
36
- await this.leash.recordBodyHung(this.paths, { sequence: this.bodySequence, diagnostic, at });
37
- }
38
- async refresh() {
39
- this.publish(await readHeart(this.paths));
40
- return this.observation;
41
- }
42
- next(after) {
43
- if (this.observation !== after)
44
- return Promise.resolve(this.observation);
45
- return new Promise((resolve) => { this.waiter = resolve; });
46
- }
47
- cancel(reason) {
48
- if (this.stopping !== undefined)
49
- return;
50
- this.stopping = reason;
51
- this.controller.abort(new Error(reason === "control"
52
- ? "Akuma Body interrupted by durable control"
53
- : "Akuma Heart disappeared"));
54
- this.waiter?.(this.observation);
55
- this.waiter = undefined;
56
- }
57
- async close() {
58
- this.finished.abort();
59
- await this.observer;
60
- this.waiter = undefined;
61
- }
62
- publish(snapshot) {
63
- this.observation = snapshot;
64
- this.waiter?.(snapshot);
65
- this.waiter = undefined;
66
- }
67
- async observe() {
68
- for (;;) {
69
- const snapshot = this.observation;
70
- if (!await heartExists(this.paths)) {
71
- this.cancel("heart-gone");
72
- return;
73
- }
74
- if (bodyControlRequested(snapshot, this.bodySequence)) {
75
- this.cancel("control");
76
- return;
77
- }
78
- try {
79
- await abortableDelay(BODY_CONTROL_OBSERVATION_MS, this.finished.signal);
80
- }
81
- catch {
82
- return;
83
- }
84
- try {
85
- await this.refresh();
86
- }
87
- catch (error) {
88
- if (await heartExists(this.paths))
89
- throw error;
90
- this.cancel("heart-gone");
91
- return;
92
- }
93
- }
94
- }
95
- }
96
- function serializeEffects() {
97
- let tail = Promise.resolve();
98
- let failed = false;
99
- let failure;
100
- const serialize = async (effect) => {
101
- const result = tail.then(effect);
102
- tail = result.then(() => undefined, (error) => {
103
- if (!failed)
104
- failure = error;
105
- failed = true;
106
- });
107
- return await result;
108
- };
109
- serialize.drain = async () => {
110
- await tail;
111
- if (failed)
112
- throw failure;
113
- };
114
- return serialize;
115
- }
9
+ export { CONTROL_RESPONSE_MS } from "./body-turn.js";
116
10
  function missing(error) {
117
11
  return isHeartAbsent(error) || error.code === "ENOENT";
118
12
  }
119
- async function writeProviderEvent(input, active, event) {
120
- if (input.supervisor.signal.aborted)
121
- return;
122
- const at = input.now();
123
- if (event.type === "session") {
124
- await recordSession(input.paths, {
125
- provider: input.soul.provider.name,
126
- coordinate: event.coordinate,
127
- cwd: active.cwd,
128
- options: active.options,
129
- admittedAt: at,
130
- });
131
- }
132
- await appendActivity(input.paths, {
133
- turnSequence: active.turnSequence,
134
- event: encodeAgentEvent(event),
135
- at,
136
- });
137
- }
138
- function bodyControlRequested(snapshot, bodySequence) {
139
- return snapshot.stop?.bodySequence === bodySequence
140
- || snapshot.pause?.bodySequence === bodySequence;
141
- }
142
13
  async function putDownIfControlled(paths, supervisor, bodySequence, now) {
143
14
  if (supervisor.reason === "control" && await heartExists(paths)) {
144
15
  await breakBody(paths, { sequence: bodySequence, end: "put-down", at: now() });
145
16
  }
146
17
  }
147
- async function turnRecipe(paths, soul) {
148
- const latest = (await readHeart(paths)).latestSession;
149
- const admitted = latest?.provider === soul.provider.name ? latest : undefined;
150
- const session = admitted?.coordinate;
151
- return {
152
- cwd: admitted?.cwd ?? soul.cwd,
153
- options: admitted?.options ?? soul.options,
154
- ...(session === undefined ? {} : { session }),
155
- };
156
- }
157
18
  async function takeLeash(paths) {
158
19
  for (;;) {
159
20
  try {
@@ -169,270 +30,6 @@ async function takeLeash(paths) {
169
30
  await abortableDelay(LEASH_RETRY_MS);
170
31
  }
171
32
  }
172
- async function startTurnDrive(input) {
173
- const { cwd, options, session } = await turnRecipe(input.paths, input.soul);
174
- if (session !== undefined && input.adapter.resume === undefined)
175
- return { kind: "resume-unsupported" };
176
- const turn = await beginTurn(input.paths, {
177
- bodySequence: input.bodySequence,
178
- startedAt: input.now(),
179
- ...(input.call === undefined ? {} : { call: input.call }),
180
- });
181
- const requests = input.soul.confinement.kind === "declared"
182
- ? await BodyRequestPump.open({
183
- paths: input.paths,
184
- parent: input.soul,
185
- bodySequence: input.bodySequence,
186
- now: input.now,
187
- spawn: input.runtimeSpawn,
188
- ...(input.upstream === undefined ? {} : { upstream: input.upstream }),
189
- signal: input.supervisor.signal,
190
- })
191
- : null;
192
- const driveInput = {
193
- body: input.body,
194
- launchTells: input.launchTells.map((tell) => ({ id: tell.id, text: tell.body })),
195
- cwd,
196
- options,
197
- signal: input.supervisor.signal,
198
- ...(requests === null ? {} : { requests: { dir: requests.directory } }),
199
- };
200
- const setup = session === undefined
201
- ? input.adapter.start({ ...driveInput, session: { kind: "fresh" } })
202
- : input.adapter.resume({ ...driveInput, session: { kind: "resume", coordinate: session } });
203
- try {
204
- const selected = await setup;
205
- if (input.supervisor.signal.aborted) {
206
- await retireProviderCustody(input, turn.sequence, selected);
207
- await requests?.close();
208
- return { kind: "stopped" };
209
- }
210
- if (input.launchTells.length > 0) {
211
- await recordTellDeliveries(input.paths, input.launchTells.map((tell) => ({
212
- tellId: tell.id,
213
- route: "launch",
214
- turnSequence: turn.sequence,
215
- fence: selected.admission.fence,
216
- deliveredAt: input.now(),
217
- })));
218
- }
219
- if (requests !== null)
220
- void selected.completion.then(() => requests.stopAdmission());
221
- return { turnSequence: turn.sequence, drive: selected, requests, cwd, options,
222
- ...(session === undefined ? {} : { resume: session }) };
223
- }
224
- catch (error) {
225
- await requests?.close();
226
- if (input.supervisor.signal.aborted) {
227
- if (input.supervisor.reason === "heart-gone")
228
- throw error;
229
- return { kind: "stopped" };
230
- }
231
- return {
232
- kind: "failed",
233
- turnSequence: turn.sequence,
234
- diagnostic: error instanceof Error ? error.message : String(error),
235
- };
236
- }
237
- }
238
- async function retireProviderCustody(input, turnSequence, drive) {
239
- const outcome = await Promise.race([
240
- drive.abort().then(() => ({ kind: "retired" }), (error) => ({ kind: "held", error })),
241
- abortableDelay(CONTROL_RESPONSE_MS).then(() => ({
242
- kind: "held",
243
- error: new Error(`provider custody remained live after ${CONTROL_RESPONSE_MS}ms`),
244
- })),
245
- ]);
246
- if (outcome.kind === "retired")
247
- return;
248
- if (await heartExists(input.paths)) {
249
- const diagnostic = outcome.error instanceof Error ? outcome.error.message : String(outcome.error);
250
- const at = input.now();
251
- try {
252
- await input.supervisor.recordHung(diagnostic, at);
253
- await appendActivity(input.paths, {
254
- turnSequence,
255
- event: encodeAgentEvent({ type: "note", text: `Provider custody was not retired: ${diagnostic}` }),
256
- at,
257
- });
258
- }
259
- catch { /* undisposed provider custody still owns the leash */ }
260
- }
261
- for (;;)
262
- await abortableDelay(60_000);
263
- }
264
- function pumpReceipts(writers) {
265
- const { input, turnSequence, drive, writeWitness, mayWrite } = writers;
266
- return (async () => {
267
- if (drive.receipts === undefined)
268
- return;
269
- for await (const receipt of drive.receipts) {
270
- if (!mayWrite())
271
- return;
272
- await writeWitness(async () => {
273
- if (!mayWrite())
274
- return;
275
- await recordTellReceipt(input.paths, receipt.evidence === "exact"
276
- ? { ...receipt, receivedAt: input.now() }
277
- : { ...receipt, turnSequence, receivedAt: input.now() });
278
- });
279
- }
280
- })();
281
- }
282
- function observeReceiptFailure(receiptPump) {
283
- return receiptPump.then(() => new Promise(() => { }), (error) => Promise.reject(error));
284
- }
285
- async function submitPendingLiveTells(writers, pending, attempted, tellLive) {
286
- const { input, turnSequence, drive, writeWitness, mayWrite } = writers;
287
- for (const tell of pending) {
288
- if (attempted.has(tell.id))
289
- continue;
290
- attempted.add(tell.id);
291
- const outcome = await writeWitness(async () => {
292
- const submission = await tellLive({ id: tell.id, text: tell.body });
293
- if (!mayWrite())
294
- return "turn-ended";
295
- if (submission.kind === "turn-ended")
296
- return "turn-ended";
297
- await recordTellDeliveries(input.paths, [{
298
- tellId: tell.id,
299
- route: "live",
300
- turnSequence,
301
- fence: submission.fence,
302
- receipt: drive.receipts === undefined ? "unavailable" : "required",
303
- deliveredAt: input.now(),
304
- }]);
305
- return "accepted";
306
- });
307
- if (outcome === "turn-ended")
308
- return "turn-ended";
309
- }
310
- return "live";
311
- }
312
- async function stopActiveDrive(input, active) {
313
- await retireProviderCustody(input, active.turnSequence, active.drive);
314
- await active.requests?.close();
315
- }
316
- function hasUnattemptedTell(liveTells, tellPump, pending, attempted) {
317
- return liveTells && tellPump === null && pending.some((tell) => !attempted.has(tell.id));
318
- }
319
- function persistProviderEvent(_input, _active, event) {
320
- return event.type === "session" ? event.coordinate : undefined;
321
- }
322
- async function settleCompletion(result, session, requests) {
323
- await requests?.close();
324
- return result.kind === "answered" ? { ...result, ...(session === undefined ? {} : { session }) } : result;
325
- }
326
- async function consumeTurnDrive(input, active) {
327
- const { turnSequence, drive, requests, resume } = active;
328
- let heart = input.supervisor.current();
329
- let turnSession = resume;
330
- const attempted = new Set(input.launchTells.map((tell) => tell.id));
331
- const writeWitness = serializeEffects();
332
- let writesOpen = true;
333
- const mayWrite = () => writesOpen && !input.supervisor.signal.aborted;
334
- const writers = { input, turnSequence, drive, writeWitness, mayWrite };
335
- const receiptPump = pumpReceipts(writers);
336
- const receiptFailure = observeReceiptFailure(receiptPump);
337
- const iterator = drive.events[Symbol.asyncIterator]();
338
- let pending = iterator.next();
339
- let liveTells = true;
340
- let tellPump = null;
341
- let tellObservation = null;
342
- try {
343
- for (;;) {
344
- if (input.supervisor.signal.aborted) {
345
- writesOpen = false;
346
- await stopActiveDrive(input, active);
347
- return { kind: "stopped" };
348
- }
349
- if (hasUnattemptedTell(liveTells, tellPump, heart.pending, attempted)) {
350
- if (drive.tell === undefined) {
351
- writesOpen = false;
352
- await stopActiveDrive(input, active);
353
- return { kind: "handoff" };
354
- }
355
- tellPump = submitPendingLiveTells(writers, heart.pending, attempted, drive.tell);
356
- tellObservation = tellPump.then((result) => ({ kind: "tell", result }));
357
- }
358
- const next = await Promise.race([
359
- pending.then((event) => ({ kind: "event", event })),
360
- input.supervisor.next(heart).then((observation) => ({ kind: "heart", observation })),
361
- ...(tellObservation === null ? [] : [tellObservation]),
362
- receiptFailure,
363
- ...(requests === null ? [] : [requests.failure]),
364
- ]);
365
- if (next.kind === "event" && !next.event.done) {
366
- await writeProviderEvent(input, active, next.event.value);
367
- }
368
- if (next.kind === "heart") {
369
- heart = next.observation;
370
- continue;
371
- }
372
- if (next.kind === "tell") {
373
- tellPump = null;
374
- tellObservation = null;
375
- liveTells = next.result === "live";
376
- continue;
377
- }
378
- if (next.event.done)
379
- break;
380
- turnSession = persistProviderEvent(input, active, next.event.value) ?? turnSession;
381
- pending = iterator.next();
382
- }
383
- const result = await drive.completion;
384
- if (tellPump !== null)
385
- await tellPump;
386
- await writeWitness.drain();
387
- writesOpen = false;
388
- return await settleCompletion(result, turnSession, requests);
389
- }
390
- catch (error) {
391
- writesOpen = false;
392
- if (input.supervisor.signal.aborted) {
393
- await stopActiveDrive(input, active);
394
- return { kind: "stopped" };
395
- }
396
- await retireProviderCustody(input, turnSequence, drive);
397
- try {
398
- await requests?.close();
399
- }
400
- catch { /* preserve the first pump failure */ }
401
- return { kind: "failed", diagnostic: error instanceof Error ? error.message : String(error) };
402
- }
403
- }
404
- async function driveTurn(input) {
405
- let active;
406
- try {
407
- const started = await startTurnDrive(input);
408
- if ("kind" in started)
409
- return started;
410
- active = started;
411
- }
412
- catch (error) {
413
- if (!await heartExists(input.paths)) {
414
- input.supervisor.cancel("heart-gone");
415
- return { kind: "stopped" };
416
- }
417
- throw error;
418
- }
419
- try {
420
- const result = await consumeTurnDrive(input, active);
421
- return result.kind === "stopped" || result.kind === "handoff"
422
- ? result
423
- : { ...result, turnSequence: active.turnSequence };
424
- }
425
- catch (error) {
426
- if (await heartExists(input.paths)) {
427
- await active.requests?.close();
428
- return { kind: "failed", diagnostic: error instanceof Error ? error.message : String(error),
429
- turnSequence: active.turnSequence };
430
- }
431
- input.supervisor.cancel("heart-gone");
432
- await stopActiveDrive(input, active);
433
- return { kind: "stopped" };
434
- }
435
- }
436
33
  async function bornSoul(launch, leash, now) {
437
34
  const before = await readHeart(launch.paths);
438
35
  if (before.soul !== null)
@@ -542,6 +139,8 @@ async function runBodyTurns(input) {
542
139
  ...(runtime.upstream === undefined ? {} : { upstream: runtime.upstream }),
543
140
  now: runtime.now,
544
141
  });
142
+ if (result.kind === "hung")
143
+ return;
545
144
  if (result.kind === "stopped") {
546
145
  await putDownIfControlled(launch.paths, supervisor, bodySequence, runtime.now);
547
146
  return;
@@ -567,7 +166,7 @@ export async function driveAkumaBody(launch, adapter, runtime = defaultRuntime()
567
166
  const soul = await bornSoul(launch, leash, runtime.now());
568
167
  if (soul === null)
569
168
  return;
570
- const selected = adapter ?? resolveProviderExecution(soul.provider).adapter;
169
+ const selected = adapter ?? (await resolveProviderExecution(soul.provider)).adapter;
571
170
  if (!await prepareBodyStart(launch.paths, leash))
572
171
  return;
573
172
  const body = await leash.recordBody(launch.paths, { leashTakenAt: runtime.now() });
@@ -610,14 +209,10 @@ export async function spawnAkumaBody(launch) {
610
209
  });
611
210
  owned.release();
612
211
  }
613
- export async function runAkumaBody(upstreamFor) {
614
- const encoded = process.argv[2];
615
- if (encoded === undefined)
616
- throw new TypeError("Akuma body launch payload is missing");
617
- const launch = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
212
+ export async function runAkumaBody(launch, upstream) {
618
213
  await driveAkumaBody(launch, undefined, {
619
214
  now: () => new Date().toISOString(),
620
215
  spawnChild: spawnAkumaBody,
621
- upstream: upstreamFor(launch),
216
+ upstream,
622
217
  });
623
218
  }
@@ -2,13 +2,8 @@ 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";
5
6
  export type { ResumeCoordinate } from "../coordinate.js";
6
- export type Confinement = Readonly<{
7
- kind: "unconfined";
8
- }> | Readonly<{
9
- kind: "declared";
10
- writableRoots: readonly string[];
11
- }>;
12
7
  export type AkumaOrigin = Readonly<{
13
8
  kind: "direct";
14
9
  }> | Readonly<{
@@ -29,11 +24,10 @@ export type Soul = Readonly<{
29
24
  readonly?: ReadonlyRestraint;
30
25
  cwd: string;
31
26
  origin: AkumaOrigin;
32
- confinement: Confinement;
33
27
  allowed: AllowedActions;
34
28
  createdAt: string;
35
29
  }>;
36
- export type RequestRecipe = Pick<Soul, "description" | "provider" | "options" | "readonly" | "confinement" | "allowed">;
30
+ export type RequestRecipe = Pick<Soul, "description" | "provider" | "options" | "readonly" | "allowed">;
37
31
  export type BodyEnd = "exited" | "broke-off" | "put-down";
38
32
  export type BodyFact = Readonly<{
39
33
  sequence: number;
@@ -129,6 +123,12 @@ export type TellReceiptInput = Readonly<{
129
123
  turnSequence: number;
130
124
  fence: string;
131
125
  }>);
126
+ export type TaskRequestInput = Readonly<{
127
+ id: string;
128
+ action: TaskMutationAction;
129
+ world: string;
130
+ request: TaskMutationRequest;
131
+ }>;
132
132
  export type RequestInput = Readonly<{
133
133
  id: string;
134
134
  action: "akuma.call";
@@ -152,7 +152,22 @@ export type RequestInput = Readonly<{
152
152
  id: string;
153
153
  action: "akuma.kill";
154
154
  targets: readonly AkuId[];
155
- }>;
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;
156
171
  export type UpstreamRequestService = Readonly<{
157
172
  action: "akuma.wait";
158
173
  }> | Readonly<{
@@ -165,6 +180,18 @@ export type UpstreamRequestService = Readonly<{
165
180
  id: AkuId;
166
181
  evidence: KillEvidence;
167
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"];
168
195
  }>;
169
196
  type AdmittedRequest = RequestInput & Readonly<{
170
197
  requester: AkuId;
@@ -223,6 +250,7 @@ export type HeartSnapshot = Readonly<{
223
250
  latestKill: KillFact | null;
224
251
  stop: StopFact | null;
225
252
  pause: PauseFact | null;
253
+ lastActivityAt: string | null;
226
254
  }>;
227
255
  export declare function life(input: Readonly<{
228
256
  leash: LeashProbe;
@@ -1,6 +1,8 @@
1
1
  export function life(input) {
2
+ if (input.body?.hung !== undefined)
3
+ return "hung";
2
4
  if (input.leash === "held")
3
- return input.body?.hung === undefined ? "running" : "hung";
5
+ return "running";
4
6
  if (input.body === null || input.body.end === undefined)
5
7
  return "untidy";
6
8
  if (input.kill?.bodySequence === input.body.sequence)
@@ -1,11 +1,12 @@
1
- import type { AkuId, AkumaPaths } from "../identity.js";
2
- import type { BodyEnd, BodyFact, ForkPoint, HeartSnapshot, KillFact, RequestFact, RequestInput, UpstreamRequestService, SealFact, SessionFact, Soul, TellDeliveryInput, TellFact, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact } from "./facts.js";
1
+ import type { AkumaPaths } from "../identity.js";
2
+ import type { BodyEnd, BodyFact, ForkPoint, HeartSnapshot, KillFact, SealFact, SessionFact, Soul, TellDeliveryInput, TellFact, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact } from "./facts.js";
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
6
  export { HeartAbsentError, HeldAkumaLeash, initializeHeart, isHeartAbsent, probeLeash } from "./storage.js";
7
+ export { admitRequest, readNonterminalRequests, readRequest, refuseRequest, reserveRequest, serveRequest, serveUpstreamRequest, voidRequest, } from "./request-authority.js";
7
8
  export { life, lifeAt } from "./facts.js";
8
- export type { AkumaLife, AkumaOrigin, BodyEnd, BodyFact, Confinement, 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, UpstreamRequestService, SealFact, SessionFact, Soul, StopFact, TellFact, TellDelivery, TellDeliveryInput, TellReceiptInput, TurnEndFact, TurnFact, TurnOutcome, TurnStartFact, } from "./facts.js";
9
10
  export type { ResumeCoordinate } from "../coordinate.js";
10
11
  export declare function readSoul(paths: AkumaPaths): Promise<Soul | null>;
11
12
  export declare function heartExists(paths: AkumaPaths): Promise<boolean>;
@@ -28,16 +29,6 @@ export declare function recordTell(paths: AkumaPaths, tell: Omit<TellFact, "sequ
28
29
  }>>;
29
30
  export declare function recordTellDeliveries(paths: AkumaPaths, inputs: readonly TellDeliveryInput[]): Promise<void>;
30
31
  export declare function recordTellReceipt(paths: AkumaPaths, input: TellReceiptInput): Promise<void>;
31
- export declare function admitRequest(paths: AkumaPaths, input: RequestInput & Readonly<{
32
- admittedAt: string;
33
- }>): Promise<RequestFact>;
34
- export declare function reserveRequest(paths: AkumaPaths, id: string, child: AkuId): Promise<RequestFact>;
35
- export declare function serveRequest(paths: AkumaPaths, id: string, child: AkuId): Promise<RequestFact>;
36
- export declare function serveUpstreamRequest(paths: AkumaPaths, id: string, service: UpstreamRequestService): Promise<RequestFact>;
37
- export declare function refuseRequest(paths: AkumaPaths, id: string, diagnostic: string): Promise<RequestFact>;
38
- export declare function voidRequest(paths: AkumaPaths, id: string, evidence: string): Promise<RequestFact>;
39
- export declare function readRequest(paths: AkumaPaths, id: string): Promise<RequestFact | null>;
40
- export declare function readNonterminalRequests(paths: AkumaPaths): Promise<readonly RequestFact[]>;
41
32
  export declare function readKill(paths: AkumaPaths, bodySequence: number): Promise<KillFact | null>;
42
33
  export declare function requestStop(paths: AkumaPaths, at: string): Promise<Readonly<{
43
34
  kind: "requested";