@farmslot/protocol 0.21.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.
- package/CHANGELOG.md +96 -0
- package/dist/contracts/agents.d.ts +16 -0
- package/dist/contracts/agents.d.ts.map +1 -1
- package/dist/contracts/backlog.d.ts +8 -0
- package/dist/contracts/backlog.d.ts.map +1 -1
- package/dist/contracts/backlog.js.map +1 -1
- package/dist/contracts/device-inventory.d.ts +118 -0
- package/dist/contracts/device-inventory.d.ts.map +1 -0
- package/dist/contracts/device-inventory.js +51 -0
- package/dist/contracts/device-inventory.js.map +1 -0
- package/dist/contracts/dispatch.d.ts +2 -0
- package/dist/contracts/dispatch.d.ts.map +1 -1
- package/dist/contracts/execution-templates.d.ts +10 -0
- package/dist/contracts/execution-templates.d.ts.map +1 -1
- package/dist/contracts/gate-park.d.ts +284 -0
- package/dist/contracts/gate-park.d.ts.map +1 -0
- package/dist/contracts/gate-park.js +415 -0
- package/dist/contracts/gate-park.js.map +1 -0
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +4 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/pressure-admission.d.ts +175 -0
- package/dist/contracts/pressure-admission.d.ts.map +1 -0
- package/dist/contracts/pressure-admission.js +26 -0
- package/dist/contracts/pressure-admission.js.map +1 -0
- package/dist/contracts/resource-posture.d.ts +379 -0
- package/dist/contracts/resource-posture.d.ts.map +1 -0
- package/dist/contracts/resource-posture.js +293 -0
- package/dist/contracts/resource-posture.js.map +1 -0
- package/dist/contracts/resources.d.ts +27 -1
- package/dist/contracts/resources.d.ts.map +1 -1
- package/dist/contracts/resources.js +1 -1
- package/dist/contracts/resources.js.map +1 -1
- package/dist/contracts/reviews.d.ts +2 -0
- package/dist/contracts/reviews.d.ts.map +1 -1
- package/dist/contracts/reviews.js.map +1 -1
- package/dist/contracts/runs.d.ts +480 -7
- package/dist/contracts/runs.d.ts.map +1 -1
- package/dist/contracts/runs.js +130 -1
- package/dist/contracts/runs.js.map +1 -1
- package/dist/contracts/runtime-capabilities.d.ts +255 -3
- package/dist/contracts/runtime-capabilities.d.ts.map +1 -1
- package/dist/contracts/runtime-capabilities.js +113 -1
- package/dist/contracts/runtime-capabilities.js.map +1 -1
- package/dist/contracts/slots.d.ts +53 -1
- package/dist/contracts/slots.d.ts.map +1 -1
- package/dist/recipes/step-io.d.ts +10 -1
- package/dist/recipes/step-io.d.ts.map +1 -1
- package/dist/rpc/config.d.ts +9 -1
- package/dist/rpc/config.d.ts.map +1 -1
- package/dist/rpc/copilot-runtime.d.ts +17 -0
- package/dist/rpc/copilot-runtime.d.ts.map +1 -1
- package/dist/rpc/copilot-runtime.js +5 -0
- package/dist/rpc/copilot-runtime.js.map +1 -1
- package/dist/rpc/dispatch.d.ts +39 -1
- package/dist/rpc/dispatch.d.ts.map +1 -1
- package/dist/rpc/dispatch.js +2 -0
- package/dist/rpc/dispatch.js.map +1 -1
- package/dist/rpc/git.d.ts +35 -0
- package/dist/rpc/git.d.ts.map +1 -1
- package/dist/rpc/index.d.ts +3 -0
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +3 -0
- package/dist/rpc/index.js.map +1 -1
- package/dist/rpc/machine-pause.d.ts +158 -0
- package/dist/rpc/machine-pause.d.ts.map +1 -0
- package/dist/rpc/machine-pause.js +8 -0
- package/dist/rpc/machine-pause.js.map +1 -0
- package/dist/rpc/registry.d.ts +16 -0
- package/dist/rpc/registry.d.ts.map +1 -1
- package/dist/rpc/registry.js +17 -0
- package/dist/rpc/registry.js.map +1 -1
- package/dist/rpc/resource-posture.d.ts +36 -0
- package/dist/rpc/resource-posture.d.ts.map +1 -0
- package/dist/rpc/resource-posture.js +7 -0
- package/dist/rpc/resource-posture.js.map +1 -0
- package/dist/rpc/resource-pressure-selection.d.ts +4 -0
- package/dist/rpc/resource-pressure-selection.d.ts.map +1 -0
- package/dist/rpc/resource-pressure-selection.js +21 -0
- package/dist/rpc/resource-pressure-selection.js.map +1 -0
- package/dist/rpc/resources.d.ts +176 -1
- package/dist/rpc/resources.d.ts.map +1 -1
- package/dist/rpc/resources.js +6 -0
- package/dist/rpc/resources.js.map +1 -1
- package/dist/rpc/run.d.ts +122 -5
- package/dist/rpc/run.d.ts.map +1 -1
- package/dist/rpc/run.js +1 -0
- package/dist/rpc/run.js.map +1 -1
- package/dist/rpc/runtime-capabilities.d.ts +73 -3
- package/dist/rpc/runtime-capabilities.d.ts.map +1 -1
- package/dist/rpc/runtime-capabilities.js +11 -0
- package/dist/rpc/runtime-capabilities.js.map +1 -1
- package/dist/rpc/slot.d.ts +9 -1
- package/dist/rpc/slot.d.ts.map +1 -1
- package/dist/rpc/slot.js.map +1 -1
- package/dist/rpc/tmux.d.ts +4 -0
- package/dist/rpc/tmux.d.ts.map +1 -1
- package/dist/runs/decision-resolution.d.ts +7 -0
- package/dist/runs/decision-resolution.d.ts.map +1 -1
- package/dist/runs/decision-resolution.js +1 -0
- package/dist/runs/decision-resolution.js.map +1 -1
- package/dist/slots/tracking-branch.d.ts +12 -0
- package/dist/slots/tracking-branch.d.ts.map +1 -1
- package/dist/slots/tracking-branch.js +12 -0
- package/dist/slots/tracking-branch.js.map +1 -1
- package/dist/transport/events.d.ts +7 -1
- package/dist/transport/events.d.ts.map +1 -1
- package/dist/transport/events.js +2 -0
- package/dist/transport/events.js.map +1 -1
- package/dist/transport/signal.d.ts +11 -0
- package/dist/transport/signal.d.ts.map +1 -1
- package/dist/transport/signal.js +19 -1
- package/dist/transport/signal.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate-park state for clients (ADR-054 `free-slot` at an operator wait).
|
|
3
|
+
*
|
|
4
|
+
* A run parked with `free-slot` keeps its gate answerable while its slot goes
|
|
5
|
+
* back to dispatch. Three facts then live in three different places — the park
|
|
6
|
+
* record's slot disposition, the restore stages the record owes, and the
|
|
7
|
+
* Gateway's verdict on whether the original slot can take the run back — and a
|
|
8
|
+
* surface that reads any one of them alone gets the run's state wrong:
|
|
9
|
+
*
|
|
10
|
+
* - occupancy alone reports a restore that re-bound the slot and then failed
|
|
11
|
+
* as "back", so the gate looks answerable against a worker nothing proved;
|
|
12
|
+
* - the phase alone reports a `partial` that never reached the slot the same
|
|
13
|
+
* way as one that freed it;
|
|
14
|
+
* - a client that decides slot availability itself picks a slot the Gateway
|
|
15
|
+
* did not, which is the one thing ADR-054 forbids.
|
|
16
|
+
*
|
|
17
|
+
* So this module owns the single reading, and Command Center, Companion, and
|
|
18
|
+
* the CLI all render it. Availability is never derived here: it is carried in
|
|
19
|
+
* from a Gateway verdict, or reported as not known.
|
|
20
|
+
*
|
|
21
|
+
* The predicates below moved out of the Gateway so clients share the exact
|
|
22
|
+
* definitions the Gateway acts on rather than approximations of them.
|
|
23
|
+
*/
|
|
24
|
+
import { MACHINE_PARK_RESTORE_STAGES, } from './runs.js';
|
|
25
|
+
/**
|
|
26
|
+
* Whether this run's machine-park record released its slot (ADR-054
|
|
27
|
+
* `free-slot` at an operator wait, amending ADR-038's gate-held slot hold).
|
|
28
|
+
*
|
|
29
|
+
* `slotFreedAt` records the fact, not the intent: it is written only after the
|
|
30
|
+
* park stopped the runner and every manifest resource AND the ownership
|
|
31
|
+
* release landed, so a partial park never reads as freed. While it is set, the
|
|
32
|
+
* park record — not the slot row — is the authority for the run's slot
|
|
33
|
+
* binding: the run keeps `slotId` (the recovery handle and the workspace
|
|
34
|
+
* branch key off it) but stops counting as an occupant of that slot.
|
|
35
|
+
*
|
|
36
|
+
* This is the OCCUPANCY predicate. It must never claim a slot is free before
|
|
37
|
+
* the release actually landed, so dispatch cannot hand out a slot whose worker
|
|
38
|
+
* is still running. Use `isGateParkInFlightOrFreed` for the safety fences,
|
|
39
|
+
* which have the opposite bias.
|
|
40
|
+
*/
|
|
41
|
+
export function isSlotFreedByPark(run) {
|
|
42
|
+
const park = run.park;
|
|
43
|
+
if (!park?.slotFreedAt)
|
|
44
|
+
return false;
|
|
45
|
+
// `slotReboundAt` is the counterpart fact, and it is what ends the release.
|
|
46
|
+
// `slotFreedAt` deliberately survives the whole restore — it is what tells a
|
|
47
|
+
// retry which stages it still owes — so reading it alone would report a slot
|
|
48
|
+
// the run is sitting in as free for dispatch.
|
|
49
|
+
return !park.slotReboundAt;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether a gate park still owes a restore before its gate may be answered.
|
|
53
|
+
*
|
|
54
|
+
* The question consumption asks, and it is NOT "does the run occupy its slot".
|
|
55
|
+
* A restore that re-bound the slot, booted its resources, and then failed to
|
|
56
|
+
* get a structured acknowledgement out of the worker leaves an occupied slot
|
|
57
|
+
* and a running process — and answering the gate there drives the engine
|
|
58
|
+
* against a worker that never confirmed it came back. So this keys on the
|
|
59
|
+
* restore's own stage record, which is the only thing that says what landed.
|
|
60
|
+
*/
|
|
61
|
+
export function needsGateParkRestore(run) {
|
|
62
|
+
const park = run.park;
|
|
63
|
+
if (!park)
|
|
64
|
+
return false;
|
|
65
|
+
// `restored` is the ONLY thing that ends the obligation. Not the stage list:
|
|
66
|
+
// every stage can be complete and the record still be `partial`, because the
|
|
67
|
+
// orchestration resume after them failed — and reading the stages as done
|
|
68
|
+
// there left the run unable to answer its gate and unable to be restored
|
|
69
|
+
// through it. Not the residuals either: a reload that started the worker and
|
|
70
|
+
// lost its acknowledgement leaves an occupied slot and a running process.
|
|
71
|
+
if (park.phase === 'restored' || park.phase === 'cancelled')
|
|
72
|
+
return false;
|
|
73
|
+
if (park.mode !== 'release' || park.slotDisposition !== 'freed')
|
|
74
|
+
return false;
|
|
75
|
+
// The park itself is still landing. There is nothing coherent to restore
|
|
76
|
+
// into yet, and the in-flight fence covers that case instead.
|
|
77
|
+
//
|
|
78
|
+
// Everything else got PAST the park: it freed the slot, or a restore already
|
|
79
|
+
// re-bound it. A record written before stages were tracked lands here through
|
|
80
|
+
// `slotReboundAt` — it cleared its freed marker at the rebind, so that is the
|
|
81
|
+
// only fact left saying a restore touched it.
|
|
82
|
+
//
|
|
83
|
+
// A park that settled without reaching the slot at all is deliberately NOT
|
|
84
|
+
// here. It owes no freed-slot stages, and the outstanding-effect fence below
|
|
85
|
+
// is the right guard for it: it can still leave a run answerable where it
|
|
86
|
+
// stands when the park stopped nothing.
|
|
87
|
+
return Boolean(park.slotFreedAt) || Boolean(park.slotReboundAt);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Whether a slot-freeing park is either done or still in flight for this run.
|
|
91
|
+
*
|
|
92
|
+
* The opposite bias to `isSlotFreedByPark`: it goes true the moment the
|
|
93
|
+
* write-ahead record declares a freeing park and stays true through the window
|
|
94
|
+
* where the runner and resources are being stopped but `slotFreedAt` has not
|
|
95
|
+
* been written yet.
|
|
96
|
+
*
|
|
97
|
+
* Every guard that must not act on a run whose slot is disappearing uses this:
|
|
98
|
+
* resolving a gate, applying a posture, driving a resolved gate onward, or
|
|
99
|
+
* tearing the slot down after a failure. Answering a gate mid-park would
|
|
100
|
+
* publish against a worker that is being stopped underneath it.
|
|
101
|
+
*
|
|
102
|
+
* It is keyed on intent-or-fact HONESTLY, which matters as much as the fence
|
|
103
|
+
* itself. A fence that never lifts is not a fence, it is a strand: the run can
|
|
104
|
+
* neither answer its gate nor be restored, and cancelling it is the only exit.
|
|
105
|
+
* So:
|
|
106
|
+
*
|
|
107
|
+
* - the record owes a restore — it freed the slot, or a restore re-bound it
|
|
108
|
+
* and has not settled `restored`. Fenced, until that restore or a cancel.
|
|
109
|
+
* - a park that never reached the slot and settled `partial` — it will not
|
|
110
|
+
* finish. It is still fenced
|
|
111
|
+
* while ANY of its effects is outstanding: a detach not yet rolled back, or
|
|
112
|
+
* a runner that is not PROVABLY still running. A stopped worker cannot act
|
|
113
|
+
* on a gate answer, and letting the operator answer anyway would be the
|
|
114
|
+
* silent version of the strand. `machine.pause.restore` is the exit: it
|
|
115
|
+
* reloads the worker and settles the record, which lifts the fence. Only a
|
|
116
|
+
* park that detached nothing and left an observably live worker leaves the
|
|
117
|
+
* run answerable where it stands.
|
|
118
|
+
* - otherwise, while the intent is live — fenced.
|
|
119
|
+
*/
|
|
120
|
+
export function isGateParkInFlightOrFreed(run) {
|
|
121
|
+
const park = run.park;
|
|
122
|
+
if (!park)
|
|
123
|
+
return false;
|
|
124
|
+
// A record the operator already settled fences nothing, even though it still
|
|
125
|
+
// carries the historical `slotFreedAt` of the release it undid.
|
|
126
|
+
if (park.phase === 'restored' || park.phase === 'cancelled')
|
|
127
|
+
return false;
|
|
128
|
+
// Everything that still owes a restore is fenced, by construction rather than
|
|
129
|
+
// by two lists of conditions that have to be kept in step. A gate that can be
|
|
130
|
+
// answered while a restore is outstanding is the whole failure this guards,
|
|
131
|
+
// and `needsGateParkRestore` already covers every freed or re-bound record —
|
|
132
|
+
// so what remains below is only the park that never reached the slot.
|
|
133
|
+
if (needsGateParkRestore(run))
|
|
134
|
+
return true;
|
|
135
|
+
if (park.mode !== 'release' || park.slotDisposition !== 'freed')
|
|
136
|
+
return false;
|
|
137
|
+
if (park.phase === 'partial') {
|
|
138
|
+
if (park.preservedWorkspace?.detachedAt)
|
|
139
|
+
return true;
|
|
140
|
+
// The park stops the runner before it ever touches the slot, so a partial
|
|
141
|
+
// that got past that point has a dead worker even though the run still owns
|
|
142
|
+
// its slot. Restore is what brings it back.
|
|
143
|
+
//
|
|
144
|
+
// `unknown` fences too, and that direction matters: it means the probe
|
|
145
|
+
// could not see the worker, which for a failure before the re-host is the
|
|
146
|
+
// NORMAL answer — the recorded handle still names the pane a successor
|
|
147
|
+
// destroyed. Reading "could not observe" as "still running" lifts the fence
|
|
148
|
+
// on a dead worker, and the next gate answer runs FINALIZE against it. Only
|
|
149
|
+
// an observed live worker leaves the run answerable.
|
|
150
|
+
return park.residuals?.runner !== 'running';
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Whether machine parking still holds this run.
|
|
156
|
+
*
|
|
157
|
+
* The park RECORD is the authority for "is this run parked", not the run's
|
|
158
|
+
* persisted posture. A restore or a cancel settles the record while the posture
|
|
159
|
+
* it was applied under stays on the run, so a reader that trusts the posture
|
|
160
|
+
* decides an already-restored run is still parked — and then refuses to park it
|
|
161
|
+
* again, forever, as a no-op.
|
|
162
|
+
*/
|
|
163
|
+
export function hasLiveParkRecord(run) {
|
|
164
|
+
const park = run.park;
|
|
165
|
+
if (!park)
|
|
166
|
+
return false;
|
|
167
|
+
return park.phase !== 'restored' && park.phase !== 'cancelled';
|
|
168
|
+
}
|
|
169
|
+
function slotStateOf(park) {
|
|
170
|
+
if (park.phase === 'restored' || park.phase === 'cancelled')
|
|
171
|
+
return 'settled';
|
|
172
|
+
if (park.mode !== 'release' || park.slotDisposition !== 'freed')
|
|
173
|
+
return 'retained';
|
|
174
|
+
if (park.slotFreedAt && !park.slotReboundAt)
|
|
175
|
+
return 'freed';
|
|
176
|
+
// The re-home note is written write-ahead, before the claim, so it can be
|
|
177
|
+
// present while the slot is still freed — which is why occupancy is read
|
|
178
|
+
// FIRST above. Here the slot is bound, and `rehome` says which one.
|
|
179
|
+
if (park.slotReboundAt)
|
|
180
|
+
return park.rehome ? 'rehoming' : 'restoring';
|
|
181
|
+
// A `partial` never reached the slot AND has stopped trying, so it is not
|
|
182
|
+
// "still landing". Whether its gate is answerable is not a second opinion
|
|
183
|
+
// formed here — it is `isGateParkInFlightOrFreed`, the same predicate
|
|
184
|
+
// `assertNotGateParked` fences the resolution on. Deriving it any other way
|
|
185
|
+
// is how the surfaces came to tell an operator to wait for a park that had
|
|
186
|
+
// already given up, on a run whose worker was alive and whose gate the
|
|
187
|
+
// Gateway would have accepted.
|
|
188
|
+
if (park.phase === 'partial') {
|
|
189
|
+
return isGateParkInFlightOrFreed({ park }) ? 'partial-needs-restore' : 'partial-answerable';
|
|
190
|
+
}
|
|
191
|
+
// The write-ahead record declares the intent before any release effect lands.
|
|
192
|
+
return 'freeing';
|
|
193
|
+
}
|
|
194
|
+
function restoreStageView(park) {
|
|
195
|
+
const progress = park.restoreProgress;
|
|
196
|
+
if (!progress) {
|
|
197
|
+
return {
|
|
198
|
+
state: 'not-started',
|
|
199
|
+
attempting: null,
|
|
200
|
+
completed: [],
|
|
201
|
+
remaining: MACHINE_PARK_RESTORE_STAGES,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const completed = MACHINE_PARK_RESTORE_STAGES.filter((stage) => progress.completed.includes(stage));
|
|
205
|
+
const remaining = MACHINE_PARK_RESTORE_STAGES.filter((stage) => !progress.completed.includes(stage));
|
|
206
|
+
// An attempted stage is in flight, not complete: the marker is written BEFORE
|
|
207
|
+
// the stage runs, so a crash inside one is visible as unfinished rather than
|
|
208
|
+
// as an absence. `complete` therefore requires every stage landed AND nothing
|
|
209
|
+
// being attempted, which is `machineParkRestoreComplete`.
|
|
210
|
+
const state = remaining.length === 0 && !progress.attempting
|
|
211
|
+
? 'complete'
|
|
212
|
+
: completed.length === 0 && !progress.attempting
|
|
213
|
+
? 'not-started'
|
|
214
|
+
: 'in-progress';
|
|
215
|
+
return {
|
|
216
|
+
state,
|
|
217
|
+
attempting: progress.attempting ?? null,
|
|
218
|
+
completed,
|
|
219
|
+
remaining,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The one reading of a run's gate park, or `null` when the run has no park
|
|
224
|
+
* record at all.
|
|
225
|
+
*
|
|
226
|
+
* `verdict` carries a Gateway-resolved restore target when the caller has read
|
|
227
|
+
* one (`machine.pause.restore`). Without it the target's `available` stays
|
|
228
|
+
* `null`: the record says which slot a restore would use, never whether that
|
|
229
|
+
* slot is free right now.
|
|
230
|
+
*/
|
|
231
|
+
export function gateParkView(run, verdict) {
|
|
232
|
+
const park = run.park;
|
|
233
|
+
if (!park)
|
|
234
|
+
return null;
|
|
235
|
+
const disposition = park.slotDisposition ?? 'retained';
|
|
236
|
+
const slotState = slotStateOf(park);
|
|
237
|
+
const proof = park.recoveryProof;
|
|
238
|
+
return {
|
|
239
|
+
runId: run.id,
|
|
240
|
+
machine: park.machine,
|
|
241
|
+
slotId: park.slotId,
|
|
242
|
+
phase: park.phase,
|
|
243
|
+
slotState,
|
|
244
|
+
slotDisposition: disposition,
|
|
245
|
+
freedSlotId: isSlotFreedByPark({ park }) ? park.slotId : null,
|
|
246
|
+
...(park.slotFreedAt ? { slotFreedAt: park.slotFreedAt } : {}),
|
|
247
|
+
...(park.slotReboundAt ? { slotReboundAt: park.slotReboundAt } : {}),
|
|
248
|
+
...(park.preservedWorkspace ? { preservedWorkspace: park.preservedWorkspace } : {}),
|
|
249
|
+
restoreBeforeGateAnswer: needsGateParkRestore({ park }),
|
|
250
|
+
restoreStage: restoreStageView(park),
|
|
251
|
+
restoreTarget: {
|
|
252
|
+
slotId: verdict?.target.slotId ?? park.rehome?.toSlotId ?? park.slotId,
|
|
253
|
+
// The park's ORIGINAL slot, which the record no longer names once a
|
|
254
|
+
// re-home has moved `slotId`. `rehome.fromSlotId` is the only surviving
|
|
255
|
+
// record of it, so it wins over the record's current binding.
|
|
256
|
+
originalSlotId: verdict?.target.originalSlotId ?? park.rehome?.fromSlotId ?? park.slotId,
|
|
257
|
+
disposition: verdict?.target.disposition ?? disposition,
|
|
258
|
+
available: verdict ? verdict.target.available : null,
|
|
259
|
+
...(verdict?.eligibility ? { code: verdict.eligibility.code } : {}),
|
|
260
|
+
...(verdict?.eligibility ? { reason: verdict.eligibility.reason } : {}),
|
|
261
|
+
},
|
|
262
|
+
...(park.restoreRefusal ? { refusal: park.restoreRefusal } : {}),
|
|
263
|
+
...(proof
|
|
264
|
+
? {
|
|
265
|
+
workerProof: {
|
|
266
|
+
kind: proof.acknowledgement.kind,
|
|
267
|
+
reason: proof.acknowledgement.reason,
|
|
268
|
+
acceptedAt: proof.acceptedAt,
|
|
269
|
+
},
|
|
270
|
+
}
|
|
271
|
+
: {}),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* The gate park a client should render beside a run's gate, or `null` when
|
|
276
|
+
* there is nothing outstanding to say.
|
|
277
|
+
*
|
|
278
|
+
* A settled record is deliberately excluded: it describes a park the operator
|
|
279
|
+
* already resolved, and showing it beside a live gate reads as "this run is
|
|
280
|
+
* parked" when it is not.
|
|
281
|
+
*/
|
|
282
|
+
export function liveGateParkView(run, verdict) {
|
|
283
|
+
const view = gateParkView(run, verdict);
|
|
284
|
+
if (!view || view.slotState === 'settled')
|
|
285
|
+
return null;
|
|
286
|
+
return view;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Operator wording for the run's slot under its park.
|
|
290
|
+
*
|
|
291
|
+
* The sentences live here rather than in each client because the same claim has
|
|
292
|
+
* to read the same way in Command Center, Companion, and the CLI. A per-client
|
|
293
|
+
* copy is how "parked" came to mean the slot was gone on one surface and still
|
|
294
|
+
* held on another.
|
|
295
|
+
*/
|
|
296
|
+
export function gateParkStateLabel(view) {
|
|
297
|
+
if (view.slotState === 'retained')
|
|
298
|
+
return 'Parked, slot retained';
|
|
299
|
+
if (view.slotState === 'freeing')
|
|
300
|
+
return 'Parking, slot not freed yet';
|
|
301
|
+
// Neither partial says "parking": the park stopped, and the difference
|
|
302
|
+
// between the two is the only thing that tells the operator what to do next.
|
|
303
|
+
if (view.slotState === 'partial-answerable') {
|
|
304
|
+
return 'Park failed before the slot; worker still running';
|
|
305
|
+
}
|
|
306
|
+
if (view.slotState === 'partial-needs-restore')
|
|
307
|
+
return 'Park failed partway; needs a restore';
|
|
308
|
+
if (view.slotState === 'freed')
|
|
309
|
+
return 'Parked, slot freed for dispatch';
|
|
310
|
+
if (view.slotState === 'restoring')
|
|
311
|
+
return 'Restoring into its slot';
|
|
312
|
+
if (view.slotState === 'rehoming') {
|
|
313
|
+
return `Restoring into ${view.restoreTarget.slotId} (was ${view.restoreTarget.originalSlotId})`;
|
|
314
|
+
}
|
|
315
|
+
return 'Park settled';
|
|
316
|
+
}
|
|
317
|
+
/** One compact line: what the park did with the slot, the branch it preserved, what it still owes. */
|
|
318
|
+
export function gateParkSummaryLine(view) {
|
|
319
|
+
const target = view.restoreTarget;
|
|
320
|
+
const rehomed = target.slotId !== target.originalSlotId;
|
|
321
|
+
const parts = [
|
|
322
|
+
gateParkStateLabel(view),
|
|
323
|
+
// The slot the run is going to, and where it came from. A single `slot X`
|
|
324
|
+
// after a re-home named the NEW slot with no hint it had moved, which reads
|
|
325
|
+
// as if the park had always been there.
|
|
326
|
+
rehomed ? `slot ${target.slotId} (was ${target.originalSlotId})` : `slot ${view.slotId}`,
|
|
327
|
+
];
|
|
328
|
+
if (view.preservedWorkspace) {
|
|
329
|
+
const workspace = view.preservedWorkspace;
|
|
330
|
+
parts.push(`branch ${workspace.branch} at ${workspace.headSha}${workspace.detachedAt ? ' (detached)' : ''}`);
|
|
331
|
+
}
|
|
332
|
+
if (view.restoreStage.remaining.length && view.restoreStage.state !== 'not-started') {
|
|
333
|
+
parts.push(`restore owes ${view.restoreStage.remaining.join(', ')}`);
|
|
334
|
+
}
|
|
335
|
+
if (view.restoreStage.attempting)
|
|
336
|
+
parts.push(`attempting ${view.restoreStage.attempting}`);
|
|
337
|
+
if (view.workerProof)
|
|
338
|
+
parts.push(`worker ${view.workerProof.kind}`);
|
|
339
|
+
return parts.join(' · ');
|
|
340
|
+
}
|
|
341
|
+
export function gateParkGateNotice(view) {
|
|
342
|
+
if (!view)
|
|
343
|
+
return null;
|
|
344
|
+
if (view.slotState === 'freeing') {
|
|
345
|
+
return {
|
|
346
|
+
kind: 'park-in-flight',
|
|
347
|
+
blocking: true,
|
|
348
|
+
message: 'A free-slot park is still landing for this run, so its gate cannot be answered yet.',
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
if (view.slotState === 'partial-needs-restore') {
|
|
352
|
+
return {
|
|
353
|
+
kind: 'park-needs-restore',
|
|
354
|
+
blocking: true,
|
|
355
|
+
// Deliberately says what to DO. This park has stopped, so "wait" is the
|
|
356
|
+
// one instruction that cannot work, and it is what the old copy gave.
|
|
357
|
+
message: `A free-slot park failed partway and left an effect outstanding, so this gate cannot be answered until a restore settles it. Waiting will not clear it — restore the run into ${view.slotId}, or cancel it.`,
|
|
358
|
+
...(view.refusal ? { refusal: view.refusal } : {}),
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
if (view.slotState === 'partial-answerable') {
|
|
362
|
+
return {
|
|
363
|
+
kind: 'park-answerable',
|
|
364
|
+
blocking: false,
|
|
365
|
+
message: `A free-slot park failed before it reached ${view.slotId} and left the worker running, so this gate can be answered where it stands.`,
|
|
366
|
+
...(view.refusal ? { refusal: view.refusal } : {}),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
if (!view.restoreBeforeGateAnswer)
|
|
370
|
+
return null;
|
|
371
|
+
const target = view.restoreTarget;
|
|
372
|
+
// `available === null` is "not known", never "unavailable": only a Gateway
|
|
373
|
+
// verdict answers it, and treating an unread answer as a block would stand in
|
|
374
|
+
// the operator's way for a restore that would have succeeded.
|
|
375
|
+
//
|
|
376
|
+
// A recorded refusal is likewise not a current verdict. It says the LAST
|
|
377
|
+
// attempt refused, which is the best thing known only while nothing newer has
|
|
378
|
+
// looked; an `available: true` verdict is newer by construction, and letting
|
|
379
|
+
// a stale refusal outrank it blocks a restore the Gateway just approved.
|
|
380
|
+
if (target.available === false) {
|
|
381
|
+
return {
|
|
382
|
+
kind: 'restore-blocked',
|
|
383
|
+
blocking: true,
|
|
384
|
+
message: `Answering this gate restores the run into ${target.slotId} first, and the Gateway reports that slot cannot take it back.${target.reason ? ` ${target.reason}` : ''}`,
|
|
385
|
+
...(view.refusal ? { refusal: view.refusal } : {}),
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
if (target.available === null && view.refusal) {
|
|
389
|
+
return {
|
|
390
|
+
kind: 'restore-blocked',
|
|
391
|
+
blocking: true,
|
|
392
|
+
message: `Answering this gate restores the run into ${target.slotId} first, and the last restore attempt refused. Nothing has re-checked that slot since.`,
|
|
393
|
+
refusal: view.refusal,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
if (target.slotId !== target.originalSlotId) {
|
|
397
|
+
return {
|
|
398
|
+
kind: 'restore-first',
|
|
399
|
+
blocking: false,
|
|
400
|
+
// Says the slot MOVED, because the operator's attach target moves with
|
|
401
|
+
// it. A message naming only the new slot reads as if the park had been
|
|
402
|
+
// there all along, and one naming only the old sends them to a pane a
|
|
403
|
+
// successor owns.
|
|
404
|
+
message: `Answering this gate restores the run into ${target.slotId} first — ${target.originalSlotId} was taken — then resolves the decision.`,
|
|
405
|
+
...(view.refusal ? { refusal: view.refusal, refusalSuperseded: true } : {}),
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
kind: 'restore-first',
|
|
410
|
+
blocking: false,
|
|
411
|
+
message: `Answering this gate restores the run into ${target.slotId} first, then resolves the decision.`,
|
|
412
|
+
...(view.refusal ? { refusal: view.refusal, refusalSuperseded: true } : {}),
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
//# sourceMappingURL=gate-park.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-park.js","sourceRoot":"","sources":["../../src/contracts/gate-park.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,14 +6,18 @@ export * from './bug-score.js';
|
|
|
6
6
|
export * from './chat.js';
|
|
7
7
|
export * from './common.js';
|
|
8
8
|
export * from './config.js';
|
|
9
|
+
export * from './device-inventory.js';
|
|
9
10
|
export * from './dispatch.js';
|
|
10
11
|
export * from './evals.js';
|
|
11
12
|
export * from './execution-templates.js';
|
|
12
13
|
export * from './family.js';
|
|
14
|
+
export * from './gate-park.js';
|
|
13
15
|
export * from './interactive-operator-packets.js';
|
|
14
16
|
export * from './pr-recommendation.js';
|
|
17
|
+
export * from './pressure-admission.js';
|
|
15
18
|
export * from './provider-accounts.js';
|
|
16
19
|
export * from './recipes.js';
|
|
20
|
+
export * from './resource-posture.js';
|
|
17
21
|
export * from './resources.js';
|
|
18
22
|
export * from './reviews.js';
|
|
19
23
|
export * from './roadmap.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,mCAAmC,CAAC;AAClD,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mCAAmC,CAAC;AAClD,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC"}
|
package/dist/contracts/index.js
CHANGED
|
@@ -6,14 +6,18 @@ export * from './bug-score.js';
|
|
|
6
6
|
export * from './chat.js';
|
|
7
7
|
export * from './common.js';
|
|
8
8
|
export * from './config.js';
|
|
9
|
+
export * from './device-inventory.js';
|
|
9
10
|
export * from './dispatch.js';
|
|
10
11
|
export * from './evals.js';
|
|
11
12
|
export * from './execution-templates.js';
|
|
12
13
|
export * from './family.js';
|
|
14
|
+
export * from './gate-park.js';
|
|
13
15
|
export * from './interactive-operator-packets.js';
|
|
14
16
|
export * from './pr-recommendation.js';
|
|
17
|
+
export * from './pressure-admission.js';
|
|
15
18
|
export * from './provider-accounts.js';
|
|
16
19
|
export * from './recipes.js';
|
|
20
|
+
export * from './resource-posture.js';
|
|
17
21
|
export * from './resources.js';
|
|
18
22
|
export * from './reviews.js';
|
|
19
23
|
export * from './roadmap.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,mCAAmC,CAAC;AAClD,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mCAAmC,CAAC;AAClD,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { ProcessAttributionConfidence, ProcessOwnershipClass } from '../rpc/resources.js';
|
|
2
|
+
import type { HostPressureAdmissionMode } from './runtime-capabilities.js';
|
|
3
|
+
/**
|
|
4
|
+
* Dispatch admission has no queue: a machine under sustained pressure either
|
|
5
|
+
* accepts new dispatches or refuses them. Same vocabulary as the capability
|
|
6
|
+
* side so one word means one thing across both gates.
|
|
7
|
+
*/
|
|
8
|
+
export type DispatchPressureAdmissionMode = Exclude<HostPressureAdmissionMode, 'queue'>;
|
|
9
|
+
export declare const DISPATCH_PRESSURE_ADMISSION_MODES: readonly DispatchPressureAdmissionMode[];
|
|
10
|
+
/** Machine-level admission state derived from the bounded pressure sample
|
|
11
|
+
* ring. `disabled` means the gateway-owned switch is off — the DEFAULT: the
|
|
12
|
+
* dispatch is admitted whatever the evidence says, while the evidence itself
|
|
13
|
+
* is still evaluated and carried as an advisory, and sampling/history/charts
|
|
14
|
+
* continue. */
|
|
15
|
+
export type PressureAdmissionState = 'green' | 'transient' | 'sustained-critical' | 'unavailable' | 'stale' | 'override' | 'disabled';
|
|
16
|
+
/** Stable machine-readable rejection codes. Never rename — clients and
|
|
17
|
+
* operators key automation off these. */
|
|
18
|
+
export declare const PRESSURE_ADMISSION_REJECTION_CODES: readonly ["PRESSURE_SUSTAINED_CRITICAL", "PRESSURE_EVIDENCE_UNAVAILABLE", "PRESSURE_EVIDENCE_STALE", "PRESSURE_PREVIEW_STALE", "PRESSURE_OVERRIDE_STALE", "PRESSURE_OVERRIDE_MISMATCH", "PRESSURE_OVERRIDE_REASON_REQUIRED", "PRESSURE_OVERRIDE_CONSUMED"];
|
|
19
|
+
export type PressureAdmissionRejectionCode = (typeof PRESSURE_ADMISSION_REJECTION_CODES)[number];
|
|
20
|
+
/** One normalized sample from the bounded machine pressure ring. Ratios are
|
|
21
|
+
* 0..1 (load1 is load average over cores, so it can exceed 1). */
|
|
22
|
+
export interface PressureAdmissionSample {
|
|
23
|
+
collectedAt: string;
|
|
24
|
+
/** Process-inventory generation the sample was collected under, when known. */
|
|
25
|
+
generation?: string;
|
|
26
|
+
sampleId?: number;
|
|
27
|
+
cpu: number;
|
|
28
|
+
memory: number;
|
|
29
|
+
disk: number;
|
|
30
|
+
load1?: number;
|
|
31
|
+
/** True when this sample crossed the policy's critical thresholds. */
|
|
32
|
+
critical: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Attributed cause behind the pressure, from Goal 1 process attribution.
|
|
35
|
+
* Unknown/manual ownership can explain pressure but is never a cleanup target. */
|
|
36
|
+
export interface PressureAdmissionCause {
|
|
37
|
+
process: string;
|
|
38
|
+
processCount: number;
|
|
39
|
+
cpuPercent: number;
|
|
40
|
+
rssBytes: number;
|
|
41
|
+
classification: ProcessOwnershipClass;
|
|
42
|
+
confidence: ProcessAttributionConfidence;
|
|
43
|
+
slotId?: string;
|
|
44
|
+
runId?: string;
|
|
45
|
+
/** False for unknown/manual ownership — those rows must never be rendered as
|
|
46
|
+
* cleanup targets, only as explanation. */
|
|
47
|
+
cleanupEligible: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** Evidence backing an admission decision. `generation` is the preview
|
|
50
|
+
* identity: execution rejects decisions bound to a generation that no longer
|
|
51
|
+
* matches the current ring. */
|
|
52
|
+
export interface PressureAdmissionEvidence {
|
|
53
|
+
machine: string;
|
|
54
|
+
/** Opaque identity of the latest sample (generation/sampleId/collectedAt
|
|
55
|
+
* digest). Null when no sample exists — nothing to bind an override to. */
|
|
56
|
+
generation: string | null;
|
|
57
|
+
evaluatedAt: string;
|
|
58
|
+
/** Tail of the bounded ring the policy evaluated, oldest first. */
|
|
59
|
+
samples: PressureAdmissionSample[];
|
|
60
|
+
consecutiveCriticalSamples: number;
|
|
61
|
+
requiredConsecutiveCriticalSamples: number;
|
|
62
|
+
/** Milliseconds after which the newest sample counts as stale. */
|
|
63
|
+
staleAfterMs: number;
|
|
64
|
+
latestSampleAt: string | null;
|
|
65
|
+
/** Present when a validation-only fixture forced this machine's state.
|
|
66
|
+
* Real fleet evidence never carries this flag. */
|
|
67
|
+
validationFixture?: true;
|
|
68
|
+
}
|
|
69
|
+
/** Preview identity carried from an admitted preview into execution. FIND_SLOT
|
|
70
|
+
* validates it against fresh evidence BEFORE claiming a slot and, on success,
|
|
71
|
+
* consumes it by stamping `consumedAt` — so a long PREPARE cannot turn a
|
|
72
|
+
* green-to-green generation move into a failure at launch time. Execution
|
|
73
|
+
* still recomputes fresh evidence and rejects if pressure became unsafe; an
|
|
74
|
+
* UNconsumed ref reaching execution (a path that skipped FIND_SLOT
|
|
75
|
+
* validation) is rejected with PRESSURE_PREVIEW_STALE as defense in depth.
|
|
76
|
+
* `consumedAt` is gateway-stamped only; client-supplied values are stripped. */
|
|
77
|
+
export interface PressureAdmissionReference {
|
|
78
|
+
machine: string;
|
|
79
|
+
pressureGeneration: string;
|
|
80
|
+
consumedAt?: string;
|
|
81
|
+
}
|
|
82
|
+
/** One-dispatch operator override request. Bound to an exact machine and the
|
|
83
|
+
* pressure generation the operator saw; execution recomputes and rejects the
|
|
84
|
+
* override when the generation moved. */
|
|
85
|
+
export interface PressureDispatchOverride {
|
|
86
|
+
machine: string;
|
|
87
|
+
pressureGeneration: string;
|
|
88
|
+
reason: string;
|
|
89
|
+
}
|
|
90
|
+
/** Audit record stamped by the gateway when an override is accepted. */
|
|
91
|
+
export interface PressureOverrideAudit extends PressureDispatchOverride {
|
|
92
|
+
/** Authenticated principal that requested the override ('system' for
|
|
93
|
+
* in-process maintenance callers, which cannot originate from an ingress). */
|
|
94
|
+
principalId: string;
|
|
95
|
+
requestedAt: string;
|
|
96
|
+
/** An override never outlives the single dispatch it was issued for. */
|
|
97
|
+
scope: 'single-dispatch';
|
|
98
|
+
/**
|
|
99
|
+
* Durable consumption record, persisted at the launch gate BEFORE the
|
|
100
|
+
* runner starts (intent before effect). Bound to one exact DISPATCH engine
|
|
101
|
+
* attempt: a same-attempt provider retry sees its own attempt key and stays
|
|
102
|
+
* idempotent; a replay or new attempt rejects with
|
|
103
|
+
* PRESSURE_OVERRIDE_CONSUMED and needs a fresh override.
|
|
104
|
+
*/
|
|
105
|
+
consumed?: {
|
|
106
|
+
attemptKey: string;
|
|
107
|
+
consumedAt: string;
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* What the policy WOULD have rejected with, on a dispatch that was admitted
|
|
112
|
+
* anyway because the gate is switched off. Advisory only: nothing downstream
|
|
113
|
+
* may turn this into a refusal.
|
|
114
|
+
*/
|
|
115
|
+
export interface PressureAdmissionAdvisory {
|
|
116
|
+
code: PressureAdmissionRejectionCode;
|
|
117
|
+
/** Operator-facing reason. Backend-owned; clients render it verbatim. */
|
|
118
|
+
reason: string;
|
|
119
|
+
causes: PressureAdmissionCause[];
|
|
120
|
+
}
|
|
121
|
+
export interface PressureAdmissionAdmitted {
|
|
122
|
+
outcome: 'admitted';
|
|
123
|
+
machine: string;
|
|
124
|
+
state: Extract<PressureAdmissionState, 'green' | 'transient' | 'override' | 'disabled'>;
|
|
125
|
+
evidence: PressureAdmissionEvidence;
|
|
126
|
+
/** Present only when state='override': the accepted one-shot override. */
|
|
127
|
+
override?: PressureOverrideAudit;
|
|
128
|
+
/**
|
|
129
|
+
* Present ONLY on state='disabled': the gate is switched off, so this
|
|
130
|
+
* dispatch was admitted without enforcement. Distinguishes "evaluated and
|
|
131
|
+
* green" from "not enforced at all".
|
|
132
|
+
*/
|
|
133
|
+
enforced?: false;
|
|
134
|
+
/** Present when an unenforced decision would otherwise have been rejected. */
|
|
135
|
+
advisory?: PressureAdmissionAdvisory;
|
|
136
|
+
}
|
|
137
|
+
export interface PressureAdmissionRejected {
|
|
138
|
+
outcome: 'rejected';
|
|
139
|
+
machine: string;
|
|
140
|
+
state: Extract<PressureAdmissionState, 'sustained-critical' | 'unavailable' | 'stale'>;
|
|
141
|
+
code: PressureAdmissionRejectionCode;
|
|
142
|
+
/** Operator-facing reason. Backend-owned; clients render it verbatim. */
|
|
143
|
+
reason: string;
|
|
144
|
+
causes: PressureAdmissionCause[];
|
|
145
|
+
evidence: PressureAdmissionEvidence;
|
|
146
|
+
/** True when a fresh explicit override against `evidence.generation` can
|
|
147
|
+
* admit one dispatch. False for unavailable/stale evidence — fail closed. */
|
|
148
|
+
overridable: boolean;
|
|
149
|
+
}
|
|
150
|
+
export type PressureAdmissionDecision = PressureAdmissionAdmitted | PressureAdmissionRejected;
|
|
151
|
+
/** Gateway-owned durable switch for pressure-based dispatch prevention.
|
|
152
|
+
* Default DISABLED — sustained-pressure dispatch prevention is opt-in. Enabling
|
|
153
|
+
* turns on pressure rejection/override prompts; sampling, history, and charts
|
|
154
|
+
* run either way. Never affects slot ownership, capability, runner, branch, or
|
|
155
|
+
* other safety checks. */
|
|
156
|
+
export interface PressureAdmissionControlState {
|
|
157
|
+
enabled: boolean;
|
|
158
|
+
/** ISO timestamp of the last change; null when still at the default. */
|
|
159
|
+
updatedAt: string | null;
|
|
160
|
+
/** Authenticated principal that made the last change; null at the default. */
|
|
161
|
+
updatedBy: string | null;
|
|
162
|
+
/**
|
|
163
|
+
* Set when FARMSLOT_DISPATCH_PRESSURE_ADMISSION is exported on the gateway
|
|
164
|
+
* process. The env value WINS over the durable state above, which is still
|
|
165
|
+
* reported verbatim so an operator can see both.
|
|
166
|
+
*/
|
|
167
|
+
envOverride?: DispatchPressureAdmissionMode;
|
|
168
|
+
}
|
|
169
|
+
export interface PressureAdmissionSetEnabledParams {
|
|
170
|
+
enabled: boolean;
|
|
171
|
+
}
|
|
172
|
+
export type PressureAdmissionGetResult = PressureAdmissionControlState;
|
|
173
|
+
export type PressureAdmissionSetEnabledResult = PressureAdmissionControlState;
|
|
174
|
+
export declare function isPressureAdmissionRejected(decision: PressureAdmissionDecision | undefined): decision is PressureAdmissionRejected;
|
|
175
|
+
//# sourceMappingURL=pressure-admission.d.ts.map
|