@astrosheep/keiyaku 4.0.4 → 4.0.6

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 (233) 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 +15 -7
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -3
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +24 -4
  8. package/build/src/akuma/akuma.d.ts +2 -1
  9. package/build/src/akuma/akuma.js +27 -9
  10. package/build/src/akuma/allowed.d.ts +1 -1
  11. package/build/src/akuma/allowed.js +3 -10
  12. package/build/src/akuma/archetype.d.ts +3 -1
  13. package/build/src/akuma/archetype.js +11 -6
  14. package/build/src/akuma/body-turn.d.ts +64 -0
  15. package/build/src/akuma/body-turn.js +449 -0
  16. package/build/src/akuma/body.d.ts +4 -5
  17. package/build/src/akuma/body.js +9 -414
  18. package/build/src/akuma/heart/facts.d.ts +37 -9
  19. package/build/src/akuma/heart/facts.js +3 -1
  20. package/build/src/akuma/heart/index.d.ts +4 -13
  21. package/build/src/akuma/heart/index.js +14 -135
  22. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  23. package/build/src/akuma/heart/request-authority.js +119 -0
  24. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  25. package/build/src/akuma/heart/request-rows.js +88 -0
  26. package/build/src/akuma/heart/rows.d.ts +1 -28
  27. package/build/src/akuma/heart/rows.js +4 -138
  28. package/build/src/akuma/heart/schema.d.ts +1 -1
  29. package/build/src/akuma/heart/schema.js +11 -3
  30. package/build/src/akuma/heart/soul.js +0 -36
  31. package/build/src/akuma/heart/timeline.d.ts +1 -0
  32. package/build/src/akuma/heart/timeline.js +19 -0
  33. package/build/src/akuma/index.d.ts +1 -1
  34. package/build/src/akuma/nuke.d.ts +2 -0
  35. package/build/src/akuma/nuke.js +152 -0
  36. package/build/src/akuma/provider-recipe.js +1 -11
  37. package/build/src/akuma/provider.d.ts +4 -7
  38. package/build/src/akuma/providers/acp/config.d.ts +8 -0
  39. package/build/src/akuma/providers/acp/config.js +37 -0
  40. package/build/src/akuma/providers/acp/core.js +12 -2
  41. package/build/src/akuma/providers/acp/index.d.ts +1 -8
  42. package/build/src/akuma/providers/acp/index.js +2 -38
  43. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  44. package/build/src/akuma/providers/claude/index.js +12 -3
  45. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  46. package/build/src/akuma/providers/codex-app-server/index.js +5 -2
  47. package/build/src/akuma/providers/grok-build/index.js +1 -2
  48. package/build/src/akuma/providers/index.d.ts +3 -2
  49. package/build/src/akuma/providers/index.js +36 -36
  50. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  51. package/build/src/akuma/providers/opencode-sdk/index.js +14 -4
  52. package/build/src/akuma/providers/opencode-sdk/session.d.ts +2 -2
  53. package/build/src/akuma/providers/opencode-sdk/session.js +2 -2
  54. package/build/src/akuma/providers/pi/index.d.ts +1 -1
  55. package/build/src/akuma/providers/pi/index.js +29 -6
  56. package/build/src/akuma/request-serve.d.ts +88 -0
  57. package/build/src/akuma/request-serve.js +484 -0
  58. package/build/src/akuma/request-wire.d.ts +125 -0
  59. package/build/src/akuma/request-wire.js +383 -0
  60. package/build/src/akuma/requests.d.ts +28 -94
  61. package/build/src/akuma/requests.js +52 -562
  62. package/build/src/akuma-body.d.ts +7 -0
  63. package/build/src/akuma-body.js +69 -2
  64. package/build/src/alias/index.d.ts +1 -0
  65. package/build/src/alias/index.js +34 -1
  66. package/build/src/body/arc.js +4 -29
  67. package/build/src/body/decode.js +5 -39
  68. package/build/src/body/envelope.d.ts +7 -0
  69. package/build/src/body/envelope.js +37 -0
  70. package/build/src/cli/accepted.js +21 -9
  71. package/build/src/cli/commands/akuma-invoke.js +1 -0
  72. package/build/src/cli/commands/akuma.d.ts +1 -0
  73. package/build/src/cli/commands/akuma.js +13 -10
  74. package/build/src/cli/commands/contract.d.ts +28 -17
  75. package/build/src/cli/commands/contract.js +23 -17
  76. package/build/src/cli/commands/install.d.ts +2 -2
  77. package/build/src/cli/commands/install.js +6 -6
  78. package/build/src/cli/commands/nuke.d.ts +10 -0
  79. package/build/src/cli/commands/nuke.js +20 -0
  80. package/build/src/cli/commands/task-invoke.d.ts +15 -0
  81. package/build/src/cli/commands/task-invoke.js +144 -24
  82. package/build/src/cli/commands/task-query.d.ts +2 -2
  83. package/build/src/cli/commands/task-query.js +1 -2
  84. package/build/src/cli/commands/task.js +22 -22
  85. package/build/src/cli/coordinates.d.ts +6 -2
  86. package/build/src/cli/coordinates.js +12 -56
  87. package/build/src/cli/invoke.d.ts +5 -4
  88. package/build/src/cli/invoke.js +112 -58
  89. package/build/src/cli/main.d.ts +0 -2
  90. package/build/src/cli/main.js +4 -140
  91. package/build/src/cli/parse.d.ts +17 -4
  92. package/build/src/cli/parse.js +93 -15
  93. package/build/src/cli/render/akuma.js +111 -53
  94. package/build/src/cli/render/audit.js +2 -6
  95. package/build/src/cli/render/contract.js +61 -20
  96. package/build/src/cli/render/kanshi.js +15 -5
  97. package/build/src/cli/render/nuke.d.ts +3 -0
  98. package/build/src/cli/render/nuke.js +8 -0
  99. package/build/src/cli/render/receipt.js +28 -1
  100. package/build/src/cli/render/refusal.d.ts +2 -1
  101. package/build/src/cli/render/refusal.js +31 -0
  102. package/build/src/cli/render/terminal.d.ts +0 -2
  103. package/build/src/cli/render/terminal.js +0 -29
  104. package/build/src/cli/render/text.js +6 -1
  105. package/build/src/cli/result.d.ts +36 -9
  106. package/build/src/cli/runtime.d.ts +2 -0
  107. package/build/src/cli/runtime.js +140 -0
  108. package/build/src/cli/usage.d.ts +0 -2
  109. package/build/src/cli/usage.js +0 -4
  110. package/build/src/contract-worktree.d.ts +29 -14
  111. package/build/src/contract-worktree.js +131 -70
  112. package/build/src/core/facts/codec.js +9 -0
  113. package/build/src/core/facts/fold.js +13 -1
  114. package/build/src/core/facts/types.d.ts +8 -1
  115. package/build/src/core/subject.js +4 -3
  116. package/build/src/core/verbs/placement.d.ts +9 -1
  117. package/build/src/core/verbs/placement.js +24 -6
  118. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  119. package/build/src/core/verbs/reintegrate.js +24 -0
  120. package/build/src/dispatch/index.d.ts +1 -1
  121. package/build/src/git/admission.d.ts +2 -1
  122. package/build/src/git/hooks.d.ts +2 -0
  123. package/build/src/git/hooks.js +34 -1
  124. package/build/src/git/integration.d.ts +9 -2
  125. package/build/src/git/integration.js +92 -1
  126. package/build/src/git/nuke.d.ts +2 -0
  127. package/build/src/git/nuke.js +97 -0
  128. package/build/src/git/observe.d.ts +2 -1
  129. package/build/src/git/observe.js +6 -5
  130. package/build/src/git/process.d.ts +28 -0
  131. package/build/src/git/process.js +94 -0
  132. package/build/src/git/read-observation.d.ts +2 -1
  133. package/build/src/git/read-observation.js +3 -2
  134. package/build/src/git/reconcile.d.ts +4 -1
  135. package/build/src/git/reconcile.js +42 -8
  136. package/build/src/git/repository.d.ts +2 -29
  137. package/build/src/git/repository.js +7 -118
  138. package/build/src/git/scratch.d.ts +1 -1
  139. package/build/src/git/scratch.js +1 -1
  140. package/build/src/git/target-placement.d.ts +3 -2
  141. package/build/src/git/target-placement.js +15 -14
  142. package/build/src/git/tender.d.ts +2 -1
  143. package/build/src/git/tender.js +4 -3
  144. package/build/src/git/terminal-seal.d.ts +2 -2
  145. package/build/src/git/terminal-seal.js +3 -6
  146. package/build/src/git/workspace.d.ts +4 -1
  147. package/build/src/git/workspace.js +1 -1
  148. package/build/src/index.d.ts +1 -2
  149. package/build/src/index.js +1 -1
  150. package/build/src/kanshi/read.js +5 -1
  151. package/build/src/library/address.js +7 -1
  152. package/build/src/library/akuma-creation.d.ts +1 -0
  153. package/build/src/library/akuma-creation.js +8 -1
  154. package/build/src/library/audit.d.ts +3 -1
  155. package/build/src/library/audit.js +2 -1
  156. package/build/src/library/bind.d.ts +2 -1
  157. package/build/src/library/bind.js +1 -1
  158. package/build/src/library/configuration.d.ts +1 -1
  159. package/build/src/library/configuration.js +52 -18
  160. package/build/src/library/contract.d.ts +59 -4
  161. package/build/src/library/contract.js +195 -34
  162. package/build/src/library/delivery.d.ts +4 -2
  163. package/build/src/library/fleet.d.ts +27 -7
  164. package/build/src/library/fleet.js +79 -39
  165. package/build/src/library/input.d.ts +0 -1
  166. package/build/src/library/input.js +0 -5
  167. package/build/src/library/keiyaku.d.ts +6 -2
  168. package/build/src/library/keiyaku.js +2 -0
  169. package/build/src/library/mutation.d.ts +3 -1
  170. package/build/src/library/mutation.js +3 -0
  171. package/build/src/library/nuke.d.ts +14 -0
  172. package/build/src/library/nuke.js +54 -0
  173. package/build/src/library/reconcile.d.ts +2 -1
  174. package/build/src/library/reconcile.js +8 -3
  175. package/build/src/library/refusal.d.ts +10 -1
  176. package/build/src/library/region.d.ts +1 -1
  177. package/build/src/library/repo.d.ts +4 -1
  178. package/build/src/library/repo.js +10 -4
  179. package/build/src/protocol/abandon.d.ts +9 -0
  180. package/build/src/protocol/abandon.js +15 -0
  181. package/build/src/protocol/amend.d.ts +16 -0
  182. package/build/src/protocol/amend.js +77 -0
  183. package/build/src/protocol/arc.d.ts +6 -0
  184. package/build/src/protocol/arc.js +12 -0
  185. package/build/src/protocol/attempt.d.ts +2 -1
  186. package/build/src/protocol/audit.d.ts +53 -0
  187. package/build/src/protocol/audit.js +147 -0
  188. package/build/src/protocol/bind.d.ts +1 -1
  189. package/build/src/protocol/completion.d.ts +42 -0
  190. package/build/src/protocol/completion.js +183 -0
  191. package/build/src/protocol/deliver.d.ts +49 -0
  192. package/build/src/protocol/deliver.js +261 -0
  193. package/build/src/protocol/intent.d.ts +2 -1
  194. package/build/src/protocol/intent.js +8 -2
  195. package/build/src/protocol/operations.d.ts +93 -202
  196. package/build/src/protocol/operations.js +23 -642
  197. package/build/src/protocol/placement.d.ts +12 -13
  198. package/build/src/protocol/placement.js +8 -19
  199. package/build/src/protocol/read/status.d.ts +17 -5
  200. package/build/src/protocol/read/status.js +57 -13
  201. package/build/src/protocol/reconcile.d.ts +35 -0
  202. package/build/src/protocol/reconcile.js +41 -0
  203. package/build/src/protocol/reintegrate.d.ts +31 -0
  204. package/build/src/protocol/reintegrate.js +74 -0
  205. package/build/src/protocol/review.d.ts +34 -0
  206. package/build/src/protocol/review.js +156 -0
  207. package/build/src/protocol/run.d.ts +1 -1
  208. package/build/src/runtime/proc/run.js +9 -5
  209. package/build/src/settlement/fence.d.ts +3 -1
  210. package/build/src/settlement/fence.js +24 -0
  211. package/build/src/settlement/holder.d.ts +1 -1
  212. package/build/src/settlement/settle.d.ts +1 -1
  213. package/build/src/settlement/settle.js +1 -2
  214. package/build/src/task/board.d.ts +0 -1
  215. package/build/src/task/board.js +0 -3
  216. package/build/src/task/compose.d.ts +2 -2
  217. package/build/src/task/compose.js +13 -11
  218. package/build/src/task/context.d.ts +14 -2
  219. package/build/src/task/context.js +30 -7
  220. package/build/src/task/index.d.ts +7 -6
  221. package/build/src/task/index.js +17 -145
  222. package/build/src/task/input.d.ts +18 -0
  223. package/build/src/task/input.js +189 -0
  224. package/build/src/task/mutation.d.ts +44 -0
  225. package/build/src/task/mutation.js +93 -0
  226. package/build/src/task/operations.d.ts +14 -6
  227. package/build/src/task/operations.js +57 -57
  228. package/build/src/task/store.d.ts +1 -0
  229. package/build/src/task/store.js +91 -3
  230. package/build/src/verification/execution.d.ts +1 -1
  231. package/build/src/workspace-place.d.ts +3 -4
  232. package/build/src/workspace-place.js +26 -15
  233. package/package.json +3 -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,16 @@ 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;
28
+ type PlacementAdmissionInput<ExtraRefusal> = Readonly<{
29
+ channel: GitDecodeChannel;
30
+ repository: GitRepository;
31
+ target: string | undefined;
32
+ placement: PlacementProtocolInput;
33
+ hereWorkspacePath?: string;
34
+ onDeliveryMissing?: () => Promise<PlacementProtocolResult<ExtraRefusal> | undefined>;
36
35
  }>;
37
- /** Observe prospective target followability without fencing or placing. */
38
- export declare function observeProspectiveTargetPlacement(repository: GitRepository, input: TargetPlacementObservationInput): Promise<ProspectiveTargetPreview>;
36
+ /** Hold the existing target-placement fence for one owner callback. */
37
+ export declare function runUnderTargetPlacementFence<T>(repository: GitRepository, target: string, run: () => Promise<T>, onReleaseFailure?: (result: T, error: unknown) => T | PlacementExecutionFailure): Promise<T | PlacementExecutionFailure>;
39
38
  /** Run the sole placement adjudicator inside the target's physical fence. */
40
- export declare function admitPlacement<ExtraRefusal = never>(channel: GitDecodeChannel, repository: GitRepository, target: string | undefined, input: PlacementProtocolInput, onDeliveryMissing?: () => Promise<PlacementProtocolResult<ExtraRefusal> | undefined>): Promise<PlacementProtocolResult<ExtraRefusal>>;
39
+ export declare function admitPlacement<ExtraRefusal = never>(admission: PlacementAdmissionInput<ExtraRefusal>): Promise<PlacementProtocolResult<ExtraRefusal>>;
41
40
  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,19 +20,7 @@ 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
- async function runFencedPlacement(repository, input, protocol) {
23
+ async function runFencedPlacement(repository, input, protocol, hereWorkspacePath) {
36
24
  for (let index = 0; index < protocol.attempts.length; index += 1) {
37
25
  const prepared = await prepareProtocolAttempt(protocol, protocol.attempts[index]);
38
26
  if (prepared.kind === "refused")
@@ -52,7 +40,7 @@ async function runFencedPlacement(repository, input, protocol) {
52
40
  observed,
53
41
  };
54
42
  }
55
- const physical = await prepareTargetPlacement(repository, state, prepared.offer.target);
43
+ const physical = await prepareTargetPlacement(repository, state, prepared.offer.target, hereWorkspacePath);
56
44
  if (physical.kind === "refused")
57
45
  return physical;
58
46
  const result = await admitDecidedOffer({
@@ -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);
@@ -123,7 +111,8 @@ function isDeliveryMissing(result) {
123
111
  return result.kind === "refused" && result.refusal.kind === "delivery-missing";
124
112
  }
125
113
  /** Run the sole placement adjudicator inside the target's physical fence. */
126
- export async function admitPlacement(channel, repository, target, input, onDeliveryMissing) {
114
+ export async function admitPlacement(admission) {
115
+ const { channel, repository, target, placement: input, hereWorkspacePath, onDeliveryMissing } = admission;
127
116
  const attempts = mintAttempts({ entryCount: 1 });
128
117
  const protocol = {
129
118
  input,
@@ -137,7 +126,7 @@ export async function admitPlacement(channel, repository, target, input, onDeliv
137
126
  if (target === undefined)
138
127
  return await runProtocol(protocol);
139
128
  return await runUnderTargetPlacementFence(repository, target, async () => {
140
- const result = await runFencedPlacement(repository, input, protocol);
129
+ const result = await runFencedPlacement(repository, input, protocol, hereWorkspacePath);
141
130
  if (onDeliveryMissing === undefined || !isDeliveryMissing(result))
142
131
  return result;
143
132
  return await onDeliveryMissing() ?? result;
@@ -1,8 +1,8 @@
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
- import type { ContractId, ContractState, DeliverData, SnapshotId } from "../../core/facts/types.js";
5
+ import type { ContractId, ContractState, DeliverData, JournalEntry, SnapshotId } from "../../core/facts/types.js";
6
6
  export type ContractPhase = "waiting" | "bound" | "pending-delivery" | "claimed" | "abandoned";
7
7
  export type ContractDisposition = "active" | "terminal";
8
8
  export type ContractGateCurrent = GateCurrent;
@@ -11,11 +11,22 @@ export type ContractGateReport = Readonly<{
11
11
  current: ContractGateCurrent;
12
12
  }>;
13
13
  export type { ContractTargetLag, ContractWorkspaceObservation };
14
+ export type HereWorkspaceObservationResolution = Readonly<{
15
+ kind: "appointed";
16
+ path: string;
17
+ }> | Readonly<{
18
+ kind: "unappointed";
19
+ }> | Readonly<{
20
+ kind: "failed";
21
+ diagnostic: string;
22
+ }>;
23
+ export type HereWorkspaceObservationResolver = (contractId: ContractId) => Promise<HereWorkspaceObservationResolution>;
14
24
  export type ContractRow = Readonly<{
15
25
  id: ContractId;
16
26
  title: string | null;
17
27
  phase: ContractPhase;
18
28
  phaseAt: string;
29
+ lastJournalAt: string;
19
30
  disposition: ContractDisposition;
20
31
  workspace: "worktree" | "here";
21
32
  worktreePath: string | null;
@@ -45,9 +56,10 @@ export type ContractObservation = Readonly<{
45
56
  row: ContractRow;
46
57
  }>;
47
58
  export declare function phaseAtFor(state: Pick<ContractState, "terminal" | "delivery" | "bound">, bindAt: string): string;
59
+ export declare function lastJournalAtFor(entries: readonly Pick<JournalEntry, "at">[]): string;
48
60
  /** Build the Contract board from one immutable git observation. */
49
- export declare function readContractBoard(observation: GitReadObservation, selected?: ContractId): Promise<ContractBoard>;
61
+ export declare function readContractBoard(observation: GitReadObservation, selected?: ContractId, resolveHereWorkspace?: HereWorkspaceObservationResolver): Promise<ContractBoard>;
50
62
  /** Observe one Contract and its target from one fresh ref epoch. */
51
- export declare function readContractObservation(observation: GitReadObservation, id: ContractId): Promise<ContractObservation>;
63
+ export declare function readContractObservation(observation: GitReadObservation, id: ContractId, resolveHereWorkspace?: HereWorkspaceObservationResolver): Promise<ContractObservation>;
52
64
  /** Observe one Contract and its target from one fresh ref epoch. */
53
- export declare function readContractObservationAt(repository: GitRepository, channel: GitDecodeChannel, id: ContractId): Promise<ContractObservation>;
65
+ export declare function readContractObservationAt(repository: GitRepository, channel: GitDecodeChannel, id: ContractId, resolveHereWorkspace?: HereWorkspaceObservationResolver): Promise<ContractObservation>;
@@ -27,6 +27,12 @@ function phaseFor(state) {
27
27
  export function phaseAtFor(state, bindAt) {
28
28
  return state.terminal?.at ?? state.delivery?.at ?? state.bound?.at ?? bindAt;
29
29
  }
30
+ export function lastJournalAtFor(entries) {
31
+ const last = entries.at(-1);
32
+ if (last === undefined)
33
+ throw new Error("present Contract journal is empty");
34
+ return last.at;
35
+ }
30
36
  async function managedWorkspaceFacts(repository, state, register, targetObservation) {
31
37
  const appointed = appointmentFor(register, state.id);
32
38
  if (appointed === undefined) {
@@ -43,31 +49,52 @@ async function managedWorkspaceFacts(repository, state, register, targetObservat
43
49
  ]);
44
50
  return { appointed, workspaceObservation, targetLag };
45
51
  }
46
- async function hereWorkspaceFacts(repository, targetObservation) {
52
+ async function hereWorkspaceFacts(repository, contractId, targetObservation, resolveHereWorkspace) {
53
+ const resolved = resolveHereWorkspace === undefined
54
+ ? { kind: "unappointed" }
55
+ : await resolveHereWorkspace(contractId);
56
+ if (resolved.kind === "failed") {
57
+ return {
58
+ appointed: undefined,
59
+ workspaceObservation: { kind: "failed", diagnostic: resolved.diagnostic },
60
+ targetLag: targetObservation === null ? { kind: "none" } : { kind: "unknown" },
61
+ };
62
+ }
63
+ if (resolved.kind === "unappointed") {
64
+ return {
65
+ appointed: undefined,
66
+ workspaceObservation: { kind: "unappointed" },
67
+ targetLag: targetObservation === null ? { kind: "none" } : { kind: "unknown" },
68
+ };
69
+ }
47
70
  const [workspaceObservation, targetLag] = await Promise.all([
48
- observeWorkspace(repository, { kind: "here" }, repository.effectiveCwd),
49
- observeTargetLag(repository, repository.effectiveCwd, targetObservation?.head),
71
+ observeWorkspace(repository, { kind: "here" }, resolved.path),
72
+ observeTargetLag(repository, resolved.path, targetObservation?.head),
50
73
  ]);
51
74
  return { appointed: undefined, workspaceObservation, targetLag };
52
75
  }
53
- async function rowFor(repository, state, bindAt, targetObservation, register) {
76
+ async function rowFor(input) {
77
+ const { repository, state, bindAt, lastJournalAt, targetObservation, register, resolveHereWorkspace } = input;
54
78
  const workspace = state.coordinates.workspace;
55
79
  const gates = gateReports(state);
56
80
  const { appointed, workspaceObservation, targetLag } = workspace === "worktree"
57
81
  ? await managedWorkspaceFacts(repository, state, register, targetObservation)
58
- : await hereWorkspaceFacts(repository, targetObservation);
82
+ : await hereWorkspaceFacts(repository, state.id, targetObservation, resolveHereWorkspace);
59
83
  return {
60
84
  id: state.id,
61
85
  title: titleFor(state),
62
86
  phase: phaseFor(state),
63
87
  phaseAt: phaseAtFor(state, bindAt),
88
+ lastJournalAt,
64
89
  disposition: state.terminal === null ? "active" : "terminal",
65
90
  workspace,
66
91
  worktreePath: appointed === undefined ? null : worktreePath(repository, appointed.place),
67
92
  workspaceObservation,
68
93
  target: state.coordinates.target ?? null,
69
94
  targetLag,
70
- delivery: state.delivery?.data ?? null,
95
+ delivery: state.delivery === null || state.currentIntegration === null
96
+ ? null
97
+ : { ...state.delivery.data, integration: state.currentIntegration },
71
98
  targetObservation,
72
99
  gates: {
73
100
  reports: gates.reports.map((report) => ({ gate: report.gate, current: report.current })),
@@ -76,9 +103,9 @@ async function rowFor(repository, state, bindAt, targetObservation, register) {
76
103
  };
77
104
  }
78
105
  /** Build the Contract board from one immutable git observation. */
79
- export async function readContractBoard(observation, selected) {
106
+ export async function readContractBoard(observation, selected, resolveHereWorkspace) {
80
107
  if (selected !== undefined) {
81
- const contract = await readContractObservation(observation, selected);
108
+ const contract = await readContractObservation(observation, selected, resolveHereWorkspace);
82
109
  return {
83
110
  root: observation.repository.primaryWorktree,
84
111
  state: observation.snapshot.commit,
@@ -93,12 +120,21 @@ export async function readContractBoard(observation, selected) {
93
120
  continue;
94
121
  const state = value.state;
95
122
  const bindAt = value.entries[0].at;
96
- rows.push(observeDeliveryTargetAt(observation, state).then((target) => rowFor(observation.repository, state, bindAt, target, register)));
123
+ const lastJournalAt = lastJournalAtFor(value.entries);
124
+ rows.push(observeDeliveryTargetAt(observation, state).then((target) => rowFor({
125
+ repository: observation.repository,
126
+ state,
127
+ bindAt,
128
+ lastJournalAt,
129
+ targetObservation: target,
130
+ register,
131
+ ...(resolveHereWorkspace === undefined ? {} : { resolveHereWorkspace }),
132
+ })));
97
133
  }
98
134
  return { root: observation.repository.primaryWorktree, state: observed.snapshot, rows: await Promise.all(rows) };
99
135
  }
100
136
  /** Observe one Contract and its target from one fresh ref epoch. */
101
- export async function readContractObservation(observation, id) {
137
+ export async function readContractObservation(observation, id, resolveHereWorkspace) {
102
138
  const observed = await observeContractsForAdmissionInObservationAt(observation, [id]);
103
139
  const record = observed.journals.get(id);
104
140
  if (record === undefined)
@@ -108,10 +144,18 @@ export async function readContractObservation(observation, id) {
108
144
  ? { kind: "missing", id }
109
145
  : {
110
146
  kind: "present",
111
- row: await rowFor(observation.repository, state, record.entries[0].at, await observeDeliveryTargetAt(observation, state), await readPlaceRegister(observation.repository)),
147
+ row: await rowFor({
148
+ repository: observation.repository,
149
+ state,
150
+ bindAt: record.entries[0].at,
151
+ lastJournalAt: lastJournalAtFor(record.entries),
152
+ targetObservation: await observeDeliveryTargetAt(observation, state),
153
+ register: await readPlaceRegister(observation.repository),
154
+ ...(resolveHereWorkspace === undefined ? {} : { resolveHereWorkspace }),
155
+ }),
112
156
  };
113
157
  }
114
158
  /** Observe one Contract and its target from one fresh ref epoch. */
115
- export async function readContractObservationAt(repository, channel, id) {
116
- return withContractReadObservationAt(repository, channel, id, async (observation) => await readContractObservation(observation, id));
159
+ export async function readContractObservationAt(repository, channel, id, resolveHereWorkspace) {
160
+ return withContractReadObservationAt(repository, channel, id, async (observation) => await readContractObservation(observation, id, resolveHereWorkspace));
117
161
  }
@@ -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,34 @@
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
+ workspacePath?: string;
23
+ }>): Promise<{
24
+ kind: "prepared";
25
+ data: Readonly<{
26
+ changeId: DeliverData["integration"]["changeId"];
27
+ workspace?: WorkspaceDirtyDelta;
28
+ }>;
29
+ } | {
30
+ kind: "refused";
31
+ refusal: ReviewPreparationRefusal;
32
+ }>;
33
+ export declare function reviewOperation(input: ReviewOperationInput): Promise<IntentOutcome<ReviewValue, ReviewRefusal>>;
34
+ export {};