feat/4-wizard-gating
- WizardState: Codable persisted fields — currentStage, basename, cwd, printerName, sessionMode (profile|calibration), profileBasename; WizardStateStore writes wizard_state.json atomically - WizardGating: pure gating — 1 always; 2 on .ti1; 3 on .ti1+.ti2; 4 on .ti3 only (never .ti2 — #109/#110); 5 on .ti3+profile (#69). Forward gated, backward always; Stage 0 a side-trip - WizardViewModel: setTarget sanitises basename (#60) and resolves cwd (#59); locked forward nav shows a warning banner; windowDidBecomeKey re-probes and drops back to deepest unlocked when files vanish (#151) - RootView: NSWindow.didBecomeKeyNotification -> revalidate - Sidebar stepper enabled state now driven by artefact gating - 11 new tests incl. gating matrix + persistence; 71/71 green Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>