Thanks for your interest in contributing! This guide covers what we expect in issues and pull requests.
For the full rationale behind the PR guidelines, see the PR Contribution Guidelines ADR.
The fastest way to file an issue is to use the issue templates — they auto-apply the correct labels and pass automated validation.
| Type | Template | Required Sections |
|---|---|---|
| Bug | bug.yml | Description, Steps to Reproduce, Expected Behavior |
| Feature | feature.yml | Description, Use Case |
| Documentation | documentation.yml | Description |
| Guidance | guidance.yml | Question |
| RFC | rfc.yml | Proposal (free-form, no heading validation) |
If you file an issue via CLI or API (bypassing the template UI), keep these rules in mind:
-
Title prefix helps auto-detection. The following prefixes are recognized:
fix(...)orbug(...)→ Bugfeat(...)orfeature(...)→ Featuredocs(...)ordocumentation(...)→ DocumentationRFC:→ RFC
-
Use the required headings (as
##or###). Common synonyms are accepted:Required Field Accepted Synonyms Description Problem, Summary, Overview, Background, What happened, Bug description Steps to Reproduce Reproduction, How to reproduce, Repro steps, Steps to replicate, Repro Expected Behavior Expected result, What should happen, Expected behaviour, Expected outcome Use Case Motivation, Why, Rationale, Use cases, Why it matters, Benefits, Proposal Question (no synonyms) -
Headings must have content. An empty heading or
_No response_does not count.
A GitHub Action (issue-check.yml) runs on every issue open, edit, and label event:
- Missing type label + unrecognizable format →
incompletelabel is added, a bot comment asks you to wait for a maintainer to apply a type label. - Type is known but required sections are missing →
incompletelabel is added, a bot comment lists exactly what's missing. - All required sections present →
incompletelabel is automatically removed.
To fix an incomplete issue, simply edit the issue body to add the missing sections — no need to close and re-open.
Every PR must address the following in its description. The PR template will prompt you for each section.
All PRs must include a Discord Discussion URL in the PR body (e.g. https://discord.com/channels/...). Discussing your idea in Discord before opening a PR helps align on direction and avoids wasted effort. PRs without a Discord Discussion URL will be automatically closed in 24 hours.
Describe the pain point or requirement in plain language. Link the related issue.
Provide an ASCII diagram showing the high-level flow or where your change fits in the system. For docs-only or trivial changes, write "N/A".
Required for architectural, runtime, agent, scheduling, delivery, or persistence changes. For docs-only, chore, CI, release, or trivial bug fixes, write "Not applicable" with a brief reason.
When prior art research is required, investigate at minimum:
- OpenClaw — the largest open-source AI agent gateway
- Hermes Agent — Nous Research's self-hosted agent with multi-platform messaging
Include links to relevant source code, documentation, or discussions. If neither project addresses the problem, state that explicitly with evidence.
Describe your technical approach, architecture decisions, and key implementation details.
Explain why you chose this approach over the alternatives found in your research. Be explicit about:
- Tradeoffs you accepted
- Known limitations
- How this could evolve in the future
List approaches you evaluated but did not choose, and explain why they were rejected.
Pick the checks relevant to your PR type:
- Rust changes:
cargo check,cargo test,cargo clippy - Helm chart changes:
helm lint,helm template - CI/workflow changes: workflow syntax validation, dry-run where possible
- Docs-only changes: links are valid, renders correctly in GitHub preview
Describe any manual testing performed and add unit tests for new functionality.
OpenAB is a young project. We want every design decision to be informed by what's already working in production elsewhere. This:
- Prevents reinventing the wheel
- Surfaces better patterns we might not have considered
- Documents the design space for future contributors
- Makes reviews faster — reviewers don't have to do the research themselves
cargo build
cargo test
cargo checkOAB spawns agent adapters (agy-acp, codex-acp, etc.) as child processes with a minimal environment — only env vars explicitly listed in [agent].env config are passed. No .profile, .bashrc, or login shell is sourced.
If your agent adapter spawns further subprocesses (e.g. agy, codex), those tools may depend on PATH entries set up by shell init files (fnm, nvm, cargo, etc.). Do not rely on login shells (bash -lc) — shell metacharacters in user prompts will break argument passing.
Instead, augment PATH directly in your adapter code:
fn augmented_path() -> String {
let home = std::env::var("HOME").unwrap_or_else(|_| "/home/agent".to_string());
let base = std::env::var("PATH").unwrap_or_else(|_| "/usr/local/bin:/usr/bin:/bin".to_string());
format!("{home}/bin:{home}/.local/bin:{home}/.local/share/fnm/aliases/default/bin:{base}")
}
// Then when spawning:
Command::new("/usr/local/bin/agy")
.args(&args)
.env("PATH", augmented_path())
.spawn();Use the PR Preview Build workflow for fast iteration:
# 1. Push code to PR branch
# 2. Build the image
gh workflow run "PR Preview Build" --repo openabdev/openab \
--ref <branch> -f pr_number=<N> -f variant=<antigravity|codex|claude|default>
# 3. Wait for build
gh run view <run_id> --repo openabdev/openab --json conclusion -q .conclusion
# 4. Deploy and test (depends on your environment)
# - Kubernetes: kubectl rollout restart deployment/<name>
# - ECS Fargate (OAB fleet): [ecsctl](https://github.com/oablab/ecsctl) restart <bot> --wait
# - Local: docker run with the PR image tagNever run two instances with the same bot token — both receive messages and send duplicate/conflicting responses.
- Run
cargo fmtbefore committing - Run
cargo clippyand address warnings - Keep PRs focused — one feature or fix per PR
Every PR follows a label-driven lifecycle that keeps the review loop moving.
┌──────────────┐
│ PR Created │
└──────┬───────┘
│
▼
┌──────────────────────┐
│ Automated Checks │
│ (CI, rebase, etc.) │
└──────┬───────────────┘
│
├── all pass ──────────────────────►┌──────────────────────┐
│ │ pending-maintainer │
│ └──────────┬───────────┘
│ │
│ ├── LGTM → approve & merge (or request
│ │ another maintainer review)
│ │ stays pending-maintainer
│ │
│ └── pending actions for contributor
│ │
│ ▼
└── any fail ──────────────────────►┌──────────────────────┐
│ pending-contributor │◄─────────┐
└──────────┬───────────┘ │
│ │
│ stale 2 days │
│ (no author activity) │
▼ │
┌───────────────────┐ │
│ closing-soon │ │
│ (or immediate if │ │
│ blocker detected)│ │
└────────┬──────────┘ │
│ │
┌────────────┴──────────┐ │
│ │ │
▼ ▼ │
author comments 3 more days │
within 3 days no activity │
│ │ │
▼ ▼ │
┌────────────────────┐ ┌────────────┐ │
│ pending-maintainer │ │ PR Closed │ │
│ (labels removed) │ └────────────┘ │
└────────┬───────────┘ │
│ │
└── re-check fails ────────────────────┘
| Current State | Trigger | Action |
|---|---|---|
pending-contributor |
No author activity for 2 days | Add closing-soon |
closing-soon |
No author activity for 3 more days | Auto-close PR |
pending-contributor |
Author adds a comment | Remove pending-contributor, add pending-maintainer |
closing-soon |
Author adds a comment | Remove closing-soon and pending-contributor, add pending-maintainer |
pending-contributor— the ball is on the contributor; maintainers are waiting for updates.closing-soon— warning that the PR will be auto-closed if no response within 3 days. For PRs missing a Discord Discussion URL, auto-close happens in 24 hours.- Author comment always resets — any comment by the PR author removes
pending-contributorandclosing-soon, flipping the PR back topending-maintainer. - Re-check may re-apply
closing-soon— after the flip, automated checks still run. If blockers remain (e.g., missing Discord URL, CI failure,needs-rebase),closing-soonwill be re-applied immediately, keeping the ball on the contributor. - Immediate
closing-soon— in some cases (e.g., missing Discord Discussion URL),closing-soonis applied immediately without waiting for the stale period. Auto-close follows in 24 hours.