Skip to content

Development

Writ edited this page Aug 5, 2026 · 2 revisions

Development

Running from source

cd coordinator
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
alembic upgrade head
python serve.py
cd frontend
npm ci
npm run dev        # Vite on :5173, proxying the API

For a local trial you may boot with insecure defaults:

ENVIRONMENT=development ALLOW_INSECURE_DEV=true

Never on anything reachable.

Tests

cd coordinator && python -m pytest -q -ra

The DB-backed fixtures bind to a throwaway SQLite file — the engine the product actually ships — so a bare checkout exercises real database code with no services running. Set DATABASE_URL to a postgresql:// URL to run them against Postgres instead.

cd doc-extract && pip install -r requirements.txt && pytest -q

Most of those importorskip their heavy dependency, so a bare checkout reports honestly on what is installed. That has a sharp edge — a suite where everything skipped still prints green — so CI sets DOC_EXTRACT_REQUIRE_DEPS=1, which turns a missing dependency into a failure. The PDF fixtures are built from raw PDF bytes with no library at all, so the core paths run either way.

cd connectors/writ-mcp && npm test

CI gates

Every one of these is a hard gate except where noted:

Job What it runs
Backend compileall, then alembic upgrade head on a fresh SQLite database
Backend (pytest) the full suite
Backend (ruff) the correctness subset: E9,F6,F7,F81,F82,B002,B006,B012
Quality + SAST bandit and pip-audit are gates; mypy is advisory
doc-extract the suite with DOC_EXTRACT_REQUIRE_DEPS=1, plus a no-telemetry check
Frontend tsc --noEmit, eslint, i18n coverage, segmented-control radii, build
Connector tests on Node 18, 20 and 22, plus a publish-tarball check

mypy is advisory because its first real run reports 541 errors across 89 of 220 files, almost all consequences of unannotated code rather than defects. A permanently-red required check trains everyone to ignore the board. The ratchet is per-module.

The custom checks

Two live in scripts/ because nothing off the shelf catches them:

check-i18n.mjs — natural-language keys degrade to English when a translation is missing, so nothing else notices. It also rejects module-level i18n.t(), which freezes a string at import time and makes a language switch a no-op for that module.

check-ui-radius.mjs — a selected pill whose radius does not match its track reads as a rectangle in a stadium. rounded-md is absent from this theme's radius scale and silently falls back to Tailwind's 6px, so the mistake is individually plausible on every line it appears.

Conventions

  • Every user-facing string goes through t(), with fr and es added in the same change. CI fails otherwise.
  • vite build does not type-check — run tsc yourself.
  • Frontend lint is a hard gate at zero errors. ~1000 no-explicit-any warnings remain and are tracked, not gating.

Contributing

Read CONTRIBUTING.md and the Code of Conduct. Report security issues privately, never as a public issue.

Clone this wiki locally