Skip to content

feat(organizations): add gated organization mode defaults#3981

Open
pandemicsyn wants to merge 5 commits into
mainfrom
feat/organization-mode-default-models
Open

feat(organizations): add gated organization mode defaults#3981
pandemicsyn wants to merge 5 commits into
mainfrom
feat/organization-mode-default-models

Conversation

@pandemicsyn

@pandemicsyn pandemicsyn commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add optional defaultModel support to organization mode config so organizations can choose a model per mode before CLI and VSCode clients begin consuming that field.
  • This enables organizations to steer different workflows toward different models, such as using a stronger planning model for architect while keeping code on a faster coding model, without removing user-level model overrides.
  • The follow-up CLI and VSCode work will consume these mode defaults below user-driven selection, so cloud admins can establish sensible organizational defaults while users retain the ability to override them locally.
  • This is the cloud-side first step of a staged rollout: it establishes the additive storage contract, validation, audit behavior, and UI controls while keeping existing clients unchanged.
  • Add server-side validation for concrete model IDs, organization allow/deny policy checks, audit diffs, and release-flag-gated writes through org-default-model-config.
  • Add the cloud UI picker and mode-card display behind the same flag, including built-in override clear behavior and development-mode visibility.
  • Keep the picker sourced from the existing org-scoped model list so mode defaults are selected only from models currently allowed for that organization.

Verification

API response sample

❯ http GET http://localhost:3000/api/organizations/9c3780e5-69ce-4d18-a0a8-b1ec0998db83/modes \
  Authorization:"Bearer very secret" \
  X-KiloCode-OrganizationId:"9c3780e5-69ce-4d18-a0a8-b1ec0998db83"
HTTP/1.1 200 OK
Connection: keep-alive
Cross-Origin-Embedder-Policy-Report-Only: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Date: Fri, 12 Jun 2026 14:14:37 GMT
Keep-Alive: timeout=5
Permissions-Policy: geolocation=(self), camera=(), microphone=()
Referrer-Policy: strict-origin-when-cross-origin
Strict-Transport-Security: max-age=31536000; includeSubDomains
Transfer-Encoding: chunked
<headers trimmed>

{
    "modes": [
        {
            "config": {
                "customInstructions": “",
                "defaultModel": "kilo-auto/balanced",
                "description": "Write, modify, and refactor code",
                "groups": [
                    "browser",
                    "command",
                    "edit",
                    "mcp",
                    "read"
                ],
                "roleDefinition": "You are Kilo Code, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.",
                "whenToUse": "Use this mode when you need to write, modify, or refactor code. Ideal for implementing features, fixing bugs, creating new files, or making code improvements across any programming language or framework."
            },
            "created_at": "2026-06-11 21:54:37.803677+00",
            "created_by": "94ab8d78-f30c-4840-aa1e-387de292c95b",
            "id": "3b325243-bd36-48aa-b9ee-3cb4e8a83cc1",
            "name": "Code",
            "organization_id": "9c3780e5-69ce-4d18-a0a8-b1ec0998db83",
            "slug": "code",
            "updated_at": "2026-06-12 14:14:30.317325+00"
        }
    ]
}

Visual Changes

Before After
Mode drawer without a mode default model control Mode drawer with gated Mode Default Model picker
Mode cards without model metadata Mode cards showing gated default-model metadata
Built-in mode overrides only supported config edits Built-in mode overrides can clear the last default-model override and revert
SCR-20260612-ipys Screenshot 2026-06-12 at 9 18 04 AM Screenshot 2026-06-12 at 9 18 16 AM

Reviewer Notes

  • This is intentionally additive and safe for existing mode rows because defaultModel is optional in the JSONB config.
  • The flag is off for all users except *kilocode.ai emails, so existing cloud behavior remains unchanged until the CLI pr lands and is shipped/vetted/tested.
  • The main risk area is the distinction between clearing a mode-specific default and deleting the last built-in override row.

@pandemicsyn pandemicsyn marked this pull request as ready for review June 12, 2026 14:12
Comment thread apps/web/src/components/organizations/custom-modes/EditModeForm.tsx Outdated
Comment thread apps/web/src/routers/organizations/organization-modes-router.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental diff refactors the default-model validation logic from ad-hoc boolean/branded-type guards into a clean discriminated union (DefaultModelChange), with no behavioral changes. Both previously flagged issues remain resolved.

Files Reviewed (1 file changed since previous review)
  • apps/web/src/routers/organizations/organization-modes-router.ts — clean refactor, no issues
Previously Reviewed Files (unchanged, 6 files)
  • apps/web/src/components/organizations/custom-modes/CustomModesLayout.tsx
  • apps/web/src/components/organizations/custom-modes/EditModeForm.tsx — ✅ groups order-sensitivity fixed
  • apps/web/src/components/organizations/custom-modes/ModeForm.tsx
  • apps/web/src/components/organizations/custom-modes/NewModeForm.tsx
  • apps/web/src/lib/organizations/organization-modes.ts
  • packages/db/src/schema-types.ts
Previous Review Summary (commit 166e95a)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 166e95a)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Both previously flagged issues have been resolved in this update: the groups comparison in matchesBuiltInModeState is now order-insensitive via normalizeGroups, and the audit diff now reads from normalizedConfig (the value actually written to the DB) rather than raw pre-normalization input.

Files Reviewed (7 files)
  • apps/web/src/components/organizations/custom-modes/CustomModesLayout.tsx
  • apps/web/src/components/organizations/custom-modes/EditModeForm.tsx — ✅ groups order-sensitivity fixed
  • apps/web/src/components/organizations/custom-modes/ModeForm.tsx
  • apps/web/src/components/organizations/custom-modes/NewModeForm.tsx
  • apps/web/src/lib/organizations/organization-modes.ts
  • apps/web/src/routers/organizations/organization-modes-router.ts — ✅ audit diff now uses normalized config
  • packages/db/src/schema-types.ts

Reviewed by deepseek-v4-pro-20260423 · 195,858 tokens

Review guidance: REVIEW.md from base branch main

Comment thread apps/web/src/routers/organizations/organization-modes-router.ts Outdated
@pandemicsyn pandemicsyn requested a review from jrf0110 June 15, 2026 16:44

@jeanduplessis jeanduplessis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judgement Review

Problem statement

  • non-blocking: PR explains staged rollout well. Could add one sentence naming expected client precedence order in final shipped behavior: user local override > org mode default > existing fallback.

Solution

  • Pragmatic and clear solution, no feedback.

Risk

  • No feedback.

Architecture

  • blocking: Mode default model writes diverge from existing org model-setting ownership. Current org default model and access-list mutations use organizationBillingMutationProcedure (owner or billing manager), and UI copy says only owners can edit model access. This PR adds per-mode model defaults through organizationMemberMutationProcedure. That creates two architecture concepts for who owns org model policy. Align defaultModel writes with existing org model-setting ownership, or document why mode defaults intentionally follow broader custom-mode permissions.

Operability

  • blocking: Rollback and stale-default behavior are unclear. Disabling org-default-model-config stops UI/write access, but /api/organizations/[id]/modes still returns persisted config.defaultModel. Also, if org policy later denies stored model, test coverage keeps stale value in mode config. Future clients may consume invalid defaults unless endpoint filters them or clients must validate. Add explicit contract plus tests: either server filters/omits invalid mode defaults, settings changes clear invalid mode defaults, or clients must validate against allowed model list before use.
  • non-blocking: Add short rollback note: Something like disable flag, clear affected config.defaultModel values if clients already shipped, verify mode API no longer returns active defaults.

Verification

  • blocking: Verification section lacks confirmation of manual verification for main user journeys: flag on/off behavior, setting and clearing a mode default in UI, built-in override clear/revert behavior, Teams org rejection, denied model rejection, and API payload after set/clear.
  • non-blocking: Add verification steps for reviewer to confirm these flows locally.

Agent Entropy

  • non-blocking: Add short comment or doc near OrganizationModeConfigSchema naming relationship to organization.settings.default_model: org default is global fallback; mode default is per-mode override; user local selection still wins. This will prevent future agent confusion once client work lands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants