- land the spec 192 resource, guard, browser smoke, and documentation changes - add unhandled rejection request correlation for 419 diagnostics - disable panel-wide database notification polling and cover it with focused tests
23 KiB
Implementation Plan: Record Page Header Discipline & Contextual Navigation
Branch: 192-record-header-discipline | Date: 2026-04-11 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/192-record-header-discipline/spec.md
Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/192-record-header-discipline/spec.md
Note: This plan keeps the work inside the existing Filament v5 / Livewire v4 resource pages, existing related-navigation helpers, and the existing action-surface guard infrastructure. It explicitly avoids introducing a new header-action framework.
Summary
Codify one bounded header-discipline contract for classic record/detail/edit pages in the admin panel. Reuse existing Filament header actions, ActionGroup, UiEnforcement, and RelatedNavigationResolver patterns to inventory all in-scope surfaces, remediate the five standard pages that currently have noisy headers, preserve already-clean reference pages, explicitly document ViewTenant as a workflow-heavy special type, and extend the existing action-surface and browser regression layers so new header sprawl does not re-enter the repo.
Technical Context
Language/Version: PHP 8.4.15
Primary Dependencies: Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing UiEnforcement, RelatedNavigationResolver, ActionSurfaceValidator, and page-local Filament action builders
Storage: PostgreSQL through existing workspace-owned and tenant-owned resource models; no schema change planned
Testing: Pest feature tests, existing guard tests, and browser smoke tests run through Laravel Sail
Target Platform: Laravel monolith web application under apps/platform, with workspace/admin routes under /admin, tenant-context routes under /admin/t/{tenant}/..., and no panel expansion planned
Project Type: web application
Performance Goals: Preserve the 5-second scan rule on record pages, keep all affected pages DB-only at render time, avoid new polling or asset work, and prevent header cleanup from adding extra query churn or remote calls
Constraints: No new action framework, no new persistence, no route or panel changes, no authorization-plane changes, no new status language, no silent special-type exemptions, and no expansion of Spec 133 body-composition requirements beyond current scope
Scale/Scope: 14 in-scope record/detail/edit surfaces, 5 remediation-required standard pages, 1 explicit workflow-heavy special-type exception, 2 minor-alignment audits, 6 compliant/no-op reference pages, and focused guard plus feature plus browser regression coverage
Constitution Check
GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.
| Principle | Pre-Research | Post-Design | Notes |
|---|---|---|---|
| Inventory-first / snapshots-second | PASS | PASS | The feature does not alter inventory or snapshot truth; it only reorganizes page headers. |
| Read/write separation | PASS | PASS | Existing mutations keep their current confirmation, audit, and test behavior. No new writes are introduced. |
| Graph contract path | N/A | N/A | No new Microsoft Graph call path or contract-registry change is planned. |
| Deterministic capabilities | PASS | PASS | Capability checks remain in canonical registries and UiEnforcement; regrouping actions does not change entitlement logic. |
| Workspace + tenant isolation | PASS | PASS | Existing route scopes and related-navigation availability rules remain authoritative. |
| RBAC-UX authorization semantics | PASS | PASS | Non-members remain 404, in-scope capability denial remains 403, and server-side authorization stays unchanged. |
| Run observability / Ops-UX | PASS | PASS | Underlying long-running actions such as capture, compare, refresh, and verification keep their existing OperationRun semantics. |
| Data minimization | PASS | PASS | No new persistence, caches, or header-state artifacts are introduced. |
| Proportionality / anti-bloat | PASS | PASS | The work stays inside existing pages and guard infrastructure instead of creating a new framework. |
| UI semantics / few layers | PASS | PASS | The feature relies on direct action placement and classification rather than a new presenter or semantic layer. |
| Filament-native UI | PASS | PASS | Native Filament header actions and ActionGroup remain the implementation path. |
| Surface taxonomy / HDR-001 | PASS | PASS | The plan explicitly classifies every in-scope page and documents the one workflow-heavy special type. |
| Filament v5 / Livewire v4 compliance | PASS | PASS | All touched pages remain inside the existing Filament v5 + Livewire v4 stack. |
| Provider registration location | PASS | PASS | No provider change is needed; Laravel 11+ provider registration remains in bootstrap/providers.php. |
| Global search hard rule | PASS | PASS | No new globally searchable resource is introduced; touched resources already have View/Edit pages where needed. |
| Destructive action safety | PASS | PASS | Existing destructive or governance-changing actions keep ->requiresConfirmation() and stay authorization-gated. |
| Asset strategy | PASS | PASS | No new assets or lazy-load registrations are needed; existing deploy handling of cd apps/platform && php artisan filament:assets remains unchanged. |
Filament-Specific Compliance Notes
- Livewire v4.0+ compliance: The plan remains on Filament v5 + Livewire v4 and introduces no legacy or mixed-version API usage.
- Provider registration location: No panel or provider changes are required; Laravel 11+ panel providers remain registered in
bootstrap/providers.php. - Global search: The feature does not add a new globally searchable resource. Touched resources continue to satisfy the Filament hard rule because they already have View and/or Edit pages; search behavior is otherwise unchanged.
- Destructive actions:
Expire snapshot,Revoke exception,Archive review, tenant lifecycle actions, backup lifecycle actions, and provider credential danger actions remain routed throughAction::make(...)->action(...)with->requiresConfirmation()and existing authorization. - Asset strategy: No new global or on-demand asset registration is planned. Existing deployment handling of
cd apps/platform && php artisan filament:assetsremains sufficient. - Testing plan: Extend the existing action-surface guard layer, add focused Livewire/Pest tests for the remediated pages and the explicit special type, and add a browser smoke suite that proves visible hierarchy on remediated headers.
Phase 0 Research
Research outcomes are captured in /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/192-record-header-discipline/research.md.
Key decisions:
- Reuse existing page-local action builders,
UiEnforcement,ActionGroup, andRelatedNavigationResolverinstead of introducing a header-action framework. - Move pure navigation to contextual placement outside the header instead of equal-weight header placement.
- Treat
ViewTenantas an explicit workflow-heavy special-type exception rather than a standard record page. - Preserve already-clean pages as reference patterns instead of cosmetically normalizing them.
- Build regression protection on top of the existing
ActionSurfaceValidator, focused page tests, and browser smoke patterns.
Phase 1 Design
Design artifacts are created under /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/192-record-header-discipline/:
research.md: decisions and rejected alternatives for bounded header disciplinedata-model.md: derived header-surface inventory, render contract, and regression expectation modelscontracts/record-header-discipline.logical.openapi.yaml: internal logical contract for standard-page headers, the special-type exception, and regression expectationsquickstart.md: implementation and verification sequence for the feature
Design highlights:
- Keep all classification and render rules derived, not persisted.
- Represent each in-scope surface through one explicit inventory entry and one explicit regression expectation.
- Keep state-sensitive primary-action decisions local to the existing pages rather than moving them into a shared runtime resolver.
- Treat
ViewTenantas the only explicit special type and require an exception reason in the regression layer. - Extend the existing guard system rather than creating a new validation framework.
Phase 1 — Agent Context Update
Planned command:
.specify/scripts/bash/update-agent-context.sh copilot
This feature does not introduce a new technology stack, but the required agent-context refresh still runs to keep the planning workflow complete.
Project Structure
Documentation (this feature)
specs/192-record-header-discipline/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── spec.md
├── contracts/
│ └── record-header-discipline.logical.openapi.yaml
└── checklists/
└── requirements.md
Source Code (repository root)
apps/platform/
├── app/
│ ├── Filament/
│ │ └── Resources/
│ │ ├── BaselineProfileResource.php # MODIFY
│ │ ├── BaselineProfileResource/
│ │ │ └── Pages/
│ │ │ └── ViewBaselineProfile.php # MODIFY
│ │ ├── EvidenceSnapshotResource.php # MODIFY
│ │ ├── EvidenceSnapshotResource/
│ │ │ └── Pages/
│ │ │ └── ViewEvidenceSnapshot.php # MODIFY
│ │ ├── FindingExceptionResource.php # MODIFY
│ │ ├── FindingExceptionResource/
│ │ │ └── Pages/
│ │ │ └── ViewFindingException.php # MODIFY
│ │ ├── TenantReviewResource.php # MODIFY
│ │ ├── TenantReviewResource/
│ │ │ └── Pages/
│ │ │ └── ViewTenantReview.php # MODIFY
│ │ ├── TenantResource.php # MODIFY
│ │ ├── TenantResource/
│ │ │ └── Pages/
│ │ │ ├── EditTenant.php # MODIFY
│ │ │ └── ViewTenant.php # MODIFY (special type ordering only)
│ │ ├── ProviderConnectionResource/
│ │ │ └── Pages/
│ │ │ └── ViewProviderConnection.php # AUDIT / possible minor alignment
│ │ ├── FindingResource/
│ │ │ └── Pages/
│ │ │ └── ViewFinding.php # AUDIT / possible minor alignment
│ │ ├── BackupSetResource/
│ │ │ └── Pages/
│ │ │ └── ViewBackupSet.php # REFERENCE only
│ │ ├── BaselineSnapshotResource/
│ │ │ └── Pages/
│ │ │ └── ViewBaselineSnapshot.php # REFERENCE only
│ │ ├── ReviewPackResource/
│ │ │ └── Pages/
│ │ │ └── ViewReviewPack.php # REFERENCE only
│ │ ├── AlertDestinationResource/
│ │ │ └── Pages/
│ │ │ └── ViewAlertDestination.php # REFERENCE only
│ │ ├── PolicyVersionResource/
│ │ │ └── Pages/
│ │ │ └── ViewPolicyVersion.php # REFERENCE only
│ │ └── Workspaces/
│ │ └── Pages/
│ │ └── ViewWorkspace.php # REFERENCE only
│ ├── Support/
│ │ ├── Navigation/
│ │ │ └── RelatedNavigationResolver.php # REUSE
│ │ ├── Rbac/
│ │ │ └── UiEnforcement.php # REUSE
│ │ └── Ui/
│ │ └── ActionSurface/
│ │ ├── ActionSurfaceValidator.php # MODIFY
│ │ ├── ActionSurfaceExemptions.php # MODIFY
│ │ ├── ActionSurfaceProfileDefinition.php # POSSIBLE MODIFY
│ │ └── Enums/
│ │ └── ActionSurfaceProfile.php # POSSIBLE MODIFY
├── resources/
│ └── views/
│ └── filament/
│ └── infolists/
│ └── entries/
│ └── tenant-review-summary.blade.php # MODIFY
└── tests/
├── Feature/
│ ├── Guards/
│ │ ├── ActionSurfaceContractTest.php # MODIFY
│ │ ├── ActionSurfaceValidatorTest.php # MODIFY
│ │ └── Spec192RecordPageHeaderDisciplineGuardTest.php # NEW
│ └── Filament/
│ ├── BaselineProfileCaptureStartSurfaceTest.php # MODIFY or REUSE
│ ├── BaselineProfileCompareStartSurfaceTest.php # MODIFY or REUSE
│ ├── TenantViewHeaderUiEnforcementTest.php # MODIFY or REUSE
│ ├── FindingExceptionHeaderDisciplineTest.php # NEW
│ ├── TenantReviewHeaderDisciplineTest.php # NEW
│ └── EditTenantHeaderDisciplineTest.php # NEW
└── Browser/
├── Spec174EvidenceFreshnessPublicationTrustSmokeTest.php # REUSE for patterns
├── Spec190BaselineCompareMatrixSmokeTest.php # REUSE for patterns
└── Spec192RecordPageHeaderDisciplineSmokeTest.php # NEW
Additional reused test files referenced in tasks.md, such as EvidenceSnapshotResourceTest.php, TenantReviewUiContractTest.php, and RBAC regression suites, remain in scope even when they are not repeated in the summary tree above.
Structure Decision: Keep the work entirely inside the existing Laravel/Filament monolith under apps/platform. Modify only the affected resource classes, page classes, the tenant-review contextual Blade partial, the existing action-surface validation layer, and focused tests. Do not create a new support framework beyond the minimum needed to extend the existing guard patterns.
Complexity Tracking
| Violation | Why Needed | Simpler Alternative Rejected Because |
|---|---|---|
| Cross-page header taxonomy and explicit exception catalog (BLOAT-001 trigger) | The feature must distinguish standard record pages, reference pages, minor-alignment pages, and the single workflow-heavy exception in a way CI can validate. | Pure page-local cleanup would reduce immediate noise but would not prevent future drift or document why ViewTenant is intentionally different. |
Proportionality Review
- Current operator problem: Several classic record/detail/edit pages still present navigation, routine mutations, and danger as flat peers, slowing interpretation and weakening action hierarchy.
- Existing structure is insufficient because: The constitution now carries HDR-001, but the repo lacks a concrete inventory, a bounded classification model, and a regression hook that can distinguish standard pages from an allowed special type.
- Narrowest correct implementation: Keep all changes inside existing page classes and the existing action-surface validation layer, classify only the explicitly named pages, remediate only the pages that need it, and document exactly one special-type exception.
- Ownership cost created: A small amount of guard configuration, a few focused page tests, one smoke suite, and ongoing review discipline for future record pages.
- Alternative intentionally rejected: A new header-action framework, resolver, or interface layer was rejected because the current repo already has enough primitives to implement the discipline directly.
- Release truth: current-release operator clarity and action-surface discipline
Implementation Strategy
Phase A — Codify the inventory and the regression contract
Goal: turn the spec inventory into an enforceable project-level contract without introducing a new framework.
Changes:
- Extend the existing action-surface validation and exemption layer with Spec 192 surface expectations.
- Encode the explicit workflow-heavy exception for
ViewTenant. - Record which pages are remediation-required, which are audit-only, and which are compliant references.
Tests:
- Add
Spec192RecordPageHeaderDisciplineGuardTest.php. - Extend
ActionSurfaceContractTest.phpandActionSurfaceValidatorTest.phpwith Spec 192 expectations.
Phase B — Remediate the highest-noise standard record pages
Goal: implement the clearest header-discipline wins first on the pages with the most obvious peer-action sprawl.
Changes:
- Refactor
ViewBaselineProfileto expose one state-sensitive primary action and move navigation plus secondary actions out of the flat primary lane. - Refactor
ViewTenantReviewso only one lifecycle action stays primary and the rest become grouped or contextual. - Keep all existing action semantics, notifications,
OperationRunlinks, confirmations, and authorization unchanged.
Tests:
- Reuse or extend existing baseline profile feature tests.
- Add runtime assertions for visible primary action count, grouped secondary placement, and preserved authorization behavior.
Phase C — Remediate the remaining standard record and edit surfaces
Goal: finish the standard-page cleanup with lower-complexity but still important record surfaces.
Changes:
- Refactor
ViewEvidenceSnapshotto keep one central next step and separate lifecycle danger from related navigation. - Refactor
ViewFindingExceptionso navigation becomes secondary while governance lifecycle remains clear. - Refactor
EditTenantso the header no longer competes with the edit task.
Tests:
- Add focused feature tests for
EvidenceSnapshot,FindingException, andEditTenant. - Preserve existing capability gating and confirmation behavior in all assertions.
Phase D — Tighten the explicit exception and audit-only pages
Goal: make the special type explicit and ensure audit-only pages stay calm.
Changes:
- Move pure navigation on
ViewTenantinto contextual placement outside the header and reorder grouped header actions by explicit buckets: external links, verification, setup, and lifecycle. - Audit
ViewProviderConnectionandViewFindingfor minor alignment only and change them only if they still present real header-noise issues. - Confirm
ViewBaselineSnapshot,ViewBackupSet,ViewReviewPack,ViewAlertDestination,ViewPolicyVersion, andViewWorkspaceremain compliant references.
Tests:
- Extend
TenantViewHeaderUiEnforcementTest.phpor add a dedicated special-type feature test. - Cover the explicit exception reason in the guard layer.
Phase E — Browser verification and final regression protection
Goal: prove the new hierarchy in a real browser and keep CI from accepting future header sprawl.
Changes:
- Add
Spec192RecordPageHeaderDisciplineSmokeTest.phpcovering the remediated pages, the workflow-heavy exception, and a no-regression baseline over the compliant reference set. - Ensure the guard layer fails on multiple competing primaries, missing grouped secondary structure where required, or silent exceptions.
- Re-run formatting and the focused Sail test pack.
Tests:
- Browser smoke coverage for visible hierarchy and no JavaScript errors.
- Focused guard and page-level tests for each remediated or exceptional surface.
Risk Assessment
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Cleanup grows into a new action framework | Medium | Low | Keep all changes inside existing page classes and the current action-surface guard layer. |
More groups become junk drawers |
Medium | Medium | Treat internal order as part of the contract and test it on the special-type and remediated pages. |
| State-driven primary action is chosen incorrectly | High | Medium | Add focused runtime assertions for BaselineProfile and TenantReview state transitions. |
ViewTenant silently bypasses the standard-page rule |
Medium | Medium | Encode the special-type exception in the guard layer with an explicit reason and browser coverage. |
| Reference pages get unnecessary churn | Medium | Low | Keep a documented compliant-reference set and use it as a regression baseline. |
Test Strategy
- Extend
ActionSurfaceContractTest.phpandActionSurfaceValidatorTest.phpso Spec 192 becomes an explicit CI-enforced rule rather than a manual review note. - Add
Spec192RecordPageHeaderDisciplineGuardTest.phpto validate remediation-required pages, the explicit special type, and any whitelisted references. - Reuse existing baseline profile tests where possible and add focused feature tests for
EvidenceSnapshot,FindingException,TenantReview, andEditTenantwhere no dedicated header-discipline tests exist yet. - Extend
TenantViewHeaderUiEnforcementTest.phpor add a dedicated special-type test so grouped ordering and exception semantics stay covered. - Add
Spec192RecordPageHeaderDisciplineSmokeTest.phpusing the existing browser-smoke infrastructure and fixture traits already used by Spec 174 and Spec 190, including a no-regression pass over the compliant reference set. - Add explicit regression assertions that this feature does not force Spec 133 body-layout rollout and does not expand confirmation depth, reason capture, or provider-dispatch semantics.
- Run the focused Sail verification commands from
quickstart.md, then runcd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent.
Constitution Check (Post-Design)
Re-check result: PASS.
- Livewire v4.0+ compliance remains intact because all touched surfaces stay inside the existing Filament v5 + Livewire v4 stack.
- Provider registration remains unchanged in
bootstrap/providers.php. - No new globally searchable resource is introduced; touched resources already have View and/or Edit pages where relevant.
- Destructive actions remain confirmation-gated and authorization-gated.
- No new asset strategy is required; deploy handling of
cd apps/platform && php artisan filament:assetsremains unchanged. - The testing plan covers the remediated standard pages, the explicit workflow-heavy exception, and the project-level regression guard for future record-page header drift.