diff --git a/src/components/settings/__tests__/score-section-saved-selection.test.tsx b/src/components/settings/__tests__/score-section-saved-selection.test.tsx
new file mode 100644
index 000000000..2e92203aa
--- /dev/null
+++ b/src/components/settings/__tests__/score-section-saved-selection.test.tsx
@@ -0,0 +1,213 @@
+/**
+ * What the score settings page does with a selection that is already
+ * stored, and what it puts on the wire when you press Save.
+ *
+ * The v1.35.0 defect this pins the fix for: the page filtered the
+ * selection on its way to the server, so the answer that came back could
+ * never match the form that sent it. The switches then re-seeded from the
+ * server's narrower list — a pillar the person had never touched read as
+ * switched off — and the draft could never equal the server copy again,
+ * which left Save lit and the card claiming unsaved changes forever.
+ *
+ * Two ends and the pipe between them:
+ *
+ * - the rows a stored selection renders (`data-counts` per pillar),
+ * - the state of the Save button, which is the whole "did this settle"
+ * question in one attribute,
+ * - the body the mutation actually hands to `apiPatch`, driven through
+ * the component's own `mutationFn` rather than restated here.
+ *
+ * SSR markup, matching the rest of the settings suite. The draft re-seed
+ * happens in render, so a static render is enough to see it.
+ */
+import { beforeEach, describe, expect, it, vi } from "vitest";
+import { renderToStaticMarkup } from "react-dom/server";
+
+import {
+ SCORE_PILLAR_IDS,
+ type ScorePillarId,
+} from "@/lib/analytics/score/types";
+
+const ALL: ScorePillarId[] = [...SCORE_PILLAR_IDS];
+
+/** The resolved config the page's primary read returns. */
+const configState: { pillars: ScorePillarId[] } = { pillars: [...ALL] };
+
+/** Every `mutationFn` the component registered, newest last. */
+const mutationFns: Array<(input: never) => unknown> = [];
+
+const apiPatch = vi.fn(async () => ({ pillars: configState.pillars }));
+
+vi.mock("@tanstack/react-query", () => ({
+ useQuery: ({ queryKey }: { queryKey: readonly unknown[] }) => {
+ // The factory's key, not a guess: `queryKeys.healthScoreConfig()`.
+ if (
+ Array.isArray(queryKey) &&
+ queryKey[0] === "settings" &&
+ queryKey[1] === "health-score-config"
+ ) {
+ return {
+ data: {
+ pillars: configState.pillars,
+ excludedPillars: ALL.filter(
+ (id) => !configState.pillars.includes(id),
+ ),
+ hasSelection: true,
+ version: 1,
+ changedAt: null,
+ updatedAt: "2026-08-01T00:00:00.000Z",
+ },
+ isSuccess: true,
+ isLoading: false,
+ isError: false,
+ refetch: vi.fn(),
+ };
+ }
+ return {
+ data: undefined,
+ isSuccess: false,
+ isLoading: false,
+ isError: false,
+ refetch: vi.fn(),
+ };
+ },
+ useMutation: (options: { mutationFn?: (input: never) => unknown }) => {
+ if (options.mutationFn) mutationFns.push(options.mutationFn);
+ return { mutate: vi.fn(), isPending: false };
+ },
+ useQueryClient: () => ({
+ setQueryData: vi.fn(),
+ getQueryData: vi.fn(),
+ invalidateQueries: vi.fn(),
+ }),
+}));
+
+vi.mock("sonner", () => ({
+ toast: { message: vi.fn(), error: vi.fn(), success: vi.fn() },
+}));
+
+vi.mock("@/components/outcome/outcome-toast", () => ({
+ toastWrittenOutcome: vi.fn(),
+}));
+
+vi.mock("@/lib/api/api-fetch", () => ({
+ apiGet: vi.fn(),
+ apiPost: vi.fn(),
+ apiPatch: (...args: unknown[]) =>
+ (apiPatch as unknown as (...a: unknown[]) => unknown)(...args),
+ ApiError: class ApiError extends Error {},
+}));
+
+vi.mock("@/hooks/use-auth", () => ({
+ useAuth: () => ({ isAuthenticated: true, isLoading: false, user: {} }),
+}));
+
+vi.mock("@/lib/queries/use-analytics-query", () => ({
+ useAnalyticsQuery: () => ({
+ data: undefined,
+ isError: false,
+ refetch: vi.fn(),
+ }),
+}));
+
+import { I18nProvider } from "@/lib/i18n/context";
+import { ScoreSection } from "../score-section";
+
+function render(): string {
+ return renderToStaticMarkup(
+
+
+ ,
+ );
+}
+
+/** `data-counts` per pillar, read off the rendered rows. */
+function countsByPillar(html: string): Record {
+ const out: Record = {};
+ for (const match of html.matchAll(
+ /data-pillar="([A-Z_]+)"[^>]*data-counts="(true|false)"/g,
+ )) {
+ out[match[1]] = match[2];
+ }
+ return out;
+}
+
+function saveIsDisabled(html: string): boolean {
+ const at = html.indexOf('data-slot="score-config-save"');
+ expect(at, "save button is rendered").toBeGreaterThan(-1);
+ const open = html.lastIndexOf("