diff --git a/ui/src/pages/InstanceExperimentalSettings.test.tsx b/ui/src/pages/InstanceExperimentalSettings.test.tsx
index 1cfa6da65e..3e6ae06160 100644
--- a/ui/src/pages/InstanceExperimentalSettings.test.tsx
+++ b/ui/src/pages/InstanceExperimentalSettings.test.tsx
@@ -862,3 +862,67 @@ describe("InstanceExperimentalSettings — cloud-managed keys", () => {
expect(mockInstanceSettingsApi.updateExperimental).toHaveBeenCalledWith({ enableApps: true });
});
});
+
+describe("InstanceExperimentalSettings — card ordering and headings (PAP-393)", () => {
+ let container: HTMLDivElement;
+ let root: Root | null = null;
+
+ async function renderPage(settings: InstanceExperimentalSettingsWithManaged) {
+ mockInstanceSettingsApi.getExperimental.mockResolvedValue({ ...settings });
+ root = createRoot(container);
+ const queryClient = new QueryClient({
+ defaultOptions: { queries: { retry: false } },
+ });
+ flushSync(() => {
+ root!.render(
+
+
+ ,
+ );
+ });
+ await flushReact();
+ }
+
+ beforeEach(() => {
+ container = document.createElement("div");
+ document.body.appendChild(container);
+ mockInstanceSettingsApi.updateExperimental.mockImplementation(async (patch) => ({
+ ...defaultExperimentalSettings(),
+ ...patch,
+ }));
+ });
+
+ afterEach(() => {
+ flushSync(() => {
+ root?.unmount();
+ });
+ root = null;
+ container.remove();
+ vi.clearAllMocks();
+ });
+
+ it("renders every card heading in alphabetical order", async () => {
+ await renderPage(defaultExperimentalSettings());
+
+ const headings = [...container.querySelectorAll("h2")].map(
+ (heading) => heading.textContent ?? "",
+ );
+
+ // Sanity: the page rendered a meaningful set of cards, not an empty list.
+ expect(headings.length).toBeGreaterThan(10);
+
+ const alphabetical = [...headings].sort((a, b) =>
+ a.localeCompare(b, undefined, { sensitivity: "base" }),
+ );
+ expect(headings).toEqual(alphabetical);
+ });
+
+ it("no longer renders an 'Experimental' secondary badge on any card", async () => {
+ await renderPage(defaultExperimentalSettings());
+
+ const badges = [...container.querySelectorAll('[data-slot="badge"]')].map(
+ (badge) => badge.textContent?.trim(),
+ );
+ expect(badges).not.toContain("Experimental");
+ });
+});
diff --git a/ui/src/pages/InstanceExperimentalSettings.tsx b/ui/src/pages/InstanceExperimentalSettings.tsx
index d450863600..40a2a40359 100644
--- a/ui/src/pages/InstanceExperimentalSettings.tsx
+++ b/ui/src/pages/InstanceExperimentalSettings.tsx
@@ -87,7 +87,6 @@ function ManagedByCloudBadge() {
function ExperimentalToggleCard({
title,
- experimental = false,
description,
footnote,
checked,
@@ -97,7 +96,6 @@ function ExperimentalToggleCard({
ariaLabel,
}: {
title: string;
- experimental?: boolean;
description: string;
footnote?: string;
checked: boolean;
@@ -113,7 +111,6 @@ function ExperimentalToggleCard({
{title}
- {experimental ? Experimental : null}
{isManaged ? : null}
{description}
@@ -460,66 +457,8 @@ export function InstanceExperimentalSettings() {
)}
- {inWorktree ? (
-
-
-
-
-
-
Run tasks in this worktree
- {worktreeRunExecutionManaged ? : null}
-
-
- This is an isolated git-worktree preview instance. Turn this on to let the scheduler execute runs
- here. Only tasks created after enabling will run automatically — copied/pre-existing tasks stay
- parked. Toggling off and on resets the cutoff.
-
-
-
{
- if (worktreeRunExecutionManaged) return;
- toggleMutation.mutate({ enableWorktreeRunExecution: checked });
- }}
- disabled={toggleMutation.isPending || worktreeRunExecutionManaged}
- aria-label="Toggle worktree run execution setting"
- />
-
-
- {worktreeRunExecutionState.kind === "armed" ? (
-
-
-
- Running tasks created after{" "}
-
- {formatActivationTimestamp(worktreeRunExecutionState.activatedAt)}
-
- .
-
-
- ) : null}
-
- {worktreeRunExecutionState.kind === "fail_closed" ? (
-
-
-
-
Execution is suppressed — effectively off.
-
- {worktreeRunExecutionState.reason === "instance_mismatch"
- ? "This setting was armed in a different instance and copied here, so no tasks run automatically."
- : "This setting is missing its activation cutoff, so no tasks run automatically."}{" "}
- Toggle it off and back on to arm execution for tasks created here.
-
-
-
- ) : null}
-
-
- ) : null}
-
toggleMutation.mutate({ enableApps: checked })}
@@ -528,206 +467,6 @@ export function InstanceExperimentalSettings() {
ariaLabel="Toggle apps experimental setting"
/>
- toggleMutation.mutate({ enableCases: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableCases}
- ariaLabel="Toggle cases experimental setting"
- />
-
- toggleMutation.mutate({ enableEnvironments: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableEnvironments}
- ariaLabel="Toggle environments experimental setting"
- />
-
- toggleMutation.mutate({ enableBuiltInAgents: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableBuiltInAgents}
- ariaLabel="Toggle built-in agents experimental setting"
- />
-
- toggleMutation.mutate({ enableBetaSkills: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableBetaSkills}
- ariaLabel="Toggle beta skills experimental setting"
- />
-
-
- toggleMutation.mutate(
- checked || !enableStatusCards
- ? { enableSummaries: checked }
- : { enableSummaries: false, enableStatusCards: false },
- )
- }
- disabled={toggleMutation.isPending || summariesRequiredByManagedStatusCards}
- managed={managedKeys.enableSummaries}
- ariaLabel="Toggle summaries experimental setting"
- />
-
- toggleMutation.mutate({ enableExperimentalFileViewer: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableExperimentalFileViewer}
- ariaLabel="Toggle experimental file viewer setting"
- />
-
-
- toggleMutation.mutate(
- checked
- ? { enableSummaries: true, enableStatusCards: true }
- : { enableStatusCards: false },
- )
- }
- disabled={toggleMutation.isPending || statusCardsBlockedByManagedSummaries}
- managed={managedKeys.enableStatusCards}
- ariaLabel="Toggle status cards experimental setting"
- />
-
- toggleMutation.mutate({ enableExternalObjects: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableExternalObjects}
- ariaLabel="Toggle external objects experimental setting"
- />
-
- toggleMutation.mutate({ enableDecisions: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableDecisions}
- ariaLabel="Toggle decisions experimental setting"
- />
-
- toggleMutation.mutate({ enableGoalsSidebarLink: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableGoalsSidebarLink}
- ariaLabel="Toggle goals sidebar link experimental setting"
- />
-
- toggleMutation.mutate({ enableIsolatedWorkspaces: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableIsolatedWorkspaces}
- ariaLabel="Toggle isolated workspaces experimental setting"
- />
-
- {SHOW_CONFERENCE_ROOM_EXPERIMENTAL_SETTING ? (
- toggleMutation.mutate({ enableConferenceRoomChat: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableConferenceRoomChat}
- ariaLabel="Toggle conference room chat experimental setting"
- />
- ) : null}
-
- toggleMutation.mutate({ enableIssuePlanDecompositions: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableIssuePlanDecompositions}
- ariaLabel="Toggle task plan decomposition panel experimental setting"
- />
-
- toggleMutation.mutate({ enableTaskChatRedesign: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableTaskChatRedesign}
- ariaLabel="Toggle chat-style tasks experimental setting"
- />
-
- toggleMutation.mutate({ enableTaskWatchdogs: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableTaskWatchdogs}
- ariaLabel="Toggle task watchdogs experimental setting"
- />
-
- toggleMutation.mutate({ enableServerInfoDebugView: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableServerInfoDebugView}
- ariaLabel="Toggle server info debug view experimental setting"
- />
-
- toggleMutation.mutate({ enableSmokeLab: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.enableSmokeLab}
- ariaLabel="Toggle smoke lab experimental setting"
- />
-
- toggleMutation.mutate({ autoRestartDevServerWhenIdle: checked })}
- disabled={toggleMutation.isPending}
- managed={managedKeys.autoRestartDevServerWhenIdle}
- ariaLabel="Toggle guarded dev-server auto-restart"
- />
-
@@ -818,6 +557,261 @@ export function InstanceExperimentalSettings() {
+
toggleMutation.mutate({ autoRestartDevServerWhenIdle: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.autoRestartDevServerWhenIdle}
+ ariaLabel="Toggle guarded dev-server auto-restart"
+ />
+
+ toggleMutation.mutate({ enableBetaSkills: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableBetaSkills}
+ ariaLabel="Toggle beta skills experimental setting"
+ />
+
+ toggleMutation.mutate({ enableBuiltInAgents: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableBuiltInAgents}
+ ariaLabel="Toggle built-in agents experimental setting"
+ />
+
+ toggleMutation.mutate({ enableCases: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableCases}
+ ariaLabel="Toggle cases experimental setting"
+ />
+
+ toggleMutation.mutate({ enableTaskChatRedesign: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableTaskChatRedesign}
+ ariaLabel="Toggle chat-style tasks experimental setting"
+ />
+
+ {SHOW_CONFERENCE_ROOM_EXPERIMENTAL_SETTING ? (
+ toggleMutation.mutate({ enableConferenceRoomChat: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableConferenceRoomChat}
+ ariaLabel="Toggle conference room chat experimental setting"
+ />
+ ) : null}
+
+ toggleMutation.mutate({ enableDecisions: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableDecisions}
+ ariaLabel="Toggle decisions experimental setting"
+ />
+
+ toggleMutation.mutate({ enableEnvironments: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableEnvironments}
+ ariaLabel="Toggle environments experimental setting"
+ />
+
+ toggleMutation.mutate({ enableExternalObjects: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableExternalObjects}
+ ariaLabel="Toggle external objects experimental setting"
+ />
+
+ toggleMutation.mutate({ enableIsolatedWorkspaces: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableIsolatedWorkspaces}
+ ariaLabel="Toggle isolated workspaces experimental setting"
+ />
+
+ toggleMutation.mutate({ enableExperimentalFileViewer: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableExperimentalFileViewer}
+ ariaLabel="Toggle experimental file viewer setting"
+ />
+
+ toggleMutation.mutate({ enableGoalsSidebarLink: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableGoalsSidebarLink}
+ ariaLabel="Toggle goals sidebar link experimental setting"
+ />
+
+ {inWorktree ? (
+
+
+
+
+
+
Run tasks in this worktree
+ {worktreeRunExecutionManaged ? : null}
+
+
+ This is an isolated git-worktree preview instance. Turn this on to let the scheduler execute runs
+ here. Only tasks created after enabling will run automatically — copied/pre-existing tasks stay
+ parked. Toggling off and on resets the cutoff.
+
+
+
{
+ if (worktreeRunExecutionManaged) return;
+ toggleMutation.mutate({ enableWorktreeRunExecution: checked });
+ }}
+ disabled={toggleMutation.isPending || worktreeRunExecutionManaged}
+ aria-label="Toggle worktree run execution setting"
+ />
+
+
+ {worktreeRunExecutionState.kind === "armed" ? (
+
+
+
+ Running tasks created after{" "}
+
+ {formatActivationTimestamp(worktreeRunExecutionState.activatedAt)}
+
+ .
+
+
+ ) : null}
+
+ {worktreeRunExecutionState.kind === "fail_closed" ? (
+
+
+
+
Execution is suppressed — effectively off.
+
+ {worktreeRunExecutionState.reason === "instance_mismatch"
+ ? "This setting was armed in a different instance and copied here, so no tasks run automatically."
+ : "This setting is missing its activation cutoff, so no tasks run automatically."}{" "}
+ Toggle it off and back on to arm execution for tasks created here.
+
+
+
+ ) : null}
+
+
+ ) : null}
+
+ toggleMutation.mutate({ enableServerInfoDebugView: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableServerInfoDebugView}
+ ariaLabel="Toggle server info debug view experimental setting"
+ />
+
+ toggleMutation.mutate({ enableSmokeLab: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableSmokeLab}
+ ariaLabel="Toggle smoke lab experimental setting"
+ />
+
+
+ toggleMutation.mutate(
+ checked
+ ? { enableSummaries: true, enableStatusCards: true }
+ : { enableStatusCards: false },
+ )
+ }
+ disabled={toggleMutation.isPending || statusCardsBlockedByManagedSummaries}
+ managed={managedKeys.enableStatusCards}
+ ariaLabel="Toggle status cards experimental setting"
+ />
+
+
+ toggleMutation.mutate(
+ checked || !enableStatusCards
+ ? { enableSummaries: checked }
+ : { enableSummaries: false, enableStatusCards: false },
+ )
+ }
+ disabled={toggleMutation.isPending || summariesRequiredByManagedStatusCards}
+ managed={managedKeys.enableSummaries}
+ ariaLabel="Toggle summaries experimental setting"
+ />
+
+ toggleMutation.mutate({ enableIssuePlanDecompositions: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableIssuePlanDecompositions}
+ ariaLabel="Toggle task plan decomposition panel experimental setting"
+ />
+
+ toggleMutation.mutate({ enableTaskWatchdogs: checked })}
+ disabled={toggleMutation.isPending}
+ managed={managedKeys.enableTaskWatchdogs}
+ ariaLabel="Toggle task watchdogs experimental setting"
+ />
+
{previewDialogOpen && !autoRecoveryManaged ? (