openapi: 3.1.0 info: title: Findings Intake & Team Queue Surface Contract version: 1.1.0 description: >- Internal reference contract for the canonical Findings intake queue, the narrow Claim finding shortcut, and intake continuity into tenant finding detail and My Findings. The application continues to return rendered HTML through Filament and Livewire. The vendor media types below document the structured page and action models that must be derivable before rendering. This is not a public API commitment. paths: /admin/findings/intake: get: summary: Canonical shared findings intake queue description: >- Returns the rendered admin-plane intake queue for visible unassigned findings in the current workspace. The page always keeps the fixed intake scope and may apply an active-tenant prefilter. Queue views are limited to Unassigned and Needs triage. responses: '302': description: Redirects into the existing workspace chooser flow when workspace context is not yet established '200': description: Rendered Findings intake page content: text/html: schema: type: string application/vnd.tenantpilot.findings-intake+json: schema: $ref: '#/components/schemas/FindingsIntakePage' '403': description: Workspace membership exists but no currently viewable findings scope exists for intake disclosure anywhere in the workspace '404': description: Workspace scope is not visible because membership is missing or out of scope /admin/findings/intake/{finding}/claim: post: summary: Claim a visible intake finding into personal execution description: >- Logical contract for the Livewire-backed Claim finding row action after the operator has reviewed the lightweight preview/confirmation content. The server must re-check entitlement, assign capability, and current assignee under lock before mutating the record. parameters: - name: finding in: path required: true schema: type: integer responses: '200': description: Claim succeeded and the finding left intake content: application/vnd.tenantpilot.findings-intake-claim+json: schema: $ref: '#/components/schemas/ClaimFindingResult' '403': description: Viewer is in scope but lacks the existing findings assign capability '404': description: Workspace or tenant scope is not visible for the referenced finding '409': description: The row is no longer claimable because another operator claimed it first or it otherwise left intake scope before mutation /admin/t/{tenant}/findings/{finding}: get: summary: Tenant finding detail with intake continuity support description: >- Returns the rendered tenant finding detail page. The logical contract below documents only the continuity inputs required when the page is opened from Findings intake. parameters: - name: tenant in: path required: true schema: type: integer - name: finding in: path required: true schema: type: integer - name: nav in: query required: false style: deepObject explode: true schema: $ref: '#/components/schemas/CanonicalNavigationContext' responses: '200': description: Rendered tenant finding detail page content: text/html: schema: type: string application/vnd.tenantpilot.finding-detail-from-intake+json: schema: $ref: '#/components/schemas/FindingDetailContinuation' '403': description: Viewer is in scope but lacks the existing findings capability for the tenant detail destination '404': description: Tenant or finding is not visible because workspace or tenant entitlement is missing components: schemas: FindingsIntakePage: type: object required: - header - appliedScope - queueViews - summaryCounts - rows - emptyState properties: header: $ref: '#/components/schemas/IntakeHeader' appliedScope: $ref: '#/components/schemas/IntakeAppliedScope' queueViews: type: array items: $ref: '#/components/schemas/QueueViewDefinition' summaryCounts: $ref: '#/components/schemas/IntakeSummaryCounts' rows: description: >- Rows are ordered overdue first, reopened second, new third, then remaining unassigned backlog. Within each bucket, rows with due dates sort by dueAt ascending, rows without due dates sort last, and remaining ties sort by findingId descending. type: array items: $ref: '#/components/schemas/IntakeFindingRow' emptyState: oneOf: - $ref: '#/components/schemas/IntakeEmptyState' - type: 'null' IntakeHeader: type: object required: - title - description properties: title: type: string enum: - Findings intake description: type: string clearTenantFilterAction: oneOf: - $ref: '#/components/schemas/ActionLink' - type: 'null' IntakeAppliedScope: type: object required: - workspaceScoped - fixedScope - queueView - tenantPrefilterSource properties: workspaceScoped: type: boolean fixedScope: type: string enum: - visible_unassigned_open_findings_only queueView: type: string enum: - unassigned - needs_triage tenantPrefilterSource: type: string enum: - active_tenant_context - explicit_filter - none tenantLabel: type: - string - 'null' QueueViewDefinition: type: object required: - key - label - fixed - active properties: key: type: string enum: - unassigned - needs_triage label: type: string fixed: type: boolean active: type: boolean badgeCount: type: - integer - 'null' minimum: 0 IntakeSummaryCounts: type: object description: Counts derived only from visible intake rows. required: - visibleUnassigned - visibleNeedsTriage - visibleOverdue properties: visibleUnassigned: type: integer minimum: 0 visibleNeedsTriage: type: integer minimum: 0 visibleOverdue: type: integer minimum: 0 IntakeFindingRow: type: object required: - findingId - tenantId - tenantLabel - summary - severity - status - intakeReason - dueState - detailUrl properties: findingId: type: integer tenantId: type: integer tenantLabel: type: string summary: type: string severity: $ref: '#/components/schemas/Badge' status: $ref: '#/components/schemas/Badge' dueAt: type: - string - 'null' format: date-time dueState: $ref: '#/components/schemas/DueState' ownerLabel: type: - string - 'null' intakeReason: type: string enum: - Unassigned - Needs triage claimAction: oneOf: - $ref: '#/components/schemas/ClaimFindingAffordance' - type: 'null' detailUrl: type: string navigationContext: oneOf: - $ref: '#/components/schemas/CanonicalNavigationContext' - type: 'null' ClaimFindingAffordance: type: object required: - actionId - label - enabled - requiresConfirmation properties: actionId: type: string enum: - claim label: type: string enum: - Claim finding enabled: type: boolean requiresConfirmation: type: boolean enum: - true confirmationTitle: type: - string - 'null' confirmationBody: type: - string - 'null' disabledReason: type: - string - 'null' DueState: type: object required: - label - tone properties: label: type: string tone: type: string enum: - calm - warning - danger IntakeEmptyState: type: object required: - title - body - action properties: title: type: string body: type: string reason: type: string enum: - no_visible_intake_work - active_tenant_prefilter_excludes_rows action: oneOf: - $ref: '#/components/schemas/OpenMyFindingsActionLink' - $ref: '#/components/schemas/ClearTenantFilterActionLink' ClaimFindingResult: type: object required: - findingId - tenantId - assigneeUserId - auditActionId - queueOutcome - nextPrimaryAction properties: findingId: type: integer tenantId: type: integer assigneeUserId: type: integer auditActionId: type: string enum: - finding.assigned queueOutcome: type: string enum: - removed_from_intake nextPrimaryAction: $ref: '#/components/schemas/OpenMyFindingsActionLink' nextInspectAction: oneOf: - $ref: '#/components/schemas/OpenFindingActionLink' - type: 'null' FindingDetailContinuation: type: object description: >- Continuity payload for tenant finding detail when it is opened from the Findings intake queue. The backLink is present whenever canonical intake navigation context is provided and may be null only for direct entry without intake continuity context. required: - findingId - tenantId properties: findingId: type: integer tenantId: type: integer backLink: oneOf: - $ref: '#/components/schemas/BackToFindingsIntakeActionLink' - type: 'null' CanonicalNavigationContext: type: object required: - source_surface - canonical_route_name properties: source_surface: type: string canonical_route_name: type: string tenant_id: type: - integer - 'null' back_label: type: - string - 'null' back_url: type: - string - 'null' ActionLink: type: object required: - label - url properties: label: type: string url: type: string OpenMyFindingsActionLink: allOf: - $ref: '#/components/schemas/ActionLink' - type: object properties: label: type: string enum: - Open my findings OpenFindingActionLink: allOf: - $ref: '#/components/schemas/ActionLink' - type: object properties: label: type: string enum: - Open finding ClearTenantFilterActionLink: allOf: - $ref: '#/components/schemas/ActionLink' - type: object properties: label: type: string enum: - Clear tenant filter BackToFindingsIntakeActionLink: allOf: - $ref: '#/components/schemas/ActionLink' - type: object properties: label: type: string enum: - Back to findings intake Badge: type: object required: - label properties: label: type: string color: type: - string - 'null'