TenantAtlas/specs/231-finding-outcome-taxonomy/data-model.md
Ahmed Darrazi 807578dd9c
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 4m16s
feat: implement finding outcome taxonomy
2026-04-23 09:24:59 +02:00

9.6 KiB

Data Model: Finding Outcome Taxonomy & Verification Semantics

Overview

This feature does not add a new table or a new top-level persisted entity. It reuses the current findings row as the source of truth for current terminal meaning, keeps reopen rationale in audit metadata, and derives verification or reporting buckets through one findings-local semantics helper.

Entity: Finding

Persistence: existing findings table
Owner: tenant-owned record
Primary responsibility: current workflow status, current terminal-outcome key, timestamps, and tenant-scoped operational ownership

Relevant persisted fields

Field Type Source Notes
id integer existing Primary key
workspace_id integer existing Workspace isolation boundary
tenant_id integer existing Tenant isolation boundary
status string existing Primary lifecycle status; remains one of new, acknowledged, triaged, in_progress, reopened, resolved, closed, risk_accepted
severity string existing Existing priority and SLA signal
resolved_reason string nullable existing Becomes a bounded canonical resolve key instead of free-form prose
closed_reason string nullable existing Becomes a bounded canonical close key and remains the stored reason for risk_accepted
resolved_at datetime nullable existing Marks the current resolved terminal timestamp
closed_at datetime nullable existing Marks the current closed or risk-accepted terminal timestamp
reopened_at datetime nullable existing Marks the current reopen timestamp
closed_by_user_id integer nullable existing Current actor for close and risk-accept paths
owner_user_id integer nullable existing Accountability owner
assignee_user_id integer nullable existing Active assignee
evidence_jsonb jsonb existing Current supporting evidence; unchanged in this slice

Relationships

Relationship Type Notes
tenant() belongsTo Tenant scope owner
ownerUser() belongsTo Accountability owner
assigneeUser() belongsTo Active assignee
closedByUser() belongsTo Actor for close/risk accept
findingException() hasOne Existing risk-governance truth from Spec 154

Validation rules introduced by this feature

Rule Description
status No new status is introduced; all existing transition rules stay in force
resolved_reason Required for resolve and system-clear transitions; must be a canonical key from the resolve-reason family
closed_reason Required for close and risk-accept transitions; must be a canonical key from the close-reason family or the risk-accept key
reopen_reason Required for reopen transitions; remains audit metadata and must be a canonical key from the reopen-reason family

Canonical reason families

Resolve reason keys

Key Meaning Derived verification state
remediated Operator declares that remediation work was completed pending_verification
no_longer_drifting Trusted compare no longer reproduces prior drift verified_cleared
permission_granted Trusted permission evidence no longer reproduces the finding condition verified_cleared
permission_removed_from_registry Trusted permission evidence confirms the triggering permission was removed verified_cleared
role_assignment_removed Trusted role evidence confirms the triggering assignment was removed verified_cleared
ga_count_within_threshold Trusted role evidence confirms the triggering count is now safe verified_cleared

Close reason keys

Key Meaning Outcome family
false_positive The finding should not have been actionable administrative_closure
duplicate The finding duplicates another case administrative_closure
no_longer_applicable The finding no longer applies to the tenant context administrative_closure
accepted_risk Existing accepted-risk path only; still governed by exception validity accepted_risk

Reopen reason keys

Key Meaning Persistence
recurred_after_resolution A previously addressed condition reappeared audit metadata only
verification_failed Trusted evidence contradicted the earlier resolved outcome audit metadata only
manual_reassessment An operator reopened the finding after review audit metadata only

Derived facets from the current row

Derived facet Source Meaning
verification_state status + resolved_reason pending_verification, verified_cleared, or not_applicable
terminal_outcome_key status + canonical reason key Stable UI/reporting key such as resolved_pending_verification, verified_cleared, closed_false_positive, closed_duplicate, closed_no_longer_applicable, or risk_accepted
report_bucket terminal_outcome_key + governance validity Report-friendly aggregation bucket
outcome_label terminal_outcome_key Canonical operator wording

State transitions

From Action Stored result Derived outcome
new, triaged, in_progress, reopened, acknowledged resolve(remediated) status=resolved, resolved_reason=remediated Resolved pending verification
open statuses close(false_positive) status=closed, closed_reason=false_positive Closed as false positive
open statuses close(duplicate) status=closed, closed_reason=duplicate Closed as duplicate
open statuses close(no_longer_applicable) status=closed, closed_reason=no_longer_applicable Closed as no longer applicable
open statuses riskAccept(accepted_risk) status=risk_accepted, closed_reason=accepted_risk Risk accepted with separate governance validity
resolved with resolved_reason=remediated trusted system clear status=resolved, resolved_reason=<system clear key> Verified cleared
open statuses direct trusted system clear status=resolved, resolved_reason=<system clear key> Verified cleared
resolved, closed, risk_accepted reopen(<canonical reopen key>) status=reopened, terminal reason fields cleared, reopen reason recorded in audit metadata open finding again

Entity: FindingException

Persistence: existing finding_exceptions table
Owner: tenant-owned record
Primary responsibility: governance validity for risk_accepted

Relevant fields consumed by this feature

Field Type Notes
status string Existing workflow for exception requests and approvals
current_validity_state string Current validity used by FindingRiskGovernanceResolver
effective_from datetime nullable Existing validity window
expires_at datetime nullable Existing validity window
review_due_at datetime nullable Existing governance follow-up signal

Rule in this feature

  • FindingException continues to determine whether risk_accepted is governed safely.
  • FindingException does not contribute to verified_cleared and does not change remediation buckets.

Derived read model: FindingOutcomeSemantics

Persistence: not persisted
Owner: findings-local support helper
Primary responsibility: unify list, detail, filter, and reporting semantics from current finding truth

Inputs

Input Source
status Finding row
resolved_reason Finding row
closed_reason Finding row
findingException validity FindingException relationship via existing resolver
system_origin and prior workflow steps audit metadata, only when reconstructing history or detailed provenance

Outputs

Output Type Notes
terminalOutcomeKey string Stable internal key
label string Canonical operator-facing wording
verificationState string pending_verification, verified_cleared, not_applicable
reportBucket string Aggregation bucket for reviews and exports
historicalContext string nullable Reuses current resolver-style explanatory text where appropriate

Report bucket mapping

Terminal outcome key Report bucket
resolved_pending_verification remediation_pending_verification
verified_cleared remediation_verified
closed_false_positive administrative_closure
closed_duplicate administrative_closure
closed_no_longer_applicable administrative_closure
risk_accepted accepted_risk

Audit metadata additions or constraints

Key Existing/New Purpose
resolved_reason existing Canonical current resolve key
closed_reason existing Canonical current close or risk-accept key
reopened_reason existing Canonical reopen key for reviewability
system_origin existing Provenance flag for system transitions
resolved_at, closed_at, reopened_at existing Timeline reconstruction

Audit rule

  • Audit metadata remains the place to reconstruct path history, such as whether a verified-clear outcome happened directly through automation or after a prior manual remediated transition.
  • The current row remains the source of truth for current filters and summaries.