@astrosheep/keiyaku 2.9.8 → 2.9.10

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 (230) hide show
  1. package/README.md +50 -182
  2. package/build/.tsbuildinfo +1 -1
  3. package/build/agents/harness/control-types.js +18 -1
  4. package/build/agents/harness/index.js +2 -0
  5. package/build/agents/harness/outcome-error.js +81 -0
  6. package/build/agents/harness/projection.js +10 -7
  7. package/build/agents/harness/router.js +5 -1
  8. package/build/agents/providers/claude-agent-sdk/adapter.js +18 -4
  9. package/build/agents/providers/claude-agent-sdk/registration.js +11 -1
  10. package/build/agents/providers/claude-agent-sdk/session.js +19 -5
  11. package/build/agents/providers/codex-app-server/adapter.js +11 -6
  12. package/build/agents/providers/codex-app-server/events.js +67 -6
  13. package/build/agents/providers/codex-app-server/registration.js +11 -1
  14. package/build/agents/providers/opencode-sdk/adapter.js +8 -1
  15. package/build/agents/providers/opencode-sdk/events.js +24 -2
  16. package/build/agents/providers/opencode-sdk/registration.js +11 -1
  17. package/build/agents/providers/pi/checkpoint.js +9 -1
  18. package/build/agents/providers/pi/events.js +2 -0
  19. package/build/agents/providers/pi/registration.js +14 -1
  20. package/build/cli/commands/akuma/akuma/handler.js +1 -1
  21. package/build/cli/commands/akuma/akuma/meta.js +3 -3
  22. package/build/cli/commands/akuma/catalog.js +2 -2
  23. package/build/cli/commands/akuma/{view → show}/handler.js +5 -5
  24. package/build/cli/commands/akuma/{view → show}/meta.js +3 -3
  25. package/build/cli/commands/akuma.js +1 -1
  26. package/build/cli/commands/contract/amend/handler.js +5 -4
  27. package/build/cli/commands/contract/arc/handler.js +5 -4
  28. package/build/cli/commands/contract/audit/handler.js +2 -2
  29. package/build/cli/commands/contract/bind/handler.js +12 -3
  30. package/build/cli/commands/contract/bind/meta.js +45 -15
  31. package/build/cli/commands/contract/forfeit/handler.js +9 -5
  32. package/build/cli/commands/contract/log/handler.js +2 -2
  33. package/build/cli/commands/contract/petition/handler.js +34 -7
  34. package/build/cli/commands/contract/renew/handler.js +7 -7
  35. package/build/cli/commands/contract/renew/meta.js +3 -3
  36. package/build/cli/commands/metadata.js +10 -6
  37. package/build/cli/commands/projection/call/meta.js +1 -1
  38. package/build/cli/commands/projection/catalog.js +2 -0
  39. package/build/cli/commands/projection/history/handler.js +21 -0
  40. package/build/cli/commands/projection/history/meta.js +9 -0
  41. package/build/cli/commands/projection/shared.js +3 -4
  42. package/build/cli/commands/projection/status/handler.js +3 -3
  43. package/build/cli/commands/projection/wait/handler.js +20 -11
  44. package/build/cli/commands/task/add/handler.js +14 -5
  45. package/build/cli/commands/task/add/meta.js +2 -2
  46. package/build/cli/commands/task/catalog.js +4 -0
  47. package/build/cli/commands/task/done/handler.js +1 -4
  48. package/build/cli/commands/task/done/meta.js +1 -1
  49. package/build/cli/commands/task/drop/meta.js +1 -1
  50. package/build/cli/commands/task/hold/handler.js +3 -0
  51. package/build/cli/commands/task/hold/meta.js +8 -0
  52. package/build/cli/commands/task/log/handler.js +1 -1
  53. package/build/cli/commands/task/log/meta.js +2 -2
  54. package/build/cli/commands/task/resume/handler.js +3 -0
  55. package/build/cli/commands/task/resume/meta.js +8 -0
  56. package/build/cli/commands/task/shared.js +39 -14
  57. package/build/cli/commands/task/show/handler.js +1 -1
  58. package/build/cli/commands/task/show/meta.js +1 -1
  59. package/build/cli/commands/task/start/meta.js +1 -1
  60. package/build/cli/commands/task/stop/handler.js +1 -4
  61. package/build/cli/commands/task/stop/meta.js +1 -1
  62. package/build/cli/commands/task/update/handler.js +11 -3
  63. package/build/cli/commands/task/update/meta.js +3 -3
  64. package/build/cli/completion.js +3 -2
  65. package/build/cli/flags.js +51 -14
  66. package/build/cli/help.js +4 -1
  67. package/build/cli/index.js +40 -25
  68. package/build/cli/parse-flags.js +40 -7
  69. package/build/cli/parse-metadata.js +5 -2
  70. package/build/cli/parse-selectors.js +2 -3
  71. package/build/cli/parse.js +40 -6
  72. package/build/cli/projection-address.js +12 -10
  73. package/build/cli/render/amendment-warning.js +8 -0
  74. package/build/cli/render/arc.js +6 -2
  75. package/build/cli/render/audit.js +400 -81
  76. package/build/cli/render/kanshi.js +242 -79
  77. package/build/cli/render/lifecycle.js +56 -0
  78. package/build/cli/render/misc.js +24 -28
  79. package/build/cli/render/petition.js +5 -0
  80. package/build/cli/render/projection-activity.js +65 -29
  81. package/build/cli/render/projection-history.js +64 -0
  82. package/build/cli/render/shared.js +23 -9
  83. package/build/cli/render/status.js +13 -35
  84. package/build/cli/render/task.js +51 -26
  85. package/build/cli/render/terminal-failure.js +3 -1
  86. package/build/cli/render/wait.js +45 -69
  87. package/build/cli/subagent-guard.js +1 -1
  88. package/build/cli/types.js +1 -1
  89. package/build/config/env-keys.js +3 -1
  90. package/build/config/env.js +24 -1
  91. package/build/config/settings/schema.js +3 -1
  92. package/build/core/address-carrier.js +89 -0
  93. package/build/core/addressing.js +255 -196
  94. package/build/core/amend.js +115 -38
  95. package/build/core/amendment-criteria.js +17 -0
  96. package/build/core/amendment-warning.js +10 -0
  97. package/build/core/arc.js +184 -83
  98. package/build/core/audit/candidate.js +110 -9
  99. package/build/core/audit/coordinates.js +120 -65
  100. package/build/core/audit/evidence.js +19 -23
  101. package/build/core/audit/facade.js +34 -11
  102. package/build/core/audit/report.js +5 -5
  103. package/build/core/bind-reconciliation.js +390 -0
  104. package/build/core/bind-workspace.js +12 -20
  105. package/build/core/bind.js +242 -273
  106. package/build/core/call/call.js +1 -0
  107. package/build/core/call/context.js +46 -71
  108. package/build/core/call/prompt.js +6 -3
  109. package/build/core/context.js +49 -35
  110. package/build/core/contract-carrier-runtime.js +408 -0
  111. package/build/core/contract-carrier.js +270 -0
  112. package/build/core/contract-view.js +33 -27
  113. package/build/core/contract.js +5 -1
  114. package/build/core/derived-replay.js +207 -0
  115. package/build/core/draft.js +125 -57
  116. package/build/core/forfeit.js +113 -56
  117. package/build/core/identifier-slug.js +63 -13
  118. package/build/core/ids.js +4 -4
  119. package/build/core/lifecycle-history.js +35 -0
  120. package/build/core/lifecycle-recovery.js +117 -0
  121. package/build/core/lifecycle-runner.js +377 -0
  122. package/build/core/log.js +37 -11
  123. package/build/core/outcome-base.js +181 -0
  124. package/build/core/process-group.js +139 -0
  125. package/build/core/projection/generation/database.js +82 -7
  126. package/build/core/projection/generation/model.js +9 -36
  127. package/build/core/projection/generation/projection-generation-continuation.js +10 -22
  128. package/build/core/projection/generation/projection-generation-execution.js +13 -6
  129. package/build/core/projection/index.js +5 -4
  130. package/build/core/projection/projection-activity.js +29 -8
  131. package/build/core/projection/projection-alias.js +23 -10
  132. package/build/core/projection/projection-core.js +21 -7
  133. package/build/core/projection/projection-execution-observer.js +91 -39
  134. package/build/core/projection/projection-history.js +474 -0
  135. package/build/core/projection/projection-runner-lock.js +12 -0
  136. package/build/core/projection/projection-status-observation.js +365 -0
  137. package/build/core/projection/projection-status.js +35 -337
  138. package/build/core/projection/projection-terminal-failure.js +13 -8
  139. package/build/core/projection/projection-wait.js +7 -2
  140. package/build/core/projection/tell/launch-store.js +244 -0
  141. package/build/core/projection/tell/model.js +3 -3
  142. package/build/core/projection/tell/store.js +70 -118
  143. package/build/core/registry.js +22 -87
  144. package/build/core/renew-build.js +424 -0
  145. package/build/core/renew-plan.js +239 -0
  146. package/build/core/renew-rewrite.js +77 -0
  147. package/build/core/renew.js +295 -520
  148. package/build/core/repository-ledger/accepted-fold-read.js +19 -0
  149. package/build/core/repository-ledger/accepted-tail.js +116 -0
  150. package/build/core/repository-ledger/admission.js +38 -0
  151. package/build/core/repository-ledger/authoritative-transaction.js +1 -0
  152. package/build/core/repository-ledger/claim-evidence.js +147 -0
  153. package/build/core/repository-ledger/codec.js +297 -0
  154. package/build/core/repository-ledger/current-state-store.js +853 -0
  155. package/build/core/repository-ledger/fold-repository.js +375 -0
  156. package/build/core/repository-ledger/fold.js +248 -0
  157. package/build/core/repository-ledger/git-object-store.js +243 -0
  158. package/build/core/repository-ledger/history-read.js +15 -0
  159. package/build/core/repository-ledger/incremental-read.js +153 -0
  160. package/build/core/repository-ledger/index.js +15 -0
  161. package/build/core/repository-ledger/inventory-plan.js +75 -0
  162. package/build/core/repository-ledger/inventory.js +310 -0
  163. package/build/core/repository-ledger/publication-admission.js +125 -0
  164. package/build/core/repository-ledger/publication.js +353 -0
  165. package/build/core/repository-ledger/read-model.js +469 -0
  166. package/build/core/repository-ledger/transaction-membership.js +78 -0
  167. package/build/core/repository-ledger/traversal.js +404 -0
  168. package/build/core/repository-ledger/write-transaction.js +339 -0
  169. package/build/core/seal.js +168 -161
  170. package/build/core/settlement/claim-delivery.js +42 -215
  171. package/build/core/settlement/claim.js +235 -153
  172. package/build/core/settlement/index.js +4 -4
  173. package/build/core/settlement/petition-claim-gates.js +52 -33
  174. package/build/core/settlement/petition-forfeit.js +12 -5
  175. package/build/core/settlement/petition-head-guard.js +8 -5
  176. package/build/core/settlement/petition-preview.js +68 -56
  177. package/build/core/settlement/petition-window.js +50 -0
  178. package/build/core/settlement/petition.js +252 -131
  179. package/build/core/settlement/queue-read-model.js +72 -95
  180. package/build/core/settlement/queue-seat-allocation.js +35 -126
  181. package/build/core/settlement/queue.js +1 -1
  182. package/build/core/settlement/settlement.js +172 -80
  183. package/build/core/settlement/verdict.js +112 -66
  184. package/build/core/settlement/verification-coordination.js +305 -0
  185. package/build/core/settlement/verification-supervisor.js +275 -0
  186. package/build/core/settlement/verification.js +398 -31
  187. package/build/core/status/board.js +125 -127
  188. package/build/core/status/lifecycle.js +7 -80
  189. package/build/core/structured-query.js +23 -0
  190. package/build/core/target-ref.js +1 -1
  191. package/build/core/task/board.js +59 -24
  192. package/build/core/task/commands.js +181 -33
  193. package/build/core/task/coordinate.js +56 -0
  194. package/build/core/task/document.js +25 -9
  195. package/build/core/task/index.js +7 -4
  196. package/build/core/task/query.js +17 -27
  197. package/build/core/task/settlement-git.js +164 -179
  198. package/build/core/task/settlement-policy.js +15 -11
  199. package/build/core/task/source-board.js +31 -13
  200. package/build/core/task/task-bind-preparation.js +193 -0
  201. package/build/core/task/task-contract.js +102 -193
  202. package/build/core/task/task-file-transaction.js +171 -0
  203. package/build/core/task/task-git-runtime.js +76 -14
  204. package/build/core/task/task-git-store.js +68 -169
  205. package/build/core/task/task-store-repository.js +13 -6
  206. package/build/core/task/task-worktree.js +6 -33
  207. package/build/core/task/task.js +1 -1
  208. package/build/core/task/tree.js +3 -3
  209. package/build/core/task/validation.js +4 -3
  210. package/build/core/transcripts.js +93 -1
  211. package/build/core/worktree-bootstrap.js +44 -36
  212. package/build/core/worktree-path.js +210 -77
  213. package/build/flow-error.js +7 -7
  214. package/build/generated/version.js +2 -2
  215. package/build/git/core.js +76 -13
  216. package/build/git/refs.js +168 -46
  217. package/build/git/streaming-batch.js +73 -13
  218. package/package.json +1 -1
  219. package/skills/keiyaku/SKILL.md +1 -1
  220. package/skills/keiyaku-akuma/SKILL.md +3 -3
  221. package/skills/keiyaku-task/SKILL.md +4 -2
  222. package/skills/keiyaku-workflow/SKILL.md +88 -203
  223. package/build/core/entry.js +0 -305
  224. package/build/core/ledger-batch.js +0 -194
  225. package/build/core/ledger.js +0 -84
  226. package/build/core/projection/leash.js +0 -87
  227. package/build/core/ref-log.js +0 -119
  228. package/build/core/renew-session.js +0 -128
  229. package/build/core/status/ledger-batch.js +0 -1
  230. package/build/core/status/reconciliation.js +0 -137
@@ -0,0 +1,339 @@
1
+ import { runGitProcess } from "../../git/core.js";
2
+ import { commitRefTransaction, } from "../../git/refs.js";
3
+ import { REPOSITORY_LEDGER_REF, evidenceObjectId, formatLifecycleEntry, formatLifecycleTransaction, repositoryDeliveryRef, } from "./codec.js";
4
+ import { assertHostObjectId, assertReadableCommit, deriveHostGitCoordinates, } from "./git-object-store.js";
5
+ import { assertHonestClaimEvidence } from "./claim-evidence.js";
6
+ import { transactionMembershipError } from "./transaction-membership.js";
7
+ function replayFailure(effect, error) {
8
+ const source = error;
9
+ return {
10
+ effect,
11
+ status: "failed",
12
+ cause: {
13
+ code: typeof source?.code === "string" ? source.code : "REPLAY_FAILED",
14
+ message: typeof source?.message === "string" ? source.message : String(error),
15
+ },
16
+ };
17
+ }
18
+ function validateReplayPlan(plan) {
19
+ if (plan === undefined)
20
+ return;
21
+ const preceding = new Set();
22
+ for (const step of plan.steps) {
23
+ if (!step.effect)
24
+ throw new Error("replay effect name must not be empty");
25
+ if (preceding.has(step.effect))
26
+ throw new Error(`duplicate replay effect ${step.effect}`);
27
+ for (const dependency of step.dependencies ?? []) {
28
+ if (!preceding.has(dependency)) {
29
+ throw new Error(`replay effect ${step.effect} has non-preceding dependency ${dependency}`);
30
+ }
31
+ }
32
+ preceding.add(step.effect);
33
+ }
34
+ }
35
+ async function executeReplayPlan(plan, context) {
36
+ if (plan === undefined || plan.steps.length === 0) {
37
+ return {
38
+ committedHead: context.ledgerHead,
39
+ status: "contained",
40
+ effects: [{
41
+ effect: "replay-plan",
42
+ status: "not-attempted",
43
+ dependency: plan === undefined ? "replay-plan-not-provided" : "replay-plan-empty",
44
+ }],
45
+ };
46
+ }
47
+ const effects = [];
48
+ const outcomes = new Map();
49
+ for (const step of plan.steps) {
50
+ const blockedBy = (step.dependencies ?? []).find((dependency) => outcomes.get(dependency)?.status !== "succeeded");
51
+ let effect;
52
+ if (blockedBy !== undefined) {
53
+ effect = { effect: step.effect, status: "not-attempted", dependency: blockedBy };
54
+ }
55
+ else {
56
+ try {
57
+ await step.run(context);
58
+ effect = { effect: step.effect, status: "succeeded" };
59
+ }
60
+ catch (error) {
61
+ effect = replayFailure(step.effect, error);
62
+ }
63
+ }
64
+ effects.push(effect);
65
+ outcomes.set(step.effect, effect);
66
+ }
67
+ return {
68
+ committedHead: context.ledgerHead,
69
+ status: effects.every((effect) => effect.status === "succeeded") ? "complete" : "contained",
70
+ effects,
71
+ };
72
+ }
73
+ async function assertAuthoritativeCommitTipClosure(cwd, coordinates, operations) {
74
+ const checked = new Set();
75
+ for (const operation of operations) {
76
+ if (operation.kind !== "update" || operation.ref === REPOSITORY_LEDGER_REF || checked.has(operation.newOid))
77
+ continue;
78
+ assertHostObjectId(coordinates, operation.newOid);
79
+ await assertReadableCommit(cwd, coordinates, operation.newOid);
80
+ checked.add(operation.newOid);
81
+ }
82
+ }
83
+ export async function buildLifecycleEntry(cwd, entry, expectedLedgerHead) {
84
+ const coordinates = await deriveHostGitCoordinates(cwd);
85
+ if (expectedLedgerHead !== null)
86
+ assertHostObjectId(coordinates, expectedLedgerHead);
87
+ const evidence = evidenceObjectId(entry);
88
+ if (evidence !== null) {
89
+ assertHostObjectId(coordinates, evidence);
90
+ await assertReadableCommit(cwd, coordinates, evidence);
91
+ }
92
+ const parents = [
93
+ ...(expectedLedgerHead === null ? [] : [expectedLedgerHead]),
94
+ ...(evidence === null ? [] : [evidence]),
95
+ ];
96
+ const args = ["commit-tree", coordinates.emptyTree, ...parents.flatMap((parent) => ["-p", parent])];
97
+ const result = await runGitProcess(cwd, args, {
98
+ input: formatLifecycleEntry(entry, coordinates.objectFormat),
99
+ env: {
100
+ GIT_AUTHOR_NAME: "Keiyaku",
101
+ GIT_AUTHOR_EMAIL: "keiyaku@localhost",
102
+ GIT_COMMITTER_NAME: "Keiyaku",
103
+ GIT_COMMITTER_EMAIL: "keiyaku@localhost",
104
+ GIT_AUTHOR_DATE: entry.at,
105
+ GIT_COMMITTER_DATE: entry.at,
106
+ },
107
+ });
108
+ if (result.status !== 0 || result.error) {
109
+ const detail = result.stderr.trim() || result.error?.message || `exit ${String(result.status)}`;
110
+ throw new Error(`cannot build ${entry.kind} ledger object: ${detail}`, { cause: result.error });
111
+ }
112
+ const objectId = result.stdout.trim();
113
+ assertHostObjectId(coordinates, objectId);
114
+ return { entry, objectId, expectedLedgerHead, parents, coordinates };
115
+ }
116
+ export async function buildLifecycleTail(cwd, entries, expectedLedgerHead) {
117
+ if (entries.length === 0)
118
+ throw new Error("a lifecycle tail requires at least one entry");
119
+ const built = [];
120
+ let parent = expectedLedgerHead;
121
+ for (const entry of entries) {
122
+ const next = await buildLifecycleEntry(cwd, entry, parent);
123
+ built.push(next);
124
+ parent = next.objectId;
125
+ }
126
+ return { entries: built, expectedLedgerHead };
127
+ }
128
+ export async function buildLifecycleTransactionNode(input) {
129
+ if (input.entries.length === 0)
130
+ throw new Error("a lifecycle transaction requires at least one introduced entry");
131
+ const coordinates = input.entries[0].coordinates;
132
+ if (input.entries.some((entry) => entry.coordinates.objectFormat !== coordinates.objectFormat
133
+ || entry.coordinates.emptyTree !== coordinates.emptyTree
134
+ || entry.coordinates.objectIdLength !== coordinates.objectIdLength)) {
135
+ throw new Error("lifecycle transaction entries use inconsistent host coordinates");
136
+ }
137
+ if (input.predecessor !== null)
138
+ assertHostObjectId(coordinates, input.predecessor);
139
+ const membership = transactionMembershipError(input.verb, input.entries.map((entry) => entry.entry));
140
+ if (membership)
141
+ throw new Error(membership);
142
+ const first = input.entries[0];
143
+ if (input.verb === "bind" && first.expectedLedgerHead !== null) {
144
+ throw new Error("bind transaction member must be causally parentless");
145
+ }
146
+ if (input.verb !== "bind" && first.expectedLedgerHead === null) {
147
+ throw new Error(`${input.verb} transaction must continue lifecycle causality`);
148
+ }
149
+ for (let index = 1; index < input.entries.length; index += 1) {
150
+ if (input.entries[index].expectedLedgerHead !== input.entries[index - 1].objectId) {
151
+ throw new Error("transaction members must form one ordered lifecycle causal tail");
152
+ }
153
+ }
154
+ const transaction = {
155
+ v: 1,
156
+ kind: "transaction",
157
+ verb: input.verb,
158
+ predecessor: input.predecessor === null ? "none" : "p1",
159
+ };
160
+ const parents = [
161
+ ...(input.predecessor === null ? [] : [input.predecessor]),
162
+ ...input.entries.map((entry) => entry.objectId),
163
+ ];
164
+ if (new Set(parents).size !== parents.length)
165
+ throw new Error("transaction links and predecessor must be distinct");
166
+ const final = input.entries.at(-1);
167
+ const result = await runGitProcess(input.cwd, ["commit-tree", coordinates.emptyTree, ...parents.flatMap((parent) => ["-p", parent])], {
168
+ input: formatLifecycleTransaction(transaction),
169
+ env: {
170
+ GIT_AUTHOR_NAME: "Keiyaku",
171
+ GIT_AUTHOR_EMAIL: "keiyaku@localhost",
172
+ GIT_COMMITTER_NAME: "Keiyaku",
173
+ GIT_COMMITTER_EMAIL: "keiyaku@localhost",
174
+ GIT_AUTHOR_DATE: final.entry.at,
175
+ GIT_COMMITTER_DATE: final.entry.at,
176
+ },
177
+ });
178
+ if (result.status !== 0 || result.error) {
179
+ const detail = result.stderr.trim() || result.error?.message || `exit ${String(result.status)}`;
180
+ throw new Error(`cannot build ${input.verb} transaction node: ${detail}`, { cause: result.error });
181
+ }
182
+ const objectId = result.stdout.trim();
183
+ assertHostObjectId(coordinates, objectId);
184
+ return {
185
+ transaction,
186
+ objectId,
187
+ predecessor: input.predecessor,
188
+ entryObjectIds: input.entries.map((entry) => entry.objectId),
189
+ parents,
190
+ coordinates,
191
+ };
192
+ }
193
+ async function buildTransactionTail(input) {
194
+ const contract = input.entries.at(-1)?.contract;
195
+ if (!contract)
196
+ throw new Error("a lifecycle transaction requires one contract identity");
197
+ const causalParent = input.acceptedLifecycleTail;
198
+ if (input.verb === "bind" && causalParent !== null)
199
+ throw new Error(`bind transaction repeats contract ${contract}`);
200
+ if (input.verb !== "bind" && causalParent === null)
201
+ throw new Error(`${input.verb} transaction has no accepted lifecycle predecessor for ${contract}`);
202
+ const tail = await buildLifecycleTail(input.cwd, input.entries, causalParent);
203
+ const transaction = await buildLifecycleTransactionNode({
204
+ cwd: input.cwd,
205
+ verb: input.verb,
206
+ predecessor: input.predecessor,
207
+ entries: tail.entries,
208
+ });
209
+ return { tail, transaction };
210
+ }
211
+ async function publishLifecycleWrite(cwd, builtTransaction, final, ownedOperations, replayPlan, transactionRunner) {
212
+ validateReplayPlan(replayPlan);
213
+ const authoritativeOperations = [
214
+ { kind: "update", ref: REPOSITORY_LEDGER_REF, newOid: builtTransaction.objectId, expectedOldOid: builtTransaction.predecessor },
215
+ ...ownedOperations,
216
+ ];
217
+ await assertAuthoritativeCommitTipClosure(cwd, builtTransaction.coordinates, authoritativeOperations);
218
+ const transaction = await commitRefTransaction(cwd, authoritativeOperations, builtTransaction.coordinates.objectIdLength, {
219
+ ...(transactionRunner === undefined ? {} : { run: transactionRunner }),
220
+ });
221
+ if (transaction.status === "refused") {
222
+ return {
223
+ family: "refused-before-effects",
224
+ code: transaction.code,
225
+ builtLedgerHead: builtTransaction.objectId,
226
+ observations: transaction.observations,
227
+ cause: transaction.cause,
228
+ };
229
+ }
230
+ if (transaction.status === "indeterminate") {
231
+ return {
232
+ family: "indeterminate",
233
+ code: transaction.code,
234
+ builtLedgerHead: builtTransaction.objectId,
235
+ observations: transaction.observations,
236
+ cause: transaction.cause,
237
+ };
238
+ }
239
+ const replay = await executeReplayPlan(replayPlan, {
240
+ ledgerHead: builtTransaction.objectId,
241
+ entry: final.entry,
242
+ authoritativeOperations,
243
+ });
244
+ return {
245
+ family: "committed",
246
+ completion: replay.status,
247
+ ledgerHead: builtTransaction.objectId,
248
+ entry: final.entry,
249
+ authoritativeOperations,
250
+ authorityProof: transaction.proof,
251
+ authorityObservations: transaction.observations,
252
+ replay,
253
+ };
254
+ }
255
+ export async function publishBindTransaction(input) {
256
+ const expectedDeliveryRef = repositoryDeliveryRef(input.entry.contract);
257
+ if (input.delivery.ref !== expectedDeliveryRef) {
258
+ throw new Error(`bind delivery ref must be ${expectedDeliveryRef}`);
259
+ }
260
+ if (input.delivery.head !== input.entry.data.base) {
261
+ throw new Error("bind delivery head must equal the entry base");
262
+ }
263
+ const selectedTasks = input.entry.data.taskIds !== undefined;
264
+ if (selectedTasks !== (input.taskBoard !== undefined)) {
265
+ throw new Error("bind taskIds and task-board transaction must be present together");
266
+ }
267
+ if (input.taskBoard && input.taskBoard.head !== input.entry.data.base) {
268
+ throw new Error("task-selected bind base must equal the new task-board head");
269
+ }
270
+ const built = await buildTransactionTail({
271
+ cwd: input.cwd,
272
+ verb: "bind",
273
+ predecessor: input.expectedLedgerHead,
274
+ acceptedLifecycleTail: null,
275
+ entries: [input.entry],
276
+ });
277
+ const operations = [
278
+ { kind: "update", ref: input.delivery.ref, newOid: input.delivery.head, expectedOldOid: null },
279
+ ];
280
+ if (input.taskBoard) {
281
+ operations.push({
282
+ kind: "update",
283
+ ref: input.taskBoard.ref,
284
+ newOid: input.taskBoard.head,
285
+ expectedOldOid: input.taskBoard.expectedHead,
286
+ });
287
+ }
288
+ return await publishLifecycleWrite(input.cwd, built.transaction, built.tail.entries[0], operations, input.replayPlan, input.transactionRunner);
289
+ }
290
+ function assertAuthority(condition, message) {
291
+ if (!condition)
292
+ throw new Error(message);
293
+ }
294
+ function assertAuthoritativeTail(transaction) {
295
+ const error = transactionMembershipError(transaction.verb, transaction.entries);
296
+ assertAuthority(error === null, error?.replace(`${transaction.verb} transaction`, `${transaction.verb} authoritative transaction`)
297
+ ?? "invalid authoritative transaction membership");
298
+ }
299
+ /** Build and commit exactly the semantic authority selected by one lifecycle verb. */
300
+ export async function publishAuthoritativeTransaction(cwd, transaction, options = {}) {
301
+ assertAuthoritativeTail(transaction);
302
+ const built = await buildTransactionTail({
303
+ cwd,
304
+ verb: transaction.verb,
305
+ predecessor: transaction.admittedLedgerHead,
306
+ acceptedLifecycleTail: transaction.acceptedLifecycleTail,
307
+ entries: transaction.entries,
308
+ });
309
+ const builtTail = built.tail;
310
+ const final = builtTail.entries.at(-1);
311
+ const entry = final.entry;
312
+ const operations = [];
313
+ if (transaction.verb === "renew" && entry.kind === "renew") {
314
+ assertAuthority("delivery" in transaction, "renew transaction must pin its delivery ref");
315
+ assertAuthority(transaction.delivery.ref === repositoryDeliveryRef(entry.contract), "renew delivery ref does not name its contract");
316
+ assertAuthority(transaction.delivery.expectedOid === entry.data.oldHead, "renew delivery CAS must equal oldHead");
317
+ assertAuthority(entry.data.oldHead !== entry.data.newHead, "renew must replace the delivery head");
318
+ operations.push({ kind: "update", ref: transaction.delivery.ref, expectedOldOid: transaction.delivery.expectedOid, newOid: entry.data.newHead });
319
+ }
320
+ else if (transaction.verb === "forfeit") {
321
+ assertAuthority(entry.kind === "forfeit", "forfeit transaction must end in a forfeit entry");
322
+ assertAuthority(transaction.delivery.ref === repositoryDeliveryRef(entry.contract), "forfeit delivery ref does not name its contract");
323
+ assertAuthority(transaction.delivery.expectedOid === null || transaction.delivery.expectedOid === entry.data.finalHead, "forfeit delivery CAS must equal finalHead or prove absence");
324
+ operations.push(transaction.delivery.expectedOid === null
325
+ ? { kind: "verify", ref: transaction.delivery.ref, expectedOldOid: null }
326
+ : { kind: "delete", ref: transaction.delivery.ref, expectedOldOid: transaction.delivery.expectedOid });
327
+ }
328
+ else if (transaction.verb === "claim") {
329
+ assertAuthority(entry.kind === "claim", "claim transaction must end in a claim entry");
330
+ assertAuthority(transaction.target.ref === entry.data.target, "claim target ref must equal the accepted entry target");
331
+ assertAuthority(transaction.target.expectedOid === entry.data.targetHead, "claim target CAS must equal targetHead");
332
+ assertAuthority(transaction.delivery.ref === repositoryDeliveryRef(entry.contract), "claim delivery ref does not name its contract");
333
+ assertAuthority(transaction.delivery.expectedOid === entry.data.deliveryHead, "claim delivery CAS must equal deliveryHead");
334
+ await assertHonestClaimEvidence(cwd, entry.data);
335
+ operations.push({ kind: "update", ref: transaction.target.ref, expectedOldOid: transaction.target.expectedOid, newOid: entry.data.mergeCommit }, { kind: "delete", ref: transaction.delivery.ref, expectedOldOid: transaction.delivery.expectedOid });
336
+ }
337
+ const write = await publishLifecycleWrite(cwd, built.transaction, final, operations, options.replayPlan, options.transactionRunner);
338
+ return { builtTail, builtTransaction: built.transaction, write };
339
+ }