openapi: 3.1.0 info: title: Tenant Dashboard Truth Alignment Internal Surface Contract version: 0.1.0 summary: Internal logical contract for aligned tenant dashboard KPI, attention, compare, and recency surfaces description: | This contract is an internal planning artifact for Spec 173. It documents how the tenant dashboard's summary and recency surfaces must derive their meaning from existing tenant truth and how drill-through destinations must preserve that meaning. 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-dashboard-consumers: - surface: tenant.dashboard.kpis summarySource: - finding_status_helpers - finding_destination_filters - canonical_operations_links guardScope: - app/Filament/Widgets/Dashboard/DashboardKpis.php expectedContract: - each_kpi_label_matches_its_count_universe - each_kpi_destination_reproduces_or_explicitly_broadens_the_named_subset - surface: tenant.dashboard.needs_attention summarySource: - tenant_governance_aggregate - operation_run_activity guardScope: - app/Filament/Widgets/Dashboard/NeedsAttention.php expectedContract: - each_primary_item_has_one_tenant_safe_destination - healthy_fallback_is_hidden_when_any_attention_condition_exists - surface: tenant.dashboard.baseline_compare_now summarySource: - tenant_governance_aggregate - baseline_compare_summary_assessment guardScope: - app/Filament/Widgets/Dashboard/BaselineCompareNow.php expectedContract: - positive_compare_claims_do_not_outvote_stronger_attention_conditions - primary_compare_destination_uses_existing_baseline_compare_landing - surface: tenant.dashboard.recent_drift_findings summarySource: - recent_drift_query guardScope: - app/Filament/Widgets/Dashboard/RecentDriftFindings.php expectedContract: - surface_role_is_diagnostic_recency_not_primary_queue - row_click_uses_canonical_finding_detail - surface: tenant.dashboard.recent_operations summarySource: - recent_operations_query - canonical_operations_links guardScope: - app/Filament/Widgets/Dashboard/RecentOperations.php expectedContract: - surface_role_is_diagnostic_recency_not_primary_queue - row_click_uses_canonical_operation_detail paths: /admin/t/{tenant}: get: summary: Render the aligned tenant dashboard summary bundle operationId: viewTenantDashboardAlignedTruth parameters: - name: tenant in: path required: true schema: type: string responses: '200': description: Tenant dashboard rendered with aligned KPI, attention, compare, and recency semantics content: text/html: schema: type: string application/vnd.tenantpilot.tenant-dashboard-truth+json: schema: $ref: '#/components/schemas/TenantDashboardTruthBundle' '404': description: Tenant is outside workspace or tenant entitlement scope /admin/t/{tenant}/findings: get: summary: Tenant findings destination used by KPI and attention drill-throughs operationId: openTenantFindingsFromDashboard 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: status in: query required: false schema: type: string - name: finding_type in: query required: false schema: type: string responses: '200': description: Tenant findings list opened with tenant-safe dashboard continuity filters '403': description: Actor is in scope but lacks findings inspection capability '404': description: Tenant is outside workspace or tenant entitlement scope /admin/t/{tenant}/baseline-compare-landing: get: summary: Tenant baseline compare landing used by compare and attention drill-throughs operationId: openTenantBaselineCompareLandingFromDashboard parameters: - name: tenant in: path required: true schema: type: string responses: '200': description: Tenant baseline compare landing opened with the same tenant-context compare posture the dashboard summarized '403': description: Actor is in scope but lacks baseline compare inspection capability '404': description: Tenant is outside workspace or tenant entitlement scope /admin/t/{tenant}/findings/{record}: get: summary: Tenant finding detail opened from recent drift row-click inspection operationId: openTenantFindingDetailFromDashboardRecency parameters: - name: tenant in: path required: true schema: type: string - name: record in: path required: true schema: type: string responses: '200': description: Tenant finding detail opened from the recent drift diagnostic surface '403': description: Actor is in scope but lacks finding detail inspection capability '404': description: Tenant or finding is outside entitlement scope /admin/operations: get: summary: Canonical operations destination with tenant-prefilter continuity from the tenant dashboard operationId: openCanonicalOperationsFromDashboard parameters: - name: tenant_id in: query required: false schema: type: - integer - string description: Tenant filter carried forward from tenant-context dashboard navigation. - name: activeTab in: query required: false description: Uses `active` for healthy queued or running activity, `blocked` for warning, stalled, or unusually long-running follow-up needing review, and `failed` for terminal failure follow-up. schema: $ref: '#/components/schemas/OperationsTab' - name: navigationContext in: query required: false schema: type: string description: Optional serialized canonical navigation context carried from tenant dashboard drill-throughs. responses: '200': description: Canonical admin operations list filtered to the originating tenant when opened from the dashboard '403': description: Actor is in scope but lacks operations inspection capability '404': description: Tenant context is outside entitlement scope /admin/operations/{run}: get: summary: Canonical operation detail opened from recent operations row-click inspection operationId: openOperationDetailFromDashboardRecency parameters: - name: run in: path required: true schema: type: - integer - string responses: '200': description: Canonical operation detail opened from the recent operations diagnostic surface '403': description: Actor is in scope but lacks operation detail inspection capability '404': description: Operation run is outside entitlement scope components: schemas: FindingsTab: type: string enum: - all - needs_action - overdue - risk_accepted - resolved OperationsTab: type: string description: Shared canonical operations tab semantics where `active` represents healthy queued or running work, `blocked` reproduces warning, stalled, or unusually long-running follow-up, and `failed` reproduces terminal failure follow-up. enum: - all - active - blocked - succeeded - partial - failed ProblemFamily: type: string enum: - findings - governance - compare - operations FindingUniverse: type: string enum: - new_drift_only - open_drift - active_findings SeverityUniverse: type: string enum: - high_only - high_and_critical FindingsDestinationFilterState: type: object additionalProperties: false required: - tenant properties: tenant: type: string tab: oneOf: - $ref: '#/components/schemas/FindingsTab' - type: 'null' status: type: - string - 'null' high_severity: type: - boolean - 'null' finding_type: type: - string - 'null' OperationsDestinationFilterState: type: object additionalProperties: false required: - workspace_id - tenant_id properties: workspace_id: type: integer tenant_id: type: - integer - string activeTab: oneOf: - $ref: '#/components/schemas/OperationsTab' - type: 'null' navigationContext: type: - string - 'null' DestinationKind: type: string enum: - tenant_findings - baseline_compare_landing - canonical_operations - operation_detail - finding_detail - none SurfaceDestination: type: object additionalProperties: false allOf: - if: properties: actionDisabled: const: true then: required: - helperText required: - kind - tenantScoped - semanticsLabel properties: kind: $ref: '#/components/schemas/DestinationKind' tenantScoped: type: boolean semanticsLabel: type: string filterState: oneOf: - $ref: '#/components/schemas/FindingsDestinationFilterState' - $ref: '#/components/schemas/OperationsDestinationFilterState' - type: 'null' actionDisabled: type: - boolean - 'null' helperText: type: - string - 'null' ActionableDestinationKind: type: string enum: - tenant_findings - baseline_compare_landing - canonical_operations KpiDestinationKind: type: string enum: - tenant_findings - canonical_operations - none ActionableSurfaceDestination: allOf: - $ref: '#/components/schemas/SurfaceDestination' - type: object properties: kind: $ref: '#/components/schemas/ActionableDestinationKind' KpiSurfaceDestination: allOf: - $ref: '#/components/schemas/SurfaceDestination' - type: object properties: kind: $ref: '#/components/schemas/KpiDestinationKind' KpiMetric: type: object additionalProperties: false required: - key - label - count - problemFamily - destination properties: key: type: string label: type: string count: type: integer minimum: 0 problemFamily: type: string enum: - findings - operations findingUniverse: oneOf: - $ref: '#/components/schemas/FindingUniverse' - type: 'null' severityUniverse: oneOf: - type: string enum: - high_only - high_and_critical - type: 'null' destination: $ref: '#/components/schemas/KpiSurfaceDestination' AttentionItem: type: object additionalProperties: false anyOf: - required: - actionLabel - required: - nextStepLabel - properties: actionDisabled: const: true required: - actionDisabled - helperText required: - key - title - body - badge - tone - problemFamily - destination properties: key: type: string title: type: string body: type: string supportingMessage: type: - string - 'null' badge: type: string tone: type: string enum: - success - warning - danger - info - gray problemFamily: $ref: '#/components/schemas/ProblemFamily' actionLabel: type: - string - 'null' actionDisabled: type: - boolean - 'null' helperText: type: - string - 'null' nextStepLabel: type: - string - 'null' destination: $ref: '#/components/schemas/ActionableSurfaceDestination' CompareSummary: type: object additionalProperties: false required: - stateFamily - tone - headline - positiveClaimAllowed - nextAction properties: stateFamily: type: string enum: - positive - caution - stale - action_required - in_progress - unavailable tone: type: string enum: - success - warning - danger - info - gray headline: type: string supportingMessage: type: - string - 'null' positiveClaimAllowed: type: boolean nextAction: $ref: '#/components/schemas/SurfaceDestination' DiagnosticSurfaceSummary: type: object additionalProperties: false required: - heading - role - doesNotDefinePosture - fullRowClick - detailDestinationKind properties: heading: type: string role: type: string enum: - diagnostic_recency doesNotDefinePosture: type: boolean fullRowClick: type: boolean detailDestinationKind: type: string enum: - finding_detail - operation_detail TenantDashboardTruthBundle: type: object additionalProperties: false required: - tenantId - workspaceId - kpis - attentionItems - compareSummary - recentFindings - recentOperations properties: tenantId: type: integer workspaceId: type: integer kpis: type: array items: $ref: '#/components/schemas/KpiMetric' attentionItems: type: array items: $ref: '#/components/schemas/AttentionItem' compareSummary: $ref: '#/components/schemas/CompareSummary' recentFindings: $ref: '#/components/schemas/DiagnosticSurfaceSummary' recentOperations: $ref: '#/components/schemas/DiagnosticSurfaceSummary'