Skip to content
Kodakodadocs
Contributing

Submitting changes

Commits, pull requests, and review.

Koda's contribution model is plain GitHub: fork, branch, pull request. The bar is clarity — commits should read well, PRs should explain what they change and why, and CI should be green before review.

Before you start

  • Check open issues and pull requests for prior art.
  • For non-trivial changes, open a discussion or draft issue first. It's cheaper to align on approach before code than after.
  • Read CONTRIBUTING.md in the repo — it's short and authoritative.

Branches

  • Branch from main. Main always reflects the latest merged state.
  • Naming. Prefix with a short type plus a slug: feat/memory-recall-timeout, fix/session-cookie-samesite, docs/skills-authoring.
  • Keep branches short. Rebase on main regularly. A branch that lives longer than a week usually has diverged more than it gains.

Commits

  • Imperative, present-tense subjects — "Fix X" beats "Fixed X" beats "X is fixed".
  • One logical change per commit. The commit is a unit of review; mixing unrelated changes makes git log harder to read in six months.
  • Body explains why, not what — the diff already shows what changed. If the why is obvious, skip the body.

Pull requests

Description

The PR description should cover:

  • What — a concrete summary of the change. Two or three sentences is usually enough.
  • Why — the motivation, linked to an issue or discussion if one exists.
  • How to verify — steps a reviewer can follow to convince themselves the change works.
  • Risk — anything the change could break, or that operators should know about.

Scope

Keep PRs focused. A PR that changes one thing is easier to review, merge, and — if needed — revert. Mechanical refactors and the behavioural change they enable belong in separate PRs whenever possible.

Size

No hard cap, but anything over ~500 net-lines-changed benefits from being split. If a large change can't be split, pre-announce it in an issue so reviewers have context before opening the diff.

Local checks before opening

Run the full suite so the reviewer isn't the first to hit failures:

bash
# Backend
ruff check .
ruff format --check .
mypy koda/ --ignore-missing-imports
pytest --cov=koda --cov-report=term-missing
# Web
pnpm lint
pnpm typecheck
pnpm test
Pre-push hook
A pre-push hook that runs ruff check, mypy, and the web typecheck catches 80% of CI failures before you push. The repo ships an opt-in sample you can enable with git config core.hooksPath scripts/hooks.

Tests

  • Every behavioural change needs a test — preferably at the layer the change lives (unit where possible, integration where necessary).
  • Regressions take a test. Fixing a bug without a test lets the bug recur silently.
  • Memory, knowledge, and runtime each have their own test subdirectories — follow the existing pattern rather than mixing.

Documentation

If your change alters user-visible behaviour, update the docs in the same PR. User-facing docs live in docs/; contributor- facing notes live in docs/ai/. The README is for headline claims — update it when your change materially shifts one of them.

Review

  • Expect feedback. Reviews are a conversation, not a gate. Be prepared to iterate.
  • Push updates as additional commits during review; squash only on the final merge. It makes the review diff easy to follow.
  • Thank the reviewer. Review is work too.

Merging

Maintainers use squash-merge onto main by default. The final commit message is the PR title + a summary of the body, so keep both tidy.

Security-sensitive changes

If you're fixing a security issue, follow the disclosure process in SECURITY.md. Don't open a public PR with the fix before the disclosure window closes.

Next steps