# G15 tools: Debian 13 development and packages This outer repository builds and packages four pinned Git submodules: `libg15`, `libg15render`, `g15daemon`, and `g15macro`. A fifth submodule, `g15stats`, is present but is not integrated into the build or packaging pipeline. Initialize a fresh clone with `git submodule update --init --recursive`. Builds reject missing, dirty, or misaligned submodules; they export committed, unpatched Debian sources and never modify submodule working trees or refs. ## Build and verify release packages Create an empty directory outside the checkout (for example with `mktemp -d`) and run `bash packaging/run.sh /absolute/path/to/that-directory`. The runner uses disposable Debian 13 Docker containers to build all four projects in dependency order, install their own development packages before downstream builds, test distro replacement, and rebuild all four source packages without the checkout mounted. It mounts only an allowlist of build inputs; `.vscode` is not exposed to release build containers. Outputs include eight binary packages, debug symbols, four standalone Debian source packages, build metadata, submodule provenance and checksums. See `packaging/NOTES.md` for versions, overlays, QA and release behavior. The old outer `git archive` ZIP is not a source distribution: it omits submodule content. Use the verified Debian source artifacts instead. **Safety limitation:** legacy macro memory/configuration handling has known preexisting defects. Compatibility overlays do not repair the macro engine. Do not run it as root or use untrusted configuration. Build and install tests are not hardware or security certification; see `packaging/overlays/v1/README.md`. ## Recommended: Debian 13 container and packages Use local Linux Docker Engine with Compose and the Dev Containers CLI (or VS Code's Reopen in Container). From the repository root, run `devcontainer up --workspace-folder .`, then `devcontainer exec --workspace-folder . bash`. The container reuses `packaging/Dockerfile` (Debian 13/trixie), with GCC, Make, Autotools, Debian packaging tools, libusb-1.0, FreeType and XTest headers. The image does not preinstall distro G15 development libraries: package builds install the versions built from the submodules. Its normal packaging command is replaced with `sleep infinity`. No host package installation is needed beyond your existing container tooling. For distributable packages, follow `packaging/NOTES.md` using its disposable build container, not the development shell: the packaging scripts install their outputs. Initialization regenerates ignored `.devcontainer/compose.usb.yaml`, including only existing exact USB character nodes for Logitech `046d` keyboards `c222`, `c225`, `c227`, `c22b`, `c22d`, `c22e`. No keyboard is required for build-only use. Speakers and gamepanels are excluded. Remote SSH/TCP Docker endpoints and Docker Desktop are rejected; use a native local Linux daemon whose USB paths match this host (do not use a forwarded Unix socket). After reconnecting a keyboard, recreate the container with `devcontainer up --workspace-folder . --remove-existing-container` to refresh device mappings. A device disappearing during startup may require retrying. There are no whole-USB mounts, wildcard device rules, privileged mode, Docker socket mounts, or host networking. `/dev/uinput` is deliberately omitted: host input injection does not work by default. If needed, manually configure only that device and host permissions after reviewing the security implications. Rootless Docker/device permissions may further limit hardware access. Building and container checks do not establish keyboard functionality; do not run a second daemon against a keyboard already owned by a host service. Run `bash .devcontainer/test.sh` with local Linux Docker Engine, Compose, the installed Dev Containers CLI and host Node.js. It runs real CLI `up` and `exec` with the absolute checkout path, then checks `docker inspect` against the current host sysfs allowlist and rejects unexpected devices, mounts, device cgroup overrides, privileged mode and host networking. It also checks that `/dev/uinput` is absent. No keyboard is required; an empty allowlist must produce no device mappings. The container is left running for development. If USB devices changed, recreate the container as described above and rerun. These configuration checks perform no keyboard I/O, USB driver changes or keyboard functional validation. See `packaging/NOTES.md` for release test coverage and safety limitations.