@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,6 +1,6 @@
1
1
  {
2
2
  "name": "keiyaku",
3
- "version": "0.1.0+codex.20260818034655",
3
+ "version": "0.1.0+codex.20260819155641",
4
4
  "description": "Use the Keiyaku contract, task, and Akuma CLI.",
5
5
  "author": { "name": "Keiyaku" },
6
6
  "skills": "./skills/"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keiyaku",
3
- "version": "0.1.0+codex.20260818034655",
3
+ "version": "0.1.0+codex.20260819155641",
4
4
  "description": "Use the Keiyaku contract, task, and Akuma CLI.",
5
5
  "author": {
6
6
  "name": "Keiyaku"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keiyaku-harness",
3
- "version": "0.1.0+codex.20260818034655",
3
+ "version": "0.1.0+codex.20260819155641",
4
4
  "type": "module",
5
5
  "main": "./opencode.js",
6
6
  "keywords": ["pi-package"],
@@ -15,9 +15,9 @@ read `<command> --help` before using flags.
15
15
  then `keiyaku-workflow` for the remaining lifecycle.
16
16
  - An Akuma is a callable worker; see `keiyaku-akuma`.
17
17
 
18
- Settings owns named gate sets. Omitting `--gates` selects `gates.default`, or
19
- freezes an empty gate list when that entry is absent. `--gates <name>` selects
20
- one configured set; it does not add a literal gate word.
18
+ Settings owns named gate bundles. Omitting `--gates` selects `gates.default`,
19
+ or freezes `["reviewed"]` when that entry is absent. `--gates <name,...>`
20
+ selects configured bundles in order; it does not add literal gate words.
21
21
 
22
22
  ## Quick Start
23
23
 
@@ -31,7 +31,7 @@ keiyaku -C <repo> review [<contract>|@<contract>] --satisfied
31
31
  ```
32
32
 
33
33
  ```bash
34
- keiyaku -C <cwd> call <akuma-name> [--contract <kei/...>] [--alias @name] [--allowed <product.action>]... [--wait <duration> | -d | --detach] [--json] (<prompt> | -)
34
+ keiyaku -C <cwd> call <akuma-name> [--contract <kei/...>] [--alias @name] [--readonly] [--allowed <product.action>]... [--wait <duration> | -d | --detach] (<prompt> | -)
35
35
  keiyaku -C <repo> wait <akuma-selector>... [--any | --all]
36
36
  keiyaku -C <repo> tell <aku/...|@alias> (<prompt> | -)
37
37
  ```
@@ -13,7 +13,7 @@ is accepted; the identity underneath never changes.
13
13
  ## Start One
14
14
 
15
15
  ```bash
16
- keiyaku -C <cwd> call <akuma-name> [--alias @name] [--allowed <product.action>]... [--wait <duration> | -d | --detach] [--json] (<prompt> | -)
16
+ keiyaku -C <cwd> call <akuma-name> [--alias @name] [--readonly] [--allowed <product.action>]... [--wait <duration> | -d | --detach] (<prompt> | -)
17
17
  ```
18
18
 
19
19
  Give the worker's initial prompt as one argument (quote it when it contains
@@ -44,14 +44,22 @@ outgrows its Archetype mid-life.
44
44
  keiyaku status # deep fleet observation
45
45
  keiyaku status <aku/...|@alias> # one worker's snapshot
46
46
  keiyaku ls aku/ # shallow catalog; also aku/<archetype>/ and "aku/*/*"
47
- keiyaku wait <selector>... [--any | --all] [--timeout <duration>] [--json]
47
+ keiyaku wait <selector>... [--any | --all] [--timeout <duration>]
48
48
  ```
49
49
 
50
- `wait` accepts complete ids, aliases, and Akuma globs, resolved once into a
51
- stable deduplicated set. One member needs no mode; two or more require exactly
52
- one of `--any` or `--all`. A timeout returns the current real snapshot — never
53
- a fabricated timeout state — and `--any` leaves the unfinished members
54
- running.
50
+ `wait` accepts complete ids, aliases, and Akuma globs. Wait on one Akuma without
51
+ a mode. When observing multiple Akuma, prefer one plural wait over separate
52
+ waits and choose exactly one mode:
53
+
54
+ ```bash
55
+ keiyaku -C <cwd> wait @worker-a --timeout 5m
56
+ keiyaku -C <cwd> wait @worker-a @worker-b --all --timeout 5m
57
+ keiyaku -C <cwd> wait @worker-a @worker-b --any --timeout 5m
58
+ ```
59
+
60
+ `--all` waits until every selected Akuma stops running. `--any` returns when the
61
+ first one stops and leaves the others alone. When the timeout expires, `wait`
62
+ returns their current status without stopping them.
55
63
 
56
64
  ## Steer
57
65
 
@@ -66,9 +66,11 @@ reader would otherwise re-derive wrongly. Never narrative. If Objective and
66
66
  Design read the same without a sentence here, delete it.>
67
67
 
68
68
  ## Objective
69
- <One observable end-state, judged done/not-done without reading Design.
70
- If "and" joins independently acceptable outcomes, bind two Contracts. A
71
- single outcome may still require several arcs during fulfillment.>
69
+ <One end-state you could watch happen, named at the level of intent and goal
70
+ — above implementation detail, above spec recital. If "and" joins two
71
+ outcomes that would each stand alone, bind two Contracts. Even an outcome
72
+ that cannot split into two may still need arcs to organize its
73
+ fulfillment.>
72
74
 
73
75
  ## Design
74
76
  <The closed decisions. A statement belongs here exactly when a test-green
@@ -85,7 +85,8 @@ Read first:
85
85
  - <owner documents governing this delivery>
86
86
  - <source files named or selected from the Contract Region for this work>
87
87
  Objective:
88
- <bounded assignment>
88
+ <the assignment's high-level intent and goal — not implementation detail,
89
+ not a restatement of the Contract terms>
89
90
  ```
90
91
 
91
92
  Every `Read first` path is relative to `Worktree` unless it is absolute. The
@@ -94,6 +95,12 @@ frontmatter names `Contract`, then reads the listed owner documents and source
94
95
  files before acting. Do not substitute a generic repository tour for the files
95
96
  that actually govern the assignment.
96
97
 
98
+ Contract association, available forwarded actions, and the brief are
99
+ independent inputs. When a Reviewer should record its own verdict, include
100
+ `--allowed contract.review` and say in the brief to record `--satisfied` on
101
+ pass or `--unsatisfied` on failure. When a Deliverer should tender its completed
102
+ candidate, include `--allowed contract.deliver` and say so in the brief.
103
+
97
104
  A `Deliverer` implements and verifies the terms in `Worktree`. Commission a
98
105
  `Reviewer` after delivery. The reviewer inspects the complete current Contract
99
106
  worktree snapshot, not a worker report or named candidate commit, and does not
@@ -182,14 +189,24 @@ substitute for them.
182
189
 
183
190
  ## Deliver
184
191
 
192
+ When the brief assigns delivery to the Deliverer, include `--allowed
193
+ contract.deliver`; require it to run the command below after verification and
194
+ return the receipt. Otherwise the coordinator runs it after accepting the
195
+ candidate.
196
+
185
197
  Deliver when the worktree content is the candidate you intend to land:
186
198
 
187
199
  ```bash
188
- keiyaku deliver <contract>
200
+ keiyaku deliver <contract> --include-dirty
189
201
  ```
190
202
 
191
- `deliver` freshly tenders the clean `HEAD`, records the candidate, and requests
192
- placement. When a current audit attestation names the identical integration
203
+ This example includes all non-ignored staged, unstaged, and untracked bytes in
204
+ the candidate. Use `--include-dirty` only when the complete current workspace
205
+ is the intended delivery; otherwise commit the intended bytes and run
206
+ `keiyaku deliver <contract>`.
207
+
208
+ `deliver` freshly tenders the candidate, records it, and requests placement.
209
+ When a current audit attestation names the identical integration
193
210
  snapshot and Verification segment, deliver reuses it; otherwise it runs the
194
211
  declarations. Worktree, target, policy, document, Verification, or
195
212
  snapshot-producing option changes prevent reuse. If the workspace is dirty, the refusal
@@ -217,6 +234,9 @@ keiyaku review <contract> --unsatisfied --summary "<finding>"
217
234
  ```
218
235
 
219
236
  Have an independent reviewer inspect the delivered Contract worktree snapshot.
237
+ If it should record the verdict itself, dispatch it with `--allowed
238
+ contract.review` and state both verdicts in the brief. Otherwise its answer is
239
+ review input for the coordinator to record.
220
240
  The `review` command records the verdict. `--satisfied` requests placement; if
221
241
  the other gates are current, the receipt shows `claimed`.
222
242
 
@@ -10,7 +10,7 @@ export type AkumaListRow = Readonly<{
10
10
  description?: string;
11
11
  life: AkumaLife;
12
12
  lifeAt: string | null;
13
- confinement: Soul["confinement"];
13
+ lastActivityAt: string | null;
14
14
  pending: readonly string[];
15
15
  }>;
16
16
  export type AkumaStatus = Readonly<{
@@ -47,6 +47,7 @@ export type AkumaCallInput = Readonly<{
47
47
  archetype: string;
48
48
  body: string;
49
49
  cwd?: string;
50
+ readonly?: true;
50
51
  allowed?: readonly AllowedAction[];
51
52
  }>;
52
53
  type AkumaCallContext = Readonly<{
@@ -24,6 +24,13 @@ async function canonicalBirthCwd(input) {
24
24
  throw new Error(`cwd is not an existing directory: ${input}`);
25
25
  }
26
26
  }
27
+ function callReadonly(value) {
28
+ if (value === undefined)
29
+ return {};
30
+ if (value !== true)
31
+ throw new TypeError("Akuma call readonly must be true");
32
+ return { readonly: true };
33
+ }
27
34
  const CALL_EXECUTION = Symbol("akuma-call-execution");
28
35
  const CALL_WITH_CONTEXT = Symbol("akuma-call-with-context");
29
36
  export class AkumaNotBornError extends Error {
@@ -107,7 +114,7 @@ async function bornListRow(paths, expected, snapshot) {
107
114
  ...(snapshot.soul.description === undefined ? {} : { description: snapshot.soul.description }),
108
115
  life: currentLife,
109
116
  lifeAt: lifeAt(currentLife, snapshot.latestBody, snapshot.latestKill, snapshot.soul.createdAt),
110
- confinement: snapshot.soul.confinement,
117
+ lastActivityAt: snapshot.lastActivityAt,
111
118
  pending: snapshot.pending.map((tell) => tell.id),
112
119
  };
113
120
  }
@@ -118,7 +125,7 @@ async function bornStatus(paths, expected, budget) {
118
125
  const current = await bornListRow(paths, expected, snapshot);
119
126
  const resumeUnsupported = current.life === "stranded"
120
127
  && snapshot.latestSession?.provider === snapshot.soul.provider.name
121
- && resolveProviderExecution(snapshot.soul.provider).adapter.resume === undefined;
128
+ && (await resolveProviderExecution(snapshot.soul.provider)).adapter.resume === undefined;
122
129
  const slice = await activitySlice(paths);
123
130
  return {
124
131
  id: current.id,
@@ -219,6 +226,15 @@ export class AkumaHandle {
219
226
  : "unavailable" };
220
227
  }
221
228
  const settledBody = (await readHeart(this.paths)).latestBody;
229
+ if (settledBody?.sequence === request.body.sequence && settledBody.hung !== undefined) {
230
+ try {
231
+ await leash.clearPause(this.paths);
232
+ }
233
+ finally {
234
+ leash.release();
235
+ }
236
+ return { kind: "unavailable", evidence: "hung" };
237
+ }
222
238
  if (settledBody?.sequence !== request.body.sequence || settledBody.end === undefined) {
223
239
  try {
224
240
  await leash.clearPause(this.paths);
@@ -254,7 +270,7 @@ export class AkumaHandle {
254
270
  throw new AkumaNotBornError(this.id);
255
271
  if (source.id !== this.id)
256
272
  throw new Error("Akuma soul does not match its coordinate");
257
- const adapter = resolveProviderExecution(source.provider).adapter;
273
+ const adapter = (await resolveProviderExecution(source.provider)).adapter;
258
274
  if (adapter.fork === undefined)
259
275
  return { kind: "provider-cannot-fork", provider: source.provider.name };
260
276
  const point = await readForkPoint(this.paths, input.at);
@@ -294,7 +310,6 @@ export class AkumaHandle {
294
310
  allowed: source.allowed,
295
311
  cwd: source.cwd,
296
312
  origin: { kind: "fork", parent: this.id, at: input.at },
297
- confinement: source.confinement,
298
313
  },
299
314
  birthSession,
300
315
  }),
@@ -377,10 +392,16 @@ export class Akuma {
377
392
  return await this[CALL_WITH_CONTEXT](input, { initiatorCwd: process.cwd() });
378
393
  }
379
394
  async [CALL_WITH_CONTEXT](input, context) {
395
+ const readonly = callReadonly(input.readonly);
380
396
  const name = archetypeName(input.archetype);
381
397
  const home = this.configuration.home === undefined ? {} : { home: this.configuration.home };
382
398
  const settings = this.configuration.settings ?? await readSettings({ root: this.path, ...home });
383
- const archetype = await loadArchetype({ name, ...home, settings });
399
+ const archetype = await loadArchetype({
400
+ name,
401
+ ...home,
402
+ settings,
403
+ ...readonly,
404
+ });
384
405
  const allowed = input.allowed === undefined
385
406
  ? archetype.allowed
386
407
  : decodeAllowedActions(input.allowed, "Akuma call allowed");
@@ -416,10 +437,7 @@ export class Akuma {
416
437
  const cwd = input.cwd !== undefined && context?.cwdCanonical === true
417
438
  ? input.cwd
418
439
  : await canonicalBirthCwd(selectedCwd);
419
- const recipe = Object.freeze({
420
- ...requestRecipe,
421
- confinement: archetype.adapter.confinement({ cwd, options: archetype.options }),
422
- });
440
+ const recipe = requestRecipe;
423
441
  const published = await publishAkuma({
424
442
  worldPath: this.path,
425
443
  archetype: archetype.name,
@@ -1,4 +1,4 @@
1
- export declare const ALLOWED_ACTIONS: readonly ["akuma.call", "akuma.kill", "akuma.tell", "contract.deliver", "task.add", "task.addDocument", "task.compose", "task.done", "task.drop", "task.hold", "task.resume", "task.start", "task.stop", "task.update"];
1
+ export declare const ALLOWED_ACTIONS: readonly ["akuma.call", "akuma.kill", "akuma.tell", "contract.deliver", "contract.review", "task.add", "task.addDocument", "task.compose", "task.done", "task.drop", "task.hold", "task.resume", "task.start", "task.stop", "task.update"];
2
2
  export type AllowedAction = (typeof ALLOWED_ACTIONS)[number];
3
3
  export type AllowedActions = readonly AllowedAction[];
4
4
  export declare function isAllowedAction(value: unknown): value is AllowedAction;
@@ -1,18 +1,11 @@
1
+ import { TASK_MUTATION_ACTIONS } from "../task/mutation.js";
1
2
  export const ALLOWED_ACTIONS = Object.freeze([
2
3
  "akuma.call",
3
4
  "akuma.kill",
4
5
  "akuma.tell",
5
6
  "contract.deliver",
6
- "task.add",
7
- "task.addDocument",
8
- "task.compose",
9
- "task.done",
10
- "task.drop",
11
- "task.hold",
12
- "task.resume",
13
- "task.start",
14
- "task.stop",
15
- "task.update",
7
+ "contract.review",
8
+ ...TASK_MUTATION_ACTIONS,
16
9
  ]);
17
10
  const ALLOWED_ACTION_SET = new Set(ALLOWED_ACTIONS);
18
11
  export function isAllowedAction(value) {
@@ -8,6 +8,7 @@ type DecodedArchetype = Readonly<{
8
8
  provider: string;
9
9
  description?: string;
10
10
  options: ProviderOptions;
11
+ readonly?: true;
11
12
  allowed: AllowedActions;
12
13
  }>;
13
14
  export type ArchetypeCatalogRow = Readonly<{
@@ -18,7 +19,7 @@ export type ArchetypeCatalogRow = Readonly<{
18
19
  type ArchetypeDefinition = DecodedArchetype & Readonly<{
19
20
  adapter: ProviderAdapter;
20
21
  }>;
21
- type AdmittedArchetype = Omit<ArchetypeDefinition, "provider"> & Readonly<{
22
+ type AdmittedArchetype = Omit<ArchetypeDefinition, "provider" | "readonly"> & Readonly<{
22
23
  provider: ProviderExecution;
23
24
  readonly?: ReadonlyRestraint;
24
25
  }>;
@@ -39,5 +40,6 @@ export declare function loadArchetype(input: Readonly<{
39
40
  name: string;
40
41
  home?: string;
41
42
  settings: Settings;
43
+ readonly?: true;
42
44
  }>): Promise<AdmittedArchetype>;
43
45
  export {};
@@ -105,10 +105,10 @@ function decodeArchetype(name, path, markdown) {
105
105
  options: decodeProviderOptions({
106
106
  ...(model === undefined ? {} : { model }),
107
107
  ...(effort === undefined ? {} : { effort }),
108
- ...(readonly === undefined ? {} : { readonly }),
109
108
  ...(network === undefined ? {} : { network }),
110
109
  ...(systemPrompt.length === 0 ? {} : { systemPrompt }),
111
110
  }),
111
+ ...(readonly === undefined ? {} : { readonly }),
112
112
  allowed,
113
113
  });
114
114
  }
@@ -184,10 +184,10 @@ function providerExecution(settings, name) {
184
184
  return decodeProviderRecipe({ name, ...builtin });
185
185
  throw new TypeError(`unknown provider ${name}`);
186
186
  }
187
- function admitArchetype(archetype, settings) {
187
+ async function admitArchetype(archetype, settings, callReadonly) {
188
188
  let selected;
189
189
  try {
190
- selected = resolveProviderExecution(providerExecution(settings, archetype.provider));
190
+ selected = await resolveProviderExecution(providerExecution(settings, archetype.provider));
191
191
  }
192
192
  catch (error) {
193
193
  if (error instanceof TypeError)
@@ -196,12 +196,17 @@ function admitArchetype(archetype, settings) {
196
196
  }
197
197
  const execution = selected.execution;
198
198
  const adapter = selected.adapter;
199
- const admission = adapter.admitOptions(archetype.options);
199
+ const effectiveReadonly = archetype.readonly === true || callReadonly === true;
200
+ const admission = adapter.admitOptions({
201
+ ...archetype.options,
202
+ ...(effectiveReadonly ? { readonly: true } : {}),
203
+ });
200
204
  if (admission.kind === "refused") {
201
205
  throw new AkumaArchetypeError(archetype.name, [archetype.path], `is unsupported: ${admission.diagnostic}`);
202
206
  }
207
+ const { readonly: _readonly, ...definition } = archetype;
203
208
  return Object.freeze({
204
- ...archetype,
209
+ ...definition,
205
210
  provider: execution,
206
211
  adapter,
207
212
  options: admission.options,
@@ -223,7 +228,7 @@ export async function loadArchetype(input) {
223
228
  throw new AkumaArchetypeError(name, [path], `could not be read: ${error instanceof Error ? error.message : String(error)}`);
224
229
  }
225
230
  try {
226
- return admitArchetype(decodeArchetype(name, path, markdown), input.settings);
231
+ return await admitArchetype(decodeArchetype(name, path, markdown), input.settings, input.readonly);
227
232
  }
228
233
  catch (error) {
229
234
  if (error instanceof AkumaArchetypeError)
@@ -0,0 +1,64 @@
1
+ import { type HeartSnapshot, type HeldAkumaLeash, type ResumeCoordinate, type Soul, type TellFact } from "./heart/index.js";
2
+ import type { AkumaPaths } from "./identity.js";
3
+ import { type ProviderAdapter, type TurnResult } from "./provider.js";
4
+ import { type RequestChildLaunch, type UpstreamExecutionPort } from "./request-serve.js";
5
+ export declare const CONTROL_RESPONSE_MS = 1000;
6
+ export declare class BodySupervisor {
7
+ private readonly paths;
8
+ private readonly bodySequence;
9
+ private readonly leash;
10
+ readonly signal: AbortSignal;
11
+ private readonly controller;
12
+ private readonly finished;
13
+ private readonly observer;
14
+ private waiter;
15
+ private observation;
16
+ private stopping?;
17
+ private constructor();
18
+ static open(paths: AkumaPaths, bodySequence: number, leash: HeldAkumaLeash): Promise<BodySupervisor>;
19
+ get reason(): "control" | "heart-gone" | undefined;
20
+ current(): HeartSnapshot;
21
+ recordHung(diagnostic: string, at: string): Promise<void>;
22
+ refresh(): Promise<HeartSnapshot>;
23
+ next(after: HeartSnapshot): Promise<HeartSnapshot>;
24
+ cancel(reason: "control" | "heart-gone"): void;
25
+ close(): Promise<void>;
26
+ private publish;
27
+ private observe;
28
+ }
29
+ export declare function turnRecipe(paths: AkumaPaths, soul: Soul): Promise<Readonly<{
30
+ cwd: string;
31
+ options: Soul["options"];
32
+ session?: ResumeCoordinate;
33
+ }>>;
34
+ export type DrivenTurn = (Extract<TurnResult, {
35
+ kind: "answered";
36
+ }> & Readonly<{
37
+ session?: ResumeCoordinate;
38
+ }>) | Extract<TurnResult, {
39
+ kind: "failed";
40
+ }>;
41
+ export type DriveTurnInput = Readonly<{
42
+ paths: AkumaPaths;
43
+ soul: Soul;
44
+ adapter: ProviderAdapter;
45
+ bodySequence: number;
46
+ body: string;
47
+ call?: string;
48
+ launchTells: readonly TellFact[];
49
+ supervisor: BodySupervisor;
50
+ runtimeSpawn(launch: RequestChildLaunch): Promise<void>;
51
+ upstream?: UpstreamExecutionPort;
52
+ now(): string;
53
+ }>;
54
+ export declare function driveTurn(input: DriveTurnInput): Promise<(DrivenTurn & Readonly<{
55
+ turnSequence: number;
56
+ }>) | Readonly<{
57
+ kind: "stopped";
58
+ }> | Readonly<{
59
+ kind: "hung";
60
+ }> | Readonly<{
61
+ kind: "handoff";
62
+ }> | Readonly<{
63
+ kind: "resume-unsupported";
64
+ }>>;