# ColonyOS Daemon — VM Deployment Guide

## Automated Provisioning (Recommended)

The fastest way to set up ColonyOS on a fresh Ubuntu 22.04+ VM:

```bash
# Clone the repo
git clone https://github.com/rangelak/ColonyOS.git /tmp/colonyos-setup
cd /tmp/colonyos-setup

# Run the provisioning script
sudo bash deploy/provision.sh

# With Slack support:
sudo bash deploy/provision.sh --slack

# Non-interactive (reads ANTHROPIC_API_KEY and GITHUB_TOKEN from env):
sudo ANTHROPIC_API_KEY=sk-ant-... GITHUB_TOKEN=ghp_... bash deploy/provision.sh --yes

# Preview what would be done:
sudo bash deploy/provision.sh --dry-run
```

The script handles everything: Python 3.11+, Node.js, GitHub CLI, pipx,
ColonyOS, systemd service, and environment file creation.

## Manual Setup

If you prefer manual control, follow these steps:

### Prerequisites

- Ubuntu 22.04+ (or similar Linux with systemd)
- Python 3.11-3.13 recommended
- Git with `gh` CLI authenticated
- Slack Bot Token (`COLONYOS_SLACK_BOT_TOKEN`) and App Token (`COLONYOS_SLACK_APP_TOKEN`)
- Anthropic API Key (`ANTHROPIC_API_KEY`)

### Steps

1. **Clone and install**:
   ```bash
   cd /opt/colonyos
   git clone <your-repo-url> repo
   cd repo
   python -m venv ../venv
   ../venv/bin/pip install -e ".[slack]"
   ```

2. **Configure environment** — create `/opt/colonyos/env` owned by the
   `colonyos` user:
   ```bash
   ANTHROPIC_API_KEY=sk-ant-...
   COLONYOS_SLACK_BOT_TOKEN=xoxb-...
   COLONYOS_SLACK_APP_TOKEN=xapp-...
   GITHUB_TOKEN=ghp_...
   ```
   ```bash
   sudo chown colonyos:colonyos /opt/colonyos/env
   sudo chmod 600 /opt/colonyos/env
   ```
   > **Tip:** For production deployments, consider using `systemd-creds`
   > or a secrets manager (e.g., HashiCorp Vault, AWS Secrets Manager)
   > instead of a plaintext env file.

3. **Initialize ColonyOS**:
   ```bash
   cd /opt/colonyos/repo
   ../venv/bin/colonyos init
   ```

4. **Configure daemon** — edit `.colonyos/config.yaml`:
   ```yaml
   daemon:
     daily_budget_usd: 500.0
     allow_all_control_users: true
     auto_recover_dirty_worktree: true
     github_poll_interval_seconds: 120
     ceo_cooldown_minutes: 60
   slack:
     enabled: true
     channels:
       - C12345678
   ```
   `slack.allowed_user_ids` is optional. If you leave it unset, any human user in
   the configured Slack channels can submit work into the queue. If you want to
   restrict queue submission to specific people, add their Slack user IDs under
   `slack.allowed_user_ids`.

   `daemon.allowed_control_user_ids` is a separate control-path allowlist for
   Slack pause/resume commands. Set `daemon.allow_all_control_users: true` if you
   want every Slack user in the configured channels to be able to send daemon
   control commands too.

   `daemon.auto_recover_dirty_worktree: true` is recommended only for a dedicated
   daemon checkout. It lets the daemon preserve dirty state to recovery/stash,
   reset the repo, and retry once when queue execution is blocked by a dirty
   worktree preflight failure.

5. **Install and start the service**:
   ```bash
   sudo cp deploy/colonyos-daemon.service /etc/systemd/system/
   sudo systemctl daemon-reload
   sudo systemctl enable colonyos
   sudo systemctl start colonyos
   ```

6. **Verify**:
   ```bash
   sudo systemctl status colonyos
   sudo journalctl -u colonyos -f
   ```

## Monitoring

- **Logs**: `journalctl -u colonyos --since "1 hour ago"`
- **Health**: `curl http://localhost:8741/healthz`
- **Slack**: The daemon posts heartbeat messages every 4 hours
- **Daily digest**: Summary posted at the configured UTC hour

## Troubleshooting

| Symptom | Check |
|---------|-------|
| Daemon won't start | `journalctl -u colonyos -e` for errors |
| No Slack messages | Verify `COLONYOS_SLACK_BOT_TOKEN` and `COLONYOS_SLACK_APP_TOKEN` in env file; if imports fail, reinstall with `../venv/bin/pip install -e ".[slack]"` and use Python 3.11-3.13 |
| Budget paused | Check `.colonyos/daemon_state.json` for `daily_spend_usd` |
| Circuit breaker active | Check `daemon_state.json` for `circuit_breaker_until` |
| Multiple instances | Check `.colonyos/runtime.lock` and `.colonyos/runtime_processes.json` for an active repo runtime before starting another daemon or standalone watcher |

## Updating

```bash
cd /opt/colonyos/repo
git pull
../venv/bin/pip install -e ".[slack]"
sudo systemctl restart colonyos
```
