openapi: 3.1.0
info:
  title: Workspace Governance Attention Internal Surface Contract
  version: 0.1.0
  summary: Internal logical contract for governance-aware workspace overview semantics
  description: |
    This contract is an internal planning artifact for Spec 175. It documents how
    the existing workspace overview must derive governance-aware summary metrics,
    attention items, calmness claims, and drill-through destinations from visible
    tenant truth. The rendered routes still return HTML. The structured schemas
    below describe the internal page and widget models that must be derivable
    before rendering. This does not add a public HTTP API.
servers:
  - url: /internal
x-overview-consumers:
  - surface: workspace.overview.summary_stats
    summarySource:
      - workspace_overview_builder
      - tenant_governance_aggregate
      - operation_run_activity
      - alert_delivery_activity
    guardScope:
      - app/Support/Workspaces/WorkspaceOverviewBuilder.php
      - app/Filament/Widgets/Workspace/WorkspaceSummaryStats.php
    expectedContract:
      - governance_metrics_count_visible_tenants_not_raw_issue_totals
      - governance_metrics_are_distinct_from_activity_metrics
  - surface: workspace.overview.needs_attention
    summarySource:
      - workspace_overview_builder
      - tenant_governance_aggregate
      - existing_evidence_review_truth
      - operation_run_activity
      - alert_delivery_activity
    guardScope:
      - app/Support/Workspaces/WorkspaceOverviewBuilder.php
      - app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php
      - resources/views/filament/widgets/workspace/workspace-needs-attention.blade.php
    expectedContract:
      - each_item_identifies_the_visible_tenant_when_tenant_bound
      - all_attention_items_are_tenant_bound
      - governance_issues_rank_above_activity_only_items
      - compare_attention_only_uses_stale_or_compare_specific_action_required_signals
      - each_item_has_one_matching_destination_or_a_safe_disabled_state
  - surface: workspace.overview.calmness
    summarySource:
      - workspace_overview_builder
      - tenant_governance_aggregate
      - operation_run_activity
      - alert_delivery_activity
    guardScope:
      - app/Support/Workspaces/WorkspaceOverviewBuilder.php
      - resources/views/filament/pages/workspace-overview.blade.php
    expectedContract:
      - operations_quiet_alone_is_not_enough_for_calmness
      - zero_tenant_and_low_permission_states_do_not_masquerade_as_healthy_calm
      - zero_tenant_recovery_uses_switch_workspace_and_low_permission_recovery_uses_operations_index
  - surface: workspace.overview.recent_operations
    summarySource:
      - workspace_overview_builder
      - operation_run_recency_query
    guardScope:
      - app/Filament/Widgets/Workspace/WorkspaceRecentOperations.php
      - resources/views/filament/widgets/workspace/workspace-recent-operations.blade.php
    expectedContract:
      - surface_role_is_diagnostic_recency_not_primary_governance_summary
      - recent_operations_remain_filtered_to_visible_tenant_scope
      - recent_operations_are_bounded_to_five
paths:
  /admin:
    get:
      summary: Render the governance-aware workspace overview bundle
      operationId: viewWorkspaceGovernanceAttentionOverview
      responses:
        '200':
          description: Workspace overview rendered with governance-aware summary, attention, calmness, and recency semantics
          content:
            text/html:
              schema:
                type: string
            application/vnd.tenantpilot.workspace-governance-attention+json:
              schema:
                $ref: '#/components/schemas/WorkspaceGovernanceOverviewBundle'
        '302':
          description: No workspace context is active yet, so the request is redirected to `/admin/choose-workspace`
        '404':
          description: Workspace is outside entitlement scope
  /admin/choose-tenant:
    get:
      summary: Explicit tenant-entry destination used by workspace drill-down when the operator wants to pick a tenant deliberately
      operationId: openChooseTenantFromWorkspaceOverview
      responses:
        '200':
          description: Choose-tenant page opened inside the authenticated admin panel and may bootstrap workspace context from the selected tenant if no workspace is currently active
  /admin/choose-workspace:
    get:
      summary: Default workspace-switch recovery destination for zero-tenant or wrong-workspace states
      operationId: openChooseWorkspaceFromWorkspaceOverview
      responses:
        '200':
          description: Choose-workspace page opened so the operator can recover to another entitled workspace context even when no workspace is currently active
  /admin/t/{tenant}:
    get:
      summary: Tenant dashboard fallback or broad tenant drill-through from workspace attention
      operationId: openTenantDashboardFromWorkspaceAttention
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Tenant dashboard opened for the visible tenant named by the workspace item when the dashboard is the allowed fallback or primary tenant landing
        '404':
          description: Tenant is outside entitlement scope
  /admin/t/{tenant}/findings:
    get:
      summary: Tenant findings destination used by workspace governance and findings attention
      operationId: openTenantFindingsFromWorkspaceAttention
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: string
        - name: tab
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/FindingsTab'
        - name: high_severity
          in: query
          required: false
          schema:
            type: boolean
        - name: governance_validity
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/GovernanceValidityFilter'
          description: Reproduces directly filterable governance-validity subsets such as `missing_support` or `expiring`; aggregate lapsed-governance attention falls back to the tenant dashboard when the full invalid-governance family cannot be reproduced without narrowing.
      responses:
        '200':
          description: Tenant findings list opened with a subset matching the originating workspace attention item
        '403':
          description: Actor is in scope but lacks findings inspection capability
        '404':
          description: Tenant is outside entitlement scope
  /admin/t/{tenant}/baseline-compare-landing:
    get:
      summary: Tenant baseline compare landing used by workspace compare attention
      operationId: openTenantBaselineCompareFromWorkspaceAttention
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Tenant baseline compare landing opened with the same compare posture family summarized by the workspace item
        '403':
          description: Actor is in scope but lacks the current tenant-view capability required by the compare landing
        '404':
          description: Tenant is outside entitlement scope
  /admin/t/{tenant}/evidence:
    get:
      summary: Tenant evidence destination used only when existing evidence truth is the most precise workspace next jump
      operationId: openTenantEvidenceFromWorkspaceAttention
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Tenant evidence surface opened for the visible tenant named by the workspace item
        '403':
          description: Actor is in scope but lacks evidence inspection capability
        '404':
          description: Tenant is outside entitlement scope
  /admin/t/{tenant}/reviews:
    get:
      summary: Tenant reviews destination used only when existing review truth is the most precise workspace next jump
      operationId: openTenantReviewsFromWorkspaceAttention
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Tenant reviews surface opened for the visible tenant named by the workspace item
        '403':
          description: Actor is in scope but lacks review inspection capability
        '404':
          description: Tenant is outside entitlement scope
  /admin/operations:
    get:
      summary: Canonical operations index used by workspace activity and operations-follow-up signals
      operationId: openOperationsFromWorkspaceOverview
      parameters:
        - name: tenant_id
          in: query
          required: false
          schema:
            type:
              - integer
              - string
          description: Optional tenant filter when the workspace item points to one tenant's operations follow-up.
        - name: activeTab
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/OperationsTab'
      responses:
        '200':
          description: Canonical operations index opened with any tenant and tab continuity required by the workspace signal; this remains the workspace-member-safe fallback for low-permission workspace states
        '404':
          description: Requested tenant context is outside entitlement scope
  /admin/operations/{run}:
    get:
      summary: Canonical operation detail opened from workspace recent operations or operations attention
      operationId: openOperationDetailFromWorkspaceOverview
      parameters:
        - name: run
          in: path
          required: true
          schema:
            type:
              - integer
              - string
      responses:
        '200':
          description: Canonical operation detail opened for the visible run
        '403':
          description: Actor is in scope but lacks operation detail capability
        '404':
          description: Operation run is outside entitlement scope
  /admin/alerts:
    get:
      summary: Canonical alerts overview used for alert-only follow-up from the workspace home
      operationId: openAlertsOverviewFromWorkspaceOverview
      responses:
        '200':
          description: Alerts overview opened for the current workspace, including delivery follow-up and alert-health context
        '403':
          description: Actor is in scope but lacks alerts inspection capability
        '404':
          description: Workspace is outside entitlement scope
components:
  schemas:
    MetricCategory:
      type: string
      enum:
        - scope
        - governance_risk
        - activity
        - alerts
    AttentionFamily:
      type: string
      enum:
        - governance
        - findings
        - compare
        - evidence
        - review
        - operations
        - alerts
    AttentionUrgency:
      type: string
      enum:
        - critical
        - high
        - medium
        - supporting
    DestinationKind:
      type: string
      enum:
        - choose_tenant
        - tenant_dashboard
        - tenant_findings
        - baseline_compare_landing
        - tenant_evidence
        - tenant_reviews
        - operations_index
        - operation_detail
        - alerts_overview
        - switch_workspace
        - none
    CheckedDomain:
      type: string
      enum:
        - governance
        - findings
        - compare
        - evidence
        - review
        - operations
        - alerts
        - tenant_access
    FindingsTab:
      type: string
      enum:
        - all
        - needs_action
        - overdue
        - risk_accepted
        - resolved
    GovernanceValidityFilter:
      type: string
      enum:
        - missing_support
        - expiring
        - valid
    OperationsTab:
      type: string
      enum:
        - all
        - active
        - blocked
        - failed
        - partial
        - succeeded
    DrillthroughTarget:
      type: object
      additionalProperties: false
      required:
        - kind
        - disabled
      properties:
        kind:
          $ref: '#/components/schemas/DestinationKind'
        url:
          type:
            - string
            - 'null'
        tenantRouteKey:
          type:
            - string
            - 'null'
        label:
          type:
            - string
            - 'null'
        disabled:
          type: boolean
        helperText:
          type:
            - string
            - 'null'
        filters:
          type:
            - object
            - 'null'
          additionalProperties: true
    WorkspaceSummaryMetric:
      type: object
      additionalProperties: false
      required:
        - key
        - label
        - value
        - category
        - description
        - color
      properties:
        key:
          type: string
        label:
          type: string
        value:
          type: integer
          minimum: 0
        category:
          $ref: '#/components/schemas/MetricCategory'
        description:
          type: string
        color:
          type: string
        destination:
          oneOf:
            - $ref: '#/components/schemas/DrillthroughTarget'
            - type: 'null'
    WorkspaceAttentionItem:
      type: object
      additionalProperties: false
      required:
        - key
        - tenantId
        - tenantLabel
        - family
        - urgency
        - title
        - body
        - badge
        - badgeColor
      anyOf:
        - required:
            - destination
          properties:
            destination:
              $ref: '#/components/schemas/DrillthroughTarget'
        - required:
            - actionDisabled
            - helperText
          properties:
            actionDisabled:
              const: true
            helperText:
              type: string
      properties:
        key:
          type: string
        tenantId:
          type: integer
        tenantLabel:
          type: string
        family:
          $ref: '#/components/schemas/AttentionFamily'
        urgency:
          $ref: '#/components/schemas/AttentionUrgency'
        title:
          type: string
        body:
          type: string
        supportingMessage:
          type:
            - string
            - 'null'
        badge:
          type: string
        badgeColor:
          type: string
        destination:
          oneOf:
            - $ref: '#/components/schemas/DrillthroughTarget'
            - type: 'null'
        actionDisabled:
          type:
            - boolean
            - 'null'
        helperText:
          type:
            - string
            - 'null'
    WorkspaceRecentOperation:
      type: object
      additionalProperties: false
      required:
        - id
        - title
        - statusLabel
        - statusColor
        - outcomeLabel
        - outcomeColor
        - startedAt
        - destination
      properties:
        id:
          type: integer
        title:
          type: string
        tenantLabel:
          type:
            - string
            - 'null'
        statusLabel:
          type: string
        statusColor:
          type: string
        outcomeLabel:
          type: string
        outcomeColor:
          type: string
        guidance:
          type:
            - string
            - 'null'
        startedAt:
          type: string
        destination:
          $ref: '#/components/schemas/DrillthroughTarget'
    WorkspaceCalmnessState:
      type: object
      additionalProperties: false
      required:
        - isCalm
        - checkedDomains
        - title
        - body
        - nextAction
      properties:
        isCalm:
          type: boolean
        checkedDomains:
          type: array
          items:
            $ref: '#/components/schemas/CheckedDomain'
        title:
          type: string
        body:
          type: string
        nextAction:
          description: Defaults to `switch_workspace` for zero-tenant recovery and `operations_index` for low-permission workspace-state recovery unless a more specific allowed action exists.
          $ref: '#/components/schemas/DrillthroughTarget'
    WorkspaceGovernanceOverviewBundle:
      type: object
      additionalProperties: false
      required:
        - workspaceId
        - workspaceName
        - summaryMetrics
        - attentionItems
        - recentOperations
        - calmness
      properties:
        workspaceId:
          type: integer
        workspaceName:
          type: string
        summaryMetrics:
          type: array
          maxItems: 8
          items:
            $ref: '#/components/schemas/WorkspaceSummaryMetric'
        attentionItems:
          type: array
          maxItems: 5
          items:
            $ref: '#/components/schemas/WorkspaceAttentionItem'
        recentOperations:
          type: array
          maxItems: 5
          items:
            $ref: '#/components/schemas/WorkspaceRecentOperation'
        calmness:
          $ref: '#/components/schemas/WorkspaceCalmnessState'
