Observed behavior
In macapp/Sources/GoCodeUI/ModelSettingsView.swift, ModelSettingsModel.setCost (lines 132–140) was not brought in line with the fix applied elsewhere in this same file for fetch/setExposed/setAllVisible/saveProvider/delete (epic #991, slice U8, PR TBD):
func setCost(_ provider: String, _ model: String, input: Double, output: Double) async {
do {
try await client.setModelCost(
provider: provider, model: model, input: input, output: output)
await load()
} catch {
status = "Could not save cost: \(error.localizedDescription)"
}
}
The five siblings all call load(clearingStatus: false) on both branches so the message they just set survives the reload (see the load() doc comment at line 40). setCost does not: its success path calls plain load() (clearingStatus: true, the default), and its catch block sets status but never reloads at all. This is the same bug shape the U8 fix addressed for the other five actions — setCost just wasn't included, deliberately, to keep that slice's diff scoped to the findings it was written against.
Expected behavior
setCost should follow the same load(clearingStatus: false) pattern as its siblings on both the success and failure branches, so a status message it sets is not vulnerable to being cleared by a later default-clearing load() and its failure path still refreshes provider/model state.
Reproduction
Preconditions: Settings → Models, a provider with at least one model.
Exact action: Click a model's price, enter a value, Save; observe setCost's catch branch never calls load(), so on failure the provider list is not refreshed to pick up any server-side state change.
Reproduction rate: Deterministic by code inspection (ModelSettingsView.swift:132-140); not exercised against a live daemon in this pass.
Impact
Low severity, UI-consistency only — no data loss or security implication. Confusing feedback if a save fails silently-stale, and this is the last inconsistency in the load(clearingStatus:) pattern introduced for #999/U8.
Suspected seam
Owning file/type: ModelSettingsModel.setCost, macapp/Sources/GoCodeUI/ModelSettingsView.swift:132-140.
Sibling pattern to match: fetch/setExposed/setAllVisible/saveProvider/delete in the same file (all call load(clearingStatus: false)).
Regression test
Add a ModelSettingsModelTests case that sets a fake client to fail setModelCost, asserts model.status still reads the failure message after setCost returns, and — the part not yet covered — asserts providers was refreshed from the fake client's post-failure state (currently it is not, since no reload happens on the catch branch).
Deferred manual smokes from #991 (require a live app/daemon; not run in this pass)
- Transcript autoscroll: scroll-up behavior during live streaming.
- Failed-load retry with the daemon killed mid-session.
- Delete/undo confirmation cancel paths (Sessions).
- Force-rewind "Restore Anyway" path.
- Prompt-history Up/Down navigation with a half-typed draft in the composer.
- VoiceOver and keyboard-only navigation on the Sessions and Models panes.
Latent deferral: caret-aware prompt history (D1 in the plan)
macapp/Package.swift pins .macOS(.v14). Literal caret-position-aware history recall (the #998 wording) needs a SwiftUI TextSelection/caret binding, which is a macOS 15 API, or an NSTextView bridge (NSViewRepresentable). The shipped approximation (recall only when the draft is empty/unchanged) is documented as KTD-7 in the plan; true caret-awareness is out of scope until the platform floor moves or the composer is rebuilt on an NSTextView bridge.
Fix boundaries
In scope (for a follow-up fix): setCost's two branches, matching the sibling pattern; the regression test above.
Out of scope: the deferred manual smokes and the caret-awareness deferral are tracked here for visibility, not for this fix — they need either live-app access or a platform-floor decision, not a code change alone.
Related: #991
Observed behavior
In
macapp/Sources/GoCodeUI/ModelSettingsView.swift,ModelSettingsModel.setCost(lines 132–140) was not brought in line with the fix applied elsewhere in this same file forfetch/setExposed/setAllVisible/saveProvider/delete(epic #991, slice U8, PR TBD):The five siblings all call
load(clearingStatus: false)on both branches so the message they just set survives the reload (see theload()doc comment at line 40).setCostdoes not: its success path calls plainload()(clearingStatus: true, the default), and its catch block setsstatusbut never reloads at all. This is the same bug shape the U8 fix addressed for the other five actions —setCostjust wasn't included, deliberately, to keep that slice's diff scoped to the findings it was written against.Expected behavior
setCostshould follow the sameload(clearingStatus: false)pattern as its siblings on both the success and failure branches, so a status message it sets is not vulnerable to being cleared by a later default-clearingload()and its failure path still refreshes provider/model state.Reproduction
Preconditions: Settings → Models, a provider with at least one model.
Exact action: Click a model's price, enter a value, Save; observe
setCost's catch branch never callsload(), so on failure the provider list is not refreshed to pick up any server-side state change.Reproduction rate: Deterministic by code inspection (
ModelSettingsView.swift:132-140); not exercised against a live daemon in this pass.Impact
Low severity, UI-consistency only — no data loss or security implication. Confusing feedback if a save fails silently-stale, and this is the last inconsistency in the
load(clearingStatus:)pattern introduced for #999/U8.Suspected seam
Owning file/type:
ModelSettingsModel.setCost,macapp/Sources/GoCodeUI/ModelSettingsView.swift:132-140.Sibling pattern to match:
fetch/setExposed/setAllVisible/saveProvider/deletein the same file (all callload(clearingStatus: false)).Regression test
Add a
ModelSettingsModelTestscase that sets a fake client to failsetModelCost, assertsmodel.statusstill reads the failure message aftersetCostreturns, and — the part not yet covered — assertsproviderswas refreshed from the fake client's post-failure state (currently it is not, since no reload happens on the catch branch).Deferred manual smokes from #991 (require a live app/daemon; not run in this pass)
Latent deferral: caret-aware prompt history (D1 in the plan)
macapp/Package.swiftpins.macOS(.v14). Literal caret-position-aware history recall (the#998wording) needs a SwiftUITextSelection/caret binding, which is a macOS 15 API, or anNSTextViewbridge (NSViewRepresentable). The shipped approximation (recall only when the draft is empty/unchanged) is documented as KTD-7 in the plan; true caret-awareness is out of scope until the platform floor moves or the composer is rebuilt on anNSTextViewbridge.Fix boundaries
In scope (for a follow-up fix):
setCost's two branches, matching the sibling pattern; the regression test above.Out of scope: the deferred manual smokes and the caret-awareness deferral are tracked here for visibility, not for this fix — they need either live-app access or a platform-floor decision, not a code change alone.
Related: #991