320 Commits
Author SHA1 Message Date
Bentlybro f860d3186e Tighten input validation on auth, invitation and webhook routes 2026-10-19 15:38:00 +01:00
Bentlybro 6dbfbbae2a Update admin confirm dialogs 2026-10-19 11:38:05 +01:00
Bentlybro 9d0a51a265 Fix registration default when enabled by env 2026-10-19 11:33:02 +01:00
Bentlybro 21c831572c Fix project and user deletion, update admin registration toggle 2026-10-19 11:28:32 +01:00
Bentlybro 3d86c0412e Tidy comments 2026-10-19 11:15:05 +01:00
Bentlybro 3fa9e94744 Tighten Sentry config 2026-10-19 11:14:07 +01:00
Bentlybro 185a1a2625 Pin SQLAlchemy below 2.1 2026-10-19 11:12:35 +01:00
Bentlybro 9a779a4c96 Update registration settings and admin project management 2026-10-19 11:05:09 +01:00
Bently b19d3d8dbf Merge pull request #92 from Significant-Gravitas/dependabot/docker/docker/dev/python-3.14-slim
Bump python from 3.12-slim to 3.14-slim in /docker
2026-09-22 11:53:56 +01:00
Bently c7452ca294 Merge pull request #95 from Significant-Gravitas/dependabot/pip/dev/beautifulsoup4-4.15.0
Bump beautifulsoup4 from 4.14.3 to 4.15.0
2026-09-22 11:53:51 +01:00
Bently e083d307ad Merge pull request #98 from Significant-Gravitas/dependabot/pip/dev/wtforms-3.2.2
Bump wtforms from 3.2.1 to 3.2.2
2026-09-22 11:52:58 +01:00
Bently dbc7c37d9f Merge pull request #99 from Significant-Gravitas/dependabot/pip/dev/authlib-1.7.2
Bump authlib from 1.7.0 to 1.7.2
2026-09-22 11:52:53 +01:00
Bently 031b3dbd86 Merge pull request #100 from Significant-Gravitas/dependabot/pip/dev/requests-2.34.2
Bump requests from 2.33.1 to 2.34.2
2026-09-22 11:52:47 +01:00
Bently af748eac4b Merge pull request #101 from Significant-Gravitas/dependabot/github_actions/dev/actions/setup-python-7
Bump actions/setup-python from 6 to 7
2026-09-22 11:52:43 +01:00
Bently 8ea8f0fac1 Merge pull request #105 from Significant-Gravitas/dependabot/pip/dev/pre-commit-4.6.1
Bump pre-commit from 4.6.0 to 4.6.1
2026-09-22 11:52:13 +01:00
Bently 5ee1655e79 Merge pull request #106 from Significant-Gravitas/dependabot/pip/dev/sentry-sdk-gte-2.66.1-and-lt-3.0.0
Update sentry-sdk requirement from <3.0.0,>=2.64.0 to >=2.66.1,<3.0.0
2026-09-22 11:51:47 +01:00
Bently 2f08d036f6 Merge pull request #107 from Significant-Gravitas/dependabot/pip/dev/openai-gte-2.48.0-and-lt-3.0.0
Update openai requirement from <3.0.0,>=2.44.0 to >=2.48.0,<3.0.0
2026-09-22 11:51:03 +01:00
dependabot[bot] 65a4538ec4 Update openai requirement from <3.0.0,>=2.44.0 to >=2.48.0,<3.0.0
Updates the requirements on [openai](https://github.com/openai/openai-python) to permit the latest version.
- [Release notes](https://github.com/openai/openai-python/releases)
- [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/openai/openai-python/compare/v2.44.0...v2.48.0)

---
updated-dependencies:
- dependency-name: openai
  dependency-version: 2.48.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-27 08:54:22 +00:00
dependabot[bot] d651931d33 Update sentry-sdk requirement from <3.0.0,>=2.64.0 to >=2.66.1,<3.0.0
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.64.0...2.66.1)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-version: 2.66.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-27 08:54:16 +00:00
dependabot[bot] 1ed7bf4acf Bump pre-commit from 4.6.0 to 4.6.1
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 4.6.0 to 4.6.1.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v4.6.0...v4.6.1)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-version: 4.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-27 08:54:05 +00:00
dependabot[bot] 021e8f17a4 Bump actions/setup-python from 6 to 7
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-20 08:53:59 +00:00
dependabot[bot] 9b78420642 Bump requests from 2.33.1 to 2.34.2
Bumps [requests](https://github.com/psf/requests) from 2.33.1 to 2.34.2.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.33.1...v2.34.2)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.34.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-13 08:55:27 +00:00
dependabot[bot] 7f603d57f4 Bump authlib from 1.7.0 to 1.7.2
Bumps [authlib](https://github.com/authlib/authlib) from 1.7.0 to 1.7.2.
- [Release notes](https://github.com/authlib/authlib/releases)
- [Commits](https://github.com/authlib/authlib/compare/v1.7.0...v1.7.2)

---
updated-dependencies:
- dependency-name: authlib
  dependency-version: 1.7.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-13 08:55:16 +00:00
dependabot[bot] 3c9bf0f5a3 Bump wtforms from 3.2.1 to 3.2.2
Bumps [wtforms](https://github.com/pallets-eco/wtforms) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/pallets-eco/wtforms/releases)
- [Changelog](https://github.com/pallets-eco/wtforms/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets-eco/wtforms/compare/3.2.1...3.2.2)

---
updated-dependencies:
- dependency-name: wtforms
  dependency-version: 3.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-13 08:55:06 +00:00
dependabot[bot] 05d0860b47 Bump beautifulsoup4 from 4.14.3 to 4.15.0
Bumps [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) from 4.14.3 to 4.15.0.

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-version: 4.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-13 08:54:26 +00:00
dependabot[bot] 50600a0269 Bump python from 3.12-slim to 3.14-slim in /docker
Bumps python from 3.12-slim to 3.14-slim.

---
updated-dependencies:
- dependency-name: python
  dependency-version: 3.14-slim
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
2026-07-13 08:53:48 +00:00
Bentlybro e5efd669b2 Register the / -> login redirect in the app factory
The root route lived only in run.py (dev server), so gunicorn wsgi:app
never registered it and the bare domain 404'd in every deployment. Move
it into create_app so dev and prod both redirect / to the login page.
2026-07-06 14:52:18 +01:00
Bentlybro b074c10d07 Remove dead API-key reveal modal and JS
The full-key reveal modal and its click/copy handlers referenced the
plaintext key display that was dropped when keys became hashed. They
matched no elements (harmless no-ops), so remove the orphaned modal
markup and handlers; toggle/delete handlers are untouched.
2026-07-06 13:50:18 +01:00
Bentlybro e876ff796a Store API keys hashed instead of in plaintext
Keys are now stored as a SHA-256 digest in the existing key column (64
chars, no schema change). Lookups hash the presented key; rows still
holding plaintext are matched and upgraded to their hash on first use.
The full key is shown once at creation and the dashboard displays a
masked placeholder thereafter.
2026-07-06 13:41:53 +01:00
Bentlybro 9564b63bc2 Pin both Dockerfiles to python:3.12-slim
docker/Dockerfile used 3.14-slim and deploy/Dockerfile used 3.11-slim.
Unify on 3.12 — the version the CI matrix tests against and the local
venv runs — so the image matches what's actually validated. Update the
docs that referenced 3.11 to match.
2026-07-06 13:31:04 +01:00
Bentlybro 6642f71b70 Fix stale docs and remove dead code paths
- run.py and the __init__ SocketIO comment referenced the eventlet
  worker; production uses gthread. Copy-pasting the old run.py guidance
  would have redeployed the exact config wsgi.py warns against.
- README/CLAUDE tech-stack tables said Flask 2.3.3 (actual: 3.1.3);
  CLAUDE architecture tree listed a rule_cache.py that doesn't exist.
- Drop the per-request token count that was computed and stored on the
  content object but never read (the AI paths recount as needed).
- Remove the conflicting-AI-decisions manual-review branch: the pipeline
  early-exits on the first AI match, so it could never see >1 AI result.
- Read/reset the process-global cache-store counter under the cache lock
  so it can't tear against the locked increment.
2026-07-06 13:09:24 +01:00
Bentlybro a47d8c7dbe Tighten request keying and route input handling
- Resolve the /api/moderate rate-limit bucket from the request's API key
  directly (hashed) instead of request.api_key, which isn't populated yet
  at the limiter layer — so per-key limits actually apply rather than
  always falling back to per-IP.
- Bound registration password length to match the login form (8-200),
  so an over-long password can't register an account that can never log in.
- Flash generic messages on admin user/data operation failures and log
  the detail server-side instead of surfacing raw exception text.
- Only allow manual decisions on content still awaiting review (status
  'flagged'), matching the bulk path, so a decided item isn't overwritten.
- Build the manual-review API-user search's accessible-project list by
  membership rather than ownership, so member-only users get results.
2026-07-06 13:04:48 +01:00
Bentlybro 99a752f152 Harden moderation persistence and cache correctness
- Make API-key and API-user usage counters atomic (single UPDATE ...
  SET col = col + 1) so concurrent moderations for the same key/user
  don't lose increments to a read-modify-write race.
- Persist each moderation outcome (content status + user counters +
  result rows) in a single transaction via save_moderation_outcome,
  replacing three independent commits plus a no-op commit that could
  leave a decided status with no result rows on partial failure.
- Include rule.action in the batched AI cache fingerprint and clear the
  shared result cache when a rule is created/updated/toggled/deleted, so
  edits take effect immediately instead of after the 1h TTL.
- Flag (not approve) content that exceeds the per-request chunk cap:
  partial coverage must not yield a clean approval.
2026-07-06 13:00:25 +01:00
Bentlybro 24393c3269 Bump pydantic 2.13.2->2.13.4 and regex 2024.11.6->2026.6.28
Applies the two remaining Dependabot bumps (#85, #83) directly; their
PR branches had stale merge bases and conflicted after the dev history
rewrite. Supersedes both PRs.
2026-07-06 12:41:22 +01:00
dependabot[bot] 665a4df6bb Bump flask-wtf from 1.2.2 to 1.3.0 (#80)
Bumps [flask-wtf](https://github.com/pallets-eco/flask-wtf) from 1.2.2 to 1.3.0.
- [Release notes](https://github.com/pallets-eco/flask-wtf/releases)
- [Changelog](https://github.com/pallets-eco/flask-wtf/blob/main/docs/changes.rst)
- [Commits](https://github.com/pallets-eco/flask-wtf/compare/v1.2.2...v1.3.0)

---
updated-dependencies:
- dependency-name: flask-wtf
  dependency-version: 1.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:39:43 +01:00
dependabot[bot] 989d2c775c Bump actions/checkout from 6 to 7 (#88)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:39:27 +01:00
dependabot[bot] f9c3391995 Bump psycopg2-binary from 2.9.11 to 2.9.12 (#84)
Bumps [psycopg2-binary](https://github.com/psycopg/psycopg2) from 2.9.11 to 2.9.12.
- [Changelog](https://github.com/psycopg/psycopg2/blob/master/NEWS)
- [Commits](https://github.com/psycopg/psycopg2/compare/2.9.11...2.9.12)

---
updated-dependencies:
- dependency-name: psycopg2-binary
  dependency-version: 2.9.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:39:20 +01:00
dependabot[bot] 2715fc9275 Bump pre-commit from 4.5.1 to 4.6.0 (#81)
Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 4.5.1 to 4.6.0.
- [Release notes](https://github.com/pre-commit/pre-commit/releases)
- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md)
- [Commits](https://github.com/pre-commit/pre-commit/compare/v4.5.1...v4.6.0)

---
updated-dependencies:
- dependency-name: pre-commit
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:38:58 +01:00
dependabot[bot] 39444d476f Bump httpx from 0.27.2 to 0.28.1 (#79)
Bumps [httpx](https://github.com/encode/httpx) from 0.27.2 to 0.28.1.
- [Release notes](https://github.com/encode/httpx/releases)
- [Changelog](https://github.com/encode/httpx/blob/master/CHANGELOG.md)
- [Commits](https://github.com/encode/httpx/compare/0.27.2...0.28.1)

---
updated-dependencies:
- dependency-name: httpx
  dependency-version: 0.28.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:38:50 +01:00
dependabot[bot] a231dfa42f Bump gunicorn from 23.0.0 to 26.0.0 (#82)
Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 23.0.0 to 26.0.0.
- [Release notes](https://github.com/benoitc/gunicorn/releases)
- [Commits](https://github.com/benoitc/gunicorn/compare/23.0.0...26.0.0)

---
updated-dependencies:
- dependency-name: gunicorn
  dependency-version: 25.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:38:42 +01:00
dependabot[bot] 5eab49e07f Bump flask-limiter from 3.8.0 to 4.1.1 (#78)
Bumps [flask-limiter](https://github.com/alisaifee/flask-limiter) from 3.8.0 to 4.1.1.
- [Release notes](https://github.com/alisaifee/flask-limiter/releases)
- [Changelog](https://github.com/alisaifee/flask-limiter/blob/master/HISTORY.rst)
- [Commits](https://github.com/alisaifee/flask-limiter/compare/3.8.0...4.1.1)

---
updated-dependencies:
- dependency-name: flask-limiter
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:38:36 +01:00
dependabot[bot] a4b5c33661 Update openai requirement from <3.0.0,>=2.32.0 to >=2.44.0,<3.0.0 (#87)
Updates the requirements on [openai](https://github.com/openai/openai-python) to permit the latest version.
- [Release notes](https://github.com/openai/openai-python/releases)
- [Changelog](https://github.com/openai/openai-python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/openai/openai-python/compare/v2.32.0...v2.44.0)

---
updated-dependencies:
- dependency-name: openai
  dependency-version: 2.33.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:38:26 +01:00
dependabot[bot] 9d86a2a517 Update sentry-sdk requirement from <3.0.0,>=2.40.0 to >=2.64.0,<3.0.0 (#77)
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.40.0...2.64.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-version: 2.58.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 12:38:06 +01:00
Bentlybro ccbcc873ca Remove claude-code-security-review CI workflow
No longer used; the job failed on every PR because the CLAUDE_API_KEY
secret is unset, producing no findings.json and a red X on all open
Dependabot PRs. Other security checks (CodeQL, Snyk, bandit in ci.yml)
remain in place.
2026-07-06 12:07:31 +01:00
Bentlybro f27ea85c3e Stop crawler hits on Google OAuth callback from paging Sentry
Bots and link prefetchers hit /auth/google/callback directly with no
OAuth session, making Authlib raise mismatching_state. The broad
except Exception logged it at error level, promoting every crawl into a
Sentry issue (SENTRY#1386). Catch OAuthError specifically and log at
info so it stays a breadcrumb; genuine flow failures still fall through
to the error-level handler.
2026-07-06 12:05:51 +01:00
Bentlybro 6ecff36871 Filter StopIteration from Engine.IO WebSocket upgrade out of Sentry
engineio/async_drivers/_websocket_wsgi.py intentionally raises
StopIteration after a successful WebSocket upgrade to tell gunicorn
"I'm keeping this connection open, don't finalize the response." It's a
protocol signal, not a real error, but Sentry's WSGI instrumentation
captures it anyway and it gets reported as AUTOMOD-3E.

Only drop it on the /socket.io/ path so we don't accidentally hide a
genuine StopIteration bubbling up from elsewhere.
2026-04-22 14:33:09 +01:00
Bentlybro a38762dd05 Switch gunicorn worker from eventlet to gthread
Cloud Run was 500-ing every async route on the eventlet worker:

  RuntimeError: asyncio.run() cannot be called from a running event loop
  RuntimeError: You cannot use AsyncToSync in the same thread as an
                async event loop - just await the async function directly.

Root cause: standard Flask decorators (@login_required from Flask-Login,
@limiter.limit from Flask-Limiter, and Flask's own async-view wrapper)
call ``flask.current_app.ensure_sync(obj)(*a, **k)``, which uses
``asgiref.AsyncToSync``, which calls ``asyncio.run()``. Under eventlet's
greenlet hub ``asyncio.run()`` raises because the hub *is* the running
loop. Every ``async def`` route wrapped by any of those decorators (i.e.
all of /api/moderate, /auth/*, /dashboard/*) dies at the decorator
boundary before the view body ever executes. Sentry AUTOMOD-3B/3C/3D.

The dev server didn't show this because werkzeug gives each request a
fresh OS thread with no existing event loop, so asgiref can spin up its
own loop fine.

gthread worker + SOCKETIO_ASYNC_MODE=threading:
- Real OS threads for each request → asgiref's AsyncToSync works.
- Flask-SocketIO threading mode supports WebSockets for our
  dashboard-scale realtime traffic.
- Dev (run.py) and prod now use the same async mode, so behaviour
  matches end-to-end.
- 50 threads/worker = plenty of concurrency for HTTP + long-lived
  WebSocket connections.

Dropped eventlet and psycogreen from requirements.txt — they were pinned
specifically for the eventlet worker, neither is used any more.
2026-04-22 14:22:26 +01:00
Bentlybro 29d0764075 Fix Cloud Run boot crash: sentry-sdk 2.18 doesn't accept enable_logs
Cloud Run workers were dying with a TypeError in sentry_sdk.init because
`enable_logs=True` isn't a valid kwarg until sentry-sdk 2.40. Our Phase 0
pin of 2.18.0 was older than the kwarg. Two defences:

- Bump sentry-sdk[flask] to >=2.40.0,<3.0.0 so the kwarg works.
- Catch TypeError in create_app() and fall back to sentry_sdk.init without
  enable_logs, so future kwarg churn across sentry-sdk versions can't
  brick the whole app at boot — error reporting still initialises, we
  just log a warning and lose the logs feature.

The eventlet "10 RLock(s) were not greened" warning in those Cloud Run
logs is not the crash cause; gunicorn's eventlet worker monkey-patches
after its own import of gunicorn internals, and the warning is benign
for our workload. The sentry-sdk TypeError was the actual blocker.
2026-04-22 14:12:03 +01:00
Bentlybro e7418eb841 Bump deps: Flask 3.1.3, Werkzeug 3.1.8, Authlib 1.7, pydantic 2.13.2, etc.
Rolls up the open dependabot PRs #65, #66, #69, #72, #73, #74, #75, #76
into a single commit. Each bump is a minor/patch release with no breaking
changes relevant to this codebase; all chat.completions / Flask-SocketIO
/ pydantic-v1-validator usage continues to work.

- Flask[async]       3.1.2 -> 3.1.3   (#65, #72)
- Flask-SocketIO     5.6.0 -> 5.6.1   (#66)
- Werkzeug           3.1.5 -> 3.1.8   (#73; supersedes master-targeting #67
                                        which wanted 3.1.6)
- python-dotenv      1.2.1 -> 1.2.2   (#69)
- requests           2.32.5 -> 2.33.1 (#74)
- pydantic           2.12.5 -> 2.13.2 (#76)
- Authlib            1.6.8 -> 1.7.0   (#75)

Doing this as one commit on dev because dev has diverged from master
(Phase 0 + Phase 1 security/architectural work) and each dependabot PR
has a requirements.txt conflict against the new pins we added — resolving
8 of those by hand is more churn than just bumping the versions directly.
2026-04-22 14:06:23 +01:00
Bentlybro 4935119ac2 Default OPENAI_REASONING_EFFORT to 'low' (not 'minimal')
'minimal' is only valid on older gpt-5 / o-series models and is rejected
by gpt-5.4 with a 400 ("Supported values are: 'none', 'low', 'medium',
'high', 'xhigh'"). Our fail-safe silently approved every request when the
API errored, which presented as "moderation is fast but broken" in real
tests — scam / phishing / misinfo content was getting through.

'low' is the lowest common value accepted by every reasoning model in the
family so the default works regardless of which model you point the
OPENAI_CHAT_MODEL at. Empirically verified: 8/8 real-world classification
accuracy on gpt-5.4-nano with reasoning=low, vs 2/4 with reasoning=none
(false negatives on obvious scams).
2026-04-22 14:03:38 +01:00