## Summary - implement Spec 143 tenant lifecycle, operability, and tenant-context semantics across chooser, tenant management, onboarding, and canonical operation viewers - add centralized tenant lifecycle and operability support types, audit action coverage, and lifecycle-aware badge and action handling - add feature and unit coverage for tenant chooser eligibility, global search scoping, canonical operation access, onboarding authorization, and lifecycle presentation ## Testing - vendor/bin/sail artisan test --compact - vendor/bin/sail bin pint --dirty --format agent Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #172
14 KiB
Implementation Plan: Tenant Lifecycle, Operability, and Context Semantics Foundation
Branch: 143-tenant-lifecycle-operability-context-semantics | Date: 2026-03-14 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/spec.md
Input: Feature specification from /specs/143-tenant-lifecycle-operability-context-semantics/spec.md
Note: This template is filled in by the /speckit.plan command. See .specify/scripts/ for helper scripts.
Summary
Define a single foundation for tenant lifecycle, tenant operability, and tenant context semantics across workspace-scoped admin surfaces, tenant-bound pages, onboarding flows, and canonical workspace record viewers. The implementation approach is to formalize lifecycle and operability decisions behind central domain services and presentation mappings, then apply those decisions in the first rollout slice to selector eligibility, tenant management actions, onboarding visibility, tenant-safe global search, lifecycle audit coverage, and canonical operation-run viewing without letting remembered tenant context determine route legitimacy.
Technical Context
Language/Version: PHP 8.4.15
Primary Dependencies: Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4
Storage: PostgreSQL via Laravel Eloquent models and workspace/tenant scoped tables
Testing: Pest feature, unit, and browser tests run through Laravel Sail
Target Platform: Laravel web application served through Filament admin panels
Project Type: Web application with server-rendered Filament and Livewire surfaces
Performance Goals: Preserve DB-only rendering for Monitoring and canonical run viewers, eliminate false 404 outcomes caused by remembered tenant mismatch, and keep selector/context transitions request-bounded without external calls during page render
Constraints: Workspace isolation and tenant isolation are non-negotiable; admin-plane canonical viewers must preserve 404 vs 403 semantics; no new Microsoft Graph calls are introduced by this foundation; badge semantics must remain centralized; destructive actions continue to require explicit confirmation
Scale/Scope: Cross-cutting foundation across 8 primary admin routes, 5 core domain entities, multiple Filament pages/resources, and existing authorization, badge, and workspace-context helpers
Additional implementation facts:
- Livewire v4.0+ compliance is already required and preserved because this repo runs Filament v5 on Livewire v4.
- Filament panel providers are registered in
/Users/ahmeddarrazi/Documents/projects/TenantAtlas/bootstrap/providers.php. - Relevant global-search posture in current scope:
TenantResourceis globally searchable only if kept through its existing resource view/edit surface; any follow-up global-search changes must preserve a View/Edit page.OperationRunResourcehas global search disabled already.- The onboarding and workspace landing surfaces are pages, not searchable resources.
- This implementation must add explicit regression coverage to ensure lifecycle and operability rules do not leak ineligible tenants into global search results.
- Lifecycle mutations introduced or clarified by this feature must emit explicit workspace audit entries through the existing audit layer.
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
- Inventory-first: clarify what is “last observed” vs snapshots/backups
- Read/write separation: any writes require preview + confirmation + audit + tests
- Graph contract path: Graph calls only via
GraphClientInterface+config/graph_contracts.php - Deterministic capabilities: capability derivation is testable (snapshot/golden tests)
- RBAC-UX: two planes (/admin vs /system) remain separated; cross-plane is 404; tenant-context routes (/admin/t/{tenant}/...) are tenant-scoped; canonical workspace-context routes under /admin remain tenant-safe; non-member tenant/workspace access is 404; member-but-missing-capability is 403; authorization checks use Gates/Policies + capability registries (no raw strings, no role-string checks)
- Workspace isolation: non-member workspace access is 404; tenant-plane routes require an established workspace context; workspace context switching is separate from Filament Tenancy
- RBAC-UX: destructive-like actions require
->requiresConfirmation()and clear warning text - RBAC-UX: global search is tenant-scoped; non-members get no hints; inaccessible results are treated as not found (404 semantics)
- Tenant isolation: all reads/writes tenant-scoped; cross-tenant views are explicit and access-checked
- Run observability: long-running/remote/queued work creates/reuses
OperationRun; start surfaces enqueue-only; Monitoring is DB-only; DB-only <2s actions may skip runs but security-relevant ones still audit-log; auth handshake exception OPS-EX-AUTH-001 allows synchronous outbound HTTP on/auth/*withoutOperationRun - Ops-UX 3-surface feedback: if
OperationRunis used, feedback is exactly toast intent-only + progress surfaces + exactly-once terminalOperationRunCompleted(initiator-only); no queued/running DB notifications - Ops-UX lifecycle:
OperationRun.status/OperationRun.outcometransitions are service-owned (only viaOperationRunService); context-only updates allowed outside - Ops-UX summary counts:
summary_countskeys come fromOperationSummaryKeys::all()and values are flat numeric-only - Ops-UX guards: CI has regression guards that fail with actionable output (file + snippet) when these patterns regress
- Ops-UX system runs: initiator-null runs emit no terminal DB notification; audit remains via Monitoring; tenant-wide alerting goes through Alerts (not OperationRun notifications)
- Automation: queued/scheduled ops use locks + idempotency; handle 429/503 with backoff+jitter
- Data minimization: Inventory stores metadata + whitelisted meta; logs contain no secrets/tokens
- Badge semantics (BADGE-001): status-like badges use
BadgeCatalog/BadgeRenderer; no ad-hoc mappings; new values include tests - UI naming (UI-NAMING-001): operator-facing labels use
Verb + Object; scope (Workspace,Tenant) is never the primary action label; source/domain is secondary unless disambiguation is required; runs/toasts/audit prose use the same domain vocabulary; implementation-first terms do not appear in primary operator UI - Filament UI Action Surface Contract: for any new/modified Filament Resource/RelationManager/Page, define Header/Row/Bulk/Empty-State actions, ensure every List/Table has a record inspection affordance (prefer
recordUrl()clickable rows; do not render a lone View row action), keep max 2 visible row actions with the rest in “More”, group bulk actions, require confirmations for destructive actions (typed confirmation for large/bulk where applicable), write audit logs for mutations, enforce RBAC via central helpers (non-member 404, member missing capability 403), and ensure CI blocks merges if the contract is violated or not explicitly exempted - Filament UI UX-001 (Layout & IA): Create/Edit uses Main/Aside (3-col grid, Main=columnSpan(2), Aside=columnSpan(1)); all fields inside Sections/Cards (no naked inputs); View uses Infolists (not disabled edit forms); status badges use BADGE-001; empty states have specific title + explanation + 1 CTA; max 1 primary + 1 secondary header action; tables provide search/sort/filters for core dimensions; shared layout builders preferred for consistency
Gate status before Phase 0 research: PASS
- No new Graph contract work is required for this foundation because it does not add outbound Graph calls.
- The feature affects admin-plane authorization semantics and therefore must preserve canonical capability registry usage, deny-as-not-found boundaries, and central policy enforcement.
- The feature affects Filament tenant and operations surfaces, so this implementation slice must satisfy the Action Surface Contract and UX-001 for every modified surface; later follow-up specs may extend the same rules to additional screens.
- The feature affects canonical operation viewers but does not change
OperationRunlifecycle ownership; any follow-up changes must continue usingOperationRunServicefor status and outcome transitions. - Badge centralization is already available through
BadgeCatalogand must be extended rather than bypassed for tenant lifecycle semantics.
Project Structure
Documentation (this feature)
specs/143-tenant-lifecycle-operability-context-semantics/
├── plan.md # This file (/speckit.plan command output)
├── checklists/
│ └── requirements.md # Spec quality checklist
├── research.md # Phase 0 output (/speckit.plan command)
├── data-model.md # Phase 1 output (/speckit.plan command)
├── quickstart.md # Phase 1 output (/speckit.plan command)
├── contracts/ # Phase 1 output (/speckit.plan command)
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
Source Code (repository root)
app/
├── Filament/
│ ├── Pages/
│ │ ├── ChooseTenant.php
│ │ ├── Operations/TenantlessOperationRunViewer.php
│ │ └── Workspaces/
│ │ ├── ManagedTenantOnboardingWizard.php
│ │ └── ManagedTenantsLanding.php
│ ├── Resources/
│ │ ├── OperationRunResource.php
│ │ └── TenantResource.php
│ └── Concerns/
├── Http/
│ ├── Controllers/
│ │ ├── SelectTenantController.php
│ │ ├── ClearTenantContextController.php
│ │ └── SwitchWorkspaceController.php
│ └── Middleware/
├── Models/
│ ├── Tenant.php
│ ├── TenantOnboardingSession.php
│ └── OperationRun.php
├── Policies/
│ ├── OperationRunPolicy.php
│ └── TenantOnboardingSessionPolicy.php
├── Services/
│ ├── Audit/
│ ├── OperationRunService.php
│ ├── Tenants/
│ └── Onboarding/
└── Support/
├── Audit/
├── Auth/
├── Badges/
├── OperateHub/
├── Tenants/
└── Workspaces/
resources/views/
routes/web.php
bootstrap/providers.php
tests/
├── Browser/
├── Feature/
│ ├── Audit/
│ ├── Auth/
│ ├── Filament/
│ ├── Monitoring/
│ ├── Onboarding/
│ ├── Operations/
│ ├── OpsUx/
│ ├── Rbac/
│ ├── Spec085/
│ └── TenantRBAC/
└── Unit/
├── Tenants/
└── Onboarding/
Additional targeted tests may also live in existing focused suites such as tests/Feature/Guards/ when the regression is cross-cutting rather than surface-specific.
Structure Decision: Use the existing Laravel single-project structure. The implementation is cross-cutting but remains inside current app/, routes/, resources/views/, and tests/ directories. No new top-level source folders are needed, but this feature may introduce focused Tenants support/service namespaces and matching tests/Unit/Tenants coverage within the existing tree.
Complexity Tracking
Fill ONLY if Constitution Check has violations that must be justified
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| None | N/A | N/A |
Phase 0 Research
- Consolidate lifecycle semantics around the existing
Tenantstatus values instead of inventing a parallel state source. - Formalize selector eligibility and remembered-context behavior around workspace context plus operability rules.
- Decouple canonical operation-run viewer validity from active tenant mismatch while preserving existing
OperationRunPolicytenant-entitlement checks. - Extend centralized badge semantics for tenant lifecycle presentation rather than adding ad hoc UI mappings.
- Preserve separation between tenant lifecycle and onboarding draft lifecycle by layering rules across
TenantandTenantOnboardingSessioninstead of merging the models.
Research output: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/research.md
Phase 1 Design & Contracts
- Define the domain model and derived concepts for lifecycle, operability, context eligibility, canonical viewers, and remembered tenant preference.
- Record the affected route contracts for selector, tenant-bound, onboarding, and canonical record viewer semantics.
- Provide a quickstart validation flow that follow-up implementation specs can use for acceptance testing and regression targeting.
- Update agent context after design artifacts are generated.
Design outputs:
/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/data-model.md/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/contracts/admin-tenant-context-foundation.openapi.yaml/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/143-tenant-lifecycle-operability-context-semantics/quickstart.md
Post-Design Constitution Check
Gate status after Phase 1 design: PASS
- Livewire v4.0+ compliance remains explicit and unchanged.
- Filament provider registration remains correctly anchored in
bootstrap/providers.php. - No affected design artifact introduces direct Graph calls, new raw capability strings, or non-central badge mappings.
- Canonical record viewer design preserves workspace membership + tenant entitlement checks and removes remembered-tenant mismatch as a source of false 404.
- Destructive lifecycle actions remain explicitly confirmation-gated in follow-up implementation work.
Implementation Sequencing
- Introduce central lifecycle and operability abstractions around
Tenantstatus and page categories. - Refactor selector and remembered-context resolution to consume operability decisions instead of raw
status = activechecks scattered across pages and controllers. - Refactor canonical workspace record viewers, especially
TenantlessOperationRunViewer, to authorize by record and entitlement rather than active tenant equality. - Centralize lifecycle presentation and action-label semantics on tenant management surfaces.
- Add or update Pest feature, unit, and browser tests for canonical viewer access, selector eligibility, badge coverage, tenant-safe global search, lifecycle audit logging, and authorization semantics.