openapi: 3.1.0 info: title: TenantPilot Internal Finding Responsibility Contract version: 1.0.0 description: | Internal review contract for Spec 219. These are operator-facing Filament surfaces, not public API endpoints. The document exists so the feature has an explicit, reviewable contract under specs/.../contracts/. paths: /admin/t/{tenant}/findings: get: summary: Tenant findings list with explicit responsibility semantics parameters: - $ref: '#/components/parameters/TenantPathParam' responses: '200': description: Findings list rendered content: application/json: schema: $ref: '#/components/schemas/FindingListSurface' /admin/t/{tenant}/findings/{finding}: get: summary: Finding detail with owner, assignee, and optional exception-owner context parameters: - $ref: '#/components/parameters/TenantPathParam' - $ref: '#/components/parameters/FindingPathParam' responses: '200': description: Finding detail rendered content: application/json: schema: $ref: '#/components/schemas/FindingDetailSurface' /admin/t/{tenant}/findings/{finding}/responsibility: post: summary: Update finding owner and assignee semantics description: Conceptual responsibility-update contract implemented by Filament action endpoints. parameters: - $ref: '#/components/parameters/TenantPathParam' - $ref: '#/components/parameters/FindingPathParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ResponsibilityUpdateRequest' responses: '200': description: Responsibility updated content: application/json: schema: $ref: '#/components/schemas/ResponsibilityUpdateResult' '403': description: Actor is an in-scope tenant member but lacks assignment capability '404': description: Tenant or finding is outside the actor scope /admin/t/{tenant}/findings/{finding}/exception-request: post: summary: Request exception with explicitly separate exception owner description: Conceptual exception-request contract implemented by Filament action endpoints. parameters: - $ref: '#/components/parameters/TenantPathParam' - $ref: '#/components/parameters/FindingPathParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExceptionRequestInput' responses: '200': description: Exception request accepted content: application/json: schema: $ref: '#/components/schemas/ExceptionOwnershipBoundaryResult' components: parameters: TenantPathParam: name: tenant in: path required: true schema: type: string description: Tenant route identifier for tenant-scoped findings surfaces. FindingPathParam: name: finding in: path required: true schema: type: integer description: Tenant-owned finding identifier. schemas: UserReference: type: object additionalProperties: false required: - id - display_name properties: id: type: integer display_name: type: string ResponsibilityState: type: string description: Uses internal slugs for API and test contracts. The operator-facing UI label for `orphaned_accountability` is `orphaned accountability`. enum: - orphaned_accountability - owned_unassigned - assigned FindingResponsibilitySummary: type: object additionalProperties: false required: - finding_id - workflow_status - responsibility_state properties: finding_id: type: integer workflow_status: type: string owner: allOf: - $ref: '#/components/schemas/UserReference' nullable: true assignee: allOf: - $ref: '#/components/schemas/UserReference' nullable: true responsibility_state: $ref: '#/components/schemas/ResponsibilityState' accountability_gap: type: boolean exception_owner: allOf: - $ref: '#/components/schemas/UserReference' nullable: true description: Present only when a finding exception exists or is shown in current context. FindingListSurface: type: object additionalProperties: false required: - surface - collection_route - primary_inspect_model - items properties: surface: const: tenant_findings_list collection_route: const: /admin/t/{tenant}/findings primary_inspect_model: const: finding items: type: array items: $ref: '#/components/schemas/FindingResponsibilitySummary' FindingDetailSurface: allOf: - $ref: '#/components/schemas/FindingResponsibilitySummary' - type: object additionalProperties: false required: - surface - detail_route properties: surface: const: finding_detail detail_route: const: /admin/t/{tenant}/findings/{finding} ResponsibilityUpdateRequest: type: object additionalProperties: false properties: owner_user_id: type: integer nullable: true description: Accountable owner for the finding outcome. assignee_user_id: type: integer nullable: true description: Active remediation assignee for the finding. ResponsibilityUpdateResult: type: object additionalProperties: false required: - change_classification - responsibility properties: change_classification: type: string description: Uses explicit slugs for single-role clears and `owner_and_assignee` whenever both fields change in one update, including mixed set/clear combinations. enum: - owner_only - assignee_only - owner_and_assignee - clear_owner - clear_assignee responsibility: $ref: '#/components/schemas/FindingResponsibilitySummary' ExceptionRequestInput: type: object additionalProperties: false required: - owner_user_id - request_reason - review_due_at properties: owner_user_id: type: integer description: Owner of the exception artifact, not the finding owner. request_reason: type: string review_due_at: type: string format: date-time expires_at: type: string format: date-time nullable: true ExceptionOwnershipBoundaryResult: type: object additionalProperties: false required: - finding_owner_preserved - exception_owner properties: finding_owner_preserved: type: boolean const: true exception_owner: $ref: '#/components/schemas/UserReference'