Skip to content

Commit 55acd30

Browse files
authored
docs: add directory-specific AGENTS.md files and improve root guidelines (#124)
1 parent e17ce31 commit 55acd30

4 files changed

Lines changed: 177 additions & 215 deletions

File tree

AGENTS.md

Lines changed: 54 additions & 215 deletions
Original file line numberDiff line numberDiff line change
@@ -1,242 +1,81 @@
11
# Baudbot — Agent Guidelines
22

3-
Baudbot is hardened infrastructure for running always-on AI agents. Source is admin-owned; agents run from deployed copies.
3+
Baudbot is hardened infrastructure for running always-on AI agents.
44

5-
## Repo Layout
5+
Use this file for **repo-wide** guidance. For directory-specific rules, use the nearest nested `AGENTS.md`:
6+
- [`bin/AGENTS.md`](bin/AGENTS.md)
7+
- [`pi/extensions/AGENTS.md`](pi/extensions/AGENTS.md)
8+
- [`slack-bridge/AGENTS.md`](slack-bridge/AGENTS.md)
69

7-
```
8-
bin/ security & operations scripts
9-
baudbot CLI (attach, sessions, update, deploy)
10-
deploy.sh deploys a prepared source tree → agent runtime
11-
update-release.sh temp checkout → git-free /opt release snapshot → deploy
12-
rollback-release.sh rollback to previous or specified /opt release snapshot
13-
security-audit.sh security posture audit
14-
setup-firewall.sh iptables per-UID egress allowlist
15-
baudbot-safe-bash shell command deny list (installed to /usr/local/bin)
16-
baudbot-docker Docker wrapper (blocks privilege escalation)
17-
harden-permissions.sh filesystem hardening (runs on boot)
18-
scan-extensions.mjs extension static analysis
19-
redact-logs.sh secret scrubber for session logs
20-
prune-session-logs.sh retention cleanup for old pi session logs
21-
config.sh interactive secrets/config setup
22-
broker-register.mjs Slack broker workspace registration CLI
23-
doctor.sh system health checks
24-
uninstall.sh clean removal of baudbot
25-
test.sh runs all test suites
26-
baudbot-firewall.service systemd unit for firewall persistence
27-
baudbot.service systemd unit for agent process
28-
ci/ CI integration scripts
29-
droplet.sh ephemeral DigitalOcean droplet lifecycle (create/destroy/ssh)
30-
setup-ubuntu.sh Ubuntu droplet: prereqs + setup + tests
31-
setup-arch.sh Arch Linux droplet: prereqs + setup + tests
32-
lib/ shared shell helpers sourced by CLI/release scripts
33-
shell-common.sh strict mode + shared logging/error/root-check helpers
34-
paths-common.sh shared path constants (bb_init_paths, bb_refresh_release_paths)
35-
release-common.sh shared update/rollback helpers
36-
deploy-common.sh deploy/runtime helper functions
37-
doctor-common.sh doctor status/check formatting helpers
38-
json-common.sh shared JSON field extraction helper (jq)
39-
baudbot-runtime.sh runtime/status/session/attach helper module for bin/baudbot
40-
hooks/
41-
pre-commit blocks agent from modifying security files in git
42-
pi/
43-
extensions/ source of truth for pi agent extensions
44-
tool-guard.ts 🔒 tool call interception (blocks dangerous patterns)
45-
tool-guard.test.mjs 🔒 86 tests for tool-guard
46-
heartbeat.ts periodic health check loop
47-
auto-name.ts session naming
48-
control.ts inter-session communication
49-
idle-compact.ts compact context during idle periods (default 25% threshold)
50-
...
51-
skills/ source of truth for agent skill templates
52-
control-agent/ orchestration agent
53-
HEARTBEAT.md health check checklist (deployed to ~/.pi/agent/)
54-
memory/ seed files for persistent memory
55-
dev-agent/ coding agent
56-
sentry-agent/ monitoring/triage agent
57-
settings.json pi agent settings
58-
slack-bridge/
59-
bridge.mjs Slack ↔ agent bridge (legacy Socket Mode)
60-
broker-bridge.mjs Slack ↔ agent bridge (broker pull mode — preferred)
61-
security.mjs 🔒 content wrapping, rate limiting, auth
62-
security.test.mjs 🔒 tests for security module
63-
setup.sh one-time system setup (creates user, firewall, etc.)
64-
start.sh agent launcher (deployed to ~/runtime/start.sh)
65-
```
66-
67-
🔒 = security-critical files. Protected at runtime (read-only perms + tool-guard blocks writes).
10+
## How Baudbot works
6811

69-
See [CONFIGURATION.md](CONFIGURATION.md) for all env vars and how to obtain them.
12+
Baudbot is a persistent, team-facing coding agent system. It connects to Slack, receives work requests from developers, and autonomously executes coding tasks (branch, code, test, PR, CI) on a Linux server.
7013

71-
## Architecture: Source / Runtime Separation
14+
**Runtime model:** A long-running **control agent** stays connected to Slack, triages incoming requests, and delegates work to ephemeral **dev agents** that each run in isolated git worktrees. A **sentry agent** handles on-demand incident triage. All agents run as an unprivileged `baudbot_agent` Unix user.
7215

73-
Live execution is release/runtime-based (`/opt/baudbot` + `baudbot_agent` runtime).
74-
75-
Live operations are now release-based under `/opt/baudbot` (git-free):
76-
77-
```
78-
/opt/baudbot/
79-
├── releases/<sha>/ immutable snapshot (no .git)
80-
├── current -> releases/<sha> active release symlink
81-
└── previous -> releases/<sha> previous release symlink (for rollback)
16+
```text
17+
Slack
18+
19+
slack-bridge (broker pull-mode or legacy Socket Mode)
20+
21+
control-agent (always-on, manages todo/routing/Slack threads)
22+
├── dev-agent(s) — ephemeral coding workers in isolated worktrees
23+
└── sentry-agent — incident triage (Sentry alerts)
24+
25+
git commits → PRs → CI feedback → thread updates back to Slack
8226
```
8327

84-
`baudbot update` flow:
85-
1) clone target ref into `/tmp/baudbot-update.*`
86-
2) run preflight checks in temp checkout
87-
3) publish git-free snapshot to `/opt/baudbot/releases/<sha>`
88-
4) deploy runtime files from snapshot
89-
5) restart + health check
90-
6) atomically switch `/opt/baudbot/current`
28+
**Deployment model:** Admin-managed source (this repo) is deployed as immutable, git-free release snapshots under `/opt/baudbot`. The agent runtime (`/home/baudbot_agent`) receives deployed extensions, skills, and bridge code. Updates and rollbacks are atomic symlink switches. See `docs/architecture.md` for full details.
9129

92-
`baudbot rollback previous|<sha>` re-deploys an existing snapshot and flips `current`/`previous` without network access.
30+
## What this repo contains (high-level)
9331

94-
Agent runtime layout:
95-
```
96-
/home/baudbot_agent/
97-
├── runtime/
98-
│ ├── start.sh deployed launcher
99-
│ ├── bin/ harden-permissions.sh, redact-logs.sh, prune-session-logs.sh
100-
│ └── slack-bridge/ deployed bridge
101-
├── .pi/agent/
102-
│ ├── extensions/ deployed extensions
103-
│ ├── skills/ agent-owned (can modify freely)
104-
│ ├── HEARTBEAT.md periodic health check checklist (admin-managed)
105-
│ ├── memory/ persistent agent memory (agent-owned, survives deploys)
106-
│ ├── baudbot-version.json deploy version (git SHA, timestamp)
107-
│ └── baudbot-manifest.json SHA256 hashes of all deployed files
108-
├── workspace/ project repos + git worktrees
109-
└── .config/.env secrets (600 perms)
110-
```
32+
- `bin/` — operational shell CLI, deploy/update/rollback, security and health scripts
33+
- `pi/extensions/` — tool extensions and runtime behaviors deployed into agent runtime
34+
- `pi/skills/` — agent personas and behavior (`SKILL.md` defines each agent's identity, rules, and tools)
35+
- `control-agent/` — orchestration/triage persona + persistent memory seeds
36+
- `dev-agent/` — coding worker persona
37+
- `sentry-agent/` — incident triage persona
38+
- `pi/settings.json` — pi agent settings
39+
- `slack-bridge/` — Slack integration bridges + security module
40+
- `docs/` — architecture/operations/security documentation
41+
- `test/` — vitest wrappers for shell scripts, integration, and legacy Node tests
42+
- `hooks/` — git hooks (security-critical `pre-commit` protecting admin-managed files)
43+
- `.github/` — CI workflows, PR template, issue templates
44+
- `.env.schema` — canonical schema for all environment variables (see `CONFIGURATION.md`)
45+
- `bootstrap.sh`, `setup.sh`, `install.sh`, `start.sh` — bootstrap installer, system setup, interactive install, and runtime launcher
11146

112-
## Development Workflow
47+
## Core workflow
11348

11449
```bash
115-
# First-time install (interactive — handles everything)
116-
sudo ./install.sh
117-
118-
# Edit source files in this repository checkout
50+
# JS/TS + shell tests + lint
51+
npm test
52+
npm run lint
11953

120-
# For source-only changes (extensions/skills/bridge), deploy directly:
54+
# Source-only deploy (extensions/skills/bridge changes)
12155
./bin/deploy.sh
12256

123-
# For operational updates from git (recommended for live bot):
57+
# Live operational update/rollback
12458
sudo baudbot update
125-
126-
# Roll back live bot to previous snapshot if needed:
12759
sudo baudbot rollback previous
128-
129-
# Register a server with Slack broker (after OAuth callback)
130-
sudo baudbot broker register --broker-url https://broker.example.com --workspace-id T0123ABCD --registration-token <token>
131-
132-
# Rotate an API key after setup (prompts hidden input)
133-
sudo baudbot env set ANTHROPIC_API_KEY --restart
134-
135-
# Optional: use external secret source instead of ~/.baudbot/.env
136-
sudo baudbot env backend set-command 'your-secret-tool export baudbot-prod'
137-
sudo baudbot env sync --restart
138-
139-
# Launch agent directly (debug/dev)
140-
sudo -u baudbot_agent ~/runtime/start.sh
141-
142-
# Or in tmux
143-
tmux new-window -n baudbot 'sudo -u baudbot_agent ~/runtime/start.sh'
14460
```
14561

146-
## Slack broker pull-mode notes
147-
148-
- Broker delivery is now pull-based. Registration is callback-free:
149-
- `sudo baudbot broker register --broker-url ... --workspace-id T... --registration-token ...`
150-
- After a successful broker registration, always restart to load new keys:
151-
- `sudo baudbot restart`
152-
- The runtime starts `broker-bridge.mjs` automatically when `SLACK_BROKER_*` vars are present.
153-
- Quick troubleshooting when Slack replies stop:
154-
- `sudo -u baudbot_agent tmux ls` (check `slack-bridge` session exists)
155-
- `sudo baudbot attach --tmux slack-bridge` (bridge logs)
156-
- `sudo journalctl -u baudbot.service -n 200 --no-pager` (startup/runtime errors)
157-
- For local/semi-integration tests that spawn `slack-bridge/broker-bridge.mjs`, keep `libsodium-wrappers-sumo` available from root install (`npm install` at repo root).
158-
159-
## Running Tests
160-
161-
```bash
162-
# All tests (unified Vitest runner)
163-
npm test
164-
165-
# Only JS/TS tests
166-
npm run test:js
167-
168-
# Only shell/security script tests
169-
npm run test:shell
170-
171-
# JS/TS coverage
172-
npm run test:coverage
173-
174-
# Lint (Biome + ShellCheck)
175-
npm run lint
176-
```
177-
178-
Add new test files to `vitest.config.mjs` (and shell wrappers under `test/` as needed) — don't scatter test invocations across CI or docs.
179-
180-
## Conventions
181-
182-
- Security functions must be pure, testable modules (no side effects, no env vars at module scope).
183-
- All security code must have tests before merging.
184-
- Run `bin/security-audit.sh --deep` after any security-relevant changes.
185-
- Keep shell CLIs thin: move reusable logic to `bin/lib/*.sh`, and source shared helpers (`shell-common.sh`, `paths-common.sh`, `release-common.sh`, `deploy-common.sh`, `doctor-common.sh`) instead of duplicating logging/error/root-check patterns.
186-
- For shell scripts, standardize on `bb_enable_strict_mode` and shared helper functions (`bb_log`, `bb_die`, etc.) rather than ad-hoc wrappers.
187-
- Protected files (`tool-guard.ts`, `security.mjs`, their tests) are deployed read-only. The agent cannot modify them at runtime.
188-
- New integrations get their own subdirectory (e.g. `discord-bridge/`).
189-
- Extensions are deployed from `pi/extensions/` → agent's `~/.pi/agent/extensions/`.
190-
- Skills are deployed from `pi/skills/` → agent's `~/.pi/agent/skills/`.
191-
- Agent commits operational learnings to its own skills dir (not back to source).
192-
- **When changing behavior, update all docs.** Check and update: `README.md`, relevant pages in `docs/`, `CONFIGURATION.md`, skill files (`pi/skills/*/SKILL.md`), and `AGENTS.md`. Inline code examples in docs must match the actual implementation.
193-
- **Prefer distro-agnostic commands, but prioritize reliability.** Scripts should work on both Arch and Ubuntu (and standard Linux), but distro-specific branches are allowed when they improve setup reliability/UX. If you use distro-specific logic, include graceful fallbacks (or clear prereq docs), keep behavior consistent across distros, and add tests. Continue using portable shell patterns (`grep -E`, POSIX-compatible tools) wherever possible.
194-
195-
## Testing on Droplets
196-
197-
Use `bin/ci/droplet.sh` to spin up ephemeral DigitalOcean droplets for testing setup, install, or shell changes on real Linux. Requires `DO_API_TOKEN` env var.
198-
199-
```bash
200-
# Generate a throwaway SSH key
201-
ssh-keygen -t ed25519 -f /tmp/ci_key -N "" -q
202-
203-
# Create a droplet (Ubuntu or Arch)
204-
eval "$(bin/ci/droplet.sh create my-test ubuntu-24-04-x64 /tmp/ci_key.pub)"
205-
# → sets DROPLET_ID, DROPLET_IP, SSH_KEY_ID
206-
207-
# Or Arch (custom image):
208-
eval "$(bin/ci/droplet.sh create my-test 217410218 /tmp/ci_key.pub)"
209-
210-
# Wait for SSH, upload source, run a CI script
211-
bin/ci/droplet.sh wait-ssh "$DROPLET_IP" /tmp/ci_key
212-
tar czf /tmp/baudbot-src.tar.gz --exclude=node_modules --exclude=.git .
213-
scp -i /tmp/ci_key /tmp/baudbot-src.tar.gz "root@$DROPLET_IP:/tmp/"
214-
bin/ci/droplet.sh run "$DROPLET_IP" /tmp/ci_key bin/ci/setup-ubuntu.sh
215-
216-
# Or SSH in for manual poking
217-
ssh -i /tmp/ci_key "root@$DROPLET_IP"
218-
219-
# Clean up when done (~$0.003/run)
220-
bin/ci/droplet.sh destroy "$DROPLET_ID" "$SSH_KEY_ID"
221-
```
62+
## Non-negotiable guardrails
22263

223-
Droplets take ~15s to create, ~10s for SSH, ~90s for full setup+tests. Always destroy after — they cost ~$0.003 per run but add up if forgotten.
64+
**Hard constraints (enforced by pre-commit hook or CI):**
65+
- Never commit directly to `main`; use feature branches + PRs.
66+
- Security-critical files are protected by `hooks/pre-commit` — the agent cannot modify them at runtime.
67+
- Security-sensitive changes MUST include or update tests.
68+
- Do NOT weaken runtime hardening (permissions, least privilege, egress restrictions).
22469

225-
The CI scripts (`bin/ci/setup-ubuntu.sh`, `bin/ci/setup-arch.sh`) run the bootstrap flow (`bootstrap.sh``baudbot install`) with simulated input, verify the result, then run the full test suite. Use them as-is or SSH in and test manually.
70+
**Strong defaults:**
71+
- When behavior changes, update docs in the same PR (`README.md`, `docs/*`, `CONFIGURATION.md`, and relevant `AGENTS.md` files).
72+
- Prefer distro-agnostic shell; distro-specific branches are acceptable when reliability improves.
22673

227-
## Security Notes
74+
## Tests and quality gates
22875

229-
- `tool-guard.ts` is a policy/guidance layer: it blocks many risky writes/bash patterns and provides safety-interruption reasoning, but it is not a hard sandbox boundary by itself.
230-
- `baudbot-safe-bash` (root-owned, `/usr/local/bin/`) is a second deny-list layer at the shell level; hard containment still comes from OS permissions and runtime hardening.
231-
- The firewall (`setup-firewall.sh`) restricts `baudbot_agent`'s network egress to an allowlist.
232-
- `/proc` is mounted with `hidepid=2` — agent can only see its own processes.
233-
- Secrets in `~/.config/.env` are `600` perms, never committed.
234-
- Session logs are auto-pruned on startup (14-day retention) and auto-redacted for API keys/tokens.
76+
Before merge, run at minimum: `npm run lint` and `npm test`.
23577

236-
## Git Workflow
78+
## Git / PR expectations
23779

238-
- **Never commit directly to `main`.** All changes go on feature branches with PRs.
239-
- One branch per todo/task. Branch names: `<gh-username>/<description>` (e.g. `youruser/add-uninstall-script`).
240-
- Use `gh pr create` to open PRs (not the GitHub API with tokens).
241-
- Concise, action-oriented commit messages: `security: add rate limiting to bridge API`
242-
- Prefix with area: `security:`, `bridge:`, `deploy:`, `docs:`, `arch:`, `tests:`
80+
- Use concise commit messages with area prefix (`security:`, `bridge:`, `deploy:`, `docs:`, `tests:`, ...).
81+
- If a change is scoped to a subdirectory with its own `AGENTS.md`, follow that local file first.

bin/AGENTS.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# bin/ — Agent Guidelines
2+
3+
Scope: shell CLI and operational scripts under `bin/`.
4+
5+
## Focus areas
6+
7+
- CLI entrypoint (`baudbot`) and runtime helpers
8+
- deploy/update/rollback flows
9+
- security audit and firewall scripts
10+
- install/uninstall operational scripts
11+
- CI infrastructure (`bin/ci/`)
12+
- JS tooling: `broker-register.mjs`, `scan-extensions.mjs` (and their tests)
13+
- systemd unit files: `baudbot.service`, `baudbot-firewall.service`
14+
15+
## Rules
16+
17+
- Keep CLIs thin; move reusable logic into `bin/lib/*.sh`.
18+
- Reuse shared helpers (`shell-common.sh`, `paths-common.sh`, `release-common.sh`, etc.) instead of duplicating constants or logging/error patterns.
19+
- Prefer portable shell patterns; distro-specific branches are acceptable when reliability improves.
20+
- Any security-relevant shell change must include/adjust tests.
21+
22+
## Critical files
23+
24+
Treat as security-critical:
25+
- `baudbot-safe-bash` — runtime command-blocking wrapper
26+
- `harden-permissions.sh` — filesystem permission lockdown
27+
- `setup-firewall.sh` — network egress lockdown
28+
- `security-audit.sh` — security posture audit
29+
- `scan-extensions.mjs` — static analysis scanner for extensions
30+
- `redact-logs.sh` — secret redaction from session logs
31+
32+
## Notes
33+
34+
- Shared helpers in `bin/lib/` have co-located test files (e.g. `deploy-common.test.sh`, `json-common.test.sh`). Update tests when changing helpers.
35+
- For JS files in `bin/`, also run `npm run lint:js` and `npm run test:js`.
36+
37+
## Validation
38+
39+
Run before finishing shell work:
40+
41+
```bash
42+
npm run lint:shell
43+
npm run test:shell
44+
```
45+
46+
For security-sensitive updates, also run:
47+
48+
```bash
49+
bin/security-audit.sh --deep
50+
```

pi/extensions/AGENTS.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# pi/extensions/ — Agent Guidelines
2+
3+
Scope: extension code under `pi/extensions/`.
4+
5+
## Focus areas
6+
7+
- Tool extensions and runtime behaviors
8+
- Session-control and orchestration helpers
9+
- Safety/policy logic and stateful agent features
10+
11+
## Rules
12+
13+
- Keep extension behavior deterministic and testable.
14+
- Avoid module-scope side effects for security-sensitive code.
15+
- Preserve compatibility with deployed runtime assumptions (`~/.pi/agent/...`).
16+
- If changing extension behavior, update related skill/docs references where relevant.
17+
18+
## Subdirectory extensions
19+
20+
Some extensions have their own package scope:
21+
- `kernel/` — on-kernel cloud browser execution (has own `package.json`)
22+
- `agentmail/` — email integration (has own `package.json`)
23+
- `email-monitor/` — email monitoring
24+
25+
## Critical files
26+
27+
Treat these as security-critical and require strong justification + tests:
28+
- `tool-guard.ts`
29+
- `tool-guard.test.mjs`
30+
31+
## Validation
32+
33+
```bash
34+
npm run lint:js
35+
npm run test:js
36+
```

0 commit comments

Comments
 (0)