@astrosheep/keiyaku 4.0.0 → 4.0.1

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 (241) hide show
  1. package/README.md +2 -9
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +2 -2
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +4 -4
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +2 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +2 -2
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +11 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +9 -6
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +94 -0
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/agents/openai.yaml +4 -0
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +41 -6
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +162 -45
  12. package/build/src/akuma/akuma.d.ts +33 -25
  13. package/build/src/akuma/akuma.js +93 -61
  14. package/build/src/akuma/archetype.d.ts +8 -0
  15. package/build/src/akuma/archetype.js +28 -9
  16. package/build/src/akuma/body.js +196 -84
  17. package/build/src/akuma/coordinate.d.ts +9 -0
  18. package/build/src/akuma/coordinate.js +22 -0
  19. package/build/src/akuma/heart/facts.d.ts +67 -15
  20. package/build/src/akuma/heart/facts.js +3 -3
  21. package/build/src/akuma/heart/index.d.ts +41 -29
  22. package/build/src/akuma/heart/index.js +72 -193
  23. package/build/src/akuma/heart/rows.d.ts +30 -53
  24. package/build/src/akuma/heart/rows.js +91 -111
  25. package/build/src/akuma/heart/schema.d.ts +1 -1
  26. package/build/src/akuma/heart/schema.js +55 -8
  27. package/build/src/akuma/heart/storage.d.ts +33 -0
  28. package/build/src/akuma/heart/storage.js +164 -0
  29. package/build/src/akuma/heart/tells.d.ts +12 -0
  30. package/build/src/akuma/heart/tells.js +79 -0
  31. package/build/src/akuma/heart/timeline.d.ts +15 -0
  32. package/build/src/akuma/heart/timeline.js +86 -0
  33. package/build/src/akuma/index.d.ts +4 -2
  34. package/build/src/akuma/index.js +1 -1
  35. package/build/src/akuma/projection.d.ts +97 -0
  36. package/build/src/akuma/projection.js +145 -0
  37. package/build/src/akuma/provider.d.ts +57 -11
  38. package/build/src/akuma/provider.js +57 -37
  39. package/build/src/akuma/providers/{claude.d.ts → claude/events.d.ts} +9 -41
  40. package/build/src/akuma/providers/claude/events.js +185 -0
  41. package/build/src/akuma/providers/claude/index.d.ts +46 -0
  42. package/build/src/akuma/providers/claude/index.js +265 -0
  43. package/build/src/akuma/providers/claude/input.d.ts +13 -0
  44. package/build/src/akuma/providers/claude/input.js +109 -0
  45. package/build/src/akuma/providers/codex-app-server/events.d.ts +1 -1
  46. package/build/src/akuma/providers/codex-app-server/events.js +12 -12
  47. package/build/src/akuma/providers/codex-app-server/index.d.ts +13 -11
  48. package/build/src/akuma/providers/codex-app-server/index.js +73 -22
  49. package/build/src/akuma/providers/index.js +22 -8
  50. package/build/src/akuma/providers/opencode-sdk/events.d.ts +48 -0
  51. package/build/src/akuma/providers/opencode-sdk/events.js +116 -0
  52. package/build/src/akuma/providers/opencode-sdk/index.d.ts +32 -0
  53. package/build/src/akuma/providers/opencode-sdk/index.js +203 -0
  54. package/build/src/akuma/providers/opencode-sdk/session.d.ts +41 -0
  55. package/build/src/akuma/providers/opencode-sdk/session.js +62 -0
  56. package/build/src/akuma/providers/pi/events.d.ts +33 -0
  57. package/build/src/akuma/providers/pi/events.js +128 -0
  58. package/build/src/akuma/providers/pi/index.d.ts +11 -0
  59. package/build/src/akuma/providers/pi/index.js +162 -0
  60. package/build/src/akuma/requests.d.ts +1 -0
  61. package/build/src/akuma/requests.js +5 -2
  62. package/build/src/alias/index.d.ts +4 -3
  63. package/build/src/alias/index.js +2 -3
  64. package/build/src/body/render.js +2 -1
  65. package/build/src/body/shape.js +7 -1
  66. package/build/src/body/verification.js +19 -4
  67. package/build/src/cli/accepted.d.ts +2 -0
  68. package/build/src/cli/accepted.js +2 -1
  69. package/build/src/cli/commands/akuma-invoke.d.ts +42 -18
  70. package/build/src/cli/commands/akuma-invoke.js +94 -50
  71. package/build/src/cli/commands/akuma.d.ts +15 -7
  72. package/build/src/cli/commands/akuma.js +94 -56
  73. package/build/src/cli/commands/contract.d.ts +142 -0
  74. package/build/src/cli/commands/contract.js +14 -0
  75. package/build/src/cli/commands/install.js +2 -0
  76. package/build/src/cli/commands/task-invoke.d.ts +3 -1
  77. package/build/src/cli/commands/task-invoke.js +27 -2
  78. package/build/src/cli/commands/task.js +2 -2
  79. package/build/src/cli/invoke.d.ts +6 -1
  80. package/build/src/cli/invoke.js +241 -43
  81. package/build/src/cli/main.js +20 -1
  82. package/build/src/cli/parse.d.ts +13 -116
  83. package/build/src/cli/parse.js +51 -78
  84. package/build/src/cli/render/akuma-tool.d.ts +2 -0
  85. package/build/src/cli/render/akuma-tool.js +6 -2
  86. package/build/src/cli/render/akuma.d.ts +2 -1
  87. package/build/src/cli/render/akuma.js +157 -217
  88. package/build/src/cli/render/catalog.d.ts +2 -0
  89. package/build/src/cli/render/catalog.js +16 -0
  90. package/build/src/cli/render/contract.d.ts +1 -1
  91. package/build/src/cli/render/contract.js +38 -5
  92. package/build/src/cli/render/kanshi.js +53 -5
  93. package/build/src/cli/render/refusal.js +17 -0
  94. package/build/src/cli/render/terminal.d.ts +13 -0
  95. package/build/src/cli/render/terminal.js +75 -0
  96. package/build/src/cli/render/text.js +5 -0
  97. package/build/src/cli/result.d.ts +15 -3
  98. package/build/src/contract-worktree.d.ts +43 -0
  99. package/build/src/contract-worktree.js +213 -0
  100. package/build/src/coordination/durable-file.d.ts +3 -0
  101. package/build/src/coordination/durable-file.js +44 -1
  102. package/build/src/core/facts/codec.js +23 -4
  103. package/build/src/core/facts/eligibility.d.ts +1 -10
  104. package/build/src/core/facts/eligibility.js +0 -49
  105. package/build/src/core/facts/observation.d.ts +3 -0
  106. package/build/src/core/facts/observation.js +12 -0
  107. package/build/src/core/facts/types.d.ts +10 -3
  108. package/build/src/core/subject.js +2 -2
  109. package/build/src/core/verbs/amend.js +12 -16
  110. package/build/src/core/verbs/bind.js +2 -16
  111. package/build/src/core/verbs/deliver.js +20 -4
  112. package/build/src/core/verbs/placement.js +3 -8
  113. package/build/src/dispatch/index.d.ts +3 -1
  114. package/build/src/dispatch/index.js +14 -5
  115. package/build/src/duration.d.ts +10 -0
  116. package/build/src/duration.js +22 -0
  117. package/build/src/git/admission.d.ts +2 -2
  118. package/build/src/git/admission.js +26 -16
  119. package/build/src/git/hooks.d.ts +15 -0
  120. package/build/src/git/hooks.js +57 -5
  121. package/build/src/git/identity.d.ts +5 -1
  122. package/build/src/git/identity.js +23 -4
  123. package/build/src/git/integration.d.ts +49 -0
  124. package/build/src/git/integration.js +214 -0
  125. package/build/src/git/observe.d.ts +25 -13
  126. package/build/src/git/observe.js +175 -72
  127. package/build/src/git/read-observation.d.ts +41 -0
  128. package/build/src/git/read-observation.js +361 -0
  129. package/build/src/git/reconcile.d.ts +15 -5
  130. package/build/src/git/reconcile.js +238 -85
  131. package/build/src/git/repository.d.ts +19 -4
  132. package/build/src/git/repository.js +77 -43
  133. package/build/src/git/scratch.d.ts +13 -0
  134. package/build/src/git/scratch.js +66 -0
  135. package/build/src/git/target-placement.d.ts +56 -0
  136. package/build/src/git/target-placement.js +255 -0
  137. package/build/src/git/tender.d.ts +48 -0
  138. package/build/src/git/tender.js +82 -0
  139. package/build/src/git/terminal-seal.d.ts +24 -0
  140. package/build/src/git/terminal-seal.js +87 -0
  141. package/build/src/git/tree.d.ts +2 -2
  142. package/build/src/git/tree.js +4 -0
  143. package/build/src/git/workspace.d.ts +21 -0
  144. package/build/src/git/workspace.js +104 -0
  145. package/build/src/identity/selector.d.ts +6 -0
  146. package/build/src/identity/selector.js +19 -0
  147. package/build/src/index.d.ts +4 -2
  148. package/build/src/index.js +2 -1
  149. package/build/src/kanshi/index.d.ts +1 -1
  150. package/build/src/kanshi/read.d.ts +5 -2
  151. package/build/src/kanshi/read.js +154 -45
  152. package/build/src/kanshi/report.d.ts +31 -6
  153. package/build/src/kanshi/select.js +1 -1
  154. package/build/src/library/address.d.ts +48 -0
  155. package/build/src/library/address.js +134 -0
  156. package/build/src/library/akuma-creation.d.ts +10 -6
  157. package/build/src/library/akuma-creation.js +12 -11
  158. package/build/src/library/bind.d.ts +21 -0
  159. package/build/src/library/bind.js +56 -0
  160. package/build/src/library/catalog.d.ts +58 -0
  161. package/build/src/library/catalog.js +72 -0
  162. package/build/src/library/configuration.d.ts +6 -15
  163. package/build/src/library/configuration.js +14 -17
  164. package/build/src/library/contract.d.ts +21 -46
  165. package/build/src/library/contract.js +193 -183
  166. package/build/src/library/delivery.d.ts +23 -0
  167. package/build/src/library/delivery.js +21 -0
  168. package/build/src/library/fleet.d.ts +65 -0
  169. package/build/src/library/fleet.js +189 -0
  170. package/build/src/library/input.d.ts +3 -0
  171. package/build/src/library/input.js +19 -0
  172. package/build/src/library/keiyaku.d.ts +16 -2
  173. package/build/src/library/keiyaku.js +11 -1
  174. package/build/src/library/mutation.d.ts +38 -0
  175. package/build/src/library/mutation.js +39 -0
  176. package/build/src/library/refusal.d.ts +21 -0
  177. package/build/src/library/refusal.js +29 -0
  178. package/build/src/library/region.d.ts +2 -1
  179. package/build/src/library/region.js +3 -3
  180. package/build/src/library/repo.d.ts +4 -1
  181. package/build/src/library/repo.js +31 -16
  182. package/build/src/protocol/attempt.d.ts +16 -3
  183. package/build/src/protocol/attempt.js +39 -8
  184. package/build/src/protocol/bind.d.ts +9 -2
  185. package/build/src/protocol/bind.js +47 -39
  186. package/build/src/protocol/intent.d.ts +42 -18
  187. package/build/src/protocol/intent.js +36 -75
  188. package/build/src/protocol/operations.d.ts +93 -35
  189. package/build/src/protocol/operations.js +235 -123
  190. package/build/src/protocol/outcome.d.ts +7 -2
  191. package/build/src/protocol/outcome.js +9 -3
  192. package/build/src/protocol/placement.d.ts +30 -0
  193. package/build/src/protocol/placement.js +114 -0
  194. package/build/src/protocol/read/audit.d.ts +9 -3
  195. package/build/src/protocol/read/audit.js +25 -9
  196. package/build/src/protocol/read/documents.d.ts +2 -2
  197. package/build/src/protocol/read/documents.js +4 -4
  198. package/build/src/protocol/read/status.d.ts +11 -5
  199. package/build/src/protocol/read/status.js +28 -15
  200. package/build/src/protocol/run.d.ts +49 -7
  201. package/build/src/protocol/run.js +53 -25
  202. package/build/src/runtime/proc/line-rpc.d.ts +1 -0
  203. package/build/src/runtime/proc/line-rpc.js +21 -0
  204. package/build/src/runtime/proc/run.d.ts +18 -2
  205. package/build/src/runtime/proc/run.js +34 -8
  206. package/build/src/settings.d.ts +6 -0
  207. package/build/src/settings.js +29 -14
  208. package/build/src/settlement/fence.d.ts +9 -0
  209. package/build/src/settlement/fence.js +23 -0
  210. package/build/src/settlement/holder.d.ts +25 -4
  211. package/build/src/settlement/holder.js +102 -28
  212. package/build/src/settlement/settle.d.ts +8 -0
  213. package/build/src/settlement/settle.js +102 -28
  214. package/build/src/task/board.d.ts +20 -2
  215. package/build/src/task/board.js +11 -1
  216. package/build/src/task/compose.d.ts +2 -2
  217. package/build/src/task/compose.js +2 -2
  218. package/build/src/task/context.js +2 -7
  219. package/build/src/task/index.d.ts +9 -9
  220. package/build/src/task/index.js +15 -12
  221. package/build/src/task/operations.d.ts +31 -12
  222. package/build/src/task/operations.js +8 -4
  223. package/build/src/task/store.d.ts +4 -6
  224. package/build/src/task/store.js +3 -3
  225. package/build/src/verification/declaration.d.ts +1 -0
  226. package/build/src/verification/execution.d.ts +49 -0
  227. package/build/src/verification/execution.js +104 -0
  228. package/build/src/world.d.ts +13 -0
  229. package/build/src/world.js +103 -0
  230. package/package.json +7 -4
  231. package/build/src/akuma/activity.d.ts +0 -66
  232. package/build/src/akuma/activity.js +0 -139
  233. package/build/src/akuma/providers/claude.js +0 -305
  234. package/build/src/context-root.d.ts +0 -4
  235. package/build/src/context-root.js +0 -15
  236. package/build/src/git/delivery.d.ts +0 -20
  237. package/build/src/git/delivery.js +0 -109
  238. package/build/src/git/verification.d.ts +0 -14
  239. package/build/src/git/verification.js +0 -56
  240. package/build/src/verification/producer.d.ts +0 -23
  241. package/build/src/verification/producer.js +0 -54
@@ -1,8 +1,9 @@
1
- import { prepareDelivery, prepareReview, } from "../git/delivery.js";
2
- import { currentBranch, extendContractsForAdmission, observeGit, observeContract, observeContractsForAdmission, } from "../git/observe.js";
3
- import { reconcile, reconcileBatch, reconcileObservationFailure } from "../git/reconcile.js";
1
+ import { materializeIntegrationSnapshot, planIntegration, prepareReviewIntegration, readDeliveryDiff, } from "../git/integration.js";
2
+ import { captureTender, dirtyTenderDelta, dirtyTenderRefusal, materializeTenderSnapshot, } from "../git/tender.js";
3
+ import { currentBranch, extendContractsForAdmissionAt, observeContractAt, observeContractWorld, observeContractsForAdmissionAt, } from "../git/observe.js";
4
+ import { reconcile, reconcileBatch, reconcileObservationFailure, } from "../git/reconcile.js";
4
5
  import { NoGitWorldError, repositoryAt } from "../git/repository.js";
5
- import { readDeliveryDiff } from "../git/verification.js";
6
+ import { withGitReadObservation } from "../git/read-observation.js";
6
7
  import { dependencyKeySet } from "../core/subject.js";
7
8
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
8
9
  import { contractState, documentIsCurrent } from "../core/facts/observation.js";
@@ -12,102 +13,190 @@ import { decideAmend } from "../core/verbs/amend.js";
12
13
  import { decideArc } from "../core/verbs/arc.js";
13
14
  import { decideDeliver } from "../core/verbs/deliver.js";
14
15
  import { decideAttestation } from "../core/verbs/attestation.js";
15
- import { produceVerification } from "../verification/producer.js";
16
- import { admitIntent, admitPlacement, mintAttempts, verifyDelivery } from "./intent.js";
17
- import { auditReport, readAudit } from "./read/audit.js";
16
+ import { admitIntent, verifyDelivery, } from "./intent.js";
17
+ import { admitPlacement } from "./placement.js";
18
+ import { auditReport, readAuditAt } from "./read/audit.js";
18
19
  import { readDocuments } from "./read/documents.js";
19
- import { readContractBoard, readContractObservation, } from "./read/status.js";
20
- import { admitDecidedOffer } from "./attempt.js";
20
+ import { readContractBoard, readContractObservationAt, } from "./read/status.js";
21
+ import { admitDecidedOffer, mintAttempts } from "./attempt.js";
21
22
  export { bindOperation } from "./bind.js";
22
- import { accepted, admitted, complete } from "./outcome.js";
23
+ import { accepted, admitted, complete, } from "./outcome.js";
23
24
  const REVIEWED = gate("reviewed");
24
25
  function timestamp() { return new Date().toISOString(); }
25
26
  function mergeAdmissions(current, next) {
26
- return { ...next, facts: [...current.facts, ...next.facts] };
27
+ const effects = [...(current.physical?.effects ?? []), ...(next.physical?.effects ?? [])];
28
+ const lag = [...(current.physical?.lag ?? []), ...(next.physical?.lag ?? [])];
29
+ return {
30
+ ...next,
31
+ facts: [...current.facts, ...next.facts],
32
+ ...(effects.length === 0 && lag.length === 0 ? {} : { physical: { effects, lag } }),
33
+ };
27
34
  }
28
35
  function stepStop(result) {
29
36
  if (result.kind === "accepted")
30
37
  return undefined;
31
38
  return result.kind === "refused" ? { refusal: result.refusal } : { retry: result };
32
39
  }
40
+ function verificationStop(step) {
41
+ return "failure" in step ? step : stepStop(step);
42
+ }
43
+ function placementStop(result) {
44
+ if (result.kind === "accepted")
45
+ return undefined;
46
+ if (result.kind === "placement-failed") {
47
+ return { failure: "target-placement-failed", diagnostic: result.diagnostic };
48
+ }
49
+ if (result.kind === "target-moved") {
50
+ const { contractId, target, expected, observed } = result;
51
+ return { failure: "target-moved", contractId, target, expected, observed };
52
+ }
53
+ return result.kind === "refused" ? { refusal: result.refusal } : { retry: result };
54
+ }
33
55
  export { NoGitWorldError };
34
56
  export function scopeOperation(input) { return repositoryAt(input.coordinate); }
35
57
  export function currentBranchOperation(input) {
36
58
  return currentBranch(input.scope);
37
59
  }
38
- export function contractsOperation(input) { return readContractBoard(input.scope); }
60
+ export async function contractsOperation(input) {
61
+ return withGitReadObservation(input.scope, input.channel, readContractBoard);
62
+ }
39
63
  export function contractObservationOperation(input) {
40
- return readContractObservation(input.scope, input.contractId);
64
+ return readContractObservationAt(input.scope, input.channel, input.contractId);
41
65
  }
42
- export function documentsOperation(input) { return readDocuments(input.scope); }
43
- export function stateOperation(input) {
44
- const state = observeContract(input.scope, input.contractId).state;
66
+ export async function documentsOperationAt(scope, channel) {
67
+ return withGitReadObservation(scope, channel, readDocuments);
68
+ }
69
+ export async function stateOperation(input) {
70
+ const state = (await observeContractAt(input.scope, input.channel, input.contractId)).state;
45
71
  if (state === null)
46
72
  throw new Error(`contract does not exist: ${input.contractId}`);
47
73
  return state;
48
74
  }
49
- export function readStateOperation(input) { return observeContract(input.scope, input.contractId).state; }
50
- export function deliveryOperation(input) {
51
- const state = observeContract(input.scope, input.contractId).state;
52
- if (state === null || state.delivery === null)
53
- return null;
54
- return {
55
- snapshotId: state.delivery.data.candidate,
56
- changeId: state.delivery.data.deliveryPatchId,
57
- expectedPredecessor: state.delivery.data.expectedPredecessor,
58
- };
75
+ export async function deliveryOperation(input) {
76
+ const state = (await observeContractAt(input.scope, input.channel, input.contractId)).state;
77
+ return state?.delivery?.data ?? null;
59
78
  }
60
- function observePrerequisiteClosure(repository, contracts) {
61
- let observation = observeContractsForAdmission(repository, contracts);
62
- let frontier = contracts.slice(1);
63
- while (frontier.length > 0) {
64
- const next = new Set();
65
- for (const id of frontier) {
66
- const state = contractState(observation.decision, id);
67
- if (state === null)
68
- continue;
69
- for (const dependency of state.terms.after) {
70
- if (!observation.decision.has(dependency))
71
- next.add(dependency);
72
- }
79
+ export async function deliveryDiffOperation(input) { return readDeliveryDiff(input.scope, input.integrationPredecessor, input.integrationSnapshot); }
80
+ export async function amendOperation(input) {
81
+ const attempts = mintAttempts({ entryCount: 1 });
82
+ let source = input.source;
83
+ for (let index = 0; index < attempts.length; index += 1) {
84
+ let observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
85
+ const state = contractState(observation.decision, input.contractId);
86
+ if (source === undefined && state !== null)
87
+ source = state.terms;
88
+ const amendment = source === undefined || input.deriveAmendment === undefined
89
+ ? undefined
90
+ : { source, ...input.deriveAmendment(source) };
91
+ if (amendment !== undefined) {
92
+ observation = await extendContractsForAdmissionAt(input.channel, observation, [...new Set([...(state?.terms.after ?? []), ...amendment.terms.after])]);
93
+ }
94
+ const preparation = amendment === undefined
95
+ ? undefined
96
+ : amendment.verification.kind === "prepared"
97
+ ? { kind: "prepared", data: amendment.terms }
98
+ : { kind: "refused", refusal: amendment.verification.refusal };
99
+ const decision = decideAmend({
100
+ input: {
101
+ contractId: input.contractId,
102
+ ...(input.actor === undefined ? {} : { actor: input.actor }),
103
+ at: timestamp(),
104
+ ...(amendment === undefined ? {} : { source: amendment.source }),
105
+ ...(preparation === undefined ? {} : { preparation }),
106
+ },
107
+ attempt: attempts[index],
108
+ observation: observation.decision,
109
+ });
110
+ if (decision.kind === "refused")
111
+ return decision;
112
+ const admission = await admitDecidedOffer({
113
+ channel: input.channel,
114
+ repository: input.scope,
115
+ decisionObservation: observation,
116
+ attempt: attempts[index],
117
+ offer: decision.offer,
118
+ primaryContract: input.contractId,
119
+ });
120
+ if (admission.kind === "accepted") {
121
+ if (amendment === undefined)
122
+ throw new Error("accepted amendment is missing its document derivation");
123
+ return admitted(admission, amendment);
73
124
  }
74
- frontier = [...next];
75
- observation = extendContractsForAdmission(repository, observation, frontier);
125
+ if (admission.kind === "publication-failed")
126
+ return { kind: "retry", reason: admission };
127
+ if (admission.kind === "collision" && index + 1 === attempts.length)
128
+ return { kind: "retry", reason: admission };
76
129
  }
77
- return observation;
130
+ return { kind: "retry", reason: { kind: "exhausted" } };
78
131
  }
79
- export async function deliveryDiffOperation(input) { return readDeliveryDiff(input.scope, input.expectedPredecessor, input.snapshotId); }
80
- export function amendOperation(input) {
81
- const amendment = input.amendment;
82
- const preparation = amendment === undefined
83
- ? undefined
84
- : amendment.verification.kind === "prepared"
85
- ? { kind: "prepared", data: amendment.terms }
86
- : { kind: "refused", refusal: amendment.verification.refusal };
87
- const decisionInput = {
88
- contractId: input.contractId,
89
- ...(input.actor === undefined ? {} : { actor: input.actor }),
90
- at: timestamp(),
91
- ...(amendment === undefined ? {} : { source: amendment.source }),
92
- ...(preparation === undefined ? {} : { preparation }),
132
+ export function prepareDelivery(repository, stage, input) {
133
+ const { contractId, coordinates } = stage;
134
+ if (coordinates.workspace === "here" && coordinates.target !== undefined) {
135
+ const branch = currentBranch(repository);
136
+ if (branch !== coordinates.target) {
137
+ return { kind: "refused", refusal: { kind: "workspace-not-on-target", contractId, target: coordinates.target, branch } };
138
+ }
139
+ }
140
+ const tender = captureTender(repository, stage);
141
+ if (tender.kind === "refused")
142
+ return tender;
143
+ if ((tender.data.dirty && input.includeDirty !== true) || tender.data.changes.submodules.length > 0) {
144
+ return { kind: "refused", refusal: dirtyTenderRefusal(repository, contractId, tender.data) };
145
+ }
146
+ const tenderSnapshot = materializeTenderSnapshot(repository, tender.data, {
147
+ contractId,
148
+ title: input.title,
149
+ ...(input.message === undefined ? {} : { message: input.message }),
150
+ });
151
+ const requireBranchesToBeUpToDate = input.requireBranchesToBeUpToDate ?? false;
152
+ const integration = planIntegration(repository, stage, { ...tender.data, head: tenderSnapshot }, requireBranchesToBeUpToDate);
153
+ if (integration.kind === "refused")
154
+ return integration;
155
+ const integrationSnapshot = coordinates.target === undefined
156
+ ? tenderSnapshot
157
+ : materializeIntegrationSnapshot(repository, integration.data.tree, integration.data.predecessor, {
158
+ contractId,
159
+ title: input.title,
160
+ ...(input.message === undefined ? {} : { message: input.message }),
161
+ });
162
+ return {
163
+ kind: "prepared",
164
+ data: {
165
+ tenderSnapshot,
166
+ integration: { predecessor: integration.data.predecessor, snapshot: integrationSnapshot, changeId: integration.data.changeId },
167
+ method: "squash",
168
+ policy: { requireBranchesToBeUpToDate },
169
+ },
93
170
  };
94
- return complete(admitIntent(input.scope, decisionInput, decideAmend, {
95
- observedContracts: [input.contractId, ...(amendment?.terms.after ?? [])],
96
- observe: observePrerequisiteClosure,
97
- }), undefined);
98
171
  }
99
- function deliverAttempt(input, attempt) {
100
- const decisionObservation = observeContractsForAdmission(input.scope, [input.contractId]);
172
+ export function prepareReview(repository, stage) {
173
+ const tender = captureTender(repository, stage);
174
+ if (tender.kind === "refused")
175
+ return tender;
176
+ if (tender.data.changes.submodules.length > 0) {
177
+ return { kind: "refused", refusal: dirtyTenderRefusal(repository, stage.contractId, tender.data) };
178
+ }
179
+ const workspace = dirtyTenderDelta(repository, tender.data);
180
+ return prepareReviewIntegration(repository, stage, tender.data, workspace);
181
+ }
182
+ async function deliverAttempt(input, attempt) {
183
+ let decisionObservation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
101
184
  const state = contractState(decisionObservation.decision, input.contractId);
185
+ if (state !== null) {
186
+ decisionObservation = await extendContractsForAdmissionAt(input.channel, decisionObservation, state.terms.after);
187
+ }
188
+ const derivation = state === null || input.deriveDocument === undefined
189
+ ? undefined
190
+ : input.deriveDocument(state);
102
191
  let preparation;
103
- if (state === null || input.derivation === undefined) {
192
+ if (state === null || derivation === undefined) {
104
193
  preparation = { kind: "unavailable" };
105
194
  }
106
- else if (input.derivation.verification.kind === "refused") {
195
+ else if (derivation.verification.kind === "refused") {
107
196
  preparation = {
108
197
  kind: "refused",
109
- document: input.derivation.document,
110
- refusal: input.derivation.verification.refusal,
198
+ document: derivation.document,
199
+ refusal: derivation.verification.refusal,
111
200
  };
112
201
  }
113
202
  else {
@@ -115,12 +204,14 @@ function deliverAttempt(input, attempt) {
115
204
  contractId: state.id,
116
205
  coordinates: state.coordinates,
117
206
  }, {
118
- title: input.derivation.title,
207
+ title: derivation.title,
119
208
  ...(input.message === undefined ? {} : { message: input.message }),
209
+ requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate,
210
+ includeDirty: input.includeDirty,
120
211
  });
121
212
  preparation = prepared.kind === "refused"
122
- ? { kind: "refused", document: input.derivation.document, refusal: prepared.refusal }
123
- : { kind: "prepared", document: input.derivation.document, data: prepared.data };
213
+ ? { kind: "refused", document: derivation.document, refusal: prepared.refusal }
214
+ : { kind: "prepared", document: derivation.document, data: prepared.data };
124
215
  }
125
216
  const decisionInput = {
126
217
  contractId: input.contractId,
@@ -134,61 +225,64 @@ function deliverAttempt(input, attempt) {
134
225
  if (preparation.kind !== "prepared") {
135
226
  throw new Error("offered delivery is missing its mechanical preparation");
136
227
  }
137
- const admitted = admitDecidedOffer(input.scope, decisionObservation, attempt, decision.offer, input.contractId);
228
+ const admitted = await admitDecidedOffer({
229
+ channel: input.channel,
230
+ repository: input.scope,
231
+ decisionObservation,
232
+ attempt,
233
+ offer: decision.offer,
234
+ primaryContract: input.contractId,
235
+ });
138
236
  if (admitted.kind === "accepted") {
139
- return { ...admitted, value: {
140
- snapshotId: preparation.data.candidate,
141
- changeId: preparation.data.deliveryPatchId,
142
- expectedPredecessor: preparation.data.expectedPredecessor,
143
- } };
237
+ if (derivation === undefined)
238
+ throw new Error("accepted delivery is missing its document derivation");
239
+ return { ...admitted, value: { delivery: preparation.data, derivation } };
144
240
  }
145
241
  return admitted;
146
242
  }
147
243
  async function completeDelivery(input, first) {
148
- if (input.derivation === undefined) {
149
- throw new Error("accepted delivery is missing its document derivation");
150
- }
151
- const derivation = input.derivation;
244
+ const derivation = first.value.derivation;
152
245
  if (derivation.verification.kind !== "prepared") {
153
246
  throw new Error("accepted delivery is missing its Verification preparation");
154
247
  }
155
248
  let admission = first;
156
249
  let verificationValue;
250
+ let cleanup;
157
251
  let leak;
158
252
  const verification = await verifyDelivery({
253
+ channel: input.channel,
159
254
  repository: input.scope,
160
255
  contractId: input.contractId,
161
256
  ...(input.actor === undefined ? {} : { actor: input.actor }),
162
257
  at: timestamp(),
163
258
  state: first.state,
164
259
  environment: process.env,
165
- produce: produceVerification,
260
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
166
261
  ...(derivation.verification.data === null
167
262
  ? {}
168
263
  : { verification: derivation.verification.data }),
169
264
  });
170
265
  if (verification !== null) {
266
+ cleanup = verification.cleanup;
171
267
  leak = verification.leak;
172
- if ("failure" in verification.step)
173
- verificationValue = verification.step;
174
- else {
175
- verificationValue = stepStop(verification.step);
176
- if (verification.step.kind === "accepted")
177
- admission = mergeAdmissions(admission, verification.step);
268
+ verificationValue = verificationStop(verification.step);
269
+ if (!("failure" in verification.step) && verification.step.kind === "accepted") {
270
+ admission = mergeAdmissions(admission, verification.step);
178
271
  }
179
272
  }
180
- const placement = admitPlacement(input.scope, {
273
+ const placement = await admitPlacement(input.channel, input.scope, first.state.coordinates.target, {
181
274
  contractId: input.contractId,
182
275
  ...(input.actor === undefined ? {} : { actor: input.actor }),
183
276
  at: timestamp(),
184
277
  });
185
- const placementValue = stepStop(placement);
278
+ const placementValue = placementStop(placement);
186
279
  if (placement.kind === "accepted")
187
280
  admission = mergeAdmissions(admission, placement);
188
281
  return admitted(admission, {
189
- ...first.value,
282
+ ...first.value.delivery,
190
283
  ...(verificationValue === undefined ? {} : { verification: verificationValue }),
191
284
  ...(placementValue === undefined ? {} : { placement: placementValue }),
285
+ ...(cleanup === undefined ? {} : { cleanup }),
192
286
  ...(leak === undefined ? {} : { leak }),
193
287
  });
194
288
  }
@@ -196,7 +290,7 @@ export async function deliverOperation(input) {
196
290
  const attempts = mintAttempts({ entryCount: 2 });
197
291
  let first = null;
198
292
  for (let index = 0; index < attempts.length; index += 1) {
199
- const result = deliverAttempt(input, attempts[index]);
293
+ const result = await deliverAttempt(input, attempts[index]);
200
294
  if (result.kind === "accepted") {
201
295
  first = result;
202
296
  break;
@@ -214,16 +308,19 @@ export async function deliverOperation(input) {
214
308
  return { kind: "retry", reason: { kind: "exhausted" } };
215
309
  return completeDelivery(input, first);
216
310
  }
217
- export function abandonOperation(input) {
218
- return complete(admitIntent(input.scope, {
311
+ export async function abandonOperation(input) {
312
+ return complete(await admitIntent(input.channel, input.scope, {
219
313
  contractId: input.contractId,
220
314
  ...(input.actor === undefined ? {} : { actor: input.actor }),
221
315
  at: timestamp(),
222
316
  ...(input.note === undefined ? {} : { note: input.note }),
223
- }, decideAbandon, input.decorateOffer === undefined ? {} : { decorateOffer: input.decorateOffer }), undefined);
317
+ }, decideAbandon, {
318
+ ...(input.decorateOffer === undefined ? {} : { decorateOffer: input.decorateOffer }),
319
+ ...(input.observationSelection === undefined ? {} : { observationSelection: input.observationSelection }),
320
+ }), undefined);
224
321
  }
225
- export function arcOperation(input) {
226
- return complete(admitIntent(input.scope, {
322
+ export async function arcOperation(input) {
323
+ return complete(await admitIntent(input.channel, input.scope, {
227
324
  contractId: input.contractId,
228
325
  ...(input.actor === undefined ? {} : { actor: input.actor }),
229
326
  at: timestamp(),
@@ -231,9 +328,13 @@ export function arcOperation(input) {
231
328
  }, decideArc), undefined);
232
329
  }
233
330
  function reviewAttempt(input, attempt) {
234
- const decisionObservation = observeContractsForAdmission(input.scope, [input.contractId]);
331
+ return reviewAttemptObserved(input, attempt);
332
+ }
333
+ async function reviewAttemptObserved(input, attempt) {
334
+ const decisionObservation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
235
335
  const state = contractState(decisionObservation.decision, input.contractId);
236
336
  let preparation;
337
+ let workspace;
237
338
  if (state !== null) {
238
339
  const prepared = prepareReview(input.scope, { contractId: state.id, coordinates: state.coordinates });
239
340
  preparation = prepared.kind === "refused"
@@ -244,12 +345,14 @@ function reviewAttempt(input, attempt) {
244
345
  gate: REVIEWED,
245
346
  subject: dependencyKeySet([
246
347
  { kind: "document", value: state.terms.document.key },
247
- { kind: "change", value: prepared.data },
348
+ { kind: "change", value: prepared.data.changeId },
248
349
  ]),
249
350
  verdict: input.verdict,
250
351
  ...(input.summary === undefined ? {} : { summary: input.summary }),
251
352
  },
252
353
  };
354
+ if (prepared.kind === "prepared")
355
+ workspace = prepared.data.workspace;
253
356
  }
254
357
  const decisionInput = {
255
358
  contractId: input.contractId,
@@ -260,17 +363,27 @@ function reviewAttempt(input, attempt) {
260
363
  const decision = decideAttestation({ input: decisionInput, attempt, observation: decisionObservation.decision });
261
364
  if (decision.kind === "refused")
262
365
  return { kind: "refused", refusal: decision.refusal };
263
- const admitted = admitDecidedOffer(input.scope, decisionObservation, attempt, decision.offer, input.contractId);
366
+ const admitted = await admitDecidedOffer({
367
+ channel: input.channel,
368
+ repository: input.scope,
369
+ decisionObservation,
370
+ attempt,
371
+ offer: decision.offer,
372
+ primaryContract: input.contractId,
373
+ });
264
374
  if (admitted.kind === "accepted")
265
- return { ...admitted, value: undefined };
375
+ return {
376
+ ...admitted,
377
+ value: workspace === undefined ? {} : { workspace },
378
+ };
266
379
  return admitted;
267
380
  }
268
- export function reviewOperation(input) {
381
+ export async function reviewOperation(input) {
269
382
  const git = input.scope;
270
- const attempts = mintAttempts({ entryCount: 2 });
383
+ const attempts = mintAttempts({ entryCount: 1 });
271
384
  let review = null;
272
385
  for (let index = 0; index < attempts.length; index += 1) {
273
- const result = reviewAttempt(input, attempts[index]);
386
+ const result = await reviewAttempt(input, attempts[index]);
274
387
  if (result.kind === "accepted" || result.kind === "refused") {
275
388
  review = result;
276
389
  break;
@@ -285,26 +398,23 @@ export function reviewOperation(input) {
285
398
  if (review.kind !== "accepted")
286
399
  return review;
287
400
  if (input.verdict !== "satisfied")
288
- return admitted(review, {});
289
- const placement = admitPlacement(git, {
401
+ return admitted(review, review.value);
402
+ const placement = await admitPlacement(input.channel, git, review.state.coordinates.target, {
290
403
  contractId: input.contractId,
291
404
  ...(input.actor === undefined ? {} : { actor: input.actor }),
292
405
  at: timestamp(),
293
406
  });
294
- const placementStop = stepStop(placement);
407
+ const stopped = placementStop(placement);
295
408
  const admission = placement.kind === "accepted" ? mergeAdmissions(review, placement) : review;
296
- return admitted(admission, placementStop === undefined ? {} : { placement: placementStop });
409
+ return admitted(admission, { ...review.value, ...(stopped === undefined ? {} : { placement: stopped }) });
297
410
  }
298
411
  export async function auditOperation(input) {
299
412
  const git = input.scope;
300
- const initial = readAudit(git, input.contractId, REVIEWED);
413
+ const initial = await readAuditAt(git, input.channel, input.contractId, REVIEWED);
301
414
  if (initial.state === null)
302
415
  return { kind: "refused", refusal: { kind: "contract-missing", contractId: input.contractId } };
303
- const derivation = input.derivation;
304
- if (derivation === undefined) {
305
- return { kind: "refused", refusal: { kind: "document-moved", contractId: input.contractId } };
306
- }
307
- if (!documentIsCurrent(initial.state, derivation.document)) {
416
+ const derivation = input.deriveDocument?.(initial.state);
417
+ if (derivation === undefined || !documentIsCurrent(initial.state, derivation.document)) {
308
418
  return { kind: "refused", refusal: { kind: "document-moved", contractId: input.contractId } };
309
419
  }
310
420
  if (derivation.verification.kind === "refused") {
@@ -314,31 +424,27 @@ export async function auditOperation(input) {
314
424
  return accepted(initial.state, [], initial.report);
315
425
  }
316
426
  const verification = await verifyDelivery({
427
+ channel: input.channel,
317
428
  repository: git,
318
429
  contractId: input.contractId,
319
430
  ...(input.actor === undefined ? {} : { actor: input.actor }),
320
431
  at: timestamp(),
321
432
  state: initial.state,
322
433
  environment: process.env,
323
- produce: produceVerification,
434
+ ...(input.signal === undefined ? {} : { signal: input.signal }),
324
435
  verification: derivation.verification.data,
325
436
  });
326
437
  if (verification === null) {
327
438
  throw new Error("audit verification preparation unexpectedly produced no attempt");
328
439
  }
329
- const attempt = "failure" in verification.step
330
- ? verification.step
331
- : verification.step.kind === "accepted"
332
- ? undefined
333
- : verification.step.kind === "refused"
334
- ? { refusal: verification.step.refusal }
335
- : { retry: verification.step };
440
+ const attempt = verificationStop(verification.step);
336
441
  const report = !("failure" in verification.step) && verification.step.kind === "accepted"
337
- ? auditReport(verification.step.journal, REVIEWED)
442
+ ? auditReport(verification.step.journal, REVIEWED, initial.state, initial.report.targetObservation)
338
443
  : initial.report;
339
444
  const value = {
340
445
  ...report,
341
446
  ...(attempt === undefined ? {} : { attempt }),
447
+ ...(verification.cleanup === undefined ? {} : { cleanup: verification.cleanup }),
342
448
  ...(verification.leak === undefined ? {} : { leak: verification.leak }),
343
449
  };
344
450
  return !("failure" in verification.step) && verification.step.kind === "accepted"
@@ -349,9 +455,11 @@ export async function reconcileOperation(input) {
349
455
  try {
350
456
  const observation = await reconcile({
351
457
  repository: input.scope,
458
+ channel: input.channel,
352
459
  contractId: input.contractId,
353
460
  hooks: input.hooks,
354
461
  retryHooks: input.retryHooks,
462
+ ...(input.retainTerminalWorktree === undefined ? {} : { retainTerminalWorktree: input.retainTerminalWorktree }),
355
463
  });
356
464
  return { state: observation.state, report: observation.result };
357
465
  }
@@ -363,8 +471,12 @@ export async function reconcileOperation(input) {
363
471
  }
364
472
  export async function reconcileAllOperation(input) {
365
473
  const git = input.scope;
366
- const observation = observeGit(git);
367
- const contracts = (await reconcileBatch(git, observation.contracts.keys(), input.hooks, input.retryHooks)).map((item) => ({
474
+ const observation = await withGitReadObservation(input.scope, input.channel, (read) => observeContractWorld(read));
475
+ const contracts = (await reconcileBatch(git, input.channel, observation.contracts.keys(), {
476
+ hooks: input.hooks,
477
+ retryHooks: input.retryHooks,
478
+ retainTerminalWorktree: input.retainTerminalWorktree ?? false,
479
+ })).map((item) => ({
368
480
  contractId: item.contract,
369
481
  state: item.state,
370
482
  report: item.result,
@@ -1,11 +1,16 @@
1
1
  import type { ContractHead, ContractState, JournalEntry } from "../core/facts/types.js";
2
2
  import type { AcceptedAdmission } from "./attempt.js";
3
3
  import type { ProtocolResult, ProtocolTerminal } from "./run.js";
4
+ import type { ReconcileResult } from "../git/reconcile.js";
5
+ export type AcceptedProtocolStep = AcceptedAdmission & Readonly<{
6
+ physical?: ReconcileResult;
7
+ }>;
4
8
  export type IntentOutcome<Value, Refusal = never> = Readonly<{
5
9
  kind: "accepted";
6
10
  facts: readonly JournalEntry[];
7
11
  head: ContractHead;
8
12
  value: Value;
13
+ physical?: ReconcileResult;
9
14
  }> | Readonly<{
10
15
  kind: "refused";
11
16
  refusal: Refusal;
@@ -13,6 +18,6 @@ export type IntentOutcome<Value, Refusal = never> = Readonly<{
13
18
  kind: "retry";
14
19
  reason: ProtocolTerminal;
15
20
  }>;
16
- export declare function accepted<Value, Refusal = never>(state: ContractState, facts: readonly JournalEntry[], value: Value): IntentOutcome<Value, Refusal>;
17
- export declare function admitted<Value, Refusal = never>(admission: AcceptedAdmission, value: Value): IntentOutcome<Value, Refusal>;
21
+ export declare function accepted<Value, Refusal = never>(state: ContractState, facts: readonly JournalEntry[], value: Value, physical?: ReconcileResult): IntentOutcome<Value, Refusal>;
22
+ export declare function admitted<Value, Refusal = never>(admission: AcceptedProtocolStep, value: Value): IntentOutcome<Value, Refusal>;
18
23
  export declare function complete<Value, Refusal>(result: ProtocolResult<Refusal>, value: Value): IntentOutcome<Value, Refusal>;
@@ -1,10 +1,16 @@
1
- export function accepted(state, facts, value) {
1
+ export function accepted(state, facts, value, physical) {
2
2
  if (state.head === null)
3
3
  throw new Error("accepted contract is missing its journal head");
4
- return { kind: "accepted", facts, head: state.head, value };
4
+ return {
5
+ kind: "accepted",
6
+ facts,
7
+ head: state.head,
8
+ value,
9
+ ...(physical === undefined ? {} : { physical }),
10
+ };
5
11
  }
6
12
  export function admitted(admission, value) {
7
- return accepted(admission.state, admission.facts, value);
13
+ return accepted(admission.state, admission.facts, value, admission.physical);
8
14
  }
9
15
  export function complete(result, value) {
10
16
  if (result.kind === "refused")
@@ -0,0 +1,30 @@
1
+ import type { ActorId, ContractId, SnapshotId } from "../core/facts/types.js";
2
+ import { type PlacementRefusal } from "../core/verbs/placement.js";
3
+ import type { GitDecodeChannel } from "../git/read-observation.js";
4
+ import { type ReconcileResult } from "../git/reconcile.js";
5
+ import { type GitRepository } from "../git/repository.js";
6
+ import { type TargetPlacementRefusal } from "../git/target-placement.js";
7
+ import { type AcceptedAdmission } from "./attempt.js";
8
+ import { type ProtocolResult } from "./run.js";
9
+ export type PlacementExecutionFailure = Readonly<{
10
+ kind: "placement-failed";
11
+ diagnostic: string;
12
+ }>;
13
+ export type TargetMovedStop = Readonly<{
14
+ kind: "target-moved";
15
+ contractId: ContractId;
16
+ target: string;
17
+ expected: SnapshotId;
18
+ observed: SnapshotId | null;
19
+ }>;
20
+ export type PlacementProtocolResult = (AcceptedAdmission & Readonly<{
21
+ physical?: ReconcileResult;
22
+ }>) | Exclude<ProtocolResult<PlacementRefusal | TargetPlacementRefusal>, AcceptedAdmission> | TargetMovedStop | PlacementExecutionFailure;
23
+ type PlacementProtocolInput = Readonly<{
24
+ contractId: ContractId;
25
+ actor?: ActorId;
26
+ at: string;
27
+ }>;
28
+ /** Run the sole placement adjudicator inside the target's physical fence. */
29
+ export declare function admitPlacement(channel: GitDecodeChannel, repository: GitRepository, target: string | undefined, input: PlacementProtocolInput): Promise<PlacementProtocolResult>;
30
+ export {};