From 1f0f7849dbee00a18a11bed81d7e1be0234b7a0f Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:48:11 +0000 Subject: [PATCH] Ember for Miner UI 4 (0.3.16): card.tune_floor (the chosen clock is the ladder's floor), persisted as CardPref.sweep_floor Co-Authored-By: Claude Fable 5.1 --- app/igneum-app/src/config.rs | 3 +++ app/igneum-app/src/engine.rs | 4 ++++ app/igneum-app/src/hotplug.rs | 1 + app/igneum-app/src/state.rs | 1 + docs/plans/ember-tune.md | 2 +- 5 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/igneum-app/src/config.rs b/app/igneum-app/src/config.rs index d523d6db3..cadb016aa 100644 --- a/app/igneum-app/src/config.rs +++ b/app/igneum-app/src/config.rs @@ -39,6 +39,9 @@ pub struct CardPref { pub sweep_class: String, #[serde(default)] pub sweep_source: String, + /// the chosen clock sat on the ladder's floor (the lowest step measured, not the optimum) + #[serde(default)] + pub sweep_floor: bool, /// Miner UI 4 (6 October 2026): this card's goal (efficiency | balanced | rate); empty = the global tune_goal #[serde(default)] pub tune_goal: String, diff --git a/app/igneum-app/src/engine.rs b/app/igneum-app/src/engine.rs index acc8bbd7e..7a69bb149 100644 --- a/app/igneum-app/src/engine.rs +++ b/app/igneum-app/src/engine.rs @@ -2858,6 +2858,10 @@ impl Engine { e.sweep_mhs = row.mhs; e.sweep_clock_mhz = row.point.clock_mhz; e.sweep_mem_mhz = row.point.mem_mhz; + // Miner UI 4: the row's sub-line reads "(the ladder's floor)" when the chosen clock is the lowest step + let floor_point = row.point.clock_mhz > 0 && row.point.clock_mhz <= run.plan.limits.clock_floor(); + e.sweep_floor = floor_point; + c.tune_floor = floor_point; e.sweep_driver = c.driver.clone(); e.sweep_class = c.program_class.clone(); e.sweep_source = kind.name().into(); diff --git a/app/igneum-app/src/hotplug.rs b/app/igneum-app/src/hotplug.rs index c5259f82b..f54a51627 100644 --- a/app/igneum-app/src/hotplug.rs +++ b/app/igneum-app/src/hotplug.rs @@ -170,6 +170,7 @@ pub fn apply_pref(c: &mut CardState, p: &CardPref) { c.tune_goal = p.tune_goal.clone(); c.tune_before_watts = p.sweep_before_watts; c.tune_before_mhs = p.sweep_before_mhs; + c.tune_floor = p.sweep_floor; if p.sweep_mhs > 0.0 && p.sweep_watts > 0.0 { c.tune_line = crate::ember::tuned_line(p.sweep_mhs, p.sweep_watts, p.sweep_eff); } diff --git a/app/igneum-app/src/state.rs b/app/igneum-app/src/state.rs index 196652162..ee090726f 100644 --- a/app/igneum-app/src/state.rs +++ b/app/igneum-app/src/state.rs @@ -129,6 +129,7 @@ pub struct CardState { pub tune_goal: String, // this card's goal override (efficiency | balanced | rate); "" = the global goal pub tune_before_watts: f64, // the untuned point of the last full plan (step 0); 0 = never measured pub tune_before_mhs: f64, + pub tune_floor: bool, // the chosen clock is the ladder's floor (the row's sub-line says so) // a tune in progress on this card, by this engine or by a measurement engine posting /api/tune-progress // (the project lead, 6 October 2026: "don't we need to show in the app that tuning is in progress?") pub tune_step: u32, diff --git a/docs/plans/ember-tune.md b/docs/plans/ember-tune.md index 3ac2fd4da..844ad8eb4 100644 --- a/docs/plans/ember-tune.md +++ b/docs/plans/ember-tune.md @@ -318,7 +318,7 @@ For 0.3.16 (Miner UI 4's Cards tab, Ember as its second layer), on ember-tune pa | Commit | What | Where | |---|---|---| -| (past 7fadd4c) | a per-card goal: `POST /api/tune/goal {key, goal}` (efficiency, balanced, rate; "" or "global" clears), persisted as `CardPref.tune_goal`, echoed as `card.tune_goal` ("" = the global goal), resolved at the tune's start (`ember::goal_for`); the untuned point of the last full plan on the row: `card.tune_before_watts`, `card.tune_before_mhs` (its step 0, kept across confirm plans; `CardPref.sweep_before_*`), so the row can read "saves 84 W, 0.15% of rate" against `sweep_watts` / `sweep_mhs`; Retune = `POST /api/sweep/start {key}` (forced: clears a back-off since 0.3.15) | ember.rs, engine.rs, server.rs, config.rs, state.rs, hotplug.rs + test | +| (past 7fadd4c) | a per-card goal: `POST /api/tune/goal {key, goal}` (efficiency, balanced, rate; "" or "global" clears), persisted as `CardPref.tune_goal`, echoed as `card.tune_goal` ("" = the global goal), resolved at the tune's start (`ember::goal_for`); `card.tune_floor` (the chosen clock is the ladder's floor; `CardPref.sweep_floor`); the untuned point of the last full plan on the row: `card.tune_before_watts`, `card.tune_before_mhs` (its step 0, kept across confirm plans; `CardPref.sweep_before_*`), so the row can read "saves 84 W, 0.15% of rate" against `sweep_watts` / `sweep_mhs`; Retune = `POST /api/sweep/start {key}` (forced: clears a back-off since 0.3.15) | ember.rs, engine.rs, server.rs, config.rs, state.rs, hotplug.rs + test | For the 0.3.15 cut (6 October 2026 evening), on ember-tune: