# Quickstart: Tenant Governance Aggregate Contract ## Goal Validate that one derived tenant-governance aggregate now drives the shared summary posture across the tenant dashboard, the tenant governance banner, and the Baseline Compare landing without adding persistence or reintroducing local findings-count ownership. ## Prerequisites 1. Start Sail. 2. Ensure a tenant exists with an assigned baseline profile and a consumable snapshot. 3. Seed compare-run scenarios for: no result yet, compare in progress, compare failed, trustworthy no-drift, stale no-drift, overdue findings without new drift, and lapsed governance without new drift. 4. Ensure the current user is a tenant member with access to the tenant dashboard and Baseline Compare landing. ## Implementation Validation Order ### 1. Run low-level compare and aggregate coverage ```bash vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineCompareStatsTest.php vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineCompareSummaryAssessmentTest.php vendor/bin/sail artisan test --compact --filter=TenantGovernanceAggregate ``` Expected outcome: - Existing compare truth still resolves the same availability and posture states. - The new aggregate contract maps those states into one stable summary object without introducing a second query-backed truth path. ### 2. Run focused cross-surface parity coverage ```bash vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareSummaryConsistencyTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/NeedsAttentionWidgetTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareNowWidgetTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareCoverageBannerTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareLandingAdminTenantParityTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareLandingDuplicateNamesBannerTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareLandingRbacLabelsTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareLandingStartSurfaceTest.php vendor/bin/sail artisan test --compact tests/Feature/Filament/BaselineCompareLandingWhyNoFindingsTest.php ``` Expected outcome: - `NeedsAttention`, `BaselineCompareNow`, `BaselineCompareCoverageBanner`, and the landing summary agree on posture family, headline, and next-action intent for the same tenant state. - A tenant with zero visible drift but overdue or unhealthy governance still renders as action-needed on every covered surface. - The landing keeps `Compare now` confirmation and capability gating unchanged, and diagnostics remain clearly secondary to the shared summary posture. ### 3. Run request-local reuse and guard coverage ```bash vendor/bin/sail artisan test --compact --filter=TenantGovernanceAggregateMemoization vendor/bin/sail artisan test --compact tests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.php ``` Expected outcome: - One request stores one governance aggregate per tenant scope. - Covered surfaces do not fall back to widget-local ad hoc caches or repeated local findings queries. ### 4. Format touched implementation files ```bash vendor/bin/sail bin pint --dirty --format agent ``` Expected outcome: - All touched implementation files conform to the repo’s Pint rules. ## Manual Smoke Check 1. Open `/admin/t/{tenant}` for a tenant with lapsed governance and no new drift findings. 2. Confirm the dashboard `Needs Attention` widget and `Baseline Governance` card both show action-needed posture. 3. Open `/admin/t/{tenant}/baseline-compare-landing` and confirm the landing summary agrees with the dashboard posture while still showing deeper diagnostics below. 4. Use a tenant with a trustworthy no-drift result and confirm the banner hides, the dashboard falls back to healthy checks, and the landing summary presents the same all-clear posture. 5. Use a tenant with a queued or running compare and confirm dashboard, banner, and landing all present progress-aware follow-up instead of stale “all clear” messaging. 6. Switch from one tenant to another and confirm the second tenant does not reuse the first tenant’s summary posture. ## Non-Goals For This Slice - No database migration. - No new Graph call or provider-contract work. - No new assets or Filament panel registration change. - No new mutation surface beyond the existing `Compare now` action, which remains unchanged.