@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
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-L44TM4EE.cjs","../src/planning.ts","../src/amendments.ts","../src/project-records.ts","../src/board.ts","../src/storage-codec.ts","../src/numbering.ts","../src/archives.ts","../src/planning-commands.ts","../src/workflow-plans.ts","../src/task-commands.ts","../src/board-control.ts","../src/scan-commit.ts","../src/automation.ts","../src/workflow-continuation.ts","../src/workflow.ts","../src/transitions.ts","../src/reducer.ts"],"names":["plan","append"],"mappings":"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;AACM,EAAA;AACZ,EAAA;AACZ,EAAA;AACQ,EAAA;AACe,EAAA;AACF,EAAA;AACL,EAAA;AACU,EAAA;AACV,EAAA;AAC9D,EAAA;AACX;AAEoF;AACN,EAAA;AACG,EAAA;AACH,EAAA;AACA,EAAA;AACE,EAAA;AACH,EAAA;AACE,EAAA;AACV,EAAA;AACK,EAAA;AAChC,EAAA;AAAuC,IAAA;AACR,IAAA;AAAuF,EAAA;AACjF,EAAA;AACI,EAAA;AACP,EAAA;AACN,EAAA;AACE,EAAA;AACF,EAAA;AACG,EAAA;AACQ,EAAA;AACP,EAAA;AAC9D,EAAA;AACZ;AAEoH;AACzG,EAAA;AAAmD,IAAA;AAA2E,IAAA;AAC5D,IAAA;AAA0O,EAAA;AACvT;AAE4G;AAC1D,EAAA;AAC8B,EAAA;AACD,EAAA;AACR,EAAA;AACjD,EAAA;AAAW,EAAA;AACoB,EAAA;AACL,EAAA;AACS,EAAA;AAC9C,EAAA;AACX;AjBoxCkF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-L44TM4EE.cjs","sourcesContent":[null,"import type {KanbanItem, KanbanItemSummary, KanbanPlanning} from './contracts';\nimport type {KanbanState} from './ports';\nimport {workType, executable} from './configuration';\nimport {identity, requireValue, text} from './rules';\n\nexport function plan(item: KanbanItem): KanbanPlanning {\n return item.planning ?? {kind: 'task', priority: 2, dependencies: [], references: []};\n}\nexport function summary(item: KanbanItem): KanbanItemSummary {\n return {launch:item.launch, analysis:item.analysis, control:item.control, issues:item.issues, blocked:item.blocked, id: item.id, number: item.number, title: item.title, status: item.status, revision: item.revision, createdAt: item.createdAt,\n updatedAt: item.updatedAt, discoveryFingerprint: item.origin?.fingerprint, pendingAmendments: item.amendments?.filter(proposal => proposal.status === 'pending').length, externalRefs: item.externalRefs, closedAt: item.closedAt, planning: plan(item), sessionIds: item.participants.map(p => p.sessionId)};\n}\nexport function terminal(item: Pick<KanbanItem, 'status'>): boolean {return item.status === 'completed' || item.status === 'cancelled';}\nexport function catalog(state: KanbanState): KanbanItemSummary[] {return [...state.board.items.map(summary), ...(state.archiveIndex ?? [])];}\nexport function limits(state: KanbanState) {\n const p = state.board.policy;\n return {ready: p.maxReady ?? 20, inProgress: p.maxInProgress ?? 3, perAgent: p.maxInProgressPerAssignee ?? p.maxInProgressPerAgent ?? 1, perAssignee: p.maxInProgressPerAssignee ?? p.maxInProgressPerAgent ?? 1};\n}\nexport function validatePlan(state: KanbanState, item: KanbanItem, value: KanbanPlanning): void {\n requireValue(typeof value.kind === 'string' && Number.isInteger(value.priority) && value.priority >= 0 && value.priority <= 4, 'INVALID_PLANNING');\n requireValue(Array.isArray(value.dependencies) && value.dependencies.length <= 100 && Array.isArray(value.references) && value.references.length <= 100, 'PLANNING_LIMIT');\n value.dependencies.forEach(identity); value.references.forEach(text);\n if (value.area !== undefined) identity(value.area); if (value.milestone !== undefined) identity(value.milestone);\n requireValue(value.execution===undefined||['direct','children'].includes(value.execution),'INVALID_EXECUTION_MODE');\n const type = workType(state.board, value.kind);\n if (value.dueAt !== undefined) requireValue(Number.isFinite(value.dueAt) && value.dueAt >= 0, 'INVALID_DUE_DATE');\n const all = catalog(state), parent = all.find(i => i.id === value.parentId);\n if (value.parentId) {\n identity(value.parentId); requireValue(parent && !parent.archivedAt && !terminal(parent) && !['claimed','review'].includes(parent.status), 'PARENT_UNAVAILABLE');\n requireValue(parent.id !== item.id && workType(state.board, parent.planning.kind).rank < type.rank, 'INVALID_PARENT_KIND');\n }\n requireValue(value.execution==='children'||!all.some(child=>child.planning.parentId===item.id),'CHILDREN_REQUIRE_AGGREGATION');\n requireValue(!all.some(child => child.planning.parentId === item.id && workType(state.board, child.planning.kind).rank <= type.rank), 'INVALID_CHILD_KIND');\n for (const id of value.dependencies) requireValue(id !== item.id && all.some(i => i.id === id), 'INVALID_DEPENDENCY');\n const visited = new Set<string>(), pending = [...value.dependencies];\n while (pending.length) {\n const id = pending.pop()!; requireValue(id !== item.id, 'DEPENDENCY_CYCLE');\n if (visited.has(id)) continue; visited.add(id);\n pending.push(...(all.find(i => i.id === id)?.planning.dependencies ?? []));\n }\n}\nexport function assertReady(state: KanbanState, item: KanbanItem): void {\n requireValue(executable(state.board, item), 'PLAN_NOT_EXECUTABLE');\n requireValue(!item.blocked, 'ITEM_BLOCKED');\n const all = catalog(state);\n requireValue(plan(item).dependencies.every(id => all.find(i => i.id === id)?.status === 'completed'), 'DEPENDENCIES_UNFINISHED');\n}\nexport function setStage(state: KanbanState, item: KanbanItem, stage: 'backlog' | 'open', now: number): void {\n requireValue(['proposed', 'backlog', 'open'].includes(item.status), 'ITEM_NOT_PLANNABLE');\n requireValue(stage === 'backlog' || stage === 'open', 'INVALID_STAGE');\n if (stage === 'open') {\n assertReady(state, item);\n requireValue(item.status === 'open' || state.board.items.filter(i => i.status === 'open').length < limits(state).ready, 'READY_LIMIT');\n }\n item.status = stage; item.readyAt = now; item.updatedAt = now; item.revision++;\n}\n\nexport function automaticStage(state: KanbanState, item: KanbanItem): 'open' | 'backlog' {\n const all = catalog(state);\n const dependenciesComplete = plan(item).dependencies.every(id => all.find(i => i.id === id)?.status === 'completed');\n return executable(state.board, item) && !item.blocked && dependenciesComplete && state.board.items.filter(i => i.status === 'open').length < limits(state).ready ? 'open' : 'backlog';\n}\n","import {plan} from './planning';\nimport {sha256HexSync} from './utils';\nimport type {KanbanActor, KanbanBoard, KanbanCommand, KanbanDiscoveryChange, KanbanItem, KanbanText} from './contracts';\nimport {identity, requireValue, text} from './rules';\nimport {principal, principalKey} from './identity';\nexport const textOf = (item: KanbanText): KanbanText => ({title: item.title, responsibility: item.responsibility, acceptance: item.acceptance});\nexport const textDigest = (item: KanbanText): string => sha256HexSync(JSON.stringify(textOf(item)));\nexport function workFingerprint(item: KanbanItem): string {\n const planning = plan(item);\n return sha256HexSync(JSON.stringify({text: textOf(item), kind: planning.kind, parentId: planning.parentId ?? null,\n area: planning.area ?? null, milestone: planning.milestone ?? null, priority: planning.priority,\n dependencies: [...planning.dependencies].sort(), dueAt: planning.dueAt ?? null}));\n}\nexport function validateSources(sources: KanbanDiscoveryChange['sources']): void {\n requireValue(Array.isArray(sources) && sources.length <= 100, 'SOURCE_LIMIT');\n for (const source of sources) {\n identity(source.sessionId); identity(source.messageId); identity(source.revision);\n requireValue(source.role === 'user' || source.role === 'assistant', 'INVALID_SOURCE');\n }\n}\nexport function proposeAmendment(item: KanbanItem, change: KanbanDiscoveryChange, actor: KanbanActor, now: number, runId: string): void {\n text(change.title); text(change.responsibility); text(change.acceptance); validateSources(change.sources);\n const proposed = textOf(change), fingerprint = textDigest(proposed);\n if (textDigest(item) === fingerprint || item.amendments?.some(p => p.fingerprint === fingerprint)) return;\n requireValue((item.amendments?.length ?? 0) < 20, 'AMENDMENT_LIMIT');\n (item.amendments ??= []).push({runId, id: `amendment-${sha256HexSync(JSON.stringify([runId, item.id, fingerprint]))}`, fingerprint,\n baseRevision: item.revision, baseDigest: textDigest(item), proposed, proposedBy: principal(actor), sources: structuredClone(change.sources),\n createdAt: now, status: 'pending'});\n}\nexport function requireReviewer(board: KanbanBoard, actor: KanbanActor): void {\n const key = principalKey(principal(actor));\n requireValue(board.members?.some(m => principalKey(m) === key && m.roles?.some(role => role === 'coordinator' || role === 'reviewer')),\n 'REVIEWER_REQUIRED');\n}\nexport function reviewAmendment(board: KanbanBoard, command: Extract<KanbanCommand, {type: 'review-amendment'}>, actor: KanbanActor, now: number): void {\n requireReviewer(board, actor);\n const item = board.items.find(i => i.id === command.itemId), proposal = item?.amendments?.find(p => p.id === command.amendmentId);\n requireValue(item && proposal?.status === 'pending', 'AMENDMENT_NOT_PENDING');\n if (command.accept) {\n requireValue(principal(actor).kind === 'human' || principalKey(proposal.proposedBy) !== principalKey(principal(actor)), 'INDEPENDENT_REVIEW_REQUIRED');\n requireValue(['proposed', 'backlog', 'open'].includes(item.status), 'ITEM_NOT_PLANNABLE');\n requireValue(textDigest(item) === proposal.baseDigest, 'AMENDMENT_STALE');\n Object.assign(item, proposal.proposed);\n if (item.status === 'open') {item.status = 'backlog'; item.readyAt = now;}\n } else {requireValue(!!command.reason?.trim(), 'AMENDMENT_REASON_REQUIRED'); text(command.reason!);}\n proposal.status = command.accept ? 'accepted' : 'rejected'; proposal.reviewedAt = now; proposal.reviewedBy = principal(actor); proposal.reason = command.reason;\n item.updatedAt = now; item.revision++;\n}\n","import {sha256HexSync} from './utils';\nimport type {KanbanActor, KanbanCommand, KanbanProjectRecord, KanbanRecordPage, KanbanRecordQuery} from './contracts';\nimport type {KanbanState} from './ports';\nimport {identity, requireValue, text} from './rules';\nimport {principal, principalKey} from './identity';\nimport {requireReviewer, validateSources} from './amendments';\nexport type RecordCommand = Extract<KanbanCommand, {type: 'append-record' | 'review-record' | 'link-record'}>;\nexport function isRecordCommand(command: KanbanCommand): command is RecordCommand {\n return ['append-record', 'review-record', 'link-record'].includes(command.type);\n}\nexport function applyRecord(state: KanbanState, command: RecordCommand, actor: KanbanActor, now: number, forceDraft = false): void {\n if (command.type === 'append-record') {append(state, command, actor, now, forceDraft); return;}\n const record = state.records?.find(record => record.id === command.recordId); requireValue(record, 'RECORD_NOT_FOUND');\n if (command.type === 'link-record') {\n validateItems(state, [command.itemId]);\n if (!record.itemIds.includes(command.itemId)) {requireValue(record.itemIds.length < 100, 'RECORD_LINK_LIMIT'); record.itemIds.push(command.itemId);}\n } else {\n requireReviewer(state.board, actor); requireValue(record.status === 'draft', 'RECORD_NOT_DRAFT');\n if (command.accept) {\n requireValue(principal(actor).kind === 'human' || principalKey(record.author) !== principalKey(principal(actor)), 'INDEPENDENT_REVIEW_REQUIRED');\n supersede(state, record, now); record.status = 'confirmed';\n } else record.status = 'rejected';\n record.reviewedBy = principal(actor);\n }\n record.updatedAt = now; record.revision++;\n}\nfunction append(state: KanbanState, command: Extract<RecordCommand, {type: 'append-record'}>, actor: KanbanActor, now: number, forceDraft: boolean): void {\n validateSources(command.record.sources);\n const {id, kind, title, content, rationale, itemIds, sources, supersedes, coordination, externalRefs} = command.record;\n const input = structuredClone({id, kind, title, content, rationale, itemIds, sources: sources.map(source => ({sessionId: source.sessionId, messageId: source.messageId, revision: source.revision, role: source.role})), supersedes, ...(coordination ? {coordination}: {}), ...(externalRefs ? {externalRefs} : {})}); identity(input.id); text(input.title); text(input.content);\n validateRecordReferences(externalRefs);\n requireValue(input.kind === 'log' || input.kind === 'decision', 'INVALID_RECORD_KIND');\n requireValue(!state.records?.some(record => record.id === input.id), 'RECORD_EXISTS');\n requireValue((state.records?.length ?? 0) < 200, 'RECORD_LIMIT'); validateItems(state, input.itemIds); validateSources(input.sources);\n if (input.rationale !== undefined) text(input.rationale);\n if (input.kind === 'decision') text(input.rationale ?? '');\n if (coordination) validateCoordination(state, input);\n if (input.supersedes) {identity(input.supersedes); requireValue(input.kind === 'decision' && input.supersedes !== input.id\n && state.records?.some(record => record.id === input.supersedes && record.kind === 'decision' && record.status === 'confirmed'), 'INVALID_SUPERSEDED_RECORD');}\n const author = principal(actor), manual = author.kind === 'human' && !forceDraft;\n (state.records ??= []).push({...input, author, origin: manual ? 'manual' : 'flow',\n status: manual && input.kind === 'log' ? 'confirmed' : 'draft', revision: 1, createdAt: now, updatedAt: now});\n}\nfunction validateCoordination(state: KanbanState, input: import('./contracts').KanbanRecordInput): void {\n requireValue(input.kind === 'decision', 'DECISION_COORDINATION_ONLY');\n for (const owner of [input.coordination!.manager, input.coordination!.executor].filter(Boolean)) {\n requireValue(owner && ['agent','human','service'].includes(owner.kind), 'INVALID_PRINCIPAL');identity(owner.id);\n const member=state.board.members?.find(member=>principalKey(member)===principalKey(owner));\n requireValue(member, 'ASSIGNEE_NOT_REGISTERED');\n if(owner===input.coordination!.manager) requireValue(member.roles?.includes('coordinator'), 'COORDINATOR_REQUIRED');\n }\n}\nfunction validateItems(state: KanbanState, ids: string[]): void {\n requireValue(Array.isArray(ids) && ids.length <= 100 && new Set(ids).size === ids.length, 'RECORD_LINK_LIMIT');\n for (const id of ids) {identity(id); requireValue(state.board.items.some(item => item.id === id) || state.archiveIndex?.some(item => item.id === id), 'ITEM_NOT_FOUND');}\n}\nfunction supersede(state: KanbanState, record: KanbanProjectRecord, now: number): void {\n if (!record.supersedes) return;\n const previous = state.records?.find(entry => entry.id === record.supersedes);\n requireValue(previous?.kind === 'decision' && previous.status === 'confirmed', 'SUPERSEDED_RECORD_CHANGED');\n previous.status = 'superseded'; previous.supersededBy = record.id; previous.revision++; previous.updatedAt = now;\n}\nexport function queryRecords(state: KanbanState, query: KanbanRecordQuery = {}, summaries = (state.records ?? []).map(recordSummary)): KanbanRecordPage {\n const {cursor, ...filter} = query, limit = query.limit ?? 50;\n requireValue(Number.isSafeInteger(limit) && limit > 0 && limit <= 200, 'INVALID_LIMIT');\n if (query.kind) requireValue(['log', 'decision'].includes(query.kind), 'INVALID_RECORD_KIND');\n if (query.itemId !== undefined) identity(query.itemId);\n if (query.status) requireValue(['draft', 'confirmed', 'rejected', 'superseded'].includes(query.status), 'INVALID_RECORD_STATUS');\n const digest = sha256HexSync(JSON.stringify(filter)); let offset = 0;\n if (cursor) {\n let decoded; try {decoded = JSON.parse(decodeURIComponent(cursor));} catch {requireValue(false, 'INVALID_CURSOR');}\n requireValue(decoded && typeof decoded === 'object' && !Array.isArray(decoded) && typeof decoded.filter === 'string'\n && typeof decoded.revision === 'number', 'INVALID_CURSOR');\n requireValue(decoded.revision === state.board.revision && decoded.filter === digest, 'CURSOR_STALE');\n offset = decoded.offset; requireValue(Number.isSafeInteger(offset) && offset >= 0, 'INVALID_CURSOR');\n }\n const matched = summaries.filter(record => (!query.kind || query.kind === record.kind)\n && (!query.itemId || record.itemIds.includes(query.itemId)) && (!query.status || query.status === record.status))\n .sort((a, b) => b.createdAt - a.createdAt || a.id.localeCompare(b.id));\n const items = matched.slice(offset, offset + limit);\n return {revision: state.board.revision, total: matched.length, items, ...(offset + limit < matched.length\n ? {nextCursor: encodeURIComponent(JSON.stringify({revision: state.board.revision, filter: digest, offset: offset + limit}))} : {})};\n}\n\nexport function recordFingerprint(record: import('./contracts').KanbanRecordInput): string {\n return sha256HexSync(JSON.stringify({kind: record.kind, title: record.title, content: record.content, rationale: record.rationale ?? null,\n itemIds: [...record.itemIds].sort(), sources: record.sources.map(source => JSON.stringify([source.sessionId, source.messageId, source.role])).sort(), ...(record.coordination?{coordination:record.coordination}: {}), ...(record.externalRefs ? {externalRefs: record.externalRefs} : {})}));\n}\n\nfunction validateRecordReferences(refs: import('./contracts').KanbanExternalReference[] | undefined): void {\n if (refs === undefined) return;\n requireValue(Array.isArray(refs) && refs.length <= 100, 'REFERENCE_LIMIT');\n const keys = new Set<string>();\n for (const ref of refs) {\n requireValue(ref && typeof ref === 'object', 'INVALID_REFERENCE');\n identity(ref.system); identity(ref.id); if (ref.revision !== undefined) text(ref.revision);\n const key = JSON.stringify([ref.system, ref.id]);\n requireValue(!keys.has(key), 'DUPLICATE_REFERENCE'); keys.add(key);\n }\n}\n\nexport function recordSummary(record: KanbanProjectRecord): import('./contracts').KanbanRecordSummary {\n const {content: _content, rationale: _rationale, sources, ...metadata} = record;\n return {...metadata, sessionIds: [...new Set(sources.map(source => source.sessionId))]};\n}\n","import type {KanbanActor, KanbanBoardInput} from './contracts';\nimport type {KanbanState} from './ports';\nimport {policy} from './configuration';\nimport {participant, validateBoard} from './rules';\n\nexport function createBoardState(input: KanbanBoardInput, actor: KanbanActor, now: number): KanbanState {\n const board = {...structuredClone(input), policy: policy(input.policy), revision: 1, items: [], participants: []};\n validateBoard(board);\n if (actor.sessionId) participant(board.participants, actor.sessionId, actor.agentId, 'creator', true, now);\n for (const session of board.policy.escalationSessionIds) participant(board.participants, session, undefined, 'escalation', true, now);\n return {schema: 1, board, sequence: 0, events: [], escalations: []};\n}\n","import {randomUUID, sha256HexSync} from './utils';\nimport type {KanbanItem, KanbanProjectRecord} from './contracts';\nimport {summary} from './planning';\nimport {recordSummary} from './project-records';\nimport {KanbanError, type KanbanReadView, type KanbanState} from './ports';\nimport {requireValue} from './rules';\n\nexport interface KanbanBodyStore {\n read(sha256: string): Promise<ArrayBuffer | null>;\n write(sha256: string, bytes: ArrayBuffer): Promise<void>;\n}\ninterface Manifest {itemIndex: KanbanReadView['items']; recordIndex: KanbanReadView['records']; layout: 2; generation: string; state: KanbanState; itemIds: string[]; recordIds: string[]}\ninterface BodyRef {body: 'kanban-body/v1'; sha256: string; bytes: number}\nexport interface StoredBoard {raw: string | null; rows: Record<string, string>}\nexport const boardKey = (id: string): string => `board/${encodeURIComponent(id)}`;\nexport const archiveKey = (board: string, item: string): string => `archive/${encodeURIComponent(board)}/${encodeURIComponent(item)}`;\nconst rowKey = (kind: 'item' | 'record', board: string, id: string): string => `${kind}/${encodeURIComponent(board)}/${encodeURIComponent(id)}`;\n\nexport function rowKeys(raw: string | null): string[] {\n if (raw === null) return [];\n const saved = JSON.parse(raw) as Manifest;\n if (saved.layout !== 2) return [];\n requireValue(Array.isArray(saved.itemIds) && Array.isArray(saved.recordIds) && saved.state?.board, 'INVALID_STORAGE');\n return [...saved.itemIds.map(id => rowKey('item', saved.state.board.id, id)), ...saved.recordIds.map(id => rowKey('record', saved.state.board.id, id))];\n}\nexport async function hydrate(saved: StoredBoard, bodies?: KanbanBodyStore): Promise<KanbanState | null> {\n if (saved.raw === null) return null;\n const parsed = JSON.parse(saved.raw) as Manifest;\n if (parsed.layout !== 2) return validateState(parsed as unknown as KanbanState);\n const state = validateState(parsed.state), id = state.board.id;\n state.board.items = await Promise.all(parsed.itemIds.map(async itemId => {\n const item = await decodeRow<KanbanItem>(requiredRow(saved, rowKey('item', id, itemId)), bodies);\n requireValue(item.id === itemId, 'INVALID_STORAGE'); return item;\n }));\n state.records = await Promise.all(parsed.recordIds.map(async recordId => {\n const record = await decodeRow<KanbanProjectRecord>(requiredRow(saved, rowKey('record', id, recordId)), bodies);\n requireValue(record.id === recordId, 'INVALID_STORAGE'); return record;\n }));\n return state;\n}\nexport async function encodeBoard(state: KanbanState, bodies?: KanbanBodyStore): Promise<StoredBoard> {\n const rows: Record<string, string> = {}, id = state.board.id;\n for (const item of state.board.items) rows[rowKey('item', id, item.id)] = await encodeRow(item, bodies);\n for (const record of state.records ?? []) rows[rowKey('record', id, record.id)] = await encodeRow(record, bodies);\n const manifest: Manifest = {itemIndex: state.board.items.map(summary), recordIndex: (state.records ?? []).map(recordSummary), layout: 2, generation: randomUUID(), state: {...state, board: {...state.board, items: []}, records: []},\n itemIds: state.board.items.map(item => item.id), recordIds: (state.records ?? []).map(record => record.id)};\n return {raw: JSON.stringify(manifest), rows};\n}\nexport function rowChanges(before: StoredBoard, after: StoredBoard): Array<{key: string; value: string | null}> {\n const writes = Object.entries(after.rows).filter(([key, value]) => before.rows[key] !== value).map(([key, value]) => ({key, value: value as string | null}));\n for (const key of Object.keys(before.rows)) if (!(key in after.rows)) writes.push({key, value: null});\n return writes;\n}\nexport function receiptDigest(fingerprint: string): string {return `sha256:v1:${sha256HexSync(fingerprint)}`;}\nexport function verifyReceipt(saved: string, fingerprint: string): void {\n requireValue(saved === fingerprint || saved === receiptDigest(fingerprint), 'IDEMPOTENCY_CONFLICT');\n}\nexport async function encodeRow(value: unknown, bodies?: KanbanBodyStore): Promise<string> {\n const raw = JSON.stringify(value), bytes = new TextEncoder().encode(raw);\n if (!bodies || bytes.length <= 8192) return raw;\n const ref: BodyRef = {body: 'kanban-body/v1', sha256: sha256HexSync(bytes), bytes: bytes.length};\n // Body publication precedes the referencing transaction; unreferenced files are retained.\n const existing = await bodies.read(ref.sha256);\n if (existing !== null) verifyBody(existing, ref);\n else {\n let failure: unknown;\n try {await bodies.write(ref.sha256, bytes.buffer);} catch (error) {failure = error;}\n const confirmed = await bodies.read(ref.sha256);\n if (confirmed === null) throw failure ?? new KanbanError('BODY_WRITE_UNCONFIRMED');\n verifyBody(confirmed, ref);\n }\n return JSON.stringify(ref);\n}\nexport async function decodeRow<T>(raw: string, bodies?: KanbanBodyStore): Promise<T> {\n const parsed = JSON.parse(raw) as BodyRef;\n if (parsed?.body !== 'kanban-body/v1') return parsed as T;\n requireValue(/^[a-f0-9]{64}$/.test(parsed.sha256) && Number.isSafeInteger(parsed.bytes) && parsed.bytes > 8192, 'INVALID_BODY_REFERENCE');\n requireValue(bodies, 'BODY_STORE_REQUIRED'); const bytes = await bodies.read(parsed.sha256);\n requireValue(bytes !== null, 'BODY_MISSING'); verifyBody(bytes, parsed);\n return JSON.parse(new TextDecoder('utf-8', {fatal: true}).decode(bytes)) as T;\n}\nfunction verifyBody(bytes: ArrayBuffer, ref: BodyRef): void {\n requireValue(bytes instanceof ArrayBuffer && bytes.byteLength === ref.bytes && sha256HexSync(bytes) === ref.sha256, 'BODY_INTEGRITY');\n}\nfunction requiredRow(saved: StoredBoard, key: string): string {requireValue(typeof saved.rows[key] === 'string', 'MISSING_STORAGE_ROW'); return saved.rows[key];}\nfunction validateState(state: KanbanState): KanbanState {\n requireValue(state?.schema === 1 && state.board && Array.isArray(state.board.items) && Array.isArray(state.events), 'INVALID_STORAGE'); return state;\n}\n\nexport function indexedView(raw: string | null): KanbanReadView | null {\n if (raw === null) return null;\n const parsed = JSON.parse(raw) as Manifest;\n if (parsed.layout === 2 && Array.isArray(parsed.itemIndex) && Array.isArray(parsed.recordIndex))\n return {state: validateState(parsed.state), items: parsed.itemIndex, records: parsed.recordIndex};\n return null;\n}\nexport function viewFromState(state: KanbanState): KanbanReadView {\n return {state: {...state, board: {...state.board, items: []}, records: []}, items: state.board.items.map(summary), records: (state.records ?? []).map(recordSummary)};\n}\n","import type {KanbanState} from './ports';\nimport {requireValue} from './rules';\n\nexport const boardCounterKey = 'counter/board';\nexport const boardNumberKey = (number: number): string => `reference/board/${number}`;\nexport function counter(raw: string | null): number {\n requireValue(raw === null || /^(0|[1-9]\\d*)$/.test(raw), 'INVALID_NUMBER_COUNTER');\n const value = raw === null ? 0 : Number(raw);\n requireValue(Number.isSafeInteger(value) && value >= 0 && value <= Number.MAX_SAFE_INTEGER, 'INVALID_NUMBER_COUNTER'); return value;\n}\nexport function storedBoardNumber(raw: string | null): number | undefined {\n if (raw === null) return undefined;\n const parsed = JSON.parse(raw), number = (parsed.layout === 2 ? parsed.state?.board : parsed.board)?.number;\n if (number !== undefined) requireValue(Number.isSafeInteger(number) && number > 0, 'INVALID_NUMBERING'); return number;\n}\nexport function patchBoardNumber(raw: string, number: number): string {\n const parsed = JSON.parse(raw); parsed.state.board.number = number; return JSON.stringify(parsed);\n}\n/** Counters and identities live in the board commit, including drafts and archived items. */\nexport function numberEntities(state: KanbanState): void {\n const high = state.numbering ??= {item: 0, log: 0, decision: 0};\n const items = [...state.board.items, ...(state.archiveIndex ?? []), ...(state.archiveWrites ?? []).flatMap(write => write.value ? [write.value.item] : [])];\n high.item = assign(items, high.item);\n for (const kind of ['log', 'decision'] as const) high[kind] = assign((state.records ?? []).filter(record => record.kind === kind), high[kind]);\n}\nfunction assign(rows: Array<{id: string; number?: number}>, high: number): number {\n counter(String(high)); const used = new Map<number, string>(), known = new Map<string, number>();\n for (const row of rows) if (row.number !== undefined) {\n requireValue(Number.isSafeInteger(row.number) && row.number > 0 && (!used.has(row.number) || used.get(row.number) === row.id)\n && (!known.has(row.id) || known.get(row.id) === row.number), 'INVALID_NUMBERING');\n used.set(row.number, row.id); known.set(row.id, row.number); high = Math.max(high, row.number);\n }\n for (const row of rows) if (row.number === undefined) {\n if (!known.has(row.id)) {requireValue(high < Number.MAX_SAFE_INTEGER, 'NUMBER_COUNTER_EXHAUSTED'); known.set(row.id, ++high);}\n row.number = known.get(row.id)!;\n }\n return high;\n}\n\nexport function allocateBoardNumber(raw: string | null, high: number): number {\n const known = storedBoardNumber(raw); if (known !== undefined) return known;\n requireValue(high < Number.MAX_SAFE_INTEGER, 'NUMBER_COUNTER_EXHAUSTED'); return high + 1;\n}\n","import type {KanbanArchivedItem} from './contracts';\nimport type {KanbanState} from './ports';\nimport {requireValue, text} from './rules';\nimport {summary, terminal} from './planning';\n\nexport function archiveItems(state: KanbanState, ids: string[], reason: string, now: number): void {\n text(reason); requireValue(ids.length > 0 && ids.length <= 50 && new Set(ids).size === ids.length, 'ARCHIVE_BATCH_LIMIT');\n const items = ids.map(id => state.board.items.find(i => i.id === id));\n requireValue(items.every(item => item && terminal(item)), 'ARCHIVE_REQUIRES_CLOSED_ITEM');\n for (const item of items) {\n const archived: KanbanArchivedItem = {item: item!, archivedAt: now, reason};\n (state.archiveIndex ??= []).push({...summary(item!), archivedAt: now, archiveReason: reason});\n (state.archiveWrites ??= []).push({id: item!.id, value: archived});\n }\n const selected = new Set(ids); state.board.items = state.board.items.filter(i => !selected.has(i.id));\n}\nexport function restoreItem(state: KanbanState, id: string, now: number): void {\n const record = state.restore;\n requireValue(record?.item.id === id && state.archiveIndex?.some(i => i.id === id), 'ARCHIVED_ITEM_NOT_FOUND');\n requireValue(!state.board.items.some(i => i.id === id), 'ITEM_EXISTS');\n record.item.restoredAt = now; record.item.updatedAt = now; record.item.revision++; state.board.items.push(record.item);\n state.archiveIndex = state.archiveIndex!.filter(i => i.id !== id);\n (state.archiveWrites ??= []).push({id, value: null}); delete state.restore;\n}\nexport function archiveExpired(state: KanbanState, now: number): string[] {\n const age = state.board.policy.archiveAfterMs;\n if (age === undefined) return [];\n const ids = state.board.items.filter(i => terminal(i) && now - Math.max(i.closedAt ?? i.updatedAt, i.restoredAt ?? 0) >= age).slice(0, 50).map(i => i.id);\n if (ids.length) archiveItems(state, ids, 'retention-policy', now);\n return ids;\n}\n","import {assertDefinitionEditable} from './task-commands';\nimport type {KanbanActor, KanbanCommand, KanbanExternalReference, KanbanItem} from './contracts';\nimport type {KanbanState} from './ports';\nimport {requireValue, text, identity, owned} from './rules';\nimport {catalog, setStage, terminal, validatePlan} from './planning';\nimport {executable} from './configuration';\nimport {archiveItems, restoreItem} from './archives';\n\ntype OperationalCommand = Extract<KanbanCommand, {type: 'block-item' | 'unblock-item' | 'link-reference' | 'release-item'}>;\ntype PlanCommand = Extract<KanbanCommand, {type: 'edit-item' | 'plan-item' | 'set-stage' | 'publish-proposal' | 'cancel-item' | 'close-plan'}>;\nexport type PlanningCommand = PlanCommand | OperationalCommand | Extract<KanbanCommand, {type: 'archive-items' | 'restore-item'}>;\nexport function planningCommand(command: KanbanCommand): command is PlanningCommand {\n return ['edit-item', 'plan-item', 'set-stage', 'publish-proposal', 'cancel-item', 'close-plan', 'archive-items', 'restore-item', 'block-item', 'unblock-item', 'link-reference', 'release-item'].includes(command.type);\n}\nexport function applyPlanningCommand(state: KanbanState, command: PlanningCommand, now: number, actor: KanbanActor, internal = false): void {\n if (command.type === 'archive-items') return archiveItems(state, command.itemIds, command.reason, now);\n if (command.type === 'restore-item') return restoreItem(state, command.itemId, now);\n const item = state.board.items.find(i => i.id === command.itemId); requireValue(item, 'ITEM_NOT_FOUND');\n if (isOperational(command)) operate(item, command, now, actor);\n else {\n if (!internal && ['edit-item','plan-item','review-amendment'].includes(command.type)) assertDefinitionEditable(item, now);\n updatePlan(state, item, command, now);\n }\n}\nfunction isOperational(command: PlanCommand | OperationalCommand): command is OperationalCommand {\n return ['block-item', 'unblock-item', 'link-reference', 'release-item'].includes(command.type);\n}\nfunction operate(item: KanbanItem, command: OperationalCommand, now: number, actor: KanbanActor): void {\n if (command.type === 'release-item') {\n requireValue(['claimed', 'review'].includes(item.status) && item.owner?.token === command.token, 'OWNER_MISMATCH');\n requireValue(['backlog', 'cancelled'].includes(command.next), 'INVALID_STAGE'); text(command.reason);\n item.status = command.next;\n if (command.next === 'cancelled') {item.closedAt = now; item.closureReason = command.reason;}\n delete item.owner; delete item.transfer; delete item.estimate;\n } else if (command.type === 'link-reference') attachReference(item, command.reference);\n else {\n requireValue(!terminal(item), 'ITEM_COMPLETED');\n if (item.status === 'claimed') owned(item, actor, command.token ?? '', now);\n if (command.type === 'block-item') {text(command.reason); item.blocked = {reason: command.reason, at: now};}\n else delete item.blocked;\n }\n item.updatedAt = now; item.revision++;\n}\nfunction updatePlan(state: KanbanState, item: KanbanItem, command: PlanCommand, now: number): void {\n if(command.type==='cancel-item')requireValue(item.launch?.admittedAt===undefined,'TASK_CONTROL_REQUIRED');\n if (command.type === 'publish-proposal') {\n requireValue(item.status === 'proposed', 'NOT_PROPOSED'); return setStage(state, item, command.stage ?? 'backlog', now);\n }\n if (command.type === 'set-stage') return setStage(state, item, command.stage, now);\n requireValue(['proposed', 'backlog', 'open'].includes(item.status), 'ITEM_NOT_PLANNABLE');\n if (command.type === 'edit-item') {\n text(command.title); text(command.responsibility); text(command.acceptance);\n item.title = command.title; item.responsibility = command.responsibility; item.acceptance = command.acceptance;\n if (item.status === 'open') return setStage(state, item, 'backlog', now);\n } else if (command.type === 'plan-item') {\n validatePlan(state, item, command.planning); item.planning = command.planning;\n if (item.status === 'open') return setStage(state, item, 'backlog', now);\n } else {\n requireValue(catalog(state).filter(i => i.planning.parentId === item.id).every(terminal), 'CHILDREN_UNFINISHED');\n if (command.type === 'close-plan') {\n requireValue(!executable(state.board, item), 'TASK_REQUIRES_REVIEW'); text(command.resultRef);\n const children=catalog(state).filter(child=>child.planning.parentId===item.id);\n if(item.planning?.execution==='children')requireValue(children.length>0&&children.every(child=>child.status==='completed'),'CHILDREN_UNFINISHED');\n item.status = 'completed'; item.resultRef = command.resultRef;\n } else {text(command.reason); item.status = 'cancelled'; item.closureReason = command.reason;}\n item.closedAt = now;\n }\n item.updatedAt = now; item.revision++;\n}\nexport function attachReference(item: KanbanItem, reference: KanbanExternalReference): void {\n identity(reference.system); identity(reference.id); if (reference.revision !== undefined) text(reference.revision);\n item.externalRefs ??= [];\n if (item.externalRefs.some(r => r.system === reference.system && r.id === reference.id && r.revision === reference.revision)) return;\n requireValue(item.externalRefs.length < 100, 'REFERENCE_LIMIT'); item.externalRefs.push(reference);\n}\n","import type {KanbanActor, KanbanCommand, KanbanWorkDefinition, KanbanWorkPlan, KanbanPublishedPlan} from './contracts';\nimport type {KanbanState} from './ports';\nimport {sha256HexSync} from './utils';\nimport {identity, requireValue} from './rules';\nimport {principal, principalKey, validateCandidates} from './identity';\nimport {plan as planning} from './planning';\nexport type ApplyWorkCommand = (command: KanbanCommand, actor?: KanbanActor) => void;\n\nexport function requireCoordinator(state: KanbanState, actor: KanbanActor): void {\n requireValue(state.board.members?.some(member => principalKey(member) === principalKey(principal(actor)) && member.roles?.includes('coordinator')), 'COORDINATOR_REQUIRED');\n}\nexport function publishPlan(state: KanbanState, plan: KanbanWorkPlan, actor: KanbanActor, apply: ApplyWorkCommand): void {\n requireCoordinator(state, actor); requireValue(plan && typeof plan === 'object', 'INVALID_WORK_PLAN'); identity(plan.id);\n requireValue(plan.schema === 'kanban.plan/1' && typeof plan.sealed === 'boolean' && Array.isArray(plan.items) && plan.items.length > 0 && plan.items.length <= 100, 'INVALID_WORK_PLAN');\n const workflow = state.workflow!, previous = workflow.plans[plan.id];\n requireValue(Number.isSafeInteger(plan.revision) && plan.revision === (previous?.revision ?? 0) + 1, 'PLAN_REVISION_CONFLICT');\n requireValue(!Object.values(workflow.dispatches).some(dispatch => dispatch.planId === plan.id && ['prepared','running','unknown','succeeded'].includes(dispatch.outcome)), 'PLAN_EXECUTION_UNSETTLED');\n if (plan.decisionId) {\n const decision=state.records?.find(record => record.id === plan.decisionId && record.kind === 'decision' && record.status === 'confirmed');\n requireValue(decision, 'DECISION_NOT_CONFIRMED');\n if(decision.coordination) requireValue(principalKey(decision.coordination.manager)===principalKey(principal(actor)), 'DECISION_MANAGER_REQUIRED');\n }\n if(plan.rootItemId) {\n const root=state.board.items.find(item=>item.id===plan.rootItemId);\n requireValue(root&&!root.owner&&['backlog','open'].includes(root.status),'PLAN_ROOT_UNAVAILABLE');\n if(root.planning?.execution!=='children')apply({type:'plan-item',itemId:root.id,planning:{...planning(root),execution:'children'}});\n }\n const ordered = orderWork(plan.items, state), definitions: KanbanPublishedPlan['definitions'] = {};\n for (const item of ordered) {\n const digest = sha256HexSync(JSON.stringify(item));\n requireValue(!Object.values(workflow.plans).some(other => other.id !== plan.id && other.itemIds.includes(item.id)), 'ITEM_IN_OTHER_PLAN');\n const exists=state.board.items.some(old => old.id === item.id)||state.archiveIndex?.some(old=>old.id===item.id);\n if (exists && previous?.definitions[item.id]?.digest !== digest) {\n requireValue(!previous?.definitions[item.id], 'PLAN_ITEM_CHANGED_REQUIRES_NEW_ID');\n adoptItem(state, item, apply);\n }\n if (!exists) apply({type:'create-item', item:{id:item.id,title:item.title,responsibility:item.responsibility,acceptance:item.acceptance,eligiblePrincipals:[item.assignee],externalRefs:item.externalRefs},\n planning:{kind:item.workType??state.board.defaultWorkType ?? 'task',priority:2,dependencies:item.dependsOn,references:[],...(plan.rootItemId ? {parentId:plan.rootItemId}: {})}});\n definitions[item.id] = {digest, inputs:item.inputs, outputs:item.outputs ?? []};\n }\n workflow.plans[plan.id] = {schema:plan.schema,id:plan.id,revision:plan.revision,decisionId:plan.decisionId,rootItemId:plan.rootItemId,sealed:plan.sealed,itemIds:ordered.map(item=>item.id),definitions};\n}\nfunction adoptItem(state: KanbanState, definition: KanbanWorkDefinition, apply: ApplyWorkCommand): void {\n const item = state.board.items.find(item => item.id === definition.id);\n requireValue(item && definition.expectedRevision === item.revision && ['backlog', 'open'].includes(item.status)\n && !item.owner && !item.blocked, 'PLAN_ITEM_CHANGED_REQUIRES_NEW_ID');\n requireValue(!definition.workType||definition.workType===item.planning?.kind,'PLAN_ITEM_CHANGED_REQUIRES_NEW_ID');\n requireValue(!definition.externalRefs||definition.externalRefs.every(ref=>item.externalRefs?.some(existing=>JSON.stringify(existing)===JSON.stringify(ref))),'PLAN_RESOURCE_MISMATCH');\n requireValue(item.title === definition.title && item.responsibility === definition.responsibility\n && item.acceptance === definition.acceptance, 'PLAN_ITEM_CHANGED_REQUIRES_NEW_ID');\n requireValue(planning(item).dependencies.every(id => definition.dependsOn.includes(id)), 'EXISTING_DEPENDENCY_REQUIRED');\n apply({type: 'plan-item', itemId: item.id, planning: {...planning(item), dependencies: definition.dependsOn}});\n item.eligiblePrincipals = [definition.assignee]; delete item.eligibleAgentIds;\n validateCandidates(state.board, item, true);\n}\nfunction orderWork(items: KanbanWorkDefinition[], state: KanbanState): KanbanWorkDefinition[] {\n for (const item of items) validateDefinition(item);\n const ids = new Set(items.map(item => item.id)); requireValue(ids.size === items.length, 'DUPLICATE_PLAN_ITEM');\n for (const item of items) {\n identity(item.id); requireValue(Array.isArray(item.dependsOn) && item.dependsOn.length <= 100 && new Set(item.dependsOn).size === item.dependsOn.length, 'INVALID_DEPENDENCIES');\n requireValue(Object.keys(item.inputs ?? {}).length <= 100 && Array.isArray(item.outputs ?? []) && (item.outputs ?? []).length <= 100 && new Set(item.outputs ?? []).size === (item.outputs ?? []).length, 'PLAN_BINDING_LIMIT');\n for (const name of [...Object.keys(item.inputs ?? {}), ...(item.outputs ?? [])]) requireValue(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(name), 'INVALID_OUTPUT_NAME');\n for (const binding of Object.values(item.inputs ?? {})) {\n requireValue(binding && item.dependsOn.includes(binding.fromItemId) && typeof binding.output === 'string', 'INPUT_DEPENDENCY_REQUIRED');\n const producer=items.find(other=>other.id===binding.fromItemId), existing=Object.values(state.workflow!.dispatches).some(dispatch=>dispatch.itemId===binding.fromItemId&&dispatch.outcome==='accepted'&&dispatch.outputs?.some(output=>output.name===binding.output));\n requireValue(producer ? producer.outputs?.includes(binding.output) : existing, 'OUTPUT_NOT_DECLARED');\n }\n for (const dependency of item.dependsOn) requireValue(ids.has(dependency) || [...state.board.items,...(state.archiveIndex ?? [])].some(old => old.id === dependency), 'DEPENDENCY_NOT_FOUND');\n }\n const ordered: KanbanWorkDefinition[] = [], remaining = [...items], done = new Set<string>();\n while (remaining.length) {\n const next = remaining.findIndex(item => item.dependsOn.every(id => !ids.has(id) || done.has(id)));\n requireValue(next >= 0, 'DEPENDENCY_CYCLE'); const [item] = remaining.splice(next,1); ordered.push(item); done.add(item.id);\n }\n return ordered;\n}\nfunction validateDefinition(item: KanbanWorkDefinition): void {\n requireValue(item && typeof item === 'object' && !Array.isArray(item), 'INVALID_WORK_DEFINITION');\n const assignee=item.assignee;\n requireValue(assignee && ['agent','human','service'].includes(assignee.kind), 'INVALID_PRINCIPAL'); identity(assignee.id);\n if(item.inputs!==undefined) requireValue(item.inputs && typeof item.inputs==='object' && !Array.isArray(item.inputs), 'INVALID_INPUT_BINDINGS');\n if(item.outputs!==undefined) requireValue(Array.isArray(item.outputs) && item.outputs.every(name=>typeof name==='string'), 'INVALID_OUTPUT_NAMES');\n}\n","import {boardAllowsStart} from './contracts/board-control';\nimport {sha256HexSync} from './utils';\nimport type {KanbanActor, KanbanCommand, KanbanItem, KanbanTaskCommand} from './contracts';\nimport type {KanbanState} from './ports';\nimport {principal, principalKey} from './identity';\nimport {identity, requireValue, text} from './rules';\nimport {taskDue, taskEditing, taskStartAt} from './contracts/task-projection';\nimport {validatePlan, catalog} from './planning';\nimport {attachReference} from './planning-commands';\nimport {requireCoordinator} from './workflow-plans';\n\nconst types = ['set-launch-mode', 'retry-analysis', 'begin-edit', 'end-edit', 'save-edit', 'request-run', 'admit-item', 'report-analysis', 'request-control', 'control-receipt', 'report-issue', 'resolve-issue'];\nexport function taskCommand(command: KanbanCommand): command is KanbanTaskCommand {return types.includes(command.type);}\nexport function assertDefinitionEditable(item: KanbanItem, now: number, editId?: string, actor?: KanbanActor): void {\n requireValue(['proposed', 'backlog', 'open'].includes(item.status) && !item.owner && item.launch?.admittedAt === undefined, 'TASK_DEFINITION_FROZEN');\n if (taskEditing(item, now)) requireValue(item.launch!.editing!.id === editId && !!actor && principalKey(item.launch!.editing!.principal) === principalKey(principal(actor)), 'EDIT_LEASE_ACTIVE');\n}\nexport function applyTaskCommand(state: KanbanState, command: KanbanTaskCommand, actor: KanbanActor, now: number): void {\n const item = state.board.items.find(i => i.id === command.itemId); requireValue(item, 'ITEM_NOT_FOUND');\n item.launch ??= {startAt: taskStartAt(item)};\n if (['begin-edit', 'end-edit', 'save-edit'].includes(command.type)) edit(state, item, command, actor, now);\n else if(command.type==='retry-analysis') {\n identity(command.retryId);requireValue(['failed','clarification'].includes(item.analysis?.state??'')&&!item.owner,'ANALYSIS_NOT_RETRYABLE');\n item.launch.analysisEpoch=command.retryId;delete item.analysis;\n }\n else if (command.type === 'set-launch-mode') {assertDefinitionEditable(item, now); setMode(item, command.mode);}\n else if (command.type === 'request-run') {assertDefinitionEditable(item, now); item.launch.requestedAt ??= now;}\n else if (command.type === 'admit-item') {\n requireCoordinator(state, actor); assertDefinitionEditable(item, now);\n requireValue(boardAllowsStart(state.board, item), 'BOARD_EXECUTION_PAUSED');\n requireValue(command.trigger === 'manual' ? item.launch.requestedAt !== undefined : taskDue(item, now), 'START_NOT_DUE');\n requireValue(!item.blocked && item.control?.action !== 'pause', 'ITEM_BLOCKED');\n requireValue(item.planning?.dependencies.every(id => catalog(state).find(i => i.id === id)?.status === 'completed') ?? true, 'DEPENDENCIES_UNFINISHED');\n item.launch.admittedAt = now;\n } else if (command.type === 'report-analysis') {\n requireCoordinator(state, actor); identity(command.operationId); requireValue(command.status.itemId === item.id, 'ANALYSIS_SCOPE_MISMATCH');\n item.analysis = structuredClone(command.status);\n } else if (command.type === 'request-control') requestControl(state, item, command);\n else if (command.type === 'control-receipt') {\n requireCoordinator(state, actor); requireValue(item.control?.id === command.controlId, 'STALE_CONTROL_RECEIPT');\n requireValue(['accepted', 'paused', 'resumed', 'failed', 'unknown'].includes(command.state), 'INVALID_CONTROL_STATE');\n item.control!.state = command.state; item.control!.code = command.code;\n } else issues(state, item, command, actor);\n item.updatedAt = now; item.revision++;\n}\nfunction edit(state: KanbanState, item: KanbanItem, command: KanbanTaskCommand, actor: KanbanActor, now: number): void {\n if (command.type === 'begin-edit') {\n assertDefinitionEditable(item, now, command.editId, actor); identity(command.editId);\n requireValue(Number.isSafeInteger(command.leaseMs) && command.leaseMs >= 1000 && command.leaseMs <= 300000, 'INVALID_EDIT_LEASE');\n item.launch!.editing = {id: command.editId, principal: principal(actor), expiresAt: now + command.leaseMs}; return;\n }\n if (command.type !== 'save-edit' && command.type !== 'end-edit') return;\n assertDefinitionEditable(item, now, command.editId, actor);\n requireValue(taskEditing(item, now) && item.launch!.editing!.id === command.editId, 'EDIT_LEASE_EXPIRED');\n if (command.type === 'save-edit') {\n text(command.title); text(command.responsibility); text(command.acceptance); validatePlan(state, item, command.planning);\n if (command.launchMode !== undefined) setMode(item, command.launchMode);\n Object.assign(item, {title: command.title, responsibility: command.responsibility, acceptance: command.acceptance, planning: command.planning});\n if (command.externalRefs) {item.externalRefs = []; for (const ref of command.externalRefs) attachReference(item, ref);}\n }\n if(command.type==='save-edit')for(const plan of Object.values(state.workflow?.plans??{})) {\n const definition=plan.definitions[item.id];if(!definition)continue;\n requireValue(Object.values(definition.inputs??{}).every(binding=>item.planning?.dependencies.includes(binding.fromItemId)),'EXISTING_DEPENDENCY_REQUIRED');\n definition.digest=sha256HexSync(JSON.stringify([item.title,item.responsibility,item.acceptance,item.planning,item.externalRefs,definition.inputs,definition.outputs]));\n }\n delete item.launch!.editing;\n}\nfunction requestControl(state: KanbanState, item: KanbanItem, command: Extract<KanbanTaskCommand, {type: 'request-control'}>): void {\n requireValue(!['completed', 'cancelled', 'review'].includes(item.status), 'ITEM_COMPLETED'); identity(command.controlId);\n requireValue(['pause', 'resume'].includes(command.action), 'INVALID_CONTROL_ACTION');\n if (item.control?.id === command.controlId) {requireValue(item.control.action === command.action, 'IDEMPOTENCY_CONFLICT'); return;}\n requireValue(!item.control || !['requested', 'unknown'].includes(item.control.state), 'CONTROL_UNSETTLED');\n const dispatch = Object.values(state.workflow?.dispatches ?? {}).find(d => d.itemId === item.id && ['prepared', 'running', 'unknown'].includes(d.outcome));\n requireValue(dispatch || item.launch?.admittedAt === undefined, 'TASK_CONTROL_UNSUPPORTED');\n requireValue(command.action === 'pause' || item.control?.action === 'pause', 'TASK_NOT_PAUSED');\n item.control = {id: command.controlId, dispatchId: dispatch?.id, action: command.action, state: 'requested'};\n}\nfunction issues(state: KanbanState, item: KanbanItem, command: KanbanTaskCommand, actor: KanbanActor): void {\n requireCoordinator(state, actor);\n if (command.type === 'report-issue') {\n const issue = command.issue; identity(issue.id); identity(issue.attemptId);\n requireValue(!issue.resolvedBy && ['clarification', 'error'].includes(issue.type), 'INVALID_ISSUE');\n requireValue(state.workflow?.dispatches[issue.attemptId]?.itemId === item.id && item.owner?.token === state.workflow.dispatches[issue.attemptId].fence, 'STALE_EXECUTION_RESULT');\n item.issues ??= []; const old = item.issues.find(i => i.id === issue.id && i.attemptId === issue.attemptId);\n if (!old) {requireValue(item.issues.length < 200, 'ISSUE_LIMIT'); item.issues.push(structuredClone(issue));}\n } else if (command.type === 'resolve-issue') {\n const issue = item.issues?.find(i => i.id === command.issueId && i.attemptId === command.attemptId); requireValue(issue, 'ISSUE_NOT_FOUND');\n identity(command.resolvedBy); requireValue(!issue.resolvedBy || issue.resolvedBy === command.resolvedBy, 'ISSUE_ALREADY_RESOLVED'); issue.resolvedBy = command.resolvedBy;\n }\n}\n\nexport function initializeTaskLaunch(state:KanbanState,item:KanbanItem):boolean {\n if(item.launch)return false;\n const first=Object.values(state.workflow?.dispatches??{}).filter(d=>d.itemId===item.id).sort((a,b)=>a.attempt-b.attempt)[0];\n const admittedAt=first?.preparedAt??item.owner?.claimedAt;\n item.launch={startAt:taskStartAt(item),...(admittedAt===undefined?{}:{admittedAt})};item.revision++;return true;\n}\n\nfunction setMode(item: KanbanItem, mode: 'automatic' | 'manual'): void {\n requireValue(['automatic', 'manual'].includes(mode), 'INVALID_LAUNCH_MODE');\n item.launch!.mode = mode; delete item.launch!.requestedAt;\n}\n","import type {KanbanActor, KanbanCommand} from './contracts';\nimport type {KanbanState} from './ports';\nimport {requireValue} from './rules';\nimport {applyTaskCommand} from './task-commands';\n\ntype Command = Extract<KanbanCommand, {type: 'set-board-control'}>;\n/** The scheduling barrier and original execution control requests commit together. */\nexport function setBoardControl(state: KanbanState, command: Command, actor: KanbanActor, now: number, token: string): void {\n requireValue(actor.kind === 'human', 'FORBIDDEN');\n requireValue(command.mode !== undefined || command.paused !== undefined, 'INVALID_BOARD_CONTROL');\n requireValue(command.mode === undefined || ['automatic', 'manual'].includes(command.mode), 'INVALID_LAUNCH_MODE');\n requireValue(command.paused === undefined || typeof command.paused === 'boolean', 'INVALID_BOARD_CONTROL');\n const policy = state.board.executionControl ??= {mode: 'automatic', paused: false, controls: {}};\n if (command.mode) policy.mode = command.mode;\n if (command.paused === undefined || command.paused === policy.paused) return;\n if (!command.paused) requireValue(!state.board.items.some(item => policy.controls[item.id] === item.control?.id && ['requested', 'unknown'].includes(item.control!.state)), 'CONTROL_UNSETTLED');\n policy.paused = command.paused;\n if (policy.paused) policy.controls = {};\n state.board.items.forEach((item, index) => {\n if (['completed', 'cancelled', 'review'].includes(item.status)) return;\n const active = Object.values(state.workflow?.dispatches ?? {}).some(d => d.itemId === item.id && ['prepared', 'running', 'unknown'].includes(d.outcome));\n const managed = policy.controls[item.id] === item.control?.id;\n if (policy.paused ? !active || item.control?.action === 'pause' : !managed || item.control?.action !== 'pause') return;\n if (item.control && ['requested', 'unknown'].includes(item.control.state)) return;\n const controlId = token + '-' + index;\n applyTaskCommand(state, {type: 'request-control', itemId: item.id, controlId, action: policy.paused ? 'pause' : 'resume'}, actor, now);\n policy.controls[item.id] = controlId;\n });\n}\n","import {TASK_START_DELAY_MS} from './contracts/task-projection';\nimport {discoveryState} from './discovery-state';\nimport {applyRecord, recordFingerprint} from './project-records';\nimport {principal, principalKey} from './identity';\nimport {workFingerprint, proposeAmendment, validateSources} from './amendments';\nimport type {KanbanActor, KanbanDiscoveryBatch, KanbanDiscoveryChange, KanbanItem} from './contracts';\nimport type {KanbanState} from './ports';\nimport {executable} from './configuration';\nimport {validateCandidates} from './identity';\nimport {plan, setStage, validatePlan, automaticStage} from './planning';\nimport {identity, participant, requireValue, text} from './rules';\n\n/** Commit accepted changes and source watermarks in the same board transaction. */\nexport function applyDiscovery(state: KanbanState, batch: KanbanDiscoveryBatch, actor: KanbanActor, now: number): void {\n const discovery = discoveryState(state), pending = discovery?.pending;\n requireValue(pending && pending.runId === batch.runId && pending.token === batch.leaseToken && pending.leaseUntil > now, 'SCAN_LEASE_EXPIRED');\n requireValue(pending.request?.command.type === 'apply-discovery' && JSON.stringify(pending.request.command.batch) === JSON.stringify(batch), 'SCAN_BATCH_MISMATCH');\n requireValue(batch.changes.length <= 50, 'SCAN_CHANGE_LIMIT');\n for (const change of batch.changes) {\n identity(change.itemId); validateSources(change.sources);\n requireValue(change.sources.length > 0 && change.sources.some(s => s.role === 'user'), 'USER_EVIDENCE_REQUIRED');\n const item = change.action === 'create' ? createItem(state, change, actor, now, batch.autoCreate, batch.runId) : updateItem(state, change, actor, now, batch.runId);\n if (item) attachSources(item, change, now);\n }\n requireValue((batch.records?.length ?? 0) <= 20, 'SCAN_RECORD_LIMIT');\n for (const record of batch.records ?? []) {\n requireValue(record.sources.some(source => source.role === 'user'), 'USER_EVIDENCE_REQUIRED');\n const duplicate = state.records?.some(old => recordFingerprint(old) === recordFingerprint(record));\n if (!duplicate) {applyRecord(state, {type: 'append-record', record}, actor, now, true); state.records!.find(entry => entry.id === record.id)!.originRunId = batch.runId;}\n }\n for (const checkpoint of batch.checkpoints) discovery!.checkpoints[checkpoint.sessionId] = checkpoint.revision;\n discovery!.lastRun = {runId: batch.runId, outcome: 'committed', at: now};\n delete discovery!.pending;\n}\nfunction createItem(state: KanbanState, change: KanbanDiscoveryChange, actor: KanbanActor, now: number, autoCreate: boolean, runId: string): KanbanItem | undefined {\n text(change.title); text(change.responsibility); text(change.acceptance);\n const item: KanbanItem = {origin: {kind: 'discovery', principal: principal(actor), runId}, id: change.itemId, title: change.title, responsibility: change.responsibility, acceptance: change.acceptance,\n eligibleAgentIds: change.eligibleAgentIds, eligiblePrincipals: change.eligiblePrincipals, status: 'proposed', revision: 1,\n createdAt: now, readyAt: now, updatedAt: now, workUnits: 0, participants: [], sources: []};\n item.launch={startAt:now+TASK_START_DELAY_MS};\n item.planning = change.planning ?? {...plan(item), kind: state.board.defaultWorkType ?? 'task'};\n const fingerprint = workFingerprint(item); item.origin!.fingerprint = fingerprint;\n validateCandidates(state.board, item, executable(state.board, item));\n if (state.archiveIndex?.some(old => old.discoveryFingerprint === fingerprint)) return undefined;\n const existing = state.board.items.find(old => workFingerprint(old) === fingerprint || old.origin?.fingerprint === fingerprint);\n if (existing) {existing.revision++; existing.updatedAt = now; return existing;}\n requireValue(!state.board.items.some(old => old.id === change.itemId) && !state.archiveIndex?.some(old => old.id === change.itemId), 'ITEM_EXISTS');\n validatePlan(state, item, item.planning); state.board.items.push(item);\n if (autoCreate) setStage(state, item, automaticStage(state, item), now);\n if (actor.sessionId) participant(item.participants, actor.sessionId, actor.agentId, 'creator', true, now);\n return item;\n}\nfunction updateItem(state: KanbanState, change: KanbanDiscoveryChange, actor: KanbanActor, now: number, runId: string): KanbanItem {\n const item = state.board.items.find(i => i.id === change.itemId); requireValue(item, 'ITEM_NOT_FOUND');\n if (change.action === 'update') {\n requireValue(!change.planning, 'SCAN_PLANNING_REQUIRES_REVIEW');\n const ownDraft = item.status === 'proposed' && item.origin?.kind === 'discovery'\n && principalKey(item.origin.principal) === principalKey(principal(actor));\n if (ownDraft) {\n text(change.title); text(change.responsibility); text(change.acceptance);\n item.title = change.title; item.responsibility = change.responsibility; item.acceptance = change.acceptance;\n } else proposeAmendment(item, change, actor, now, runId);\n } else requireValue(change.action === 'link', 'INVALID_CHANGE');\n item.revision++; item.updatedAt = now; return item;\n}\nfunction attachSources(item: KanbanItem, change: KanbanDiscoveryChange, now: number): void {\n for (const source of change.sources) {\n const subscribed = item.participants.find(p => p.sessionId === source.sessionId)?.subscribed ?? false;\n participant(item.participants, source.sessionId, undefined, source.role === 'user' ? 'creator' : 'consultant', subscribed, now);\n item.sources ??= [];\n if (!item.sources.some(s => s.sessionId === source.sessionId && s.messageId === source.messageId && s.revision === source.revision)) item.sources.push(source);\n }\n}\n","import type {KanbanAutomationSettings, KanbanBoard, KanbanActor, KanbanMember} from './contracts';\nimport {identity, requireValue, validateBoard} from './rules';\n\n/** Configuration grants no host authority; every execution still requires host admission. */\nexport function configureAutomation(board: KanbanBoard, settings: KanbanAutomationSettings, actor: KanbanActor): void {\n requireValue(settings && typeof settings.enabled === 'boolean' && typeof settings.autoAccept === 'boolean', 'INVALID_AUTOMATION');\n for (const ref of [settings.planner, settings.executor, ...(settings.preparation ? [settings.preparation] : [])]) {\n requireValue(ref && typeof ref === 'object', 'INVALID_AUTOMATION_TARGET');\n identity(ref.system); identity(ref.id); identity(ref.revision ?? '');\n }\n validateOptions(settings.preparationOptions);\n requireValue(settings.preparation || !Object.keys(settings.preparationOptions ?? {}).length, 'PREPARATION_REQUIRED');\n const members: KanbanMember[] = [...(board.members ?? []), ...(board.agents ?? []).filter(agent =>\n !board.members?.some(member => member.kind === 'agent' && member.id === agent.agentId))\n .map(agent => ({kind: 'agent' as const, id: agent.agentId, responsibility: agent.responsibility}))];\n for (const [principal, role] of [[settings.coordinator, 'coordinator'], [settings.worker, 'worker']] as const) {\n requireValue(principal && ['agent', 'human', 'service'].includes(principal.kind), 'INVALID_PRINCIPAL'); identity(principal.id);\n const existing = members.find(member => member.kind === principal.kind && member.id === principal.id);\n if (existing) existing.roles = [...new Set([...(existing.roles ?? []), role])];\n else members.push({...principal, responsibility: role, roles: [role]});\n }\n addReviewer(members, actor);\n board.members = members; delete board.agents; board.automation = structuredClone(settings);\n board.policy.review = settings.autoAccept ? 'assignee' : 'independent';\n validateBoard(board);\n}\nfunction addReviewer(members: KanbanMember[], actor: KanbanActor): void {\n if (actor.kind !== 'human' || !actor.id) return;\n const existing = members.find(member => member.kind === 'human' && member.id === actor.id);\n if (existing) existing.roles = [...new Set([...(existing.roles ?? []), 'reviewer' as const, 'coordinator' as const])];\n else members.push({kind: 'human', id: actor.id, responsibility: 'Review work', roles: ['reviewer', 'coordinator']});\n}\n\nfunction validateOptions(options: Record<string, string> | undefined): void {\n if (options === undefined) return;\n requireValue(options && typeof options === 'object' && !Array.isArray(options) && Object.keys(options).length <= 16, 'INVALID_PREPARATION_OPTIONS');\n for (const [key, value] of Object.entries(options)) {\n requireValue(/^[a-zA-Z][a-zA-Z0-9_-]{0,63}$/.test(key) && typeof value === 'string' && value.length <= 4096, 'INVALID_PREPARATION_OPTIONS');\n }\n}\n","import type {KanbanActor, KanbanWorkflowCommand} from './contracts';\nimport type {KanbanState} from './ports';\nimport {identity, requireValue} from './rules';\nimport {requireCoordinator, type ApplyWorkCommand} from './workflow-plans';\n\n/** A new fenced attempt preserves terminal history and explicitly names its predecessor. */\nexport function continueExecution(state: KanbanState, command: Extract<KanbanWorkflowCommand, {type: 'continue-execution'}>,\n actor: KanbanActor, now: number, apply: ApplyWorkCommand): void {\n requireCoordinator(state, actor); identity(command.dispatchId);\n const workflow = state.workflow!, previous = workflow.dispatches[command.previousDispatchId];\n requireValue(previous && ['failed', 'cancelled'].includes(previous.outcome), 'EXECUTION_NOT_CONTINUABLE');\n requireValue(!workflow.dispatches[command.dispatchId], 'DISPATCH_EXISTS');\n const item = state.board.items.find(item => item.id === previous.itemId), plan = workflow.plans[previous.planId];\n requireValue(item && ['backlog', 'open'].includes(item.status) && !item.owner, 'ITEM_NOT_CONTINUABLE');\n const attempts = Object.values(workflow.dispatches).filter(row => row.itemId === item.id);\n requireValue(attempts.every(row => row.attempt <= previous.attempt), 'STALE_CONTINUATION');\n requireValue(!attempts.some(row => ['prepared', 'running', 'unknown', 'succeeded'].includes(row.outcome)), 'EXECUTION_UNSETTLED');\n requireValue(plan?.revision === previous.planRevision && plan.definitions[item.id]?.digest === previous.definitionDigest, 'PLAN_CHANGED');\n requireValue(command.instruction === undefined || typeof command.instruction === 'string' && command.instruction.trim().length > 0\n && command.instruction.length <= 8000, 'INVALID_CONTINUATION_INSTRUCTION');\n requireValue(!item.blocked || item.blocked.reason === (previous.code ?? 'EXECUTION_FAILED'), 'ITEM_BLOCKED');\n delete item.blocked;\n if (item.status === 'backlog') apply({type: 'set-stage', itemId: item.id, stage: 'open'});\n apply({type: 'claim', itemId: item.id, estimate: item.estimate}, previous.principal);\n workflow.dispatches[command.dispatchId] = {id: command.dispatchId, itemId: item.id, itemRevision: item.revision,\n planId: previous.planId, planRevision: previous.planRevision, principal: previous.principal,\n definitionDigest: previous.definitionDigest, attempt: previous.attempt + 1, fence: item.owner!.token,\n preparedAt: now, outcome: 'prepared', inputs: structuredClone(previous.inputs),\n continuation: {previousDispatchId: previous.id, ...(command.instruction ? {instruction: command.instruction} : {})}};\n}\n","import {boardAllowsStart} from './contracts/board-control';\nimport {taskDue, taskEditing, taskStartAt} from './contracts/task-projection';\nimport type {KanbanActor, KanbanCommand, KanbanWorkflowCommand, KanbanDispatch, KanbanArtifactRef} from './contracts';\nimport {sameAutomationBinding, executableWorkItem} from './contracts';\nimport type {KanbanState} from './ports';\nimport {identity, requireValue} from './rules';\nimport {principal} from './identity';\nimport {publishPlan, requireCoordinator, type ApplyWorkCommand} from './workflow-plans';\nimport {catalog} from './planning';\nimport {executionObservationChanged} from './execution-observation';\nimport {continueExecution} from './workflow-continuation';\nexport function isWorkflowCommand(command: KanbanCommand): command is KanbanWorkflowCommand {\n return ['publish-plan','prepare-dispatch','continue-execution','observe-execution','accept-execution'].includes(command.type);\n}\n/** Plan definitions and live admissions cannot be bypassed by ordinary board commands. */\nexport function protectWorkflowItem(state: KanbanState, command: KanbanCommand): void {\n if (command.type === 'configure-automation' && Object.values(state.workflow?.dispatches ?? {}).some(dispatch =>\n ['prepared', 'running', 'unknown', 'succeeded'].includes(dispatch.outcome))) {\n requireValue(sameAutomationBinding(state.board.automation, command.settings), 'PLAN_EXECUTION_UNSETTLED');\n }\n if (!('itemId' in command) || !command.itemId || !state.workflow) return;\n const plan=Object.values(state.workflow.plans).find(plan=>plan.itemIds.includes(command.itemId!));\n if (!plan) return;\n requireValue(!['edit-item','plan-item','review-amendment'].includes(command.type),'PLAN_ITEM_CHANGED_REQUIRES_NEW_ID');\n if (plan.sealed) requireValue(!['claim','submit','review','close-plan'].includes(command.type),'WORKFLOW_COMMAND_REQUIRED');\n const live=Object.values(state.workflow.dispatches).some(dispatch=>dispatch.itemId===command.itemId&&['prepared','running','unknown','succeeded'].includes(dispatch.outcome));\n if (live) requireValue(!['request-transfer','accept-transfer','release-item','cancel-item'].includes(command.type),'EXECUTION_UNSETTLED');\n}\nexport function applyWorkflow(state: KanbanState, command: KanbanWorkflowCommand, actor: KanbanActor, now: number, apply: ApplyWorkCommand): boolean {\n state.workflow ??= {plans:{},dispatches:{},ready:[],completedPlans:[]};\n let changed = true;\n if (command.type === 'publish-plan') publishPlan(state,command.plan,actor,apply);\n else if (command.type === 'prepare-dispatch') prepare(state,command,actor,now,apply);\n else if (command.type === 'continue-execution') {requireValue(!state.board.executionControl?.paused, 'BOARD_EXECUTION_PAUSED'); continueExecution(state, command, actor, now, apply);}\n else if (command.type === 'observe-execution') changed = observe(state,command,actor,now);\n else accept(state,command,actor,apply);\n refreshReady(state);\n return changed;\n}\nfunction prepare(state: KanbanState, command: Extract<KanbanWorkflowCommand,{type:'prepare-dispatch'}>, actor: KanbanActor, now: number, apply: ApplyWorkCommand): void {\n identity(command.dispatchId); const workflow=state.workflow!;\n requireValue(!workflow.dispatches[command.dispatchId], 'DISPATCH_EXISTS'); refreshReady(state);\n requireValue(workflow.ready.includes(command.itemId), 'WORK_NOT_READY');\n const plan=Object.values(workflow.plans).find(plan=>plan.itemIds.includes(command.itemId))!;\n requireValue(!Object.values(workflow.dispatches).some(dispatch=>dispatch.itemId===command.itemId&&['prepared','running','unknown','succeeded'].includes(dispatch.outcome)), 'EXECUTION_UNSETTLED');\n const item=state.board.items.find(item=>item.id===command.itemId)!;\n if (item.status==='backlog') apply({type:'set-stage',itemId:item.id,stage:'open'});\n requireValue(!taskEditing(item, now), 'EDIT_LEASE_ACTIVE');\n requireValue(!state.board.executionControl?.paused, 'BOARD_EXECUTION_PAUSED');\n if (command.trigger === 'automatic') requireValue(boardAllowsStart(state.board, item) && taskDue(item, now), 'START_NOT_DUE');\n item.launch ??= {startAt: taskStartAt(item)}; item.launch.admittedAt ??= now;\n apply({type:'claim',itemId:item.id,estimate:command.estimate});\n const inputs: Record<string,KanbanArtifactRef>={};\n for(const [name,binding] of Object.entries(plan.definitions[item.id].inputs ?? {})) {\n const producer=Object.values(workflow.dispatches).reverse().find(dispatch=>dispatch.itemId===binding.fromItemId&&dispatch.outcome==='accepted');\n const output=producer?.outputs?.find(output=>output.name===binding.output);requireValue(output,'DEPENDENCY_OUTPUT_MISSING');inputs[name]=structuredClone(output);\n }\n const attempt=Math.max(0,...Object.values(workflow.dispatches).filter(dispatch=>dispatch.itemId===item.id).map(dispatch=>dispatch.attempt))+1;\n workflow.dispatches[command.dispatchId]={id:command.dispatchId,itemId:item.id,itemRevision:item.revision,planId:plan.id,planRevision:plan.revision,principal:principal(actor),definitionDigest:plan.definitions[item.id].digest,attempt,fence:item.owner!.token,preparedAt:now,outcome:'prepared',inputs};\n}\nfunction observe(state: KanbanState, command: Extract<KanbanWorkflowCommand,{type:'observe-execution'}>, actor: KanbanActor, now: number): boolean {\n requireCoordinator(state,actor); const dispatch=activeDispatch(state,command.dispatchId);\n requireValue(command.fence===dispatch.fence && ['prepared','running','unknown'].includes(dispatch.outcome),'STALE_EXECUTION_RESULT');\n requireValue(['running','unknown','succeeded','failed','cancelled'].includes(command.outcome),'INVALID_EXECUTION_OUTCOME');\n if(command.code!==undefined) requireValue(/^[A-Z][A-Z0-9_]{0,79}$/.test(command.code),'INVALID_ERROR_CODE');\n const item=state.board.items.find(item=>item.id===dispatch.itemId)!;\n if (command.executionSessionId) {identity(command.executionSessionId); requireValue(!dispatch.executionSessionId || dispatch.executionSessionId === command.executionSessionId, 'EXECUTION_SESSION_LOCKED'); dispatch.executionSessionId = command.executionSessionId;}\n if(command.controlCapabilities) {\n requireValue(['boundary','none'].includes(command.controlCapabilities.pause)&&typeof command.controlCapabilities.resume==='boolean','INVALID_CONTROL_CAPABILITIES');\n dispatch.controlCapabilities=structuredClone(command.controlCapabilities);\n }\n const outputs=command.outputs ?? [];validateOutputs(outputs);\n if (['running', 'unknown'].includes(command.outcome)) item.owner!.leaseUntil = Math.max(item.owner!.leaseUntil, now + state.board.policy.leaseMs);\n if (!executionObservationChanged(dispatch, command)) return false;\n if(command.outcome==='succeeded') {\n const required=state.workflow!.plans[dispatch.planId].definitions[item.id].outputs;\n requireValue(required.every(name=>outputs.some(output=>output.name===name)),'REQUIRED_OUTPUT_MISSING');\n item.status=state.board.policy.review==='assignee'?'completed':'review';if(item.status==='completed') item.closedAt=now;item.resultRef=`kanban:dispatch:${dispatch.id}`;dispatch.outputs=structuredClone(outputs);\n } else if(command.outcome==='failed'||command.outcome==='cancelled') {\n item.status='backlog';item.blocked={reason:command.code ?? 'EXECUTION_FAILED',at:now};delete item.owner;\n }\n dispatch.outcome=command.outcome==='succeeded'&&state.board.policy.review==='assignee'?'accepted':command.outcome;dispatch.code=command.code;item.updatedAt=now;item.revision++;dispatch.itemRevision=item.revision;\n return true;\n}\nfunction accept(state: KanbanState, command: Extract<KanbanWorkflowCommand,{type:'accept-execution'}>, actor: KanbanActor, apply: ApplyWorkCommand): void {\n requireCoordinator(state,actor);const dispatch=activeDispatch(state,command.dispatchId);\n requireValue(dispatch.outcome==='succeeded','EXECUTION_NOT_SUCCEEDED');\n apply({type:'review',itemId:dispatch.itemId,accept:command.accept},actor);\n dispatch.outcome=command.accept?'accepted':'rejected';\n if(!command.accept) {const item=state.board.items.find(item=>item.id===dispatch.itemId)!;item.status='backlog';item.blocked={reason:'EXECUTION_REJECTED',at:item.updatedAt};}\n}\nfunction activeDispatch(state: KanbanState, id: string): KanbanDispatch {\n const dispatch=state.workflow!.dispatches[id];requireValue(dispatch,'DISPATCH_NOT_FOUND');\n const item=state.board.items.find(item=>item.id===dispatch.itemId), plan=state.workflow!.plans[dispatch.planId];\n requireValue(plan?.revision===dispatch.planRevision&&item?.owner?.token===dispatch.fence&&plan.definitions[dispatch.itemId]?.digest===dispatch.definitionDigest,'STALE_EXECUTION_RESULT');return dispatch;\n}\nexport function validateOutputs(outputs: KanbanArtifactRef[]): void {\n requireValue(Array.isArray(outputs)&&outputs.length<=100&&outputs.every(output=>output&&typeof output==='object'&&typeof output.name==='string')&&new Set(outputs.map(output=>output.name)).size===outputs.length,'INVALID_OUTPUTS');\n for(const output of outputs) requireValue(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(output.name)&&typeof output.ref==='string'&&output.ref.length>0&&output.ref.length<=2048\n &&/^[a-f0-9]{64}$/.test(output.sha256)&&Number.isSafeInteger(output.bytes)&&output.bytes>=0,'INVALID_OUTPUT_REFERENCE');\n}\nexport function refreshReady(state: KanbanState): void {\n if(!state.workflow) return; const all=catalog(state), included=new Set(Object.values(state.workflow.plans).filter(plan=>plan.sealed).flatMap(plan=>plan.itemIds));\n state.workflow.completedPlans=Object.values(state.workflow.plans).filter(plan=>plan.sealed&&plan.itemIds.every(id=>all.find(item=>item.id===id)?.status==='completed')).map(plan=>plan.id);\n state.workflow.ready=state.board.items.filter(item=>included.has(item.id)&&executableWorkItem(state.board,item)&&['backlog','open'].includes(item.status)&&!item.owner&&!item.blocked&&item.control?.action!=='pause'\n &&(item.planning?.dependencies ?? []).every(id=>all.find(other=>other.id===id)?.status==='completed')).map(item=>item.id);\n}\n","import {taskEditing} from './contracts/task-projection';\nimport type {KanbanActor, KanbanBoard, KanbanCommand, KanbanItem, KanbanPrincipal} from './contracts';\nimport type {KanbanState} from './ports';\nimport type {PlanningCommand} from './planning-commands';\nimport {assertReady, limits, catalog, terminal} from './planning';\nimport {eligible, principal, principalKey, assigneeKey, candidates} from './identity';\nimport {owned, participant, requireValue, text, validateEstimate} from './rules';\n\ntype ItemCommand = Exclude<KanbanCommand, import('./contracts').KanbanTaskCommand | import('./contracts').KanbanWorkflowCommand | PlanningCommand | {type: 'set-board-control' | 'delete-board' | 'append-record' | 'review-record' | 'link-record' | 'review-amendment' | 'configure-automation'} | {type: 'create-item' | 'register-session' | 'message' | 'scan' | 'apply-discovery' | 'publish-proposal'}>;\nexport function transition(state: KanbanState, item: KanbanItem, command: ItemCommand, actor: KanbanActor, now: number, token: string): void {\n requireValue(item.status !== 'completed' && item.status !== 'cancelled', 'ITEM_COMPLETED');\n if (command.type === 'claim' || command.type === 'accept-transfer') claim(state, item, command, actor, now, token);\n else if (command.type === 'review') review(state, item, command.accept, actor, now);\n else {\n owned(item, actor, command.token, now);\n if (command.type === 'submit') requireValue(catalog(state).filter(i => i.planning.parentId === item.id).every(terminal), 'CHILDREN_UNFINISHED');\n ownerUpdate(state.board, item, command, now, token);}\n if (command.type !== 'renew') {item.revision++; item.updatedAt = now;}\n}\nfunction claim(state: KanbanState, item: KanbanItem, command: Extract<ItemCommand, {type: 'claim' | 'accept-transfer'}>, actor: KanbanActor, now: number, token: string): void {\n const board = state.board, key = principalKey(principal(actor));\n requireValue(!taskEditing(item,now),'EDIT_LEASE_ACTIVE');\n eligible(board, item, actor); assertReady(state, item);\n requireValue(command.estimate || board.policy.requireEstimate === false, 'ESTIMATE_REQUIRED'); if (command.estimate) validateEstimate(command.estimate);\n const wip = board.items.filter(i => i.status === 'claimed' || i.status === 'review');\n if (command.type === 'claim') requireValue(wip.length < limits(state).inProgress, 'WIP_LIMIT');\n requireValue(wip.filter(i => i.id !== item.id && i.owner && assigneeKey(i.owner) === key).length < limits(state).perAssignee, principal(actor).kind === 'agent' ? 'AGENT_WIP_LIMIT' : 'ASSIGNEE_WIP_LIMIT');\n if (command.type === 'claim') requireValue(item.status === 'open' && !item.owner, 'ALREADY_OWNED');\n else {\n requireValue(item.status === 'claimed' && item.transfer && principalKey(transferTarget(item.transfer)) === key, 'TRANSFER_NOT_OFFERED');\n requireValue(item.transfer.expiresAt > now && item.owner && item.owner.leaseUntil > now, 'TRANSFER_EXPIRED');\n requireValue(assigneeKey(item.owner) !== key, 'SELF_TRANSFER');\n }\n item.owner = {...actor, principalId: key, token, claimedAt: now, leaseUntil: now + board.policy.leaseMs};\n item.estimate = command.estimate; item.status = 'claimed'; item.progressAt = now; delete item.transfer;\n if (actor.sessionId) participant(item.participants, actor.sessionId, actor.agentId, 'owner', true, now);\n}\nfunction review(state: KanbanState, item: KanbanItem, accept: boolean, actor: KanbanActor, now: number): void {\n requireValue(item.status === 'review', 'NOT_IN_REVIEW');\n const key = principalKey(principal(actor));\n const registered = actor.sessionId && item.participants.some(p => p.sessionId === actor.sessionId && p.roles.includes('reviewer'))\n || state.board.members?.some(m => principalKey(m) === key && m.roles?.includes('reviewer'));\n requireValue(registered, 'REVIEWER_REQUIRED');\n requireValue(!item.owner || assigneeKey(item.owner) !== key, 'INDEPENDENT_REVIEW_REQUIRED');\n item.status = accept ? 'completed' : state.board.items.filter(i => i.status === 'open').length < limits(state).ready ? 'open' : 'backlog';\n if (accept) item.closedAt = now;\n if (!accept) {delete item.owner; delete item.estimate; delete item.resultRef; item.readyAt = now;}\n}\nfunction ownerUpdate(board: KanbanBoard, item: KanbanItem, command: Exclude<ItemCommand, {type: 'claim' | 'accept-transfer' | 'review'}>, now: number, token: string): void {\n switch (command.type) {\n case 'renew': item.owner!.leaseUntil = now + board.policy.leaseMs; break;\n case 'progress':\n requireValue(Number.isFinite(command.workUnits) && command.workUnits >= item.workUnits, 'INVALID_WORK_UNITS');\n item.workUnits = command.workUnits; item.progressAt = now;\n if (command.estimate) {validateEstimate(command.estimate); item.estimate = command.estimate;} break;\n case 'request-transfer': requestTransfer(board, item, command, now, token); break;\n case 'submit':\n text(command.resultRef); item.resultRef = command.resultRef; item.status = board.policy.review === 'assignee' ? 'completed' : 'review';\n if (item.status === 'completed') item.closedAt = now; delete item.transfer; break;\n }\n}\nfunction requestTransfer(board: KanbanBoard, item: KanbanItem, command: Extract<ItemCommand, {type: 'request-transfer'}>, now: number, token: string): void {\n requireValue(Boolean(command.target) !== Boolean(command.agentId), 'TRANSFER_TARGET_REQUIRED');\n const target = command.target ?? {kind: 'agent' as const, id: command.agentId!}, key = principalKey(target);\n requireValue(candidates(board, item).some(p => principalKey(p) === key), 'AGENT_NOT_ELIGIBLE');\n requireValue(assigneeKey(item.owner!) !== key, 'SELF_TRANSFER'); requireValue(!item.transfer, 'TRANSFER_ALREADY_PENDING');\n item.transfer = {id: token, target, ...(target.kind === 'agent' ? {agentId: target.id} : {}), requestedAt: now, expiresAt: now + board.policy.transferTimeoutMs};\n}\nfunction transferTarget(value: NonNullable<KanbanItem['transfer']>): KanbanPrincipal {return value.target ?? {kind: 'agent', id: value.agentId!};}\n","import {setBoardControl} from './board-control';\nimport {taskCommand, applyTaskCommand, assertDefinitionEditable, initializeTaskLaunch} from './task-commands';\nimport {TASK_START_DELAY_MS} from './contracts/task-projection';\nimport {applyDiscovery} from './scan-commit';\nimport {configureAutomation} from './automation';\nimport {applyWorkflow, isWorkflowCommand, refreshReady, protectWorkflowItem} from './workflow';\nimport {numberEntities} from './numbering';\nimport {isRecordCommand, applyRecord} from './project-records';\nimport {reviewAmendment} from './amendments';\nimport {principal} from './identity';\nimport type { KanbanActor, KanbanBoard, KanbanCommand, KanbanEvent, KanbanItem } from './contracts';\nimport type { KanbanState } from './ports';\nimport { identity, participant, requireValue, text } from './rules';\nimport { transition } from './transitions';\nimport {planningCommand, applyPlanningCommand, attachReference} from './planning-commands';\nimport {plan, setStage, validatePlan, terminal} from './planning';\nimport {executable} from './configuration';\nimport {validateCandidates} from './identity';\nimport {archiveExpired} from './archives';\n\nexport function reduce(state: KanbanState, command: KanbanCommand, actor: KanbanActor,\n operationId: string, now: number, token: string, workflowInternal = false): KanbanState {\n requireValue(state.board.deletedAt === undefined, 'BOARD_DELETED');\n numberEntities(state);\n if (!workflowInternal) protectWorkflowItem(state, command);\n const board = state.board;\n if (command.type === 'delete-board') return deleteBoard(state, actor, operationId, now);\n if (command.type === 'scan') { scan(state, actor, operationId, now); refreshReady(state); return state; }\n let recordEvent = command.type !== 'renew';\n if (command.type === 'set-board-control') setBoardControl(state, command, actor, now, token);\n else if (taskCommand(command)) applyTaskCommand(state, command, actor, now);\n else if (isWorkflowCommand(command)) recordEvent = applyWorkflow(state, command, actor, now, (inner, owner = actor) => {reduce(state,inner,owner,operationId,now,token,true);});\n else if (command.type === 'apply-discovery') applyDiscovery(state, command.batch, actor, now);\n else if (isRecordCommand(command)) applyRecord(state, command, actor, now);\n else if (command.type === 'review-amendment') {if(command.accept)assertDefinitionEditable(itemFor(board,command.itemId),now);reviewAmendment(board, command, actor, now);}\n else if (planningCommand(command)) applyPlanningCommand(state, command, now, actor, workflowInternal);\n else if (command.type === 'create-item') createItem(state, command, actor, now, token);\n else if (command.type === 'configure-automation') configureAutomation(board, command.settings, actor);\n else if (command.type === 'register-session') {\n const item = command.itemId ? itemFor(board, command.itemId) : undefined;\n const list = item ? item.participants : board.participants;\n participant(list, command.sessionId, command.agentId, command.role, command.subscribed, now);\n if (item) item.revision++;\n } else if (command.type === 'message') {\n text(command.message); command.recipientSessionIds.forEach(identity);\n if (command.itemId) itemFor(board, command.itemId);\n requireValue(command.recipientSessionIds.every(id => related(board).includes(id)), 'UNKNOWN_RECIPIENT');\n } else transition(state, itemFor(board, command.itemId), command, actor, now, token);\n numberEntities(state); refreshReady(state);\n board.revision++;\n if (recordEvent) append(state, actor, operationId, now, command.type, 'itemId' in command ? command.itemId : command.type === 'create-item' ? command.item.id : 'dispatchId' in command ? state.workflow?.dispatches[command.dispatchId]?.itemId : undefined,\n eventData(command, state),\n command.type === 'message' ? command.recipientSessionIds : undefined);\n scan(state, actor, operationId, now);\n return state;\n}\nfunction createItem(state: KanbanState, command: Extract<KanbanCommand, { type: 'create-item' }>, actor: KanbanActor, now: number, token: string): void {\n const {id, title, responsibility, acceptance, eligibleAgentIds, eligiblePrincipals, externalRefs} = command.item;\n const input = {id, title, responsibility, acceptance, eligibleAgentIds, eligiblePrincipals, externalRefs}, board = state.board;\n identity(input.id); text(input.title); text(input.responsibility); text(input.acceptance);\n requireValue(!board.items.some(i => i.id === input.id) && !state.archiveIndex?.some(i => i.id === input.id), 'ITEM_EXISTS');\n const item: KanbanItem = { ...input, origin: {kind: 'direct', principal: principal(actor)}, status: 'backlog', revision: 1, createdAt: now, readyAt: now, updatedAt: now, workUnits: 0, participants: [] };\n item.launch = {startAt: now + TASK_START_DELAY_MS};\n requireValue(command.launch?.mode === undefined || ['automatic', 'manual'].includes(command.launch.mode), 'INVALID_LAUNCH_MODE');\n requireValue(command.launch?.paused === undefined || typeof command.launch.paused === 'boolean', 'INVALID_TASK_PAUSE');\n if (command.launch?.mode) item.launch!.mode = command.launch.mode;\n if (command.launch?.paused) item.control = {id: 'initial-' + token, action: 'pause', state: 'paused'};\n item.planning = command.planning ?? {...plan(item), kind: board.defaultWorkType ?? 'task'};\n const references = item.externalRefs ?? []; item.externalRefs = [];\n for (const reference of references) attachReference(item, reference);\n validateCandidates(board, item, executable(board, item)); validatePlan(state, item, item.planning);\n if(item.planning.parentId) {\n const parent=board.items.find(parent=>parent.id===item.planning!.parentId)!;\n if(parent.planning?.execution!=='children') {parent.planning={...plan(parent),execution:'children'};parent.updatedAt=now;parent.revision++;}\n }\n if (actor.sessionId) participant(item.participants, actor.sessionId, actor.agentId, 'creator', true, now); board.items.push(item);\n if (command.stage === 'open') setStage(state, item, 'open', now);\n}\nfunction itemFor(board: KanbanBoard, id: string): KanbanItem {\n const item = board.items.find(value => value.id === id); requireValue(item, 'ITEM_NOT_FOUND'); return item;\n}\nexport function related(board: KanbanBoard): string[] {\n return [...new Set([...board.participants, ...board.items.flatMap(i => i.participants)].map(p => p.sessionId))];\n}\nfunction append(state: KanbanState, actor: KanbanActor, operationId: string, at: number, kind: string,\n itemId?: string, data: KanbanEvent['data'] = {}, recipients?: string[]): void {\n const archived = state.archiveWrites?.flatMap(write => write.value?.item.participants ?? []) ?? [];\n const members = [...archived, ...state.board.participants, ...state.board.items.filter(i => i.id === itemId).flatMap(i => i.participants)];\n state.events.push({ sequence: ++state.sequence, boardId: state.board.id, itemId, operationId, at, kind, actor,\n recipients: [...new Set(recipients ?? members.filter(p => p.subscribed).map(p => p.sessionId))], data });\n}\nfunction scan(state: KanbanState, actor: KanbanActor, operationId: string, now: number): void {\n for (const item of state.board.items) {\n if(initializeTaskLaunch(state,item)) {state.board.revision++;append(state,actor,operationId,now,'task-launch-initialized',item.id,{code:'LEGACY_LAUNCH_INITIALIZED'});}\n if (terminal(item)) continue;\n for (const reason of escalationReasons(state.board, item, now)) {\n const epoch = reason === 'transfer-timeout' ? item.transfer?.id : reason === 'backlog-review' ? item.updatedAt : item.owner?.token ?? item.readyAt;\n const key = JSON.stringify([item.id, epoch, reason]);\n if (state.escalations.includes(key)) continue;\n state.escalations.push(key); state.board.revision++;\n append(state, actor, operationId, now, 'escalated', item.id, { reason }, state.board.policy.escalationSessionIds);\n }\n if (item.transfer && item.transfer.expiresAt <= now) { delete item.transfer; item.revision++; item.updatedAt = now; state.board.revision++; }\n }\n const archived = archiveExpired(state, now);\n if (archived.length) {state.board.revision++; append(state, actor, operationId, now, 'items.archived', undefined, {reason: 'retention-policy'});}\n}\nexport function escalationReasons(board: KanbanBoard, item: KanbanItem, now: number): string[] {\n const p = board.policy, result: string[] = [];\n if (item.status === 'backlog' && p.backlogReviewMs && now - item.updatedAt >= p.backlogReviewMs) result.push('backlog-review');\n if (item.planning?.dueAt !== undefined && now >= item.planning.dueAt) result.push('due-date');\n if (item.blocked && now - item.blocked.at >= p.progressTimeoutMs) result.push('blocked-age');\n if (!item.blocked && item.status === 'open' && now - item.readyAt >= p.claimTimeoutMs) result.push('unclaimed');\n if (item.status === 'review' && now - item.updatedAt >= p.progressTimeoutMs) result.push('review-timeout');\n if (item.transfer && now >= item.transfer.expiresAt) result.push('transfer-timeout');\n if (item.status !== 'claimed' || !item.owner) return result;\n if (now >= item.owner.leaseUntil) result.push('lease-expired');\n if (now - (item.progressAt ?? item.owner.claimedAt) >= p.progressTimeoutMs) result.push('no-progress');\n if (now - item.owner.claimedAt >= Math.min(item.estimate?.durationMs ?? p.maxDurationMs, p.maxDurationMs)) result.push('execution-timeout');\n if ((item.estimate?.complexity ?? 0) >= p.maxComplexity) result.push('complexity-threshold');\n if (Math.max(item.workUnits, item.estimate?.workUnits ?? 0) >= p.maxWorkUnits) result.push('work-threshold');\n if ((item.estimate?.durationMs ?? 0) >= p.maxDurationMs) result.push('duration-threshold');\n return result;\n}\n\nfunction eventData(command: KanbanCommand, state: KanbanState): KanbanEvent['data'] {\n if (command.type === 'set-board-control') return {code: 'BOARD_' + (state.board.executionControl?.paused ? 'PAUSE_REQUESTED' : state.board.executionControl?.mode?.toUpperCase())};\n if (command.type === 'apply-discovery') return discoveryEvent(state, command.batch);\n if (command.type === 'report-analysis') return {code:command.status.code, reason:'analysis-'+command.status.state};\n if (command.type === 'control-receipt') return {code:command.code, reason:'control-'+command.state};\n if (isWorkflowCommand(command)) return {readyItemIds:state.workflow?.ready, ...('dispatchId' in command ? {dispatchId:command.dispatchId} : {planId:command.plan.id}), ...('outcome' in command ? {reason:`execution-${command.outcome}`, code: command.code, status: state.board.items.find(item => item.id === state.workflow?.dispatches[command.dispatchId]?.itemId)?.status} : command.type === 'accept-execution' ? {reason: command.accept ? 'accepted' : 'rejected'} : {})};\n if (command.type === 'create-item') return {itemTitle: command.item.title};\n if (command.type === 'link-reference') return {reference: command.reference};\n if (command.type === 'block-item') return {reason: command.reason};\n if (command.type === 'release-item') return {reason: command.next === 'cancelled' ? 'cancelled' : 'released'};\n if (command.type === 'review') return {reason: command.accept ? 'accepted' : 'rejected',\n dispatchId: Object.values(state.workflow?.dispatches ?? {}).find(dispatch => dispatch.itemId === command.itemId && dispatch.outcome === 'succeeded')?.id};\n if (command.type === 'append-record') return {recordId: command.record.id, reason: command.record.kind === 'decision' ? 'decision-draft' : 'log'};\n if (command.type === 'review-record' || command.type === 'link-record') return {recordId: command.recordId};\n if (command.type === 'archive-items') return {itemIds: command.itemIds, reason: command.reason};\n if (command.type === 'cancel-item') return {reason: command.reason};\n if (command.type === 'plan-item') return {planning: command.planning};\n if (command.type === 'message') return { message: command.message };\n if (command.type === 'submit') return { resultRef: command.resultRef };\n if (command.type === 'claim' || command.type === 'accept-transfer') return { estimate: command.estimate };\n if (command.type === 'progress') return { estimate: command.estimate, workUnits: command.workUnits };\n return {};\n}\n\nfunction discoveryEvent(state: KanbanState, batch: import('./contracts').KanbanDiscoveryBatch): KanbanEvent['data'] {\n return {itemIds: batch.changes.map(change => change.itemId), recordIds: batch.records?.filter(record => state.records?.some(entry => entry.id === record.id && entry.originRunId === batch.runId)).map(record => record.id),\n ...(state.board.items.some(item => item.amendments?.some(proposal => proposal.runId === batch.runId && proposal.status === 'pending')) ? {reason: 'amendment-proposed'} : state.board.items.some(item => item.status === 'proposed' && item.origin?.runId === batch.runId) ? {reason: 'proposal-created'} : {})};\n}\n\nfunction deleteBoard(state: KanbanState, actor: KanbanActor, operationId: string, now: number): KanbanState {\n const owner = principal(actor), board = state.board;\n requireValue(owner.kind === 'human' && board.members?.some(member => member.kind === owner.kind && member.id === owner.id && member.roles?.includes('coordinator')), 'COORDINATOR_REQUIRED');\n requireValue(!board.items.some(item => item.owner || item.transfer || item.status === 'claimed'), 'BOARD_EXECUTION_ACTIVE');\n requireValue(!Object.values(state.workflow?.dispatches ?? {}).some(dispatch => ['prepared', 'running', 'unknown', 'succeeded'].includes(dispatch.outcome)), 'BOARD_EXECUTION_UNSETTLED');\n board.deletedAt = now; board.revision++;\n if (board.automation) board.automation.enabled = false;\n if (state.workflow) state.workflow.ready = [];\n append(state, actor, operationId, now, 'delete-board');\n return state;\n}\n"]}
@@ -1,20 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/contracts/board-control.ts
2
- function boardAllowsStart(board, item) {
3
- return !_optionalChain([board, 'access', _ => _.executionControl, 'optionalAccess', _2 => _2.paused]) && (_optionalChain([board, 'access', _3 => _3.executionControl, 'optionalAccess', _4 => _4.mode]) !== "manual" || _optionalChain([item, 'optionalAccess', _5 => _5.launch, 'optionalAccess', _6 => _6.requestedAt]) !== void 0);
4
- }
5
- function boardControlPhase(board) {
6
- const policy = board.executionControl;
7
- const controls = Object.entries(_nullishCoalesce(_optionalChain([policy, 'optionalAccess', _7 => _7.controls]), () => ( {}))).flatMap(([id, controlId]) => {
8
- const item = board.items.find((item2) => item2.id === id);
9
- return item && !["completed", "cancelled", "review"].includes(item.status) && _optionalChain([item, 'access', _8 => _8.control, 'optionalAccess', _9 => _9.id]) === controlId ? [item.control] : [];
10
- });
11
- if (controls.some((control) => _optionalChain([control, 'optionalAccess', _10 => _10.state]) === "failed" || _optionalChain([control, 'optionalAccess', _11 => _11.state]) === "unknown")) return "error";
12
- if (controls.some((control) => _optionalChain([control, 'optionalAccess', _12 => _12.state]) === "requested" || _optionalChain([control, 'optionalAccess', _13 => _13.state]) === "accepted")) return _optionalChain([policy, 'optionalAccess', _14 => _14.paused]) ? "pausing" : "resuming";
13
- return _optionalChain([policy, 'optionalAccess', _15 => _15.paused]) ? "paused" : _nullishCoalesce(_optionalChain([policy, 'optionalAccess', _16 => _16.mode]), () => ( "automatic"));
14
- }
15
-
16
-
17
-
18
-
19
- exports.boardAllowsStart = boardAllowsStart; exports.boardControlPhase = boardControlPhase;
20
- //# sourceMappingURL=chunk-LSE6JG5I.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-LSE6JG5I.cjs","../src/contracts/board-control.ts"],"names":["item"],"mappings":"AAAA;ACOO,SAAS,gBAAA,CAAiB,KAAA,EAA8C,IAAA,EAA4C;AACvH,EAAA,OAAO,iBAAC,KAAA,mBAAM,gBAAA,6BAAkB,SAAA,GAAA,iBAAW,KAAA,qBAAM,gBAAA,6BAAkB,OAAA,IAAS,SAAA,mBAAY,IAAA,6BAAM,MAAA,6BAAQ,cAAA,IAAgB,KAAA,CAAA,CAAA;AAC1H;AACO,SAAS,iBAAA,CAAkB,KAAA,EAAoL;AAClN,EAAA,MAAM,OAAA,EAAS,KAAA,CAAM,gBAAA;AACrB,EAAA,MAAM,SAAA,EAAW,MAAA,CAAO,OAAA,kCAAQ,MAAA,6BAAQ,UAAA,UAAY,CAAC,GAAC,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,EAAA,EAAI,SAAS,CAAA,EAAA,GAAM;AACjF,IAAA,MAAM,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,IAAA,CAAK,CAAAA,KAAAA,EAAAA,GAAQA,KAAAA,CAAK,GAAA,IAAO,EAAE,CAAA;AACpD,IAAA,OAAO,KAAA,GAAQ,CAAC,CAAC,WAAA,EAAa,WAAA,EAAa,QAAQ,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,MAAM,EAAA,mBAAK,IAAA,qBAAK,OAAA,6BAAS,KAAA,IAAO,UAAA,EAAY,CAAC,IAAA,CAAK,OAAO,EAAA,EAAI,CAAC,CAAA;AAAA,EACrI,CAAC,CAAA;AACD,EAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,CAAA,OAAA,EAAA,mBAAW,OAAA,+BAAS,QAAA,IAAU,SAAA,mBAAY,OAAA,+BAAS,QAAA,IAAU,SAAS,CAAA,EAAG,OAAO,OAAA;AAClG,EAAA,GAAA,CAAI,QAAA,CAAS,IAAA,CAAK,CAAA,OAAA,EAAA,mBAAW,OAAA,+BAAS,QAAA,IAAU,YAAA,mBAAe,OAAA,+BAAS,QAAA,IAAU,UAAU,CAAA,EAAG,uBAAO,MAAA,+BAAQ,SAAA,EAAS,UAAA,EAAY,UAAA;AACnI,EAAA,uBAAO,MAAA,+BAAQ,SAAA,EAAS,SAAA,mCAAW,MAAA,+BAAQ,MAAA,UAAQ,aAAA;AACvD;ADLA;AACA;AACE;AACA;AACF,2FAAC","file":"/home/li/share/prj/x1/release/local-libraries/work/1ca933a0-6fe7-4e9c-b13b-76d7f318e0fb/source/libraries/kanban/dist/chunk-LSE6JG5I.cjs","sourcesContent":[null,"import type {KanbanBoard, KanbanItem} from './contracts';\n\nexport interface KanbanBoardControl {\n mode: 'automatic' | 'manual'; paused: boolean;\n controls: Record<string, string>;\n}\n/** Manual mode still honors an explicit per-task run request. */\nexport function boardAllowsStart(board: Pick<KanbanBoard, 'executionControl'>, item?: Pick<KanbanItem, 'launch'>): boolean {\n return !board.executionControl?.paused && (board.executionControl?.mode !== 'manual' || item?.launch?.requestedAt !== undefined);\n}\nexport function boardControlPhase(board: Pick<KanbanBoard, 'executionControl'> & {items: Array<Pick<KanbanItem, 'id' | 'status' | 'control'>>}): 'automatic' | 'manual' | 'pausing' | 'paused' | 'resuming' | 'error' {\n const policy = board.executionControl;\n const controls = Object.entries(policy?.controls ?? {}).flatMap(([id, controlId]) => {\n const item = board.items.find(item => item.id === id);\n return item && !['completed', 'cancelled', 'review'].includes(item.status) && item.control?.id === controlId ? [item.control] : [];\n });\n if (controls.some(control => control?.state === 'failed' || control?.state === 'unknown')) return 'error';\n if (controls.some(control => control?.state === 'requested' || control?.state === 'accepted')) return policy?.paused ? 'pausing' : 'resuming';\n return policy?.paused ? 'paused' : policy?.mode ?? 'automatic';\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/contracts/task-projection.ts"],"sourcesContent":["import type {KanbanDispatch,KanbanItem,KanbanItemSummary,KanbanWorkflowState,KanbanTaskProjection,KanbanTaskPhase} from './index';\n\ntype Item=Pick<KanbanItem,'id'|'status'|'createdAt'|'launch'|'analysis'|'control'|'issues'|'blocked'|'externalRefs'|'planning'>;\ntype Fact={phase:KanbanTaskPhase;reason?:string;actions?:KanbanTaskProjection['actions']};\nexport const TASK_START_DELAY_MS=300000;\nexport function taskStartAt(item:Pick<Item,'createdAt'|'launch'>):number {return item.launch?.startAt??item.createdAt+TASK_START_DELAY_MS;}\nexport function taskEditing(item:Pick<Item,'launch'>,now:number):boolean {return (item.launch?.editing?.expiresAt??0)>now;}\nexport function taskDue(item:Item,now:number):boolean {\n return !taskEditing(item,now)&&!item.blocked&&item.control?.action!=='pause'\n &&(item.launch?.requestedAt!==undefined||item.launch?.mode!=='manual'&&taskStartAt(item)<=now);\n}\n/** Ordered evidence projection shared by storage queries, CLI and UI. Session idle never proves acceptance. */\nexport function projectKanbanTask(item:Item,workflow?:KanbanWorkflowState,now=Date.now(),all:Array<Pick<KanbanItemSummary,'id'|'status'>>=[]):KanbanTaskProjection {\n const dispatch=Object.values(workflow?.dispatches??{}).filter(d=>d.itemId===item.id).sort((a,b)=>b.attempt-a.attempt)[0];\n const fact=terminalFact(item)??issueFact(item,dispatch)??failureFact(item,dispatch)??controlFact(item)??executionFact(item,dispatch)??waitingFact(item,now,all);\n return {...fact,startAt:taskStartAt(item),dispatchId:dispatch?.id,sessionId:dispatch?.executionSessionId,\n actions:[...fact.actions??[],...(dispatch||item.launch?.admittedAt!==undefined||['claimed','review','completed'].includes(item.status)?['fix' as const]:[]),...(dispatch?.executionSessionId?['open-session' as const]:[])]};\n}\nfunction terminalFact(item:Item):Fact|undefined {\n if(item.status==='completed'||item.status==='cancelled')return {phase:item.status};\n if(item.status==='review')return {phase:'review',actions:['review']};\n}\nfunction issueFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n const issue=item.issues?.find(i=>!i.resolvedBy&&(!dispatch||i.attemptId===dispatch.id));\n if(issue)return {phase:issue.type==='clarification'?'waiting-input':'error',reason:issue.id,actions:['resolve']};\n}\nfunction controlFact(item:Item):Fact|undefined {\n const control=item.control;if(!control)return;\n const reason=control.code;\n if(control.state==='unknown')return {phase:'unknown',reason};\n if(control.state==='failed')return {phase:'error',reason,actions:['resume']};\n if(control.action==='pause')return {phase:control.state==='paused'?'paused':'pausing',reason,actions:['resume']};\n if(['requested','accepted'].includes(control.state))return {phase:'resuming',reason};\n}\nfunction failureFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n if(dispatch?.outcome==='unknown'||item.analysis?.state==='unknown')return {phase:'unknown',reason:dispatch?.code??item.analysis?.code};\n if(dispatch&&['failed','cancelled','rejected'].includes(dispatch.outcome))return {phase:'error',reason:dispatch.code??dispatch.outcome};\n if(item.analysis?.state==='failed')return {phase:'error',reason:item.analysis.code};\n}\nfunction executionFact(item:Item,dispatch?:KanbanDispatch):Fact|undefined {\n if(item.blocked)return {phase:item.blocked.reason==='WORKSPACE_INPUT_REQUIRED'?'waiting-input':'error',reason:item.blocked.reason};\n if(dispatch?.outcome==='prepared')return {phase:'preparing'};\n if(dispatch?.outcome==='running'||item.status==='claimed')return {phase:'running',actions:dispatch?.controlCapabilities?.pause==='boundary'?['pause']:[]};\n}\nfunction waitingFact(item:Item,now:number,all:Array<Pick<KanbanItemSummary,'id'|'status'>>):Fact {\n const analysis=analysisFact(item);if(analysis)return analysis;\n const dependency=item.planning?.dependencies.find(id=>all.find(i=>i.id===id)?.status!=='completed');\n if(dependency)return {phase:'waiting-dependency',reason:'DEPENDENCY_UNFINISHED:'+dependency,actions:item.launch?.admittedAt===undefined?['edit','cancel']:[]};\n if(taskEditing(item,now))return {phase:'waiting-start',reason:'EDIT_LEASE_ACTIVE'};\n if(item.launch?.admittedAt!==undefined)return {phase:'queued'};\n return {phase:'waiting-start',reason:item.launch?.mode==='manual'?'MANUAL_START_REQUIRED':taskDue(item,now)?'ADMISSION_PENDING':'START_AT_PENDING',actions:['run','edit','pause','cancel']};\n}\nfunction analysisFact(item:Item):Fact|undefined {\n if(item.analysis?.state==='clarification')return {phase:'waiting-input',reason:item.analysis.reason};\n if(item.analysis?.state==='analyzing')return {phase:'analyzing'};\n}\n"],"mappings":"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","names":[]}