diff --git a/CHANGELOG.md b/CHANGELOG.md
index 278995c..9037da6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -246,6 +246,15 @@ for every approved plan. Desktop's version follows the engine generation, so it
a sticky header, or the suggestion list a field opens when it is filled.
### Fixed
+- **Switching to a cloud model no longer repeats the subscription notice.** Picking a cloud model
+ announced that cloud models need an ollama.com subscription. It was meant to say so once, but the
+ "already said it" memory belonged to a single agent rather than the app, so every agent you
+ switched said it again — and a tab restored onto a cloud model marked the notice as shown without
+ displaying it, suppressing it for the rest of that session. The notice is gone entirely rather
+ than repaired: the model chip already marks a model as `cloud`, and if a cloud request actually
+ fails you now get the only message that was ever actionable — that the account is signed in but
+ has no active subscription. The setup wizard still explains cloud versus local while you are
+ choosing, and still offers to sign you in when you are not.
- **Deleting a snapshot, past conversation, or note no longer resets the list.** These panels
rebuilt themselves after every deletion, so the surviving cards slid back up and expanded project
groups collapsed — losing your place in the middle of tidying up. The lists now update in place:
diff --git a/src/MandoCode.Desktop.Tests/ModelNoticeReplayTests.cs b/src/MandoCode.Desktop.Tests/ModelNoticeReplayTests.cs
index c05e92e..b97bafe 100644
--- a/src/MandoCode.Desktop.Tests/ModelNoticeReplayTests.cs
+++ b/src/MandoCode.Desktop.Tests/ModelNoticeReplayTests.cs
@@ -20,6 +20,23 @@ public void RepeatedRestoresDropAllHistoricalSetupNoticesButKeepConversation()
Assert.Equal(replay, replay.Where(h => !ModelNoticeReplay.IsTransient(h)));
}
+ [Fact]
+ public void TheRetiredCloudNoticeIsStrippedInBothOfItsWordings()
+ {
+ // The notice is no longer produced at all — a model switch says nothing about cloud
+ // subscriptions now. But it sits in the journals of anyone who switched to a cloud model
+ // before it was removed, and replay is the ONLY thing keeping it off screen, so both
+ // shipped wordings have to stay recognised.
+ Assert.True(ModelNoticeReplay.IsTransient(
+ Notice("Cloud models run on ollama.com and need an active cloud subscription.")));
+
+ // The 0.14.x wording. Journaled HTML-ENCODED, because it contains an apostrophe — matching
+ // it against a raw literal silently fails, which is how it would come back on restore.
+ Assert.True(ModelNoticeReplay.IsTransient(
+ Notice("Cloud model — runs on ollama.com's servers and needs an account with an " +
+ "active cloud subscription. Without one, requests return 403 Forbidden.")));
+ }
+
[Fact]
public void QuotedWordingAndActualWarningsArePreserved()
{
@@ -28,5 +45,13 @@ public void QuotedWordingAndActualWarningsArePreserved()
Assert.False(ModelNoticeReplay.IsTransient(Notice(Sizing, "warn")));
Assert.False(ModelNoticeReplay.IsTransient(Notice("The context window is too small for this request.")));
Assert.False(ModelNoticeReplay.IsTransient(Notice("Project root changed to: C:\\project")));
+
+ // The setup wizard's cloud-vs-local explainer is also a dim notice and mentions the same
+ // subscription. It is part of a walkthrough the user went through, so it is history and
+ // must survive — the match is on the exact retired notices, not on the word "cloud".
+ Assert.False(ModelNoticeReplay.IsTransient(Notice(
+ "Cloud models run on ollama.com's servers: more capable, no GPU needed, but they " +
+ "require an ollama.com account with an active cloud subscription. Local models run " +
+ "privately on your own hardware, free — bigger is smarter but needs more memory.")));
}
}
diff --git a/src/MandoCode.Desktop/Services/ModelNoticeReplay.cs b/src/MandoCode.Desktop/Services/ModelNoticeReplay.cs
index c55b7eb..52ee00e 100644
--- a/src/MandoCode.Desktop/Services/ModelNoticeReplay.cs
+++ b/src/MandoCode.Desktop/Services/ModelNoticeReplay.cs
@@ -1,3 +1,4 @@
+using System.Net;
using System.Text.RegularExpressions;
namespace MandoCode.Desktop.Services;
@@ -5,6 +6,20 @@ namespace MandoCode.Desktop.Services;
///