|
| 1 | +# OpenAB — Agent Guidelines |
| 2 | + |
| 3 | +You are contributing to OpenAB, a lightweight Rust-based ACP harness bridging Discord, Slack, and webhook platforms to coding CLIs over stdio JSON-RPC. |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +``` |
| 8 | +src/ |
| 9 | +├── main.rs # entrypoint, multi-adapter startup, graceful shutdown |
| 10 | +├── adapter.rs # ChatAdapter trait, AdapterRouter (platform-agnostic) |
| 11 | +├── config.rs # TOML config + ${ENV_VAR} expansion |
| 12 | +├── discord.rs # DiscordAdapter (serenity EventHandler) |
| 13 | +├── slack.rs # SlackAdapter (Socket Mode) |
| 14 | +├── gateway.rs # Custom Gateway WebSocket adapter |
| 15 | +├── cron.rs # Config-driven + usercron scheduler |
| 16 | +├── media.rs # Image resize/compress + STT download |
| 17 | +├── format.rs # Message splitting, thread name shortening |
| 18 | +├── markdown.rs # Discord markdown rendering |
| 19 | +├── reactions.rs # Emoji status controller (debounce, stall detection) |
| 20 | +├── bot_turns.rs # Bot turn tracking |
| 21 | +├── error_display.rs # User-facing error formatting |
| 22 | +├── stt.rs # Speech-to-text (Whisper API) |
| 23 | +├── setup/ # Interactive setup wizard |
| 24 | +│ ├── config.rs # Setup config helpers |
| 25 | +│ ├── validate.rs # Input validation |
| 26 | +│ └── wizard.rs # CLI setup flow |
| 27 | +└── acp/ |
| 28 | + ├── protocol.rs # JSON-RPC types + ACP event classification |
| 29 | + ├── connection.rs # Spawn CLI, stdio JSON-RPC, env_clear whitelist |
| 30 | + └── pool.rs # Session key → AcpConnection map + lifecycle |
| 31 | +``` |
| 32 | + |
| 33 | +**Helm chart:** `charts/openab/` — Go templates, values.yaml, NOTES.txt |
| 34 | +**Gateway:** `gateway/` — standalone Rust binary for Telegram/LINE/Teams |
| 35 | +**Docs:** `docs/` — user-facing guides, ADRs, config reference |
| 36 | + |
| 37 | +## Message Flow |
| 38 | + |
| 39 | +``` |
| 40 | +Discord/Slack event |
| 41 | + → channel allowlist check |
| 42 | + → user allowlist check (bot messages bypass this) |
| 43 | + → bot message filter (off/mentions/all) |
| 44 | + → thread detection (thread_metadata = thread, NOT parent_id) |
| 45 | + → bot ownership check (bot_owns = thread creator matches bot user ID) |
| 46 | + → multibot detection (allowUserMessages mode) |
| 47 | + → handle_message → pool.get_or_create → ACP JSON-RPC |
| 48 | +``` |
| 49 | + |
| 50 | +Understand this pipeline before modifying any adapter code. |
| 51 | + |
| 52 | +## Critical Rules |
| 53 | + |
| 54 | +### 1. Backward-Compatible Defaults |
| 55 | + |
| 56 | +New config fields MUST default to the previous behavior. Never change what existing deployments experience without an explicit opt-in. |
| 57 | + |
| 58 | +### 2. Thread Detection |
| 59 | + |
| 60 | +The definitive rules — do NOT reinvent this: |
| 61 | +- A channel is a thread if `thread_metadata` is present (NOT `parent_id`) |
| 62 | +- `bot_owns` = thread's `owner_id` matches the bot's user ID |
| 63 | +- Use `ChannelType` enum, not structural heuristics |
| 64 | +- Forum posts are threads with `parent_id` pointing to a forum channel |
| 65 | + |
| 66 | +### 3. Security — Child Process Environment |
| 67 | + |
| 68 | +Agent subprocesses start with `env_clear()`. The baseline env passed to the child is: |
| 69 | +- **All platforms:** `HOME`, `PATH` |
| 70 | +- **Unix only:** `USER` |
| 71 | +- **Windows only:** `USERPROFILE`, `USERNAME`, `SystemRoot`, `SystemDrive` |
| 72 | +- Plus any explicit `[agent].env` keys (logged with a prompt-injection warning) |
| 73 | + |
| 74 | +Never leak `DISCORD_BOT_TOKEN` or other OAB credentials to the agent. |
| 75 | + |
| 76 | +### 4. Dockerfile Discipline |
| 77 | + |
| 78 | +There are 7 Dockerfiles: `Dockerfile`, `Dockerfile.claude`, `Dockerfile.codex`, `Dockerfile.copilot`, `Dockerfile.cursor`, `Dockerfile.gemini`, `Dockerfile.opencode`. |
| 79 | + |
| 80 | +A change to one MUST be evaluated against ALL. Common layers (base image, openab binary, tini) are shared — update all or explain why not. |
| 81 | + |
| 82 | +### 5. Cross-Platform |
| 83 | + |
| 84 | +Gate platform-specific code with `#[cfg(target_os = "...")]`. After adding Unix-only calls (libc, signals), verify: |
| 85 | +```bash |
| 86 | +cargo check --target x86_64-pc-windows-gnu |
| 87 | +``` |
| 88 | + |
| 89 | +### 6. Discord API Limits |
| 90 | + |
| 91 | +- Select menu: max 25 options (truncate with count, don't crash) |
| 92 | +- Message content: max 2000 chars (use `format.rs` splitting) |
| 93 | +- Rate limits: respect serenity's built-in ratelimiter |
| 94 | + |
| 95 | +## Helm Chart Checklist |
| 96 | + |
| 97 | +Before merging any chart change: |
| 98 | + |
| 99 | +```bash |
| 100 | +helm template test charts/openab |
| 101 | +helm template test charts/openab --set agents.kiro.enabled=false |
| 102 | +``` |
| 103 | + |
| 104 | +- Boolean fields: use `{{ if hasKey .Values "field" }}` not `{{ if .Values.field }}` (Go nil trap) |
| 105 | +- Channel/user IDs: always `--set-string` (float64 precision loss) |
| 106 | +- PVCs: set `"helm.sh/resource-policy": keep` — never delete user data on uninstall |
| 107 | +- New values: add to `values.yaml` with comment + update `docs/config-reference.md` |
| 108 | + |
| 109 | +## Breaking Changes |
| 110 | + |
| 111 | +If your change alters existing behavior: |
| 112 | + |
| 113 | +1. Add `!` to commit type: `feat(cron)!: description` |
| 114 | +2. Include migration steps in PR body |
| 115 | +3. Update relevant docs with migration callout |
| 116 | +4. Ensure release note has ⚠️ Breaking Change section |
| 117 | + |
| 118 | +## Build & Verify |
| 119 | + |
| 120 | +```bash |
| 121 | +cargo fmt |
| 122 | +cargo clippy -- -D warnings |
| 123 | +cargo test |
| 124 | +``` |
| 125 | + |
| 126 | +All three must pass before pushing. For cross-platform changes, add: |
| 127 | +```bash |
| 128 | +cargo check --target x86_64-pc-windows-gnu |
| 129 | +``` |
| 130 | + |
| 131 | +## PR Standards |
| 132 | + |
| 133 | +- One logical change per PR |
| 134 | +- Commit message: `type(scope): description` — types: `feat`, `fix`, `docs`, `refactor`, `test`, `ci`, `build` |
| 135 | +- Include regression tests for bug fixes |
| 136 | +- Reference issues: `Closes #123` or `Fixes #456` |
| 137 | + |
| 138 | +## ADRs |
| 139 | + |
| 140 | +Read `docs/adr/` before implementing features in these areas: |
| 141 | +- Cron scheduler → `docs/adr/basic-cronjob.md` |
| 142 | +- Custom Gateway → `docs/adr/custom-gateway.md` |
| 143 | +- LINE adapter → `docs/adr/line-adapter.md` |
| 144 | +- Multi-platform adapters → `docs/adr/multi-platform-adapters.md` |
| 145 | + |
| 146 | +Write a new ADR if your feature introduces a new subsystem. |
0 commit comments