## Summary - add a request-scoped derived-state store with deterministic keying and freshness controls - adopt the shared contract in ArtifactTruthPresenter, OperationUxPresenter, and RelatedNavigationResolver plus the covered Filament consumers - add spec, plan, contracts, guardrails, and focused memoization and freshness test coverage for spec 167 ## Verification - vendor/bin/sail artisan test --compact tests/Feature/078/RelatedLinksOnDetailTest.php - vendor/bin/sail artisan test --compact tests/Feature/078/ tests/Feature/Operations/TenantlessOperationRunViewerTest.php tests/Feature/Monitoring/OperationsCanonicalUrlsTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php tests/Feature/Verification/VerificationAuthorizationTest.php tests/Feature/Verification/VerificationReportViewerDbOnlyTest.php tests/Feature/Verification/VerificationReportRedactionTest.php tests/Feature/Verification/VerificationReportMissingOrMalformedTest.php tests/Feature/OpsUx/FailureSanitizationTest.php tests/Feature/OpsUx/CanonicalViewRunLinksTest.php - vendor/bin/sail bin pint --dirty --format agent ## Notes - Livewire v4.0+ compliance preserved - provider registration remains in bootstrap/providers.php - no Filament assets or panel registration changes - no global-search behavior changes - no destructive action behavior changes in this PR Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #198
17 KiB
Tasks: Request-Scoped Derived State and Resolver Memoization
Input: Design documents from /specs/167-derived-state-memoization/
Prerequisites: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/, quickstart.md
Tests: Tests are REQUIRED for this feature. Use Pest coverage in tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php, tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php, tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php, tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php, tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php, tests/Feature/Filament/DerivedStateMutationFreshnessTest.php, and tests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.php.
Operations: This feature touches existing OperationRun list/detail surfaces and OperationUxPresenter, but it does not create a new run type, does not change run lifecycle ownership, and does not add a new Ops-UX feedback surface.
RBAC: Existing workspace membership, tenant entitlement, and 404 vs 403 semantics remain unchanged. Tasks must preserve tenant-safe and workspace-safe derived-state reuse and add focused scope-safety regression coverage.
Operator Surfaces: Covered list, detail, and canonical surfaces must keep their current operator-visible meaning while sharing one request-local derived-state result per family where appropriate.
Filament UI Action Surfaces: No new actions or inspect affordances are added. Existing action inventories, confirmations, and detail/list interaction patterns must remain intact.
Filament UI UX-001: No screen layout redesign is introduced. Existing table, detail, and widget structures remain intact while consumer seams are refactored to reuse derived-state results.
Badges: Existing badge semantics must continue to flow through BadgeCatalog / BadgeRenderer; no page-local mappings are introduced as part of memoization work.
Organization: Tasks are grouped by user story so each story can be implemented and verified independently after the shared runtime contract is in place.
Phase 1: Setup (Shared Runtime Scaffolding)
Purpose: Create the narrow runtime and test scaffolding required for the request-scoped contract.
- T001 [P] Create the request-scoped derived-state support files in
app/Support/Ui/DerivedState/DerivedStateFamily.php,app/Support/Ui/DerivedState/DerivedStateKey.php, andapp/Support/Ui/DerivedState/RequestScopedDerivedStateStore.php - T002 [P] Create the focused test files in
tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php,tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php,tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php,tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php,tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php,tests/Feature/Filament/DerivedStateMutationFreshnessTest.php, andtests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.php
Phase 2: Foundational (Blocking Runtime Contract)
Purpose: Build the core request-scoped store and binding that all user stories depend on.
⚠️ CRITICAL: No user story work should begin until this phase is complete.
- T003 [P] Add unit coverage for key composition, hit/miss behavior, negative-result reuse, variant separation, and invalidation in
tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php - T004 [P] Implement the derived-state family and key value objects in
app/Support/Ui/DerivedState/DerivedStateFamily.phpandapp/Support/Ui/DerivedState/DerivedStateKey.php - T005 Implement request-local resolve, reuse, and invalidation behavior in
app/Support/Ui/DerivedState/RequestScopedDerivedStateStore.php - T006 Register the request-scoped derived-state store binding in
app/Providers/AppServiceProvider.php
Checkpoint: The request-scoped derived-state runtime contract exists and can be adopted by presenter and resolver families.
Phase 3: User Story 1 - Reuse One Derived Truth Per Record (Priority: P1)
Goal: Reuse one artifact-truth derivation per covered record on representative list and canonical surfaces.
Independent Test: Review Register and Evidence Overview render the same labels, explanations, and next-step text as before while each covered artifact-truth result resolves once per request for the same record and variant.
Tests for User Story 1
- T007 [P] [US1] Add per-row artifact-truth reuse assertions for
ReviewRegisterintests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php - T008 [P] [US1] Add canonical per-row artifact-truth reuse assertions plus one explicit entitlement-boundary regression for
EvidenceOverviewintests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php
Implementation for User Story 1
- T009 [US1] Route
ArtifactTruthPresenter::forBaselineSnapshot(),forEvidenceSnapshot(),forTenantReview(),forReviewPack(), andforOperationRun()through the request-scoped store inapp/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php - T010 [US1] Replace repeated
forTenantReview()closure calls with a row-safe artifact-truth access path inapp/Filament/Pages/Reviews/ReviewRegister.php - T011 [US1] Reuse a single artifact-truth resolution per active snapshot row in
app/Filament/Pages/Monitoring/EvidenceOverview.php - T012 [US1] Keep the first-slice baseline snapshot, evidence snapshot, tenant review, review pack, and operation-run helper consumers aligned to the shared artifact-truth contract in
app/Filament/Resources/BaselineSnapshotResource.php,app/Filament/Resources/BaselineSnapshotResource/Pages/ViewBaselineSnapshot.php,app/Filament/Resources/EvidenceSnapshotResource.php,app/Filament/Resources/TenantReviewResource.php,app/Filament/Resources/ReviewPackResource.php, andapp/Filament/Resources/OperationRunResource.php - T013 [US1] Run the focused artifact-truth memoization pack in
tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.phpandtests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php
Checkpoint: Covered artifact-truth list and canonical surfaces now reuse one deterministic truth result per record and request.
Phase 4: User Story 2 - Reuse Derived State Across Surface Fragments In One Request (Priority: P1)
Goal: Reuse operation guidance and related-navigation state across list/detail fragments and converge existing hidden local caches.
Independent Test: Operation run list/detail surfaces and representative related-navigation consumers keep the same URLs and guidance text while each covered family resolves once per request for the same scope and also safely reuses deterministic negative results.
Tests for User Story 2
- T014 [P] [US2] Add operation-guidance and operator-explanation reuse assertions for list/detail surfaces in
tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php - T015 [P] [US2] Add related-navigation reuse, negative-result caching, deny-as-not-found regressions for non-members or wrong-scope users, forbidden regressions for in-scope users lacking capability, and tenant/workspace entitlement-boundary assertions in
tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php
Implementation for User Story 2
- T016 [US2] Route covered guidance and explanation reads through the request-scoped store in
app/Support/OpsUx/OperationUxPresenter.php - T017 [US2] Route primary, detail, and header related-navigation resolution through the request-scoped store in
app/Support/Navigation/RelatedNavigationResolver.php - T018 [US2] Reuse operation guidance and related-context state on run list/detail surfaces in
app/Filament/Resources/OperationRunResource.phpandapp/Filament/Pages/Operations/TenantlessOperationRunViewer.php - T019 [US2] Converge page-local related-entry consumers with the shared contract in
app/Filament/Resources/FindingResource.phpandapp/Filament/Resources/PolicyVersionResource/Pages/ViewPolicyVersion.php - T020 [US2] Run the focused guidance and navigation memoization pack in
tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.phpandtests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php
Checkpoint: Covered operation-guidance and related-navigation surfaces now share one request-local derived-state contract instead of separate local cache patterns.
Phase 5: User Story 3 - Preserve Freshness In Mutation Flows (Priority: P2)
Goal: Make post-mutation freshness explicit so request-local reuse never returns stale artifact truth or navigation after business state changes.
Independent Test: A covered mutating action changes business truth within the same request and the subsequent visible artifact-truth or related state is freshly determined instead of reusing stale pre-action results.
Tests for User Story 3
- T021 [P] [US3] Add post-mutation freshness regression coverage for covered truth-, guidance-, or navigation-affecting generation or review actions in
tests/Feature/Filament/DerivedStateMutationFreshnessTest.php - T022 [P] [US3] Add no-reuse and invalidate-after-mutation assertions to
tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php
Implementation for User Story 3
- T023 [US3] Add family freshness-policy and invalidation APIs in
app/Support/Ui/DerivedState/DerivedStateFamily.phpandapp/Support/Ui/DerivedState/RequestScopedDerivedStateStore.php - T024 [US3] Invalidate or bypass stale artifact-truth entries after covered tenant review, evidence snapshot, and review pack mutations in
app/Filament/Resources/TenantReviewResource.php,app/Filament/Resources/EvidenceSnapshotResource.php, andapp/Filament/Resources/ReviewPackResource.php - T025 [US3] Update post-action truth, guidance, and related-navigation helper access to use explicit fresh-access paths in
app/Filament/Resources/TenantReviewResource.php,app/Filament/Resources/EvidenceSnapshotResource.php,app/Filament/Resources/ReviewPackResource.php,app/Filament/Resources/OperationRunResource.php, andapp/Filament/Resources/PolicyVersionResource/Pages/ViewPolicyVersion.php - T026 [US3] Run the freshness regression pack in
tests/Feature/Filament/DerivedStateMutationFreshnessTest.phpandtests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php
Checkpoint: Covered mutation flows now have explicit freshness behavior and cannot accidentally reuse stale request-local derived state.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Add the automated future-family guard, remove superseded local patterns, format touched files, and run the full focused verification pack.
- T027 Implement the automated derived-state adoption guard in
tests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.phpusing existing guard-test scanning patterns plus declaredsurface,family,variant,accessPattern,scopeInputs,freshnessPolicy, andguardScopemetadata to fail with actionable file-and-snippet output when covered families reintroduce ad hoc local caches or undeclared adoption paths - T028 Remove or collapse superseded ad hoc local derived-state caches and document future-family adoption guardrails in
app/Filament/Pages/Reviews/ReviewRegister.php,app/Filament/Pages/Monitoring/EvidenceOverview.php,app/Filament/Resources/FindingResource.php,app/Filament/Resources/PolicyVersionResource/Pages/ViewPolicyVersion.php,specs/167-derived-state-memoization/quickstart.md, andspecs/167-derived-state-memoization/contracts/request-scoped-derived-state.logical.openapi.yaml - T029 Run formatting for touched implementation files with
vendor/bin/sail bin pint --dirty --format agentusingspecs/167-derived-state-memoization/quickstart.md - T030 Run the final focused verification pack from
specs/167-derived-state-memoization/quickstart.mdagainsttests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php,tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php,tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php,tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php,tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php,tests/Feature/Filament/DerivedStateMutationFreshnessTest.php, andtests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.php
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): Starts immediately and creates the narrow runtime and test scaffolding.
- Foundational (Phase 2): Depends on Setup and blocks all user stories until the request-scoped store and binding exist.
- User Story 1 (Phase 3): Starts after Foundational and delivers the MVP artifact-truth reuse slice.
- User Story 2 (Phase 4): Starts after Foundational and can overlap with User Story 1 after the shared store is available, but it is safest after artifact-truth adoption confirms the key contract.
- User Story 3 (Phase 5): Starts after User Stories 1 and 2 have established the family adoption seams because freshness rules depend on the shared contract being in use.
- Polish (Phase 6): Starts after all desired user stories are complete and ends with the automated adoption guard plus focused verification pack passing.
User Story Dependencies
- User Story 1 (P1): Depends only on the request-scoped store, key contract, and binding from Phase 2.
- User Story 2 (P1): Depends on the same foundational contract and can proceed independently of US1 at the store level, but shares adoption patterns and should follow once the artifact-truth slice proves the consumer seam.
- User Story 3 (P2): Depends on the adoption work from US1 and US2 because mutation freshness only matters after reuse is in place.
Within Each User Story
- Tests should be added before or alongside implementation and must fail before the story is considered complete.
- Family entry-point changes should land before consumer refactors in the same story.
- Consumer refactors should land before the focused story-level regression run.
Parallel Opportunities
T001andT002can run in parallel during Setup.T003andT004can run in parallel during Foundational work.T007andT008can run in parallel for User Story 1.T014andT015can run in parallel for User Story 2.T021andT022can run in parallel for User Story 3.
Parallel Example: User Story 1
# User Story 1 tests in parallel:
Task: T007 tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php
Task: T008 tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php
# User Story 1 implementation split after test expectations are clear:
Task: T010 app/Filament/Pages/Reviews/ReviewRegister.php
Task: T011 app/Filament/Pages/Monitoring/EvidenceOverview.php
Parallel Example: User Story 2
# User Story 2 tests in parallel:
Task: T014 tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php
Task: T015 tests/Feature/Navigation/RelatedNavigationResolverMemoizationTest.php
# User Story 2 implementation split after family entry-point work lands:
Task: T018 app/Filament/Resources/OperationRunResource.php and app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
Task: T019 app/Filament/Resources/FindingResource.php and app/Filament/Resources/PolicyVersionResource/Pages/ViewPolicyVersion.php
Parallel Example: User Story 3
# User Story 3 freshness coverage in parallel:
Task: T021 tests/Feature/Filament/DerivedStateMutationFreshnessTest.php
Task: T022 tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php
# User Story 3 implementation split after freshness rules are fixed:
Task: T024 app/Filament/Resources/TenantReviewResource.php, app/Filament/Resources/EvidenceSnapshotResource.php, and app/Filament/Resources/ReviewPackResource.php
Task: T025 app/Filament/Resources/TenantReviewResource.php, app/Filament/Resources/EvidenceSnapshotResource.php, and app/Filament/Resources/ReviewPackResource.php
Implementation Strategy
MVP First
- Complete Phase 1 and Phase 2.
- Deliver User Story 1 as the MVP slice.
- Verify that representative artifact-truth surfaces now reuse one deterministic result per request without changing visible meaning.
Incremental Delivery
- Add User Story 2 next to cover operation guidance and related-navigation reuse across multi-fragment surfaces.
- Add User Story 3 last to make mutation freshness explicit once the reuse seams are in place.
Verification Finish
- Run the derived-state adoption guard test from
quickstart.md. - Run Pint on touched files.
- Run the focused verification pack from
quickstart.md. - If broader confidence is needed after focused verification, run the wider suite separately.