# Contributing to geniex Thanks for your interest in contributing! Whether you're fixing a typo, adding a backend, or landing a new feature, this guide takes you from `git clone` to a merged PR. The same rules apply to external and internal contributors — this is the single source of truth. The commit and PR rules are **SemVer-driven**: they must encode enough information for [`/release`](.claude/commands/release.md) (and future automation) to derive the next version tag deterministically. The full tag procedure lives in [notes/release.md](notes/release.md). ## Getting started Prerequisites: - **[Bazelisk](https://github.com/bazelbuild/bazelisk)** — builds the Go CLI and fetches all CLI-side dependencies. The Bazel version is pinned in [.bazelversion](.bazelversion). Install: `winget install --id Bazel.Bazelisk` (Windows) or `bazelisk` from your package manager (Linux). - **CMake** — builds the SDK bridge and native plugins via presets in [sdk/CMakePresets.json](sdk/CMakePresets.json). - **Docker** — the Linux and Android SDK builds run inside prebuilt toolchain images (`qualcomm/geniex-toolchain-linux`, `qualcomm/geniex-toolchain-android`). A full Windows Snapdragon build additionally needs the Hexagon SDK, OpenCL SDK, and Windows Driver Kit. Clone with submodules — the SDK vendors `third-party/llama.cpp` and `third-party/geniex-qairt`: ```bash git clone --recursive https://github.com/qualcomm/GenieX.git ``` > [!IMPORTANT] > **Build the SDK before the CLI.** In the default local-SDK mode the CLI links against `sdk/pkg-geniex/`, which must already exist. Full per-platform build commands (Windows ARM64, Linux, Android) live in [notes/build.md](notes/build.md); Python bindings in [bindings/python/README.md](bindings/python/README.md). ## Running tests - **Go / CLI** — run via coverage rather than plain `test` (every package ships a placeholder test to stay in the coverage denominator): ```bash bazelisk coverage //... --combined_report=lcov ``` The [`coverage`](.claude/skills/coverage/SKILL.md) skill wraps this and renders HTML. - **SDK / plugins (Python)** — end-to-end pytest suite driven through the public binding. Model-free checks run anywhere; model and device cells need Snapdragon hardware (see [tests/README.md](tests/README.md)): ```bash pytest tests -m api # model-free, runs anywhere pytest tests -m "api or (llama_cpp and device_cpu)" # adds llama_cpp CPU cells GENIEX_DEVICE_TEST=1 pytest tests # full matrix, Snapdragon only ``` CI runs only the model-free shard on GitHub runners; the device matrix runs on real QDC hardware via [pr-check.yml](.github/workflows/pr-check.yml). ## Project structure | Directory | Contents | |------------------|--------------------------------------------------------------------------------| | [sdk/](sdk/) | Native C-ABI core (`include/geniex.h`), backend plugins (`llama_cpp`, `qairt`), Rust model-manager, benchmark. | | [cli/](cli/) | Go CLI (`cmd/`, `internal/`, `server/`, `release/`), built with Bazel. | | [bindings/](bindings/) | Language bindings: `android/`, `go/`, `python/`, `python-llama-cpp/`, `python-qairt/`. | | [docs/](docs/) | Documentation site (Mintlify). | | [examples/](examples/) | Sample usage (`android/`, `python/`). | | [tests/](tests/) | SDK/plugin pytest suite + Go CLI black-box tests + QDC device harness. | | [scripts/](scripts/) | Bazel helper rules. | | [third-party/](third-party/) | Vendored `llama.cpp` and `geniex-qairt` submodules. | | [notes/](notes/) | Developer playbooks (build, run, release, bench, AI). | ## Making a change ### Branches Format: `/`. Base branch is `main`. | Type | Use for | Example | |-----------|--------------------------------------------|-----------------------------| | `feat` | New feature work. | `feat/ccache-sdk-build` | | `fix` | Non-urgent bug fix targeting main. | `fix/windows-dll-directory` | | `hotfix` | Urgent fix for a shipped release. | `hotfix/signing-regression` | | `chore` | Tooling, deps, infra. | `chore/claude-framework` | | `docs` | Documentation only. | `docs/release-procedure` | | `ci` | CI config only. | `ci/add-windows-runner` | | `release` | Long-lived release-prep branches (rare). | `release/0.5` | Personal dev branches like `perry/dev/` are allowed for shared WIP. Tag policy (which channels may be cut from which branches) lives in [notes/release.md](notes/release.md). ### Commits — Conventional Commits ``` ()[!]: # optional; only when the "why" is non-obvious