# Workspace Route Coverage

> Canonical path: `specs/deployment/workspace-route-coverage-fix.md`
> Status: current
> Related specs: [Server Profile Routing](../api/server-profile-routing.md),
> [AgentTeam Server Workspace Isolation](./agentteam-server-workspace-isolation.md), and
> [Daemon](../daemon/daemon.md). The target public URL and activation contract
> is [Workspace-Owned URL Canonicalization](./workspace-url-canonicalization.md).

## Contract

Every request owned by a workspace must carry a workspace discriminator before
it crosses the Edge Gateway:

- REST clients use `X-AgentTeam-Route-Workspace-Id`.
- Browser realtime uses the workspace-explicit
  `/api/v1/workspaces/:workspaceId/events/stream` path because a browser cannot
  attach an arbitrary routing header to a WebSocket upgrade.
- Daemon and App runtime routes use their workspace-explicit v1 paths when the
  workspace is known. The Gateway retains the legacy `/daemon/*` and
  `/internal/app/runtime/*` entry points. It accepts an explicit
  `workspaceId`/`workspace_id` discriminator, or resolves the workspace from
  authenticated machine or App identity before normalizing the request to its
  canonical workspace-scoped path.
- Retired `/internal/agent/*` requests are unsupported and receive an explicit
  Gateway 404. Agent Runtime callers use only
  `/api/v1/workspaces/:workspaceId/agents/:agentId/runtime/*`; the Gateway does
  not infer a workspace from Agent identity or adapt the retired wire.
- A supported legacy Daemon or App request with neither an explicit workspace
  nor an authoritative runtime credential association fails closed. A user
  session is not a default-workspace routing source.

The authenticated workspace identity remains authoritative. A route header,
path parameter, or retry hint selects a backend; it does not grant access and
must still agree with the authenticated workspace.

This document defines discriminator coverage for the compatibility surface.
The canonical target moves workspace-owned public business routes under
`/api/v1/workspaces/:workspaceId/*`, keeps old-URL normalization at the Gateway,
and removes old public aliases from Workspace Server as specified by
[Workspace-Owned URL Canonicalization](./workspace-url-canonicalization.md).

## Browser Requirements

- Workspace event streams must encode the explicit workspace id in the URL.
- Workspace-scoped API clients must pass the workspace id to the shared request
  transport so it can attach the route header.
- Queries must not issue workspace-scoped requests until a non-empty workspace
  id is available.
- Stream cursor, batching, acknowledgement, and gap recovery state must remain
  isolated per workspace.

The retired HTTP message-sync cursor endpoint is not part of the runtime
contract.

## Daemon Requirements

- Persisted daemon profiles use workspace-explicit connect and runtime routes.
- A compatibility connect attempted without a workspace id is normalized by
  the Gateway only after the machine key resolves to one workspace.
- Compatibility normalization does not weaken machine or App authentication;
  the workspace owner revalidates the same credential against the rewritten
  route workspace.
- Placement changes require the serving workspace profile to have an updated
  managed-workspace set before it accepts traffic.

## Edge Requirements

- Workspace-explicit paths are routed by their workspace segment.
- The route workspace header is preserved on REST traffic.
- Headerless traffic must never be routed by a default workspace *group*, a
  client-supplied owner hint, or an unrelated principal default.
- Conflicting path, query, header, credential, or owner identities fail closed.
- Native AGS REST, raw, and Git paths keep their protocol shape, but authority
  and placement follow the canonical [request workspace routing matrix](../api/request-workspace-routing-matrix.md).
  Workspace-local, public, or credential traffic never defaults when unresolved.
- Repository management APIs are unsupported in split mode and return 404.
- Split `/api/graphql` is unsupported and rejected by the Gateway. The embedded
  all-profile handler remains unchanged; enabling GraphQL through a multi-owner
  edge requires a separate storage-aware contract.

## Verification

The durable checks are:

- `web/src/agentteam/api/im.transport.test.ts` for the workspace-explicit event
  stream URL.
- Web API transport tests for `X-AgentTeam-Route-Workspace-Id`.
- Gateway tests for supported legacy URL normalization, credential resolution,
  conflicting-discriminator rejection, and explicit 404 rejection of the
  retired Agent Runtime URL.
- Agent API tests for the canonical workspace-scoped runtime wire.
- Gateway tests for authenticated workspace placement, zero-upstream 404 of
  non-product AGS compatibility, and stable rejection of deferred
  management/GraphQL routes.
- Desktop Wire/channel tests for workspace route persistence and bounded retry.
- workspace stream helper/controller tests for per-workspace cursor, batching,
  acknowledgement, and gap recovery behavior.

Deployment smoke checks use a non-default workspace and verify browser
realtime, workspace-scoped REST calls, and daemon connection without manual
workspace configuration.
