On this page

Contributing and development

Four contribution paths: ship a module, report a bug, improve this manual, or work on the platform.

Contribution paths#

PathStart with
Ship a module — the highest-impact contributionYour first module, then the author checklist. Your citation travels with the manifest, so users always see whose method they are running.
Report a bug or request a featuregithub.com/Process-Science-Community/MATE/issues. Attach the diagnostics blob from Settings → About, plus the steps and the expected result. A minimal reproduction beats a long description.
Improve this documentationEdit the markdown under landing/docs/content/, run make docs, open a pull request. The authoring syntax is documented in landing/docs/README.md.
Work on the platformHow MATE works for the mechanisms, then the setup below.

Toolchains#

ToolVersionUsed for
Python3.12 (pinned by .python-version)API, Python SDK, module backends
uvcurrentDependency resolution and virtual environments
Node.js + pnpm20+ / currentWeb app, TypeScript SDK, docs build
Docker + Compose v2currentThe full stack
JDK 17+optionalJVM module SDK and its conformance tests
First run
git clone https://github.com/Process-Science-Community/MATE.git mate
cd mate
make install       # uv sync --extra dev + pnpm install
make dev           # alembic upgrade head, then uvicorn --reload and next dev

make dev runs a preflight that frees port 8000 and clears stale processes, applies migrations, then starts both servers. A host API defaults to SQLite under data/.

Development loop#

TaskCommand
Both servers with reloadmake dev (or make dev-api, make dev-web)
Both servers in containers with reloadmake up-dev
API testsmake test
One testuv run --extra dev pytest apps/api/tests/test_x.py::test_y -v
One module's testsuv run pytest modules/<folder>/tests
Python type checkuv run pyright (strict)
Web type checkmake typecheck
Format Pythonmake fmt
Regenerate API typesmake codegen (API on :8000)
Rebuild this manualmake docs
Wipe local statemake clean (irrevocable)

Migrations#

Adding a migration
cd apps/api && uv run alembic revision -m "add watched folder retry counter"
# edit apps/api/alembic/versions/<rev>.py — additive only
# make dev applies it on boot

Never edit a migration that has been applied anywhere, keep DDL additive (add nullable columns, backfill, then tighten), and remember that rolling back code does not roll back the schema.

Testing approach#

LayerApproach
Routeshttpx.ASGITransport against the app, with a scoped SQLite database per session.
ModulesThe real loader with fixture module folders, plus Protocol-faithful fakes for unit tests.
IsolationConformance tests that run the same expectations against Python and JVM workers.
AI and MCPTests that assert the data wall by attempting to read rows through an AI-scoped context.
StorageQuota, eviction, migration, and snapshot tests against a fake S3 layer.

Two testing conventions: name each test as an expectation (test_returns_404_for_another_users_log), and write the failing test before fixing a bug.

Enforced conventions#

ConventionWhy
Modules never import platform internalsThe SDK is the contract; anything else breaks on upgrade.
Bus events carry user_idServer-side fan-out filters on it; omitting it leaks events.
Analytics routes avoid trigger words (/usage, /sync, /insights)Ad blockers break otherwise working pages.
Mutations to existing resources are optimistic in the web appSnapshot, write the expected state, roll back on error, reconcile on settle.
Account-scoped flags are server state, not localStorageThey must follow the account across browsers.
Module frontends import only declared externalsAnything else breaks the esbuild bundle.
Code comments cite the design document by section (INSTRUCTIONS.md §5.4)The reason stays one hop from the mechanism.

Pull requests#

  • The suite passes: make test, uv run pyright, make typecheck.
  • New behaviour has a test that would fail without it.
  • Route or schema changes are followed by make codegen, with the regenerated types committed.
  • Documentation that is now wrong is fixed in the same pull request.
  • The description states the problem first, not the files touched.

Design documents#

The manual explains how to use and extend MATE; these explain why it is built the way it is.

DocumentContents
docs/INSTRUCTIONS.mdThe platform specification: principles, tech stack, storage strategy, the module system (§5), API surface (§6), frontend (§7), jobs and progress (§8).
docs/DEPLOY.mdThe production runbook in full: proxy chain, secrets and realm, resource limits, verification, MCP enablement.
docs/MCP.mdThe MCP consumer reference in depth.
docs/S3_OFFLOAD.mdThe S3 design: cache and eviction, migration and quota, the still-open multi-node seams.
modules/PROTOCOL.md · modules/SIDECAR_SERVICES.mdThe worker wire protocol, and the contract for modules with their own server.
docs/README.mdThe index of every document in the repository.

A decision that a reader would otherwise have to reverse-engineer belongs in a document: record the rationale there, cite it from the code that implements it, and update this manual in the same pull request.

Specified but unimplemented#

Documenting them prevents conflicting implementations: Node and R runtimes for modules (the protocol needs no host change), git-URL and registry module installs (today the only channel is an uploaded archive), multi-node deployments (the S3 layer is the groundwork, and the open seams are named in S3_OFFLOAD.md), and additional dataset shapes (the envelope is shape-tagged, so new shapes are additive).

Deliberately out of scope: a multi-tenant SaaS, a plugin marketplace with ranking, anything that requires a managed cloud service, and replacing the analyst — modules produce results and explanations; interpretation stays with people.