## Summary - productize the governance inbox decision-first workbench surface and related section-building logic - update the panel theme asset and governance inbox Blade view for the new page treatment - add Governance Inbox feature coverage and a Spec 327 browser smoke test - add Spec 327 planning artifacts under `specs/327-governance-inbox-decision-first-workbench-productization` ## Testing - not run as part of this handoff Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #388
15 KiB
15 KiB
Spec 327 Repo Truth Map
Status: implemented Created: 2026-05-18 Purpose: classify each Governance Inbox decision-first workbench element before runtime implementation. This map is based on repository inspection only; implementation must update it before runtime changes if new source gaps appear.
Classification Legend
repo-verified: exact runtime source exists and was inspected.foundation-real: backend model/service/policy exists, but exact page binding still needs implementation verification.derived from existing model: display value can be derived from existing persisted/domain truth.empty state / unavailable: no safe source/action exists for v1; show explicit unavailable state or omit.deferred future capability: outside Spec 327 and must not be shown as live runtime truth.
Required Data Areas
| Data area | Repo source | Preparation finding |
|---|---|---|
| Findings | Finding, FindingResource, GovernanceInboxSectionBuilder::assignedFindingsSection() and intakeFindingsSection() |
repo-real for subject/title, status, owner/assignee, due, environment, source links, severity/family fields |
| Finding Exceptions / Accepted Risks | FindingException, FindingExceptionDecision, FindingExceptionEvidenceReference, FindingExceptionsQueue, FindingExceptionResource |
repo-real for status, validity, owner, request reason, due/expiry, current decision, evidence refs |
| Governance Inbox current state | GovernanceInbox, governance-inbox.blade.php, GovernanceInboxSectionBuilder |
route/page/view/builder exist; current layout is section/queue-first |
| Decision Register / decisions | DecisionRegister, FindingExceptionDecision, Specs 265/306/307/308 |
foundation-real for decision-related links/states; only show if existing source route/action is repo-real and authorized |
| Evidence links | EvidenceSnapshot, EvidenceSnapshotItem, FindingExceptionEvidenceReference, EvidenceSnapshotPolicy, Capabilities::EVIDENCE_VIEW |
foundation-real; exact inbox binding must be verified during implementation |
| OperationRun links | OperationRun, OperationRunLinks, RelatedNavigationResolver |
repo-real for stale/terminal follow-up and proof deep links |
| Workspace / Environment filter state | WorkspaceContext, WorkspaceHubEnvironmentFilter, WorkspaceHubFilterStateResetter, WorkspaceHubRegistry, filter chip partial |
repo-real canonical environment_id, clear filter, alias rejection, cross-workspace guard |
| Owners / assignments | Finding.owner_user_id, Finding.assignee_user_id, FindingException.owner_user_id, resource display helpers |
repo-real where fields are present; unavailable otherwise |
| Due dates | Finding.due_at, FindingException.review_due_at, FindingException.expires_at |
repo-real where fields are present; unavailable otherwise |
| Statuses / priorities / severities | source model status/severity fields and builder ordering | derived; no new persisted status family |
| Alerts | AlertDelivery, AlertDeliveryResource, Capabilities::ALERTS_VIEW |
repo-real for failed delivery attention family |
| Reviews / review follow-up | ManagedEnvironmentTriageReview, EnvironmentReview, EnvironmentReviewRegisterService, CustomerReviewWorkspace |
repo-real for follow-up and review workspace handoff |
UI Element Map
| UI element | Source model/service/page | Status source | Authorization/capability | Workspace/Environment scope | Evidence/OperationRun/Audit link | Fallback/empty state | Classification |
|---|---|---|---|---|---|---|---|
| Governance Inbox route | GovernanceInbox page, slug governance/inbox |
Filament page registration | workspace membership via WorkspaceCapabilityResolver::isMember() |
WorkspaceContext session; optional environment_id |
no direct audit found during prep | redirect workspace chooser, 404, or 403 per existing behavior | repo-verified |
| Header title | governance-inbox.blade.php, page title |
static page copy | page access | workspace-wide or filtered | none | static title | repo-verified |
| Workspace chip | appliedScope()['workspace_label'] |
current Workspace name |
page access | workspace session | none | omit if unavailable | repo-verified |
| Environment filter chip | workspace-hub-environment-filter-chip partial |
WorkspaceHubEnvironmentFilter::fromRequest() |
actor must access environment | ?environment_id={id} only |
none | no chip on clean URL | repo-verified |
| Clear filter action | pageUrl(['environment_id' => null]), shared chip |
clean URL generated by page/helper | page access | removes canonical filter | none | omit when unfiltered | repo-verified |
| Legacy alias rejection | WorkspaceHubRegistry, WorkspaceHubFilterStateResetter, navigation tests |
forbidden query keys | page/source access | aliases do not set filter | none | workspace-wide view or safe 404 | repo-verified |
| Cross-workspace environment guard | WorkspaceHubEnvironmentFilter::fromRequest() |
environment scoped by workspace and canAccessTenant() |
workspace and environment entitlement | current workspace only | none | NotFoundHttpException |
repo-verified |
| Main decision question | new page/view copy | static stable copy | page access | current scope | none | visible even empty with honest state | empty state / unavailable until implemented |
| Highest-priority/selected item | existing section entries plus builder ordering | entry urgency_rank, source model status/due |
source-family capabilities | current workspace/filter | source links | no selected item / no visible decisions | derived from existing model |
| Decision title | Finding subject, FindingException finding label, OperationRun problem class, alert title, review family label |
existing entry headline |
source-family capability | current workspace/filter | source route | fallback source identifier | repo-verified |
| Reason | FindingException.request_reason, operation problem class, alert error/event, review row state, finding status/reopened/due |
source fields and builder summaries | source-family capability | current workspace/filter | source route/proof links | Reason unavailable if absent |
derived from existing model |
| Impact | source severity/status/validity/problem class/review follow-up | Finding.severity, FindingException.current_validity_state, OperationRun::problemClass(), review state |
source-family capability | current workspace/filter | source route/proof links | Impact unavailable if no safe mapping |
derived from existing model |
| Owner | Finding.ownerUser, Finding.assigneeUser, FindingException.owner |
owner/assignee user relationships | source-family capability | environment/workspace scoped | source route | Owner missing or Owner unavailable |
repo-verified |
| Due date | Finding.due_at, FindingException.review_due_at, FindingException.expires_at |
model casts and resource relative-time helpers | source-family capability | environment/workspace scoped | source route | Due date unavailable |
repo-verified |
| Evidence state | Finding.evidence_jsonb, FindingException.evidence_summary, FindingExceptionEvidenceReference, EvidenceSnapshot |
existing JSON/relations where linked | Capabilities::EVIDENCE_VIEW for evidence links |
environment/workspace scoped | evidence snapshot/reference links if authorized | Evidence missing, Unavailable, or omit |
foundation-real |
| Evidence path | evidence refs, snapshots, review context, source routes | relation presence and policy checks | EVIDENCE_VIEW plus source policies |
current workspace/filter | evidence/operation/review links only | unavailable rows | foundation-real |
| Operation proof | OperationRun, OperationRunLinks |
run relation or operation attention entry | existing operation entitlement checks | workspace and environment entitlement | canonical operation links | Operation proof unavailable |
repo-verified |
| Accepted-risk / exception state | FindingException.status, current_validity_state, Finding.status = risk_accepted |
existing constants and validity fields | FINDING_EXCEPTION_VIEW/MANAGE/APPROVE, findings view |
environment/workspace scoped | current decision/evidence references if authorized | No exception or unavailable |
repo-verified |
| Decision Register link/action | DecisionRegister, FindingExceptionDecision, existing decision routes/tests |
current decision/link presence | existing decision/finding exception capabilities | workspace hub with optional filter | decision proof/run links where existing | omit / No active decision record |
foundation-real |
| Primary next action | existing source routes/actions from builder entries | destination URL/action label per family | source route/action authorization | current workspace/filter | source route/proof links | Next action unavailable |
repo-verified for open-source links; derived for selected action label |
| Assign owner action | FindingPolicy::assign, Capabilities::TENANT_FINDINGS_ASSIGN |
existing capability/policy | tenant/environment capability | source environment | audit on source action if existing | hide/unavailable unless source action exists | foundation-real |
| Create/update exception action | FindingExceptionPolicy, Capabilities::FINDING_EXCEPTION_MANAGE/APPROVE, existing source surfaces |
existing policy and source action | workspace/environment capability | source environment | source audit if action exists | hide/unavailable unless source action exists | foundation-real |
| Open evidence action | EvidenceSnapshotResource, EvidenceSnapshotPolicy |
linked evidence and capability | EVIDENCE_VIEW |
source environment/workspace | evidence detail route | hide/unavailable | foundation-real |
| Open diagnostics action | Capabilities::SUPPORT_DIAGNOSTICS_VIEW if exposed |
no current default inbox raw diagnostics | support diagnostics capability | current scope | source diagnostics only if repo-real | collapsed/hidden | empty state / unavailable |
| Summary card: open decisions | current selected/available entries count | builder total_count or filtered item count |
source-family capabilities | current scope | source links | 0 visible decisions |
repo-verified as visible attention count; label must avoid unsupported claim |
| Summary card: critical/high priority | Finding.severity, exception validity/status, operation problem class |
model fields | source-family capabilities | current scope | source links | unavailable if no safe cross-family mapping | derived from existing model |
| Summary card: overdue | Finding.due_at, FindingException.review_due_at/expires_at |
datetime fields | source-family capabilities | current scope | source links | No due dates available |
derived from existing model |
| Summary card: owner missing | finding/exception owner fields | nullable owner/assignee IDs | source-family capabilities | current scope | source links | unavailable for families without owner source | derived from existing model |
| Summary card: evidence missing | evidence refs/summary/snapshot presence | evidence fields/relations | source-family and evidence capabilities | current scope | evidence links | unavailable where not supported | foundation-real |
| Queue/table context | existing sections/entries rendered in Blade | builder sections and entries | source-family capabilities | current scope and family filter | source routes | existing calm empty states | repo-verified |
| Right decision/detail panel | new layout over selected/highest entry | selected entry and source-specific derived fields | source-family capabilities | current scope | source/evidence/operation links | panel shows unavailable states | empty state / unavailable until implemented |
| Diagnostics disclosure | new collapsed section if needed | safe copy only unless authorized diagnostics source exists | SUPPORT_DIAGNOSTICS_VIEW if raw detail exists |
current scope | source routes only | collapsed/hidden | empty state / unavailable |
| Raw provider payloads | raw Graph/provider payloads | not safe default | support-only future | N/A | N/A | never default-visible | deferred future capability |
| Platform-context tenant copy guard | runtime copy/tests | string assertions | N/A | page copy | N/A | use Workspace/Environment | repo-verified need; implementation test required |
Required Runtime Element Decisions
| Element | v1 decision |
|---|---|
| New persisted inbox item | deferred future capability; do not build |
| New Decision Register workflow | deferred future capability; do not rebuild |
| AI prioritization | deferred future capability; do not show |
| Owner/due/evidence where absent | explicit unavailable/missing state; do not invent |
| Green success state | allowed only for exact repo-backed proof; otherwise avoid |
| Diagnostics | collapsed/hidden by default and capability-aware if exposed |
| Dangerous/mutating actions | do not add unless spec/plan updated first |
| Legacy query aliases | rejected/neutralized; do not support |
Implementation Update Rule
If implementation discovers that a planned UI element has no safe source, no authorization path, or would require new persisted truth, the element must become empty state / unavailable or deferred future capability. Do not create backend foundation inside Spec 327 without updating spec.md, plan.md, and this map first.
Implementation Close-Out
Implemented on 2026-05-18 against the existing /admin/governance/inbox Filament page.
- The workbench now derives selected/highest-priority state from existing
GovernanceInboxSectionBuilderentries; no new persisted inbox item, status family, queue, migration, or backend source of truth was added. - Findings and finding exceptions now expose repo-backed decision labels, reasons, impact, owner/due, evidence, accepted-risk/exception, and primary source-action labels. Unsupported fields render explicit missing or unavailable states.
- Alert delivery failure copy no longer exposes raw provider/error diagnostics in the default inbox entry. Diagnostics remain collapsed and point operators back to authorized source surfaces.
- The page remains workspace-owned with optional canonical
environment_idfiltering. Legacy tenant/environment aliases were not added or supported. - Primary actions are read-first source navigation links. No destructive, provider-changing, approve/reject, restore, delete, or remediation action was added.
- Browser proof and screenshots live under
specs/327-governance-inbox-decision-first-workbench-productization/artifacts/screenshots/. The route inventory/design coverage registry were not changed because the route and UI-028 strategic-surface classification are unchanged. - Follow-up refinement removed the duplicate in-view page heading and moved the first dominant experience to the decision/evidence workbench. Empty workbench state now renders one compact
No governance decisions need attentiondecision state instead of primary zero-metric cards. - Final browser proof keeps the empty state separate and adds a non-empty repo-backed finding fixture that visibly renders the decision title, reason, impact, missing owner, due date, missing evidence, accepted-risk state, and primary next action in the decision workbench plus right-side evidence panel. The required screenshot artifact is
artifacts/screenshots/governance-inbox-decision-workbench.png.