Before touching a subsystem, read the relevant notes in contributing/: ARCHITECTURE.md,
PIPELINES.md, LOCKING.md, MIGRATIONS.md, RUNS-AND-JOBS.md, AUTOSCALING.md,
BACKENDS.md, GPUHUNT.md, PROXY.md, RUNNER-AND-SHIM.md, FRONTEND.md, DOCS.md,
DEVELOPMENT.md, RELEASE.md.
- Core Python package lives in
src/dstack; internal modules (including server) sit under_internal, API surfaces underapi, and plugin integrations underplugins. - Tests reside in
src/testsand mirror package paths; add new suites alongside the code they cover. - Frontend lives in
frontend(React/webpack) and is built intosrc/dstack/_internal/server/statics. - Docs sources are in
mkdocs/docs/with extra contributor notes incontributing/*.md.
- Install deps (editable package with extras):
uv sync --all-extras(uses.venvin repo). - Run CLI/server from source:
uv run dstack ...(e.g.,uv run dstack server --port 8000). - Lint/format:
uv run ruff check .anduv run ruff format .. - Type check:
uv run pyright -p .. - Test suite:
uv run pytest. - Frontend: from
frontend/runnpm install,npm run build, then copyfrontend/buildintosrc/dstack/_internal/server/statics/; for dev,npm run startwith API on port 8000.
- Python targets 3.10+ with 4-space indentation and max line length of 99 (see
pyproject.toml;E501is ignored but keep lines readable). - Imports are sorted via Ruff’s isort settings (
dstacktreated as first-party). - Keep primary/public functions before local helper functions in a module section.
- Roughly keep function definitions in the order they are referenced within a file so call flow stays easy to follow.
- Prefer early returns over nested
if/elseblocks when they make the control flow simpler. - Keep private classes, exceptions, and similar implementation-specific types close to the private functions that use them unless they are shared more broadly in the module.
- Prefer pydantic-style models in
core/models. - Document attributes when the note adds behavior, compatibility, or semantic context that is not obvious from the name and type. Use attribute docstrings without leading newline.
- Tests use
test_*.pymodules andtest_*functions; fixtures live near usage. - Never make network calls inside a DB session or transaction. Fetch what you need before opening the session, or commit and close it before the call.
- Don't use function-level (inner) imports to break circular imports. Inject the dependency or move the shared code to a lower-level module instead.
- Never edit a migration that has already been applied or released; add a new migration instead.
- Default to
uv run pytest. Use markers fromtests/conftest.pylike--runpostgresif need to include specific tests. - Scope the run to the change: for trivial or localized edits, run only the affected test modules,
Test*classes, or-kselection instead of the whole suite. Reserve the full suite for broad or cross-cutting changes. - Speed up large runs with
-n auto(pytest-xdist), e.g.uv run pytest -n auto. - Group tests for the same unit (function/class) using
Test*classes that mirror unit's name. - Keep tests hermetic (network disabled except localhost per
pytest.ini); stub cloud calls with mocks.
- Name branches
issue_{issue_num}_{title}when the work tracks an issue (e.g.issue_3959_replicated_alb_gateways), andpr_{title}otherwise. - Commit messages follow the existing style: short, imperative summaries (e.g., “Fix exclude_not_available ignored”); include rationale in the body if needed.
- For PRs, describe behavior changes and link related issues.
- Include screenshots or terminal output when touching UX/CLI messages or frontend flows.
- Always disclose AI Assistance in PRs.