diff --git a/services/platform/app/features/chat/components/__tests__/model-selector.test.tsx b/services/platform/app/features/chat/components/__tests__/model-selector.test.tsx
index 040eea82a1..eb2dd23e5f 100644
--- a/services/platform/app/features/chat/components/__tests__/model-selector.test.tsx
+++ b/services/platform/app/features/chat/components/__tests__/model-selector.test.tsx
@@ -67,6 +67,10 @@ vi.mock('@/app/features/settings/providers/hooks/queries', () => ({
   }),
 }));
 
+vi.mock('../../hooks/use-default-model', () => ({
+  useDefaultModel: () => ({ data: null }),
+}));
+
 vi.mock('../model-tag-icons', () => ({
   ModelTagIcons: () => null,
 }));
diff --git a/services/platform/app/features/chat/components/chat-interface.tsx b/services/platform/app/features/chat/components/chat-interface.tsx
index 1efcd9a3f2..ef9d74876a 100644
--- a/services/platform/app/features/chat/components/chat-interface.tsx
+++ b/services/platform/app/features/chat/components/chat-interface.tsx
@@ -35,6 +35,7 @@ import {
 } from '../hooks/queries';
 import { useChatLoadingState } from '../hooks/use-chat-loading-state';
 import { useConvexFileUpload } from '../hooks/use-convex-file-upload';
+import { useDefaultModel } from '../hooks/use-default-model';
 import { useEffectiveAgent } from '../hooks/use-effective-agent';
 import { useFileIndexingStatus } from '../hooks/use-file-indexing-status';
 import { useMergedChatItems } from '../hooks/use-merged-chat-items';
@@ -126,6 +127,7 @@ export function ChatInterface({
 
   const { agent: effectiveAgent, isLoading: isAgentLoading } =
     useEffectiveAgent(organizationId);
+  const { data: governanceDefault } = useDefaultModel(organizationId);
 
   const [inputValue, setInputValue, clearInputValue] = usePersistedState(
     chatDraftKey(user?.userId, organizationId, threadId),
@@ -422,7 +424,8 @@ export function ChatInterface({
     },
     selectedAgent: effectiveAgent,
     modelId: effectiveAgent?.name
-      ? selectedModelOverrides[effectiveAgent.name]
+      ? (selectedModelOverrides[effectiveAgent.name] ??
+        governanceDefault?.modelId)
       : undefined,
     userContext,
     arena: arenaContext ?? undefined,
@@ -473,7 +476,8 @@ export function ChatInterface({
     async (newContent: string) => {
       if (!editingMessage || !dataThreadId || !effectiveAgent) return;
       const modelId = effectiveAgent.name
-        ? selectedModelOverrides[effectiveAgent.name]
+        ? (selectedModelOverrides[effectiveAgent.name] ??
+          governanceDefault?.modelId)
         : undefined;
 
       // Optimistic: show edited content immediately, truncate messages after it.
@@ -510,6 +514,7 @@ export function ChatInterface({
       rootThreadId,
       effectiveAgent,
       selectedModelOverrides,
+      governanceDefault,
       organizationId,
       userContext,
       editAndBranchAction,
diff --git a/services/platform/app/features/chat/components/model-selector.tsx b/services/platform/app/features/chat/components/model-selector.tsx
index 9f4ef80551..e2c5bfba6c 100644
--- a/services/platform/app/features/chat/components/model-selector.tsx
+++ b/services/platform/app/features/chat/components/model-selector.tsx
@@ -18,6 +18,7 @@ import { useT } from '@/lib/i18n/client';
 
 import { useChatLayout } from '../context/chat-layout-context';
 import { useChatAgents } from '../hooks/queries';
+import { useDefaultModel } from '../hooks/use-default-model';
 import { useEffectiveAgent } from '../hooks/use-effective-agent';
 import { ModelTagIcons } from './model-tag-icons';
 
@@ -36,6 +37,7 @@ export function ModelSelector({ organizationId }: ModelSelectorProps) {
   const { agents } = useChatAgents(organizationId);
   const { providers } = useListProviders('default');
   const { selectedModelOverrides, setSelectedModelOverride } = useChatLayout();
+  const { data: governanceDefault } = useDefaultModel(organizationId);
   const [open, setOpen] = useState(false);
 
   const supportedModels = useMemo(() => {
@@ -88,10 +90,26 @@ export function ModelSelector({ organizationId }: ModelSelectorProps) {
     [modelInfoMap],
   );
 
-  const currentModelId =
-    (effectiveAgent?.name && selectedModelOverrides[effectiveAgent.name]) ||
-    filteredModels[0] ||
-    null;
+  const currentModelId = useMemo(() => {
+    // 1. User's explicit override (localStorage) takes highest priority
+    if (effectiveAgent?.name && selectedModelOverrides[effectiveAgent.name]) {
+      return selectedModelOverrides[effectiveAgent.name];
+    }
+    // 2. Governance team/role default (if model is in agent's supported list)
+    if (
+      governanceDefault?.modelId &&
+      filteredModels.includes(governanceDefault.modelId)
+    ) {
+      return governanceDefault.modelId;
+    }
+    // 3. Agent's primary model
+    return filteredModels[0] ?? null;
+  }, [
+    effectiveAgent?.name,
+    selectedModelOverrides,
+    governanceDefault,
+    filteredModels,
+  ]);
 
   // Clear stale override when agent changes
   useEffect(() => {
@@ -110,13 +128,25 @@ export function ModelSelector({ organizationId }: ModelSelectorProps) {
   const handleSelect = useCallback(
     (modelId: string) => {
       if (!effectiveAgent?.name) return;
-      if (modelId === filteredModels[0]) {
+      // Only clear the override when the user picks the effective default
+      // (governance default if present, otherwise the agent's primary model).
+      const effectiveDefault =
+        governanceDefault?.modelId &&
+        filteredModels.includes(governanceDefault.modelId)
+          ? governanceDefault.modelId
+          : filteredModels[0];
+      if (modelId === effectiveDefault) {
         setSelectedModelOverride(effectiveAgent.name, null);
       } else {
         setSelectedModelOverride(effectiveAgent.name, modelId);
       }
     },
-    [effectiveAgent?.name, filteredModels, setSelectedModelOverride],
+    [
+      effectiveAgent?.name,
+      filteredModels,
+      governanceDefault,
+      setSelectedModelOverride,
+    ],
   );
 
   if (!currentModelId) return null;
diff --git a/services/platform/app/features/chat/hooks/use-default-model.ts b/services/platform/app/features/chat/hooks/use-default-model.ts
new file mode 100644
index 0000000000..ac7aade83c
--- /dev/null
+++ b/services/platform/app/features/chat/hooks/use-default-model.ts
@@ -0,0 +1,8 @@
+import { useConvexQuery } from '@/app/hooks/use-convex-query';
+import { api } from '@/convex/_generated/api';
+
+export function useDefaultModel(organizationId: string) {
+  return useConvexQuery(api.governance.default_model_query.getMyDefaultModel, {
+    organizationId,
+  });
+}
diff --git a/services/platform/app/features/settings/governance/components/default-model-editor.test.tsx b/services/platform/app/features/settings/governance/components/default-model-editor.test.tsx
new file mode 100644
index 0000000000..7aa65c620f
--- /dev/null
+++ b/services/platform/app/features/settings/governance/components/default-model-editor.test.tsx
@@ -0,0 +1,69 @@
+import { describe, it, vi } from 'vitest';
+
+import { checkAccessibility } from '@/test/utils/a11y';
+import { render } from '@/test/utils/render';
+
+import { DefaultModelEditor } from './default-model-editor';
+
+vi.mock('@/app/hooks/use-toast', () => ({
+  useToast: () => ({ toast: vi.fn() }),
+}));
+
+vi.mock('../hooks/mutations', () => ({
+  useUpsertGovernancePolicy: () => ({ mutateAsync: vi.fn(), isPending: false }),
+}));
+
+vi.mock('../hooks/queries', () => ({
+  useGovernancePolicy: () => ({
+    data: null,
+    isLoading: false,
+  }),
+}));
+
+vi.mock('@/app/features/settings/teams/hooks/queries', () => ({
+  useOrgTeams: () => ({
+    teams: [{ id: 'team-1', name: 'Engineering' }],
+    isLoading: false,
+  }),
+}));
+
+vi.mock('@/app/features/settings/providers/hooks/queries', () => ({
+  useListProviders: () => ({
+    providers: [
+      {
+        name: 'openai',
+        displayName: 'OpenAI',
+        models: [
+          {
+            id: 'openai/gpt-4o',
+            displayName: 'GPT-4o',
+            tags: ['chat'],
+          },
+        ],
+      },
+    ],
+    isLoading: false,
+  }),
+}));
+
+vi.mock('@/app/hooks/use-ability', () => ({
+  useAbility: () => ({
+    can: () => true,
+    cannot: () => false,
+  }),
+}));
+
+vi.mock('@/app/hooks/use-organization-id', () => ({
+  useOrganizationId: () => 'org-1',
+}));
+
+describe('DefaultModelEditor', () => {
+  describe('accessibility', () => {
+    it('passes axe audit', async () => {
+      const { container } = render(
+        <DefaultModelEditor organizationId="org-1" />,
+      );
+      await checkAccessibility(container);
+    });
+  });
+});
diff --git a/services/platform/app/features/settings/governance/components/default-model-editor.tsx b/services/platform/app/features/settings/governance/components/default-model-editor.tsx
new file mode 100644
index 0000000000..be275c476e
--- /dev/null
+++ b/services/platform/app/features/settings/governance/components/default-model-editor.tsx
@@ -0,0 +1,601 @@
+'use client';
+
+import { Pencil, Plus, Trash2 } from 'lucide-react';
+import { useCallback, useEffect, useMemo, useState } from 'react';
+
+import { FormDialog } from '@/app/components/ui/dialog/form-dialog';
+import { SearchableSelect } from '@/app/components/ui/forms/searchable-select';
+import { Select } from '@/app/components/ui/forms/select';
+import { Switch } from '@/app/components/ui/forms/switch';
+import { HStack, Stack } from '@/app/components/ui/layout/layout';
+import { PageSection } from '@/app/components/ui/layout/page-section';
+import { Button } from '@/app/components/ui/primitives/button';
+import { Text } from '@/app/components/ui/typography/text';
+import { useListProviders } from '@/app/features/settings/providers/hooks/queries';
+import { useOrgTeams } from '@/app/features/settings/teams/hooks/queries';
+import { useAbility } from '@/app/hooks/use-ability';
+import { useToast } from '@/app/hooks/use-toast';
+import { useT } from '@/lib/i18n/client';
+import {
+  defaultModelsConfigSchema,
+  type DefaultModelsConfig,
+  type DefaultModelRule,
+} from '@/lib/shared/schemas/governance';
+import { isRecord } from '@/lib/utils/type-guards';
+
+import { useUpsertGovernancePolicy } from '../hooks/mutations';
+import { useGovernancePolicy } from '../hooks/queries';
+
+interface DefaultModelEditorProps {
+  organizationId: string;
+}
+
+const SCOPE_OPTIONS = [
+  { value: 'default', label: 'Default' },
+  { value: 'team', label: 'Team' },
+  { value: 'role', label: 'Role' },
+];
+
+function isScopeValue(v: string): v is DefaultModelRule['scope'] {
+  return SCOPE_OPTIONS.some((o) => o.value === v);
+}
+
+const ROLE_OPTIONS = [
+  { value: 'admin', label: 'Admin' },
+  { value: 'developer', label: 'Developer' },
+  { value: 'editor', label: 'Editor' },
+  { value: 'member', label: 'Member' },
+];
+
+function emptyRule(): DefaultModelRule {
+  return {
+    scope: 'default',
+    providerName: '',
+    modelId: '',
+  };
+}
+
+function parseDefaultModelsConfig(policy: unknown): DefaultModelsConfig {
+  const config = isRecord(policy) ? policy : {};
+  const result = defaultModelsConfigSchema.safeParse(config);
+  if (result.success) {
+    return result.data;
+  }
+  return { enabled: false, rules: [] };
+}
+
+interface ProviderModel {
+  id: string;
+  displayName: string;
+  tags: string[];
+}
+
+interface ProviderInfo {
+  name: string;
+  displayName: string;
+  models: ProviderModel[];
+}
+
+interface RuleDialogProps {
+  open: boolean;
+  onOpenChange: (open: boolean) => void;
+  rule: DefaultModelRule;
+  onSave: (rule: DefaultModelRule) => void;
+  title: string;
+  cannotManage: boolean;
+  teamOptions: { value: string; label: string }[];
+  providerList: ProviderInfo[];
+}
+
+function RuleDialog({
+  open,
+  onOpenChange,
+  rule: initialRule,
+  onSave,
+  title,
+  cannotManage,
+  teamOptions,
+  providerList,
+}: RuleDialogProps) {
+  const { t } = useT('governance');
+  const [draft, setDraft] = useState(initialRule);
+
+  useEffect(() => {
+    if (open) {
+      setDraft(initialRule);
+    }
+  }, [open, initialRule]);
+
+  const updateDraft = useCallback((patch: Partial<DefaultModelRule>) => {
+    setDraft((prev) => {
+      const updated = { ...prev, ...patch };
+      if (patch.scope !== undefined) {
+        if (patch.scope === 'default') {
+          delete updated.scopeId;
+        } else {
+          updated.scopeId = '';
+        }
+      }
+      if (patch.providerName && patch.providerName !== prev.providerName) {
+        updated.modelId = '';
+      }
+      return updated;
+    });
+  }, []);
+
+  const handleSubmit = useCallback(
+    (e: React.FormEvent) => {
+      e.preventDefault();
+      if (!draft.providerName || !draft.modelId) return;
+      if (draft.scope !== 'default' && !draft.scopeId) return;
+      onSave(draft);
+      onOpenChange(false);
+    },
+    [draft, onSave, onOpenChange],
+  );
+
+  const providerOptions = useMemo(
+    () =>
+      providerList.map((p) => ({
+        value: p.name,
+        label: p.displayName || p.name,
+      })),
+    [providerList],
+  );
+
+  const modelOptions = useMemo(() => {
+    const provider = providerList.find((p) => p.name === draft.providerName);
+    if (!provider) return [];
+    return provider.models
+      .filter((m) => m.tags.includes('chat'))
+      .map((m) => ({
+        value: m.id,
+        label: m.displayName || m.id,
+      }));
+  }, [providerList, draft.providerName]);
+
+  return (
+    <FormDialog
+      open={open}
+      onOpenChange={onOpenChange}
+      title={title}
+      onSubmit={handleSubmit}
+      submitText={t('defaultModels.confirm')}
+    >
+      <Stack gap={4}>
+        <HStack gap={3} wrap>
+          <div className="w-40">
+            <Select
+              label={t('defaultModels.scope')}
+              options={SCOPE_OPTIONS}
+              value={draft.scope}
+              onValueChange={(value: string) => {
+                if (isScopeValue(value)) {
+                  updateDraft({ scope: value });
+                }
+              }}
+              disabled={cannotManage}
+              size="sm"
+            />
+          </div>
+
+          {draft.scope === 'role' && (
+            <div className="w-40">
+              <Select
+                label={t('defaultModels.role')}
+                options={ROLE_OPTIONS}
+                value={draft.scopeId ?? ''}
+                onValueChange={(value) => updateDraft({ scopeId: value })}
+                disabled={cannotManage}
+                size="sm"
+              />
+            </div>
+          )}
+
+          {draft.scope === 'team' && (
+            <div className="w-56">
+              <Text className="mb-1 text-xs font-medium">
+                {t('defaultModels.target')}
+              </Text>
+              <SearchableSelect
+                value={draft.scopeId ?? null}
+                onValueChange={(value) => updateDraft({ scopeId: value })}
+                options={teamOptions}
+                searchPlaceholder={t('defaultModels.searchTeams')}
+                emptyText={t('defaultModels.noTeamsFound')}
+                aria-label={t('defaultModels.target')}
+                trigger={
+                  <button
+                    type="button"
+                    disabled={cannotManage}
+                    className="border-input ring-offset-background flex h-8 w-full items-center justify-between rounded-md border bg-transparent px-3 text-sm disabled:cursor-not-allowed disabled:opacity-50"
+                  >
+                    <span
+                      className={draft.scopeId ? '' : 'text-muted-foreground'}
+                    >
+                      {draft.scopeId
+                        ? (teamOptions.find((o) => o.value === draft.scopeId)
+                            ?.label ?? draft.scopeId)
+                        : t('defaultModels.selectTeam')}
+                    </span>
+                  </button>
+                }
+              />
+            </div>
+          )}
+        </HStack>
+
+        <HStack gap={3} wrap>
+          <div className="w-56">
+            <Text className="mb-1 text-xs font-medium">
+              {t('defaultModels.provider')}
+            </Text>
+            <SearchableSelect
+              value={draft.providerName || null}
+              onValueChange={(value) => updateDraft({ providerName: value })}
+              options={providerOptions}
+              searchPlaceholder={t('defaultModels.searchProviders')}
+              emptyText={t('defaultModels.noProvidersFound')}
+              aria-label={t('defaultModels.provider')}
+              trigger={
+                <button
+                  type="button"
+                  disabled={cannotManage}
+                  className="border-input ring-offset-background flex h-8 w-full items-center justify-between rounded-md border bg-transparent px-3 text-sm disabled:cursor-not-allowed disabled:opacity-50"
+                >
+                  <span
+                    className={
+                      draft.providerName ? '' : 'text-muted-foreground'
+                    }
+                  >
+                    {draft.providerName
+                      ? (providerOptions.find(
+                          (o) => o.value === draft.providerName,
+                        )?.label ?? draft.providerName)
+                      : t('defaultModels.selectProvider')}
+                  </span>
+                </button>
+              }
+            />
+          </div>
+
+          <div className="w-56">
+            <Text className="mb-1 text-xs font-medium">
+              {t('defaultModels.model')}
+            </Text>
+            <SearchableSelect
+              value={draft.modelId || null}
+              onValueChange={(value) => updateDraft({ modelId: value })}
+              options={modelOptions}
+              searchPlaceholder={t('defaultModels.searchModels')}
+              emptyText={t('defaultModels.noModelsFound')}
+              aria-label={t('defaultModels.model')}
+              trigger={
+                <button
+                  type="button"
+                  disabled={cannotManage || !draft.providerName}
+                  className="border-input ring-offset-background flex h-8 w-full items-center justify-between rounded-md border bg-transparent px-3 text-sm disabled:cursor-not-allowed disabled:opacity-50"
+                >
+                  <span
+                    className={draft.modelId ? '' : 'text-muted-foreground'}
+                  >
+                    {draft.modelId
+                      ? (modelOptions.find((o) => o.value === draft.modelId)
+                          ?.label ?? draft.modelId)
+                      : t('defaultModels.selectModel')}
+                  </span>
+                </button>
+              }
+            />
+          </div>
+        </HStack>
+      </Stack>
+    </FormDialog>
+  );
+}
+
+export function DefaultModelEditor({
+  organizationId,
+}: DefaultModelEditorProps) {
+  const { t } = useT('governance');
+  const { toast } = useToast();
+  const ability = useAbility();
+
+  const { data: policy, isLoading } = useGovernancePolicy(
+    organizationId,
+    'default_models',
+  );
+  const upsertMutation = useUpsertGovernancePolicy();
+  const { teams } = useOrgTeams();
+  const { providers } = useListProviders('default');
+
+  const teamOptions = useMemo(
+    () =>
+      (teams ?? []).map((team) => ({
+        value: team.id,
+        label: team.name || team.id,
+      })),
+    [teams],
+  );
+
+  const providerList = useMemo<ProviderInfo[]>(() => {
+    const list: ProviderInfo[] = [];
+    for (const provider of providers) {
+      if (
+        !provider ||
+        !('models' in provider) ||
+        !Array.isArray(provider.models)
+      )
+        continue;
+      list.push({
+        name: provider.name,
+        displayName: provider.displayName ?? provider.name,
+        models: provider.models.map(
+          (m: { id: string; displayName: string; tags?: string[] }) => ({
+            id: m.id,
+            displayName: m.displayName,
+            tags: m.tags ?? [],
+          }),
+        ),
+      });
+    }
+    return list;
+  }, [providers]);
+
+  const savedConfig = useMemo(
+    () => parseDefaultModelsConfig(policy?.config),
+    [policy],
+  );
+
+  const [enabled, setEnabled] = useState(false);
+  const [rules, setRules] = useState<DefaultModelRule[]>([]);
+
+  const [dialogOpen, setDialogOpen] = useState(false);
+  const [editingIndex, setEditingIndex] = useState<number | null>(null);
+  const [dialogRule, setDialogRule] = useState(emptyRule());
+
+  useEffect(() => {
+    setEnabled(savedConfig.enabled);
+    setRules(savedConfig.rules);
+  }, [savedConfig]);
+
+  const cannotManage = ability.cannot('write', 'orgSettings');
+
+  const saveConfig = useCallback(
+    async (configToSave: { enabled: boolean; rules: DefaultModelRule[] }) => {
+      try {
+        await upsertMutation.mutateAsync({
+          organizationId,
+          policyType: 'default_models',
+          config: configToSave,
+        });
+        toast({ title: t('defaultModels.saved'), variant: 'success' });
+      } catch (error: unknown) {
+        const message =
+          error instanceof Error ? error.message : 'Failed to save';
+        toast({ title: message, variant: 'destructive' });
+      }
+    },
+    [organizationId, upsertMutation, toast, t],
+  );
+
+  const handleToggleEnabled = useCallback(
+    (checked: boolean) => {
+      setEnabled(checked);
+      void saveConfig({ enabled: checked, rules });
+    },
+    [saveConfig, rules],
+  );
+
+  const removeRule = useCallback(
+    (index: number) => {
+      const newRules = rules.filter((_, i) => i !== index);
+      setRules(newRules);
+      void saveConfig({ enabled, rules: newRules });
+    },
+    [rules, enabled, saveConfig],
+  );
+
+  const openAddDialog = useCallback(() => {
+    setEditingIndex(null);
+    setDialogRule(emptyRule());
+    setDialogOpen(true);
+  }, []);
+
+  const openEditDialog = useCallback(
+    (index: number) => {
+      setEditingIndex(index);
+      setDialogRule(rules[index]);
+      setDialogOpen(true);
+    },
+    [rules],
+  );
+
+  const handleDialogSave = useCallback(
+    (rule: DefaultModelRule) => {
+      let newRules: DefaultModelRule[];
+      if (editingIndex === null) {
+        newRules = [...rules, rule];
+      } else {
+        newRules = rules.map((r, i) => (i === editingIndex ? rule : r));
+      }
+      setRules(newRules);
+      void saveConfig({ enabled, rules: newRules });
+    },
+    [editingIndex, rules, enabled, saveConfig],
+  );
+
+  const resolveTarget = useCallback(
+    (rule: DefaultModelRule): string => {
+      switch (rule.scope) {
+        case 'team': {
+          if (!rule.scopeId) return '\u2014';
+          return (
+            teamOptions.find((o) => o.value === rule.scopeId)?.label ??
+            rule.scopeId
+          );
+        }
+        case 'role':
+          return rule.scopeId ?? '\u2014';
+        case 'default':
+          return t('defaultModels.allUsers');
+        default:
+          return '\u2014';
+      }
+    },
+    [teamOptions, t],
+  );
+
+  const resolveModelName = useCallback(
+    (rule: DefaultModelRule): string => {
+      for (const provider of providerList) {
+        if (provider.name !== rule.providerName) continue;
+        const model = provider.models.find((m) => m.id === rule.modelId);
+        if (model) return model.displayName;
+      }
+      return rule.modelId;
+    },
+    [providerList],
+  );
+
+  const resolveProviderName = useCallback(
+    (rule: DefaultModelRule): string => {
+      const provider = providerList.find((p) => p.name === rule.providerName);
+      return provider?.displayName ?? rule.providerName;
+    },
+    [providerList],
+  );
+
+  if (isLoading) {
+    return null;
+  }
+
+  return (
+    <PageSection
+      title={t('defaultModels.title')}
+      description={t('defaultModels.description')}
+      action={
+        <Switch
+          label={t('defaultModels.enabled')}
+          checked={enabled}
+          onCheckedChange={handleToggleEnabled}
+          disabled={cannotManage || upsertMutation.isPending}
+        />
+      }
+    >
+      <Stack gap={6}>
+        <Stack gap={3}>
+          {rules.length > 0 ? (
+            <div className="overflow-x-auto">
+              <table className="w-full text-sm">
+                <caption className="sr-only">
+                  {t('defaultModels.title')}
+                </caption>
+                <thead>
+                  <tr className="border-border border-b">
+                    <th
+                      scope="col"
+                      className="text-muted-foreground px-3 py-2 text-left font-medium"
+                    >
+                      {t('defaultModels.scope')}
+                    </th>
+                    <th
+                      scope="col"
+                      className="text-muted-foreground px-3 py-2 text-left font-medium"
+                    >
+                      {t('defaultModels.target')}
+                    </th>
+                    <th
+                      scope="col"
+                      className="text-muted-foreground px-3 py-2 text-left font-medium"
+                    >
+                      {t('defaultModels.provider')}
+                    </th>
+                    <th
+                      scope="col"
+                      className="text-muted-foreground px-3 py-2 text-left font-medium"
+                    >
+                      {t('defaultModels.model')}
+                    </th>
+                    <th
+                      scope="col"
+                      className="text-muted-foreground px-3 py-2 text-right font-medium"
+                    >
+                      {t('defaultModels.actions')}
+                    </th>
+                  </tr>
+                </thead>
+                <tbody>
+                  {rules.map((rule, index) => (
+                    <tr key={index} className="border-border border-b">
+                      <td className="px-3 py-2 capitalize">{rule.scope}</td>
+                      <td className="px-3 py-2">{resolveTarget(rule)}</td>
+                      <td className="px-3 py-2">{resolveProviderName(rule)}</td>
+                      <td className="px-3 py-2">{resolveModelName(rule)}</td>
+                      <td className="px-3 py-2 text-right">
+                        <HStack gap={1} justify="end">
+                          <Button
+                            variant="ghost"
+                            size="icon"
+                            onClick={() => openEditDialog(index)}
+                            disabled={cannotManage}
+                            aria-label={t('defaultModels.editRule', {
+                              index: index + 1,
+                            })}
+                          >
+                            <Pencil className="size-4" />
+                          </Button>
+                          <Button
+                            variant="ghost"
+                            size="icon"
+                            onClick={() => removeRule(index)}
+                            disabled={cannotManage}
+                            aria-label={t('defaultModels.removeRule', {
+                              index: index + 1,
+                            })}
+                          >
+                            <Trash2 className="size-4" />
+                          </Button>
+                        </HStack>
+                      </td>
+                    </tr>
+                  ))}
+                </tbody>
+              </table>
+            </div>
+          ) : (
+            <Text variant="muted" className="text-sm">
+              {t('defaultModels.noRules')}
+            </Text>
+          )}
+
+          <Button
+            variant="secondary"
+            size="sm"
+            onClick={openAddDialog}
+            disabled={cannotManage}
+            className="self-start"
+          >
+            <Plus className="mr-1.5 size-4" />
+            {t('defaultModels.addRule')}
+          </Button>
+        </Stack>
+      </Stack>
+
+      <RuleDialog
+        open={dialogOpen}
+        onOpenChange={setDialogOpen}
+        rule={dialogRule}
+        onSave={handleDialogSave}
+        title={
+          editingIndex === null
+            ? t('defaultModels.addRuleTitle')
+            : t('defaultModels.editRuleTitle')
+        }
+        cannotManage={cannotManage}
+        teamOptions={teamOptions}
+        providerList={providerList}
+      />
+    </PageSection>
+  );
+}
diff --git a/services/platform/app/routes/dashboard/$id/settings/governance.tsx b/services/platform/app/routes/dashboard/$id/settings/governance.tsx
index 7cb91859d4..e74ce30a62 100644
--- a/services/platform/app/routes/dashboard/$id/settings/governance.tsx
+++ b/services/platform/app/routes/dashboard/$id/settings/governance.tsx
@@ -12,8 +12,15 @@ import { SystemPromptEditor } from '@/app/features/settings/governance/component
 import { UsageDashboard } from '@/app/features/settings/governance/components/usage-dashboard';
 import { useAbility, useAbilityLoading } from '@/app/hooks/use-ability';
 import { useT } from '@/lib/i18n/client';
+import { lazyComponent } from '@/lib/utils/lazy-component';
 import { seo } from '@/lib/utils/seo';
 
+const DefaultModelEditor = lazyComponent<{ organizationId: string }>(() =>
+  import('@/app/features/settings/governance/components/default-model-editor').then(
+    (m) => ({ default: m.DefaultModelEditor }),
+  ),
+);
+
 const searchSchema = z.object({
   tab: z.string().optional(),
 });
@@ -58,6 +65,11 @@ function GovernanceSettingsPage() {
         label: t('tabs.budgets'),
         content: <BudgetEditor organizationId={organizationId} />,
       },
+      {
+        value: 'default-models',
+        label: t('defaultModels.title'),
+        content: <DefaultModelEditor organizationId={organizationId} />,
+      },
       {
         value: 'retention',
         label: 'Retention',
diff --git a/services/platform/convex/_generated/api.d.ts b/services/platform/convex/_generated/api.d.ts
index f241ec6b2f..2b4a7b6a89 100644
--- a/services/platform/convex/_generated/api.d.ts
+++ b/services/platform/convex/_generated/api.d.ts
@@ -286,6 +286,7 @@ import type * as folders_mutations from "../folders/mutations.js";
 import type * as folders_queries from "../folders/queries.js";
 import type * as governance_budget_enforcement from "../governance/budget_enforcement.js";
 import type * as governance_cost_estimation from "../governance/cost_estimation.js";
+import type * as governance_default_model_query from "../governance/default_model_query.js";
 import type * as governance_entra_attribute_matcher from "../governance/entra_attribute_matcher.js";
 import type * as governance_feature_enforcement from "../governance/feature_enforcement.js";
 import type * as governance_helpers from "../governance/helpers.js";
@@ -1209,6 +1210,7 @@ declare const fullApi: ApiFromModules<{
   "folders/queries": typeof folders_queries;
   "governance/budget_enforcement": typeof governance_budget_enforcement;
   "governance/cost_estimation": typeof governance_cost_estimation;
+  "governance/default_model_query": typeof governance_default_model_query;
   "governance/entra_attribute_matcher": typeof governance_entra_attribute_matcher;
   "governance/feature_enforcement": typeof governance_feature_enforcement;
   "governance/helpers": typeof governance_helpers;
diff --git a/services/platform/convex/agents/unified_chat.ts b/services/platform/convex/agents/unified_chat.ts
index ced431c8ee..c244be7060 100644
--- a/services/platform/convex/agents/unified_chat.ts
+++ b/services/platform/convex/agents/unified_chat.ts
@@ -93,13 +93,30 @@ export const chatWithAgent = action({
       }
     }
 
+    // Resolve governance default model when no explicit model is provided
+    let effectiveModelId = args.modelId;
+    if (!effectiveModelId) {
+      const governanceDefault = await ctx.runQuery(
+        internal.governance.internal_queries.resolveDefaultModelInternal,
+        {
+          organizationId: args.organizationId,
+          userId: String(authUser._id),
+          userEmail: authUser.email,
+          userName: authUser.name,
+        },
+      );
+      if (governanceDefault) {
+        effectiveModelId = governanceDefault.modelId;
+      }
+    }
+
     const agentConfig = await ctx.runAction(
       internal.agents.file_actions.resolveAgentConfig,
       {
         orgSlug: args.orgSlug,
         agentSlug: args.agentSlug,
         organizationId: args.organizationId,
-        modelId: args.modelId,
+        modelId: effectiveModelId,
       },
     );
 
diff --git a/services/platform/convex/governance/__tests__/resolve_default_model.test.ts b/services/platform/convex/governance/__tests__/resolve_default_model.test.ts
new file mode 100644
index 0000000000..05fc491f92
--- /dev/null
+++ b/services/platform/convex/governance/__tests__/resolve_default_model.test.ts
@@ -0,0 +1,255 @@
+import { describe, it, expect, vi, beforeEach } from 'vitest';
+
+// ---------------------------------------------------------------------------
+// Mocks
+// ---------------------------------------------------------------------------
+
+const mockReadPolicyConfig = vi.fn();
+
+vi.mock('../helpers', () => ({
+  readPolicyConfig: (...args: unknown[]) => mockReadPolicyConfig(...args),
+}));
+
+// Import after mocks
+const { resolveDefaultModel } = await import('../resolve_default_model');
+
+// Minimal ctx stub (only used to pass through to readPolicyConfig)
+const ctx = {} as Parameters<typeof resolveDefaultModel>[0];
+
+// ---------------------------------------------------------------------------
+// Tests
+// ---------------------------------------------------------------------------
+
+describe('resolveDefaultModel', () => {
+  beforeEach(() => {
+    vi.clearAllMocks();
+  });
+
+  it('returns null when no default_models policy exists', async () => {
+    mockReadPolicyConfig.mockResolvedValue(null);
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-1'],
+      'member',
+    );
+
+    expect(result).toBeNull();
+    expect(mockReadPolicyConfig).toHaveBeenCalledWith(
+      ctx,
+      'org-1',
+      'default_models',
+    );
+  });
+
+  it('returns null when policy is disabled', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: false,
+      rules: [
+        {
+          scope: 'default',
+          providerName: 'openai',
+          modelId: 'gpt-4o',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-1'],
+      'member',
+    );
+
+    expect(result).toBeNull();
+  });
+
+  it('returns null when rules array is empty', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [],
+    });
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-1'],
+      'member',
+    );
+
+    expect(result).toBeNull();
+  });
+
+  it('returns team-scoped rule when user belongs to that team', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [
+        {
+          scope: 'team',
+          scopeId: 'team-engineering',
+          providerName: 'openai',
+          modelId: 'gpt-4o',
+        },
+        {
+          scope: 'default',
+          providerName: 'anthropic',
+          modelId: 'claude-sonnet',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-engineering'],
+      'member',
+    );
+
+    expect(result).toEqual({ providerName: 'openai', modelId: 'gpt-4o' });
+  });
+
+  it('team rule takes priority over role rule', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [
+        {
+          scope: 'role',
+          scopeId: 'admin',
+          providerName: 'anthropic',
+          modelId: 'claude-opus',
+        },
+        {
+          scope: 'team',
+          scopeId: 'team-1',
+          providerName: 'openai',
+          modelId: 'gpt-4o',
+        },
+        {
+          scope: 'default',
+          providerName: 'google',
+          modelId: 'gemini-pro',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(ctx, 'org-1', ['team-1'], 'admin');
+
+    expect(result).toEqual({ providerName: 'openai', modelId: 'gpt-4o' });
+  });
+
+  it('role rule takes priority over default rule', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [
+        {
+          scope: 'role',
+          scopeId: 'developer',
+          providerName: 'anthropic',
+          modelId: 'claude-sonnet',
+        },
+        {
+          scope: 'default',
+          providerName: 'openai',
+          modelId: 'gpt-4o-mini',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-unrelated'],
+      'developer',
+    );
+
+    expect(result).toEqual({
+      providerName: 'anthropic',
+      modelId: 'claude-sonnet',
+    });
+  });
+
+  it('returns default rule when no team or role matches', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [
+        {
+          scope: 'team',
+          scopeId: 'team-engineering',
+          providerName: 'openai',
+          modelId: 'gpt-4o',
+        },
+        {
+          scope: 'role',
+          scopeId: 'admin',
+          providerName: 'anthropic',
+          modelId: 'claude-opus',
+        },
+        {
+          scope: 'default',
+          providerName: 'google',
+          modelId: 'gemini-pro',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-marketing'],
+      'member',
+    );
+
+    expect(result).toEqual({ providerName: 'google', modelId: 'gemini-pro' });
+  });
+
+  it('multi-team membership: first matching rule wins by rules array order', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [
+        {
+          scope: 'team',
+          scopeId: 'team-b',
+          providerName: 'anthropic',
+          modelId: 'claude-sonnet',
+        },
+        {
+          scope: 'team',
+          scopeId: 'team-a',
+          providerName: 'openai',
+          modelId: 'gpt-4o',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(
+      ctx,
+      'org-1',
+      ['team-a', 'team-b'],
+      'member',
+    );
+
+    expect(result).toEqual({
+      providerName: 'anthropic',
+      modelId: 'claude-sonnet',
+    });
+  });
+
+  it('returns null when no userRole is provided and only role rules exist', async () => {
+    mockReadPolicyConfig.mockResolvedValue({
+      enabled: true,
+      rules: [
+        {
+          scope: 'role',
+          scopeId: 'admin',
+          providerName: 'openai',
+          modelId: 'gpt-4o',
+        },
+      ],
+    });
+
+    const result = await resolveDefaultModel(ctx, 'org-1', [], undefined);
+
+    expect(result).toBeNull();
+  });
+});
diff --git a/services/platform/convex/governance/default_model_query.ts b/services/platform/convex/governance/default_model_query.ts
new file mode 100644
index 0000000000..d2d41cfeed
--- /dev/null
+++ b/services/platform/convex/governance/default_model_query.ts
@@ -0,0 +1,56 @@
+import { v } from 'convex/values';
+
+import { components } from '../_generated/api';
+import { query } from '../_generated/server';
+import { authComponent } from '../auth';
+import { getOrganizationMember } from '../lib/rls';
+import { resolveDefaultModel } from './resolve_default_model';
+
+interface BetterAuthTeamMember {
+  teamId: string;
+}
+
+interface BetterAuthFindManyResult<T> {
+  page: T[];
+  continueCursor: string;
+  isDone: boolean;
+}
+
+export const getMyDefaultModel = query({
+  args: {
+    organizationId: v.string(),
+  },
+  returns: v.union(
+    v.object({
+      providerName: v.string(),
+      modelId: v.string(),
+    }),
+    v.null(),
+  ),
+  handler: async (ctx, args) => {
+    let authUser = null;
+    try {
+      authUser = await authComponent.getAuthUser(ctx);
+    } catch {}
+    if (!authUser) return null;
+
+    const member = await getOrganizationMember(ctx, args.organizationId, {
+      userId: String(authUser._id),
+      email: authUser.email,
+      name: authUser.name,
+    });
+
+    const membershipsResult: BetterAuthFindManyResult<BetterAuthTeamMember> =
+      await ctx.runQuery(components.betterAuth.adapter.findMany, {
+        model: 'teamMember',
+        paginationOpts: { cursor: null, numItems: 100 },
+        where: [
+          { field: 'userId', operator: 'eq', value: String(authUser._id) },
+        ],
+      });
+
+    const teamIds = membershipsResult?.page.map((m) => m.teamId) ?? [];
+
+    return resolveDefaultModel(ctx, args.organizationId, teamIds, member.role);
+  },
+});
diff --git a/services/platform/convex/governance/internal_queries.ts b/services/platform/convex/governance/internal_queries.ts
index 4e8f08424e..126b608b0d 100644
--- a/services/platform/convex/governance/internal_queries.ts
+++ b/services/platform/convex/governance/internal_queries.ts
@@ -1,6 +1,9 @@
 import { v } from 'convex/values';
 
+import { components } from '../_generated/api';
 import { internalQuery } from '../_generated/server';
+import { getOrganizationMember } from '../lib/rls';
+import { resolveDefaultModel } from './resolve_default_model';
 
 export const getPiiConfigInternal = internalQuery({
   args: {
@@ -103,3 +106,47 @@ export const listExpiredDocuments = internalQuery({
     return docs;
   },
 });
+
+interface BetterAuthTeamMember {
+  teamId: string;
+}
+
+interface BetterAuthFindManyResult<T> {
+  page: T[];
+  continueCursor: string;
+  isDone: boolean;
+}
+
+export const resolveDefaultModelInternal = internalQuery({
+  args: {
+    organizationId: v.string(),
+    userId: v.string(),
+    userEmail: v.string(),
+    userName: v.optional(v.string()),
+  },
+  returns: v.union(
+    v.object({
+      providerName: v.string(),
+      modelId: v.string(),
+    }),
+    v.null(),
+  ),
+  handler: async (ctx, args) => {
+    const member = await getOrganizationMember(ctx, args.organizationId, {
+      userId: args.userId,
+      email: args.userEmail,
+      name: args.userName,
+    });
+
+    const membershipsResult: BetterAuthFindManyResult<BetterAuthTeamMember> =
+      await ctx.runQuery(components.betterAuth.adapter.findMany, {
+        model: 'teamMember',
+        paginationOpts: { cursor: null, numItems: 1000 },
+        where: [{ field: 'userId', operator: 'eq', value: member.userId }],
+      });
+
+    const teamIds = membershipsResult?.page.map((m) => m.teamId) ?? [];
+
+    return resolveDefaultModel(ctx, args.organizationId, teamIds, member.role);
+  },
+});
diff --git a/services/platform/convex/governance/mutations.ts b/services/platform/convex/governance/mutations.ts
index 4b23577eba..d56e221915 100644
--- a/services/platform/convex/governance/mutations.ts
+++ b/services/platform/convex/governance/mutations.ts
@@ -2,6 +2,7 @@ import { v } from 'convex/values';
 
 import {
   budgetConfigSchema,
+  defaultModelsConfigSchema,
   featureFlagsConfigSchema,
   piiConfigSchema,
 } from '../../lib/shared/schemas/governance';
@@ -45,6 +46,15 @@ export const upsertPolicy = mutation({
       }
     }
 
+    if (args.policyType === 'default_models') {
+      const parsed = defaultModelsConfigSchema.safeParse(args.config);
+      if (!parsed.success) {
+        throw new Error(
+          `Invalid default models configuration: ${parsed.error.message}`,
+        );
+      }
+    }
+
     if (args.policyType === 'pii_config') {
       const parsed = piiConfigSchema.safeParse(args.config);
       if (!parsed.success) {
diff --git a/services/platform/messages/de-AT.json b/services/platform/messages/de-AT.json
index 92255a5fd4..57b03f9ee2 100644
--- a/services/platform/messages/de-AT.json
+++ b/services/platform/messages/de-AT.json
@@ -57,6 +57,38 @@
     },
     "usageCount": "{count, plural, one {# Verwendung} other {# Verwendungen}}"
   },
+  "governance": {
+    "defaultModels": {
+      "title": "Standardmodelle",
+      "description": "Standardmodelle für bestimmte Benutzergruppen oder Rollen festlegen.",
+      "addMapping": "Modellzuordnung hinzufügen",
+      "saved": "Standardmodell-Konfiguration gespeichert",
+      "addRule": "Regel hinzufügen",
+      "addRuleTitle": "Standardmodell-Regel hinzufügen",
+      "editRuleTitle": "Standardmodell-Regel bearbeiten",
+      "editRule": "Regel {index} bearbeiten",
+      "removeRule": "Regel {index} entfernen",
+      "scope": "Geltungsbereich",
+      "target": "Ziel",
+      "provider": "Anbieter",
+      "model": "Modell",
+      "role": "Rolle",
+      "actions": "Aktionen",
+      "noRules": "Keine Standardmodell-Regeln konfiguriert. Füge eine Regel hinzu, um Team- oder Rollen-Standards festzulegen.",
+      "allUsers": "Alle Benutzer",
+      "selectProvider": "Anbieter auswählen...",
+      "selectModel": "Modell auswählen...",
+      "selectTeam": "Team auswählen...",
+      "searchProviders": "Anbieter suchen...",
+      "searchModels": "Modelle suchen...",
+      "searchTeams": "Teams suchen...",
+      "noProvidersFound": "Keine Anbieter gefunden",
+      "noModelsFound": "Keine Modelle gefunden",
+      "noTeamsFound": "Keine Teams gefunden",
+      "enabled": "Aktiviert",
+      "confirm": "Bestätigen"
+    }
+  },
   "settings": {
     "agents": {
       "form": {
diff --git a/services/platform/messages/de-CH.json b/services/platform/messages/de-CH.json
index a7bd686c58..2d78257a96 100644
--- a/services/platform/messages/de-CH.json
+++ b/services/platform/messages/de-CH.json
@@ -108,6 +108,36 @@
     "uploadPolicy": {
       "description": "Erlaubte Dateitypen, maximale Dateigrösse und Volumenlimits konfigurieren.",
       "maxFileSize": "Maximale Dateigrösse"
+    },
+    "defaultModels": {
+      "title": "Standardmodelle",
+      "description": "Standardmodelle für bestimmte Benutzergruppen oder Rollen festlegen.",
+      "addMapping": "Modellzuordnung hinzufügen",
+      "saved": "Standardmodell-Konfiguration gespeichert",
+      "addRule": "Regel hinzufügen",
+      "addRuleTitle": "Standardmodell-Regel hinzufügen",
+      "editRuleTitle": "Standardmodell-Regel bearbeiten",
+      "editRule": "Regel {index} bearbeiten",
+      "removeRule": "Regel {index} entfernen",
+      "scope": "Geltungsbereich",
+      "target": "Ziel",
+      "provider": "Anbieter",
+      "model": "Modell",
+      "role": "Rolle",
+      "actions": "Aktionen",
+      "noRules": "Keine Standardmodell-Regeln konfiguriert. Füge eine Regel hinzu, um Team- oder Rollen-Standards festzulegen.",
+      "allUsers": "Alle Benutzer",
+      "selectProvider": "Anbieter auswählen...",
+      "selectModel": "Modell auswählen...",
+      "selectTeam": "Team auswählen...",
+      "searchProviders": "Anbieter suchen...",
+      "searchModels": "Modelle suchen...",
+      "searchTeams": "Teams suchen...",
+      "noProvidersFound": "Keine Anbieter gefunden",
+      "noModelsFound": "Keine Modelle gefunden",
+      "noTeamsFound": "Keine Teams gefunden",
+      "enabled": "Aktiviert",
+      "confirm": "Bestätigen"
     }
   },
   "prompts": {
diff --git a/services/platform/messages/de.json b/services/platform/messages/de.json
index a303f84308..a24af96dda 100644
--- a/services/platform/messages/de.json
+++ b/services/platform/messages/de.json
@@ -3696,7 +3696,31 @@
       "title": "Standardmodelle",
       "description": "Standardmodelle für bestimmte Benutzergruppen oder Rollen festlegen.",
       "addMapping": "Modellzuordnung hinzufügen",
-      "saved": "Standardmodell-Konfiguration gespeichert"
+      "saved": "Standardmodell-Konfiguration gespeichert",
+      "addRule": "Regel hinzufügen",
+      "addRuleTitle": "Standardmodell-Regel hinzufügen",
+      "editRuleTitle": "Standardmodell-Regel bearbeiten",
+      "editRule": "Regel {index} bearbeiten",
+      "removeRule": "Regel {index} entfernen",
+      "scope": "Geltungsbereich",
+      "target": "Ziel",
+      "provider": "Anbieter",
+      "model": "Modell",
+      "role": "Rolle",
+      "actions": "Aktionen",
+      "noRules": "Keine Standardmodell-Regeln konfiguriert. Füge eine Regel hinzu, um Team- oder Rollen-Standards festzulegen.",
+      "allUsers": "Alle Benutzer",
+      "selectProvider": "Anbieter auswählen...",
+      "selectModel": "Modell auswählen...",
+      "selectTeam": "Team auswählen...",
+      "searchProviders": "Anbieter suchen...",
+      "searchModels": "Modelle suchen...",
+      "searchTeams": "Teams suchen...",
+      "noProvidersFound": "Keine Anbieter gefunden",
+      "noModelsFound": "Keine Modelle gefunden",
+      "noTeamsFound": "Keine Teams gefunden",
+      "enabled": "Aktiviert",
+      "confirm": "Bestätigen"
     },
     "uploadPolicy": {
       "title": "Upload-Richtlinie",
diff --git a/services/platform/messages/en.json b/services/platform/messages/en.json
index 5ef9169d09..c4ca4c28c8 100644
--- a/services/platform/messages/en.json
+++ b/services/platform/messages/en.json
@@ -1451,7 +1451,7 @@
     },
     "providers": {
       "title": "Providers",
-      "description": "Description",
+      "description": "Manage LLM providers and their models",
       "addProvider": "Add provider",
       "editProvider": "Edit provider",
       "deleteProvider": "Delete provider",
@@ -3686,7 +3686,31 @@
       "title": "Default Models",
       "description": "Set default models for specific user groups or roles.",
       "addMapping": "Add model mapping",
-      "saved": "Default model configuration saved"
+      "saved": "Default model configuration saved",
+      "addRule": "Add rule",
+      "addRuleTitle": "Add default model rule",
+      "editRuleTitle": "Edit default model rule",
+      "editRule": "Edit rule {index}",
+      "removeRule": "Remove rule {index}",
+      "scope": "Scope",
+      "target": "Target",
+      "provider": "Provider",
+      "model": "Model",
+      "role": "Role",
+      "actions": "Actions",
+      "noRules": "No default model rules configured. Add a rule to set team or role defaults.",
+      "allUsers": "All users",
+      "selectProvider": "Select provider...",
+      "selectModel": "Select model...",
+      "selectTeam": "Select team...",
+      "searchProviders": "Search providers...",
+      "searchModels": "Search models...",
+      "searchTeams": "Search teams...",
+      "noProvidersFound": "No providers found",
+      "noModelsFound": "No models found",
+      "noTeamsFound": "No teams found",
+      "enabled": "Enabled",
+      "confirm": "Confirm"
     },
     "uploadPolicy": {
       "title": "Upload Policy",
