TenantAtlas/specs/167-derived-state-memoization/tasks.md
ahmido d98dc30520 feat: add request-scoped derived state memoization (#198)
## 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
2026-03-28 14:58:30 +00:00

209 lines
17 KiB
Markdown

# 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.
- [X] T001 [P] Create the request-scoped derived-state support files in `app/Support/Ui/DerivedState/DerivedStateFamily.php`, `app/Support/Ui/DerivedState/DerivedStateKey.php`, and `app/Support/Ui/DerivedState/RequestScopedDerivedStateStore.php`
- [X] 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`, and `tests/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.
- [X] 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`
- [X] T004 [P] Implement the derived-state family and key value objects in `app/Support/Ui/DerivedState/DerivedStateFamily.php` and `app/Support/Ui/DerivedState/DerivedStateKey.php`
- [X] T005 Implement request-local resolve, reuse, and invalidation behavior in `app/Support/Ui/DerivedState/RequestScopedDerivedStateStore.php`
- [X] 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
- [X] T007 [P] [US1] Add per-row artifact-truth reuse assertions for `ReviewRegister` in `tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php`
- [X] T008 [P] [US1] Add canonical per-row artifact-truth reuse assertions plus one explicit entitlement-boundary regression for `EvidenceOverview` in `tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php`
### Implementation for User Story 1
- [X] T009 [US1] Route `ArtifactTruthPresenter::forBaselineSnapshot()`, `forEvidenceSnapshot()`, `forTenantReview()`, `forReviewPack()`, and `forOperationRun()` through the request-scoped store in `app/Support/Ui/GovernanceArtifactTruth/ArtifactTruthPresenter.php`
- [X] T010 [US1] Replace repeated `forTenantReview()` closure calls with a row-safe artifact-truth access path in `app/Filament/Pages/Reviews/ReviewRegister.php`
- [X] T011 [US1] Reuse a single artifact-truth resolution per active snapshot row in `app/Filament/Pages/Monitoring/EvidenceOverview.php`
- [X] 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`, and `app/Filament/Resources/OperationRunResource.php`
- [X] T013 [US1] Run the focused artifact-truth memoization pack in `tests/Feature/Filament/ReviewRegisterDerivedStateMemoizationTest.php` and `tests/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
- [X] T014 [P] [US2] Add operation-guidance and operator-explanation reuse assertions for list/detail surfaces in `tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php`
- [X] 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
- [X] T016 [US2] Route covered guidance and explanation reads through the request-scoped store in `app/Support/OpsUx/OperationUxPresenter.php`
- [X] T017 [US2] Route primary, detail, and header related-navigation resolution through the request-scoped store in `app/Support/Navigation/RelatedNavigationResolver.php`
- [X] T018 [US2] Reuse operation guidance and related-context state on run list/detail surfaces in `app/Filament/Resources/OperationRunResource.php` and `app/Filament/Pages/Operations/TenantlessOperationRunViewer.php`
- [X] T019 [US2] Converge page-local related-entry consumers with the shared contract in `app/Filament/Resources/FindingResource.php` and `app/Filament/Resources/PolicyVersionResource/Pages/ViewPolicyVersion.php`
- [X] T020 [US2] Run the focused guidance and navigation memoization pack in `tests/Feature/Filament/OperationRunDerivedStateMemoizationTest.php` and `tests/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
- [X] 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`
- [X] T022 [P] [US3] Add no-reuse and invalidate-after-mutation assertions to `tests/Unit/Support/Ui/DerivedState/RequestScopedDerivedStateStoreTest.php`
### Implementation for User Story 3
- [X] T023 [US3] Add family freshness-policy and invalidation APIs in `app/Support/Ui/DerivedState/DerivedStateFamily.php` and `app/Support/Ui/DerivedState/RequestScopedDerivedStateStore.php`
- [X] 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`, and `app/Filament/Resources/ReviewPackResource.php`
- [X] 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`, and `app/Filament/Resources/PolicyVersionResource/Pages/ViewPolicyVersion.php`
- [X] T026 [US3] Run the freshness regression pack in `tests/Feature/Filament/DerivedStateMutationFreshnessTest.php` and `tests/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.
- [X] T027 Implement the automated derived-state adoption guard in `tests/Feature/Guards/DerivedStateConsumerAdoptionGuardTest.php` using existing guard-test scanning patterns plus declared `surface`, `family`, `variant`, `accessPattern`, `scopeInputs`, `freshnessPolicy`, and `guardScope` metadata to fail with actionable file-and-snippet output when covered families reintroduce ad hoc local caches or undeclared adoption paths
- [X] 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`, and `specs/167-derived-state-memoization/contracts/request-scoped-derived-state.logical.openapi.yaml`
- [X] T029 Run formatting for touched implementation files with `vendor/bin/sail bin pint --dirty --format agent` using `specs/167-derived-state-memoization/quickstart.md`
- [X] T030 Run the final focused verification pack from `specs/167-derived-state-memoization/quickstart.md` against `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`
---
## 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
- `T001` and `T002` can run in parallel during Setup.
- `T003` and `T004` can run in parallel during Foundational work.
- `T007` and `T008` can run in parallel for User Story 1.
- `T014` and `T015` can run in parallel for User Story 2.
- `T021` and `T022` can run in parallel for User Story 3.
---
## Parallel Example: User Story 1
```bash
# 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
```bash
# 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
```bash
# 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.