# Route Contracts: Canonical Operation Viewer Context Decoupling ## Scope These contracts describe the expected request and response behavior for the canonical operations routes affected by Spec 144. ## Canonical Routes ### GET /admin/operations | Property | Value | |----------|-------| | Route name | `admin.operations.index` | | Purpose | Workspace-level operations index with optional tenant-context convenience filtering | | Auth | Requires authenticated admin-plane user plus valid workspace membership | | Selected tenant behavior | May default filters and return affordances when an active entitled tenant exists | | Legitimacy rule | Index remains valid even when there is no selected tenant | | Forbidden state | Not primary for this route; out-of-scope access is deny-as-not-found | | Not found state | Non-member workspace access resolves as deny-as-not-found | ### GET /admin/operations/{run} | Property | Value | |----------|-------| | Route name | `admin.operations.view` | | Purpose | Canonical workspace-level record viewer for one operation run | | Primary subject | `OperationRun` | | Auth | Requires authenticated admin-plane user, workspace membership for the run's workspace, direct tenant entitlement when `tenant_id` is present, and any resolved capability for the run type | | Selected tenant behavior | Selected or remembered tenant context may affect informational banners and convenience navigation only | | Success state | 200 when the run exists and the actor is authorized | | Not found state | 404 when the run does not exist, the actor is not a workspace member, or the actor lacks entitlement to the run's linked tenant | | Forbidden state | 403 only when the actor is otherwise in scope but lacks the capability resolved for the run type | | Prohibited behavior | The route must not require the selected header tenant to match the run's tenant | ## Canonical Deep-Link Contract - All in-product run links in this scope must resolve through `admin.operations.view`. - Canonical run links from tenant pages, notifications, verification surfaces, and monitoring surfaces must be self-sufficient: if the run is viewable, the route must open regardless of the selected tenant context in the header. - A generating page's tenant context must not be required to reproduce the same result when the link is opened later. ## Presentation Contract ### Canonical Viewer Banner States | State | Required Behavior | |-------|-------------------| | Matching selected header tenant | Viewer may omit mismatch banner | | Different selected header tenant | Viewer remains valid and shows a non-blocking mismatch message | | No selected tenant | Viewer remains valid and may show workspace-level framing | | Run linked to onboarding, archived, or another selector-excluded tenant under existing availability rules | Viewer remains valid and shows lifecycle-aware framing | | Tenantless run | Viewer remains valid and clearly indicates workspace-level scope | ### Follow-Up Navigation - Related links or actions may be reduced, disabled, or absent when the run's tenant is not entitled or when lifecycle rules make follow-up surfaces unavailable. - Follow-up affordances must be evaluated independently from canonical viewer legitimacy when the run tenant is onboarding, archived, or otherwise excluded from the selector by existing availability rules. - Missing follow-up links must not be interpreted as run invalidity and must not block the canonical viewer. ## Non-Goals For This Contract - No change to `OperationRun` ownership - No new route family - No automatic tenant-context switching during run viewing - No change to operation start, progress, or completion notification contracts