- 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
326 lines
23 KiB
Markdown
326 lines
23 KiB
Markdown
# 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 through `Action::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:assets` remains 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`, and `RelatedNavigationResolver` instead of introducing a header-action framework.
|
|
- Move pure navigation to contextual placement outside the header instead of equal-weight header placement.
|
|
- Treat `ViewTenant` as 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 discipline
|
|
- `data-model.md`: derived header-surface inventory, render contract, and regression expectation models
|
|
- `contracts/record-header-discipline.logical.openapi.yaml`: internal logical contract for standard-page headers, the special-type exception, and regression expectations
|
|
- `quickstart.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 `ViewTenant` as 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)
|
|
|
|
```text
|
|
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)
|
|
|
|
```text
|
|
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.php` and `ActionSurfaceValidatorTest.php` with 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 `ViewBaselineProfile` to expose one state-sensitive primary action and move navigation plus secondary actions out of the flat primary lane.
|
|
- Refactor `ViewTenantReview` so only one lifecycle action stays primary and the rest become grouped or contextual.
|
|
- Keep all existing action semantics, notifications, `OperationRun` links, 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 `ViewEvidenceSnapshot` to keep one central next step and separate lifecycle danger from related navigation.
|
|
- Refactor `ViewFindingException` so navigation becomes secondary while governance lifecycle remains clear.
|
|
- Refactor `EditTenant` so the header no longer competes with the edit task.
|
|
|
|
Tests:
|
|
|
|
- Add focused feature tests for `EvidenceSnapshot`, `FindingException`, and `EditTenant`.
|
|
- 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 `ViewTenant` into contextual placement outside the header and reorder grouped header actions by explicit buckets: external links, verification, setup, and lifecycle.
|
|
- Audit `ViewProviderConnection` and `ViewFinding` for minor alignment only and change them only if they still present real header-noise issues.
|
|
- Confirm `ViewBaselineSnapshot`, `ViewBackupSet`, `ViewReviewPack`, `ViewAlertDestination`, `ViewPolicyVersion`, and `ViewWorkspace` remain compliant references.
|
|
|
|
Tests:
|
|
|
|
- Extend `TenantViewHeaderUiEnforcementTest.php` or 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.php` covering 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.php` and `ActionSurfaceValidatorTest.php` so Spec 192 becomes an explicit CI-enforced rule rather than a manual review note.
|
|
- Add `Spec192RecordPageHeaderDisciplineGuardTest.php` to 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`, and `EditTenant` where no dedicated header-discipline tests exist yet.
|
|
- Extend `TenantViewHeaderUiEnforcementTest.php` or add a dedicated special-type test so grouped ordering and exception semantics stay covered.
|
|
- Add `Spec192RecordPageHeaderDisciplineSmokeTest.php` using 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 run `cd 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:assets` remains 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.
|