@farmslot/protocol 0.21.0 → 0.26.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 +115 -0
- package/dist/contracts/agents.d.ts +33 -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 +4 -0
- package/dist/contracts/dispatch.d.ts.map +1 -1
- package/dist/contracts/execution-templates.d.ts +16 -0
- package/dist/contracts/execution-templates.d.ts.map +1 -1
- package/dist/contracts/execution-templates.js +6 -0
- package/dist/contracts/execution-templates.js.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 +8 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +8 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/pr-monitoring.d.ts +167 -0
- package/dist/contracts/pr-monitoring.d.ts.map +1 -0
- package/dist/contracts/pr-monitoring.js +2 -0
- package/dist/contracts/pr-monitoring.js.map +1 -0
- package/dist/contracts/pr-rules.d.ts +350 -0
- package/dist/contracts/pr-rules.d.ts.map +1 -0
- package/dist/contracts/pr-rules.js +6 -0
- package/dist/contracts/pr-rules.js.map +1 -0
- 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/readiness.d.ts +37 -0
- package/dist/contracts/readiness.d.ts.map +1 -0
- package/dist/contracts/readiness.js +8 -0
- package/dist/contracts/readiness.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 +3 -0
- package/dist/contracts/reviews.d.ts.map +1 -1
- package/dist/contracts/reviews.js.map +1 -1
- package/dist/contracts/runs.d.ts +501 -12
- package/dist/contracts/runs.d.ts.map +1 -1
- package/dist/contracts/runs.js +148 -5
- 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/contracts/template-placeholders.d.ts +16 -0
- package/dist/contracts/template-placeholders.d.ts.map +1 -0
- package/dist/contracts/template-placeholders.js +39 -0
- package/dist/contracts/template-placeholders.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/integrations/pr-monitoring.d.ts +13 -0
- package/dist/integrations/pr-monitoring.d.ts.map +1 -0
- package/dist/integrations/pr-monitoring.js +160 -0
- package/dist/integrations/pr-monitoring.js.map +1 -0
- package/dist/integrations/pr-project-import.d.ts +12 -0
- package/dist/integrations/pr-project-import.d.ts.map +1 -0
- package/dist/integrations/pr-project-import.js +279 -0
- package/dist/integrations/pr-project-import.js.map +1 -0
- package/dist/integrations/pr-review-requirements.d.ts +4 -0
- package/dist/integrations/pr-review-requirements.d.ts.map +1 -0
- package/dist/integrations/pr-review-requirements.js +21 -0
- package/dist/integrations/pr-review-requirements.js.map +1 -0
- package/dist/integrations/pr-rule-config.d.ts +6 -0
- package/dist/integrations/pr-rule-config.d.ts.map +1 -0
- package/dist/integrations/pr-rule-config.js +217 -0
- package/dist/integrations/pr-rule-config.js.map +1 -0
- package/dist/integrations/pr-rule-predicates.d.ts +9 -0
- package/dist/integrations/pr-rule-predicates.d.ts.map +1 -0
- package/dist/integrations/pr-rule-predicates.js +223 -0
- package/dist/integrations/pr-rule-predicates.js.map +1 -0
- package/dist/recipes/step-io.d.ts +10 -1
- package/dist/recipes/step-io.d.ts.map +1 -1
- package/dist/rpc/backlog.d.ts +2 -2
- package/dist/rpc/backlog.d.ts.map +1 -1
- package/dist/rpc/backlog.js +2 -1
- package/dist/rpc/backlog.js.map +1 -1
- package/dist/rpc/config.d.ts +22 -2
- package/dist/rpc/config.d.ts.map +1 -1
- package/dist/rpc/config.js +1 -0
- package/dist/rpc/config.js.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 +7 -0
- package/dist/rpc/index.d.ts.map +1 -1
- package/dist/rpc/index.js +7 -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/native-session.d.ts +193 -0
- package/dist/rpc/native-session.d.ts.map +1 -0
- package/dist/rpc/native-session.js +2 -0
- package/dist/rpc/native-session.js.map +1 -0
- package/dist/rpc/pr-push.d.ts +56 -0
- package/dist/rpc/pr-push.d.ts.map +1 -0
- package/dist/rpc/pr-push.js +2 -0
- package/dist/rpc/pr-push.js.map +1 -0
- package/dist/rpc/pr-rules.d.ts +72 -0
- package/dist/rpc/pr-rules.d.ts.map +1 -0
- package/dist/rpc/pr-rules.js +2 -0
- package/dist/rpc/pr-rules.js.map +1 -0
- package/dist/rpc/pr-watch.d.ts +43 -0
- package/dist/rpc/pr-watch.d.ts.map +1 -0
- package/dist/rpc/pr-watch.js +2 -0
- package/dist/rpc/pr-watch.js.map +1 -0
- package/dist/rpc/registry.d.ts +56 -0
- package/dist/rpc/registry.d.ts.map +1 -1
- package/dist/rpc/registry.js +57 -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/roadmap.d.ts +1 -1
- package/dist/rpc/roadmap.d.ts.map +1 -1
- package/dist/rpc/roadmap.js +2 -1
- package/dist/rpc/roadmap.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/rpc/worker-session-history.d.ts +1 -1
- package/dist/rpc/worker-session-history.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/runs/interactive-handoff.d.ts +14 -0
- package/dist/runs/interactive-handoff.d.ts.map +1 -0
- package/dist/runs/interactive-handoff.js +69 -0
- package/dist/runs/interactive-handoff.js.map +1 -0
- package/dist/runs/portable-bundle.d.ts +2 -0
- package/dist/runs/portable-bundle.d.ts.map +1 -1
- package/dist/runs/portable-bundle.js +14 -1
- package/dist/runs/portable-bundle.js.map +1 -1
- package/dist/runs/review-chain.d.ts +3 -2
- package/dist/runs/review-chain.d.ts.map +1 -1
- package/dist/runs/review-chain.js +4 -2
- package/dist/runs/review-chain.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 +19 -2
- package/dist/transport/events.d.ts.map +1 -1
- package/dist/transport/events.js +6 -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,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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pressure-admission.d.ts","sourceRoot":"","sources":["../../src/contracts/pressure-admission.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Sustained-pressure dispatch admission contract (MANUAL-000109).
|
|
2
|
+
//
|
|
3
|
+
// One backend-owned decision shared by dispatch preview, automatic slot
|
|
4
|
+
// selection, and dispatch execution. Clients render these decisions and never
|
|
5
|
+
// re-derive thresholds. The evidence is the Goal 1 node-pressure history and
|
|
6
|
+
// process attribution — no dispatch-side sampler exists.
|
|
7
|
+
export const DISPATCH_PRESSURE_ADMISSION_MODES = [
|
|
8
|
+
'off',
|
|
9
|
+
'refuse',
|
|
10
|
+
];
|
|
11
|
+
/** Stable machine-readable rejection codes. Never rename — clients and
|
|
12
|
+
* operators key automation off these. */
|
|
13
|
+
export const PRESSURE_ADMISSION_REJECTION_CODES = [
|
|
14
|
+
'PRESSURE_SUSTAINED_CRITICAL',
|
|
15
|
+
'PRESSURE_EVIDENCE_UNAVAILABLE',
|
|
16
|
+
'PRESSURE_EVIDENCE_STALE',
|
|
17
|
+
'PRESSURE_PREVIEW_STALE',
|
|
18
|
+
'PRESSURE_OVERRIDE_STALE',
|
|
19
|
+
'PRESSURE_OVERRIDE_MISMATCH',
|
|
20
|
+
'PRESSURE_OVERRIDE_REASON_REQUIRED',
|
|
21
|
+
'PRESSURE_OVERRIDE_CONSUMED',
|
|
22
|
+
];
|
|
23
|
+
export function isPressureAdmissionRejected(decision) {
|
|
24
|
+
return decision?.outcome === 'rejected';
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=pressure-admission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pressure-admission.js","sourceRoot":"","sources":["../../src/contracts/pressure-admission.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,wEAAwE;AACxE,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AAazD,MAAM,CAAC,MAAM,iCAAiC,GAA6C;IACzF,KAAK;IACL,QAAQ;CACT,CAAC;AAgBF;yCACyC;AACzC,MAAM,CAAC,MAAM,kCAAkC,GAAG;IAChD,6BAA6B;IAC7B,+BAA+B;IAC/B,yBAAyB;IACzB,wBAAwB;IACxB,yBAAyB;IACzB,4BAA4B;IAC5B,mCAAmC;IACnC,4BAA4B;CACpB,CAAC;AA2KX,MAAM,UAAU,2BAA2B,CACzC,QAA+C;IAE/C,OAAO,QAAQ,EAAE,OAAO,KAAK,UAAU,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readiness record: what a harness did to make a checkout ready for a task and
|
|
3
|
+
* whether it succeeded. Farmslot defines the shape; a harness (mm-harness) fills
|
|
4
|
+
* the steps. Lives at `<artifacts dir>/sandbox.json` — the task's `artifacts/`
|
|
5
|
+
* for a skill run, the checkout runtime dir for a farm slot.
|
|
6
|
+
*/
|
|
7
|
+
export declare const READINESS_RECORD = "sandbox.json";
|
|
8
|
+
export type ReadinessStepStatus = 'pass' | 'fail' | 'skipped';
|
|
9
|
+
export interface ReadinessStep {
|
|
10
|
+
/** Stable step id, e.g. `doctor`, `status`, `launch`, `fixtures`, `verify`. */
|
|
11
|
+
id: string;
|
|
12
|
+
/** The exact command line the harness ran. */
|
|
13
|
+
command: string;
|
|
14
|
+
status: ReadinessStepStatus;
|
|
15
|
+
exitCode: number;
|
|
16
|
+
/** Report the step produced, relative to the record's directory, when it wrote one. */
|
|
17
|
+
reportPath?: string;
|
|
18
|
+
/** One-line reason for a fail or skip. */
|
|
19
|
+
reason?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ReadinessRecord {
|
|
22
|
+
schemaVersion: 1;
|
|
23
|
+
harness: {
|
|
24
|
+
name: string;
|
|
25
|
+
version: string;
|
|
26
|
+
/** How the executable was chosen: env override, task-local lock, PATH, … */
|
|
27
|
+
source: string;
|
|
28
|
+
executable: string;
|
|
29
|
+
};
|
|
30
|
+
platform: string;
|
|
31
|
+
mobilePlatform?: 'ios' | 'android';
|
|
32
|
+
steps: ReadinessStep[];
|
|
33
|
+
/** True when every non-skipped step passed. */
|
|
34
|
+
ready: boolean;
|
|
35
|
+
recordedAt: string;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=readiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.d.ts","sourceRoot":"","sources":["../../src/contracts/readiness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,4EAA4E;QAC5E,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,+CAA+C;IAC/C,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Readiness record: what a harness did to make a checkout ready for a task and
|
|
3
|
+
* whether it succeeded. Farmslot defines the shape; a harness (mm-harness) fills
|
|
4
|
+
* the steps. Lives at `<artifacts dir>/sandbox.json` — the task's `artifacts/`
|
|
5
|
+
* for a skill run, the checkout runtime dir for a farm slot.
|
|
6
|
+
*/
|
|
7
|
+
export const READINESS_RECORD = 'sandbox.json';
|
|
8
|
+
//# sourceMappingURL=readiness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readiness.js","sourceRoot":"","sources":["../../src/contracts/readiness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC"}
|
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run resource posture (ADR-054).
|
|
3
|
+
*
|
|
4
|
+
* The Gateway owns one semantic posture per run describing which runtime
|
|
5
|
+
* capabilities should be live at the current lifecycle boundary. Clients render
|
|
6
|
+
* the Gateway's decision — desired disposition, observed provider state, the
|
|
7
|
+
* winning policy source — and never resolve policy themselves.
|
|
8
|
+
*/
|
|
9
|
+
import type { DeviceInventoryKey } from './device-inventory.js';
|
|
10
|
+
import type { MachinePauseEligibilityDetails } from './runs.js';
|
|
11
|
+
import type { RuntimeCapabilityAcquireConflict, RuntimeCapabilityClaimScope, RuntimeCapabilityHealthState, RuntimeCapabilityLeaseOwner, RuntimeCapabilityLeaseState, RuntimeCapabilityTarget } from './runtime-capabilities.js';
|
|
12
|
+
/**
|
|
13
|
+
* The lease fields `observedStateForLease` reads. Structural so this module
|
|
14
|
+
* stays free of a value-level dependency on the lease type.
|
|
15
|
+
*/
|
|
16
|
+
export interface RuntimeCapabilityLeaseLike {
|
|
17
|
+
state: RuntimeCapabilityLeaseState;
|
|
18
|
+
health: {
|
|
19
|
+
state: RuntimeCapabilityHealthState;
|
|
20
|
+
};
|
|
21
|
+
keepWarmUntil?: string;
|
|
22
|
+
cleanupFailure?: string;
|
|
23
|
+
}
|
|
24
|
+
/** Semantic lifecycle intent. Never derived from run status, step names, or slot phases. */
|
|
25
|
+
export declare const RESOURCE_POSTURES: readonly ["active", "operator-wait", "parked", "terminal"];
|
|
26
|
+
export type ResourcePosture = (typeof RESOURCE_POSTURES)[number];
|
|
27
|
+
/** Operator vocabulary at a human gate; each resolves to a posture plus proof plan. */
|
|
28
|
+
export declare const RESOURCE_POSTURE_GATE_CHOICES: readonly ["keep-for-validation", "minimize", "free-slot", "project-default"];
|
|
29
|
+
export type ResourcePostureGateChoice = (typeof RESOURCE_POSTURE_GATE_CHOICES)[number];
|
|
30
|
+
/**
|
|
31
|
+
* Dispatch-time preset for every durable wait of a run. `project-default` is
|
|
32
|
+
* excluded: a preset that defers to the lower precedence levels is a no-op, and
|
|
33
|
+
* omitting the field already expresses it.
|
|
34
|
+
*/
|
|
35
|
+
export declare const RESOURCE_POSTURE_WAIT_POLICIES: readonly ["keep-for-validation", "minimize", "free-slot"];
|
|
36
|
+
export type ResourcePostureWaitPolicy = (typeof RESOURCE_POSTURE_WAIT_POLICIES)[number];
|
|
37
|
+
/** Which precedence level produced the effective policy. */
|
|
38
|
+
export declare const RESOURCE_POSTURE_POLICY_SOURCES: readonly ["gate-choice", "run-dispatch", "project-default", "framework-default"];
|
|
39
|
+
export type ResourcePosturePolicySource = (typeof RESOURCE_POSTURE_POLICY_SOURCES)[number];
|
|
40
|
+
/** What the Gateway intends for a capability. Distinct from what is observed. */
|
|
41
|
+
export declare const RESOURCE_POSTURE_DISPOSITIONS: readonly ["acquired", "warm", "stopped"];
|
|
42
|
+
export type ResourcePostureDesiredDisposition = (typeof RESOURCE_POSTURE_DISPOSITIONS)[number];
|
|
43
|
+
/**
|
|
44
|
+
* What the provider is actually doing. A released lease with a live keep-warm
|
|
45
|
+
* provider is `running`, not `stopped`.
|
|
46
|
+
*/
|
|
47
|
+
export declare const RESOURCE_POSTURE_OBSERVED_STATES: readonly ["running", "stopped", "unhealthy", "transitioning", "unknown"];
|
|
48
|
+
export type ResourcePostureObservedState = (typeof RESOURCE_POSTURE_OBSERVED_STATES)[number];
|
|
49
|
+
/** Per-provider project retention policy for a posture. */
|
|
50
|
+
export declare const RESOURCE_POSTURE_RETENTIONS: readonly ["retain", "warm", "stop"];
|
|
51
|
+
export type ResourcePostureRetention = (typeof RESOURCE_POSTURE_RETENTIONS)[number];
|
|
52
|
+
/**
|
|
53
|
+
* Postures a project may configure retention for. `active` is derived from the
|
|
54
|
+
* current proof plan and `parked` delegates to machine parking, so neither
|
|
55
|
+
* accepts a retention override.
|
|
56
|
+
*/
|
|
57
|
+
export declare const RESOURCE_POSTURE_RETENTION_BOUNDARIES: readonly ["operator-wait", "terminal"];
|
|
58
|
+
export type ResourcePostureRetentionBoundary = (typeof RESOURCE_POSTURE_RETENTION_BOUNDARIES)[number];
|
|
59
|
+
/** Project-level posture defaults; per-provider `retention` overrides these. */
|
|
60
|
+
export interface ProjectResourcePostureConfig {
|
|
61
|
+
defaults?: Partial<Record<ResourcePostureRetentionBoundary, ResourcePostureRetention>>;
|
|
62
|
+
}
|
|
63
|
+
export interface ResourcePostureCapabilityState {
|
|
64
|
+
capabilityId: string;
|
|
65
|
+
desiredDisposition: ResourcePostureDesiredDisposition;
|
|
66
|
+
observedState: ResourcePostureObservedState;
|
|
67
|
+
policySource: ResourcePosturePolicySource;
|
|
68
|
+
reason: string;
|
|
69
|
+
leaseId?: string;
|
|
70
|
+
owner?: RuntimeCapabilityLeaseOwner;
|
|
71
|
+
/**
|
|
72
|
+
* The device identity the holding lease actually resolved to, when the
|
|
73
|
+
* provider takes one. Read off the lease's stored acquire parameters, so a
|
|
74
|
+
* client shows the device that is really in use rather than the slot's
|
|
75
|
+
* configured default after a re-target.
|
|
76
|
+
*/
|
|
77
|
+
target?: RuntimeCapabilityTarget;
|
|
78
|
+
/** Deadline until which a released provider stays live. */
|
|
79
|
+
warmUntil?: string;
|
|
80
|
+
lastTransitionAt?: string;
|
|
81
|
+
releaseEffects: string[];
|
|
82
|
+
cleanupFailure?: string;
|
|
83
|
+
}
|
|
84
|
+
export type ResourcePostureRejection = {
|
|
85
|
+
kind: 'park-ineligible';
|
|
86
|
+
/** Machine-parking eligibility code, passed through unchanged. */
|
|
87
|
+
code: string;
|
|
88
|
+
reason: string;
|
|
89
|
+
/** Structured facts for the code, passed through unchanged. */
|
|
90
|
+
details?: MachinePauseEligibilityDetails;
|
|
91
|
+
} | {
|
|
92
|
+
kind: 'capability-unavailable';
|
|
93
|
+
capabilityId: string;
|
|
94
|
+
reason: string;
|
|
95
|
+
conflict: RuntimeCapabilityAcquireConflict;
|
|
96
|
+
} | {
|
|
97
|
+
/**
|
|
98
|
+
* A re-target named a device the slot's machine does not have
|
|
99
|
+
* (MANUAL-000124). Refused BEFORE the run's current device is released,
|
|
100
|
+
* so a typo costs the run nothing.
|
|
101
|
+
*/
|
|
102
|
+
kind: 'device-unknown';
|
|
103
|
+
capabilityId: string;
|
|
104
|
+
/** The machine whose inventory was read. Device names are machine-scoped. */
|
|
105
|
+
machine: string;
|
|
106
|
+
/** The device-identity key the target named. */
|
|
107
|
+
key: DeviceInventoryKey;
|
|
108
|
+
identity: string;
|
|
109
|
+
/** Identities of the same key the machine does have, nearest first. */
|
|
110
|
+
nearest: string[];
|
|
111
|
+
reason: string;
|
|
112
|
+
} | {
|
|
113
|
+
kind: 'invalid-request';
|
|
114
|
+
reason: string;
|
|
115
|
+
};
|
|
116
|
+
export declare const RESOURCE_POSTURE_TRANSITION_OUTCOMES: readonly ["in-progress", "applied", "idempotent", "partial", "rejected", "failed"];
|
|
117
|
+
export type ResourcePostureTransitionOutcome = (typeof RESOURCE_POSTURE_TRANSITION_OUTCOMES)[number];
|
|
118
|
+
export interface ResourcePostureTransitionFailure {
|
|
119
|
+
capabilityId: string;
|
|
120
|
+
leaseId?: string;
|
|
121
|
+
reason: string;
|
|
122
|
+
}
|
|
123
|
+
export interface ResourcePostureTransition {
|
|
124
|
+
/** Caller-supplied `operationId` when present, so a replay returns this record. */
|
|
125
|
+
id: string;
|
|
126
|
+
posture: ResourcePosture;
|
|
127
|
+
policySource: ResourcePosturePolicySource;
|
|
128
|
+
gateChoice?: ResourcePostureGateChoice;
|
|
129
|
+
requestedAt: string;
|
|
130
|
+
completedAt?: string;
|
|
131
|
+
outcome: ResourcePostureTransitionOutcome;
|
|
132
|
+
effects: string[];
|
|
133
|
+
progress: {
|
|
134
|
+
total: number;
|
|
135
|
+
completed: number;
|
|
136
|
+
};
|
|
137
|
+
failures: ResourcePostureTransitionFailure[];
|
|
138
|
+
rejection?: ResourcePostureRejection;
|
|
139
|
+
}
|
|
140
|
+
/** Exact effect of applying a posture, returned before an operator commits. */
|
|
141
|
+
export interface ResourcePosturePlan {
|
|
142
|
+
runId: string;
|
|
143
|
+
slotId: string | null;
|
|
144
|
+
posture: ResourcePosture;
|
|
145
|
+
policySource: ResourcePosturePolicySource;
|
|
146
|
+
reason: string;
|
|
147
|
+
acquire: ResourcePostureCapabilityState[];
|
|
148
|
+
retain: ResourcePostureCapabilityState[];
|
|
149
|
+
warm: ResourcePostureCapabilityState[];
|
|
150
|
+
stop: ResourcePostureCapabilityState[];
|
|
151
|
+
/** Declared release effects of everything this plan would stop. */
|
|
152
|
+
effects: string[];
|
|
153
|
+
rejection?: ResourcePostureRejection;
|
|
154
|
+
}
|
|
155
|
+
/** Persisted on the run so a reconnecting client sees the same thing. */
|
|
156
|
+
export interface RunResourcePostureState {
|
|
157
|
+
posture: ResourcePosture;
|
|
158
|
+
policySource: ResourcePosturePolicySource;
|
|
159
|
+
gateChoice?: ResourcePostureGateChoice;
|
|
160
|
+
/**
|
|
161
|
+
* The run generation a `machine.pause.restore` replay took ownership at, when
|
|
162
|
+
* that restore re-presented a gate whose stored choice would re-park the run.
|
|
163
|
+
*
|
|
164
|
+
* Without it a run whose stored choice is `free-slot` re-parks itself the
|
|
165
|
+
* instant restore re-presents its gate: the replayed gate reaches the
|
|
166
|
+
* operator-wait boundary, the stored choice is carried forward, and the run
|
|
167
|
+
* parks again before the operator ever sees it. The restored gate therefore
|
|
168
|
+
* falls back to the framework default once; choosing `free-slot` again is
|
|
169
|
+
* still available, it just has to be chosen rather than inherited.
|
|
170
|
+
*
|
|
171
|
+
* Keyed on the GENERATION rather than a bare flag so it cannot outlive the
|
|
172
|
+
* gate it was set for. The replay is fire-and-forget: if it never reaches a
|
|
173
|
+
* wait boundary, a bare flag would sit on the run and silently swallow the
|
|
174
|
+
* operator's choice at some unrelated later wait. A generation that has moved
|
|
175
|
+
* on makes the suppression simply not apply.
|
|
176
|
+
*
|
|
177
|
+
* Cleared by the first wait boundary after it is set, whether or not that
|
|
178
|
+
* boundary carried an explicit choice — an operator who answers the restored
|
|
179
|
+
* gate consumes it just as an inheriting wait does.
|
|
180
|
+
*/
|
|
181
|
+
gateChoiceSuppressedForGeneration?: number;
|
|
182
|
+
waitPolicy?: ResourcePostureWaitPolicy;
|
|
183
|
+
capabilities: ResourcePostureCapabilityState[];
|
|
184
|
+
/**
|
|
185
|
+
* The scoped resource claim this run is queued behind, while it is queued.
|
|
186
|
+
*
|
|
187
|
+
* Derived from the last transition's rejection rather than written
|
|
188
|
+
* separately, so it cannot outlive the wait it describes. A later transition
|
|
189
|
+
* that is not a scoped wait clears it. The work-graph reads this to report
|
|
190
|
+
* the node as `waitingOn.kind: 'resource'`.
|
|
191
|
+
*/
|
|
192
|
+
resourceWait?: RunResourceWait;
|
|
193
|
+
/** ADR-038: no posture resolved here stops a gate-held worker. */
|
|
194
|
+
workerRetained: boolean;
|
|
195
|
+
lastTransition?: ResourcePostureTransition;
|
|
196
|
+
/**
|
|
197
|
+
* Recent transitions, newest first, bounded by
|
|
198
|
+
* `RESOURCE_POSTURE_TRANSITION_HISTORY`. Replaying an `operationId` returns the
|
|
199
|
+
* stored outcome for any id still in here, so a retry of an earlier operation
|
|
200
|
+
* cannot re-execute and undo a later one.
|
|
201
|
+
*/
|
|
202
|
+
recentTransitions?: ResourcePostureTransition[];
|
|
203
|
+
updatedAt: string;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* How far along a run's place in a scoped claim's queue is.
|
|
207
|
+
*
|
|
208
|
+
* `queued` is waiting its turn behind a holder. `granted` is the reservation
|
|
209
|
+
* the drain hands the head waiter: the claim is now held for this run and no
|
|
210
|
+
* provider has booted for it yet, so the run is not waiting on anyone else —
|
|
211
|
+
* it is waiting on its own completion. The two are reported separately because
|
|
212
|
+
* a `granted` wait that never clears is a stranded claim nobody else can take,
|
|
213
|
+
* and reporting nothing at all is how that used to stay invisible.
|
|
214
|
+
*/
|
|
215
|
+
export declare const RUN_RESOURCE_WAIT_PHASES: readonly ["queued", "granted"];
|
|
216
|
+
export type RunResourceWaitPhase = (typeof RUN_RESOURCE_WAIT_PHASES)[number];
|
|
217
|
+
/**
|
|
218
|
+
* A run's durable place in a scoped claim's queue.
|
|
219
|
+
*
|
|
220
|
+
* `position` is a snapshot from the moment the acquire was refused, not a live
|
|
221
|
+
* counter: nothing renumbers a queue, and re-deriving it here would need the
|
|
222
|
+
* whole fleet's leases on every read of a run. A `granted` wait is past the
|
|
223
|
+
* queue entirely and reports position 0.
|
|
224
|
+
*/
|
|
225
|
+
export interface RunResourceWait {
|
|
226
|
+
capabilityId: string;
|
|
227
|
+
claimId: string;
|
|
228
|
+
scope: RuntimeCapabilityClaimScope;
|
|
229
|
+
phase: RunResourceWaitPhase;
|
|
230
|
+
/** The run holding the claim, which is usually on another slot. */
|
|
231
|
+
blockingOwner: RuntimeCapabilityLeaseOwner;
|
|
232
|
+
/** The queued lease that holds this run's place in line. */
|
|
233
|
+
queuedLeaseId: string;
|
|
234
|
+
/** 1-based place in line, or 0 once the claim is reserved for this run. */
|
|
235
|
+
position: number;
|
|
236
|
+
since: string;
|
|
237
|
+
reason: string;
|
|
238
|
+
}
|
|
239
|
+
/** How many transitions a run keeps for operation-id replay. */
|
|
240
|
+
export declare const RESOURCE_POSTURE_TRANSITION_HISTORY = 20;
|
|
241
|
+
/** Gate choice -> posture. The only place this mapping exists. */
|
|
242
|
+
export declare function postureForGateChoice(choice: Exclude<ResourcePostureGateChoice, 'project-default'>): ResourcePosture;
|
|
243
|
+
/**
|
|
244
|
+
* The single derivation of a provider's observed state from its lease.
|
|
245
|
+
*
|
|
246
|
+
* Shared so the Gateway and every client answer "is this provider running?"
|
|
247
|
+
* identically. A client that re-derives this locally will drift — Slot View
|
|
248
|
+
* once decided an elapsed warm deadline meant `stopped` while the Gateway
|
|
249
|
+
* reported `unknown`, which labels a live provider as dead.
|
|
250
|
+
*
|
|
251
|
+
* `nowMs` is passed in so the caller evaluates the warm deadline against the
|
|
252
|
+
* same instant it rendered with.
|
|
253
|
+
*/
|
|
254
|
+
export declare function observedStateForLease(lease: RuntimeCapabilityLeaseLike | undefined, nowMs: number): ResourcePostureObservedState;
|
|
255
|
+
export declare function isResourcePosture(value: unknown): value is ResourcePosture;
|
|
256
|
+
export declare function isResourcePostureGateChoice(value: unknown): value is ResourcePostureGateChoice;
|
|
257
|
+
export declare function isResourcePostureWaitPolicy(value: unknown): value is ResourcePostureWaitPolicy;
|
|
258
|
+
/**
|
|
259
|
+
* How the observed provider state stands against what the Gateway wanted.
|
|
260
|
+
*
|
|
261
|
+
* `unproven` is deliberately not folded into `mismatch` or `matches`: an
|
|
262
|
+
* `unknown` observation means the Gateway could not see the provider, and
|
|
263
|
+
* claiming either outcome from it would be a guess.
|
|
264
|
+
*/
|
|
265
|
+
export type ResourcePostureRowStatus = 'matches' | 'pending' | 'mismatch' | 'unproven';
|
|
266
|
+
/**
|
|
267
|
+
* The single comparison of desired disposition against observed provider state.
|
|
268
|
+
*
|
|
269
|
+
* Shared so Command Center, Companion, and the CLI agree on when the Gateway
|
|
270
|
+
* got what it asked for. A client that re-derives this locally drifts, and the
|
|
271
|
+
* drift is always in the same direction: reporting a provider as handled when
|
|
272
|
+
* nothing observed it.
|
|
273
|
+
*/
|
|
274
|
+
export declare function resourcePostureRowStatus(desired: ResourcePostureDesiredDisposition, observed: ResourcePostureObservedState): ResourcePostureRowStatus;
|
|
275
|
+
/**
|
|
276
|
+
* Counts of what the providers are observed to be doing, not of what was
|
|
277
|
+
* wanted. `stopped` requires an observed `stopped`: a provider the Gateway
|
|
278
|
+
* intended to stop but which is still running, or whose cleanup failed, must
|
|
279
|
+
* never be counted as stopped. Anything the Gateway cannot currently place —
|
|
280
|
+
* unknown, transitioning, or contradicting its intent — lands in `unresolved`
|
|
281
|
+
* so the buckets always account for every capability instead of quietly
|
|
282
|
+
* dropping one.
|
|
283
|
+
*/
|
|
284
|
+
export interface ResourcePostureCounts {
|
|
285
|
+
retained: number;
|
|
286
|
+
warm: number;
|
|
287
|
+
stopped: number;
|
|
288
|
+
failed: number;
|
|
289
|
+
unresolved: number;
|
|
290
|
+
}
|
|
291
|
+
export declare function resourcePostureCounts(capabilities: readonly ResourcePostureCapabilityState[], lastTransition?: ResourcePostureTransition): ResourcePostureCounts;
|
|
292
|
+
/**
|
|
293
|
+
* Transition failures that are not already reported on a capability entry.
|
|
294
|
+
*
|
|
295
|
+
* A failed cleanup lands in both places: the transition's failure list and the
|
|
296
|
+
* capability's own `cleanupFailure`. Reporting both gives the operator the same
|
|
297
|
+
* alert twice. The capability entry wins — it sits next to that capability's
|
|
298
|
+
* desired and observed state, which is the context needed to act on it.
|
|
299
|
+
*
|
|
300
|
+
* The match is on capability AND reason. The Gateway reports a failure per
|
|
301
|
+
* lease while a capability entry carries one reason, so suppressing every
|
|
302
|
+
* failure for a capability that had any entry failure would silently drop a
|
|
303
|
+
* sibling lease's different failure — the one case where the transition list is
|
|
304
|
+
* the only place that failure is reported at all.
|
|
305
|
+
*/
|
|
306
|
+
export declare function resourcePostureTransitionFailuresToShow(capabilities: readonly Pick<ResourcePostureCapabilityState, 'capabilityId' | 'cleanupFailure'>[], lastTransition?: ResourcePostureTransition): ResourcePostureTransitionFailure[];
|
|
307
|
+
/**
|
|
308
|
+
* Outcomes that end a transition. `in-progress` is deliberately absent: it is a
|
|
309
|
+
* wait, not an answer, and adopting it reports a reconciliation that can still
|
|
310
|
+
* fail as the operator's result.
|
|
311
|
+
*
|
|
312
|
+
* This is an allowlist rather than `!== 'in-progress'` so a new outcome added to
|
|
313
|
+
* the protocol is treated as non-terminal until it is considered here. The
|
|
314
|
+
* inverse defaults a new outcome to terminal on whichever client happens to
|
|
315
|
+
* update last, which is the wrong direction to fail in.
|
|
316
|
+
*/
|
|
317
|
+
export declare const RESOURCE_POSTURE_TERMINAL_OUTCOMES: readonly ResourcePostureTransitionOutcome[];
|
|
318
|
+
export declare function isTerminalResourcePostureOutcome(outcome: ResourcePostureTransitionOutcome): boolean;
|
|
319
|
+
/** How many status reads a client waits through before reporting reconciliation pending. */
|
|
320
|
+
export declare const RESOURCE_POSTURE_TRANSITION_POLL_LIMIT = 10;
|
|
321
|
+
/**
|
|
322
|
+
* What a client knew before it sent a resolution, so the answer can be told
|
|
323
|
+
* apart from what was already there.
|
|
324
|
+
*/
|
|
325
|
+
export interface ResourcePostureTransitionBaseline {
|
|
326
|
+
/** Transition ids the Gateway had already recorded. */
|
|
327
|
+
transitionIds: readonly string[];
|
|
328
|
+
/**
|
|
329
|
+
* Newest `requestedAt` among those, in the Gateway's own clock. Recency is
|
|
330
|
+
* compared Gateway-to-Gateway; a client clock never enters the comparison.
|
|
331
|
+
*/
|
|
332
|
+
newestRequestedAt: string | undefined;
|
|
333
|
+
/** The gate choice the client forwarded, when it forwarded one. */
|
|
334
|
+
choice: ResourcePostureGateChoice | null;
|
|
335
|
+
}
|
|
336
|
+
/** The records to correlate over, newest first, as the protocol persists them. */
|
|
337
|
+
export declare function resourcePostureTransitions(state: Pick<RunResourcePostureState, 'recentTransitions' | 'lastTransition'> | undefined): readonly ResourcePostureTransition[];
|
|
338
|
+
export declare function resourcePostureTransitionBaseline(state: Pick<RunResourcePostureState, 'recentTransitions' | 'lastTransition'> | undefined, choice: ResourcePostureGateChoice | null): ResourcePostureTransitionBaseline;
|
|
339
|
+
/**
|
|
340
|
+
* The transition a resolution actually produced, or `undefined` while the
|
|
341
|
+
* Gateway has not recorded one yet.
|
|
342
|
+
*
|
|
343
|
+
* `run.resolveDecision` returns before posture reconciliation finishes, so the
|
|
344
|
+
* record on its response is frequently the one from BEFORE the resolution.
|
|
345
|
+
* Presenting that reports an old outcome as the answer to what the operator just
|
|
346
|
+
* did. Every client applies these four rules, from this one implementation:
|
|
347
|
+
*
|
|
348
|
+
* 1. Novelty. A record whose id was already in the baseline is one the Gateway
|
|
349
|
+
* had before the resolution, and is never adopted.
|
|
350
|
+
* 2. Recency, in Gateway time. A record must not be older than the newest
|
|
351
|
+
* `requestedAt` in the baseline. Both sides come from the Gateway, so no
|
|
352
|
+
* client clock is involved: anchoring on the client's send moment compares a
|
|
353
|
+
* phone or browser clock against the Gateway's, and a skewed client either
|
|
354
|
+
* adopts a stale record or rejects the real one forever. Not-older rather
|
|
355
|
+
* than strictly-newer, so two reconciliations in the same millisecond are not
|
|
356
|
+
* dropped; novelty already excludes the baseline itself. This rule excludes a
|
|
357
|
+
* backfilled or out-of-order record; it cannot exclude a genuinely concurrent
|
|
358
|
+
* one, which is what rule 3 is for.
|
|
359
|
+
* 3. Attribution. A record attributed to a different gate choice is excluded. A
|
|
360
|
+
* record carrying no `gateChoice` is never excluded on that basis, because
|
|
361
|
+
* the Gateway drops `project-default` before it picks a policy source and
|
|
362
|
+
* genuine rejections can also arrive without one. Among the survivors, a
|
|
363
|
+
* record the Gateway attributed to this choice WINS over an unattributed one;
|
|
364
|
+
* an unattributed record is only the fallback. Without that preference a
|
|
365
|
+
* concurrent unattributed reconciliation that lands afterwards is newest and
|
|
366
|
+
* therefore chosen, which misattributes it.
|
|
367
|
+
* 4. Terminality is the caller's half: `in-progress` is not an answer, so the
|
|
368
|
+
* caller keeps polling until `isTerminalResourcePostureOutcome`, bounded by
|
|
369
|
+
* `RESOURCE_POSTURE_TRANSITION_POLL_LIMIT`, and reports the wait on timeout.
|
|
370
|
+
*
|
|
371
|
+
* What this still cannot do: the record carries no decision key, and the
|
|
372
|
+
* resolve path supplies no `operationId` for the Gateway to mint the id from, so
|
|
373
|
+
* for a record with nothing attributed the correlation is positional. A
|
|
374
|
+
* concurrent reconciliation from another boundary could in principle be picked
|
|
375
|
+
* up. Surfaced wording must therefore describe what the run's posture did, never
|
|
376
|
+
* claim the operator's choice caused it.
|
|
377
|
+
*/
|
|
378
|
+
export declare function correlateResourcePostureTransition(baseline: ResourcePostureTransitionBaseline, records: readonly ResourcePostureTransition[]): ResourcePostureTransition | undefined;
|
|
379
|
+
//# sourceMappingURL=resource-posture.d.ts.map
|