toolroll 0.9.52 → 0.9.54

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 (187) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +55 -80
  3. package/dist/agentconfig.d.ts +11 -36
  4. package/dist/agentconfig.js +3 -62
  5. package/dist/approval-policy.d.ts +1 -1
  6. package/dist/approval-policy.js +1 -1
  7. package/dist/board.d.ts +3 -19
  8. package/dist/board.js +4 -42
  9. package/dist/browser/workspace.js +18 -18
  10. package/dist/browser-workspace.d.ts +2 -1
  11. package/dist/builder.d.ts +9 -40
  12. package/dist/builder.js +50 -257
  13. package/dist/chat-actions.js +3 -14
  14. package/dist/chat-ask.js +8 -8
  15. package/dist/chat-controls.d.ts +0 -4
  16. package/dist/chat-controls.js +0 -1
  17. package/dist/chat-core.d.ts +171 -0
  18. package/dist/chat-core.js +288 -0
  19. package/dist/chat-decide.d.ts +10 -8
  20. package/dist/chat-decide.js +27 -24
  21. package/dist/chat-delivery-state.d.ts +51 -75
  22. package/dist/chat-delivery-state.js +140 -170
  23. package/dist/chat-delivery.d.ts +21 -4
  24. package/dist/chat-delivery.js +313 -195
  25. package/dist/chat-flow.d.ts +29 -1
  26. package/dist/chat-flow.js +24 -50
  27. package/dist/chat-messages.d.ts +319 -0
  28. package/dist/chat-messages.js +841 -0
  29. package/dist/chat-migration.d.ts +30 -0
  30. package/dist/chat-migration.js +802 -0
  31. package/dist/chat-quiet.d.ts +3 -0
  32. package/dist/chat-quiet.js +7 -2
  33. package/dist/chat-task-actions.d.ts +1 -1
  34. package/dist/chat-task-actions.js +0 -2
  35. package/dist/claim.d.ts +79 -244
  36. package/dist/claim.js +688 -1023
  37. package/dist/cli.d.ts +2 -0
  38. package/dist/cli.js +10 -2
  39. package/dist/contracts/chat-content.d.ts +71 -2
  40. package/dist/contracts/chat-content.js +22 -3
  41. package/dist/contracts/chat-tables.d.ts +11 -4
  42. package/dist/contracts/chat-tables.js +165 -87
  43. package/dist/contracts/cli.d.ts +0 -13
  44. package/dist/contracts/cli.js +0 -2
  45. package/dist/contracts/console-api.d.ts +5 -10
  46. package/dist/contracts/console-api.js +4 -10
  47. package/dist/contracts/discord-callback.js +2 -1
  48. package/dist/contracts/flow.d.ts +50 -0
  49. package/dist/contracts/flow.js +26 -1
  50. package/dist/contracts/lead-tools.d.ts +0 -13
  51. package/dist/contracts/lead-tools.js +3 -3
  52. package/dist/contracts/slack-callback.js +3 -2
  53. package/dist/contracts/store-json.d.ts +1 -29
  54. package/dist/contracts/store-json.js +4 -17
  55. package/dist/contracts/teams-callback.js +2 -1
  56. package/dist/converse.d.ts +1 -11
  57. package/dist/converse.js +6 -38
  58. package/dist/coordinator.d.ts +0 -1
  59. package/dist/coordinator.js +3 -5
  60. package/dist/demo.js +16 -26
  61. package/dist/desktop-update-gate.js +0 -1
  62. package/dist/desktop-update.js +1 -3
  63. package/dist/discord-chat.js +19 -38
  64. package/dist/discord-settings.js +4 -13
  65. package/dist/discord.js +4 -14
  66. package/dist/dispatch.d.ts +1 -1
  67. package/dist/dispatch.js +1 -1
  68. package/dist/dispose.d.ts +2 -3
  69. package/dist/dispose.js +17 -92
  70. package/dist/envelope.js +0 -3
  71. package/dist/exec.d.ts +0 -64
  72. package/dist/exec.js +3 -356
  73. package/dist/exhaustion.d.ts +22 -76
  74. package/dist/exhaustion.js +14 -140
  75. package/dist/export.js +8 -8
  76. package/dist/flow-engine.js +1 -1
  77. package/dist/flow-schedule.d.ts +154 -0
  78. package/dist/flow-schedule.js +321 -0
  79. package/dist/flow-share.js +1 -1
  80. package/dist/flow-triggers.d.ts +6 -1
  81. package/dist/flow-triggers.js +65 -10
  82. package/dist/flows-cli.js +8 -4
  83. package/dist/flows-ui.js +2 -0
  84. package/dist/flows.js +1 -1
  85. package/dist/guides.js +9 -29
  86. package/dist/invoke.d.ts +1 -24
  87. package/dist/invoke.js +17 -259
  88. package/dist/lead-status.js +2 -4
  89. package/dist/lead-voice.js +1 -1
  90. package/dist/mate-doors.d.ts +1 -2
  91. package/dist/mate-doors.js +12 -25
  92. package/dist/mate-tools.d.ts +2 -2
  93. package/dist/mate-tools.js +13 -24
  94. package/dist/modes.d.ts +19 -8
  95. package/dist/modes.js +24 -14
  96. package/dist/notification-rows.d.ts +30 -0
  97. package/dist/notification-rows.js +102 -0
  98. package/dist/operate-remote-arguments.js +2 -6
  99. package/dist/operate-remote.js +6 -7
  100. package/dist/operate.d.ts +0 -6
  101. package/dist/operate.js +226 -2248
  102. package/dist/phase-routing.d.ts +13 -23
  103. package/dist/phase-routing.js +13 -35
  104. package/dist/plan-auto.js +2 -2
  105. package/dist/plane-review.js +5 -11
  106. package/dist/planner-source.js +2 -1
  107. package/dist/policy.d.ts +1 -4
  108. package/dist/policy.js +0 -8
  109. package/dist/process-recovery-eligibility.js +2 -3
  110. package/dist/project-delete.js +24 -41
  111. package/dist/proposal.d.ts +4 -24
  112. package/dist/proposal.js +3 -88
  113. package/dist/provider-auth.d.ts +3 -3
  114. package/dist/provider-auth.js +4 -6
  115. package/dist/provider.d.ts +11 -25
  116. package/dist/provider.js +4 -36
  117. package/dist/push.js +1 -1
  118. package/dist/recipe-ui.js +6 -6
  119. package/dist/recipes.d.ts +3 -3
  120. package/dist/recipes.js +27 -23
  121. package/dist/result-shots.js +2 -2
  122. package/dist/retention.js +1 -1
  123. package/dist/run-closeout.d.ts +1 -1
  124. package/dist/run-closeout.js +1 -4
  125. package/dist/scope.d.ts +11 -65
  126. package/dist/scope.js +17 -82
  127. package/dist/serve.js +15 -24
  128. package/dist/server/chat.js +7 -30
  129. package/dist/server/flows.js +11 -10
  130. package/dist/server/guards.js +0 -1
  131. package/dist/server/pages-assets.js +1 -1
  132. package/dist/server/pages.js +0 -2
  133. package/dist/server/people-tokens.js +0 -4
  134. package/dist/server/route-table.d.ts +1 -1
  135. package/dist/server/route-table.js +2 -17
  136. package/dist/server/settings.js +6 -12
  137. package/dist/server/shared.d.ts +28 -212
  138. package/dist/server/shared.js +71 -780
  139. package/dist/server/task-views.js +9 -76
  140. package/dist/server/tasks.d.ts +1 -50
  141. package/dist/server/tasks.js +36 -946
  142. package/dist/setup-guide.d.ts +2 -2
  143. package/dist/slack-api.d.ts +5 -1
  144. package/dist/slack-api.js +2 -2
  145. package/dist/slack-chat.d.ts +9 -6
  146. package/dist/slack-chat.js +29 -53
  147. package/dist/slack-settings.js +6 -15
  148. package/dist/slack.js +6 -16
  149. package/dist/store.d.ts +200 -1702
  150. package/dist/store.js +811 -5439
  151. package/dist/surface.js +10 -24
  152. package/dist/task-composer.d.ts +1 -1
  153. package/dist/task-composer.js +1 -1
  154. package/dist/task-control.d.ts +3 -10
  155. package/dist/task-control.js +2 -7
  156. package/dist/teammate-desk.js +1 -1
  157. package/dist/teammate-question.js +12 -12
  158. package/dist/teammates-ui.js +1 -1
  159. package/dist/teams-chat.js +12 -9
  160. package/dist/teams-settings.js +2 -2
  161. package/dist/teams.js +4 -5
  162. package/dist/telegram-flow.js +5 -5
  163. package/dist/telegram-mate.d.ts +0 -3
  164. package/dist/telegram-mate.js +0 -1
  165. package/dist/telegram.js +4 -4
  166. package/dist/templates.d.ts +11 -7
  167. package/dist/templates.js +12 -9
  168. package/dist/toolroll-update.d.ts +20 -0
  169. package/dist/toolroll-update.js +104 -5
  170. package/dist/work-index.js +2 -6
  171. package/dist/workspace-revision.js +3 -1
  172. package/dist/workspace-ui.js +1 -1
  173. package/package.json +1 -1
  174. package/scripts/recovery-canary.mjs +3 -3
  175. package/dist/contest.d.ts +0 -318
  176. package/dist/contest.js +0 -753
  177. package/dist/held.d.ts +0 -150
  178. package/dist/held.js +0 -799
  179. package/dist/liveness.d.ts +0 -30
  180. package/dist/liveness.js +0 -42
  181. package/dist/pricing.d.ts +0 -45
  182. package/dist/pricing.js +0 -77
  183. package/dist/routine.d.ts +0 -228
  184. package/dist/routine.js +0 -764
  185. package/dist/slack-state.d.ts +0 -13
  186. package/dist/slack-state.js +0 -10
  187. package/dist/supervisor.mjs +0 -297
package/dist/store.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { type ChatBinding } from "./chat-core.js";
2
+ import { ChatMessages, TELEGRAM_HOLD_REASONS, TELEGRAM_SKIPPED_ELSEWHERE, TELEGRAM_SKIPPED_OTHER_CHAT, TELEGRAM_SKIPPED_QUIET } from "./chat-messages.js";
3
+ import { isLifecycleNotification, isTelegramProgressNotification, LIFECYCLE_KEY_PREFIX, LIFECYCLE_KINDS, proposalTaskOf, type LifecycleKind } from "./notification-rows.js";
1
4
  import { ServerTelemetry } from "./server-telemetry.js";
2
5
  import type { DecisionOption } from "./contracts/decision.js";
3
6
  import { type SavedToolAction, type SavedToolRule } from "./contracts/store-json.js";
@@ -6,9 +9,9 @@ import { type Actor } from "./actor.js";
6
9
  import { type LiveActivityKind } from "./live.js";
7
10
  import { type TokenPurpose } from "./api-tokens.js";
8
11
  import { type CriterionMatrixRow, type CriterionJudgementWord } from "./proof.js";
9
- import { type ExecutionProfile, type ChainEntry, type UnattendedPermissionMode, type AcceptanceCriterion } from "./scope.js";
10
- import { type ProviderRoom, type CandidateTier, type TaskSize, type TaskSizing, type PhaseRoute, type PublicationAuthority, type RouteStamp, type ReadinessLookup, type ReadinessObservation, type RiskLevel, type RouteOverride } from "./phase-routing.js";
11
- import { type TerminalClass } from "./exhaustion.js";
12
+ import { type ExecutionProfile, type UnattendedPermissionMode, type AcceptanceCriterion } from "./scope.js";
13
+ import { type ProviderRoom, type CandidateTier, type TaskSize, type TaskSizing, type PhaseRoute, type PublicationAuthority, type RouteStamp, type ReadinessLookup, type ReadinessObservation, type RouteOverride } from "./phase-routing.js";
14
+ import type { TerminalClass } from "./exhaustion.js";
12
15
  import { type ProviderId } from "./provider.js";
13
16
  import type { BoardFacts } from "./board.js";
14
17
  import type { BackendGrant, TaskOrigin } from "./grant.js";
@@ -67,7 +70,7 @@ export declare const MATE_ASK_SCHEMA = "\nCREATE TABLE IF NOT EXISTS mate_ask (\
67
70
  * person (shown on the card, and read again by every chat app that delivers it); telegram_flow_choice is one opaque button
68
71
  * per option for one visit of one card, placed on the message it rides. A reply to that message is the note
69
72
  * (telegram_flow_prompt, mode send-back). The chat apps keep their buttons beside their messages (chat-delivery-state.ts). */
70
- export declare const FLOW_SEND_SCHEMA = "\nCREATE TABLE IF NOT EXISTS flow_send (\n card INTEGER NOT NULL REFERENCES flow_card(id),\n entry INTEGER NOT NULL,\n stage TEXT NOT NULL,\n person TEXT NOT NULL,\n content_json TEXT NOT NULL,\n created_at TEXT NOT NULL,\n PRIMARY KEY (card, entry)\n);\nCREATE TABLE IF NOT EXISTS telegram_flow_choice (\n token TEXT PRIMARY KEY,\n binding INTEGER NOT NULL REFERENCES telegram_binding(id) ON DELETE RESTRICT,\n card INTEGER NOT NULL REFERENCES flow_card(id),\n entry INTEGER NOT NULL,\n choice INTEGER NOT NULL,\n label TEXT NOT NULL,\n chat_id TEXT NOT NULL,\n message_id TEXT,\n created_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n consumed_at TEXT\n);\nCREATE INDEX IF NOT EXISTS telegram_flow_choice_visit ON telegram_flow_choice (card, entry);\n";
73
+ export declare const FLOW_SEND_SCHEMA = "\nCREATE TABLE IF NOT EXISTS flow_send (\n card INTEGER NOT NULL REFERENCES flow_card(id),\n entry INTEGER NOT NULL,\n stage TEXT NOT NULL,\n person TEXT NOT NULL,\n content_json TEXT NOT NULL,\n created_at TEXT NOT NULL,\n PRIMARY KEY (card, entry)\n);\n";
71
74
  /** An owner's lasting choice to approve plans and merges from their paired chat (chat-approval.ts), for all their
72
75
  * projects (scope '*') or one (its path), with the limits they agreed to. Off unless a row says on; a project's own row
73
76
  * outranks the all-projects one. `generation` is the account's at the change: a reset password ends it. */
@@ -76,9 +79,6 @@ export declare const FLOW_SEND_SCHEMA = "\nCREATE TABLE IF NOT EXISTS flow_send
76
79
  * a finished run's row goes with the live log's own retention (sweepRunActivity). */
77
80
  export declare const RUN_ACTIVITY_SCHEMA = "\nCREATE TABLE IF NOT EXISTS run_activity (\n run INTEGER PRIMARY KEY REFERENCES run(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('session','message','edit','command','read','search','lookup','plan','delegate','tool')),\n at TEXT NOT NULL\n);\n";
78
81
  export declare const CHAT_APPROVAL_SCHEMA = "\nCREATE TABLE IF NOT EXISTS chat_approval_setting (\n approver TEXT NOT NULL,\n scope TEXT NOT NULL,\n enabled INTEGER NOT NULL CHECK (enabled IN (0,1)),\n full_access INTEGER NOT NULL DEFAULT 0 CHECK (full_access IN (0,1)),\n attempt_cap_microusd INTEGER CHECK (attempt_cap_microusd IS NULL OR attempt_cap_microusd >= 0),\n generation INTEGER NOT NULL,\n digest TEXT NOT NULL,\n updated_by TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (approver, scope)\n);\n";
79
- /** The second tap on a flow decision in Telegram (telegram-flow.ts): Approve arms Yes and Cancel, bound to the binding,
80
- * chat, message and exact visit of the card; Yes decides it once. */
81
- export declare const TELEGRAM_FLOW_CONFIRM_SCHEMA = "\nCREATE TABLE IF NOT EXISTS telegram_flow_confirm (\n token TEXT PRIMARY KEY,\n binding INTEGER NOT NULL,\n chat_id TEXT NOT NULL,\n message_id TEXT NOT NULL,\n card INTEGER NOT NULL,\n entry INTEGER NOT NULL,\n phase TEXT NOT NULL CHECK (phase IN ('yes','cancel')),\n created_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n consumed_at TEXT\n);\nCREATE INDEX IF NOT EXISTS telegram_flow_confirm_visit ON telegram_flow_confirm (card, entry);\n";
82
82
  export declare const CHAT_DECIDE_SCHEMA = "\nCREATE TABLE IF NOT EXISTS chat_decide_action (\n token TEXT PRIMARY KEY,\n channel TEXT NOT NULL,\n binding INTEGER NOT NULL,\n chat TEXT NOT NULL,\n message TEXT,\n act TEXT NOT NULL CHECK (act IN ('accept','changes','retry','approve','not-now','merge')),\n phase TEXT NOT NULL CHECK (phase IN ('offer','yes','cancel')),\n task_id TEXT NOT NULL,\n run INTEGER,\n digest TEXT NOT NULL,\n created_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n consumed_at TEXT\n);\nCREATE INDEX IF NOT EXISTS chat_decide_action_message ON chat_decide_action (channel, chat, message);\nCREATE TABLE IF NOT EXISTS chat_decide_prompt (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n channel TEXT NOT NULL,\n binding INTEGER NOT NULL,\n chat TEXT NOT NULL,\n task_id TEXT NOT NULL,\n run INTEGER NOT NULL,\n digest TEXT NOT NULL,\n message TEXT,\n created_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n consumed_at TEXT\n);\nCREATE INDEX IF NOT EXISTS chat_decide_prompt_open ON chat_decide_prompt (channel, binding, consumed_at);\n";
83
83
  export type MateAsk = {
84
84
  turn: number;
@@ -152,7 +152,9 @@ export type SealedLedgerEntry = LedgerEntry & {
152
152
  hash: string;
153
153
  } | null;
154
154
  };
155
- export declare const SCHEMA_VERSION = 114;
155
+ export declare const SCHEMA_VERSION = 116;
156
+ /** v115: the tables migrateToV115 drops. */
157
+ export declare const V115_DROPPED_TABLES: readonly string[];
156
158
  /**
157
159
  * The migrations `toolroll update` may carry a database through in place: each
158
160
  * one only adds (a table, a column, an accepted value) and leaves every saved row
@@ -171,6 +173,17 @@ export declare const SCHEMA_VERSION = 114;
171
173
  * (rows removed equal the witnesses summarized), and notification drops its
172
174
  * delivery columns only after every value moves into one legacy receipt per row
173
175
  * (rows and ids carried whole; legacy receipts added equal the rows carried).
176
+ * v115 removes contests, held sessions, fallback chains and routines, and is
177
+ * checked under rules named for exactly that: the eleven removed tables may go
178
+ * whole, every kept flow and trigger row stays as it was, and the only rows
179
+ * added are one flow and one schedule trigger per saved routine (paused unless
180
+ * the routine was approved and running). Its other changes add a column or
181
+ * settle rows in place; a database whose removed features still held a hold
182
+ * to lift or place changes that table's rows and is refused, so it takes the
183
+ * separate procedure. v116 is the next declared exception: every row of the 70 old
184
+ * per-app chat tables moves into the shared chat tables keyed by provider, in one
185
+ * transaction that checks each count before the old tables are dropped; the
186
+ * rehearsal checks each moved table's rows arrived (HISTORY_RULES).
174
187
  */
175
188
  export declare const UPDATE_SAFE_MIGRATIONS: readonly number[];
176
189
  /** Whether a database settled at `version` reaches this build's schema through update-safe migrations alone. */
@@ -296,9 +309,7 @@ export type TaskRef = {
296
309
  /** What comes back (v34): a branch to publish, or a report to read.
297
310
  * Set at filing and never rewritten — a scout's strikes are the task's. */
298
311
  deliverable: "branch" | "report";
299
- /** The standing order this task is an instance of; null for one-off work. */
300
- routineId: number | null;
301
- /** The pinned agent, when a fire transaction stamped one. Authoritative. */
312
+ /** The pinned agent, when an approved standing order stamped one. Authoritative. */
302
313
  agentProvider: string | null;
303
314
  agentModel: string | null;
304
315
  /** Durable per-task override. null means the installation default is used
@@ -308,9 +319,6 @@ export type TaskRef = {
308
319
  /** Durable per-task evidence-policy override. null inherits the
309
320
  * installation default when a scope is next written. */
310
321
  qualityMode?: QualityMode | null;
311
- /** v47: the task's declared risk; null reads as routine when the next
312
- * scope is filed. The scope stores the signed level. */
313
- riskLevel?: RiskLevel | null;
314
322
  /** v47: the approver's per-phase route overrides, applied when the next
315
323
  * scope is filed and recorded in the sealed route. null = the stored
316
324
  * list is malformed; the next filing goes unresolved rather than routing
@@ -334,88 +342,11 @@ export type TaskRef = {
334
342
  origin: TaskOrigin;
335
343
  };
336
344
  /** A standing order: a pre-approved template whose instances build unattended. */
337
- export type TournamentTerms = {
338
- id: number;
339
- taskRef: number;
340
- generation: number;
341
- active: boolean;
342
- /** v27: 'race' = dollar-capped tournament; 'comparison' = labeled
343
- * cross-runtime comparison with no dollar terms. */
344
- kind: "race" | "comparison";
345
- raceDigest: string;
346
- /** Ordered agents: exact model ids, resolved at filing. */
347
- agents: {
348
- provider: string;
349
- model: string;
350
- repairModel: string;
351
- permissionMode?: UnattendedPermissionMode;
352
- }[];
353
- n: number;
354
- perAgentBudgetMicrousd: number;
355
- overrunReserveMicrousd: number;
356
- totalBudgetMicrousd: number;
357
- priceVersion: number;
358
- retries: number;
359
- publicationPolicy: string;
360
- createdAt: string;
361
- approvedAt: string | null;
362
- approvedBy: string | null;
363
- approvedDigest: string | null;
364
- };
365
- export type ContestState = "dispatching" | "racing" | "pick-wait" | "decision-wait" | "picked" | "abandoned" | "interrupted" | "exhausted";
366
- export type Contest = {
367
- id: number;
368
- taskRef: number;
369
- terms: number;
370
- generation: number;
371
- state: ContestState;
372
- scopeDigest: string;
373
- raceDigest: string;
374
- baseSha: string | null;
375
- setupDigest: string | null;
376
- currentLeaseId: string | null;
377
- runner: string | null;
378
- incarnation: string | null;
379
- createdAt: string;
380
- pickedAt: string | null;
381
- pickedBy: string | null;
382
- winnerContestant: number | null;
383
- /** One escalation page per tournament, ever — set with the page. */
384
- overduePaged: boolean;
385
- /** v27: denormalized from the terms at admission. */
386
- kind: "race" | "comparison";
387
- };
388
- export type ContestantState = "pending" | "ready" | "building" | "parked" | "built" | "failed" | "stopped";
389
- export type Contestant = {
390
- /** v24: the contestant's own sealed execution profile. */
391
- profile?: ExecutionProfile | null;
392
- id: number;
393
- contest: number;
394
- ordinal: number;
395
- provider: string;
396
- model: string;
397
- repairModel: string;
398
- branch: string;
399
- worktree: string | null;
400
- generation: number;
401
- state: ContestantState;
402
- activeRun: number | null;
403
- budgetMicrousd: number;
404
- reserveMicrousd: number;
405
- /** What the provider reported — monotonic, never guessed. */
406
- measuredMicrousd: number;
407
- /** What the ledger charges — the full reservation when unknowable. */
408
- accountedMicrousd: number;
409
- unknownSpend: boolean;
410
- cleanup: "pending" | "done" | "attention" | null;
411
- custody: string | null;
412
- };
413
345
  export type ExecutionSlot = {
414
346
  id: number;
415
347
  runner: string;
416
348
  state: "reserved" | "running" | "released";
417
349
  run: number | null;
418
- contestant: number | null;
419
350
  incarnation: string | null;
420
351
  processGroup: number | null;
421
352
  reservedAt: string;
@@ -483,14 +414,6 @@ export type ChatSnapshot = {
483
414
  ageHours: number;
484
415
  }[];
485
416
  incidentsSaturated: boolean;
486
- routines: {
487
- repoIndex: number;
488
- name: string;
489
- schedule: string;
490
- status: string;
491
- lastFire: string | null;
492
- }[];
493
- routinesSaturated: boolean;
494
417
  publications: {
495
418
  repoIndex: number;
496
419
  pr: number | null;
@@ -858,14 +781,6 @@ export type FlowTriggerRow = {
858
781
  updatedAt: string;
859
782
  };
860
783
  export type FlowEventOutcome = "created" | "ok" | "fail" | "moved" | "approved" | "sent-back" | "cancelled";
861
- /** The one task a card is about: a task its confirmation created (a new
862
- * task, a revision), else the task it names (and, for feedback on a result,
863
- * that result). Null for a card about no single task. A pointer for
864
- * replies, never an authority. */
865
- export declare function proposalTaskOf(proposal: MateProposal | null): {
866
- task: string;
867
- run: number | null;
868
- } | null;
869
784
  export type MateTurn = {
870
785
  id: number;
871
786
  approver: string;
@@ -884,76 +799,10 @@ export type MateTurn = {
884
799
  tokensOut: number | null;
885
800
  failureReason: string | null;
886
801
  };
887
- export type Routine = {
888
- id: number;
889
- name: string;
890
- /** v102: who made it (its instances are filed as theirs); null before v102 or when no person is known. */
891
- createdBy: string | null;
892
- repo: string;
893
- goal: string;
894
- outOfScope: string | null;
895
- touches: string[];
896
- /** v39: the signed rubric every instance's scope copies forward. */
897
- acceptance: AcceptanceCriterion[];
898
- requirements: string[];
899
- /** 'every:<minutes>', 'daily:<HH:MM>[@Zone]', or 'weekly:<0-6>:<HH:MM>[@Zone]' (UTC by default). */
900
- schedule: string;
901
- singleFlight: boolean;
902
- /** Rolling 7-day dollar ceiling; null = none. Enforcement fails closed. */
903
- costCeilingUsd: number | null;
904
- /** Per-instance dollar cap (v16); copied into each instance's scope. */
905
- budgetPerRunMicrousd: number | null;
906
- paused: boolean;
907
- /** Of every term above. Approval binds to this exact value. */
908
- digest: string;
909
- approvedAt: string | null;
910
- approvedBy: string | null;
911
- approvedDigest: string | null;
912
- /** The next scheduled occurrence; null until approved. */
913
- nextFireAt: string | null;
914
- /** Immutable filing provenance (v12); null on rows from before it existed. */
915
- filedVia: string | null;
916
- createdAt: string;
917
- updatedAt: string;
918
- /** v24: the working execution profile and the approval's sealed snapshot. */
919
- profile?: ExecutionProfile | null;
920
- approvedProfile?: ExecutionProfile | null;
921
- /** v48: the four-role agent route the digest binds, and the snapshot the
922
- * approval sealed. Null on a routine filed before routing froze — such a
923
- * routine cannot be approved or fired until it is filed again. A row
924
- * carrying unreadable route bytes reads null too, and fails closed. */
925
- route?: PhaseRoute | null;
926
- approvedRoute?: PhaseRoute | null;
927
- /** v48: true when the row CARRIES route or profile bytes that do not
928
- * read back — a corrupt snapshot, as distinct from one never taken. Every
929
- * surface says which, and both fail closed. */
930
- routeUnreadable?: boolean;
931
- approvedRouteUnreadable?: boolean;
932
- approvedProfileUnreadable?: boolean;
933
- /** THE RAW TERMS VERDICT (raw authority repair): null when every stored
934
- * term the digest binds read back EXACTLY — touches and requirements as
935
- * JSON lists of strings, the rubric as whole criteria with no unknown
936
- * key, the flags as 0/1, the ceilings as numbers or null — and the words
937
- * when one did not. The integrity projection reads it FIRST: a row whose
938
- * terms cannot be read exactly is not approved, not live, not approvable,
939
- * and not refreshable, so the lenient fields above can never become a
940
- * firing's authority. Undefined on a hand-built routine. */
941
- termsProblem?: string | null;
942
- };
943
- /** One scheduled slot's outcome, fired or skipped — never silent. */
944
- export type RoutineFire = {
945
- id: number;
946
- routineId: number;
947
- scheduledFor: string;
948
- outcome: "fired" | "skipped";
949
- reason: string | null;
950
- instanceTaskRef: number | null;
951
- createdAt: string;
952
- };
953
802
  /** Who placed a hold — and therefore who alone may lift it. */
954
803
  /** 'stop' (v52) = the pause one exact attempt's operator stop placed — lifted
955
804
  * only by resuming THAT attempt, never by `unhold` or by answering a decision. */
956
- export type HoldOwner = "operator" | "decision" | "incident" | "backoff" | "contest" | "revision" | "stop";
805
+ export type HoldOwner = "operator" | "decision" | "incident" | "backoff" | "revision" | "stop";
957
806
  export type Hold = {
958
807
  id: number;
959
808
  taskRef: number;
@@ -1008,23 +857,6 @@ type NotificationInput = {
1008
857
  /** v83: one person's notification — only their own phone, chats and browsers get it; no channel-wide webhook does. */
1009
858
  recipient?: string;
1010
859
  };
1011
- /**
1012
- * Task lifecycle updates (Telegram task updates, 2026-09-16): the CLOSED
1013
- * vocabulary of routine progress facts the shared mutations record beside
1014
- * the change that made them true. None carries a push class — they are
1015
- * digest-eligible progress, never a page — and every one is project-bound
1016
- * through the task it names. A decision, incident, gap, stall, publication
1017
- * or merge page keeps its own producer; nothing here repeats one.
1018
- */
1019
- export declare const LIFECYCLE_KINDS: readonly ["task-filed", "scope-approved", "approval-withdrawn", "task-held", "task-released", "task-queued", "task-requeued", "task-cancelled", "run-started", "run-phase", "check-progress", "run-finished", "run-stopping", "run-stopped", "run-resumed", "review-requested", "review-finished", "acceptance-evidence", "acceptance-ready"];
1020
- export type LifecycleKind = (typeof LIFECYCLE_KINDS)[number];
1021
- /** Every lifecycle dedupe key starts here: `life:<kind>:<identity>:<ordinal>`. */
1022
- export declare const LIFECYCLE_KEY_PREFIX = "life:";
1023
- /** A progress fact, told apart by its durable key — never by display text. */
1024
- export declare function isLifecycleNotification(row: Pick<Notification, "dedupeKey">): boolean;
1025
- /** Only known progress producers can repaint a card. Decisions and urgent
1026
- * incidents keep their own alerts; a routine retry updates its saved attempt. */
1027
- export declare function isTelegramProgressNotification(row: Pick<Notification, "dedupeKey" | "kind" | "pushClass" | "run">): boolean;
1028
860
  /** A fact that wants a person, durably. */
1029
861
  export type Notification = {
1030
862
  id: number;
@@ -1116,8 +948,9 @@ export type RunnerWorkRecovery = {
1116
948
  requeued: string[];
1117
949
  };
1118
950
  /** How a stop's settlement was established (v52). `interrupted` = the
1119
- * owning worker sealed the attempt after its processes ended; `held` = the
1120
- * held-session supervisor fenced it; `recovered` = dead-incarnation
951
+ * owning worker sealed the attempt after its processes ended; `held`
952
+ * (v52-v114, history only) = the removed held-session supervisor fenced it;
953
+ * `recovered` = dead-incarnation
1121
954
  * recovery settled a run whose worker is proven gone; `finished` = the
1122
955
  * attempt reached another ending first (the stop was recorded, but the
1123
956
  * run's own outcome stands — the words say which). */
@@ -1218,11 +1051,9 @@ export type Run = {
1218
1051
  branch: string | null;
1219
1052
  worktree: string | null;
1220
1053
  model: string | null;
1221
- /** 'interrupted' (v25) = a held attended session cut down mid-flight. */
1054
+ /** 'interrupted' (v25–v114) = a held session cut down mid-flight; kept so old rows read. */
1222
1055
  outcome: "built" | "failed" | "refused" | "parked" | "no-change" | "interrupted" | null;
1223
1056
  reason: string | null;
1224
- /** The attended authorization this run consumed (v25); null = ordinary dispatch. */
1225
- attendedAuthorization?: string | null;
1226
1057
  committed: boolean | null;
1227
1058
  startedAt: string;
1228
1059
  finishedAt: string | null;
@@ -1238,24 +1069,12 @@ export type Run = {
1238
1069
  headRevision: string | null;
1239
1070
  /** The validated terminal handoff's conclusion. */
1240
1071
  handoff: string | null;
1241
- /** When racing: which tournament agent this run belongs to. */
1242
- contestant: number | null;
1243
1072
  /**
1244
1073
  * Where the machine is in ITS OWN state machine — stamped by the control
1245
1074
  * plane at boundaries it owns, never parsed from a provider stream (M5.4).
1246
1075
  * Meaningful while the run is open; the last value simply remains after.
1247
1076
  */
1248
1077
  phase: RunPhase | null;
1249
- /**
1250
- * The fallback-chain metadata (v30), NULL on every run outside a chain.
1251
- * `chainCycle`/`chainIndex`/`entryDigest` are stamped at admission (or at
1252
- * base-cycle open) and bind the run to exactly one entry of an immutable
1253
- * approved chain — the runtime re-derives authority from the snapshot,
1254
- * never from these, but reads them to know which entry ran.
1255
- */
1256
- chainCycle?: number | null;
1257
- chainIndex?: number | null;
1258
- entryDigest?: string | null;
1259
1078
  /**
1260
1079
  * How this attempt authenticated (v30) — 'subscription' or 'api-key' —
1261
1080
  * stamped by the gateway. Decides which exhaustion class a match yields.
@@ -1263,10 +1082,8 @@ export type Run = {
1263
1082
  authMode?: "subscription" | "api-key" | null;
1264
1083
  /**
1265
1084
  * The gateway's honest classification of how this attempt ENDED (v30),
1266
- * computed at disposal from the structural terminal + the authoritative
1267
- * version + auth mode (exhaustion.ts). Fail-closed: 'unknown' until a
1268
- * fixture-backed recognizer exists. NEVER an authority by itself — the
1269
- * dispatch's C8 gate re-checks hasRecognizer before any advance.
1085
+ * computed where the structural terminal still exists (exhaustion.ts).
1086
+ * `auth-expired` pauses its provider; every other class is a record.
1270
1087
  */
1271
1088
  terminalClass?: TerminalClass | null;
1272
1089
  /** v44 (adaptive execution plans): the exact plan revision this attempt's
@@ -1280,88 +1097,6 @@ export type Run = {
1280
1097
  /** The bounded activity vocabulary. Machine-authored — a model's prose never becomes one of these. */
1281
1098
  export declare const RUN_PHASES: readonly ["agent-running", "validating-handoff", "capturing-evidence", "committing", "verifying-proof", "correcting-proof"];
1282
1099
  export type RunPhase = (typeof RUN_PHASES)[number];
1283
- /**
1284
- * One person's signed authority for ONE watched attempt (ruling 12). The id
1285
- * is a pre-minted UUID — it IS the attempt identity the dispatch proof
1286
- * consumes. Consumed (attemptRun set) is NOT closed: the authorization
1287
- * stays active across its held session; closure is explicit and terminal.
1288
- */
1289
- export type AttendedAuthorization = {
1290
- id: string;
1291
- taskRef: number;
1292
- approver: string;
1293
- runner: string;
1294
- runnerGeneration: number;
1295
- compositeDigest: string;
1296
- termsJson: string;
1297
- maxSessionTurns: number;
1298
- /** A STOP THRESHOLD, not a ceiling: the agent halts when its total crosses it. */
1299
- budgetMicrousd: number;
1300
- /** Continuation: the finished parent attempt, also inside the signed terms. */
1301
- parentRun: number | null;
1302
- followup: string | null;
1303
- createdAt: string;
1304
- absoluteExpiry: string;
1305
- lastBeatAt: string | null;
1306
- attemptRun: number | null;
1307
- consumedAt: string | null;
1308
- closedAt: string | null;
1309
- endReason: string | null;
1310
- };
1311
- /**
1312
- * One stdin injection into a held session (ruling 15). Author is a verified
1313
- * operator name for 'operator' turns ONLY — brief and repair turns are
1314
- * machine-authored and say so with null. 'uncertain' is TERMINAL: written
1315
- * (or accepted) but never proven settled; charged at its reservation and
1316
- * NEVER reinjected.
1317
- */
1318
- export type SessionTurn = {
1319
- id: number;
1320
- run: number;
1321
- seq: number;
1322
- sourceKind: "brief" | "answer" | "operator" | "repair";
1323
- /** The decision id for 'answer' turns, the triggering decision for 'repair'. */
1324
- sourceId: number | null;
1325
- author: string | null;
1326
- text: string;
1327
- reservedMicrousd: number;
1328
- accountedMicrousd: number | null;
1329
- accountedAt: string | null;
1330
- recordedAt: string;
1331
- writtenAt: string | null;
1332
- acceptedAt: string | null;
1333
- settledAt: string | null;
1334
- /** Marginal delta from the held session's durable cumulative baseline. */
1335
- measuredMicrousd: number | null;
1336
- outputTokens: number | null;
1337
- state: "recorded" | "written" | "accepted" | "settled" | "uncertain" | "cancelled";
1338
- };
1339
- /**
1340
- * Durable crash custody for one held session (ruling 15). The orphan
1341
- * predicate is lease-based; 'fencing' is a helpable, leased state with
1342
- * deadline takeover. cumulativeMicrousd is the settlement baseline the
1343
- * provider's cumulative totals are diffed against.
1344
- */
1345
- export type HeldSession = {
1346
- run: number;
1347
- authorizationId: string;
1348
- runner: string;
1349
- leaseId: string;
1350
- upIncarnation: string;
1351
- cookie: string;
1352
- socketPath: string;
1353
- supervisorPid: number | null;
1354
- agentPgid: number | null;
1355
- cumulativeMicrousd: number;
1356
- cumulativeTokensOut: number;
1357
- state: "open" | "fencing";
1358
- fencer: string | null;
1359
- fencingDeadline: string | null;
1360
- startedAt: string;
1361
- endedAt: string | null;
1362
- endReason: string | null;
1363
- };
1364
- export type RecordTurnRefusal = "no-held-session" | "fenced" | "turn-cap" | "turn-open" | "budget-exhausted" | "decision-open" | "repair-exhausted" | "answer-delivered";
1365
1100
  /**
1366
1101
  * One operator steering note (arc 1, v22). Attached ≠ delivered: attachment
1367
1102
  * says which build the note rode toward; delivery settles only on the
@@ -1770,12 +1505,6 @@ export declare const DEFAULT_ACTOR = "operator";
1770
1505
  export declare class RunAdmissionRefused extends Error {
1771
1506
  constructor(message: string);
1772
1507
  }
1773
- /** A present fallback-chain row carries this many entries after the base
1774
- * (atomic authority closure) — the same bound `config set fallback`
1775
- * enforces at the CLI, held again at the store's read and write so a row
1776
- * outside it is a stated problem, never an empty chain. */
1777
- export declare const FALLBACK_ENTRIES_MIN = 1;
1778
- export declare const FALLBACK_ENTRIES_MAX = 3;
1779
1508
  /**
1780
1509
  * The subset of `node:sqlite` this module uses, named so the rest of the file
1781
1510
  * is not written against an `any` and so a test can substitute a handle.
@@ -2050,7 +1779,7 @@ export declare class Store {
2050
1779
  * rank any still-dispatchable task holds, computed and written in ONE
2051
1780
  * transaction (two racing "next" calls get distinct ranks; the later
2052
1781
  * ask wins). Scheduling only: it refuses anything not plainly queued —
2053
- * building, finished, failed, cancelled, or racing a tournament — and
1782
+ * building, finished, failed, or cancelled — and
2054
1783
  * never touches updated_at, which the board reads as the stall clock.
2055
1784
  */
2056
1785
  moveTaskNext(taskId: string, now: Date, mutation?: Mutation): {
@@ -2083,7 +1812,7 @@ export declare class Store {
2083
1812
  * One atomic queue move (queue-columns review, findings 3/9/13): the
2084
1813
  * revision CAS, every refusal, the assignment write, and the rerank of
2085
1814
  * BOTH affected columns are one transaction. The rerank member set is
2086
- * the FREE members only — anything live-claimed or racing a tournament
1815
+ * the FREE members only — anything live-claimed
2087
1816
  * keeps its rank untouched, so a drag can never rewrite work being
2088
1817
  * taken (a setup-failure release rejoins with the rank the operator
2089
1818
  * last gave it — intent, not a bug). Scheduling, never authority.
@@ -2228,8 +1957,7 @@ export declare class Store {
2228
1957
  * Establish a mirror: the ONE act that makes a local task stand for a
2229
1958
  * tracker item. Identity and provenance are immutable after this row
2230
1959
  * (trigger-enforced); labels and titles may nominate work, only this
2231
- * establishes whose it is. Refuses tasks carrying race terms or an open
2232
- * tournament (D1 — external work does not race in this release).
1960
+ * establishes whose it is.
2233
1961
  */
2234
1962
  establishMirror(mirror: {
2235
1963
  localTaskId: string;
@@ -2244,7 +1972,7 @@ export declare class Store {
2244
1972
  ok: true;
2245
1973
  } | {
2246
1974
  ok: false;
2247
- reason: "unknown-task" | "duplicate" | "racing";
1975
+ reason: "unknown-task" | "duplicate";
2248
1976
  };
2249
1977
  mirrorByTask(taskId: string): ExternalMirror | null;
2250
1978
  mirrorByRemote(backend: string, remoteRepo: string, remoteId: string): ExternalMirror | null;
@@ -2263,7 +1991,7 @@ export declare class Store {
2263
1991
  /**
2264
1992
  * The reopen act (v3 §7 + findings 18/30): an authenticated CAS that
2265
1993
  * requires the tracker to have been SEEN open again after the close,
2266
- * and the task to be clean — no live claim, no open tournament, no
1994
+ * and the task to be clean — no live claim, no
2267
1995
  * active hold, no open question, no unresolved incident. It reconciles
2268
1996
  * task state from any admitted state back to queued; the approved
2269
1997
  * scope is preserved (its digest never changed) — this act is the
@@ -2273,7 +2001,7 @@ export declare class Store {
2273
2001
  ok: true;
2274
2002
  } | {
2275
2003
  ok: false;
2276
- reason: "unknown-task" | "not-latched" | "not-seen-open" | "claimed" | "contest-open" | "held" | "question-open" | "incident-open" | "bad-state";
2004
+ reason: "unknown-task" | "not-latched" | "not-seen-open" | "claimed" | "held" | "question-open" | "incident-open" | "bad-state";
2277
2005
  };
2278
2006
  /** The last COMPLETE sync pass for a tracker, or null — freshness's anchor. */
2279
2007
  lastCompleteSync(backend: string, remoteRepo: string): {
@@ -2312,7 +2040,7 @@ export declare class Store {
2312
2040
  why: "stale-mirror" | "external-closed" | "dispatch-revoked" | "plane-blocked";
2313
2041
  }[];
2314
2042
  /** Whether a fresh completion may stand as done (v4 §24) — read INSIDE
2315
- * completeFenced's transaction. Non-mirrors always complete. */
2043
+ * finalize's complete-ending transaction. Non-mirrors always complete. */
2316
2044
  mirrorAllowsCompletion(taskId: string): boolean;
2317
2045
  /** Whether a stored acquire mutation exists — the replay marker's fact. */
2318
2046
  hasMutationRecord(mutation: Mutation): boolean;
@@ -2333,14 +2061,13 @@ export declare class Store {
2333
2061
  revokeGrant(repo: string, backend: string, mutation?: Mutation): boolean;
2334
2062
  saveScope(scope: Scope, mutation?: Mutation, options?: {
2335
2063
  profile?: ExecutionProfile;
2336
- /** v48: a FROZEN route — a routine firing's approved snapshot —
2064
+ /** v48: a FROZEN route — an approved standing order's snapshot —
2337
2065
  * filed verbatim instead of being recommended afresh from today's
2338
2066
  * configuration. Requires an explicit profile, and the two must
2339
2067
  * agree exactly (the same belt every other road wears). */
2340
2068
  route?: PhaseRoute;
2341
2069
  permissionMode?: UnattendedPermissionMode;
2342
2070
  qualityMode?: QualityMode;
2343
- riskLevel?: RiskLevel;
2344
2071
  posture?: "escalated";
2345
2072
  proposedVia?: "mate" | "coordinator" | "scout" | null;
2346
2073
  }): void;
@@ -2816,8 +2543,8 @@ export declare class Store {
2816
2543
  /**
2817
2544
  * The revocation that actually severs (D7), one transaction: the stamp
2818
2545
  * plus a generation bump (live console sessions die at their next
2819
- * lookup; bearer credentials die at authenticateAccount), their open
2820
- * attended authorizations close, their unconsumed invites die, every
2546
+ * lookup; bearer credentials die at authenticateAccount), their
2547
+ * unconsumed invites die, every
2821
2548
  * mode THEY signed is revoked with the typed 'signer-revoked' event —
2822
2549
  * demoting its derived merge authority through the one reconciliation
2823
2550
  * road — and the derived-authority sweep clears Telegram and push.
@@ -2830,7 +2557,7 @@ export declare class Store {
2830
2557
  * invites, modes and everything mode-derived (their sealed filings
2831
2558
  * demote through the reconciliation road), Telegram, push. Standing
2832
2559
  * acts they completed WITH full ceremony — publication/backend/intake
2833
- * grants, worktree setups, approved routines, approved scopes sealed by
2560
+ * grants, worktree setups, approved standing orders, approved scopes sealed by
2834
2561
  * password — deliberately survive: those are the instance's promises,
2835
2562
  * approved as themselves, and undoing history is not what revocation
2836
2563
  * means. An operator who distrusts those acts revokes them by their own
@@ -2839,18 +2566,11 @@ export declare class Store {
2839
2566
  revokeAccount(name: string, by: string, now: Date): {
2840
2567
  ok: true;
2841
2568
  modesRevoked: number;
2842
- authorizationsClosed: number;
2843
2569
  invitesRevoked: number;
2844
2570
  } | {
2845
2571
  ok: false;
2846
2572
  reason: "unknown" | "already-revoked" | "last-approver";
2847
2573
  };
2848
- /** One person's open attended sessions, for their People card. */
2849
- openAttendedOf(name: string): {
2850
- taskId: string;
2851
- createdAt: string;
2852
- lastBeatAt: string | null;
2853
- }[];
2854
2574
  /**
2855
2575
  * One person's recent consequential acts (U3), from the rows that were
2856
2576
  * ALREADY author-stamped — no new event kinds, just the ledger asked a
@@ -3166,321 +2886,6 @@ export declare class Store {
3166
2886
  * finds nothing to consume instead of minting a duplicate task.
3167
2887
  */
3168
2888
  consumeDiffComments(runId: number, ids: readonly number[], taskId: string): number;
3169
- /** The open cycle for a task, if one exists (the runtime's read). */
3170
- fallbackCycleFor(taskRef: number): FallbackCycle | null;
3171
- /** Open a fresh cycle at index 0 for a running base attempt. One live
3172
- * cycle per task — the SELECT-then-INSERT under BEGIN IMMEDIATE
3173
- * serializes writers, and the one_live_fallback_cycle_per_task partial
3174
- * unique index is the durable backstop (finding 5). A second refuses. */
3175
- openFallbackCycle(taskRef: number, chainDigest: string, tailRun: number | null, now: Date): {
3176
- ok: true;
3177
- id: number;
3178
- } | {
3179
- ok: false;
3180
- };
3181
- /**
3182
- * The task's IMMUTABLE approved chain — the runtime's single source of
3183
- * truth for chain length and per-entry authority (never mutable config).
3184
- * Returns the rehydrated entries when the approval sealed a chain and the
3185
- * snapshot still rehydrates strictly; null otherwise (a single-profile
3186
- * approval, or a snapshot that fails the strict rehydrator — fail closed,
3187
- * so a corrupt chain dispatches nothing).
3188
- */
3189
- approvedChainOf(taskId: string): ChainEntry[] | null;
3190
- /**
3191
- * The ONE chain-cycle resolver at a run's end (E3c/E3d): every concluded
3192
- * tail resolves its cycle — success closes it, an ordinary end closes it
3193
- * (the retry road runs the BASE entry under a FRESH cycle; a concluded
3194
- * tail can never be re-tagged, so leaving it open would only strand it),
3195
- * a parked tail is a PAUSED lineage and stays open for repair, and a
3196
- * recognized eligible exhaustion advances. Both the disposition hook and
3197
- * the crash reconciler call THIS method, so a crash between disposition
3198
- * and resolution re-derives the same answer from durable state.
3199
- *
3200
- * The advance is FAIL CLOSED at every gate:
3201
- * - an OPEN cycle whose tail is exactly this finished run;
3202
- * - the run genuinely finished (outcome + finished_at +
3203
- * provider_started_at, same task) — never live custody;
3204
- * - a fallback-ELIGIBLE class consistent with the run's auth mode;
3205
- * - the C8 re-check: THIS build recognizes the exact class/auth for the
3206
- * run's (provider, version) — a downgrade severs to incident;
3207
- * - the LIVE signed mode's paid-fallback grant, re-read IN-transaction;
3208
- * - a next entry in the IMMUTABLE approved chain (else exhausted-end).
3209
- * The fenced custody walk — sanitize, advance, release-to-pending — runs
3210
- * atomically inside ONE transaction; a lost inner CAS rolls the whole
3211
- * walk back. It NEVER dispatches: the admission pass creates the run.
3212
- */
3213
- resolveChainOnRunEnd(taskRef: number, taskId: string, repo: string | null, finishedRunId: number, now: Date): {
3214
- kind: "advanced";
3215
- toIndex: number;
3216
- } | {
3217
- kind: "exhausted-end";
3218
- } | {
3219
- kind: "closed";
3220
- reason: "succeeded" | "entry-ended";
3221
- } | {
3222
- kind: "blocked";
3223
- reason: "no-recognizer" | "grant-withheld" | "corrupt-chain" | "cycle-mismatch";
3224
- } | {
3225
- kind: "parked-tail";
3226
- } | {
3227
- kind: "no-cycle";
3228
- };
3229
- /**
3230
- * The crash reconciler's read (E3d, review finding 3): OPEN cycles whose
3231
- * tail run CONCLUDED (non-parked) but whose cycle was never resolved — the
3232
- * window a crash between disposition and resolveChainOnRunEnd leaves. The
3233
- * reconciler feeds each through the SAME resolver, so nothing is decided
3234
- * twice or differently.
3235
- */
3236
- strandedChainCycles(repo: string): {
3237
- cycleId: number;
3238
- taskRef: number;
3239
- taskId: string;
3240
- tailRun: number;
3241
- }[];
3242
- /**
3243
- * The chain reconciler in ONE callable piece (F+G review, finding 5): the
3244
- * EXACT code the tick runs each pass, so the fault tests drive the same
3245
- * road production does — deleting the tick's call would fail them.
3246
- * Resolves every open cycle whose tail concluded (non-parked) through the
3247
- * one resolver; returns how many it fed through.
3248
- */
3249
- reconcileStrandedChains(repo: string, now: Date): number;
3250
- /** Cycles awaiting their next entry's admission, for one repo — what the
3251
- * tick's chain admission pass walks. */
3252
- pendingChainAdmissions(repo: string): {
3253
- cycleId: number;
3254
- taskRef: number;
3255
- taskId: string;
3256
- cursor: number;
3257
- }[];
3258
- /**
3259
- * The PROVING admission (E3d): create the next entry's run from a
3260
- * pending-admission cycle, with EVERY authority re-derived inside one
3261
- * transaction — the approved chain must still stand and match the cycle's
3262
- * digest, the entry at the cursor must exist, the LIVE signed mode must
3263
- * still grant the paid fallback (revocation between advance and admission
3264
- * denies), and the exact unconsumed pending edge is consumed by the run
3265
- * it creates (admitFallback's single-use CAS). The caller carries only
3266
- * claim, worktree, and rail; nothing it asserts becomes authority.
3267
- */
3268
- admitNextChainEntry(cycleId: number, run: {
3269
- leaseId: string;
3270
- runner: string;
3271
- branch: string;
3272
- worktree: string;
3273
- recoveredFrom?: number;
3274
- }, now: Date): {
3275
- ok: true;
3276
- runId: number;
3277
- taskId: string;
3278
- provider: string;
3279
- model: string;
3280
- } | {
3281
- ok: false;
3282
- reason: "not-pending" | "stale-approval" | "grant-withheld" | "no-edge" | "raced" | "provider-unavailable";
3283
- detail?: string;
3284
- };
3285
- /**
3286
- * The PRE-SPAWN custody proof (Codex E3d review, finding 3): the LAST
3287
- * gate before a chain-bound run's provider process starts, coupled to the
3288
- * start stamp in ONE transaction so nothing can lapse between the proof
3289
- * and the money. Re-derives, from durable state only: the approved chain
3290
- * still stands (freshness + digest); the run's cycle is live and OPEN
3291
- * with THIS run as tail at THIS run's index; the entry digest and pinned
3292
- * auth mode still match; and — for any entry past the base — the LIVE
3293
- * signed mode still grants the paid fallback (a base entry is the
3294
- * ordinary approved work and needs no grant). Only when every fact stands
3295
- * is provider_started_at stamped (first-write, with the version when the
3296
- * gateway proved one). Returns false — and stamps NOTHING — otherwise.
3297
- */
3298
- proveChainCustodyForSpawn(runId: number, now: Date, providerVersion?: string): boolean;
3299
- /**
3300
- * open -> sanitizing (C7): a recognized ELIGIBLE exhaustion of the tail
3301
- * run begins the sanitizer. CAS proves exact state, generation, and tail
3302
- * run; a stale caller loses. Marks the cycle sanitizing so ordinary
3303
- * admission is blocked even if the claim later expires.
3304
- */
3305
- beginFallbackSanitize(cycleId: number, expectGeneration: number, tailRun: number, now: Date): boolean;
3306
- /**
3307
- * sanitizing -> awaiting-release (C2/C7): the durable one-step advance.
3308
- * ONE transaction: prove the cycle is sanitizing at this generation and
3309
- * cursor i with this tail run; insert the immutable transition (unique
3310
- * per (cycle, from_index)); advance the cursor to i+1; bump generation.
3311
- * The target index MUST be < chainLength (proven by the caller from the
3312
- * approved snapshot). Returns the new transition id, or null on a lost
3313
- * CAS or an already-recorded step.
3314
- */
3315
- advanceFallbackFenced(args: {
3316
- cycleId: number;
3317
- expectGeneration: number;
3318
- fromIndex: number;
3319
- chainLength: number;
3320
- predecessorRun: number;
3321
- terminalClass: string;
3322
- evidence: {
3323
- provider: string;
3324
- version: string | null;
3325
- authMode: string;
3326
- fp: string;
3327
- };
3328
- }, now: Date): {
3329
- ok: true;
3330
- transitionId: number;
3331
- toIndex: number;
3332
- } | {
3333
- ok: false;
3334
- reason: "raced" | "at-end" | "dup";
3335
- };
3336
- /** awaiting-release -> pending-admission (C7): the epoch-fenced custody
3337
- * release completed; the next entry is now admittable. */
3338
- releaseFallbackToPending(cycleId: number, expectGeneration: number, now: Date): boolean;
3339
- /**
3340
- * pending-admission -> open at the new index (C3): the SINGLE-USE
3341
- * admission. ONE transaction: prove pending at this generation, consume
3342
- * the transition (consumed_by set once — a replay finds it consumed and
3343
- * loses), and open the cycle at the new tail. Returns false on a lost
3344
- * CAS or an already-consumed transition.
3345
- */
3346
- /**
3347
- * THE FALLBACK ADMISSION (E3d; the ONE insert path for `fallback`
3348
- * provenance since the v48 integrity repair). Every run bound to a
3349
- * NON-primary entry of the approved chain — the entry's own admission
3350
- * from a pending edge, a parked tail's successor, a repair turn under
3351
- * the live tail — is created here and nowhere else; the generic
3352
- * admission refuses `fallback` outright.
3353
- *
3354
- * EVERYTHING the caller states is re-proved against durable state
3355
- * before any row exists, and one disagreement creates no run and
3356
- * consumes no edge: the cycle is the task's own and live; the approved
3357
- * chain still stands, is the cycle's, and its base entry is mirrored by
3358
- * the sealed profile exactly as the caller presents it; the cursor,
3359
- * the tail, the entry digest, the auth mode, the provider, the EXACT
3360
- * model (required, never defaulted), and the repair binding all equal
3361
- * the approved entry at the cursor; the presented stamp is `fallback`
3362
- * on exactly that entry for the phase this run spends as; and the
3363
- * kind-specific custody fact holds — an unconsumed pending edge at the
3364
- * cursor, a parked tail the cycle still names, or a live parent tail.
3365
- * The run is opened WITH its chain metadata (cycle, index, entry
3366
- * digest, auth mode) and its route in one body, so nothing downstream
3367
- * can substitute a foreign run.
3368
- */
3369
- admitFallback(args: {
3370
- run: {
3371
- taskRef: number;
3372
- leaseId: string;
3373
- runner: string;
3374
- branch: string;
3375
- worktree: string;
3376
- provider: string;
3377
- model: string;
3378
- sessionId?: string;
3379
- /** The interrupted attempt whose draft this entry or resume
3380
- * recovers (raw authority repair): proved this task's own run and
3381
- * written as the row's parent in this same insert — never stamped
3382
- * later. A repair turn's parent is its live tail; it recovers none. */
3383
- recoveredFrom?: number;
3384
- };
3385
- cycleId: number;
3386
- /** The cursor the caller understands the cycle to stand at — the
3387
- * entry index this run binds to. */
3388
- expectCursor: number;
3389
- /** The cycle's tail as the caller understands it: null for an entry
3390
- * admitted from a pending edge, the parked run for a resume, the
3391
- * live parent for a repair turn. */
3392
- expectTail: number | null;
3393
- entryDigest: string;
3394
- authMode: "subscription" | "api-key";
3395
- /** The entry's effective repair model as the caller understands it —
3396
- * `inherit` resolved to the build model — proved against the approved
3397
- * entry so a repair turn later spends as exactly what was approved. */
3398
- repairModel: string;
3399
- /** The approved authority as the caller holds it: the chain's digest
3400
- * and the FULL sealed-profile mirror (the chain's base entry). */
3401
- approved: {
3402
- chainDigest: string;
3403
- profile: ExecutionProfile;
3404
- };
3405
- /** The run's `fallback` route provenance, proved against the exact
3406
- * entry this admission binds (cursor + entry digest) BEFORE the row
3407
- * exists and written beside it. Required: nothing is dictated here. */
3408
- route: RouteStamp;
3409
- } & ({
3410
- kind: "entry";
3411
- expectGeneration: number;
3412
- transitionId: number;
3413
- } | {
3414
- kind: "resume";
3415
- parkedRun: number;
3416
- } | {
3417
- kind: "repair";
3418
- parentRun: number;
3419
- }), now: Date): {
3420
- ok: true;
3421
- runId: number;
3422
- } | {
3423
- ok: false;
3424
- reason: "refused" | "raced";
3425
- problem: string;
3426
- };
3427
- /**
3428
- * THE UNAVAILABLE-PRIMARY TRANSITION (v47): the approved chain's base
3429
- * entry runs a provider THIS runner has reported unavailable, so the
3430
- * task moves — before any claim, run, or spend — to the EXPLICITLY
3431
- * APPROVED next entry, and only that one: a fresh cycle opens at index 0
3432
- * with no tail and skips, one step, to pending-admission at index 1,
3433
- * citing the readiness observation as its evidence. The admission pass
3434
- * then re-proves everything (approved chain standing, live paid-fallback
3435
- * grant, the next entry's own readiness) before it runs. Every other
3436
- * case fails closed with the words: no approved chain, a live cycle
3437
- * already, a base that is not actually unavailable, no next entry, a
3438
- * next entry that is unavailable too, or no live grant — nothing
3439
- * substitutes outside the approved chain.
3440
- */
3441
- skipUnavailablePrimary(taskRef: number, taskId: string, repo: string | null, runner: string, now: Date): {
3442
- ok: true;
3443
- cycleId: number;
3444
- toIndex: number;
3445
- next: {
3446
- provider: string;
3447
- model: string;
3448
- };
3449
- } | {
3450
- ok: false;
3451
- reason: "no-chain" | "cycle-live" | "primary-available" | "at-end" | "next-unavailable" | "grant-withheld" | "raced";
3452
- detail: string;
3453
- };
3454
- /** open -> open at i+1 via a quota-skip (C7): index 0 (or any) already
3455
- * durably exhausted before dispatch is skipped, one step, recorded. */
3456
- quotaSkipFallback(args: {
3457
- cycleId: number;
3458
- expectGeneration: number;
3459
- fromIndex: number;
3460
- chainLength: number;
3461
- tailRun: number | null;
3462
- evidence?: {
3463
- provider: string;
3464
- fp: string;
3465
- };
3466
- }, now: Date): {
3467
- ok: true;
3468
- toIndex: number;
3469
- transitionId: number;
3470
- } | {
3471
- ok: false;
3472
- reason: "raced" | "at-end" | "dup";
3473
- };
3474
- /** Any nonterminal state -> incident (C8): a sanitizer failure, a
3475
- * severed grant, or a policy downgrade pages a human; never silent. */
3476
- /** Any nonterminal -> incident (C8): CAS on the exact generation so a
3477
- * STALE observer cannot terminate a cycle that has since advanced
3478
- * (Codex E1 review, finding 1). */
3479
- incidentFallback(cycleId: number, expectGeneration: number, reason: string, now: Date): boolean;
3480
- /** A cycle succeeds or exhausts its chain: closed, terminally — CAS on
3481
- * the exact generation (finding 1: a stale success observer cannot close
3482
- * after an advance + admit). */
3483
- closeFallbackCycle(cycleId: number, expectGeneration: number, reason: string, now: Date): boolean;
3484
2889
  /**
3485
2890
  * The bounded review-retry projection (v50): one source run's ROOT
3486
2891
  * reviewer attempts in ordinal order, its open request, and the ONE
@@ -3669,7 +3074,7 @@ export declare class Store {
3669
3074
  * exactly one wins; the loser refuses in words with zero rows.
3670
3075
  *
3671
3076
  * The child is filed UNAPPROVED, always: this method never stamps an
3672
- * approval, never mints an attended authorization, never touches a
3077
+ * approval, never touches a
3673
3078
  * publication or merge grant. Only the normal approval roads — the
3674
3079
  * password ceremony, or a live mode's own filing coverage re-proved by
3675
3080
  * the caller inside its own transaction — can approve the child.
@@ -3995,12 +3400,10 @@ export declare class Store {
3995
3400
  * default when the scope is filed. */
3996
3401
  qualityMode?: QualityMode;
3997
3402
  /** The revision road's inherited declarations (contract handoff task
3998
- * 2): the source's declared risk, the approver's per-phase route
3999
- * overrides, and its build/plan pins — stamped on the ref BEFORE the
3403
+ * 2): the approver's per-phase route overrides, and its build/plan pins — stamped on the ref BEFORE the
4000
3404
  * scope resolves, so the child's route is recommended over them
4001
3405
  * exactly as the source's was, never over the installation's
4002
3406
  * defaults of the day. */
4003
- riskLevel?: RiskLevel;
4004
3407
  /** How big the change is, sized at filing (v2 routing). */
4005
3408
  sizing?: TaskSizing;
4006
3409
  routeOverridesJson?: string | null;
@@ -4134,34 +3537,6 @@ export declare class Store {
4134
3537
  }[];
4135
3538
  /** Write one complete pair. Audited: who changed spend routing, and when. */
4136
3539
  setPhaseConfig(scope: string, phase: string, provider: string, model: string | null, by: string, now: Date): void;
4137
- /** The ordered FALLBACK entries after the base, for a scope's build
4138
- * phase (v30). Each entry: {provider, model, authMode, repairModel?}.
4139
- * Returns [] when none configured — a chain-of-one is the base alone. */
4140
- fallbackConfig(scope: string): {
4141
- provider: string;
4142
- model: string;
4143
- authMode: "subscription" | "api-key";
4144
- repairModel?: string;
4145
- }[];
4146
- /**
4147
- * The configured fallback entries, or the words for why the row on file
4148
- * cannot be read (v48): a row that EXISTS but is not a list of
4149
- * well-shaped entries — corrupt JSON, a non-list, an entry missing its
4150
- * provider, model, or auth mode — is a stated problem, never an empty
4151
- * list. Filing a scope under such a row refuses in these words rather
4152
- * than silently sealing a single-profile approval the operator did not
4153
- * configure; the chain the person believes they set never shrinks to
4154
- * nothing behind their back.
4155
- */
4156
- fallbackConfigProblem(scope: string): string | null;
4157
- private readFallbackConfig;
4158
- setFallbackConfig(scope: string, entries: {
4159
- provider: string;
4160
- model: string;
4161
- authMode: "subscription" | "api-key";
4162
- repairModel?: string;
4163
- }[], by: string, now: Date): void;
4164
- clearFallbackConfig(scope: string): boolean;
4165
3540
  clearPhaseConfig(scope: string, phase: string): boolean;
4166
3541
  /** The operator's named STRONG candidate for a phase at a scope, or null.
4167
3542
  * Read by the routing policy only — a phase_config row stays the routine
@@ -4209,7 +3584,7 @@ export declare class Store {
4209
3584
  * nothing. A signed routing input, read at filing. */
4210
3585
  publicationAuthorityOf(repo: string | null, now: Date): PublicationAuthority;
4211
3586
  /**
4212
- * THE ROUTE EDIT (v47): declare the task's risk, override one phase to an
3587
+ * THE ROUTE EDIT (v47): set the task's size, override one phase to an
4213
3588
  * exact agent, or clear an override — ONE authenticated transaction that
4214
3589
  * re-proves the editor's authority, CAS-checks the scope digest the
4215
3590
  * editor saw (a string to match, null = "I saw no scope", undefined =
@@ -4219,7 +3594,7 @@ export declare class Store {
4219
3594
  * is recomputed and the prior approval goes stale by digest, and — when
4220
3595
  * a drafted plan came from the old planner — asks for a real re-plan.
4221
3596
  * No claimant can observe a half-updated authority: it is all or
4222
- * nothing, and refused under a live claim or tournament terms.
3597
+ * nothing, and refused under a live claim.
4223
3598
  */
4224
3599
  editTaskRoute(taskRef: number, edit: {
4225
3600
  by: string;
@@ -4229,7 +3604,6 @@ export declare class Store {
4229
3604
  ok: false;
4230
3605
  reason: string;
4231
3606
  };
4232
- risk?: RiskLevel;
4233
3607
  /** v2: a person's size for the task — it outranks the classifier's. */
4234
3608
  size?: {
4235
3609
  size: TaskSize;
@@ -4258,7 +3632,7 @@ export declare class Store {
4258
3632
  overrides: RouteOverride[];
4259
3633
  } | {
4260
3634
  ok: false;
4261
- reason: "unauthenticated" | "no-task" | "live-claim" | "contest-open" | "changed" | "nothing" | "not-configured";
3635
+ reason: "unauthenticated" | "no-task" | "live-claim" | "changed" | "nothing" | "not-configured";
4262
3636
  detail: string;
4263
3637
  choices?: {
4264
3638
  provider: string;
@@ -4267,9 +3641,8 @@ export declare class Store {
4267
3641
  };
4268
3642
  /** Store a task's size (v2 routing); the next scope filing routes by it. */
4269
3643
  writeSizing(taskRef: number, sizing: TaskSizing): void;
4270
- /** Planning follows the size and risk while nothing has run: a small
4271
- * change at routine risk drops a plan that is only requested; a large or
4272
- * risky one, or any task at elevated or high risk, asks for a plan. A
3644
+ /** Planning follows the size while nothing has run: a small change drops
3645
+ * a plan that is only requested; a large or risky one asks for a plan. A
4273
3646
  * drafted plan is never discarded. */
4274
3647
  private planToSizing;
4275
3648
  /**
@@ -4314,11 +3687,9 @@ export declare class Store {
4314
3687
  * phase's exact leg. A planner may also run under the working
4315
3688
  * proposed route, or — with no scope yet — the live recommendation,
4316
3689
  * re-derived here from durable state. Nothing else.
4317
- * fallback — the task's approved chain: the digest is the sealed
4318
- * route's (or the chain's, when no route is sealed) and the pair is
4319
- * a NON-primary entry of that chain (its repair model for a repair).
4320
- * legacy — only a row proven to predate routing, a task with no scope,
4321
- * a tournament lane, or an attended session; never a routed row.
3690
+ * fallback — never (fallback chains were removed in v115).
3691
+ * legacy — only a row proven to predate routing or a task with no
3692
+ * scope; never a routed row.
4322
3693
  */
4323
3694
  private routeAdmissionProblem;
4324
3695
  /**
@@ -4357,41 +3728,6 @@ export declare class Store {
4357
3728
  approvedRouteOf(taskId: string): PhaseRoute | null;
4358
3729
  /** Pin a task's agent — the fire transaction's stamp; flags never override it. */
4359
3730
  pinTaskAgent(taskRef: number, provider: string, model: string | null): void;
4360
- /**
4361
- * File a standing order, unapproved. The digest is computed by the caller
4362
- * (routineDigestOf) from exactly the terms stored here; approval later
4363
- * binds to it. Nothing fires until a person agrees to the template.
4364
- */
4365
- createRoutine(spec: {
4366
- name: string;
4367
- repo: string;
4368
- goal: string;
4369
- outOfScope: string | null;
4370
- touches: string[];
4371
- acceptance: AcceptanceCriterion[];
4372
- requirements: string[];
4373
- schedule: string;
4374
- singleFlight: boolean;
4375
- costCeilingUsd: number | null;
4376
- budgetPerRunMicrousd?: number | null;
4377
- digest: string;
4378
- /** Immutable provenance (v12), same contract as createConsoleTask's. */
4379
- filedVia?: string;
4380
- /** v102: who made it; its instances are filed as theirs. */
4381
- createdBy?: string | null;
4382
- /** v24: resolved at filing by the caller who computed the digest —
4383
- * stored verbatim so digest and profile can never disagree. */
4384
- profile?: ExecutionProfile;
4385
- /** v48: the four-role route the digest binds, computed by the same
4386
- * caller from the same configuration — stored verbatim. */
4387
- route?: PhaseRoute;
4388
- }, now: Date): {
4389
- ok: true;
4390
- id: number;
4391
- } | {
4392
- ok: false;
4393
- reason: "duplicate";
4394
- };
4395
3731
  /**
4396
3732
  * Set-once installation markers (v12). INSERT OR IGNORE is the whole
4397
3733
  * contract: the first write wins forever, there is no update and no
@@ -4405,151 +3741,22 @@ export declare class Store {
4405
3741
  isDemo(): boolean;
4406
3742
  setSpendDefaults(defaults: {
4407
3743
  buildPerRunMicrousd: number | null;
4408
- racePerAgentMicrousd: number | null;
4409
- raceTotalMicrousd: number | null;
4410
- raceAgents?: number | null;
4411
3744
  }, by: string, now: Date): void;
4412
3745
  getSpendDefaults(): {
4413
3746
  buildPerRunMicrousd: number | null;
4414
- racePerAgentMicrousd: number | null;
4415
- raceTotalMicrousd: number | null;
4416
- raceAgents: number | null;
4417
3747
  updatedBy: string;
4418
3748
  } | null;
4419
- /**
4420
- * File a new terms row: the previous active row (if any) deactivates in
4421
- * the same transaction — rows are immutable, the ACTIVE pointer moves.
4422
- * Approval lands later, by the same ceremony that approves the scope.
4423
- */
4424
- /** Withdraw the standing race: the row survives deactivated, exactly as
4425
- * a superseding filing would leave it — the task returns to the ordinary
4426
- * one-agent path. */
4427
- retractTournamentTerms(taskRef: number): boolean;
4428
- fileTournamentTerms(spec: {
4429
- taskRef: number;
4430
- /** v27: absent = 'race' (every historical caller). */
4431
- kind?: "race" | "comparison";
4432
- raceDigest: string;
4433
- agents: {
4434
- provider: string;
4435
- model: string;
4436
- repairModel: string;
4437
- permissionMode?: UnattendedPermissionMode;
4438
- }[];
4439
- perAgentBudgetMicrousd: number;
4440
- overrunReserveMicrousd: number;
4441
- totalBudgetMicrousd: number;
4442
- priceVersion: number;
4443
- publicationPolicy: string;
4444
- }, now: Date): number;
4445
- activeTournamentTerms(taskRef: number): TournamentTerms | null;
4446
- /** Approval persistence only — the restating ceremony wires in later. */
4447
- approveTournamentTerms(id: number, by: string, sawDigest: string, now: Date): boolean;
4448
- createContest(spec: {
4449
- taskRef: number;
4450
- terms: number;
4451
- scopeDigest: string;
4452
- raceDigest: string;
4453
- kind?: "race" | "comparison";
4454
- }, now: Date): number;
4455
- getContest(id: number): Contest | null;
4456
- /** The one non-finished tournament for a task, when one exists. */
4457
- /** The newest tournament still owed to an operator — open states plus
4458
- * the two that end with nothing pickable and wait for a human verdict. */
4459
- contestNeedingOperator(taskRef: number): Contest | null;
4460
- openContestFor(taskRef: number): Contest | null;
4461
- /**
4462
- * Every state change is a compare-and-swap on (state, generation): the
4463
- * caller proves what it believes, the write bumps the generation, and
4464
- * whichever of aggregation, reaping, or crash recovery loses the race
4465
- * changes nothing (finding 17/27).
4466
- */
4467
- casContestState(id: number, from: readonly ContestState[], to: ContestState, expectedGeneration: number): boolean;
4468
- stampContestLease(id: number, leaseId: string, runner: string, incarnation: string | null): void;
4469
- stampContestDispatch(id: number, baseSha: string, setupDigest: string | null): void;
4470
- createContestants(contest: number, agents: {
4471
- provider: string;
4472
- model: string;
4473
- repairModel: string;
4474
- permissionMode?: UnattendedPermissionMode;
4475
- branch: string;
4476
- budgetMicrousd: number;
4477
- reserveMicrousd: number;
4478
- unknownSpend?: boolean;
4479
- }[]): number[];
4480
- /** The lane's CUMULATIVE wall clock across its whole lineage — main
4481
- * attempt, resumes, and repair children (Phase 3 slice B, Codex
4482
- * finding 1): three sealed clocks bound a comparison lane. */
4483
- contestantCumulativeMs(contestantId: number): number;
4484
- /** The lane's money and tokens across its WHOLE lineage — main attempt,
4485
- * resumes, and repair children (Codex slice-B finding 6): a lane's cell
4486
- * that reads only the newest run under-reports every park cycle. */
4487
- contestantSpendRollup(contestantId: number): {
4488
- costMicrousd: number;
4489
- tokensIn: number;
4490
- tokensOut: number;
4491
- measuredRuns: number;
4492
- totalRuns: number;
4493
- };
4494
- contestants(contest: number): Contestant[];
4495
- getContestant(id: number): Contestant | null;
4496
- casContestantState(id: number, from: readonly ContestantState[], to: ContestantState, expectedGeneration: number): boolean;
4497
- /**
4498
- * The exact authority a contest lane PRESENTS at admission (raw
4499
- * authority repair): its race-approved profile's digest as a `legacy`
4500
- * stamp, with the pair the lane spends as for the phase — the same
4501
- * facts `startRun` re-proves against the lane before the row exists.
4502
- * Null for no such lane.
4503
- */
4504
- laneAuthorityFor(contestantId: number, phase?: "build" | "repair"): RouteStamp | null;
4505
- releaseContestantRun(id: number, runId: number): void;
4506
- setContestantWorktree(id: number, worktree: string): void;
4507
- /** The lineage meter (finding 25 + round-2 finding on repairs): each
4508
- * finished invocation settles ONCE, and the agent's total is the SUM
4509
- * across its whole lineage — a park's spend and its resume's spend are
4510
- * both real money. Accounted tracks at least the measured total. */
4511
- recordContestantSpend(id: number, invocationMicrousd: number): void;
4512
- /** A started invocation that never reported: the ledger charges the FULL
4513
- * reservation — never the remaining amount — and says the real figure is
4514
- * unknown (finding 25). Idempotent; never lowers a larger accounting. */
4515
- latchContestantUnknownSpend(id: number): void;
4516
- setContestantCustody(id: number, custody: string | null): void;
4517
- /** The cleanup queue (stage 6): agents of DECIDED tournaments whose
4518
- * checkouts still sit outside the pool. Terminal contest states only —
4519
- * an undecided tournament's evidence is never touched. */
4520
- contestantsForCleanup(): Contestant[];
4521
- /** Exactly-once overdue escalation: the mark rides the page (stage 6). */
4522
- markContestOverduePaged(contestId: number): boolean;
4523
- /** The pick, stamped: who chose, when, and which agent won. */
4524
- setContestWinner(contestId: number, contestantId: number, approver: string, now: Date): void;
4525
- setContestantCleanup(id: number, cleanup: "pending" | "done" | "attention"): void;
4526
- contestsInStates(states: readonly ContestState[]): Contest[];
4527
3749
  /** The still-live claim behind a lease id, or null — recovery's question.
4528
3750
  * The clock is INJECTED like everywhere else; SQL wall-clock time would
4529
3751
  * silently disagree with every test's fixed timestamps. */
4530
3752
  liveClaimByLease(leaseId: string, now: Date): {
4531
3753
  leaseId: string;
4532
3754
  } | null;
4533
- /**
4534
- * Close a racing agent's question WITHOUT answering it (the exclude
4535
- * ceremony, round-3 finding 28): typed closure, never a fake option.
4536
- * The caller owns authentication and the contestant's stop.
4537
- */
4538
- excludeDecision(id: number, by: string, now: Date): boolean;
4539
- /** A racing agent's answered-but-undelivered question, for the resume pass. */
4540
- answeredDecisionForContestant(contestantId: number): number | null;
4541
- /** A racing agent's one open (or expired-but-unanswered) question. */
4542
- openDecisionForContestant(contestantId: number): number | null;
4543
- /** Admission binds each reserved slot to its agent, so recovery can
4544
- * find and free every one of them (nothing reserved is ever orphaned). */
4545
- assignSlotContestant(slotId: number, contestantId: number): void;
4546
- releaseSlotsForContest(contestId: number, now: Date): number;
4547
3755
  reserveExecutionSlots(runner: string, count: number, now: Date): number[];
4548
3756
  /** reserved → running happens in the stamp-before-spawn moment, carrying
4549
3757
  * the process group so recovery can ask the OS before freeing capacity. */
4550
3758
  markSlotRunning(id: number, facts: {
4551
3759
  run: number;
4552
- contestant?: number | null;
4553
3760
  incarnation?: string | null;
4554
3761
  processGroup?: number | null;
4555
3762
  }, now: Date): boolean;
@@ -4557,7 +3764,6 @@ export declare class Store {
4557
3764
  * root attempt. It may refresh only that attempt's exact occupied slot. */
4558
3765
  refreshSlotProcess(id: number, facts: {
4559
3766
  run: number;
4560
- contestant?: number | null;
4561
3767
  incarnation?: string | null;
4562
3768
  processGroup: number;
4563
3769
  }): boolean;
@@ -4692,7 +3898,7 @@ export declare class Store {
4692
3898
  title: string;
4693
3899
  repo: string | null;
4694
3900
  }[];
4695
- /** Whether any work was ever filed — task or routine. */
3901
+ /** Whether any work was ever filed. */
4696
3902
  hasAnyWork(): boolean;
4697
3903
  /** Which door filed a task; null for history from before v12. */
4698
3904
  /** The coordinator provenance label for a task — `mcp:<name>#<cid4>` —
@@ -4704,137 +3910,6 @@ export declare class Store {
4704
3910
  filedAt: string | null;
4705
3911
  } | null;
4706
3912
  filedViaOf(taskId: string): string | null;
4707
- getRoutine(id: number): Routine | null;
4708
- routineByName(name: string): Routine | null;
4709
- /** Every routine one view may see. NULL repo filter means "no filter". */
4710
- listRoutines(repo: string | null, admitted?: string[] | null): Routine[];
4711
- /**
4712
- * Rewrite a template's terms. The new digest rides along, and the old
4713
- * approval is kept — invalidated by the mismatch, exactly like a scope
4714
- * edit, so the refusal can say "approved, then edited" rather than
4715
- * "never approved". The firing transaction re-proves the match.
4716
- */
4717
- updateRoutineTerms(id: number, terms: {
4718
- goal: string;
4719
- outOfScope: string | null;
4720
- touches: string[];
4721
- /** v39: absent leaves the stored rubric untouched (a caller editing
4722
- * goal/touches without an opinion on acceptance); present REPLACES
4723
- * it — never merged, so the digest the caller computed from these
4724
- * exact terms is what ends up stored. */
4725
- acceptance?: AcceptanceCriterion[];
4726
- requirements: string[];
4727
- schedule: string;
4728
- costCeilingUsd: number | null;
4729
- digest: string;
4730
- /** v24: restatement carries the profile its digest binds. */
4731
- profile?: ExecutionProfile | null;
4732
- /** v48: restatement carries the route its digest binds; absent or
4733
- * null leaves the stored route untouched. */
4734
- route?: PhaseRoute | null;
4735
- }, now: Date): boolean;
4736
- /**
4737
- * The approval stamp, raw. Callers own the ceremony — credential,
4738
- * digest re-read, and the transaction — in approveRoutine (routine.ts).
4739
- */
4740
- stampRoutineApproval(id: number, by: string, digest: string, nextFireAt: string, now: Date): void;
4741
- /**
4742
- * WITHDRAW an approval that no longer verifies (v48 authority repair): the refresh road
4743
- * clears the approval's authority — its digest, its frozen snapshot, the
4744
- * armed schedule — so a corrupt or never-taken snapshot cannot keep
4745
- * reading as approved while the working agents happen to be unchanged.
4746
- * `approved_at`/`approved_by` stay as history: the page reads "approved,
4747
- * then refreshed — approve again", never "never approved".
4748
- */
4749
- withdrawRoutineApproval(id: number, now: Date): boolean;
4750
- /** Pausing is instant and needs no ceremony; resuming re-arms the schedule. */
4751
- setRoutinePaused(id: number, paused: boolean, now: Date): boolean;
4752
- /**
4753
- * Routines a pass should try to fire: approved (digest intact), unpaused,
4754
- * due, and placed in this pass's repository. Each candidate is re-proved
4755
- * inside fireRoutine's own transaction — this list only nominates.
4756
- */
4757
- dueRoutines(repo: string, now: Date): Routine[];
4758
- /** The last firings, newest first — the board's run-history strip. */
4759
- routineFires(routineId: number, limit?: number): (RoutineFire & {
4760
- instanceTaskId: string | null;
4761
- instanceState: string | null;
4762
- })[];
4763
- /**
4764
- * What one routine's instances actually cost in a window, and whether any
4765
- * paid run in it is unmeasured. NULL costs are counted, not summed over:
4766
- * a sum that silently omits them reads as headroom that may not exist
4767
- * (finding 5 — the arithmetic behind failing closed).
4768
- */
4769
- routineSpend(routineId: number, sinceIso: string): {
4770
- costUsd: number;
4771
- unmeasuredRuns: number;
4772
- totalRuns: number;
4773
- };
4774
- /**
4775
- * The single-flight question: the oldest instance not successfully
4776
- * completed nor explicitly abandoned — queued, running, held, parked,
4777
- * and failed instances all block (finding 9's definition, verbatim).
4778
- * A LIVE CLAIM blocks regardless of task state (Codex Phase C review,
4779
- * H2): a state string written over a running build — `task state <id>
4780
- * done` bypassing the guarded cancel — must not conjure a twin beside
4781
- * a provider that is still spending.
4782
- */
4783
- routineBlocker(routineId: number, now: Date): {
4784
- taskId: string;
4785
- state: string;
4786
- } | null;
4787
- /**
4788
- * Whether a slot is still unrecorded. Only sound inside the fire
4789
- * transaction — the IMMEDIATE lock is what makes read-then-insert atomic.
4790
- */
4791
- routineSlotOpen(routineId: number, scheduledFor: string): boolean;
4792
- /** Record one slot's outcome. False: the slot was already recorded — the caller lost the race. */
4793
- recordRoutineFire(fire: {
4794
- routineId: number;
4795
- scheduledFor: string;
4796
- outcome: "fired" | "skipped";
4797
- reason: string | null;
4798
- instanceTaskRef: number | null;
4799
- }, now: Date): boolean;
4800
- /** Advance the schedule. The fire transaction is the only caller. */
4801
- setRoutineNextFire(id: number, nextFireAt: string, now: Date): void;
4802
- /** Stamp which routine a task is an instance of. Set at spawn, never after. */
4803
- linkRoutineInstance(taskRef: number, routineId: number): void;
4804
- /**
4805
- * Page a blocked track once per EPISODE: an open episode under this
4806
- * prefix already nags, so nothing enqueues; a resolved one is history,
4807
- * and the fresh suffix keys a new row past the dedupe uniqueness — a
4808
- * recurrence after recovery pages again (Codex Phase C review, L1).
4809
- * Prefix matching is exact-bytes (substr), never LIKE — task ids may
4810
- * contain `_`, which LIKE would read as a wildcard.
4811
- */
4812
- enqueueRoutineEpisode(prefix: string, notification: Omit<NotificationInput, "dedupeKey">, suffix: string, now: Date): boolean;
4813
- /**
4814
- * Close every blocked-track episode for a routine — called when a firing
4815
- * succeeds, because success is the proof the blocker is gone (budget
4816
- * cleared, blocking instance finished). Receipts stay; only the "wants a
4817
- * person" bit resolves.
4818
- */
4819
- resolveRoutineEpisodes(routineId: number, now: Date): void;
4820
- /**
4821
- * Everything the board's track rows need, in one snapshot: each routine
4822
- * with its recent firings, its rolling-window spend, and the instance
4823
- * blocking it, if any. The caller applies the ceiling row by row.
4824
- */
4825
- routineTracks(repo: string | null, now: Date, admitted?: string[] | null): {
4826
- routine: Routine;
4827
- fires: ReturnType<Store["routineFires"]>;
4828
- spend: {
4829
- costUsd: number;
4830
- unmeasuredRuns: number;
4831
- totalRuns: number;
4832
- };
4833
- blocker: {
4834
- taskId: string;
4835
- state: string;
4836
- } | null;
4837
- }[];
4838
3913
  /** The latest saved line for one approved check. Corrupt rows stay absent. */
4839
3914
  checkProgress(run: number): CheckProgress | null;
4840
3915
  /**
@@ -4867,8 +3942,8 @@ export declare class Store {
4867
3942
  * not failed. Failures, refusals, parks, plans and reports already page
4868
3943
  * through their own producers (build-failed, stalled, commit-failure,
4869
3944
  * malformed-*, plan-ready, report-ready, fenced, external-closed) and are
4870
- * not repeated here. Contest lanes and repair/correction children are the
4871
- * attempt's own and say nothing on their own.
3945
+ * not repeated here. Repair/correction children are the attempt's own
3946
+ * and say nothing on their own.
4872
3947
  */
4873
3948
  private noteRunEnding;
4874
3949
  /** True if this is a new fact; false if the episode already knows.
@@ -4888,6 +3963,8 @@ export declare class Store {
4888
3963
  resolveEpisodes(prefix: string, now: Date): number;
4889
3964
  notificationById(id: number): Notification | null;
4890
3965
  notificationsAfter(id: number, limit?: number): Notification[];
3966
+ /** What landed before a pairing (and at or before `through`) and still wants that person (WANTED_BEFORE_PAIRING). */
3967
+ notificationsWantedBefore(created: string, through: number, limit?: number): Notification[];
4891
3968
  listNotifications(only?: "pending" | "all"): Notification[];
4892
3969
  /**
4893
3970
  * Close a gap's notification episode. Called when its capability verifies:
@@ -4908,13 +3985,12 @@ export declare class Store {
4908
3985
  * mid-flight, visible the next morning instead of vanished.
4909
3986
  *
4910
3987
  * THE GENERIC ADMISSION (atomic authority closure) opens exactly four
4911
- * shapes: an ordinary builder (no parent, no lane, no open attended
4912
- * authorization on its task), a planner (optionally continuing its own
3988
+ * shapes: an ordinary builder (no parent, no lane), a planner (optionally continuing its own
4913
3989
  * same-task planner run), a scout, and a ROOT reviewer answering an open
4914
3990
  * review request. Every other shape has its own admission that proves
4915
3991
  * and consumes or binds its exact authority in one transaction —
4916
- * `admitRepair`, `admitAttended`, `admitCorrection`, `admitContestLane`,
4917
- * `admitRecoveredBuilder`, `admitFallback` — and this road refuses it in
3992
+ * `admitRepair`, `admitCorrection`,
3993
+ * `admitRecoveredBuilder` — and this road refuses it in
4918
3994
  * words before any row exists. Every run PRESENTS its route authority: a
4919
3995
  * task with no scope presents the bare word `legacy` for the exact pair
4920
3996
  * it spends as; nothing opens unstamped anywhere.
@@ -4935,20 +4011,6 @@ export declare class Store {
4935
4011
  * a caller can spread the authority it resolved; absent at runtime
4936
4012
  * it refuses in words. */
4937
4013
  route?: RouteStamp;
4938
- /** v48 authority repair: how this run takes fallback-chain custody, proved and
4939
- * persisted in this same insert — `base` opens the task's cycle at
4940
- * the approved chain's first entry (inert without a chain approval),
4941
- * `resume` takes a parked BASE tail's custody through the proven
4942
- * transfer. A binding that cannot be proved rolls the insert back.
4943
- * Builder-only: no other role takes custody. Every run bound to a
4944
- * NON-primary entry — the entry's own admission, a parked tail's
4945
- * successor, a repair turn — is admitted by admitFallback alone. */
4946
- custody?: {
4947
- kind: "base";
4948
- } | {
4949
- kind: "resume";
4950
- parkedRun: number;
4951
- };
4952
4014
  now: Date;
4953
4015
  } & ({
4954
4016
  role?: "builder" | "planner" | "scout";
@@ -4976,12 +4038,7 @@ export declare class Store {
4976
4038
  * this task's, is a builder, is still open, and this turn runs under
4977
4039
  * the parent's own runner and lease — which must be the task's CURRENT
4978
4040
  * live claim, on the runner that claim names (repair custody closure:
4979
- * the same tuple invariant every fallback admission proves). An
4980
- * attended parent's authorization
4981
- * must have spent its one attempt on that parent; a racing lane's
4982
- * parent must be the lane's live run; a chain-bound parent must be the
4983
- * live base tail (a fallback entry's repair is admitFallback's). The
4984
- * stamp is the repair leg of the authority the parent spent under.
4041
+ * the exact claim tuple). The stamp is the repair leg of the authority the parent spent under.
4985
4042
  * Value-shaped: a refusal names its reason and leaves zero rows.
4986
4043
  */
4987
4044
  admitRepair(run: {
@@ -5003,41 +4060,6 @@ export declare class Store {
5003
4060
  ok: false;
5004
4061
  problem: string;
5005
4062
  };
5006
- /**
5007
- * THE ATTENDED ADMISSION (atomic authority closure): one watched attempt
5008
- * opens under exactly ONE live authorization the caller names — open on
5009
- * this task, unexpired, unspent, minted for this runner at this
5010
- * generation, pinning a readable profile the stamp restates as its
5011
- * legacy authority; a continuation names the finished parent the
5012
- * authorization continues, nothing else names a parent. The insert
5013
- * binds the row to the authorization and CONSUMES its one attempt in
5014
- * the same transaction: `run.attended_authorization` and
5015
- * `authorization.attempt_run` move together or not at all.
5016
- */
5017
- admitAttended(run: {
5018
- taskRef: number;
5019
- leaseId: string;
5020
- runner: string;
5021
- branch: string;
5022
- worktree: string;
5023
- provider: string;
5024
- model?: string;
5025
- sessionId?: string;
5026
- parentRun?: number;
5027
- authorization: {
5028
- id: string;
5029
- runner: string;
5030
- generation: number;
5031
- };
5032
- route: RouteStamp;
5033
- now: Date;
5034
- }): {
5035
- ok: true;
5036
- runId: number;
5037
- } | {
5038
- ok: false;
5039
- problem: string;
5040
- };
5041
4063
  /**
5042
4064
  * THE CORRECTION ADMISSION (atomic authority closure): a reviewer
5043
4065
  * correction continues a LIVE root review in the SAME session — the
@@ -5064,37 +4086,6 @@ export declare class Store {
5064
4086
  ok: false;
5065
4087
  problem: string;
5066
4088
  };
5067
- /**
5068
- * THE CONTEST LANE ADMISSION (atomic authority closure): a racing agent's
5069
- * run opens on ITS lane, in a contest still dispatching or racing, under
5070
- * the contest's live custody — the caller's lease, runner, and watch
5071
- * incarnation are exactly the ones the contest was stamped with — and it
5072
- * presents the lane's STORED sealed profile as its legacy authority: no
5073
- * synthesized profile, no other digest. The lane's pointer moves to the
5074
- * row inside the insert (from free, or from the parked attempt this run
5075
- * resumes); a lane that moved rolls the row back.
5076
- */
5077
- admitContestLane(run: {
5078
- taskRef: number;
5079
- leaseId: string;
5080
- runner: string;
5081
- incarnation: string | null;
5082
- branch: string;
5083
- worktree: string;
5084
- provider: string;
5085
- model?: string;
5086
- sessionId?: string;
5087
- contestant: number;
5088
- parentRun?: number;
5089
- route: RouteStamp;
5090
- now: Date;
5091
- }): {
5092
- ok: true;
5093
- runId: number;
5094
- } | {
5095
- ok: false;
5096
- problem: string;
5097
- };
5098
4089
  /**
5099
4090
  * THE RECOVERED-DRAFT ADMISSION (atomic authority closure): a fresh
5100
4091
  * builder attempt that inherits an INTERRUPTED attempt's draft names it
@@ -5114,12 +4105,6 @@ export declare class Store {
5114
4105
  model?: string;
5115
4106
  sessionId?: string;
5116
4107
  recoveredFrom: number;
5117
- custody?: {
5118
- kind: "base";
5119
- } | {
5120
- kind: "resume";
5121
- parkedRun: number;
5122
- };
5123
4108
  route: RouteStamp;
5124
4109
  now: Date;
5125
4110
  }): {
@@ -5134,22 +4119,17 @@ export declare class Store {
5134
4119
  private admission;
5135
4120
  private admitRun;
5136
4121
  /**
5137
- * THE CURRENT CLAIM, exactly (final admission closure): every admission
5138
- * that changes fallback state — the base that opens a cycle, an entry
5139
- * admitted from a pending edge, a parked tail's resume, a repair turn
5140
- * under the live tail — proves in its own transaction that the run it
5141
- * opens is the task's, under the lease that holds the task RIGHT NOW,
5142
- * on the runner that claim names. A lease nobody holds, one released,
5143
- * expired, or superseded by a newer generation, or a claim another
5144
- * machine holds admits nothing: the words say which, and no cycle,
5145
- * edge, tail, or claim moves. Shared by the fallback road, the primary
5146
- * repair road, and the generic road's custody so all refuse in the
5147
- * same words.
4122
+ * THE CURRENT CLAIM, exactly (final admission closure): a repair turn
4123
+ * proves in its own transaction that the run it opens is the task's,
4124
+ * under the lease that holds the task RIGHT NOW, on the runner that
4125
+ * claim names. A lease nobody holds, one released, expired, or
4126
+ * superseded by a newer generation, or a claim another machine holds
4127
+ * admits nothing: the words say which.
5148
4128
  */
5149
4129
  private custodyClaimProblem;
5150
4130
  /**
5151
4131
  * THE ONE RECOVERY GRANT (final authority closure), shared by the
5152
- * recovered-draft admission and the fallback admission's `recoveredFrom`:
4132
+ * recovered-draft admission's `recoveredFrom`:
5153
4133
  * the interrupted attempt whose draft a fresh run inherits is THIS
5154
4134
  * task's own builder or repair turn, left in this very worktree on this
5155
4135
  * branch, either ended as `failed` for `interrupted` (or `no-handoff`) or still open under
@@ -5159,25 +4139,15 @@ export declare class Store {
5159
4139
  * say which, and the caller opens nothing.
5160
4140
  */
5161
4141
  private recoveryGrantProblem;
5162
- /**
5163
- * Whether `holder` is the LIVE tail of its task's open fallback cycle
5164
- * under the approved chain — the words when it is not (v48 integrity).
5165
- * Re-derived from durable state only: the task's one live cycle is the
5166
- * holder's cycle, open, its cursor at the holder's index, the holder as
5167
- * its tail, its digest the approved chain's, and the approved entry at
5168
- * that index carrying exactly the holder's digest and auth mode.
5169
- */
5170
- private liveTailProblem;
5171
4142
  /**
5172
4143
  * THE WORKING PLAN AUTHORITY (final authority closure): the route a
5173
4144
  * planner runs under before any approval, believed only as the ONE strict
5174
4145
  * stored-scope projection proves it — exact raw terms (a proposed-via
5175
4146
  * marker this code never writes is a terms problem), a resolved profile,
5176
- * a whole fallback chain (an empty or malformed one is no chain), a
5177
- * readable route whose build and repair legs are the profile's exact
4147
+ * a readable route whose build and repair legs are the profile's exact
5178
4148
  * pairs and whose signed risk and quality are the row's, the digest
5179
4149
  * re-derived from those very values, the operator's live auth mode read
5180
- * strictly and agreeing with a chain's pinned base mode, and no leg
4150
+ * strictly, and no leg
5181
4151
  * stating a problem. The claim, the admission, and the invocation all
5182
4152
  * ask this same question; one disagreement is the words, and nothing
5183
4153
  * opens or spawns on it. A sealed route is not this road's business —
@@ -5208,8 +4178,7 @@ export declare class Store {
5208
4178
  * The exact route authority a task holds for one run, in the caller's
5209
4179
  * hands (v48 authority repair): the sealed route's leg for the run's phase when the
5210
4180
  * approval stands; the working proposed route's plan leg for a planner
5211
- * before any approval; for a run bound to a NON-primary chain entry, that
5212
- * entry's `fallback` provenance for its phase. The store never applies
4181
+ * before any approval. The store never applies
5213
4182
  * this on a caller's behalf — `startRun` requires the caller to PRESENT
5214
4183
  * it and proves the presented stamp against the same durable state, so
5215
4184
  * a caller that holds no authority opens nothing. Null when the task is
@@ -5217,10 +4186,7 @@ export declare class Store {
5217
4186
  * scope — those roads stamp when they spend); the words when the task
5218
4187
  * is routed and nothing could govern the run.
5219
4188
  */
5220
- routeAuthorityFor(taskRef: number, role: Run["role"] | "scout", bound?: {
5221
- index: number;
5222
- entryDigest: string;
5223
- } | null,
4189
+ routeAuthorityFor(taskRef: number, role: Run["role"] | "scout",
5224
4190
  /** What the run would spend as, for the roads no profile governs: the
5225
4191
  * bare word `legacy` on a task with no scope, and the plan/review
5226
4192
  * pair of a pre-routing row (its profile names only build and
@@ -5300,8 +4266,7 @@ export declare class Store {
5300
4266
  committed?: boolean;
5301
4267
  now: Date;
5302
4268
  /** v52: how this ending settles a pending operator stop on the run,
5303
- * when one stands. The fenced interruption seal and the held fence
5304
- * name their own word; every other road settles it as `finished` —
4269
+ * when one stands. The fenced interruption seal names its own word; every other road settles it as `finished` —
5305
4270
  * the attempt reached this ending first, and its outcome stands. */
5306
4271
  stopSettlement?: StopSettlement;
5307
4272
  }): void;
@@ -5322,15 +4287,12 @@ export declare class Store {
5322
4287
  */
5323
4288
  stampProviderStart(id: number, now: Date, providerVersion?: string): void;
5324
4289
  /**
5325
- * The gateway's honest disposal record for the fallback taxonomy (E2):
5326
- * how this attempt authenticated, and the class its terminal fell into.
5327
- * Recorded where the evidence still exists — the gateway holds the
5328
- * structural terminal, the authoritative version, and the auth mode — and
5329
- * NEVER re-derived in disposal, by which time the structural signal is
5330
- * gone. Purely observational: the class is stamped on EVERY finished
5331
- * attempt (usually 'unknown'/'not-exhausted', since the recognizers ship
5332
- * empty), and it authorizes NOTHING on its own — the dispatch's C8 gate
5333
- * re-proves hasRecognizer before any advance ever reads it.
4290
+ * The gateway's honest disposal record (E2): how this attempt
4291
+ * authenticated, and the class its terminal fell into. Recorded where the
4292
+ * evidence still exists — the gateway holds the structural terminal and
4293
+ * the auth mode — and NEVER re-derived in disposal, by which time the
4294
+ * structural signal is gone. `auth-expired` pauses its provider; every
4295
+ * other class is observational.
5334
4296
  */
5335
4297
  stampTerminalClass(id: number, authMode: "subscription" | "api-key", terminalClass: TerminalClass): void;
5336
4298
  /** The race-refusal stamp (Phase 3 C5): the version that was REFUSED,
@@ -5376,14 +4338,12 @@ export declare class Store {
5376
4338
  setOrgPolicy(policy: OrgPolicy, by: string, now: Date): SavedPolicy;
5377
4339
  /** The policy's changes, newest first, from the action ledger. */
5378
4340
  policyHistory(limit?: number): LedgerEntry[];
5379
- /** Why the policy stops a task's approved terms (its profile, every fallback entry, every routed leg), or null. */
4341
+ /** Why the policy stops a task's approved terms (its profile, every routed leg), or null. */
5380
4342
  scopePolicyRefusal(taskId: string): string | null;
5381
4343
  /** Why the policy stops an agent on a provider and model now, or null (chats, teammates, flow steps). */
5382
4344
  agentPolicyRefusal(provider: string, model: string | null): string | null;
5383
4345
  /** Why the policy stops a planner, scout or native coding session (no profile to lower) on a provider and model, or null. */
5384
4346
  sessionPolicyRefusal(provider: string, model: string | null, what: string): string | null;
5385
- /** Why the policy stops an attended session's signed profile, or null (it is never lowered: see policy.attendedRefusal). */
5386
- attendedPolicyRefusal(profile: ExecutionProfile): string | null;
5387
4347
  /** The policy's word on a profile about to run: refused, or what runs (lowered under the ceiling, with words). */
5388
4348
  runPolicy(profile: ExecutionProfile): ReturnType<typeof underCeiling>;
5389
4349
  /** The budgets in force. */
@@ -5539,8 +4499,6 @@ export declare class Store {
5539
4499
  recommendation: string;
5540
4500
  assignee?: string;
5541
4501
  deadline?: string;
5542
- /** Which racing agent asked (v14); absent = ordinary. */
5543
- contestant?: number;
5544
4502
  }, now: Date): number;
5545
4503
  getDecision(id: number): Decision | null;
5546
4504
  decisionForRun(run: number): Decision | null;
@@ -5678,223 +4636,21 @@ export declare class Store {
5678
4636
  attachAnswers(runId: number, taskRef: number): (Decision & {
5679
4637
  taskId: string;
5680
4638
  })[];
5681
- /**
5682
- * Mint one attended authorization. Expired predecessors are closed in the
5683
- * SAME transaction (end reason 'expired'); a live one refuses — revoke
5684
- * first, never silently supersede a signature.
5685
- */
5686
- mintAttendedAuthorization(input: {
5687
- id: string;
5688
- taskRef: number;
5689
- approver: string;
5690
- runner: string;
5691
- runnerGeneration: number;
5692
- compositeDigest: string;
5693
- termsJson: string;
5694
- maxSessionTurns: number;
5695
- budgetMicrousd: number;
5696
- parentRun?: number | null;
5697
- followup?: string | null;
5698
- absoluteExpiry: string;
5699
- /** Quick mint (C2/M4): the mode signature substitutes for the
5700
- * per-mint password — RE-PROVED here, in the mint transaction
5701
- * itself, never a pre-checked flag: the mode must be live, its
5702
- * digest exact, and the minting approver must BE the signer. */
5703
- basis?: {
5704
- kind: "mode";
5705
- digest: string;
5706
- };
5707
- now: Date;
5708
- }, mutation?: Mutation): {
5709
- ok: true;
5710
- authorization: AttendedAuthorization;
5711
- } | {
5712
- ok: false;
5713
- reason: "authorization-open" | "mode-ended" | "approval-rules";
5714
- };
5715
- /** Close every authorization past its absolute expiry (round-6 finding
5716
- * 8): the durable closure the gates and the partial unique rely on —
5717
- * an expired corpse must not keep a task locked to its named runner. */
5718
- sweepExpiredAuthorizations(now: Date): number;
5719
- readAuthorization(id: string): AttendedAuthorization | null;
5720
- /** Open continuation authorizations named to this runner (Phase 2E, A4):
5721
- * unconsumed, carrying a parent attempt — tick's continuation pass reads
5722
- * this; liveness is the caller's check, as everywhere. */
5723
- openContinuationAuthorizations(runner: string): AttendedAuthorization[];
5724
- /**
5725
- * Why a finished run cannot be continued right now, in words — or null.
5726
- * The ENUMERATED non-terminal publication states (round-3 R7 demanded
5727
- * the concrete list, not "open intents"): a publication still moving
5728
- * ('intended','pushed', or 'opened' with the remote not yet settled) and
5729
- * a merge intent still live ('pending','claimed') both block.
5730
- */
5731
- continuationBlockOf(runId: number): string | null;
5732
- /** The one OPEN authorization for a task, or null. */
5733
- openAuthorizationFor(taskRef: number): AttendedAuthorization | null;
5734
- /**
5735
- * One durable liveness beat. The DURABLE COLUMN IS THE AUTHORITATIVE
5736
- * CLOCK; the only suppressed writes are duplicate-tab beats landing
5737
- * within 5 seconds of the stored value, so observed grace never shrinks
5738
- * below 40 of the nominal 45 seconds.
5739
- */
5740
- beatAuthorization(id: string, now: Date): boolean;
5741
- /** Explicit terminal closure — run end, expiry, or revocation. CAS on open. */
5742
- closeAuthorization(id: string, endReason: string, now: Date): boolean;
5743
- /**
5744
- * Money already committed against an authorization: settled and uncertain
5745
- * turns at their accounted charge, plus the live reservation of any
5746
- * unsettled turn. The budget gate reads THIS, never run.cost_usd.
5747
- */
5748
- authorizationSpendMicrousd(id: string): number;
5749
- /**
5750
- * Record one turn — the gate where the cap, the single-flight rule, the
5751
- * budget reservation, the lease re-proof, and the open-decision rule all
5752
- * hold or refuse ATOMICALLY (v6 W6: a fenced coordinator fails inside
5753
- * this transaction, not at its next poll). For 'answer' turns the
5754
- * delivery-CAS on decision.delivered_turn happens here; run_decision
5755
- * attaches only at ACCEPTANCE (v6 W5).
5756
- */
5757
- recordSessionTurn(input: {
5758
- run: number;
5759
- sourceKind: SessionTurn["sourceKind"];
5760
- sourceId?: number | null;
5761
- author?: string | null;
5762
- text: string;
5763
- repairLimit?: number;
5764
- now: Date;
5765
- }): {
5766
- ok: true;
5767
- turn: SessionTurn;
5768
- } | {
5769
- ok: false;
5770
- reason: RecordTurnRefusal;
5771
- };
5772
- /** Answered decisions on a held run whose answer has not yet been
5773
- * injected — the coordinator's per-pulse scan (v3 R3). */
5774
- undeliveredDecisionsOf(run: number): Decision[];
5775
- readSessionTurn(id: number): SessionTurn | null;
5776
- sessionTurnsOf(run: number): SessionTurn[];
5777
- /** Bytes flushed to stdin. Write success is NOT acceptance (spike fact 5). */
5778
- markTurnWritten(id: number, now: Date): boolean;
5779
- /**
5780
- * Bind pending answers to the BRIEF turn (round-6 finding 2): a held
5781
- * build's brief carries every answered-but-undelivered decision, and the
5782
- * builder's ordinary pre-spawn attach would claim delivery the agent
5783
- * never proved. The pre-attached run_decision rows are WITHDRAWN here and
5784
- * each decision's delivery-CAS points at the brief turn — run_decision
5785
- * re-attaches only at that turn's acceptance, exactly like answer turns.
5786
- */
5787
- bindBriefDeliveries(runId: number, briefTurn: number, decisionIds: readonly number[]): void;
5788
- /**
5789
- * Acceptance — THIS turn's system/init (or its result, retroactively).
5790
- * This is also where run_decision attaches, for EVERY decision whose
5791
- * delivery-CAS points at this turn (answer turns claim one at recording;
5792
- * a brief turn claims every pending answer it carried): delivery is
5793
- * claimed only once the agent provably received the words (v6 W5).
5794
- */
5795
- markTurnAccepted(id: number, now: Date): boolean;
5796
- private attachDeliveriesOf;
5797
- /**
5798
- * Settle a turn from its result. The provider's totals are CUMULATIVE per
5799
- * process, so the measured charge is the marginal delta from the held
5800
- * session's durable baseline, advanced here atomically. A missing or
5801
- * regressing total is a TELEMETRY FAILURE: the turn settles uncertain at
5802
- * its reservation, the baseline stays, and the caller must end the hold.
5803
- * Run aggregates gain the same delta so attended spend never disappears
5804
- * from routine reporting (v3 R4).
5805
- */
5806
- settleTurn(id: number, result: {
5807
- cumulativeMicrousd: number | null;
5808
- outputTokens: number | null;
5809
- now: Date;
5810
- }): {
5811
- ok: true;
5812
- measuredMicrousd: number;
5813
- } | {
5814
- ok: false;
5815
- reason: "telemetry" | "not-unsettled";
5816
- };
5817
- /**
5818
- * Terminal conservative settlement on process exit (ruling 15).
5819
- * 'cancelled' = recorded but never written: charged zero. 'uncertain' =
5820
- * written or accepted but never proven settled: charged its reservation.
5821
- * A turn that never reached ACCEPTANCE reverts its delivery claim so the
5822
- * ordinary road can deliver the answer later (v6 W5); an accepted turn
5823
- * keeps its attach — acceptance is the proof.
5824
- */
5825
- settleTurnTerminal(id: number, terminal: "uncertain" | "cancelled", now: Date): boolean;
5826
- private chargeRunAggregates;
5827
- /**
5828
- * Custody intent — INSERTed in the final dispatch-proof transaction,
5829
- * before spawn. The run-held partial unique refuses a
5830
- * second hold typed, not by accident.
5831
- */
5832
- openHeldSession(input: {
5833
- run: number;
5834
- authorizationId: string;
5835
- runner: string;
5836
- leaseId: string;
5837
- upIncarnation: string;
5838
- cookie: string;
5839
- socketPath: string;
5840
- now: Date;
5841
- }): {
5842
- ok: true;
5843
- } | {
5844
- ok: false;
5845
- reason: "run-held";
5846
- };
5847
- /** Stamp pids after spawn. False = the row closed underneath the spawn — kill the child. */
5848
- stampHeldSession(run: number, supervisorPid: number, agentPgid: number): boolean;
5849
- heldSessionOf(run: number): HeldSession | null;
5850
- /** Every un-ended custody row — the fence sweep's and hard-stop's read. */
5851
- /** The durable session gauge (v28): open custody rows for this runner —
5852
- * a restarted `up` with orphans pending must count them, so the
5853
- * in-process map is never the truth. */
5854
- openHeldSessionCount(runner: string): number;
5855
- /** Every open authorization on this runner — the beat-all's worklist. */
5856
- openAuthorizationsOf(runner: string): AttendedAuthorization[];
5857
- openHeldSessions(): HeldSession[];
5858
- /** Ordinary close by the owning coordinator. CAS on un-ended. */
5859
- endHeldSession(run: number, endReason: string, now: Date): boolean;
5860
- /**
5861
- * SEIZE custody for fencing (v6, after v4 Q5): CAS open→fencing AND fence
5862
- * the recorded lease in ONE transaction, so a wedged owner's heartbeat
5863
- * revival and every later coordinator write fail before any kill happens.
5864
- */
5865
- seizeHeldSession(run: number, fencer: string, deadline: Date, now: Date): {
5866
- ok: true;
5867
- session: HeldSession;
5868
- } | {
5869
- ok: false;
5870
- reason: "not-open";
5871
- };
5872
- /**
5873
- * Take over a fencing operation whose owner went quiet (v5 P3): CAS on
5874
- * the EXPIRED deadline. A loser stops only while a live fencer owns it.
5875
- */
5876
- takeoverHeldFencing(run: number, fencer: string, deadline: Date, now: Date): boolean;
5877
- /** Re-arm the fencing deadline while the work continues. Owner-CASed. */
5878
- renewHeldFencing(run: number, fencer: string, deadline: Date): boolean;
5879
- /** Final close of a fenced session — owner-CASed, after kill + settlement. */
5880
- closeHeldFencing(run: number, fencer: string, endReason: string, now: Date): boolean;
5881
4639
  /**
5882
4640
  * File one steering note (arc 1). Validation is validateNote EXACTLY —
5883
- * no bespoke rule — and filing refuses on finished tasks and during open
5884
- * tournaments (contestants share a task; all-racer delivery is a future
5885
- * many-to-many, not a silent single-racer lie).
4641
+ * no bespoke rule — and filing refuses on finished tasks.
5886
4642
  */
5887
4643
  fileSteerNote(taskId: string, author: VerifiedAuthor, note: string, now: Date, mutation?: Mutation): {
5888
4644
  ok: true;
5889
4645
  id: number;
5890
4646
  } | {
5891
4647
  ok: false;
5892
- reason: "unknown-task" | "task-finished" | "contest-open" | "invalid-note";
4648
+ reason: "unknown-task" | "task-finished" | "invalid-note";
5893
4649
  problem?: string;
5894
4650
  };
5895
4651
  /** Every steering note of a task, filing order, delivery state included. */
5896
4652
  listSteerNotes(taskRef: number): SteerNote[];
5897
- /** Undelivered, unsuperseded notes — the admitContest refusal predicate. */
4653
+ /** Undelivered, unsuperseded notes. */
5898
4654
  pendingSteerCount(taskRef: number): number;
5899
4655
  /**
5900
4656
  * The attach transaction (arc 1 finding 9): a DEDICATED pre-invocation
@@ -6015,7 +4771,9 @@ export declare class Store {
6015
4771
  resolveIncident(id: number, by: string, now: Date): boolean;
6016
4772
  /** The body, for callers already holding the transaction (requeueTask). */
6017
4773
  private resolveIncidentLocked;
6018
- /** Mint a pairing code's record. The code itself was shown once; this is its hash. */
4774
+ /** The shared chat core, bound to Telegram: the same pairing, rooms and worker rules every chat app keeps. */
4775
+ telegramChat(): ChatMessages;
4776
+ /** Mint a pairing code's record. The code itself was shown once; this is its hash. A Telegram code works on its bot. */
6019
4777
  createTelegramPairing(pairing: {
6020
4778
  codeHash: string;
6021
4779
  approver: string;
@@ -6023,14 +4781,15 @@ export declare class Store {
6023
4781
  ttlMs: number;
6024
4782
  }, now: Date): void;
6025
4783
  /**
6026
- * Consume a pairing code and create the binding, as one transaction.
4784
+ * Consume a pairing code and create the binding, as one transaction, by the rules every chat app shares
4785
+ * (ChatCore.consumePairing): a replay of the very update that paired finds its finished binding.
6027
4786
  *
6028
- * The conditional UPDATE is the consumption: exactly one caller ever sees
6029
- * `changes = 1`, however many pollers race. A replay of the very update
6030
- * that paired (Telegram redelivers) recognizes the finished binding
6031
- * instead of failing. Success invalidates every other outstanding code —
6032
- * a code that was minted and superseded must not still open a door — and
6033
- * the partial unique index enforces one live binding per bot.
4787
+ * A person's FIRST pairing starts from now (Telegram task updates): every ROUTINE fact already in the outbox is
4788
+ * history for this destination — settled here, in the pairing's own transaction, with a receipt that says it was
4789
+ * skipped, never sent as a backlog to a phone that just arrived. The skip is explicit: no delivered_at, no attempt,
4790
+ * only the `skipped:` receipt — a message no phone received is never reported as delivered (see TELEGRAM_UNSETTLED).
4791
+ * An open decision or an attention-class fact still wants a person and stays pending. A re-pairing after a
4792
+ * revocation keeps the older promise instead: what no phone ever received still waits for whenever pairing happens.
6034
4793
  */
6035
4794
  consumeTelegramPairing(attempt: {
6036
4795
  codeHash: string;
@@ -6049,13 +4808,7 @@ export declare class Store {
6049
4808
  /** The live team-conversation row for one chat, group or private. */
6050
4809
  telegramTeamChat(botId: string, chatId: string): TelegramTeamChat | null;
6051
4810
  listTelegramTeamChats(botId: string): TelegramTeamChat[];
6052
- /**
6053
- * Point a chat at a team conversation: an earlier choice for the same chat
6054
- * is revoked in the same transaction, and delivery starts from now — the
6055
- * conversation's history is read in the console, never replayed into a
6056
- * chat that just arrived. A group already following another conversation
6057
- * elsewhere, or a conversation already followed by another group, refuses.
6058
- */
4811
+ /** Point a chat at a team conversation (ChatCore.bindRoom: the same rule in every chat app). */
6059
4812
  bindTelegramTeamChat(args: {
6060
4813
  botId: string;
6061
4814
  chatId: string;
@@ -6074,11 +4827,9 @@ export declare class Store {
6074
4827
  /** Forward only: a cursor never moves back, and a revoked row keeps its last position. */
6075
4828
  advanceTelegramTeamCursor(id: number, messageId: number): boolean;
6076
4829
  /**
6077
- * Every live binding for a bot, oldest first — and only while each
6078
- * approver's credential generation still matches. A rotation that
6079
- * somehow missed the sweep reads as no binding at all, which is the
6080
- * failure direction that fails closed. Several teammates may each hold
6081
- * one (v72); nothing here ranks them.
4830
+ * Every live binding for a bot, oldest first — and only while each approver's credential generation still matches.
4831
+ * A rotation that somehow missed the sweep reads as no binding at all, which is the failure direction that fails
4832
+ * closed. Several teammates may each hold one (v72); nothing here ranks them.
6082
4833
  */
6083
4834
  liveTelegramBindings(botId: string): TelegramBinding[];
6084
4835
  /** The live binding one Telegram user holds with a bot, if any. */
@@ -6092,130 +4843,41 @@ export declare class Store {
6092
4843
  /** Revoke every live binding one person holds with a bot, and everything
6093
4844
  * those chats could still do. Teammates' bindings are untouched. */
6094
4845
  unpairTelegram(botId: string, by: string, now: Date): boolean;
6095
- createTelegramAction(action: {
6096
- token: string;
6097
- binding: number;
6098
- decision: number;
6099
- optionId: string;
6100
- phase: "choose" | "confirm" | "cancel";
6101
- chatId: string;
6102
- messageId?: string;
6103
- ttlMs?: number;
6104
- /** Binds an irreversible confirmation to the EXACT note it showed. */
6105
- noteDigest?: string;
6106
- }, now: Date): void;
6107
- /** Which decision an outbound Telegram message carried. Recorded after the
6108
- * send returns its id; a send whose record was lost routes nothing. */
6109
- recordTelegramDecisionMessage(binding: number, chatId: string, messageId: string, decision: number, now: Date): void;
6110
- /** The decision behind an exact replied-to message, or nothing. Never "the latest". */
6111
- decisionForTelegramMessage(binding: number, chatId: string, messageId: string): number | null;
6112
- /** The one live, unexpired draft for a decision, if any. */
6113
- liveNoteDraft(binding: number, decision: number, now: Date): {
6114
- id: number;
6115
- note: string;
6116
- updateId: number;
6117
- state: string;
6118
- } | null;
6119
- /**
6120
- * Persist a validated note as the live draft. A newer update SUPERSEDES
6121
- * the old draft — drafts are immutable, and only a GREATER update_id may
6122
- * replace one, so out-of-order delivery cannot resurrect an older note
6123
- * (Codex free-text review, state machine). Returns false when an older
6124
- * or equal update tried.
6125
- */
6126
- saveNoteDraft(draft: {
6127
- binding: number;
6128
- decision: number;
6129
- updateId: number;
6130
- messageId: string;
6131
- replyTo: string;
6132
- note: string;
6133
- }, now: Date, ttlMs?: number): boolean;
6134
- /** Move a draft between states; the caller owns the transaction story. */
6135
- setNoteDraftState(id: number, state: "pending" | "armed" | "superseded" | "consumed" | "discarded"): void;
6136
- createTelegramFlowActions(at: {
6137
- binding: number;
6138
- chatId: string;
6139
- card: number;
6140
- entry: number;
6141
- }, actions: readonly {
6142
- token: string;
6143
- action: TelegramFlowAction["action"];
6144
- }[], now: Date, days?: number): void;
6145
- getTelegramFlowAction(token: string): TelegramFlowAction | null;
6146
- placeTelegramFlowActions(tokens: readonly string[], messageId: string): void;
6147
- /** Retire every button (and prompt) for one visit of a card: it was decided, or its draft replaced. */
6148
- retireTelegramFlowVisit(card: number, entry: number, now: Date): void;
6149
- recordTelegramFlowPrompt(prompt: TelegramFlowPrompt, now: Date, hours?: number): void;
6150
- /** The live prompt a message replies to, if any. */
6151
- telegramFlowPrompt(chatId: string, messageId: string, now: Date): TelegramFlowPrompt | null;
4846
+ createTelegramAction(...args: Parameters<ChatMessages["createDecisionAction"]>): ReturnType<ChatMessages["createDecisionAction"]>;
4847
+ recordTelegramDecisionMessage(...args: Parameters<ChatMessages["recordDecisionMessage"]>): ReturnType<ChatMessages["recordDecisionMessage"]>;
4848
+ decisionForTelegramMessage(...args: Parameters<ChatMessages["decisionForMessage"]>): ReturnType<ChatMessages["decisionForMessage"]>;
4849
+ liveNoteDraft(...args: Parameters<ChatMessages["liveNoteDraft"]>): ReturnType<ChatMessages["liveNoteDraft"]>;
4850
+ saveNoteDraft(...args: Parameters<ChatMessages["saveNoteDraft"]>): ReturnType<ChatMessages["saveNoteDraft"]>;
4851
+ setNoteDraftState(...args: Parameters<ChatMessages["setNoteDraftState"]>): ReturnType<ChatMessages["setNoteDraftState"]>;
4852
+ createTelegramFlowActions(...args: Parameters<ChatMessages["createFlowActions"]>): ReturnType<ChatMessages["createFlowActions"]>;
4853
+ getTelegramFlowAction(...args: Parameters<ChatMessages["flowAction"]>): ReturnType<ChatMessages["flowAction"]>;
4854
+ placeTelegramFlowActions(...args: Parameters<ChatMessages["placeFlowActions"]>): ReturnType<ChatMessages["placeFlowActions"]>;
4855
+ retireTelegramFlowVisit(...args: Parameters<ChatMessages["retireFlowVisit"]>): ReturnType<ChatMessages["retireFlowVisit"]>;
4856
+ recordTelegramFlowPrompt(...args: Parameters<ChatMessages["recordFlowPrompt"]>): ReturnType<ChatMessages["recordFlowPrompt"]>;
4857
+ telegramFlowPrompt(...args: Parameters<ChatMessages["flowPrompt"]>): ReturnType<ChatMessages["flowPrompt"]>;
6152
4858
  /** What one visit sent: recorded once, the first time (a later pass finds it kept). */
6153
4859
  recordFlowSend(row: Omit<FlowSendRow, "createdAt">, now: Date): boolean;
6154
4860
  flowSend(card: number, entry: number): FlowSendRow | null;
6155
4861
  /** Every visit's send for a card, newest first: what the card shows it sent. */
6156
4862
  flowSends(card: number): FlowSendRow[];
6157
- createTelegramFlowChoices(at: {
6158
- binding: number;
6159
- chatId: string;
6160
- card: number;
6161
- entry: number;
6162
- }, choices: readonly {
6163
- token: string;
6164
- choice: number;
6165
- label: string;
6166
- }[], now: Date, days?: number): void;
6167
- getTelegramFlowChoice(token: string): TelegramFlowChoice | null;
6168
- placeTelegramFlowChoices(tokens: readonly string[], messageId: string): void;
6169
- /** Retire every choice button for one visit of a card (and its reply prompt): it was chosen, or the card moved on. */
4863
+ createTelegramFlowChoices(...args: Parameters<ChatMessages["createFlowChoices"]>): ReturnType<ChatMessages["createFlowChoices"]>;
4864
+ getTelegramFlowChoice(...args: Parameters<ChatMessages["flowChoice"]>): ReturnType<ChatMessages["flowChoice"]>;
4865
+ placeTelegramFlowChoices(...args: Parameters<ChatMessages["placeFlowChoices"]>): ReturnType<ChatMessages["placeFlowChoices"]>;
6170
4866
  /** A choice was made (or the card moved on): every option button, reply prompt and "Use this as your note?" for that
6171
- * visit is spent, in Telegram and in every other chat app, whichever place it was made in. */
4867
+ * visit is spent, in every chat app, whichever place it was made in. */
6172
4868
  retireFlowChoices(card: number, entry: number, now: Date): void;
6173
- createTelegramQuestionActions(at: {
6174
- binding: number;
6175
- chatId: string;
6176
- question: number;
6177
- }, choices: readonly {
6178
- token: string;
6179
- choice: string | null;
6180
- }[], now: Date, days?: number): void;
6181
- getTelegramQuestionAction(token: string): {
6182
- token: string;
6183
- binding: number;
6184
- question: number;
6185
- choice: string | null;
6186
- chatId: string;
6187
- messageId: string | null;
6188
- expiresAt: string;
6189
- consumedAt: string | null;
6190
- } | null;
6191
- placeTelegramQuestionActions(tokens: readonly string[], messageId: string): void;
6192
- /** Retire every button and prompt for a question: it was answered (anywhere). */
6193
- retireTelegramQuestion(question: number, now: Date): void;
6194
- recordTelegramQuestionPrompt(prompt: {
6195
- chatId: string;
6196
- messageId: string;
6197
- binding: number;
6198
- question: number;
6199
- }, now: Date, hours?: number): void;
6200
- telegramQuestionPrompt(chatId: string, messageId: string, now: Date): {
6201
- chatId: string;
6202
- messageId: string;
6203
- binding: number;
6204
- question: number;
6205
- } | null;
6206
- getTelegramAction(token: string): TelegramAction | null;
6207
- /**
6208
- * Kill every live confirm/cancel challenge on a decision. Cancel means
6209
- * cancelled: a confirm that survived its own cancellation would be an
6210
- * irreversible choice still armed after the person said stop.
6211
- */
6212
- consumeTelegramChallenges(decision: number, now: Date): void;
6213
- /** Consume once. False means somebody already did, or it expired — either way, no. */
6214
- consumeTelegramAction(token: string, now: Date): boolean;
6215
- /** Stamp the message a choose-action's keyboard actually landed on. */
6216
- placeTelegramActions(tokens: readonly string[], messageId: string): void;
6217
- /**
6218
- * Take or renew the bridge's poll lease. One live poller per bot: cron
4869
+ createTelegramQuestionActions(...args: Parameters<ChatMessages["createQuestionActions"]>): ReturnType<ChatMessages["createQuestionActions"]>;
4870
+ getTelegramQuestionAction(...args: Parameters<ChatMessages["questionAction"]>): ReturnType<ChatMessages["questionAction"]>;
4871
+ placeTelegramQuestionActions(...args: Parameters<ChatMessages["placeQuestionActions"]>): ReturnType<ChatMessages["placeQuestionActions"]>;
4872
+ retireTelegramQuestion(...args: Parameters<ChatMessages["retireQuestion"]>): ReturnType<ChatMessages["retireQuestion"]>;
4873
+ recordTelegramQuestionPrompt(...args: Parameters<ChatMessages["recordQuestionPrompt"]>): ReturnType<ChatMessages["recordQuestionPrompt"]>;
4874
+ telegramQuestionPrompt(...args: Parameters<ChatMessages["questionPrompt"]>): ReturnType<ChatMessages["questionPrompt"]>;
4875
+ getTelegramAction(...args: Parameters<ChatMessages["decisionAction"]>): ReturnType<ChatMessages["decisionAction"]>;
4876
+ consumeTelegramChallenges(...args: Parameters<ChatMessages["consumeChallenges"]>): ReturnType<ChatMessages["consumeChallenges"]>;
4877
+ consumeTelegramAction(...args: Parameters<ChatMessages["consumeDecisionAction"]>): ReturnType<ChatMessages["consumeDecisionAction"]>;
4878
+ placeTelegramActions(...args: Parameters<ChatMessages["placeDecisionActions"]>): ReturnType<ChatMessages["placeDecisionActions"]>;
4879
+ /**
4880
+ * Take or renew the bridge's poll lease (ChatCore.acquire). One live poller per bot: cron
6219
4881
  * overlapping a follower gets `bridge-busy`, an expired holder is taken
6220
4882
  * over at the next generation, and the cursor rides the lease so a stale
6221
4883
  * generation can neither poll nor move it.
@@ -6879,10 +5541,30 @@ export declare class Store {
6879
5541
  flowTriggerCard(trigger: number, key: string): number | null;
6880
5542
  /** The active chat trigger a channel feeds (v89), if any: one per channel. */
6881
5543
  chatTriggerFor(app: string, installation: string, chat: string): FlowTriggerRow | null;
6882
- /** Record what a trigger did with one outside thing: the card it made, or why it made none. False when it was already recorded. */
6883
- recordFlowTriggerEvent(trigger: number, key: string, card: number | null, note: string | null, now: Date): boolean;
5544
+ /**
5545
+ * Record what a trigger did with one outside thing: the card it made, or why it made none, and (a standing order's
5546
+ * firing) the task it filed. False when it was already recorded.
5547
+ */
5548
+ recordFlowTriggerEvent(trigger: number, key: string, card: number | null, note: string | null, now: Date, task?: string | null): boolean;
6884
5549
  /** The last card a trigger made, if any. */
6885
5550
  lastFlowTriggerCard(trigger: number): number | null;
5551
+ /**
5552
+ * One at a time (v115, from routines): the oldest task a standing order filed that has neither finished nor been
5553
+ * cancelled — queued, running, held, parked and failed ones all count. A live claim counts whatever the task's state
5554
+ * says, so a state written over a running build can't start a twin beside it.
5555
+ */
5556
+ standingOrderBlocker(trigger: number, routine: number | null, now: Date): {
5557
+ taskId: string;
5558
+ state: string;
5559
+ } | null;
5560
+ /**
5561
+ * What a standing order's tasks spent since `sinceIso` (v115, from routines), anchored to when each provider started:
5562
+ * a paid run whose cost never landed is counted as unmeasured, and a ceiling fails closed on it.
5563
+ */
5564
+ standingOrderSpend(trigger: number, routine: number | null, sinceIso: string): {
5565
+ costUsd: number;
5566
+ unmeasuredRuns: number;
5567
+ };
6886
5568
  /** The tools a project's builds get now (active only), oldest first. */
6887
5569
  projectTools(repo: string): {
6888
5570
  id: number;
@@ -6935,10 +5617,7 @@ export declare class Store {
6935
5617
  reason: string;
6936
5618
  }[];
6937
5619
  } | null;
6938
- /** A Telegram message this bot sent that showed one task (v79): a reply to
6939
- * it is about that task (and that result, when it showed one). A message
6940
- * edited to show something else forgets it. */
6941
- recordTelegramTaskMessage(binding: TelegramBinding, messageId: string, taskId: string | null, run: number | null, now: Date): void;
5620
+ recordTelegramTaskMessage(...args: Parameters<ChatMessages["recordTaskMessage"]>): ReturnType<ChatMessages["recordTaskMessage"]>;
6942
5621
  /** The approver's live personal threads that have messages, most recent
6943
5622
  * first — the chat list. Team conversations list themselves. */
6944
5623
  listMateThreads(approver: string, limit?: number): MateThreadSummary[];
@@ -7348,9 +6027,8 @@ export declare class Store {
7348
6027
  * built-in task ids it returned to the queue — rather than a bare count.
7349
6028
  * Nothing here decides liveness: the caller proves the runner is gone (or
7350
6029
  * is taking its name over) inside the transaction that calls this. What it
7351
- * never does: touch a run that already has an outcome, a run under a live
7352
- * held session, another runner's rows, or a task some newer live lease
7353
- * owns. A second pass over the same runner settles nothing and says so.
6030
+ * never does: touch a run that already has an outcome, another runner's
6031
+ * rows, or a task some newer live lease owns. A second pass over the same runner settles nothing and says so.
7354
6032
  */
7355
6033
  recoverRunnerWork(runner: string, now: Date): RunnerWorkRecovery;
7356
6034
  /**
@@ -7401,8 +6079,7 @@ export declare class Store {
7401
6079
  * durably with who asked and when BEFORE any process is signalled. The
7402
6080
  * transaction proves the run is this task's, is still open, holds the
7403
6081
  * task's CURRENT live claim (a reviewer's synthetic lease counts through
7404
- * its open outcome alone), is not a racing lane (tournaments keep their
7405
- * own controls), and has admitted no publication — an external request
6082
+ * its open outcome alone), and has admitted no publication — an external request
7406
6083
  * in flight is never recalled by a stop, and the words say so. The
7407
6084
  * stop's hold rides the same write, owned by this run, so nothing
7408
6085
  * automatic retries the task while it is paused; a repeated request
@@ -7419,7 +6096,7 @@ export declare class Store {
7419
6096
  repeated: boolean;
7420
6097
  } | {
7421
6098
  ok: false;
7422
- reason: "no-run" | "wrong-task" | "finished" | "not-live" | "tournament" | "publication";
6099
+ reason: "no-run" | "wrong-task" | "finished" | "not-live" | "publication";
7423
6100
  detail: string;
7424
6101
  };
7425
6102
  /** Settle a stop — compare-and-set on the unsettled row. True when THIS
@@ -7574,10 +6251,7 @@ export declare class Store {
7574
6251
  clearQuota(runner: string, provider: string, scope: string, authMode?: "subscription" | "api-key", credentialFp?: string): boolean;
7575
6252
  /**
7576
6253
  * Live claims this runner holds right now — the occupied slots of §8's
7577
- * capacity gate. A claim whose run is a HELD attended session is EXCLUDED
7578
- * (v6 W2): capacity governs unattended work; the attended bound is the
7579
- * session's own signed envelope (v28: any number of them), so watched
7580
- * conversations never freeze the runner's queue.
6254
+ * capacity gate.
7581
6255
  */
7582
6256
  liveClaimCount(runner: string, now: Date): number;
7583
6257
  /** The same live claims as liveClaimCount, by the project their task is placed in. */
@@ -7588,15 +6262,9 @@ export declare class Store {
7588
6262
  recordProjectConcurrency(by: string, repo: string, before: number, after: number, now: Date): void;
7589
6263
  /** Review 827: a project's demo URL changed (`off` when it has none). */
7590
6264
  recordProjectDemo(by: string, repo: string, before: string | null, after: string | null, now: Date): void;
7591
- /** Forward only, and only under the live generation. A stale poller moves nothing. */
7592
- /** v98: an update Telegram pushed, kept until the bridge applies it; false when it's already kept or applied. */
7593
- queueTelegramUpdate(botId: string, updateId: number, payload: string, now: Date): boolean;
7594
- /** v98: pushed updates waiting for the bridge, oldest first. */
7595
- telegramInbox(botId: string, limit: number): {
7596
- updateId: number;
7597
- payload: string;
7598
- }[];
7599
- dropTelegramInbox(updateId: number): void;
6265
+ queueTelegramUpdate(...args: Parameters<ChatMessages["queueUpdate"]>): ReturnType<ChatMessages["queueUpdate"]>;
6266
+ telegramInbox(...args: Parameters<ChatMessages["inbox"]>): ReturnType<ChatMessages["inbox"]>;
6267
+ dropTelegramInbox(...args: Parameters<ChatMessages["dropInbox"]>): ReturnType<ChatMessages["dropInbox"]>;
7600
6268
  /** v98: where Telegram pushes this bot's updates (null: the bridge asks for them), and what's wrong, if anything. */
7601
6269
  setTelegramPush(botId: string, state: {
7602
6270
  url: string | null;
@@ -7607,164 +6275,43 @@ export declare class Store {
7607
6275
  problem: string | null;
7608
6276
  at: string | null;
7609
6277
  } | null;
6278
+ /** Forward only, and only under the live generation. A stale poller moves nothing. */
7610
6279
  advanceBridgeCursor(botId: string, owner: string, generation: number, cursor: number, now: Date): boolean;
7611
- /** True if this update has not been applied before. The PRIMARY KEY is the idempotency. */
7612
- markTelegramUpdateApplied(updateId: number, result: string, now: Date): boolean;
7613
- /** Persist one ordinary message before its update is acknowledged. The caller's transaction also marks the update applied. */
7614
- enqueueTelegramConversation(row: {
7615
- binding: TelegramBinding;
7616
- updateId: number;
7617
- messageId: string;
7618
- replyTo: string | null;
7619
- request: string;
7620
- text: string;
7621
- context: string | null;
7622
- taskId: string | null;
7623
- sourceRun: number | null;
7624
- }, now: Date): number;
7625
- /** Whether a message from this chat is already waiting on, or being answered from, this bot message (a tapped question). */
7626
- telegramConversationWaitingOn(binding: number, messageId: string): boolean;
7627
- getTelegramConversation(id: number): TelegramConversation | null;
7628
- listTelegramConversations(botId: string): TelegramConversation[];
7629
- /**
7630
- * Claim the oldest message that still needs a turn: queued, or running
7631
- * under a claim that lapsed (a crash mid-turn), and not deferred past now.
7632
- * One at a time per bot — the mate runs one turn per approver anyway.
7633
- */
7634
- claimTelegramConversation(botId: string, owner: string, ttlMs: number, now: Date, only?: "turns" | "replies"): TelegramConversation | null;
7635
- /** Extend a held claim; false means it lapsed and somebody else may hold the row. */
7636
- renewTelegramConversation(id: number, owner: string, ttlMs: number, now: Date): boolean;
7637
- /**
7638
- * Bind the session a turn is about to be dispatched under, BEFORE the
7639
- * dispatch: the engine receipts the request inside that session, so a
7640
- * later attempt — after a crash, even after the session was ended and
7641
- * replaced from the console — reads the receipt where it was written
7642
- * instead of resolving today's session and finding nothing there.
7643
- */
7644
- bindTelegramConversationSession(id: number, owner: string, session: number): boolean;
7645
- /** Bind the admitted turn to its row as soon as the engine's receipt names it. */
7646
- bindTelegramConversationTurn(id: number, owner: string, session: number, turn: number): boolean;
7647
- /**
7648
- * Settle a claimed row: done or failed with its outcome word, or back to
7649
- * queued for a later attempt (a busy engine). Only the claim holder may;
7650
- * a lapsed claim settles nothing, so a reclaimer's outcome stands.
7651
- */
7652
- finishTelegramConversation(id: number, owner: string, result: {
7653
- state: "done" | "failed";
7654
- outcome: string;
7655
- replyMessageId?: string | null;
7656
- } | {
7657
- state: "queued";
7658
- outcome: string;
7659
- nextAttemptAt: string;
7660
- }, now: Date): boolean;
7661
- /**
7662
- * Replies the assistant wrote that still have not reached the person
7663
- * `since` ago or longer (status and the console show them with a Retry):
7664
- * the message's row, whose it is, when the oldest unsent part was
7665
- * written, and the last send error.
7666
- */
7667
- unsentTelegramReplies(botId: string | null, approver: string | null, since: Date): {
7668
- conversation: number;
7669
- approver: string;
7670
- since: string;
7671
- error: string | null;
7672
- }[];
7673
- /** Send unsent replies on the next bridge pass instead of waiting out their backoff; returns how many. */
7674
- retryTelegramReplies(approver: string | null, now: Date): number;
7675
- /**
7676
- * Persist the whole outbound half of a turn — every reply part and every
7677
- * card, with the cards' tokens already minted — in one transaction, BEFORE
7678
- * any send. Only the claim holder may, and only once: a row that already
7679
- * has parts keeps them (a retry resumes, never re-plans). The turn's
7680
- * identity rides the row too, so the parts answer to exactly that turn.
7681
- */
7682
- planTelegramConversationParts(id: number, owner: string, turn: {
7683
- session: number;
7684
- turn: number;
7685
- }, parts: readonly TelegramConversationPartPlan[], now: Date): boolean;
7686
- listTelegramConversationParts(conversation: number): TelegramConversationPart[];
7687
- /**
7688
- * Settle one send attempt under the row's claim. A confirmed message id
7689
- * is the only success: the part is sent, and a reply part's id becomes
7690
- * the row's reply id. Anything else leaves the part pending with its
7691
- * attempt counted, its error named, its next attempt scheduled, and —
7692
- * when the answer was lost rather than refused — its uncertainty counted.
7693
- * A lapsed claim settles nothing, so a reclaimer's outcome stands.
7694
- */
7695
- settleTelegramConversationPart(conversation: number, ordinal: number, owner: string, outcome: {
7696
- ok: true;
7697
- messageId: string;
7698
- } | {
7699
- ok: false;
7700
- error: string;
7701
- uncertain: boolean;
7702
- retryAt: string;
7703
- }, now: Date): boolean;
7704
- /** A card whose proposal no longer waits (confirmed or dismissed from another surface, or gone) is moot: dropped with the reason, never sent. */
7705
- dropTelegramConversationPart(conversation: number, ordinal: number, owner: string, reason: string, now: Date): boolean;
7706
- /** The exact task/run bindings of one outbound message this bot sent: a
7707
- * plain fact names one, a digest part may name several, (v64) a confirmed
7708
- * result image names its exact task and run, the lead's reply names the
7709
- * task its turn was about, a card names its task, and (v79) a status
7710
- * message names the task it showed. */
7711
- telegramMessageBindings(binding: TelegramBinding, messageId: string): {
7712
- taskId: string | null;
7713
- taskRef: number | null;
7714
- run: number | null;
7715
- project: string | null;
7716
- }[];
7717
- createTelegramProposalAction(action: {
7718
- token: string;
7719
- binding: number;
7720
- proposal: number;
7721
- phase: TelegramProposalAction["phase"];
7722
- chatId: string;
7723
- messageId?: string;
7724
- ttlMs?: number;
7725
- }, now: Date): void;
7726
- getTelegramProposalAction(token: string): TelegramProposalAction | null;
7727
- /** Consume once. False means somebody already did, or it expired. */
7728
- consumeTelegramProposalAction(token: string, now: Date): boolean;
7729
- /** Kill every live token on a proposal — after it resolves, or when a challenge is cancelled. */
7730
- consumeTelegramProposalActions(proposal: number, now: Date, phases?: readonly TelegramProposalAction["phase"][]): void;
7731
- /** Stamp the message a card's keyboard actually landed on. */
7732
- placeTelegramProposalActions(tokens: readonly string[], messageId: string): void;
7733
- telegramDestination(binding: TelegramBinding): string;
7734
- /** A progress card belongs to one builder result, including its root review.
7735
- * Do not combine planners, correction children, or separate build attempts. */
7736
- telegramProgressRun(row: Pick<Notification, "taskRef" | "run">): Run | null;
7737
- /** Reuse a confirmed message in this exact destination. A mixed digest,
7738
- * decision, image, or message naming another attempt is never editable. The
7739
- * outbound history survives a restart even if the final receipt was lost. */
7740
- telegramProgressMessage(binding: TelegramBinding, result: Run): string | null;
7741
- /** The existing outbox, with a separate receipt for this exact pairing. */
7742
- claimTelegramDeliveries(binding: TelegramBinding, owner: string, ttlMs: number, now: Date, only?: "all" | "urgent"): TelegramDelivery[];
6280
+ markTelegramUpdateApplied(...args: Parameters<ChatMessages["markUpdateApplied"]>): ReturnType<ChatMessages["markUpdateApplied"]>;
6281
+ enqueueTelegramConversation(...args: Parameters<ChatMessages["enqueueMessage"]>): ReturnType<ChatMessages["enqueueMessage"]>;
6282
+ telegramConversationWaitingOn(...args: Parameters<ChatMessages["messageWaitingOn"]>): ReturnType<ChatMessages["messageWaitingOn"]>;
6283
+ getTelegramConversation(...args: Parameters<ChatMessages["getMessage"]>): ReturnType<ChatMessages["getMessage"]>;
6284
+ listTelegramConversations(...args: Parameters<ChatMessages["listMessages"]>): ReturnType<ChatMessages["listMessages"]>;
6285
+ claimTelegramConversation(...args: Parameters<ChatMessages["claimMessage"]>): ReturnType<ChatMessages["claimMessage"]>;
6286
+ renewTelegramConversation(...args: Parameters<ChatMessages["renewMessage"]>): ReturnType<ChatMessages["renewMessage"]>;
6287
+ bindTelegramConversationSession(...args: Parameters<ChatMessages["bindMessageSession"]>): ReturnType<ChatMessages["bindMessageSession"]>;
6288
+ bindTelegramConversationTurn(...args: Parameters<ChatMessages["bindMessageTurn"]>): ReturnType<ChatMessages["bindMessageTurn"]>;
6289
+ finishTelegramConversation(...args: Parameters<ChatMessages["finishMessage"]>): ReturnType<ChatMessages["finishMessage"]>;
6290
+ unsentTelegramReplies(...args: Parameters<ChatMessages["unsentReplies"]>): ReturnType<ChatMessages["unsentReplies"]>;
6291
+ retryTelegramReplies(...args: Parameters<ChatMessages["retryReplies"]>): ReturnType<ChatMessages["retryReplies"]>;
6292
+ planTelegramConversationParts(...args: Parameters<ChatMessages["planReplyParts"]>): ReturnType<ChatMessages["planReplyParts"]>;
6293
+ listTelegramConversationParts(...args: Parameters<ChatMessages["replyParts"]>): ReturnType<ChatMessages["replyParts"]>;
6294
+ settleTelegramConversationPart(...args: Parameters<ChatMessages["settleReplyPart"]>): ReturnType<ChatMessages["settleReplyPart"]>;
6295
+ dropTelegramConversationPart(...args: Parameters<ChatMessages["dropReplyPart"]>): ReturnType<ChatMessages["dropReplyPart"]>;
6296
+ telegramMessageBindings(...args: Parameters<ChatMessages["messageBindings"]>): ReturnType<ChatMessages["messageBindings"]>;
6297
+ createTelegramProposalAction(...args: Parameters<ChatMessages["createProposalAction"]>): ReturnType<ChatMessages["createProposalAction"]>;
6298
+ getTelegramProposalAction(...args: Parameters<ChatMessages["proposalAction"]>): ReturnType<ChatMessages["proposalAction"]>;
6299
+ consumeTelegramProposalAction(...args: Parameters<ChatMessages["consumeProposalAction"]>): ReturnType<ChatMessages["consumeProposalAction"]>;
6300
+ consumeTelegramProposalActions(...args: Parameters<ChatMessages["consumeProposalActions"]>): ReturnType<ChatMessages["consumeProposalActions"]>;
6301
+ placeTelegramProposalActions(...args: Parameters<ChatMessages["placeProposalActions"]>): ReturnType<ChatMessages["placeProposalActions"]>;
6302
+ telegramDestination(...args: Parameters<ChatMessages["destination"]>): ReturnType<ChatMessages["destination"]>;
6303
+ telegramProgressRun(...args: Parameters<ChatMessages["progressRun"]>): ReturnType<ChatMessages["progressRun"]>;
6304
+ telegramProgressMessage(...args: Parameters<ChatMessages["progressMessage"]>): ReturnType<ChatMessages["progressMessage"]>;
6305
+ claimTelegramDeliveries(...args: Parameters<ChatMessages["claimDeliveries"]>): ReturnType<ChatMessages["claimDeliveries"]>;
7743
6306
  telegramRetryAt(botId: string): string;
7744
6307
  deferTelegram(botId: string, until: string): void;
7745
- /** Synchronous final fence, called AFTER each asynchronous enrollment read. */
7746
- telegramDeliveryProblem(row: TelegramDelivery, binding: TelegramBinding, owner: string, projects: readonly string[], now: Date, batch?: readonly number[]): string | null;
7747
- private telegramClaimHeld;
7748
- /** A confirmed network message remains history even if authority changed
7749
- * while it was in flight. It only binds the OLD destination, never new work. */
7750
- recordTelegramMessage(row: TelegramDelivery, binding: TelegramBinding, messageId: string, now: Date): void;
7751
- /** The newest confirmed message this notification became at one destination, if any. */
7752
- telegramMessageOf(notification: number, destination: string): string | null;
7753
- finalizeTelegramDelivery(row: TelegramDelivery, binding: TelegramBinding, owner: string, outcome: {
7754
- ok: true;
7755
- receipt: string | null;
7756
- } | {
7757
- ok: false;
7758
- error: string;
7759
- retryAt?: string;
7760
- }, now: Date): boolean;
7761
- /** The notifications this pairing holds, each with its delivery state there. */
7762
- telegramDeliveries(binding: TelegramBinding): NotificationReceipt[];
7763
- /** The digest cadence: null everyMs = off. */
7764
- telegramDigest(): TelegramDigest;
7765
- /** Set (or clear, with null) the cadence. Turning it on starts the
7766
- * window NOW — nothing held before the choice is dumped at once. */
7767
- setTelegramDigest(everyMs: number | null, by: string, now: Date): void;
6308
+ telegramDeliveryProblem(...args: Parameters<ChatMessages["deliveryProblem"]>): ReturnType<ChatMessages["deliveryProblem"]>;
6309
+ recordTelegramMessage(...args: Parameters<ChatMessages["recordMessage"]>): ReturnType<ChatMessages["recordMessage"]>;
6310
+ telegramMessageOf(...args: Parameters<ChatMessages["messageOf"]>): ReturnType<ChatMessages["messageOf"]>;
6311
+ finalizeTelegramDelivery(...args: Parameters<ChatMessages["finalizeDelivery"]>): ReturnType<ChatMessages["finalizeDelivery"]>;
6312
+ telegramDeliveries(...args: Parameters<ChatMessages["deliveries"]>): ReturnType<ChatMessages["deliveries"]>;
6313
+ telegramDigest(...args: Parameters<ChatMessages["digest"]>): ReturnType<ChatMessages["digest"]>;
6314
+ setTelegramDigest(...args: Parameters<ChatMessages["setDigest"]>): ReturnType<ChatMessages["setDigest"]>;
7768
6315
  /** How chats reach this person: only when they are needed unless they chose every step. */
7769
6316
  notificationPreference(account: string): NotificationPreference;
7770
6317
  /** Change one person's choice; a digest time is a local HH:MM, or null for no evening digest. */
@@ -7881,7 +6428,7 @@ export declare class Store {
7881
6428
  chatBatchMessageFor(destination: string, taskRef: number, run: number): string | null;
7882
6429
  /** The message now showing this card, and what it shows. */
7883
6430
  setChatCardMessage(id: number, message: string, digest: string): void;
7884
- markTelegramDigestSent(now: Date): void;
6431
+ markTelegramDigestSent(...args: Parameters<ChatMessages["markDigestSent"]>): ReturnType<ChatMessages["markDigestSent"]>;
7885
6432
  /** Routine rows waiting for the next digest: pending, and not urgent.
7886
6433
  * A row the live pairing delivered, or skipped as pre-pairing history,
7887
6434
  * is settled and not waiting. */
@@ -8006,42 +6553,10 @@ export declare class Store {
8006
6553
  * explicit skip, with no delivered timestamp and no attempt, so suppressed
8007
6554
  * history is never reported as a send that happened. */
8008
6555
  export declare const TELEGRAM_SKIPPED_RECEIPT = "skipped:before-pairing";
8009
- /** v83: a notification for another person, settled for this destination without sending. */
8010
- export declare const TELEGRAM_SKIPPED_ELSEWHERE = "skipped:for-another-person";
8011
- /** A met promise the lead made on another chat: reported there, settled here without sending. */
8012
- export declare const TELEGRAM_SKIPPED_OTHER_CHAT = "skipped:for-another-chat";
8013
- /** A fact this person is not messaged about: the lead's work, their own act, or a project they muted. */
8014
- export declare const TELEGRAM_SKIPPED_QUIET = "skipped:quiet";
8015
- /**
8016
- * Why the store itself holds a Telegram delivery back: authority,
8017
- * provenance, ordering, a switched-off channel, or a wait it imposed. A
8018
- * row held for one of these is waiting on policy, not failing on the wire.
8019
- * Every other error recorded on a receipt came from an actual send, and
8020
- * THAT is delivery trouble (`pendingForAttention`). One table, so the
8021
- * fences and the tally can never disagree about the words.
8022
- */
8023
- export declare const TELEGRAM_HOLD_REASONS: Readonly<{
8024
- authority: "Telegram pairing or actor authorization changed";
8025
- destination: "Telegram destination changed";
8026
- claim: "Telegram delivery claim expired or changed";
8027
- rateLimit: "Telegram rate limit is still active";
8028
- resolved: "Notification no longer needs delivery";
8029
- provenance: "Notification has no trusted project provenance";
8030
- installation: "Installation notification requires instance access";
8031
- project: "Notification project is not currently authorized and enrolled";
8032
- task: "Notification task provenance changed";
8033
- order: "Earlier task notification is still undelivered";
8034
- disabled: "Telegram delivery is disabled";
8035
- }>;
8036
- /**
8037
- * Why a contest lane cannot present or accept authority (final authority
8038
- * closure), or null when it can: the lane must be nonterminal, carry a
8039
- * readable stored profile, and that profile's provider, model, and
8040
- * effective repair model must BE the lane's own columns. A profile_json
8041
- * copied from another agent beside stale provider/model columns is a row
8042
- * two authorities wrote; nothing spends on it.
8043
- */
8044
- export declare function laneAuthorityProblem(lane: Contestant): string | null;
6556
+ export { TELEGRAM_HOLD_REASONS, TELEGRAM_SKIPPED_ELSEWHERE, TELEGRAM_SKIPPED_OTHER_CHAT, TELEGRAM_SKIPPED_QUIET };
6557
+ export { isLifecycleNotification, isTelegramProgressNotification, LIFECYCLE_KEY_PREFIX, LIFECYCLE_KINDS, proposalTaskOf, type LifecycleKind };
6558
+ /** A Telegram pairing, in the Telegram adapter's names: the bot is the installation, the user the member, the private chat the channel. */
6559
+ export declare function telegramBindingOf(binding: ChatBinding): TelegramBinding;
8045
6560
  export type WorktreeRow = {
8046
6561
  path: string;
8047
6562
  repo: string;
@@ -8074,16 +6589,6 @@ export type IntakeGrant = {
8074
6589
  revokedBy: string | null;
8075
6590
  };
8076
6591
  /** A review comment bound to the exact bytes of an immutable terminal diff. */
8077
- export type FallbackCycle = {
8078
- id: number;
8079
- taskRef: number;
8080
- chainDigest: string;
8081
- cursor: number;
8082
- state: "open" | "sanitizing" | "awaiting-release" | "pending-admission" | "incident" | "closed";
8083
- transitionGeneration: number;
8084
- tailRun: number | null;
8085
- closedReason: string | null;
8086
- };
8087
6592
  export type DiffComment = {
8088
6593
  id: number;
8089
6594
  artifact: number;
@@ -8192,21 +6697,19 @@ export type RevisionRefusal = "busy" | "source-task" | "source-run" | "stale-sou
8192
6697
  * INHERITED, verbatim, from the source (declared requirements and
8193
6698
  * constraints — never the installation's defaults of the day):
8194
6699
  * goal (the child appends its explicitly described repair), exclusions,
8195
- * touches, the exact rubric, declared risk (never below the source's
8196
- * signed level or its durable task choice), quality mode (strict stays
6700
+ * touches, the exact rubric, quality mode (strict stays
8197
6701
  * strict), permission posture (the source's durable choice, else the
8198
6702
  * posture its sealed profile ran under — never wider), the per-attempt
8199
6703
  * budget ceiling (never lifted; a mode's filing default may only
8200
6704
  * tighten it), the approver's per-phase route overrides, and the
8201
6705
  * build/plan agent pins.
8202
6706
  * RE-RESOLVED at filing, then approved afresh: the phase route and its
8203
- * execution profile (recommended over the inherited risk, quality,
8204
- * overrides, and pins under today's configuration), the fallback
8205
- * chain (from the repository's configuration, never copied), and the
6707
+ * execution profile (recommended over the inherited quality,
6708
+ * overrides, and pins under today's configuration), and the
8206
6709
  * auth mode. The child's digest binds what it resolved to; a yes on
8207
6710
  * the source never covers it.
8208
- * NEVER INHERITED: the approval stamp and its basis, attended
8209
- * authorizations, publication and merge grants, the plan document and
6711
+ * NEVER INHERITED: the approval stamp and its basis,
6712
+ * publication and merge grants, the plan document and
8210
6713
  * its revision ledger (a revision is planned afresh, if at all; the
8211
6714
  * brief plus the source scope are its contract), strikes, holds.
8212
6715
  * FRESH from a live mode, only when the caller re-proved coverage inside
@@ -8221,7 +6724,6 @@ export type RevisionTerms = {
8221
6724
  outOfScope: string | null;
8222
6725
  touches: string[];
8223
6726
  acceptance: AcceptanceCriterion[];
8224
- riskLevel: RiskLevel;
8225
6727
  qualityMode: QualityMode;
8226
6728
  permissionMode: UnattendedPermissionMode;
8227
6729
  budgetMicrousd: number | null;
@@ -8240,7 +6742,7 @@ export type RevisionTerms = {
8240
6742
  };
8241
6743
  /** The operator-facing posture a sealed profile actually ran under. */
8242
6744
  export declare function permissionModeOfProfile(profile: ExecutionProfile | null): UnattendedPermissionMode | null;
8243
- export declare function revisionTermsOf(sourceRef: Pick<TaskRef, "riskLevel" | "qualityMode" | "permissionMode" | "routeOverrides" | "agentProvider" | "agentModel" | "planProvider" | "planModel">, sourceScope: Scope | null, coverage: {
6745
+ export declare function revisionTermsOf(sourceRef: Pick<TaskRef, "qualityMode" | "permissionMode" | "routeOverrides" | "agentProvider" | "agentModel" | "planProvider" | "planModel">, sourceScope: Scope | null, coverage: {
8244
6746
  defaultBudgetMicrousd: number | null;
8245
6747
  escalated: boolean;
8246
6748
  } | null, permissionDefault: UnattendedPermissionMode, qualityDefault: QualityMode): RevisionTerms;
@@ -8264,7 +6766,6 @@ export type RevisionLineage = {
8264
6766
  ancestors: string[];
8265
6767
  root: string;
8266
6768
  terms: {
8267
- riskLevel: RiskLevel;
8268
6769
  qualityMode: QualityMode;
8269
6770
  permissionMode: UnattendedPermissionMode;
8270
6771
  budgetMicrousd: number | null;
@@ -8305,9 +6806,6 @@ export type ProofAcceptanceRow = {
8305
6806
  note: string | null;
8306
6807
  acceptedAt: string;
8307
6808
  };
8308
- /** A contestant's execution profile (v24): exact ids from the race terms,
8309
- * effective limits from the same constants every dispatch uses. */
8310
- export declare function contestantProfileOf(provider: string, model: string, repairModel: string, permissionMode?: UnattendedPermissionMode): ExecutionProfile;
8311
6809
  /**
8312
6810
  * The raw terms verdict for one stored scope row (raw authority repair):
8313
6811
  * every term the digest binds and every metadata word an authority reads,