A+BGet involved

Contributing

One maintainer, many agent workers, and a short list of rules that keeps their changes coherent. Adapted from CONTRIBUTING.md, which still calls the project by its repository name, music-dj-tools: setting up and testing, then landing a change.

Public source No public pull request or issue inbox at launch. The source opens as a public mirror of the repository once its go-public content check passes; the source link appears after the public mirror is verified. GitHub issues will be off on the mirror, so the steps below describe the process inside the private repository: do not open a pull request on the mirror until this box names a route. Until then, hello@open-dj.com works once its forwarding is verified (Press).
ADeck A / Set up and test

One verified path.

You need macOS, git, just and uv. uv fetches the pinned Python for you. The frontend needs Node.js 22.14 or newer and pnpm only.

set upCONTRIBUTING.md
# After the public mirror opens, clone it with:
git clone <public repository URL> opendj
cd opendj
uv sync --frozen --extra dev --python 3.11.15

corepack enable
cd apps/webui/frontend
pnpm install --frozen-lockfile
run only what you changedCONTRIBUTING.md
uv run pytest tests/<area> -n 4   # backend, scoped
cd apps/webui/frontend
pnpm test:unit                    # frontend unit tests
pnpm check                        # svelte-check (types)
make lint LINT_PATHS="path/to/file.py"

Fixtures you may not have

The rekordbox and USB-export fixtures live on an external fixture host most contributors do not have. A test that needs one fails loudly when the host is unavailable, so a missing fixture never reads as a green run. If you knowingly lack the host, set MDT_ALLOW_MISSING_FIXTURES=1 and those tests skip instead. A fixture that is present but stale or corrupt still fails.

Lint and heavy packages

Lint reports an absolute count that is not zero today; the gate fails only when the count grows. Do not reformat files you did not otherwise change. Heavy machine-learning packages such as torch and demucs never enter the repository environment; they run from standalone scripts under uv run.

BDeck B / Land a change

Inside the private repository, every change is a pull request.

Nothing lands on main directly, not even a one-line docs fix. Branch, keep the diff to one logical change, run the scoped tests, and describe in plain language what changed, why, and how you checked it. Inside the private repository, changes merge once required checks pass and review threads are resolved, and agents merge their own. The public mirror has no route for outside pull requests yet; the Public source box above names one when it exists. Until then you can read and run the code, and report a security problem through the route on the Security page.

branches and commitsCONTRIBUTING.md
feat/<slug>  fix/<slug>  docs/<slug>
chore/<slug>  refactor/<slug>  test/<slug>

# Conventional Commits, signed off (DCO)
git commit -s -m "feat(<scope>): <summary>"

Developer Certificate of Origin

Sign off every commit with -s (the Developer Certificate of Origin); the pull request template asks for it, and no check enforces it yet. The flag certifies that you wrote the patch or otherwise have the right to pass it on as an open-source patch (developercertificate.org). By contributing you agree your contribution is licensed under Apache-2.0; do not add GPL-licensed code to the tree.

A larger change

Propose it first with one paragraph of scope, the safety rails it touches, the test fixtures it needs, and a rough exit criterion. Where proposals go is named in the Public source box once a public route exists.

House rules.

The most common reason a pull request is sent back.

Nothing is mocked

A control with no real data source renders inert rather than showing invented data, and code fails loudly instead of falling back silently.

Six rails on every write

The rule: any code path that writes to rekordbox, djay, Serato, Traktor or a user's files must go through the six rails in the README's Safety section. Today apps/sync/safety.py and the rekordbox and djay writers implement the rails (that module lists its own seven, see Security); the Traktor writer has only a dry run and two flags, and is the open gap. A new writer without a reversal script will not be merged.

Fixture-first tests

Anything that reads a real library gets a tiny deterministic fixture under tests/fixtures/. Tests that reach into someone's actual library are not acceptable.

Secrets stay out of the tree

Credentials come from environment variables injected at run time. Never commit a .env file or a key.

Plain English

Short sentences in docs, commit messages and comments, with American spelling: color, analyze, behavior, license.

Apache-2.0, no relicensing

Do not add GPL source to the tree. A GPL package may only be a runtime dependency installed separately, noted in NOTICE; mutagen, an optional extra, is the worked example.

A+BConduct

Code of conduct.

The project follows the Contributor Covenant (CODE_OF_CONDUCT.md). Abusive, harassing or otherwise unacceptable behavior may be reported privately to the people responsible for enforcement, by contacting the repository owner through their GitHub profile, or, after the public mirror is verified, through its Security tab (Report a vulnerability). Every complaint is reviewed, and the privacy and security of the reporter are respected.

A / Parity
Beyond / B { type: 'crossfader', value: 0.50 }