Document omitted float-bar selection fields in SETTINGS_JSON.md (SBS-877) - #316
Document omitted float-bar selection fields in SETTINGS_JSON.md (SBS-877)#316tsouth89 wants to merge 3 commits into
Conversation
…in SETTINGS_JSON.md. The schema doc claimed to mirror settings.rs while omitting two shipped float-bar fields.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
ceiling | 03217ee | Commit Preview URL Branch Preview URL |
Aug 16 2026, 11:33 AM |
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 59 minutes Limit details: You’ve used all 1 included review currently available under your plan. You completed 92 included PR reviews in the past 7 days; at that activity level, included reviews refill at 1 review per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Comment |
Automated reviewNew in this pass: 4 issues.
Resolved since the previous pass: 1. For coding agents: fix BLOCK and FIX IF QUICK findings now; everything else is tracked or informational; never exceed one CodeRev fix round per PR. Advisory. Findings generated by |
…877) `"active"` does not mean "only the app focused right now". `snapshot_now` writes a match into `LAST_ACTIVE` and never clears it, and `selectVisibleFloatBarProviders` keeps that id when the focused window does not match; before anything has matched it returns the pinned list. A reader of the old row would expect the bar to drop the provider as soon as focus left a supported app.
| | `taskbar_widget_open_on_hover` | boolean | `true` | Open the taskbar glance panel after pointer dwell. Safe to edit. | | ||
| | `float_bar_density` | string | `"standard"` | `"compact"`, `"standard"`, or `"detailed"`. Safe to edit. | | ||
| | `float_bar_information_mode` | string | `"exact"` | `"exact"` or `"calm"`. Safe to edit. | | ||
| | `float_bar_selection_mode` | string | `"pinned"` | `"pinned"` (the configured list), `"active"` (the focused supported app), or `"activePlusCritical"` (active plus any pinned provider at or above the warning threshold); an invalid string normalizes to `"pinned"`. The active provider is sticky: focusing an unsupported app keeps the last matched provider, and the pinned list is used until something has matched at least once. Safe to edit. | |
There was a problem hiding this comment.
Stickiness sentence is false after a mapped-but-ineligible app · disposition: fix-if-quick · confidence: high · severity: medium · quick win
The new sentence says focusing an unsupported app keeps the last matched provider. snapshot_now writes every match_foreground_provider hit into LAST_ACTIVE with no enabled/error check, and selectVisibleFloatBarProviders then looks that id up only in allEligible (enabled and error-free). Focus Cursor, then Warp/Gemini/Windsurf/Copilot while that provider is off or errored, then Chrome: last-active is the ineligible id, the lookup misses, and the bar shows the full pinned list instead of Cursor.
Prompt for AI agents
Qualify the new sentence: last-active is shown only while that provider is still enabled and float-bar eligible; focusing a mapped app that is not eligible replaces last-active and the bar returns to the pinned list. Verify against the current code first; if no longer valid, skip with a brief reason. Keep the change minimal.
CodeRev · advisory
| | `taskbar_widget_open_on_hover` | boolean | `true` | Open the taskbar glance panel after pointer dwell. Safe to edit. | | ||
| | `float_bar_density` | string | `"standard"` | `"compact"`, `"standard"`, or `"detailed"`. Safe to edit. | | ||
| | `float_bar_information_mode` | string | `"exact"` | `"exact"` or `"calm"`. Safe to edit. | | ||
| | `float_bar_selection_mode` | string | `"pinned"` | `"pinned"` (the configured list), `"active"` (the focused supported app), or `"activePlusCritical"` (active plus any pinned provider at or above the warning threshold); an invalid string normalizes to `"pinned"`. The active provider is sticky: focusing an unsupported app keeps the last matched provider, and the pinned list is used until something has matched at least once. Safe to edit. | |
There was a problem hiding this comment.
activePlusCritical scope misstates empty float_bar_provider_ids · disposition: fix-if-quick · confidence: medium · severity: low · quick win
The new row says activePlusCritical shows "active plus any pinned provider at or above the warning threshold". When float_bar_provider_ids is [] (the default, meaning all enabled providers) the effective pinned set is all enabled providers, not an explicit pinned subset. A user with the default empty list will read "pinned provider" as "explicitly pinned" and expect no critical overlay unless they pinned something, but the implementation will evaluate every enabled provider against the warning threshold and show more icons than documented.
Prompt for AI agents
Clarify that "pinned" means the effective display set: float_bar_provider_ids when non-empty, otherwise all enabled providers. State that the warning-threshold check is applied to that effective set. Verify against the current code first; if no longer valid, skip with a brief reason. Keep the change minimal.
CodeRev · advisory
| | `taskbar_widget_open_on_hover` | boolean | `true` | Open the taskbar glance panel after pointer dwell. Safe to edit. | | ||
| | `float_bar_density` | string | `"standard"` | `"compact"`, `"standard"`, or `"detailed"`. Safe to edit. | | ||
| | `float_bar_information_mode` | string | `"exact"` | `"exact"` or `"calm"`. Safe to edit. | | ||
| | `float_bar_selection_mode` | string | `"pinned"` | `"pinned"` (the configured list), `"active"` (the focused supported app), or `"activePlusCritical"` (active plus any pinned provider at or above the warning threshold); an invalid string normalizes to `"pinned"`. The active provider is sticky: focusing an unsupported app keeps the last matched provider, and the pinned list is used until something has matched at least once. Safe to edit. | |
There was a problem hiding this comment.
Sticky active provider docs omit unavailable-provider fallback · disposition: fix-if-quick · confidence: medium · severity: low · quick win
Docs state focusing an unsupported app keeps the last matched provider and the pinned list is used until something has matched. If that last-matched provider is later disabled, removed from float_bar_provider_ids, or uninstalled, the sticky reference points to a provider no longer in the enabled/effective set. Docs do not say whether the bar keeps showing a stale provider, clears, or falls back to the pinned list, so the observed fallback is undocumented.
Prompt for AI agents
Document the fallback: when the sticky last-active provider is no longer enabled/effective, the bar reverts to the pinned list until the next supported foreground match. Verify against the current code first; if no longer valid, skip with a brief reason. Keep the change minimal.
CodeRev · advisory
| | `taskbar_widget_open_on_hover` | boolean | `true` | Open the taskbar glance panel after pointer dwell. Safe to edit. | | ||
| | `float_bar_density` | string | `"standard"` | `"compact"`, `"standard"`, or `"detailed"`. Safe to edit. | | ||
| | `float_bar_information_mode` | string | `"exact"` | `"exact"` or `"calm"`. Safe to edit. | | ||
| | `float_bar_selection_mode` | string | `"pinned"` | `"pinned"` (the configured list), `"active"` (the focused supported app), or `"activePlusCritical"` (active plus any pinned provider at or above the warning threshold); an invalid string normalizes to `"pinned"`. The active provider is sticky: focusing an unsupported app keeps the last matched provider, and the pinned list is used until something has matched at least once. Safe to edit. | |
There was a problem hiding this comment.
Invalid-string normalization omits case/whitespace handling · disposition: fix-if-quick · confidence: medium · severity: low · quick win
Docs say an invalid string normalizes to "pinned" but do not define what counts as invalid. A user writing "Active", "ACTIVE" or " active " in settings.json will silently fall back to pinned with no error, thinking active mode is enabled. Whether the parser is case-sensitive and whitespace-sensitive determines if this silent fallback occurs on realistic hand-edits.
Prompt for AI agents
Document exact matching rules (case-sensitive, no trimming) or make the parser trim/case-fold and document it; add a note that any non-exact value falls back to pinned. Verify against the current code first; if no longer valid, skip with a brief reason. Keep the change minimal.
CodeRev · advisory
…(SBS-877) Four things the previous wording got wrong or left out. "Any pinned provider at or above the warning threshold" reads as "only what I explicitly pinned", but `float_bar_provider_ids` defaults to empty and `pinned` in FloatBar.tsx then means every enabled provider, so the critical overlay is evaluated against a much wider set than a hand-editor expects. Stickiness is not just about unsupported windows. `snapshot_now` writes every `match_foreground_provider` hit into `LAST_ACTIVE` with no enabled or error check, and `selectVisibleFloatBarProviders` looks that id up only in the eligible set. Focus a mapped app whose provider is off or failing and the sticky id becomes unusable, so the bar drops back to the display set rather than keeping the provider you last used. Same path covers a provider that is later disabled or unpinned. `normalize_float_bar_selection_mode` matches the three tokens exactly, with no trim and no case folding, so `"Active"` and `" active "` silently become `"pinned"`. The row now says so rather than leaving "an invalid string" to the reader.
SBS-877 implementation report
Branch:
fix/sbs-877-settings-json-float-bar-fieldsat5ec975cd(origin/main).Worktree:
/home/box/projects/ceiling-sbs-877only.Linear: not commented, not closed, not edited.
Diff summary
One file:
docs/SETTINGS_JSON.md.Inserted two top-level table rows between
float_bar_information_modeandfloat_bar_contrast:float_bar_selection_mode"pinned""pinned"(the configured list),"active"(the focused supported app), or"activePlusCritical"(active plus any pinned provider at or above the warning threshold); an invalid string normalizes to"pinned". Safe to edit.float_bar_foreground_detectiontruefalse,"active"/"activePlusCritical"keep the pinned list and do not read the focused window. Safe to edit.No Rust, TS, locale, CHANGELOG, or
docs/audit/changes.A user who hand-edits
%APPDATA%\Ceiling\settings.jsoncan now set Active / Active+critical ("active"/"activePlusCritical") and Watch focused app (float_bar_foreground_detection) from the documented table.Every factual claim written, and where it was checked
float_bar_selection_modefloat_bar_selection_moderust/src/settings.rs:348(pub float_bar_selection_mode: String);rust/src/settings/raw.rs:178;Settingsuses default serde field names (settings.rs:93–96, norename_all). Deserialize goes throughRawSettings(settings.rs:95).Stringon bothSettings(settings.rs:348) andRawSettings(raw.rs:178). Table style for otherStringfields isstring."pinned"default_float_bar_selection_mode()returns"pinned".to_string()(settings.rs:433–435).Settings::defaultassignsdefault_float_bar_selection_mode()(settings.rs:703). BothSettingsandRawSettingsuse#[serde(default = "default_float_bar_selection_mode")](settings.rs:347,raw.rs:177). Testtest_settings_defaultassertssettings.float_bar_selection_mode == "pinned"(tests.rs:12)."pinned","active","activePlusCritical"settings.rs:344–346).normalize_float_bar_selection_modematch arms accept"active"and"activePlusCritical"; every other input, including"pinned", becomes"pinned"(settings.rs:440–446). Tests pin"pinned"/"active"/"activePlusCritical"(tests.rs:289–294). UI select options are exactly those three tokens (SettingsSection.tsx:510–516)."pinned"means the configured listsettings.rs:344–345:"pinned" (the configured list)."active"means the focused supported appsettings.rs:345:"active" (the focused supported app)."activePlusCritical"means active plus any pinned provider at or above the warning thresholdsettings.rs:345–346:"activePlusCritical" (active plus any pinned provider at or above the warning threshold)."pinned"_arm ofnormalize_float_bar_selection_mode(settings.rs:444). Applied on load inFrom<RawSettings>(raw.rs:676–678). Tests:""→"pinned","Active"→"pinned"(tests.rs:295–296). No other accepted tokens exist in that match.SettingsSection.tsx:503–521). Not marked leave-unchanged likefloat_bar_show_cost/unrecognized_provider_configs.UI (not claimed in the table; checked so the report does not invent a control): Preferences select labeled
FloatBarProvidersMode="Providers shown"(en-US.ftl:736). Help text describes pinned / active / active+critical (en-US.ftl:737). Select is disabled whensavingor!settings.floatBarEnabled(SettingsSection.tsx:509).float_bar_foreground_detectionfloat_bar_foreground_detectionsettings.rs:353;raw.rs:180. Same default serde names.boolon both (settings.rs:353,raw.rs:180). Table style for otherboolfields isboolean.true(missing key istrue, not the bool type default)#[serde(default = "default_true")]onSettings(settings.rs:352) andRawSettings(raw.rs:179).default_true()returnstrue(settings.rs:562–564).Settings::defaultsetsfloat_bar_foreground_detection: true(settings.rs:704). Testtest_settings_defaultassertssettings.float_bar_foreground_detection(tests.rs:13). There is no extra normalize:From<RawSettings>copies the bool through (raw.rs:679).false,"active"/"activePlusCritical"keep the pinned list and do not read the focused windowsettings.rs:350–351:When false, active / active-plus-critical modes keep the pinned list and do not read the focused window.Table uses the stored tokens so a hand-editor can copy them.SettingsSection.tsx:523–537).UI (not claimed in the table): Toggle labeled
WatchFocusedApp="Watch focused app"(en-US.ftl:741). Disabled whensavingor float bar is off or selection mode is"pinned"(SettingsSection.tsx:531–535).Claims I did not write
Active,active_plus_critical,active+critical, etc.).SettingsSection.tsx:531–535; the persisted value still stores if a hand-edit sets it while mode is"pinned".rust/,apps/,.github/forSETTINGS_JSON/settings.json.mdreturned no hits). Rule 6 (fail-without-fix) does not apply to a table row unless a test already pins the table.Sweep results
1.
Settings/RawSettingsvs top-level tableExtracted every
pubfield onSettings(settings.rs:96–391) and every field onRawSettings(raw.rs:16–199), then diffed against the table after the edit.Settingspub fields: 68. Table rows after the edit: 68.Settingsbut not table, before the edit:float_bar_selection_mode,float_bar_foreground_detection. After: none.Settings: none.Settingsdeclaration order (python check:fields == table_fields).RawSettingsfields not onSettings(28 legacy flat keys):claude_usage_source,codex_usage_source,codex_cookie_source,codex_historical_tracking,codex_openai_web_extras,claude_cookie_source,cursor_cookie_source,opencode_cookie_source,opencode_workspace_id,factory_cookie_source,alibaba_cookie_source,alibaba_cookie_header,alibaba_api_region,kimi_cookie_source,kimi_manual_cookie_header,minimax_cookie_source,augment_cookie_source,augment_cookie_header,amp_cookie_source,amp_cookie_header,ollama_cookie_source,ollama_cookie_header,zai_api_region,jetbrains_ide_base_path,minimax_cookie_header,minimax_api_token,minimax_api_region,claude_avoid_keychain_prompts.These are load-only migration fields (
raw.rs:72–128).RawSettingsdocs say saves go throughSettingsSerialize and write only the new format (raw.rs:12–13).SETTINGS_JSON.md:100–102(after the insert: lines 100–102 in the original file at 98–100) already says legacy flat fields are accepted on load and migrated intoprovider_configs. I did not add them as top-level table rows: they are not current persisted settings.No other omitted top-level persisted
Settingsfield. Nothing else of this class to add.2.
provider_configsvsProviderConfigProviderConfig(types.rs:278–311):cookie_source,usage_source,api_region,manual_cookie_header,api_token,workspace_id,gateway_url,ide_base_path,openai_web_extras,spark_usage_visible,historical_tracking,avoid_keychain_prompts.Documented: all of those except
manual_cookie_headerandapi_token.Mismatches (left out on purpose):
manual_cookie_header—#[serde(default, skip_serializing)](types.rs:288–289). Comment: accepted only to migrate older settings; secrets must never be serialized back into the general settings document (types.rs:285–287).api_token— same skip (types.rs:290–291).SETTINGS_JSON.mdSecrets section already says API keys and manual cookies live in DPAPI stores, notsettings.json. Adding those two as Safe-to-edit rows would contradict that and the skip. They are not omitted persisted settings of the same class as the float-bar fields.Documented
usage_sourcedefault"auto"is still true: accessorSettings::usage_sourceunwraps toDEFAULT_PROVIDER_SOURCE(settings.rs:1172–1178), andDEFAULT_PROVIDER_SOURCEis"auto"(settings.rs:574). I did not change that row.3. Other docs (except
docs/audit/)rg for
float_bar_selection_mode,float_bar_foreground_detection, settings-schema completeness, and float-bar setting lists indocs/excludingdocs/audit/:docs/SETTINGS_JSON.md— the completeness claim at lines 5–6 (mirrors the fields in rust/src/settings.rs and rust/src/settings/raw.rs). This is the file that omitted the two fields. Fixed.docs/CLI.md:256— link only:- [SETTINGS_JSON.md](SETTINGS_JSON.md). Does not list fields.docs/DATA_SOURCES.md:21— link only: schema pointer toSETTINGS_JSON.md. Does not list fields.docs/CEILING_UI.md— visual system; no settings-schema field list.README.md,CHANGELOG.md,CONTRIBUTING.md,docs/HANDOFF.md,docs/BUILDING.md,rust/CHANGELOG.md— no hits for these two field names.No other maintained doc claims completeness and omits these two fields. No second schema-doc fix.
4. Tests
No existing test pins
SETTINGS_JSON.md. I did not invent one. Rule 6 does not apply.I did not run
cargo fmt,cargo clippy, orcargo test. CI required jobs (.github/workflows/ci.yml) are Frontend (pnpm test/pnpm build), Rust/shared (cargo fmt --all --check,cargo test --manifest-path rust/Cargo.toml,cargo clippy ... -D warnings), and Rust/desktop (cargo test/clippyon the Tauri crate). None of those read this markdown table. This change cannot make those jobs fail, and running them would not verify the table.Gaps / what I did not do
docs/audit/.ceiling-sbs-872,ceiling-sbs-876,cubby*,toolport*,matteshot*).provider_metricsallowed values, threshold object shape, or other existing table notes. Those rows were not in this ticket; I did not re-verify every existing note, only the two new rows plus the sweep diffs above.settings.jsonon Windows.settings.rs~327–331 andraw.rs~171–172. On this tree the fields are atsettings.rs:344–353andraw.rs:177–180. The code on disk won; I used the lines I opened.What this change makes more likely (rule 9)
"active"/"activePlusCritical"will happen more often. Downstream of that, foreground-window matching (apps/desktop-tauri/src-tauri/src/foreground.rs) runs when detection is on and mode is not pinned. Any latent matching bug will fire more often for people who only use the JSON file."Active"or"active_plus_critical". Normalize already maps those to"pinned"(settings.rs:444, teststests.rs:295–296). The table now states that fallback, so a failed hand-edit looks like “it ignored me and stayed pinned” rather than an undocumented no-op. That silent fallback was already the load behavior.float_bar_foreground_detectiontofalsewhile mode is"pinned"will look like a no-op in the UI (toggle is disabled in pinned mode) but the value persists and applies the next time mode is active. That was already true; documenting the bool makes that sequence more likely.Settingsfields. Future omitted fields will be harder to notice without a table test. Drift is still likely because no test pins the table.Whether I committed
Yes. Local commit
3b66db3donfix/sbs-877-settings-json-float-bar-fields(docs/SETTINGS_JSON.mdonly, +2 lines). Not pushed. Every new token was checked against source; the sweep found no second omitted persisted top-level field. Quality-gate items that apply to a table row (claims, sweep, no invented test) passed.Note
Document
float_bar_selection_modeandfloat_bar_foreground_detectionfields in SETTINGS_JSON.mdAdds two previously undocumented top-level fields to the SETTINGS_JSON.md reference table.
float_bar_selection_mode(default"pinned") controls which windows are selected by the float bar, with documented behavior for"pinned","active", and"activePlusCritical"values including matching rules and fallback behavior.float_bar_foreground_detection(defaulttrue) is a boolean that affects behavior when active selection modes are in use.Macroscope summarized 03217ee.