Add memory management panel for breadram #78

Merged
Breadway merged 2 commits from feature/ram-27-memory-panel into main 2026-10-14 10:32:59 +08:00
Owner

RAM-27. Live daemon state (mode, pressure, memory, version, effective rules, bounded action history with expected versus measured relief) degrades to an honest absent state with nothing running. Settings edit ~/.config/breadram/breadram.toml non-destructively with atomic backed-up writes; mode and protection changes also go through the daemon validated IPC with optional persist. Profile presets resolve to explicit settings. Registered as the Memory page with search entries and a screenshot view.

Verified in headless sway against a scripted breadramd socket, plus Rust round-trip/refusal tests. Head: d5311d98fb

RAM-27. Live daemon state (mode, pressure, memory, version, effective rules, bounded action history with expected versus measured relief) degrades to an honest absent state with nothing running. Settings edit ~/.config/breadram/breadram.toml non-destructively with atomic backed-up writes; mode and protection changes also go through the daemon validated IPC with optional persist. Profile presets resolve to explicit settings. Registered as the Memory page with search entries and a screenshot view. Verified in headless sway against a scripted breadramd socket, plus Rust round-trip/refusal tests. Head: d5311d98fbf182dcc8c8b4d80bb52309611b73c7
feat: add memory management panel for breadram
Some checks failed
check / check (push) Failing after 10s
d5311d98fb
Live daemon state (mode, pressure, memory, version, effective rules,
bounded action history with expected versus measured relief) degrades to
an honest absent state with nothing running. Settings edit
~/.config/breadram/breadram.toml non-destructively with atomic backed-up
writes; mode and protection changes also go through the daemon's own
validated IPC with optional persist. Profile presets resolve to explicit
settings. Registered as the Memory page with search entries and a
screenshot view.
Author
Owner

Independent review of head d5311d98fb: changes requested, CI red. Do not merge.

Required check state on this exact SHA: check / check (push) is failure (run 148). Local repro: cargo fmt --all -- --check in src/ reports diffs in src/src/commands/breadram.rs (lines 34, 47, 125 and following). cargo test (148 passed) and cargo clippy --all-targets (clean) and svelte-check (0 errors, 0 warnings) pass here, so fmt is the CI blocker. Fix with cargo fmt --all on the branch.

Criterion mapping (all line refs are this head):

  1. Daemon validation and effective settings: partial. set_breadram_mode allow-lists monitor/automatic before the wire (breadram.rs:479) and both mode and protection go through the daemon IPC, good. Effective rules render mode/actions/protected/config_path (Memory.svelte:337-346). But the rules payload's budgets and rules lists (typed at Memory.svelte:73-74) are fetched and never rendered, and the plan (with its explanation of declined actions) is fetched and never rendered. Budgets are part of effective settings per RAM-22, so this is a gap, not a pass.

  2. Why observation-only / idle-unknown / unsupported: missing. The panel never renders plan explanations, requires_confirmed_idle, action states (unsupported/skipped/denied), control levels, or capability reasons. capabilities is extracted in breadram.rs:460 but the Memory view never displays it. History rows show only reason as hint text (Memory.svelte:358-363). A user cannot learn from this panel why a workload is observe-only or an action unsupported.

  3. Host RAM vs VRAM, reload delays, hard-limit consequences: missing. No VRAM display anywhere (the Rust layer drops vram_bytes/gtt_*, Memory.svelte only formats ram_available/ram_total). No reload-delay or hard-limit text in the diff (grep for vram/reload/hard-limit/observation-only across the PR diff is empty).

  4. Atomic save, working config on error, reversible changes: fails on one real defect, rest passes. Atomic backed-up writes via the shared helper and refusal-before-write (breadram.rs:164-217, test bad_values_are_refused_before_touching_the_file) pass; useDraft autosave passes. Defect A: save_config_to rewrites [[providers]] modelling only 5 fields (breadram.rs:221-231), silently deleting daemon fields the panel does not model: credential_ref, igpu, command (the hook program), hook_timeout_ms, hook_max_output_bytes (see breadram-core config/mod.rs ProviderEndpoint). Saving any provider edit on a hook-provider config deletes its command and breaks it. Preserve unmodelled provider keys like the top-level round-trip test already requires. Defect B: gib_to_bytes (breadram.rs:155-157) is unsanitized: NaN passes the < 0.0 guard and writes 0 bytes, +Inf saturates to i64::MAX, no upper bound (frontend caps at 1024 GiB but the command accepts any f64 from the webview). Reject non-finite and unreasonably large values before the write. Note (not a blocker today): apply_profile_to (breadram.rs:248-280) replaces the whole [automation]/[protection] tables; safe only because those tables currently hold single keys.

  5. Opens with no daemon installed, honest absence: pass. Every live call degrades to present: false (breadram.rs:447-473), panel renders Unavailable/Daemon unavailable/Empty states, covered by live_calls_report_presence_and_degrade_to_absence.

  6. Real controls, narrow layouts, accessibility, errors, reconnect in isolation: unverified by this reviewer. Code shows a 10s live poll plus Retry (Memory.svelte:133-141, 219-223), aria-labels on controls, flex-wrap rows. I ran the unit suites but did not repeat the headless sway session; re-verify after rework.

Security (bakery-shipped, webview-exposed): no generic runner (7 typed commands, lib.rs:115-121), no credential or argv handling, provider URLs are stored strings and never fetched, socket messages are fixed-shape with mode allow-listed pre-wire. Protection add/remove strings do reach the wire, but constrained to scope-key lists the daemon validates. No findings here beyond Defect A/B above.

Next action for coordinator: fix fmt, preserve unmodelled provider keys on save, sanitize GiB inputs, render budgets/capabilities/plan-explanation including observe-only and unsupported reasons, add VRAM/reload/hard-limit explanations, then request fresh review. This head must not merge.

Independent review of head d5311d98fbf182dcc8c8b4d80bb52309611b73c7: changes requested, CI red. Do not merge. Required check state on this exact SHA: `check / check (push)` is failure (run 148). Local repro: `cargo fmt --all -- --check` in `src/` reports diffs in `src/src/commands/breadram.rs` (lines 34, 47, 125 and following). `cargo test` (148 passed) and `cargo clippy --all-targets` (clean) and `svelte-check` (0 errors, 0 warnings) pass here, so fmt is the CI blocker. Fix with `cargo fmt --all` on the branch. Criterion mapping (all line refs are this head): 1. Daemon validation and effective settings: partial. `set_breadram_mode` allow-lists monitor/automatic before the wire (breadram.rs:479) and both mode and protection go through the daemon IPC, good. Effective rules render mode/actions/protected/config_path (Memory.svelte:337-346). But the `rules` payload's `budgets` and `rules` lists (typed at Memory.svelte:73-74) are fetched and never rendered, and the `plan` (with its explanation of declined actions) is fetched and never rendered. Budgets are part of effective settings per RAM-22, so this is a gap, not a pass. 2. Why observation-only / idle-unknown / unsupported: missing. The panel never renders plan explanations, `requires_confirmed_idle`, action states (unsupported/skipped/denied), control levels, or capability reasons. `capabilities` is extracted in breadram.rs:460 but the Memory view never displays it. History rows show only `reason` as hint text (Memory.svelte:358-363). A user cannot learn from this panel why a workload is observe-only or an action unsupported. 3. Host RAM vs VRAM, reload delays, hard-limit consequences: missing. No VRAM display anywhere (the Rust layer drops `vram_bytes`/`gtt_*`, Memory.svelte only formats ram_available/ram_total). No reload-delay or hard-limit text in the diff (grep for vram/reload/hard-limit/observation-only across the PR diff is empty). 4. Atomic save, working config on error, reversible changes: fails on one real defect, rest passes. Atomic backed-up writes via the shared helper and refusal-before-write (breadram.rs:164-217, test `bad_values_are_refused_before_touching_the_file`) pass; useDraft autosave passes. Defect A: `save_config_to` rewrites `[[providers]]` modelling only 5 fields (breadram.rs:221-231), silently deleting daemon fields the panel does not model: `credential_ref`, `igpu`, `command` (the hook program), `hook_timeout_ms`, `hook_max_output_bytes` (see breadram-core `config/mod.rs` ProviderEndpoint). Saving any provider edit on a hook-provider config deletes its command and breaks it. Preserve unmodelled provider keys like the top-level round-trip test already requires. Defect B: `gib_to_bytes` (breadram.rs:155-157) is unsanitized: NaN passes the `< 0.0` guard and writes 0 bytes, +Inf saturates to i64::MAX, no upper bound (frontend caps at 1024 GiB but the command accepts any f64 from the webview). Reject non-finite and unreasonably large values before the write. Note (not a blocker today): `apply_profile_to` (breadram.rs:248-280) replaces the whole `[automation]`/`[protection]` tables; safe only because those tables currently hold single keys. 5. Opens with no daemon installed, honest absence: pass. Every live call degrades to `present: false` (breadram.rs:447-473), panel renders Unavailable/Daemon unavailable/Empty states, covered by `live_calls_report_presence_and_degrade_to_absence`. 6. Real controls, narrow layouts, accessibility, errors, reconnect in isolation: unverified by this reviewer. Code shows a 10s live poll plus Retry (Memory.svelte:133-141, 219-223), aria-labels on controls, flex-wrap rows. I ran the unit suites but did not repeat the headless sway session; re-verify after rework. Security (bakery-shipped, webview-exposed): no generic runner (7 typed commands, lib.rs:115-121), no credential or argv handling, provider URLs are stored strings and never fetched, socket messages are fixed-shape with mode allow-listed pre-wire. Protection add/remove strings do reach the wire, but constrained to scope-key lists the daemon validates. No findings here beyond Defect A/B above. Next action for coordinator: fix fmt, preserve unmodelled provider keys on save, sanitize GiB inputs, render budgets/capabilities/plan-explanation including observe-only and unsupported reasons, add VRAM/reload/hard-limit explanations, then request fresh review. This head must not merge.
fix: preserve unmodelled keys, sanitize inputs, render reasons
All checks were successful
check / check (push) Successful in 3m47s
2214f71f16
Provider saves merge into existing tables by name instead of rewriting
them, so hook commands, credential refs, and other unmodelled keys
survive. GiB inputs must be finite, non-negative, and within a pebibyte
before anything is written. The panel now renders budgets, the plan with
its explanation, per-action file-versus-effective state, probed host
capabilities with reasons, device memory as measured-or-honest, per-kind
reload notes, and the no-default-hard-cap note.
Author
Owner

Independent merge-review verdict: PASS on exact head 2214f71f16.

Pre-merge re-checks (fresh, this session):

  • Head unmoved: origin/feature/ram-27-memory-panel == 2214f71 (no pushes since blocked verdict).
  • Base unmoved: origin/main == 14d1315872 == PR base; merge-base == base, PR reports mergeable true.
  • Required check green on exact SHA: check / check (push) success (Actions run 2461, index 149, commit_sha bound to 2214f71, push event on feature/ram-27-memory-panel).
  • Diff intact vs reviewed state: 8 files, +1104/-0, matches prior review scope; cargo fmt check clean re-run on this head.
  • Prior re-review found no code defects on this head; no outstanding change requests via API. Merging with repo default strategy (merge commit) to main, origin only. No tag. No attribution, no em dashes.

Code criteria mapping: see card comment on RAM-27 (re-review of this head). Merging under explicit authorization for this exact SHA only.

Independent merge-review verdict: PASS on exact head 2214f71f166713c890dc4c35930f72c462e0de97. Pre-merge re-checks (fresh, this session): - Head unmoved: origin/feature/ram-27-memory-panel == 2214f71 (no pushes since blocked verdict). - Base unmoved: origin/main == 14d13158722527ff88f810b5c32f6679cea34833 == PR base; merge-base == base, PR reports mergeable true. - Required check green on exact SHA: check / check (push) success (Actions run 2461, index 149, commit_sha bound to 2214f71, push event on feature/ram-27-memory-panel). - Diff intact vs reviewed state: 8 files, +1104/-0, matches prior review scope; cargo fmt check clean re-run on this head. - Prior re-review found no code defects on this head; no outstanding change requests via API. Merging with repo default strategy (merge commit) to main, origin only. No tag. No attribution, no em dashes. Code criteria mapping: see card comment on RAM-27 (re-review of this head). Merging under explicit authorization for this exact SHA only.
Author
Owner

Integration result: PR 78 merged to main as 91cc5206c3 (merge commit, repo default strategy, origin only, no tag). Merged head is the reviewed SHA 2214f71f16; base was 14d1315872; required check check / check (push) was success on the merged head. Branch feature/ram-27-memory-panel preserved for coordinator cleanup. Coordinator to verify integrated behavior; card stays in review per gate rules.

Integration result: PR 78 merged to main as 91cc5206c30d04a1f1961905d353dc38a3319ab8 (merge commit, repo default strategy, origin only, no tag). Merged head is the reviewed SHA 2214f71f166713c890dc4c35930f72c462e0de97; base was 14d13158722527ff88f810b5c32f6679cea34833; required check check / check (push) was success on the merged head. Branch feature/ram-27-memory-panel preserved for coordinator cleanup. Coordinator to verify integrated behavior; card stays in review per gate rules.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/bos-settings!78
No description provided.