* feat(teams): apply default organization to new teams from default team settings
Adds organization_id to DefaultTeamSSOParams so proxy admins can pick a
default organization in Default Team Settings. new_team applies it before
org validation whenever a team is created without an explicit
organization_id, so API, Admin UI, SCIM, SSO, and team upsert creations
all inherit it and go through the same existence and org-limit checks.
Explicit organization selections win and existing teams are untouched.
The default is validated at save time (PATCH /update/default_team_settings
returns 400 for an unknown org) and at create time, where a missing org now
surfaces as a clean 400 instead of a 500 by routing OrganizationNotFoundError
into the previously dead org_table None guard.
The Admin UI Default Team Settings tab gets a Default Organization row
backed by the shared OrganizationDropdown.
* fix(teams): validate org limits against final team state including defaults
Applies default_team_params and the legacy max_budget fallback before the
organization validation block, so _check_org_team_limits sees the values the
team will actually be persisted with. Also loads the org's budget table in
the lookup; without include_budget_table every budget comparison in
_check_org_team_limits was skipped because litellm_budget_table was None.
* test(proxy_behavior): pin org team limits as enforced on /team/new
The dead-code pins existed to turn red when include_budget_table went
live; that happened, so the scenarios now assert the 400 rejections plus
within-cap acceptance, and the unknown-org pin asserts the handler's 400
instead of the surfaced 500.
* test(proxy): behavior-pinning matrix for team management endpoints
PR2 (Team Tier-1) of the management-endpoint behavior-pinning effort.
Extends the tests/proxy_behavior/management/ harness PR1 built and adds
the actor x target-resource authz matrix for the 7 team endpoints:
/team/new, /team/info, /team/list, /team/update, /team/member_add,
/team/member_delete, /team/member_update.
Tests-only, no production code changes.
Harness extensions:
- actors.py: ORG_B_ADMIN actor (org admin of ORG_B) and TEAM_GAMMA (an
ORG_A team with no actor members), so team-targeting endpoints get a
clean own / same-org-other / cross-org target axis.
- conftest.py: create_scratch_team() raw-seeds target teams without
/team/new side effects; the scratch teardown now also strips dangling
scratch-team refs from LiteLLM_UserTable.teams.
156 new scenarios; status codes pinned to observed handler behavior.
* test(proxy): record mutmut run blockers in PR2 triage doc
Attempted a scoped local mutmut run for G5; it did not complete. Record
the three concrete blockers in mutmut_triage/pr2-team-tier1.md so the next
attempt has a head start:
1. mutmut's mutants/ sandbox is import-shadowed by the worktree source.
2. the legacy mock suite and the real-DB behavior suite cannot share a
pytest session (mock suite globally patches prisma_client).
3. the CI mutation-test.yml workflow starts no Postgres, so its stats
phase now aborts on the behavior-suite tests PR1 added to tests_dir.
mutmut stays a deferred follow-up (as in PR1); the binding pre-merge
signal remains the behavior matrix (G1) and the G4 regression-replay.
* test(proxy): drop suite README + triage doc, trim test comments
Remove the two prose docs from the behavior suite (README.md and
mutmut_triage/pr2-team-tier1.md) and tighten the comment blocks on the
team test files + harness down to the load-bearing parts (the gate each
matrix pins, plus genuinely surprising results). No behavior change —
all 286 scenarios still pass.
* test(proxy): remove mutmut tests_dir comment