openapi: 3.1.0 info: title: Tenant Governance Aggregate Internal Surface Contract version: 0.1.0 summary: Internal logical contract for the shared tenant-governance summary aggregate description: | This contract is an internal planning artifact for Spec 168. It documents the derived tenant-governance aggregate and the way tenant dashboard, banner, and Baseline Compare landing surfaces consume it. 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-governance-consumers: - surface: tenant.dashboard.needs_attention summarySource: tenant_governance_aggregate accessPattern: widget_safe guardScope: - app/Filament/Widgets/Dashboard/NeedsAttention.php requiredMarkers: - 'TenantGovernanceAggregate' - 'Needs Attention' maxOccurrences: - needle: 'Finding::query()' max: 0 - surface: tenant.dashboard.baseline_governance summarySource: tenant_governance_aggregate accessPattern: widget_safe guardScope: - app/Filament/Widgets/Dashboard/BaselineCompareNow.php requiredMarkers: - 'TenantGovernanceAggregate' - 'Baseline Governance' - surface: tenant.banner.baseline_compare_coverage summarySource: tenant_governance_aggregate accessPattern: widget_safe guardScope: - app/Filament/Widgets/Tenant/BaselineCompareCoverageBanner.php requiredMarkers: - 'TenantGovernanceAggregate' - 'nextActionUrl' - surface: tenant.page.baseline_compare_landing summarySource: tenant_governance_aggregate accessPattern: page_safe guardScope: - app/Filament/Pages/BaselineCompareLanding.php requiredMarkers: - 'TenantGovernanceAggregate' - 'Compare now' paths: /tenants/{tenant}/governance-aggregate: get: summary: Resolve the derived tenant-governance aggregate for one tenant operationId: resolveTenantGovernanceAggregate parameters: - name: tenant in: path required: true schema: type: string description: Tenant route key or canonical tenant identifier for the current tenant scope. - name: surface in: query required: false schema: $ref: '#/components/schemas/GovernanceSurface' responses: '200': description: Aggregate resolved for the current tenant scope content: application/vnd.tenantpilot.tenant-governance-aggregate+json: schema: $ref: '#/components/schemas/TenantGovernanceAggregate' '403': description: Actor is in scope but lacks the capability required to view the target surface '404': description: Tenant is outside workspace or tenant entitlement scope /admin/t/{tenant}: get: summary: Tenant dashboard governance summary surfaces operationId: viewTenantDashboardGovernance parameters: - name: tenant in: path required: true schema: type: string responses: '200': description: Rendered tenant dashboard with shared governance summary surfaces content: text/html: schema: type: string application/vnd.tenantpilot.tenant-dashboard-governance+json: schema: $ref: '#/components/schemas/TenantDashboardGovernanceBundle' '403': description: Actor is in scope but lacks the required tenant capability '404': description: Tenant is not visible in the current workspace or membership scope /admin/t/{tenant}/baseline-compare-landing: get: summary: Baseline Compare landing governance summary and diagnostics split operationId: viewBaselineCompareLandingGovernance parameters: - name: tenant in: path required: true schema: type: string responses: '200': description: Rendered Baseline Compare landing page content: text/html: schema: type: string application/vnd.tenantpilot.baseline-compare-landing-governance+json: schema: $ref: '#/components/schemas/BaselineCompareLandingGovernanceView' '403': description: Actor is in scope but lacks the required tenant capability '404': description: Tenant is not visible in the current workspace or membership scope components: schemas: GovernanceSurface: type: string enum: - dashboard_needs_attention - dashboard_baseline_governance - baseline_compare_landing - coverage_banner NextActionTarget: type: string enum: - findings - run - landing - none GovernanceCounts: type: object additionalProperties: false required: - visibleDriftFindingsCount - overdueOpenFindingsCount - expiringGovernanceCount - lapsedGovernanceCount - activeNonNewFindingsCount - highSeverityActiveFindingsCount properties: visibleDriftFindingsCount: type: integer minimum: 0 overdueOpenFindingsCount: type: integer minimum: 0 expiringGovernanceCount: type: integer minimum: 0 lapsedGovernanceCount: type: integer minimum: 0 activeNonNewFindingsCount: type: integer minimum: 0 highSeverityActiveFindingsCount: type: integer minimum: 0 NextActionIntent: type: object additionalProperties: false required: - label - target properties: label: type: string target: $ref: '#/components/schemas/NextActionTarget' ComparePosture: type: object additionalProperties: false required: - compareState - stateFamily - tone - headline - positiveClaimAllowed properties: compareState: type: string enum: - no_tenant - no_assignment - no_snapshot - idle - comparing - failed - ready 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' reasonCode: type: - string - 'null' lastComparedLabel: type: - string - 'null' positiveClaimAllowed: type: boolean TenantGovernanceAggregate: type: object additionalProperties: false required: - tenantId - workspaceId - posture - counts - nextAction properties: tenantId: type: integer workspaceId: type: integer profileName: type: - string - 'null' posture: $ref: '#/components/schemas/ComparePosture' counts: $ref: '#/components/schemas/GovernanceCounts' nextAction: $ref: '#/components/schemas/NextActionIntent' operationRunId: type: - integer - 'null' diagnosticsOwner: type: string enum: - baseline_compare_stats NeedsAttentionItem: type: object additionalProperties: false required: - title - badge - badgeColor properties: title: type: string body: type: - string - 'null' supportingMessage: type: - string - 'null' badge: type: string badgeColor: type: string nextStep: type: - string - 'null' TenantDashboardGovernanceBundle: type: object additionalProperties: false required: - aggregate properties: aggregate: $ref: '#/components/schemas/TenantGovernanceAggregate' needsAttentionItems: type: array items: $ref: '#/components/schemas/NeedsAttentionItem' baselineGovernanceCard: type: object additionalProperties: false required: - aggregate properties: aggregate: $ref: '#/components/schemas/TenantGovernanceAggregate' BaselineCompareLandingGovernanceView: type: object additionalProperties: false required: - aggregate - diagnosticsPolicy properties: aggregate: $ref: '#/components/schemas/TenantGovernanceAggregate' diagnosticsPolicy: type: object additionalProperties: false required: - compareDiagnosticsRemainLocal - evidenceGapDetailsRemainLocal - compareActionUnchanged properties: compareDiagnosticsRemainLocal: type: boolean evidenceGapDetailsRemainLocal: type: boolean compareActionUnchanged: type: boolean