docs/book/src/contributing/how-to.md
We accept code, docs, bug reports, and feedback from anyone willing to file them clearly. This page covers the mechanics: how to get a change in, what we look for in review, and what to expect after you open a PR.
See Communication for non-code contributions (reporting issues, feedback, getting help).
See RFC process for larger changes that need design discussion before implementation.
For anything larger than a typo fix:
AGENTS.md. The repo's root AGENTS.md is the canonical source of convention: risk tiers, PR discipline, anti-patterns, and review standards live there.master. Fork the repo and branch from there; there's no develop/integration branch to go through.fork → branch → commit → push → open PR → review → merge (squash)
The key checkpoints:
.github/pull_request_template.md. Fill it out. The summary, testing evidence, and compatibility sections are non-negotiable.ci.yml is the composite gate; all legs must pass.cargo fmt clean (checked in CI)cargo clippy -D warnings clean (checked in CI)#[allow(dead_code)]; reserve underscore names for required but intentionally unused API, trait, or callback parameters.anyhow::Result at binary boundaries, typed errors in library crates. No unwrap() / expect() in production code paths: propagate with ? or document the invariant that makes panic impossible.zeroclaw-api, then implement in the right edge crate#[cfg(test)] mod tests {} at the bottom of the file or a sibling tests.rsmod tests)tests/ and crate-local unit tests: run via cargo nextest run --locked --workspace --exclude zeroclaw-desktopFor the full five-level taxonomy (unit / component / integration / system / live), shared mock infrastructure, and JSON trace fixture format, see Testing.
docs/book/src/**/*.md (this mdBook)///) changes update the API reference automatically on deploydocs/book/src/reference/cli.md, config.md) are generated; don't hand-edit. Run cargo mdbook refs and commit the output.po churn; use the standard PR-body note in Building the docs locally.cargo mdbook sync, commit the resulting .po files, and validate them with cargo mdbook checkWhen you publish a blog post or otherwise update the public blog metadata, update the hand-maintained feed timestamps in the same PR:
web/public/blog/rss.xml: set <lastBuildDate> to the latest post publish time in RFC 2822 / GMT formatweb/public/blog/atom.xml: set <updated> to the latest post publish time in ISO 8601 UTC formatweb/public/sitemap.xml: set the /blog entry's <lastmod> to the latest publish dateKeep feed discovery environment-local:
web/index.html should keep /blog/rss.xml, /blog/atom.xml, and /sitemap.xml as root-relative linksweb/public/sitemap.xml should list the human-facing /blog page, not the XML feed filesConventional Commits:
feat(providers): add support for DeepSeek reasoning mode
fix(channels/matrix): prevent duplicate device sessions after verify
docs(getting-started): add YOLO-mode quick-start
refactor(runtime): split agent loop into steps
chore: bump tokio to 1.43
AI-assisted collaboration is welcome, but do not add bot/AI attribution trailers or generated tool footers to PR bodies or commit-message tails. Human Co-authored-by: trailers remain appropriate for incorporated contributor work when they follow the superseding and privacy rules. See FND-005 (Contribution Culture) for the full norm.
Title mirrors the squash commit:
feat(scope): short description
Body uses the PR template. The testing section is required: explain how the change was checked, and paste the checks that match the change. The reviewer-run A/B recipe under How you can test is only needed when manual verification adds useful signal; mark it N/A for docs-only, pure-refactor, or trivial changes without a meaningful reviewer test path. For docs-only PRs, use scripts/ci/docs_quality_gate.sh and scripts/ci/docs_links_gate.sh or explain why link checking had no added links to inspect. For Rust/code PRs, use the evidence that matches the changed surface: required CI checks, focused crate or regression tests, manual smoke, or full workspace checks when broad coverage proves something narrower evidence would miss. Fresh required CI is enough when it covers the changed surface; extra local Cargo is not required just to duplicate the same head, target, and feature set. Add more evidence when the PR depends on a known CI coverage gap: platform-specific tests, cross-platform lint, desktop app coverage, release target builds, stale CI, or unavailable CI. "It works on my machine" is not evidence.
Risk labels:
risk:low: rollback is a revert; no user action neededrisk:medium: users may need to update config / env / CLI usage; rollback plan requiredrisk:high: security-critical, schema changes, breaking behaviour. Rollback plan, feature flag, and observable failure symptoms requiredMerge strategy: squash-merge with the full commit history preserved in the body. See .claude/skills/squash-merge/SKILL.md for the exact format: TL;DR: PR title + (#number) as the subject, bullet list of original commits as the body.
Release: changes land on master; master does not auto-release. A maintainer bumps the version and tags vX.Y.Z when a release ships. You'll see your PR in the CHANGELOG.
| Area | Where to start |
|---|---|
| New channel | crates/zeroclaw-channels/: copy an existing channel of similar shape |
| New provider | crates/zeroclaw-providers/: compatible.rs covers most OpenAI-like ones |
| Docs | docs/book/src/: anything marked outdated or missing |
| Translations | cargo fluent fill --locale <code>: see Maintainers → Docs & Translations |
| Hardware | crates/zeroclaw-hardware/: new board support, new sensor drivers |
Don't be a jerk. Disagree on ideas; not people. Accept that maintainers will close things they don't want to own, usually with an explanation, occasionally without. If a close feels unjustified, ask; if the ask goes nowhere, move on.