@llblab/pi-kit 0.19.2 → 0.21.0

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 (102) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +3 -3
  3. package/node_modules/@llblab/pi-state-flow/AGENTS.md +6 -6
  4. package/node_modules/@llblab/pi-state-flow/CHANGELOG.md +9 -0
  5. package/node_modules/@llblab/pi-state-flow/README.md +4 -4
  6. package/node_modules/@llblab/pi-state-flow/dist/index.d.ts +2 -2
  7. package/node_modules/@llblab/pi-state-flow/dist/index.js +2 -2
  8. package/node_modules/@llblab/pi-state-flow/dist/lib/durable.d.ts +1 -0
  9. package/node_modules/@llblab/pi-state-flow/dist/lib/durable.js +7 -3
  10. package/node_modules/@llblab/pi-state-flow/dist/lib/extension.js +41 -11
  11. package/node_modules/@llblab/pi-state-flow/dist/lib/git.d.ts +6 -0
  12. package/node_modules/@llblab/pi-state-flow/dist/lib/git.js +94 -1
  13. package/node_modules/@llblab/pi-state-flow/dist/lib/protocol.js +2 -5
  14. package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.d.ts +2 -0
  15. package/node_modules/@llblab/pi-state-flow/dist/lib/runtime.js +11 -0
  16. package/node_modules/@llblab/pi-state-flow/dist/lib/status.d.ts +4 -2
  17. package/node_modules/@llblab/pi-state-flow/dist/lib/status.js +8 -2
  18. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.d.ts +6 -1
  19. package/node_modules/@llblab/pi-state-flow/dist/lib/telegram.js +19 -6
  20. package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.d.ts +5 -0
  21. package/node_modules/@llblab/pi-state-flow/dist/lib/temporal.js +27 -3
  22. package/node_modules/@llblab/pi-state-flow/dist/lib/transition.js +2 -2
  23. package/node_modules/@llblab/pi-state-flow/dist/package.json +1 -1
  24. package/node_modules/@llblab/pi-state-flow/docs/architecture.md +10 -8
  25. package/node_modules/@llblab/pi-state-flow/docs/lazy-state.md +2 -2
  26. package/node_modules/@llblab/pi-state-flow/docs/temporal-acceptance.md +4 -3
  27. package/node_modules/@llblab/pi-state-flow/docs/usage.md +5 -5
  28. package/node_modules/@llblab/pi-state-flow/index.ts +2 -2
  29. package/node_modules/@llblab/pi-state-flow/lib/durable.ts +8 -3
  30. package/node_modules/@llblab/pi-state-flow/lib/extension.ts +41 -9
  31. package/node_modules/@llblab/pi-state-flow/lib/git.ts +83 -1
  32. package/node_modules/@llblab/pi-state-flow/lib/protocol.ts +2 -4
  33. package/node_modules/@llblab/pi-state-flow/lib/runtime.ts +11 -0
  34. package/node_modules/@llblab/pi-state-flow/lib/status.ts +10 -4
  35. package/node_modules/@llblab/pi-state-flow/lib/telegram.ts +23 -6
  36. package/node_modules/@llblab/pi-state-flow/lib/temporal.ts +29 -3
  37. package/node_modules/@llblab/pi-state-flow/lib/transition.ts +2 -2
  38. package/node_modules/@llblab/pi-state-flow/package.json +1 -1
  39. package/node_modules/@llblab/pi-telegram/AGENTS.md +9 -7
  40. package/node_modules/@llblab/pi-telegram/BACKLOG.md +13 -32
  41. package/node_modules/@llblab/pi-telegram/CHANGELOG.md +11 -0
  42. package/node_modules/@llblab/pi-telegram/README.md +4 -3
  43. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.d.ts +2 -2
  44. package/node_modules/@llblab/pi-telegram/dist/lib/bindings.js +3 -5
  45. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.d.ts +1 -1
  46. package/node_modules/@llblab/pi-telegram/dist/lib/bus-follower.js +93 -9
  47. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.d.ts +9 -3
  48. package/node_modules/@llblab/pi-telegram/dist/lib/bus-leader.js +231 -71
  49. package/node_modules/@llblab/pi-telegram/dist/lib/bus.d.ts +4 -0
  50. package/node_modules/@llblab/pi-telegram/dist/lib/bus.js +34 -7
  51. package/node_modules/@llblab/pi-telegram/dist/lib/extension.js +63 -2
  52. package/node_modules/@llblab/pi-telegram/dist/lib/journal.d.ts +3 -0
  53. package/node_modules/@llblab/pi-telegram/dist/lib/journal.js +13 -0
  54. package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.d.ts +2 -0
  55. package/node_modules/@llblab/pi-telegram/dist/lib/lifecycle.js +25 -4
  56. package/node_modules/@llblab/pi-telegram/dist/lib/locks.d.ts +1 -0
  57. package/node_modules/@llblab/pi-telegram/dist/lib/locks.js +32 -12
  58. package/node_modules/@llblab/pi-telegram/dist/lib/paths.d.ts +10 -0
  59. package/node_modules/@llblab/pi-telegram/dist/lib/paths.js +22 -1
  60. package/node_modules/@llblab/pi-telegram/dist/lib/polling.js +2 -2
  61. package/node_modules/@llblab/pi-telegram/dist/lib/queue.d.ts +1 -1
  62. package/node_modules/@llblab/pi-telegram/dist/lib/queue.js +1 -2
  63. package/node_modules/@llblab/pi-telegram/dist/lib/sync.d.ts +9 -0
  64. package/node_modules/@llblab/pi-telegram/dist/lib/sync.js +41 -1
  65. package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.d.ts +9 -1
  66. package/node_modules/@llblab/pi-telegram/dist/lib/telegram-api.js +23 -3
  67. package/node_modules/@llblab/pi-telegram/dist/lib/thread-cleanup-manager.js +7 -2
  68. package/node_modules/@llblab/pi-telegram/dist/lib/threads.d.ts +2 -0
  69. package/node_modules/@llblab/pi-telegram/dist/lib/threads.js +68 -37
  70. package/node_modules/@llblab/pi-telegram/dist/lib/updates.d.ts +6 -4
  71. package/node_modules/@llblab/pi-telegram/dist/lib/updates.js +134 -61
  72. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.d.ts +9 -0
  73. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-admission.js +49 -3
  74. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.d.ts +77 -6
  75. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-retirement.js +384 -8
  76. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-slots.d.ts +3 -0
  77. package/node_modules/@llblab/pi-telegram/dist/lib/workspace-slots.js +6 -0
  78. package/node_modules/@llblab/pi-telegram/dist/package.json +1 -1
  79. package/node_modules/@llblab/pi-telegram/docs/architecture.md +21 -14
  80. package/node_modules/@llblab/pi-telegram/docs/multi-instance-bus.md +31 -10
  81. package/node_modules/@llblab/pi-telegram/docs/updates.md +2 -0
  82. package/node_modules/@llblab/pi-telegram/lib/bindings.ts +5 -7
  83. package/node_modules/@llblab/pi-telegram/lib/bus-follower.ts +69 -12
  84. package/node_modules/@llblab/pi-telegram/lib/bus-leader.ts +236 -94
  85. package/node_modules/@llblab/pi-telegram/lib/bus.ts +39 -9
  86. package/node_modules/@llblab/pi-telegram/lib/extension.ts +69 -2
  87. package/node_modules/@llblab/pi-telegram/lib/journal.ts +14 -0
  88. package/node_modules/@llblab/pi-telegram/lib/lifecycle.ts +23 -4
  89. package/node_modules/@llblab/pi-telegram/lib/locks.ts +32 -13
  90. package/node_modules/@llblab/pi-telegram/lib/paths.ts +29 -1
  91. package/node_modules/@llblab/pi-telegram/lib/polling.ts +2 -2
  92. package/node_modules/@llblab/pi-telegram/lib/queue.ts +2 -3
  93. package/node_modules/@llblab/pi-telegram/lib/sync.ts +45 -1
  94. package/node_modules/@llblab/pi-telegram/lib/telegram-api.ts +30 -2
  95. package/node_modules/@llblab/pi-telegram/lib/thread-cleanup-manager.ts +11 -3
  96. package/node_modules/@llblab/pi-telegram/lib/threads.ts +73 -36
  97. package/node_modules/@llblab/pi-telegram/lib/updates.ts +145 -78
  98. package/node_modules/@llblab/pi-telegram/lib/workspace-admission.ts +67 -4
  99. package/node_modules/@llblab/pi-telegram/lib/workspace-retirement.ts +465 -7
  100. package/node_modules/@llblab/pi-telegram/lib/workspace-slots.ts +7 -0
  101. package/node_modules/@llblab/pi-telegram/package.json +1 -1
  102. package/package.json +3 -3
@@ -195,6 +195,12 @@ function normalizeFence(value, profileKey) {
195
195
  deletionIssuedAtMs: value.deletionIssuedAtMs,
196
196
  };
197
197
  }
198
+ if (value.phase === "deletion-rejected" &&
199
+ (value.destructiveKind === undefined || value.destructiveKind === "pressure-retirement") &&
200
+ isSafeTimestamp(value.deletionIssuedAtMs) && isSafeTimestamp(value.rejectionConfirmedAtMs)) {
201
+ return { ...base, destructiveKind: value.destructiveKind, phase: "deletion-rejected",
202
+ deletionIssuedAtMs: value.deletionIssuedAtMs, rejectionConfirmedAtMs: value.rejectionConfirmedAtMs };
203
+ }
198
204
  if (value.phase === "commit-ready" &&
199
205
  isSafeTimestamp(value.absenceConfirmedAtMs) &&
200
206
  (value.deletionIssuedAtMs === undefined ||
@@ -395,6 +401,10 @@ function areFencesEqual(left, right) {
395
401
  right.phase === "deletion-issued") {
396
402
  return left.deletionIssuedAtMs === right.deletionIssuedAtMs;
397
403
  }
404
+ if (left.phase === "deletion-rejected" && right.phase === "deletion-rejected") {
405
+ return left.deletionIssuedAtMs === right.deletionIssuedAtMs &&
406
+ left.rejectionConfirmedAtMs === right.rejectionConfirmedAtMs;
407
+ }
398
408
  return (left.phase === "commit-ready" &&
399
409
  right.phase === "commit-ready" &&
400
410
  left.absenceConfirmedAtMs === right.absenceConfirmedAtMs &&
@@ -1023,6 +1033,9 @@ export function createTelegramWorkspaceAdmissionLedger(options) {
1023
1033
  if (!areOwnersEqual(expected.owner, options.owner)) {
1024
1034
  authorityChanged("Telegram Workspace absence confirmation requires fence owner authority.");
1025
1035
  }
1036
+ if (expected.phase === "deletion-rejected") {
1037
+ authorityChanged("Rejected Telegram Workspace deletion cannot confirm absence.");
1038
+ }
1026
1039
  return transact((state) => {
1027
1040
  if (!state.fence || !isTelegramWorkspaceRetirementFence(state.fence)) {
1028
1041
  authorityChanged("Telegram Workspace retirement fence is absent or has another kind.");
@@ -1069,7 +1082,7 @@ export function createTelegramWorkspaceAdmissionLedger(options) {
1069
1082
  return { result: true, changed: true };
1070
1083
  });
1071
1084
  }
1072
- function completeRetirementFence(expected, expectedKind = "pressure-retirement") {
1085
+ function completeDestructiveFence(expected, expectedKind, requiredPhase) {
1073
1086
  validateExpectedFence(expected, options.profileKey);
1074
1087
  if (resolveTelegramWorkspaceDestructiveFenceKind(expected) !== expectedKind)
1075
1088
  authorityChanged("Telegram Workspace destructive fence kind changed.");
@@ -1084,13 +1097,44 @@ export function createTelegramWorkspaceAdmissionLedger(options) {
1084
1097
  if (!areFencesEqual(state.fence, expected)) {
1085
1098
  authorityChanged("Telegram Workspace retirement fence authority changed.");
1086
1099
  }
1087
- if (state.fence.phase !== "commit-ready") {
1088
- authorityChanged("Telegram Workspace retirement commit is not ready.");
1100
+ if (state.fence.phase !== requiredPhase) {
1101
+ authorityChanged(requiredPhase === "commit-ready"
1102
+ ? "Telegram Workspace retirement commit is not ready."
1103
+ : "Telegram Workspace retirement rejection is not confirmed.");
1089
1104
  }
1090
1105
  delete state.fence;
1091
1106
  return { result: true, changed: true };
1092
1107
  });
1093
1108
  }
1109
+ function confirmRetirementRejection(expected) {
1110
+ validateExpectedFence(expected, options.profileKey);
1111
+ if (resolveTelegramWorkspaceDestructiveFenceKind(expected) !== "pressure-retirement" ||
1112
+ !areOwnersEqual(expected.owner, options.owner) ||
1113
+ (expected.phase !== "deletion-issued" && expected.phase !== "deletion-rejected")) {
1114
+ authorityChanged("Telegram Workspace rejection requires exact issued retirement authority.");
1115
+ }
1116
+ return transact((state) => {
1117
+ const current = state.fence;
1118
+ if (!current || !isTelegramWorkspaceRetirementFence(current) || !areFenceBasesEqual(current, expected) ||
1119
+ (current.phase !== "deletion-issued" && current.phase !== "deletion-rejected") ||
1120
+ current.deletionIssuedAtMs !== expected.deletionIssuedAtMs ||
1121
+ (expected.phase === "deletion-rejected" && !areFencesEqual(current, expected))) {
1122
+ authorityChanged("Telegram Workspace retirement fence authority changed.");
1123
+ }
1124
+ if (current.phase === "deletion-rejected")
1125
+ return { result: cloneFence(current), changed: false };
1126
+ const rejected = { ...current,
1127
+ destructiveKind: "pressure-retirement", phase: "deletion-rejected", rejectionConfirmedAtMs: getNowMs() };
1128
+ state.fence = rejected;
1129
+ return { result: cloneFence(rejected), changed: true };
1130
+ });
1131
+ }
1132
+ function completeRetirementFence(expected, expectedKind = "pressure-retirement") {
1133
+ return completeDestructiveFence(expected, expectedKind, "commit-ready");
1134
+ }
1135
+ function completeRejectedRetirementFence(expected) {
1136
+ return completeDestructiveFence(expected, "pressure-retirement", "deletion-rejected");
1137
+ }
1094
1138
  function adoptThreadCleanupFence(expected, replacement) {
1095
1139
  return adoptRetirementFence(expected, replacement, "manual-thread-cleanup");
1096
1140
  }
@@ -1128,6 +1172,8 @@ export function createTelegramWorkspaceAdmissionLedger(options) {
1128
1172
  issueThreadCleanupDeletionPermit,
1129
1173
  confirmRetirementAbsence,
1130
1174
  confirmThreadCleanupAbsence,
1175
+ confirmRetirementRejection,
1176
+ completeRejectedRetirementFence,
1131
1177
  releaseUnissuedRetirementFence,
1132
1178
  releaseUnissuedThreadCleanupFence,
1133
1179
  completeRetirementFence,
@@ -1,10 +1,12 @@
1
1
  /**
2
- * Workspace retirement preparation
2
+ * Workspace slot rotation
3
3
  * Zones: telegram, workspace identity, lifecycle
4
- * Owns fail-closed protection composition, pressure selection, exact-intent admission,
5
- * successor adoption, and gated mocked deletion with durable retirement commit.
4
+ * Owns fail-closed protection, demand-driven pressure retirement, exact-intent admission,
5
+ * successor recovery, and fenced one-shot deletion before durable slot reuse.
6
6
  */
7
+ import type { TelegramUpdateJournalDeadQueueOwnerRecoveryInput, TelegramUpdateJournalDeadQueueOwnerRecoveryResult, TelegramUpdateJournalEntry, TelegramUpdateJournalQueueOwnerIdentity } from "./journal.ts";
7
8
  import type { TelegramTarget } from "./target.ts";
9
+ import { type TelegramWorkspaceThreadDeletionTransport } from "./telegram-api.ts";
8
10
  import type { TelegramTopicTargetStore, TelegramWorkspaceExternalProtectionEvidence, TelegramWorkspaceRetirementIntent, TelegramWorkspaceProtectionState, TelegramWorkspaceThreadBinding } from "./threads.ts";
9
11
  import { type TelegramWorkspaceAdmissionLedger, type TelegramWorkspaceAdmissionScope, type TelegramWorkspaceDeletionPermit } from "./workspace-admission.ts";
10
12
  export interface TelegramWorkspaceOperationGate {
@@ -36,6 +38,11 @@ interface TelegramWorkspaceJournalReader {
36
38
  }[];
37
39
  };
38
40
  };
41
+ readForProtection?: () => {
42
+ entries: readonly {
43
+ update: unknown;
44
+ }[];
45
+ };
39
46
  }
40
47
  export declare function captureTelegramWorkspaceJournalProtectionSources(input: {
41
48
  binding: TelegramWorkspaceThreadBinding;
@@ -134,6 +141,54 @@ export declare function createTelegramWorkspaceExternalProtectionCapture(deps: {
134
141
  getJournalWriterProtection?: (journalBindingKey: string) => TelegramWorkspaceProtectionState;
135
142
  getDeliveryAuthorityProtection?: (binding: TelegramWorkspaceThreadBinding) => TelegramWorkspaceProtectionState;
136
143
  }): (binding: TelegramWorkspaceThreadBinding) => TelegramWorkspaceExternalProtectionEvidence;
144
+ export declare function isCurrentTelegramWorkspaceBinding(store: Pick<TelegramTopicTargetStore, "listWorkspaceBindings">, expected: TelegramWorkspaceThreadBinding): boolean;
145
+ export interface TelegramWorkspaceDeadQueueJournalBinding {
146
+ recoveryKey?: string;
147
+ readForProtection?: () => {
148
+ entries: readonly TelegramUpdateJournalEntry[];
149
+ };
150
+ journal: {
151
+ recoverDeadQueueOwner: (input: TelegramUpdateJournalDeadQueueOwnerRecoveryInput) => TelegramUpdateJournalDeadQueueOwnerRecoveryResult;
152
+ };
153
+ }
154
+ export type TelegramWorkspaceDeadQueueReclamation = {
155
+ kind: "not-needed";
156
+ } | {
157
+ kind: "recovered";
158
+ receipts: number;
159
+ updateIds: number[];
160
+ } | {
161
+ kind: "blocked";
162
+ reason: "authority-changed" | "live-owner" | "local-work" | "incomplete-source" | "unsupported-custody" | "owner-alive" | "owner-unverifiable" | "mutation-refused" | "protection-retained";
163
+ };
164
+ /**
165
+ * Demand-only preparation for pressure retirement. Every removed group is still
166
+ * owned by the journal's exact dead-owner CAS; this function never clears local
167
+ * queue memory or turns unknown evidence into deletion authority.
168
+ */
169
+ export declare function createTelegramWorkspaceDeadOwnerQueueReclaimer(deps: {
170
+ getExternalProtection: (binding: TelegramWorkspaceThreadBinding) => TelegramWorkspaceExternalProtectionEvidence;
171
+ getActiveTurnTarget: () => TelegramTarget | undefined;
172
+ getQueuedItems: () => readonly {
173
+ chatId: number;
174
+ target?: TelegramTarget;
175
+ }[];
176
+ resolveLeaderJournal: () => TelegramWorkspaceDeadQueueJournalBinding | undefined;
177
+ createFollowerJournalResolver: (journalBindingKey: string) => () => TelegramWorkspaceDeadQueueJournalBinding | undefined;
178
+ discoverFollowerJournals?: () => {
179
+ paths: readonly string[];
180
+ complete: boolean;
181
+ };
182
+ createJournalPathResolver?: (path: string) => () => TelegramWorkspaceDeadQueueJournalBinding | undefined;
183
+ withJournalReference?: <T>(binding: TelegramWorkspaceDeadQueueJournalBinding, operation: () => T) => T;
184
+ getRecoveryOwner: () => TelegramUpdateJournalQueueOwnerIdentity;
185
+ getQueueOwnerLiveness: (owner: {
186
+ processId: number;
187
+ processBirthId: string;
188
+ }) => "alive" | "dead" | "unverifiable";
189
+ isBindingCurrent: (binding: TelegramWorkspaceThreadBinding) => boolean;
190
+ onMutationError?: (error: unknown) => void;
191
+ }): (binding: TelegramWorkspaceThreadBinding, isCurrent: () => boolean) => Promise<TelegramWorkspaceDeadQueueReclamation>;
137
192
  export type TelegramWorkspaceRetirementAdoption = {
138
193
  kind: "adopted";
139
194
  intent: TelegramWorkspaceRetirementIntent;
@@ -154,14 +209,17 @@ export type TelegramWorkspaceRetirementExecution = {
154
209
  kind: "retired";
155
210
  bindingKey: string;
156
211
  slot: string;
212
+ } | {
213
+ kind: "cancelled";
214
+ reason: "delete-rejected";
157
215
  } | {
158
216
  kind: "retained";
159
- reason: "stale-intent" | "protection-changed" | "admission-active" | "fence-conflict" | "delete-unconfirmed" | "authority-changed" | "commit-rejected" | "fence-release-unconfirmed";
217
+ reason: "stale-intent" | "protection-changed" | "admission-active" | "fence-conflict" | "delete-unconfirmed" | "delete-rejected" | "authority-changed" | "commit-rejected" | "fence-release-unconfirmed";
160
218
  };
161
219
  export type TelegramWorkspaceRetirementAbsence = "absent" | "present" | "unknown";
162
220
  export declare function executeTelegramWorkspaceRetirement(input: {
163
- store: Pick<TelegramTopicTargetStore, "captureWorkspaceSlotOccupancy" | "listWorkspaceBindings" | "listWorkspaceRetirementIntents" | "commitWorkspaceRetirement">;
164
- admission: Pick<TelegramWorkspaceAdmissionLedger, "getOwner" | "read" | "acquireRetirementFence" | "adoptRetirementFence" | "issueDeletionPermit" | "confirmRetirementAbsence" | "releaseUnissuedRetirementFence" | "completeRetirementFence">;
221
+ store: Pick<TelegramTopicTargetStore, "captureWorkspaceSlotOccupancy" | "listWorkspaceBindings" | "listWorkspaceRetirementIntents" | "commitWorkspaceRetirement" | "removeWorkspaceRetirementIntent" | "persist">;
222
+ admission: Pick<TelegramWorkspaceAdmissionLedger, "getOwner" | "read" | "acquireRetirementFence" | "adoptRetirementFence" | "issueDeletionPermit" | "confirmRetirementAbsence" | "confirmRetirementRejection" | "completeRejectedRetirementFence" | "releaseUnissuedRetirementFence" | "completeRetirementFence">;
165
223
  intent: TelegramWorkspaceRetirementIntent;
166
224
  getExternalProtection: (binding: TelegramWorkspaceThreadBinding) => TelegramWorkspaceExternalProtectionEvidence;
167
225
  getLeaderEpoch: () => number | string | undefined;
@@ -216,4 +274,17 @@ export declare function runTelegramWorkspaceRetirementLifecycle(input: {
216
274
  deleteForumTopic: Parameters<typeof executeTelegramWorkspaceRetirement>[0]["deleteForumTopic"];
217
275
  confirmTargetAbsent?: Parameters<typeof executeTelegramWorkspaceRetirement>[0]["confirmTargetAbsent"];
218
276
  }): Promise<TelegramWorkspaceRetirementLifecycleResult>;
277
+ export type TelegramWorkspaceCapacityRunner = <T>(operation: () => Promise<T>) => Promise<T>;
278
+ export interface TelegramWorkspaceSlotRotationPorts extends TelegramWorkspaceOperationGate {
279
+ getAdmission: () => TelegramWorkspaceAdmissionLedger | undefined;
280
+ deleteThread: TelegramWorkspaceThreadDeletionTransport;
281
+ reclaimDeadOwnerQueuedWork?: (binding: TelegramWorkspaceThreadBinding, isCurrent: () => boolean) => Promise<TelegramWorkspaceDeadQueueReclamation>;
282
+ }
283
+ /** Retry allocation once, only after the failed operation released all ordinary leases. */
284
+ export declare function createTelegramWorkspaceSlotRotation(input: TelegramWorkspaceSlotRotationPorts & {
285
+ store: TelegramTopicTargetStore;
286
+ getLeaderEpoch: () => number | string | undefined;
287
+ getExternalProtection: (binding: TelegramWorkspaceThreadBinding) => TelegramWorkspaceExternalProtectionEvidence;
288
+ recordEvent: (message: string, details: Record<string, unknown>) => void;
289
+ }): TelegramWorkspaceCapacityRunner;
219
290
  export {};