@astrosheep/keiyaku 4.5.19 → 4.5.21

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 (197) hide show
  1. package/README.md +4 -4
  2. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +14 -7
  3. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +53 -20
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +237 -0
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +6 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +2 -4
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -3
  8. package/build/src/akuma/akuma-handle.d.ts +5 -1
  9. package/build/src/akuma/akuma-handle.js +4 -1
  10. package/build/src/akuma/akuma-instance.d.ts +7 -2
  11. package/build/src/akuma/akuma-instance.js +14 -7
  12. package/build/src/akuma/akuma-observe.d.ts +11 -0
  13. package/build/src/akuma/akuma-observe.js +23 -0
  14. package/build/src/akuma/akuma-product.d.ts +2 -0
  15. package/build/src/akuma/akuma-product.js +6 -0
  16. package/build/src/akuma/akuma.d.ts +20 -1
  17. package/build/src/akuma/akuma.js +2 -0
  18. package/build/src/akuma/allowed.d.ts +20 -0
  19. package/build/src/akuma/allowed.js +11 -0
  20. package/build/src/akuma/archetype.js +3 -0
  21. package/build/src/akuma/body.d.ts +25 -5
  22. package/build/src/akuma/body.js +70 -31
  23. package/build/src/akuma/call-request.d.ts +5 -0
  24. package/build/src/akuma/call-request.js +14 -4
  25. package/build/src/akuma/fleet-execution.d.ts +28 -0
  26. package/build/src/akuma/fleet-execution.js +36 -4
  27. package/build/src/akuma/fleet-observation.d.ts +54 -0
  28. package/build/src/akuma/fleet-request.d.ts +10 -0
  29. package/build/src/akuma/fleet-request.js +13 -3
  30. package/build/src/akuma/heart/facts.d.ts +2 -0
  31. package/build/src/akuma/heart/index.d.ts +1 -0
  32. package/build/src/akuma/heart/index.js +4 -1
  33. package/build/src/akuma/heart/rows.d.ts +2 -0
  34. package/build/src/akuma/heart/rows.js +7 -5
  35. package/build/src/akuma/heart/schema.d.ts +1 -1
  36. package/build/src/akuma/heart/schema.js +3 -1
  37. package/build/src/akuma/heart/tells.js +6 -5
  38. package/build/src/akuma/heart/timeline.js +1 -1
  39. package/build/src/akuma/provider-recipe.d.ts +1 -0
  40. package/build/src/akuma/provider-recipe.js +5 -0
  41. package/build/src/akuma/provider.d.ts +1 -1
  42. package/build/src/akuma/provider.js +1 -1
  43. package/build/src/akuma/providers/acp/core.js +3 -6
  44. package/build/src/akuma/providers/acp/index.js +3 -0
  45. package/build/src/akuma/providers/claude/index.js +10 -10
  46. package/build/src/akuma/providers/codex-app-server/index.js +12 -11
  47. package/build/src/akuma/providers/execution-environment.d.ts +6 -0
  48. package/build/src/akuma/providers/execution-environment.js +24 -0
  49. package/build/src/akuma/providers/grok-build/index.js +3 -0
  50. package/build/src/akuma/providers/opencode-sdk/index.js +32 -23
  51. package/build/src/akuma/providers/opencode-sdk/session.d.ts +8 -1
  52. package/build/src/akuma/providers/opencode-sdk/session.js +6 -5
  53. package/build/src/akuma/providers/pi/events.js +7 -2
  54. package/build/src/akuma/providers/pi/index.js +5 -2
  55. package/build/src/akuma/request-observation.d.ts +45 -0
  56. package/build/src/akuma/request-observation.js +162 -0
  57. package/build/src/akuma/request-rendezvous.d.ts +6 -3
  58. package/build/src/akuma/request-rendezvous.js +80 -14
  59. package/build/src/akuma/request-serve.js +27 -4
  60. package/build/src/akuma/request-wire.d.ts +5 -0
  61. package/build/src/akuma/request-wire.js +2 -0
  62. package/build/src/akuma/turn-drive.d.ts +1 -0
  63. package/build/src/akuma/turn-drive.js +2 -0
  64. package/build/src/akuma-body.js +5 -0
  65. package/build/src/body/amend.js +6 -4
  66. package/build/src/body/decode.d.ts +3 -1
  67. package/build/src/body/decode.js +53 -17
  68. package/build/src/body/region.d.ts +9 -1
  69. package/build/src/body/region.js +87 -12
  70. package/build/src/body/render.js +1 -1
  71. package/build/src/body/verification.d.ts +3 -1
  72. package/build/src/body/verification.js +4 -1
  73. package/build/src/cli/accepted.js +19 -2
  74. package/build/src/cli/commands/akuma-invoke.d.ts +3 -1
  75. package/build/src/cli/commands/akuma-invoke.js +134 -14
  76. package/build/src/cli/commands/akuma.js +24 -12
  77. package/build/src/cli/commands/contract-help.d.ts +15 -15
  78. package/build/src/cli/commands/contract-help.js +45 -19
  79. package/build/src/cli/commands/contract-invoke.d.ts +3 -0
  80. package/build/src/cli/commands/contract-invoke.js +25 -11
  81. package/build/src/cli/commands/contract.js +6 -4
  82. package/build/src/cli/commands/install.d.ts +1 -1
  83. package/build/src/cli/commands/install.js +1 -1
  84. package/build/src/cli/commands/status-set.js +15 -24
  85. package/build/src/cli/commands/task.js +18 -18
  86. package/build/src/cli/invoke.d.ts +3 -0
  87. package/build/src/cli/invoke.js +58 -23
  88. package/build/src/cli/main.js +5 -0
  89. package/build/src/cli/parse.d.ts +3 -0
  90. package/build/src/cli/parse.js +26 -4
  91. package/build/src/cli/render/akuma-activity.d.ts +100 -2
  92. package/build/src/cli/render/akuma-activity.js +485 -40
  93. package/build/src/cli/render/akuma.d.ts +10 -0
  94. package/build/src/cli/render/akuma.js +31 -21
  95. package/build/src/cli/render/audit.js +1 -1
  96. package/build/src/cli/render/board.js +1 -1
  97. package/build/src/cli/render/catalog.js +16 -13
  98. package/build/src/cli/render/contract-history.js +39 -10
  99. package/build/src/cli/render/contract-observation.js +10 -6
  100. package/build/src/cli/render/contract.js +109 -106
  101. package/build/src/cli/render/execution-progress.d.ts +26 -0
  102. package/build/src/cli/render/execution-progress.js +178 -0
  103. package/build/src/cli/render/kanshi-akuma.js +27 -39
  104. package/build/src/cli/render/kanshi.js +33 -26
  105. package/build/src/cli/render/nuke.js +1 -1
  106. package/build/src/cli/render/receipt.d.ts +1 -1
  107. package/build/src/cli/render/receipt.js +6 -6
  108. package/build/src/cli/render/refusal.js +10 -7
  109. package/build/src/cli/render/region.js +1 -1
  110. package/build/src/cli/render/settings.js +12 -2
  111. package/build/src/cli/render/status-line.d.ts +30 -0
  112. package/build/src/cli/render/status-line.js +58 -0
  113. package/build/src/cli/render/status-set.js +1 -1
  114. package/build/src/cli/render/task.d.ts +2 -0
  115. package/build/src/cli/render/task.js +11 -7
  116. package/build/src/cli/render/terminal.d.ts +0 -1
  117. package/build/src/cli/render/terminal.js +47 -15
  118. package/build/src/cli/result.d.ts +1 -0
  119. package/build/src/cli/runtime.d.ts +2 -0
  120. package/build/src/cli/runtime.js +36 -4
  121. package/build/src/cli/usage.js +2 -2
  122. package/build/src/cli/version.d.ts +1 -0
  123. package/build/src/cli/version.js +25 -0
  124. package/build/src/git/hooks.d.ts +13 -1
  125. package/build/src/git/hooks.js +2 -1
  126. package/build/src/git/workspace.d.ts +1 -1
  127. package/build/src/git/workspace.js +1 -1
  128. package/build/src/identity/mint.d.ts +13 -0
  129. package/build/src/identity/mint.js +26 -0
  130. package/build/src/identity/normalize.d.ts +4 -0
  131. package/build/src/identity/normalize.js +30 -0
  132. package/build/src/index.d.ts +2 -0
  133. package/build/src/index.js +1 -0
  134. package/build/src/kanshi/read.js +17 -4
  135. package/build/src/kanshi/report.d.ts +1 -0
  136. package/build/src/library/akuma-creation.d.ts +2 -0
  137. package/build/src/library/akuma-creation.js +34 -18
  138. package/build/src/library/audit.d.ts +2 -0
  139. package/build/src/library/audit.js +1 -0
  140. package/build/src/library/bind.js +18 -16
  141. package/build/src/library/composition.d.ts +1 -0
  142. package/build/src/library/contract-bind.d.ts +3 -1
  143. package/build/src/library/contract-bind.js +5 -3
  144. package/build/src/library/contract-execution.d.ts +2 -0
  145. package/build/src/library/contract-execution.js +15 -1
  146. package/build/src/library/contract-forwarding.d.ts +4 -0
  147. package/build/src/library/contract-forwarding.js +3 -0
  148. package/build/src/library/contract-handle.d.ts +7 -0
  149. package/build/src/library/contract-handle.js +25 -0
  150. package/build/src/library/contract-operations.d.ts +7 -2
  151. package/build/src/library/contract-operations.js +21 -1
  152. package/build/src/library/contract-types.d.ts +1 -0
  153. package/build/src/library/execution-result.d.ts +2 -2
  154. package/build/src/library/execution.d.ts +8 -0
  155. package/build/src/library/execution.js +102 -0
  156. package/build/src/library/fleet.d.ts +4 -1
  157. package/build/src/library/fleet.js +32 -8
  158. package/build/src/library/keiyaku.d.ts +2 -0
  159. package/build/src/library/mutation.js +15 -7
  160. package/build/src/plugin/akuma-signals.d.ts +6 -0
  161. package/build/src/plugin/akuma-signals.js +9 -1
  162. package/build/src/plugin/public.d.ts +6 -2
  163. package/build/src/plugin/runtime.d.ts +1 -3
  164. package/build/src/plugin/runtime.js +95 -103
  165. package/build/src/protocol/amend.js +4 -3
  166. package/build/src/protocol/attempt.d.ts +2 -0
  167. package/build/src/protocol/bind.js +41 -14
  168. package/build/src/protocol/completion.d.ts +3 -0
  169. package/build/src/protocol/completion.js +35 -11
  170. package/build/src/protocol/deliver.js +165 -92
  171. package/build/src/protocol/execution-observation.d.ts +181 -0
  172. package/build/src/protocol/execution-observation.js +45 -0
  173. package/build/src/protocol/intent.d.ts +18 -22
  174. package/build/src/protocol/intent.js +63 -41
  175. package/build/src/protocol/operations.d.ts +2 -0
  176. package/build/src/protocol/placement.js +5 -1
  177. package/build/src/protocol/progress.d.ts +5 -1
  178. package/build/src/protocol/progress.js +10 -1
  179. package/build/src/protocol/read/status.d.ts +1 -0
  180. package/build/src/protocol/read/status.js +10 -2
  181. package/build/src/protocol/reintegrate.d.ts +1 -1
  182. package/build/src/protocol/reintegrate.js +70 -43
  183. package/build/src/protocol/result-codec.js +27 -11
  184. package/build/src/protocol/review.js +53 -30
  185. package/build/src/protocol/run.d.ts +83 -36
  186. package/build/src/protocol/run.js +90 -75
  187. package/build/src/runtime/proc/run.d.ts +16 -4
  188. package/build/src/runtime/proc/run.js +64 -22
  189. package/build/src/runtime/proc/windows-launch.exe +0 -0
  190. package/build/src/settings.js +5 -14
  191. package/build/src/task/document.d.ts +5 -1
  192. package/build/src/task/document.js +6 -1
  193. package/build/src/verification/execution.d.ts +10 -2
  194. package/build/src/verification/execution.js +143 -42
  195. package/build/src/verification/observation.d.ts +41 -0
  196. package/build/src/verification/observation.js +29 -0
  197. package/package.json +3 -1
@@ -2,7 +2,7 @@ import { materializeIntegrationSnapshot, materializeJudgedConflict, planIntegrat
2
2
  import { captureTender, dirtyTenderRefusal, materializeTenderSnapshot, prepareDeliveryCommitMetadata, } from "../git/tender.js";
3
3
  import { checkoutDetachedSnapshot, recordConflictHandoff, retireConflictHandoff, workspaceMergeStatePresent, worktreePath, conflictRecovery, } from "../git/workspace.js";
4
4
  import { observeContractsForAdmissionAt } from "../git/observe.js";
5
- import { matchingPrivateRootObservation, privateStateSeatAttempt, sameSpeculativeWorktreeInput, } from "./run.js";
5
+ import { contractStateWitness, privateStateSeatAttempt, sameWorktreeWitness, STALE_PRIVATE_STATE_PREPARATION, } from "./run.js";
6
6
  import { contractState } from "../core/facts/observation.js";
7
7
  import { decideDeliver } from "../core/verbs/deliver.js";
8
8
  import { currentVerifiedAttestation } from "./intent.js";
@@ -134,52 +134,132 @@ function hasSupersedingVerification(state, journal) {
134
134
  const verificationIndex = journal.findIndex((entry) => entry.entry === current.entry);
135
135
  return deliveryIndex >= 0 && verificationIndex > deliveryIndex;
136
136
  }
137
- async function speculateDelivery(input) {
137
+ /**
138
+ * Repeatable physical delivery work outside the publication seat: locate the appointed worktree from
139
+ * one non-authoritative private-state read, capture its bytes, and materialize the prepared artifacts.
140
+ */
141
+ async function prepareExternalDelivery(input) {
138
142
  const observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
139
143
  const state = contractState(observation.decision, input.contractId);
140
- const derivation = state === null ? undefined : input.deriveDocument(state);
141
- if (state === null || derivation === undefined) {
142
- return { observation, state, preparation: { kind: "unavailable" } };
144
+ if (state === null)
145
+ return { kind: "unavailable" };
146
+ return {
147
+ kind: "artifacts",
148
+ witness: contractStateWitness(state),
149
+ artifacts: await prepareDeliveryArtifacts(input, observation, state),
150
+ };
151
+ }
152
+ async function prepareDeliveryArtifacts(input, observation, state) {
153
+ const derivation = input.deriveDocument(state);
154
+ if (derivation.verification.kind === "refused")
155
+ return { kind: "defer" };
156
+ if (reusesCurrentCandidate(input, state, derivation))
157
+ return { kind: "defer" };
158
+ if (input.materializeConflict === true && state.terminal === null)
159
+ return { kind: "defer" };
160
+ const captured = await captureAuthorizedDeliveryTender(input.scope, { contractId: state.id, coordinates: state.coordinates }, input.includeDirty);
161
+ if (captured.kind === "refused")
162
+ return { kind: "refused", refusal: captured.refusal };
163
+ const worktree = await worktreeInput(input.scope, state, captured.data);
164
+ if (state.terminal === null &&
165
+ state.delivery !== null &&
166
+ worktree.changeId === state.delivery.data.integration.changeId &&
167
+ !hasSupersedingVerification(state, observation.journals.get(state.id)?.entries ?? [])) {
168
+ return {
169
+ kind: "continuation",
170
+ worktree,
171
+ };
143
172
  }
173
+ const prepared = await mechanicalDeliveryPreparation(input, state, derivation, captured.data);
174
+ return prepared.kind === "prepared"
175
+ ? { kind: "mechanical", data: prepared.data, worktree: prepared.worktree }
176
+ : { kind: "refused", refusal: prepared.refusal };
177
+ }
178
+ /**
179
+ * Assemble the in-custody decision input from the fresh Contract. State-derived choices are recomputed
180
+ * here; artifacts the fresh state cannot justify are spent, which restarts the whole preparation.
181
+ */
182
+ async function assembleDeliveryAttempt(input, observation, external) {
183
+ const state = contractState(observation.decision, input.contractId);
184
+ if (external.kind === "unavailable") {
185
+ return state === null
186
+ ? { kind: "assembled", state: null, preparation: { kind: "unavailable" } }
187
+ : { kind: "stale" };
188
+ }
189
+ if (state === null)
190
+ return { kind: "stale" };
191
+ if (external.witness.head !== state.head)
192
+ return { kind: "stale" };
193
+ const derivation = input.deriveDocument(state);
144
194
  if (derivation.verification.kind === "refused") {
145
195
  return {
146
- observation,
196
+ kind: "assembled",
147
197
  state,
148
198
  derivation,
149
199
  preparation: { kind: "refused", document: derivation.document, refusal: derivation.verification.refusal },
150
200
  };
151
201
  }
152
202
  if (reusesCurrentCandidate(input, state, derivation))
153
- return { observation, state, derivation };
154
- if (input.materializeConflict === true && state.terminal === null)
155
- return { observation, state, derivation };
156
- const captured = await captureAuthorizedDeliveryTender(input.scope, { contractId: state.id, coordinates: state.coordinates }, input.includeDirty);
157
- if (captured.kind === "refused") {
203
+ return { kind: "assembled", state, derivation };
204
+ const artifacts = external.artifacts;
205
+ if (artifacts.kind === "defer")
206
+ return await completeDeferredDelivery(input, state, derivation);
207
+ if (artifacts.kind === "refused") {
158
208
  return {
159
- observation,
209
+ kind: "assembled",
160
210
  state,
161
211
  derivation,
162
- preparation: { kind: "refused", document: derivation.document, refusal: captured.refusal },
212
+ preparation: { kind: "refused", document: derivation.document, refusal: artifacts.refusal },
163
213
  };
164
214
  }
165
- const capturedWorktree = await worktreeInput(input.scope, state, captured.data);
166
- if (state.terminal === null &&
167
- state.delivery !== null &&
168
- capturedWorktree.changeId === state.delivery.data.integration.changeId &&
169
- !hasSupersedingVerification(state, observation.journals.get(state.id)?.entries ?? [])) {
215
+ if (!sameWorktreeWitness(artifacts.worktree, await recaptureDeliveryWorktree(input, state))) {
216
+ return { kind: "stale" };
217
+ }
218
+ if (artifacts.kind === "continuation") {
219
+ const delivery = state.delivery;
220
+ if (delivery === null)
221
+ return { kind: "stale" };
170
222
  return {
171
- observation,
223
+ kind: "assembled",
172
224
  state,
173
225
  derivation,
174
- preparation: { kind: "prepared", document: derivation.document, data: state.delivery.data },
175
- worktree: capturedWorktree,
226
+ preparation: { kind: "prepared", document: derivation.document, data: delivery.data },
176
227
  continuation: true,
177
228
  };
178
229
  }
179
- const prepared = await mechanicalDeliveryPreparation(input, state, derivation, captured.data);
180
- return prepared.kind === "prepared"
181
- ? { observation, state, derivation, preparation: prepared, worktree: prepared.worktree }
182
- : { observation, state, derivation, preparation: prepared };
230
+ return {
231
+ kind: "assembled",
232
+ state,
233
+ derivation,
234
+ preparation: { kind: "prepared", document: derivation.document, data: artifacts.data },
235
+ };
236
+ }
237
+ /**
238
+ * Complete a preparation the outside phase could not settle. A requested conflict materialization
239
+ * must retire its owned handoff and then capture the worktree that follows, so it only runs under
240
+ * this custody; every other deferred state is decided by reuse above or refuses on its own.
241
+ */
242
+ async function completeDeferredDelivery(input, state, derivation) {
243
+ if (input.materializeConflict !== true || state.terminal !== null)
244
+ return { kind: "assembled", state, derivation };
245
+ const materialization = await materializationMergeStateRefusal(input);
246
+ if (materialization !== undefined) {
247
+ return {
248
+ kind: "assembled",
249
+ state,
250
+ derivation,
251
+ preparation: { kind: "refused", document: derivation.document, refusal: materialization },
252
+ };
253
+ }
254
+ const prepared = await mechanicalDeliveryPreparation(input, state, derivation);
255
+ return {
256
+ kind: "assembled",
257
+ state,
258
+ derivation,
259
+ preparation: prepared.kind === "prepared"
260
+ ? { kind: "prepared", document: derivation.document, data: prepared.data }
261
+ : prepared,
262
+ };
183
263
  }
184
264
  function reusesCurrentCandidate(input, state, derivation) {
185
265
  return (input.overwrite !== true &&
@@ -189,60 +269,54 @@ function reusesCurrentCandidate(input, state, derivation) {
189
269
  derivation.verification.data !== null &&
190
270
  currentVerifiedAttestation(state) === undefined);
191
271
  }
192
- async function resolveDeliveryPreparation(input, speculated) {
193
- if (speculated.preparation !== undefined)
194
- return speculated.preparation;
195
- if (speculated.state === null || speculated.derivation === undefined)
196
- return { kind: "unavailable" };
197
- const materialization = await materializationMergeStateRefusal(input);
198
- if (materialization !== undefined) {
199
- return { kind: "refused", document: speculated.derivation.document, refusal: materialization };
200
- }
201
- const prepared = await mechanicalDeliveryPreparation(input, speculated.state, speculated.derivation);
202
- return prepared.kind === "prepared"
203
- ? { kind: "prepared", document: prepared.document, data: prepared.data }
204
- : prepared;
272
+ /** Accept a delivery whose current candidate is already admitted, without admitting it again. */
273
+ function currentCandidateDeliveryDecision(input, observation, assembled) {
274
+ const state = assembled.state;
275
+ if (state === null || assembled.derivation === undefined)
276
+ return undefined;
277
+ if (!reusesCurrentCandidate(input, state, assembled.derivation))
278
+ return undefined;
279
+ const record = observation.journals.get(input.contractId);
280
+ const delivery = record?.entries.findLast((entry) => entry.kind === "deliver");
281
+ if (record === undefined || delivery === undefined)
282
+ throw new Error("current delivery is missing its journal fact");
283
+ input.progress?.recordAdmission({ kind: "accepted", facts: [], state, journal: record.entries });
284
+ return {
285
+ kind: "accepted",
286
+ facts: [],
287
+ state,
288
+ journal: record.entries,
289
+ value: {
290
+ ...state.delivery.data,
291
+ leading: { kind: "already-admitted", fact: delivery.entry },
292
+ },
293
+ };
205
294
  }
206
- async function decideAndAdmitDelivery(input, attempt, seat, observation, speculated) {
207
- const currentState = speculated.state;
208
- if (currentState !== null &&
209
- speculated.derivation !== undefined &&
210
- reusesCurrentCandidate(input, currentState, speculated.derivation)) {
211
- const record = observation.journals.get(input.contractId);
212
- const delivery = record?.entries.findLast((entry) => entry.kind === "deliver");
213
- if (record === undefined || delivery === undefined)
214
- throw new Error("current delivery is missing its journal fact");
215
- input.progress?.recordAdmission({ kind: "accepted", facts: [], state: currentState, journal: record.entries });
216
- return {
217
- kind: "accepted",
218
- facts: [],
219
- state: currentState,
220
- journal: record.entries,
221
- value: {
222
- ...currentState.delivery.data,
223
- leading: { kind: "already-admitted", fact: delivery.entry },
224
- },
225
- };
226
- }
227
- if (speculated.continuation === true) {
228
- const record = observation.journals.get(input.contractId);
229
- if (record === undefined ||
230
- record.state === null ||
231
- record.state.delivery === null ||
232
- speculated.derivation === undefined) {
233
- return { kind: "redecide" };
234
- }
235
- const state = record.state;
236
- input.progress?.recordAdmission({ kind: "accepted", facts: [], state, journal: record.entries });
237
- return {
238
- kind: "accepted",
239
- facts: [],
240
- state,
241
- journal: record.entries,
242
- value: record.state.delivery.data,
243
- };
295
+ /** Continue the admitted integration this worktree already carries, without a new offer. */
296
+ function continuationDeliveryDecision(input, observation, assembled) {
297
+ const record = observation.journals.get(input.contractId);
298
+ const state = record?.state ?? null;
299
+ if (record === undefined || state === null || state.delivery === null || assembled.derivation === undefined) {
300
+ return { kind: "redecide" };
244
301
  }
245
- const preparation = await resolveDeliveryPreparation(input, speculated);
302
+ input.progress?.recordAdmission({ kind: "accepted", facts: [], state, journal: record.entries });
303
+ return {
304
+ kind: "accepted",
305
+ facts: [],
306
+ state,
307
+ journal: record.entries,
308
+ value: state.delivery.data,
309
+ };
310
+ }
311
+ async function decideAndAdmitDelivery(input, attempt, seat, observation, assembled) {
312
+ const current = currentCandidateDeliveryDecision(input, observation, assembled);
313
+ if (current !== undefined)
314
+ return current;
315
+ if (assembled.continuation === true)
316
+ return continuationDeliveryDecision(input, observation, assembled);
317
+ const preparation = assembled.preparation ?? STALE_PRIVATE_STATE_PREPARATION;
318
+ if (preparation.kind === "stale")
319
+ return preparation;
246
320
  const decision = decideDeliver({
247
321
  input: {
248
322
  contractId: input.contractId,
@@ -274,22 +348,19 @@ async function decideAndAdmitDelivery(input, attempt, seat, observation, specula
274
348
  value: preparation.data,
275
349
  };
276
350
  }
277
- async function deliverAttemptInPrivateStateSeat(input, attempt, seat, speculated) {
278
- const observation = await matchingPrivateRootObservation(input.scope, input.channel, input.contractId, speculated.observation, async (fresh) => {
279
- if (speculated.worktree === undefined)
280
- return true;
281
- const state = contractState(fresh.decision, input.contractId);
282
- if (state === null)
283
- return false;
284
- return sameSpeculativeWorktreeInput(speculated.worktree, await recaptureDeliveryWorktree(input, state));
285
- });
286
- return "kind" in observation
287
- ? observation
288
- : await decideAndAdmitDelivery(input, attempt, seat, observation, speculated);
289
- }
351
+ /**
352
+ * One delivery attempt: the repeatable physical preparation happens outside custody, then a single
353
+ * in-custody observation, witness validation, assembly, decision, and atomic publication.
354
+ */
290
355
  async function deliverAttempt(input, attempt) {
291
- const speculated = await speculateDelivery(input);
292
- return await privateStateSeatAttempt(input.scope, async (seat) => await deliverAttemptInPrivateStateSeat(input, attempt, seat, speculated), attemptDecisionWithSeatClose);
356
+ const external = await prepareExternalDelivery(input);
357
+ return await privateStateSeatAttempt(input.scope, async (seat) => {
358
+ const observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
359
+ const assembled = await assembleDeliveryAttempt(input, observation, external);
360
+ if (assembled.kind === "stale")
361
+ return STALE_PRIVATE_STATE_PREPARATION;
362
+ return await decideAndAdmitDelivery(input, attempt, seat, observation, assembled);
363
+ }, attemptDecisionWithSeatClose);
293
364
  }
294
365
  function isIntegrationConflict(refusal) {
295
366
  return refusal.kind === "integration-failed" && refusal.reason === "conflict";
@@ -417,6 +488,8 @@ export async function admitDeliveryOperation(input) {
417
488
  return await finishDeliverRefusal(input, result.refusal);
418
489
  if (result.kind === "publication-failed")
419
490
  return { kind: "retry", reason: result };
491
+ if (result.kind === "stale" || result.kind === "redecide")
492
+ continue;
420
493
  if (result.kind === "collision" && index + 1 === attempts.length)
421
494
  return { kind: "retry", reason: result };
422
495
  }
@@ -0,0 +1,181 @@
1
+ import { z } from "zod";
2
+ declare const observationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
+ kind: z.ZodLiteral<"admitted">;
4
+ contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ContractId, string>>;
5
+ fact: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
6
+ v: 1;
7
+ kind: "bind";
8
+ contract: import("../core/facts/types.js").ContractId;
9
+ entry: import("../core/facts/types.js").EntryUlid;
10
+ at: string;
11
+ actor?: import("../core/facts/types.js").ActorId;
12
+ data: Readonly<{
13
+ coordinates: import("../core/facts/types.js").ContractCoordinates;
14
+ terms: import("../core/facts/types.js").ContractTerms;
15
+ }>;
16
+ }> | Readonly<{
17
+ v: 1;
18
+ kind: "amend";
19
+ contract: import("../core/facts/types.js").ContractId;
20
+ entry: import("../core/facts/types.js").EntryUlid;
21
+ at: string;
22
+ actor?: import("../core/facts/types.js").ActorId;
23
+ data: Readonly<{
24
+ document: Readonly<{
25
+ bytes: string;
26
+ key: import("../core/facts/types.js").DocumentKey;
27
+ }>;
28
+ segments: readonly import("../core/facts/types.js").DocumentSegmentKey[];
29
+ gates: readonly import("../core/facts/types.js").Gate[];
30
+ after: readonly import("../core/facts/types.js").ContractId[];
31
+ }>;
32
+ }> | Readonly<{
33
+ v: 1;
34
+ kind: "bound";
35
+ contract: import("../core/facts/types.js").ContractId;
36
+ entry: import("../core/facts/types.js").EntryUlid;
37
+ at: string;
38
+ actor?: import("../core/facts/types.js").ActorId;
39
+ data: Readonly<Record<string, never>>;
40
+ }> | Readonly<{
41
+ v: 1;
42
+ kind: "deliver";
43
+ contract: import("../core/facts/types.js").ContractId;
44
+ entry: import("../core/facts/types.js").EntryUlid;
45
+ at: string;
46
+ actor?: import("../core/facts/types.js").ActorId;
47
+ data: Readonly<{
48
+ tenderSnapshot: import("../core/facts/types.js").SnapshotId;
49
+ integration: Readonly<{
50
+ predecessor: import("../core/facts/types.js").SnapshotId;
51
+ snapshot: import("../core/facts/types.js").SnapshotId;
52
+ changeId: import("../core/facts/types.js").ChangeId;
53
+ }>;
54
+ method: "squash";
55
+ policy: Readonly<{
56
+ requireBranchesToBeUpToDate: boolean;
57
+ }>;
58
+ }>;
59
+ }> | Readonly<{
60
+ v: 1;
61
+ kind: "reintegrated";
62
+ contract: import("../core/facts/types.js").ContractId;
63
+ entry: import("../core/facts/types.js").EntryUlid;
64
+ at: string;
65
+ actor?: import("../core/facts/types.js").ActorId;
66
+ data: Readonly<{
67
+ predecessor: import("../core/facts/types.js").SnapshotId;
68
+ snapshot: import("../core/facts/types.js").SnapshotId;
69
+ }>;
70
+ }> | Readonly<{
71
+ v: 1;
72
+ kind: "attestation";
73
+ contract: import("../core/facts/types.js").ContractId;
74
+ entry: import("../core/facts/types.js").EntryUlid;
75
+ at: string;
76
+ actor?: import("../core/facts/types.js").ActorId;
77
+ data: Readonly<{
78
+ gate: import("../core/facts/types.js").Gate;
79
+ subject: import("../core/facts/types.js").DependencyKeySet;
80
+ verdict: "satisfied" | "unsatisfied";
81
+ summary?: string;
82
+ }>;
83
+ }> | Readonly<{
84
+ v: 1;
85
+ kind: "claimed";
86
+ contract: import("../core/facts/types.js").ContractId;
87
+ entry: import("../core/facts/types.js").EntryUlid;
88
+ at: string;
89
+ actor?: import("../core/facts/types.js").ActorId;
90
+ data: Readonly<{
91
+ delivery: import("../core/facts/types.js").EntryUlid;
92
+ }>;
93
+ }> | Readonly<{
94
+ v: 1;
95
+ kind: "arc";
96
+ contract: import("../core/facts/types.js").ContractId;
97
+ entry: import("../core/facts/types.js").EntryUlid;
98
+ at: string;
99
+ actor?: import("../core/facts/types.js").ActorId;
100
+ data: Readonly<{
101
+ seq: number;
102
+ title: string;
103
+ objective: string;
104
+ brief: string;
105
+ }>;
106
+ }> | Readonly<{
107
+ v: 1;
108
+ kind: "abandoned";
109
+ contract: import("../core/facts/types.js").ContractId;
110
+ entry: import("../core/facts/types.js").EntryUlid;
111
+ at: string;
112
+ actor?: import("../core/facts/types.js").ActorId;
113
+ data: Readonly<{
114
+ note?: string;
115
+ }>;
116
+ }>, unknown>>;
117
+ }, z.core.$strict>, z.ZodObject<{
118
+ kind: z.ZodLiteral<"verification">;
119
+ contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ContractId, string>>;
120
+ snapshot: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
121
+ observation: z.ZodDiscriminatedUnion<[z.ZodObject<{
122
+ state: z.ZodEnum<{
123
+ finished: "finished";
124
+ started: "started";
125
+ }>;
126
+ outcome: z.ZodOptional<z.ZodString>;
127
+ elapsedMs: z.ZodOptional<z.ZodNumber>;
128
+ phase: z.ZodEnum<{
129
+ cleanup: "cleanup";
130
+ materialize: "materialize";
131
+ setup: "setup";
132
+ declaration: "declaration";
133
+ }>;
134
+ cwd: z.ZodOptional<z.ZodString>;
135
+ name: z.ZodOptional<z.ZodString>;
136
+ command: z.ZodOptional<z.ZodString>;
137
+ index: z.ZodOptional<z.ZodNumber>;
138
+ total: z.ZodOptional<z.ZodNumber>;
139
+ kind: z.ZodLiteral<"phase">;
140
+ }, z.core.$strict>, z.ZodObject<{
141
+ stream: z.ZodEnum<{
142
+ stdout: "stdout";
143
+ stderr: "stderr";
144
+ }>;
145
+ text: z.ZodString;
146
+ phase: z.ZodEnum<{
147
+ cleanup: "cleanup";
148
+ materialize: "materialize";
149
+ setup: "setup";
150
+ declaration: "declaration";
151
+ }>;
152
+ cwd: z.ZodOptional<z.ZodString>;
153
+ name: z.ZodOptional<z.ZodString>;
154
+ command: z.ZodOptional<z.ZodString>;
155
+ index: z.ZodOptional<z.ZodNumber>;
156
+ total: z.ZodOptional<z.ZodNumber>;
157
+ kind: z.ZodLiteral<"output">;
158
+ }, z.core.$strict>], "kind">;
159
+ }, z.core.$strict>, z.ZodObject<{
160
+ kind: z.ZodLiteral<"stage">;
161
+ contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ContractId, string>>;
162
+ stage: z.ZodEnum<{
163
+ placement: "placement";
164
+ continuation: "continuation";
165
+ reconciliation: "reconciliation";
166
+ }>;
167
+ state: z.ZodEnum<{
168
+ finished: "finished";
169
+ started: "started";
170
+ }>;
171
+ }, z.core.$strict>, z.ZodObject<{
172
+ kind: z.ZodLiteral<"progress-dropped">;
173
+ count: z.ZodNumber;
174
+ }, z.core.$strict>], "kind">;
175
+ export type ExecutionEvent = z.infer<typeof observationSchema>;
176
+ export type ExecutionObserver = (event: ExecutionEvent) => void;
177
+ /** One owner decoder for local and transported ephemeral observations. */
178
+ export declare function decodeExecutionEvent(value: unknown): ExecutionEvent;
179
+ /** Observation failure cannot change execution, admission, or process custody. */
180
+ export declare function observeExecution(observer: ExecutionObserver | undefined, event: ExecutionEvent): void;
181
+ export {};
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import { decodeJournalEntry } from "../core/facts/codec.js";
3
+ import { contractId, snapshotId } from "../core/facts/types.js";
4
+ import { verificationObservationSchema } from "../verification/observation.js";
5
+ const contract = z.string().transform((value) => contractId(value));
6
+ const snapshot = z.string().transform((value) => snapshotId(value));
7
+ const observationSchema = z.discriminatedUnion("kind", [
8
+ z
9
+ .object({
10
+ kind: z.literal("admitted"),
11
+ contractId: contract,
12
+ fact: z.unknown().transform(decodeJournalEntry),
13
+ })
14
+ .strict(),
15
+ z
16
+ .object({
17
+ kind: z.literal("verification"),
18
+ contractId: contract,
19
+ snapshot,
20
+ observation: verificationObservationSchema,
21
+ })
22
+ .strict(),
23
+ z
24
+ .object({
25
+ kind: z.literal("stage"),
26
+ contractId: contract,
27
+ stage: z.enum(["placement", "continuation", "reconciliation"]),
28
+ state: z.enum(["started", "finished"]),
29
+ })
30
+ .strict(),
31
+ z.object({ kind: z.literal("progress-dropped"), count: z.number().int().positive() }).strict(),
32
+ ]);
33
+ /** One owner decoder for local and transported ephemeral observations. */
34
+ export function decodeExecutionEvent(value) {
35
+ return observationSchema.parse(value);
36
+ }
37
+ /** Observation failure cannot change execution, admission, or process custody. */
38
+ export function observeExecution(observer, event) {
39
+ try {
40
+ observer?.(event);
41
+ }
42
+ catch {
43
+ // A consumer controls observation only, not the operation being observed.
44
+ }
45
+ }
@@ -2,43 +2,39 @@ import type { ExecutionProgress } from "./progress.js";
2
2
  import type { GitDecisionObservation } from "../git/observe.js";
3
3
  import type { GitDecodeChannel, GitTreeSelection } from "../git/read-observation.js";
4
4
  import type { GitRepository } from "../git/process.js";
5
- import type { GitRefAssertion } from "../git/repository.js";
6
5
  import { type WorktreeLeak } from "../git/scratch.js";
7
6
  import type { HookFailure } from "../git/hooks.js";
8
7
  import type { DecideInput, OfferDecision } from "../core/decide.js";
9
8
  import type { ActorId, ContractId, ContractState, EntryUlid, SnapshotId } from "../core/facts/types.js";
10
9
  import { type AttestationRefusal } from "../core/verbs/attestation.js";
10
+ import { type CapturedOutput } from "../verification/execution.js";
11
11
  import { type VerificationDefinition } from "../verification/declaration.js";
12
- import { type CompanionDecorator, type ProtocolResult } from "./run.js";
13
- type IntentAdmissionOptions<Input, Refusal, Seed> = Readonly<{
12
+ import { type CompanionDecorator, type ProtocolPreparation, type ProtocolResult } from "./run.js";
13
+ type CommonIntentAdmissionOptions<Refusal> = Readonly<{
14
14
  progress?: ExecutionProgress;
15
15
  observedContracts?: readonly ContractId[];
16
16
  observe?: (repository: GitRepository, channel: GitDecodeChannel, contracts: readonly ContractId[]) => Promise<GitDecisionObservation>;
17
17
  decorateOffer?: CompanionDecorator;
18
18
  validateAdmission?: (observation: GitDecisionObservation) => Refusal | undefined | Promise<Refusal | undefined>;
19
19
  observationSelection?: GitTreeSelection;
20
- prepareInput?: (observation: GitDecisionObservation, input: Seed) => Readonly<{
21
- kind: "prepared";
22
- input: Input;
23
- assertions?: readonly GitRefAssertion[];
24
- }> | Readonly<{
25
- kind: "refused";
26
- refusal: Refusal;
27
- }> | Promise<Readonly<{
28
- kind: "prepared";
29
- input: Input;
30
- assertions?: readonly GitRefAssertion[];
31
- }> | Readonly<{
32
- kind: "refused";
33
- refusal: Refusal;
34
- }>>;
35
20
  }>;
36
- /** Observe, decide, and atomically admit one intent with bounded Git retries. */
21
+ type IntentAdmissionOptions<Refusal = never> = CommonIntentAdmissionOptions<Refusal>;
22
+ type PreparedIntentAdmissionOptions<Input, Refusal, Seed, Prepared> = CommonIntentAdmissionOptions<Refusal> & Readonly<{
23
+ preparation: ProtocolPreparation<Input, Refusal, Seed, Prepared>;
24
+ }>;
25
+ /** Observe, decide, and atomically admit one intent whose invocation already is its decision input. */
37
26
  export declare function admitIntent<Input extends Readonly<{
38
27
  contractId: ContractId;
28
+ }>, Refusal>(channel: GitDecodeChannel, repository: GitRepository, input: Input, decide: (input: DecideInput<Input>) => OfferDecision<Refusal>, options?: IntentAdmissionOptions<Refusal>): Promise<ProtocolResult<Refusal>>;
29
+ /**
30
+ * Observe, decide, and atomically admit one intent whose repeatable preparation happens outside
31
+ * the publication seat and whose decision input is assembled from the fresh in-custody observation.
32
+ */
33
+ export declare function admitPreparedIntent<Input extends Readonly<{
34
+ contractId: ContractId;
39
35
  }>, Refusal, Seed extends Readonly<{
40
36
  contractId: ContractId;
41
- }> = Input>(channel: GitDecodeChannel, repository: GitRepository, input: Seed, decide: (input: DecideInput<Input>) => OfferDecision<Refusal>, options?: IntentAdmissionOptions<Input, Refusal, Seed>): Promise<ProtocolResult<Refusal>>;
37
+ }>, Prepared>(channel: GitDecodeChannel, repository: GitRepository, input: Seed, decide: (input: DecideInput<Input>) => OfferDecision<Refusal>, options: PreparedIntentAdmissionOptions<Input, Refusal, Seed, Prepared>): Promise<ProtocolResult<Refusal>>;
42
38
  type VerifyDeliveryInput = Readonly<{
43
39
  channel: GitDecodeChannel;
44
40
  repository: GitRepository;
@@ -51,7 +47,7 @@ type VerifyDeliveryInput = Readonly<{
51
47
  verification?: VerificationDefinition;
52
48
  progress?: ExecutionProgress;
53
49
  }>;
54
- export type VerificationRuntimeStop = Readonly<{
50
+ export type VerificationRuntimeStop = CapturedOutput & (Readonly<{
55
51
  failure: "unknown-exit" | "cancelled";
56
52
  }> | Readonly<{
57
53
  failure: "candidate-unavailable" | "spawn-error";
@@ -63,7 +59,7 @@ export type VerificationRuntimeStop = Readonly<{
63
59
  failure: "environment-failure";
64
60
  name: string;
65
61
  detail: HookFailure;
66
- }>;
62
+ }>);
67
63
  export type VerificationCleanupFailure = Readonly<{
68
64
  phase: "destroy";
69
65
  name: string;