* feat(setup): prompt for local profile on first run
* refactor: encapsulate DB config backup/restore into Settings helpers
Extract backup_database_config() and restore_database_config() on Settings
to replace inline field-by-field save/restore in the setup wizard. Cleaner
interface, consistent with project encapsulation standards.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(setup): address henrypark133 + zmanian review — reorder flow, remove backup/restore (#2389)
- Remove `DatabaseConfigBackup` struct and backup/restore methods;
reorder quick-mode flow so profile selection runs before
`auto_setup_database()`, letting the existing clone→try_load→merge_from
pattern preserve wizard-chosen DB settings naturally (henrypark133).
- Add comment explaining the cfg-gated `loaded` variable shadowing in
`try_load_existing_settings` (zmanian #1).
- Change catch-all `_ =>` to explicit `1 => ... _ => unreachable!()`
in profile match arm (zmanian #3).
- Add caller-level test verifying profile application preserves DB config
through the merge_from cycle (henrypark133 testing feedback).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add extensible deployment profiles (IRONCLAW_PROFILE)
Add a profile system that lets users select a deployment shape with a
single env var. Profiles are partial Settings TOML files merged onto
defaults before config.toml and DB overlays.
Built-in profiles: local, local-sandbox, server, server-multitenant.
Users can create custom profiles in ~/.ironclaw/profiles/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: address review comments — path traversal, case normalization, override order, formatting
- Sanitize IRONCLAW_PROFILE to reject path traversal attempts (/, \, ..)
- Normalize profile name to lowercase for both user-path and built-in lookups
- Fix load_bootstrap_settings to use Settings::default() matching from_env() pattern
- Collapse .unwrap_or_default() onto one line to satisfy rustfmt
- Improve user_profile_overrides_builtin test to exercise actual merge logic
- Add path_traversal_rejected test with 5 malicious name patterns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>