# Feature Specification: Decision Register & Approval Workflow v1

**Feature Branch**: `265-decision-register-approval`  
**Created**: 2026-05-02  
**Status**: Ready for implementation  
**Input**: User description: "Prepare Decision Register & Approval Workflow v1 so workspace operators can review, own, close, and audit exception and accepted-risk governance decisions from one bounded register without inventing a generic task engine or broader workflow platform."

## Spec Candidate Check *(mandatory - SPEC-GATE-001)*

- **Problem**: TenantPilot already has repo-real accepted-risk lifecycle truth through `FindingException`, append-only `FindingExceptionDecision` history, existing approval actions on the exception detail flow, and decision-entry surfaces such as `GovernanceInbox` and `FindingExceptionsQueue`, but operators still lack one calm register that answers which governance decisions need approval, renewal, review, or closure now.
- **Today's failure**: Operators still reconstruct decision follow-through by hopping between the exception queue, exception detail, customer-safe review context, and audit history. Ownership, due date, closure reason, and next action remain harder to scan than they should be, which makes expiring or lapsed accepted-risk governance feel like scattered admin detail instead of an explicit decision workflow.
- **User-visible improvement**: One workspace decision register shows the active and recently closed accepted-risk governance decisions for visible tenants, including owner, due or review date, current decision state, impact, next action, and links into the existing proof or approval surfaces.
- **Smallest enterprise-capable version**: One new workspace-level decision register page under `/admin` that hosts a Filament-native table or list surface, derives rows from current `FindingException`, `FindingExceptionDecision`, and current governance validity truth, defaults to open decisions, exposes a bounded recently-closed view for decisions closed within the last 30 calendar days, and deep-links to the existing `ViewFindingException` detail page for proof and approval actions. No inline approval on the register itself.
- **Explicit non-goals**: No new `GovernanceDecision` table; no generic task engine; no new cross-family queue for alerts, operations, and reviews; no customer-facing decision portal; no inline approve, reject, renew, or revoke actions on the register page; no autonomous escalation; no new review-pack workflow; no new OperationRun start path.
- **Permanent complexity imported**: One new native Filament page, one bounded derived register-builder seam, one local derived register-state filter family, optional launch or return-context handling, and focused `Unit` plus `Feature` coverage.
- **Why now**: `docs/product/spec-candidates.md` and `docs/product/roadmap.md` both identify the decision register as the highest-priority manual-promotion gap after the automatic queue was deliberately exhausted. The repo already has the exception-decision persistence and service logic, so the next product value is productizing that truth, not creating more foundations.
- **Why not local**: Extending only `FindingExceptionsQueue` or only `ViewFindingException` would keep the current multi-surface reconstruction problem intact and would not provide a single truthful answer to `which decision needs follow-through now?`.
- **Approval class**: Workflow Compression
- **Red flags triggered**: One multi-surface follow-through flag and one new workspace register surface flag. Defense: the slice stays on existing decision truth, introduces no new persistence, and refuses a generic workflow engine.
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 1 | Produktnaehe: 2 | Wiederverwendung: 2 | **Gesamt: 11/12**
- **Decision**: approve

## Spec Scope Fields *(mandatory)*

- **Scope**: canonical-view
- **Primary Routes**:
  - new canonical workspace route `/admin/governance/decisions`
  - existing tenant-scoped `FindingExceptionResource` list and view routes as the owning proof and approval surfaces
  - existing `FindingExceptionsQueue` route as contextual queue input only
  - existing `GovernanceInbox` route as contextual launch or return input only when later connected
- **Data Ownership**:
  - tenant-owned `Finding`, `FindingException`, `FindingExceptionDecision`, and `FindingExceptionEvidenceReference` remain the only persisted truth for the decision rows
  - existing `AuditLog` entries remain the only audit truth for decision actions
  - existing `TenantReview`, `ReviewPack`, and `OperationRun` records remain secondary linked proof only when current repo truth already exposes them
  - the decision register introduces no new table, cache, mirror entity, or workflow-state persistence
- **RBAC**:
  - workspace membership remains the first boundary for the register page
  - register visibility reuses existing exception visibility semantics through `Capabilities::FINDING_EXCEPTION_VIEW`
  - approval, rejection, renewal, and revocation remain on the existing exception detail surface and continue to require the current approval capability family such as `Capabilities::FINDING_EXCEPTION_APPROVE`
  - if a row exposes a related review or pack link, that link appears only when the actor already satisfies the existing review visibility checks
  - non-members and explicit out-of-scope tenant targets remain `404` deny-as-not-found boundaries
  - in-scope workspace members with no visible decision rows in the default unfiltered register receive `403`, not a silent empty shell
  - once an entitled actor is on the register, user-applied tenant or register-state filters that narrow visible rows to zero show a truthful filtered empty state instead of escalating to `403`

For canonical-view specs, the spec MUST define:

- **Default filter behavior when tenant-context is active**: when launched from a tenant-scoped exception or review surface, the decision register prefilters to that tenant and keeps `register_state=open` as the default. Clearing the tenant filter returns to the workspace-wide open register rather than freezing the page on one tenant forever.
- **Explicit entitlement checks preventing cross-tenant leakage**: broad register counts and rows omit hidden tenants and hidden proof links before counts are derived. Explicit tenant filters or explicit decision targets outside visible scope resolve as not found and do not reveal whether another tenant has pending or closed decisions.

## Cross-Cutting / Shared Pattern Reuse *(mandatory when the feature touches notifications, status messaging, action links, header actions, dashboard signals/cards, alerts, navigation entry points, evidence/report viewers, or any other existing shared operator interaction family; otherwise write `N/A - no shared interaction family touched`)*

- **Cross-cutting feature?**: yes
- **Interaction class(es)**: navigation entry points, governance queues or registers, action links, status messaging, badge semantics, evidence and proof drill-through, and audit-aware decision history disclosure
- **Systems touched**: `FindingExceptionsQueue`, `FindingExceptionResource`, `ViewFindingException`, `GovernanceInbox`, `CanonicalNavigationContext`, `OperationRunLinks`, `BadgeRenderer`, the current finding-exception detail action surface, and current audit-trail presentation
- **Existing pattern(s) to extend**: existing exception-decision append-only history, current exception-detail approval actions, current queue and detail launch conventions, and current governance navigation continuity
- **Shared contract / presenter / builder / renderer to reuse**: `CanonicalNavigationContext`, `OperationRunLinks`, `BadgeRenderer`, existing `FindingExceptionService` lifecycle semantics, and current action-surface declarations on the exception pages
- **Why the existing shared path is sufficient or insufficient**: the repo already has the underlying decision truth and approval actions, but the current shared surfaces are insufficient as a bounded register because they answer queue work or record proof, not one calm workspace closure view.
- **Allowed deviation and why**: none planned. If implementation needs one local register builder, it must stay page-scoped and derived from current exception truth instead of becoming a reusable workflow engine.
- **Consistency impact**: `Decision register`, `Open decision`, decision-state wording, owner or due-date language, badge meaning, and proof-link labels must stay aligned with the current exception detail and queue surfaces.
- **Review focus**: reviewers must block any implementation that introduces a generic decision framework, a second approval action surface, or a second persisted decision summary.

## OperationRun UX Impact *(mandatory when the feature creates, queues, deduplicates, resumes, blocks, completes, or deep-links to an `OperationRun`; otherwise write `N/A - no OperationRun start or link semantics touched`)*

- **Touches OperationRun start/completion/link UX?**: yes, deep-link only when current proof already has a related run
- **Shared OperationRun UX contract/layer reused**: `OperationRunLinks`
- **Delegated start/completion UX behaviors**: existing `Open operation` link resolution only when a current related run already exists. No queued toast, run-enqueued browser event, dedupe message, or terminal notification behavior is introduced.
- **Local surface-owned behavior that remains**: the register may show whether a related proof link exists, but all decision lifecycle actions remain DB-backed and detail-surface-owned.
- **Queued DB-notification policy**: `N/A`
- **Terminal notification path**: `N/A`
- **Exception required?**: none

## Provider Boundary / Platform Core Check *(mandatory when the feature changes shared provider/platform seams, identity scope, governed-subject taxonomy, compare strategy selection, provider connection descriptors, or operator vocabulary that may leak provider-specific semantics into platform-core truth; otherwise write `N/A - no shared provider/platform boundary touched`)*

N/A - no shared provider or platform-core seam is widened. The slice only productizes existing governance decision truth in the admin plane.

## UI / Surface Guardrail Impact *(mandatory when operator-facing surfaces are changed; otherwise write `N/A`)*

| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note |
|---|---|---|---|---|---|---|
| Governance decision register page | yes | Native Filament page plus shared badges and navigation helpers | workspace decision home, queue-to-detail drill-through, proof-link semantics | page, URL-query | no | One new bounded register over existing exception-decision truth |
| Finding exception detail page | yes | Native Filament resource page | proof surface, current approval actions, launch and return context | page, detail, URL-query | no | Remains the only owning approval surface |

Implementation intent: the new register is a Filament-native table or list surface hosted by a page. If `decision-register.blade.php` is needed, it stays a thin page wrapper around native Filament table primitives instead of bespoke row markup. The later implementation review must explicitly pass `docs/product/standards/list-surface-review-checklist.md`, or record a narrow exception with rationale.

## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*

| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|---|---|---|---|---|---|---|---|
| Governance decision register page | Primary Decision Surface | Operator decides which accepted-risk governance decision needs follow-through now | tenant, decision state, owner, due or review date, impact, and one dominant next action | full exception history, evidence references, audit trail, related review or run links after explicit open | Primary because it becomes the bounded closure surface for existing decision truth rather than another queue or record detail page | Follows `what governance decision needs action now?` before `what does this record contain?` | Replaces queue hopping and record-by-record search |
| Finding exception detail page | Secondary Context | Operator validates proof and performs the existing approval or closure action | current decision summary, current validity, evidence summary, and existing action hierarchy | full append-only decision history, evidence references, audit trail, and related proof links | Secondary because it remains the proof and action owner after the register chooses the record | Keeps action and proof inside the current exception workflow | Prevents the register from becoming a duplicate mutation lane |

## Audience-Aware Disclosure *(mandatory when operator-facing surfaces are changed)*

| Surface | Audience Modes In Scope | Decision-First Default-Visible Content | Operator Diagnostics | Support / Raw Evidence | One Dominant Next Action | Hidden / Gated By Default | Duplicate-Truth Prevention |
|---|---|---|---|---|---|---|---|
| Governance decision register page | operator-MSP | decision status, owner, due or review date, impact, next action, and source tenant | deeper history, review context, and proof remain on the detail surface | raw JSON, copied payloads, and low-level audit metadata stay off the register page | `Open decision` | raw or support detail is not rendered on the register page | the register states the decision truth once and defers proof to the detail page |
| Finding exception detail page | operator-MSP | current decision, why it needs action, evidence summary, and the existing action hierarchy | append-only history, audit trail, and optional related proof links | low-level metadata and raw support context stay secondary and capability-gated | one existing state-appropriate action such as `Approve exception` or `Review renewal` | raw/support sections remain secondary | the detail page deepens the chosen decision and does not restate the workspace-wide register summary |

## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*

| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Governance decision register page | Utility / Workspace Decision | Read-only decision register | Open the correct decision for proof or approval | explicit row action into the existing detail surface | forbidden | filter controls and proof links only | none | `/admin/governance/decisions` | existing tenant-scoped `FindingExceptionResource` view route | active workspace, optional tenant filter, register-state filter | Decision register | which governance decision needs follow-through now | none |
| Finding exception detail page | Detail / Reviewable governance record | Action-owning detail surface | Approve, reject, renew, revoke, or confirm the current decision state | explicit open from register or queue | `N/A` | supporting links and secondary proof actions only | current risky actions remain grouped on the detail page and keep their current confirmation rules | existing tenant-scoped `FindingExceptionResource` list route | existing tenant-scoped `FindingExceptionResource` view route | tenant scope, decision status, current validity | Finding exception | current decision truth and actionability for the opened record | none |

## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*

| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|---|
| Governance decision register page | Workspace operator / MSP operator | Decide which current governance decision needs follow-through | Workspace decision hub | Which accepted-risk or exception decision needs action now, who owns it, and where do I go next? | tenant, owner, due or review date, decision state, impact, next action, and proof availability | append-only history, evidence detail, audit, and optional review or run context | decision state, governance validity, due or review timing, impact | none on the register page itself | Open decision | none |
| Finding exception detail page | Workspace operator / approver | Validate proof and perform the current decision lifecycle action | Detail surface | Why is this decision in its current state, and what action is allowed now? | current decision summary, evidence summary, action-ready state, and current owner or due context | full decision history, deeper evidence, audit trail, and related proof links | decision lifecycle, governance validity, expiry, audit status | existing exception decision lifecycle only | existing detail-owned action such as approve, reject, renew, or revoke | current detail-owned risky actions only |

## Proportionality Review *(mandatory when structural complexity is introduced)*

- **New source of truth?**: no
- **New persisted entity/table/artifact?**: no
- **New abstraction?**: yes - one bounded register builder or assembler may be needed to derive row state, next action, and proof links from current exception decision truth
- **New enum/state/reason family?**: no persisted family; any register-state keys remain local derived filters only
- **New cross-domain UI framework/taxonomy?**: no
- **Current operator problem**: operators cannot answer `which governance decision still needs action now?` from one bounded surface, even though current repo truth already stores append-only decision records and exception lifecycle state.
- **Existing structure is insufficient because**: the current queue and detail pages answer different parts of the workflow, but neither page gives one bounded cross-tenant closure view with owner, due date, and next action.
- **Narrowest correct implementation**: one derived workspace register over current `FindingException` and `FindingExceptionDecision` truth plus current detail-page launch continuity.
- **Ownership cost**: one new page, one derived row contract, filter state, and focused tests.
- **Alternative intentionally rejected**: a new `GovernanceDecision` entity or generic approval engine was rejected because the repo already has the exception-decision history and action seams needed for v1.
- **Release truth**: current-release workflow compression over existing decision truth, not future-release workflow-platform preparation.

### Compatibility posture

This feature assumes a pre-production environment.

Backward compatibility, migration shims, legacy aliases, and a second decision-store fallback are out of scope unless explicitly required by this spec.

Canonical reuse of current exception-decision truth is preferred over a parallel decision domain.

## Testing / Lane / Runtime Impact *(mandatory for runtime behavior changes)*

- **Test purpose / classification**: Unit, Feature
- **Validation lane(s)**: fast-feedback, confidence
- **Why this classification and these lanes are sufficient**: unit coverage can prove row-state derivation, omission rules, and next-action mapping cheaply. Focused feature coverage can prove workspace visibility, `404` vs `403`, tenant and state filter behavior, and register-to-detail launch continuity on native Filament surfaces. A new browser family is unnecessary for v1; one narrow manual smoke remains sufficient for the later implementation loop.
- **New or expanded test families**: one focused `Unit/Support/GovernanceDecisions` family and focused `Feature/Governance` plus `Feature/Findings` coverage
- **Fixture / helper cost impact**: moderate. Tests need visible and hidden tenants, exception decisions in pending, approved, renewal-requested, revoked, and expired states, plus current owner and evidence references, but they should reuse existing factories and avoid queue or browser-heavy defaults.
- **Heavy-family visibility / justification**: none
- **Special surface test profile**: global-context-shell
- **Standard-native relief or required special coverage**: required state-contract coverage for tenant-filter continuity, the 30-calendar-day recently-closed window, one dominant next action, diagnostics-secondary treatment, no duplicate visible decision summary, and register-to-detail launch continuity
- **Reviewer handoff**: reviewers must confirm that the register stays read-only, hidden tenants do not leak through counts or empty states, and existing detail actions remain the only approval surface.
- **Budget / baseline / trend impact**: low feature-local increase only
- **Escalation needed**: none
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage
- **Planned validation commands**:
  - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/GovernanceDecisions/GovernanceDecisionRegisterBuilderTest.php`
  - `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Governance/DecisionRegisterPageTest.php tests/Feature/Governance/DecisionRegisterAuthorizationTest.php tests/Feature/Findings/FindingExceptionDecisionRegisterNavigationTest.php tests/Feature/Findings/FindingExceptionDetailDecisionSummaryTest.php tests/Feature/Findings/FindingExceptionDecisionRegisterBoundariesTest.php`

## Scope Boundaries

### In Scope

- one workspace-level governance decision register in the existing admin plane
- default open-decision visibility plus one bounded recently-closed register-state view derived from current exception decision history
- row-level owner, due or review date, decision state, impact, next action, and proof-availability cues derived from current exception truth
- existing detail-surface launch continuity and truthful return context
- existing evidence, audit, and optional related proof links only when current repo truth already exposes them

### Non-Goals

- a new persisted decision table, cache, or projection store
- inline decision lifecycle mutations on the register page
- a generic workflow engine or cross-family register for alerts, operations, or reviews
- customer-facing decision pages or customer-side approval actions
- new review-pack generation, new queue family, or new OperationRun start semantics
- a governance inbox rewrite; any later inbox launch affordance is a follow-up, not a prerequisite for this slice

## Assumptions

- current `FindingException` and `FindingExceptionDecision` fields are sufficient to derive owner, due context, closure reason, and next action for the bounded register
- the current exception detail surface remains the correct owner for approval, rejection, renewal, and revocation actions
- existing audit and evidence references are sufficient for v1 proof links without a second summary store
- if a related review or run link is unavailable for a row, truthful omission is acceptable in v1

## Risks

- the slice could drift into a generic decision engine if implementation tries to absorb alerts, operations, and reviews as equal peers instead of staying on existing exception-decision truth
- if register rows try to solve missing proof by creating new persistence or mirrored summaries, the feature would violate proportionality and source-of-truth rules
- the detail page could become duplicative if it starts repeating the workspace-level register summary instead of deepening the chosen decision

## Candidate Selection Rationale

- **Selected candidate**: Decision Register & Approval Workflow v1
- **Source locations**:
  - `docs/product/spec-candidates.md`
  - `docs/product/roadmap.md`
  - `docs/product/implementation-ledger.md`
- **Why selected**: the active auto-prep queue is intentionally empty, and this is the highest-priority manual-promotion backlog item. The repo already contains the key enabling truth: append-only `FindingExceptionDecision` history, existing exception approval actions, and decision-first governance surfaces.
- **Why this is the smallest viable implementation slice**: v1 stays on current accepted-risk and exception decision truth only, adds one bounded register, and reuses the existing detail-page approval workflow instead of inventing a broader multi-family closure engine.
- **Intentional narrowing from source candidate**: the roadmap candidate names owner, due date, status, reason, impact, next action, linked evidence, linked `OperationRun`, accepted-risk path, closure reason, escalation hook, and optional approval or closure semantics. This v1 narrows that list to the repo-real exception and accepted-risk decision family only, keeps related proof links optional and derived, and defers broader cross-family escalation or approval packages.
- **Why close alternatives were deferred**:
  - `Governance Artifact Lifecycle & Retention v1` remains broader and more cross-domain than the current repo-ready decision seam.
  - `Billing & Subscription Truth Layer v1` and `Customer-Facing Localization Adoption v1` remain valid manual promotions, but neither is as directly enabled by current persisted decision truth.
  - `Enterprise Access Boundary & Support Access Governance v1` remains product-sensitive and less repo-ready than this bounded exception-decision slice.

## Follow-up Candidates

- governance inbox launch or summary integration once the bounded register is proven
- broader multi-family decision register work for alerts, operations, and review follow-up only after the exception-decision slice remains calm and bounded
- customer-safe awareness or delivery-pack follow-through for accepted-risk decisions only after the operator register proves the closure semantics

## User Scenarios & Testing *(mandatory)*

### User Story 1 - See open governance decisions in one register (Priority: P1)

As a workspace operator, I want one register that shows the accepted-risk and exception decisions that still need approval, renewal, or review so I can decide where to work next without scanning several pages first.

**Why this priority**: This is the core product gap. Without one bounded register, the product still forces decision reconstruction across queue and detail pages.

**Independent Test**: Seed visible and hidden tenants with pending, expiring, lapsed, and recently closed exception decisions, open the register, and verify that the page shows only visible-tenant rows with owner, due context, decision state, and one dominant next action.

**Acceptance Scenarios**:

1. **Given** the actor has visible pending and expiring exception decisions across two visible tenants, **When** they open the decision register, **Then** the page shows separate rows with owner, due or review date, impact, and `Open decision` as the only dominant row action.
2. **Given** the actor has hidden-tenant decisions they are not entitled to see, **When** they open the decision register, **Then** those decisions do not affect visible counts, labels, or empty-state hints.
3. **Given** the actor applies a tenant filter that hides all current open rows, **When** they view the page, **Then** the page shows a truthful filtered empty state instead of implying the whole workspace is calm.

---

### User Story 2 - Open the existing approval surface with context (Priority: P1)

As a workspace operator, I want the register to open the current exception detail and approval surface with preserved context so the register stays a decision hub instead of becoming a second mutation lane.

**Why this priority**: The register only helps if the next click lands on the existing proof and action surface without losing context.

**Independent Test**: Open a decision row from the register, land on the existing exception detail page, verify the current approval or closure actions remain there, and return to the same register scope.

**Acceptance Scenarios**:

1. **Given** a pending exception decision is visible in the register, **When** the actor opens it, **Then** the destination is the existing exception detail page with the current approve or reject actions, not a new register-owned detail shell.
2. **Given** an expiring or lapsed governance decision is visible, **When** the actor opens it from the register, **Then** the detail page preserves tenant and return context and makes the current renewal or revocation path explicit through the existing action surface.
3. **Given** a row has no related review or run proof link, **When** the actor opens the decision, **Then** the detail page still loads truthfully and does not imply missing proof exists elsewhere.

---

### User Story 3 - Keep decision truth audit-safe and bounded (Priority: P2)

As a reviewer or operator, I want the register to remain derived from the existing exception-decision history, audit trail, and evidence references so the feature does not create a second workflow state or a hidden approval engine.

**Why this priority**: This protects the architecture and keeps the manual-promotion slice narrow enough to implement safely.

**Independent Test**: Inspect the register and detail behavior after implementation and verify that register rows derive from current exception-decision history, recently closed rows are limited to terminal decisions from the last 30 calendar days, and no new persisted decision summary exists.

**Acceptance Scenarios**:

1. **Given** an exception has more than one append-only decision row, **When** it appears in the register, **Then** the register derives its current row state from the current decision and current validity without collapsing or mutating history.
2. **Given** a rejected, revoked, or superseded decision has a current terminal decision timestamp inside the last 30 calendar days, **When** the actor switches the register to recently closed, **Then** the row shows closure reason from the current decision history without reopening a new workflow state.
3. **Given** a decision is approved but no longer has valid supporting governance, **When** it appears in the open register, **Then** the row is presented as follow-up-needed rather than calm or closed.

### Edge Cases

- What happens when the same finding has current decision history plus older request, approval, and revocation rows? The register must surface only the current derived row while the detail page preserves full append-only history.
- What happens at the recently-closed boundary? A row is eligible only when its current terminal decision timestamp is within the last 30 calendar days; rows older than that stay out of the register.
- What happens when an active decision has no owner assigned? The register should show the missing owner truthfully and treat it as follow-up-needed instead of hiding the row.
- What happens when a row has no related review or `OperationRun` link? The register omits the proof link and does not start or generate anything.
- What happens when the actor has access to only one tenant from a multi-tenant workspace? The register must stay honest and derive counts only from that visible tenant.

## Requirements *(mandatory)*

**Constitution alignment (required):** This feature introduces no new Graph calls and no new remote or queued work. It reuses the existing DB-backed accepted-risk decision workflow, current audit trail, current capability checks, and current tenant-safe proof links.

**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** The feature must not add a new persisted decision entity, decision summary cache, or generic workflow layer. Any new builder or helper must stay bounded to the register page and current exception decision truth.

**Constitution alignment (XCUT-001):** The feature must extend the current navigation, badge, proof-link, and exception-detail interaction families instead of inventing parallel local patterns.

- **FR-001**: The system MUST provide one workspace-level `Decision register` page in the existing admin plane that lists the current accepted-risk and exception decisions visible to the actor.
- **FR-002**: Each register row MUST derive from existing `FindingException`, `FindingExceptionDecision`, and current governance validity truth and MUST NOT create a second persisted decision summary.
- **FR-003**: The register MUST provide a default open-decision view and a bounded recently-closed view. The recently-closed view MUST show only rows whose current exception state is terminal (`rejected`, `revoked`, or `superseded`) and whose current terminal decision timestamp falls within the last 30 calendar days; anything older stays out of the register.
- **FR-004**: Each visible row MUST show tenant, current decision state, owner, due or review date when present, impact cue, next action cue, and the dominant `Open decision` action. Rows in the recently-closed view MUST also show closure reason derived from the current terminal decision.
- **FR-005**: The register page MUST stay read-only. Approval, rejection, renewal, revocation, or any other mutation MUST remain on the existing exception detail surface.
- **FR-006**: Opening a row from the register MUST land on the existing exception detail page with truthful tenant and return context preserved.
- **FR-007**: Non-members and out-of-scope tenant targets MUST resolve as `404`; in-scope members with no visible decision rows in the default unfiltered register MUST receive `403`; user-applied tenant or register-state filters that narrow an already-authorized register view to zero rows MUST show a truthful filtered empty state.
- **FR-008**: Hidden tenants, hidden decision rows, and hidden proof links MUST be omitted before counts, labels, and empty states are derived.
- **FR-009**: If current repo truth already exposes evidence references, related reviews, or related runs for a decision, the register or detail surface MAY link to them through existing helpers. Missing proof MUST remain truthful and MUST NOT trigger generation or a new `OperationRun`.
- **FR-010**: The feature MUST keep current append-only decision history, existing audit log behavior, and current detail action confirmations authoritative. It MUST NOT introduce a second approval engine, a second audit family, or a local register mutation lane.
- **FR-011**: The register MUST be implemented as a Filament-native table or list surface and later reviewed against `docs/product/standards/list-surface-review-checklist.md`. Any deviation from that checklist MUST be explicit and justified.

## Acceptance Criteria

- The selected candidate is narrowed to current exception and accepted-risk decision truth only.
- The prep package names real repo surfaces and keeps implementation bounded to existing models, services, detail pages, and shared helpers.
- No new persisted decision entity or generic workflow framework is required by the prepared spec.
- The implementation plan and task list include explicit RBAC, test, and smoke-validation coverage for the register and detail-launch flow.

## Success Criteria

- A later implementation can deliver the first decision-follow-through slice without inventing new persistence or reopening current exception lifecycle truth.
- Reviewers can point to one primary operator question for the new page and one existing detail surface that owns mutations.
- The package is explicit enough that a later implementation loop can validate it with bounded `Unit` plus `Feature` coverage and one narrow browser or manual smoke path.

## Open Questions

None blocking safe implementation. V1 deliberately chooses a standalone governance navigation entry and bounded detail launch continuity; broader governance-inbox integration remains a follow-up candidate.