feat(stability): unify readiness and recovery
CI - Build & Test / Backend (.NET) (push) Successful in 45s
CI - Build & Test / Backend integration (PostgreSQL/Toxiproxy) (push) Failing after 1m0s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m49s
CI - Build & Test / Security Check (push) Successful in 7s
CI - Build & Test / Deploy Nexus (push) Has been skipped

This commit is contained in:
AzuTear
2026-08-01 01:21:33 +02:00
parent 38282e4f7f
commit cd8c78d165
67 changed files with 2616 additions and 601 deletions
+31 -3
View File
@@ -44,6 +44,13 @@ isolated from the frontend and the Nexus domain model.
> Gitea run 362 deployed commit `144edf58fe5928a3e04816f4435ea574d64211a1`;
> PostgreSQL and the OpenClaw HTTP runtime are healthy. Productive Protocol-v4
> management remains intentionally blocked by the external Client-ID gate.
>
> **Stability and recovery v0.2.60 candidate (2026-07-31):**
> [implementation and acceptance](docs/audits/2026-07-31/stability-v0.2.60/IMPLEMENTATION_AND_ACCEPTANCE.md).
> Readiness, browser-origin protection, generated ProblemDetails metadata,
> shared UI recovery states, version provenance and mandatory container-backed
> CI are implemented. The audit separates locally proven behavior from the
> Linux/Docker, deployment, credentialed-production and OpenClaw-write gates.
> 📋 **Architektur-Review** (2026-06-22): Board-first Orchestrierung, sichere
> Backend-Brücke und Gateway-Integration geprüft. Siehe
@@ -73,6 +80,10 @@ isolated from the frontend and the Nexus domain model.
- keyset-paginated Task Board with targeted live card reconciliation
- structured mutation results with entity references, trace metadata and
cross-page frontend deep links
- one generated `ProblemDetails` contract and shared loading, empty, error,
offline, stale and partial presentation across all authenticated views
- separate process liveness, database-backed readiness and full runtime
diagnostics used consistently by deploy and rollback
- Responsive dark-mode operations dashboard
- Traefik reverse-proxy with Let's Encrypt TLS on `nexus.noveria.net`
@@ -96,6 +107,8 @@ cp .env.template .env
# 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/live
curl http://127.0.0.1:18880/health/ready
curl http://127.0.0.1:18880/health
```
@@ -193,11 +206,17 @@ The dashboard prioritizes the live agent topology:
- Access tokens expire after 15 minutes and are held only in browser memory.
- 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.
- Cookie-backed refresh and logout reject explicit cross-site browser requests
through `Origin` and `Sec-Fetch-Site` validation. Non-browser API clients
without provenance headers still require a valid refresh cookie and the
normal rate limit.
- Login and refresh endpoints are rate-limited per forwarded client IP (5 attempts/minute).
- 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).
- The unused antiforgery-token endpoint was removed. Nexus does not advertise a
token that no mutation validates; strict cookies plus the refresh/logout
origin guard form the browser boundary for those anonymous cookie calls.
### Security
@@ -464,8 +483,9 @@ Response-Format (TaskBridgeCommandResponse<T>):
| Method | Path | Auth | Description |
|---|---|---|---|
| `GET` | `/health` | No | Health check with runtime + PostgreSQL |
| `GET` | `/api/v1/auth/csrf` | No | Get CSRF token |
| `GET` | `/health/live` | No | Process liveness only; no dependency probe |
| `GET` | `/health/ready` | No | `200` only when Nexus can serve through PostgreSQL; otherwise `503` |
| `GET` | `/health` | No | Full diagnostic projection for PostgreSQL and OpenClaw runtime; may return `Degraded` with HTTP 200 so the UI remains available for recovery |
| `POST` | `/api/v1/auth/login` | No (rate-limited) | Login with email/password |
| `POST` | `/api/v1/auth/refresh` | No (rate-limited) | Refresh access token |
| `POST` | `/api/v1/auth/logout` | No | Clear refresh token |
@@ -473,6 +493,14 @@ Response-Format (TaskBridgeCommandResponse<T>):
| `PATCH` | `/api/v1/auth/profile` | Yes | Update display name |
| `POST` | `/api/v1/auth/change-password` | Yes | Change password (min 10 chars) |
Ordinary API failures use `application/problem+json` with a stable `code`, HTTP
`status`, `title`, `detail` and `traceId`. Conflict revisions, operation IDs and
retry delays are included only when applicable. The generated OpenAPI contract
is the frontend source for these fields; mutations are never automatically
retried. Durable operation endpoints retain their typed operation envelope for
states such as `partial`, `failed` and `in_doubt`; those states must remain
inspectable and are not collapsed into a transient HTTP exception.
### Operations
| Method | Path | Description |