Admin Record State UX Follow-up Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Make exceptional page, layout, media, widget, and widget-asset records discoverable, actionable, and safe to review in Filament without overstating incomplete usage evidence.
Architecture: Reuse the completed Admin record-state contract and have each owning package resolve its own queryable facts in typed Actions/Data. Tables use bounded query predicates and aggregates; headers, selectors, confirmations, and the Layout Builder health widget receive preloaded data and do not query while rendering. Unused is emitted only from an authoritative complete usage boundary; all other zero evidence uses a scoped or tracked-use label.
Tech Stack: PHP 8.4, Laravel, Filament 4, Spatie Laravel Data, Pest, Blade, Core/Admin packages, and the Layout Builder companion package.
Closeout: Implemented and locally verified on 2026-08-02. Core/Admin
focused tests (46 / 297), record-state fixture tests (5 / 37), and full static
analysis pass. Layout Builder focused tests (33 / 555), targeted static
analysis, screenshot-runner JavaScript tests (5 / 5), and two authenticated
integrity captures pass. Full companion analysis remains blocked by the
pre-existing nullable-label finding in packages/navigation’s
NavigationSelect, outside this slice. Sol final review approved all
task-owned changes.
File Map
Section titled “File Map”Core/Admin changes live in this repository.
- Create
packages/admin/src/Data/RecordDeletionImpactData.php: immutable copy-ready summary of known direct dependencies, authority, and optional view-uses URL. - Create
packages/admin/src/Actions/Pages/BuildPageDeletionImpactAction.phpandpackages/admin/src/Actions/Layouts/BuildLayoutDeletionImpactAction.php: build only the bounded facts that the existing delete action can safely disclose. - Modify
packages/admin/src/Data/Pages/PageRelationshipCountsData.phpandpackages/admin/src/Filament/Resources/PageUrls/Tables/PageUrlsTable.php: add a pageable filter and matching Page URL management URLs to already-resolved positive count data. - Modify
packages/admin/src/Support/Layouts/LayoutCardData.php,packages/admin/src/Filament/Components/Forms/Page/LayoutSelect.php, andpackages/admin/src/Filament/Resources/Layouts/Tables/LayoutsTable.php: use the existing variation-aware aggregate for links, filters, and impact summaries. - Modify
packages/admin/src/Filament/Resources/Pages/Tables/PagesTable.php: add availability-only filters while retaining the existing publication filter. - Modify
packages/admin/src/Filament/Resources/Media/Tables/MediaTable.php: add an authority-labelled tracked-use filter and deep link to its existing usage surface. - Modify
packages/admin/resources/lang/en/table.phpandpackages/admin/resources/lang/en/generic.php: translated filter, impact, and work-queue copy. - Add/update focused Admin tests in
packages/admin/tests/Feature/Actions/Pages,packages/admin/tests/Feature/Actions/Layouts,packages/admin/tests/Feature/Filament/Resources/Page,packages/admin/tests/Feature/Filament/Resources/Layout,packages/admin/tests/Feature/Filament/Resources/Media, andpackages/admin/tests/Feature/Filament/Components.
Layout Builder changes live in the sibling ../capell-packages-4 checkout.
- Create
packages/layout-builder/src/Data/Dashboard/LayoutHealthWorkQueueItemData.phpandpackages/layout-builder/src/Actions/BuildLayoutHealthWorkQueueAction.php: package-owned scoped work-queue facts and URLs. - Create
packages/layout-builder/src/Actions/BuildWidgetDeletionImpactAction.php: widget placement/asset impact facts without decoding layout content per row. - Modify
packages/layout-builder/src/Filament/Resources/Widgets/Tables/WidgetsTable.php,WidgetAssetsTable.php,WidgetSelectionTable.php,packages/layout-builder/src/Filament/Components/Forms/WidgetSelect.php, andPages/EditWidget.php: filters, state-bearing selection labels, and impact copy. - Modify
packages/layout-builder/src/Data/Dashboard/LayoutHealthData.php,packages/layout-builder/src/Filament/Widgets/LayoutHealthFilamentWidget.php, andresources/views/filament/widgets/layout-health.blade.php: render the bounded work queue and deep links. - Modify
packages/layout-builder/resources/lang/en/table.phpandpackages/layout-builder/resources/lang/en/widgets.php: translated state, filter, impact, and work-queue copy. - Add/update focused tests in
packages/layout-builder/tests/Unit/Filament,packages/layout-builder/tests/Feature/Filament/Resources/Widget, andpackages/layout-builder/tests/Unit.
Task 1: Establish authority-aware deletion-impact data and presentation
Section titled “Task 1: Establish authority-aware deletion-impact data and presentation”Files:
-
Create:
packages/admin/src/Data/RecordDeletionImpactData.php -
Create:
packages/admin/resources/views/components/record-deletion-impact.blade.php -
Modify:
packages/admin/resources/lang/en/generic.php -
Test:
packages/admin/tests/Feature/Filament/Components/RecordDeletionImpactPresentationTest.php -
Step 1: Write failing rendering and data tests
Add tests that construct these three cases and render the component:
new RecordDeletionImpactData(knownReferenceCount: 0,authoritative: true,noReferencesLabel: __('capell-admin::generic.deletion_impact_unused'),);new RecordDeletionImpactData(knownReferenceCount: 3,authoritative: true,affectedLabel: trans_choice('capell-admin::generic.deletion_impact_pages', 3, ['count' => 3]),referencesUrl: '/admin/pages?filters[layout_id][value]=7',);new RecordDeletionImpactData(knownReferenceCount: 0,authoritative: false,noReferencesLabel: __('capell-admin::generic.deletion_impact_no_tracked_uses'),);Assert visible text in all cases, a link only for the known-reference case, and that neither zero case renders the word
Unusedunlessauthoritativeis true. -
Step 2: Run the focused test to verify the missing contract
Run:
Terminal window ./vendor/bin/pest packages/admin/tests/Feature/Filament/Components/RecordDeletionImpactPresentationTest.php --configuration=phpunit.xmlExpected: FAIL because the Data class and Blade component do not exist.
-
Step 3: Implement the immutable contract and accessible component
Create
RecordDeletionImpactDatawith this public constructor shape:final class RecordDeletionImpactData extends Data{public function __construct(public readonly int $knownReferenceCount,public readonly bool $authoritative,public readonly string $noReferencesLabel,public readonly ?string $affectedLabel = null,public readonly ?string $referencesUrl = null,public readonly ?string $reviewLabel = null,) {}}The Blade component must render
noReferencesLabelwhen the count is zero; otherwise it rendersaffectedLabeland wraps it in an anchor only whenreferencesUrlis non-empty.reviewLabelis supplementary visible copy for incomplete/broken evidence. Do not compose HTML in an Action. -
Step 4: Add translations and verify the test passes
Add singular/plural impact labels and the two explicit zero labels to
generic.php, then rerun Step 2. Expected: PASS. -
Step 5: Commit the shared contract
Terminal window git add packages/admin/src/Data/RecordDeletionImpactData.php packages/admin/resources/views/components/record-deletion-impact.blade.php packages/admin/resources/lang/en/generic.php packages/admin/tests/Feature/Filament/Components/RecordDeletionImpactPresentationTest.phpgit commit -m "feat(admin): add record deletion impact summaries"
Task 2: Add page and layout availability discovery, count links, and delete copy
Section titled “Task 2: Add page and layout availability discovery, count links, and delete copy”Files:
-
Create:
packages/admin/src/Actions/Pages/BuildPageDeletionImpactAction.php -
Create:
packages/admin/src/Actions/Layouts/BuildLayoutDeletionImpactAction.php -
Modify:
packages/admin/src/Data/Pages/PageRelationshipCountsData.php -
Modify:
packages/admin/src/Filament/Resources/PageUrls/Tables/PageUrlsTable.php -
Modify:
packages/admin/src/Filament/Resources/Pages/Tables/PagesTable.php -
Modify:
packages/admin/src/Filament/Resources/Layouts/Tables/LayoutsTable.php -
Modify:
packages/admin/src/Support/Layouts/LayoutCardData.php -
Modify:
packages/admin/src/Filament/Components/Forms/Page/LayoutSelect.php -
Test:
packages/admin/tests/Feature/Actions/Pages/BuildPageDeletionImpactActionTest.php -
Test:
packages/admin/tests/Feature/Actions/Layouts/BuildLayoutDeletionImpactActionTest.php -
Test:
packages/admin/tests/Feature/Filament/Resources/Page/Tables/PagesTableAvailabilityFilterTest.php -
Test:
packages/admin/tests/Feature/Filament/Resources/Layout/Pages/ListLayoutsTest.php -
Test:
packages/admin/tests/Feature/Filament/Components/LayoutSelectTest.php -
Step 1: Write failing Action tests for bounded page and layout facts
Cover a page with zero/one URL and a layout used by pages in two registered page variations. Assert the Actions return these exact facts:
expect(BuildPageDeletionImpactAction::run($page))->toMatchObject(['knownReferenceCount' => 1,'authoritative' => true,'referencesUrl' => PageUrlResource::getUrl('index', ['filters[pageable][pageable_type]' => $page->getMorphClass(),'filters[pageable][pageable_id]' => $page->getKey(),]),]);expect(BuildLayoutDeletionImpactAction::run($layout))->toMatchObject(['knownReferenceCount' => 2,'authoritative' => true,]);The layout test must prove both variation tables contribute to the count and that a site-scoped actor sees only permitted page references.
-
Step 2: Add failing table/filter tests
In
PagesTableAvailabilityFilterTest, reflect and invoke a newapplyAvailabilityFilterQuery(Builder $query, array $data)for:['value' => 'no_active_url']['value' => 'some_urls_disabled']Seed enabled and disabled
PageUrlrows and assert the first query selects only pages without an enabled URL while the second selects pages that have at least one enabled URL and at least one disabled URL. InListLayoutsTest, assertdisabledandunusedfilters respect the existinggetUsesCountSelect()site constraint and that a positive page count renders a page-list URL. InLayoutSelectTest, assert the same aggregate produces a deep link, not a fresh per-option query. -
Step 3: Run the focused failing tests
Run:
Terminal window ./vendor/bin/pest packages/admin/tests/Feature/Actions/Pages/BuildPageDeletionImpactActionTest.php packages/admin/tests/Feature/Actions/Layouts/BuildLayoutDeletionImpactActionTest.php packages/admin/tests/Feature/Filament/Resources/Page/Tables/PagesTableAvailabilityFilterTest.php packages/admin/tests/Feature/Filament/Resources/Layout/Pages/ListLayoutsTest.php packages/admin/tests/Feature/Filament/Components/LayoutSelectTest.php --configuration=phpunit.xmlExpected: FAIL because the Actions, availability filter, and URL-bearing relationship data are not implemented.
-
Step 4: Implement the page data flow
Add a
SelectFilter::make('availability')toPagesTable::getBaseTableFilters()with translated optionsno_active_urlandsome_urls_disabled. Implement its query with relationships, not presentation state:return match ($value) {'no_active_url' => $query->whereDoesntHave('pageUrls', fn (Builder $urlQuery): Builder => $urlQuery->where('status', true)),'some_urls_disabled' => $query->whereHas('pageUrls', fn (Builder $urlQuery): Builder => $urlQuery->where('status', true))->whereHas('pageUrls', fn (Builder $urlQuery): Builder => $urlQuery->where('status', false)),default => $query,};Add
Filter::make('pageable')toPageUrlsTablewith hiddenpageable_typeandpageable_idfields, and apply both columns when they are populated. MakePageRelationshipCountsData::fromPage()supply the matching Page URL index URL only whenpage_urls_count > 0.BuildPageDeletionImpactActionreuses that count and URL; it does not inspect page content or discover indirect uses. Set the record and bulk Page delete modal content to the shared impact component, preservingvalidateDelete()andPageDeletedActionhooks. -
Step 5: Implement variation-aware layout flow
Add
TernaryFilter::make('status')for disabled layouts and a separateFilter::make('unused')that compares the sameLayoutsTable::getUsesCountSelect($query)expression to zero. Reuse the existing selected aggregate inLayoutCardDataandLayoutSelect; populateRecordRelationshipCountData::$urlonly from a stable filtered page-resource URL. Do not loop through page variations in a formatter closure.BuildLayoutDeletionImpactActionreceives a Layout withpages_countwhen present and otherwise performs one actor-scoped variation aggregate. It marks the result authoritative only for that complete registered variation query. Attach the shared component to individual and bulk Layout delete actions without changingvalidateDelete()behaviour. -
Step 6: Run tests and static analysis
Rerun Step 3, then run:
Terminal window composer analyzeExpected: focused tests PASS and static analysis reports 0 errors.
-
Step 7: Commit page and layout work
Terminal window git add packages/admin/src/Actions/Pages packages/admin/src/Actions/Layouts packages/admin/src/Data/Pages/PageRelationshipCountsData.php packages/admin/src/Filament/Resources/PageUrls/Tables/PageUrlsTable.php packages/admin/src/Filament/Resources/Pages/Tables/PagesTable.php packages/admin/src/Filament/Resources/Layouts/Tables/LayoutsTable.php packages/admin/src/Support/Layouts/LayoutCardData.php packages/admin/src/Filament/Components/Forms/Page/LayoutSelect.php packages/admin/resources/lang/en/table.php packages/admin/resources/lang/en/generic.php packages/admin/tests/Feature/Actions/Pages packages/admin/tests/Feature/Actions/Layouts packages/admin/tests/Feature/Filament/Resources/Page packages/admin/tests/Feature/Filament/Resources/Layout packages/admin/tests/Feature/Filament/Components/LayoutSelectTest.phpgit commit -m "feat(admin): make page and layout exceptions actionable"
Task 3: Add media tracked-use discovery without inventing an exhaustive asset claim
Section titled “Task 3: Add media tracked-use discovery without inventing an exhaustive asset claim”Files:
-
Modify:
packages/admin/src/Filament/Resources/Media/Tables/MediaTable.php -
Modify:
packages/admin/resources/lang/en/table.php -
Test:
packages/admin/tests/Feature/Filament/Resources/Media/Pages/ListMediaTest.php -
Step 1: Write failing media filter and deep-link tests
Seed one media record with an
AssetAttachmentand one without. Assert a newtracked_usefilter selects only the zero-attachment record and its indicator saysNo tracked uses. Assert the existing positive usage count continues to link to the existing media usage surface; zero remains text, never a cleanup action. -
Step 2: Run the focused test to confirm failure
Terminal window ./vendor/bin/pest packages/admin/tests/Feature/Filament/Resources/Media/Pages/ListMediaTest.php --configuration=phpunit.xmlExpected: FAIL because no tracked-use filter is registered.
-
Step 3: Implement the bounded filter and presentation
Add a
SelectFilter::make('tracked_use')withusedandunusedoptions. Use the model’s existing attachment usage query/count source rather than a generic mediadoesntHave()relation, so the predicate exactly matches the establishedusage_countsemantics. Keep theusage_countcolumn’s warning badge, useNo tracked usesfor zero, and add an owner-authorized usage URL only for positive counts. The attachment tracker is not represented as a complete cross-extension reference boundary. -
Step 4: Rerun test and commit
Terminal window ./vendor/bin/pest packages/admin/tests/Feature/Filament/Resources/Media/Pages/ListMediaTest.php --configuration=phpunit.xmlgit add packages/admin/src/Filament/Resources/Media/Tables/MediaTable.php packages/admin/resources/lang/en/table.php packages/admin/tests/Feature/Filament/Resources/Media/Pages/ListMediaTest.phpgit commit -m "feat(admin): filter media by tracked usage"Expected: test PASS; the commit contains no media deletion or storage changes.
Task 4: Make Layout Builder widget and widget-asset state discoverable in tables, headers, and selects
Section titled “Task 4: Make Layout Builder widget and widget-asset state discoverable in tables, headers, and selects”Files:
-
Create:
packages/layout-builder/src/Actions/BuildWidgetDeletionImpactAction.php -
Modify:
packages/layout-builder/src/Filament/Resources/Widgets/Tables/WidgetsTable.php -
Modify:
packages/layout-builder/src/Filament/Resources/Widgets/Tables/WidgetAssetsTable.php -
Modify:
packages/layout-builder/src/Filament/Resources/Widgets/Tables/WidgetSelectionTable.php -
Modify:
packages/layout-builder/src/Filament/Components/Forms/WidgetSelect.php -
Modify:
packages/layout-builder/src/Filament/Resources/Widgets/Pages/EditWidget.php -
Modify:
packages/layout-builder/resources/lang/en/table.php -
Test:
packages/layout-builder/tests/Unit/Filament/LayoutBuilderResourceTableCoverageTest.php -
Test:
packages/layout-builder/tests/Feature/Filament/Resources/Widget/Pages/EditWidgetTest.php -
Test:
packages/layout-builder/tests/Unit/WidgetDeletionImpactActionTest.php -
Step 1: Write failing widget state tests
Extend table coverage to prove that widgets with
layouts_count = 0match anunusedfilter, disabled widgets match the existing status filter, and theWidgetSelectlabel includes both disabled/unavailable and usage state. Seed a widget asset with a missingassettarget and one with a valid layout-level target without pageable fields; assert their integrity filter separatesbroken_referencefromunscoped.Add a deletion-impact Action test asserting a widget with layout placements receives a positive count and Layout index URL, while a zero count uses the authority-aware zero label. The test must use the existing indexed
layouts_countquery/source and must not construct JSON layout content in PHP. -
Step 2: Run the companion focused tests and confirm failure
Terminal window ./vendor/bin/pest packages/layout-builder/tests/Unit/Filament/LayoutBuilderResourceTableCoverageTest.php packages/layout-builder/tests/Feature/Filament/Resources/Widget/Pages/EditWidgetTest.php packages/layout-builder/tests/Unit/WidgetDeletionImpactActionTest.php --configuration=phpunit.xmlExpected: FAIL because the filters, select state metadata, header summary, and deletion-impact Action are absent.
-
Step 3: Implement widget state and safe impact flow
Ensure
WidgetsTableselects the existinglayouts_countaggregate once; add aFilter::make('usage')that uses its query-safe source forunused. UpdateWidgetSelectto eager-load the same count plus status and passRecordStateData/RecordRelationshipCountDataintoHasCustomSelectOption:'states' => array_values(array_filter([$record->isDisabled() ? new RecordStateData(key: 'disabled',label: (string) __('capell-admin::generic.disabled'),description: (string) __('capell-layout-builder::table.widget_unavailable_tooltip'),color: 'danger',icon: Heroicon::OutlinedEyeSlash,priority: 10,) : null,$layoutsCount === 0 ? new RecordStateData(key: 'unused',label: (string) __('capell-admin::table.unused'),description: (string) __('capell-layout-builder::table.widget_usage_unused_tooltip'),color: 'warning',icon: Heroicon::OutlinedExclamationTriangle,priority: 20,) : null,])),'relationships' => [new RecordRelationshipCountData(key: 'layouts',label: (string) __('capell-admin::table.total_layouts'),count: $layoutsCount,url: $layoutsCount > 0 ? $layoutsUrl : null,)],Replace
EditWidget::getSubheading()’s hand-built disabled span with the shared Admin state summary. Add the custom AdminDeleteActionmodal content fromBuildWidgetDeletionImpactActionto widget delete actions only; preserve soft-delete and force-delete authorization.In
WidgetAssetsTable, eager-loadwidget,asset, andpageable; add a dedicated state filter whose predicates match the existingusage_statuslogic. Missing targets areBroken reference; valid no-pageable assignment isUnscoped. Do not call eitherUnused. -
Step 4: Rerun focused tests and package-local static analysis
Terminal window ./vendor/bin/pest packages/layout-builder/tests/Unit/Filament/LayoutBuilderResourceTableCoverageTest.php packages/layout-builder/tests/Feature/Filament/Resources/Widget/Pages/EditWidgetTest.php packages/layout-builder/tests/Unit/WidgetDeletionImpactActionTest.php --configuration=phpunit.xml./vendor/bin/phpstan analyse packages/layout-builder/src/Actions/BuildWidgetDeletionImpactAction.php packages/layout-builder/src/Filament/Resources/Widgets/Tables/WidgetsTable.php packages/layout-builder/src/Filament/Resources/Widgets/Tables/WidgetAssetsTable.php packages/layout-builder/src/Filament/Components/Forms/WidgetSelect.php packages/layout-builder/src/Filament/Resources/Widgets/Pages/EditWidget.php --memory-limit=4G --configuration=phpstan.neonExpected: focused tests PASS and targeted PHPStan reports 0 errors. If the unrelated
NavigationSelectnullable-string finding still blocks full companion analysis, record it separately and do not alter that unrelated file. -
Step 5: Commit companion resource work
Terminal window git add packages/layout-builder/src/Actions/BuildWidgetDeletionImpactAction.php packages/layout-builder/src/Filament/Resources/Widgets packages/layout-builder/src/Filament/Components/Forms/WidgetSelect.php packages/layout-builder/resources/lang/en/table.php packages/layout-builder/tests/Unit/Filament/LayoutBuilderResourceTableCoverageTest.php packages/layout-builder/tests/Feature/Filament/Resources/Widget/Pages/EditWidgetTest.php packages/layout-builder/tests/Unit/WidgetDeletionImpactActionTest.phpgit commit -m "feat(layout-builder): make widget states actionable"
Task 5: Turn the existing Layout Health widget into a scoped work queue
Section titled “Task 5: Turn the existing Layout Health widget into a scoped work queue”Files:
-
Create:
packages/layout-builder/src/Data/Dashboard/LayoutHealthWorkQueueItemData.php -
Create:
packages/layout-builder/src/Actions/BuildLayoutHealthWorkQueueAction.php -
Modify:
packages/layout-builder/src/Data/Dashboard/LayoutHealthData.php -
Modify:
packages/layout-builder/src/Filament/Widgets/LayoutHealthFilamentWidget.php -
Modify:
packages/layout-builder/resources/views/filament/widgets/layout-health.blade.php -
Modify:
packages/layout-builder/resources/lang/en/widgets.php -
Test:
packages/layout-builder/tests/Unit/BuildLayoutHealthWorkQueueActionTest.php -
Test:
packages/layout-builder/tests/Unit/LayoutBuilderThirdRoundResidualCoverageTest.php -
Step 1: Write failing work-queue Action tests
Build fixtures for unused widgets, disabled widgets, broken widget assets, unscoped widget assets, disabled layouts, and a page with no active URL. Assert the Action returns only items accessible to the actor, each item has a translated label/count, and only records with a stable resource query receive a URL. Assert a zero count for a non-authoritative boundary has label
No tracked uses, notUnused. -
Step 2: Run the focused test to confirm failure
Terminal window ./vendor/bin/pest packages/layout-builder/tests/Unit/BuildLayoutHealthWorkQueueActionTest.php packages/layout-builder/tests/Unit/LayoutBuilderThirdRoundResidualCoverageTest.php --configuration=phpunit.xmlExpected: FAIL because the Action and work-queue data are missing.
-
Step 3: Implement one bounded work-queue Action
Create this data shape:
final class LayoutHealthWorkQueueItemData extends Data{public function __construct(public readonly string $key,public readonly string $label,public readonly int $count,public readonly string $color,public readonly ?string $url,public readonly bool $authoritative,) {}}BuildLayoutHealthWorkQueueActionowns all queries and returns a short, deterministic list. It usesAdminSurfaceLookup::resourceIfRegistered()before attempting Admin URLs, applies the current actor’s scope to layouts and pages, and returns no page/layout item when the matching Admin resource is unavailable. It never loops over layout JSON to count uses.Add
Collection<int, LayoutHealthWorkQueueItemData> $workQueuetoLayoutHealthData, replace the widget’s ad-hoc unused-widget query with the Action result, and render a compact linked list under a translatedNeeds attentionheading. Preserve the existing group and least-used-widget information in the same rendering path. -
Step 4: Verify presentation and query safety
Rerun Step 2 and add a view assertion for the heading, count, state label, and URL. Confirm the Blade view accesses only
$data->workQueueproperties; it must not call model relations or Actions. -
Step 5: Commit the health queue
Terminal window git add packages/layout-builder/src/Data/Dashboard packages/layout-builder/src/Actions/BuildLayoutHealthWorkQueueAction.php packages/layout-builder/src/Filament/Widgets/LayoutHealthFilamentWidget.php packages/layout-builder/resources/views/filament/widgets/layout-health.blade.php packages/layout-builder/resources/lang/en packages/layout-builder/tests/Unit/BuildLayoutHealthWorkQueueActionTest.php packages/layout-builder/tests/Unit/LayoutBuilderThirdRoundResidualCoverageTest.phpgit commit -m "feat(layout-builder): add record health work queue"
Task 6: Run regression verification, update the design status, and record the cross-repository handoff
Section titled “Task 6: Run regression verification, update the design status, and record the cross-repository handoff”Files:
-
Modify:
docs/admin/record-state-ux-follow-up-design.md -
Modify:
docs/admin/record-state-ux-follow-up-plan.md -
Modify: the internal ledger’s
projects/capell/TODO.mdin a safe ledger branch/worktree only -
Step 1: Run focused cross-repository regression suites
In Core/Admin:
Terminal window ./vendor/bin/pest packages/admin/tests/Feature/Actions/Pages packages/admin/tests/Feature/Actions/Layouts packages/admin/tests/Feature/Filament/Components/RecordDeletionImpactPresentationTest.php packages/admin/tests/Feature/Filament/Resources/Page packages/admin/tests/Feature/Filament/Resources/Layout packages/admin/tests/Feature/Filament/Resources/Media --configuration=phpunit.xmlcomposer analyzephp scripts/check-docs-links.phpIn Layout Builder:
Terminal window ./vendor/bin/pest packages/layout-builder/tests/Unit/Filament/LayoutBuilderResourceTableCoverageTest.php packages/layout-builder/tests/Feature/Filament/Resources/Widget/Pages/EditWidgetTest.php packages/layout-builder/tests/Unit/WidgetDeletionImpactActionTest.php packages/layout-builder/tests/Unit/BuildLayoutHealthWorkQueueActionTest.php --configuration=phpunit.xml./vendor/bin/phpstan analyse packages/layout-builder/src/Actions/BuildWidgetDeletionImpactAction.php packages/layout-builder/src/Actions/BuildLayoutHealthWorkQueueAction.php packages/layout-builder/src/Filament/Resources/Widgets packages/layout-builder/src/Filament/Widgets/LayoutHealthFilamentWidget.php --memory-limit=4G --configuration=phpstan.neonExpected: focused suites and targeted static analysis PASS. Report the known unrelated full companion PHPStan failure only if it still occurs.
-
Step 2: Perform an Admin browser/user test if the local application is available
Verify a disabled/scheduled page, unused layout, unused/no-tracked-use media, unused widget, and broken widget asset in their actual table and selected option. Verify each deep link preserves its filter and that delete modals show consequence copy without changing delete eligibility. Capture no customer data and do not perform a deletion.
-
Step 3: Request and resolve the Sol expert review
Request a read-only Sol review of the exact Core/Admin and Layout Builder diffs after the focused suites pass. Give the reviewer the approved design, the authority rule for
Unused, the no-query-in-rendering rule, and the known unrelated companion PHPStan finding. Resolve every P1/P2 finding and any low-risk P3 correctness/accessibility issue, then rerun the focused tests that cover the changed area. Record accepted residuals only when they are explicitly outside this slice. -
Step 4: Reconcile documentation and ledger
Mark completed plan checkboxes, update the design status to implemented, and add exact commits/test output/review result to CAP-0080. Preserve the primary ledger checkout’s unrelated changes by using a dedicated ledger branch or worktree; do not push, open a PR, merge, release, deploy, seed, or migrate.
-
Step 5: Commit closeout documentation separately in each repository
Terminal window git add docs/admin/record-state-ux-follow-up-design.md docs/admin/record-state-ux-follow-up-plan.mdgit commit -m "docs(admin): record state UX follow-up verification"Commit the ledger only on its dedicated branch with a CAP-0080-specific message. Keep Core/Admin and Layout Builder commits focused; do not combine companion changes with the existing unrelated release-catalogue history.