TenantAtlas/specs/175-workspace-governance-attention/plan.md

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 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)

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 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.