WS8 PR F review fix: enforce firm model policy on the chat routes
Blocker from independent review: firm model config was filtered client-side
only. POST /chat and POST /projects/:id/chat accepted a raw body.model, so a
policy-OFF member (or a policy-ON member under a provider restriction) could
bypass the policy with a crafted request ("gate the routes, not the tabs").
Fix: new resolveOrgChatModel(userId, requested, db) in userSettings.ts, applied
right after model resolution on both streaming chat routes. Rules: local ids
pass through untouched; fail-open on org-lookup error / orgless; policy-OFF +
firm default -> forced to firm default; requested provider outside a non-empty
offeredProviders -> substituted (firm default -> default main model -> first
offered provider's default). models.ts gains safeProviderForModel +
defaultMainModelForProvider.
Coherence: PATCH /admin/model-config now rejects (400) a MERGED config whose
cloud default model's provider sits outside a non-empty offeredProviders, so the
clamp can treat a set firm default as an in-set substitute; a local default is
exempt.
Routes checked for raw client model ids: tabular resolves via getUserModelSettings
(already firm-aware); workflows accepts no client model - neither needs a clamp.
Tests: +14 (309 total, 24 files) - resolveOrgChatModel clamp matrix and the
model-config coherence 400s. Backend tsc + vitest green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| Repository | Sloth-ninja/JessicaOSS |
|---|---|
| Author | sloth-ninja <ezanahaddis@gmail.com> |
| Authored | |
| Parents | e504926a |
| Stats | 8 files changed , +293 , -19 |
| Part of | WS8 PR F: firm model preferences |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-3fa1d9eb.md
from inside the repo you want the change in.