# Balda Setup & Status > Last updated: 2026-06-07 ## Runtime | Item | Value | |------|-------| | Binary | `~/Developer/balda/balda` (built from source) | | Process | Managed by launchd (`com.normahq.balda`) | | Log | `/private/tmp/balda.log` | | Config | `~/Developer/balda/.config/balda/config.yaml` | | State dir | `~/Developer/balda/.config/balda/` | | Sessions | SQLite persistence | | Provider | `deepseek` (openai type, model: `deepseek-chat`, via `https://api.deepseek.com/v1`) | Balda is managed by launchd. Full restart (reloads plist env vars): ```bash launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.normahq.balda.plist launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.normahq.balda.plist ``` Quick restart (does NOT reload plist env vars — use bootout/bootstrap for env changes): ```bash launchctl kickstart -k gui/$(id -u)/com.normahq.balda ``` ## Zulip Webhook | Item | Value | |------|-------| | Status | ENABLED | | Listen address | `0.0.0.0:8091` | | Path | `/zulip/webhook` | | Webhook bot URL | `http://host.docker.internal:8091/zulip/webhook` | Port was **changed from 8090 → 8091** on 2026-06-07 (see Port Conflict below). ## Architecture Balda uses the **outgoing webhook** mechanism — Zulip pushes events to Balda's HTTP endpoint. This differs from Eagle/Kit which use polling. - Zulip runs in Docker (container: `zulip-zulip-1`), exposed on `127.0.0.1:8000` - Balda runs natively on Mac (not in Docker) - Colima maps `host.docker.internal:PORT → 127.0.0.1:PORT` on the Mac host, so the bot URL uses `host.docker.internal` to reach Balda from inside Docker ## Soul / Prompt The `global_instruction` field in `config.yaml` defines Balda's persona (Валера). The canonical source is `soul.md` in this folder — sync manually to config after edits, then restart Balda. Provider-level `system_instructions` are documented in `workspace-context.md`. --- ## Bug Fixed 2026-06-07 — Context Canceled on First DB Operation **File:** `zulip_handler.go`, line 236 **Root cause:** The message-processing goroutine was launched with the HTTP request context: ```go // Before (broken) go h.processMessage(r.Context(), payload) ``` When the handler returns HTTP 200, Go cancels `r.Context()`. The goroutine then hits its first database operation and fails with `context canceled`. **Fix:** ```go // After (fixed) go h.processMessage(context.WithoutCancel(r.Context()), payload) ``` `context.WithoutCancel` creates a copy of the parent context that is never canceled when the parent is — so the goroutine lives past the HTTP handler return. --- ## Port Conflict 2026-06-07 — Moved 8090 → 8091 **Root cause:** Colima (Docker runtime) maps `host.docker.internal:PORT → 127.0.0.1:PORT` on the Mac host. `openclaw/claude-proxy` was occupying `127.0.0.1:8090`, intercepting Balda's webhook traffic before it reached Balda. **Solution:** Changed Balda's listen port from `8090` to `8091` in `config.yaml`. ### Resolution Webhook bot URL updated in Zulip DB via `docker exec psql` on 2026-06-07: `http://host.docker.internal:8090/zulip/webhook` → `http://host.docker.internal:8091/zulip/webhook` --- ## DeepSeek Provider via norma-local Fork Balda's `openai` provider type in norma hardcoded `api.openai.com`. To support DeepSeek (or any OpenAI-compatible API), the norma source was forked locally: - Fork path: `~/Developer/norma-local` - Patched files: - `pkg/runtime/hostedagent/openai.go` — added `openAIBaseURL()` reading `OPENAI_BASE_URL` env var - `pkg/runtime/agentfactory/agentfactory.go` — removed MCP restriction for `openai` type - Env var `OPENAI_BASE_URL=https://api.deepseek.com/v1` is set in the launchd plist - go.mod `replace` directive (`normahq/norma v0.0.6 → ../norma-local`) is local only (not committed to the PR branch — needs a separate norma upstream PR or fork) To rebuild after patching norma: ```bash cd ~/Developer/balda go build -o balda ./cmd/balda/ ``` --- ## CLAUDECODE Environment Bug (Fixed 2026-06-07) When launched from an Eagle terminal session, Balda inherited `CLAUDECODE=1`, which caused the Claude Code CLI to refuse to start (it detected a nested invocation). **Fix:** Use `launchctl bootout + bootstrap` to start Balda clean — launchd does not inherit parent shell env vars. --- ## Config Snippet (key sections) ```yaml balda: global_instruction: | runtime: providers: deepseek: type: openai openai: api_key: "" model: deepseek-chat zulip: webhook: enabled: true listen: "0.0.0.0:8091" path: /zulip/webhook allowed_owners: - amartemyanov@duckduckgo.com ```