@astrosheep/keiyaku 4.0.3 → 4.0.5

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 (238) hide show
  1. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  2. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
  9. package/build/src/akuma/akuma.d.ts +34 -12
  10. package/build/src/akuma/akuma.js +118 -63
  11. package/build/src/akuma/allowed.d.ts +7 -0
  12. package/build/src/akuma/allowed.js +33 -0
  13. package/build/src/akuma/archetype.d.ts +7 -4
  14. package/build/src/akuma/archetype.js +15 -16
  15. package/build/src/akuma/body.d.ts +6 -1
  16. package/build/src/akuma/body.js +36 -27
  17. package/build/src/akuma/heart/facts.d.ts +82 -14
  18. package/build/src/akuma/heart/index.d.ts +5 -18
  19. package/build/src/akuma/heart/index.js +14 -84
  20. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  21. package/build/src/akuma/heart/request-authority.js +119 -0
  22. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  23. package/build/src/akuma/heart/request-rows.js +88 -0
  24. package/build/src/akuma/heart/rows.d.ts +1 -26
  25. package/build/src/akuma/heart/rows.js +0 -50
  26. package/build/src/akuma/heart/schema.d.ts +1 -1
  27. package/build/src/akuma/heart/schema.js +22 -10
  28. package/build/src/akuma/heart/soul.js +2 -36
  29. package/build/src/akuma/heart/storage.d.ts +1 -0
  30. package/build/src/akuma/heart/storage.js +15 -0
  31. package/build/src/akuma/heart/timeline.d.ts +1 -5
  32. package/build/src/akuma/heart/timeline.js +8 -17
  33. package/build/src/akuma/index.d.ts +5 -2
  34. package/build/src/akuma/index.js +1 -0
  35. package/build/src/akuma/projection.d.ts +17 -3
  36. package/build/src/akuma/projection.js +40 -3
  37. package/build/src/akuma/provider-recipe.js +1 -11
  38. package/build/src/akuma/provider.d.ts +2 -7
  39. package/build/src/akuma/provider.js +2 -1
  40. package/build/src/akuma/providers/acp/core.d.ts +3 -1
  41. package/build/src/akuma/providers/acp/core.js +10 -6
  42. package/build/src/akuma/providers/acp/events.d.ts +11 -3
  43. package/build/src/akuma/providers/acp/events.js +78 -4
  44. package/build/src/akuma/providers/acp/index.js +0 -1
  45. package/build/src/akuma/providers/claude/events.js +62 -3
  46. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  47. package/build/src/akuma/providers/claude/index.js +7 -3
  48. package/build/src/akuma/providers/codex-app-server/events.js +1 -13
  49. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  50. package/build/src/akuma/providers/codex-app-server/index.js +0 -2
  51. package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
  52. package/build/src/akuma/providers/grok-build/index.js +72 -3
  53. package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
  54. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  55. package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
  56. package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
  57. package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
  58. package/build/src/akuma/providers/pi/events.js +17 -3
  59. package/build/src/akuma/providers/pi/index.js +11 -4
  60. package/build/src/akuma/providers/unified-patch.d.ts +4 -0
  61. package/build/src/akuma/providers/unified-patch.js +14 -0
  62. package/build/src/akuma/publication.d.ts +1 -1
  63. package/build/src/akuma/publication.js +1 -1
  64. package/build/src/akuma/request-serve.d.ts +87 -0
  65. package/build/src/akuma/request-serve.js +484 -0
  66. package/build/src/akuma/request-wire.d.ts +124 -0
  67. package/build/src/akuma/request-wire.js +380 -0
  68. package/build/src/akuma/requests.d.ts +41 -41
  69. package/build/src/akuma/requests.js +75 -374
  70. package/build/src/akuma-body.d.ts +8 -0
  71. package/build/src/akuma-body.js +84 -0
  72. package/build/src/body/arc.js +4 -29
  73. package/build/src/body/decode.js +5 -39
  74. package/build/src/body/envelope.d.ts +7 -0
  75. package/build/src/body/envelope.js +37 -0
  76. package/build/src/cli/accepted.d.ts +4 -1
  77. package/build/src/cli/accepted.js +39 -9
  78. package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
  79. package/build/src/cli/commands/akuma-invoke.js +18 -10
  80. package/build/src/cli/commands/akuma.d.ts +11 -2
  81. package/build/src/cli/commands/akuma.js +67 -28
  82. package/build/src/cli/commands/amend.d.ts +1 -1
  83. package/build/src/cli/commands/amend.js +1 -1
  84. package/build/src/cli/commands/contract.d.ts +8 -8
  85. package/build/src/cli/commands/contract.js +3 -3
  86. package/build/src/cli/commands/install.js +2 -2
  87. package/build/src/cli/commands/task-invoke.js +98 -9
  88. package/build/src/cli/commands/task-query.d.ts +1 -1
  89. package/build/src/cli/commands/task-query.js +11 -5
  90. package/build/src/cli/coordinates.d.ts +2 -0
  91. package/build/src/cli/coordinates.js +12 -5
  92. package/build/src/cli/invoke.d.ts +1 -0
  93. package/build/src/cli/invoke.js +116 -75
  94. package/build/src/cli/main.d.ts +2 -0
  95. package/build/src/cli/main.js +29 -4
  96. package/build/src/cli/parse.d.ts +3 -2
  97. package/build/src/cli/parse.js +25 -8
  98. package/build/src/cli/render/akuma.d.ts +2 -2
  99. package/build/src/cli/render/akuma.js +138 -24
  100. package/build/src/cli/render/audit.js +18 -8
  101. package/build/src/cli/render/contract.d.ts +2 -0
  102. package/build/src/cli/render/contract.js +243 -36
  103. package/build/src/cli/render/kanshi.js +64 -29
  104. package/build/src/cli/render/receipt.d.ts +2 -1
  105. package/build/src/cli/render/receipt.js +37 -2
  106. package/build/src/cli/render/terminal.d.ts +0 -2
  107. package/build/src/cli/render/terminal.js +0 -29
  108. package/build/src/cli/render/text.js +3 -1
  109. package/build/src/cli/result.d.ts +52 -9
  110. package/build/src/cli/selectors.d.ts +1 -0
  111. package/build/src/cli/selectors.js +9 -6
  112. package/build/src/contract-worktree.d.ts +1 -2
  113. package/build/src/contract-worktree.js +7 -9
  114. package/build/src/core/facts/codec.js +9 -0
  115. package/build/src/core/facts/fold.js +13 -1
  116. package/build/src/core/facts/types.d.ts +8 -1
  117. package/build/src/core/subject.js +4 -3
  118. package/build/src/core/verbs/placement.d.ts +9 -1
  119. package/build/src/core/verbs/placement.js +24 -6
  120. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  121. package/build/src/core/verbs/reintegrate.js +24 -0
  122. package/build/src/dispatch/index.d.ts +1 -1
  123. package/build/src/dispatch/index.js +50 -39
  124. package/build/src/git/admission.d.ts +2 -1
  125. package/build/src/git/hooks.d.ts +0 -4
  126. package/build/src/git/hooks.js +0 -36
  127. package/build/src/git/integration.d.ts +7 -8
  128. package/build/src/git/integration.js +62 -9
  129. package/build/src/git/observe.d.ts +2 -1
  130. package/build/src/git/observe.js +6 -5
  131. package/build/src/git/process.d.ts +26 -0
  132. package/build/src/git/process.js +94 -0
  133. package/build/src/git/read-observation.d.ts +2 -1
  134. package/build/src/git/read-observation.js +3 -2
  135. package/build/src/git/reconcile.d.ts +8 -2
  136. package/build/src/git/reconcile.js +63 -14
  137. package/build/src/git/repository.d.ts +2 -29
  138. package/build/src/git/repository.js +4 -118
  139. package/build/src/git/scratch.d.ts +1 -1
  140. package/build/src/git/scratch.js +1 -1
  141. package/build/src/git/target-placement.d.ts +1 -1
  142. package/build/src/git/target-placement.js +9 -7
  143. package/build/src/git/tender.d.ts +20 -5
  144. package/build/src/git/tender.js +45 -13
  145. package/build/src/git/terminal-seal.d.ts +16 -2
  146. package/build/src/git/terminal-seal.js +15 -5
  147. package/build/src/git/workspace.d.ts +2 -1
  148. package/build/src/git/workspace.js +13 -5
  149. package/build/src/index.d.ts +1 -2
  150. package/build/src/index.js +1 -1
  151. package/build/src/kanshi/index.d.ts +1 -1
  152. package/build/src/kanshi/index.js +1 -1
  153. package/build/src/kanshi/read.d.ts +9 -1
  154. package/build/src/kanshi/read.js +91 -37
  155. package/build/src/kanshi/report.d.ts +1 -0
  156. package/build/src/library/address.d.ts +5 -14
  157. package/build/src/library/address.js +27 -23
  158. package/build/src/library/akuma-creation.d.ts +4 -2
  159. package/build/src/library/akuma-creation.js +43 -26
  160. package/build/src/library/audit.d.ts +2 -1
  161. package/build/src/library/audit.js +1 -1
  162. package/build/src/library/bind.d.ts +2 -1
  163. package/build/src/library/bind.js +4 -4
  164. package/build/src/library/catalog.d.ts +1 -2
  165. package/build/src/library/catalog.js +11 -6
  166. package/build/src/library/configuration.d.ts +5 -1
  167. package/build/src/library/configuration.js +71 -18
  168. package/build/src/library/contract.d.ts +70 -3
  169. package/build/src/library/contract.js +213 -27
  170. package/build/src/library/delivery.d.ts +1 -1
  171. package/build/src/library/fleet.d.ts +70 -12
  172. package/build/src/library/fleet.js +236 -56
  173. package/build/src/library/input.d.ts +0 -1
  174. package/build/src/library/input.js +1 -5
  175. package/build/src/library/keiyaku.d.ts +4 -4
  176. package/build/src/library/keiyaku.js +1 -2
  177. package/build/src/library/mutation.d.ts +2 -1
  178. package/build/src/library/reconcile.d.ts +2 -1
  179. package/build/src/library/reconcile.js +3 -1
  180. package/build/src/library/region.d.ts +1 -1
  181. package/build/src/library/repo.d.ts +3 -1
  182. package/build/src/library/repo.js +8 -4
  183. package/build/src/protocol/abandon.d.ts +9 -0
  184. package/build/src/protocol/abandon.js +15 -0
  185. package/build/src/protocol/amend.d.ts +16 -0
  186. package/build/src/protocol/amend.js +77 -0
  187. package/build/src/protocol/arc.d.ts +6 -0
  188. package/build/src/protocol/arc.js +12 -0
  189. package/build/src/protocol/attempt.d.ts +2 -1
  190. package/build/src/protocol/audit.d.ts +53 -0
  191. package/build/src/protocol/audit.js +140 -0
  192. package/build/src/protocol/bind.d.ts +2 -3
  193. package/build/src/protocol/bind.js +2 -16
  194. package/build/src/protocol/completion.d.ts +32 -0
  195. package/build/src/protocol/completion.js +130 -0
  196. package/build/src/protocol/deliver.d.ts +37 -0
  197. package/build/src/protocol/deliver.js +160 -0
  198. package/build/src/protocol/intent.d.ts +1 -1
  199. package/build/src/protocol/intent.js +1 -1
  200. package/build/src/protocol/operations.d.ts +65 -198
  201. package/build/src/protocol/operations.js +21 -634
  202. package/build/src/protocol/placement.d.ts +4 -13
  203. package/build/src/protocol/placement.js +3 -15
  204. package/build/src/protocol/read/status.d.ts +4 -2
  205. package/build/src/protocol/read/status.js +27 -15
  206. package/build/src/protocol/reconcile.d.ts +35 -0
  207. package/build/src/protocol/reconcile.js +41 -0
  208. package/build/src/protocol/reintegrate.d.ts +31 -0
  209. package/build/src/protocol/reintegrate.js +74 -0
  210. package/build/src/protocol/review.d.ts +33 -0
  211. package/build/src/protocol/review.js +148 -0
  212. package/build/src/protocol/run.d.ts +1 -1
  213. package/build/src/runtime/proc/run.d.ts +1 -0
  214. package/build/src/runtime/proc/run.js +9 -2
  215. package/build/src/settlement/fence.d.ts +1 -1
  216. package/build/src/settlement/holder.d.ts +1 -1
  217. package/build/src/settlement/settle.d.ts +2 -1
  218. package/build/src/settlement/settle.js +4 -1
  219. package/build/src/task/board.d.ts +18 -4
  220. package/build/src/task/board.js +73 -29
  221. package/build/src/task/compose.d.ts +1 -1
  222. package/build/src/task/compose.js +11 -4
  223. package/build/src/task/index.d.ts +4 -4
  224. package/build/src/task/index.js +8 -131
  225. package/build/src/task/input.d.ts +18 -0
  226. package/build/src/task/input.js +189 -0
  227. package/build/src/task/mutation.d.ts +39 -0
  228. package/build/src/task/mutation.js +85 -0
  229. package/build/src/task/operations.d.ts +4 -19
  230. package/build/src/task/operations.js +64 -18
  231. package/build/src/task/query.d.ts +9 -2
  232. package/build/src/task/query.js +32 -64
  233. package/build/src/task/store.js +0 -2
  234. package/build/src/verification/execution.d.ts +1 -1
  235. package/build/src/verification/execution.js +2 -1
  236. package/build/src/workspace-place.d.ts +1 -4
  237. package/build/src/workspace-place.js +0 -15
  238. package/package.json +5 -3
@@ -2,8 +2,8 @@ import type { ActorId, ContractId, SnapshotId } from "../core/facts/types.js";
2
2
  import { type PlacementRefusal } from "../core/verbs/placement.js";
3
3
  import type { GitDecodeChannel } from "../git/read-observation.js";
4
4
  import { type ReconcileResult } from "../git/reconcile.js";
5
- import { type GitRepository } from "../git/repository.js";
6
- import { type TargetPlacementObservationInput, type TargetPlacementRefusal } from "../git/target-placement.js";
5
+ import { type GitRepository } from "../git/process.js";
6
+ import { type TargetPlacementRefusal } from "../git/target-placement.js";
7
7
  import { type AcceptedAdmission } from "./attempt.js";
8
8
  import { type ProtocolResult } from "./run.js";
9
9
  export type PlacementExecutionFailure = Readonly<{
@@ -25,17 +25,8 @@ type PlacementProtocolInput = Readonly<{
25
25
  actor?: ActorId;
26
26
  at: string;
27
27
  }>;
28
- export type ProspectiveTargetPreview = Readonly<{
29
- kind: "ready";
30
- }> | Readonly<{
31
- kind: "refused";
32
- refusal: TargetPlacementRefusal;
33
- }> | Readonly<{
34
- kind: "failed";
35
- diagnostic: string;
36
- }>;
37
- /** Observe prospective target followability without fencing or placing. */
38
- export declare function observeProspectiveTargetPlacement(repository: GitRepository, input: TargetPlacementObservationInput): Promise<ProspectiveTargetPreview>;
28
+ /** Hold the existing target-placement fence for one owner callback. */
29
+ export declare function runUnderTargetPlacementFence<T>(repository: GitRepository, target: string, run: () => Promise<T>, onReleaseFailure?: (result: T, error: unknown) => T | PlacementExecutionFailure): Promise<T | PlacementExecutionFailure>;
39
30
  /** Run the sole placement adjudicator inside the target's physical fence. */
40
31
  export declare function admitPlacement<ExtraRefusal = never>(channel: GitDecodeChannel, repository: GitRepository, target: string | undefined, input: PlacementProtocolInput, onDeliveryMissing?: () => Promise<PlacementProtocolResult<ExtraRefusal> | undefined>): Promise<PlacementProtocolResult<ExtraRefusal>>;
41
32
  export {};
@@ -4,8 +4,8 @@ import { contractState } from "../core/facts/observation.js";
4
4
  import { decidePlacement } from "../core/verbs/placement.js";
5
5
  import { observeGitForAdmissionAt } from "../git/observe.js";
6
6
  import { reconcileEffectFailure } from "../git/reconcile.js";
7
- import { GitPlumbingError } from "../git/repository.js";
8
- import { acquireTargetPlacementFence, followTargetPlacement, prepareTargetPlacement, observeTargetHead, observeTargetPlacement, } from "../git/target-placement.js";
7
+ import { GitPlumbingError } from "../git/process.js";
8
+ import { acquireTargetPlacementFence, followTargetPlacement, prepareTargetPlacement, observeTargetHead, } from "../git/target-placement.js";
9
9
  import { admitDecidedOffer, mintAttempts } from "./attempt.js";
10
10
  import { prepareProtocolAttempt, runProtocol, } from "./run.js";
11
11
  function placementFailure(error) {
@@ -20,18 +20,6 @@ function expectedOperationalDiagnostic(error) {
20
20
  function expectedPlacementFailure(error) {
21
21
  return { kind: "placement-failed", diagnostic: expectedOperationalDiagnostic(error) };
22
22
  }
23
- /** Observe prospective target followability without fencing or placing. */
24
- export async function observeProspectiveTargetPlacement(repository, input) {
25
- try {
26
- const observed = await observeTargetPlacement(repository, input);
27
- return observed.kind === "ready"
28
- ? { kind: "ready" }
29
- : { kind: "refused", refusal: observed.refusal };
30
- }
31
- catch (error) {
32
- return { kind: "failed", diagnostic: expectedOperationalDiagnostic(error) };
33
- }
34
- }
35
23
  async function runFencedPlacement(repository, input, protocol) {
36
24
  for (let index = 0; index < protocol.attempts.length; index += 1) {
37
25
  const prepared = await prepareProtocolAttempt(protocol, protocol.attempts[index]);
@@ -74,7 +62,7 @@ async function runFencedPlacement(repository, input, protocol) {
74
62
  return { kind: "exhausted" };
75
63
  }
76
64
  /** Hold the existing target-placement fence for one owner callback. */
77
- async function runUnderTargetPlacementFence(repository, target, run, onReleaseFailure) {
65
+ export async function runUnderTargetPlacementFence(repository, target, run, onReleaseFailure) {
78
66
  let held;
79
67
  try {
80
68
  held = await acquireTargetPlacementFence(repository, target);
@@ -1,5 +1,5 @@
1
1
  import type { ContractTargetLag, ContractWorkspaceObservation } from "../../git/workspace.js";
2
- import type { GitRepository } from "../../git/repository.js";
2
+ import type { GitRepository } from "../../git/process.js";
3
3
  import type { GitDecodeChannel, GitReadObservation } from "../../git/read-observation.js";
4
4
  import { type GateCurrent } from "../../core/facts/gate.js";
5
5
  import type { ContractId, ContractState, DeliverData, SnapshotId } from "../../core/facts/types.js";
@@ -46,6 +46,8 @@ export type ContractObservation = Readonly<{
46
46
  }>;
47
47
  export declare function phaseAtFor(state: Pick<ContractState, "terminal" | "delivery" | "bound">, bindAt: string): string;
48
48
  /** Build the Contract board from one immutable git observation. */
49
- export declare function readContractBoard(observation: GitReadObservation): Promise<ContractBoard>;
49
+ export declare function readContractBoard(observation: GitReadObservation, selected?: ContractId): Promise<ContractBoard>;
50
+ /** Observe one Contract and its target from one fresh ref epoch. */
51
+ export declare function readContractObservation(observation: GitReadObservation, id: ContractId): Promise<ContractObservation>;
50
52
  /** Observe one Contract and its target from one fresh ref epoch. */
51
53
  export declare function readContractObservationAt(repository: GitRepository, channel: GitDecodeChannel, id: ContractId): Promise<ContractObservation>;
@@ -67,7 +67,9 @@ async function rowFor(repository, state, bindAt, targetObservation, register) {
67
67
  workspaceObservation,
68
68
  target: state.coordinates.target ?? null,
69
69
  targetLag,
70
- delivery: state.delivery?.data ?? null,
70
+ delivery: state.delivery === null || state.currentIntegration === null
71
+ ? null
72
+ : { ...state.delivery.data, integration: state.currentIntegration },
71
73
  targetObservation,
72
74
  gates: {
73
75
  reports: gates.reports.map((report) => ({ gate: report.gate, current: report.current })),
@@ -76,7 +78,15 @@ async function rowFor(repository, state, bindAt, targetObservation, register) {
76
78
  };
77
79
  }
78
80
  /** Build the Contract board from one immutable git observation. */
79
- export async function readContractBoard(observation) {
81
+ export async function readContractBoard(observation, selected) {
82
+ if (selected !== undefined) {
83
+ const contract = await readContractObservation(observation, selected);
84
+ return {
85
+ root: observation.repository.primaryWorktree,
86
+ state: observation.snapshot.commit,
87
+ rows: contract.kind === "missing" ? [] : [contract.row],
88
+ };
89
+ }
80
90
  const observed = await observeActiveContractWorld(observation);
81
91
  const register = await readPlaceRegister(observation.repository);
82
92
  const rows = [];
@@ -90,18 +100,20 @@ export async function readContractBoard(observation) {
90
100
  return { root: observation.repository.primaryWorktree, state: observed.snapshot, rows: await Promise.all(rows) };
91
101
  }
92
102
  /** Observe one Contract and its target from one fresh ref epoch. */
103
+ export async function readContractObservation(observation, id) {
104
+ const observed = await observeContractsForAdmissionInObservationAt(observation, [id]);
105
+ const record = observed.journals.get(id);
106
+ if (record === undefined)
107
+ throw new Error(`missing requested Contract observation: ${id}`);
108
+ const state = record.state;
109
+ return state === null
110
+ ? { kind: "missing", id }
111
+ : {
112
+ kind: "present",
113
+ row: await rowFor(observation.repository, state, record.entries[0].at, await observeDeliveryTargetAt(observation, state), await readPlaceRegister(observation.repository)),
114
+ };
115
+ }
116
+ /** Observe one Contract and its target from one fresh ref epoch. */
93
117
  export async function readContractObservationAt(repository, channel, id) {
94
- return withContractReadObservationAt(repository, channel, id, async (observation) => {
95
- const observed = await observeContractsForAdmissionInObservationAt(observation, [id]);
96
- const record = observed.journals.get(id);
97
- if (record === undefined)
98
- throw new Error(`missing requested Contract observation: ${id}`);
99
- const state = record.state;
100
- return state === null
101
- ? { kind: "missing", id }
102
- : {
103
- kind: "present",
104
- row: await rowFor(observation.repository, state, record.entries[0].at, await observeDeliveryTargetAt(observation, state), await readPlaceRegister(observation.repository)),
105
- };
106
- });
118
+ return withContractReadObservationAt(repository, channel, id, async (observation) => await readContractObservation(observation, id));
107
119
  }
@@ -0,0 +1,35 @@
1
+ import { type ReconcileResult } from "../git/reconcile.js";
2
+ import type { ContractId, ContractState } from "../core/facts/types.js";
3
+ import type { WorktreeHooks } from "../git/hooks.js";
4
+ import type { GitDecodeChannel } from "../git/read-observation.js";
5
+ import type { MutationOperationInput, RepositoryScope } from "./operations.js";
6
+ export type ReconcileReport = ReconcileResult;
7
+ type ReconcileObservation = Readonly<{
8
+ state: ContractState | null;
9
+ report: ReconcileReport;
10
+ }>;
11
+ type ReconcileOptions = Readonly<{
12
+ hooks: WorktreeHooks;
13
+ retryHooks: boolean;
14
+ retainTerminalWorktree?: boolean;
15
+ place?: string;
16
+ places?: ReadonlyMap<ContractId, string>;
17
+ }>;
18
+ export declare function reconcileOperation(input: MutationOperationInput & ReconcileOptions): Promise<ReconcileObservation>;
19
+ type RepoReconcileItem = Readonly<{
20
+ contractId: ContractId;
21
+ state: ContractState | null;
22
+ report: ReconcileReport;
23
+ }>;
24
+ type RepoReconcileReport = Readonly<{
25
+ contracts: readonly RepoReconcileItem[];
26
+ }>;
27
+ export declare function worldContractStates(input: Readonly<{
28
+ scope: RepositoryScope;
29
+ channel: GitDecodeChannel;
30
+ }>): Promise<readonly ContractState[]>;
31
+ export declare function reconcileAllOperation(input: Readonly<{
32
+ scope: RepositoryScope;
33
+ channel: GitDecodeChannel;
34
+ }> & ReconcileOptions): Promise<RepoReconcileReport>;
35
+ export {};
@@ -0,0 +1,41 @@
1
+ import { reconcile, reconcileBatch, reconcileObservationFailure } from "../git/reconcile.js";
2
+ import { observeContractWorld } from "../git/observe.js";
3
+ import { withGitReadObservation } from "../git/read-observation.js";
4
+ import { AuthorityCorruptionError } from "../core/facts/errors.js";
5
+ export async function reconcileOperation(input) {
6
+ try {
7
+ const observation = await reconcile({
8
+ repository: input.scope,
9
+ channel: input.channel,
10
+ contractId: input.contractId,
11
+ hooks: input.hooks,
12
+ retryHooks: input.retryHooks,
13
+ ...(input.retainTerminalWorktree === undefined ? {} : { retainTerminalWorktree: input.retainTerminalWorktree }),
14
+ ...(input.place === undefined ? {} : { place: input.place }),
15
+ });
16
+ return { state: observation.state, report: observation.result };
17
+ }
18
+ catch (error) {
19
+ if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
20
+ throw error;
21
+ return { state: null, report: reconcileObservationFailure(error) };
22
+ }
23
+ }
24
+ export async function worldContractStates(input) {
25
+ const observation = await withGitReadObservation(input.scope, input.channel, async (read) => await observeContractWorld(read));
26
+ return [...observation.contracts.values()].flatMap((value) => value.state === null ? [] : [value.state]);
27
+ }
28
+ export async function reconcileAllOperation(input) {
29
+ const observation = await withGitReadObservation(input.scope, input.channel, async (read) => await observeContractWorld(read));
30
+ const contracts = (await reconcileBatch(input.scope, input.channel, observation.contracts.keys(), {
31
+ hooks: input.hooks,
32
+ retryHooks: input.retryHooks,
33
+ retainTerminalWorktree: input.retainTerminalWorktree ?? false,
34
+ ...(input.places === undefined ? {} : { places: input.places }),
35
+ })).map((item) => ({
36
+ contractId: item.contract,
37
+ state: item.state,
38
+ report: item.result,
39
+ }));
40
+ return { contracts };
41
+ }
@@ -0,0 +1,31 @@
1
+ import type { ActorId, ContractId, ReintegratedData } from "../core/facts/types.js";
2
+ import { type ReintegrateRefusal } from "../core/verbs/reintegrate.js";
3
+ import { type IntegrationPreparationRefusal } from "../git/integration.js";
4
+ import type { GitRepository } from "../git/process.js";
5
+ import type { GitDecodeChannel } from "../git/read-observation.js";
6
+ import { type AcceptedAdmission } from "./attempt.js";
7
+ import type { ProtocolTerminal } from "./run.js";
8
+ import { type PlacementExecutionFailure } from "./placement.js";
9
+ type TargetMissing = Readonly<{
10
+ kind: "target-missing";
11
+ contractId: ContractId;
12
+ }>;
13
+ export type ReintegrationRefusal = ReintegrateRefusal | TargetMissing | IntegrationPreparationRefusal;
14
+ export type ReintegrationResult = (AcceptedAdmission & Readonly<{
15
+ value: ReintegratedData;
16
+ }>) | Readonly<{
17
+ kind: "refused";
18
+ refusal: ReintegrationRefusal;
19
+ }> | Readonly<{
20
+ kind: "retry";
21
+ reason: ProtocolTerminal;
22
+ }> | PlacementExecutionFailure;
23
+ type ReintegrationInput = Readonly<{
24
+ channel: GitDecodeChannel;
25
+ repository: GitRepository;
26
+ contractId: ContractId;
27
+ target: string;
28
+ actor?: ActorId;
29
+ }>;
30
+ export declare function reintegrateOperation(input: ReintegrationInput): Promise<ReintegrationResult>;
31
+ export {};
@@ -0,0 +1,74 @@
1
+ import { contractState } from "../core/facts/observation.js";
2
+ import { decideReintegrate, } from "../core/verbs/reintegrate.js";
3
+ import { materializeReintegrationSnapshot, persistedTender, planIntegration, } from "../git/integration.js";
4
+ import { observeContractsForAdmissionAt } from "../git/observe.js";
5
+ import { admitDecidedOffer, mintAttempts } from "./attempt.js";
6
+ import { timestamp } from "./operations.js";
7
+ import { runUnderTargetPlacementFence } from "./placement.js";
8
+ async function runReintegration(input) {
9
+ const attempts = mintAttempts({ entryCount: 1 });
10
+ for (let index = 0; index < attempts.length; index += 1) {
11
+ const attempt = attempts[index];
12
+ const observation = await observeContractsForAdmissionAt(input.repository, input.channel, [input.contractId]);
13
+ const state = contractState(observation.decision, input.contractId);
14
+ let preparation;
15
+ let assertions = [];
16
+ if (state === null || state.delivery === null || state.currentIntegration === null) {
17
+ preparation = {
18
+ kind: "refused",
19
+ refusal: {
20
+ kind: state === null ? "contract-missing" : "delivery-missing",
21
+ contractId: input.contractId,
22
+ },
23
+ };
24
+ }
25
+ else {
26
+ const planned = await planIntegration(input.repository, { contractId: input.contractId, coordinates: state.coordinates }, await persistedTender(input.repository, state.delivery.data.tenderSnapshot), state.delivery.data.policy.requireBranchesToBeUpToDate);
27
+ if (planned.kind === "refused") {
28
+ preparation = planned;
29
+ }
30
+ else {
31
+ const snapshot = await materializeReintegrationSnapshot(input.repository, planned.data.tree, planned.data.predecessor, state.delivery.data.integration.snapshot);
32
+ preparation = {
33
+ kind: "prepared",
34
+ data: { predecessor: planned.data.predecessor, snapshot },
35
+ };
36
+ assertions = [{ ref: input.target, oid: planned.data.predecessor }];
37
+ }
38
+ }
39
+ const decision = decideReintegrate({
40
+ input: {
41
+ contractId: input.contractId,
42
+ ...(input.actor === undefined ? {} : { actor: input.actor }),
43
+ at: timestamp(),
44
+ preparation,
45
+ },
46
+ attempt,
47
+ observation: observation.decision,
48
+ });
49
+ if (decision.kind === "refused")
50
+ return { kind: "refused", refusal: decision.refusal };
51
+ const result = await admitDecidedOffer({
52
+ channel: input.channel,
53
+ repository: input.repository,
54
+ decisionObservation: observation,
55
+ attempt,
56
+ offer: decision.offer,
57
+ primaryContract: input.contractId,
58
+ assertions,
59
+ });
60
+ if (result.kind === "accepted") {
61
+ if (preparation.kind !== "prepared")
62
+ throw new Error("accepted reintegration has no preparation");
63
+ return { ...result, value: preparation.data };
64
+ }
65
+ if (result.kind === "publication-failed")
66
+ return { kind: "retry", reason: result };
67
+ if (result.kind === "collision" && index + 1 === attempts.length)
68
+ return { kind: "retry", reason: result };
69
+ }
70
+ return { kind: "retry", reason: { kind: "exhausted" } };
71
+ }
72
+ export async function reintegrateOperation(input) {
73
+ return await runUnderTargetPlacementFence(input.repository, input.target, async () => await runReintegration(input));
74
+ }
@@ -0,0 +1,33 @@
1
+ import { type WorkspaceDirtyDelta } from "../git/tender.js";
2
+ import type { AttestationData, ContractState, DeliverData } from "../core/facts/types.js";
3
+ import { type AttestationRefusal } from "../core/verbs/attestation.js";
4
+ import { type CompletionEvidence } from "./completion.js";
5
+ import type { DocumentDerivation, IntentOutcome, MutationOperationInput, RepositoryScope } from "./operations.js";
6
+ type ReviewPreparationRefusal = Readonly<{
7
+ kind: "worktree-missing";
8
+ contractId: import("../core/facts/types.js").ContractId;
9
+ }> | import("../git/tender.js").DirtyWorkspaceRefusal;
10
+ type ReviewRefusal = AttestationRefusal | ReviewPreparationRefusal;
11
+ type ReviewOperationInput = MutationOperationInput & Readonly<{
12
+ verdict: AttestationData["verdict"];
13
+ summary?: string;
14
+ deriveDocument?: (state: ContractState) => DocumentDerivation;
15
+ }>;
16
+ export type ReviewValue = CompletionEvidence & Readonly<{
17
+ workspace?: WorkspaceDirtyDelta;
18
+ }>;
19
+ export declare function prepareReview(repository: RepositoryScope, stage: Readonly<{
20
+ contractId: import("../core/facts/types.js").ContractId;
21
+ coordinates: ContractState["coordinates"];
22
+ }>): Promise<{
23
+ kind: "prepared";
24
+ data: Readonly<{
25
+ changeId: DeliverData["integration"]["changeId"];
26
+ workspace?: WorkspaceDirtyDelta;
27
+ }>;
28
+ } | {
29
+ kind: "refused";
30
+ refusal: ReviewPreparationRefusal;
31
+ }>;
32
+ export declare function reviewOperation(input: ReviewOperationInput): Promise<IntentOutcome<ReviewValue, ReviewRefusal>>;
33
+ export {};
@@ -0,0 +1,148 @@
1
+ import { worktreeChangeId } from "../git/integration.js";
2
+ import { captureTender, dirtyTenderDelta, dirtyTenderRefusal, } from "../git/tender.js";
3
+ import { observeContractsForAdmissionAt } from "../git/observe.js";
4
+ import { dependencyKeySet } from "../core/subject.js";
5
+ import { contractState } from "../core/facts/observation.js";
6
+ import { gate } from "../core/facts/types.js";
7
+ import { decideAttestation } from "../core/verbs/attestation.js";
8
+ import { admitDecidedOffer, mintAttempts } from "./attempt.js";
9
+ import { admitted } from "./outcome.js";
10
+ import { completeCandidate } from "./completion.js";
11
+ import { appointmentFor, readPlaceRegister } from "../workspace-place.js";
12
+ import { timestamp } from "./operations.js";
13
+ const REVIEWED = gate("reviewed");
14
+ async function captureReviewableWorktree(repository, stage) {
15
+ const appointed = stage.coordinates.workspace === "worktree"
16
+ ? appointmentFor(await readPlaceRegister(repository), stage.contractId)
17
+ : undefined;
18
+ const tender = await captureTender(repository, {
19
+ ...stage,
20
+ ...(appointed === undefined ? {} : { place: appointed.place }),
21
+ });
22
+ if (tender.kind === "refused")
23
+ return tender;
24
+ if (tender.data.changes.submodules.length > 0) {
25
+ return { kind: "refused", refusal: await dirtyTenderRefusal(repository, stage.contractId, tender.data) };
26
+ }
27
+ const workspace = await dirtyTenderDelta(repository, tender.data);
28
+ return {
29
+ kind: "prepared",
30
+ data: {
31
+ changeId: await worktreeChangeId(repository, stage, tender.data),
32
+ tender: tender.data,
33
+ ...(workspace === undefined ? {} : { workspace }),
34
+ },
35
+ };
36
+ }
37
+ export async function prepareReview(repository, stage) {
38
+ const prepared = await captureReviewableWorktree(repository, stage);
39
+ if (prepared.kind === "refused")
40
+ return prepared;
41
+ return {
42
+ kind: "prepared",
43
+ data: {
44
+ changeId: prepared.data.changeId,
45
+ ...(prepared.data.workspace === undefined ? {} : { workspace: prepared.data.workspace }),
46
+ },
47
+ };
48
+ }
49
+ function reviewValue(value, completion = {}) {
50
+ return {
51
+ ...(value.workspace === undefined ? {} : { workspace: value.workspace }),
52
+ ...completion,
53
+ };
54
+ }
55
+ async function reviewAttempt(input, attempt) {
56
+ const decisionObservation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
57
+ const state = contractState(decisionObservation.decision, input.contractId);
58
+ let preparation;
59
+ let workspace;
60
+ let tender;
61
+ if (state !== null) {
62
+ const prepared = await captureReviewableWorktree(input.scope, {
63
+ contractId: state.id,
64
+ coordinates: state.coordinates,
65
+ });
66
+ preparation = prepared.kind === "refused"
67
+ ? { kind: "refused", refusal: prepared.refusal }
68
+ : {
69
+ kind: "prepared",
70
+ data: {
71
+ gate: REVIEWED,
72
+ subject: dependencyKeySet([
73
+ { kind: "document", value: state.terms.document.key },
74
+ { kind: "change", value: prepared.data.changeId },
75
+ ]),
76
+ verdict: input.verdict,
77
+ ...(input.summary === undefined ? {} : { summary: input.summary }),
78
+ },
79
+ };
80
+ if (prepared.kind === "prepared") {
81
+ workspace = prepared.data.workspace;
82
+ tender = prepared.data.tender;
83
+ }
84
+ }
85
+ const decision = decideAttestation({
86
+ input: {
87
+ contractId: input.contractId,
88
+ ...(input.actor === undefined ? {} : { actor: input.actor }),
89
+ at: timestamp(),
90
+ ...(preparation === undefined ? {} : { preparation }),
91
+ },
92
+ attempt,
93
+ observation: decisionObservation.decision,
94
+ });
95
+ if (decision.kind === "refused")
96
+ return { kind: "refused", refusal: decision.refusal };
97
+ const admission = await admitDecidedOffer({
98
+ channel: input.channel,
99
+ repository: input.scope,
100
+ decisionObservation,
101
+ attempt,
102
+ offer: decision.offer,
103
+ primaryContract: input.contractId,
104
+ });
105
+ if (admission.kind === "accepted")
106
+ return {
107
+ ...admission,
108
+ value: {
109
+ ...(workspace === undefined ? {} : { workspace }),
110
+ ...(tender === undefined ? {} : { tender }),
111
+ },
112
+ };
113
+ return admission;
114
+ }
115
+ export async function reviewOperation(input) {
116
+ const git = input.scope;
117
+ const attempts = mintAttempts({ entryCount: 1 });
118
+ let review = null;
119
+ for (let index = 0; index < attempts.length; index += 1) {
120
+ const result = await reviewAttempt(input, attempts[index]);
121
+ if (result.kind === "accepted" || result.kind === "refused") {
122
+ review = result;
123
+ break;
124
+ }
125
+ if (result.kind === "publication-failed")
126
+ return { kind: "retry", reason: result };
127
+ if (result.kind === "collision" && index + 1 === attempts.length)
128
+ return { kind: "retry", reason: result };
129
+ }
130
+ if (review === null)
131
+ return { kind: "retry", reason: { kind: "exhausted" } };
132
+ if (review.kind !== "accepted")
133
+ return review;
134
+ if (input.verdict !== "satisfied")
135
+ return admitted(review, reviewValue(review.value));
136
+ const derivation = input.deriveDocument?.(review.state);
137
+ const completed = await completeCandidate({
138
+ channel: input.channel,
139
+ repository: git,
140
+ contractId: input.contractId,
141
+ ...(input.actor === undefined ? {} : { actor: input.actor }),
142
+ ...(review.state.coordinates.target === undefined ? {} : { target: review.state.coordinates.target }),
143
+ verification: derivation?.verification ?? { kind: "prepared", data: null },
144
+ initial: review,
145
+ verifyInitial: false,
146
+ });
147
+ return admitted(completed.admission, reviewValue(review.value, completed.evidence));
148
+ }
@@ -1,6 +1,6 @@
1
1
  import { type GitDecisionObservation } from "../git/observe.js";
2
2
  import type { GitDecodeChannel, GitTreeSelection } from "../git/read-observation.js";
3
- import type { GitRepository } from "../git/repository.js";
3
+ import type { GitRepository } from "../git/process.js";
4
4
  import type { GitRefAssertion } from "../git/repository.js";
5
5
  import type { AttemptContext, DecideInput, OfferDecision } from "../core/decide.js";
6
6
  import type { Offer, TreeUpdate } from "../core/facts/offer.js";
@@ -51,6 +51,7 @@ export type OwnedProcess = Readonly<{
51
51
  export declare function terminateOwnedProcess(child: ChildProcess, force?: boolean): Promise<void>;
52
52
  export declare function spawnDetachedProcess(input: DetachedProcessInput): Promise<OwnedProcess>;
53
53
  export declare function runProcess(input: ProcessInput): Promise<ProcessOutcome>;
54
+ export declare function runCrossPlatformProcess(input: ProcessInput): Promise<ProcessOutcome>;
54
55
  export declare function runProcessToExit(input: ProcessLaunch): Promise<ProcessOutcome>;
55
56
  export declare function consumeProcessStdout(input: ProcessInput, consume: (chunk: Buffer) => void): Promise<ProcessConsumption>;
56
57
  export {};
@@ -2,6 +2,7 @@ import { execFile, spawn } from "node:child_process";
2
2
  import { open } from "node:fs/promises";
3
3
  import { setTimeout as delay } from "node:timers/promises";
4
4
  import { promisify } from "node:util";
5
+ import crossSpawn from "cross-spawn";
5
6
  const TERMINATION_GRACE_MS = 250;
6
7
  const STREAM_TAIL_BYTES = 16 * 1024;
7
8
  function tailCapture(limit) {
@@ -138,10 +139,10 @@ function terminalOutcome(code, stdout, stderr, consuming) {
138
139
  truncated: (consuming ? false : stdout.truncated) || stderr.truncated,
139
140
  };
140
141
  }
141
- async function executeProcess(input, timeoutMs, consumeStdout) {
142
+ async function executeProcess(input, timeoutMs, consumeStdout, spawnProcess = spawn) {
142
143
  if (input.signal?.aborted === true)
143
144
  return { outcome: { kind: "cancelled" }, pid: null };
144
- const child = spawn(input.argv[0], input.argv.slice(1), {
145
+ const child = spawnProcess(input.argv[0], input.argv.slice(1), {
145
146
  cwd: input.cwd,
146
147
  env: input.env,
147
148
  detached: true,
@@ -223,6 +224,12 @@ export async function runProcess(input) {
223
224
  throw new Error("buffered process produced a stream consumer error");
224
225
  return result.outcome;
225
226
  }
227
+ export async function runCrossPlatformProcess(input) {
228
+ const result = await executeProcess(input, input.timeoutMs, undefined, crossSpawn);
229
+ if (result.outcome.kind === "stream-error")
230
+ throw new Error("buffered process produced a stream consumer error");
231
+ return result.outcome;
232
+ }
226
233
  export async function runProcessToExit(input) {
227
234
  const result = await executeProcess(input, undefined);
228
235
  if (result.outcome.kind === "stream-error")
@@ -1,5 +1,5 @@
1
1
  import { type HeldSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
2
- import { type GitRepository } from "../git/repository.js";
2
+ import type { GitRepository } from "../git/process.js";
3
3
  import type { TaskId } from "../task/identity.js";
4
4
  export declare function settlementFencePath(repository: GitRepository, taskId: TaskId): string;
5
5
  export declare function acquireTaskSettlementFence(repository: GitRepository, taskId: TaskId): Promise<HeldSqliteTransactionLock>;
@@ -1,7 +1,7 @@
1
1
  import type { TreeUpdate } from "../core/facts/offer.js";
2
2
  import { type ContractId } from "../core/facts/types.js";
3
3
  import type { GitDecisionObservation } from "../git/observe.js";
4
- import { type GitRepository } from "../git/repository.js";
4
+ import type { GitRepository } from "../git/process.js";
5
5
  import { type GitDecodeChannel, type GitReadObservation, type GitTreeSelection } from "../git/read-observation.js";
6
6
  import { type TaskId } from "../task/identity.js";
7
7
  export declare function taskHolderObservationSelection(): GitTreeSelection;
@@ -1,7 +1,7 @@
1
1
  import { type ContractId, type ContractState } from "../core/facts/types.js";
2
2
  import type { GitDecodeChannel } from "../git/read-observation.js";
3
3
  import type { Effect } from "../git/reconcile.js";
4
- import type { GitRepository } from "../git/repository.js";
4
+ import type { GitRepository } from "../git/process.js";
5
5
  import type { TaskId } from "../task/identity.js";
6
6
  export type SettlementAction = Readonly<{
7
7
  kind: "task";
@@ -29,6 +29,7 @@ export declare function deferredTaskHolderSettlement(input: Readonly<{
29
29
  taskId: TaskId;
30
30
  diagnostic: string;
31
31
  }>): SettlementReport;
32
+ export declare function contractNamespace(id: ContractId): readonly [string];
32
33
  export type SettlementInput = Readonly<{
33
34
  repository: GitRepository;
34
35
  channel: GitDecodeChannel;
@@ -7,6 +7,9 @@ import { World } from "../world.js";
7
7
  export function deferredTaskHolderSettlement(input) {
8
8
  return { actions: [], lags: [{ kind: "settlement-failed", surface: "task-holder", ...input }] };
9
9
  }
10
+ export function contractNamespace(id) {
11
+ return [contractSegment(id)];
12
+ }
10
13
  function diagnostic(error) {
11
14
  return error instanceof Error ? error.message : String(error);
12
15
  }
@@ -79,7 +82,7 @@ async function settleNamespace(state, effects, actions, lags) {
79
82
  actions.push({
80
83
  kind: "namespace-context",
81
84
  path: effect.path,
82
- action: await repairNamespaceContext(world, [contractSegment(state.id)]),
85
+ action: await repairNamespaceContext(world, contractNamespace(state.id)),
83
86
  });
84
87
  }
85
88
  catch (error) {