Skip to main content

State

Struct State 

Source
pub struct State {
Show 16 fields pub stage: Stage, pub phase: u32, pub agent: AgentKind, pub mode: Mode, pub gate_pending: bool, pub consecutive_failures: u32, pub infra_failures: u32, pub preflight_retries: u32, pub started_at: String, pub project_root: PathBuf, pub worktree_path: Option<PathBuf>, pub monitor_pid: Option<u32>, pub stop_until: Option<Stage>, pub stopped: bool, pub stop_reason: Option<String>, pub yes_ship: bool,
}
Expand description

Full workflow state persisted to .devflow/state.json.

Fields§

§stage: Stage

Current workflow stage.

§phase: u32

Phase number being worked on.

§agent: AgentKind

Which coding agent was launched.

§mode: Mode

How the pipeline is driven (auto vs. supervise).

§gate_pending: bool

Whether a gate has been written and is awaiting a human response.

§consecutive_failures: u32

Consecutive Validate failures — drives the Auto-mode forced gate after crate::mode::MAX_CONSECUTIVE_FAILURES failures. Persisted across devflow advance invocations so the counter survives monitor restarts.

§infra_failures: u32

Consecutive infrastructure-class faults (ResourceKilled, AgentUnavailable) — distinct from Self::consecutive_failures (D-08, 17-01). Gates at crate::mode::MAX_INFRA_FAILURES. Any increment (wired in Plan 04) must use saturating_add so a long-running stuck loop cannot overflow u32. A serde-absent value (older persisted state) defaults to 0. Reset to 0 on every successful stage transition, alongside consecutive_failures (CR-01, 17-06 gap closure), so the ceiling bounds a stuck loop, not a phase’s lifetime.

§preflight_retries: u32

How many times a preflight gate has been resolved and retried for this phase (18f). Bounded by crate::mode::MAX_PREFLIGHT_RETRIES. Persisted rather than recursion-scoped because the documented wedge spanned separate devflow invocations after a monitor death — an in-process recursion-depth counter would reset to zero on every new process and fail to bound the exact incident it exists to prevent. Reset to 0 whenever preflight passes and whenever a human explicitly approves (GateAction::Advance), both inside run_preflight. Unlike Self::consecutive_failures and Self::infra_failures, this counter is NOT touched by transition().

§started_at: String

When the phase started (Unix seconds).

§project_root: PathBuf

Path to the project root.

§worktree_path: Option<PathBuf>

Working directory for the agent when running in a git worktree.

None means the agent runs in project_root. State and capture files always live under the main project_root; only the agent’s cwd changes.

§monitor_pid: Option<u32>

PID of the detached monitor process that owns the agent for the current stage, recorded by launch_stage at spawn time. None means no monitor has been spawned for this state yet, OR the state was written by a binary predating this field — in both cases the liveness probe reports Unknown, never Stuck.

§stop_until: Option<Stage>

The stage devflow start --until <stage> requests as the last stage to run before halting (20c). None means no stop point was requested (the pipeline runs to Ship), OR the state was written by a binary predating this field — both cases behave identically (no interception in transition()).

§stopped: bool

Set by transition() when stop_until names the stage just completed — a terminal-but-not-failed halt short of Ship (20c). false for a normal in-flight or completed-to-Ship phase, and for any state written by a binary predating this field.

§stop_reason: Option<String>

Human-readable reason recorded alongside stopped (20c). None when stopped is false, or when the state predates this field.

§yes_ship: bool

Pre-authorization for the Ship gate (D-04/D-05/D-06, 23-09), set only from the --yes-ship CLI flag typed on devflow start.

Persisted rather than passed through the call stack: the Ship gate fires inside a detached monitor’s advance process, minutes to hours after the launching devflow start process has already exited, so a CLI-scoped value would be gone by the time it matters — only a value written to state.json at start time survives to be read back by that later, separate process. false for any state written by a binary predating this field.

Implementations§

Source§

impl State

Source

pub fn new( phase: u32, agent: AgentKind, mode: Mode, project_root: PathBuf, ) -> Self

Create a new state for starting a phase at the Stage::Define stage.

Trait Implementations§

Source§

impl Clone for State

Source§

fn clone(&self) -> State

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 State

Source§

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

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

impl<'de> Deserialize<'de> for State

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 State

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§

§

impl Freeze for State

§

impl RefUnwindSafe for State

§

impl Send for State

§

impl Sync for State

§

impl Unpin for State

§

impl UnsafeUnpin for State

§

impl UnwindSafe for State

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> 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 = Infallible

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