> ## Documentation Index
> Fetch the complete documentation index at: https://ancplua.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Gateway runbook

# Gateway runbook

Use this page for day-1 startup and day-2 operations of the Gateway service.

<CardGroup>
  <Card title="Deep troubleshooting" icon="siren" href="/datzi/gateway/troubleshooting">
    Symptom-first diagnostics with exact command ladders and log signatures.
  </Card>

  <Card title="Configuration" icon="sliders" href="/datzi/gateway/configuration">
    Task-oriented setup guide + full configuration reference.
  </Card>
</CardGroup>

## 5-minute local startup

<Steps>
  <Step title="Start the Gateway">
    ```bash theme={null}
    datzi gateway --port 18789
    # debug/trace mirrored to stdio
    datzi gateway --port 18789 --verbose
    # force-kill listener on selected port, then start
    datzi gateway --force
    ```
  </Step>

  <Step title="Verify service health">
    ```bash theme={null}
    datzi gateway status
    datzi status
    datzi logs --follow
    ```

    Healthy baseline: `Runtime: running` and `RPC probe: ok`.
  </Step>

  <Step title="Validate channel readiness">
    ```bash theme={null}
    datzi channels status --probe
    ```
  </Step>
</Steps>

<Note>
  Gateway config reload watches the active config file path (resolved from
  profile/state defaults, or `DATZI_CONFIG_PATH` when set). Default mode is
  `gateway.reload.mode="hybrid"`.
</Note>

## Runtime model

* One always-on process for routing, control plane, and channel connections.
* Single multiplexed port for:
  * WebSocket control/RPC
  * HTTP APIs (OpenAI-compatible, Responses, tools invoke)
  * Control UI and hooks
* Default bind mode: `loopback`.
* Auth is required by default (`gateway.auth.token` / `gateway.auth.password`, or `DATZI_GATEWAY_TOKEN` /
  `DATZI_GATEWAY_PASSWORD`).

### Port and bind precedence

| Setting      | Resolution order                                           |
| ------------ | ---------------------------------------------------------- |
| Gateway port | `--port` → `DATZI_GATEWAY_PORT` → `gateway.port` → `18789` |
| Bind mode    | CLI/override → `gateway.bind` → `loopback`                 |

### Hot reload modes

| `gateway.reload.mode` | Behavior                                   |
| --------------------- | ------------------------------------------ |
| `off`                 | No config reload                           |
| `hot`                 | Apply only hot-safe changes                |
| `restart`             | Restart on reload-required changes         |
| `hybrid` (default)    | Hot-apply when safe, restart when required |

## Operator command set

```bash theme={null}
datzi gateway status
datzi gateway status --deep
datzi gateway status --json
datzi gateway install
datzi gateway restart
datzi gateway stop
datzi logs --follow
datzi doctor
```

## Remote access

Preferred: Tailscale/VPN.
Fallback: SSH tunnel.

```bash theme={null}
ssh -N -L 18789:127.0.0.1:18789 user@host
```

Then connect clients to `ws://127.0.0.1:18789` locally.

<Warning>
  If gateway auth is configured, clients still must send auth
  (`token`/`password`) even over SSH tunnels.
</Warning>

See: [Remote Gateway](/datzi/gateway/remote), [Authentication](/datzi/gateway/authentication), Tailscale.

## Supervision and service lifecycle

Use supervised runs for production-like reliability.

<Tabs>
  <Tab title="macOS (launchd)">
    ```bash theme={null}
    datzi gateway install
    datzi gateway status
    datzi gateway restart
    datzi gateway stop
    ```

    LaunchAgent labels are `ai.datzi.gateway` (default) or `ai.datzi.<profile>` (named profile). `datzi doctor` audits and repairs service config drift.
  </Tab>

  <Tab title="Linux (systemd user)">
    ```bash theme={null}
    datzi gateway install
    systemctl --user enable --now datzi-gateway[-<profile>].service
    datzi gateway status
    ```

    For persistence after logout, enable lingering:

    ```bash theme={null}
    sudo loginctl enable-linger <user>
    ```
  </Tab>

  <Tab title="Linux (system service)">
    Use a system unit for multi-user/always-on hosts.

    ```bash theme={null}
    sudo systemctl daemon-reload
    sudo systemctl enable --now datzi-gateway[-<profile>].service
    ```
  </Tab>
</Tabs>

## Multiple gateways on one host

Most setups should run **one** Gateway.
Use multiple only for strict isolation/redundancy (for example a rescue profile).

Checklist per instance:

* Unique `gateway.port`
* Unique `DATZI_CONFIG_PATH`
* Unique `DATZI_STATE_DIR`
* Unique `agents.defaults.workspace`

Example:

```bash theme={null}
DATZI_CONFIG_PATH=~/.datzi/a.json DATZI_STATE_DIR=~/.datzi-a datzi gateway --port 19001
DATZI_CONFIG_PATH=~/.datzi/b.json DATZI_STATE_DIR=~/.datzi-b datzi gateway --port 19002
```

See: Multiple gateways.

### Dev profile quick path

```bash theme={null}
datzi --dev setup
datzi --dev gateway --allow-unconfigured
datzi --dev status
```

Defaults include isolated state/config and base gateway port `19001`.

## Protocol quick reference (operator view)

* First client frame must be `connect`.
* Gateway returns `hello-ok` snapshot (`presence`, `health`, `stateVersion`, `uptimeMs`, limits/policy).
* Requests: `req(method, params)` → `res(ok/payload|error)`.
* Common events: `connect.challenge`, `agent`, `chat`, `presence`, `tick`, `health`, `heartbeat`, `shutdown`.

Agent runs are two-stage:

1. Immediate accepted ack (`status:"accepted"`)
2. Final completion response (`status:"ok"|"error"`), with streamed `agent` events in between.

See full protocol docs: Gateway Protocol.

## Operational checks

### Liveness

* Open WS and send `connect`.
* Expect `hello-ok` response with snapshot.

### Readiness

```bash theme={null}
datzi gateway status
datzi channels status --probe
datzi health
```

### Gap recovery

Events are not replayed. On sequence gaps, refresh state (`health`, `system-presence`) before continuing.

## Common failure signatures

| Signature                                                      | Likely issue                             |
| -------------------------------------------------------------- | ---------------------------------------- |
| `refusing to bind gateway ... without auth`                    | Non-loopback bind without token/password |
| `another gateway instance is already listening` / `EADDRINUSE` | Port conflict                            |
| `Gateway start blocked: set gateway.mode=local`                | Config set to remote mode                |
| `unauthorized` during connect                                  | Auth mismatch between client and gateway |

For full diagnosis ladders, use [Gateway Troubleshooting](/datzi/gateway/troubleshooting).

## Safety guarantees

* Gateway protocol clients fail fast when Gateway is unavailable (no implicit direct-channel fallback).
* Invalid/non-connect first frames are rejected and closed.
* Graceful shutdown emits `shutdown` event before socket close.

***

Related:

* [Troubleshooting](/datzi/gateway/troubleshooting)
* Background Process
* [Configuration](/datzi/gateway/configuration)
* [Health](/datzi/gateway/health)
* [Doctor](/datzi/gateway/troubleshooting)
* [Authentication](/datzi/gateway/authentication)
