Reference

Testing and quality gates

Pick the tests that match what your change could break, run them locally, and run the full pre-push check before you open a pull request. A passing unit test suite doesn't prove that queues, outside services or AI models work.

Contribute

Running the tests

Start with the smallest test that covers your change. Widen it when the change affects other parts of the system. The testing guide on GitHub gives these commands:

AreaWhere the tests liveCommand
Backend unit and regressionbackend/testsFrom backend: python -m pytest tests -m 'not integration and not live'
Frontend unitNext to the code under frontend/srcFrom frontend: npm test
Frontend types and buildfrontendFrom frontend: npm run type-check, then npm run build
Browser journeysfrontend/tests (Playwright)From frontend: npm run test:e2e:ci
CLIcli/testspython -m pytest cli/tests, with the CLI installed
MCP servermcp/testspython -m pytest mcp/tests, with the MCP dependencies installed
Client SDKsclient/tests and each language packagePython pytest, plus each language’s own build and test steps

The Makefile also has shortcuts:

Terminal window
make test-backend
make test-frontend
make test-e2e
make lint
make type-check

Run each package’s tests in an environment with its real dependencies. Run the CLI, SDK, MCP and backend suites separately, so that their Python import paths don’t clash.

Before you push, the contribution policy asks you to run the full pre-push check:

Terminal window
make push-check # runs what CI runs
make push-check-list # prints the full list of checks
make install-hooks # makes the full check run on every git push

The pre-push check runs what CI runs, including checks that live outside the test suites:

A full run takes about 30 minutes. The hook installer sets Git’s core.hooksPath to the tracked hooks folder, so the full check runs on every push.

Pushes that change only documentation skip the check, as CI does. “Only documentation” means the files in the CI workflow’s paths-ignore list:

A Markdown edit inside the architecture or docs folders still runs everything. To force the full check anyway, run python scripts/push_check.py --full. The quick check, make push-check-quick, is a faster but weaker first pass. Passing it doesn’t predict CI.

A few local results differ from CI on purpose:

Details: the quality gate script is scripts/quality_gate.py, and the hooks folder is .githooks/.

Run the guard checks on their own

The Makefile also runs the project-wide guard checks on their own:

CommandWhat it does
make quality-gateRuns scripts/quality_gate.py
make quality-gate-listPrints every guard with a one-line description
make quality-gate-testRuns the guard script’s own tests
make quality-gate-update-baselineSaves the current results as the ratchet’s new reference point, for a reviewed commit
make verify-ops-scriptsLints and unit-tests the backup, restore and upgrade scripts, with no running services

In the frontend folder, these are the checks CI runs:

CommandWhat it does
npm run check:bundleChecks the bundle size
npm run check:themeChecks the theme tokens
npm run test:visualCompares charts against the committed Linux reference images
npm run test:visual:updateRewrites those reference images. Review every changed image before you commit it.

Documentation generation

The generated references live under docs/reference. They cover the OpenAPI document, the endpoint index, one page per API area, the schema catalogue, the data dictionary, settings, migrations and worker tasks. They’re built from the tracked code, without starting any service.

From the repository root, run the same three steps as CI’s backend job:

Terminal window
python scripts/generate_reference.py --check
python scripts/check_reference_docs.py
python -m pytest scripts/test_reference_docs.py -q -p no:cacheprovider

CI checks Mermaid diagrams in a separate job.

The reference generator and the documentation checker on GitHub define what they check. Review the generated diff. A clean generation doesn’t replace reading the text or testing the running app.

Unit tests and tests with real services

When no database address is set, backend pytest supplies a placeholder that points nowhere, so that imports succeed. That doesn’t create PostgreSQL, MongoDB, Redis, file storage, queues or outside providers. Read a test’s fixtures and markers before you assume it needs no services.

Use throwaway services for integration and live tests. When your change affects them, test these cases:

Say clearly whether each provider was mocked, offline or live.

For a change to live uploads, a stress script runs many live SDK sessions and WebSocket watchers at once against a throwaway local copy. It refuses any host that isn’t local. It reports how long finishing a run takes, frames per second, Redis stream depth and waits for database connections.

Details: the stress script is backend/scripts/stress_live_ingest.py.

Typed AI output, JSON repair and plans that stay fixed once made all make AI results traceable and check their shape. They don’t prove that the content is correct, or that a rerun gives exactly the same result. Recording feedback gives TestLookup something to learn from. It doesn’t show that a replacement model was trained, checked or put into use.

Existing CI gates

The CI workflow on GitHub defines these jobs:

CI also runs the Playwright browser journeys in four shards, which are parts that run in parallel. Those journeys answer API calls from fixtures. The chart visual tests run against committed Linux reference images in two shards.

Some expensive jobs for queues and large uploads run only when matching paths change. You can also start them by hand with two workflow inputs:

To see which jobs actually ran for your change, open the GitHub Actions run for your commit. Deployment and release workflows use their own credentials and environments.

Tests a fix needs

Write a test that fails without your fix before you rely on the fix. Where they apply, cover:

Architecture rules and checks on the source text help stop the code getting worse. They don’t replace tests of behavior.

For storage changes, plan the forward migration and the rollback. For queue work, test routing, which queues the workers read, retries, the dead-letter queue, cancellation and the final state. The dead-letter queue holds messages that kept failing.

For changes to the UI or a client, test the public behavior rather than the implementation details. When public behavior changes, update the generated references and the written documentation.

Evidence to attach

In your pull request, include:

Include the failing test that led to the change, and the final passing run.

For a release-level check, add proof that the workers read every queue. Also show one report going all the way through saving, analysis, review and the final report. Notes from checking an earlier commit describe that commit only.

The maintainers’ verification page lists what the documentation checks prove and what they don’t. For example, the checks don’t start the app, apply migrations, deliver a queued task or call a model. The page is in docs/maintainers/, next to the notes on documentation upkeep, the known limitations and a glossary.

Next: extend TestLookup, or review the contribution process.