Repository navigation
Switchable Team Features 2026 10 24
The fourth Project Review pass left two things between the project and a 10: queued runs live only in memory, so a server restart drops them, and the team server has one shared token, so there are no per-person accounts, roles or audit trail. Both are what a bigger team wants. Neither should cost anything for one developer running testo on a laptop or a small team sharing one token, which is most users today.
Each feature is a switch with today's behaviour as the default. Turning a switch off returns exactly the old code path.
-
memory: unchanged. Queued runs are in the in-process FIFO only. -
db:CycleExecutionManageralso writes each queued run as a row ofqueued_runin the run-history database (SQLite or Postgres, whateverDATABASE_URLpoints at). The row holds aRunRequest(testo_api/run_queue.py): the cycle or ad-hoc stage and its options, as JSON. -
Lifetime. A worker deletes the row as it starts the run (
claim). So the table only holds runs that have not started, and a run that was running when the process died is not repeated (the orphaned-run cleanup already marks it failed in the history). Repeating half-finished test runs automatically was judged worse than failing them visibly. -
Restart. The API's startup hook calls
recover_queued(), which queues every row again under its old execution id, oldest first, so a client that was polling that id carries on. -
Two processes.
claimis an atomicDELETE; if two processes both re-queued a row, only the one whose delete removed it runs it. One server process is still the supported setup: the one-run-per-cycle guard andTESTO_MAX_CONCURRENT_RUNSare per process. - The in-process FIFO stays the source of order. The table is only the durable copy, so there is one queue implementation, not two.
-
token: unchanged. OneTESTO_API_TOKEN, and/logintrades it for a session cookie. -
accounts: people sign in at/loginwith a username and password. Accounts live in the run-history database (user_account): password hashed withscrypt(stdlib, salted), a role, and a session version that signs that user out everywhere when bumped. Managed withtesto users add|list|set-role|remove|reset-password, which talk to the database directly, so there is no sign-up page to attack. -
Roles.
viewerreads;runneralso starts runs and uploads results;adminalso changes AI settings. The bearerTESTO_API_TOKENkeeps working as an admin for CI and scripts, and is the secret the session cookies are signed with. -
Audit log. Every write by a signed-in user (or the token) is recorded in
audit_event(time, user, method, path, status) and readable by admins atGET /api/v1/audit. -
GET /api/v1/auth/metells the UI who is signed in and with what role.
- A real queue service (Redis + RQ/Celery). Survives restarts and scales across machines, but adds a service and a second process to run. Rejected: the database is already there and the load is a handful of runs.
- Re-running interrupted runs on restart. Rejected: a half-run suite may have changed shared state (a test database, deployed fixtures); failing it visibly is safer.
-
OAuth / SSO (GitHub, Google, OIDC) instead of passwords. The right end state for a company, but it needs a public callback URL and a provider app per install. Rejected for now;
TESTO_AUTHleaves room for anoidcvalue later. - Always-on accounts. Rejected: it would make the laptop and small-team setups create a user before anything works.
- With both switches at their defaults, nothing changes: no new tables are used and no behaviour differs. The team server compose file shows both switches, still off.
- Both modes of each switch have tests and have to be kept working. That is the price of not forcing the team features on small users.
- In
dbmode the queued run's request (including an ad-hoc run'sextra_env) sits in the database until the run starts. - Tests:
tests/unit/test_run_queue.py(round trip, claim once, restart recovery, env parsing) andtests/contract/api/test_accounts_contract.py.
Generated from docs/Specs & ADRs/Switchable Team Features - 2026-10-24.md. Edit it there; changes made in the wiki are overwritten.
Architecture
CLI Commands
Processes & Guides
- CI-CD Pipeline Setup
- E2E Harness Operations Guide
- GitLab Pages Demo
- Publishing Docker Images
- Publishing to Artifactory
- Publishing to PyPI
- Team Server
Prompts & Snippets
Roadmap & Strategy
Specs & ADRs
- Alerts Where Developers Look - 2026-10-22
- Architecture Consolidation - 2026-10-06
- BehaveX Reports - 2026-10-21
- Command Adapter and JUnit Import - 2026-09-25
- Config JSON Schema - 2026-10-22
- Delta Comparison Policy
- Docs Site - 2026-10-19
- Docs Vault and Wiki Sync - 2026-10-07
- Flaky Test Quarantine - 2026-10-22
- GitHub Action PR Comment - 2026-10-19
- Ingest and Team Server - 2026-10-22
- Interview Readiness Fixes - 2026-10-07
- Library Packaging
- Open Source Features - 2026-10-19
- Phase 3 Delta Comparison Engine Plan
- Phase 3 Unified Dashboard Plan
- Phase 4 BYOK and Failure Analysis
- Phase 5 UI Redesign - Cycles-First Navigation
- Playwright Adapter - 2026-10-19
- Playwright JSON Import - 2026-10-22
- Plugin API - 2026-10-19
- Specs & ADRs
- Repository Pattern - Database-Agnostic Refactor
- Scale Runs and Stages - 2026-10-24
- Switchable Team Features - 2026-10-24
- Throwaway Stage Containers - 2026-10-24
- UI Restyle - 2026-10-19
Testing Workflows
Vault