Last verified: February 27, 2026
This document tracks how stateset-desktop integrates with
/home/dom/stateset-orchestration-engine, with emphasis on payload compatibility
and failure-safe behavior.
- Keep desktop runtime stable across engine response variants.
- Fail closed on auth/scope errors.
- Avoid silent UI breakage when engine payloads evolve.
| Area | Desktop Client Path | Engine Route Family | Notes |
|---|---|---|---|
| Auth | src/lib/registration.ts, src/stores/auth.ts |
/api/v1/auth/* |
register/login/me aligned. forgot-password is optional; desktop now returns a dedicated 404 message. |
| Health | src/hooks/useOnlineStatus.ts |
/health, /api/v1/health/detailed, /health/detailed |
Desktop prefers authenticated detailed route and falls back to legacy route only on 404. |
| Agent sessions | src/lib/api.ts (agentApi) |
/api/v1/tenants/:tenant_id/agents and /brands/:brand_id/agents/* |
Session CRUD/start-stop config + stream token aligned. |
| Agent stream | src/hooks/useAgentStream.ts |
/stream/token, /stream |
Supports query-token and API-key auth strategies for SSE. |
| Secrets | src/lib/api.ts (secretsApi) |
/secrets + /secrets/:platform/test |
Handles canonical {ok,data:{platforms}} and legacy variants. |
| Webhooks | src/lib/api.ts (webhooksApi) |
Tenant webhook routes + brand create route | Desktop now normalizes both minimal create responses and canonical delivery/test payloads. |
Engine create handlers can return minimal objects:
idurleventssecretenabledcreated_at
Desktop mitigation:
EngineWebhookSchemaaccepts optionaltenant_id,brand_id, andupdated_at.webhooksApi.create(...)applies fallbacks from request context:- tenant id from method arg
- brand id from active selection
- name from submitted create payload
updated_atdefaulted tocreated_at
Engine canonical delivery uses DB-oriented fields:
payloadas JSON objectresponse_statusattemptsdelivered_at- no guaranteed
duration_ms/success
Desktop mitigation:
EngineWebhookDeliverySchemaaccepts object/string payloads.- payload is normalized to string JSON for renderer usage.
duration_msdefaults to0when absent.successis derived fromresponse_statuswhen absent.
Engine may return:
- legacy test result (
{ success, status_code, duration_ms }) - canonical
ApiResponse<WebhookDelivery>
Desktop mitigation:
WebhookTestResponseSchemaaccepts both and transforms into:success: booleanstatus_code: number | nullduration_ms: number
Potential drift:
{ ok, data }envelope vs direct object- unknown/missing check statuses
- missing circuit breaker keys
Desktop mitigation:
parseDetailedHealth(...)unwraps either shape.- unknown check statuses normalize to
unknown. - missing circuit breaker entries default to
closed.
src/lib/api.test.ts- webhook create minimal response normalization
- canonical webhook test delivery normalization
- canonical webhook deliveries normalization
src/lib/schemas.test.ts- relaxed webhook schema (optional tenant/updated fields)
- delivery normalization (
payload,duration_ms,success) - webhook test response normalization
src/hooks/useOnlineStatus.test.ts- detailed health fallback behavior
- envelope parsing and unknown status normalization
src/lib/registration.test.ts- dedicated 404 handling for optional password reset endpoint
- Keep this file updated whenever engine route signatures or envelopes change.
- Add a CI contract check that snapshots representative engine responses and validates desktop schemas.
- Treat all new engine fields as additive; avoid requiring them in desktop schemas unless truly mandatory.