Reference

Extending TestLookup

Change the smallest part that does the job, and follow what each part promises, from the API route to the screen. Code under backend/app/services is shared code inside the backend. It isn't a separately deployed service.

Codebase map

Routes, services and schemas

Start from the HTTP or streaming route. From there, follow:

Add typed contracts, which spell out what each part promises, together with the change in behavior. Add tests for refused access at the same time.

Keep a project ID in the route path, not in a query parameter. The authorization architecture test checks only routes with a project ID in the path. So a project ID passed as a query parameter escapes that check.

The codebase map on GitHub explains what each part of the repository does.

Parser and format

Treat these parts as one unit that must stay compatible: report detection, parsing, archive unpacking, validation, the normalized results, the limits and the rejected rows. A new format needs:

Don’t assume TestLookup supports a format just because an SDK or upload method accepts the file. Check what the upload route accepts, and keep existing formats and error responses working. Writing results needs the QA engineer role or higher, whatever the credential.

A new live reporter should follow the shared adapter rules. Missing configuration turns the reporter off with one warning. Network errors never fail the test run.

Add an agent or tool

An agent is an automated helper that investigates or acts inside TestLookup. A new agent, tool or model capability needs all of these:

Workflow stages are listed in backend/app/services/agent_capability_registry.py. The agents.capability-has-executor quality-gate check keeps that list in step with the stage lists.

Test these cases: providers that aren’t available, refused tools, running out of time or budget, and losing a lease on a task. Also test cancellation, badly formed output and a predictable final report.

Keep drafts, findings, evidence, review decisions and outside actions separate. Optional model behavior needs a path for when the model is offline or unavailable, and users must be able to see that path.

Agents that propose changes work in three modes, which a QA lead sets for each project:

Only three action types can run:

Clients and the UI

Update everything that uses the contract:

Keep the credential kind, scopes, project context, streaming protocol, retry behavior and version alignment intact. When permissions are involved, add a test for a wrong scope or out-of-date state.

Discuss changes to the MCP tool list before you make them. The MCP server accepts only JWT access tokens, not API keys.

The development guide on GitHub has the route-to-UI exercise and the extension checklist.

Database changes

A storage change needs an Alembic migration, updated ORM models and serializers, a forward-compatibility review, and a rollback or recovery plan. Think about:

Discuss schema migrations before you build them. This command generates a revision inside the backend container, for you to review and edit:

Terminal window
make migrate-create MSG="..."

Stage the new migration in Git before you regenerate the references. The migration list is read from git ls-files.

If the change touches MongoDB, file storage, Redis or derived indexes, document how they’re updated and recovered too. A relational migration doesn’t make an operation across several stores all-or-nothing.

Decide what project export includes

Project export includes run history as well as settings and the test catalog. So every new table, run-scoped collection or kind of stored object needs a clear export decision. Tests name anything left unclassified, and they keep the import free of side effects.

Tests, docs and compatibility

Add focused behavior tests and tests for refused access. Then run the wider package, integration, architecture and deployment checks that match your change, as Testing and quality gates describes.

When a contract changes, regenerate the references and update the client examples and user documentation. Review the generated diff rather than accepting it as it is.

Terminal window
python scripts/generate_reference.py

The pull request template also asks for:

The documentation lives in three places:

Say how the change stays compatible, and how feature flags affect it. Keep old consumers working, or document how to move them over. Don’t rely on a source-text guard alone to prove behavior.

Use the full codebase map.