--- phase: 02-lifecycle-command-safety plan: 02 subsystem: ui tags: [react, typescript, runtime, lifecycle, tauri] requires: - phase: 02-lifecycle-command-safety provides: backend lifecycle snapshot metadata and conflict guards from plan 02-01 provides: - frontend lifecycle command and result types - manager-owned lifecycle progress and apply-impact state - RuntimeSurface regression coverage for lifecycle manager semantics affects: [phase-02-03, runtime-status-card, runtime-settings-drawer] tech-stack: added: [] patterns: [manager-owned lifecycle state, apply-impact classification from saved-versus-draft config] key-files: created: [] modified: - tauri-app/src/features/runtime/types.ts - tauri-app/src/features/runtime/api.ts - tauri-app/src/features/runtime/runtime-utils.ts - tauri-app/src/features/runtime/useRuntimeManager.ts - tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx key-decisions: - "Mirror backend lifecycle metadata directly into the frontend RuntimeSnapshot so polling and command responses share one contract." - "Derive applyImpact from saved baseline versus draft config using the backend restart-required field list instead of UI-only heuristics." - "Expose activeLifecycleCommand, lastLifecycleResult, and lifecycleBusy from the manager so status-card and drawer copy can consume explicit state in plan 02-03." patterns-established: - "Runtime manager normalizes lifecycle metadata on every snapshot before reconciling draft-safe state." - "Blocked duplicate lifecycle requests become manager-visible lifecycle results before UI surfaces render them." requirements-completed: [CTRL-01, CTRL-02, CTRL-03] duration: 14min completed: 2026-03-29 --- # Phase 2 Plan 02: Lifecycle Command Safety Summary **Frontend runtime state now tracks explicit lifecycle commands, completion messages, and restart/apply impact on top of the Phase 1 draft model** ## Performance - **Duration:** 14 min - **Started:** 2026-03-29T03:56:04Z - **Completed:** 2026-03-29T04:10:22Z - **Tasks:** 2 - **Files modified:** 5 ## Accomplishments - Added frontend lifecycle command, result, and apply-impact types plus fallback snapshot support in the runtime API layer. - Refactored the runtime manager to expose `activeLifecycleCommand`, `lastLifecycleResult`, `lifecycleBusy`, and `applyImpact` while keeping dirty-draft polling safety intact. - Expanded `RuntimeSurface` tests to cover lifecycle metadata mirroring, apply-impact classification, start/stop progress, and restart-required manager state. ## Task Commits Each task was committed atomically: 1. **Task 1: Mirror backend lifecycle metadata and define frontend apply-impact contracts** - `a72c902` (test) 2. **Task 1: Mirror backend lifecycle metadata and define frontend apply-impact contracts** - `2cb6cad` (feat) 3. **Task 2: Replace generic busy handling with action-specific manager state** - `1d45342` (test) 4. **Task 2: Replace generic busy handling with action-specific manager state** - `1bcd4be` (feat) ## Files Created/Modified - `tauri-app/src/features/runtime/types.ts` - mirrors backend lifecycle fields and apply-impact unions in the frontend contract. - `tauri-app/src/features/runtime/api.ts` - preserves lifecycle result metadata in local fallback snapshots. - `tauri-app/src/features/runtime/runtime-utils.ts` - classifies apply impact from the backend restart-required field list and provides lifecycle result defaults. - `tauri-app/src/features/runtime/useRuntimeManager.ts` - owns explicit lifecycle progress and completion state alongside the existing draft/live split. - `tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx` - covers manager lifecycle semantics through the React runtime feature harness. ## Decisions Made - Normalized snapshots inside the manager so older fallback payloads and fresh backend payloads both produce defined lifecycle fields. - Kept `busy` available for brownfield consumers while adding explicit lifecycle state that plan 02-03 can render directly. - Used the backend restart-required field list (`connection_mode`, `model_path`, `addr`, `gpu_layers`, `ctx_size`) as the only source of truth for `restart_required` apply impact. ## Deviations from Plan None - plan executed as written. ## Issues Encountered - None. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - `RuntimeStatusCard` and `RuntimeSettingsDrawer` can now render explicit lifecycle progress and apply guidance from manager props instead of inferring from `busy`. - Phase 2 UI work can show restart-required and save-before-apply messaging without re-implementing backend guard logic. --- *Phase: 02-lifecycle-command-safety* *Completed: 2026-03-29*