CONTRIBUTING.md
Rama main · réplica de lectura del repositorio original.
# Contributing to OpenClaw
Welcome to the lobster tank! 🦞
## Quick Links
- **GitHub:** https://github.com/openclaw/openclaw
- **Vision:** [`VISION.md`](VISION.md)
- **Support:** https://community.openclaw.ai/
- **Discord:** https://openclaw.ai/discord?from=github-openclaw-contributing
- **X/Twitter:** [@openclaw](https://x.com/openclaw)
## Maintainers
The current OpenClaw Foundation team and Core Maintainers are listed on the
OpenClaw people page: https://www.openclaw.org/people
## How to Contribute
1. **Bugs & small fixes** → Open a PR!
2. **New features / architecture** → Start a [GitHub Issue](https://github.com/openclaw/openclaw/issues/new/choose) or ask in Discord first. Most features are not accepted and should be third party plugins instead using our plugin SDK.
3. **Refactor-only PRs** → Don't open a PR. We are not accepting refactor-only changes unless a maintainer explicitly asks for them as part of a concrete fix.
4. **Test/CI-only PRs for known `main` failures** → Don't open a PR. The Maintainer team is already tracking those failures, and PRs that only tweak tests or CI to chase them will be closed unless they are required to validate a new fix.
5. **Questions and setup help** → [Official OpenClaw support](https://community.openclaw.ai/)
## Issue, PR, and Contact Routing
Start from this routing map before creating GitHub items:
| Situation | Use | Required evidence |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Product bug, regression, crash, or behavior defect | [Bug report](https://github.com/openclaw/openclaw/issues/new?template=bug_report.yml) | Repro steps, expected vs actual behavior, version, OS, model/provider route when relevant, logs/screenshots, impact |
| Documentation bug or missing/contradictory docs | [Docs bug report](https://github.com/openclaw/openclaw/issues/new?template=docs_bug_report.yml) | Affected docs path or URL, verification steps, expected docs content, actual docs content, impact, evidence |
| New feature, architecture change, or product improvement | [Feature request](https://github.com/openclaw/openclaw/issues/new?template=feature_request.yml) or Discord first | Problem, proposed solution, alternatives, impact, examples or prior art |
| Onboarding, setup help, or general support question | [Official OpenClaw support](https://community.openclaw.ai/) | Do not open a GitHub issue unless there is a concrete product defect or docs gap |
| Security vulnerability | See [Report a Vulnerability](#report-a-vulnerability) below | Do not file public issues for private security reports |
| PR for an existing or newly filed issue | Use the [PR template](.github/pull_request_template.md) | Visible `Closes #<issue>` or `Related: #<issue>`, problem, shipped solution, user impact, validation evidence |
For agent-authored or otherwise non-trivial work, create or reuse the issue first, then open the PR against it. Bugs and very small fixes may go straight to PR, but still link existing context when it exists and fill out the PR template.
Do not guess who to tag. Let issue forms, labels/automation, and `.github/CODEOWNERS` route the work. Mention a maintainer only when an owned path or documented responsibility is directly relevant and you need a decision; otherwise rely on normal review. For coordinated change sets, ask in **#clawtributors** before opening more than the PR limit.
## PR Limits
We cap at **20 open PRs per author**. If you exceed this, the `r: too-many-prs` label is added and your PR is auto-closed. This is a hard limit.
For coordinated change sets that genuinely need more than 20 PRs, join the **#clawtributors** channel in Discord and talk to maintainers first.
## Source dependencies
Run `pnpm install --frozen-lockfile` from the workspace root. Source checkouts use
pnpm's isolated linker, which keeps dependencies in `node_modules/.pnpm` and links
them into each workspace package. On supported macOS volumes, this also lets pnpm
reuse whole-package APFS clones instead of importing every file separately.
Installation also prepares Kysely declarations from the SQL schemas in `src/state`.
The generated files live in ignored `.artifacts/kysely/`; build, typecheck,
type-aware lint, and test entrypoints refresh them automatically, including after an install with
`--ignore-scripts`. Unchanged inputs reuse the declarations without rewriting
them. `pnpm db:kysely:check` checks schema projection and generator contracts.
Sparse core, script, and root-test lint prepare only the available schemas and
retire declarations for omitted schemas. Normal source generation, verification,
and extension-boundary builds still require complete schemas.
Give each source checkout its own physical dependency installation. Tooling does
not automatically link a missing `node_modules` to another checkout. Existing
borrowed installs can still serve direct Node tooling. Normal pnpm install checks
the checkout-root `node_modules`, the explicitly configured root module directory,
and their `.pnpm` directories before reconciliation, refusing borrowed links there.
Preserve that donor and create an independently owned install instead of removing
or reinstalling through its link. Explicit hydrated module directories remain
supported when the workspace link points to the configured physical directory.
This admission check runs through `pnpm:devPreinstall`; `--ignore-scripts` skips
it. The check does not lock paths against concurrent replacement, inspect every
workspace package's dependencies, or validate every alternate pnpm directory setting.
When updating a checkout that used the hoisted layout, stop builds, tests, and
watchers using that checkout's dependencies before running the install command.
Do not change the linker while other jobs are using the same `node_modules`.
Declare dependencies in the package that imports them; root tooling and tests
must declare their own development dependencies rather than rely on hoisting.
## Before You PR
- Use **Node 24.22.1+ LTS** or **Node 26.12.1+** for source checkouts. Compatible Node 24.16.0+ on 24.x and 26.1.0+ also work with safe SQLite, but warn about missing security patches. Older Node releases can truncate SQLite TEXT reads; Node 22, 23, and 25 are unsupported. See [Node install guidance](docs/install/node.md).
- Local tests and `pnpm dev` use the pinned OpenClaw Bun fork. See [local development tools](https://docs.openclaw.ai/reference/test/local#openclaw-bun-fork) for supported platforms, automatic staging, runtime/tool overrides, and fallbacks, and [CI runtime selection](https://docs.openclaw.ai/ci/pipeline#test-runtime-selection) for CI policy.
- Test locally with your OpenClaw instance
- An explicit maintainer repair-and-land request covers internal database scheduling, admission, and lifecycle decisions. The implementer owns the design and its verification. Get separate design acceptance when changing public contracts, schemas, durability, retention, or permissions; see the [database schema review checkpoint](docs/reference/database-schemas.md#review-checkpoint-for-material-changes).
- External PRs must describe the user, product, or operational problem in **What Problem This Solves** and include useful validation in **Evidence**. Focused tests, CI results, screenshots, recordings, terminal output, live observations, redacted logs, and artifact links all count. Reviewers will inspect the code, tests, and CI; use the PR body to explain intent and make validation easy to understand.
- Follow the [PR template](.github/pull_request_template.md): lead with the plain-language problem and concrete user impact, then a brief explanation and useful evidence. Keep technical inventories in the diff or optional details, not the opening summary. Keep important risks, migrations, required actions, and evidence gaps visible; do not invent a user benefit for internal-only work.
- When ClawSweeper, Barnacle, or a maintainer asks for more context or evidence, edit the PR description instead of only replying in a new comment. Keep **What Problem This Solves**, **User Impact**, **Why This Change Was Made**, and **Evidence** current; a short comment can point reviewers to the update, but the PR body should remain the durable explanation for maintainers and bots.
- Keep PRs takeover-ready: open them from a branch maintainers can push to. For fork PRs, leave GitHub's **Allow edits by maintainers** option enabled so maintainers can finish urgent fixes or merge prep when needed. If GitHub shows **Allow edits and access to secrets by maintainers**, enable it only when that workflow/secrets access is acceptable and say so in the PR.
- Do not edit the generated `CHANGELOG.md` index or release-owned `CHANGELOG/**` entries and contribution records in normal PRs or at merge. Initial changelogs are generated at release time from merged PRs and commits; keep release-note context in PR bodies or commit messages until then. Explicit release-docs publication changes follow the [release artifact procedure](.agents/skills/openclaw-changelog-update/SKILL.md#post-release-docs-mirrors).
- Run focused tests for touched code (`pnpm test <file> --maxWorkers=1`) and targeted typecheck, lint, and format checks. Build when the change affects build output or package boundaries. Open a ready PR once required builds and focused proof pass; PR CI runs the full suite. When build capacity is unavailable, follow the [draft/CI proof policy](.agents/skills/openclaw-testing/SKILL.md#proof-policy) before publication. A draft does not waive the build.
- When adding a maintained standalone command or dynamically loaded child, keep Knip's graph aligned with the real execution path. A command invoked by a package script, workflow, Docker scenario, or documentation—or a child executed as a spawned, preloaded, or worker process entrypoint through an exact path—is an exact Knip entry (`repositoryScriptEntries` in `config/knip.config.ts` for root repository scripts). When a child is instead reached as a computed module edge from a parent, use the existing source-derived consumer projection that owns that edge, such as `config/knip-dynamic-consumers.mjs` for root scripts; do not declare the child as an independent root solely to suppress a finding or mask it with an ignore or wildcard. Run `pnpm deadcode:unused-files` on the exact candidate; `pnpm check:changed` and [ordinary PR CI](docs/ci/scope-and-routing/selection.md#pr-vs-hourly-vs-release) do not run this unused-file proof. If unrelated existing findings keep the aggregate scan red, verify and report whether your owned paths appear rather than calling the aggregate a pass.
- After PR CI fails, run `pnpm test:ci-failed <pr>` and read the failure classification. Fix new failures, use `pnpm test:ci-failed <pr> --run` until those pass locally, then push once. Do not rerun CI just to chase green or run the full local suite. Pre-existing failures follow the [failure-table landing rule](.agents/skills/openclaw-pr-maintainer/references/landing.md#red-main-and-inherited-failures).
- For iterative local commits after running equivalent targeted validation for the touched surface, `git commit --no-verify` skips commit hooks.
- For extension/plugin changes, run the fast local lane first:
- `pnpm test:extension <extension-name>`
- `pnpm test:extension --list` to see valid extension ids
- If you changed shared plugin or channel surfaces, run `pnpm test:contracts`
- For targeted shared-surface work, use `pnpm test:contracts:channels` or `pnpm test:contracts:plugins`
- These commands also cover the shared integration/smoke files that the default unit lane skips
- For broader runtime changes, select focused tests that cover the touched contracts; PR CI runs the wider lanes (`pnpm test:extensions`, `pnpm test:channels`, or `pnpm test`) before landing
- If you touched bundled-plugin boundaries in shared code, run the matching inventories:
- `node --import tsx scripts/check-src-extension-import-boundary.mts --json` for `src/**`
- `node --import tsx scripts/check-sdk-package-extension-import-boundary.mts --json` for `src/plugin-sdk/**` and `packages/**`
- `node --import tsx scripts/check-test-helper-extension-import-boundary.mts --json` for `test/helpers/**`
- Shared test helpers must use `src/test-utils/bundled-plugin-public-surface.ts` instead of repo-relative `extensions/**` imports. Keep plugin-local deep mocks inside the owning bundled plugin package.
- Local review is strongly encouraged for contributors: use autoreview or optional local ClawSweeper. Follow the [local review route](https://docs.openclaw.ai/reference/pull-request-review-flow#local-review-before-a-pr) for public setup, maintainer requirements, and review evidence. Address actionable findings before asking for review.
- Do not submit refactor-only PRs unless a maintainer explicitly requested that refactor for an active fix or deliverable.
- Do not submit test or CI-config fixes for failures already red on `main` CI. If a failure is already visible in the [main branch CI runs](https://github.com/openclaw/openclaw/actions), it's a known issue the Maintainer team is tracking, and a PR that only addresses those failures will be closed automatically. If you spot a _new_ regression not yet shown in main CI, report it as an issue first.
- Do not submit test-only PRs that just try to make known `main` CI failures pass. Test changes are acceptable when they are required to validate a new fix or cover new behavior in the same PR.
- Check that CI checks pass
- Keep PRs focused (one thing per PR; do not mix unrelated concerns)
- Describe what & why
- **Include screenshots** — one showing the problem/before, one showing the fix/after (for UI or visual changes)
- Use American English spelling and grammar in code, comments, docs, and UI strings
## Security-sensitive changes
Changes to authentication, credentials, secret handling, sandboxing, or execution
permissions receive a security-review notice with the affected files and review
guidance. A PR author with a GitHub user account and repository `maintain` or
`admin` access needs no additional security approval. Other authors need a
command comment from a user with either role:
- `/allow-security-sensitive-change` for sensitive product changes.
- `/allow-dependencies-change` for dependency changes that require approval.
Wait for the guard notice to show the current PR commit, then post the applicable
command on its own line in a new PR comment. Use only command lines in that
comment. If both guards require approval, post both commands; they can be on
separate lines in one comment. A later push requires a new comment after the
notices update. Editing an older comment does
not grant fresh approval. Deleting the comment or removing a command revokes that
command's approval. Normal GitHub **Approve** reviews and labels do not satisfy
these command requirements.
PR updates, approval comment events, and CI completion run security review
automatically. Approval comments update the review result without rerunning the
test suite. Missing approval fails the check. Automation using a GitHub user
account follows the same role checks; GitHub App bot identities do not qualify.
Open PRs targeting the same branch must have distinct head commits. GitHub shares
commit statuses across PRs, so duplicate heads block security approval. Close the
duplicate PR or push a distinct commit; security review evaluates automatically.
The human-readable [security review policy](.github/security-review-policy.yml)
lists sensitive product categories, review guidance, exclusions, and dependency
paths. Changes to that inventory require SecOps approval.
Security policy, CodeQL, and the security-review enforcement files listed in
[CODEOWNERS](.github/CODEOWNERS) require an independent
`@openclaw/openclaw-secops` approval, including on maintainer-authored PRs. A
maintainer approval of product code does not replace that code-owner requirement.
Normal project review and release-owner requirements still apply.
The existing maintainer CI bypass can override a missing command approval, but
does not bypass the separate code-owner review requirement.
See [security review checks](https://docs.openclaw.ai/ci/pipeline#security-review-checks)
for check behavior and enforcement setup.
## Local commit hook
`pnpm format` and the formatting hook share the [local development tool selector](https://docs.openclaw.ai/reference/test/local#openclaw-bun-fork).
Use `OPENCLAW_FORMAT_TOOL=oxfmt pnpm format` to force oxfmt. The linked reference
covers the pinned fork, supported platforms, overrides, fallbacks, and CI parity.
Dedicated artifact formatters are listed in the [formatter caller inventory](scripts/README.md#formatting-and-lint-selection).
Outside CI, the normal `pnpm install` setup enables the repository's pre-commit
formatting hook when `core.hooksPath` is unset. Existing hook selections, including
an explicitly empty value, are preserved. Git scopes initialization to the current
checkout. With multiple worktrees, automatic setup requires `extensions.worktreeConfig`;
otherwise Git reports a warning and installation continues without changing hook
settings. The repository owner can enable per-worktree configuration following
[Git's configuration guidance](https://git-scm.com/docs/git-worktree#_configuration_file).
The hook's optional content guard reads a private UTF-8 file selected by
the native Git setting `hooks.blockedLiteralsFile`. Keep one literal per nonempty
line in a file outside the checkout, such as
`~/.config/openclaw/blocked-literals.txt`, then configure this checkout:
```bash
git config --local hooks.blockedLiteralsFile "$HOME/.config/openclaw/blocked-literals.txt"
```
Git metadata is another safe untracked location for the private file. Never put
private rule contents in tracked files or PRs. With no setting, the content guard
is disabled and formatting runs normally; a configured empty path or missing,
unreadable, empty, or invalid file blocks the commit.
When configured, the guard checks case-sensitive literal substrings before
formatting and again after formatting restages files. Each scan checks the full
staged contents of added, modified, and type-changed files, including rename
destinations and unchanged lines within modified files. Docs, tests, generated
files, and binary files are included; no tracked file is exempt.
If the hook blocks a commit, remove the matching content and restage the reported
files. Unchanged historical files and deletions are not scanned. Submodule contents
and symlink targets are not searched. This is a local safeguard, not CI or server
enforcement: bypassing or disabling hooks also bypasses this check.
## Review Conversations Are Author-Owned
After your PR receives Barnacle, ClawSweeper, or maintainer feedback, read the [pull request review flow](https://docs.openclaw.ai/reference/pull-request-review-flow) for how to interpret rank-up moves, proof guidance, re-review requests, and review conversation follow-up.
## Control UI
The Control UI uses **Solid 2** and native primitives, not Lit or decorator-based
reactive fields. Before changing UI code, read the [Control UI guide](ui/AGENTS.md)
and the [Solid skill](.agents/skills/solid/SKILL.md) for the current patterns and
validation requirements.
## AI/Vibe-Coded PRs Welcome! 🤖
Built with Codex, Claude, or other AI tools? **Welcome!** No AI-assistance label or disclosure is required.
Please include in your PR:
- [ ] Include a concise **Evidence** section with the most useful validation. Reviewers will inspect the code, tests, and CI rather than relying on the PR body alone.
- [ ] Confirm you understand what the code does
- [ ] Follow the [local review route](https://docs.openclaw.ai/reference/pull-request-review-flow#local-review-before-a-pr), address actionable findings, and record the outcome or unavailable-tool gap
- [ ] Follow the [pull request review flow](https://docs.openclaw.ai/reference/pull-request-review-flow) after Barnacle, ClawSweeper, or maintainer feedback
AI PRs are first-class citizens here and follow the same quality and review standards as any other PR.
## Current Focus & Roadmap 🗺
We are currently prioritizing:
- **Stability**: Fixing edge cases in channel connections (WhatsApp/Telegram).
- **UX**: Improving the onboarding wizard and error messages.
- **Skills**: For skill contributions, head to [ClawHub](https://clawhub.ai/) — the community hub for OpenClaw skills.
- **Performance**: Optimizing token usage and compaction logic.
Check the [GitHub Issues](https://github.com/openclaw/openclaw/issues) for
["good first issue"](https://github.com/openclaw/openclaw/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
labels. If none are open, pick a small docs or bug issue and leave a quick comment saying
you'd like to work on it.
## Maintainers
We're selectively expanding the maintainer team.
If you're an experienced contributor who wants to help shape OpenClaw's direction — whether through code, docs, or community — we'd like to hear from you.
Being a maintainer is a responsibility, not an honorary title. We expect active, consistent involvement — triaging issues, reviewing PRs, and helping move the project forward.
Still interested? Email contributing@openclaw.ai with:
- Links to your PRs on OpenClaw (if you don't have any, start there first)
- Links to open source projects you maintain or actively contribute to
- Your GitHub, Discord, and X/Twitter handles
- A brief intro: background, experience, and areas of interest
- Languages you speak and where you're based
- How much time you can realistically commit
We welcome people across all skill sets — engineering, documentation, community management, and more.
We review every human-only-written application carefully and add maintainers slowly and deliberately.
Please allow a few weeks for a response.
## Report a Vulnerability
We take security reports seriously. Report vulnerabilities directly to the repository where the issue lives:
- **Core CLI and gateway** — [openclaw/openclaw](https://github.com/openclaw/openclaw)
- **macOS desktop app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/macos)
- **iOS app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/ios)
- **Android app** — [openclaw/openclaw](https://github.com/openclaw/openclaw) (apps/android)
- **ClawHub** — [openclaw/clawhub](https://github.com/openclaw/clawhub)
For issues that don't fit a specific repo, or if you're unsure, email **security@openclaw.ai** and we'll route it.
### Required in Reports
1. **Title**
2. **Severity Assessment**
3. **Impact**
4. **Affected Component**
5. **Technical Reproduction**
6. **Demonstrated Impact**
7. **Environment**
8. **Remediation Advice**
Reports without reproduction steps, demonstrated impact, and remediation advice will be deprioritized. Given the volume of AI-generated scanner findings, we need reports that researchers have checked and understand.