# Implementation Plan: Enterprise Evidence Gap Details for Baseline Compare **Branch**: `162-baseline-gap-details` | **Date**: 2026-03-24 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/162-baseline-gap-details/spec.md` **Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/162-baseline-gap-details/spec.md` ## Summary Expose baseline compare evidence gaps as an operator-first, searchable, tenant-safe detail experience backed by immutable `OperationRun.context` data. The implementation keeps compare execution and `OperationRun` lifecycle unchanged, persists bounded per-reason subject details during compare/capture work, renders them in the canonical run-detail and tenant compare surfaces ahead of raw JSON diagnostics, and validates the behavior with Pest feature coverage for persistence, rendering, and legacy-run fallbacks. ## Technical Context **Language/Version**: PHP 8.4 / Laravel 12, Blade, Alpine via Filament, Tailwind CSS v4 **Primary Dependencies**: Filament v5, Livewire v4, Pest v4, Laravel Sail, existing `OperationRun` and baseline compare services **Storage**: PostgreSQL with JSONB-backed `operation_runs.context`; no new tables required **Testing**: Pest feature tests run through Sail, plus existing Filament page rendering tests **Target Platform**: Laravel web application in Sail locally and Linux container deployment in staging/production **Project Type**: Web application **Performance Goals**: DB-only render path; no render-time Graph calls; searchable gap detail remains usable for bounded per-reason subject lists; operator can isolate a relevant subject in under 30 seconds **Constraints**: Preserve `OperationRunService` ownership of status/outcome, keep evidence-gap JSON bounded by existing caps, retain tenant-safe canonical monitoring behavior, add no destructive actions, and avoid new global/published Filament assets **Scale/Scope**: Tenant-scoped baseline compare runs for enterprise tenants, subject-detail persistence within the existing compare job/capture pipeline, read-only UX changes across the canonical run detail and tenant baseline compare landing surfaces ## Constitution Check *GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.* - Inventory-first: Pass. This feature reads existing inventory and baseline snapshot outputs and only improves how compare gaps are persisted and presented. - Read/write separation: Pass. Compare initiation remains unchanged; the new surface is read-only and introduces no new mutation path. - Graph contract path: Pass. No new Graph calls or contract bypasses are introduced; all render behavior remains DB-only. - Deterministic capabilities: Pass. No new capability derivation is introduced. - RBAC-UX plane separation and tenant safety: Pass. Canonical `/admin/operations/{run}` remains tenant-safe through existing workspace + tenant entitlement checks, and tenant landing remains tenant-scoped. - Workspace isolation: Pass. No workspace-context semantics are broadened. - Destructive confirmation: Pass. No destructive action is added or changed. - Global search safety: Pass. No global-search behavior is introduced or modified. - Tenant isolation: Pass. Evidence-gap detail is persisted on the tenant-owned `OperationRun` and revealed only through already authorized run/tenant surfaces. - Run observability: Pass. Existing baseline compare `OperationRun` behavior stays intact; this feature enriches context only. - Ops-UX 3-surface feedback: Pass. No additional toasts, progress surfaces, or terminal notifications are introduced. - Ops-UX lifecycle ownership: Pass. `status`/`outcome` transitions remain service-owned; only `context` payload content is extended. - Ops-UX summary counts: Pass. No new `summary_counts` keys are added. - Ops-UX guards and system-run rules: Pass. Existing monitoring and notification invariants remain untouched. - Automation/backoff: Pass. Existing capture-phase retry/backoff behavior remains the only throttling mechanism in scope. - Data minimization: Pass. Persisted detail is bounded, operator-safe subject identity rather than raw payload dumps or secrets. - Badge semantics: Pass. Existing run outcome/trust badges remain centralized; evidence-gap detail is plain text/searchable rows. - UI naming: Pass. The operator copy uses domain terms such as `Evidence gap details`, `Policy type`, and `Subject key`. - Operator surfaces: Pass. Outcome and trust stay ahead of diagnostics, and the detail section is secondary to result meaning. - Filament Action Surface Contract: Pass. The change is read-only and does not alter header/row/bulk/destructive semantics. - UX-001 Layout and IA: Pass. The detail stays sectioned and readable within the existing enterprise detail layout. - Filament v5 / Livewire v4 compliance: Pass. The feature remains within the existing Filament v5 + Livewire v4 stack. - Provider registration location: Pass. No panel provider changes are required; Laravel 11+ registration remains in `bootstrap/providers.php`. - Global search hard rule: Pass. No resource searchability changes are required. - Asset strategy: Pass. The design relies on existing Filament/Blade/Alpine capabilities and does not require new published or on-demand assets. ## Phase 0 Research Research outcomes are captured in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/162-baseline-gap-details/research.md`. Key decisions: - Persist subject-level evidence gaps as an immutable read model under `baseline_compare.evidence_gaps.subjects` inside `OperationRun.context`. - Merge subject detail from all compare evidence-gap sources: ambiguous inventory matches, capture-phase failures, and drift-time missing evidence. - Keep filtering local to the rendered detail section because the stored dataset is intentionally bounded and render-time network/database chatter would add unnecessary complexity. - Preserve operator-first reading order: result meaning and trust first, evidence-gap detail second, raw JSON last. - Treat legacy runs with counts but no recorded subjects as a first-class fallback state rather than as empty/healthy runs. ## Phase 1 Design Design artifacts are created under `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/162-baseline-gap-details/`: - `data-model.md`: JSONB-backed read-model contract and derived UI row shape. - `contracts/baseline-gap-details.openapi.yaml`: internal reference schema for the shared evidence-gap read model used by both operator surfaces; it is not a commitment to add new HTTP endpoints in this slice. - `quickstart.md`: verification path covering focused tests, tenant-safety checks, render-safety checks, local run review, and legacy-run fallback checks. Design decisions: - No schema migration is required; the durable contract is an extension of the existing JSONB payload. - The canonical record remains `OperationRun`; no separate evidence-gap table or Eloquent model is introduced. - Filtering is modeled as reason/policy-type/subject-key matching over persisted row data in the page surface, not via new server-side filtering endpoints in this slice. - Tenant landing and canonical run detail must consume semantically identical evidence-gap groupings and preserve operator-first summary ordering ahead of diagnostics. - Regression coverage must explicitly prove tenant-safe access semantics and the no-external-calls-on-render rule on both affected surfaces. ## Project Structure ### Documentation (this feature) ```text specs/162-baseline-gap-details/ ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ └── baseline-gap-details.openapi.yaml └── tasks.md ``` ### Source Code (repository root) ```text app/ ├── Filament/ │ └── Resources/ │ └── OperationRunResource.php ├── Jobs/ │ └── CompareBaselineToTenantJob.php ├── Models/ │ └── OperationRun.php └── Services/ └── Baselines/ └── BaselineContentCapturePhase.php resources/ └── views/ └── filament/ └── infolists/ └── entries/ └── evidence-gap-subjects.blade.php tests/ └── Feature/ ├── Baselines/ │ ├── BaselineCompareAmbiguousMatchGapTest.php │ └── BaselineCompareResumeTokenTest.php └── Filament/ └── OperationRunEnterpriseDetailPageTest.php ``` **Structure Decision**: Single Laravel web application. The feature stays inside the existing baseline compare pipeline, `OperationRun` read model, Filament resource rendering, Blade view composition, and Pest feature-test layout. ## Implementation Strategy 1. Normalize and persist subject-level gap detail in the compare/capture pipeline while preserving bounded payload size and legacy compare semantics. 2. Render the evidence-gap detail section from `OperationRun.context` on canonical run detail and keep the tenant landing semantics aligned. 3. Support operator filtering across reason, policy type, and subject key without introducing a new server-side search endpoint in the first implementation. 4. Keep operator-first summary content ahead of diagnostics on both the canonical run detail and tenant landing surfaces. 5. Add regression coverage for new-run persistence, tenant-safe access semantics, render-safety, UI visibility, and legacy/no-detail behavior. ## Complexity Tracking No constitution violations or justified complexity exceptions were identified.