From 1fdacec7c163d7ee489a950f2730fa07ab09450b Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Wed, 11 Feb 2026 21:43:05 +0000 Subject: [PATCH 1/9] docs: add initial docs/ information architecture + stubs --- docs/README.md | 24 ++++++++++++-------- docs/architecture/README.md | 10 ++++++++ docs/deployment/README.md | 14 ++++++++++-- docs/development/README.md | 16 +++++++++++++ docs/getting-started/README.md | 30 ++++++++++++++++++++++++ docs/operations/README.md | 10 ++++++++ docs/reference/api.md | 10 ++++++++ docs/reference/authentication.md | 30 ++++++++++++++++++++++++ docs/reference/configuration.md | 19 ++++++++++++++++ docs/style-guide.md | 39 ++++++++++++++++++++++++++++++++ docs/troubleshooting/README.md | 9 ++++++++ 11 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 docs/architecture/README.md create mode 100644 docs/development/README.md create mode 100644 docs/getting-started/README.md create mode 100644 docs/operations/README.md create mode 100644 docs/reference/api.md create mode 100644 docs/reference/authentication.md create mode 100644 docs/reference/configuration.md create mode 100644 docs/style-guide.md diff --git a/docs/README.md b/docs/README.md index 99fc18e8..4da650b4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,20 +1,24 @@ -# Mission Control docs +# Mission Control Docs -This folder is the starting point for Mission Control documentation. +This folder is the documentation home for **OpenClaw Mission Control**. -## Sections +## Start here -- [Development workflow](./03-development.md) -- [Testing guide](./testing/README.md) -- [Coverage policy](./coverage-policy.md) +- [Getting started](./getting-started/README.md) - [Deployment](./deployment/README.md) -- [Production notes](./production/README.md) +- [Development](./development/README.md) +- [Operations](./operations/README.md) - [Troubleshooting](./troubleshooting/README.md) - [Gateway agent provisioning and check-in troubleshooting](./troubleshooting/gateway-agent-provisioning.md) - [Gateway WebSocket protocol](./openclaw_gateway_ws.md) - [OpenClaw baseline configuration](./openclaw_baseline_config.md) -## Status +## Reference -These pages are minimal placeholders so repo-relative links stay healthy. The actual docs -information architecture will be defined in the Docs overhaul tasks. +- [Configuration reference](./reference/configuration.md) +- [Authentication](./reference/authentication.md) +- [API notes](./reference/api.md) + +## Contributing to docs + +- [Docs style guide](./style-guide.md) diff --git a/docs/architecture/README.md b/docs/architecture/README.md new file mode 100644 index 00000000..656db21c --- /dev/null +++ b/docs/architecture/README.md @@ -0,0 +1,10 @@ +# Architecture + +## High level + +- Frontend: Next.js +- Backend: FastAPI +- Database: Postgres + +> **Note** +> Add component diagrams and key data flows (auth, task lifecycle, gateway integration) as they solidify. diff --git a/docs/deployment/README.md b/docs/deployment/README.md index cb39e267..5cfc521d 100644 --- a/docs/deployment/README.md +++ b/docs/deployment/README.md @@ -1,3 +1,13 @@ -# Deployment guide +# Deployment -Placeholder. +This section covers deploying Mission Control in self-hosted environments. + +## Topics + +- Docker Compose (single host) +- Environment variables and secrets +- Database persistence and migrations +- Reverse proxy / TLS + +> **Note** +> This page is currently a stub; expand it as deployment patterns stabilize. diff --git a/docs/development/README.md b/docs/development/README.md new file mode 100644 index 00000000..f5f8f011 --- /dev/null +++ b/docs/development/README.md @@ -0,0 +1,16 @@ +# Development + +This section is for contributors developing Mission Control locally. + +## Useful commands + +From repo root: + +```bash +make help +make setup +make check +``` + +> **Note** +> Add deeper guides here (frontend, backend, DB/migrations) as the workflow stabilizes. diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md new file mode 100644 index 00000000..ae54f033 --- /dev/null +++ b/docs/getting-started/README.md @@ -0,0 +1,30 @@ +# Getting started + +## What is Mission Control? + +Mission Control is the web UI and HTTP API for operating OpenClaw. + +It provides a control plane for boards, tasks, agents, approvals, and (optionally) gateway connections. + +## Quickstart (Docker Compose) + +From repo root: + +```bash +cp .env.example .env + +# REQUIRED when AUTH_MODE=local +# Set LOCAL_AUTH_TOKEN to a non-placeholder value with at least 50 characters. + +docker compose -f compose.yml --env-file .env up -d --build +``` + +Open: +- Frontend: http://localhost:3000 +- Backend health: http://localhost:8000/healthz + +## Next steps + +- [Authentication](../reference/authentication.md) +- [Deployment](../deployment/README.md) +- [Development](../development/README.md) diff --git a/docs/operations/README.md b/docs/operations/README.md new file mode 100644 index 00000000..dce94e5b --- /dev/null +++ b/docs/operations/README.md @@ -0,0 +1,10 @@ +# Operations + +Runbooks and operational notes for running Mission Control. + +## Topics + +- Monitoring/metrics +- Backups +- Log locations and common errors +- Upgrade/rollback diff --git a/docs/reference/api.md b/docs/reference/api.md new file mode 100644 index 00000000..eab14351 --- /dev/null +++ b/docs/reference/api.md @@ -0,0 +1,10 @@ +# API notes + +- Backend defaults to http://localhost:8000 +- Health endpoints: + - `/health` + - `/healthz` + - `/readyz` + +> **Note** +> Add canonical API docs strategy here (OpenAPI, versioning, examples). diff --git a/docs/reference/authentication.md b/docs/reference/authentication.md new file mode 100644 index 00000000..b791ad73 --- /dev/null +++ b/docs/reference/authentication.md @@ -0,0 +1,30 @@ +# Authentication + +Mission Control supports two auth modes via `AUTH_MODE`: + +- `local`: shared bearer token auth for self-hosted deployments +- `clerk`: Clerk JWT auth + +## Local mode + +Backend: + +- `AUTH_MODE=local` +- `LOCAL_AUTH_TOKEN=` + +Frontend: + +- `NEXT_PUBLIC_AUTH_MODE=local` +- Provide the token via the login UI. + +## Clerk mode + +Backend: + +- `AUTH_MODE=clerk` +- `CLERK_SECRET_KEY=` + +Frontend: + +- `NEXT_PUBLIC_AUTH_MODE=clerk` +- `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=` diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md new file mode 100644 index 00000000..ae7037dc --- /dev/null +++ b/docs/reference/configuration.md @@ -0,0 +1,19 @@ +# Configuration reference + +This page collects the most important config values. + +## Root `.env` (Compose) + +See `.env.example` for defaults and required values. + +### `NEXT_PUBLIC_API_URL` + +- **Where set:** `.env` (frontend container environment) +- **Purpose:** Public URL the browser uses to call the backend. +- **Gotcha:** Must be reachable from the *browser* (host), not a Docker network alias. + +### `LOCAL_AUTH_TOKEN` + +- **Where set:** `.env` (backend) +- **When required:** `AUTH_MODE=local` +- **Policy:** Must be non-placeholder and at least 50 characters. diff --git a/docs/style-guide.md b/docs/style-guide.md new file mode 100644 index 00000000..bd75495a --- /dev/null +++ b/docs/style-guide.md @@ -0,0 +1,39 @@ +# Docs style guide + +## Principles + +- **Be concrete.** Prefer commands, examples, and “expected output” over prose. +- **Don’t invent behavior.** If unsure, link to the source file and mark it as “verify”. +- **Optimize for scanning.** Short sections, bullets, and tables. +- **Call out risk.** Anything destructive or security-sensitive should be labeled clearly. + +## Markdown conventions + +- Use sentence-case headings. +- Prefer fenced code blocks with a language (`bash`, `yaml`, `json`). +- For warnings/notes, use simple callouts: + +```md +> **Note** +> ... + +> **Warning** +> ... +``` + +## Common templates + +### Procedure + +1. Prereqs +2. Steps +3. Verify +4. Troubleshooting + +### Config reference entry + +- **Name** +- **Where set** (`.env`, env var, compose) +- **Default** +- **Example** +- **Notes / pitfalls** diff --git a/docs/troubleshooting/README.md b/docs/troubleshooting/README.md index ad2526ee..cb2efac4 100644 --- a/docs/troubleshooting/README.md +++ b/docs/troubleshooting/README.md @@ -1,3 +1,12 @@ # Troubleshooting - [Gateway agent provisioning and check-in](./gateway-agent-provisioning.md) + +## Common issues + +- Frontend can’t reach backend (check `NEXT_PUBLIC_API_URL`) +- Auth errors (check `AUTH_MODE`, tokens) +- DB connection/migrations + +> **Note** +> Expand with concrete symptoms + fixes as issues are discovered. From e477cffe7eddb1bf75f22740e26878bb5daf04fe Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Wed, 11 Feb 2026 22:52:47 +0000 Subject: [PATCH 2/9] docs: add testing + release checklist; fix contributing links --- CONTRIBUTING.md | 5 ++- docs/README.md | 4 +- docs/development/README.md | 49 ++++++++++++++++++++-- docs/release/README.md | 62 ++++++++++++++++++++++++++++ docs/testing/README.md | 83 +++++++++++++++++++++++++++++++++++++- 5 files changed, 195 insertions(+), 8 deletions(-) create mode 100644 docs/release/README.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c5303a1..c7d8d95c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,8 +11,9 @@ This repo welcomes contributions in three broad categories: ## Where to start - Docs landing page: [Docs landing](./docs/README.md) -- Development workflow: [Development workflow](./docs/03-development.md) -- Testing guide: [Testing guide](./docs/testing/README.md) +- Development workflow: [Development](./docs/development/README.md) +- Testing guide: [Testing](./docs/testing/README.md) +- Release checklist: [Release checklist](./docs/release/README.md) ## Filing issues diff --git a/docs/README.md b/docs/README.md index 4da650b4..6e424b76 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,8 +5,10 @@ This folder is the documentation home for **OpenClaw Mission Control**. ## Start here - [Getting started](./getting-started/README.md) -- [Deployment](./deployment/README.md) - [Development](./development/README.md) +- [Testing](./testing/README.md) +- [Deployment](./deployment/README.md) +- [Release checklist](./release/README.md) - [Operations](./operations/README.md) - [Troubleshooting](./troubleshooting/README.md) - [Gateway agent provisioning and check-in troubleshooting](./troubleshooting/gateway-agent-provisioning.md) diff --git a/docs/development/README.md b/docs/development/README.md index f5f8f011..045cfc77 100644 --- a/docs/development/README.md +++ b/docs/development/README.md @@ -2,15 +2,58 @@ This section is for contributors developing Mission Control locally. -## Useful commands +## Recommended workflow (fast loop) + +Run Postgres in Docker, run backend + frontend on your host. + +### 1) Start Postgres From repo root: +```bash +cp .env.example .env +docker compose -f compose.yml --env-file .env up -d db +``` + +### 2) Run the backend (dev) + +```bash +cd backend +cp .env.example .env + +uv sync --extra dev +uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 +``` + +Verify: + +```bash +curl -f http://localhost:8000/healthz +``` + +### 3) Run the frontend (dev) + +```bash +cd frontend +cp .env.example .env.local +npm install +npm run dev +``` + +Open http://localhost:3000. + +## Useful repo-root commands + ```bash make help make setup make check ``` -> **Note** -> Add deeper guides here (frontend, backend, DB/migrations) as the workflow stabilizes. +- `make setup`: sync backend + frontend deps +- `make check`: lint + typecheck + tests + build (closest CI parity) + +## Related docs + +- [Testing](../testing/README.md) +- [Release checklist](../release/README.md) diff --git a/docs/release/README.md b/docs/release/README.md new file mode 100644 index 00000000..f7287ae6 --- /dev/null +++ b/docs/release/README.md @@ -0,0 +1,62 @@ +# Release checklist + +This is a lightweight, operator-friendly checklist for releasing Mission Control. + +> Goal: **no data loss** and **near-zero (ideally zero) user-visible downtime**. + +## Before you release + +- [ ] Confirm the target version/commit SHA. +- [ ] Review merged PRs since last release (especially DB schema/auth changes). +- [ ] Ensure CI is green on the target SHA. +- [ ] Confirm you have: + - [ ] access to the host(s) + - [ ] access to Postgres backups (or snapshots) + - [ ] a rollback plan + +## Database safety + +- [ ] Verify migrations are **backward compatible** with the current running app (if doing rolling deploys). +- [ ] Take a backup / snapshot. +- [ ] If migrations are risky or not backward compatible, schedule a maintenance window. + +## Deploy (Docker Compose) + +- [ ] Pull / build the new images (or update the repo checkout). +- [ ] Apply migrations (if you run them manually): + +```bash +# example: if running backend locally on the host +cd backend +uv run alembic upgrade head +``` + +- [ ] Restart services with minimal disruption: + +```bash +docker compose -f compose.yml --env-file .env up -d --build +``` + +## Post-deploy verification + +- [ ] Backend health: `GET /healthz` returns 200 +- [ ] Backend readiness: `GET /readyz` returns 200 +- [ ] Frontend loads (no console spam) +- [ ] Login works (local/clerk mode) +- [ ] Core flows work end-to-end: + - [ ] View board + - [ ] Create/update a task + - [ ] Post a comment + - [ ] Heartbeat check-in succeeds + +## Rollback (if needed) + +- [ ] Roll back the app version (compose / images). +- [ ] If migrations were applied and are not reversible, rollbacks may require a DB restore. + +## Notes to keep this honest + +- If you add a new operational dependency (e.g., redis), update: + - `README.md` (overview + quickstart) + - `docs/deployment/README.md` + - this checklist diff --git a/docs/testing/README.md b/docs/testing/README.md index 80dcee45..3d56f4bd 100644 --- a/docs/testing/README.md +++ b/docs/testing/README.md @@ -1,3 +1,82 @@ -# Testing guide +# Testing -Placeholder: see root `README.md` and `CONTRIBUTING.md` for current commands. +This guide describes how to run Mission Control tests locally. + +## Quick start (repo root) + +```bash +make setup +make check +``` + +`make check` is the closest thing to “CI parity”: + +- backend: lint + typecheck + unit tests (with scoped coverage gate) +- frontend: lint + typecheck + unit tests (Vitest) + production build + +## Backend tests + +From repo root: + +```bash +make backend-test +make backend-coverage +``` + +Or from `backend/`: + +```bash +cd backend +uv run pytest +``` + +Notes: + +- Some tests may require a running Postgres (see root `compose.yml`). +- `make backend-coverage` enforces a strict coverage gate on a scoped set of modules. + +## Frontend tests + +From repo root: + +```bash +make frontend-test +``` + +Or from `frontend/`: + +```bash +cd frontend +npm run test +npm run test:watch +``` + +## End-to-end (Cypress) + +The frontend has Cypress configured in `frontend/cypress/`. + +Typical flow: + +1) Start the stack (or start backend + frontend separately) +2) Run Cypress + +Example (two terminals): + +```bash +# terminal 1 +cp .env.example .env +docker compose -f compose.yml --env-file .env up -d --build +``` + +```bash +# terminal 2 +cd frontend +npm run e2e +``` + +Or run interactively: + +```bash +cd frontend +npm run e2e:open +``` From a3a9a12a0201bb64f32e1bf97d3a010f385a0e6a Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Thu, 12 Feb 2026 00:15:04 +0000 Subject: [PATCH 3/9] docs: flesh out deployment + operations runbooks --- docs/deployment/README.md | 101 +++++++++++++++++++++++++++++++++++--- docs/operations/README.md | 82 +++++++++++++++++++++++++++++-- 2 files changed, 171 insertions(+), 12 deletions(-) diff --git a/docs/deployment/README.md b/docs/deployment/README.md index 5cfc521d..a65acb0d 100644 --- a/docs/deployment/README.md +++ b/docs/deployment/README.md @@ -2,12 +2,99 @@ This section covers deploying Mission Control in self-hosted environments. -## Topics +> **Goal** +> A simple, reproducible deploy that preserves the Postgres volume and supports safe upgrades. -- Docker Compose (single host) -- Environment variables and secrets -- Database persistence and migrations -- Reverse proxy / TLS +## Deployment mode: single host (Docker Compose) -> **Note** -> This page is currently a stub; expand it as deployment patterns stabilize. +### Prerequisites + +- Docker + Docker Compose v2 (`docker compose`) +- A host where the **browser** can reach the backend URL you configure (see `NEXT_PUBLIC_API_URL` below) + +### 1) Configure environment + +From repo root: + +```bash +cp .env.example .env +``` + +Edit `.env`: + +- `AUTH_MODE=local` (default) +- **Set** `LOCAL_AUTH_TOKEN` to a non-placeholder value (≥ 50 chars) +- Ensure `NEXT_PUBLIC_API_URL` is reachable from the browser (not a Docker-internal hostname) + +Key variables (from `.env.example` / `compose.yml`): + +- Frontend: `FRONTEND_PORT` (default `3000`) +- Backend: `BACKEND_PORT` (default `8000`) +- Postgres: `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_PORT` +- Backend: + - `DB_AUTO_MIGRATE` (default `true` in compose) + - `CORS_ORIGINS` (default `http://localhost:3000`) + +### 2) Start the stack + +```bash +docker compose -f compose.yml --env-file .env up -d --build +``` + +Open: + +- Frontend: `http://localhost:${FRONTEND_PORT:-3000}` +- Backend health: `http://localhost:${BACKEND_PORT:-8000}/healthz` + +### 3) Verify + +```bash +curl -f "http://localhost:${BACKEND_PORT:-8000}/healthz" +``` + +If the frontend loads but API calls fail, double-check: + +- `NEXT_PUBLIC_API_URL` is set and reachable from the **browser** +- backend CORS includes the frontend origin (`CORS_ORIGINS`) + +## Database persistence + +The Compose stack uses a named volume: + +- `postgres_data` → `/var/lib/postgresql/data` + +This means: + +- `docker compose ... down` preserves data +- `docker compose ... down -v` is **destructive** (deletes the DB volume) + +## Migrations / upgrades + +### Default behavior in Compose + +In `compose.yml`, the backend container defaults: + +- `DB_AUTO_MIGRATE=true` + +So on startup the backend will attempt to run Alembic migrations automatically. + +> **Warning** +> For zero/near-zero downtime, migrations must be **backward compatible** with the currently running app if you do rolling deploys. + +### Safer operator pattern (manual migrations) + +If you want more control, set `DB_AUTO_MIGRATE=false` and run migrations explicitly during deploy: + +```bash +cd backend +uv run alembic upgrade head +``` + +## Reverse proxy / TLS + +Typical setup (outline): + +- Put the frontend behind HTTPS (reverse proxy) +- Ensure the frontend can reach the backend over the configured `NEXT_PUBLIC_API_URL` + +This section is intentionally minimal until we standardize a recommended proxy (Caddy/Nginx/Traefik). diff --git a/docs/operations/README.md b/docs/operations/README.md index dce94e5b..9dbfcfa9 100644 --- a/docs/operations/README.md +++ b/docs/operations/README.md @@ -2,9 +2,81 @@ Runbooks and operational notes for running Mission Control. -## Topics +## Health checks -- Monitoring/metrics -- Backups -- Log locations and common errors -- Upgrade/rollback +Backend exposes: + +- `/healthz` — liveness +- `/readyz` — readiness + +Example: + +```bash +curl -f http://localhost:8000/healthz +curl -f http://localhost:8000/readyz +``` + +## Logs + +### Docker Compose + +```bash +# tail everything +docker compose -f compose.yml --env-file .env logs -f --tail=200 + +# tail just backend +docker compose -f compose.yml --env-file .env logs -f --tail=200 backend +``` + +The backend supports slow-request logging via `REQUEST_LOG_SLOW_MS`. + +## Backups + +The DB runs in Postgres (Compose `db` service) and persists to the `postgres_data` named volume. + +### Minimal backup (logical) + +Example with `pg_dump` (run on the host): + +```bash +# uses values from .env +export POSTGRES_DB=mission_control +export POSTGRES_USER=postgres +export POSTGRES_PASSWORD=postgres +export POSTGRES_PORT=5432 + +PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \ + -h 127.0.0.1 -p "$POSTGRES_PORT" -U "$POSTGRES_USER" \ + -d "$POSTGRES_DB" \ + --format=custom > mission_control.backup +``` + +> **Note** +> For real production, prefer automated backups + retention + periodic restore drills. + +## Upgrades / rollbacks + +### Upgrade (Compose) + +```bash +docker compose -f compose.yml --env-file .env up -d --build +``` + +### Rollback + +Rollback typically means deploying a previous image/commit. + +> **Warning** +> If you applied non-backward-compatible DB migrations, rolling back the app may require restoring the database. + +## Common issues + +### Frontend loads but API calls fail + +- Confirm `NEXT_PUBLIC_API_URL` is set and reachable from the browser. +- Confirm backend CORS includes the frontend origin (`CORS_ORIGINS`). + +### Auth mismatch + +- Backend: `AUTH_MODE` (`local` or `clerk`) +- Frontend: `NEXT_PUBLIC_AUTH_MODE` should match From 32e8855404bbd5da4ffbe58c50f240c8ce4c7844 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Thu, 12 Feb 2026 08:14:36 +0000 Subject: [PATCH 4/9] docs(api): document auth, request ids, errors, examples --- docs/reference/api.md | 145 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 7 deletions(-) diff --git a/docs/reference/api.md b/docs/reference/api.md index eab14351..77e83c13 100644 --- a/docs/reference/api.md +++ b/docs/reference/api.md @@ -1,10 +1,141 @@ -# API notes +# API reference (notes + conventions) -- Backend defaults to http://localhost:8000 +Mission Control exposes a JSON HTTP API (FastAPI) under `/api/v1/*`. + +- Default backend base URL (local): `http://localhost:8000` - Health endpoints: - - `/health` - - `/healthz` - - `/readyz` + - `GET /health` (liveness) + - `GET /healthz` (liveness alias) + - `GET /readyz` (readiness) -> **Note** -> Add canonical API docs strategy here (OpenAPI, versioning, examples). +## OpenAPI / Swagger + +- OpenAPI schema: `GET /openapi.json` +- Swagger UI (FastAPI default): `GET /docs` + +> If you are building clients, prefer generating from `openapi.json`. + +## API versioning + +- Current prefix: `/api/v1` +- Backwards compatibility is **best-effort** while the project is under active development. + +## Authentication + +All protected endpoints expect a bearer token: + +```http +Authorization: Bearer +``` + +Auth mode is controlled by `AUTH_MODE`: + +- `local`: shared bearer token auth (token is `LOCAL_AUTH_TOKEN`) +- `clerk`: Clerk JWT auth + +Notes: +- The frontend uses the same bearer token scheme in local mode (users paste the token into the UI). +- Many “agent” endpoints use an agent token header instead (see below). + +### Agent auth (Mission Control agents) + +Some endpoints are designed for autonomous agents and use an agent token header: + +```http +X-Agent-Token: +``` + +In the backend, these are enforced via the “agent auth” context. When in doubt, consult the route’s dependencies (e.g., `require_admin_or_agent`). + +## Authorization / permissions model (high level) + +The backend distinguishes between: + +- **users** (humans) authenticated via `AUTH_MODE` +- **agents** authenticated via agent tokens + +Common patterns: + +- **Admin-only** user endpoints: require an authenticated user with admin privileges. +- **Admin or agent** endpoints: allow either an admin user or an authenticated agent. +- **Board-scoped access**: user/agent access may be restricted to a specific board. + +> SOC2 note: the API produces an audit-friendly request id (see below), but role/permission policy should be documented per endpoint as we stabilize. + +## Request IDs + +Every response includes an `X-Request-Id` header. + +- Clients may supply their own `X-Request-Id`; otherwise the server generates one. +- Use this id to correlate client reports with server logs. + +## Errors + +Errors are returned as JSON with a stable top-level shape: + +```json +{ + "detail": "...", + "request_id": "..." +} +``` + +Common status codes: + +- `401 Unauthorized`: missing/invalid credentials +- `403 Forbidden`: authenticated but not allowed +- `404 Not Found`: resource missing (or not visible) +- `422 Unprocessable Entity`: request validation error +- `500 Internal Server Error`: unhandled server errors + +Validation errors (`422`) typically return `detail` as a list of structured field errors (FastAPI/Pydantic style). + +## Pagination + +List endpoints commonly return an `items` array with paging fields (varies by endpoint). If you’re implementing new list endpoints, prefer consistent parameters: + +- `limit` +- `offset` + +…and return: + +- `items: []` +- `total` +- `limit` +- `offset` + +## Examples (curl) + +### Health + +```bash +curl -f http://localhost:8000/healthz +``` + +### Agent heartbeat check-in + +```bash +curl -s -X POST http://localhost:8000/api/v1/agent/heartbeat \ + -H "X-Agent-Token: $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"name":"Tessa","board_id":"","status":"online"}' +``` + +### List tasks for a board + +```bash +curl -s "http://localhost:8000/api/v1/agent/boards//tasks?status=inbox&limit=10" \ + -H "X-Agent-Token: $AUTH_TOKEN" +``` + +## Gaps / follow-ups + +- Per-endpoint documentation of: + - required auth header (`Authorization` vs `X-Agent-Token`) + - required role (admin vs member vs agent) + - common error responses per endpoint +- Rate limits are not currently specified in the docs; if enforced, document them here and in OpenAPI. +- Add canonical examples for: + - creating/updating tasks + comments + - board memory streaming + - approvals workflow From a21226557366b02c32bac15eedb7c7f2815c2d59 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Thu, 12 Feb 2026 13:47:39 +0000 Subject: [PATCH 5/9] fix(mypy): cast legacy approval task_id after None-check --- backend/app/services/approval_task_links.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/backend/app/services/approval_task_links.py b/backend/app/services/approval_task_links.py index 595cabd3..6d513387 100644 --- a/backend/app/services/approval_task_links.py +++ b/backend/app/services/approval_task_links.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections.abc import Iterable, Sequence -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, cast from uuid import UUID from sqlalchemy import case, delete, exists, func @@ -266,8 +266,9 @@ async def task_counts_for_board( for legacy_task_id, total, pending in list(await session.exec(legacy_statement)): if legacy_task_id is None: continue - previous = counts.get(legacy_task_id, (0, 0)) - counts[legacy_task_id] = ( + task_uuid = cast(UUID, legacy_task_id) + previous = counts.get(task_uuid, (0, 0)) + counts[task_uuid] = ( previous[0] + int(total or 0), previous[1] + int(pending or 0), ) From 17dd8c549badc90b664485ccc6ee301014132ce3 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Fri, 13 Feb 2026 21:51:52 +0000 Subject: [PATCH 6/9] fix(mypy): remove redundant UUID cast --- backend/app/services/approval_task_links.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/services/approval_task_links.py b/backend/app/services/approval_task_links.py index 6d513387..6cb16104 100644 --- a/backend/app/services/approval_task_links.py +++ b/backend/app/services/approval_task_links.py @@ -266,7 +266,7 @@ async def task_counts_for_board( for legacy_task_id, total, pending in list(await session.exec(legacy_statement)): if legacy_task_id is None: continue - task_uuid = cast(UUID, legacy_task_id) + task_uuid = legacy_task_id previous = counts.get(task_uuid, (0, 0)) counts[task_uuid] = ( previous[0] + int(total or 0), From 4321a7f71145681544be7a603567d98fdb8e914b Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Fri, 13 Feb 2026 21:56:12 +0000 Subject: [PATCH 7/9] fix(lint): remove unused typing.cast import --- backend/app/services/approval_task_links.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/services/approval_task_links.py b/backend/app/services/approval_task_links.py index 6cb16104..8013ad4a 100644 --- a/backend/app/services/approval_task_links.py +++ b/backend/app/services/approval_task_links.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections.abc import Iterable, Sequence -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from uuid import UUID from sqlalchemy import case, delete, exists, func From 7fa0959f63e9d920cc4dba07d2651692d742a744 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sun, 15 Feb 2026 04:15:38 +0000 Subject: [PATCH 8/9] docs: use sentence-case heading in docs landing --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 6e424b76..39fa9bff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,4 +1,4 @@ -# Mission Control Docs +# Mission Control docs This folder is the documentation home for **OpenClaw Mission Control**. From bee40c36cdc3a850648027ee7dd34dc04233707e Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Tue, 3 Mar 2026 05:17:31 +0530 Subject: [PATCH 9/9] fix: address PR #100 review comments --- backend/app/services/approval_task_links.py | 5 ++--- docs/operations/README.md | 14 +++++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/backend/app/services/approval_task_links.py b/backend/app/services/approval_task_links.py index 8013ad4a..595cabd3 100644 --- a/backend/app/services/approval_task_links.py +++ b/backend/app/services/approval_task_links.py @@ -266,9 +266,8 @@ async def task_counts_for_board( for legacy_task_id, total, pending in list(await session.exec(legacy_statement)): if legacy_task_id is None: continue - task_uuid = legacy_task_id - previous = counts.get(task_uuid, (0, 0)) - counts[task_uuid] = ( + previous = counts.get(legacy_task_id, (0, 0)) + counts[legacy_task_id] = ( previous[0] + int(total or 0), previous[1] + int(pending or 0), ) diff --git a/docs/operations/README.md b/docs/operations/README.md index 9dbfcfa9..42546271 100644 --- a/docs/operations/README.md +++ b/docs/operations/README.md @@ -39,11 +39,15 @@ The DB runs in Postgres (Compose `db` service) and persists to the `postgres_dat Example with `pg_dump` (run on the host): ```bash -# uses values from .env -export POSTGRES_DB=mission_control -export POSTGRES_USER=postgres -export POSTGRES_PASSWORD=postgres -export POSTGRES_PORT=5432 +# load variables from .env (trusted file only) +set -a +. ./.env +set +a + +: "${POSTGRES_DB:?set POSTGRES_DB in .env}" +: "${POSTGRES_USER:?set POSTGRES_USER in .env}" +: "${POSTGRES_PORT:?set POSTGRES_PORT in .env}" +: "${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env (strong, unique value; not \"postgres\")}" PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \ -h 127.0.0.1 -p "$POSTGRES_PORT" -U "$POSTGRES_USER" \