@nestos/kanban 0.5.1 → 0.5.2

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 (147) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +73 -29
  3. package/dist/{activity-C6xDM-cg.d.cts → activity-BbC4sgKL.d.cts} +28 -2
  4. package/dist/{activity-Dw8DOw0L.d.ts → activity-Czlan5xW.d.ts} +28 -2
  5. package/dist/activity-module-DaO1Rry0.d.cts +22 -0
  6. package/dist/activity-module-T22wliZu.d.ts +22 -0
  7. package/dist/activity-ports-Dqxa86zT.d.cts +12 -0
  8. package/dist/activity-ports-cxfrelaL.d.ts +12 -0
  9. package/dist/activity.cjs +10 -282
  10. package/dist/activity.cjs.map +1 -1
  11. package/dist/activity.d.cts +8 -30
  12. package/dist/activity.d.ts +8 -30
  13. package/dist/activity.js +9 -281
  14. package/dist/activity.js.map +1 -1
  15. package/dist/{chunk-O4OGAAV4.js → chunk-3JYLJPE5.js} +29 -5
  16. package/dist/chunk-3JYLJPE5.js.map +1 -0
  17. package/dist/{chunk-ATUFFNLV.js → chunk-3LEIHB7Y.js} +5 -5
  18. package/dist/chunk-4XF6LQSU.cjs.map +1 -1
  19. package/dist/chunk-5Q7WB63A.cjs +282 -0
  20. package/dist/chunk-5Q7WB63A.cjs.map +1 -0
  21. package/dist/{chunk-PSKQAFDF.cjs → chunk-7KDOTBRX.cjs} +1 -1
  22. package/dist/chunk-7KDOTBRX.cjs.map +1 -0
  23. package/dist/{chunk-5DLZWW5Y.js → chunk-AHHEGTUA.js} +3 -3
  24. package/dist/chunk-AOHQCX7K.cjs +95 -0
  25. package/dist/chunk-AOHQCX7K.cjs.map +1 -0
  26. package/dist/{chunk-IUI5CI2S.cjs → chunk-DINLR6E6.cjs} +96 -92
  27. package/dist/chunk-DINLR6E6.cjs.map +1 -0
  28. package/dist/{chunk-L44TM4EE.cjs → chunk-EYTVC2H5.cjs} +568 -454
  29. package/dist/chunk-EYTVC2H5.cjs.map +1 -0
  30. package/dist/chunk-FEE2YBZ7.js +1972 -0
  31. package/dist/chunk-FEE2YBZ7.js.map +1 -0
  32. package/dist/chunk-FNO5K3A7.js +282 -0
  33. package/dist/chunk-FNO5K3A7.js.map +1 -0
  34. package/dist/chunk-IHHDXZPZ.js +382 -0
  35. package/dist/chunk-IHHDXZPZ.js.map +1 -0
  36. package/dist/chunk-J3EAIVA3.js +280 -0
  37. package/dist/chunk-J3EAIVA3.js.map +1 -0
  38. package/dist/{chunk-DFTOTBGF.js → chunk-KH3WF3K4.js} +20 -16
  39. package/dist/chunk-KH3WF3K4.js.map +1 -0
  40. package/dist/{chunk-TB2RZGDV.js → chunk-M35X5PHO.js} +14 -1
  41. package/dist/chunk-M35X5PHO.js.map +1 -0
  42. package/dist/chunk-QRGZD2JU.cjs +1972 -0
  43. package/dist/chunk-QRGZD2JU.cjs.map +1 -0
  44. package/dist/{chunk-4KF7KUAI.cjs → chunk-RBOER6EW.cjs} +6 -6
  45. package/dist/chunk-RBOER6EW.cjs.map +1 -0
  46. package/dist/{chunk-6MN3H3YF.cjs → chunk-RSH6QSEC.cjs} +16 -3
  47. package/dist/chunk-RSH6QSEC.cjs.map +1 -0
  48. package/dist/{chunk-T7P5EIC4.cjs → chunk-VMRDXOLX.cjs} +33 -33
  49. package/dist/chunk-VMRDXOLX.cjs.map +1 -0
  50. package/dist/{chunk-5XKOCKY2.js → chunk-X4UHZX6F.js} +1 -1
  51. package/dist/chunk-XBSGUVCY.cjs +382 -0
  52. package/dist/chunk-XBSGUVCY.cjs.map +1 -0
  53. package/dist/{chunk-OHQTKGQN.js → chunk-XKDZHAUE.js} +242 -128
  54. package/dist/chunk-XKDZHAUE.js.map +1 -0
  55. package/dist/chunk-ZUZGAO6G.cjs +280 -0
  56. package/dist/chunk-ZUZGAO6G.cjs.map +1 -0
  57. package/dist/{content-CAIp1njn.d.cts → content-C5aJZFlw.d.cts} +1 -1
  58. package/dist/{content-CGMJdyH_.d.ts → content-hLH5BNud.d.ts} +1 -1
  59. package/dist/contracts/index.cjs +13 -3
  60. package/dist/contracts/index.cjs.map +1 -1
  61. package/dist/contracts/index.d.cts +5 -4
  62. package/dist/contracts/index.d.ts +5 -4
  63. package/dist/contracts/index.js +14 -4
  64. package/dist/{discovery-DxpirOz3.d.cts → discovery-9E-LfwIw.d.cts} +1 -1
  65. package/dist/{discovery-gSqWpuRm.d.ts → discovery-D60yrjej.d.ts} +1 -1
  66. package/dist/discovery.cjs +63 -65
  67. package/dist/discovery.cjs.map +1 -1
  68. package/dist/discovery.d.cts +4 -4
  69. package/dist/discovery.d.ts +4 -4
  70. package/dist/discovery.js +5 -7
  71. package/dist/discovery.js.map +1 -1
  72. package/dist/execution-bridge-fpCnH6z5.d.cts +52 -0
  73. package/dist/execution-bridge-rk0uVy_n.d.ts +52 -0
  74. package/dist/execution.cjs +6 -356
  75. package/dist/execution.cjs.map +1 -1
  76. package/dist/execution.d.cts +4 -51
  77. package/dist/execution.d.ts +4 -51
  78. package/dist/execution.js +9 -359
  79. package/dist/execution.js.map +1 -1
  80. package/dist/index.cjs +10 -12
  81. package/dist/index.cjs.map +1 -1
  82. package/dist/index.d.cts +9 -16
  83. package/dist/index.d.ts +9 -16
  84. package/dist/index.js +10 -12
  85. package/dist/index.js.map +1 -1
  86. package/dist/{module-CWNK2BMj.d.ts → module-CYfE7YhM.d.ts} +2 -2
  87. package/dist/{module-BbvwdCDF.d.cts → module-Ca9L3qCn.d.cts} +2 -2
  88. package/dist/{planning-CcFZYdIL.d.cts → planning-CHrOqQ6b.d.cts} +45 -10
  89. package/dist/{planning-CcFZYdIL.d.ts → planning-CHrOqQ6b.d.ts} +45 -10
  90. package/dist/{ports-Bn6ro2FB.d.ts → ports-B0McVg7B.d.ts} +4 -3
  91. package/dist/ports-BeGO1VRI.d.cts +49 -0
  92. package/dist/{ports-CaL6geqR.d.cts → ports-GQy0x-RI.d.cts} +4 -3
  93. package/dist/ports-ykGiNUSx.d.ts +49 -0
  94. package/dist/runtime/index.cjs +205 -0
  95. package/dist/runtime/index.cjs.map +1 -0
  96. package/dist/runtime/index.d.cts +75 -0
  97. package/dist/runtime/index.d.ts +75 -0
  98. package/dist/runtime/index.js +205 -0
  99. package/dist/runtime/index.js.map +1 -0
  100. package/dist/runtime/integration.cjs +423 -0
  101. package/dist/runtime/integration.cjs.map +1 -0
  102. package/dist/runtime/integration.d.cts +658 -0
  103. package/dist/runtime/integration.d.ts +658 -0
  104. package/dist/runtime/integration.js +423 -0
  105. package/dist/runtime/integration.js.map +1 -0
  106. package/dist/storage.cjs +9 -277
  107. package/dist/storage.cjs.map +1 -1
  108. package/dist/storage.d.cts +6 -6
  109. package/dist/storage.d.ts +6 -6
  110. package/dist/storage.js +11 -279
  111. package/dist/storage.js.map +1 -1
  112. package/dist/{store-q63eSMoT.d.cts → store-DPwHzGiz.d.cts} +2 -2
  113. package/dist/{store-Ct0gOAAg.d.ts → store-DgdrPCV9.d.ts} +2 -2
  114. package/dist/task-projection-CSorlMws.d.ts +11 -0
  115. package/dist/task-projection-DKKB_ueb.d.cts +11 -0
  116. package/examples/standalone.ts +22 -0
  117. package/package.json +117 -87
  118. package/dist/chunk-2YFPV5GF.cjs +0 -16
  119. package/dist/chunk-2YFPV5GF.cjs.map +0 -1
  120. package/dist/chunk-4KF7KUAI.cjs.map +0 -1
  121. package/dist/chunk-6MN3H3YF.cjs.map +0 -1
  122. package/dist/chunk-DFTOTBGF.js.map +0 -1
  123. package/dist/chunk-G6FCDLDF.js +0 -16
  124. package/dist/chunk-G6FCDLDF.js.map +0 -1
  125. package/dist/chunk-IUI5CI2S.cjs.map +0 -1
  126. package/dist/chunk-KYNYPKKH.cjs +0 -71
  127. package/dist/chunk-KYNYPKKH.cjs.map +0 -1
  128. package/dist/chunk-L44TM4EE.cjs.map +0 -1
  129. package/dist/chunk-LSE6JG5I.cjs +0 -20
  130. package/dist/chunk-LSE6JG5I.cjs.map +0 -1
  131. package/dist/chunk-O4OGAAV4.js.map +0 -1
  132. package/dist/chunk-OHQTKGQN.js.map +0 -1
  133. package/dist/chunk-PSKQAFDF.cjs.map +0 -1
  134. package/dist/chunk-QTMTBEBA.js +0 -20
  135. package/dist/chunk-QTMTBEBA.js.map +0 -1
  136. package/dist/chunk-T7P5EIC4.cjs.map +0 -1
  137. package/dist/chunk-TB2RZGDV.js.map +0 -1
  138. package/dist/ui/index.cjs +0 -1961
  139. package/dist/ui/index.cjs.map +0 -1
  140. package/dist/ui/index.d.cts +0 -209
  141. package/dist/ui/index.d.ts +0 -209
  142. package/dist/ui/index.js +0 -1961
  143. package/dist/ui/index.js.map +0 -1
  144. package/dist/ui/kanban.css +0 -194
  145. /package/dist/{chunk-ATUFFNLV.js.map → chunk-3LEIHB7Y.js.map} +0 -0
  146. /package/dist/{chunk-5DLZWW5Y.js.map → chunk-AHHEGTUA.js.map} +0 -0
  147. /package/dist/{chunk-5XKOCKY2.js.map → chunk-X4UHZX6F.js.map} +0 -0
@@ -0,0 +1,423 @@
1
+ import {
2
+ KanbanAutomationJournal,
3
+ KanbanWorkLog,
4
+ adoptDecomposition,
5
+ advanceRecordControl,
6
+ analysisHistory,
7
+ analysisSignature,
8
+ analysisStatus,
9
+ analyzeItem,
10
+ assembleKanbanRuntime,
11
+ boardDeletionBlockers,
12
+ cancelTaskMaintenance,
13
+ cancelTaskReplies,
14
+ completeCompositePlans,
15
+ createBoardDeletion,
16
+ createKanbanAutomation,
17
+ createRecordExecution,
18
+ defaultReferences,
19
+ deletionPreview,
20
+ dependencyResults,
21
+ drainBoardAnalyses,
22
+ journalCommand,
23
+ parseAnalysis,
24
+ recordControlKey,
25
+ requestRecordControl,
26
+ safeCode,
27
+ scanBoardStopWork,
28
+ scanTaskControls,
29
+ validateResourceReferences,
30
+ validateSubtasks,
31
+ withBoardDeletion,
32
+ workContext
33
+ } from "../chunk-FEE2YBZ7.js";
34
+ import "../chunk-FNO5K3A7.js";
35
+ import "../chunk-KH3WF3K4.js";
36
+ import "../chunk-J3EAIVA3.js";
37
+ import "../chunk-AHHEGTUA.js";
38
+ import "../chunk-XKDZHAUE.js";
39
+ import "../chunk-IHHDXZPZ.js";
40
+ import "../chunk-RQP77ZTY.js";
41
+ import {
42
+ requireValue
43
+ } from "../chunk-3LEIHB7Y.js";
44
+ import "../chunk-X4UHZX6F.js";
45
+ import {
46
+ randomUUID,
47
+ sha256HexSync
48
+ } from "../chunk-M35X5PHO.js";
49
+ import "../chunk-3JYLJPE5.js";
50
+
51
+ // src/runtime/task-fix.ts
52
+ function createTaskFix(options) {
53
+ return new TaskFix(options);
54
+ }
55
+ var TaskFix = class {
56
+ constructor(options) {
57
+ this.options = options;
58
+ this.executor = options.executor;
59
+ }
60
+ stopping = false;
61
+ executor;
62
+ pending = /* @__PURE__ */ new Map();
63
+ serial(id, run) {
64
+ requireValue(!this.stopping, "SERVICE_STOPPING");
65
+ const next = (this.pending.get(id) ?? Promise.resolve()).catch(() => {
66
+ }).then(run);
67
+ this.pending.set(id, next);
68
+ void next.finally(() => {
69
+ if (this.pending.get(id) === next) this.pending.delete(id);
70
+ }).catch(() => {
71
+ });
72
+ return next;
73
+ }
74
+ async prepare(fix) {
75
+ if (fix.request) return fix;
76
+ const work = await this.executor.prepare(fix.dispatch, fix.item);
77
+ return this.options.journal.update("fix:" + fix.id, (old) => ({ ...old, request: old.request ?? work }));
78
+ }
79
+ async advance(fix) {
80
+ const { options } = this;
81
+ fix = await options.journal.get("fix:" + fix.id);
82
+ if (fix.state === "cancelling") return this.stop(fix);
83
+ if (fix.state === "cancelled") return view(fix);
84
+ if (fix.phase === "prepared" && (await options.service.read(fix.boardId)).lifecycle) return view(fix);
85
+ fix = await this.prepare(fix);
86
+ if (fix.snapshot) {
87
+ await options.accept(fix);
88
+ return view(await options.journal.get("fix:" + fix.id));
89
+ }
90
+ const claimed = await options.journal.claim("fix:" + fix.id);
91
+ const observation = await (claimed ? this.executor.start(fix.request) : this.executor.inspect(fix.request));
92
+ const sessionId = observation.executionSessionId ?? fix.sessionId;
93
+ if (sessionId !== fix.id) await options.journal.update("fix-session:" + sessionId, (old) => old ?? fix.id);
94
+ const saved = await options.journal.update("fix:" + fix.id, (old) => ({ ...old, sessionId, code: observation.code }));
95
+ await options.observe(saved);
96
+ return view(saved);
97
+ }
98
+ fixTask = async (boardId, request) => {
99
+ requireValue(!this.stopping, "SERVICE_STOPPING");
100
+ const fix = await this.options.freeze(boardId, request);
101
+ return this.serial(fix.id, () => this.advance(fix));
102
+ };
103
+ taskFixes = async (boardId, itemId) => {
104
+ await this.options.service.item(boardId, itemId);
105
+ return (await this.options.journal.findForBoard("fix:", boardId, (fix) => fix.itemId === itemId)).map((row) => view(row.value));
106
+ };
107
+ cancelFix = async (boardId, request) => this.serial(request.fixId, async () => {
108
+ requireValue(/^[\w-]{1,128}$/.test(request.operationId), "INVALID_OPERATION_ID");
109
+ const board = await this.options.service.read(boardId), actor = await this.options.service.currentPrincipal();
110
+ requireValue(actor.kind === "human" && board.members?.some((m) => m.kind === actor.kind && m.id === actor.id && m.roles?.includes("coordinator")), "COORDINATOR_REQUIRED");
111
+ const fix = await this.options.journal.update("fix:" + request.fixId, (old) => {
112
+ requireValue(old?.boardId === boardId, "FIX_NOT_FOUND");
113
+ requireValue(!old.accepted, "FIX_ALREADY_ACCEPTED");
114
+ return { ...old, state: old.state === "cancelled" ? "cancelled" : "cancelling", cancelOperationId: old.cancelOperationId ?? request.operationId };
115
+ });
116
+ return fix.state === "cancelled" ? view(fix) : this.stop(fix);
117
+ });
118
+ async stop(fix) {
119
+ const started = Date.now();
120
+ try {
121
+ let stopped = fix.phase === "prepared" || fix.phase === "settled";
122
+ if (!stopped) stopped = await this.options.control.control({ executionId: fix.id, operationId: fix.cancelOperationId, action: "cancel" }) === "cancelled";
123
+ if (stopped && fix.snapshot) stopped = await this.stopCreatedTask(fix);
124
+ const saved = await this.options.journal.update("fix:" + fix.id, (old) => ({ ...old, state: stopped ? "cancelled" : "cancelling", ...stopped ? { phase: "settled" } : {}, code: void 0 }));
125
+ this.options.log({ operationId: fix.cancelOperationId, boardId: fix.boardId, stage: "fix.cancel", result: "success", durationMs: Date.now() - started });
126
+ return view(saved);
127
+ } catch (error) {
128
+ const code = safeCode(error, "FIX_CANCEL_UNKNOWN");
129
+ await this.options.journal.update("fix:" + fix.id, (old) => ({ ...old, code }));
130
+ this.options.log({ operationId: fix.cancelOperationId, boardId: fix.boardId, stage: "fix.cancel", result: "failure", code, durationMs: Date.now() - started });
131
+ throw error;
132
+ }
133
+ }
134
+ async stopCreatedTask(fix) {
135
+ let item;
136
+ try {
137
+ item = (await this.options.service.item(fix.boardId, fix.snapshot.operationId)).item;
138
+ } catch (error) {
139
+ if (error.code === "ITEM_NOT_FOUND") return true;
140
+ throw error;
141
+ }
142
+ if (["completed", "cancelled"].includes(item.status)) return true;
143
+ const controlId = "fix-cancel-" + fix.id;
144
+ await journalCommand(
145
+ this.options.journal,
146
+ this.options.service,
147
+ fix.boardId,
148
+ controlId,
149
+ { type: "request-control", itemId: item.id, controlId, action: "cancel" }
150
+ );
151
+ return false;
152
+ }
153
+ intercept = async (sessionId, input) => {
154
+ const id = await this.options.journal.get("fix-session:" + sessionId);
155
+ if (!id) return false;
156
+ return this.serial(id, async () => {
157
+ const current = await this.options.journal.get("fix:" + id);
158
+ requireValue(!["cancelling", "cancelled"].includes(current.state), "FIX_INPUT_CLOSED");
159
+ return this.options.confirm(current, input);
160
+ });
161
+ };
162
+ quiesce = async () => {
163
+ this.stopping = true;
164
+ await Promise.allSettled([...this.pending.values()]);
165
+ };
166
+ scan = async () => {
167
+ for (const id of await this.options.journal.get("fix-index") ?? []) {
168
+ if (this.stopping) return;
169
+ const fix = await this.options.journal.get("fix:" + id);
170
+ if (!fix || fix.accepted || fix.state === "cancelled") continue;
171
+ try {
172
+ await this.serial(id, () => this.advance(fix));
173
+ } catch (error) {
174
+ this.options.log({ operationId: id, boardId: fix.boardId, stage: "fix.recover", result: "failure", code: safeCode(error, "FIX_RECOVERY_FAILED"), durationMs: 0 });
175
+ }
176
+ }
177
+ };
178
+ };
179
+ function view(fix) {
180
+ const { id, boardId, itemId, sessionId, state, createdItemId, code } = fix;
181
+ return { id, boardId, itemId, sessionId, state, createdItemId, code };
182
+ }
183
+
184
+ // src/runtime/task-replies.ts
185
+ function taskReplies(service, journal, port) {
186
+ const replyTask = async (boardId, request) => {
187
+ requireValue(/^[\w-]{1,96}$/.test(request.operationId) && typeof request.content === "string" && !!request.content.trim() && request.content.length <= 8e3, "WORKSPACE_REPLY_INVALID");
188
+ await service.item(boardId, request.itemId);
189
+ const old = await journal.get("task-reply:" + request.operationId);
190
+ requireValue(!old || old.boardId === boardId && JSON.stringify(old.request) === JSON.stringify(request), "IDEMPOTENCY_CONFLICT");
191
+ if (await journal.get("task-reply-delivered:" + request.operationId)) return;
192
+ const frozen = await freezeReply(service, journal, port, boardId, request);
193
+ await journal.update("task-reply-index", (previous) => previous?.includes(request.operationId) ? previous : [...previous ?? [], request.operationId]);
194
+ const claimed = await journal.claim("task-reply:" + request.operationId);
195
+ const current = await journal.get("task-reply:" + request.operationId);
196
+ if (current.phase === "cancelled" || current.phase === "cancelling") return;
197
+ if (claimed || current.phase === "submitting" || current.phase === void 0) await port.deliver(frozen);
198
+ await journal.update("task-reply-delivered:" + request.operationId, () => true);
199
+ };
200
+ return Object.assign(replyTask, { async scan() {
201
+ for (const id of await journal.get("task-reply-index") ?? []) {
202
+ if (await journal.get("task-reply-delivered:" + id) || await journal.get("task-reply-cancelled:" + id)) continue;
203
+ const saved = await journal.get("task-reply:" + id);
204
+ if (saved && !["cancelling", "cancelled"].includes(saved.phase ?? "") && !(await service.read(saved.boardId)).lifecycle) await replyTask(saved.boardId, saved.request);
205
+ }
206
+ } });
207
+ }
208
+ async function freezeReply(service, journal, port, boardId, request) {
209
+ const { item } = await service.item(boardId, request.itemId);
210
+ requireValue(item.deletedAt === void 0 && item.control?.action !== "cancel", "TASK_CANCELLING");
211
+ const workflow = await service.workflow(boardId), dispatch = workflow.dispatches[request.attemptId];
212
+ requireValue(dispatch?.itemId === item.id && item.owner?.token === dispatch.fence && ["prepared", "running", "unknown"].includes(dispatch.outcome), "STALE_EXECUTION_RESULT");
213
+ requireValue(item.issues?.some((issue) => issue.id === request.replyTo && issue.attemptId === request.attemptId && !issue.resolvedBy), "ISSUE_NOT_FOUND");
214
+ const previous = await journal.get("task-reply:" + request.operationId);
215
+ if (previous) return previous;
216
+ const prepared = await port.prepare({ boardId, request, item, dispatch });
217
+ return journal.update("task-reply:" + request.operationId, (old) => {
218
+ requireValue(!old || old.boardId === boardId && JSON.stringify(old.request) === JSON.stringify(request), "IDEMPOTENCY_CONFLICT");
219
+ return old ?? { ...prepared, phase: "prepared", boardId, request: structuredClone(request) };
220
+ });
221
+ }
222
+
223
+ // src/runtime/operation-runner.ts
224
+ async function coordinateOperation(options) {
225
+ const { journal, key, port } = options;
226
+ let record = await journal.get(key) ?? options.record;
227
+ requireValue(record.fingerprint === options.record.fingerprint, "OPERATION_IDENTITY_CONFLICT");
228
+ if (record.phase === "settled" || record.phase === "prepared" && (await options.service.read(record.boardId)).lifecycle) return record;
229
+ const started = Date.now();
230
+ try {
231
+ if (record.phase === "prepared") {
232
+ if (!await journal.claim(key)) return await journal.get(key);
233
+ record = { ...record, phase: "submitting" };
234
+ await port.start(record);
235
+ }
236
+ const observed = await port.inspect(record);
237
+ const waiting = observed.state === "succeeded" && observed.output === void 0;
238
+ if (observed.state === "succeeded" && !waiting) await port.validate?.(record, observed.output);
239
+ const terminal = !waiting && ["succeeded", "failed"].includes(observed.state);
240
+ return await save(options, {
241
+ ...record,
242
+ phase: terminal ? "settled" : record.phase,
243
+ state: waiting ? "unknown" : observed.state,
244
+ sessionId: observed.executionId,
245
+ code: waiting ? "OPERATION_RESULT_PENDING" : observed.code,
246
+ ...terminal ? { result: observed.output } : {}
247
+ });
248
+ } catch (error) {
249
+ const failure = port.classify?.(error) ?? { code: safeCode(error, "OPERATION_OBSERVATION_FAILED"), disposition: "unknown" };
250
+ journal.diagnostic({ operationId: record.id, boardId: record.boardId, itemId: record.itemId, stage: "operation." + record.action, result: "failure", code: failure.code, durationMs: Date.now() - started });
251
+ return save(options, {
252
+ ...record,
253
+ phase: failure.disposition === "retry-unstarted" ? "prepared" : failure.disposition === "terminal" ? "settled" : record.phase,
254
+ state: failure.disposition === "terminal" ? "failed" : "unknown",
255
+ code: failure.code,
256
+ ...failure.result !== void 0 ? { result: failure.result } : {}
257
+ });
258
+ }
259
+ }
260
+ async function save({ journal, key, port, record }, next) {
261
+ const saved = await journal.update(key, (current) => {
262
+ requireValue(current?.fingerprint === record.fingerprint, "OPERATION_IDENTITY_CONFLICT");
263
+ return current.phase === "settled" ? current : JSON.stringify(current) === JSON.stringify(next) ? current : next;
264
+ });
265
+ await port.report?.(saved);
266
+ return saved;
267
+ }
268
+
269
+ // src/runtime/collaboration.ts
270
+ var KanbanCollaboration = class {
271
+ constructor(service, journal) {
272
+ this.service = service;
273
+ this.journal = journal;
274
+ }
275
+ async prepareFix(boardId, request, prepare) {
276
+ requireValue(/^[\w-]{1,128}$/.test(request.operationId), "INVALID_OPERATION_ID");
277
+ const board = await this.service.read(boardId), item = (await this.service.item(boardId, request.itemId)).item;
278
+ requireValue(!board.lifecycle, "BOARD_STOPPING");
279
+ requireValue(item.deletedAt === void 0, "ITEM_DELETED");
280
+ requireValue(item.launch?.admittedAt !== void 0 || ["claimed", "review", "completed"].includes(item.status), "FIX_REQUIRES_STARTED_TASK");
281
+ const id = await this.journal.update("fix-operation:" + boardId + ":" + request.operationId, (old) => old ?? randomUUID());
282
+ let fix = await this.journal.get("fix:" + id);
283
+ requireValue(!fix || fix.boardId === boardId && fix.itemId === item.id, "IDEMPOTENCY_CONFLICT");
284
+ if (!fix) {
285
+ requireValue(board.automation, "FIX_PREPARATION_UNAVAILABLE");
286
+ const prepared = await prepare({ id, board, item });
287
+ const dispatch = {
288
+ id,
289
+ itemId: item.id,
290
+ itemRevision: item.revision,
291
+ planId: id,
292
+ planRevision: 1,
293
+ principal: board.automation.worker,
294
+ definitionDigest: sha256HexSync(JSON.stringify(prepared.context)),
295
+ attempt: 1,
296
+ fence: id,
297
+ preparedAt: Date.now(),
298
+ outcome: "prepared",
299
+ inputs: {}
300
+ };
301
+ fix = await this.journal.update("fix:" + id, (old) => old ?? {
302
+ id,
303
+ boardId,
304
+ itemId: item.id,
305
+ sessionId: id,
306
+ state: "clarifying",
307
+ phase: "prepared",
308
+ dispatch,
309
+ item: structuredClone(item),
310
+ resourceId: prepared.resourceId,
311
+ context: prepared.context,
312
+ request: null
313
+ });
314
+ }
315
+ await this.journal.update("fix-index", (old) => old?.includes(id) ? old : [...old ?? [], id]);
316
+ return fix;
317
+ }
318
+ async fix(id) {
319
+ const fix = await this.journal.get("fix:" + id);
320
+ requireValue(fix, "FIX_NOT_FOUND");
321
+ await this.service.item(fix.boardId, fix.itemId);
322
+ return fix;
323
+ }
324
+ async confirmFix(id, snapshot) {
325
+ const fix = await this.fix(id);
326
+ requireValue(!["cancelling", "cancelled"].includes(fix.state), "FIX_INPUT_CLOSED");
327
+ return this.journal.update("fix:" + id, (old) => {
328
+ requireValue(old && !["cancelling", "cancelled"].includes(old.state), "FIX_INPUT_CLOSED");
329
+ requireValue(!old.snapshot || old.snapshot.messageId === snapshot.messageId && old.snapshot.digest === snapshot.digest, "FIX_INPUT_CLOSED");
330
+ return old.snapshot ? old : { ...old, snapshot: structuredClone(snapshot), state: "frozen" };
331
+ });
332
+ }
333
+ async acceptFix(id, policy, deliver) {
334
+ const fix = await this.fix(id), snapshot = fix.snapshot;
335
+ requireValue(snapshot, "FIX_PROPOSAL_REQUIRED");
336
+ requireValue(!["cancelling", "cancelled"].includes(fix.state), "FIX_INPUT_CLOSED");
337
+ const board = await this.service.read(fix.boardId);
338
+ requireValue(!board.workTypes?.length || board.workTypes.some((type) => type.id === policy.kind && type.executable), "FIX_WORK_TYPE_REQUIRED");
339
+ await this.publishFix(fix);
340
+ await journalCommand(this.journal, this.service, fix.boardId, "fix-create:" + fix.id, {
341
+ type: "create-item",
342
+ item: {
343
+ id: snapshot.operationId,
344
+ title: snapshot.definition.title,
345
+ responsibility: snapshot.definition.responsibility,
346
+ acceptance: snapshot.definition.acceptance,
347
+ externalRefs: fix.item.externalRefs?.filter((ref) => policy.inheritSystems.includes(ref.system))
348
+ },
349
+ planning: { kind: policy.kind, priority: fix.item.planning?.priority ?? 2, dependencies: snapshot.definition.dependencies, references: [] }
350
+ });
351
+ await deliver(fix);
352
+ await this.journal.update("fix:" + id, (old) => ({ ...old, accepted: true, state: "accepted", createdItemId: snapshot.operationId }));
353
+ }
354
+ async publishFix(fix) {
355
+ const snapshot = fix.snapshot, envelope = {
356
+ schema: "kanban.fix/1",
357
+ version: 1,
358
+ operationId: snapshot.operationId,
359
+ sourceSessionId: fix.sessionId,
360
+ confirmation: { messageId: snapshot.messageId, content: snapshot.content, digest: snapshot.digest },
361
+ board: { id: fix.boardId },
362
+ resource: { id: fix.resourceId },
363
+ ...snapshot.definition
364
+ };
365
+ await this.journal.update("fix-definition:" + fix.id, (old) => {
366
+ requireValue(!old || JSON.stringify(old) === JSON.stringify(envelope), "FIX_DEFINITION_CHANGED");
367
+ return old ?? envelope;
368
+ });
369
+ }
370
+ async decisionSnapshot(identity) {
371
+ await this.service.read(identity.sourceBoardId);
372
+ const runs = await this.journal.get("record-runs:" + identity.sourceBoardId);
373
+ const record = runs?.find((run) => run.id === identity.runId)?.record ?? await this.service.record(identity.sourceBoardId, identity.recordId);
374
+ requireValue(record.id === identity.recordId && record.revision === identity.recordRevision, "FIX_DECISION_REVISION_UNAVAILABLE");
375
+ return record;
376
+ }
377
+ };
378
+ async function collaborationRelations(journal, boardId, itemId) {
379
+ const analyses = await analysisHistory(journal, boardId, itemId);
380
+ const replies = await journal.findForBoard("task-reply:", boardId, (row) => row.request.itemId === itemId && row.phase !== "cancelled");
381
+ const activeReplies = [];
382
+ for (const { value } of replies) if (!await journal.get("task-reply-cancelled:" + value.request.operationId)) activeReplies.push({ operationId: value.request.operationId, executionId: value.sessionId });
383
+ return { planning: analyses.map((job) => ({ id: job.id, request: job.input })), replies: activeReplies };
384
+ }
385
+ export {
386
+ KanbanAutomationJournal,
387
+ KanbanCollaboration,
388
+ KanbanWorkLog,
389
+ adoptDecomposition,
390
+ advanceRecordControl,
391
+ analysisHistory,
392
+ analysisSignature,
393
+ analysisStatus,
394
+ analyzeItem,
395
+ assembleKanbanRuntime,
396
+ boardDeletionBlockers,
397
+ cancelTaskMaintenance,
398
+ cancelTaskReplies,
399
+ collaborationRelations,
400
+ completeCompositePlans,
401
+ coordinateOperation,
402
+ createBoardDeletion,
403
+ createKanbanAutomation,
404
+ createRecordExecution,
405
+ createTaskFix,
406
+ defaultReferences,
407
+ deletionPreview,
408
+ dependencyResults,
409
+ drainBoardAnalyses,
410
+ journalCommand,
411
+ parseAnalysis,
412
+ recordControlKey,
413
+ requestRecordControl,
414
+ safeCode,
415
+ scanBoardStopWork,
416
+ scanTaskControls,
417
+ taskReplies,
418
+ validateResourceReferences,
419
+ validateSubtasks,
420
+ withBoardDeletion,
421
+ workContext
422
+ };
423
+ //# sourceMappingURL=integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/runtime/task-fix.ts","../../src/runtime/task-replies.ts","../../src/runtime/operation-runner.ts","../../src/runtime/collaboration.ts"],"sourcesContent":["import {journalCommand} from './journal-command';\nimport type {KanbanFixSession} from '../contracts';\nimport type {KanbanExecutionPort} from '../execution';\nimport type {KanbanFixOptions,SavedFix} from './task-fix-ports';\nimport {requireValue} from '../rules';\nimport {safeCode} from './diagnostics';\nexport interface KanbanTaskFix<Instruction> {\n fixTask(board:string,request:{itemId:string;operationId:string}):Promise<KanbanFixSession>;\n taskFixes(board:string,item:string):Promise<KanbanFixSession[]>;\n cancelFix(board:string,request:{fixId:string;operationId:string}):Promise<KanbanFixSession>;\n intercept(session:string,input:Instruction):Promise<boolean>;\n scan():Promise<void>;\n quiesce():Promise<void>;\n}\nexport function createTaskFix<Instruction>(options:KanbanFixOptions<Instruction>):KanbanTaskFix<Instruction> {return new TaskFix(options);}\n/** Confirmation and admission use durable identities; Session observation cannot create another task. */\nclass TaskFix<Instruction> {\n private stopping=false;\n private readonly executor:KanbanExecutionPort;\n private readonly pending = new Map<string, Promise<unknown>>();\n private serial<T>(id: string, run: () => Promise<T>): Promise<T> {\n requireValue(!this.stopping,'SERVICE_STOPPING');\n const next = (this.pending.get(id) ?? Promise.resolve()).catch(() => {}).then(run);\n this.pending.set(id, next);\n void next.finally(() => {if (this.pending.get(id) === next) this.pending.delete(id);}).catch(() => {});\n return next;\n }\n constructor(private readonly options:KanbanFixOptions<Instruction>) {this.executor=options.executor;}\n private async prepare(fix:SavedFix):Promise<SavedFix> {\n if(fix.request)return fix;\n const work=await this.executor.prepare(fix.dispatch,fix.item);\n return this.options.journal.update<SavedFix>('fix:'+fix.id,old=>({...old!,request:old!.request??work}));\n }\n private async advance(fix:SavedFix):Promise<KanbanFixSession> {\n const {options}=this;\n fix = (await options.journal.get<SavedFix>('fix:' + fix.id))!;\n if (fix.state === 'cancelling') return this.stop(fix);\n if (fix.state === 'cancelled') return view(fix);\n if (fix.phase === 'prepared' && (await options.service.read(fix.boardId)).lifecycle) return view(fix);\n fix=await this.prepare(fix);\n if(fix.snapshot) {await options.accept(fix);return view((await options.journal.get<SavedFix>('fix:'+fix.id))!);}\n const claimed=await options.journal.claim('fix:'+fix.id);\n const observation=await (claimed?this.executor.start(fix.request):this.executor.inspect(fix.request));\n const sessionId=observation.executionSessionId??fix.sessionId;\n if(sessionId!==fix.id)await options.journal.update('fix-session:'+sessionId,old=>old??fix.id);\n const saved=await options.journal.update<SavedFix>('fix:'+fix.id,old=>({...old!,sessionId,code:observation.code}));\n await options.observe(saved);return view(saved);\n }\n fixTask=async(boardId:string,request:{itemId:string;operationId:string}):Promise<KanbanFixSession>=>{\n requireValue(!this.stopping,'SERVICE_STOPPING');\n const fix = await this.options.freeze(boardId,request); return this.serial(fix.id, () => this.advance(fix));\n };\n taskFixes = async (boardId: string, itemId: string): Promise<KanbanFixSession[]> => {\n await this.options.service.item(boardId, itemId);\n return (await this.options.journal.findForBoard<SavedFix>('fix:', boardId, fix => fix.itemId === itemId)).map(row => view(row.value));\n };\n cancelFix = async (boardId: string, request: {fixId: string; operationId: string}): Promise<KanbanFixSession> => this.serial(request.fixId, async () => {\n requireValue(/^[\\w-]{1,128}$/.test(request.operationId), 'INVALID_OPERATION_ID');\n const board = await this.options.service.read(boardId), actor = await this.options.service.currentPrincipal();\n requireValue(actor.kind === 'human' && board.members?.some(m => m.kind === actor.kind && m.id === actor.id && m.roles?.includes('coordinator')), 'COORDINATOR_REQUIRED');\n const fix = await this.options.journal.update<SavedFix>('fix:' + request.fixId, old => {\n requireValue(old?.boardId === boardId, 'FIX_NOT_FOUND');\n requireValue(!old.accepted, 'FIX_ALREADY_ACCEPTED');\n return {...old, state: old.state === 'cancelled' ? 'cancelled' : 'cancelling', cancelOperationId: old.cancelOperationId ?? request.operationId};\n });\n return fix.state === 'cancelled' ? view(fix) : this.stop(fix);\n });\n private async stop(fix: SavedFix): Promise<KanbanFixSession> {\n const started = Date.now();\n try {\n let stopped = fix.phase === 'prepared' || fix.phase === 'settled';\n if (!stopped) stopped = await this.options.control.control({executionId:fix.id,operationId:fix.cancelOperationId!,action:'cancel'}) === 'cancelled';\n if (stopped && fix.snapshot) stopped = await this.stopCreatedTask(fix);\n const saved = await this.options.journal.update<SavedFix>('fix:' + fix.id, old => ({...old!, state: stopped ? 'cancelled' : 'cancelling', ...(stopped ? {phase: 'settled' as const} : {}), code: undefined}));\n this.options.log({operationId: fix.cancelOperationId!, boardId: fix.boardId, stage: 'fix.cancel', result: 'success', durationMs: Date.now() - started});\n return view(saved);\n } catch (error) {\n const code = safeCode(error, 'FIX_CANCEL_UNKNOWN');\n await this.options.journal.update<SavedFix>('fix:' + fix.id, old => ({...old!, code}));\n this.options.log({operationId: fix.cancelOperationId!, boardId: fix.boardId, stage: 'fix.cancel', result: 'failure', code, durationMs: Date.now() - started});\n throw error;\n }\n }\n private async stopCreatedTask(fix: SavedFix): Promise<boolean> {\n let item;\n try {item = (await this.options.service.item(fix.boardId, fix.snapshot!.operationId)).item;}\n catch (error) {if ((error as {code?: string}).code === 'ITEM_NOT_FOUND') return true; throw error;}\n if (['completed','cancelled'].includes(item.status)) return true;\n const controlId = 'fix-cancel-' + fix.id;\n await journalCommand(this.options.journal, this.options.service, fix.boardId, controlId,\n {type:'request-control', itemId:item.id, controlId, action:'cancel'});\n return false;\n }\n intercept=async(sessionId:string,input:Instruction):Promise<boolean>=>{\n const id=await this.options.journal.get<string>('fix-session:'+sessionId);if(!id)return false;\n return this.serial(id, async () => {\n const current = (await this.options.journal.get<SavedFix>('fix:' + id))!;\n requireValue(!['cancelling','cancelled'].includes(current.state), 'FIX_INPUT_CLOSED');\n return this.options.confirm(current,input);\n });\n };\n quiesce=async()=>{this.stopping=true;await Promise.allSettled([...this.pending.values()]);};\n scan=async()=>{\n for(const id of await this.options.journal.get<string[]>('fix-index')??[]) {\n if(this.stopping)return;\n const fix=await this.options.journal.get<SavedFix>('fix:'+id);if(!fix||fix.accepted||fix.state==='cancelled')continue;\n try {await this.serial(id, () => this.advance(fix));} catch(error) {this.options.log({operationId:id,boardId:fix.boardId,stage:'fix.recover',result:'failure',code:safeCode(error,'FIX_RECOVERY_FAILED'),durationMs:0});}\n }\n };\n}\nfunction view(fix:SavedFix):KanbanFixSession {const {id,boardId,itemId,sessionId,state,createdItemId,code}=fix;return {id,boardId,itemId,sessionId,state,createdItemId,code};}\n","import type {KanbanClient,KanbanItem,KanbanDispatch} from '../contracts';\nimport type {KanbanAutomationJournal} from './automation-journal';\nimport {requireValue} from '../rules';\nexport interface KanbanTaskReply {itemId:string;attemptId:string;replyTo:string;operationId:string;content:string}\nexport type FrozenReply<T=unknown> = T & {phase?:'prepared'|'submitting'|'cancelling'|'cancelled';boardId:string;request:KanbanTaskReply;sessionId:string};\nexport interface KanbanReplyPort<T> {\n prepare(input:{boardId:string;request:KanbanTaskReply;item:KanbanItem;dispatch:KanbanDispatch}):Promise<T & {sessionId:string}>;\n deliver(reply:FrozenReply<T>):Promise<void>;\n}\n/** The durable Session queue carries correlated user input without a workspace mailbox. */\nexport function taskReplies<T>(service:KanbanClient,journal:KanbanAutomationJournal,port:KanbanReplyPort<T>) {\n const replyTask=async(boardId:string,request:KanbanTaskReply):Promise<void>=>{\n requireValue(/^[\\w-]{1,96}$/.test(request.operationId)&&typeof request.content==='string'&&!!request.content.trim()&&request.content.length<=8000,'WORKSPACE_REPLY_INVALID');\n await service.item(boardId,request.itemId);\n const old=await journal.get<FrozenReply<T>>('task-reply:'+request.operationId);\n requireValue(!old||old.boardId===boardId&&JSON.stringify(old.request)===JSON.stringify(request),'IDEMPOTENCY_CONFLICT');\n if(await journal.get('task-reply-delivered:'+request.operationId))return;\n const frozen=await freezeReply(service,journal,port,boardId,request);\n await journal.update<string[]>('task-reply-index',previous=>previous?.includes(request.operationId)?previous:[...previous??[],request.operationId]);\n const claimed = await journal.claim('task-reply:' + request.operationId);\n const current = (await journal.get<FrozenReply<T>>('task-reply:' + request.operationId))!;\n if (current.phase === 'cancelled' || current.phase === 'cancelling') return;\n if (claimed || current.phase === 'submitting' || current.phase === undefined) await port.deliver(frozen);\n await journal.update('task-reply-delivered:'+request.operationId,()=>true);\n };\n return Object.assign(replyTask,{async scan(){\n for(const id of await journal.get<string[]>('task-reply-index')??[]) {\n if(await journal.get('task-reply-delivered:'+id)||await journal.get('task-reply-cancelled:'+id))continue;\n const saved=await journal.get<FrozenReply<T>>('task-reply:'+id);if(saved&&!['cancelling','cancelled'].includes(saved.phase??'') && !(await service.read(saved.boardId)).lifecycle)await replyTask(saved.boardId,saved.request);\n }\n }});\n}\nasync function freezeReply<T>(service:KanbanClient,journal:KanbanAutomationJournal,port:KanbanReplyPort<T>,boardId:string,request:KanbanTaskReply):Promise<FrozenReply<T>> {\n const {item}=await service.item(boardId,request.itemId);\n requireValue(item.deletedAt===undefined&&item.control?.action!=='cancel','TASK_CANCELLING');\n const workflow=await service.workflow(boardId),dispatch=workflow.dispatches[request.attemptId];\n requireValue(dispatch?.itemId===item.id&&item.owner?.token===dispatch.fence&&['prepared','running','unknown'].includes(dispatch.outcome),'STALE_EXECUTION_RESULT');\n requireValue(item.issues?.some(issue=>issue.id===request.replyTo&&issue.attemptId===request.attemptId&&!issue.resolvedBy),'ISSUE_NOT_FOUND');\n const previous=await journal.get<FrozenReply<T>>('task-reply:'+request.operationId);\n if(previous)return previous;\n const prepared=await port.prepare({boardId,request,item,dispatch});\n return journal.update<FrozenReply<T>>('task-reply:'+request.operationId,old=>{\n requireValue(!old||old.boardId===boardId&&JSON.stringify(old.request)===JSON.stringify(request),'IDEMPOTENCY_CONFLICT');\n return old??{...prepared,phase:'prepared',boardId,request:structuredClone(request)};\n });\n}\n","import type {KanbanClient} from '../contracts';\nimport type {KanbanAutomationJournal} from './automation-journal';\nimport type {KanbanOperationRecord,KanbanOperationPort} from './operation-contracts';\nimport {requireValue} from '../rules';\nimport {safeCode} from './diagnostics';\ninterface Options<T extends KanbanOperationRecord> {\n service:Pick<KanbanClient,'read'>;journal:KanbanAutomationJournal;key:string;record:T;port:KanbanOperationPort<T>;\n}\n/** A frozen record crosses the submission boundary once; response loss only triggers inspection. */\nexport async function coordinateOperation<T extends KanbanOperationRecord>(options:Options<T>):Promise<T> {\n const {journal,key,port}=options;let record=await journal.get<T>(key)??options.record;\n requireValue(record.fingerprint===options.record.fingerprint,'OPERATION_IDENTITY_CONFLICT');\n if(record.phase==='settled'||record.phase==='prepared'&&(await options.service.read(record.boardId)).lifecycle)return record;\n const started=Date.now();\n try {\n if(record.phase==='prepared') {\n if(!await journal.claim(key))return (await journal.get<T>(key))!;\n record={...record,phase:'submitting'};await port.start(record);\n }\n const observed=await port.inspect(record);\n const waiting=observed.state==='succeeded'&&observed.output===undefined;\n if(observed.state==='succeeded'&&!waiting)await port.validate?.(record,observed.output);\n const terminal=!waiting&&['succeeded','failed'].includes(observed.state);\n return await save(options,{...record,phase:terminal?'settled':record.phase,\n state:waiting?'unknown':observed.state,sessionId:observed.executionId,\n code:waiting?'OPERATION_RESULT_PENDING':observed.code,...(terminal?{result:observed.output}:{})});\n }catch(error) {\n const failure=port.classify?.(error)??{code:safeCode(error,'OPERATION_OBSERVATION_FAILED'),disposition:'unknown'};\n journal.diagnostic({operationId:record.id,boardId:record.boardId,itemId:record.itemId,stage:'operation.'+record.action,result:'failure',code:failure.code,durationMs:Date.now()-started});\n return save(options,{...record,phase:failure.disposition==='retry-unstarted'?'prepared':failure.disposition==='terminal'?'settled':record.phase,\n state:failure.disposition==='terminal'?'failed':'unknown',code:failure.code,...(failure.result!==undefined?{result:failure.result}:{})});\n }\n}\nasync function save<T extends KanbanOperationRecord>({journal,key,port,record}:Options<T>,next:T):Promise<T> {\n const saved=await journal.update<T>(key,current=>{\n requireValue(current?.fingerprint===record.fingerprint,'OPERATION_IDENTITY_CONFLICT');\n return current.phase==='settled'?current:JSON.stringify(current)===JSON.stringify(next)?current:next;\n });\n await port.report?.(saved);return saved;\n}\n","import type {KanbanClient,KanbanBoard,KanbanItem,KanbanDispatch,KanbanProjectRecord} from '../contracts';\nimport type {KanbanAutomationJournal} from './automation-journal';\nimport type {SavedFix,Snapshot} from './task-fix-ports';\nimport {journalCommand} from './journal-command';\nimport {analysisHistory,type AnalysisJournalEntry} from './analysis-history';\nimport {randomUUID,sha256HexSync} from '../utils';\nimport {requireValue} from '../rules';\nexport interface KanbanFixPreparation {resourceId:string;context:unknown}\nexport class KanbanCollaboration {\n constructor(private readonly service:KanbanClient,private readonly journal:KanbanAutomationJournal) {}\n async prepareFix(boardId:string,request:{itemId:string;operationId:string},prepare:(input:{id:string;board:KanbanBoard;item:KanbanItem})=>Promise<KanbanFixPreparation>):Promise<SavedFix> {\n requireValue(/^[\\w-]{1,128}$/.test(request.operationId),'INVALID_OPERATION_ID');\n const board=await this.service.read(boardId),item=(await this.service.item(boardId,request.itemId)).item;\n requireValue(!board.lifecycle,'BOARD_STOPPING');requireValue(item.deletedAt===undefined,'ITEM_DELETED');\n requireValue(item.launch?.admittedAt!==undefined||['claimed','review','completed'].includes(item.status),'FIX_REQUIRES_STARTED_TASK');\n const id=await this.journal.update<string>('fix-operation:'+boardId+':'+request.operationId,old=>old??randomUUID());\n let fix=await this.journal.get<SavedFix>('fix:'+id);\n requireValue(!fix||fix.boardId===boardId&&fix.itemId===item.id,'IDEMPOTENCY_CONFLICT');\n if(!fix) {\n requireValue(board.automation,'FIX_PREPARATION_UNAVAILABLE');\n const prepared=await prepare({id,board,item});\n const dispatch:KanbanDispatch={id,itemId:item.id,itemRevision:item.revision,planId:id,planRevision:1,principal:board.automation.worker,\n definitionDigest:sha256HexSync(JSON.stringify(prepared.context)),attempt:1,fence:id,preparedAt:Date.now(),outcome:'prepared',inputs:{}};\n fix=await this.journal.update<SavedFix>('fix:'+id,old=>old??{id,boardId,itemId:item.id,sessionId:id,state:'clarifying',phase:'prepared',dispatch,item:structuredClone(item),\n resourceId:prepared.resourceId,context:prepared.context,request:null});\n }\n await this.journal.update<string[]>('fix-index',old=>old?.includes(id)?old:[...old??[],id]);return fix;\n }\n async fix(id:string):Promise<SavedFix> {\n const fix=await this.journal.get<SavedFix>('fix:'+id);requireValue(fix,'FIX_NOT_FOUND');\n await this.service.item(fix.boardId,fix.itemId);return fix;\n }\n async confirmFix(id:string,snapshot:Snapshot):Promise<SavedFix> {\n const fix=await this.fix(id);requireValue(!['cancelling','cancelled'].includes(fix.state),'FIX_INPUT_CLOSED');\n return this.journal.update<SavedFix>('fix:'+id,old=>{\n requireValue(old&&!['cancelling','cancelled'].includes(old.state),'FIX_INPUT_CLOSED');\n requireValue(!old.snapshot||old.snapshot.messageId===snapshot.messageId&&old.snapshot.digest===snapshot.digest,'FIX_INPUT_CLOSED');\n return old.snapshot?old:{...old,snapshot:structuredClone(snapshot),state:'frozen'};\n });\n }\n async acceptFix(id:string,policy:{kind:string;inheritSystems:string[]},deliver:(fix:SavedFix)=>Promise<void>):Promise<void> {\n const fix=await this.fix(id),snapshot=fix.snapshot;requireValue(snapshot,'FIX_PROPOSAL_REQUIRED');\n requireValue(!['cancelling','cancelled'].includes(fix.state),'FIX_INPUT_CLOSED');\n const board=await this.service.read(fix.boardId);\n requireValue(!board.workTypes?.length||board.workTypes.some(type=>type.id===policy.kind&&type.executable),'FIX_WORK_TYPE_REQUIRED');\n await this.publishFix(fix);\n await journalCommand(this.journal,this.service,fix.boardId,'fix-create:'+fix.id,{type:'create-item',item:{id:snapshot.operationId,\n title:snapshot.definition.title,responsibility:snapshot.definition.responsibility,acceptance:snapshot.definition.acceptance,\n externalRefs:fix.item.externalRefs?.filter(ref=>policy.inheritSystems.includes(ref.system))},\n planning:{kind:policy.kind,priority:fix.item.planning?.priority??2,dependencies:snapshot.definition.dependencies,references:[]}});\n await deliver(fix);\n await this.journal.update<SavedFix>('fix:'+id,old=>({...old!,accepted:true,state:'accepted',createdItemId:snapshot.operationId}));\n }\n private async publishFix(fix:SavedFix):Promise<void> {\n const snapshot=fix.snapshot!,envelope={schema:'kanban.fix/1',version:1,operationId:snapshot.operationId,sourceSessionId:fix.sessionId,\n confirmation:{messageId:snapshot.messageId,content:snapshot.content,digest:snapshot.digest},board:{id:fix.boardId},resource:{id:fix.resourceId},...snapshot.definition};\n await this.journal.update('fix-definition:'+fix.id,old=>{requireValue(!old||JSON.stringify(old)===JSON.stringify(envelope),'FIX_DEFINITION_CHANGED');return old??envelope;});\n }\n async decisionSnapshot(identity:{sourceBoardId:string;recordId:string;recordRevision:number;runId:string}):Promise<KanbanProjectRecord> {\n await this.service.read(identity.sourceBoardId);\n const runs=await this.journal.get<Array<{id:string;record:KanbanProjectRecord}>>('record-runs:'+identity.sourceBoardId);\n const record=runs?.find(run=>run.id===identity.runId)?.record??await this.service.record(identity.sourceBoardId,identity.recordId);\n requireValue(record.id===identity.recordId&&record.revision===identity.recordRevision,'FIX_DECISION_REVISION_UNAVAILABLE');return record;\n }\n\n}\n/** Adapter requests remain opaque; relation projection does not expose journal layouts. */\nexport async function collaborationRelations<Input=unknown>(journal:KanbanAutomationJournal,boardId:string,itemId:string) {\n const analyses=await analysisHistory<AnalysisJournalEntry & {input:Input}>(journal,boardId,itemId);\n const replies=await journal.findForBoard<{sessionId:string;phase?:string;request:{itemId:string;operationId:string}}>('task-reply:',boardId,row=>row.request.itemId===itemId&&row.phase!=='cancelled');\n const activeReplies:Array<{operationId:string;executionId:string}>=[];\n for(const {value} of replies)if(!await journal.get('task-reply-cancelled:'+value.request.operationId))activeReplies.push({operationId:value.request.operationId,executionId:value.sessionId});\n return {planning:analyses.map(job=>({id:job.id,request:job.input})),replies:activeReplies};\n}\n"],"mappings":"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","names":[]}