Skip to main content

CoderSession

Struct CoderSession 

Source
pub struct CoderSession {
Show 37 fields pub id: String, pub repo: PathBuf, pub intent: String, pub engine: EngineChoice, pub state: CoderState, pub contract: Option<OutcomeContract>, pub workspace_path: Option<PathBuf>, pub project: Option<String>, pub project_kind: Option<ProjectKind>, pub built_agent: Option<DeclarativeAgentSpec>, pub agent_build_progress: Option<AgentBuildProgress>, pub iterations: u32, pub max_iterations: u32, pub cost_usd: Option<f64>, pub repair_invokes: Option<u32>, pub transient_retries: Option<u32>, pub keep_workspace_on_failure: bool, pub model: Option<String>, pub last_check_results: Vec<CheckResult>, pub baseline: Vec<CheckResult>, pub baseline_gates_nothing: bool, pub result_branch: Option<String>, pub failure_kind: Option<String>, pub discussion_id: Option<String>, pub browser: bool, pub distributed: bool, pub workers: Vec<String>, pub pool_workers: Vec<String>, pub placements: Vec<Placement>, pub integrated_subtasks: Vec<IntegratedSubtask>, pub repaired_locally: bool, pub authored_by: Vec<String>, pub created_at: u64, pub updated_at: u64, pub error: Option<String>, pub workspace: Option<AgentWorkspace>, pub state_dir: Option<PathBuf>,
}
Expand description

A coding session. Serializes to the JSON snapshot persisted on every transition; the live worktree handle is process-only (#[serde(skip)]).

Fields§

§id: String§repo: PathBuf

The user’s repository root (never written to directly).

§intent: String§engine: EngineChoice§state: CoderState§contract: Option<OutcomeContract>§workspace_path: Option<PathBuf>

Where the throwaway worktree lives (kept in the snapshot so orphaned sessions after a daemon restart can still report it).

§project: Option<String>

When this session works on a CAR-managed project (vs. a raw repo path), the project slug + kind. Drives delivery (commit straight to the project’s main instead of publishing a car/coder/<id> branch) and, for Agent projects, the scenario-based contract + agent registration on approve. None = raw-repo session (the original behavior).

§project_kind: Option<ProjectKind>§built_agent: Option<DeclarativeAgentSpec>

For an Agent project: the declarative agent spec the build loop produced, stashed so approve_merge can register it. Persisted so coder.get can show what was built.

§agent_build_progress: Option<AgentBuildProgress>

Present only for Agent-project builds. Additive on coder.get; older hosts ignore it and older snapshots deserialize with None.

§iterations: u32§max_iterations: u32§cost_usd: Option<f64>

Metered inference spend, when anything reported it. None is unknown, not free — the native loop does not meter.

§repair_invokes: Option<u32>

Per-session external-engine hypothesis budget. None = engine default.

§transient_retries: Option<u32>

Per-session external-engine availability budget. None = engine default.

§keep_workspace_on_failure: bool

When a session ends Failed, keep the throwaway worktree on disk (and its handle in-process) so the operator can inspect it for a postmortem instead of having it reaped on the terminal transition. Sourced from ~/.car/coder.toml (keep_workspace_on_failure); default false.

§model: Option<String>

Pin the native loop’s inference model (e.g. "parslee/reasoning"). None = adaptive routing. Sourced from ~/.car/coder.toml (model).

§last_check_results: Vec<CheckResult>§baseline: Vec<CheckResult>

The contract’s red-green baseline — how each check fared against the unmodified worktree (car#707). Stored rather than recomputed because it is part of how the current draft READS: a board renders the contract with its baseline beside it, so a coder.revise_contract that could not be honored has to hand back both, or the contract it swore was unchanged visibly changes anyway when the baseline blanks out.

§baseline_gates_nothing: bool

Whether every baseline check already passed — i.e. the contract gates nothing for this task. Travels with baseline for the same reason.

§result_branch: Option<String>§failure_kind: Option<String>

Why a failed session failed, as a machine-readable kind: "budget_exhausted" | "auth_required" | "configuration" | "infrastructure" | "error". Persisted so a summary read from disk after a daemon restart still distinguishes “ran out of clock” from “nobody signed in” from “routing excludes every model” from “the machinery broke” from “the work was judged and rejected” — a live-only derivation would go blank exactly when the operator comes back to look.

"infrastructure" is the one a scorer must act on: nothing was judged, so the session is not a task loss. See rpc::failure_kind_for for how it is chosen and why it is not folded into "error".

§discussion_id: Option<String>

The coder.discuss conversation this run was distilled from, when the operator went through a discussion. Provenance only — the run itself is independent of the discussion’s lifetime.

§browser: bool

Whether this session explicitly opted into the assistant’s browser tool surface. False by default and persisted so contract review cannot change which tools the later confirmed run receives.

§distributed: bool

Farm subtasks across reachable CAR instances rather than this machine alone. Only the foreman engine reads it.

Persisted, and reported on the coder.list row, so a finished run can say which way it ran. That is the whole reason — a session does NOT resume across a daemon restart (adopt_orphaned_sessions rewrites every non-terminal orphan to Failed), so this is not protecting a resumed run from silently becoming local.

§workers: Vec<String>

Instances a distributed run is restricted to. Empty = every instance that can serve the repository.

The operator’s FILTER, not the resolved pool — see Self::pool_workers for what the run actually got.

§pool_workers: Vec<String>

The peers the pool actually resolved to, recorded when it is built.

workers above is what the operator asked to restrict to; this is what answering that restriction against reachability, enrollment and repo eligibility produced. It was emitted as a foreman: "pool" event and then dropped, so a subscriber that was not attached saw nothing and the snapshot carried no record at all.

Written BEFORE any subtask runs, which is what makes it the durable answer to “which machines was this farmed to?”. Self::placements cannot answer it on its own: a placement is recorded when a worker RETURNS, and foreman runs a level under join_all rather than spawning, so coder.cancel’s abort drops every in-flight future before it records — the subtasks running at the moment an operator gives up are exactly the ones the ledger omits (car#1346). Empty on a local run.

§placements: Vec<Placement>

Where each of a distributed run’s subtasks actually ran, including the workers that failed it first.

Empty for a local run, and for a distributed one that fell off the foreman rung before farming anything out.

Not a proxy for “a distributed run completed.” A cancelled run carries this populated with Self::integrated_subtasks empty, and so does a run whose foreman union the gate rejected — three different states, separated by state and by nothing else. And it is a floor, not a census: subtasks still in flight at a cancel never reach it, which is what Self::pool_workers is for.

foreman.run has reported this all along; the pipeline that DELIVERS had strictly less provenance than the one that only reports, because fleet_pool_for erased FleetPool to Arc<dyn WorktreeAgent> and placements() is on the concrete type (car#1322). CAR’s position is that receipts decide completion, and a delivered commit whose hunks were authored on unnamed machines is the wrong artifact for that claim — the question arrives the first time a distributed run produces something surprising.

§integrated_subtasks: Vec<IntegratedSubtask>

Which of those subtasks actually LANDED in the worktree, and what each wrote. The diagnostic record above says what happened; this says what is in the tree, and only this may back a claim in the delivered commit.

§repaired_locally: bool

Foreman’s union was integrated and then the native loop repaired on top of it, so some delivered hunks were written locally by no listed worker.

Without this the commit body would credit the fleet for a diff it only partly wrote — the same false attribution as crediting it for one it did not write at all, in a milder form.

§authored_by: Vec<String>

Every model that AUTHORED part of this session’s work, as opposed to Self::model, which is the pin the caller asked for.

They differ exactly when it matters: unpinned, the router chooses, and on a machine with one reachable credential that choice can also be a review-panel seat — the self-review the gate refuses when a coder is pinned, permitted by default because nothing knew who wrote the change (car#1299).

A projection of the journal (EventSink::authoring_models), not a second record of the same fact — two records can disagree and then the question is which one the gate believes. Empty for a session with no native turns (foreman/external), which is the DEFAULT engine: read it as “CAR’s own loop did not write this”, not “nobody did”.

§created_at: u64§updated_at: u64§error: Option<String>§workspace: Option<AgentWorkspace>

RAII worktree handle. Dropping it removes the worktree, so terminal transitions release it explicitly.

§state_dir: Option<PathBuf>

Where snapshots/journals/worktrees go; None disables persistence.

Implementations§

Source§

impl CoderSession

Source

pub fn new( repo: impl Into<PathBuf>, intent: impl Into<String>, engine: EngineChoice, max_iterations: u32, state_dir: Option<PathBuf>, ) -> Self

Source

pub fn with_project(self, slug: impl Into<String>, kind: ProjectKind) -> Self

Mark this session as working on a managed project (builder so existing call sites and tests stay green).

Source

pub fn short_id(&self) -> &str

Short suffix for branch names and worktree dirs.

Source

pub fn provision_workspace(&mut self) -> Result<PathBuf, String>

Provision the throwaway git worktree under the state dir (NOT inside the user’s repo, so their git status stays clean).

Source

pub fn transition( &mut self, to: CoderState, sink: &EventSink, ) -> Result<(), String>

Validated state transition: updates timestamps, emits StateChanged, persists the snapshot, and releases the worktree on terminal states.

Source

pub fn persist(&self) -> Result<(), String>

Write the JSON snapshot to <state_dir>/<id>.json (no-op without a state dir, e.g. in unit tests).

Source

pub fn load(path: &Path) -> Result<Self, String>

Load a snapshot from disk. The worktree handle is NOT restored — a loaded session is read-only history unless re-provisioned.

Source

pub fn list(state_dir: &Path) -> Vec<CoderSession>

All persisted sessions under state_dir, newest first.

Trait Implementations§

Source§

impl Debug for CoderSession

Source§

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

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

impl<'de> Deserialize<'de> for CoderSession

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 CoderSession

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

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

Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

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, !>

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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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