@astrosheep/keiyaku 4.1.0 → 4.1.2

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 (278) hide show
  1. package/README.md +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -0
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +3 -0
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -6
  5. package/build/src/akuma/akuma-errors.d.ts +6 -0
  6. package/build/src/akuma/akuma-errors.js +9 -0
  7. package/build/src/akuma/akuma-handle.d.ts +39 -0
  8. package/build/src/akuma/akuma-handle.js +263 -0
  9. package/build/src/akuma/akuma-observe.d.ts +19 -0
  10. package/build/src/akuma/akuma-observe.js +74 -0
  11. package/build/src/akuma/akuma-product-symbols.d.ts +1 -0
  12. package/build/src/akuma/akuma-product-symbols.js +1 -0
  13. package/build/src/akuma/akuma-product.d.ts +18 -0
  14. package/build/src/akuma/akuma-product.js +154 -0
  15. package/build/src/akuma/akuma.d.ts +37 -81
  16. package/build/src/akuma/akuma.js +39 -447
  17. package/build/src/akuma/allowed.d.ts +1 -0
  18. package/build/src/akuma/allowed.js +6 -0
  19. package/build/src/akuma/archetype.js +8 -5
  20. package/build/src/akuma/body-supervisor.d.ts +26 -0
  21. package/build/src/akuma/body-supervisor.js +89 -0
  22. package/build/src/akuma/body.d.ts +45 -4
  23. package/build/src/akuma/body.js +145 -35
  24. package/build/src/akuma/coordinate.js +17 -7
  25. package/build/src/akuma/heart/facts.js +1 -1
  26. package/build/src/akuma/heart/index.d.ts +1 -1
  27. package/build/src/akuma/heart/index.js +2 -4
  28. package/build/src/akuma/heart/request-authority.js +4 -4
  29. package/build/src/akuma/heart/request-rows.js +27 -16
  30. package/build/src/akuma/heart/rows.js +79 -41
  31. package/build/src/akuma/heart/soul.js +1 -1
  32. package/build/src/akuma/heart/storage.d.ts +1 -0
  33. package/build/src/akuma/heart/storage.js +76 -11
  34. package/build/src/akuma/heart/tells.js +35 -18
  35. package/build/src/akuma/heart/timeline.js +19 -11
  36. package/build/src/akuma/identity.d.ts +1 -0
  37. package/build/src/akuma/identity.js +1 -0
  38. package/build/src/akuma/index.d.ts +3 -3
  39. package/build/src/akuma/index.js +1 -1
  40. package/build/src/akuma/nuke.js +106 -14
  41. package/build/src/akuma/projection-read.d.ts +17 -0
  42. package/build/src/akuma/projection-read.js +135 -0
  43. package/build/src/akuma/projection.d.ts +1 -16
  44. package/build/src/akuma/projection.js +77 -154
  45. package/build/src/akuma/provider-recipe.js +11 -5
  46. package/build/src/akuma/provider.js +105 -62
  47. package/build/src/akuma/providers/acp/config.js +5 -6
  48. package/build/src/akuma/providers/acp/core.js +17 -10
  49. package/build/src/akuma/providers/acp/events.js +38 -29
  50. package/build/src/akuma/providers/acp/index.js +13 -9
  51. package/build/src/akuma/providers/claude/events.js +8 -12
  52. package/build/src/akuma/providers/claude/index.d.ts +1 -0
  53. package/build/src/akuma/providers/claude/index.js +55 -26
  54. package/build/src/akuma/providers/claude/input.js +6 -2
  55. package/build/src/akuma/providers/codex-app-server/events.js +61 -36
  56. package/build/src/akuma/providers/codex-app-server/index.js +25 -13
  57. package/build/src/akuma/providers/grok-build/index.js +22 -25
  58. package/build/src/akuma/providers/index.js +2 -18
  59. package/build/src/akuma/providers/opencode-sdk/events.js +32 -18
  60. package/build/src/akuma/providers/opencode-sdk/index.js +26 -17
  61. package/build/src/akuma/providers/opencode-sdk/session.js +21 -5
  62. package/build/src/akuma/providers/pi/events.js +26 -19
  63. package/build/src/akuma/providers/pi/index.js +58 -40
  64. package/build/src/akuma/publication.js +9 -9
  65. package/build/src/akuma/request-execution.d.ts +6 -0
  66. package/build/src/akuma/request-execution.js +86 -0
  67. package/build/src/akuma/request-serve.d.ts +12 -1
  68. package/build/src/akuma/request-serve.js +19 -122
  69. package/build/src/akuma/request-wire.d.ts +2 -2
  70. package/build/src/akuma/request-wire.js +75 -102
  71. package/build/src/akuma/requests.js +2 -2
  72. package/build/src/akuma/{body-turn.d.ts → turn-drive.d.ts} +2 -25
  73. package/build/src/akuma/{body-turn.js → turn-drive.js} +20 -103
  74. package/build/src/akuma-body.js +6 -5
  75. package/build/src/body/amend.d.ts +4 -1
  76. package/build/src/body/amend.js +14 -6
  77. package/build/src/body/decode.js +2 -4
  78. package/build/src/body/envelope.js +2 -4
  79. package/build/src/body/region.d.ts +1 -2
  80. package/build/src/body/region.js +2 -70
  81. package/build/src/body/render.js +17 -12
  82. package/build/src/body/shape.js +1 -7
  83. package/build/src/cli/accepted.d.ts +1 -1
  84. package/build/src/cli/accepted.js +8 -1
  85. package/build/src/cli/commands/akuma-invoke.js +18 -6
  86. package/build/src/cli/commands/akuma.d.ts +0 -6
  87. package/build/src/cli/commands/akuma.js +11 -24
  88. package/build/src/cli/commands/amend.d.ts +2 -2
  89. package/build/src/cli/commands/amend.js +2 -4
  90. package/build/src/cli/commands/bind.d.ts +4 -4
  91. package/build/src/cli/commands/bind.js +16 -6
  92. package/build/src/cli/commands/contract-invoke.d.ts +25 -0
  93. package/build/src/cli/commands/contract-invoke.js +193 -0
  94. package/build/src/cli/commands/contract.d.ts +109 -10
  95. package/build/src/cli/commands/contract.js +339 -16
  96. package/build/src/cli/commands/install.d.ts +1 -1
  97. package/build/src/cli/commands/install.js +23 -15
  98. package/build/src/cli/commands/task-invoke.js +187 -67
  99. package/build/src/cli/commands/task-query.js +48 -24
  100. package/build/src/cli/commands/task.js +150 -38
  101. package/build/src/cli/coordinates.js +2 -4
  102. package/build/src/cli/invoke.js +92 -208
  103. package/build/src/cli/main.js +4 -2
  104. package/build/src/cli/parse.d.ts +3 -90
  105. package/build/src/cli/parse.js +27 -233
  106. package/build/src/cli/render/akuma-activity.d.ts +38 -0
  107. package/build/src/cli/render/akuma-activity.js +362 -0
  108. package/build/src/cli/render/akuma-tool-command.js +6 -7
  109. package/build/src/cli/render/akuma-tool.js +10 -8
  110. package/build/src/cli/render/akuma.d.ts +1 -1
  111. package/build/src/cli/render/akuma.js +61 -353
  112. package/build/src/cli/render/audit.js +5 -15
  113. package/build/src/cli/render/board.d.ts +1 -0
  114. package/build/src/cli/render/board.js +17 -0
  115. package/build/src/cli/render/catalog.js +81 -8
  116. package/build/src/cli/render/contract-history.d.ts +2 -0
  117. package/build/src/cli/render/contract-history.js +83 -0
  118. package/build/src/cli/render/contract-observation.d.ts +10 -0
  119. package/build/src/cli/render/contract-observation.js +58 -0
  120. package/build/src/cli/render/contract.d.ts +1 -2
  121. package/build/src/cli/render/contract.js +41 -142
  122. package/build/src/cli/render/kanshi.js +239 -215
  123. package/build/src/cli/render/receipt.js +2 -9
  124. package/build/src/cli/render/refusal.js +10 -15
  125. package/build/src/cli/render/region.js +22 -6
  126. package/build/src/cli/render/settings.js +4 -4
  127. package/build/src/cli/render/task.js +34 -14
  128. package/build/src/cli/render/terminal.js +16 -5
  129. package/build/src/cli/result.d.ts +3 -3
  130. package/build/src/cli/runtime.d.ts +6 -1
  131. package/build/src/cli/runtime.js +84 -63
  132. package/build/src/cli/selectors.js +2 -4
  133. package/build/src/cli/usage.js +6 -5
  134. package/build/src/contract-worktree.d.ts +1 -23
  135. package/build/src/contract-worktree.js +79 -155
  136. package/build/src/coordination/durable-file.js +7 -3
  137. package/build/src/coordination/sqlite-transaction-lock.js +29 -12
  138. package/build/src/core/facts/codec.js +7 -3
  139. package/build/src/core/facts/types.d.ts +1 -1
  140. package/build/src/core/subject.js +16 -9
  141. package/build/src/core/verbs/abandon.d.ts +1 -1
  142. package/build/src/core/verbs/abandon.js +1 -1
  143. package/build/src/core/verbs/amend.d.ts +1 -1
  144. package/build/src/core/verbs/amend.js +7 -7
  145. package/build/src/core/verbs/attestation.js +4 -1
  146. package/build/src/core/verbs/bind.d.ts +1 -1
  147. package/build/src/core/verbs/bind.js +1 -1
  148. package/build/src/core/verbs/placement.d.ts +1 -1
  149. package/build/src/core/verbs/placement.js +10 -8
  150. package/build/src/dispatch/index.js +8 -6
  151. package/build/src/duration.js +5 -1
  152. package/build/src/git/admission.js +5 -3
  153. package/build/src/git/hooks.d.ts +8 -0
  154. package/build/src/git/hooks.js +63 -14
  155. package/build/src/git/identity.js +1 -4
  156. package/build/src/git/integration.d.ts +2 -3
  157. package/build/src/git/integration.js +32 -39
  158. package/build/src/git/nuke.d.ts +1 -1
  159. package/build/src/git/nuke.js +110 -57
  160. package/build/src/git/observe.d.ts +13 -1
  161. package/build/src/git/observe.js +51 -44
  162. package/build/src/git/process.js +4 -2
  163. package/build/src/git/read-observation.js +10 -8
  164. package/build/src/git/reconcile.d.ts +22 -2
  165. package/build/src/git/reconcile.js +38 -274
  166. package/build/src/git/repository.d.ts +2 -0
  167. package/build/src/git/repository.js +13 -22
  168. package/build/src/git/scratch.d.ts +8 -5
  169. package/build/src/git/scratch.js +29 -2
  170. package/build/src/git/target-placement.d.ts +9 -10
  171. package/build/src/git/target-placement.js +59 -62
  172. package/build/src/git/tender.js +13 -46
  173. package/build/src/git/terminal-reconcile.d.ts +21 -0
  174. package/build/src/git/terminal-reconcile.js +278 -0
  175. package/build/src/git/terminal-seal.js +15 -12
  176. package/build/src/git/tree.js +5 -2
  177. package/build/src/git/workspace.d.ts +24 -2
  178. package/build/src/git/workspace.js +120 -16
  179. package/build/src/identity/coordinates.js +3 -1
  180. package/build/src/identity/selector.js +6 -3
  181. package/build/src/kanshi/fleet.d.ts +6 -0
  182. package/build/src/kanshi/fleet.js +27 -0
  183. package/build/src/kanshi/index.d.ts +1 -1
  184. package/build/src/kanshi/read.js +60 -48
  185. package/build/src/kanshi/report.d.ts +11 -23
  186. package/build/src/kanshi/select.js +25 -24
  187. package/build/src/library/address.d.ts +2 -1
  188. package/build/src/library/address.js +7 -8
  189. package/build/src/library/akuma-creation.js +20 -12
  190. package/build/src/library/audit.d.ts +0 -1
  191. package/build/src/library/audit.js +1 -2
  192. package/build/src/library/bind.d.ts +53 -5
  193. package/build/src/library/bind.js +98 -22
  194. package/build/src/library/catalog.d.ts +1 -0
  195. package/build/src/library/catalog.js +6 -3
  196. package/build/src/library/configuration.js +3 -1
  197. package/build/src/library/continuation.d.ts +15 -4
  198. package/build/src/library/continuation.js +24 -16
  199. package/build/src/library/contract-bind.d.ts +26 -0
  200. package/build/src/library/contract-bind.js +106 -0
  201. package/build/src/library/contract-operations.d.ts +77 -0
  202. package/build/src/library/contract-operations.js +130 -0
  203. package/build/src/library/contract-types.d.ts +95 -0
  204. package/build/src/library/contract-types.js +1 -0
  205. package/build/src/library/contract.d.ts +19 -154
  206. package/build/src/library/contract.js +46 -261
  207. package/build/src/library/fleet.d.ts +1 -1
  208. package/build/src/library/fleet.js +19 -11
  209. package/build/src/library/input.d.ts +2 -0
  210. package/build/src/library/input.js +14 -0
  211. package/build/src/library/keiyaku.d.ts +8 -7
  212. package/build/src/library/keiyaku.js +3 -3
  213. package/build/src/library/nuke.js +14 -5
  214. package/build/src/library/reconcile.d.ts +9 -4
  215. package/build/src/library/reconcile.js +30 -24
  216. package/build/src/library/refusal.d.ts +13 -5
  217. package/build/src/library/refusal.js +7 -0
  218. package/build/src/library/region.d.ts +8 -7
  219. package/build/src/library/region.js +31 -11
  220. package/build/src/library/repo.js +2 -2
  221. package/build/src/markdown/lex.js +9 -2
  222. package/build/src/markdown/parse.js +11 -7
  223. package/build/src/markdown/query.js +4 -2
  224. package/build/src/protocol/amend.js +3 -1
  225. package/build/src/protocol/attempt.d.ts +7 -3
  226. package/build/src/protocol/attempt.js +9 -5
  227. package/build/src/protocol/audit.d.ts +1 -1
  228. package/build/src/protocol/audit.js +4 -14
  229. package/build/src/protocol/bind.d.ts +19 -6
  230. package/build/src/protocol/bind.js +28 -13
  231. package/build/src/protocol/completion.d.ts +0 -1
  232. package/build/src/protocol/completion.js +1 -3
  233. package/build/src/protocol/deliver.d.ts +1 -3
  234. package/build/src/protocol/deliver.js +15 -39
  235. package/build/src/protocol/intent.d.ts +1 -0
  236. package/build/src/protocol/intent.js +9 -7
  237. package/build/src/protocol/operations.d.ts +3 -7
  238. package/build/src/protocol/operations.js +5 -3
  239. package/build/src/protocol/placement.d.ts +0 -1
  240. package/build/src/protocol/placement.js +6 -6
  241. package/build/src/protocol/read/observation.d.ts +11 -0
  242. package/build/src/protocol/read/observation.js +37 -0
  243. package/build/src/protocol/read/status.d.ts +23 -12
  244. package/build/src/protocol/read/status.js +90 -72
  245. package/build/src/protocol/reconcile.d.ts +1 -0
  246. package/build/src/protocol/reconcile.js +2 -3
  247. package/build/src/protocol/reintegrate.js +1 -1
  248. package/build/src/protocol/review.d.ts +0 -1
  249. package/build/src/protocol/review.js +15 -22
  250. package/build/src/protocol/run.d.ts +1 -0
  251. package/build/src/protocol/run.js +4 -5
  252. package/build/src/runtime/proc/launch.d.ts +33 -0
  253. package/build/src/runtime/proc/launch.js +98 -0
  254. package/build/src/runtime/proc/line-rpc.js +9 -3
  255. package/build/src/runtime/proc/run.d.ts +12 -6
  256. package/build/src/runtime/proc/run.js +78 -21
  257. package/build/src/runtime/proc/stdio.js +7 -10
  258. package/build/src/settings.js +6 -2
  259. package/build/src/settlement/holder.js +13 -10
  260. package/build/src/settlement/settle.js +39 -6
  261. package/build/src/task/board.js +12 -6
  262. package/build/src/task/compose.js +85 -22
  263. package/build/src/task/context.js +21 -8
  264. package/build/src/task/document.js +46 -10
  265. package/build/src/task/identity.js +5 -2
  266. package/build/src/task/index.d.ts +0 -1
  267. package/build/src/task/index.js +119 -34
  268. package/build/src/task/input.js +29 -7
  269. package/build/src/task/mutation.js +61 -19
  270. package/build/src/task/operations.d.ts +6 -1
  271. package/build/src/task/operations.js +83 -29
  272. package/build/src/task/query.js +55 -26
  273. package/build/src/task/store.d.ts +3 -1
  274. package/build/src/task/store.js +81 -17
  275. package/build/src/verification/execution.js +14 -11
  276. package/build/src/workspace-place.js +19 -7
  277. package/build/src/world.js +16 -6
  278. package/package.json +8 -3
@@ -3,7 +3,7 @@ import { reconcileAllOperation, reconcileOperation, worldContractStates, } from
3
3
  import { reconcileObservationFailure } from "../git/reconcile.js";
4
4
  import { stateOperation } from "../protocol/operations.js";
5
5
  import { settle, settleAll } from "../settlement/settle.js";
6
- import { projectContractWorktree, } from "../contract-worktree.js";
6
+ import { projectContractWorktree } from "../contract-worktree.js";
7
7
  import { appointManagedWorktrees, placeRegisterPath, releaseManagedWorktrees, } from "../workspace-place.js";
8
8
  function registerLag(scope, error) {
9
9
  return {
@@ -13,9 +13,6 @@ function registerLag(scope, error) {
13
13
  diagnostic: error instanceof Error ? error.message : String(error),
14
14
  };
15
15
  }
16
- function hereConflict(diagnostic) {
17
- throw new AuthorityCorruptionError(diagnostic);
18
- }
19
16
  function emptySettlement() {
20
17
  return { actions: [], lags: [] };
21
18
  }
@@ -26,18 +23,13 @@ function isManagedTerminal(state) {
26
23
  return state !== null && isManagedWorktree(state) && state.terminal !== null;
27
24
  }
28
25
  function appointableManagedContracts(states) {
29
- return states
30
- .filter((state) => isManagedWorktree(state) && state.terminal === null)
31
- .map((state) => state.id);
26
+ return states.filter((state) => isManagedWorktree(state) && state.terminal === null).map((state) => state.id);
32
27
  }
33
28
  async function appointPlaces(scope, states) {
34
29
  return await appointManagedWorktrees(scope, appointableManagedContracts(states));
35
30
  }
36
31
  function releaseEligible(state, cleanup, appointed) {
37
- return cleanup !== undefined
38
- && cleanup.lag.length === 0
39
- && isManagedTerminal(state)
40
- && appointed;
32
+ return cleanup !== undefined && cleanup.lag.length === 0 && isManagedTerminal(state) && appointed;
41
33
  }
42
34
  async function releaseAppointments(scope, contracts) {
43
35
  try {
@@ -94,35 +86,50 @@ export async function completeReconcile(input) {
94
86
  retainTerminalWorktree: true,
95
87
  ...appointed,
96
88
  });
97
- const projection = await projectContractWorktree(input.scope, retained.state, appointment.register, hereConflict);
89
+ const projection = await projectContractWorktree(input.scope, retained.state, appointment.register);
98
90
  const settlement = await settle({
99
91
  repository: input.scope,
100
92
  channel: input.channel,
101
93
  state: retained.state,
102
94
  effects: retained.report.effects,
103
95
  });
104
- const cleanup = isManagedTerminal(retained.state)
105
- ? await reconcileOperation({ ...input, ...appointed })
106
- : null;
96
+ const cleanup = isManagedTerminal(retained.state) ? await reconcileOperation({ ...input, ...appointed }) : null;
107
97
  const release = releaseEligible(retained.state, cleanup?.report, appointment.place !== undefined)
108
98
  ? await releaseAppointments(input.scope, [input.contractId])
109
99
  : undefined;
110
100
  return {
111
101
  effects: [...retained.report.effects, ...projection.effects, ...(cleanup?.report.effects ?? [])],
112
- lag: [...retained.report.lag, ...projection.lag, ...(cleanup?.report.lag ?? []), ...(release === undefined ? [] : [release])],
102
+ lag: [
103
+ ...retained.report.lag,
104
+ ...projection.lag,
105
+ ...(cleanup?.report.lag ?? []),
106
+ ...(release === undefined ? [] : [release]),
107
+ ],
113
108
  settlement,
114
109
  };
115
110
  }
116
111
  function attachReleaseLag(contracts, released, lag) {
117
112
  const affected = new Set(released);
118
113
  return {
114
+ kind: "completed",
119
115
  contracts: contracts.map((contract) => affected.has(contract.contractId)
120
116
  ? { ...contract, report: { ...contract.report, lag: [...contract.report.lag, lag] } }
121
117
  : contract),
122
118
  };
123
119
  }
120
+ function worldObservationDiagnostic(error) {
121
+ return (error instanceof Error ? error.message : String(error)).trim();
122
+ }
124
123
  export async function completeRepoReconcile(input) {
125
- const states = await worldContractStates(input);
124
+ let states;
125
+ try {
126
+ states = await worldContractStates(input);
127
+ }
128
+ catch (error) {
129
+ if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
130
+ throw error;
131
+ return { kind: "world-observation-failed", diagnostic: worldObservationDiagnostic(error) };
132
+ }
126
133
  let appointed;
127
134
  try {
128
135
  appointed = await appointPlaces(input.scope, states);
@@ -140,11 +147,12 @@ export async function completeRepoReconcile(input) {
140
147
  : await completeReconcile({ ...input, contractId: state.id }),
141
148
  });
142
149
  }
143
- return { contracts };
150
+ return { kind: "completed", contracts };
144
151
  }
145
152
  const places = new Map(appointed.appointments.map((appointment) => [appointment.contract, appointment.place]));
146
153
  const retained = await reconcileAllOperation({
147
154
  ...input,
155
+ states,
148
156
  retainTerminalWorktree: true,
149
157
  places,
150
158
  });
@@ -157,11 +165,9 @@ export async function completeRepoReconcile(input) {
157
165
  })),
158
166
  });
159
167
  const cleanup = retained.contracts.some((contract) => isManagedTerminal(contract.state))
160
- ? await reconcileAllOperation({ ...input, places })
168
+ ? await reconcileAllOperation({ ...input, states, places })
161
169
  : null;
162
- const later = cleanup === null
163
- ? null
164
- : new Map(cleanup.contracts.map((contract) => [contract.contractId, contract.report]));
170
+ const later = cleanup === null ? null : new Map(cleanup.contracts.map((contract) => [contract.contractId, contract.report]));
165
171
  const released = [];
166
172
  const contracts = [];
167
173
  for (const [index, contract] of retained.contracts.entries()) {
@@ -169,7 +175,7 @@ export async function completeRepoReconcile(input) {
169
175
  if (releaseEligible(contract.state, report, places.has(contract.contractId))) {
170
176
  released.push(contract.contractId);
171
177
  }
172
- const projection = await projectContractWorktree(input.scope, contract.state, appointed, hereConflict);
178
+ const projection = await projectContractWorktree(input.scope, contract.state, appointed);
173
179
  contracts.push({
174
180
  contractId: contract.contractId,
175
181
  report: {
@@ -180,5 +186,5 @@ export async function completeRepoReconcile(input) {
180
186
  });
181
187
  }
182
188
  const lag = await releaseAppointments(input.scope, released);
183
- return lag === undefined ? { contracts } : attachReleaseLag(contracts, released, lag);
189
+ return lag === undefined ? { kind: "completed", contracts } : attachReleaseLag(contracts, released, lag);
184
190
  }
@@ -1,10 +1,9 @@
1
1
  import type { ContractId } from "../core/facts/types.js";
2
2
  import type { IntentOutcome, IntentRefusal, IntentRetry } from "../protocol/operations.js";
3
3
  import type { AcceptedIntent } from "./mutation.js";
4
- export type ContractAppointmentRefusal = Readonly<{
5
- kind: "here-worktree-appointed";
6
- path: string;
7
- contract?: ContractId;
4
+ export type ForkSourceRefusal = Readonly<{
5
+ kind: "fork-source-missing" | "fork-source-unavailable" | "fork-source-invalid" | "fork-source-moved";
6
+ contractId: ContractId;
8
7
  }>;
9
8
  export type NukeConfirmationRefusal = Readonly<{
10
9
  kind: "nuke-confirmation-mismatch";
@@ -15,7 +14,7 @@ export type NukeConfirmationRequiredRefusal = Readonly<{
15
14
  kind: "nuke-confirmation-required";
16
15
  world: string;
17
16
  }>;
18
- export type KeiyakuRefusal = IntentRefusal | ContractAppointmentRefusal | NukeConfirmationRefusal | NukeConfirmationRequiredRefusal;
17
+ export type KeiyakuRefusal = IntentRefusal | ForkSourceRefusal | NukeConfirmationRefusal | NukeConfirmationRequiredRefusal;
19
18
  export type KeiyakuRetryReason = IntentRetry;
20
19
  export declare class KeiyakuRefused extends Error {
21
20
  readonly refusal: KeiyakuRefusal;
@@ -28,3 +27,12 @@ export declare class KeiyakuRetry extends Error {
28
27
  get code(): KeiyakuRetryReason["kind"];
29
28
  }
30
29
  export declare function requireAccepted<Value, Refusal extends KeiyakuRefusal>(result: IntentOutcome<Value, Refusal>): AcceptedIntent<Value>;
30
+ export declare function forwardedMutationFailure(error: unknown): Readonly<{
31
+ result: Readonly<{
32
+ kind: "refused";
33
+ refusal: KeiyakuRefusal;
34
+ } | {
35
+ kind: "retry";
36
+ reason: KeiyakuRetryReason;
37
+ }>;
38
+ }>;
@@ -27,3 +27,10 @@ export function requireAccepted(result) {
27
27
  throw new KeiyakuRetry(result.reason);
28
28
  return result;
29
29
  }
30
+ export function forwardedMutationFailure(error) {
31
+ if (error instanceof KeiyakuRefused)
32
+ return { result: { kind: "refused", refusal: error.refusal } };
33
+ if (error instanceof KeiyakuRetry)
34
+ return { result: { kind: "retry", reason: error.reason } };
35
+ throw error;
36
+ }
@@ -1,5 +1,5 @@
1
1
  import type { ContractId } from "../core/facts/types.js";
2
- import type { GitDecodeChannel } from "../git/read-observation.js";
2
+ import { type GitDecodeChannel } from "../git/read-observation.js";
3
3
  import { type RepositoryScope } from "../protocol/operations.js";
4
4
  import type { ContractDocumentProjection } from "../protocol/read/documents.js";
5
5
  export type RegionOverlap = Readonly<{
@@ -16,15 +16,16 @@ export type RegionObservation = Readonly<{
16
16
  overlapFailure: string;
17
17
  overlaps?: never;
18
18
  }>;
19
+ export type AmendRegionObservation = RegionObservation | Readonly<{
20
+ overlaps?: never;
21
+ overlapFailure?: never;
22
+ }>;
19
23
  export type RegionDeclarationRead = Readonly<{
20
24
  contract: ContractId;
21
25
  patterns: readonly string[];
22
26
  }>;
23
27
  export declare function readRegionDeclarations(documents: readonly ContractDocumentProjection[]): readonly RegionDeclarationRead[];
24
- export declare function regionIntersections(left: readonly string[], right: readonly string[]): readonly Readonly<{
25
- left: string;
26
- right: string;
27
- }>[];
28
- export declare function regionPathMatches(patterns: readonly string[], path: string): readonly string[];
29
- export declare function validateRegionPath(path: unknown): asserts path is string;
28
+ export declare function regionOverlaps(mine: readonly string[], declarations: readonly RegionDeclarationRead[]): readonly RegionOverlap[];
29
+ export declare function validateRegionPatterns(patterns: unknown): readonly [string, ...string[]];
30
30
  export declare function observeRegion(scope: RepositoryScope, channel: GitDecodeChannel, self: ContractId, mine: readonly string[]): Promise<RegionObservation>;
31
+ export declare function observeChangedRegion(scope: RepositoryScope, self: ContractId, changed: ReadonlySet<string> | undefined, mine: readonly string[]): Promise<AmendRegionObservation>;
@@ -1,19 +1,34 @@
1
1
  import { decodeContractDocument } from "../body/decode.js";
2
- import { assertCanonicalRegionPath, regionPatternsMatchPath, regionsOverlap } from "../body/region.js";
2
+ import { assertRegionPattern, regionsOverlap } from "../body/region.js";
3
+ import { withGitDecodeChannel } from "../git/read-observation.js";
3
4
  import { documentsOperationAt } from "../protocol/operations.js";
4
5
  export function readRegionDeclarations(documents) {
5
- return documents.map((document) => ({ contract: document.contract, patterns: decodeContractDocument(document.documentBytes).region }));
6
+ return documents.map((document) => ({
7
+ contract: document.contract,
8
+ patterns: decodeContractDocument(document.documentBytes).region,
9
+ }));
6
10
  }
7
- export function regionIntersections(left, right) {
8
- return regionsOverlap(left, right).map(([leftPattern, rightPattern]) => ({ left: leftPattern, right: rightPattern }));
9
- }
10
- export function regionPathMatches(patterns, path) {
11
- return regionPatternsMatchPath(patterns, path);
11
+ export function regionOverlaps(mine, declarations) {
12
+ const overlaps = [];
13
+ for (const declaration of declarations) {
14
+ const pairs = regionsOverlap(mine, declaration.patterns);
15
+ if (pairs.length === 0)
16
+ continue;
17
+ overlaps.push({
18
+ contract: declaration.contract,
19
+ patterns: pairs.map(([minePattern, theirsPattern]) => ({ mine: minePattern, theirs: theirsPattern })),
20
+ });
21
+ }
22
+ return overlaps;
12
23
  }
13
- export function validateRegionPath(path) {
14
- if (typeof path !== "string")
15
- throw new Error("Region path must be a string");
16
- assertCanonicalRegionPath(path);
24
+ export function validateRegionPatterns(patterns) {
25
+ if (!Array.isArray(patterns) || patterns.length === 0)
26
+ throw new Error("Region query requires one or more path patterns");
27
+ return patterns.map((pattern) => {
28
+ if (typeof pattern !== "string")
29
+ throw new Error("Region path patterns must be strings");
30
+ return assertRegionPattern(pattern);
31
+ });
17
32
  }
18
33
  function diagnostic(error) {
19
34
  return error instanceof Error ? error.message : String(error);
@@ -42,3 +57,8 @@ export async function observeRegion(scope, channel, self, mine) {
42
57
  return { overlapFailure: diagnostic(error) };
43
58
  }
44
59
  }
60
+ export async function observeChangedRegion(scope, self, changed, mine) {
61
+ if (!changed?.has("region"))
62
+ return {};
63
+ return await withGitDecodeChannel(scope, async (channel) => await observeRegion(scope, channel, self, mine));
64
+ }
@@ -1,9 +1,9 @@
1
- import { currentBranchOperation, scopeOperation, } from "../protocol/operations.js";
1
+ import { currentBranchOperation, scopeOperation } from "../protocol/operations.js";
2
2
  import { NoGitWorldError } from "../git/repository.js";
3
3
  import { optionalNonblank, requireInput } from "./input.js";
4
4
  import { worktreeHooksOption } from "./configuration.js";
5
5
  import { withGitDecodeChannel } from "../git/read-observation.js";
6
- import { completeRepoReconcile, } from "./reconcile.js";
6
+ import { completeRepoReconcile } from "./reconcile.js";
7
7
  export { NoGitWorldError };
8
8
  const REPO_SCOPES = new WeakMap();
9
9
  async function resolvePinnedScope(path, gitPath) {
@@ -52,7 +52,11 @@ function header(line) {
52
52
  level += 1;
53
53
  if (level === 0 || (line[level] !== " " && line[level] !== "\t"))
54
54
  return null;
55
- const text = line.slice(level).trim().replace(/[ \t]+#+[ \t]*$/, "").trimEnd();
55
+ const text = line
56
+ .slice(level)
57
+ .trim()
58
+ .replace(/[ \t]+#+[ \t]*$/, "")
59
+ .trimEnd();
56
60
  return text.length === 0 ? null : { level, text };
57
61
  }
58
62
  function listMarker(line) {
@@ -149,7 +153,10 @@ function frontmatter(lines) {
149
153
  closing += 1;
150
154
  if (closing >= lines.length)
151
155
  return null;
152
- const yaml = lines.slice(1, closing).map((line) => line.text).join("\n");
156
+ const yaml = lines
157
+ .slice(1, closing)
158
+ .map((line) => line.text)
159
+ .join("\n");
153
160
  const entries = parseFrontmatter(yaml);
154
161
  const selected = lines.slice(0, closing + 1);
155
162
  return {
@@ -149,12 +149,14 @@ class Parser {
149
149
  }
150
150
  parseListItem(marker, indent) {
151
151
  const bodyOffset = marker.bodyStart - marker.span.start;
152
- const itemTokens = [{
152
+ const itemTokens = [
153
+ {
153
154
  type: "text",
154
155
  raw: marker.raw.slice(bodyOffset),
155
156
  span: { start: marker.bodyStart, end: marker.span.end },
156
157
  leadingSpaces: 0,
157
- }];
158
+ },
159
+ ];
158
160
  let end = marker.span.end;
159
161
  while (!this.done()) {
160
162
  const token = this.peek();
@@ -173,15 +175,18 @@ class Parser {
173
175
  end = token.span.end;
174
176
  }
175
177
  const childSpan = { start: itemTokens[0].span.start, end: itemTokens.at(-1).span.end };
176
- const children = new Parser(itemTokens, { mode: "item" })
177
- .parseDocument("", childSpan, 0).children;
178
+ const children = new Parser(itemTokens, { mode: "item" }).parseDocument("", childSpan, 0).children;
178
179
  return { type: "list_item", span: { start: marker.span.start, end }, marker: marker.marker, indent, children };
179
180
  }
180
181
  parseText(stop) {
181
182
  const tokens = [];
182
183
  while (!this.done() && !stop()) {
183
184
  const token = this.peek();
184
- if (token === undefined || token.type === "fence" || token.type === "header" || token.type === "blockquote" || token.type === "frontmatter")
185
+ if (token === undefined ||
186
+ token.type === "fence" ||
187
+ token.type === "header" ||
188
+ token.type === "blockquote" ||
189
+ token.type === "frontmatter")
185
190
  break;
186
191
  if (token.type === "list_marker" && (this.options.mode === "item" || token.indent <= 3))
187
192
  break;
@@ -216,6 +221,5 @@ class Parser {
216
221
  }
217
222
  export function parseToAST(source) {
218
223
  const bomLength = source.startsWith("\uFEFF") ? 1 : 0;
219
- return new Parser(lexMarkdown(source), { mode: "document" })
220
- .parseDocument(source, { start: 0, end: source.length }, bomLength);
224
+ return new Parser(lexMarkdown(source), { mode: "document" }).parseDocument(source, { start: 0, end: source.length }, bomLength);
221
225
  }
@@ -42,8 +42,10 @@ export function sectionContent(document, section) {
42
42
  }
43
43
  export function indexedHeadings(index, query) {
44
44
  const candidates = query.title === undefined
45
- ? query.level === undefined ? [] : index.byLevel.get(query.level) ?? []
46
- : index.byTitle.get(normalizeTitle(query.title)) ?? [];
45
+ ? query.level === undefined
46
+ ? []
47
+ : (index.byLevel.get(query.level) ?? [])
48
+ : (index.byTitle.get(normalizeTitle(query.title)) ?? []);
47
49
  return query.level === undefined ? candidates : candidates.filter((node) => node.level === query.level);
48
50
  }
49
51
  export function directChildren(node, type) {
@@ -35,7 +35,9 @@ export async function amendOperation(input) {
35
35
  ? undefined
36
36
  : { source, ...input.deriveAmendment(source) };
37
37
  if (amendment !== undefined) {
38
- observation = await extendPrerequisiteClosureAt(input.channel, observation, [...new Set([...(state?.terms.after ?? []), ...amendment.terms.after])]);
38
+ observation = await extendPrerequisiteClosureAt(input.channel, observation, [
39
+ ...new Set([...(state?.terms.after ?? []), ...amendment.terms.after]),
40
+ ]);
39
41
  }
40
42
  const preparation = amendment === undefined
41
43
  ? undefined
@@ -31,11 +31,14 @@ export type AcceptedAdmission = Readonly<{
31
31
  export type AttemptTerminal = Readonly<{
32
32
  kind: "collision";
33
33
  }> | PublicationFailed;
34
- export type DecidedOfferResult = AcceptedAdmission | AttemptTerminal | Readonly<{
34
+ export type DecidedOfferResult<Refusal = never> = AcceptedAdmission | AttemptTerminal | Readonly<{
35
35
  kind: "redecide";
36
+ }> | Readonly<{
37
+ kind: "refused";
38
+ refusal: Refusal;
36
39
  }>;
37
40
  /** Admit one decided offer without making another legal decision. */
38
- export declare function admitDecidedOffer(input: Readonly<{
41
+ export declare function admitDecidedOffer<Refusal = never>(input: Readonly<{
39
42
  channel: GitDecodeChannel;
40
43
  repository: GitRepository;
41
44
  decisionObservation: GitDecisionObservation;
@@ -43,7 +46,8 @@ export declare function admitDecidedOffer(input: Readonly<{
43
46
  offer: Offer;
44
47
  primaryContract: ContractId;
45
48
  assertions?: readonly GitRefAssertion[];
46
- }>): Promise<DecidedOfferResult>;
49
+ validateAdmission?: (observation: GitDecisionObservation) => Refusal | undefined | Promise<Refusal | undefined>;
50
+ }>): Promise<DecidedOfferResult<Refusal>>;
47
51
  /** Classify an unknown atomic-publication outcome using only a captured Git observation. */
48
52
  export declare function classifyUnknownAttempt(observation: Readonly<{
49
53
  contracts: GitDecisionObservation["journals"];
@@ -78,13 +78,12 @@ function recoveredAcceptance(observation, offer, primaryContract) {
78
78
  };
79
79
  }
80
80
  async function publicationPremiseMoved(repository, observation, offer, assertions) {
81
- if (await readRef(repository, GIT_REF) !== observation.admission.snapshot.commit)
81
+ if ((await readRef(repository, GIT_REF)) !== observation.admission.snapshot.commit)
82
82
  return true;
83
83
  for (const assertion of assertions)
84
- if (await readRef(repository, assertion.ref) !== assertion.oid)
84
+ if ((await readRef(repository, assertion.ref)) !== assertion.oid)
85
85
  return true;
86
- return offer.target !== undefined
87
- && await readRef(repository, offer.target.target) !== offer.target.expectedOid;
86
+ return offer.target !== undefined && (await readRef(repository, offer.target.target)) !== offer.target.expectedOid;
88
87
  }
89
88
  /** Admit one decided offer without making another legal decision. */
90
89
  export async function admitDecidedOffer(input) {
@@ -92,6 +91,11 @@ export async function admitDecidedOffer(input) {
92
91
  const assertions = input.assertions ?? [];
93
92
  validateOffer(offer, attempt);
94
93
  const primary = primaryAppend(offer, primaryContract);
94
+ if (input.validateAdmission !== undefined) {
95
+ const refusal = await input.validateAdmission(decisionObservation);
96
+ if (refusal !== undefined)
97
+ return { kind: "refused", refusal };
98
+ }
95
99
  const admission = await admit(repository, offer, decisionObservation.admission, assertions);
96
100
  if (admission.kind === "accepted") {
97
101
  return {
@@ -102,7 +106,7 @@ export async function admitDecidedOffer(input) {
102
106
  };
103
107
  }
104
108
  if (admission.kind === "publication-failed") {
105
- return await publicationPremiseMoved(repository, decisionObservation, offer, assertions)
109
+ return (await publicationPremiseMoved(repository, decisionObservation, offer, assertions))
106
110
  ? { kind: "redecide" }
107
111
  : admission;
108
112
  }
@@ -3,7 +3,7 @@ import type { ChangeId, ContractState, DeliverData } from "../core/facts/types.j
3
3
  import { type AuditTargetAnswer } from "../git/target-placement.js";
4
4
  import type { DeliveryPreparationRefusal, DocumentDerivation, IntentOutcome, MutationOperationInput, VerificationStop } from "./operations.js";
5
5
  type AuditWorkspace = Readonly<{
6
- kind: "worktree" | "here";
6
+ kind: "worktree";
7
7
  path: string;
8
8
  }>;
9
9
  type DiffScope = DeliveryDiffScope;
@@ -7,15 +7,7 @@ import { verifyDelivery } from "./intent.js";
7
7
  import { accepted, admitted } from "./outcome.js";
8
8
  import { prepareDelivery } from "./deliver.js";
9
9
  import { timestamp, unpackVerificationOutcome } from "./operations.js";
10
- async function auditWorkspace(repository, state, resolveHereWorkspace) {
11
- if (state.coordinates.workspace === "here") {
12
- const path = resolveHereWorkspace === undefined
13
- ? repository.effectiveCwd
14
- : await resolveHereWorkspace(state.id);
15
- return path === undefined
16
- ? { kind: "unappointed" }
17
- : { kind: "ready", answer: { kind: "here", path } };
18
- }
10
+ async function auditWorkspace(repository, state) {
19
11
  const appointed = await readManagedWorktreeAppointment(repository, state.id);
20
12
  if (appointed.kind === "failed")
21
13
  throw new Error(appointed.diagnostic);
@@ -73,7 +65,7 @@ async function readyAuditCandidate(repository, candidate, workspace, showDiff) {
73
65
  ...(diff === undefined || diff === null ? {} : { diff }),
74
66
  };
75
67
  }
76
- async function auditTargetAnswer(repository, state, candidate, workspacePath) {
68
+ async function auditTargetAnswer(repository, state, candidate) {
77
69
  const target = state.coordinates.target;
78
70
  if (target === undefined)
79
71
  return { kind: "not-observed" };
@@ -82,7 +74,6 @@ async function auditTargetAnswer(repository, state, candidate, workspacePath) {
82
74
  coordinates: { ...state.coordinates, target },
83
75
  predecessor: candidate.integration.predecessor,
84
76
  candidate: candidate.integration.snapshot,
85
- ...(workspacePath === undefined ? {} : { hereWorkspacePath: workspacePath }),
86
77
  });
87
78
  }
88
79
  function blockedAudit(refusal) {
@@ -112,7 +103,7 @@ export async function auditOperation(input) {
112
103
  }
113
104
  if (derivation.verification.kind === "refused")
114
105
  return { kind: "refused", refusal: derivation.verification.refusal };
115
- const workspace = await auditWorkspace(input.scope, state, input.resolveHereWorkspace);
106
+ const workspace = await auditWorkspace(input.scope, state);
116
107
  if (workspace.kind === "unappointed") {
117
108
  return accepted(state, [], blockedAudit({ kind: "worktree-missing", contractId: state.id }));
118
109
  }
@@ -120,7 +111,6 @@ export async function auditOperation(input) {
120
111
  contractId: state.id,
121
112
  coordinates: state.coordinates,
122
113
  ...(workspace.appointment === undefined ? {} : { appointment: workspace.appointment }),
123
- ...(workspace.answer.kind === "here" ? { workspacePath: workspace.answer.path } : {}),
124
114
  }, {
125
115
  title: derivation.title,
126
116
  document: derivation.bytes,
@@ -140,7 +130,7 @@ export async function auditOperation(input) {
140
130
  verification,
141
131
  target: verification.kind === "stopped"
142
132
  ? { kind: "not-observed" }
143
- : await auditTargetAnswer(input.scope, state, prepared.data, workspace.answer.kind === "here" ? workspace.answer.path : undefined),
133
+ : await auditTargetAnswer(input.scope, state, prepared.data),
144
134
  ...(delivery === undefined ? {} : { delivery }),
145
135
  };
146
136
  return completedAudit(state, verified, value);
@@ -1,3 +1,5 @@
1
+ import { type BindTargetSelection } from "../git/observe.js";
2
+ export type { BindTargetSelection };
1
3
  import type { GitRepository } from "../git/process.js";
2
4
  import type { GitDecodeChannel } from "../git/read-observation.js";
3
5
  import type { BindData, ActorId, ContractId } from "../core/facts/types.js";
@@ -11,21 +13,32 @@ export type TargetInputRefusal = Readonly<{
11
13
  }> | Readonly<{
12
14
  kind: "target-missing";
13
15
  }> | Readonly<{
14
- kind: "here-target-mismatch";
15
- target: string;
16
- branch: string | null;
16
+ kind: "unborn-head";
17
+ }>;
18
+ export type ForkSourceMovedRefusal = Readonly<{
19
+ kind: "fork-source-moved";
20
+ contractId: ContractId;
17
21
  }>;
18
22
  type BindOperationInput = Readonly<{
19
23
  scope: GitRepository;
20
24
  channel: GitDecodeChannel;
21
25
  terms: BindData["terms"];
22
26
  verification: VerificationDeclarationPreparation;
23
- target?: string;
24
- workspace: "worktree" | "here";
27
+ targetSelection?: BindTargetSelection;
28
+ workspace: "worktree";
25
29
  actor?: ActorId;
26
30
  decorateOffer?: CompanionDecorator;
27
31
  contractId: ContractId;
32
+ coordinates?: Readonly<{
33
+ start: import("../core/facts/types.js").SnapshotId;
34
+ }>;
35
+ source?: Readonly<{
36
+ contractId: ContractId;
37
+ head: import("../core/facts/types.js").ContractHead | null;
38
+ start: import("../core/facts/types.js").SnapshotId;
39
+ document: import("../core/facts/types.js").DocumentKey;
40
+ }>;
28
41
  }>;
29
42
  export declare function bindOperation(input: BindOperationInput): Promise<IntentOutcome<Readonly<{
30
43
  contractId: ContractId;
31
- }>, BindRefusal | TargetInputRefusal | VerificationDeclarationRefusal>>;
44
+ }>, BindRefusal | TargetInputRefusal | VerificationDeclarationRefusal | ForkSourceMovedRefusal>>;
@@ -3,18 +3,19 @@ import { gitObjectIdForSnapshot } from "../git/identity.js";
3
3
  import { decideBind } from "../core/verbs/bind.js";
4
4
  import { admitIntent } from "./intent.js";
5
5
  import { complete } from "./outcome.js";
6
- async function bindPreparation(input, target, seed) {
6
+ async function bindPreparation(input, selection, seed) {
7
7
  if (input.verification.kind === "refused") {
8
8
  return { kind: "prepared", input: { ...seed, preparation: input.verification } };
9
9
  }
10
- const observed = await observeBindCoordinates(input.scope, target);
10
+ const observed = await observeBindCoordinates(input.scope, selection);
11
11
  if (observed === null)
12
12
  return { kind: "refused", refusal: { kind: "target-missing" } };
13
- if (input.workspace === "here" && target !== undefined && observed.branch !== target) {
14
- return { kind: "refused", refusal: { kind: "here-target-mismatch", target, branch: observed.branch } };
13
+ if (!("start" in observed)) {
14
+ return { kind: "refused", refusal: { kind: "unborn-head" } };
15
15
  }
16
- const oid = gitObjectIdForSnapshot(observed.start);
17
- const assertions = [{ ref: target ?? "HEAD", oid }];
16
+ const start = input.coordinates?.start ?? observed.start;
17
+ const oid = gitObjectIdForSnapshot(input.coordinates === undefined ? start : observed.start);
18
+ const assertions = input.coordinates === undefined ? [{ ref: observed.target ?? "HEAD", oid }] : [];
18
19
  return {
19
20
  kind: "prepared",
20
21
  input: {
@@ -23,7 +24,7 @@ async function bindPreparation(input, target, seed) {
23
24
  kind: "prepared",
24
25
  data: {
25
26
  coordinates: {
26
- start: observed.start,
27
+ start,
27
28
  ...(observed.target === undefined ? {} : { target: observed.target }),
28
29
  workspace: input.workspace,
29
30
  },
@@ -35,12 +36,12 @@ async function bindPreparation(input, target, seed) {
35
36
  };
36
37
  }
37
38
  export async function bindOperation(input) {
38
- let target;
39
- if (input.target !== undefined) {
40
- const normalized = await normalizeTargetBranch(input.scope, input.target);
39
+ let selection = input.targetSelection ?? { kind: "targetless" };
40
+ if (selection.kind === "explicit") {
41
+ const normalized = await normalizeTargetBranch(input.scope, selection.target);
41
42
  if (normalized === null)
42
43
  return { kind: "refused", refusal: { kind: "invalid-target" } };
43
- target = normalized;
44
+ selection = { kind: "explicit", target: normalized };
44
45
  }
45
46
  const at = new Date().toISOString();
46
47
  const id = input.contractId;
@@ -49,8 +50,22 @@ export async function bindOperation(input) {
49
50
  ...(input.actor === undefined ? {} : { actor: input.actor }),
50
51
  at,
51
52
  }, decideBind, {
52
- observedContracts: [id, ...input.terms.after],
53
- prepareInput: async (_observation, original) => bindPreparation(input, target, original),
53
+ observedContracts: [id, ...input.terms.after, ...(input.source === undefined ? [] : [input.source.contractId])],
54
+ prepareInput: async (_observation, original) => bindPreparation(input, selection, original),
55
+ ...(input.source === undefined
56
+ ? {}
57
+ : {
58
+ validateAdmission: (observation) => {
59
+ const current = observation.decision.get(input.source.contractId);
60
+ return current !== null &&
61
+ current !== undefined &&
62
+ current.head === input.source.head &&
63
+ current.coordinates.start === input.source.start &&
64
+ current.terms.document.key === input.source.document
65
+ ? undefined
66
+ : { kind: "fork-source-moved", contractId: input.source.contractId };
67
+ },
68
+ }),
54
69
  ...(input.decorateOffer === undefined ? {} : { decorateOffer: input.decorateOffer }),
55
70
  }), { contractId: id });
56
71
  }
@@ -32,7 +32,6 @@ type CompletionInput = Readonly<{
32
32
  verification: VerificationDeclarationPreparation;
33
33
  initial: AcceptedProtocolStep;
34
34
  verifyInitial: boolean;
35
- hereWorkspacePath?: string;
36
35
  }>;
37
36
  export type CompletionResult = Readonly<{
38
37
  admission: AcceptedProtocolStep;