@astrosheep/keiyaku 4.0.1 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/README.md +137 -5
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
  9. package/build/src/akuma/abort.d.ts +2 -0
  10. package/build/src/akuma/abort.js +50 -0
  11. package/build/src/akuma/akuma.d.ts +23 -14
  12. package/build/src/akuma/akuma.js +120 -104
  13. package/build/src/akuma/archetype.d.ts +7 -6
  14. package/build/src/akuma/archetype.js +68 -41
  15. package/build/src/akuma/body.d.ts +3 -5
  16. package/build/src/akuma/body.js +408 -213
  17. package/build/src/akuma/heart/facts.d.ts +25 -34
  18. package/build/src/akuma/heart/facts.js +18 -7
  19. package/build/src/akuma/heart/index.d.ts +39 -42
  20. package/build/src/akuma/heart/index.js +134 -93
  21. package/build/src/akuma/heart/rows.d.ts +9 -31
  22. package/build/src/akuma/heart/rows.js +26 -44
  23. package/build/src/akuma/heart/schema.d.ts +1 -1
  24. package/build/src/akuma/heart/schema.js +7 -15
  25. package/build/src/akuma/heart/soul.d.ts +8 -0
  26. package/build/src/akuma/heart/soul.js +136 -0
  27. package/build/src/akuma/heart/storage.d.ts +28 -14
  28. package/build/src/akuma/heart/storage.js +86 -26
  29. package/build/src/akuma/identity.d.ts +2 -2
  30. package/build/src/akuma/identity.js +9 -9
  31. package/build/src/akuma/index.d.ts +6 -1
  32. package/build/src/akuma/index.js +6 -0
  33. package/build/src/akuma/projection.d.ts +117 -38
  34. package/build/src/akuma/projection.js +208 -97
  35. package/build/src/akuma/provider-recipe.d.ts +24 -0
  36. package/build/src/akuma/provider-recipe.js +100 -0
  37. package/build/src/akuma/provider.d.ts +12 -4
  38. package/build/src/akuma/provider.js +117 -70
  39. package/build/src/akuma/providers/acp/core.d.ts +19 -0
  40. package/build/src/akuma/providers/acp/core.js +159 -0
  41. package/build/src/akuma/providers/acp/events.d.ts +20 -0
  42. package/build/src/akuma/providers/acp/events.js +73 -0
  43. package/build/src/akuma/providers/acp/index.d.ts +12 -0
  44. package/build/src/akuma/providers/acp/index.js +94 -0
  45. package/build/src/akuma/providers/claude/events.js +66 -13
  46. package/build/src/akuma/providers/claude/index.d.ts +2 -1
  47. package/build/src/akuma/providers/claude/index.js +35 -21
  48. package/build/src/akuma/providers/codex-app-server/events.js +4 -1
  49. package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
  50. package/build/src/akuma/providers/codex-app-server/index.js +24 -31
  51. package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
  52. package/build/src/akuma/providers/grok-build/index.js +70 -0
  53. package/build/src/akuma/providers/index.d.ts +5 -3
  54. package/build/src/akuma/providers/index.js +24 -59
  55. package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
  56. package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
  57. package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
  58. package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
  59. package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
  60. package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
  61. package/build/src/akuma/providers/pi/events.js +49 -11
  62. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  63. package/build/src/akuma/providers/pi/index.js +50 -21
  64. package/build/src/akuma/publication.d.ts +3 -3
  65. package/build/src/akuma/publication.js +28 -40
  66. package/build/src/akuma/requests.d.ts +9 -7
  67. package/build/src/akuma/requests.js +92 -65
  68. package/build/src/alias/index.d.ts +2 -2
  69. package/build/src/alias/index.js +10 -10
  70. package/build/src/body/decode.js +7 -1
  71. package/build/src/body/region.d.ts +2 -0
  72. package/build/src/body/region.js +77 -7
  73. package/build/src/cli/accepted.d.ts +17 -13
  74. package/build/src/cli/accepted.js +72 -34
  75. package/build/src/cli/actor.js +3 -3
  76. package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
  77. package/build/src/cli/commands/akuma-invoke.js +14 -9
  78. package/build/src/cli/commands/akuma.d.ts +13 -3
  79. package/build/src/cli/commands/akuma.js +67 -34
  80. package/build/src/cli/commands/contract.d.ts +18 -5
  81. package/build/src/cli/commands/contract.js +9 -3
  82. package/build/src/cli/commands/task-invoke.d.ts +17 -4
  83. package/build/src/cli/commands/task-invoke.js +43 -20
  84. package/build/src/cli/commands/task-query.d.ts +5 -0
  85. package/build/src/cli/commands/task-query.js +247 -0
  86. package/build/src/cli/commands/task.d.ts +3 -1
  87. package/build/src/cli/commands/task.js +51 -13
  88. package/build/src/cli/coordinates.d.ts +18 -0
  89. package/build/src/cli/coordinates.js +120 -0
  90. package/build/src/cli/draft.d.ts +8 -0
  91. package/build/src/cli/draft.js +96 -0
  92. package/build/src/cli/invoke.d.ts +4 -3
  93. package/build/src/cli/invoke.js +160 -179
  94. package/build/src/cli/main.js +34 -6
  95. package/build/src/cli/parse.d.ts +9 -2
  96. package/build/src/cli/parse.js +29 -7
  97. package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
  98. package/build/src/cli/render/akuma-tool-command.js +144 -0
  99. package/build/src/cli/render/akuma-tool.d.ts +2 -2
  100. package/build/src/cli/render/akuma-tool.js +30 -4
  101. package/build/src/cli/render/akuma.d.ts +1 -0
  102. package/build/src/cli/render/akuma.js +211 -116
  103. package/build/src/cli/render/audit.d.ts +3 -0
  104. package/build/src/cli/render/audit.js +104 -0
  105. package/build/src/cli/render/contract.d.ts +3 -3
  106. package/build/src/cli/render/contract.js +192 -79
  107. package/build/src/cli/render/kanshi.js +263 -168
  108. package/build/src/cli/render/receipt.d.ts +19 -0
  109. package/build/src/cli/render/receipt.js +106 -0
  110. package/build/src/cli/render/refusal.d.ts +16 -2
  111. package/build/src/cli/render/refusal.js +88 -20
  112. package/build/src/cli/render/region.d.ts +2 -0
  113. package/build/src/cli/render/region.js +17 -0
  114. package/build/src/cli/render/task.d.ts +2 -1
  115. package/build/src/cli/render/task.js +223 -60
  116. package/build/src/cli/render/terminal.d.ts +7 -0
  117. package/build/src/cli/render/terminal.js +46 -0
  118. package/build/src/cli/render/text.js +6 -3
  119. package/build/src/cli/result.d.ts +115 -20
  120. package/build/src/cli/usage.d.ts +1 -0
  121. package/build/src/cli/usage.js +3 -0
  122. package/build/src/contract-worktree.d.ts +6 -5
  123. package/build/src/contract-worktree.js +95 -57
  124. package/build/src/coordination/durable-file.d.ts +4 -3
  125. package/build/src/coordination/durable-file.js +29 -25
  126. package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
  127. package/build/src/coordination/sqlite-transaction-lock.js +22 -5
  128. package/build/src/core/facts/fold.js +1 -6
  129. package/build/src/core/facts/gate.d.ts +1 -0
  130. package/build/src/core/facts/gate.js +1 -0
  131. package/build/src/core/verbs/amend.d.ts +1 -1
  132. package/build/src/core/verbs/amend.js +0 -11
  133. package/build/src/core/verbs/deliver.d.ts +1 -1
  134. package/build/src/core/verbs/deliver.js +1 -7
  135. package/build/src/core/verbs/placement.d.ts +1 -1
  136. package/build/src/core/verbs/placement.js +4 -1
  137. package/build/src/dispatch/index.d.ts +2 -2
  138. package/build/src/dispatch/index.js +17 -17
  139. package/build/src/git/admission.d.ts +1 -1
  140. package/build/src/git/admission.js +11 -11
  141. package/build/src/git/hooks.js +13 -13
  142. package/build/src/git/integration.d.ts +14 -15
  143. package/build/src/git/integration.js +80 -44
  144. package/build/src/git/observe.d.ts +5 -3
  145. package/build/src/git/observe.js +18 -12
  146. package/build/src/git/read-observation.js +9 -9
  147. package/build/src/git/reconcile.d.ts +2 -0
  148. package/build/src/git/reconcile.js +138 -95
  149. package/build/src/git/repository.d.ts +27 -19
  150. package/build/src/git/repository.js +155 -83
  151. package/build/src/git/scratch.d.ts +7 -3
  152. package/build/src/git/scratch.js +44 -37
  153. package/build/src/git/target-placement.d.ts +40 -4
  154. package/build/src/git/target-placement.js +221 -101
  155. package/build/src/git/tender.d.ts +6 -5
  156. package/build/src/git/tender.js +24 -43
  157. package/build/src/git/terminal-seal.d.ts +1 -1
  158. package/build/src/git/terminal-seal.js +7 -5
  159. package/build/src/git/workspace.d.ts +36 -4
  160. package/build/src/git/workspace.js +53 -18
  161. package/build/src/identity/selector.js +1 -1
  162. package/build/src/index.d.ts +3 -3
  163. package/build/src/index.js +1 -1
  164. package/build/src/kanshi/index.d.ts +2 -2
  165. package/build/src/kanshi/index.js +1 -1
  166. package/build/src/kanshi/read.d.ts +2 -1
  167. package/build/src/kanshi/read.js +118 -27
  168. package/build/src/kanshi/report.d.ts +50 -0
  169. package/build/src/kanshi/select.d.ts +5 -0
  170. package/build/src/kanshi/select.js +32 -0
  171. package/build/src/library/address.d.ts +12 -3
  172. package/build/src/library/address.js +77 -46
  173. package/build/src/library/akuma-creation.d.ts +6 -1
  174. package/build/src/library/akuma-creation.js +86 -13
  175. package/build/src/library/audit.d.ts +18 -0
  176. package/build/src/library/audit.js +44 -0
  177. package/build/src/library/bind.js +4 -4
  178. package/build/src/library/catalog.d.ts +1 -1
  179. package/build/src/library/catalog.js +5 -8
  180. package/build/src/library/contract.d.ts +5 -6
  181. package/build/src/library/contract.js +11 -35
  182. package/build/src/library/delivery.d.ts +2 -1
  183. package/build/src/library/fleet.d.ts +2 -2
  184. package/build/src/library/fleet.js +35 -71
  185. package/build/src/library/keiyaku.d.ts +3 -2
  186. package/build/src/library/keiyaku.js +1 -0
  187. package/build/src/library/mutation.d.ts +7 -6
  188. package/build/src/library/mutation.js +23 -25
  189. package/build/src/library/reconcile.d.ts +29 -0
  190. package/build/src/library/reconcile.js +179 -0
  191. package/build/src/library/region.d.ts +12 -0
  192. package/build/src/library/region.js +15 -1
  193. package/build/src/library/repo.d.ts +4 -16
  194. package/build/src/library/repo.js +13 -38
  195. package/build/src/protocol/attempt.js +6 -6
  196. package/build/src/protocol/bind.js +4 -4
  197. package/build/src/protocol/intent.d.ts +15 -2
  198. package/build/src/protocol/intent.js +21 -6
  199. package/build/src/protocol/operations.d.ts +73 -22
  200. package/build/src/protocol/operations.js +292 -88
  201. package/build/src/protocol/outcome.d.ts +9 -3
  202. package/build/src/protocol/outcome.js +3 -1
  203. package/build/src/protocol/placement.d.ts +15 -4
  204. package/build/src/protocol/placement.js +58 -25
  205. package/build/src/protocol/read/status.d.ts +8 -1
  206. package/build/src/protocol/read/status.js +61 -14
  207. package/build/src/runtime/proc/line-rpc.d.ts +3 -8
  208. package/build/src/runtime/proc/line-rpc.js +16 -43
  209. package/build/src/runtime/proc/run.d.ts +15 -29
  210. package/build/src/runtime/proc/run.js +113 -105
  211. package/build/src/runtime/proc/stdio.d.ts +18 -0
  212. package/build/src/runtime/proc/stdio.js +58 -0
  213. package/build/src/settings.d.ts +2 -2
  214. package/build/src/settings.js +8 -8
  215. package/build/src/settlement/fence.d.ts +0 -4
  216. package/build/src/settlement/fence.js +0 -9
  217. package/build/src/settlement/holder.d.ts +11 -1
  218. package/build/src/settlement/holder.js +25 -0
  219. package/build/src/settlement/settle.d.ts +1 -1
  220. package/build/src/settlement/settle.js +52 -89
  221. package/build/src/task/board.d.ts +3 -3
  222. package/build/src/task/board.js +6 -9
  223. package/build/src/task/compose.d.ts +1 -1
  224. package/build/src/task/compose.js +18 -10
  225. package/build/src/task/context.d.ts +3 -3
  226. package/build/src/task/context.js +14 -14
  227. package/build/src/task/document.d.ts +2 -1
  228. package/build/src/task/document.js +15 -5
  229. package/build/src/task/index.d.ts +19 -7
  230. package/build/src/task/index.js +42 -23
  231. package/build/src/task/operations.d.ts +15 -9
  232. package/build/src/task/operations.js +78 -48
  233. package/build/src/task/query.d.ts +67 -0
  234. package/build/src/task/query.js +279 -0
  235. package/build/src/task/store.d.ts +2 -2
  236. package/build/src/task/store.js +40 -25
  237. package/build/src/verification/execution.d.ts +4 -2
  238. package/build/src/verification/execution.js +9 -5
  239. package/build/src/workspace-place.d.ts +41 -0
  240. package/build/src/workspace-place.js +386 -0
  241. package/build/src/world.d.ts +13 -2
  242. package/build/src/world.js +81 -48
  243. package/package.json +3 -2
  244. package/build/src/protocol/read/audit.d.ts +0 -31
  245. package/build/src/protocol/read/audit.js +0 -55
@@ -1,4 +1,3 @@
1
- import { samePrerequisites } from "./eligibility.js";
2
1
  import { gatesSatisfied } from "./gate.js";
3
2
  import { AuthorityCorruptionError } from "./errors.js";
4
3
  function foldError(message) {
@@ -47,12 +46,8 @@ function foldEntry(state, entry, attestations) {
47
46
  switch (entry.kind) {
48
47
  case "bind":
49
48
  foldError("bind may appear only once");
50
- case "amend": {
51
- if (state.bound !== null && !samePrerequisites(state.terms.after, entry.data.after)) {
52
- foldError("cannot change after once prerequisites are consumed");
53
- }
49
+ case "amend":
54
50
  return { ...state, terms: cloneTerms(entry.data) };
55
- }
56
51
  case "bound":
57
52
  if (state.bound !== null)
58
53
  foldError("bound may appear only once");
@@ -3,6 +3,7 @@ export type GateCurrent = Readonly<{
3
3
  kind: "attested";
4
4
  verdict: "satisfied" | "unsatisfied";
5
5
  summary?: string;
6
+ at: string;
6
7
  }> | Readonly<{
7
8
  kind: "stale";
8
9
  priorVerdict: "satisfied" | "unsatisfied";
@@ -37,6 +37,7 @@ export function gateReports(state) {
37
37
  kind: "attested",
38
38
  verdict: attestation.data.verdict,
39
39
  ...(attestation.data.summary === undefined ? {} : { summary: attestation.data.summary }),
40
+ at: attestation.at,
40
41
  },
41
42
  };
42
43
  }
@@ -8,7 +8,7 @@ export type AmendInput<Failure = never> = Readonly<{
8
8
  preparation?: Preparation<AmendData, Failure>;
9
9
  }>;
10
10
  export type AmendRefusal = Readonly<{
11
- kind: "contract-missing" | "terminal" | "terms-moved" | "prerequisites-already-consumed" | "unknown-prerequisite" | "cyclic-prerequisite";
11
+ kind: "contract-missing" | "terminal" | "terms-moved" | "unknown-prerequisite" | "cyclic-prerequisite";
12
12
  contractId: ContractId;
13
13
  }>;
14
14
  export declare function decideAmend<Failure>({ input, attempt, observation }: DecideInput<AmendInput<Failure>>): OfferDecision<AmendRefusal | Failure>;
@@ -1,13 +1,5 @@
1
1
  import { prerequisitesReach, samePrerequisites } from "../facts/eligibility.js";
2
2
  import { activeContract, prerequisiteStatus } from "../facts/observation.js";
3
- function prerequisitesConsumed(current, next, observation) {
4
- if (samePrerequisites(current.terms.after, next.after))
5
- return false;
6
- const status = prerequisiteStatus(current.terms.after, observation);
7
- if (status === "unknown")
8
- throw new Error("current prerequisite is absent from the decision observation");
9
- return current.bound !== null || status === "claimed";
10
- }
11
3
  export function decideAmend({ input, attempt, observation }) {
12
4
  const id = input.contractId;
13
5
  const current = activeContract(observation, id);
@@ -29,9 +21,6 @@ export function decideAmend({ input, attempt, observation }) {
29
21
  if (input.preparation.kind === "refused")
30
22
  return { kind: "refused", refusal: input.preparation.refusal };
31
23
  const { data } = input.preparation;
32
- if (prerequisitesConsumed(current, data, observation)) {
33
- return { kind: "refused", refusal: { kind: "prerequisites-already-consumed", contractId: id } };
34
- }
35
24
  const prerequisites = prerequisiteStatus(data.after, observation);
36
25
  if (prerequisites === "unknown") {
37
26
  return { kind: "refused", refusal: { kind: "unknown-prerequisite", contractId: id } };
@@ -7,7 +7,7 @@ export type DeliverInput<Failure = never> = Readonly<{
7
7
  preparation: StampedPreparation<DeliverData, Failure>;
8
8
  }>;
9
9
  export type DeliverRefusal = Readonly<{
10
- kind: "contract-missing" | "not-bound" | "terminal" | "document-moved";
10
+ kind: "contract-missing" | "terminal" | "document-moved";
11
11
  contractId: ContractId;
12
12
  }>;
13
13
  export declare function decideDeliver<Failure>({ input, attempt, observation, }: DecideInput<DeliverInput<Failure>>): OfferDecision<DeliverRefusal | Failure>;
@@ -1,14 +1,8 @@
1
- import { activeContract, documentIsCurrent, prerequisiteStatus } from "../facts/observation.js";
1
+ import { activeContract, documentIsCurrent } from "../facts/observation.js";
2
2
  export function decideDeliver({ input, attempt, observation, }) {
3
3
  const state = activeContract(observation, input.contractId);
4
4
  if ("kind" in state)
5
5
  return { kind: "refused", refusal: state };
6
- const prerequisites = state.bound === null
7
- ? prerequisiteStatus(state.terms.after, observation)
8
- : "claimed";
9
- if (prerequisites !== "claimed") {
10
- return { kind: "refused", refusal: { kind: "not-bound", contractId: input.contractId } };
11
- }
12
6
  if (input.preparation.kind === "unavailable") {
13
7
  throw new Error("existing contract requires a stamped delivery preparation");
14
8
  }
@@ -6,7 +6,7 @@ type PlacementInput = Readonly<{
6
6
  at: string;
7
7
  }>;
8
8
  export type PlacementRefusal = Readonly<{
9
- kind: "contract-missing" | "delivery-missing" | "terminal" | "gates-unsatisfied";
9
+ kind: "contract-missing" | "delivery-missing" | "terminal" | "prerequisites-unsatisfied" | "gates-unsatisfied";
10
10
  contractId: ContractId;
11
11
  }>;
12
12
  export declare function decidePlacement({ input, attempt, observation }: DecideInput<PlacementInput>): OfferDecision<PlacementRefusal>;
@@ -1,5 +1,5 @@
1
1
  import { gatesSatisfied } from "../facts/gate.js";
2
- import { activeContract } from "../facts/observation.js";
2
+ import { activeContract, prerequisiteStatus } from "../facts/observation.js";
3
3
  export function decidePlacement({ input, attempt, observation }) {
4
4
  const id = input.contractId;
5
5
  const current = activeContract(observation, id);
@@ -9,6 +9,9 @@ export function decidePlacement({ input, attempt, observation }) {
9
9
  if (!delivery) {
10
10
  return { kind: "refused", refusal: { kind: "delivery-missing", contractId: id } };
11
11
  }
12
+ if (prerequisiteStatus(current.terms.after, observation) !== "claimed") {
13
+ return { kind: "refused", refusal: { kind: "prerequisites-unsatisfied", contractId: id } };
14
+ }
12
15
  if (!gatesSatisfied(current)) {
13
16
  return { kind: "refused", refusal: { kind: "gates-unsatisfied", contractId: id } };
14
17
  }
@@ -23,11 +23,11 @@ export type DispatchPublication = Readonly<{
23
23
  kind: "failed";
24
24
  failure: DispatchFailure;
25
25
  }>;
26
- export declare function readDispatch(repository: GitRepository, value: AkuId): Dispatch | null;
26
+ export declare function readDispatch(repository: GitRepository, value: AkuId): Promise<Dispatch | null>;
27
27
  export declare function readDispatchesAt(observation: GitReadObservation): Promise<readonly Dispatch[]>;
28
28
  export declare function readDispatches(repository: GitRepository): Promise<readonly Dispatch[]>;
29
29
  export declare function publishDispatch(input: Readonly<{
30
30
  repository: GitRepository;
31
31
  akuId: AkuId;
32
32
  contractId: ContractId;
33
- }>): DispatchPublication;
33
+ }>): Promise<DispatchPublication>;
@@ -64,19 +64,19 @@ function decode(path, bytes) {
64
64
  }
65
65
  return dispatch;
66
66
  }
67
- function dispatchFromSnapshot(repository, snapshot, akuId) {
67
+ async function dispatchFromSnapshot(repository, snapshot, akuId) {
68
68
  const path = pathFor(akuId);
69
69
  const entry = snapshot.paths.get(path);
70
70
  if (entry === undefined)
71
71
  return null;
72
72
  if (entry.type !== "blob")
73
73
  corruption(`Dispatch path is not a blob: ${path}`);
74
- return decode(path, readBlob(repository, entry.oid));
74
+ return decode(path, await readBlob(repository, entry.oid));
75
75
  }
76
- export function readDispatch(repository, value) {
76
+ export async function readDispatch(repository, value) {
77
77
  const akuId = parseAkuId(value).id;
78
78
  const path = pathFor(akuId);
79
- return dispatchFromSnapshot(repository, readGitPaths(repository, [path]), akuId);
79
+ return await dispatchFromSnapshot(repository, await readGitPaths(repository, [path]), akuId);
80
80
  }
81
81
  export async function readDispatchesAt(observation) {
82
82
  const entries = [...observation.snapshot.paths]
@@ -105,10 +105,10 @@ export async function readDispatchesAt(observation) {
105
105
  return dispatches.sort((left, right) => Buffer.compare(Buffer.from(left.akuId), Buffer.from(right.akuId)));
106
106
  }
107
107
  export async function readDispatches(repository) {
108
- return withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, readDispatchesAt));
108
+ return await withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, readDispatchesAt));
109
109
  }
110
- function observedPublication(repository, akuId, owner) {
111
- const current = readDispatch(repository, akuId);
110
+ async function observedPublication(repository, akuId, owner) {
111
+ const current = await readDispatch(repository, akuId);
112
112
  if (current === null)
113
113
  return null;
114
114
  return current.contractId === owner
@@ -118,14 +118,14 @@ function observedPublication(repository, akuId, owner) {
118
118
  function diagnostic(error) {
119
119
  return error instanceof Error ? error.message : String(error);
120
120
  }
121
- export function publishDispatch(input) {
121
+ export async function publishDispatch(input) {
122
122
  const akuId = parseAkuId(input.akuId).id;
123
123
  const owner = contractId(input.contractId);
124
124
  const intended = { akuId, contractId: owner, dispatchedAt: new Date().toISOString() };
125
125
  const path = pathFor(akuId);
126
126
  for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt += 1) {
127
- const snapshot = readGitPaths(input.repository, [path]);
128
- const current = dispatchFromSnapshot(input.repository, snapshot, akuId);
127
+ const snapshot = await readGitPaths(input.repository, [path]);
128
+ const current = await dispatchFromSnapshot(input.repository, snapshot, akuId);
129
129
  if (current !== null) {
130
130
  return current.contractId === owner
131
131
  ? { kind: "dispatched", dispatch: current }
@@ -133,29 +133,29 @@ export function publishDispatch(input) {
133
133
  }
134
134
  const changes = new Map();
135
135
  if (snapshot.commit === null) {
136
- changes.set(GIT_FORMAT_PATH, { oid: writeBlob(input.repository, GIT_FORMAT_BYTES) });
136
+ changes.set(GIT_FORMAT_PATH, { oid: await writeBlob(input.repository, GIT_FORMAT_BYTES) });
137
137
  }
138
- changes.set(path, { oid: writeBlob(input.repository, bytesFor(intended)) });
139
- const tree = updateGitTree(input.repository, snapshot.tree, changes);
140
- const commit = writeCommit({
138
+ changes.set(path, { oid: await writeBlob(input.repository, bytesFor(intended)) });
139
+ const tree = await updateGitTree(input.repository, snapshot.tree, changes);
140
+ const commit = await writeCommit({
141
141
  repository: input.repository,
142
142
  tree,
143
143
  parent: snapshot.commit,
144
144
  message: `dispatch ${akuId}`,
145
145
  at: intended.dispatchedAt,
146
146
  });
147
- const publication = updateRefsAtomically(input.repository, [{
147
+ const publication = await updateRefsAtomically(input.repository, [{
148
148
  ref: GIT_REF,
149
149
  newOid: commit,
150
150
  expectedOid: snapshot.commit,
151
151
  }]);
152
152
  if (publication.kind === "published")
153
153
  return { kind: "dispatched", dispatch: intended };
154
- const observed = observedPublication(input.repository, akuId, owner);
154
+ const observed = await observedPublication(input.repository, akuId, owner);
155
155
  if (observed !== null)
156
156
  return observed;
157
157
  if (publication.kind === "non-published") {
158
- const fresh = readGitPaths(input.repository, [path]);
158
+ const fresh = await readGitPaths(input.repository, [path]);
159
159
  if (fresh.commit === snapshot.commit) {
160
160
  return {
161
161
  kind: "failed",
@@ -14,5 +14,5 @@ type Unknown = Readonly<{
14
14
  kind: "unknown";
15
15
  }>;
16
16
  export type Admission = Accepted | PublicationFailed | Unknown;
17
- export declare function admit(repository: GitRepository, offer: Offer, admission: GitAdmissionSnapshot, assertions?: readonly GitRefAssertion[]): Admission;
17
+ export declare function admit(repository: GitRepository, offer: Offer, admission: GitAdmissionSnapshot, assertions?: readonly GitRefAssertion[]): Promise<Admission>;
18
18
  export {};
@@ -53,16 +53,16 @@ function readCanonicalJournal(admission, id) {
53
53
  throw new Error(`missing frozen journal bytes: ${path}`);
54
54
  return { bytes: journal, path };
55
55
  }
56
- function buildOffer(repository, admission, appends, companions) {
56
+ async function buildOffer(repository, admission, appends, companions) {
57
57
  const snapshot = admission.snapshot;
58
58
  const changes = new Map();
59
59
  const heads = {};
60
60
  if (snapshot.commit === null) {
61
- changes.set(GIT_FORMAT_PATH, { oid: writeBlob(repository, GIT_FORMAT_BYTES), mode: "100644", type: "blob" });
61
+ changes.set(GIT_FORMAT_PATH, { oid: await writeBlob(repository, GIT_FORMAT_BYTES), mode: "100644", type: "blob" });
62
62
  }
63
63
  for (const companion of companions) {
64
64
  changes.set(companion.path, {
65
- oid: writeBlob(repository, companion.bytes),
65
+ oid: await writeBlob(repository, companion.bytes),
66
66
  mode: "100644",
67
67
  type: "blob",
68
68
  });
@@ -72,7 +72,7 @@ function buildOffer(repository, admission, appends, companions) {
72
72
  let journal = current.bytes;
73
73
  for (const entry of append.entries)
74
74
  journal = Buffer.concat([journal, Buffer.from(encodeEntry(entry))]);
75
- const blob = writeBlob(repository, journal);
75
+ const blob = await writeBlob(repository, journal);
76
76
  const entries = decodeJournal(journal.toString("utf8"));
77
77
  const terminal = entries.some((entry) => entry.kind === "claimed" || entry.kind === "abandoned");
78
78
  const destination = contractJournalPath(append.contractId, terminal ? "terminal" : "active");
@@ -83,15 +83,15 @@ function buildOffer(repository, admission, appends, companions) {
83
83
  }
84
84
  return { changes, heads };
85
85
  }
86
- function publishOffer(repository, admission, target, changes, assertions) {
86
+ async function publishOffer(repository, admission, target, changes, assertions) {
87
87
  const { snapshot } = admission;
88
- const gitTree = updateGitTreeFromFrozenDirectories(repository, snapshot.tree, admission.treeDirectories, changes);
89
- const gitCommit = mintSnapshotId(writeCommit({
88
+ const gitTree = await updateGitTreeFromFrozenDirectories(repository, snapshot.tree, admission.treeDirectories, changes);
89
+ const gitCommit = mintSnapshotId(await writeCommit({
90
90
  repository,
91
91
  tree: gitTree,
92
92
  parent: snapshot.commit,
93
93
  }));
94
- return updateRefsAtomically(repository, [
94
+ return await updateRefsAtomically(repository, [
95
95
  { ref: GIT_REF, newOid: gitObjectIdForSnapshot(gitCommit), expectedOid: snapshot.commit },
96
96
  ...(target === null
97
97
  ? []
@@ -102,15 +102,15 @@ function publishOffer(repository, admission, target, changes, assertions) {
102
102
  }]),
103
103
  ], assertions);
104
104
  }
105
- export function admit(repository, offer, admission, assertions = []) {
105
+ export async function admit(repository, offer, admission, assertions = []) {
106
106
  if (!Array.isArray(offer.facts) || offer.facts.length === 0) {
107
107
  throw new Error("facts must be a nonempty array");
108
108
  }
109
109
  const appends = assertAppendStructure(offer.facts);
110
110
  const companions = assertCompanionStructure(offer.companions ?? [], appends);
111
111
  const target = offer.target ?? null;
112
- const attempt = buildOffer(repository, admission, appends, companions);
113
- const publication = publishOffer(repository, admission, target, attempt.changes, assertions);
112
+ const attempt = await buildOffer(repository, admission, appends, companions);
113
+ const publication = await publishOffer(repository, admission, target, attempt.changes, assertions);
114
114
  if (publication.kind === "published") {
115
115
  return {
116
116
  kind: "accepted",
@@ -1,4 +1,4 @@
1
- import { mkdirSync, readFileSync } from "node:fs";
1
+ import { mkdir, readFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { replaceFileDurably } from "../coordination/durable-file.js";
@@ -140,9 +140,9 @@ function decodeMarker(bytes) {
140
140
  export function hookMarkerPath(administrationDirectory) {
141
141
  return join(administrationDirectory, "keiyaku", "hooks.json");
142
142
  }
143
- function readMarker(administrationDirectory) {
143
+ async function readMarker(administrationDirectory) {
144
144
  try {
145
- return decodeMarker(readFileSync(hookMarkerPath(administrationDirectory), "utf8"));
145
+ return decodeMarker(await readFile(hookMarkerPath(administrationDirectory), "utf8"));
146
146
  }
147
147
  catch (error) {
148
148
  if (error.code === "ENOENT")
@@ -150,10 +150,10 @@ function readMarker(administrationDirectory) {
150
150
  throw error;
151
151
  }
152
152
  }
153
- function writeMarker(administrationDirectory, marker) {
153
+ async function writeMarker(administrationDirectory, marker) {
154
154
  const path = hookMarkerPath(administrationDirectory);
155
- mkdirSync(dirname(path), { recursive: true });
156
- replaceFileDurably(path, `${JSON.stringify(marker)}\n`);
155
+ await mkdir(dirname(path), { recursive: true });
156
+ await replaceFileDurably(path, `${JSON.stringify(marker)}\n`);
157
157
  }
158
158
  function freshMarker(commands, createPending) {
159
159
  return {
@@ -227,7 +227,7 @@ async function executePendingCommand(input) {
227
227
  mode: "immediate",
228
228
  });
229
229
  try {
230
- const marker = readMarker(input.administrationDirectory);
230
+ const marker = await readMarker(input.administrationDirectory);
231
231
  if (marker === null)
232
232
  throw new Error("worktree hook marker disappeared before execution");
233
233
  const progress = marker[input.phase];
@@ -241,7 +241,7 @@ async function executePendingCommand(input) {
241
241
  throw new Error("managed hook runner cancelled without a signal");
242
242
  const failure = result.kind === "failed" ? result.failure : null;
243
243
  const next = input.command + 1;
244
- writeMarker(input.administrationDirectory, withProgress(marker, input.phase, failure === null
244
+ await writeMarker(input.administrationDirectory, withProgress(marker, input.phase, failure === null
245
245
  ? next === marker.commands[input.phase].length ? { status: "ok" } : { status: "pending", next }
246
246
  : { status: "failed", command: input.command, failure }));
247
247
  }
@@ -268,14 +268,14 @@ async function runPendingCommand(input) {
268
268
  throw runnerFailure(outcome);
269
269
  }
270
270
  async function runPhase(worktree, administrationDirectory, hooks, phase, retryHooks) {
271
- let marker = readMarker(administrationDirectory);
271
+ let marker = await readMarker(administrationDirectory);
272
272
  if (marker === null) {
273
273
  marker = freshMarker(hooks, phase === "create");
274
- writeMarker(administrationDirectory, marker);
274
+ await writeMarker(administrationDirectory, marker);
275
275
  }
276
276
  let retryFailure = retryHooks && marker[phase].status === "failed";
277
277
  for (;;) {
278
- marker = readMarker(administrationDirectory);
278
+ marker = await readMarker(administrationDirectory);
279
279
  if (marker === null)
280
280
  throw new Error("worktree hook marker disappeared during execution");
281
281
  const progress = marker[phase];
@@ -286,11 +286,11 @@ async function runPhase(worktree, administrationDirectory, hooks, phase, retryHo
286
286
  return { kind: "worktree-hook-failed", phase, path: worktree, command: progress.command, failure: progress.failure };
287
287
  }
288
288
  retryFailure = false;
289
- writeMarker(administrationDirectory, withProgress(marker, phase, { status: "pending", next: progress.command }));
289
+ await writeMarker(administrationDirectory, withProgress(marker, phase, { status: "pending", next: progress.command }));
290
290
  continue;
291
291
  }
292
292
  if (progress.next === marker.commands[phase].length) {
293
- writeMarker(administrationDirectory, withProgress(marker, phase, { status: "ok" }));
293
+ await writeMarker(administrationDirectory, withProgress(marker, phase, { status: "ok" }));
294
294
  continue;
295
295
  }
296
296
  await runPendingCommand({ administrationDirectory, worktree, phase, command: progress.next });
@@ -3,7 +3,6 @@ import type { ChangeId, ContractCoordinates, ContractId, SnapshotId } from "../c
3
3
  import { type GitObjectId } from "./identity.js";
4
4
  import { type GitRepository } from "./repository.js";
5
5
  import type { TenderCapture } from "./tender.js";
6
- import type { WorkspaceDirtyDelta } from "./tender.js";
7
6
  declare const REQUIRED_GIT: "2.38";
8
7
  export type IntegrationPreparationRefusal = Readonly<{
9
8
  kind: "integration-failed";
@@ -23,27 +22,27 @@ export type IntegrationCoordinates = Readonly<{
23
22
  export type IntegrationPlan = Readonly<{
24
23
  predecessor: SnapshotId;
25
24
  tree: GitObjectId;
26
- changeId: ChangeId;
27
- }>;
28
- export type ReviewIntegration = Readonly<{
29
- changeId: ChangeId;
30
- workspace?: WorkspaceDirtyDelta;
31
25
  }>;
26
+ /** Mint the one worktree-content identity shared by review and delivery. */
27
+ export declare function worktreeChangeId(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture): Promise<ChangeId>;
32
28
  /** Materialize the exact integration tree against its observed predecessor. */
33
29
  export declare function materializeIntegrationSnapshot(repository: GitRepository, tree: GitObjectId, parent: SnapshotId, input: Readonly<{
34
30
  contractId: ContractId;
35
31
  title: string;
36
32
  message?: string;
37
- }>): SnapshotId;
38
- export declare function planIntegration(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture, requireBranchesToBeUpToDate: boolean): Preparation<IntegrationPlan, Readonly<{
39
- kind: "target-missing";
40
- contractId: ContractId;
41
- }> | IntegrationPreparationRefusal>;
42
- /** Prepare the integration-derived review subject from one captured tender. */
43
- export declare function prepareReviewIntegration(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture, workspace?: WorkspaceDirtyDelta): Preparation<ReviewIntegration, Readonly<{
33
+ }>): Promise<SnapshotId>;
34
+ export declare function planIntegration(repository: GitRepository, input: IntegrationCoordinates, tender: TenderCapture, requireBranchesToBeUpToDate: boolean): Promise<Preparation<IntegrationPlan, Readonly<{
44
35
  kind: "target-missing";
45
36
  contractId: ContractId;
46
- }> | IntegrationPreparationRefusal>;
37
+ }> | IntegrationPreparationRefusal>>;
38
+ export type DeliveryDiffScope = Readonly<{
39
+ filesChanged: number;
40
+ insertions: number;
41
+ deletions: number;
42
+ paths?: readonly string[];
43
+ }>;
44
+ /** Compute predecessor-to-candidate scope from the exact integration trees. */
45
+ export declare function readDeliveryScope(repository: GitRepository, predecessor: SnapshotId, candidate: SnapshotId, includePaths: boolean): Promise<DeliveryDiffScope>;
47
46
  /** Read a recorded integration pair's patch, or null when Git no longer has it. */
48
- export declare function readDeliveryDiff(repository: GitRepository, predecessor: SnapshotId, candidate: SnapshotId): string | null;
47
+ export declare function readDeliveryDiff(repository: GitRepository, predecessor: SnapshotId, candidate: SnapshotId): Promise<string | null>;
49
48
  export {};