Commit Graph

24 Commits

Author SHA1 Message Date
overseer bdc984e5ff fix: stop duplicate-key 500 cascade on shared PG connection
The REST/Web-UI HTTPServer shares one long-lived PG connection across all
requests. Any statement that raised mid-request (e.g. a UniqueViolation from
a desynced SERIAL sequence) aborted the transaction; the global handler
returned 500 without rolling back, so every subsequent request failed with
InFailedSqlTransaction until restart — surfacing as "duplicate keys cause
500s" and "500 immediately after login".

- server.py: global handler now always rolls back the shared connection on
  error and maps constraint violations to 409 (was 500/400). This is the one
  funnel that guarantees the connection is never left aborted.
- db.py: add is_integrity_error() — dual-backend (psycopg + sqlite3)
  constraint-violation classifier; replaces the fragile `"UNIQUE" in msg`
  string match that never matched Postgres' error text.
- Remove make_write_mcp_server: a never-run duplicate of the MCP write tools
  that had bit-rotted (wrong file_update arg order + FK-violating hardcoded
  actor). Live writes go through oauth_mcp_app, which is correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 21:10:12 +00:00
overseer 80635ce011 fix: drop NOT NULL on user_id FK columns for ON DELETE SET NULL
audit_log.user_id, change_requests.submitted_by, reviews.reviewer_id
were NOT NULL but had ON DELETE SET NULL — PG can't set a NOT NULL
column to NULL on delete, so user deletion failed. Migration now drops
NOT NULL before altering the FK constraint.
2026-06-25 14:47:37 +00:00
overseer 9bb89ee62f feat: allow user deletion — FK constraints ON DELETE SET NULL
- schema.sql: all user_id FKs now ON DELETE SET NULL (was RESTRICT)
- migrate_user_fk_set_null.py: drop+readd constraints on existing DBs
- entrypoint.sh: runs migration automatically on startup (non-fatal)
- db.py: rollback moved before FK check (cleanup)

Deleting a user now nullifies their references in audit_log,
project_context, context_files, change_requests, reviews instead of
blocking with a 409.
2026-06-25 14:43:58 +00:00
overseer bc43e9a8d1 fix: rollback aborted PG transaction on user delete FK violation
PostgreSQL enters 'current transaction is aborted' state after a
ForeignKeyViolation. Without rollback(), every subsequent query on the
shared connection fails with 'commands ignored until end of transaction
block'. Now both db.py and server.py rollback on the error path.
2026-06-25 14:29:00 +00:00
overseer d2c6906c4f ui: show activate OR inactivate based on user state (not both) 2026-06-25 14:24:37 +00:00
overseer 570b7d1dba ui: move activate/inactivate/delete to user list table actions column
- New actions column (right of state) with inline buttons per row
- Manage form keeps save user + clear only (no duplicate action buttons)
- Themed to match admin dialog: JetBrains Mono, uppercase, square borders
- Delete uses danger styling
2026-06-25 14:19:11 +00:00
overseer 451732c867 ui: OAuth client list scopes button matches admin theme 2026-06-25 14:07:32 +00:00
overseer 9e85c1b8ec ops: prevent 502 from ctxd without postgres
- entrypoint: wait for DATABASE_URL (CTXD_PG_WAIT_SECONDS) with clear fatal message
- scripts/deploy.sh: postgres healthy then force-recreate ctxd
- compose + README: ban --no-deps ctxd as default; 502 troubleshooting
2026-06-25 13:59:51 +00:00
overseer 59609f93c4 fix: MCP OAuth discovery for ChatGPT (RFC 9728 /mcp PRM, WWW-Authenticate)
- scopes_supported on protected-resource metadata
- /.well-known/oauth-protected-resource/mcp (path-prefix match)
- 401 on /mcp points resource_metadata at PRM URL; advertise scopes
- Prefer client_secret_basic in AS metadata (ChatGPT connector quirk)
- README: does not implement OAuth / 502 / 404 troubleshooting
2026-06-25 13:53:31 +00:00
overseer 07cf223d16 docs: ChatGPT MCP connector checklist in README 2026-06-25 13:46:22 +00:00
overseer ce1c0a175f docs: admin OAuth scope caps in SKILL.md 2026-06-25 13:13:31 +00:00
overseer 1c9d8f7648 feat: OAuth client scope assignment in admin panel
- Create client: ctxd.read / ctxd.write checkboxes
- Client list: show scopes, edit via PATCH /oauth/clients/:id
- Authorize grants intersection of client allowed scopes and request
- CLI oauth-client-create --scope; DCR default ctxd.read ctxd.write
2026-06-25 13:13:25 +00:00
overseer 87f02eb4d1 test: hit /mcp in tools/list fallback branch 2026-06-25 12:46:05 +00:00
overseer 289c6b9300 refactor: public OAuth MCP at /mcp (readonly path is alias)
- OAuth read+write on /mcp; API key on /mcp still full internal tools (LAN)
- /readonly/mcp and /oauth/mcp remain OAuth aliases
- OAuth metadata and connector_url point to /mcp
- README + Traefik template: route Host without blocking /mcp
2026-06-25 12:45:59 +00:00
overseer 12b60ee8c7 feat: unified OAuth MCP connector (read+write on /readonly/mcp)
Scope-gated tools on one Streamable HTTP URL; /oauth/mcp alias.
Reconnect Claude once with ctxd.read ctxd.write.
2026-06-25 12:44:01 +00:00
overseer e3567f649f fix: OAuth write MCP via SSE; require container recreate after build
- Route public write at GET /write/sse and POST /write/messages (ctxd.write)
- Always require write token on /write/messages (was optional)
- Remove debug tracing; document SSE write surface in SKILL.md
- Add scripts/test_write_mcp.py for local OAuth write smoke test
2026-06-25 12:38:50 +00:00
overseer fe63ad350e fix: reset SERIAL sequences after SQLite migration to prevent UniqueViolation
Migration script now resets SERIAL sequences (audit_log, context_files, etc.)
to max(existing_id) after copying rows. Without this, the sequence is still at
its post-schema-creation value and every INSERT hits a duplicate key error.
2026-06-25 10:50:35 +00:00
overseer 364c7795d4 fix: entrypoint.sh set -e crash, __main__.py PostgreSQL check, cli.py seed placeholders
- entrypoint.sh: use NEEDS_INIT variable instead of exit codes (set -e was killing the script)
- __main__.py: skip db_path.exists() check when using PostgreSQL
- cli.py: use dual-backend placeholders for _seed_context (was using SQLite ? syntax)
- cli.py: use 'admin' instead of 'system' for seed updated_by (FK constraint)
2026-06-25 00:20:55 +00:00
overseer b9f911994d refactor: rename container from dossier to ctxd
- docker-compose.yml: service name dossier → ctxd, container_name dossier → ctxd
- README.md, SKILL.md, LLM.txt: all docker exec/logs references updated
- Hermes skill files: all references updated
2026-06-24 23:19:08 +00:00
overseer b91d03a6cd docs: add LLM.txt for automated installation and deployment assistance 2026-06-24 22:55:05 +00:00
overseer fc1a2f5103 feat: PostgreSQL migration, OAuth write MCP, Streamable HTTP, env-driven config, admin UI, landing page
- Migrate database from SQLite to PostgreSQL 16 (dual-backend with SQLite fallback)
- Add Streamable HTTP MCP transport (replaces SSE): /readonly/mcp, /write/mcp, /mcp
- Add OAuth ctxd.write scope and public write MCP surface
- Add ctxd.write token validation (write-scoped tokens only on /write/mcp)
- Add env-driven configuration (.env file with env var precedence over ctxd.yaml)
- Add PostgreSQL to docker-compose.yml with healthcheck
- Add psycopg dependency, migration script (SQLite → PostgreSQL)
- Add admin UI: projects tab with typed-confirm delete, user management (list/manage subtabs)
- Add OAuth client management: create, list, revoke (UI, CLI, API)
- Add user active/inactive lifecycle (PATCH/DELETE APIs)
- Add public landing page with themed login form (cookie-based session)
- Add get_client_guide MCP tool (locked LLM-CLIENT.MD in ctxd-docs project)
- Add DELETE /projects/<id> endpoint with cascading deletes
- Add project_delete to db.py with FK ON DELETE SET NULL for audit_log
- Add cookie-based session auth (ctxd_session cookie on login)
- Add landing.html (public host) vs ui.html (internal dashboard)
- Add schema_sqlite.sql for SQLite fallback
- Add auth_password.py (PBKDF2-SHA256 password hashing)
- Add .env.example template with all documented env vars
- Add README.md with full setup, config, API, CLI, and troubleshooting docs
- Add SKILL.md (canonical LLM client guide, lives in project root)
- Update Traefik template: route everything except /mcp
- Update OAuth discovery: advertise ctxd.write scope, /readonly/mcp resource
- Update Hermes MCP config: /mcp endpoint with Bearer header
- Remove DB-level audit_log triggers (conflict with FK ON DELETE SET NULL)
- Remove SSE transport code (replaced by Streamable HTTP)
- Untrack __pycache__ and data/ctxd.db from git
2026-06-24 22:50:54 +00:00
overseer a9ccfa2694 Stop tracking ctxd.db-shm and ctxd.db-wal and add to .gitignore 2026-06-24 11:12:33 +00:00
overseer 5a0aa2d4fe Stop tracking ctxd.yaml and add to .gitignore 2026-06-24 10:57:53 +00:00
overseer 3c9742ff87 Initial Commit 2026-06-23 23:54:37 +00:00