# Quickstart: Central Tenant Operability Policy ## Goal Validate that one central operability authority now drives selector membership, remembered-context validity, tenant-bound page legitimacy, canonical viewer behavior, and lifecycle-safe action availability. ## Prerequisites 1. Start Sail. 2. Ensure a test workspace exists with tenants covering `draft`, `onboarding`, `active`, and `archived` lifecycle states. 3. Ensure at least one onboarding session is linked to a `draft` or `onboarding` tenant. 4. Ensure at least one `OperationRun` references a tenant that is not standard-selector eligible. ## Implementation Validation Order ### 1. Run focused unit coverage for the policy core ```bash vendor/bin/sail artisan test --compact tests/Unit/Tenants ``` Expected outcome: - Operability outcomes are stable across all lifecycle and lane combinations. - Reason codes distinguish lifecycle denial, lane denial, and capability denial. ### 2. Run focused selector and remembered-context tests ```bash vendor/bin/sail artisan test --compact --filter=ChooseTenant vendor/bin/sail artisan test --compact --filter=SelectTenant vendor/bin/sail artisan test --compact --filter=remembered ``` Expected outcome: - Only `active` tenants are selectable in the standard selector. - Stale remembered context is cleared when the tenant becomes missing, out of workspace, or selector-ineligible. ### 3. Run focused tenant-bound and canonical-view tests ```bash vendor/bin/sail artisan test --compact tests/Feature/Operations vendor/bin/sail artisan test --compact --filter=TenantlessOperationRunViewer vendor/bin/sail artisan test --compact --filter=OperateHubShell vendor/bin/sail artisan test --compact --filter=ViewTenant ``` Expected outcome: - `/admin/operations/{run}` remains valid under mismatched or empty selected tenant context. - `/admin/tenants/{tenant}` remains valid for authorized onboarding or archived tenants even when they are not selector-eligible. - Shell-level context resolution keeps canonical and tenant-bound routes valid without falling back to selector-lane assumptions. ### 4. Run focused lifecycle-action tests ```bash vendor/bin/sail artisan test --compact --filter=archive vendor/bin/sail artisan test --compact --filter=restore vendor/bin/sail artisan test --compact --filter="resume onboarding" vendor/bin/sail artisan test --compact tests/Feature/Onboarding/OnboardingDraftAuthorizationTest.php vendor/bin/sail artisan test --compact --filter="onboarding completion" vendor/bin/sail artisan test --compact --filter=readiness ``` Expected outcome: - `Archive`, `Restore`, and `Resume onboarding` resolve from the central operability layer. - Onboarding-completion plus readiness or verification affordances resolve from the same policy boundary with lifecycle-aware and capability-aware reasons. - Non-members remain 404. - In-scope users without capability remain 403. ### 5. Run focused discoverability and global-search tests ```bash vendor/bin/sail artisan test --compact --filter=TenantResourceGlobalSearch vendor/bin/sail artisan test --compact --filter=discoverability ``` Expected outcome: - Administrative discoverability and tenant global search do not collapse back to standard selector eligibility. - Non-active tenants can remain administratively discoverable when policy allows, even though they are not selectable in the active-lane chooser. ### 6. Manual smoke-check in the browser 1. Open `/admin/choose-tenant` and confirm only active tenants are selectable. 2. Open `/admin/tenants` with no selected tenant and confirm the list remains usable. 3. Open `/admin/onboarding` and `/admin/onboarding/{onboardingDraft}` and confirm onboarding-lane actions remain available only when operability allows them. 4. Open an archived tenant detail route directly and confirm the page renders when authorized. 5. Open `/admin/operations/{run}` for a run linked to an onboarding or archived tenant while a different tenant is selected and confirm the mismatch is informational only. 6. Verify lifecycle action buttons plus onboarding-completion and readiness or verification affordances remain honest and confirmation-backed where applicable. ## Non-Goals For This Slice - No schema migration. - No new Graph calls. - No new assets or Filament panel registration changes. - No new `OperationRun` type.