@astrosheep/keiyaku 4.6.4 → 4.6.7

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 (247) hide show
  1. package/README.md +7 -0
  2. package/build/{integrations/marketplace → plugins}/.agents/plugins/marketplace.json +1 -1
  3. package/build/plugins/.claude-plugin/marketplace.json +5 -0
  4. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/.claude-plugin/plugin.json +1 -1
  5. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-akuma/SKILL.md +43 -8
  6. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/SKILL.md +7 -8
  7. package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-workflow/SKILL.md +3 -3
  8. package/build/{integrations/marketplace/plugins/keiyaku → plugins/codex}/.codex-plugin/plugin.json +1 -1
  9. package/build/plugins/codex/skills/keiyaku/SKILL.md +44 -0
  10. package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +130 -0
  11. package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +269 -0
  12. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +65 -0
  13. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +216 -0
  14. package/build/plugins/codex/skills/keiyaku-bind/agents/openai.yaml +4 -0
  15. package/build/plugins/codex/skills/keiyaku-task/SKILL.md +104 -0
  16. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +129 -0
  17. package/build/plugins/opencode/package.json +6 -0
  18. package/build/plugins/opencode/skills/keiyaku/SKILL.md +44 -0
  19. package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +130 -0
  20. package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +269 -0
  21. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +65 -0
  22. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +216 -0
  23. package/build/plugins/opencode/skills/keiyaku-bind/agents/openai.yaml +4 -0
  24. package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +104 -0
  25. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +129 -0
  26. package/build/skills/keiyaku/SKILL.md +44 -0
  27. package/build/skills/keiyaku-akuma/SKILL.md +130 -0
  28. package/build/skills/keiyaku-akuma/references/automation.md +269 -0
  29. package/build/skills/keiyaku-babysit/SKILL.md +65 -0
  30. package/build/skills/keiyaku-bind/SKILL.md +216 -0
  31. package/build/skills/keiyaku-bind/agents/openai.yaml +4 -0
  32. package/build/skills/keiyaku-task/SKILL.md +104 -0
  33. package/build/skills/keiyaku-workflow/SKILL.md +129 -0
  34. package/build/src/akuma/akuma-instance.js +7 -5
  35. package/build/src/akuma/akuma-observe.d.ts +22 -15
  36. package/build/src/akuma/akuma-observe.js +87 -16
  37. package/build/src/akuma/akuma-owner.d.ts +3 -2
  38. package/build/src/akuma/akuma-owner.js +28 -10
  39. package/build/src/akuma/akuma-selection-execution.d.ts +3 -1
  40. package/build/src/akuma/akuma-selection-execution.js +2 -1
  41. package/build/src/akuma/akuma-wait.d.ts +6 -4
  42. package/build/src/akuma/akuma-wait.js +78 -53
  43. package/build/src/akuma/akuma.d.ts +6 -4
  44. package/build/src/akuma/akuma.js +4 -0
  45. package/build/src/akuma/body.d.ts +1 -0
  46. package/build/src/akuma/body.js +12 -23
  47. package/build/src/akuma/call-initial-tell.d.ts +2 -2
  48. package/build/src/akuma/call-initial-tell.js +1 -1
  49. package/build/src/akuma/call-request.d.ts +2 -2
  50. package/build/src/akuma/heart/index.d.ts +7 -2
  51. package/build/src/akuma/heart/index.js +50 -5
  52. package/build/src/akuma/heart/tells.d.ts +33 -2
  53. package/build/src/akuma/heart/tells.js +24 -18
  54. package/build/src/akuma/heart/timeline.d.ts +23 -1
  55. package/build/src/akuma/heart/timeline.js +28 -21
  56. package/build/src/akuma/projection.d.ts +10 -10
  57. package/build/src/akuma/providers/pi/index.js +72 -39
  58. package/build/src/akuma/selection-observation.d.ts +20 -20
  59. package/build/src/akuma/selection-owner-port.d.ts +1 -1
  60. package/build/src/akuma/selection-owner-port.js +16 -5
  61. package/build/src/akuma/selection-request.d.ts +2 -0
  62. package/build/src/akuma/selection-request.js +2 -1
  63. package/build/src/akuma-body.js +5 -2
  64. package/build/src/alias/index.d.ts +0 -1
  65. package/build/src/alias/index.js +0 -4
  66. package/build/src/body/amend.d.ts +0 -4
  67. package/build/src/body/amend.js +0 -3
  68. package/build/src/body/region.d.ts +0 -1
  69. package/build/src/body/region.js +0 -3
  70. package/build/src/body/verification.d.ts +0 -1
  71. package/build/src/cli/commands/akuma-grammar.js +23 -66
  72. package/build/src/cli/commands/akuma.js +23 -42
  73. package/build/src/cli/commands/contract-grammar.d.ts +14 -1
  74. package/build/src/cli/commands/contract-grammar.js +54 -21
  75. package/build/src/cli/commands/contract-help.d.ts +9 -8
  76. package/build/src/cli/commands/contract-help.js +14 -7
  77. package/build/src/cli/commands/contract.js +57 -117
  78. package/build/src/cli/commands/install.d.ts +5 -5
  79. package/build/src/cli/commands/install.js +4 -7
  80. package/build/src/cli/commands/task-grammar.js +10 -66
  81. package/build/src/cli/commands/task.d.ts +0 -1
  82. package/build/src/cli/commands/task.js +34 -53
  83. package/build/src/cli/coordinates.d.ts +1 -2
  84. package/build/src/cli/coordinates.js +1 -4
  85. package/build/src/cli/parse.d.ts +2 -3
  86. package/build/src/cli/parse.js +24 -66
  87. package/build/src/cli/render/akuma.d.ts +3 -16
  88. package/build/src/cli/render/akuma.js +1 -13
  89. package/build/src/cli/render/audit.js +1 -1
  90. package/build/src/cli/render/contract.js +34 -32
  91. package/build/src/cli/render/kanshi-akuma.d.ts +8 -2
  92. package/build/src/cli/render/kanshi-akuma.js +14 -7
  93. package/build/src/cli/render/kanshi.d.ts +3 -1
  94. package/build/src/cli/render/kanshi.js +44 -32
  95. package/build/src/cli/render/receipt.js +6 -1
  96. package/build/src/cli/render/task.d.ts +1 -1
  97. package/build/src/cli/render/task.js +3 -27
  98. package/build/src/cli/render/terminal.d.ts +6 -2
  99. package/build/src/cli/render/terminal.js +8 -2
  100. package/build/src/cli/runtime.js +3 -16
  101. package/build/src/cli/scan.d.ts +26 -0
  102. package/build/src/cli/scan.js +82 -0
  103. package/build/src/cli/streams.d.ts +5 -0
  104. package/build/src/cli/streams.js +11 -0
  105. package/build/src/contract-worktree.js +38 -21
  106. package/build/src/core/facts/codec.d.ts +1 -2
  107. package/build/src/core/facts/codec.js +5 -11
  108. package/build/src/core/facts/types.d.ts +16 -2
  109. package/build/src/core/facts/types.js +15 -0
  110. package/build/src/core/verbs/abandon.js +3 -9
  111. package/build/src/core/verbs/amend.js +2 -9
  112. package/build/src/core/verbs/arc.js +6 -13
  113. package/build/src/core/verbs/attestation.js +2 -9
  114. package/build/src/core/verbs/bind.js +2 -9
  115. package/build/src/core/verbs/deliver.js +2 -9
  116. package/build/src/core/verbs/placement.d.ts +1 -1
  117. package/build/src/core/verbs/placement.js +2 -9
  118. package/build/src/core/verbs/reintegrate.d.ts +1 -1
  119. package/build/src/core/verbs/reintegrate.js +2 -9
  120. package/build/src/dispatch/index.d.ts +2 -2
  121. package/build/src/dispatch/index.js +33 -11
  122. package/build/src/git/hooks.d.ts +2 -4
  123. package/build/src/git/hooks.js +0 -12
  124. package/build/src/git/integration.d.ts +5 -3
  125. package/build/src/git/integration.js +36 -25
  126. package/build/src/git/nuke.js +4 -4
  127. package/build/src/git/observe.d.ts +4 -4
  128. package/build/src/git/observe.js +5 -5
  129. package/build/src/git/process.d.ts +1 -4
  130. package/build/src/git/process.js +1 -11
  131. package/build/src/git/read-observation.js +1 -1
  132. package/build/src/git/reconcile.d.ts +1 -1
  133. package/build/src/git/reconcile.js +15 -13
  134. package/build/src/git/repository.d.ts +2 -6
  135. package/build/src/git/repository.js +18 -31
  136. package/build/src/git/scratch.d.ts +6 -6
  137. package/build/src/git/scratch.js +110 -46
  138. package/build/src/git/target-placement.d.ts +5 -5
  139. package/build/src/git/target-placement.js +18 -33
  140. package/build/src/git/tender.d.ts +6 -2
  141. package/build/src/git/tender.js +19 -12
  142. package/build/src/git/terminal-reconcile.js +24 -13
  143. package/build/src/git/terminal-seal.d.ts +2 -5
  144. package/build/src/git/terminal-seal.js +5 -3
  145. package/build/src/git/workspace.d.ts +17 -13
  146. package/build/src/git/workspace.js +58 -41
  147. package/build/src/kanshi/index.d.ts +2 -2
  148. package/build/src/kanshi/index.js +1 -1
  149. package/build/src/kanshi/read.d.ts +8 -1
  150. package/build/src/kanshi/read.js +72 -7
  151. package/build/src/kanshi/report.d.ts +12 -0
  152. package/build/src/library/akuma-creation.d.ts +4 -4
  153. package/build/src/library/akuma-creation.js +21 -19
  154. package/build/src/library/bind.d.ts +1 -63
  155. package/build/src/library/bind.js +3 -9
  156. package/build/src/library/contract-creation.js +2 -30
  157. package/build/src/library/contract-execution.d.ts +0 -1
  158. package/build/src/library/contract-execution.js +9 -34
  159. package/build/src/library/contract-operations.d.ts +5 -1
  160. package/build/src/library/contract-operations.js +7 -3
  161. package/build/src/library/contract-types.d.ts +1 -1
  162. package/build/src/library/delivery.d.ts +91 -93
  163. package/build/src/library/delivery.js +2 -1
  164. package/build/src/library/input.d.ts +0 -2
  165. package/build/src/library/input.js +0 -4
  166. package/build/src/library/invocation.d.ts +0 -1
  167. package/build/src/library/invocation.js +3 -25
  168. package/build/src/library/outcome.d.ts +651 -602
  169. package/build/src/library/outcome.js +4 -4
  170. package/build/src/library/reconcile.d.ts +6 -0
  171. package/build/src/library/reconcile.js +31 -1
  172. package/build/src/library/repo.d.ts +0 -1
  173. package/build/src/library/selection.d.ts +1 -10
  174. package/build/src/library/selection.js +19 -17
  175. package/build/src/plugin/akuma-signals.d.ts +10 -11
  176. package/build/src/plugin/akuma-signals.js +36 -20
  177. package/build/src/plugin/public.d.ts +5 -0
  178. package/build/src/plugin/runtime.d.ts +1 -0
  179. package/build/src/plugin/runtime.js +34 -23
  180. package/build/src/protocol/abandon.d.ts +1 -1
  181. package/build/src/protocol/abandon.js +3 -10
  182. package/build/src/protocol/amend.js +2 -5
  183. package/build/src/protocol/arc.d.ts +1 -1
  184. package/build/src/protocol/arc.js +2 -9
  185. package/build/src/protocol/attempt.d.ts +3 -20
  186. package/build/src/protocol/attempt.js +6 -5
  187. package/build/src/protocol/audit.d.ts +1 -0
  188. package/build/src/protocol/audit.js +10 -11
  189. package/build/src/protocol/completion.d.ts +129 -55
  190. package/build/src/protocol/completion.js +62 -73
  191. package/build/src/protocol/deliver.d.ts +7 -5
  192. package/build/src/protocol/deliver.js +74 -44
  193. package/build/src/protocol/execution-observation.d.ts +2 -4
  194. package/build/src/protocol/execution-observation.js +3 -7
  195. package/build/src/protocol/intent.d.ts +1 -1
  196. package/build/src/protocol/intent.js +1 -0
  197. package/build/src/protocol/operations.d.ts +24 -12
  198. package/build/src/protocol/operations.js +36 -15
  199. package/build/src/protocol/placement.d.ts +2 -1
  200. package/build/src/protocol/placement.js +21 -5
  201. package/build/src/protocol/progress.d.ts +1 -1
  202. package/build/src/protocol/read/status.js +58 -41
  203. package/build/src/protocol/reintegrate.d.ts +1 -1
  204. package/build/src/protocol/reintegrate.js +10 -19
  205. package/build/src/protocol/review.d.ts +3 -28
  206. package/build/src/protocol/review.js +10 -37
  207. package/build/src/protocol/run.d.ts +19 -7
  208. package/build/src/protocol/run.js +19 -9
  209. package/build/src/runtime/proc/windows-launch.exe +0 -0
  210. package/build/src/settlement/holder.d.ts +2 -4
  211. package/build/src/settlement/holder.js +3 -6
  212. package/build/src/task/board.d.ts +6 -0
  213. package/build/src/task/board.js +30 -1
  214. package/build/src/task/catalog.js +1 -4
  215. package/build/src/task/compose.d.ts +0 -1
  216. package/build/src/task/compose.js +0 -1
  217. package/build/src/task/context.d.ts +0 -1
  218. package/build/src/task/context.js +0 -3
  219. package/build/src/task/created-observation.d.ts +5 -1
  220. package/build/src/task/created-observation.js +12 -5
  221. package/build/src/task/index.d.ts +1 -1
  222. package/build/src/task/index.js +7 -6
  223. package/build/src/task/input.d.ts +0 -6
  224. package/build/src/task/input.js +2 -14
  225. package/build/src/task/mutation.d.ts +3 -4
  226. package/build/src/task/mutation.js +11 -39
  227. package/build/src/task/operations.d.ts +2 -7
  228. package/build/src/task/operations.js +37 -49
  229. package/build/src/task/query.d.ts +0 -1
  230. package/build/src/task/query.js +1 -4
  231. package/build/src/task/store.d.ts +0 -2
  232. package/build/src/task/store.js +27 -11
  233. package/build/src/verification/declaration.js +3 -2
  234. package/build/src/verification/execution.d.ts +3 -2
  235. package/build/src/verification/execution.js +10 -6
  236. package/build/src/workspace-place.d.ts +0 -1
  237. package/build/src/workspace-place.js +0 -11
  238. package/package.json +13 -9
  239. package/build/integrations/marketplace/.claude-plugin/marketplace.json +0 -5
  240. package/build/integrations/marketplace/plugins/keiyaku/package.json +0 -17
  241. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku/SKILL.md +0 -0
  242. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-akuma/references/automation.md +0 -0
  243. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-babysit/SKILL.md +0 -0
  244. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/agents/openai.yaml +0 -0
  245. /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-task/SKILL.md +0 -0
  246. /package/build/{integrations/marketplace/plugins/keiyaku/opencode.js → plugins/opencode/index.js} +0 -0
  247. /package/build/{integrations → plugins}/pi/keiyaku.ts +0 -0
@@ -2,19 +2,23 @@ import { entryUlidSchema } from "./attempt.js";
2
2
  import { z } from "zod";
3
3
  import { snapshotIdSchema } from "./operations.js";
4
4
  import { conflictRecoverySchema, worktreeWorkspaceSchema } from "../git/workspace.js";
5
- import { materializeIntegrationSnapshot, materializeJudgedConflict, planIntegration, worktreeChangeId, } from "../git/integration.js";
5
+ import { materializeIntegrationSnapshot, materializeJudgedConflict, planIntegration, reusableIntegrationSnapshot, worktreeChangeId, } from "../git/integration.js";
6
6
  import { captureTender, dirtyTenderRefusal, materializeTenderSnapshot, prepareDeliveryCommitMetadata, } from "../git/tender.js";
7
7
  import { checkoutDetachedSnapshot, recordConflictHandoff, retireConflictHandoff, workspaceMergeStatePresent, worktreePath, conflictRecovery, } from "../git/workspace.js";
8
8
  import { observeContractsForAdmissionAt } from "../git/observe.js";
9
- import { contractStateWitness, privateStateSeatAttempt, runBoundedAttempts, sameWorktreeWitness, STALE_PRIVATE_STATE_PREPARATION, } from "./run.js";
9
+ import { externalPreparation, privateStateSeatAttempt, runBoundedAttempts, sameWorktreeWitness, STALE_PRIVATE_STATE_PREPARATION, } from "./run.js";
10
10
  import { contractState } from "../core/facts/observation.js";
11
11
  import { decideDeliver } from "../core/verbs/deliver.js";
12
12
  import { currentVerifiedAttestation } from "./intent.js";
13
13
  import { admitDecidedOffer, mintAttempts } from "./attempt.js";
14
14
  import { appointmentFor, readPlaceRegister } from "../workspace-place.js";
15
- import { attemptDecisionWithSeatClose, timestamp } from "./operations.js";
15
+ import { attemptDecisionWithSeatClose, recordedIntegrationSnapshots, timestamp } from "./operations.js";
16
16
  export const deliverLeadingSchema = z
17
- .object({ kind: z.enum(["admitted-now", "already-admitted"]), fact: entryUlidSchema })
17
+ .object({
18
+ kind: z.enum(["admitted-now", "already-admitted"]),
19
+ fact: entryUlidSchema,
20
+ reusedIntegration: snapshotIdSchema.optional(),
21
+ })
18
22
  .strict();
19
23
  export const materializedConflictSchema = z
20
24
  .object({
@@ -69,12 +73,16 @@ async function prepareDeliveryWithWorktree(repository, stage, input, captured) {
69
73
  if (integration.kind === "refused")
70
74
  return integration;
71
75
  const changeId = await worktreeChangeId(repository, { contractId, coordinates }, tender.data);
72
- const integrationSnapshot = coordinates.target === undefined
73
- ? tenderSnapshot
74
- : await materializeIntegrationSnapshot(repository, integration.data.tree, integration.data.predecessor, commit);
76
+ const reusedIntegration = await reusableIntegrationSnapshot(repository, integration.data.tree, integration.data.predecessor, stage.recordedIntegrations ?? []);
77
+ const integrationSnapshot = reusedIntegration ??
78
+ (coordinates.target === undefined
79
+ ? tenderSnapshot
80
+ : await materializeIntegrationSnapshot(repository, integration.data.tree, integration.data.predecessor, commit));
75
81
  return {
76
82
  kind: "prepared",
83
+ ...(reusedIntegration === undefined ? {} : { reusedIntegration }),
77
84
  data: {
85
+ ...(input.message === undefined ? {} : { note: input.message }),
78
86
  tenderSnapshot,
79
87
  integration: {
80
88
  predecessor: integration.data.predecessor,
@@ -119,8 +127,12 @@ async function recaptureDeliveryWorktree(input, state) {
119
127
  changeId: await worktreeChangeId(input.scope, { contractId: state.id, coordinates: state.coordinates }, tender.data),
120
128
  };
121
129
  }
122
- async function mechanicalDeliveryPreparation(input, state, derivation, captured) {
123
- const prepared = await prepareDeliveryWithWorktree(input.scope, { contractId: state.id, coordinates: state.coordinates }, deliveryPreparationInput(input, derivation), captured);
130
+ async function mechanicalDeliveryPreparation(input, state, derivation, journal, captured) {
131
+ const prepared = await prepareDeliveryWithWorktree(input.scope, {
132
+ contractId: state.id,
133
+ coordinates: state.coordinates,
134
+ recordedIntegrations: recordedIntegrationSnapshots(journal),
135
+ }, deliveryPreparationInput(input, derivation), captured);
124
136
  if (prepared.kind === "refused") {
125
137
  return { kind: "refused", document: derivation.document, refusal: prepared.refusal };
126
138
  }
@@ -129,6 +141,7 @@ async function mechanicalDeliveryPreparation(input, state, derivation, captured)
129
141
  document: derivation.document,
130
142
  data: prepared.data,
131
143
  worktree: prepared.worktree,
144
+ ...(prepared.reusedIntegration === undefined ? {} : { reusedIntegration: prepared.reusedIntegration }),
132
145
  };
133
146
  }
134
147
  function worktreeInput(repository, state, tender) {
@@ -155,28 +168,21 @@ function hasSupersedingVerification(state, journal) {
155
168
  * one non-authoritative private-state read, capture its bytes, and materialize the prepared artifacts.
156
169
  */
157
170
  async function prepareExternalDelivery(input) {
158
- const observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
159
- const state = contractState(observation.decision, input.contractId);
160
- if (state === null)
161
- return { kind: "unavailable" };
162
- return {
163
- kind: "artifacts",
164
- witness: contractStateWitness(state),
165
- artifacts: await prepareDeliveryArtifacts(input, observation, state),
166
- };
171
+ return await externalPreparation(input, (observation, state) => prepareDeliveryArtifacts(input, observation, state));
167
172
  }
168
173
  async function prepareDeliveryArtifacts(input, observation, state) {
169
174
  const derivation = input.deriveDocument(state);
170
175
  if (derivation.verification.kind === "refused")
171
176
  return { kind: "defer" };
172
- if (reusesCurrentCandidate(input, state, derivation))
173
- return { kind: "defer" };
174
177
  if (input.materializeConflict === true && state.terminal === null)
175
178
  return { kind: "defer" };
176
179
  const captured = await captureAuthorizedDeliveryTender(input.scope, { contractId: state.id, coordinates: state.coordinates }, input.includeDirty);
177
180
  if (captured.kind === "refused")
178
181
  return { kind: "refused", refusal: captured.refusal };
179
182
  const worktree = await worktreeInput(input.scope, state, captured.data);
183
+ if (reusesCurrentCandidate(input, state, derivation, worktree.changeId)) {
184
+ return { kind: "reuse", worktree };
185
+ }
180
186
  if (state.terminal === null &&
181
187
  state.delivery !== null &&
182
188
  worktree.changeId === state.delivery.data.integration.changeId &&
@@ -186,9 +192,14 @@ async function prepareDeliveryArtifacts(input, observation, state) {
186
192
  worktree,
187
193
  };
188
194
  }
189
- const prepared = await mechanicalDeliveryPreparation(input, state, derivation, captured.data);
195
+ const prepared = await mechanicalDeliveryPreparation(input, state, derivation, observation.journals.get(state.id)?.entries ?? [], captured.data);
190
196
  return prepared.kind === "prepared"
191
- ? { kind: "mechanical", data: prepared.data, worktree: prepared.worktree }
197
+ ? {
198
+ kind: "mechanical",
199
+ data: prepared.data,
200
+ worktree: prepared.worktree,
201
+ ...(prepared.reusedIntegration === undefined ? {} : { reusedIntegration: prepared.reusedIntegration }),
202
+ }
192
203
  : { kind: "refused", refusal: prepared.refusal };
193
204
  }
194
205
  /**
@@ -215,11 +226,9 @@ async function assembleDeliveryAttempt(input, observation, external) {
215
226
  preparation: { kind: "refused", document: derivation.document, refusal: derivation.verification.refusal },
216
227
  };
217
228
  }
218
- if (reusesCurrentCandidate(input, state, derivation))
219
- return { kind: "assembled", state, derivation };
220
229
  const artifacts = external.artifacts;
221
230
  if (artifacts.kind === "defer")
222
- return await completeDeferredDelivery(input, state, derivation);
231
+ return await completeDeferredDelivery(input, state, derivation, observation.journals.get(state.id)?.entries ?? []);
223
232
  if (artifacts.kind === "refused") {
224
233
  return {
225
234
  kind: "assembled",
@@ -231,6 +240,11 @@ async function assembleDeliveryAttempt(input, observation, external) {
231
240
  if (!sameWorktreeWitness(artifacts.worktree, await recaptureDeliveryWorktree(input, state))) {
232
241
  return { kind: "stale" };
233
242
  }
243
+ if (artifacts.kind === "reuse") {
244
+ return reusesCurrentCandidate(input, state, derivation, artifacts.worktree.changeId)
245
+ ? { kind: "assembled", state, derivation, reuse: true }
246
+ : { kind: "stale" };
247
+ }
234
248
  if (artifacts.kind === "continuation") {
235
249
  const delivery = state.delivery;
236
250
  if (delivery === null)
@@ -248,16 +262,21 @@ async function assembleDeliveryAttempt(input, observation, external) {
248
262
  state,
249
263
  derivation,
250
264
  preparation: { kind: "prepared", document: derivation.document, data: artifacts.data },
265
+ ...(artifacts.reusedIntegration === undefined ? {} : { reusedIntegration: artifacts.reusedIntegration }),
251
266
  };
252
267
  }
253
268
  /**
254
269
  * Complete a preparation the outside phase could not settle. A requested conflict materialization
255
270
  * must retire its owned handoff and then capture the worktree that follows, so it only runs under
256
- * this custody; every other deferred state is decided by reuse above or refuses on its own.
271
+ * this custody; an unchanged candidate may still be reused before that materialization.
257
272
  */
258
- async function completeDeferredDelivery(input, state, derivation) {
273
+ async function completeDeferredDelivery(input, state, derivation, journal) {
259
274
  if (input.materializeConflict !== true || state.terminal !== null)
260
275
  return { kind: "assembled", state, derivation };
276
+ const worktree = await recaptureDeliveryWorktree(input, state);
277
+ if (worktree !== undefined && reusesCurrentCandidate(input, state, derivation, worktree.changeId)) {
278
+ return { kind: "assembled", state, derivation, reuse: true };
279
+ }
261
280
  const materialization = await materializationMergeStateRefusal(input);
262
281
  if (materialization !== undefined) {
263
282
  return {
@@ -267,30 +286,32 @@ async function completeDeferredDelivery(input, state, derivation) {
267
286
  preparation: { kind: "refused", document: derivation.document, refusal: materialization },
268
287
  };
269
288
  }
270
- const prepared = await mechanicalDeliveryPreparation(input, state, derivation);
289
+ const prepared = await mechanicalDeliveryPreparation(input, state, derivation, journal);
271
290
  return {
272
291
  kind: "assembled",
273
292
  state,
274
293
  derivation,
294
+ ...(prepared.kind !== "prepared" || prepared.reusedIntegration === undefined
295
+ ? {}
296
+ : { reusedIntegration: prepared.reusedIntegration }),
275
297
  preparation: prepared.kind === "prepared"
276
298
  ? { kind: "prepared", document: derivation.document, data: prepared.data }
277
299
  : prepared,
278
300
  };
279
301
  }
280
- function reusesCurrentCandidate(input, state, derivation) {
302
+ function reusesCurrentCandidate(input, state, derivation, changeId) {
281
303
  return (input.overwrite !== true &&
282
304
  state.terminal === null &&
283
305
  state.delivery !== null &&
284
306
  derivation.verification.kind === "prepared" &&
285
307
  derivation.verification.data !== null &&
286
- currentVerifiedAttestation(state) === undefined);
308
+ currentVerifiedAttestation(state) === undefined &&
309
+ state.delivery.data.integration.changeId === changeId);
287
310
  }
288
311
  /** Accept a delivery whose current candidate is already admitted, without admitting it again. */
289
312
  function currentCandidateDeliveryDecision(input, observation, assembled) {
290
313
  const state = assembled.state;
291
- if (state === null || assembled.derivation === undefined)
292
- return undefined;
293
- if (!reusesCurrentCandidate(input, state, assembled.derivation))
314
+ if (state === null || assembled.derivation === undefined || assembled.reuse !== true)
294
315
  return undefined;
295
316
  const record = observation.journals.get(input.contractId);
296
317
  const delivery = record?.entries.findLast((entry) => entry.kind === "deliver");
@@ -353,26 +374,35 @@ async function decideAndAdmitDelivery(input, attempt, seat, observation, assembl
353
374
  return { kind: "refused", refusal: decision.refusal };
354
375
  if (preparation.kind !== "prepared")
355
376
  throw new Error("offered delivery is missing its mechanical preparation");
356
- const admission = await admitDecidedOffer({
357
- channel: input.channel,
358
- repository: input.scope,
359
- seat,
360
- decisionObservation: observation,
361
- attempt,
362
- offer: decision.offer,
363
- primaryContract: input.contractId,
364
- ...(input.progress === undefined ? {} : { progress: input.progress }),
365
- });
377
+ const admission = await admitDecidedOffer({ ...input, seat, observation, attempt, offer: decision.offer });
366
378
  if (admission.kind !== "accepted")
367
379
  return admission;
368
380
  const deliverFact = admission.facts.find((fact) => fact.contract === input.contractId && fact.kind === "deliver");
369
381
  if (deliverFact?.kind !== "deliver")
370
382
  throw new Error("confirmed delivery requires its own receipt");
383
+ const previousChange = assembled.state?.delivery?.data.integration.changeId;
384
+ const currentChange = preparation.data.integration.changeId;
371
385
  return {
372
386
  ...admission,
373
387
  value: {
374
388
  ...preparation.data,
375
- leading: { kind: "admitted-now", fact: deliverFact.entry },
389
+ leading: {
390
+ kind: "admitted-now",
391
+ fact: deliverFact.entry,
392
+ ...(assembled.reusedIntegration === undefined ? {} : { reusedIntegration: assembled.reusedIntegration }),
393
+ },
394
+ ...(previousChange === undefined || previousChange === currentChange
395
+ ? {}
396
+ : {
397
+ contentChange: {
398
+ kind: "candidate-content-changed",
399
+ ...(assembled.state?.coordinates.target === undefined
400
+ ? {}
401
+ : { target: assembled.state.coordinates.target }),
402
+ previousChange,
403
+ currentChange,
404
+ },
405
+ }),
376
406
  },
377
407
  };
378
408
  }
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- declare const observationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
2
+ export declare const observationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
3
3
  kind: z.ZodLiteral<"admitted">;
4
4
  contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../index.js").ContractId, string>>;
5
5
  fact: z.ZodPipe<z.ZodUnknown, z.ZodTransform<Readonly<{
@@ -37,6 +37,7 @@ declare const observationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
37
37
  at: string;
38
38
  actor?: import("../index.js").ActorId;
39
39
  data: Readonly<{
40
+ note?: string;
40
41
  tenderSnapshot: import("../index.js").SnapshotId;
41
42
  integration: Readonly<{
42
43
  predecessor: import("../index.js").SnapshotId;
@@ -165,8 +166,5 @@ declare const observationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
165
166
  }, z.core.$strict>], "kind">;
166
167
  export type ExecutionObservation = z.infer<typeof observationSchema>;
167
168
  export type ExecutionObserver = (event: ExecutionObservation) => void | PromiseLike<void>;
168
- /** One owner decoder for local and transported ephemeral observations. */
169
- export declare function decodeExecutionObservation(value: unknown): ExecutionObservation;
170
169
  /** Observation failure cannot change execution, admission, or process custody. */
171
170
  export declare function observeExecution(observer: ExecutionObserver | undefined, event: ExecutionObservation): void;
172
- export {};
@@ -1,13 +1,13 @@
1
1
  import { z } from "zod";
2
- import { decodeJournalEntry } from "../core/facts/codec.js";
2
+ import { validateEntry } from "../core/facts/codec.js";
3
3
  import { contractIdSchema, snapshotIdSchema } from "../git/identity.js";
4
4
  import { verificationObservationSchema } from "../verification/observation.js";
5
- const observationSchema = z.discriminatedUnion("kind", [
5
+ export const observationSchema = z.discriminatedUnion("kind", [
6
6
  z
7
7
  .object({
8
8
  kind: z.literal("admitted"),
9
9
  contractId: contractIdSchema,
10
- fact: z.unknown().transform(decodeJournalEntry),
10
+ fact: z.unknown().transform(validateEntry),
11
11
  })
12
12
  .strict(),
13
13
  z
@@ -28,10 +28,6 @@ const observationSchema = z.discriminatedUnion("kind", [
28
28
  .strict(),
29
29
  z.object({ kind: z.literal("progress-dropped"), count: z.number().int().positive() }).strict(),
30
30
  ]);
31
- /** One owner decoder for local and transported ephemeral observations. */
32
- export function decodeExecutionObservation(value) {
33
- return observationSchema.parse(value);
34
- }
35
31
  /** Observation failure cannot change execution, admission, or process custody. */
36
32
  export function observeExecution(observer, event) {
37
33
  try {
@@ -17,7 +17,7 @@ type CommonIntentAdmissionOptions<Refusal> = Readonly<{
17
17
  validateAdmission?: (observation: GitDecisionObservation) => Refusal | undefined | Promise<Refusal | undefined>;
18
18
  observationSelection?: GitTreeSelection;
19
19
  }>;
20
- type IntentAdmissionOptions<Refusal = never> = CommonIntentAdmissionOptions<Refusal>;
20
+ export type IntentAdmissionOptions<Refusal = never> = CommonIntentAdmissionOptions<Refusal>;
21
21
  type PreparedIntentAdmissionOptions<Input, Refusal, Seed, Prepared> = CommonIntentAdmissionOptions<Refusal> & Readonly<{
22
22
  preparation: ProtocolPreparation<Input, Refusal, Seed, Prepared>;
23
23
  }>;
@@ -194,6 +194,7 @@ export async function verifyDelivery(input) {
194
194
  const execution = await executeVerification({
195
195
  repository: input.repository,
196
196
  candidate: snapshot,
197
+ contractId: input.contractId,
197
198
  declarations: input.verification.declarations,
198
199
  materializeScratchCandidate,
199
200
  projectSettings,
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import type { ContractId, ContractState, DeliverData, DocumentKey, SnapshotId } from "../core/facts/types.js";
2
+ import type { DecideInput, OfferDecision } from "../core/decide.js";
3
+ import type { ActorId, ContractId, ContractState, DeliverData, DocumentKey, JournalEntry, SnapshotId } from "../core/facts/types.js";
3
4
  import type { IntegrationPreparationRefusal } from "../git/integration.js";
4
5
  import { type PrivateStateSeatOutcome } from "../git/private-state-seat.js";
5
6
  import type { GitRepository } from "../git/process.js";
@@ -7,17 +8,19 @@ import { type GitDecodeChannel } from "../git/read-observation.js";
7
8
  import type { WorktreeLeak } from "../git/scratch.js";
8
9
  import type { VerificationDeclarationPreparation } from "../verification/declaration.js";
9
10
  import type { AcceptedAdmission, DecidedOfferResult } from "./attempt.js";
11
+ import { type IntentAdmissionOptions } from "./intent.js";
10
12
  import type { VerificationCleanupFailure, VerificationResult } from "./intent.js";
11
- import type { AcceptedProtocolStep, IntentOutcome as ProtocolIntentOutcome } from "./outcome.js";
13
+ import { type AcceptedProtocolStep, type IntentOutcome as ProtocolIntentOutcome } from "./outcome.js";
12
14
  import type { PlacementProtocolResult } from "./placement.js";
13
15
  import type { ProtocolProgress } from "./progress.js";
14
16
  import { type ContractDocumentProjection } from "./read/documents.js";
15
17
  import { type ContractBoard, type ContractCatalogue, type ContractObservation } from "./read/status.js";
16
- import type { ProtocolResult, ProtocolTerminal } from "./run.js";
18
+ import type { ProtocolTerminal } from "./run.js";
17
19
  export { changeIdSchema, contractIdSchema, snapshotIdSchema } from "../git/identity.js";
18
20
  export { entryUlidSchema } from "./attempt.js";
19
21
  export declare const gateSchema: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").Gate, string>>;
20
22
  export declare const deliverDataSchema: z.ZodObject<{
23
+ note: z.ZodOptional<z.ZodString>;
21
24
  tenderSnapshot: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
22
25
  integration: z.ZodObject<{
23
26
  predecessor: z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>;
@@ -29,6 +32,7 @@ export declare const deliverDataSchema: z.ZodObject<{
29
32
  requireBranchesToBeUpToDate: z.ZodBoolean;
30
33
  }, z.core.$strict>;
31
34
  }, z.core.$strict>;
35
+ export declare function recordedIntegrationSnapshots(journal: readonly JournalEntry[]): readonly SnapshotId[];
32
36
  export declare const verdictSchema: z.ZodEnum<{
33
37
  satisfied: "satisfied";
34
38
  unsatisfied: "unsatisfied";
@@ -70,6 +74,12 @@ export declare const verificationDeclarationRefusalSchema: z.ZodObject<{
70
74
  kind: z.ZodLiteral<"verification-declaration-invalid">;
71
75
  contractId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<ContractId, string>>>;
72
76
  }, z.core.$strict>;
77
+ export declare const candidateContentChangeSchema: z.ZodObject<{
78
+ kind: z.ZodLiteral<"candidate-content-changed">;
79
+ target: z.ZodOptional<z.ZodString>;
80
+ previousChange: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ChangeId, string>>;
81
+ currentChange: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").ChangeId, string>>;
82
+ }, z.core.$strict>;
73
83
  export declare const gateReportSchema: z.ZodObject<{
74
84
  gate: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").Gate, string>>;
75
85
  current: z.ZodUnion<readonly [z.ZodObject<{
@@ -399,19 +409,23 @@ export type MutationOperationInput = OperationInput & Readonly<{
399
409
  channel: GitDecodeChannel;
400
410
  progress?: ProtocolProgress;
401
411
  }>;
412
+ /** The decision input of an intent whose verb contributes only its own payload. */
413
+ type VoidIntentDecision<Payload extends object> = Payload & Readonly<{
414
+ contractId: ContractId;
415
+ actor?: ActorId;
416
+ at: string;
417
+ }>;
418
+ /**
419
+ * Observe, decide, and atomically admit one intent over the invoking actor and time, then complete it
420
+ * as a void outcome. The verb contributes only its own decision payload.
421
+ */
422
+ export declare function admitVoidIntent<Payload extends object, Refusal>(input: MutationOperationInput, payload: Payload, decide: (input: DecideInput<VoidIntentDecision<Payload>>) => OfferDecision<Refusal>, options?: IntentAdmissionOptions<Refusal>): Promise<IntentOutcome<void, Refusal>>;
402
423
  export type DocumentDerivation = Readonly<{
403
424
  document: DocumentKey;
404
425
  bytes: string;
405
426
  title: string;
406
427
  verification: VerificationDeclarationPreparation;
407
428
  }>;
408
- type StepStop<R> = Readonly<{
409
- refusal: R;
410
- retry?: never;
411
- } | {
412
- retry: IntentRetry;
413
- refusal?: never;
414
- }>;
415
429
  export declare const verificationStopSchema: z.ZodUnion<readonly [z.ZodObject<{
416
430
  refusal: z.ZodUnion<readonly [z.ZodObject<{
417
431
  kind: z.ZodEnum<{
@@ -617,8 +631,6 @@ export type AttemptDecision<Value, Refusal = IntentRefusal> = (AcceptedAdmission
617
631
  }>;
618
632
  export declare function timestamp(): string;
619
633
  export declare function attemptDecisionWithSeatClose<Value, Refusal = IntentRefusal>(outcome: PrivateStateSeatOutcome<AttemptDecision<Value, Refusal>>): AttemptDecision<Value, Refusal>;
620
- export declare function mergeAdmissions(current: AcceptedProtocolStep, next: AcceptedProtocolStep): AcceptedProtocolStep;
621
- export declare function stepStop<Refusal>(result: ProtocolResult<Refusal>): StepStop<Refusal> | undefined;
622
634
  export declare function unpackVerificationOutcome(verification: VerificationResult): Readonly<{
623
635
  cleanup?: VerificationCleanupFailure;
624
636
  leak?: WorktreeLeak;
@@ -4,14 +4,16 @@ import { gate } from "../core/facts/types.js";
4
4
  import { changeIdSchema, contractIdSchema, snapshotIdSchema } from "../git/identity.js";
5
5
  import { integrationPreparationRefusalSchema, readDeliveryDiff } from "../git/integration.js";
6
6
  import { currentBranch, observeContractAt } from "../git/observe.js";
7
- import { appendPrivateStateSeatClose, concatenatePrivateStateSeatClose, mergePrivateStateSeatClose, } from "../git/private-state-seat.js";
7
+ import { appendPrivateStateSeatClose, mergePrivateStateSeatClose, } from "../git/private-state-seat.js";
8
8
  import { withGitReadObservation } from "../git/read-observation.js";
9
9
  import { repositoryAt } from "../git/repository.js";
10
10
  import { checkoutNotFollowableRefusalSchema } from "../git/target-placement.js";
11
11
  import { dirtyWorkspaceRefusalSchema, unmergedPathsRefusalSchema, worktreeMissingRefusalSchema, } from "../git/tender.js";
12
12
  import { conflictRecoverySchema, worktreeWorkspaceSchema } from "../git/workspace.js";
13
13
  import { forkSourceMovedRefusalSchema, targetInputRefusalSchema } from "./bind.js";
14
+ import { admitIntent } from "./intent.js";
14
15
  import { verificationRuntimeStopSchema } from "./intent.js";
16
+ import { complete } from "./outcome.js";
15
17
  import { readDocuments } from "./read/documents.js";
16
18
  import { readContractBoard, readContractCatalogue, readContractObservationAt, } from "./read/status.js";
17
19
  import { protocolTerminalSchema } from "./run.js";
@@ -28,6 +30,10 @@ export const gateSchema = z.string().transform((value, context) => {
28
30
  });
29
31
  export const deliverDataSchema = z
30
32
  .object({
33
+ note: z
34
+ .string()
35
+ .refine((value) => value.trim() !== "")
36
+ .optional(),
31
37
  tenderSnapshot: snapshotIdSchema,
32
38
  integration: z
33
39
  .object({ predecessor: snapshotIdSchema, snapshot: snapshotIdSchema, changeId: changeIdSchema })
@@ -36,6 +42,15 @@ export const deliverDataSchema = z
36
42
  policy: z.object({ requireBranchesToBeUpToDate: z.boolean() }).strict(),
37
43
  })
38
44
  .strict();
45
+ export function recordedIntegrationSnapshots(journal) {
46
+ return journal
47
+ .flatMap((entry) => entry.kind === "deliver"
48
+ ? [entry.data.integration.snapshot]
49
+ : entry.kind === "reintegrated"
50
+ ? [entry.data.snapshot]
51
+ : [])
52
+ .reverse();
53
+ }
39
54
  export const verdictSchema = z.enum(["satisfied", "unsatisfied"]);
40
55
  export const activeContractRefusalSchema = z
41
56
  .object({ kind: z.enum(["contract-missing", "terminal"]), contractId: contractIdSchema })
@@ -55,7 +70,7 @@ export const deliverRefusalSchema = z
55
70
  export const verificationDeclarationRefusalSchema = z
56
71
  .object({ kind: z.literal("verification-declaration-invalid"), contractId: contractIdSchema.optional() })
57
72
  .strict();
58
- const staleGateReasonSchema = z
73
+ export const candidateContentChangeSchema = z
59
74
  .object({
60
75
  kind: z.literal("candidate-content-changed"),
61
76
  target: z.string().optional(),
@@ -72,7 +87,11 @@ export const gateReportSchema = z
72
87
  .object({ kind: z.literal("attested"), verdict: verdictSchema, at: z.string(), summary: z.string().optional() })
73
88
  .strict(),
74
89
  z
75
- .object({ kind: z.literal("stale"), priorVerdict: verdictSchema, reason: staleGateReasonSchema.optional() })
90
+ .object({
91
+ kind: z.literal("stale"),
92
+ priorVerdict: verdictSchema,
93
+ reason: candidateContentChangeSchema.optional(),
94
+ })
76
95
  .strict(),
77
96
  ]),
78
97
  })
@@ -136,6 +155,19 @@ export const intentRefusalSchema = z.union([
136
155
  targetInputRefusalSchema,
137
156
  verificationDeclarationRefusalSchema,
138
157
  ]);
158
+ /**
159
+ * Observe, decide, and atomically admit one intent over the invoking actor and time, then complete it
160
+ * as a void outcome. The verb contributes only its own decision payload.
161
+ */
162
+ export async function admitVoidIntent(input, payload, decide, options) {
163
+ const decisionInput = {
164
+ contractId: input.contractId,
165
+ ...(input.actor === undefined ? {} : { actor: input.actor }),
166
+ at: timestamp(),
167
+ ...payload,
168
+ };
169
+ return complete(await admitIntent(input.channel, input.scope, decisionInput, decide, options), undefined);
170
+ }
139
171
  export const verificationStopSchema = z.union([
140
172
  z.object({ refusal: z.union([activeContractRefusalSchema, verificationDeclarationRefusalSchema]) }).strict(),
141
173
  z.object({ retry: protocolTerminalSchema }).strict(),
@@ -191,18 +223,7 @@ export function attemptDecisionWithSeatClose(outcome) {
191
223
  return { ...value, seatClose: appendPrivateStateSeatClose(value.seatClose, closeLag) };
192
224
  });
193
225
  }
194
- export function mergeAdmissions(current, next) {
195
- const effects = [...(current.physical?.effects ?? []), ...(next.physical?.effects ?? [])];
196
- const lag = [...(current.physical?.lag ?? []), ...(next.physical?.lag ?? [])];
197
- const seatClose = concatenatePrivateStateSeatClose(current.seatClose, next.seatClose);
198
- return {
199
- ...next,
200
- facts: [...current.facts, ...next.facts],
201
- ...(effects.length === 0 && lag.length === 0 ? {} : { physical: { effects, lag } }),
202
- ...(seatClose === undefined ? {} : { seatClose }),
203
- };
204
- }
205
- export function stepStop(result) {
226
+ function stepStop(result) {
206
227
  if (result.kind === "accepted")
207
228
  return undefined;
208
229
  return result.kind === "refused" ? { refusal: result.refusal } : { retry: result };
@@ -12,7 +12,7 @@ export type PlacementExecutionFailure = Readonly<{
12
12
  kind: "placement-failed";
13
13
  diagnostic: string;
14
14
  }>;
15
- export type TargetMovedStop = Readonly<{
15
+ type TargetMovedStop = Readonly<{
16
16
  kind: "target-moved";
17
17
  contractId: ContractId;
18
18
  target: string;
@@ -20,6 +20,7 @@ export type TargetMovedStop = Readonly<{
20
20
  observed: SnapshotId | null;
21
21
  observedTreeEqualsCandidate: boolean;
22
22
  }>;
23
+ export declare function observeIntegrationTargetMovement(repository: GitRepository, state: import("../core/facts/types.js").ContractState): Promise<TargetMovedStop | undefined>;
23
24
  export type PlacementProtocolResult<ExtraRefusal = never> = (AcceptedAdmission & Readonly<{
24
25
  physical?: ReconcileResult;
25
26
  }>) | Exclude<ProtocolResult<PlacementRefusal | TargetPlacementRefusal | ExtraRefusal>, AcceptedAdmission> | TargetMovedStop | PlacementExecutionFailure;
@@ -10,6 +10,23 @@ import { acquireTargetPlacementFence, followTargetPlacement, prepareTargetPlacem
10
10
  import { admitDecidedOffer, mintAttempts } from "./attempt.js";
11
11
  import { prepareProtocolAttempt, runProtocol } from "./run.js";
12
12
  export { observeTargetPlacement } from "../git/target-placement.js";
13
+ export async function observeIntegrationTargetMovement(repository, state) {
14
+ const target = state.coordinates.target;
15
+ const integration = state.currentIntegration;
16
+ if (target === undefined || integration === null)
17
+ return undefined;
18
+ const observed = await observeTargetHead(repository, target);
19
+ if (observed === integration.predecessor)
20
+ return undefined;
21
+ return {
22
+ kind: "target-moved",
23
+ contractId: state.id,
24
+ target,
25
+ expected: integration.predecessor,
26
+ observed,
27
+ observedTreeEqualsCandidate: await observedTreeEqualsCandidate(repository, observed, integration.snapshot),
28
+ };
29
+ }
13
30
  function placementFailure(error) {
14
31
  return { kind: "placement-failed", diagnostic: error instanceof Error ? error.message : String(error) };
15
32
  }
@@ -75,14 +92,13 @@ async function runFencedPlacement(repository, input, protocol) {
75
92
  if (physical.kind === "refused")
76
93
  return physical;
77
94
  const admitted = await admitDecidedOffer({
78
- channel: protocol.channel,
79
- repository,
95
+ ...protocol,
96
+ scope: repository,
97
+ contractId: input.contractId,
80
98
  seat,
81
- decisionObservation: prepared.observation,
99
+ observation: prepared.observation,
82
100
  attempt: prepared.attempt,
83
101
  offer: prepared.offer,
84
- primaryContract: input.contractId,
85
- ...(protocol.progress === undefined ? {} : { progress: protocol.progress }),
86
102
  });
87
103
  if (admitted.kind === "accepted")
88
104
  preparedPhysical = physical.placement;
@@ -50,7 +50,7 @@ export declare const executionCleanupSchema: z.ZodUnion<readonly [z.ZodObject<{
50
50
  contractId: z.ZodPipe<z.ZodString, z.ZodTransform<ContractId, string>>;
51
51
  snapshot: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<SnapshotId, string>>>;
52
52
  leak: z.ZodObject<{
53
- path: z.ZodString;
53
+ path: z.ZodOptional<z.ZodString>;
54
54
  diagnostic: z.ZodString;
55
55
  }, z.core.$strict>;
56
56
  }, z.core.$strict>, z.ZodObject<{