TenantAtlas/specs/192-record-header-discipline/plan.md
Ahmed Darrazi 72ddc18743 feat: implement spec 192 header discipline
- 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
2026-04-11 23:09:42 +02:00

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 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)

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.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.