Skip to main content

inferlab_protocol/
measurement_data_asset.rs

1//! Wire declarations owned by measurement data-asset preparation.
2
3use crate::wire::{BenchAgenticSourceInput, ClientStatus, EvalDefinitionInput, ProtocolVersion};
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use std::collections::BTreeMap;
7use std::path::PathBuf;
8
9/// One narrowly scoped source-preparation request issued before measurement
10/// materialization. The selected measurement definition remains authoritative
11/// for dataset semantics.
12#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
13#[serde(deny_unknown_fields)]
14pub struct MeasurementDataAssetPreparationRequest {
15    pub protocol_version: ProtocolVersion,
16    pub phase: MeasurementDataAssetPreparationPhase,
17    pub source: MeasurementDataAssetSourceInput,
18    pub artifact_dir: PathBuf,
19}
20
21/// One externally observable source-preparation phase. Separating resolution
22/// from acquisition lets the control plane durably commit each result.
23#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
24#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
25pub enum MeasurementDataAssetPreparationPhase {
26    Resolve,
27    SnapshotLocal,
28    Acquire {
29        resolved_revision: String,
30        cache_state_before: MeasurementDataAssetCacheOutcome,
31    },
32}
33
34/// The next separately durable preparation phase selected by the owning
35/// runtime after source resolution.
36#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
37#[serde(rename_all = "snake_case")]
38pub enum MeasurementDataAssetPreparationNextPhase {
39    SnapshotLocal,
40}
41
42/// The measurement-owned source whose bytes or task selection are prepared.
43#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
44#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
45pub enum MeasurementDataAssetSourceInput {
46    Eval {
47        workspace_root: PathBuf,
48        #[serde(default)]
49        workspace_source_exclusions: Vec<PathBuf>,
50        definition: Box<EvalDefinitionInput>,
51    },
52    Agentic {
53        source: Box<BenchAgenticSourceInput>,
54    },
55}
56
57/// A normalized mapping from dataset split names to selected file patterns.
58#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
59#[serde(transparent)]
60pub struct MeasurementDataFiles(pub BTreeMap<String, Vec<String>>);
61
62/// The effective selection reported by the owning measurement runtime.
63#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
64#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
65pub enum MeasurementDataAssetEffectiveSelection {
66    Eval {
67        task_identity: String,
68        #[serde(default)]
69        dataset_path: Option<String>,
70        #[serde(default)]
71        dataset_name: Option<String>,
72        #[serde(default)]
73        evaluation_split: Option<String>,
74        #[serde(default)]
75        fewshot_split: Option<String>,
76        #[serde(default)]
77        data_files: Option<MeasurementDataFiles>,
78    },
79    Agentic {
80        repository: String,
81        requested_revision: String,
82        #[serde(default)]
83        observed_revision: Option<String>,
84        filename: String,
85    },
86}
87
88/// One member of a complete, ordered content closure.
89#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
90#[serde(deny_unknown_fields)]
91pub struct MeasurementDataAssetContentEntry {
92    pub relative_path: String,
93    pub sha256: String,
94}
95
96/// Expected-versus-observed integrity evidence for qualified source content.
97#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
98#[serde(deny_unknown_fields)]
99pub struct MeasurementDataAssetVerification {
100    pub subject: String,
101    pub expected: String,
102    #[serde(default)]
103    pub observed: Option<String>,
104    pub matched: bool,
105}
106
107/// The complete immutable source identity established by preparation.
108#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
109#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
110pub enum MeasurementDataAssetAcquiredSource {
111    ReleaseQualified {
112        identity: String,
113        closure: Vec<MeasurementDataAssetContentEntry>,
114    },
115    LocalFileClosure {
116        source_root: PathBuf,
117        files: Vec<MeasurementDataAssetContentEntry>,
118    },
119}
120
121/// The immutable workspace-task snapshot consumed by one Eval client.
122#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
123#[serde(deny_unknown_fields)]
124pub struct EvalPreparedSourceBinding {
125    pub workspace_root: PathBuf,
126    pub task_path: PathBuf,
127}
128
129/// Whether preparation established a closed source or an explicitly opaque
130/// non-reproducible source.
131#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
132#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
133pub enum MeasurementDataAssetReadiness {
134    Closed {
135        acquired_source: Box<MeasurementDataAssetAcquiredSource>,
136        #[serde(default)]
137        verification: Vec<MeasurementDataAssetVerification>,
138        #[serde(default, skip_serializing_if = "Option::is_none")]
139        eval_binding: Option<Box<EvalPreparedSourceBinding>>,
140    },
141    Opaque {
142        reason: String,
143        #[serde(default)]
144        unresolved_path: Option<PathBuf>,
145        deferred_source_access: bool,
146    },
147}
148
149/// Read-only or preparation-time outcome for one independently owned cache.
150#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
151#[serde(rename_all = "snake_case")]
152pub enum MeasurementDataAssetCacheOutcome {
153    FullHit,
154    Miss,
155    PartialReuse,
156    Unavailable,
157}
158
159/// One effective physical cache store as reported by its owning runtime.
160#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
161#[serde(deny_unknown_fields)]
162pub struct MeasurementDataAssetCacheStore {
163    pub authority: String,
164    pub purpose: String,
165    #[serde(default)]
166    pub path: Option<PathBuf>,
167    pub outcome: MeasurementDataAssetCacheOutcome,
168}
169
170/// Whether preparation contacted a remote metadata authority.
171#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
172#[serde(rename_all = "snake_case")]
173pub enum MeasurementDataAssetRemoteMetadataOutcome {
174    NotAccessed,
175    Accessed,
176    Unavailable,
177}
178
179/// Whether immutable source bytes were reused or downloaded.
180#[derive(Clone, Copy, Debug, Deserialize, Eq, JsonSchema, PartialEq, Serialize)]
181#[serde(rename_all = "snake_case")]
182pub enum MeasurementDataAssetSourceBytesOutcome {
183    NotAccessed,
184    Reused,
185    Downloaded,
186    Unavailable,
187}
188
189/// Terminal result returned by the owning measurement runtime.
190#[derive(Clone, Debug, Deserialize, JsonSchema, PartialEq, Serialize)]
191#[serde(deny_unknown_fields)]
192pub struct MeasurementDataAssetPreparationResult {
193    pub schema_version: u32,
194    pub status: ClientStatus,
195    #[serde(default)]
196    pub effective_selection: Option<MeasurementDataAssetEffectiveSelection>,
197    #[serde(default)]
198    pub readiness: Option<MeasurementDataAssetReadiness>,
199    #[serde(default)]
200    pub next_phase: Option<MeasurementDataAssetPreparationNextPhase>,
201    #[serde(default)]
202    pub cache_stores: Vec<MeasurementDataAssetCacheStore>,
203    pub remote_metadata: MeasurementDataAssetRemoteMetadataOutcome,
204    pub source_bytes: MeasurementDataAssetSourceBytesOutcome,
205    #[serde(default)]
206    pub error: Option<String>,
207}