The runtime backend distinguishes active lifecycle operations from idle snapshots so overlapping start and stop requests do not silently race.
The runtime backend returns explicit conflict or completion metadata that frontend consumers can turn into trustworthy lifecycle feedback.
Restart-impacting save rules remain aligned with the actual backend fields that require a local runtime restart.
path
provides
tauri-app/src-tauri/src/runtime/mod.rs
lifecycle command guards, structured command results, and start/stop flow behavior
path
provides
tauri-app/src-tauri/src/runtime/state.rs
authoritative runtime snapshot state and process-refresh rules for in-flight lifecycle actions
path
provides
tauri-app/src-tauri/src/runtime/types.rs
serialized lifecycle metadata that the frontend can consume without guessing command outcomes
from
to
via
pattern
tauri-app/src-tauri/src/runtime/mod.rs
tauri-app/src-tauri/src/runtime/types.rs
serialized lifecycle command fields added to the runtime snapshot
RuntimeSnapshot|RuntimeStatus|last_error
from
to
via
pattern
tauri-app/src-tauri/src/runtime/mod.rs
tauri-app/src-tauri/src/runtime/state.rs
shared guard rules for starting, stopping, and process refresh transitions
start|stop|refresh_process_state
Create the backend lifecycle contract that Phase 2 can build on before frontend state and UI changes begin.
Purpose: make start, stop, and conflicting lifecycle requests deterministic at the Tauri runtime boundary instead of relying on a single frontend busy boolean.
Output: runtime snapshot metadata and guard behavior that explicitly describe in-flight operations, blocked conflicts, and lifecycle completion outcomes.
Task 1: Add explicit lifecycle command metadata to the runtime snapshot
tauri-app/src-tauri/src/runtime/types.rs, tauri-app/src-tauri/src/runtime/state.rs
- tauri-app/src-tauri/src/runtime/types.rs
- tauri-app/src-tauri/src/runtime/state.rs
- tauri-app/src/features/runtime/types.ts
- .planning/phases/02-lifecycle-command-safety/02-RESEARCH.md
- Test 1: the serialized runtime snapshot exposes the currently active lifecycle action and the last completed lifecycle result.
- Test 2: snapshots still report existing status, readiness, process_running, and error fields without breaking current callers.
Extend `tauri-app/src-tauri/src/runtime/types.rs` and `tauri-app/src-tauri/src/runtime/state.rs` with concrete lifecycle metadata. Add a serialized enum or string union for the active command with the values `idle`, `save`, `start`, `stop`, and `save_and_start`. Add a serialized result payload or equivalent snapshot fields that record the last command name, a terminal outcome of `succeeded`, `blocked`, or `failed`, and a human-readable message. Keep the existing `RuntimeSnapshot`, `RuntimeStatus`, and `RuntimeErrorInfo` fields intact; add new fields instead of replacing old ones so brownfield frontend callers continue compiling.
- `tauri-app/src-tauri/src/runtime/types.rs` defines serialized lifecycle command metadata alongside `RuntimeSnapshot`.
- `tauri-app/src-tauri/src/runtime/state.rs` stores enough lifecycle metadata to build snapshots with active-command and last-result information.
- Existing snapshot fields `status`, `ready`, `process_running`, `resolved_url`, `binary_path`, `last_error`, and `config` remain present in `RuntimeSnapshot`.
cargo test -p tauri-app runtime::
The runtime snapshot becomes an explicit transport for lifecycle state instead of forcing the frontend to infer command outcomes from generic status changes.
Task 2: Guard conflicting lifecycle commands and preserve restart-impacting save rules
tauri-app/src-tauri/src/runtime/mod.rs, tauri-app/src-tauri/src/runtime/state.rs
- tauri-app/src-tauri/src/runtime/mod.rs
- tauri-app/src-tauri/src/runtime/state.rs
- tauri-app/src-tauri/src/runtime/process.rs
- .planning/phases/02-lifecycle-command-safety/02-RESEARCH.md
- Test 1: a second `start_runtime` request while a start or stop command is active returns a blocked lifecycle result instead of mutating process state.
- Test 2: `stop_runtime` while no local process is running returns a blocked or no-op lifecycle result with a stable message.
- Test 3: saving a running local config that changes `connection_mode`, `model_path`, `addr`, `gpu_layers`, or `ctx_size` still returns `restart_required` guidance.
Refactor `tauri-app/src-tauri/src/runtime/mod.rs` to centralize lifecycle command guards before mutating process state. Add explicit conflict handling for these cases: `start_runtime` while `status` is `Starting` or `Stopping`, `start_runtime` while a managed child already exists, `stop_runtime` while `status` is `Starting` or `Stopping`, and `stop_runtime` when no managed child exists. For each blocked case, populate the new lifecycle result metadata with `blocked` and a concrete message such as `Local API start already in progress.`, `Stop the local API before starting it again.`, or `Local API is already stopped.`. Preserve the existing restart-impacting save guard for `connection_mode`, `model_path`, `addr`, `gpu_layers`, and `ctx_size`, and route it through the same structured lifecycle result metadata so the frontend receives one consistent contract.
- `tauri-app/src-tauri/src/runtime/mod.rs` contains explicit guard branches for duplicate or conflicting start/stop requests.
- Blocked lifecycle cases return concrete user-facing messages containing `already in progress`, `already running`, or `already stopped`.
- The restart-impacting field list in `requires_runtime_restart` remains limited to `connection_mode`, `model_path`, `addr`, `gpu_layers`, and `ctx_size` unless tests are updated to prove a different list.
cargo test -p tauri-app runtime::
The backend becomes the authoritative source for lifecycle conflict prevention and restart-required guidance.
- `cargo test -p tauri-app runtime::`
<success_criteria>
Start and stop requests have explicit blocked-state outcomes instead of silent no-ops.
Runtime snapshots expose active and completed lifecycle command information.
Restart-required saves still map to the existing backend-impact field list.
</success_criteria>
After completion, create `.planning/phases/02-lifecycle-command-safety/02-01-SUMMARY.md`