# Implementation Plan: Workspace Governance Attention Foundation **Branch**: `175-workspace-governance-attention` | **Date**: 2026-04-04 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/175-workspace-governance-attention/spec.md` **Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/175-workspace-governance-attention/spec.md` **Note**: This plan follows the existing TenantPilot workspace and tenant-truth architecture. It hardens the current workspace overview instead of introducing a new workspace posture subsystem. ## Summary Promote existing tenant governance truth into the existing workspace overview so `/admin` becomes a trustworthy multi-tenant governance attention surface instead of an operations-first calm surface. The implementation will keep `WorkspaceOverviewBuilder` as the orchestration point, reuse `TenantGovernanceAggregateResolver`, `BaselineCompareStats`, existing findings and compare destinations, and optionally already-available evidence or review surfaces where they provide a more precise next jump. The first slice will harden summary metrics, attention ranking, tenant identification, compare breadth across stale, failed, and degraded states, and calmness semantics; the second slice will preserve activity versus governance separation and protect the new contract with focused workspace overview regression tests. ## Technical Context **Language/Version**: PHP 8.4.15 **Primary Dependencies**: Laravel 12, Filament v5, Livewire v4, Pest v4, existing `WorkspaceOverviewBuilder`, `TenantGovernanceAggregateResolver`, `BaselineCompareStats`, `BaselineCompareSummaryAssessor`, `WorkspaceSummaryStats`, `WorkspaceNeedsAttention`, `WorkspaceRecentOperations`, `WorkspaceCapabilityResolver`, `CapabilityResolver`, `FindingResource`, `BaselineCompareLanding`, `EvidenceSnapshotResource`, `TenantReviewResource`, and canonical admin Operations routes **Storage**: PostgreSQL unchanged; no new persistence, cache table, or materialized aggregate is introduced **Testing**: Pest 4 feature and Livewire-style widget tests through Laravel Sail using existing workspace overview tests plus new governance attention and drill-through coverage **Target Platform**: Laravel monolith web application in Sail locally and containerized Linux deployment in staging and production **Project Type**: web application **Performance Goals**: Keep `/admin` DB-only at render time, keep workspace attention bounded, reuse request-scoped derived-state caching for tenant governance aggregates, and avoid uncontrolled polling or unbounded cross-tenant queries **Constraints**: No new table, no new workspace posture score, no full portfolio matrix, no new panel/provider, no cross-tenant leakage, no dead-end drill-throughs for visible states, no ad-hoc status taxonomy, and no broad workspace IA redesign **Scale/Scope**: One workspace landing page, three existing workspace widgets, one builder, one accessible-tenant slice per workspace, six central governance signal families, and focused regression coverage for workspace calmness, ranking, drill-through continuity, and RBAC-safe omission or fallback behavior ## Constitution Check *GATE: Passed before Phase 0 research. Re-check after Phase 1 design.* | Principle | Pre-Research | Post-Design | Notes | |-----------|--------------|-------------|-------| | Inventory-first / snapshots-second | PASS | PASS | The feature adds no new inventory or snapshot truth. It only changes read-time workspace aggregation over existing records. | | Read/write separation | PASS | PASS | The slice is read-only workspace overview hardening. No new write path, preview flow, or destructive action is introduced. | | Graph contract path | N/A | N/A | No Graph call or `config/graph_contracts.php` change is required. | | Deterministic capabilities | PASS | PASS | Existing workspace membership and tenant capability checks remain authoritative for aggregation and drill-through behavior. | | RBAC-UX authorization semantics | PASS | PASS | `/admin` remains workspace-scoped, tenant destinations remain tenant-scoped, non-members stay `404`, and members missing downstream capability must not receive dead-end links. | | Workspace and tenant isolation | PASS | PASS | Aggregation stays limited to visible tenants in the active workspace and uses existing `scopeToAuthorizedTenants()` style filtering. | | Run observability / Ops-UX | PASS | PASS | No new `OperationRun` type, feedback surface, or lifecycle change is added. Existing operations destinations remain canonical. | | Data minimization | PASS | PASS | The plan adds no new persistence and no broader route exposure. Only already-visible tenant truth is promoted into the workspace home. | | Proportionality / no premature abstraction | PASS | PASS | The plan reuses `WorkspaceOverviewBuilder` and `TenantGovernanceAggregateResolver` instead of adding a new workspace posture framework or aggregate layer. | | Persisted truth / behavioral state | PASS | PASS | No new table, enum, status family, or persisted summary artifact is planned. | | UI semantics / few layers | PASS | PASS | The feature aligns existing widget semantics rather than introducing a new presenter or badge taxonomy. | | Badge semantics (BADGE-001) | PASS | PASS | Existing badge and tone domains remain the source for operations and compare posture meaning. New workspace items reuse those semantics rather than inventing new colors or labels. | | Filament-native UI / Action Surface Contract | PASS | PASS | `WorkspaceOverview` and its widgets remain navigation and inspection surfaces only. No destructive or redundant action model is added. | | Filament UX-001 | PASS | PASS | No create or edit page is touched. The design keeps governance attention above recent operations and uses bounded empty-state wording. | | Filament v5 / Livewire v4 compliance | PASS | PASS | The design stays within the current Filament v5 + Livewire v4 stack. | | Provider registration location | PASS | PASS | No panel/provider registration change is required. Laravel 11+ provider registration remains in `bootstrap/providers.php`. | | Global search hard rule | PASS | PASS | No global-searchable resource behavior is changed in this slice. | | Destructive action safety | PASS | PASS | The feature introduces no destructive action. | | Asset strategy | PASS | PASS | No new assets or `filament:assets` deployment change is required. | | Testing truth (TEST-TRUTH-001) | PASS | PASS | The plan adds tests around business consequences: false calmness, tenant identification, ordering, continuity, and RBAC-safe navigation behavior. | ## Phase 0 Research Research outcomes are captured in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/175-workspace-governance-attention/research.md`. Key decisions: - Reuse `WorkspaceOverviewBuilder` as the single orchestration point instead of creating a new workspace posture service. - Reuse `TenantGovernanceAggregateResolver` and `BaselineCompareStats` per visible tenant as the primary source for lapsed governance, overdue findings, expiring governance, high-severity active findings, and stale, failed, or materially degraded compare posture. - Count governance risk at the tenant level for workspace summary metrics so the workspace answer is “how many tenants need attention,” not “how many raw issues exist.” - Rank governance-critical tenant states above activity-only or alert-delivery-only items, while keeping operations and alerts available as lower-priority supporting attention. - Make every workspace attention item tenant-identifiable and map it to exactly one matching destination, with an RBAC-safe fallback or disabled/non-clickable explanatory state when the exact destination is not allowed. - Default zero-tenant recovery to the existing choose-workspace route and keep alert-only follow-up on the existing alerts overview route. - Keep `WorkspaceRecentOperations` as a diagnostic activity surface, not a governance surface. - Promote evidence or review truth only when an existing tenant-level evidence or review surface already carries a clearer next jump than the tenant dashboard fallback. - Lean on request-scoped derived-state caching to keep per-tenant aggregate resolution viable for normal workspace sizes without new persistence. ## Phase 1 Design Design artifacts are created under `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/175-workspace-governance-attention/`: - `data-model.md`: persistent source truths and derived workspace attention contracts for this slice - `contracts/workspace-governance-attention.openapi.yaml`: internal surface contract for workspace governance-aware overview semantics and drill-through continuity - `quickstart.md`: focused implementation and verification workflow Design highlights: - `WorkspaceOverviewBuilder` remains the builder boundary and becomes responsible for deriving governance-aware summary metrics, attention candidates, and calmness claims from visible tenants only. - `TenantGovernanceAggregateResolver` is the primary source for governance-related tenant promotion, mirroring the mature tenant dashboard semantics rather than reinterpreting the same truth a second time. - Workspace summary metrics are split into scope, governance-risk, and activity categories so the stat strip can no longer blur portfolio activity with portfolio risk. - Workspace attention items become structured tenant-bound records carrying tenant label, problem family, urgency, and one primary drill-through target. - `WorkspaceNeedsAttention` remains bounded and prioritized, favoring the highest-value tenant signal per item instead of dumping every raw issue into the workspace surface. - Compare-driven workspace attention must preserve stale, failed, and materially degraded posture families rather than collapsing them into a single degraded-only bucket. - Compare attention promotes `STATE_STALE` directly and only treats `STATE_ACTION_REQUIRED` as materially degraded compare posture when the aggregate's next action remains compare-specific rather than findings-driven; `STATE_CAUTION` remains below the workspace-attention threshold unless another governance signal independently warrants promotion. - Existing evidence and review surfaces stay optional targets in this slice: they are only used when already-available truth makes them the most precise next jump. - Zero-tenant recovery defaults to `ChooseWorkspace`, and alert-only follow-up reuses the existing alerts overview at `/admin/alerts`. - `WorkspaceRecentOperations` remains a recency surface and is intentionally prevented from defining calmness on its own. ## Phase 1 — Agent Context Update Run after artifact generation: - `.specify/scripts/bash/update-agent-context.sh copilot` ## Project Structure ### Documentation (this feature) ```text specs/175-workspace-governance-attention/ ├── spec.md ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ └── workspace-governance-attention.openapi.yaml ├── checklists/ │ └── requirements.md └── tasks.md ``` ### Source Code (repository root) ```text app/ ├── Filament/ │ ├── Pages/ │ │ ├── WorkspaceOverview.php │ │ ├── ChooseTenant.php │ │ ├── TenantDashboard.php │ │ └── BaselineCompareLanding.php │ ├── Resources/ │ │ ├── FindingResource.php │ │ ├── EvidenceSnapshotResource.php │ │ └── TenantReviewResource.php │ └── Widgets/ │ ├── Dashboard/ │ │ └── NeedsAttention.php │ └── Workspace/ │ ├── WorkspaceSummaryStats.php │ ├── WorkspaceNeedsAttention.php │ └── WorkspaceRecentOperations.php ├── Models/ │ ├── Finding.php │ ├── AlertDelivery.php │ ├── OperationRun.php │ ├── EvidenceSnapshot.php │ └── TenantReview.php ├── Services/ │ └── Auth/ │ ├── WorkspaceCapabilityResolver.php │ └── CapabilityResolver.php └── Support/ ├── Auth/ │ └── Capabilities.php ├── Baselines/ │ ├── BaselineCompareStats.php │ ├── BaselineCompareSummaryAssessment.php │ ├── BaselineCompareSummaryAssessor.php │ ├── TenantGovernanceAggregate.php │ └── TenantGovernanceAggregateResolver.php ├── OperationRunLinks.php └── Workspaces/ └── WorkspaceOverviewBuilder.php resources/ └── views/ └── filament/ ├── pages/ │ └── workspace-overview.blade.php └── widgets/ └── workspace/ ├── workspace-needs-attention.blade.php └── workspace-recent-operations.blade.php tests/ └── Feature/ └── Filament/ ├── WorkspaceOverviewAccessTest.php ├── WorkspaceOverviewAuthorizationTest.php ├── WorkspaceOverviewContentTest.php ├── WorkspaceOverviewEmptyStatesTest.php ├── WorkspaceOverviewLandingTest.php ├── WorkspaceOverviewNavigationTest.php ├── WorkspaceOverviewOperationsTest.php ├── WorkspaceOverviewPermissionVisibilityTest.php ├── WorkspaceOverviewGovernanceAttentionTest.php ├── WorkspaceOverviewDbOnlyTest.php ├── WorkspaceOverviewDrilldownContinuityTest.php └── WorkspaceOverviewSummaryMetricsTest.php ``` **Structure Decision**: Keep the feature entirely inside the existing Laravel/Filament monolith. Extend the current workspace overview builder, workspace widgets, tenant truth helpers, and existing destination resources or pages instead of creating a new workspace domain layer. ## Complexity Tracking > No Constitution Check violations are planned. No exceptions are currently justified. | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | — | — | — | ## Proportionality Review > No new enum/status family, persisted entity, abstraction layer, taxonomy, or cross-domain UI framework is planned in this slice. - **Current operator problem**: The workspace home can look calm even when visible tenants already carry governance-critical problems. - **Existing structure is insufficient because**: Workspace aggregation currently stops at operations and alerts and fails to propagate already-mature tenant governance truth. - **Narrowest correct implementation**: Extend the existing workspace overview builder and widgets to consume existing tenant aggregates and destination contracts. - **Ownership cost created**: Modest additional workspace-level aggregation logic and focused regression coverage. - **Alternative intentionally rejected**: A new workspace posture subsystem, new persistence, or a matrix-style redesign. - **Release truth**: Current-release truth. ## Implementation Strategy ### Phase A — Reuse Existing Tenant Truth In The Workspace Builder **Goal**: Make `WorkspaceOverviewBuilder` governance-aware without creating a parallel truth layer. | Step | File | Change | |------|------|--------| | A.1 | `app/Support/Workspaces/WorkspaceOverviewBuilder.php` | Add a visible-tenant governance promotion pass that resolves `TenantGovernanceAggregate` for accessible tenants and builds a bounded set of governance candidates from overdue findings, lapsed governance, expiring governance, high-severity active findings, stale, failed, or materially degraded compare posture, and optionally already-available evidence or review attention. | | A.2 | `app/Support/Baselines/TenantGovernanceAggregateResolver.php` and existing tenant truth classes | Reuse existing aggregate outputs as-is; only add plan-level consumption, not a second interpretation layer. | | A.3 | `tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php` plus existing overview tests | Prove that visible governance-critical tenants now surface on the workspace home even when operations are quiet. | ### Phase B — Separate Governance Metrics From Activity Metrics **Goal**: Make the stat strip clearly answer risk versus activity instead of flattening them into one line of numbers. | Step | File | Change | |------|------|--------| | B.1 | `app/Support/Workspaces/WorkspaceOverviewBuilder.php` | Replace or augment the current `needs_attention` stat with one or more tenant-level governance-risk metrics such as tenants needing governance attention, tenants with overdue findings, tenants with lapsed governance, or tenants with stale, failed, or materially degraded compare posture. | | B.2 | `app/Filament/Widgets/Workspace/WorkspaceSummaryStats.php` and `resources/views/filament/pages/workspace-overview.blade.php` | Preserve the existing stat strip but ensure risk metrics and activity metrics are semantically and visually distinguishable through grouping, wording, and destination meaning. | | B.3 | `tests/Feature/Filament/WorkspaceOverviewSummaryMetricsTest.php` and existing content tests | Prove that governance metrics count affected visible tenants, activity metrics remain activity-only, and the two meanings are not mixed. | ### Phase C — Make Workspace Attention Tenant-Addressable And Actionable **Goal**: Turn workspace attention into a real start surface with tenant identity, reason, priority, and next jump. | Step | File | Change | |------|------|--------| | C.1 | `app/Support/Workspaces/WorkspaceOverviewBuilder.php` | Expand the attention item payload to include tenant label, tenant route key or id, problem family, urgency, and one primary target kind. Keep every attention item tenant-bound, leave workspace-wide operations or alert totals in metrics or recency surfaces, and rank governance issues above activity-only items while keeping the list bounded. | | C.2 | `resources/views/filament/widgets/workspace/workspace-needs-attention.blade.php` | Render tenant identity, family, urgency, and one explicit primary action or a disabled explanatory state when the exact destination is not allowed. | | C.3 | `tests/Feature/Filament/WorkspaceOverviewDrilldownContinuityTest.php` and `tests/Feature/Filament/WorkspaceOverviewGovernanceAttentionTest.php` | Prove that each central attention family leads to the correct tenant dashboard, findings, compare, evidence, review, or operation destination and that dead-end links are not exposed. | ### Phase D — Fix Workspace Calmness And Empty-State Semantics **Goal**: Stop the workspace home from claiming calmness when only operations are quiet. | Step | File | Change | |------|------|--------| | D.1 | `app/Support/Workspaces/WorkspaceOverviewBuilder.php` | Change empty-state and calmness logic so calm claims are suppressed whenever visible tenant governance or compare issues exist, even if operations and alerts are healthy. Keep zero-tenant states distinct from healthy states and default their recovery action to the existing choose-workspace route. | | D.2 | `app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php`, `resources/views/filament/pages/workspace-overview.blade.php`, and `resources/views/filament/widgets/workspace/workspace-needs-attention.blade.php` | Tighten copy so the workspace can say “nothing urgent” only for the domains actually checked and only when no visible governance-critical tenant state exists. | | D.3 | `tests/Feature/Filament/WorkspaceOverviewEmptyStatesTest.php` and new governance attention coverage | Prove false calmness is suppressed and low-permission or zero-tenant scenarios remain clearly distinct from healthy calm. | ### Phase E — Preserve Operations As Diagnostic Recency, Not Portfolio Posture **Goal**: Keep `WorkspaceRecentOperations` useful without letting it dominate workspace risk semantics. | Step | File | Change | |------|------|--------| | E.1 | `app/Filament/Widgets/Workspace/WorkspaceRecentOperations.php` and `resources/views/filament/widgets/workspace/workspace-recent-operations.blade.php` | Preserve existing recency behavior and row-open model, but ensure surrounding copy and page hierarchy keep it clearly subordinate to governance attention and summary metrics. | | E.2 | `tests/Feature/Filament/WorkspaceOverviewOperationsTest.php` and content tests | Prove operations remain filtered to the visible tenant slice, remain non-polling by default, and no longer define calmness on their own. | ### Phase F — Tighten RBAC-Safe Destination Selection **Goal**: Ensure visible truth never creates a broken or misleading navigation path. | Step | File | Change | |------|------|--------| | F.1 | `app/Support/Workspaces/WorkspaceOverviewBuilder.php`, `app/Services/Auth/WorkspaceCapabilityResolver.php`, `app/Services/Auth/CapabilityResolver.php`, and tenant resource URL helpers | For each attention family, choose the most precise destination the current in-scope user may actually open; otherwise fall back to an allowed tenant dashboard or disabled explanatory state. Aggregate lapsed-governance attention stays tenant-bound but falls back to the tenant dashboard when the current findings filters would narrow the invalid-governance family. Alert-only follow-up reuses `/admin/alerts`, and zero-tenant recovery reuses `/admin/choose-workspace`. | | F.2 | `tests/Feature/Filament/WorkspaceOverviewPermissionVisibilityTest.php`, `WorkspaceOverviewAuthorizationTest.php`, and new drilldown tests | Prove non-members still receive `404`, hidden tenants do not affect visible output, and members missing downstream capability do not receive clickable dead-end links. | ### Phase G — Verification And Formatting **Goal**: Lock the new workspace truth and performance contract in place. | Step | File | Change | |------|------|--------| | G.1 | Workspace overview focused test pack | Add or extend tests for governance promotion, stale, failed, and materially degraded compare breadth, ordering, tenant identity, summary metric separation, calmness suppression, zero-tenant next-step recovery, low-permission operations fallback, drill-through continuity, DB-only query-bounded rendering, and permission-safe fallbacks. | | G.2 | `vendor/bin/sail bin pint --dirty --format agent` and focused Pest runs | Apply formatting and run the smallest verification pack that covers the builder, workspace view rendering, and navigation behavior. | ## Key Design Decisions ### D-001 — Keep `WorkspaceOverviewBuilder` as the single orchestration boundary The repo already has one place that constructs the workspace overview payload. Extending that builder is narrower than inventing a separate workspace governance service or presenter layer. ### D-002 — Promote tenant truth by tenant, not by raw issue count The workspace operator needs to know which tenants need attention first. A tenant-level risk count is a better workspace answer than raw issue totals because it preserves the MSP triage shape and avoids making one noisy tenant dominate the stat strip. ### D-003 — Reuse `TenantGovernanceAggregate` before touching lower-level logic The tenant dashboard already uses a mature governance aggregate. Workspace attention should consume that same truth path rather than rebuilding overdue, lapsed, or compare logic with new ad-hoc queries. ### D-004 — Keep workspace attention bounded and prioritized The spec hardens the workspace entry point, not a portfolio matrix. The workspace home should surface the top visible reasons to act, not every raw tenant issue. One high-value item per visible problem family is preferable to a noisy stream. ### D-005 — Treat evidence and review as opportunistic precision targets Evidence and reviews are in scope only when they already represent the best existing tenant-level next jump. They are not a reason to create a new workspace evidence or review aggregate in this slice. ### D-006 — Calmness is a checked-domain claim, not a decorative empty state The workspace may only look calm when both governance and activity signals in visible scope are calm. Operations-only quietness is never enough. ### D-007 — Disabled or fallback navigation is preferable to dead-end clicks If the current in-scope user can see that a tenant has a problem but cannot open the most precise destination, the UI must not offer a clickable link that fails later. The surface must either choose an allowed fallback or render a disabled explanatory state. ## Risk Assessment | Risk | Impact | Likelihood | Mitigation | |------|--------|------------|------------| | Workspace attention becomes noisy by promoting too many tenant signals | High | Medium | Bound the list, rank governance-critical families first, and cap per-page attention items. | | Per-tenant aggregate resolution introduces avoidable N+1 behavior | High | Medium | Reuse `TenantGovernanceAggregateResolver` request-scoped caching and keep the visible tenant slice bounded. | | Workspace and tenant truth diverge because workspace logic starts reinterpreting the same facts | High | Medium | Consume `TenantGovernanceAggregate` and existing destinations instead of rebuilding semantics with ad-hoc query logic. | | Capability gaps create misleading or broken drill-throughs | High | Medium | Implement explicit destination selection with fallback or disabled states and cover it with focused tests. | | Calmness copy still overstates health after the change | Medium | Medium | Add explicit calmness-suppression tests covering quiet-ops but risky-governance scenarios. | ## Test Strategy - Extend existing workspace overview tests to preserve landing, navigation, authorization, permission visibility, and operations-slice behavior. - Add focused governance attention coverage for overdue findings, lapsed governance, expiring governance, high-severity active findings, stale, failed, or materially degraded compare posture, and quiet-ops-but-risky-governance scenarios. - Add summary-metric tests proving governance-risk metrics count affected visible tenants rather than raw issue counts and remain distinct from activity metrics. - Add drill-through continuity tests covering tenant dashboard fallback, findings filters, baseline compare landing, evidence or review targets where applicable, and canonical operation detail or index routes. - Add permission-sensitive tests ensuring non-members remain `404`, invisible tenants do not affect visible output, members missing a downstream capability get a safe fallback or disabled state rather than a clickable dead end, and zero-tenant members receive the choose-workspace recovery action instead of healthy calm messaging. - Add DB-only and query-bounding verification so render-time aggregation stays inside the plan's performance constraints and benefits from existing request-scoped caching. - Keep the verification pack Sail-first and run `vendor/bin/sail bin pint --dirty --format agent` before closing implementation. ## Constitution Check (Post-Design) Re-check result: PASS. - Livewire v4.0+ compliance: preserved because the design stays inside existing Filament v5 widgets and pages. - Provider registration location: unchanged; no panel/provider registration work is needed beyond the existing `bootstrap/providers.php` setup. - Global-searchable resources: unchanged; no resource search behavior is altered. - Destructive actions: unchanged; the feature adds no destructive action and therefore no new confirmation flow. - Asset strategy: unchanged; no new asset bundle or deploy-time asset step is introduced. - Testing plan: focused Pest coverage will be added or extended for workspace overview rendering, governance promotion, calmness suppression, summary metric separation, drill-through continuity, and RBAC-safe behavior.