@astrosheep/keiyaku 4.0.4 → 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 (173) 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 +3 -3
  5. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +14 -0
  6. package/build/src/akuma/akuma.d.ts +0 -1
  7. package/build/src/akuma/akuma.js +1 -6
  8. package/build/src/akuma/allowed.d.ts +1 -1
  9. package/build/src/akuma/allowed.js +3 -10
  10. package/build/src/akuma/body.d.ts +5 -2
  11. package/build/src/akuma/body.js +29 -23
  12. package/build/src/akuma/heart/facts.d.ts +35 -9
  13. package/build/src/akuma/heart/index.d.ts +4 -13
  14. package/build/src/akuma/heart/index.js +2 -133
  15. package/build/src/akuma/heart/request-authority.d.ts +12 -0
  16. package/build/src/akuma/heart/request-authority.js +119 -0
  17. package/build/src/akuma/heart/request-rows.d.ts +16 -0
  18. package/build/src/akuma/heart/request-rows.js +88 -0
  19. package/build/src/akuma/heart/rows.d.ts +1 -28
  20. package/build/src/akuma/heart/rows.js +0 -137
  21. package/build/src/akuma/heart/schema.d.ts +1 -1
  22. package/build/src/akuma/heart/schema.js +9 -2
  23. package/build/src/akuma/heart/soul.js +0 -36
  24. package/build/src/akuma/index.d.ts +1 -1
  25. package/build/src/akuma/provider-recipe.js +1 -11
  26. package/build/src/akuma/provider.d.ts +1 -6
  27. package/build/src/akuma/providers/acp/core.js +6 -2
  28. package/build/src/akuma/providers/acp/index.js +0 -1
  29. package/build/src/akuma/providers/claude/index.d.ts +0 -4
  30. package/build/src/akuma/providers/claude/index.js +7 -3
  31. package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
  32. package/build/src/akuma/providers/codex-app-server/index.js +0 -2
  33. package/build/src/akuma/providers/grok-build/index.js +0 -1
  34. package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
  35. package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
  36. package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
  37. package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
  38. package/build/src/akuma/providers/pi/index.js +11 -4
  39. package/build/src/akuma/request-serve.d.ts +87 -0
  40. package/build/src/akuma/request-serve.js +484 -0
  41. package/build/src/akuma/request-wire.d.ts +124 -0
  42. package/build/src/akuma/request-wire.js +380 -0
  43. package/build/src/akuma/requests.d.ts +28 -94
  44. package/build/src/akuma/requests.js +52 -562
  45. package/build/src/akuma-body.d.ts +7 -0
  46. package/build/src/akuma-body.js +54 -1
  47. package/build/src/body/arc.js +4 -29
  48. package/build/src/body/decode.js +5 -39
  49. package/build/src/body/envelope.d.ts +7 -0
  50. package/build/src/body/envelope.js +37 -0
  51. package/build/src/cli/accepted.js +17 -9
  52. package/build/src/cli/commands/akuma.js +2 -2
  53. package/build/src/cli/commands/contract.d.ts +6 -6
  54. package/build/src/cli/commands/contract.js +3 -3
  55. package/build/src/cli/commands/task-invoke.js +98 -9
  56. package/build/src/cli/coordinates.d.ts +1 -0
  57. package/build/src/cli/coordinates.js +7 -4
  58. package/build/src/cli/invoke.js +28 -4
  59. package/build/src/cli/parse.d.ts +2 -2
  60. package/build/src/cli/parse.js +21 -8
  61. package/build/src/cli/render/akuma.js +56 -13
  62. package/build/src/cli/render/audit.js +2 -6
  63. package/build/src/cli/render/contract.js +40 -0
  64. package/build/src/cli/render/receipt.js +28 -1
  65. package/build/src/cli/render/terminal.d.ts +0 -2
  66. package/build/src/cli/render/terminal.js +0 -29
  67. package/build/src/cli/result.d.ts +15 -7
  68. package/build/src/contract-worktree.d.ts +1 -2
  69. package/build/src/contract-worktree.js +4 -9
  70. package/build/src/core/facts/codec.js +9 -0
  71. package/build/src/core/facts/fold.js +13 -1
  72. package/build/src/core/facts/types.d.ts +8 -1
  73. package/build/src/core/subject.js +4 -3
  74. package/build/src/core/verbs/placement.d.ts +9 -1
  75. package/build/src/core/verbs/placement.js +24 -6
  76. package/build/src/core/verbs/reintegrate.d.ts +13 -0
  77. package/build/src/core/verbs/reintegrate.js +24 -0
  78. package/build/src/dispatch/index.d.ts +1 -1
  79. package/build/src/git/admission.d.ts +2 -1
  80. package/build/src/git/integration.d.ts +5 -2
  81. package/build/src/git/integration.js +54 -1
  82. package/build/src/git/observe.d.ts +2 -1
  83. package/build/src/git/observe.js +6 -5
  84. package/build/src/git/process.d.ts +26 -0
  85. package/build/src/git/process.js +94 -0
  86. package/build/src/git/read-observation.d.ts +2 -1
  87. package/build/src/git/read-observation.js +3 -2
  88. package/build/src/git/reconcile.d.ts +2 -1
  89. package/build/src/git/reconcile.js +9 -6
  90. package/build/src/git/repository.d.ts +2 -29
  91. package/build/src/git/repository.js +4 -118
  92. package/build/src/git/scratch.d.ts +1 -1
  93. package/build/src/git/scratch.js +1 -1
  94. package/build/src/git/target-placement.d.ts +1 -1
  95. package/build/src/git/target-placement.js +9 -7
  96. package/build/src/git/tender.d.ts +1 -1
  97. package/build/src/git/tender.js +2 -1
  98. package/build/src/git/terminal-seal.d.ts +2 -2
  99. package/build/src/git/terminal-seal.js +3 -6
  100. package/build/src/git/workspace.d.ts +1 -1
  101. package/build/src/git/workspace.js +1 -1
  102. package/build/src/index.d.ts +1 -2
  103. package/build/src/index.js +1 -1
  104. package/build/src/library/address.js +7 -1
  105. package/build/src/library/audit.d.ts +2 -1
  106. package/build/src/library/audit.js +1 -1
  107. package/build/src/library/bind.d.ts +2 -1
  108. package/build/src/library/bind.js +1 -1
  109. package/build/src/library/configuration.d.ts +1 -1
  110. package/build/src/library/configuration.js +52 -18
  111. package/build/src/library/contract.d.ts +55 -2
  112. package/build/src/library/contract.js +162 -23
  113. package/build/src/library/delivery.d.ts +1 -1
  114. package/build/src/library/fleet.d.ts +27 -7
  115. package/build/src/library/fleet.js +79 -39
  116. package/build/src/library/input.d.ts +0 -1
  117. package/build/src/library/input.js +0 -5
  118. package/build/src/library/keiyaku.d.ts +1 -1
  119. package/build/src/library/mutation.d.ts +2 -1
  120. package/build/src/library/reconcile.d.ts +2 -1
  121. package/build/src/library/reconcile.js +3 -1
  122. package/build/src/library/region.d.ts +1 -1
  123. package/build/src/library/repo.d.ts +3 -1
  124. package/build/src/library/repo.js +8 -4
  125. package/build/src/protocol/abandon.d.ts +9 -0
  126. package/build/src/protocol/abandon.js +15 -0
  127. package/build/src/protocol/amend.d.ts +16 -0
  128. package/build/src/protocol/amend.js +77 -0
  129. package/build/src/protocol/arc.d.ts +6 -0
  130. package/build/src/protocol/arc.js +12 -0
  131. package/build/src/protocol/attempt.d.ts +2 -1
  132. package/build/src/protocol/audit.d.ts +53 -0
  133. package/build/src/protocol/audit.js +140 -0
  134. package/build/src/protocol/bind.d.ts +1 -1
  135. package/build/src/protocol/completion.d.ts +32 -0
  136. package/build/src/protocol/completion.js +130 -0
  137. package/build/src/protocol/deliver.d.ts +37 -0
  138. package/build/src/protocol/deliver.js +160 -0
  139. package/build/src/protocol/intent.d.ts +1 -1
  140. package/build/src/protocol/intent.js +1 -1
  141. package/build/src/protocol/operations.d.ts +64 -200
  142. package/build/src/protocol/operations.js +21 -640
  143. package/build/src/protocol/placement.d.ts +4 -13
  144. package/build/src/protocol/placement.js +3 -15
  145. package/build/src/protocol/read/status.d.ts +1 -1
  146. package/build/src/protocol/read/status.js +3 -1
  147. package/build/src/protocol/reconcile.d.ts +35 -0
  148. package/build/src/protocol/reconcile.js +41 -0
  149. package/build/src/protocol/reintegrate.d.ts +31 -0
  150. package/build/src/protocol/reintegrate.js +74 -0
  151. package/build/src/protocol/review.d.ts +33 -0
  152. package/build/src/protocol/review.js +148 -0
  153. package/build/src/protocol/run.d.ts +1 -1
  154. package/build/src/settlement/fence.d.ts +1 -1
  155. package/build/src/settlement/holder.d.ts +1 -1
  156. package/build/src/settlement/settle.d.ts +1 -1
  157. package/build/src/task/board.d.ts +0 -1
  158. package/build/src/task/board.js +0 -3
  159. package/build/src/task/compose.d.ts +1 -1
  160. package/build/src/task/compose.js +11 -4
  161. package/build/src/task/index.d.ts +1 -1
  162. package/build/src/task/index.js +2 -127
  163. package/build/src/task/input.d.ts +18 -0
  164. package/build/src/task/input.js +189 -0
  165. package/build/src/task/mutation.d.ts +39 -0
  166. package/build/src/task/mutation.js +85 -0
  167. package/build/src/task/operations.d.ts +2 -0
  168. package/build/src/task/operations.js +35 -11
  169. package/build/src/task/store.js +0 -2
  170. package/build/src/verification/execution.d.ts +1 -1
  171. package/build/src/workspace-place.d.ts +1 -4
  172. package/build/src/workspace-place.js +0 -15
  173. package/package.json +3 -3
@@ -1,8 +1,7 @@
1
- import { spawn } from "node:child_process";
2
1
  import { isAbsolute, resolve } from "node:path";
3
2
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
4
- import { consumeProcessStdout } from "../runtime/proc/run.js";
5
3
  import { gitObjectId } from "./identity.js";
4
+ import { GitPlumbingError, runGit, runGitWithEnvironment } from "./process.js";
6
5
  import { parseTreeObject, prepareTreeUpdate, treeUpdate, validPath, } from "./tree.js";
7
6
  export const GIT_REF = "refs/heads/keiyaku-state";
8
7
  export const DELIVERY_REF_NAMESPACE = "refs/heads/keiyaku-delivery";
@@ -25,21 +24,6 @@ export class NoGitWorldError extends Error {
25
24
  this.path = path;
26
25
  }
27
26
  }
28
- export class GitPlumbingError extends Error {
29
- stdout;
30
- stderr;
31
- status;
32
- pid;
33
- constructor(input) {
34
- super(input.message);
35
- this.name = "GitPlumbingError";
36
- this.stdout = Buffer.from(input.stdout ?? "");
37
- this.stderr = Buffer.from(input.stderr);
38
- this.status = input.status;
39
- this.pid = input.pid ?? null;
40
- }
41
- }
42
- const GIT_STDERR_BYTES = 16 * 1024;
43
27
  function worktreesFromPorcelain(output) {
44
28
  const fields = output.toString("utf8").split("\0");
45
29
  const worktrees = [];
@@ -79,12 +63,13 @@ export async function registeredWorktrees(repository) {
79
63
  export async function registeredWorktreePaths(repository) {
80
64
  return (await registeredWorktrees(repository)).map((worktree) => worktree.path);
81
65
  }
82
- export async function repositoryAt(cwd) {
66
+ export async function repositoryAt(cwd, gitPath = "git") {
83
67
  if (typeof cwd !== "string" || cwd.length === 0) {
84
68
  throw new Error("repository path must be a nonempty string");
85
69
  }
86
70
  const effectiveCwd = resolve(cwd);
87
71
  const provisional = {
72
+ gitPath,
88
73
  effectiveCwd,
89
74
  primaryWorktree: effectiveCwd,
90
75
  commonDirectory: effectiveCwd,
@@ -101,7 +86,7 @@ export async function repositoryAt(cwd) {
101
86
  }
102
87
  throw error;
103
88
  }
104
- return { effectiveCwd, primaryWorktree, commonDirectory };
89
+ return { gitPath, effectiveCwd, primaryWorktree, commonDirectory };
105
90
  }
106
91
  async function absoluteGitPath(repository, args, label) {
107
92
  const value = (await runGit(repository, ["rev-parse", "--path-format=absolute", ...args])).toString("utf8").trim();
@@ -119,83 +104,6 @@ export async function worktreeGitDirectory(repository, worktree) {
119
104
  export async function worktreeRoot(repository) {
120
105
  return await absoluteGitPath(repository, ["--show-toplevel"], "worktree root");
121
106
  }
122
- function commandError(command, error) {
123
- const candidate = error;
124
- const stderr = candidate.stderr === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stderr);
125
- const stdout = candidate.stdout === undefined ? Buffer.alloc(0) : Buffer.from(candidate.stdout);
126
- const detail = stderr.length === 0 ? candidate.message ?? "git command failed" : stderr.toString("utf8");
127
- return new GitPlumbingError({
128
- stdout,
129
- stderr,
130
- status: candidate.status ?? null,
131
- message: `${command.join(" ")}: ${detail}`,
132
- pid: candidate.pid ?? null,
133
- });
134
- }
135
- async function executeGit(repository, args, input, environment) {
136
- const stdout = [];
137
- const stderr = [];
138
- let stderrBytes = 0;
139
- let inputError;
140
- const child = spawn("git", [...args], {
141
- cwd: repository.effectiveCwd,
142
- ...(environment === undefined ? {} : { env: { ...process.env, ...environment } }),
143
- stdio: ["pipe", "pipe", "pipe"],
144
- windowsHide: true,
145
- });
146
- child.stdout.on("data", (chunk) => stdout.push(chunk));
147
- child.stderr.on("data", (chunk) => {
148
- if (stderrBytes >= GIT_STDERR_BYTES)
149
- return;
150
- const retained = chunk.subarray(0, GIT_STDERR_BYTES - stderrBytes);
151
- stderr.push(retained);
152
- stderrBytes += retained.length;
153
- });
154
- child.stdin.on("error", (error) => { inputError = error; });
155
- child.stdin.end(input);
156
- const terminal = await new Promise((resolveTerminal) => {
157
- child.once("error", (error) => resolveTerminal({ code: null, error }));
158
- child.once("close", (code) => resolveTerminal({ code }));
159
- });
160
- const output = Buffer.concat(stdout);
161
- if (terminal.code === 0 && inputError === undefined)
162
- return output;
163
- throw commandError(args, {
164
- message: terminal.error?.message ?? inputError?.message ?? `git exited with status ${terminal.code ?? "unknown"}`,
165
- stdout: output,
166
- stderr: Buffer.concat(stderr),
167
- status: terminal.code,
168
- pid: child.pid,
169
- });
170
- }
171
- export async function runGit(repository, args, input) {
172
- return await executeGit(repository, args, input);
173
- }
174
- export async function consumeGitStdout(repository, args, consume) {
175
- const result = await consumeProcessStdout({
176
- argv: ["git", ...args],
177
- cwd: repository.effectiveCwd,
178
- }, consume);
179
- const { outcome } = result;
180
- if (outcome.kind === "terminal" && outcome.code === 0)
181
- return;
182
- const status = outcome.kind === "terminal" ? outcome.code : null;
183
- const stderr = outcome.kind === "terminal" ? outcome.stderr : "";
184
- const message = outcome.kind === "terminal"
185
- ? `git exited with status ${outcome.code}`
186
- : outcome.kind === "spawn-error" || outcome.kind === "stream-error"
187
- ? outcome.diagnostic
188
- : `git process ended with ${outcome.kind}`;
189
- throw commandError(args, {
190
- message,
191
- stderr,
192
- status,
193
- pid: result.pid ?? undefined,
194
- });
195
- }
196
- export async function runGitWithEnvironment(repository, args, input, environment) {
197
- return await executeGit(repository, args, input, environment);
198
- }
199
107
  function assertOid(oid, label) {
200
108
  gitObjectId(oid, label);
201
109
  }
@@ -282,28 +190,6 @@ export async function readGitPaths(repository, requestedPaths) {
282
190
  await validateGitFormat(repository, paths);
283
191
  return { commit, tree, paths };
284
192
  }
285
- /** Add paths from the same immutable Git tree without rereading its ref. */
286
- export async function extendGitPaths(repository, snapshot, requestedPaths) {
287
- for (const path of requestedPaths)
288
- validPath(path);
289
- if (snapshot.tree === null || requestedPaths.length === 0)
290
- return snapshot;
291
- const additions = parseTreeEntries(await runGit(repository, [
292
- "ls-tree",
293
- "-z",
294
- "--full-tree",
295
- snapshot.tree,
296
- "--",
297
- ...requestedPaths,
298
- ]));
299
- return { ...snapshot, paths: new Map([...snapshot.paths, ...additions]) };
300
- }
301
- /** Expand a targeted immutable snapshot to its complete already-pinned tree. */
302
- export async function expandGitSnapshot(repository, snapshot) {
303
- if (snapshot.tree === null)
304
- return snapshot;
305
- return { ...snapshot, paths: await readTreeEntries(repository, snapshot.tree) };
306
- }
307
193
  export async function writeBlob(repository, bytes) {
308
194
  const oid = (await runGit(repository, ["hash-object", "-w", "--stdin"], bytes)).toString("utf8").trim();
309
195
  assertOid(oid, "written blob");
@@ -1,5 +1,5 @@
1
1
  import type { SnapshotId } from "../core/facts/types.js";
2
- import { type GitRepository } from "./repository.js";
2
+ import { type GitRepository } from "./process.js";
3
3
  export type MaterializedScratchCandidate = Readonly<{
4
4
  cwd: string;
5
5
  dispose: () => Promise<WorktreeLeak | null>;
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
4
4
  import { basename, dirname, join } from "node:path";
5
5
  import { tryAcquireSqliteTransactionLock, } from "../coordination/sqlite-transaction-lock.js";
6
6
  import { gitObjectIdForSnapshot } from "./identity.js";
7
- import { runGit } from "./repository.js";
7
+ import { runGit } from "./process.js";
8
8
  const SCRATCH_PREFIX = "keiyaku-v4-verify-";
9
9
  const SCRATCH_ROOT = await realpath(tmpdir());
10
10
  const SCRATCH_PATTERN = /^keiyaku-v4-verify-([0-9a-f]{24})$/;
@@ -1,7 +1,7 @@
1
1
  import { type HeldSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
2
2
  import type { ContractId, ContractState, SnapshotId } from "../core/facts/types.js";
3
3
  import type { RefOperation } from "../core/facts/offer.js";
4
- import { type GitRepository } from "./repository.js";
4
+ import { type GitRepository } from "./process.js";
5
5
  export type WorkspaceNotOnTargetRefusal = Readonly<{
6
6
  kind: "workspace-not-on-target";
7
7
  contractId: ContractId;
@@ -3,7 +3,8 @@ import { resolve } from "node:path";
3
3
  import { acquireSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
4
4
  import { gitObjectId, gitObjectIdForSnapshot, gitRefLocator, mintSnapshotId } from "./identity.js";
5
5
  import { currentBranch } from "./observe.js";
6
- import { commonGitDirectory, consumeGitStdout, GitPlumbingError, readRef, registeredWorktrees, runGit, } from "./repository.js";
6
+ import { commonGitDirectory, readRef, registeredWorktrees, } from "./repository.js";
7
+ import { consumeGitStdout, GitPlumbingError, runGit, } from "./process.js";
7
8
  import { captureWorkspaceTree } from "./workspace.js";
8
9
  export async function observeTargetHead(repository, target) {
9
10
  const value = await readRef(repository, target);
@@ -254,7 +255,7 @@ export async function adjudicateAuditTarget(repository, input) {
254
255
  }
255
256
  }
256
257
  export async function prepareTargetPlacement(repository, state, target) {
257
- if (state.coordinates.target !== target.target || state.delivery?.data.integration.snapshot !== target.newOid) {
258
+ if (state.coordinates.target !== target.target || state.currentIntegration?.snapshot !== target.newOid) {
258
259
  throw new Error("placement state does not match its offered target movement");
259
260
  }
260
261
  const observation = await observeTargetPlacement(repository, {
@@ -340,10 +341,11 @@ export async function recoverTargetPlacement(repository, state) {
340
341
  const delivery = state.delivery;
341
342
  if (state.terminal?.kind !== "claimed" || target === undefined || delivery === null)
342
343
  return { effects: [], lag: [] };
343
- if (await readRef(repository, target) !== delivery.data.integration.snapshot)
344
+ const integration = state.currentIntegration;
345
+ if (integration === null || await readRef(repository, target) !== integration.snapshot)
344
346
  return { effects: [], lag: [] };
345
- const candidateTree = await commitTree(repository, delivery.data.integration.snapshot);
346
- const predecessorTree = await commitTree(repository, delivery.data.integration.predecessor);
347
+ const candidateTree = await commitTree(repository, integration.snapshot);
348
+ const predecessorTree = await commitTree(repository, integration.predecessor);
347
349
  const worktrees = (await registeredWorktrees(repository))
348
350
  .filter((worktree) => worktree.branch === target)
349
351
  .sort((left, right) => left.path.localeCompare(right.path));
@@ -354,8 +356,8 @@ export async function recoverTargetPlacement(repository, state) {
354
356
  const recovery = await recoverCheckout({
355
357
  repository,
356
358
  path: worktree.path,
357
- predecessor: delivery.data.integration.predecessor,
358
- candidate: delivery.data.integration.snapshot,
359
+ predecessor: integration.predecessor,
360
+ candidate: integration.snapshot,
359
361
  predecessorTree,
360
362
  candidateTree,
361
363
  });
@@ -1,7 +1,7 @@
1
1
  import type { Preparation } from "../core/decide.js";
2
2
  import type { ActorId, ContractCoordinates, ContractId, SnapshotId } from "../core/facts/types.js";
3
3
  import { type GitObjectId } from "./identity.js";
4
- import { type GitRepository } from "./repository.js";
4
+ import { type GitRepository } from "./process.js";
5
5
  import { captureWorkspaceTree } from "./workspace.js";
6
6
  export type TenderCaptureCoordinates = Readonly<{
7
7
  contractId: ContractId;
@@ -1,6 +1,7 @@
1
1
  import { access } from "node:fs/promises";
2
2
  import { gitObjectIdForSnapshot, mintSnapshotId } from "./identity.js";
3
- import { decodeGitNumstat, GitPlumbingError, registeredWorktreePaths, runGit, runGitWithEnvironment, } from "./repository.js";
3
+ import { decodeGitNumstat, registeredWorktreePaths, } from "./repository.js";
4
+ import { GitPlumbingError, runGit, runGitWithEnvironment, } from "./process.js";
4
5
  import { captureWorkspaceTree, worktreePath } from "./workspace.js";
5
6
  async function workspaceExists(repository, workspace, path) {
6
7
  const exists = await access(path).then(() => true, () => false);
@@ -1,6 +1,7 @@
1
1
  import type { ContractState, SnapshotId } from "../core/facts/types.js";
2
2
  import { type GitObjectId } from "./identity.js";
3
- import { type GitOid, type GitRepository } from "./repository.js";
3
+ import type { GitOid } from "./repository.js";
4
+ import { type GitRepository } from "./process.js";
4
5
  import { captureWorkspaceTree } from "./workspace.js";
5
6
  export type UnsealedBytes = Readonly<{
6
7
  kind: "unsealed-bytes";
@@ -33,6 +34,5 @@ export type TerminalWorkspaceObservation = Readonly<{
33
34
  export declare function terminalSealSnapshots(state: ContractState): readonly SnapshotId[];
34
35
  export declare function terminalSealExpectations(state: ContractState, objects: ReadonlyMap<GitOid, TerminalSealObject>): TerminalSealExpectations;
35
36
  export declare function unsealedWorkspaceBytes(repository: GitRepository, path: string, expected: TerminalSealExpectations, workspace: WorkspaceTree): Promise<UnsealedBytes | null>;
36
- export declare function unsealedBytes(repository: GitRepository, path: string, expected: TerminalSealExpectations): Promise<UnsealedBytes | null>;
37
37
  export declare function observeTerminalWorkspace(repository: GitRepository, path: string, expected: TerminalSealExpectations): Promise<TerminalWorkspaceObservation>;
38
38
  export {};
@@ -1,12 +1,12 @@
1
1
  import { gitObjectId, gitObjectIdForSnapshot, mintSnapshotId } from "./identity.js";
2
- import { runGit } from "./repository.js";
2
+ import { runGit } from "./process.js";
3
3
  import { captureWorkspaceTree } from "./workspace.js";
4
4
  export function terminalSealSnapshots(state) {
5
5
  return [...new Set([
6
6
  state.coordinates.start,
7
7
  ...(state.delivery === null ? [] : [
8
8
  state.delivery.data.tenderSnapshot,
9
- state.delivery.data.integration.snapshot,
9
+ ...(state.currentIntegration === null ? [] : [state.currentIntegration.snapshot]),
10
10
  ]),
11
11
  ])];
12
12
  }
@@ -51,7 +51,7 @@ export function terminalSealExpectations(state, objects) {
51
51
  state.coordinates.start,
52
52
  ...(tenderParent === undefined ? [] : [tenderParent]),
53
53
  tender,
54
- state.delivery.data.integration.snapshot,
54
+ state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot,
55
55
  ])],
56
56
  trees: [...treeBySnapshot.values()],
57
57
  treeBySnapshot,
@@ -86,9 +86,6 @@ export async function unsealedWorkspaceBytes(repository, path, expected, workspa
86
86
  ...(headIsSealed ? {} : { head: workspace.head }),
87
87
  };
88
88
  }
89
- export async function unsealedBytes(repository, path, expected) {
90
- return (await observeTerminalWorkspace(repository, path, expected)).unsealed;
91
- }
92
89
  export async function observeTerminalWorkspace(repository, path, expected) {
93
90
  const captured = await captureWorkspaceTree(repository, path);
94
91
  return {
@@ -1,6 +1,6 @@
1
1
  import type { SnapshotId } from "../core/facts/types.js";
2
2
  import { type GitObjectId } from "./identity.js";
3
- import { type GitRepository } from "./repository.js";
3
+ import { type GitRepository } from "./process.js";
4
4
  export type WorkspaceChanges = Readonly<{
5
5
  staged: readonly string[];
6
6
  unstaged: readonly string[];
@@ -2,7 +2,7 @@ import { mkdtemp, rm } from "node:fs/promises";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
4
  import { gitObjectId, mintSnapshotId } from "./identity.js";
5
- import { runGit, runGitWithEnvironment } from "./repository.js";
5
+ import { runGit, runGitWithEnvironment } from "./process.js";
6
6
  const WORKTREE_DIRECTORY = ["keiyaku", "wt"];
7
7
  export function worktreePath(repository, place) {
8
8
  return resolve(repository.commonDirectory, ...WORKTREE_DIRECTORY, place);
@@ -1,6 +1,5 @@
1
- export { AuthorityCorruptionError, AkumaWorldScopeError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
1
+ export * from "./library/keiyaku.js";
2
2
  export { settings } from "./settings.js";
3
3
  export { World, WorldError } from "./world.js";
4
4
  export type { WorldResolution, WorldResolutionInput, WorldRoot } from "./world.js";
5
5
  export type { Settings, SettingsEntry, SettingsInput, SettingsNamespaceFailure, SettingsNamespaceView, SettingsScope, SettingsScopeState, } from "./settings.js";
6
- export type { AttestationVerdict, AbandonInput, ActorId, AkuId, AllowedAction, AllowedActions, AkumaAddressInput, AkumaAlias, AkumaGlob, AkumaHistoryInput, AkumaHistoryResult, AkumaInterruptInput, AkumaInterruptResult, AkumaKillResult, AkumaObservation, AkumaSetAddressInput, AkumaStatus, AkumaTellInput, CreatedTaskObservation, AkumaTellResult, AkumaWaitInput, AkumaWaitResult, AkumaWorldScopeRefusal, AliasBinding, AliasStage, AmendResult, AmendInput, ArcInput, AuditReport, DeliveryPreparationRefusal, BindInput, BindResult, CallInput, CallObservation, CallResult, Catalog, CatalogInput, CatalogQuery, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractHistory, ContractHistoryEvent, ContractListInput, ContractObservation, ContractObservationInput, ContractPhase, ContractRow, DeliverInput, Fact, FactKind, Dispatch, DispatchFailure, DispatchStage, DirectAkumaSelector, Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, KeiyakuOfInput, KeiyakuRefusal, KeiyakuRetryReason, ForkInput, ForkResult, IntegrationFailure, Lag, MutationResult, PlacementStop, RegionOverlap, ReconcileInput, RepoReconcileReport, Review, ReconcileReport, ReviewInput, RepoAtInput, AuditInput, SnapshotId, SettlementAction, SettlementLag, SettlementReport, SetAkumaSelector, TaskId, TopologyEffect, VerificationReuse, VerificationStop, WorktreeHooks, } from "./library/keiyaku.js";
@@ -1,3 +1,3 @@
1
- export { AuthorityCorruptionError, AkumaWorldScopeError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
1
+ export * from "./library/keiyaku.js";
2
2
  export { settings } from "./settings.js";
3
3
  export { World, WorldError } from "./world.js";
@@ -116,7 +116,13 @@ function addSelectorIds(selector, sources, selected, contractMembers) {
116
116
  selected.add(selector.value);
117
117
  }
118
118
  async function contractMemberInWorld(path, id) {
119
- return await probeBornAkuma(path, id);
119
+ try {
120
+ return await probeBornAkuma(path, id);
121
+ }
122
+ catch {
123
+ // A dispatched physical member remains selected when its Heart cannot be read.
124
+ return true;
125
+ }
120
126
  }
121
127
  async function refuseForeignContractMembers(path, ids, contractMembers) {
122
128
  const foreign = [];
@@ -1,5 +1,6 @@
1
1
  import type { ContractId } from "../core/facts/types.js";
2
- import { type AuditReport, type RepositoryScope } from "../protocol/operations.js";
2
+ import { type AuditReport } from "../protocol/audit.js";
3
+ import type { RepositoryScope } from "../protocol/operations.js";
3
4
  import { type WorktreeHooks } from "./configuration.js";
4
5
  import { type MutationResult } from "./mutation.js";
5
6
  export type AuditInput = Readonly<{
@@ -1,6 +1,6 @@
1
1
  import { decodeContractDocument } from "../body/decode.js";
2
2
  import { withGitDecodeChannel } from "../git/read-observation.js";
3
- import { auditOperation, } from "../protocol/operations.js";
3
+ import { auditOperation } from "../protocol/audit.js";
4
4
  import { worktreeHooksOption } from "./configuration.js";
5
5
  import { actorOption, documentDerivation, optionalBoolean, optionalSignal, requireInput, } from "./input.js";
6
6
  import { completeMutation } from "./mutation.js";
@@ -1,6 +1,7 @@
1
1
  import { type ActorId, type ContractId } from "../core/facts/types.js";
2
2
  import type { GitDecodeChannel } from "../git/read-observation.js";
3
- import { bindOperation, type IntentOutcome, type RepositoryScope } from "../protocol/operations.js";
3
+ import { bindOperation } from "../protocol/bind.js";
4
+ import type { IntentOutcome, RepositoryScope } from "../protocol/operations.js";
4
5
  import type { TaskId } from "../task/identity.js";
5
6
  import type { VerificationDeclarationPreparation } from "../verification/declaration.js";
6
7
  import type { KeiyakuRefusal } from "./refusal.js";
@@ -2,7 +2,7 @@ import { randomBytes } from "node:crypto";
2
2
  import { releaseContractWorktree, reserveContractWorktree, withContractWorktreeAppointment, } from "../contract-worktree.js";
3
3
  import { contractIdFromSegment } from "../core/facts/types.js";
4
4
  import { fitIdentityStem, normalizeIdentityStem } from "../identity/normalize.js";
5
- import { bindOperation } from "../protocol/operations.js";
5
+ import { bindOperation } from "../protocol/bind.js";
6
6
  import { claimTaskHolder } from "../settlement/holder.js";
7
7
  function candidateId(title, collision) {
8
8
  const stem = fitIdentityStem({ stem: normalizeIdentityStem({ source: title }) || "contract", maxBytes: 48 });
@@ -4,7 +4,7 @@ export type { HookCommand, WorktreeHooks } from "../git/hooks.js";
4
4
  export type Gate = string;
5
5
  export type GatesFromInput = Readonly<{
6
6
  settings: Settings;
7
- name?: string;
7
+ names?: readonly string[];
8
8
  }>;
9
9
  export type RequireBranchesToBeUpToDateFromInput = Readonly<{
10
10
  settings: Settings;
@@ -9,31 +9,65 @@ function namespaceFailure(view) {
9
9
  throw new Error("settings namespace failure expected");
10
10
  throw new SettingsError(view.failures.map((failure) => `${failure.scope}: ${failure.diagnostic}`).join("; "));
11
11
  }
12
+ function bundleGates(name, value) {
13
+ if (!record(value))
14
+ throw new SettingsError(`gate bundle '${name}' must be an object`);
15
+ if (value.kind !== "bundle") {
16
+ throw new SettingsError(`gate bundle '${name}' has unsupported kind: ${String(value.kind)}`);
17
+ }
18
+ for (const field of Object.keys(value)) {
19
+ if (field !== "kind" && field !== "gates") {
20
+ throw new SettingsError(`gate bundle '${name}' has unknown field: ${field}`);
21
+ }
22
+ }
23
+ if (!Array.isArray(value.gates)) {
24
+ throw new SettingsError(`gate bundle '${name}'.gates must be an array`);
25
+ }
26
+ return value.gates.map((gate) => {
27
+ if (!gateWord(gate)) {
28
+ throw new SettingsError(`gate bundle '${name}' contains an invalid gate word`);
29
+ }
30
+ if (gate !== "reviewed" && gate !== "verified") {
31
+ throw new SettingsError(`gate bundle '${name}' contains a gate without a producer: ${gate}`);
32
+ }
33
+ return gate;
34
+ });
35
+ }
12
36
  export function gatesFrom(input) {
13
37
  if (!record(input))
14
38
  throw new TypeError("gatesFrom input must be an object");
15
- const name = input.name ?? "default";
16
- if (!gateWord(name))
17
- throw new SettingsError("gate set name must match ^[a-z][a-z0-9-]{0,63}$");
39
+ if (input.names !== undefined && !Array.isArray(input.names)) {
40
+ throw new TypeError("gatesFrom names must be an array");
41
+ }
42
+ const names = input.names ?? ["default"];
43
+ for (const name of names) {
44
+ if (!gateWord(name))
45
+ throw new SettingsError("gate bundle name must match ^[a-z][a-z0-9-]{0,63}$");
46
+ }
18
47
  const view = input.settings.namespace("gates");
19
48
  if (view.kind === "failed")
20
49
  namespaceFailure(view);
21
- const selected = view.entries.find((entry) => entry.name === name);
22
- if (selected === undefined) {
23
- if (input.name === undefined)
24
- return Object.freeze([]);
25
- throw new SettingsError(`unknown gate set: ${name}`);
50
+ const expanded = [];
51
+ const seen = new Set();
52
+ for (const name of names) {
53
+ const selected = view.entries.find((entry) => entry.name === name);
54
+ if (selected === undefined) {
55
+ if (input.names === undefined) {
56
+ if (!seen.has("reviewed"))
57
+ expanded.push("reviewed");
58
+ seen.add("reviewed");
59
+ continue;
60
+ }
61
+ throw new SettingsError(`unknown gate bundle: ${name}`);
62
+ }
63
+ for (const gate of bundleGates(name, selected.value)) {
64
+ if (seen.has(gate))
65
+ continue;
66
+ seen.add(gate);
67
+ expanded.push(gate);
68
+ }
26
69
  }
27
- if (!Array.isArray(selected.value))
28
- throw new SettingsError(`gate set '${name}' must be an array`);
29
- const values = selected.value.map((value) => {
30
- if (!gateWord(value))
31
- throw new SettingsError(`gate set '${name}' contains an invalid gate word`);
32
- return value;
33
- });
34
- if (new Set(values).size !== values.length)
35
- throw new SettingsError(`gate set '${name}' contains duplicate gates`);
36
- return Object.freeze(values);
70
+ return Object.freeze(expanded);
37
71
  }
38
72
  function command(value, coordinate, ErrorType) {
39
73
  if (!record(value))
@@ -3,7 +3,13 @@ import { type RegionObservation, type RegionOverlap } from "./region.js";
3
3
  import { type Gate, type WorktreeHooks } from "./configuration.js";
4
4
  import { type ChangeId, type ContractId, type ContractState, type JournalEntry, type SnapshotId } from "../core/facts/types.js";
5
5
  export { AuthorityCorruptionError } from "../core/facts/errors.js";
6
- import { type AuditReport, type ContractBoard, type ContractDisposition, type ContractGateCurrent, type ContractGateReport, type ContractObservation, type ContractPhase, type ContractRow, type FactKind, type PlacementStop, type ReconcileReport as ProtocolReconcileReport, type RepositoryScope, type ReviewValue, type VerificationReuse, type VerificationStop, type DeliveryPreparationRefusal } from "../protocol/operations.js";
6
+ import { type PlacementStop, type RepositoryScope, type VerificationStop, type DeliveryPreparationRefusal } from "../protocol/operations.js";
7
+ import type { ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow } from "../protocol/read/status.js";
8
+ import type { AuditReport } from "../protocol/audit.js";
9
+ import { type DeliverValue, type VerificationReuse } from "../protocol/deliver.js";
10
+ import type { ReconcileReport as ProtocolReconcileReport } from "../protocol/reconcile.js";
11
+ import { type ReviewValue } from "../protocol/review.js";
12
+ import type { FactKind } from "../core/facts/types.js";
7
13
  import { type Dispatch } from "../dispatch/index.js";
8
14
  import { type SettlementReport } from "../settlement/settle.js";
9
15
  import { type TaskId } from "../task/identity.js";
@@ -11,7 +17,10 @@ import { Repo, type ReconcileInput } from "./repo.js";
11
17
  import { type AuditInput } from "./audit.js";
12
18
  import { Delivery } from "./delivery.js";
13
19
  import { type MutationResult } from "./mutation.js";
14
- export { KeiyakuRefused, KeiyakuRetry, type ContractAppointmentRefusal, type KeiyakuRefusal, type KeiyakuRetryReason, } from "./refusal.js";
20
+ import { KeiyakuRetry, type KeiyakuRefusal, type KeiyakuRetryReason } from "./refusal.js";
21
+ export { KeiyakuRefused, type ContractAppointmentRefusal, } from "./refusal.js";
22
+ export { KeiyakuRetry };
23
+ export type { KeiyakuRefusal, KeiyakuRetryReason };
15
24
  export { gatesFrom, requireBranchesToBeUpToDateFrom, SettingsError } from "./configuration.js";
16
25
  export type { Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, WorktreeHooks } from "./configuration.js";
17
26
  export type { AuditReport, DeliveryPreparationRefusal, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractObservation, ContractPhase, ContractRow, FactKind, SnapshotId, };
@@ -103,7 +112,51 @@ export type DeliverInput = ActorOptions & Readonly<{
103
112
  includeDirty?: boolean;
104
113
  signal?: AbortSignal;
105
114
  }>;
115
+ type ForwardedDeliveryReceipt = Readonly<{
116
+ kind: "accepted";
117
+ result: MutationResult<DeliverValue>;
118
+ }> | Readonly<{
119
+ kind: "refused";
120
+ refusal: KeiyakuRefusal;
121
+ }> | Readonly<{
122
+ kind: "retry";
123
+ reason: KeiyakuRetryReason;
124
+ }>;
125
+ type ForwardedReviewReceipt = Readonly<{
126
+ kind: "accepted";
127
+ result: MutationResult<ReviewValue>;
128
+ }> | Readonly<{
129
+ kind: "refused";
130
+ refusal: KeiyakuRefusal;
131
+ }> | Readonly<{
132
+ kind: "retry";
133
+ reason: KeiyakuRetryReason;
134
+ }>;
106
135
  export type { AuditInput };
136
+ export declare function executeForwardedDeliver(input: Readonly<{
137
+ repo: Repo;
138
+ contractId: string;
139
+ requester: string;
140
+ message?: string;
141
+ includeDirty: boolean;
142
+ requireBranchesToBeUpToDate: boolean;
143
+ hooks: WorktreeHooks;
144
+ signal?: AbortSignal;
145
+ }>): Promise<Readonly<{
146
+ result: ForwardedDeliveryReceipt;
147
+ deliveryFactId?: string;
148
+ }>>;
149
+ export declare function executeForwardedReview(input: Readonly<{
150
+ repo: Repo;
151
+ contractId: string;
152
+ requester: string;
153
+ verdict: AttestationVerdict;
154
+ summary?: string;
155
+ hooks: WorktreeHooks;
156
+ }>): Promise<Readonly<{
157
+ result: ForwardedReviewReceipt;
158
+ reviewFactId?: string;
159
+ }>>;
107
160
  export declare class KeiyakuHandle {
108
161
  private readonly id;
109
162
  private readonly scope;