openapi: 3.1.0 info: title: Portfolio Triage Review State Internal Surface Contract version: 0.1.0 summary: Internal logical contract for persisted triage-review state, current-set progress, and operator mutations description: | This contract is an internal planning artifact for Spec 189. The affected routes still render HTML through Filament and Livewire. The schemas below describe the bounded read models and mutation payloads that must be derivable or writable before portfolio-triage surfaces render review-state badges, progress summaries, or mutation actions. servers: - url: /internal x-triage-review-consumers: - surface: workspace.overview.progress sourceFiles: - apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php - apps/platform/app/Filament/Widgets/Workspace/WorkspaceSummaryStats.php - apps/platform/app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php mustRender: - concern_family - affected_total - reviewed_count - follow_up_needed_count - changed_since_review_count - surface: tenant.registry.triage sourceFiles: - apps/platform/app/Filament/Resources/TenantResource.php - apps/platform/app/Filament/Resources/TenantResource/Pages/ListTenants.php mustRender: - concern_family - derived_review_state - reviewed_at - reviewed_by_user_id mustAccept: - review_state - backup_posture - recovery_evidence - triage_sort - surface: tenant.dashboard.arrival sourceFiles: - apps/platform/app/Filament/Pages/TenantDashboard.php - apps/platform/app/Filament/Widgets/Tenant/TenantTriageArrivalContinuity.php mustRender: - concern_family - derived_review_state - mark_reviewed_action - mark_follow_up_needed_action paths: /admin: get: summary: Workspace overview exposes current-set triage progress summaries operationId: viewWorkspaceOverviewWithTriageReviewProgress responses: '200': description: Rendered workspace overview with additive progress summary semantics content: text/html: schema: type: string application/vnd.tenantpilot.workspace-triage-progress+json: schema: $ref: '#/components/schemas/WorkspaceTriageProgressBundle' '404': description: Workspace scope is not available to the actor /admin/tenants: get: summary: Tenant registry triage renders review-state badges and accepts review-state filters operationId: viewTenantRegistryWithTriageReviewState parameters: - name: backup_posture in: query required: false schema: type: array items: $ref: '#/components/schemas/BackupConcernState' - name: recovery_evidence in: query required: false schema: type: array items: $ref: '#/components/schemas/RecoveryConcernState' - name: review_state in: query required: false schema: type: array items: $ref: '#/components/schemas/DerivedReviewState' - name: triage_sort in: query required: false schema: type: string enum: - worst_first responses: '200': description: Rendered tenant registry with concern truth plus review-state context content: text/html: schema: type: string application/vnd.tenantpilot.tenant-registry-triage-review+json: schema: $ref: '#/components/schemas/TenantRegistryTriageReviewBundle' '404': description: Workspace scope is not available to the actor /admin/t/{tenant}: get: summary: Tenant dashboard arrival continuity shows the current review state for the focused concern family operationId: viewTenantDashboardWithTriageReviewState parameters: - name: tenant in: path required: true schema: type: string - name: arrival in: query required: false schema: type: string description: Existing portfolio-arrival token carrying concern-family focus. responses: '200': description: Rendered tenant dashboard with optional continuity review-state controls content: text/html: schema: type: string application/vnd.tenantpilot.tenant-dashboard-triage-review+json: schema: $ref: '#/components/schemas/TenantDashboardTriageReviewBundle' '404': description: Tenant is outside workspace or tenant entitlement scope /internal/workspaces/{workspace}/tenants/{tenant}/triage-review-state: put: summary: Upsert the active triage-review record for one workspace, tenant, and concern family operationId: upsertTenantTriageReviewState parameters: - name: workspace in: path required: true schema: type: integer - name: tenant in: path required: true schema: type: integer requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TriageReviewMutationRequest' responses: '200': description: Active review record updated and current derived state returned content: application/vnd.tenantpilot.triage-review-state+json: schema: $ref: '#/components/schemas/TriageReviewMutationResult' '403': description: Actor is in scope but lacks the capability to mutate triage review state '404': description: Workspace or tenant is outside the actor's entitlement scope components: schemas: ConcernFamily: type: string enum: - backup_health - recovery_evidence BackupConcernState: type: string enum: - absent - stale - degraded RecoveryConcernState: type: string enum: - unvalidated - weakened ConcernState: type: string enum: - absent - stale - degraded - unvalidated - weakened ManualReviewState: type: string enum: - reviewed - follow_up_needed DerivedReviewState: type: string enum: - not_reviewed - reviewed - follow_up_needed - changed_since_review TriageReviewSnapshot: type: object additionalProperties: false required: - concernFamily - concernState properties: concernFamily: $ref: '#/components/schemas/ConcernFamily' concernState: $ref: '#/components/schemas/ConcernState' reasonCode: type: - string - 'null' severityKey: type: - string - 'null' supportingKey: type: - string - 'null' ActiveTriageReviewRecord: type: object additionalProperties: false required: - workspaceId - tenantId - concernFamily - currentState - reviewedAt - reviewFingerprint properties: workspaceId: type: integer tenantId: type: integer concernFamily: $ref: '#/components/schemas/ConcernFamily' currentState: $ref: '#/components/schemas/ManualReviewState' reviewedAt: type: string format: date-time reviewedByUserId: type: - integer - 'null' reviewFingerprint: type: string reviewSnapshot: $ref: '#/components/schemas/TriageReviewSnapshot' lastSeenMatchingAt: type: - string - 'null' format: date-time resolvedAt: type: - string - 'null' format: date-time ResolvedTriageReviewState: type: object additionalProperties: false required: - concernFamily - derivedState - currentConcernPresent properties: concernFamily: $ref: '#/components/schemas/ConcernFamily' derivedState: $ref: '#/components/schemas/DerivedReviewState' currentConcernPresent: type: boolean currentFingerprint: type: - string - 'null' reviewedAt: type: - string - 'null' format: date-time reviewedByUserId: type: - integer - 'null' snapshot: anyOf: - $ref: '#/components/schemas/TriageReviewSnapshot' - type: 'null' TriageProgressSummary: type: object additionalProperties: false required: - concernFamily - affectedTotal - reviewedCount - followUpNeededCount - changedSinceReviewCount - notReviewedCount properties: concernFamily: $ref: '#/components/schemas/ConcernFamily' affectedTotal: type: integer reviewedCount: type: integer followUpNeededCount: type: integer changedSinceReviewCount: type: integer notReviewedCount: type: integer TriageReviewMutationRequest: type: object additionalProperties: false required: - concernFamily - state - currentFingerprint - snapshot properties: concernFamily: $ref: '#/components/schemas/ConcernFamily' state: $ref: '#/components/schemas/ManualReviewState' currentFingerprint: type: string snapshot: $ref: '#/components/schemas/TriageReviewSnapshot' sourceSurface: type: - string - 'null' enum: - tenant_registry - tenant_dashboard_arrival - null TriageReviewMutationResult: type: object additionalProperties: false required: - activeRecord - resolvedState properties: activeRecord: $ref: '#/components/schemas/ActiveTriageReviewRecord' resolvedState: $ref: '#/components/schemas/ResolvedTriageReviewState' WorkspaceTriageProgressBundle: type: object additionalProperties: false required: - summaries properties: summaries: type: array items: $ref: '#/components/schemas/TriageProgressSummary' TenantRegistryRowReviewState: type: object additionalProperties: false required: - tenantId - concernFamily - derivedState properties: tenantId: type: integer concernFamily: $ref: '#/components/schemas/ConcernFamily' derivedState: $ref: '#/components/schemas/DerivedReviewState' reviewedAt: type: - string - 'null' format: date-time reviewedByUserId: type: - integer - 'null' TenantRegistryTriageReviewBundle: type: object additionalProperties: false required: - rows properties: concernFamilyFocus: type: - string - 'null' enum: - backup_health - recovery_evidence - null rows: type: array items: $ref: '#/components/schemas/TenantRegistryRowReviewState' activeFilters: type: - object - 'null' additionalProperties: true TenantDashboardTriageReviewBundle: type: object additionalProperties: false required: - canRenderReviewControls properties: concernFamilyFocus: anyOf: - $ref: '#/components/schemas/ConcernFamily' - type: 'null' reviewState: anyOf: - $ref: '#/components/schemas/ResolvedTriageReviewState' - type: 'null' canRenderReviewControls: type: boolean markReviewedAllowed: type: boolean markFollowUpNeededAllowed: type: boolean