--- phase: 02-lifecycle-command-safety plan: 03 subsystem: ui tags: [react, css, runtime, lifecycle, ux] requires: - phase: 02-lifecycle-command-safety provides: explicit manager lifecycle state and apply-impact semantics from plan 02-02 provides: - status card lifecycle progress and result messaging - drawer apply guidance for immediate, restart-required, and save-before-apply states - UI regression coverage for lifecycle-safe runtime controls affects: [phase-03, runtime-workspace, lifecycle-ux] tech-stack: added: [] patterns: [action-specific CTA copy, lifecycle result banners, pre-action apply guidance] key-files: created: [] modified: - tauri-app/src/features/runtime/components/RuntimeStatusCard.tsx - tauri-app/src/features/runtime/components/RuntimeStatusCard.css - tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx - tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.css - tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx - tauri-app/src/components/Sidebar.tsx - tauri-app/src/features/runtime/runtime-utils.test.ts key-decisions: - "Use explicit lifecycle result banners instead of overloading last_error so completed and blocked actions remain visible after polling refreshes." - "Render apply guidance in the drawer before the CTA row so users see whether a draft applies immediately, needs restart, or must be saved before apply." - "Keep status-card and drawer props backward-compatible with optional lifecycle fields while Sidebar forwards the new manager contract." patterns-established: - "Status card consumes activeLifecycleCommand plus lastLifecycleResult to show action-specific CTA labels and stable completion feedback." - "Drawer CTA text and disabled states derive from applyImpact and lifecycleBusy instead of one generic busy label." requirements-completed: [CTRL-01, CTRL-02, CTRL-03] duration: 13min completed: 2026-03-29 --- # Phase 2 Plan 03: Lifecycle Command Safety Summary **The runtime workspace now tells the user what lifecycle action is running, what just completed, and whether saved draft changes apply now or wait for restart** ## Performance - **Duration:** 13 min - **Started:** 2026-03-29T04:04:51Z - **Completed:** 2026-03-29T04:17:00Z - **Tasks:** 2 - **Files modified:** 7 ## Accomplishments - Replaced generic status-card busy copy with action-specific lifecycle labels and result banners. - Added explicit drawer guidance for immediate-apply, restart-required, and save-before-apply runtime drafts. - Extended UI regression coverage and build wiring so the lifecycle manager contract reaches both the sidebar shell and direct test helpers. ## Task Commits Each task was committed atomically: 1. **Task 1: Update the runtime status card for action-specific lifecycle feedback** - `8c303a9` (test) 2. **Task 2: Make drawer CTA copy and apply guidance explicit** - `06c1a44` (feat) 3. **Build follow-up: wire lifecycle props through build callers** - `93f7fd9` (fix) ## Files Created/Modified - `tauri-app/src/features/runtime/components/RuntimeStatusCard.tsx` - renders explicit start/stop labels, lifecycle result messages, and disabled conflicting actions. - `tauri-app/src/features/runtime/components/RuntimeStatusCard.css` - styles lifecycle result banners to match the existing runtime card tone system. - `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.tsx` - drives CTA labels and helper guidance from `applyImpact`, `activeLifecycleCommand`, and `lifecycleBusy`. - `tauri-app/src/features/runtime/components/RuntimeSettingsDrawer.css` - styles apply-guidance rows and lifecycle outcome messaging. - `tauri-app/src/features/runtime/components/RuntimeSurface.test.tsx` - covers UI lifecycle copy, result banners, and apply-guidance behavior. - `tauri-app/src/components/Sidebar.tsx` - forwards lifecycle manager props to the status card and drawer. - `tauri-app/src/features/runtime/runtime-utils.test.ts` - keeps direct snapshot helpers aligned with the expanded lifecycle snapshot shape. ## Decisions Made - Status-card completion feedback lives in a dedicated lifecycle result banner so success, blocked, and failure messages do not compete with runtime error diagnostics. - Drawer helper copy uses exact operator-facing phrases from the plan to keep restart and mode-switch behavior predictable. - Optional lifecycle props on UI components preserve compatibility for direct component renders while the live app passes explicit manager state. ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 3 - Blocking] Wired expanded lifecycle props through build callers and helper tests** - **Found during:** Task 2 (Make drawer CTA copy and apply guidance explicit) - **Issue:** `npm run build` failed because `Sidebar.tsx` and `runtime-utils.test.ts` still used the older component and snapshot contracts. - **Fix:** Forwarded lifecycle props from `Sidebar.tsx`, made status-card lifecycle props optional for direct renders, and updated `runtime-utils.test.ts` snapshot fixtures to include lifecycle defaults. - **Files modified:** `tauri-app/src/components/Sidebar.tsx`, `tauri-app/src/features/runtime/components/RuntimeStatusCard.tsx`, `tauri-app/src/features/runtime/runtime-utils.test.ts` - **Verification:** `npm test -- RuntimeSurface` and `npm run build` - **Committed in:** `93f7fd9` (follow-up fix commit) --- **Total deviations:** 1 auto-fixed (1 blocking) **Impact on plan:** The follow-up kept the new UI contract buildable and testable without changing the plan's scope. ## Issues Encountered - The first full frontend build surfaced stale callers that still used the pre-Phase-2 component contracts; the fix was contained to the sidebar shell and helper test fixtures. ## User Setup Required None - no external service configuration required. ## Next Phase Readiness - Phase 2 lifecycle command safety is ready for workspace consolidation in Phase 3. - Phase 3 can now compose the runtime workspace around one trustworthy lifecycle/apply state model instead of duplicated control heuristics. --- *Phase: 02-lifecycle-command-safety* *Completed: 2026-03-29*