# Contributing Public product name is **Oneirodex**. Defaults that are already decided live in [docs/dev/agent-locks.md](docs/dev/agent-locks.md) — do not re-ask them. ## Repo layout | Path | What | | --------------------- | ----------------------- | | `oneirodex/` | Flask app | | `frontend/member-app` | Household SPA | | `frontend/admin-app` | Admin SPA | | `frontend/ops-glance` | Ops widgets | | `frontend/api-client` | `@oneirodex/api-client` | | `frontend/shared` | `@oneirodex/ui` | | `clients/desktop` | Tauri companion | | `tests/` | pytest | | `docs/` | [index](docs/README.md) | ## Running things Servers start through `startweb.sh` / `startweb_windows.cmd` — never `python asgi.py` directly ([ADR 0006](docs/adr/0006-asgi-bridge-a2wsgi.md)). ```bash # Frontend (from a SPA directory, or via the repo-root workspace) npm test -- --run # vitest, scoped to one file where you can npm run typecheck npm run lint && npm run format:check # both — Prettier fails CI on its own # Python — the database name MUST contain `test` (conftest hard-fails otherwise) python -m pytest tests/test_whatever.py ``` The test database is the container **`oneirodex-review-db`**. `docker start oneirodex-review-db` if it is stopped; if it does not exist at all, `docker compose -f docker-compose.review.yml up -d db` and create `oneirodextest` — [local-postgres-pytest.md](docs/runbooks/local-postgres-pytest.md). A pytest run that produces no output for minutes is a refused connection, not a slow suite. Full-tree pytest is **not** all-green today — **42 failed / 4,450 passed** on 2026-09-16, every one named in [test-suite-failures-2026-09-16.md](docs/dev/archive/test-suite-failures-2026-09-16.md). CI runs every test not marked `integration`, minus a named deselect list of known failures ([ci-gates.md](docs/dev/ci-gates.md)) — a new test file is gated by default. Passing CI is still not the full suite: the `integration` modules (live services, Unraid-shaped fixtures) run locally and at release. ## Ratchets — do not regress ```bash python scripts/api_envelope_lint.py # JSON sites off api_ok/api_error — 11 documented keeps python scripts/print_lint.py # print() calls — 591 python scripts/get_json_lint.py # raw request.get_json() sites — 103, migrating to @validate_body node scripts/css-token-lint.mjs # raw colour/radius/type literals — 0 node scripts/any_lint.mjs # explicit `any` in .ts/.tsx sources — 1,208 (test harness excluded) node scripts/od_btn_lint.mjs # raw