Skip to main content

RunConfig

Struct RunConfig 

Source
pub struct RunConfig {
Show 22 fields pub mecha_version: String, pub provider: String, pub model: String, pub workspace: PathBuf, pub system_prompt: Option<String>, pub tools: Vec<String>, pub tools_hash: Option<String>, pub effort: Option<Effort>, pub temperature: Option<f64>, pub seed: Option<u64>, pub thinking: bool, pub cache_prompt: bool, pub max_tokens: u32, pub max_turns: u32, pub max_output_tokens: Option<u64>, pub max_cost_usd: Option<f64>, pub compact_at_tokens: Option<u64>, pub compact_keep_recent: usize, pub permission_mode: PermissionMode, pub trifecta: TrifectaPolicy, pub sandbox: String, pub sandbox_network: bool,
}
Expand description

What a run was configured with, recorded so it can be replayed.

The rule behind the field list: anything that shapes the request or constrains the run is a confound if it is not recorded. That is not theoretical here — compaction on versus off measured 1/5 against 5/5 on the same task, so a replay that did not know whether compaction was enabled would compare two incomparable runs and report a model regression.

The system prompt is stored in full rather than hashed. A hash tells you only that something differed; the text lets a replay rebuild the request. It is no more sensitive than the transcript sitting beside it.

The sampler is recorded only as far as it is pinned: temperature and seed hold what this process sent, and None means the server chose. Replay against an unpinned run has to be pass@k-shaped rather than exact-match-shaped; against a pinned, seeded run driven sequentially it can expect to match. (Not greedy — temperature 0.0 walks qwen3.6 into verbatim repetition loops. And only sequentially: llama-server’s continuous batching makes concurrent requests perturb each other’s numerics, seed or no seed.)

Fields§

§mecha_version: String

Which harness produced this. The axis every replay diff is measured on.

§provider: String§model: String§workspace: PathBuf§system_prompt: Option<String>

The resolved text, not the path it may have come from.

§tools: Vec<String>

Tool names in registry order — which is the order they are sent, and the front of the cached prefix. A tool added, removed or renamed between recording and replay changes what the model could have done.

§tools_hash: Option<String>

The surface those names actually described, by hash.

Names were never enough, and the comment above says why without seeing it. Add, remove and rename are the three that almost never happen; re-describe happens constantly — 49 commits touched tool definitions in three weeks of this store — and a list of names cannot see it. Tools render before the system prompt, so a replay was rebuilding the second half of the prefix byte-exactly and the first half from whatever the registry says today. Measured consequence: 12 of 13 counterfactual probes inconclusive, deterministically, median divergence one tool call in.

The specs themselves live in crate::surface::SurfaceStore — 69 KB against a 25 KB average session is why this is a citation and not the text, where system_prompt above is the text.

None is a recording from before this existed, and must never read as a matchcrate::surface::Fidelity is the three-state answer, and its Unknown arm is the one every session on disk today lands in.

Scope: registry().specs(), unfiltered — not necessarily what this turn’s request actually sent. The wire request goes through registry.specs_for(cx.phase), which also applies Phase::Plan’s read-only filter and a loaded skill’s tools: narrowing (matching this struct’s own tools field, so this is not a new gap, only a named one). A run under Plan, or one that had a narrowing skill loaded, sent fewer specs than this hash covers — and since the surface can narrow mid-run, no single hash can describe every turn’s request exactly. Fidelity::Matches here means “the full registry is unchanged since this was recorded”, which is what makes a replay worth attempting; it is not a claim that the request bytes were identical.

§effort: Option<Effort>§temperature: Option<f64>

The temperature and seed actually sent, when the provider config pins them. Unset means the server chose, and the run is not repeatable.

§seed: Option<u64>§thinking: bool§cache_prompt: bool

No effect on semantics; large effect on the token counts a replay diffs.

§max_tokens: u32§max_turns: u32§max_output_tokens: Option<u64>§max_cost_usd: Option<f64>§compact_at_tokens: Option<u64>§compact_keep_recent: usize§permission_mode: PermissionMode

A denied call redirects the whole trajectory, so replaying a read-only session under --yes compares nothing.

§trifecta: TrifectaPolicy§sandbox: String

none | bwrap | docker | landlock. Load-bearing beyond the obvious: shell declares narrower capabilities when confined, and the interlock believes them, so the same prompt can be refused in one and allowed in the other. (landlock never narrows external_send — see the sandbox module — so it patterns with none for the interlock while still confining files.)

§sandbox_network: bool

Implementations§

Source§

impl RunConfig

Source

pub fn of(agent: &Agent, config: &Config, provider: &str) -> Self

Read it off the built agent rather than off the config file, so what is recorded is what is actually being sent — flags, layered TOML and defaults already resolved.

Trait Implementations§

Source§

impl Clone for RunConfig

Source§

fn clone(&self) -> RunConfig

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for RunConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for RunConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for RunConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for RunConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more