@farmslot/protocol 0.20.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/dist/contracts/agents.d.ts +18 -0
  3. package/dist/contracts/agents.d.ts.map +1 -1
  4. package/dist/contracts/backlog.d.ts +8 -0
  5. package/dist/contracts/backlog.d.ts.map +1 -1
  6. package/dist/contracts/backlog.js.map +1 -1
  7. package/dist/contracts/chat.d.ts +6 -1
  8. package/dist/contracts/chat.d.ts.map +1 -1
  9. package/dist/contracts/chat.js.map +1 -1
  10. package/dist/contracts/config.d.ts +9 -2
  11. package/dist/contracts/config.d.ts.map +1 -1
  12. package/dist/contracts/config.js.map +1 -1
  13. package/dist/contracts/device-inventory.d.ts +118 -0
  14. package/dist/contracts/device-inventory.d.ts.map +1 -0
  15. package/dist/contracts/device-inventory.js +51 -0
  16. package/dist/contracts/device-inventory.js.map +1 -0
  17. package/dist/contracts/dispatch.d.ts +2 -0
  18. package/dist/contracts/dispatch.d.ts.map +1 -1
  19. package/dist/contracts/execution-templates.d.ts +10 -0
  20. package/dist/contracts/execution-templates.d.ts.map +1 -1
  21. package/dist/contracts/gate-park.d.ts +284 -0
  22. package/dist/contracts/gate-park.d.ts.map +1 -0
  23. package/dist/contracts/gate-park.js +415 -0
  24. package/dist/contracts/gate-park.js.map +1 -0
  25. package/dist/contracts/index.d.ts +5 -0
  26. package/dist/contracts/index.d.ts.map +1 -1
  27. package/dist/contracts/index.js +5 -0
  28. package/dist/contracts/index.js.map +1 -1
  29. package/dist/contracts/pressure-admission.d.ts +175 -0
  30. package/dist/contracts/pressure-admission.d.ts.map +1 -0
  31. package/dist/contracts/pressure-admission.js +26 -0
  32. package/dist/contracts/pressure-admission.js.map +1 -0
  33. package/dist/contracts/resource-posture.d.ts +379 -0
  34. package/dist/contracts/resource-posture.d.ts.map +1 -0
  35. package/dist/contracts/resource-posture.js +293 -0
  36. package/dist/contracts/resource-posture.js.map +1 -0
  37. package/dist/contracts/resources.d.ts +27 -1
  38. package/dist/contracts/resources.d.ts.map +1 -1
  39. package/dist/contracts/resources.js +1 -1
  40. package/dist/contracts/resources.js.map +1 -1
  41. package/dist/contracts/reviews.d.ts +2 -0
  42. package/dist/contracts/reviews.d.ts.map +1 -1
  43. package/dist/contracts/reviews.js.map +1 -1
  44. package/dist/contracts/runs.d.ts +521 -6
  45. package/dist/contracts/runs.d.ts.map +1 -1
  46. package/dist/contracts/runs.js +131 -2
  47. package/dist/contracts/runs.js.map +1 -1
  48. package/dist/contracts/runtime-capabilities.d.ts +386 -0
  49. package/dist/contracts/runtime-capabilities.d.ts.map +1 -0
  50. package/dist/contracts/runtime-capabilities.js +114 -0
  51. package/dist/contracts/runtime-capabilities.js.map +1 -0
  52. package/dist/contracts/slots.d.ts +53 -1
  53. package/dist/contracts/slots.d.ts.map +1 -1
  54. package/dist/recipes/step-io.d.ts +10 -1
  55. package/dist/recipes/step-io.d.ts.map +1 -1
  56. package/dist/rpc/chat.d.ts +2 -0
  57. package/dist/rpc/chat.d.ts.map +1 -1
  58. package/dist/rpc/config.d.ts +9 -1
  59. package/dist/rpc/config.d.ts.map +1 -1
  60. package/dist/rpc/copilot-runtime.d.ts +131 -0
  61. package/dist/rpc/copilot-runtime.d.ts.map +1 -0
  62. package/dist/rpc/copilot-runtime.js +12 -0
  63. package/dist/rpc/copilot-runtime.js.map +1 -0
  64. package/dist/rpc/dispatch.d.ts +39 -1
  65. package/dist/rpc/dispatch.d.ts.map +1 -1
  66. package/dist/rpc/dispatch.js +2 -0
  67. package/dist/rpc/dispatch.js.map +1 -1
  68. package/dist/rpc/git.d.ts +40 -0
  69. package/dist/rpc/git.d.ts.map +1 -1
  70. package/dist/rpc/index.d.ts +5 -0
  71. package/dist/rpc/index.d.ts.map +1 -1
  72. package/dist/rpc/index.js +5 -0
  73. package/dist/rpc/index.js.map +1 -1
  74. package/dist/rpc/machine-pause.d.ts +158 -0
  75. package/dist/rpc/machine-pause.d.ts.map +1 -0
  76. package/dist/rpc/machine-pause.js +8 -0
  77. package/dist/rpc/machine-pause.js.map +1 -0
  78. package/dist/rpc/pr.d.ts +2 -0
  79. package/dist/rpc/pr.d.ts.map +1 -1
  80. package/dist/rpc/registry.d.ts +23 -0
  81. package/dist/rpc/registry.d.ts.map +1 -1
  82. package/dist/rpc/registry.js +25 -0
  83. package/dist/rpc/registry.js.map +1 -1
  84. package/dist/rpc/resource-posture.d.ts +36 -0
  85. package/dist/rpc/resource-posture.d.ts.map +1 -0
  86. package/dist/rpc/resource-posture.js +7 -0
  87. package/dist/rpc/resource-posture.js.map +1 -0
  88. package/dist/rpc/resource-pressure-selection.d.ts +4 -0
  89. package/dist/rpc/resource-pressure-selection.d.ts.map +1 -0
  90. package/dist/rpc/resource-pressure-selection.js +21 -0
  91. package/dist/rpc/resource-pressure-selection.js.map +1 -0
  92. package/dist/rpc/resources.d.ts +176 -1
  93. package/dist/rpc/resources.d.ts.map +1 -1
  94. package/dist/rpc/resources.js +6 -0
  95. package/dist/rpc/resources.js.map +1 -1
  96. package/dist/rpc/run.d.ts +122 -5
  97. package/dist/rpc/run.d.ts.map +1 -1
  98. package/dist/rpc/run.js +1 -0
  99. package/dist/rpc/run.js.map +1 -1
  100. package/dist/rpc/runtime-capabilities.d.ts +136 -0
  101. package/dist/rpc/runtime-capabilities.d.ts.map +1 -0
  102. package/dist/rpc/runtime-capabilities.js +19 -0
  103. package/dist/rpc/runtime-capabilities.js.map +1 -0
  104. package/dist/rpc/slot.d.ts +9 -1
  105. package/dist/rpc/slot.d.ts.map +1 -1
  106. package/dist/rpc/slot.js.map +1 -1
  107. package/dist/rpc/tmux.d.ts +4 -0
  108. package/dist/rpc/tmux.d.ts.map +1 -1
  109. package/dist/runs/decision-resolution.d.ts +7 -0
  110. package/dist/runs/decision-resolution.d.ts.map +1 -1
  111. package/dist/runs/decision-resolution.js +1 -0
  112. package/dist/runs/decision-resolution.js.map +1 -1
  113. package/dist/slots/tracking-branch.d.ts +12 -0
  114. package/dist/slots/tracking-branch.d.ts.map +1 -1
  115. package/dist/slots/tracking-branch.js +12 -0
  116. package/dist/slots/tracking-branch.js.map +1 -1
  117. package/dist/transport/events.d.ts +12 -1
  118. package/dist/transport/events.d.ts.map +1 -1
  119. package/dist/transport/events.js +4 -0
  120. package/dist/transport/events.js.map +1 -1
  121. package/dist/transport/signal.d.ts +13 -0
  122. package/dist/transport/signal.d.ts.map +1 -1
  123. package/dist/transport/signal.js +19 -1
  124. package/dist/transport/signal.js.map +1 -1
  125. package/dist/version.d.ts +1 -1
  126. package/dist/version.js +1 -1
  127. package/package.json +6 -1
@@ -1,14 +1,18 @@
1
1
  import type { ArtifactRef, SelfReviewIssue } from '../recipes/step-io.js';
2
2
  import type { WorkerSignalChecklistEvent, WorkerSignalChecklistTiming } from '../transport/signal.js';
3
- import type { AgentContext, SafetyTier, ScriptedRunnerConfig } from './agents.js';
3
+ import type { AgentContext, AgentContextTarget, SafetyTier, ScriptedRunnerConfig } from './agents.js';
4
4
  import type { FailureCategory, RunRecoveryProposalConfidence } from './chat.js';
5
5
  import type { TaskTemplateSelection, TemplateProvenance } from './evals.js';
6
6
  import type { EvidenceQualityReport, RecipeQualityArtifact } from './recipes.js';
7
+ import type { ResourcePostureWaitPolicy, RunResourcePostureState } from './resource-posture.js';
8
+ import type { ResourceType } from './resources.js';
7
9
  import type { RunImportProvenance } from './run-bundles.js';
10
+ import type { RuntimeCapabilityProofRequirement } from './runtime-capabilities.js';
8
11
  import type { SlotHealth } from './slots.js';
9
12
  import type { ProfileFitSuggestion, ValidationPlanStep } from './validation-plan.js';
10
13
  export type RunStatus = 'created' | 'grading' | 'writing-task' | 'slot-finding' | 'preparing' | 'dispatching' | 'monitoring' | 'self-reviewing' | 'completing' | 'human-gating' | 'ci-watching' | 'paused' | 'done' | 'blocked' | 'failed' | 'cancelled';
11
14
  export declare const TERMINAL_RUN_STATUSES: readonly RunStatus[];
15
+ export declare const ACTIVE_RUN_STATUSES: readonly RunStatus[];
12
16
  export declare function isTerminalRunStatus(status: RunStatus): boolean;
13
17
  /**
14
18
  * Runs eligible for activate-on-slot re-bind (ADR-024 §7 addendum): terminal
@@ -94,7 +98,10 @@ export type PublicationStatus = 'not_published' | 'pending_publish' | 'published
94
98
  export interface ReviewDepthPolicy {
95
99
  minimumIndependentReviews: number;
96
100
  requireCrossRunner: boolean;
101
+ /** Independent review loops required beyond `minimumIndependentReviews`. */
97
102
  extraLoopsRequested: number;
103
+ /** V2 counts the first configured loop in the minimum, not again as an extra. */
104
+ countingVersion?: 2;
98
105
  requestedBy: 'dispatch' | 'human-gate' | 'agent-gate';
99
106
  }
100
107
  /**
@@ -254,9 +261,13 @@ export interface IndependentReviewAttempt {
254
261
  loopNumber: number;
255
262
  verdict: 'pending' | 'pass' | 'issues' | 'failed' | 'cancelled' | 'skipped';
256
263
  unresolvedCount: number;
264
+ /** Transport/lifecycle explanation when a review did not complete normally. */
265
+ reason?: string;
257
266
  issues?: SelfReviewIssue[];
258
267
  validationDepth?: ReviewValidationDepth;
259
268
  usage?: RunnerSessionUsage;
269
+ /** Checklist marks and timings captured from this review round's role-scoped signal. */
270
+ checklistTiming?: WorkerSignalChecklistTiming;
260
271
  reviewSnapshot?: ReviewDiffSnapshot;
261
272
  fixDelta?: ReviewFixDeltaSnapshot;
262
273
  artifactPaths?: string[];
@@ -275,6 +286,8 @@ export interface IndependentReviewStatus {
275
286
  loopNumber: number;
276
287
  verdict: 'pending' | 'pass' | 'issues' | 'failed' | 'cancelled' | 'skipped';
277
288
  unresolvedCount: number;
289
+ /** Transport/lifecycle explanation when a review did not complete normally. */
290
+ reason?: string;
278
291
  issues?: SelfReviewIssue[];
279
292
  validationDepth?: ReviewValidationDepth;
280
293
  usage?: RunnerSessionUsage;
@@ -1028,11 +1041,82 @@ export declare function buildComparisonVariant(runner: string | null | undefined
1028
1041
  export declare function nextFreeComparisonVariant(familyRuns: ReadonlyArray<{
1029
1042
  variant?: string | null;
1030
1043
  }>, runner: string | null | undefined, model: string | null | undefined): string;
1044
+ /** Incremental/cached session-usage sample for soft turn/token budgets. */
1045
+ export interface RunMonitorBudgetUsageState {
1046
+ path: string | null;
1047
+ size: number;
1048
+ mtimeMs: number;
1049
+ offset: number;
1050
+ turns: number;
1051
+ totalTokens: number;
1052
+ inputTokens: number;
1053
+ outputTokens: number;
1054
+ cacheCreation: number;
1055
+ cacheRead: number;
1056
+ sampledAt?: string;
1057
+ unavailableReason?: string;
1058
+ /** Persistent fail-closed reason when bounded parsing loses accounting integrity. */
1059
+ integrityFailureReason?: string;
1060
+ /** True while advancing past a record larger than the bounded read window. */
1061
+ skippingOversizedRecord?: boolean;
1062
+ /** Count of records skipped for exceeding the window (their usage is uncounted). */
1063
+ skippedOversizedRecords?: number;
1064
+ /**
1065
+ * Last session-total reading for runners that restate totals rather than reporting
1066
+ * per-record usage (codex). Zeros mean counting from the start of the transcript;
1067
+ * absent means counting started at a byte offset, so the next reading only sets the
1068
+ * reference.
1069
+ */
1070
+ lastCumulative?: {
1071
+ input: number;
1072
+ output: number;
1073
+ cacheRead: number;
1074
+ total: number;
1075
+ };
1076
+ /** Discard the next complete record: it is the previous writer's in-flight record. */
1077
+ discardNextRecord?: boolean;
1078
+ /** Filesystem identity of the counted transcript; path equality is not identity. */
1079
+ fileId?: string;
1080
+ /**
1081
+ * True once counting has been deliberately anchored at a byte offset (a warm-handoff
1082
+ * pin). Providers report increments, so there is no total to subtract.
1083
+ */
1084
+ baselineCaptured?: boolean;
1085
+ /** Legacy: parent totals the pre-increment guard subtracted. Migrated on restore. */
1086
+ baselineTurns?: number;
1087
+ baselineTotalTokens?: number;
1088
+ }
1089
+ /** Persisted form of the budget guard's delivery state machine. */
1090
+ export interface RunBudgetDeliveryState {
1091
+ phase: 'ok' | 'breach-pending' | 'delivered' | 'abandoned' | 'unenforceable';
1092
+ pendingMessage: string | null;
1093
+ operatorMessage: string | null;
1094
+ attempts: number;
1095
+ firstHeldAt?: number;
1096
+ }
1031
1097
  export interface RunMonitorState {
1032
1098
  nudgeCount: number;
1033
1099
  lastPollAt: string;
1034
1100
  startedAt: string;
1035
1101
  lastPaneHash?: string;
1102
+ /** ISO time of last structured runner progress; used to restore stuck clocks. */
1103
+ lastStructuredProgressAt?: string;
1104
+ /** True after a one-shot usage-budget warning was emitted for this monitor session. */
1105
+ budgetWarned?: boolean;
1106
+ /** True after a budget nudge was confirmed delivered (may retry while false). */
1107
+ budgetNudgeSent?: boolean;
1108
+ /**
1109
+ * Delivery attempts made for the budget nudge. Retries stop at
1110
+ * MAX_BUDGET_NUDGE_ATTEMPTS so an unconfirmable pane cannot accumulate copies
1111
+ * of the warning in the runner composer.
1112
+ */
1113
+ budgetNudgeAttempts?: number;
1114
+ /** Epoch ms of the first mid-turn deferral of a pending budget warning. */
1115
+ budgetFirstDeferredAt?: number;
1116
+ /** The budget guard's delivery state. Supersedes the flags below. */
1117
+ budgetDelivery?: RunBudgetDeliveryState;
1118
+ /** Append-only transcript sample cache for the soft budget guard. */
1119
+ budgetUsage?: RunMonitorBudgetUsageState;
1036
1120
  }
1037
1121
  export interface RunLink {
1038
1122
  label: string;
@@ -1126,6 +1210,411 @@ export declare function normalizeRunTags(values: readonly string[] | undefined |
1126
1210
  */
1127
1211
  export declare const DOMAIN_NAME_RE: RegExp;
1128
1212
  export declare function isValidDomainName(value: string): boolean;
1213
+ export type MachinePauseMode = 'orchestration' | 'release';
1214
+ /** Durable checkpoints used to resume an interrupted park/restore operation. */
1215
+ export type MachineParkPhase = 'intent-persisted' | 'orchestration-pausing' | 'orchestration-paused' | 'runner-stopping' | 'runner-stopped' | 'resources-stopping' | 'parked' | 'resources-restoring' | 'runner-reloading' | 'orchestration-resuming' | 'restored' | 'cancelling' | 'partial' | 'failed' | 'cancelled';
1216
+ export type MachineParkResourcePhase = 'observed-running' | 'stopping' | 'stopped'
1217
+ /** Left running on purpose because the catalog says releasing never stops it, and verified still running at settle. */
1218
+ | 'retained' | 'restoring' | 'restored' | 'failed';
1219
+ export type MachineParkCapabilityLeaseState = 'held' | 'releasing' | 'released' | 'reacquiring' | 'reacquired' | 'failed';
1220
+ export interface MachineParkCapabilityLease {
1221
+ leaseId: string;
1222
+ /** Lease created when restore reacquires this capability; differs from the released lease id. */
1223
+ restoredLeaseId?: string;
1224
+ capabilityId: string;
1225
+ state: MachineParkCapabilityLeaseState;
1226
+ parameters: Record<string, unknown>;
1227
+ proofRequirement: RuntimeCapabilityProofRequirement;
1228
+ ownerFamilyId?: string;
1229
+ /** Optional provider-resource association; leases remain first-class manifest entries. */
1230
+ resourceId?: string;
1231
+ error?: string;
1232
+ }
1233
+ /** Parking's factual disposition for one manifest resource. */
1234
+ export type MachineParkResourceReleaseEffect = 'stop' | 'retain';
1235
+ /** One resource that was observed running when release-pause intent was captured. */
1236
+ export interface MachineParkResource {
1237
+ resourceId: string;
1238
+ label: string;
1239
+ type: ResourceType;
1240
+ observedStatus: 'running';
1241
+ phase: MachineParkResourcePhase;
1242
+ /**
1243
+ * What parking does to this resource, resolved from the project catalog's
1244
+ * affected-resource metadata. `stop` shuts it down and restore boots it back;
1245
+ * `retain` leaves it running and restore only verifies it never stopped.
1246
+ * Absent on records journalled before the metadata existed; read it as `stop`.
1247
+ */
1248
+ releaseEffect?: MachineParkResourceReleaseEffect;
1249
+ capabilityLeaseIds: string[];
1250
+ stoppedAt?: string;
1251
+ restoredAt?: string;
1252
+ error?: string;
1253
+ }
1254
+ /** What restore did to one resource, emitted by the code path that did it. */
1255
+ export type MachineParkRestoreAction = 'verified' | 'booted' | 'stopped' | 'skipped';
1256
+ /**
1257
+ * One lifecycle effect a restore performed, recorded as fact rather than
1258
+ * inferred from the absence of an error. A successful boot leaves no error
1259
+ * behind, so "no boot error" can never prove no boot happened; this can.
1260
+ */
1261
+ export interface MachineParkRestoreEffect {
1262
+ resourceId: string;
1263
+ action: MachineParkRestoreAction;
1264
+ /** Gateway clock, when the effect was performed or observed. */
1265
+ at: string;
1266
+ /** False when the action failed, or when it happened and should not have. */
1267
+ ok: boolean;
1268
+ reason?: string;
1269
+ }
1270
+ export interface MachineParkResourceManifest {
1271
+ capturedAt: string;
1272
+ resources: MachineParkResource[];
1273
+ capabilityLeases: MachineParkCapabilityLease[];
1274
+ }
1275
+ /** Exact persisted runner identity required to restore a released worker. */
1276
+ export interface MachinePauseRecoveryHandle {
1277
+ version: 1;
1278
+ runnerId: string;
1279
+ contextId: string;
1280
+ sessionId: string;
1281
+ sessionPath: string;
1282
+ target: AgentContextTarget & {
1283
+ paneId: string;
1284
+ };
1285
+ model: string | null;
1286
+ effort?: string | null;
1287
+ safetyTier?: SafetyTier;
1288
+ runtimeDir?: string;
1289
+ taskDir?: string;
1290
+ capturedAt: string;
1291
+ }
1292
+ export interface MachineParkError {
1293
+ phase: MachineParkPhase;
1294
+ action: string;
1295
+ code: string;
1296
+ message: string;
1297
+ occurredAt: string;
1298
+ retryable: boolean;
1299
+ resourceId?: string;
1300
+ }
1301
+ export type MachineParkResidualState = 'running' | 'stopped' | 'unknown';
1302
+ export interface MachineParkResiduals {
1303
+ runner: MachineParkResidualState;
1304
+ resources: Array<{
1305
+ resourceId: string;
1306
+ state: MachineParkResidualState;
1307
+ detail?: string;
1308
+ }>;
1309
+ }
1310
+ export interface MachineParkCurrentStep {
1311
+ index: number;
1312
+ name: string;
1313
+ status: RunStepStatus;
1314
+ }
1315
+ /**
1316
+ * What a release-mode park does with the run's slot.
1317
+ *
1318
+ * `retained` keeps the slot bound to the parked run (machine-wide pause of a
1319
+ * monitoring or CI-watching run). `freed` releases slot ownership so dispatch
1320
+ * can select it while the run stays parked at its operator wait — the park
1321
+ * record, not the slot row, is then the authority for the run's slot binding.
1322
+ * Absent on records written before slot freeing existed; treat as `retained`.
1323
+ */
1324
+ export type MachineParkSlotDisposition = 'retained' | 'freed';
1325
+ /**
1326
+ * Machine-pause eligibility codes that clients and the Gateway share. Every
1327
+ * other code stays private to the Gateway verdict; these are the gate-park
1328
+ * contract added by the free-slot-at-an-operator-wait decision.
1329
+ */
1330
+ export declare const MachineParkEligibilityCodes: {
1331
+ /** A gate-held publication run may be released and its slot freed. */
1332
+ readonly eligibleGateRelease: "ELIGIBLE_GATE_RELEASE_PAUSE";
1333
+ /** The run's runner declares no graceful stop plus persisted session reload. */
1334
+ readonly runnerReloadUnsupported: "RUNNER_RELOAD_UNSUPPORTED";
1335
+ /** A gate-held run can only be parked in release mode; orchestration-only would strand its gate. */
1336
+ readonly gateParkRequiresRelease: "GATE_PARK_REQUIRES_RELEASE";
1337
+ /**
1338
+ * The record freed its slot, so the operation asked for cannot act on the
1339
+ * run until a restore has put it back. Not a refusal of restore itself:
1340
+ * `machine.pause.restore` and gate resolution both drive that restore.
1341
+ */
1342
+ readonly freedSlotRestoreRequired: "FREED_SLOT_RESTORE_REQUIRED";
1343
+ /**
1344
+ * Restore refused: the original slot is no longer free AND no other slot on
1345
+ * the machine could take the run instead. The record stays parked and its
1346
+ * decision stays pending, so the run can be restored later or cancelled.
1347
+ *
1348
+ * Kept as the refusal for the case where re-homing was not even attempted —
1349
+ * the runner cannot carry its session across working directories, or the
1350
+ * record has no preserved workspace to re-home. When a re-home WAS attempted
1351
+ * and every candidate failed a proof, `RESTORE_NO_REHOME_TARGET` says so.
1352
+ */
1353
+ readonly restoreSlotTaken: "RESTORE_SLOT_TAKEN";
1354
+ /**
1355
+ * The original slot was taken, so the restore will put the run into a
1356
+ * DIFFERENT free slot on the same machine. An eligible verdict, not a
1357
+ * refusal: the Gateway picked the target through the same dispatch scoring
1358
+ * that picks a slot for a new run, and the preview names it so the operator
1359
+ * sees where the run is going before answering the gate.
1360
+ */
1361
+ readonly restoreRehomed: "ELIGIBLE_FREED_SLOT_REHOME";
1362
+ /**
1363
+ * Re-home refused: the run's runner scopes its persisted session by working
1364
+ * directory, so the session recorded under the original slot's workspace
1365
+ * could not be resumed from another slot's. Fails closed — a reload that
1366
+ * silently started a FRESH conversation would lose the run's whole context
1367
+ * while reporting a successful restore.
1368
+ */
1369
+ readonly restoreRehomeSessionNotPortable: "RESTORE_REHOME_SESSION_NOT_PORTABLE";
1370
+ /**
1371
+ * Re-home refused: the original slot is taken and no other slot on the
1372
+ * machine passed every read-only eligibility proof. Distinct from
1373
+ * `RESTORE_SLOT_TAKEN`: a re-home WAS attempted, so the operator knows the
1374
+ * machine has no home for this run rather than that the feature declined to
1375
+ * look.
1376
+ */
1377
+ readonly restoreNoRehomeTarget: "RESTORE_NO_REHOME_TARGET";
1378
+ /**
1379
+ * Restore refused: the preserved branch cannot be checked back out — the
1380
+ * successor left uncommitted work in the tree, or the branch no longer sits
1381
+ * at the tip the park detached from.
1382
+ */
1383
+ readonly restoreWorkspaceUnavailable: "RESTORE_WORKSPACE_UNAVAILABLE";
1384
+ /**
1385
+ * Restore refused: the persisted runner session could not be reloaded with a
1386
+ * structured acknowledgement, so nothing may claim the worker is back.
1387
+ */
1388
+ readonly restoreRunnerReloadFailed: "RESTORE_RUNNER_RELOAD_FAILED";
1389
+ /**
1390
+ * The restore had to re-present the gate because its engine loop had exited,
1391
+ * so the decision the operator answered is no longer the live one.
1392
+ */
1393
+ readonly restoreGateReplayed: "RESTORE_GATE_REPLAYED";
1394
+ /**
1395
+ * Freeing the slot would expose the run's workspace to the next occupant's
1396
+ * prepare, and its branch tip could not be preserved first.
1397
+ */
1398
+ readonly workspaceNotPreservable: "WORKSPACE_NOT_PRESERVABLE";
1399
+ /** A gate park is in flight for this run; its gate cannot be resolved yet. */
1400
+ readonly gateParkInFlight: "GATE_PARK_IN_FLIGHT";
1401
+ /**
1402
+ * The runner liveness probe exceeded its fixed budget before it could say
1403
+ * whether the worker is alive. Distinct from `RUNNER_RELOAD_UNSUPPORTED` and
1404
+ * from the gateway's generic recovery-handle refusal: nothing was decided
1405
+ * about this runner's capability, so the operator's own retry is the answer.
1406
+ * `details.probeBudgetMs` carries the budget that elapsed.
1407
+ */
1408
+ readonly runnerLivenessProbeTimeout: "RUNNER_LIVENESS_PROBE_TIMEOUT";
1409
+ /**
1410
+ * The machine-pause preview digest moved between preview and execute, so the
1411
+ * batch the operator reviewed is no longer the batch that would run. A race,
1412
+ * not a verdict about the run: previewing again resolves it.
1413
+ */
1414
+ readonly machinePausePreviewStale: "MACHINE_PAUSE_PREVIEW_STALE";
1415
+ };
1416
+ export type MachineParkEligibilityCode = (typeof MachineParkEligibilityCodes)[keyof typeof MachineParkEligibilityCodes];
1417
+ /**
1418
+ * Structured facts behind an eligibility verdict, for the codes that have one.
1419
+ *
1420
+ * The reason string is prose for an operator; anything a client or a validation
1421
+ * harness has to BRANCH on belongs here instead, so nobody has to parse the
1422
+ * sentence back apart to recover a number the gateway already knew.
1423
+ */
1424
+ export interface MachinePauseEligibilityDetails {
1425
+ /** Budget the runner liveness probe exhausted (`RUNNER_LIVENESS_PROBE_TIMEOUT`). */
1426
+ probeBudgetMs?: number;
1427
+ }
1428
+ /**
1429
+ * The git identity a freeing park took out of the slot's working tree.
1430
+ *
1431
+ * A linked worktree keeps the parked run's branch checked out, and the next
1432
+ * occupant's prepare resets the checked-out branch to its base ref — which
1433
+ * would move the parked branch and discard its commits. The park detaches HEAD
1434
+ * first and records what it detached from, so the branch ref survives at
1435
+ * `headSha` and restore can check it out again.
1436
+ */
1437
+ export interface MachineParkWorkspace {
1438
+ branch: string;
1439
+ headSha: string;
1440
+ /**
1441
+ * When the detach actually landed, not when it was planned. Absent means the
1442
+ * branch is still checked out in the slot, so the park had no workspace
1443
+ * effect yet. Same fact-versus-intent split as `slotFreedAt`.
1444
+ */
1445
+ detachedAt?: string;
1446
+ }
1447
+ /**
1448
+ * A restore that put the run back into a DIFFERENT slot than the park freed.
1449
+ *
1450
+ * Written write-ahead, before the slot claim, for the same reason every other
1451
+ * park transition is: the re-home is two writes — the record's slot binding and
1452
+ * the slot row's owner — and a crash between them must leave the repair path a
1453
+ * marker saying which slot this record is now homed to. `repairRestoreSlotIntent`
1454
+ * reads `toSlotId`, never the journalled snapshot's `slotId`.
1455
+ *
1456
+ * `fromSlotId` is the slot the park freed, and it stays meaningful after the
1457
+ * re-home: the preserved workspace's detached HEAD is still sitting THERE, so
1458
+ * dispatch's detached-HEAD exemption keys on it rather than on the record's
1459
+ * current slot.
1460
+ */
1461
+ export interface MachineParkRehome {
1462
+ /** The slot the park freed, whose successor made a same-slot restore impossible. */
1463
+ fromSlotId: string;
1464
+ /** The slot the restore re-bound the run into instead. */
1465
+ toSlotId: string;
1466
+ at: string;
1467
+ /** Why the original could not take the run back — the availability refusal, verbatim. */
1468
+ reason: string;
1469
+ }
1470
+ /**
1471
+ * The stages a freed-slot restore owes, in the order it owes them.
1472
+ *
1473
+ * Tracked as its own sequence rather than inferred from what the record happens
1474
+ * to look like. Occupancy, the detached branch, the lease states, and the
1475
+ * runner proof each record ONE stage's outcome, so reading them as a whole is a
1476
+ * guess: a restore that re-bound the slot and then died before re-creating the
1477
+ * pane looks, to an occupancy reader, exactly like a restore that never had to
1478
+ * touch the slot at all — and the retry then takes the ordinary path and fails
1479
+ * on a recovery handle nothing re-hosted.
1480
+ */
1481
+ export declare const MACHINE_PARK_RESTORE_STAGES: readonly ["rebind", "reattach", "reacquire", "reload"];
1482
+ export type MachineParkRestoreStage = (typeof MACHINE_PARK_RESTORE_STAGES)[number];
1483
+ /**
1484
+ * How far the current restore attempt got, written around each stage.
1485
+ *
1486
+ * `attempting` is written BEFORE the stage runs and `completed` only after it
1487
+ * lands, so a crash anywhere inside a stage is visible as an unfinished stage
1488
+ * rather than as an absence. The write-ahead journal is kept until every stage
1489
+ * is in `completed`.
1490
+ */
1491
+ export interface MachineParkRestoreProgress {
1492
+ /** The restore operation these stages belong to; a newer one starts over. */
1493
+ operationId: string;
1494
+ /** The stage currently being attempted, if any. Cleared when it completes. */
1495
+ attempting?: MachineParkRestoreStage;
1496
+ /** Stages proven complete, in the order they landed. */
1497
+ completed: MachineParkRestoreStage[];
1498
+ updatedAt: string;
1499
+ }
1500
+ /** Whether every stage a freed-slot restore owes has landed. */
1501
+ export declare function machineParkRestoreComplete(progress: MachineParkRestoreProgress | undefined): boolean;
1502
+ /**
1503
+ * Why the last restore attempt refused, kept on the record so a reconnecting
1504
+ * client sees the reason without replaying the RPC that produced it.
1505
+ *
1506
+ * A refusal is not a failure of the park: the record stays `parked`, its
1507
+ * decision stays pending, and the run can be restored again later or
1508
+ * cancelled. Cleared the moment a restore gets past the refusal.
1509
+ */
1510
+ export interface MachineParkRestoreRefusal {
1511
+ /** A `MachineParkEligibilityCode`; carried as a string like every verdict code. */
1512
+ code: string;
1513
+ reason: string;
1514
+ at: string;
1515
+ }
1516
+ /** Write-ahead per-run record; persisted on Run before any release side effect. */
1517
+ export interface MachineParkRecord {
1518
+ version: 1;
1519
+ operationId: string;
1520
+ previewId: string;
1521
+ runId: string;
1522
+ generation: number;
1523
+ restoredGeneration?: number;
1524
+ machine: string;
1525
+ slotId: string;
1526
+ mode: MachinePauseMode;
1527
+ phase: MachineParkPhase;
1528
+ prePauseStatus: RunStatus;
1529
+ prePauseCurrentStep: MachineParkCurrentStep | null;
1530
+ resourceManifest: MachineParkResourceManifest;
1531
+ recoveryHandle: MachinePauseRecoveryHandle | null;
1532
+ /** Slot intent decided at preview; absent means `retained`. */
1533
+ slotDisposition?: MachineParkSlotDisposition;
1534
+ /**
1535
+ * The workspace a freeing park detached, so the next occupant's prepare
1536
+ * cannot reset the parked run's branch. Written before slot ownership is
1537
+ * released; `restore` checks the branch back out at this exact tip.
1538
+ */
1539
+ preservedWorkspace?: MachineParkWorkspace;
1540
+ /**
1541
+ * When slot ownership was actually released, not merely intended. Set only
1542
+ * after the park stopped the runner and every manifest resource, so a partial
1543
+ * park never advertises a freed slot.
1544
+ *
1545
+ * Kept for the whole restore and cleared only when every restore stage has
1546
+ * landed, so it stays the marker of "this record owes a freed-slot restore".
1547
+ * OCCUPANCY is `slotReboundAt`, which lands earlier: the two are deliberately
1548
+ * separate, because a restore that re-bound the slot and then failed still
1549
+ * owes the rest of its stages.
1550
+ */
1551
+ slotFreedAt?: string;
1552
+ /**
1553
+ * When a restore re-bound the freed slot to this run, not merely intended
1554
+ * to. Written in the same write-ahead window that clears `slotFreedAt`, so a
1555
+ * crash between the slot claim and the record write is repairable. Survives
1556
+ * the restore as the note that this record's slot came back.
1557
+ */
1558
+ slotReboundAt?: string;
1559
+ /**
1560
+ * Set when a restore re-bound a DIFFERENT slot than the park freed, because
1561
+ * the original had been taken. `slotId` above already names the new slot —
1562
+ * this is the note that says it moved, and from where.
1563
+ */
1564
+ rehome?: MachineParkRehome;
1565
+ /**
1566
+ * How far the current restore attempt got. Absent until a freed-slot restore
1567
+ * starts, and the authority for what a retry still owes — never inferred from
1568
+ * whether the run currently occupies its slot.
1569
+ */
1570
+ restoreProgress?: MachineParkRestoreProgress;
1571
+ /**
1572
+ * Why the last restore attempt refused, when it refused without changing
1573
+ * anything. Absent once a restore gets past the refusal.
1574
+ */
1575
+ restoreRefusal?: MachineParkRestoreRefusal;
1576
+ /** Restore intent classification persisted before any selected batch member mutates. */
1577
+ restoreDisposition?: 'zero-effect' | 'effectful';
1578
+ /**
1579
+ * What the last restore attempt actually did to each manifest resource, in
1580
+ * the order it did it. Reset at the start of each attempt. Absent on records
1581
+ * written before restore recorded its effects.
1582
+ */
1583
+ restoreEffects?: MachineParkRestoreEffect[];
1584
+ /** Exact runner-native acknowledgement captured before orchestration resumes. */
1585
+ recoveryProof?: {
1586
+ sessionId: string;
1587
+ live: true;
1588
+ acknowledgement: {
1589
+ /**
1590
+ * How the worker was proven back.
1591
+ *
1592
+ * `structured` — the restore relaunched the session and the runner
1593
+ * acknowledged the continuation prompt: a turn was delivered and started.
1594
+ *
1595
+ * `adopted` — the worker was ALREADY running this run's persisted session
1596
+ * when the restore reached it, so nothing was relaunched and no turn was
1597
+ * delivered. The evidence is the structured live-binding check, not a
1598
+ * prompt acknowledgement, and the two must be distinguishable: a consumer
1599
+ * with only `source` to go on cannot tell a delivered turn from an
1600
+ * inherited one.
1601
+ */
1602
+ kind: 'structured' | 'adopted';
1603
+ source: string;
1604
+ reason: string;
1605
+ /** Present only for `structured`; an adopted worker started no turn. */
1606
+ turnToken?: string;
1607
+ };
1608
+ acceptedAt: string;
1609
+ };
1610
+ errors: MachineParkError[];
1611
+ residuals: MachineParkResiduals;
1612
+ createdAt: string;
1613
+ updatedAt: string;
1614
+ parkedAt?: string;
1615
+ restoredAt?: string;
1616
+ cancelledAt?: string;
1617
+ }
1129
1618
  export interface Run {
1130
1619
  id: string;
1131
1620
  familyId: string;
@@ -1159,6 +1648,11 @@ export interface Run {
1159
1648
  domain?: string;
1160
1649
  /** Named prepare profile requested for this run (ADR-037). */
1161
1650
  prepareProfile?: string;
1651
+ /**
1652
+ * Dispatch-time resource posture preset (ADR-054). Presets the gate choice for
1653
+ * every durable operator wait of this run; an explicit gate choice still wins.
1654
+ */
1655
+ waitPolicy?: ResourcePostureWaitPolicy;
1162
1656
  /**
1163
1657
  * Branch-update strategy for `update-branch` runs (rebase | merge |
1164
1658
  * project-default). Ignored for other flows. Rendered into the worker task
@@ -1174,6 +1668,15 @@ export interface Run {
1174
1668
  branch: string | null;
1175
1669
  /** Completion side-effect policy; artifact-only suppresses publication/PR mutation paths. */
1176
1670
  completionPolicy?: RunCompletionPolicy;
1671
+ /** Principal-stamped one-dispatch pressure override requested for this run.
1672
+ * Bound to one machine + pressure generation; dispatch execution recomputes
1673
+ * the admission decision and rejects the override when the generation moved. */
1674
+ pressureOverride?: import('./pressure-admission.js').PressureOverrideAudit;
1675
+ /** Preview identity of the admitted pressure decision this run was created
1676
+ * against (client-rendered preview, or FIND_SLOT's selected decision for
1677
+ * automatic runs). Execution rejects with PRESSURE_PREVIEW_STALE when it no
1678
+ * longer matches freshly recomputed evidence. */
1679
+ pressureAdmissionRef?: import('./pressure-admission.js').PressureAdmissionReference;
1177
1680
  /** Requested/resolved base ref for artifact-only comparison replay runs. */
1178
1681
  startRef?: RunStartRefProvenance | null;
1179
1682
  /** Gateway-captured template provenance for the rendered worker task. */
@@ -1267,6 +1770,10 @@ export interface Run {
1267
1770
  analyticsEmittedAt?: string;
1268
1771
  /** Present when this run record was imported from a portable bundle (ADR-039). */
1269
1772
  importProvenance?: RunImportProvenance;
1773
+ /** Durable machine-scoped pause/release/restore state. */
1774
+ park?: MachineParkRecord | null;
1775
+ /** Gateway-owned effective resource posture and last transition (ADR-054). */
1776
+ resourcePosture?: RunResourcePostureState;
1270
1777
  /** Imported reference-only runs must not be re-dispatched or activated on slot. */
1271
1778
  readOnly?: boolean;
1272
1779
  /** Slot HEAD SHA captured at dispatch (after prepare) — base for per-run iteration diff. */
@@ -1281,9 +1788,9 @@ export interface RunEngineState {
1281
1788
  * `nudgeReuse` is set when the operator picks "Nudge worker" in the dispatch wizard or the
1282
1789
  * branch-affinity decision card; FIND_SLOT honors it to bind the busy slot, and DISPATCH
1283
1790
  * routes through `nudgeDispatch` (skip PREPARE, send-keys to existing tmux session) instead
1284
- * of `dispatchExecute` (kill + relaunch). `freshReuse` is the "Kill & dispatch fresh"
1285
- * sibling FIND_SLOT hard-kills the prior worker BEFORE PREPARE so git reset / checkout /
1286
- * dependency install don't race a still-writing worker in the same worktree.
1791
+ * of `dispatchExecute` (kill + relaunch). `freshReuse` replaces either that busy
1792
+ * branch-affinity worker or an unowned warm runner. FIND_SLOT hard-kills it BEFORE PREPARE
1793
+ * so git reset / checkout / dependency install don't race a still-writing worker.
1287
1794
  * `warmSessionReuse` is set on CI-watch chained follow-ups (pr-complete / update-branch)
1288
1795
  * when the parent kept its worker warm through finalize; DISPATCH tries handoff into that
1289
1796
  * session and falls back to fresh `dispatchExecute` when the process is dead or not nudgeable. */
@@ -1300,9 +1807,17 @@ export interface RunEngineState {
1300
1807
  * affinity) — warm handoff targets held/ci-watch slots with an idle agent status.
1301
1808
  */
1302
1809
  warmSessionReuse?: boolean;
1810
+ /**
1811
+ * True only when DISPATCH actually handed off into the warm parent session.
1812
+ * False when warmSessionReuse was requested but fell back to fresh dispatch.
1813
+ * Soft budget baselines use this — not the request flag alone.
1814
+ */
1815
+ warmHandoffSucceeded?: boolean;
1303
1816
  };
1304
1817
  /** Monotonic replay generation counter; startRun bails if the run has been superseded. */
1305
1818
  generation?: number;
1819
+ /** Operator `run.forceComplete` on a failed run. Replay must not treat this as ordinary done. */
1820
+ operatorForceCompleted?: true;
1306
1821
  /** Multi-surface validation matrix suggested at dispatch (farmslot profile-fit). */
1307
1822
  validationPlan?: ValidationPlanStep[];
1308
1823
  profileFitSuggestion?: ProfileFitSuggestion;
@@ -1592,9 +2107,9 @@ export declare const DEFAULT_CODEX_MODEL = "gpt-5.6-sol";
1592
2107
  /** Default Codex reasoning effort when dispatch/launch omits effort. */
1593
2108
  export declare const DEFAULT_CODEX_EFFORT = "xhigh";
1594
2109
  /** Default Cursor Agent model used when no slot/task/project/user override is set. */
1595
- export declare const DEFAULT_CURSOR_MODEL = "composer-2.5";
2110
+ export declare const DEFAULT_CURSOR_MODEL = "cursor-grok-4.6-high-fast";
1596
2111
  /** Default Grok model used when no slot/task/project/user override is set. */
1597
- export declare const DEFAULT_GROK_MODEL = "grok-4.5";
2112
+ export declare const DEFAULT_GROK_MODEL = "grok-4.6";
1598
2113
  /** Default Grok reasoning effort when dispatch/launch omits effort. */
1599
2114
  export declare const DEFAULT_GROK_EFFORT = "xhigh";
1600
2115
  export type DecisionType = 'collision_check' | 'plan_confirmation' | 'retrospective' | 'review_posting' | 'blocked_alert' | 'review_comments' | 'improvement' | 'recipe_strategy' | `engine_${string}` | `monitor_${string}` | `ci_${string}`;