# General Bots AI Agent Guidelines - For host/infra operations see INFRA.md (container ops, Vault, CI/CD, DNS, MinIO, alerts) - stop saving .png on root! Use /tmp. never allow new files on root. - never push to alm without asking first - it is production! - NEVER deploy to production manually — ALWAYS use CI/CD pipeline - NEVER include sensitive data (IPs, tokens, passwords, keys) in any documentation - NEVER use scp or manual deployment to system container - ALWAYS push to ALM → CI builds on alm-ci → CI deploys automatically - 8080 is server, 3000 is client UI - Test web: http://localhost:3000 (botui!) - Test login: http://localhost:3000/suite/auth/login.html - DEV ENV — sometimes pasting from PROD, do not treat as prod. Just fix, push to CI. - Use Playwright MCP to start localhost:3000/botname now. - NEVER create files with secrets in repository root - Mask IPs in logs (10.x.x.x pattern, not real IPs) - NEVER use cargo clean — causes 30min rebuilds, use ./reset.sh for DB issues - Secret files go in /tmp/ only (vault-token-gb, vault-unseal-key-gb) - See botserver/src/drive/local_file_monitor.rs for how bots load from drive (MinIO) --- ## WORKSPACE STRUCTURE | Crate | Purpose | Port | Tech | |-------|---------|------|------| | botserver | Main API server, business logic | 8080 | Axum, Diesel, Rhai BASIC | | botui | Web UI server (dev) + proxy | 3000 | Axum, HTML/HTMX/CSS | | botapp | Desktop app wrapper | - | Tauri 2 | | botlib | Shared library | - | Core types, errors | | botbook | Documentation | - | mdBook | | bottest | Integration tests | - | tokio-test | | botdevice | IoT/Device support | - | Rust | | botplugin | Browser extension | - | JS | Key Paths: target/debug/botserver | botserver/.env | botui/ui/suite/ --- ## CHAT FLOW 1. WebSocket connect → UserSession created, session_id generated 2. start.bas runs ONCE per session → ADD_SUGGESTION calls, Redis flag set 3. Message processing → if type 6: TOOL_EXEC (bypass LLM), else: KB injection + LLM 4. Tool Execution → Direct .ast via Rhai, no LLM/KB 5. LLM Response → Streaming via WebSocket chunks 6. Frontend Display → HTMX, suggestion buttons from Redis Message Types: 0=EXTERNAL 1=USER 2=BOT_RESPONSE 3=CONTINUE 4=SUGGESTION 5=CONTEXT_CHANGE 6=TOOL_EXEC Bots live in drive (MinIO storage), each bucket is a bot. Respect LOAD_ONLY. --- ## BASIC SCRIPT ARCHITECTURE - start.bas — Runs once per session, loads suggestions - tables.bas — Parsed at compile time, defines DB schema (DO NOT CALL with CALL) - tool.bas — Compiled to .ast, executed via CALL or TOOL_EXEC type 6 ### BASIC Keywords — Syntax Signatures (no quotes, bare tokens) TALK message | HEAR prompt AS variable | USE KB name | CLEAR KB USE WEBSITE url | ADD SUGGESTION text | CLEAR SUGGESTIONS GET FROM table WHERE condition | SAVE record TO table | FIND value IN table FIRST(array) | LAST(array) | COUNT(array) | FORMAT template, var1, var2 CREATE FILE path WITH content | READ FILE path | WRITE FILE path WITH content DELETE FILE path | COPY FILE source TO dest | LIST FILES path UPLOAD data TO path | DOWNLOAD url TO path GET HTTP url | POST HTTP url WITH data | WEBHOOK url WITH data CREATE_TASK title, assignee, due, project_id | WAIT seconds ON EMAIL FROM filter DO CALL handler | ON CHANGE table DO CALL handler SET BOT MEMORY key = value | GET BOT MEMORY key | REMEMBER key = value SET CONTEXT key = value | SET USER property = value | TRANSFER TO HUMAN ADD BOT name WITH TRIGGER phrase | DELEGATE TO name | SEND TO BOT name MESSAGE msg SEND MAIL TO email WITH subject, body | SEND SMS TO phone MESSAGE text CREATE DRAFT title WITH content | CREATE SITE name WITH config POST TO SOCIAL platform MESSAGE text | LLM prompt DETECT tablename | CALL scriptname Built-in Variables: TODAY, NOW, USER, SESSION, BOT > Full keyword docs: botbook/src/04-basic-scripting/ --- ## SECURITY DIRECTIVES — MANDATORY 1. Error Handling: NO unwrap/expect/panic/todo/unimplemented. Use value? or ok_or_else 2. Command Execution: Use SafeCommand, never Command::new directly 3. Error Responses: Use log_and_sanitize, never raw error strings to clients 4. SQL: Use sql_guard sanitize_identifier/validate_table_name, never format strings 5. Rate Limiting: governor crate, per-IP and per-User, WebSocket 10 msgs/s 6. CSRF: All state-changing endpoints need CSRF token (exempt: Bearer Token APIs) 7. Security Headers on ALL responses: CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy 8. Dependency Pinning: Critical deps exact version, track Cargo.lock for app crates > Full security docs: botbook/src/09-security/ --- ## MANDATORY CODE PATTERNS - Use Self in impl blocks, not MyStruct - Derive PartialEq + Eq together - format!(name) not format!({}, name) - Combine identical match arms: A | B => thing() --- ## ABSOLUTE PROHIBITIONS - NEVER search /target folder (binary compiled) - NEVER hardcode credentials — use generate_random_string() or env vars - NEVER build in release mode or use --release flag - NEVER run cargo build — use cargo check - NEVER deploy manually — always push to ALM, CI/CD deploys - NEVER use scp/SSH to deploy — CI workflow handles it - NEVER use cargo clean — causes 30min rebuilds - NEVER use panic/todo/unimplemented/Command::new/unwrap/expect - NEVER use #[allow()] — FIX the code - NEVER add lint exceptions to Cargo.toml - NEVER prefix unused vars with _ — DELETE or USE them - NEVER leave unused imports or dead code - NEVER use CDN links — all assets local - NEVER comment out code — DELETE it - NEVER create .md files without checking botbook/ first - NEVER write internal IPs to logs — mask as 10.x.x.x --- ## FILE SIZE LIMIT: 450 LINES MAX Split at 350 lines proactively: types.rs, handlers.rs, operations.rs, utils.rs, mod.rs --- ## ERROR FIXING WORKFLOW OFFLINE FIRST: Read ALL errors → group by file → fix ALL per file → write once → verify LAST NEVER run cargo check DURING fixing — fix ALL offline, verify ONCE at end Streaming Build Rule: Cancel build as soon as first errors appear, fix immediately --- ## MEMORY MANAGEMENT If Killed during compile: pkill -9 cargo; pkill -9 rustc; pkill -9 botserver Then: CARGO_BUILD_JOBS=1 cargo check -p botserver 2>&1 | tail -200 --- ## RESET PROCESS reset.sh cleans and restarts dev env. Bootstrap takes 3-5 min. If timeout: check botserver.log for Bootstrap process completed Manual: ps aux | grep botserver | grep -v grep; curl http://localhost:8080/health; ./restart.sh Verify: PostgreSQL 5432, Valkey 6379, BotServer 8080, BotUI 3000 --- ## PLAYWRIGHT BROWSER TESTING 1. Navigate to http://localhost:3000/botname 2. Take snapshot → test flows → verify results → validate backend 3. Desktop may have maximized chat — click middle button to minimize 4. Backend validation: psql or tail logs after UI interactions --- ## ADDING NEW FEATURES 1. Add types to botlib if shared 2. Add migration SQL + Diesel model 3. Add business logic in botserver/src/features/ 4. Add API endpoint 5. Add BASIC keyword if needed (register_custom_syntax, spawn thread for async) 6. Security: input validation, auth, rate limit, sanitize errors, no unwrap > Architecture details: botbook/src/02-architecture-packages/architecture.md --- ## BUG FIXING 1. Reproduce: grep errors in botserver.log, trace data flow 2. Find code: grep -r pattern --include=*.rs, check mod.rs 3. Fix minimal: wrong variable? missing validation? race condition? 4. Test: cargo check -p botserver, ./restart.sh, verify in browser 5. Commit: clear message with root cause, impact, files, testing notes Logs: check container logs via `sudo incus exec system -- journalctl -u botserver` | botserver.log (dev only) | botui.log | [drive_monitor] prefix | CLIENT: prefix On staging/production: check logs in container via `sudo incus exec system -- tail -f logs/err.log` > Troubleshooting: botbook/src/12-ecosystem-reference/troubleshooting.md --- ## DEPLOY WORKFLOW Push to ALM → CI builds on alm-ci → deploys to system container via SSH NEVER deploy manually. CI path: alm-ci builds → tar+gzip → /opt/gbo/bin/botserver → restart CI deploy: alm-ci at /opt/gbo/bin/botserver → SSH → system container Runner: gbuser uid 1000, workspace /opt/gbo/data/, SSH key /home/gbuser/.ssh/id_ed25519 > CI/CD details: botbook/src/12-ecosystem-reference/ci-cd.md --- ## PRODUCTION CONTAINER ARCHITECTURE | Container | Service | Port | |-----------|---------|------| | system | BotServer + Valkey | 8080/6379 | | vault | Vault | 8200 | | tables | PostgreSQL | 5432 | | drive | MinIO | 9000/9100 | | directory | Zitadel | 9000 | | meet | LiveKit | 7880 | | vectordb | Qdrant | 6333 | | llm | llama.cpp | 8081 | | email | Stalwart | 993/465/587 | | alm | Forgejo | 4747 (NOT 3000!) | | alm-ci | Forgejo Runner | - | | proxy | Caddy | 80/443 | | dns | CoreDNS | 53 | Container ops: sudo incus list/start/stop/restart/exec/snapshot Backup: pg_dump -U postgres -F c -f /tmp/backup.dump dbname ALM port is 4747. Runner token in action_runner_token table. > Container details: botbook/src/02-architecture-packages/containers.md > Backup/Recovery: botbook/src/12-ecosystem-reference/backup-recovery.md --- ## PRODUCTION OPERATIONS — QUICK REFERENCE ### Critical Safety Rules - NEVER modify iptables without explicit confirmation - NEVER touch PROD without asking first - ALWAYS backup files to /tmp before editing ### Infrastructure Paths - Base: /opt/gbo/ | Bin: /opt/gbo/bin | Conf: /opt/gbo/conf | Logs: /opt/gbo/logs - Bots are stored in MinIO (drive), NOT in /opt/gbo/data ### Service Operations - DNS (CoreDNS): config /opt/gbo/conf/Corefile, zones in MinIO - PostgreSQL: backup pg_dump, restore pg_restore - Email (Stalwart): config /opt/gbo/conf/config.toml, check DKIM TXT records - Proxy (Caddy): config /opt/gbo/conf/config, validate then reload - MinIO: internal API http://drive-ip:9000, bots stored as buckets - Bot System: binary /opt/gbo/bin/botserver, Valkey port 6379 - ALM (Forgejo): port 4747, CI runner separate container, token from DB - CI Runner: config /opt/gbo/bin/config.yaml, runs as gbuser, systemd service sccache at /usr/local/bin/sccache, workspace /opt/gbo/data/ ### Network — NAT Port Forwarding External ports DNAT to container IPs via iptables. Rules in /etc/iptables.rules Always use external interface (-i iface) to avoid loopback issues. Port Map: 53=DNS 80/443=HTTP/HTTPS 5432=PostgreSQL 993=IMAPS 465=SMTPS 587=Submission 4747=Forgejo 9000=MinIO 8200=Vault ### Container Management sudo incus list | start/stop/restart container | exec container -- bash sudo incus snapshot create container name | copy container/snapshot target ### Troubleshooting - Container won't start: sudo incus list, sudo incus log container --show-log - Service not running: sudo incus exec container -- pgrep -a process - Email delivery: check stalwart, IMAP/SMTP ports, DKIM records - Disk space: df -h, sudo btrfs filesystem df /var/lib/incus > Full operations: botbook/src/02-architecture-packages/containers.md --- ## STAGING ENVIRONMENT (STAGE-GBO) Use 10.0.3.x subnet for container IPs. Route via host gateway 10.0.0.1. Do NOT confuse staging (10.0.3.x) with production ranges. --- ## FRONTEND STANDARDS HTMX-first: hx-get, hx-post, hx-target, hx-swap. No CDN. All assets local. > UI details: botbook/src/07-user-interface/htmx-architecture.md --- ## PERFORMANCE & LINTING - Clippy: 0 warnings. No #[allow()] — fix code - Release profile: opt-level=z, lto=true, codegen-units=1, strip=true, panic=abort - Weekly: cargo tree --duplicates, cargo machete, cargo audit --- ## TESTING - Unit tests: inline #[cfg(test)] modules or crate tests/ dir - Integration tests: bottest/ crate, cargo test -p bottest - Coverage: 80%+ for critical paths, ALL error paths, ALL security guards > Testing details: botbook/src/12-ecosystem-reference/architecture.md --- ## CONTINUATION PROMPT 1. Check build/diagnostics 2. Fix ALL warnings and errors — no #[allow()] 3. Delete unused code 4. Replace ALL unwrap/expect with proper error handling 5. Verify after each fix batch 6. Loop until 0 warnings, 0 errors 7. Refactor files >450 lines --- ## MEMORY DIRECTIVES OFFLINE FIRST → BATCH BY FILE → WRITE ONCE → VERIFY LAST → DELETE DEAD CODE Push to ALL remotes (github, pragmatismo) --- ## SECRET FILES — /tmp/ ONLY vault-token-gb and vault-unseal-key-gb go in /tmp/ only — cleared on reboot, not tracked by git.