feat: ship agent-first mission control v0.2.57
This commit is contained in:
@@ -1,7 +1,43 @@
|
||||
# Nexus
|
||||
|
||||
Nexus is the operations platform for the Noveria ecosystem. OpenClaw is an
|
||||
adapter-backed agent runtime, not a dependency of the frontend or domain model.
|
||||
Nexus is the operations platform for the Noveria ecosystem. OpenClaw is the
|
||||
mandatory agent runtime and gateway behind the Nexus control plane; it remains
|
||||
isolated from the frontend and the Nexus domain model.
|
||||
|
||||
> **Project audit (2026-07-26, commit `3bc7622`):**
|
||||
> [analysis](docs/PROJECT_ANALYSIS_2026-07-26.md),
|
||||
> [all-page audit](docs/audits/2026-07-26/PAGE_AUDIT.md),
|
||||
> [security spot check](docs/SECURITY_SPOT_CHECK_2026-07-26.md), and
|
||||
> [evaluation](docs/PROJECT_EVALUATION_2026-07-26.md).
|
||||
|
||||
> **Agent-first evaluation (2026-07-27):**
|
||||
> [all-page and capability evaluation](docs/audits/2026-07-27/agent-first-evaluation/PAGE_AND_CAPABILITY_EVALUATION.md),
|
||||
> [mission-control target contract](docs/AGENT_FIRST_MISSION_CONTROL.md), and
|
||||
> [canonical roadmap](docs/MISSION_CONTROL_ROADMAP.md).
|
||||
|
||||
> **OpenClaw core integration checkpoint (2026-07-28):**
|
||||
> [implementation evidence](docs/audits/2026-07-28/openclaw-core-integration/IMPLEMENTATION_EVIDENCE.md),
|
||||
> [route evaluation](docs/audits/2026-07-28/openclaw-core-integration/ROUTE_EVALUATION.md),
|
||||
> and [design QA](docs/audits/2026-07-28/openclaw-core-integration/design-qa.md).
|
||||
|
||||
> **OpenClaw agent-first hardening checkpoint (2026-07-30):**
|
||||
> [acceptance evidence](docs/audits/2026-07-30/openclaw-agent-first-hardening/ACCEPTANCE_EVIDENCE.md),
|
||||
> [route and agent-first evaluation](docs/audits/2026-07-30/openclaw-agent-first-hardening/ROUTE_AND_AGENT_FIRST_EVALUATION.md),
|
||||
> [Gateway connection contract](docs/OPENCLAW_GATEWAY_CONNECTION.md), and
|
||||
> [agent-first target contract](docs/AGENT_FIRST_MISSION_CONTROL.md).
|
||||
>
|
||||
> **OpenClaw Attach & Adopt checkpoint (2026-07-30):**
|
||||
> [implementation and acceptance](docs/audits/2026-07-30/openclaw-attach-adopt/IMPLEMENTATION_AND_ACCEPTANCE.md)
|
||||
> and
|
||||
> [structural proof preflight](docs/audits/2026-07-30/openclaw-attach-adopt/STRUCTURAL_PROOF_PREFLIGHT.md).
|
||||
>
|
||||
> **Agent-first and Performance V2 checkpoint (2026-07-30):**
|
||||
> [implementation and acceptance](docs/audits/2026-07-30/agent-first-performance-v2/IMPLEMENTATION_AND_ACCEPTANCE.md),
|
||||
> [agent-first target contract](docs/AGENT_FIRST_MISSION_CONTROL.md), and
|
||||
> [QA automation boundaries](docs/QA_AUTOMATION.md).
|
||||
>
|
||||
> **Structured operation results checkpoint (2026-07-31):**
|
||||
> [implementation and acceptance](docs/audits/2026-07-31/operation-results-deep-links/IMPLEMENTATION_AND_ACCEPTANCE.md).
|
||||
|
||||
> 📋 **Architektur-Review** (2026-06-22): Board-first Orchestrierung, sichere
|
||||
> Backend-Brücke und Gateway-Integration geprüft. Siehe
|
||||
@@ -18,110 +54,132 @@ adapter-backed agent runtime, not a dependency of the frontend or domain model.
|
||||
- Vue 3, TypeScript, Pinia, Vue Router and Tailwind CSS
|
||||
- ASP.NET Core 10 REST API (Minimal API pattern)
|
||||
- Entity Framework Core and PostgreSQL
|
||||
- generated OpenAPI 3.1 contracts with `openapi-typescript` and `openapi-fetch`
|
||||
- TanStack Vue Query for migrated server-state domains
|
||||
- PostgreSQL transactional outbox and a sequenced domain-event stream
|
||||
- OpenTelemetry instrumentation and allow-listed browser Web Vitals
|
||||
- JWT owner authentication with rotating refresh sessions
|
||||
- `IAgentRuntime` abstraction with an OpenClaw adapter (Ollama and NVIDIA removed — OpenClaw-only)
|
||||
- `IAgentRuntime` abstraction with OpenClaw as the currently registered runtime
|
||||
- protocol-v4 `IGatewayConnector` and browser-safe `IOpenClawControlService`
|
||||
- owner-only OpenClaw Attach & Adopt setup with one persisted `primary` profile
|
||||
- live OpenClaw agent files, schema-based config and cron management through RPC
|
||||
- owner-approved agent proposals with durable provisioning recovery
|
||||
- keyset-paginated Task Board with targeted live card reconciliation
|
||||
- structured mutation results with entity references, trace metadata and
|
||||
cross-page frontend deep links
|
||||
- Responsive dark-mode operations dashboard
|
||||
- Traefik reverse-proxy with Let's Encrypt TLS on `nexus.noveria.net`
|
||||
|
||||
## Product target
|
||||
|
||||
Nexus is the primary daily control plane for agents, tasks, runs, approvals,
|
||||
tools, schedules, knowledge and operational recovery. All agent and model
|
||||
execution travels through OpenClaw; OpenAI is the intended primary provider
|
||||
configured inside OpenClaw. Nexus does not call OpenAI directly. The browser
|
||||
and Nexus domain model stay independent of gateway and provider internals.
|
||||
|
||||
The binding product and architecture direction is documented in
|
||||
[Agent-First Mission Control](docs/AGENT_FIRST_MISSION_CONTROL.md); the ordered
|
||||
feature plan is the [Mission Control Roadmap](docs/MISSION_CONTROL_ROADMAP.md).
|
||||
|
||||
## Local/container start
|
||||
|
||||
```bash
|
||||
cp .env.template .env
|
||||
# Replace every placeholder, especially POSTGRES_PASSWORD, JWT_KEY and BOOTSTRAP_OWNER_EMAIL.
|
||||
# Replace every placeholder, especially POSTGRES_PASSWORD, JWT_KEY,
|
||||
# BOOTSTRAP_OWNER_EMAIL, BOOTSTRAP_OWNER_PASSWORD and the OpenClaw credential.
|
||||
# Pin OPENCLAW_REQUIRED_VERSION for a production deployment.
|
||||
docker compose up --build -d
|
||||
curl http://127.0.0.1:18880/health
|
||||
```
|
||||
|
||||
On an empty database the API creates exactly one owner from `BOOTSTRAP_OWNER_EMAIL`,
|
||||
derives the initial display name from that email, and logs a generated temporary password once.
|
||||
derives the initial display name from that email, and hashes the explicitly configured
|
||||
`BOOTSTRAP_OWNER_PASSWORD`. Bootstrap credentials are never written to application logs.
|
||||
After first seed the password lives only in PostgreSQL. Existing databases are
|
||||
never overwritten by the bootstrap process.
|
||||
|
||||
The API is exposed via Traefik reverse-proxy with automatic Let's Encrypt TLS.
|
||||
Health checks, rate limiting, and security headers are active.
|
||||
|
||||
## Workspace mounts
|
||||
## OpenClaw runtime data
|
||||
|
||||
The API container mounts agent workspaces from the host for file browsing
|
||||
and the config editor. These are mounted under `/mnt/workspace-{agentId}`:
|
||||
OpenClaw remains authoritative for its agents, bootstrap files, arbitrary
|
||||
workspace files, configuration and cron jobs. Nexus does not copy this state
|
||||
into a competing configuration:
|
||||
|
||||
| Host path | Container mount |
|
||||
|---|---|
|
||||
| `/home/projekte_bao/openclaw/data/openclaw/workspace-iris` | `/mnt/workspace-iris` |
|
||||
| `/home/projekte_bao/openclaw/data/openclaw/workspace-programmer` | `/mnt/workspace-programmer` |
|
||||
| `/home/projekte_bao/openclaw/data/openclaw/workspace-reviewer` | `/mnt/workspace-reviewer` |
|
||||
| `/home/projekte_bao/openclaw/data/openclaw/workspace-architekt` | `/mnt/workspace-architekt` |
|
||||
| `/home/projekte_bao/openclaw/data/openclaw/workspace-researcher` | `/mnt/workspace-researcher` |
|
||||
| `/home/projekte_bao/openclaw/data/openclaw/workspace-executor` | `/mnt/workspace-executor` |
|
||||
- agent inventory comes from `agents.list`;
|
||||
- supported bootstrap files are read and written through
|
||||
`agents.files.list/get/set`;
|
||||
- additional workspace files are browsed read-only through
|
||||
`agents.workspace.list/get`; and
|
||||
- OpenClaw configuration is read and patched through
|
||||
`config.schema.lookup`, `config.get` and `config.patch`.
|
||||
|
||||
Agent inventory and configuration therefore do not depend on a
|
||||
`/mnt/workspace-{agentId}` naming convention. The owner-only Nexus
|
||||
Memory/Docs/Incidents read surfaces also resolve their live content through
|
||||
OpenClaw RPC. Their DTOs retain the source agent and safe workspace path so the
|
||||
UI can show provenance without mounting or inferring a host workspace.
|
||||
|
||||
## Frontend architecture
|
||||
|
||||
### Source layout
|
||||
### Server-state and API boundary
|
||||
|
||||
```
|
||||
frontend/src/
|
||||
├── App.vue # Root shell with sidebar + standalone views
|
||||
├── main.ts # App bootstrap
|
||||
├── router.ts # Vue Router config
|
||||
├── types/
|
||||
│ ├── index.ts # Re-exports
|
||||
│ ├── agent.ts # AgentInfo, AgentDetail, TeamMember
|
||||
│ ├── config.ts # ConfigFileInfo, SecurityStatus
|
||||
│ ├── dashboard.ts # OperationsSnapshot, RuntimeStatus, etc.
|
||||
│ └── project.ts # MemoryFile, DocFile types
|
||||
├── stores/
|
||||
│ ├── auth.ts # Auth store (JWT, login/refresh/logout)
|
||||
│ └── operations.ts # Operations store (snapshot, CRUD, approve/reject)
|
||||
├── services/
|
||||
│ └── api.ts # Authenticated fetch wrapper (auto-refresh)
|
||||
├── composables/
|
||||
│ └── useTime.ts # Greeting composable (Morgen/Tag/Abend)
|
||||
├── views/
|
||||
│ ├── LoginView.vue
|
||||
│ ├── DashboardView.vue # New dashboard (Phase 2)
|
||||
│ ├── ProjectDetailView.vue
|
||||
│ ├── SettingsView.vue
|
||||
│ ├── MemoryView.vue
|
||||
│ ├── DocsView.vue
|
||||
│ ├── TeamView.vue
|
||||
│ ├── SecurityView.vue
|
||||
│ ├── IncidentsView.vue
|
||||
│ ├── CalendarView.vue
|
||||
│ ├── AgentDetailView.vue
|
||||
│ └── AgentsIndexView.vue
|
||||
├── components/
|
||||
│ ├── layout/
|
||||
│ │ ├── AppSidebar.vue
|
||||
│ │ └── AppHeader.vue
|
||||
│ └── dashboard/ # New dashboard components (Phase 2)
|
||||
│ ├── IrisPanel.vue # Agent overview + metrics + chat
|
||||
│ ├── OperationsFeed.vue # Live activity feed with filters
|
||||
│ ├── AgendaPanel.vue # Daily agenda with checkboxes + localStorage
|
||||
│ ├── ActiveInitiatives.vue # Project cards with progress
|
||||
│ └── RecentlyFinished.vue # Quick status chips
|
||||
└── ModuleView.vue
|
||||
```
|
||||
- `backend/openapi/Nexus.Api.json` is the checked-in OpenAPI 3.1 contract.
|
||||
`pnpm openapi:generate` produces
|
||||
`frontend/src/api/generated/schema.d.ts`; CI rejects generated drift.
|
||||
- `frontend/src/api/` owns generated DTO use, typed requests, Query keys and
|
||||
the common `ProblemDetails` adapter. Views must not reimplement transport
|
||||
contracts.
|
||||
- TanStack Vue Query owns canonical reads for the Task Board, projects,
|
||||
proposals, activity, notifications and the OpenClaw agent, overview, run,
|
||||
cron, model, content and security domains. Shared Query keys deduplicate
|
||||
consumers and preserve visible data during background refresh.
|
||||
- Pinia remains only for authentication, navigation/modals, local drafts,
|
||||
setup/wizard workflow state and shared command facades. It is not a second
|
||||
cache for canonical runtime collections.
|
||||
- A single authenticated fetch-based SSE hub parses domain events with a
|
||||
bounded buffer, token refresh, abort, heartbeat and jittered reconnect.
|
||||
Content-minimized deltas patch or invalidate only affected Query domains.
|
||||
- The old operations/task/notification/dashboard server-state stores, static
|
||||
agent sources, duplicate live-sync modules and per-view SSE readers have
|
||||
been removed after route and error-state parity checks.
|
||||
|
||||
### App.vue `standaloneViews` whitelist
|
||||
### App.vue route rendering
|
||||
|
||||
New views must be registered in the `standaloneViews` computed property in
|
||||
`App.vue` (line ~34). Without this entry, `RouterView` will not render the
|
||||
component — the route is valid but the template stays empty.
|
||||
`/dashboard` uses `NexusLayout`; `/login` renders directly. Routes with
|
||||
`meta.standalone` render their registered view inside the shared legacy shell.
|
||||
Projects, Models and Activity are dedicated typed views. Iris chat is a
|
||||
global, on-demand modal on authenticated routes and has no separate `/chat`
|
||||
route.
|
||||
|
||||
### New dashboard (Phase 2)
|
||||
### Live orchestration dashboard
|
||||
|
||||
The dashboard was redesigned with a three-column layout:
|
||||
The dashboard prioritizes the live agent topology:
|
||||
|
||||
- **IrisPanel** — Agent avatar/greeting, metrics counters (open tasks, blocked,
|
||||
overdue, today), AI suggestions, quick action buttons, and an inline chat box.
|
||||
- **OperationsFeed** — Searchable/filterable activity feed with colour-coded
|
||||
status dots and yesterday/today/week grouping.
|
||||
- **AgendaPanel** — Daily agenda with checkable items persisted in
|
||||
`localStorage` under key `nexus-agenda-done`. Items are sectioned into
|
||||
"Heute", "Morgen", and "Überfällig".
|
||||
- **ActiveInitiatives** — Project initiative cards with progress bars, status
|
||||
badges (healthy/attention/blocked/paused/completed), and last activity timestamps.
|
||||
- **RecentlyFinished** — Horizontally scrollable chip list of recently completed items.
|
||||
- **AlertBar** — compact active/planning/idle, usage and blocker status.
|
||||
- **FlowCanvas** — agent topology, selection, layout reset and model controls.
|
||||
- **TaskStrip** — compact focus tasks linked to the task workflow.
|
||||
- **IrisChat** — hidden by default and opened from the topbar as a modal.
|
||||
- **AgentDetailModal** — live summary, activity and model selection.
|
||||
|
||||
### Global agent-first controls
|
||||
|
||||
- `Ctrl/Cmd+K` opens a real command palette on every authenticated route.
|
||||
- The palette navigates to core surfaces and loaded projects, tasks, agents and
|
||||
sessions. From a task, project or agent it can prefill a correlated durable
|
||||
run.
|
||||
- “Ask Iris” sends only bounded route, surface, object-type and object-id
|
||||
context. The backend labels this caller-provided context as untrusted
|
||||
metadata before placing it ahead of the user's message.
|
||||
- Command and Iris dialogs are mutually exclusive and support keyboard
|
||||
selection, dismissal and focus restoration.
|
||||
- Mission-control mutations publish one shared result tray with status,
|
||||
revision, trace metadata and links to their primary and affected entities.
|
||||
Task, OpenClaw runtime, cron, approval, config, agent-file, project,
|
||||
notification and activity links select the addressed result on the target
|
||||
surface instead of only opening its index route.
|
||||
|
||||
### Authentication
|
||||
|
||||
@@ -130,7 +188,8 @@ The dashboard was redesigned with a three-column layout:
|
||||
- Refresh tokens are random, stored only as SHA-256 hashes in PostgreSQL, rotated on use and checked for reuse.
|
||||
- The browser receives the refresh token only as a `HttpOnly`, `Secure`, `SameSite=Strict` cookie.
|
||||
- Login and refresh endpoints are rate-limited per forwarded client IP (5 attempts/minute).
|
||||
- All `/api/v1` operations routes require a valid access token; `/health` remains public.
|
||||
- The API uses an authenticated-by-default fallback policy; only the login and
|
||||
recovery flow plus the explicit liveness/Gateway-health probes are anonymous.
|
||||
- Swagger is enabled only in the Development environment.
|
||||
- CSRF protection via `X-CSRF-TOKEN` header and `nexus-csrf` cookie (not HttpOnly).
|
||||
|
||||
@@ -145,32 +204,31 @@ The dashboard was redesigned with a three-column layout:
|
||||
|
||||
## Frontend routes (SPA)
|
||||
|
||||
The SPA uses history-mode routes. Standalone views (whitelisted in App.vue):
|
||||
The SPA uses history-mode routes. Registered standalone views:
|
||||
|
||||
| Route | View | Description |
|
||||
|---|---|---|
|
||||
| `/login` | LoginView | Owner login |
|
||||
| `/dashboard` | DashboardView | Operations snapshot with IrisPanel, Feed, Agenda |
|
||||
| `/dashboard` | FlowBoard | Live orchestration, compact task focus and Iris modal |
|
||||
| `/memory` | MemoryView | Memory file browser with search |
|
||||
| `/docs` | DocsView | Documentation file browser |
|
||||
| `/team` | TeamView | Agent team org map |
|
||||
| `/security` | SecurityView | Security status center |
|
||||
| `/projects/:id` | ProjectDetailView | Project detail |
|
||||
| `/incidents` | IncidentsView | Incident diary |
|
||||
| `/calendar` | CalendarView | Cron/scheduler overview |
|
||||
| `/agents` | AgentsIndexView | Agent inventory |
|
||||
| `/agents/:id` | AgentDetailView | Agent detail + config editor |
|
||||
| `/settings` | SettingsView | Profile + password management |
|
||||
|
||||
Legacy ModuleView routes (not standalone, rendered through `ModuleView.vue`):
|
||||
|
||||
| Route | Name | Description |
|
||||
|---|---|---|
|
||||
| `/projects` | Projects | Project portfolio |
|
||||
| `/tasks` | Task Board | Task board with visible parent/child agent flow |
|
||||
| `/models` | Models | Provider routing status |
|
||||
| `/activity` | Activity | Audit timeline |
|
||||
| `/chat` | Mobile Chat | Owner-chat preview |
|
||||
| `/agents/new` | AgentCreateView | Owner-only agent proposal form |
|
||||
| `/agents/proposals/:proposalId` | AgentProposalDetailView | Proposal approval, provisioning and recovery state |
|
||||
| `/agents/:id` | AgentDetailView | Agent detail, live bootstrap files, read-only workspace and Standing Orders |
|
||||
| `/security` | SecurityView | Security status center |
|
||||
| `/incidents` | IncidentsView | Incident diary |
|
||||
| `/calendar` | CalendarView | OpenClaw cron lifecycle, detail and run history |
|
||||
| `/projects` | ProjectsIndexView | Project portfolio and creation |
|
||||
| `/projects/:id` | ProjectDetailView | Project detail with scoped tasks |
|
||||
| `/tasks` | TaskBoardView | Active task board and keyset-paginated Done history |
|
||||
| `/tasks/:id` | TaskDetailView | Task detail, subtasks and activity |
|
||||
| `/notifications` | NotificationsView | Notification inbox |
|
||||
| `/settings` | SettingsView | Profile, owner setup center, OpenClaw config and user management |
|
||||
| `/runs` | RunControlView | OpenClaw tasks, sessions, approvals, cron and events |
|
||||
| `/runs/:id` | RunDetailView | Durable run state, history, correlations and recovery actions |
|
||||
| `/models` | ModelsView | Live OpenClaw model catalog and sanitized auth status |
|
||||
| `/activity` | ActivityView | Nexus and OpenClaw event feed |
|
||||
|
||||
## API endpoints
|
||||
|
||||
@@ -179,11 +237,15 @@ Legacy ModuleView routes (not standalone, rendered through `ModuleView.vue`):
|
||||
Nexus exposes an MCP endpoint at `/mcp` for agent-facing board operations.
|
||||
It uses the official `ModelContextProtocol.AspNetCore` SDK with stateless
|
||||
streamable HTTP transport. Tools are a thin facade over `ITaskBridgeService`;
|
||||
they must not duplicate board business logic.
|
||||
they must not duplicate board business logic. Two additional proposal tools
|
||||
use the same durable proposal service as the owner UI and cannot approve or
|
||||
provision an agent.
|
||||
|
||||
Auth follows the bridge rules: requests provide `X-Agent-Id` and/or
|
||||
`X-Nexus-Api-Key`. Secrets stay in OpenClaw/Gateway config and are never
|
||||
embedded in frontend code.
|
||||
The bridge requires a verified JWT or `X-Nexus-Api-Key`. `X-Agent-Id` is
|
||||
accepted only for a service or privileged user principal as an allow-listed
|
||||
actor hint; the header is not an authentication credential.
|
||||
Secrets stay in server-side runtime configuration and are never embedded in
|
||||
frontend code.
|
||||
|
||||
Registered tools:
|
||||
|
||||
@@ -199,6 +261,8 @@ Registered tools:
|
||||
| `nexus_update_status` | Update status using the canonical enum only |
|
||||
| `nexus_append_activity` | Append checkpoint/activity |
|
||||
| `nexus_handoff` | Handoff to a known agent |
|
||||
| `nexus_propose_agent` | Create an approval-required proposal; never mutate OpenClaw |
|
||||
| `nexus_get_agent_proposal` | Read one durable proposal and provisioning state |
|
||||
|
||||
The compatible `/api/bridge` HTTP facade remains available for internal
|
||||
diagnostics and transition clients. New agent integrations should use MCP;
|
||||
@@ -209,34 +273,161 @@ diagnostics and transition clients. New agent integrations should use MCP;
|
||||
Nexus keeps the Browser -> Nexus -> OpenClaw boundary: the frontend never talks
|
||||
to OpenClaw directly. Read-only Gateway status is exposed through
|
||||
`GET /api/dashboard/gateway`; it reports reachability, discovered Gateway
|
||||
version and the optional `Integrations:OpenClaw:RequiredVersion` pin. A set pin
|
||||
does not mutate production config, but makes protocol drift visible in the UI.
|
||||
version and the fail-fast `Integrations:OpenClaw:RequiredVersion` pin. Nexus
|
||||
defaults to the verified stable `2026.7.1` contract; upgrades are an explicit
|
||||
deployment decision.
|
||||
|
||||
The primary browser contract is the authenticated, typed
|
||||
`/api/v1/openclaw/*` facade. It uses the Gateway protocol-v4 WebSocket connector,
|
||||
reports missing methods separately from missing scopes, and returns explicit
|
||||
recovery state instead of converting failures to plausible empty data.
|
||||
|
||||
| Method | Path | Purpose |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/v1/openclaw/setup` | Owner-only state of the single persisted `primary` connection profile |
|
||||
| `POST` | `/api/v1/openclaw/setup/discover` | Discover only bounded, known Gateway candidates |
|
||||
| `POST` | `/api/v1/openclaw/setup/probe` | Validate endpoint, transport, version and client compatibility |
|
||||
| `POST` | `/api/v1/openclaw/setup/attach` | Start a read-only attachment with an in-memory bootstrap credential |
|
||||
| `POST` | `/api/v1/openclaw/setup/verify` | Re-check pairing, scopes and capability state |
|
||||
| `POST` | `/api/v1/openclaw/setup/adopt` | Capture live inventory and persist adoption/capability metadata without copying runtime data |
|
||||
| `POST` | `/api/v1/openclaw/setup/management` | Deliberately request the required management scope upgrade |
|
||||
| `DELETE` | `/api/v1/openclaw/setup/connection` | Confirmed detach of profile, bound device token and active socket |
|
||||
| `POST/GET` | `/api/v1/openclaw/setup/wizard/*` | Render the official OpenClaw `wizard.*` setup flow after management authorization |
|
||||
| `GET` | `/api/v1/openclaw/overview` | Connection, capabilities and all core runtime collections |
|
||||
| `GET` | `/api/v1/openclaw/tasks` | Runtime task ledger |
|
||||
| `POST` | `/api/v1/openclaw/tasks/{id}/cancel` | Owner-only task cancellation |
|
||||
| `GET` | `/api/v1/openclaw/sessions` | Runtime sessions |
|
||||
| `POST` | `/api/v1/openclaw/sessions/abort` | Owner-only session abort |
|
||||
| `POST` | `/api/v1/openclaw/sessions/model` | Owner-only session model patch |
|
||||
| `GET/POST` | `/api/v1/openclaw/cron` | Paginated runtime schedules and owner-only creation |
|
||||
| `GET/PATCH/DELETE` | `/api/v1/openclaw/cron/{id}` | Owner-only detail and hash-guarded mutation |
|
||||
| `GET` | `/api/v1/openclaw/cron/{id}/runs` | Paginated authoritative OpenClaw run history |
|
||||
| `POST` | `/api/v1/openclaw/cron/{id}/run` | Queue an owner-only force run and correlate its returned run id |
|
||||
| `GET` | `/api/v1/openclaw/approvals` | Pending runtime approvals |
|
||||
| `POST` | `/api/v1/openclaw/approvals/{id}/resolve` | Owner-only approval decision |
|
||||
| `GET` | `/api/v1/openclaw/activity` | Normalized Gateway event buffer |
|
||||
| `GET` | `/api/v1/openclaw/models` | Provider-safe live model catalog |
|
||||
| `GET` | `/api/v1/openclaw/models/auth-status` | Sanitized `models.authStatus` projection |
|
||||
| `GET` | `/api/v1/openclaw/agents` | Runtime agents |
|
||||
| `GET` | `/api/v1/openclaw/agents/create-options` | Server-derived workspace, model and production-gate options |
|
||||
| `GET/POST` | `/api/v1/openclaw/agent-proposals` | Owner proposal list and manual proposal creation |
|
||||
| `GET` | `/api/v1/openclaw/agent-proposals/{id}` | Proposal, approval and provisioning state |
|
||||
| `POST` | `/api/v1/openclaw/agent-proposals/{id}/approve` | Owner approval and durable provisioning queue |
|
||||
| `POST` | `/api/v1/openclaw/agent-proposals/{id}/reject` | Owner rejection with optimistic revision |
|
||||
| `POST` | `/api/v1/openclaw/agent-proposals/{id}/retry` | Explicit recovery after failed or uncertain provisioning |
|
||||
| `GET/PUT` | `/api/v1/openclaw/agents/{id}/files/*` | Live bootstrap-file list, read and hash-guarded write |
|
||||
| `GET` | `/api/v1/openclaw/agents/{id}/workspace*` | Read-only arbitrary workspace browsing |
|
||||
| `GET/PATCH` | `/api/v1/openclaw/config*` | Schema lookup, redacted snapshot and hash-guarded patch |
|
||||
| `GET` | `/api/v1/openclaw/events` | Authenticated SSE projection with cursor replay and gap signals |
|
||||
| `GET` | `/api/v1/openclaw/runs` | Durable run collection and correlation filters |
|
||||
| `POST` | `/api/v1/openclaw/runs` | Owner-only durable dispatch |
|
||||
| `GET` | `/api/v1/openclaw/runs/{id}` | Durable run state |
|
||||
| `GET` | `/api/v1/openclaw/runs/{id}/history` | Nexus transition history plus redacted Gateway history when available |
|
||||
| `POST` | `/api/v1/openclaw/runs/{id}/stop` | Owner-only exact-run stop |
|
||||
| `POST` | `/api/v1/openclaw/runs/{id}/retry` | Owner-only correlated retry as a new run |
|
||||
| `POST` | `/api/v1/openclaw/runs/{id}/resume` | Explicitly reports unsupported until OpenClaw exposes a same-run resume contract |
|
||||
|
||||
The compatibility OpenClaw event stream projects connection, run, session,
|
||||
tool, approval, artifact and other Gateway events from the bounded connector
|
||||
buffer. It accepts `Last-Event-ID`, emits heartbeat and replay-gap events and
|
||||
redacts projected payloads. It remains a backend adapter during migration; the
|
||||
frontend does not consume raw or projected OpenClaw payloads directly.
|
||||
|
||||
The OpenClaw stream above remains the sanitized Runtime projection. Nexus-owned
|
||||
workflow changes additionally use `GET /api/v1/events?afterSequence=`. This
|
||||
authenticated stream replays the PostgreSQL outbox by global sequence and
|
||||
emits content-minimized task, project, proposal, run, activity and notification
|
||||
deltas. A cursor older than the retained range returns `resync_required`;
|
||||
clients then refresh only affected Query domains. The frontend never consumes
|
||||
raw OpenClaw event payloads.
|
||||
|
||||
### Agent proposal and provisioning boundary
|
||||
|
||||
Manual creation and Iris both create the same durable proposal:
|
||||
|
||||
```text
|
||||
local form draft -> awaiting_approval -> provisioning
|
||||
-> ready | partial | failed | in_doubt
|
||||
-> rejected
|
||||
```
|
||||
|
||||
Iris has only `nexus_propose_agent` and `nexus_get_agent_proposal`; neither can
|
||||
approve or mutate OpenClaw. After explicit owner approval, the worker rechecks
|
||||
local management consent, the official external Client ID, endpoint/TLS trust,
|
||||
advertised capability, `operator.admin`, proposal revision and idempotency. It
|
||||
derives the workspace from server-side OpenClaw configuration, calls
|
||||
`agents.create` at most once, reads the inventory back and only then writes and
|
||||
verifies approved standard files. A timeout after possible dispatch becomes
|
||||
`in_doubt`; a later retry first reconciles `agents.list`. Post-create file
|
||||
failure becomes `partial` and never triggers an automatic agent deletion.
|
||||
|
||||
Production provisioning remains disabled while the pinned OpenClaw version
|
||||
lacks an officially supported external Nexus or generic operator identity.
|
||||
|
||||
Durable runs are stored in PostgreSQL before dispatch together with their
|
||||
transition history. They correlate OpenClaw run/session ids with optional
|
||||
Nexus task and project ids, actor, correlation id and trace context. Start,
|
||||
stop and retry are implemented. Same-run resume is deliberately disabled
|
||||
because the pinned Gateway contract does not currently advertise such an RPC.
|
||||
|
||||
Nexus does not impersonate OpenClaw's reserved `gateway-client/backend`
|
||||
identity. Production attachment remains blocked until the pinned OpenClaw
|
||||
release officially supports the external `nexus` client id or another approved
|
||||
generic external-operator identity. Once that contract exists, remote or
|
||||
container-to-host operation uses Nexus' persisted Ed25519 identity and signed
|
||||
challenge response. The exact `PAIRING_REQUIRED` request id is surfaced to the
|
||||
owner; a resulting device token stays bound server-side to the normalized
|
||||
endpoint, TLS fingerprint and role. The Compose volume
|
||||
`nexus-openclaw-device` keeps identity state stable across API restarts and
|
||||
must be protected as credential material.
|
||||
See [OpenClaw Gateway connection](docs/OPENCLAW_GATEWAY_CONNECTION.md).
|
||||
|
||||
Every typed OpenClaw mutation carries a Nexus invocation context with actor,
|
||||
correlation id, W3C `traceparent`, and idempotency key. The PostgreSQL claim
|
||||
store keeps only metadata and hashed idempotency keys. Because the current
|
||||
OpenClaw schemas for `tasks.cancel`, `sessions.abort`, `sessions.patch`,
|
||||
`cron.run`, and `approval.resolve` are closed and do not declare an
|
||||
`idempotencyKey`, Nexus deduplicates these calls locally instead of sending an
|
||||
undocumented field. Schema-confirmed methods such as `chat.send` can opt in to
|
||||
wire-level `idempotencyKey` propagation. Active claims and terminal outcomes
|
||||
are stored transactionally in PostgreSQL `OperationClaims`; any existing JSONL
|
||||
file is treated as an immutable legacy archive and is neither read nor
|
||||
appended by the registered store.
|
||||
|
||||
Agent activity shown as "Thinking" is redacted before display. Lines containing
|
||||
token, password, bearer, authorization, API key or secret markers are replaced
|
||||
with a redaction marker. Persisted audit-worthy events should be written as
|
||||
short Activity entries, not raw session transcripts.
|
||||
|
||||
Nexus activity updates stream live through the Dashboard SSE channel and are
|
||||
filtered by explicit `agentIds`. Gateway session history is read-only fallback
|
||||
data: it is fetched on demand, redacted before display and not persisted as a
|
||||
long-term raw transcript. Agent "Now" and "Today" summaries are deterministic
|
||||
derivations from redacted Nexus activity plus redacted Gateway history; Nexus
|
||||
does not call an LLM to summarize this feed.
|
||||
Dashboard and agent telemetry no longer invent progress, elapsed time, next
|
||||
steps, cost or synthetic “Thinking” items. Progress is shown only when a Nexus
|
||||
task reports it, token totals only when a Gateway session reports them, and
|
||||
unreported values are rendered as unknown. Cost remains unknown until the
|
||||
runtime supplies authoritative cost data.
|
||||
|
||||
Config writes and approval actions are owner-only. Config saves validate before
|
||||
replacement, keep a `.bak` when an existing file is replaced, write audit events
|
||||
without file contents or secrets and return structured `validation`, `backup`
|
||||
and `reloadCheck` results. Workspace Markdown hot reload is currently reported
|
||||
truthfully as `not_supported`; JSON validation exists in the save path but JSON
|
||||
files are not exposed unless they are explicitly allowlisted for editing.
|
||||
Nexus activity changes arrive as content-minimized domain events and invalidate
|
||||
only the affected Query keys. Gateway session history remains read-only
|
||||
fallback data: it is fetched on demand, redacted before display and not
|
||||
persisted as a long-term raw transcript. Agent "Now" and "Today" summaries are
|
||||
deterministic derivations from redacted Nexus activity plus redacted Gateway
|
||||
history; Nexus does not call an LLM to summarize this feed.
|
||||
|
||||
Config writes and approval actions are owner-only. Agent bootstrap-file writes
|
||||
require `expectedHash` and `Idempotency-Key`, re-read before the write, use
|
||||
OpenClaw's `agents.files.set`, and verify the stored result afterward. Nexus
|
||||
reports only “saved and read back”; it does not claim an unconfirmed runtime
|
||||
hot reload. Arbitrary workspace files remain read-only. OpenClaw configuration
|
||||
patches use the live schema, `baseHash`, a visible diff and explicit
|
||||
`replacePaths`; secret values are never projected to the browser.
|
||||
|
||||
### Backend Bridge (Agent-zu-Backend, NICHT Frontend)
|
||||
|
||||
Der `/api/bridge/` Pfad ist ein strukturierter MCP-artiger Kommando-Adapter für die
|
||||
Agent-zu-Backend-Kommunikation. Kein Frontend-Code ruft diese Endpunkte auf.
|
||||
|
||||
Auth: `X-Agent-Id` Header, `X-Nexus-Api-Key`, oder JWT. Rate-Limited (30/min).
|
||||
Auth: verifiziertes JWT oder `X-Nexus-Api-Key`, rate-limited (30/min).
|
||||
`X-Agent-Id` ist für Service- oder privilegierte User-Principals nur ein
|
||||
allow-gelisteter Actor-Hinweis und niemals selbst ein Credential.
|
||||
|
||||
| Methode | Pfad | Kommando | Beschreibung |
|
||||
|---|---|---|---|
|
||||
@@ -280,7 +471,12 @@ Response-Format (TaskBridgeCommandResponse<T>):
|
||||
|
||||
| Method | Path | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/v1/operations/snapshot` | Full operations snapshot (runtime, agents, projects, tasks, activity, metrics) |
|
||||
| `GET` | `/api/v1/operations/snapshot` | Transitional aggregate snapshot for compatibility views |
|
||||
|
||||
New views must use the typed domain endpoints and shared Query keys instead of
|
||||
expanding the operations snapshot. The endpoint remains a backend
|
||||
compatibility surface, but the old frontend operations/task stores and
|
||||
duplicate live-sync files have been removed.
|
||||
|
||||
### Parent/Child task flow
|
||||
|
||||
@@ -291,6 +487,21 @@ The Task Board now models OpenClaw delegation as a visible parent/child flow:
|
||||
- Agent progress hints on parent tasks derive from recent activity and child-task status summaries.
|
||||
- Full workflow documentation: [`docs/openclaw-task-board-flow.md`](docs/openclaw-task-board-flow.md)
|
||||
|
||||
The initial board request projects every non-Done task and the newest 50 Done
|
||||
tasks without entity tracking. Child counts and latest activity are correlated
|
||||
inside the projected SQL; the initial path uses at most three statements.
|
||||
Further Done pages use an opaque `(UpdatedAt, Id)` keyset cursor and omit the
|
||||
active-task query. Task mutations and outbox events reconcile only
|
||||
`/api/v1/tasks/{id}/board-card`; a full board reload is reserved for failed
|
||||
delta recovery or an explicit stream resync. The supporting PostgreSQL indexes
|
||||
are created by
|
||||
`20260730224500_AddAgentProvisioningAndBoardIndexes`.
|
||||
|
||||
These structural properties do not prove the release performance budgets.
|
||||
The 1,000-task/10,000-activity k6 result, SQL plans, statement-count trace and
|
||||
browser navigation-to-visible p95 remain separate acceptance evidence; see
|
||||
[QA automation](docs/QA_AUTOMATION.md).
|
||||
|
||||
### Projects
|
||||
|
||||
| Method | Path | Description |
|
||||
@@ -298,6 +509,7 @@ The Task Board now models OpenClaw delegation as a visible parent/child flow:
|
||||
| `GET` | `/api/v1/projects` | List all projects |
|
||||
| `POST` | `/api/v1/projects` | Create project |
|
||||
| `GET` | `/api/v1/projects/{id}` | Get project detail |
|
||||
| `GET` | `/api/v1/projects/{id}/tasks` | Get only tasks scoped to the project |
|
||||
| `PATCH` | `/api/v1/projects/{id}` | Update project (name, description, status) |
|
||||
| `DELETE` | `/api/v1/projects/{id}` | Delete or archive project (archives if has tasks) |
|
||||
|
||||
@@ -306,6 +518,8 @@ The Task Board now models OpenClaw delegation as a visible parent/child flow:
|
||||
| Method | Path | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/v1/tasks` | List all tasks |
|
||||
| `GET` | `/api/v1/tasks/board` | All active cards plus keyset-paginated Done cards |
|
||||
| `GET` | `/api/v1/tasks/{id}/board-card` | One compact card for live delta reconciliation |
|
||||
| `POST` | `/api/v1/tasks` | Create task |
|
||||
| `GET` | `/api/v1/tasks/pending-approval` | Owner-only pending approvals |
|
||||
| `PATCH` | `/api/v1/tasks/{id}` | Update task (title, priority, projectId) |
|
||||
@@ -323,9 +537,12 @@ The Task Board now models OpenClaw delegation as a visible parent/child flow:
|
||||
| `GET` | `/api/v1/agents/{id}/activity` | Agent-specific activity (last 50) |
|
||||
| `GET` | `/api/v1/agents/{id}/summary` | Redacted deterministic Now/Today summary |
|
||||
| `POST` | `/api/v1/agents/{id}/command` | Send command to agent |
|
||||
| `GET` | `/api/v1/agents/{id}/config` | List agent config files (IDENTITY.md, SOUL.md, etc.) |
|
||||
| `GET` | `/api/v1/agents/{id}/config/{fileName}` | Read config file content |
|
||||
| `PUT` | `/api/v1/agents/{id}/config/{fileName}` | Owner-only validated config save with backup/audit/reload result |
|
||||
| `GET` | `/api/v1/agents/{id}/config` | Transitional owner-only adapter to the live OpenClaw file list |
|
||||
| `GET` | `/api/v1/agents/{id}/config/{fileName}` | Transitional owner-only adapter to live file content |
|
||||
| `PUT` | `/api/v1/agents/{id}/config/{fileName}` | Transitional owner-only adapter to verified OpenClaw file writes |
|
||||
|
||||
New clients use the `/api/v1/openclaw/agents/{id}/files` and
|
||||
`/api/v1/openclaw/agents/{id}/workspace` contracts documented above.
|
||||
|
||||
### Memory & Docs
|
||||
|
||||
@@ -352,14 +569,36 @@ The Task Board now models OpenClaw delegation as a visible parent/child flow:
|
||||
|
||||
| Method | Path | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/v1/calendar` | Cron job overview (gateway or fallback) |
|
||||
| `GET` | `/api/v1/calendar/upcoming` | Upcoming cron jobs |
|
||||
| `GET` | `/api/v1/calendar` | Transitional calendar projection |
|
||||
| `GET` | `/api/v1/calendar/upcoming` | Transitional upcoming-job projection |
|
||||
|
||||
Create, edit, enable/disable, delete, immediate run and paginated history use
|
||||
the typed `/api/v1/openclaw/cron` contracts. OpenClaw remains the only cron
|
||||
data authority.
|
||||
|
||||
### Chat
|
||||
|
||||
| Method | Path | Auth | Description |
|
||||
|---|---|---|---|
|
||||
| `POST` | `/api/v1/chat` | Yes (rate-limited) | Route message through IAgentRuntime |
|
||||
| `POST` | `/api/v1/chat` | Yes (rate-limited) | Route message through Protocol-v4 OpenClaw chat service |
|
||||
|
||||
### Domain events and browser telemetry
|
||||
|
||||
| Method | Path | Description |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/v1/events?afterSequence=` | Authenticated replayable PostgreSQL domain stream |
|
||||
| `POST` | `/api/v1/telemetry/browser` | Allow-listed Web Vital or browser performance metric |
|
||||
|
||||
`OutboxEvents` is the durable Nexus event source for migrated domains. A background worker claims
|
||||
unpublished rows with a lease and `FOR UPDATE SKIP LOCKED`, publishes them to
|
||||
bounded in-process subscribers, and retains at least 24 hours and 10,000
|
||||
sequences. Reconnect replay is capped at 512 deltas.
|
||||
|
||||
Browser telemetry accepts only metric name, value, rating, route name, build
|
||||
version, live mode and correlation ID. OpenTelemetry processors remove URL
|
||||
queries, SQL text, exception messages/stacks and other content-bearing
|
||||
attributes. Prompts, chat text, Markdown, tool arguments, secrets and
|
||||
credentials are never valid telemetry.
|
||||
|
||||
Project and task mutations create activity records. The API applies committed EF
|
||||
Core migrations after PostgreSQL becomes healthy. No destructive endpoints are
|
||||
@@ -379,21 +618,17 @@ Backlog → Blocked → In progress / Done
|
||||
|
||||
## Runtime chat and model routing
|
||||
|
||||
`POST /api/v1/chat` routes authenticated owner messages through the
|
||||
`IAgentRuntime` contract. The browser never receives a Gateway password or model
|
||||
provider key. Conversation IDs are stable per browser and Iris is the default
|
||||
agent target.
|
||||
`POST /api/v1/chat` routes authenticated messages through
|
||||
`IOpenClawChatService` and Protocol-v4 `chat.send`. The older parallel
|
||||
OpenAI-compatible `/v1/chat/completions` path is not a Nexus runtime path.
|
||||
The browser never receives a Gateway password or model-provider key.
|
||||
Conversation IDs are stable per browser and Iris is the default agent target.
|
||||
|
||||
The configured model-routing policy routes through the OpenClaw Gateway only.
|
||||
Ollama and NVIDIA providers have been removed. Currently active models:
|
||||
|
||||
| Agent | Model |
|
||||
|-------|-------|
|
||||
| Iris | `openai/gpt-5.4` |
|
||||
| Programmer, Executor | `deepseek/deepseek-v4-flash` |
|
||||
| Reviewer, Architekt, Researcher | `deepseek/deepseek-v4-pro` |
|
||||
|
||||
Claude models (Sonnet 4.6, Opus 4.6/4.7/4.8) are available via `claude-cli` backend.
|
||||
Nexus no longer defines a static active-model table. `/models`, routing status
|
||||
and agent model choices are projections of the catalog and active sessions
|
||||
reported by OpenClaw. OpenAI is the intended primary provider and must be
|
||||
configured and proven inside OpenClaw; Nexus stores no OpenAI credential.
|
||||
|
||||
The Settings module reports runtime and provider state without exposing
|
||||
credentials.
|
||||
@@ -403,8 +638,11 @@ credentials.
|
||||
### CI — Automatic
|
||||
|
||||
Every push to `main` triggers `.gitea/workflows/ci.yaml`:
|
||||
- **Backend**: .NET restore → build → test
|
||||
- **Frontend**: pnpm install → type-check → test → build
|
||||
- **Backend**: .NET restore → build → checked-in OpenAPI drift check → test
|
||||
- **Frontend**: pnpm install → type-check → generated client drift check →
|
||||
unit test → build → Playwright Chromium E2E
|
||||
- **Optional integration**: environment-gated Testcontainers PostgreSQL and
|
||||
Toxiproxy tests
|
||||
- **Security**: Scan for hardcoded secrets in source code
|
||||
|
||||
CI must never break. If it does, Reviewer fixes.
|
||||
|
||||
Reference in New Issue
Block a user