TenantAtlas/specs/234-dead-transitional-residue/plan.md
ahmido 603d509b8f
Some checks failed
Main Confidence / confidence (push) Failing after 58s
cleanup: retire dead transitional residue (#270)
## Summary
- remove deprecated baseline profile status alias constants and keep baseline lifecycle semantics on the canonical enum path
- retire the dead tenant app-status badge/default-fixture residue from the active runtime support path
- add the `234-dead-transitional-residue` spec, plan, research, data-model, quickstart, checklist, and task artifacts plus focused regression assertions

## Validation
- not rerun during this PR creation step

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #270
2026-04-23 16:54:48 +00:00

20 KiB

Implementation Plan: Dead Transitional Residue Cleanup

Branch: 234-dead-transitional-residue | Date: 2026-04-23 | Spec: spec.md Input: Feature specification from /specs/234-dead-transitional-residue/spec.md

Note: This plan keeps historical tenant app_status storage and historical migrations intact. It removes only dead runtime alias/support paths and tightens fixtures/tests so legacy values become explicit opt-in setup rather than ambient repo truth.

Summary

Remove the dead BaselineProfile::STATUS_* alias layer and retire tenant app-status residue from the centralized badge catalog, default test fixtures, browser smoke seed data, and legacy-facing tests. The implementation stays intentionally small: no schema change, no new status family, no operator-surface redesign, and no compatibility shim. The proof burden is that current tenant truth and baseline profile behavior remain unchanged while the dead semantics disappear from active runtime language.

Technical Context

Language/Version: PHP 8.4.15, Laravel 12, Filament v5, Livewire v4
Primary Dependencies: App\Models\BaselineProfile, App\Support\Baselines\BaselineProfileStatus, App\Support\Badges\BadgeCatalog, App\Support\Badges\BadgeDomain, Database\Factories\TenantFactory, App\Console\Commands\SeedBackupHealthBrowserFixture, existing tenant-truth and baseline-profile Pest tests
Storage: Existing PostgreSQL baseline_profiles and tenants tables; no new persistence and no schema migration in this slice
Testing: Pest v4 feature and unit tests through Laravel Sail
Validation Lanes: fast-feedback, confidence
Target Platform: Laravel admin web application in Sail containers with admin routes under /admin
Project Type: Monorepo with one Laravel runtime in apps/platform and spec artifacts at repository root
Performance Goals: Preserve current request/query behavior; cleanup must not add runtime branching, new queries, or new UI layers
Constraints: No schema change, no compatibility aliases, no new badge/readiness domain, no authorization changes, no global-search broadening, and no new operator-facing surface
Scale/Scope: One Eloquent model, one central badge registry path, one legacy badge mapper, one tenant factory, one browser fixture command, and focused tenant/baseline regression families

Filament v5 Implementation Contract

  • Livewire v4.0+ compliance: Preserved. The cleanup does not introduce any legacy Livewire patterns and does not add new Filament component types.
  • Provider registration location: Unchanged. Panel providers remain registered in bootstrap/providers.php.
  • Global search coverage: TenantResource remains globally searchable and already has View/Edit pages. BaselineProfileResource keeps global search disabled via $isGloballySearchable = false and already has View/Edit pages. This cleanup adds no new global-search exposure.
  • Destructive actions: No destructive action is introduced or changed. Existing tenant and baseline profile destructive flows remain on their current confirmation and authorization paths.
  • Asset strategy: No new assets are planned. Deployment expectations remain unchanged, including cd apps/platform && php artisan filament:assets only when future work adds registered assets.
  • Testing plan: Prove the cleanup with focused feature tests for tenant-truth continuity and baseline-profile list/view/edit/archive continuity, plus unit coverage for central badge-catalog cleanup.

UI / Surface Guardrail Plan

  • Guardrail scope: no operator-facing surface change
  • Native vs custom classification summary: N/A
  • Shared-family relevance: none
  • State layers in scope: none
  • Handling modes by drift class or surface: report-only
  • Repository-signal treatment: review-mandatory because this is a repo-hygiene cleanup that removes active residue rather than hiding it
  • Special surface test profiles: N/A
  • Required tests or manual smoke: functional-core
  • Exception path and spread control: none
  • Active feature PR close-out entry: Guardrail

Shared Pattern & System Fit

  • Cross-cutting feature marker: no
  • Systems touched: centralized badge registry, baseline profile status model language, tenant default fixtures, browser smoke fixture command, and focused tenant/baseline regression files
  • Shared abstractions reused: BaselineProfileStatus, BadgeCatalog, BadgeDomain, and the existing tenant/baseline regression families
  • New abstraction introduced? why?: none
  • Why the existing abstraction was sufficient or insufficient: Existing abstractions are sufficient because this work removes dead support paths instead of creating a new semantic or presentation layer.
  • Bounded deviation / spread control: none

Constitution Check

GATE: Passed before Phase 0 research. Re-check after Phase 1 design: still passed with no new persistence, no new semantic family, and no operator-surface expansion.

Gate Status Plan Notes
Inventory-first / read-write separation PASS No Graph path, no new mutation flow, and no snapshot or restore behavior change.
RBAC, workspace isolation, tenant isolation PASS No route, policy, capability, or resource visibility behavior changes are planned.
Run observability / Ops-UX lifecycle PASS No OperationRun is created or modified; this cleanup is outside queued or remote execution semantics.
Shared pattern first PASS The plan simplifies the central badge path by removing an unused legacy domain rather than bypassing it with a local mapping.
Proportionality / no premature abstraction PASS The plan removes existing residue and introduces no new abstraction, enum, registry, or persistence.
Persisted truth / behavioral state PASS Historical columns and migrations remain untouched; no new state or artifact is introduced.
Badge semantics / Filament-native discipline PASS Central badge semantics remain authoritative, and no page-local or view-local replacement badge language is added.
Filament v5 / Livewire v4 contract PASS Existing resources remain unchanged in behavior; provider registration and global-search posture stay compliant.
Test governance PASS Proof stays in focused feature/unit lanes with no heavy-family promotion and a net reduction in fixture-default ambiguity.

Test Governance Check

  • Test purpose / classification by changed surface: Feature for tenant-truth and baseline-profile continuity; Unit for central badge-catalog cleanup
  • Affected validation lanes: fast-feedback, confidence
  • Why this lane mix is the narrowest sufficient proof: The business truth is continuity after residue removal. Feature tests prove runtime behavior on current tenant and baseline flows, while one small unit slice proves the central badge cleanup without widening into browser or heavy-governance coverage.
  • Narrowest proving command(s):
    • export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
    • export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantTruthCleanupSpec179Test.php tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php
    • export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Baselines/BaselineProfileArchiveActionTest.php tests/Feature/Filament/BaselineProfileListFiltersTest.php tests/Feature/Filament/BaselineProfileScopeV2PersistenceTest.php tests/Feature/Baselines/BaselineProfileWorkspaceOwnershipTest.php tests/Feature/Baselines/BaselineProfileAuthorizationTest.php
    • export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Badges/TenantBadgesTest.php tests/Unit/Badges/BadgeCatalogTest.php
    • export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd /Users/ahmeddarrazi/Documents/projects/wt-plattform && rg -n "BaselineProfile::STATUS_|TenantAppStatus|tenant_app_status" apps/platform/app apps/platform/tests apps/platform/database/factories && rg -n -- "app_status" apps/platform/app apps/platform/tests apps/platform/database/factories
  • Fixture / helper / factory / seed / context cost risks: Low to moderate. Removing the default app_status from TenantFactory and browser fixture setup can expose hidden reliance on ambient legacy values in tests or smoke commands.
  • Expensive defaults or shared helper growth introduced?: No. The change reduces a misleading default rather than adding a new helper burden.
  • Heavy-family additions, promotions, or visibility changes: none
  • Surface-class relief / special coverage rule: standard-native relief
  • Closing validation and reviewer handoff: Reviewers should verify that removed residue had no active runtime dependency, that tenant/baseline tests still pass without ambient legacy defaults, and that no migration or new compatibility path slipped in.
  • Budget / baseline / trend follow-up: none
  • Review-stop questions: Did any test or fixture still need app_status but fail to set it explicitly? Did badge cleanup remove a still-used domain? Did alias removal trigger any runtime or static reference outside the planned scope? Did the cleanup expand into schema or route changes?
  • Escalation path: document-in-feature
  • Active feature PR close-out entry: Guardrail
  • Why no dedicated follow-up spec is needed: This is routine current-release cleanup. A follow-up spec is only needed if a hidden runtime dependency forces a broader domain decision rather than simple residue removal.

Project Structure

Documentation (this feature)

specs/234-dead-transitional-residue/
├── spec.md
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── checklists/
│   └── requirements.md
└── tasks.md

No contracts artifact is planned because this cleanup changes no route, API, or standalone logical interaction contract.

Source Code (repository root)

apps/platform/
├── app/
│   ├── Console/Commands/
│   │   └── SeedBackupHealthBrowserFixture.php
│   ├── Models/
│   │   └── BaselineProfile.php
│   └── Support/Badges/
│       ├── BadgeCatalog.php
│       ├── BadgeDomain.php
│       └── Domains/
│           └── TenantAppStatusBadge.php
├── database/
│   └── factories/
│       └── TenantFactory.php
└── tests/
    ├── Feature/
    │   ├── Baselines/
    │   │   ├── BaselineProfileArchiveActionTest.php
    │   │   ├── BaselineProfileAuthorizationTest.php
    │   │   └── BaselineProfileWorkspaceOwnershipTest.php
    │   └── Filament/
    │       ├── BaselineProfileListFiltersTest.php
    │       ├── BaselineProfileScopeV2PersistenceTest.php
    │       ├── TenantLifecycleStatusDomainSeparationTest.php
    │       └── TenantTruthCleanupSpec179Test.php
    └── Unit/
        └── Badges/
            ├── BadgeCatalogTest.php
            └── TenantBadgesTest.php

Structure Decision: Keep the work entirely inside the existing Laravel application in apps/platform. The plan updates one model, one central badge path, one default tenant factory, one browser fixture command, and focused regression files rather than touching resource layout or introducing a cleanup subsystem.

Complexity Tracking

No constitutional violation is planned. No new structure is introduced, so no complexity exception is required.

Violation Why Needed Simpler Alternative Rejected Because

Proportionality Review

No new enum, persisted entity, abstraction layer, taxonomy, or cross-domain UI framework is planned in this slice.

  • Current operator problem: Dead alias and legacy-support residue still make it easy for contributors and tests to treat retired semantics as current repo truth.
  • Existing structure is insufficient because: The current code already has the canonical BaselineProfileStatus path and current tenant-truth behavior, but dead support artifacts continue to conserve the older semantics around them.
  • Narrowest correct implementation: Remove only the dead alias/support paths and make any still-needed legacy values explicit in the few tests or fixtures that truly need them.
  • Ownership cost created: Small one-time cleanup across a handful of files, followed by lower ongoing cognitive and maintenance cost.
  • Alternative intentionally rejected: Keeping deprecated aliases, badge domains, or factory defaults for convenience was rejected because this is a pre-production repo and the residue already undermines cleanup discipline.
  • Release truth: Current-release truth cleanup.

Phase 0 Research Summary

  • BaselineProfile::STATUS_DRAFT, STATUS_ACTIVE, and STATUS_ARCHIVED exist only in apps/platform/app/Models/BaselineProfile.php; no current apps/platform runtime or test reference still needs them.
  • The tenant app-status badge path is now pure residue: BadgeDomain::TenantAppStatus, the BadgeCatalog mapper entry, and TenantAppStatusBadge remain, but the only confirmed consumers are badge tests, not current runtime surfaces.
  • TenantFactory still defaults app_status to ok, and SeedBackupHealthBrowserFixture still writes app_status => 'ok', which keeps a retired value ambient in test and smoke data even though current tenant surfaces no longer depend on it.
  • Existing tenant-truth regressions intentionally set app_status in a few scenarios to prove suppression. Those explicit setups should remain where meaningful; only ambient defaults should go away.
  • Historical migrations and historical stored columns are not part of this cleanup. The correct scope is runtime/support residue removal first, not schema deletion.

Phase 1 Design Summary

  • research.md records the cleanup decisions and rejected alternatives.
  • data-model.md documents the still-active persistent truths and the support artifacts that should stop acting as active repo truth.
  • quickstart.md gives the narrow validation order for alias removal, badge cleanup, fixture cleanup, and regression verification.
  • No contracts artifact is created because the feature changes no route, API, or new user interaction contract.

Phase 1 — Agent Context Update

Run after artifact generation:

  • .specify/scripts/bash/update-agent-context.sh copilot

Implementation Strategy

Phase A — Remove dead baseline profile alias language

Goal: Make BaselineProfileStatus the only active baseline profile status contract.

Step File Change
A.1 apps/platform/app/Models/BaselineProfile.php Remove deprecated STATUS_DRAFT, STATUS_ACTIVE, and STATUS_ARCHIVED constants.
A.2 Targeted grep + baseline regression files Confirm no runtime or test path in apps/platform still references the removed aliases; keep baseline profile behavior proved through existing feature tests rather than adding a new alias-specific shim.

Phase B — Retire the dead tenant app-status badge path centrally

Goal: Remove the last active runtime support entry point for tenant app-status semantics.

Step File Change
B.1 apps/platform/app/Support/Badges/BadgeDomain.php Remove the TenantAppStatus enum case if no active runtime consumer remains.
B.2 apps/platform/app/Support/Badges/BadgeCatalog.php Remove the TenantAppStatus mapper registration.
B.3 apps/platform/app/Support/Badges/Domains/TenantAppStatusBadge.php Remove the mapper class once the registry path is gone.
B.4 apps/platform/tests/Unit/Badges/TenantBadgesTest.php and apps/platform/tests/Unit/Badges/BadgeCatalogTest.php Update badge coverage to prove the canonical tenant lifecycle/RBAC/permission domains still work and that the removed legacy domain no longer acts as active repo truth.

Phase C — Make legacy app-status explicit instead of ambient in defaults and smoke data

Goal: Stop silently injecting retired tenant app-status semantics into factories and browser fixture setup.

Step File Change
C.1 apps/platform/database/factories/TenantFactory.php Remove the default app_status => 'ok' assignment so tests must opt in explicitly when they need a historical value.
C.2 apps/platform/app/Console/Commands/SeedBackupHealthBrowserFixture.php Remove or conditionalize the forced app_status => 'ok' write unless the scenario explicitly requires it for a still-active smoke purpose.
C.3 Targeted tenant-truth tests Keep explicit app_status setup only in cases that intentionally prove the legacy field no longer surfaces as truth.

Phase D — Rebalance regression coverage around explicit legacy setup

Goal: Preserve current behavior while making the cleanup durable.

Step File Change
D.1 apps/platform/tests/Feature/Filament/TenantTruthCleanupSpec179Test.php Keep explicit legacy app_status values where they prove suppression; stop depending on factory defaults.
D.2 apps/platform/tests/Feature/Filament/TenantLifecycleStatusDomainSeparationTest.php Keep lifecycle/RBAC separation assertions intact with explicit historical setup where needed.
D.3 apps/platform/tests/Feature/Baselines/BaselineProfileArchiveActionTest.php, apps/platform/tests/Feature/Filament/BaselineProfileListFiltersTest.php, apps/platform/tests/Feature/Filament/BaselineProfileScopeV2PersistenceTest.php, apps/platform/tests/Feature/Baselines/BaselineProfileWorkspaceOwnershipTest.php, and apps/platform/tests/Feature/Baselines/BaselineProfileAuthorizationTest.php Use these existing baseline profile tests as continuity proof after alias removal across archive, list/filter, view/edit, and workspace-owned behavior.

Risks and Mitigations

  • Hidden dependency on removed badge domain: A helper or test outside the initial grep scope may still call BadgeDomain::TenantAppStatus. Mitigation: targeted grep before merge plus running TenantBadgesTest and BadgeCatalogTest after central removal.
  • Ambient fixture reliance on app_status: Removing the factory default can reveal tests or smoke commands that only passed because app_status was silently set to ok. Mitigation: convert those cases to explicit setup rather than restoring the default.
  • Baseline alias removal reaches farther than expected: A non-obvious reference could still exist outside the model. Mitigation: grep for BaselineProfile::STATUS_ before merge and rely on existing baseline feature tests for continuity.
  • Cleanup scope drifts into schema deletion: The presence of migrations and stored columns can tempt a larger cut. Mitigation: keep historical schema/migrations explicitly out of scope in both plan and tasks.

Post-Design Re-check

The plan remains constitution-compliant, Livewire v4 / Filament v5 compliant, and appropriately narrow. It removes dead runtime/support residue, preserves existing tenant and baseline behavior, introduces no new persistence or abstraction, and is ready for /speckit.tasks.

Implementation Close-Out

  • Residue search result: Clean for active runtime/support paths. Remaining tenant_app_status and BaselineProfile::class.'::STATUS_*' matches are negative regression assertions only.
  • Remaining app_status usage: Explicit historical setup and suppression assertions in tenant-truth tests only. TenantFactory and the backup-health browser fixture no longer write ambient app_status defaults.
  • Follow-up decision: No hidden runtime dependency was found, so no follow-up cleanup spec is needed for this slice.