27 KiB
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
WorkspaceOverviewBuilderas the single orchestration point instead of creating a new workspace posture service. - Reuse
TenantGovernanceAggregateResolverandBaselineCompareStatsper 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
WorkspaceRecentOperationsas 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 slicecontracts/workspace-governance-attention.openapi.yaml: internal surface contract for workspace governance-aware overview semantics and drill-through continuityquickstart.md: focused implementation and verification workflow
Design highlights:
WorkspaceOverviewBuilderremains the builder boundary and becomes responsible for deriving governance-aware summary metrics, attention candidates, and calmness claims from visible tenants only.TenantGovernanceAggregateResolveris 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.
WorkspaceNeedsAttentionremains 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_STALEdirectly and only treatsSTATE_ACTION_REQUIREDas materially degraded compare posture when the aggregate's next action remains compare-specific rather than findings-driven;STATE_CAUTIONremains 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. WorkspaceRecentOperationsremains 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)
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)
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 agentbefore 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.phpsetup. - 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.