@astrosheep/keiyaku 4.6.8 → 4.6.9

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 (253) hide show
  1. package/README.md +40 -14
  2. package/build/plugins/claude/.claude-plugin/plugin.json +1 -1
  3. package/build/plugins/claude/skills/keiyaku/SKILL.md +5 -6
  4. package/build/plugins/claude/skills/keiyaku-akuma/SKILL.md +1 -1
  5. package/build/plugins/claude/skills/keiyaku-akuma/references/automation.md +8 -8
  6. package/build/plugins/claude/skills/keiyaku-babysit/SKILL.md +1 -1
  7. package/build/plugins/claude/skills/keiyaku-bind/SKILL.md +9 -9
  8. package/build/plugins/claude/skills/keiyaku-debt/SKILL.md +91 -0
  9. package/build/plugins/claude/skills/keiyaku-workflow/SKILL.md +2 -2
  10. package/build/plugins/codex/.codex-plugin/plugin.json +1 -1
  11. package/build/plugins/codex/skills/keiyaku/SKILL.md +5 -6
  12. package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +1 -1
  13. package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +8 -8
  14. package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +1 -1
  15. package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +9 -9
  16. package/build/plugins/codex/skills/keiyaku-debt/SKILL.md +91 -0
  17. package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +2 -2
  18. package/build/plugins/opencode/index.js +1 -1
  19. package/build/plugins/opencode/skills/keiyaku/SKILL.md +5 -6
  20. package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +1 -1
  21. package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +8 -8
  22. package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +1 -1
  23. package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +9 -9
  24. package/build/plugins/opencode/skills/keiyaku-debt/SKILL.md +91 -0
  25. package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +2 -2
  26. package/build/skills/keiyaku/SKILL.md +5 -6
  27. package/build/skills/keiyaku-akuma/SKILL.md +1 -1
  28. package/build/skills/keiyaku-akuma/references/automation.md +8 -8
  29. package/build/skills/keiyaku-babysit/SKILL.md +1 -1
  30. package/build/skills/keiyaku-bind/SKILL.md +9 -9
  31. package/build/skills/keiyaku-debt/SKILL.md +91 -0
  32. package/build/skills/keiyaku-workflow/SKILL.md +2 -2
  33. package/build/src/akuma/akuma-instance.d.ts +2 -0
  34. package/build/src/akuma/akuma-instance.js +10 -0
  35. package/build/src/akuma/akuma-observe.d.ts +33 -8
  36. package/build/src/akuma/akuma-observe.js +88 -64
  37. package/build/src/akuma/akuma-owner.d.ts +11 -2
  38. package/build/src/akuma/akuma-owner.js +45 -35
  39. package/build/src/akuma/akuma-selection-execution.js +9 -1
  40. package/build/src/akuma/akuma-stream.d.ts +22 -0
  41. package/build/src/akuma/akuma-stream.js +116 -0
  42. package/build/src/akuma/akuma-wait.d.ts +1 -40
  43. package/build/src/akuma/akuma-wait.js +23 -84
  44. package/build/src/akuma/akuma.d.ts +17 -11
  45. package/build/src/akuma/akuma.js +2 -0
  46. package/build/src/akuma/allowed.d.ts +7 -12
  47. package/build/src/akuma/allowed.js +13 -4
  48. package/build/src/akuma/body-supervisor.d.ts +5 -5
  49. package/build/src/akuma/body-supervisor.js +22 -20
  50. package/build/src/akuma/body.js +28 -1
  51. package/build/src/akuma/call-request.d.ts +12 -22
  52. package/build/src/akuma/heart/activity-schema.d.ts +12 -0
  53. package/build/src/akuma/heart/activity-schema.js +6 -0
  54. package/build/src/akuma/heart/index.d.ts +59 -2
  55. package/build/src/akuma/heart/index.js +87 -8
  56. package/build/src/akuma/heart/rows.js +5 -3
  57. package/build/src/akuma/heart/soul.d.ts +9 -0
  58. package/build/src/akuma/heart/soul.js +29 -0
  59. package/build/src/akuma/heart/storage.d.ts +15 -0
  60. package/build/src/akuma/heart/storage.js +55 -0
  61. package/build/src/akuma/heart/timeline.d.ts +7 -0
  62. package/build/src/akuma/heart/timeline.js +10 -0
  63. package/build/src/akuma/index.d.ts +1 -0
  64. package/build/src/akuma/projection.d.ts +25 -0
  65. package/build/src/akuma/projection.js +24 -7
  66. package/build/src/akuma/provider-recipe.d.ts +11 -0
  67. package/build/src/akuma/provider-recipe.js +23 -0
  68. package/build/src/akuma/provider.d.ts +25 -0
  69. package/build/src/akuma/provider.js +99 -7
  70. package/build/src/akuma/providers/acp/events.js +25 -2
  71. package/build/src/akuma/providers/claude/events.js +76 -10
  72. package/build/src/akuma/providers/claude/index.js +2 -5
  73. package/build/src/akuma/providers/codex-app-server/events.js +17 -2
  74. package/build/src/akuma/providers/codex-app-server/index.js +15 -9
  75. package/build/src/akuma/providers/decode.d.ts +8 -0
  76. package/build/src/akuma/providers/decode.js +21 -0
  77. package/build/src/akuma/providers/grok-build/index.js +10 -26
  78. package/build/src/akuma/providers/opencode-sdk/event-stream.d.ts +3 -3
  79. package/build/src/akuma/providers/opencode-sdk/event-stream.js +2 -25
  80. package/build/src/akuma/providers/opencode-sdk/events.d.ts +7 -43
  81. package/build/src/akuma/providers/opencode-sdk/events.js +147 -284
  82. package/build/src/akuma/providers/opencode-sdk/index.js +267 -421
  83. package/build/src/akuma/providers/opencode-sdk/native-http.d.ts +9 -0
  84. package/build/src/akuma/providers/opencode-sdk/native-http.js +69 -0
  85. package/build/src/akuma/providers/opencode-sdk/session.d.ts +42 -36
  86. package/build/src/akuma/providers/opencode-sdk/session.js +75 -82
  87. package/build/src/akuma/providers/paseo/events.d.ts +8 -0
  88. package/build/src/akuma/providers/paseo/events.js +58 -11
  89. package/build/src/akuma/providers/paseo/index.js +11 -7
  90. package/build/src/akuma/providers/pi/events.d.ts +2 -0
  91. package/build/src/akuma/providers/pi/events.js +32 -24
  92. package/build/src/akuma/providers/pi/index.js +21 -35
  93. package/build/src/akuma/request-lifecycle.d.ts +1 -2
  94. package/build/src/akuma/request-lifecycle.js +2 -8
  95. package/build/src/akuma/request-rendezvous.js +38 -55
  96. package/build/src/akuma/request-serve.d.ts +1 -1
  97. package/build/src/akuma/request-serve.js +77 -113
  98. package/build/src/akuma/selection-observation.d.ts +57 -51
  99. package/build/src/akuma/selection-observation.js +3 -3
  100. package/build/src/akuma/turn-drive.d.ts +3 -0
  101. package/build/src/akuma/turn-drive.js +26 -5
  102. package/build/src/akuma-body.js +12 -22
  103. package/build/src/cli/akuma-caller.js +10 -0
  104. package/build/src/cli/commands/akuma-grammar.js +3 -4
  105. package/build/src/cli/commands/akuma.js +13 -51
  106. package/build/src/cli/commands/contract-grammar.d.ts +7 -6
  107. package/build/src/cli/commands/contract-grammar.js +27 -32
  108. package/build/src/cli/commands/contract-help.d.ts +16 -7
  109. package/build/src/cli/commands/contract-help.js +20 -11
  110. package/build/src/cli/commands/contract.js +11 -11
  111. package/build/src/cli/commands/debt-grammar.d.ts +19 -0
  112. package/build/src/cli/commands/debt-grammar.js +323 -0
  113. package/build/src/cli/commands/debt-query.d.ts +5 -0
  114. package/build/src/cli/commands/{task-query.js → debt-query.js} +9 -9
  115. package/build/src/cli/commands/{task.d.ts → debt.d.ts} +2 -2
  116. package/build/src/cli/commands/{task.js → debt.js} +83 -143
  117. package/build/src/cli/coordinates.d.ts +1 -1
  118. package/build/src/cli/coordinates.js +1 -1
  119. package/build/src/cli/parse.d.ts +4 -4
  120. package/build/src/cli/parse.js +17 -16
  121. package/build/src/cli/render/akuma-activity.d.ts +11 -83
  122. package/build/src/cli/render/akuma-activity.js +20 -382
  123. package/build/src/cli/render/catalog.d.ts +2 -2
  124. package/build/src/cli/render/catalog.js +5 -5
  125. package/build/src/cli/render/contract.js +2 -2
  126. package/build/src/cli/render/debt.d.ts +28 -0
  127. package/build/src/cli/render/{task.js → debt.js} +51 -112
  128. package/build/src/cli/render/kanshi.js +28 -28
  129. package/build/src/cli/render/marks.d.ts +5 -5
  130. package/build/src/cli/render/marks.js +4 -10
  131. package/build/src/cli/render/nuke.js +1 -1
  132. package/build/src/cli/runtime.js +3 -3
  133. package/build/src/cli/scan.d.ts +1 -1
  134. package/build/src/cli/usage.d.ts +1 -1
  135. package/build/src/cli/usage.js +4 -4
  136. package/build/src/contract-worktree.js +3 -3
  137. package/build/src/debt/board.d.ts +160 -0
  138. package/build/src/{task → debt}/board.js +89 -89
  139. package/build/src/debt/catalog.d.ts +11 -0
  140. package/build/src/debt/catalog.js +59 -0
  141. package/build/src/{task → debt}/context.d.ts +1 -1
  142. package/build/src/{task → debt}/context.js +1 -1
  143. package/build/src/{task → debt}/created-observation.d.ts +6 -10
  144. package/build/src/{task → debt}/created-observation.js +7 -7
  145. package/build/src/debt/document.d.ts +37 -0
  146. package/build/src/{task → debt}/document.js +37 -37
  147. package/build/src/debt/identity.d.ts +21 -0
  148. package/build/src/{task → debt}/identity.js +35 -35
  149. package/build/src/debt/index.d.ts +111 -0
  150. package/build/src/debt/index.js +203 -0
  151. package/build/src/{task → debt}/input.d.ts +8 -8
  152. package/build/src/{task → debt}/input.js +21 -21
  153. package/build/src/debt/lifecycle-operations.d.ts +6 -0
  154. package/build/src/{task → debt}/lifecycle-operations.js +27 -31
  155. package/build/src/debt/mutation-result.d.ts +981 -0
  156. package/build/src/debt/mutation-result.js +109 -0
  157. package/build/src/debt/mutation.d.ts +424 -0
  158. package/build/src/debt/mutation.js +223 -0
  159. package/build/src/debt/operation-types.d.ts +71 -0
  160. package/build/src/debt/operations.d.ts +28 -0
  161. package/build/src/{task → debt}/operations.js +59 -60
  162. package/build/src/debt/query.d.ts +76 -0
  163. package/build/src/{task → debt}/query.js +55 -55
  164. package/build/src/{task → debt}/store.d.ts +13 -13
  165. package/build/src/{task → debt}/store.js +58 -49
  166. package/build/src/debt/view.d.ts +4 -0
  167. package/build/src/debt/view.js +7 -0
  168. package/build/src/identity/coordinates.d.ts +1 -1
  169. package/build/src/index.d.ts +13 -13
  170. package/build/src/index.js +9 -9
  171. package/build/src/kanshi/index.d.ts +1 -1
  172. package/build/src/kanshi/read.js +33 -33
  173. package/build/src/kanshi/report.d.ts +7 -7
  174. package/build/src/kanshi/select.js +4 -4
  175. package/build/src/library/akumas.d.ts +2 -3
  176. package/build/src/library/bind.d.ts +3 -3
  177. package/build/src/library/bind.js +5 -5
  178. package/build/src/library/contract-creation.js +5 -5
  179. package/build/src/library/contract-execution.js +4 -4
  180. package/build/src/library/contract-types.d.ts +2 -2
  181. package/build/src/library/input.d.ts +2 -2
  182. package/build/src/library/input.js +5 -5
  183. package/build/src/library/invocation.js +2 -2
  184. package/build/src/library/nuke.js +3 -3
  185. package/build/src/library/outcome.d.ts +126 -126
  186. package/build/src/library/outcome.js +3 -3
  187. package/build/src/library/selection.d.ts +1 -4
  188. package/build/src/library/selection.js +11 -62
  189. package/build/src/plugin/public.d.ts +5 -0
  190. package/build/src/plugin/runtime.js +3 -1
  191. package/build/src/runtime/proc/windows-launch.exe +0 -0
  192. package/build/src/settlement/fence.d.ts +3 -3
  193. package/build/src/settlement/fence.js +4 -4
  194. package/build/src/settlement/holder.d.ts +16 -16
  195. package/build/src/settlement/holder.js +69 -63
  196. package/build/src/settlement/settle.d.ts +5 -5
  197. package/build/src/settlement/settle.js +53 -53
  198. package/package.json +12 -6
  199. package/plugins/paseo/plugin/index.server.ts +17 -0
  200. package/plugins/paseo/plugin/paseo-plugin.json +4 -0
  201. package/plugins/paseo/plugin/server/attach.ts +52 -0
  202. package/plugins/paseo/plugin/server/keiyaku.ts +44 -0
  203. package/plugins/paseo/plugin/server/message.ts +60 -0
  204. package/plugins/paseo/plugin/server/mirror.ts +193 -0
  205. package/plugins/paseo/plugin/server/model.ts +14 -0
  206. package/plugins/paseo/plugin/server/provider.ts +276 -0
  207. package/plugins/paseo/plugin/server/sdk-worker.ts +237 -0
  208. package/plugins/paseo/plugin/server/sdk.ts +289 -0
  209. package/plugins/paseo/plugin/server/stop.ts +26 -0
  210. package/plugins/paseo/plugin/server/transport.ts +35 -0
  211. package/plugins/paseo/plugin/shared/attach-rpc.ts +10 -0
  212. package/plugins/paseo/plugin/shared/refresh-rpc.ts +6 -0
  213. package/plugins/paseo/plugin/tsconfig.json +6 -0
  214. package/skills/keiyaku/SKILL.md +5 -6
  215. package/skills/keiyaku-akuma/SKILL.md +1 -1
  216. package/skills/keiyaku-akuma/references/automation.md +8 -8
  217. package/skills/keiyaku-babysit/SKILL.md +1 -1
  218. package/skills/keiyaku-bind/SKILL.md +9 -9
  219. package/skills/keiyaku-debt/SKILL.md +91 -0
  220. package/skills/keiyaku-workflow/SKILL.md +2 -2
  221. package/build/plugins/claude/skills/keiyaku-task/SKILL.md +0 -104
  222. package/build/plugins/codex/skills/keiyaku-task/SKILL.md +0 -104
  223. package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +0 -104
  224. package/build/skills/keiyaku-task/SKILL.md +0 -104
  225. package/build/src/cli/commands/task-grammar.d.ts +0 -19
  226. package/build/src/cli/commands/task-grammar.js +0 -384
  227. package/build/src/cli/commands/task-query.d.ts +0 -5
  228. package/build/src/cli/render/task.d.ts +0 -39
  229. package/build/src/task/board.d.ts +0 -168
  230. package/build/src/task/catalog.d.ts +0 -11
  231. package/build/src/task/catalog.js +0 -59
  232. package/build/src/task/compose-language.d.ts +0 -57
  233. package/build/src/task/compose-language.js +0 -364
  234. package/build/src/task/compose-parser.d.ts +0 -32
  235. package/build/src/task/compose-parser.js +0 -180
  236. package/build/src/task/compose.d.ts +0 -16
  237. package/build/src/task/compose.js +0 -189
  238. package/build/src/task/document.d.ts +0 -39
  239. package/build/src/task/identity.d.ts +0 -21
  240. package/build/src/task/index.d.ts +0 -138
  241. package/build/src/task/index.js +0 -269
  242. package/build/src/task/lifecycle-operations.d.ts +0 -6
  243. package/build/src/task/mutation-result.d.ts +0 -1726
  244. package/build/src/task/mutation-result.js +0 -198
  245. package/build/src/task/mutation.d.ts +0 -590
  246. package/build/src/task/mutation.js +0 -262
  247. package/build/src/task/operation-types.d.ts +0 -71
  248. package/build/src/task/operations.d.ts +0 -28
  249. package/build/src/task/query.d.ts +0 -76
  250. package/build/src/task/view.d.ts +0 -4
  251. package/build/src/task/view.js +0 -7
  252. package/skills/keiyaku-task/SKILL.md +0 -104
  253. /package/build/src/{task → debt}/operation-types.js +0 -0
@@ -22,7 +22,7 @@ import { regionOverlapSchema } from "./region.js";
22
22
  // One invocation-wide tagged Effect carrier
23
23
  // ---------------------------------------------------------------------------
24
24
  const reconciliationEffectSchema = z.union([reconcileEffectSchema, contractFileEffectSchema]);
25
- const resetOwnerSchema = z.enum(["akuma", "git", "task", "world"]);
25
+ const resetOwnerSchema = z.enum(["akuma", "git", "debt", "world"]);
26
26
  const resetEffectFields = { world: z.string().min(1), owner: resetOwnerSchema, diagnostic: z.string().min(1) };
27
27
  const resetEffectSchema = z.union([
28
28
  z.object({ kind: z.literal("reset-owner-stopped"), ...resetEffectFields }).strict(),
@@ -158,7 +158,7 @@ export function project(operation, snapshot, projection) {
158
158
  if (operation !== "nuke")
159
159
  throw new Error("reset projection requires nuke");
160
160
  const effects = snapshot.effects.filter((effect) => effect.kind === "reset-owner-stopped" || effect.kind === "reset-residue");
161
- const value = { removed: snapshot.reset?.removed ?? { refs: 0, worktrees: 0, tasks: 0 } };
161
+ const value = { removed: snapshot.reset?.removed ?? { refs: 0, worktrees: 0, debts: 0 } };
162
162
  const base = { operation, world: projection.world, effects, pending: projectPending(operation, value, effects) };
163
163
  if (projection.kind === "failed")
164
164
  return {
@@ -404,7 +404,7 @@ const resetCountsSchema = z
404
404
  .object({
405
405
  refs: z.number().int().nonnegative(),
406
406
  worktrees: z.number().int().nonnegative(),
407
- tasks: z.number().int().nonnegative(),
407
+ debts: z.number().int().nonnegative(),
408
408
  })
409
409
  .strict();
410
410
  const resetValueSchema = z.object({ removed: resetCountsSchema }).strict();
@@ -1,5 +1,4 @@
1
1
  import { type AskObserver } from "../akuma/akuma-selection-execution.js";
2
- import { type WaitObserver } from "../akuma/akuma-wait.js";
3
2
  import { type AkumaStatus } from "../akuma/akuma.js";
4
3
  import { type ActivityHistory, type OutcomeRow } from "../akuma/projection.js";
5
4
  import { type ExecutionContext } from "../akuma/requests.js";
@@ -28,7 +27,7 @@ type SelectionWaitMode = Readonly<{
28
27
  export type SelectionSeam = Readonly<{
29
28
  addressOne(input: UncheckedSelectionAddress): Promise<AddressedAkuma>;
30
29
  addressSet(input: UncheckedSelectionAddress): Promise<AddressedAkumaSet>;
31
- wait(addressed: AddressedAkumaSet, mode: SelectionWaitMode, observer?: WaitObserver): Promise<AkumaWaitResult>;
30
+ wait(addressed: AddressedAkumaSet, mode: SelectionWaitMode): Promise<AkumaWaitResult>;
32
31
  kill(addressed: AddressedAkumaSet, signal?: AbortSignal): Promise<AkumaKillResult>;
33
32
  tell(addressed: AddressedAkuma, input: AkumaTellInput, signal?: AbortSignal): Promise<AkumaTellResult>;
34
33
  ask<T>(addressed: AddressedAkuma, input: AkumaAskInput<T>, signal?: AbortSignal): Promise<AkumaAskResult<T>>;
@@ -38,8 +37,6 @@ export type AkumaWaitInput = AkumaSetAddressInput & Readonly<{
38
37
  completion?: "any" | "all";
39
38
  timeoutMs?: number;
40
39
  signal?: AbortSignal;
41
- /** The existing optional live-observation seam, validated here like Ask's. */
42
- observe?: WaitObserver;
43
40
  }>;
44
41
  export type AkumaTellInput = AkumaAddressInput & Readonly<{
45
42
  body: string;
@@ -3,16 +3,15 @@ import { withoutReportedChanges } from "../akuma/projection.js";
3
3
  import { AkumaNotBornError, AkumaObservationError } from "../akuma/akuma-errors.js";
4
4
  import { AkumaOwner } from "../akuma/akuma-owner.js";
5
5
  import { decodeAskObservation, executeAskAkuma, executeKillAkuma, executeTellAkuma, } from "../akuma/akuma-selection-execution.js";
6
- import { executeWaitAkuma, } from "../akuma/akuma-wait.js";
6
+ import { executeWaitAkuma } from "../akuma/akuma-wait.js";
7
7
  import { parsePublicHistoryId } from "../akuma/identity.js";
8
8
  import { executionChannel } from "../akuma/requests.js";
9
9
  import { schemaJsonText } from "../akuma/schema.js";
10
10
  import { requestForwardedSelectionAsk, requestForwardedSelectionKill, requestForwardedSelectionTell, requestForwardedSelectionWait, } from "../akuma/selection-request.js";
11
- import { readAliases } from "../alias/index.js";
12
11
  import { observeDispatchAssociations } from "../dispatch/index.js";
13
12
  import { observeContractAt } from "../git/observe.js";
14
13
  import { withGitDecodeChannel } from "../git/read-observation.js";
15
- import { observeCreatedTaskObservations } from "../task/created-observation.js";
14
+ import { observeCreatedDebtObservations } from "../debt/created-observation.js";
16
15
  import { outcomePluginObserver, stderrPluginDiagnostic } from "../plugin/akuma-signals.js";
17
16
  import { addressAkuma, addressAkumaSet, resolveAkuma, resolveAkumaSet, } from "./address.js";
18
17
  import { requireInput } from "./input.js";
@@ -60,7 +59,7 @@ function localSelection(reportDiagnostic) {
60
59
  return {
61
60
  addressOne: addressAkuma,
62
61
  addressSet: addressAkumaSet,
63
- wait: async (addressed, mode, observer) => await localWait(addressed, { ...mode, ...(observer === undefined ? {} : { observer }) }, reportDiagnostic),
62
+ wait: async (addressed, mode) => await localWait(addressed, mode, reportDiagnostic),
64
63
  kill: async (addressed, abort) => await executeKillAkuma({
65
64
  path: addressed.path,
66
65
  ids: addressed.orderedIds,
@@ -136,43 +135,19 @@ function placementDischarged(repo) {
136
135
  async function composeObservation(status, contract, discharged) {
137
136
  return (await discharged(contract)) ? { ...status, timeline: withoutReportedChanges(status.timeline) } : status;
138
137
  }
139
- async function createdTasksFor(path, statuses) {
140
- return await observeCreatedTaskObservations(path, statuses.map((status) => status.id));
141
- }
142
- /**
143
- * One wait's identity-fact resolver: the alias bound to an Akuma in its world and
144
- * its Dispatch association. The alias index is read once, on the first observed
145
- * Akuma, and each Akuma's alias is the first binding the canonical order offers.
146
- * Alias bindings and selected Dispatch associations are read once for this live
147
- * stage. Final result composition owns a separate, fresh Dispatch observation.
148
- */
149
- function waitIdentityFacts(path, repo, selected) {
150
- let aliases;
151
- let contracts;
152
- return async (id) => {
153
- if (aliases === undefined) {
154
- const bound = new Map();
155
- for (const binding of await readAliases(path)) {
156
- if (!bound.has(binding.akuId))
157
- bound.set(binding.akuId, binding.alias);
158
- }
159
- aliases = bound;
160
- }
161
- contracts ??= await dispatchAssociations(repo, selected);
162
- const alias = aliases.get(id);
163
- return { ...(alias === undefined ? {} : { alias }), contract: contracts.get(id) };
164
- };
138
+ async function createdDebtsFor(path, statuses) {
139
+ return await observeCreatedDebtObservations(path, statuses.map((status) => status.id));
165
140
  }
166
141
  async function observeAkuma(status, path, repo) {
167
142
  return (await composeAkumaAssociations([status], path, repo))[0];
168
143
  }
169
144
  /**
170
145
  * The one upper composition of association-free native status evidence into its
171
- * public observation shape. It reads Alias-independent Dispatch and Task
146
+ * public observation shape. It reads Alias-independent Dispatch and Debt
172
147
  * associations after the lower values, never before or inside them.
173
148
  */
174
149
  async function composeAkumaAssociations(statuses, path, repo) {
175
- const created = await createdTasksFor(path, statuses);
150
+ const created = await createdDebtsFor(path, statuses);
176
151
  const discharged = placementDischarged(repo);
177
152
  const contracts = await dispatchAssociations(repo, statuses.map((status) => status.id));
178
153
  return await Promise.all(statuses.map(async (status, index) => {
@@ -180,7 +155,7 @@ async function composeAkumaAssociations(statuses, path, repo) {
180
155
  return {
181
156
  status: await composeObservation(status, contract, discharged),
182
157
  contract,
183
- createdTasks: created[index],
158
+ createdDebts: created[index],
184
159
  };
185
160
  }));
186
161
  }
@@ -214,7 +189,7 @@ async function composeWaitResult(path, repo, result) {
214
189
  }
215
190
  /**
216
191
  * Re-attach upper associations after a wait result crosses a forwarded
217
- * boundary; the serving side must observe its own Dispatch and Task state.
192
+ * boundary; the serving side must observe its own Dispatch and Debt state.
218
193
  */
219
194
  async function attachWaitAssociations(path, repo, result) {
220
195
  return await composeWaitResult(path, repo, {
@@ -273,10 +248,6 @@ async function localWait(addressed, input, reportDiagnostic) {
273
248
  outcomeObserved: outcomePluginObserver({ world: addressed.path, reportDiagnostic }),
274
249
  ...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
275
250
  ...(input.signal === undefined ? {} : { signal: input.signal }),
276
- identity: waitIdentityFacts(addressed.path, input.repo, addressed.orderedIds),
277
- selectionOrder: addressed.orderedIds,
278
- ...(input.observer?.selected === undefined ? {} : { onSelected: input.observer.selected }),
279
- ...(input.observer?.observe === undefined ? {} : { observe: input.observer.observe }),
280
251
  }));
281
252
  }
282
253
  catch (error) {
@@ -285,35 +256,13 @@ async function localWait(addressed, input, reportDiagnostic) {
285
256
  throw observationError(addressed.orderedIds[0], error);
286
257
  }
287
258
  }
288
- function waitObserver(value) {
289
- if (value === undefined)
290
- return undefined;
291
- if (typeof value !== "object" || value === null || Array.isArray(value))
292
- throw new TypeError("observe must be a WaitObserver");
293
- const record = value;
294
- for (const key of Object.keys(record)) {
295
- if (key !== "selected" && key !== "observe")
296
- throw new TypeError(`observe has unknown field: ${key}`);
297
- if (record[key] !== undefined && typeof record[key] !== "function")
298
- throw new TypeError(`observe.${key} must be a function`);
299
- }
300
- return {
301
- ...(record.selected === undefined
302
- ? {}
303
- : { selected: record.selected }),
304
- ...(record.observe === undefined
305
- ? {}
306
- : { observe: record.observe }),
307
- };
308
- }
309
259
  export async function waitAkumaOn(seam, input) {
310
260
  const values = requireInput(input, "Akumas.wait input");
311
261
  for (const key of Object.keys(values)) {
312
- if (!["path", "akuma", "repo", "completion", "timeoutMs", "signal", "observe"].includes(key)) {
262
+ if (!["path", "akuma", "repo", "completion", "timeoutMs", "signal"].includes(key)) {
313
263
  throw new TypeError(`Akumas.wait input has unknown field: ${key}`);
314
264
  }
315
265
  }
316
- const observer = waitObserver(values.observe);
317
266
  const selected = completionMode(values.completion);
318
267
  const timeoutMs = timeout(values.timeoutMs);
319
268
  const callerSignal = signal(values.signal);
@@ -324,7 +273,7 @@ export async function waitAkumaOn(seam, input) {
324
273
  ...(timeoutMs === undefined ? {} : { timeoutMs }),
325
274
  ...(callerSignal === undefined ? {} : { signal: callerSignal }),
326
275
  ...(repo === undefined ? {} : { repo }),
327
- }, observer);
276
+ });
328
277
  }
329
278
  export async function killAkumaOn(seam, input) {
330
279
  const values = requireInput(input, "Akumas.kill input");
@@ -54,6 +54,11 @@ export type PluginSignalMap = Readonly<{
54
54
  historyId: string;
55
55
  observer?: string;
56
56
  }>;
57
+ "akuma.turn-started": Readonly<{
58
+ akumaId: string;
59
+ turnSequence: number;
60
+ initiator?: string;
61
+ }>;
57
62
  "akuma.turn-outcome": Readonly<{
58
63
  akumaId: string;
59
64
  bodySequence: number;
@@ -7,6 +7,7 @@ const DIAGNOSTIC_LIMIT = 500;
7
7
  const PLUGIN_ATTEMPT_TIMEOUT_MS = 5_000;
8
8
  const PLUGIN_NAMESPACE = "plugins";
9
9
  const SQUARE_PLUGIN_PACKAGE = "@astrosheep/keiyaku-plugin-square";
10
+ const BUNDLED_PLUGIN_PACKAGES = new Set([SQUARE_PLUGIN_PACKAGE, "@astrosheep/keiyaku-plugin-paseo"]);
10
11
  const BUILTIN_PLUGINS = Object.freeze([
11
12
  Object.freeze({ id: "square", package: SQUARE_PLUGIN_PACKAGE, config: undefined }),
12
13
  ]);
@@ -206,6 +207,7 @@ const SIGNAL_KINDS = Object.freeze({
206
207
  "akuma.initiating": true,
207
208
  "akuma.born": true,
208
209
  "akuma.outcome-observed": true,
210
+ "akuma.turn-started": true,
209
211
  "akuma.turn-outcome": true,
210
212
  "akuma.body-ended": true,
211
213
  });
@@ -245,7 +247,7 @@ function sourceUrl(world, packageName) {
245
247
  return null;
246
248
  }
247
249
  async function importFromWorld(world, packageName) {
248
- if (packageName === SQUARE_PLUGIN_PACKAGE)
250
+ if (BUNDLED_PLUGIN_PACKAGES.has(packageName))
249
251
  return (await import(packageName));
250
252
  const direct = sourceUrl(world, packageName);
251
253
  if (direct !== null)
@@ -1,5 +1,5 @@
1
1
  import { type HeldSqliteTransactionLock } from "../coordination/sqlite-transaction-lock.js";
2
2
  import type { GitRepository } from "../git/process.js";
3
- import type { TaskId } from "../task/identity.js";
4
- export declare function settlementFencePath(repository: GitRepository, taskId: TaskId): string;
5
- export declare function acquireTaskSettlementFence(repository: GitRepository, taskId: TaskId): Promise<HeldSqliteTransactionLock>;
3
+ import type { DebtId } from "../debt/identity.js";
4
+ export declare function settlementFencePath(repository: GitRepository, debtId: DebtId): string;
5
+ export declare function acquireDebtSettlementFence(repository: GitRepository, debtId: DebtId): Promise<HeldSqliteTransactionLock>;
@@ -2,13 +2,13 @@ import { createHash } from "node:crypto";
2
2
  import { resolve } from "node:path";
3
3
  import { acquireSqliteTransactionLock, } from "../coordination/sqlite-transaction-lock.js";
4
4
  import { commonGitDirectory } from "../git/repository.js";
5
- export function settlementFencePath(repository, taskId) {
6
- const locator = createHash("sha256").update(taskId).digest("hex");
5
+ export function settlementFencePath(repository, debtId) {
6
+ const locator = createHash("sha256").update(debtId).digest("hex");
7
7
  return resolve(commonGitDirectory(repository), "keiyaku", "locks", "settlement", `${locator}.sqlite`);
8
8
  }
9
- export function acquireTaskSettlementFence(repository, taskId) {
9
+ export function acquireDebtSettlementFence(repository, debtId) {
10
10
  return acquireSqliteTransactionLock({
11
- path: settlementFencePath(repository, taskId),
11
+ path: settlementFencePath(repository, debtId),
12
12
  mode: "immediate",
13
13
  });
14
14
  }
@@ -4,31 +4,31 @@ import type { GitDecisionObservation } from "../git/observe.js";
4
4
  import { type PrivateStatePublicationSeat } from "../git/private-state-seat.js";
5
5
  import type { GitRepository } from "../git/process.js";
6
6
  import { type GitDecodeChannel, type GitReadObservation, type GitTreeSelection } from "../git/read-observation.js";
7
- import { type TaskId } from "../task/identity.js";
8
- export declare function taskHolderObservationSelection(): GitTreeSelection;
9
- export type TaskHolder = Readonly<{
7
+ import { type DebtId } from "../debt/identity.js";
8
+ export declare function debtHolderObservationSelection(): GitTreeSelection;
9
+ export type DebtHolder = Readonly<{
10
10
  version: 1;
11
- taskId: TaskId;
11
+ debtId: DebtId;
12
12
  contractId: ContractId;
13
13
  disposition: "held" | "released";
14
14
  }>;
15
- export type TaskHolderProjection = ReadonlyMap<ContractId, TaskHolder>;
16
- export declare function claimTaskHolder(taskId: TaskId, owner: ContractId): TreeUpdate;
15
+ export type DebtHolderProjection = ReadonlyMap<ContractId, DebtHolder>;
16
+ export declare function claimDebtHolder(debtId: DebtId, owner: ContractId): TreeUpdate;
17
17
  type AdmissionOutcome = Readonly<{
18
18
  kind: string;
19
19
  }>;
20
- type TaskHolderAdmission<T extends AdmissionOutcome> = Readonly<{
20
+ type DebtHolderAdmission<T extends AdmissionOutcome> = Readonly<{
21
21
  kind: "completed";
22
22
  result: T;
23
23
  }> | Readonly<{
24
24
  kind: "accepted-release-failed";
25
25
  result: T;
26
- taskId: TaskId;
26
+ debtId: DebtId;
27
27
  diagnostic: string;
28
28
  }>;
29
- export declare function admitWithTaskHolderFence<T extends AdmissionOutcome>(repository: GitRepository, taskId: TaskId, action: () => T | Promise<T>): Promise<TaskHolderAdmission<T>>;
30
- export declare function releaseTaskHolder(channel: GitDecodeChannel, observation: GitDecisionObservation, owner: ContractId): Promise<TreeUpdate | null>;
31
- type TaskHolderReleasePublication = Readonly<{
29
+ export declare function admitWithDebtHolderFence<T extends AdmissionOutcome>(repository: GitRepository, debtId: DebtId, action: () => T | Promise<T>): Promise<DebtHolderAdmission<T>>;
30
+ export declare function releaseDebtHolder(channel: GitDecodeChannel, observation: GitDecisionObservation, owner: ContractId): Promise<TreeUpdate | null>;
31
+ type DebtHolderReleasePublication = Readonly<{
32
32
  kind: "released";
33
33
  }> | Readonly<{
34
34
  kind: "not-held";
@@ -37,9 +37,9 @@ type TaskHolderReleasePublication = Readonly<{
37
37
  diagnostic: string;
38
38
  }>;
39
39
  /** Publish the released holder against the same frozen observation that decided the release. */
40
- export declare function publishTaskHolderRelease(repository: GitRepository, channel: GitDecodeChannel, observation: GitDecisionObservation, owner: ContractId, seat: PrivateStatePublicationSeat): Promise<TaskHolderReleasePublication>;
41
- export declare function readTaskHolderProjectionFromDecision(channel: GitDecodeChannel, observation: GitDecisionObservation): Promise<TaskHolderProjection>;
42
- export declare function releaseTaskHolderWithFence<T extends AdmissionOutcome>(repository: GitRepository, channel: GitDecodeChannel, owner: ContractId, action: () => T | Promise<T>): Promise<TaskHolderAdmission<T>>;
43
- export declare function readTaskHoldersAt(observation: Pick<GitReadObservation, "snapshot" | "readBlobs">): Promise<readonly TaskHolder[]>;
44
- export declare function readTaskHolderProjectionAt(observation: GitReadObservation): Promise<TaskHolderProjection>;
40
+ export declare function publishDebtHolderRelease(repository: GitRepository, channel: GitDecodeChannel, observation: GitDecisionObservation, owner: ContractId, seat: PrivateStatePublicationSeat): Promise<DebtHolderReleasePublication>;
41
+ export declare function readDebtHolderProjectionFromDecision(channel: GitDecodeChannel, observation: GitDecisionObservation): Promise<DebtHolderProjection>;
42
+ export declare function releaseDebtHolderWithFence<T extends AdmissionOutcome>(repository: GitRepository, channel: GitDecodeChannel, owner: ContractId, action: () => T | Promise<T>): Promise<DebtHolderAdmission<T>>;
43
+ export declare function readDebtHoldersAt(observation: Pick<GitReadObservation, "snapshot" | "readBlobs">): Promise<readonly DebtHolder[]>;
44
+ export declare function readDebtHolderProjectionAt(observation: GitReadObservation): Promise<DebtHolderProjection>;
45
45
  export {};
@@ -4,20 +4,26 @@ import { contractId } from "../core/facts/types.js";
4
4
  import { GIT_REF, updateGitTree, updateRefsAtomically, writeBlob, writeStateCommit } from "../git/repository.js";
5
5
  import { confirmPrivateStatePublication } from "../git/private-state-seat.js";
6
6
  import { withGitTargetedReadObservation, } from "../git/read-observation.js";
7
- import { parseTaskId } from "../task/identity.js";
8
- import { acquireTaskSettlementFence } from "./fence.js";
7
+ import { parseDebtId } from "../debt/identity.js";
8
+ import { acquireDebtSettlementFence } from "./fence.js";
9
+ // The private persisted spelling predates the product rename. Keep its bytes
10
+ // and path stable so an existing held association still settles after upgrade.
9
11
  const HOLDER_ROOT = "settlement/task-holders";
10
12
  const HOLDER_PREFIX = `${HOLDER_ROOT}/`;
11
13
  const HOLDER_SUFFIX = ".json";
12
- export function taskHolderObservationSelection() {
14
+ export function debtHolderObservationSelection() {
13
15
  return { subtrees: [HOLDER_ROOT] };
14
16
  }
15
- function holderPath(taskId) {
16
- const digest = createHash("sha256").update(taskId).digest("hex");
17
+ function storedIdentity(debtId) {
18
+ return `task/${debtId.slice("debt/".length)}`;
19
+ }
20
+ function holderPath(debtId) {
21
+ const digest = createHash("sha256").update(storedIdentity(debtId)).digest("hex");
17
22
  return `${HOLDER_PREFIX}${digest}${HOLDER_SUFFIX}`;
18
23
  }
19
24
  function canonicalBytes(holder) {
20
- return Buffer.from(`${JSON.stringify(holder)}\n`);
25
+ const { version, debtId, contractId, disposition } = holder;
26
+ return Buffer.from(`${JSON.stringify({ version, taskId: storedIdentity(debtId), contractId, disposition })}\n`);
21
27
  }
22
28
  function corruption(message, cause) {
23
29
  throw new AuthorityCorruptionError(message, cause === undefined ? {} : { cause });
@@ -27,67 +33,67 @@ function decodeHolder(path, bytes) {
27
33
  try {
28
34
  const text = Buffer.from(bytes).toString("utf8");
29
35
  if (!text.endsWith("\n") || text.slice(0, -1).includes("\n"))
30
- corruption(`TaskHolder is not one canonical JSON line: ${path}`);
36
+ corruption(`DebtHolder is not one canonical JSON line: ${path}`);
31
37
  value = JSON.parse(text);
32
38
  }
33
39
  catch (error) {
34
40
  if (error instanceof AuthorityCorruptionError)
35
41
  throw error;
36
- return corruption(`invalid TaskHolder JSON: ${path}`, error);
42
+ return corruption(`invalid DebtHolder JSON: ${path}`, error);
37
43
  }
38
44
  if (typeof value !== "object" || value === null || Array.isArray(value))
39
- corruption(`TaskHolder must be an object: ${path}`);
45
+ corruption(`DebtHolder must be an object: ${path}`);
40
46
  const record = value;
41
47
  const keys = Object.keys(record);
42
48
  if (keys.length !== 4 || keys.some((key) => !["version", "taskId", "contractId", "disposition"].includes(key))) {
43
- corruption(`TaskHolder has invalid fields: ${path}`);
49
+ corruption(`DebtHolder has invalid fields: ${path}`);
44
50
  }
45
51
  if (record.version !== 1)
46
- corruption(`TaskHolder version must be 1: ${path}`);
47
- if (typeof record.taskId !== "string")
48
- corruption(`TaskHolder taskId is invalid: ${path}`);
52
+ corruption(`DebtHolder version must be 1: ${path}`);
53
+ if (typeof record.taskId !== "string" || !record.taskId.startsWith("task/"))
54
+ corruption(`DebtHolder identity is invalid: ${path}`);
49
55
  if (typeof record.contractId !== "string")
50
- corruption(`TaskHolder contractId is invalid: ${path}`);
51
- let taskId;
56
+ corruption(`DebtHolder contractId is invalid: ${path}`);
57
+ let debtId;
52
58
  let owner;
53
59
  try {
54
- parseTaskId(record.taskId);
55
- taskId = record.taskId;
60
+ debtId = `debt/${record.taskId.slice("task/".length)}`;
61
+ parseDebtId(debtId);
56
62
  owner = contractId(record.contractId);
57
63
  }
58
64
  catch (error) {
59
- return corruption(`TaskHolder identity is invalid: ${path}`, error);
65
+ return corruption(`DebtHolder identity is invalid: ${path}`, error);
60
66
  }
61
67
  if (record.disposition !== "held" && record.disposition !== "released") {
62
- corruption(`TaskHolder disposition is invalid: ${path}`);
68
+ corruption(`DebtHolder disposition is invalid: ${path}`);
63
69
  }
64
- const holder = { version: 1, taskId, contractId: owner, disposition: record.disposition };
65
- if (holderPath(taskId) !== path)
66
- corruption(`TaskHolder path does not match taskId: ${path}`);
70
+ const holder = { version: 1, debtId, contractId: owner, disposition: record.disposition };
71
+ if (holderPath(debtId) !== path)
72
+ corruption(`DebtHolder path does not match debtId: ${path}`);
67
73
  if (!Buffer.from(canonicalBytes(holder)).equals(Buffer.from(bytes)))
68
- corruption(`TaskHolder bytes are not canonical: ${path}`);
74
+ corruption(`DebtHolder bytes are not canonical: ${path}`);
69
75
  return holder;
70
76
  }
71
- function projectTaskHolders(holders) {
77
+ function projectDebtHolders(holders) {
72
78
  const projection = new Map();
73
79
  for (const holder of holders) {
74
80
  if (projection.has(holder.contractId)) {
75
- corruption(`Contract has multiple current TaskHolders: ${holder.contractId}`);
81
+ corruption(`Contract has multiple current DebtHolders: ${holder.contractId}`);
76
82
  }
77
83
  projection.set(holder.contractId, holder);
78
84
  }
79
85
  return projection;
80
86
  }
81
87
  function update(holder) {
82
- return { path: holderPath(holder.taskId), bytes: canonicalBytes(holder) };
88
+ return { path: holderPath(holder.debtId), bytes: canonicalBytes(holder) };
83
89
  }
84
- export function claimTaskHolder(taskId, owner) {
85
- return update({ version: 1, taskId, contractId: owner, disposition: "held" });
90
+ export function claimDebtHolder(debtId, owner) {
91
+ return update({ version: 1, debtId, contractId: owner, disposition: "held" });
86
92
  }
87
93
  function detail(error) {
88
94
  return error instanceof Error ? error.message : String(error);
89
95
  }
90
- function finishTaskHolderAdmission(taskId, result, close) {
96
+ function finishDebtHolderAdmission(debtId, result, close) {
91
97
  try {
92
98
  close();
93
99
  return { kind: "completed", result };
@@ -95,11 +101,11 @@ function finishTaskHolderAdmission(taskId, result, close) {
95
101
  catch (error) {
96
102
  if (result.kind !== "accepted")
97
103
  throw error;
98
- return { kind: "accepted-release-failed", result, taskId, diagnostic: detail(error) };
104
+ return { kind: "accepted-release-failed", result, debtId, diagnostic: detail(error) };
99
105
  }
100
106
  }
101
- export async function admitWithTaskHolderFence(repository, taskId, action) {
102
- const held = await acquireTaskSettlementFence(repository, taskId);
107
+ export async function admitWithDebtHolderFence(repository, debtId, action) {
108
+ const held = await acquireDebtSettlementFence(repository, debtId);
103
109
  let result;
104
110
  try {
105
111
  result = await action();
@@ -113,19 +119,19 @@ export async function admitWithTaskHolderFence(repository, taskId, action) {
113
119
  }
114
120
  throw error;
115
121
  }
116
- return finishTaskHolderAdmission(taskId, result, () => held.close());
122
+ return finishDebtHolderAdmission(debtId, result, () => held.close());
117
123
  }
118
- export async function releaseTaskHolder(channel, observation, owner) {
119
- const current = (await readTaskHolderProjectionFromDecision(channel, observation)).get(owner) ?? null;
124
+ export async function releaseDebtHolder(channel, observation, owner) {
125
+ const current = (await readDebtHolderProjectionFromDecision(channel, observation)).get(owner) ?? null;
120
126
  return current === null || current.disposition !== "held" ? null : update({ ...current, disposition: "released" });
121
127
  }
122
128
  async function releasedHolderIsCurrent(repository, channel, owner, expected) {
123
- const current = (await observeTaskHolderProjection(repository, channel)).get(owner) ?? null;
129
+ const current = (await observeDebtHolderProjection(repository, channel)).get(owner) ?? null;
124
130
  return current?.disposition === "released" && Buffer.from(canonicalBytes(current)).equals(expected);
125
131
  }
126
132
  /** Publish the released holder against the same frozen observation that decided the release. */
127
- export async function publishTaskHolderRelease(repository, channel, observation, owner, seat) {
128
- const release = await releaseTaskHolder(channel, observation, owner);
133
+ export async function publishDebtHolderRelease(repository, channel, observation, owner, seat) {
134
+ const release = await releaseDebtHolder(channel, observation, owner);
129
135
  if (release === null)
130
136
  return { kind: "not-held" };
131
137
  const tree = await updateGitTree(repository, observation.admission.snapshot.tree, new Map([[release.path, { oid: await writeBlob(repository, release.bytes) }]]));
@@ -133,7 +139,7 @@ export async function publishTaskHolderRelease(repository, channel, observation,
133
139
  repository,
134
140
  tree,
135
141
  parent: observation.admission.snapshot.commit,
136
- message: `release held Task completion: ${owner}`,
142
+ message: `release held Debt completion: ${owner}`,
137
143
  });
138
144
  const publication = await updateRefsAtomically(repository, [
139
145
  {
@@ -154,10 +160,10 @@ export async function publishTaskHolderRelease(repository, channel, observation,
154
160
  kind: "non-published",
155
161
  diagnostic: publication.kind === "non-published"
156
162
  ? detail(publication.error)
157
- : "Task holder release publication state is unknown",
163
+ : "Debt holder release publication state is unknown",
158
164
  };
159
165
  }
160
- export async function readTaskHolderProjectionFromDecision(channel, observation) {
166
+ export async function readDebtHolderProjectionFromDecision(channel, observation) {
161
167
  const read = {
162
168
  snapshot: observation.admission.snapshot,
163
169
  readBlobs: async (oids) => {
@@ -168,29 +174,29 @@ export async function readTaskHolderProjectionFromDecision(channel, observation)
168
174
  blobs.set(oid, object);
169
175
  else {
170
176
  if (object.type !== "blob")
171
- corruption(`TaskHolder Git object is not a blob: ${oid}`);
177
+ corruption(`DebtHolder Git object is not a blob: ${oid}`);
172
178
  blobs.set(oid, { kind: "present", bytes: object.bytes });
173
179
  }
174
180
  }
175
181
  return blobs;
176
182
  },
177
183
  };
178
- return projectTaskHolders(await readTaskHoldersAt(read));
184
+ return projectDebtHolders(await readDebtHoldersAt(read));
179
185
  }
180
- function observeTaskHolderProjection(repository, channel) {
181
- return withGitTargetedReadObservation(repository, channel, taskHolderObservationSelection(), readTaskHolderProjectionAt);
186
+ function observeDebtHolderProjection(repository, channel) {
187
+ return withGitTargetedReadObservation(repository, channel, debtHolderObservationSelection(), readDebtHolderProjectionAt);
182
188
  }
183
- async function heldTaskForContract(repository, channel, owner) {
184
- const holder = (await observeTaskHolderProjection(repository, channel)).get(owner) ?? null;
185
- return holder?.disposition === "held" ? holder.taskId : null;
189
+ async function heldDebtForContract(repository, channel, owner) {
190
+ const holder = (await observeDebtHolderProjection(repository, channel)).get(owner) ?? null;
191
+ return holder?.disposition === "held" ? holder.debtId : null;
186
192
  }
187
- export async function releaseTaskHolderWithFence(repository, channel, owner, action) {
188
- const taskId = await heldTaskForContract(repository, channel, owner);
189
- return taskId === null
193
+ export async function releaseDebtHolderWithFence(repository, channel, owner, action) {
194
+ const debtId = await heldDebtForContract(repository, channel, owner);
195
+ return debtId === null
190
196
  ? { kind: "completed", result: await action() }
191
- : admitWithTaskHolderFence(repository, taskId, action);
197
+ : admitWithDebtHolderFence(repository, debtId, action);
192
198
  }
193
- export async function readTaskHoldersAt(observation) {
199
+ export async function readDebtHoldersAt(observation) {
194
200
  const entries = [...observation.snapshot.paths].filter(([path, entry]) => path.startsWith(HOLDER_PREFIX) && entry.type === "blob");
195
201
  const blobs = await observation.readBlobs(entries.map(([, entry]) => entry.oid));
196
202
  const holders = [];
@@ -198,26 +204,26 @@ export async function readTaskHoldersAt(observation) {
198
204
  for (const [path, entry] of observation.snapshot.paths) {
199
205
  if (path === HOLDER_ROOT) {
200
206
  if (entry.type !== "tree")
201
- corruption(`TaskHolder authority root is not a tree: ${path}`);
207
+ corruption(`DebtHolder authority root is not a tree: ${path}`);
202
208
  continue;
203
209
  }
204
210
  if (!path.startsWith(HOLDER_PREFIX))
205
211
  continue;
206
212
  if (!path.endsWith(HOLDER_SUFFIX))
207
- corruption(`unexpected TaskHolder authority path: ${path}`);
213
+ corruption(`unexpected DebtHolder authority path: ${path}`);
208
214
  if (entry.type !== "blob")
209
- corruption(`TaskHolder path is not a blob: ${path}`);
215
+ corruption(`DebtHolder path is not a blob: ${path}`);
210
216
  const result = blobs.get(entry.oid);
211
217
  if (result?.kind !== "present")
212
- corruption(`missing TaskHolder Git object: ${path}`);
218
+ corruption(`missing DebtHolder Git object: ${path}`);
213
219
  const holder = decodeHolder(path, result.bytes);
214
- if (seen.has(holder.taskId))
215
- corruption(`duplicate TaskHolder identity: ${holder.taskId}`);
216
- seen.add(holder.taskId);
220
+ if (seen.has(holder.debtId))
221
+ corruption(`duplicate DebtHolder identity: ${holder.debtId}`);
222
+ seen.add(holder.debtId);
217
223
  holders.push(holder);
218
224
  }
219
- return holders.sort((left, right) => Buffer.compare(Buffer.from(left.taskId), Buffer.from(right.taskId)));
225
+ return holders.sort((left, right) => Buffer.compare(Buffer.from(left.debtId), Buffer.from(right.debtId)));
220
226
  }
221
- export async function readTaskHolderProjectionAt(observation) {
222
- return projectTaskHolders(await readTaskHoldersAt(observation));
227
+ export async function readDebtHolderProjectionAt(observation) {
228
+ return projectDebtHolders(await readDebtHoldersAt(observation));
223
229
  }
@@ -5,19 +5,19 @@ import type { GitDecodeChannel } from "../git/read-observation.js";
5
5
  import type { Effect } from "../git/reconcile.js";
6
6
  import { type GitRepository } from "../git/process.js";
7
7
  export declare const settlementActionSchema: z.ZodObject<{
8
- kind: z.ZodLiteral<"task">;
9
- taskId: z.ZodPipe<z.ZodString, z.ZodTransform<`task/${string}`, string>>;
8
+ kind: z.ZodLiteral<"debt">;
9
+ debtId: z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>;
10
10
  action: z.ZodLiteral<"done">;
11
11
  }, z.core.$strict>;
12
12
  export type SettlementAction = z.infer<typeof settlementActionSchema>;
13
13
  export declare const settlementLagSchema: z.ZodObject<{
14
14
  kind: z.ZodLiteral<"settlement-failed">;
15
15
  surface: z.ZodEnum<{
16
- task: "task";
17
- "task-holder": "task-holder";
16
+ debt: "debt";
17
+ "debt-holder": "debt-holder";
18
18
  }>;
19
19
  contractId: z.ZodPipe<z.ZodString, z.ZodTransform<ContractId, string>>;
20
- taskId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<`task/${string}`, string>>>;
20
+ debtId: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodTransform<`debt/${string}`, string>>>;
21
21
  path: z.ZodOptional<z.ZodString>;
22
22
  diagnostic: z.ZodString;
23
23
  }, z.core.$strict>;