Contributing
How to set up a horus-os dev environment, run the lint and test checks, follow the commit conventions, and the hard rules every contribution must meet.
Status: open for contributions#
horus-os accepts outside contributions as of 2026-06-10. The project was open-sourced from a working private command center and spent its first weeks behind a supply-chain readiness gate (sigstore-signed releases, SBOMs, pip-audit, SHA-pinned actions, sandboxed forked-PR CI). That gate shipped, and the flow below is live.
If anything in this guide is wrong, unclear, or out of date, open an issue on GitHub.
Where to start#
- Pick an issue labeled
good-first-issueorhelp-wantedand comment to claim it. The maintainer reviews the claim and assigns the issue by adding theclaimedlabel; until that label lands, the issue is not reserved. Once assigned, open a draft PR within 7 days. - File issues for real bugs you hit running
horus-oslocally. - Open Discussions for design questions or scope proposals before writing code.
- Run the project for real and write up your experience. Real-use feedback still shapes the roadmap more than anything else.
Honest expectations#
horus-os is solo-maintained. Triage targets a weekly Sunday pass and may go quiet for up to two weeks. Every PR runs the full three-OS CI matrix before human review, and forked-PR builds run with restricted tokens that never see repository secrets. There is no CLA: Apache 2.0 inbound-equals-outbound is the only licensing requirement.
Dev setup#
Clone the repo, create a virtual environment, and install the package in editable mode with the dev extras.
git clone https://github.com/Ridou/horus-os.git
cd horus-os
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e '.[dev]'That installs the package in editable mode, plus pytest, ruff, and the optional FastAPI surface used by the dashboard tests.
To exercise the full provider stack locally, install the all extra and export your provider keys.
pip install -e '.[all]'
export ANTHROPIC_API_KEY=your-anthropic-key # optional
export GEMINI_API_KEY=your-gemini-key # optionalThe test suite does not require live API keys. Provider tests use recorded responses and adapters.
horus-os runs on Python 3.11+. CI exercises both Python 3.11 and 3.12, so develop against a version in that range.
Workflow#
- Pick or open an issue. New contributors should look for the
good-first-issueandhelp-wantedlabels. - Branch from
main. Branch names use the pattern<type>/<short-slug>, for examplefeat/streaming-responsesorfix/wizard-windows-paths. Long-lived forks of project direction are not accepted without a roadmap update first. - Make your change. Keep PRs focused. One concern per branch.
- Add at least one regression test when you can. The test directory mirrors the source layout under
tests/. - Run the local checks before pushing (see below).
- Open a PR. Fill out the template. Link the issue you are closing.
- CI must be green. The matrix runs Ubuntu, macOS, and Windows on Python 3.11 and 3.12. The
install-smokejob verifies a freshpip installworks on every supported OS. PRs that break the matrix are not merged.
Lint and format#
horus-os uses ruff as both linter and formatter. Configuration lives in pyproject.toml.
- Line length: 100, enforced by
ruff format. - Imports: ruff handles ordering via the
Irule set. - Type hints: use them on every new public function. Internal helpers can skip them if obvious.
- Paths: always
pathlib.Path, never raw string concatenation. Cross-OS regressions are caught by CI on Windows.
Run the formatter and linter before you push.
ruff check .
ruff format --check .Testing#
pytest runs from the repo root. The test directory mirrors the source layout under tests/, and code changes ship with at least one regression test when feasible.
pytestCI runs the suite as a three-OS matrix. Every change is exercised on Ubuntu, macOS, and Windows, each on Python 3.11 and Python 3.12. A separate install-smoke job verifies that a fresh pip install works on each supported OS. A PR that breaks any cell of the matrix is not merged.
Commit style#
Use conventional commits in present tense, with an optional phase prefix when the change belongs to a tracked phase.
feat(02): agent runtime supports async tool execution
fix(07): cli init handles a pre-existing config file
docs: refresh architecture diagram
test(05): cover memory read with unicode filenamesPrefixes in use: feat, fix, docs, chore, test, refactor, build, ci, perf.
Hard rules#
These rules are non-negotiable. Reviewers enforce them, and some are enforced by CI.
No em-dashes#
Do not use em-dash characters in committed prose. Use commas, periods, or hyphens instead. This applies to code comments, docs, commit messages, and any user-visible string.
No personal information#
Do not commit personal information in any file. That includes names, emails, phone numbers, IP addresses, host names, vault paths, API keys, and account identifiers. Use placeholder values like your-api-key, your-project-name, or ~/.config/horus-os/.
Apache 2.0#
Apache 2.0 applies to every contribution. By opening a PR you confirm you have the right to license the change under Apache 2.0. There is no separate Contributor License Agreement: Apache 2.0 inbound-equals-outbound is the only licensing requirement.
New files do not require a per-file license header for v0.x. The top-level LICENSE covers the whole repository.
What does not get merged#
- Personal information in committed text. See the hard rules above.
- AI provider abstractions that hide the SDK from the caller. The Anthropic and Google SDKs are first-class. Wrappers that obscure cost, latency, or capabilities are rejected.
- SaaS-only features. Optional cloud integrations are fine when opt-in. Required cloud dependencies are not.
- Em-dashes. See the hard rules above.
Scope check#
Before opening a substantial PR, read:
PROJECT.md, the project intent and out-of-scope list.ROADMAP.md, the current milestone and phases.ARCHITECTURE.md, the technical shape.
Changes that align with an open phase or a clearly stated roadmap item get reviewed fast. Changes that expand scope or fork project direction need a roadmap update first. Open an issue and propose the scope change before writing the code.
Pull requests are not the right place to negotiate scope. If a PR reveals a scope question, the review pauses until an issue captures the decision.
Where to discuss#
- Bugs and concrete proposals: GitHub issues.
- Design questions and longer-form discussion: GitHub Discussions (enabled on the repo).
- Questions, help, and casual discussion: the community Discord, where
#helpis a searchable forum. - Security reports: see the security policy.