@astrosheep/keiyaku 4.5.7 → 4.5.8

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 (234) hide show
  1. package/README.md +10 -0
  2. package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
  3. package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
  4. package/build/integrations/marketplace/plugins/keiyaku/opencode.js +3 -2
  5. package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
  6. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +10 -9
  7. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +22 -1
  8. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
  9. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
  10. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
  11. package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
  12. package/build/src/akuma/abort.d.ts +2 -1
  13. package/build/src/akuma/abort.js +6 -23
  14. package/build/src/akuma/akuma-handle.js +4 -2
  15. package/build/src/akuma/akuma-observe.d.ts +2 -0
  16. package/build/src/akuma/akuma-observe.js +1 -0
  17. package/build/src/akuma/akuma-product.js +9 -7
  18. package/build/src/akuma/akuma.d.ts +372 -9
  19. package/build/src/akuma/akuma.js +31 -1
  20. package/build/src/akuma/allowed.d.ts +1 -1
  21. package/build/src/akuma/allowed.js +1 -0
  22. package/build/src/akuma/body.d.ts +6 -4
  23. package/build/src/akuma/body.js +5 -3
  24. package/build/src/akuma/call-request.d.ts +80 -0
  25. package/build/src/akuma/call-request.js +211 -0
  26. package/build/src/akuma/heart/facts.d.ts +6 -78
  27. package/build/src/akuma/heart/index.d.ts +1 -1
  28. package/build/src/akuma/heart/request-authority.d.ts +5 -4
  29. package/build/src/akuma/heart/request-authority.js +20 -34
  30. package/build/src/akuma/heart/request-rows.js +12 -23
  31. package/build/src/akuma/heart/schema.d.ts +1 -1
  32. package/build/src/akuma/heart/schema.js +5 -13
  33. package/build/src/akuma/index.d.ts +1 -1
  34. package/build/src/akuma/index.js +1 -1
  35. package/build/src/akuma/projection-read.d.ts +1 -0
  36. package/build/src/akuma/projection-read.js +8 -1
  37. package/build/src/akuma/projection.d.ts +856 -137
  38. package/build/src/akuma/projection.js +190 -0
  39. package/build/src/akuma/provider.d.ts +30 -3
  40. package/build/src/akuma/provider.js +104 -0
  41. package/build/src/akuma/providers/acp/core.d.ts +2 -2
  42. package/build/src/akuma/providers/acp/core.js +13 -6
  43. package/build/src/akuma/providers/acp/index.js +5 -4
  44. package/build/src/akuma/providers/claude/index.d.ts +3 -3
  45. package/build/src/akuma/providers/claude/index.js +16 -5
  46. package/build/src/akuma/providers/codex-app-server/events.js +1 -1
  47. package/build/src/akuma/providers/codex-app-server/index.js +18 -6
  48. package/build/src/akuma/providers/grok-build/index.js +5 -4
  49. package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
  50. package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
  51. package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
  52. package/build/src/akuma/providers/pi/index.js +42 -14
  53. package/build/src/akuma/request-lifecycle.d.ts +3 -9
  54. package/build/src/akuma/request-lifecycle.js +4 -4
  55. package/build/src/akuma/request-rendezvous.d.ts +26 -0
  56. package/build/src/akuma/request-rendezvous.js +100 -0
  57. package/build/src/akuma/request-serve.d.ts +5 -65
  58. package/build/src/akuma/request-serve.js +81 -208
  59. package/build/src/akuma/request-wire.d.ts +109 -115
  60. package/build/src/akuma/request-wire.js +63 -318
  61. package/build/src/akuma/requests.d.ts +19 -47
  62. package/build/src/akuma/requests.js +51 -107
  63. package/build/src/akuma/turn-drive.d.ts +5 -3
  64. package/build/src/akuma/turn-drive.js +32 -10
  65. package/build/src/akuma-body.d.ts +7 -2
  66. package/build/src/akuma-body.js +68 -46
  67. package/build/src/cli/accepted.d.ts +1 -1
  68. package/build/src/cli/accepted.js +2 -2
  69. package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
  70. package/build/src/cli/commands/akuma-invoke.js +17 -9
  71. package/build/src/cli/commands/akuma.js +7 -7
  72. package/build/src/cli/commands/contract-invoke.d.ts +3 -2
  73. package/build/src/cli/commands/contract-invoke.js +26 -19
  74. package/build/src/cli/commands/contract.d.ts +13 -13
  75. package/build/src/cli/commands/contract.js +32 -17
  76. package/build/src/cli/commands/install.d.ts +1 -1
  77. package/build/src/cli/commands/install.js +1 -1
  78. package/build/src/cli/commands/task-invoke.d.ts +3 -0
  79. package/build/src/cli/commands/task-invoke.js +23 -140
  80. package/build/src/cli/commands/task.js +54 -20
  81. package/build/src/cli/invoke.js +39 -25
  82. package/build/src/cli/main.js +2 -1
  83. package/build/src/cli/parse.d.ts +2 -2
  84. package/build/src/cli/parse.js +37 -22
  85. package/build/src/cli/render/akuma-activity.d.ts +4 -1
  86. package/build/src/cli/render/akuma-activity.js +45 -30
  87. package/build/src/cli/render/akuma-tool.d.ts +5 -1
  88. package/build/src/cli/render/akuma.js +5 -9
  89. package/build/src/cli/render/audit.js +1 -1
  90. package/build/src/cli/render/catalog.js +80 -21
  91. package/build/src/cli/render/contract-observation.d.ts +2 -0
  92. package/build/src/cli/render/contract-observation.js +11 -0
  93. package/build/src/cli/render/contract.js +25 -65
  94. package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
  95. package/build/src/cli/render/kanshi-akuma.js +111 -0
  96. package/build/src/cli/render/kanshi.js +108 -213
  97. package/build/src/cli/render/receipt.d.ts +1 -2
  98. package/build/src/cli/render/receipt.js +76 -26
  99. package/build/src/cli/render/refusal.js +2 -10
  100. package/build/src/cli/render/region.js +5 -2
  101. package/build/src/cli/render/settings.d.ts +1 -1
  102. package/build/src/cli/render/settings.js +27 -8
  103. package/build/src/cli/render/task.js +22 -5
  104. package/build/src/cli/render/terminal.d.ts +28 -0
  105. package/build/src/cli/render/terminal.js +65 -0
  106. package/build/src/cli/result.d.ts +3 -3
  107. package/build/src/cli/runtime.js +3 -1
  108. package/build/src/cli/selectors.d.ts +2 -1
  109. package/build/src/cli/selectors.js +4 -3
  110. package/build/src/cli/square-edge.js +120 -36
  111. package/build/src/cli/usage.js +2 -1
  112. package/build/src/contract-guidance.d.ts +5 -0
  113. package/build/src/contract-guidance.js +121 -0
  114. package/build/src/contract-worktree.d.ts +0 -1
  115. package/build/src/contract-worktree.js +32 -83
  116. package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
  117. package/build/src/coordination/sqlite-transaction-lock.js +5 -0
  118. package/build/src/core/facts/codec.d.ts +2 -0
  119. package/build/src/core/facts/codec.js +4 -0
  120. package/build/src/core/verbs/placement.d.ts +6 -1
  121. package/build/src/core/verbs/placement.js +5 -3
  122. package/build/src/dispatch/index.d.ts +0 -2
  123. package/build/src/dispatch/index.js +54 -55
  124. package/build/src/git/admission.js +2 -2
  125. package/build/src/git/hooks.d.ts +9 -15
  126. package/build/src/git/hooks.js +23 -317
  127. package/build/src/git/nuke.d.ts +2 -1
  128. package/build/src/git/nuke.js +36 -18
  129. package/build/src/git/private-state-seat.d.ts +12 -0
  130. package/build/src/git/private-state-seat.js +39 -0
  131. package/build/src/git/process.d.ts +6 -0
  132. package/build/src/git/process.js +19 -7
  133. package/build/src/git/read-observation.js +29 -20
  134. package/build/src/git/reconcile.d.ts +11 -0
  135. package/build/src/git/reconcile.js +64 -11
  136. package/build/src/git/repository.d.ts +6 -2
  137. package/build/src/git/repository.js +8 -0
  138. package/build/src/git/target-placement.d.ts +1 -0
  139. package/build/src/git/target-placement.js +5 -0
  140. package/build/src/git/tender.d.ts +1 -0
  141. package/build/src/git/terminal-reconcile.d.ts +1 -1
  142. package/build/src/git/terminal-reconcile.js +22 -20
  143. package/build/src/git/workspace.d.ts +14 -0
  144. package/build/src/git/workspace.js +44 -0
  145. package/build/src/kanshi/index.d.ts +1 -1
  146. package/build/src/kanshi/read.js +16 -16
  147. package/build/src/kanshi/report.d.ts +2 -2
  148. package/build/src/library/address.d.ts +9 -3
  149. package/build/src/library/address.js +3 -2
  150. package/build/src/library/akuma-creation.d.ts +4 -3
  151. package/build/src/library/akuma-creation.js +19 -13
  152. package/build/src/library/audit.d.ts +1 -1
  153. package/build/src/library/audit.js +5 -3
  154. package/build/src/library/catalog.d.ts +3 -1
  155. package/build/src/library/catalog.js +20 -6
  156. package/build/src/library/composition.d.ts +371 -0
  157. package/build/src/library/composition.js +28 -0
  158. package/build/src/library/configuration.js +8 -2
  159. package/build/src/library/continuation.js +66 -30
  160. package/build/src/library/contract-bind.js +10 -2
  161. package/build/src/library/contract-forwarding-reconciliation-result.d.ts +96 -0
  162. package/build/src/library/contract-forwarding-reconciliation-result.js +83 -0
  163. package/build/src/library/contract-forwarding-result.d.ts +6723 -0
  164. package/build/src/library/contract-forwarding-result.js +521 -0
  165. package/build/src/library/contract-forwarding.d.ts +72 -0
  166. package/build/src/library/contract-forwarding.js +125 -0
  167. package/build/src/library/contract-handle.d.ts +36 -0
  168. package/build/src/library/contract-handle.js +313 -0
  169. package/build/src/library/contract-operations.d.ts +1044 -67
  170. package/build/src/library/contract-operations.js +190 -118
  171. package/build/src/library/contract.d.ts +11 -32
  172. package/build/src/library/contract.js +16 -289
  173. package/build/src/library/fleet-result.d.ts +1454 -0
  174. package/build/src/library/fleet-result.js +96 -0
  175. package/build/src/library/fleet.d.ts +112 -54
  176. package/build/src/library/fleet.js +211 -71
  177. package/build/src/library/input.d.ts +2 -0
  178. package/build/src/library/input.js +4 -0
  179. package/build/src/library/keiyaku.d.ts +371 -20
  180. package/build/src/library/keiyaku.js +8 -21
  181. package/build/src/library/mutation.d.ts +3 -3
  182. package/build/src/library/mutation.js +5 -9
  183. package/build/src/library/nuke.d.ts +1 -1
  184. package/build/src/library/nuke.js +4 -3
  185. package/build/src/library/reconcile.d.ts +4 -0
  186. package/build/src/library/reconcile.js +2 -0
  187. package/build/src/library/refusal.d.ts +0 -9
  188. package/build/src/library/refusal.js +0 -7
  189. package/build/src/protocol/amend.js +56 -50
  190. package/build/src/protocol/attempt.d.ts +2 -0
  191. package/build/src/protocol/attempt.js +8 -1
  192. package/build/src/protocol/completion.js +7 -0
  193. package/build/src/protocol/deliver.js +6 -2
  194. package/build/src/protocol/operations.d.ts +4 -1
  195. package/build/src/protocol/operations.js +5 -2
  196. package/build/src/protocol/placement.d.ts +1 -0
  197. package/build/src/protocol/placement.js +52 -38
  198. package/build/src/protocol/read/observation.d.ts +1 -4
  199. package/build/src/protocol/read/observation.js +2 -15
  200. package/build/src/protocol/reintegrate.js +62 -58
  201. package/build/src/protocol/review.js +5 -0
  202. package/build/src/protocol/run.js +17 -13
  203. package/build/src/runtime/proc/run.d.ts +8 -0
  204. package/build/src/runtime/proc/run.js +27 -0
  205. package/build/src/runtime/proc/termination.js +26 -22
  206. package/build/src/runtime/proc/windows-launch.exe +0 -0
  207. package/build/src/settlement/holder.d.ts +2 -1
  208. package/build/src/settlement/holder.js +15 -4
  209. package/build/src/settlement/settle.js +99 -33
  210. package/build/src/task/board.d.ts +68 -27
  211. package/build/src/task/board.js +31 -1
  212. package/build/src/task/catalog.d.ts +4 -0
  213. package/build/src/task/catalog.js +23 -0
  214. package/build/src/task/compose-language.js +33 -7
  215. package/build/src/task/compose-parser.d.ts +1 -1
  216. package/build/src/task/compose-parser.js +1 -1
  217. package/build/src/task/compose.js +2 -0
  218. package/build/src/task/index.d.ts +12 -4
  219. package/build/src/task/index.js +97 -16
  220. package/build/src/task/mutation-result.d.ts +923 -0
  221. package/build/src/task/mutation-result.js +140 -0
  222. package/build/src/task/mutation.d.ts +552 -28
  223. package/build/src/task/mutation.js +304 -97
  224. package/build/src/task/operations.d.ts +1 -4
  225. package/build/src/task/operations.js +0 -6
  226. package/build/src/task/public.d.ts +2 -0
  227. package/build/src/task/public.js +1 -0
  228. package/build/src/workspace-place.d.ts +7 -2
  229. package/build/src/workspace-place.js +34 -24
  230. package/build/src/world.d.ts +1 -0
  231. package/build/src/world.js +11 -0
  232. package/package.json +8 -6
  233. package/build/src/akuma/request-execution.d.ts +0 -8
  234. package/build/src/akuma/request-execution.js +0 -98
@@ -1,5 +1,5 @@
1
- import { spawn } from "node:child_process";
2
1
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
2
+ import { spawnCancellableProcess } from "../runtime/proc/run.js";
3
3
  import { gitObjectId } from "./identity.js";
4
4
  import { parseTreeObject, validPath } from "./tree.js";
5
5
  import { GIT_FORMAT_BYTES, GIT_FORMAT_PATH, GIT_REF, readRef } from "./repository.js";
@@ -36,11 +36,18 @@ function streamCursor(stream) {
36
36
  };
37
37
  return { line, exact };
38
38
  }
39
+ async function batchObjects(oids, object) {
40
+ const unique = [...new Set(oids)];
41
+ for (const oid of unique)
42
+ gitObjectId(oid, "Git object");
43
+ const entries = await Promise.all(unique.map(async (oid) => [oid, await object(oid)]));
44
+ return new Map(entries);
45
+ }
39
46
  function batchChild(repository) {
40
- return spawn(repository.gitPath, ["cat-file", "--batch"], {
47
+ return spawnCancellableProcess({
48
+ argv: [repository.gitPath, "cat-file", "--batch"],
41
49
  cwd: repository.effectiveCwd,
42
- stdio: ["pipe", "pipe", "pipe"],
43
- windowsHide: true,
50
+ ...(repository.signal === undefined ? {} : { signal: repository.signal }),
44
51
  });
45
52
  }
46
53
  function batchError(child, stderr, message, status) {
@@ -51,8 +58,18 @@ function batchError(child, stderr, message, status) {
51
58
  pid: child.pid ?? null,
52
59
  });
53
60
  }
61
+ async function closeBatchProcess(process, child, closed, spawnError, stderr) {
62
+ if (!child.stdin.destroyed)
63
+ child.stdin.end();
64
+ const outcome = await closed;
65
+ await process.waitTermination();
66
+ if (spawnError !== null || outcome.code !== 0) {
67
+ throw batchError(child, stderr, process.cancelled() ? "git process cancelled" : "git cat-file --batch did not close cleanly", outcome.code);
68
+ }
69
+ }
54
70
  function batchObjectReader(repository) {
55
- const child = batchChild(repository);
71
+ const process = batchChild(repository);
72
+ const child = process.child;
56
73
  const cursor = streamCursor(child.stdout);
57
74
  const cache = new Map();
58
75
  const stderr = [];
@@ -101,9 +118,10 @@ function batchObjectReader(repository) {
101
118
  catch (error) {
102
119
  if (failure !== null)
103
120
  throw failure;
104
- child.kill();
121
+ await process.terminate(true);
105
122
  await closed;
106
- failure = batchError(child, stderr, error instanceof Error ? error.message : String(error), child.exitCode);
123
+ await process.waitTermination();
124
+ failure = batchError(child, stderr, process.cancelled() ? "git process cancelled" : error instanceof Error ? error.message : String(error), process.cancelled() ? null : child.exitCode);
107
125
  throw failure;
108
126
  }
109
127
  };
@@ -116,23 +134,14 @@ function batchObjectReader(repository) {
116
134
  cache.set(oid, requested);
117
135
  return requested;
118
136
  };
119
- const objects = async (oids) => {
120
- const unique = [...new Set(oids)];
121
- for (const oid of unique)
122
- gitObjectId(oid, "Git object");
123
- const entries = await Promise.all(unique.map(async (oid) => [oid, await object(oid)]));
124
- return new Map(entries);
125
- };
137
+ const objects = (oids) => batchObjects(oids, object);
126
138
  const close = async () => {
127
139
  await tail.catch(() => undefined);
128
- if (failure !== null)
140
+ if (failure !== null) {
141
+ await process.waitTermination();
129
142
  return;
130
- if (!child.stdin.destroyed)
131
- child.stdin.end();
132
- const outcome = await closed;
133
- if (spawnError !== null || outcome.code !== 0) {
134
- throw batchError(child, stderr, "git cat-file --batch did not close cleanly", outcome.code);
135
143
  }
144
+ await closeBatchProcess(process, child, closed, spawnError, stderr);
136
145
  };
137
146
  return { objects, close };
138
147
  }
@@ -46,6 +46,7 @@ type WorktreeFollowRetained = Readonly<{
46
46
  tender: SnapshotId;
47
47
  head: SnapshotId;
48
48
  reason: "head-moved" | "head-attached" | "operation-in-progress" | "unsupported-parent-shape";
49
+ paths?: readonly string[];
49
50
  }>;
50
51
  export type ReconcileFailure = Readonly<{
51
52
  kind: "reconcile-failed";
@@ -56,6 +57,10 @@ export type ReconcileLag = WorktreeRetained | WorktreeFollowRetained | UnsealedB
56
57
  export type ReconcileResult = Readonly<{
57
58
  effects: readonly Effect[];
58
59
  lag: readonly ReconcileLag[];
60
+ hookRuns?: readonly {
61
+ phase: "create" | "destroy";
62
+ name: string;
63
+ }[];
59
64
  }>;
60
65
  type ReconcileBatchItem = Readonly<{
61
66
  contract: ContractId;
@@ -72,8 +77,14 @@ export type WorktreeTopology = Readonly<{
72
77
  export type ReconcileAccumulation = Readonly<{
73
78
  effects: Effect[];
74
79
  lag: ReconcileLag[];
80
+ hookRuns: {
81
+ phase: "create" | "destroy";
82
+ name: string;
83
+ }[];
75
84
  }>;
76
85
  export declare function reconcile(input: ReconcileInput): Promise<GitReconcileObservation>;
86
+ /** Reconcile one retained dependent worktree under its normal per-Contract lock. */
87
+ export declare function reconcileDependentWorktree(repository: GitRepository, contractId: ContractId, path: string, target: SnapshotId): Promise<ReconcileResult>;
77
88
  export declare function reconcileObservationFailure(error: unknown): ReconcileResult;
78
89
  export declare function reconcileEffectFailure(error: unknown, prior?: ReconcileResult): ReconcileResult;
79
90
  type ReconcileBatchOptions = Readonly<{
@@ -2,13 +2,13 @@ import { access, mkdir } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import { acquireSqliteTransactionLock, } from "../coordination/sqlite-transaction-lock.js";
4
4
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
5
- import { CANDIDATE_PIN_REF_NAMESPACE, commonGitDirectory, DELIVERY_REF_NAMESPACE, registeredWorktreePaths, worktreeGitDirectory, } from "./repository.js";
5
+ import { CANDIDATE_PIN_REF_NAMESPACE, commonGitDirectory, DELIVERY_REF_NAMESPACE, registeredWorktreePaths, } from "./repository.js";
6
6
  import { runGit } from "./process.js";
7
7
  import { contractLocator, contractPhysicalName, gitObjectIdForSnapshot } from "./identity.js";
8
8
  import { observeContractAt } from "./observe.js";
9
9
  import { acquireTargetPlacementFence, recoverTargetPlacement, } from "./target-placement.js";
10
10
  import { runCreateHooks } from "./hooks.js";
11
- import { followManagedWorktree, worktreePath } from "./workspace.js";
11
+ import { followDependentManagedWorktree, followManagedWorktree, worktreePath } from "./workspace.js";
12
12
  import { removeCollectableScratchWorktrees } from "./scratch.js";
13
13
  import { reconcileTerminalManagedWorktree, removeRef, updateRef } from "./terminal-reconcile.js";
14
14
  const pathExists = (path) => access(path).then(() => true, () => false);
@@ -31,8 +31,8 @@ async function acquireWorktreeTopology(repository) {
31
31
  function diagnostic(error) {
32
32
  return error instanceof Error ? error.message : String(error);
33
33
  }
34
- function complete(effects = [], lag = []) {
35
- return { effects, lag };
34
+ function complete(effects = [], lag = [], hookRuns = []) {
35
+ return hookRuns.length === 0 ? { effects, lag } : { effects, lag, hookRuns };
36
36
  }
37
37
  function failed(stage, error, effects = [], lag = []) {
38
38
  if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
@@ -103,7 +103,7 @@ async function reconcileTargetCheckouts(repository, state) {
103
103
  result = failed("effect", releaseFailure, result.effects, result.lag);
104
104
  return result;
105
105
  }
106
- async function reconcileActiveManagedWorktree({ repository, hooks, retryHooks, place }, state, topology, { effects, lag }) {
106
+ async function reconcileActiveManagedWorktree({ repository, hooks, retryHooks, place }, state, topology, { effects, lag, hookRuns }) {
107
107
  if (place === undefined)
108
108
  return complete(effects, [...lag, missingPlaceLag(repository)]);
109
109
  const path = worktreePath(repository, place);
@@ -131,18 +131,22 @@ async function reconcileActiveManagedWorktree({ repository, hooks, retryHooks, p
131
131
  else {
132
132
  effects.push(projection);
133
133
  }
134
- const hookLag = await runCreateHooks(path, await worktreeGitDirectory(repository, path), hooks, retryHooks);
135
- if (hookLag !== null)
136
- lag.push(hookLag);
134
+ if (projection.action === "created" || retryHooks) {
135
+ const hookRun = await runCreateHooks(path, hooks);
136
+ hookRuns.push(...hookRun.runs.map((name) => ({ phase: "create", name })));
137
+ if (hookRun.lag !== null)
138
+ lag.push(hookRun.lag);
139
+ }
137
140
  effects.push(await (state.delivery
138
141
  ? await updateRef(repository, candidatePinRefFor(state.id), state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot)
139
142
  : await removeRef(repository, candidatePinRefFor(state.id))));
140
- return complete(effects, lag);
143
+ return complete(effects, lag, hookRuns);
141
144
  }
142
145
  async function reconcileWithTopology(input, state, topology) {
143
146
  const { repository } = input;
144
147
  const effects = [];
145
148
  const lag = [];
149
+ const hookRuns = [];
146
150
  try {
147
151
  await removeCollectableScratch(repository, topology, effects, lag);
148
152
  if (!state)
@@ -151,9 +155,10 @@ async function reconcileWithTopology(input, state, topology) {
151
155
  effects.push(...targetCheckouts.effects);
152
156
  lag.push(...targetCheckouts.lag);
153
157
  if (state.terminal) {
154
- return await reconcileTerminalManagedWorktree(input, state, topology, { effects, lag }, { ref: deliveryRefFor(state.id), pin: candidatePinRefFor(state.id) });
158
+ return await reconcileTerminalManagedWorktree(input, state, topology, { effects, lag, hookRuns }, { ref: deliveryRefFor(state.id), pin: candidatePinRefFor(state.id) });
155
159
  }
156
- return await reconcileActiveManagedWorktree(input, state, topology, { effects, lag });
160
+ const result = await reconcileActiveManagedWorktree(input, state, topology, { effects, lag, hookRuns });
161
+ return hookRuns.length === 0 ? result : { ...result, hookRuns };
157
162
  }
158
163
  catch (error) {
159
164
  return failed("effect", error, effects, lag);
@@ -206,6 +211,54 @@ export async function reconcile(input) {
206
211
  throw new Error("reconcile produced no observation");
207
212
  return observation;
208
213
  }
214
+ /** Reconcile one retained dependent worktree under its normal per-Contract lock. */
215
+ export async function reconcileDependentWorktree(repository, contractId, path, target) {
216
+ let held;
217
+ try {
218
+ held = await acquireSqliteTransactionLock({ path: reconcileLockPath(repository, contractId), mode: "immediate" });
219
+ }
220
+ catch (error) {
221
+ return failed("effect", error);
222
+ }
223
+ let result;
224
+ try {
225
+ const follow = await followDependentManagedWorktree(repository, path, target);
226
+ if (follow.kind === "followed") {
227
+ result = {
228
+ effects: [{ kind: "worktree", path, action: "followed", before: follow.before, after: follow.after }],
229
+ lag: [],
230
+ };
231
+ }
232
+ else if (follow.kind === "unchanged") {
233
+ result = { effects: [], lag: [] };
234
+ }
235
+ else {
236
+ result = {
237
+ effects: [{ kind: "worktree", path, action: "unchanged" }],
238
+ lag: [
239
+ {
240
+ kind: "worktree-follow-retained",
241
+ path,
242
+ tender: target,
243
+ head: follow.head,
244
+ reason: follow.reason,
245
+ ...(follow.paths.length === 0 ? {} : { paths: follow.paths }),
246
+ },
247
+ ],
248
+ };
249
+ }
250
+ }
251
+ catch (error) {
252
+ result = failed("effect", error, [{ kind: "worktree", path, action: "unchanged" }]);
253
+ }
254
+ try {
255
+ held.close();
256
+ }
257
+ catch (error) {
258
+ result = failed("effect", error, result.effects, result.lag);
259
+ }
260
+ return result;
261
+ }
209
262
  export function reconcileObservationFailure(error) {
210
263
  return failed("observation", error);
211
264
  }
@@ -8,6 +8,7 @@ export declare const MIGRATION_DELIVERY_REF_NAMESPACE = "refs/keiyaku/delivery";
8
8
  export declare const MIGRATION_CANDIDATE_PIN_REF_NAMESPACE = "refs/keiyaku/candidate";
9
9
  export declare const GIT_FORMAT_PATH = "meta/format.json";
10
10
  export declare const GIT_FORMAT_BYTES = "{\"version\":4}\n";
11
+ export declare const STATE_COMMIT_SUBJECT = "keiyaku authority - do not delete or rewrite";
11
12
  export declare function isKeiyakuOwnedRef(ref: string): boolean;
12
13
  export type GitOid = string;
13
14
  export type RefPublication = Readonly<{
@@ -54,14 +55,17 @@ export declare function readBlob(repository: GitRepository, oid: GitOid): Promis
54
55
  export declare function updateGitTree(repository: GitRepository, baseTree: GitOid | null, changes: ReadonlyMap<string, TreeChange>): Promise<GitOid>;
55
56
  /** Write a tree update from directory entries frozen with the admitted base tree. */
56
57
  export declare function updateGitTreeFromFrozenDirectories(repository: GitRepository, baseTree: GitOid | null, directories: ReadonlyMap<string, ReadonlyMap<string, TreeEntry>>, changes: ReadonlyMap<string, TreeChange>): Promise<GitOid>;
57
- export declare function writeCommit(input: Readonly<{
58
+ type WriteCommitInput = Readonly<{
58
59
  repository: GitRepository;
59
60
  tree: GitOid;
60
61
  parent: GitOid | null;
61
62
  message?: string;
62
63
  actor?: string;
63
64
  at?: string;
64
- }>): Promise<GitOid>;
65
+ }>;
66
+ export declare function writeCommit(input: WriteCommitInput): Promise<GitOid>;
67
+ /** Write a commit that will become the canonical keiyaku-state tip. */
68
+ export declare function writeStateCommit(input: WriteCommitInput): Promise<GitOid>;
65
69
  export declare function updateRefsAtomically(repository: GitRepository, updates: readonly ({
66
70
  readonly ref: typeof GIT_REF;
67
71
  readonly newOid: GitOid;
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-lines */
1
2
  import { isAbsolute, resolve } from "node:path";
2
3
  import { AuthorityCorruptionError } from "../core/facts/errors.js";
3
4
  import { gitObjectId } from "./identity.js";
@@ -11,6 +12,7 @@ export const MIGRATION_CANDIDATE_PIN_REF_NAMESPACE = "refs/keiyaku/candidate";
11
12
  export const GIT_FORMAT_PATH = "meta/format.json";
12
13
  const CURRENT_FORMAT_VERSION = 4;
13
14
  export const GIT_FORMAT_BYTES = `{"version":${CURRENT_FORMAT_VERSION}}\n`;
15
+ export const STATE_COMMIT_SUBJECT = "keiyaku authority - do not delete or rewrite";
14
16
  export function isKeiyakuOwnedRef(ref) {
15
17
  return (ref === GIT_REF ||
16
18
  ref === DELIVERY_REF_NAMESPACE ||
@@ -380,6 +382,12 @@ export async function writeCommit(input) {
380
382
  ...(input.at === undefined ? {} : { at: input.at }),
381
383
  });
382
384
  }
385
+ /** Write a commit that will become the canonical keiyaku-state tip. */
386
+ export async function writeStateCommit(input) {
387
+ const detail = input.message;
388
+ const message = detail === undefined || detail.length === 0 ? STATE_COMMIT_SUBJECT : `${STATE_COMMIT_SUBJECT}\n\n${detail}`;
389
+ return await writeCommit({ ...input, message });
390
+ }
383
391
  function refAssertionLine(assertion) {
384
392
  assertAssertionRef(assertion.ref);
385
393
  gitObjectId(assertion.oid, `expected oid for ${assertion.ref}`);
@@ -43,6 +43,7 @@ export type TargetPlacementPreparation = Readonly<{
43
43
  refusal: TargetPlacementRefusal;
44
44
  }>;
45
45
  export declare function observeTargetHead(repository: GitRepository, target: string): Promise<SnapshotId | null>;
46
+ export declare function observedTreeEqualsCandidate(repository: GitRepository, observed: SnapshotId | null, candidate: SnapshotId): Promise<boolean>;
46
47
  export declare function acquireTargetPlacementFence(repository: GitRepository, target: string): Promise<HeldSqliteTransactionLock>;
47
48
  export type TargetedContractCoordinates = ContractState["coordinates"] & Readonly<{
48
49
  target: string;
@@ -27,6 +27,11 @@ function literalPath(path) {
27
27
  async function commitTree(repository, snapshot) {
28
28
  return gitObjectId((await runGit(repository, ["show", "-s", "--format=%T", gitObjectIdForSnapshot(snapshot)])).toString("utf8").trim(), "commit tree");
29
29
  }
30
+ export async function observedTreeEqualsCandidate(repository, observed, candidate) {
31
+ if (observed === null)
32
+ return false;
33
+ return (await commitTree(repository, observed)) === (await commitTree(repository, candidate));
34
+ }
30
35
  function checkoutRefusal(contractId, target, path, reason, paths) {
31
36
  return { kind: "checkout-not-followable", contractId, target: target.target, path, reason, paths };
32
37
  }
@@ -9,6 +9,7 @@ export type TenderCaptureCoordinates = Readonly<{
9
9
  place?: string;
10
10
  workspacePath?: string;
11
11
  captureMergeState?: boolean;
12
+ /** Opt-in real-index UU refusal. Omit or false when authorized capture must read current worktree bytes. */
12
13
  rejectUnmerged?: boolean;
13
14
  }>;
14
15
  export type WorktreeMissingRefusal = Readonly<{
@@ -17,5 +17,5 @@ type TerminalCustodyRefs = Readonly<{
17
17
  }>;
18
18
  export declare function updateRef(repository: GitRepository, ref: string, desired: SnapshotId): Promise<Effect>;
19
19
  export declare function removeRef(repository: GitRepository, ref: string): Promise<Effect>;
20
- export declare function reconcileTerminalManagedWorktree({ repository, channel, hooks, retryHooks, retainTerminalWorktree, place }: TerminalReconcileInput, state: ContractState, topology: WorktreeTopology, acc: ReconcileAccumulation, { ref, pin }: TerminalCustodyRefs): Promise<ReconcileResult>;
20
+ export declare function reconcileTerminalManagedWorktree({ repository, channel, hooks, retainTerminalWorktree, place }: TerminalReconcileInput, state: ContractState, topology: WorktreeTopology, acc: ReconcileAccumulation, { ref, pin }: TerminalCustodyRefs): Promise<ReconcileResult>;
21
21
  export {};
@@ -1,5 +1,5 @@
1
1
  import { access } from "node:fs/promises";
2
- import { isKeiyakuOwnedRef, readRef, writeCommit, worktreeGitDirectory } from "./repository.js";
2
+ import { isKeiyakuOwnedRef, readRef, writeCommit } from "./repository.js";
3
3
  import { gitObjectIdForSnapshot, mintSnapshotId } from "./identity.js";
4
4
  import { runDestroyHooks } from "./hooks.js";
5
5
  import { terminalSealExpectations as decodeTerminalSealExpectations, terminalSealSnapshots, observeTerminalWorkspace, } from "./terminal-seal.js";
@@ -9,10 +9,7 @@ const pathExists = (path) => access(path).then(() => true, () => false);
9
9
  async function removeTerminalWorktree(repository, topology, path) {
10
10
  const registered = topology.paths.has(path);
11
11
  if (!registered) {
12
- return {
13
- effect: { kind: "worktree", path, action: "unchanged" },
14
- retained: await pathExists(path),
15
- };
12
+ return { retained: await pathExists(path) };
16
13
  }
17
14
  if (!(await pathExists(path))) {
18
15
  await runGit(repository, ["worktree", "remove", path]);
@@ -105,20 +102,20 @@ async function snapshotCustodian(repository, snapshot) {
105
102
  function fromPrimaryWorktree(repository) {
106
103
  return { ...repository, effectiveCwd: repository.primaryWorktree };
107
104
  }
108
- function complete(effects = [], lag = []) {
109
- return { effects, lag };
105
+ function complete(effects = [], lag = [], hookRuns = []) {
106
+ return hookRuns.length === 0 ? { effects, lag } : { effects, lag, hookRuns };
110
107
  }
111
- function retainTerminalWorktree(path, retainedLag, { effects, lag }) {
108
+ function retainTerminalWorktree(path, retainedLag, { effects, lag, hookRuns }) {
112
109
  effects.push({ kind: "worktree", path, action: "unchanged" });
113
110
  lag.push(retainedLag);
114
- return complete(effects, lag);
111
+ return complete(effects, lag, hookRuns);
115
112
  }
116
113
  async function terminalSealExpectations(channel, state) {
117
114
  const snapshots = terminalSealSnapshots(state);
118
115
  const objects = await channel.readObjects(snapshots.map(gitObjectIdForSnapshot));
119
116
  return decodeTerminalSealExpectations(state, objects);
120
117
  }
121
- async function removeSealedTerminalWorktree({ repository, topology, path, state, expected, hooks, retryHooks, acc, }) {
118
+ async function removeSealedTerminalWorktree({ repository, topology, path, state, expected, hooks, acc, }) {
122
119
  if (topology.paths.has(path) && (await pathExists(path))) {
123
120
  const terminal = state.terminal;
124
121
  if (terminal === null)
@@ -156,9 +153,10 @@ async function removeSealedTerminalWorktree({ repository, topology, path, state,
156
153
  }
157
154
  recovery = await recordRecovery(beforeWorkspace);
158
155
  }
159
- const hookLag = await runDestroyHooks(path, await worktreeGitDirectory(repository, path), hooks, retryHooks);
160
- if (hookLag !== null)
161
- return retainTerminalWorktree(path, hookLag, acc);
156
+ const hookRun = await runDestroyHooks(path, hooks);
157
+ acc.hookRuns.push(...hookRun.runs.map((name) => ({ phase: "destroy", name })));
158
+ if (hookRun.lag !== null)
159
+ return retainTerminalWorktree(path, hookRun.lag, acc);
162
160
  const after = await observeTerminalWorkspace(repository, path, expected);
163
161
  const afterWorkspace = after.workspace;
164
162
  const afterHooks = after.unsealed;
@@ -180,7 +178,8 @@ async function removeSealedTerminalWorktree({ repository, topology, path, state,
180
178
  const removal = await removeTerminalWorktree(repository, topology, path);
181
179
  if (removal.retained)
182
180
  return retainTerminalWorktree(path, { kind: "worktree-retained", path }, acc);
183
- acc.effects.push(removal.effect);
181
+ if (removal.effect !== undefined)
182
+ acc.effects.push(removal.effect);
184
183
  return null;
185
184
  }
186
185
  async function targetCustodyForClaimedIntegration(repository, state, integration) {
@@ -244,23 +243,27 @@ async function releaseTerminalCustody({ repository, state, resolveSeal, ref, pin
244
243
  }
245
244
  }
246
245
  }
247
- export async function reconcileTerminalManagedWorktree({ repository, channel, hooks, retryHooks, retainTerminalWorktree, place }, state, topology, acc, { ref, pin }) {
246
+ export async function reconcileTerminalManagedWorktree({ repository, channel, hooks, retainTerminalWorktree, place }, state, topology, acc, { ref, pin }) {
248
247
  const primary = fromPrimaryWorktree(repository);
249
248
  const path = place === undefined ? undefined : worktreePath(repository, place);
250
249
  const resolveSeal = async () => await terminalSealExpectations(channel, state);
251
250
  if (path === undefined) {
252
251
  if (retainTerminalWorktree === true)
253
- return complete(acc.effects, acc.lag);
252
+ return complete(acc.effects, acc.lag, acc.hookRuns);
254
253
  await releaseTerminalCustody({ repository: primary, state, resolveSeal, ref, pin, acc });
255
- return complete(acc.effects, acc.lag);
254
+ return complete(acc.effects, acc.lag, acc.hookRuns);
256
255
  }
257
256
  const expected = await resolveSeal();
258
257
  acc.effects.push(await updateRef(primary, ref, state.delivery?.data.tenderSnapshot ?? state.coordinates.start));
259
258
  if (state.delivery !== null) {
260
259
  acc.effects.push(await updateRef(primary, pin, state.currentIntegration?.snapshot ?? state.delivery.data.integration.snapshot));
261
260
  }
262
- if (retainTerminalWorktree === true)
261
+ if (retainTerminalWorktree === true) {
262
+ if (topology.paths.has(path) && (await pathExists(path))) {
263
+ acc.effects.push({ kind: "worktree", path, action: "unchanged" });
264
+ }
263
265
  return complete(acc.effects, acc.lag);
266
+ }
264
267
  const retained = await removeSealedTerminalWorktree({
265
268
  repository: primary,
266
269
  topology,
@@ -268,11 +271,10 @@ export async function reconcileTerminalManagedWorktree({ repository, channel, ho
268
271
  state,
269
272
  expected,
270
273
  hooks,
271
- retryHooks,
272
274
  acc,
273
275
  });
274
276
  if (retained !== null)
275
277
  return retained;
276
278
  await releaseTerminalCustody({ repository: primary, state, resolveSeal: async () => expected, ref, pin, acc });
277
- return complete(acc.effects, acc.lag);
279
+ return complete(acc.effects, acc.lag, acc.hookRuns);
278
280
  }
@@ -26,8 +26,22 @@ export type ManagedWorktreeFollow = Readonly<{
26
26
  head: SnapshotId;
27
27
  reason: "head-moved" | "head-attached" | "operation-in-progress" | "unsupported-parent-shape";
28
28
  }>;
29
+ export type DependentWorktreeFollow = Readonly<{
30
+ kind: "followed";
31
+ before: SnapshotId;
32
+ after: SnapshotId;
33
+ }> | Readonly<{
34
+ kind: "unchanged";
35
+ }> | Readonly<{
36
+ kind: "retained";
37
+ head: SnapshotId;
38
+ reason: "head-moved" | "head-attached" | "operation-in-progress";
39
+ paths: readonly string[];
40
+ }>;
29
41
  /** Follow an accepted tender only through the native index-and-HEAD transition. */
30
42
  export declare function followManagedWorktree(repository: GitRepository, workspace: string, tender: SnapshotId): Promise<ManagedWorktreeFollow>;
43
+ /** Follow a dependency baseline only through a clean, detached fast-forward. */
44
+ export declare function followDependentManagedWorktree(repository: GitRepository, workspace: string, target: SnapshotId): Promise<DependentWorktreeFollow>;
31
45
  export declare function withPrivateGitIndex<Value>(action: (environment: Readonly<{
32
46
  GIT_INDEX_FILE: string;
33
47
  }>) => Value | PromiseLike<Value>): Promise<Value>;
@@ -70,6 +70,50 @@ export async function followManagedWorktree(repository, workspace, tender) {
70
70
  await runGit(repository, ["-C", workspace, "reset", "--mixed", gitObjectId(tender)]);
71
71
  return { kind: "followed", before: head, after: tender };
72
72
  }
73
+ /** Follow a dependency baseline only through a clean, detached fast-forward. */
74
+ export async function followDependentManagedWorktree(repository, workspace, target) {
75
+ const head = await workspaceRevision(repository, workspace, "HEAD");
76
+ if (head === null)
77
+ throw new Error("managed worktree HEAD is missing");
78
+ const status = await workspaceStatus(repository, workspace);
79
+ const gitDirectory = await worktreeGitDirectory(repository, workspace);
80
+ const operation = await workspaceOperationState(repository, workspace, gitDirectory);
81
+ const mergeHead = await workspaceRevision(repository, workspace, "MERGE_HEAD");
82
+ const paths = [
83
+ ...new Set([
84
+ ...status.staged,
85
+ ...status.unstaged,
86
+ ...status.untracked,
87
+ ...status.submodules,
88
+ ...status.unmergedPaths,
89
+ ]),
90
+ ].sort();
91
+ const attached = await runGit(repository, ["-C", workspace, "symbolic-ref", "--quiet", "HEAD"]).then(() => true, (error) => {
92
+ if (error instanceof GitPlumbingError && error.status === 1)
93
+ return false;
94
+ throw error;
95
+ });
96
+ if (attached)
97
+ return { kind: "retained", head, reason: "head-attached", paths };
98
+ if (mergeHead !== null || operation.other || operation.unmerged || paths.length > 0) {
99
+ return { kind: "retained", head, reason: "operation-in-progress", paths };
100
+ }
101
+ if (head === target)
102
+ return { kind: "unchanged" };
103
+ let ancestor = false;
104
+ try {
105
+ await runGit(repository, ["merge-base", "--is-ancestor", gitObjectId(head), gitObjectId(target)]);
106
+ ancestor = true;
107
+ }
108
+ catch (error) {
109
+ if (!(error instanceof GitPlumbingError) || error.status !== 1)
110
+ throw error;
111
+ }
112
+ if (!ancestor)
113
+ return { kind: "retained", head, reason: "head-moved", paths };
114
+ await runGit(repository, ["-C", workspace, "checkout", "--quiet", "--detach", gitObjectId(target)]);
115
+ return { kind: "followed", before: head, after: target };
116
+ }
73
117
  export async function withPrivateGitIndex(action) {
74
118
  const directory = await mkdtemp(join(tmpdir(), "keiyaku-v4-index-"));
75
119
  try {
@@ -1,5 +1,5 @@
1
1
  export { kanshi, observeKanshi } from "./read.js";
2
2
  export { selectKanshi, selectRegion } from "./select.js";
3
3
  export type { KanshiInput } from "./read.js";
4
- export type { AkumaKanshiRow, AkumaKanshiWorld, ContractEndpointObservation, ContractHolderObservation, ContractKanshiBoard, ContractKanshiRow, CurrentPhysicalIssue, KanshiReport, Section, TaskKanshiRow, TaskKanshiWorld, KanshiRegionSelection, RegionDeclaration, RegionOverlap, RegionRead, } from "./report.js";
4
+ export type { AkumaKanshiRow, AkumaKanshiWorld, ContractEndpointObservation, ContractHolderObservation, ContractKanshiBoard, ContractKanshiRow, KanshiReport, Section, TaskKanshiRow, TaskKanshiWorld, KanshiRegionSelection, RegionDeclaration, RegionOverlap, RegionRead, } from "./report.js";
5
5
  export type { KanshiSelection } from "./select.js";
@@ -122,22 +122,6 @@ async function readContracts(observation, include) {
122
122
  return { kind: "failed", failure: { message: diagnostic(error) } };
123
123
  }
124
124
  }
125
- async function attachSelectedIssue(observation, contracts, selected) {
126
- if (contracts.kind !== "present")
127
- return contracts;
128
- try {
129
- const rows = await Promise.all(contracts.value.rows.map(async (row) => {
130
- if (row.id !== selected)
131
- return row;
132
- const issue = await observeCurrentPhysicalIssue(observation.repository, row);
133
- return issue === undefined ? row : { ...row, issue };
134
- }));
135
- return { kind: "present", value: { ...contracts.value, rows } };
136
- }
137
- catch (error) {
138
- return { kind: "failed", failure: { message: diagnostic(error) } };
139
- }
140
- }
141
125
  async function readHolders(observation) {
142
126
  try {
143
127
  return { kind: "present", value: await readTaskHolderProjectionAt(observation) };
@@ -393,3 +377,19 @@ export async function observeKanshi(input) {
393
377
  export async function kanshi(input) {
394
378
  return (await observeKanshi(input)).report;
395
379
  }
380
+ async function attachSelectedIssue(observation, contracts, selected) {
381
+ if (contracts.kind !== "present")
382
+ return contracts;
383
+ try {
384
+ const rows = await Promise.all(contracts.value.rows.map(async (row) => {
385
+ if (row.id !== selected)
386
+ return row;
387
+ const issue = await observeCurrentPhysicalIssue(observation.repository, row);
388
+ return issue === undefined ? row : { ...row, issue };
389
+ }));
390
+ return { kind: "present", value: { ...contracts.value, rows } };
391
+ }
392
+ catch (error) {
393
+ return { kind: "failed", failure: { message: diagnostic(error) } };
394
+ }
395
+ }
@@ -1,11 +1,11 @@
1
1
  import type { ContractBoard, ContractDisposition, ContractPhase } from "../library/contract.js";
2
- import type { CurrentPhysicalIssue } from "../protocol/read/observation.js";
3
2
  import type { TaskId, TaskRef, TaskRow } from "../task/index.js";
4
3
  import type { AkumaList, AkumaListRow, UnbornAkumaListRow, ActivitySnapshot } from "../akuma/index.js";
5
4
  import type { AkumaAlias } from "../identity/selector.js";
6
5
  import type { WorldRoot } from "../world.js";
7
6
  import type { ContractId } from "../library/contract.js";
8
7
  import type { RegionOverlap } from "../library/region.js";
8
+ import type { CurrentPhysicalIssue } from "../protocol/read/observation.js";
9
9
  export type { RegionOverlap };
10
10
  export type Section<Value> = Readonly<{
11
11
  kind: "present";
@@ -31,7 +31,6 @@ export type ContractFleetAttachment = Readonly<{
31
31
  id: string;
32
32
  aliases: readonly AkumaAlias[];
33
33
  }>;
34
- export type { CurrentPhysicalIssue };
35
34
  export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
36
35
  phase: ContractPhase;
37
36
  holder: ContractHolderObservation;
@@ -98,3 +97,4 @@ export type KanshiReport = Readonly<{
98
97
  akuma: Section<AkumaKanshiWorld>;
99
98
  region?: Section<RegionRead>;
100
99
  }>;
100
+ export type { CurrentPhysicalIssue };
@@ -2,7 +2,7 @@ import { type AliasBinding } from "../alias/index.js";
2
2
  import { type AkuId } from "../akuma/identity.js";
3
3
  import { contractId } from "../core/facts/types.js";
4
4
  import { type AkumaAlias, type AkumaGlob } from "../identity/selector.js";
5
- import type { WorldRoot } from "../world.js";
5
+ import { type WorldRoot } from "../world.js";
6
6
  import type { KanshiReport, Section } from "../kanshi/index.js";
7
7
  import { type Repo } from "./repo.js";
8
8
  export type DirectAkumaSelector = AkuId | AkumaAlias;
@@ -17,6 +17,11 @@ export type AkumaSetAddressInput = Readonly<{
17
17
  akuma: readonly string[];
18
18
  repo?: Repo;
19
19
  }>;
20
+ type UncheckedAkumaAddressInput = Readonly<{
21
+ path: unknown;
22
+ akuma: unknown;
23
+ repo?: unknown;
24
+ }>;
20
25
  export type AkumaWorldScopeRefusal = Readonly<{
21
26
  kind: "akuma-not-in-world";
22
27
  ids: readonly AkuId[];
@@ -39,11 +44,12 @@ export type NamedAddressInput = Readonly<{
39
44
  aliases: Section<readonly AliasBinding[]>;
40
45
  }>;
41
46
  export declare function resolveNamedAddress(input: NamedAddressInput): NamedAddress;
42
- export declare function addressAkuma(input: AkumaAddressInput): Promise<Readonly<{
47
+ export declare function addressAkuma(input: UncheckedAkumaAddressInput): Promise<Readonly<{
43
48
  path: WorldRoot;
44
49
  id: AkuId;
45
50
  }>>;
46
- export declare function addressAkumaSet(input: AkumaSetAddressInput): Promise<Readonly<{
51
+ export declare function addressAkumaSet(input: UncheckedAkumaAddressInput): Promise<Readonly<{
47
52
  path: WorldRoot;
48
53
  ids: readonly AkuId[];
49
54
  }>>;
55
+ export {};