You are contributing to OpenAB, a lightweight Rust-based ACP harness bridging Discord, Slack, and webhook platforms to coding CLIs over stdio JSON-RPC.
src/
├── main.rs # entrypoint, multi-adapter startup, graceful shutdown
├── adapter.rs # ChatAdapter trait, AdapterRouter (platform-agnostic)
├── config.rs # TOML config + ${ENV_VAR} expansion
├── discord.rs # DiscordAdapter (serenity EventHandler)
├── slack.rs # SlackAdapter (Socket Mode)
├── gateway.rs # Custom Gateway WebSocket adapter
├── cron.rs # Config-driven + usercron scheduler
├── media.rs # Image resize/compress + STT download
├── format.rs # Message splitting, thread name shortening
├── markdown.rs # Discord markdown rendering
├── reactions.rs # Emoji status controller (debounce, stall detection)
├── bot_turns.rs # Bot turn tracking
├── error_display.rs # User-facing error formatting
├── stt.rs # Speech-to-text (Whisper API)
├── setup/ # Interactive setup wizard
│ ├── config.rs # Setup config helpers
│ ├── validate.rs # Input validation
│ └── wizard.rs # CLI setup flow
└── acp/
├── protocol.rs # JSON-RPC types + ACP event classification
├── connection.rs # Spawn CLI, stdio JSON-RPC, env_clear whitelist
└── pool.rs # Session key → AcpConnection map + lifecycle
Helm chart: charts/openab/ — Go templates, values.yaml, NOTES.txt
Gateway: gateway/ — standalone Rust binary for Telegram/LINE/Teams
Docs: docs/ — user-facing guides, ADRs, config reference
Discord/Slack event
→ channel allowlist check
→ user allowlist check (bot messages bypass this)
→ bot message filter (off/mentions/all)
→ thread detection (thread_metadata = thread, NOT parent_id)
→ bot ownership check (bot_owns = thread creator matches bot user ID)
→ multibot detection (allowUserMessages mode)
→ handle_message → pool.get_or_create → ACP JSON-RPC
Understand this pipeline before modifying any adapter code.
New config fields MUST default to the previous behavior. Never change what existing deployments experience without an explicit opt-in.
The definitive rules — do NOT reinvent this:
- A channel is a thread if
thread_metadatais present (NOTparent_id) bot_owns= thread'sowner_idmatches the bot's user ID- Use
ChannelTypeenum, not structural heuristics - Forum posts are threads with
parent_idpointing to a forum channel
Agent subprocesses start with env_clear(). The baseline env passed to the child is:
- All platforms:
HOME,PATH - Unix only:
USER - Windows only:
USERPROFILE,USERNAME,SystemRoot,SystemDrive - Plus any explicit
[agent].envkeys (logged with a prompt-injection warning)
Never leak DISCORD_BOT_TOKEN or other OAB credentials to the agent.
There are 7 Dockerfiles: Dockerfile, Dockerfile.claude, Dockerfile.codex, Dockerfile.copilot, Dockerfile.cursor, Dockerfile.gemini, Dockerfile.opencode.
A change to one MUST be evaluated against ALL. Common layers (base image, openab binary, tini) are shared — update all or explain why not.
Gate platform-specific code with #[cfg(target_os = "...")]. After adding Unix-only calls (libc, signals), verify:
cargo check --target x86_64-pc-windows-gnu- Select menu: max 25 options (truncate with count, don't crash)
- Message content: max 2000 chars (use
format.rssplitting) - Rate limits: respect serenity's built-in ratelimiter
Before merging any chart change:
helm template test charts/openab
helm template test charts/openab --set agents.kiro.enabled=false- Boolean fields: use
{{ if hasKey .Values "field" }}not{{ if .Values.field }}(Go nil trap) - Channel/user IDs: always
--set-string(float64 precision loss) - PVCs: set
"helm.sh/resource-policy": keep— never delete user data on uninstall - New values: add to
values.yamlwith comment + updatedocs/config-reference.md
If your change alters existing behavior:
- Add
!to commit type:feat(cron)!: description - Include migration steps in PR body
- Update relevant docs with migration callout
- Ensure release note has
⚠️ Breaking Change section
cargo fmt
cargo clippy -- -D warnings
cargo testAll three must pass before pushing. For cross-platform changes, add:
cargo check --target x86_64-pc-windows-gnu- One logical change per PR
- Commit message:
type(scope): description— types:feat,fix,docs,refactor,test,ci,build - Include regression tests for bug fixes
- Reference issues:
Closes #123orFixes #456
Read docs/adr/ before implementing features in these areas:
- Cron scheduler →
docs/adr/basic-cronjob.md - Custom Gateway →
docs/adr/custom-gateway.md - LINE adapter →
docs/adr/line-adapter.md - Multi-platform adapters →
docs/adr/multi-platform-adapters.md
Write a new ADR if your feature introduces a new subsystem.