Merge ticket 049 (inline profiles into settings.json) with auto-derived-param promotion

worktree-agent-a19b9ef959dcda6b2 (ticket 049) was branched from before "Auto
derived format" (1a481d3) landed on main, so its synchronous
persist_metric_declaration(_update) and ProfileStore::record_metric_declaration(_update)
didn't know about promoting auto-derived engine params into the persisted
profile. This merge reconciles the two:

- src/api.rs: kept the async persist_metric_declaration/_update methods and
  promoted_param_records helper from "Auto derived format", but switched their
  persistence from ProfileStore::load/record_metric_declaration to the new
  Settings-based settings.record_metric_declaration(_update), matching ticket
  049's single-settings.json model. Dropped the now-unused
  active_profile_location helper in favor of locking self.settings directly.
- src/profile.rs: removed the standalone ProfileStore struct/impl entirely
  (049 folds profiles into Settings), keeping load_legacy_profile_store for
  migrating a pre-049 profiles.json. Extended record_metric_declaration and
  record_metric_declaration_update (now methods on Settings) to keep taking
  promoted_params: &[ParamDeclarationRecord], persisting promoted auto-derived
  params alongside the metric via Settings::save. Moved the ticket 037/038
  legacy-shape migration (migrate_legacy_metric_params /
  migrate_duration_value_params) out of the removed ProfileStore::load into a
  new pub(crate) migrate_legacy_profile_shapes(profiles), invoked from
  Settings::load (via a new Settings::migrate_legacy_profile_shapes) so
  profiles inlined in settings.json still get migrated forward on every load.
  Rewrote the ProfileStore-based tests (legacy-shape migration tests, the
  no-op-migration test, and the auto-derived-param promotion round-trip test)
  to exercise Settings directly, including a write_legacy_settings_json helper
  that replaces the old write_legacy_profiles_json.
- src/api.rs tests: rewrote declaring_metric_against_auto_derived_param_promotes_it_into_the_profile
  to create/activate the profile via settings_handle.lock() and reload via
  Settings::load instead of ProfileStore.

Also fixed one clippy::collapsible_if warning introduced by the new
Settings::migrate_legacy_profile_shapes.

cargo build, cargo test (222 passed, 0 failed, 0 ignored), and
cargo clippy --all-targets all pass; no new clippy warnings beyond
pre-existing ones in files untouched by this merge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-06 02:03:22 +01:00
co-authored by Claude Sonnet 5
6 changed files with 624 additions and 494 deletions
+1 -1
View File
@@ -198,7 +198,7 @@ impl From<&Settings> for SettingsDto {
fn from(settings: &Settings) -> Self {
SettingsDto {
color_scheme: settings.color_scheme,
active_profile: settings.profiles.active_profile.clone(),
active_profile: settings.active_profile.clone(),
max_logs: settings.max_logs,
custom_theme_id: settings.custom_theme_id.clone(),
ntfy_topic: settings.ntfy_topic.clone(),